From: John Marino Date: Tue, 6 Sep 2016 16:03:50 +0000 (-0500) Subject: Merge branch 'vendor/LIBRESSL' X-Git-Tag: v4.8.0rc~1030 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/4188afc709be91c60882529929ad3e74932fc51c?hp=39f8331b1a6f295291e08c377da12a8e7a5436c0 Merge branch 'vendor/LIBRESSL' --- diff --git a/crypto/libressl/COPYING b/crypto/libressl/COPYING new file mode 100644 index 0000000000..892e14a450 --- /dev/null +++ b/crypto/libressl/COPYING @@ -0,0 +1,133 @@ + + LibReSSL files are retained under the copyright of the authors. New + additions are ISC licensed as per OpenBSD's normal licensing policy, + or are placed in the public domain. + + The OpenSSL code is distributed under the terms of the original OpenSSL + licenses which follow: + + LICENSE ISSUES + ============== + + The OpenSSL toolkit stays under a dual license, i.e. both the conditions of + the OpenSSL License and the original SSLeay license apply to the toolkit. + See below for the actual license texts. In case of any license issues + related to OpenSSL please contact openssl-core@openssl.org. + + OpenSSL License + --------------- + +/* ==================================================================== + * Copyright (c) 1998-2011 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + Original SSLeay License + ----------------------- + +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + diff --git a/crypto/libressl/ChangeLog b/crypto/libressl/ChangeLog new file mode 100644 index 0000000000..6ec28e0d09 --- /dev/null +++ b/crypto/libressl/ChangeLog @@ -0,0 +1,594 @@ +Because this project is maintained both in the OpenBSD tree using CVS and in +Git, it can be confusing following all of the changes. + +Most of the libssl and libcrypto source code is is here in OpenBSD CVS: + + http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libssl/ + +Some of the libcrypto and OS-compatibility files for entropy and random number +generation are here: + + http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libcrypto/ + +A simplified TLS wrapper library is here: + + http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libtls/ + +The LibreSSL Portable project copies these portions of the OpenBSD tree, along +with relevant portions of the C library, to a Git repository. This makes it +easier to follow all of the relevant changes to the upstream project in a +single place: + + https://github.com/libressl-portable/openbsd + +The portable bits of the project are largely maintained out-of-tree, and their +history is also available from Git. + + https://github.com/libressl-portable/portable + +LibreSSL Portable Release Notes: + +2.4.2 - Bug fixes and improvements + + * Fixed loading default certificate locations with openssl s_client. + + * Ensured OSCP only uses and compares GENERALIZEDTIME values as per + RFC6960. Also added fixes for OCSP to work with intermediate + certificates provided in responses. + + * Improved behavior of arc4random on Windows to not appear to leak + memory in debug tools, reduced privileges of allocated memory. + + * Fixed incorrect results from BN_mod_word() when the modulus is too + large, thanks to Brian Smith from BoringSSL. + + * Correctly handle an EOF prior to completing the TLS handshake in + libtls. + + * Improved libtls ceritificate loading and cipher string validation. + + * Updated libtls cipher group suites into four categories: + "secure" (TLSv1.2+AEAD+PFS) + "compat" (HIGH:!aNULL) + "legacy" (HIGH:MEDIUM:!aNULL) + "insecure" (ALL:!aNULL:!eNULL) + This allows for flexibility and finer grained control, rather than + having two extremes. + + * Limited support for 'backward compatible' SSLv2 handshake packets to + when TLS 1.0 is enabled, providing more restricted compatibility + with TLS 1.0 clients. + + * openssl(1) and other documentation improvements. + + * Removed flags for disabling constant-time operations. + This removes support for DSA_FLAG_NO_EXP_CONSTTIME, + DH_FLAG_NO_EXP_CONSTTIME, and RSA_FLAG_NO_CONSTTIME flags, making + all of these operations unconditionally constant-time. + + +2.4.1 - Security fix + + * Correct a problem that prevents the DSA signing algorithm from + running in constant time even if the flag BN_FLG_CONSTTIME is set. + This issue was reported by Cesar Pereida (Aalto University), Billy + Brumley (Tampere University of Technology), and Yuval Yarom (The + University of Adelaide and NICTA). The fix was developed by Cesar + Pereida. + +2.4.0 - Build improvements, new features + + * Many improvements to the CMake build infrastructure, including + Solaris, mingw-w64, Cygwin, and HP-UX support. Thanks to Kinichiro + Inoguchi for this work. + + * Added missing error handling around bn_wexpand() calls. + + * Added explicit_bzero calls for freed ASN.1 objects. + + * Fixed X509_*set_object functions to return 0 on allocation failure. + + * Implemented the IETF ChaCha20-Poly1305 cipher suites. + + * Changed default EVP_aead_chacha20_poly1305() implementation to the + IETF version, which is now the default. + + * Fixed password prompts from openssl(1) to properly handle ^C. + + * Reworked error handling in libtls so that configuration errors are + visible. + + * Deprecated internal use of EVP_[Cipher|Encrypt|Decrypt]_Final. + + * Manpage fixes and updates + +2.3.5 - Reliability fix + + * Fixed an error in libcrypto when parsing some ASN.1 elements > 16k. + +2.3.4 - Security Update + + * Fix multiple vulnerabilities in libcrypto relating to ASN.1 and encoding. + From OpenSSL. + + * Minor build fixes + +2.3.3 - OpenBSD 5.9 release branch tagged + + * Reworked build scripts to better sync with OpenNTPD-portable + + * Fixed broken manpage links + + * Fixed an nginx compatibility issue by adding an 'install_sw' make alias + + * Fixed HP-UX builds + + * Changed the default configuration directory to c:\LibreSSL\ssl on Windows + binary builds + + * cert.pem has been reorganized and synced with Mozilla's certificate store + +2.3.2 - Compatibility and Reliability fixes + + * Changed format of LIBRESSL_VERSION_NUMBER to match that of + OPENSSL_VERSION_NUMBER, see: + https://wiki.openssl.org/index.php/Manual:OPENSSL_VERSION_NUMBER(3) + + * Added EVP_aead_chacha20_poly1305_ietf() which matches the AEAD + construction introduced in RFC 7539, which is different than that + already used in TLS with EVP_aead_chacha20_poly1305() + + * Avoid a potential undefined C99+ behavior due to shift overflow in + AES_decrypt, reported by Pascal Cuoq + + * More man pages converted from pod to mdoc format + + * Added COMODO RSA Certification Authority and QuoVadis + root certificates to cert.pem + + * Removed Remove "C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification + Authority" (serial 3c:91:31:cb:1f:f6:d0:1b:0e:9a:b8:d0:44:bf:12:be) root + certificate from cert.pem + + * Added support for building nc(1) on Solaris + + * Fixed GCC 5.x+ preprocessor checks, reported by Ruslan Babayev + + * Improved console handling with openssl(1) on Windows + + * Ensure the network stack is enabled on Windows when running + tls_init() + + * Fixed incorrect TLS certificate loading by nc(1) + + * Added support for Solaris 11.3's getentropy(2) system call + + * Enabled support for using NetBSD 7.0's arc4random(3) implementation + + * Deprecated the SSL_OP_SINGLE_DH_USE flag by disabling its effect + + * Fixes from OpenSSL 1.0.1q + - CVE-2015-3194 - NULL pointer dereference in client side certificate + validation. + - CVE-2015-3195 - Memory leak in PKCS7 - not reachable from TLS/SSL + + * The following OpenSSL CVEs did not apply to LibreSSL + - CVE-2015-3193 - Carry propagating bug in the x86_64 Montgomery + squaring procedure. + - CVE-2015-3196 - Double free race condition of the identify hint + data. + + See https://marc.info/?l=openbsd-announce&m=144925068504102 + +2.3.1 - ASN.1 and time handling cleanups + + * ASN.1 cleanups and RFC5280 compliance fixes. + + * Time representations switched from 'unsigned long' to 'time_t'. LibreSSL + now checks if the host OS supports 64-bit time_t. + + * Fixed a leak in SSL_new in the error path. + + * Support always extracting the peer cipher and version with libtls. + + * Added ability to check certificate validity times with libtls, + tls_peer_cert_notbefore and tls_peer_cert_notafter. + + * Changed tls_connect_servername to use the first address that resolves with + getaddrinfo(). + + * Remove broken conditional EVP_CHECK_DES_KEY code (non-functional since + initial commit in 2004). + + * Fixed a memory leak and out-of-bounds access in OBJ_obj2txt, reported + by Qualys Security. + + * Fixed an up-to 7 byte overflow in RC4 when len is not a multiple of + sizeof(RC4_CHUNK), reported by Pascal Cuoq . + + * Reject too small bits value in BN_generate_prime_ex(), so that it does + not risk becoming negative in probable_prime_dh_safe(), reported by + Franck Denis. + + * Enable nc(1) builds on more platforms. + +2.3.0 - SSLv3 removed, libtls API changes, portability improvements + + * SSLv3 is now permanently removed from the tree. + + * The libtls API is changed from the 2.2.x series. + + The read/write functions work correctly with external event + libraries. See the tls_init man page for examples of using libtls + correctly in asynchronous mode. + + Client-side verification is now supported, with the client supplying + the certificate to the server. + + Also, when using tls_connect_fds, tls_connect_socket or + tls_accept_fds, libtls no longer implicitly closes the passed in + sockets. The caller is responsible for closing them in this case. + + * When loading a DSA key from an raw (without DH parameters) ASN.1 + serialization, perform some consistency checks on its `p' and `q' + values, and return an error if the checks failed. + + Thanks for Georgi Guninski (guninski at guninski dot com) for + mentioning the possibility of a weak (non prime) q value and + providing a test case. + + See + https://cpunks.org/pipermail/cypherpunks/2015-September/009007.html + for a longer discussion. + + * Fixed a bug in ECDH_compute_key that can lead to silent truncation + of the result key without error. A coding error could cause software + to use much shorter keys than intended. + + * Removed support for DTLS_BAD_VER. Pre-DTLSv1 implementations are no + longer supported. + + * The engine command and parameters are removed from the openssl(1). + Previous releases removed dynamic and builtin engine support + already. + + * SHA-0 is removed, which was withdrawn shortly after publication 20 + years ago. + + * Added Certplus CA root certificate to the default cert.pem file. + + * New interface OPENSSL_cpu_caps is provided that does not allow + software to inadvertently modify cpu capability flags. + OPENSSL_ia32cap and OPENSSL_ia32cap_loc are removed. + + * The out_len argument of AEAD changed from ssize_t to size_t. + + * Deduplicated DTLS code, sharing bugfixes and improvements with + TLS. + + * Converted 'nc' to use libtls for client and server operations; it is + included in the libressl-portable distribution as an example of how + to use the library. + +2.2.3 - Bug fixes, build enhancements + + * LibreSSL 2.2.2 incorrectly handles ClientHello messages that do not + include TLS extensions, resulting in such handshakes being aborted. + This release corrects the handling of such messages. Thanks to + Ligushka from github for reporting the issue. + + * Added install target for cmake builds. Thanks to TheNietsnie from + github. + + * Updated pkgconfig files to correctly report the release version + number, not the individual library ABI version numbers. Thanks to + Jan Engelhardt for reporting the issue. + +2.2.2 - More TLS parser rework, bug fixes, expanded portable build support + + * Switched 'openssl dhparam' default from 512 to 2048 bits + + * Reworked openssl(1) option handling + + * More CRYPTO ByteString (CBC) packet parsing conversions + + * Fixed 'openssl pkeyutl -verify' to exit with a 0 on success + + * Fixed dozens of Coverity issues including dead code, memory leaks, + logic errors and more. + + * Ensure that openssl(1) restores terminal echo state after reading a + password. + + * Incorporated fix for OpenSSL Issue #3683 + + * LibreSSL version define LIBRESSL_VERSION_NUMBER will now be bumped + for each portable release. + + * Removed workarounds for TLS client padding bugs. + + * No longer disable ECDHE-ECDSA on OS X + + * Removed SSLv3 support from openssl(1) + + * Removed IE 6 SSLv3 workarounds. + + * Modified tls_write in libtls to allow partial writes, clarified with + examples in the documentation. + + * Removed RSAX engine + + * Tested SSLv3 removal with the OpenBSD ports tree and found several + applications that were not ready to build without SSLv3 yet. For + now, building a program that intentionally uses SSLv3 will result in + a linker warning. + + * Added TLS_method, TLS_client_method and TLS_server_method as a + replacement for the SSLv23_*method calls. + + * Added initial cmake build support, including support for building with + Visual Studio, currently tested with Visual Studio 2013 Community + Edition. + + * --with-enginesdir is removed as a configuration parameter + + * Default cert.pem, openssl.cnf, and x509v3.cnf files are now + installed under $sysconfdir/ssl or the directory specified by + --with-openssldir. Previous versions of LibreSSL left these empty. + +2.2.1 - Build fixes, feature added, features removed + + * Assorted build fixes for musl, HP-UX, Mingw, Solaris. + + * Initial support for Windows Embedded 2009, Server 2003, XP + + * Protocol parsing conversions to BoringSSL's CRYPTO ByteString (CBS) API + + * Added EC_curve_nid2nist and EC_curve_nist2nid from OpenSSL + + * Removed Dynamic Engine support + + * Removed unused and obsolete MDC-2DES cipher + + * Removed workarounds for obsolete SSL implementations + +2.2.0 - Build cleanups and new OS support, Security Updates + + * AIX Support - thanks to Michael Felt + + * Cygwin Support - thanks to Corinna Vinschen + + * Refactored build macros, support packaging libtls independently. + There are more pieces required to support building and using OpenSSL + with libtls, but this is an initial start at providing an + independent package for people to start hacking on. + + * Removal of OPENSSL_issetugid and all library getenv calls. + Applications can and should no longer rely on environment variables + for changing library behavior. OPENSSL_CONF/SSLEAY_CONF is still + supported with the openssl(1) command. + + * libtls API and documentation additions + + * Various bug fixes and simplifications to libssl and libcrypto + + * Fixes for the following issues are integrated into LibreSSL 2.2.0: + - CVE-2015-1788 - Malformed ECParameters causes infinite loop + - CVE-2015-1789 - Exploitable out-of-bounds read in X509_cmp_time + - CVE-2015-1792 - CMS verify infinite loop with unknown hash function + + * The following CVEs did not apply to LibreSSL or were fixed in + earlier releases: + - CVE-2015-4000 - DHE man-in-the-middle protection (Logjam) + - CVE-2015-1790 - PKCS7 crash with missing EnvelopedContent + - CVE-2014-8176 - Invalid free in DTLS + + * Fixes for the following CVEs are still in review for LibreSSL + - CVE-2015-1791 - Race condition handling NewSessionTicket + +2.1.6 - Security update + + * Fixes for the following issues are integrated into LibreSSL 2.1.6: + - CVE-2015-0209 - Use After Free following d2i_ECPrivatekey error + - CVE-2015-0286 - Segmentation fault in ASN1_TYPE_cmp + - CVE-2015-0287 - ASN.1 structure reuse memory corruption + - CVE-2015-0288 - X509_to_X509_REQ NULL pointer deref + - CVE-2015-0289 - PKCS7 NULL pointer dereferences + + * The fix for CVE-2015-0207 - Segmentation fault in DTLSv1_listen + is integrated for safety, but LibreSSL is not vulnerable. + + * Libtls is now built by default. The --enable-libtls + configuration option is no longer required. + The libtls API is now stable for the 2.1.x series. + +2.1.5 - Bug fixes and a security update + * Fix incorrect comparison function in openssl(1) certhash command. + Thanks to Christian Neukirchen / Void Linux. + + * Windows port improvements and bug fixes. + - Removed a dependency on libgcc in 32-bit dynamic libraries. + - Correct a hang in openssl(1) reading from stdin on an connection. + - Initialize winsock in openssl(1) earlier, allow 'openssl ocsp' and + any other network-related commands to function properly. + + * Reject all server DH keys smaller than 1024 bits. + +2.1.4 - Security and feature updates + * Improvements to libtls: + - a new API for loading CA chains directly from memory instead of a + file, allowing verification with privilege separation in a chroot + without direct access to CA certificate files. + + - Ciphers default to TLSv1.2 with AEAD and PFS. + + - Improved error handling and message generation + + - New APIs and improved documentation + + * Added X509_STORE_load_mem API for loading certificates from memory. + This facilitates accessing certificates from a chrooted environment. + + * New AEAD "MAC alias" allows configuring TLSv1.2 AEAD ciphers by + using 'TLSv1.2+AEAD' as the cipher selection string. + + * Dead and disabled code removal including MD5, Netscape workarounds, + non-POSIX IO, SCTP, RFC 3779 support, many #if 0 sections, and more. + + * ASN1 macro maze expanded to aid reading and searching the code. + + * NULL pointer asserts removed in favor of letting the OS/signal + handler catch them. + + * Refactored argument handling in openssl(1) for consistency and + maintainability. + + * New openssl(1) command 'certhash' replaces the c_rehash script. + + * Support for building with OPENSSL_NO_DEPRECATED + + * Server-side support for TLS_FALLBACK_SCSV for compatibility with + various auditor and vulnerability scanners. + + * Dozens of issues found with the Coverity scanner fixed. + + * Security Updates: + + - Fix a minor information leak that was introduced in t1_lib.c + r1.71, whereby an additional 28 bytes of .rodata (or .data) is + provided to the network. In most cases this is a non-issue since + the memory content is already public. Issue found and reported by + Felix Groebert of the Google Security Team. + + - Fixes for the following low-severity issues were integrated into + LibreSSL from OpenSSL 1.0.1k: + + CVE-2015-0205 - DH client certificates accepted without + verification + CVE-2014-3570 - Bignum squaring may produce incorrect results + CVE-2014-8275 - Certificate fingerprints can be modified + CVE-2014-3572 - ECDHE silently downgrades to ECDH [Client] + Reported by Karthikeyan Bhargavan of the PROSECCO team at INRIA. + + The following CVEs were fixed in earlier LibreSSL releases: + CVE-2015-0206 - Memory leak handling repeated DLTS records + CVE-2014-3510 - Flaw handling DTLS anonymous EC(DH) ciphersuites. + + The following CVEs did not apply to LibreSSL: + CVE-2014-3571 - DTLS segmentation fault in dtls1_get_record + CVE-2014-3569 - no-ssl3 configuration sets method to NULL + CVE-2015-0204 - RSA silently downgrades to EXPORT_RSA + +2.1.3 - Security update and OS support improvements + * Fixed various memory leaks in DTLS, including fixes for + CVE-2015-0206. + + * Added Application-Layer Protocol Negotiation (ALPN) support. + + * Removed GOST R 34.10-94 signature authentication. + + * Removed nonfunctional Netscape browser-hang workaround code. + + * Simplfied and refactored SSL/DTLS handshake code. + + * Added SHA256 Camellia cipher suites for TLS 1.2 from RFC 5932. + + * Hide timing info about padding errors during handshakes. + + * Improved libtls support for non-blocking sockets, added randomized + session ID contexts. Work is ongoing with this library - feedback + and potential use-cases are welcome. + + * Support building Windows DLLs. + Thanks to Jan Engelhard. + + * Packaged config wrapper for better compatibility with OpenSSL-based + build systems. + Thanks to @technion from github + + * Ensure the stack is marked non-executable for assembly sections. + Thanks to Anthony G. Bastile. + + * Enable extra compiler hardening flags by default, where applicable. + The default set of hardening features can vary by OS to OS, so + feedback is welcome on this. To disable the default hardening flags, + specify '--disable-hardening' during configure. + Thanks to Jim Barlow + + * Initial HP-UX support, tested with HP-UX 11.31 ia64 + Thanks to Kinichiro Inoguchi + + * Initial NetBSD support, tested with NetBSD 6.1.5 x86_64 + Imported from OpenNTPD, thanks to @gitisihara from github + +2.1.2 - Many new features and improvements + * Added reworked GOST cipher suite support + thanks to Dmitry Eremin-Solenikov + + * Enabled Camellia ciphers due to improved patent situation + + * Use builtin arc4random implementation on OS X and FreeBSD + this addresses some deficiencies in the native implementations of + these operating systems, see commit logs for more information + + * Added initial Windows mingw-w64 support (32 and 64-bit) + thanks to Song Dongsheng and others for code and feedback + + * Enabled assembly optimizations on x86_64 CPUs + supports Linux, *BSD, Solaris and OS X operating systems + thanks to Wouter Clarie for the initial implementation + + * Added no_ssl3/no_tls1_1/no_tls1_2 options to openssl(1) + + * Improved build infrastructure, 'make distcheck' now passes + this simplifies and speeds developer efficiency + thanks to Dmitry Eremin-Solenikov and Wouter Clarie + + * Allow conditional building of the libtls library + expect the API and ABI of the library to change + feedback is welcome + + * Fixes for more memory leaks, cleanups, etc. + +2.1.1 - Security update + * Address POODLE attack by disabling SSLv3 by default + + * Fix Eliptical Curve cipher selection bug + (https://github.com/libressl-portable/portable/issues/35) + +2.1.0 - First release from the OpenBSD 5.7 tree + * Added support for automatic ephemeral EC keys + + * Fixes for many memory leaks and overflows in error handlers + + * The TLS padding extension (that works around bugs in F5 terminators) is + off by default + + * support for getrandom(2) on Linux 3.17 + + * the NO_ASM macro is no longer being set, providing the first bits toward + enabling other assembly offloads. + +2.0.5 - Fixes for CVEs from OpenSSL 1.0.1i + * CVE-2014-3506 + * CVE-2014-3507 + * CVE-2014-3508 (partially vulnerable)he + * CVE-2014-3509 + * CVE-2014-3510 + * CVE-2014-3511 + * Synced LibreSSL Portable with the release version of OpenBSD 5.6 + +2.0.4 - Portability fixes, deleted unused SRP code + +2.0.3 - Portability fixes, improvements to fork detection + +2.0.2 - Address arc4random fork PID wraparound issues with pthread_atfork + +2.0.1 - Portability fixes: + * Removed -Werror and and other non-portable compiler flags + + * Allow setting OPENSSLDIR and ENGINSDIR + +2.0.0 - First release from the OpenBSD 5.6 tree + * Removal of many obsolete features and coding conventions from the OpenSSL + 1.0.1h source diff --git a/crypto/libressl/VERSION b/crypto/libressl/VERSION new file mode 100644 index 0000000000..b674b92354 --- /dev/null +++ b/crypto/libressl/VERSION @@ -0,0 +1,2 @@ +2.4.2 + diff --git a/crypto/libressl/apps/nc/atomicio.c b/crypto/libressl/apps/nc/atomicio.c new file mode 100644 index 0000000000..8ca68b45aa --- /dev/null +++ b/crypto/libressl/apps/nc/atomicio.c @@ -0,0 +1,67 @@ +/* $OpenBSD: atomicio.c,v 1.10 2011/01/08 00:47:19 jeremy Exp $ */ +/* + * Copyright (c) 2006 Damien Miller. All rights reserved. + * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. + * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. + * 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 +#include +#include + +#include "atomicio.h" + +/* + * ensure all of data on socket comes through. f==read || f==vwrite + */ +size_t +atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n) +{ + char *s = _s; + size_t pos = 0; + ssize_t res; + struct pollfd pfd; + + pfd.fd = fd; + pfd.events = f == read ? POLLIN : POLLOUT; + while (n > pos) { + res = (f) (fd, s + pos, n - pos); + switch (res) { + case -1: + if (errno == EINTR) + continue; + if ((errno == EAGAIN) || (errno == ENOBUFS)) { + (void)poll(&pfd, 1, -1); + continue; + } + return 0; + case 0: + errno = EPIPE; + return pos; + default: + pos += (size_t)res; + } + } + return (pos); +} diff --git a/crypto/libressl/apps/nc/atomicio.h b/crypto/libressl/apps/nc/atomicio.h new file mode 100644 index 0000000000..8edc3e8118 --- /dev/null +++ b/crypto/libressl/apps/nc/atomicio.h @@ -0,0 +1,39 @@ +/* $OpenBSD: atomicio.h,v 1.1 2005/05/24 20:13:28 avsm Exp $ */ + +/* + * Copyright (c) 2006 Damien Miller. All rights reserved. + * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. + * 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. + */ + +#ifndef _ATOMICIO_H +#define _ATOMICIO_H + +/* + * Ensure all of data on socket comes through. f==read || f==vwrite + */ +size_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t); + +#define vwrite (ssize_t (*)(int, void *, size_t))write + +#endif /* _ATOMICIO_H */ diff --git a/crypto/libressl/apps/nc/compat/accept4.c b/crypto/libressl/apps/nc/compat/accept4.c new file mode 100644 index 0000000000..278198baad --- /dev/null +++ b/crypto/libressl/apps/nc/compat/accept4.c @@ -0,0 +1,17 @@ +#include +#include + +int +accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) +{ + int rets = accept(s, addr, addrlen); + if (rets == -1) + return s; + + if (flags & SOCK_CLOEXEC) { + flags = fcntl(s, F_GETFD); + fcntl(rets, F_SETFD, flags | FD_CLOEXEC); + } + + return rets; +} diff --git a/crypto/libressl/apps/nc/compat/base64.c b/crypto/libressl/apps/nc/compat/base64.c new file mode 100644 index 0000000000..e90696df67 --- /dev/null +++ b/crypto/libressl/apps/nc/compat/base64.c @@ -0,0 +1,315 @@ +/* $OpenBSD: base64.c,v 1.8 2015/01/16 16:48:51 deraadt Exp $ */ + +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM 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. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +static const char Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char Pad64 = '='; + +/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) + The following encoding technique is taken from RFC 1521 by Borenstein + and Freed. It is reproduced here in a slightly edited form for + convenience. + + A 65-character subset of US-ASCII is used, enabling 6 bits to be + represented per printable character. (The extra 65th character, "=", + is used to signify a special processing function.) + + The encoding process represents 24-bit groups of input bits as output + strings of 4 encoded characters. Proceeding from left to right, a + 24-bit input group is formed by concatenating 3 8-bit input groups. + These 24 bits are then treated as 4 concatenated 6-bit groups, each + of which is translated into a single digit in the base64 alphabet. + + Each 6-bit group is used as an index into an array of 64 printable + characters. The character referenced by the index is placed in the + output string. + + Table 1: The Base64 Alphabet + + Value Encoding Value Encoding Value Encoding Value Encoding + 0 A 17 R 34 i 51 z + 1 B 18 S 35 j 52 0 + 2 C 19 T 36 k 53 1 + 3 D 20 U 37 l 54 2 + 4 E 21 V 38 m 55 3 + 5 F 22 W 39 n 56 4 + 6 G 23 X 40 o 57 5 + 7 H 24 Y 41 p 58 6 + 8 I 25 Z 42 q 59 7 + 9 J 26 a 43 r 60 8 + 10 K 27 b 44 s 61 9 + 11 L 28 c 45 t 62 + + 12 M 29 d 46 u 63 / + 13 N 30 e 47 v + 14 O 31 f 48 w (pad) = + 15 P 32 g 49 x + 16 Q 33 h 50 y + + Special processing is performed if fewer than 24 bits are available + at the end of the data being encoded. A full encoding quantum is + always completed at the end of a quantity. When fewer than 24 input + bits are available in an input group, zero bits are added (on the + right) to form an integral number of 6-bit groups. Padding at the + end of the data is performed using the '=' character. + + Since all base64 input is an integral number of octets, only the + ------------------------------------------------- + following cases can arise: + + (1) the final quantum of encoding input is an integral + multiple of 24 bits; here, the final unit of encoded + output will be an integral multiple of 4 characters + with no "=" padding, + (2) the final quantum of encoding input is exactly 8 bits; + here, the final unit of encoded output will be two + characters followed by two "=" padding characters, or + (3) the final quantum of encoding input is exactly 16 bits; + here, the final unit of encoded output will be three + characters followed by one "=" padding character. + */ + +int +b64_ntop(src, srclength, target, targsize) + u_char const *src; + size_t srclength; + char *target; + size_t targsize; +{ + size_t datalength = 0; + u_char input[3]; + u_char output[4]; + int i; + + while (2 < srclength) { + input[0] = *src++; + input[1] = *src++; + input[2] = *src++; + srclength -= 3; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + output[3] = input[2] & 0x3f; + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + target[datalength++] = Base64[output[2]]; + target[datalength++] = Base64[output[3]]; + } + + /* Now we worry about padding. */ + if (0 != srclength) { + /* Get what's left. */ + input[0] = input[1] = input[2] = '\0'; + for (i = 0; i < srclength; i++) + input[i] = *src++; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + if (srclength == 1) + target[datalength++] = Pad64; + else + target[datalength++] = Base64[output[2]]; + target[datalength++] = Pad64; + } + if (datalength >= targsize) + return (-1); + target[datalength] = '\0'; /* Returned value doesn't count \0. */ + return (datalength); +} + +/* skips all whitespace anywhere. + converts characters, four at a time, starting at (or after) + src from base - 64 numbers into three 8 bit bytes in the target area. + it returns the number of data bytes stored at the target, or -1 on error. + */ + +int +b64_pton(src, target, targsize) + char const *src; + u_char *target; + size_t targsize; +{ + int tarindex, state, ch; + u_char nextbyte; + char *pos; + + state = 0; + tarindex = 0; + + while ((ch = (unsigned char)*src++) != '\0') { + if (isspace(ch)) /* Skip whitespace anywhere. */ + continue; + + if (ch == Pad64) + break; + + pos = strchr(Base64, ch); + if (pos == 0) /* A non-base64 character. */ + return (-1); + + switch (state) { + case 0: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] = (pos - Base64) << 2; + } + state = 1; + break; + case 1: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 4; + nextbyte = ((pos - Base64) & 0x0f) << 4; + if (tarindex + 1 < targsize) + target[tarindex+1] = nextbyte; + else if (nextbyte) + return (-1); + } + tarindex++; + state = 2; + break; + case 2: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 2; + nextbyte = ((pos - Base64) & 0x03) << 6; + if (tarindex + 1 < targsize) + target[tarindex+1] = nextbyte; + else if (nextbyte) + return (-1); + } + tarindex++; + state = 3; + break; + case 3: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64); + } + tarindex++; + state = 0; + break; + } + } + + /* + * We are done decoding Base-64 chars. Let's see if we ended + * on a byte boundary, and/or with erroneous trailing characters. + */ + + if (ch == Pad64) { /* We got a pad char. */ + ch = (unsigned char)*src++; /* Skip it, get next. */ + switch (state) { + case 0: /* Invalid = in first position */ + case 1: /* Invalid = in second position */ + return (-1); + + case 2: /* Valid, means one byte of info */ + /* Skip any number of spaces. */ + for (; ch != '\0'; ch = (unsigned char)*src++) + if (!isspace(ch)) + break; + /* Make sure there is another trailing = sign. */ + if (ch != Pad64) + return (-1); + ch = (unsigned char)*src++; /* Skip the = */ + /* Fall through to "single trailing =" case. */ + /* FALLTHROUGH */ + + case 3: /* Valid, means two bytes of info */ + /* + * We know this char is an =. Is there anything but + * whitespace after it? + */ + for (; ch != '\0'; ch = (unsigned char)*src++) + if (!isspace(ch)) + return (-1); + + /* + * Now make sure for cases 2 and 3 that the "extra" + * bits that slopped past the last full byte were + * zeros. If we don't check them, they become a + * subliminal channel. + */ + if (target && tarindex < targsize && + target[tarindex] != 0) + return (-1); + } + } else { + /* + * We ended by seeing the end of the string. Make sure we + * have no partial bytes lying around. + */ + if (state != 0) + return (-1); + } + + return (tarindex); +} diff --git a/crypto/libressl/apps/nc/compat/readpassphrase.c b/crypto/libressl/apps/nc/compat/readpassphrase.c new file mode 100644 index 0000000000..f3aa24868e --- /dev/null +++ b/crypto/libressl/apps/nc/compat/readpassphrase.c @@ -0,0 +1,205 @@ +/* $OpenBSD: readpassphrase.c,v 1.22 2010/01/13 10:20:54 dtucker Exp $ */ + +/* + * Copyright (c) 2000-2002, 2007 Todd C. 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. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ + +/* OPENBSD ORIGINAL: lib/libc/gen/readpassphrase.c */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifndef _PATH_TTY +# define _PATH_TTY "/dev/tty" +#endif + +#ifdef TCSASOFT +# define _T_FLUSH (TCSAFLUSH|TCSASOFT) +#else +# define _T_FLUSH (TCSAFLUSH) +#endif + +/* SunOS 4.x which lacks _POSIX_VDISABLE, but has VDISABLE */ +#if !defined(_POSIX_VDISABLE) && defined(VDISABLE) +# define _POSIX_VDISABLE VDISABLE +#endif + +#ifndef _NSIG +# ifdef NSIG +# define _NSIG NSIG +# else +# define _NSIG 128 +# endif +#endif + +static volatile sig_atomic_t signo[_NSIG]; + +static void handler(int); + +char * +readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) +{ + ssize_t bytes_written = 0; + ssize_t nr; + int input, output, save_errno, i, need_restart; + char ch, *p, *end; + struct termios term, oterm; + struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm; + struct sigaction savetstp, savettin, savettou, savepipe; + + /* I suppose we could alloc on demand in this case (XXX). */ + if (bufsiz == 0) { + errno = EINVAL; + return(NULL); + } + +restart: + for (i = 0; i < _NSIG; i++) + signo[i] = 0; + nr = -1; + save_errno = 0; + need_restart = 0; + /* + * Read and write to /dev/tty if available. If not, read from + * stdin and write to stderr unless a tty is required. + */ + if ((flags & RPP_STDIN) || + (input = output = open(_PATH_TTY, O_RDWR)) == -1) { + if (flags & RPP_REQUIRE_TTY) { + errno = ENOTTY; + return(NULL); + } + input = STDIN_FILENO; + output = STDERR_FILENO; + } + + /* + * Catch signals that would otherwise cause the user to end + * up with echo turned off in the shell. Don't worry about + * things like SIGXCPU and SIGVTALRM for now. + */ + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; /* don't restart system calls */ + sa.sa_handler = handler; + (void)sigaction(SIGALRM, &sa, &savealrm); + (void)sigaction(SIGHUP, &sa, &savehup); + (void)sigaction(SIGINT, &sa, &saveint); + (void)sigaction(SIGPIPE, &sa, &savepipe); + (void)sigaction(SIGQUIT, &sa, &savequit); + (void)sigaction(SIGTERM, &sa, &saveterm); + (void)sigaction(SIGTSTP, &sa, &savetstp); + (void)sigaction(SIGTTIN, &sa, &savettin); + (void)sigaction(SIGTTOU, &sa, &savettou); + + /* Turn off echo if possible. */ + if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) { + memcpy(&term, &oterm, sizeof(term)); + if (!(flags & RPP_ECHO_ON)) + term.c_lflag &= ~(ECHO | ECHONL); +#ifdef VSTATUS + if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) + term.c_cc[VSTATUS] = _POSIX_VDISABLE; +#endif + (void)tcsetattr(input, _T_FLUSH, &term); + } else { + memset(&term, 0, sizeof(term)); + term.c_lflag |= ECHO; + memset(&oterm, 0, sizeof(oterm)); + oterm.c_lflag |= ECHO; + } + + /* No I/O if we are already backgrounded. */ + if (signo[SIGTTOU] != 1 && signo[SIGTTIN] != 1) { + if (!(flags & RPP_STDIN)) + bytes_written = write(output, prompt, strlen(prompt)); + end = buf + bufsiz - 1; + p = buf; + while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') { + if (p < end) { + if ((flags & RPP_SEVENBIT)) + ch &= 0x7f; + if (isalpha((unsigned char)ch)) { + if ((flags & RPP_FORCELOWER)) + ch = (char)tolower((unsigned char)ch); + if ((flags & RPP_FORCEUPPER)) + ch = (char)toupper((unsigned char)ch); + } + *p++ = ch; + } + } + *p = '\0'; + save_errno = errno; + if (!(term.c_lflag & ECHO)) + bytes_written = write(output, "\n", 1); + } + + (void) bytes_written; + + /* Restore old terminal settings and signals. */ + if (memcmp(&term, &oterm, sizeof(term)) != 0) { + while (tcsetattr(input, _T_FLUSH, &oterm) == -1 && + errno == EINTR) + continue; + } + (void)sigaction(SIGALRM, &savealrm, NULL); + (void)sigaction(SIGHUP, &savehup, NULL); + (void)sigaction(SIGINT, &saveint, NULL); + (void)sigaction(SIGQUIT, &savequit, NULL); + (void)sigaction(SIGPIPE, &savepipe, NULL); + (void)sigaction(SIGTERM, &saveterm, NULL); + (void)sigaction(SIGTSTP, &savetstp, NULL); + (void)sigaction(SIGTTIN, &savettin, NULL); + (void)sigaction(SIGTTOU, &savettou, NULL); + if (input != STDIN_FILENO) + (void)close(input); + + /* + * If we were interrupted by a signal, resend it to ourselves + * now that we have restored the signal handlers. + */ + for (i = 0; i < _NSIG; i++) { + if (signo[i]) { + kill(getpid(), i); + switch (i) { + case SIGTSTP: + case SIGTTIN: + case SIGTTOU: + need_restart = 1; + } + } + } + if (need_restart) + goto restart; + + if (save_errno) + errno = save_errno; + return(nr == -1 ? NULL : buf); +} + +static void handler(int s) +{ + signo[s] = 1; +} diff --git a/crypto/libressl/apps/nc/compat/socket.c b/crypto/libressl/apps/nc/compat/socket.c new file mode 100644 index 0000000000..fd699f9fd7 --- /dev/null +++ b/crypto/libressl/apps/nc/compat/socket.c @@ -0,0 +1,29 @@ +#define SOCKET_FLAGS_PRIV + +#include + +#ifdef NEED_SOCKET_FLAGS + +#include + +int +_socket(int domain, int type, int protocol) +{ + int s = socket(domain, type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK), protocol); + int flags; + if (s == -1) + return s; + + if (type & SOCK_CLOEXEC) { + flags = fcntl(s, F_GETFD); + fcntl(s, F_SETFD, flags | FD_CLOEXEC); + } + + if (type & SOCK_NONBLOCK) { + flags = fcntl(s, F_GETFL); + fcntl(s, F_SETFL, flags | O_NONBLOCK); + } + return s; +} + +#endif diff --git a/crypto/libressl/apps/nc/compat/strtonum.c b/crypto/libressl/apps/nc/compat/strtonum.c new file mode 100644 index 0000000000..1aeee3467b --- /dev/null +++ b/crypto/libressl/apps/nc/compat/strtonum.c @@ -0,0 +1,65 @@ +/* $OpenBSD: strtonum.c,v 1.7 2013/04/17 18:40:58 tedu Exp $ */ + +/* + * Copyright (c) 2004 Ted Unangst and Todd Miller + * All rights reserved. + * + * 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 +#include +#include + +#define INVALID 1 +#define TOOSMALL 2 +#define TOOLARGE 3 + +long long +strtonum(const char *numstr, long long minval, long long maxval, + const char **errstrp) +{ + long long ll = 0; + int error = 0; + char *ep; + struct errval { + const char *errstr; + int err; + } ev[4] = { + { NULL, 0 }, + { "invalid", EINVAL }, + { "too small", ERANGE }, + { "too large", ERANGE }, + }; + + ev[0].err = errno; + errno = 0; + if (minval > maxval) { + error = INVALID; + } else { + ll = strtoll(numstr, &ep, 10); + if (numstr == ep || *ep != '\0') + error = INVALID; + else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) + error = TOOSMALL; + else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) + error = TOOLARGE; + } + if (errstrp != NULL) + *errstrp = ev[error].errstr; + errno = ev[error].err; + if (error) + ll = 0; + + return (ll); +} diff --git a/crypto/libressl/apps/nc/compat/sys/socket.h b/crypto/libressl/apps/nc/compat/sys/socket.h new file mode 100644 index 0000000000..13eb380b42 --- /dev/null +++ b/crypto/libressl/apps/nc/compat/sys/socket.h @@ -0,0 +1,31 @@ +/* + * Public domain + * sys/socket.h compatibility shim + */ + +#ifndef _WIN32 +#include_next + +#if !defined(SOCK_NONBLOCK) || !defined(SOCK_CLOEXEC) +#define NEED_SOCKET_FLAGS +int _socket(int domain, int type, int protocol); +#ifndef SOCKET_FLAGS_PRIV +#define socket(d, t, p) _socket(d, t, p) +#endif +#endif + +#ifndef SOCK_NONBLOCK +#define SOCK_NONBLOCK 0x4000 /* set O_NONBLOCK */ +#endif + +#ifndef SOCK_CLOEXEC +#define SOCK_CLOEXEC 0x8000 /* set FD_CLOEXEC */ +#endif + +#ifndef HAVE_ACCEPT4 +int accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags); +#endif + +#else +#include +#endif diff --git a/crypto/libressl/apps/nc/nc.1 b/crypto/libressl/apps/nc/nc.1 new file mode 100644 index 0000000000..e9d3499ffa --- /dev/null +++ b/crypto/libressl/apps/nc/nc.1 @@ -0,0 +1,533 @@ +.\" $OpenBSD: nc.1,v 1.73 2016/06/28 17:35:14 jca Exp $ +.\" +.\" Copyright (c) 1996 David Sacerdote +.\" 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. 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. +.\" +.Dd $Mdocdate: June 28 2016 $ +.Dt NC 1 +.Os +.Sh NAME +.Nm nc +.Nd arbitrary TCP and UDP connections and listens +.Sh SYNOPSIS +.Nm nc +.Op Fl 46cDdFhklNnrStUuvz +.Op Fl C Ar certfile +.Op Fl e Ar name +.Op Fl H Ar hash +.Op Fl I Ar length +.Op Fl i Ar interval +.Op Fl K Ar keyfile +.Op Fl M Ar ttl +.Op Fl m Ar minttl +.Op Fl O Ar length +.Op Fl P Ar proxy_username +.Op Fl p Ar source_port +.Op Fl R Ar CAfile +.Op Fl s Ar source +.Op Fl T Ar keyword +.Op Fl V Ar rtable +.Op Fl w Ar timeout +.Op Fl X Ar proxy_protocol +.Op Fl x Ar proxy_address Ns Op : Ns Ar port +.Op Ar destination +.Op Ar port +.Sh DESCRIPTION +The +.Nm +(or +.Nm netcat ) +utility is used for just about anything under the sun involving TCP, +UDP, or +.Ux Ns -domain +sockets. +It can open TCP connections, send UDP packets, listen on arbitrary +TCP and UDP ports, do port scanning, and deal with both IPv4 and +IPv6. +Unlike +.Xr telnet 1 , +.Nm +scripts nicely, and separates error messages onto standard error instead +of sending them to standard output, as +.Xr telnet 1 +does with some. +.Pp +Common uses include: +.Pp +.Bl -bullet -offset indent -compact +.It +simple TCP proxies +.It +shell-script based HTTP clients and servers +.It +network daemon testing +.It +a SOCKS or HTTP ProxyCommand for +.Xr ssh 1 +.It +and much, much more +.El +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl 4 +Forces +.Nm +to use IPv4 addresses only. +.It Fl 6 +Forces +.Nm +to use IPv6 addresses only. +.It Fl C Ar certfile +Specifies the filename from which the public key part of the TLS +certificate is loaded, in PEM format. +May only be used with TLS. +.It Fl c +If using a TCP socket to connect or listen, use TLS. +Illegal if not using TCP sockets. +.It Fl D +Enable debugging on the socket. +.It Fl d +Do not attempt to read from stdin. +.It Fl e Ar name +Specify the name that must be present in the peer certificate when using TLS. +Illegal if not using TLS. +.It Fl F +Pass the first connected socket using +.Xr sendmsg 2 +to stdout and exit. +This is useful in conjunction with +.Fl X +to have +.Nm +perform connection setup with a proxy but then leave the rest of the +connection to another program (e.g.\& +.Xr ssh 1 +using the +.Xr ssh_config 5 +.Cm ProxyUseFdpass +option). +.It Fl H Ar hash +Specifies the required hash string of the peer certificate when using TLS. +The string format required is that used by +.Xr tls_peer_cert_hash 3 . +Illegal if not using TLS, and may not be used with -T noverify. +.It Fl h +Prints out +.Nm +help. +.It Fl I Ar length +Specifies the size of the TCP receive buffer. +.It Fl i Ar interval +Specifies a delay time interval between lines of text sent and received. +Also causes a delay time between connections to multiple ports. +.It Fl K Ar keyfile +Specifies the filename from which the private key +is loaded in PEM format. +May only be used with TLS. +.It Fl k +Forces +.Nm +to stay listening for another connection after its current connection +is completed. +It is an error to use this option without the +.Fl l +option. +When used together with the +.Fl u +option, the server socket is not connected and it can receive UDP datagrams from +multiple hosts. +.It Fl l +Used to specify that +.Nm +should listen for an incoming connection rather than initiate a +connection to a remote host. +It is an error to use this option in conjunction with the +.Fl p , +.Fl s , +or +.Fl z +options. +Additionally, any timeouts specified with the +.Fl w +option are ignored. +.It Fl M Ar ttl +Set the TTL / hop limit of outgoing packets. +.It Fl m Ar minttl +Ask the kernel to drop incoming packets whose TTL / hop limit is under +.Ar minttl . +.It Fl N +.Xr shutdown 2 +the network socket after EOF on the input. +Some servers require this to finish their work. +.It Fl n +Do not do any DNS or service lookups on any specified addresses, +hostnames or ports. +.It Fl O Ar length +Specifies the size of the TCP send buffer. +.It Fl P Ar proxy_username +Specifies a username to present to a proxy server that requires authentication. +If no username is specified then authentication will not be attempted. +Proxy authentication is only supported for HTTP CONNECT proxies at present. +.It Fl p Ar source_port +Specifies the source port +.Nm +should use, subject to privilege restrictions and availability. +It is an error to use this option in conjunction with the +.Fl l +option. +.It Fl R Ar CAfile +Specifies the filename from which the root CA bundle for certificate +verification is loaded, in PEM format. +Illegal if not using TLS. +The default is +.Pa /etc/ssl/cert.pem . +.It Fl r +Specifies that source and/or destination ports should be chosen randomly +instead of sequentially within a range or in the order that the system +assigns them. +.It Fl S +Enables the RFC 2385 TCP MD5 signature option. +.It Fl s Ar source +Specifies the IP of the interface which is used to send the packets. +For +.Ux Ns -domain +datagram sockets, specifies the local temporary socket file +to create and use so that datagrams can be received. +It is an error to use this option in conjunction with the +.Fl l +option. +.It Fl T Ar keyword +Change IPv4 TOS value or TLS options. +For TLS options +.Ar keyword +may be one of +.Ar tlslegacy , +which allows legacy TLS protocols; +.Ar noverify , +which disables certificate verification; +.Ar noname , +which disables certificate name checking; or +.Ar clientcert , +which requires a client certificate on incoming connections. +It is illegal to specify TLS options if not using TLS. +.Pp +For IPv4 TOS value +.Ar keyword +may be one of +.Ar critical , +.Ar inetcontrol , +.Ar lowdelay , +.Ar netcontrol , +.Ar throughput , +.Ar reliability , +or one of the DiffServ Code Points: +.Ar ef , +.Ar af11 ... af43 , +.Ar cs0 ... cs7 ; +or a number in either hex or decimal. +.It Fl t +Causes +.Nm +to send RFC 854 DON'T and WON'T responses to RFC 854 DO and WILL requests. +This makes it possible to use +.Nm +to script telnet sessions. +.It Fl U +Specifies to use +.Ux Ns -domain +sockets. +.It Fl u +Use UDP instead of the default option of TCP. +For +.Ux Ns -domain +sockets, use a datagram socket instead of a stream socket. +If a +.Ux Ns -domain +socket is used, a temporary receiving socket is created in +.Pa /tmp +unless the +.Fl s +flag is given. +.It Fl V Ar rtable +Set the routing table to be used. +.It Fl v +Have +.Nm +give more verbose output. +.It Fl w Ar timeout +Connections which cannot be established or are idle timeout after +.Ar timeout +seconds. +The +.Fl w +flag has no effect on the +.Fl l +option, i.e.\& +.Nm +will listen forever for a connection, with or without the +.Fl w +flag. +The default is no timeout. +.It Fl X Ar proxy_protocol +Requests that +.Nm +should use the specified protocol when talking to the proxy server. +Supported protocols are +.Dq 4 +(SOCKS v.4), +.Dq 5 +(SOCKS v.5) +and +.Dq connect +(HTTPS proxy). +If the protocol is not specified, SOCKS version 5 is used. +.It Fl x Ar proxy_address Ns Op : Ns Ar port +Requests that +.Nm +should connect to +.Ar destination +using a proxy at +.Ar proxy_address +and +.Ar port . +If +.Ar port +is not specified, the well-known port for the proxy protocol is used (1080 +for SOCKS, 3128 for HTTPS). +.It Fl z +Specifies that +.Nm +should just scan for listening daemons, without sending any data to them. +It is an error to use this option in conjunction with the +.Fl l +option. +.El +.Pp +.Ar destination +can be a numerical IP address or a symbolic hostname +(unless the +.Fl n +option is given). +In general, a destination must be specified, +unless the +.Fl l +option is given +(in which case the local host is used). +For +.Ux Ns -domain +sockets, a destination is required and is the socket path to connect to +(or listen on if the +.Fl l +option is given). +.Pp +.Ar port +can be a specified as a numeric port number, or as a service name. +Ports may be specified in a range of the form nn-mm. +In general, +a destination port must be specified, +unless the +.Fl U +option is given. +.Sh CLIENT/SERVER MODEL +It is quite simple to build a very basic client/server model using +.Nm . +On one console, start +.Nm +listening on a specific port for a connection. +For example: +.Pp +.Dl $ nc -l 1234 +.Pp +.Nm +is now listening on port 1234 for a connection. +On a second console +.Pq or a second machine , +connect to the machine and port being listened on: +.Pp +.Dl $ nc 127.0.0.1 1234 +.Pp +There should now be a connection between the ports. +Anything typed at the second console will be concatenated to the first, +and vice-versa. +After the connection has been set up, +.Nm +does not really care which side is being used as a +.Sq server +and which side is being used as a +.Sq client . +The connection may be terminated using an +.Dv EOF +.Pq Sq ^D . +.Sh DATA TRANSFER +The example in the previous section can be expanded to build a +basic data transfer model. +Any information input into one end of the connection will be output +to the other end, and input and output can be easily captured in order to +emulate file transfer. +.Pp +Start by using +.Nm +to listen on a specific port, with output captured into a file: +.Pp +.Dl $ nc -l 1234 \*(Gt filename.out +.Pp +Using a second machine, connect to the listening +.Nm +process, feeding it the file which is to be transferred: +.Pp +.Dl $ nc -N host.example.com 1234 \*(Lt filename.in +.Pp +After the file has been transferred, the connection will close automatically. +.Sh TALKING TO SERVERS +It is sometimes useful to talk to servers +.Dq by hand +rather than through a user interface. +It can aid in troubleshooting, +when it might be necessary to verify what data a server is sending +in response to commands issued by the client. +For example, to retrieve the home page of a web site: +.Bd -literal -offset indent +$ printf "GET / HTTP/1.0\er\en\er\en" | nc host.example.com 80 +.Ed +.Pp +Note that this also displays the headers sent by the web server. +They can be filtered, using a tool such as +.Xr sed 1 , +if necessary. +.Pp +More complicated examples can be built up when the user knows the format +of requests required by the server. +As another example, an email may be submitted to an SMTP server using: +.Bd -literal -offset indent +$ nc localhost 25 \*(Lt\*(Lt EOF +HELO host.example.com +MAIL FROM:\*(Ltuser@host.example.com\*(Gt +RCPT TO:\*(Ltuser2@host.example.com\*(Gt +DATA +Body of email. +\&. +QUIT +EOF +.Ed +.Sh PORT SCANNING +It may be useful to know which ports are open and running services on +a target machine. +The +.Fl z +flag can be used to tell +.Nm +to report open ports, +rather than initiate a connection. +For example: +.Bd -literal -offset indent +$ nc -z host.example.com 20-30 +Connection to host.example.com 22 port [tcp/ssh] succeeded! +Connection to host.example.com 25 port [tcp/smtp] succeeded! +.Ed +.Pp +The port range was specified to limit the search to ports 20 \- 30. +.Pp +Alternatively, it might be useful to know which server software +is running, and which versions. +This information is often contained within the greeting banners. +In order to retrieve these, it is necessary to first make a connection, +and then break the connection when the banner has been retrieved. +This can be accomplished by specifying a small timeout with the +.Fl w +flag, or perhaps by issuing a +.Qq Dv QUIT +command to the server: +.Bd -literal -offset indent +$ echo "QUIT" | nc host.example.com 20-30 +SSH-1.99-OpenSSH_3.6.1p2 +Protocol mismatch. +220 host.example.com IMS SMTP Receiver Version 0.84 Ready +.Ed +.Sh EXAMPLES +Open a TCP connection to port 42 of host.example.com, using port 31337 as +the source port, with a timeout of 5 seconds: +.Pp +.Dl $ nc -p 31337 -w 5 host.example.com 42 +.Pp +Open a TCP connection to port 443 of www.google.ca, and negotiate TLS. +Check for a different name in the certificate for validation. +.Pp +.Dl $ nc -v -c -e adsf.au.doubleclick.net www.google.ca 443 +.Pp +Open a UDP connection to port 53 of host.example.com: +.Pp +.Dl $ nc -u host.example.com 53 +.Pp +Open a TCP connection to port 42 of host.example.com using 10.1.2.3 as the +IP for the local end of the connection: +.Pp +.Dl $ nc -s 10.1.2.3 host.example.com 42 +.Pp +Create and listen on a +.Ux Ns -domain +stream socket: +.Pp +.Dl $ nc -lU /var/tmp/dsocket +.Pp +Connect to port 42 of host.example.com via an HTTP proxy at 10.2.3.4, +port 8080. +This example could also be used by +.Xr ssh 1 ; +see the +.Cm ProxyCommand +directive in +.Xr ssh_config 5 +for more information. +.Pp +.Dl $ nc -x10.2.3.4:8080 -Xconnect host.example.com 42 +.Pp +The same example again, this time enabling proxy authentication with username +.Dq ruser +if the proxy requires it: +.Pp +.Dl $ nc -x10.2.3.4:8080 -Xconnect -Pruser host.example.com 42 +.Sh SEE ALSO +.Xr cat 1 , +.Xr ssh 1 +.Sh AUTHORS +Original implementation by *Hobbit* +.Aq Mt hobbit@avian.org . +.br +Rewritten with IPv6 support by +.An Eric Jackson Aq Mt ericj@monkey.org . +.Sh CAVEATS +UDP port scans using the +.Fl uz +combination of flags will always report success irrespective of +the target machine's state. +However, +in conjunction with a traffic sniffer either on the target machine +or an intermediary device, +the +.Fl uz +combination could be useful for communications diagnostics. +Note that the amount of UDP traffic generated may be limited either +due to hardware resources and/or configuration settings. diff --git a/crypto/libressl/apps/nc/netcat.c b/crypto/libressl/apps/nc/netcat.c new file mode 100644 index 0000000000..cdb2db277e --- /dev/null +++ b/crypto/libressl/apps/nc/netcat.c @@ -0,0 +1,1676 @@ +/* $OpenBSD: netcat.c,v 1.159 2016/07/07 14:09:44 jsing Exp $ */ +/* + * Copyright (c) 2001 Eric Jackson + * Copyright (c) 2015 Bob Beck. 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. 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. + */ + +/* + * Re-written nc(1) for OpenBSD. Original implementation by + * *Hobbit* . + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "atomicio.h" + +#define PORT_MAX 65535 +#define UNIX_DG_TMP_SOCKET_SIZE 19 + +#define POLL_STDIN 0 +#define POLL_NETOUT 1 +#define POLL_NETIN 2 +#define POLL_STDOUT 3 +#define BUFSIZE 16384 +#ifndef DEFAULT_CA_FILE +#define DEFAULT_CA_FILE "/etc/ssl/cert.pem" +#endif + +#define TLS_LEGACY (1 << 1) +#define TLS_NOVERIFY (1 << 2) +#define TLS_NONAME (1 << 3) +#define TLS_CCERT (1 << 4) + +/* Command Line Options */ +int dflag; /* detached, no stdin */ +int Fflag; /* fdpass sock to stdout */ +unsigned int iflag; /* Interval Flag */ +int kflag; /* More than one connect */ +int lflag; /* Bind to local port */ +int Nflag; /* shutdown() network socket */ +int nflag; /* Don't do name look up */ +char *Pflag; /* Proxy username */ +char *pflag; /* Localport flag */ +int rflag; /* Random ports flag */ +char *sflag; /* Source Address */ +int tflag; /* Telnet Emulation */ +int uflag; /* UDP - Default to TCP */ +int vflag; /* Verbosity */ +int xflag; /* Socks proxy */ +int zflag; /* Port Scan Flag */ +int Dflag; /* sodebug */ +int Iflag; /* TCP receive buffer size */ +int Oflag; /* TCP send buffer size */ +#ifdef TCP_MD5SIG +int Sflag; /* TCP MD5 signature option */ +#endif +int Tflag = -1; /* IP Type of Service */ +#ifdef SO_RTABLE +int rtableid = -1; +#endif + +int usetls; /* use TLS */ +char *Cflag; /* Public cert file */ +char *Kflag; /* Private key file */ +char *Rflag = DEFAULT_CA_FILE; /* Root CA file */ +int tls_cachanged; /* Using non-default CA file */ +int TLSopt; /* TLS options */ +char *tls_expectname; /* required name in peer cert */ +char *tls_expecthash; /* required hash of peer cert */ +uint8_t *cacert; +size_t cacertlen; +uint8_t *privkey; +size_t privkeylen; +uint8_t *pubcert; +size_t pubcertlen; + +int timeout = -1; +int family = AF_UNSPEC; +char *portlist[PORT_MAX+1]; +char *unix_dg_tmp_socket; +int ttl = -1; +int minttl = -1; + +void atelnet(int, unsigned char *, unsigned int); +void build_ports(char *); +void help(void); +int local_listen(char *, char *, struct addrinfo); +void readwrite(int, struct tls *); +void fdpass(int nfd) __attribute__((noreturn)); +int remote_connect(const char *, const char *, struct addrinfo); +int timeout_connect(int, const struct sockaddr *, socklen_t); +int socks_connect(const char *, const char *, struct addrinfo, + const char *, const char *, struct addrinfo, int, const char *); +int udptest(int); +int unix_bind(char *, int); +int unix_connect(char *); +int unix_listen(char *); +void set_common_sockopts(int, int); +int map_tos(char *, int *); +int map_tls(char *, int *); +void report_connect(const struct sockaddr *, socklen_t, char *); +void report_tls(struct tls *tls_ctx, char * host, char *tls_expectname); +void usage(int); +ssize_t drainbuf(int, unsigned char *, size_t *, struct tls *); +ssize_t fillbuf(int, unsigned char *, size_t *, struct tls *); +void tls_setup_client(struct tls *, int, char *); +struct tls *tls_setup_server(struct tls *, int, char *); + +int +main(int argc, char *argv[]) +{ + int ch, s = -1, ret, socksv; + char *host, *uport; + struct addrinfo hints; + struct servent *sv; + socklen_t len; + struct sockaddr_storage cliaddr; + char *proxy = NULL; + const char *errstr, *proxyhost = "", *proxyport = NULL; + struct addrinfo proxyhints; + char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE]; + struct tls_config *tls_cfg = NULL; + struct tls *tls_ctx = NULL; + + ret = 1; + socksv = 5; + host = NULL; + uport = NULL; + sv = NULL; + + signal(SIGPIPE, SIG_IGN); + + while ((ch = getopt(argc, argv, + "46C:cDde:FH:hI:i:K:klM:m:NnO:P:p:R:rSs:T:tUuV:vw:X:x:z")) != -1) { + switch (ch) { + case '4': + family = AF_INET; + break; + case '6': + family = AF_INET6; + break; + case 'U': + family = AF_UNIX; + break; + case 'X': + if (strcasecmp(optarg, "connect") == 0) + socksv = -1; /* HTTP proxy CONNECT */ + else if (strcmp(optarg, "4") == 0) + socksv = 4; /* SOCKS v.4 */ + else if (strcmp(optarg, "5") == 0) + socksv = 5; /* SOCKS v.5 */ + else + errx(1, "unsupported proxy protocol"); + break; + case 'C': + Cflag = optarg; + break; + case 'c': + usetls = 1; + break; + case 'd': + dflag = 1; + break; + case 'e': + tls_expectname = optarg; + break; + case 'F': + Fflag = 1; + break; + case 'H': + tls_expecthash = optarg; + break; + case 'h': + help(); + break; + case 'i': + iflag = strtonum(optarg, 0, UINT_MAX, &errstr); + if (errstr) + errx(1, "interval %s: %s", errstr, optarg); + break; + case 'K': + Kflag = optarg; + break; + case 'k': + kflag = 1; + break; + case 'l': + lflag = 1; + break; + case 'M': + ttl = strtonum(optarg, 0, 255, &errstr); + if (errstr) + errx(1, "ttl is %s", errstr); + break; + case 'm': + minttl = strtonum(optarg, 0, 255, &errstr); + if (errstr) + errx(1, "minttl is %s", errstr); + break; + case 'N': + Nflag = 1; + break; + case 'n': + nflag = 1; + break; + case 'P': + Pflag = optarg; + break; + case 'p': + pflag = optarg; + break; + case 'R': + tls_cachanged = 1; + Rflag = optarg; + break; + case 'r': + rflag = 1; + break; + case 's': + sflag = optarg; + break; + case 't': + tflag = 1; + break; + case 'u': + uflag = 1; + break; +#ifdef SO_RTABLE + case 'V': + rtableid = (int)strtonum(optarg, 0, + RT_TABLEID_MAX, &errstr); + if (errstr) + errx(1, "rtable %s: %s", errstr, optarg); + break; +#endif + case 'v': + vflag = 1; + break; + case 'w': + timeout = strtonum(optarg, 0, INT_MAX / 1000, &errstr); + if (errstr) + errx(1, "timeout %s: %s", errstr, optarg); + timeout *= 1000; + break; + case 'x': + xflag = 1; + if ((proxy = strdup(optarg)) == NULL) + err(1, NULL); + break; + case 'z': + zflag = 1; + break; + case 'D': + Dflag = 1; + break; + case 'I': + Iflag = strtonum(optarg, 1, 65536 << 14, &errstr); + if (errstr != NULL) + errx(1, "TCP receive window %s: %s", + errstr, optarg); + break; + case 'O': + Oflag = strtonum(optarg, 1, 65536 << 14, &errstr); + if (errstr != NULL) + errx(1, "TCP send window %s: %s", + errstr, optarg); + break; +#ifdef TCP_MD5SIG + case 'S': + Sflag = 1; + break; +#endif + case 'T': + errstr = NULL; + errno = 0; + if (map_tos(optarg, &Tflag)) + break; + if (map_tls(optarg, &TLSopt)) + break; + if (strlen(optarg) > 1 && optarg[0] == '0' && + optarg[1] == 'x') + Tflag = (int)strtol(optarg, NULL, 16); + else + Tflag = (int)strtonum(optarg, 0, 255, + &errstr); + if (Tflag < 0 || Tflag > 255 || errstr || errno) + errx(1, "illegal tos/tls value %s", optarg); + break; + default: + usage(1); + } + } + argc -= optind; + argv += optind; + +#ifdef SO_RTABLE + if (rtableid >= 0) + if (setrtable(rtableid) == -1) + err(1, "setrtable"); +#endif + + if (family == AF_UNIX) { + if (pledge("stdio rpath wpath cpath tmppath unix", NULL) == -1) + err(1, "pledge"); + } else if (Fflag) { + if (Pflag) { + if (pledge("stdio inet dns sendfd tty", NULL) == -1) + err(1, "pledge"); + } else if (pledge("stdio inet dns sendfd", NULL) == -1) + err(1, "pledge"); + } else if (Pflag) { + if (pledge("stdio inet dns tty", NULL) == -1) + err(1, "pledge"); + } else if (usetls) { + if (pledge("stdio rpath inet dns", NULL) == -1) + err(1, "pledge"); + } else if (pledge("stdio inet dns", NULL) == -1) + err(1, "pledge"); + + /* Cruft to make sure options are clean, and used properly. */ + if (argv[0] && !argv[1] && family == AF_UNIX) { + host = argv[0]; + uport = NULL; + } else if (argv[0] && !argv[1]) { + if (!lflag) + usage(1); + uport = argv[0]; + host = NULL; + } else if (argv[0] && argv[1]) { + host = argv[0]; + uport = argv[1]; + } else + usage(1); + + if (lflag && sflag) + errx(1, "cannot use -s and -l"); + if (lflag && pflag) + errx(1, "cannot use -p and -l"); + if (lflag && zflag) + errx(1, "cannot use -z and -l"); + if (!lflag && kflag) + errx(1, "must use -l with -k"); + if (uflag && usetls) + errx(1, "cannot use -c and -u"); + if ((family == AF_UNIX) && usetls) + errx(1, "cannot use -c and -U"); + if ((family == AF_UNIX) && Fflag) + errx(1, "cannot use -F and -U"); + if (Fflag && usetls) + errx(1, "cannot use -c and -F"); + if (TLSopt && !usetls) + errx(1, "you must specify -c to use TLS options"); + if (Cflag && !usetls) + errx(1, "you must specify -c to use -C"); + if (Kflag && !usetls) + errx(1, "you must specify -c to use -K"); + if (tls_cachanged && !usetls) + errx(1, "you must specify -c to use -R"); + if (tls_expecthash && !usetls) + errx(1, "you must specify -c to use -H"); + if (tls_expectname && !usetls) + errx(1, "you must specify -c to use -e"); + + /* Get name of temporary socket for unix datagram client */ + if ((family == AF_UNIX) && uflag && !lflag) { + if (sflag) { + unix_dg_tmp_socket = sflag; + } else { + strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc.XXXXXXXXXX", + UNIX_DG_TMP_SOCKET_SIZE); + if (mktemp(unix_dg_tmp_socket_buf) == NULL) + err(1, "mktemp"); + unix_dg_tmp_socket = unix_dg_tmp_socket_buf; + } + } + + /* Initialize addrinfo structure. */ + if (family != AF_UNIX) { + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = family; + hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; + hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; + if (nflag) + hints.ai_flags |= AI_NUMERICHOST; + } + + if (xflag) { + if (uflag) + errx(1, "no proxy support for UDP mode"); + + if (lflag) + errx(1, "no proxy support for listen"); + + if (family == AF_UNIX) + errx(1, "no proxy support for unix sockets"); + + /* XXX IPv6 transport to proxy would probably work */ + if (family == AF_INET6) + errx(1, "no proxy support for IPv6"); + + if (sflag) + errx(1, "no proxy support for local source address"); + + proxyhost = strsep(&proxy, ":"); + proxyport = proxy; + + memset(&proxyhints, 0, sizeof(struct addrinfo)); + proxyhints.ai_family = family; + proxyhints.ai_socktype = SOCK_STREAM; + proxyhints.ai_protocol = IPPROTO_TCP; + if (nflag) + proxyhints.ai_flags |= AI_NUMERICHOST; + } + + if (usetls) { + if (Rflag && (cacert = tls_load_file(Rflag, &cacertlen, NULL)) == NULL) + errx(1, "unable to load root CA file %s", Rflag); + if (Cflag && (pubcert = tls_load_file(Cflag, &pubcertlen, NULL)) == NULL) + errx(1, "unable to load TLS certificate file %s", Cflag); + if (Kflag && (privkey = tls_load_file(Kflag, &privkeylen, NULL)) == NULL) + errx(1, "unable to load TLS key file %s", Kflag); + + if (Pflag) { + if (pledge("stdio inet dns tty", NULL) == -1) + err(1, "pledge"); + } else if (pledge("stdio inet dns", NULL) == -1) + err(1, "pledge"); + + if (tls_init() == -1) + errx(1, "unable to initialize TLS"); + if ((tls_cfg = tls_config_new()) == NULL) + errx(1, "unable to allocate TLS config"); + if (Rflag && tls_config_set_ca_mem(tls_cfg, cacert, cacertlen) == -1) + errx(1, "unable to set root CA file %s", Rflag); + if (Cflag && tls_config_set_cert_mem(tls_cfg, pubcert, pubcertlen) == -1) + errx(1, "unable to set TLS certificate file %s", Cflag); + if (Kflag && tls_config_set_key_mem(tls_cfg, privkey, privkeylen) == -1) + errx(1, "unable to set TLS key file %s", Kflag); + if (TLSopt & TLS_LEGACY) { + tls_config_set_protocols(tls_cfg, TLS_PROTOCOLS_ALL); + tls_config_set_ciphers(tls_cfg, "all"); + } + if (!lflag && (TLSopt & TLS_CCERT)) + errx(1, "clientcert is only valid with -l"); + if (TLSopt & TLS_NONAME) + tls_config_insecure_noverifyname(tls_cfg); + if (TLSopt & TLS_NOVERIFY) { + if (tls_expecthash != NULL) + errx(1, "-H and -T noverify may not be used" + "together"); + tls_config_insecure_noverifycert(tls_cfg); + } else { + if (Rflag && access(Rflag, R_OK) == -1) + errx(1, "unable to find root CA file %s", Rflag); + } + } + if (lflag) { + struct tls *tls_cctx = NULL; + int connfd; + ret = 0; + + if (family == AF_UNIX) { + if (uflag) + s = unix_bind(host, 0); + else + s = unix_listen(host); + } + + if (usetls) { + tls_config_verify_client_optional(tls_cfg); + if ((tls_ctx = tls_server()) == NULL) + errx(1, "tls server creation failed"); + if (tls_configure(tls_ctx, tls_cfg) == -1) + errx(1, "tls configuration failed (%s)", + tls_error(tls_ctx)); + } + /* Allow only one connection at a time, but stay alive. */ + for (;;) { + if (family != AF_UNIX) + s = local_listen(host, uport, hints); + if (s < 0) + err(1, NULL); + /* + * For UDP and -k, don't connect the socket, let it + * receive datagrams from multiple socket pairs. + */ + if (uflag && kflag) + readwrite(s, NULL); + /* + * For UDP and not -k, we will use recvfrom() initially + * to wait for a caller, then use the regular functions + * to talk to the caller. + */ + else if (uflag && !kflag) { + int rv, plen; + char buf[16384]; + struct sockaddr_storage z; + + len = sizeof(z); + plen = 2048; + rv = recvfrom(s, buf, plen, MSG_PEEK, + (struct sockaddr *)&z, &len); + if (rv < 0) + err(1, "recvfrom"); + + rv = connect(s, (struct sockaddr *)&z, len); + if (rv < 0) + err(1, "connect"); + + if (vflag) + report_connect((struct sockaddr *)&z, len, NULL); + + readwrite(s, NULL); + } else { + len = sizeof(cliaddr); + connfd = accept4(s, (struct sockaddr *)&cliaddr, + &len, SOCK_NONBLOCK); + if (connfd == -1) { + /* For now, all errnos are fatal */ + err(1, "accept"); + } + if (vflag) + report_connect((struct sockaddr *)&cliaddr, len, + family == AF_UNIX ? host : NULL); + if ((usetls) && + (tls_cctx = tls_setup_server(tls_ctx, connfd, host))) + readwrite(connfd, tls_cctx); + if (!usetls) + readwrite(connfd, NULL); + if (tls_cctx) { + int i; + + do { + i = tls_close(tls_cctx); + } while (i == TLS_WANT_POLLIN || + i == TLS_WANT_POLLOUT); + tls_free(tls_cctx); + tls_cctx = NULL; + } + close(connfd); + } + if (family != AF_UNIX) + close(s); + else if (uflag) { + if (connect(s, NULL, 0) < 0) + err(1, "connect"); + } + + if (!kflag) + break; + } + } else if (family == AF_UNIX) { + ret = 0; + + if ((s = unix_connect(host)) > 0 && !zflag) { + readwrite(s, NULL); + close(s); + } else + ret = 1; + + if (uflag) + unlink(unix_dg_tmp_socket); + exit(ret); + + } else { + int i = 0; + + /* Construct the portlist[] array. */ + build_ports(uport); + + /* Cycle through portlist, connecting to each port. */ + for (s = -1, i = 0; portlist[i] != NULL; i++) { + if (s != -1) + close(s); + + if (usetls) { + if ((tls_ctx = tls_client()) == NULL) + errx(1, "tls client creation failed"); + if (tls_configure(tls_ctx, tls_cfg) == -1) + errx(1, "tls configuration failed (%s)", + tls_error(tls_ctx)); + } + if (xflag) + s = socks_connect(host, portlist[i], hints, + proxyhost, proxyport, proxyhints, socksv, + Pflag); + else + s = remote_connect(host, portlist[i], hints); + + if (s == -1) + continue; + + ret = 0; + if (vflag || zflag) { + /* For UDP, make sure we are connected. */ + if (uflag) { + if (udptest(s) == -1) { + ret = 1; + continue; + } + } + + /* Don't look up port if -n. */ + if (nflag) + sv = NULL; + else { + sv = getservbyport( + ntohs(atoi(portlist[i])), + uflag ? "udp" : "tcp"); + } + + fprintf(stderr, + "Connection to %s %s port [%s/%s] " + "succeeded!\n", host, portlist[i], + uflag ? "udp" : "tcp", + sv ? sv->s_name : "*"); + } + if (Fflag) + fdpass(s); + else { + if (usetls) + tls_setup_client(tls_ctx, s, host); + if (!zflag) + readwrite(s, tls_ctx); + if (tls_ctx) { + int j; + + do { + j = tls_close(tls_ctx); + } while (j == TLS_WANT_POLLIN || + j == TLS_WANT_POLLOUT); + tls_free(tls_ctx); + tls_ctx = NULL; + } + } + } + } + + if (s != -1) + close(s); + + tls_config_free(tls_cfg); + + exit(ret); +} + +/* + * unix_bind() + * Returns a unix socket bound to the given path + */ +int +unix_bind(char *path, int flags) +{ + struct sockaddr_un s_un; + int s, save_errno; + + /* Create unix domain socket. */ + if ((s = socket(AF_UNIX, flags | (uflag ? SOCK_DGRAM : SOCK_STREAM), + 0)) < 0) + return (-1); + + memset(&s_un, 0, sizeof(struct sockaddr_un)); + s_un.sun_family = AF_UNIX; + + if (strlcpy(s_un.sun_path, path, sizeof(s_un.sun_path)) >= + sizeof(s_un.sun_path)) { + close(s); + errno = ENAMETOOLONG; + return (-1); + } + + if (bind(s, (struct sockaddr *)&s_un, sizeof(s_un)) < 0) { + save_errno = errno; + close(s); + errno = save_errno; + return (-1); + } + return (s); +} + +void +tls_setup_client(struct tls *tls_ctx, int s, char *host) +{ + int i; + + if (tls_connect_socket(tls_ctx, s, + tls_expectname ? tls_expectname : host) == -1) { + errx(1, "tls connection failed (%s)", + tls_error(tls_ctx)); + } + do { + if ((i = tls_handshake(tls_ctx)) == -1) + errx(1, "tls handshake failed (%s)", + tls_error(tls_ctx)); + } while (i == TLS_WANT_POLLIN || i == TLS_WANT_POLLOUT); + if (vflag) + report_tls(tls_ctx, host, tls_expectname); + if (tls_expecthash && tls_peer_cert_hash(tls_ctx) && + strcmp(tls_expecthash, tls_peer_cert_hash(tls_ctx)) != 0) + errx(1, "peer certificate is not %s", tls_expecthash); +} + +struct tls * +tls_setup_server(struct tls *tls_ctx, int connfd, char *host) +{ + struct tls *tls_cctx; + + if (tls_accept_socket(tls_ctx, &tls_cctx, + connfd) == -1) { + warnx("tls accept failed (%s)", + tls_error(tls_ctx)); + tls_cctx = NULL; + } else { + int i; + + do { + if ((i = tls_handshake(tls_cctx)) == -1) + warnx("tls handshake failed (%s)", + tls_error(tls_cctx)); + } while(i == TLS_WANT_POLLIN || i == TLS_WANT_POLLOUT); + } + if (tls_cctx) { + int gotcert = tls_peer_cert_provided(tls_cctx); + + if (vflag && gotcert) + report_tls(tls_cctx, host, tls_expectname); + if ((TLSopt & TLS_CCERT) && !gotcert) + warnx("No client certificate provided"); + else if (gotcert && tls_peer_cert_hash(tls_ctx) && tls_expecthash && + strcmp(tls_expecthash, tls_peer_cert_hash(tls_ctx)) != 0) + warnx("peer certificate is not %s", tls_expecthash); + else if (gotcert && tls_expectname && + (!tls_peer_cert_contains_name(tls_cctx, tls_expectname))) + warnx("name (%s) not found in client cert", + tls_expectname); + else { + return tls_cctx; + } + } + return NULL; +} + +/* + * unix_connect() + * Returns a socket connected to a local unix socket. Returns -1 on failure. + */ +int +unix_connect(char *path) +{ + struct sockaddr_un s_un; + int s, save_errno; + + if (uflag) { + if ((s = unix_bind(unix_dg_tmp_socket, SOCK_CLOEXEC)) < 0) + return (-1); + } else { + if ((s = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) < 0) + return (-1); + } + + memset(&s_un, 0, sizeof(struct sockaddr_un)); + s_un.sun_family = AF_UNIX; + + if (strlcpy(s_un.sun_path, path, sizeof(s_un.sun_path)) >= + sizeof(s_un.sun_path)) { + close(s); + errno = ENAMETOOLONG; + return (-1); + } + if (connect(s, (struct sockaddr *)&s_un, sizeof(s_un)) < 0) { + save_errno = errno; + close(s); + errno = save_errno; + return (-1); + } + return (s); + +} + +/* + * unix_listen() + * Create a unix domain socket, and listen on it. + */ +int +unix_listen(char *path) +{ + int s; + if ((s = unix_bind(path, 0)) < 0) + return (-1); + + if (listen(s, 5) < 0) { + close(s); + return (-1); + } + return (s); +} + +/* + * remote_connect() + * Returns a socket connected to a remote host. Properly binds to a local + * port or source address if needed. Returns -1 on failure. + */ +int +remote_connect(const char *host, const char *port, struct addrinfo hints) +{ + struct addrinfo *res, *res0; + int s, error, save_errno; +#ifdef SO_BINDANY + int on = 1; +#endif + + if ((error = getaddrinfo(host, port, &hints, &res))) + errx(1, "getaddrinfo: %s", gai_strerror(error)); + + res0 = res; + do { + if ((s = socket(res0->ai_family, res0->ai_socktype | + SOCK_NONBLOCK, res0->ai_protocol)) < 0) + continue; + + /* Bind to a local port or source address if specified. */ + if (sflag || pflag) { + struct addrinfo ahints, *ares; + +#ifdef SO_BINDANY + /* try SO_BINDANY, but don't insist */ + setsockopt(s, SOL_SOCKET, SO_BINDANY, &on, sizeof(on)); +#endif + memset(&ahints, 0, sizeof(struct addrinfo)); + ahints.ai_family = res0->ai_family; + ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; + ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; + ahints.ai_flags = AI_PASSIVE; + if ((error = getaddrinfo(sflag, pflag, &ahints, &ares))) + errx(1, "getaddrinfo: %s", gai_strerror(error)); + + if (bind(s, (struct sockaddr *)ares->ai_addr, + ares->ai_addrlen) < 0) + err(1, "bind failed"); + freeaddrinfo(ares); + } + + set_common_sockopts(s, res0->ai_family); + + if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0) + break; + if (vflag) + warn("connect to %s port %s (%s) failed", host, port, + uflag ? "udp" : "tcp"); + + save_errno = errno; + close(s); + errno = save_errno; + s = -1; + } while ((res0 = res0->ai_next) != NULL); + + freeaddrinfo(res); + + return (s); +} + +int +timeout_connect(int s, const struct sockaddr *name, socklen_t namelen) +{ + struct pollfd pfd; + socklen_t optlen; + int optval; + int ret; + + if ((ret = connect(s, name, namelen)) != 0 && errno == EINPROGRESS) { + pfd.fd = s; + pfd.events = POLLOUT; + if ((ret = poll(&pfd, 1, timeout)) == 1) { + optlen = sizeof(optval); + if ((ret = getsockopt(s, SOL_SOCKET, SO_ERROR, + &optval, &optlen)) == 0) { + errno = optval; + ret = optval == 0 ? 0 : -1; + } + } else if (ret == 0) { + errno = ETIMEDOUT; + ret = -1; + } else + err(1, "poll failed"); + } + + return (ret); +} + +/* + * local_listen() + * Returns a socket listening on a local port, binds to specified source + * address. Returns -1 on failure. + */ +int +local_listen(char *host, char *port, struct addrinfo hints) +{ + struct addrinfo *res, *res0; + int s, save_errno; +#ifdef SO_REUSEPORT + int ret, x = 1; +#endif + int error; + + /* Allow nodename to be null. */ + hints.ai_flags |= AI_PASSIVE; + + /* + * In the case of binding to a wildcard address + * default to binding to an ipv4 address. + */ + if (host == NULL && hints.ai_family == AF_UNSPEC) + hints.ai_family = AF_INET; + + if ((error = getaddrinfo(host, port, &hints, &res))) + errx(1, "getaddrinfo: %s", gai_strerror(error)); + + res0 = res; + do { + if ((s = socket(res0->ai_family, res0->ai_socktype, + res0->ai_protocol)) < 0) + continue; + +#ifdef SO_REUSEPORT + ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x)); + if (ret == -1) + err(1, NULL); +#endif + + set_common_sockopts(s, res0->ai_family); + + if (bind(s, (struct sockaddr *)res0->ai_addr, + res0->ai_addrlen) == 0) + break; + + save_errno = errno; + close(s); + errno = save_errno; + s = -1; + } while ((res0 = res0->ai_next) != NULL); + + if (!uflag && s != -1) { + if (listen(s, 1) < 0) + err(1, "listen"); + } + + freeaddrinfo(res); + + return (s); +} + +/* + * readwrite() + * Loop that polls on the network file descriptor and stdin. + */ +void +readwrite(int net_fd, struct tls *tls_ctx) +{ + struct pollfd pfd[4]; + int stdin_fd = STDIN_FILENO; + int stdout_fd = STDOUT_FILENO; + unsigned char netinbuf[BUFSIZE]; + size_t netinbufpos = 0; + unsigned char stdinbuf[BUFSIZE]; + size_t stdinbufpos = 0; + int n, num_fds; + ssize_t ret; + + /* don't read from stdin if requested */ + if (dflag) + stdin_fd = -1; + + /* stdin */ + pfd[POLL_STDIN].fd = stdin_fd; + pfd[POLL_STDIN].events = POLLIN; + + /* network out */ + pfd[POLL_NETOUT].fd = net_fd; + pfd[POLL_NETOUT].events = 0; + + /* network in */ + pfd[POLL_NETIN].fd = net_fd; + pfd[POLL_NETIN].events = POLLIN; + + /* stdout */ + pfd[POLL_STDOUT].fd = stdout_fd; + pfd[POLL_STDOUT].events = 0; + + while (1) { + /* both inputs are gone, buffers are empty, we are done */ + if (pfd[POLL_STDIN].fd == -1 && pfd[POLL_NETIN].fd == -1 && + stdinbufpos == 0 && netinbufpos == 0) { + close(net_fd); + return; + } + /* both outputs are gone, we can't continue */ + if (pfd[POLL_NETOUT].fd == -1 && pfd[POLL_STDOUT].fd == -1) { + close(net_fd); + return; + } + /* listen and net in gone, queues empty, done */ + if (lflag && pfd[POLL_NETIN].fd == -1 && + stdinbufpos == 0 && netinbufpos == 0) { + close(net_fd); + return; + } + + /* help says -i is for "wait between lines sent". We read and + * write arbitrary amounts of data, and we don't want to start + * scanning for newlines, so this is as good as it gets */ + if (iflag) + sleep(iflag); + + /* poll */ + num_fds = poll(pfd, 4, timeout); + + /* treat poll errors */ + if (num_fds == -1) { + close(net_fd); + err(1, "polling error"); + } + + /* timeout happened */ + if (num_fds == 0) + return; + + /* treat socket error conditions */ + for (n = 0; n < 4; n++) { + if (pfd[n].revents & (POLLERR|POLLNVAL)) { + pfd[n].fd = -1; + } + } + /* reading is possible after HUP */ + if (pfd[POLL_STDIN].events & POLLIN && + pfd[POLL_STDIN].revents & POLLHUP && + !(pfd[POLL_STDIN].revents & POLLIN)) + pfd[POLL_STDIN].fd = -1; + + if (pfd[POLL_NETIN].events & POLLIN && + pfd[POLL_NETIN].revents & POLLHUP && + !(pfd[POLL_NETIN].revents & POLLIN)) + pfd[POLL_NETIN].fd = -1; + + if (pfd[POLL_NETOUT].revents & POLLHUP) { + if (Nflag) + shutdown(pfd[POLL_NETOUT].fd, SHUT_WR); + pfd[POLL_NETOUT].fd = -1; + } + /* if HUP, stop watching stdout */ + if (pfd[POLL_STDOUT].revents & POLLHUP) + pfd[POLL_STDOUT].fd = -1; + /* if no net out, stop watching stdin */ + if (pfd[POLL_NETOUT].fd == -1) + pfd[POLL_STDIN].fd = -1; + /* if no stdout, stop watching net in */ + if (pfd[POLL_STDOUT].fd == -1) { + if (pfd[POLL_NETIN].fd != -1) + shutdown(pfd[POLL_NETIN].fd, SHUT_RD); + pfd[POLL_NETIN].fd = -1; + } + + /* try to read from stdin */ + if (pfd[POLL_STDIN].revents & POLLIN && stdinbufpos < BUFSIZE) { + ret = fillbuf(pfd[POLL_STDIN].fd, stdinbuf, + &stdinbufpos, NULL); + if (ret == TLS_WANT_POLLIN) + pfd[POLL_STDIN].events = POLLIN; + else if (ret == TLS_WANT_POLLOUT) + pfd[POLL_STDIN].events = POLLOUT; + else if (ret == 0 || ret == -1) + pfd[POLL_STDIN].fd = -1; + /* read something - poll net out */ + if (stdinbufpos > 0) + pfd[POLL_NETOUT].events = POLLOUT; + /* filled buffer - remove self from polling */ + if (stdinbufpos == BUFSIZE) + pfd[POLL_STDIN].events = 0; + } + /* try to write to network */ + if (pfd[POLL_NETOUT].revents & POLLOUT && stdinbufpos > 0) { + ret = drainbuf(pfd[POLL_NETOUT].fd, stdinbuf, + &stdinbufpos, tls_ctx); + if (ret == TLS_WANT_POLLIN) + pfd[POLL_NETOUT].events = POLLIN; + else if (ret == TLS_WANT_POLLOUT) + pfd[POLL_NETOUT].events = POLLOUT; + else if (ret == -1) + pfd[POLL_NETOUT].fd = -1; + /* buffer empty - remove self from polling */ + if (stdinbufpos == 0) + pfd[POLL_NETOUT].events = 0; + /* buffer no longer full - poll stdin again */ + if (stdinbufpos < BUFSIZE) + pfd[POLL_STDIN].events = POLLIN; + } + /* try to read from network */ + if (pfd[POLL_NETIN].revents & POLLIN && netinbufpos < BUFSIZE) { + ret = fillbuf(pfd[POLL_NETIN].fd, netinbuf, + &netinbufpos, tls_ctx); + if (ret == TLS_WANT_POLLIN) + pfd[POLL_NETIN].events = POLLIN; + else if (ret == TLS_WANT_POLLOUT) + pfd[POLL_NETIN].events = POLLOUT; + else if (ret == -1) + pfd[POLL_NETIN].fd = -1; + /* eof on net in - remove from pfd */ + if (ret == 0) { + shutdown(pfd[POLL_NETIN].fd, SHUT_RD); + pfd[POLL_NETIN].fd = -1; + } + /* read something - poll stdout */ + if (netinbufpos > 0) + pfd[POLL_STDOUT].events = POLLOUT; + /* filled buffer - remove self from polling */ + if (netinbufpos == BUFSIZE) + pfd[POLL_NETIN].events = 0; + /* handle telnet */ + if (tflag) + atelnet(pfd[POLL_NETIN].fd, netinbuf, + netinbufpos); + } + /* try to write to stdout */ + if (pfd[POLL_STDOUT].revents & POLLOUT && netinbufpos > 0) { + ret = drainbuf(pfd[POLL_STDOUT].fd, netinbuf, + &netinbufpos, NULL); + if (ret == TLS_WANT_POLLIN) + pfd[POLL_STDOUT].events = POLLIN; + else if (ret == TLS_WANT_POLLOUT) + pfd[POLL_STDOUT].events = POLLOUT; + else if (ret == -1) + pfd[POLL_STDOUT].fd = -1; + /* buffer empty - remove self from polling */ + if (netinbufpos == 0) + pfd[POLL_STDOUT].events = 0; + /* buffer no longer full - poll net in again */ + if (netinbufpos < BUFSIZE) + pfd[POLL_NETIN].events = POLLIN; + } + + /* stdin gone and queue empty? */ + if (pfd[POLL_STDIN].fd == -1 && stdinbufpos == 0) { + if (pfd[POLL_NETOUT].fd != -1 && Nflag) + shutdown(pfd[POLL_NETOUT].fd, SHUT_WR); + pfd[POLL_NETOUT].fd = -1; + } + /* net in gone and queue empty? */ + if (pfd[POLL_NETIN].fd == -1 && netinbufpos == 0) { + pfd[POLL_STDOUT].fd = -1; + } + } +} + +ssize_t +drainbuf(int fd, unsigned char *buf, size_t *bufpos, struct tls *tls) +{ + ssize_t n; + ssize_t adjust; + + if (tls) + n = tls_write(tls, buf, *bufpos); + else { + n = write(fd, buf, *bufpos); + /* don't treat EAGAIN, EINTR as error */ + if (n == -1 && (errno == EAGAIN || errno == EINTR)) + n = TLS_WANT_POLLOUT; + } + if (n <= 0) + return n; + /* adjust buffer */ + adjust = *bufpos - n; + if (adjust > 0) + memmove(buf, buf + n, adjust); + *bufpos -= n; + return n; +} + +ssize_t +fillbuf(int fd, unsigned char *buf, size_t *bufpos, struct tls *tls) +{ + size_t num = BUFSIZE - *bufpos; + ssize_t n; + + if (tls) + n = tls_read(tls, buf + *bufpos, num); + else { + n = read(fd, buf + *bufpos, num); + /* don't treat EAGAIN, EINTR as error */ + if (n == -1 && (errno == EAGAIN || errno == EINTR)) + n = TLS_WANT_POLLIN; + } + if (n <= 0) + return n; + *bufpos += n; + return n; +} + +/* + * fdpass() + * Pass the connected file descriptor to stdout and exit. + */ +void +fdpass(int nfd) +{ + struct msghdr mh; + union { + struct cmsghdr hdr; + char buf[CMSG_SPACE(sizeof(int))]; + } cmsgbuf; + struct cmsghdr *cmsg; + struct iovec iov; + char c = '\0'; + ssize_t r; + struct pollfd pfd; + + /* Avoid obvious stupidity */ + if (isatty(STDOUT_FILENO)) + errx(1, "Cannot pass file descriptor to tty"); + + bzero(&mh, sizeof(mh)); + bzero(&cmsgbuf, sizeof(cmsgbuf)); + bzero(&iov, sizeof(iov)); + + mh.msg_control = (caddr_t)&cmsgbuf.buf; + mh.msg_controllen = sizeof(cmsgbuf.buf); + cmsg = CMSG_FIRSTHDR(&mh); + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + *(int *)CMSG_DATA(cmsg) = nfd; + + iov.iov_base = &c; + iov.iov_len = 1; + mh.msg_iov = &iov; + mh.msg_iovlen = 1; + + bzero(&pfd, sizeof(pfd)); + pfd.fd = STDOUT_FILENO; + pfd.events = POLLOUT; + for (;;) { + r = sendmsg(STDOUT_FILENO, &mh, 0); + if (r == -1) { + if (errno == EAGAIN || errno == EINTR) { + if (poll(&pfd, 1, -1) == -1) + err(1, "poll"); + continue; + } + err(1, "sendmsg"); + } else if (r != 1) + errx(1, "sendmsg: unexpected return value %zd", r); + else + break; + } + exit(0); +} + +/* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */ +void +atelnet(int nfd, unsigned char *buf, unsigned int size) +{ + unsigned char *p, *end; + unsigned char obuf[4]; + + if (size < 3) + return; + end = buf + size - 2; + + for (p = buf; p < end; p++) { + if (*p != IAC) + continue; + + obuf[0] = IAC; + p++; + if ((*p == WILL) || (*p == WONT)) + obuf[1] = DONT; + else if ((*p == DO) || (*p == DONT)) + obuf[1] = WONT; + else + continue; + + p++; + obuf[2] = *p; + if (atomicio(vwrite, nfd, obuf, 3) != 3) + warn("Write Error!"); + } +} + + +int +strtoport(char *portstr, int udp) +{ + struct servent *entry; + const char *errstr; + char *proto; + int port = -1; + + proto = udp ? "udp" : "tcp"; + + port = strtonum(portstr, 1, PORT_MAX, &errstr); + if (errstr == NULL) + return port; + if (errno != EINVAL) + errx(1, "port number %s: %s", errstr, portstr); + if ((entry = getservbyname(portstr, proto)) == NULL) + errx(1, "service \"%s\" unknown", portstr); + return ntohs(entry->s_port); +} + +/* + * build_ports() + * Build an array of ports in portlist[], listing each port + * that we should try to connect to. + */ +void +build_ports(char *p) +{ + char *n; + int hi, lo, cp; + int x = 0; + + if ((n = strchr(p, '-')) != NULL) { + *n = '\0'; + n++; + + /* Make sure the ports are in order: lowest->highest. */ + hi = strtoport(n, uflag); + lo = strtoport(p, uflag); + if (lo > hi) { + cp = hi; + hi = lo; + lo = cp; + } + + /* + * Initialize portlist with a random permutation. Based on + * Knuth, as in ip_randomid() in sys/netinet/ip_id.c. + */ + if (rflag) { + for (x = 0; x <= hi - lo; x++) { + cp = arc4random_uniform(x + 1); + portlist[x] = portlist[cp]; + if (asprintf(&portlist[cp], "%d", x + lo) < 0) + err(1, "asprintf"); + } + } else { /* Load ports sequentially. */ + for (cp = lo; cp <= hi; cp++) { + if (asprintf(&portlist[x], "%d", cp) < 0) + err(1, "asprintf"); + x++; + } + } + } else { + char *tmp; + + hi = strtoport(p, uflag); + if (asprintf(&tmp, "%d", hi) != -1) + portlist[0] = tmp; + else + err(1, NULL); + } +} + +/* + * udptest() + * Do a few writes to see if the UDP port is there. + * Fails once PF state table is full. + */ +int +udptest(int s) +{ + int i, ret; + + for (i = 0; i <= 3; i++) { + if (write(s, "X", 1) == 1) + ret = 1; + else + ret = -1; + } + return (ret); +} + +void +set_common_sockopts(int s, int af) +{ + int x = 1; + +#ifdef TCP_MD5SIG + if (Sflag) { + if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG, + &x, sizeof(x)) == -1) + err(1, NULL); + } +#endif + if (Dflag) { + if (setsockopt(s, SOL_SOCKET, SO_DEBUG, + &x, sizeof(x)) == -1) + err(1, NULL); + } + if (Tflag != -1) { + if (af == AF_INET && setsockopt(s, IPPROTO_IP, + IP_TOS, &Tflag, sizeof(Tflag)) == -1) + err(1, "set IP ToS"); + + else if (af == AF_INET6 && setsockopt(s, IPPROTO_IPV6, + IPV6_TCLASS, &Tflag, sizeof(Tflag)) == -1) + err(1, "set IPv6 traffic class"); + } + if (Iflag) { + if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, + &Iflag, sizeof(Iflag)) == -1) + err(1, "set TCP receive buffer size"); + } + if (Oflag) { + if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, + &Oflag, sizeof(Oflag)) == -1) + err(1, "set TCP send buffer size"); + } + + if (ttl != -1) { + if (af == AF_INET && setsockopt(s, IPPROTO_IP, + IP_TTL, &ttl, sizeof(ttl))) + err(1, "set IP TTL"); + + else if (af == AF_INET6 && setsockopt(s, IPPROTO_IPV6, + IPV6_UNICAST_HOPS, &ttl, sizeof(ttl))) + err(1, "set IPv6 unicast hops"); + } + + if (minttl != -1) { +#ifdef IP_MINTTL + if (af == AF_INET && setsockopt(s, IPPROTO_IP, + IP_MINTTL, &minttl, sizeof(minttl))) + err(1, "set IP min TTL"); +#endif + +#ifdef IPV6_MINHOPCOUNT + if (af == AF_INET6 && setsockopt(s, IPPROTO_IPV6, + IPV6_MINHOPCOUNT, &minttl, sizeof(minttl))) + err(1, "set IPv6 min hop count"); +#endif + } +} + +int +map_tos(char *s, int *val) +{ + /* DiffServ Codepoints and other TOS mappings */ + const struct toskeywords { + const char *keyword; + int val; + } *t, toskeywords[] = { + { "af11", IPTOS_DSCP_AF11 }, + { "af12", IPTOS_DSCP_AF12 }, + { "af13", IPTOS_DSCP_AF13 }, + { "af21", IPTOS_DSCP_AF21 }, + { "af22", IPTOS_DSCP_AF22 }, + { "af23", IPTOS_DSCP_AF23 }, + { "af31", IPTOS_DSCP_AF31 }, + { "af32", IPTOS_DSCP_AF32 }, + { "af33", IPTOS_DSCP_AF33 }, + { "af41", IPTOS_DSCP_AF41 }, + { "af42", IPTOS_DSCP_AF42 }, + { "af43", IPTOS_DSCP_AF43 }, + { "critical", IPTOS_PREC_CRITIC_ECP }, + { "cs0", IPTOS_DSCP_CS0 }, + { "cs1", IPTOS_DSCP_CS1 }, + { "cs2", IPTOS_DSCP_CS2 }, + { "cs3", IPTOS_DSCP_CS3 }, + { "cs4", IPTOS_DSCP_CS4 }, + { "cs5", IPTOS_DSCP_CS5 }, + { "cs6", IPTOS_DSCP_CS6 }, + { "cs7", IPTOS_DSCP_CS7 }, + { "ef", IPTOS_DSCP_EF }, + { "inetcontrol", IPTOS_PREC_INTERNETCONTROL }, + { "lowdelay", IPTOS_LOWDELAY }, + { "netcontrol", IPTOS_PREC_NETCONTROL }, + { "reliability", IPTOS_RELIABILITY }, + { "throughput", IPTOS_THROUGHPUT }, + { NULL, -1 }, + }; + + for (t = toskeywords; t->keyword != NULL; t++) { + if (strcmp(s, t->keyword) == 0) { + *val = t->val; + return (1); + } + } + + return (0); +} + +int +map_tls(char *s, int *val) +{ + const struct tlskeywords { + const char *keyword; + int val; + } *t, tlskeywords[] = { + { "tlslegacy", TLS_LEGACY }, + { "noverify", TLS_NOVERIFY }, + { "noname", TLS_NONAME }, + { "clientcert", TLS_CCERT}, + { NULL, -1 }, + }; + + for (t = tlskeywords; t->keyword != NULL; t++) { + if (strcmp(s, t->keyword) == 0) { + *val |= t->val; + return (1); + } + } + return (0); +} + +void +report_tls(struct tls * tls_ctx, char * host, char *tls_expectname) +{ + time_t t; + fprintf(stderr, "TLS handshake negotiated %s/%s with host %s\n", + tls_conn_version(tls_ctx), tls_conn_cipher(tls_ctx), host); + fprintf(stderr, "Peer name: %s\n", + tls_expectname ? tls_expectname : host); + if (tls_peer_cert_subject(tls_ctx)) + fprintf(stderr, "Subject: %s\n", + tls_peer_cert_subject(tls_ctx)); + if (tls_peer_cert_issuer(tls_ctx)) + fprintf(stderr, "Issuer: %s\n", + tls_peer_cert_issuer(tls_ctx)); + if ((t = tls_peer_cert_notbefore(tls_ctx)) != -1) + fprintf(stderr, "Valid From: %s", ctime(&t)); + if ((t = tls_peer_cert_notafter(tls_ctx)) != -1) + fprintf(stderr, "Valid Until: %s", ctime(&t)); + if (tls_peer_cert_hash(tls_ctx)) + fprintf(stderr, "Cert Hash: %s\n", + tls_peer_cert_hash(tls_ctx)); +} + +void +report_connect(const struct sockaddr *sa, socklen_t salen, char *path) +{ + char remote_host[NI_MAXHOST]; + char remote_port[NI_MAXSERV]; + int herr; + int flags = NI_NUMERICSERV; + + if (path != NULL) { + fprintf(stderr, "Connection on %s received!\n", path); + return; + } + + if (nflag) + flags |= NI_NUMERICHOST; + + if ((herr = getnameinfo(sa, salen, + remote_host, sizeof(remote_host), + remote_port, sizeof(remote_port), + flags)) != 0) { + if (herr == EAI_SYSTEM) + err(1, "getnameinfo"); + else + errx(1, "getnameinfo: %s", gai_strerror(herr)); + } + + fprintf(stderr, + "Connection from %s %s " + "received!\n", remote_host, remote_port); +} + +void +help(void) +{ + usage(0); + fprintf(stderr, "\tCommand Summary:\n\ + \t-4 Use IPv4\n\ + \t-6 Use IPv6\n\ + \t-C certfile Public key file\n\ + \t-c Use TLS\n\ + \t-D Enable the debug socket option\n\ + \t-d Detach from stdin\n\ + \t-e name\t Required name in peer certificate\n\ + \t-F Pass socket fd\n\ + \t-H hash\t Hash string of peer certificate\n\ + \t-h This help text\n\ + \t-I length TCP receive buffer length\n\ + \t-i interval Delay interval for lines sent, ports scanned\n\ + \t-K keyfile Private key file\n\ + \t-k Keep inbound sockets open for multiple connects\n\ + \t-l Listen mode, for inbound connects\n\ + \t-M ttl Outgoing TTL / Hop Limit\n\ + \t-m minttl Minimum incoming TTL / Hop Limit\n\ + \t-N Shutdown the network socket after EOF on stdin\n\ + \t-n Suppress name/port resolutions\n\ + \t-O length TCP send buffer length\n\ + \t-P proxyuser\tUsername for proxy authentication\n\ + \t-p port\t Specify local port for remote connects\n\ + \t-R CAfile CA bundle\n\ + \t-r Randomize remote ports\n" +#ifdef TCP_MD5SIG + "\ + \t-S Enable the TCP MD5 signature option\n" +#endif + "\ + \t-s source Local source address\n\ + \t-T keyword TOS value or TLS options\n\ + \t-t Answer TELNET negotiation\n\ + \t-U Use UNIX domain socket\n\ + \t-u UDP mode\n" +#ifdef SO_RTABLE + "\ + \t-V rtable Specify alternate routing table\n" +#endif + "\ + \t-v Verbose\n\ + \t-w timeout Timeout for connects and final net reads\n\ + \t-X proto Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\ + \t-x addr[:port]\tSpecify proxy address and port\n\ + \t-z Zero-I/O mode [used for scanning]\n\ + Port numbers can be individual or ranges: lo-hi [inclusive]\n"); + exit(1); +} + +void +usage(int ret) +{ + fprintf(stderr, + "usage: nc [-46cDdFhklNnrStUuvz] [-C certfile] [-e name] " + "[-H hash] [-I length]\n" + "\t [-i interval] [-K keyfile] [-M ttl] [-m minttl] [-O length]\n" + "\t [-P proxy_username] [-p source_port] [-R CAfile] [-s source]\n" + "\t [-T keyword] [-V rtable] [-w timeout] [-X proxy_protocol]\n" + "\t [-x proxy_address[:port]] [destination] [port]\n"); + if (ret) + exit(1); +} diff --git a/crypto/libressl/apps/nc/socks.c b/crypto/libressl/apps/nc/socks.c new file mode 100644 index 0000000000..8935e5b91a --- /dev/null +++ b/crypto/libressl/apps/nc/socks.c @@ -0,0 +1,396 @@ +/* $OpenBSD: socks.c,v 1.23 2015/12/10 18:31:52 mmcc Exp $ */ + +/* + * Copyright (c) 1999 Niklas Hallqvist. All rights reserved. + * Copyright (c) 2004, 2005 Damien Miller. 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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "atomicio.h" + +#define SOCKS_PORT "1080" +#define HTTP_PROXY_PORT "3128" +#define HTTP_MAXHDRS 64 +#define SOCKS_V5 5 +#define SOCKS_V4 4 +#define SOCKS_NOAUTH 0 +#define SOCKS_NOMETHOD 0xff +#define SOCKS_CONNECT 1 +#define SOCKS_IPV4 1 +#define SOCKS_DOMAIN 3 +#define SOCKS_IPV6 4 + +int remote_connect(const char *, const char *, struct addrinfo); +int socks_connect(const char *, const char *, struct addrinfo, + const char *, const char *, struct addrinfo, int, + const char *); + +static int +decode_addrport(const char *h, const char *p, struct sockaddr *addr, + socklen_t addrlen, int v4only, int numeric) +{ + int r; + struct addrinfo hints, *res; + + bzero(&hints, sizeof(hints)); + hints.ai_family = v4only ? PF_INET : PF_UNSPEC; + hints.ai_flags = numeric ? AI_NUMERICHOST : 0; + hints.ai_socktype = SOCK_STREAM; + r = getaddrinfo(h, p, &hints, &res); + /* Don't fatal when attempting to convert a numeric address */ + if (r != 0) { + if (!numeric) { + errx(1, "getaddrinfo(\"%.64s\", \"%.64s\"): %s", h, p, + gai_strerror(r)); + } + return (-1); + } + if (addrlen < res->ai_addrlen) { + freeaddrinfo(res); + errx(1, "internal error: addrlen < res->ai_addrlen"); + } + memcpy(addr, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + return (0); +} + +static int +proxy_read_line(int fd, char *buf, size_t bufsz) +{ + size_t off; + + for(off = 0;;) { + if (off >= bufsz) + errx(1, "proxy read too long"); + if (atomicio(read, fd, buf + off, 1) != 1) + err(1, "proxy read"); + /* Skip CR */ + if (buf[off] == '\r') + continue; + if (buf[off] == '\n') { + buf[off] = '\0'; + break; + } + off++; + } + return (off); +} + +static const char * +getproxypass(const char *proxyuser, const char *proxyhost) +{ + char prompt[512]; + static char pw[256]; + + snprintf(prompt, sizeof(prompt), "Proxy password for %s@%s: ", + proxyuser, proxyhost); + if (readpassphrase(prompt, pw, sizeof(pw), RPP_REQUIRE_TTY) == NULL) + errx(1, "Unable to read proxy passphrase"); + return (pw); +} + +/* + * Error strings adapted from the generally accepted SOCKSv4 spec: + * + * http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol + */ +static const char * +socks4_strerror(int e) +{ + switch (e) { + case 90: + return "Succeeded"; + case 91: + return "Request rejected or failed"; + case 92: + return "SOCKS server cannot connect to identd on the client"; + case 93: + return "Client program and identd report different user-ids"; + default: + return "Unknown error"; + } +} + +/* + * Error strings taken almost directly from RFC 1928. + */ +static const char * +socks5_strerror(int e) +{ + switch (e) { + case 0: + return "Succeeded"; + case 1: + return "General SOCKS server failure"; + case 2: + return "Connection not allowed by ruleset"; + case 3: + return "Network unreachable"; + case 4: + return "Host unreachable"; + case 5: + return "Connection refused"; + case 6: + return "TTL expired"; + case 7: + return "Command not supported"; + case 8: + return "Address type not supported"; + default: + return "Unknown error"; + } +} + +int +socks_connect(const char *host, const char *port, + struct addrinfo hints __attribute__ ((__unused__)), + const char *proxyhost, const char *proxyport, struct addrinfo proxyhints, + int socksv, const char *proxyuser) +{ + int proxyfd, r, authretry = 0; + size_t hlen, wlen; + unsigned char buf[1024]; + size_t cnt; + struct sockaddr_storage addr; + struct sockaddr_in *in4 = (struct sockaddr_in *)&addr; + struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&addr; + in_port_t serverport; + const char *proxypass = NULL; + + if (proxyport == NULL) + proxyport = (socksv == -1) ? HTTP_PROXY_PORT : SOCKS_PORT; + + /* Abuse API to lookup port */ + if (decode_addrport("0.0.0.0", port, (struct sockaddr *)&addr, + sizeof(addr), 1, 1) == -1) + errx(1, "unknown port \"%.64s\"", port); + serverport = in4->sin_port; + + again: + if (authretry++ > 3) + errx(1, "Too many authentication failures"); + + proxyfd = remote_connect(proxyhost, proxyport, proxyhints); + + if (proxyfd < 0) + return (-1); + + if (socksv == 5) { + if (decode_addrport(host, port, (struct sockaddr *)&addr, + sizeof(addr), 0, 1) == -1) + addr.ss_family = 0; /* used in switch below */ + + /* Version 5, one method: no authentication */ + buf[0] = SOCKS_V5; + buf[1] = 1; + buf[2] = SOCKS_NOAUTH; + cnt = atomicio(vwrite, proxyfd, buf, 3); + if (cnt != 3) + err(1, "write failed (%zu/3)", cnt); + + cnt = atomicio(read, proxyfd, buf, 2); + if (cnt != 2) + err(1, "read failed (%zu/3)", cnt); + + if (buf[1] == SOCKS_NOMETHOD) + errx(1, "authentication method negotiation failed"); + + switch (addr.ss_family) { + case 0: + /* Version 5, connect: domain name */ + + /* Max domain name length is 255 bytes */ + hlen = strlen(host); + if (hlen > 255) + errx(1, "host name too long for SOCKS5"); + buf[0] = SOCKS_V5; + buf[1] = SOCKS_CONNECT; + buf[2] = 0; + buf[3] = SOCKS_DOMAIN; + buf[4] = hlen; + memcpy(buf + 5, host, hlen); + memcpy(buf + 5 + hlen, &serverport, sizeof serverport); + wlen = 7 + hlen; + break; + case AF_INET: + /* Version 5, connect: IPv4 address */ + buf[0] = SOCKS_V5; + buf[1] = SOCKS_CONNECT; + buf[2] = 0; + buf[3] = SOCKS_IPV4; + memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr); + memcpy(buf + 8, &in4->sin_port, sizeof in4->sin_port); + wlen = 10; + break; + case AF_INET6: + /* Version 5, connect: IPv6 address */ + buf[0] = SOCKS_V5; + buf[1] = SOCKS_CONNECT; + buf[2] = 0; + buf[3] = SOCKS_IPV6; + memcpy(buf + 4, &in6->sin6_addr, sizeof in6->sin6_addr); + memcpy(buf + 20, &in6->sin6_port, + sizeof in6->sin6_port); + wlen = 22; + break; + default: + errx(1, "internal error: silly AF"); + } + + cnt = atomicio(vwrite, proxyfd, buf, wlen); + if (cnt != wlen) + err(1, "write failed (%zu/%zu)", cnt, wlen); + + cnt = atomicio(read, proxyfd, buf, 4); + if (cnt != 4) + err(1, "read failed (%zu/4)", cnt); + if (buf[1] != 0) { + errx(1, "connection failed, SOCKSv5 error: %s", + socks5_strerror(buf[1])); + } + switch (buf[3]) { + case SOCKS_IPV4: + cnt = atomicio(read, proxyfd, buf + 4, 6); + if (cnt != 6) + err(1, "read failed (%zu/6)", cnt); + break; + case SOCKS_IPV6: + cnt = atomicio(read, proxyfd, buf + 4, 18); + if (cnt != 18) + err(1, "read failed (%zu/18)", cnt); + break; + default: + errx(1, "connection failed, unsupported address type"); + } + } else if (socksv == 4) { + /* This will exit on lookup failure */ + decode_addrport(host, port, (struct sockaddr *)&addr, + sizeof(addr), 1, 0); + + /* Version 4 */ + buf[0] = SOCKS_V4; + buf[1] = SOCKS_CONNECT; /* connect */ + memcpy(buf + 2, &in4->sin_port, sizeof in4->sin_port); + memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr); + buf[8] = 0; /* empty username */ + wlen = 9; + + cnt = atomicio(vwrite, proxyfd, buf, wlen); + if (cnt != wlen) + err(1, "write failed (%zu/%zu)", cnt, wlen); + + cnt = atomicio(read, proxyfd, buf, 8); + if (cnt != 8) + err(1, "read failed (%zu/8)", cnt); + if (buf[1] != 90) { + errx(1, "connection failed, SOCKSv4 error: %s", + socks4_strerror(buf[1])); + } + } else if (socksv == -1) { + /* HTTP proxy CONNECT */ + + /* Disallow bad chars in hostname */ + if (strcspn(host, "\r\n\t []:") != strlen(host)) + errx(1, "Invalid hostname"); + + /* Try to be sane about numeric IPv6 addresses */ + if (strchr(host, ':') != NULL) { + r = snprintf(buf, sizeof(buf), + "CONNECT [%s]:%d HTTP/1.0\r\n", + host, ntohs(serverport)); + } else { + r = snprintf(buf, sizeof(buf), + "CONNECT %s:%d HTTP/1.0\r\n", + host, ntohs(serverport)); + } + if (r == -1 || (size_t)r >= sizeof(buf)) + errx(1, "hostname too long"); + r = strlen(buf); + + cnt = atomicio(vwrite, proxyfd, buf, r); + if (cnt != r) + err(1, "write failed (%zu/%d)", cnt, r); + + if (authretry > 1) { + char resp[1024]; + + proxypass = getproxypass(proxyuser, proxyhost); + r = snprintf(buf, sizeof(buf), "%s:%s", + proxyuser, proxypass); + if (r == -1 || (size_t)r >= sizeof(buf) || + b64_ntop(buf, strlen(buf), resp, + sizeof(resp)) == -1) + errx(1, "Proxy username/password too long"); + r = snprintf(buf, sizeof(buf), "Proxy-Authorization: " + "Basic %s\r\n", resp); + if (r == -1 || (size_t)r >= sizeof(buf)) + errx(1, "Proxy auth response too long"); + r = strlen(buf); + if ((cnt = atomicio(vwrite, proxyfd, buf, r)) != r) + err(1, "write failed (%zu/%d)", cnt, r); + } + + /* Terminate headers */ + if ((cnt = atomicio(vwrite, proxyfd, "\r\n", 2)) != 2) + err(1, "write failed (%zu/2)", cnt); + + /* Read status reply */ + proxy_read_line(proxyfd, buf, sizeof(buf)); + if (proxyuser != NULL && + strncmp(buf, "HTTP/1.0 407 ", 12) == 0) { + if (authretry > 1) { + fprintf(stderr, "Proxy authentication " + "failed\n"); + } + close(proxyfd); + goto again; + } else if (strncmp(buf, "HTTP/1.0 200 ", 12) != 0 && + strncmp(buf, "HTTP/1.1 200 ", 12) != 0) + errx(1, "Proxy error: \"%s\"", buf); + + /* Headers continue until we hit an empty line */ + for (r = 0; r < HTTP_MAXHDRS; r++) { + proxy_read_line(proxyfd, buf, sizeof(buf)); + if (*buf == '\0') + break; + } + if (*buf != '\0') + errx(1, "Too many proxy headers received"); + } else + errx(1, "Unknown proxy protocol %d", socksv); + + return (proxyfd); +} diff --git a/crypto/libressl/apps/openssl/apps.c b/crypto/libressl/apps/openssl/apps.c new file mode 100644 index 0000000000..6e4096562d --- /dev/null +++ b/crypto/libressl/apps/openssl/apps.c @@ -0,0 +1,2322 @@ +/* $OpenBSD: apps.c,v 1.36 2015/09/13 12:41:01 bcook Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * 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. + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "apps.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +typedef struct { + const char *name; + unsigned long flag; + unsigned long mask; +} NAME_EX_TBL; + +UI_METHOD *ui_method = NULL; + +static int set_table_opts(unsigned long *flags, const char *arg, + const NAME_EX_TBL *in_tbl); +static int set_multi_opts(unsigned long *flags, const char *arg, + const NAME_EX_TBL *in_tbl); + +#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) +/* Looks like this stuff is worth moving into separate function */ +static EVP_PKEY *load_netscape_key(BIO *err, BIO *key, const char *file, + const char *key_descrip, int format); +#endif + +int +str2fmt(char *s) +{ + if (s == NULL) + return FORMAT_UNDEF; + if ((*s == 'D') || (*s == 'd')) + return (FORMAT_ASN1); + else if ((*s == 'T') || (*s == 't')) + return (FORMAT_TEXT); + else if ((*s == 'N') || (*s == 'n')) + return (FORMAT_NETSCAPE); + else if ((*s == 'S') || (*s == 's')) + return (FORMAT_SMIME); + else if ((*s == 'M') || (*s == 'm')) + return (FORMAT_MSBLOB); + else if ((*s == '1') || + (strcmp(s, "PKCS12") == 0) || (strcmp(s, "pkcs12") == 0) || + (strcmp(s, "P12") == 0) || (strcmp(s, "p12") == 0)) + return (FORMAT_PKCS12); + else if ((*s == 'P') || (*s == 'p')) { + if (s[1] == 'V' || s[1] == 'v') + return FORMAT_PVK; + else + return (FORMAT_PEM); + } else + return (FORMAT_UNDEF); +} + +void +program_name(char *in, char *out, int size) +{ + char *p; + + p = strrchr(in, '/'); + if (p != NULL) + p++; + else + p = in; + strlcpy(out, p, size); +} + +int +chopup_args(ARGS *arg, char *buf, int *argc, char **argv[]) +{ + int num, i; + char *p; + + *argc = 0; + *argv = NULL; + + i = 0; + if (arg->count == 0) { + arg->count = 20; + arg->data = reallocarray(NULL, arg->count, sizeof(char *)); + if (arg->data == NULL) + return 0; + } + for (i = 0; i < arg->count; i++) + arg->data[i] = NULL; + + num = 0; + p = buf; + for (;;) { + /* first scan over white space */ + if (!*p) + break; + while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n'))) + p++; + if (!*p) + break; + + /* The start of something good :-) */ + if (num >= arg->count) { + char **tmp_p; + int tlen = arg->count + 20; + tmp_p = reallocarray(arg->data, tlen, sizeof(char *)); + if (tmp_p == NULL) + return 0; + arg->data = tmp_p; + arg->count = tlen; + /* initialize newly allocated data */ + for (i = num; i < arg->count; i++) + arg->data[i] = NULL; + } + arg->data[num++] = p; + + /* now look for the end of this */ + if ((*p == '\'') || (*p == '\"')) { /* scan for closing + * quote */ + i = *(p++); + arg->data[num - 1]++; /* jump over quote */ + while (*p && (*p != i)) + p++; + *p = '\0'; + } else { + while (*p && ((*p != ' ') && + (*p != '\t') && (*p != '\n'))) + p++; + + if (*p == '\0') + p--; + else + *p = '\0'; + } + p++; + } + *argc = num; + *argv = arg->data; + return (1); +} + +int +dump_cert_text(BIO *out, X509 *x) +{ + char *p; + + p = X509_NAME_oneline(X509_get_subject_name(x), NULL, 0); + BIO_puts(out, "subject="); + BIO_puts(out, p); + free(p); + + p = X509_NAME_oneline(X509_get_issuer_name(x), NULL, 0); + BIO_puts(out, "\nissuer="); + BIO_puts(out, p); + BIO_puts(out, "\n"); + free(p); + + return 0; +} + +int +ui_open(UI *ui) +{ + return UI_method_get_opener(UI_OpenSSL()) (ui); +} + +int +ui_read(UI *ui, UI_STRING *uis) +{ + const char *password; + int string_type; + + if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD && + UI_get0_user_data(ui)) { + string_type = UI_get_string_type(uis); + if (string_type == UIT_PROMPT || string_type == UIT_VERIFY) { + password = + ((PW_CB_DATA *)UI_get0_user_data(ui))->password; + if (password && password[0] != '\0') { + UI_set_result(ui, uis, password); + return 1; + } + } + } + return UI_method_get_reader(UI_OpenSSL()) (ui, uis); +} + +int +ui_write(UI *ui, UI_STRING *uis) +{ + const char *password; + int string_type; + + if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD && + UI_get0_user_data(ui)) { + string_type = UI_get_string_type(uis); + if (string_type == UIT_PROMPT || string_type == UIT_VERIFY) { + password = + ((PW_CB_DATA *)UI_get0_user_data(ui))->password; + if (password && password[0] != '\0') + return 1; + } + } + return UI_method_get_writer(UI_OpenSSL()) (ui, uis); +} + +int +ui_close(UI *ui) +{ + return UI_method_get_closer(UI_OpenSSL()) (ui); +} + +int +password_callback(char *buf, int bufsiz, int verify, void *arg) +{ + PW_CB_DATA *cb_tmp = arg; + UI *ui = NULL; + int res = 0; + const char *prompt_info = NULL; + const char *password = NULL; + PW_CB_DATA *cb_data = (PW_CB_DATA *) cb_tmp; + + if (cb_data) { + if (cb_data->password) + password = cb_data->password; + if (cb_data->prompt_info) + prompt_info = cb_data->prompt_info; + } + if (password) { + res = strlen(password); + if (res > bufsiz) + res = bufsiz; + memcpy(buf, password, res); + return res; + } + ui = UI_new_method(ui_method); + if (ui) { + int ok = 0; + char *buff = NULL; + int ui_flags = 0; + char *prompt = NULL; + + prompt = UI_construct_prompt(ui, "pass phrase", prompt_info); + + ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD; + UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0); + + if (ok >= 0) + ok = UI_add_input_string(ui, prompt, ui_flags, buf, + PW_MIN_LENGTH, bufsiz - 1); + if (ok >= 0 && verify) { + buff = malloc(bufsiz); + ok = UI_add_verify_string(ui, prompt, ui_flags, buff, + PW_MIN_LENGTH, bufsiz - 1, buf); + } + if (ok >= 0) + do { + ok = UI_process(ui); + } while (ok < 0 && + UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0)); + + if (buff) { + explicit_bzero(buff, (unsigned int) bufsiz); + free(buff); + } + if (ok >= 0) + res = strlen(buf); + if (ok == -1) { + BIO_printf(bio_err, "User interface error\n"); + ERR_print_errors(bio_err); + explicit_bzero(buf, (unsigned int) bufsiz); + res = 0; + } + if (ok == -2) { + BIO_printf(bio_err, "aborted!\n"); + explicit_bzero(buf, (unsigned int) bufsiz); + res = 0; + } + UI_free(ui); + free(prompt); + } + return res; +} + +static char *app_get_pass(BIO *err, char *arg, int keepbio); + +int +app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2) +{ + int same; + + if (!arg2 || !arg1 || strcmp(arg1, arg2)) + same = 0; + else + same = 1; + if (arg1) { + *pass1 = app_get_pass(err, arg1, same); + if (!*pass1) + return 0; + } else if (pass1) + *pass1 = NULL; + if (arg2) { + *pass2 = app_get_pass(err, arg2, same ? 2 : 0); + if (!*pass2) + return 0; + } else if (pass2) + *pass2 = NULL; + return 1; +} + +static char * +app_get_pass(BIO *err, char *arg, int keepbio) +{ + char *tmp, tpass[APP_PASS_LEN]; + static BIO *pwdbio = NULL; + const char *errstr = NULL; + int i; + + if (!strncmp(arg, "pass:", 5)) + return strdup(arg + 5); + if (!strncmp(arg, "env:", 4)) { + tmp = getenv(arg + 4); + if (!tmp) { + BIO_printf(err, "Can't read environment variable %s\n", + arg + 4); + return NULL; + } + return strdup(tmp); + } + if (!keepbio || !pwdbio) { + if (!strncmp(arg, "file:", 5)) { + pwdbio = BIO_new_file(arg + 5, "r"); + if (!pwdbio) { + BIO_printf(err, "Can't open file %s\n", + arg + 5); + return NULL; + } + } else if (!strncmp(arg, "fd:", 3)) { + BIO *btmp; + i = strtonum(arg + 3, 0, INT_MAX, &errstr); + if (errstr) { + BIO_printf(err, + "Invalid file descriptor %s: %s\n", + arg, errstr); + return NULL; + } + pwdbio = BIO_new_fd(i, BIO_NOCLOSE); + if (!pwdbio) { + BIO_printf(err, + "Can't access file descriptor %s\n", + arg + 3); + return NULL; + } + /* + * Can't do BIO_gets on an fd BIO so add a buffering + * BIO + */ + btmp = BIO_new(BIO_f_buffer()); + pwdbio = BIO_push(btmp, pwdbio); + } else if (!strcmp(arg, "stdin")) { + pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE); + if (!pwdbio) { + BIO_printf(err, "Can't open BIO for stdin\n"); + return NULL; + } + } else { + BIO_printf(err, "Invalid password argument \"%s\"\n", + arg); + return NULL; + } + } + i = BIO_gets(pwdbio, tpass, APP_PASS_LEN); + if (keepbio != 1) { + BIO_free_all(pwdbio); + pwdbio = NULL; + } + if (i <= 0) { + BIO_printf(err, "Error reading password from BIO\n"); + return NULL; + } + tmp = strchr(tpass, '\n'); + if (tmp) + *tmp = 0; + return strdup(tpass); +} + +int +add_oid_section(BIO *err, CONF *conf) +{ + char *p; + STACK_OF(CONF_VALUE) *sktmp; + CONF_VALUE *cnf; + int i; + + if (!(p = NCONF_get_string(conf, NULL, "oid_section"))) { + ERR_clear_error(); + return 1; + } + if (!(sktmp = NCONF_get_section(conf, p))) { + BIO_printf(err, "problem loading oid section %s\n", p); + return 0; + } + for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { + cnf = sk_CONF_VALUE_value(sktmp, i); + if (OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) { + BIO_printf(err, "problem creating object %s=%s\n", + cnf->name, cnf->value); + return 0; + } + } + return 1; +} + +static int +load_pkcs12(BIO *err, BIO *in, const char *desc, pem_password_cb *pem_cb, + void *cb_data, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) +{ + const char *pass; + char tpass[PEM_BUFSIZE]; + int len, ret = 0; + PKCS12 *p12; + + p12 = d2i_PKCS12_bio(in, NULL); + if (p12 == NULL) { + BIO_printf(err, "Error loading PKCS12 file for %s\n", desc); + goto die; + } + /* See if an empty password will do */ + if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0)) + pass = ""; + else { + if (!pem_cb) + pem_cb = password_callback; + len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data); + if (len < 0) { + BIO_printf(err, "Passpharse callback error for %s\n", + desc); + goto die; + } + if (len < PEM_BUFSIZE) + tpass[len] = 0; + if (!PKCS12_verify_mac(p12, tpass, len)) { + BIO_printf(err, + "Mac verify error (wrong password?) in PKCS12 file for %s\n", desc); + goto die; + } + pass = tpass; + } + ret = PKCS12_parse(p12, pass, pkey, cert, ca); + +die: + if (p12) + PKCS12_free(p12); + return ret; +} + +X509 * +load_cert(BIO *err, const char *file, int format, const char *pass, + const char *cert_descrip) +{ + X509 *x = NULL; + BIO *cert; + + if ((cert = BIO_new(BIO_s_file())) == NULL) { + ERR_print_errors(err); + goto end; + } + if (file == NULL) { + setvbuf(stdin, NULL, _IONBF, 0); + BIO_set_fp(cert, stdin, BIO_NOCLOSE); + } else { + if (BIO_read_filename(cert, file) <= 0) { + BIO_printf(err, "Error opening %s %s\n", + cert_descrip, file); + ERR_print_errors(err); + goto end; + } + } + + if (format == FORMAT_ASN1) + x = d2i_X509_bio(cert, NULL); + else if (format == FORMAT_NETSCAPE) { + NETSCAPE_X509 *nx; + nx = ASN1_item_d2i_bio(ASN1_ITEM_rptr(NETSCAPE_X509), + cert, NULL); + if (nx == NULL) + goto end; + + if ((strncmp(NETSCAPE_CERT_HDR, (char *) nx->header->data, + nx->header->length) != 0)) { + NETSCAPE_X509_free(nx); + BIO_printf(err, + "Error reading header on certificate\n"); + goto end; + } + x = nx->cert; + nx->cert = NULL; + NETSCAPE_X509_free(nx); + } else if (format == FORMAT_PEM) + x = PEM_read_bio_X509_AUX(cert, NULL, password_callback, NULL); + else if (format == FORMAT_PKCS12) { + if (!load_pkcs12(err, cert, cert_descrip, NULL, NULL, + NULL, &x, NULL)) + goto end; + } else { + BIO_printf(err, "bad input format specified for %s\n", + cert_descrip); + goto end; + } + +end: + if (x == NULL) { + BIO_printf(err, "unable to load certificate\n"); + ERR_print_errors(err); + } + BIO_free(cert); + return (x); +} + +EVP_PKEY * +load_key(BIO *err, const char *file, int format, int maybe_stdin, + const char *pass, const char *key_descrip) +{ + BIO *key = NULL; + EVP_PKEY *pkey = NULL; + PW_CB_DATA cb_data; + + cb_data.password = pass; + cb_data.prompt_info = file; + + if (file == NULL && (!maybe_stdin)) { + BIO_printf(err, "no keyfile specified\n"); + goto end; + } + key = BIO_new(BIO_s_file()); + if (key == NULL) { + ERR_print_errors(err); + goto end; + } + if (file == NULL && maybe_stdin) { + setvbuf(stdin, NULL, _IONBF, 0); + BIO_set_fp(key, stdin, BIO_NOCLOSE); + } else if (BIO_read_filename(key, file) <= 0) { + BIO_printf(err, "Error opening %s %s\n", + key_descrip, file); + ERR_print_errors(err); + goto end; + } + if (format == FORMAT_ASN1) { + pkey = d2i_PrivateKey_bio(key, NULL); + } else if (format == FORMAT_PEM) { + pkey = PEM_read_bio_PrivateKey(key, NULL, password_callback, &cb_data); + } +#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) + else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC) + pkey = load_netscape_key(err, key, file, key_descrip, format); +#endif + else if (format == FORMAT_PKCS12) { + if (!load_pkcs12(err, key, key_descrip, password_callback, &cb_data, + &pkey, NULL, NULL)) + goto end; + } +#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4) + else if (format == FORMAT_MSBLOB) + pkey = b2i_PrivateKey_bio(key); + else if (format == FORMAT_PVK) + pkey = b2i_PVK_bio(key, password_callback, + &cb_data); +#endif + else { + BIO_printf(err, "bad input format specified for key file\n"); + goto end; + } +end: + BIO_free(key); + if (pkey == NULL) { + BIO_printf(err, "unable to load %s\n", key_descrip); + ERR_print_errors(err); + } + return (pkey); +} + +EVP_PKEY * +load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, + const char *pass, const char *key_descrip) +{ + BIO *key = NULL; + EVP_PKEY *pkey = NULL; + PW_CB_DATA cb_data; + + cb_data.password = pass; + cb_data.prompt_info = file; + + if (file == NULL && !maybe_stdin) { + BIO_printf(err, "no keyfile specified\n"); + goto end; + } + key = BIO_new(BIO_s_file()); + if (key == NULL) { + ERR_print_errors(err); + goto end; + } + if (file == NULL && maybe_stdin) { + setvbuf(stdin, NULL, _IONBF, 0); + BIO_set_fp(key, stdin, BIO_NOCLOSE); + } else if (BIO_read_filename(key, file) <= 0) { + BIO_printf(err, "Error opening %s %s\n", key_descrip, file); + ERR_print_errors(err); + goto end; + } + if (format == FORMAT_ASN1) { + pkey = d2i_PUBKEY_bio(key, NULL); + } + else if (format == FORMAT_ASN1RSA) { + RSA *rsa; + rsa = d2i_RSAPublicKey_bio(key, NULL); + if (rsa) { + pkey = EVP_PKEY_new(); + if (pkey) + EVP_PKEY_set1_RSA(pkey, rsa); + RSA_free(rsa); + } else + pkey = NULL; + } else if (format == FORMAT_PEMRSA) { + RSA *rsa; + rsa = PEM_read_bio_RSAPublicKey(key, NULL, password_callback, &cb_data); + if (rsa) { + pkey = EVP_PKEY_new(); + if (pkey) + EVP_PKEY_set1_RSA(pkey, rsa); + RSA_free(rsa); + } else + pkey = NULL; + } + else if (format == FORMAT_PEM) { + pkey = PEM_read_bio_PUBKEY(key, NULL, password_callback, &cb_data); + } +#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) + else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC) + pkey = load_netscape_key(err, key, file, key_descrip, format); +#endif +#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) + else if (format == FORMAT_MSBLOB) + pkey = b2i_PublicKey_bio(key); +#endif + else { + BIO_printf(err, "bad input format specified for key file\n"); + goto end; + } + +end: + BIO_free(key); + if (pkey == NULL) + BIO_printf(err, "unable to load %s\n", key_descrip); + return (pkey); +} + +#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) +static EVP_PKEY * +load_netscape_key(BIO *err, BIO *key, const char *file, + const char *key_descrip, int format) +{ + EVP_PKEY *pkey; + BUF_MEM *buf; + RSA *rsa; + const unsigned char *p; + int size, i; + + buf = BUF_MEM_new(); + pkey = EVP_PKEY_new(); + size = 0; + if (buf == NULL || pkey == NULL) + goto error; + for (;;) { + if (!BUF_MEM_grow_clean(buf, size + 1024 * 10)) + goto error; + i = BIO_read(key, &(buf->data[size]), 1024 * 10); + size += i; + if (i == 0) + break; + if (i < 0) { + BIO_printf(err, "Error reading %s %s", + key_descrip, file); + goto error; + } + } + p = (unsigned char *) buf->data; + rsa = d2i_RSA_NET(NULL, &p, (long) size, NULL, + (format == FORMAT_IISSGC ? 1 : 0)); + if (rsa == NULL) + goto error; + BUF_MEM_free(buf); + EVP_PKEY_set1_RSA(pkey, rsa); + return pkey; + +error: + BUF_MEM_free(buf); + EVP_PKEY_free(pkey); + return NULL; +} +#endif /* ndef OPENSSL_NO_RC4 */ + +static int +load_certs_crls(BIO *err, const char *file, int format, const char *pass, + const char *desc, STACK_OF(X509) **pcerts, + STACK_OF(X509_CRL) **pcrls) +{ + int i; + BIO *bio; + STACK_OF(X509_INFO) *xis = NULL; + X509_INFO *xi; + PW_CB_DATA cb_data; + int rv = 0; + + cb_data.password = pass; + cb_data.prompt_info = file; + + if (format != FORMAT_PEM) { + BIO_printf(err, "bad input format specified for %s\n", desc); + return 0; + } + if (file == NULL) + bio = BIO_new_fp(stdin, BIO_NOCLOSE); + else + bio = BIO_new_file(file, "r"); + + if (bio == NULL) { + BIO_printf(err, "Error opening %s %s\n", + desc, file ? file : "stdin"); + ERR_print_errors(err); + return 0; + } + xis = PEM_X509_INFO_read_bio(bio, NULL, password_callback, &cb_data); + + BIO_free(bio); + + if (pcerts) { + *pcerts = sk_X509_new_null(); + if (!*pcerts) + goto end; + } + if (pcrls) { + *pcrls = sk_X509_CRL_new_null(); + if (!*pcrls) + goto end; + } + for (i = 0; i < sk_X509_INFO_num(xis); i++) { + xi = sk_X509_INFO_value(xis, i); + if (xi->x509 && pcerts) { + if (!sk_X509_push(*pcerts, xi->x509)) + goto end; + xi->x509 = NULL; + } + if (xi->crl && pcrls) { + if (!sk_X509_CRL_push(*pcrls, xi->crl)) + goto end; + xi->crl = NULL; + } + } + + if (pcerts && sk_X509_num(*pcerts) > 0) + rv = 1; + + if (pcrls && sk_X509_CRL_num(*pcrls) > 0) + rv = 1; + +end: + if (xis) + sk_X509_INFO_pop_free(xis, X509_INFO_free); + + if (rv == 0) { + if (pcerts) { + sk_X509_pop_free(*pcerts, X509_free); + *pcerts = NULL; + } + if (pcrls) { + sk_X509_CRL_pop_free(*pcrls, X509_CRL_free); + *pcrls = NULL; + } + BIO_printf(err, "unable to load %s\n", + pcerts ? "certificates" : "CRLs"); + ERR_print_errors(err); + } + return rv; +} + +STACK_OF(X509) * +load_certs(BIO *err, const char *file, int format, const char *pass, + const char *desc) +{ + STACK_OF(X509) *certs; + + if (!load_certs_crls(err, file, format, pass, desc, &certs, NULL)) + return NULL; + return certs; +} + +STACK_OF(X509_CRL) * +load_crls(BIO *err, const char *file, int format, const char *pass, + const char *desc) +{ + STACK_OF(X509_CRL) *crls; + + if (!load_certs_crls(err, file, format, pass, desc, NULL, &crls)) + return NULL; + return crls; +} + +#define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) +/* Return error for unknown extensions */ +#define X509V3_EXT_DEFAULT 0 +/* Print error for unknown extensions */ +#define X509V3_EXT_ERROR_UNKNOWN (1L << 16) +/* ASN1 parse unknown extensions */ +#define X509V3_EXT_PARSE_UNKNOWN (2L << 16) +/* BIO_dump unknown extensions */ +#define X509V3_EXT_DUMP_UNKNOWN (3L << 16) + +#define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \ + X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION) + +int +set_cert_ex(unsigned long *flags, const char *arg) +{ + static const NAME_EX_TBL cert_tbl[] = { + {"compatible", X509_FLAG_COMPAT, 0xffffffffl}, + {"ca_default", X509_FLAG_CA, 0xffffffffl}, + {"no_header", X509_FLAG_NO_HEADER, 0}, + {"no_version", X509_FLAG_NO_VERSION, 0}, + {"no_serial", X509_FLAG_NO_SERIAL, 0}, + {"no_signame", X509_FLAG_NO_SIGNAME, 0}, + {"no_validity", X509_FLAG_NO_VALIDITY, 0}, + {"no_subject", X509_FLAG_NO_SUBJECT, 0}, + {"no_issuer", X509_FLAG_NO_ISSUER, 0}, + {"no_pubkey", X509_FLAG_NO_PUBKEY, 0}, + {"no_extensions", X509_FLAG_NO_EXTENSIONS, 0}, + {"no_sigdump", X509_FLAG_NO_SIGDUMP, 0}, + {"no_aux", X509_FLAG_NO_AUX, 0}, + {"no_attributes", X509_FLAG_NO_ATTRIBUTES, 0}, + {"ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK}, + {"ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, + {"ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, + {"ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, + {NULL, 0, 0} + }; + return set_multi_opts(flags, arg, cert_tbl); +} + +int +set_name_ex(unsigned long *flags, const char *arg) +{ + static const NAME_EX_TBL ex_tbl[] = { + {"esc_2253", ASN1_STRFLGS_ESC_2253, 0}, + {"esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0}, + {"esc_msb", ASN1_STRFLGS_ESC_MSB, 0}, + {"use_quote", ASN1_STRFLGS_ESC_QUOTE, 0}, + {"utf8", ASN1_STRFLGS_UTF8_CONVERT, 0}, + {"ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0}, + {"show_type", ASN1_STRFLGS_SHOW_TYPE, 0}, + {"dump_all", ASN1_STRFLGS_DUMP_ALL, 0}, + {"dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0}, + {"dump_der", ASN1_STRFLGS_DUMP_DER, 0}, + {"compat", XN_FLAG_COMPAT, 0xffffffffL}, + {"sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK}, + {"sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK}, + {"sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK}, + {"sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK}, + {"dn_rev", XN_FLAG_DN_REV, 0}, + {"nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK}, + {"sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK}, + {"lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK}, + {"align", XN_FLAG_FN_ALIGN, 0}, + {"oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK}, + {"space_eq", XN_FLAG_SPC_EQ, 0}, + {"dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0}, + {"RFC2253", XN_FLAG_RFC2253, 0xffffffffL}, + {"oneline", XN_FLAG_ONELINE, 0xffffffffL}, + {"multiline", XN_FLAG_MULTILINE, 0xffffffffL}, + {"ca_default", XN_FLAG_MULTILINE, 0xffffffffL}, + {NULL, 0, 0} + }; + return set_multi_opts(flags, arg, ex_tbl); +} + +int +set_ext_copy(int *copy_type, const char *arg) +{ + if (!strcasecmp(arg, "none")) + *copy_type = EXT_COPY_NONE; + else if (!strcasecmp(arg, "copy")) + *copy_type = EXT_COPY_ADD; + else if (!strcasecmp(arg, "copyall")) + *copy_type = EXT_COPY_ALL; + else + return 0; + return 1; +} + +int +copy_extensions(X509 *x, X509_REQ *req, int copy_type) +{ + STACK_OF(X509_EXTENSION) *exts = NULL; + X509_EXTENSION *ext, *tmpext; + ASN1_OBJECT *obj; + int i, idx, ret = 0; + + if (!x || !req || (copy_type == EXT_COPY_NONE)) + return 1; + exts = X509_REQ_get_extensions(req); + + for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { + ext = sk_X509_EXTENSION_value(exts, i); + obj = X509_EXTENSION_get_object(ext); + idx = X509_get_ext_by_OBJ(x, obj, -1); + /* Does extension exist? */ + if (idx != -1) { + /* If normal copy don't override existing extension */ + if (copy_type == EXT_COPY_ADD) + continue; + /* Delete all extensions of same type */ + do { + tmpext = X509_get_ext(x, idx); + X509_delete_ext(x, idx); + X509_EXTENSION_free(tmpext); + idx = X509_get_ext_by_OBJ(x, obj, -1); + } while (idx != -1); + } + if (!X509_add_ext(x, ext, -1)) + goto end; + } + + ret = 1; + +end: + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + + return ret; +} + +static int +set_multi_opts(unsigned long *flags, const char *arg, + const NAME_EX_TBL *in_tbl) +{ + STACK_OF(CONF_VALUE) *vals; + CONF_VALUE *val; + int i, ret = 1; + + if (!arg) + return 0; + vals = X509V3_parse_list(arg); + for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { + val = sk_CONF_VALUE_value(vals, i); + if (!set_table_opts(flags, val->name, in_tbl)) + ret = 0; + } + sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); + return ret; +} + +static int +set_table_opts(unsigned long *flags, const char *arg, + const NAME_EX_TBL *in_tbl) +{ + char c; + const NAME_EX_TBL *ptbl; + + c = arg[0]; + if (c == '-') { + c = 0; + arg++; + } else if (c == '+') { + c = 1; + arg++; + } else + c = 1; + + for (ptbl = in_tbl; ptbl->name; ptbl++) { + if (!strcasecmp(arg, ptbl->name)) { + *flags &= ~ptbl->mask; + if (c) + *flags |= ptbl->flag; + else + *flags &= ~ptbl->flag; + return 1; + } + } + return 0; +} + +void +print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags) +{ + char *buf; + char mline = 0; + int indent = 0; + + if (title) + BIO_puts(out, title); + if ((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { + mline = 1; + indent = 4; + } + if (lflags == XN_FLAG_COMPAT) { + buf = X509_NAME_oneline(nm, 0, 0); + BIO_puts(out, buf); + BIO_puts(out, "\n"); + free(buf); + } else { + if (mline) + BIO_puts(out, "\n"); + X509_NAME_print_ex(out, nm, indent, lflags); + BIO_puts(out, "\n"); + } +} + +X509_STORE * +setup_verify(BIO *bp, char *CAfile, char *CApath) +{ + X509_STORE *store; + X509_LOOKUP *lookup; + + if (!(store = X509_STORE_new())) + goto end; + lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); + if (lookup == NULL) + goto end; + if (CAfile) { + if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) { + BIO_printf(bp, "Error loading file %s\n", CAfile); + goto end; + } + } else + X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); + + lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); + if (lookup == NULL) + goto end; + if (CApath) { + if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) { + BIO_printf(bp, "Error loading directory %s\n", CApath); + goto end; + } + } else + X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); + + ERR_clear_error(); + return store; + +end: + X509_STORE_free(store); + return NULL; +} + +int +load_config(BIO *err, CONF *cnf) +{ + static int load_config_called = 0; + + if (load_config_called) + return 1; + load_config_called = 1; + if (cnf == NULL) + cnf = config; + if (cnf == NULL) + return 1; + + OPENSSL_load_builtin_modules(); + + if (CONF_modules_load(cnf, NULL, 0) <= 0) { + BIO_printf(err, "Error configuring OpenSSL\n"); + ERR_print_errors(err); + return 0; + } + return 1; +} + +char * +make_config_name() +{ + const char *t = X509_get_default_cert_area(); + char *p; + + if (asprintf(&p, "%s/openssl.cnf", t) == -1) + return NULL; + return p; +} + +static unsigned long +index_serial_hash(const OPENSSL_CSTRING *a) +{ + const char *n; + + n = a[DB_serial]; + while (*n == '0') + n++; + return (lh_strhash(n)); +} + +static int +index_serial_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b) +{ + const char *aa, *bb; + + for (aa = a[DB_serial]; *aa == '0'; aa++) + ; + for (bb = b[DB_serial]; *bb == '0'; bb++) + ; + return (strcmp(aa, bb)); +} + +static int +index_name_qual(char **a) +{ + return (a[0][0] == 'V'); +} + +static unsigned long +index_name_hash(const OPENSSL_CSTRING *a) +{ + return (lh_strhash(a[DB_name])); +} + +int +index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b) +{ + return (strcmp(a[DB_name], b[DB_name])); +} + +static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING) +static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING) +static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING) +static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING) + +#define BUFLEN 256 + +BIGNUM * +load_serial(char *serialfile, int create, ASN1_INTEGER **retai) +{ + BIO *in = NULL; + BIGNUM *ret = NULL; + char buf[1024]; + ASN1_INTEGER *ai = NULL; + + ai = ASN1_INTEGER_new(); + if (ai == NULL) + goto err; + + if ((in = BIO_new(BIO_s_file())) == NULL) { + ERR_print_errors(bio_err); + goto err; + } + if (BIO_read_filename(in, serialfile) <= 0) { + if (!create) { + perror(serialfile); + goto err; + } else { + ret = BN_new(); + if (ret == NULL || !rand_serial(ret, ai)) + BIO_printf(bio_err, "Out of memory\n"); + } + } else { + if (!a2i_ASN1_INTEGER(in, ai, buf, 1024)) { + BIO_printf(bio_err, "unable to load number from %s\n", + serialfile); + goto err; + } + ret = ASN1_INTEGER_to_BN(ai, NULL); + if (ret == NULL) { + BIO_printf(bio_err, + "error converting number from bin to BIGNUM\n"); + goto err; + } + } + + if (ret && retai) { + *retai = ai; + ai = NULL; + } + +err: + if (in != NULL) + BIO_free(in); + if (ai != NULL) + ASN1_INTEGER_free(ai); + return (ret); +} + +int +save_serial(char *serialfile, char *suffix, BIGNUM *serial, + ASN1_INTEGER **retai) +{ + char buf[1][BUFLEN]; + BIO *out = NULL; + int ret = 0, n; + ASN1_INTEGER *ai = NULL; + int j; + + if (suffix == NULL) + j = strlen(serialfile); + else + j = strlen(serialfile) + strlen(suffix) + 1; + if (j >= BUFLEN) { + BIO_printf(bio_err, "file name too long\n"); + goto err; + } + if (suffix == NULL) + n = strlcpy(buf[0], serialfile, BUFLEN); + else + n = snprintf(buf[0], sizeof buf[0], "%s.%s", + serialfile, suffix); + if (n == -1 || n >= sizeof(buf[0])) { + BIO_printf(bio_err, "serial too long\n"); + goto err; + } + out = BIO_new(BIO_s_file()); + if (out == NULL) { + ERR_print_errors(bio_err); + goto err; + } + if (BIO_write_filename(out, buf[0]) <= 0) { + perror(serialfile); + goto err; + } + if ((ai = BN_to_ASN1_INTEGER(serial, NULL)) == NULL) { + BIO_printf(bio_err, + "error converting serial to ASN.1 format\n"); + goto err; + } + i2a_ASN1_INTEGER(out, ai); + BIO_puts(out, "\n"); + ret = 1; + if (retai) { + *retai = ai; + ai = NULL; + } + +err: + if (out != NULL) + BIO_free_all(out); + if (ai != NULL) + ASN1_INTEGER_free(ai); + return (ret); +} + +int +rotate_serial(char *serialfile, char *new_suffix, char *old_suffix) +{ + char buf[5][BUFLEN]; + int i, j; + + i = strlen(serialfile) + strlen(old_suffix); + j = strlen(serialfile) + strlen(new_suffix); + if (i > j) + j = i; + if (j + 1 >= BUFLEN) { + BIO_printf(bio_err, "file name too long\n"); + goto err; + } + snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, new_suffix); + snprintf(buf[1], sizeof buf[1], "%s.%s", serialfile, old_suffix); + + + if (rename(serialfile, buf[1]) < 0 && + errno != ENOENT && errno != ENOTDIR) { + BIO_printf(bio_err, "unable to rename %s to %s\n", + serialfile, buf[1]); + perror("reason"); + goto err; + } + + + if (rename(buf[0], serialfile) < 0) { + BIO_printf(bio_err, "unable to rename %s to %s\n", + buf[0], serialfile); + perror("reason"); + if (rename(buf[1], serialfile) < 0) { + BIO_printf(bio_err, "unable to rename %s to %s\n", + buf[1], serialfile); + perror("reason"); + } + goto err; + } + return 1; + +err: + return 0; +} + +int +rand_serial(BIGNUM *b, ASN1_INTEGER *ai) +{ + BIGNUM *btmp; + int ret = 0; + + if (b) + btmp = b; + else + btmp = BN_new(); + + if (!btmp) + return 0; + + if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0)) + goto error; + if (ai && !BN_to_ASN1_INTEGER(btmp, ai)) + goto error; + + ret = 1; + +error: + if (!b) + BN_free(btmp); + + return ret; +} + +CA_DB * +load_index(char *dbfile, DB_ATTR *db_attr) +{ + CA_DB *retdb = NULL; + TXT_DB *tmpdb = NULL; + BIO *in = BIO_new(BIO_s_file()); + CONF *dbattr_conf = NULL; + char buf[1][BUFLEN]; + long errorline = -1; + + if (in == NULL) { + ERR_print_errors(bio_err); + goto err; + } + if (BIO_read_filename(in, dbfile) <= 0) { + perror(dbfile); + BIO_printf(bio_err, "unable to open '%s'\n", dbfile); + goto err; + } + if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL) + goto err; + + snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile); + dbattr_conf = NCONF_new(NULL); + if (NCONF_load(dbattr_conf, buf[0], &errorline) <= 0) { + if (errorline > 0) { + BIO_printf(bio_err, + "error on line %ld of db attribute file '%s'\n", + errorline, buf[0]); + goto err; + } else { + NCONF_free(dbattr_conf); + dbattr_conf = NULL; + } + } + if ((retdb = malloc(sizeof(CA_DB))) == NULL) { + fprintf(stderr, "Out of memory\n"); + goto err; + } + retdb->db = tmpdb; + tmpdb = NULL; + if (db_attr) + retdb->attributes = *db_attr; + else { + retdb->attributes.unique_subject = 1; + } + + if (dbattr_conf) { + char *p = NCONF_get_string(dbattr_conf, NULL, "unique_subject"); + if (p) { + retdb->attributes.unique_subject = parse_yesno(p, 1); + } + } + +err: + if (dbattr_conf) + NCONF_free(dbattr_conf); + if (tmpdb) + TXT_DB_free(tmpdb); + if (in) + BIO_free_all(in); + return retdb; +} + +int +index_index(CA_DB *db) +{ + if (!TXT_DB_create_index(db->db, DB_serial, NULL, + LHASH_HASH_FN(index_serial), LHASH_COMP_FN(index_serial))) { + BIO_printf(bio_err, + "error creating serial number index:(%ld,%ld,%ld)\n", + db->db->error, db->db->arg1, db->db->arg2); + return 0; + } + if (db->attributes.unique_subject && + !TXT_DB_create_index(db->db, DB_name, index_name_qual, + LHASH_HASH_FN(index_name), LHASH_COMP_FN(index_name))) { + BIO_printf(bio_err, "error creating name index:(%ld,%ld,%ld)\n", + db->db->error, db->db->arg1, db->db->arg2); + return 0; + } + return 1; +} + +int +save_index(const char *dbfile, const char *suffix, CA_DB *db) +{ + char buf[3][BUFLEN]; + BIO *out = BIO_new(BIO_s_file()); + int j; + + if (out == NULL) { + ERR_print_errors(bio_err); + goto err; + } + j = strlen(dbfile) + strlen(suffix); + if (j + 6 >= BUFLEN) { + BIO_printf(bio_err, "file name too long\n"); + goto err; + } + snprintf(buf[2], sizeof buf[2], "%s.attr", dbfile); + snprintf(buf[1], sizeof buf[1], "%s.attr.%s", dbfile, suffix); + snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, suffix); + + + if (BIO_write_filename(out, buf[0]) <= 0) { + perror(dbfile); + BIO_printf(bio_err, "unable to open '%s'\n", dbfile); + goto err; + } + j = TXT_DB_write(out, db->db); + if (j <= 0) + goto err; + + BIO_free(out); + + out = BIO_new(BIO_s_file()); + + + if (BIO_write_filename(out, buf[1]) <= 0) { + perror(buf[2]); + BIO_printf(bio_err, "unable to open '%s'\n", buf[2]); + goto err; + } + BIO_printf(out, "unique_subject = %s\n", + db->attributes.unique_subject ? "yes" : "no"); + BIO_free(out); + + return 1; + +err: + return 0; +} + +int +rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix) +{ + char buf[5][BUFLEN]; + int i, j; + + i = strlen(dbfile) + strlen(old_suffix); + j = strlen(dbfile) + strlen(new_suffix); + if (i > j) + j = i; + if (j + 6 >= BUFLEN) { + BIO_printf(bio_err, "file name too long\n"); + goto err; + } + snprintf(buf[4], sizeof buf[4], "%s.attr", dbfile); + snprintf(buf[2], sizeof buf[2], "%s.attr.%s", dbfile, new_suffix); + snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, new_suffix); + snprintf(buf[1], sizeof buf[1], "%s.%s", dbfile, old_suffix); + snprintf(buf[3], sizeof buf[3], "%s.attr.%s", dbfile, old_suffix); + + + if (rename(dbfile, buf[1]) < 0 && errno != ENOENT && errno != ENOTDIR) { + BIO_printf(bio_err, "unable to rename %s to %s\n", + dbfile, buf[1]); + perror("reason"); + goto err; + } + + + if (rename(buf[0], dbfile) < 0) { + BIO_printf(bio_err, "unable to rename %s to %s\n", + buf[0], dbfile); + perror("reason"); + if (rename(buf[1], dbfile) < 0) { + BIO_printf(bio_err, "unable to rename %s to %s\n", + buf[1], dbfile); + perror("reason"); + } + goto err; + } + + + if (rename(buf[4], buf[3]) < 0 && errno != ENOENT && errno != ENOTDIR) { + BIO_printf(bio_err, "unable to rename %s to %s\n", + buf[4], buf[3]); + perror("reason"); + if (rename(dbfile, buf[0]) < 0) { + BIO_printf(bio_err, "unable to rename %s to %s\n", + dbfile, buf[0]); + perror("reason"); + } + if (rename(buf[1], dbfile) < 0) { + BIO_printf(bio_err, "unable to rename %s to %s\n", + buf[1], dbfile); + perror("reason"); + } + goto err; + } + + + if (rename(buf[2], buf[4]) < 0) { + BIO_printf(bio_err, "unable to rename %s to %s\n", + buf[2], buf[4]); + perror("reason"); + if (rename(buf[3], buf[4]) < 0) { + BIO_printf(bio_err, "unable to rename %s to %s\n", + buf[3], buf[4]); + perror("reason"); + } + if (rename(dbfile, buf[0]) < 0) { + BIO_printf(bio_err, "unable to rename %s to %s\n", + dbfile, buf[0]); + perror("reason"); + } + if (rename(buf[1], dbfile) < 0) { + BIO_printf(bio_err, "unable to rename %s to %s\n", + buf[1], dbfile); + perror("reason"); + } + goto err; + } + return 1; + +err: + return 0; +} + +void +free_index(CA_DB *db) +{ + if (db) { + if (db->db) + TXT_DB_free(db->db); + free(db); + } +} + +int +parse_yesno(const char *str, int def) +{ + int ret = def; + + if (str) { + switch (*str) { + case 'f': /* false */ + case 'F': /* FALSE */ + case 'n': /* no */ + case 'N': /* NO */ + case '0': /* 0 */ + ret = 0; + break; + case 't': /* true */ + case 'T': /* TRUE */ + case 'y': /* yes */ + case 'Y': /* YES */ + case '1': /* 1 */ + ret = 1; + break; + default: + ret = def; + break; + } + } + return ret; +} + +/* + * subject is expected to be in the format /type0=value0/type1=value1/type2=... + * where characters may be escaped by \ + */ +X509_NAME * +parse_name(char *subject, long chtype, int multirdn) +{ + X509_NAME *name = NULL; + size_t buflen, max_ne; + char **ne_types, **ne_values; + char *buf, *bp, *sp; + int i, nid, ne_num = 0; + int *mval; + + /* + * Buffer to copy the types and values into. Due to escaping the + * copy can only become shorter. + */ + buflen = strlen(subject) + 1; + buf = malloc(buflen); + + /* Maximum number of name elements. */ + max_ne = buflen / 2 + 1; + ne_types = reallocarray(NULL, max_ne, sizeof(char *)); + ne_values = reallocarray(NULL, max_ne, sizeof(char *)); + mval = reallocarray(NULL, max_ne, sizeof(int)); + + if (buf == NULL || ne_types == NULL || ne_values == NULL || + mval == NULL) { + BIO_printf(bio_err, "malloc error\n"); + goto error; + } + + bp = buf; + sp = subject; + + if (*subject != '/') { + BIO_printf(bio_err, "Subject does not start with '/'.\n"); + goto error; + } + + /* Skip leading '/'. */ + sp++; + + /* No multivalued RDN by default. */ + mval[ne_num] = 0; + + while (*sp) { + /* Collect type. */ + ne_types[ne_num] = bp; + while (*sp) { + /* is there anything to escape in the type...? */ + if (*sp == '\\') { + if (*++sp) + *bp++ = *sp++; + else { + BIO_printf(bio_err, "escape character " + "at end of string\n"); + goto error; + } + } else if (*sp == '=') { + sp++; + *bp++ = '\0'; + break; + } else + *bp++ = *sp++; + } + if (!*sp) { + BIO_printf(bio_err, "end of string encountered while " + "processing type of subject name element #%d\n", + ne_num); + goto error; + } + ne_values[ne_num] = bp; + while (*sp) { + if (*sp == '\\') { + if (*++sp) + *bp++ = *sp++; + else { + BIO_printf(bio_err, "escape character " + "at end of string\n"); + goto error; + } + } else if (*sp == '/') { + sp++; + /* no multivalued RDN by default */ + mval[ne_num + 1] = 0; + break; + } else if (*sp == '+' && multirdn) { + /* a not escaped + signals a multivalued RDN */ + sp++; + mval[ne_num + 1] = -1; + break; + } else + *bp++ = *sp++; + } + *bp++ = '\0'; + ne_num++; + } + + if ((name = X509_NAME_new()) == NULL) + goto error; + + for (i = 0; i < ne_num; i++) { + if ((nid = OBJ_txt2nid(ne_types[i])) == NID_undef) { + BIO_printf(bio_err, + "Subject Attribute %s has no known NID, skipped\n", + ne_types[i]); + continue; + } + if (!*ne_values[i]) { + BIO_printf(bio_err, "No value provided for Subject " + "Attribute %s, skipped\n", ne_types[i]); + continue; + } + if (!X509_NAME_add_entry_by_NID(name, nid, chtype, + (unsigned char *) ne_values[i], -1, -1, mval[i])) + goto error; + } + goto done; + +error: + X509_NAME_free(name); + name = NULL; + +done: + free(ne_values); + free(ne_types); + free(mval); + free(buf); + + return name; +} + +int +args_verify(char ***pargs, int *pargc, int *badarg, BIO *err, + X509_VERIFY_PARAM **pm) +{ + ASN1_OBJECT *otmp = NULL; + unsigned long flags = 0; + int i; + int purpose = 0, depth = -1; + char **oldargs = *pargs; + char *arg = **pargs, *argn = (*pargs)[1]; + time_t at_time = 0; + const char *errstr = NULL; + + if (!strcmp(arg, "-policy")) { + if (!argn) + *badarg = 1; + else { + otmp = OBJ_txt2obj(argn, 0); + if (!otmp) { + BIO_printf(err, "Invalid Policy \"%s\"\n", + argn); + *badarg = 1; + } + } + (*pargs)++; + } else if (strcmp(arg, "-purpose") == 0) { + X509_PURPOSE *xptmp; + if (!argn) + *badarg = 1; + else { + i = X509_PURPOSE_get_by_sname(argn); + if (i < 0) { + BIO_printf(err, "unrecognized purpose\n"); + *badarg = 1; + } else { + xptmp = X509_PURPOSE_get0(i); + purpose = X509_PURPOSE_get_id(xptmp); + } + } + (*pargs)++; + } else if (strcmp(arg, "-verify_depth") == 0) { + if (!argn) + *badarg = 1; + else { + depth = strtonum(argn, 1, INT_MAX, &errstr); + if (errstr) { + BIO_printf(err, "invalid depth %s: %s\n", + argn, errstr); + *badarg = 1; + } + } + (*pargs)++; + } else if (strcmp(arg, "-attime") == 0) { + if (!argn) + *badarg = 1; + else { + long long timestamp; + /* + * interpret the -attime argument as seconds since + * Epoch + */ + if (sscanf(argn, "%lli", ×tamp) != 1) { + BIO_printf(bio_err, + "Error parsing timestamp %s\n", + argn); + *badarg = 1; + } + /* XXX 2038 truncation */ + at_time = (time_t) timestamp; + } + (*pargs)++; + } else if (!strcmp(arg, "-ignore_critical")) + flags |= X509_V_FLAG_IGNORE_CRITICAL; + else if (!strcmp(arg, "-issuer_checks")) + flags |= X509_V_FLAG_CB_ISSUER_CHECK; + else if (!strcmp(arg, "-crl_check")) + flags |= X509_V_FLAG_CRL_CHECK; + else if (!strcmp(arg, "-crl_check_all")) + flags |= X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL; + else if (!strcmp(arg, "-policy_check")) + flags |= X509_V_FLAG_POLICY_CHECK; + else if (!strcmp(arg, "-explicit_policy")) + flags |= X509_V_FLAG_EXPLICIT_POLICY; + else if (!strcmp(arg, "-inhibit_any")) + flags |= X509_V_FLAG_INHIBIT_ANY; + else if (!strcmp(arg, "-inhibit_map")) + flags |= X509_V_FLAG_INHIBIT_MAP; + else if (!strcmp(arg, "-x509_strict")) + flags |= X509_V_FLAG_X509_STRICT; + else if (!strcmp(arg, "-extended_crl")) + flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT; + else if (!strcmp(arg, "-use_deltas")) + flags |= X509_V_FLAG_USE_DELTAS; + else if (!strcmp(arg, "-policy_print")) + flags |= X509_V_FLAG_NOTIFY_POLICY; + else if (!strcmp(arg, "-check_ss_sig")) + flags |= X509_V_FLAG_CHECK_SS_SIGNATURE; + else + return 0; + + if (*badarg) { + if (*pm) + X509_VERIFY_PARAM_free(*pm); + *pm = NULL; + goto end; + } + if (!*pm && !(*pm = X509_VERIFY_PARAM_new())) { + *badarg = 1; + goto end; + } + if (otmp) { + X509_VERIFY_PARAM_add0_policy(*pm, otmp); + otmp = NULL; + } + if (flags) + X509_VERIFY_PARAM_set_flags(*pm, flags); + + if (purpose) + X509_VERIFY_PARAM_set_purpose(*pm, purpose); + + if (depth >= 0) + X509_VERIFY_PARAM_set_depth(*pm, depth); + + if (at_time) + X509_VERIFY_PARAM_set_time(*pm, at_time); + +end: + (*pargs)++; + + if (pargc) + *pargc -= *pargs - oldargs; + + ASN1_OBJECT_free(otmp); + return 1; +} + +/* Read whole contents of a BIO into an allocated memory buffer and + * return it. + */ + +int +bio_to_mem(unsigned char **out, int maxlen, BIO *in) +{ + BIO *mem; + int len, ret; + unsigned char tbuf[1024]; + + mem = BIO_new(BIO_s_mem()); + if (!mem) + return -1; + for (;;) { + if ((maxlen != -1) && maxlen < 1024) + len = maxlen; + else + len = 1024; + len = BIO_read(in, tbuf, len); + if (len <= 0) + break; + if (BIO_write(mem, tbuf, len) != len) { + BIO_free(mem); + return -1; + } + maxlen -= len; + + if (maxlen == 0) + break; + } + ret = BIO_get_mem_data(mem, (char **) out); + BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY); + BIO_free(mem); + return ret; +} + +int +pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value) +{ + int rv; + char *stmp, *vtmp = NULL; + + if (value == NULL) + return -1; + stmp = strdup(value); + if (!stmp) + return -1; + vtmp = strchr(stmp, ':'); + if (vtmp) { + *vtmp = 0; + vtmp++; + } + rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp); + free(stmp); + + return rv; +} + +static void +nodes_print(BIO *out, const char *name, STACK_OF(X509_POLICY_NODE) *nodes) +{ + X509_POLICY_NODE *node; + int i; + + BIO_printf(out, "%s Policies:", name); + if (nodes) { + BIO_puts(out, "\n"); + for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) { + node = sk_X509_POLICY_NODE_value(nodes, i); + X509_POLICY_NODE_print(out, node, 2); + } + } else + BIO_puts(out, " \n"); +} + +void +policies_print(BIO *out, X509_STORE_CTX *ctx) +{ + X509_POLICY_TREE *tree; + int explicit_policy; + int free_out = 0; + + if (out == NULL) { + out = BIO_new_fp(stderr, BIO_NOCLOSE); + free_out = 1; + } + tree = X509_STORE_CTX_get0_policy_tree(ctx); + explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx); + + BIO_printf(out, "Require explicit Policy: %s\n", + explicit_policy ? "True" : "False"); + + nodes_print(out, "Authority", X509_policy_tree_get0_policies(tree)); + nodes_print(out, "User", X509_policy_tree_get0_user_policies(tree)); + if (free_out) + BIO_free(out); +} + +/* next_protos_parse parses a comma separated list of strings into a string + * in a format suitable for passing to SSL_CTX_set_next_protos_advertised. + * outlen: (output) set to the length of the resulting buffer on success. + * err: (maybe NULL) on failure, an error message line is written to this BIO. + * in: a NUL termianted string like "abc,def,ghi" + * + * returns: a malloced buffer or NULL on failure. + */ +unsigned char * +next_protos_parse(unsigned short *outlen, const char *in) +{ + size_t len; + unsigned char *out; + size_t i, start = 0; + + len = strlen(in); + if (len >= 65535) + return NULL; + + out = malloc(strlen(in) + 1); + if (!out) + return NULL; + + for (i = 0; i <= len; ++i) { + if (i == len || in[i] == ',') { + if (i - start > 255) { + free(out); + return NULL; + } + out[start] = i - start; + start = i + 1; + } else + out[i + 1] = in[i]; + } + + *outlen = len + 1; + return out; +} + +int +app_isdir(const char *name) +{ + struct stat st; + + if (stat(name, &st) == 0) + return S_ISDIR(st.st_mode); + return -1; +} + +#define OPTION_WIDTH 18 + +void +options_usage(struct option *opts) +{ + const char *p, *q; + char optstr[32]; + int i; + + for (i = 0; opts[i].name != NULL; i++) { + if (opts[i].desc == NULL) + continue; + + snprintf(optstr, sizeof(optstr), "-%s %s", opts[i].name, + (opts[i].argname != NULL) ? opts[i].argname : ""); + fprintf(stderr, " %-*s", OPTION_WIDTH, optstr); + if (strlen(optstr) > OPTION_WIDTH) + fprintf(stderr, "\n %-*s", OPTION_WIDTH, ""); + + p = opts[i].desc; + while ((q = strchr(p, '\n')) != NULL) { + fprintf(stderr, " %.*s", (int)(q - p), p); + fprintf(stderr, "\n %-*s", OPTION_WIDTH, ""); + p = q + 1; + } + fprintf(stderr, " %s\n", p); + } +} + +int +options_parse(int argc, char **argv, struct option *opts, char **unnamed, + int *argsused) +{ + const char *errstr; + struct option *opt; + long long val; + char *arg, *p; + int fmt, used; + int ord = 0; + int i, j; + + if (unnamed != NULL) + *unnamed = NULL; + + for (i = 1; i < argc; i++) { + p = arg = argv[i]; + + /* Single unnamed argument (without leading hyphen). */ + if (*p++ != '-') { + if (argsused != NULL) + goto done; + if (unnamed == NULL) + goto unknown; + if (*unnamed != NULL) + goto toomany; + *unnamed = arg; + continue; + } + + /* End of named options (single hyphen). */ + if (*p == '\0') { + if (++i >= argc) + goto done; + if (argsused != NULL) + goto done; + if (unnamed != NULL && i == argc - 1) { + if (*unnamed != NULL) + goto toomany; + *unnamed = argv[i]; + continue; + } + goto unknown; + } + + /* See if there is a matching option... */ + for (j = 0; opts[j].name != NULL; j++) { + if (strcmp(p, opts[j].name) == 0) + break; + } + opt = &opts[j]; + if (opt->name == NULL && opt->type == 0) + goto unknown; + + if (opt->type == OPTION_ARG || + opt->type == OPTION_ARG_FORMAT || + opt->type == OPTION_ARG_FUNC || + opt->type == OPTION_ARG_INT || + opt->type == OPTION_ARG_LONG) { + if (++i >= argc) { + fprintf(stderr, "missing %s argument for -%s\n", + opt->argname, opt->name); + return (1); + } + } + + switch (opt->type) { + case OPTION_ARG: + *opt->opt.arg = argv[i]; + break; + + case OPTION_ARGV_FUNC: + if (opt->opt.argvfunc(argc - i, &argv[i], &used) != 0) + return (1); + i += used - 1; + break; + + case OPTION_ARG_FORMAT: + fmt = str2fmt(argv[i]); + if (fmt == FORMAT_UNDEF) { + fprintf(stderr, "unknown %s '%s' for -%s\n", + opt->argname, argv[i], opt->name); + return (1); + } + *opt->opt.value = fmt; + break; + + case OPTION_ARG_FUNC: + if (opt->opt.argfunc(argv[i]) != 0) + return (1); + break; + + case OPTION_ARG_INT: + val = strtonum(argv[i], 0, INT_MAX, &errstr); + if (errstr != NULL) { + fprintf(stderr, "%s %s argument for -%s\n", + errstr, opt->argname, opt->name); + return (1); + } + *opt->opt.value = (int)val; + break; + + case OPTION_ARG_LONG: + val = strtonum(argv[i], 0, LONG_MAX, &errstr); + if (errstr != NULL) { + fprintf(stderr, "%s %s argument for -%s\n", + errstr, opt->argname, opt->name); + return (1); + } + *opt->opt.lvalue = (long)val; + break; + + case OPTION_DISCARD: + break; + + case OPTION_FUNC: + if (opt->opt.func() != 0) + return (1); + break; + + case OPTION_FLAG: + *opt->opt.flag = 1; + break; + + case OPTION_FLAG_ORD: + *opt->opt.flag = ++ord; + break; + + case OPTION_VALUE: + *opt->opt.value = opt->value; + break; + + case OPTION_VALUE_AND: + *opt->opt.value &= opt->value; + break; + + case OPTION_VALUE_OR: + *opt->opt.value |= opt->value; + break; + + default: + fprintf(stderr, "option %s - unknown type %i\n", + opt->name, opt->type); + return (1); + } + } + +done: + if (argsused != NULL) + *argsused = i; + + return (0); + +toomany: + fprintf(stderr, "too many arguments\n"); + return (1); + +unknown: + fprintf(stderr, "unknown option '%s'\n", arg); + return (1); +} diff --git a/crypto/libressl/apps/openssl/apps.h b/crypto/libressl/apps/openssl/apps.h new file mode 100644 index 0000000000..889abfd0a0 --- /dev/null +++ b/crypto/libressl/apps/openssl/apps.h @@ -0,0 +1,321 @@ +/* $OpenBSD: apps.h,v 1.16 2015/09/13 12:41:01 bcook Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_APPS_H +#define HEADER_APPS_H + +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_NO_OCSP +#include +#endif + +#include +extern int single_execution; + +extern CONF *config; +extern char *default_config_file; +extern BIO *bio_err; + +typedef struct args_st { + char **data; + int count; +} ARGS; + +#define PW_MIN_LENGTH 4 +typedef struct pw_cb_data { + const void *password; + const char *prompt_info; +} PW_CB_DATA; + +int password_callback(char *buf, int bufsiz, int verify, void *cb_data); + +int setup_ui(void); +void destroy_ui(void); + +extern UI_METHOD *ui_method; +int ui_open(UI *ui); +int ui_read(UI *ui, UI_STRING *uis); +int ui_write(UI *ui, UI_STRING *uis); +int ui_close(UI *ui); + +int should_retry(int i); +int args_from_file(char *file, int *argc, char **argv[]); +int str2fmt(char *s); +void program_name(char *in, char *out, int size); +int chopup_args(ARGS *arg, char *buf, int *argc, char **argv[]); +#ifdef HEADER_X509_H +int dump_cert_text(BIO *out, X509 *x); +void print_name(BIO *out, const char *title, X509_NAME *nm, + unsigned long lflags); +#endif +int set_cert_ex(unsigned long *flags, const char *arg); +int set_name_ex(unsigned long *flags, const char *arg); +int set_ext_copy(int *copy_type, const char *arg); +int copy_extensions(X509 *x, X509_REQ *req, int copy_type); +int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2); +int add_oid_section(BIO *err, CONF *conf); +X509 *load_cert(BIO *err, const char *file, int format, + const char *pass, const char *cert_descrip); +EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin, + const char *pass, const char *key_descrip); +EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, + const char *pass, const char *key_descrip); +STACK_OF(X509) *load_certs(BIO *err, const char *file, int format, + const char *pass, const char *cert_descrip); +STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format, + const char *pass, const char *cert_descrip); +X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath); + +#ifndef OPENSSL_NO_OCSP +OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req, + char *host, char *path, char *port, int use_ssl, + STACK_OF(CONF_VALUE) *headers, int req_timeout); +#endif + +int load_config(BIO *err, CONF *cnf); +char *make_config_name(void); + +/* Functions defined in ca.c and also used in ocsp.c */ +int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, + ASN1_GENERALIZEDTIME **pinvtm, const char *str); + +#define DB_type 0 +#define DB_exp_date 1 +#define DB_rev_date 2 +#define DB_serial 3 /* index - unique */ +#define DB_file 4 +#define DB_name 5 /* index - unique when active and not disabled */ +#define DB_NUMBER 6 + +#define DB_TYPE_REV 'R' +#define DB_TYPE_EXP 'E' +#define DB_TYPE_VAL 'V' + +typedef struct db_attr_st { + int unique_subject; +} DB_ATTR; +typedef struct ca_db_st { + DB_ATTR attributes; + TXT_DB *db; +} CA_DB; + +BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai); +int save_serial(char *serialfile, char *suffix, BIGNUM *serial, + ASN1_INTEGER **retai); +int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix); +int rand_serial(BIGNUM *b, ASN1_INTEGER *ai); +CA_DB *load_index(char *dbfile, DB_ATTR *dbattr); +int index_index(CA_DB *db); +int save_index(const char *dbfile, const char *suffix, CA_DB *db); +int rotate_index(const char *dbfile, const char *new_suffix, + const char *old_suffix); +void free_index(CA_DB *db); +#define index_name_cmp_noconst(a, b) \ + index_name_cmp((const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, a), \ + (const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, b)) +int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b); +int parse_yesno(const char *str, int def); + +X509_NAME *parse_name(char *str, long chtype, int multirdn); +int args_verify(char ***pargs, int *pargc, int *badarg, BIO *err, + X509_VERIFY_PARAM **pm); +void policies_print(BIO *out, X509_STORE_CTX *ctx); +int bio_to_mem(unsigned char **out, int maxlen, BIO *in); +int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value); +int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx, const char *algname, + int do_param); +int do_X509_sign(BIO *err, X509 *x, EVP_PKEY *pkey, const EVP_MD *md, + STACK_OF(OPENSSL_STRING) *sigopts); +int do_X509_REQ_sign(BIO *err, X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md, + STACK_OF(OPENSSL_STRING) *sigopts); +int do_X509_CRL_sign(BIO *err, X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md, + STACK_OF(OPENSSL_STRING) *sigopts); + +unsigned char *next_protos_parse(unsigned short *outlen, const char *in); + +#define FORMAT_UNDEF 0 +#define FORMAT_ASN1 1 +#define FORMAT_TEXT 2 +#define FORMAT_PEM 3 +#define FORMAT_NETSCAPE 4 +#define FORMAT_PKCS12 5 +#define FORMAT_SMIME 6 + +#define FORMAT_IISSGC 8 /* XXX this stupid macro helps us to avoid + * adding yet another param to load_*key() */ +#define FORMAT_PEMRSA 9 /* PEM RSAPubicKey format */ +#define FORMAT_ASN1RSA 10 /* DER RSAPubicKey format */ +#define FORMAT_MSBLOB 11 /* MS Key blob format */ +#define FORMAT_PVK 12 /* MS PVK file format */ + +#define EXT_COPY_NONE 0 +#define EXT_COPY_ADD 1 +#define EXT_COPY_ALL 2 + +#define NETSCAPE_CERT_HDR "certificate" + +#define APP_PASS_LEN 1024 + +#define SERIAL_RAND_BITS 64 + +int app_isdir(const char *); + +#define TM_START 0 +#define TM_STOP 1 +double app_tminterval (int stop, int usertime); + +#define OPENSSL_NO_SSL_INTERN + +struct option { + const char *name; + const char *argname; + const char *desc; + enum { + OPTION_ARG, + OPTION_ARGV_FUNC, + OPTION_ARG_FORMAT, + OPTION_ARG_FUNC, + OPTION_ARG_INT, + OPTION_ARG_LONG, + OPTION_DISCARD, + OPTION_FUNC, + OPTION_FLAG, + OPTION_FLAG_ORD, + OPTION_VALUE, + OPTION_VALUE_AND, + OPTION_VALUE_OR, + } type; + union { + char **arg; + int (*argfunc)(char *arg); + int (*argvfunc)(int argc, char **argv, int *argsused); + int *flag; + int (*func)(void); + long *lvalue; + int *value; + } opt; + const int value; +}; + +void options_usage(struct option *opts); +int options_parse(int argc, char **argv, struct option *opts, char **unnamed, + int *argsused); + +#endif diff --git a/crypto/libressl/apps/openssl/apps_posix.c b/crypto/libressl/apps/openssl/apps_posix.c new file mode 100644 index 0000000000..67cd465088 --- /dev/null +++ b/crypto/libressl/apps/openssl/apps_posix.c @@ -0,0 +1,164 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * Functions that need to be overridden by non-POSIX operating systems. + */ + +#include + +#include + +#include "apps.h" + +double +app_tminterval(int stop, int usertime) +{ + double ret = 0; + struct tms rus; + clock_t now = times(&rus); + static clock_t tmstart; + + if (usertime) + now = rus.tms_utime; + + if (stop == TM_START) + tmstart = now; + else { + long int tck = sysconf(_SC_CLK_TCK); + ret = (now - tmstart) / (double) tck; + } + + return (ret); +} + +int +setup_ui(void) +{ + ui_method = UI_create_method("OpenSSL application user interface"); + UI_method_set_opener(ui_method, ui_open); + UI_method_set_reader(ui_method, ui_read); + UI_method_set_writer(ui_method, ui_write); + UI_method_set_closer(ui_method, ui_close); + return 0; +} + +void +destroy_ui(void) +{ + if (ui_method) { + UI_destroy_method(ui_method); + ui_method = NULL; + } +} diff --git a/crypto/libressl/apps/openssl/apps_win.c b/crypto/libressl/apps/openssl/apps_win.c new file mode 100644 index 0000000000..37bfcc99af --- /dev/null +++ b/crypto/libressl/apps/openssl/apps_win.c @@ -0,0 +1,60 @@ +/* + * Public domain + * + * Dongsheng Song + * Brent Cook + */ + +#include + +#include +#include + +#include "apps.h" + +double +app_tminterval(int stop, int usertime) +{ + static unsigned __int64 tmstart; + union { + unsigned __int64 u64; + FILETIME ft; + } ct, et, kt, ut; + + GetProcessTimes(GetCurrentProcess(), &ct.ft, &et.ft, &kt.ft, &ut.ft); + + if (stop == TM_START) { + tmstart = ut.u64 + kt.u64; + } else { + return (ut.u64 + kt.u64 - tmstart) / (double) 10000000; + } + return 0; +} + +int +setup_ui(void) +{ + ui_method = UI_create_method("OpenSSL application user interface"); + UI_method_set_opener(ui_method, ui_open); + UI_method_set_reader(ui_method, ui_read); + UI_method_set_writer(ui_method, ui_write); + UI_method_set_closer(ui_method, ui_close); + + /* + * Set STDIO to binary + */ + _setmode(_fileno(stdin), _O_BINARY); + _setmode(_fileno(stdout), _O_BINARY); + _setmode(_fileno(stderr), _O_BINARY); + + return 0; +} + +void +destroy_ui(void) +{ + if (ui_method) { + UI_destroy_method(ui_method); + ui_method = NULL; + } +} diff --git a/crypto/libressl/apps/openssl/asn1pars.c b/crypto/libressl/apps/openssl/asn1pars.c new file mode 100644 index 0000000000..713e5ff49f --- /dev/null +++ b/crypto/libressl/apps/openssl/asn1pars.c @@ -0,0 +1,482 @@ +/* $OpenBSD: asn1pars.c,v 1.5 2015/10/10 22:28:51 doug Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* A nice addition from Dr Stephen Henson to + * add the -strparse option which parses nested binary structures + */ + +#include +#include +#include +#include + +#include "apps.h" +#include "progs.h" + +#include +#include +#include +#include + +static struct { + char *derfile; + int dump; + char *genconf; + char *genstr; + int indent; + char *infile; + int informat; + unsigned int length; + int noout; + int offset; + char *oidfile; + STACK_OF(OPENSSL_STRING) *osk; +} asn1pars_config; + +static int +asn1pars_opt_dlimit(char *arg) +{ + const char *errstr; + + asn1pars_config.dump = strtonum(arg, 1, INT_MAX, &errstr); + if (errstr) { + fprintf(stderr, "-dlimit must be from 1 to INT_MAX: %s\n", + errstr); + return (-1); + } + return (0); +} + +static int +asn1pars_opt_length(char *arg) +{ + const char *errstr; + + asn1pars_config.length = strtonum(arg, 1, UINT_MAX, &errstr); + if (errstr) { + fprintf(stderr, "-length must be from 1 to UINT_MAX: %s\n", + errstr); + return (-1); + } + return (0); +} + +static int +asn1pars_opt_strparse(char *arg) +{ + if (sk_OPENSSL_STRING_push(asn1pars_config.osk, arg) == 0) { + fprintf(stderr, "-strparse cannot add argument\n"); + return (-1); + } + return (0); +} + +static struct option asn1pars_options[] = { + { + .name = "dump", + .desc = "Dump unknown data in hex form", + .type = OPTION_VALUE, + .value = -1, + .opt.value = &asn1pars_config.dump, + }, + { + .name = "dlimit", + .argname = "num", + .desc = "Dump the first num bytes of unknown data in hex form", + .type = OPTION_ARG_FUNC, + .opt.argfunc = asn1pars_opt_dlimit, + }, + { + .name = "genconf", + .argname = "file", + .desc = "File to generate ASN.1 structure from", + .type = OPTION_ARG, + .opt.arg = &asn1pars_config.genconf, + }, + { + .name = "genstr", + .argname = "string", + .desc = "String to generate ASN.1 structure from", + .type = OPTION_ARG, + .opt.arg = &asn1pars_config.genstr, + }, + { + .name = "i", + .desc = "Indent output according to depth of structures", + .type = OPTION_FLAG, + .opt.flag = &asn1pars_config.indent, + }, + { + .name = "in", + .argname = "file", + .desc = "The input file (default stdin)", + .type = OPTION_ARG, + .opt.arg = &asn1pars_config.infile, + }, + { + .name = "inform", + .argname = "fmt", + .desc = "Input format (DER, TXT or PEM (default))", + .type = OPTION_ARG_FORMAT, + .opt.value = &asn1pars_config.informat, + }, + { + .name = "length", + .argname = "num", + .desc = "Number of bytes to parse (default until EOF)", + .type = OPTION_ARG_FUNC, + .opt.argfunc = asn1pars_opt_length, + }, + { + .name = "noout", + .desc = "Do not produce any output", + .type = OPTION_FLAG, + .opt.flag = &asn1pars_config.noout, + }, + { + .name = "offset", + .argname = "num", + .desc = "Offset to begin parsing", + .type = OPTION_ARG_INT, + .opt.value = &asn1pars_config.offset, + }, + { + .name = "oid", + .argname = "file", + .desc = "File containing additional object identifiers (OIDs)", + .type = OPTION_ARG, + .opt.arg = &asn1pars_config.oidfile, + }, + { + .name = "out", + .argname = "file", + .desc = "Output file in DER format", + .type = OPTION_ARG, + .opt.arg = &asn1pars_config.derfile, + }, + { + .name = "strparse", + .argname = "offset", + .desc = "Parse the content octets of ASN.1 object starting at" + " offset", + .type = OPTION_ARG_FUNC, + .opt.argfunc = asn1pars_opt_strparse, + }, + { NULL }, +}; + +static void +asn1pars_usage() +{ + fprintf(stderr, + "usage: asn1parse [-i] [-dlimit num] [-dump] [-genconf file] " + "[-genstr string]\n" + " [-in file] [-inform fmt] [-length num] [-noout] [-offset num] " + "[-oid file]\n" + " [-out file] [-strparse offset]\n\n"); + options_usage(asn1pars_options); +} + +static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf); + +int +asn1parse_main(int argc, char **argv) +{ + int i, j, ret = 1; + long num, tmplen; + BIO *in = NULL, *out = NULL, *b64 = NULL, *derout = NULL; + char *str = NULL; + const char *errstr = NULL; + unsigned char *tmpbuf; + const unsigned char *ctmpbuf; + BUF_MEM *buf = NULL; + ASN1_TYPE *at = NULL; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + memset(&asn1pars_config, 0, sizeof(asn1pars_config)); + + asn1pars_config.informat = FORMAT_PEM; + if ((asn1pars_config.osk = sk_OPENSSL_STRING_new_null()) == NULL) { + BIO_printf(bio_err, "Memory allocation failure\n"); + goto end; + } + + if (options_parse(argc, argv, asn1pars_options, NULL, NULL) != 0) { + asn1pars_usage(); + return (1); + } + + in = BIO_new(BIO_s_file()); + out = BIO_new(BIO_s_file()); + if ((in == NULL) || (out == NULL)) { + ERR_print_errors(bio_err); + goto end; + } + BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT); + + if (asn1pars_config.oidfile != NULL) { + if (BIO_read_filename(in, asn1pars_config.oidfile) <= 0) { + BIO_printf(bio_err, "problems opening %s\n", + asn1pars_config.oidfile); + ERR_print_errors(bio_err); + goto end; + } + OBJ_create_objects(in); + } + if (asn1pars_config.infile == NULL) + BIO_set_fp(in, stdin, BIO_NOCLOSE); + else { + if (BIO_read_filename(in, asn1pars_config.infile) <= 0) { + perror(asn1pars_config.infile); + goto end; + } + } + + if (asn1pars_config.derfile) { + if (!(derout = BIO_new_file(asn1pars_config.derfile, "wb"))) { + BIO_printf(bio_err, "problems opening %s\n", + asn1pars_config.derfile); + ERR_print_errors(bio_err); + goto end; + } + } + if ((buf = BUF_MEM_new()) == NULL) + goto end; + if (!BUF_MEM_grow(buf, BUFSIZ * 8)) + goto end; /* Pre-allocate :-) */ + + if (asn1pars_config.genstr || asn1pars_config.genconf) { + num = do_generate(bio_err, asn1pars_config.genstr, + asn1pars_config.genconf, buf); + if (num < 0) { + ERR_print_errors(bio_err); + goto end; + } + } else { + + if (asn1pars_config.informat == FORMAT_PEM) { + BIO *tmp; + + if ((b64 = BIO_new(BIO_f_base64())) == NULL) + goto end; + BIO_push(b64, in); + tmp = in; + in = b64; + b64 = tmp; + } + num = 0; + for (;;) { + if (!BUF_MEM_grow(buf, (int) num + BUFSIZ)) + goto end; + i = BIO_read(in, &(buf->data[num]), BUFSIZ); + if (i <= 0) + break; + num += i; + } + } + str = buf->data; + + /* If any structs to parse go through in sequence */ + + if (sk_OPENSSL_STRING_num(asn1pars_config.osk)) { + tmpbuf = (unsigned char *) str; + tmplen = num; + for (i = 0; i < sk_OPENSSL_STRING_num(asn1pars_config.osk); + i++) { + ASN1_TYPE *atmp; + int typ; + j = strtonum( + sk_OPENSSL_STRING_value(asn1pars_config.osk, i), + 1, INT_MAX, &errstr); + if (errstr) { + BIO_printf(bio_err, + "'%s' is an invalid number: %s\n", + sk_OPENSSL_STRING_value(asn1pars_config.osk, + i), errstr); + continue; + } + tmpbuf += j; + tmplen -= j; + atmp = at; + ctmpbuf = tmpbuf; + at = d2i_ASN1_TYPE(NULL, &ctmpbuf, tmplen); + ASN1_TYPE_free(atmp); + if (!at) { + BIO_printf(bio_err, "Error parsing structure\n"); + ERR_print_errors(bio_err); + goto end; + } + typ = ASN1_TYPE_get(at); + if ((typ == V_ASN1_OBJECT) || + (typ == V_ASN1_NULL)) { + BIO_printf(bio_err, "Can't parse %s type\n", + typ == V_ASN1_NULL ? "NULL" : "OBJECT"); + ERR_print_errors(bio_err); + goto end; + } + /* hmm... this is a little evil but it works */ + tmpbuf = at->value.asn1_string->data; + tmplen = at->value.asn1_string->length; + } + str = (char *) tmpbuf; + num = tmplen; + } + if (asn1pars_config.offset >= num) { + BIO_printf(bio_err, "Error: offset too large\n"); + goto end; + } + num -= asn1pars_config.offset; + + if ((asn1pars_config.length == 0) || + ((long)asn1pars_config.length > num)) + asn1pars_config.length = (unsigned int) num; + if (derout) { + if (BIO_write(derout, str + asn1pars_config.offset, + asn1pars_config.length) != (int)asn1pars_config.length) { + BIO_printf(bio_err, "Error writing output\n"); + ERR_print_errors(bio_err); + goto end; + } + } + if (!asn1pars_config.noout && + !ASN1_parse_dump(out, + (unsigned char *)&(str[asn1pars_config.offset]), + asn1pars_config.length, asn1pars_config.indent, + asn1pars_config.dump)) { + ERR_print_errors(bio_err); + goto end; + } + ret = 0; +end: + BIO_free(derout); + BIO_free(in); + BIO_free_all(out); + BIO_free(b64); + if (ret != 0) + ERR_print_errors(bio_err); + BUF_MEM_free(buf); + if (at != NULL) + ASN1_TYPE_free(at); + sk_OPENSSL_STRING_free(asn1pars_config.osk); + OBJ_cleanup(); + + return (ret); +} + +static int +do_generate(BIO * bio, char *genstr, char *genconf, BUF_MEM * buf) +{ + CONF *cnf = NULL; + int len; + long errline; + unsigned char *p; + ASN1_TYPE *atyp = NULL; + + if (genconf) { + cnf = NCONF_new(NULL); + if (!NCONF_load(cnf, genconf, &errline)) + goto conferr; + if (!genstr) + genstr = NCONF_get_string(cnf, "default", "asn1"); + if (!genstr) { + BIO_printf(bio, "Can't find 'asn1' in '%s'\n", genconf); + goto err; + } + } + atyp = ASN1_generate_nconf(genstr, cnf); + NCONF_free(cnf); + cnf = NULL; + + if (!atyp) + return -1; + + len = i2d_ASN1_TYPE(atyp, NULL); + if (len <= 0) + goto err; + + if (!BUF_MEM_grow(buf, len)) + goto err; + + p = (unsigned char *) buf->data; + + i2d_ASN1_TYPE(atyp, &p); + + ASN1_TYPE_free(atyp); + return len; + +conferr: + + if (errline > 0) + BIO_printf(bio, "Error on line %ld of config file '%s'\n", + errline, genconf); + else + BIO_printf(bio, "Error loading config file '%s'\n", genconf); + +err: + NCONF_free(cnf); + ASN1_TYPE_free(atyp); + + return -1; + +} diff --git a/crypto/libressl/apps/openssl/ca.c b/crypto/libressl/apps/openssl/ca.c new file mode 100644 index 0000000000..1499ae1696 --- /dev/null +++ b/crypto/libressl/apps/openssl/ca.c @@ -0,0 +1,2716 @@ +/* $OpenBSD: ca.c,v 1.19 2015/10/17 15:00:11 doug Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* The PPKI stuff has been donated by Jeff Barber */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "apps.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BASE_SECTION "ca" + +#define ENV_DEFAULT_CA "default_ca" + +#define STRING_MASK "string_mask" +#define UTF8_IN "utf8" + +#define ENV_NEW_CERTS_DIR "new_certs_dir" +#define ENV_CERTIFICATE "certificate" +#define ENV_SERIAL "serial" +#define ENV_CRLNUMBER "crlnumber" +#define ENV_PRIVATE_KEY "private_key" +#define ENV_DEFAULT_DAYS "default_days" +#define ENV_DEFAULT_STARTDATE "default_startdate" +#define ENV_DEFAULT_ENDDATE "default_enddate" +#define ENV_DEFAULT_CRL_DAYS "default_crl_days" +#define ENV_DEFAULT_CRL_HOURS "default_crl_hours" +#define ENV_DEFAULT_MD "default_md" +#define ENV_DEFAULT_EMAIL_DN "email_in_dn" +#define ENV_PRESERVE "preserve" +#define ENV_POLICY "policy" +#define ENV_EXTENSIONS "x509_extensions" +#define ENV_CRLEXT "crl_extensions" +#define ENV_MSIE_HACK "msie_hack" +#define ENV_NAMEOPT "name_opt" +#define ENV_CERTOPT "cert_opt" +#define ENV_EXTCOPY "copy_extensions" +#define ENV_UNIQUE_SUBJECT "unique_subject" + +#define ENV_DATABASE "database" + +/* Additional revocation information types */ + +#define REV_NONE 0 /* No addditional information */ +#define REV_CRL_REASON 1 /* Value is CRL reason code */ +#define REV_HOLD 2 /* Value is hold instruction */ +#define REV_KEY_COMPROMISE 3 /* Value is cert key compromise time */ +#define REV_CA_COMPROMISE 4 /* Value is CA key compromise time */ + +static const char *ca_usage[] = { + "usage: ca args\n", + "\n", + " -verbose - Talk a lot while doing things\n", + " -config file - A config file\n", + " -name arg - The particular CA definition to use\n", + " -gencrl - Generate a new CRL\n", + " -crldays days - Days is when the next CRL is due\n", + " -crlhours hours - Hours is when the next CRL is due\n", + " -startdate YYMMDDHHMMSSZ - certificate validity notBefore\n", + " -enddate YYMMDDHHMMSSZ - certificate validity notAfter (overrides -days)\n", + " -days arg - number of days to certify the certificate for\n", + " -md arg - md to use, one of md5 or sha1\n", + " -policy arg - The CA 'policy' to support\n", + " -keyfile arg - private key file\n", + " -keyform arg - private key file format (PEM)\n", + " -key arg - key to decode the private key if it is encrypted\n", + " -cert file - The CA certificate\n", + " -selfsign - sign a certificate with the key associated with it\n", + " -in file - The input PEM encoded certificate request(s)\n", + " -out file - Where to put the output file(s)\n", + " -outdir dir - Where to put output certificates\n", + " -infiles .... - The last argument, requests to process\n", + " -spkac file - File contains DN and signed public key and challenge\n", + " -ss_cert file - File contains a self signed cert to sign\n", + " -preserveDN - Don't re-order the DN\n", + " -noemailDN - Don't add the EMAIL field into certificate' subject\n", + " -batch - Don't ask questions\n", + " -msie_hack - msie modifications to handle all those universal strings\n", + " -revoke file - Revoke a certificate (given in file)\n", + " -subj arg - Use arg instead of request's subject\n", + " -utf8 - input characters are UTF8 (default ASCII)\n", + " -multivalue-rdn - enable support for multivalued RDNs\n", + " -extensions .. - Extension section (override value in config file)\n", + " -extfile file - Configuration file with X509v3 extentions to add\n", + " -crlexts .. - CRL extension section (override value in config file)\n", + " -status serial - Shows certificate status given the serial number\n", + " -updatedb - Updates db for expired certificates\n", + NULL +}; + +static void lookup_fail(const char *name, const char *tag); +static int certify(X509 ** xret, char *infile, EVP_PKEY * pkey, X509 * x509, + const EVP_MD * dgst, STACK_OF(OPENSSL_STRING) * sigopts, + STACK_OF(CONF_VALUE) * policy, CA_DB * db, BIGNUM * serial, char *subj, + unsigned long chtype, int multirdn, int email_dn, char *startdate, + char *enddate, long days, int batch, char *ext_sect, CONF * conf, + int verbose, unsigned long certopt, unsigned long nameopt, + int default_op, int ext_copy, int selfsign); +static int certify_cert(X509 ** xret, char *infile, EVP_PKEY * pkey, + X509 * x509, const EVP_MD * dgst, STACK_OF(OPENSSL_STRING) * sigopts, + STACK_OF(CONF_VALUE) * policy, CA_DB * db, BIGNUM * serial, char *subj, + unsigned long chtype, int multirdn, int email_dn, char *startdate, + char *enddate, long days, int batch, char *ext_sect, CONF * conf, + int verbose, unsigned long certopt, unsigned long nameopt, int default_op, + int ext_copy); +static int certify_spkac(X509 ** xret, char *infile, EVP_PKEY * pkey, + X509 * x509, const EVP_MD * dgst, STACK_OF(OPENSSL_STRING) * sigopts, + STACK_OF(CONF_VALUE) * policy, CA_DB * db, BIGNUM * serial, char *subj, + unsigned long chtype, int multirdn, int email_dn, char *startdate, + char *enddate, long days, char *ext_sect, CONF * conf, int verbose, + unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy); +static void write_new_certificate(BIO * bp, X509 * x, int output_der, + int notext); +static int do_body(X509 ** xret, EVP_PKEY * pkey, X509 * x509, + const EVP_MD * dgst, STACK_OF(OPENSSL_STRING) * sigopts, + STACK_OF(CONF_VALUE) * policy, CA_DB * db, BIGNUM * serial, char *subj, + unsigned long chtype, int multirdn, int email_dn, char *startdate, + char *enddate, long days, int batch, int verbose, X509_REQ * req, + char *ext_sect, CONF * conf, unsigned long certopt, unsigned long nameopt, + int default_op, int ext_copy, int selfsign); +static int do_revoke(X509 * x509, CA_DB * db, int ext, char *extval); +static int get_certificate_status(const char *ser_status, CA_DB * db); +static int do_updatedb(CA_DB * db); +static int check_time_format(const char *str); +static char * bin2hex(unsigned char *, size_t); +char *make_revocation_str(int rev_type, char *rev_arg); +int make_revoked(X509_REVOKED * rev, const char *str); +int old_entry_print(BIO * bp, ASN1_OBJECT * obj, ASN1_STRING * str); +static CONF *conf = NULL; +static CONF *extconf = NULL; +static char *section = NULL; + +static int preserve = 0; +static int msie_hack = 0; + + +int +ca_main(int argc, char **argv) +{ + char *key = NULL, *passargin = NULL; + int create_ser = 0; + int free_key = 0; + int total = 0; + int total_done = 0; + int badops = 0; + int ret = 1; + int email_dn = 1; + int req = 0; + int verbose = 0; + int gencrl = 0; + int dorevoke = 0; + int doupdatedb = 0; + long crldays = 0; + long crlhours = 0; + long crlsec = 0; + long errorline = -1; + char *configfile = NULL; + char *md = NULL; + char *policy = NULL; + char *keyfile = NULL; + char *certfile = NULL; + int keyform = FORMAT_PEM; + char *infile = NULL; + char *spkac_file = NULL; + char *ss_cert_file = NULL; + char *ser_status = NULL; + EVP_PKEY *pkey = NULL; + int output_der = 0; + char *outfile = NULL; + char *outdir = NULL; + char *serialfile = NULL; + char *crlnumberfile = NULL; + char *extensions = NULL; + char *extfile = NULL; + char *subj = NULL; + unsigned long chtype = MBSTRING_ASC; + int multirdn = 0; + char *tmp_email_dn = NULL; + char *crl_ext = NULL; + int rev_type = REV_NONE; + char *rev_arg = NULL; + BIGNUM *serial = NULL; + BIGNUM *crlnumber = NULL; + char *startdate = NULL; + char *enddate = NULL; + long days = 0; + int batch = 0; + int notext = 0; + unsigned long nameopt = 0, certopt = 0; + int default_op = 1; + int ext_copy = EXT_COPY_NONE; + int selfsign = 0; + X509 *x509 = NULL, *x509p = NULL; + X509 *x = NULL; + BIO *in = NULL, *out = NULL, *Sout = NULL, *Cout = NULL; + char *dbfile = NULL; + CA_DB *db = NULL; + X509_CRL *crl = NULL; + X509_REVOKED *r = NULL; + ASN1_TIME *tmptm; + ASN1_INTEGER *tmpser; + char *f; + const char *p; + char *const * pp; + int i, j; + const EVP_MD *dgst = NULL; + STACK_OF(CONF_VALUE) * attribs = NULL; + STACK_OF(X509) * cert_sk = NULL; + STACK_OF(OPENSSL_STRING) * sigopts = NULL; +#define BUFLEN 256 + char buf[3][BUFLEN]; + char *tofree = NULL; + const char *errstr = NULL; + DB_ATTR db_attr; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + conf = NULL; + key = NULL; + section = NULL; + + preserve = 0; + msie_hack = 0; + + argc--; + argv++; + while (argc >= 1) { + if (strcmp(*argv, "-verbose") == 0) + verbose = 1; + else if (strcmp(*argv, "-config") == 0) { + if (--argc < 1) + goto bad; + configfile = *(++argv); + } else if (strcmp(*argv, "-name") == 0) { + if (--argc < 1) + goto bad; + section = *(++argv); + } else if (strcmp(*argv, "-subj") == 0) { + if (--argc < 1) + goto bad; + subj = *(++argv); + /* preserve=1; */ + } else if (strcmp(*argv, "-utf8") == 0) + chtype = MBSTRING_UTF8; + else if (strcmp(*argv, "-create_serial") == 0) + create_ser = 1; + else if (strcmp(*argv, "-multivalue-rdn") == 0) + multirdn = 1; + else if (strcmp(*argv, "-startdate") == 0) { + if (--argc < 1) + goto bad; + startdate = *(++argv); + } else if (strcmp(*argv, "-enddate") == 0) { + if (--argc < 1) + goto bad; + enddate = *(++argv); + } else if (strcmp(*argv, "-days") == 0) { + if (--argc < 1) + goto bad; + days = strtonum(*(++argv), 0, LONG_MAX, &errstr); + if (errstr) + goto bad; + } else if (strcmp(*argv, "-md") == 0) { + if (--argc < 1) + goto bad; + md = *(++argv); + } else if (strcmp(*argv, "-policy") == 0) { + if (--argc < 1) + goto bad; + policy = *(++argv); + } else if (strcmp(*argv, "-keyfile") == 0) { + if (--argc < 1) + goto bad; + keyfile = *(++argv); + } else if (strcmp(*argv, "-keyform") == 0) { + if (--argc < 1) + goto bad; + keyform = str2fmt(*(++argv)); + } else if (strcmp(*argv, "-passin") == 0) { + if (--argc < 1) + goto bad; + passargin = *(++argv); + } else if (strcmp(*argv, "-key") == 0) { + if (--argc < 1) + goto bad; + key = *(++argv); + } else if (strcmp(*argv, "-cert") == 0) { + if (--argc < 1) + goto bad; + certfile = *(++argv); + } else if (strcmp(*argv, "-selfsign") == 0) + selfsign = 1; + else if (strcmp(*argv, "-in") == 0) { + if (--argc < 1) + goto bad; + infile = *(++argv); + req = 1; + } else if (strcmp(*argv, "-out") == 0) { + if (--argc < 1) + goto bad; + outfile = *(++argv); + } else if (strcmp(*argv, "-outdir") == 0) { + if (--argc < 1) + goto bad; + outdir = *(++argv); + } else if (strcmp(*argv, "-sigopt") == 0) { + if (--argc < 1) + goto bad; + if (!sigopts) + sigopts = sk_OPENSSL_STRING_new_null(); + if (!sigopts || + !sk_OPENSSL_STRING_push(sigopts, *(++argv))) + goto bad; + } else if (strcmp(*argv, "-notext") == 0) + notext = 1; + else if (strcmp(*argv, "-batch") == 0) + batch = 1; + else if (strcmp(*argv, "-preserveDN") == 0) + preserve = 1; + else if (strcmp(*argv, "-noemailDN") == 0) + email_dn = 0; + else if (strcmp(*argv, "-gencrl") == 0) + gencrl = 1; + else if (strcmp(*argv, "-msie_hack") == 0) + msie_hack = 1; + else if (strcmp(*argv, "-crldays") == 0) { + if (--argc < 1) + goto bad; + crldays = strtonum(*(++argv), 0, LONG_MAX, &errstr); + if (errstr) + goto bad; + } else if (strcmp(*argv, "-crlhours") == 0) { + if (--argc < 1) + goto bad; + crlhours = strtonum(*(++argv), 0, LONG_MAX, &errstr); + if (errstr) + goto bad; + } else if (strcmp(*argv, "-crlsec") == 0) { + if (--argc < 1) + goto bad; + crlsec = strtonum(*(++argv), 0, LONG_MAX, &errstr); + if (errstr) + goto bad; + } else if (strcmp(*argv, "-infiles") == 0) { + argc--; + argv++; + req = 1; + break; + } else if (strcmp(*argv, "-ss_cert") == 0) { + if (--argc < 1) + goto bad; + ss_cert_file = *(++argv); + req = 1; + } else if (strcmp(*argv, "-spkac") == 0) { + if (--argc < 1) + goto bad; + spkac_file = *(++argv); + req = 1; + } else if (strcmp(*argv, "-revoke") == 0) { + if (--argc < 1) + goto bad; + infile = *(++argv); + dorevoke = 1; + } else if (strcmp(*argv, "-extensions") == 0) { + if (--argc < 1) + goto bad; + extensions = *(++argv); + } else if (strcmp(*argv, "-extfile") == 0) { + if (--argc < 1) + goto bad; + extfile = *(++argv); + } else if (strcmp(*argv, "-status") == 0) { + if (--argc < 1) + goto bad; + ser_status = *(++argv); + } else if (strcmp(*argv, "-updatedb") == 0) { + doupdatedb = 1; + } else if (strcmp(*argv, "-crlexts") == 0) { + if (--argc < 1) + goto bad; + crl_ext = *(++argv); + } else if (strcmp(*argv, "-crl_reason") == 0) { + if (--argc < 1) + goto bad; + rev_arg = *(++argv); + rev_type = REV_CRL_REASON; + } else if (strcmp(*argv, "-crl_hold") == 0) { + if (--argc < 1) + goto bad; + rev_arg = *(++argv); + rev_type = REV_HOLD; + } else if (strcmp(*argv, "-crl_compromise") == 0) { + if (--argc < 1) + goto bad; + rev_arg = *(++argv); + rev_type = REV_KEY_COMPROMISE; + } else if (strcmp(*argv, "-crl_CA_compromise") == 0) { + if (--argc < 1) + goto bad; + rev_arg = *(++argv); + rev_type = REV_CA_COMPROMISE; + } + else { +bad: + if (errstr) + BIO_printf(bio_err, "invalid argument %s: %s\n", + *argv, errstr); + else + BIO_printf(bio_err, "unknown option %s\n", *argv); + badops = 1; + break; + } + argc--; + argv++; + } + + if (badops) { + const char **pp2; + + for (pp2 = ca_usage; (*pp2 != NULL); pp2++) + BIO_printf(bio_err, "%s", *pp2); + goto err; + } + + /*****************************************************************/ + tofree = NULL; + if (configfile == NULL) + configfile = getenv("OPENSSL_CONF"); + if (configfile == NULL) { + if ((tofree = make_config_name()) == NULL) { + BIO_printf(bio_err, "error making config file name\n"); + goto err; + } + configfile = tofree; + } + BIO_printf(bio_err, "Using configuration from %s\n", configfile); + conf = NCONF_new(NULL); + if (NCONF_load(conf, configfile, &errorline) <= 0) { + if (errorline <= 0) + BIO_printf(bio_err, + "error loading the config file '%s'\n", + configfile); + else + BIO_printf(bio_err, + "error on line %ld of config file '%s'\n", + errorline, configfile); + goto err; + } + free(tofree); + tofree = NULL; + + /* Lets get the config section we are using */ + if (section == NULL) { + section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_CA); + if (section == NULL) { + lookup_fail(BASE_SECTION, ENV_DEFAULT_CA); + goto err; + } + } + if (conf != NULL) { + p = NCONF_get_string(conf, NULL, "oid_file"); + if (p == NULL) + ERR_clear_error(); + if (p != NULL) { + BIO *oid_bio; + + oid_bio = BIO_new_file(p, "r"); + if (oid_bio == NULL) { + /* + BIO_printf(bio_err, + "problems opening %s for extra oid's\n", p); + ERR_print_errors(bio_err); + */ + ERR_clear_error(); + } else { + OBJ_create_objects(oid_bio); + BIO_free(oid_bio); + } + } + if (!add_oid_section(bio_err, conf)) { + ERR_print_errors(bio_err); + goto err; + } + } + f = NCONF_get_string(conf, section, STRING_MASK); + if (!f) + ERR_clear_error(); + + if (f && !ASN1_STRING_set_default_mask_asc(f)) { + BIO_printf(bio_err, + "Invalid global string mask setting %s\n", f); + goto err; + } + if (chtype != MBSTRING_UTF8) { + f = NCONF_get_string(conf, section, UTF8_IN); + if (!f) + ERR_clear_error(); + else if (!strcmp(f, "yes")) + chtype = MBSTRING_UTF8; + } + db_attr.unique_subject = 1; + p = NCONF_get_string(conf, section, ENV_UNIQUE_SUBJECT); + if (p) { + db_attr.unique_subject = parse_yesno(p, 1); + } else + ERR_clear_error(); + + in = BIO_new(BIO_s_file()); + out = BIO_new(BIO_s_file()); + Sout = BIO_new(BIO_s_file()); + Cout = BIO_new(BIO_s_file()); + if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL)) { + ERR_print_errors(bio_err); + goto err; + } + /*****************************************************************/ + /* report status of cert with serial number given on command line */ + if (ser_status) { + if ((dbfile = NCONF_get_string(conf, section, + ENV_DATABASE)) == NULL) { + lookup_fail(section, ENV_DATABASE); + goto err; + } + db = load_index(dbfile, &db_attr); + if (db == NULL) + goto err; + + if (!index_index(db)) + goto err; + + if (get_certificate_status(ser_status, db) != 1) + BIO_printf(bio_err, "Error verifying serial %s!\n", + ser_status); + goto err; + } + /*****************************************************************/ + /* we definitely need a private key, so let's get it */ + + if ((keyfile == NULL) && ((keyfile = NCONF_get_string(conf, + section, ENV_PRIVATE_KEY)) == NULL)) { + lookup_fail(section, ENV_PRIVATE_KEY); + goto err; + } + if (!key) { + free_key = 1; + if (!app_passwd(bio_err, passargin, NULL, &key, NULL)) { + BIO_printf(bio_err, "Error getting password\n"); + goto err; + } + } + pkey = load_key(bio_err, keyfile, keyform, 0, key, "CA private key"); + if (key) + explicit_bzero(key, strlen(key)); + if (pkey == NULL) { + /* load_key() has already printed an appropriate message */ + goto err; + } + /*****************************************************************/ + /* we need a certificate */ + if (!selfsign || spkac_file || ss_cert_file || gencrl) { + if ((certfile == NULL) && + ((certfile = NCONF_get_string(conf, + section, ENV_CERTIFICATE)) == NULL)) { + lookup_fail(section, ENV_CERTIFICATE); + goto err; + } + x509 = load_cert(bio_err, certfile, FORMAT_PEM, NULL, + "CA certificate"); + if (x509 == NULL) + goto err; + + if (!X509_check_private_key(x509, pkey)) { + BIO_printf(bio_err, + "CA certificate and CA private key do not match\n"); + goto err; + } + } + if (!selfsign) + x509p = x509; + + f = NCONF_get_string(conf, BASE_SECTION, ENV_PRESERVE); + if (f == NULL) + ERR_clear_error(); + if ((f != NULL) && ((*f == 'y') || (*f == 'Y'))) + preserve = 1; + f = NCONF_get_string(conf, BASE_SECTION, ENV_MSIE_HACK); + if (f == NULL) + ERR_clear_error(); + if ((f != NULL) && ((*f == 'y') || (*f == 'Y'))) + msie_hack = 1; + + f = NCONF_get_string(conf, section, ENV_NAMEOPT); + + if (f) { + if (!set_name_ex(&nameopt, f)) { + BIO_printf(bio_err, + "Invalid name options: \"%s\"\n", f); + goto err; + } + default_op = 0; + } else + ERR_clear_error(); + + f = NCONF_get_string(conf, section, ENV_CERTOPT); + + if (f) { + if (!set_cert_ex(&certopt, f)) { + BIO_printf(bio_err, + "Invalid certificate options: \"%s\"\n", f); + goto err; + } + default_op = 0; + } else + ERR_clear_error(); + + f = NCONF_get_string(conf, section, ENV_EXTCOPY); + + if (f) { + if (!set_ext_copy(&ext_copy, f)) { + BIO_printf(bio_err, + "Invalid extension copy option: \"%s\"\n", f); + goto err; + } + } else + ERR_clear_error(); + + /*****************************************************************/ + /* lookup where to write new certificates */ + if ((outdir == NULL) && (req)) { + + if ((outdir = NCONF_get_string(conf, section, + ENV_NEW_CERTS_DIR)) == NULL) { + BIO_printf(bio_err, "there needs to be defined a directory for new certificate to be placed in\n"); + goto err; + } + /* + * outdir is a directory spec, but access() for VMS demands a + * filename. In any case, stat(), below, will catch the + * problem if outdir is not a directory spec, and the fopen() + * or open() will catch an error if there is no write access. + * + * Presumably, this problem could also be solved by using the + * DEC C routines to convert the directory syntax to Unixly, + * and give that to access(). However, time's too short to + * do that just now. + */ + if (access(outdir, R_OK | W_OK | X_OK) != 0) { + BIO_printf(bio_err, + "I am unable to access the %s directory\n", outdir); + perror(outdir); + goto err; + } + if (app_isdir(outdir) <= 0) { + BIO_printf(bio_err, + "%s need to be a directory\n", outdir); + perror(outdir); + goto err; + } + } + /*****************************************************************/ + /* we need to load the database file */ + if ((dbfile = NCONF_get_string(conf, section, ENV_DATABASE)) == NULL) { + lookup_fail(section, ENV_DATABASE); + goto err; + } + db = load_index(dbfile, &db_attr); + if (db == NULL) + goto err; + + /* Lets check some fields */ + for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { + pp = sk_OPENSSL_PSTRING_value(db->db->data, i); + if ((pp[DB_type][0] != DB_TYPE_REV) && + (pp[DB_rev_date][0] != '\0')) { + BIO_printf(bio_err, "entry %d: not revoked yet, but has a revocation date\n", i + 1); + goto err; + } + if ((pp[DB_type][0] == DB_TYPE_REV) && + !make_revoked(NULL, pp[DB_rev_date])) { + BIO_printf(bio_err, " in entry %d\n", i + 1); + goto err; + } + if (!check_time_format((char *) pp[DB_exp_date])) { + BIO_printf(bio_err, "entry %d: invalid expiry date\n", + i + 1); + goto err; + } + p = pp[DB_serial]; + j = strlen(p); + if (*p == '-') { + p++; + j--; + } + if ((j & 1) || (j < 2)) { + BIO_printf(bio_err, + "entry %d: bad serial number length (%d)\n", + i + 1, j); + goto err; + } + while (*p) { + if (!(((*p >= '0') && (*p <= '9')) || + ((*p >= 'A') && (*p <= 'F')) || + ((*p >= 'a') && (*p <= 'f')))) { + BIO_printf(bio_err, "entry %d: bad serial number characters, char pos %ld, char is '%c'\n", i + 1, (long) (p - pp[DB_serial]), *p); + goto err; + } + p++; + } + } + if (verbose) { + BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT); /* cannot fail */ + TXT_DB_write(out, db->db); + BIO_printf(bio_err, "%d entries loaded from the database\n", + sk_OPENSSL_PSTRING_num(db->db->data)); + BIO_printf(bio_err, "generating index\n"); + } + if (!index_index(db)) + goto err; + + /*****************************************************************/ + /* Update the db file for expired certificates */ + if (doupdatedb) { + if (verbose) + BIO_printf(bio_err, "Updating %s ...\n", dbfile); + + i = do_updatedb(db); + if (i == -1) { + BIO_printf(bio_err, "Malloc failure\n"); + goto err; + } else if (i == 0) { + if (verbose) + BIO_printf(bio_err, + "No entries found to mark expired\n"); + } else { + if (!save_index(dbfile, "new", db)) + goto err; + + if (!rotate_index(dbfile, "new", "old")) + goto err; + + if (verbose) + BIO_printf(bio_err, + "Done. %d entries marked as expired\n", i); + } + } + /*****************************************************************/ + /* Read extentions config file */ + if (extfile) { + extconf = NCONF_new(NULL); + if (NCONF_load(extconf, extfile, &errorline) <= 0) { + if (errorline <= 0) + BIO_printf(bio_err, + "ERROR: loading the config file '%s'\n", + extfile); + else + BIO_printf(bio_err, + "ERROR: on line %ld of config file '%s'\n", + errorline, extfile); + ret = 1; + goto err; + } + if (verbose) + BIO_printf(bio_err, + "Successfully loaded extensions file %s\n", + extfile); + + /* We can have sections in the ext file */ + if (!extensions && !(extensions = NCONF_get_string(extconf, + "default", "extensions"))) + extensions = "default"; + } + /*****************************************************************/ + if (req || gencrl) { + if (outfile != NULL) { + if (BIO_write_filename(Sout, outfile) <= 0) { + perror(outfile); + goto err; + } + } else { + BIO_set_fp(Sout, stdout, BIO_NOCLOSE | BIO_FP_TEXT); + } + } + if ((md == NULL) && ((md = NCONF_get_string(conf, section, + ENV_DEFAULT_MD)) == NULL)) { + lookup_fail(section, ENV_DEFAULT_MD); + goto err; + } + if (!strcmp(md, "default")) { + int def_nid; + if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0) { + BIO_puts(bio_err, "no default digest\n"); + goto err; + } + md = (char *) OBJ_nid2sn(def_nid); + } + if ((dgst = EVP_get_digestbyname(md)) == NULL) { + BIO_printf(bio_err, + "%s is an unsupported message digest type\n", md); + goto err; + } + if (req) { + if ((email_dn == 1) && ((tmp_email_dn = NCONF_get_string(conf, + section, ENV_DEFAULT_EMAIL_DN)) != NULL)) { + if (strcmp(tmp_email_dn, "no") == 0) + email_dn = 0; + } + if (verbose) + BIO_printf(bio_err, "message digest is %s\n", + OBJ_nid2ln(dgst->type)); + if ((policy == NULL) && ((policy = NCONF_get_string(conf, + section, ENV_POLICY)) == NULL)) { + lookup_fail(section, ENV_POLICY); + goto err; + } + if (verbose) + BIO_printf(bio_err, "policy is %s\n", policy); + + if ((serialfile = NCONF_get_string(conf, section, + ENV_SERIAL)) == NULL) { + lookup_fail(section, ENV_SERIAL); + goto err; + } + if (!extconf) { + /* + * no '-extfile' option, so we look for extensions in + * the main configuration file + */ + if (!extensions) { + extensions = NCONF_get_string(conf, section, + ENV_EXTENSIONS); + if (!extensions) + ERR_clear_error(); + } + if (extensions) { + /* Check syntax of file */ + X509V3_CTX ctx; + X509V3_set_ctx_test(&ctx); + X509V3_set_nconf(&ctx, conf); + if (!X509V3_EXT_add_nconf(conf, &ctx, + extensions, NULL)) { + BIO_printf(bio_err, + "Error Loading extension section %s\n", + extensions); + ret = 1; + goto err; + } + } + } + if (startdate == NULL) { + startdate = NCONF_get_string(conf, section, + ENV_DEFAULT_STARTDATE); + if (startdate == NULL) + ERR_clear_error(); + } + if (startdate && !ASN1_TIME_set_string(NULL, startdate)) { + BIO_printf(bio_err, "start date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n"); + goto err; + } + if (startdate == NULL) + startdate = "today"; + + if (enddate == NULL) { + enddate = NCONF_get_string(conf, section, + ENV_DEFAULT_ENDDATE); + if (enddate == NULL) + ERR_clear_error(); + } + if (enddate && !ASN1_TIME_set_string(NULL, enddate)) { + BIO_printf(bio_err, "end date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n"); + goto err; + } + if (days == 0) { + if (!NCONF_get_number(conf, section, + ENV_DEFAULT_DAYS, &days)) + days = 0; + } + if (!enddate && (days == 0)) { + BIO_printf(bio_err, + "cannot lookup how many days to certify for\n"); + goto err; + } + if ((serial = load_serial(serialfile, create_ser, NULL)) == + NULL) { + BIO_printf(bio_err, + "error while loading serial number\n"); + goto err; + } + if (verbose) { + if (BN_is_zero(serial)) + BIO_printf(bio_err, + "next serial number is 00\n"); + else { + if ((f = BN_bn2hex(serial)) == NULL) + goto err; + BIO_printf(bio_err, + "next serial number is %s\n", f); + free(f); + } + } + if ((attribs = NCONF_get_section(conf, policy)) == NULL) { + BIO_printf(bio_err, + "unable to find 'section' for %s\n", policy); + goto err; + } + if ((cert_sk = sk_X509_new_null()) == NULL) { + BIO_printf(bio_err, "Memory allocation failure\n"); + goto err; + } + if (spkac_file != NULL) { + total++; + j = certify_spkac(&x, spkac_file, pkey, x509, dgst, + sigopts, attribs, db, serial, subj, chtype, + multirdn, email_dn, startdate, enddate, days, + extensions, conf, verbose, certopt, nameopt, + default_op, ext_copy); + if (j < 0) + goto err; + if (j > 0) { + total_done++; + BIO_printf(bio_err, "\n"); + if (!BN_add_word(serial, 1)) + goto err; + if (!sk_X509_push(cert_sk, x)) { + BIO_printf(bio_err, + "Memory allocation failure\n"); + goto err; + } + if (outfile) { + output_der = 1; + batch = 1; + } + } + } + if (ss_cert_file != NULL) { + total++; + j = certify_cert(&x, ss_cert_file, pkey, x509, dgst, + sigopts, attribs, db, serial, subj, chtype, + multirdn, email_dn, startdate, enddate, days, batch, + extensions, conf, verbose, certopt, nameopt, + default_op, ext_copy); + if (j < 0) + goto err; + if (j > 0) { + total_done++; + BIO_printf(bio_err, "\n"); + if (!BN_add_word(serial, 1)) + goto err; + if (!sk_X509_push(cert_sk, x)) { + BIO_printf(bio_err, + "Memory allocation failure\n"); + goto err; + } + } + } + if (infile != NULL) { + total++; + j = certify(&x, infile, pkey, x509p, dgst, sigopts, + attribs, db, serial, subj, chtype, multirdn, + email_dn, startdate, enddate, days, batch, + extensions, conf, verbose, certopt, nameopt, + default_op, ext_copy, selfsign); + if (j < 0) + goto err; + if (j > 0) { + total_done++; + BIO_printf(bio_err, "\n"); + if (!BN_add_word(serial, 1)) + goto err; + if (!sk_X509_push(cert_sk, x)) { + BIO_printf(bio_err, + "Memory allocation failure\n"); + goto err; + } + } + } + for (i = 0; i < argc; i++) { + total++; + j = certify(&x, argv[i], pkey, x509p, dgst, sigopts, + attribs, db, serial, subj, chtype, multirdn, + email_dn, startdate, enddate, days, batch, + extensions, conf, verbose, certopt, nameopt, + default_op, ext_copy, selfsign); + if (j < 0) + goto err; + if (j > 0) { + total_done++; + BIO_printf(bio_err, "\n"); + if (!BN_add_word(serial, 1)) + goto err; + if (!sk_X509_push(cert_sk, x)) { + BIO_printf(bio_err, + "Memory allocation failure\n"); + goto err; + } + } + } + /* + * we have a stack of newly certified certificates and a data + * base and serial number that need updating + */ + + if (sk_X509_num(cert_sk) > 0) { + if (!batch) { + BIO_printf(bio_err, "\n%d out of %d certificate requests certified, commit? [y/n]", total_done, total); + (void) BIO_flush(bio_err); + buf[0][0] = '\0'; + if (!fgets(buf[0], 10, stdin)) { + BIO_printf(bio_err, "CERTIFICATION CANCELED: I/O error\n"); + ret = 0; + goto err; + } + if ((buf[0][0] != 'y') && (buf[0][0] != 'Y')) { + BIO_printf(bio_err, "CERTIFICATION CANCELED\n"); + ret = 0; + goto err; + } + } + BIO_printf(bio_err, "Write out database with %d new entries\n", sk_X509_num(cert_sk)); + + if (!save_serial(serialfile, "new", serial, NULL)) + goto err; + + if (!save_index(dbfile, "new", db)) + goto err; + } + if (verbose) + BIO_printf(bio_err, "writing new certificates\n"); + for (i = 0; i < sk_X509_num(cert_sk); i++) { + int k; + char *serialstr; + unsigned char *data; + + x = sk_X509_value(cert_sk, i); + + j = x->cert_info->serialNumber->length; + data = (unsigned char *)x->cert_info->serialNumber->data; + if (j > 0) + serialstr = bin2hex(data, j); + else + serialstr = strdup("00"); + if (serialstr) { + k = snprintf(buf[2], sizeof(buf[2]), + "%s/%s.pem", outdir, serialstr); + free(serialstr); + if (k == -1 || k >= sizeof(buf[2])) { + BIO_printf(bio_err, + "certificate file name too long\n"); + goto err; + } + } else { + BIO_printf(bio_err, + "memory allocation failed\n"); + goto err; + } + if (verbose) + BIO_printf(bio_err, "writing %s\n", buf[2]); + + if (BIO_write_filename(Cout, buf[2]) <= 0) { + perror(buf[2]); + goto err; + } + write_new_certificate(Cout, x, 0, notext); + write_new_certificate(Sout, x, output_der, notext); + } + + if (sk_X509_num(cert_sk)) { + /* Rename the database and the serial file */ + if (!rotate_serial(serialfile, "new", "old")) + goto err; + + if (!rotate_index(dbfile, "new", "old")) + goto err; + + BIO_printf(bio_err, "Data Base Updated\n"); + } + } + /*****************************************************************/ + if (gencrl) { + int crl_v2 = 0; + if (!crl_ext) { + crl_ext = NCONF_get_string(conf, section, ENV_CRLEXT); + if (!crl_ext) + ERR_clear_error(); + } + if (crl_ext) { + /* Check syntax of file */ + X509V3_CTX ctx; + X509V3_set_ctx_test(&ctx); + X509V3_set_nconf(&ctx, conf); + if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL)) { + BIO_printf(bio_err, + "Error Loading CRL extension section %s\n", + crl_ext); + ret = 1; + goto err; + } + } + if ((crlnumberfile = NCONF_get_string(conf, section, + ENV_CRLNUMBER)) != NULL) + if ((crlnumber = load_serial(crlnumberfile, 0, + NULL)) == NULL) { + BIO_printf(bio_err, + "error while loading CRL number\n"); + goto err; + } + if (!crldays && !crlhours && !crlsec) { + if (!NCONF_get_number(conf, section, + ENV_DEFAULT_CRL_DAYS, &crldays)) + crldays = 0; + if (!NCONF_get_number(conf, section, + ENV_DEFAULT_CRL_HOURS, &crlhours)) + crlhours = 0; + ERR_clear_error(); + } + if ((crldays == 0) && (crlhours == 0) && (crlsec == 0)) { + BIO_printf(bio_err, "cannot lookup how long until the next CRL is issued\n"); + goto err; + } + if (verbose) + BIO_printf(bio_err, "making CRL\n"); + if ((crl = X509_CRL_new()) == NULL) + goto err; + if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) + goto err; + + tmptm = ASN1_TIME_new(); + if (!tmptm) + goto err; + X509_gmtime_adj(tmptm, 0); + X509_CRL_set_lastUpdate(crl, tmptm); + if (!X509_time_adj_ex(tmptm, crldays, + crlhours * 60 * 60 + crlsec, NULL)) { + BIO_puts(bio_err, "error setting CRL nextUpdate\n"); + goto err; + } + X509_CRL_set_nextUpdate(crl, tmptm); + + ASN1_TIME_free(tmptm); + + for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { + pp = sk_OPENSSL_PSTRING_value(db->db->data, i); + if (pp[DB_type][0] == DB_TYPE_REV) { + if ((r = X509_REVOKED_new()) == NULL) + goto err; + j = make_revoked(r, pp[DB_rev_date]); + if (!j) + goto err; + if (j == 2) + crl_v2 = 1; + if (!BN_hex2bn(&serial, pp[DB_serial])) + goto err; + tmpser = BN_to_ASN1_INTEGER(serial, NULL); + BN_free(serial); + serial = NULL; + if (!tmpser) + goto err; + X509_REVOKED_set_serialNumber(r, tmpser); + ASN1_INTEGER_free(tmpser); + X509_CRL_add0_revoked(crl, r); + } + } + + /* + * sort the data so it will be written in serial number order + */ + X509_CRL_sort(crl); + + /* we now have a CRL */ + if (verbose) + BIO_printf(bio_err, "signing CRL\n"); + + /* Add any extensions asked for */ + + if (crl_ext || crlnumberfile != NULL) { + X509V3_CTX crlctx; + X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0); + X509V3_set_nconf(&crlctx, conf); + + if (crl_ext) + if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx, + crl_ext, crl)) + goto err; + if (crlnumberfile != NULL) { + tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL); + if (!tmpser) + goto err; + X509_CRL_add1_ext_i2d(crl, NID_crl_number, + tmpser, 0, 0); + ASN1_INTEGER_free(tmpser); + crl_v2 = 1; + if (!BN_add_word(crlnumber, 1)) + goto err; + } + } + if (crl_ext || crl_v2) { + if (!X509_CRL_set_version(crl, 1)) + goto err; /* version 2 CRL */ + } + if (crlnumberfile != NULL) /* we have a CRL number that + * need updating */ + if (!save_serial(crlnumberfile, "new", crlnumber, NULL)) + goto err; + + if (crlnumber) { + BN_free(crlnumber); + crlnumber = NULL; + } + if (!do_X509_CRL_sign(bio_err, crl, pkey, dgst, sigopts)) + goto err; + + PEM_write_bio_X509_CRL(Sout, crl); + + if (crlnumberfile != NULL) /* Rename the crlnumber file */ + if (!rotate_serial(crlnumberfile, "new", "old")) + goto err; + + } + /*****************************************************************/ + if (dorevoke) { + if (infile == NULL) { + BIO_printf(bio_err, "no input files\n"); + goto err; + } else { + X509 *revcert; + revcert = load_cert(bio_err, infile, FORMAT_PEM, + NULL, infile); + if (revcert == NULL) + goto err; + j = do_revoke(revcert, db, rev_type, rev_arg); + if (j <= 0) + goto err; + X509_free(revcert); + + if (!save_index(dbfile, "new", db)) + goto err; + + if (!rotate_index(dbfile, "new", "old")) + goto err; + + BIO_printf(bio_err, "Data Base Updated\n"); + } + } + /*****************************************************************/ + ret = 0; + +err: + free(tofree); + + BIO_free_all(Cout); + BIO_free_all(Sout); + BIO_free_all(out); + BIO_free_all(in); + + if (cert_sk) + sk_X509_pop_free(cert_sk, X509_free); + + if (ret) + ERR_print_errors(bio_err); + if (free_key && key) + free(key); + BN_free(serial); + BN_free(crlnumber); + free_index(db); + if (sigopts) + sk_OPENSSL_STRING_free(sigopts); + EVP_PKEY_free(pkey); + if (x509) + X509_free(x509); + X509_CRL_free(crl); + NCONF_free(conf); + NCONF_free(extconf); + OBJ_cleanup(); + + return (ret); +} + +static void +lookup_fail(const char *name, const char *tag) +{ + BIO_printf(bio_err, "variable lookup failed for %s::%s\n", name, tag); +} + +static int +certify(X509 ** xret, char *infile, EVP_PKEY * pkey, X509 * x509, + const EVP_MD * dgst, STACK_OF(OPENSSL_STRING) * sigopts, + STACK_OF(CONF_VALUE) * policy, CA_DB * db, BIGNUM * serial, char *subj, + unsigned long chtype, int multirdn, int email_dn, char *startdate, + char *enddate, long days, int batch, char *ext_sect, CONF * lconf, + int verbose, unsigned long certopt, unsigned long nameopt, int default_op, + int ext_copy, int selfsign) +{ + X509_REQ *req = NULL; + BIO *in = NULL; + EVP_PKEY *pktmp = NULL; + int ok = -1, i; + + in = BIO_new(BIO_s_file()); + + if (BIO_read_filename(in, infile) <= 0) { + perror(infile); + goto err; + } + if ((req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL)) == NULL) { + BIO_printf(bio_err, "Error reading certificate request in %s\n", + infile); + goto err; + } + if (verbose) + X509_REQ_print(bio_err, req); + + BIO_printf(bio_err, "Check that the request matches the signature\n"); + + if (selfsign && !X509_REQ_check_private_key(req, pkey)) { + BIO_printf(bio_err, + "Certificate request and CA private key do not match\n"); + ok = 0; + goto err; + } + if ((pktmp = X509_REQ_get_pubkey(req)) == NULL) { + BIO_printf(bio_err, "error unpacking public key\n"); + goto err; + } + i = X509_REQ_verify(req, pktmp); + EVP_PKEY_free(pktmp); + if (i < 0) { + ok = 0; + BIO_printf(bio_err, "Signature verification problems....\n"); + goto err; + } + if (i == 0) { + ok = 0; + BIO_printf(bio_err, + "Signature did not match the certificate request\n"); + goto err; + } else + BIO_printf(bio_err, "Signature ok\n"); + + ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, + subj, chtype, multirdn, email_dn, startdate, enddate, days, batch, + verbose, req, ext_sect, lconf, certopt, nameopt, default_op, + ext_copy, selfsign); + +err: + if (req != NULL) + X509_REQ_free(req); + if (in != NULL) + BIO_free(in); + return (ok); +} + +static int +certify_cert(X509 ** xret, char *infile, EVP_PKEY * pkey, X509 * x509, + const EVP_MD * dgst, STACK_OF(OPENSSL_STRING) * sigopts, + STACK_OF(CONF_VALUE) * policy, CA_DB * db, BIGNUM * serial, char *subj, + unsigned long chtype, int multirdn, int email_dn, char *startdate, + char *enddate, long days, int batch, char *ext_sect, CONF * lconf, + int verbose, unsigned long certopt, unsigned long nameopt, int default_op, + int ext_copy) +{ + X509 *req = NULL; + X509_REQ *rreq = NULL; + EVP_PKEY *pktmp = NULL; + int ok = -1, i; + + if ((req = load_cert(bio_err, infile, FORMAT_PEM, NULL, + infile)) == NULL) + goto err; + if (verbose) + X509_print(bio_err, req); + + BIO_printf(bio_err, "Check that the request matches the signature\n"); + + if ((pktmp = X509_get_pubkey(req)) == NULL) { + BIO_printf(bio_err, "error unpacking public key\n"); + goto err; + } + i = X509_verify(req, pktmp); + EVP_PKEY_free(pktmp); + if (i < 0) { + ok = 0; + BIO_printf(bio_err, "Signature verification problems....\n"); + goto err; + } + if (i == 0) { + ok = 0; + BIO_printf(bio_err, + "Signature did not match the certificate\n"); + goto err; + } else + BIO_printf(bio_err, "Signature ok\n"); + + if ((rreq = X509_to_X509_REQ(req, NULL, EVP_md5())) == NULL) + goto err; + + ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, + subj, chtype, multirdn, email_dn, startdate, enddate, days, batch, + verbose, rreq, ext_sect, lconf, certopt, nameopt, default_op, + ext_copy, 0); + +err: + if (rreq != NULL) + X509_REQ_free(rreq); + if (req != NULL) + X509_free(req); + return (ok); +} + +static int +do_body(X509 ** xret, EVP_PKEY * pkey, X509 * x509, const EVP_MD * dgst, + STACK_OF(OPENSSL_STRING) * sigopts, STACK_OF(CONF_VALUE) * policy, + CA_DB * db, BIGNUM * serial, char *subj, unsigned long chtype, int multirdn, + int email_dn, char *startdate, char *enddate, long days, int batch, + int verbose, X509_REQ * req, char *ext_sect, CONF * lconf, + unsigned long certopt, unsigned long nameopt, int default_op, + int ext_copy, int selfsign) +{ + X509_NAME *name = NULL, *CAname = NULL, *subject = NULL, *dn_subject = NULL; + ASN1_UTCTIME *tm, *tmptm; + ASN1_STRING *str, *str2; + ASN1_OBJECT *obj; + X509 *ret = NULL; + X509_CINF *ci; + X509_NAME_ENTRY *ne; + X509_NAME_ENTRY *tne, *push; + EVP_PKEY *pktmp; + int ok = -1, i, j, last, nid; + const char *p; + CONF_VALUE *cv; + OPENSSL_STRING row[DB_NUMBER]; + OPENSSL_STRING *irow = NULL; + OPENSSL_STRING *rrow = NULL; + char buf[25]; + + tmptm = ASN1_UTCTIME_new(); + if (tmptm == NULL) { + BIO_printf(bio_err, "malloc error\n"); + return (0); + } + for (i = 0; i < DB_NUMBER; i++) + row[i] = NULL; + + if (subj) { + X509_NAME *n = parse_name(subj, chtype, multirdn); + + if (!n) { + ERR_print_errors(bio_err); + goto err; + } + X509_REQ_set_subject_name(req, n); + req->req_info->enc.modified = 1; + X509_NAME_free(n); + } + if (default_op) + BIO_printf(bio_err, + "The Subject's Distinguished Name is as follows\n"); + + name = X509_REQ_get_subject_name(req); + for (i = 0; i < X509_NAME_entry_count(name); i++) { + ne = X509_NAME_get_entry(name, i); + str = X509_NAME_ENTRY_get_data(ne); + obj = X509_NAME_ENTRY_get_object(ne); + + if (msie_hack) { + /* assume all type should be strings */ + nid = OBJ_obj2nid(ne->object); + + if (str->type == V_ASN1_UNIVERSALSTRING) + ASN1_UNIVERSALSTRING_to_string(str); + + if ((str->type == V_ASN1_IA5STRING) && + (nid != NID_pkcs9_emailAddress)) + str->type = V_ASN1_T61STRING; + + if ((nid == NID_pkcs9_emailAddress) && + (str->type == V_ASN1_PRINTABLESTRING)) + str->type = V_ASN1_IA5STRING; + } + /* If no EMAIL is wanted in the subject */ + if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn)) + continue; + + /* check some things */ + if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && + (str->type != V_ASN1_IA5STRING)) { + BIO_printf(bio_err, "\nemailAddress type needs to be of type IA5STRING\n"); + goto err; + } + if ((str->type != V_ASN1_BMPSTRING) && + (str->type != V_ASN1_UTF8STRING)) { + j = ASN1_PRINTABLE_type(str->data, str->length); + if (((j == V_ASN1_T61STRING) && + (str->type != V_ASN1_T61STRING)) || + ((j == V_ASN1_IA5STRING) && + (str->type == V_ASN1_PRINTABLESTRING))) { + BIO_printf(bio_err, "\nThe string contains characters that are illegal for the ASN.1 type\n"); + goto err; + } + } + if (default_op) + old_entry_print(bio_err, obj, str); + } + + /* Ok, now we check the 'policy' stuff. */ + if ((subject = X509_NAME_new()) == NULL) { + BIO_printf(bio_err, "Memory allocation failure\n"); + goto err; + } + /* take a copy of the issuer name before we mess with it. */ + if (selfsign) + CAname = X509_NAME_dup(name); + else + CAname = X509_NAME_dup(x509->cert_info->subject); + if (CAname == NULL) + goto err; + str = str2 = NULL; + + for (i = 0; i < sk_CONF_VALUE_num(policy); i++) { + cv = sk_CONF_VALUE_value(policy, i); /* get the object id */ + if ((j = OBJ_txt2nid(cv->name)) == NID_undef) { + BIO_printf(bio_err, "%s:unknown object type in 'policy' configuration\n", cv->name); + goto err; + } + obj = OBJ_nid2obj(j); + + last = -1; + for (;;) { + /* lookup the object in the supplied name list */ + j = X509_NAME_get_index_by_OBJ(name, obj, last); + if (j < 0) { + if (last != -1) + break; + tne = NULL; + } else { + tne = X509_NAME_get_entry(name, j); + } + last = j; + + /* depending on the 'policy', decide what to do. */ + push = NULL; + if (strcmp(cv->value, "optional") == 0) { + if (tne != NULL) + push = tne; + } else if (strcmp(cv->value, "supplied") == 0) { + if (tne == NULL) { + BIO_printf(bio_err, "The %s field needed to be supplied and was missing\n", cv->name); + goto err; + } else + push = tne; + } else if (strcmp(cv->value, "match") == 0) { + int last2; + + if (tne == NULL) { + BIO_printf(bio_err, "The mandatory %s field was missing\n", cv->name); + goto err; + } + last2 = -1; + +again2: + j = X509_NAME_get_index_by_OBJ(CAname, obj, last2); + if ((j < 0) && (last2 == -1)) { + BIO_printf(bio_err, "The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n", cv->name); + goto err; + } + if (j >= 0) { + push = X509_NAME_get_entry(CAname, j); + str = X509_NAME_ENTRY_get_data(tne); + str2 = X509_NAME_ENTRY_get_data(push); + last2 = j; + if (ASN1_STRING_cmp(str, str2) != 0) + goto again2; + } + if (j < 0) { + BIO_printf(bio_err, "The %s field needed to be the same in the\nCA certificate (%s) and the request (%s)\n", cv->name, ((str2 == NULL) ? "NULL" : (char *) str2->data), ((str == NULL) ? "NULL" : (char *) str->data)); + goto err; + } + } else { + BIO_printf(bio_err, "%s:invalid type in 'policy' configuration\n", cv->value); + goto err; + } + + if (push != NULL) { + if (!X509_NAME_add_entry(subject, push, + -1, 0)) { + if (push != NULL) + X509_NAME_ENTRY_free(push); + BIO_printf(bio_err, + "Memory allocation failure\n"); + goto err; + } + } + if (j < 0) + break; + } + } + + if (preserve) { + X509_NAME_free(subject); + /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */ + subject = X509_NAME_dup(name); + if (subject == NULL) + goto err; + } + if (verbose) + BIO_printf(bio_err, "The subject name appears to be ok, checking data base for clashes\n"); + + /* Build the correct Subject if no email is wanted in the subject */ + /* + * and add it later on because of the method extensions are added + * (altName) + */ + + if (email_dn) + dn_subject = subject; + else { + X509_NAME_ENTRY *tmpne; + /* + * Its best to dup the subject DN and then delete any email + * addresses because this retains its structure. + */ + if (!(dn_subject = X509_NAME_dup(subject))) { + BIO_printf(bio_err, "Memory allocation failure\n"); + goto err; + } + while ((i = X509_NAME_get_index_by_NID(dn_subject, + NID_pkcs9_emailAddress, -1)) >= 0) { + tmpne = X509_NAME_get_entry(dn_subject, i); + X509_NAME_delete_entry(dn_subject, i); + X509_NAME_ENTRY_free(tmpne); + } + } + + if (BN_is_zero(serial)) + row[DB_serial] = strdup("00"); + else + row[DB_serial] = BN_bn2hex(serial); + if (row[DB_serial] == NULL) { + BIO_printf(bio_err, "Memory allocation failure\n"); + goto err; + } + if (db->attributes.unique_subject) { + OPENSSL_STRING *crow = row; + + rrow = TXT_DB_get_by_index(db->db, DB_name, crow); + if (rrow != NULL) { + BIO_printf(bio_err, + "ERROR:There is already a certificate for %s\n", + row[DB_name]); + } + } + if (rrow == NULL) { + rrow = TXT_DB_get_by_index(db->db, DB_serial, row); + if (rrow != NULL) { + BIO_printf(bio_err, + "ERROR:Serial number %s has already been issued,\n", + row[DB_serial]); + BIO_printf(bio_err, " check the database/serial_file for corruption\n"); + } + } + if (rrow != NULL) { + BIO_printf(bio_err, + "The matching entry has the following details\n"); + if (rrow[DB_type][0] == 'E') + p = "Expired"; + else if (rrow[DB_type][0] == 'R') + p = "Revoked"; + else if (rrow[DB_type][0] == 'V') + p = "Valid"; + else + p = "\ninvalid type, Data base error\n"; + BIO_printf(bio_err, "Type :%s\n", p); + if (rrow[DB_type][0] == 'R') { + p = rrow[DB_exp_date]; + if (p == NULL) + p = "undef"; + BIO_printf(bio_err, "Was revoked on:%s\n", p); + } + p = rrow[DB_exp_date]; + if (p == NULL) + p = "undef"; + BIO_printf(bio_err, "Expires on :%s\n", p); + p = rrow[DB_serial]; + if (p == NULL) + p = "undef"; + BIO_printf(bio_err, "Serial Number :%s\n", p); + p = rrow[DB_file]; + if (p == NULL) + p = "undef"; + BIO_printf(bio_err, "File name :%s\n", p); + p = rrow[DB_name]; + if (p == NULL) + p = "undef"; + BIO_printf(bio_err, "Subject Name :%s\n", p); + ok = -1; /* This is now a 'bad' error. */ + goto err; + } + /* We are now totally happy, lets make and sign the certificate */ + if (verbose) + BIO_printf(bio_err, "Everything appears to be ok, creating and signing the certificate\n"); + + if ((ret = X509_new()) == NULL) + goto err; + ci = ret->cert_info; + +#ifdef X509_V3 + /* Make it an X509 v3 certificate. */ + if (!X509_set_version(ret, 2)) + goto err; +#endif + if (ci->serialNumber == NULL) + goto err; + if (BN_to_ASN1_INTEGER(serial, ci->serialNumber) == NULL) + goto err; + if (selfsign) { + if (!X509_set_issuer_name(ret, subject)) + goto err; + } else { + if (!X509_set_issuer_name(ret, X509_get_subject_name(x509))) + goto err; + } + + if (strcmp(startdate, "today") == 0) + X509_gmtime_adj(X509_get_notBefore(ret), 0); + else + ASN1_TIME_set_string(X509_get_notBefore(ret), startdate); + + if (enddate == NULL) + X509_time_adj_ex(X509_get_notAfter(ret), days, 0, NULL); + else + ASN1_TIME_set_string(X509_get_notAfter(ret), enddate); + + if (!X509_set_subject_name(ret, subject)) + goto err; + + pktmp = X509_REQ_get_pubkey(req); + i = X509_set_pubkey(ret, pktmp); + EVP_PKEY_free(pktmp); + if (!i) + goto err; + + /* Lets add the extensions, if there are any */ + if (ext_sect) { + X509V3_CTX ctx; + if (ci->version == NULL) + if ((ci->version = ASN1_INTEGER_new()) == NULL) + goto err; + ASN1_INTEGER_set(ci->version, 2); /* version 3 certificate */ + + /* + * Free the current entries if any, there should not be any I + * believe + */ + if (ci->extensions != NULL) + sk_X509_EXTENSION_pop_free(ci->extensions, + X509_EXTENSION_free); + + ci->extensions = NULL; + + /* Initialize the context structure */ + if (selfsign) + X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0); + else + X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0); + + if (extconf) { + if (verbose) + BIO_printf(bio_err, + "Extra configuration file found\n"); + + /* Use the extconf configuration db LHASH */ + X509V3_set_nconf(&ctx, extconf); + + /* Test the structure (needed?) */ + /* X509V3_set_ctx_test(&ctx); */ + + /* Adds exts contained in the configuration file */ + if (!X509V3_EXT_add_nconf(extconf, &ctx, + ext_sect, ret)) { + BIO_printf(bio_err, + "ERROR: adding extensions in section %s\n", + ext_sect); + ERR_print_errors(bio_err); + goto err; + } + if (verbose) + BIO_printf(bio_err, "Successfully added extensions from file.\n"); + } else if (ext_sect) { + /* We found extensions to be set from config file */ + X509V3_set_nconf(&ctx, lconf); + + if (!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret)) { + BIO_printf(bio_err, + "ERROR: adding extensions in section %s\n", + ext_sect); + ERR_print_errors(bio_err); + goto err; + } + if (verbose) + BIO_printf(bio_err, "Successfully added extensions from config\n"); + } + } + /* Copy extensions from request (if any) */ + + if (!copy_extensions(ret, req, ext_copy)) { + BIO_printf(bio_err, "ERROR: adding extensions from request\n"); + ERR_print_errors(bio_err); + goto err; + } + /* Set the right value for the noemailDN option */ + if (email_dn == 0) { + if (!X509_set_subject_name(ret, dn_subject)) + goto err; + } + if (!default_op) { + BIO_printf(bio_err, "Certificate Details:\n"); + /* + * Never print signature details because signature not + * present + */ + certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME; + X509_print_ex(bio_err, ret, nameopt, certopt); + } + BIO_printf(bio_err, "Certificate is to be certified until "); + ASN1_TIME_print(bio_err, X509_get_notAfter(ret)); + if (days) + BIO_printf(bio_err, " (%ld days)", days); + BIO_printf(bio_err, "\n"); + + if (!batch) { + + BIO_printf(bio_err, "Sign the certificate? [y/n]:"); + (void) BIO_flush(bio_err); + buf[0] = '\0'; + if (!fgets(buf, sizeof(buf) - 1, stdin)) { + BIO_printf(bio_err, + "CERTIFICATE WILL NOT BE CERTIFIED: I/O error\n"); + ok = 0; + goto err; + } + if (!((buf[0] == 'y') || (buf[0] == 'Y'))) { + BIO_printf(bio_err, + "CERTIFICATE WILL NOT BE CERTIFIED\n"); + ok = 0; + goto err; + } + } + pktmp = X509_get_pubkey(ret); + if (EVP_PKEY_missing_parameters(pktmp) && + !EVP_PKEY_missing_parameters(pkey)) + EVP_PKEY_copy_parameters(pktmp, pkey); + EVP_PKEY_free(pktmp); + + if (!do_X509_sign(bio_err, ret, pkey, dgst, sigopts)) + goto err; + + /* We now just add it to the database */ + row[DB_type] = malloc(2); + + tm = X509_get_notAfter(ret); + row[DB_exp_date] = malloc(tm->length + 1); + if (row[DB_type] == NULL || row[DB_exp_date] == NULL) { + BIO_printf(bio_err, "Memory allocation failure\n"); + goto err; + } + + memcpy(row[DB_exp_date], tm->data, tm->length); + row[DB_exp_date][tm->length] = '\0'; + + row[DB_rev_date] = NULL; + + /* row[DB_serial] done already */ + row[DB_file] = malloc(8); + row[DB_name] = X509_NAME_oneline(X509_get_subject_name(ret), NULL, 0); + + if ((row[DB_type] == NULL) || (row[DB_file] == NULL) || + (row[DB_name] == NULL)) { + BIO_printf(bio_err, "Memory allocation failure\n"); + goto err; + } + (void) strlcpy(row[DB_file], "unknown", 8); + row[DB_type][0] = 'V'; + row[DB_type][1] = '\0'; + + if ((irow = reallocarray(NULL, DB_NUMBER + 1, sizeof(char *))) == + NULL) { + BIO_printf(bio_err, "Memory allocation failure\n"); + goto err; + } + for (i = 0; i < DB_NUMBER; i++) { + irow[i] = row[i]; + row[i] = NULL; + } + irow[DB_NUMBER] = NULL; + + if (!TXT_DB_insert(db->db, irow)) { + BIO_printf(bio_err, "failed to update database\n"); + BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error); + goto err; + } + ok = 1; +err: + for (i = 0; i < DB_NUMBER; i++) + free(row[i]); + + if (CAname != NULL) + X509_NAME_free(CAname); + if (subject != NULL) + X509_NAME_free(subject); + if ((dn_subject != NULL) && !email_dn) + X509_NAME_free(dn_subject); + if (tmptm != NULL) + ASN1_UTCTIME_free(tmptm); + if (ok <= 0) { + if (ret != NULL) + X509_free(ret); + ret = NULL; + } else + *xret = ret; + return (ok); +} + +static void +write_new_certificate(BIO * bp, X509 * x, int output_der, int notext) +{ + if (output_der) { + (void) i2d_X509_bio(bp, x); + return; + } + if (!notext) + X509_print(bp, x); + PEM_write_bio_X509(bp, x); +} + +static int +certify_spkac(X509 ** xret, char *infile, EVP_PKEY * pkey, X509 * x509, + const EVP_MD * dgst, STACK_OF(OPENSSL_STRING) * sigopts, + STACK_OF(CONF_VALUE) * policy, CA_DB * db, BIGNUM * serial, char *subj, + unsigned long chtype, int multirdn, int email_dn, char *startdate, + char *enddate, long days, char *ext_sect, CONF * lconf, int verbose, + unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy) +{ + STACK_OF(CONF_VALUE) * sk = NULL; + LHASH_OF(CONF_VALUE) * parms = NULL; + X509_REQ *req = NULL; + CONF_VALUE *cv = NULL; + NETSCAPE_SPKI *spki = NULL; + X509_REQ_INFO *ri; + char *type, *buf; + EVP_PKEY *pktmp = NULL; + X509_NAME *n = NULL; + int ok = -1, i, j; + long errline; + int nid; + + /* + * Load input file into a hash table. (This is just an easy + * way to read and parse the file, then put it into a convenient + * STACK format). + */ + parms = CONF_load(NULL, infile, &errline); + if (parms == NULL) { + BIO_printf(bio_err, "error on line %ld of %s\n", + errline, infile); + ERR_print_errors(bio_err); + goto err; + } + sk = CONF_get_section(parms, "default"); + if (sk_CONF_VALUE_num(sk) == 0) { + BIO_printf(bio_err, "no name/value pairs found in %s\n", + infile); + CONF_free(parms); + goto err; + } + /* + * Now create a dummy X509 request structure. We don't actually + * have an X509 request, but we have many of the components + * (a public key, various DN components). The idea is that we + * put these components into the right X509 request structure + * and we can use the same code as if you had a real X509 request. + */ + req = X509_REQ_new(); + if (req == NULL) { + ERR_print_errors(bio_err); + goto err; + } + /* + * Build up the subject name set. + */ + ri = req->req_info; + n = ri->subject; + + for (i = 0;; i++) { + if (sk_CONF_VALUE_num(sk) <= i) + break; + + cv = sk_CONF_VALUE_value(sk, i); + type = cv->name; + /* + * Skip past any leading X. X: X, etc to allow for multiple + * instances + */ + for (buf = cv->name; *buf; buf++) { + if ((*buf == ':') || (*buf == ',') || (*buf == '.')) { + buf++; + if (*buf) + type = buf; + break; + } + } + + buf = cv->value; + if ((nid = OBJ_txt2nid(type)) == NID_undef) { + if (strcmp(type, "SPKAC") == 0) { + spki = NETSCAPE_SPKI_b64_decode(cv->value, -1); + if (spki == NULL) { + BIO_printf(bio_err, "unable to load Netscape SPKAC structure\n"); + ERR_print_errors(bio_err); + goto err; + } + } + continue; + } + if (!X509_NAME_add_entry_by_NID(n, nid, chtype, + (unsigned char *)buf, -1, -1, 0)) + goto err; + } + if (spki == NULL) { + BIO_printf(bio_err, + "Netscape SPKAC structure not found in %s\n", infile); + goto err; + } + /* + * Now extract the key from the SPKI structure. + */ + + BIO_printf(bio_err, + "Check that the SPKAC request matches the signature\n"); + + if ((pktmp = NETSCAPE_SPKI_get_pubkey(spki)) == NULL) { + BIO_printf(bio_err, "error unpacking SPKAC public key\n"); + goto err; + } + j = NETSCAPE_SPKI_verify(spki, pktmp); + if (j <= 0) { + BIO_printf(bio_err, + "signature verification failed on SPKAC public key\n"); + goto err; + } + BIO_printf(bio_err, "Signature ok\n"); + + X509_REQ_set_pubkey(req, pktmp); + EVP_PKEY_free(pktmp); + ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, + subj, chtype, multirdn, email_dn, startdate, enddate, days, 1, + verbose, req, ext_sect, lconf, certopt, nameopt, default_op, + ext_copy, 0); + +err: + if (req != NULL) + X509_REQ_free(req); + if (parms != NULL) + CONF_free(parms); + if (spki != NULL) + NETSCAPE_SPKI_free(spki); + + return (ok); +} + +static int +check_time_format(const char *str) +{ + return ASN1_TIME_set_string(NULL, str); +} + +static int +do_revoke(X509 * x509, CA_DB * db, int type, char *value) +{ + ASN1_UTCTIME *tm = NULL; + char *row[DB_NUMBER], **rrow, **irow; + char *rev_str = NULL; + BIGNUM *bn = NULL; + int ok = -1, i; + + for (i = 0; i < DB_NUMBER; i++) + row[i] = NULL; + row[DB_name] = X509_NAME_oneline(X509_get_subject_name(x509), NULL, 0); + bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509), NULL); + if (!bn) + goto err; + if (BN_is_zero(bn)) + row[DB_serial] = strdup("00"); + else + row[DB_serial] = BN_bn2hex(bn); + BN_free(bn); + if ((row[DB_name] == NULL) || (row[DB_serial] == NULL)) { + BIO_printf(bio_err, "Memory allocation failure\n"); + goto err; + } + /* + * We have to lookup by serial number because name lookup skips + * revoked certs + */ + rrow = TXT_DB_get_by_index(db->db, DB_serial, row); + if (rrow == NULL) { + BIO_printf(bio_err, + "Adding Entry with serial number %s to DB for %s\n", + row[DB_serial], row[DB_name]); + + /* We now just add it to the database */ + row[DB_type] = malloc(2); + + tm = X509_get_notAfter(x509); + row[DB_exp_date] = malloc(tm->length + 1); + if (row[DB_type] == NULL || row[DB_exp_date] == NULL) { + BIO_printf(bio_err, "Memory allocation failure\n"); + goto err; + } + memcpy(row[DB_exp_date], tm->data, tm->length); + row[DB_exp_date][tm->length] = '\0'; + + row[DB_rev_date] = NULL; + + /* row[DB_serial] done already */ + row[DB_file] = malloc(8); + + /* row[DB_name] done already */ + + if ((row[DB_type] == NULL) || (row[DB_file] == NULL)) { + BIO_printf(bio_err, "Memory allocation failure\n"); + goto err; + } + (void) strlcpy(row[DB_file], "unknown", 8); + row[DB_type][0] = 'V'; + row[DB_type][1] = '\0'; + + if ((irow = reallocarray(NULL, sizeof(char *), + (DB_NUMBER + 1))) == NULL) { + BIO_printf(bio_err, "Memory allocation failure\n"); + goto err; + } + for (i = 0; i < DB_NUMBER; i++) { + irow[i] = row[i]; + row[i] = NULL; + } + irow[DB_NUMBER] = NULL; + + if (!TXT_DB_insert(db->db, irow)) { + BIO_printf(bio_err, "failed to update database\n"); + BIO_printf(bio_err, "TXT_DB error number %ld\n", + db->db->error); + goto err; + } + /* Revoke Certificate */ + ok = do_revoke(x509, db, type, value); + + goto err; + + } else if (index_name_cmp_noconst(row, rrow)) { + BIO_printf(bio_err, "ERROR:name does not match %s\n", + row[DB_name]); + goto err; + } else if (rrow[DB_type][0] == 'R') { + BIO_printf(bio_err, "ERROR:Already revoked, serial number %s\n", + row[DB_serial]); + goto err; + } else { + BIO_printf(bio_err, "Revoking Certificate %s.\n", + rrow[DB_serial]); + rev_str = make_revocation_str(type, value); + if (!rev_str) { + BIO_printf(bio_err, "Error in revocation arguments\n"); + goto err; + } + rrow[DB_type][0] = 'R'; + rrow[DB_type][1] = '\0'; + rrow[DB_rev_date] = rev_str; + } + ok = 1; + +err: + for (i = 0; i < DB_NUMBER; i++) + free(row[i]); + + return (ok); +} + +static int +get_certificate_status(const char *serial, CA_DB * db) +{ + char *row[DB_NUMBER], **rrow; + int ok = -1, i; + + /* Free Resources */ + for (i = 0; i < DB_NUMBER; i++) + row[i] = NULL; + + /* Malloc needed char spaces */ + row[DB_serial] = malloc(strlen(serial) + 2); + if (row[DB_serial] == NULL) { + BIO_printf(bio_err, "Malloc failure\n"); + goto err; + } + if (strlen(serial) % 2) { + /* Set the first char to 0 */ ; + row[DB_serial][0] = '0'; + + /* Copy String from serial to row[DB_serial] */ + memcpy(row[DB_serial] + 1, serial, strlen(serial)); + row[DB_serial][strlen(serial) + 1] = '\0'; + } else { + /* Copy String from serial to row[DB_serial] */ + memcpy(row[DB_serial], serial, strlen(serial)); + row[DB_serial][strlen(serial)] = '\0'; + } + + /* Make it Upper Case */ + for (i = 0; row[DB_serial][i] != '\0'; i++) + row[DB_serial][i] = toupper((unsigned char) row[DB_serial][i]); + + + ok = 1; + + /* Search for the certificate */ + rrow = TXT_DB_get_by_index(db->db, DB_serial, row); + if (rrow == NULL) { + BIO_printf(bio_err, "Serial %s not present in db.\n", + row[DB_serial]); + ok = -1; + goto err; + } else if (rrow[DB_type][0] == 'V') { + BIO_printf(bio_err, "%s=Valid (%c)\n", + row[DB_serial], rrow[DB_type][0]); + goto err; + } else if (rrow[DB_type][0] == 'R') { + BIO_printf(bio_err, "%s=Revoked (%c)\n", + row[DB_serial], rrow[DB_type][0]); + goto err; + } else if (rrow[DB_type][0] == 'E') { + BIO_printf(bio_err, "%s=Expired (%c)\n", + row[DB_serial], rrow[DB_type][0]); + goto err; + } else if (rrow[DB_type][0] == 'S') { + BIO_printf(bio_err, "%s=Suspended (%c)\n", + row[DB_serial], rrow[DB_type][0]); + goto err; + } else { + BIO_printf(bio_err, "%s=Unknown (%c).\n", + row[DB_serial], rrow[DB_type][0]); + ok = -1; + } + +err: + for (i = 0; i < DB_NUMBER; i++) + free(row[i]); + + return (ok); +} + +static int +do_updatedb(CA_DB * db) +{ + ASN1_UTCTIME *a_tm = NULL; + int i, cnt = 0; + int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */ + char **rrow, *a_tm_s; + + a_tm = ASN1_UTCTIME_new(); + + /* get actual time and make a string */ + a_tm = X509_gmtime_adj(a_tm, 0); + a_tm_s = malloc(a_tm->length + 1); + if (a_tm_s == NULL) { + cnt = -1; + goto err; + } + memcpy(a_tm_s, a_tm->data, a_tm->length); + a_tm_s[a_tm->length] = '\0'; + + if (strncmp(a_tm_s, "49", 2) <= 0) + a_y2k = 1; + else + a_y2k = 0; + + for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { + rrow = sk_OPENSSL_PSTRING_value(db->db->data, i); + + if (rrow[DB_type][0] == 'V') { + /* ignore entries that are not valid */ + if (strncmp(rrow[DB_exp_date], "49", 2) <= 0) + db_y2k = 1; + else + db_y2k = 0; + + if (db_y2k == a_y2k) { + /* all on the same y2k side */ + if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0) { + rrow[DB_type][0] = 'E'; + rrow[DB_type][1] = '\0'; + cnt++; + + BIO_printf(bio_err, "%s=Expired\n", + rrow[DB_serial]); + } + } else if (db_y2k < a_y2k) { + rrow[DB_type][0] = 'E'; + rrow[DB_type][1] = '\0'; + cnt++; + + BIO_printf(bio_err, "%s=Expired\n", + rrow[DB_serial]); + } + } + } + +err: + ASN1_UTCTIME_free(a_tm); + free(a_tm_s); + + return (cnt); +} + +static const char *crl_reasons[] = { + /* CRL reason strings */ + "unspecified", + "keyCompromise", + "CACompromise", + "affiliationChanged", + "superseded", + "cessationOfOperation", + "certificateHold", + "removeFromCRL", + /* Additional pseudo reasons */ + "holdInstruction", + "keyTime", + "CAkeyTime" +}; + +#define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *)) + +/* Given revocation information convert to a DB string. + * The format of the string is: + * revtime[,reason,extra]. Where 'revtime' is the + * revocation time (the current time). 'reason' is the + * optional CRL reason and 'extra' is any additional + * argument + */ + +char * +make_revocation_str(int rev_type, char *rev_arg) +{ + char *other = NULL, *str; + const char *reason = NULL; + ASN1_OBJECT *otmp; + ASN1_UTCTIME *revtm = NULL; + int i; + switch (rev_type) { + case REV_NONE: + break; + + case REV_CRL_REASON: + for (i = 0; i < 8; i++) { + if (!strcasecmp(rev_arg, crl_reasons[i])) { + reason = crl_reasons[i]; + break; + } + } + if (reason == NULL) { + BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg); + return NULL; + } + break; + + case REV_HOLD: + /* Argument is an OID */ + + otmp = OBJ_txt2obj(rev_arg, 0); + ASN1_OBJECT_free(otmp); + + if (otmp == NULL) { + BIO_printf(bio_err, + "Invalid object identifier %s\n", rev_arg); + return NULL; + } + reason = "holdInstruction"; + other = rev_arg; + break; + + case REV_KEY_COMPROMISE: + case REV_CA_COMPROMISE: + + /* Argument is the key compromise time */ + if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg)) { + BIO_printf(bio_err, + "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", + rev_arg); + return NULL; + } + other = rev_arg; + if (rev_type == REV_KEY_COMPROMISE) + reason = "keyTime"; + else + reason = "CAkeyTime"; + + break; + + } + + revtm = X509_gmtime_adj(NULL, 0); + if (asprintf(&str, "%s%s%s%s%s", revtm->data, + reason ? "," : "", reason ? reason : "", + other ? "," : "", other ? other : "") == -1) + str = NULL; + ASN1_UTCTIME_free(revtm); + return str; +} + +/* Convert revocation field to X509_REVOKED entry + * return code: + * 0 error + * 1 OK + * 2 OK and some extensions added (i.e. V2 CRL) + */ + +int +make_revoked(X509_REVOKED * rev, const char *str) +{ + char *tmp = NULL; + int reason_code = -1; + int i, ret = 0; + ASN1_OBJECT *hold = NULL; + ASN1_GENERALIZEDTIME *comp_time = NULL; + ASN1_ENUMERATED *rtmp = NULL; + + ASN1_TIME *revDate = NULL; + + i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str); + + if (i == 0) + goto err; + + if (rev && !X509_REVOKED_set_revocationDate(rev, revDate)) + goto err; + + if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)) { + rtmp = ASN1_ENUMERATED_new(); + if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code)) + goto err; + if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0)) + goto err; + } + if (rev && comp_time) { + if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, + comp_time, 0, 0)) + goto err; + } + if (rev && hold) { + if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, + hold, 0, 0)) + goto err; + } + if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS) + ret = 2; + else + ret = 1; + +err: + free(tmp); + + ASN1_OBJECT_free(hold); + ASN1_GENERALIZEDTIME_free(comp_time); + ASN1_ENUMERATED_free(rtmp); + ASN1_TIME_free(revDate); + + return ret; +} + +int +old_entry_print(BIO * bp, ASN1_OBJECT * obj, ASN1_STRING * str) +{ + char buf[25], *pbuf, *p; + int j; + + j = i2a_ASN1_OBJECT(bp, obj); + pbuf = buf; + for (j = 22 - j; j > 0; j--) + *(pbuf++) = ' '; + *(pbuf++) = ':'; + *(pbuf++) = '\0'; + BIO_puts(bp, buf); + + if (str->type == V_ASN1_PRINTABLESTRING) + BIO_printf(bp, "PRINTABLE:'"); + else if (str->type == V_ASN1_T61STRING) + BIO_printf(bp, "T61STRING:'"); + else if (str->type == V_ASN1_IA5STRING) + BIO_printf(bp, "IA5STRING:'"); + else if (str->type == V_ASN1_UNIVERSALSTRING) + BIO_printf(bp, "UNIVERSALSTRING:'"); + else + BIO_printf(bp, "ASN.1 %2d:'", str->type); + + p = (char *) str->data; + for (j = str->length; j > 0; j--) { + if ((*p >= ' ') && (*p <= '~')) + BIO_printf(bp, "%c", *p); + else if (*p & 0x80) + BIO_printf(bp, "\\0x%02X", *p); + else if ((unsigned char) *p == 0xf7) + BIO_printf(bp, "^?"); + else + BIO_printf(bp, "^%c", *p + '@'); + p++; + } + BIO_printf(bp, "'\n"); + return 1; +} + +int +unpack_revinfo(ASN1_TIME ** prevtm, int *preason, ASN1_OBJECT ** phold, + ASN1_GENERALIZEDTIME ** pinvtm, const char *str) +{ + char *tmp = NULL; + char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p; + int reason_code = -1; + int ret = 0; + unsigned int i; + ASN1_OBJECT *hold = NULL; + ASN1_GENERALIZEDTIME *comp_time = NULL; + + if ((tmp = strdup(str)) == NULL) { + BIO_printf(bio_err, "malloc failed\n"); + goto err; + } + p = strchr(tmp, ','); + rtime_str = tmp; + + if (p) { + *p = '\0'; + p++; + reason_str = p; + p = strchr(p, ','); + if (p) { + *p = '\0'; + arg_str = p + 1; + } + } + if (prevtm) { + *prevtm = ASN1_UTCTIME_new(); + if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str)) { + BIO_printf(bio_err, "invalid revocation date %s\n", + rtime_str); + goto err; + } + } + if (reason_str) { + for (i = 0; i < NUM_REASONS; i++) { + if (!strcasecmp(reason_str, crl_reasons[i])) { + reason_code = i; + break; + } + } + if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS) { + BIO_printf(bio_err, "invalid reason code %s\n", + reason_str); + goto err; + } + if (reason_code == 7) + reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL; + else if (reason_code == 8) { /* Hold instruction */ + if (!arg_str) { + BIO_printf(bio_err, + "missing hold instruction\n"); + goto err; + } + reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD; + hold = OBJ_txt2obj(arg_str, 0); + + if (!hold) { + BIO_printf(bio_err, + "invalid object identifier %s\n", arg_str); + goto err; + } + if (phold) + *phold = hold; + } else if ((reason_code == 9) || (reason_code == 10)) { + if (!arg_str) { + BIO_printf(bio_err, + "missing compromised time\n"); + goto err; + } + comp_time = ASN1_GENERALIZEDTIME_new(); + if (!ASN1_GENERALIZEDTIME_set_string(comp_time, + arg_str)) { + BIO_printf(bio_err, + "invalid compromised time %s\n", arg_str); + goto err; + } + if (reason_code == 9) + reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE; + else + reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE; + } + } + if (preason) + *preason = reason_code; + if (pinvtm) + *pinvtm = comp_time; + else + ASN1_GENERALIZEDTIME_free(comp_time); + + ret = 1; + +err: + free(tmp); + + if (!phold) + ASN1_OBJECT_free(hold); + if (!pinvtm) + ASN1_GENERALIZEDTIME_free(comp_time); + + return ret; +} + +static char * +bin2hex(unsigned char * data, size_t len) +{ + char *ret = NULL; + char hex[] = "0123456789ABCDEF"; + int i; + + if ((ret = malloc(len * 2 + 1))) { + for (i = 0; i < len; i++) { + ret[i * 2 + 0] = hex[data[i] >> 4]; + ret[i * 2 + 1] = hex[data[i] & 0x0F]; + } + ret[len * 2] = '\0'; + } + return ret; +} diff --git a/crypto/libressl/apps/openssl/cert.pem b/crypto/libressl/apps/openssl/cert.pem new file mode 100644 index 0000000000..359544635c --- /dev/null +++ b/crypto/libressl/apps/openssl/cert.pem @@ -0,0 +1,3580 @@ +# $OpenBSD: cert.pem,v 1.11 2016/02/17 13:06:54 sthen Exp $ + +### AddTrust AB + +=== AddTrust Class 1 CA Root +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: May 30 10:38:31 2000 GMT + Not After : May 30 10:38:31 2020 GMT + Subject: C=SE, O=AddTrust AB, OU=AddTrust TTP Network, CN=AddTrust Class 1 CA Root + X509v3 extensions: + X509v3 Subject Key Identifier: + 95:B1:B4:F0:94:B6:BD:C7:DA:D1:11:09:21:BE:C1:AF:49:FD:10:7B + X509v3 Key Usage: + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Authority Key Identifier: + keyid:95:B1:B4:F0:94:B6:BD:C7:DA:D1:11:09:21:BE:C1:AF:49:FD:10:7B + DirName:/C=SE/O=AddTrust AB/OU=AddTrust TTP Network/CN=AddTrust Class 1 CA Root + serial:01 + +SHA1 Fingerprint=CC:AB:0E:A0:4C:23:01:D6:69:7B:DD:37:9F:CD:12:EB:24:E3:94:9D +SHA256 Fingerprint=8C:72:09:27:9A:C0:4E:27:5E:16:D0:7F:D3:B7:75:E8:01:54:B5:96:80:46:E3:1F:52:DD:25:76:63:24:E9:A7 +-----BEGIN CERTIFICATE----- +MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 +b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw +MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD +VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul +CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n +tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl +dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch +PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC ++Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O +BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl +MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk +ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB +IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X +7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz +43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY +eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl +pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA +WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= +-----END CERTIFICATE----- +=== AddTrust External CA Root +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: May 30 10:48:38 2000 GMT + Not After : May 30 10:48:38 2020 GMT + Subject: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root + X509v3 extensions: + X509v3 Subject Key Identifier: + AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A + X509v3 Key Usage: + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Authority Key Identifier: + keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A + DirName:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root + serial:01 + +SHA1 Fingerprint=02:FA:F3:E2:91:43:54:68:60:78:57:69:4D:F5:E4:5B:68:85:18:68 +SHA256 Fingerprint=68:7F:A4:51:38:22:78:FF:F0:C8:B1:1F:8D:43:D5:76:67:1C:6E:B2:BC:EA:B4:13:FB:83:D9:65:D0:6D:2F:F2 +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs +IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 +MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h +bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt +H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 +uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX +mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX +a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN +E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 +WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD +VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 +Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU +cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx +IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN +AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH +YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC +Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX +c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a +mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE----- +=== AddTrust Public CA Root +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: May 30 10:41:50 2000 GMT + Not After : May 30 10:41:50 2020 GMT + Subject: C=SE, O=AddTrust AB, OU=AddTrust TTP Network, CN=AddTrust Public CA Root + X509v3 extensions: + X509v3 Subject Key Identifier: + 81:3E:37:D8:92:B0:1F:77:9F:5C:B4:AB:73:AA:E7:F6:34:60:2F:FA + X509v3 Key Usage: + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Authority Key Identifier: + keyid:81:3E:37:D8:92:B0:1F:77:9F:5C:B4:AB:73:AA:E7:F6:34:60:2F:FA + DirName:/C=SE/O=AddTrust AB/OU=AddTrust TTP Network/CN=AddTrust Public CA Root + serial:01 + +SHA1 Fingerprint=2A:B6:28:48:5E:78:FB:F3:AD:9E:79:10:DD:6B:DF:99:72:2C:96:E5 +SHA256 Fingerprint=07:91:CA:07:49:B2:07:82:AA:D3:C7:D7:BD:0C:DF:C9:48:58:35:84:3E:B2:D7:99:60:09:CE:43:AB:6C:69:27 +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 +b3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAx +MDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtB +ZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIDAeBgNV +BAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV +6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nX +GCwwfQ56HmIexkvA/X1id9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnP +dzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH +1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF +62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQW +BBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDEL +MAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU +cnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJv +b3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmuG7jD8WS6 +IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL+YPoRNWyQSW/ +iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao +GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh +4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQm +XiLsks3/QppEIW1cxeMiHV9HEufOX1362KqxMy3ZdvJOOjMMK7MtkAY= +-----END CERTIFICATE----- +=== AddTrust Qualified CA Root +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: May 30 10:44:50 2000 GMT + Not After : May 30 10:44:50 2020 GMT + Subject: C=SE, O=AddTrust AB, OU=AddTrust TTP Network, CN=AddTrust Qualified CA Root + X509v3 extensions: + X509v3 Subject Key Identifier: + 39:95:8B:62:8B:5C:C9:D4:80:BA:58:0F:97:3F:15:08:43:CC:98:A7 + X509v3 Key Usage: + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Authority Key Identifier: + keyid:39:95:8B:62:8B:5C:C9:D4:80:BA:58:0F:97:3F:15:08:43:CC:98:A7 + DirName:/C=SE/O=AddTrust AB/OU=AddTrust TTP Network/CN=AddTrust Qualified CA Root + serial:01 + +SHA1 Fingerprint=4D:23:78:EC:91:95:39:B5:00:7F:75:8F:03:3B:21:1E:C5:4D:8B:CF +SHA256 Fingerprint=80:95:21:08:05:DB:4B:BC:35:5E:44:28:D8:FD:6E:C2:CD:E3:AB:5F:B9:7A:99:42:98:8E:B8:F4:DC:D0:60:16 +-----BEGIN CERTIFICATE----- +MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 +b3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1 +MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYTAlNFMRQwEgYDVQQK +EwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIzAh +BgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwq +xBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G +87B4pfYOQnrjfxvM0PC3KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i +2O+tCBGaKZnhqkRFmhJePp1tUvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8U +WfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c1 +0cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0G +A1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6Fr +pGkwZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL +ExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlm +aWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2VhlRO6aQTv +hsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxGGuoYQ992zPlm +hpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X +dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3 +P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9Y +iQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5no +xqE= +-----END CERTIFICATE----- + +### Baltimore + +=== Baltimore CyberTrust Root +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 33554617 (0x20000b9) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: May 12 18:46:00 2000 GMT + Not After : May 12 23:59:00 2025 GMT + Subject: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root + X509v3 extensions: + X509v3 Subject Key Identifier: + E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0 + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:3 + X509v3 Key Usage: critical + Certificate Sign, CRL Sign +SHA1 Fingerprint=D4:DE:20:D0:5E:66:FC:53:FE:1A:50:88:2C:78:DB:28:52:CA:E4:74 +SHA256 Fingerprint=16:AF:57:A9:F6:76:B0:AB:12:60:95:AA:5E:BA:DE:F2:2A:B3:11:19:D6:44:AC:95:CD:4B:93:DB:F3:F2:6A:EB +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX +DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y +ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy +VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr +mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr +IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK +mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu +XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy +dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye +jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 +BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 +DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 +9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx +jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 +Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz +ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS +R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- + +### Certplus + +=== Class 2 Primary CA +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 85:bd:4b:f3:d8:da:e3:69:f6:94:d7:5f:c3:a5:44:23 + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Jul 7 17:05:00 1999 GMT + Not After : Jul 6 23:59:59 2019 GMT + Subject: C=FR, O=Certplus, CN=Class 2 Primary CA + X509v3 extensions: + X509v3 Basic Constraints: + CA:TRUE, pathlen:10 + X509v3 Key Usage: + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + E3:73:2D:DF:CB:0E:28:0C:DE:DD:B3:A4:CA:79:B8:8E:BB:E8:30:89 + Netscape Cert Type: + SSL CA, S/MIME CA + X509v3 CRL Distribution Points: + + Full Name: + URI:http://www.certplus.com/CRL/class2.crl + +SHA1 Fingerprint=74:20:74:41:72:9C:DD:92:EC:79:31:D8:23:10:8D:C2:81:92:E2:BB +SHA256 Fingerprint=0F:99:3C:8A:EF:97:BA:AF:56:87:14:0E:D5:9A:D1:82:1B:B4:AF:AC:F0:AA:9A:58:B5:D5:7A:33:8A:3A:FB:CB +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw +PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz +cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9 +MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz +IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ +ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR +VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL +kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd +EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas +H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0 +HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud +DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4 +QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu +Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/ +AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8 +yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR +FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA +ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB +kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 +l7+ijrRU +-----END CERTIFICATE----- + +### COMODO CA Limited + +=== COMODO Certification Authority +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 4e:81:2d:8a:82:65:e0:0b:02:ee:3e:35:02:46:e5:3d + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Dec 1 00:00:00 2006 GMT + Not After : Dec 31 23:59:59 2029 GMT + Subject: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO Certification Authority + X509v3 extensions: + X509v3 Subject Key Identifier: + 0B:58:E5:8B:C6:4C:15:37:A4:40:A9:30:A9:21:BE:47:36:5A:56:FF + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.comodoca.com/COMODOCertificationAuthority.crl + +SHA1 Fingerprint=66:31:BF:9E:F7:4F:9E:B6:C9:D5:A6:0C:BA:6A:BE:D1:F7:BD:EF:7B +SHA256 Fingerprint=0C:2C:D6:3D:F7:80:6F:A3:99:ED:E8:09:11:6B:57:5B:F8:79:89:F0:65:18:F9:80:8C:86:05:03:17:8B:AF:66 +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB +gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV +BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw +MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl +YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P +RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 +UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI +2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 +Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp ++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ +DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O +nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW +/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g +PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u +QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY +SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv +IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 +zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd +BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB +ZQ== +-----END CERTIFICATE----- +=== COMODO ECC Certification Authority +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 1f:47:af:aa:62:00:70:50:54:4c:01:9e:9b:63:99:2a + Signature Algorithm: ecdsa-with-SHA384 + Validity + Not Before: Mar 6 00:00:00 2008 GMT + Not After : Jan 18 23:59:59 2038 GMT + Subject: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO ECC Certification Authority + X509v3 extensions: + X509v3 Subject Key Identifier: + 75:71:A7:19:48:19:BC:9D:9D:EA:41:47:DF:94:C4:48:77:99:D3:79 + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE +SHA1 Fingerprint=9F:74:4E:9F:2B:4D:BA:EC:0F:31:2C:50:B6:56:3B:8E:2D:93:C3:11 +SHA256 Fingerprint=17:93:92:7A:06:14:54:97:89:AD:CE:2F:8F:34:F7:F0:B6:6D:0F:3A:E3:A3:B8:4D:21:EC:15:DB:BA:4F:AD:C7 +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- +=== COMODO RSA Certification Authority +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 4c:aa:f9:ca:db:63:6f:e0:1f:f7:4e:d8:5b:03:86:9d + Signature Algorithm: sha384WithRSAEncryption + Validity + Not Before: Jan 19 00:00:00 2010 GMT + Not After : Jan 18 23:59:59 2038 GMT + Subject: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO RSA Certification Authority + X509v3 extensions: + X509v3 Subject Key Identifier: + BB:AF:7E:02:3D:FA:A6:F1:3C:84:8E:AD:EE:38:98:EC:D9:32:32:D4 + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE +SHA1 Fingerprint=AF:E5:D2:44:A8:D1:19:42:30:FF:47:9F:E2:F8:97:BB:CD:7A:8C:B4 +SHA256 Fingerprint=52:F0:E1:C4:E5:8E:C6:29:29:1B:60:31:7F:07:46:71:B8:5D:7E:A8:0D:5B:07:27:34:63:53:4B:32:B4:02:34 +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR +6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X +pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC +9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV +/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf +Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z ++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w +qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah +SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC +u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf +Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq +crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl +wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM +4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV +2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna +FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ +CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK +boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke +jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL +S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb +QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl +0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB +NVOFBkpdn627G190 +-----END CERTIFICATE----- + +### Comodo CA Limited + +=== AAA Certificate Services +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Jan 1 00:00:00 2004 GMT + Not After : Dec 31 23:59:59 2028 GMT + Subject: C=GB, ST=Greater Manchester, L=Salford, O=Comodo CA Limited, CN=AAA Certificate Services + X509v3 extensions: + X509v3 Subject Key Identifier: + A0:11:0A:23:3E:96:F1:07:EC:E2:AF:29:EF:82:A5:7F:D0:30:A4:B4 + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.comodoca.com/AAACertificateServices.crl + + Full Name: + URI:http://crl.comodo.net/AAACertificateServices.crl + +SHA1 Fingerprint=D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49 +SHA256 Fingerprint=D7:A7:A0:FB:5D:7E:27:31:D7:71:E9:48:4E:BC:DE:F7:1D:5F:0C:3E:0A:29:48:78:2B:C8:3E:E0:EA:69:9E:F4 +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj +YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM +GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua +BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe +3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 +YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR +rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm +ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU +oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v +QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t +b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF +AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q +GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 +G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi +l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 +smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- +=== Secure Certificate Services +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Jan 1 00:00:00 2004 GMT + Not After : Dec 31 23:59:59 2028 GMT + Subject: C=GB, ST=Greater Manchester, L=Salford, O=Comodo CA Limited, CN=Secure Certificate Services + X509v3 extensions: + X509v3 Subject Key Identifier: + 3C:D8:93:88:C2:C0:82:09:CC:01:99:06:93:20:E9:9E:70:09:63:4F + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.comodoca.com/SecureCertificateServices.crl + + Full Name: + URI:http://crl.comodo.net/SecureCertificateServices.crl + +SHA1 Fingerprint=4A:65:D5:F4:1D:EF:39:B8:B8:90:4A:4A:D3:64:81:33:CF:C7:A1:D1 +SHA256 Fingerprint=BD:81:CE:3B:4F:65:91:D1:1A:67:B5:FC:7A:47:FD:EF:25:52:1B:F9:AA:4E:18:B9:E3:DF:2E:34:A7:80:3B:E8 +-----BEGIN CERTIFICATE----- +MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp +ZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow +fjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV +BAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM +cm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S +HpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996 +CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk +3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz +6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV +HQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud +EwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv +Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw +Oi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww +DQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0 +5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj +Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI +gKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ +aD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl +izeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk= +-----END CERTIFICATE----- +=== Trusted Certificate Services +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Jan 1 00:00:00 2004 GMT + Not After : Dec 31 23:59:59 2028 GMT + Subject: C=GB, ST=Greater Manchester, L=Salford, O=Comodo CA Limited, CN=Trusted Certificate Services + X509v3 extensions: + X509v3 Subject Key Identifier: + C5:7B:58:BD:ED:DA:25:69:D2:F7:59:16:A8:B3:32:C0:7B:27:5B:F4 + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.comodoca.com/TrustedCertificateServices.crl + + Full Name: + URI:http://crl.comodo.net/TrustedCertificateServices.crl + +SHA1 Fingerprint=E1:9F:E3:0E:8B:84:60:9E:80:9B:17:0D:72:A8:C5:BA:6E:14:09:BD +SHA256 Fingerprint=3F:06:E5:56:81:D4:96:F5:BE:16:9E:B5:38:9F:9F:2B:8F:F6:1E:17:08:DF:68:81:72:48:49:CD:5D:27:CB:69 +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0 +aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla +MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO +BgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD +VQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW +fnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt +TGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL +fhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW +1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7 +kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G +A1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v +ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo +dHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu +Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/ +HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 +pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS +jBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+ +xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn +dBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi +-----END CERTIFICATE----- + +### Deutsche Telekom AG + +=== Deutsche Telekom Root CA 2 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 38 (0x26) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Jul 9 12:11:00 1999 GMT + Not After : Jul 9 23:59:00 2019 GMT + Subject: C=DE, O=Deutsche Telekom AG, OU=T-TeleSec Trust Center, CN=Deutsche Telekom Root CA 2 + X509v3 extensions: + X509v3 Subject Key Identifier: + 31:C3:79:1B:BA:F5:53:D7:17:E0:89:7A:2D:17:6C:0A:B3:2B:9D:33 + X509v3 Basic Constraints: + CA:TRUE, pathlen:5 + X509v3 Key Usage: critical + Certificate Sign, CRL Sign +SHA1 Fingerprint=85:A4:08:C0:9C:19:3E:5D:51:58:7D:CD:D6:13:30:FD:8C:DE:37:BF +SHA256 Fingerprint=B6:19:1A:50:D0:C3:97:7F:7D:A9:9B:CD:AA:C8:6A:22:7D:AE:B9:67:9E:C7:0B:A3:B0:C9:D9:22:71:C1:70:D3 +-----BEGIN CERTIFICATE----- +MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc +MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj +IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB +IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE +RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl +U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290 +IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU +ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC +QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr +rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S +NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc +QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH +txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP +BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC +AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp +tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa +IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl +6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+ +xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU +Cm26OWMohpLzGITY+9HPBVZkVw== +-----END CERTIFICATE----- + +### DigiCert Inc + +=== DigiCert Assured ID Root CA +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 0c:e7:e0:e5:17:d8:46:fe:8f:e5:60:fc:1b:f0:30:39 + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Nov 10 00:00:00 2006 GMT + Not After : Nov 10 00:00:00 2031 GMT + Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root CA + X509v3 extensions: + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + 45:EB:A2:AF:F4:92:CB:82:31:2D:51:8B:A7:A7:21:9D:F3:6D:C8:0F + X509v3 Authority Key Identifier: + keyid:45:EB:A2:AF:F4:92:CB:82:31:2D:51:8B:A7:A7:21:9D:F3:6D:C8:0F + +SHA1 Fingerprint=05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43 +SHA256 Fingerprint=3E:90:99:B5:01:5E:8F:48:6C:00:BC:EA:9D:11:1E:E7:21:FA:BA:35:5A:89:BC:F1:DF:69:56:1E:3D:C6:32:5C +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c +JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP +mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ +wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 +VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ +AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB +AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun +pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC +dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf +fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm +NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx +H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- +=== DigiCert Assured ID Root G2 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 0b:93:1c:3a:d6:39:67:ea:67:23:bf:c3:af:9a:f4:4b + Signature Algorithm: sha256WithRSAEncryption + Validity + Not Before: Aug 1 12:00:00 2013 GMT + Not After : Jan 15 12:00:00 2038 GMT + Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root G2 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + CE:C3:4A:B9:99:55:F2:B8:DB:60:BF:A9:7E:BD:56:B5:97:36:A7:D6 +SHA1 Fingerprint=A1:4B:48:D9:43:EE:0A:0E:40:90:4F:3C:E0:A4:C0:91:93:51:5D:3F +SHA256 Fingerprint=7D:05:EB:B6:82:33:9F:8C:94:51:EE:09:4E:EB:FE:FA:79:53:A1:14:ED:B2:F4:49:49:45:2F:AB:7D:2F:C1:85 +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA +n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc +biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp +EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA +bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu +YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW +BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI +QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I +0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni +lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 +B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv +ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- +=== DigiCert Assured ID Root G3 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 0b:a1:5a:fa:1d:df:a0:b5:49:44:af:cd:24:a0:6c:ec + Signature Algorithm: ecdsa-with-SHA384 + Validity + Not Before: Aug 1 12:00:00 2013 GMT + Not After : Jan 15 12:00:00 2038 GMT + Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root G3 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + CB:D0:BD:A9:E1:98:05:51:A1:4D:37:A2:83:79:CE:8D:1D:2A:E4:84 +SHA1 Fingerprint=F5:17:A2:4F:9A:48:C6:C9:F8:A2:00:26:9F:DC:0F:48:2C:AB:30:89 +SHA256 Fingerprint=7E:37:CB:8B:4C:47:09:0C:AB:36:55:1B:A6:F4:5D:B8:40:68:0F:BA:16:6A:95:2D:B1:00:71:7F:43:05:3F:C2 +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg +RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf +Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q +RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD +AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY +JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv +6pZjamVFkpUBtA== +-----END CERTIFICATE----- +=== DigiCert Global Root CA +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 08:3b:e0:56:90:42:46:b1:a1:75:6a:c9:59:91:c7:4a + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Nov 10 00:00:00 2006 GMT + Not After : Nov 10 00:00:00 2031 GMT + Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA + X509v3 extensions: + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + 03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55 + X509v3 Authority Key Identifier: + keyid:03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55 + +SHA1 Fingerprint=A8:98:5D:3A:65:E5:E5:C4:B2:D7:D6:6D:40:C6:DD:2F:B1:9C:54:36 +SHA256 Fingerprint=43:48:A0:E9:44:4C:78:CB:26:5E:05:8D:5E:89:44:B4:D8:4F:96:62:BD:26:DB:25:7F:89:34:A4:43:C7:01:61 +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- +=== DigiCert Global Root G2 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 03:3a:f1:e6:a7:11:a9:a0:bb:28:64:b1:1d:09:fa:e5 + Signature Algorithm: sha256WithRSAEncryption + Validity + Not Before: Aug 1 12:00:00 2013 GMT + Not After : Jan 15 12:00:00 2038 GMT + Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G2 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 4E:22:54:20:18:95:E6:E3:6E:E6:0F:FA:FA:B9:12:ED:06:17:8F:39 +SHA1 Fingerprint=DF:3C:24:F9:BF:D6:66:76:1B:26:80:73:FE:06:D1:CC:8D:4F:82:A4 +SHA256 Fingerprint=CB:3C:CB:B7:60:31:E5:E0:13:8F:8D:D3:9A:23:F9:DE:47:FF:C3:5E:43:C1:14:4C:EA:27:D4:6A:5A:B1:CB:5F +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- +=== DigiCert Global Root G3 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 05:55:56:bc:f2:5e:a4:35:35:c3:a4:0f:d5:ab:45:72 + Signature Algorithm: ecdsa-with-SHA384 + Validity + Not Before: Aug 1 12:00:00 2013 GMT + Not After : Jan 15 12:00:00 2038 GMT + Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G3 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + B3:DB:48:A4:F9:A1:C5:D8:AE:36:41:CC:11:63:69:62:29:BC:4B:C6 +SHA1 Fingerprint=7E:04:DE:89:6A:3E:66:6D:00:E6:87:D3:3F:FA:D9:3B:E8:3D:34:9E +SHA256 Fingerprint=31:AD:66:48:F8:10:41:38:C7:38:F3:9E:A4:32:01:33:39:3E:3A:18:CC:02:29:6E:F9:7C:2A:C9:EF:67:31:D0 +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- +=== DigiCert High Assurance EV Root CA +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 02:ac:5c:26:6a:0b:40:9b:8f:0b:79:f2:ae:46:25:77 + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Nov 10 00:00:00 2006 GMT + Not After : Nov 10 00:00:00 2031 GMT + Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA + X509v3 extensions: + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3 + X509v3 Authority Key Identifier: + keyid:B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3 + +SHA1 Fingerprint=5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25 +SHA256 Fingerprint=74:31:E5:F4:C3:C1:CE:46:90:77:4F:0B:61:E0:54:40:88:3B:A9:A0:1E:D0:0B:A6:AB:D7:80:6E:D3:B1:18:CF +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- +=== DigiCert Trusted Root G4 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 05:9b:1b:57:9e:8e:21:32:e2:39:07:bd:a7:77:75:5c + Signature Algorithm: sha384WithRSAEncryption + Validity + Not Before: Aug 1 12:00:00 2013 GMT + Not After : Jan 15 12:00:00 2038 GMT + Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Trusted Root G4 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + EC:D7:E3:82:D2:71:5D:64:4C:DF:2E:67:3F:E7:BA:98:AE:1C:0F:4F +SHA1 Fingerprint=DD:FB:16:CD:49:31:C9:73:A2:03:7D:3F:C8:3A:4D:7D:77:5D:05:E4 +SHA256 Fingerprint=55:2F:7B:DC:F1:A7:AF:9E:6C:E6:72:01:7F:4F:12:AB:F7:72:40:C7:8E:76:1A:C2:03:D1:D9:D2:0A:C8:99:88 +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ +-----END CERTIFICATE----- + +### Digital Signature Trust Co. + +=== DST Root CA X3 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 44:af:b0:80:d6:a3:27:ba:89:30:39:86:2e:f8:40:6b + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Sep 30 21:12:19 2000 GMT + Not After : Sep 30 14:01:15 2021 GMT + Subject: O=Digital Signature Trust Co., CN=DST Root CA X3 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + C4:A7:B1:A4:7B:2C:71:FA:DB:E1:4B:90:75:FF:C4:15:60:85:89:10 +SHA1 Fingerprint=DA:C9:02:4F:54:D8:F6:DF:94:93:5F:B1:73:26:38:CA:6A:D7:7C:13 +SHA256 Fingerprint=06:87:26:03:31:A7:24:03:D9:09:F1:05:E6:9B:CF:0D:32:E1:BD:24:93:FF:C6:D9:20:6D:11:BC:D6:77:07:39 +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ +MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT +DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow +PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD +Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O +rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq +OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b +xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw +7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD +aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG +SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 +ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr +AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz +R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 +JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo +Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +-----END CERTIFICATE----- + +### Entrust, Inc. + +=== Entrust Root Certification Authority +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1164660820 (0x456b5054) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Nov 27 20:23:42 2006 GMT + Not After : Nov 27 20:53:42 2026 GMT + Subject: C=US, O=Entrust, Inc., OU=www.entrust.net/CPS is incorporated by reference, OU=(c) 2006 Entrust, Inc., CN=Entrust Root Certification Authority + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Private Key Usage Period: + Not Before: Nov 27 20:23:42 2006 GMT, Not After: Nov 27 20:53:42 2026 GMT + X509v3 Authority Key Identifier: + keyid:68:90:E4:67:A4:A6:53:80:C7:86:66:A4:F1:F7:4B:43:FB:84:BD:6D + + X509v3 Subject Key Identifier: + 68:90:E4:67:A4:A6:53:80:C7:86:66:A4:F1:F7:4B:43:FB:84:BD:6D + 1.2.840.113533.7.65.0: + 0...V7.1:4.0.... +SHA1 Fingerprint=B3:1E:B1:B7:40:E3:6C:84:02:DA:DC:37:D4:4D:F5:D4:67:49:52:F9 +SHA256 Fingerprint=73:C1:76:43:4F:1B:C6:D5:AD:F4:5B:0E:76:E7:27:28:7C:8D:E5:76:16:C1:E6:E6:14:1A:2B:2C:BC:7D:8E:4C +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 +Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW +KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw +NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw +NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy +ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV +BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo +Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 +4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 +KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI +rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi +94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB +sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi +gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo +kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE +vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t +O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua +AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP +9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ +eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m +0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- +=== Entrust Root Certification Authority - EC1 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + a6:8b:79:29:00:00:00:00:50:d0:91:f9 + Signature Algorithm: ecdsa-with-SHA384 + Validity + Not Before: Dec 18 15:25:36 2012 GMT + Not After : Dec 18 15:55:36 2037 GMT + Subject: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - EC1 + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + B7:63:E7:1A:DD:8D:E9:08:A6:55:83:A4:E0:6A:50:41:65:11:42:49 +SHA1 Fingerprint=20:D8:06:40:DF:9B:25:F5:12:25:3A:11:EA:F7:59:8A:EB:14:B5:47 +SHA256 Fingerprint=02:ED:0E:B2:8C:14:DA:45:16:5C:56:67:91:70:0D:64:51:D7:FB:56:F0:B2:AB:1D:3B:8E:B0:70:E5:6E:DF:F5 +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- +=== Entrust Root Certification Authority - G2 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1246989352 (0x4a538c28) + Signature Algorithm: sha256WithRSAEncryption + Validity + Not Before: Jul 7 17:25:54 2009 GMT + Not After : Dec 7 17:55:54 2030 GMT + Subject: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2009 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - G2 + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + 6A:72:26:7A:D0:1E:EF:7D:E7:3B:69:51:D4:6C:8D:9F:90:12:66:AB +SHA1 Fingerprint=8C:F4:27:FD:79:0C:3A:D1:66:06:8D:E8:1E:57:EF:BB:93:22:72:D4 +SHA256 Fingerprint=43:DF:57:74:B0:3E:7F:EF:5F:E4:0D:93:1A:7B:ED:F1:BB:2E:6B:42:73:8C:4E:6D:38:41:10:3D:3A:A7:F3:39 +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- + +### Entrust.net + +=== Entrust.net Certification Authority (2048) +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 946069240 (0x3863def8) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Dec 24 17:50:51 1999 GMT + Not After : Jul 24 14:15:12 2029 GMT + Subject: O=Entrust.net, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Certification Authority (2048) + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + 55:E4:81:D1:11:80:BE:D8:89:B9:08:A3:31:F9:A1:24:09:16:B9:70 +SHA1 Fingerprint=50:30:06:09:1D:97:D4:F5:AE:39:F7:CB:E7:92:7D:7D:65:2D:34:31 +SHA256 Fingerprint=6D:C4:71:72:E0:1C:BC:B0:BF:62:58:0D:89:5F:E2:B8:AC:9A:D4:F8:73:80:1E:0C:10:B9:C8:37:D2:1E:B1:77 +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 +MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH +4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub +j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo +U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b +u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ +bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er +fF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- +=== Entrust.net Secure Server Certification Authority +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 927650371 (0x374ad243) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: May 25 16:09:40 1999 GMT + Not After : May 25 16:39:40 2019 GMT + Subject: C=US, O=Entrust.net, OU=www.entrust.net/CPS incorp. by ref. (limits liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Secure Server Certification Authority + X509v3 extensions: + Netscape Cert Type: + SSL CA, S/MIME CA, Object Signing CA + X509v3 CRL Distribution Points: + + Full Name: + DirName: C = US, O = Entrust.net, OU = www.entrust.net/CPS incorp. by ref. (limits liab.), OU = (c) 1999 Entrust.net Limited, CN = Entrust.net Secure Server Certification Authority, CN = CRL1 + + Full Name: + URI:http://www.entrust.net/CRL/net1.crl + + X509v3 Private Key Usage Period: + Not Before: May 25 16:09:40 1999 GMT, Not After: May 25 16:09:40 2019 GMT + X509v3 Key Usage: + Certificate Sign, CRL Sign + X509v3 Authority Key Identifier: + keyid:F0:17:62:13:55:3D:B3:FF:0A:00:6B:FB:50:84:97:F3:ED:62:D0:1A + + X509v3 Subject Key Identifier: + F0:17:62:13:55:3D:B3:FF:0A:00:6B:FB:50:84:97:F3:ED:62:D0:1A + X509v3 Basic Constraints: + CA:TRUE + 1.2.840.113533.7.65.0: + 0 +..V4.0.... +SHA1 Fingerprint=99:A6:9B:E6:1A:FE:88:6B:4D:2B:82:00:7C:B8:54:FC:31:7E:15:39 +SHA256 Fingerprint=62:F2:40:27:8C:56:4C:4D:D8:BF:7D:9D:4F:6F:36:6E:A8:94:D2:2F:5F:34:D9:89:A9:83:AC:EC:2F:FF:ED:50 +-----BEGIN CERTIFICATE----- +MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC +VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u +ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc +KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u +ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1 +MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE +ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j +b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF +bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg +U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA +A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/ +I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3 +wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC +AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb +oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5 +BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p +dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk +MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp +b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu +dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0 +MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi +E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa +MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI +hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN +95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd +2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI= +-----END CERTIFICATE----- + +### Equifax + +=== Equifax Secure Certificate Authority +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 903804111 (0x35def4cf) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Aug 22 16:41:51 1998 GMT + Not After : Aug 22 16:41:51 2018 GMT + Subject: C=US, O=Equifax, OU=Equifax Secure Certificate Authority + X509v3 extensions: + X509v3 CRL Distribution Points: + + Full Name: + DirName: C = US, O = Equifax, OU = Equifax Secure Certificate Authority, CN = CRL1 + + X509v3 Private Key Usage Period: + Not After: Aug 22 16:41:51 2018 GMT + X509v3 Key Usage: + Certificate Sign, CRL Sign + X509v3 Authority Key Identifier: + keyid:48:E6:68:F9:2B:D2:B2:95:D7:47:D8:23:20:10:4F:33:98:90:9F:D4 + + X509v3 Subject Key Identifier: + 48:E6:68:F9:2B:D2:B2:95:D7:47:D8:23:20:10:4F:33:98:90:9F:D4 + X509v3 Basic Constraints: + CA:TRUE + 1.2.840.113533.7.65.0: + 0...V3.0c.... +SHA1 Fingerprint=D2:32:09:AD:23:D3:14:23:21:74:E4:0D:7F:9D:62:13:97:86:63:3A +SHA256 Fingerprint=08:29:7A:40:47:DB:A2:36:80:C7:31:DB:6E:31:76:53:CA:78:48:E1:BE:BD:3A:0B:01:79:A7:07:F9:2C:F1:78 +-----BEGIN CERTIFICATE----- +MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV +UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy +dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1 +MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx +dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f +BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A +cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC +AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm +aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw +ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj +IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF +MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA +A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y +7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh +1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4 +-----END CERTIFICATE----- + +### Equifax Secure Inc. + +=== Equifax Secure eBusiness CA-1 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 4 (0x4) + Signature Algorithm: md5WithRSAEncryption + Validity + Not Before: Jun 21 04:00:00 1999 GMT + Not After : Jun 21 04:00:00 2020 GMT + Subject: C=US, O=Equifax Secure Inc., CN=Equifax Secure eBusiness CA-1 + X509v3 extensions: + Netscape Cert Type: + SSL CA, S/MIME CA, Object Signing CA + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Authority Key Identifier: + keyid:4A:78:32:52:11:DB:59:16:36:5E:DF:C1:14:36:40:6A:47:7C:4C:A1 + + X509v3 Subject Key Identifier: + 4A:78:32:52:11:DB:59:16:36:5E:DF:C1:14:36:40:6A:47:7C:4C:A1 +SHA1 Fingerprint=DA:40:18:8B:91:89:A3:ED:EE:AE:DA:97:FE:2F:9D:F5:B7:D1:8A:41 +SHA256 Fingerprint=CF:56:FF:46:A4:A1:86:10:9D:D9:65:84:B5:EE:B5:8A:51:0C:42:75:B0:E5:F9:4F:40:BB:AE:86:5E:19:F6:73 +-----BEGIN CERTIFICATE----- +MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc +MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT +ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw +MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j +LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ +KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo +RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu +WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw +Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD +AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK +eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM +zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+ +WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN +/Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ== +-----END CERTIFICATE----- +=== Equifax Secure Global eBusiness CA-1 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: md5WithRSAEncryption + Validity + Not Before: Jun 21 04:00:00 1999 GMT + Not After : Jun 21 04:00:00 2020 GMT + Subject: C=US, O=Equifax Secure Inc., CN=Equifax Secure Global eBusiness CA-1 + X509v3 extensions: + Netscape Cert Type: + SSL CA, S/MIME CA, Object Signing CA + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Authority Key Identifier: + keyid:BE:A8:A0:74:72:50:6B:44:B7:C9:23:D8:FB:A8:FF:B3:57:6B:68:6C + + X509v3 Subject Key Identifier: + BE:A8:A0:74:72:50:6B:44:B7:C9:23:D8:FB:A8:FF:B3:57:6B:68:6C +SHA1 Fingerprint=7E:78:4A:10:1C:82:65:CC:2D:E1:F1:6D:47:B4:40:CA:D9:0A:19:45 +SHA256 Fingerprint=5F:0B:62:EA:B5:E3:53:EA:65:21:65:16:58:FB:B6:53:59:F4:43:28:0A:4A:FB:D1:04:D7:7D:10:F9:F0:4C:07 +-----BEGIN CERTIFICATE----- +MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc +MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT +ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw +MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj +dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l +c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC +UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc +58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/ +o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr +aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA +A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA +Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv +8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV +-----END CERTIFICATE----- + +### GeoTrust Inc. + +=== GeoTrust Global CA +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 144470 (0x23456) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: May 21 04:00:00 2002 GMT + Not After : May 21 04:00:00 2022 GMT + Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E + X509v3 Authority Key Identifier: + keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E + +SHA1 Fingerprint=DE:28:F4:A4:FF:E5:B9:2F:A3:C5:03:D1:A3:49:A7:F9:96:2A:82:12 +SHA256 Fingerprint=FF:85:6A:2D:25:1D:CD:88:D3:66:56:F4:50:12:67:98:CF:AB:AA:DE:40:79:9C:72:2D:E4:D2:B5:DB:36:A7:3A +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg +R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 +9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq +fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv +iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU +1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ +bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW +MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA +ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l +uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn +Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS +tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF +PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un +hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV +5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== +-----END CERTIFICATE----- +=== GeoTrust Global CA 2 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Mar 4 05:00:00 2004 GMT + Not After : Mar 4 05:00:00 2019 GMT + Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA 2 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + 71:38:36:F2:02:31:53:47:2B:6E:BA:65:46:A9:10:15:58:20:05:09 + X509v3 Authority Key Identifier: + keyid:71:38:36:F2:02:31:53:47:2B:6E:BA:65:46:A9:10:15:58:20:05:09 + + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign +SHA1 Fingerprint=A9:E9:78:08:14:37:58:88:F2:05:19:B0:6D:2B:0D:2B:60:16:90:7D +SHA256 Fingerprint=CA:2D:82:A0:86:77:07:2F:8A:B6:76:4F:F0:35:67:6C:FE:3E:5E:32:5E:01:21:72:DF:3F:92:09:6D:B7:9B:85 +-----BEGIN CERTIFICATE----- +MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFs +IENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg +R2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvPE1A +PRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/NTL8 +Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hL +TytCOb1kLUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL +5mkWRxHCJ1kDs6ZgwiFAVvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7 +S4wMcoKK+xfNAGw6EzywhIdLFnopsk/bHdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe +2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNHK266ZUap +EBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6td +EPx7srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv +/NgdRN3ggX+d6YvhZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywN +A0ZF66D0f0hExghAzN4bcLUprbqLOzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0 +abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkCx1YAzUm5s2x7UwQa4qjJqhIF +I8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqFH4z1Ir+rzoPz +4iIprn2DQKi6bA== +-----END CERTIFICATE----- +=== GeoTrust Primary Certification Authority +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 18:ac:b5:6a:fd:69:b6:15:3a:63:6c:af:da:fa:c4:a1 + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Nov 27 00:00:00 2006 GMT + Not After : Jul 16 23:59:59 2036 GMT + Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 2C:D5:50:41:97:15:8B:F0:8F:36:61:5B:4A:FB:6B:D9:99:C9:33:92 +SHA1 Fingerprint=32:3C:11:8E:1B:F7:B8:B6:52:54:E2:E2:10:0D:D6:02:90:37:F0:96 +SHA256 Fingerprint=37:D5:10:06:C5:12:EA:AB:62:64:21:F1:EC:8C:92:01:3F:C5:F8:2A:E9:8E:E5:33:EB:46:19:B8:DE:B4:D0:6C +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY +MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo +R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx +MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK +Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9 +AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA +ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0 +7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W +kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI +mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ +KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1 +6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl +4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K +oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj +UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU +AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= +-----END CERTIFICATE----- +=== GeoTrust Primary Certification Authority - G2 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 3c:b2:f4:48:0a:00:e2:fe:eb:24:3b:5e:60:3e:c3:6b + Signature Algorithm: ecdsa-with-SHA384 + Validity + Not Before: Nov 5 00:00:00 2007 GMT + Not After : Jan 18 23:59:59 2038 GMT + Subject: C=US, O=GeoTrust Inc., OU=(c) 2007 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G2 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 15:5F:35:57:51:55:FB:25:B2:AD:03:69:FC:01:A3:FA:BE:11:55:D5 +SHA1 Fingerprint=8D:17:84:D5:37:F3:03:7D:EC:70:FE:57:8B:51:9A:99:E6:10:D7:B0 +SHA256 Fingerprint=5E:DB:7A:C4:3B:82:A0:6A:87:61:E8:D7:BE:49:79:EB:F2:61:1F:7D:D7:9B:F9:1C:1C:6B:56:6A:21:9E:D7:66 +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL +MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj +KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 +MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw +NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV +BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH +MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL +So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal +tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG +CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT +qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz +rD6ogRLQy7rQkgu2npaqBA+K +-----END CERTIFICATE----- +=== GeoTrust Primary Certification Authority - G3 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 15:ac:6e:94:19:b2:79:4b:41:f6:27:a9:c3:18:0f:1f + Signature Algorithm: sha256WithRSAEncryption + Validity + Not Before: Apr 2 00:00:00 2008 GMT + Not After : Dec 1 23:59:59 2037 GMT + Subject: C=US, O=GeoTrust Inc., OU=(c) 2008 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G3 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + C4:79:CA:8E:A1:4E:03:1D:1C:DC:6B:DB:31:5B:94:3E:3F:30:7F:2D +SHA1 Fingerprint=03:9E:ED:B8:0B:E7:A0:3C:69:53:89:3B:20:D2:D9:32:3A:4C:2A:FD +SHA256 Fingerprint=B4:78:B8:12:25:0D:F8:78:63:5C:2A:A7:EC:7D:15:5E:AA:62:5E:E8:29:16:E2:CD:29:43:61:88:6C:D1:FB:D4 +-----BEGIN CERTIFICATE----- +MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB +mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT +MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ +BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg +MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0 +BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz ++uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm +hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn +5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W +JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL +DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC +huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw +HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB +AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB +zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN +kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD +AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH +SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G +spki4cErx5z481+oghLrGREt +-----END CERTIFICATE----- +=== GeoTrust Universal CA +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Mar 4 05:00:00 2004 GMT + Not After : Mar 4 05:00:00 2029 GMT + Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Universal CA + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + DA:BB:2E:AA:B0:0C:B8:88:26:51:74:5C:6D:03:D3:C0:D8:8F:7A:D6 + X509v3 Authority Key Identifier: + keyid:DA:BB:2E:AA:B0:0C:B8:88:26:51:74:5C:6D:03:D3:C0:D8:8F:7A:D6 + + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign +SHA1 Fingerprint=E6:21:F3:35:43:79:05:9A:4B:68:30:9D:8A:2F:74:22:15:87:EC:79 +SHA256 Fingerprint=A0:45:9B:9F:63:B2:25:59:F5:FA:5D:4C:6D:B3:F9:F7:2F:F1:93:42:03:35:78:F0:73:BF:1D:1B:46:CB:B9:12 +-----BEGIN CERTIFICATE----- +MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy +c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE +BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0 +IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV +VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8 +cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT +QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh +F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v +c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w +mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd +VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX +teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ +f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe +Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+ +nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB +/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY +MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG +9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc +aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX +IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn +ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z +uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN +Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja +QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW +koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9 +ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt +DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm +bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw= +-----END CERTIFICATE----- +=== GeoTrust Universal CA 2 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Mar 4 05:00:00 2004 GMT + Not After : Mar 4 05:00:00 2029 GMT + Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Universal CA 2 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + 76:F3:55:E1:FA:A4:36:FB:F0:9F:5C:62:71:ED:3C:F4:47:38:10:2B + X509v3 Authority Key Identifier: + keyid:76:F3:55:E1:FA:A4:36:FB:F0:9F:5C:62:71:ED:3C:F4:47:38:10:2B + + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign +SHA1 Fingerprint=37:9A:19:7B:41:85:45:35:0C:A6:03:69:F3:3C:2E:AF:47:4F:20:79 +SHA256 Fingerprint=A0:23:4F:3B:C8:52:7C:A5:62:8E:EC:81:AD:5D:69:89:5D:A5:68:0D:C9:1D:1C:B8:47:7F:33:F8:78:B9:5B:0B +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy +c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD +VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1 +c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81 +WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG +FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq +XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL +se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb +KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd +IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73 +y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt +hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc +QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4 +Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV +HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ +KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z +dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ +L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr +Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo +ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY +T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz +GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m +1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV +OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH +6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX +QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS +-----END CERTIFICATE----- + +### GlobalSign + +=== GlobalSign +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 04:00:00:00:00:01:21:58:53:08:a2 + Signature Algorithm: sha256WithRSAEncryption + Validity + Not Before: Mar 18 10:00:00 2009 GMT + Not After : Mar 18 10:00:00 2029 GMT + Subject: OU=GlobalSign Root CA - R3, O=GlobalSign, CN=GlobalSign + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + 8F:F0:4B:7F:A8:2E:45:24:AE:4D:50:FA:63:9A:8B:DE:E2:DD:1B:BC +SHA1 Fingerprint=D6:9B:56:11:48:F0:1C:77:C5:45:78:C1:09:26:DF:5B:85:69:76:AD +SHA256 Fingerprint=CB:B5:22:D7:B7:F1:27:AD:6A:01:13:86:5B:DF:1C:D4:10:2E:7D:07:59:AF:63:5A:7C:F4:72:0D:C9:63:C5:3B +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- + +### GlobalSign nv-sa + +=== GlobalSign Root CA +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 04:00:00:00:00:01:15:4b:5a:c3:94 + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Sep 1 12:00:00 1998 GMT + Not After : Jan 28 12:00:00 2028 GMT + Subject: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + 60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B +SHA1 Fingerprint=B1:BC:96:8B:D4:F4:9D:62:2A:A8:9A:81:F2:15:01:52:A4:1D:82:9C +SHA256 Fingerprint=EB:D4:10:40:E4:BB:3E:C7:42:C9:E3:81:D3:1E:F2:A4:1A:48:B6:68:5C:96:E7:CE:F3:C1:DF:6C:D4:33:1C:99 +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw +MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT +aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ +jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp +xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp +1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG +snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ +U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 +9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B +AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz +yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE +38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP +AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad +DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME +HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +### GoDaddy.com, Inc. + +=== Go Daddy Root Certificate Authority - G2 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 0 (0x0) + Signature Algorithm: sha256WithRSAEncryption + Validity + Not Before: Sep 1 00:00:00 2009 GMT + Not After : Dec 31 23:59:59 2037 GMT + Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE +SHA1 Fingerprint=47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B +SHA256 Fingerprint=45:14:0B:32:47:EB:9C:C8:C5:B4:F0:D7:B5:30:91:F7:32:92:08:9E:6E:5A:63:E2:74:9D:D3:AC:A9:19:8E:DA +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI +4uJEvlz36hz1 +-----END CERTIFICATE----- + +### GTE Corporation + +=== GTE CyberTrust Global Root +Certificate: + Data: + Version: 1 (0x0) + Serial Number: 421 (0x1a5) + Signature Algorithm: md5WithRSAEncryption + Validity + Not Before: Aug 13 00:29:00 1998 GMT + Not After : Aug 13 23:59:00 2018 GMT + Subject: C=US, O=GTE Corporation, OU=GTE CyberTrust Solutions, Inc., CN=GTE CyberTrust Global Root +SHA1 Fingerprint=97:81:79:50:D8:1C:96:70:CC:34:D8:09:CF:79:44:31:36:7E:F4:74 +SHA256 Fingerprint=A5:31:25:18:8D:21:10:AA:96:4B:02:C7:B7:C6:DA:32:03:17:08:94:E5:FB:71:FF:FB:66:67:D5:E6:81:0A:36 +-----BEGIN CERTIFICATE----- +MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYD +VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv +bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv +b3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEzMjM1OTAwWjB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrH +iM3dFw4usJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTS +r41tiGeA5u2ylc9yMcqlHHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X4 +04Wqk2kmhXBIgD8SFcd5tB8FLztimQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAG3r +GwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l9 +3PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0P +lZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ +-----END CERTIFICATE----- + +### NetLock Kft. + +=== NetLock Arany (Class Gold) F\U0151tan\FAs\EDtv\E1ny +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 80544274841616 (0x49412ce40010) + Signature Algorithm: sha256WithRSAEncryption + Validity + Not Before: Dec 11 15:08:21 2008 GMT + Not After : Dec 6 15:08:21 2028 GMT + Subject: C=HU, L=Budapest, O=NetLock Kft., OU=Tan\xC3\xBAs\xC3\xADtv\xC3\xA1nykiad\xC3\xB3k (Certification Services), CN=NetLock Arany (Class Gold) F\xC5\x91tan\xC3\xBAs\xC3\xADtv\xC3\xA1ny + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:4 + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + CC:FA:67:93:F0:B6:B8:D0:A5:C0:1E:F3:53:FD:8C:53:DF:83:D7:96 +SHA1 Fingerprint=06:08:3F:59:3F:15:A1:04:A0:69:A4:6B:A9:03:D0:06:B7:97:09:91 +SHA256 Fingerprint=6C:61:DA:C3:A2:DE:F0:31:50:6B:E0:36:D2:A6:FE:40:19:94:FB:D1:3D:F9:C8:D4:66:59:92:74:C4:46:EC:98 +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG +EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 +MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR +dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB +pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM +b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm +aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz +IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT +lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz +AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 +VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG +ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 +BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG +AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M +U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh +bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C ++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F +uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 +XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +### Network Solutions L.L.C. + +=== Network Solutions Certificate Authority +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 57:cb:33:6f:c2:5c:16:e6:47:16:17:e3:90:31:68:e0 + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Dec 1 00:00:00 2006 GMT + Not After : Dec 31 23:59:59 2029 GMT + Subject: C=US, O=Network Solutions L.L.C., CN=Network Solutions Certificate Authority + X509v3 extensions: + X509v3 Subject Key Identifier: + 21:30:C9:FB:00:D7:4E:98:DA:87:AA:2A:D0:A7:2E:B1:40:31:A7:4C + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.netsolssl.com/NetworkSolutionsCertificateAuthority.crl + +SHA1 Fingerprint=74:F8:A3:C3:EF:E7:B3:90:06:4B:83:90:3C:21:64:60:20:E5:DF:CE +SHA256 Fingerprint=15:F0:BA:00:A3:AC:7A:F3:AC:88:4C:07:2B:10:11:A0:77:BD:77:C0:97:F4:01:64:B2:F8:59:8A:BD:83:86:0C +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi +MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp +dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV +UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO +ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz +c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP +OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl +mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF +BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 +qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw +gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu +bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp +dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 +6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ +h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH +/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN +pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- + +### QuoVadis Limited + +=== QuoVadis Root CA 1 G3 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 78:58:5f:2e:ad:2c:19:4b:e3:37:07:35:34:13:28:b5:96:d4:65:93 + Signature Algorithm: sha256WithRSAEncryption + Validity + Not Before: Jan 12 17:27:44 2012 GMT + Not After : Jan 12 17:27:44 2042 GMT + Subject: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 1 G3 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + A3:97:D6:F3:5E:A2:10:E1:AB:45:9F:3C:17:64:3C:EE:01:70:9C:CC +SHA1 Fingerprint=1B:8E:EA:57:96:29:1A:C9:39:EA:B8:0A:81:1A:73:73:C0:93:79:67 +SHA256 Fingerprint=8A:86:6F:D1:B2:76:B5:7E:57:8E:92:1C:65:82:8A:2B:ED:58:E9:F2:F2:88:05:41:34:B7:F1:F4:BF:C9:CC:74 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 +MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV +wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe +rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 +68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh +4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp +UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o +abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc +3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G +KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt +hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO +Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt +zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD +ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 +cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN +qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 +YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv +b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 +8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k +NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj +ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp +q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt +nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD +-----END CERTIFICATE----- +=== QuoVadis Root CA 2 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1289 (0x509) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Nov 24 18:27:00 2006 GMT + Not After : Nov 24 18:23:33 2031 GMT + Subject: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 2 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 1A:84:62:BC:48:4C:33:25:04:D4:EE:D0:F6:03:C4:19:46:D1:94:6B + X509v3 Authority Key Identifier: + keyid:1A:84:62:BC:48:4C:33:25:04:D4:EE:D0:F6:03:C4:19:46:D1:94:6B + DirName:/C=BM/O=QuoVadis Limited/CN=QuoVadis Root CA 2 + serial:05:09 + +SHA1 Fingerprint=CA:3A:FB:CF:12:40:36:4B:44:B2:16:20:88:80:48:39:19:93:7C:F7 +SHA256 Fingerprint=85:A0:DD:7D:D7:20:AD:B7:FF:05:F8:3D:54:2B:20:9D:C7:FF:45:28:F7:D6:77:B1:83:89:FE:A5:E5:C4:9E:86 +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa +GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg +Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J +WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB +rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp ++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 +ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i +Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz +PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og +/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH +oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI +yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud +EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 +A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL +MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f +BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn +g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl +fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K +WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha +B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc +hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR +TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD +mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z +ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y +4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza +8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- +=== QuoVadis Root CA 2 G3 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 44:57:34:24:5b:81:89:9b:35:f2:ce:b8:2b:3b:5b:a7:26:f0:75:28 + Signature Algorithm: sha256WithRSAEncryption + Validity + Not Before: Jan 12 18:59:32 2012 GMT + Not After : Jan 12 18:59:32 2042 GMT + Subject: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 2 G3 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + ED:E7:6F:76:5A:BF:60:EC:49:5B:C6:A5:77:BB:72:16:71:9B:C4:3D +SHA1 Fingerprint=09:3C:61:F3:8B:8B:DC:7D:55:DF:75:38:02:05:00:E1:25:F5:C8:36 +SHA256 Fingerprint=8F:E4:FB:0A:F9:3A:4D:0D:67:DB:0B:EB:B2:3E:37:C7:1B:F3:25:DC:BC:DD:24:0E:A0:4D:AF:58:B4:7E:18:40 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 +MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf +qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW +n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym +c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ +O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 +o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j +IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq +IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz +8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh +vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l +7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG +cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD +ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC +roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga +W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n +lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE ++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV +csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd +dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg +KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM +HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 +WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M +-----END CERTIFICATE----- +=== QuoVadis Root CA 3 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1478 (0x5c6) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Nov 24 19:11:23 2006 GMT + Not After : Nov 24 19:06:44 2031 GMT + Subject: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 3 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Certificate Policies: + Policy: 1.3.6.1.4.1.8024.0.3 + User Notice: + Explicit Text: Any use of this Certificate constitutes acceptance of the QuoVadis Root CA 3 Certificate Policy / Certification Practice Statement. + CPS: http://www.quovadisglobal.com/cps + + X509v3 Key Usage: + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + F2:C0:13:E0:82:43:3E:FB:EE:2F:67:32:96:35:5C:DB:B8:CB:02:D0 + X509v3 Authority Key Identifier: + keyid:F2:C0:13:E0:82:43:3E:FB:EE:2F:67:32:96:35:5C:DB:B8:CB:02:D0 + DirName:/C=BM/O=QuoVadis Limited/CN=QuoVadis Root CA 3 + serial:05:C6 + +SHA1 Fingerprint=1F:49:14:F7:D8:74:95:1D:DD:AE:02:C0:BE:FD:3A:2D:82:75:51:85 +SHA256 Fingerprint=18:F1:FC:7F:20:5D:F8:AD:DD:EB:7F:E0:07:DD:57:E3:AF:37:5A:9C:4D:8D:73:54:6B:F4:F1:FE:D1:E1:8D:35 +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM +V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB +4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr +H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd +8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv +vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT +mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe +btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc +T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt +WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ +c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A +4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD +VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG +CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 +aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu +dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw +czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G +A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg +Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 +7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem +d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd ++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B +4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN +t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x +DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 +k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s +zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j +Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT +mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK +4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- +=== QuoVadis Root CA 3 G3 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 2e:f5:9b:02:28:a7:db:7a:ff:d5:a3:a9:ee:bd:03:a0:cf:12:6a:1d + Signature Algorithm: sha256WithRSAEncryption + Validity + Not Before: Jan 12 20:26:32 2012 GMT + Not After : Jan 12 20:26:32 2042 GMT + Subject: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 3 G3 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + C6:17:D0:BC:A8:EA:02:43:F2:1B:06:99:5D:2B:90:20:B9:D7:9C:E4 +SHA1 Fingerprint=48:12:BD:92:3C:A8:C4:39:06:E7:30:6D:27:96:E6:A4:CF:22:2E:7D +SHA256 Fingerprint=88:EF:81:DE:20:2E:B0:18:45:2E:43:F8:64:72:5C:EA:5F:BD:1F:C2:D9:D2:05:73:07:09:C5:D8:B8:69:0F:46 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 +MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR +/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu +FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR +U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c +ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR +FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k +A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw +eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl +sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp +VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q +A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ +ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD +ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI +FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv +oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg +u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP +0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf +3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl +8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ +DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN +PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ +ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- +=== QuoVadis Root Certification Authority +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 985026699 (0x3ab6508b) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Mar 19 18:33:33 2001 GMT + Not After : Mar 17 18:33:33 2021 GMT + Subject: C=BM, O=QuoVadis Limited, OU=Root Certification Authority, CN=QuoVadis Root Certification Authority + X509v3 extensions: + Authority Information Access: + OCSP - URI:https://ocsp.quovadisoffshore.com + + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Certificate Policies: + Policy: 1.3.6.1.4.1.8024.0.1 + User Notice: + Explicit Text: Reliance on the QuoVadis Root Certificate by any party assumes acceptance of the then applicable standard terms and conditions of use, certification practices, and the QuoVadis Certificate Policy. + CPS: http://www.quovadis.bm + + X509v3 Subject Key Identifier: + 8B:4B:6D:ED:D3:29:B9:06:19:EC:39:39:A9:F0:97:84:6A:CB:EF:DF + X509v3 Authority Key Identifier: + keyid:8B:4B:6D:ED:D3:29:B9:06:19:EC:39:39:A9:F0:97:84:6A:CB:EF:DF + DirName:/C=BM/O=QuoVadis Limited/OU=Root Certification Authority/CN=QuoVadis Root Certification Authority + serial:3A:B6:50:8B + + X509v3 Key Usage: critical + Certificate Sign, CRL Sign +SHA1 Fingerprint=DE:3F:40:BD:50:93:D3:9B:6C:60:F6:DA:BC:07:62:01:00:89:76:C9 +SHA256 Fingerprint=A4:5E:DE:3B:BB:F0:9C:8A:E1:5C:72:EF:C0:72:68:D6:93:A2:1C:99:6F:D5:1E:67:CA:07:94:60:FD:6D:88:73 +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz +MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw +IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR +dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp +li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D +rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ +WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug +F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU +xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC +Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv +dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw +ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl +IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh +c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy +ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI +KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T +KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq +y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p +dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD +VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL +MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk +fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8 +7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R +cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y +mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW +xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK +SnQ2+Q== +-----END CERTIFICATE----- + +### Starfield Technologies, Inc. + +=== Starfield Class 2 Certification Authority +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 0 (0x0) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Jun 29 17:39:16 2004 GMT + Not After : Jun 29 17:39:16 2034 GMT + Subject: C=US, O=Starfield Technologies, Inc., OU=Starfield Class 2 Certification Authority + X509v3 extensions: + X509v3 Subject Key Identifier: + BF:5F:B7:D1:CE:DD:1F:86:F4:5B:55:AC:DC:D7:10:C2:0E:A9:88:E7 + X509v3 Authority Key Identifier: + keyid:BF:5F:B7:D1:CE:DD:1F:86:F4:5B:55:AC:DC:D7:10:C2:0E:A9:88:E7 + DirName:/C=US/O=Starfield Technologies, Inc./OU=Starfield Class 2 Certification Authority + serial:00 + + X509v3 Basic Constraints: + CA:TRUE +SHA1 Fingerprint=AD:7E:1C:28:B0:64:EF:8F:60:03:40:20:14:C3:D0:E3:37:0E:B5:8A +SHA256 Fingerprint=14:65:FA:20:53:97:B8:76:FA:A6:F0:A9:95:8E:55:90:E4:0F:CC:7F:AA:4F:B7:C2:C8:67:75:21:FB:5F:B6:58 +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl +MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp +U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw +NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp +ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 +DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf +8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN ++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 +X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa +K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA +1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G +A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR +zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 +YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD +bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 +L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D +eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp +VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY +WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- +=== Starfield Root Certificate Authority - G2 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 0 (0x0) + Signature Algorithm: sha256WithRSAEncryption + Validity + Not Before: Sep 1 00:00:00 2009 GMT + Not After : Dec 31 23:59:59 2037 GMT + Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Root Certificate Authority - G2 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 7C:0C:32:1F:A7:D9:30:7F:C4:7D:68:A3:62:A8:A1:CE:AB:07:5B:27 +SHA1 Fingerprint=B5:1C:06:7C:EE:2B:0C:3D:F8:55:AB:2D:92:F4:FE:39:D4:E7:0F:0E +SHA256 Fingerprint=2C:E1:CB:0B:F9:D2:F9:E1:02:99:3F:BE:21:51:52:C3:B2:DD:0C:AB:DE:1C:68:E5:31:9B:83:91:54:DB:B7:F5 +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw +MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj +aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp +Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg +nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 +HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N +Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN +dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 +HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G +CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU +sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 +4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg +8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 +mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- +=== Starfield Services Root Certificate Authority - G2 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 0 (0x0) + Signature Algorithm: sha256WithRSAEncryption + Validity + Not Before: Sep 1 00:00:00 2009 GMT + Not After : Dec 31 23:59:59 2037 GMT + Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Services Root Certificate Authority - G2 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 9C:5F:00:DF:AA:01:D7:30:2B:38:88:A2:B8:6D:4A:9C:F2:11:91:83 +SHA1 Fingerprint=92:5A:8F:8D:2C:6D:04:E0:66:5F:59:6A:FF:22:D8:63:E8:25:6F:3F +SHA256 Fingerprint=56:8D:69:05:A2:C8:87:08:A4:B3:02:51:90:ED:CF:ED:B1:97:4A:60:6A:13:C6:E5:29:0F:CB:2A:E6:3E:DA:B5 +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN +sSi6 +-----END CERTIFICATE----- + +### StartCom Ltd. + +=== StartCom Certification Authority +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 45 (0x2d) + Signature Algorithm: sha256WithRSAEncryption + Validity + Not Before: Sep 17 19:46:37 2006 GMT + Not After : Sep 17 19:46:36 2036 GMT + Subject: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Certification Authority + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 4E:0B:EF:1A:A4:40:5B:A5:17:69:87:30:CA:34:68:43:D0:41:AE:F2 + X509v3 Authority Key Identifier: + keyid:4E:0B:EF:1A:A4:40:5B:A5:17:69:87:30:CA:34:68:43:D0:41:AE:F2 + + X509v3 Certificate Policies: + Policy: 1.3.6.1.4.1.23223.1.1.1 + CPS: http://www.startssl.com/policy.pdf + CPS: http://www.startssl.com/intermediate.pdf + User Notice: + Organization: Start Commercial (StartCom) Ltd. + Number: 1 + Explicit Text: Limited Liability, read the section *Legal Limitations* of the StartCom Certification Authority Policy available at http://www.startssl.com/policy.pdf + + Netscape Cert Type: + SSL CA, S/MIME CA, Object Signing CA + Netscape Comment: + StartCom Free SSL Certification Authority +SHA1 Fingerprint=A3:F1:33:3F:E2:42:BF:CF:C5:D1:4E:8F:39:42:98:40:68:10:D1:A0 +SHA256 Fingerprint=E1:78:90:EE:09:A3:FB:F4:F4:8B:9C:41:4A:17:D6:37:B7:A5:06:47:E9:BC:75:23:22:72:7F:CC:17:42:A9:11 +-----BEGIN CERTIFICATE----- +MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW +MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg +Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9 +MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi +U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh +cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk +pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf +OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C +Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT +Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi +HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM +Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w ++2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ +Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 +Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B +26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID +AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul +F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC +ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w +ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk +aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0 +YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg +c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93 +d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG +CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF +wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS +Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst +0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc +pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl +CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF +P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK +1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm +KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE +JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ +8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm +fyWl8kgAwKQB2j8= +-----END CERTIFICATE----- +=== StartCom Certification Authority G2 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 59 (0x3b) + Signature Algorithm: sha256WithRSAEncryption + Validity + Not Before: Jan 1 01:00:01 2010 GMT + Not After : Dec 31 23:59:01 2039 GMT + Subject: C=IL, O=StartCom Ltd., CN=StartCom Certification Authority G2 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 4B:C5:B4:40:6B:AD:1C:B3:A5:1C:65:6E:46:36:89:87:05:0C:0E:B6 +SHA1 Fingerprint=31:F1:FD:68:22:63:20:EE:C6:3B:3F:9D:EA:4A:3E:53:7C:7C:39:17 +SHA256 Fingerprint=C7:BA:65:67:DE:93:A7:98:AE:1F:AA:79:1E:71:2D:37:8F:AE:1F:93:C4:39:7F:EA:44:1B:B7:CB:E6:FD:59:95 +-----BEGIN CERTIFICATE----- +MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW +MBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1 +OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG +A1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ +JZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD +vfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo +D/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/ +Q0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW +RST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK +HDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN +nw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM +0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i +UUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9 +Ha90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg +TuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL +BQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K +2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX +UfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl +6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK +9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ +HgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI +wpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY +XzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l +IxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo +hdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr +so8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI +-----END CERTIFICATE----- + +### SwissSign AG + +=== SwissSign Gold CA - G2 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 13492815561806991280 (0xbb401c43f55e4fb0) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Oct 25 08:30:35 2006 GMT + Not After : Oct 25 08:30:35 2036 GMT + Subject: C=CH, O=SwissSign AG, CN=SwissSign Gold CA - G2 + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + 5B:25:7B:96:A4:65:51:7E:B8:39:F3:C0:78:66:5E:E8:3A:E7:F0:EE + X509v3 Authority Key Identifier: + keyid:5B:25:7B:96:A4:65:51:7E:B8:39:F3:C0:78:66:5E:E8:3A:E7:F0:EE + + X509v3 Certificate Policies: + Policy: 2.16.756.1.89.1.2.1.1 + CPS: http://repository.swisssign.com/ + +SHA1 Fingerprint=D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61 +SHA256 Fingerprint=62:DD:0B:E9:B9:F5:0A:16:3E:A0:F8:E7:5C:05:3B:1E:CA:57:EA:55:C8:68:8F:64:7C:68:81:F2:C8:35:7B:95 +-----BEGIN CERTIFICATE----- +MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV +BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln +biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF +MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT +d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8 +76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+ +bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c +6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE +emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd +MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt +MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y +MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y +FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi +aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM +gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB +qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7 +lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn +8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov +L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6 +45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO +UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5 +O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC +bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv +GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a +77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC +hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3 +92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp +Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w +ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt +Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ +-----END CERTIFICATE----- +=== SwissSign Platinum CA - G2 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 5670595323396054351 (0x4eb200670c035d4f) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Oct 25 08:36:00 2006 GMT + Not After : Oct 25 08:36:00 2036 GMT + Subject: C=CH, O=SwissSign AG, CN=SwissSign Platinum CA - G2 + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + 50:AF:CC:07:87:15:47:6F:38:C5:B4:65:D1:DE:95:AA:E9:DF:9C:CC + X509v3 Authority Key Identifier: + keyid:50:AF:CC:07:87:15:47:6F:38:C5:B4:65:D1:DE:95:AA:E9:DF:9C:CC + + X509v3 Certificate Policies: + Policy: 2.16.756.1.89.1.1.1.1 + CPS: http://repository.swisssign.com/ + +SHA1 Fingerprint=56:E0:FA:C0:3B:8F:18:23:55:18:E5:D3:11:CA:E8:C2:43:31:AB:66 +SHA256 Fingerprint=3B:22:2E:56:67:11:E9:92:30:0D:C0:B1:5A:B9:47:3D:AF:DE:F8:C8:4D:0C:EF:7D:33:17:B4:C1:82:1D:14:36 +-----BEGIN CERTIFICATE----- +MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE +BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWdu +IFBsYXRpbnVtIENBIC0gRzIwHhcNMDYxMDI1MDgzNjAwWhcNMzYxMDI1MDgzNjAw +WjBJMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMSMwIQYDVQQD +ExpTd2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAMrfogLi2vj8Bxax3mCq3pZcZB/HL37PZ/pEQtZ2Y5Wu669y +IIpFR4ZieIbWIDkm9K6j/SPnpZy1IiEZtzeTIsBQnIJ71NUERFzLtMKfkr4k2Htn +IuJpX+UFeNSH2XFwMyVTtIc7KZAoNppVRDBopIOXfw0enHb/FZ1glwCNioUD7IC+ +6ixuEFGSzH7VozPY1kneWCqv9hbrS3uQMpe5up1Y8fhXSQQeol0GcN1x2/ndi5ob +jM89o03Oy3z2u5yg+gnOI2Ky6Q0f4nIoj5+saCB9bzuohTEJfwvH6GXp43gOCWcw +izSC+13gzJ2BbWLuCB4ELE6b7P6pT1/9aXjvCR+htL/68++QHkwFix7qepF6w9fl ++zC8bBsQWJj3Gl/QKTIDE0ZNYWqFTFJ0LwYfexHihJfGmfNtf9dng34TaNhxKFrY +zt3oEBSa/m0jh26OWnA81Y0JAKeqvLAxN23IhBQeW71FYyBrS3SMvds6DsHPWhaP +pZjydomyExI7C3d3rLvlPClKknLKYRorXkzig3R3+jVIeoVNjZpTxN94ypeRSCtF +KwH3HBqi7Ri6Cr2D+m+8jVeTO9TUps4e8aCxzqv9KyiaTxvXw3LbpMS/XUz13XuW +ae5ogObnmLo2t/5u7Su9IPhlGdpVCX4l3P5hYnL5fhgC72O00Puv5TtjjGePAgMB +AAGjgawwgakwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFFCvzAeHFUdvOMW0ZdHelarp35zMMB8GA1UdIwQYMBaAFFCvzAeHFUdvOMW0 +ZdHelarp35zMMEYGA1UdIAQ/MD0wOwYJYIV0AVkBAQEBMC4wLAYIKwYBBQUHAgEW +IGh0dHA6Ly9yZXBvc2l0b3J5LnN3aXNzc2lnbi5jb20vMA0GCSqGSIb3DQEBBQUA +A4ICAQAIhab1Fgz8RBrBY+D5VUYI/HAcQiiWjrfFwUF1TglxeeVtlspLpYhg0DB0 +uMoI3LQwnkAHFmtllXcBrqS3NQuB2nEVqXQXOHtYyvkv+8Bldo1bAbl93oI9ZLi+ +FHSjClTTLJUYFzX1UWs/j6KWYTl4a0vlpqD4U99REJNi54Av4tHgvI42Rncz7Lj7 +jposiU0xEQ8mngS7twSNC/K5/FqdOxa3L8iYq/6KUFkuozv8KV2LwUvJ4ooTHbG/ +u0IdUt1O2BReEMYxB+9xJ/cbOQncguqLs5WGXv312l0xpuAxtpTmREl0xRbl9x8D +YSjFyMsSoEJL+WuICI20MhjzdZ/EfwBPBZWcoxcCw7NTm6ogOSkrZvqdr16zktK1 +puEa+S1BaYEUtLS17Yk9zvupnTVCRLEcFHOBzyoBNZox1S2PbYTfgE1X4z/FhHXa +icYwu+uPyyIIoK6q8QNsOktNCaUOcsZWayFCTiMlFGiudgp8DAdwZPmaL/YFOSbG +DI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSYMdp08YSTcU1f+2BY0fvEwW2JorsgH51x +kcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAciIfNAChs0B0QTwoRqjt8Z +Wr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g== +-----END CERTIFICATE----- +=== SwissSign Silver CA - G2 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 5700383053117599563 (0x4f1bd42f54bb2f4b) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Oct 25 08:32:46 2006 GMT + Not After : Oct 25 08:32:46 2036 GMT + Subject: C=CH, O=SwissSign AG, CN=SwissSign Silver CA - G2 + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + 17:A0:CD:C1:E4:41:B6:3A:5B:3B:CB:45:9D:BD:1C:C2:98:FA:86:58 + X509v3 Authority Key Identifier: + keyid:17:A0:CD:C1:E4:41:B6:3A:5B:3B:CB:45:9D:BD:1C:C2:98:FA:86:58 + + X509v3 Certificate Policies: + Policy: 2.16.756.1.89.1.3.1.1 + CPS: http://repository.swisssign.com/ + +SHA1 Fingerprint=9B:AA:E5:9F:56:EE:21:CB:43:5A:BE:25:93:DF:A7:F0:40:D1:1D:CB +SHA256 Fingerprint=BE:6C:4D:A2:BB:B9:BA:59:B6:F3:93:97:68:37:42:46:C3:C0:05:99:3F:A9:8F:02:0D:1D:ED:BE:D4:8A:81:D5 +-----BEGIN CERTIFICATE----- +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE +BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu +IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow +RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY +U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv +Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br +YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF +nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH +6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt +eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/ +c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ +MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH +HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf +jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6 +5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB +rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c +wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB +AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp +WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9 +xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ +2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ +IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8 +aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X +em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR +dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/ +OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ +hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy +tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u +-----END CERTIFICATE----- + +### T-Systems Enterprise Services GmbH + +=== T-TeleSec GlobalRoot Class 2 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Validity + Not Before: Oct 1 10:40:14 2008 GMT + Not After : Oct 1 23:59:59 2033 GMT + Subject: C=DE, O=T-Systems Enterprise Services GmbH, OU=T-Systems Trust Center, CN=T-TeleSec GlobalRoot Class 2 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + BF:59:20:36:00:79:A0:A0:22:6B:8C:D5:F2:61:D2:B8:2C:CB:82:4A +SHA1 Fingerprint=59:0D:2D:7D:88:4F:40:2E:61:7E:A5:62:32:17:65:CF:17:D8:94:E9 +SHA256 Fingerprint=91:E2:F5:78:8D:58:10:EB:A7:BA:58:73:7D:E1:54:8A:8E:CA:CD:01:45:98:BC:0B:14:3E:04:1B:17:05:25:52 +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd +AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC +FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi +1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq +jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ +wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ +WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy +NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC +uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw +IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 +g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP +BSeOE6Fuwg== +-----END CERTIFICATE----- +=== T-TeleSec GlobalRoot Class 3 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Validity + Not Before: Oct 1 10:29:56 2008 GMT + Not After : Oct 1 23:59:59 2033 GMT + Subject: C=DE, O=T-Systems Enterprise Services GmbH, OU=T-Systems Trust Center, CN=T-TeleSec GlobalRoot Class 3 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + B5:03:F7:76:3B:61:82:6A:12:AA:18:53:EB:03:21:94:BF:FE:CE:CA +SHA1 Fingerprint=55:A6:72:3E:CB:F2:EC:CD:C3:23:74:70:19:9D:2A:BE:11:E3:81:D1 +SHA256 Fingerprint=FD:73:DA:D3:1C:64:4F:F1:B4:3B:EF:0C:CD:DA:96:71:0B:9C:D9:87:5E:CA:7E:31:70:7A:F3:E9:6D:52:2B:BD +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN +8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ +RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 +hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 +ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM +EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 +A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy +WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ +1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 +6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT +91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p +TpPDpFQUWw== +-----END CERTIFICATE----- + +### Thawte Consulting cc + +=== Thawte Premium Server CA +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: md5WithRSAEncryption + Validity + Not Before: Aug 1 00:00:00 1996 GMT + Not After : Dec 31 23:59:59 2020 GMT + Subject: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE +SHA1 Fingerprint=62:7F:8D:78:27:65:63:99:D2:7D:7F:90:44:C9:FE:B3:F3:3E:FA:9A +SHA256 Fingerprint=AB:70:36:36:5C:71:54:AA:29:C2:C2:9F:5D:41:91:16:3B:16:2A:22:25:01:13:57:D5:6D:07:FF:A7:BC:1F:72 +-----BEGIN CERTIFICATE----- +MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx +FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD +VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy +dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t +MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB +MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG +A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp +b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl +cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv +bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE +VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ +ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR +uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG +9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI +hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM +pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg== +-----END CERTIFICATE----- +=== Thawte Server CA +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: md5WithRSAEncryption + Validity + Not Before: Aug 1 00:00:00 1996 GMT + Not After : Dec 31 23:59:59 2020 GMT + Subject: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Server CA/emailAddress=server-certs@thawte.com + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE +SHA1 Fingerprint=23:E5:94:94:51:95:F2:41:48:03:B4:D5:64:D2:A3:A3:F5:D8:8B:8C +SHA256 Fingerprint=B4:41:0B:73:E2:E6:EA:CA:47:FB:C4:2F:8F:A4:01:8A:F4:38:1D:C5:4C:FA:A8:44:50:46:1E:ED:09:45:4D:E9 +-----BEGIN CERTIFICATE----- +MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkEx +FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD +VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEm +MCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wHhcNOTYwODAx +MDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT +DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3 +dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNl +cyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3 +DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD +gY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91 +yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCX +L+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGj +EzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG +7oWDTSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e +QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZ +qdq5snUb9kLy78fyGPmJvKP/iiMucEc= +-----END CERTIFICATE----- + +### thawte, Inc. + +=== thawte Primary Root CA +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 34:4e:d5:57:20:d5:ed:ec:49:f4:2f:ce:37:db:2b:6d + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Nov 17 00:00:00 2006 GMT + Not After : Jul 16 23:59:59 2036 GMT + Subject: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50 +SHA1 Fingerprint=91:C6:D6:EE:3E:8A:C8:63:84:E5:48:C2:99:29:5C:75:6C:81:7B:81 +SHA256 Fingerprint=8D:72:2F:81:A9:C1:13:C0:79:1D:F1:36:A2:96:6D:B2:6C:95:0A:97:1D:B4:6B:41:99:F4:EA:54:B7:8B:FB:9F +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB +qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV +BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw +NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j +LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG +A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs +W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta +3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk +6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 +Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J +NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP +r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU +DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz +YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 +/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ +LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 +jVaMaA== +-----END CERTIFICATE----- +=== thawte Primary Root CA - G2 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 35:fc:26:5c:d9:84:4f:c9:3d:26:3d:57:9b:ae:d7:56 + Signature Algorithm: ecdsa-with-SHA384 + Validity + Not Before: Nov 5 00:00:00 2007 GMT + Not After : Jan 18 23:59:59 2038 GMT + Subject: C=US, O=thawte, Inc., OU=(c) 2007 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G2 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 9A:D8:00:30:00:E7:6B:7F:85:18:EE:8B:B6:CE:8A:0C:F8:11:E1:BB +SHA1 Fingerprint=AA:DB:BC:22:23:8F:C4:01:A1:27:BB:38:DD:F4:1D:DB:08:9E:F0:12 +SHA256 Fingerprint=A4:31:0D:50:AF:18:A6:44:71:90:37:2A:86:AF:AF:8B:95:1F:FB:43:1D:83:7F:1E:56:88:B4:59:71:ED:15:57 +-----BEGIN CERTIFICATE----- +MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp +IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi +BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw +MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh +d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig +YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v +dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/ +BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6 +papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K +DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3 +KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox +XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== +-----END CERTIFICATE----- +=== thawte Primary Root CA - G3 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 60:01:97:b7:46:a7:ea:b4:b4:9a:d6:4b:2f:f7:90:fb + Signature Algorithm: sha256WithRSAEncryption + Validity + Not Before: Apr 2 00:00:00 2008 GMT + Not After : Dec 1 23:59:59 2037 GMT + Subject: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2008 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G3 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + AD:6C:AA:94:60:9C:ED:E4:FF:FA:3E:0A:74:2B:63:03:F7:B6:59:BF +SHA1 Fingerprint=F1:8B:53:8D:1B:E9:03:B6:A6:F0:56:43:5B:17:15:89:CA:F3:6B:F2 +SHA256 Fingerprint=4B:03:F4:58:07:AD:70:F2:1B:FC:2C:AE:71:C9:FD:E4:60:4C:06:4C:F5:FF:B6:86:BA:E5:DB:AA:D7:FD:D3:4C +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB +rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV +BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa +Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl +LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u +MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl +ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm +gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8 +YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf +b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9 +9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S +zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk +OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV +HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA +2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW +oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu +t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c +KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM +m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu +MdRAGmI0Nj81Aa6sY6A= +-----END CERTIFICATE----- + +### The Go Daddy Group, Inc. + +=== Go Daddy Class 2 Certification Authority +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 0 (0x0) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Jun 29 17:06:20 2004 GMT + Not After : Jun 29 17:06:20 2034 GMT + Subject: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority + X509v3 extensions: + X509v3 Subject Key Identifier: + D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3 + X509v3 Authority Key Identifier: + keyid:D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3 + DirName:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority + serial:00 + + X509v3 Basic Constraints: + CA:TRUE +SHA1 Fingerprint=27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4 +SHA256 Fingerprint=C3:84:6B:F2:4B:9E:93:CA:64:27:4C:0E:C6:7C:1E:CC:5E:02:4F:FC:AC:D2:D7:40:19:35:0E:81:FE:54:6A:E4 +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh +MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE +YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 +MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo +ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg +MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN +ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA +PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w +wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi +EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY +avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ +YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE +sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h +/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 +IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy +OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P +TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER +dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf +ReYNnyicsbkqWletNw+vHX/bvZ8= +-----END CERTIFICATE----- + +### The USERTRUST Network + +=== USERTrust ECC Certification Authority +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 5c:8b:99:c5:5a:94:c5:d2:71:56:de:cd:89:80:cc:26 + Signature Algorithm: ecdsa-with-SHA384 + Validity + Not Before: Feb 1 00:00:00 2010 GMT + Not After : Jan 18 23:59:59 2038 GMT + Subject: C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust ECC Certification Authority + X509v3 extensions: + X509v3 Subject Key Identifier: + 3A:E1:09:86:D4:CF:19:C2:96:76:74:49:76:DC:E0:35:C6:63:63:9A + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE +SHA1 Fingerprint=D1:CB:CA:5D:B2:D5:2A:7F:69:3B:67:4D:E5:F0:5A:1D:0C:95:7D:F0 +SHA256 Fingerprint=4F:F4:60:D5:4B:9C:86:DA:BF:BC:FC:57:12:E0:40:0D:2B:ED:3F:BC:4D:4F:BD:AA:86:E0:6A:DC:D2:A9:AD:7A +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- +=== USERTrust RSA Certification Authority +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 01:fd:6d:30:fc:a3:ca:51:a8:1b:bc:64:0e:35:03:2d + Signature Algorithm: sha384WithRSAEncryption + Validity + Not Before: Feb 1 00:00:00 2010 GMT + Not After : Jan 18 23:59:59 2038 GMT + Subject: C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust RSA Certification Authority + X509v3 extensions: + X509v3 Subject Key Identifier: + 53:79:BF:5A:AA:2B:4A:CF:54:80:E1:D8:9B:C0:9D:F2:B2:03:66:CB + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE +SHA1 Fingerprint=2B:8F:1B:57:33:0D:BB:A2:D0:7A:6C:51:F7:0E:E9:0D:DA:B9:AD:8E +SHA256 Fingerprint=E7:93:C9:B0:2F:D8:AA:13:E2:1C:31:22:8A:CC:B0:81:19:64:3B:74:9C:89:89:64:B1:74:6D:46:C3:D4:CB:D2 +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG +jjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- +=== UTN-USERFirst-Hardware +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 44:be:0c:8b:50:00:24:b4:11:d3:36:2a:fe:65:0a:fd + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Jul 9 18:10:42 1999 GMT + Not After : Jul 9 18:19:22 2019 GMT + Subject: C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network, OU=http://www.usertrust.com, CN=UTN-USERFirst-Hardware + X509v3 extensions: + X509v3 Key Usage: + Digital Signature, Non Repudiation, Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + A1:72:5F:26:1B:28:98:43:95:5D:07:37:D5:85:96:9D:4B:D2:C3:45 + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.usertrust.com/UTN-USERFirst-Hardware.crl + + X509v3 Extended Key Usage: + TLS Web Server Authentication, IPSec End System, IPSec Tunnel, IPSec User +SHA1 Fingerprint=04:83:ED:33:99:AC:36:08:05:87:22:ED:BC:5E:46:00:E3:BE:F9:D7 +SHA256 Fingerprint=6E:A5:47:41:D0:04:66:7E:ED:1B:48:16:63:4A:A3:A7:9E:6E:4B:96:95:0F:82:79:DA:FC:8D:9B:D8:81:21:37 +-----BEGIN CERTIFICATE----- +MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB +lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt +SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG +A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe +MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v +d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh +cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn +0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ +M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a +MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd +oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI +DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy +oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0 +dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy +bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF +BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM +//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli +CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE +CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t +3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS +KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA== +-----END CERTIFICATE----- + +### Unizeto Sp. z o.o. + +=== Certum CA +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 65568 (0x10020) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Jun 11 10:46:39 2002 GMT + Not After : Jun 11 10:46:39 2027 GMT + Subject: C=PL, O=Unizeto Sp. z o.o., CN=Certum CA + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE +SHA1 Fingerprint=62:52:DC:40:F7:11:43:A2:2F:DE:9E:F7:34:8E:06:42:51:B1:81:18 +SHA256 Fingerprint=D8:E0:FE:BC:1D:B2:E3:8D:00:94:0F:37:D2:7D:41:34:4D:99:3E:73:4B:99:D5:65:6D:97:78:D4:D8:14:36:24 +-----BEGIN CERTIFICATE----- +MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM +MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD +QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM +MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD +QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E +jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo +ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI +ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu +Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg +AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7 +HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA +uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa +TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg +xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q +CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x +O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs +6GAqm4VKQPNriiTsBhYscw== +-----END CERTIFICATE----- + +### ValiCert, Inc. + +=== http://www.valicert.com/ +Certificate: + Data: + Version: 1 (0x0) + Serial Number: 1 (0x1) + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Jun 26 00:19:54 1999 GMT + Not After : Jun 26 00:19:54 2019 GMT + Subject: L=ValiCert Validation Network, O=ValiCert, Inc., OU=ValiCert Class 2 Policy Validation Authority, CN=http://www.valicert.com//emailAddress=info@valicert.com +SHA1 Fingerprint=31:7A:2A:D0:7F:2B:33:5E:F5:A1:C3:4E:4B:57:E8:B7:D8:F1:FC:A6 +SHA256 Fingerprint=58:D0:17:27:9C:D4:DC:63:AB:DD:B1:96:A6:C9:90:6C:30:C4:E0:87:83:EA:E8:C1:60:99:54:D6:93:55:59:6B +-----BEGIN CERTIFICATE----- +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 +IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz +BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y +aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG +9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy +NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y +azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw +Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl +cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY +dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9 +WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS +v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v +UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu +IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC +W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd +-----END CERTIFICATE----- + +### VeriSign, Inc. + +=== VeriSign Class 3 Public Primary Certification Authority - G3 +Certificate: + Data: + Version: 1 (0x0) + Serial Number: + 9b:7e:06:49:a3:3e:62:b9:d5:ee:90:48:71:29:ef:57 + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Oct 1 00:00:00 1999 GMT + Not After : Jul 16 23:59:59 2036 GMT + Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 1999 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G3 +SHA1 Fingerprint=13:2D:0D:45:53:4B:69:97:CD:B2:D5:C3:39:E2:55:76:60:9B:5C:C6 +SHA256 Fingerprint=EB:04:CF:5E:B1:F3:9A:FA:76:2F:2B:B1:20:F2:96:CB:A5:20:C1:B9:7D:B1:58:95:65:B8:1C:B9:A1:7B:72:44 +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl +cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu +LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT +aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD +VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ +bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu +IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b +N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t +KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu +kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm +CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ +Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu +imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te +2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe +DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC +/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p +F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt +TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== +-----END CERTIFICATE----- +=== VeriSign Class 3 Public Primary Certification Authority - G4 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 2f:80:fe:23:8c:0e:22:0f:48:67:12:28:91:87:ac:b3 + Signature Algorithm: ecdsa-with-SHA384 + Validity + Not Before: Nov 5 00:00:00 2007 GMT + Not After : Jan 18 23:59:59 2038 GMT + Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2007 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G4 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + 1.3.6.1.5.5.7.1.12: + 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif + X509v3 Subject Key Identifier: + B3:16:91:FD:EE:A6:6E:E4:B5:2E:49:8F:87:78:81:80:EC:E5:B1:B5 +SHA1 Fingerprint=22:D5:D8:DF:8F:02:31:D1:8D:F7:9D:B7:CF:8A:2D:64:C9:3F:6C:3A +SHA256 Fingerprint=69:DD:D7:EA:90:BB:57:C9:3E:13:5D:C8:5E:A6:FC:D5:48:0B:60:32:39:BD:C4:54:FC:75:8B:2A:26:CF:7F:79 +-----BEGIN CERTIFICATE----- +MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG +A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp +U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg +SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln +biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm +GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve +fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ +aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj +aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW +kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC +4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga +FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== +-----END CERTIFICATE----- +=== VeriSign Class 3 Public Primary Certification Authority - G5 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 18:da:d1:9e:26:7d:e8:bb:4a:21:58:cd:cc:6b:3b:4a + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Nov 8 00:00:00 2006 GMT + Not After : Jul 16 23:59:59 2036 GMT + Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5 + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + 1.3.6.1.5.5.7.1.12: + 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif + X509v3 Subject Key Identifier: + 7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33 +SHA1 Fingerprint=4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5 +SHA256 Fingerprint=9A:CF:AB:7E:43:C8:D8:80:D0:6B:26:2A:94:DE:EE:E4:B4:65:99:89:C3:D0:CA:F1:9B:AF:64:05:E4:1A:B7:DF +-----BEGIN CERTIFICATE----- +MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW +ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1 +nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex +t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz +SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG +BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+ +rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/ +NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E +BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH +BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy +aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv +MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE +p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y +5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK +WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ +4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N +hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq +-----END CERTIFICATE----- +=== VeriSign Class 4 Public Primary Certification Authority - G3 +Certificate: + Data: + Version: 1 (0x0) + Serial Number: + ec:a0:a7:8b:6e:75:6a:01:cf:c4:7c:cc:2f:94:5e:d7 + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: Oct 1 00:00:00 1999 GMT + Not After : Jul 16 23:59:59 2036 GMT + Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 1999 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 4 Public Primary Certification Authority - G3 +SHA1 Fingerprint=C8:EC:8C:87:92:69:CB:4B:AB:39:E9:8D:7E:57:67:F3:14:95:73:9D +SHA256 Fingerprint=E3:89:36:0D:0F:DB:AE:B3:D2:50:58:4B:47:30:31:4E:22:2F:39:C1:56:A0:20:14:4E:8D:96:05:61:79:15:06 +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl +cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu +LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT +aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD +VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ +bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu +IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1 +GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ ++mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd +U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm +NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY +ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ +ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1 +CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq +g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm +fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c +2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/ +bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg== +-----END CERTIFICATE----- +=== VeriSign Trust Network +Certificate: + Data: + Version: 1 (0x0) + Serial Number: + 7d:d9:fe:07:cf:a8:1e:b7:10:79:67:fb:a7:89:34:c6 + Signature Algorithm: sha1WithRSAEncryption + Validity + Not Before: May 18 00:00:00 1998 GMT + Not After : Aug 1 23:59:59 2028 GMT + Subject: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority - G2, OU=(c) 1998 VeriSign, Inc. - For authorized use only, OU=VeriSign Trust Network +SHA1 Fingerprint=85:37:1C:A6:E5:50:14:3D:CE:28:03:47:1B:DE:3A:09:E8:F8:77:0F +SHA256 Fingerprint=83:CE:3C:12:29:68:8A:59:3D:48:5F:81:97:3C:0F:91:95:43:1E:DA:37:CC:5E:36:43:0E:79:C7:A8:88:63:8B +-----BEGIN CERTIFICATE----- +MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ +BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh +c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy +MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp +emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X +DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw +FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg +UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo +YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 +MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4 +pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0 +13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID +AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk +U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i +F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY +oJ2daZH9 +-----END CERTIFICATE----- +=== VeriSign Universal Root Certification Authority +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 40:1a:c4:64:21:b3:13:21:03:0e:bb:e4:12:1a:c5:1d + Signature Algorithm: sha256WithRSAEncryption + Validity + Not Before: Apr 2 00:00:00 2008 GMT + Not After : Dec 1 23:59:59 2037 GMT + Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2008 VeriSign, Inc. - For authorized use only, CN=VeriSign Universal Root Certification Authority + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + 1.3.6.1.5.5.7.1.12: + 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif + X509v3 Subject Key Identifier: + B6:77:FA:69:48:47:9F:53:12:D5:C2:EA:07:32:76:07:D1:97:07:19 +SHA1 Fingerprint=36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54 +SHA256 Fingerprint=23:99:56:11:27:A5:71:25:DE:8C:EF:EA:61:0D:DF:2F:A0:78:B5:C8:06:7F:4E:82:82:90:BF:B8:60:E8:4B:3C +-----BEGIN CERTIFICATE----- +MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB +vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W +ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX +MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0 +IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y +IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh +bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF +9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH +H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H +LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN +/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT +rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw +WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs +exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud +DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4 +sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+ +seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz +4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+ +BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR +lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3 +7M2CYfE45k+XmCpajQ== +-----END CERTIFICATE----- diff --git a/crypto/libressl/apps/openssl/certhash.c b/crypto/libressl/apps/openssl/certhash.c new file mode 100644 index 0000000000..842c184ad1 --- /dev/null +++ b/crypto/libressl/apps/openssl/certhash.c @@ -0,0 +1,688 @@ +/* + * Copyright (c) 2014, 2015 Joel Sing + * + * 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 +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "apps.h" + +static struct { + int dryrun; + int verbose; +} certhash_config; + +struct option certhash_options[] = { + { + .name = "n", + .desc = "Perform a dry-run - do not make any changes", + .type = OPTION_FLAG, + .opt.flag = &certhash_config.dryrun, + }, + { + .name = "v", + .desc = "Verbose", + .type = OPTION_FLAG, + .opt.flag = &certhash_config.verbose, + }, + { NULL }, +}; + +struct hashinfo { + char *filename; + char *target; + unsigned long hash; + unsigned int index; + unsigned char fingerprint[EVP_MAX_MD_SIZE]; + int is_crl; + int is_dup; + int exists; + int changed; + struct hashinfo *reference; + struct hashinfo *next; +}; + +static struct hashinfo * +hashinfo(const char *filename, unsigned long hash, unsigned char *fingerprint) +{ + struct hashinfo *hi; + + if ((hi = calloc(1, sizeof(*hi))) == NULL) + return (NULL); + if (filename != NULL) { + if ((hi->filename = strdup(filename)) == NULL) { + free(hi); + return (NULL); + } + } + hi->hash = hash; + if (fingerprint != NULL) + memcpy(hi->fingerprint, fingerprint, sizeof(hi->fingerprint)); + + return (hi); +} + +static void +hashinfo_free(struct hashinfo *hi) +{ + if (hi == NULL) + return; + + free(hi->filename); + free(hi->target); + free(hi); +} + +#ifdef DEBUG +static void +hashinfo_print(struct hashinfo *hi) +{ + int i; + + printf("hashinfo %s %08lx %u %i\n", hi->filename, hi->hash, + hi->index, hi->is_crl); + for (i = 0; i < (int)EVP_MAX_MD_SIZE; i++) { + printf("%02X%c", hi->fingerprint[i], + (i + 1 == (int)EVP_MAX_MD_SIZE) ? '\n' : ':'); + } +} +#endif + +static int +hashinfo_compare(const void *a, const void *b) +{ + struct hashinfo *hia = *(struct hashinfo **)a; + struct hashinfo *hib = *(struct hashinfo **)b; + int rv; + + rv = hia->hash < hib->hash ? -1 : hia->hash > hib->hash; + if (rv != 0) + return (rv); + rv = memcmp(hia->fingerprint, hib->fingerprint, + sizeof(hia->fingerprint)); + if (rv != 0) + return (rv); + return strcmp(hia->filename, hib->filename); +} + +static struct hashinfo * +hashinfo_chain(struct hashinfo *head, struct hashinfo *entry) +{ + struct hashinfo *hi = head; + + if (hi == NULL) + return (entry); + while (hi->next != NULL) + hi = hi->next; + hi->next = entry; + + return (head); +} + +static void +hashinfo_chain_free(struct hashinfo *hi) +{ + struct hashinfo *next; + + while (hi != NULL) { + next = hi->next; + hashinfo_free(hi); + hi = next; + } +} + +static size_t +hashinfo_chain_length(struct hashinfo *hi) +{ + int len = 0; + + while (hi != NULL) { + len++; + hi = hi->next; + } + return (len); +} + +static int +hashinfo_chain_sort(struct hashinfo **head) +{ + struct hashinfo **list, *entry; + size_t len; + int i; + + if (*head == NULL) + return (0); + + len = hashinfo_chain_length(*head); + if ((list = reallocarray(NULL, len, sizeof(struct hashinfo *))) == NULL) + return (-1); + + for (entry = *head, i = 0; entry != NULL; entry = entry->next, i++) + list[i] = entry; + qsort(list, len, sizeof(struct hashinfo *), hashinfo_compare); + + *head = entry = list[0]; + for (i = 1; i < len; i++) { + entry->next = list[i]; + entry = list[i]; + } + entry->next = NULL; + + free(list); + return (0); +} + +static char * +hashinfo_linkname(struct hashinfo *hi) +{ + char *filename; + + if (asprintf(&filename, "%08lx.%s%u", hi->hash, + (hi->is_crl ? "r" : ""), hi->index) == -1) + return (NULL); + + return (filename); +} + +static int +filename_is_hash(const char *filename) +{ + const char *p = filename; + + while ((*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f')) + p++; + if (*p++ != '.') + return (0); + if (*p == 'r') /* CRL format. */ + p++; + while (*p >= '0' && *p <= '9') + p++; + if (*p != '\0') + return (0); + + return (1); +} + +static int +filename_is_pem(const char *filename) +{ + const char *q, *p = filename; + + if ((q = strchr(p, '\0')) == NULL) + return (0); + if ((q - p) < 4) + return (0); + if (strncmp((q - 4), ".pem", 4) != 0) + return (0); + + return (1); +} + +static struct hashinfo * +hashinfo_from_linkname(const char *linkname, const char *target) +{ + struct hashinfo *hi = NULL; + const char *errstr; + char *l, *p, *ep; + long long val; + + if ((l = strdup(linkname)) == NULL) + goto err; + if ((p = strchr(l, '.')) == NULL) + goto err; + *p++ = '\0'; + + if ((hi = hashinfo(linkname, 0, NULL)) == NULL) + goto err; + if ((hi->target = strdup(target)) == NULL) + goto err; + + errno = 0; + val = strtoll(l, &ep, 16); + if (l[0] == '\0' || *ep != '\0') + goto err; + if (errno == ERANGE && (val == LLONG_MAX || val == LLONG_MIN)) + goto err; + if (val < 0 || val > ULONG_MAX) + goto err; + hi->hash = (unsigned long)val; + + if (*p == 'r') { + hi->is_crl = 1; + p++; + } + + val = strtonum(p, 0, 0xffffffff, &errstr); + if (errstr != NULL) + goto err; + + hi->index = (unsigned int)val; + + goto done; + +err: + hashinfo_free(hi); + hi = NULL; + +done: + free(l); + + return (hi); +} + +static struct hashinfo * +certhash_cert(BIO *bio, const char *filename) +{ + unsigned char fingerprint[EVP_MAX_MD_SIZE]; + struct hashinfo *hi = NULL; + const EVP_MD *digest; + X509 *cert = NULL; + unsigned long hash; + unsigned int len; + + if ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL) + goto err; + + hash = X509_subject_name_hash(cert); + + digest = EVP_sha256(); + if (X509_digest(cert, digest, fingerprint, &len) != 1) { + fprintf(stderr, "out of memory\n"); + goto err; + } + + hi = hashinfo(filename, hash, fingerprint); + +err: + X509_free(cert); + + return (hi); +} + +static struct hashinfo * +certhash_crl(BIO *bio, const char *filename) +{ + unsigned char fingerprint[EVP_MAX_MD_SIZE]; + struct hashinfo *hi = NULL; + const EVP_MD *digest; + X509_CRL *crl = NULL; + unsigned long hash; + unsigned int len; + + if ((crl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) == NULL) + return (NULL); + + hash = X509_NAME_hash(X509_CRL_get_issuer(crl)); + + digest = EVP_sha256(); + if (X509_CRL_digest(crl, digest, fingerprint, &len) != 1) { + fprintf(stderr, "out of memory\n"); + goto err; + } + + hi = hashinfo(filename, hash, fingerprint); + +err: + X509_CRL_free(crl); + + return (hi); +} + +static int +certhash_addlink(struct hashinfo **links, struct hashinfo *hi) +{ + struct hashinfo *link = NULL; + + if ((link = hashinfo(NULL, hi->hash, hi->fingerprint)) == NULL) + goto err; + + if ((link->filename = hashinfo_linkname(hi)) == NULL) + goto err; + + link->reference = hi; + link->changed = 1; + *links = hashinfo_chain(*links, link); + hi->reference = link; + + return (0); + +err: + hashinfo_free(link); + return (-1); +} + +static void +certhash_findlink(struct hashinfo *links, struct hashinfo *hi) +{ + struct hashinfo *link; + + for (link = links; link != NULL; link = link->next) { + if (link->is_crl == hi->is_crl && + link->hash == hi->hash && + link->index == hi->index && + link->reference == NULL) { + link->reference = hi; + if (link->target == NULL || + strcmp(link->target, hi->filename) != 0) + link->changed = 1; + hi->reference = link; + break; + } + } +} + +static void +certhash_index(struct hashinfo *head, const char *name) +{ + struct hashinfo *last, *entry; + int index = 0; + + last = NULL; + for (entry = head; entry != NULL; entry = entry->next) { + if (last != NULL) { + if (entry->hash == last->hash) { + if (memcmp(entry->fingerprint, + last->fingerprint, + sizeof(entry->fingerprint)) == 0) { + fprintf(stderr, "WARNING: duplicate %s " + "in %s (using %s), ignoring...\n", + name, entry->filename, + last->filename); + entry->is_dup = 1; + continue; + } + index++; + } else { + index = 0; + } + } + entry->index = index; + last = entry; + } +} + +static int +certhash_merge(struct hashinfo **links, struct hashinfo **certs, + struct hashinfo **crls) +{ + struct hashinfo *cert, *crl; + + /* Pass 1 - sort and index entries. */ + if (hashinfo_chain_sort(certs) == -1) + return (-1); + if (hashinfo_chain_sort(crls) == -1) + return (-1); + certhash_index(*certs, "certificate"); + certhash_index(*crls, "CRL"); + + /* Pass 2 - map to existing links. */ + for (cert = *certs; cert != NULL; cert = cert->next) { + if (cert->is_dup == 1) + continue; + certhash_findlink(*links, cert); + } + for (crl = *crls; crl != NULL; crl = crl->next) { + if (crl->is_dup == 1) + continue; + certhash_findlink(*links, crl); + } + + /* Pass 3 - determine missing links. */ + for (cert = *certs; cert != NULL; cert = cert->next) { + if (cert->is_dup == 1 || cert->reference != NULL) + continue; + if (certhash_addlink(links, cert) == -1) + return (-1); + } + for (crl = *crls; crl != NULL; crl = crl->next) { + if (crl->is_dup == 1 || crl->reference != NULL) + continue; + if (certhash_addlink(links, crl) == -1) + return (-1); + } + + return (0); +} + +static int +certhash_link(struct dirent *dep, struct hashinfo **links) +{ + struct hashinfo *hi = NULL; + char target[PATH_MAX]; + struct stat sb; + int n; + + if (lstat(dep->d_name, &sb) == -1) { + fprintf(stderr, "failed to stat %s\n", dep->d_name); + return (-1); + } + if (!S_ISLNK(sb.st_mode)) + return (0); + + n = readlink(dep->d_name, target, sizeof(target) - 1); + if (n == -1) { + fprintf(stderr, "failed to readlink %s\n", dep->d_name); + return (-1); + } + target[n] = '\0'; + + hi = hashinfo_from_linkname(dep->d_name, target); + if (hi == NULL) { + fprintf(stderr, "failed to get hash info %s\n", dep->d_name); + return (-1); + } + hi->exists = 1; + *links = hashinfo_chain(*links, hi); + + return (0); +} + +static int +certhash_file(struct dirent *dep, struct hashinfo **certs, + struct hashinfo **crls) +{ + struct hashinfo *hi = NULL; + int has_cert, has_crl; + int ret = -1; + BIO *bio = NULL; + FILE *f; + + has_cert = has_crl = 0; + + if ((f = fopen(dep->d_name, "r")) == NULL) { + fprintf(stderr, "failed to fopen %s\n", dep->d_name); + goto err; + } + if ((bio = BIO_new_fp(f, BIO_CLOSE)) == NULL) { + fprintf(stderr, "failed to create bio\n"); + fclose(f); + goto err; + } + + if ((hi = certhash_cert(bio, dep->d_name)) != NULL) { + has_cert = 1; + *certs = hashinfo_chain(*certs, hi); + } + + if (BIO_reset(bio) != 0) { + fprintf(stderr, "BIO_reset failed\n"); + goto err; + } + + if ((hi = certhash_crl(bio, dep->d_name)) != NULL) { + has_crl = hi->is_crl = 1; + *crls = hashinfo_chain(*crls, hi); + } + + if (!has_cert && !has_crl) + fprintf(stderr, "PEM file %s does not contain a certificate " + "or CRL, ignoring...\n", dep->d_name); + + ret = 0; + +err: + BIO_free(bio); + + return (ret); +} + +static int +certhash_directory(const char *path) +{ + struct hashinfo *links = NULL, *certs = NULL, *crls = NULL, *link; + int ret = 0; + struct dirent *dep; + DIR *dip = NULL; + + if ((dip = opendir(".")) == NULL) { + fprintf(stderr, "failed to open directory %s\n", path); + goto err; + } + + if (certhash_config.verbose) + fprintf(stdout, "scanning directory %s\n", path); + + /* Create lists of existing hash links, certs and CRLs. */ + while ((dep = readdir(dip)) != NULL) { + if (filename_is_hash(dep->d_name)) { + if (certhash_link(dep, &links) == -1) + goto err; + } + if (filename_is_pem(dep->d_name)) { + if (certhash_file(dep, &certs, &crls) == -1) + goto err; + } + } + + if (certhash_merge(&links, &certs, &crls) == -1) { + fprintf(stderr, "certhash merge failed\n"); + goto err; + } + + /* Remove spurious links. */ + for (link = links; link != NULL; link = link->next) { + if (link->exists == 0 || + (link->reference != NULL && link->changed == 0)) + continue; + if (certhash_config.verbose) + fprintf(stdout, "%s link %s -> %s\n", + (certhash_config.dryrun ? "would remove" : + "removing"), link->filename, link->target); + if (certhash_config.dryrun) + continue; + if (unlink(link->filename) == -1) { + fprintf(stderr, "failed to remove link %s\n", + link->filename); + goto err; + } + } + + /* Create missing links. */ + for (link = links; link != NULL; link = link->next) { + if (link->exists == 1 && link->changed == 0) + continue; + if (certhash_config.verbose) + fprintf(stdout, "%s link %s -> %s\n", + (certhash_config.dryrun ? "would create" : + "creating"), link->filename, + link->reference->filename); + if (certhash_config.dryrun) + continue; + if (symlink(link->reference->filename, link->filename) == -1) { + fprintf(stderr, "failed to create link %s -> %s\n", + link->filename, link->reference->filename); + goto err; + } + } + + goto done; + +err: + ret = 1; + +done: + hashinfo_chain_free(certs); + hashinfo_chain_free(crls); + hashinfo_chain_free(links); + + if (dip != NULL) + closedir(dip); + return (ret); +} + +static void +certhash_usage(void) +{ + fprintf(stderr, "usage: certhash [-nv] dir ...\n"); + options_usage(certhash_options); +} + +int +certhash_main(int argc, char **argv) +{ + int argsused; + int i, cwdfd, ret = 0; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + memset(&certhash_config, 0, sizeof(certhash_config)); + + if (options_parse(argc, argv, certhash_options, NULL, &argsused) != 0) { + certhash_usage(); + return (1); + } + + if ((cwdfd = open(".", O_RDONLY)) == -1) { + perror("failed to open current directory"); + return (1); + } + + for (i = argsused; i < argc; i++) { + if (chdir(argv[i]) == -1) { + fprintf(stderr, + "failed to change to directory %s: %s\n", + argv[i], strerror(errno)); + ret = 1; + continue; + } + ret |= certhash_directory(argv[i]); + if (fchdir(cwdfd) == -1) { + perror("failed to restore current directory"); + ret = 1; + break; /* can't continue safely */ + } + } + close(cwdfd); + + return (ret); +} diff --git a/crypto/libressl/apps/openssl/certhash_win.c b/crypto/libressl/apps/openssl/certhash_win.c new file mode 100644 index 0000000000..8238ff7c95 --- /dev/null +++ b/crypto/libressl/apps/openssl/certhash_win.c @@ -0,0 +1,13 @@ +/* + * Public domain + * certhash dummy implementation for platforms without symlinks + */ + +#include "apps.h" + +int +certhash_main(int argc, char **argv) +{ + fprintf(stderr, "certhash is not enabled on this platform\n"); + return (1); +} diff --git a/crypto/libressl/apps/openssl/ciphers.c b/crypto/libressl/apps/openssl/ciphers.c new file mode 100644 index 0000000000..d6f7efba9e --- /dev/null +++ b/crypto/libressl/apps/openssl/ciphers.c @@ -0,0 +1,152 @@ +/* $OpenBSD: ciphers.c,v 1.7 2015/10/10 22:28:51 doug Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * 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 +#include + +#include +#include + +#include "apps.h" +#include "progs.h" + +struct { + int usage; + int verbose; +} ciphers_config; + +struct option ciphers_options[] = { + { + .name = "h", + .type = OPTION_FLAG, + .opt.flag = &ciphers_config.usage, + }, + { + .name = "?", + .type = OPTION_FLAG, + .opt.flag = &ciphers_config.usage, + }, + { + .name = "tls1", + .desc = "This option is deprecated since it is the default", + .type = OPTION_DISCARD, + }, + { + .name = "v", + .desc = "Provide cipher listing", + .type = OPTION_VALUE, + .opt.value = &ciphers_config.verbose, + .value = 1, + }, + { + .name = "V", + .desc = "Provide cipher listing with cipher suite values", + .type = OPTION_VALUE, + .opt.value = &ciphers_config.verbose, + .value = 2, + }, + { NULL }, +}; + +static void +ciphers_usage(void) +{ + fprintf(stderr, "usage: ciphers [-hVv] [-tls1] [cipherlist]\n"); + options_usage(ciphers_options); +} + +int +ciphers_main(int argc, char **argv) +{ + char *cipherlist = NULL; + STACK_OF(SSL_CIPHER) *ciphers; + const SSL_CIPHER *cipher; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + uint16_t value; + int i, rv = 0; + char *desc; + + if (single_execution) { + if (pledge("stdio rpath", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + memset(&ciphers_config, 0, sizeof(ciphers_config)); + + if (options_parse(argc, argv, ciphers_options, &cipherlist, + NULL) != 0) { + ciphers_usage(); + return (1); + } + + if (ciphers_config.usage) { + ciphers_usage(); + return (1); + } + + if ((ssl_ctx = SSL_CTX_new(TLSv1_client_method())) == NULL) + goto err; + + if (cipherlist != NULL) { + if (SSL_CTX_set_cipher_list(ssl_ctx, cipherlist) == 0) + goto err; + } + + if ((ssl = SSL_new(ssl_ctx)) == NULL) + goto err; + + if ((ciphers = SSL_get_ciphers(ssl)) == NULL) + goto err; + + for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { + cipher = sk_SSL_CIPHER_value(ciphers, i); + if (ciphers_config.verbose == 0) { + fprintf(stdout, "%s%s", (i ? ":" : ""), + SSL_CIPHER_get_name(cipher)); + continue; + } + if (ciphers_config.verbose > 1) { + value = SSL_CIPHER_get_value(cipher); + fprintf(stdout, "%-*s0x%02X,0x%02X - ", 10, "", + ((value >> 8) & 0xff), (value & 0xff)); + } + desc = SSL_CIPHER_description(cipher, NULL, 0); + if (strcmp(desc, "OPENSSL_malloc Error") == 0) { + fprintf(stderr, "out of memory\n"); + goto err; + } + fprintf(stdout, "%s", desc); + free(desc); + } + if (ciphers_config.verbose == 0) + fprintf(stdout, "\n"); + + goto done; + +err: + ERR_print_errors_fp(stderr); + rv = 1; + +done: + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + + return (rv); +} diff --git a/crypto/libressl/apps/openssl/cms.c b/crypto/libressl/apps/openssl/cms.c new file mode 100644 index 0000000000..55c881572a --- /dev/null +++ b/crypto/libressl/apps/openssl/cms.c @@ -0,0 +1,1142 @@ +/* $OpenBSD: cms.c,v 1.5 2015/10/17 07:51:10 semarie Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +/* CMS utility function */ + +#include +#include + +#include "apps.h" + +#ifndef OPENSSL_NO_CMS + +#include +#include +#include +#include +#include +#include + +static int save_certs(char *signerfile, STACK_OF(X509) * signers); +static int cms_cb(int ok, X509_STORE_CTX * ctx); +static void receipt_request_print(BIO * out, CMS_ContentInfo * cms); +static CMS_ReceiptRequest * make_receipt_request( + STACK_OF(OPENSSL_STRING) * rr_to, int rr_allorfirst, + STACK_OF(OPENSSL_STRING) * rr_from); + +#define SMIME_OP 0x10 +#define SMIME_IP 0x20 +#define SMIME_SIGNERS 0x40 +#define SMIME_ENCRYPT (1 | SMIME_OP) +#define SMIME_DECRYPT (2 | SMIME_IP) +#define SMIME_SIGN (3 | SMIME_OP | SMIME_SIGNERS) +#define SMIME_VERIFY (4 | SMIME_IP) +#define SMIME_CMSOUT (5 | SMIME_IP | SMIME_OP) +#define SMIME_RESIGN (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS) +#define SMIME_DATAOUT (7 | SMIME_IP) +#define SMIME_DATA_CREATE (8 | SMIME_OP) +#define SMIME_DIGEST_VERIFY (9 | SMIME_IP) +#define SMIME_DIGEST_CREATE (10 | SMIME_OP) +#define SMIME_UNCOMPRESS (11 | SMIME_IP) +#define SMIME_COMPRESS (12 | SMIME_OP) +#define SMIME_ENCRYPTED_DECRYPT (13 | SMIME_IP) +#define SMIME_ENCRYPTED_ENCRYPT (14 | SMIME_OP) +#define SMIME_SIGN_RECEIPT (15 | SMIME_IP | SMIME_OP) +#define SMIME_VERIFY_RECEIPT (16 | SMIME_IP) + +int verify_err = 0; + +int +cms_main(int argc, char **argv) +{ + int operation = 0; + int ret = 0; + char **args; + const char *inmode = "r", *outmode = "w"; + char *infile = NULL, *outfile = NULL, *rctfile = NULL; + char *signerfile = NULL, *recipfile = NULL; + STACK_OF(OPENSSL_STRING) * sksigners = NULL, *skkeys = NULL; + char *certfile = NULL, *keyfile = NULL, *contfile = NULL; + char *certsoutfile = NULL; + const EVP_CIPHER *cipher = NULL; + CMS_ContentInfo *cms = NULL, *rcms = NULL; + X509_STORE *store = NULL; + X509 *cert = NULL, *recip = NULL, *signer = NULL; + EVP_PKEY *key = NULL; + STACK_OF(X509) * encerts = NULL, *other = NULL; + BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL; + int badarg = 0; + int flags = CMS_DETACHED, noout = 0, print = 0; + int verify_retcode = 0; + int rr_print = 0, rr_allorfirst = -1; + STACK_OF(OPENSSL_STRING) * rr_to = NULL, *rr_from = NULL; + CMS_ReceiptRequest *rr = NULL; + char *to = NULL, *from = NULL, *subject = NULL; + char *CAfile = NULL, *CApath = NULL; + char *passargin = NULL, *passin = NULL; + const EVP_MD *sign_md = NULL; + int informat = FORMAT_SMIME, outformat = FORMAT_SMIME; + int rctformat = FORMAT_SMIME, keyform = FORMAT_PEM; + unsigned char *secret_key = NULL, *secret_keyid = NULL; + unsigned char *pwri_pass = NULL, *pwri_tmp = NULL; + size_t secret_keylen = 0, secret_keyidlen = 0; + + ASN1_OBJECT *econtent_type = NULL; + + X509_VERIFY_PARAM *vpm = NULL; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + args = argv + 1; + ret = 1; + + while (!badarg && *args && *args[0] == '-') { + if (!strcmp(*args, "-encrypt")) + operation = SMIME_ENCRYPT; + else if (!strcmp(*args, "-decrypt")) + operation = SMIME_DECRYPT; + else if (!strcmp(*args, "-sign")) + operation = SMIME_SIGN; + else if (!strcmp(*args, "-sign_receipt")) + operation = SMIME_SIGN_RECEIPT; + else if (!strcmp(*args, "-resign")) + operation = SMIME_RESIGN; + else if (!strcmp(*args, "-verify")) + operation = SMIME_VERIFY; + else if (!strcmp(*args, "-verify_retcode")) + verify_retcode = 1; + else if (!strcmp(*args, "-verify_receipt")) { + operation = SMIME_VERIFY_RECEIPT; + if (!args[1]) + goto argerr; + args++; + rctfile = *args; + } else if (!strcmp(*args, "-cmsout")) + operation = SMIME_CMSOUT; + else if (!strcmp(*args, "-data_out")) + operation = SMIME_DATAOUT; + else if (!strcmp(*args, "-data_create")) + operation = SMIME_DATA_CREATE; + else if (!strcmp(*args, "-digest_verify")) + operation = SMIME_DIGEST_VERIFY; + else if (!strcmp(*args, "-digest_create")) + operation = SMIME_DIGEST_CREATE; + else if (!strcmp(*args, "-compress")) + operation = SMIME_COMPRESS; + else if (!strcmp(*args, "-uncompress")) + operation = SMIME_UNCOMPRESS; + else if (!strcmp(*args, "-EncryptedData_decrypt")) + operation = SMIME_ENCRYPTED_DECRYPT; + else if (!strcmp(*args, "-EncryptedData_encrypt")) + operation = SMIME_ENCRYPTED_ENCRYPT; +#ifndef OPENSSL_NO_DES + else if (!strcmp(*args, "-des3")) + cipher = EVP_des_ede3_cbc(); + else if (!strcmp(*args, "-des")) + cipher = EVP_des_cbc(); +#endif +#ifndef OPENSSL_NO_RC2 + else if (!strcmp(*args, "-rc2-40")) + cipher = EVP_rc2_40_cbc(); + else if (!strcmp(*args, "-rc2-128")) + cipher = EVP_rc2_cbc(); + else if (!strcmp(*args, "-rc2-64")) + cipher = EVP_rc2_64_cbc(); +#endif +#ifndef OPENSSL_NO_AES + else if (!strcmp(*args, "-aes128")) + cipher = EVP_aes_128_cbc(); + else if (!strcmp(*args, "-aes192")) + cipher = EVP_aes_192_cbc(); + else if (!strcmp(*args, "-aes256")) + cipher = EVP_aes_256_cbc(); +#endif +#ifndef OPENSSL_NO_CAMELLIA + else if (!strcmp(*args, "-camellia128")) + cipher = EVP_camellia_128_cbc(); + else if (!strcmp(*args, "-camellia192")) + cipher = EVP_camellia_192_cbc(); + else if (!strcmp(*args, "-camellia256")) + cipher = EVP_camellia_256_cbc(); +#endif + else if (!strcmp(*args, "-debug_decrypt")) + flags |= CMS_DEBUG_DECRYPT; + else if (!strcmp(*args, "-text")) + flags |= CMS_TEXT; + else if (!strcmp(*args, "-nointern")) + flags |= CMS_NOINTERN; + else if (!strcmp(*args, "-noverify") || + !strcmp(*args, "-no_signer_cert_verify")) + flags |= CMS_NO_SIGNER_CERT_VERIFY; + else if (!strcmp(*args, "-nocerts")) + flags |= CMS_NOCERTS; + else if (!strcmp(*args, "-noattr")) + flags |= CMS_NOATTR; + else if (!strcmp(*args, "-nodetach")) + flags &= ~CMS_DETACHED; + else if (!strcmp(*args, "-nosmimecap")) + flags |= CMS_NOSMIMECAP; + else if (!strcmp(*args, "-binary")) + flags |= CMS_BINARY; + else if (!strcmp(*args, "-keyid")) + flags |= CMS_USE_KEYID; + else if (!strcmp(*args, "-nosigs")) + flags |= CMS_NOSIGS; + else if (!strcmp(*args, "-no_content_verify")) + flags |= CMS_NO_CONTENT_VERIFY; + else if (!strcmp(*args, "-no_attr_verify")) + flags |= CMS_NO_ATTR_VERIFY; + else if (!strcmp(*args, "-stream")) + flags |= CMS_STREAM; + else if (!strcmp(*args, "-indef")) + flags |= CMS_STREAM; + else if (!strcmp(*args, "-noindef")) + flags &= ~CMS_STREAM; + else if (!strcmp(*args, "-nooldmime")) + flags |= CMS_NOOLDMIMETYPE; + else if (!strcmp(*args, "-crlfeol")) + flags |= CMS_CRLFEOL; + else if (!strcmp(*args, "-noout")) + noout = 1; + else if (!strcmp(*args, "-receipt_request_print")) + rr_print = 1; + else if (!strcmp(*args, "-receipt_request_all")) + rr_allorfirst = 0; + else if (!strcmp(*args, "-receipt_request_first")) + rr_allorfirst = 1; + else if (!strcmp(*args, "-receipt_request_from")) { + if (!args[1]) + goto argerr; + args++; + if (!rr_from) + rr_from = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(rr_from, *args); + } else if (!strcmp(*args, "-receipt_request_to")) { + if (!args[1]) + goto argerr; + args++; + if (!rr_to) + rr_to = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(rr_to, *args); + } else if (!strcmp(*args, "-print")) { + noout = 1; + print = 1; + } else if (!strcmp(*args, "-secretkey")) { + long ltmp; + if (!args[1]) + goto argerr; + args++; + secret_key = string_to_hex(*args, <mp); + if (!secret_key) { + BIO_printf(bio_err, "Invalid key %s\n", *args); + goto argerr; + } + secret_keylen = (size_t) ltmp; + } else if (!strcmp(*args, "-secretkeyid")) { + long ltmp; + if (!args[1]) + goto argerr; + args++; + secret_keyid = string_to_hex(*args, <mp); + if (!secret_keyid) { + BIO_printf(bio_err, "Invalid id %s\n", *args); + goto argerr; + } + secret_keyidlen = (size_t) ltmp; + } else if (!strcmp(*args, "-pwri_password")) { + if (!args[1]) + goto argerr; + args++; + pwri_pass = (unsigned char *) *args; + } else if (!strcmp(*args, "-econtent_type")) { + if (!args[1]) + goto argerr; + args++; + econtent_type = OBJ_txt2obj(*args, 0); + if (!econtent_type) { + BIO_printf(bio_err, "Invalid OID %s\n", *args); + goto argerr; + } + } + else if (!strcmp(*args, "-passin")) { + if (!args[1]) + goto argerr; + passargin = *++args; + } else if (!strcmp(*args, "-to")) { + if (!args[1]) + goto argerr; + to = *++args; + } else if (!strcmp(*args, "-from")) { + if (!args[1]) + goto argerr; + from = *++args; + } else if (!strcmp(*args, "-subject")) { + if (!args[1]) + goto argerr; + subject = *++args; + } else if (!strcmp(*args, "-signer")) { + if (!args[1]) + goto argerr; + /* If previous -signer argument add signer to list */ + + if (signerfile) { + if (!sksigners) + sksigners = + sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(sksigners, signerfile); + if (!keyfile) + keyfile = signerfile; + if (!skkeys) + skkeys = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(skkeys, keyfile); + keyfile = NULL; + } + signerfile = *++args; + } else if (!strcmp(*args, "-recip")) { + if (!args[1]) + goto argerr; + recipfile = *++args; + } else if (!strcmp(*args, "-certsout")) { + if (!args[1]) + goto argerr; + certsoutfile = *++args; + } else if (!strcmp(*args, "-md")) { + if (!args[1]) + goto argerr; + sign_md = EVP_get_digestbyname(*++args); + if (sign_md == NULL) { + BIO_printf(bio_err, "Unknown digest %s\n", + *args); + goto argerr; + } + } else if (!strcmp(*args, "-inkey")) { + if (!args[1]) + goto argerr; + /* If previous -inkey arument add signer to list */ + if (keyfile) { + if (!signerfile) { + BIO_puts(bio_err, + "Illegal -inkey without -signer\n"); + goto argerr; + } + if (!sksigners) + sksigners = + sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(sksigners, signerfile); + signerfile = NULL; + if (!skkeys) + skkeys = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(skkeys, keyfile); + } + keyfile = *++args; + } else if (!strcmp(*args, "-keyform")) { + if (!args[1]) + goto argerr; + keyform = str2fmt(*++args); + } else if (!strcmp(*args, "-rctform")) { + if (!args[1]) + goto argerr; + rctformat = str2fmt(*++args); + } else if (!strcmp(*args, "-certfile")) { + if (!args[1]) + goto argerr; + certfile = *++args; + } else if (!strcmp(*args, "-CAfile")) { + if (!args[1]) + goto argerr; + CAfile = *++args; + } else if (!strcmp(*args, "-CApath")) { + if (!args[1]) + goto argerr; + CApath = *++args; + } else if (!strcmp(*args, "-in")) { + if (!args[1]) + goto argerr; + infile = *++args; + } else if (!strcmp(*args, "-inform")) { + if (!args[1]) + goto argerr; + informat = str2fmt(*++args); + } else if (!strcmp(*args, "-outform")) { + if (!args[1]) + goto argerr; + outformat = str2fmt(*++args); + } else if (!strcmp(*args, "-out")) { + if (!args[1]) + goto argerr; + outfile = *++args; + } else if (!strcmp(*args, "-content")) { + if (!args[1]) + goto argerr; + contfile = *++args; + } else if (args_verify(&args, NULL, &badarg, bio_err, &vpm)) + continue; + else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL) + badarg = 1; + args++; + } + + if (((rr_allorfirst != -1) || rr_from) && !rr_to) { + BIO_puts(bio_err, "No Signed Receipts Recipients\n"); + goto argerr; + } + if (!(operation & SMIME_SIGNERS) && (rr_to || rr_from)) { + BIO_puts(bio_err, "Signed receipts only allowed with -sign\n"); + goto argerr; + } + if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) { + BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); + goto argerr; + } + if (operation & SMIME_SIGNERS) { + if (keyfile && !signerfile) { + BIO_puts(bio_err, "Illegal -inkey without -signer\n"); + goto argerr; + } + /* Check to see if any final signer needs to be appended */ + if (signerfile) { + if (!sksigners) + sksigners = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(sksigners, signerfile); + if (!skkeys) + skkeys = sk_OPENSSL_STRING_new_null(); + if (!keyfile) + keyfile = signerfile; + sk_OPENSSL_STRING_push(skkeys, keyfile); + } + if (!sksigners) { + BIO_printf(bio_err, + "No signer certificate specified\n"); + badarg = 1; + } + signerfile = NULL; + keyfile = NULL; + } else if (operation == SMIME_DECRYPT) { + if (!recipfile && !keyfile && !secret_key && !pwri_pass) { + BIO_printf(bio_err, + "No recipient certificate or key specified\n"); + badarg = 1; + } + } else if (operation == SMIME_ENCRYPT) { + if (!*args && !secret_key && !pwri_pass) { + BIO_printf(bio_err, + "No recipient(s) certificate(s) specified\n"); + badarg = 1; + } + } else if (!operation) + badarg = 1; + + if (badarg) { +argerr: + BIO_printf(bio_err, "Usage cms [options] cert.pem ...\n"); + BIO_printf(bio_err, "where options are\n"); + BIO_printf(bio_err, "-encrypt encrypt message\n"); + BIO_printf(bio_err, "-decrypt decrypt encrypted message\n"); + BIO_printf(bio_err, "-sign sign message\n"); + BIO_printf(bio_err, "-verify verify signed message\n"); + BIO_printf(bio_err, "-cmsout output CMS structure\n"); +#ifndef OPENSSL_NO_DES + BIO_printf(bio_err, "-des3 encrypt with triple DES\n"); + BIO_printf(bio_err, "-des encrypt with DES\n"); +#endif +#ifndef OPENSSL_NO_RC2 + BIO_printf(bio_err, "-rc2-40 encrypt with RC2-40 (default)\n"); + BIO_printf(bio_err, "-rc2-64 encrypt with RC2-64\n"); + BIO_printf(bio_err, "-rc2-128 encrypt with RC2-128\n"); +#endif +#ifndef OPENSSL_NO_AES + BIO_printf(bio_err, "-aes128, -aes192, -aes256\n"); + BIO_printf(bio_err, " encrypt PEM output with cbc aes\n"); +#endif +#ifndef OPENSSL_NO_CAMELLIA + BIO_printf(bio_err, "-camellia128, -camellia192, -camellia256\n"); + BIO_printf(bio_err, " encrypt PEM output with cbc camellia\n"); +#endif + BIO_printf(bio_err, "-nointern don't search certificates in message for signer\n"); + BIO_printf(bio_err, "-nosigs don't verify message signature\n"); + BIO_printf(bio_err, "-noverify don't verify signers certificate\n"); + BIO_printf(bio_err, "-nocerts don't include signers certificate when signing\n"); + BIO_printf(bio_err, "-nodetach use opaque signing\n"); + BIO_printf(bio_err, "-noattr don't include any signed attributes\n"); + BIO_printf(bio_err, "-binary don't translate message to text\n"); + BIO_printf(bio_err, "-certfile file other certificates file\n"); + BIO_printf(bio_err, "-certsout file certificate output file\n"); + BIO_printf(bio_err, "-signer file signer certificate file\n"); + BIO_printf(bio_err, "-recip file recipient certificate file for decryption\n"); + BIO_printf(bio_err, "-keyid use subject key identifier\n"); + BIO_printf(bio_err, "-in file input file\n"); + BIO_printf(bio_err, "-inform arg input format SMIME (default), PEM or DER\n"); + BIO_printf(bio_err, "-inkey file input private key (if not signer or recipient)\n"); + BIO_printf(bio_err, "-keyform arg input private key format (PEM)\n"); + BIO_printf(bio_err, "-out file output file\n"); + BIO_printf(bio_err, "-outform arg output format SMIME (default), PEM or DER\n"); + BIO_printf(bio_err, "-content file supply or override content for detached signature\n"); + BIO_printf(bio_err, "-to addr to address\n"); + BIO_printf(bio_err, "-from ad from address\n"); + BIO_printf(bio_err, "-subject s subject\n"); + BIO_printf(bio_err, "-text include or delete text MIME headers\n"); + BIO_printf(bio_err, "-CApath dir trusted certificates directory\n"); + BIO_printf(bio_err, "-CAfile file trusted certificates file\n"); + BIO_printf(bio_err, "-crl_check check revocation status of signer's certificate using CRLs\n"); + BIO_printf(bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n"); + BIO_printf(bio_err, "-passin arg input file pass phrase source\n"); + BIO_printf(bio_err, "cert.pem recipient certificate(s) for encryption\n"); + goto end; + } + + if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { + BIO_printf(bio_err, "Error getting password\n"); + goto end; + } + ret = 2; + + if (!(operation & SMIME_SIGNERS)) + flags &= ~CMS_DETACHED; + + if (operation & SMIME_OP) { + if (outformat == FORMAT_ASN1) + outmode = "wb"; + } else { + if (flags & CMS_BINARY) + outmode = "wb"; + } + + if (operation & SMIME_IP) { + if (informat == FORMAT_ASN1) + inmode = "rb"; + } else { + if (flags & CMS_BINARY) + inmode = "rb"; + } + + if (operation == SMIME_ENCRYPT) { + if (!cipher) { +#ifndef OPENSSL_NO_DES + cipher = EVP_des_ede3_cbc(); +#else + BIO_printf(bio_err, "No cipher selected\n"); + goto end; +#endif + } + if (secret_key && !secret_keyid) { + BIO_printf(bio_err, "No secret key id\n"); + goto end; + } + if (*args) + encerts = sk_X509_new_null(); + while (*args) { + if (!(cert = load_cert(bio_err, *args, FORMAT_PEM, + NULL, e, "recipient certificate file"))) + goto end; + sk_X509_push(encerts, cert); + cert = NULL; + args++; + } + } + if (certfile) { + if (!(other = load_certs(bio_err, certfile, FORMAT_PEM, NULL, + e, "certificate file"))) { + ERR_print_errors(bio_err); + goto end; + } + } + if (recipfile && (operation == SMIME_DECRYPT)) { + if (!(recip = load_cert(bio_err, recipfile, FORMAT_PEM, NULL, + e, "recipient certificate file"))) { + ERR_print_errors(bio_err); + goto end; + } + } + if (operation == SMIME_SIGN_RECEIPT) { + if (!(signer = load_cert(bio_err, signerfile, FORMAT_PEM, NULL, + e, "receipt signer certificate file"))) { + ERR_print_errors(bio_err); + goto end; + } + } + if (operation == SMIME_DECRYPT) { + if (!keyfile) + keyfile = recipfile; + } else if ((operation == SMIME_SIGN) || + (operation == SMIME_SIGN_RECEIPT)) { + if (!keyfile) + keyfile = signerfile; + } else + keyfile = NULL; + + if (keyfile) { + key = load_key(bio_err, keyfile, keyform, 0, passin, e, + "signing key file"); + if (!key) + goto end; + } + if (infile) { + if (!(in = BIO_new_file(infile, inmode))) { + BIO_printf(bio_err, + "Can't open input file %s\n", infile); + goto end; + } + } else + in = BIO_new_fp(stdin, BIO_NOCLOSE); + + if (operation & SMIME_IP) { + if (informat == FORMAT_SMIME) + cms = SMIME_read_CMS(in, &indata); + else if (informat == FORMAT_PEM) + cms = PEM_read_bio_CMS(in, NULL, NULL, NULL); + else if (informat == FORMAT_ASN1) + cms = d2i_CMS_bio(in, NULL); + else { + BIO_printf(bio_err, "Bad input format for CMS file\n"); + goto end; + } + + if (!cms) { + BIO_printf(bio_err, "Error reading S/MIME message\n"); + goto end; + } + if (contfile) { + BIO_free(indata); + if (!(indata = BIO_new_file(contfile, "rb"))) { + BIO_printf(bio_err, + "Can't read content file %s\n", contfile); + goto end; + } + } + if (certsoutfile) { + STACK_OF(X509) * allcerts; + allcerts = CMS_get1_certs(cms); + if (!save_certs(certsoutfile, allcerts)) { + BIO_printf(bio_err, + "Error writing certs to %s\n", + certsoutfile); + ret = 5; + goto end; + } + sk_X509_pop_free(allcerts, X509_free); + } + } + if (rctfile) { + char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r"; + if (!(rctin = BIO_new_file(rctfile, rctmode))) { + BIO_printf(bio_err, + "Can't open receipt file %s\n", rctfile); + goto end; + } + if (rctformat == FORMAT_SMIME) + rcms = SMIME_read_CMS(rctin, NULL); + else if (rctformat == FORMAT_PEM) + rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL); + else if (rctformat == FORMAT_ASN1) + rcms = d2i_CMS_bio(rctin, NULL); + else { + BIO_printf(bio_err, "Bad input format for receipt\n"); + goto end; + } + + if (!rcms) { + BIO_printf(bio_err, "Error reading receipt\n"); + goto end; + } + } + if (outfile) { + if (!(out = BIO_new_file(outfile, outmode))) { + BIO_printf(bio_err, + "Can't open output file %s\n", outfile); + goto end; + } + } else { + out = BIO_new_fp(stdout, BIO_NOCLOSE); + } + + if ((operation == SMIME_VERIFY) || + (operation == SMIME_VERIFY_RECEIPT)) { + if (!(store = setup_verify(bio_err, CAfile, CApath))) + goto end; + X509_STORE_set_verify_cb(store, cms_cb); + if (vpm) + X509_STORE_set1_param(store, vpm); + } + ret = 3; + + if (operation == SMIME_DATA_CREATE) { + cms = CMS_data_create(in, flags); + } else if (operation == SMIME_DIGEST_CREATE) { + cms = CMS_digest_create(in, sign_md, flags); + } else if (operation == SMIME_COMPRESS) { + cms = CMS_compress(in, -1, flags); + } else if (operation == SMIME_ENCRYPT) { + flags |= CMS_PARTIAL; + cms = CMS_encrypt(encerts, in, cipher, flags); + if (!cms) + goto end; + if (secret_key) { + if (!CMS_add0_recipient_key(cms, NID_undef, secret_key, + secret_keylen, secret_keyid, secret_keyidlen, + NULL, NULL, NULL)) + goto end; + /* NULL these because call absorbs them */ + secret_key = NULL; + secret_keyid = NULL; + } + if (pwri_pass) { + pwri_tmp = strdup(pwri_pass); + if (!pwri_tmp) + goto end; + if (!CMS_add0_recipient_password(cms, -1, NID_undef, + NID_undef, pwri_tmp, -1, NULL)) + goto end; + pwri_tmp = NULL; + } + if (!(flags & CMS_STREAM)) { + if (!CMS_final(cms, in, NULL, flags)) + goto end; + } + } else if (operation == SMIME_ENCRYPTED_ENCRYPT) { + cms = CMS_EncryptedData_encrypt(in, cipher, secret_key, + secret_keylen, flags); + + } else if (operation == SMIME_SIGN_RECEIPT) { + CMS_ContentInfo *srcms = NULL; + STACK_OF(CMS_SignerInfo) * sis; + CMS_SignerInfo *si; + sis = CMS_get0_SignerInfos(cms); + if (!sis) + goto end; + si = sk_CMS_SignerInfo_value(sis, 0); + srcms = CMS_sign_receipt(si, signer, key, other, flags); + if (!srcms) + goto end; + CMS_ContentInfo_free(cms); + cms = srcms; + } else if (operation & SMIME_SIGNERS) { + int i; + /* + * If detached data content we enable streaming if S/MIME + * output format. + */ + if (operation == SMIME_SIGN) { + + if (flags & CMS_DETACHED) { + if (outformat == FORMAT_SMIME) + flags |= CMS_STREAM; + } + flags |= CMS_PARTIAL; + cms = CMS_sign(NULL, NULL, other, in, flags); + if (!cms) + goto end; + if (econtent_type) + CMS_set1_eContentType(cms, econtent_type); + + if (rr_to) { + rr = make_receipt_request(rr_to, rr_allorfirst, + rr_from); + if (!rr) { + BIO_puts(bio_err, + "Signed Receipt Request Creation Error\n"); + goto end; + } + } + } else + flags |= CMS_REUSE_DIGEST; + for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) { + CMS_SignerInfo *si; + signerfile = sk_OPENSSL_STRING_value(sksigners, i); + keyfile = sk_OPENSSL_STRING_value(skkeys, i); + signer = load_cert(bio_err, signerfile, FORMAT_PEM, + NULL, e, "signer certificate"); + if (!signer) + goto end; + key = load_key(bio_err, keyfile, keyform, 0, passin, e, + "signing key file"); + if (!key) + goto end; + si = CMS_add1_signer(cms, signer, key, sign_md, flags); + if (!si) + goto end; + if (rr && !CMS_add1_ReceiptRequest(si, rr)) + goto end; + X509_free(signer); + signer = NULL; + EVP_PKEY_free(key); + key = NULL; + } + /* If not streaming or resigning finalize structure */ + if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM)) { + if (!CMS_final(cms, in, NULL, flags)) + goto end; + } + } + if (!cms) { + BIO_printf(bio_err, "Error creating CMS structure\n"); + goto end; + } + ret = 4; + if (operation == SMIME_DECRYPT) { + if (flags & CMS_DEBUG_DECRYPT) + CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags); + + if (secret_key) { + if (!CMS_decrypt_set1_key(cms, secret_key, + secret_keylen, secret_keyid, secret_keyidlen)) { + BIO_puts(bio_err, + "Error decrypting CMS using secret key\n"); + goto end; + } + } + if (key) { + if (!CMS_decrypt_set1_pkey(cms, key, recip)) { + BIO_puts(bio_err, + "Error decrypting CMS using private key\n"); + goto end; + } + } + if (pwri_pass) { + if (!CMS_decrypt_set1_password(cms, pwri_pass, -1)) { + BIO_puts(bio_err, + "Error decrypting CMS using password\n"); + goto end; + } + } + if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags)) { + BIO_printf(bio_err, "Error decrypting CMS structure\n"); + goto end; + } + } else if (operation == SMIME_DATAOUT) { + if (!CMS_data(cms, out, flags)) + goto end; + } else if (operation == SMIME_UNCOMPRESS) { + if (!CMS_uncompress(cms, indata, out, flags)) + goto end; + } else if (operation == SMIME_DIGEST_VERIFY) { + if (CMS_digest_verify(cms, indata, out, flags) > 0) + BIO_printf(bio_err, "Verification successful\n"); + else { + BIO_printf(bio_err, "Verification failure\n"); + goto end; + } + } else if (operation == SMIME_ENCRYPTED_DECRYPT) { + if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen, + indata, out, flags)) + goto end; + } else if (operation == SMIME_VERIFY) { + if (CMS_verify(cms, other, store, indata, out, flags) > 0) + BIO_printf(bio_err, "Verification successful\n"); + else { + BIO_printf(bio_err, "Verification failure\n"); + if (verify_retcode) + ret = verify_err + 32; + goto end; + } + if (signerfile) { + STACK_OF(X509) * signers; + signers = CMS_get0_signers(cms); + if (!save_certs(signerfile, signers)) { + BIO_printf(bio_err, + "Error writing signers to %s\n", + signerfile); + ret = 5; + goto end; + } + sk_X509_free(signers); + } + if (rr_print) + receipt_request_print(bio_err, cms); + + } else if (operation == SMIME_VERIFY_RECEIPT) { + if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0) + BIO_printf(bio_err, "Verification successful\n"); + else { + BIO_printf(bio_err, "Verification failure\n"); + goto end; + } + } else { + if (noout) { + if (print) + CMS_ContentInfo_print_ctx(out, cms, 0, NULL); + } else if (outformat == FORMAT_SMIME) { + if (to) + BIO_printf(out, "To: %s\n", to); + if (from) + BIO_printf(out, "From: %s\n", from); + if (subject) + BIO_printf(out, "Subject: %s\n", subject); + if (operation == SMIME_RESIGN) + ret = SMIME_write_CMS(out, cms, indata, flags); + else + ret = SMIME_write_CMS(out, cms, in, flags); + } else if (outformat == FORMAT_PEM) + ret = PEM_write_bio_CMS_stream(out, cms, in, flags); + else if (outformat == FORMAT_ASN1) + ret = i2d_CMS_bio_stream(out, cms, in, flags); + else { + BIO_printf(bio_err, "Bad output format for CMS file\n"); + goto end; + } + if (ret <= 0) { + ret = 6; + goto end; + } + } + ret = 0; + +end: + if (ret) + ERR_print_errors(bio_err); + sk_X509_pop_free(encerts, X509_free); + sk_X509_pop_free(other, X509_free); + if (vpm) + X509_VERIFY_PARAM_free(vpm); + if (sksigners) + sk_OPENSSL_STRING_free(sksigners); + if (skkeys) + sk_OPENSSL_STRING_free(skkeys); + free(secret_key); + free(secret_keyid); + free(pwri_tmp); + if (econtent_type) + ASN1_OBJECT_free(econtent_type); + if (rr) + CMS_ReceiptRequest_free(rr); + if (rr_to) + sk_OPENSSL_STRING_free(rr_to); + if (rr_from) + sk_OPENSSL_STRING_free(rr_from); + X509_STORE_free(store); + X509_free(cert); + X509_free(recip); + X509_free(signer); + EVP_PKEY_free(key); + CMS_ContentInfo_free(cms); + CMS_ContentInfo_free(rcms); + BIO_free(rctin); + BIO_free(in); + BIO_free(indata); + BIO_free_all(out); + free(passin); + return (ret); +} + +static int +save_certs(char *signerfile, STACK_OF(X509) * signers) +{ + int i; + BIO *tmp; + + if (!signerfile) + return 1; + tmp = BIO_new_file(signerfile, "w"); + if (!tmp) + return 0; + for (i = 0; i < sk_X509_num(signers); i++) + PEM_write_bio_X509(tmp, sk_X509_value(signers, i)); + BIO_free(tmp); + return 1; +} + +/* Minimal callback just to output policy info (if any) */ + +static int +cms_cb(int ok, X509_STORE_CTX * ctx) +{ + int error; + + error = X509_STORE_CTX_get_error(ctx); + + verify_err = error; + + if ((error != X509_V_ERR_NO_EXPLICIT_POLICY) && + ((error != X509_V_OK) || (ok != 2))) + return ok; + + policies_print(NULL, ctx); + + return ok; +} + +static void +gnames_stack_print(BIO * out, STACK_OF(GENERAL_NAMES) * gns) +{ + STACK_OF(GENERAL_NAME) * gens; + GENERAL_NAME *gen; + int i, j; + + for (i = 0; i < sk_GENERAL_NAMES_num(gns); i++) { + gens = sk_GENERAL_NAMES_value(gns, i); + for (j = 0; j < sk_GENERAL_NAME_num(gens); j++) { + gen = sk_GENERAL_NAME_value(gens, j); + BIO_puts(out, " "); + GENERAL_NAME_print(out, gen); + BIO_puts(out, "\n"); + } + } + return; +} + +static void +receipt_request_print(BIO * out, CMS_ContentInfo * cms) +{ + STACK_OF(CMS_SignerInfo) * sis; + CMS_SignerInfo *si; + CMS_ReceiptRequest *rr; + int allorfirst; + STACK_OF(GENERAL_NAMES) * rto, *rlist; + ASN1_STRING *scid; + int i, rv; + + sis = CMS_get0_SignerInfos(cms); + for (i = 0; i < sk_CMS_SignerInfo_num(sis); i++) { + si = sk_CMS_SignerInfo_value(sis, i); + rv = CMS_get1_ReceiptRequest(si, &rr); + BIO_printf(bio_err, "Signer %d:\n", i + 1); + if (rv == 0) + BIO_puts(bio_err, " No Receipt Request\n"); + else if (rv < 0) { + BIO_puts(bio_err, " Receipt Request Parse Error\n"); + ERR_print_errors(bio_err); + } else { + char *id; + int idlen; + CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst, + &rlist, &rto); + BIO_puts(out, " Signed Content ID:\n"); + idlen = ASN1_STRING_length(scid); + id = (char *) ASN1_STRING_data(scid); + BIO_dump_indent(out, id, idlen, 4); + BIO_puts(out, " Receipts From"); + if (rlist) { + BIO_puts(out, " List:\n"); + gnames_stack_print(out, rlist); + } else if (allorfirst == 1) + BIO_puts(out, ": First Tier\n"); + else if (allorfirst == 0) + BIO_puts(out, ": All\n"); + else + BIO_printf(out, " Unknown (%d)\n", allorfirst); + BIO_puts(out, " Receipts To:\n"); + gnames_stack_print(out, rto); + } + if (rr) + CMS_ReceiptRequest_free(rr); + } +} + +static STACK_OF(GENERAL_NAMES) * +make_names_stack(STACK_OF(OPENSSL_STRING) * ns) +{ + int i; + STACK_OF(GENERAL_NAMES) * ret; + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gen = NULL; + ret = sk_GENERAL_NAMES_new_null(); + if (!ret) + goto err; + for (i = 0; i < sk_OPENSSL_STRING_num(ns); i++) { + char *str = sk_OPENSSL_STRING_value(ns, i); + gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0); + if (!gen) + goto err; + gens = GENERAL_NAMES_new(); + if (!gens) + goto err; + if (!sk_GENERAL_NAME_push(gens, gen)) + goto err; + gen = NULL; + if (!sk_GENERAL_NAMES_push(ret, gens)) + goto err; + gens = NULL; + } + + return ret; + +err: + if (ret) + sk_GENERAL_NAMES_pop_free(ret, GENERAL_NAMES_free); + if (gens) + GENERAL_NAMES_free(gens); + if (gen) + GENERAL_NAME_free(gen); + return NULL; +} + + +static CMS_ReceiptRequest * +make_receipt_request(STACK_OF(OPENSSL_STRING) * rr_to, int rr_allorfirst, + STACK_OF(OPENSSL_STRING) * rr_from) +{ + STACK_OF(GENERAL_NAMES) * rct_to, *rct_from; + CMS_ReceiptRequest *rr; + + rct_to = make_names_stack(rr_to); + if (!rct_to) + goto err; + if (rr_from) { + rct_from = make_names_stack(rr_from); + if (!rct_from) + goto err; + } else + rct_from = NULL; + rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from, + rct_to); + return rr; + +err: + return NULL; +} + +#endif diff --git a/crypto/libressl/apps/openssl/compat/poll_win.c b/crypto/libressl/apps/openssl/compat/poll_win.c new file mode 100644 index 0000000000..ce47b015c8 --- /dev/null +++ b/crypto/libressl/apps/openssl/compat/poll_win.c @@ -0,0 +1,327 @@ +/* + * Public domain + * + * poll(2) emulation for Windows + * + * This emulates just-enough poll functionality on Windows to work in the + * context of the openssl(1) program. This is not a replacement for + * POSIX.1-2001 poll(2), though it may come closer than I care to admit. + * + * Dongsheng Song + * Brent Cook + */ + +#include +#include +#include +#include +#include + +static int +conn_is_closed(int fd) +{ + char buf[1]; + int ret = recv(fd, buf, 1, MSG_PEEK); + if (ret == -1) { + switch (WSAGetLastError()) { + case WSAECONNABORTED: + case WSAECONNRESET: + case WSAENETRESET: + case WSAESHUTDOWN: + return 1; + } + } + return 0; +} + +static int +conn_has_oob_data(int fd) +{ + char buf[1]; + return (recv(fd, buf, 1, MSG_PEEK | MSG_OOB) == 1); +} + +static int +is_socket(int fd) +{ + if (fd < 3) + return 0; + WSANETWORKEVENTS events; + return (WSAEnumNetworkEvents((SOCKET)fd, NULL, &events) == 0); +} + +static int +compute_select_revents(int fd, short events, + fd_set *rfds, fd_set *wfds, fd_set *efds) +{ + int rc = 0; + + if ((events & (POLLIN | POLLRDNORM | POLLRDBAND)) && + FD_ISSET(fd, rfds)) { + if (conn_is_closed(fd)) + rc |= POLLHUP; + else + rc |= POLLIN | POLLRDNORM; + } + + if ((events & (POLLOUT | POLLWRNORM | POLLWRBAND)) && + FD_ISSET(fd, wfds)) + rc |= POLLOUT; + + if (FD_ISSET(fd, efds)) { + if (conn_is_closed(fd)) + rc |= POLLHUP; + else if (conn_has_oob_data(fd)) + rc |= POLLRDBAND | POLLPRI; + } + + return rc; +} + +static int +compute_wait_revents(HANDLE h, short events, int object, int wait_rc) +{ + int rc = 0; + INPUT_RECORD record; + DWORD num_read; + + /* + * Assume we can always write to file handles (probably a bad + * assumption but works for now, at least it doesn't block). + */ + if (events & (POLLOUT | POLLWRNORM)) + rc |= POLLOUT; + + /* + * Check if this handle was signaled by WaitForMultipleObjects + */ + if (wait_rc >= WAIT_OBJECT_0 && (object == (wait_rc - WAIT_OBJECT_0)) + && (events & (POLLIN | POLLRDNORM))) { + + /* + * Check if this file is stdin, and if so, if it is a console. + */ + if (h == GetStdHandle(STD_INPUT_HANDLE) && + PeekConsoleInput(h, &record, 1, &num_read) == 1) { + + /* + * Handle the input console buffer differently, + * since it can signal on other events like + * window and mouse, but read can still block. + */ + if (record.EventType == KEY_EVENT && + record.Event.KeyEvent.bKeyDown) { + rc |= POLLIN; + } else { + /* + * Flush non-character events from the + * console buffer. + */ + ReadConsoleInput(h, &record, 1, &num_read); + } + } else { + rc |= POLLIN; + } + } + + return rc; +} + +static int +wsa_select_errno(int err) +{ + switch (err) { + case WSAEINTR: + case WSAEINPROGRESS: + errno = EINTR; + break; + case WSAEFAULT: + /* + * Windows uses WSAEFAULT for both resource allocation failures + * and arguments not being contained in the user's address + * space. So, we have to choose EFAULT or ENOMEM. + */ + errno = EFAULT; + break; + case WSAEINVAL: + errno = EINVAL; + break; + case WSANOTINITIALISED: + errno = EPERM; + break; + case WSAENETDOWN: + errno = ENOMEM; + break; + } + return -1; +} + +int +poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) +{ + nfds_t i; + int timespent_ms, looptime_ms; + + /* + * select machinery + */ + fd_set rfds, wfds, efds; + int rc; + int num_sockets; + + /* + * wait machinery + */ + DWORD wait_rc; + HANDLE handles[FD_SETSIZE]; + int num_handles; + + if (pfds == NULL) { + errno = EINVAL; + return -1; + } + + if (nfds <= 0) { + return 0; + } + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&efds); + num_sockets = 0; + num_handles = 0; + + for (i = 0; i < nfds; i++) { + if ((int)pfds[i].fd < 0) + continue; + + if (is_socket(pfds[i].fd)) { + if (num_sockets >= FD_SETSIZE) { + errno = EINVAL; + return -1; + } + + FD_SET(pfds[i].fd, &efds); + + if (pfds[i].events & + (POLLIN | POLLRDNORM | POLLRDBAND)) { + FD_SET(pfds[i].fd, &rfds); + } + + if (pfds[i].events & + (POLLOUT | POLLWRNORM | POLLWRBAND)) { + FD_SET(pfds[i].fd, &wfds); + } + num_sockets++; + + } else { + if (num_handles >= FD_SETSIZE) { + errno = EINVAL; + return -1; + } + + handles[num_handles++] = + (HANDLE)_get_osfhandle(pfds[i].fd); + } + } + + /* + * Determine if the files, pipes, sockets, consoles, etc. have signaled. + * + * Do this by alternating a loop between WaitForMultipleObjects for + * non-sockets and and select for sockets. + * + * I tried to implement this all in terms of WaitForMultipleObjects + * with a select-based 'poll' of the sockets at the end to get extra + * specific socket status. + * + * However, the cost of setting up an event handle for each socket and + * cleaning them up reliably was pretty high. Since the event handle + * associated with a socket is also global, creating a new one here + * cancels one that may exist externally to this function. + * + * At any rate, even if global socket event handles were not an issue, + * the 'FD_WRITE' status of a socket event handle does not behave in an + * expected fashion, being triggered by an edge on a write buffer rather + * than simply triggering if there is space available. + */ + timespent_ms = 0; + wait_rc = WAIT_FAILED; + + if (timeout_ms < 0) + timeout_ms = INFINITE; + looptime_ms = timeout_ms > 100 ? 100 : timeout_ms; + + do { + struct timeval tv = {0, looptime_ms * 1000}; + int handle_signaled = 0; + + /* + * Check if any file handles have signaled + */ + if (num_handles) { + wait_rc = WaitForMultipleObjects(num_handles, handles, + FALSE, 0); + if (wait_rc == WAIT_FAILED) { + /* + * The documentation for WaitForMultipleObjects + * does not specify what values GetLastError + * may return here. Rather than enumerate + * badness like for wsa_select_errno, assume a + * general errno value. + */ + errno = ENOMEM; + return 0; + } + } + + /* + * If we signaled on a file handle, don't wait on the sockets. + */ + if (wait_rc >= WAIT_OBJECT_0 && + (wait_rc <= WAIT_OBJECT_0 + num_handles - 1)) { + tv.tv_usec = 0; + handle_signaled = 1; + } + + /* + * Check if any sockets have signaled + */ + rc = select(0, &rfds, &wfds, &efds, &tv); + if (!handle_signaled && rc == SOCKET_ERROR) + return wsa_select_errno(WSAGetLastError()); + + if (handle_signaled || (num_sockets && rc > 0)) + break; + + timespent_ms += looptime_ms; + + } while (timespent_ms < timeout_ms); + + rc = 0; + num_handles = 0; + for (i = 0; i < nfds; i++) { + pfds[i].revents = 0; + + if ((int)pfds[i].fd < 0) + continue; + + if (is_socket(pfds[i].fd)) { + + pfds[i].revents = compute_select_revents(pfds[i].fd, + pfds[i].events, &rfds, &wfds, &efds); + + } else { + pfds[i].revents = compute_wait_revents( + handles[num_handles], pfds[i].events, num_handles, + wait_rc); + num_handles++; + } + + if (pfds[i].revents) + rc++; + } + + return rc; +} + diff --git a/crypto/libressl/apps/openssl/compat/strtonum.c b/crypto/libressl/apps/openssl/compat/strtonum.c new file mode 100644 index 0000000000..1aeee3467b --- /dev/null +++ b/crypto/libressl/apps/openssl/compat/strtonum.c @@ -0,0 +1,65 @@ +/* $OpenBSD: strtonum.c,v 1.7 2013/04/17 18:40:58 tedu Exp $ */ + +/* + * Copyright (c) 2004 Ted Unangst and Todd Miller + * All rights reserved. + * + * 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 +#include +#include + +#define INVALID 1 +#define TOOSMALL 2 +#define TOOLARGE 3 + +long long +strtonum(const char *numstr, long long minval, long long maxval, + const char **errstrp) +{ + long long ll = 0; + int error = 0; + char *ep; + struct errval { + const char *errstr; + int err; + } ev[4] = { + { NULL, 0 }, + { "invalid", EINVAL }, + { "too small", ERANGE }, + { "too large", ERANGE }, + }; + + ev[0].err = errno; + errno = 0; + if (minval > maxval) { + error = INVALID; + } else { + ll = strtoll(numstr, &ep, 10); + if (numstr == ep || *ep != '\0') + error = INVALID; + else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) + error = TOOSMALL; + else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) + error = TOOLARGE; + } + if (errstrp != NULL) + *errstrp = ev[error].errstr; + errno = ev[error].err; + if (error) + ll = 0; + + return (ll); +} diff --git a/crypto/libressl/apps/openssl/crl.c b/crypto/libressl/apps/openssl/crl.c new file mode 100644 index 0000000000..9fbfe58fb9 --- /dev/null +++ b/crypto/libressl/apps/openssl/crl.c @@ -0,0 +1,477 @@ +/* $OpenBSD: crl.c,v 1.8 2015/10/10 22:28:51 doug Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "apps.h" + +#include +#include +#include +#include +#include + +static struct { + char *cafile; + char *capath; + int crlnumber; + int fingerprint; + int hash; + int hash_old; + char *infile; + int informat; + int issuer; + int lastupdate; + char *nameopt; + int nextupdate; + int noout; + char *outfile; + int outformat; + int text; + int verify; +} crl_config; + +static struct option crl_options[] = { + { + .name = "CAfile", + .argname = "file", + .desc = "Verify the CRL using certificates in the given file", + .type = OPTION_ARG, + .opt.arg = &crl_config.cafile, + }, + { + .name = "CApath", + .argname = "path", + .desc = "Verify the CRL using certificates in the given path", + .type = OPTION_ARG, + .opt.arg = &crl_config.capath, + }, + { + .name = "crlnumber", + .desc = "Print the CRL number", + .type = OPTION_FLAG_ORD, + .opt.flag = &crl_config.crlnumber, + }, + { + .name = "fingerprint", + .desc = "Print the CRL fingerprint", + .type = OPTION_FLAG_ORD, + .opt.flag = &crl_config.fingerprint, + }, + { + .name = "hash", + .desc = "Print the hash of the issuer name", + .type = OPTION_FLAG_ORD, + .opt.flag = &crl_config.hash, + }, + { + .name = "hash_old", + .desc = "Print an old-style (MD5) hash of the issuer name", + .type = OPTION_FLAG_ORD, + .opt.flag = &crl_config.hash_old, + }, + { + .name = "in", + .argname = "file", + .desc = "Input file to read from (stdin if unspecified)", + .type = OPTION_ARG, + .opt.arg = &crl_config.infile, + }, + { + .name = "inform", + .argname = "format", + .desc = "Input format (DER or PEM)", + .type = OPTION_ARG_FORMAT, + .opt.value = &crl_config.informat, + }, + { + .name = "issuer", + .desc = "Print the issuer name", + .type = OPTION_FLAG_ORD, + .opt.flag = &crl_config.issuer, + }, + { + .name = "lastupdate", + .desc = "Print the lastUpdate field", + .type = OPTION_FLAG_ORD, + .opt.flag = &crl_config.lastupdate, + }, + { + .name = "nameopt", + .argname = "options", + .desc = "Specify certificate name options", + .type = OPTION_ARG, + .opt.arg = &crl_config.nameopt, + }, + { + .name = "nextupdate", + .desc = "Print the nextUpdate field", + .type = OPTION_FLAG_ORD, + .opt.flag = &crl_config.nextupdate, + }, + { + .name = "noout", + .desc = "Do not output the encoded version of the CRL", + .type = OPTION_FLAG, + .opt.flag = &crl_config.noout, + }, + { + .name = "out", + .argname = "file", + .desc = "Output file to write to (stdout if unspecified)", + .type = OPTION_ARG, + .opt.arg = &crl_config.outfile, + }, + { + .name = "outform", + .argname = "format", + .desc = "Output format (DER or PEM)", + .type = OPTION_ARG_FORMAT, + .opt.value = &crl_config.outformat, + }, + { + .name = "text", + .desc = "Print out the CRL in text form", + .type = OPTION_FLAG, + .opt.flag = &crl_config.text, + }, + { + .name = "verify", + .desc = "Verify the signature on the CRL", + .type = OPTION_FLAG, + .opt.flag = &crl_config.verify, + }, + {NULL}, +}; + +static void +crl_usage(void) +{ + fprintf(stderr, + "usage: crl [-CAfile file] [-CApath dir] [-fingerprint] [-hash]\n" + " [-in file] [-inform DER | PEM] [-issuer] [-lastupdate]\n" + " [-nextupdate] [-noout] [-out file] [-outform DER | PEM]\n" + " [-text]\n\n"); + options_usage(crl_options); +} + +static X509_CRL *load_crl(char *file, int format); +static BIO *bio_out = NULL; + +int +crl_main(int argc, char **argv) +{ + unsigned long nmflag = 0; + X509_CRL *x = NULL; + int ret = 1, i; + BIO *out = NULL; + X509_STORE *store = NULL; + X509_STORE_CTX ctx; + X509_LOOKUP *lookup = NULL; + X509_OBJECT xobj; + EVP_PKEY *pkey; + const EVP_MD *digest; + char *digest_name = NULL; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + if (bio_out == NULL) { + if ((bio_out = BIO_new(BIO_s_file())) != NULL) { + BIO_set_fp(bio_out, stdout, BIO_NOCLOSE); + } + } + + digest = EVP_sha1(); + + memset(&crl_config, 0, sizeof(crl_config)); + crl_config.informat = FORMAT_PEM; + crl_config.outformat = FORMAT_PEM; + + if (options_parse(argc, argv, crl_options, &digest_name, NULL) != 0) { + crl_usage(); + goto end; + } + + if (crl_config.cafile != NULL || crl_config.capath != NULL) + crl_config.verify = 1; + + if (crl_config.nameopt != NULL) { + if (set_name_ex(&nmflag, crl_config.nameopt) != 1) { + fprintf(stderr, + "Invalid -nameopt argument '%s'\n", + crl_config.nameopt); + goto end; + } + } + + if (digest_name != NULL) { + if ((digest = EVP_get_digestbyname(digest_name)) == NULL) { + fprintf(stderr, + "Unknown message digest algorithm '%s'\n", + digest_name); + goto end; + } + } + + x = load_crl(crl_config.infile, crl_config.informat); + if (x == NULL) + goto end; + + if (crl_config.verify) { + store = X509_STORE_new(); + lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); + if (lookup == NULL) + goto end; + if (!X509_LOOKUP_load_file(lookup, crl_config.cafile, + X509_FILETYPE_PEM)) + X509_LOOKUP_load_file(lookup, NULL, + X509_FILETYPE_DEFAULT); + + lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); + if (lookup == NULL) + goto end; + if (!X509_LOOKUP_add_dir(lookup, crl_config.capath, + X509_FILETYPE_PEM)) + X509_LOOKUP_add_dir(lookup, NULL, + X509_FILETYPE_DEFAULT); + ERR_clear_error(); + + if (!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) { + BIO_printf(bio_err, + "Error initialising X509 store\n"); + goto end; + } + i = X509_STORE_get_by_subject(&ctx, X509_LU_X509, + X509_CRL_get_issuer(x), &xobj); + if (i <= 0) { + BIO_printf(bio_err, + "Error getting CRL issuer certificate\n"); + goto end; + } + pkey = X509_get_pubkey(xobj.data.x509); + X509_OBJECT_free_contents(&xobj); + if (!pkey) { + BIO_printf(bio_err, + "Error getting CRL issuer public key\n"); + goto end; + } + i = X509_CRL_verify(x, pkey); + EVP_PKEY_free(pkey); + if (i < 0) + goto end; + if (i == 0) + BIO_printf(bio_err, "verify failure\n"); + else + BIO_printf(bio_err, "verify OK\n"); + } + + /* Print requested information the order that the flags were given. */ + for (i = 1; i <= argc; i++) { + if (crl_config.issuer == i) { + print_name(bio_out, "issuer=", + X509_CRL_get_issuer(x), nmflag); + } + if (crl_config.crlnumber == i) { + ASN1_INTEGER *crlnum; + crlnum = X509_CRL_get_ext_d2i(x, + NID_crl_number, NULL, NULL); + BIO_printf(bio_out, "crlNumber="); + if (crlnum) { + i2a_ASN1_INTEGER(bio_out, crlnum); + ASN1_INTEGER_free(crlnum); + } else + BIO_puts(bio_out, ""); + BIO_printf(bio_out, "\n"); + } + if (crl_config.hash == i) { + BIO_printf(bio_out, "%08lx\n", + X509_NAME_hash(X509_CRL_get_issuer(x))); + } +#ifndef OPENSSL_NO_MD5 + if (crl_config.hash_old == i) { + BIO_printf(bio_out, "%08lx\n", + X509_NAME_hash_old(X509_CRL_get_issuer(x))); + } +#endif + if (crl_config.lastupdate == i) { + BIO_printf(bio_out, "lastUpdate="); + ASN1_TIME_print(bio_out, + X509_CRL_get_lastUpdate(x)); + BIO_printf(bio_out, "\n"); + } + if (crl_config.nextupdate == i) { + BIO_printf(bio_out, "nextUpdate="); + if (X509_CRL_get_nextUpdate(x)) + ASN1_TIME_print(bio_out, + X509_CRL_get_nextUpdate(x)); + else + BIO_printf(bio_out, "NONE"); + BIO_printf(bio_out, "\n"); + } + if (crl_config.fingerprint == i) { + int j; + unsigned int n; + unsigned char md[EVP_MAX_MD_SIZE]; + + if (!X509_CRL_digest(x, digest, md, &n)) { + BIO_printf(bio_err, "out of memory\n"); + goto end; + } + BIO_printf(bio_out, "%s Fingerprint=", + OBJ_nid2sn(EVP_MD_type(digest))); + for (j = 0; j < (int) n; j++) { + BIO_printf(bio_out, "%02X%c", md[j], + (j + 1 == (int)n) ? '\n' : ':'); + } + } + } + + out = BIO_new(BIO_s_file()); + if (out == NULL) { + ERR_print_errors(bio_err); + goto end; + } + if (crl_config.outfile == NULL) { + BIO_set_fp(out, stdout, BIO_NOCLOSE); + } else { + if (BIO_write_filename(out, crl_config.outfile) <= 0) { + perror(crl_config.outfile); + goto end; + } + } + + if (crl_config.text) + X509_CRL_print(out, x); + + if (crl_config.noout) { + ret = 0; + goto end; + } + if (crl_config.outformat == FORMAT_ASN1) + i = (int) i2d_X509_CRL_bio(out, x); + else if (crl_config.outformat == FORMAT_PEM) + i = PEM_write_bio_X509_CRL(out, x); + else { + BIO_printf(bio_err, + "bad output format specified for outfile\n"); + goto end; + } + if (!i) { + BIO_printf(bio_err, "unable to write CRL\n"); + goto end; + } + ret = 0; + +end: + BIO_free_all(out); + BIO_free_all(bio_out); + bio_out = NULL; + X509_CRL_free(x); + if (store) { + X509_STORE_CTX_cleanup(&ctx); + X509_STORE_free(store); + } + + return (ret); +} + +static X509_CRL * +load_crl(char *infile, int format) +{ + X509_CRL *x = NULL; + BIO *in = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + ERR_print_errors(bio_err); + goto end; + } + if (infile == NULL) + BIO_set_fp(in, stdin, BIO_NOCLOSE); + else { + if (BIO_read_filename(in, infile) <= 0) { + perror(infile); + goto end; + } + } + if (format == FORMAT_ASN1) + x = d2i_X509_CRL_bio(in, NULL); + else if (format == FORMAT_PEM) + x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); + else { + BIO_printf(bio_err, + "bad input format specified for input crl\n"); + goto end; + } + if (x == NULL) { + BIO_printf(bio_err, "unable to load CRL\n"); + ERR_print_errors(bio_err); + goto end; + } + +end: + BIO_free(in); + return (x); +} diff --git a/crypto/libressl/apps/openssl/crl2p7.c b/crypto/libressl/apps/openssl/crl2p7.c new file mode 100644 index 0000000000..89ee367974 --- /dev/null +++ b/crypto/libressl/apps/openssl/crl2p7.c @@ -0,0 +1,333 @@ +/* $OpenBSD: crl2p7.c,v 1.5 2015/10/10 22:28:51 doug Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* This was written by Gordon Chaffee + * and donated 'to the cause' along with lots and lots of other fixes to + * the library. */ + +#include + +#include +#include + +#include "apps.h" + +#include +#include +#include +#include +#include +#include + +static int add_certs_from_file(STACK_OF(X509) * stack, char *certfile); + +static struct { + STACK_OF(OPENSSL_STRING) *certflst; + char *infile; + int informat; + int nocrl; + char *outfile; + int outformat; +} crl2p7_config; + +static int +crl2p7_opt_certfile(char *arg) +{ + if (crl2p7_config.certflst == NULL) + crl2p7_config.certflst = sk_OPENSSL_STRING_new_null(); + if (crl2p7_config.certflst == NULL) { + fprintf(stderr, "out of memory\n"); + return (1); + } + if (!sk_OPENSSL_STRING_push(crl2p7_config.certflst, arg)) { + fprintf(stderr, "out of memory\n"); + return (1); + } + + return (0); +} + +static struct option crl2p7_options[] = { + { + .name = "certfile", + .argname = "file", + .desc = "Chain of PEM certificates to a trusted CA", + .type = OPTION_ARG_FUNC, + .opt.argfunc = crl2p7_opt_certfile, + }, + { + .name = "in", + .argname = "file", + .desc = "Input file (default stdin)", + .type = OPTION_ARG, + .opt.arg = &crl2p7_config.infile, + }, + { + .name = "inform", + .argname = "format", + .desc = "Input format (DER or PEM (default))", + .type = OPTION_ARG_FORMAT, + .opt.value = &crl2p7_config.informat, + }, + { + .name = "nocrl", + .desc = "Do not read CRL from input or include CRL in output", + .type = OPTION_FLAG, + .opt.flag = &crl2p7_config.nocrl, + }, + { + .name = "out", + .argname = "file", + .desc = "Output file (default stdout)", + .type = OPTION_ARG, + .opt.arg = &crl2p7_config.outfile, + }, + { + .name = "outform", + .argname = "format", + .desc = "Output format (DER or PEM (default))", + .type = OPTION_ARG_FORMAT, + .opt.value = &crl2p7_config.outformat, + }, + { NULL }, +}; + +static void +crl2p7_usage(void) +{ + fprintf(stderr, + "usage: crl2p7 [-certfile file] [-in file] [-inform DER | PEM]\n" + " [-nocrl] [-out file] [-outform DER | PEM]\n\n"); + options_usage(crl2p7_options); +} + +int +crl2pkcs7_main(int argc, char **argv) +{ + int i; + BIO *in = NULL, *out = NULL; + char *certfile; + PKCS7 *p7 = NULL; + PKCS7_SIGNED *p7s = NULL; + X509_CRL *crl = NULL; + STACK_OF(X509_CRL) *crl_stack = NULL; + STACK_OF(X509) *cert_stack = NULL; + int ret = 1; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + memset(&crl2p7_config, 0, sizeof(crl2p7_config)); + + crl2p7_config.informat = FORMAT_PEM; + crl2p7_config.outformat = FORMAT_PEM; + + if (options_parse(argc, argv, crl2p7_options, NULL, NULL) != 0) { + crl2p7_usage(); + goto end; + } + + in = BIO_new(BIO_s_file()); + out = BIO_new(BIO_s_file()); + if (in == NULL || out == NULL) { + ERR_print_errors(bio_err); + goto end; + } + if (!crl2p7_config.nocrl) { + if (crl2p7_config.infile == NULL) + BIO_set_fp(in, stdin, BIO_NOCLOSE); + else { + if (BIO_read_filename(in, crl2p7_config.infile) <= 0) { + perror(crl2p7_config.infile); + goto end; + } + } + + if (crl2p7_config.informat == FORMAT_ASN1) + crl = d2i_X509_CRL_bio(in, NULL); + else if (crl2p7_config.informat == FORMAT_PEM) + crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); + else { + BIO_printf(bio_err, + "bad input format specified for input crl\n"); + goto end; + } + if (crl == NULL) { + BIO_printf(bio_err, "unable to load CRL\n"); + ERR_print_errors(bio_err); + goto end; + } + } + if ((p7 = PKCS7_new()) == NULL) + goto end; + if ((p7s = PKCS7_SIGNED_new()) == NULL) + goto end; + p7->type = OBJ_nid2obj(NID_pkcs7_signed); + p7->d.sign = p7s; + p7s->contents->type = OBJ_nid2obj(NID_pkcs7_data); + + if (!ASN1_INTEGER_set(p7s->version, 1)) + goto end; + if ((crl_stack = sk_X509_CRL_new_null()) == NULL) + goto end; + p7s->crl = crl_stack; + if (crl != NULL) { + sk_X509_CRL_push(crl_stack, crl); + crl = NULL; /* now part of p7 for freeing */ + } + if ((cert_stack = sk_X509_new_null()) == NULL) + goto end; + p7s->cert = cert_stack; + + if (crl2p7_config.certflst) { + for (i = 0; i < sk_OPENSSL_STRING_num(crl2p7_config.certflst); i++) { + certfile = sk_OPENSSL_STRING_value(crl2p7_config.certflst, i); + if (add_certs_from_file(cert_stack, certfile) < 0) { + BIO_printf(bio_err, + "error loading certificates\n"); + ERR_print_errors(bio_err); + goto end; + } + } + } + + sk_OPENSSL_STRING_free(crl2p7_config.certflst); + + if (crl2p7_config.outfile == NULL) { + BIO_set_fp(out, stdout, BIO_NOCLOSE); + } else { + if (BIO_write_filename(out, crl2p7_config.outfile) <= 0) { + perror(crl2p7_config.outfile); + goto end; + } + } + + if (crl2p7_config.outformat == FORMAT_ASN1) + i = i2d_PKCS7_bio(out, p7); + else if (crl2p7_config.outformat == FORMAT_PEM) + i = PEM_write_bio_PKCS7(out, p7); + else { + BIO_printf(bio_err, + "bad output format specified for outfile\n"); + goto end; + } + if (!i) { + BIO_printf(bio_err, "unable to write pkcs7 object\n"); + ERR_print_errors(bio_err); + goto end; + } + ret = 0; + +end: + if (in != NULL) + BIO_free(in); + if (out != NULL) + BIO_free_all(out); + if (p7 != NULL) + PKCS7_free(p7); + if (crl != NULL) + X509_CRL_free(crl); + + return (ret); +} + +static int +add_certs_from_file(STACK_OF(X509) *stack, char *certfile) +{ + BIO *in = NULL; + int count = 0; + int ret = -1; + STACK_OF(X509_INFO) *sk = NULL; + X509_INFO *xi; + + in = BIO_new(BIO_s_file()); + if (in == NULL || BIO_read_filename(in, certfile) <= 0) { + BIO_printf(bio_err, "error opening the file, %s\n", certfile); + goto end; + } + /* This loads from a file, a stack of x509/crl/pkey sets */ + sk = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); + if (sk == NULL) { + BIO_printf(bio_err, "error reading the file, %s\n", certfile); + goto end; + } + /* scan over it and pull out the CRL's */ + while (sk_X509_INFO_num(sk)) { + xi = sk_X509_INFO_shift(sk); + if (xi->x509 != NULL) { + sk_X509_push(stack, xi->x509); + xi->x509 = NULL; + count++; + } + X509_INFO_free(xi); + } + + ret = count; + +end: + /* never need to free x */ + if (in != NULL) + BIO_free(in); + if (sk != NULL) + sk_X509_INFO_free(sk); + return (ret); +} diff --git a/crypto/libressl/apps/openssl/dgst.c b/crypto/libressl/apps/openssl/dgst.c new file mode 100644 index 0000000000..480eaffd0c --- /dev/null +++ b/crypto/libressl/apps/openssl/dgst.c @@ -0,0 +1,544 @@ +/* $OpenBSD: dgst.c,v 1.8 2015/10/17 07:51:10 semarie Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "apps.h" + +#include +#include +#include +#include +#include +#include +#include + +#define BUFSIZE 1024*8 + +int +do_fp(BIO * out, unsigned char *buf, BIO * bp, int sep, int binout, + EVP_PKEY * key, unsigned char *sigin, int siglen, + const char *sig_name, const char *md_name, + const char *file, BIO * bmd); + +static void +list_md_fn(const EVP_MD * m, const char *from, const char *to, void *arg) +{ + const char *mname; + /* Skip aliases */ + if (!m) + return; + mname = OBJ_nid2ln(EVP_MD_type(m)); + /* Skip shortnames */ + if (strcmp(from, mname)) + return; + /* Skip clones */ + if (EVP_MD_flags(m) & EVP_MD_FLAG_PKEY_DIGEST) + return; + if (strchr(mname, ' ')) + mname = EVP_MD_name(m); + BIO_printf(arg, "-%-14s to use the %s message digest algorithm\n", + mname, mname); +} + +int +dgst_main(int argc, char **argv) +{ + unsigned char *buf = NULL; + int i, err = 1; + const EVP_MD *md = NULL, *m; + BIO *in = NULL, *inp; + BIO *bmd = NULL; + BIO *out = NULL; +#define PROG_NAME_SIZE 39 + char pname[PROG_NAME_SIZE + 1]; + int separator = 0; + int debug = 0; + int keyform = FORMAT_PEM; + const char *outfile = NULL, *keyfile = NULL; + const char *sigfile = NULL; + int out_bin = -1, want_pub = 0, do_verify = 0; + EVP_PKEY *sigkey = NULL; + unsigned char *sigbuf = NULL; + int siglen = 0; + char *passargin = NULL, *passin = NULL; + char *hmac_key = NULL; + char *mac_name = NULL; + STACK_OF(OPENSSL_STRING) * sigopts = NULL, *macopts = NULL; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + if ((buf = malloc(BUFSIZE)) == NULL) { + BIO_printf(bio_err, "out of memory\n"); + goto end; + } + + /* first check the program name */ + program_name(argv[0], pname, sizeof pname); + + md = EVP_get_digestbyname(pname); + + argc--; + argv++; + while (argc > 0) { + if ((*argv)[0] != '-') + break; + if (strcmp(*argv, "-c") == 0) + separator = 1; + else if (strcmp(*argv, "-r") == 0) + separator = 2; + else if (strcmp(*argv, "-out") == 0) { + if (--argc < 1) + break; + outfile = *(++argv); + } else if (strcmp(*argv, "-sign") == 0) { + if (--argc < 1) + break; + keyfile = *(++argv); + } else if (!strcmp(*argv, "-passin")) { + if (--argc < 1) + break; + passargin = *++argv; + } else if (strcmp(*argv, "-verify") == 0) { + if (--argc < 1) + break; + keyfile = *(++argv); + want_pub = 1; + do_verify = 1; + } else if (strcmp(*argv, "-prverify") == 0) { + if (--argc < 1) + break; + keyfile = *(++argv); + do_verify = 1; + } else if (strcmp(*argv, "-signature") == 0) { + if (--argc < 1) + break; + sigfile = *(++argv); + } else if (strcmp(*argv, "-keyform") == 0) { + if (--argc < 1) + break; + keyform = str2fmt(*(++argv)); + } + else if (strcmp(*argv, "-hex") == 0) + out_bin = 0; + else if (strcmp(*argv, "-binary") == 0) + out_bin = 1; + else if (strcmp(*argv, "-d") == 0) + debug = 1; + else if (!strcmp(*argv, "-hmac")) { + if (--argc < 1) + break; + hmac_key = *++argv; + } else if (!strcmp(*argv, "-mac")) { + if (--argc < 1) + break; + mac_name = *++argv; + } else if (strcmp(*argv, "-sigopt") == 0) { + if (--argc < 1) + break; + if (!sigopts) + sigopts = sk_OPENSSL_STRING_new_null(); + if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv))) + break; + } else if (strcmp(*argv, "-macopt") == 0) { + if (--argc < 1) + break; + if (!macopts) + macopts = sk_OPENSSL_STRING_new_null(); + if (!macopts || !sk_OPENSSL_STRING_push(macopts, *(++argv))) + break; + } else if ((m = EVP_get_digestbyname(&((*argv)[1]))) != NULL) + md = m; + else + break; + argc--; + argv++; + } + + + if (do_verify && !sigfile) { + BIO_printf(bio_err, "No signature to verify: use the -signature option\n"); + goto end; + } + if ((argc > 0) && (argv[0][0] == '-')) { /* bad option */ + BIO_printf(bio_err, "unknown option '%s'\n", *argv); + BIO_printf(bio_err, "options are\n"); + BIO_printf(bio_err, "-c to output the digest with separating colons\n"); + BIO_printf(bio_err, "-r to output the digest in coreutils format\n"); + BIO_printf(bio_err, "-d to output debug info\n"); + BIO_printf(bio_err, "-hex output as hex dump\n"); + BIO_printf(bio_err, "-binary output in binary form\n"); + BIO_printf(bio_err, "-sign file sign digest using private key in file\n"); + BIO_printf(bio_err, "-verify file verify a signature using public key in file\n"); + BIO_printf(bio_err, "-prverify file verify a signature using private key in file\n"); + BIO_printf(bio_err, "-keyform arg key file format (PEM)\n"); + BIO_printf(bio_err, "-out filename output to filename rather than stdout\n"); + BIO_printf(bio_err, "-signature file signature to verify\n"); + BIO_printf(bio_err, "-sigopt nm:v signature parameter\n"); + BIO_printf(bio_err, "-hmac key create hashed MAC with key\n"); + BIO_printf(bio_err, "-mac algorithm create MAC (not neccessarily HMAC)\n"); + BIO_printf(bio_err, "-macopt nm:v MAC algorithm parameters or key\n"); + + EVP_MD_do_all_sorted(list_md_fn, bio_err); + goto end; + } + + in = BIO_new(BIO_s_file()); + bmd = BIO_new(BIO_f_md()); + if (in == NULL || bmd == NULL) { + ERR_print_errors(bio_err); + goto end; + } + + if (debug) { + BIO_set_callback(in, BIO_debug_callback); + /* needed for windows 3.1 */ + BIO_set_callback_arg(in, (char *) bio_err); + } + if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { + BIO_printf(bio_err, "Error getting password\n"); + goto end; + } + if (out_bin == -1) { + if (keyfile) + out_bin = 1; + else + out_bin = 0; + } + + if (outfile) { + if (out_bin) + out = BIO_new_file(outfile, "wb"); + else + out = BIO_new_file(outfile, "w"); + } else { + out = BIO_new_fp(stdout, BIO_NOCLOSE); + } + + if (!out) { + BIO_printf(bio_err, "Error opening output file %s\n", + outfile ? outfile : "(stdout)"); + ERR_print_errors(bio_err); + goto end; + } + if ((!!mac_name + !!keyfile + !!hmac_key) > 1) { + BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n"); + goto end; + } + if (keyfile) { + if (want_pub) + sigkey = load_pubkey(bio_err, keyfile, keyform, 0, NULL, + "key file"); + else + sigkey = load_key(bio_err, keyfile, keyform, 0, passin, + "key file"); + if (!sigkey) { + /* + * load_[pub]key() has already printed an appropriate + * message + */ + goto end; + } + } + if (mac_name) { + EVP_PKEY_CTX *mac_ctx = NULL; + int r = 0; + if (!init_gen_str(bio_err, &mac_ctx, mac_name, 0)) + goto mac_end; + if (macopts) { + char *macopt; + for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) { + macopt = sk_OPENSSL_STRING_value(macopts, i); + if (pkey_ctrl_string(mac_ctx, macopt) <= 0) { + BIO_printf(bio_err, + "MAC parameter error \"%s\"\n", + macopt); + ERR_print_errors(bio_err); + goto mac_end; + } + } + } + if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) { + BIO_puts(bio_err, "Error generating key\n"); + ERR_print_errors(bio_err); + goto mac_end; + } + r = 1; +mac_end: + if (mac_ctx) + EVP_PKEY_CTX_free(mac_ctx); + if (r == 0) + goto end; + } + if (hmac_key) { + sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, + (unsigned char *) hmac_key, -1); + if (!sigkey) + goto end; + } + if (sigkey) { + EVP_MD_CTX *mctx = NULL; + EVP_PKEY_CTX *pctx = NULL; + int r; + if (!BIO_get_md_ctx(bmd, &mctx)) { + BIO_printf(bio_err, "Error getting context\n"); + ERR_print_errors(bio_err); + goto end; + } + if (do_verify) + r = EVP_DigestVerifyInit(mctx, &pctx, md, NULL, sigkey); + else + r = EVP_DigestSignInit(mctx, &pctx, md, NULL, sigkey); + if (!r) { + BIO_printf(bio_err, "Error setting context\n"); + ERR_print_errors(bio_err); + goto end; + } + if (sigopts) { + char *sigopt; + for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { + sigopt = sk_OPENSSL_STRING_value(sigopts, i); + if (pkey_ctrl_string(pctx, sigopt) <= 0) { + BIO_printf(bio_err, + "parameter error \"%s\"\n", + sigopt); + ERR_print_errors(bio_err); + goto end; + } + } + } + } + /* we use md as a filter, reading from 'in' */ + else { + if (md == NULL) + md = EVP_md5(); + if (!BIO_set_md(bmd, md)) { + BIO_printf(bio_err, "Error setting digest %s\n", pname); + ERR_print_errors(bio_err); + goto end; + } + } + + if (sigfile && sigkey) { + BIO *sigbio; + siglen = EVP_PKEY_size(sigkey); + sigbuf = malloc(siglen); + if (sigbuf == NULL) { + BIO_printf(bio_err, "out of memory\n"); + ERR_print_errors(bio_err); + goto end; + } + sigbio = BIO_new_file(sigfile, "rb"); + if (!sigbio) { + BIO_printf(bio_err, "Error opening signature file %s\n", + sigfile); + ERR_print_errors(bio_err); + goto end; + } + siglen = BIO_read(sigbio, sigbuf, siglen); + BIO_free(sigbio); + if (siglen <= 0) { + BIO_printf(bio_err, "Error reading signature file %s\n", + sigfile); + ERR_print_errors(bio_err); + goto end; + } + } + inp = BIO_push(bmd, in); + + if (md == NULL) { + EVP_MD_CTX *tctx; + BIO_get_md_ctx(bmd, &tctx); + md = EVP_MD_CTX_md(tctx); + } + if (argc == 0) { + BIO_set_fp(in, stdin, BIO_NOCLOSE); + err = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, + siglen, NULL, NULL, "stdin", bmd); + } else { + const char *md_name = NULL, *sig_name = NULL; + if (!out_bin) { + if (sigkey) { + const EVP_PKEY_ASN1_METHOD *ameth; + ameth = EVP_PKEY_get0_asn1(sigkey); + if (ameth) + EVP_PKEY_asn1_get0_info(NULL, NULL, + NULL, NULL, &sig_name, ameth); + } + md_name = EVP_MD_name(md); + } + err = 0; + for (i = 0; i < argc; i++) { + int r; + if (BIO_read_filename(in, argv[i]) <= 0) { + perror(argv[i]); + err++; + continue; + } else { + r = do_fp(out, buf, inp, separator, out_bin, + sigkey, sigbuf, siglen, sig_name, md_name, + argv[i], bmd); + } + if (r) + err = r; + (void) BIO_reset(bmd); + } + } + +end: + if (buf != NULL) { + explicit_bzero(buf, BUFSIZE); + free(buf); + } + if (in != NULL) + BIO_free(in); + free(passin); + BIO_free_all(out); + EVP_PKEY_free(sigkey); + if (sigopts) + sk_OPENSSL_STRING_free(sigopts); + if (macopts) + sk_OPENSSL_STRING_free(macopts); + free(sigbuf); + if (bmd != NULL) + BIO_free(bmd); + + return (err); +} + +int +do_fp(BIO * out, unsigned char *buf, BIO * bp, int sep, int binout, + EVP_PKEY * key, unsigned char *sigin, int siglen, + const char *sig_name, const char *md_name, + const char *file, BIO * bmd) +{ + size_t len; + int i; + + for (;;) { + i = BIO_read(bp, (char *) buf, BUFSIZE); + if (i < 0) { + BIO_printf(bio_err, "Read Error in %s\n", file); + ERR_print_errors(bio_err); + return 1; + } + if (i == 0) + break; + } + if (sigin) { + EVP_MD_CTX *ctx; + BIO_get_md_ctx(bp, &ctx); + i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int) siglen); + if (i > 0) + BIO_printf(out, "Verified OK\n"); + else if (i == 0) { + BIO_printf(out, "Verification Failure\n"); + return 1; + } else { + BIO_printf(bio_err, "Error Verifying Data\n"); + ERR_print_errors(bio_err); + return 1; + } + return 0; + } + if (key) { + EVP_MD_CTX *ctx; + BIO_get_md_ctx(bp, &ctx); + len = BUFSIZE; + if (!EVP_DigestSignFinal(ctx, buf, &len)) { + BIO_printf(bio_err, "Error Signing Data\n"); + ERR_print_errors(bio_err); + return 1; + } + } else { + len = BIO_gets(bp, (char *) buf, BUFSIZE); + if ((int) len < 0) { + ERR_print_errors(bio_err); + return 1; + } + } + + if (binout) + BIO_write(out, buf, len); + else if (sep == 2) { + for (i = 0; i < (int) len; i++) + BIO_printf(out, "%02x", buf[i]); + BIO_printf(out, " *%s\n", file); + } else { + if (sig_name) + BIO_printf(out, "%s-%s(%s)= ", sig_name, md_name, file); + else if (md_name) + BIO_printf(out, "%s(%s)= ", md_name, file); + else + BIO_printf(out, "(%s)= ", file); + for (i = 0; i < (int) len; i++) { + if (sep && (i != 0)) + BIO_printf(out, ":"); + BIO_printf(out, "%02x", buf[i]); + } + BIO_printf(out, "\n"); + } + return 0; +} diff --git a/crypto/libressl/apps/openssl/dh.c b/crypto/libressl/apps/openssl/dh.c new file mode 100644 index 0000000000..c6f84aad73 --- /dev/null +++ b/crypto/libressl/apps/openssl/dh.c @@ -0,0 +1,300 @@ +/* $OpenBSD: dh.c,v 1.7 2015/10/10 22:28:51 doug Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include /* for OPENSSL_NO_DH */ + +#ifndef OPENSSL_NO_DH + +#include +#include +#include +#include + +#include "apps.h" + +#include +#include +#include +#include +#include +#include + +static struct { + int C; + int check; + char *infile; + int informat; + int noout; + char *outfile; + int outformat; + int text; +} dh_config; + +static struct option dh_options[] = { + { + .name = "C", + .desc = "Convert DH parameters into C code", + .type = OPTION_FLAG, + .opt.flag = &dh_config.C, + }, + { + .name = "check", + .desc = "Check the DH parameters", + .type = OPTION_FLAG, + .opt.flag = &dh_config.check, + }, + { + .name = "in", + .argname = "file", + .desc = "Input file (default stdin)", + .type = OPTION_ARG, + .opt.arg = &dh_config.infile, + }, + { + .name = "inform", + .argname = "format", + .desc = "Input format (DER or PEM (default))", + .type = OPTION_ARG_FORMAT, + .opt.value = &dh_config.informat, + }, + { + .name = "noout", + .desc = "No output", + .type = OPTION_FLAG, + .opt.flag = &dh_config.noout, + }, + { + .name = "out", + .argname = "file", + .desc = "Output file (default stdout)", + .type = OPTION_ARG, + .opt.arg = &dh_config.outfile, + }, + { + .name = "outform", + .argname = "format", + .desc = "Output format (DER or PEM (default))", + .type = OPTION_ARG_FORMAT, + .opt.value = &dh_config.outformat, + }, + { + .name = "text", + .desc = "Print a text form of the DH parameters", + .type = OPTION_FLAG, + .opt.flag = &dh_config.text, + }, + { NULL }, +}; + +static void +dh_usage(void) +{ + fprintf(stderr, + "usage: dh [-C] [-check] [-in file] [-inform format]\n" + " [-noout] [-out file] [-outform format] [-text]\n\n"); + options_usage(dh_options); +} + +int +dh_main(int argc, char **argv) +{ + DH *dh = NULL; + int i; + BIO *in = NULL, *out = NULL; + int ret = 1; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + memset(&dh_config, 0, sizeof(dh_config)); + + dh_config.informat = FORMAT_PEM; + dh_config.outformat = FORMAT_PEM; + + if (options_parse(argc, argv, dh_options, NULL, NULL) != 0) { + dh_usage(); + goto end; + } + + in = BIO_new(BIO_s_file()); + out = BIO_new(BIO_s_file()); + if (in == NULL || out == NULL) { + ERR_print_errors(bio_err); + goto end; + } + if (dh_config.infile == NULL) + BIO_set_fp(in, stdin, BIO_NOCLOSE); + else { + if (BIO_read_filename(in, dh_config.infile) <= 0) { + perror(dh_config.infile); + goto end; + } + } + if (dh_config.outfile == NULL) { + BIO_set_fp(out, stdout, BIO_NOCLOSE); + } else { + if (BIO_write_filename(out, dh_config.outfile) <= 0) { + perror(dh_config.outfile); + goto end; + } + } + + if (dh_config.informat == FORMAT_ASN1) + dh = d2i_DHparams_bio(in, NULL); + else if (dh_config.informat == FORMAT_PEM) + dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); + else { + BIO_printf(bio_err, "bad input format specified\n"); + goto end; + } + if (dh == NULL) { + BIO_printf(bio_err, "unable to load DH parameters\n"); + ERR_print_errors(bio_err); + goto end; + } + if (dh_config.text) { + DHparams_print(out, dh); + } + if (dh_config.check) { + if (!DH_check(dh, &i)) { + ERR_print_errors(bio_err); + goto end; + } + if (i & DH_CHECK_P_NOT_PRIME) + printf("p value is not prime\n"); + if (i & DH_CHECK_P_NOT_SAFE_PRIME) + printf("p value is not a safe prime\n"); + if (i & DH_UNABLE_TO_CHECK_GENERATOR) + printf("unable to check the generator value\n"); + if (i & DH_NOT_SUITABLE_GENERATOR) + printf("the g value is not a generator\n"); + if (i == 0) + printf("DH parameters appear to be ok.\n"); + } + if (dh_config.C) { + unsigned char *data; + int len, l, bits; + + len = BN_num_bytes(dh->p); + bits = BN_num_bits(dh->p); + data = malloc(len); + if (data == NULL) { + perror("malloc"); + goto end; + } + l = BN_bn2bin(dh->p, data); + printf("static unsigned char dh%d_p[] = {", bits); + for (i = 0; i < l; i++) { + if ((i % 12) == 0) + printf("\n\t"); + printf("0x%02X, ", data[i]); + } + printf("\n\t};\n"); + + l = BN_bn2bin(dh->g, data); + printf("static unsigned char dh%d_g[] = {", bits); + for (i = 0; i < l; i++) { + if ((i % 12) == 0) + printf("\n\t"); + printf("0x%02X, ", data[i]); + } + printf("\n\t};\n\n"); + + printf("DH *get_dh%d()\n\t{\n", bits); + printf("\tDH *dh;\n\n"); + printf("\tif ((dh = DH_new()) == NULL) return(NULL);\n"); + printf("\tdh->p = BN_bin2bn(dh%d_p, sizeof(dh%d_p), NULL);\n", + bits, bits); + printf("\tdh->g = BN_bin2bn(dh%d_g, sizeof(dh%d_g), NULL);\n", + bits, bits); + printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n"); + printf("\t\treturn(NULL);\n"); + printf("\treturn(dh);\n\t}\n"); + free(data); + } + if (!dh_config.noout) { + if (dh_config.outformat == FORMAT_ASN1) + i = i2d_DHparams_bio(out, dh); + else if (dh_config.outformat == FORMAT_PEM) + i = PEM_write_bio_DHparams(out, dh); + else { + BIO_printf(bio_err, "bad output format specified for outfile\n"); + goto end; + } + if (!i) { + BIO_printf(bio_err, "unable to write DH parameters\n"); + ERR_print_errors(bio_err); + goto end; + } + } + ret = 0; + +end: + BIO_free(in); + if (out != NULL) + BIO_free_all(out); + if (dh != NULL) + DH_free(dh); + + return (ret); +} +#endif diff --git a/crypto/libressl/apps/openssl/dhparam.c b/crypto/libressl/apps/openssl/dhparam.c new file mode 100644 index 0000000000..b4951f90ad --- /dev/null +++ b/crypto/libressl/apps/openssl/dhparam.c @@ -0,0 +1,499 @@ +/* $OpenBSD: dhparam.c,v 1.7 2015/10/10 22:28:51 doug Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include /* for OPENSSL_NO_DH */ + +#ifndef OPENSSL_NO_DH + +#include +#include +#include +#include + +#include "apps.h" + +#include +#include +#include +#include +#include +#include + +#include + +#define DEFBITS 2048 + +struct { + int C; + int check; + int dsaparam; + int g; + char *infile; + int informat; + int noout; + char *outfile; + int outformat; + int text; +} dhparam_config; + +struct option dhparam_options[] = { + { + .name = "2", + .desc = "Generate DH parameters with a generator value of 2 " + "(default)", + .type = OPTION_VALUE, + .opt.value = &dhparam_config.g, + .value = 2, + }, + { + .name = "5", + .desc = "Generate DH parameters with a generator value of 5", + .type = OPTION_VALUE, + .opt.value = &dhparam_config.g, + .value = 5, + }, + { + .name = "C", + .desc = "Convert DH parameters into C code", + .type = OPTION_FLAG, + .opt.flag = &dhparam_config.C, + }, + { + .name = "check", + .desc = "Check the DH parameters", + .type = OPTION_FLAG, + .opt.flag = &dhparam_config.check, + }, + { + .name = "dsaparam", + .desc = "Read or generate DSA parameters and convert to DH", + .type = OPTION_FLAG, + .opt.flag = &dhparam_config.dsaparam, + }, + { + .name = "in", + .argname = "file", + .desc = "Input file (default stdin)", + .type = OPTION_ARG, + .opt.arg = &dhparam_config.infile, + }, + { + .name = "inform", + .argname = "format", + .desc = "Input format (DER or PEM (default))", + .type = OPTION_ARG_FORMAT, + .opt.value = &dhparam_config.informat, + }, + { + .name = "noout", + .desc = "Do not output encoded version of DH parameters", + .type = OPTION_FLAG, + .opt.flag = &dhparam_config.noout, + }, + { + .name = "out", + .argname = "file", + .desc = "Output file (default stdout)", + .type = OPTION_ARG, + .opt.arg = &dhparam_config.outfile, + }, + { + .name = "outform", + .argname = "format", + .desc = "Output format (DER or PEM (default))", + .type = OPTION_ARG_FORMAT, + .opt.value = &dhparam_config.outformat, + }, + { + .name = "text", + .desc = "Print DH parameters in plain text", + .type = OPTION_FLAG, + .opt.flag = &dhparam_config.text, + }, + { NULL }, +}; + +static void +dhparam_usage() +{ + fprintf(stderr, + "usage: dhparam [-2 | -5] [-C] [-check] [-dsaparam]\n" + " [-in file] [-inform DER | PEM] [-noout] [-out file]\n" + " [-outform DER | PEM] [-text] [numbits]\n\n"); + options_usage(dhparam_options); +} + +static int dh_cb(int p, int n, BN_GENCB * cb); + +int +dhparam_main(int argc, char **argv) +{ + BIO *in = NULL, *out = NULL; + char *num_bits = NULL; + DH *dh = NULL; + int num = 0; + int ret = 1; + int i; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + memset(&dhparam_config, 0, sizeof(dhparam_config)); + + dhparam_config.informat = FORMAT_PEM; + dhparam_config.outformat = FORMAT_PEM; + + if (options_parse(argc, argv, dhparam_options, &num_bits, NULL) != 0) { + dhparam_usage(); + return (1); + } + + if (num_bits != NULL) { + if(sscanf(num_bits, "%d", &num) == 0 || num <= 0) { + BIO_printf(bio_err, "invalid number of bits: %s\n", + num_bits); + return (1); + } + } + + if (dhparam_config.g && !num) + num = DEFBITS; + + if (dhparam_config.dsaparam) { + if (dhparam_config.g) { + BIO_printf(bio_err, "generator may not be chosen for DSA parameters\n"); + goto end; + } + } else { + /* DH parameters */ + if (num && !dhparam_config.g) + dhparam_config.g = 2; + } + + if (num) { + + BN_GENCB cb; + BN_GENCB_set(&cb, dh_cb, bio_err); + if (dhparam_config.dsaparam) { + DSA *dsa = DSA_new(); + + BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", num); + if (!dsa || !DSA_generate_parameters_ex(dsa, num, + NULL, 0, NULL, NULL, &cb)) { + if (dsa) + DSA_free(dsa); + ERR_print_errors(bio_err); + goto end; + } + dh = DSA_dup_DH(dsa); + DSA_free(dsa); + if (dh == NULL) { + ERR_print_errors(bio_err); + goto end; + } + } else { + dh = DH_new(); + BIO_printf(bio_err, "Generating DH parameters, %d bit long safe prime, generator %d\n", num, dhparam_config.g); + BIO_printf(bio_err, "This is going to take a long time\n"); + if (!dh || !DH_generate_parameters_ex(dh, num, dhparam_config.g, &cb)) { + ERR_print_errors(bio_err); + goto end; + } + } + } else { + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + ERR_print_errors(bio_err); + goto end; + } + if (dhparam_config.infile == NULL) + BIO_set_fp(in, stdin, BIO_NOCLOSE); + else { + if (BIO_read_filename(in, dhparam_config.infile) <= 0) { + perror(dhparam_config.infile); + goto end; + } + } + + if (dhparam_config.informat != FORMAT_ASN1 && + dhparam_config.informat != FORMAT_PEM) { + BIO_printf(bio_err, "bad input format specified\n"); + goto end; + } + if (dhparam_config.dsaparam) { + DSA *dsa; + + if (dhparam_config.informat == FORMAT_ASN1) + dsa = d2i_DSAparams_bio(in, NULL); + else /* informat == FORMAT_PEM */ + dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL); + + if (dsa == NULL) { + BIO_printf(bio_err, "unable to load DSA parameters\n"); + ERR_print_errors(bio_err); + goto end; + } + dh = DSA_dup_DH(dsa); + DSA_free(dsa); + if (dh == NULL) { + ERR_print_errors(bio_err); + goto end; + } + } else + { + if (dhparam_config.informat == FORMAT_ASN1) + dh = d2i_DHparams_bio(in, NULL); + else /* informat == FORMAT_PEM */ + dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); + + if (dh == NULL) { + BIO_printf(bio_err, "unable to load DH parameters\n"); + ERR_print_errors(bio_err); + goto end; + } + } + + /* dh != NULL */ + } + + out = BIO_new(BIO_s_file()); + if (out == NULL) { + ERR_print_errors(bio_err); + goto end; + } + if (dhparam_config.outfile == NULL) { + BIO_set_fp(out, stdout, BIO_NOCLOSE); + } else { + if (BIO_write_filename(out, dhparam_config.outfile) <= 0) { + perror(dhparam_config.outfile); + goto end; + } + } + + + if (dhparam_config.text) { + DHparams_print(out, dh); + } + if (dhparam_config.check) { + if (!DH_check(dh, &i)) { + ERR_print_errors(bio_err); + goto end; + } + if (i & DH_CHECK_P_NOT_PRIME) + printf("p value is not prime\n"); + if (i & DH_CHECK_P_NOT_SAFE_PRIME) + printf("p value is not a safe prime\n"); + if (i & DH_UNABLE_TO_CHECK_GENERATOR) + printf("unable to check the generator value\n"); + if (i & DH_NOT_SUITABLE_GENERATOR) + printf("the g value is not a generator\n"); + if (i == 0) + printf("DH parameters appear to be ok.\n"); + } + if (dhparam_config.C) { + unsigned char *data; + int len, l, bits; + + len = BN_num_bytes(dh->p); + bits = BN_num_bits(dh->p); + data = malloc(len); + if (data == NULL) { + perror("malloc"); + goto end; + } + printf("#ifndef HEADER_DH_H\n" + "#include \n" + "#endif\n"); + printf("DH *get_dh%d()\n\t{\n", bits); + + l = BN_bn2bin(dh->p, data); + printf("\tstatic unsigned char dh%d_p[] = {", bits); + for (i = 0; i < l; i++) { + if ((i % 12) == 0) + printf("\n\t\t"); + printf("0x%02X, ", data[i]); + } + printf("\n\t\t};\n"); + + l = BN_bn2bin(dh->g, data); + printf("\tstatic unsigned char dh%d_g[] = {", bits); + for (i = 0; i < l; i++) { + if ((i % 12) == 0) + printf("\n\t\t"); + printf("0x%02X, ", data[i]); + } + printf("\n\t\t};\n"); + + printf("\tDH *dh;\n\n"); + printf("\tif ((dh = DH_new()) == NULL) return(NULL);\n"); + printf("\tdh->p = BN_bin2bn(dh%d_p, sizeof(dh%d_p), NULL);\n", + bits, bits); + printf("\tdh->g = BN_bin2bn(dh%d_g, sizeof(dh%d_g), NULL);\n", + bits, bits); + printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n"); + printf("\t\t{ DH_free(dh); return(NULL); }\n"); + if (dh->length) + printf("\tdh->length = %ld;\n", dh->length); + printf("\treturn(dh);\n\t}\n"); + free(data); + } + if (!dhparam_config.noout) { + if (dhparam_config.outformat == FORMAT_ASN1) + i = i2d_DHparams_bio(out, dh); + else if (dhparam_config.outformat == FORMAT_PEM) + i = PEM_write_bio_DHparams(out, dh); + else { + BIO_printf(bio_err, "bad output format specified for outfile\n"); + goto end; + } + if (!i) { + BIO_printf(bio_err, "unable to write DH parameters\n"); + ERR_print_errors(bio_err); + goto end; + } + } + ret = 0; + +end: + BIO_free(in); + if (out != NULL) + BIO_free_all(out); + if (dh != NULL) + DH_free(dh); + + return (ret); +} + +/* dh_cb is identical to dsa_cb in apps/dsaparam.c */ +static int +dh_cb(int p, int n, BN_GENCB * cb) +{ + char c = '*'; + + if (p == 0) + c = '.'; + if (p == 1) + c = '+'; + if (p == 2) + c = '*'; + if (p == 3) + c = '\n'; + BIO_write(cb->arg, &c, 1); + (void) BIO_flush(cb->arg); + return 1; +} + +#endif diff --git a/crypto/libressl/apps/openssl/dsa.c b/crypto/libressl/apps/openssl/dsa.c new file mode 100644 index 0000000000..336c886da6 --- /dev/null +++ b/crypto/libressl/apps/openssl/dsa.c @@ -0,0 +1,373 @@ +/* $OpenBSD: dsa.c,v 1.7 2015/10/17 07:51:10 semarie Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include /* for OPENSSL_NO_DSA */ + +#include +#include +#include +#include +#include + +#include "apps.h" + +#include +#include +#include +#include +#include +#include +#include + +static struct { + const EVP_CIPHER *enc; + char *infile; + int informat; + int modulus; + int noout; + char *outfile; + int outformat; + char *passargin; + char *passargout; + int pubin; + int pubout; + int pvk_encr; + int text; +} dsa_config; + +static int +dsa_opt_enc(int argc, char **argv, int *argsused) +{ + char *name = argv[0]; + + if (*name++ != '-') + return (1); + + if ((dsa_config.enc = EVP_get_cipherbyname(name)) != NULL) { + *argsused = 1; + return (0); + } + + return (1); +} + +static struct option dsa_options[] = { + { + .name = "in", + .argname = "file", + .desc = "Input file (default stdin)", + .type = OPTION_ARG, + .opt.arg = &dsa_config.infile, + }, + { + .name = "inform", + .argname = "format", + .desc = "Input format (PEM (default) or any other supported" + " format)", + .type = OPTION_ARG_FORMAT, + .opt.value = &dsa_config.informat, + }, + { + .name = "noout", + .desc = "No output", + .type = OPTION_FLAG, + .opt.flag = &dsa_config.noout, + }, + { + .name = "out", + .argname = "file", + .desc = "Output file (default stdout)", + .type = OPTION_ARG, + .opt.arg = &dsa_config.outfile, + }, + { + .name = "outform", + .argname = "format", + .desc = "Output format (DER, MSBLOB, PEM (default) or PVK)", + .type = OPTION_ARG_FORMAT, + .opt.value = &dsa_config.outformat, + }, + { + .name = "passin", + .argname = "source", + .desc = "Input file passphrase source", + .type = OPTION_ARG, + .opt.arg = &dsa_config.passargin, + }, + { + .name = "passout", + .argname = "source", + .desc = "Output file passphrase source", + .type = OPTION_ARG, + .opt.arg = &dsa_config.passargout, + }, + { + .name = "pubin", + .desc = "Read a public key from the input file instead of" + " private key", + .type = OPTION_FLAG, + .opt.flag = &dsa_config.pubin, + }, + { + .name = "pubout", + .desc = "Output a public key instead of private key", + .type = OPTION_FLAG, + .opt.flag = &dsa_config.pubout, + }, + { + .name = "pvk-none", + .desc = "PVK encryption level", + .type = OPTION_VALUE, + .value = 0, + .opt.value = &dsa_config.pvk_encr, + }, + { + .name = "pvk-strong", + .desc = "PVK encryption level (default)", + .type = OPTION_VALUE, + .value = 2, + .opt.value = &dsa_config.pvk_encr, + }, + { + .name = "pvk-weak", + .desc = "PVK encryption level", + .type = OPTION_VALUE, + .value = 1, + .opt.value = &dsa_config.pvk_encr, + }, + { + .name = "text", + .desc = "Print the key in text form", + .type = OPTION_FLAG, + .opt.flag = &dsa_config.text, + }, + { + .name = NULL, + .type = OPTION_ARGV_FUNC, + .opt.argvfunc = dsa_opt_enc, + }, + { NULL }, +}; + +static void +show_ciphers(const OBJ_NAME *name, void *arg) +{ + static int n; + + if (!islower((unsigned char)*name->name)) + return; + + fprintf(stderr, " -%-24s%s", name->name, (++n % 3 ? "" : "\n")); +} + +static void +dsa_usage(void) +{ + fprintf(stderr, + "usage: dsa [-in file] [-inform format] [-noout]\n" + " [-out file] [-outform format] [-passin src] [-passout src]\n" + " [-pubin] [-pubout] [-pvk-none | -pvk-strong | -pvk-weak]\n" + " [-text] [-ciphername]\n\n"); + options_usage(dsa_options); + fprintf(stderr, "\n"); + + fprintf(stderr, "Valid ciphername values:\n\n"); + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_ciphers, NULL); + fprintf(stderr, "\n"); +} + +int +dsa_main(int argc, char **argv) +{ + int ret = 1; + DSA *dsa = NULL; + int i; + BIO *in = NULL, *out = NULL; + char *passin = NULL, *passout = NULL; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + memset(&dsa_config, 0, sizeof(dsa_config)); + + dsa_config.pvk_encr = 2; + dsa_config.informat = FORMAT_PEM; + dsa_config.outformat = FORMAT_PEM; + + if (options_parse(argc, argv, dsa_options, NULL, NULL) != 0) { + dsa_usage(); + goto end; + } + + if (!app_passwd(bio_err, dsa_config.passargin, dsa_config.passargout, + &passin, &passout)) { + BIO_printf(bio_err, "Error getting passwords\n"); + goto end; + } + + in = BIO_new(BIO_s_file()); + out = BIO_new(BIO_s_file()); + if (in == NULL || out == NULL) { + ERR_print_errors(bio_err); + goto end; + } + if (dsa_config.infile == NULL) + BIO_set_fp(in, stdin, BIO_NOCLOSE); + else { + if (BIO_read_filename(in, dsa_config.infile) <= 0) { + perror(dsa_config.infile); + goto end; + } + } + + BIO_printf(bio_err, "read DSA key\n"); + + { + EVP_PKEY *pkey; + + if (dsa_config.pubin) + pkey = load_pubkey(bio_err, dsa_config.infile, + dsa_config.informat, 1, passin, "Public Key"); + else + pkey = load_key(bio_err, dsa_config.infile, + dsa_config.informat, 1, passin, "Private Key"); + + if (pkey) { + dsa = EVP_PKEY_get1_DSA(pkey); + EVP_PKEY_free(pkey); + } + } + if (dsa == NULL) { + BIO_printf(bio_err, "unable to load Key\n"); + ERR_print_errors(bio_err); + goto end; + } + if (dsa_config.outfile == NULL) { + BIO_set_fp(out, stdout, BIO_NOCLOSE); + } else { + if (BIO_write_filename(out, dsa_config.outfile) <= 0) { + perror(dsa_config.outfile); + goto end; + } + } + + if (dsa_config.text) { + if (!DSA_print(out, dsa, 0)) { + perror(dsa_config.outfile); + ERR_print_errors(bio_err); + goto end; + } + } + if (dsa_config.modulus) { + fprintf(stdout, "Public Key="); + BN_print(out, dsa->pub_key); + fprintf(stdout, "\n"); + } + if (dsa_config.noout) + goto end; + BIO_printf(bio_err, "writing DSA key\n"); + if (dsa_config.outformat == FORMAT_ASN1) { + if (dsa_config.pubin || dsa_config.pubout) + i = i2d_DSA_PUBKEY_bio(out, dsa); + else + i = i2d_DSAPrivateKey_bio(out, dsa); + } else if (dsa_config.outformat == FORMAT_PEM) { + if (dsa_config.pubin || dsa_config.pubout) + i = PEM_write_bio_DSA_PUBKEY(out, dsa); + else + i = PEM_write_bio_DSAPrivateKey(out, dsa, dsa_config.enc, + NULL, 0, NULL, passout); +#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_RC4) + } else if (dsa_config.outformat == FORMAT_MSBLOB || + dsa_config.outformat == FORMAT_PVK) { + EVP_PKEY *pk; + pk = EVP_PKEY_new(); + EVP_PKEY_set1_DSA(pk, dsa); + if (dsa_config.outformat == FORMAT_PVK) + i = i2b_PVK_bio(out, pk, dsa_config.pvk_encr, 0, + passout); + else if (dsa_config.pubin || dsa_config.pubout) + i = i2b_PublicKey_bio(out, pk); + else + i = i2b_PrivateKey_bio(out, pk); + EVP_PKEY_free(pk); +#endif + } else { + BIO_printf(bio_err, "bad output format specified for outfile\n"); + goto end; + } + if (i <= 0) { + BIO_printf(bio_err, "unable to write private key\n"); + ERR_print_errors(bio_err); + } else + ret = 0; +end: + BIO_free(in); + if (out != NULL) + BIO_free_all(out); + if (dsa != NULL) + DSA_free(dsa); + free(passin); + free(passout); + + return (ret); +} diff --git a/crypto/libressl/apps/openssl/dsaparam.c b/crypto/libressl/apps/openssl/dsaparam.c new file mode 100644 index 0000000000..2091c5dfb4 --- /dev/null +++ b/crypto/libressl/apps/openssl/dsaparam.c @@ -0,0 +1,371 @@ +/* $OpenBSD: dsaparam.c,v 1.6 2015/10/10 22:28:51 doug Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include /* for OPENSSL_NO_DSA */ + +/* Until the key-gen callbacks are modified to use newer prototypes, we allow + * deprecated functions for openssl-internal code */ +#ifdef OPENSSL_NO_DEPRECATED +#undef OPENSSL_NO_DEPRECATED +#endif + +#include +#include +#include +#include +#include + +#include "apps.h" + +#include +#include +#include +#include +#include +#include + +static struct { + int C; + int genkey; + char *infile; + int informat; + int noout; + char *outfile; + int outformat; + int text; +} dsaparam_config; + +static struct option dsaparam_options[] = { + { + .name = "C", + .desc = "Convert DSA parameters into C code", + .type = OPTION_FLAG, + .opt.flag = &dsaparam_config.C, + }, + { + .name = "genkey", + .desc = "Generate a DSA key", + .type = OPTION_FLAG, + .opt.flag = &dsaparam_config.genkey, + }, + { + .name = "in", + .argname = "file", + .desc = "Input file (default stdin)", + .type = OPTION_ARG, + .opt.arg = &dsaparam_config.infile, + }, + { + .name = "inform", + .argname = "format", + .desc = "Input format (DER or PEM (default))", + .type = OPTION_ARG_FORMAT, + .opt.value = &dsaparam_config.informat, + }, + { + .name = "noout", + .desc = "No output", + .type = OPTION_FLAG, + .opt.flag = &dsaparam_config.noout, + }, + { + .name = "out", + .argname = "file", + .desc = "Output file (default stdout)", + .type = OPTION_ARG, + .opt.arg = &dsaparam_config.outfile, + }, + { + .name = "outform", + .argname = "format", + .desc = "Output format (DER or PEM (default))", + .type = OPTION_ARG_FORMAT, + .opt.value = &dsaparam_config.outformat, + }, + { + .name = "text", + .desc = "Print as text", + .type = OPTION_FLAG, + .opt.flag = &dsaparam_config.text, + }, + { NULL }, +}; + +static void +dsaparam_usage(void) +{ + fprintf(stderr, + "usage: dsaparam [-C] [-genkey] [-in file]\n" + " [-inform format] [-noout] [-out file] [-outform format]\n" + " [-text] [numbits]\n\n"); + options_usage(dsaparam_options); +} + +static int dsa_cb(int p, int n, BN_GENCB * cb); + +int +dsaparam_main(int argc, char **argv) +{ + DSA *dsa = NULL; + int i; + BIO *in = NULL, *out = NULL; + int ret = 1; + int numbits = -1; + char *strbits = NULL; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + memset(&dsaparam_config, 0, sizeof(dsaparam_config)); + + dsaparam_config.informat = FORMAT_PEM; + dsaparam_config.outformat = FORMAT_PEM; + + if (options_parse(argc, argv, dsaparam_options, &strbits, NULL) != 0) { + dsaparam_usage(); + goto end; + } + + if (strbits != NULL) { + const char *errstr; + numbits = strtonum(strbits, 0, INT_MAX, &errstr); + if (errstr) { + fprintf(stderr, "Invalid number of bits: %s", errstr); + goto end; + } + } + + in = BIO_new(BIO_s_file()); + out = BIO_new(BIO_s_file()); + if (in == NULL || out == NULL) { + ERR_print_errors(bio_err); + goto end; + } + if (dsaparam_config.infile == NULL) + BIO_set_fp(in, stdin, BIO_NOCLOSE); + else { + if (BIO_read_filename(in, dsaparam_config.infile) <= 0) { + perror(dsaparam_config.infile); + goto end; + } + } + if (dsaparam_config.outfile == NULL) { + BIO_set_fp(out, stdout, BIO_NOCLOSE); + } else { + if (BIO_write_filename(out, dsaparam_config.outfile) <= 0) { + perror(dsaparam_config.outfile); + goto end; + } + } + + if (numbits > 0) { + BN_GENCB cb; + BN_GENCB_set(&cb, dsa_cb, bio_err); + dsa = DSA_new(); + if (!dsa) { + BIO_printf(bio_err, "Error allocating DSA object\n"); + goto end; + } + BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", numbits); + BIO_printf(bio_err, "This could take some time\n"); + if (!DSA_generate_parameters_ex(dsa, numbits, NULL, 0, NULL, NULL, &cb)) { + ERR_print_errors(bio_err); + BIO_printf(bio_err, "Error, DSA key generation failed\n"); + goto end; + } + } else if (dsaparam_config.informat == FORMAT_ASN1) + dsa = d2i_DSAparams_bio(in, NULL); + else if (dsaparam_config.informat == FORMAT_PEM) + dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL); + else { + BIO_printf(bio_err, "bad input format specified\n"); + goto end; + } + if (dsa == NULL) { + BIO_printf(bio_err, "unable to load DSA parameters\n"); + ERR_print_errors(bio_err); + goto end; + } + if (dsaparam_config.text) { + DSAparams_print(out, dsa); + } + if (dsaparam_config.C) { + unsigned char *data; + int l, len, bits_p; + + len = BN_num_bytes(dsa->p); + bits_p = BN_num_bits(dsa->p); + data = malloc(len + 20); + if (data == NULL) { + perror("malloc"); + goto end; + } + l = BN_bn2bin(dsa->p, data); + printf("static unsigned char dsa%d_p[] = {", bits_p); + for (i = 0; i < l; i++) { + if ((i % 12) == 0) + printf("\n\t"); + printf("0x%02X, ", data[i]); + } + printf("\n\t};\n"); + + l = BN_bn2bin(dsa->q, data); + printf("static unsigned char dsa%d_q[] = {", bits_p); + for (i = 0; i < l; i++) { + if ((i % 12) == 0) + printf("\n\t"); + printf("0x%02X, ", data[i]); + } + printf("\n\t};\n"); + + l = BN_bn2bin(dsa->g, data); + printf("static unsigned char dsa%d_g[] = {", bits_p); + for (i = 0; i < l; i++) { + if ((i % 12) == 0) + printf("\n\t"); + printf("0x%02X, ", data[i]); + } + free(data); + printf("\n\t};\n\n"); + + printf("DSA *get_dsa%d()\n\t{\n", bits_p); + printf("\tDSA *dsa;\n\n"); + printf("\tif ((dsa = DSA_new()) == NULL) return(NULL);\n"); + printf("\tdsa->p = BN_bin2bn(dsa%d_p, sizeof(dsa%d_p), NULL);\n", + bits_p, bits_p); + printf("\tdsa->q = BN_bin2bn(dsa%d_q, sizeof(dsa%d_q), NULL);\n", + bits_p, bits_p); + printf("\tdsa->g = BN_bin2bn(dsa%d_g, sizeof(dsa%d_g), NULL);\n", + bits_p, bits_p); + printf("\tif ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))\n"); + printf("\t\t{ DSA_free(dsa); return(NULL); }\n"); + printf("\treturn(dsa);\n\t}\n"); + } + if (!dsaparam_config.noout) { + if (dsaparam_config.outformat == FORMAT_ASN1) + i = i2d_DSAparams_bio(out, dsa); + else if (dsaparam_config.outformat == FORMAT_PEM) + i = PEM_write_bio_DSAparams(out, dsa); + else { + BIO_printf(bio_err, "bad output format specified for outfile\n"); + goto end; + } + if (!i) { + BIO_printf(bio_err, "unable to write DSA parameters\n"); + ERR_print_errors(bio_err); + goto end; + } + } + if (dsaparam_config.genkey) { + DSA *dsakey; + + if ((dsakey = DSAparams_dup(dsa)) == NULL) + goto end; + if (!DSA_generate_key(dsakey)) { + ERR_print_errors(bio_err); + DSA_free(dsakey); + goto end; + } + if (dsaparam_config.outformat == FORMAT_ASN1) + i = i2d_DSAPrivateKey_bio(out, dsakey); + else if (dsaparam_config.outformat == FORMAT_PEM) + i = PEM_write_bio_DSAPrivateKey(out, dsakey, NULL, NULL, 0, NULL, NULL); + else { + BIO_printf(bio_err, "bad output format specified for outfile\n"); + DSA_free(dsakey); + goto end; + } + DSA_free(dsakey); + } + ret = 0; + +end: + BIO_free(in); + if (out != NULL) + BIO_free_all(out); + if (dsa != NULL) + DSA_free(dsa); + + return (ret); +} + +static int +dsa_cb(int p, int n, BN_GENCB * cb) +{ + char c = '*'; + + if (p == 0) + c = '.'; + if (p == 1) + c = '+'; + if (p == 2) + c = '*'; + if (p == 3) + c = '\n'; + BIO_write(cb->arg, &c, 1); + (void) BIO_flush(cb->arg); +#ifdef GENCB_TEST + if (stop_keygen_flag) + return 0; +#endif + return 1; +} diff --git a/crypto/libressl/apps/openssl/ec.c b/crypto/libressl/apps/openssl/ec.c new file mode 100644 index 0000000000..287b8bc7e8 --- /dev/null +++ b/crypto/libressl/apps/openssl/ec.c @@ -0,0 +1,406 @@ +/* $OpenBSD: ec.c,v 1.7 2015/10/17 07:51:10 semarie Exp $ */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#ifndef OPENSSL_NO_EC + +#include +#include +#include +#include + +#include "apps.h" + +#include +#include +#include +#include + +static struct { + int asn1_flag; + const EVP_CIPHER *enc; + point_conversion_form_t form; + char *infile; + int informat; + char *outfile; + int outformat; + int new_asn1_flag; + int new_form; + int noout; + int param_out; + char *passargin; + char *passargout; + int pubin; + int pubout; + int text; +} ec_config; + +static int +ec_opt_enc(int argc, char **argv, int *argsused) +{ + char *name = argv[0]; + + if (*name++ != '-') + return (1); + + if ((ec_config.enc = EVP_get_cipherbyname(name)) != NULL) { + *argsused = 1; + return (0); + } + + return (1); +} + +static int +ec_opt_form(char *arg) +{ + if (strcmp(arg, "compressed") == 0) + ec_config.form = POINT_CONVERSION_COMPRESSED; + else if (strcmp(arg, "uncompressed") == 0) + ec_config.form = POINT_CONVERSION_UNCOMPRESSED; + else if (strcmp(arg, "hybrid") == 0) + ec_config.form = POINT_CONVERSION_HYBRID; + else { + fprintf(stderr, "Invalid point conversion: %s\n", arg); + return (1); + } + + ec_config.new_form = 1; + return (0); +} + +static int +ec_opt_named(char *arg) +{ + if (strcmp(arg, "named_curve") == 0) + ec_config.asn1_flag = OPENSSL_EC_NAMED_CURVE; + else if (strcmp(arg, "explicit") == 0) + ec_config.asn1_flag = 0; + else { + fprintf(stderr, "Invalid curve type: %s\n", arg); + return (1); + } + + ec_config.new_asn1_flag = 1; + return (0); +} + +static struct option ec_options[] = { + { + .name = "conv_form", + .argname = "form", + .desc = "Specify the point conversion form (default" + " \"named_curve\")", + .type = OPTION_ARG_FUNC, + .opt.argfunc = ec_opt_form, + }, + { + .name = "in", + .argname = "file", + .desc = "Input file (default stdin)", + .type = OPTION_ARG, + .opt.arg = &ec_config.infile, + }, + { + .name = "inform", + .argname = "format", + .desc = "Input format (DER or PEM (default))", + .type = OPTION_ARG_FORMAT, + .opt.value = &ec_config.informat, + }, + { + .name = "noout", + .desc = "No output", + .type = OPTION_FLAG, + .opt.flag = &ec_config.noout, + }, + { + .name = "out", + .argname = "file", + .desc = "Output file (default stdout)", + .type = OPTION_ARG, + .opt.arg = &ec_config.outfile, + }, + { + .name = "outform", + .argname = "format", + .desc = "Output format (DER or PEM (default))", + .type = OPTION_ARG_FORMAT, + .opt.value = &ec_config.outformat, + }, + { + .name = "param_enc", + .argname = "type", + .desc = "Specify the way the ec parameters are encoded" + " (default \"uncompressed\")", + .type = OPTION_ARG_FUNC, + .opt.argfunc = ec_opt_named, + }, + { + .name = "param_out", + .desc = "Print the elliptic curve parameters", + .type = OPTION_FLAG, + .opt.flag = &ec_config.param_out, + }, + { + .name = "passin", + .argname = "source", + .desc = "Input file passphrase source", + .type = OPTION_ARG, + .opt.arg = &ec_config.passargin, + }, + { + .name = "passout", + .argname = "source", + .desc = "Output file passphrase source", + .type = OPTION_ARG, + .opt.arg = &ec_config.passargout, + }, + { + .name = "pubin", + .desc = "Read public key instead of private key from input", + .type = OPTION_FLAG, + .opt.flag = &ec_config.pubin, + }, + { + .name = "pubout", + .desc = "Output public key instead of private key in output", + .type = OPTION_FLAG, + .opt.flag = &ec_config.pubout, + }, + { + .name = "text", + .desc = "Print the public/private key components and parameters", + .type = OPTION_FLAG, + .opt.flag = &ec_config.text, + }, + { + .name = NULL, + .desc = "Cipher to encrypt the output if using PEM format", + .type = OPTION_ARGV_FUNC, + .opt.argvfunc = ec_opt_enc, + }, + { NULL }, +}; + +static void +show_ciphers(const OBJ_NAME *name, void *arg) +{ + static int n; + + if (!islower((unsigned char)*name->name)) + return; + + fprintf(stderr, " -%-24s%s", name->name, (++n % 3 ? "" : "\n")); +} + +static void +ec_usage(void) +{ + fprintf(stderr, + "usage: ec [-conv_form form] [-in file]\n" + " [-inform format] [-noout] [-out file] [-outform format]\n" + " [-param_enc type] [-param_out] [-passin file]\n" + " [-passout file] [-pubin] [-pubout] [-text] [-ciphername]\n\n"); + options_usage(ec_options); + + fprintf(stderr, "\n"); + + fprintf(stderr, "Valid ciphername values:\n\n"); + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_ciphers, NULL); + fprintf(stderr, "\n"); +} + +int +ec_main(int argc, char **argv) +{ + int ret = 1; + EC_KEY *eckey = NULL; + const EC_GROUP *group; + int i; + BIO *in = NULL, *out = NULL; + char *passin = NULL, *passout = NULL; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + memset(&ec_config, 0, sizeof(ec_config)); + + ec_config.asn1_flag = OPENSSL_EC_NAMED_CURVE; + ec_config.form = POINT_CONVERSION_UNCOMPRESSED; + ec_config.informat = FORMAT_PEM; + ec_config.outformat = FORMAT_PEM; + + if (options_parse(argc, argv, ec_options, NULL, NULL) != 0) { + ec_usage(); + goto end; + } + + if (!app_passwd(bio_err, ec_config.passargin, ec_config.passargout, + &passin, &passout)) { + BIO_printf(bio_err, "Error getting passwords\n"); + goto end; + } + in = BIO_new(BIO_s_file()); + out = BIO_new(BIO_s_file()); + if (in == NULL || out == NULL) { + ERR_print_errors(bio_err); + goto end; + } + if (ec_config.infile == NULL) + BIO_set_fp(in, stdin, BIO_NOCLOSE); + else { + if (BIO_read_filename(in, ec_config.infile) <= 0) { + perror(ec_config.infile); + goto end; + } + } + + BIO_printf(bio_err, "read EC key\n"); + if (ec_config.informat == FORMAT_ASN1) { + if (ec_config.pubin) + eckey = d2i_EC_PUBKEY_bio(in, NULL); + else + eckey = d2i_ECPrivateKey_bio(in, NULL); + } else if (ec_config.informat == FORMAT_PEM) { + if (ec_config.pubin) + eckey = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, + NULL); + else + eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL, + passin); + } else { + BIO_printf(bio_err, "bad input format specified for key\n"); + goto end; + } + if (eckey == NULL) { + BIO_printf(bio_err, "unable to load Key\n"); + ERR_print_errors(bio_err); + goto end; + } + if (ec_config.outfile == NULL) { + BIO_set_fp(out, stdout, BIO_NOCLOSE); + } else { + if (BIO_write_filename(out, ec_config.outfile) <= 0) { + perror(ec_config.outfile); + goto end; + } + } + + group = EC_KEY_get0_group(eckey); + + if (ec_config.new_form) + EC_KEY_set_conv_form(eckey, ec_config.form); + + if (ec_config.new_asn1_flag) + EC_KEY_set_asn1_flag(eckey, ec_config.asn1_flag); + + if (ec_config.text) + if (!EC_KEY_print(out, eckey, 0)) { + perror(ec_config.outfile); + ERR_print_errors(bio_err); + goto end; + } + if (ec_config.noout) { + ret = 0; + goto end; + } + BIO_printf(bio_err, "writing EC key\n"); + if (ec_config.outformat == FORMAT_ASN1) { + if (ec_config.param_out) + i = i2d_ECPKParameters_bio(out, group); + else if (ec_config.pubin || ec_config.pubout) + i = i2d_EC_PUBKEY_bio(out, eckey); + else + i = i2d_ECPrivateKey_bio(out, eckey); + } else if (ec_config.outformat == FORMAT_PEM) { + if (ec_config.param_out) + i = PEM_write_bio_ECPKParameters(out, group); + else if (ec_config.pubin || ec_config.pubout) + i = PEM_write_bio_EC_PUBKEY(out, eckey); + else + i = PEM_write_bio_ECPrivateKey(out, eckey, + ec_config.enc, NULL, 0, NULL, passout); + } else { + BIO_printf(bio_err, "bad output format specified for " + "outfile\n"); + goto end; + } + + if (!i) { + BIO_printf(bio_err, "unable to write private key\n"); + ERR_print_errors(bio_err); + } else + ret = 0; +end: + BIO_free(in); + if (out) + BIO_free_all(out); + if (eckey) + EC_KEY_free(eckey); + free(passin); + free(passout); + + return (ret); +} +#endif diff --git a/crypto/libressl/apps/openssl/ecparam.c b/crypto/libressl/apps/openssl/ecparam.c new file mode 100644 index 0000000000..9d7e1cab61 --- /dev/null +++ b/crypto/libressl/apps/openssl/ecparam.c @@ -0,0 +1,615 @@ +/* $OpenBSD: ecparam.c,v 1.14 2015/10/10 22:28:51 doug Exp $ */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#include + +#ifndef OPENSSL_NO_EC + +#include +#include +#include +#include + +#include "apps.h" + +#include +#include +#include +#include +#include +#include + +static int ecparam_print_var(BIO *, BIGNUM *, const char *, int, + unsigned char *); + +static struct { + int C; + int asn1_flag; + int check; + char *curve_name; + point_conversion_form_t form; + int genkey; + char *infile; + int informat; + int list_curves; + int new_asn1_flag; + int new_form; + int no_seed; + int noout; + char *outfile; + int outformat; + int text; +} ecparam_config; + +static int +ecparam_opt_form(char *arg) +{ + if (strcmp(arg, "compressed") == 0) + ecparam_config.form = POINT_CONVERSION_COMPRESSED; + else if (strcmp(arg, "uncompressed") == 0) + ecparam_config.form = POINT_CONVERSION_UNCOMPRESSED; + else if (strcmp(arg, "hybrid") == 0) + ecparam_config.form = POINT_CONVERSION_HYBRID; + else + return (1); + + ecparam_config.new_form = 1; + return (0); +} + +static int +ecparam_opt_enctype(char *arg) +{ + if (strcmp(arg, "explicit") == 0) + ecparam_config.asn1_flag = 0; + else if (strcmp(arg, "named_curve") == 0) + ecparam_config.asn1_flag = OPENSSL_EC_NAMED_CURVE; + else + return (1); + + ecparam_config.new_asn1_flag = 1; + return (0); +} + +struct option ecparam_options[] = { + { + .name = "C", + .desc = "Convert the EC parameters into C code", + .type = OPTION_FLAG, + .opt.flag = &ecparam_config.C, + }, + { + .name = "check", + .desc = "Validate the elliptic curve parameters", + .type = OPTION_FLAG, + .opt.flag = &ecparam_config.check, + }, + { + .name = "conv_form", + .argname = "form", + .desc = "Specify point conversion form:\n" + " compressed, uncompressed (default), hybrid", + .type = OPTION_ARG_FUNC, + .opt.argfunc = ecparam_opt_form, + }, + { + .name = "genkey", + .desc = "Generate an EC private key using the specified " + "parameters", + .type = OPTION_FLAG, + .opt.flag = &ecparam_config.genkey, + }, + { + .name = "in", + .argname = "file", + .desc = "Input file to read parameters from (default stdin)", + .type = OPTION_ARG, + .opt.arg = &ecparam_config.infile, + }, + { + .name = "inform", + .argname = "format", + .desc = "Input format (DER or PEM)", + .type = OPTION_ARG_FORMAT, + .opt.value = &ecparam_config.informat, + }, + { + .name = "list_curves", + .desc = "Print list of all currently implemented EC " + "parameter names", + .type = OPTION_FLAG, + .opt.flag = &ecparam_config.list_curves, + }, + { + .name = "name", + .argname = "curve", + .desc = "Use the EC parameters with the specified name", + .type = OPTION_ARG, + .opt.arg = &ecparam_config.curve_name, + }, + { + .name = "no_seed", + .desc = "Do not output seed with explicit parameter encoding", + .type = OPTION_FLAG, + .opt.flag = &ecparam_config.no_seed, + }, + { + .name = "noout", + .desc = "Do not output encoded version of EC parameters", + .type = OPTION_FLAG, + .opt.flag = &ecparam_config.noout, + }, + { + .name = "out", + .argname = "file", + .desc = "Output file to write parameters to (default stdout)", + .type = OPTION_ARG, + .opt.arg = &ecparam_config.outfile, + }, + { + .name = "outform", + .argname = "format", + .desc = "Output format (DER or PEM)", + .type = OPTION_ARG_FORMAT, + .opt.value = &ecparam_config.outformat, + }, + { + .name = "param_enc", + .argname = "type", + .desc = "Specify EC parameter ASN.1 encoding type:\n" + " explicit, named_curve (default)", + .type = OPTION_ARG_FUNC, + .opt.argfunc = ecparam_opt_enctype, + }, + { + .name = "text", + .desc = "Print out the EC parameters in human readable form", + .type = OPTION_FLAG, + .opt.flag = &ecparam_config.text, + }, + {NULL}, +}; + +static void +ecparam_usage(void) +{ + fprintf(stderr, "usage: ecparam [-C] [-check] [-conv_form arg] " + " [-genkey]\n" + " [-in file] [-inform DER | PEM] [-list_curves] [-name arg]\n" + " [-no_seed] [-noout] [-out file] [-outform DER | PEM]\n" + " [-param_enc arg] [-text]\n\n"); + options_usage(ecparam_options); +} + +int +ecparam_main(int argc, char **argv) +{ + BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL, *ec_gen = NULL; + BIGNUM *ec_order = NULL, *ec_cofactor = NULL; + EC_GROUP *group = NULL; + unsigned char *buffer = NULL; + BIO *in = NULL, *out = NULL; + int i, ret = 1; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + memset(&ecparam_config, 0, sizeof(ecparam_config)); + ecparam_config.asn1_flag = OPENSSL_EC_NAMED_CURVE; + ecparam_config.form = POINT_CONVERSION_UNCOMPRESSED; + ecparam_config.informat = FORMAT_PEM; + ecparam_config.outformat = FORMAT_PEM; + + if (options_parse(argc, argv, ecparam_options, NULL, NULL) != 0) { + ecparam_usage(); + goto end; + } + + in = BIO_new(BIO_s_file()); + out = BIO_new(BIO_s_file()); + if ((in == NULL) || (out == NULL)) { + ERR_print_errors(bio_err); + goto end; + } + if (ecparam_config.infile == NULL) + BIO_set_fp(in, stdin, BIO_NOCLOSE); + else { + if (BIO_read_filename(in, ecparam_config.infile) <= 0) { + perror(ecparam_config.infile); + goto end; + } + } + if (ecparam_config.outfile == NULL) { + BIO_set_fp(out, stdout, BIO_NOCLOSE); + } else { + if (BIO_write_filename(out, ecparam_config.outfile) <= 0) { + perror(ecparam_config.outfile); + goto end; + } + } + + if (ecparam_config.list_curves) { + EC_builtin_curve *curves = NULL; + size_t crv_len = 0; + size_t n = 0; + + crv_len = EC_get_builtin_curves(NULL, 0); + + curves = reallocarray(NULL, crv_len, sizeof(EC_builtin_curve)); + if (curves == NULL) + goto end; + + if (!EC_get_builtin_curves(curves, crv_len)) { + free(curves); + goto end; + } + for (n = 0; n < crv_len; n++) { + const char *comment; + const char *sname; + comment = curves[n].comment; + sname = OBJ_nid2sn(curves[n].nid); + if (comment == NULL) + comment = "CURVE DESCRIPTION NOT AVAILABLE"; + if (sname == NULL) + sname = ""; + + BIO_printf(out, " %-10s: ", sname); + BIO_printf(out, "%s\n", comment); + } + + free(curves); + ret = 0; + goto end; + } + if (ecparam_config.curve_name != NULL) { + int nid; + + /* + * workaround for the SECG curve names secp192r1 and + * secp256r1 (which are the same as the curves prime192v1 and + * prime256v1 defined in X9.62) + */ + if (!strcmp(ecparam_config.curve_name, "secp192r1")) { + BIO_printf(bio_err, "using curve name prime192v1 " + "instead of secp192r1\n"); + nid = NID_X9_62_prime192v1; + } else if (!strcmp(ecparam_config.curve_name, "secp256r1")) { + BIO_printf(bio_err, "using curve name prime256v1 " + "instead of secp256r1\n"); + nid = NID_X9_62_prime256v1; + } else + nid = OBJ_sn2nid(ecparam_config.curve_name); + + if (nid == 0) + nid = EC_curve_nist2nid(ecparam_config.curve_name); + + if (nid == 0) { + BIO_printf(bio_err, "unknown curve name (%s)\n", + ecparam_config.curve_name); + goto end; + } + group = EC_GROUP_new_by_curve_name(nid); + if (group == NULL) { + BIO_printf(bio_err, "unable to create curve (%s)\n", + ecparam_config.curve_name); + goto end; + } + EC_GROUP_set_asn1_flag(group, ecparam_config.asn1_flag); + EC_GROUP_set_point_conversion_form(group, ecparam_config.form); + } else if (ecparam_config.informat == FORMAT_ASN1) { + group = d2i_ECPKParameters_bio(in, NULL); + } else if (ecparam_config.informat == FORMAT_PEM) { + group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL); + } else { + BIO_printf(bio_err, "bad input format specified\n"); + goto end; + } + + if (group == NULL) { + BIO_printf(bio_err, + "unable to load elliptic curve parameters\n"); + ERR_print_errors(bio_err); + goto end; + } + if (ecparam_config.new_form) + EC_GROUP_set_point_conversion_form(group, ecparam_config.form); + + if (ecparam_config.new_asn1_flag) + EC_GROUP_set_asn1_flag(group, ecparam_config.asn1_flag); + + if (ecparam_config.no_seed) + EC_GROUP_set_seed(group, NULL, 0); + + if (ecparam_config.text) { + if (!ECPKParameters_print(out, group, 0)) + goto end; + } + if (ecparam_config.check) { + BIO_printf(bio_err, "checking elliptic curve parameters: "); + if (!EC_GROUP_check(group, NULL)) { + BIO_printf(bio_err, "failed\n"); + ERR_print_errors(bio_err); + } else + BIO_printf(bio_err, "ok\n"); + + } + if (ecparam_config.C) { + size_t buf_len = 0, tmp_len = 0; + const EC_POINT *point; + int is_prime, len = 0; + const EC_METHOD *meth = EC_GROUP_method_of(group); + + if ((ec_p = BN_new()) == NULL || (ec_a = BN_new()) == NULL || + (ec_b = BN_new()) == NULL || (ec_gen = BN_new()) == NULL || + (ec_order = BN_new()) == NULL || + (ec_cofactor = BN_new()) == NULL) { + perror("malloc"); + goto end; + } + is_prime = (EC_METHOD_get_field_type(meth) == + NID_X9_62_prime_field); + + if (is_prime) { + if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a, + ec_b, NULL)) + goto end; + } else { + if (!EC_GROUP_get_curve_GF2m(group, ec_p, ec_a, + ec_b, NULL)) + goto end; + } + + if ((point = EC_GROUP_get0_generator(group)) == NULL) + goto end; + if (!EC_POINT_point2bn(group, point, + EC_GROUP_get_point_conversion_form(group), ec_gen, + NULL)) + goto end; + if (!EC_GROUP_get_order(group, ec_order, NULL)) + goto end; + if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL)) + goto end; + + len = BN_num_bits(ec_order); + + if ((tmp_len = (size_t) BN_num_bytes(ec_p)) > buf_len) + buf_len = tmp_len; + if ((tmp_len = (size_t) BN_num_bytes(ec_a)) > buf_len) + buf_len = tmp_len; + if ((tmp_len = (size_t) BN_num_bytes(ec_b)) > buf_len) + buf_len = tmp_len; + if ((tmp_len = (size_t) BN_num_bytes(ec_gen)) > buf_len) + buf_len = tmp_len; + if ((tmp_len = (size_t) BN_num_bytes(ec_order)) > buf_len) + buf_len = tmp_len; + if ((tmp_len = (size_t) BN_num_bytes(ec_cofactor)) > buf_len) + buf_len = tmp_len; + + buffer = malloc(buf_len); + + if (buffer == NULL) { + perror("malloc"); + goto end; + } + ecparam_print_var(out, ec_p, "ec_p", len, buffer); + ecparam_print_var(out, ec_a, "ec_a", len, buffer); + ecparam_print_var(out, ec_b, "ec_b", len, buffer); + ecparam_print_var(out, ec_gen, "ec_gen", len, buffer); + ecparam_print_var(out, ec_order, "ec_order", len, buffer); + ecparam_print_var(out, ec_cofactor, "ec_cofactor", len, + buffer); + + BIO_printf(out, "\n\n"); + + BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n\t{\n", len); + BIO_printf(out, "\tint ok=0;\n"); + BIO_printf(out, "\tEC_GROUP *group = NULL;\n"); + BIO_printf(out, "\tEC_POINT *point = NULL;\n"); + BIO_printf(out, "\tBIGNUM *tmp_1 = NULL, *tmp_2 = NULL, " + "*tmp_3 = NULL;\n\n"); + BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_p_%d, " + "sizeof(ec_p_%d), NULL)) == NULL)\n\t\t" + "goto err;\n", len, len); + BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_a_%d, " + "sizeof(ec_a_%d), NULL)) == NULL)\n\t\t" + "goto err;\n", len, len); + BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_b_%d, " + "sizeof(ec_b_%d), NULL)) == NULL)\n\t\t" + "goto err;\n", len, len); + if (is_prime) { + BIO_printf(out, "\tif ((group = EC_GROUP_new_curve_" + "GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)" + "\n\t\tgoto err;\n\n"); + } else { + BIO_printf(out, "\tif ((group = EC_GROUP_new_curve_" + "GF2m(tmp_1, tmp_2, tmp_3, NULL)) == NULL)" + "\n\t\tgoto err;\n\n"); + } + BIO_printf(out, "\t/* build generator */\n"); + BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_gen_%d, " + "sizeof(ec_gen_%d), tmp_1)) == NULL)" + "\n\t\tgoto err;\n", len, len); + BIO_printf(out, "\tpoint = EC_POINT_bn2point(group, tmp_1, " + "NULL, NULL);\n"); + BIO_printf(out, "\tif (point == NULL)\n\t\tgoto err;\n"); + BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_order_%d, " + "sizeof(ec_order_%d), tmp_2)) == NULL)" + "\n\t\tgoto err;\n", len, len); + BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_cofactor_%d, " + "sizeof(ec_cofactor_%d), tmp_3)) == NULL)" + "\n\t\tgoto err;\n", len, len); + BIO_printf(out, "\tif (!EC_GROUP_set_generator(group, point," + " tmp_2, tmp_3))\n\t\tgoto err;\n"); + BIO_printf(out, "\n\tok=1;\n"); + BIO_printf(out, "err:\n"); + BIO_printf(out, "\tif (tmp_1)\n\t\tBN_free(tmp_1);\n"); + BIO_printf(out, "\tif (tmp_2)\n\t\tBN_free(tmp_2);\n"); + BIO_printf(out, "\tif (tmp_3)\n\t\tBN_free(tmp_3);\n"); + BIO_printf(out, "\tif (point)\n\t\tEC_POINT_free(point);\n"); + BIO_printf(out, "\tif (!ok)\n"); + BIO_printf(out, "\t\t{\n"); + BIO_printf(out, "\t\tEC_GROUP_free(group);\n"); + BIO_printf(out, "\t\tgroup = NULL;\n"); + BIO_printf(out, "\t\t}\n"); + BIO_printf(out, "\treturn(group);\n\t}\n"); + } + if (!ecparam_config.noout) { + if (ecparam_config.outformat == FORMAT_ASN1) + i = i2d_ECPKParameters_bio(out, group); + else if (ecparam_config.outformat == FORMAT_PEM) + i = PEM_write_bio_ECPKParameters(out, group); + else { + BIO_printf(bio_err, "bad output format specified for" + " outfile\n"); + goto end; + } + if (!i) { + BIO_printf(bio_err, "unable to write elliptic " + "curve parameters\n"); + ERR_print_errors(bio_err); + goto end; + } + } + if (ecparam_config.genkey) { + EC_KEY *eckey = EC_KEY_new(); + + if (eckey == NULL) + goto end; + + if (EC_KEY_set_group(eckey, group) == 0) { + EC_KEY_free(eckey); + goto end; + } + + if (!EC_KEY_generate_key(eckey)) { + EC_KEY_free(eckey); + goto end; + } + if (ecparam_config.outformat == FORMAT_ASN1) + i = i2d_ECPrivateKey_bio(out, eckey); + else if (ecparam_config.outformat == FORMAT_PEM) + i = PEM_write_bio_ECPrivateKey(out, eckey, NULL, + NULL, 0, NULL, NULL); + else { + BIO_printf(bio_err, "bad output format specified " + "for outfile\n"); + EC_KEY_free(eckey); + goto end; + } + EC_KEY_free(eckey); + } + ret = 0; + +end: + BN_free(ec_p); + BN_free(ec_a); + BN_free(ec_b); + BN_free(ec_gen); + BN_free(ec_order); + BN_free(ec_cofactor); + + free(buffer); + + BIO_free(in); + BIO_free_all(out); + EC_GROUP_free(group); + + return (ret); +} + +static int +ecparam_print_var(BIO * out, BIGNUM * in, const char *var, + int len, unsigned char *buffer) +{ + BIO_printf(out, "static unsigned char %s_%d[] = {", var, len); + if (BN_is_zero(in)) + BIO_printf(out, "\n\t0x00"); + else { + int i, l; + + l = BN_bn2bin(in, buffer); + for (i = 0; i < l - 1; i++) { + if ((i % 12) == 0) + BIO_printf(out, "\n\t"); + BIO_printf(out, "0x%02X,", buffer[i]); + } + if ((i % 12) == 0) + BIO_printf(out, "\n\t"); + BIO_printf(out, "0x%02X", buffer[i]); + } + BIO_printf(out, "\n\t};\n\n"); + return 1; +} +#endif diff --git a/crypto/libressl/apps/openssl/enc.c b/crypto/libressl/apps/openssl/enc.c new file mode 100644 index 0000000000..7204936aa5 --- /dev/null +++ b/crypto/libressl/apps/openssl/enc.c @@ -0,0 +1,770 @@ +/* $OpenBSD: enc.c,v 1.10 2015/10/17 15:00:11 doug Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#include "apps.h" + +#include +#include +#include +#include +#include +#include +#include + +int set_hex(char *in, unsigned char *out, int size); + +#define SIZE (512) +#define BSIZE (8*1024) + +static struct { + int base64; + char *bufsize; + const EVP_CIPHER *cipher; + int debug; +#ifdef ZLIB + int do_zlib; +#endif + int enc; + char *hiv; + char *hkey; + char *hsalt; + char *inf; + char *keyfile; + char *keystr; + char *md; + int nopad; + int nosalt; + int olb64; + char *outf; + char *passarg; + int printkey; + int verbose; +} enc_config; + +static int +enc_opt_cipher(int argc, char **argv, int *argsused) +{ + char *name = argv[0]; + + if (*name++ != '-') + return (1); + + if (strcmp(name, "none") == 0) { + enc_config.cipher = NULL; + *argsused = 1; + return (0); + } + + if ((enc_config.cipher = EVP_get_cipherbyname(name)) != NULL) { + *argsused = 1; + return (0); + } + + return (1); +} + +static struct option enc_options[] = { + { + .name = "A", + .desc = "Process base64 data on one line (requires -a)", + .type = OPTION_FLAG, + .opt.flag = &enc_config.olb64, + }, + { + .name = "a", + .desc = "Perform base64 encoding/decoding (alias -base64)", + .type = OPTION_FLAG, + .opt.flag = &enc_config.base64, + }, + { + .name = "base64", + .type = OPTION_FLAG, + .opt.flag = &enc_config.base64, + }, + { + .name = "bufsize", + .argname = "size", + .desc = "Specify the buffer size to use for I/O", + .type = OPTION_ARG, + .opt.arg = &enc_config.bufsize, + }, + { + .name = "d", + .desc = "Decrypt the input data", + .type = OPTION_VALUE, + .opt.value = &enc_config.enc, + .value = 0, + }, + { + .name = "debug", + .desc = "Print debugging information", + .type = OPTION_FLAG, + .opt.flag = &enc_config.debug, + }, + { + .name = "e", + .desc = "Encrypt the input data (default)", + .type = OPTION_VALUE, + .opt.value = &enc_config.enc, + .value = 1, + }, + { + .name = "in", + .argname = "file", + .desc = "Input file to read from (default stdin)", + .type = OPTION_ARG, + .opt.arg = &enc_config.inf, + }, + { + .name = "iv", + .argname = "IV", + .desc = "IV to use, specified as a hexadecimal string", + .type = OPTION_ARG, + .opt.arg = &enc_config.hiv, + }, + { + .name = "K", + .argname = "key", + .desc = "Key to use, specified as a hexadecimal string", + .type = OPTION_ARG, + .opt.arg = &enc_config.hkey, + }, + { + .name = "k", /* Superseded by -pass. */ + .type = OPTION_ARG, + .opt.arg = &enc_config.keystr, + }, + { + .name = "kfile", /* Superseded by -pass. */ + .type = OPTION_ARG, + .opt.arg = &enc_config.keyfile, + }, + { + .name = "md", + .argname = "digest", + .desc = "Digest to use to create a key from the passphrase", + .type = OPTION_ARG, + .opt.arg = &enc_config.md, + }, + { + .name = "none", + .desc = "Use NULL cipher (no encryption or decryption)", + .type = OPTION_ARGV_FUNC, + .opt.argvfunc = enc_opt_cipher, + }, + { + .name = "nopad", + .desc = "Disable standard block padding", + .type = OPTION_FLAG, + .opt.flag = &enc_config.nopad, + }, + { + .name = "nosalt", + .type = OPTION_VALUE, + .opt.value = &enc_config.nosalt, + .value = 1, + }, + { + .name = "out", + .argname = "file", + .desc = "Output file to write to (default stdout)", + .type = OPTION_ARG, + .opt.arg = &enc_config.outf, + }, + { + .name = "P", + .desc = "Print out the salt, key and IV used, then exit\n" + " (no encryption or decryption is performed)", + .type = OPTION_VALUE, + .opt.value = &enc_config.printkey, + .value = 2, + }, + { + .name = "p", + .desc = "Print out the salt, key and IV used", + .type = OPTION_VALUE, + .opt.value = &enc_config.printkey, + .value = 1, + }, + { + .name = "pass", + .argname = "source", + .desc = "Password source", + .type = OPTION_ARG, + .opt.arg = &enc_config.passarg, + }, + { + .name = "S", + .argname = "salt", + .desc = "Salt to use, specified as a hexadecimal string", + .type = OPTION_ARG, + .opt.arg = &enc_config.hsalt, + }, + { + .name = "salt", + .desc = "Use a salt in the key derivation routines (default)", + .type = OPTION_VALUE, + .opt.value = &enc_config.nosalt, + .value = 0, + }, + { + .name = "v", + .desc = "Verbose", + .type = OPTION_FLAG, + .opt.flag = &enc_config.verbose, + }, +#ifdef ZLIB + { + .name = "z", + .desc = "Perform zlib compression/decompression", + .type = OPTION_FLAG, + .opt.flag = &enc_config.do_zlib, + }, +#endif + { + .name = NULL, + .type = OPTION_ARGV_FUNC, + .opt.argvfunc = enc_opt_cipher, + }, + { NULL }, +}; + +static void +show_ciphers(const OBJ_NAME *name, void *arg) +{ + static int n; + + if (!islower((unsigned char)*name->name)) + return; + + fprintf(stderr, " -%-24s%s", name->name, (++n % 3 ? "" : "\n")); +} + +static void +enc_usage(void) +{ + fprintf(stderr, "usage: enc -ciphername [-AadePp] [-base64] " + "[-bufsize number] [-debug]\n" + " [-in file] [-iv IV] [-K key] [-k password]\n" + " [-kfile file] [-md digest] [-none] [-nopad] [-nosalt]\n" + " [-out file] [-pass arg] [-S salt] [-salt]\n\n"); + options_usage(enc_options); + fprintf(stderr, "\n"); + + fprintf(stderr, "Valid ciphername values:\n\n"); + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_ciphers, NULL); + fprintf(stderr, "\n"); +} + +int +enc_main(int argc, char **argv) +{ + static const char magic[] = "Salted__"; + char mbuf[sizeof magic - 1]; + char *strbuf = NULL, *pass = NULL; + unsigned char *buff = NULL; + int bsize = BSIZE; + int ret = 1, inl; + unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; + unsigned char salt[PKCS5_SALT_LEN]; +#ifdef ZLIB + BIO *bzl = NULL; +#endif + EVP_CIPHER_CTX *ctx = NULL; + const EVP_MD *dgst = NULL; + BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL; + BIO *rbio = NULL, *wbio = NULL; +#define PROG_NAME_SIZE 39 + char pname[PROG_NAME_SIZE + 1]; + int i; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + memset(&enc_config, 0, sizeof(enc_config)); + enc_config.enc = 1; + + /* first check the program name */ + program_name(argv[0], pname, sizeof(pname)); + + if (strcmp(pname, "base64") == 0) + enc_config.base64 = 1; + +#ifdef ZLIB + if (strcmp(pname, "zlib") == 0) + enc_config.do_zlib = 1; +#endif + + enc_config.cipher = EVP_get_cipherbyname(pname); + +#ifdef ZLIB + if (!enc_config.do_zlib && !enc_config.base64 && + enc_config.cipher == NULL && strcmp(pname, "enc") != 0) +#else + if (!enc_config.base64 && enc_config.cipher == NULL && + strcmp(pname, "enc") != 0) +#endif + { + BIO_printf(bio_err, "%s is an unknown cipher\n", pname); + goto end; + } + + if (options_parse(argc, argv, enc_options, NULL, NULL) != 0) { + enc_usage(); + goto end; + } + + if (enc_config.keyfile != NULL) { + static char buf[128]; + FILE *infile; + + infile = fopen(enc_config.keyfile, "r"); + if (infile == NULL) { + BIO_printf(bio_err, "unable to read key from '%s'\n", + enc_config.keyfile); + goto end; + } + buf[0] = '\0'; + if (!fgets(buf, sizeof buf, infile)) { + BIO_printf(bio_err, "unable to read key from '%s'\n", + enc_config.keyfile); + fclose(infile); + goto end; + } + fclose(infile); + i = strlen(buf); + if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) + buf[--i] = '\0'; + if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) + buf[--i] = '\0'; + if (i < 1) { + BIO_printf(bio_err, "zero length password\n"); + goto end; + } + enc_config.keystr = buf; + } + + if (enc_config.md != NULL && + (dgst = EVP_get_digestbyname(enc_config.md)) == NULL) { + BIO_printf(bio_err, + "%s is an unsupported message digest type\n", + enc_config.md); + goto end; + } + if (dgst == NULL) { + dgst = EVP_md5(); /* XXX */ + } + + if (enc_config.bufsize != NULL) { + char *p = enc_config.bufsize; + unsigned long n; + + /* XXX - provide an OPTION_ARG_DISKUNIT. */ + for (n = 0; *p != '\0'; p++) { + i = *p; + if ((i <= '9') && (i >= '0')) + n = n * 10 + i - '0'; + else if (i == 'k') { + n *= 1024; + p++; + break; + } + } + if (*p != '\0') { + BIO_printf(bio_err, "invalid 'bufsize' specified.\n"); + goto end; + } + /* It must be large enough for a base64 encoded line. */ + if (enc_config.base64 && n < 80) + n = 80; + + bsize = (int)n; + if (enc_config.verbose) + BIO_printf(bio_err, "bufsize=%d\n", bsize); + } + strbuf = malloc(SIZE); + buff = malloc(EVP_ENCODE_LENGTH(bsize)); + if ((buff == NULL) || (strbuf == NULL)) { + BIO_printf(bio_err, "malloc failure %ld\n", (long) EVP_ENCODE_LENGTH(bsize)); + goto end; + } + in = BIO_new(BIO_s_file()); + out = BIO_new(BIO_s_file()); + if ((in == NULL) || (out == NULL)) { + ERR_print_errors(bio_err); + goto end; + } + if (enc_config.debug) { + BIO_set_callback(in, BIO_debug_callback); + BIO_set_callback(out, BIO_debug_callback); + BIO_set_callback_arg(in, (char *) bio_err); + BIO_set_callback_arg(out, (char *) bio_err); + } + if (enc_config.inf == NULL) { + if (enc_config.bufsize != NULL) + setvbuf(stdin, (char *) NULL, _IONBF, 0); + BIO_set_fp(in, stdin, BIO_NOCLOSE); + } else { + if (BIO_read_filename(in, enc_config.inf) <= 0) { + perror(enc_config.inf); + goto end; + } + } + + if (!enc_config.keystr && enc_config.passarg) { + if (!app_passwd(bio_err, enc_config.passarg, NULL, + &pass, NULL)) { + BIO_printf(bio_err, "Error getting password\n"); + goto end; + } + enc_config.keystr = pass; + } + if (enc_config.keystr == NULL && enc_config.cipher != NULL && + enc_config.hkey == NULL) { + for (;;) { + char buf[200]; + int retval; + + retval = snprintf(buf, sizeof buf, + "enter %s %s password:", + OBJ_nid2ln(EVP_CIPHER_nid(enc_config.cipher)), + enc_config.enc ? "encryption" : "decryption"); + if ((size_t)retval >= sizeof buf) { + BIO_printf(bio_err, + "Password prompt too long\n"); + goto end; + } + strbuf[0] = '\0'; + i = EVP_read_pw_string((char *)strbuf, SIZE, buf, + enc_config.enc); + if (i == 0) { + if (strbuf[0] == '\0') { + ret = 1; + goto end; + } + enc_config.keystr = strbuf; + break; + } + if (i < 0) { + BIO_printf(bio_err, "bad password read\n"); + goto end; + } + } + } + if (enc_config.outf == NULL) { + BIO_set_fp(out, stdout, BIO_NOCLOSE); + if (enc_config.bufsize != NULL) + setvbuf(stdout, (char *)NULL, _IONBF, 0); + } else { + if (BIO_write_filename(out, enc_config.outf) <= 0) { + perror(enc_config.outf); + goto end; + } + } + + rbio = in; + wbio = out; + +#ifdef ZLIB + if (do_zlib) { + if ((bzl = BIO_new(BIO_f_zlib())) == NULL) + goto end; + if (enc) + wbio = BIO_push(bzl, wbio); + else + rbio = BIO_push(bzl, rbio); + } +#endif + + if (enc_config.base64) { + if ((b64 = BIO_new(BIO_f_base64())) == NULL) + goto end; + if (enc_config.debug) { + BIO_set_callback(b64, BIO_debug_callback); + BIO_set_callback_arg(b64, (char *) bio_err); + } + if (enc_config.olb64) + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + if (enc_config.enc) + wbio = BIO_push(b64, wbio); + else + rbio = BIO_push(b64, rbio); + } + if (enc_config.cipher != NULL) { + /* + * Note that keystr is NULL if a key was passed on the command + * line, so we get no salt in that case. Is this a bug? + */ + if (enc_config.keystr != NULL) { + /* + * Salt handling: if encrypting generate a salt and + * write to output BIO. If decrypting read salt from + * input BIO. + */ + unsigned char *sptr; + if (enc_config.nosalt) + sptr = NULL; + else { + if (enc_config.enc) { + if (enc_config.hsalt) { + if (!set_hex(enc_config.hsalt, salt, sizeof salt)) { + BIO_printf(bio_err, + "invalid hex salt value\n"); + goto end; + } + } else + arc4random_buf(salt, + sizeof(salt)); + /* + * If -P option then don't bother + * writing + */ + if ((enc_config.printkey != 2) + && (BIO_write(wbio, magic, + sizeof magic - 1) != sizeof magic - 1 + || BIO_write(wbio, + (char *) salt, + sizeof salt) != sizeof salt)) { + BIO_printf(bio_err, "error writing output file\n"); + goto end; + } + } else if (BIO_read(rbio, mbuf, sizeof mbuf) != sizeof mbuf + || BIO_read(rbio, + (unsigned char *) salt, + sizeof salt) != sizeof salt) { + BIO_printf(bio_err, "error reading input file\n"); + goto end; + } else if (memcmp(mbuf, magic, sizeof magic - 1)) { + BIO_printf(bio_err, "bad magic number\n"); + goto end; + } + sptr = salt; + } + + EVP_BytesToKey(enc_config.cipher, dgst, sptr, + (unsigned char *)enc_config.keystr, + strlen(enc_config.keystr), 1, key, iv); + /* + * zero the complete buffer or the string passed from + * the command line bug picked up by Larry J. Hughes + * Jr. + */ + if (enc_config.keystr == strbuf) + explicit_bzero(enc_config.keystr, SIZE); + else + explicit_bzero(enc_config.keystr, + strlen(enc_config.keystr)); + } + if (enc_config.hiv != NULL && + !set_hex(enc_config.hiv, iv, sizeof iv)) { + BIO_printf(bio_err, "invalid hex iv value\n"); + goto end; + } + if (enc_config.hiv == NULL && enc_config.keystr == NULL && + EVP_CIPHER_iv_length(enc_config.cipher) != 0) { + /* + * No IV was explicitly set and no IV was generated + * during EVP_BytesToKey. Hence the IV is undefined, + * making correct decryption impossible. + */ + BIO_printf(bio_err, "iv undefined\n"); + goto end; + } + if (enc_config.hkey != NULL && + !set_hex(enc_config.hkey, key, sizeof key)) { + BIO_printf(bio_err, "invalid hex key value\n"); + goto end; + } + if ((benc = BIO_new(BIO_f_cipher())) == NULL) + goto end; + + /* + * Since we may be changing parameters work on the encryption + * context rather than calling BIO_set_cipher(). + */ + + BIO_get_cipher_ctx(benc, &ctx); + + if (!EVP_CipherInit_ex(ctx, enc_config.cipher, NULL, NULL, + NULL, enc_config.enc)) { + BIO_printf(bio_err, "Error setting cipher %s\n", + EVP_CIPHER_name(enc_config.cipher)); + ERR_print_errors(bio_err); + goto end; + } + if (enc_config.nopad) + EVP_CIPHER_CTX_set_padding(ctx, 0); + + if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, + enc_config.enc)) { + BIO_printf(bio_err, "Error setting cipher %s\n", + EVP_CIPHER_name(enc_config.cipher)); + ERR_print_errors(bio_err); + goto end; + } + if (enc_config.debug) { + BIO_set_callback(benc, BIO_debug_callback); + BIO_set_callback_arg(benc, (char *) bio_err); + } + if (enc_config.printkey) { + if (!enc_config.nosalt) { + printf("salt="); + for (i = 0; i < (int) sizeof(salt); i++) + printf("%02X", salt[i]); + printf("\n"); + } + if (enc_config.cipher->key_len > 0) { + printf("key="); + for (i = 0; i < enc_config.cipher->key_len; i++) + printf("%02X", key[i]); + printf("\n"); + } + if (enc_config.cipher->iv_len > 0) { + printf("iv ="); + for (i = 0; i < enc_config.cipher->iv_len; i++) + printf("%02X", iv[i]); + printf("\n"); + } + if (enc_config.printkey == 2) { + ret = 0; + goto end; + } + } + } + /* Only encrypt/decrypt as we write the file */ + if (benc != NULL) + wbio = BIO_push(benc, wbio); + + for (;;) { + inl = BIO_read(rbio, (char *) buff, bsize); + if (inl <= 0) + break; + if (BIO_write(wbio, (char *) buff, inl) != inl) { + BIO_printf(bio_err, "error writing output file\n"); + goto end; + } + } + if (!BIO_flush(wbio)) { + BIO_printf(bio_err, "bad decrypt\n"); + goto end; + } + ret = 0; + if (enc_config.verbose) { + BIO_printf(bio_err, "bytes read :%8ld\n", BIO_number_read(in)); + BIO_printf(bio_err, "bytes written:%8ld\n", BIO_number_written(out)); + } +end: + ERR_print_errors(bio_err); + free(strbuf); + free(buff); + BIO_free(in); + if (out != NULL) + BIO_free_all(out); + BIO_free(benc); + BIO_free(b64); +#ifdef ZLIB + BIO_free(bzl); +#endif + free(pass); + + return (ret); +} + +int +set_hex(char *in, unsigned char *out, int size) +{ + int i, n; + unsigned char j; + + n = strlen(in); + if (n > (size * 2)) { + BIO_printf(bio_err, "hex string is too long\n"); + return (0); + } + memset(out, 0, size); + for (i = 0; i < n; i++) { + j = (unsigned char) *in; + *(in++) = '\0'; + if (j == 0) + break; + if ((j >= '0') && (j <= '9')) + j -= '0'; + else if ((j >= 'A') && (j <= 'F')) + j = j - 'A' + 10; + else if ((j >= 'a') && (j <= 'f')) + j = j - 'a' + 10; + else { + BIO_printf(bio_err, "non-hex digit\n"); + return (0); + } + if (i & 1) + out[i / 2] |= j; + else + out[i / 2] = (j << 4); + } + return (1); +} diff --git a/crypto/libressl/apps/openssl/errstr.c b/crypto/libressl/apps/openssl/errstr.c new file mode 100644 index 0000000000..5ce5e60426 --- /dev/null +++ b/crypto/libressl/apps/openssl/errstr.c @@ -0,0 +1,148 @@ +/* $OpenBSD: errstr.c,v 1.5 2015/10/10 22:28:51 doug Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#include "apps.h" + +#include +#include +#include +#include + +struct { + int stats; +} errstr_config; + +struct option errstr_options[] = { + { + .name = "stats", + .desc = "Print debugging statistics for the hash table", + .type = OPTION_FLAG, + .opt.flag = &errstr_config.stats, + }, + { NULL }, +}; + +static void +errstr_usage() +{ + fprintf(stderr, "usage: errstr [-stats] errno ...\n"); + options_usage(errstr_options); +} + +int +errstr_main(int argc, char **argv) +{ + unsigned long ulval; + char *ularg, *ep; + int argsused, i; + char buf[256]; + int ret = 0; + + if (single_execution) { + if (pledge("stdio rpath", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + memset(&errstr_config, 0, sizeof(errstr_config)); + + if (options_parse(argc, argv, errstr_options, NULL, &argsused) != 0) { + errstr_usage(); + return (1); + } + + if (errstr_config.stats) { + BIO *out; + + if ((out = BIO_new_fp(stdout, BIO_NOCLOSE)) == NULL) { + fprintf(stderr, "Out of memory"); + return (1); + } + + lh_ERR_STRING_DATA_node_stats_bio(ERR_get_string_table(), out); + lh_ERR_STRING_DATA_stats_bio(ERR_get_string_table(), out); + lh_ERR_STRING_DATA_node_usage_stats_bio( + ERR_get_string_table(), out); + + BIO_free_all(out); + } + + for (i = argsused; i < argc; i++) { + errno = 0; + ularg = argv[i]; + ulval = strtoul(ularg, &ep, 16); + if (strchr(ularg, '-') != NULL || + (ularg[0] == '\0' || *ep != '\0') || + (errno == ERANGE && ulval == ULONG_MAX)) { + printf("%s: bad error code\n", ularg); + ret++; + continue; + } + + ERR_error_string_n(ulval, buf, sizeof(buf)); + printf("%s\n", buf); + } + + return (ret); +} diff --git a/crypto/libressl/apps/openssl/gendh.c b/crypto/libressl/apps/openssl/gendh.c new file mode 100644 index 0000000000..09dfdd118f --- /dev/null +++ b/crypto/libressl/apps/openssl/gendh.c @@ -0,0 +1,217 @@ +/* $OpenBSD: gendh.c,v 1.6 2015/10/10 22:28:51 doug Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +/* Until the key-gen callbacks are modified to use newer prototypes, we allow + * deprecated functions for openssl-internal code */ +#ifdef OPENSSL_NO_DEPRECATED +#undef OPENSSL_NO_DEPRECATED +#endif + +#ifndef OPENSSL_NO_DH + +#include +#include + +#include +#include +#include + +#include "apps.h" + +#include +#include +#include +#include +#include +#include + +#define DEFBITS 512 + +static int dh_cb(int p, int n, BN_GENCB * cb); + +static struct { + int g; + char *outfile; +} gendh_config; + +static struct option gendh_options[] = { + { + .name = "2", + .desc = "Generate DH parameters with a generator value of 2 " + "(default)", + .type = OPTION_VALUE, + .value = 2, + .opt.value = &gendh_config.g, + }, + { + .name = "5", + .desc = "Generate DH parameters with a generator value of 5", + .type = OPTION_VALUE, + .value = 5, + .opt.value = &gendh_config.g, + }, + { + .name = "out", + .argname = "file", + .desc = "Output file (default stdout)", + .type = OPTION_ARG, + .opt.arg = &gendh_config.outfile, + }, + { NULL }, +}; + +static void +gendh_usage(void) +{ + fprintf(stderr, + "usage: gendh [-2 | -5] [-out file] [numbits]\n\n"); + options_usage(gendh_options); +} + +int +gendh_main(int argc, char **argv) +{ + BN_GENCB cb; + DH *dh = NULL; + int ret = 1, numbits = DEFBITS; + BIO *out = NULL; + char *strbits = NULL; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + BN_GENCB_set(&cb, dh_cb, bio_err); + + memset(&gendh_config, 0, sizeof(gendh_config)); + + gendh_config.g = 2; + + if (options_parse(argc, argv, gendh_options, &strbits, NULL) != 0) { + gendh_usage(); + goto end; + } + + if (strbits != NULL) { + const char *errstr; + numbits = strtonum(strbits, 0, INT_MAX, &errstr); + if (errstr) { + fprintf(stderr, "Invalid number of bits: %s\n", errstr); + goto end; + } + } + + out = BIO_new(BIO_s_file()); + if (out == NULL) { + ERR_print_errors(bio_err); + goto end; + } + if (gendh_config.outfile == NULL) { + BIO_set_fp(out, stdout, BIO_NOCLOSE); + } else { + if (BIO_write_filename(out, gendh_config.outfile) <= 0) { + perror(gendh_config.outfile); + goto end; + } + } + + BIO_printf(bio_err, "Generating DH parameters, %d bit long safe prime," + " generator %d\n", numbits, gendh_config.g); + BIO_printf(bio_err, "This is going to take a long time\n"); + + if (((dh = DH_new()) == NULL) || + !DH_generate_parameters_ex(dh, numbits, gendh_config.g, &cb)) + goto end; + + if (!PEM_write_bio_DHparams(out, dh)) + goto end; + ret = 0; +end: + if (ret != 0) + ERR_print_errors(bio_err); + if (out != NULL) + BIO_free_all(out); + if (dh != NULL) + DH_free(dh); + + return (ret); +} + +static int +dh_cb(int p, int n, BN_GENCB * cb) +{ + char c = '*'; + + if (p == 0) + c = '.'; + if (p == 1) + c = '+'; + if (p == 2) + c = '*'; + if (p == 3) + c = '\n'; + BIO_write(cb->arg, &c, 1); + (void) BIO_flush(cb->arg); + return 1; +} +#endif diff --git a/crypto/libressl/apps/openssl/gendsa.c b/crypto/libressl/apps/openssl/gendsa.c new file mode 100644 index 0000000000..bdf4c571f9 --- /dev/null +++ b/crypto/libressl/apps/openssl/gendsa.c @@ -0,0 +1,216 @@ +/* $OpenBSD: gendsa.c,v 1.6 2015/10/17 07:51:10 semarie Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include /* for OPENSSL_NO_DSA */ + + +#include +#include + +#include +#include + +#include "apps.h" + +#include +#include +#include +#include +#include +#include + +int +gendsa_main(int argc, char **argv) +{ + DSA *dsa = NULL; + int ret = 1; + char *outfile = NULL; + char *dsaparams = NULL; + char *passargout = NULL, *passout = NULL; + BIO *out = NULL, *in = NULL; + const EVP_CIPHER *enc = NULL; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + argv++; + argc--; + for (;;) { + if (argc <= 0) + break; + if (strcmp(*argv, "-out") == 0) { + if (--argc < 1) + goto bad; + outfile = *(++argv); + } else if (strcmp(*argv, "-passout") == 0) { + if (--argc < 1) + goto bad; + passargout = *(++argv); + } + else if (strcmp(*argv, "-") == 0) + goto bad; +#ifndef OPENSSL_NO_DES + else if (strcmp(*argv, "-des") == 0) + enc = EVP_des_cbc(); + else if (strcmp(*argv, "-des3") == 0) + enc = EVP_des_ede3_cbc(); +#endif +#ifndef OPENSSL_NO_IDEA + else if (strcmp(*argv, "-idea") == 0) + enc = EVP_idea_cbc(); +#endif +#ifndef OPENSSL_NO_AES + else if (strcmp(*argv, "-aes128") == 0) + enc = EVP_aes_128_cbc(); + else if (strcmp(*argv, "-aes192") == 0) + enc = EVP_aes_192_cbc(); + else if (strcmp(*argv, "-aes256") == 0) + enc = EVP_aes_256_cbc(); +#endif +#ifndef OPENSSL_NO_CAMELLIA + else if (strcmp(*argv, "-camellia128") == 0) + enc = EVP_camellia_128_cbc(); + else if (strcmp(*argv, "-camellia192") == 0) + enc = EVP_camellia_192_cbc(); + else if (strcmp(*argv, "-camellia256") == 0) + enc = EVP_camellia_256_cbc(); +#endif + else if (**argv != '-' && dsaparams == NULL) { + dsaparams = *argv; + } else + goto bad; + argv++; + argc--; + } + + if (dsaparams == NULL) { +bad: + BIO_printf(bio_err, "usage: gendsa [args] dsaparam-file\n"); + BIO_printf(bio_err, " -out file - output the key to 'file'\n"); +#ifndef OPENSSL_NO_DES + BIO_printf(bio_err, " -des - encrypt the generated key with DES in cbc mode\n"); + BIO_printf(bio_err, " -des3 - encrypt the generated key with DES in ede cbc mode (168 bit key)\n"); +#endif +#ifndef OPENSSL_NO_IDEA + BIO_printf(bio_err, " -idea - encrypt the generated key with IDEA in cbc mode\n"); +#endif +#ifndef OPENSSL_NO_AES + BIO_printf(bio_err, " -aes128, -aes192, -aes256\n"); + BIO_printf(bio_err, " encrypt PEM output with cbc aes\n"); +#endif +#ifndef OPENSSL_NO_CAMELLIA + BIO_printf(bio_err, " -camellia128, -camellia192, -camellia256\n"); + BIO_printf(bio_err, " encrypt PEM output with cbc camellia\n"); +#endif + BIO_printf(bio_err, " dsaparam-file\n"); + BIO_printf(bio_err, " - a DSA parameter file as generated by the dsaparam command\n"); + goto end; + } + if (!app_passwd(bio_err, NULL, passargout, NULL, &passout)) { + BIO_printf(bio_err, "Error getting password\n"); + goto end; + } + in = BIO_new(BIO_s_file()); + if (!(BIO_read_filename(in, dsaparams))) { + perror(dsaparams); + goto end; + } + if ((dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL)) == NULL) { + BIO_printf(bio_err, "unable to load DSA parameter file\n"); + goto end; + } + BIO_free(in); + in = NULL; + + out = BIO_new(BIO_s_file()); + if (out == NULL) + goto end; + + if (outfile == NULL) { + BIO_set_fp(out, stdout, BIO_NOCLOSE); + } else { + if (BIO_write_filename(out, outfile) <= 0) { + perror(outfile); + goto end; + } + } + + BIO_printf(bio_err, "Generating DSA key, %d bits\n", + BN_num_bits(dsa->p)); + if (!DSA_generate_key(dsa)) + goto end; + + if (!PEM_write_bio_DSAPrivateKey(out, dsa, enc, NULL, 0, NULL, passout)) + goto end; + ret = 0; +end: + if (ret != 0) + ERR_print_errors(bio_err); + BIO_free(in); + if (out != NULL) + BIO_free_all(out); + if (dsa != NULL) + DSA_free(dsa); + free(passout); + + return (ret); +} diff --git a/crypto/libressl/apps/openssl/genpkey.c b/crypto/libressl/apps/openssl/genpkey.c new file mode 100644 index 0000000000..6e21608d3a --- /dev/null +++ b/crypto/libressl/apps/openssl/genpkey.c @@ -0,0 +1,359 @@ +/* $OpenBSD: genpkey.c,v 1.7 2015/10/17 07:51:10 semarie Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006 + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include "apps.h" + +#include +#include +#include + +static int +init_keygen_file(BIO * err, EVP_PKEY_CTX ** pctx, const char *file); +static int genpkey_cb(EVP_PKEY_CTX * ctx); + +int +genpkey_main(int argc, char **argv) +{ + char **args, *outfile = NULL; + char *passarg = NULL; + BIO *in = NULL, *out = NULL; + const EVP_CIPHER *cipher = NULL; + int outformat; + int text = 0; + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx = NULL; + char *pass = NULL; + int badarg = 0; + int ret = 1, rv; + + int do_param = 0; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + outformat = FORMAT_PEM; + + args = argv + 1; + while (!badarg && *args && *args[0] == '-') { + if (!strcmp(*args, "-outform")) { + if (args[1]) { + args++; + outformat = str2fmt(*args); + } else + badarg = 1; + } else if (!strcmp(*args, "-pass")) { + if (!args[1]) + goto bad; + passarg = *(++args); + } + else if (!strcmp(*args, "-paramfile")) { + if (!args[1]) + goto bad; + args++; + if (do_param == 1) + goto bad; + if (!init_keygen_file(bio_err, &ctx, *args)) + goto end; + } else if (!strcmp(*args, "-out")) { + if (args[1]) { + args++; + outfile = *args; + } else + badarg = 1; + } else if (strcmp(*args, "-algorithm") == 0) { + if (!args[1]) + goto bad; + if (!init_gen_str(bio_err, &ctx, *(++args), do_param)) + goto end; + } else if (strcmp(*args, "-pkeyopt") == 0) { + if (!args[1]) + goto bad; + if (!ctx) { + BIO_puts(bio_err, "No keytype specified\n"); + goto bad; + } else if (pkey_ctrl_string(ctx, *(++args)) <= 0) { + BIO_puts(bio_err, "parameter setting error\n"); + ERR_print_errors(bio_err); + goto end; + } + } else if (strcmp(*args, "-genparam") == 0) { + if (ctx) + goto bad; + do_param = 1; + } else if (strcmp(*args, "-text") == 0) + text = 1; + else { + cipher = EVP_get_cipherbyname(*args + 1); + if (!cipher) { + BIO_printf(bio_err, "Unknown cipher %s\n", + *args + 1); + badarg = 1; + } + if (do_param == 1) + badarg = 1; + } + args++; + } + + if (!ctx) + badarg = 1; + + if (badarg) { +bad: + BIO_printf(bio_err, "Usage: genpkey [options]\n"); + BIO_printf(bio_err, "where options may be\n"); + BIO_printf(bio_err, "-out file output file\n"); + BIO_printf(bio_err, "-outform X output format (DER or PEM)\n"); + BIO_printf(bio_err, "-pass arg output file pass phrase source\n"); + BIO_printf(bio_err, "- use cipher to encrypt the key\n"); + BIO_printf(bio_err, "-paramfile file parameters file\n"); + BIO_printf(bio_err, "-algorithm alg the public key algorithm\n"); + BIO_printf(bio_err, "-pkeyopt opt:value set the public key algorithm option \n" + " to value \n"); + BIO_printf(bio_err, "-genparam generate parameters, not key\n"); + BIO_printf(bio_err, "-text print the in text\n"); + BIO_printf(bio_err, "NB: options order may be important! See the manual page.\n"); + goto end; + } + if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { + BIO_puts(bio_err, "Error getting password\n"); + goto end; + } + if (outfile) { + if (!(out = BIO_new_file(outfile, "wb"))) { + BIO_printf(bio_err, + "Can't open output file %s\n", outfile); + goto end; + } + } else { + out = BIO_new_fp(stdout, BIO_NOCLOSE); + } + + EVP_PKEY_CTX_set_cb(ctx, genpkey_cb); + EVP_PKEY_CTX_set_app_data(ctx, bio_err); + + if (do_param) { + if (EVP_PKEY_paramgen(ctx, &pkey) <= 0) { + BIO_puts(bio_err, "Error generating parameters\n"); + ERR_print_errors(bio_err); + goto end; + } + } else { + if (EVP_PKEY_keygen(ctx, &pkey) <= 0) { + BIO_puts(bio_err, "Error generating key\n"); + ERR_print_errors(bio_err); + goto end; + } + } + + if (do_param) + rv = PEM_write_bio_Parameters(out, pkey); + else if (outformat == FORMAT_PEM) + rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, + NULL, pass); + else if (outformat == FORMAT_ASN1) + rv = i2d_PrivateKey_bio(out, pkey); + else { + BIO_printf(bio_err, "Bad format specified for key\n"); + goto end; + } + + if (rv <= 0) { + BIO_puts(bio_err, "Error writing key\n"); + ERR_print_errors(bio_err); + } + if (text) { + if (do_param) + rv = EVP_PKEY_print_params(out, pkey, 0, NULL); + else + rv = EVP_PKEY_print_private(out, pkey, 0, NULL); + + if (rv <= 0) { + BIO_puts(bio_err, "Error printing key\n"); + ERR_print_errors(bio_err); + } + } + ret = 0; + +end: + if (pkey) + EVP_PKEY_free(pkey); + if (ctx) + EVP_PKEY_CTX_free(ctx); + if (out) + BIO_free_all(out); + BIO_free(in); + free(pass); + + return ret; +} + +static int +init_keygen_file(BIO * err, EVP_PKEY_CTX ** pctx, + const char *file) +{ + BIO *pbio; + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx = NULL; + if (*pctx) { + BIO_puts(err, "Parameters already set!\n"); + return 0; + } + pbio = BIO_new_file(file, "r"); + if (!pbio) { + BIO_printf(err, "Can't open parameter file %s\n", file); + return 0; + } + pkey = PEM_read_bio_Parameters(pbio, NULL); + BIO_free(pbio); + + if (!pkey) { + BIO_printf(bio_err, "Error reading parameter file %s\n", file); + return 0; + } + ctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!ctx) + goto err; + if (EVP_PKEY_keygen_init(ctx) <= 0) + goto err; + EVP_PKEY_free(pkey); + *pctx = ctx; + return 1; + +err: + BIO_puts(err, "Error initializing context\n"); + ERR_print_errors(err); + if (ctx) + EVP_PKEY_CTX_free(ctx); + if (pkey) + EVP_PKEY_free(pkey); + return 0; + +} + +int +init_gen_str(BIO * err, EVP_PKEY_CTX ** pctx, + const char *algname, int do_param) +{ + EVP_PKEY_CTX *ctx = NULL; + const EVP_PKEY_ASN1_METHOD *ameth; + int pkey_id; + + if (*pctx) { + BIO_puts(err, "Algorithm already set!\n"); + return 0; + } + ameth = EVP_PKEY_asn1_find_str(NULL, algname, -1); + + if (!ameth) { + BIO_printf(bio_err, "Algorithm %s not found\n", algname); + return 0; + } + ERR_clear_error(); + + EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); + ctx = EVP_PKEY_CTX_new_id(pkey_id, NULL); + + if (!ctx) + goto err; + if (do_param) { + if (EVP_PKEY_paramgen_init(ctx) <= 0) + goto err; + } else { + if (EVP_PKEY_keygen_init(ctx) <= 0) + goto err; + } + + *pctx = ctx; + return 1; + +err: + BIO_printf(err, "Error initializing %s context\n", algname); + ERR_print_errors(err); + if (ctx) + EVP_PKEY_CTX_free(ctx); + return 0; + +} + +static int +genpkey_cb(EVP_PKEY_CTX * ctx) +{ + char c = '*'; + BIO *b = EVP_PKEY_CTX_get_app_data(ctx); + int p; + p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); + if (p == 0) + c = '.'; + if (p == 1) + c = '+'; + if (p == 2) + c = '*'; + if (p == 3) + c = '\n'; + BIO_write(b, &c, 1); + (void) BIO_flush(b); + return 1; +} diff --git a/crypto/libressl/apps/openssl/genrsa.c b/crypto/libressl/apps/openssl/genrsa.c new file mode 100644 index 0000000000..e2196427b0 --- /dev/null +++ b/crypto/libressl/apps/openssl/genrsa.c @@ -0,0 +1,266 @@ +/* $OpenBSD: genrsa.c,v 1.7 2015/10/17 07:51:10 semarie Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +/* Until the key-gen callbacks are modified to use newer prototypes, we allow + * deprecated functions for openssl-internal code */ +#ifdef OPENSSL_NO_DEPRECATED +#undef OPENSSL_NO_DEPRECATED +#endif + + +#include +#include + +#include +#include + +#include "apps.h" + +#include +#include +#include +#include +#include +#include +#include + +#define DEFBITS 2048 + +static int genrsa_cb(int p, int n, BN_GENCB * cb); + +int +genrsa_main(int argc, char **argv) +{ + BN_GENCB cb; + int ret = 1; + int i, num = DEFBITS; + long l; + const EVP_CIPHER *enc = NULL; + unsigned long f4 = RSA_F4; + char *outfile = NULL; + char *passargout = NULL, *passout = NULL; + BIO *out = NULL; + BIGNUM *bn = BN_new(); + RSA *rsa = NULL; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + if (!bn) + goto err; + + BN_GENCB_set(&cb, genrsa_cb, bio_err); + + if ((out = BIO_new(BIO_s_file())) == NULL) { + BIO_printf(bio_err, "unable to create BIO for output\n"); + goto err; + } + argv++; + argc--; + for (;;) { + if (argc <= 0) + break; + if (strcmp(*argv, "-out") == 0) { + if (--argc < 1) + goto bad; + outfile = *(++argv); + } else if (strcmp(*argv, "-3") == 0) + f4 = 3; + else if (strcmp(*argv, "-F4") == 0 || strcmp(*argv, "-f4") == 0) + f4 = RSA_F4; +#ifndef OPENSSL_NO_DES + else if (strcmp(*argv, "-des") == 0) + enc = EVP_des_cbc(); + else if (strcmp(*argv, "-des3") == 0) + enc = EVP_des_ede3_cbc(); +#endif +#ifndef OPENSSL_NO_IDEA + else if (strcmp(*argv, "-idea") == 0) + enc = EVP_idea_cbc(); +#endif +#ifndef OPENSSL_NO_AES + else if (strcmp(*argv, "-aes128") == 0) + enc = EVP_aes_128_cbc(); + else if (strcmp(*argv, "-aes192") == 0) + enc = EVP_aes_192_cbc(); + else if (strcmp(*argv, "-aes256") == 0) + enc = EVP_aes_256_cbc(); +#endif +#ifndef OPENSSL_NO_CAMELLIA + else if (strcmp(*argv, "-camellia128") == 0) + enc = EVP_camellia_128_cbc(); + else if (strcmp(*argv, "-camellia192") == 0) + enc = EVP_camellia_192_cbc(); + else if (strcmp(*argv, "-camellia256") == 0) + enc = EVP_camellia_256_cbc(); +#endif + else if (strcmp(*argv, "-passout") == 0) { + if (--argc < 1) + goto bad; + passargout = *(++argv); + } else + break; + argv++; + argc--; + } + if ((argc >= 1) && ((sscanf(*argv, "%d", &num) == 0) || (num < 0))) { +bad: + BIO_printf(bio_err, "usage: genrsa [args] [numbits]\n"); + BIO_printf(bio_err, " -des encrypt the generated key with DES in cbc mode\n"); + BIO_printf(bio_err, " -des3 encrypt the generated key with DES in ede cbc mode (168 bit key)\n"); +#ifndef OPENSSL_NO_IDEA + BIO_printf(bio_err, " -idea encrypt the generated key with IDEA in cbc mode\n"); +#endif +#ifndef OPENSSL_NO_AES + BIO_printf(bio_err, " -aes128, -aes192, -aes256\n"); + BIO_printf(bio_err, " encrypt PEM output with cbc aes\n"); +#endif +#ifndef OPENSSL_NO_CAMELLIA + BIO_printf(bio_err, " -camellia128, -camellia192, -camellia256\n"); + BIO_printf(bio_err, " encrypt PEM output with cbc camellia\n"); +#endif + BIO_printf(bio_err, " -out file output the key to 'file\n"); + BIO_printf(bio_err, " -passout arg output file pass phrase source\n"); + BIO_printf(bio_err, " -f4 use F4 (0x10001) for the E value\n"); + BIO_printf(bio_err, " -3 use 3 for the E value\n"); + goto err; + } + + if (!app_passwd(bio_err, NULL, passargout, NULL, &passout)) { + BIO_printf(bio_err, "Error getting password\n"); + goto err; + } + + if (outfile == NULL) { + BIO_set_fp(out, stdout, BIO_NOCLOSE); + } else { + if (BIO_write_filename(out, outfile) <= 0) { + perror(outfile); + goto err; + } + } + + BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus\n", + num); + rsa = RSA_new(); + if (!rsa) + goto err; + + if (!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, &cb)) + goto err; + + /* + * We need to do the following for when the base number size is < + * long, esp windows 3.1 :-(. + */ + l = 0L; + for (i = 0; i < rsa->e->top; i++) { +#ifndef _LP64 + l <<= BN_BITS4; + l <<= BN_BITS4; +#endif + l += rsa->e->d[i]; + } + BIO_printf(bio_err, "e is %ld (0x%lX)\n", l, l); + { + PW_CB_DATA cb_data; + cb_data.password = passout; + cb_data.prompt_info = outfile; + if (!PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0, + password_callback, &cb_data)) + goto err; + } + + ret = 0; +err: + if (bn) + BN_free(bn); + if (rsa) + RSA_free(rsa); + if (out) + BIO_free_all(out); + free(passout); + if (ret != 0) + ERR_print_errors(bio_err); + + return (ret); +} + +static int +genrsa_cb(int p, int n, BN_GENCB * cb) +{ + char c = '*'; + + if (p == 0) + c = '.'; + if (p == 1) + c = '+'; + if (p == 2) + c = '*'; + if (p == 3) + c = '\n'; + BIO_write(cb->arg, &c, 1); + (void) BIO_flush(cb->arg); + return 1; +} diff --git a/crypto/libressl/apps/openssl/nseq.c b/crypto/libressl/apps/openssl/nseq.c new file mode 100644 index 0000000000..be555df6e4 --- /dev/null +++ b/crypto/libressl/apps/openssl/nseq.c @@ -0,0 +1,176 @@ +/* $OpenBSD: nseq.c,v 1.5 2015/10/10 22:28:51 doug Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include "apps.h" + +#include +#include + +static struct { + char *infile; + char *outfile; + int toseq; +} nseq_config; + +static struct option nseq_options[] = { + { + .name = "in", + .argname = "file", + .desc = "Input file to read from (default stdin)", + .type = OPTION_ARG, + .opt.arg = &nseq_config.infile, + }, + { + .name = "out", + .argname = "file", + .desc = "Output file to write to (default stdout)", + .type = OPTION_ARG, + .opt.arg = &nseq_config.outfile, + }, + { + .name = "toseq", + .desc = "Convert certificates to Netscape certificate sequence", + .type = OPTION_FLAG, + .opt.flag = &nseq_config.toseq, + }, + { NULL }, +}; + +static void +nseq_usage() +{ + fprintf(stderr, "usage: nseq [-in file] [-out file] [-toseq]\n"); + options_usage(nseq_options); +} + +int +nseq_main(int argc, char **argv) +{ + BIO *in = NULL, *out = NULL; + X509 *x509 = NULL; + NETSCAPE_CERT_SEQUENCE *seq = NULL; + int i, ret = 1; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + memset(&nseq_config, 0, sizeof(nseq_config)); + + if (options_parse(argc, argv, nseq_options, NULL, NULL) != 0) { + nseq_usage(); + return (1); + } + + if (nseq_config.infile) { + if (!(in = BIO_new_file(nseq_config.infile, "r"))) { + BIO_printf(bio_err, + "Can't open input file %s\n", nseq_config.infile); + goto end; + } + } else + in = BIO_new_fp(stdin, BIO_NOCLOSE); + + if (nseq_config.outfile) { + if (!(out = BIO_new_file(nseq_config.outfile, "w"))) { + BIO_printf(bio_err, + "Can't open output file %s\n", nseq_config.outfile); + goto end; + } + } else { + out = BIO_new_fp(stdout, BIO_NOCLOSE); + } + if (nseq_config.toseq) { + seq = NETSCAPE_CERT_SEQUENCE_new(); + seq->certs = sk_X509_new_null(); + while ((x509 = PEM_read_bio_X509(in, NULL, NULL, NULL))) + sk_X509_push(seq->certs, x509); + + if (!sk_X509_num(seq->certs)) { + BIO_printf(bio_err, "Error reading certs file %s\n", nseq_config.infile); + ERR_print_errors(bio_err); + goto end; + } + PEM_write_bio_NETSCAPE_CERT_SEQUENCE(out, seq); + ret = 0; + goto end; + } + if (!(seq = PEM_read_bio_NETSCAPE_CERT_SEQUENCE(in, NULL, NULL, NULL))) { + BIO_printf(bio_err, "Error reading sequence file %s\n", nseq_config.infile); + ERR_print_errors(bio_err); + goto end; + } + for (i = 0; i < sk_X509_num(seq->certs); i++) { + x509 = sk_X509_value(seq->certs, i); + dump_cert_text(out, x509); + PEM_write_bio_X509(out, x509); + } + ret = 0; +end: + BIO_free(in); + BIO_free_all(out); + NETSCAPE_CERT_SEQUENCE_free(seq); + + return (ret); +} diff --git a/crypto/libressl/apps/openssl/ocsp.c b/crypto/libressl/apps/openssl/ocsp.c new file mode 100644 index 0000000000..9fa0d3b104 --- /dev/null +++ b/crypto/libressl/apps/openssl/ocsp.c @@ -0,0 +1,1220 @@ +/* $OpenBSD: ocsp.c,v 1.7 2015/10/17 15:00:11 doug Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef OPENSSL_NO_OCSP + +#include + +#include +#include +#include +#include +#include +#include + +/* Needs to be included before the openssl headers! */ +#include "apps.h" + +#include +#include +#include +#include +#include +#include + +/* Maximum leeway in validity period: default 5 minutes */ +#define MAX_VALIDITY_PERIOD (5 * 60) + +static int +add_ocsp_cert(OCSP_REQUEST ** req, X509 * cert, const EVP_MD * cert_id_md, X509 * issuer, + STACK_OF(OCSP_CERTID) * ids); +static int add_ocsp_serial(OCSP_REQUEST ** req, char *serial, const EVP_MD * cert_id_md, X509 * issuer, + STACK_OF(OCSP_CERTID) * ids); +static int print_ocsp_summary(BIO * out, OCSP_BASICRESP * bs, OCSP_REQUEST * req, + STACK_OF(OPENSSL_STRING) * names, + STACK_OF(OCSP_CERTID) * ids, long nsec, + long maxage); + +static int make_ocsp_response(OCSP_RESPONSE ** resp, OCSP_REQUEST * req, CA_DB * db, + X509 * ca, X509 * rcert, EVP_PKEY * rkey, + STACK_OF(X509) * rother, unsigned long flags, + int nmin, int ndays); + +static char **lookup_serial(CA_DB * db, ASN1_INTEGER * ser); +static BIO *init_responder(char *port); +static int do_responder(OCSP_REQUEST ** preq, BIO ** pcbio, BIO * acbio, char *port); +static int send_ocsp_response(BIO * cbio, OCSP_RESPONSE * resp); +static OCSP_RESPONSE *query_responder(BIO * err, BIO * cbio, char *path, + STACK_OF(CONF_VALUE) * headers, + OCSP_REQUEST * req, int req_timeout); + +int +ocsp_main(int argc, char **argv) +{ + char **args; + char *host = NULL, *port = NULL, *path = "/"; + char *reqin = NULL, *respin = NULL; + char *reqout = NULL, *respout = NULL; + char *signfile = NULL, *keyfile = NULL; + char *rsignfile = NULL, *rkeyfile = NULL; + char *outfile = NULL; + int add_nonce = 1, noverify = 0, use_ssl = -1; + STACK_OF(CONF_VALUE) * headers = NULL; + OCSP_REQUEST *req = NULL; + OCSP_RESPONSE *resp = NULL; + OCSP_BASICRESP *bs = NULL; + X509 *issuer = NULL, *cert = NULL; + X509 *signer = NULL, *rsigner = NULL; + EVP_PKEY *key = NULL, *rkey = NULL; + BIO *acbio = NULL, *cbio = NULL; + BIO *derbio = NULL; + BIO *out = NULL; + int req_timeout = -1; + int req_text = 0, resp_text = 0; + long nsec = MAX_VALIDITY_PERIOD, maxage = -1; + char *CAfile = NULL, *CApath = NULL; + X509_STORE *store = NULL; + STACK_OF(X509) * sign_other = NULL, *verify_other = NULL, *rother = NULL; + char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL; + unsigned long sign_flags = 0, verify_flags = 0, rflags = 0; + int ret = 1; + int accept_count = -1; + int badarg = 0; + int i; + int ignore_err = 0; + STACK_OF(OPENSSL_STRING) * reqnames = NULL; + STACK_OF(OCSP_CERTID) * ids = NULL; + X509 *rca_cert = NULL; + char *ridx_filename = NULL; + char *rca_filename = NULL; + CA_DB *rdb = NULL; + int nmin = 0, ndays = -1; + const EVP_MD *cert_id_md = NULL; + const char *errstr = NULL; + + if (single_execution) { + if (pledge("stdio inet dns rpath wpath cpath", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + args = argv + 1; + reqnames = sk_OPENSSL_STRING_new_null(); + ids = sk_OCSP_CERTID_new_null(); + while (!badarg && *args && *args[0] == '-') { + if (!strcmp(*args, "-out")) { + if (args[1]) { + args++; + outfile = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-timeout")) { + if (args[1]) { + args++; + req_timeout = strtonum(*args, 0, + INT_MAX, &errstr); + if (errstr) { + BIO_printf(bio_err, + "Illegal timeout value %s: %s\n", + *args, errstr); + badarg = 1; + } + } else + badarg = 1; + } else if (!strcmp(*args, "-url")) { + if (args[1]) { + args++; + if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl)) { + BIO_printf(bio_err, "Error parsing URL\n"); + badarg = 1; + } + } else + badarg = 1; + } else if (!strcmp(*args, "-host")) { + if (args[1]) { + args++; + host = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-port")) { + if (args[1]) { + args++; + port = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-header")) { + if (args[1] && args[2]) { + if (!X509V3_add_value(args[1], args[2], &headers)) + goto end; + args += 2; + } else + badarg = 1; + } else if (!strcmp(*args, "-ignore_err")) + ignore_err = 1; + else if (!strcmp(*args, "-noverify")) + noverify = 1; + else if (!strcmp(*args, "-nonce")) + add_nonce = 2; + else if (!strcmp(*args, "-no_nonce")) + add_nonce = 0; + else if (!strcmp(*args, "-resp_no_certs")) + rflags |= OCSP_NOCERTS; + else if (!strcmp(*args, "-resp_key_id")) + rflags |= OCSP_RESPID_KEY; + else if (!strcmp(*args, "-no_certs")) + sign_flags |= OCSP_NOCERTS; + else if (!strcmp(*args, "-no_signature_verify")) + verify_flags |= OCSP_NOSIGS; + else if (!strcmp(*args, "-no_cert_verify")) + verify_flags |= OCSP_NOVERIFY; + else if (!strcmp(*args, "-no_chain")) + verify_flags |= OCSP_NOCHAIN; + else if (!strcmp(*args, "-no_cert_checks")) + verify_flags |= OCSP_NOCHECKS; + else if (!strcmp(*args, "-no_explicit")) + verify_flags |= OCSP_NOEXPLICIT; + else if (!strcmp(*args, "-trust_other")) + verify_flags |= OCSP_TRUSTOTHER; + else if (!strcmp(*args, "-no_intern")) + verify_flags |= OCSP_NOINTERN; + else if (!strcmp(*args, "-text")) { + req_text = 1; + resp_text = 1; + } else if (!strcmp(*args, "-req_text")) + req_text = 1; + else if (!strcmp(*args, "-resp_text")) + resp_text = 1; + else if (!strcmp(*args, "-reqin")) { + if (args[1]) { + args++; + reqin = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-respin")) { + if (args[1]) { + args++; + respin = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-signer")) { + if (args[1]) { + args++; + signfile = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-VAfile")) { + if (args[1]) { + args++; + verify_certfile = *args; + verify_flags |= OCSP_TRUSTOTHER; + } else + badarg = 1; + } else if (!strcmp(*args, "-sign_other")) { + if (args[1]) { + args++; + sign_certfile = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-verify_other")) { + if (args[1]) { + args++; + verify_certfile = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-CAfile")) { + if (args[1]) { + args++; + CAfile = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-CApath")) { + if (args[1]) { + args++; + CApath = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-validity_period")) { + if (args[1]) { + args++; + nsec = strtonum(*args, 0, LONG_MAX, &errstr); + if (errstr) { + BIO_printf(bio_err, + "Illegal validity period %s: %s\n", + *args, errstr); + badarg = 1; + } + } else + badarg = 1; + } else if (!strcmp(*args, "-status_age")) { + if (args[1]) { + args++; + maxage = strtonum(*args, 0, LONG_MAX, &errstr); + if (errstr) { + BIO_printf(bio_err, + "Illegal validity age %s: %s\n", + *args, errstr); + badarg = 1; + } + } else + badarg = 1; + } else if (!strcmp(*args, "-signkey")) { + if (args[1]) { + args++; + keyfile = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-reqout")) { + if (args[1]) { + args++; + reqout = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-respout")) { + if (args[1]) { + args++; + respout = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-path")) { + if (args[1]) { + args++; + path = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-issuer")) { + if (args[1]) { + args++; + X509_free(issuer); + issuer = load_cert(bio_err, *args, FORMAT_PEM, + NULL, "issuer certificate"); + if (!issuer) + goto end; + } else + badarg = 1; + } else if (!strcmp(*args, "-cert")) { + if (args[1]) { + args++; + X509_free(cert); + cert = load_cert(bio_err, *args, FORMAT_PEM, + NULL, "certificate"); + if (!cert) + goto end; + if (!cert_id_md) + cert_id_md = EVP_sha1(); + if (!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids)) + goto end; + if (!sk_OPENSSL_STRING_push(reqnames, *args)) + goto end; + } else + badarg = 1; + } else if (!strcmp(*args, "-serial")) { + if (args[1]) { + args++; + if (!cert_id_md) + cert_id_md = EVP_sha1(); + if (!add_ocsp_serial(&req, *args, cert_id_md, issuer, ids)) + goto end; + if (!sk_OPENSSL_STRING_push(reqnames, *args)) + goto end; + } else + badarg = 1; + } else if (!strcmp(*args, "-index")) { + if (args[1]) { + args++; + ridx_filename = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-CA")) { + if (args[1]) { + args++; + rca_filename = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-nmin")) { + if (args[1]) { + args++; + nmin = strtonum(*args, 0, INT_MAX, &errstr); + if (errstr) { + BIO_printf(bio_err, + "Illegal update period %s: %s\n", + *args, errstr); + badarg = 1; + } + } + if (ndays == -1) + ndays = 0; + else + badarg = 1; + } else if (!strcmp(*args, "-nrequest")) { + if (args[1]) { + args++; + accept_count = strtonum(*args, 0, INT_MAX, &errstr); + if (errstr) { + BIO_printf(bio_err, + "Illegal accept count %s: %s\n", + *args, errstr); + badarg = 1; + } + } else + badarg = 1; + } else if (!strcmp(*args, "-ndays")) { + if (args[1]) { + args++; + ndays = strtonum(*args, 0, INT_MAX, &errstr); + if (errstr) { + BIO_printf(bio_err, + "Illegal update period %s: %s\n", + *args, errstr); + badarg = 1; + } + } else + badarg = 1; + } else if (!strcmp(*args, "-rsigner")) { + if (args[1]) { + args++; + rsignfile = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-rkey")) { + if (args[1]) { + args++; + rkeyfile = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-rother")) { + if (args[1]) { + args++; + rcertfile = *args; + } else + badarg = 1; + } else if ((cert_id_md = EVP_get_digestbyname((*args) + 1)) == NULL) { + badarg = 1; + } + args++; + } + + /* Have we anything to do? */ + if (!req && !reqin && !respin && !(port && ridx_filename)) + badarg = 1; + + if (badarg) { + BIO_printf(bio_err, "OCSP utility\n"); + BIO_printf(bio_err, "Usage ocsp [options]\n"); + BIO_printf(bio_err, "where options are\n"); + BIO_printf(bio_err, "-out file output filename\n"); + BIO_printf(bio_err, "-issuer file issuer certificate\n"); + BIO_printf(bio_err, "-cert file certificate to check\n"); + BIO_printf(bio_err, "-serial n serial number to check\n"); + BIO_printf(bio_err, "-signer file certificate to sign OCSP request with\n"); + BIO_printf(bio_err, "-signkey file private key to sign OCSP request with\n"); + BIO_printf(bio_err, "-sign_other file additional certificates to include in signed request\n"); + BIO_printf(bio_err, "-no_certs don't include any certificates in signed request\n"); + BIO_printf(bio_err, "-req_text print text form of request\n"); + BIO_printf(bio_err, "-resp_text print text form of response\n"); + BIO_printf(bio_err, "-text print text form of request and response\n"); + BIO_printf(bio_err, "-reqout file write DER encoded OCSP request to \"file\"\n"); + BIO_printf(bio_err, "-respout file write DER encoded OCSP reponse to \"file\"\n"); + BIO_printf(bio_err, "-reqin file read DER encoded OCSP request from \"file\"\n"); + BIO_printf(bio_err, "-respin file read DER encoded OCSP reponse from \"file\"\n"); + BIO_printf(bio_err, "-nonce add OCSP nonce to request\n"); + BIO_printf(bio_err, "-no_nonce don't add OCSP nonce to request\n"); + BIO_printf(bio_err, "-url URL OCSP responder URL\n"); + BIO_printf(bio_err, "-host host:n send OCSP request to host on port n\n"); + BIO_printf(bio_err, "-path path to use in OCSP request\n"); + BIO_printf(bio_err, "-CApath dir trusted certificates directory\n"); + BIO_printf(bio_err, "-CAfile file trusted certificates file\n"); + BIO_printf(bio_err, "-VAfile file validator certificates file\n"); + BIO_printf(bio_err, "-validity_period n maximum validity discrepancy in seconds\n"); + BIO_printf(bio_err, "-status_age n maximum status age in seconds\n"); + BIO_printf(bio_err, "-noverify don't verify response at all\n"); + BIO_printf(bio_err, "-verify_other file additional certificates to search for signer\n"); + BIO_printf(bio_err, "-trust_other don't verify additional certificates\n"); + BIO_printf(bio_err, "-no_intern don't search certificates contained in response for signer\n"); + BIO_printf(bio_err, "-no_signature_verify don't check signature on response\n"); + BIO_printf(bio_err, "-no_cert_verify don't check signing certificate\n"); + BIO_printf(bio_err, "-no_chain don't chain verify response\n"); + BIO_printf(bio_err, "-no_cert_checks don't do additional checks on signing certificate\n"); + BIO_printf(bio_err, "-port num port to run responder on\n"); + BIO_printf(bio_err, "-index file certificate status index file\n"); + BIO_printf(bio_err, "-CA file CA certificate\n"); + BIO_printf(bio_err, "-rsigner file responder certificate to sign responses with\n"); + BIO_printf(bio_err, "-rkey file responder key to sign responses with\n"); + BIO_printf(bio_err, "-rother file other certificates to include in response\n"); + BIO_printf(bio_err, "-resp_no_certs don't include any certificates in response\n"); + BIO_printf(bio_err, "-nmin n number of minutes before next update\n"); + BIO_printf(bio_err, "-ndays n number of days before next update\n"); + BIO_printf(bio_err, "-resp_key_id identify reponse by signing certificate key ID\n"); + BIO_printf(bio_err, "-nrequest n number of requests to accept (default unlimited)\n"); + BIO_printf(bio_err, "- use specified digest in the request\n"); + goto end; + } + if (outfile) + out = BIO_new_file(outfile, "w"); + else + out = BIO_new_fp(stdout, BIO_NOCLOSE); + + if (!out) { + BIO_printf(bio_err, "Error opening output file\n"); + goto end; + } + if (!req && (add_nonce != 2)) + add_nonce = 0; + + if (!req && reqin) { + derbio = BIO_new_file(reqin, "rb"); + if (!derbio) { + BIO_printf(bio_err, "Error Opening OCSP request file\n"); + goto end; + } + req = d2i_OCSP_REQUEST_bio(derbio, NULL); + BIO_free(derbio); + if (!req) { + BIO_printf(bio_err, "Error reading OCSP request\n"); + goto end; + } + } + if (!req && port) { + acbio = init_responder(port); + if (!acbio) + goto end; + } + if (rsignfile && !rdb) { + if (!rkeyfile) + rkeyfile = rsignfile; + rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM, + NULL, "responder certificate"); + if (!rsigner) { + BIO_printf(bio_err, "Error loading responder certificate\n"); + goto end; + } + rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM, + NULL, "CA certificate"); + if (rcertfile) { + rother = load_certs(bio_err, rcertfile, FORMAT_PEM, + NULL, "responder other certificates"); + if (!rother) + goto end; + } + rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, + "responder private key"); + if (!rkey) + goto end; + } + if (acbio) + BIO_printf(bio_err, "Waiting for OCSP client connections...\n"); + +redo_accept: + + if (acbio) { + if (!do_responder(&req, &cbio, acbio, port)) + goto end; + if (!req) { + resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL); + send_ocsp_response(cbio, resp); + goto done_resp; + } + } + if (!req && (signfile || reqout || host || add_nonce || ridx_filename)) { + BIO_printf(bio_err, "Need an OCSP request for this operation!\n"); + goto end; + } + if (req && add_nonce) + OCSP_request_add1_nonce(req, NULL, -1); + + if (signfile) { + if (!keyfile) + keyfile = signfile; + signer = load_cert(bio_err, signfile, FORMAT_PEM, + NULL, "signer certificate"); + if (!signer) { + BIO_printf(bio_err, "Error loading signer certificate\n"); + goto end; + } + if (sign_certfile) { + sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM, + NULL, "signer certificates"); + if (!sign_other) + goto end; + } + key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, + "signer private key"); + if (!key) + goto end; + + if (!OCSP_request_sign(req, signer, key, NULL, sign_other, sign_flags)) { + BIO_printf(bio_err, "Error signing OCSP request\n"); + goto end; + } + } + if (req_text && req) + OCSP_REQUEST_print(out, req, 0); + + if (reqout) { + derbio = BIO_new_file(reqout, "wb"); + if (!derbio) { + BIO_printf(bio_err, "Error opening file %s\n", reqout); + goto end; + } + i2d_OCSP_REQUEST_bio(derbio, req); + BIO_free(derbio); + } + if (ridx_filename && (!rkey || !rsigner || !rca_cert)) { + BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n"); + goto end; + } + if (ridx_filename && !rdb) { + rdb = load_index(ridx_filename, NULL); + if (!rdb) + goto end; + if (!index_index(rdb)) + goto end; + } + if (rdb) { + i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays); + if (cbio) + send_ocsp_response(cbio, resp); + } else if (host) { + resp = process_responder(bio_err, req, host, path, + port, use_ssl, headers, req_timeout); + if (!resp) + goto end; + } else if (respin) { + derbio = BIO_new_file(respin, "rb"); + if (!derbio) { + BIO_printf(bio_err, "Error Opening OCSP response file\n"); + goto end; + } + resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); + BIO_free(derbio); + if (!resp) { + BIO_printf(bio_err, "Error reading OCSP response\n"); + goto end; + } + } else { + ret = 0; + goto end; + } + +done_resp: + + if (respout) { + derbio = BIO_new_file(respout, "wb"); + if (!derbio) { + BIO_printf(bio_err, "Error opening file %s\n", respout); + goto end; + } + i2d_OCSP_RESPONSE_bio(derbio, resp); + BIO_free(derbio); + } + i = OCSP_response_status(resp); + + if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) { + BIO_printf(out, "Responder Error: %s (%d)\n", + OCSP_response_status_str(i), i); + if (ignore_err) + goto redo_accept; + ret = 0; + goto end; + } + if (resp_text) + OCSP_RESPONSE_print(out, resp, 0); + + /* If running as responder don't verify our own response */ + if (cbio) { + if (accept_count > 0) + accept_count--; + /* Redo if more connections needed */ + if (accept_count) { + BIO_free_all(cbio); + cbio = NULL; + OCSP_REQUEST_free(req); + req = NULL; + OCSP_RESPONSE_free(resp); + resp = NULL; + goto redo_accept; + } + goto end; + } + if (!store) + store = setup_verify(bio_err, CAfile, CApath); + if (!store) + goto end; + if (verify_certfile) { + verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM, + NULL, "validator certificate"); + if (!verify_other) + goto end; + } + bs = OCSP_response_get1_basic(resp); + + if (!bs) { + BIO_printf(bio_err, "Error parsing response\n"); + goto end; + } + if (!noverify) { + if (req && ((i = OCSP_check_nonce(req, bs)) <= 0)) { + if (i == -1) + BIO_printf(bio_err, "WARNING: no nonce in response\n"); + else { + BIO_printf(bio_err, "Nonce Verify error\n"); + goto end; + } + } + i = OCSP_basic_verify(bs, verify_other, store, verify_flags); + if (i < 0) + i = OCSP_basic_verify(bs, NULL, store, 0); + + if (i <= 0) { + BIO_printf(bio_err, "Response Verify Failure\n"); + ERR_print_errors(bio_err); + } else + BIO_printf(bio_err, "Response verify OK\n"); + + } + if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage)) + goto end; + + ret = 0; + +end: + ERR_print_errors(bio_err); + X509_free(signer); + X509_STORE_free(store); + EVP_PKEY_free(key); + EVP_PKEY_free(rkey); + X509_free(issuer); + X509_free(cert); + X509_free(rsigner); + X509_free(rca_cert); + free_index(rdb); + BIO_free_all(cbio); + BIO_free_all(acbio); + BIO_free(out); + OCSP_REQUEST_free(req); + OCSP_RESPONSE_free(resp); + OCSP_BASICRESP_free(bs); + sk_OPENSSL_STRING_free(reqnames); + sk_OCSP_CERTID_free(ids); + sk_X509_pop_free(sign_other, X509_free); + sk_X509_pop_free(verify_other, X509_free); + sk_CONF_VALUE_pop_free(headers, X509V3_conf_free); + + if (use_ssl != -1) { + free(host); + free(port); + free(path); + } + return (ret); +} + +static int +add_ocsp_cert(OCSP_REQUEST ** req, X509 * cert, const EVP_MD * cert_id_md, X509 * issuer, + STACK_OF(OCSP_CERTID) * ids) +{ + OCSP_CERTID *id; + if (!issuer) { + BIO_printf(bio_err, "No issuer certificate specified\n"); + return 0; + } + if (!*req) + *req = OCSP_REQUEST_new(); + if (!*req) + goto err; + id = OCSP_cert_to_id(cert_id_md, cert, issuer); + if (!id || !sk_OCSP_CERTID_push(ids, id)) + goto err; + if (!OCSP_request_add0_id(*req, id)) + goto err; + return 1; + +err: + BIO_printf(bio_err, "Error Creating OCSP request\n"); + return 0; +} + +static int +add_ocsp_serial(OCSP_REQUEST ** req, char *serial, const EVP_MD * cert_id_md, X509 * issuer, + STACK_OF(OCSP_CERTID) * ids) +{ + OCSP_CERTID *id; + X509_NAME *iname; + ASN1_BIT_STRING *ikey; + ASN1_INTEGER *sno; + if (!issuer) { + BIO_printf(bio_err, "No issuer certificate specified\n"); + return 0; + } + if (!*req) + *req = OCSP_REQUEST_new(); + if (!*req) + goto err; + iname = X509_get_subject_name(issuer); + ikey = X509_get0_pubkey_bitstr(issuer); + sno = s2i_ASN1_INTEGER(NULL, serial); + if (!sno) { + BIO_printf(bio_err, "Error converting serial number %s\n", serial); + return 0; + } + id = OCSP_cert_id_new(cert_id_md, iname, ikey, sno); + ASN1_INTEGER_free(sno); + if (!id || !sk_OCSP_CERTID_push(ids, id)) + goto err; + if (!OCSP_request_add0_id(*req, id)) + goto err; + return 1; + +err: + BIO_printf(bio_err, "Error Creating OCSP request\n"); + return 0; +} + +static int +print_ocsp_summary(BIO * out, OCSP_BASICRESP * bs, OCSP_REQUEST * req, + STACK_OF(OPENSSL_STRING) * names, + STACK_OF(OCSP_CERTID) * ids, long nsec, + long maxage) +{ + OCSP_CERTID *id; + char *name; + int i; + + int status, reason; + + ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; + + if (!bs || !req || !sk_OPENSSL_STRING_num(names) || !sk_OCSP_CERTID_num(ids)) + return 1; + + for (i = 0; i < sk_OCSP_CERTID_num(ids); i++) { + id = sk_OCSP_CERTID_value(ids, i); + name = sk_OPENSSL_STRING_value(names, i); + BIO_printf(out, "%s: ", name); + + if (!OCSP_resp_find_status(bs, id, &status, &reason, + &rev, &thisupd, &nextupd)) { + BIO_puts(out, "ERROR: No Status found.\n"); + continue; + } + /* + * Check validity: if invalid write to output BIO so we know + * which response this refers to. + */ + if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage)) { + BIO_puts(out, "WARNING: Status times invalid.\n"); + ERR_print_errors(out); + } + BIO_printf(out, "%s\n", OCSP_cert_status_str(status)); + + BIO_puts(out, "\tThis Update: "); + ASN1_GENERALIZEDTIME_print(out, thisupd); + BIO_puts(out, "\n"); + + if (nextupd) { + BIO_puts(out, "\tNext Update: "); + ASN1_GENERALIZEDTIME_print(out, nextupd); + BIO_puts(out, "\n"); + } + if (status != V_OCSP_CERTSTATUS_REVOKED) + continue; + + if (reason != -1) + BIO_printf(out, "\tReason: %s\n", + OCSP_crl_reason_str(reason)); + + BIO_puts(out, "\tRevocation Time: "); + ASN1_GENERALIZEDTIME_print(out, rev); + BIO_puts(out, "\n"); + } + + return 1; +} + + +static int +make_ocsp_response(OCSP_RESPONSE ** resp, OCSP_REQUEST * req, CA_DB * db, + X509 * ca, X509 * rcert, EVP_PKEY * rkey, + STACK_OF(X509) * rother, unsigned long flags, + int nmin, int ndays) +{ + ASN1_TIME *thisupd = NULL, *nextupd = NULL; + OCSP_CERTID *cid, *ca_id = NULL; + OCSP_BASICRESP *bs = NULL; + int i, id_count, ret = 1; + + id_count = OCSP_request_onereq_count(req); + + if (id_count <= 0) { + *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL); + goto end; + } + bs = OCSP_BASICRESP_new(); + thisupd = X509_gmtime_adj(NULL, 0); + if (ndays != -1) + nextupd = X509_gmtime_adj(NULL, nmin * 60 + ndays * 3600 * 24); + + /* Examine each certificate id in the request */ + for (i = 0; i < id_count; i++) { + OCSP_ONEREQ *one; + ASN1_INTEGER *serial; + char **inf; + ASN1_OBJECT *cert_id_md_oid; + const EVP_MD *cert_id_md; + one = OCSP_request_onereq_get0(req, i); + cid = OCSP_onereq_get0_id(one); + + OCSP_id_get0_info(NULL, &cert_id_md_oid, NULL, NULL, cid); + + cert_id_md = EVP_get_digestbyobj(cert_id_md_oid); + if (!cert_id_md) { + *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR, + NULL); + goto end; + } + if (ca_id) + OCSP_CERTID_free(ca_id); + ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca); + + /* Is this request about our CA? */ + if (OCSP_id_issuer_cmp(ca_id, cid)) { + OCSP_basic_add1_status(bs, cid, + V_OCSP_CERTSTATUS_UNKNOWN, + 0, NULL, + thisupd, nextupd); + continue; + } + OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid); + inf = lookup_serial(db, serial); + if (!inf) + OCSP_basic_add1_status(bs, cid, + V_OCSP_CERTSTATUS_UNKNOWN, + 0, NULL, + thisupd, nextupd); + else if (inf[DB_type][0] == DB_TYPE_VAL) + OCSP_basic_add1_status(bs, cid, + V_OCSP_CERTSTATUS_GOOD, + 0, NULL, + thisupd, nextupd); + else if (inf[DB_type][0] == DB_TYPE_REV) { + ASN1_OBJECT *inst = NULL; + ASN1_TIME *revtm = NULL; + ASN1_GENERALIZEDTIME *invtm = NULL; + OCSP_SINGLERESP *single; + int reason = -1; + unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]); + single = OCSP_basic_add1_status(bs, cid, + V_OCSP_CERTSTATUS_REVOKED, + reason, revtm, + thisupd, nextupd); + if (invtm) + OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date, invtm, 0, 0); + else if (inst) + OCSP_SINGLERESP_add1_ext_i2d(single, NID_hold_instruction_code, inst, 0, 0); + ASN1_OBJECT_free(inst); + ASN1_TIME_free(revtm); + ASN1_GENERALIZEDTIME_free(invtm); + } + } + + OCSP_copy_nonce(bs, req); + + OCSP_basic_sign(bs, rcert, rkey, NULL, rother, flags); + + *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs); + +end: + ASN1_TIME_free(thisupd); + ASN1_TIME_free(nextupd); + OCSP_CERTID_free(ca_id); + OCSP_BASICRESP_free(bs); + return ret; + +} + +static char ** +lookup_serial(CA_DB * db, ASN1_INTEGER * ser) +{ + int i; + BIGNUM *bn = NULL; + char *itmp, *row[DB_NUMBER], **rrow; + for (i = 0; i < DB_NUMBER; i++) + row[i] = NULL; + bn = ASN1_INTEGER_to_BN(ser, NULL); + OPENSSL_assert(bn); /* FIXME: should report an error at this + * point and abort */ + if (BN_is_zero(bn)) + itmp = strdup("00"); + else + itmp = BN_bn2hex(bn); + row[DB_serial] = itmp; + BN_free(bn); + rrow = TXT_DB_get_by_index(db->db, DB_serial, row); + free(itmp); + return rrow; +} + +/* Quick and dirty OCSP server: read in and parse input request */ + +static BIO * +init_responder(char *port) +{ + BIO *acbio = NULL, *bufbio = NULL; + bufbio = BIO_new(BIO_f_buffer()); + if (!bufbio) + goto err; + acbio = BIO_new_accept(port); + if (!acbio) + goto err; + BIO_set_accept_bios(acbio, bufbio); + bufbio = NULL; + + if (BIO_do_accept(acbio) <= 0) { + BIO_printf(bio_err, "Error setting up accept BIO\n"); + ERR_print_errors(bio_err); + goto err; + } + return acbio; + +err: + BIO_free_all(acbio); + BIO_free(bufbio); + return NULL; +} + +static int +do_responder(OCSP_REQUEST ** preq, BIO ** pcbio, BIO * acbio, char *port) +{ + int have_post = 0, len; + OCSP_REQUEST *req = NULL; + char inbuf[1024]; + BIO *cbio = NULL; + + if (BIO_do_accept(acbio) <= 0) { + BIO_printf(bio_err, "Error accepting connection\n"); + ERR_print_errors(bio_err); + return 0; + } + cbio = BIO_pop(acbio); + *pcbio = cbio; + + for (;;) { + len = BIO_gets(cbio, inbuf, sizeof inbuf); + if (len <= 0) + return 1; + /* Look for "POST" signalling start of query */ + if (!have_post) { + if (strncmp(inbuf, "POST", 4)) { + BIO_printf(bio_err, "Invalid request\n"); + return 1; + } + have_post = 1; + } + /* Look for end of headers */ + if ((inbuf[0] == '\r') || (inbuf[0] == '\n')) + break; + } + + /* Try to read OCSP request */ + + req = d2i_OCSP_REQUEST_bio(cbio, NULL); + + if (!req) { + BIO_printf(bio_err, "Error parsing OCSP request\n"); + ERR_print_errors(bio_err); + } + *preq = req; + + return 1; + +} + +static int +send_ocsp_response(BIO * cbio, OCSP_RESPONSE * resp) +{ + static const char http_resp[] = + "HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n" + "Content-Length: %d\r\n\r\n"; + if (!cbio) + return 0; + BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL)); + i2d_OCSP_RESPONSE_bio(cbio, resp); + (void) BIO_flush(cbio); + return 1; +} + +static OCSP_RESPONSE * +query_responder(BIO * err, BIO * cbio, char *path, + STACK_OF(CONF_VALUE) * headers, + OCSP_REQUEST * req, int req_timeout) +{ + int fd; + int rv; + int i; + OCSP_REQ_CTX *ctx = NULL; + OCSP_RESPONSE *rsp = NULL; + struct pollfd pfd[1]; + + if (req_timeout != -1) + BIO_set_nbio(cbio, 1); + + rv = BIO_do_connect(cbio); + + if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio))) { + BIO_puts(err, "Error connecting BIO\n"); + return NULL; + } + if (BIO_get_fd(cbio, &fd) < 0) { + BIO_puts(err, "Can't get connection fd\n"); + goto err; + } + if (req_timeout != -1 && rv <= 0) { + pfd[0].fd = fd; + pfd[0].events = POLLOUT; + rv = poll(pfd, 1, req_timeout * 1000); + if (rv == 0) { + BIO_puts(err, "Timeout on connect\n"); + return NULL; + } + if (rv == -1) { + BIO_puts(err, "Poll error\n"); + return NULL; + } + } + ctx = OCSP_sendreq_new(cbio, path, NULL, -1); + if (!ctx) + return NULL; + + for (i = 0; i < sk_CONF_VALUE_num(headers); i++) { + CONF_VALUE *hdr = sk_CONF_VALUE_value(headers, i); + if (!OCSP_REQ_CTX_add1_header(ctx, hdr->name, hdr->value)) + goto err; + } + + if (!OCSP_REQ_CTX_set1_req(ctx, req)) + goto err; + + for (;;) { + rv = OCSP_sendreq_nbio(&rsp, ctx); + if (rv != -1) + break; + if (req_timeout == -1) + continue; + pfd[0].fd = fd; + if (BIO_should_read(cbio)) + pfd[0].events = POLLIN; + else if (BIO_should_write(cbio)) + pfd[0].events = POLLOUT; + else { + BIO_puts(err, "Unexpected retry condition\n"); + goto err; + } + rv = poll(pfd, 1, req_timeout * 1000); + if (rv == 0) { + BIO_puts(err, "Timeout on request\n"); + break; + } + if (rv == -1 || (pfd[0].revents & (POLLERR|POLLNVAL))) { + BIO_puts(err, "Poll error\n"); + break; + } + } +err: + if (ctx) + OCSP_REQ_CTX_free(ctx); + + return rsp; +} + +OCSP_RESPONSE * +process_responder(BIO * err, OCSP_REQUEST * req, + char *host, char *path, char *port, int use_ssl, + STACK_OF(CONF_VALUE) * headers, + int req_timeout) +{ + BIO *cbio = NULL; + SSL_CTX *ctx = NULL; + OCSP_RESPONSE *resp = NULL; + cbio = BIO_new_connect(host); + if (!cbio) { + BIO_printf(err, "Error creating connect BIO\n"); + goto end; + } + if (port) + BIO_set_conn_port(cbio, port); + if (use_ssl == 1) { + BIO *sbio; + ctx = SSL_CTX_new(SSLv23_client_method()); + if (ctx == NULL) { + BIO_printf(err, "Error creating SSL context.\n"); + goto end; + } + SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); + sbio = BIO_new_ssl(ctx, 1); + cbio = BIO_push(sbio, cbio); + } + resp = query_responder(err, cbio, path, headers, req, req_timeout); + if (!resp) + BIO_printf(bio_err, "Error querying OCSP responder\n"); +end: + if (cbio) + BIO_free_all(cbio); + if (ctx) + SSL_CTX_free(ctx); + return resp; +} + +#endif diff --git a/crypto/libressl/apps/openssl/openssl.1 b/crypto/libressl/apps/openssl/openssl.1 new file mode 100644 index 0000000000..c942c02a91 --- /dev/null +++ b/crypto/libressl/apps/openssl/openssl.1 @@ -0,0 +1,9150 @@ +.\" $OpenBSD: openssl.1,v 1.39 2016/07/21 18:40:26 jmc Exp $ +.\" ==================================================================== +.\" Copyright (c) 1998-2002 The OpenSSL Project. 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 acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" +.\" +.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +.\" endorse or promote products derived from this software without +.\" prior written permission. For written permission, please contact +.\" openssl-core@openssl.org. +.\" +.\" 5. Products derived from this software may not be called "OpenSSL" +.\" nor may "OpenSSL" appear in their names without prior written +.\" permission of the OpenSSL Project. +.\" +.\" 6. Redistributions of any form whatsoever must retain the following +.\" acknowledgment: +.\" "This product includes software developed by the OpenSSL Project +.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +.\" EXPRESSED 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 OpenSSL PROJECT OR +.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +.\" OF THE POSSIBILITY OF SUCH DAMAGE. +.\" ==================================================================== +.\" +.\" This product includes cryptographic software written by Eric Young +.\" (eay@cryptsoft.com). This product includes software written by Tim +.\" Hudson (tjh@cryptsoft.com). +.\" +.\" +.\" Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) +.\" All rights reserved. +.\" +.\" This package is an SSL implementation written +.\" by Eric Young (eay@cryptsoft.com). +.\" The implementation was written so as to conform with Netscapes SSL. +.\" +.\" This library is free for commercial and non-commercial use as long as +.\" the following conditions are aheared to. The following conditions +.\" apply to all code found in this distribution, be it the RC4, RSA, +.\" lhash, DES, etc., code; not just the SSL code. The SSL documentation +.\" included with this distribution is covered by the same copyright terms +.\" except that the holder is Tim Hudson (tjh@cryptsoft.com). +.\" +.\" Copyright remains Eric Young's, and as such any Copyright notices in +.\" the code are not to be removed. +.\" If this package is used in a product, Eric Young should be given attribution +.\" as the author of the parts of the library used. +.\" This can be in the form of a textual message at program startup or +.\" in documentation (online or textual) provided with the package. +.\" +.\" 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 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 cryptographic software written by +.\" Eric Young (eay@cryptsoft.com)" +.\" The word 'cryptographic' can be left out if the rouines from the library +.\" being used are not cryptographic related :-). +.\" 4. If you include any Windows specific code (or a derivative thereof) from +.\" the apps directory (application code) you must include an +.\" acknowledgement: +.\" "This product includes software written by Tim Hudson +.\" (tjh@cryptsoft.com)" +.\" +.\" THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" The licence and distribution terms for any publically available version or +.\" derivative of this code cannot be changed. i.e. this code cannot simply be +.\" copied and put under another distribution licence +.\" [including the GNU Public Licence.] +.\" +.\" OPENSSL +.\" +.Dd $Mdocdate: July 21 2016 $ +.Dt OPENSSL 1 +.Os +.Sh NAME +.Nm openssl +.Nd OpenSSL command line tool +.Sh SYNOPSIS +.Nm +.Cm command +.Op Ar command_opts +.Op Ar command_args +.Pp +.Nm +.Cm list-standard-commands | +.Cm list-message-digest-commands | +.Cm list-cipher-commands | +.Cm list-cipher-algorithms | +.Cm list-message-digest-algorithms | +.Cm list-public-key-algorithms +.Pp +.Nm +.Cm no- Ns Ar command +.Sh DESCRIPTION +.Nm OpenSSL +is a cryptography toolkit implementing the +Transport Layer Security +.Pq TLS v1 +network protocol, +as well as related cryptography standards. +.Pp +The +.Nm +program is a command line tool for using the various +cryptography functions of +.Nm openssl Ns 's +crypto library from the shell. +.Pp +The pseudo-commands +.Cm list-standard-commands , list-message-digest-commands , +and +.Cm list-cipher-commands +output a list +.Pq one entry per line +of the names of all standard commands, message digest commands, +or cipher commands, respectively, that are available in the present +.Nm +utility. +.Pp +The pseudo-commands +.Cm list-cipher-algorithms +and +.Cm list-message-digest-algorithms +list all cipher and message digest names, +one entry per line. +Aliases are listed as: +.Pp +.D1 from => to +.Pp +The pseudo-command +.Cm list-public-key-algorithms +lists all supported public key algorithms. +.Pp +The pseudo-command +.Cm no- Ns Ar command +tests whether a command of the +specified name is available. +If +.Ar command +does not exist, +it returns 0 +and prints +.Cm no- Ns Ar command ; +otherwise it returns 1 and prints +.Ar command . +In both cases, the output goes to stdout and nothing is printed to stderr. +Additional command line arguments are always ignored. +Since for each cipher there is a command of the same name, +this provides an easy way for shell scripts to test for the +availability of ciphers in the +.Nm +program. +.Pp +.Sy Note : +.Cm no- Ns Ar command +is not able to detect pseudo-commands such as +.Cm quit , +.Cm list- Ns Ar ... Ns Cm -commands , +or +.Cm no- Ns Ar command +itself. +.Sh ASN1PARSE +.nr nS 1 +.Nm "openssl asn1parse" +.Op Fl i +.Op Fl dlimit Ar number +.Op Fl dump +.Op Fl genconf Ar file +.Op Fl genstr Ar str +.Op Fl in Ar file +.Op Fl inform Cm der | pem | txt +.Op Fl length Ar number +.Op Fl noout +.Op Fl offset Ar number +.Op Fl oid Ar file +.Op Fl out Ar file +.Op Fl strparse Ar offset +.nr nS 0 +.Pp +The +.Nm asn1parse +command is a diagnostic utility that can parse ASN.1 structures. +It can also be used to extract data from ASN.1 formatted data. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl dlimit Ar number +Dump the first +.Ar number +bytes of unknown data in hex form. +.It Fl dump +Dump unknown data in hex form. +.It Fl genconf Ar file , Fl genstr Ar str +Generate encoded data based on string +.Ar str , +file +.Ar file , +or both, using the format described in +.Xr ASN1_generate_nconf 3 . +If only +.Ar file +is present then the string is obtained from the default section +using the name +.Dq asn1 . +The encoded data is passed through the ASN1 parser and printed out as +though it came from a file; +the contents can thus be examined and written to a file using the +.Fl out +option. +.It Fl i +Indent the output according to the +.Qq depth +of the structures. +.It Fl in Ar file +The input file; the default is standard input. +.It Fl inform Cm der | pem | txt +The input format. +.It Fl length Ar number +Number of bytes to parse; the default is until end of file. +.It Fl noout +Don't output the parsed version of the input file. +.It Fl offset Ar number +Starting offset to begin parsing; the default is start of file. +.It Fl oid Ar file +A file containing additional object identifiers +.Pq OIDs . +If an OID +.Pq object identifier +is not part of +.Nm openssl Ns 's +internal table it will be represented in +numerical form +.Pq for example 1.2.3.4 . +.Pp +Each line consists of three columns: +the first column is the OID in numerical format and should be followed by +whitespace. +The second column is the +.Qq short name , +which is a single word followed by whitespace. +The final column is the rest of the line and is the +.Qq long name . +.Nm asn1parse +displays the long name. +.It Fl out Ar file +The DER-encoded output file; the default is no encoded output +(useful when combined with +.Fl strparse ) . +.It Fl strparse Ar offset +Parse the content octets of the ASN.1 object starting at +.Ar offset . +This option can be used multiple times to +.Qq drill down +into a nested structure. +.El +.Sh CA +.nr nS 1 +.Nm "openssl ca" +.Op Fl batch +.Op Fl cert Ar file +.Op Fl config Ar file +.Op Fl crl_CA_compromise Ar time +.Op Fl crl_compromise Ar time +.Op Fl crl_hold Ar instruction +.Op Fl crl_reason Ar reason +.Op Fl crldays Ar days +.Op Fl crlexts Ar section +.Op Fl crlhours Ar hours +.Op Fl days Ar arg +.Op Fl enddate Ar date +.Op Fl extensions Ar section +.Op Fl extfile Ar section +.Op Fl gencrl +.Op Fl in Ar file +.Op Fl infiles +.Op Fl key Ar keyfile +.Op Fl keyfile Ar arg +.Op Fl keyform Ar PEM +.Op Fl md Ar arg +.Op Fl msie_hack +.Op Fl name Ar section +.Op Fl noemailDN +.Op Fl notext +.Op Fl out Ar file +.Op Fl outdir Ar dir +.Op Fl passin Ar arg +.Op Fl policy Ar arg +.Op Fl preserveDN +.Op Fl revoke Ar file +.Op Fl spkac Ar file +.Op Fl ss_cert Ar file +.Op Fl startdate Ar date +.Op Fl status Ar serial +.Op Fl subj Ar arg +.Op Fl updatedb +.Op Fl verbose +.nr nS 0 +.Pp +The +.Nm ca +command is a minimal certificate authority (CA) application. +It can be used to sign certificate requests in a variety of forms +and generate certificate revocation lists (CRLs). +It also maintains a text database of issued certificates and their status. +.Pp +The options relevant to CAs are as follows: +.Bl -tag -width "XXXX" +.It Fl batch +This sets the batch mode. +In this mode no questions will be asked +and all certificates will be certified automatically. +.It Fl cert Ar file +The CA certificate file. +.It Fl config Ar file +Specifies the configuration file to use. +.It Fl days Ar arg +The number of days to certify the certificate for. +.It Fl enddate Ar date +This allows the expiry date to be explicitly set. +The format of the date is YYMMDDHHMMSSZ +.Pq the same as an ASN1 UTCTime structure . +.It Fl extensions Ar section +The section of the configuration file containing certificate extensions +to be added when a certificate is issued (defaults to +.Cm x509_extensions +unless the +.Fl extfile +option is used). +If no extension section is present, a V1 certificate is created. +If the extension section is present +.Pq even if it is empty , +then a V3 certificate is created. +.It Fl extfile Ar file +An additional configuration +.Ar file +to read certificate extensions from +(using the default section unless the +.Fl extensions +option is also used). +.It Fl in Ar file +An input +.Ar file +containing a single certificate request to be signed by the CA. +.It Fl infiles +If present, this should be the last option; all subsequent arguments +are assumed to be the names of files containing certificate requests. +.It Fl key Ar keyfile +The password used to encrypt the private key. +Since on some systems the command line arguments are visible, +this option should be used with caution. +.It Fl keyfile Ar file +The private key to sign requests with. +.It Fl keyform Ar PEM +Private key file format. +.It Fl md Ar alg +The message digest to use. +Possible values include +.Ar md5 +and +.Ar sha1 . +This option also applies to CRLs. +.It Fl msie_hack +This is a legacy option to make +.Nm ca +work with very old versions of the IE certificate enrollment control +.Qq certenr3 . +It used UniversalStrings for almost everything. +Since the old control has various security bugs, +its use is strongly discouraged. +The newer control +.Qq Xenroll +does not need this option. +.It Fl name Ar section +Specifies the configuration file +.Ar section +to use (overrides +.Cm default_ca +in the +.Cm ca +section). +.It Fl noemailDN +The DN of a certificate can contain the EMAIL field if present in the +request DN, however it is good policy just having the email set into +the +.Cm altName +extension of the certificate. +When this option is set, the EMAIL field is removed from the certificate's +subject and set only in the, eventually present, extensions. +The +.Ar email_in_dn +keyword can be used in the configuration file to enable this behaviour. +.It Fl notext +Don't output the text form of a certificate to the output file. +.It Fl out Ar file +The output file to output certificates to. +The default is standard output. +The certificate details will also be printed out to this file. +.It Fl outdir Ar directory +The +.Ar directory +to output certificates to. +The certificate will be written to a file consisting of the +serial number in hex with +.Qq .pem +appended. +.It Fl passin Ar arg +The key password source. +.It Fl policy Ar arg +This option defines the CA +.Qq policy +to use. +The policy section in the configuration file +consists of a set of variables corresponding to certificate DN fields. +The values may be one of +.Qq match +(the value must match the same field in the CA certificate), +.Qq supplied +(the value must be present), or +.Qq optional +(the value may be present). +Any fields not mentioned in the policy section +are silently deleted, unless the +.Fl preserveDN +option is set, +but this can be regarded more of a quirk than intended behaviour. +.It Fl preserveDN +Normally, the DN order of a certificate is the same as the order of the +fields in the relevant policy section. +When this option is set, the order is the same as the request. +This is largely for compatibility with the older IE enrollment control +which would only accept certificates if their DNs matched the order of the +request. +This is not needed for Xenroll. +.It Fl spkac Ar file +A file containing a single Netscape signed public key and challenge, +and additional field values to be signed by the CA. +This will usually come from the +KEYGEN tag in an HTML form to create a new private key. +It is, however, possible to create SPKACs using the +.Nm spkac +utility. +.Pp +The file should contain the variable SPKAC set to the value of +the SPKAC and also the required DN components as name value pairs. +If it's necessary to include the same component twice, +then it can be preceded by a number and a +.Sq \&. . +.It Fl ss_cert Ar file +A single self-signed certificate to be signed by the CA. +.It Fl startdate Ar date +This allows the start date to be explicitly set. +The format of the date is YYMMDDHHMMSSZ +.Pq the same as an ASN1 UTCTime structure . +.It Fl status Ar serial +Show the status of the certificate with serial number +.Ar serial . +.It Fl updatedb +Update database for expired certificates. +.It Fl verbose +This prints extra details about the operations being performed. +.El +.Pp +The options relevant to CRLs are as follows: +.Bl -tag -width "XXXX" +.It Fl crl_CA_compromise Ar time +This is the same as +.Fl crl_compromise , +except the revocation reason is set to CACompromise. +.It Fl crl_compromise Ar time +This sets the revocation reason to keyCompromise and the compromise time to +.Ar time . +.Ar time +should be in GeneralizedTime format, i.e. YYYYMMDDHHMMSSZ. +.It Fl crl_hold Ar instruction +This sets the CRL revocation reason code to certificateHold and the hold +instruction to +.Ar instruction +which must be an OID. +Although any OID can be used, only holdInstructionNone +(the use of which is discouraged by RFC 2459), holdInstructionCallIssuer or +holdInstructionReject will normally be used. +.It Fl crl_reason Ar reason +Revocation reason, where +.Ar reason +is one of: +unspecified, keyCompromise, CACompromise, affiliationChanged, superseded, +cessationOfOperation, certificateHold or removeFromCRL. +The matching of +.Ar reason +is case insensitive. +Setting any revocation reason will make the CRL v2. +In practice, removeFromCRL is not particularly useful because it is only used +in delta CRLs which are not currently implemented. +.It Fl crldays Ar num +The number of days before the next CRL is due. +This is the days from now to place in the CRL +.Cm nextUpdate +field. +.It Fl crlexts Ar section +The +.Ar section +of the configuration file containing CRL extensions to include. +If no CRL extension section is present then a V1 CRL is created; +if the CRL extension section is present +.Pq even if it is empty +then a V2 CRL is created. +The CRL extensions specified are CRL extensions and +.Em not +CRL entry extensions. +It should be noted that some software +.Pq for example Netscape +can't handle V2 CRLs. +.It Fl crlhours Ar num +The number of hours before the next CRL is due. +.It Fl gencrl +This option generates a CRL based on information in the index file. +.It Fl revoke Ar file +A +.Ar file +containing a certificate to revoke. +.It Fl subj Ar arg +Supersedes the subject name given in the request. +The +.Ar arg +must be formatted as +.Ar /type0=value0/type1=value1/type2=... ; +characters may be escaped by +.Sq \e +.Pq backslash , +no spaces are skipped. +.El +.Pp +Many of the options can be set in the +.Cm ca +section of the configuration file +(or in the default section of the configuration file), +specified using +.Cm default_ca +or +.Fl name . +The options +.Cm preserve +and +.Cm msie_hack +are read directly from the +.Cm ca +section. +.Pp +Many of the configuration file options are identical to command line +options. +Where the option is present in the configuration file and the command line, +the command line value is used. +Where an option is described as mandatory, then it must be present in +the configuration file or the command line equivalent +.Pq if any +used. +.Bl -tag -width "XXXX" +.It Cm certificate +The same as +.Fl cert . +It gives the file containing the CA certificate. +Mandatory. +.It Cm copy_extensions +Determines how extensions in certificate requests should be handled. +If set to +.Cm none +or this option is not present, then extensions are +ignored and not copied to the certificate. +If set to +.Cm copy , +then any extensions present in the request that are not already present +are copied to the certificate. +If set to +.Cm copyall , +then all extensions in the request are copied to the certificate: +if the extension is already present in the certificate it is deleted first. +.Pp +The +.Cm copy_extensions +option should be used with caution. +If care is not taken, it can be a security risk. +For example, if a certificate request contains a +.Cm basicConstraints +extension with CA:TRUE and the +.Cm copy_extensions +value is set to +.Cm copyall +and the user does not spot +this when the certificate is displayed, then this will hand the requestor +a valid CA certificate. +.Pp +This situation can be avoided by setting +.Cm copy_extensions +to +.Cm copy +and including +.Cm basicConstraints +with CA:FALSE in the configuration file. +Then if the request contains a +.Cm basicConstraints +extension, it will be ignored. +.Pp +The main use of this option is to allow a certificate request to supply +values for certain extensions such as +.Cm subjectAltName . +.It Cm crl_extensions +The same as +.Fl crlexts . +.It Cm crlnumber +A text file containing the next CRL number to use in hex. +The CRL number will be inserted in the CRLs only if this file exists. +If this file is present, it must contain a valid CRL number. +.It Cm database +The text database file to use. +Mandatory. +This file must be present, though initially it will be empty. +.It Cm default_crl_hours , default_crl_days +The same as the +.Fl crlhours +and +.Fl crldays +options. +These will only be used if neither command line option is present. +At least one of these must be present to generate a CRL. +.It Cm default_days +The same as the +.Fl days +option. +The number of days to certify a certificate for. +.It Cm default_enddate +The same as the +.Fl enddate +option. +Either this option or +.Cm default_days +.Pq or the command line equivalents +must be present. +.It Cm default_md +The same as the +.Fl md +option. +The message digest to use. +Mandatory. +.It Cm default_startdate +The same as the +.Fl startdate +option. +The start date to certify a certificate for. +If not set, the current time is used. +.It Cm email_in_dn +The same as +.Fl noemailDN . +If the EMAIL field is to be removed from the DN of the certificate, +simply set this to +.Qq no . +If not present, the default is to allow for the EMAIL field in the +certificate's DN. +.It Cm msie_hack +The same as +.Fl msie_hack . +.It Cm name_opt , cert_opt +These options allow the format used to display the certificate details +when asking the user to confirm signing. +All the options supported by the +.Nm x509 +utilities' +.Fl nameopt +and +.Fl certopt +switches can be used here, except that +.Cm no_signame +and +.Cm no_sigdump +are permanently set and cannot be disabled +(this is because the certificate signature cannot be displayed because +the certificate has not been signed at this point). +.Pp +For convenience, the value +.Cm ca_default +is accepted by both to produce a reasonable output. +.Pp +If neither option is present, the format used in earlier versions of +.Nm openssl +is used. +Use of the old format is +.Em strongly +discouraged because it only displays fields mentioned in the +.Cm policy +section, +mishandles multicharacter string types and does not display extensions. +.It Cm new_certs_dir +The same as the +.Fl outdir +command line option. +It specifies the directory where new certificates will be placed. +Mandatory. +.It Cm oid_file +This specifies a file containing additional object identifiers. +Each line of the file should consist of the numerical form of the +object identifier followed by whitespace, then the short name followed +by whitespace and finally the long name. +.It Cm oid_section +This specifies a section in the configuration file containing extra +object identifiers. +Each line should consist of the short name of the object identifier +followed by +.Sq = +and the numerical form. +The short and long names are the same when this option is used. +.It Cm policy +The same as +.Fl policy . +Mandatory. +.It Cm preserve +The same as +.Fl preserveDN . +.It Cm private_key +Same as the +.Fl keyfile +option. +The file containing the CA private key. +Mandatory. +.It Cm serial +A text file containing the next serial number to use in hex. +Mandatory. +This file must be present and contain a valid serial number. +.It Cm unique_subject +If the value +.Cm yes +is given, the valid certificate entries in the +database must have unique subjects. +If the value +.Cm no +is given, +several valid certificate entries may have the exact same subject. +The default value is +.Cm yes . +.It Cm x509_extensions +The same as +.Fl extensions . +.El +.Sh CIPHERS +.Nm openssl ciphers +.Op Fl hVv +.Op Fl tls1 +.Op Ar cipherlist +.Pp +The +.Nm ciphers +command converts +.Nm openssl +cipher lists into ordered SSL cipher preference lists. +It can be used as a test tool to determine the appropriate cipherlist. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl h , \&? +Print a brief usage message. +.It Fl tls1 +Only include TLS v1 ciphers. +.It Fl V +Verbose. +List ciphers with a complete description of protocol version, +key exchange, authentication, encryption and mac algorithms, +any key size restrictions, +and cipher suite codes (hex format). +.It Fl v +Like +.Fl V , +but without cipher suite codes. +.It Ar cipherlist +A cipher list to convert to a cipher preference list. +If it is not included, the default cipher list will be used. +.Pp +The cipher list consists of one or more cipher strings +separated by colons. +Commas or spaces are also acceptable separators, but colons are normally used. +.Pp +The actual cipher string can take several different forms: +.Pp +It can consist of a single cipher suite, such as RC4-SHA. +.Pp +It can represent a list of cipher suites containing a certain algorithm, +or cipher suites of a certain type. +For example SHA1 represents all cipher suites using the digest algorithm SHA1. +.Pp +Lists of cipher suites can be combined in a single cipher string using the +.Sq + +character +(logical AND operation). +For example, SHA1+DES represents all cipher suites +containing the SHA1 and DES algorithms. +.Pp +Each cipher string can be optionally preceded by the characters +.Sq \&! , +.Sq - , +or +.Sq + . +If +.Sq !\& +is used, then the ciphers are permanently deleted from the list. +The ciphers deleted can never reappear in the list even if they are +explicitly stated. +If +.Sq - +is used, then the ciphers are deleted from the list, but some or +all of the ciphers can be added again by later options. +If +.Sq + +is used, then the ciphers are moved to the end of the list. +This option doesn't add any new ciphers, it just moves matching existing ones. +.Pp +If none of these characters is present, the string is just interpreted +as a list of ciphers to be appended to the current preference list. +If the list includes any ciphers already present, they will be ignored; +that is, they will not be moved to the end of the list. +.Pp +Additionally, the cipher string +.Cm @STRENGTH +can be used at any point to sort the current cipher list in order of +encryption algorithm key length. +.El +.Pp +The following is a list of all permitted cipher strings and their meanings. +.Bl -tag -width "XXXX" +.It Cm DEFAULT +The default cipher list. +This is determined at compile time and is currently +.Cm ALL:!aNULL:!eNULL:!SSLv2 . +This must be the first cipher string specified. +.It Cm COMPLEMENTOFDEFAULT +The ciphers included in +.Cm ALL , +but not enabled by default. +Currently this is +.Cm ADH . +Note that this rule does not cover +.Cm eNULL , +which is not included by +.Cm ALL +(use +.Cm COMPLEMENTOFALL +if necessary). +.It Cm ALL +All cipher suites except the +.Cm eNULL +ciphers, which must be explicitly enabled. +.It Cm COMPLEMENTOFALL +The cipher suites not enabled by +.Cm ALL , +currently being +.Cm eNULL . +.It Cm HIGH +.Qq High +encryption cipher suites. +This currently means those with key lengths larger than 128 bits. +.It Cm MEDIUM +.Qq Medium +encryption cipher suites, currently those using 128-bit encryption. +.It Cm LOW +.Qq Low +encryption cipher suites, currently those using 64- or 56-bit encryption +algorithms. +.It Cm eNULL , NULL +The +.Qq NULL +ciphers; that is, those offering no encryption. +Because these offer no encryption at all and are a security risk, +they are disabled unless explicitly included. +.It Cm aNULL +The cipher suites offering no authentication. +This is currently the anonymous DH algorithms. +These cipher suites are vulnerable to a +.Qq man in the middle +attack, so their use is normally discouraged. +.It Cm kRSA , RSA +Cipher suites using RSA key exchange. +.It Cm kEDH +Cipher suites using ephemeral DH key agreement. +.It Cm aRSA +Cipher suites using RSA authentication, i.e. the certificates carry RSA keys. +.It Cm aDSS , DSS +Cipher suites using DSS authentication, i.e. the certificates carry DSS keys. +.It Cm TLSv1 +TLS v1.0 cipher suites. +.It Cm DH +Cipher suites using DH, including anonymous DH. +.It Cm ADH +Anonymous DH cipher suites. +.It Cm AES +Cipher suites using AES. +.It Cm 3DES +Cipher suites using triple DES. +.It Cm DES +Cipher suites using DES +.Pq not triple DES . +.It Cm RC4 +Cipher suites using RC4. +.It Cm CAMELLIA +Cipher suites using Camellia. +.It Cm CHACHA20 +Cipher suites using ChaCha20. +.It Cm IDEA +Cipher suites using IDEA. +.It Cm MD5 +Cipher suites using MD5. +.It Cm SHA1 , SHA +Cipher suites using SHA1. +.El +.Sh CRL +.nr nS 1 +.Nm "openssl crl" +.Op Fl CAfile Ar file +.Op Fl CApath Ar dir +.Op Fl fingerprint +.Op Fl hash +.Op Fl in Ar file +.Op Fl inform Cm der | pem +.Op Fl issuer +.Op Fl lastupdate +.Op Fl nextupdate +.Op Fl noout +.Op Fl out Ar file +.Op Fl outform Cm der | pem +.Op Fl text +.nr nS 0 +.Pp +The +.Nm crl +command processes CRL files in DER or PEM format. +The PEM CRL format uses the header and footer lines: +.Bd -unfilled -offset indent +-----BEGIN X509 CRL----- +-----END X509 CRL----- +.Ed +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl CAfile Ar file +Verify the signature on a CRL by looking up the issuing certificate in +.Ar file . +.It Fl CApath Ar directory +Verify the signature on a CRL by looking up the issuing certificate in +.Ar dir . +This directory must be a standard certificate directory, +i.e. a hash of each subject name (using +.Cm x509 Fl hash ) +should be linked to each certificate. +.It Fl fingerprint +Print the CRL fingerprint. +.It Fl hash +Output a hash of the issuer name. +This can be used to look up CRLs in a directory by issuer name. +.It Fl in Ar file +The input file to read from, or standard input if not specified. +.It Fl inform Cm der | pem +The input format. +.It Fl issuer +Output the issuer name. +.It Fl lastupdate +Output the +.Cm lastUpdate +field. +.It Fl nextupdate +Output the +.Cm nextUpdate +field. +.It Fl noout +Don't output the encoded version of the CRL. +.It Fl out Ar file +The output file to write to, or standard output if not specified. +.It Fl outform Cm der | pem +The output format. +.It Fl text +Print out the CRL in text form. +.El +.Sh CRL2PKCS7 +.nr nS 1 +.Nm "openssl crl2pkcs7" +.Op Fl certfile Ar file +.Op Fl in Ar file +.Op Fl inform Cm der | pem +.Op Fl nocrl +.Op Fl out Ar file +.Op Fl outform Cm der | pem +.nr nS 0 +.Pp +The +.Nm crl2pkcs7 +command takes an optional CRL and one or more +certificates and converts them into a PKCS#7 degenerate +.Qq certificates only +structure. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl certfile Ar file +Add the certificates in PEM +.Ar file +to the PKCS#7 structure. +This option can be used more than once +to read certificates from multiple files. +.It Fl in Ar file +Read the CRL from +.Ar file , +or standard input if not specified. +.It Fl inform Cm der | pem +Specify the CRL input format. +.It Fl nocrl +Normally, a CRL is included in the output file. +With this option, no CRL is +included in the output file and a CRL is not read from the input file. +.It Fl out Ar file +Write the PKCS#7 structure to +.Ar file , +or standard output if not specified. +.It Fl outform Cm der | pem +Specify the PKCS#7 structure output format. +.El +.\" +.\" DGST +.\" +.Sh DGST +.nr nS 1 +.Nm "openssl dgst" +.Bk -words +.Oo +.Fl gost-mac | streebog256 | streebog512 | md_gost94 | +.Fl md4 | md5 | ripemd160 | sha1 | +.Fl sha224 | sha256 | sha384 | sha512 | whirlpool +.Oc +.Op Fl binary +.Op Fl cd +.Op Fl hex +.Op Fl hmac Ar key +.Op Fl keyform Ar PEM +.Op Fl mac Ar algorithm +.Op Fl macopt Ar nm : Ns Ar v +.Op Fl out Ar file +.Op Fl passin Ar arg +.Op Fl prverify Ar file +.Op Fl sign Ar file +.Op Fl signature Ar file +.Op Fl sigopt Ar nm : Ns Ar v +.Op Fl verify Ar file +.Op Ar +.Ek +.nr nS 0 +.Pp +.Nm openssl +.Cm gost-mac | streebog256 | streebog512 | md_gost94 | +.Cm md4 | md5 | ripemd160 | sha1 | +.Cm sha224 | sha256 | sha384 | sha512 | whirlpool +.Op Fl c +.Op Fl d +.Op Ar +.Pp +The digest functions output the message digest of a supplied +.Ar file +or +.Ar files +in hexadecimal form. +They can also be used for digital signing and verification. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl binary +Output the digest or signature in binary form. +.It Fl c +Print out the digest in two-digit groups separated by colons; only relevant if +.Em hex +format output is used. +.It Fl d +Print out BIO debugging information. +.It Fl hex +Digest is to be output as a hex dump. +This is the default case for a +.Qq normal +digest as opposed to a digital signature. +.It Fl hmac Ar key +Create a hashed MAC using +.Ar key . +.It Fl keyform Ar PEM +Specifies the key format to sign the digest with. +.It Fl mac Ar algorithm +Create a keyed Message Authentication Code (MAC). +The most popular MAC algorithm is HMAC (hash-based MAC), +but there are other MAC algorithms which are not based on hash. +MAC keys and other options should be set via the +.Fl macopt +parameter. +.It Fl macopt Ar nm : Ns Ar v +Passes options to the MAC algorithm, specified by +.Fl mac . +The following options are supported by HMAC: +.Bl -tag -width Ds +.It Ar key : Ns Ar string +Specifies the MAC key as an alphanumeric string +(use if the key contain printable characters only). +String length must conform to any restrictions of the MAC algorithm. +.It Ar hexkey : Ns Ar string +Specifies the MAC key in hexadecimal form (two hex digits per byte). +Key length must conform to any restrictions of the MAC algorithm. +.El +.It Fl out Ar file +The file to output to, or standard output by default. +.It Fl passin Ar arg +The key password source. +.It Fl prverify Ar file +Verify the signature using the private key in +.Ar file . +The output is either +.Qq Verification OK +or +.Qq Verification Failure . +.It Fl sign Ar file +Digitally sign the digest using the private key in +.Ar file . +.It Fl signature Ar file +The actual signature to verify. +.It Fl sigopt Ar nm : Ns Ar v +Pass options to the signature algorithm during sign or verify operations. +The names and values of these options are algorithm-specific. +.It Fl verify Ar file +Verify the signature using the public key in +.Ar file . +The output is either +.Qq Verification OK +or +.Qq Verification Failure . +.It Ar +File or files to digest. +If no files are specified then standard input is used. +.El +.Sh DGST NOTES +The digest of choice for all new applications is SHA1. +Other digests are, however, still widely used. +.Pp +If you wish to sign or verify data using the DSA algorithm, the dss1 +digest must be used. +.Pp +A source of random numbers is required for certain signing algorithms, in +particular DSA. +.Pp +The signing and verify options should only be used if a single file is +being signed or verified. +.\" +.\" DH +.\" +.Sh DH +Diffie-Hellman Parameter Management. +The +.Nm dh +command has been replaced by +.Nm dhparam . +See +.Sx DHPARAM +below. +.\" +.\" DHPARAM +.\" +.Sh DHPARAM +.nr nS 1 +.Nm "openssl dhparam" +.Bk -words +.Op Fl 2 | 5 +.Op Fl C +.Op Fl check +.Op Fl dsaparam +.Op Fl in Ar file +.Op Fl inform Ar DER | PEM +.Op Fl noout +.Op Fl out Ar file +.Op Fl outform Ar DER | PEM +.Op Fl text +.Op Ar numbits +.Ek +.nr nS 0 +.Pp +The +.Nm dhparam +command is used to manipulate DH parameter files. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl 2 , 5 +The generator to use, either 2 or 5. +2 is the default. +If present, the input file is ignored and parameters are generated instead. +.It Fl C +This option converts the parameters into C code. +The parameters can then be loaded by calling the +.Cm get_dh Ns Ar numbits Ns Li () +function. +.It Fl check +Check the DH parameters. +.It Fl dsaparam +If this option is used, DSA rather than DH parameters are read or created; +they are converted to DH format. +Otherwise, +.Qq strong +primes +.Pq such that (p-1)/2 is also prime +will be used for DH parameter generation. +.Pp +DH parameter generation with the +.Fl dsaparam +option is much faster, +and the recommended exponent length is shorter, +which makes DH key exchange more efficient. +Beware that with such DSA-style DH parameters, +a fresh DH key should be created for each use to +avoid small-subgroup attacks that may be possible otherwise. +.It Fl in Ar file +This specifies the input +.Ar file +to read parameters from, or standard input if this option is not specified. +.It Fl inform Ar DER | PEM +This specifies the input format. +The argument +.Ar DER +uses an ASN1 DER-encoded form compatible with the PKCS#3 DHparameter +structure. +The +.Ar PEM +form is the default format: +it consists of the DER format base64-encoded with +additional header and footer lines. +.It Fl noout +This option inhibits the output of the encoded version of the parameters. +.It Ar numbits +This argument specifies that a parameter set should be generated of size +.Ar numbits . +It must be the last option. +If not present, a value of 2048 is used. +If this value is present, the input file is ignored and +parameters are generated instead. +.It Fl out Ar file +This specifies the output +.Ar file +to write parameters to. +Standard output is used if this option is not present. +The output filename should +.Em not +be the same as the input filename. +.It Fl outform Ar DER | PEM +This specifies the output format; the options have the same meaning as the +.Fl inform +option. +.It Fl text +This option prints out the DH parameters in human readable form. +.El +.Sh DHPARAM WARNINGS +The program +.Nm dhparam +combines the functionality of the programs +.Nm dh +and +.Nm gendh +in previous versions of +.Nm OpenSSL +and +.Nm SSLeay . +The +.Nm dh +and +.Nm gendh +programs are retained for now, but may have different purposes in future +versions of +.Nm OpenSSL . +.Sh DHPARAM NOTES +PEM format DH parameters use the header and footer lines: +.Bd -unfilled -offset indent +-----BEGIN DH PARAMETERS----- +-----END DH PARAMETERS----- +.Ed +.Pp +.Nm OpenSSL +currently only supports the older PKCS#3 DH, +not the newer X9.42 DH. +.Pp +This program manipulates DH parameters not keys. +.Sh DHPARAM BUGS +There should be a way to generate and manipulate DH keys. +.Sh DHPARAM HISTORY +The +.Nm dhparam +command was added in +.Nm OpenSSL +0.9.5. +The +.Fl dsaparam +option was added in +.Nm OpenSSL +0.9.6. +.\" +.\" DSA +.\" +.Sh DSA +.nr nS 1 +.Nm "openssl dsa" +.Bk -words +.Oo +.Fl aes128 | aes192 | aes256 | +.Fl des | des3 +.Oc +.Op Fl in Ar file +.Op Fl inform Ar DER | PEM +.Op Fl modulus +.Op Fl noout +.Op Fl out Ar file +.Op Fl outform Ar DER | PEM +.Op Fl passin Ar arg +.Op Fl passout Ar arg +.Op Fl pubin +.Op Fl pubout +.Op Fl text +.Ek +.nr nS 0 +.Pp +The +.Nm dsa +command processes DSA keys. +They can be converted between various forms and their components printed out. +.Pp +.Sy Note : +This command uses the traditional +.Nm SSLeay +compatible format for private key encryption: +newer applications should use the more secure PKCS#8 format using the +.Nm pkcs8 +command. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Xo +.Fl aes128 | aes192 | aes256 | +.Fl des | des3 +.Xc +These options encrypt the private key with the AES, DES, or the triple DES +ciphers, respectively, before outputting it. +A pass phrase is prompted for. +If none of these options is specified, the key is written in plain text. +This means that using the +.Nm dsa +utility to read in an encrypted key with no encryption option can be used to +remove the pass phrase from a key, +or by setting the encryption options it can be use to add or change +the pass phrase. +These options can only be used with PEM format output files. +.It Fl in Ar file +This specifies the input +.Ar file +to read a key from, or standard input if this option is not specified. +If the key is encrypted, a pass phrase will be prompted for. +.It Fl inform Ar DER | PEM +This specifies the input format. +The +.Ar DER +argument with a private key uses an ASN1 DER-encoded form of an ASN.1 +SEQUENCE consisting of the values of version +.Pq currently zero , +P, Q, G, +and the public and private key components, respectively, as ASN.1 INTEGERs. +When used with a public key it uses a +.Em SubjectPublicKeyInfo +structure: it is an error if the key is not DSA. +.Pp +The +.Ar PEM +form is the default format: +it consists of the DER format base64-encoded with additional header and footer +lines. +In the case of a private key, PKCS#8 format is also accepted. +.It Fl modulus +This option prints out the value of the public key component of the key. +.It Fl noout +This option prevents output of the encoded version of the key. +.It Fl out Ar file +This specifies the output +.Ar file +to write a key to, or standard output if not specified. +If any encryption options are set then a pass phrase will be +prompted for. +The output filename should +.Em not +be the same as the input filename. +.It Fl outform Ar DER | PEM +This specifies the output format; the options have the same meaning as the +.Fl inform +option. +.It Fl passin Ar arg +The key password source. +.It Fl passout Ar arg +The output file password source. +.It Fl pubin +By default, a private key is read from the input file. +With this option a public key is read instead. +.It Fl pubout +By default, a private key is output. +With this option a public key will be output instead. +This option is automatically set if the input is a public key. +.It Fl text +Prints out the public/private key components and parameters. +.El +.Sh DSA NOTES +The PEM private key format uses the header and footer lines: +.Bd -unfilled -offset indent +-----BEGIN DSA PRIVATE KEY----- +-----END DSA PRIVATE KEY----- +.Ed +.Pp +The PEM public key format uses the header and footer lines: +.Bd -unfilled -offset indent +-----BEGIN PUBLIC KEY----- +-----END PUBLIC KEY----- +.Ed +.Sh DSA EXAMPLES +To remove the pass phrase on a DSA private key: +.Pp +.Dl $ openssl dsa -in key.pem -out keyout.pem +.Pp +To encrypt a private key using triple DES: +.Pp +.Dl $ openssl dsa -in key.pem -des3 -out keyout.pem +.Pp +To convert a private key from PEM to DER format: +.Pp +.Dl $ openssl dsa -in key.pem -outform DER -out keyout.der +.Pp +To print out the components of a private key to standard output: +.Pp +.Dl $ openssl dsa -in key.pem -text -noout +.Pp +To just output the public part of a private key: +.Pp +.Dl $ openssl dsa -in key.pem -pubout -out pubkey.pem +.\" +.\" DSAPARAM +.\" +.Sh DSAPARAM +.nr nS 1 +.Nm "openssl dsaparam" +.Bk -words +.Op Fl C +.Op Fl genkey +.Op Fl in Ar file +.Op Fl inform Ar DER | PEM +.Op Fl noout +.Op Fl out Ar file +.Op Fl outform Ar DER | PEM +.Op Fl text +.Op Ar numbits +.Ek +.nr nS 0 +.Pp +The +.Nm dsaparam +command is used to manipulate or generate DSA parameter files. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl C +This option converts the parameters into C code. +The parameters can then be loaded by calling the +.Cm get_dsa Ns Ar XXX Ns Li () +function. +.It Fl genkey +This option will generate a DSA either using the specified or generated +parameters. +.It Fl in Ar file +This specifies the input +.Ar file +to read parameters from, or standard input if this option is not specified. +If the +.Ar numbits +parameter is included, then this option will be ignored. +.It Fl inform Ar DER | PEM +This specifies the input format. +The +.Ar DER +argument uses an ASN1 DER-encoded form compatible with RFC 2459 +.Pq PKIX +DSS-Parms that is a SEQUENCE consisting of p, q and g, respectively. +The +.Ar PEM +form is the default format: +it consists of the DER format base64-encoded with additional header +and footer lines. +.It Fl noout +This option inhibits the output of the encoded version of the parameters. +.It Ar numbits +This option specifies that a parameter set should be generated of size +.Ar numbits . +If this option is included, the input file +.Pq if any +is ignored. +.It Fl out Ar file +This specifies the output +.Ar file +to write parameters to. +Standard output is used if this option is not present. +The output filename should +.Em not +be the same as the input filename. +.It Fl outform Ar DER | PEM +This specifies the output format; the options have the same meaning as the +.Fl inform +option. +.It Fl text +This option prints out the DSA parameters in human readable form. +.El +.Sh DSAPARAM NOTES +PEM format DSA parameters use the header and footer lines: +.Bd -unfilled -offset indent +-----BEGIN DSA PARAMETERS----- +-----END DSA PARAMETERS----- +.Ed +.Pp +DSA parameter generation is a slow process and as a result the same set of +DSA parameters is often used to generate several distinct keys. +.\" +.\" EC +.\" +.Sh EC +.nr nS 1 +.Nm "openssl ec" +.Bk -words +.Op Fl conv_form Ar arg +.Op Fl des +.Op Fl des3 +.Op Fl in Ar file +.Op Fl inform Ar DER | PEM +.Op Fl noout +.Op Fl out Ar file +.Op Fl outform Ar DER | PEM +.Op Fl param_enc Ar arg +.Op Fl param_out +.Op Fl passin Ar arg +.Op Fl passout Ar arg +.Op Fl pubin +.Op Fl pubout +.Op Fl text +.Ek +.nr nS 0 +.Pp +The +.Nm ec +command processes EC keys. +They can be converted between various +forms and their components printed out. +Note: +.Nm OpenSSL +uses the private key format specified in +.Dq SEC 1: Elliptic Curve Cryptography +.Pq Lk http://www.secg.org/ . +To convert an +.Nm OpenSSL +EC private key into the PKCS#8 private key format use the +.Nm pkcs8 +command. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl conv_form Ar arg +This specifies how the points on the elliptic curve are converted +into octet strings. +Possible values are: +.Cm compressed +(the default value), +.Cm uncompressed , +and +.Cm hybrid . +For more information regarding +the point conversion forms please read the X9.62 standard. +Note: +Due to patent issues the +.Cm compressed +option is disabled by default for binary curves +and can be enabled by defining the preprocessor macro +.Ar OPENSSL_EC_BIN_PT_COMP +at compile time. +.It Fl des | des3 +These options encrypt the private key with the DES, triple DES, or +any other cipher supported by +.Nm OpenSSL +before outputting it. +A pass phrase is prompted for. +If none of these options is specified the key is written in plain text. +This means that using the +.Nm ec +utility to read in an encrypted key with no +encryption option can be used to remove the pass phrase from a key, +or by setting the encryption options +it can be use to add or change the pass phrase. +These options can only be used with PEM format output files. +.It Fl in Ar file +This specifies the input filename to read a key from, +or standard input if this option is not specified. +If the key is encrypted a pass phrase will be prompted for. +.It Fl inform Ar DER | PEM +This specifies the input format. +DER with a private key uses +an ASN.1 DER-encoded SEC1 private key. +When used with a public key it +uses the SubjectPublicKeyInfo structure as specified in RFC 3280. +PEM is the default format: +it consists of the DER format base64 +encoded with additional header and footer lines. +In the case of a private key +PKCS#8 format is also accepted. +.It Fl noout +Prevents output of the encoded version of the key. +.It Fl out Ar file +Specifies the output filename to write a key to, +or standard output if none is specified. +If any encryption options are set then a pass phrase will be prompted for. +The output filename should +.Em not +be the same as the input filename. +.It Fl outform Ar DER | PEM +This specifies the output format. +The options have the same meaning as the +.Fl inform +option. +.It Fl param_enc Ar arg +This specifies how the elliptic curve parameters are encoded. +Possible value are: +.Cm named_curve , +i.e. the EC parameters are specified by an OID; or +.Cm explicit , +where the EC parameters are explicitly given +(see RFC 3279 for the definition of the EC parameter structures). +The default value is +.Cm named_curve . +Note: the +.Cm implicitlyCA +alternative, +as specified in RFC 3279, +is currently not implemented in +.Nm OpenSSL . +.It Fl passin Ar arg +The key password source. +.It Fl passout Ar arg +The output file password source. +.It Fl pubin +By default a private key is read from the input file; +with this option a public key is read instead. +.It Fl pubout +By default a private key is output; +with this option a public key is output instead. +This option is automatically set if the input is a public key. +.It Fl text +Prints out the public/private key components and parameters. +.El +.Sh EC NOTES +The PEM private key format uses the header and footer lines: +.Bd -literal -offset indent +-----BEGIN EC PRIVATE KEY----- +-----END EC PRIVATE KEY----- +.Ed +.Pp +The PEM public key format uses the header and footer lines: +.Bd -literal -offset indent +-----BEGIN PUBLIC KEY----- +-----END PUBLIC KEY----- +.Ed +.Sh EC EXAMPLES +To encrypt a private key using triple DES: +.Bd -literal -offset indent +$ openssl ec -in key.pem -des3 -out keyout.pem +.Ed +.Pp +To convert a private key from PEM to DER format: +.Bd -literal -offset indent +$ openssl ec -in key.pem -outform DER -out keyout.der +.Ed +.Pp +To print out the components of a private key to standard output: +.Bd -literal -offset indent +$ openssl ec -in key.pem -text -noout +.Ed +.Pp +To just output the public part of a private key: +.Bd -literal -offset indent +$ openssl ec -in key.pem -pubout -out pubkey.pem +.Ed +.Pp +To change the parameter encoding to +.Cm explicit : +.Bd -literal -offset indent +$ openssl ec -in key.pem -param_enc explicit -out keyout.pem +.Ed +.Pp +To change the point conversion form to +.Cm compressed : +.Bd -literal -offset indent +$ openssl ec -in key.pem -conv_form compressed -out keyout.pem +.Ed +.Sh EC HISTORY +The +.Nm ec +command was first introduced in +.Nm OpenSSL +0.9.8. +.Sh EC AUTHORS +.An Nils Larsch . +.\" +.\" ECPARAM +.\" +.Sh ECPARAM +.nr nS 1 +.Nm "openssl ecparam" +.Bk -words +.Op Fl C +.Op Fl check +.Op Fl conv_form Ar arg +.Op Fl genkey +.Op Fl in Ar file +.Op Fl inform Ar DER | PEM +.Op Fl list_curves +.Op Fl name Ar arg +.Op Fl no_seed +.Op Fl noout +.Op Fl out Ar file +.Op Fl outform Ar DER | PEM +.Op Fl param_enc Ar arg +.Op Fl text +.Ek +.nr nS 0 +.Pp +This command is used to manipulate or generate EC parameter files. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl C +Convert the EC parameters into C code. +The parameters can then be loaded by calling the +.Fn get_ec_group_XXX +function. +.It Fl check +Validate the elliptic curve parameters. +.It Fl conv_form Ar arg +Specify how the points on the elliptic curve are converted +into octet strings. +Possible values are: +.Cm compressed +(the default value), +.Cm uncompressed , +and +.Cm hybrid . +For more information regarding +the point conversion forms please read the X9.62 standard. +Note: +Due to patent issues the +.Cm compressed +option is disabled by default for binary curves +and can be enabled by defining the preprocessor macro +.Ar OPENSSL_EC_BIN_PT_COMP +at compile time. +.It Fl genkey +Generate an EC private key using the specified parameters. +.It Fl in Ar file +Specify the input filename to read parameters from or standard input if +this option is not specified. +.It Fl inform Ar DER | PEM +Specify the input format. +DER uses an ASN.1 DER-encoded +form compatible with RFC 3279 EcpkParameters. +PEM is the default format: +it consists of the DER format base64 encoded with additional +header and footer lines. +.It Fl list_curves +Print out a list of all +currently implemented EC parameter names and exit. +.It Fl name Ar arg +Use the EC parameters with the specified 'short' name. +Use +.Fl list_curves +to get a list of all currently implemented EC parameters. +.It Fl no_seed +Inhibit that the 'seed' for the parameter generation +is included in the ECParameters structure (see RFC 3279). +.It Fl noout +Inhibit the output of the encoded version of the parameters. +.It Fl out Ar file +Specify the output filename parameters are written to. +Standard output is used if this option is not present. +The output filename should +.Em not +be the same as the input filename. +.It Fl outform Ar DER | PEM +Specify the output format; +the parameters have the same meaning as the +.Fl inform +option. +.It Fl param_enc Ar arg +This specifies how the elliptic curve parameters are encoded. +Possible value are: +.Cm named_curve , +i.e. the EC parameters are specified by an OID, or +.Cm explicit , +where the EC parameters are explicitly given +(see RFC 3279 for the definition of the EC parameter structures). +The default value is +.Cm named_curve . +Note: the +.Cm implicitlyCA +alternative, as specified in RFC 3279, +is currently not implemented in +.Nm OpenSSL . +.It Fl text +Print out the EC parameters in human readable form. +.El +.Sh ECPARAM NOTES +PEM format EC parameters use the header and footer lines: +.Bd -literal -offset indent +-----BEGIN EC PARAMETERS----- +-----END EC PARAMETERS----- +.Ed +.Pp +.Nm OpenSSL +is currently not able to generate new groups and therefore +.Nm ecparam +can only create EC parameters from known (named) curves. +.Sh ECPARAM EXAMPLES +To create EC parameters with the group 'prime192v1': +.Bd -literal -offset indent +$ openssl ecparam -out ec_param.pem -name prime192v1 +.Ed +.Pp +To create EC parameters with explicit parameters: +.Bd -literal -offset indent +$ openssl ecparam -out ec_param.pem -name prime192v1 \e + -param_enc explicit +.Ed +.Pp +To validate given EC parameters: +.Bd -literal -offset indent +$ openssl ecparam -in ec_param.pem -check +.Ed +.Pp +To create EC parameters and a private key: +.Bd -literal -offset indent +$ openssl ecparam -out ec_key.pem -name prime192v1 -genkey +.Ed +.Pp +To change the point encoding to 'compressed': +.Bd -literal -offset indent +$ openssl ecparam -in ec_in.pem -out ec_out.pem \e + -conv_form compressed +.Ed +.Pp +To print out the EC parameters to standard output: +.Bd -literal -offset indent +$ openssl ecparam -in ec_param.pem -noout -text +.Ed +.Sh ECPARAM HISTORY +The +.Nm ecparam +command was first introduced in +.Nm OpenSSL +0.9.8. +.Sh ECPARAM AUTHORS +.An Nils Larsch . +.\" +.\" ENC +.\" +.Sh ENC +.nr nS 1 +.Nm "openssl enc" +.Bk -words +.Fl ciphername +.Op Fl AadePp +.Op Fl base64 +.Op Fl bufsize Ar number +.Op Fl debug +.Op Fl in Ar file +.Op Fl iv Ar IV +.Op Fl K Ar key +.Op Fl k Ar password +.Op Fl kfile Ar file +.Op Fl md Ar digest +.Op Fl none +.Op Fl nopad +.Op Fl nosalt +.Op Fl out Ar file +.Op Fl pass Ar arg +.Op Fl S Ar salt +.Op Fl salt +.Ek +.nr nS 0 +.Pp +The symmetric cipher commands allow data to be encrypted or decrypted +using various block and stream ciphers using keys based on passwords +or explicitly provided. +Base64 encoding or decoding can also be performed either by itself +or in addition to the encryption or decryption. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl A +If the +.Fl a +option is set, then base64 process the data on one line. +.It Fl a , base64 +Base64 process the data. +This means that if encryption is taking place, the data is base64-encoded +after encryption. +If decryption is set, the input data is base64 decoded before +being decrypted. +.It Fl bufsize Ar number +Set the buffer size for I/O. +.It Fl d +Decrypt the input data. +.It Fl debug +Debug the BIOs used for I/O. +.It Fl e +Encrypt the input data: this is the default. +.It Fl in Ar file +The input +.Ar file ; +standard input by default. +.It Fl iv Ar IV +The actual +.Ar IV +.Pq initialisation vector +to use: +this must be represented as a string comprised only of hex digits. +When only the +.Ar key +is specified using the +.Fl K +option, the +.Ar IV +must explicitly be defined. +When a password is being specified using one of the other options, +the +.Ar IV +is generated from this password. +.It Fl K Ar key +The actual +.Ar key +to use: +this must be represented as a string comprised only of hex digits. +If only the key is specified, the +.Ar IV +must be additionally specified using the +.Fl iv +option. +When both a +.Ar key +and a +.Ar password +are specified, the +.Ar key +given with the +.Fl K +option will be used and the +.Ar IV +generated from the password will be taken. +It probably does not make much sense to specify both +.Ar key +and +.Ar password . +.It Fl k Ar password +The +.Ar password +to derive the key from. +This is for compatibility with previous versions of +.Nm OpenSSL . +Superseded by the +.Fl pass +option. +.It Fl kfile Ar file +Read the password to derive the key from the first line of +.Ar file . +This is for compatibility with previous versions of +.Nm OpenSSL . +Superseded by the +.Fl pass +option. +.It Fl md Ar digest +Use +.Ar digest +to create a key from a pass phrase. +.Ar digest +may be one of +.Dq md5 +or +.Dq sha1 . +.It Fl none +Use NULL cipher (no encryption or decryption of input). +.It Fl nopad +Disable standard block padding. +.It Fl nosalt +Don't use a +.Ar salt +in the key derivation routines. +This option should +.Em NEVER +be used unless compatibility with previous versions of +.Nm OpenSSL +or +.Nm SSLeay +is required. +.It Fl out Ar file +The output +.Ar file , +standard output by default. +.It Fl P +Print out the +.Ar salt , +.Ar key , +and +.Ar IV +used, then immediately exit; +don't do any encryption or decryption. +.It Fl p +Print out the +.Ar salt , +.Ar key , +and +.Ar IV +used. +.It Fl pass Ar arg +The password source. +.It Fl S Ar salt +The actual +.Ar salt +to use: +this must be represented as a string comprised only of hex digits. +.It Fl salt +Use a +.Ar salt +in the key derivation routines. +This is the default. +.El +.Sh ENC NOTES +The program can be called either as +.Nm openssl ciphername +or +.Nm openssl enc -ciphername . +.Pp +A password will be prompted for to derive the +.Ar key +and +.Ar IV +if necessary. +.Pp +The +.Fl nosalt +option should +.Em NEVER +be used unless compatibility with previous versions of +.Nm OpenSSL +or +.Nm SSLeay +is required. +.Pp +With the +.Fl nosalt +option it is possible to perform efficient dictionary +attacks on the password and to attack stream cipher encrypted data. +The reason for this is that without the salt +the same password always generates the same encryption key. +When the salt +is being used the first eight bytes of the encrypted data are reserved +for the salt: +it is generated at random when encrypting a file and read from the +encrypted file when it is decrypted. +.Pp +Some of the ciphers do not have large keys and others have security +implications if not used correctly. +A beginner is advised to just use a strong block cipher in CBC mode +such as bf or des3. +.Pp +All the block ciphers normally use PKCS#5 padding also known as standard block +padding: +this allows a rudimentary integrity or password check to be performed. +However, since the chance of random data passing the test is +better than 1 in 256, it isn't a very good test. +.Pp +If padding is disabled, the input data must be a multiple of the cipher +block length. +.Pp +All RC2 ciphers have the same key and effective key length. +.Pp +Blowfish and RC5 algorithms use a 128-bit key. +.Sh ENC SUPPORTED CIPHERS +.Bd -unfilled -offset indent +aes-[128|192|256]-cbc 128/192/256 bit AES in CBC mode +aes-[128|192|256] Alias for aes-[128|192|256]-cbc +aes-[128|192|256]-cfb 128/192/256 bit AES in 128 bit CFB mode +aes-[128|192|256]-cfb1 128/192/256 bit AES in 1 bit CFB mode +aes-[128|192|256]-cfb8 128/192/256 bit AES in 8 bit CFB mode +aes-[128|192|256]-ecb 128/192/256 bit AES in ECB mode +aes-[128|192|256]-ofb 128/192/256 bit AES in OFB mode + +base64 Base 64 + +bf Alias for bf-cbc +bf-cbc Blowfish in CBC mode +bf-cfb Blowfish in CFB mode +bf-ecb Blowfish in ECB mode +bf-ofb Blowfish in OFB mode + +cast Alias for cast-cbc +cast-cbc CAST in CBC mode +cast5-cbc CAST5 in CBC mode +cast5-cfb CAST5 in CFB mode +cast5-ecb CAST5 in ECB mode +cast5-ofb CAST5 in OFB mode + +des Alias for des-cbc +des-cbc DES in CBC mode +des-cfb DES in CBC mode +des-ecb DES in ECB mode +des-ofb DES in OFB mode + +des-ede Two key triple DES EDE in ECB mode +des-ede-cbc Two key triple DES EDE in CBC mode +des-ede-cfb Two key triple DES EDE in CFB mode +des-ede-ofb Two key triple DES EDE in OFB mode + +des3 Alias for des-ede3-cbc +des-ede3 Three key triple DES EDE in ECB mode +des-ede3-cbc Three key triple DES EDE in CBC mode +des-ede3-cfb Three key triple DES EDE CFB mode +des-ede3-ofb Three key triple DES EDE in OFB mode + +desx DESX algorithm + +rc2 Alias for rc2-cbc +rc2-cbc 128-bit RC2 in CBC mode +rc2-cfb 128-bit RC2 in CFB mode +rc2-ecb 128-bit RC2 in ECB mode +rc2-ofb 128-bit RC2 in OFB mode +rc2-64-cbc 64-bit RC2 in CBC mode +rc2-40-cbc 40-bit RC2 in CBC mode + +rc4 128-bit RC4 +rc4-40 40-bit RC4 +.Ed +.Sh ENC EXAMPLES +Just base64 encode a binary file: +.Pp +.Dl $ openssl base64 -in file.bin -out file.b64 +.Pp +Decode the same file: +.Pp +.Dl $ openssl base64 -d -in file.b64 -out file.bin +.Pp +Encrypt a file using triple DES in CBC mode using a prompted password: +.Pp +.Dl $ openssl des3 -salt -in file.txt -out file.des3 +.Pp +Decrypt a file using a supplied password: +.Pp +.Dl "$ openssl des3 -d -in file.des3 -out file.txt -k mypassword" +.Pp +Encrypt a file then base64 encode it +(so it can be sent via mail for example) +using Blowfish in CBC mode: +.Pp +.Dl $ openssl bf -a -salt -in file.txt -out file.bf +.Pp +Base64 decode a file then decrypt it: +.Pp +.Dl "$ openssl bf -d -a -in file.bf -out file.txt" +.Sh ENC BUGS +The +.Fl A +option when used with large files doesn't work properly. +.Pp +There should be an option to allow an iteration count to be included. +.Pp +The +.Nm enc +program only supports a fixed number of algorithms with certain parameters. +Therefore it is not possible to use RC2 with a 76-bit key +or RC4 with an 84-bit key with this program. +.\" +.\" ERRSTR +.\" +.Sh ERRSTR +.Nm openssl errstr +.Op Fl stats +.Ar errno ... +.Pp +The +.Nm errstr +command performs error number to error string conversion, +generating a human-readable string representing the error code +.Ar errno . +The string is obtained through the +.Xr ERR_error_string_n 3 +function and has the following format: +.Pp +.Dl error:[error code]:[library name]:[function name]:[reason string] +.Pp +.Bq error code +is an 8-digit hexadecimal number. +The remaining fields +.Bq library name , +.Bq function name , +and +.Bq reason string +are all ASCII text. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl stats +Print debugging statistics about various aspects of the hash table. +.El +.Sh ERRSTR EXAMPLES +The following error code: +.Pp +.Dl 27594:error:2006D080:lib(32):func(109):reason(128):bss_file.c:107: +.Pp +\&...can be displayed with: +.Pp +.Dl $ openssl errstr 2006D080 +.Pp +\&...to produce the error message: +.Pp +.Dl error:2006D080:BIO routines:BIO_new_file:no such file +.\" +.\" GENDH +.\" +.Sh GENDH +Generation of Diffie-Hellman Parameters. +Replaced by +.Nm dhparam . +See +.Sx DHPARAM +above. +.\" +.\" GENDSA +.\" +.Sh GENDSA +.nr nS 1 +.Nm "openssl gendsa" +.Bk -words +.Oo +.Fl aes128 | aes192 | aes256 | +.Fl des | des3 +.Oc +.Op Fl out Ar file +.Op Ar paramfile +.Ek +.nr nS 0 +.Pp +The +.Nm gendsa +command generates a DSA private key from a DSA parameter file +(which will typically be generated by the +.Nm openssl dsaparam +command). +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Xo +.Fl aes128 | aes192 | aes256 | +.Fl des | des3 +.Xc +These options encrypt the private key with the AES, DES, +or the triple DES ciphers, respectively, before outputting it. +A pass phrase is prompted for. +If none of these options are specified, no encryption is used. +.It Fl out Ar file +The output +.Ar file . +If this argument is not specified, standard output is used. +.It Ar paramfile +This option specifies the DSA parameter file to use. +The parameters in this file determine the size of the private key. +DSA parameters can be generated and examined using the +.Nm openssl dsaparam +command. +.El +.Sh GENDSA NOTES +DSA key generation is little more than random number generation so it is +much quicker than RSA key generation, for example. +.\" +.\" GENPKEY +.\" +.Sh GENPKEY +.nr nS 1 +.Nm "openssl genpkey" +.Bk -words +.Op Fl algorithm Ar alg +.Op Ar cipher +.Op Fl genparam +.Op Fl out Ar file +.Op Fl outform Ar DER | PEM +.Op Fl paramfile Ar file +.Op Fl pass Ar arg +.Op Fl pkeyopt Ar opt : Ns Ar value +.Op Fl text +.Ek +.nr nS 0 +.Pp +The +.Nm genpkey +command generates private keys. +The use of this +program is encouraged over the algorithm specific utilities +because additional algorithm options can be used. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl algorithm Ar alg +The public key algorithm to use, +such as RSA, DSA, or DH. +If used this option must precede any +.Fl pkeyopt +options. +The options +.Fl paramfile +and +.Fl algorithm +are mutually exclusive. +.It Ar cipher +Encrypt the private key with the supplied cipher. +Any algorithm name accepted by +.Fn EVP_get_cipherbyname +is acceptable, such as +.Cm des3 . +.It Fl genparam +Generate a set of parameters instead of a private key. +If used this option must precede any +.Fl algorithm , +.Fl paramfile , +or +.Fl pkeyopt +options. +.It Fl out Ar file +The output filename. +If this argument is not specified then standard output is used. +.It Fl outform Ar DER | PEM +This specifies the output format, DER or PEM. +.It Fl paramfile Ar file +Some public key algorithms generate a private key based on a set of parameters. +They can be supplied using this option. +If this option is used the public key +algorithm used is determined by the parameters. +If used this option must precede any +.Fl pkeyopt +options. +The options +.Fl paramfile +and +.Fl algorithm +are mutually exclusive. +.It Fl pass Ar arg +The output file password source. +.It Fl pkeyopt Ar opt : Ns Ar value +Set the public key algorithm option +.Ar opt +to +.Ar value . +The precise set of options supported +depends on the public key algorithm used and its implementation. +See +.Sx GENPKEY KEY GENERATION OPTIONS +below for more details. +.It Fl text +Print an (unencrypted) text representation of private and public keys and +parameters along with the DER or PEM structure. +.El +.Sh GENPKEY KEY GENERATION OPTIONS +The options supported by each algorithm +and indeed each implementation of an algorithm can vary. +The options for the +.Nm OpenSSL +implementations are detailed below. +.Bl -tag -width Ds -offset indent +.It rsa_keygen_bits : Ns Ar numbits +(RSA) +The number of bits in the generated key. +If not specified 2048 is used. +.It rsa_keygen_pubexp : Ns Ar value +(RSA) +The RSA public exponent value. +This can be a large decimal or hexadecimal value if preceded by 0x. +The default value is 65537. +.It dsa_paramgen_bits : Ns Ar numbits +(DSA) +The number of bits in the generated parameters. +If not specified 1024 is used. +.It dh_paramgen_prime_len : Ns Ar numbits +(DH) +The number of bits in the prime parameter +.Ar p . +.It dh_paramgen_generator : Ns Ar value +(DH) +The value to use for the generator +.Ar g . +.It ec_paramgen_curve : Ns Ar curve +(EC) +The EC curve to use. +.El +.Sh GENPKEY EXAMPLES +Generate an RSA private key using default parameters: +.Bd -literal -offset indent +$ openssl genpkey -algorithm RSA -out key.pem +.Ed +.Pp +Encrypt and output a private key using 128-bit AES and the passphrase "hello": +.Bd -literal -offset indent +$ openssl genpkey -algorithm RSA -out key.pem \e + -aes-128-cbc -pass pass:hello +.Ed +.Pp +Generate a 2048-bit RSA key using 3 as the public exponent: +.Bd -literal -offset indent +$ openssl genpkey -algorithm RSA -out key.pem \e + -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:3 +.Ed +.Pp +Generate 1024-bit DSA parameters: +.Bd -literal -offset indent +$ openssl genpkey -genparam -algorithm DSA \e + -out dsap.pem -pkeyopt dsa_paramgen_bits:1024 +.Ed +.Pp +Generate a DSA key from parameters: +.Bd -literal -offset indent +$ openssl genpkey -paramfile dsap.pem -out dsakey.pem +.Ed +.Pp +Generate 1024-bit DH parameters: +.Bd -literal -offset indent +$ openssl genpkey -genparam -algorithm DH \e + -out dhp.pem -pkeyopt dh_paramgen_prime_len:1024 +.Ed +.Pp +Generate a DH key from parameters: +.Bd -literal -offset indent +$ openssl genpkey -paramfile dhp.pem -out dhkey.pem +.Ed +.\" +.\" GENRSA +.\" +.Sh GENRSA +.nr nS 1 +.Nm "openssl genrsa" +.Bk -words +.Op Fl 3 | f4 +.Oo +.Fl aes128 | aes192 | aes256 | +.Fl des | des3 +.Oc +.Op Fl out Ar file +.Op Fl passout Ar arg +.Op Ar numbits +.Ek +.nr nS 0 +.Pp +The +.Nm genrsa +command generates an RSA private key. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl 3 | f4 +The public exponent to use, either 3 or 65537. +The default is 65537. +.It Xo +.Fl aes128 | aes192 | aes256 | +.Fl des | des3 +.Xc +These options encrypt the private key with the AES, DES, +or the triple DES ciphers, respectively, before outputting it. +If none of these options are specified, no encryption is used. +If encryption is used, a pass phrase is prompted for, +if it is not supplied via the +.Fl passout +option. +.It Fl out Ar file +The output +.Ar file . +If this argument is not specified, standard output is used. +.It Fl passout Ar arg +The output file password source. +.It Ar numbits +The size of the private key to generate in bits. +This must be the last option specified. +The default is 2048. +.El +.Sh GENRSA NOTES +RSA private key generation essentially involves the generation of two prime +numbers. +When generating a private key, various symbols will be output to +indicate the progress of the generation. +A +.Sq \&. +represents each number which has passed an initial sieve test; +.Sq + +means a number has passed a single round of the Miller-Rabin primality test. +A newline means that the number has passed all the prime tests +.Pq the actual number depends on the key size . +.Pp +Because key generation is a random process, +the time taken to generate a key may vary somewhat. +.Sh GENRSA BUGS +A quirk of the prime generation algorithm is that it cannot generate small +primes. +Therefore the number of bits should not be less that 64. +For typical private keys this will not matter because for security reasons +they will be much larger +.Pq typically 2048 bits . +.\" +.\" NSEQ +.\" +.Sh NSEQ +.Nm openssl nseq +.Op Fl in Ar file +.Op Fl out Ar file +.Op Fl toseq +.Pp +The +.Nm nseq +command takes a file containing a Netscape certificate +sequence and prints out the certificates contained in it or takes a +file of certificates and converts it into a Netscape certificate +sequence. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl in Ar file +This specifies the input +.Ar file +to read, or standard input if this option is not specified. +.It Fl out Ar file +Specifies the output +.Ar file , +or standard output by default. +.It Fl toseq +Normally, a Netscape certificate sequence will be input and the output +is the certificates contained in it. +With the +.Fl toseq +option the situation is reversed: +a Netscape certificate sequence is created from a file of certificates. +.El +.Sh NSEQ EXAMPLES +Output the certificates in a Netscape certificate sequence: +.Bd -literal -offset indent +$ openssl nseq -in nseq.pem -out certs.pem +.Ed +.Pp +Create a Netscape certificate sequence: +.Bd -literal -offset indent +$ openssl nseq -in certs.pem -toseq -out nseq.pem +.Ed +.Sh NSEQ NOTES +The PEM-encoded form uses the same headers and footers as a certificate: +.Bd -unfilled -offset indent +-----BEGIN CERTIFICATE----- +-----END CERTIFICATE----- +.Ed +.Pp +A Netscape certificate sequence is a Netscape specific form that can be sent +to browsers as an alternative to the standard PKCS#7 format when several +certificates are sent to the browser: +for example during certificate enrollment. +It is used by the Netscape certificate server, for example. +.Sh NSEQ BUGS +This program needs a few more options, +like allowing DER or PEM input and output files +and allowing multiple certificate files to be used. +.\" +.\" OCSP +.\" +.Sh OCSP +.nr nS 1 +.Nm "openssl ocsp" +.Bk -words +.Op Fl CA Ar file +.Op Fl CAfile Ar file +.Op Fl CApath Ar directory +.Op Fl cert Ar file +.Op Fl dgst Ar alg +.Oo +.Fl host +.Ar hostname : Ns Ar port +.Oc +.Op Fl index Ar indexfile +.Op Fl issuer Ar file +.Op Fl ndays Ar days +.Op Fl nmin Ar minutes +.Op Fl no_cert_checks +.Op Fl no_cert_verify +.Op Fl no_certs +.Op Fl no_chain +.Op Fl no_intern +.Op Fl no_nonce +.Op Fl no_signature_verify +.Op Fl nonce +.Op Fl noverify +.Op Fl nrequest Ar number +.Op Fl out Ar file +.Op Fl path Ar path +.Op Fl port Ar portnum +.Op Fl req_text +.Op Fl reqin Ar file +.Op Fl reqout Ar file +.Op Fl resp_key_id +.Op Fl resp_no_certs +.Op Fl resp_text +.Op Fl respin Ar file +.Op Fl respout Ar file +.Op Fl rkey Ar file +.Op Fl rother Ar file +.Op Fl rsigner Ar file +.Op Fl serial Ar number +.Op Fl sign_other Ar file +.Op Fl signer Ar file +.Op Fl signkey Ar file +.Op Fl status_age Ar age +.Op Fl text +.Op Fl trust_other +.Op Fl url Ar responder_url +.Op Fl VAfile Ar file +.Op Fl validity_period Ar nsec +.Op Fl verify_other Ar file +.Ek +.nr nS 0 +.Pp +The Online Certificate Status Protocol +.Pq OCSP +enables applications to determine the +.Pq revocation +state of an identified certificate +.Pq RFC 2560 . +.Pp +The +.Nm ocsp +command performs many common OCSP tasks. +It can be used to print out requests and responses, +create requests and send queries to an OCSP responder, +and behave like a mini OCSP server itself. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl CAfile Ar file , Fl CApath Ar directory +.Ar file +or +.Ar path +containing trusted CA certificates. +These are used to verify the signature on the OCSP response. +.It Fl cert Ar file +Add the certificate +.Ar file +to the request. +The issuer certificate is taken from the previous +.Fl issuer +option, or an error occurs if no issuer certificate is specified. +.It Fl dgst Ar alg +Sets the digest algorithm to use for certificate identification +in the OCSP request. +By default SHA-1 is used. +.It Xo +.Fl host Ar hostname : Ns Ar port , +.Fl path Ar path +.Xc +If the +.Fl host +option is present, then the OCSP request is sent to the host +.Ar hostname +on port +.Ar port . +.Fl path +specifies the HTTP path name to use, or +.Sq / +by default. +.It Fl issuer Ar file +This specifies the current issuer certificate. +This option can be used multiple times. +The certificate specified in +.Ar file +must be in PEM format. +This option +.Em must +come before any +.Fl cert +options. +.It Fl no_cert_checks +Don't perform any additional checks on the OCSP response signer's certificate. +That is, do not make any checks to see if the signer's certificate is +authorised to provide the necessary status information: +as a result this option should only be used for testing purposes. +.It Fl no_cert_verify +Don't verify the OCSP response signer's certificate at all. +Since this option allows the OCSP response to be signed by any certificate, +it should only be used for testing purposes. +.It Fl no_certs +Don't include any certificates in signed request. +.It Fl no_chain +Do not use certificates in the response as additional untrusted CA +certificates. +.It Fl no_intern +Ignore certificates contained in the OCSP response +when searching for the signer's certificate. +With this option, the signer's certificate must be specified with either the +.Fl verify_other +or +.Fl VAfile +options. +.It Fl no_signature_verify +Don't check the signature on the OCSP response. +Since this option tolerates invalid signatures on OCSP responses, +it will normally only be used for testing purposes. +.It Fl nonce , no_nonce +Add an OCSP +.Em nonce +extension to a request or disable an OCSP +.Em nonce +addition. +Normally, if an OCSP request is input using the +.Fl respin +option no +.Em nonce +is added: +using the +.Fl nonce +option will force addition of a +.Em nonce . +If an OCSP request is being created (using the +.Fl cert +and +.Fl serial +options) +a +.Em nonce +is automatically added; specifying +.Fl no_nonce +overrides this. +.It Fl noverify +Don't attempt to verify the OCSP response signature or the +.Em nonce +values. +This option will normally only be used for debugging +since it disables all verification of the responder's certificate. +.It Fl out Ar file +Specify output +.Ar file ; +default is standard output. +.It Fl req_text , resp_text , text +Print out the text form of the OCSP request, response, or both, respectively. +.It Fl reqin Ar file , Fl respin Ar file +Read an OCSP request or response file from +.Ar file . +These options are ignored +if an OCSP request or response creation is implied by other options +(for example with the +.Fl serial , cert , +and +.Fl host +options). +.It Fl reqout Ar file , Fl respout Ar file +Write out the DER-encoded certificate request or response to +.Ar file . +.It Fl serial Ar num +Same as the +.Fl cert +option except the certificate with serial number +.Ar num +is added to the request. +The serial number is interpreted as a decimal integer unless preceded by +.Sq 0x . +Negative integers can also be specified by preceding the value with a +.Sq - +sign. +.It Fl sign_other Ar file +Additional certificates to include in the signed request. +.It Fl signer Ar file , Fl signkey Ar file +Sign the OCSP request using the certificate specified in the +.Fl signer +option and the private key specified by the +.Fl signkey +option. +If the +.Fl signkey +option is not present, then the private key is read from the same file +as the certificate. +If neither option is specified, the OCSP request is not signed. +.It Fl trust_other +The certificates specified by the +.Fl verify_other +option should be explicitly trusted and no additional checks will be +performed on them. +This is useful when the complete responder certificate chain is not available +or trusting a root CA is not appropriate. +.It Fl url Ar responder_url +Specify the responder URL. +Both HTTP and HTTPS +.Pq SSL/TLS +URLs can be specified. +.It Fl VAfile Ar file +.Ar file +containing explicitly trusted responder certificates. +Equivalent to the +.Fl verify_other +and +.Fl trust_other +options. +.It Fl validity_period Ar nsec , Fl status_age Ar age +These options specify the range of times, in seconds, which will be tolerated +in an OCSP response. +Each certificate status response includes a +.Em notBefore +time and an optional +.Em notAfter +time. +The current time should fall between these two values, +but the interval between the two times may be only a few seconds. +In practice the OCSP responder and clients' clocks may not be precisely +synchronised and so such a check may fail. +To avoid this the +.Fl validity_period +option can be used to specify an acceptable error range in seconds, +the default value is 5 minutes. +.Pp +If the +.Em notAfter +time is omitted from a response, then this means that new status +information is immediately available. +In this case the age of the +.Em notBefore +field is checked to see it is not older than +.Ar age +seconds old. +By default, this additional check is not performed. +.It Fl verify_other Ar file +.Ar file +containing additional certificates to search when attempting to locate +the OCSP response signing certificate. +Some responders omit the actual signer's certificate from the response; +this option can be used to supply the necessary certificate in such cases. +.El +.Sh OCSP SERVER OPTIONS +.Bl -tag -width "XXXX" +.It Fl CA Ar file +CA certificate corresponding to the revocation information in +.Ar indexfile . +.It Fl index Ar indexfile +.Ar indexfile +is a text index file in +.Nm ca +format containing certificate revocation information. +.Pp +If the +.Fl index +option is specified, the +.Nm ocsp +utility is in +.Em responder +mode, otherwise it is in +.Em client +mode. +The request(s) the responder processes can be either specified on +the command line (using the +.Fl issuer +and +.Fl serial +options), supplied in a file (using the +.Fl respin +option) or via external OCSP clients (if +.Ar port +or +.Ar url +is specified). +.Pp +If the +.Fl index +option is present, then the +.Fl CA +and +.Fl rsigner +options must also be present. +.It Fl nmin Ar minutes , Fl ndays Ar days +Number of +.Ar minutes +or +.Ar days +when fresh revocation information is available: used in the +.Ar nextUpdate +field. +If neither option is present, the +.Em nextUpdate +field is omitted, meaning fresh revocation information is immediately available. +.It Fl nrequest Ar number +The OCSP server will exit after receiving +.Ar number +requests, default unlimited. +.It Fl port Ar portnum +Port to listen for OCSP requests on. +The port may also be specified using the +.Fl url +option. +.It Fl resp_key_id +Identify the signer certificate using the key ID; +default is to use the subject name. +.It Fl resp_no_certs +Don't include any certificates in the OCSP response. +.It Fl rkey Ar file +The private key to sign OCSP responses with; +if not present, the file specified in the +.Fl rsigner +option is used. +.It Fl rother Ar file +Additional certificates to include in the OCSP response. +.It Fl rsigner Ar file +The certificate to sign OCSP responses with. +.El +.Sh OCSP RESPONSE VERIFICATION +OCSP Response follows the rules specified in RFC 2560. +.Pp +Initially the OCSP responder certificate is located and the signature on +the OCSP request checked using the responder certificate's public key. +.Pp +Then a normal certificate verify is performed on the OCSP responder certificate +building up a certificate chain in the process. +The locations of the trusted certificates used to build the chain can be +specified by the +.Fl CAfile +and +.Fl CApath +options or they will be looked for in the standard +.Nm OpenSSL +certificates +directory. +.Pp +If the initial verify fails, the OCSP verify process halts with an +error. +.Pp +Otherwise the issuing CA certificate in the request is compared to the OCSP +responder certificate: if there is a match then the OCSP verify succeeds. +.Pp +Otherwise the OCSP responder certificate's CA is checked against the issuing +CA certificate in the request. +If there is a match and the OCSPSigning extended key usage is present +in the OCSP responder certificate, then the OCSP verify succeeds. +.Pp +Otherwise the root CA of the OCSP responder's CA is checked to see if it +is trusted for OCSP signing. +If it is, the OCSP verify succeeds. +.Pp +If none of these checks is successful, the OCSP verify fails. +.Pp +What this effectively means is that if the OCSP responder certificate is +authorised directly by the CA it is issuing revocation information about +.Pq and it is correctly configured , +then verification will succeed. +.Pp +If the OCSP responder is a +.Em global responder +which can give details about multiple CAs and has its own separate +certificate chain, then its root CA can be trusted for OCSP signing. +For example: +.Bd -literal -offset indent +$ openssl x509 -in ocspCA.pem -addtrust OCSPSigning \e + -out trustedCA.pem +.Ed +.Pp +Alternatively, the responder certificate itself can be explicitly trusted +with the +.Fl VAfile +option. +.Sh OCSP NOTES +As noted, most of the verify options are for testing or debugging purposes. +Normally, only the +.Fl CApath , CAfile +and +.Pq if the responder is a `global VA' +.Fl VAfile +options need to be used. +.Pp +The OCSP server is only useful for test and demonstration purposes: +it is not really usable as a full OCSP responder. +It contains only a very simple HTTP request handling and can only handle +the POST form of OCSP queries. +It also handles requests serially, meaning it cannot respond to +new requests until it has processed the current one. +The text index file format of revocation is also inefficient for large +quantities of revocation data. +.Pp +It is possible to run the +.Nm ocsp +application in +.Em responder +mode via a CGI script using the +.Fl respin +and +.Fl respout +options. +.Sh OCSP EXAMPLES +Create an OCSP request and write it to a file: +.Bd -literal -offset indent +$ openssl ocsp -issuer issuer.pem -cert c1.pem -cert c2.pem \e + -reqout req.der +.Ed +.Pp +Send a query to an OCSP responder with URL +.Pa http://ocsp.myhost.com/ , +save the response to a file and print it out in text form: +.Bd -literal -offset indent +$ openssl ocsp -issuer issuer.pem -cert c1.pem -cert c2.pem \e + -url http://ocsp.myhost.com/ -resp_text -respout resp.der +.Ed +.Pp +Read in an OCSP response and print out in text form: +.Pp +.Dl $ openssl ocsp -respin resp.der -text +.Pp +OCSP server on port 8888 using a standard +.Nm ca +configuration, and a separate responder certificate. +All requests and responses are printed to a file: +.Bd -literal -offset indent +$ openssl ocsp -index demoCA/index.txt -port 8888 -rsigner \e + rcert.pem -CA demoCA/cacert.pem -text -out log.txt +.Ed +.Pp +As above, but exit after processing one request: +.Bd -literal -offset indent +$ openssl ocsp -index demoCA/index.txt -port 8888 -rsigner \e + rcert.pem -CA demoCA/cacert.pem -nrequest 1 +.Ed +.Pp +Query status information using internally generated request: +.Bd -literal -offset indent +$ openssl ocsp -index demoCA/index.txt -rsigner rcert.pem -CA \e + demoCA/cacert.pem -issuer demoCA/cacert.pem -serial 1 +.Ed +.Pp +Query status information using request read from a file and write +the response to a second file: +.Bd -literal -offset indent +$ openssl ocsp -index demoCA/index.txt -rsigner rcert.pem -CA \e + demoCA/cacert.pem -reqin req.der -respout resp.der +.Ed +.\" +.\" PASSWD +.\" +.Sh PASSWD +.nr nS 1 +.Nm "openssl passwd" +.Op Fl 1 | apr1 | crypt +.Op Fl in Ar file +.Op Fl noverify +.Op Fl quiet +.Op Fl reverse +.Op Fl salt Ar string +.Op Fl stdin +.Op Fl table +.Op Ar password +.nr nS 0 +.Pp +The +.Nm passwd +command computes the hash of a password typed at run-time +or the hash of each password in a list. +The password list is taken from the named +.Ar file +for option +.Fl in , +from stdin for option +.Fl stdin , +or from the command line, or from the terminal otherwise. +The +.Ux +standard algorithm +.Em crypt +and the MD5-based +.Bx +password algorithm +.Em 1 +and its Apache variant +.Em apr1 +are available. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl 1 +Use the MD5 based +.Bx +password algorithm +.Em 1 . +.It Fl apr1 +Use the +.Em apr1 +algorithm +.Pq Apache variant of the +.Bx +algorithm. +.It Fl crypt +Use the +.Em crypt +algorithm +.Pq default . +.It Fl in Ar file +Read passwords from +.Ar file . +.It Fl noverify +Don't verify when reading a password from the terminal. +.It Fl quiet +Don't output warnings when passwords given on the command line are truncated. +.It Fl reverse +Switch table columns. +This only makes sense in conjunction with the +.Fl table +option. +.It Fl salt Ar string +Use the specified +.Ar salt . +When reading a password from the terminal, this implies +.Fl noverify . +.It Fl stdin +Read passwords from +.Em stdin . +.It Fl table +In the output list, prepend the cleartext password and a TAB character +to each password hash. +.El +.Sh PASSWD EXAMPLES +.Dl $ openssl passwd -crypt -salt xx password +prints +.Qq xxj31ZMTZzkVA . +.Pp +.Dl $ openssl passwd -1 -salt xxxxxxxx password +prints +.Qq $1$xxxxxxxx$UYCIxa628.9qXjpQCjM4a. . +.Pp +.Dl $ openssl passwd -apr1 -salt xxxxxxxx password +prints +.Qq $apr1$xxxxxxxx$dxHfLAsjHkDRmG83UXe8K0 . +.\" +.\" PKCS7 +.\" +.Sh PKCS7 +.nr nS 1 +.Nm "openssl pkcs7" +.Bk -words +.Op Fl in Ar file +.Op Fl inform Ar DER | PEM +.Op Fl noout +.Op Fl out Ar file +.Op Fl outform Ar DER | PEM +.Op Fl print_certs +.Op Fl text +.Ek +.nr nS 0 +.Pp +The +.Nm pkcs7 +command processes PKCS#7 files in DER or PEM format. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl in Ar file +This specifies the input +.Ar file +to read from, or standard input if this option is not specified. +.It Fl inform Ar DER | PEM +This specifies the input format. +.Ar DER +format is a DER-encoded PKCS#7 v1.5 structure. +.Ar PEM +.Pq the default +is a base64-encoded version of the DER form with header and footer lines. +.It Fl noout +Don't output the encoded version of the PKCS#7 structure +(or certificates if +.Fl print_certs +is set). +.It Fl out Ar file +Specifies the output +.Ar file +to write to, or standard output by default. +.It Fl outform Ar DER | PEM +This specifies the output format; the options have the same meaning as the +.Fl inform +option. +.It Fl print_certs +Prints out any certificates or CRLs contained in the file. +They are preceded by their subject and issuer names in a one-line format. +.It Fl text +Prints out certificate details in full rather than just subject and +issuer names. +.El +.Sh PKCS7 EXAMPLES +Convert a PKCS#7 file from PEM to DER: +.Pp +.Dl $ openssl pkcs7 -in file.pem -outform DER -out file.der +.Pp +Output all certificates in a file: +.Pp +.Dl $ openssl pkcs7 -in file.pem -print_certs -out certs.pem +.Sh PKCS7 NOTES +The PEM PKCS#7 format uses the header and footer lines: +.Bd -unfilled -offset indent +-----BEGIN PKCS7----- +-----END PKCS7----- +.Ed +.Pp +For compatibility with some CAs it will also accept: +.Bd -unfilled -offset indent +-----BEGIN CERTIFICATE----- +-----END CERTIFICATE----- +.Ed +.Sh PKCS7 RESTRICTIONS +There is no option to print out all the fields of a PKCS#7 file. +.Pp +The PKCS#7 routines only understand PKCS#7 v 1.5 as specified in RFC 2315. +They cannot currently parse, for example, the new CMS as described in RFC 2630. +.\" +.\" PKCS8 +.\" +.Sh PKCS8 +.nr nS 1 +.Nm "openssl pkcs8" +.Bk -words +.Op Fl embed +.Op Fl in Ar file +.Op Fl inform Ar DER | PEM +.Op Fl nocrypt +.Op Fl noiter +.Op Fl nooct +.Op Fl nsdb +.Op Fl out Ar file +.Op Fl outform Ar DER | PEM +.Op Fl passin Ar arg +.Op Fl passout Ar arg +.Op Fl topk8 +.Op Fl v1 Ar alg +.Op Fl v2 Ar alg +.Ek +.nr nS 0 +.Pp +The +.Nm pkcs8 +command processes private keys in PKCS#8 format. +It can handle both unencrypted PKCS#8 PrivateKeyInfo format +and EncryptedPrivateKeyInfo format with a variety of PKCS#5 +.Pq v1.5 and v2.0 +and PKCS#12 algorithms. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl embed +This option generates DSA keys in a broken format. +The DSA parameters are embedded inside the +.Em PrivateKey +structure. +In this form the OCTET STRING contains an ASN1 SEQUENCE consisting of +two structures: +a SEQUENCE containing the parameters and an ASN1 INTEGER containing +the private key. +.It Fl in Ar file +This specifies the input +.Ar file +to read a key from, or standard input if this option is not specified. +If the key is encrypted, a pass phrase will be prompted for. +.It Fl inform Ar DER | PEM +This specifies the input format. +If a PKCS#8 format key is expected on input, +then either a +DER- or PEM-encoded version of a PKCS#8 key will be expected. +Otherwise the DER or PEM format of the traditional format private key is used. +.It Fl nocrypt +PKCS#8 keys generated or input are normally PKCS#8 +.Em EncryptedPrivateKeyInfo +structures using an appropriate password-based encryption algorithm. +With this option, an unencrypted +.Em PrivateKeyInfo +structure is expected or output. +This option does not encrypt private keys at all and should only be used +when absolutely necessary. +Certain software such as some versions of Java code signing software use +unencrypted private keys. +.It Fl noiter +Use an iteration count of 1. +See the +.Sx PKCS12 +section below for a detailed explanation of this option. +.It Fl nooct +This option generates RSA private keys in a broken format that some software +uses. +Specifically the private key should be enclosed in an OCTET STRING, +but some software just includes the structure itself without the +surrounding OCTET STRING. +.It Fl nsdb +This option generates DSA keys in a broken format compatible with Netscape +private key databases. +The +.Em PrivateKey +contains a SEQUENCE consisting of the public and private keys, respectively. +.It Fl out Ar file +This specifies the output +.Ar file +to write a key to, or standard output by default. +If any encryption options are set, a pass phrase will be prompted for. +The output filename should +.Em not +be the same as the input filename. +.It Fl outform Ar DER | PEM +This specifies the output format; the options have the same meaning as the +.Fl inform +option. +.It Fl passin Ar arg +The key password source. +.It Fl passout Ar arg +The output file password source. +.It Fl topk8 +Normally, a PKCS#8 private key is expected on input and a traditional format +private key will be written. +With the +.Fl topk8 +option the situation is reversed: +it reads a traditional format private key and writes a PKCS#8 format key. +.It Fl v1 Ar alg +This option specifies a PKCS#5 v1.5 or PKCS#12 algorithm to use. +A complete list of possible algorithms is included below. +.It Fl v2 Ar alg +This option enables the use of PKCS#5 v2.0 algorithms. +Normally, PKCS#8 private keys are encrypted with the password-based +encryption algorithm called +.Em pbeWithMD5AndDES-CBC ; +this uses 56-bit DES encryption but it was the strongest encryption +algorithm supported in PKCS#5 v1.5. +Using the +.Fl v2 +option PKCS#5 v2.0 algorithms are used which can use any +encryption algorithm such as 168-bit triple DES or 128-bit RC2, however +not many implementations support PKCS#5 v2.0 yet. +If using private keys with +.Nm OpenSSL +then this doesn't matter. +.Pp +The +.Ar alg +argument is the encryption algorithm to use; valid values include +.Ar des , des3 , +and +.Ar rc2 . +It is recommended that +.Ar des3 +is used. +.El +.Sh PKCS8 NOTES +The encrypted form of a PEM-encoded PKCS#8 file uses the following +headers and footers: +.Bd -unfilled -offset indent +-----BEGIN ENCRYPTED PRIVATE KEY----- +-----END ENCRYPTED PRIVATE KEY----- +.Ed +.Pp +The unencrypted form uses: +.Bd -unfilled -offset indent +-----BEGIN PRIVATE KEY----- +-----END PRIVATE KEY----- +.Ed +.Pp +Private keys encrypted using PKCS#5 v2.0 algorithms and high iteration +counts are more secure than those encrypted using the traditional +.Nm SSLeay +compatible formats. +So if additional security is considered important, the keys should be converted. +.Pp +The default encryption is only 56 bits because this is the encryption +that most current implementations of PKCS#8 support. +.Pp +Some software may use PKCS#12 password-based encryption algorithms +with PKCS#8 format private keys: these are handled automatically +but there is no option to produce them. +.Pp +It is possible to write out +DER-encoded encrypted private keys in PKCS#8 format because the encryption +details are included at an ASN1 +level whereas the traditional format includes them at a PEM level. +.Sh PKCS#5 V1.5 AND PKCS#12 ALGORITHMS +Various algorithms can be used with the +.Fl v1 +command line option, including PKCS#5 v1.5 and PKCS#12. +These are described in more detail below. +.Pp +.Bl -tag -width "XXXX" -compact +.It Ar PBE-MD5-DES +These algorithms were included in the original PKCS#5 v1.5 specification. +They only offer 56 bits of protection since they both use DES. +.Pp +.It Ar PBE-SHA1-RC2-64 | PBE-MD5-RC2-64 | PBE-SHA1-DES +These algorithms are not mentioned in the original PKCS#5 v1.5 specification +but they use the same key derivation algorithm and are supported by some +software. +They are mentioned in PKCS#5 v2.0. +They use either 64-bit RC2 or 56-bit DES. +.Pp +.It Ar PBE-SHA1-RC4-128 | PBE-SHA1-RC4-40 | PBE-SHA1-3DES | PBE-SHA1-2DES +.It Ar PBE-SHA1-RC2-128 | PBE-SHA1-RC2-40 +These algorithms use the PKCS#12 password-based encryption algorithm and +allow strong encryption algorithms like triple DES or 128-bit RC2 to be used. +.El +.Sh PKCS8 EXAMPLES +Convert a private key from traditional to PKCS#5 v2.0 format using triple DES: +.Pp +.Dl "$ openssl pkcs8 -in key.pem -topk8 -v2 des3 -out enckey.pem" +.Pp +Convert a private key to PKCS#8 using a PKCS#5 1.5 compatible algorithm +.Pq DES : +.Pp +.Dl $ openssl pkcs8 -in key.pem -topk8 -out enckey.pem +.Pp +Convert a private key to PKCS#8 using a PKCS#12 compatible algorithm +.Pq 3DES : +.Bd -literal -offset indent +$ openssl pkcs8 -in key.pem -topk8 -out enckey.pem \e + -v1 PBE-SHA1-3DES +.Ed +.Pp +Read a DER-unencrypted PKCS#8 format private key: +.Pp +.Dl "$ openssl pkcs8 -inform DER -nocrypt -in key.der -out key.pem" +.Pp +Convert a private key from any PKCS#8 format to traditional format: +.Pp +.Dl $ openssl pkcs8 -in pk8.pem -out key.pem +.Sh PKCS8 STANDARDS +Test vectors from this PKCS#5 v2.0 implementation were posted to the +pkcs-tng mailing list using triple DES, DES and RC2 with high iteration counts; +several people confirmed that they could decrypt the private +keys produced and therefore it can be assumed that the PKCS#5 v2.0 +implementation is reasonably accurate at least as far as these +algorithms are concerned. +.Pp +The format of PKCS#8 DSA +.Pq and other +private keys is not well documented: +it is hidden away in PKCS#11 v2.01, section 11.9; +.Nm OpenSSL Ns Li 's +default DSA PKCS#8 private key format complies with this standard. +.Sh PKCS8 BUGS +There should be an option that prints out the encryption algorithm +in use and other details such as the iteration count. +.Pp +PKCS#8 using triple DES and PKCS#5 v2.0 should be the default private +key format; for +.Nm OpenSSL +compatibility, several of the utilities use the old format at present. +.\" +.\" PKCS12 +.\" +.Sh PKCS12 +.nr nS 1 +.Nm "openssl pkcs12" +.Bk -words +.Oo +.Fl aes128 | aes192 | aes256 | +.Fl des | des3 +.Oc +.Op Fl cacerts +.Op Fl CAfile Ar file +.Op Fl caname Ar name +.Op Fl CApath Ar directory +.Op Fl certfile Ar file +.Op Fl certpbe Ar alg +.Op Fl chain +.Op Fl clcerts +.Op Fl CSP Ar name +.Op Fl descert +.Op Fl export +.Op Fl in Ar file +.Op Fl info +.Op Fl inkey Ar file +.Op Fl keyex +.Op Fl keypbe Ar alg +.Op Fl keysig +.Op Fl macalg Ar alg +.Op Fl maciter +.Op Fl name Ar name +.Op Fl nocerts +.Op Fl nodes +.Op Fl noiter +.Op Fl nokeys +.Op Fl nomac +.Op Fl nomaciter +.Op Fl nomacver +.Op Fl noout +.Op Fl out Ar file +.Op Fl passin Ar arg +.Op Fl passout Ar arg +.Op Fl twopass +.Ek +.nr nS 0 +.Pp +The +.Nm pkcs12 +command allows PKCS#12 files +.Pq sometimes referred to as PFX files +to be created and parsed. +PKCS#12 files are used by several programs including Netscape, MSIE +and MS Outlook. +.Pp +There are a lot of options; the meaning of some depends on whether a +PKCS#12 file is being created or parsed. +By default, a PKCS#12 file is parsed; +a PKCS#12 file can be created by using the +.Fl export +option +.Pq see below . +.Sh PKCS12 PARSING OPTIONS +.Bl -tag -width "XXXX" +.It Xo +.Fl aes128 | aes192 | aes256 | +.Fl des | des3 +.Xc +Use AES, DES, or triple DES, respectively, +to encrypt private keys before outputting. +The default is triple DES. +.It Fl cacerts +Only output CA certificates +.Pq not client certificates . +.It Fl clcerts +Only output client certificates +.Pq not CA certificates . +.It Fl in Ar file +This specifies the +.Ar file +of the PKCS#12 file to be parsed. +Standard input is used by default. +.It Fl info +Output additional information about the PKCS#12 file structure, +algorithms used, and iteration counts. +.It Fl nocerts +No certificates at all will be output. +.It Fl nodes +Don't encrypt the private keys at all. +.It Fl nokeys +No private keys will be output. +.It Fl nomacver +Don't attempt to verify the integrity MAC before reading the file. +.It Fl noout +This option inhibits output of the keys and certificates to the output file +version of the PKCS#12 file. +.It Fl out Ar file +The +.Ar file +to write certificates and private keys to, standard output by default. +They are all written in PEM format. +.It Fl passin Ar arg +The key password source. +.It Fl passout Ar arg +The output file password source. +.It Fl twopass +Prompt for separate integrity and encryption passwords: most software +always assumes these are the same so this option will render such +PKCS#12 files unreadable. +.El +.Sh PKCS12 FILE CREATION OPTIONS +.Bl -tag -width "XXXX" +.It Fl CAfile Ar file +CA storage as a file. +.It Fl CApath Ar directory +CA storage as a directory. +This directory must be a standard certificate directory: +that is, a hash of each subject name (using +.Cm x509 -hash ) +should be linked to each certificate. +.It Fl caname Ar name +This specifies the +.Qq friendly name +for other certificates. +This option may be used multiple times to specify names for all certificates +in the order they appear. +Netscape ignores friendly names on other certificates, +whereas MSIE displays them. +.It Fl certfile Ar file +A file to read additional certificates from. +.It Fl certpbe Ar alg , Fl keypbe Ar alg +These options allow the algorithm used to encrypt the private key and +certificates to be selected. +Any PKCS#5 v1.5 or PKCS#12 PBE algorithm name can be used (see the +.Sx PKCS12 NOTES +section for more information). +If a cipher name +(as output by the +.Cm list-cipher-algorithms +command) is specified then it +is used with PKCS#5 v2.0. +For interoperability reasons it is advisable to only use PKCS#12 algorithms. +.It Fl chain +If this option is present, an attempt is made to include the entire +certificate chain of the user certificate. +The standard CA store is used for this search. +If the search fails, it is considered a fatal error. +.It Fl CSP Ar name +Write +.Ar name +as a Microsoft CSP name. +.It Fl descert +Encrypt the certificate using triple DES; this may render the PKCS#12 +file unreadable by some +.Qq export grade +software. +By default, the private key is encrypted using triple DES and the +certificate using 40-bit RC2. +.It Fl export +This option specifies that a PKCS#12 file will be created rather than +parsed. +.It Fl in Ar file +The +.Ar file +to read certificates and private keys from, standard input by default. +They must all be in PEM format. +The order doesn't matter but one private key and its corresponding +certificate should be present. +If additional certificates are present, they will also be included +in the PKCS#12 file. +.It Fl inkey Ar file +File to read private key from. +If not present, a private key must be present in the input file. +.It Fl keyex | keysig +Specifies that the private key is to be used for key exchange or just signing. +This option is only interpreted by MSIE and similar MS software. +Normally, +.Qq export grade +software will only allow 512-bit RSA keys to be +used for encryption purposes, but arbitrary length keys for signing. +The +.Fl keysig +option marks the key for signing only. +Signing only keys can be used for S/MIME signing, authenticode +.Pq ActiveX control signing +and SSL client authentication; +however, due to a bug only MSIE 5.0 and later support +the use of signing only keys for SSL client authentication. +.It Fl macalg Ar alg +Specify the MAC digest algorithm. +If not included then SHA1 is used. +.It Fl maciter +This option is included for compatibility with previous versions; it used +to be needed to use MAC iterations counts but they are now used by default. +.It Fl name Ar name +This specifies the +.Qq friendly name +for the certificate and private key. +This name is typically displayed in list boxes by software importing the file. +.It Fl nomac +Don't attempt to provide the MAC integrity. +.It Fl nomaciter , noiter +These options affect the iteration counts on the MAC and key algorithms. +Unless you wish to produce files compatible with MSIE 4.0, you should leave +these options alone. +.Pp +To discourage attacks by using large dictionaries of common passwords, +the algorithm that derives keys from passwords can have an iteration count +applied to it: this causes a certain part of the algorithm to be repeated +and slows it down. +The MAC is used to check the file integrity but since it will normally +have the same password as the keys and certificates it could also be attacked. +By default, both MAC and encryption iteration counts are set to 2048; +using these options the MAC and encryption iteration counts can be set to 1. +Since this reduces the file security you should not use these options +unless you really have to. +Most software supports both MAC and key iteration counts. +MSIE 4.0 doesn't support MAC iteration counts, so it needs the +.Fl nomaciter +option. +.It Fl out Ar file +This specifies +.Ar file +to write the PKCS#12 file to. +Standard output is used by default. +.It Fl passin Ar arg +The key password source. +.It Fl passout Ar arg +The output file password source. +.El +.Sh PKCS12 NOTES +Although there are a large number of options, +most of them are very rarely used. +For PKCS#12 file parsing, only +.Fl in +and +.Fl out +need to be used for PKCS#12 file creation. +.Fl export +and +.Fl name +are also used. +.Pp +If none of the +.Fl clcerts , cacerts , +or +.Fl nocerts +options are present, then all certificates will be output in the order +they appear in the input PKCS#12 files. +There is no guarantee that the first certificate present is +the one corresponding to the private key. +Certain software which requires a private key and certificate and assumes +the first certificate in the file is the one corresponding to the private key: +this may not always be the case. +Using the +.Fl clcerts +option will solve this problem by only outputting the certificate +corresponding to the private key. +If the CA certificates are required, they can be output to a separate +file using the +.Fl nokeys +and +.Fl cacerts +options to just output CA certificates. +.Pp +The +.Fl keypbe +and +.Fl certpbe +algorithms allow the precise encryption algorithms for private keys +and certificates to be specified. +Normally, the defaults are fine but occasionally software can't handle +triple DES encrypted private keys; +then the option +.Fl keypbe Ar PBE-SHA1-RC2-40 +can be used to reduce the private key encryption to 40-bit RC2. +A complete description of all algorithms is contained in the +.Sx PKCS8 +section above. +.Sh PKCS12 EXAMPLES +Parse a PKCS#12 file and output it to a file: +.Pp +.Dl $ openssl pkcs12 -in file.p12 -out file.pem +.Pp +Output only client certificates to a file: +.Pp +.Dl $ openssl pkcs12 -in file.p12 -clcerts -out file.pem +.Pp +Don't encrypt the private key: +.Pp +.Dl $ openssl pkcs12 -in file.p12 -out file.pem -nodes +.Pp +Print some info about a PKCS#12 file: +.Pp +.Dl $ openssl pkcs12 -in file.p12 -info -noout +.Pp +Create a PKCS#12 file: +.Bd -literal -offset indent +$ openssl pkcs12 -export -in file.pem -out file.p12 \e + -name "My Certificate" +.Ed +.Pp +Include some extra certificates: +.Bd -literal -offset indent +$ openssl pkcs12 -export -in file.pem -out file.p12 \e + -name "My Certificate" -certfile othercerts.pem +.Ed +.Sh PKCS12 BUGS +Some would argue that the PKCS#12 standard is one big bug :\-) +.Pp +Versions of +.Nm OpenSSL +before 0.9.6a had a bug in the PKCS#12 key generation routines. +Under rare circumstances this could produce a PKCS#12 file encrypted +with an invalid key. +As a result some PKCS#12 files which triggered this bug +from other implementations +.Pq MSIE or Netscape +could not be decrypted by +.Nm OpenSSL +and similarly +.Nm OpenSSL +could produce PKCS#12 files which could not be decrypted by other +implementations. +The chances of producing such a file are relatively small: less than 1 in 256. +.Pp +A side effect of fixing this bug is that any old invalidly encrypted PKCS#12 +files can no longer be parsed by the fixed version. +Under such circumstances the +.Nm pkcs12 +utility will report that the MAC is OK but fail with a decryption +error when extracting private keys. +.Pp +This problem can be resolved by extracting the private keys and certificates +from the PKCS#12 file using an older version of +.Nm OpenSSL +and recreating +the PKCS#12 file from the keys and certificates using a newer version of +.Nm OpenSSL . +For example: +.Bd -literal -offset indent +$ old-openssl -in bad.p12 -out keycerts.pem +$ openssl -in keycerts.pem -export -name "My PKCS#12 file" \e + -out fixed.p12 +.Ed +.\" +.\" PKEY +.\" +.Sh PKEY +.nr nS 1 +.Nm "openssl pkey" +.Bk -words +.Op Ar cipher +.Op Fl in Ar file +.Op Fl inform Ar DER | PEM +.Op Fl noout +.Op Fl out Ar file +.Op Fl outform Ar DER | PEM +.Op Fl passin Ar arg +.Op Fl passout Ar arg +.Op Fl pubin +.Op Fl pubout +.Op Fl text +.Op Fl text_pub +.Ek +.nr nS 0 +.Pp +The +.Nm pkey +command processes public or private keys. +They can be converted between various forms +and their components printed out. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Ar cipher +These options encrypt the private key with the supplied cipher. +Any algorithm name accepted by +.Fn EVP_get_cipherbyname +is acceptable, such as +.Cm des3 . +.It Fl in Ar file +This specifies the input filename to read a key from, +or standard input if this option is not specified. +If the key is encrypted a pass phrase will be prompted for. +.It Fl inform Ar DER | PEM +This specifies the input format, DER or PEM. +.It Fl noout +Do not output the encoded version of the key. +.It Fl out Ar file +This specifies the output filename to write a key to, +or standard output if this option is not specified. +If any encryption options are set then a pass phrase +will be prompted for. +The output filename should +.Em not +be the same as the input filename. +.It Fl outform Ar DER | PEM +This specifies the output format; +the options have the same meaning as the +.Fl inform +option. +.It Fl passin Ar arg +The key password source. +.It Fl passout Ar arg +The output file password source. +.It Fl pubin +By default a private key is read from the input file: +with this option a public key is read instead. +.It Fl pubout +By default a private key is output: +with this option a public key will be output instead. +This option is automatically set if +the input is a public key. +.It Fl text +Print out the various public or private key components in +plain text in addition to the encoded version. +.It Fl text_pub +Print out only public key components +even if a private key is being processed. +.El +.Sh PKEY EXAMPLES +To remove the pass phrase on an RSA private key: +.Bd -literal -offset indent +$ openssl pkey -in key.pem -out keyout.pem +.Ed +.Pp +To encrypt a private key using triple DES: +.Bd -literal -offset indent +$ openssl pkey -in key.pem -des3 -out keyout.pem +.Ed +.Pp +To convert a private key from PEM to DER format: +.Bd -literal -offset indent +$ openssl pkey -in key.pem -outform DER -out keyout.der +.Ed +.Pp +To print the components of a private key to standard output: +.Bd -literal -offset indent +$ openssl pkey -in key.pem -text -noout +.Ed +.Pp +To print the public components of a private key to standard output: +.Bd -literal -offset indent +$ openssl pkey -in key.pem -text_pub -noout +.Ed +.Pp +To just output the public part of a private key: +.Bd -literal -offset indent +$ openssl pkey -in key.pem -pubout -out pubkey.pem +.Ed +.\" +.\" PKEYPARAM +.\" +.Sh PKEYPARAM +.Cm openssl pkeyparam +.Op Fl in Ar file +.Op Fl noout +.Op Fl out Ar file +.Op Fl text +.Pp +The +.Nm pkey +command processes public or private keys. +They can be converted between various forms and their components printed out. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl in Ar file +This specifies the input filename to read parameters from, +or standard input if this option is not specified. +.It Fl noout +Do not output the encoded version of the parameters. +.It Fl out Ar file +This specifies the output filename to write parameters to, +or standard output if this option is not specified. +.It Fl text +Prints out the parameters in plain text in addition to the encoded version. +.El +.Sh PKEYPARAM EXAMPLES +Print out text version of parameters: +.Bd -literal -offset indent +$ openssl pkeyparam -in param.pem -text +.Ed +.Sh PKEYPARAM NOTES +There are no +.Fl inform +or +.Fl outform +options for this command because only PEM format is supported +because the key type is determined by the PEM headers. +.\" +.\" PKEYUTL +.\" +.Sh PKEYUTL +.nr nS 1 +.Nm "openssl pkeyutl" +.Bk -words +.Op Fl asn1parse +.Op Fl certin +.Op Fl decrypt +.Op Fl derive +.Op Fl encrypt +.Op Fl hexdump +.Op Fl in Ar file +.Op Fl inkey Ar file +.Op Fl keyform Ar DER | PEM +.Op Fl out Ar file +.Op Fl passin Ar arg +.Op Fl peerform Ar DER | PEM +.Op Fl peerkey Ar file +.Op Fl pkeyopt Ar opt : Ns Ar value +.Op Fl pubin +.Op Fl rev +.Op Fl sigfile Ar file +.Op Fl sign +.Op Fl verify +.Op Fl verifyrecover +.Ek +.nr nS 0 +.Pp +The +.Nm pkeyutl +command can be used to perform public key operations using +any supported algorithm. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl asn1parse +ASN1parse the output data. +This is useful when combined with the +.Fl verifyrecover +option when an ASN1 structure is signed. +.It Fl certin +The input is a certificate containing a public key. +.It Fl decrypt +Decrypt the input data using a private key. +.It Fl derive +Derive a shared secret using the peer key. +.It Fl encrypt +Encrypt the input data using a public key. +.It Fl hexdump +Hex dump the output data. +.It Fl in Ar file +Specify the input filename to read data from, +or standard input if this option is not specified. +.It Fl inkey Ar file +The input key file. +By default it should be a private key. +.It Fl keyform Ar DER | PEM +The key format DER or PEM. +.It Fl out Ar file +Specify the output filename to write to, +or standard output by default. +.It Fl passin Ar arg +The key password source. +.It Fl peerform Ar DER | PEM +The peer key format DER or PEM. +.It Fl peerkey Ar file +The peer key file, used by key derivation (agreement) operations. +.It Fl pkeyopt Ar opt : Ns Ar value +Public key options. +.It Fl pubin +The input file is a public key. +.It Fl rev +Reverse the order of the input buffer. +This is useful for some libraries (such as CryptoAPI) +which represent the buffer in little endian format. +.It Fl sigfile Ar file +Signature file (verify operation only). +.It Fl sign +Sign the input data and output the signed result. +This requires a private key. +.It Fl verify +Verify the input data against the signature file and indicate if the +verification succeeded or failed. +.It Fl verifyrecover +Verify the input data and output the recovered data. +.El +.Sh PKEYUTL NOTES +The operations and options supported vary according to the key algorithm +and its implementation. +The +.Nm OpenSSL +operations and options are indicated below. +.Pp +Unless otherwise mentioned all algorithms support the +.Ar digest : Ns Ar alg +option which specifies the digest in use +for sign, verify, and verifyrecover operations. +The value +.Ar alg +should represent a digest name as used in the +.Fn EVP_get_digestbyname +function, for example +.Cm sha1 . +.Ss RSA algorithm +The RSA algorithm supports the +encrypt, decrypt, sign, verify, and verifyrecover operations in general. +Some padding modes only support some of these +operations however. +.Bl -tag -width Ds +.It rsa_padding_mode : Ns Ar mode +This sets the RSA padding mode. +Acceptable values for +.Ar mode +are +.Cm pkcs1 +for PKCS#1 padding; +.Cm none +for no padding; +.Cm oaep +for OAEP mode; +.Cm x931 +for X9.31 mode; +and +.Cm pss +for PSS. +.Pp +In PKCS#1 padding if the message digest is not set then the supplied data is +signed or verified directly instead of using a DigestInfo structure. +If a digest is set then a DigestInfo +structure is used and its length +must correspond to the digest type. +.Pp +For oeap mode only encryption and decryption is supported. +.Pp +For x931 if the digest type is set it is used to format the block data; +otherwise the first byte is used to specify the X9.31 digest ID. +Sign, verify, and verifyrecover can be performed in this mode. +.Pp +For pss mode only sign and verify are supported and the digest type must be +specified. +.It rsa_pss_saltlen : Ns Ar len +For pss +mode only this option specifies the salt length. +Two special values are supported: +-1 sets the salt length to the digest length. +When signing -2 sets the salt length to the maximum permissible value. +When verifying -2 causes the salt length to be automatically determined +based on the PSS block structure. +.El +.Ss DSA algorithm +The DSA algorithm supports the sign and verify operations. +Currently there are no additional options other than +.Ar digest . +Only the SHA1 digest can be used and this digest is assumed by default. +.Ss DH algorithm +The DH algorithm supports the derive operation +and no additional options. +.Ss EC algorithm +The EC algorithm supports the sign, verify, and derive operations. +The sign and verify operations use ECDSA and derive uses ECDH. +Currently there are no additional options other than +.Ar digest . +Only the SHA1 digest can be used and this digest is assumed by default. +.Sh PKEYUTL EXAMPLES +Sign some data using a private key: +.Bd -literal -offset indent +$ openssl pkeyutl -sign -in file -inkey key.pem -out sig +.Ed +.Pp +Recover the signed data (e.g. if an RSA key is used): +.Bd -literal -offset indent +$ openssl pkeyutl -verifyrecover -in sig -inkey key.pem +.Ed +.Pp +Verify the signature (e.g. a DSA key): +.Bd -literal -offset indent +$ openssl pkeyutl -verify -in file -sigfile sig \e + -inkey key.pem +.Ed +.Pp +Sign data using a message digest value (this is currently only valid for RSA): +.Bd -literal -offset indent +$ openssl pkeyutl -sign -in file -inkey key.pem \e + -out sig -pkeyopt digest:sha256 +.Ed +.Pp +Derive a shared secret value: +.Bd -literal -offset indent +$ openssl pkeyutl -derive -inkey key.pem \e + -peerkey pubkey.pem -out secret +.Ed +.\" +.\" PRIME +.\" +.Sh PRIME +.Cm openssl prime +.Op Fl bits Ar n +.Op Fl checks Ar n +.Op Fl generate +.Op Fl hex +.Op Fl safe +.Ar p +.Pp +The +.Nm prime +command is used to generate prime numbers, +or to check numbers for primality. +Results are probabilistic: +they have an exceedingly high likelihood of being correct, +but are not guaranteed. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl bits Ar n +Specify the number of bits in the generated prime number. +Must be used in conjunction with +.Fl generate . +.It Fl checks Ar n +Perform a Miller-Rabin probabilistic primality test with +.Ar n +iterations. +The default is 20. +.It Fl generate +Generate a pseudo-random prime number. +Must be used in conjunction with +.Fl bits . +.It Fl hex +Output in hex format. +.It Fl safe +Generate only +.Qq safe +prime numbers +(i.e. a prime p so that (p-1)/2 is also prime). +.It Ar p +Test if number +.Ar p +is prime. +.El +.\" +.\" RAND +.\" +.Sh RAND +.nr nS 1 +.Nm "openssl rand" +.Op Fl base64 +.Op Fl hex +.Op Fl out Ar file +.Ar num +.nr nS 0 +.Pp +The +.Nm rand +command outputs +.Ar num +pseudo-random bytes. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl base64 +Perform +.Em base64 +encoding on the output. +.It Fl hex +Specify hexadecimal output. +.It Fl out Ar file +Write to +.Ar file +instead of standard output. +.El +.\" +.\" REQ +.\" +.Sh REQ +.nr nS 1 +.Nm "openssl req" +.Bk -words +.Op Fl asn1-kludge +.Op Fl batch +.Op Fl config Ar file +.Op Fl days Ar n +.Op Fl extensions Ar section +.Op Fl in Ar file +.Op Fl inform Ar DER | PEM +.Op Fl key Ar keyfile +.Op Fl keyform Ar DER | PEM +.Op Fl keyout Ar file +.Op Fl md4 | md5 | sha1 +.Op Fl modulus +.Op Fl nameopt Ar option +.Op Fl new +.Op Fl newhdr +.Op Fl newkey Ar arg +.Op Fl no-asn1-kludge +.Op Fl nodes +.Op Fl noout +.Op Fl out Ar file +.Op Fl outform Ar DER | PEM +.Op Fl passin Ar arg +.Op Fl passout Ar arg +.Op Fl pubkey +.Op Fl reqexts Ar section +.Op Fl reqopt Ar option +.Op Fl set_serial Ar n +.Op Fl subj Ar arg +.Op Fl subject +.Op Fl text +.Op Fl utf8 +.Op Fl verbose +.Op Fl verify +.Op Fl x509 +.Ek +.nr nS 0 +.Pp +The +.Nm req +command primarily creates and processes certificate requests +in PKCS#10 format. +It can additionally create self-signed certificates, +for use as root CAs, for example. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl asn1-kludge +By default, the +.Nm req +command outputs certificate requests containing +no attributes in the correct PKCS#10 format. +However certain CAs will only +accept requests containing no attributes in an invalid form: this +option produces this invalid format. +.Pp +More precisely, the +.Em Attributes +in a PKCS#10 certificate request are defined as a SET OF Attribute. +They are +.Em not +optional, so if no attributes are present then they should be encoded as an +empty SET OF. +The invalid form does not include the empty +SET OF, whereas the correct form does. +.Pp +It should be noted that very few CAs still require the use of this option. +.It Fl batch +Non-interactive mode. +.It Fl config Ar file +This allows an alternative configuration file to be specified; +this overrides the compile time filename or any specified in +the +.Ev OPENSSL_CONF +environment variable. +.It Fl days Ar n +When the +.Fl x509 +option is being used, this specifies the number of +days to certify the certificate for. +The default is 30 days. +.It Fl extensions Ar section , Fl reqexts Ar section +These options specify alternative sections to include certificate +extensions (if the +.Fl x509 +option is present) or certificate request extensions. +This allows several different sections to +be used in the same configuration file to specify requests for +a variety of purposes. +.It Fl in Ar file +This specifies the input +.Ar file +to read a request from, or standard input +if this option is not specified. +A request is only read if the creation options +.Fl new +and +.Fl newkey +are not specified. +.It Fl inform Ar DER | PEM +This specifies the input format. +The +.Ar DER +argument uses an ASN1 DER-encoded form compatible with the PKCS#10. +The +.Ar PEM +form is the default format: +it consists of the DER format base64-encoded with additional header and +footer lines. +.It Fl key Ar keyfile +This specifies the file to read the private key from. +It also accepts PKCS#8 format private keys for PEM format files. +.It Fl keyform Ar DER | PEM +The format of the private key file specified in the +.Fl key +argument. +.Ar PEM +is the default. +.It Fl keyout Ar file +This gives the +.Ar file +to write the newly created private key to. +If this option is not specified, the filename present in the +configuration file is used. +.It Fl md5 | sha1 | sha256 +This specifies the message digest to sign the request with. +This overrides the digest algorithm specified in the configuration file. +.Pp +Some public key algorithms may override this choice. +For instance, DSA signatures always use SHA1. +.It Fl modulus +This option prints out the value of the modulus of the public key +contained in the request. +.It Fl nameopt Ar option , Fl reqopt Ar option +These options determine how the subject or issuer names are displayed. +The +.Ar option +argument can be a single option or multiple options separated by commas. +Alternatively, these options may be used more than once to set multiple options. +See the +.Sx X509 +section below for details. +.It Fl new +This option generates a new certificate request. +It will prompt the user for the relevant field values. +The actual fields prompted for and their maximum and minimum sizes +are specified in the configuration file and any requested extensions. +.Pp +If the +.Fl key +option is not used, it will generate a new RSA private +key using information specified in the configuration file. +.It Fl newhdr +Adds the word NEW to the PEM file header and footer lines +on the outputed request. +Some software +.Pq Netscape certificate server +and some CAs need this. +.It Fl newkey Ar arg +This option creates a new certificate request and a new private key. +The argument takes one of several forms. +.Ar rsa : Ns Ar nbits , +where +.Ar nbits +is the number of bits, generates an RSA key +.Ar nbits +in size. +If +.Ar nbits +is omitted, i.e.\& +.Cm -newkey rsa +specified, +the default key size, specified in the configuration file, is used. +.Pp +All other algorithms support the +.Ar alg : Ns Ar file +form, +where file may be an algorithm parameter file, +created by the +.Cm genpkey -genparam +command or an X.509 certificate for a key with appropriate algorithm. +.Pp +.Ar param : Ns Ar file +generates a key using the parameter file or certificate +.Ar file ; +the algorithm is determined by the parameters. +.Ar algname : Ns Ar file +use algorithm +.Ar algname +and parameter file +.Ar file : +the two algorithms must match or an error occurs. +.Ar algname +just uses algorithm +.Ar algname , +and parameters, if necessary, +should be specified via the +.Fl pkeyopt +option. +.Pp +.Ar dsa : Ns Ar file +generates a DSA key using the parameters in the file +.Ar file . +.It Fl no-asn1-kludge +Reverses the effect of +.Fl asn1-kludge . +.It Fl nodes +If this option is specified and a private key is created, it +will not be encrypted. +.It Fl noout +This option prevents output of the encoded version of the request. +.It Fl out Ar file +This specifies the output +.Ar file +to write to, or standard output by default. +.It Fl outform Ar DER | PEM +This specifies the output format; the options have the same meaning as the +.Fl inform +option. +.It Fl passin Ar arg +The key password source. +.It Fl passout Ar arg +The output file password source. +.It Fl pubkey +Outputs the public key. +.It Fl reqopt Ar option +Customise the output format used with +.Fl text . +The +.Ar option +argument can be a single option or multiple options separated by commas. +.Pp +See the discussion of the +.Fl certopt +option in the +.Nm x509 +command. +.It Fl set_serial Ar n +Serial number to use when outputting a self-signed certificate. +This may be specified as a decimal value or a hex value if preceded by +.Sq 0x . +It is possible to use negative serial numbers but this is not recommended. +.It Fl subj Ar arg +Replaces subject field of input request with specified data and outputs +modified request. +The arg must be formatted as +.Em /type0=value0/type1=value1/type2=... ; +characters may be escaped by +.Sq \e +.Pq backslash ; +no spaces are skipped. +.It Fl subject +Prints out the request subject (or certificate subject if +.Fl x509 +is specified. +.It Fl text +Prints out the certificate request in text form. +.It Fl utf8 +This option causes field values to be interpreted as UTF8 strings; +by default they are interpreted as ASCII. +This means that the field values, whether prompted from a terminal or +obtained from a configuration file, must be valid UTF8 strings. +.It Fl verbose +Print extra details about the operations being performed. +.It Fl verify +Verifies the signature on the request. +.It Fl x509 +This option outputs a self-signed certificate instead of a certificate +request. +This is typically used to generate a test certificate or +a self-signed root CA. +The extensions added to the certificate +.Pq if any +are specified in the configuration file. +Unless specified using the +.Fl set_serial +option, 0 will be used for the serial number. +.El +.Sh REQ CONFIGURATION FILE FORMAT +The configuration options are specified in the +.Em req +section of the configuration file. +As with all configuration files, if no value is specified in the specific +section (i.e.\& +.Em req ) +then the initial unnamed or +.Em default +section is searched too. +.Pp +The options available are described in detail below. +.Bl -tag -width "XXXX" +.It Ar attributes +This specifies the section containing any request attributes: its format +is the same as +.Ar distinguished_name . +Typically these may contain the +.Em challengePassword +or +.Em unstructuredName +types. +They are currently ignored by +.Nm OpenSSL Ns Li 's +request signing utilities, but some CAs might want them. +.It Ar default_bits +This specifies the default key size in bits. +If not specified, 2048 is used. +It is used if the +.Fl new +option is used. +It can be overridden by using the +.Fl newkey +option. +.It Ar default_keyfile +This is the default file to write a private key to. +If not specified, the key is written to standard output. +This can be overridden by the +.Fl keyout +option. +.It Ar default_md +This option specifies the digest algorithm to use. +Possible values include +.Ar md5 , +.Ar sha1 +and +.Ar sha256 . +If not present, SHA256 is used. +This option can be overridden on the command line. +.It Ar distinguished_name +This specifies the section containing the distinguished name fields to +prompt for when generating a certificate or certificate request. +The format is described in the next section. +.It Ar encrypt_key +If this is set to +.Em no +and a private key is generated, it is +.Em not +encrypted. +This is equivalent to the +.Fl nodes +command line option. +For compatibility, +.Ar encrypt_rsa_key +is an equivalent option. +.It Ar input_password | output_password +The passwords for the input private key file +.Pq if present +and the output private key file +.Pq if one will be created . +The command line options +.Fl passin +and +.Fl passout +override the configuration file values. +.It Ar oid_file +This specifies a file containing additional OBJECT IDENTIFIERS. +Each line of the file should consist of the numerical form of the +object identifier, followed by whitespace, then the short name followed +by whitespace and finally the long name. +.It Ar oid_section +This specifies a section in the configuration file containing extra +object identifiers. +Each line should consist of the short name of the +object identifier followed by +.Sq = +and the numerical form. +The short and long names are the same when this option is used. +.It Ar prompt +If set to the value +.Em no , +this disables prompting of certificate fields +and just takes values from the config file directly. +It also changes the expected format of the +.Em distinguished_name +and +.Em attributes +sections. +.It Ar req_extensions +This specifies the configuration file section containing a list of +extensions to add to the certificate request. +It can be overridden by the +.Fl reqexts +command line switch. +.It Ar string_mask +This option limits the string types for encoding certain +fields. +The following values may be used, limiting strings to the indicated types: +.Bl -tag -width "MASK:number" +.It Ar utf8only +.Em UTF8String. +This is the default, as recommended by PKIX in RFC 2459. +.It Ar default +.Em PrintableString , IA5String , T61String , BMPString , UTF8String . +.It Ar pkix +.Em PrintableString , IA5String , BMPString , UTF8String . +This was inspired by the PKIX recommendation in RFC 2459 for certificates +generated before 2004, but differs by also permitting +.Em IA5String . +.It Ar nombstr +.Em PrintableString , IA5String , T61String , UniversalString . +This was a workaround for some ancient software that had problems +with the variable-sized +.Em BMPString +and +.Em UTF8String +types. +.It Cm MASK : Ns Ar number +This is an explicit bitmask of permitted types, where +.Ar number +is a C-style hex, decimal, or octal number that's a bit-wise OR of +.Dv B_ASN1_* +values from +.In openssl/asn1.h . +.El +.It Ar utf8 +If set to the value +.Em yes , +then field values are interpreted as UTF8 strings; +by default they are interpreted as ASCII. +This means that the field values, whether prompted from a terminal or +obtained from a configuration file, must be valid UTF8 strings. +.It Ar x509_extensions +This specifies the configuration file section containing a list of +extensions to add to a certificate generated when the +.Fl x509 +switch is used. +It can be overridden by the +.Fl extensions +command line switch. +.El +.Sh REQ DISTINGUISHED NAME AND ATTRIBUTE SECTION FORMAT +There are two separate formats for the distinguished name and attribute +sections. +If the +.Fl prompt +option is set to +.Em no , +then these sections just consist of field names and values: for example, +.Bd -unfilled -offset indent +CN=My Name +OU=My Organization +emailAddress=someone@somewhere.org +.Ed +.Pp +This allows external programs +.Pq e.g. GUI based +to generate a template file with all the field names and values +and just pass it to +.Nm req . +An example of this kind of configuration file is contained in the +.Sx REQ EXAMPLES +section. +.Pp +Alternatively if the +.Fl prompt +option is absent or not set to +.Em no , +then the file contains field prompting information. +It consists of lines of the form: +.Bd -unfilled -offset indent +fieldName="prompt" +fieldName_default="default field value" +fieldName_min= 2 +fieldName_max= 4 +.Ed +.Pp +.Qq fieldName +is the field name being used, for example +.Em commonName +.Pq or CN . +The +.Qq prompt +string is used to ask the user to enter the relevant details. +If the user enters nothing, the default value is used; +if no default value is present, the field is omitted. +A field can still be omitted if a default value is present, +if the user just enters the +.Sq \&. +character. +.Pp +The number of characters entered must be between the +.Em fieldName_min +and +.Em fieldName_max +limits: +there may be additional restrictions based on the field being used +(for example +.Em countryName +can only ever be two characters long and must fit in a +.Em PrintableString ) . +.Pp +Some fields (such as +.Em organizationName ) +can be used more than once in a DN. +This presents a problem because configuration files will +not recognize the same name occurring twice. +To avoid this problem, if the +.Em fieldName +contains some characters followed by a full stop, they will be ignored. +So, for example, a second +.Em organizationName +can be input by calling it +.Qq 1.organizationName . +.Pp +The actual permitted field names are any object identifier short or +long names. +These are compiled into +.Nm OpenSSL +and include the usual values such as +.Em commonName , countryName , localityName , organizationName , +.Em organizationUnitName , stateOrProvinceName . +Additionally, +.Em emailAddress +is included as well as +.Em name , surname , givenName initials +and +.Em dnQualifier . +.Pp +Additional object identifiers can be defined with the +.Ar oid_file +or +.Ar oid_section +options in the configuration file. +Any additional fields will be treated as though they were a +.Em DirectoryString . +.Sh REQ EXAMPLES +Examine and verify a certificate request: +.Pp +.Dl $ openssl req -in req.pem -text -verify -noout +.Pp +Create a private key and then generate a certificate request from it: +.Bd -literal -offset indent +$ openssl genrsa -out key.pem 2048 +$ openssl req -new -key key.pem -out req.pem +.Ed +.Pp +The same but just using req: +.Pp +.Dl $ openssl req -newkey rsa:2048 -keyout key.pem -out req.pem +.Pp +Generate a self-signed root certificate: +.Pp +.Dl "$ openssl req -x509 -newkey rsa:2048 -keyout key.pem -out req.pem" +.Pp +Example of a file pointed to by the +.Ar oid_file +option: +.Bd -unfilled -offset indent +1.2.3.4 shortName A longer Name +1.2.3.6 otherName Other longer Name +.Ed +.Pp +Example of a section pointed to by +.Ar oid_section +making use of variable expansion: +.Bd -unfilled -offset indent +testoid1=1.2.3.5 +testoid2=${testoid1}.6 +.Ed +.Pp +Sample configuration file prompting for field values: +.Bd -literal +\& [ req ] +\& default_bits = 1024 +\& default_keyfile = privkey.pem +\& distinguished_name = req_distinguished_name +\& attributes = req_attributes +\& x509_extensions = v3_ca + +\& dirstring_type = nobmp + +\& [ req_distinguished_name ] +\& countryName = Country Name (2 letter code) +\& countryName_default = AU +\& countryName_min = 2 +\& countryName_max = 2 + +\& localityName = Locality Name (eg, city) + +\& organizationalUnitName = Organizational Unit Name (eg, section) + +\& commonName = Common Name (eg, YOUR name) +\& commonName_max = 64 + +\& emailAddress = Email Address +\& emailAddress_max = 40 + +\& [ req_attributes ] +\& challengePassword = A challenge password +\& challengePassword_min = 4 +\& challengePassword_max = 20 + +\& [ v3_ca ] + +\& subjectKeyIdentifier=hash +\& authorityKeyIdentifier=keyid:always,issuer:always +\& basicConstraints = CA:true +.Ed +.Pp +Sample configuration containing all field values: +.Bd -literal + +\& [ req ] +\& default_bits = 1024 +\& default_keyfile = keyfile.pem +\& distinguished_name = req_distinguished_name +\& attributes = req_attributes +\& prompt = no +\& output_password = mypass + +\& [ req_distinguished_name ] +\& C = GB +\& ST = Test State or Province +\& L = Test Locality +\& O = Organization Name +\& OU = Organizational Unit Name +\& CN = Common Name +\& emailAddress = test@email.address + +\& [ req_attributes ] +\& challengePassword = A challenge password +.Ed +.Sh REQ NOTES +The header and footer lines in the PEM format are normally: +.Bd -unfilled -offset indent +-----BEGIN CERTIFICATE REQUEST----- +-----END CERTIFICATE REQUEST----- +.Ed +.Pp +Some software +.Pq some versions of Netscape certificate server +instead needs: +.Bd -unfilled -offset indent +-----BEGIN NEW CERTIFICATE REQUEST----- +-----END NEW CERTIFICATE REQUEST----- +.Ed +.Pp +which is produced with the +.Fl newhdr +option but is otherwise compatible. +Either form is accepted transparently on input. +.Pp +The certificate requests generated by Xenroll with MSIE have extensions added. +It includes the +.Em keyUsage +extension which determines the type of key +.Pq signature only or general purpose +and any additional OIDs entered by the script in an +.Em extendedKeyUsage +extension. +.Sh REQ DIAGNOSTICS +The following messages are frequently asked about: +.Bd -unfilled -offset indent +Using configuration from /some/path/openssl.cnf +Unable to load config info +.Ed +.Pp +This is followed some time later by... +.Bd -unfilled -offset indent +unable to find 'distinguished_name' in config +problems making Certificate Request +.Ed +.Pp +The first error message is the clue: it can't find the configuration +file! +Certain operations +.Pq like examining a certificate request +don't need a configuration file so its use isn't enforced. +Generation of certificates or requests, however, do need a configuration file. +This could be regarded as a bug. +.Pp +Another puzzling message is this: +.Bd -unfilled -offset indent +Attributes: + a0:00 +.Ed +.Pp +This is displayed when no attributes are present and the request includes +the correct empty SET OF structure +.Pq the DER encoding of which is 0xa0 0x00 . +If you just see: +.Pp +.D1 Attributes: +.Pp +then the SET OF is missing and the encoding is technically invalid +.Pq but it is tolerated . +See the description of the command line option +.Fl asn1-kludge +for more information. +.Sh REQ ENVIRONMENT VARIABLES +The variable +.Ev OPENSSL_CONF , +if defined, allows an alternative configuration +file location to be specified; it will be overridden by the +.Fl config +command line switch if it is present. +.Sh REQ BUGS +.Nm OpenSSL Ns Li 's +handling of T61Strings +.Pq aka TeletexStrings +is broken: it effectively treats them as ISO 8859-1 +.Pq Latin 1 ; +Netscape and MSIE have similar behaviour. +This can cause problems if you need characters that aren't available in +.Em PrintableStrings +and you don't want to or can't use +.Em BMPStrings . +.Pp +As a consequence of the T61String handling, the only correct way to represent +accented characters in +.Nm OpenSSL +is to use a +.Em BMPString : +unfortunately Netscape currently chokes on these. +If you have to use accented characters with Netscape +and MSIE then you currently need to use the invalid T61String form. +.Pp +The current prompting is not very friendly. +It doesn't allow you to confirm what you've just entered. +Other things, like extensions in certificate requests, are +statically defined in the configuration file. +Some of these, like an email address in +.Em subjectAltName , +should be input by the user. +.\" +.\" RSA +.\" +.Sh RSA +.nr nS 1 +.Nm "openssl rsa" +.Bk -words +.Oo +.Fl aes128 | aes192 | aes256 | +.Fl des | des3 +.Oc +.Op Fl check +.Op Fl in Ar file +.Op Fl inform Ar DER | NET | PEM +.Op Fl modulus +.Op Fl noout +.Op Fl out Ar file +.Op Fl outform Ar DER | NET | PEM +.Op Fl passin Ar arg +.Op Fl passout Ar arg +.Op Fl pubin +.Op Fl pubout +.Op Fl sgckey +.Op Fl text +.nr nS 0 +.Ek +.Pp +The +.Nm rsa +command processes RSA keys. +They can be converted between various forms and their components printed out. +.Pp +.Sy Note : +this command uses the traditional +.Nm SSLeay +compatible format for private key encryption: +newer applications should use the more secure PKCS#8 format using the +.Nm pkcs8 +utility. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Xo +.Fl aes128 | aes192 | aes256 | +.Fl des | des3 +.Xc +These options encrypt the private key with the AES, DES, +or the triple DES ciphers, respectively, before outputting it. +A pass phrase is prompted for. +If none of these options are specified, the key is written in plain text. +This means that using the +.Nm rsa +utility to read in an encrypted key with no encryption option can be used +to remove the pass phrase from a key, or by setting the encryption options +it can be used to add or change the pass phrase. +These options can only be used with PEM format output files. +.It Fl check +This option checks the consistency of an RSA private key. +.It Fl in Ar file +This specifies the input +.Ar file +to read a key from, or standard input if this +option is not specified. +If the key is encrypted, a pass phrase will be prompted for. +.It Fl inform Ar DER | NET | PEM +This specifies the input format. +The +.Ar DER +argument +uses an ASN1 DER-encoded form compatible with the PKCS#1 +RSAPrivateKey or SubjectPublicKeyInfo format. +The +.Ar PEM +form is the default format: it consists of the DER format base64-encoded with +additional header and footer lines. +On input PKCS#8 format private keys are also accepted. +The +.Ar NET +form is a format described in the +.Sx RSA NOTES +section. +.It Fl noout +This option prevents output of the encoded version of the key. +.It Fl modulus +This option prints out the value of the modulus of the key. +.It Fl out Ar file +This specifies the output +.Ar file +to write a key to, or standard output if this option is not specified. +If any encryption options are set, a pass phrase will be prompted for. +The output filename should +.Em not +be the same as the input filename. +.It Fl outform Ar DER | NET | PEM +This specifies the output format; the options have the same meaning as the +.Fl inform +option. +.It Fl passin Ar arg +The key password source. +.It Fl passout Ar arg +The output file password source. +.It Fl pubin +By default, a private key is read from the input file; with this +option a public key is read instead. +.It Fl pubout +By default, a private key is output; +with this option a public key will be output instead. +This option is automatically set if the input is a public key. +.It Fl sgckey +Use the modified +.Em NET +algorithm used with some versions of Microsoft IIS and SGC keys. +.It Fl text +Prints out the various public or private key components in +plain text, in addition to the encoded version. +.El +.Sh RSA NOTES +The PEM private key format uses the header and footer lines: +.Bd -unfilled -offset indent +-----BEGIN RSA PRIVATE KEY----- +-----END RSA PRIVATE KEY----- +.Ed +.Pp +The PEM public key format uses the header and footer lines: +.Bd -unfilled -offset indent +-----BEGIN PUBLIC KEY----- +-----END PUBLIC KEY----- +.Ed +.Pp +The +.Em NET +form is a format compatible with older Netscape servers +and Microsoft IIS .key files; this uses unsalted RC4 for its encryption. +It is not very secure and so should only be used when necessary. +.Pp +Some newer version of IIS have additional data in the exported .key files. +To use these with the +.Nm rsa +utility, view the file with a binary editor +and look for the string +.Qq private-key , +then trace back to the byte sequence 0x30, 0x82 +.Pq this is an ASN1 SEQUENCE . +Copy all the data from this point onwards to another file and use that as +the input to the +.Nm rsa +utility with the +.Fl inform Ar NET +option. +If there is an error after entering the password, try the +.Fl sgckey +option. +.Sh RSA EXAMPLES +To remove the pass phrase on an RSA private key: +.Pp +.Dl $ openssl rsa -in key.pem -out keyout.pem +.Pp +To encrypt a private key using triple DES: +.Pp +.Dl $ openssl rsa -in key.pem -des3 -out keyout.pem +.Pp +To convert a private key from PEM to DER format: +.Pp +.Dl $ openssl rsa -in key.pem -outform DER -out keyout.der +.Pp +To print out the components of a private key to standard output: +.Pp +.Dl $ openssl rsa -in key.pem -text -noout +.Pp +To just output the public part of a private key: +.Pp +.Dl $ openssl rsa -in key.pem -pubout -out pubkey.pem +.Sh RSA BUGS +The command line password arguments don't currently work with +.Em NET +format. +.Pp +There should be an option that automatically handles .key files, +without having to manually edit them. +.\" +.\" RSAUTL +.\" +.Sh RSAUTL +.nr nS 1 +.Nm "openssl rsautl" +.Bk -words +.Op Fl asn1parse +.Op Fl certin +.Op Fl decrypt +.Op Fl encrypt +.Op Fl hexdump +.Op Fl in Ar file +.Op Fl inkey Ar file +.Op Fl keyform Ar DER | PEM +.Op Fl oaep | pkcs | raw | ssl +.Op Fl out Ar file +.Op Fl pubin +.Op Fl sign +.Op Fl verify +.Ek +.nr nS 0 +.Pp +The +.Nm rsautl +command can be used to sign, verify, encrypt and decrypt +data using the RSA algorithm. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl asn1parse +Asn1parse the output data; this is useful when combined with the +.Fl verify +option. +.It Fl certin +The input is a certificate containing an RSA public key. +.It Fl decrypt +Decrypt the input data using an RSA private key. +.It Fl encrypt +Encrypt the input data using an RSA public key. +.It Fl hexdump +Hex dump the output data. +.It Fl in Ar file +This specifies the input +.Ar file +to read data from, or standard input +if this option is not specified. +.It Fl inkey Ar file +The input key file, by default it should be an RSA private key. +.It Fl keyform Ar DER | PEM +Private ket format. +Default is +.Ar PEM . +.It Fl oaep | pkcs | raw | ssl +The padding to use: +PKCS#1 OAEP, PKCS#1 v1.5 +.Pq the default , +or no padding, respectively. +For signatures, only +.Fl pkcs +and +.Fl raw +can be used. +.It Fl out Ar file +Specifies the output +.Ar file +to write to, or standard output by +default. +.It Fl pubin +The input file is an RSA public key. +.It Fl sign +Sign the input data and output the signed result. +This requires an RSA private key. +.It Fl verify +Verify the input data and output the recovered data. +.El +.Sh RSAUTL NOTES +.Nm rsautl , +because it uses the RSA algorithm directly, can only be +used to sign or verify small pieces of data. +.Sh RSAUTL EXAMPLES +Sign some data using a private key: +.Pp +.Dl "$ openssl rsautl -sign -in file -inkey key.pem -out sig" +.Pp +Recover the signed data: +.Pp +.Dl $ openssl rsautl -verify -in sig -inkey key.pem +.Pp +Examine the raw signed data: +.Pp +.Li "\ \&$ openssl rsautl -verify -in file -inkey key.pem -raw -hexdump" +.Bd -unfilled +\& 0000 - 00 01 ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ +\& 0010 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ +\& 0020 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ +\& 0030 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ +\& 0040 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ +\& 0050 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ +\& 0060 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ +\& 0070 - ff ff ff ff 00 68 65 6c-6c 6f 20 77 6f 72 6c 64 .....hello world +.Ed +.Pp +The PKCS#1 block formatting is evident from this. +If this was done using encrypt and decrypt, the block would have been of type 2 +.Pq the second byte +and random padding data visible instead of the 0xff bytes. +.Pp +It is possible to analyse the signature of certificates using this +utility in conjunction with +.Nm asn1parse . +Consider the self-signed example in +.Pa certs/pca-cert.pem : +running +.Nm asn1parse +as follows yields: +.Pp +.Li "\ \&$ openssl asn1parse -in pca-cert.pem" +.Bd -unfilled +\& 0:d=0 hl=4 l= 742 cons: SEQUENCE +\& 4:d=1 hl=4 l= 591 cons: SEQUENCE +\& 8:d=2 hl=2 l= 3 cons: cont [ 0 ] +\& 10:d=3 hl=2 l= 1 prim: INTEGER :02 +\& 13:d=2 hl=2 l= 1 prim: INTEGER :00 +\& 16:d=2 hl=2 l= 13 cons: SEQUENCE +\& 18:d=3 hl=2 l= 9 prim: OBJECT :md5WithRSAEncryption +\& 29:d=3 hl=2 l= 0 prim: NULL +\& 31:d=2 hl=2 l= 92 cons: SEQUENCE +\& 33:d=3 hl=2 l= 11 cons: SET +\& 35:d=4 hl=2 l= 9 cons: SEQUENCE +\& 37:d=5 hl=2 l= 3 prim: OBJECT :countryName +\& 42:d=5 hl=2 l= 2 prim: PRINTABLESTRING :AU +\& .... +\& 599:d=1 hl=2 l= 13 cons: SEQUENCE +\& 601:d=2 hl=2 l= 9 prim: OBJECT :md5WithRSAEncryption +\& 612:d=2 hl=2 l= 0 prim: NULL +\& 614:d=1 hl=3 l= 129 prim: BIT STRING +.Ed +.Pp +The final BIT STRING contains the actual signature. +It can be extracted with: +.Pp +.Dl "$ openssl asn1parse -in pca-cert.pem -out sig -noout -strparse 614" +.Pp +The certificate public key can be extracted with: +.Pp +.Dl $ openssl x509 -in test/testx509.pem -pubkey -noout \*(Gtpubkey.pem +.Pp +The signature can be analysed with: +.Pp +.Li "\ \&$ openssl rsautl -in sig -verify -asn1parse -inkey pubkey.pem -pubin" +.Bd -unfilled +\& 0:d=0 hl=2 l= 32 cons: SEQUENCE +\& 2:d=1 hl=2 l= 12 cons: SEQUENCE +\& 4:d=2 hl=2 l= 8 prim: OBJECT :md5 +\& 14:d=2 hl=2 l= 0 prim: NULL +\& 16:d=1 hl=2 l= 16 prim: OCTET STRING +\& 0000 - f3 46 9e aa 1a 4a 73 c9-37 ea 93 00 48 25 08 b5 .F...Js.7...H%.. +.Ed +.Pp +This is the parsed version of an ASN1 +.Em DigestInfo +structure. +It can be seen that the digest used was MD5. +The actual part of the certificate that was signed can be extracted with: +.Pp +.Dl "$ openssl asn1parse -in pca-cert.pem -out tbs -noout -strparse 4" +.Pp +and its digest computed with: +.Pp +.Dl $ openssl md5 -c tbs +.D1 MD5(tbs)= f3:46:9e:aa:1a:4a:73:c9:37:ea:93:00:48:25:08:b5 +.Pp +which it can be seen agrees with the recovered value above. +.\" +.\" S_CLIENT +.\" +.Sh S_CLIENT +.nr nS 1 +.Nm "openssl s_client" +.Bk -words +.Op Fl 4 | 6 +.Op Fl bugs +.Op Fl CAfile Ar file +.Op Fl CApath Ar directory +.Op Fl cert Ar file +.Op Fl check_ss_sig +.Op Fl cipher Ar cipherlist +.Oo +.Fl connect Ar host : Ns Ar port | +.Ar host Ns / Ns Ar port +.Oc +.Op Fl crl_check +.Op Fl crl_check_all +.Op Fl crlf +.Op Fl debug +.Op Fl extended_crl +.Op Fl ign_eof +.Op Fl ignore_critical +.Op Fl issuer_checks +.Op Fl key Ar keyfile +.Op Fl msg +.Op Fl nbio +.Op Fl nbio_test +.Op Fl no_ticket +.Op Fl no_tls1 +.Op Fl no_tls1_1 +.Op Fl no_tls1_2 +.Op Fl pause +.Op Fl policy_check +.Op Fl prexit +.Op Fl proxy Ar host : Ns Ar port +.Op Fl psk Ar key +.Op Fl psk_identity Ar identity +.Op Fl quiet +.Op Fl reconnect +.Op Fl servername Ar name +.Op Fl showcerts +.Op Fl starttls Ar protocol +.Op Fl state +.Op Fl tls1 +.Op Fl tls1_1 +.Op Fl tls1_2 +.Op Fl tlsextdebug +.Op Fl verify Ar depth +.Op Fl x509_strict +.Op Fl xmpphost Ar host +.Ek +.nr nS 0 +.Pp +The +.Nm s_client +command implements a generic SSL/TLS client which connects +to a remote host using SSL/TLS. +It is a +.Em very +useful diagnostic tool for SSL servers. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl 4 +Specify that +.Nm s_client +should attempt connections using IPv4 only. +.It Fl 6 +Specify that +.Nm s_client +should attempt connections using IPv6 only. +.It Fl bugs +There are several known bugs in SSL and TLS implementations. +Adding this option enables various workarounds. +.It Fl CAfile Ar file +A +.Ar file +containing trusted certificates to use during server authentication +and to use when attempting to build the client certificate chain. +.It Fl CApath Ar directory +The +.Ar directory +to use for server certificate verification. +This directory must be in +.Qq hash format ; +see +.Fl verify +for more information. +These are also used when building the client certificate chain. +.It Fl cert Ar file +The certificate to use, if one is requested by the server. +The default is not to use a certificate. +.It Xo +.Fl check_ss_sig , +.Fl crl_check , +.Fl crl_check_all , +.Fl extended_crl , +.Fl ignore_critical , +.Fl issuer_checks , +.Fl policy_check , +.Fl x509_strict +.Xc +Set various certificate chain validation options. +See the +.Nm VERIFY +command for details. +.It Fl cipher Ar cipherlist +This allows the cipher list sent by the client to be modified. +Although the server determines which cipher suite is used, it should take +the first supported cipher in the list sent by the client. +See the +.Sx CIPHERS +section above for more information. +.It Xo +.Fl connect Ar host : Ns Ar port | +.Ar host Ns / Ns Ar port +.Xc +This specifies the +.Ar host +and optional +.Ar port +to connect to. +If not specified, an attempt is made to connect to the local host +on port 4433. +Alternatively, the host and port pair may be separated using a forward-slash +character. +This form is useful for numeric IPv6 addresses. +.It Fl crlf +This option translates a line feed from the terminal into CR+LF as required +by some servers. +.It Fl debug +Print extensive debugging information including a hex dump of all traffic. +.It Fl ign_eof +Inhibit shutting down the connection when end of file is reached in the +input. +.It Fl key Ar keyfile +The private key to use. +If not specified, the certificate file will be used. +.It Fl msg +Show all protocol messages with hex dump. +.It Fl nbio +Turns on non-blocking I/O. +.It Fl nbio_test +Tests non-blocking I/O. +.It Fl no_tls1 | no_tls1_1 | no_tls1_2 +By default, the initial handshake uses a method which should be compatible +with servers supporting any version of TLS. +These options disable the use of TLS1.0, 1.1, and 1.2, respectively. +.Pp +Unfortunately there are a lot of ancient and broken servers in use which +cannot handle this technique and will fail to connect. +.It Fl no_ticket +Disable RFC 4507 session ticket support. +.It Fl pause +Pauses 1 second between each read and write call. +.It Fl prexit +Print session information when the program exits. +This will always attempt +to print out information even if the connection fails. +Normally, information will only be printed out once if the connection succeeds. +This option is useful because the cipher in use may be renegotiated +or the connection may fail because a client certificate is required or is +requested only after an attempt is made to access a certain URL. +.Sy Note : +the output produced by this option is not always accurate because a +connection might never have been established. +.It Fl proxy Ar host : Ns Ar port +Use the HTTP proxy at +.Ar host +and +.Ar port . +The connection to the proxy is done in cleartext and the +.Fl connect +argument is given to the proxy. +If not specified, localhost is used as final destination. +After that, switch the connection through the proxy to the destination +to TLS. +.It Fl psk Ar key +Use the PSK key +.Ar key +when using a PSK cipher suite. +The key is given as a hexadecimal number without the leading 0x, +for example -psk 1a2b3c4d. +.It Fl psk_identity Ar identity +Use the PSK identity +.Ar identity +when using a PSK cipher suite. +.It Fl quiet +Inhibit printing of session and certificate information. +This implicitly turns on +.Fl ign_eof +as well. +.It Fl reconnect +Reconnects to the same server 5 times using the same session ID; this can +be used as a test that session caching is working. +.It Fl servername Ar name +Include the TLS Server Name Indication (SNI) extension in the ClientHello +message, using the specified server +.Ar name . +.It Fl showcerts +Display the whole server certificate chain: normally only the server +certificate itself is displayed. +.It Fl starttls Ar protocol +Send the protocol-specific message(s) to switch to TLS for communication. +.Ar protocol +is a keyword for the intended protocol. +Currently, the supported keywords are +.Qq ftp , +.Qq imap , +.Qq smtp , +.Qq pop3 , +and +.Qq xmpp . +.It Fl state +Prints out the SSL session states. +.It Fl tls1 | tls1_1 | tls1_2 +Permit only TLS1.0, 1.1, or 1.2, respectively. +.It Fl tlsextdebug +Print out a hex dump of any TLS extensions received from the server. +.It Fl verify Ar depth +The verify +.Ar depth +to use. +This specifies the maximum length of the +server certificate chain and turns on server certificate verification. +Currently the verify operation continues after errors so all the problems +with a certificate chain can be seen. +As a side effect the connection will never fail due to a server +certificate verify failure. +.It Fl xmpphost Ar hostname +This option, when used with +.Fl starttls Ar xmpp , +specifies the host for the "to" attribute of the stream element. +If this option is not specified then the host specified with +.Fl connect +will be used. +.El +.Sh S_CLIENT CONNECTED COMMANDS +If a connection is established with an SSL server, any data received +from the server is displayed and any key presses will be sent to the +server. +When used interactively (which means neither +.Fl quiet +nor +.Fl ign_eof +have been given), the session will be renegotiated if the line begins with an +.Em R ; +if the line begins with a +.Em Q +or if end of file is reached, the connection will be closed down. +.Sh S_CLIENT NOTES +.Nm s_client +can be used to debug SSL servers. +To connect to an SSL HTTP server the command: +.Pp +.Dl $ openssl s_client -connect servername:443 +.Pp +would typically be used +.Pq HTTPS uses port 443 . +If the connection succeeds, an HTTP command can be given such as +.Qq GET +to retrieve a web page. +.Pp +If the handshake fails, there are several possible causes; if it is +nothing obvious like no client certificate, then the +.Fl bugs , tls1 , tls1_1, tls1_2 , no_tls1 , no_tls1_1 , +and +.Fl no_tls1_2 +options can be tried in case it is a buggy server. +.Pp +A frequent problem when attempting to get client certificates working +is that a web client complains it has no certificates or gives an empty +list to choose from. +This is normally because the server is not sending the client's certificate +authority in its +.Qq acceptable CA list +when it requests a certificate. +By using +.Nm s_client +the CA list can be viewed and checked. +However some servers only request client authentication +after a specific URL is requested. +To obtain the list in this case it is necessary to use the +.Fl prexit +option and send an HTTP request for an appropriate page. +.Pp +If a certificate is specified on the command line using the +.Fl cert +option, it will not be used unless the server specifically requests +a client certificate. +Therefore merely including a client certificate +on the command line is no guarantee that the certificate works. +.Pp +If there are problems verifying a server certificate, the +.Fl showcerts +option can be used to show the whole chain. +.Pp +Compression methods are only supported for +.Fl tls1 . +.Sh S_CLIENT BUGS +Because this program has a lot of options and also because some of +the techniques used are rather old, the C source of +.Nm s_client +is rather hard to read and not a model of how things should be done. +A typical SSL client program would be much simpler. +.Pp +The +.Fl verify +option should really exit if the server verification fails. +.Pp +The +.Fl prexit +option is a bit of a hack. +We should really report information whenever a session is renegotiated. +.\" +.\" S_SERVER +.\" +.Sh S_SERVER +.nr nS 1 +.Nm "openssl s_server" +.Bk -words +.Op Fl accept Ar port +.Op Fl bugs +.Op Fl CAfile Ar file +.Op Fl CApath Ar directory +.Op Fl cert Ar file +.Op Fl cipher Ar cipherlist +.Op Fl context Ar id +.Op Fl crl_check +.Op Fl crl_check_all +.Op Fl crlf +.Op Fl dcert Ar file +.Op Fl debug +.Op Fl dhparam Ar file +.Op Fl dkey Ar file +.Op Fl hack +.Op Fl HTTP +.Op Fl id_prefix Ar arg +.Op Fl key Ar keyfile +.Op Fl msg +.Op Fl nbio +.Op Fl nbio_test +.Op Fl no_dhe +.Op Fl no_tls1 +.Op Fl no_tls1_1 +.Op Fl no_tls1_2 +.Op Fl no_tmp_rsa +.Op Fl nocert +.Op Fl psk Ar key +.Op Fl psk_hint Ar hint +.Op Fl quiet +.Op Fl serverpref +.Op Fl state +.Op Fl tls1 +.Op Fl tls1_1 +.Op Fl tls1_2 +.Op Fl Verify Ar depth +.Op Fl verify Ar depth +.Op Fl WWW +.Op Fl www +.Ek +.nr nS 0 +.Pp +The +.Nm s_server +command implements a generic SSL/TLS server which listens +for connections on a given port using SSL/TLS. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl accept Ar port +The TCP +.Ar port +to listen on for connections. +If not specified, 4433 is used. +.It Fl bugs +There are several known bugs in SSL and TLS implementations. +Adding this option enables various workarounds. +.It Fl CAfile Ar file +A file containing trusted certificates to use during client authentication +and to use when attempting to build the server certificate chain. +The list is also used in the list of acceptable client CAs passed to the +client when a certificate is requested. +.It Fl CApath Ar directory +The +.Ar directory +to use for client certificate verification. +This directory must be in +.Qq hash format ; +see +.Fl verify +for more information. +These are also used when building the server certificate chain. +.It Fl cert Ar file +The certificate to use; most server's cipher suites require the use of a +certificate and some require a certificate with a certain public key type: +for example the DSS cipher suites require a certificate containing a DSS +.Pq DSA +key. +If not specified, the file +.Pa server.pem +will be used. +.It Fl cipher Ar cipherlist +This allows the cipher list used by the server to be modified. +When the client sends a list of supported ciphers, the first client cipher +also included in the server list is used. +Because the client specifies the preference order, the order of the server +cipherlist is irrelevant. +See the +.Sx CIPHERS +section for more information. +.It Fl context Ar id +Sets the SSL context ID. +It can be given any string value. +If this option is not present, a default value will be used. +.It Fl crl_check , crl_check_all +Check the peer certificate has not been revoked by its CA. +The CRLs are appended to the certificate file. +With the +.Fl crl_check_all +option, all CRLs of all CAs in the chain are checked. +.It Fl crlf +This option translates a line feed from the terminal into CR+LF. +.It Fl dcert Ar file , Fl dkey Ar file +Specify an additional certificate and private key; these behave in the +same manner as the +.Fl cert +and +.Fl key +options except there is no default if they are not specified +.Pq no additional certificate or key is used . +As noted above some cipher suites require a certificate containing a key of +a certain type. +Some cipher suites need a certificate carrying an RSA key +and some a DSS +.Pq DSA +key. +By using RSA and DSS certificates and keys, +a server can support clients which only support RSA or DSS cipher suites +by using an appropriate certificate. +.It Fl debug +Print extensive debugging information including a hex dump of all traffic. +.It Fl dhparam Ar file +The DH parameter file to use. +The ephemeral DH cipher suites generate keys +using a set of DH parameters. +If not specified, an attempt is made to +load the parameters from the server certificate file. +If this fails, a static set of parameters hard coded into the +.Nm s_server +program will be used. +.It Fl hack +This option enables a further workaround for some early Netscape +SSL code +.Pq \&? . +.It Fl HTTP +Emulates a simple web server. +Pages will be resolved relative to the current directory; +for example if the URL +.Pa https://myhost/page.html +is requested, the file +.Pa ./page.html +will be loaded. +The files loaded are assumed to contain a complete and correct HTTP +response (lines that are part of the HTTP response line and headers +must end with CRLF). +.It Fl id_prefix Ar arg +Generate SSL/TLS session IDs prefixed by +.Ar arg . +This is mostly useful for testing any SSL/TLS code +.Pq e.g. proxies +that wish to deal with multiple servers, when each of which might be +generating a unique range of session IDs +.Pq e.g. with a certain prefix . +.It Fl key Ar keyfile +The private key to use. +If not specified, the certificate file will be used. +.It Fl msg +Show all protocol messages with hex dump. +.It Fl nbio +Turns on non-blocking I/O. +.It Fl nbio_test +Tests non-blocking I/O. +.It Fl no_dhe +If this option is set, no DH parameters will be loaded, effectively +disabling the ephemeral DH cipher suites. +.It Fl no_tls1 | no_tls1_1 | no_tls1_2 +By default, the initial handshake uses a method which should be compatible +with clients supporting any version of TLS. +These options disable the use of TLS1.0, 1.1, and 1.2, respectively. +.It Fl no_tmp_rsa +Certain export cipher suites sometimes use a temporary RSA key; this option +disables temporary RSA key generation. +.It Fl nocert +If this option is set, no certificate is used. +This restricts the cipher suites available to the anonymous ones +.Pq currently just anonymous DH . +.It Fl psk Ar key +Use the PSK key +.Ar key +when using a PSK cipher suite. +The key is given as a hexadecimal number without the leading 0x, +for example -psk 1a2b3c4d. +.It Fl psk_hint Ar hint +Use the PSK identity hint +.Ar hint +when using a PSK cipher suite. +.It Fl quiet +Inhibit printing of session and certificate information. +.It Fl serverpref +Use server's cipher preferences. +.It Fl state +Prints out the SSL session states. +.It Fl tls1 | tls1_1 | tls1_2 +Permit only TLS1.0, 1.1, or 1.2, respectively. +.It Fl WWW +Emulates a simple web server. +Pages will be resolved relative to the current directory; +for example if the URL +.Pa https://myhost/page.html +is requested, the file +.Pa ./page.html +will be loaded. +.It Fl www +Sends a status message back to the client when it connects. +This includes lots of information about the ciphers used and various +session parameters. +The output is in HTML format so this option will normally be used with a +web browser. +.It Fl Verify Ar depth , Fl verify Ar depth +The verify +.Ar depth +to use. +This specifies the maximum length of the client certificate chain +and makes the server request a certificate from the client. +With the +.Fl Verify +option, the client must supply a certificate or an error occurs. +With the +.Fl verify +option, a certificate is requested but the client does not have to send one. +.El +.Sh S_SERVER CONNECTED COMMANDS +If a connection request is established with an SSL client and neither the +.Fl www +nor the +.Fl WWW +option has been used, then normally any data received +from the client is displayed and any key presses will be sent to the client. +.Pp +Certain single letter commands are also recognized which perform special +operations: these are listed below. +.Bl -tag -width "XXXX" +.It Ar P +Send some plain text down the underlying TCP connection: this should +cause the client to disconnect due to a protocol violation. +.It Ar Q +End the current SSL connection and exit. +.It Ar q +End the current SSL connection, but still accept new connections. +.It Ar R +Renegotiate the SSL session and request a client certificate. +.It Ar r +Renegotiate the SSL session. +.It Ar S +Print out some session cache status information. +.El +.Sh S_SERVER NOTES +.Nm s_server +can be used to debug SSL clients. +To accept connections from a web browser the command: +.Pp +.Dl $ openssl s_server -accept 443 -www +.Pp +can be used, for example. +.Pp +Most web browsers +.Pq in particular Netscape and MSIE +only support RSA cipher suites, so they cannot connect to servers +which don't use a certificate carrying an RSA key or a version of +.Nm OpenSSL +with RSA disabled. +.Pp +Although specifying an empty list of CAs when requesting a client certificate +is strictly speaking a protocol violation, some SSL +clients interpret this to mean any CA is acceptable. +This is useful for debugging purposes. +.Pp +The session parameters can printed out using the +.Nm sess_id +program. +.Sh S_SERVER BUGS +Because this program has a lot of options and also because some of +the techniques used are rather old, the C source of +.Nm s_server +is rather hard to read and not a model of how things should be done. +A typical SSL server program would be much simpler. +.Pp +The output of common ciphers is wrong: it just gives the list of ciphers that +.Nm OpenSSL +recognizes and the client supports. +.Pp +There should be a way for the +.Nm s_server +program to print out details of any +unknown cipher suites a client says it supports. +.\" +.\" S_TIME +.\" +.Sh S_TIME +.nr nS 1 +.Nm "openssl s_time" +.Bk -words +.Op Fl bugs +.Op Fl CAfile Ar file +.Op Fl CApath Ar directory +.Op Fl cert Ar file +.Op Fl cipher Ar cipherlist +.Op Fl connect Ar host : Ns Ar port +.Op Fl key Ar keyfile +.Op Fl nbio +.Op Fl new +.Op Fl no_shutdown +.Op Fl reuse +.Op Fl time Ar seconds +.Op Fl verify Ar depth +.Op Fl www Ar page +.Ek +.nr nS 0 +.Pp +The +.Nm s_client +command implements a generic SSL/TLS client which connects to a +remote host using SSL/TLS. +It can request a page from the server and includes +the time to transfer the payload data in its timing measurements. +It measures the number of connections within a given timeframe, +the amount of data transferred +.Pq if any , +and calculates the average time spent for one connection. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl bugs +There are several known bugs in SSL and TLS implementations. +Adding this option enables various workarounds. +.It Fl CAfile Ar file +A file containing trusted certificates to use during server authentication +and to use when attempting to build the client certificate chain. +.It Fl CApath Ar directory +The directory to use for server certificate verification. +This directory must be in +.Qq hash format ; +see +.Nm verify +for more information. +These are also used when building the client certificate chain. +.It Fl cert Ar file +The certificate to use, if one is requested by the server. +The default is not to use a certificate. +The file is in PEM format. +.It Fl cipher Ar cipherlist +This allows the cipher list sent by the client to be modified. +Although the server determines which cipher suite is used, +it should take the first supported cipher in the list sent by the client. +See the +.Nm ciphers +command for more information. +.It Fl connect Ar host : Ns Ar port +This specifies the host and optional port to connect to. +.It Fl key Ar keyfile +The private key to use. +If not specified, the certificate file will be used. +The file is in PEM format. +.It Fl nbio +Turns on non-blocking I/O. +.It Fl new +Performs the timing test using a new session ID for each connection. +If neither +.Fl new +nor +.Fl reuse +are specified, +they are both on by default and executed in sequence. +.It Fl no_shutdown +Shut down the connection without sending a +.Dq close notify +shutdown alert to the server. +.It Fl reuse +Performs the timing test using the same session ID; +this can be used as a test that session caching is working. +If neither +.Fl new +nor +.Fl reuse +are specified, +they are both on by default and executed in sequence. +.It Fl time Ar seconds +Specifies how long +.Pq in seconds +.Nm s_time +should establish connections and +optionally transfer payload data from a server. +The default is 30 seconds. +Server and client performance and the link speed +determine how many connections +.Nm s_time +can establish. +.It Fl verify Ar depth +The verify depth to use. +This specifies the maximum length of the server certificate chain +and turns on server certificate verification. +Currently the verify operation continues after errors, so all the problems +with a certificate chain can be seen. +As a side effect, +the connection will never fail due to a server certificate verify failure. +.It Fl www Ar page +This specifies the page to GET from the server. +A value of +.Sq / +gets the index.htm[l] page. +If this parameter is not specified, +.Nm s_time +will only perform the handshake to establish SSL connections +but not transfer any payload data. +.El +.Sh S_TIME NOTES +.Nm s_client +can be used to measure the performance of an SSL connection. +To connect to an SSL HTTP server and get the default page the command +.Bd -literal -offset indent +$ openssl s_time -connect servername:443 -www / -CApath yourdir \e + -CAfile yourfile.pem -cipher commoncipher +.Ed +.Pp +would typically be used +.Pq HTTPS uses port 443 . +.Dq commoncipher +is a cipher to which both client and server can agree; +see the +.Nm ciphers +command for details. +.Pp +If the handshake fails, there are several possible causes: +if it is nothing obvious like no client certificate, the +.Fl bugs +option can be tried in case it is a buggy server. +.Pp +A frequent problem when attempting to get client certificates working +is that a web client complains it has no certificates or gives an empty +list to choose from. +This is normally because the server is not sending +the clients certificate authority in its +.Qq acceptable CA list +when it requests a certificate. +By using +.Nm s_client , +the CA list can be viewed and checked. +However some servers only request client authentication +after a specific URL is requested. +To obtain the list in this case, it is necessary to use the +.Fl prexit +option of +.Nm s_client +and send an HTTP request for an appropriate page. +.Pp +If a certificate is specified on the command line using the +.Fl cert +option, +it will not be used unless the server specifically requests +a client certificate. +Therefore merely including a client certificate +on the command line is no guarantee that the certificate works. +.Sh S_TIME BUGS +Because this program does not have all the options of the +.Nm s_client +program to turn protocols on and off, +you may not be able to measure the performance +of all protocols with all servers. +.Pp +The +.Fl verify +option should really exit if the server verification fails. +.\" +.\" SESS_ID +.\" +.Sh SESS_ID +.nr nS 1 +.Nm "openssl sess_id" +.Bk -words +.Op Fl cert +.Op Fl context Ar ID +.Op Fl in Ar file +.Op Fl inform Ar DER | PEM +.Op Fl noout +.Op Fl out Ar file +.Op Fl outform Ar DER | PEM +.Op Fl text +.Ek +.nr nS 0 +.Pp +The +.Nm sess_id +program processes the encoded version of the SSL session structure and +optionally prints out SSL session details +.Pq for example the SSL session master key +in human readable format. +Since this is a diagnostic tool that needs some knowledge of the SSL +protocol to use properly, most users will not need to use it. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl cert +If a certificate is present in the session, +it will be output using this option; +if the +.Fl text +option is also present, then it will be printed out in text form. +.It Fl context Ar ID +This option can set the session ID so the output session information uses the +supplied +.Ar ID . +The +.Ar ID +can be any string of characters. +This option won't normally be used. +.It Fl in Ar file +This specifies the input +.Ar file +to read session information from, or standard input by default. +.It Fl inform Ar DER | PEM +This specifies the input format. +The +.Ar DER +argument uses an ASN1 DER-encoded +format containing session details. +The precise format can vary from one version to the next. +The +.Ar PEM +form is the default format: it consists of the DER +format base64-encoded with additional header and footer lines. +.It Fl noout +This option prevents output of the encoded version of the session. +.It Fl out Ar file +This specifies the output +.Ar file +to write session information to, or standard +output if this option is not specified. +.It Fl outform Ar DER | PEM +This specifies the output format; the options have the same meaning as the +.Fl inform +option. +.It Fl text +Prints out the various public or private key components in +plain text in addition to the encoded version. +.El +.Sh SESS_ID OUTPUT +Typical output: +.Bd -literal +SSL-Session: + Protocol : TLSv1 + Cipher : 0016 + Session-ID: 871E62626C554CE95488823752CBD5F3673A3EF3DCE9C67BD916C809914B40ED + Session-ID-ctx: 01000000 + Master-Key: A7CEFC571974BE02CAC305269DC59F76EA9F0B180CB6642697A68251F2D2BB57E51DBBB4C7885573192AE9AEE220FACD + Key-Arg : None + Start Time: 948459261 + Timeout : 300 (sec) + Verify return code 0 (ok) +.Ed +.Pp +These are described below in more detail. +.Pp +.Bl -tag -width "Verify return code " -compact +.It Ar Protocol +This is the protocol in use. +.It Ar Cipher +The cipher used is the actual raw SSL or TLS cipher code; +see the SSL or TLS specifications for more information. +.It Ar Session-ID +The SSL session ID in hex format. +.It Ar Session-ID-ctx +The session ID context in hex format. +.It Ar Master-Key +This is the SSL session master key. +.It Ar Key-Arg +The key argument; this is only used in SSL v2. +.It Ar Start Time +This is the session start time, represented as an integer in standard +.Ux +format. +.It Ar Timeout +The timeout in seconds. +.It Ar Verify return code +This is the return code when an SSL client certificate is verified. +.El +.Sh SESS_ID NOTES +The PEM-encoded session format uses the header and footer lines: +.Bd -unfilled -offset indent +-----BEGIN SSL SESSION PARAMETERS----- +-----END SSL SESSION PARAMETERS----- +.Ed +.Pp +Since the SSL session output contains the master key, it is possible to read +the contents of an encrypted session using this information. +Therefore appropriate security precautions +should be taken if the information is being output by a +.Qq real +application. +This is, however, strongly discouraged and should only be used for +debugging purposes. +.Sh SESS_ID BUGS +The cipher and start time should be printed out in human readable form. +.\" +.\" SMIME +.\" +.Sh SMIME +.nr nS 1 +.Nm "openssl smime" +.Bk -words +.Oo +.Fl aes128 | aes192 | aes256 | des | +.Fl des3 | rc2-40 | rc2-64 | rc2-128 +.Oc +.Op Fl binary +.Op Fl CAfile Ar file +.Op Fl CApath Ar directory +.Op Fl certfile Ar file +.Op Fl check_ss_sig +.Op Fl content Ar file +.Op Fl crl_check +.Op Fl crl_check_all +.Op Fl decrypt +.Op Fl encrypt +.Op Fl extended_crl +.Op Fl from Ar addr +.Op Fl ignore_critical +.Op Fl in Ar file +.Op Fl indef +.Op Fl inform Ar DER | PEM | SMIME +.Op Fl inkey Ar file +.Op Fl issuer_checks +.Op Fl keyform Ar PEM +.Op Fl md Ar digest +.Op Fl noattr +.Op Fl nocerts +.Op Fl nochain +.Op Fl nodetach +.Op Fl noindef +.Op Fl nointern +.Op Fl nosigs +.Op Fl noverify +.Op Fl out Ar file +.Op Fl outform Ar DER | PEM | SMIME +.Op Fl passin Ar arg +.Op Fl pk7out +.Op Fl policy_check +.Op Fl recip Ar file +.Op Fl resign +.Op Fl sign +.Op Fl signer Ar file +.Op Fl stream +.Op Fl subject Ar s +.Op Fl text +.Op Fl to Ar addr +.Op Fl verify +.Op Fl x509_strict +.Op Ar cert.pem ... +.Ek +.nr nS 0 +.Pp +The +.Nm smime +command handles +.Em S/MIME +mail. +It can encrypt, decrypt, sign, and verify +.Em S/MIME +messages. +.Pp +There are six operation options that set the type of operation to be performed. +The meaning of the other options varies according to the operation type. +.Pp +The six operation options are as follows: +.Bl -tag -width "XXXX" +.It Fl decrypt +Decrypt mail using the supplied certificate and private key. +Expects an encrypted mail message in +.Em MIME +format for the input file. +The decrypted mail is written to the output file. +.It Fl encrypt +Encrypt mail for the given recipient certificates. +Input file is the message to be encrypted. +The output file is the encrypted mail in +.Em MIME +format. +.It Fl pk7out +Takes an input message and writes out a PEM-encoded PKCS#7 structure. +.It Fl resign +Resign a message: take an existing message and one or more new signers. +.It Fl sign +Sign mail using the supplied certificate and private key. +Input file is the message to be signed. +The signed message in +.Em MIME +format is written to the output file. +.It Fl verify +Verify signed mail. +Expects a signed mail message on input and outputs the signed data. +Both clear text and opaque signing is supported. +.El +.Pp +The remaining options are as follows: +.Bl -tag -width "XXXX" +.It Xo +.Fl aes128 | aes192 | aes256 | des | +.Fl des3 | rc2-40 | rc2-64 | rc2-128 +.Xc +The encryption algorithm to use. +128-, 192-, or 256-bit AES, +DES +.Pq 56 bits , +triple DES +.Pq 168 bits , +or 40-, 64-, or 128-bit RC2, respectively; +if not specified, 40-bit RC2 is +used. +Only used with +.Fl encrypt . +.It Fl binary +Normally, the input message is converted to +.Qq canonical +format which is effectively using CR and LF as end of line \- +as required by the +.Em S/MIME +specification. +When this option is present no translation occurs. +This is useful when handling binary data which may not be in +.Em MIME +format. +.It Fl CAfile Ar file +A +.Ar file +containing trusted CA certificates; only used with +.Fl verify . +.It Fl CApath Ar directory +A +.Ar directory +containing trusted CA certificates; only used with +.Fl verify . +This directory must be a standard certificate directory: +that is, a hash of each subject name (using +.Nm x509 -hash ) +should be linked to each certificate. +.It Ar cert.pem ... +One or more certificates of message recipients: used when encrypting +a message. +.It Fl certfile Ar file +Allows additional certificates to be specified. +When signing, these will be included with the message. +When verifying, these will be searched for the signers' certificates. +The certificates should be in PEM format. +.It Xo +.Fl check_ss_sig , +.Fl crl_check , +.Fl crl_check_all , +.Fl extended_crl , +.Fl ignore_critical , +.Fl issuer_checks , +.Fl policy_check , +.Fl x509_strict +.Xc +Set various certificate chain validation options. +See the +.Nm VERIFY +command for details. +.It Fl content Ar file +This specifies a file containing the detached content. +This is only useful with the +.Fl verify +command. +This is only usable if the PKCS#7 structure is using the detached +signature form where the content is not included. +This option will override any content if the input format is +.Em S/MIME +and it uses the multipart/signed +.Em MIME +content type. +.It Xo +.Fl from Ar addr , +.Fl subject Ar s , +.Fl to Ar addr +.Xc +The relevant mail headers. +These are included outside the signed +portion of a message so they may be included manually. +When signing, many +.Em S/MIME +mail clients check that the signer's certificate email +address matches the From: address. +.It Fl in Ar file +The input message to be encrypted or signed or the +.Em MIME +message to +be decrypted or verified. +.It Fl indef +Enable streaming I/O for encoding operations. +This permits single pass processing of data without +the need to hold the entire contents in memory, +potentially supporting very large files. +Streaming is automatically set for S/MIME signing with detached +data if the output format is SMIME; +it is currently off by default for all other operations. +.It Fl inform Ar DER | PEM | SMIME +This specifies the input format for the PKCS#7 structure. +The default is +.Em SMIME , +which reads an +.Em S/MIME +format message. +.Ar PEM +and +.Ar DER +format change this to expect PEM and DER format PKCS#7 structures +instead. +This currently only affects the input format of the PKCS#7 +structure; if no PKCS#7 structure is being input (for example with +.Fl encrypt +or +.Fl sign ) , +this option has no effect. +.It Fl inkey Ar file +The private key to use when signing or decrypting. +This must match the corresponding certificate. +If this option is not specified, the private key must be included +in the certificate file specified with +the +.Fl recip +or +.Fl signer +file. +When signing, +this option can be used multiple times to specify successive keys. +.It Fl keyform Ar PEM +Input private key format. +.It Fl md Ar digest +The digest algorithm to use when signing or resigning. +If not present then the default digest algorithm for the signing key is used +(usually SHA1). +.It Fl noattr +Normally, when a message is signed a set of attributes are included which +include the signing time and supported symmetric algorithms. +With this option they are not included. +.It Fl nocerts +When signing a message, the signer's certificate is normally included; +with this option it is excluded. +This will reduce the size of the signed message but the verifier must +have a copy of the signer's certificate available locally (passed using the +.Fl certfile +option, for example). +.It Fl nochain +Do not do chain verification of signers' certificates: that is, +don't use the certificates in the signed message as untrusted CAs. +.It Fl nodetach +When signing a message use opaque signing: this form is more resistant +to translation by mail relays but it cannot be read by mail agents that +do not support +.Em S/MIME . +Without this option cleartext signing with the +.Em MIME +type multipart/signed is used. +.It Fl noindef +Disable streaming I/O where it would produce an encoding of indefinite length. +This option currently has no effect. +In future streaming will be enabled by default on all relevant operations +and this option will disable it. +.It Fl nointern +When verifying a message, normally certificates +.Pq if any +included in the message are searched for the signing certificate. +With this option, only the certificates specified in the +.Fl certfile +option are used. +The supplied certificates can still be used as untrusted CAs however. +.It Fl nosigs +Don't try to verify the signatures on the message. +.It Fl noverify +Do not verify the signer's certificate of a signed message. +.It Fl out Ar file +The message text that has been decrypted or verified, or the output +.Em MIME +format message that has been signed or verified. +.It Fl outform Ar DER | PEM | SMIME +This specifies the output format for the PKCS#7 structure. +The default is +.Em SMIME , +which writes an +.Em S/MIME +format message. +.Ar PEM +and +.Ar DER +format change this to write PEM and DER format PKCS#7 structures +instead. +This currently only affects the output format of the PKCS#7 +structure; if no PKCS#7 structure is being output (for example with +.Fl verify +or +.Fl decrypt ) +this option has no effect. +.It Fl passin Ar arg +The key password source. +.It Fl recip Ar file +The recipients certificate when decrypting a message. +This certificate +must match one of the recipients of the message or an error occurs. +.It Fl signer Ar file +A signing certificate when signing or resigning a message; +this option can be used multiple times if more than one signer is required. +If a message is being verified, the signer's certificates will be +written to this file if the verification was successful. +.It Fl stream +The same as +.Fl indef . +.It Fl text +This option adds plain text +.Pq text/plain +.Em MIME +headers to the supplied message if encrypting or signing. +If decrypting or verifying, it strips off text headers: +if the decrypted or verified message is not of +.Em MIME +type text/plain then an error occurs. +.El +.Sh SMIME NOTES +The +.Em MIME +message must be sent without any blank lines between the +headers and the output. +Some mail programs will automatically add a blank line. +Piping the mail directly to an MTA is one way to +achieve the correct format. +.Pp +The supplied message to be signed or encrypted must include the +necessary +.Em MIME +headers or many +.Em S/MIME +clients won't display it properly +.Pq if at all . +You can use the +.Fl text +option to automatically add plain text headers. +.Pp +A +.Qq signed and encrypted +message is one where a signed message is then encrypted. +This can be produced by encrypting an already signed message: +see the +.Sx SMIME EXAMPLES +section. +.Pp +This version of the program only allows one signer per message, but it +will verify multiple signers on received messages. +Some +.Em S/MIME +clients choke if a message contains multiple signers. +It is possible to sign messages +.Qq in parallel +by signing an already signed message. +.Pp +The options +.Fl encrypt +and +.Fl decrypt +reflect common usage in +.Em S/MIME +clients. +Strictly speaking these process PKCS#7 enveloped data: PKCS#7 +encrypted data is used for other purposes. +.Pp +The +.Fl resign +option uses an existing message digest when adding a new signer. +This means that attributes must be present in at least one existing +signer using the same message digest or this operation will fail. +.Pp +The +.Fl stream +and +.Fl indef +options enable experimental streaming I/O support. +As a result the encoding is BER using indefinite length constructed encoding +and no longer DER. +Streaming is supported for the +.Fl encrypt +and +.Fl sign +operations if the content is not detached. +.Pp +Streaming is always used for the +.Fl sign +operation with detached data +but since the content is no longer part of the PKCS#7 structure +the encoding remains DER. +.Sh SMIME EXIT CODES +.Bl -tag -width "XXXX" +.It Ar 0 +The operation was completely successful. +.It Ar 1 +An error occurred parsing the command options. +.It Ar 2 +One of the input files could not be read. +.It Ar 3 +An error occurred creating the PKCS#7 file or when reading the +.Em MIME +message. +.It Ar 4 +An error occurred decrypting or verifying the message. +.It Ar 5 +The message was verified correctly, but an error occurred writing out +the signer's certificates. +.El +.Sh SMIME EXAMPLES +Create a cleartext signed message: +.Bd -literal -offset indent +$ openssl smime -sign -in message.txt -text -out mail.msg \e + -signer mycert.pem +.Ed +.Pp +Create an opaque signed message: +.Bd -literal -offset indent +$ openssl smime -sign -in message.txt -text -out mail.msg \e + -nodetach -signer mycert.pem +.Ed +.Pp +Create a signed message, include some additional certificates and +read the private key from another file: +.Bd -literal -offset indent +$ openssl smime -sign -in in.txt -text -out mail.msg \e + -signer mycert.pem -inkey mykey.pem -certfile mycerts.pem +.Ed +.Pp +Create a signed message with two signers: +.Bd -literal -offset indent +openssl smime -sign -in message.txt -text -out mail.msg \e + -signer mycert.pem -signer othercert.pem +.Ed +.Pp +Send a signed message under +.Ux +directly to +.Xr sendmail 8 , +including headers: +.Bd -literal -offset indent +$ openssl smime -sign -in in.txt -text -signer mycert.pem \e + -from steve@openssl.org -to someone@somewhere \e + -subject "Signed message" | sendmail someone@somewhere +.Ed +.Pp +Verify a message and extract the signer's certificate if successful: +.Bd -literal -offset indent +$ openssl smime -verify -in mail.msg -signer user.pem \e + -out signedtext.txt +.Ed +.Pp +Send encrypted mail using triple DES: +.Bd -literal -offset indent +$ openssl smime -encrypt -in in.txt -from steve@openssl.org \e + -to someone@somewhere -subject "Encrypted message" \e + -des3 -out mail.msg user.pem +.Ed +.Pp +Sign and encrypt mail: +.Bd -literal -offset indent +$ openssl smime -sign -in ml.txt -signer my.pem -text | \e + openssl smime -encrypt -out mail.msg \e + -from steve@openssl.org -to someone@somewhere \e + -subject "Signed and Encrypted message" -des3 user.pem +.Ed +.Pp +.Sy Note : +The encryption command does not include the +.Fl text +option because the message being encrypted already has +.Em MIME +headers. +.Pp +Decrypt mail: +.Bd -literal -offset indent +$ openssl smime -decrypt -in mail.msg -recip mycert.pem \e + -inkey key.pem" +.Ed +.Pp +The output from Netscape form signing is a PKCS#7 structure with the +detached signature format. +You can use this program to verify the signature by line wrapping the +base64-encoded structure and surrounding it with: +.Bd -unfilled -offset indent +-----BEGIN PKCS7----- +-----END PKCS7----- +.Ed +.Pp +and using the command: +.Bd -literal -offset indent +$ openssl smime -verify -inform PEM -in signature.pem \e + -content content.txt +.Ed +.Pp +Alternatively, you can base64 decode the signature and use: +.Bd -literal -offset indent +$ openssl smime -verify -inform DER -in signature.der \e + -content content.txt +.Ed +.Pp +Create an encrypted message using 128-bit AES: +.Bd -literal -offset indent +openssl smime -encrypt -in plain.txt -aes128 \e + -out mail.msg cert.pem +.Ed +.Pp +Add a signer to an existing message: +.Bd -literal -offset indent +openssl smime -resign -in mail.msg -signer newsign.pem \e + -out mail2.msg +.Ed +.Sh SMIME BUGS +The +.Em MIME +parser isn't very clever: it seems to handle most messages that I've thrown +at it, but it may choke on others. +.Pp +The code currently will only write out the signer's certificate to a file: +if the signer has a separate encryption certificate this must be manually +extracted. +There should be some heuristic that determines the correct encryption +certificate. +.Pp +Ideally, a database should be maintained of a certificate for each email +address. +.Pp +The code doesn't currently take note of the permitted symmetric encryption +algorithms as supplied in the +.Em SMIMECapabilities +signed attribute. +This means the user has to manually include the correct encryption algorithm. +It should store the list of permitted ciphers in a database and only use those. +.Pp +No revocation checking is done on the signer's certificate. +.Pp +The current code can only handle +.Em S/MIME +v2 messages; the more complex +.Em S/MIME +v3 structures may cause parsing errors. +.Sh SMIME HISTORY +The use of multiple +.Fl signer +options and the +.Fl resign +command were first added in +.Nm OpenSSL +1.0.0. +.\" +.\" SPEED +.\" +.Sh SPEED +.nr nS 1 +.Nm "openssl speed" +.Bk -words +.Op Cm aes +.Op Cm aes-128-cbc +.Op Cm aes-192-cbc +.Op Cm aes-256-cbc +.Op Cm aes-128-gcm +.Op Cm aes-256-gcm +.Op Cm blowfish +.Op Cm bf-cbc +.Op Cm cast +.Op Cm cast-cbc +.Op Cm chacha20-poly1305 +.Op Cm des +.Op Cm des-cbc +.Op Cm des-ede3 +.Op Cm dsa +.Op Cm dsa512 +.Op Cm dsa1024 +.Op Cm dsa2048 +.Op Cm hmac +.Op Cm md4 +.Op Cm md5 +.Op Cm rc2 +.Op Cm rc2-cbc +.Op Cm rc4 +.Op Cm rmd160 +.Op Cm rsa +.Op Cm rsa512 +.Op Cm rsa1024 +.Op Cm rsa2048 +.Op Cm rsa4096 +.Op Cm sha1 +.Op Fl decrypt +.Op Fl elapsed +.Op Fl evp Ar e +.Op Fl mr +.Op Fl multi Ar number +.Ek +.nr nS 0 +.Pp +The +.Nm speed +command is used to test the performance of cryptographic algorithms. +.Bl -tag -width "XXXX" +.It Bq Cm zero or more test algorithms +If any options are given, +.Nm speed +tests those algorithms, otherwise all of the above are tested. +.It Fl decrypt +Time decryption instead of encryption +.Pq only EVP . +.It Fl elapsed +Measure time in real time instead of CPU user time. +.It Fl evp Ar e +Use EVP +.Ar e . +.It Fl mr +Produce machine readable output. +.It Fl multi Ar number +Run +.Ar number +benchmarks in parallel. +.El +.\" +.\" TS +.\" +.Sh TS +.nr nS 1 +.Nm "openssl ts" +.Bk -words +.Fl query +.Op Fl md4 | md5 | ripemd160 | sha1 +.Op Fl cert +.Op Fl config Ar configfile +.Op Fl data Ar file_to_hash +.Op Fl digest Ar digest_bytes +.Op Fl in Ar request.tsq +.Op Fl no_nonce +.Op Fl out Ar request.tsq +.Op Fl policy Ar object_id +.Op Fl text +.Ek +.nr nS 0 +.Pp +.nr nS 1 +.Nm "openssl ts" +.Bk -words +.Fl reply +.Op Fl chain Ar certs_file.pem +.Op Fl config Ar configfile +.Op Fl in Ar response.tsr +.Op Fl inkey Ar private.pem +.Op Fl out Ar response.tsr +.Op Fl passin Ar arg +.Op Fl policy Ar object_id +.Op Fl queryfile Ar request.tsq +.Op Fl section Ar tsa_section +.Op Fl signer Ar tsa_cert.pem +.Op Fl text +.Op Fl token_in +.Op Fl token_out +.Ek +.nr nS 0 +.Pp +.nr nS 1 +.Nm "openssl ts" +.Bk -words +.Fl verify +.Op Fl CAfile Ar trusted_certs.pem +.Op Fl CApath Ar trusted_cert_path +.Op Fl data Ar file_to_hash +.Op Fl digest Ar digest_bytes +.Op Fl in Ar response.tsr +.Op Fl queryfile Ar request.tsq +.Op Fl token_in +.Op Fl untrusted Ar cert_file.pem +.Ek +.nr nS 0 +.Pp +The +.Nm ts +command is a basic Time Stamping Authority (TSA) client and server +application as specified in RFC 3161 (Time-Stamp Protocol, TSP). +A TSA can be part of a PKI deployment and its role is to provide long +term proof of the existence of a certain datum before a particular time. +Here is a brief description of the protocol: +.Bl -enum +.It +The TSA client computes a one-way hash value for a data file and sends +the hash to the TSA. +.It +The TSA attaches the current date and time to the received hash value, +signs them and sends the time stamp token back to the client. +By creating this token the TSA certifies the existence of the original +data file at the time of response generation. +.It +The TSA client receives the time stamp token and verifies the +signature on it. +It also checks if the token contains the same hash +value that it had sent to the TSA. +.El +.Pp +There is one DER-encoded protocol data unit defined for transporting a time +stamp request to the TSA and one for sending the time stamp response +back to the client. +The +.Nm ts +command has three main functions: +creating a time stamp request based on a data file; +creating a time stamp response based on a request; +and verifying if a response corresponds +to a particular request or a data file. +.Pp +There is no support for sending the requests/responses automatically +over HTTP or TCP yet as suggested in RFC 3161. +Users must send the requests either by FTP or email. +.Pp +The +.Fl query +switch can be used for creating and printing a time stamp +request with the following options: +.Bl -tag -width Ds +.It Fl cert +The TSA is expected to include its signing certificate in the +response. +.It Fl config Ar configfile +The configuration file to use. +This option overrides the +.Ev OPENSSL_CONF +environment variable. +Only the OID section of the config file is used with the +.Fl query +command. +.It Fl data Ar file_to_hash +The data file for which the time stamp request needs to be created. +stdin is the default if neither the +.Fl data +nor the +.Fl digest +option is specified. +.It Fl digest Ar digest_bytes +It is possible to specify the message imprint explicitly without the data +file. +The imprint must be specified in a hexadecimal format, +two characters per byte, +the bytes optionally separated by colons (e.g. 1A:F6:01:... or 1AF601...). +The number of bytes must match the message digest algorithm in use. +.It Fl in Ar request.tsq +This option specifies a previously created time stamp request in DER +format that will be printed into the output file. +Useful when you need to examine the content of a request in human-readable +format. +.It Fl md4|md5|ripemd160|sha|sha1 +The message digest to apply to the data file. +It supports all the message digest algorithms that are supported by the +.Nm dgst +command. +The default is SHA-1. +.It Fl no_nonce +No nonce is specified in the request if this option is given. +Otherwise a 64-bit long pseudo-random none is +included in the request. +It is recommended to use nonce to protect against replay-attacks. +.It Fl out Ar request.tsq +Name of the output file to which the request will be written. +The default is stdout. +.It Fl policy Ar object_id +The policy that the client expects the TSA to use for creating the +time stamp token. +Either the dotted OID notation or OID names defined +in the config file can be used. +If no policy is requested the TSA will +use its own default policy. +.It Fl text +If this option is specified the output is in human-readable text format +instead of DER. +.El +.Pp +A time stamp response (TimeStampResp) consists of a response status +and the time stamp token itself (ContentInfo), +if the token generation was successful. +The +.Fl reply +command is for creating a time stamp +response or time stamp token based on a request and printing the +response/token in human-readable format. +If +.Fl token_out +is not specified the output is always a time stamp response (TimeStampResp), +otherwise it is a time stamp token (ContentInfo). +.Bl -tag -width Ds +.It Fl chain Ar certs_file.pem +The collection of certificates, in PEM format, +that will be included in the response +in addition to the signer certificate if the +.Fl cert +option was used for the request. +This file is supposed to contain the certificate chain +for the signer certificate from its issuer upwards. +The +.Fl reply +command does not build a certificate chain automatically. +.It Fl config Ar configfile +The configuration file to use. +This option overrides the +.Ev OPENSSL_CONF +environment variable. +See +.Sx TS CONFIGURATION FILE OPTIONS +for configurable variables. +.It Fl in Ar response.tsr +Specifies a previously created time stamp response or time stamp token, if +.Fl token_in +is also specified, +in DER format that will be written to the output file. +This option does not require a request; +it is useful, for example, +when you need to examine the content of a response or token +or you want to extract the time stamp token from a response. +If the input is a token and the output is a time stamp response a default +.Dq granted +status info is added to the token. +.It Fl inkey Ar private.pem +The signer private key of the TSA in PEM format. +Overrides the +.Cm signer_key +config file option. +.It Fl out Ar response.tsr +The response is written to this file. +The format and content of the file depends on other options (see +.Fl text +and +.Fl token_out ) . +The default is stdout. +.It Fl passin Ar arg +The key password source. +.It Fl policy Ar object_id +The default policy to use for the response unless the client +explicitly requires a particular TSA policy. +The OID can be specified either in dotted notation or with its name. +Overrides the +.Cm default_policy +config file option. +.It Fl queryfile Ar request.tsq +The name of the file containing a DER-encoded time stamp request. +.It Fl section Ar tsa_section +The name of the config file section containing the settings for the +response generation. +If not specified the default TSA section is used; see +.Sx TS CONFIGURATION FILE OPTIONS +for details. +.It Fl signer Ar tsa_cert.pem +The signer certificate of the TSA in PEM format. +The TSA signing certificate must have exactly one extended key usage +assigned to it: timeStamping. +The extended key usage must also be critical, +otherwise the certificate is going to be refused. +Overrides the +.Cm signer_cert +variable of the config file. +.It Fl text +If this option is specified the output is human-readable text format +instead of DER. +.It Fl token_in +This flag can be used together with the +.Fl in +option and indicates that the input is a DER-encoded time stamp token +(ContentInfo) instead of a time stamp response (TimeStampResp). +.It Fl token_out +The output is a time stamp token (ContentInfo) instead of time stamp +response (TimeStampResp). +.El +.Pp +The +.Fl verify +command is for verifying if a time stamp response or time stamp token +is valid and matches a particular time stamp request or data file. +The +.Fl verify +command does not use the configuration file. +.Bl -tag -width Ds +.It Fl CAfile Ar trusted_certs.pem +The name of the file containing a set of trusted self-signed CA +certificates in PEM format. +See the similar option of +.Nm verify +for additional details. +Either this option or +.Fl CApath +must be specified. +.It Fl CApath Ar trusted_cert_path +The name of the directory containing the trused CA certificates of the +client. +See the similar option of +.Nm verify +for additional details. +Either this option or +.Fl CAfile +must be specified. +.It Fl data Ar file_to_hash +The response or token must be verified against +.Ar file_to_hash . +The file is hashed with the message digest algorithm specified in the token. +The +.Fl digest +and +.Fl queryfile +options must not be specified with this one. +.It Fl digest Ar digest_bytes +The response or token must be verified against the message digest specified +with this option. +The number of bytes must match the message digest algorithm +specified in the token. +The +.Fl data +and +.Fl queryfile +options must not be specified with this one. +.It Fl in Ar response.tsr +The time stamp response that needs to be verified, in DER format. +This option in mandatory. +.It Fl queryfile Ar request.tsq +The original time stamp request, in DER format. +The +.Fl data +and +.Fl digest +options must not be specified with this one. +.It Fl token_in +This flag can be used together with the +.Fl in +option and indicates that the input is a DER-encoded time stamp token +(ContentInfo) instead of a time stamp response (TimeStampResp). +.It Fl untrusted Ar cert_file.pem +Set of additional untrusted certificates in PEM format which may be +needed when building the certificate chain for the TSA's signing +certificate. +This file must contain the TSA signing certificate and +all intermediate CA certificates unless the response includes them. +.El +.Sh TS CONFIGURATION FILE OPTIONS +The +.Fl query +and +.Fl reply +options make use of a configuration file defined by the +.Ev OPENSSL_CONF +environment variable. +The +.Fl query +option uses only the symbolic OID names section +and it can work without it. +However, the +.Fl reply +option needs the config file for its operation. +.Pp +When there is a command line switch equivalent of a variable the +switch always overrides the settings in the config file. +.Bl -tag -width Ds +.It Cm tsa Ar section , Cm default_tsa +This is the main section and it specifies the name of another section +that contains all the options for the +.Fl reply +option. +This default section can be overridden with the +.Fl section +command line switch. +.It Cm oid_file +See +.Nm ca +for a description. +.It Cm oid_section +See +.Nm ca +for a description. +.It Cm serial +The name of the file containing the hexadecimal serial number of the +last time stamp response created. +This number is incremented by 1 for each response. +If the file does not exist at the time of response +generation a new file is created with serial number 1. +This parameter is mandatory. +.It Cm signer_cert +TSA signing certificate, in PEM format. +The same as the +.Fl signer +command line option. +.It Cm certs +A file containing a set of PEM-encoded certificates that need to be +included in the response. +The same as the +.Fl chain +command line option. +.It Cm signer_key +The private key of the TSA, in PEM format. +The same as the +.Fl inkey +command line option. +.It Cm default_policy +The default policy to use when the request does not mandate any policy. +The same as the +.Fl policy +command line option. +.It Cm other_policies +Comma separated list of policies that are also acceptable by the TSA +and used only if the request explicitly specifies one of them. +.It Cm digests +The list of message digest algorithms that the TSA accepts. +At least one algorithm must be specified. +This parameter is mandatory. +.It Cm accuracy +The accuracy of the time source of the TSA in seconds, milliseconds +and microseconds. +For example, secs:1, millisecs:500, microsecs:100. +If any of the components is missing, +zero is assumed for that field. +.It Cm clock_precision_digits +Specifies the maximum number of digits, which represent the fraction of +seconds, that need to be included in the time field. +The trailing zeroes must be removed from the time, +so there might actually be fewer digits, +or no fraction of seconds at all. +The maximum value is 6; +the default is 0. +.It Cm ordering +If this option is yes, +the responses generated by this TSA can always be ordered, +even if the time difference between two responses is less +than the sum of their accuracies. +The default is no. +.It Cm tsa_name +Set this option to yes if the subject name of the TSA must be included in +the TSA name field of the response. +The default is no. +.It Cm ess_cert_id_chain +The SignedData objects created by the TSA always contain the +certificate identifier of the signing certificate in a signed +attribute (see RFC 2634, Enhanced Security Services). +If this option is set to yes and either the +.Cm certs +variable or the +.Fl chain +option is specified then the certificate identifiers of the chain will also +be included in the SigningCertificate signed attribute. +If this variable is set to no, +only the signing certificate identifier is included. +The default is no. +.El +.Sh TS ENVIRONMENT VARIABLES +.Ev OPENSSL_CONF +contains the path of the configuration file and can be +overridden by the +.Fl config +command line option. +.Sh TS EXAMPLES +All the examples below presume that +.Ev OPENSSL_CONF +is set to a proper configuration file, +e.g. the example configuration file +.Pa openssl/apps/openssl.cnf +will do. +.Pp +To create a time stamp request for design1.txt with SHA-1 +without nonce and policy and no certificate is required in the response: +.Bd -literal -offset indent +$ openssl ts -query -data design1.txt -no_nonce \e + -out design1.tsq +.Ed +.Pp +To create a similar time stamp request but specifying the message imprint +explicitly: +.Bd -literal -offset indent +$ openssl ts -query \e + -digest b7e5d3f93198b38379852f2c04e78d73abdd0f4b \e + -no_nonce -out design1.tsq +.Ed +.Pp +To print the content of the previous request in human readable format: +.Bd -literal -offset indent +$ openssl ts -query -in design1.tsq -text +.Ed +.Pp +To create a time stamp request which includes the MD5 digest +of design2.txt, requests the signer certificate and nonce, +specifies a policy ID +(assuming the tsa_policy1 name is defined in the +OID section of the config file): +.Bd -literal -offset indent +$ openssl ts -query -data design2.txt -md5 \e + -policy tsa_policy1 -cert -out design2.tsq +.Ed +.Pp +Before generating a response, +a signing certificate must be created for the TSA that contains the +.Cm timeStamping +critical extended key usage extension +without any other key usage extensions. +You can add the +.Dq extendedKeyUsage = critical,timeStamping +line to the user certificate section +of the config file to generate a proper certificate. +See the +.Nm req , +.Nm ca , +and +.Nm x509 +commands for instructions. +The examples below assume that cacert.pem contains the certificate of the CA, +tsacert.pem is the signing certificate issued by cacert.pem and +tsakey.pem is the private key of the TSA. +.Pp +To create a time stamp response for a request: +.Bd -literal -offset indent +$ openssl ts -reply -queryfile design1.tsq -inkey tsakey.pem \e + -signer tsacert.pem -out design1.tsr +.Ed +.Pp +If you want to use the settings in the config file you could just write: +.Bd -literal -offset indent +$ openssl ts -reply -queryfile design1.tsq -out design1.tsr +.Ed +.Pp +To print a time stamp reply to stdout in human readable format: +.Bd -literal -offset indent +$ openssl ts -reply -in design1.tsr -text +.Ed +.Pp +To create a time stamp token instead of time stamp response: +.Bd -literal -offset indent +$ openssl ts -reply -queryfile design1.tsq \e + -out design1_token.der -token_out +.Ed +.Pp +To print a time stamp token to stdout in human readable format: +.Bd -literal -offset indent +$ openssl ts -reply -in design1_token.der -token_in \e + -text -token_out +.Ed +.Pp +To extract the time stamp token from a response: +.Bd -literal -offset indent +$ openssl ts -reply -in design1.tsr -out design1_token.der \e + -token_out +.Ed +.Pp +To add +.Dq granted +status info to a time stamp token thereby creating a valid response: +.Bd -literal -offset indent +$ openssl ts -reply -in design1_token.der \e + -token_in -out design1.tsr +.Ed +.Pp +To verify a time stamp reply against a request: +.Bd -literal -offset indent +$ openssl ts -verify -queryfile design1.tsq -in design1.tsr \e + -CAfile cacert.pem -untrusted tsacert.pem +.Ed +.Pp +To verify a time stamp reply that includes the certificate chain: +.Bd -literal -offset indent +$ openssl ts -verify -queryfile design2.tsq -in design2.tsr \e + -CAfile cacert.pem +.Ed +.Pp +To verify a time stamp token against the original data file: +.Bd -literal -offset indent +$ openssl ts -verify -data design2.txt -in design2.tsr \e + -CAfile cacert.pem +.Ed +.Pp +To verify a time stamp token against a message imprint: +.Bd -literal -offset indent +$ openssl ts -verify \e + -digest b7e5d3f93198b38379852f2c04e78d73abdd0f4b \e + -in design2.tsr -CAfile cacert.pem +.Ed +.Sh TS BUGS +No support for time stamps over SMTP, though it is quite easy +to implement an automatic email-based TSA with +.Xr procmail +and +.Xr perl 1 . +Pure TCP/IP is not supported. +.Pp +The file containing the last serial number of the TSA is not +locked when being read or written. +This is a problem if more than one instance of +.Nm OpenSSL +is trying to create a time stamp +response at the same time. +.Pp +Look for the FIXME word in the source files. +.Pp +The source code should really be reviewed by somebody else, too. +.Pp +More testing is needed. +.Sh TS AUTHORS +.An Zoltan Glozik Aq Mt zglozik@opentsa.org , +OpenTSA project +.Pq Lk http://www.opentsa.org . +.\" +.\" SPKAC +.\" +.Sh SPKAC +.nr nS 1 +.Nm "openssl spkac" +.Bk -words +.Op Fl challenge Ar string +.Op Fl in Ar file +.Op Fl key Ar keyfile +.Op Fl noout +.Op Fl out Ar file +.Op Fl passin Ar arg +.Op Fl pubkey +.Op Fl spkac Ar spkacname +.Op Fl spksect Ar section +.Op Fl verify +.Ek +.nr nS 0 +.Pp +The +.Nm spkac +command processes Netscape signed public key and challenge +.Pq SPKAC +files. +It can print out their contents, verify the signature, +and produce its own SPKACs from a supplied private key. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl challenge Ar string +Specifies the challenge string if an SPKAC is being created. +.It Fl in Ar file +This specifies the input +.Ar file +to read from, or standard input if this option is not specified. +Ignored if the +.Fl key +option is used. +.It Fl key Ar keyfile +Create an SPKAC file using the private key in +.Ar keyfile . +The +.Fl in , noout , spksect , +and +.Fl verify +options are ignored if present. +.It Fl noout +Don't output the text version of the SPKAC +.Pq not used if an SPKAC is being created . +.It Fl out Ar file +Specifies the output +.Ar file +to write to, or standard output by default. +.It Fl passin Ar arg +The key password source. +.It Fl pubkey +Output the public key of an SPKAC +.Pq not used if an SPKAC is being created . +.It Fl spkac Ar spkacname +Allows an alternative name for the variable containing the SPKAC. +The default is "SPKAC". +This option affects both generated and input SPKAC files. +.It Fl spksect Ar section +Allows an alternative name for the +.Ar section +containing the SPKAC. +The default is the default section. +.It Fl verify +Verifies the digital signature on the supplied SPKAC. +.El +.Sh SPKAC EXAMPLES +Print out the contents of an SPKAC: +.Pp +.Dl $ openssl spkac -in spkac.cnf +.Pp +Verify the signature of an SPKAC: +.Pp +.Dl $ openssl spkac -in spkac.cnf -noout -verify +.Pp +Create an SPKAC using the challenge string +.Qq hello : +.Pp +.Dl $ openssl spkac -key key.pem -challenge hello -out spkac.cnf +.Pp +Example of an SPKAC, +.Pq long lines split up for clarity : +.Bd -unfilled -offset indent +SPKAC=MIG5MGUwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA1cCoq2Wa3Ixs47uI7F\e +PVwHVIPDx5yso105Y6zpozam135a8R0CpoRvkkigIyXfcCjiVi5oWk+6FfPaD03u\e +PFoQIDAQABFgVoZWxsbzANBgkqhkiG9w0BAQQFAANBAFpQtY/FojdwkJh1bEIYuc\e +2EeM2KHTWPEepWYeawvHD0gQ3DngSC75YCWnnDdq+NQ3F+X4deMx9AaEglZtULwV\e +4= +.Ed +.Sh SPKAC NOTES +A created SPKAC with suitable DN components appended can be fed into +the +.Nm ca +utility. +.Pp +SPKACs are typically generated by Netscape when a form is submitted +containing the +.Em KEYGEN +tag as part of the certificate enrollment process. +.Pp +The challenge string permits a primitive form of proof of possession +of private key. +By checking the SPKAC signature and a random challenge +string, some guarantee is given that the user knows the private key +corresponding to the public key being certified. +This is important in some applications. +Without this it is possible for a previous SPKAC +to be used in a +.Qq replay attack . +.\" +.\" VERIFY +.\" +.Sh VERIFY +.nr nS 1 +.Nm "openssl verify" +.Bk -words +.Op Fl CAfile Ar file +.Op Fl CApath Ar directory +.Op Fl check_ss_sig +.Op Fl crl_check +.Op Fl crl_check_all +.Op Fl explicit_policy +.Op Fl extended_crl +.Op Fl help +.Op Fl ignore_critical +.Op Fl inhibit_any +.Op Fl inhibit_map +.Op Fl issuer_checks +.Op Fl policy_check +.Op Fl purpose Ar purpose +.Op Fl untrusted Ar file +.Op Fl verbose +.Op Fl x509_strict +.Op Fl +.Op Ar certificates +.Ek +.nr nS 0 +.Pp +The +.Nm verify +command verifies certificate chains. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl check_ss_sig +Verify the signature on the self-signed root CA. +This is disabled by default +because it doesn't add any security. +.It Fl CAfile Ar file +A +.Ar file +of trusted certificates. +The +.Ar file +should contain multiple certificates in PEM format, concatenated together. +.It Fl CApath Ar directory +A +.Ar directory +of trusted certificates. +The certificates should have names of the form +.Em hash.0 , +or have symbolic links to them of this form +("hash" is the hashed certificate subject name: see the +.Fl hash +option of the +.Nm x509 +utility). +The +.Nm c_rehash +script distributed with OpenSSL +will automatically create symbolic links to a directory of certificates. +.It Fl crl_check +Checks end entity certificate validity by attempting to look up a valid CRL. +If a valid CRL cannot be found an error occurs. +.It Fl crl_check_all +Checks the validity of all certificates in the chain by attempting +to look up valid CRLs. +.It Fl explicit_policy +Set policy variable require-explicit-policy (see RFC 3280 et al). +.It Fl extended_crl +Enable extended CRL features such as indirect CRLs and alternate CRL +signing keys. +.It Fl help +Prints out a usage message. +.It Fl ignore_critical +Normally if an unhandled critical extension is present which is not +supported by +.Nm OpenSSL , +the certificate is rejected (as required by RFC 3280 et al). +If this option is set, critical extensions are ignored. +.It Fl inhibit_any +Set policy variable inhibit-any-policy (see RFC 3280 et al). +.It Fl inhibit_map +Set policy variable inhibit-policy-mapping (see RFC 3280 et al). +.It Fl issuer_checks +Print out diagnostics relating to searches for the issuer certificate +of the current certificate. +This shows why each candidate issuer certificate was rejected. +However the presence of rejection messages +does not itself imply that anything is wrong: during the normal +verify process several rejections may take place. +.It Fl policy_check +Enables certificate policy processing. +.It Fl purpose Ar purpose +The intended use for the certificate. +Without this option no chain verification will be done. +Currently accepted uses are +.Ar sslclient , sslserver , +.Ar nssslserver , smimesign , +.Ar smimeencrypt , crlsign , +.Ar any , +and +.Ar ocsphelper . +See the +.Sx VERIFY OPERATION +section for more information. +.It Fl untrusted Ar file +A +.Ar file +of untrusted certificates. +The +.Ar file +should contain multiple certificates. +.It Fl verbose +Print extra information about the operations being performed. +.It Fl x509_strict +Disable workarounds for broken certificates which have to be disabled +for strict X.509 compliance. +.It Fl +Marks the last option. +All arguments following this are assumed to be certificate files. +This is useful if the first certificate filename begins with a +.Sq - . +.It Ar certificates +One or more +.Ar certificates +to verify. +If no certificate files are included, an attempt is made to read +a certificate from standard input. +They should all be in PEM format. +.El +.Sh VERIFY OPERATION +The +.Nm verify +program uses the same functions as the internal SSL and S/MIME verification, +therefore this description applies to these verify operations too. +.Pp +There is one crucial difference between the verify operations performed +by the +.Nm verify +program: wherever possible an attempt is made to continue +after an error, whereas normally the verify operation would halt on the +first error. +This allows all the problems with a certificate chain to be determined. +.Pp +The verify operation consists of a number of separate steps: +.Pp +Firstly a certificate chain is built up starting from the supplied certificate +and ending in the root CA. +It is an error if the whole chain cannot be built up. +The chain is built up by looking up the issuer's certificate of the current +certificate. +If a certificate is found which is its own issuer, it is assumed +to be the root CA. +.Pp +The process of +.Qq looking up the issuer's certificate +itself involves a number of steps. +In versions of +.Nm OpenSSL +before 0.9.5a the first certificate whose subject name matched the issuer +of the current certificate was assumed to be the issuer's certificate. +In +.Nm OpenSSL +0.9.6 and later all certificates whose subject name matches the issuer name +of the current certificate are subject to further tests. +The relevant authority key identifier components of the current certificate +.Pq if present +must match the subject key identifier +.Pq if present +and issuer and serial number of the candidate issuer; in addition the +.Em keyUsage +extension of the candidate issuer +.Pq if present +must permit certificate signing. +.Pp +The lookup first looks in the list of untrusted certificates and if no match +is found the remaining lookups are from the trusted certificates. +The root CA is always looked up in the trusted certificate list: if the +certificate to verify is a root certificate, then an exact match must be +found in the trusted list. +.Pp +The second operation is to check every untrusted certificate's extensions for +consistency with the supplied purpose. +If the +.Fl purpose +option is not included, then no checks are done. +The supplied or +.Qq leaf +certificate must have extensions compatible with the supplied purpose +and all other certificates must also be valid CA certificates. +The precise extensions required are described in more detail in +the +.Sx X.509 CERTIFICATE EXTENSIONS +section below. +.Pp +The third operation is to check the trust settings on the root CA. +The root CA should be trusted for the supplied purpose. +For compatibility with previous versions of +.Nm SSLeay +and +.Nm OpenSSL , +a certificate with no trust settings is considered to be valid for +all purposes. +.Pp +The final operation is to check the validity of the certificate chain. +The validity period is checked against the current system time and the +.Em notBefore +and +.Em notAfter +dates in the certificate. +The certificate signatures are also checked at this point. +.Pp +If all operations complete successfully, the certificate is considered +valid. +If any operation fails then the certificate is not valid. +.Sh VERIFY DIAGNOSTICS +When a verify operation fails, the output messages can be somewhat cryptic. +The general form of the error message is: +.Bd -unfilled +\& server.pem: /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024-bit) +\& error 24 at 1 depth lookup:invalid CA certificate +.Ed +.Pp +The first line contains the name of the certificate being verified, followed by +the subject name of the certificate. +The second line contains the error number and the depth. +The depth is the number of the certificate being verified when a +problem was detected starting with zero for the certificate being verified +itself, then 1 for the CA that signed the certificate and so on. +Finally a text version of the error number is presented. +.Pp +An exhaustive list of the error codes and messages is shown below; this also +includes the name of the error code as defined in the header file +.In openssl/x509_vfy.h . +Some of the error codes are defined but never returned: these are described +as +.Qq unused . +.Bl -tag -width "XXXX" +.It Ar "0 X509_V_OK: ok" +The operation was successful. +.It Ar 2 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: unable to get issuer certificate +The issuer certificate could not be found: this occurs if the issuer certificate +of an untrusted certificate cannot be found. +.It Ar 3 X509_V_ERR_UNABLE_TO_GET_CRL: unable to get certificate CRL +The CRL of a certificate could not be found. +.It Ar 4 X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: unable to decrypt certificate's signature +The certificate signature could not be decrypted. +This means that the actual signature value could not be determined rather +than it not matching the expected value. +This is only meaningful for RSA keys. +.It Ar 5 X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: unable to decrypt CRL's signature +The CRL signature could not be decrypted: this means that the actual +signature value could not be determined rather than it not matching the +expected value. +Unused. +.It Ar 6 X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: unable to decode issuer public key +The public key in the certificate +.Em SubjectPublicKeyInfo +could not be read. +.It Ar 7 X509_V_ERR_CERT_SIGNATURE_FAILURE: certificate signature failure +The signature of the certificate is invalid. +.It Ar 8 X509_V_ERR_CRL_SIGNATURE_FAILURE: CRL signature failure +The signature of the certificate is invalid. +.It Ar 9 X509_V_ERR_CERT_NOT_YET_VALID: certificate is not yet valid +The certificate is not yet valid: the +.Em notBefore +date is after the current time. +.It Ar 10 X509_V_ERR_CERT_HAS_EXPIRED: certificate has expired +The certificate has expired; that is, the +.Em notAfter +date is before the current time. +.It Ar 11 X509_V_ERR_CRL_NOT_YET_VALID: CRL is not yet valid +The CRL is not yet valid. +.It Ar 12 X509_V_ERR_CRL_HAS_EXPIRED: CRL has expired +The CRL has expired. +.It Ar 13 X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: format error in certificate's notBefore field +The certificate +.Em notBefore +field contains an invalid time. +.It Ar 14 X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: format error in certificate's notAfter field +The certificate +.Em notAfter +field contains an invalid time. +.It Ar 15 X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: format error in CRL's lastUpdate field +The CRL +.Em lastUpdate +field contains an invalid time. +.It Ar 16 X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: format error in CRL's nextUpdate field +The CRL +.Em nextUpdate +field contains an invalid time. +.It Ar 17 X509_V_ERR_OUT_OF_MEM: out of memory +An error occurred trying to allocate memory. +This should never happen. +.It Ar 18 X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: self signed certificate +The passed certificate is self-signed and the same certificate cannot be +found in the list of trusted certificates. +.It Ar 19 X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: self signed certificate in certificate chain +The certificate chain could be built up using the untrusted certificates but +the root could not be found locally. +.It Ar 20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate +The issuer certificate of a locally looked up certificate could not be found. +This normally means the list of trusted certificates is not complete. +.It Ar 21 X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: unable to verify the first certificate +No signatures could be verified because the chain contains only one +certificate and it is not self-signed. +.It Ar 22 X509_V_ERR_CERT_CHAIN_TOO_LONG: certificate chain too long +The certificate chain length is greater than the supplied maximum depth. +Unused. +.It Ar 23 X509_V_ERR_CERT_REVOKED: certificate revoked +The certificate has been revoked. +.It Ar 24 X509_V_ERR_INVALID_CA: invalid CA certificate +A CA certificate is invalid. +Either it is not a CA or its extensions are not consistent +with the supplied purpose. +.It Ar 25 X509_V_ERR_PATH_LENGTH_EXCEEDED: path length constraint exceeded +The +.Em basicConstraints +pathlength parameter has been exceeded. +.It Ar 26 X509_V_ERR_INVALID_PURPOSE: unsupported certificate purpose +The supplied certificate cannot be used for the specified purpose. +.It Ar 27 X509_V_ERR_CERT_UNTRUSTED: certificate not trusted +The root CA is not marked as trusted for the specified purpose. +.It Ar 28 X509_V_ERR_CERT_REJECTED: certificate rejected +The root CA is marked to reject the specified purpose. +.It Ar 29 X509_V_ERR_SUBJECT_ISSUER_MISMATCH: subject issuer mismatch +The current candidate issuer certificate was rejected because its subject name +did not match the issuer name of the current certificate. +Only displayed when the +.Fl issuer_checks +option is set. +.It Ar 30 X509_V_ERR_AKID_SKID_MISMATCH: authority and subject key identifier mismatch +The current candidate issuer certificate was rejected because its subject key +identifier was present and did not match the authority key identifier current +certificate. +Only displayed when the +.Fl issuer_checks +option is set. +.It Ar 31 X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: authority and issuer serial number mismatch +The current candidate issuer certificate was rejected because its issuer name +and serial number were present and did not match the authority key identifier +of the current certificate. +Only displayed when the +.Fl issuer_checks +option is set. +.It Ar 32 X509_V_ERR_KEYUSAGE_NO_CERTSIGN:key usage does not include certificate signing +The current candidate issuer certificate was rejected because its +.Em keyUsage +extension does not permit certificate signing. +.It Ar 50 X509_V_ERR_APPLICATION_VERIFICATION: application verification failure +An application specific error. +Unused. +.El +.Sh VERIFY BUGS +Although the issuer checks are a considerable improvement over the old +technique, they still suffer from limitations in the underlying +X509_LOOKUP API. +One consequence of this is that trusted certificates with matching subject +name must either appear in a file (as specified by the +.Fl CAfile +option) or a directory (as specified by +.Fl CApath ) . +If they occur in both, only the certificates in the file will +be recognised. +.Pp +Previous versions of +.Nm OpenSSL +assumed certificates with matching subject name were identical and +mishandled them. +.\" +.\" VERSION +.\" +.Sh VERSION +.Nm openssl version +.Op Fl abdfopv +.Pp +The +.Nm version +command is used to print out version information about +.Nm OpenSSL . +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl a +All information: this is the same as setting all the other flags. +.It Fl b +The date the current version of +.Nm OpenSSL +was built. +.It Fl d +.Ev OPENSSLDIR +setting. +.It Fl f +Compilation flags. +.It Fl o +Option information: various options set when the library was built. +.It Fl p +Platform setting. +.It Fl v +The current +.Nm OpenSSL +version. +.El +.Sh VERSION NOTES +The output of +.Nm openssl version -a +would typically be used when sending in a bug report. +.Sh VERSION HISTORY +The +.Fl d +option was added in +.Nm OpenSSL +0.9.7. +.\" +.\" X509 +.\" +.Sh X509 +.nr nS 1 +.Nm "openssl x509" +.Bk -words +.Op Fl C +.Op Fl addreject Ar arg +.Op Fl addtrust Ar arg +.Op Fl alias +.Op Fl CA Ar file +.Op Fl CAcreateserial +.Op Fl CAform Ar DER | PEM +.Op Fl CAkey Ar file +.Op Fl CAkeyform Ar DER | PEM +.Op Fl CAserial Ar file +.Op Fl certopt Ar option +.Op Fl checkend Ar arg +.Op Fl clrext +.Op Fl clrreject +.Op Fl clrtrust +.Op Fl dates +.Op Fl days Ar arg +.Op Fl email +.Op Fl enddate +.Op Fl extensions Ar section +.Op Fl extfile Ar file +.Op Fl fingerprint +.Op Fl hash +.Op Fl in Ar file +.Op Fl inform Ar DER | NET | PEM +.Op Fl issuer +.Op Fl issuer_hash +.Op Fl issuer_hash_old +.Op Fl keyform Ar DER | PEM +.Op Fl md5 | sha1 +.Op Fl modulus +.Op Fl nameopt Ar option +.Op Fl noout +.Op Fl ocsp_uri +.Op Fl ocspid +.Op Fl out Ar file +.Op Fl outform Ar DER | NET | PEM +.Op Fl passin Ar arg +.Op Fl pubkey +.Op Fl purpose +.Op Fl req +.Op Fl serial +.Op Fl set_serial Ar n +.Op Fl setalias Ar arg +.Op Fl signkey Ar file +.Op Fl startdate +.Op Fl subject +.Op Fl subject_hash +.Op Fl subject_hash_old +.Op Fl text +.Op Fl trustout +.Op Fl x509toreq +.Ek +.nr nS 0 +.Pp +The +.Nm x509 +command is a multi-purpose certificate utility. +It can be used to display certificate information, convert certificates to +various forms, sign certificate requests like a +.Qq mini CA , +or edit certificate trust settings. +.Pp +Since there are a large number of options, they are split up into +various sections. +.Sh X509 INPUT, OUTPUT, AND GENERAL PURPOSE OPTIONS +.Bl -tag -width "XXXX" +.It Fl in Ar file +This specifies the input +.Ar file +to read a certificate from, or standard input if this option is not specified. +.It Fl inform Ar DER | NET | PEM +This specifies the input format. +Normally, the command will expect an X.509 certificate, +but this can change if other options such as +.Fl req +are present. +The +.Ar DER +format is the DER encoding of the certificate and +.Ar PEM +is the base64 encoding of the DER encoding with header and footer lines added. +The +.Ar NET +option is an obscure Netscape server format that is now +obsolete. +.It Fl md5 | sha1 +The digest to use. +This affects any signing or display option that uses a message digest, +such as the +.Fl fingerprint , signkey , +and +.Fl CA +options. +If not specified, MD5 is used. +If the key being used to sign with is a DSA key, +this option has no effect: SHA1 is always used with DSA keys. +.It Fl out Ar file +This specifies the output +.Ar file +to write to, or standard output by default. +.It Fl outform Ar DER | NET | PEM +This specifies the output format; the options have the same meaning as the +.Fl inform +option. +.It Fl passin Ar arg +The key password source. +.El +.Sh X509 DISPLAY OPTIONS +.Sy Note : +The +.Fl alias +and +.Fl purpose +options are also display options but are described in the +.Sx X509 TRUST SETTINGS +section. +.Bl -tag -width "XXXX" +.It Fl C +This outputs the certificate in the form of a C source file. +.It Fl certopt Ar option +Customise the output format used with +.Fl text . +The +.Ar option +argument can be a single option or multiple options separated by commas. +The +.Fl certopt +switch may also be used more than once to set multiple options. +See the +.Sx X509 TEXT OPTIONS +section for more information. +.It Fl dates +Prints out the start and expiry dates of a certificate. +.It Fl email +Outputs the email address(es), if any. +.It Fl enddate +Prints out the expiry date of the certificate; that is, the +.Em notAfter +date. +.It Fl fingerprint +Prints out the digest of the DER-encoded version of the whole certificate +(see +.Sx DIGEST OPTIONS ) . +.It Fl hash +A synonym for +.Fl subject_hash , +for backwards compatibility. +.It Fl issuer +Outputs the issuer name. +.It Fl issuer_hash +Outputs the +.Qq hash +of the certificate issuer name. +.It Fl issuer_hash_old +Outputs the +.Qq hash +of the certificate issuer name using the older algorithm +as used by +.Nm OpenSSL +versions before 1.0.0. +.It Fl modulus +This option prints out the value of the modulus of the public key +contained in the certificate. +.It Fl nameopt Ar option +Option which determines how the subject or issuer names are displayed. +The +.Ar option +argument can be a single option or multiple options separated by commas. +Alternatively, the +.Fl nameopt +switch may be used more than once to set multiple options. +See the +.Sx X509 NAME OPTIONS +section for more information. +.It Fl noout +This option prevents output of the encoded version of the request. +.It Fl ocsp_uri +Outputs the OCSP responder addresses, if any. +.It Fl ocspid +Print OCSP hash values for the subject name and public key. +.It Fl pubkey +Output the public key. +.It Fl serial +Outputs the certificate serial number. +.It Fl startdate +Prints out the start date of the certificate; that is, the +.Em notBefore +date. +.It Fl subject +Outputs the subject name. +.It Fl subject_hash +Outputs the +.Qq hash +of the certificate subject name. +This is used in +.Nm OpenSSL +to form an index to allow certificates in a directory to be looked up +by subject name. +.It Fl subject_hash_old +Outputs the +.Qq hash +of the certificate subject name using the older algorithm +as used by +.Nm OpenSSL +versions before 1.0.0. +.It Fl text +Prints out the certificate in text form. +Full details are output including the public key, signature algorithms, +issuer and subject names, serial number, any extensions present, +and any trust settings. +.El +.Sh X509 TRUST SETTINGS +Please note these options are currently experimental and may well change. +.Pp +A +.Em trusted certificate +is an ordinary certificate which has several +additional pieces of information attached to it such as the permitted +and prohibited uses of the certificate and an +.Qq alias . +.Pp +Normally, when a certificate is being verified at least one certificate +must be +.Qq trusted . +By default, a trusted certificate must be stored +locally and must be a root CA: any certificate chain ending in this CA +is then usable for any purpose. +.Pp +Trust settings currently are only used with a root CA. +They allow a finer control over the purposes the root CA can be used for. +For example, a CA may be trusted for an SSL client but not for +SSL server use. +.Pp +See the description of the +.Nm verify +utility for more information on the meaning of trust settings. +.Pp +Future versions of +.Nm OpenSSL +will recognize trust settings on any certificate: not just root CAs. +.Bl -tag -width "XXXX" +.It Fl addreject Ar arg +Adds a prohibited use. +It accepts the same values as the +.Fl addtrust +option. +.It Fl addtrust Ar arg +Adds a trusted certificate use. +Any object name can be used here, but currently only +.Ar clientAuth +.Pq SSL client use , +.Ar serverAuth +.Pq SSL server use , +and +.Ar emailProtection +.Pq S/MIME email +are used. +Other +.Nm OpenSSL +applications may define additional uses. +.It Fl alias +Outputs the certificate alias, if any. +.It Fl clrreject +Clears all the prohibited or rejected uses of the certificate. +.It Fl clrtrust +Clears all the permitted or trusted uses of the certificate. +.It Fl purpose +This option performs tests on the certificate extensions and outputs +the results. +For a more complete description, see the +.Sx X.509 CERTIFICATE EXTENSIONS +section. +.It Fl setalias Ar arg +Sets the alias of the certificate. +This will allow the certificate to be referred to using a nickname, +for example +.Qq Steve's Certificate . +.It Fl trustout +This causes +.Nm x509 +to output a +.Em trusted certificate . +An ordinary or trusted certificate can be input, but by default an ordinary +certificate is output and any trust settings are discarded. +With the +.Fl trustout +option a trusted certificate is output. +A trusted certificate is automatically output if any trust settings +are modified. +.El +.Sh X509 SIGNING OPTIONS +The +.Nm x509 +utility can be used to sign certificates and requests: it +can thus behave like a +.Qq mini CA . +.Bl -tag -width "XXXX" +.It Fl CA Ar file +Specifies the CA certificate to be used for signing. +When this option is present, +.Nm x509 +behaves like a +.Qq mini CA . +The input file is signed by the CA using this option; +that is, its issuer name is set to the subject name of the CA and it is +digitally signed using the CA's private key. +.Pp +This option is normally combined with the +.Fl req +option. +Without the +.Fl req +option, the input is a certificate which must be self-signed. +.It Fl CAcreateserial +With this option the CA serial number file is created if it does not exist: +it will contain the serial number +.Sq 02 +and the certificate being signed will have +.Sq 1 +as its serial number. +Normally, if the +.Fl CA +option is specified and the serial number file does not exist, it is an error. +.It Fl CAform Ar DER | PEM +The format of the CA certificate file. +The default is +.Ar PEM . +.It Fl CAkey Ar file +Sets the CA private key to sign a certificate with. +If this option is not specified, it is assumed that the CA private key +is present in the CA certificate file. +.It Fl CAkeyform Ar DER | PEM +The format of the CA private key. +The default is +.Ar PEM . +.It Fl CAserial Ar file +Sets the CA serial number file to use. +.Pp +When the +.Fl CA +option is used to sign a certificate, +it uses a serial number specified in a file. +This file consists of one line containing an even number of hex digits +with the serial number to use. +After each use the serial number is incremented and written out +to the file again. +.Pp +The default filename consists of the CA certificate file base name with +.Pa .srl +appended. +For example, if the CA certificate file is called +.Pa mycacert.pem , +it expects to find a serial number file called +.Pa mycacert.srl . +.It Fl checkend Ar arg +Check whether the certificate expires in the next +.Ar arg +seconds. +If so, exit with return value 1; +otherwise exit with return value 0. +.It Fl clrext +Delete any extensions from a certificate. +This option is used when a certificate is being created from another +certificate (for example with the +.Fl signkey +or the +.Fl CA +options). +Normally, all extensions are retained. +.It Fl days Ar arg +Specifies the number of days to make a certificate valid for. +The default is 30 days. +.It Fl extensions Ar section +The section to add certificate extensions from. +If this option is not specified, the extensions should either be +contained in the unnamed +.Pq default +section or the default section should contain a variable called +.Qq extensions +which contains the section to use. +.It Fl extfile Ar file +File containing certificate extensions to use. +If not specified, no extensions are added to the certificate. +.It Fl keyform Ar DER | PEM +Specifies the format +.Pq DER or PEM +of the private key file used in the +.Fl signkey +option. +.It Fl req +By default, a certificate is expected on input. +With this option a certificate request is expected instead. +.It Fl set_serial Ar n +Specifies the serial number to use. +This option can be used with either the +.Fl signkey +or +.Fl CA +options. +If used in conjunction with the +.Fl CA +option, the serial number file (as specified by the +.Fl CAserial +or +.Fl CAcreateserial +options) is not used. +.Pp +The serial number can be decimal or hex (if preceded by +.Sq 0x ) . +Negative serial numbers can also be specified but their use is not recommended. +.It Fl signkey Ar file +This option causes the input file to be self-signed using the supplied +private key. +.Pp +If the input file is a certificate, it sets the issuer name to the +subject name +.Pq i.e. makes it self-signed , +changes the public key to the supplied value, +and changes the start and end dates. +The start date is set to the current time and the end date is set to +a value determined by the +.Fl days +option. +Any certificate extensions are retained unless the +.Fl clrext +option is supplied. +.Pp +If the input is a certificate request, a self-signed certificate +is created using the supplied private key using the subject name in +the request. +.It Fl x509toreq +Converts a certificate into a certificate request. +The +.Fl signkey +option is used to pass the required private key. +.El +.Sh X509 NAME OPTIONS +The +.Fl nameopt +command line switch determines how the subject and issuer +names are displayed. +If no +.Fl nameopt +switch is present, the default +.Qq oneline +format is used which is compatible with previous versions of +.Nm OpenSSL . +Each option is described in detail below; all options can be preceded by a +.Sq - +to turn the option off. +Only +.Ar compat , +.Ar RFC2253 , +.Ar oneline , +and +.Ar multiline +will normally be used. +.Bl -tag -width "XXXX" +.It Ar align +Align field values for a more readable output. +Only usable with +.Ar sep_multiline . +.It Ar compat +Use the old format. +This is equivalent to specifying no name options at all. +.It Ar dn_rev +Reverse the fields of the DN. +This is required by RFC 2253. +As a side effect, this also reverses the order of multiple AVAs but this is +permissible. +.It Ar dump_all +Dump all fields. +This option, when used with +.Ar dump_der , +allows the DER encoding of the structure to be unambiguously determined. +.It Ar dump_der +When this option is set, any fields that need to be hexdumped will +be dumped using the DER encoding of the field. +Otherwise just the content octets will be displayed. +Both options use the RFC 2253 #XXXX... format. +.It Ar dump_nostr +Dump non-character string types +.Pq for example OCTET STRING ; +if this option is not set, non-character string types will be displayed +as though each content octet represents a single character. +.It Ar dump_unknown +Dump any field whose OID is not recognised by +.Nm OpenSSL . +.It Ar esc_2253 +Escape the +.Qq special +characters required by RFC 2253 in a field that is +.Dq \& ,+"\*(Lt\*(Gt; . +Additionally, +.Sq # +is escaped at the beginning of a string +and a space character at the beginning or end of a string. +.It Ar esc_ctrl +Escape control characters. +That is, those with ASCII values less than 0x20 +.Pq space +and the delete +.Pq 0x7f +character. +They are escaped using the RFC 2253 \eXX notation (where XX are two hex +digits representing the character value). +.It Ar esc_msb +Escape characters with the MSB set; that is, with ASCII values larger than +127. +.It Ar multiline +A multiline format. +It is equivalent to +.Ar esc_ctrl , esc_msb , sep_multiline , +.Ar space_eq , lname , +and +.Ar align . +.It Ar no_type +This option does not attempt to interpret multibyte characters in any +way. +That is, their content octets are merely dumped as though one octet +represents each character. +This is useful for diagnostic purposes but will result in rather odd +looking output. +.It Ar nofname , sname , lname , oid +These options alter how the field name is displayed. +.Ar nofname +does not display the field at all. +.Ar sname +uses the +.Qq short name +form (CN for +.Ar commonName , +for example). +.Ar lname +uses the long form. +.Ar oid +represents the OID in numerical form and is useful for diagnostic purpose. +.It Ar oneline +A oneline format which is more readable than +.Ar RFC2253 . +It is equivalent to specifying the +.Ar esc_2253 , esc_ctrl , esc_msb , utf8 , +.Ar dump_nostr , dump_der , use_quote , sep_comma_plus_spc , +.Ar space_eq , +and +.Ar sname +options. +.It Ar RFC2253 +Displays names compatible with RFC 2253; equivalent to +.Ar esc_2253 , esc_ctrl , +.Ar esc_msb , utf8 , dump_nostr , dump_unknown , +.Ar dump_der , sep_comma_plus , dn_rev , +and +.Ar sname . +.It Ar sep_comma_plus , sep_comma_plus_space , sep_semi_plus_space , sep_multiline +These options determine the field separators. +The first character is between RDNs and the second between multiple AVAs +(multiple AVAs are very rare and their use is discouraged). +The options ending in +.Qq space +additionally place a space after the separator to make it more readable. +The +.Ar sep_multiline +uses a linefeed character for the RDN separator and a spaced +.Sq + +for the AVA separator. +It also indents the fields by four characters. +.It Ar show_type +Show the type of the ASN1 character string. +The type precedes the field contents. +For example +.Qq BMPSTRING: Hello World . +.It Ar space_eq +Places spaces round the +.Sq = +character which follows the field name. +.It Ar use_quote +Escapes some characters by surrounding the whole string with +.Sq \&" +characters. +Without the option, all escaping is done with the +.Sq \e +character. +.It Ar utf8 +Convert all strings to UTF8 format first. +This is required by RFC 2253. +If you are lucky enough to have a UTF8 compatible terminal, +the use of this option (and +.Em not +setting +.Ar esc_msb ) +may result in the correct display of multibyte +.Pq international +characters. +If this option is not present, multibyte characters larger than 0xff +will be represented using the format \eUXXXX for 16 bits and \eWXXXXXXXX +for 32 bits. +Also, if this option is off, any UTF8Strings will be converted to their +character form first. +.El +.Sh X509 TEXT OPTIONS +As well as customising the name output format, it is also possible to +customise the actual fields printed using the +.Fl certopt +options when the +.Fl text +option is present. +The default behaviour is to print all fields. +.Bl -tag -width "XXXX" +.It Ar ca_default +The value used by the +.Nm ca +utility; equivalent to +.Ar no_issuer , no_pubkey , no_header , +.Ar no_version , no_sigdump , +and +.Ar no_signame . +.It Ar compatible +Use the old format. +This is equivalent to specifying no output options at all. +.It Ar ext_default +Retain default extension behaviour: attempt to print out unsupported +certificate extensions. +.It Ar ext_dump +Hex dump unsupported extensions. +.It Ar ext_error +Print an error message for unsupported certificate extensions. +.It Ar ext_parse +ASN1 parse unsupported extensions. +.It Ar no_aux +Don't print out certificate trust information. +.It Ar no_extensions +Don't print out any X509V3 extensions. +.It Ar no_header +Don't print header information: that is, the lines saying +.Qq Certificate +and +.Qq Data . +.It Ar no_issuer +Don't print out the issuer name. +.It Ar no_pubkey +Don't print out the public key. +.It Ar no_serial +Don't print out the serial number. +.It Ar no_sigdump +Don't give a hexadecimal dump of the certificate signature. +.It Ar no_signame +Don't print out the signature algorithm used. +.It Ar no_subject +Don't print out the subject name. +.It Ar no_validity +Don't print the validity; that is, the +.Em notBefore +and +.Em notAfter +fields. +.It Ar no_version +Don't print out the version number. +.El +.Sh X509 EXAMPLES +Display the contents of a certificate: +.Pp +.Dl $ openssl x509 -in cert.pem -noout -text +.Pp +Display the certificate serial number: +.Pp +.Dl $ openssl x509 -in cert.pem -noout -serial +.Pp +Display the certificate subject name: +.Pp +.Dl $ openssl x509 -in cert.pem -noout -subject +.Pp +Display the certificate subject name in RFC 2253 form: +.Pp +.Dl $ openssl x509 -in cert.pem -noout -subject -nameopt RFC2253 +.Pp +Display the certificate subject name in oneline form on a terminal +supporting UTF8: +.Bd -literal -offset indent +$ openssl x509 -in cert.pem -noout -subject \e + -nameopt oneline,-esc_msb +.Ed +.Pp +Display the certificate MD5 fingerprint: +.Pp +.Dl $ openssl x509 -in cert.pem -noout -fingerprint +.Pp +Display the certificate SHA1 fingerprint: +.Pp +.Dl $ openssl x509 -sha1 -in cert.pem -noout -fingerprint +.Pp +Convert a certificate from PEM to DER format: +.Pp +.Dl "$ openssl x509 -in cert.pem -inform PEM -out cert.der -outform DER" +.Pp +Convert a certificate to a certificate request: +.Bd -literal -offset indent +$ openssl x509 -x509toreq -in cert.pem -out req.pem \e + -signkey key.pem +.Ed +.Pp +Convert a certificate request into a self-signed certificate using +extensions for a CA: +.Bd -literal -offset indent +$ openssl x509 -req -in careq.pem -extfile openssl.cnf -extensions \e + v3_ca -signkey key.pem -out cacert.pem +.Ed +.Pp +Sign a certificate request using the CA certificate above and add user +certificate extensions: +.Bd -literal -offset indent +$ openssl x509 -req -in req.pem -extfile openssl.cnf -extensions \e + v3_usr -CA cacert.pem -CAkey key.pem -CAcreateserial +.Ed +.Pp +Set a certificate to be trusted for SSL +client use and set its alias to +.Qq Steve's Class 1 CA : +.Bd -literal -offset indent +$ openssl x509 -in cert.pem -addtrust clientAuth \e + -setalias "Steve's Class 1 CA" -out trust.pem +.Ed +.Sh X509 NOTES +The PEM format uses the header and footer lines: +.Bd -unfilled -offset indent +-----BEGIN CERTIFICATE----- +-----END CERTIFICATE----- +.Ed +.Pp +It will also handle files containing: +.Bd -unfilled -offset indent +-----BEGIN X509 CERTIFICATE----- +-----END X509 CERTIFICATE----- +.Ed +.Pp +Trusted certificates have the lines: +.Bd -unfilled -offset indent +-----BEGIN TRUSTED CERTIFICATE----- +-----END TRUSTED CERTIFICATE----- +.Ed +.Pp +The conversion to UTF8 format used with the name options assumes that +T61Strings use the ISO 8859-1 character set. +This is wrong, but Netscape and MSIE do this, as do many certificates. +So although this is incorrect +it is more likely to display the majority of certificates correctly. +.Pp +The +.Fl fingerprint +option takes the digest of the DER-encoded certificate. +This is commonly called a +.Qq fingerprint . +Because of the nature of message digests, the fingerprint of a certificate +is unique to that certificate and two certificates with the same fingerprint +can be considered to be the same. +.Pp +The Netscape fingerprint uses MD5, whereas MSIE uses SHA1. +.Pp +The +.Fl email +option searches the subject name and the subject alternative +name extension. +Only unique email addresses will be printed out: it will +not print the same address more than once. +.Sh X.509 CERTIFICATE EXTENSIONS +The +.Fl purpose +option checks the certificate extensions and determines +what the certificate can be used for. +The actual checks done are rather +complex and include various hacks and workarounds to handle broken +certificates and software. +.Pp +The same code is used when verifying untrusted certificates in chains, +so this section is useful if a chain is rejected by the verify code. +.Pp +The +.Em basicConstraints +extension CA flag is used to determine whether the +certificate can be used as a CA. +If the CA flag is true, it is a CA; +if the CA flag is false, it is not a CA. +.Em All +CAs should have the CA flag set to true. +.Pp +If the +.Em basicConstraints +extension is absent, then the certificate is +considered to be a +.Qq possible CA ; +other extensions are checked according to the intended use of the certificate. +A warning is given in this case because the certificate should really not +be regarded as a CA: however, +it is allowed to be a CA to work around some broken software. +.Pp +If the certificate is a V1 certificate +.Pq and thus has no extensions +and it is self-signed, it is also assumed to be a CA but a warning is again +given: this is to work around the problem of Verisign roots which are V1 +self-signed certificates. +.Pp +If the +.Em keyUsage +extension is present, then additional restraints are +made on the uses of the certificate. +A CA certificate +.Em must +have the +.Em keyCertSign +bit set if the +.Em keyUsage +extension is present. +.Pp +The extended key usage extension places additional restrictions on the +certificate uses. +If this extension is present +.Pq whether critical or not , +the key can only be used for the purposes specified. +.Pp +A complete description of each test is given below. +The comments about +.Em basicConstraints +and +.Em keyUsage +and V1 certificates above apply to +.Em all +CA certificates. +.Bl -tag -width "XXXX" +.It Ar SSL Client +The extended key usage extension must be absent or include the +.Qq web client authentication +OID. +.Ar keyUsage +must be absent or it must have the +.Em digitalSignature +bit set. +Netscape certificate type must be absent or it must have the SSL +client bit set. +.It Ar SSL Client CA +The extended key usage extension must be absent or include the +.Qq web client authentication +OID. +Netscape certificate type must be absent or it must have the SSL CA +bit set: this is used as a work around if the +.Em basicConstraints +extension is absent. +.It Ar SSL Server +The extended key usage extension must be absent or include the +.Qq web server authentication +and/or one of the SGC OIDs. +.Em keyUsage +must be absent or it must have the +.Em digitalSignature +set, the +.Em keyEncipherment +set, or both bits set. +Netscape certificate type must be absent or have the SSL server bit set. +.It Ar SSL Server CA +The extended key usage extension must be absent or include the +.Qq web server authentication +and/or one of the SGC OIDs. +Netscape certificate type must be absent or the SSL CA +bit must be set: this is used as a work around if the +.Em basicConstraints +extension is absent. +.It Ar Netscape SSL Server +For Netscape SSL clients to connect to an SSL server; it must have the +.Em keyEncipherment +bit set if the +.Em keyUsage +extension is present. +This isn't always valid because some cipher suites use the key for +digital signing. +Otherwise it is the same as a normal SSL server. +.It Ar Common S/MIME Client Tests +The extended key usage extension must be absent or include the +.Qq email protection +OID. +Netscape certificate type must be absent or should have the +.Em S/MIME +bit set. +If the +.Em S/MIME +bit is not set in Netscape certificate type, then the SSL +client bit is tolerated as an alternative but a warning is shown: +this is because some Verisign certificates don't set the +.Em S/MIME +bit. +.It Ar S/MIME Signing +In addition to the common +.Em S/MIME +client tests, the +.Em digitalSignature +bit must be set if the +.Em keyUsage +extension is present. +.It Ar S/MIME Encryption +In addition to the common +.Em S/MIME +tests, the +.Em keyEncipherment +bit must be set if the +.Em keyUsage +extension is present. +.It Ar S/MIME CA +The extended key usage extension must be absent or include the +.Qq email protection +OID. +Netscape certificate type must be absent or must have the +.Em S/MIME CA +bit set: this is used as a work around if the +.Em basicConstraints +extension is absent. +.It Ar CRL Signing +The +.Em keyUsage +extension must be absent or it must have the +.Em CRL +signing bit set. +.It Ar CRL Signing CA +The normal CA tests apply. +Except in this case the +.Em basicConstraints +extension must be present. +.El +.Sh X509 BUGS +Extensions in certificates are not transferred to certificate requests and +vice versa. +.Pp +It is possible to produce invalid certificates or requests by specifying the +wrong private key or using inconsistent options in some cases: these should +be checked. +.Pp +There should be options to explicitly set such things as start and end dates, +rather than an offset from the current time. +.Pp +The code to implement the verify behaviour described in the +.Sx X509 TRUST SETTINGS +is currently being developed. +It thus describes the intended behaviour rather than the current behaviour. +It is hoped that it will represent reality in +.Nm OpenSSL +0.9.5 and later. +.Sh X509 HISTORY +Before +.Nm OpenSSL +0.9.8, +the default digest for RSA keys was MD5. +.Pp +The hash algorithm used in the +.Fl subject_hash +and +.Fl issuer_hash +options before +.Nm OpenSSL +1.0.0 was based on the deprecated MD5 algorithm and the encoding +of the distinguished name. +In +.Nm OpenSSL +1.0.0 and later it is based on a canonical version of the DN using SHA1. +This means that any directories using the old form +must have their links rebuilt using +.Ar c_rehash +or similar. +.Sh COMMON NOTATION +Several commands share a common syntax, +as detailed below. +.Pp +Password arguments, typically specified using +.Fl passin +and +.Fl passout +for input and output passwords, +allow passwords to be obtained from a variety of sources. +Both of these options take a single argument, described below. +If no password argument is given and a password is required, +then the user is prompted to enter one: +this will typically be read from the current terminal with echoing turned off. +.Bl -tag -width "pass:password" -offset indent +.It Cm pass : Ns Ar password +The actual password is +.Ar password . +Since the password is visible to utilities, +this form should only be used where security is not important. +.It Cm env : Ns Ar var +Obtain the password from the environment variable +.Ar var . +Since the environment of other processes is visible, +this option should be used with caution. +.It Cm file : Ns Ar path +The first line of +.Ar path +is the password. +If the same +.Ar path +argument is supplied to +.Fl passin +and +.Fl passout , +then the first line will be used for the input password and the next line +for the output password. +.Ar path +need not refer to a regular file: +it could, for example, refer to a device or named pipe. +.It Cm fd : Ns Ar number +Read the password from the file descriptor +.Ar number . +This can be used to send the data via a pipe, for example. +.It Cm stdin +Read the password from standard input. +.El +.Pp +File formats, +typically specified using +.Fl inform +and +.Fl outform , +indicate the type of file being read from +or the file format to write. +The argument is case insensitive. +.Pp +.Bl -tag -width Ds -offset indent -compact +.It Cm der +Distinguished Encoding Rules (DER) +is a binary format. +.It Cm pem +Privacy Enhanced Mail (PEM) +is base64-encoded. +.It Cm txt +Plain ASCII text. +.El +.Sh ENVIRONMENT +The following environment variables affect the execution of +.Nm openssl : +.Bl -tag -width "/etc/ssl/openssl.cnf" +.It Ev OPENSSL_CONF +The location of the master configuration file. +.El +.\" +.\" FILES +.\" +.Sh FILES +.Bl -tag -width "/etc/ssl/openssl.cnf" -compact +.It Pa /etc/ssl/ +Default config directory for +.Nm openssl . +.It Pa /etc/ssl/lib/ +Unused. +.It Pa /etc/ssl/private/ +Default private key directory. +.It Pa /etc/ssl/openssl.cnf +Default configuration file for +.Nm openssl . +.It Pa /etc/ssl/x509v3.cnf +Default configuration file for +.Nm x509 +certificates. +.El +.\" +.\" SEE ALSO +.\" +.Sh SEE ALSO +.Xr nc 1 , +.Xr ssl 8 , +.Xr starttls 8 +.Sh STANDARDS +.Rs +.%D February 1995 +.%Q Netscape Communications Corp. +.%T The SSL Protocol +.Re +.Pp +.Rs +.%D November 1996 +.%Q Netscape Communications Corp. +.%T The SSL 3.0 Protocol +.Re +.Pp +.Rs +.%A T. Dierks +.%A C. Allen +.%D January 1999 +.%R RFC 2246 +.%T The TLS Protocol Version 1.0 +.Re +.Pp +.Rs +.%A M. Wahl +.%A S. Killie +.%A T. Howes +.%D December 1997 +.%R RFC 2253 +.%T Lightweight Directory Access Protocol (v3): UTF-8 String Representation of Distinguished Names +.Re +.Pp +.Rs +.%A B. Kaliski +.%D March 1998 +.%R RFC 2315 +.%T PKCS #7: Cryptographic Message Syntax Version 1.5 +.Re +.Pp +.Rs +.%A R. Housley +.%A W. Ford +.%A W. Polk +.%A D. Solo +.%D January 1999 +.%R RFC 2459 +.%T Internet X.509 Public Key Infrastructure Certificate and CRL Profile +.Re +.Pp +.Rs +.%A M. Myers +.%A R. Ankney +.%A A. Malpani +.%A S. Galperin +.%A C. Adams +.%D June 1999 +.%R RFC 2560 +.%T X.509 Internet Public Key Infrastructure Online Certificate Status Protocol \(en OCSP +.Re +.Pp +.Rs +.%A R. Housley +.%D June 1999 +.%R RFC 2630 +.%T Cryptographic Message Syntax +.Re +.Pp +.Rs +.%A P. Chown +.%D June 2002 +.%R RFC 3268 +.%T Advanced Encryption Standard (AES) Ciphersuites for Transport Layer Security (TLS) +.Re +.\" +.\" OPENSSL HISTORY +.\" +.Sh HISTORY +The +.Xr openssl 1 +document appeared in +.Nm OpenSSL +0.9.2. +The +.Cm list- Ns XXX Ns Cm -commands +pseudo-commands were added in +.Nm OpenSSL +0.9.3; +the +.Cm no- Ns XXX +pseudo-commands were added in +.Nm OpenSSL +0.9.5a; +the +.Cm list- Ns XXX Ns Cm -algorithms +pseudo-commands were added in +.Nm OpenSSL +1.0.0. diff --git a/crypto/libressl/apps/openssl/openssl.c b/crypto/libressl/apps/openssl/openssl.c new file mode 100644 index 0000000000..42976b821b --- /dev/null +++ b/crypto/libressl/apps/openssl/openssl.c @@ -0,0 +1,836 @@ +/* $OpenBSD: openssl.c,v 1.22 2015/12/01 01:24:47 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include + +#include "apps.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "progs.h" +#include "s_apps.h" + +#define FUNC_TYPE_GENERAL 1 +#define FUNC_TYPE_MD 2 +#define FUNC_TYPE_CIPHER 3 +#define FUNC_TYPE_PKEY 4 +#define FUNC_TYPE_MD_ALG 5 +#define FUNC_TYPE_CIPHER_ALG 6 + +int single_execution = 0; + +typedef struct { + int type; + const char *name; + int (*func)(int argc, char **argv); +} FUNCTION; + +DECLARE_LHASH_OF(FUNCTION); + +FUNCTION functions[] = { + + /* General functions. */ + { FUNC_TYPE_GENERAL, "asn1parse", asn1parse_main }, + { FUNC_TYPE_GENERAL, "ca", ca_main }, + { FUNC_TYPE_GENERAL, "certhash", certhash_main }, + { FUNC_TYPE_GENERAL, "ciphers", ciphers_main }, +#ifndef OPENSSL_NO_CMS + { FUNC_TYPE_GENERAL, "cms", cms_main }, +#endif + { FUNC_TYPE_GENERAL, "crl2pkcs7", crl2pkcs7_main }, + { FUNC_TYPE_GENERAL, "crl", crl_main }, + { FUNC_TYPE_GENERAL, "dgst", dgst_main }, + { FUNC_TYPE_GENERAL, "enc", enc_main }, + { FUNC_TYPE_GENERAL, "errstr", errstr_main }, + { FUNC_TYPE_GENERAL, "genpkey", genpkey_main }, + { FUNC_TYPE_GENERAL, "nseq", nseq_main }, +#ifndef OPENSSL_NO_OCSP + { FUNC_TYPE_GENERAL, "ocsp", ocsp_main }, +#endif + { FUNC_TYPE_GENERAL, "passwd", passwd_main }, + { FUNC_TYPE_GENERAL, "pkcs7", pkcs7_main }, + { FUNC_TYPE_GENERAL, "pkcs8", pkcs8_main }, +#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1) + { FUNC_TYPE_GENERAL, "pkcs12", pkcs12_main }, +#endif + { FUNC_TYPE_GENERAL, "pkey", pkey_main }, + { FUNC_TYPE_GENERAL, "pkeyparam", pkeyparam_main }, + { FUNC_TYPE_GENERAL, "pkeyutl", pkeyutl_main }, + { FUNC_TYPE_GENERAL, "prime", prime_main }, + { FUNC_TYPE_GENERAL, "rand", rand_main }, + { FUNC_TYPE_GENERAL, "req", req_main }, + { FUNC_TYPE_GENERAL, "s_client", s_client_main }, + { FUNC_TYPE_GENERAL, "s_server", s_server_main }, + { FUNC_TYPE_GENERAL, "s_time", s_time_main }, + { FUNC_TYPE_GENERAL, "sess_id", sess_id_main }, + { FUNC_TYPE_GENERAL, "smime", smime_main }, +#ifndef OPENSSL_NO_SPEED + { FUNC_TYPE_GENERAL, "speed", speed_main }, +#endif + { FUNC_TYPE_GENERAL, "spkac", spkac_main }, + { FUNC_TYPE_GENERAL, "ts", ts_main }, + { FUNC_TYPE_GENERAL, "verify", verify_main }, + { FUNC_TYPE_GENERAL, "version", version_main }, + { FUNC_TYPE_GENERAL, "x509", x509_main }, + +#ifndef OPENSSL_NO_DH + { FUNC_TYPE_GENERAL, "dh", dh_main }, + { FUNC_TYPE_GENERAL, "dhparam", dhparam_main }, + { FUNC_TYPE_GENERAL, "gendh", gendh_main }, +#endif +#ifndef OPENSSL_NO_DSA + { FUNC_TYPE_GENERAL, "dsa", dsa_main }, + { FUNC_TYPE_GENERAL, "dsaparam", dsaparam_main }, + { FUNC_TYPE_GENERAL, "gendsa", gendsa_main }, +#endif +#ifndef OPENSSL_NO_EC + { FUNC_TYPE_GENERAL, "ec", ec_main }, + { FUNC_TYPE_GENERAL, "ecparam", ecparam_main }, +#endif +#ifndef OPENSSL_NO_RSA + { FUNC_TYPE_GENERAL, "genrsa", genrsa_main }, + { FUNC_TYPE_GENERAL, "rsa", rsa_main }, + { FUNC_TYPE_GENERAL, "rsautl", rsautl_main }, +#endif + + /* Message Digests. */ +#ifndef OPENSSL_NO_GOST + { FUNC_TYPE_MD, "gost-mac", dgst_main }, + { FUNC_TYPE_MD, "md_gost94", dgst_main }, + { FUNC_TYPE_MD, "streebog256", dgst_main }, + { FUNC_TYPE_MD, "streebog512", dgst_main }, +#endif +#ifndef OPENSSL_NO_MD4 + { FUNC_TYPE_MD, "md4", dgst_main }, +#endif +#ifndef OPENSSL_NO_MD5 + { FUNC_TYPE_MD, "md5", dgst_main }, +#endif +#ifndef OPENSSL_NO_RIPEMD160 + { FUNC_TYPE_MD, "ripemd160", dgst_main }, +#endif +#ifndef OPENSSL_NO_SHA1 + { FUNC_TYPE_MD, "sha1", dgst_main }, +#endif +#ifndef OPENSSL_NO_SHA224 + { FUNC_TYPE_MD, "sha224", dgst_main }, +#endif +#ifndef OPENSSL_NO_SHA256 + { FUNC_TYPE_MD, "sha256", dgst_main }, +#endif +#ifndef OPENSSL_NO_SHA384 + { FUNC_TYPE_MD, "sha384", dgst_main }, +#endif +#ifndef OPENSSL_NO_SHA512 + { FUNC_TYPE_MD, "sha512", dgst_main }, +#endif +#ifndef OPENSSL_NO_WHIRLPOOL + { FUNC_TYPE_MD, "whirlpool", dgst_main }, +#endif + + /* Ciphers. */ + { FUNC_TYPE_CIPHER, "base64", enc_main }, +#ifndef OPENSSL_NO_AES + { FUNC_TYPE_CIPHER, "aes-128-cbc", enc_main }, + { FUNC_TYPE_CIPHER, "aes-128-ecb", enc_main }, + { FUNC_TYPE_CIPHER, "aes-192-cbc", enc_main }, + { FUNC_TYPE_CIPHER, "aes-192-ecb", enc_main }, + { FUNC_TYPE_CIPHER, "aes-256-cbc", enc_main }, + { FUNC_TYPE_CIPHER, "aes-256-ecb", enc_main }, +#endif +#ifndef OPENSSL_NO_BF + { FUNC_TYPE_CIPHER, "bf", enc_main }, + { FUNC_TYPE_CIPHER, "bf-cbc", enc_main }, + { FUNC_TYPE_CIPHER, "bf-ecb", enc_main }, + { FUNC_TYPE_CIPHER, "bf-cfb", enc_main }, + { FUNC_TYPE_CIPHER, "bf-ofb", enc_main }, +#endif +#ifndef OPENSSL_NO_CAMELLIA + { FUNC_TYPE_CIPHER, "camellia-128-cbc", enc_main }, + { FUNC_TYPE_CIPHER, "camellia-128-ecb", enc_main }, + { FUNC_TYPE_CIPHER, "camellia-192-cbc", enc_main }, + { FUNC_TYPE_CIPHER, "camellia-192-ecb", enc_main }, + { FUNC_TYPE_CIPHER, "camellia-256-cbc", enc_main }, + { FUNC_TYPE_CIPHER, "camellia-256-ecb", enc_main }, +#endif +#ifndef OPENSSL_NO_CAST + { FUNC_TYPE_CIPHER, "cast", enc_main }, + { FUNC_TYPE_CIPHER, "cast5-cbc", enc_main }, + { FUNC_TYPE_CIPHER, "cast5-ecb", enc_main }, + { FUNC_TYPE_CIPHER, "cast5-cfb", enc_main }, + { FUNC_TYPE_CIPHER, "cast5-ofb", enc_main }, + { FUNC_TYPE_CIPHER, "cast-cbc", enc_main }, +#endif +#ifndef OPENSSL_NO_CHACHA + { FUNC_TYPE_CIPHER, "chacha", enc_main }, +#endif +#ifndef OPENSSL_NO_DES + { FUNC_TYPE_CIPHER, "des", enc_main }, + { FUNC_TYPE_CIPHER, "des3", enc_main }, + { FUNC_TYPE_CIPHER, "desx", enc_main }, + { FUNC_TYPE_CIPHER, "des-ecb", enc_main }, + { FUNC_TYPE_CIPHER, "des-ede", enc_main }, + { FUNC_TYPE_CIPHER, "des-ede3", enc_main }, + { FUNC_TYPE_CIPHER, "des-cbc", enc_main }, + { FUNC_TYPE_CIPHER, "des-ede-cbc", enc_main }, + { FUNC_TYPE_CIPHER, "des-ede3-cbc", enc_main }, + { FUNC_TYPE_CIPHER, "des-cfb", enc_main }, + { FUNC_TYPE_CIPHER, "des-ede-cfb", enc_main }, + { FUNC_TYPE_CIPHER, "des-ede3-cfb", enc_main }, + { FUNC_TYPE_CIPHER, "des-ofb", enc_main }, + { FUNC_TYPE_CIPHER, "des-ede-ofb", enc_main }, + { FUNC_TYPE_CIPHER, "des-ede3-ofb", enc_main }, +#endif +#ifndef OPENSSL_NO_IDEA + { FUNC_TYPE_CIPHER, "idea", enc_main }, + { FUNC_TYPE_CIPHER, "idea-cbc", enc_main }, + { FUNC_TYPE_CIPHER, "idea-ecb", enc_main }, + { FUNC_TYPE_CIPHER, "idea-cfb", enc_main }, + { FUNC_TYPE_CIPHER, "idea-ofb", enc_main }, +#endif +#ifndef OPENSSL_NO_RC2 + { FUNC_TYPE_CIPHER, "rc2", enc_main }, + { FUNC_TYPE_CIPHER, "rc2-cbc", enc_main }, + { FUNC_TYPE_CIPHER, "rc2-ecb", enc_main }, + { FUNC_TYPE_CIPHER, "rc2-cfb", enc_main }, + { FUNC_TYPE_CIPHER, "rc2-ofb", enc_main }, + { FUNC_TYPE_CIPHER, "rc2-64-cbc", enc_main }, + { FUNC_TYPE_CIPHER, "rc2-40-cbc", enc_main }, +#endif +#ifndef OPENSSL_NO_RC4 + { FUNC_TYPE_CIPHER, "rc4", enc_main }, + { FUNC_TYPE_CIPHER, "rc4-40", enc_main }, +#endif +#ifdef ZLIB + { FUNC_TYPE_CIPHER, "zlib", enc_main }, +#endif + + { 0, NULL, NULL } +}; + +static void openssl_startup(void); +static void openssl_shutdown(void); + +/* The LHASH callbacks ("hash" & "cmp") have been replaced by functions with the + * base prototypes (we cast each variable inside the function to the required + * type of "FUNCTION*"). This removes the necessity for macro-generated wrapper + * functions. */ + +static LHASH_OF(FUNCTION) *prog_init(void); +static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]); +static void list_pkey(BIO * out); +static void list_cipher(BIO * out); +static void list_md(BIO * out); +char *default_config_file = NULL; + +CONF *config = NULL; +BIO *bio_err = NULL; + +static void +lock_dbg_cb(int mode, int type, const char *file, int line) +{ + static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */ + const char *errstr = NULL; + int rw; + + rw = mode & (CRYPTO_READ | CRYPTO_WRITE); + if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE))) { + errstr = "invalid mode"; + goto err; + } + if (type < 0 || type >= CRYPTO_NUM_LOCKS) { + errstr = "type out of bounds"; + goto err; + } + if (mode & CRYPTO_LOCK) { + if (modes[type]) { + errstr = "already locked"; + /* + * must not happen in a single-threaded program + * (would deadlock) + */ + goto err; + } + modes[type] = rw; + } else if (mode & CRYPTO_UNLOCK) { + if (!modes[type]) { + errstr = "not locked"; + goto err; + } + if (modes[type] != rw) { + errstr = (rw == CRYPTO_READ) ? + "CRYPTO_r_unlock on write lock" : + "CRYPTO_w_unlock on read lock"; + } + modes[type] = 0; + } else { + errstr = "invalid mode"; + goto err; + } + +err: + if (errstr) { + /* we cannot use bio_err here */ + fprintf(stderr, "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n", + errstr, mode, type, file, line); + } +} + +static void +openssl_startup(void) +{ +#ifndef _WIN32 + signal(SIGPIPE, SIG_IGN); +#endif + + OpenSSL_add_all_algorithms(); + SSL_library_init(); + SSL_load_error_strings(); + + setup_ui(); +} + +static void +openssl_shutdown(void) +{ + CONF_modules_unload(1); + destroy_ui(); + OBJ_cleanup(); + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); + ERR_remove_thread_state(NULL); + ERR_free_strings(); +} + +int +main(int argc, char **argv) +{ + ARGS arg; +#define PROG_NAME_SIZE 39 + char pname[PROG_NAME_SIZE + 1]; + FUNCTION f, *fp; + const char *prompt; + char buf[1024]; + char *to_free = NULL; + int n, i, ret = 0; + char *p; + LHASH_OF(FUNCTION) * prog = NULL; + long errline; + + arg.data = NULL; + arg.count = 0; + + if (pledge("stdio inet dns rpath wpath cpath proc flock tty", NULL) == -1) { + fprintf(stderr, "openssl: pledge: %s\n", strerror(errno)); + exit(1); + } + + bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); + if (bio_err == NULL) { + fprintf(stderr, "openssl: failed to initialise bio_err\n"); + exit(1); + } + + if (BIO_sock_init() != 1) { + BIO_printf(bio_err, "BIO_sock_init failed\n"); + exit(1); + } + + CRYPTO_set_locking_callback(lock_dbg_cb); + + openssl_startup(); + + /* Lets load up our environment a little */ + p = getenv("OPENSSL_CONF"); + if (p == NULL) { + p = to_free = make_config_name(); + if (p == NULL) { + BIO_printf(bio_err, "error making config file name\n"); + goto end; + } + } + + default_config_file = p; + + config = NCONF_new(NULL); + i = NCONF_load(config, p, &errline); + if (i == 0) { + if (ERR_GET_REASON(ERR_peek_last_error()) == + CONF_R_NO_SUCH_FILE) { + BIO_printf(bio_err, + "WARNING: can't open config file: %s\n", p); + ERR_clear_error(); + NCONF_free(config); + config = NULL; + } else { + ERR_print_errors(bio_err); + NCONF_free(config); + exit(1); + } + } + + if (!load_config(bio_err, NULL)) { + BIO_printf(bio_err, "failed to load configuration\n"); + goto end; + } + + prog = prog_init(); + + /* first check the program name */ + program_name(argv[0], pname, sizeof pname); + + f.name = pname; + fp = lh_FUNCTION_retrieve(prog, &f); + if (fp != NULL) { + argv[0] = pname; + + single_execution = 1; + ret = fp->func(argc, argv); + goto end; + } + /* + * ok, now check that there are not arguments, if there are, run with + * them, shifting the ssleay off the front + */ + if (argc != 1) { + argc--; + argv++; + + single_execution = 1; + ret = do_cmd(prog, argc, argv); + if (ret < 0) + ret = 0; + goto end; + } + /* ok, lets enter the old 'OpenSSL>' mode */ + + for (;;) { + ret = 0; + p = buf; + n = sizeof buf; + i = 0; + for (;;) { + p[0] = '\0'; + if (i++) + prompt = ">"; + else + prompt = "OpenSSL> "; + fputs(prompt, stdout); + fflush(stdout); + if (!fgets(p, n, stdin)) + goto end; + if (p[0] == '\0') + goto end; + i = strlen(p); + if (i <= 1) + break; + if (p[i - 2] != '\\') + break; + i -= 2; + p += i; + n -= i; + } + if (!chopup_args(&arg, buf, &argc, &argv)) + break; + + ret = do_cmd(prog, argc, argv); + if (ret < 0) { + ret = 0; + goto end; + } + if (ret != 0) + BIO_printf(bio_err, "error in %s\n", argv[0]); + (void) BIO_flush(bio_err); + } + BIO_printf(bio_err, "bad exit\n"); + ret = 1; + +end: + free(to_free); + + if (config != NULL) { + NCONF_free(config); + config = NULL; + } + if (prog != NULL) + lh_FUNCTION_free(prog); + free(arg.data); + + openssl_shutdown(); + + if (bio_err != NULL) { + BIO_free(bio_err); + bio_err = NULL; + } + return (ret); +} + +#define LIST_STANDARD_COMMANDS "list-standard-commands" +#define LIST_MESSAGE_DIGEST_COMMANDS "list-message-digest-commands" +#define LIST_MESSAGE_DIGEST_ALGORITHMS "list-message-digest-algorithms" +#define LIST_CIPHER_COMMANDS "list-cipher-commands" +#define LIST_CIPHER_ALGORITHMS "list-cipher-algorithms" +#define LIST_PUBLIC_KEY_ALGORITHMS "list-public-key-algorithms" + + +static int +do_cmd(LHASH_OF(FUNCTION) * prog, int argc, char *argv[]) +{ + FUNCTION f, *fp; + int i, ret = 1, tp, nl; + + if ((argc <= 0) || (argv[0] == NULL)) { + ret = 0; + goto end; + } + f.name = argv[0]; + fp = lh_FUNCTION_retrieve(prog, &f); + if (fp == NULL) { + if (EVP_get_digestbyname(argv[0])) { + f.type = FUNC_TYPE_MD; + f.func = dgst_main; + fp = &f; + } else if (EVP_get_cipherbyname(argv[0])) { + f.type = FUNC_TYPE_CIPHER; + f.func = enc_main; + fp = &f; + } + } + if (fp != NULL) { + ret = fp->func(argc, argv); + } else if ((strncmp(argv[0], "no-", 3)) == 0) { + BIO *bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE); + f.name = argv[0] + 3; + ret = (lh_FUNCTION_retrieve(prog, &f) != NULL); + if (!ret) + BIO_printf(bio_stdout, "%s\n", argv[0]); + else + BIO_printf(bio_stdout, "%s\n", argv[0] + 3); + BIO_free_all(bio_stdout); + goto end; + } else if ((strcmp(argv[0], "quit") == 0) || + (strcmp(argv[0], "q") == 0) || + (strcmp(argv[0], "exit") == 0) || + (strcmp(argv[0], "bye") == 0)) { + ret = -1; + goto end; + } else if ((strcmp(argv[0], LIST_STANDARD_COMMANDS) == 0) || + (strcmp(argv[0], LIST_MESSAGE_DIGEST_COMMANDS) == 0) || + (strcmp(argv[0], LIST_MESSAGE_DIGEST_ALGORITHMS) == 0) || + (strcmp(argv[0], LIST_CIPHER_COMMANDS) == 0) || + (strcmp(argv[0], LIST_CIPHER_ALGORITHMS) == 0) || + (strcmp(argv[0], LIST_PUBLIC_KEY_ALGORITHMS) == 0)) { + int list_type; + BIO *bio_stdout; + + if (strcmp(argv[0], LIST_STANDARD_COMMANDS) == 0) + list_type = FUNC_TYPE_GENERAL; + else if (strcmp(argv[0], LIST_MESSAGE_DIGEST_COMMANDS) == 0) + list_type = FUNC_TYPE_MD; + else if (strcmp(argv[0], LIST_MESSAGE_DIGEST_ALGORITHMS) == 0) + list_type = FUNC_TYPE_MD_ALG; + else if (strcmp(argv[0], LIST_PUBLIC_KEY_ALGORITHMS) == 0) + list_type = FUNC_TYPE_PKEY; + else if (strcmp(argv[0], LIST_CIPHER_ALGORITHMS) == 0) + list_type = FUNC_TYPE_CIPHER_ALG; + else /* strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0 */ + list_type = FUNC_TYPE_CIPHER; + bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE); + + if (list_type == FUNC_TYPE_PKEY) + list_pkey(bio_stdout); + if (list_type == FUNC_TYPE_MD_ALG) + list_md(bio_stdout); + if (list_type == FUNC_TYPE_CIPHER_ALG) + list_cipher(bio_stdout); + else { + for (fp = functions; fp->name != NULL; fp++) + if (fp->type == list_type) + BIO_printf(bio_stdout, "%s\n", + fp->name); + } + BIO_free_all(bio_stdout); + ret = 0; + goto end; + } else { + BIO_printf(bio_err, + "openssl:Error: '%s' is an invalid command.\n", + argv[0]); + BIO_printf(bio_err, "\nStandard commands"); + i = 0; + tp = 0; + for (fp = functions; fp->name != NULL; fp++) { + nl = 0; +#ifdef OPENSSL_NO_CAMELLIA + if (((i++) % 5) == 0) +#else + if (((i++) % 4) == 0) +#endif + { + BIO_printf(bio_err, "\n"); + nl = 1; + } + if (fp->type != tp) { + tp = fp->type; + if (!nl) + BIO_printf(bio_err, "\n"); + if (tp == FUNC_TYPE_MD) { + i = 1; + BIO_printf(bio_err, + "\nMessage Digest commands (see the `dgst' command for more details)\n"); + } else if (tp == FUNC_TYPE_CIPHER) { + i = 1; + BIO_printf(bio_err, "\nCipher commands (see the `enc' command for more details)\n"); + } + } +#ifdef OPENSSL_NO_CAMELLIA + BIO_printf(bio_err, "%-15s", fp->name); +#else + BIO_printf(bio_err, "%-18s", fp->name); +#endif + } + BIO_printf(bio_err, "\n\n"); + ret = 0; + } +end: + return (ret); +} + +static int +SortFnByName(const void *_f1, const void *_f2) +{ + const FUNCTION *f1 = _f1; + const FUNCTION *f2 = _f2; + + if (f1->type != f2->type) + return f1->type - f2->type; + return strcmp(f1->name, f2->name); +} + +static void +list_pkey(BIO * out) +{ + int i; + + for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) { + const EVP_PKEY_ASN1_METHOD *ameth; + int pkey_id, pkey_base_id, pkey_flags; + const char *pinfo, *pem_str; + ameth = EVP_PKEY_asn1_get0(i); + EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags, + &pinfo, &pem_str, ameth); + if (pkey_flags & ASN1_PKEY_ALIAS) { + BIO_printf(out, "Name: %s\n", + OBJ_nid2ln(pkey_id)); + BIO_printf(out, "\tType: Alias to %s\n", + OBJ_nid2ln(pkey_base_id)); + } else { + BIO_printf(out, "Name: %s\n", pinfo); + BIO_printf(out, "\tType: %s Algorithm\n", + pkey_flags & ASN1_PKEY_DYNAMIC ? + "External" : "Builtin"); + BIO_printf(out, "\tOID: %s\n", OBJ_nid2ln(pkey_id)); + if (pem_str == NULL) + pem_str = "(none)"; + BIO_printf(out, "\tPEM string: %s\n", pem_str); + } + + } +} + +static void +list_cipher_fn(const EVP_CIPHER * c, const char *from, const char *to, + void *arg) +{ + if (c) + BIO_printf(arg, "%s\n", EVP_CIPHER_name(c)); + else { + if (!from) + from = ""; + if (!to) + to = ""; + BIO_printf(arg, "%s => %s\n", from, to); + } +} + +static void +list_cipher(BIO * out) +{ + EVP_CIPHER_do_all_sorted(list_cipher_fn, out); +} + +static void +list_md_fn(const EVP_MD * m, const char *from, const char *to, void *arg) +{ + if (m) + BIO_printf(arg, "%s\n", EVP_MD_name(m)); + else { + if (!from) + from = ""; + if (!to) + to = ""; + BIO_printf(arg, "%s => %s\n", from, to); + } +} + +static void +list_md(BIO * out) +{ + EVP_MD_do_all_sorted(list_md_fn, out); +} + +static int +function_cmp(const FUNCTION * a, const FUNCTION * b) +{ + return strncmp(a->name, b->name, 8); +} + +static IMPLEMENT_LHASH_COMP_FN(function, FUNCTION) + +static unsigned long +function_hash(const FUNCTION * a) +{ + return lh_strhash(a->name); +} + +static IMPLEMENT_LHASH_HASH_FN(function, FUNCTION) + +static LHASH_OF(FUNCTION) * +prog_init(void) +{ + LHASH_OF(FUNCTION) * ret; + FUNCTION *f; + size_t i; + + /* Purely so it looks nice when the user hits ? */ + for (i = 0, f = functions; f->name != NULL; ++f, ++i) + ; + qsort(functions, i, sizeof *functions, SortFnByName); + + if ((ret = lh_FUNCTION_new()) == NULL) + return (NULL); + + for (f = functions; f->name != NULL; f++) + (void) lh_FUNCTION_insert(ret, f); + return (ret); +} diff --git a/crypto/libressl/apps/openssl/openssl.cnf b/crypto/libressl/apps/openssl/openssl.cnf new file mode 100644 index 0000000000..8ce83bf90d --- /dev/null +++ b/crypto/libressl/apps/openssl/openssl.cnf @@ -0,0 +1,24 @@ +[ req ] +#default_bits = 2048 +#default_md = sha256 +#default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +attributes = req_attributes + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_min = 2 +countryName_max = 2 +stateOrProvinceName = State or Province Name (full name) +localityName = Locality Name (eg, city) +0.organizationName = Organization Name (eg, company) +organizationalUnitName = Organizational Unit Name (eg, section) +commonName = Common Name (eg, fully qualified host name) +commonName_max = 64 +emailAddress = Email Address +emailAddress_max = 64 + +[ req_attributes ] +challengePassword = A challenge password +challengePassword_min = 4 +challengePassword_max = 20 diff --git a/crypto/libressl/apps/openssl/passwd.c b/crypto/libressl/apps/openssl/passwd.c new file mode 100644 index 0000000000..31052a685c --- /dev/null +++ b/crypto/libressl/apps/openssl/passwd.c @@ -0,0 +1,491 @@ +/* $OpenBSD: passwd.c,v 1.6 2015/10/17 07:51:10 semarie Exp $ */ + +#if defined OPENSSL_NO_MD5 +#define NO_MD5CRYPT_1 +#endif + +#if !defined(OPENSSL_NO_DES) || !defined(NO_MD5CRYPT_1) + +#include +#include + +#include "apps.h" + +#include +#include +#include + +#ifndef OPENSSL_NO_DES +#include +#endif + +#ifndef NO_MD5CRYPT_1 +#include +#endif + +static unsigned const char cov_2char[64] = { + /* from crypto/des/fcrypt.c */ + 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, + 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, + 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, + 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, + 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, + 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A +}; + +static int +do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p, + char *passwd, BIO * out, int quiet, int table, int reverse, + size_t pw_maxlen, int usecrypt, int use1, int useapr1); + +static struct { + char *infile; + int in_stdin; + int noverify; + int quiet; + int reverse; + char *salt; + int table; + int use1; + int useapr1; + int usecrypt; +} passwd_config; + +static struct option passwd_options[] = { +#ifndef NO_MD5CRYPT_1 + { + .name = "1", + .desc = "Use MD5 based BSD password algorithm 1", + .type = OPTION_FLAG, + .opt.flag = &passwd_config.use1, + }, + { + .name = "apr1", + .desc = "Use apr1 algorithm (Apache variant of BSD algorithm)", + .type = OPTION_FLAG, + .opt.flag = &passwd_config.useapr1, + }, +#endif +#ifndef OPENSSL_NO_DES + { + .name = "crypt", + .desc = "Use crypt algorithm (default)", + .type = OPTION_FLAG, + .opt.flag = &passwd_config.usecrypt, + }, +#endif + { + .name = "in", + .argname = "file", + .desc = "Read passwords from specified file", + .type = OPTION_ARG, + .opt.arg = &passwd_config.infile, + }, + { + .name = "noverify", + .desc = "Do not verify password", + .type = OPTION_FLAG, + .opt.flag = &passwd_config.noverify, + }, + { + .name = "quiet", + .desc = "Do not output warnings", + .type = OPTION_FLAG, + .opt.flag = &passwd_config.quiet, + }, + { + .name = "reverse", + .desc = "Reverse table columns (requires -table)", + .type = OPTION_FLAG, + .opt.flag = &passwd_config.reverse, + }, + { + .name = "salt", + .argname = "string", + .desc = "Use specified salt", + .type = OPTION_ARG, + .opt.arg = &passwd_config.salt, + }, + { + .name = "stdin", + .desc = "Read passwords from stdin", + .type = OPTION_FLAG, + .opt.flag = &passwd_config.in_stdin, + }, + { + .name = "table", + .desc = "Output cleartext and hashed passwords (tab separated)", + .type = OPTION_FLAG, + .opt.flag = &passwd_config.table, + }, + { NULL }, +}; + +static void +passwd_usage(void) +{ + fprintf(stderr, "usage: passwd [-1 | -apr1 | -crypt] [-in file] " + "[-noverify] [-quiet]\n" + " [-reverse] [-salt string] [-stdin] [-table] [password]\n\n"); + options_usage(passwd_options); +} + +int +passwd_main(int argc, char **argv) +{ + char *passwd = NULL, **passwds = NULL; + char *salt_malloc = NULL, *passwd_malloc = NULL; + size_t passwd_malloc_size = 0; + BIO *in = NULL, *out = NULL; + int badopt = 0; + int passed_salt = 0; + size_t pw_maxlen = 0; + int argsused; + int ret = 1; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + memset(&passwd_config, 0, sizeof(passwd_config)); + + if (options_parse(argc, argv, passwd_options, NULL, &argsused) != 0) { + passwd_usage(); + goto err; + } + + if (argsused < argc) + passwds = &argv[argsused]; + if (passwd_config.salt != NULL) + passed_salt = 1; + + if (!passwd_config.usecrypt && !passwd_config.use1 && + !passwd_config.useapr1) + passwd_config.usecrypt = 1; /* use default */ + if (passwd_config.usecrypt + passwd_config.use1 + + passwd_config.useapr1 > 1) + badopt = 1; /* conflicting options */ + + /* Reject unsupported algorithms */ +#ifdef OPENSSL_NO_DES + if (passwd_config.usecrypt) + badopt = 1; +#endif +#ifdef NO_MD5CRYPT_1 + if (passwd_config.use1 || passwd_config.useapr1) + badopt = 1; +#endif + + if (badopt) { + passwd_usage(); + goto err; + } + + if ((out = BIO_new(BIO_s_file())) == NULL) + goto err; + BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT); + + if (passwd_config.infile != NULL || passwd_config.in_stdin) { + if ((in = BIO_new(BIO_s_file())) == NULL) + goto err; + if (passwd_config.infile != NULL) { + assert(passwd_config.in_stdin == 0); + if (BIO_read_filename(in, passwd_config.infile) <= 0) + goto err; + } else { + assert(passwd_config.in_stdin); + BIO_set_fp(in, stdin, BIO_NOCLOSE); + } + } + if (passwd_config.usecrypt) + pw_maxlen = 8; + else if (passwd_config.use1 || passwd_config.useapr1) + pw_maxlen = 256;/* arbitrary limit, should be enough for most + * passwords */ + + if (passwds == NULL) { + /* no passwords on the command line */ + + passwd_malloc_size = pw_maxlen + 2; + /* longer than necessary so that we can warn about truncation */ + passwd = passwd_malloc = malloc(passwd_malloc_size); + if (passwd_malloc == NULL) + goto err; + } + if (in == NULL && passwds == NULL) { + /* build a null-terminated list */ + static char *passwds_static[2] = {NULL, NULL}; + + passwds = passwds_static; + if (in == NULL) + if (EVP_read_pw_string(passwd_malloc, + passwd_malloc_size, "Password: ", + !(passed_salt || passwd_config.noverify)) != 0) + goto err; + passwds[0] = passwd_malloc; + } + if (in == NULL) { + assert(passwds != NULL); + assert(*passwds != NULL); + + do { /* loop over list of passwords */ + passwd = *passwds++; + if (!do_passwd(passed_salt, &passwd_config.salt, + &salt_malloc, passwd, out, passwd_config.quiet, + passwd_config.table, passwd_config.reverse, + pw_maxlen, passwd_config.usecrypt, + passwd_config.use1, passwd_config.useapr1)) + goto err; + } while (*passwds != NULL); + } else { + int done; + + assert(passwd != NULL); + do { + int r = BIO_gets(in, passwd, pw_maxlen + 1); + if (r > 0) { + char *c = (strchr(passwd, '\n')); + if (c != NULL) + *c = 0; /* truncate at newline */ + else { + /* ignore rest of line */ + char trash[BUFSIZ]; + do + r = BIO_gets(in, trash, sizeof trash); + while ((r > 0) && (!strchr(trash, '\n'))); + } + + if (!do_passwd(passed_salt, &passwd_config.salt, + &salt_malloc, passwd, out, + passwd_config.quiet, passwd_config.table, + passwd_config.reverse, pw_maxlen, + passwd_config.usecrypt, passwd_config.use1, + passwd_config.useapr1)) + goto err; + } + done = (r <= 0); + } while (!done); + } + ret = 0; + +err: + ERR_print_errors(bio_err); + + free(salt_malloc); + free(passwd_malloc); + + BIO_free(in); + BIO_free_all(out); + + return (ret); +} + + +#ifndef NO_MD5CRYPT_1 +/* MD5-based password algorithm (should probably be available as a library + * function; then the static buffer would not be acceptable). + * For magic string "1", this should be compatible to the MD5-based BSD + * password algorithm. + * For 'magic' string "apr1", this is compatible to the MD5-based Apache + * password algorithm. + * (Apparently, the Apache password algorithm is identical except that the + * 'magic' string was changed -- the laziest application of the NIH principle + * I've ever encountered.) + */ +static char * +md5crypt(const char *passwd, const char *magic, const char *salt) +{ + static char out_buf[6 + 9 + 24 + 2]; /* "$apr1$..salt..$.......md5h + * ash..........\0" */ + unsigned char buf[MD5_DIGEST_LENGTH]; + char *salt_out; + int n; + unsigned int i; + EVP_MD_CTX md, md2; + size_t passwd_len, salt_len; + + passwd_len = strlen(passwd); + out_buf[0] = '$'; + out_buf[1] = 0; + assert(strlen(magic) <= 4); /* "1" or "apr1" */ + strlcat(out_buf, magic, sizeof(out_buf)); + strlcat(out_buf, "$", sizeof(out_buf)); + strlcat(out_buf, salt, sizeof(out_buf)); + assert(strlen(out_buf) <= 6 + 8); /* "$apr1$..salt.." */ + salt_out = out_buf + 2 + strlen(magic); + salt_len = strlen(salt_out); + assert(salt_len <= 8); + + EVP_MD_CTX_init(&md); + EVP_DigestInit_ex(&md, EVP_md5(), NULL); + EVP_DigestUpdate(&md, passwd, passwd_len); + EVP_DigestUpdate(&md, "$", 1); + EVP_DigestUpdate(&md, magic, strlen(magic)); + EVP_DigestUpdate(&md, "$", 1); + EVP_DigestUpdate(&md, salt_out, salt_len); + + EVP_MD_CTX_init(&md2); + EVP_DigestInit_ex(&md2, EVP_md5(), NULL); + EVP_DigestUpdate(&md2, passwd, passwd_len); + EVP_DigestUpdate(&md2, salt_out, salt_len); + EVP_DigestUpdate(&md2, passwd, passwd_len); + EVP_DigestFinal_ex(&md2, buf, NULL); + + for (i = passwd_len; i > sizeof buf; i -= sizeof buf) + EVP_DigestUpdate(&md, buf, sizeof buf); + EVP_DigestUpdate(&md, buf, i); + + n = passwd_len; + while (n) { + EVP_DigestUpdate(&md, (n & 1) ? "\0" : passwd, 1); + n >>= 1; + } + EVP_DigestFinal_ex(&md, buf, NULL); + + for (i = 0; i < 1000; i++) { + EVP_DigestInit_ex(&md2, EVP_md5(), NULL); + EVP_DigestUpdate(&md2, (i & 1) ? (unsigned const char *) passwd : buf, + (i & 1) ? passwd_len : sizeof buf); + if (i % 3) + EVP_DigestUpdate(&md2, salt_out, salt_len); + if (i % 7) + EVP_DigestUpdate(&md2, passwd, passwd_len); + EVP_DigestUpdate(&md2, (i & 1) ? buf : (unsigned const char *) passwd, + (i & 1) ? sizeof buf : passwd_len); + EVP_DigestFinal_ex(&md2, buf, NULL); + } + EVP_MD_CTX_cleanup(&md2); + + { + /* transform buf into output string */ + + unsigned char buf_perm[sizeof buf]; + int dest, source; + char *output; + + /* silly output permutation */ + for (dest = 0, source = 0; dest < 14; dest++, source = (source + 6) % 17) + buf_perm[dest] = buf[source]; + buf_perm[14] = buf[5]; + buf_perm[15] = buf[11]; + assert(16 == sizeof buf_perm); + + output = salt_out + salt_len; + assert(output == out_buf + strlen(out_buf)); + + *output++ = '$'; + + for (i = 0; i < 15; i += 3) { + *output++ = cov_2char[buf_perm[i + 2] & 0x3f]; + *output++ = cov_2char[((buf_perm[i + 1] & 0xf) << 2) | + (buf_perm[i + 2] >> 6)]; + *output++ = cov_2char[((buf_perm[i] & 3) << 4) | + (buf_perm[i + 1] >> 4)]; + *output++ = cov_2char[buf_perm[i] >> 2]; + } + assert(i == 15); + *output++ = cov_2char[buf_perm[i] & 0x3f]; + *output++ = cov_2char[buf_perm[i] >> 6]; + *output = 0; + assert(strlen(out_buf) < sizeof(out_buf)); + } + EVP_MD_CTX_cleanup(&md); + + return out_buf; +} +#endif + + +static int +do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p, + char *passwd, BIO * out, int quiet, int table, int reverse, + size_t pw_maxlen, int usecrypt, int use1, int useapr1) +{ + char *hash = NULL; + + assert(salt_p != NULL); + assert(salt_malloc_p != NULL); + + /* first make sure we have a salt */ + if (!passed_salt) { +#ifndef OPENSSL_NO_DES + if (usecrypt) { + if (*salt_malloc_p == NULL) { + *salt_p = *salt_malloc_p = malloc(3); + if (*salt_malloc_p == NULL) + goto err; + } + arc4random_buf(*salt_p, 2); + (*salt_p)[0] = cov_2char[(*salt_p)[0] & 0x3f]; /* 6 bits */ + (*salt_p)[1] = cov_2char[(*salt_p)[1] & 0x3f]; /* 6 bits */ + (*salt_p)[2] = 0; + } +#endif /* !OPENSSL_NO_DES */ + +#ifndef NO_MD5CRYPT_1 + if (use1 || useapr1) { + int i; + + if (*salt_malloc_p == NULL) { + *salt_p = *salt_malloc_p = malloc(9); + if (*salt_malloc_p == NULL) + goto err; + } + arc4random_buf(*salt_p, 8); + + for (i = 0; i < 8; i++) + (*salt_p)[i] = cov_2char[(*salt_p)[i] & 0x3f]; /* 6 bits */ + (*salt_p)[8] = 0; + } +#endif /* !NO_MD5CRYPT_1 */ + } + assert(*salt_p != NULL); + + /* truncate password if necessary */ + if ((strlen(passwd) > pw_maxlen)) { + if (!quiet) + /* + * XXX: really we should know how to print a size_t, + * not cast it + */ + BIO_printf(bio_err, "Warning: truncating password to %u characters\n", (unsigned) pw_maxlen); + passwd[pw_maxlen] = 0; + } + assert(strlen(passwd) <= pw_maxlen); + + /* now compute password hash */ +#ifndef OPENSSL_NO_DES + if (usecrypt) + hash = DES_crypt(passwd, *salt_p); +#endif +#ifndef NO_MD5CRYPT_1 + if (use1 || useapr1) + hash = md5crypt(passwd, (use1 ? "1" : "apr1"), *salt_p); +#endif + assert(hash != NULL); + + if (table && !reverse) + BIO_printf(out, "%s\t%s\n", passwd, hash); + else if (table && reverse) + BIO_printf(out, "%s\t%s\n", hash, passwd); + else + BIO_printf(out, "%s\n", hash); + return 1; + +err: + return 0; +} +#else + +int +passwd_main(int argc, char **argv) +{ + fputs("Program not available.\n", stderr) + return (1); +} +#endif diff --git a/crypto/libressl/apps/openssl/pkcs12.c b/crypto/libressl/apps/openssl/pkcs12.c new file mode 100644 index 0000000000..705575eab6 --- /dev/null +++ b/crypto/libressl/apps/openssl/pkcs12.c @@ -0,0 +1,896 @@ +/* $OpenBSD: pkcs12.c,v 1.6 2015/10/17 07:51:10 semarie Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1) + +#include +#include +#include + +#include "apps.h" + +#include +#include +#include +#include + +const EVP_CIPHER *enc; + +#define NOKEYS 0x1 +#define NOCERTS 0x2 +#define INFO 0x4 +#define CLCERTS 0x8 +#define CACERTS 0x10 + +int get_cert_chain(X509 * cert, X509_STORE * store, STACK_OF(X509) ** chain); +int dump_certs_keys_p12(BIO * out, PKCS12 * p12, char *pass, int passlen, + int options, char *pempass); +int dump_certs_pkeys_bags(BIO * out, STACK_OF(PKCS12_SAFEBAG) * bags, char *pass, + int passlen, int options, char *pempass); +int dump_certs_pkeys_bag(BIO * out, PKCS12_SAFEBAG * bags, char *pass, int passlen, + int options, char *pempass); +int print_attribs(BIO * out, STACK_OF(X509_ATTRIBUTE) * attrlst, const char *name); +void hex_prin(BIO * out, unsigned char *buf, int len); +int alg_print(BIO * x, X509_ALGOR * alg); +int cert_load(BIO * in, STACK_OF(X509) * sk); +static int set_pbe(BIO * err, int *ppbe, const char *str); + +int +pkcs12_main(int argc, char **argv) +{ + char *infile = NULL, *outfile = NULL, *keyname = NULL; + char *certfile = NULL; + BIO *in = NULL, *out = NULL; + char **args; + char *name = NULL; + char *csp_name = NULL; + int add_lmk = 0; + PKCS12 *p12 = NULL; + char pass[50], macpass[50]; + int export_cert = 0; + int options = 0; + int chain = 0; + int badarg = 0; + int iter = PKCS12_DEFAULT_ITER; + int maciter = PKCS12_DEFAULT_ITER; + int twopass = 0; + int keytype = 0; + int cert_pbe; + int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + int ret = 1; + int macver = 1; + int noprompt = 0; + STACK_OF(OPENSSL_STRING) * canames = NULL; + char *cpass = NULL, *mpass = NULL; + char *passargin = NULL, *passargout = NULL, *passarg = NULL; + char *passin = NULL, *passout = NULL; + char *macalg = NULL; + char *CApath = NULL, *CAfile = NULL; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; + + enc = EVP_des_ede3_cbc(); + + args = argv + 1; + + while (*args) { + if (*args[0] == '-') { + if (!strcmp(*args, "-nokeys")) + options |= NOKEYS; + else if (!strcmp(*args, "-keyex")) + keytype = KEY_EX; + else if (!strcmp(*args, "-keysig")) + keytype = KEY_SIG; + else if (!strcmp(*args, "-nocerts")) + options |= NOCERTS; + else if (!strcmp(*args, "-clcerts")) + options |= CLCERTS; + else if (!strcmp(*args, "-cacerts")) + options |= CACERTS; + else if (!strcmp(*args, "-noout")) + options |= (NOKEYS | NOCERTS); + else if (!strcmp(*args, "-info")) + options |= INFO; + else if (!strcmp(*args, "-chain")) + chain = 1; + else if (!strcmp(*args, "-twopass")) + twopass = 1; + else if (!strcmp(*args, "-nomacver")) + macver = 0; + else if (!strcmp(*args, "-descert")) + cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + else if (!strcmp(*args, "-export")) + export_cert = 1; + else if (!strcmp(*args, "-des")) + enc = EVP_des_cbc(); + else if (!strcmp(*args, "-des3")) + enc = EVP_des_ede3_cbc(); +#ifndef OPENSSL_NO_IDEA + else if (!strcmp(*args, "-idea")) + enc = EVP_idea_cbc(); +#endif +#ifndef OPENSSL_NO_AES + else if (!strcmp(*args, "-aes128")) + enc = EVP_aes_128_cbc(); + else if (!strcmp(*args, "-aes192")) + enc = EVP_aes_192_cbc(); + else if (!strcmp(*args, "-aes256")) + enc = EVP_aes_256_cbc(); +#endif +#ifndef OPENSSL_NO_CAMELLIA + else if (!strcmp(*args, "-camellia128")) + enc = EVP_camellia_128_cbc(); + else if (!strcmp(*args, "-camellia192")) + enc = EVP_camellia_192_cbc(); + else if (!strcmp(*args, "-camellia256")) + enc = EVP_camellia_256_cbc(); +#endif + else if (!strcmp(*args, "-noiter")) + iter = 1; + else if (!strcmp(*args, "-maciter")) + maciter = PKCS12_DEFAULT_ITER; + else if (!strcmp(*args, "-nomaciter")) + maciter = 1; + else if (!strcmp(*args, "-nomac")) + maciter = -1; + else if (!strcmp(*args, "-macalg")) + if (args[1]) { + args++; + macalg = *args; + } else + badarg = 1; + else if (!strcmp(*args, "-nodes")) + enc = NULL; + else if (!strcmp(*args, "-certpbe")) { + if (!set_pbe(bio_err, &cert_pbe, *++args)) + badarg = 1; + } else if (!strcmp(*args, "-keypbe")) { + if (!set_pbe(bio_err, &key_pbe, *++args)) + badarg = 1; + } else if (!strcmp(*args, "-inkey")) { + if (args[1]) { + args++; + keyname = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-certfile")) { + if (args[1]) { + args++; + certfile = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-name")) { + if (args[1]) { + args++; + name = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-LMK")) + add_lmk = 1; + else if (!strcmp(*args, "-CSP")) { + if (args[1]) { + args++; + csp_name = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-caname")) { + if (args[1]) { + args++; + if (!canames) + canames = sk_OPENSSL_STRING_new_null(); + sk_OPENSSL_STRING_push(canames, *args); + } else + badarg = 1; + } else if (!strcmp(*args, "-in")) { + if (args[1]) { + args++; + infile = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-out")) { + if (args[1]) { + args++; + outfile = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-passin")) { + if (args[1]) { + args++; + passargin = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-passout")) { + if (args[1]) { + args++; + passargout = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-password")) { + if (args[1]) { + args++; + passarg = *args; + noprompt = 1; + } else + badarg = 1; + } else if (!strcmp(*args, "-CApath")) { + if (args[1]) { + args++; + CApath = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-CAfile")) { + if (args[1]) { + args++; + CAfile = *args; + } else + badarg = 1; + } else + badarg = 1; + + } else + badarg = 1; + args++; + } + + if (badarg) { + BIO_printf(bio_err, "Usage: pkcs12 [options]\n"); + BIO_printf(bio_err, "where options are\n"); + BIO_printf(bio_err, "-export output PKCS12 file\n"); + BIO_printf(bio_err, "-chain add certificate chain\n"); + BIO_printf(bio_err, "-inkey file private key if not infile\n"); + BIO_printf(bio_err, "-certfile f add all certs in f\n"); + BIO_printf(bio_err, "-CApath arg - PEM format directory of CA's\n"); + BIO_printf(bio_err, "-CAfile arg - PEM format file of CA's\n"); + BIO_printf(bio_err, "-name \"name\" use name as friendly name\n"); + BIO_printf(bio_err, "-caname \"nm\" use nm as CA friendly name (can be used more than once).\n"); + BIO_printf(bio_err, "-in infile input filename\n"); + BIO_printf(bio_err, "-out outfile output filename\n"); + BIO_printf(bio_err, "-noout don't output anything, just verify.\n"); + BIO_printf(bio_err, "-nomacver don't verify MAC.\n"); + BIO_printf(bio_err, "-nocerts don't output certificates.\n"); + BIO_printf(bio_err, "-clcerts only output client certificates.\n"); + BIO_printf(bio_err, "-cacerts only output CA certificates.\n"); + BIO_printf(bio_err, "-nokeys don't output private keys.\n"); + BIO_printf(bio_err, "-info give info about PKCS#12 structure.\n"); + BIO_printf(bio_err, "-des encrypt private keys with DES\n"); + BIO_printf(bio_err, "-des3 encrypt private keys with triple DES (default)\n"); +#ifndef OPENSSL_NO_IDEA + BIO_printf(bio_err, "-idea encrypt private keys with idea\n"); +#endif +#ifndef OPENSSL_NO_AES + BIO_printf(bio_err, "-aes128, -aes192, -aes256\n"); + BIO_printf(bio_err, " encrypt PEM output with cbc aes\n"); +#endif +#ifndef OPENSSL_NO_CAMELLIA + BIO_printf(bio_err, "-camellia128, -camellia192, -camellia256\n"); + BIO_printf(bio_err, " encrypt PEM output with cbc camellia\n"); +#endif + BIO_printf(bio_err, "-nodes don't encrypt private keys\n"); + BIO_printf(bio_err, "-noiter don't use encryption iteration\n"); + BIO_printf(bio_err, "-nomaciter don't use MAC iteration\n"); + BIO_printf(bio_err, "-maciter use MAC iteration\n"); + BIO_printf(bio_err, "-nomac don't generate MAC\n"); + BIO_printf(bio_err, "-twopass separate MAC, encryption passwords\n"); + BIO_printf(bio_err, "-descert encrypt PKCS#12 certificates with triple DES (default RC2-40)\n"); + BIO_printf(bio_err, "-certpbe alg specify certificate PBE algorithm (default RC2-40)\n"); + BIO_printf(bio_err, "-keypbe alg specify private key PBE algorithm (default 3DES)\n"); + BIO_printf(bio_err, "-macalg alg digest algorithm used in MAC (default SHA1)\n"); + BIO_printf(bio_err, "-keyex set MS key exchange type\n"); + BIO_printf(bio_err, "-keysig set MS key signature type\n"); + BIO_printf(bio_err, "-password p set import/export password source\n"); + BIO_printf(bio_err, "-passin p input file pass phrase source\n"); + BIO_printf(bio_err, "-passout p output file pass phrase source\n"); + BIO_printf(bio_err, "-CSP name Microsoft CSP name\n"); + BIO_printf(bio_err, "-LMK Add local machine keyset attribute to private key\n"); + goto end; + } + + if (passarg) { + if (export_cert) + passargout = passarg; + else + passargin = passarg; + } + if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { + BIO_printf(bio_err, "Error getting passwords\n"); + goto end; + } + if (!cpass) { + if (export_cert) + cpass = passout; + else + cpass = passin; + } + if (cpass) { + mpass = cpass; + noprompt = 1; + } else { + cpass = pass; + mpass = macpass; + } + + if (!infile) + in = BIO_new_fp(stdin, BIO_NOCLOSE); + else + in = BIO_new_file(infile, "rb"); + if (!in) { + BIO_printf(bio_err, "Error opening input file %s\n", + infile ? infile : ""); + perror(infile); + goto end; + } + + if (!outfile) { + out = BIO_new_fp(stdout, BIO_NOCLOSE); + } else + out = BIO_new_file(outfile, "wb"); + if (!out) { + BIO_printf(bio_err, "Error opening output file %s\n", + outfile ? outfile : ""); + perror(outfile); + goto end; + } + if (twopass) { + if (EVP_read_pw_string(macpass, sizeof macpass, "Enter MAC Password:", export_cert)) { + BIO_printf(bio_err, "Can't read Password\n"); + goto end; + } + } + if (export_cert) { + EVP_PKEY *key = NULL; + X509 *ucert = NULL, *x = NULL; + STACK_OF(X509) * certs = NULL; + const EVP_MD *macmd = NULL; + unsigned char *catmp = NULL; + int i; + + if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) { + BIO_printf(bio_err, "Nothing to do!\n"); + goto export_end; + } + if (options & NOCERTS) + chain = 0; + + if (!(options & NOKEYS)) { + key = load_key(bio_err, keyname ? keyname : infile, + FORMAT_PEM, 1, passin, "private key"); + if (!key) + goto export_end; + } + + /* Load in all certs in input file */ + if (!(options & NOCERTS)) { + certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, + "certificates"); + if (!certs) + goto export_end; + + if (key) { + /* Look for matching private key */ + for (i = 0; i < sk_X509_num(certs); i++) { + x = sk_X509_value(certs, i); + if (X509_check_private_key(x, key)) { + ucert = x; + /* Zero keyid and alias */ + X509_keyid_set1(ucert, NULL, 0); + X509_alias_set1(ucert, NULL, 0); + /* Remove from list */ + (void) sk_X509_delete(certs, i); + break; + } + } + if (!ucert) { + BIO_printf(bio_err, "No certificate matches private key\n"); + goto export_end; + } + } + } + + /* Add any more certificates asked for */ + if (certfile) { + STACK_OF(X509) * morecerts = NULL; + if (!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM, + NULL, "certificates from certfile"))) + goto export_end; + while (sk_X509_num(morecerts) > 0) + sk_X509_push(certs, sk_X509_shift(morecerts)); + sk_X509_free(morecerts); + } + + + /* If chaining get chain from user cert */ + if (chain) { + int vret; + STACK_OF(X509) * chain2; + X509_STORE *store = X509_STORE_new(); + if (!store) { + BIO_printf(bio_err, "Memory allocation error\n"); + goto export_end; + } + if (!X509_STORE_load_locations(store, CAfile, CApath)) + X509_STORE_set_default_paths(store); + + vret = get_cert_chain(ucert, store, &chain2); + X509_STORE_free(store); + + if (!vret) { + /* Exclude verified certificate */ + for (i = 1; i < sk_X509_num(chain2); i++) + sk_X509_push(certs, sk_X509_value(chain2, i)); + /* Free first certificate */ + X509_free(sk_X509_value(chain2, 0)); + sk_X509_free(chain2); + } else { + if (vret >= 0) + BIO_printf(bio_err, "Error %s getting chain.\n", + X509_verify_cert_error_string(vret)); + else + ERR_print_errors(bio_err); + goto export_end; + } + } + /* Add any CA names */ + + for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++) { + catmp = (unsigned char *) sk_OPENSSL_STRING_value(canames, i); + X509_alias_set1(sk_X509_value(certs, i), catmp, -1); + } + + if (csp_name && key) + EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name, + MBSTRING_ASC, (unsigned char *) csp_name, -1); + + if (add_lmk && key) + EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1); + + + if (!noprompt && + EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:", 1)) { + BIO_printf(bio_err, "Can't read Password\n"); + goto export_end; + } + if (!twopass) + strlcpy(macpass, pass, sizeof macpass); + + + p12 = PKCS12_create(cpass, name, key, ucert, certs, + key_pbe, cert_pbe, iter, -1, keytype); + + if (!p12) { + ERR_print_errors(bio_err); + goto export_end; + } + if (macalg) { + macmd = EVP_get_digestbyname(macalg); + if (!macmd) { + BIO_printf(bio_err, "Unknown digest algorithm %s\n", + macalg); + } + } + if (maciter != -1) + PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd); + + + i2d_PKCS12_bio(out, p12); + + ret = 0; + +export_end: + + if (key) + EVP_PKEY_free(key); + if (certs) + sk_X509_pop_free(certs, X509_free); + if (ucert) + X509_free(ucert); + + goto end; + + } + if (!(p12 = d2i_PKCS12_bio(in, NULL))) { + ERR_print_errors(bio_err); + goto end; + } + if (!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:", 0)) { + BIO_printf(bio_err, "Can't read Password\n"); + goto end; + } + + if (!twopass) + strlcpy(macpass, pass, sizeof macpass); + + if ((options & INFO) && p12->mac) + BIO_printf(bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get(p12->mac->iter) : 1); + if (macver) { + /* If we enter empty password try no password first */ + if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) { + /* If mac and crypto pass the same set it to NULL too */ + if (!twopass) + cpass = NULL; + } else if (!PKCS12_verify_mac(p12, mpass, -1)) { + BIO_printf(bio_err, "Mac verify error: invalid password?\n"); + ERR_print_errors(bio_err); + goto end; + } + BIO_printf(bio_err, "MAC verified OK\n"); + } + if (!dump_certs_keys_p12(out, p12, cpass, -1, options, passout)) { + BIO_printf(bio_err, "Error outputting keys and certificates\n"); + ERR_print_errors(bio_err); + goto end; + } + ret = 0; +end: + if (p12) + PKCS12_free(p12); + BIO_free(in); + BIO_free_all(out); + if (canames) + sk_OPENSSL_STRING_free(canames); + free(passin); + free(passout); + + return (ret); +} + +int +dump_certs_keys_p12(BIO * out, PKCS12 * p12, char *pass, + int passlen, int options, char *pempass) +{ + STACK_OF(PKCS7) * asafes = NULL; + STACK_OF(PKCS12_SAFEBAG) * bags; + int i, bagnid; + int ret = 0; + PKCS7 *p7; + + if (!(asafes = PKCS12_unpack_authsafes(p12))) + return 0; + for (i = 0; i < sk_PKCS7_num(asafes); i++) { + p7 = sk_PKCS7_value(asafes, i); + bagnid = OBJ_obj2nid(p7->type); + if (bagnid == NID_pkcs7_data) { + bags = PKCS12_unpack_p7data(p7); + if (options & INFO) + BIO_printf(bio_err, "PKCS7 Data\n"); + } else if (bagnid == NID_pkcs7_encrypted) { + if (options & INFO) { + BIO_printf(bio_err, "PKCS7 Encrypted data: "); + alg_print(bio_err, + p7->d.encrypted->enc_data->algorithm); + } + bags = PKCS12_unpack_p7encdata(p7, pass, passlen); + } else + continue; + if (!bags) + goto err; + if (!dump_certs_pkeys_bags(out, bags, pass, passlen, + options, pempass)) { + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + goto err; + } + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + bags = NULL; + } + ret = 1; + +err: + + if (asafes) + sk_PKCS7_pop_free(asafes, PKCS7_free); + return ret; +} + +int +dump_certs_pkeys_bags(BIO * out, STACK_OF(PKCS12_SAFEBAG) * bags, + char *pass, int passlen, int options, char *pempass) +{ + int i; + for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { + if (!dump_certs_pkeys_bag(out, + sk_PKCS12_SAFEBAG_value(bags, i), + pass, passlen, + options, pempass)) + return 0; + } + return 1; +} + +int +dump_certs_pkeys_bag(BIO * out, PKCS12_SAFEBAG * bag, char *pass, + int passlen, int options, char *pempass) +{ + EVP_PKEY *pkey; + PKCS8_PRIV_KEY_INFO *p8; + X509 *x509; + + switch (M_PKCS12_bag_type(bag)) { + case NID_keyBag: + if (options & INFO) + BIO_printf(bio_err, "Key bag\n"); + if (options & NOKEYS) + return 1; + print_attribs(out, bag->attrib, "Bag Attributes"); + p8 = bag->value.keybag; + if (!(pkey = EVP_PKCS82PKEY(p8))) + return 0; + print_attribs(out, p8->attributes, "Key Attributes"); + PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass); + EVP_PKEY_free(pkey); + break; + + case NID_pkcs8ShroudedKeyBag: + if (options & INFO) { + BIO_printf(bio_err, "Shrouded Keybag: "); + alg_print(bio_err, bag->value.shkeybag->algor); + } + if (options & NOKEYS) + return 1; + print_attribs(out, bag->attrib, "Bag Attributes"); + if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) + return 0; + if (!(pkey = EVP_PKCS82PKEY(p8))) { + PKCS8_PRIV_KEY_INFO_free(p8); + return 0; + } + print_attribs(out, p8->attributes, "Key Attributes"); + PKCS8_PRIV_KEY_INFO_free(p8); + PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass); + EVP_PKEY_free(pkey); + break; + + case NID_certBag: + if (options & INFO) + BIO_printf(bio_err, "Certificate bag\n"); + if (options & NOCERTS) + return 1; + if (PKCS12_get_attr(bag, NID_localKeyID)) { + if (options & CACERTS) + return 1; + } else if (options & CLCERTS) + return 1; + print_attribs(out, bag->attrib, "Bag Attributes"); + if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) + return 1; + if (!(x509 = PKCS12_certbag2x509(bag))) + return 0; + dump_cert_text(out, x509); + PEM_write_bio_X509(out, x509); + X509_free(x509); + break; + + case NID_safeContentsBag: + if (options & INFO) + BIO_printf(bio_err, "Safe Contents bag\n"); + print_attribs(out, bag->attrib, "Bag Attributes"); + return dump_certs_pkeys_bags(out, bag->value.safes, pass, + passlen, options, pempass); + + default: + BIO_printf(bio_err, "Warning unsupported bag type: "); + i2a_ASN1_OBJECT(bio_err, bag->type); + BIO_printf(bio_err, "\n"); + return 1; + break; + } + return 1; +} + +/* Given a single certificate return a verified chain or NULL if error */ + +/* Hope this is OK .... */ + +int +get_cert_chain(X509 * cert, X509_STORE * store, STACK_OF(X509) ** chain) +{ + X509_STORE_CTX store_ctx; + STACK_OF(X509) * chn; + int i = 0; + + /* + * FIXME: Should really check the return status of + * X509_STORE_CTX_init for an error, but how that fits into the + * return value of this function is less obvious. + */ + X509_STORE_CTX_init(&store_ctx, store, cert, NULL); + if (X509_verify_cert(&store_ctx) <= 0) { + i = X509_STORE_CTX_get_error(&store_ctx); + if (i == 0) + /* + * avoid returning 0 if X509_verify_cert() did not + * set an appropriate error value in the context + */ + i = -1; + chn = NULL; + goto err; + } else + chn = X509_STORE_CTX_get1_chain(&store_ctx); +err: + X509_STORE_CTX_cleanup(&store_ctx); + *chain = chn; + + return i; +} + +int +alg_print(BIO * x, X509_ALGOR * alg) +{ + PBEPARAM *pbe; + const unsigned char *p; + p = alg->parameter->value.sequence->data; + pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length); + if (!pbe) + return 1; + BIO_printf(bio_err, "%s, Iteration %ld\n", + OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)), + ASN1_INTEGER_get(pbe->iter)); + PBEPARAM_free(pbe); + return 1; +} + +/* Load all certificates from a given file */ + +int +cert_load(BIO * in, STACK_OF(X509) * sk) +{ + int ret; + X509 *cert; + ret = 0; + while ((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) { + ret = 1; + sk_X509_push(sk, cert); + } + if (ret) + ERR_clear_error(); + return ret; +} + +/* Generalised attribute print: handle PKCS#8 and bag attributes */ + +int +print_attribs(BIO * out, STACK_OF(X509_ATTRIBUTE) * attrlst, const char *name) +{ + X509_ATTRIBUTE *attr; + ASN1_TYPE *av; + char *value; + int i, attr_nid; + if (!attrlst) { + BIO_printf(out, "%s: \n", name); + return 1; + } + if (!sk_X509_ATTRIBUTE_num(attrlst)) { + BIO_printf(out, "%s: \n", name); + return 1; + } + BIO_printf(out, "%s\n", name); + for (i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) { + attr = sk_X509_ATTRIBUTE_value(attrlst, i); + attr_nid = OBJ_obj2nid(attr->object); + BIO_printf(out, " "); + if (attr_nid == NID_undef) { + i2a_ASN1_OBJECT(out, attr->object); + BIO_printf(out, ": "); + } else + BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid)); + + if (sk_ASN1_TYPE_num(attr->value.set)) { + av = sk_ASN1_TYPE_value(attr->value.set, 0); + switch (av->type) { + case V_ASN1_BMPSTRING: + value = OPENSSL_uni2asc(av->value.bmpstring->data, + av->value.bmpstring->length); + BIO_printf(out, "%s\n", value); + free(value); + break; + + case V_ASN1_OCTET_STRING: + hex_prin(out, av->value.octet_string->data, + av->value.octet_string->length); + BIO_printf(out, "\n"); + break; + + case V_ASN1_BIT_STRING: + hex_prin(out, av->value.bit_string->data, + av->value.bit_string->length); + BIO_printf(out, "\n"); + break; + + default: + BIO_printf(out, "\n", av->type); + break; + } + } else + BIO_printf(out, "\n"); + } + return 1; +} + +void +hex_prin(BIO * out, unsigned char *buf, int len) +{ + int i; + for (i = 0; i < len; i++) + BIO_printf(out, "%02X ", buf[i]); +} + +static int +set_pbe(BIO * err, int *ppbe, const char *str) +{ + if (!str) + return 0; + if (!strcmp(str, "NONE")) { + *ppbe = -1; + return 1; + } + *ppbe = OBJ_txt2nid(str); + if (*ppbe == NID_undef) { + BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str); + return 0; + } + return 1; +} + +#endif diff --git a/crypto/libressl/apps/openssl/pkcs7.c b/crypto/libressl/apps/openssl/pkcs7.c new file mode 100644 index 0000000000..c8e197d5b8 --- /dev/null +++ b/crypto/libressl/apps/openssl/pkcs7.c @@ -0,0 +1,289 @@ +/* $OpenBSD: pkcs7.c,v 1.7 2015/10/10 22:28:51 doug Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#include "apps.h" + +#include +#include +#include +#include +#include +#include + +static struct { + char *infile; + int informat; + int noout; + char *outfile; + int outformat; + int p7_print; + int print_certs; + int text; +} pkcs7_config; + +static struct option pkcs7_options[] = { + { + .name = "in", + .argname = "file", + .desc = "Input file (default stdin)", + .type = OPTION_ARG, + .opt.arg = &pkcs7_config.infile, + }, + { + .name = "inform", + .argname = "format", + .desc = "Input format (DER or PEM (default))", + .type = OPTION_ARG_FORMAT, + .opt.value = &pkcs7_config.informat, + }, + { + .name = "noout", + .desc = "Do not output encoded version of PKCS#7 structure", + .type = OPTION_FLAG, + .opt.flag = &pkcs7_config.noout, + }, + { + .name = "out", + .argname = "file", + .desc = "Output file (default stdout)", + .type = OPTION_ARG, + .opt.arg = &pkcs7_config.outfile, + }, + { + .name = "outform", + .argname = "format", + .desc = "Output format (DER or PEM (default))", + .type = OPTION_ARG_FORMAT, + .opt.value = &pkcs7_config.outformat, + }, + { + .name = "print", + .desc = "Output ASN.1 representation of PKCS#7 structure", + .type = OPTION_FLAG, + .opt.flag = &pkcs7_config.p7_print, + }, + { + .name = "print_certs", + .desc = "Print out any certificates or CRLs contained in file", + .type = OPTION_FLAG, + .opt.flag = &pkcs7_config.print_certs, + }, + { + .name = "text", + .desc = "Print out full certificate details", + .type = OPTION_FLAG, + .opt.flag = &pkcs7_config.text, + }, + { NULL }, +}; + +static void +pkcs7_usage() +{ + fprintf(stderr, "usage: pkcs7 [-in file] " + "[-inform DER | PEM] [-noout]\n" + " [-out file] [-outform DER | PEM] [-print_certs] [-text]\n\n"); + options_usage(pkcs7_options); +} + +int +pkcs7_main(int argc, char **argv) +{ + PKCS7 *p7 = NULL; + BIO *in = NULL, *out = NULL; + int ret = 1; + int i; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + memset(&pkcs7_config, 0, sizeof(pkcs7_config)); + + pkcs7_config.informat = FORMAT_PEM; + pkcs7_config.outformat = FORMAT_PEM; + + if (options_parse(argc, argv, pkcs7_options, NULL, NULL) != 0) { + pkcs7_usage(); + goto end; + } + + in = BIO_new(BIO_s_file()); + out = BIO_new(BIO_s_file()); + if ((in == NULL) || (out == NULL)) { + ERR_print_errors(bio_err); + goto end; + } + if (pkcs7_config.infile == NULL) + BIO_set_fp(in, stdin, BIO_NOCLOSE); + else { + if (BIO_read_filename(in, pkcs7_config.infile) <= 0) { + perror(pkcs7_config.infile); + goto end; + } + } + + if (pkcs7_config.informat == FORMAT_ASN1) + p7 = d2i_PKCS7_bio(in, NULL); + else if (pkcs7_config.informat == FORMAT_PEM) + p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); + else { + BIO_printf(bio_err, "bad input format specified for pkcs7 object\n"); + goto end; + } + if (p7 == NULL) { + BIO_printf(bio_err, "unable to load PKCS7 object\n"); + ERR_print_errors(bio_err); + goto end; + } + if (pkcs7_config.outfile == NULL) { + BIO_set_fp(out, stdout, BIO_NOCLOSE); + } else { + if (BIO_write_filename(out, pkcs7_config.outfile) <= 0) { + perror(pkcs7_config.outfile); + goto end; + } + } + + if (pkcs7_config.p7_print) + PKCS7_print_ctx(out, p7, 0, NULL); + + if (pkcs7_config.print_certs) { + STACK_OF(X509) * certs = NULL; + STACK_OF(X509_CRL) * crls = NULL; + + i = OBJ_obj2nid(p7->type); + switch (i) { + case NID_pkcs7_signed: + certs = p7->d.sign->cert; + crls = p7->d.sign->crl; + break; + case NID_pkcs7_signedAndEnveloped: + certs = p7->d.signed_and_enveloped->cert; + crls = p7->d.signed_and_enveloped->crl; + break; + default: + break; + } + + if (certs != NULL) { + X509 *x; + + for (i = 0; i < sk_X509_num(certs); i++) { + x = sk_X509_value(certs, i); + if (pkcs7_config.text) + X509_print(out, x); + else + dump_cert_text(out, x); + + if (!pkcs7_config.noout) + PEM_write_bio_X509(out, x); + BIO_puts(out, "\n"); + } + } + if (crls != NULL) { + X509_CRL *crl; + + for (i = 0; i < sk_X509_CRL_num(crls); i++) { + crl = sk_X509_CRL_value(crls, i); + + X509_CRL_print(out, crl); + + if (!pkcs7_config.noout) + PEM_write_bio_X509_CRL(out, crl); + BIO_puts(out, "\n"); + } + } + ret = 0; + goto end; + } + if (!pkcs7_config.noout) { + if (pkcs7_config.outformat == FORMAT_ASN1) + i = i2d_PKCS7_bio(out, p7); + else if (pkcs7_config.outformat == FORMAT_PEM) + i = PEM_write_bio_PKCS7(out, p7); + else { + BIO_printf(bio_err, "bad output format specified for outfile\n"); + goto end; + } + + if (!i) { + BIO_printf(bio_err, "unable to write pkcs7 object\n"); + ERR_print_errors(bio_err); + goto end; + } + } + ret = 0; +end: + if (p7 != NULL) + PKCS7_free(p7); + if (in != NULL) + BIO_free(in); + if (out != NULL) + BIO_free_all(out); + + return (ret); +} diff --git a/crypto/libressl/apps/openssl/pkcs8.c b/crypto/libressl/apps/openssl/pkcs8.c new file mode 100644 index 0000000000..1a5a836b81 --- /dev/null +++ b/crypto/libressl/apps/openssl/pkcs8.c @@ -0,0 +1,419 @@ +/* $OpenBSD: pkcs8.c,v 1.8 2015/10/17 07:51:10 semarie Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999-2004. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include "apps.h" +#include "progs.h" + +#include +#include +#include +#include + +static struct { + const EVP_CIPHER *cipher; + char *infile; + int informat; + int iter; + int nocrypt; + char *outfile; + int outformat; + int p8_broken; + char *passargin; + char *passargout; + int pbe_nid; + int topk8; +} pkcs8_config; + +static int +pkcs8_opt_v1(char *arg) +{ + if ((pkcs8_config.pbe_nid = OBJ_txt2nid(arg)) == NID_undef) { + fprintf(stderr, "Unknown PBE algorithm '%s'\n", arg); + return (1); + } + + return (0); +} + +static int +pkcs8_opt_v2(char *arg) +{ + if ((pkcs8_config.cipher = EVP_get_cipherbyname(arg)) == NULL) { + fprintf(stderr, "Unknown cipher '%s'\n", arg); + return (1); + } + + return (0); +} + +static struct option pkcs8_options[] = { + { + .name = "embed", + .desc = "Generate DSA keys in a broken format", + .type = OPTION_VALUE, + .value = PKCS8_EMBEDDED_PARAM, + .opt.value = &pkcs8_config.p8_broken, + }, + { + .name = "in", + .argname = "file", + .desc = "Input file (default stdin)", + .type = OPTION_ARG, + .opt.arg = &pkcs8_config.infile, + }, + { + .name = "inform", + .argname = "format", + .desc = "Input format (DER or PEM (default))", + .type = OPTION_ARG_FORMAT, + .opt.value = &pkcs8_config.informat, + }, + { + .name = "nocrypt", + .desc = "Use or expect unencrypted private key", + .type = OPTION_FLAG, + .opt.flag = &pkcs8_config.nocrypt, + }, + { + .name = "noiter", + .desc = "Use 1 as iteration count", + .type = OPTION_VALUE, + .value = 1, + .opt.value = &pkcs8_config.iter, + }, + { + .name = "nooct", + .desc = "Generate RSA keys in a broken format (no octet)", + .type = OPTION_VALUE, + .value = PKCS8_NO_OCTET, + .opt.value = &pkcs8_config.p8_broken, + }, + { + .name = "nsdb", + .desc = "Generate DSA keys in the broken Netscape DB format", + .type = OPTION_VALUE, + .value = PKCS8_NS_DB, + .opt.value = &pkcs8_config.p8_broken, + }, + { + .name = "out", + .argname = "file", + .desc = "Output file (default stdout)", + .type = OPTION_ARG, + .opt.arg = &pkcs8_config.outfile, + }, + { + .name = "outform", + .argname = "format", + .desc = "Output format (DER or PEM (default))", + .type = OPTION_ARG_FORMAT, + .opt.value = &pkcs8_config.outformat, + }, + { + .name = "passin", + .argname = "source", + .desc = "Input file passphrase source", + .type = OPTION_ARG, + .opt.arg = &pkcs8_config.passargin, + }, + { + .name = "passout", + .argname = "source", + .desc = "Output file passphrase source", + .type = OPTION_ARG, + .opt.arg = &pkcs8_config.passargout, + }, + { + .name = "topk8", + .desc = "Read traditional format key and write PKCS#8 format" + " key", + .type = OPTION_FLAG, + .opt.flag = &pkcs8_config.topk8, + }, + { + .name = "v1", + .argname = "algorithm", + .desc = "Use PKCS#5 v1.5 or PKCS#12 with given algorithm", + .type = OPTION_ARG_FUNC, + .opt.argfunc = pkcs8_opt_v1, + }, + { + .name = "v2", + .argname = "cipher", + .desc = "Use PKCS#5 v2.0 with given cipher", + .type = OPTION_ARG_FUNC, + .opt.argfunc = pkcs8_opt_v2, + }, + { NULL }, +}; + +static void +pkcs8_usage() +{ + fprintf(stderr, "usage: pkcs8 [-embed] [-in file] " + "[-inform fmt] [-nocrypt]\n" + " [-noiter] [-nooct] [-nsdb] [-out file] [-outform fmt] " + "[-passin src]\n" + " [-passout src] [-topk8] [-v1 alg] [-v2 alg]\n\n"); + options_usage(pkcs8_options); +} + +int +pkcs8_main(int argc, char **argv) +{ + BIO *in = NULL, *out = NULL; + X509_SIG *p8 = NULL; + PKCS8_PRIV_KEY_INFO *p8inf = NULL; + EVP_PKEY *pkey = NULL; + char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL; + int ret = 1; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + memset(&pkcs8_config, 0, sizeof(pkcs8_config)); + + pkcs8_config.iter = PKCS12_DEFAULT_ITER; + pkcs8_config.informat = FORMAT_PEM; + pkcs8_config.outformat = FORMAT_PEM; + pkcs8_config.p8_broken = PKCS8_OK; + pkcs8_config.pbe_nid = -1; + + if (options_parse(argc, argv, pkcs8_options, NULL, NULL) != 0) { + pkcs8_usage(); + return (1); + } + + if (!app_passwd(bio_err, pkcs8_config.passargin, + pkcs8_config.passargout, &passin, &passout)) { + BIO_printf(bio_err, "Error getting passwords\n"); + goto end; + } + if ((pkcs8_config.pbe_nid == -1) && !pkcs8_config.cipher) + pkcs8_config.pbe_nid = NID_pbeWithMD5AndDES_CBC; + + if (pkcs8_config.infile) { + if (!(in = BIO_new_file(pkcs8_config.infile, "rb"))) { + BIO_printf(bio_err, + "Can't open input file '%s'\n", + pkcs8_config.infile); + goto end; + } + } else + in = BIO_new_fp(stdin, BIO_NOCLOSE); + + if (pkcs8_config.outfile) { + if (!(out = BIO_new_file(pkcs8_config.outfile, "wb"))) { + BIO_printf(bio_err, "Can't open output file '%s'\n", + pkcs8_config.outfile); + goto end; + } + } else { + out = BIO_new_fp(stdout, BIO_NOCLOSE); + } + if (pkcs8_config.topk8) { + pkey = load_key(bio_err, pkcs8_config.infile, + pkcs8_config.informat, 1, passin, "key"); + if (!pkey) + goto end; + if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, + pkcs8_config.p8_broken))) { + BIO_printf(bio_err, "Error converting key\n"); + ERR_print_errors(bio_err); + goto end; + } + if (pkcs8_config.nocrypt) { + if (pkcs8_config.outformat == FORMAT_PEM) + PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf); + else if (pkcs8_config.outformat == FORMAT_ASN1) + i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf); + else { + BIO_printf(bio_err, + "Bad format specified for key\n"); + goto end; + } + } else { + if (passout) + p8pass = passout; + else { + p8pass = pass; + if (EVP_read_pw_string(pass, sizeof pass, + "Enter Encryption Password:", 1)) + goto end; + } + if (!(p8 = PKCS8_encrypt(pkcs8_config.pbe_nid, + pkcs8_config.cipher, p8pass, strlen(p8pass), + NULL, 0, pkcs8_config.iter, p8inf))) { + BIO_printf(bio_err, "Error encrypting key\n"); + ERR_print_errors(bio_err); + goto end; + } + if (pkcs8_config.outformat == FORMAT_PEM) + PEM_write_bio_PKCS8(out, p8); + else if (pkcs8_config.outformat == FORMAT_ASN1) + i2d_PKCS8_bio(out, p8); + else { + BIO_printf(bio_err, + "Bad format specified for key\n"); + goto end; + } + } + + ret = 0; + goto end; + } + if (pkcs8_config.nocrypt) { + if (pkcs8_config.informat == FORMAT_PEM) + p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in, NULL, + NULL, NULL); + else if (pkcs8_config.informat == FORMAT_ASN1) + p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL); + else { + BIO_printf(bio_err, "Bad format specified for key\n"); + goto end; + } + } else { + if (pkcs8_config.informat == FORMAT_PEM) + p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL); + else if (pkcs8_config.informat == FORMAT_ASN1) + p8 = d2i_PKCS8_bio(in, NULL); + else { + BIO_printf(bio_err, "Bad format specified for key\n"); + goto end; + } + + if (!p8) { + BIO_printf(bio_err, "Error reading key\n"); + ERR_print_errors(bio_err); + goto end; + } + if (passin) + p8pass = passin; + else { + p8pass = pass; + EVP_read_pw_string(pass, sizeof pass, + "Enter Password:", 0); + } + p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass)); + } + + if (!p8inf) { + BIO_printf(bio_err, "Error decrypting key\n"); + ERR_print_errors(bio_err); + goto end; + } + if (!(pkey = EVP_PKCS82PKEY(p8inf))) { + BIO_printf(bio_err, "Error converting key\n"); + ERR_print_errors(bio_err); + goto end; + } + if (p8inf->broken) { + BIO_printf(bio_err, "Warning: broken key encoding: "); + switch (p8inf->broken) { + case PKCS8_NO_OCTET: + BIO_printf(bio_err, "No Octet String in PrivateKey\n"); + break; + + case PKCS8_EMBEDDED_PARAM: + BIO_printf(bio_err, + "DSA parameters included in PrivateKey\n"); + break; + + case PKCS8_NS_DB: + BIO_printf(bio_err, + "DSA public key include in PrivateKey\n"); + break; + + case PKCS8_NEG_PRIVKEY: + BIO_printf(bio_err, "DSA private key value is negative\n"); + break; + + default: + BIO_printf(bio_err, "Unknown broken type\n"); + break; + } + } + if (pkcs8_config.outformat == FORMAT_PEM) + PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, + passout); + else if (pkcs8_config.outformat == FORMAT_ASN1) + i2d_PrivateKey_bio(out, pkey); + else { + BIO_printf(bio_err, "Bad format specified for key\n"); + goto end; + } + ret = 0; + +end: + X509_SIG_free(p8); + PKCS8_PRIV_KEY_INFO_free(p8inf); + EVP_PKEY_free(pkey); + BIO_free_all(out); + BIO_free(in); + free(passin); + free(passout); + + return ret; +} diff --git a/crypto/libressl/apps/openssl/pkey.c b/crypto/libressl/apps/openssl/pkey.c new file mode 100644 index 0000000000..a2940e41fb --- /dev/null +++ b/crypto/libressl/apps/openssl/pkey.c @@ -0,0 +1,220 @@ +/* $OpenBSD: pkey.c,v 1.7 2015/10/17 07:51:10 semarie Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006 + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include "apps.h" + +#include +#include +#include + +int +pkey_main(int argc, char **argv) +{ + char **args, *infile = NULL, *outfile = NULL; + char *passargin = NULL, *passargout = NULL; + BIO *in = NULL, *out = NULL; + const EVP_CIPHER *cipher = NULL; + int informat, outformat; + int pubin = 0, pubout = 0, pubtext = 0, text = 0, noout = 0; + EVP_PKEY *pkey = NULL; + char *passin = NULL, *passout = NULL; + int badarg = 0; + int ret = 1; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + informat = FORMAT_PEM; + outformat = FORMAT_PEM; + + args = argv + 1; + while (!badarg && *args && *args[0] == '-') { + if (!strcmp(*args, "-inform")) { + if (args[1]) { + args++; + informat = str2fmt(*args); + } else + badarg = 1; + } else if (!strcmp(*args, "-outform")) { + if (args[1]) { + args++; + outformat = str2fmt(*args); + } else + badarg = 1; + } else if (!strcmp(*args, "-passin")) { + if (!args[1]) + goto bad; + passargin = *(++args); + } else if (!strcmp(*args, "-passout")) { + if (!args[1]) + goto bad; + passargout = *(++args); + } + else if (!strcmp(*args, "-in")) { + if (args[1]) { + args++; + infile = *args; + } else + badarg = 1; + } else if (!strcmp(*args, "-out")) { + if (args[1]) { + args++; + outfile = *args; + } else + badarg = 1; + } else if (strcmp(*args, "-pubin") == 0) { + pubin = 1; + pubout = 1; + pubtext = 1; + } else if (strcmp(*args, "-pubout") == 0) + pubout = 1; + else if (strcmp(*args, "-text_pub") == 0) { + pubtext = 1; + text = 1; + } else if (strcmp(*args, "-text") == 0) + text = 1; + else if (strcmp(*args, "-noout") == 0) + noout = 1; + else { + cipher = EVP_get_cipherbyname(*args + 1); + if (!cipher) { + BIO_printf(bio_err, "Unknown cipher %s\n", + *args + 1); + badarg = 1; + } + } + args++; + } + + if (badarg) { +bad: + BIO_printf(bio_err, "Usage pkey [options]\n"); + BIO_printf(bio_err, "where options are\n"); + BIO_printf(bio_err, "-in file input file\n"); + BIO_printf(bio_err, "-inform X input format (DER or PEM)\n"); + BIO_printf(bio_err, "-passin arg input file pass phrase source\n"); + BIO_printf(bio_err, "-outform X output format (DER or PEM)\n"); + BIO_printf(bio_err, "-out file output file\n"); + BIO_printf(bio_err, "-passout arg output file pass phrase source\n"); + return 1; + } + + if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { + BIO_printf(bio_err, "Error getting passwords\n"); + goto end; + } + if (outfile) { + if (!(out = BIO_new_file(outfile, "wb"))) { + BIO_printf(bio_err, + "Can't open output file %s\n", outfile); + goto end; + } + } else { + out = BIO_new_fp(stdout, BIO_NOCLOSE); + } + + if (pubin) + pkey = load_pubkey(bio_err, infile, informat, 1, + passin, "Public Key"); + else + pkey = load_key(bio_err, infile, informat, 1, passin, "key"); + if (!pkey) + goto end; + + if (!noout) { + if (outformat == FORMAT_PEM) { + if (pubout) + PEM_write_bio_PUBKEY(out, pkey); + else + PEM_write_bio_PrivateKey(out, pkey, cipher, + NULL, 0, NULL, passout); + } else if (outformat == FORMAT_ASN1) { + if (pubout) + i2d_PUBKEY_bio(out, pkey); + else + i2d_PrivateKey_bio(out, pkey); + } else { + BIO_printf(bio_err, "Bad format specified for key\n"); + goto end; + } + + } + if (text) { + if (pubtext) + EVP_PKEY_print_public(out, pkey, 0, NULL); + else + EVP_PKEY_print_private(out, pkey, 0, NULL); + } + ret = 0; + +end: + EVP_PKEY_free(pkey); + BIO_free_all(out); + BIO_free(in); + free(passin); + free(passout); + + return ret; +} diff --git a/crypto/libressl/apps/openssl/pkeyparam.c b/crypto/libressl/apps/openssl/pkeyparam.c new file mode 100644 index 0000000000..23fc14757c --- /dev/null +++ b/crypto/libressl/apps/openssl/pkeyparam.c @@ -0,0 +1,174 @@ +/* $OpenBSD: pkeyparam.c,v 1.8 2015/10/10 22:28:51 doug Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006 + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include "apps.h" + +#include +#include +#include + +struct { + char *infile; + int noout; + char *outfile; + int text; +} pkeyparam_config; + +struct option pkeyparam_options[] = { + { + .name = "in", + .argname = "file", + .desc = "Input file (default stdin)", + .type = OPTION_ARG, + .opt.arg = &pkeyparam_config.infile, + }, + { + .name = "noout", + .desc = "Do not print encoded version of the parameters", + .type = OPTION_FLAG, + .opt.flag = &pkeyparam_config.noout, + }, + { + .name = "out", + .argname = "file", + .desc = "Output file (default stdout)", + .type = OPTION_ARG, + .opt.arg = &pkeyparam_config.outfile, + }, + { + .name = "text", + .desc = "Print out the parameters in plain text", + .type = OPTION_FLAG, + .opt.flag = &pkeyparam_config.text, + }, + { NULL }, +}; + +static void +pkeyparam_usage() +{ + fprintf(stderr, + "usage: pkeyparam [-in file] [-noout] [-out file] " + "[-text]\n"); + options_usage(pkeyparam_options); +} + +int +pkeyparam_main(int argc, char **argv) +{ + BIO *in = NULL, *out = NULL; + EVP_PKEY *pkey = NULL; + int ret = 1; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + memset(&pkeyparam_config, 0, sizeof(pkeyparam_config)); + + if (options_parse(argc, argv, pkeyparam_options, NULL, NULL) != 0) { + pkeyparam_usage(); + return (1); + } + + if (pkeyparam_config.infile) { + if (!(in = BIO_new_file(pkeyparam_config.infile, "r"))) { + BIO_printf(bio_err, "Can't open input file %s\n", + pkeyparam_config.infile); + goto end; + } + } else + in = BIO_new_fp(stdin, BIO_NOCLOSE); + + if (pkeyparam_config.outfile) { + if (!(out = BIO_new_file(pkeyparam_config.outfile, "w"))) { + BIO_printf(bio_err, "Can't open output file %s\n", + pkeyparam_config.outfile); + goto end; + } + } else { + out = BIO_new_fp(stdout, BIO_NOCLOSE); + } + + pkey = PEM_read_bio_Parameters(in, NULL); + if (!pkey) { + BIO_printf(bio_err, "Error reading parameters\n"); + ERR_print_errors(bio_err); + goto end; + } + if (!pkeyparam_config.noout) + PEM_write_bio_Parameters(out, pkey); + + if (pkeyparam_config.text) + EVP_PKEY_print_params(out, pkey, 0, NULL); + + ret = 0; + +end: + EVP_PKEY_free(pkey); + BIO_free_all(out); + BIO_free(in); + + return ret; +} diff --git a/crypto/libressl/apps/openssl/pkeyutl.c b/crypto/libressl/apps/openssl/pkeyutl.c new file mode 100644 index 0000000000..f36e60780f --- /dev/null +++ b/crypto/libressl/apps/openssl/pkeyutl.c @@ -0,0 +1,494 @@ +/* $OpenBSD: pkeyutl.c,v 1.9 2015/10/17 07:51:10 semarie Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include "apps.h" + +#include +#include +#include + +#define KEY_PRIVKEY 1 +#define KEY_PUBKEY 2 +#define KEY_CERT 3 + +static void usage(void); + +static EVP_PKEY_CTX *init_ctx(int *pkeysize, + char *keyfile, int keyform, int key_type, + char *passargin, int pkey_op); + +static int setup_peer(BIO * err, EVP_PKEY_CTX * ctx, int peerform, + const char *file); + +static int do_keyop(EVP_PKEY_CTX * ctx, int pkey_op, + unsigned char *out, size_t * poutlen, + unsigned char *in, size_t inlen); + +int +pkeyutl_main(int argc, char **argv) +{ + BIO *in = NULL, *out = NULL; + char *infile = NULL, *outfile = NULL, *sigfile = NULL; + int pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY; + int keyform = FORMAT_PEM, peerform = FORMAT_PEM; + char badarg = 0, rev = 0; + char hexdump = 0, asn1parse = 0; + EVP_PKEY_CTX *ctx = NULL; + char *passargin = NULL; + int keysize = -1; + + unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL; + size_t buf_outlen; + int buf_inlen = 0, siglen = -1; + + int ret = 1, rv = -1; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + argc--; + argv++; + + while (argc >= 1) { + if (!strcmp(*argv, "-in")) { + if (--argc < 1) + badarg = 1; + else + infile = *(++argv); + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) + badarg = 1; + else + outfile = *(++argv); + } else if (!strcmp(*argv, "-sigfile")) { + if (--argc < 1) + badarg = 1; + else + sigfile = *(++argv); + } else if (!strcmp(*argv, "-inkey")) { + if (--argc < 1) + badarg = 1; + else { + ctx = init_ctx(&keysize, + *(++argv), keyform, key_type, + passargin, pkey_op); + if (!ctx) { + BIO_puts(bio_err, + "Error initializing context\n"); + ERR_print_errors(bio_err); + badarg = 1; + } + } + } else if (!strcmp(*argv, "-peerkey")) { + if (--argc < 1) + badarg = 1; + else if (!setup_peer(bio_err, ctx, peerform, *(++argv))) + badarg = 1; + } else if (!strcmp(*argv, "-passin")) { + if (--argc < 1) + badarg = 1; + else + passargin = *(++argv); + } else if (strcmp(*argv, "-peerform") == 0) { + if (--argc < 1) + badarg = 1; + else + peerform = str2fmt(*(++argv)); + } else if (strcmp(*argv, "-keyform") == 0) { + if (--argc < 1) + badarg = 1; + else + keyform = str2fmt(*(++argv)); + } + else if (!strcmp(*argv, "-pubin")) + key_type = KEY_PUBKEY; + else if (!strcmp(*argv, "-certin")) + key_type = KEY_CERT; + else if (!strcmp(*argv, "-asn1parse")) + asn1parse = 1; + else if (!strcmp(*argv, "-hexdump")) + hexdump = 1; + else if (!strcmp(*argv, "-sign")) + pkey_op = EVP_PKEY_OP_SIGN; + else if (!strcmp(*argv, "-verify")) + pkey_op = EVP_PKEY_OP_VERIFY; + else if (!strcmp(*argv, "-verifyrecover")) + pkey_op = EVP_PKEY_OP_VERIFYRECOVER; + else if (!strcmp(*argv, "-rev")) + rev = 1; + else if (!strcmp(*argv, "-encrypt")) + pkey_op = EVP_PKEY_OP_ENCRYPT; + else if (!strcmp(*argv, "-decrypt")) + pkey_op = EVP_PKEY_OP_DECRYPT; + else if (!strcmp(*argv, "-derive")) + pkey_op = EVP_PKEY_OP_DERIVE; + else if (strcmp(*argv, "-pkeyopt") == 0) { + if (--argc < 1) + badarg = 1; + else if (!ctx) { + BIO_puts(bio_err, + "-pkeyopt command before -inkey\n"); + badarg = 1; + } else if (pkey_ctrl_string(ctx, *(++argv)) <= 0) { + BIO_puts(bio_err, "parameter setting error\n"); + ERR_print_errors(bio_err); + goto end; + } + } else + badarg = 1; + if (badarg) { + usage(); + goto end; + } + argc--; + argv++; + } + + if (!ctx) { + usage(); + goto end; + } + if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY)) { + BIO_puts(bio_err, "Signature file specified for non verify\n"); + goto end; + } + if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY)) { + BIO_puts(bio_err, "No signature file specified for verify\n"); + goto end; + } + + if (pkey_op != EVP_PKEY_OP_DERIVE) { + if (infile) { + if (!(in = BIO_new_file(infile, "rb"))) { + BIO_puts(bio_err, + "Error Opening Input File\n"); + ERR_print_errors(bio_err); + goto end; + } + } else + in = BIO_new_fp(stdin, BIO_NOCLOSE); + } + if (outfile) { + if (!(out = BIO_new_file(outfile, "wb"))) { + BIO_printf(bio_err, "Error Creating Output File\n"); + ERR_print_errors(bio_err); + goto end; + } + } else { + out = BIO_new_fp(stdout, BIO_NOCLOSE); + } + + if (sigfile) { + BIO *sigbio = BIO_new_file(sigfile, "rb"); + if (!sigbio) { + BIO_printf(bio_err, "Can't open signature file %s\n", + sigfile); + goto end; + } + siglen = bio_to_mem(&sig, keysize * 10, sigbio); + BIO_free(sigbio); + if (siglen <= 0) { + BIO_printf(bio_err, "Error reading signature data\n"); + goto end; + } + } + if (in) { + /* Read the input data */ + buf_inlen = bio_to_mem(&buf_in, keysize * 10, in); + if (buf_inlen <= 0) { + BIO_printf(bio_err, "Error reading input Data\n"); + exit(1); + } + if (rev) { + size_t i; + unsigned char ctmp; + size_t l = (size_t) buf_inlen; + for (i = 0; i < l / 2; i++) { + ctmp = buf_in[i]; + buf_in[i] = buf_in[l - 1 - i]; + buf_in[l - 1 - i] = ctmp; + } + } + } + if (pkey_op == EVP_PKEY_OP_VERIFY) { + rv = EVP_PKEY_verify(ctx, sig, (size_t) siglen, + buf_in, (size_t) buf_inlen); + if (rv == 1) { + BIO_puts(out, "Signature Verified Successfully\n"); + ret = 0; + } else + BIO_puts(out, "Signature Verification Failure\n"); + if (rv >= 0) + goto end; + } else { + rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen, + buf_in, (size_t) buf_inlen); + if (rv > 0) { + buf_out = malloc(buf_outlen); + if (!buf_out) + rv = -1; + else + rv = do_keyop(ctx, pkey_op, + buf_out, (size_t *) & buf_outlen, + buf_in, (size_t) buf_inlen); + } + } + + if (rv <= 0) { + BIO_printf(bio_err, "Public Key operation error\n"); + ERR_print_errors(bio_err); + goto end; + } + ret = 0; + if (asn1parse) { + if (!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1)) + ERR_print_errors(bio_err); + } else if (hexdump) + BIO_dump(out, (char *) buf_out, buf_outlen); + else + BIO_write(out, buf_out, buf_outlen); + +end: + if (ctx) + EVP_PKEY_CTX_free(ctx); + BIO_free(in); + BIO_free_all(out); + free(buf_in); + free(buf_out); + free(sig); + + return ret; +} + +static void +usage() +{ + BIO_printf(bio_err, "Usage: pkeyutl [options]\n"); + BIO_printf(bio_err, "-in file input file\n"); + BIO_printf(bio_err, "-out file output file\n"); + BIO_printf(bio_err, "-sigfile file signature file (verify operation only)\n"); + BIO_printf(bio_err, "-inkey file input key\n"); + BIO_printf(bio_err, "-keyform arg private key format - default PEM\n"); + BIO_printf(bio_err, "-pubin input is a public key\n"); + BIO_printf(bio_err, "-certin input is a certificate carrying a public key\n"); + BIO_printf(bio_err, "-pkeyopt X:Y public key options\n"); + BIO_printf(bio_err, "-sign sign with private key\n"); + BIO_printf(bio_err, "-verify verify with public key\n"); + BIO_printf(bio_err, "-verifyrecover verify with public key, recover original data\n"); + BIO_printf(bio_err, "-encrypt encrypt with public key\n"); + BIO_printf(bio_err, "-decrypt decrypt with private key\n"); + BIO_printf(bio_err, "-derive derive shared secret\n"); + BIO_printf(bio_err, "-hexdump hex dump output\n"); + BIO_printf(bio_err, "-passin arg pass phrase source\n"); + +} + +static EVP_PKEY_CTX * +init_ctx(int *pkeysize, + char *keyfile, int keyform, int key_type, + char *passargin, int pkey_op) +{ + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx = NULL; + char *passin = NULL; + int rv = -1; + X509 *x; + if (((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT) + || (pkey_op == EVP_PKEY_OP_DERIVE)) + && (key_type != KEY_PRIVKEY)) { + BIO_printf(bio_err, "A private key is needed for this operation\n"); + goto end; + } + if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { + BIO_printf(bio_err, "Error getting password\n"); + goto end; + } + switch (key_type) { + case KEY_PRIVKEY: + pkey = load_key(bio_err, keyfile, keyform, 0, + passin, "Private Key"); + break; + + case KEY_PUBKEY: + pkey = load_pubkey(bio_err, keyfile, keyform, 0, + NULL, "Public Key"); + break; + + case KEY_CERT: + x = load_cert(bio_err, keyfile, keyform, + NULL, "Certificate"); + if (x) { + pkey = X509_get_pubkey(x); + X509_free(x); + } + break; + + } + + *pkeysize = EVP_PKEY_size(pkey); + + if (!pkey) + goto end; + + ctx = EVP_PKEY_CTX_new(pkey, NULL); + + EVP_PKEY_free(pkey); + + if (!ctx) + goto end; + + switch (pkey_op) { + case EVP_PKEY_OP_SIGN: + rv = EVP_PKEY_sign_init(ctx); + break; + + case EVP_PKEY_OP_VERIFY: + rv = EVP_PKEY_verify_init(ctx); + break; + + case EVP_PKEY_OP_VERIFYRECOVER: + rv = EVP_PKEY_verify_recover_init(ctx); + break; + + case EVP_PKEY_OP_ENCRYPT: + rv = EVP_PKEY_encrypt_init(ctx); + break; + + case EVP_PKEY_OP_DECRYPT: + rv = EVP_PKEY_decrypt_init(ctx); + break; + + case EVP_PKEY_OP_DERIVE: + rv = EVP_PKEY_derive_init(ctx); + break; + } + + if (rv <= 0) { + EVP_PKEY_CTX_free(ctx); + ctx = NULL; + } +end: + + free(passin); + + return ctx; + + +} + +static int +setup_peer(BIO * err, EVP_PKEY_CTX * ctx, int peerform, + const char *file) +{ + EVP_PKEY *peer = NULL; + int ret; + if (!ctx) { + BIO_puts(err, "-peerkey command before -inkey\n"); + return 0; + } + peer = load_pubkey(bio_err, file, peerform, 0, NULL, "Peer Key"); + + if (!peer) { + BIO_printf(bio_err, "Error reading peer key %s\n", file); + ERR_print_errors(err); + return 0; + } + ret = EVP_PKEY_derive_set_peer(ctx, peer); + + EVP_PKEY_free(peer); + if (ret <= 0) + ERR_print_errors(err); + return ret; +} + +static int +do_keyop(EVP_PKEY_CTX * ctx, int pkey_op, + unsigned char *out, size_t * poutlen, + unsigned char *in, size_t inlen) +{ + int rv = 0; + switch (pkey_op) { + case EVP_PKEY_OP_VERIFYRECOVER: + rv = EVP_PKEY_verify_recover(ctx, out, poutlen, in, inlen); + break; + + case EVP_PKEY_OP_SIGN: + rv = EVP_PKEY_sign(ctx, out, poutlen, in, inlen); + break; + + case EVP_PKEY_OP_ENCRYPT: + rv = EVP_PKEY_encrypt(ctx, out, poutlen, in, inlen); + break; + + case EVP_PKEY_OP_DECRYPT: + rv = EVP_PKEY_decrypt(ctx, out, poutlen, in, inlen); + break; + + case EVP_PKEY_OP_DERIVE: + rv = EVP_PKEY_derive(ctx, out, poutlen); + break; + + } + return rv; +} diff --git a/crypto/libressl/apps/openssl/prime.c b/crypto/libressl/apps/openssl/prime.c new file mode 100644 index 0000000000..a70df969f3 --- /dev/null +++ b/crypto/libressl/apps/openssl/prime.c @@ -0,0 +1,199 @@ +/* $OpenBSD: prime.c,v 1.9 2015/10/10 22:28:51 doug Exp $ */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include + +#include "apps.h" + +#include +#include + +struct { + int bits; + int checks; + int generate; + int hex; + int safe; +} prime_config; + +struct option prime_options[] = { + { + .name = "bits", + .argname = "n", + .desc = "Number of bits in the generated prime number", + .type = OPTION_ARG_INT, + .opt.value = &prime_config.bits, + }, + { + .name = "checks", + .argname = "n", + .desc = "Miller-Rabin probablistic primality test iterations", + .type = OPTION_ARG_INT, + .opt.value = &prime_config.checks, + }, + { + .name = "generate", + .desc = "Generate a pseudo-random prime number", + .type = OPTION_FLAG, + .opt.flag = &prime_config.generate, + }, + { + .name = "hex", + .desc = "Hexadecimal prime numbers", + .type = OPTION_FLAG, + .opt.flag = &prime_config.hex, + }, + { + .name = "safe", + .desc = "Generate only \"safe\" prime numbers", + .type = OPTION_FLAG, + .opt.flag = &prime_config.safe, + }, + {NULL}, +}; + +static void +prime_usage() +{ + fprintf(stderr, + "usage: prime [-bits n] [-checks n] [-generate] [-hex] [-safe] " + "p\n"); + options_usage(prime_options); +} + +int +prime_main(int argc, char **argv) +{ + BIGNUM *bn = NULL; + char *prime = NULL; + BIO *bio_out; + char *s; + int ret = 1; + + if (single_execution) { + if (pledge("stdio rpath", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + memset(&prime_config, 0, sizeof(prime_config)); + + /* Default iterations for Miller-Rabin probabilistic primality test. */ + prime_config.checks = 20; + + if (options_parse(argc, argv, prime_options, &prime, NULL) != 0) { + prime_usage(); + return (1); + } + + if (prime == NULL && prime_config.generate == 0) { + BIO_printf(bio_err, "No prime specified.\n"); + prime_usage(); + return (1); + } + + if ((bio_out = BIO_new(BIO_s_file())) == NULL) { + ERR_print_errors(bio_err); + return (1); + } + BIO_set_fp(bio_out, stdout, BIO_NOCLOSE); + + if (prime_config.generate != 0) { + if (prime_config.bits == 0) { + BIO_printf(bio_err, "Specify the number of bits.\n"); + goto end; + } + bn = BN_new(); + if (!bn) { + BIO_printf(bio_err, "Out of memory.\n"); + goto end; + } + if (!BN_generate_prime_ex(bn, prime_config.bits, + prime_config.safe, NULL, NULL, NULL)) { + BIO_printf(bio_err, "Prime generation error.\n"); + goto end; + } + s = prime_config.hex ? BN_bn2hex(bn) : BN_bn2dec(bn); + if (s == NULL) { + BIO_printf(bio_err, "Out of memory.\n"); + goto end; + } + BIO_printf(bio_out, "%s\n", s); + free(s); + } else { + if (prime_config.hex) { + if (!BN_hex2bn(&bn, prime)) { + BIO_printf(bio_err, "%s is an invalid hex " + "value.\n", prime); + goto end; + } + } else { + if (!BN_dec2bn(&bn, prime)) { + BIO_printf(bio_err, "%s is an invalid decimal " + "value.\n", prime); + goto end; + } + } + + BIO_printf(bio_out, "%s is %sprime\n", prime, + BN_is_prime_ex(bn, prime_config.checks, + NULL, NULL) ? "" : "not "); + } + + ret = 0; + +end: + BN_free(bn); + BIO_free_all(bio_out); + + return (ret); +} diff --git a/crypto/libressl/apps/openssl/progs.h b/crypto/libressl/apps/openssl/progs.h new file mode 100644 index 0000000000..bde828e8f6 --- /dev/null +++ b/crypto/libressl/apps/openssl/progs.h @@ -0,0 +1,48 @@ +/* $OpenBSD: progs.h,v 1.6 2015/08/22 16:36:05 jsing Exp $ */ +/* Public domain */ + +int asn1parse_main(int argc, char **argv); +int ca_main(int argc, char **argv); +int certhash_main(int argc, char **argv); +int ciphers_main(int argc, char **argv); +int cms_main(int argc, char **argv); +int crl2pkcs7_main(int argc, char **argv); +int crl_main(int argc, char **argv); +int dgst_main(int argc, char **argv); +int dh_main(int argc, char **argv); +int dhparam_main(int argc, char **argv); +int dsa_main(int argc, char **argv); +int dsaparam_main(int argc, char **argv); +int ec_main(int argc, char **argv); +int ecparam_main(int argc, char **argv); +int enc_main(int argc, char **argv); +int errstr_main(int argc, char **argv); +int gendh_main(int argc, char **argv); +int gendsa_main(int argc, char **argv); +int genpkey_main(int argc, char **argv); +int genrsa_main(int argc, char **argv); +int nseq_main(int argc, char **argv); +int ocsp_main(int argc, char **argv); +int passwd_main(int argc, char **argv); +int pkcs7_main(int argc, char **argv); +int pkcs8_main(int argc, char **argv); +int pkcs12_main(int argc, char **argv); +int pkey_main(int argc, char **argv); +int pkeyparam_main(int argc, char **argv); +int pkeyutl_main(int argc, char **argv); +int prime_main(int argc, char **argv); +int rand_main(int argc, char **argv); +int req_main(int argc, char **argv); +int rsa_main(int argc, char **argv); +int rsautl_main(int argc, char **argv); +int s_client_main(int argc, char **argv); +int s_server_main(int argc, char **argv); +int s_time_main(int argc, char **argv); +int sess_id_main(int argc, char **argv); +int smime_main(int argc, char **argv); +int speed_main(int argc, char **argv); +int spkac_main(int argc, char **argv); +int ts_main(int argc, char **argv); +int verify_main(int argc, char **argv); +int version_main(int argc, char **argv); +int x509_main(int argc, char **argv); diff --git a/crypto/libressl/apps/openssl/rand.c b/crypto/libressl/apps/openssl/rand.c new file mode 100644 index 0000000000..e5bef4e6e4 --- /dev/null +++ b/crypto/libressl/apps/openssl/rand.c @@ -0,0 +1,185 @@ +/* $OpenBSD: rand.c,v 1.9 2015/10/10 22:28:51 doug Exp $ */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include "apps.h" + +#include +#include + +struct { + int base64; + int hex; + char *outfile; +} rand_config; + +struct option rand_options[] = { + { + .name = "base64", + .desc = "Perform base64 encoding on output", + .type = OPTION_FLAG, + .opt.flag = &rand_config.base64, + }, + { + .name = "hex", + .desc = "Hexadecimal output", + .type = OPTION_FLAG, + .opt.flag = &rand_config.hex, + }, + { + .name = "out", + .argname = "file", + .desc = "Write to the given file instead of standard output", + .type = OPTION_ARG, + .opt.arg = &rand_config.outfile, + }, + {NULL}, +}; + +static void +rand_usage() +{ + fprintf(stderr, + "usage: rand [-base64 | -hex] [-out file] num\n"); + options_usage(rand_options); +} + +int +rand_main(int argc, char **argv) +{ + char *num_bytes = NULL; + int ret = 1; + int badopt = 0; + int num = -1; + int i, r; + BIO *out = NULL; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + memset(&rand_config, 0, sizeof(rand_config)); + + if (options_parse(argc, argv, rand_options, &num_bytes, NULL) != 0) { + rand_usage(); + return (1); + } + + if (num_bytes != NULL) { + r = sscanf(num_bytes, "%d", &num); + if (r == 0 || num < 0) + badopt = 1; + } else + badopt = 1; + + if (rand_config.hex && rand_config.base64) + badopt = 1; + + if (badopt) { + rand_usage(); + goto err; + } + + out = BIO_new(BIO_s_file()); + if (out == NULL) + goto err; + if (rand_config.outfile != NULL) + r = BIO_write_filename(out, rand_config.outfile); + else + r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT); + if (r <= 0) + goto err; + if (rand_config.base64) { + BIO *b64 = BIO_new(BIO_f_base64()); + if (b64 == NULL) + goto err; + out = BIO_push(b64, out); + } + + while (num > 0) { + unsigned char buf[4096]; + int chunk; + + chunk = num; + if (chunk > (int) sizeof(buf)) + chunk = sizeof(buf); + arc4random_buf(buf, chunk); + if (rand_config.hex) { + for (i = 0; i < chunk; i++) + BIO_printf(out, "%02x", buf[i]); + } else + BIO_write(out, buf, chunk); + num -= chunk; + } + + if (rand_config.hex) + BIO_puts(out, "\n"); + (void) BIO_flush(out); + + ret = 0; + +err: + ERR_print_errors(bio_err); + if (out) + BIO_free_all(out); + + return (ret); +} diff --git a/crypto/libressl/apps/openssl/req.c b/crypto/libressl/apps/openssl/req.c new file mode 100644 index 0000000000..09607a54d8 --- /dev/null +++ b/crypto/libressl/apps/openssl/req.c @@ -0,0 +1,1560 @@ +/* $OpenBSD: req.c,v 1.12 2015/10/17 15:00:11 doug Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Until the key-gen callbacks are modified to use newer prototypes, we allow + * deprecated functions for openssl-internal code */ +#ifdef OPENSSL_NO_DEPRECATED +#undef OPENSSL_NO_DEPRECATED +#endif + +#include +#include +#include +#include +#include + +#include "apps.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define SECTION "req" + +#define BITS "default_bits" +#define KEYFILE "default_keyfile" +#define PROMPT "prompt" +#define DISTINGUISHED_NAME "distinguished_name" +#define ATTRIBUTES "attributes" +#define V3_EXTENSIONS "x509_extensions" +#define REQ_EXTENSIONS "req_extensions" +#define STRING_MASK "string_mask" +#define UTF8_IN "utf8" + +#define DEFAULT_KEY_LENGTH 2048 +#define MIN_KEY_LENGTH 384 + + +/* -inform arg - input format - default PEM (DER or PEM) + * -outform arg - output format - default PEM + * -in arg - input file - default stdin + * -out arg - output file - default stdout + * -verify - check request signature + * -noout - don't print stuff out. + * -text - print out human readable text. + * -nodes - no des encryption + * -config file - Load configuration file. + * -key file - make a request using key in file (or use it for verification). + * -keyform arg - key file format. + * -newkey - make a key and a request. + * -modulus - print RSA modulus. + * -pubkey - output Public Key. + * -x509 - output a self signed X509 structure instead. + * -asn1-kludge - output new certificate request in a format that some CA's + * require. This format is wrong + */ + +static int make_REQ(X509_REQ * req, EVP_PKEY * pkey, char *dn, int multirdn, + int attribs, unsigned long chtype); +static int build_subject(X509_REQ * req, char *subj, unsigned long chtype, + int multirdn); +static int prompt_info(X509_REQ * req, + STACK_OF(CONF_VALUE) * dn_sk, char *dn_sect, + STACK_OF(CONF_VALUE) * attr_sk, char *attr_sect, int attribs, + unsigned long chtype); +static int auto_info(X509_REQ * req, STACK_OF(CONF_VALUE) * sk, + STACK_OF(CONF_VALUE) * attr, int attribs, + unsigned long chtype); +static int add_attribute_object(X509_REQ * req, char *text, const char *def, + char *value, int nid, int n_min, + int n_max, unsigned long chtype); +static int add_DN_object(X509_NAME * n, char *text, const char *def, char *value, + int nid, int n_min, int n_max, unsigned long chtype, int mval); +static int genpkey_cb(EVP_PKEY_CTX * ctx); +static int req_check_len(int len, int n_min, int n_max); +static int check_end(const char *str, const char *end); +static EVP_PKEY_CTX *set_keygen_ctx(BIO * err, const char *gstr, int *pkey_type, + long *pkeylen, char **palgnam); +static CONF *req_conf = NULL; +static int batch = 0; + +int +req_main(int argc, char **argv) +{ + unsigned long nmflag = 0, reqflag = 0; + int ex = 1, x509 = 0, days = 30; + X509 *x509ss = NULL; + X509_REQ *req = NULL; + EVP_PKEY_CTX *genctx = NULL; + const char *keyalg = NULL; + char *keyalgstr = NULL; + STACK_OF(OPENSSL_STRING) * pkeyopts = NULL, *sigopts = NULL; + EVP_PKEY *pkey = NULL; + int i = 0, badops = 0, newreq = 0, verbose = 0, pkey_type = -1; + long newkey = -1; + BIO *in = NULL, *out = NULL; + int informat, outformat, verify = 0, noout = 0, text = 0, keyform = FORMAT_PEM; + int nodes = 0, kludge = 0, newhdr = 0, subject = 0, pubkey = 0; + char *infile, *outfile, *prog, *keyfile = NULL, *template = NULL, + *keyout = NULL; + char *extensions = NULL; + char *req_exts = NULL; + const EVP_CIPHER *cipher = NULL; + ASN1_INTEGER *serial = NULL; + int modulus = 0; + char *passargin = NULL, *passargout = NULL; + char *passin = NULL, *passout = NULL; + char *p; + char *subj = NULL; + int multirdn = 0; + const EVP_MD *md_alg = NULL, *digest = NULL; + unsigned long chtype = MBSTRING_ASC; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + req_conf = NULL; + cipher = EVP_aes_256_cbc(); + digest = EVP_sha256(); + + infile = NULL; + outfile = NULL; + informat = FORMAT_PEM; + outformat = FORMAT_PEM; + + prog = argv[0]; + argc--; + argv++; + while (argc >= 1) { + if (strcmp(*argv, "-inform") == 0) { + if (--argc < 1) + goto bad; + informat = str2fmt(*(++argv)); + } else if (strcmp(*argv, "-outform") == 0) { + if (--argc < 1) + goto bad; + outformat = str2fmt(*(++argv)); + } + else if (strcmp(*argv, "-key") == 0) { + if (--argc < 1) + goto bad; + keyfile = *(++argv); + } else if (strcmp(*argv, "-pubkey") == 0) { + pubkey = 1; + } else if (strcmp(*argv, "-new") == 0) { + newreq = 1; + } else if (strcmp(*argv, "-config") == 0) { + if (--argc < 1) + goto bad; + template = *(++argv); + } else if (strcmp(*argv, "-keyform") == 0) { + if (--argc < 1) + goto bad; + keyform = str2fmt(*(++argv)); + } else if (strcmp(*argv, "-in") == 0) { + if (--argc < 1) + goto bad; + infile = *(++argv); + } else if (strcmp(*argv, "-out") == 0) { + if (--argc < 1) + goto bad; + outfile = *(++argv); + } else if (strcmp(*argv, "-keyout") == 0) { + if (--argc < 1) + goto bad; + keyout = *(++argv); + } else if (strcmp(*argv, "-passin") == 0) { + if (--argc < 1) + goto bad; + passargin = *(++argv); + } else if (strcmp(*argv, "-passout") == 0) { + if (--argc < 1) + goto bad; + passargout = *(++argv); + } else if (strcmp(*argv, "-newkey") == 0) { + if (--argc < 1) + goto bad; + keyalg = *(++argv); + newreq = 1; + } else if (strcmp(*argv, "-pkeyopt") == 0) { + if (--argc < 1) + goto bad; + if (!pkeyopts) + pkeyopts = sk_OPENSSL_STRING_new_null(); + if (!pkeyopts || !sk_OPENSSL_STRING_push(pkeyopts, *(++argv))) + goto bad; + } else if (strcmp(*argv, "-sigopt") == 0) { + if (--argc < 1) + goto bad; + if (!sigopts) + sigopts = sk_OPENSSL_STRING_new_null(); + if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv))) + goto bad; + } else if (strcmp(*argv, "-batch") == 0) + batch = 1; + else if (strcmp(*argv, "-newhdr") == 0) + newhdr = 1; + else if (strcmp(*argv, "-modulus") == 0) + modulus = 1; + else if (strcmp(*argv, "-verify") == 0) + verify = 1; + else if (strcmp(*argv, "-nodes") == 0) + nodes = 1; + else if (strcmp(*argv, "-noout") == 0) + noout = 1; + else if (strcmp(*argv, "-verbose") == 0) + verbose = 1; + else if (strcmp(*argv, "-utf8") == 0) + chtype = MBSTRING_UTF8; + else if (strcmp(*argv, "-nameopt") == 0) { + if (--argc < 1) + goto bad; + if (!set_name_ex(&nmflag, *(++argv))) + goto bad; + } else if (strcmp(*argv, "-reqopt") == 0) { + if (--argc < 1) + goto bad; + if (!set_cert_ex(&reqflag, *(++argv))) + goto bad; + } else if (strcmp(*argv, "-subject") == 0) + subject = 1; + else if (strcmp(*argv, "-text") == 0) + text = 1; + else if (strcmp(*argv, "-x509") == 0) + x509 = 1; + else if (strcmp(*argv, "-asn1-kludge") == 0) + kludge = 1; + else if (strcmp(*argv, "-no-asn1-kludge") == 0) + kludge = 0; + else if (strcmp(*argv, "-subj") == 0) { + if (--argc < 1) + goto bad; + subj = *(++argv); + } else if (strcmp(*argv, "-multivalue-rdn") == 0) + multirdn = 1; + else if (strcmp(*argv, "-days") == 0) { + const char *errstr; + + if (--argc < 1) + goto bad; + days = strtonum(*(++argv), 1, INT_MAX, &errstr); + if (errstr) { + BIO_printf(bio_err, "bad -days %s, using 0: %s\n", + *argv, errstr); + days = 30; + } + } else if (strcmp(*argv, "-set_serial") == 0) { + if (--argc < 1) + goto bad; + serial = s2i_ASN1_INTEGER(NULL, *(++argv)); + if (!serial) + goto bad; + } else if (strcmp(*argv, "-extensions") == 0) { + if (--argc < 1) + goto bad; + extensions = *(++argv); + } else if (strcmp(*argv, "-reqexts") == 0) { + if (--argc < 1) + goto bad; + req_exts = *(++argv); + } else if ((md_alg = EVP_get_digestbyname(&((*argv)[1]))) != NULL) { + /* ok */ + digest = md_alg; + } else { + BIO_printf(bio_err, "unknown option %s\n", *argv); + badops = 1; + break; + } + argc--; + argv++; + } + + if (badops) { +bad: + BIO_printf(bio_err, "%s [options] outfile\n", prog); + BIO_printf(bio_err, "where options are\n"); + BIO_printf(bio_err, " -inform arg input format - DER or PEM\n"); + BIO_printf(bio_err, " -outform arg output format - DER or PEM\n"); + BIO_printf(bio_err, " -in arg input file\n"); + BIO_printf(bio_err, " -out arg output file\n"); + BIO_printf(bio_err, " -text text form of request\n"); + BIO_printf(bio_err, " -pubkey output public key\n"); + BIO_printf(bio_err, " -noout do not output REQ\n"); + BIO_printf(bio_err, " -verify verify signature on REQ\n"); + BIO_printf(bio_err, " -modulus RSA modulus\n"); + BIO_printf(bio_err, " -nodes don't encrypt the output key\n"); + BIO_printf(bio_err, " -subject output the request's subject\n"); + BIO_printf(bio_err, " -passin private key password source\n"); + BIO_printf(bio_err, " -key file use the private key contained in file\n"); + BIO_printf(bio_err, " -keyform arg key file format\n"); + BIO_printf(bio_err, " -keyout arg file to send the key to\n"); + BIO_printf(bio_err, " -newkey rsa:bits generate a new RSA key of 'bits' in size\n"); + BIO_printf(bio_err, " -newkey dsa:file generate a new DSA key, parameters taken from CA in 'file'\n"); + BIO_printf(bio_err, " -newkey ec:file generate a new EC key, parameters taken from CA in 'file'\n"); + BIO_printf(bio_err, " -[digest] Digest to sign with (md5, sha1, md4)\n"); + BIO_printf(bio_err, " -config file request template file.\n"); + BIO_printf(bio_err, " -subj arg set or modify request subject\n"); + BIO_printf(bio_err, " -multivalue-rdn enable support for multivalued RDNs\n"); + BIO_printf(bio_err, " -new new request.\n"); + BIO_printf(bio_err, " -batch do not ask anything during request generation\n"); + BIO_printf(bio_err, " -x509 output a x509 structure instead of a cert. req.\n"); + BIO_printf(bio_err, " -days number of days a certificate generated by -x509 is valid for.\n"); + BIO_printf(bio_err, " -set_serial serial number to use for a certificate generated by -x509.\n"); + BIO_printf(bio_err, " -newhdr output \"NEW\" in the header lines\n"); + BIO_printf(bio_err, " -asn1-kludge Output the 'request' in a format that is wrong but some CA's\n"); + BIO_printf(bio_err, " have been reported as requiring\n"); + BIO_printf(bio_err, " -extensions .. specify certificate extension section (override value in config file)\n"); + BIO_printf(bio_err, " -reqexts .. specify request extension section (override value in config file)\n"); + BIO_printf(bio_err, " -utf8 input characters are UTF8 (default ASCII)\n"); + BIO_printf(bio_err, " -nameopt arg - various certificate name options\n"); + BIO_printf(bio_err, " -reqopt arg - various request text options\n\n"); + goto end; + } + + if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { + BIO_printf(bio_err, "Error getting passwords\n"); + goto end; + } + if (template != NULL) { + long errline = -1; + + if (verbose) + BIO_printf(bio_err, "Using configuration from %s\n", template); + req_conf = NCONF_new(NULL); + i = NCONF_load(req_conf, template, &errline); + if (i == 0) { + BIO_printf(bio_err, "error on line %ld of %s\n", errline, template); + goto end; + } + } else { + req_conf = config; + + if (req_conf == NULL) { + BIO_printf(bio_err, "Unable to load config info from %s\n", default_config_file); + if (newreq) + goto end; + } else if (verbose) + BIO_printf(bio_err, "Using configuration from %s\n", + default_config_file); + } + + if (req_conf != NULL) { + if (!load_config(bio_err, req_conf)) + goto end; + p = NCONF_get_string(req_conf, NULL, "oid_file"); + if (p == NULL) + ERR_clear_error(); + if (p != NULL) { + BIO *oid_bio; + + oid_bio = BIO_new_file(p, "r"); + if (oid_bio == NULL) { + /* + BIO_printf(bio_err,"problems opening %s for extra oid's\n",p); + ERR_print_errors(bio_err); + */ + } else { + OBJ_create_objects(oid_bio); + BIO_free(oid_bio); + } + } + } + if (!add_oid_section(bio_err, req_conf)) + goto end; + + if (md_alg == NULL) { + p = NCONF_get_string(req_conf, SECTION, "default_md"); + if (p == NULL) + ERR_clear_error(); + if (p != NULL) { + if ((md_alg = EVP_get_digestbyname(p)) != NULL) + digest = md_alg; + } + } + if (!extensions) { + extensions = NCONF_get_string(req_conf, SECTION, V3_EXTENSIONS); + if (!extensions) + ERR_clear_error(); + } + if (extensions) { + /* Check syntax of file */ + X509V3_CTX ctx; + X509V3_set_ctx_test(&ctx); + X509V3_set_nconf(&ctx, req_conf); + if (!X509V3_EXT_add_nconf(req_conf, &ctx, extensions, NULL)) { + BIO_printf(bio_err, + "Error Loading extension section %s\n", extensions); + goto end; + } + } + if (!passin) { + passin = NCONF_get_string(req_conf, SECTION, "input_password"); + if (!passin) + ERR_clear_error(); + } + if (!passout) { + passout = NCONF_get_string(req_conf, SECTION, "output_password"); + if (!passout) + ERR_clear_error(); + } + p = NCONF_get_string(req_conf, SECTION, STRING_MASK); + if (!p) + ERR_clear_error(); + + if (p && !ASN1_STRING_set_default_mask_asc(p)) { + BIO_printf(bio_err, "Invalid global string mask setting %s\n", p); + goto end; + } + if (chtype != MBSTRING_UTF8) { + p = NCONF_get_string(req_conf, SECTION, UTF8_IN); + if (!p) + ERR_clear_error(); + else if (!strcmp(p, "yes")) + chtype = MBSTRING_UTF8; + } + if (!req_exts) { + req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS); + if (!req_exts) + ERR_clear_error(); + } + if (req_exts) { + /* Check syntax of file */ + X509V3_CTX ctx; + X509V3_set_ctx_test(&ctx); + X509V3_set_nconf(&ctx, req_conf); + if (!X509V3_EXT_add_nconf(req_conf, &ctx, req_exts, NULL)) { + BIO_printf(bio_err, + "Error Loading request extension section %s\n", + req_exts); + goto end; + } + } + in = BIO_new(BIO_s_file()); + out = BIO_new(BIO_s_file()); + if ((in == NULL) || (out == NULL)) + goto end; + + if (keyfile != NULL) { + pkey = load_key(bio_err, keyfile, keyform, 0, passin, + "Private Key"); + if (!pkey) { + /* + * load_key() has already printed an appropriate + * message + */ + goto end; + } + } + if (newreq && (pkey == NULL)) { + if (!NCONF_get_number(req_conf, SECTION, BITS, &newkey)) { + newkey = DEFAULT_KEY_LENGTH; + } + if (keyalg) { + genctx = set_keygen_ctx(bio_err, keyalg, &pkey_type, &newkey, + &keyalgstr); + if (!genctx) + goto end; + } + if (newkey < MIN_KEY_LENGTH && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA)) { + BIO_printf(bio_err, "private key length is too short,\n"); + BIO_printf(bio_err, "it needs to be at least %d bits, not %ld\n", MIN_KEY_LENGTH, newkey); + goto end; + } + if (!genctx) { + genctx = set_keygen_ctx(bio_err, NULL, &pkey_type, &newkey, + &keyalgstr); + if (!genctx) + goto end; + } + if (pkeyopts) { + char *genopt; + for (i = 0; i < sk_OPENSSL_STRING_num(pkeyopts); i++) { + genopt = sk_OPENSSL_STRING_value(pkeyopts, i); + if (pkey_ctrl_string(genctx, genopt) <= 0) { + BIO_printf(bio_err, + "parameter error \"%s\"\n", + genopt); + ERR_print_errors(bio_err); + goto end; + } + } + } + BIO_printf(bio_err, "Generating a %ld bit %s private key\n", + newkey, keyalgstr); + + EVP_PKEY_CTX_set_cb(genctx, genpkey_cb); + EVP_PKEY_CTX_set_app_data(genctx, bio_err); + + if (EVP_PKEY_keygen(genctx, &pkey) <= 0) { + BIO_puts(bio_err, "Error Generating Key\n"); + goto end; + } + EVP_PKEY_CTX_free(genctx); + genctx = NULL; + + if (keyout == NULL) { + keyout = NCONF_get_string(req_conf, SECTION, KEYFILE); + if (keyout == NULL) + ERR_clear_error(); + } + if (keyout == NULL) { + BIO_printf(bio_err, "writing new private key to stdout\n"); + BIO_set_fp(out, stdout, BIO_NOCLOSE); + } else { + BIO_printf(bio_err, "writing new private key to '%s'\n", keyout); + if (BIO_write_filename(out, keyout) <= 0) { + perror(keyout); + goto end; + } + } + + p = NCONF_get_string(req_conf, SECTION, "encrypt_rsa_key"); + if (p == NULL) { + ERR_clear_error(); + p = NCONF_get_string(req_conf, SECTION, "encrypt_key"); + if (p == NULL) + ERR_clear_error(); + } + if ((p != NULL) && (strcmp(p, "no") == 0)) + cipher = NULL; + if (nodes) + cipher = NULL; + + i = 0; +loop: + if (!PEM_write_bio_PrivateKey(out, pkey, cipher, + NULL, 0, NULL, passout)) { + if ((ERR_GET_REASON(ERR_peek_error()) == + PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3)) { + ERR_clear_error(); + i++; + goto loop; + } + goto end; + } + BIO_printf(bio_err, "-----\n"); + } + if (!newreq) { + /* + * Since we are using a pre-existing certificate request, the + * kludge 'format' info should not be changed. + */ + kludge = -1; + if (infile == NULL) + BIO_set_fp(in, stdin, BIO_NOCLOSE); + else { + if (BIO_read_filename(in, infile) <= 0) { + perror(infile); + goto end; + } + } + + if (informat == FORMAT_ASN1) + req = d2i_X509_REQ_bio(in, NULL); + else if (informat == FORMAT_PEM) + req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); + else { + BIO_printf(bio_err, "bad input format specified for X509 request\n"); + goto end; + } + if (req == NULL) { + BIO_printf(bio_err, "unable to load X509 request\n"); + goto end; + } + } + if (newreq || x509) { + if (pkey == NULL) { + BIO_printf(bio_err, "you need to specify a private key\n"); + goto end; + } + if (req == NULL) { + req = X509_REQ_new(); + if (req == NULL) { + goto end; + } + i = make_REQ(req, pkey, subj, multirdn, !x509, chtype); + subj = NULL; /* done processing '-subj' option */ + if ((kludge > 0) && !sk_X509_ATTRIBUTE_num(req->req_info->attributes)) { + sk_X509_ATTRIBUTE_free(req->req_info->attributes); + req->req_info->attributes = NULL; + } + if (!i) { + BIO_printf(bio_err, "problems making Certificate Request\n"); + goto end; + } + } + if (x509) { + EVP_PKEY *tmppkey; + X509V3_CTX ext_ctx; + if ((x509ss = X509_new()) == NULL) + goto end; + + /* Set version to V3 */ + if (extensions && !X509_set_version(x509ss, 2)) + goto end; + if (serial) { + if (!X509_set_serialNumber(x509ss, serial)) + goto end; + } else { + if (!rand_serial(NULL, + X509_get_serialNumber(x509ss))) + goto end; + } + + if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req))) + goto end; + if (!X509_gmtime_adj(X509_get_notBefore(x509ss), 0)) + goto end; + if (!X509_time_adj_ex(X509_get_notAfter(x509ss), days, 0, NULL)) + goto end; + if (!X509_set_subject_name(x509ss, X509_REQ_get_subject_name(req))) + goto end; + tmppkey = X509_REQ_get_pubkey(req); + if (!tmppkey || !X509_set_pubkey(x509ss, tmppkey)) + goto end; + EVP_PKEY_free(tmppkey); + + /* Set up V3 context struct */ + + X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0); + X509V3_set_nconf(&ext_ctx, req_conf); + + /* Add extensions */ + if (extensions && !X509V3_EXT_add_nconf(req_conf, + &ext_ctx, extensions, x509ss)) { + BIO_printf(bio_err, + "Error Loading extension section %s\n", + extensions); + goto end; + } + i = do_X509_sign(bio_err, x509ss, pkey, digest, sigopts); + if (!i) { + ERR_print_errors(bio_err); + goto end; + } + } else { + X509V3_CTX ext_ctx; + + /* Set up V3 context struct */ + + X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0); + X509V3_set_nconf(&ext_ctx, req_conf); + + /* Add extensions */ + if (req_exts && !X509V3_EXT_REQ_add_nconf(req_conf, + &ext_ctx, req_exts, req)) { + BIO_printf(bio_err, + "Error Loading extension section %s\n", + req_exts); + goto end; + } + i = do_X509_REQ_sign(bio_err, req, pkey, digest, sigopts); + if (!i) { + ERR_print_errors(bio_err); + goto end; + } + } + } + if (subj && x509) { + BIO_printf(bio_err, "Cannot modifiy certificate subject\n"); + goto end; + } + if (subj && !x509) { + if (verbose) { + BIO_printf(bio_err, "Modifying Request's Subject\n"); + print_name(bio_err, "old subject=", X509_REQ_get_subject_name(req), nmflag); + } + if (build_subject(req, subj, chtype, multirdn) == 0) { + BIO_printf(bio_err, "ERROR: cannot modify subject\n"); + ex = 1; + goto end; + } + req->req_info->enc.modified = 1; + + if (verbose) { + print_name(bio_err, "new subject=", X509_REQ_get_subject_name(req), nmflag); + } + } + if (verify && !x509) { + int tmp = 0; + + if (pkey == NULL) { + pkey = X509_REQ_get_pubkey(req); + tmp = 1; + if (pkey == NULL) + goto end; + } + i = X509_REQ_verify(req, pkey); + if (tmp) { + EVP_PKEY_free(pkey); + pkey = NULL; + } + if (i < 0) { + goto end; + } else if (i == 0) { + BIO_printf(bio_err, "verify failure\n"); + ERR_print_errors(bio_err); + } else /* if (i > 0) */ + BIO_printf(bio_err, "verify OK\n"); + } + if (noout && !text && !modulus && !subject && !pubkey) { + ex = 0; + goto end; + } + if (outfile == NULL) { + BIO_set_fp(out, stdout, BIO_NOCLOSE); + } else { + if ((keyout != NULL) && (strcmp(outfile, keyout) == 0)) + i = (int) BIO_append_filename(out, outfile); + else + i = (int) BIO_write_filename(out, outfile); + if (!i) { + perror(outfile); + goto end; + } + } + + if (pubkey) { + EVP_PKEY *tpubkey; + tpubkey = X509_REQ_get_pubkey(req); + if (tpubkey == NULL) { + BIO_printf(bio_err, "Error getting public key\n"); + ERR_print_errors(bio_err); + goto end; + } + PEM_write_bio_PUBKEY(out, tpubkey); + EVP_PKEY_free(tpubkey); + } + if (text) { + if (x509) + X509_print_ex(out, x509ss, nmflag, reqflag); + else + X509_REQ_print_ex(out, req, nmflag, reqflag); + } + if (subject) { + if (x509) + print_name(out, "subject=", X509_get_subject_name(x509ss), nmflag); + else + print_name(out, "subject=", X509_REQ_get_subject_name(req), nmflag); + } + if (modulus) { + EVP_PKEY *tpubkey; + + if (x509) + tpubkey = X509_get_pubkey(x509ss); + else + tpubkey = X509_REQ_get_pubkey(req); + if (tpubkey == NULL) { + fprintf(stdout, "Modulus=unavailable\n"); + goto end; + } + fprintf(stdout, "Modulus="); + if (EVP_PKEY_base_id(tpubkey) == EVP_PKEY_RSA) + BN_print(out, tpubkey->pkey.rsa->n); + else + fprintf(stdout, "Wrong Algorithm type"); + EVP_PKEY_free(tpubkey); + fprintf(stdout, "\n"); + } + if (!noout && !x509) { + if (outformat == FORMAT_ASN1) + i = i2d_X509_REQ_bio(out, req); + else if (outformat == FORMAT_PEM) { + if (newhdr) + i = PEM_write_bio_X509_REQ_NEW(out, req); + else + i = PEM_write_bio_X509_REQ(out, req); + } else { + BIO_printf(bio_err, "bad output format specified for outfile\n"); + goto end; + } + if (!i) { + BIO_printf(bio_err, "unable to write X509 request\n"); + goto end; + } + } + if (!noout && x509 && (x509ss != NULL)) { + if (outformat == FORMAT_ASN1) + i = i2d_X509_bio(out, x509ss); + else if (outformat == FORMAT_PEM) + i = PEM_write_bio_X509(out, x509ss); + else { + BIO_printf(bio_err, "bad output format specified for outfile\n"); + goto end; + } + if (!i) { + BIO_printf(bio_err, "unable to write X509 certificate\n"); + goto end; + } + } + ex = 0; +end: + if (ex) { + ERR_print_errors(bio_err); + } + if ((req_conf != NULL) && (req_conf != config)) + NCONF_free(req_conf); + BIO_free(in); + BIO_free_all(out); + EVP_PKEY_free(pkey); + if (genctx) + EVP_PKEY_CTX_free(genctx); + if (pkeyopts) + sk_OPENSSL_STRING_free(pkeyopts); + if (sigopts) + sk_OPENSSL_STRING_free(sigopts); + free(keyalgstr); + X509_REQ_free(req); + X509_free(x509ss); + ASN1_INTEGER_free(serial); + if (passargin && passin) + free(passin); + if (passargout && passout) + free(passout); + OBJ_cleanup(); + + return (ex); +} + +static int +make_REQ(X509_REQ * req, EVP_PKEY * pkey, char *subj, int multirdn, + int attribs, unsigned long chtype) +{ + int ret = 0, i; + char no_prompt = 0; + STACK_OF(CONF_VALUE) * dn_sk, *attr_sk = NULL; + char *tmp, *dn_sect, *attr_sect; + + tmp = NCONF_get_string(req_conf, SECTION, PROMPT); + if (tmp == NULL) + ERR_clear_error(); + if ((tmp != NULL) && !strcmp(tmp, "no")) + no_prompt = 1; + + dn_sect = NCONF_get_string(req_conf, SECTION, DISTINGUISHED_NAME); + if (dn_sect == NULL) { + BIO_printf(bio_err, "unable to find '%s' in config\n", + DISTINGUISHED_NAME); + goto err; + } + dn_sk = NCONF_get_section(req_conf, dn_sect); + if (dn_sk == NULL) { + BIO_printf(bio_err, "unable to get '%s' section\n", dn_sect); + goto err; + } + attr_sect = NCONF_get_string(req_conf, SECTION, ATTRIBUTES); + if (attr_sect == NULL) { + ERR_clear_error(); + attr_sk = NULL; + } else { + attr_sk = NCONF_get_section(req_conf, attr_sect); + if (attr_sk == NULL) { + BIO_printf(bio_err, "unable to get '%s' section\n", attr_sect); + goto err; + } + } + + /* setup version number */ + if (!X509_REQ_set_version(req, 0L)) + goto err; /* version 1 */ + + if (no_prompt) + i = auto_info(req, dn_sk, attr_sk, attribs, chtype); + else { + if (subj) + i = build_subject(req, subj, chtype, multirdn); + else + i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs, chtype); + } + if (!i) + goto err; + + if (!X509_REQ_set_pubkey(req, pkey)) + goto err; + + ret = 1; +err: + return (ret); +} + +/* + * subject is expected to be in the format /type0=value0/type1=value1/type2=... + * where characters may be escaped by \ + */ +static int +build_subject(X509_REQ * req, char *subject, unsigned long chtype, int multirdn) +{ + X509_NAME *n; + + if (!(n = parse_name(subject, chtype, multirdn))) + return 0; + + if (!X509_REQ_set_subject_name(req, n)) { + X509_NAME_free(n); + return 0; + } + X509_NAME_free(n); + return 1; +} + + +static int +prompt_info(X509_REQ * req, + STACK_OF(CONF_VALUE) * dn_sk, char *dn_sect, + STACK_OF(CONF_VALUE) * attr_sk, char *attr_sect, int attribs, + unsigned long chtype) +{ + int i; + char *p, *q; + char buf[100]; + int nid, mval; + long n_min, n_max; + char *type, *value; + const char *def; + CONF_VALUE *v; + X509_NAME *subj; + subj = X509_REQ_get_subject_name(req); + + if (!batch) { + BIO_printf(bio_err, "You are about to be asked to enter information that will be incorporated\n"); + BIO_printf(bio_err, "into your certificate request.\n"); + BIO_printf(bio_err, "What you are about to enter is what is called a Distinguished Name or a DN.\n"); + BIO_printf(bio_err, "There are quite a few fields but you can leave some blank\n"); + BIO_printf(bio_err, "For some fields there will be a default value,\n"); + BIO_printf(bio_err, "If you enter '.', the field will be left blank.\n"); + BIO_printf(bio_err, "-----\n"); + } + if (sk_CONF_VALUE_num(dn_sk)) { + i = -1; +start: for (;;) { + int ret; + i++; + if (sk_CONF_VALUE_num(dn_sk) <= i) + break; + + v = sk_CONF_VALUE_value(dn_sk, i); + p = q = NULL; + type = v->name; + if (!check_end(type, "_min") || !check_end(type, "_max") || + !check_end(type, "_default") || + !check_end(type, "_value")) + continue; + /* + * Skip past any leading X. X: X, etc to allow for + * multiple instances + */ + for (p = v->name; *p; p++) + if ((*p == ':') || (*p == ',') || + (*p == '.')) { + p++; + if (*p) + type = p; + break; + } + if (*type == '+') { + mval = -1; + type++; + } else + mval = 0; + /* If OBJ not recognised ignore it */ + if ((nid = OBJ_txt2nid(type)) == NID_undef) + goto start; + ret = snprintf(buf, sizeof buf, "%s_default", v->name); + if (ret == -1 || ret >= sizeof(buf)) { + BIO_printf(bio_err, "Name '%s' too long for default\n", + v->name); + return 0; + } + if ((def = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) { + ERR_clear_error(); + def = ""; + } + ret = snprintf(buf, sizeof buf, "%s_value", v->name); + if (ret == -1 || ret >= sizeof(buf)) { + BIO_printf(bio_err, "Name '%s' too long for value\n", + v->name); + return 0; + } + if ((value = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) { + ERR_clear_error(); + value = NULL; + } + ret = snprintf(buf, sizeof buf, "%s_min", v->name); + if (ret == -1 || ret >= sizeof(buf)) { + BIO_printf(bio_err, "Name '%s' too long for min\n", + v->name); + return 0; + } + if (!NCONF_get_number(req_conf, dn_sect, buf, &n_min)) { + ERR_clear_error(); + n_min = -1; + } + ret = snprintf(buf, sizeof buf, "%s_max", v->name); + if (ret == -1 || ret >= sizeof(buf)) { + BIO_printf(bio_err, "Name '%s' too long for max\n", + v->name); + return 0; + } + if (!NCONF_get_number(req_conf, dn_sect, buf, &n_max)) { + ERR_clear_error(); + n_max = -1; + } + if (!add_DN_object(subj, v->value, def, value, nid, + n_min, n_max, chtype, mval)) + return 0; + } + if (X509_NAME_entry_count(subj) == 0) { + BIO_printf(bio_err, "error, no objects specified in config file\n"); + return 0; + } + if (attribs) { + if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0) && + (!batch)) { + BIO_printf(bio_err, + "\nPlease enter the following 'extra' attributes\n"); + BIO_printf(bio_err, + "to be sent with your certificate request\n"); + } + i = -1; +start2: for (;;) { + int ret; + i++; + if ((attr_sk == NULL) || + (sk_CONF_VALUE_num(attr_sk) <= i)) + break; + + v = sk_CONF_VALUE_value(attr_sk, i); + type = v->name; + if ((nid = OBJ_txt2nid(type)) == NID_undef) + goto start2; + ret = snprintf(buf, sizeof buf, "%s_default", type); + if (ret == -1 || ret >= sizeof(buf)) { + BIO_printf(bio_err, "Name '%s' too long for default\n", + v->name); + return 0; + } + if ((def = NCONF_get_string(req_conf, attr_sect, buf)) + == NULL) { + ERR_clear_error(); + def = ""; + } + ret = snprintf(buf, sizeof buf, "%s_value", type); + if (ret == -1 || ret >= sizeof(buf)) { + BIO_printf(bio_err, "Name '%s' too long for value\n", + v->name); + return 0; + } + if ((value = NCONF_get_string(req_conf, attr_sect, buf)) + == NULL) { + ERR_clear_error(); + value = NULL; + } + ret = snprintf(buf, sizeof buf, "%s_min", type); + if (ret == -1 || ret >= sizeof(buf)) { + BIO_printf(bio_err, "Name '%s' too long for min\n", + v->name); + return 0; + } + if (!NCONF_get_number(req_conf, attr_sect, buf, &n_min)) { + ERR_clear_error(); + n_min = -1; + } + ret = snprintf(buf, sizeof buf, "%s_max", type); + if (ret == -1 || ret >= sizeof(buf)) { + BIO_printf(bio_err, "Name '%s' too long for max\n", + v->name); + return 0; + } + if (!NCONF_get_number(req_conf, attr_sect, buf, &n_max)) { + ERR_clear_error(); + n_max = -1; + } + if (!add_attribute_object(req, + v->value, def, value, nid, n_min, n_max, chtype)) + return 0; + } + } + } else { + BIO_printf(bio_err, "No template, please set one up.\n"); + return 0; + } + + return 1; + +} + +static int +auto_info(X509_REQ * req, STACK_OF(CONF_VALUE) * dn_sk, + STACK_OF(CONF_VALUE) * attr_sk, int attribs, unsigned long chtype) +{ + int i; + char *p, *q; + char *type; + CONF_VALUE *v; + X509_NAME *subj; + + subj = X509_REQ_get_subject_name(req); + + for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) { + int mval; + v = sk_CONF_VALUE_value(dn_sk, i); + p = q = NULL; + type = v->name; + /* + * Skip past any leading X. X: X, etc to allow for multiple + * instances + */ + for (p = v->name; *p; p++) + if ((*p == ':') || (*p == ',') || (*p == '.')) { + p++; + if (*p) + type = p; + break; + } + if (*p == '+') { + p++; + mval = -1; + } else + mval = 0; + if (!X509_NAME_add_entry_by_txt(subj, type, chtype, + (unsigned char *) v->value, -1, -1, mval)) + return 0; + + } + + if (!X509_NAME_entry_count(subj)) { + BIO_printf(bio_err, "error, no objects specified in config file\n"); + return 0; + } + if (attribs) { + for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) { + v = sk_CONF_VALUE_value(attr_sk, i); + if (!X509_REQ_add1_attr_by_txt(req, v->name, chtype, + (unsigned char *) v->value, -1)) + return 0; + } + } + return 1; +} + + +static int +add_DN_object(X509_NAME * n, char *text, const char *def, char *value, + int nid, int n_min, int n_max, unsigned long chtype, int mval) +{ + int i, ret = 0; + char buf[1024]; +start: + if (!batch) + BIO_printf(bio_err, "%s [%s]:", text, def); + (void) BIO_flush(bio_err); + if (value != NULL) { + strlcpy(buf, value, sizeof buf); + strlcat(buf, "\n", sizeof buf); + BIO_printf(bio_err, "%s\n", value); + } else { + buf[0] = '\0'; + if (!batch) { + if (!fgets(buf, sizeof buf, stdin)) + return 0; + } else { + buf[0] = '\n'; + buf[1] = '\0'; + } + } + + if (buf[0] == '\0') + return (0); + else if (buf[0] == '\n') { + if ((def == NULL) || (def[0] == '\0')) + return (1); + strlcpy(buf, def, sizeof buf); + strlcat(buf, "\n", sizeof buf); + } else if ((buf[0] == '.') && (buf[1] == '\n')) + return (1); + + i = strlen(buf); + if (buf[i - 1] != '\n') { + BIO_printf(bio_err, "weird input :-(\n"); + return (0); + } + buf[--i] = '\0'; + if (!req_check_len(i, n_min, n_max)) + goto start; + if (!X509_NAME_add_entry_by_NID(n, nid, chtype, + (unsigned char *) buf, -1, -1, mval)) + goto err; + ret = 1; +err: + return (ret); +} + +static int +add_attribute_object(X509_REQ * req, char *text, const char *def, + char *value, int nid, int n_min, + int n_max, unsigned long chtype) +{ + int i; + static char buf[1024]; + +start: + if (!batch) + BIO_printf(bio_err, "%s [%s]:", text, def); + (void) BIO_flush(bio_err); + if (value != NULL) { + strlcpy(buf, value, sizeof buf); + strlcat(buf, "\n", sizeof buf); + BIO_printf(bio_err, "%s\n", value); + } else { + buf[0] = '\0'; + if (!batch) { + if (!fgets(buf, sizeof buf, stdin)) + return 0; + } else { + buf[0] = '\n'; + buf[1] = '\0'; + } + } + + if (buf[0] == '\0') + return (0); + else if (buf[0] == '\n') { + if ((def == NULL) || (def[0] == '\0')) + return (1); + strlcpy(buf, def, sizeof buf); + strlcat(buf, "\n", sizeof buf); + } else if ((buf[0] == '.') && (buf[1] == '\n')) + return (1); + + i = strlen(buf); + if (buf[i - 1] != '\n') { + BIO_printf(bio_err, "weird input :-(\n"); + return (0); + } + buf[--i] = '\0'; + if (!req_check_len(i, n_min, n_max)) + goto start; + + if (!X509_REQ_add1_attr_by_NID(req, nid, chtype, + (unsigned char *) buf, -1)) { + BIO_printf(bio_err, "Error adding attribute\n"); + ERR_print_errors(bio_err); + goto err; + } + return (1); +err: + return (0); +} + +static int +req_check_len(int len, int n_min, int n_max) +{ + if ((n_min > 0) && (len < n_min)) { + BIO_printf(bio_err, "string is too short, it needs to be at least %d bytes long\n", n_min); + return (0); + } + if ((n_max >= 0) && (len > n_max)) { + BIO_printf(bio_err, "string is too long, it needs to be less than %d bytes long\n", n_max); + return (0); + } + return (1); +} + +/* Check if the end of a string matches 'end' */ +static int +check_end(const char *str, const char *end) +{ + int elen, slen; + const char *tmp; + elen = strlen(end); + slen = strlen(str); + if (elen > slen) + return 1; + tmp = str + slen - elen; + return strcmp(tmp, end); +} + +static EVP_PKEY_CTX * +set_keygen_ctx(BIO * err, const char *gstr, int *pkey_type, + long *pkeylen, char **palgnam) +{ + EVP_PKEY_CTX *gctx = NULL; + EVP_PKEY *param = NULL; + long keylen = -1; + BIO *pbio = NULL; + const char *paramfile = NULL; + const char *errstr; + + if (gstr == NULL) { + *pkey_type = EVP_PKEY_RSA; + keylen = *pkeylen; + } else if (gstr[0] >= '0' && gstr[0] <= '9') { + *pkey_type = EVP_PKEY_RSA; + keylen = strtonum(gstr, 0, LONG_MAX, &errstr); + if (errstr) { + BIO_printf(err, "bad algorithm %s: %s\n", gstr, errstr); + return NULL; + } + *pkeylen = keylen; + } else if (!strncmp(gstr, "param:", 6)) + paramfile = gstr + 6; + else { + const char *p = strchr(gstr, ':'); + int len; + const EVP_PKEY_ASN1_METHOD *ameth; + + if (p) + len = p - gstr; + else + len = strlen(gstr); + + ameth = EVP_PKEY_asn1_find_str(NULL, gstr, len); + + if (!ameth) { + BIO_printf(err, "Unknown algorithm %.*s\n", len, gstr); + return NULL; + } + EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL, + ameth); + if (*pkey_type == EVP_PKEY_RSA) { + if (p) { + keylen = strtonum(p + 1, 0, LONG_MAX, &errstr); + if (errstr) { + BIO_printf(err, "bad algorithm %s: %s\n", + p + 1, errstr); + return NULL; + } + *pkeylen = keylen; + } else + keylen = *pkeylen; + } else if (p) + paramfile = p + 1; + } + + if (paramfile) { + pbio = BIO_new_file(paramfile, "r"); + if (!pbio) { + BIO_printf(err, "Can't open parameter file %s\n", + paramfile); + return NULL; + } + param = PEM_read_bio_Parameters(pbio, NULL); + + if (!param) { + X509 *x; + (void) BIO_reset(pbio); + x = PEM_read_bio_X509(pbio, NULL, NULL, NULL); + if (x) { + param = X509_get_pubkey(x); + X509_free(x); + } + } + BIO_free(pbio); + + if (!param) { + BIO_printf(err, "Error reading parameter file %s\n", + paramfile); + return NULL; + } + if (*pkey_type == -1) + *pkey_type = EVP_PKEY_id(param); + else if (*pkey_type != EVP_PKEY_base_id(param)) { + BIO_printf(err, "Key Type does not match parameters\n"); + EVP_PKEY_free(param); + return NULL; + } + } + if (palgnam) { + const EVP_PKEY_ASN1_METHOD *ameth; + const char *anam; + ameth = EVP_PKEY_asn1_find(NULL, *pkey_type); + if (!ameth) { + BIO_puts(err, "Internal error: can't find key algorithm\n"); + return NULL; + } + EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth); + *palgnam = strdup(anam); + } + if (param) { + gctx = EVP_PKEY_CTX_new(param, NULL); + *pkeylen = EVP_PKEY_bits(param); + EVP_PKEY_free(param); + } else + gctx = EVP_PKEY_CTX_new_id(*pkey_type, NULL); + + if (!gctx) { + BIO_puts(err, "Error allocating keygen context\n"); + ERR_print_errors(err); + return NULL; + } + if (EVP_PKEY_keygen_init(gctx) <= 0) { + BIO_puts(err, "Error initializing keygen context\n"); + ERR_print_errors(err); + return NULL; + } + if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) { + if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0) { + BIO_puts(err, "Error setting RSA keysize\n"); + ERR_print_errors(err); + EVP_PKEY_CTX_free(gctx); + return NULL; + } + } + + return gctx; +} + +static int +genpkey_cb(EVP_PKEY_CTX * ctx) +{ + char c = '*'; + BIO *b = EVP_PKEY_CTX_get_app_data(ctx); + int p; + p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); + if (p == 0) + c = '.'; + if (p == 1) + c = '+'; + if (p == 2) + c = '*'; + if (p == 3) + c = '\n'; + BIO_write(b, &c, 1); + (void) BIO_flush(b); + return 1; +} + +static int +do_sign_init(BIO * err, EVP_MD_CTX * ctx, EVP_PKEY * pkey, + const EVP_MD * md, STACK_OF(OPENSSL_STRING) * sigopts) +{ + EVP_PKEY_CTX *pkctx = NULL; + int i; + EVP_MD_CTX_init(ctx); + if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey)) + return 0; + for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { + char *sigopt = sk_OPENSSL_STRING_value(sigopts, i); + if (pkey_ctrl_string(pkctx, sigopt) <= 0) { + BIO_printf(err, "parameter error \"%s\"\n", sigopt); + ERR_print_errors(bio_err); + return 0; + } + } + return 1; +} + +int +do_X509_sign(BIO * err, X509 * x, EVP_PKEY * pkey, const EVP_MD * md, + STACK_OF(OPENSSL_STRING) * sigopts) +{ + int rv; + EVP_MD_CTX mctx; + EVP_MD_CTX_init(&mctx); + rv = do_sign_init(err, &mctx, pkey, md, sigopts); + if (rv > 0) + rv = X509_sign_ctx(x, &mctx); + EVP_MD_CTX_cleanup(&mctx); + return rv > 0 ? 1 : 0; +} + + +int +do_X509_REQ_sign(BIO * err, X509_REQ * x, EVP_PKEY * pkey, const EVP_MD * md, + STACK_OF(OPENSSL_STRING) * sigopts) +{ + int rv; + EVP_MD_CTX mctx; + EVP_MD_CTX_init(&mctx); + rv = do_sign_init(err, &mctx, pkey, md, sigopts); + if (rv > 0) + rv = X509_REQ_sign_ctx(x, &mctx); + EVP_MD_CTX_cleanup(&mctx); + return rv > 0 ? 1 : 0; +} + + + +int +do_X509_CRL_sign(BIO * err, X509_CRL * x, EVP_PKEY * pkey, const EVP_MD * md, + STACK_OF(OPENSSL_STRING) * sigopts) +{ + int rv; + EVP_MD_CTX mctx; + EVP_MD_CTX_init(&mctx); + rv = do_sign_init(err, &mctx, pkey, md, sigopts); + if (rv > 0) + rv = X509_CRL_sign_ctx(x, &mctx); + EVP_MD_CTX_cleanup(&mctx); + return rv > 0 ? 1 : 0; +} diff --git a/crypto/libressl/apps/openssl/rsa.c b/crypto/libressl/apps/openssl/rsa.c new file mode 100644 index 0000000000..1c5611803c --- /dev/null +++ b/crypto/libressl/apps/openssl/rsa.c @@ -0,0 +1,449 @@ +/* $OpenBSD: rsa.c,v 1.7 2015/10/17 07:51:10 semarie Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include + +#include "apps.h" +#include "progs.h" + +#include +#include +#include +#include +#include +#include +#include + +static struct { + int check; + const EVP_CIPHER *enc; + char *infile; + int informat; + int modulus; + int noout; + char *outfile; + int outformat; + char *passargin; + char *passargout; + int pubin; + int pubout; + int pvk_encr; + int sgckey; + int text; +} rsa_config; + +static int +rsa_opt_cipher(int argc, char **argv, int *argsused) +{ + char *name = argv[0]; + + if (*name++ != '-') + return (1); + + if ((rsa_config.enc = EVP_get_cipherbyname(name)) == NULL) { + fprintf(stderr, "Invalid cipher '%s'\n", name); + return (1); + } + + *argsused = 1; + return (0); +} + +static struct option rsa_options[] = { + { + .name = "check", + .desc = "Check consistency of RSA private key", + .type = OPTION_FLAG, + .opt.flag = &rsa_config.check, + }, + { + .name = "in", + .argname = "file", + .desc = "Input file (default stdin)", + .type = OPTION_ARG, + .opt.arg = &rsa_config.infile, + }, + { + .name = "inform", + .argname = "format", + .desc = "Input format (DER, NET or PEM (default))", + .type = OPTION_ARG_FORMAT, + .opt.value = &rsa_config.informat, + }, + { + .name = "modulus", + .desc = "Print the RSA key modulus", + .type = OPTION_FLAG, + .opt.flag = &rsa_config.modulus, + }, + { + .name = "noout", + .desc = "Do not print encoded version of the key", + .type = OPTION_FLAG, + .opt.flag = &rsa_config.noout, + }, + { + .name = "out", + .argname = "file", + .desc = "Output file (default stdout)", + .type = OPTION_ARG, + .opt.arg = &rsa_config.outfile, + }, + { + .name = "outform", + .argname = "format", + .desc = "Output format (DER, NET or PEM (default PEM))", + .type = OPTION_ARG_FORMAT, + .opt.value = &rsa_config.outformat, + }, + { + .name = "passin", + .argname = "src", + .desc = "Input file passphrase source", + .type = OPTION_ARG, + .opt.arg = &rsa_config.passargin, + }, + { + .name = "passout", + .argname = "src", + .desc = "Output file passphrase source", + .type = OPTION_ARG, + .opt.arg = &rsa_config.passargout, + }, + { + .name = "pubin", + .desc = "Expect a public key (default private key)", + .type = OPTION_VALUE, + .value = 1, + .opt.value = &rsa_config.pubin, + }, + { + .name = "pubout", + .desc = "Output a public key (default private key)", + .type = OPTION_VALUE, + .value = 1, + .opt.value = &rsa_config.pubout, + }, + { + .name = "pvk-none", + .type = OPTION_VALUE, + .value = 0, + .opt.value = &rsa_config.pvk_encr, + }, + { + .name = "pvk-strong", + .type = OPTION_VALUE, + .value = 2, + .opt.value = &rsa_config.pvk_encr, + }, + { + .name = "pvk-weak", + .type = OPTION_VALUE, + .value = 1, + .opt.value = &rsa_config.pvk_encr, + }, + { + .name = "RSAPublicKey_in", + .type = OPTION_VALUE, + .value = 2, + .opt.value = &rsa_config.pubin, + }, + { + .name = "RSAPublicKey_out", + .type = OPTION_VALUE, + .value = 2, + .opt.value = &rsa_config.pubout, + }, + { + .name = "sgckey", + .desc = "Use modified NET algorithm for IIS and SGC keys", + .type = OPTION_FLAG, + .opt.flag = &rsa_config.sgckey, + }, + { + .name = "text", + .desc = "Print in plain text in addition to encoded", + .type = OPTION_FLAG, + .opt.flag = &rsa_config.text, + }, + { + .name = NULL, + .type = OPTION_ARGV_FUNC, + .opt.argvfunc = rsa_opt_cipher, + }, + { NULL } +}; + +static void +show_ciphers(const OBJ_NAME *name, void *arg) +{ + static int n; + + fprintf(stderr, " -%-24s%s", name->name, (++n % 3 ? "" : "\n")); +} + +static void +rsa_usage() +{ + fprintf(stderr, + "usage: rsa [-ciphername] [-check] [-in file] " + "[-inform fmt]\n" + " [-modulus] [-noout] [-out file] [-outform fmt] " + "[-passin src]\n" + " [-passout src] [-pubin] [-pubout] [-sgckey] [-text]\n\n"); + options_usage(rsa_options); + fprintf(stderr, "\n"); + + fprintf(stderr, "Valid ciphername values:\n\n"); + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_ciphers, NULL); + fprintf(stderr, "\n"); +} + +int +rsa_main(int argc, char **argv) +{ + int ret = 1; + RSA *rsa = NULL; + int i; + BIO *out = NULL; + char *passin = NULL, *passout = NULL; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + memset(&rsa_config, 0, sizeof(rsa_config)); + rsa_config.pvk_encr = 2; + rsa_config.informat = FORMAT_PEM; + rsa_config.outformat = FORMAT_PEM; + + if (options_parse(argc, argv, rsa_options, NULL, NULL) != 0) { + rsa_usage(); + goto end; + } + + if (!app_passwd(bio_err, rsa_config.passargin, rsa_config.passargout, + &passin, &passout)) { + BIO_printf(bio_err, "Error getting passwords\n"); + goto end; + } + if (rsa_config.check && rsa_config.pubin) { + BIO_printf(bio_err, "Only private keys can be checked\n"); + goto end; + } + out = BIO_new(BIO_s_file()); + + { + EVP_PKEY *pkey; + + if (rsa_config.pubin) { + int tmpformat = -1; + if (rsa_config.pubin == 2) { + if (rsa_config.informat == FORMAT_PEM) + tmpformat = FORMAT_PEMRSA; + else if (rsa_config.informat == FORMAT_ASN1) + tmpformat = FORMAT_ASN1RSA; + } else if (rsa_config.informat == FORMAT_NETSCAPE && + rsa_config.sgckey) + tmpformat = FORMAT_IISSGC; + else + tmpformat = rsa_config.informat; + + pkey = load_pubkey(bio_err, rsa_config.infile, + tmpformat, 1, passin, "Public Key"); + } else + pkey = load_key(bio_err, rsa_config.infile, + (rsa_config.informat == FORMAT_NETSCAPE && + rsa_config.sgckey ? FORMAT_IISSGC : + rsa_config.informat), 1, passin, "Private Key"); + + if (pkey != NULL) + rsa = EVP_PKEY_get1_RSA(pkey); + EVP_PKEY_free(pkey); + } + + if (rsa == NULL) { + ERR_print_errors(bio_err); + goto end; + } + if (rsa_config.outfile == NULL) { + BIO_set_fp(out, stdout, BIO_NOCLOSE); + } else { + if (BIO_write_filename(out, rsa_config.outfile) <= 0) { + perror(rsa_config.outfile); + goto end; + } + } + + if (rsa_config.text) + if (!RSA_print(out, rsa, 0)) { + perror(rsa_config.outfile); + ERR_print_errors(bio_err); + goto end; + } + if (rsa_config.modulus) { + BIO_printf(out, "Modulus="); + BN_print(out, rsa->n); + BIO_printf(out, "\n"); + } + if (rsa_config.check) { + int r = RSA_check_key(rsa); + + if (r == 1) + BIO_printf(out, "RSA key ok\n"); + else if (r == 0) { + unsigned long err; + + while ((err = ERR_peek_error()) != 0 && + ERR_GET_LIB(err) == ERR_LIB_RSA && + ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY && + ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE) { + BIO_printf(out, "RSA key error: %s\n", + ERR_reason_error_string(err)); + ERR_get_error(); /* remove e from error + * stack */ + } + } + if (r == -1 || ERR_peek_error() != 0) { /* should happen only if + * r == -1 */ + ERR_print_errors(bio_err); + goto end; + } + } + if (rsa_config.noout) { + ret = 0; + goto end; + } + BIO_printf(bio_err, "writing RSA key\n"); + if (rsa_config.outformat == FORMAT_ASN1) { + if (rsa_config.pubout || rsa_config.pubin) { + if (rsa_config.pubout == 2) + i = i2d_RSAPublicKey_bio(out, rsa); + else + i = i2d_RSA_PUBKEY_bio(out, rsa); + } else + i = i2d_RSAPrivateKey_bio(out, rsa); + } +#ifndef OPENSSL_NO_RC4 + else if (rsa_config.outformat == FORMAT_NETSCAPE) { + unsigned char *p, *pp; + int size; + + i = 1; + size = i2d_RSA_NET(rsa, NULL, NULL, rsa_config.sgckey); + if ((p = malloc(size)) == NULL) { + BIO_printf(bio_err, "Memory allocation failure\n"); + goto end; + } + pp = p; + i2d_RSA_NET(rsa, &p, NULL, rsa_config.sgckey); + BIO_write(out, (char *) pp, size); + free(pp); + } +#endif + else if (rsa_config.outformat == FORMAT_PEM) { + if (rsa_config.pubout || rsa_config.pubin) { + if (rsa_config.pubout == 2) + i = PEM_write_bio_RSAPublicKey(out, rsa); + else + i = PEM_write_bio_RSA_PUBKEY(out, rsa); + } else + i = PEM_write_bio_RSAPrivateKey(out, rsa, + rsa_config.enc, NULL, 0, NULL, passout); +#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) + } else if (rsa_config.outformat == FORMAT_MSBLOB || + rsa_config.outformat == FORMAT_PVK) { + EVP_PKEY *pk; + pk = EVP_PKEY_new(); + EVP_PKEY_set1_RSA(pk, rsa); + if (rsa_config.outformat == FORMAT_PVK) + i = i2b_PVK_bio(out, pk, rsa_config.pvk_encr, 0, + passout); + else if (rsa_config.pubin || rsa_config.pubout) + i = i2b_PublicKey_bio(out, pk); + else + i = i2b_PrivateKey_bio(out, pk); + EVP_PKEY_free(pk); +#endif + } else { + BIO_printf(bio_err, + "bad output format specified for outfile\n"); + goto end; + } + if (i <= 0) { + BIO_printf(bio_err, "unable to write key\n"); + ERR_print_errors(bio_err); + } else + ret = 0; + +end: + BIO_free_all(out); + RSA_free(rsa); + free(passin); + free(passout); + + return (ret); +} diff --git a/crypto/libressl/apps/openssl/rsautl.c b/crypto/libressl/apps/openssl/rsautl.c new file mode 100644 index 0000000000..4bcdcc76b6 --- /dev/null +++ b/crypto/libressl/apps/openssl/rsautl.c @@ -0,0 +1,332 @@ +/* $OpenBSD: rsautl.c,v 1.9 2015/10/17 07:51:10 semarie Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + + +#include + +#include "apps.h" + +#include +#include +#include + +#define RSA_SIGN 1 +#define RSA_VERIFY 2 +#define RSA_ENCRYPT 3 +#define RSA_DECRYPT 4 + +#define KEY_PRIVKEY 1 +#define KEY_PUBKEY 2 +#define KEY_CERT 3 + +static void usage(void); + +int +rsautl_main(int argc, char **argv) +{ + BIO *in = NULL, *out = NULL; + char *infile = NULL, *outfile = NULL; + char *keyfile = NULL; + char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY; + int keyform = FORMAT_PEM; + char need_priv = 0, badarg = 0, rev = 0; + char hexdump = 0, asn1parse = 0; + X509 *x; + EVP_PKEY *pkey = NULL; + RSA *rsa = NULL; + unsigned char *rsa_in = NULL, *rsa_out = NULL, pad; + char *passargin = NULL, *passin = NULL; + int rsa_inlen, rsa_outlen = 0; + int keysize; + + int ret = 1; + + if (single_execution) { + if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + argc--; + argv++; + + pad = RSA_PKCS1_PADDING; + + while (argc >= 1) { + if (!strcmp(*argv, "-in")) { + if (--argc < 1) + badarg = 1; + else + infile = *(++argv); + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) + badarg = 1; + else + outfile = *(++argv); + } else if (!strcmp(*argv, "-inkey")) { + if (--argc < 1) + badarg = 1; + else + keyfile = *(++argv); + } else if (!strcmp(*argv, "-passin")) { + if (--argc < 1) + badarg = 1; + else + passargin = *(++argv); + } else if (strcmp(*argv, "-keyform") == 0) { + if (--argc < 1) + badarg = 1; + else + keyform = str2fmt(*(++argv)); + } else if (!strcmp(*argv, "-pubin")) { + key_type = KEY_PUBKEY; + } else if (!strcmp(*argv, "-certin")) { + key_type = KEY_CERT; + } else if (!strcmp(*argv, "-asn1parse")) + asn1parse = 1; + else if (!strcmp(*argv, "-hexdump")) + hexdump = 1; + else if (!strcmp(*argv, "-raw")) + pad = RSA_NO_PADDING; + else if (!strcmp(*argv, "-oaep")) + pad = RSA_PKCS1_OAEP_PADDING; + else if (!strcmp(*argv, "-ssl")) + pad = RSA_SSLV23_PADDING; + else if (!strcmp(*argv, "-pkcs")) + pad = RSA_PKCS1_PADDING; + else if (!strcmp(*argv, "-x931")) + pad = RSA_X931_PADDING; + else if (!strcmp(*argv, "-sign")) { + rsa_mode = RSA_SIGN; + need_priv = 1; + } else if (!strcmp(*argv, "-verify")) + rsa_mode = RSA_VERIFY; + else if (!strcmp(*argv, "-rev")) + rev = 1; + else if (!strcmp(*argv, "-encrypt")) + rsa_mode = RSA_ENCRYPT; + else if (!strcmp(*argv, "-decrypt")) { + rsa_mode = RSA_DECRYPT; + need_priv = 1; + } else + badarg = 1; + if (badarg) { + usage(); + goto end; + } + argc--; + argv++; + } + + if (need_priv && (key_type != KEY_PRIVKEY)) { + BIO_printf(bio_err, "A private key is needed for this operation\n"); + goto end; + } + if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { + BIO_printf(bio_err, "Error getting password\n"); + goto end; + } + + switch (key_type) { + case KEY_PRIVKEY: + pkey = load_key(bio_err, keyfile, keyform, 0, + passin, "Private Key"); + break; + + case KEY_PUBKEY: + pkey = load_pubkey(bio_err, keyfile, keyform, 0, + NULL, "Public Key"); + break; + + case KEY_CERT: + x = load_cert(bio_err, keyfile, keyform, + NULL, "Certificate"); + if (x) { + pkey = X509_get_pubkey(x); + X509_free(x); + } + break; + } + + if (!pkey) + goto end; + + rsa = EVP_PKEY_get1_RSA(pkey); + EVP_PKEY_free(pkey); + + if (!rsa) { + BIO_printf(bio_err, "Error getting RSA key\n"); + ERR_print_errors(bio_err); + goto end; + } + if (infile) { + if (!(in = BIO_new_file(infile, "rb"))) { + BIO_printf(bio_err, "Error Reading Input File\n"); + ERR_print_errors(bio_err); + goto end; + } + } else + in = BIO_new_fp(stdin, BIO_NOCLOSE); + + if (outfile) { + if (!(out = BIO_new_file(outfile, "wb"))) { + BIO_printf(bio_err, "Error Reading Output File\n"); + ERR_print_errors(bio_err); + goto end; + } + } else { + out = BIO_new_fp(stdout, BIO_NOCLOSE); + } + + keysize = RSA_size(rsa); + + rsa_in = reallocarray(NULL, keysize, 2); + if (rsa_in == NULL) { + BIO_printf(bio_err, "Error allocating memory for input data\n"); + exit(1); + } + rsa_out = malloc(keysize); + if (rsa_out == NULL) { + BIO_printf(bio_err, "Error allocating memory for output data\n"); + exit(1); + } + + /* Read the input data */ + rsa_inlen = BIO_read(in, rsa_in, keysize * 2); + if (rsa_inlen <= 0) { + BIO_printf(bio_err, "Error reading input Data\n"); + exit(1); + } + if (rev) { + int i; + unsigned char ctmp; + for (i = 0; i < rsa_inlen / 2; i++) { + ctmp = rsa_in[i]; + rsa_in[i] = rsa_in[rsa_inlen - 1 - i]; + rsa_in[rsa_inlen - 1 - i] = ctmp; + } + } + switch (rsa_mode) { + + case RSA_VERIFY: + rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); + break; + + case RSA_SIGN: + rsa_outlen = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); + break; + + case RSA_ENCRYPT: + rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); + break; + + case RSA_DECRYPT: + rsa_outlen = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); + break; + + } + + if (rsa_outlen <= 0) { + BIO_printf(bio_err, "RSA operation error\n"); + ERR_print_errors(bio_err); + goto end; + } + ret = 0; + if (asn1parse) { + if (!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) { + ERR_print_errors(bio_err); + } + } else if (hexdump) + BIO_dump(out, (char *) rsa_out, rsa_outlen); + else + BIO_write(out, rsa_out, rsa_outlen); + +end: + RSA_free(rsa); + BIO_free(in); + BIO_free_all(out); + free(rsa_in); + free(rsa_out); + free(passin); + + return ret; +} + +static void +usage() +{ + BIO_printf(bio_err, "Usage: rsautl [options]\n"); + BIO_printf(bio_err, "-in file input file\n"); + BIO_printf(bio_err, "-out file output file\n"); + BIO_printf(bio_err, "-inkey file input key\n"); + BIO_printf(bio_err, "-keyform arg private key format - default PEM\n"); + BIO_printf(bio_err, "-pubin input is an RSA public\n"); + BIO_printf(bio_err, "-certin input is a certificate carrying an RSA public key\n"); + BIO_printf(bio_err, "-ssl use SSL v2 padding\n"); + BIO_printf(bio_err, "-raw use no padding\n"); + BIO_printf(bio_err, "-pkcs use PKCS#1 v1.5 padding (default)\n"); + BIO_printf(bio_err, "-oaep use PKCS#1 OAEP\n"); + BIO_printf(bio_err, "-sign sign with private key\n"); + BIO_printf(bio_err, "-verify verify with public key\n"); + BIO_printf(bio_err, "-encrypt encrypt with public key\n"); + BIO_printf(bio_err, "-decrypt decrypt with private key\n"); + BIO_printf(bio_err, "-hexdump hex dump output\n"); +} diff --git a/crypto/libressl/apps/openssl/s_apps.h b/crypto/libressl/apps/openssl/s_apps.h new file mode 100644 index 0000000000..ebc6029796 --- /dev/null +++ b/crypto/libressl/apps/openssl/s_apps.h @@ -0,0 +1,150 @@ +/* $OpenBSD: s_apps.h,v 1.2 2015/04/14 12:56:36 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include +#include + +#define PORT 4433 +#define PORT_STR "4433" +#define PROTOCOL "tcp" + +extern int verify_depth; +extern int verify_return_error; + +int do_server(int port, int type, int *ret, + int (*cb)(char *hostname, int s, unsigned char *context), + unsigned char *context); +#ifdef HEADER_X509_H +int verify_callback(int ok, X509_STORE_CTX *ctx); +#endif +#ifdef HEADER_SSL_H +int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file); +int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key); +#endif +int init_client(int *sock, char *server, char *port, int type, int af); +int should_retry(int i); +int extract_port(char *str, short *port_ptr); +int extract_host_port(char *str, char **host_ptr, unsigned char *ip, char **p); + +long bio_dump_callback(BIO *bio, int cmd, const char *argp, int argi, + long argl, long ret); + +#ifdef HEADER_SSL_H +void apps_ssl_info_callback(const SSL *s, int where, int ret); +void msg_cb(int write_p, int version, int content_type, const void *buf, + size_t len, SSL *ssl, void *arg); +void tlsext_cb(SSL *s, int client_server, int type, unsigned char *data, + int len, void *arg); +#endif + +int generate_cookie_callback(SSL *ssl, unsigned char *cookie, + unsigned int *cookie_len); +int verify_cookie_callback(SSL *ssl, unsigned char *cookie, + unsigned int cookie_len); diff --git a/crypto/libressl/apps/openssl/s_cb.c b/crypto/libressl/apps/openssl/s_cb.c new file mode 100644 index 0000000000..96177a58f4 --- /dev/null +++ b/crypto/libressl/apps/openssl/s_cb.c @@ -0,0 +1,849 @@ +/* $OpenBSD: s_cb.c,v 1.5 2015/09/10 06:36:45 bcook Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include +#include +#include +#include + +#include "apps.h" + +#include +#include +#include + +#include "s_apps.h" + +#define COOKIE_SECRET_LENGTH 16 + +int verify_depth = 0; +int verify_return_error = 0; +unsigned char cookie_secret[COOKIE_SECRET_LENGTH]; +int cookie_initialized = 0; + +int +verify_callback(int ok, X509_STORE_CTX * ctx) +{ + X509 *err_cert; + int err, depth; + + err_cert = X509_STORE_CTX_get_current_cert(ctx); + err = X509_STORE_CTX_get_error(ctx); + depth = X509_STORE_CTX_get_error_depth(ctx); + + BIO_printf(bio_err, "depth=%d ", depth); + if (err_cert) { + X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert), + 0, XN_FLAG_ONELINE); + BIO_puts(bio_err, "\n"); + } else + BIO_puts(bio_err, "\n"); + if (!ok) { + BIO_printf(bio_err, "verify error:num=%d:%s\n", err, + X509_verify_cert_error_string(err)); + if (verify_depth >= depth) { + if (!verify_return_error) + ok = 1; + } else { + ok = 0; + } + } + switch (err) { + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: + BIO_puts(bio_err, "issuer= "); + if (err_cert == NULL) + BIO_puts(bio_err, ""); + else + X509_NAME_print_ex(bio_err, + X509_get_issuer_name(err_cert), 0, XN_FLAG_ONELINE); + BIO_puts(bio_err, "\n"); + break; + case X509_V_ERR_CERT_NOT_YET_VALID: + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: + BIO_printf(bio_err, "notBefore="); + if (err_cert == NULL) + BIO_printf(bio_err, " "); + else + ASN1_TIME_print(bio_err, X509_get_notBefore(err_cert)); + BIO_printf(bio_err, "\n"); + break; + case X509_V_ERR_CERT_HAS_EXPIRED: + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: + BIO_printf(bio_err, "notAfter="); + if (err_cert == NULL) + BIO_printf(bio_err, " "); + else + ASN1_TIME_print(bio_err, X509_get_notAfter(err_cert)); + BIO_printf(bio_err, "\n"); + break; + case X509_V_ERR_NO_EXPLICIT_POLICY: + policies_print(bio_err, ctx); + break; + } + if (err == X509_V_OK && ok == 2) + policies_print(bio_err, ctx); + + BIO_printf(bio_err, "verify return:%d\n", ok); + return (ok); +} + +int +set_cert_stuff(SSL_CTX * ctx, char *cert_file, char *key_file) +{ + if (cert_file != NULL) { + /* + SSL *ssl; + X509 *x509; + */ + + if (SSL_CTX_use_certificate_file(ctx, cert_file, + SSL_FILETYPE_PEM) <= 0) { + BIO_printf(bio_err, + "unable to get certificate from '%s'\n", cert_file); + ERR_print_errors(bio_err); + return (0); + } + if (key_file == NULL) + key_file = cert_file; + if (SSL_CTX_use_PrivateKey_file(ctx, key_file, + SSL_FILETYPE_PEM) <= 0) { + BIO_printf(bio_err, + "unable to get private key from '%s'\n", key_file); + ERR_print_errors(bio_err); + return (0); + } + /* + In theory this is no longer needed + ssl=SSL_new(ctx); + x509=SSL_get_certificate(ssl); + + if (x509 != NULL) { + EVP_PKEY *pktmp; + pktmp = X509_get_pubkey(x509); + EVP_PKEY_copy_parameters(pktmp, + SSL_get_privatekey(ssl)); + EVP_PKEY_free(pktmp); + } + SSL_free(ssl); + */ + + /* + * If we are using DSA, we can copy the parameters from the + * private key + */ + + + /* + * Now we know that a key and cert have been set against the + * SSL context + */ + if (!SSL_CTX_check_private_key(ctx)) { + BIO_printf(bio_err, + "Private key does not match the certificate public key\n"); + return (0); + } + } + return (1); +} + +int +set_cert_key_stuff(SSL_CTX * ctx, X509 * cert, EVP_PKEY * key) +{ + if (cert == NULL) + return 1; + if (SSL_CTX_use_certificate(ctx, cert) <= 0) { + BIO_printf(bio_err, "error setting certificate\n"); + ERR_print_errors(bio_err); + return 0; + } + if (SSL_CTX_use_PrivateKey(ctx, key) <= 0) { + BIO_printf(bio_err, "error setting private key\n"); + ERR_print_errors(bio_err); + return 0; + } + /* + * Now we know that a key and cert have been set against the SSL + * context + */ + if (!SSL_CTX_check_private_key(ctx)) { + BIO_printf(bio_err, + "Private key does not match the certificate public key\n"); + return 0; + } + return 1; +} + +long +bio_dump_callback(BIO * bio, int cmd, const char *argp, + int argi, long argl, long ret) +{ + BIO *out; + + out = (BIO *) BIO_get_callback_arg(bio); + if (out == NULL) + return (ret); + + if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) { + BIO_printf(out, + "read from %p [%p] (%lu bytes => %ld (0x%lX))\n", + (void *) bio, argp, (unsigned long) argi, ret, ret); + BIO_dump(out, argp, (int) ret); + return (ret); + } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) { + BIO_printf(out, + "write to %p [%p] (%lu bytes => %ld (0x%lX))\n", + (void *) bio, argp, (unsigned long) argi, ret, ret); + BIO_dump(out, argp, (int) ret); + } + return (ret); +} + +void +apps_ssl_info_callback(const SSL * s, int where, int ret) +{ + const char *str; + int w; + + w = where & ~SSL_ST_MASK; + + if (w & SSL_ST_CONNECT) + str = "SSL_connect"; + else if (w & SSL_ST_ACCEPT) + str = "SSL_accept"; + else + str = "undefined"; + + if (where & SSL_CB_LOOP) { + BIO_printf(bio_err, "%s:%s\n", str, SSL_state_string_long(s)); + } else if (where & SSL_CB_ALERT) { + str = (where & SSL_CB_READ) ? "read" : "write"; + BIO_printf(bio_err, "SSL3 alert %s:%s:%s\n", str, + SSL_alert_type_string_long(ret), + SSL_alert_desc_string_long(ret)); + } else if (where & SSL_CB_EXIT) { + if (ret == 0) + BIO_printf(bio_err, "%s:failed in %s\n", + str, SSL_state_string_long(s)); + else if (ret < 0) { + BIO_printf(bio_err, "%s:error in %s\n", + str, SSL_state_string_long(s)); + } + } +} + + +void +msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL * ssl, void *arg) +{ + BIO *bio = arg; + const char *str_write_p, *str_version, *str_content_type = "", + *str_details1 = "", *str_details2 = ""; + + str_write_p = write_p ? ">>>" : "<<<"; + + switch (version) { + case SSL2_VERSION: + str_version = "SSL 2.0"; + break; + case SSL3_VERSION: + str_version = "SSL 3.0 "; + break; + case TLS1_VERSION: + str_version = "TLS 1.0 "; + break; + case TLS1_1_VERSION: + str_version = "TLS 1.1 "; + break; + case TLS1_2_VERSION: + str_version = "TLS 1.2 "; + break; + case DTLS1_VERSION: + str_version = "DTLS 1.0 "; + break; + default: + str_version = "???"; + } + + if (version == SSL2_VERSION) { + str_details1 = "???"; + + if (len > 0) { + switch (((const unsigned char *) buf)[0]) { + case 0: + str_details1 = ", ERROR:"; + str_details2 = " ???"; + if (len >= 3) { + unsigned err = (((const unsigned char *) buf)[1] << 8) + ((const unsigned char *) buf)[2]; + + switch (err) { + case 0x0001: + str_details2 = " NO-CIPHER-ERROR"; + break; + case 0x0002: + str_details2 = " NO-CERTIFICATE-ERROR"; + break; + case 0x0004: + str_details2 = " BAD-CERTIFICATE-ERROR"; + break; + case 0x0006: + str_details2 = " UNSUPPORTED-CERTIFICATE-TYPE-ERROR"; + break; + } + } + break; + case 1: + str_details1 = ", CLIENT-HELLO"; + break; + case 2: + str_details1 = ", CLIENT-MASTER-KEY"; + break; + case 3: + str_details1 = ", CLIENT-FINISHED"; + break; + case 4: + str_details1 = ", SERVER-HELLO"; + break; + case 5: + str_details1 = ", SERVER-VERIFY"; + break; + case 6: + str_details1 = ", SERVER-FINISHED"; + break; + case 7: + str_details1 = ", REQUEST-CERTIFICATE"; + break; + case 8: + str_details1 = ", CLIENT-CERTIFICATE"; + break; + } + } + } + if (version == SSL3_VERSION || version == TLS1_VERSION || + version == TLS1_1_VERSION || version == TLS1_2_VERSION || + version == DTLS1_VERSION) { + switch (content_type) { + case 20: + str_content_type = "ChangeCipherSpec"; + break; + case 21: + str_content_type = "Alert"; + break; + case 22: + str_content_type = "Handshake"; + break; + } + + if (content_type == 21) { /* Alert */ + str_details1 = ", ???"; + + if (len == 2) { + switch (((const unsigned char *) buf)[0]) { + case 1: + str_details1 = ", warning"; + break; + case 2: + str_details1 = ", fatal"; + break; + } + + str_details2 = " ???"; + switch (((const unsigned char *) buf)[1]) { + case 0: + str_details2 = " close_notify"; + break; + case 10: + str_details2 = " unexpected_message"; + break; + case 20: + str_details2 = " bad_record_mac"; + break; + case 21: + str_details2 = " decryption_failed"; + break; + case 22: + str_details2 = " record_overflow"; + break; + case 30: + str_details2 = " decompression_failure"; + break; + case 40: + str_details2 = " handshake_failure"; + break; + case 42: + str_details2 = " bad_certificate"; + break; + case 43: + str_details2 = " unsupported_certificate"; + break; + case 44: + str_details2 = " certificate_revoked"; + break; + case 45: + str_details2 = " certificate_expired"; + break; + case 46: + str_details2 = " certificate_unknown"; + break; + case 47: + str_details2 = " illegal_parameter"; + break; + case 48: + str_details2 = " unknown_ca"; + break; + case 49: + str_details2 = " access_denied"; + break; + case 50: + str_details2 = " decode_error"; + break; + case 51: + str_details2 = " decrypt_error"; + break; + case 60: + str_details2 = " export_restriction"; + break; + case 70: + str_details2 = " protocol_version"; + break; + case 71: + str_details2 = " insufficient_security"; + break; + case 80: + str_details2 = " internal_error"; + break; + case 90: + str_details2 = " user_canceled"; + break; + case 100: + str_details2 = " no_renegotiation"; + break; + case 110: + str_details2 = " unsupported_extension"; + break; + case 111: + str_details2 = " certificate_unobtainable"; + break; + case 112: + str_details2 = " unrecognized_name"; + break; + case 113: + str_details2 = " bad_certificate_status_response"; + break; + case 114: + str_details2 = " bad_certificate_hash_value"; + break; + case 115: + str_details2 = " unknown_psk_identity"; + break; + } + } + } + if (content_type == 22) { /* Handshake */ + str_details1 = "???"; + + if (len > 0) { + switch (((const unsigned char *) buf)[0]) { + case 0: + str_details1 = ", HelloRequest"; + break; + case 1: + str_details1 = ", ClientHello"; + break; + case 2: + str_details1 = ", ServerHello"; + break; + case 3: + str_details1 = ", HelloVerifyRequest"; + break; + case 11: + str_details1 = ", Certificate"; + break; + case 12: + str_details1 = ", ServerKeyExchange"; + break; + case 13: + str_details1 = ", CertificateRequest"; + break; + case 14: + str_details1 = ", ServerHelloDone"; + break; + case 15: + str_details1 = ", CertificateVerify"; + break; + case 16: + str_details1 = ", ClientKeyExchange"; + break; + case 20: + str_details1 = ", Finished"; + break; + } + } + } + } + BIO_printf(bio, "%s %s%s [length %04lx]%s%s\n", str_write_p, + str_version, str_content_type, (unsigned long) len, + str_details1, str_details2); + + if (len > 0) { + size_t num, i; + + BIO_printf(bio, " "); + num = len; + + for (i = 0; i < num; i++) { + if (i % 16 == 0 && i > 0) + BIO_printf(bio, "\n "); + BIO_printf(bio, " %02x", + ((const unsigned char *) buf)[i]); + } + if (i < len) + BIO_printf(bio, " ..."); + BIO_printf(bio, "\n"); + } + (void) BIO_flush(bio); +} + +void +tlsext_cb(SSL * s, int client_server, int type, unsigned char *data, int len, + void *arg) +{ + BIO *bio = arg; + char *extname; + + switch (type) { + case TLSEXT_TYPE_server_name: + extname = "server name"; + break; + + case TLSEXT_TYPE_max_fragment_length: + extname = "max fragment length"; + break; + + case TLSEXT_TYPE_client_certificate_url: + extname = "client certificate URL"; + break; + + case TLSEXT_TYPE_trusted_ca_keys: + extname = "trusted CA keys"; + break; + + case TLSEXT_TYPE_truncated_hmac: + extname = "truncated HMAC"; + break; + + case TLSEXT_TYPE_status_request: + extname = "status request"; + break; + + case TLSEXT_TYPE_user_mapping: + extname = "user mapping"; + break; + + case TLSEXT_TYPE_client_authz: + extname = "client authz"; + break; + + case TLSEXT_TYPE_server_authz: + extname = "server authz"; + break; + + case TLSEXT_TYPE_cert_type: + extname = "cert type"; + break; + + case TLSEXT_TYPE_elliptic_curves: + extname = "elliptic curves"; + break; + + case TLSEXT_TYPE_ec_point_formats: + extname = "EC point formats"; + break; + + case TLSEXT_TYPE_srp: + extname = "SRP"; + break; + + case TLSEXT_TYPE_signature_algorithms: + extname = "signature algorithms"; + break; + + case TLSEXT_TYPE_use_srtp: + extname = "use SRTP"; + break; + + case TLSEXT_TYPE_heartbeat: + extname = "heartbeat"; + break; + + case TLSEXT_TYPE_session_ticket: + extname = "session ticket"; + break; + + case TLSEXT_TYPE_renegotiate: + extname = "renegotiation info"; + break; + +#ifdef TLSEXT_TYPE_next_proto_neg + case TLSEXT_TYPE_next_proto_neg: + extname = "next protocol"; + break; +#endif + + default: + extname = "unknown"; + break; + + } + + BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n", + client_server ? "server" : "client", extname, type, len); + BIO_dump(bio, (char *) data, len); + (void) BIO_flush(bio); +} + +int +generate_cookie_callback(SSL * ssl, unsigned char *cookie, + unsigned int *cookie_len) +{ + unsigned char *buffer, result[EVP_MAX_MD_SIZE]; + unsigned int length, resultlength; + union { + struct sockaddr sa; + struct sockaddr_in s4; + struct sockaddr_in6 s6; + } peer; + + /* Initialize a random secret */ + if (!cookie_initialized) { + arc4random_buf(cookie_secret, COOKIE_SECRET_LENGTH); + cookie_initialized = 1; + } + /* Read peer information */ + (void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); + + /* Create buffer with peer's address and port */ + length = 0; + switch (peer.sa.sa_family) { + case AF_INET: + length += sizeof(struct in_addr); + length += sizeof(peer.s4.sin_port); + break; + case AF_INET6: + length += sizeof(struct in6_addr); + length += sizeof(peer.s6.sin6_port); + break; + default: + OPENSSL_assert(0); + break; + } + buffer = malloc(length); + + if (buffer == NULL) { + BIO_printf(bio_err, "out of memory\n"); + return 0; + } + switch (peer.sa.sa_family) { + case AF_INET: + memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port)); + memcpy(buffer + sizeof(peer.s4.sin_port), + &peer.s4.sin_addr, sizeof(struct in_addr)); + break; + case AF_INET6: + memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port)); + memcpy(buffer + sizeof(peer.s6.sin6_port), + &peer.s6.sin6_addr, sizeof(struct in6_addr)); + break; + default: + OPENSSL_assert(0); + break; + } + + /* Calculate HMAC of buffer using the secret */ + HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, + buffer, length, result, &resultlength); + free(buffer); + + memcpy(cookie, result, resultlength); + *cookie_len = resultlength; + + return 1; +} + +int +verify_cookie_callback(SSL * ssl, unsigned char *cookie, unsigned int cookie_len) +{ + unsigned char *buffer, result[EVP_MAX_MD_SIZE]; + unsigned int length, resultlength; + union { + struct sockaddr sa; + struct sockaddr_in s4; + struct sockaddr_in6 s6; + } peer; + + /* If secret isn't initialized yet, the cookie can't be valid */ + if (!cookie_initialized) + return 0; + + /* Read peer information */ + (void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); + + /* Create buffer with peer's address and port */ + length = 0; + switch (peer.sa.sa_family) { + case AF_INET: + length += sizeof(struct in_addr); + length += sizeof(peer.s4.sin_port); + break; + case AF_INET6: + length += sizeof(struct in6_addr); + length += sizeof(peer.s6.sin6_port); + break; + default: + OPENSSL_assert(0); + break; + } + buffer = malloc(length); + + if (buffer == NULL) { + BIO_printf(bio_err, "out of memory\n"); + return 0; + } + switch (peer.sa.sa_family) { + case AF_INET: + memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port)); + memcpy(buffer + sizeof(peer.s4.sin_port), + &peer.s4.sin_addr, sizeof(struct in_addr)); + break; + case AF_INET6: + memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port)); + memcpy(buffer + sizeof(peer.s6.sin6_port), + &peer.s6.sin6_addr, sizeof(struct in6_addr)); + break; + default: + OPENSSL_assert(0); + break; + } + + /* Calculate HMAC of buffer using the secret */ + HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, + buffer, length, result, &resultlength); + free(buffer); + + if (cookie_len == resultlength && + memcmp(result, cookie, resultlength) == 0) + return 1; + + return 0; +} diff --git a/crypto/libressl/apps/openssl/s_client.c b/crypto/libressl/apps/openssl/s_client.c new file mode 100644 index 0000000000..d945d90cd6 --- /dev/null +++ b/crypto/libressl/apps/openssl/s_client.c @@ -0,0 +1,1488 @@ +/* $OpenBSD: s_client.c,v 1.27 2015/12/01 12:01:56 jca Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "apps.h" + +#include +#include +#include +#include +#include +#include + +#include "s_apps.h" +#include "timeouts.h" + +/*#define SSL_HOST_NAME "www.netscape.com" */ +/*#define SSL_HOST_NAME "193.118.187.102" */ +#define SSL_HOST_NAME "localhost" + + /*#define TEST_CERT "client.pem" *//* no default cert. */ + +#define BUFSIZZ 1024*8 + +static int c_nbio = 0; +static int c_Pause = 0; +static int c_debug = 0; +static int c_tlsextdebug = 0; +static int c_status_req = 0; +static int c_msg = 0; +static int c_showcerts = 0; + +static char *keymatexportlabel = NULL; +static int keymatexportlen = 20; + +static void sc_usage(void); +static void print_stuff(BIO * berr, SSL * con, int full); +static int ocsp_resp_cb(SSL * s, void *arg); +static BIO *bio_c_out = NULL; +static int c_quiet = 0; +static int c_ign_eof = 0; + + +static void +sc_usage(void) +{ + BIO_printf(bio_err, "usage: s_client args\n"); + BIO_printf(bio_err, "\n"); + BIO_printf(bio_err, " -4 - Force IPv4\n"); + BIO_printf(bio_err, " -6 - Force IPv6\n"); + BIO_printf(bio_err, " -host host - use -connect instead\n"); + BIO_printf(bio_err, " -port port - use -connect instead\n"); + BIO_printf(bio_err, " -connect host:port - who to connect to (default is %s:%s)\n", SSL_HOST_NAME, PORT_STR); + BIO_printf(bio_err, " -proxy host:port - connect to http proxy\n"); + + BIO_printf(bio_err, " -verify arg - turn on peer certificate verification\n"); + BIO_printf(bio_err, " -cert arg - certificate file to use, PEM format assumed\n"); + BIO_printf(bio_err, " -certform arg - certificate format (PEM or DER) PEM default\n"); + BIO_printf(bio_err, " -key arg - Private key file to use, in cert file if\n"); + BIO_printf(bio_err, " not specified but cert file is.\n"); + BIO_printf(bio_err, " -keyform arg - key format (PEM or DER) PEM default\n"); + BIO_printf(bio_err, " -pass arg - private key file pass phrase source\n"); + BIO_printf(bio_err, " -CApath arg - PEM format directory of CA's\n"); + BIO_printf(bio_err, " -CAfile arg - PEM format file of CA's\n"); + BIO_printf(bio_err, " -reconnect - Drop and re-make the connection with the same Session-ID\n"); + BIO_printf(bio_err, " -pause - sleep(1) after each read(2) and write(2) system call\n"); + BIO_printf(bio_err, " -showcerts - show all certificates in the chain\n"); + BIO_printf(bio_err, " -debug - extra output\n"); + BIO_printf(bio_err, " -msg - Show protocol messages\n"); + BIO_printf(bio_err, " -nbio_test - more ssl protocol testing\n"); + BIO_printf(bio_err, " -state - print the 'ssl' states\n"); + BIO_printf(bio_err, " -nbio - Run with non-blocking IO\n"); + BIO_printf(bio_err, " -crlf - convert LF from terminal into CRLF\n"); + BIO_printf(bio_err, " -quiet - no s_client output\n"); + BIO_printf(bio_err, " -ign_eof - ignore input eof (default when -quiet)\n"); + BIO_printf(bio_err, " -no_ign_eof - don't ignore input eof\n"); + BIO_printf(bio_err, " -tls1_2 - just use TLSv1.2\n"); + BIO_printf(bio_err, " -tls1_1 - just use TLSv1.1\n"); + BIO_printf(bio_err, " -tls1 - just use TLSv1\n"); + BIO_printf(bio_err, " -dtls1 - just use DTLSv1\n"); + BIO_printf(bio_err, " -mtu - set the link layer MTU\n"); + BIO_printf(bio_err, " -no_tls1_2/-no_tls1_1/-no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n"); + BIO_printf(bio_err, " -bugs - Switch on all SSL implementation bug workarounds\n"); + BIO_printf(bio_err, " -cipher - preferred cipher to use, use the 'openssl ciphers'\n"); + BIO_printf(bio_err, " command to see what is available\n"); + BIO_printf(bio_err, " -starttls prot - use the STARTTLS command before starting TLS\n"); + BIO_printf(bio_err, " for those protocols that support it, where\n"); + BIO_printf(bio_err, " 'prot' defines which one to assume. Currently,\n"); + BIO_printf(bio_err, " only \"smtp\", \"lmtp\", \"pop3\", \"imap\", \"ftp\" and \"xmpp\"\n"); + BIO_printf(bio_err, " are supported.\n"); + BIO_printf(bio_err, " -xmpphost host - connect to this virtual host on the xmpp server\n"); + BIO_printf(bio_err, " -sess_out arg - file to write SSL session to\n"); + BIO_printf(bio_err, " -sess_in arg - file to read SSL session from\n"); + BIO_printf(bio_err, " -servername host - Set TLS extension servername in ClientHello\n"); + BIO_printf(bio_err, " -tlsextdebug - hex dump of all TLS extensions received\n"); + BIO_printf(bio_err, " -status - request certificate status from server\n"); + BIO_printf(bio_err, " -no_ticket - disable use of RFC4507bis session tickets\n"); + BIO_printf(bio_err, " -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n"); + BIO_printf(bio_err, " -alpn arg - enable ALPN extension, considering named protocols supported (comma-separated list)\n"); +#ifndef OPENSSL_NO_SRTP + BIO_printf(bio_err, " -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n"); +#endif + BIO_printf(bio_err, " -keymatexport label - Export keying material using label\n"); + BIO_printf(bio_err, " -keymatexportlen len - Export len bytes of keying material (default 20)\n"); +} + + +/* This is a context that we pass to callbacks */ +typedef struct tlsextctx_st { + BIO *biodebug; + int ack; +} tlsextctx; + + +static int +ssl_servername_cb(SSL * s, int *ad, void *arg) +{ + tlsextctx *p = (tlsextctx *) arg; + const char *hn = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); + if (SSL_get_servername_type(s) != -1) + p->ack = !SSL_session_reused(s) && hn != NULL; + else + BIO_printf(bio_err, "Can't use SSL_get_servername\n"); + + return SSL_TLSEXT_ERR_OK; +} + +#ifndef OPENSSL_NO_SRTP +char *srtp_profiles = NULL; +#endif + +/* This the context that we pass to next_proto_cb */ +typedef struct tlsextnextprotoctx_st { + unsigned char *data; + unsigned short len; + int status; +} tlsextnextprotoctx; + +static tlsextnextprotoctx next_proto; + +static int +next_proto_cb(SSL * s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg) +{ + tlsextnextprotoctx *ctx = arg; + + if (!c_quiet) { + /* We can assume that |in| is syntactically valid. */ + unsigned i; + BIO_printf(bio_c_out, "Protocols advertised by server: "); + for (i = 0; i < inlen;) { + if (i) + BIO_write(bio_c_out, ", ", 2); + BIO_write(bio_c_out, &in[i + 1], in[i]); + i += in[i] + 1; + } + BIO_write(bio_c_out, "\n", 1); + } + ctx->status = SSL_select_next_proto(out, outlen, in, inlen, ctx->data, ctx->len); + return SSL_TLSEXT_ERR_OK; +} + +enum { + PROTO_OFF = 0, + PROTO_SMTP, + PROTO_LMTP, + PROTO_POP3, + PROTO_IMAP, + PROTO_FTP, + PROTO_XMPP +}; + +int +s_client_main(int argc, char **argv) +{ + unsigned int off = 0, clr = 0; + SSL *con = NULL; + int s, k, state = 0, af = AF_UNSPEC; + char *cbuf = NULL, *sbuf = NULL, *mbuf = NULL; + int cbuf_len, cbuf_off; + int sbuf_len, sbuf_off; + char *port = PORT_STR; + int full_log = 1; + char *host = SSL_HOST_NAME; + char *xmpphost = NULL; + char *proxy = NULL, *connect = NULL; + char *cert_file = NULL, *key_file = NULL; + int cert_format = FORMAT_PEM, key_format = FORMAT_PEM; + char *passarg = NULL, *pass = NULL; + X509 *cert = NULL; + EVP_PKEY *key = NULL; + char *CApath = NULL, *CAfile = NULL, *cipher = NULL; + int reconnect = 0, badop = 0, verify = SSL_VERIFY_NONE, bugs = 0; + int crlf = 0; + int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending; + SSL_CTX *ctx = NULL; + int ret = 1, in_init = 1, i, nbio_test = 0; + int starttls_proto = PROTO_OFF; + int prexit = 0; + X509_VERIFY_PARAM *vpm = NULL; + int badarg = 0; + const SSL_METHOD *meth = NULL; + int socket_type = SOCK_STREAM; + BIO *sbio; + int mbuf_len = 0; + struct timeval timeout; + const char *errstr = NULL; + char *servername = NULL; + tlsextctx tlsextcbp = + {NULL, 0}; + const char *next_proto_neg_in = NULL; + const char *alpn_in = NULL; + char *sess_in = NULL; + char *sess_out = NULL; + struct sockaddr peer; + int peerlen = sizeof(peer); + int enable_timeouts = 0; + long socket_mtu = 0; + + if (single_execution) { + if (pledge("stdio inet dns rpath wpath cpath tty", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + meth = SSLv23_client_method(); + + c_Pause = 0; + c_quiet = 0; + c_ign_eof = 0; + c_debug = 0; + c_msg = 0; + c_showcerts = 0; + + if (((cbuf = malloc(BUFSIZZ)) == NULL) || + ((sbuf = malloc(BUFSIZZ)) == NULL) || + ((mbuf = malloc(BUFSIZZ + 1)) == NULL)) { /* NUL byte */ + BIO_printf(bio_err, "out of memory\n"); + goto end; + } + verify_depth = 0; + c_nbio = 0; + + argc--; + argv++; + while (argc >= 1) { + if (strcmp(*argv, "-host") == 0) { + if (--argc < 1) + goto bad; + host = *(++argv); + } else if (strcmp(*argv, "-port") == 0) { + if (--argc < 1) + goto bad; + port = *(++argv); + if (port == NULL || *port == '\0') + goto bad; + } else if (strcmp(*argv, "-connect") == 0) { + if (--argc < 1) + goto bad; + connect = *(++argv); + } else if (strcmp(*argv, "-proxy") == 0) { + if (--argc < 1) + goto bad; + proxy = *(++argv); + } else if (strcmp(*argv,"-xmpphost") == 0) { + if (--argc < 1) + goto bad; + xmpphost= *(++argv); + } else if (strcmp(*argv, "-verify") == 0) { + verify = SSL_VERIFY_PEER; + if (--argc < 1) + goto bad; + verify_depth = strtonum(*(++argv), 0, INT_MAX, &errstr); + if (errstr) + goto bad; + BIO_printf(bio_err, "verify depth is %d\n", verify_depth); + } else if (strcmp(*argv, "-cert") == 0) { + if (--argc < 1) + goto bad; + cert_file = *(++argv); + } else if (strcmp(*argv, "-sess_out") == 0) { + if (--argc < 1) + goto bad; + sess_out = *(++argv); + } else if (strcmp(*argv, "-sess_in") == 0) { + if (--argc < 1) + goto bad; + sess_in = *(++argv); + } else if (strcmp(*argv, "-certform") == 0) { + if (--argc < 1) + goto bad; + cert_format = str2fmt(*(++argv)); + } else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) { + if (badarg) + goto bad; + continue; + } else if (strcmp(*argv, "-verify_return_error") == 0) + verify_return_error = 1; + else if (strcmp(*argv, "-prexit") == 0) + prexit = 1; + else if (strcmp(*argv, "-crlf") == 0) + crlf = 1; + else if (strcmp(*argv, "-quiet") == 0) { + c_quiet = 1; + c_ign_eof = 1; + } else if (strcmp(*argv, "-ign_eof") == 0) + c_ign_eof = 1; + else if (strcmp(*argv, "-no_ign_eof") == 0) + c_ign_eof = 0; + else if (strcmp(*argv, "-pause") == 0) + c_Pause = 1; + else if (strcmp(*argv, "-debug") == 0) + c_debug = 1; + else if (strcmp(*argv, "-tlsextdebug") == 0) + c_tlsextdebug = 1; + else if (strcmp(*argv, "-status") == 0) + c_status_req = 1; + else if (strcmp(*argv, "-msg") == 0) + c_msg = 1; + else if (strcmp(*argv, "-showcerts") == 0) + c_showcerts = 1; + else if (strcmp(*argv, "-nbio_test") == 0) + nbio_test = 1; + else if (strcmp(*argv, "-state") == 0) + state = 1; + else if (strcmp(*argv, "-tls1_2") == 0) + meth = TLSv1_2_client_method(); + else if (strcmp(*argv, "-tls1_1") == 0) + meth = TLSv1_1_client_method(); + else if (strcmp(*argv, "-tls1") == 0) + meth = TLSv1_client_method(); +#ifndef OPENSSL_NO_DTLS1 + else if (strcmp(*argv, "-dtls1") == 0) { + meth = DTLSv1_client_method(); + socket_type = SOCK_DGRAM; + } else if (strcmp(*argv, "-timeout") == 0) + enable_timeouts = 1; + else if (strcmp(*argv, "-mtu") == 0) { + if (--argc < 1) + goto bad; + socket_mtu = strtonum(*(++argv), 0, LONG_MAX, &errstr); + if (errstr) + goto bad; + } +#endif + else if (strcmp(*argv, "-bugs") == 0) + bugs = 1; + else if (strcmp(*argv, "-keyform") == 0) { + if (--argc < 1) + goto bad; + key_format = str2fmt(*(++argv)); + } else if (strcmp(*argv, "-pass") == 0) { + if (--argc < 1) + goto bad; + passarg = *(++argv); + } else if (strcmp(*argv, "-key") == 0) { + if (--argc < 1) + goto bad; + key_file = *(++argv); + } else if (strcmp(*argv, "-reconnect") == 0) { + reconnect = 5; + } else if (strcmp(*argv, "-CApath") == 0) { + if (--argc < 1) + goto bad; + CApath = *(++argv); + } else if (strcmp(*argv, "-CAfile") == 0) { + if (--argc < 1) + goto bad; + CAfile = *(++argv); + } else if (strcmp(*argv, "-no_tls1_2") == 0) + off |= SSL_OP_NO_TLSv1_2; + else if (strcmp(*argv, "-no_tls1_1") == 0) + off |= SSL_OP_NO_TLSv1_1; + else if (strcmp(*argv, "-no_tls1") == 0) + off |= SSL_OP_NO_TLSv1; + else if (strcmp(*argv, "-no_ssl3") == 0) + off |= SSL_OP_NO_SSLv3; + else if (strcmp(*argv, "-no_ssl2") == 0) + off |= SSL_OP_NO_SSLv2; + else if (strcmp(*argv, "-no_comp") == 0) { + off |= SSL_OP_NO_COMPRESSION; + } + else if (strcmp(*argv, "-no_ticket") == 0) { + off |= SSL_OP_NO_TICKET; + } + else if (strcmp(*argv, "-nextprotoneg") == 0) { + if (--argc < 1) + goto bad; + next_proto_neg_in = *(++argv); + } + else if (strcmp(*argv, "-alpn") == 0) { + if (--argc < 1) + goto bad; + alpn_in = *(++argv); + } else if (strcmp(*argv, "-serverpref") == 0) + off |= SSL_OP_CIPHER_SERVER_PREFERENCE; + else if (strcmp(*argv, "-legacy_renegotiation") == 0) + ; /* no-op */ + else if (strcmp(*argv, "-legacy_server_connect") == 0) { + off |= SSL_OP_LEGACY_SERVER_CONNECT; + } else if (strcmp(*argv, "-no_legacy_server_connect") == 0) { + clr |= SSL_OP_LEGACY_SERVER_CONNECT; + } else if (strcmp(*argv, "-cipher") == 0) { + if (--argc < 1) + goto bad; + cipher = *(++argv); + } + else if (strcmp(*argv, "-nbio") == 0) { + c_nbio = 1; + } + else if (strcmp(*argv, "-starttls") == 0) { + if (--argc < 1) + goto bad; + ++argv; + if (strcmp(*argv, "smtp") == 0) + starttls_proto = PROTO_SMTP; + else if (strcmp(*argv, "lmtp") == 0) + starttls_proto = PROTO_LMTP; + else if (strcmp(*argv, "pop3") == 0) + starttls_proto = PROTO_POP3; + else if (strcmp(*argv, "imap") == 0) + starttls_proto = PROTO_IMAP; + else if (strcmp(*argv, "ftp") == 0) + starttls_proto = PROTO_FTP; + else if (strcmp(*argv, "xmpp") == 0) + starttls_proto = PROTO_XMPP; + else + goto bad; + } + else if (strcmp(*argv, "-4") == 0) { + af = AF_INET; + } else if (strcmp(*argv, "-6") == 0) { + af = AF_INET6; + } + else if (strcmp(*argv, "-servername") == 0) { + if (--argc < 1) + goto bad; + servername = *(++argv); + /* meth=TLSv1_client_method(); */ + } +#ifndef OPENSSL_NO_SRTP + else if (strcmp(*argv, "-use_srtp") == 0) { + if (--argc < 1) + goto bad; + srtp_profiles = *(++argv); + } +#endif + else if (strcmp(*argv, "-keymatexport") == 0) { + if (--argc < 1) + goto bad; + keymatexportlabel = *(++argv); + } else if (strcmp(*argv, "-keymatexportlen") == 0) { + if (--argc < 1) + goto bad; + keymatexportlen = strtonum(*(++argv), 1, INT_MAX, &errstr); + if (errstr) + goto bad; + } else { + BIO_printf(bio_err, "unknown option %s\n", *argv); + badop = 1; + break; + } + argc--; + argv++; + } + if (proxy != NULL) { + if (!extract_host_port(proxy, &host, NULL, &port)) + goto bad; + if (connect == NULL) + connect = SSL_HOST_NAME; + } else if (connect != NULL) { + if (!extract_host_port(connect, &host, NULL, &port)) + goto bad; + } + if (badop) { +bad: + if (errstr) + BIO_printf(bio_err, "invalid argument %s: %s\n", + *argv, errstr); + else + sc_usage(); + goto end; + } + + next_proto.status = -1; + if (next_proto_neg_in) { + next_proto.data = next_protos_parse(&next_proto.len, next_proto_neg_in); + if (next_proto.data == NULL) { + BIO_printf(bio_err, "Error parsing -nextprotoneg argument\n"); + goto end; + } + } else + next_proto.data = NULL; + + if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { + BIO_printf(bio_err, "Error getting password\n"); + goto end; + } + if (key_file == NULL) + key_file = cert_file; + + + if (key_file) { + + key = load_key(bio_err, key_file, key_format, 0, pass, + "client certificate private key file"); + if (!key) { + ERR_print_errors(bio_err); + goto end; + } + } + if (cert_file) { + cert = load_cert(bio_err, cert_file, cert_format, + NULL, "client certificate file"); + + if (!cert) { + ERR_print_errors(bio_err); + goto end; + } + } + if (bio_c_out == NULL) { + if (c_quiet && !c_debug && !c_msg) { + bio_c_out = BIO_new(BIO_s_null()); + } else { + if (bio_c_out == NULL) + bio_c_out = BIO_new_fp(stdout, BIO_NOCLOSE); + } + } + + ctx = SSL_CTX_new(meth); + if (ctx == NULL) { + ERR_print_errors(bio_err); + goto end; + } + if (vpm) + SSL_CTX_set1_param(ctx, vpm); + +#ifndef OPENSSL_NO_SRTP + if (srtp_profiles != NULL) + SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles); +#endif + if (bugs) + SSL_CTX_set_options(ctx, SSL_OP_ALL | off); + else + SSL_CTX_set_options(ctx, off); + + if (clr) + SSL_CTX_clear_options(ctx, clr); + /* + * DTLS: partial reads end up discarding unread UDP bytes :-( Setting + * read ahead solves this problem. + */ + if (socket_type == SOCK_DGRAM) + SSL_CTX_set_read_ahead(ctx, 1); + + if (next_proto.data) + SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto); + if (alpn_in) { + unsigned short alpn_len; + unsigned char *alpn = next_protos_parse(&alpn_len, alpn_in); + + if (alpn == NULL) { + BIO_printf(bio_err, "Error parsing -alpn argument\n"); + goto end; + } + SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len); + free(alpn); + } + + if (state) + SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback); + if (cipher != NULL) + if (!SSL_CTX_set_cipher_list(ctx, cipher)) { + BIO_printf(bio_err, "error setting cipher list\n"); + ERR_print_errors(bio_err); + goto end; + } + + SSL_CTX_set_verify(ctx, verify, verify_callback); + if (!set_cert_key_stuff(ctx, cert, key)) + goto end; + + if ((CAfile || CApath) + && !SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) + ERR_print_errors(bio_err); + + if (!SSL_CTX_set_default_verify_paths(ctx)) + ERR_print_errors(bio_err); + + if (servername != NULL) { + tlsextcbp.biodebug = bio_err; + SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); + SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp); + } + + con = SSL_new(ctx); + if (sess_in) { + SSL_SESSION *sess; + BIO *stmp = BIO_new_file(sess_in, "r"); + if (!stmp) { + BIO_printf(bio_err, "Can't open session file %s\n", + sess_in); + ERR_print_errors(bio_err); + goto end; + } + sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL); + BIO_free(stmp); + if (!sess) { + BIO_printf(bio_err, "Can't open session file %s\n", + sess_in); + ERR_print_errors(bio_err); + goto end; + } + SSL_set_session(con, sess); + SSL_SESSION_free(sess); + } + if (servername != NULL) { + if (!SSL_set_tlsext_host_name(con, servername)) { + BIO_printf(bio_err, "Unable to set TLS servername extension.\n"); + ERR_print_errors(bio_err); + goto end; + } + } +/* SSL_set_cipher_list(con,"RC4-MD5"); */ + +re_start: + + if (init_client(&s, host, port, socket_type, af) == 0) { + BIO_printf(bio_err, "connect:errno=%d\n", errno); + goto end; + } + BIO_printf(bio_c_out, "CONNECTED(%08X)\n", s); + + if (c_nbio) { + if (!c_quiet) + BIO_printf(bio_c_out, "turning on non blocking io\n"); + if (!BIO_socket_nbio(s, 1)) { + ERR_print_errors(bio_err); + goto end; + } + } + if (c_Pause & 0x01) + SSL_set_debug(con, 1); + + if (SSL_version(con) == DTLS1_VERSION) { + + sbio = BIO_new_dgram(s, BIO_NOCLOSE); + if (getsockname(s, &peer, (void *) &peerlen) < 0) { + BIO_printf(bio_err, "getsockname:errno=%d\n", + errno); + shutdown(s, SHUT_RD); + close(s); + goto end; + } + (void) BIO_ctrl_set_connected(sbio, 1, &peer); + + if (enable_timeouts) { + timeout.tv_sec = 0; + timeout.tv_usec = DGRAM_RCV_TIMEOUT; + BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); + + timeout.tv_sec = 0; + timeout.tv_usec = DGRAM_SND_TIMEOUT; + BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout); + } + if (socket_mtu > 28) { + SSL_set_options(con, SSL_OP_NO_QUERY_MTU); + SSL_set_mtu(con, socket_mtu - 28); + } else + /* want to do MTU discovery */ + BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); + } else + sbio = BIO_new_socket(s, BIO_NOCLOSE); + + if (nbio_test) { + BIO *test; + + test = BIO_new(BIO_f_nbio_test()); + sbio = BIO_push(test, sbio); + } + if (c_debug) { + SSL_set_debug(con, 1); + BIO_set_callback(sbio, bio_dump_callback); + BIO_set_callback_arg(sbio, (char *) bio_c_out); + } + if (c_msg) { + SSL_set_msg_callback(con, msg_cb); + SSL_set_msg_callback_arg(con, bio_c_out); + } + if (c_tlsextdebug) { + SSL_set_tlsext_debug_callback(con, tlsext_cb); + SSL_set_tlsext_debug_arg(con, bio_c_out); + } + if (c_status_req) { + SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp); + SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb); + SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out); + } + + SSL_set_bio(con, sbio, sbio); + SSL_set_connect_state(con); + + /* ok, lets connect */ + read_tty = 1; + write_tty = 0; + tty_on = 0; + read_ssl = 1; + write_ssl = 1; + + cbuf_len = 0; + cbuf_off = 0; + sbuf_len = 0; + sbuf_off = 0; + + /* This is an ugly hack that does a lot of assumptions */ + /* + * We do have to handle multi-line responses which may come in a + * single packet or not. We therefore have to use BIO_gets() which + * does need a buffering BIO. So during the initial chitchat we do + * push a buffering BIO into the chain that is removed again later on + * to not disturb the rest of the s_client operation. + */ + if (starttls_proto == PROTO_SMTP || starttls_proto == PROTO_LMTP) { + int foundit = 0; + BIO *fbio = BIO_new(BIO_f_buffer()); + BIO_push(fbio, sbio); + /* wait for multi-line response to end from SMTP */ + do { + mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + } + while (mbuf_len > 3 && mbuf[3] == '-'); + /* STARTTLS command requires EHLO... */ + BIO_printf(fbio, "%cHLO openssl.client.net\r\n", + starttls_proto == PROTO_SMTP ? 'E' : 'L'); + (void) BIO_flush(fbio); + /* wait for multi-line response to end EHLO SMTP response */ + do { + mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + if (strstr(mbuf, "STARTTLS")) + foundit = 1; + } + while (mbuf_len > 3 && mbuf[3] == '-'); + (void) BIO_flush(fbio); + BIO_pop(fbio); + BIO_free(fbio); + if (!foundit) + BIO_printf(bio_err, + "didn't found starttls in server response," + " try anyway...\n"); + BIO_printf(sbio, "STARTTLS\r\n"); + BIO_read(sbio, sbuf, BUFSIZZ); + } else if (starttls_proto == PROTO_POP3) { + mbuf_len = BIO_read(sbio, mbuf, BUFSIZZ); + if (mbuf_len == -1) { + BIO_printf(bio_err, "BIO_read failed\n"); + goto end; + } + BIO_printf(sbio, "STLS\r\n"); + BIO_read(sbio, sbuf, BUFSIZZ); + } else if (starttls_proto == PROTO_IMAP) { + int foundit = 0; + BIO *fbio = BIO_new(BIO_f_buffer()); + BIO_push(fbio, sbio); + BIO_gets(fbio, mbuf, BUFSIZZ); + /* STARTTLS command requires CAPABILITY... */ + BIO_printf(fbio, ". CAPABILITY\r\n"); + (void) BIO_flush(fbio); + /* wait for multi-line CAPABILITY response */ + do { + mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + if (strstr(mbuf, "STARTTLS")) + foundit = 1; + } + while (mbuf_len > 3 && mbuf[0] != '.'); + (void) BIO_flush(fbio); + BIO_pop(fbio); + BIO_free(fbio); + if (!foundit) + BIO_printf(bio_err, + "didn't found STARTTLS in server response," + " try anyway...\n"); + BIO_printf(sbio, ". STARTTLS\r\n"); + BIO_read(sbio, sbuf, BUFSIZZ); + } else if (starttls_proto == PROTO_FTP) { + BIO *fbio = BIO_new(BIO_f_buffer()); + BIO_push(fbio, sbio); + /* wait for multi-line response to end from FTP */ + do { + mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + } + while (mbuf_len > 3 && mbuf[3] == '-'); + (void) BIO_flush(fbio); + BIO_pop(fbio); + BIO_free(fbio); + BIO_printf(sbio, "AUTH TLS\r\n"); + BIO_read(sbio, sbuf, BUFSIZZ); + } else if (starttls_proto == PROTO_XMPP) { + int seen = 0; + BIO_printf(sbio, "", xmpphost ? xmpphost : host); + seen = BIO_read(sbio, mbuf, BUFSIZZ); + + if (seen <= 0) + goto shut; + + mbuf[seen] = 0; + while (!strstr(mbuf, ""); + seen = BIO_read(sbio, sbuf, BUFSIZZ); + sbuf[seen] = 0; + if (!strstr(sbuf, " 0) + full_log--; + + if (starttls_proto) { + BIO_write(bio_err, mbuf, mbuf_len); + /* We don't need to know any more */ + starttls_proto = PROTO_OFF; + } + if (reconnect) { + reconnect--; + BIO_printf(bio_c_out, "drop connection and then reconnect\n"); + SSL_shutdown(con); + SSL_set_connect_state(con); + shutdown(SSL_get_fd(con), SHUT_RD); + close(SSL_get_fd(con)); + goto re_start; + } + } + } + + ssl_pending = read_ssl && SSL_pending(con); + + pfd[0].fd = -1; + pfd[1].fd = -1; + if (!ssl_pending) { + if (tty_on) { + if (read_tty) { + pfd[0].fd = fileno(stdin); + pfd[0].events = POLLIN; + } + if (write_tty) { + pfd[1].fd = fileno(stdout); + pfd[1].events = POLLOUT; + } + } + + pfd[2].fd = SSL_get_fd(con); + pfd[2].events = 0; + if (read_ssl) + pfd[2].events |= POLLIN; + if (write_ssl) + pfd[2].events |= POLLOUT; + +/* printf("mode tty(%d %d%d) ssl(%d%d)\n", + tty_on,read_tty,write_tty,read_ssl,write_ssl);*/ + + i = poll(pfd, 3, ptimeout); + if (i < 0) { + BIO_printf(bio_err, "bad select %d\n", + errno); + goto shut; + /* goto end; */ + } + } + if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0) { + BIO_printf(bio_err, "TIMEOUT occured\n"); + } + if (!ssl_pending && (pfd[2].revents & (POLLOUT|POLLERR|POLLNVAL))) { + if (pfd[2].revents & (POLLERR|POLLNVAL)) { + BIO_printf(bio_err, "poll error"); + goto shut; + } + k = SSL_write(con, &(cbuf[cbuf_off]), + (unsigned int) cbuf_len); + switch (SSL_get_error(con, k)) { + case SSL_ERROR_NONE: + cbuf_off += k; + cbuf_len -= k; + if (k <= 0) + goto end; + /* we have done a write(con,NULL,0); */ + if (cbuf_len <= 0) { + read_tty = 1; + write_ssl = 0; + } else { /* if (cbuf_len > 0) */ + read_tty = 0; + write_ssl = 1; + } + break; + case SSL_ERROR_WANT_WRITE: + BIO_printf(bio_c_out, "write W BLOCK\n"); + write_ssl = 1; + read_tty = 0; + break; + case SSL_ERROR_WANT_READ: + BIO_printf(bio_c_out, "write R BLOCK\n"); + write_tty = 0; + read_ssl = 1; + write_ssl = 0; + break; + case SSL_ERROR_WANT_X509_LOOKUP: + BIO_printf(bio_c_out, "write X BLOCK\n"); + break; + case SSL_ERROR_ZERO_RETURN: + if (cbuf_len != 0) { + BIO_printf(bio_c_out, "shutdown\n"); + ret = 0; + goto shut; + } else { + read_tty = 1; + write_ssl = 0; + break; + } + + case SSL_ERROR_SYSCALL: + if ((k != 0) || (cbuf_len != 0)) { + BIO_printf(bio_err, "write:errno=%d\n", + errno); + goto shut; + } else { + read_tty = 1; + write_ssl = 0; + } + break; + case SSL_ERROR_SSL: + ERR_print_errors(bio_err); + goto shut; + } + } else if (!ssl_pending && + (pfd[1].revents & (POLLOUT|POLLERR|POLLNVAL))) { + if (pfd[1].revents & (POLLERR|POLLNVAL)) { + BIO_printf(bio_err, "poll error"); + goto shut; + } + i = write(fileno(stdout), &(sbuf[sbuf_off]), sbuf_len); + + if (i <= 0) { + BIO_printf(bio_c_out, "DONE\n"); + ret = 0; + goto shut; + /* goto end; */ + } + sbuf_len -= i; + sbuf_off += i; + if (sbuf_len <= 0) { + read_ssl = 1; + write_tty = 0; + } + } else if (ssl_pending || (pfd[2].revents & (POLLIN|POLLHUP))) { +#ifdef RENEG + { + static int iiii; + if (++iiii == 52) { + SSL_renegotiate(con); + iiii = 0; + } + } +#endif + k = SSL_read(con, sbuf, 1024 /* BUFSIZZ */ ); + + switch (SSL_get_error(con, k)) { + case SSL_ERROR_NONE: + if (k <= 0) + goto end; + sbuf_off = 0; + sbuf_len = k; + + read_ssl = 0; + write_tty = 1; + break; + case SSL_ERROR_WANT_WRITE: + BIO_printf(bio_c_out, "read W BLOCK\n"); + write_ssl = 1; + read_tty = 0; + break; + case SSL_ERROR_WANT_READ: + BIO_printf(bio_c_out, "read R BLOCK\n"); + write_tty = 0; + read_ssl = 1; + if ((read_tty == 0) && (write_ssl == 0)) + write_ssl = 1; + break; + case SSL_ERROR_WANT_X509_LOOKUP: + BIO_printf(bio_c_out, "read X BLOCK\n"); + break; + case SSL_ERROR_SYSCALL: + ret = errno; + BIO_printf(bio_err, "read:errno=%d\n", ret); + goto shut; + case SSL_ERROR_ZERO_RETURN: + BIO_printf(bio_c_out, "closed\n"); + ret = 0; + goto shut; + case SSL_ERROR_SSL: + ERR_print_errors(bio_err); + goto shut; + /* break; */ + } + } else if (pfd[0].revents) { + if (pfd[0].revents & (POLLERR|POLLNVAL)) { + BIO_printf(bio_err, "poll error"); + goto shut; + } + if (crlf) { + int j, lf_num; + + i = read(fileno(stdin), cbuf, BUFSIZZ / 2); + lf_num = 0; + /* both loops are skipped when i <= 0 */ + for (j = 0; j < i; j++) + if (cbuf[j] == '\n') + lf_num++; + for (j = i - 1; j >= 0; j--) { + cbuf[j + lf_num] = cbuf[j]; + if (cbuf[j] == '\n') { + lf_num--; + i++; + cbuf[j + lf_num] = '\r'; + } + } + assert(lf_num == 0); + } else + i = read(fileno(stdin), cbuf, BUFSIZZ); + + if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q'))) { + BIO_printf(bio_err, "DONE\n"); + ret = 0; + goto shut; + } + if ((!c_ign_eof) && (cbuf[0] == 'R')) { + BIO_printf(bio_err, "RENEGOTIATING\n"); + SSL_renegotiate(con); + cbuf_len = 0; + } else { + cbuf_len = i; + cbuf_off = 0; + } + + write_ssl = 1; + read_tty = 0; + } + } + + ret = 0; +shut: + if (in_init) + print_stuff(bio_c_out, con, full_log); + SSL_shutdown(con); + shutdown(SSL_get_fd(con), SHUT_RD); + close(SSL_get_fd(con)); +end: + if (con != NULL) { + if (prexit != 0) + print_stuff(bio_c_out, con, 1); + SSL_free(con); + } + free(next_proto.data); + if (ctx != NULL) + SSL_CTX_free(ctx); + if (cert) + X509_free(cert); + if (key) + EVP_PKEY_free(key); + free(pass); + if (vpm) + X509_VERIFY_PARAM_free(vpm); + if (cbuf != NULL) { + explicit_bzero(cbuf, BUFSIZZ); + free(cbuf); + } + if (sbuf != NULL) { + explicit_bzero(sbuf, BUFSIZZ); + free(sbuf); + } + if (mbuf != NULL) { + explicit_bzero(mbuf, BUFSIZZ); + free(mbuf); + } + if (bio_c_out != NULL) { + BIO_free(bio_c_out); + bio_c_out = NULL; + } + + return (ret); +} + + +static void +print_stuff(BIO * bio, SSL * s, int full) +{ + X509 *peer = NULL; + char *p; + static const char *space = " "; + char buf[BUFSIZ]; + STACK_OF(X509) * sk; + STACK_OF(X509_NAME) * sk2; + const SSL_CIPHER *c; + X509_NAME *xn; + int j, i; + unsigned char *exportedkeymat; + + if (full) { + int got_a_chain = 0; + + sk = SSL_get_peer_cert_chain(s); + if (sk != NULL) { + got_a_chain = 1; /* we don't have it for SSL2 + * (yet) */ + + BIO_printf(bio, "---\nCertificate chain\n"); + for (i = 0; i < sk_X509_num(sk); i++) { + X509_NAME_oneline(X509_get_subject_name( + sk_X509_value(sk, i)), buf, sizeof buf); + BIO_printf(bio, "%2d s:%s\n", i, buf); + X509_NAME_oneline(X509_get_issuer_name( + sk_X509_value(sk, i)), buf, sizeof buf); + BIO_printf(bio, " i:%s\n", buf); + if (c_showcerts) + PEM_write_bio_X509(bio, sk_X509_value(sk, i)); + } + } + BIO_printf(bio, "---\n"); + peer = SSL_get_peer_certificate(s); + if (peer != NULL) { + BIO_printf(bio, "Server certificate\n"); + if (!(c_showcerts && got_a_chain)) /* Redundant if we + * showed the whole + * chain */ + PEM_write_bio_X509(bio, peer); + X509_NAME_oneline(X509_get_subject_name(peer), + buf, sizeof buf); + BIO_printf(bio, "subject=%s\n", buf); + X509_NAME_oneline(X509_get_issuer_name(peer), + buf, sizeof buf); + BIO_printf(bio, "issuer=%s\n", buf); + } else + BIO_printf(bio, "no peer certificate available\n"); + + sk2 = SSL_get_client_CA_list(s); + if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0)) { + BIO_printf(bio, "---\nAcceptable client certificate CA names\n"); + for (i = 0; i < sk_X509_NAME_num(sk2); i++) { + xn = sk_X509_NAME_value(sk2, i); + X509_NAME_oneline(xn, buf, sizeof(buf)); + BIO_write(bio, buf, strlen(buf)); + BIO_write(bio, "\n", 1); + } + } else { + BIO_printf(bio, "---\nNo client certificate CA names sent\n"); + } + p = SSL_get_shared_ciphers(s, buf, sizeof buf); + if (p != NULL) { + /* + * This works only for SSL 2. In later protocol + * versions, the client does not know what other + * ciphers (in addition to the one to be used in the + * current connection) the server supports. + */ + + BIO_printf(bio, "---\nCiphers common between both SSL endpoints:\n"); + j = i = 0; + while (*p) { + if (*p == ':') { + BIO_write(bio, space, 15 - j % 25); + i++; + j = 0; + BIO_write(bio, ((i % 3) ? " " : "\n"), 1); + } else { + BIO_write(bio, p, 1); + j++; + } + p++; + } + BIO_write(bio, "\n", 1); + } + BIO_printf(bio, "---\nSSL handshake has read %ld bytes and written %ld bytes\n", + BIO_number_read(SSL_get_rbio(s)), + BIO_number_written(SSL_get_wbio(s))); + } + BIO_printf(bio, (SSL_cache_hit(s) ? "---\nReused, " : "---\nNew, ")); + c = SSL_get_current_cipher(s); + BIO_printf(bio, "%s, Cipher is %s\n", + SSL_CIPHER_get_version(c), + SSL_CIPHER_get_name(c)); + if (peer != NULL) { + EVP_PKEY *pktmp; + pktmp = X509_get_pubkey(peer); + BIO_printf(bio, "Server public key is %d bit\n", + EVP_PKEY_bits(pktmp)); + EVP_PKEY_free(pktmp); + } + BIO_printf(bio, "Secure Renegotiation IS%s supported\n", + SSL_get_secure_renegotiation_support(s) ? "" : " NOT"); + + /* Compression is not supported and will always be none. */ + BIO_printf(bio, "Compression: NONE\n"); + BIO_printf(bio, "Expansion: NONE\n"); + +#ifdef SSL_DEBUG + { + /* Print out local port of connection: useful for debugging */ + int sock; + struct sockaddr_in ladd; + socklen_t ladd_size = sizeof(ladd); + sock = SSL_get_fd(s); + getsockname(sock, (struct sockaddr *) & ladd, &ladd_size); + BIO_printf(bio_c_out, "LOCAL PORT is %u\n", ntohs(ladd.sin_port)); + } +#endif + + if (next_proto.status != -1) { + const unsigned char *proto; + unsigned int proto_len; + SSL_get0_next_proto_negotiated(s, &proto, &proto_len); + BIO_printf(bio, "Next protocol: (%d) ", next_proto.status); + BIO_write(bio, proto, proto_len); + BIO_write(bio, "\n", 1); + } + { + const unsigned char *proto; + unsigned int proto_len; + SSL_get0_alpn_selected(s, &proto, &proto_len); + if (proto_len > 0) { + BIO_printf(bio, "ALPN protocol: "); + BIO_write(bio, proto, proto_len); + BIO_write(bio, "\n", 1); + } else + BIO_printf(bio, "No ALPN negotiated\n"); + } + +#ifndef OPENSSL_NO_SRTP + { + SRTP_PROTECTION_PROFILE *srtp_profile = SSL_get_selected_srtp_profile(s); + + if (srtp_profile) + BIO_printf(bio, "SRTP Extension negotiated, profile=%s\n", + srtp_profile->name); + } +#endif + + SSL_SESSION_print(bio, SSL_get_session(s)); + if (keymatexportlabel != NULL) { + BIO_printf(bio, "Keying material exporter:\n"); + BIO_printf(bio, " Label: '%s'\n", keymatexportlabel); + BIO_printf(bio, " Length: %i bytes\n", keymatexportlen); + exportedkeymat = malloc(keymatexportlen); + if (exportedkeymat != NULL) { + if (!SSL_export_keying_material(s, exportedkeymat, + keymatexportlen, + keymatexportlabel, + strlen(keymatexportlabel), + NULL, 0, 0)) { + BIO_printf(bio, " Error\n"); + } else { + BIO_printf(bio, " Keying material: "); + for (i = 0; i < keymatexportlen; i++) + BIO_printf(bio, "%02X", + exportedkeymat[i]); + BIO_printf(bio, "\n"); + } + free(exportedkeymat); + } + } + BIO_printf(bio, "---\n"); + if (peer != NULL) + X509_free(peer); + /* flush, or debugging output gets mixed with http response */ + (void) BIO_flush(bio); +} + + +static int +ocsp_resp_cb(SSL * s, void *arg) +{ + const unsigned char *p; + int len; + OCSP_RESPONSE *rsp; + len = SSL_get_tlsext_status_ocsp_resp(s, &p); + BIO_puts(arg, "OCSP response: "); + if (!p) { + BIO_puts(arg, "no response sent\n"); + return 1; + } + rsp = d2i_OCSP_RESPONSE(NULL, &p, len); + if (!rsp) { + BIO_puts(arg, "response parse error\n"); + BIO_dump_indent(arg, (char *) p, len, 4); + return 0; + } + BIO_puts(arg, "\n======================================\n"); + OCSP_RESPONSE_print(arg, rsp, 0); + BIO_puts(arg, "======================================\n"); + OCSP_RESPONSE_free(rsp); + return 1; +} + diff --git a/crypto/libressl/apps/openssl/s_server.c b/crypto/libressl/apps/openssl/s_server.c new file mode 100644 index 0000000000..d27b1dd8a6 --- /dev/null +++ b/crypto/libressl/apps/openssl/s_server.c @@ -0,0 +1,2037 @@ +/* $OpenBSD: s_server.c,v 1.23 2015/12/01 12:04:51 jca Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +/* Until the key-gen callbacks are modified to use newer prototypes, we allow + * deprecated functions for openssl-internal code */ +#ifdef OPENSSL_NO_DEPRECATED +#undef OPENSSL_NO_DEPRECATED +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "apps.h" + +#include +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_NO_DH +#include +#endif + +#include + +#include "s_apps.h" +#include "timeouts.h" + +static int sv_body(char *hostname, int s, unsigned char *context); +static int www_body(char *hostname, int s, unsigned char *context); +static void close_accept_socket(void); +static void sv_usage(void); +static int init_ssl_connection(SSL * s); +static void print_stats(BIO * bp, SSL_CTX * ctx); +static int +generate_session_id(const SSL * ssl, unsigned char *id, + unsigned int *id_len); +#ifndef OPENSSL_NO_DH +static DH *load_dh_param(const char *dhfile); +#endif + +static void s_server_init(void); + +/* static int load_CA(SSL_CTX *ctx, char *file);*/ + +#define BUFSIZZ 16*1024 +static int bufsize = BUFSIZZ; +static int accept_socket = -1; + +#define TEST_CERT "server.pem" +#define TEST_CERT2 "server2.pem" + +static char *cipher = NULL; +static int s_server_verify = SSL_VERIFY_NONE; +static int s_server_session_id_context = 1; /* anything will do */ +static const char *s_cert_file = TEST_CERT, *s_key_file = NULL; +static const char *s_cert_file2 = TEST_CERT2, *s_key_file2 = NULL; +static char *s_dcert_file = NULL, *s_dkey_file = NULL; +static int s_nbio = 0; +static int s_nbio_test = 0; +int s_crlf = 0; +static SSL_CTX *ctx = NULL; +static SSL_CTX *ctx2 = NULL; +static int www = 0; + +static BIO *bio_s_out = NULL; +static int s_debug = 0; +static int s_tlsextdebug = 0; +static int s_tlsextstatus = 0; +static int cert_status_cb(SSL * s, void *arg); +static int s_msg = 0; +static int s_quiet = 0; + +static char *keymatexportlabel = NULL; +static int keymatexportlen = 20; + +static const char *session_id_prefix = NULL; + +static int enable_timeouts = 0; +static long socket_mtu; +#ifndef OPENSSL_NO_DTLS1 +static int cert_chain = 0; +#endif + + + + +static void +s_server_init(void) +{ + accept_socket = -1; + cipher = NULL; + s_server_verify = SSL_VERIFY_NONE; + s_dcert_file = NULL; + s_dkey_file = NULL; + s_cert_file = TEST_CERT; + s_key_file = NULL; + s_cert_file2 = TEST_CERT2; + s_key_file2 = NULL; + ctx2 = NULL; + s_nbio = 0; + s_nbio_test = 0; + ctx = NULL; + www = 0; + + bio_s_out = NULL; + s_debug = 0; + s_msg = 0; + s_quiet = 0; +} + +static void +sv_usage(void) +{ + BIO_printf(bio_err, "usage: s_server [args ...]\n"); + BIO_printf(bio_err, "\n"); + BIO_printf(bio_err, " -accept arg - port to accept on (default is %d)\n", PORT); + BIO_printf(bio_err, " -context arg - set session ID context\n"); + BIO_printf(bio_err, " -verify arg - turn on peer certificate verification\n"); + BIO_printf(bio_err, " -Verify arg - turn on peer certificate verification, must have a cert.\n"); + BIO_printf(bio_err, " -cert arg - certificate file to use\n"); + BIO_printf(bio_err, " (default is %s)\n", TEST_CERT); + BIO_printf(bio_err, " -crl_check - check the peer certificate has not been revoked by its CA.\n" \ + " The CRL(s) are appended to the certificate file\n"); + BIO_printf(bio_err, " -crl_check_all - check the peer certificate has not been revoked by its CA\n" \ + " or any other CRL in the CA chain. CRL(s) are appended to the\n" \ + " the certificate file.\n"); + BIO_printf(bio_err, " -certform arg - certificate format (PEM or DER) PEM default\n"); + BIO_printf(bio_err, " -key arg - Private Key file to use, in cert file if\n"); + BIO_printf(bio_err, " not specified (default is %s)\n", TEST_CERT); + BIO_printf(bio_err, " -keyform arg - key format (PEM or DER) PEM default\n"); + BIO_printf(bio_err, " -pass arg - private key file pass phrase source\n"); + BIO_printf(bio_err, " -dcert arg - second certificate file to use (usually for DSA)\n"); + BIO_printf(bio_err, " -dcertform x - second certificate format (PEM or DER) PEM default\n"); + BIO_printf(bio_err, " -dkey arg - second private key file to use (usually for DSA)\n"); + BIO_printf(bio_err, " -dkeyform arg - second key format (PEM or DER) PEM default\n"); + BIO_printf(bio_err, " -dpass arg - second private key file pass phrase source\n"); + BIO_printf(bio_err, " -dhparam arg - DH parameter file to use, in cert file if not specified\n"); + BIO_printf(bio_err, " or a default set of parameters is used\n"); + BIO_printf(bio_err, " -named_curve arg - Elliptic curve name to use for ephemeral ECDH keys.\n" \ + " Use \"openssl ecparam -list_curves\" for all names\n" \ + " (default is nistp256).\n"); + BIO_printf(bio_err, " -nbio - Run with non-blocking IO\n"); + BIO_printf(bio_err, " -nbio_test - test with the non-blocking test bio\n"); + BIO_printf(bio_err, " -crlf - convert LF from terminal into CRLF\n"); + BIO_printf(bio_err, " -debug - Print more output\n"); + BIO_printf(bio_err, " -msg - Show protocol messages\n"); + BIO_printf(bio_err, " -state - Print the SSL states\n"); + BIO_printf(bio_err, " -CApath arg - PEM format directory of CA's\n"); + BIO_printf(bio_err, " -CAfile arg - PEM format file of CA's\n"); + BIO_printf(bio_err, " -nocert - Don't use any certificates (Anon-DH)\n"); + BIO_printf(bio_err, " -cipher arg - play with 'openssl ciphers' to see what goes here\n"); + BIO_printf(bio_err, " -serverpref - Use server's cipher preferences\n"); + BIO_printf(bio_err, " -quiet - Inhibit printing of session and certificate information\n"); + BIO_printf(bio_err, " -tls1_2 - Just talk TLSv1.2\n"); + BIO_printf(bio_err, " -tls1_1 - Just talk TLSv1.1\n"); + BIO_printf(bio_err, " -tls1 - Just talk TLSv1\n"); + BIO_printf(bio_err, " -dtls1 - Just talk DTLSv1\n"); + BIO_printf(bio_err, " -timeout - Enable timeouts\n"); + BIO_printf(bio_err, " -mtu - Set link layer MTU\n"); + BIO_printf(bio_err, " -chain - Read a certificate chain\n"); + BIO_printf(bio_err, " -no_ssl2 - Just disable SSLv2\n"); + BIO_printf(bio_err, " -no_ssl3 - Just disable SSLv3\n"); + BIO_printf(bio_err, " -no_tls1 - Just disable TLSv1\n"); + BIO_printf(bio_err, " -no_tls1_1 - Just disable TLSv1.1\n"); + BIO_printf(bio_err, " -no_tls1_2 - Just disable TLSv1.2\n"); +#ifndef OPENSSL_NO_DH + BIO_printf(bio_err, " -no_dhe - Disable ephemeral DH\n"); +#endif + BIO_printf(bio_err, " -no_ecdhe - Disable ephemeral ECDH\n"); + BIO_printf(bio_err, " -bugs - Turn on SSL bug compatibility\n"); + BIO_printf(bio_err, " -www - Respond to a 'GET /' with a status page\n"); + BIO_printf(bio_err, " -WWW - Respond to a 'GET / HTTP/1.0' with file ./\n"); + BIO_printf(bio_err, " -HTTP - Respond to a 'GET / HTTP/1.0' with file ./\n"); + BIO_printf(bio_err, " with the assumption it contains a complete HTTP response.\n"); + BIO_printf(bio_err, " -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n"); + BIO_printf(bio_err, " -servername host - servername for HostName TLS extension\n"); + BIO_printf(bio_err, " -servername_fatal - on mismatch send fatal alert (default warning alert)\n"); + BIO_printf(bio_err, " -cert2 arg - certificate file to use for servername\n"); + BIO_printf(bio_err, " (default is %s)\n", TEST_CERT2); + BIO_printf(bio_err, " -key2 arg - Private Key file to use for servername, in cert file if\n"); + BIO_printf(bio_err, " not specified (default is %s)\n", TEST_CERT2); + BIO_printf(bio_err, " -tlsextdebug - hex dump of all TLS extensions received\n"); + BIO_printf(bio_err, " -no_ticket - disable use of RFC4507bis session tickets\n"); + BIO_printf(bio_err, " -nextprotoneg arg - set the advertised protocols for the NPN extension (comma-separated list)\n"); + BIO_printf(bio_err," -alpn arg - set the advertised protocols for the ALPN extension (comma-separated list)\n"); +#ifndef OPENSSL_NO_SRTP + BIO_printf(bio_err, " -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n"); +#endif + BIO_printf(bio_err, " -keymatexport label - Export keying material using label\n"); + BIO_printf(bio_err, " -keymatexportlen len - Export len bytes of keying material (default 20)\n"); +} + +static int local_argc = 0; +static char **local_argv; + + +/* This is a context that we pass to callbacks */ +typedef struct tlsextctx_st { + char *servername; + BIO *biodebug; + int extension_error; +} tlsextctx; + + +static int +ssl_servername_cb(SSL * s, int *ad, void *arg) +{ + tlsextctx *p = (tlsextctx *) arg; + const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); + if (servername && p->biodebug) + BIO_printf(p->biodebug, "Hostname in TLS extension: \"%s\"\n", servername); + + if (!p->servername) + return SSL_TLSEXT_ERR_NOACK; + + if (servername) { + if (strcmp(servername, p->servername)) + return p->extension_error; + if (ctx2) { + BIO_printf(p->biodebug, "Switching server context.\n"); + SSL_set_SSL_CTX(s, ctx2); + } + } + return SSL_TLSEXT_ERR_OK; +} + +/* Structure passed to cert status callback */ + +typedef struct tlsextstatusctx_st { + /* Default responder to use */ + char *host, *path, *port; + int use_ssl; + int timeout; + BIO *err; + int verbose; +} tlsextstatusctx; + +static tlsextstatusctx tlscstatp = {NULL, NULL, NULL, 0, -1, NULL, 0}; + +/* Certificate Status callback. This is called when a client includes a + * certificate status request extension. + * + * This is a simplified version. It examines certificates each time and + * makes one OCSP responder query for each request. + * + * A full version would store details such as the OCSP certificate IDs and + * minimise the number of OCSP responses by caching them until they were + * considered "expired". + */ + +static int +cert_status_cb(SSL * s, void *arg) +{ + tlsextstatusctx *srctx = arg; + BIO *err = srctx->err; + char *host, *port, *path; + int use_ssl; + unsigned char *rspder = NULL; + int rspderlen; + STACK_OF(OPENSSL_STRING) * aia = NULL; + X509 *x = NULL; + X509_STORE_CTX inctx; + X509_OBJECT obj; + OCSP_REQUEST *req = NULL; + OCSP_RESPONSE *resp = NULL; + OCSP_CERTID *id = NULL; + STACK_OF(X509_EXTENSION) * exts; + int ret = SSL_TLSEXT_ERR_NOACK; + int i; + + if (srctx->verbose) + BIO_puts(err, "cert_status: callback called\n"); + /* Build up OCSP query from server certificate */ + x = SSL_get_certificate(s); + aia = X509_get1_ocsp(x); + if (aia) { + if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0), + &host, &port, &path, &use_ssl)) { + BIO_puts(err, "cert_status: can't parse AIA URL\n"); + goto err; + } + if (srctx->verbose) + BIO_printf(err, "cert_status: AIA URL: %s\n", + sk_OPENSSL_STRING_value(aia, 0)); + } else { + if (!srctx->host) { + BIO_puts(srctx->err, "cert_status: no AIA and no default responder URL\n"); + goto done; + } + host = srctx->host; + path = srctx->path; + port = srctx->port; + use_ssl = srctx->use_ssl; + } + + if (!X509_STORE_CTX_init(&inctx, + SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)), + NULL, NULL)) + goto err; + if (X509_STORE_get_by_subject(&inctx, X509_LU_X509, + X509_get_issuer_name(x), &obj) <= 0) { + BIO_puts(err, "cert_status: Can't retrieve issuer certificate.\n"); + X509_STORE_CTX_cleanup(&inctx); + goto done; + } + req = OCSP_REQUEST_new(); + if (!req) + goto err; + id = OCSP_cert_to_id(NULL, x, obj.data.x509); + X509_free(obj.data.x509); + X509_STORE_CTX_cleanup(&inctx); + if (!id) + goto err; + if (!OCSP_request_add0_id(req, id)) + goto err; + id = NULL; + /* Add any extensions to the request */ + SSL_get_tlsext_status_exts(s, &exts); + for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { + X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); + if (!OCSP_REQUEST_add_ext(req, ext, -1)) + goto err; + } + resp = process_responder(err, req, host, path, port, use_ssl, NULL, + srctx->timeout); + if (!resp) { + BIO_puts(err, "cert_status: error querying responder\n"); + goto done; + } + rspderlen = i2d_OCSP_RESPONSE(resp, &rspder); + if (rspderlen <= 0) + goto err; + SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen); + if (srctx->verbose) { + BIO_puts(err, "cert_status: ocsp response sent:\n"); + OCSP_RESPONSE_print(err, resp, 2); + } + ret = SSL_TLSEXT_ERR_OK; +done: + if (ret != SSL_TLSEXT_ERR_OK) + ERR_print_errors(err); + if (aia) { + free(host); + free(path); + free(port); + X509_email_free(aia); + } + if (id) + OCSP_CERTID_free(id); + if (req) + OCSP_REQUEST_free(req); + if (resp) + OCSP_RESPONSE_free(resp); + return ret; +err: + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + goto done; +} + +/* This is the context that we pass to next_proto_cb */ +typedef struct tlsextnextprotoctx_st { + unsigned char *data; + unsigned int len; +} tlsextnextprotoctx; + +static int +next_proto_cb(SSL * s, const unsigned char **data, unsigned int *len, void *arg) +{ + tlsextnextprotoctx *next_proto = arg; + + *data = next_proto->data; + *len = next_proto->len; + + return SSL_TLSEXT_ERR_OK; +} + + +/* This the context that we pass to alpn_cb */ +typedef struct tlsextalpnctx_st { + unsigned char *data; + unsigned short len; +} tlsextalpnctx; + +static int +alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, void *arg) +{ + tlsextalpnctx *alpn_ctx = arg; + + if (!s_quiet) { + /* We can assume that in is syntactically valid. */ + unsigned i; + + BIO_printf(bio_s_out, + "ALPN protocols advertised by the client: "); + for (i = 0; i < inlen; ) { + if (i) + BIO_write(bio_s_out, ", ", 2); + BIO_write(bio_s_out, &in[i + 1], in[i]); + i += in[i] + 1; + } + BIO_write(bio_s_out, "\n", 1); + } + + if (SSL_select_next_proto((unsigned char**)out, outlen, alpn_ctx->data, + alpn_ctx->len, in, inlen) != OPENSSL_NPN_NEGOTIATED) + return (SSL_TLSEXT_ERR_NOACK); + + if (!s_quiet) { + BIO_printf(bio_s_out, "ALPN protocols selected: "); + BIO_write(bio_s_out, *out, *outlen); + BIO_write(bio_s_out, "\n", 1); + } + + return (SSL_TLSEXT_ERR_OK); +} + +#ifndef OPENSSL_NO_SRTP +static char *srtp_profiles = NULL; +#endif + +int +s_server_main(int argc, char *argv[]) +{ + X509_VERIFY_PARAM *vpm = NULL; + int badarg = 0; + short port = PORT; + char *CApath = NULL, *CAfile = NULL; + unsigned char *context = NULL; + char *dhfile = NULL; + char *named_curve = NULL; + int badop = 0, bugs = 0; + int ret = 1; + int off = 0; + int no_dhe = 0, no_ecdhe = 0, nocert = 0; + int state = 0; + const SSL_METHOD *meth = NULL; + int socket_type = SOCK_STREAM; + int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM; + char *passarg = NULL, *pass = NULL; + char *dpassarg = NULL, *dpass = NULL; + int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM; + X509 *s_cert = NULL, *s_dcert = NULL; + EVP_PKEY *s_key = NULL, *s_dkey = NULL; + int no_cache = 0; + const char *errstr = NULL; + EVP_PKEY *s_key2 = NULL; + X509 *s_cert2 = NULL; + tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING}; + const char *next_proto_neg_in = NULL; + tlsextnextprotoctx next_proto = { NULL, 0 }; + const char *alpn_in = NULL; + tlsextalpnctx alpn_ctx = { NULL, 0 }; + + if (single_execution) { + if (pledge("stdio inet dns rpath tty", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + + meth = SSLv23_server_method(); + + local_argc = argc; + local_argv = argv; + + s_server_init(); + + verify_depth = 0; + s_nbio = 0; + s_nbio_test = 0; + + argc--; + argv++; + + while (argc >= 1) { + if ((strcmp(*argv, "-port") == 0) || + (strcmp(*argv, "-accept") == 0)) { + if (--argc < 1) + goto bad; + if (!extract_port(*(++argv), &port)) + goto bad; + } else if (strcmp(*argv, "-verify") == 0) { + s_server_verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; + if (--argc < 1) + goto bad; + verify_depth = strtonum(*(++argv), 0, INT_MAX, &errstr); + if (errstr) + goto bad; + BIO_printf(bio_err, "verify depth is %d\n", verify_depth); + } else if (strcmp(*argv, "-Verify") == 0) { + s_server_verify = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | + SSL_VERIFY_CLIENT_ONCE; + if (--argc < 1) + goto bad; + verify_depth = strtonum(*(++argv), 0, INT_MAX, &errstr); + if (errstr) + goto bad; + BIO_printf(bio_err, "verify depth is %d, must return a certificate\n", verify_depth); + } else if (strcmp(*argv, "-context") == 0) { + if (--argc < 1) + goto bad; + context = (unsigned char *) *(++argv); + } else if (strcmp(*argv, "-cert") == 0) { + if (--argc < 1) + goto bad; + s_cert_file = *(++argv); + } else if (strcmp(*argv, "-certform") == 0) { + if (--argc < 1) + goto bad; + s_cert_format = str2fmt(*(++argv)); + } else if (strcmp(*argv, "-key") == 0) { + if (--argc < 1) + goto bad; + s_key_file = *(++argv); + } else if (strcmp(*argv, "-keyform") == 0) { + if (--argc < 1) + goto bad; + s_key_format = str2fmt(*(++argv)); + } else if (strcmp(*argv, "-pass") == 0) { + if (--argc < 1) + goto bad; + passarg = *(++argv); + } else if (strcmp(*argv, "-dhparam") == 0) { + if (--argc < 1) + goto bad; + dhfile = *(++argv); + } + else if (strcmp(*argv, "-named_curve") == 0) { + if (--argc < 1) + goto bad; + named_curve = *(++argv); + } + else if (strcmp(*argv, "-dcertform") == 0) { + if (--argc < 1) + goto bad; + s_dcert_format = str2fmt(*(++argv)); + } else if (strcmp(*argv, "-dcert") == 0) { + if (--argc < 1) + goto bad; + s_dcert_file = *(++argv); + } else if (strcmp(*argv, "-dkeyform") == 0) { + if (--argc < 1) + goto bad; + s_dkey_format = str2fmt(*(++argv)); + } else if (strcmp(*argv, "-dpass") == 0) { + if (--argc < 1) + goto bad; + dpassarg = *(++argv); + } else if (strcmp(*argv, "-dkey") == 0) { + if (--argc < 1) + goto bad; + s_dkey_file = *(++argv); + } else if (strcmp(*argv, "-nocert") == 0) { + nocert = 1; + } else if (strcmp(*argv, "-CApath") == 0) { + if (--argc < 1) + goto bad; + CApath = *(++argv); + } else if (strcmp(*argv, "-no_cache") == 0) + no_cache = 1; + else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) { + if (badarg) + goto bad; + continue; + } else if (strcmp(*argv, "-verify_return_error") == 0) + verify_return_error = 1; + else if (strcmp(*argv, "-serverpref") == 0) { + off |= SSL_OP_CIPHER_SERVER_PREFERENCE; + } else if (strcmp(*argv, "-legacy_renegotiation") == 0) + ; /* no-op */ + else if (strcmp(*argv, "-cipher") == 0) { + if (--argc < 1) + goto bad; + cipher = *(++argv); + } else if (strcmp(*argv, "-CAfile") == 0) { + if (--argc < 1) + goto bad; + CAfile = *(++argv); + } + else if (strcmp(*argv, "-nbio") == 0) { + s_nbio = 1; + } + else if (strcmp(*argv, "-nbio_test") == 0) { + s_nbio = 1; + s_nbio_test = 1; + } else if (strcmp(*argv, "-debug") == 0) { + s_debug = 1; + } + else if (strcmp(*argv, "-tlsextdebug") == 0) + s_tlsextdebug = 1; + else if (strcmp(*argv, "-status") == 0) + s_tlsextstatus = 1; + else if (strcmp(*argv, "-status_verbose") == 0) { + s_tlsextstatus = 1; + tlscstatp.verbose = 1; + } else if (!strcmp(*argv, "-status_timeout")) { + s_tlsextstatus = 1; + if (--argc < 1) + goto bad; + tlscstatp.timeout = strtonum(*(++argv), 0, INT_MAX, &errstr); + if (errstr) + goto bad; + } else if (!strcmp(*argv, "-status_url")) { + s_tlsextstatus = 1; + if (--argc < 1) + goto bad; + if (!OCSP_parse_url(*(++argv), + &tlscstatp.host, + &tlscstatp.port, + &tlscstatp.path, + &tlscstatp.use_ssl)) { + BIO_printf(bio_err, "Error parsing URL\n"); + goto bad; + } + } + else if (strcmp(*argv, "-msg") == 0) { + s_msg = 1; + } else if (strcmp(*argv, "-state") == 0) { + state = 1; + } else if (strcmp(*argv, "-crlf") == 0) { + s_crlf = 1; + } else if (strcmp(*argv, "-quiet") == 0) { + s_quiet = 1; + } else if (strcmp(*argv, "-bugs") == 0) { + bugs = 1; + } else if (strcmp(*argv, "-no_tmp_rsa") == 0) { + /* No-op. */ + } else if (strcmp(*argv, "-no_dhe") == 0) { + no_dhe = 1; + } else if (strcmp(*argv, "-no_ecdhe") == 0) { + no_ecdhe = 1; + } else if (strcmp(*argv, "-www") == 0) { + www = 1; + } else if (strcmp(*argv, "-WWW") == 0) { + www = 2; + } else if (strcmp(*argv, "-HTTP") == 0) { + www = 3; + } else if (strcmp(*argv, "-no_ssl2") == 0) { + off |= SSL_OP_NO_SSLv2; + } else if (strcmp(*argv, "-no_ssl3") == 0) { + off |= SSL_OP_NO_SSLv3; + } else if (strcmp(*argv, "-no_tls1") == 0) { + off |= SSL_OP_NO_TLSv1; + } else if (strcmp(*argv, "-no_tls1_1") == 0) { + off |= SSL_OP_NO_TLSv1_1; + } else if (strcmp(*argv, "-no_tls1_2") == 0) { + off |= SSL_OP_NO_TLSv1_2; + } else if (strcmp(*argv, "-no_comp") == 0) { + off |= SSL_OP_NO_COMPRESSION; + } else if (strcmp(*argv, "-no_ticket") == 0) { + off |= SSL_OP_NO_TICKET; + } else if (strcmp(*argv, "-tls1") == 0) { + meth = TLSv1_server_method(); + } else if (strcmp(*argv, "-tls1_1") == 0) { + meth = TLSv1_1_server_method(); + } else if (strcmp(*argv, "-tls1_2") == 0) { + meth = TLSv1_2_server_method(); + } +#ifndef OPENSSL_NO_DTLS1 + else if (strcmp(*argv, "-dtls1") == 0) { + meth = DTLSv1_server_method(); + socket_type = SOCK_DGRAM; + } else if (strcmp(*argv, "-timeout") == 0) + enable_timeouts = 1; + else if (strcmp(*argv, "-mtu") == 0) { + if (--argc < 1) + goto bad; + socket_mtu = strtonum(*(++argv), 0, LONG_MAX, &errstr); + if (errstr) + goto bad; + } else if (strcmp(*argv, "-chain") == 0) + cert_chain = 1; +#endif + else if (strcmp(*argv, "-id_prefix") == 0) { + if (--argc < 1) + goto bad; + session_id_prefix = *(++argv); + } + else if (strcmp(*argv, "-servername") == 0) { + if (--argc < 1) + goto bad; + tlsextcbp.servername = *(++argv); + } else if (strcmp(*argv, "-servername_fatal") == 0) { + tlsextcbp.extension_error = SSL_TLSEXT_ERR_ALERT_FATAL; + } else if (strcmp(*argv, "-cert2") == 0) { + if (--argc < 1) + goto bad; + s_cert_file2 = *(++argv); + } else if (strcmp(*argv, "-key2") == 0) { + if (--argc < 1) + goto bad; + s_key_file2 = *(++argv); + } + else if (strcmp(*argv, "-nextprotoneg") == 0) { + if (--argc < 1) + goto bad; + next_proto_neg_in = *(++argv); + } + else if (strcmp(*argv,"-alpn") == 0) { + if (--argc < 1) + goto bad; + alpn_in = *(++argv); + } +#ifndef OPENSSL_NO_SRTP + else if (strcmp(*argv, "-use_srtp") == 0) { + if (--argc < 1) + goto bad; + srtp_profiles = *(++argv); + } +#endif + else if (strcmp(*argv, "-keymatexport") == 0) { + if (--argc < 1) + goto bad; + keymatexportlabel = *(++argv); + } else if (strcmp(*argv, "-keymatexportlen") == 0) { + if (--argc < 1) + goto bad; + keymatexportlen = strtonum(*(++argv), 1, INT_MAX, &errstr); + if (errstr) + goto bad; + } else { + BIO_printf(bio_err, "unknown option %s\n", *argv); + badop = 1; + break; + } + argc--; + argv++; + } + if (badop) { +bad: + if (errstr) + BIO_printf(bio_err, "invalid argument %s: %s\n", + *argv, errstr); + else + sv_usage(); + goto end; + } + + if (!app_passwd(bio_err, passarg, dpassarg, &pass, &dpass)) { + BIO_printf(bio_err, "Error getting password\n"); + goto end; + } + if (s_key_file == NULL) + s_key_file = s_cert_file; + if (s_key_file2 == NULL) + s_key_file2 = s_cert_file2; + + if (nocert == 0) { + s_key = load_key(bio_err, s_key_file, s_key_format, 0, pass, + "server certificate private key file"); + if (!s_key) { + ERR_print_errors(bio_err); + goto end; + } + s_cert = load_cert(bio_err, s_cert_file, s_cert_format, + NULL, "server certificate file"); + + if (!s_cert) { + ERR_print_errors(bio_err); + goto end; + } + if (tlsextcbp.servername) { + s_key2 = load_key(bio_err, s_key_file2, s_key_format, 0, pass, + "second server certificate private key file"); + if (!s_key2) { + ERR_print_errors(bio_err); + goto end; + } + s_cert2 = load_cert(bio_err, s_cert_file2, s_cert_format, + NULL, "second server certificate file"); + + if (!s_cert2) { + ERR_print_errors(bio_err); + goto end; + } + } + } + if (next_proto_neg_in) { + unsigned short len; + next_proto.data = next_protos_parse(&len, next_proto_neg_in); + if (next_proto.data == NULL) + goto end; + next_proto.len = len; + } else { + next_proto.data = NULL; + } + alpn_ctx.data = NULL; + if (alpn_in) { + unsigned short len; + alpn_ctx.data = next_protos_parse(&len, alpn_in); + if (alpn_ctx.data == NULL) + goto end; + alpn_ctx.len = len; + } + + if (s_dcert_file) { + + if (s_dkey_file == NULL) + s_dkey_file = s_dcert_file; + + s_dkey = load_key(bio_err, s_dkey_file, s_dkey_format, + 0, dpass, "second certificate private key file"); + if (!s_dkey) { + ERR_print_errors(bio_err); + goto end; + } + s_dcert = load_cert(bio_err, s_dcert_file, s_dcert_format, + NULL, "second server certificate file"); + + if (!s_dcert) { + ERR_print_errors(bio_err); + goto end; + } + } + if (bio_s_out == NULL) { + if (s_quiet && !s_debug && !s_msg) { + bio_s_out = BIO_new(BIO_s_null()); + } else { + if (bio_s_out == NULL) + bio_s_out = BIO_new_fp(stdout, BIO_NOCLOSE); + } + } + if (nocert) { + s_cert_file = NULL; + s_key_file = NULL; + s_dcert_file = NULL; + s_dkey_file = NULL; + s_cert_file2 = NULL; + s_key_file2 = NULL; + } + ctx = SSL_CTX_new(meth); + if (ctx == NULL) { + ERR_print_errors(bio_err); + goto end; + } + if (session_id_prefix) { + if (strlen(session_id_prefix) >= 32) + BIO_printf(bio_err, + "warning: id_prefix is too long, only one new session will be possible\n"); + else if (strlen(session_id_prefix) >= 16) + BIO_printf(bio_err, + "warning: id_prefix is too long if you use SSLv2\n"); + if (!SSL_CTX_set_generate_session_id(ctx, generate_session_id)) { + BIO_printf(bio_err, "error setting 'id_prefix'\n"); + ERR_print_errors(bio_err); + goto end; + } + BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix); + } + SSL_CTX_set_quiet_shutdown(ctx, 1); + if (bugs) + SSL_CTX_set_options(ctx, SSL_OP_ALL); + SSL_CTX_set_options(ctx, off); + /* + * DTLS: partial reads end up discarding unread UDP bytes :-( Setting + * read ahead solves this problem. + */ + if (socket_type == SOCK_DGRAM) + SSL_CTX_set_read_ahead(ctx, 1); + + if (state) + SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback); + if (no_cache) + SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); + else + SSL_CTX_sess_set_cache_size(ctx, 128); + +#ifndef OPENSSL_NO_SRTP + if (srtp_profiles != NULL) + SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles); +#endif + + + if ((!SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) || + (!SSL_CTX_set_default_verify_paths(ctx))) { + /* BIO_printf(bio_err,"X509_load_verify_locations\n"); */ + ERR_print_errors(bio_err); + /* goto end; */ + } + if (vpm) + SSL_CTX_set1_param(ctx, vpm); + + if (s_cert2) { + ctx2 = SSL_CTX_new(meth); + if (ctx2 == NULL) { + ERR_print_errors(bio_err); + goto end; + } + } + if (ctx2) { + BIO_printf(bio_s_out, "Setting secondary ctx parameters\n"); + + if (session_id_prefix) { + if (strlen(session_id_prefix) >= 32) + BIO_printf(bio_err, + "warning: id_prefix is too long, only one new session will be possible\n"); + else if (strlen(session_id_prefix) >= 16) + BIO_printf(bio_err, + "warning: id_prefix is too long if you use SSLv2\n"); + if (!SSL_CTX_set_generate_session_id(ctx2, generate_session_id)) { + BIO_printf(bio_err, "error setting 'id_prefix'\n"); + ERR_print_errors(bio_err); + goto end; + } + BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix); + } + SSL_CTX_set_quiet_shutdown(ctx2, 1); + if (bugs) + SSL_CTX_set_options(ctx2, SSL_OP_ALL); + SSL_CTX_set_options(ctx2, off); + /* + * DTLS: partial reads end up discarding unread UDP bytes :-( + * Setting read ahead solves this problem. + */ + if (socket_type == SOCK_DGRAM) + SSL_CTX_set_read_ahead(ctx2, 1); + + if (state) + SSL_CTX_set_info_callback(ctx2, apps_ssl_info_callback); + + if (no_cache) + SSL_CTX_set_session_cache_mode(ctx2, SSL_SESS_CACHE_OFF); + else + SSL_CTX_sess_set_cache_size(ctx2, 128); + + if ((!SSL_CTX_load_verify_locations(ctx2, CAfile, CApath)) || + (!SSL_CTX_set_default_verify_paths(ctx2))) { + ERR_print_errors(bio_err); + } + if (vpm) + SSL_CTX_set1_param(ctx2, vpm); + } + if (next_proto.data) + SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb, &next_proto); + if (alpn_ctx.data) + SSL_CTX_set_alpn_select_cb(ctx, alpn_cb, &alpn_ctx); + +#ifndef OPENSSL_NO_DH + if (!no_dhe) { + DH *dh = NULL; + + if (dhfile) + dh = load_dh_param(dhfile); + else if (s_cert_file) + dh = load_dh_param(s_cert_file); + + if (dh != NULL) + BIO_printf(bio_s_out, "Setting temp DH parameters\n"); + else + BIO_printf(bio_s_out, "Using auto DH parameters\n"); + (void) BIO_flush(bio_s_out); + + if (dh == NULL) + SSL_CTX_set_dh_auto(ctx, 1); + else if (!SSL_CTX_set_tmp_dh(ctx, dh)) { + BIO_printf(bio_err, + "Error setting temp DH parameters\n"); + ERR_print_errors(bio_err); + DH_free(dh); + goto end; + } + + if (ctx2) { + if (!dhfile) { + DH *dh2 = NULL; + + if (s_cert_file2 != NULL) + dh2 = load_dh_param(s_cert_file2); + if (dh2 != NULL) { + BIO_printf(bio_s_out, "Setting temp DH parameters\n"); + (void) BIO_flush(bio_s_out); + + DH_free(dh); + dh = dh2; + } + } + if (dh == NULL) + SSL_CTX_set_dh_auto(ctx2, 1); + else if (!SSL_CTX_set_tmp_dh(ctx2, dh)) { + BIO_printf(bio_err, + "Error setting temp DH parameters\n"); + ERR_print_errors(bio_err); + DH_free(dh); + goto end; + } + } + DH_free(dh); + } +#endif + + if (!no_ecdhe) { + EC_KEY *ecdh = NULL; + + if (named_curve) { + int nid = OBJ_sn2nid(named_curve); + + if (nid == 0) { + BIO_printf(bio_err, "unknown curve name (%s)\n", + named_curve); + goto end; + } + ecdh = EC_KEY_new_by_curve_name(nid); + if (ecdh == NULL) { + BIO_printf(bio_err, "unable to create curve (%s)\n", + named_curve); + goto end; + } + } + if (ecdh != NULL) { + BIO_printf(bio_s_out, "Setting temp ECDH parameters\n"); + } else { + BIO_printf(bio_s_out, "Using default temp ECDH parameters\n"); + ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + if (ecdh == NULL) { + BIO_printf(bio_err, "unable to create curve (nistp256)\n"); + goto end; + } + } + (void) BIO_flush(bio_s_out); + + SSL_CTX_set_tmp_ecdh(ctx, ecdh); + if (ctx2) + SSL_CTX_set_tmp_ecdh(ctx2, ecdh); + EC_KEY_free(ecdh); + } + + if (!set_cert_key_stuff(ctx, s_cert, s_key)) + goto end; + if (ctx2 && !set_cert_key_stuff(ctx2, s_cert2, s_key2)) + goto end; + if (s_dcert != NULL) { + if (!set_cert_key_stuff(ctx, s_dcert, s_dkey)) + goto end; + } + + if (cipher != NULL) { + if (!SSL_CTX_set_cipher_list(ctx, cipher)) { + BIO_printf(bio_err, "error setting cipher list\n"); + ERR_print_errors(bio_err); + goto end; + } + if (ctx2 && !SSL_CTX_set_cipher_list(ctx2, cipher)) { + BIO_printf(bio_err, "error setting cipher list\n"); + ERR_print_errors(bio_err); + goto end; + } + } + SSL_CTX_set_verify(ctx, s_server_verify, verify_callback); + SSL_CTX_set_session_id_context(ctx, (void *) &s_server_session_id_context, + sizeof s_server_session_id_context); + + /* Set DTLS cookie generation and verification callbacks */ + SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback); + SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback); + + if (ctx2) { + SSL_CTX_set_verify(ctx2, s_server_verify, verify_callback); + SSL_CTX_set_session_id_context(ctx2, (void *) &s_server_session_id_context, + sizeof s_server_session_id_context); + + tlsextcbp.biodebug = bio_s_out; + SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb); + SSL_CTX_set_tlsext_servername_arg(ctx2, &tlsextcbp); + SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); + SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp); + } + + if (CAfile != NULL) { + SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CAfile)); + if (ctx2) + SSL_CTX_set_client_CA_list(ctx2, SSL_load_client_CA_file(CAfile)); + } + BIO_printf(bio_s_out, "ACCEPT\n"); + (void) BIO_flush(bio_s_out); + if (www) + do_server(port, socket_type, &accept_socket, www_body, context); + else + do_server(port, socket_type, &accept_socket, sv_body, context); + print_stats(bio_s_out, ctx); + ret = 0; +end: + if (ctx != NULL) + SSL_CTX_free(ctx); + if (s_cert) + X509_free(s_cert); + if (s_dcert) + X509_free(s_dcert); + if (s_key) + EVP_PKEY_free(s_key); + if (s_dkey) + EVP_PKEY_free(s_dkey); + free(pass); + free(dpass); + if (vpm) + X509_VERIFY_PARAM_free(vpm); + free(tlscstatp.host); + free(tlscstatp.port); + free(tlscstatp.path); + if (ctx2 != NULL) + SSL_CTX_free(ctx2); + if (s_cert2) + X509_free(s_cert2); + if (s_key2) + EVP_PKEY_free(s_key2); + free(next_proto.data); + free(alpn_ctx.data); + if (bio_s_out != NULL) { + BIO_free(bio_s_out); + bio_s_out = NULL; + } + + return (ret); +} + +static void +print_stats(BIO * bio, SSL_CTX * ssl_ctx) +{ + BIO_printf(bio, "%4ld items in the session cache\n", + SSL_CTX_sess_number(ssl_ctx)); + BIO_printf(bio, "%4ld client connects (SSL_connect())\n", + SSL_CTX_sess_connect(ssl_ctx)); + BIO_printf(bio, "%4ld client renegotiates (SSL_connect())\n", + SSL_CTX_sess_connect_renegotiate(ssl_ctx)); + BIO_printf(bio, "%4ld client connects that finished\n", + SSL_CTX_sess_connect_good(ssl_ctx)); + BIO_printf(bio, "%4ld server accepts (SSL_accept())\n", + SSL_CTX_sess_accept(ssl_ctx)); + BIO_printf(bio, "%4ld server renegotiates (SSL_accept())\n", + SSL_CTX_sess_accept_renegotiate(ssl_ctx)); + BIO_printf(bio, "%4ld server accepts that finished\n", + SSL_CTX_sess_accept_good(ssl_ctx)); + BIO_printf(bio, "%4ld session cache hits\n", SSL_CTX_sess_hits(ssl_ctx)); + BIO_printf(bio, "%4ld session cache misses\n", SSL_CTX_sess_misses(ssl_ctx)); + BIO_printf(bio, "%4ld session cache timeouts\n", SSL_CTX_sess_timeouts(ssl_ctx)); + BIO_printf(bio, "%4ld callback cache hits\n", SSL_CTX_sess_cb_hits(ssl_ctx)); + BIO_printf(bio, "%4ld cache full overflows (%ld allowed)\n", + SSL_CTX_sess_cache_full(ssl_ctx), + SSL_CTX_sess_get_cache_size(ssl_ctx)); +} + +static int +sv_body(char *hostname, int s, unsigned char *context) +{ + char *buf = NULL; + int ret = 1; + int k, i; + unsigned long l; + SSL *con = NULL; + BIO *sbio; + struct timeval timeout; + + if ((buf = malloc(bufsize)) == NULL) { + BIO_printf(bio_err, "out of memory\n"); + goto err; + } + if (s_nbio) { + if (!s_quiet) + BIO_printf(bio_err, "turning on non blocking io\n"); + if (!BIO_socket_nbio(s, 1)) + ERR_print_errors(bio_err); + } + + if (con == NULL) { + con = SSL_new(ctx); + if (s_tlsextdebug) { + SSL_set_tlsext_debug_callback(con, tlsext_cb); + SSL_set_tlsext_debug_arg(con, bio_s_out); + } + if (s_tlsextstatus) { + SSL_CTX_set_tlsext_status_cb(ctx, cert_status_cb); + tlscstatp.err = bio_err; + SSL_CTX_set_tlsext_status_arg(ctx, &tlscstatp); + } + if (context) + SSL_set_session_id_context(con, context, + strlen((char *) context)); + } + SSL_clear(con); + + if (SSL_version(con) == DTLS1_VERSION) { + + sbio = BIO_new_dgram(s, BIO_NOCLOSE); + + if (enable_timeouts) { + timeout.tv_sec = 0; + timeout.tv_usec = DGRAM_RCV_TIMEOUT; + BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); + + timeout.tv_sec = 0; + timeout.tv_usec = DGRAM_SND_TIMEOUT; + BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout); + } + if (socket_mtu > 28) { + SSL_set_options(con, SSL_OP_NO_QUERY_MTU); + SSL_set_mtu(con, socket_mtu - 28); + } else + /* want to do MTU discovery */ + BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); + + /* turn on cookie exchange */ + SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE); + } else + sbio = BIO_new_socket(s, BIO_NOCLOSE); + + if (s_nbio_test) { + BIO *test; + + test = BIO_new(BIO_f_nbio_test()); + sbio = BIO_push(test, sbio); + } + + SSL_set_bio(con, sbio, sbio); + SSL_set_accept_state(con); + /* SSL_set_fd(con,s); */ + + if (s_debug) { + SSL_set_debug(con, 1); + BIO_set_callback(SSL_get_rbio(con), bio_dump_callback); + BIO_set_callback_arg(SSL_get_rbio(con), (char *) bio_s_out); + } + if (s_msg) { + SSL_set_msg_callback(con, msg_cb); + SSL_set_msg_callback_arg(con, bio_s_out); + } + if (s_tlsextdebug) { + SSL_set_tlsext_debug_callback(con, tlsext_cb); + SSL_set_tlsext_debug_arg(con, bio_s_out); + } + + for (;;) { + int read_from_terminal; + int read_from_sslcon; + struct pollfd pfd[2]; + int ptimeout; + + read_from_terminal = 0; + read_from_sslcon = SSL_pending(con); + + if (!read_from_sslcon) { + pfd[0].fd = fileno(stdin); + pfd[0].events = POLLIN; + pfd[1].fd = s; + pfd[1].events = POLLIN; + + if ((SSL_version(con) == DTLS1_VERSION) && + DTLSv1_get_timeout(con, &timeout)) + ptimeout = timeout.tv_sec * 1000 + + timeout.tv_usec / 1000; + else + ptimeout = -1; + + i = poll(pfd, 2, ptimeout); + + if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0) { + BIO_printf(bio_err, "TIMEOUT occured\n"); + } + if (i <= 0) + continue; + if (pfd[0].revents) { + if ((pfd[0].revents & (POLLERR|POLLNVAL))) + continue; + read_from_terminal = 1; + } + if (pfd[1].revents) { + if ((pfd[1].revents & (POLLERR|POLLNVAL))) + continue; + read_from_sslcon = 1; + } + } + if (read_from_terminal) { + if (s_crlf) { + int j, lf_num; + + i = read(fileno(stdin), buf, bufsize / 2); + lf_num = 0; + /* both loops are skipped when i <= 0 */ + for (j = 0; j < i; j++) + if (buf[j] == '\n') + lf_num++; + for (j = i - 1; j >= 0; j--) { + buf[j + lf_num] = buf[j]; + if (buf[j] == '\n') { + lf_num--; + i++; + buf[j + lf_num] = '\r'; + } + } + assert(lf_num == 0); + } else + i = read(fileno(stdin), buf, bufsize); + if (!s_quiet) { + if ((i <= 0) || (buf[0] == 'Q')) { + BIO_printf(bio_s_out, "DONE\n"); + shutdown(s, SHUT_RD); + close(s); + close_accept_socket(); + ret = -11; + goto err; + } + if ((i <= 0) || (buf[0] == 'q')) { + BIO_printf(bio_s_out, "DONE\n"); + if (SSL_version(con) != DTLS1_VERSION) { + shutdown(s, SHUT_RD); + close(s); + } + /* + * close_accept_socket(); ret= -11; + */ + goto err; + } + if ((buf[0] == 'r') && + ((buf[1] == '\n') || (buf[1] == '\r'))) { + SSL_renegotiate(con); + i = SSL_do_handshake(con); + printf("SSL_do_handshake -> %d\n", i); + i = 0; /* 13; */ + continue; + /* + * RE-NEGOTIATE\n"); + */ + } + if ((buf[0] == 'R') && + ((buf[1] == '\n') || (buf[1] == '\r'))) { + SSL_set_verify(con, + SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL); + SSL_renegotiate(con); + i = SSL_do_handshake(con); + printf("SSL_do_handshake -> %d\n", i); + i = 0; /* 13; */ + continue; + /* + * RE-NEGOTIATE asking for client + * cert\n"); + */ + } + if (buf[0] == 'P') { + static const char *str = "Lets print some clear text\n"; + BIO_write(SSL_get_wbio(con), str, strlen(str)); + } + if (buf[0] == 'S') { + print_stats(bio_s_out, SSL_get_SSL_CTX(con)); + } + } + l = k = 0; + for (;;) { + /* should do a select for the write */ +#ifdef RENEG + { + static count = 0; + if (++count == 100) { + count = 0; + SSL_renegotiate(con); + } + } +#endif + k = SSL_write(con, &(buf[l]), (unsigned int) i); + switch (SSL_get_error(con, k)) { + case SSL_ERROR_NONE: + break; + case SSL_ERROR_WANT_WRITE: + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_X509_LOOKUP: + BIO_printf(bio_s_out, "Write BLOCK\n"); + break; + case SSL_ERROR_SYSCALL: + case SSL_ERROR_SSL: + BIO_printf(bio_s_out, "ERROR\n"); + ERR_print_errors(bio_err); + ret = 1; + goto err; + /* break; */ + case SSL_ERROR_ZERO_RETURN: + BIO_printf(bio_s_out, "DONE\n"); + ret = 1; + goto err; + } + l += k; + i -= k; + if (i <= 0) + break; + } + } + if (read_from_sslcon) { + if (!SSL_is_init_finished(con)) { + i = init_ssl_connection(con); + + if (i < 0) { + ret = 0; + goto err; + } else if (i == 0) { + ret = 1; + goto err; + } + } else { + again: + i = SSL_read(con, (char *) buf, bufsize); + switch (SSL_get_error(con, i)) { + case SSL_ERROR_NONE: { + int len, n; + for (len = 0; len < i;) { + do { + n = write(fileno(stdout), buf + len, i - len); + } while (n == -1 && errno == EINTR); + + if (n < 0) { + BIO_printf(bio_s_out, "ERROR\n"); + goto err; + } + len += n; + } + } + if (SSL_pending(con)) + goto again; + break; + case SSL_ERROR_WANT_WRITE: + case SSL_ERROR_WANT_READ: + BIO_printf(bio_s_out, "Read BLOCK\n"); + break; + case SSL_ERROR_SYSCALL: + case SSL_ERROR_SSL: + BIO_printf(bio_s_out, "ERROR\n"); + ERR_print_errors(bio_err); + ret = 1; + goto err; + case SSL_ERROR_ZERO_RETURN: + BIO_printf(bio_s_out, "DONE\n"); + ret = 1; + goto err; + } + } + } + } +err: + if (con != NULL) { + BIO_printf(bio_s_out, "shutting down SSL\n"); + SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); + SSL_free(con); + } + BIO_printf(bio_s_out, "CONNECTION CLOSED\n"); + if (buf != NULL) { + explicit_bzero(buf, bufsize); + free(buf); + } + if (ret >= 0) + BIO_printf(bio_s_out, "ACCEPT\n"); + return (ret); +} + +static void +close_accept_socket(void) +{ + BIO_printf(bio_err, "shutdown accept socket\n"); + if (accept_socket >= 0) { + shutdown(accept_socket, SHUT_RDWR); + close(accept_socket); + } +} + +static int +init_ssl_connection(SSL * con) +{ + int i; + const char *str; + X509 *peer; + long verify_error; + char buf[BUFSIZ]; + const unsigned char *next_proto_neg; + unsigned next_proto_neg_len; + unsigned char *exportedkeymat; + + i = SSL_accept(con); + if (i <= 0) { + if (BIO_sock_should_retry(i)) { + BIO_printf(bio_s_out, "DELAY\n"); + return (1); + } + BIO_printf(bio_err, "ERROR\n"); + verify_error = SSL_get_verify_result(con); + if (verify_error != X509_V_OK) { + BIO_printf(bio_err, "verify error:%s\n", + X509_verify_cert_error_string(verify_error)); + } else + ERR_print_errors(bio_err); + return (0); + } + PEM_write_bio_SSL_SESSION(bio_s_out, SSL_get_session(con)); + + peer = SSL_get_peer_certificate(con); + if (peer != NULL) { + BIO_printf(bio_s_out, "Client certificate\n"); + PEM_write_bio_X509(bio_s_out, peer); + X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof buf); + BIO_printf(bio_s_out, "subject=%s\n", buf); + X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf); + BIO_printf(bio_s_out, "issuer=%s\n", buf); + X509_free(peer); + } + if (SSL_get_shared_ciphers(con, buf, sizeof buf) != NULL) + BIO_printf(bio_s_out, "Shared ciphers:%s\n", buf); + str = SSL_CIPHER_get_name(SSL_get_current_cipher(con)); + BIO_printf(bio_s_out, "CIPHER is %s\n", (str != NULL) ? str : "(NONE)"); + + SSL_get0_next_proto_negotiated(con, &next_proto_neg, &next_proto_neg_len); + if (next_proto_neg) { + BIO_printf(bio_s_out, "NEXTPROTO is "); + BIO_write(bio_s_out, next_proto_neg, next_proto_neg_len); + BIO_printf(bio_s_out, "\n"); + } +#ifndef OPENSSL_NO_SRTP + { + SRTP_PROTECTION_PROFILE *srtp_profile + = SSL_get_selected_srtp_profile(con); + + if (srtp_profile) + BIO_printf(bio_s_out, "SRTP Extension negotiated, profile=%s\n", + srtp_profile->name); + } +#endif + if (SSL_cache_hit(con)) + BIO_printf(bio_s_out, "Reused session-id\n"); + BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n", + SSL_get_secure_renegotiation_support(con) ? "" : " NOT"); + if (keymatexportlabel != NULL) { + BIO_printf(bio_s_out, "Keying material exporter:\n"); + BIO_printf(bio_s_out, " Label: '%s'\n", keymatexportlabel); + BIO_printf(bio_s_out, " Length: %i bytes\n", + keymatexportlen); + exportedkeymat = malloc(keymatexportlen); + if (exportedkeymat != NULL) { + if (!SSL_export_keying_material(con, exportedkeymat, + keymatexportlen, + keymatexportlabel, + strlen(keymatexportlabel), + NULL, 0, 0)) { + BIO_printf(bio_s_out, " Error\n"); + } else { + BIO_printf(bio_s_out, " Keying material: "); + for (i = 0; i < keymatexportlen; i++) + BIO_printf(bio_s_out, "%02X", + exportedkeymat[i]); + BIO_printf(bio_s_out, "\n"); + } + free(exportedkeymat); + } + } + return (1); +} + +#ifndef OPENSSL_NO_DH +static DH * +load_dh_param(const char *dhfile) +{ + DH *ret = NULL; + BIO *bio; + + if ((bio = BIO_new_file(dhfile, "r")) == NULL) + goto err; + ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); +err: + BIO_free(bio); + return (ret); +} +#endif + +static int +www_body(char *hostname, int s, unsigned char *context) +{ + char *buf = NULL; + int ret = 1; + int i, j, k, dot; + SSL *con; + const SSL_CIPHER *c; + BIO *io, *ssl_bio, *sbio; + + buf = malloc(bufsize); + if (buf == NULL) + return (0); + io = BIO_new(BIO_f_buffer()); + ssl_bio = BIO_new(BIO_f_ssl()); + if ((io == NULL) || (ssl_bio == NULL)) + goto err; + + if (s_nbio) { + if (!s_quiet) + BIO_printf(bio_err, "turning on non blocking io\n"); + if (!BIO_socket_nbio(s, 1)) + ERR_print_errors(bio_err); + } + + /* lets make the output buffer a reasonable size */ + if (!BIO_set_write_buffer_size(io, bufsize)) + goto err; + + if ((con = SSL_new(ctx)) == NULL) + goto err; + if (s_tlsextdebug) { + SSL_set_tlsext_debug_callback(con, tlsext_cb); + SSL_set_tlsext_debug_arg(con, bio_s_out); + } + if (context) + SSL_set_session_id_context(con, context, + strlen((char *) context)); + + sbio = BIO_new_socket(s, BIO_NOCLOSE); + if (s_nbio_test) { + BIO *test; + + test = BIO_new(BIO_f_nbio_test()); + sbio = BIO_push(test, sbio); + } + SSL_set_bio(con, sbio, sbio); + SSL_set_accept_state(con); + + /* SSL_set_fd(con,s); */ + BIO_set_ssl(ssl_bio, con, BIO_CLOSE); + BIO_push(io, ssl_bio); + + if (s_debug) { + SSL_set_debug(con, 1); + BIO_set_callback(SSL_get_rbio(con), bio_dump_callback); + BIO_set_callback_arg(SSL_get_rbio(con), (char *) bio_s_out); + } + if (s_msg) { + SSL_set_msg_callback(con, msg_cb); + SSL_set_msg_callback_arg(con, bio_s_out); + } + for (;;) { + i = BIO_gets(io, buf, bufsize - 1); + if (i < 0) { /* error */ + if (!BIO_should_retry(io)) { + if (!s_quiet) + ERR_print_errors(bio_err); + goto err; + } else { + BIO_printf(bio_s_out, "read R BLOCK\n"); + sleep(1); + continue; + } + } else if (i == 0) { /* end of input */ + ret = 1; + goto end; + } + /* else we have data */ + if (((www == 1) && (strncmp("GET ", buf, 4) == 0)) || + ((www == 2) && (strncmp("GET /stats ", buf, 11) == 0))) { + char *p; + X509 *peer; + STACK_OF(SSL_CIPHER) * sk; + static const char *space = " "; + + BIO_puts(io, "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"); + BIO_puts(io, "\n"); + BIO_puts(io, "
\n");
+/*			BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/
+			BIO_puts(io, "\n");
+			for (i = 0; i < local_argc; i++) {
+				BIO_puts(io, local_argv[i]);
+				BIO_write(io, " ", 1);
+			}
+			BIO_puts(io, "\n");
+
+			BIO_printf(io,
+			    "Secure Renegotiation IS%s supported\n",
+			    SSL_get_secure_renegotiation_support(con) ?
+			    "" : " NOT");
+
+			/*
+			 * The following is evil and should not really be
+			 * done
+			 */
+			BIO_printf(io, "Ciphers supported in s_server binary\n");
+			sk = SSL_get_ciphers(con);
+			j = sk_SSL_CIPHER_num(sk);
+			for (i = 0; i < j; i++) {
+				c = sk_SSL_CIPHER_value(sk, i);
+				BIO_printf(io, "%-11s:%-25s",
+				    SSL_CIPHER_get_version(c),
+				    SSL_CIPHER_get_name(c));
+				if ((((i + 1) % 2) == 0) && (i + 1 != j))
+					BIO_puts(io, "\n");
+			}
+			BIO_puts(io, "\n");
+			p = SSL_get_shared_ciphers(con, buf, bufsize);
+			if (p != NULL) {
+				BIO_printf(io, "---\nCiphers common between both SSL end points:\n");
+				j = i = 0;
+				while (*p) {
+					if (*p == ':') {
+						BIO_write(io, space, 26 - j);
+						i++;
+						j = 0;
+						BIO_write(io, ((i % 3) ? " " : "\n"), 1);
+					} else {
+						BIO_write(io, p, 1);
+						j++;
+					}
+					p++;
+				}
+				BIO_puts(io, "\n");
+			}
+			BIO_printf(io, (SSL_cache_hit(con)
+				? "---\nReused, "
+				: "---\nNew, "));
+			c = SSL_get_current_cipher(con);
+			BIO_printf(io, "%s, Cipher is %s\n",
+			    SSL_CIPHER_get_version(c),
+			    SSL_CIPHER_get_name(c));
+			SSL_SESSION_print(io, SSL_get_session(con));
+			BIO_printf(io, "---\n");
+			print_stats(io, SSL_get_SSL_CTX(con));
+			BIO_printf(io, "---\n");
+			peer = SSL_get_peer_certificate(con);
+			if (peer != NULL) {
+				BIO_printf(io, "Client certificate\n");
+				X509_print(io, peer);
+				PEM_write_bio_X509(io, peer);
+			} else
+				BIO_puts(io, "no client certificate available\n");
+			BIO_puts(io, "\r\n\r\n");
+			break;
+		} else if ((www == 2 || www == 3)
+		    && (strncmp("GET /", buf, 5) == 0)) {
+			BIO *file;
+			char *p, *e;
+			static const char *text = "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
+
+			/* skip the '/' */
+			p = &(buf[5]);
+
+			dot = 1;
+			for (e = p; *e != '\0'; e++) {
+				if (e[0] == ' ')
+					break;
+
+				switch (dot) {
+				case 1:
+					dot = (e[0] == '.') ? 2 : 0;
+					break;
+				case 2:
+					dot = (e[0] == '.') ? 3 : 0;
+					break;
+				case 3:
+					dot = (e[0] == '/') ? -1 : 0;
+					break;
+				}
+				if (dot == 0)
+					dot = (e[0] == '/') ? 1 : 0;
+			}
+			dot = (dot == 3) || (dot == -1);	/* filename contains
+								 * ".." component */
+
+			if (*e == '\0') {
+				BIO_puts(io, text);
+				BIO_printf(io, "'%s' is an invalid file name\r\n", p);
+				break;
+			}
+			*e = '\0';
+
+			if (dot) {
+				BIO_puts(io, text);
+				BIO_printf(io, "'%s' contains '..' reference\r\n", p);
+				break;
+			}
+			if (*p == '/') {
+				BIO_puts(io, text);
+				BIO_printf(io, "'%s' is an invalid path\r\n", p);
+				break;
+			}
+			/* if a directory, do the index thang */
+			if (app_isdir(p) > 0) {
+				BIO_puts(io, text);
+				BIO_printf(io, "'%s' is a directory\r\n", p);
+				break;
+			}
+			if ((file = BIO_new_file(p, "r")) == NULL) {
+				BIO_puts(io, text);
+				BIO_printf(io, "Error opening '%s'\r\n", p);
+				ERR_print_errors(io);
+				break;
+			}
+			if (!s_quiet)
+				BIO_printf(bio_err, "FILE:%s\n", p);
+
+			if (www == 2) {
+				i = strlen(p);
+				if (((i > 5) && (strcmp(&(p[i - 5]), ".html") == 0)) ||
+				    ((i > 4) && (strcmp(&(p[i - 4]), ".php") == 0)) ||
+				    ((i > 4) && (strcmp(&(p[i - 4]), ".htm") == 0)))
+					BIO_puts(io, "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
+				else
+					BIO_puts(io, "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
+			}
+			/* send the file */
+			for (;;) {
+				i = BIO_read(file, buf, bufsize);
+				if (i <= 0)
+					break;
+
+#ifdef RENEG
+				total_bytes += i;
+				fprintf(stderr, "%d\n", i);
+				if (total_bytes > 3 * 1024) {
+					total_bytes = 0;
+					fprintf(stderr, "RENEGOTIATE\n");
+					SSL_renegotiate(con);
+				}
+#endif
+
+				for (j = 0; j < i;) {
+#ifdef RENEG
+					{
+						static count = 0;
+						if (++count == 13) {
+							SSL_renegotiate(con);
+						}
+					}
+#endif
+					k = BIO_write(io, &(buf[j]), i - j);
+					if (k <= 0) {
+						if (!BIO_should_retry(io))
+							goto write_error;
+						else {
+							BIO_printf(bio_s_out, "rwrite W BLOCK\n");
+						}
+					} else {
+						j += k;
+					}
+				}
+			}
+	write_error:
+			BIO_free(file);
+			break;
+		}
+	}
+
+	for (;;) {
+		i = (int) BIO_flush(io);
+		if (i <= 0) {
+			if (!BIO_should_retry(io))
+				break;
+		} else
+			break;
+	}
+end:
+	/* make sure we re-use sessions */
+	SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
+
+err:
+
+	if (ret >= 0)
+		BIO_printf(bio_s_out, "ACCEPT\n");
+
+	free(buf);
+	if (io != NULL)
+		BIO_free_all(io);
+/*	if (ssl_bio != NULL) BIO_free(ssl_bio);*/
+	return (ret);
+}
+
+#define MAX_SESSION_ID_ATTEMPTS 10
+static int
+generate_session_id(const SSL * ssl, unsigned char *id,
+    unsigned int *id_len)
+{
+	unsigned int count = 0;
+	do {
+		arc4random_buf(id, *id_len);
+		/*
+		 * Prefix the session_id with the required prefix. NB: If our
+		 * prefix is too long, clip it - but there will be worse
+		 * effects anyway, eg. the server could only possibly create
+		 * 1 session ID (ie. the prefix!) so all future session
+		 * negotiations will fail due to conflicts.
+		 */
+		memcpy(id, session_id_prefix,
+		    (strlen(session_id_prefix) < *id_len) ?
+		    strlen(session_id_prefix) : *id_len);
+	}
+	while (SSL_has_matching_session_id(ssl, id, *id_len) &&
+	    (++count < MAX_SESSION_ID_ATTEMPTS));
+	if (count >= MAX_SESSION_ID_ATTEMPTS)
+		return 0;
+	return 1;
+}
diff --git a/crypto/libressl/apps/openssl/s_socket.c b/crypto/libressl/apps/openssl/s_socket.c
new file mode 100644
index 0000000000..c69724ef86
--- /dev/null
+++ b/crypto/libressl/apps/openssl/s_socket.c
@@ -0,0 +1,338 @@
+/* $OpenBSD: s_socket.c,v 1.7 2015/07/20 03:22:25 doug Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "apps.h"
+
+#include 
+
+#include "s_apps.h"
+
+static int init_server(int *sock, int port, int type);
+static int init_server_long(int *sock, int port, char *ip, int type);
+static int do_accept(int acc_sock, int *sock, char **host);
+
+int
+init_client(int *sock, char *host, char *port, int type, int af)
+{
+	struct addrinfo hints, *ai_top, *ai;
+	int i, s = -1;
+
+	memset(&hints, '\0', sizeof(hints));
+	hints.ai_family = af;
+	hints.ai_socktype = type;
+
+	if ((i = getaddrinfo(host, port, &hints, &ai_top)) != 0) {
+		BIO_printf(bio_err, "getaddrinfo: %s\n", gai_strerror(i));
+		return (0);
+	}
+	if (ai_top == NULL || ai_top->ai_addr == NULL) {
+		BIO_printf(bio_err, "getaddrinfo returned no addresses\n");
+		if (ai_top != NULL) {
+			freeaddrinfo(ai_top);
+		}
+		return (0);
+	}
+	for (ai = ai_top; ai != NULL; ai = ai->ai_next) {
+		s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+		if (s == -1) {
+			continue;
+		}
+		if (type == SOCK_STREAM) {
+			i = 0;
+			i = setsockopt(s, SOL_SOCKET, SO_KEEPALIVE,
+			    (char *) &i, sizeof(i));
+			if (i < 0) {
+				perror("keepalive");
+				goto out;
+			}
+		}
+		if ((i = connect(s, ai->ai_addr, ai->ai_addrlen)) == 0) {
+			*sock = s;
+			freeaddrinfo(ai_top);
+			return (1);
+		}
+		close(s);
+		s = -1;
+	}
+
+	perror("connect");
+out:
+	if (s != -1)
+		close(s);
+	freeaddrinfo(ai_top);
+	return (0);
+}
+
+int
+do_server(int port, int type, int *ret,
+    int (*cb) (char *hostname, int s, unsigned char *context),
+    unsigned char *context)
+{
+	int sock;
+	char *name = NULL;
+	int accept_socket = 0;
+	int i;
+
+	if (!init_server(&accept_socket, port, type))
+		return (0);
+
+	if (ret != NULL) {
+		*ret = accept_socket;
+		/* return(1); */
+	}
+	for (;;) {
+		if (type == SOCK_STREAM) {
+			if (do_accept(accept_socket, &sock, &name) == 0) {
+				shutdown(accept_socket, SHUT_RD);
+				close(accept_socket);
+				return (0);
+			}
+		} else
+			sock = accept_socket;
+		i = (*cb) (name, sock, context);
+		free(name);
+		if (type == SOCK_STREAM) {
+			shutdown(sock, SHUT_RDWR);
+			close(sock);
+		}
+		if (i < 0) {
+			shutdown(accept_socket, SHUT_RDWR);
+			close(accept_socket);
+			return (i);
+		}
+	}
+}
+
+static int
+init_server_long(int *sock, int port, char *ip, int type)
+{
+	int ret = 0;
+	struct sockaddr_in server;
+	int s = -1;
+
+	memset((char *) &server, 0, sizeof(server));
+	server.sin_family = AF_INET;
+	server.sin_port = htons((unsigned short) port);
+	if (ip == NULL)
+		server.sin_addr.s_addr = INADDR_ANY;
+	else
+		memcpy(&server.sin_addr.s_addr, ip, 4);
+
+	if (type == SOCK_STREAM)
+		s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+	else			/* type == SOCK_DGRAM */
+		s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+
+	if (s == -1)
+		goto err;
+#if defined SOL_SOCKET && defined SO_REUSEADDR
+	{
+		int j = 1;
+		if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
+		    (void *) &j, sizeof j) == -1) {
+			perror("setsockopt");
+			goto err;
+		}
+	}
+#endif
+	if (bind(s, (struct sockaddr *) & server, sizeof(server)) == -1) {
+		perror("bind");
+		goto err;
+	}
+	/* Make it 128 for linux */
+	if (type == SOCK_STREAM && listen(s, 128) == -1)
+		goto err;
+	*sock = s;
+	ret = 1;
+err:
+	if ((ret == 0) && (s != -1)) {
+		shutdown(s, SHUT_RD);
+		close(s);
+	}
+	return (ret);
+}
+
+static int
+init_server(int *sock, int port, int type)
+{
+	return (init_server_long(sock, port, NULL, type));
+}
+
+static int
+do_accept(int acc_sock, int *sock, char **host)
+{
+	int ret;
+	struct hostent *h1, *h2;
+	static struct sockaddr_in from;
+	socklen_t len;
+/*	struct linger ling; */
+
+redoit:
+
+	memset((char *) &from, 0, sizeof(from));
+	len = sizeof(from);
+	ret = accept(acc_sock, (struct sockaddr *) & from, &len);
+	if (ret == -1) {
+		if (errno == EINTR) {
+			/* check_timeout(); */
+			goto redoit;
+		}
+		fprintf(stderr, "errno=%d ", errno);
+		perror("accept");
+		return (0);
+	}
+/*
+	ling.l_onoff=1;
+	ling.l_linger=0;
+	i=setsockopt(ret,SOL_SOCKET,SO_LINGER,(char *)&ling,sizeof(ling));
+	if (i < 0) { perror("linger"); return(0); }
+	i=0;
+	i=setsockopt(ret,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
+	if (i < 0) { perror("keepalive"); return(0); }
+*/
+
+	if (host == NULL)
+		goto end;
+	h1 = gethostbyaddr((char *) &from.sin_addr.s_addr,
+	    sizeof(from.sin_addr.s_addr), AF_INET);
+	if (h1 == NULL) {
+		BIO_printf(bio_err, "bad gethostbyaddr\n");
+		*host = NULL;
+		/* return(0); */
+	} else {
+		if ((*host = strdup(h1->h_name)) == NULL) {
+			perror("strdup");
+			close(ret);
+			return (0);
+		}
+
+		h2 = gethostbyname(*host);
+		if (h2 == NULL) {
+			BIO_printf(bio_err, "gethostbyname failure\n");
+			close(ret);
+			return (0);
+		}
+		if (h2->h_addrtype != AF_INET) {
+			BIO_printf(bio_err, "gethostbyname addr is not AF_INET\n");
+			close(ret);
+			return (0);
+		}
+	}
+
+end:
+	*sock = ret;
+	return (1);
+}
+
+int
+extract_host_port(char *str, char **host_ptr, unsigned char *ip,
+    char **port_ptr)
+{
+	char *h, *p;
+
+	h = str;
+	p = strrchr(str, '/');	/* IPv6 host/port */
+	if (p == NULL) {
+		p = strrchr(str, ':');
+	}
+	if (p == NULL) {
+		BIO_printf(bio_err, "no port defined\n");
+		return (0);
+	}
+	*(p++) = '\0';
+
+	if (host_ptr != NULL)
+		*host_ptr = h;
+
+	if (port_ptr != NULL && p != NULL && *p != '\0')
+		*port_ptr = p;
+
+	return (1);
+}
+
+int
+extract_port(char *str, short *port_ptr)
+{
+	int i;
+	const char *errstr;
+	struct servent *s;
+
+	i = strtonum(str, 1, 65535, &errstr);
+	if (!errstr) {
+		*port_ptr = (unsigned short) i;
+	} else {
+		s = getservbyname(str, "tcp");
+		if (s == NULL) {
+			BIO_printf(bio_err, "getservbyname failure for %s\n", str);
+			return (0);
+		}
+		*port_ptr = ntohs((unsigned short) s->s_port);
+	}
+	return (1);
+}
diff --git a/crypto/libressl/apps/openssl/s_time.c b/crypto/libressl/apps/openssl/s_time.c
new file mode 100644
index 0000000000..f08bc0afa2
--- /dev/null
+++ b/crypto/libressl/apps/openssl/s_time.c
@@ -0,0 +1,552 @@
+/* $OpenBSD: s_time.c,v 1.13 2015/10/10 22:28:51 doug Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/*-----------------------------------------
+   s_time - SSL client connection timer program
+   Written and donated by Larry Streepy 
+  -----------------------------------------*/
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "apps.h"
+
+#include 
+#include 
+#include 
+#include 
+
+#include "s_apps.h"
+
+#define SSL_CONNECT_NAME	"localhost:4433"
+
+#define BUFSIZZ 1024*10
+
+#define MYBUFSIZ 1024*8
+
+#undef min
+#undef max
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+
+#define SECONDS	30
+extern int verify_depth;
+extern int verify_error;
+
+static void s_time_usage(void);
+static SSL *doConnection(SSL * scon);
+
+static SSL_CTX *tm_ctx = NULL;
+static const SSL_METHOD *s_time_meth = NULL;
+static long bytes_read = 0;
+
+struct {
+	int bugs;
+	char *CAfile;
+	char *CApath;
+	char *certfile;
+	char *cipher;
+	char *host;
+	char *keyfile;
+	int maxtime;
+	int nbio;
+	int no_shutdown;
+	int perform;
+	int verify;
+	int verify_depth;
+	char *www_path;
+} s_time_config;
+
+struct option s_time_options[] = {
+	{
+		.name = "bugs",
+		.desc = "Enable workarounds for known SSL/TLS bugs",
+		.type = OPTION_FLAG,
+		.opt.flag = &s_time_config.bugs,
+	},
+	{
+		.name = "CAfile",
+		.argname = "file",
+		.desc = "File containing trusted certificates in PEM format",
+		.type = OPTION_ARG,
+		.opt.arg = &s_time_config.CAfile,
+	},
+	{
+		.name = "CApath",
+		.argname = "path",
+		.desc = "Directory containing trusted certificates",
+		.type = OPTION_ARG,
+		.opt.arg = &s_time_config.CApath,
+	},
+	{
+		.name = "cert",
+		.argname = "file",
+		.desc = "Client certificate to use, if one is requested",
+		.type = OPTION_ARG,
+		.opt.arg = &s_time_config.certfile,
+	},
+	{
+		.name = "cipher",
+		.argname = "list",
+		.desc = "List of cipher suites to send to the server",
+		.type = OPTION_ARG,
+		.opt.arg = &s_time_config.cipher,
+	},
+	{
+		.name = "connect",
+		.argname = "host:port",
+		.desc = "Host and port to connect to (default "
+		    SSL_CONNECT_NAME ")",
+		.type = OPTION_ARG,
+		.opt.arg = &s_time_config.host,
+	},
+	{
+		.name = "key",
+		.argname = "file",
+		.desc = "Client private key to use, if one is required",
+		.type = OPTION_ARG,
+		.opt.arg = &s_time_config.keyfile,
+	},
+	{
+		.name = "nbio",
+		.desc = "Use non-blocking I/O",
+		.type = OPTION_FLAG,
+		.opt.flag = &s_time_config.nbio,
+	},
+	{
+		.name = "new",
+		.desc = "Use a new session ID for each connection",
+		.type = OPTION_VALUE,
+		.opt.value = &s_time_config.perform,
+		.value = 1,
+	},
+	{
+		.name = "no_shutdown",
+		.desc = "Shut down the connection without notifying the server",
+		.type = OPTION_FLAG,
+		.opt.flag = &s_time_config.no_shutdown,
+	},
+	{
+		.name = "reuse",
+		.desc = "Reuse the same session ID for each connection",
+		.type = OPTION_VALUE,
+		.opt.value = &s_time_config.perform,
+		.value = 2,
+	},
+	{
+		.name = "time",
+		.argname = "seconds",
+		.desc = "Duration to perform timing tests for (default 30)",
+		.type = OPTION_ARG_INT,
+		.opt.value = &s_time_config.maxtime,
+	},
+	{
+		.name = "verify",
+		.argname = "depth",
+		.desc = "Enable peer certificate verification with given depth",
+		.type = OPTION_ARG_INT,
+		.opt.value = &s_time_config.verify_depth,
+	},
+	{
+		.name = "www",
+		.argname = "page",
+		.desc = "Page to GET from the server (default none)",
+		.type = OPTION_ARG,
+		.opt.arg = &s_time_config.www_path,
+	},
+	{ NULL },
+};
+
+static void
+s_time_usage(void)
+{
+	fprintf(stderr,
+	    "usage: s_time "
+	    "[-bugs] [-CAfile file] [-CApath directory] [-cert file]\n"
+	    "    [-cipher cipherlist] [-connect host:port] [-key keyfile]\n"
+	    "    [-nbio] [-new] [-no_shutdown] [-reuse] [-time seconds]\n"
+	    "    [-verify depth] [-www page]\n\n");
+	options_usage(s_time_options);
+}
+
+/***********************************************************************
+ * TIME - time functions
+ */
+#define START	0
+#define STOP	1
+
+static double
+tm_Time_F(int s)
+{
+	return app_tminterval(s, 1);
+}
+
+/***********************************************************************
+ * MAIN - main processing area for client
+ *			real name depends on MONOLITH
+ */
+int
+s_time_main(int argc, char **argv)
+{
+	double totalTime = 0.0;
+	int nConn = 0;
+	SSL *scon = NULL;
+	long finishtime = 0;
+	int ret = 1, i;
+	char buf[1024 * 8];
+	int ver;
+
+	if (single_execution) {
+		if (pledge("stdio inet rpath", NULL) == -1) {
+			perror("pledge");
+			exit(1);
+		}
+	}
+
+	s_time_meth = SSLv23_client_method();
+
+	verify_depth = 0;
+
+	memset(&s_time_config, 0, sizeof(s_time_config));
+
+	s_time_config.host = SSL_CONNECT_NAME;
+	s_time_config.maxtime = SECONDS;
+	s_time_config.perform = 3;
+	s_time_config.verify = SSL_VERIFY_NONE;
+	s_time_config.verify_depth = -1;
+
+	if (options_parse(argc, argv, s_time_options, NULL, NULL) != 0) {
+		s_time_usage();
+		goto end;
+	}
+
+	if (s_time_config.verify_depth >= 0) {
+		s_time_config.verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
+		verify_depth = s_time_config.verify_depth;
+		BIO_printf(bio_err, "verify depth is %d\n", verify_depth);
+	}
+
+	if (s_time_config.www_path != NULL &&
+	    strlen(s_time_config.www_path) > MYBUFSIZ - 100) {
+		BIO_printf(bio_err, "-www option too long\n");
+		goto end;
+	}
+
+	if ((tm_ctx = SSL_CTX_new(s_time_meth)) == NULL)
+		return (1);
+
+	SSL_CTX_set_quiet_shutdown(tm_ctx, 1);
+
+	if (s_time_config.bugs)
+		SSL_CTX_set_options(tm_ctx, SSL_OP_ALL);
+
+	if (s_time_config.cipher != NULL) {
+		if (!SSL_CTX_set_cipher_list(tm_ctx, s_time_config.cipher)) {
+			BIO_printf(bio_err, "error setting cipher list\n");
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+	}
+
+	SSL_CTX_set_verify(tm_ctx, s_time_config.verify, NULL);
+
+	if (!set_cert_stuff(tm_ctx, s_time_config.certfile,
+	    s_time_config.keyfile))
+		goto end;
+
+	if ((!SSL_CTX_load_verify_locations(tm_ctx, s_time_config.CAfile,
+	    s_time_config.CApath)) ||
+	    (!SSL_CTX_set_default_verify_paths(tm_ctx))) {
+		/*
+		 * BIO_printf(bio_err,"error setting default verify
+		 * locations\n");
+		 */
+		ERR_print_errors(bio_err);
+		/* goto end; */
+	}
+
+	if (!(s_time_config.perform & 1))
+		goto next;
+	printf("Collecting connection statistics for %d seconds\n",
+	    s_time_config.maxtime);
+
+	/* Loop and time how long it takes to make connections */
+
+	bytes_read = 0;
+	finishtime = (long) time(NULL) + s_time_config.maxtime;
+	tm_Time_F(START);
+	for (;;) {
+		if (finishtime < (long) time(NULL))
+			break;
+		if ((scon = doConnection(NULL)) == NULL)
+			goto end;
+
+		if (s_time_config.www_path != NULL) {
+			int retval = snprintf(buf, sizeof buf,
+			    "GET %s HTTP/1.0\r\n\r\n", s_time_config.www_path);
+			if ((size_t)retval >= sizeof buf) {
+				fprintf(stderr, "URL too long\n");
+				goto end;
+			}
+			SSL_write(scon, buf, strlen(buf));
+			while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
+				bytes_read += i;
+		}
+		if (s_time_config.no_shutdown)
+			SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN |
+			    SSL_RECEIVED_SHUTDOWN);
+		else
+			SSL_shutdown(scon);
+		shutdown(SSL_get_fd(scon), SHUT_RDWR);
+		close(SSL_get_fd(scon));
+
+		nConn += 1;
+		if (SSL_session_reused(scon))
+			ver = 'r';
+		else {
+			ver = SSL_version(scon);
+			if (ver == TLS1_VERSION)
+				ver = 't';
+			else if (ver == SSL3_VERSION)
+				ver = '3';
+			else if (ver == SSL2_VERSION)
+				ver = '2';
+			else
+				ver = '*';
+		}
+		fputc(ver, stdout);
+		fflush(stdout);
+
+		SSL_free(scon);
+		scon = NULL;
+	}
+	totalTime += tm_Time_F(STOP);	/* Add the time for this iteration */
+
+	i = (int) ((long) time(NULL) - finishtime + s_time_config.maxtime);
+	printf("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", nConn, totalTime, ((double) nConn / totalTime), bytes_read);
+	printf("%d connections in %ld real seconds, %ld bytes read per connection\n", nConn, (long) time(NULL) - finishtime + s_time_config.maxtime, bytes_read / nConn);
+
+	/*
+	 * Now loop and time connections using the same session id over and
+	 * over
+	 */
+
+next:
+	if (!(s_time_config.perform & 2))
+		goto end;
+	printf("\n\nNow timing with session id reuse.\n");
+
+	/* Get an SSL object so we can reuse the session id */
+	if ((scon = doConnection(NULL)) == NULL) {
+		fprintf(stderr, "Unable to get connection\n");
+		goto end;
+	}
+	if (s_time_config.www_path != NULL) {
+		int retval = snprintf(buf, sizeof buf,
+		    "GET %s HTTP/1.0\r\n\r\n", s_time_config.www_path);
+		if ((size_t)retval >= sizeof buf) {
+			fprintf(stderr, "URL too long\n");
+			goto end;
+		}
+		SSL_write(scon, buf, strlen(buf));
+		while (SSL_read(scon, buf, sizeof(buf)) > 0);
+	}
+	if (s_time_config.no_shutdown)
+		SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN |
+		    SSL_RECEIVED_SHUTDOWN);
+	else
+		SSL_shutdown(scon);
+	shutdown(SSL_get_fd(scon), SHUT_RDWR);
+	close(SSL_get_fd(scon));
+
+	nConn = 0;
+	totalTime = 0.0;
+
+	finishtime = (long) time(NULL) + s_time_config.maxtime;
+
+	printf("starting\n");
+	bytes_read = 0;
+	tm_Time_F(START);
+
+	for (;;) {
+		if (finishtime < (long) time(NULL))
+			break;
+		if ((doConnection(scon)) == NULL)
+			goto end;
+
+		if (s_time_config.www_path) {
+			int retval = snprintf(buf, sizeof buf,
+			    "GET %s HTTP/1.0\r\n\r\n", s_time_config.www_path);
+			if ((size_t)retval >= sizeof buf) {
+				fprintf(stderr, "URL too long\n");
+				goto end;
+			}
+			SSL_write(scon, buf, strlen(buf));
+			while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
+				bytes_read += i;
+		}
+		if (s_time_config.no_shutdown)
+			SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN |
+			    SSL_RECEIVED_SHUTDOWN);
+		else
+			SSL_shutdown(scon);
+		shutdown(SSL_get_fd(scon), SHUT_RDWR);
+		close(SSL_get_fd(scon));
+
+		nConn += 1;
+		if (SSL_session_reused(scon))
+			ver = 'r';
+		else {
+			ver = SSL_version(scon);
+			if (ver == TLS1_VERSION)
+				ver = 't';
+			else if (ver == SSL3_VERSION)
+				ver = '3';
+			else if (ver == SSL2_VERSION)
+				ver = '2';
+			else
+				ver = '*';
+		}
+		fputc(ver, stdout);
+		fflush(stdout);
+	}
+	totalTime += tm_Time_F(STOP);	/* Add the time for this iteration */
+
+
+	printf("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", nConn, totalTime, ((double) nConn / totalTime), bytes_read);
+	printf("%d connections in %ld real seconds, %ld bytes read per connection\n", nConn, (long) time(NULL) - finishtime + s_time_config.maxtime, bytes_read / nConn);
+
+	ret = 0;
+end:
+	if (scon != NULL)
+		SSL_free(scon);
+
+	if (tm_ctx != NULL) {
+		SSL_CTX_free(tm_ctx);
+		tm_ctx = NULL;
+	}
+
+	return (ret);
+}
+
+/***********************************************************************
+ * doConnection - make a connection
+ * Args:
+ *		scon	= earlier ssl connection for session id, or NULL
+ * Returns:
+ *		SSL *	= the connection pointer.
+ */
+static SSL *
+doConnection(SSL * scon)
+{
+	struct pollfd pfd[1];
+	SSL *serverCon;
+	BIO *conn;
+	long verify_error;
+	int i;
+
+	if ((conn = BIO_new(BIO_s_connect())) == NULL)
+		return (NULL);
+
+/*	BIO_set_conn_port(conn,port);*/
+	BIO_set_conn_hostname(conn, s_time_config.host);
+
+	if (scon == NULL)
+		serverCon = SSL_new(tm_ctx);
+	else {
+		serverCon = scon;
+		SSL_set_connect_state(serverCon);
+	}
+
+	SSL_set_bio(serverCon, conn, conn);
+
+	/* ok, lets connect */
+	for (;;) {
+		i = SSL_connect(serverCon);
+		if (BIO_sock_should_retry(i)) {
+			BIO_printf(bio_err, "DELAY\n");
+
+			i = SSL_get_fd(serverCon);
+			pfd[0].fd = i;
+			pfd[0].events = POLLIN;
+			poll(pfd, 1, -1);
+			continue;
+		}
+		break;
+	}
+	if (i <= 0) {
+		BIO_printf(bio_err, "ERROR\n");
+		verify_error = SSL_get_verify_result(serverCon);
+		if (verify_error != X509_V_OK)
+			BIO_printf(bio_err, "verify error:%s\n",
+			    X509_verify_cert_error_string(verify_error));
+		else
+			ERR_print_errors(bio_err);
+		if (scon == NULL)
+			SSL_free(serverCon);
+		return NULL;
+	}
+	return serverCon;
+}
diff --git a/crypto/libressl/apps/openssl/sess_id.c b/crypto/libressl/apps/openssl/sess_id.c
new file mode 100644
index 0000000000..1cec0c40e9
--- /dev/null
+++ b/crypto/libressl/apps/openssl/sess_id.c
@@ -0,0 +1,295 @@
+/* $OpenBSD: sess_id.c,v 1.6 2015/10/10 22:28:51 doug Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include "apps.h"
+#include "progs.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static struct {
+	int cert;
+	char *context;
+	char *infile;
+	int informat;
+	int noout;
+	char *outfile;
+	int outformat;
+	int text;
+} sess_id_config;
+
+static struct option sess_id_options[] = {
+	{
+		.name = "cert",
+		.desc = "Output certificate if present in session",
+		.type = OPTION_FLAG,
+		.opt.flag = &sess_id_config.cert,
+	},
+	{
+		.name = "context",
+		.argname = "id",
+		.desc = "Set the session ID context for output",
+		.type = OPTION_ARG,
+		.opt.arg = &sess_id_config.context,
+	},
+	{
+		.name = "in",
+		.argname = "file",
+		.desc = "Input file (default stdin)",
+		.type = OPTION_ARG,
+		.opt.arg = &sess_id_config.infile,
+	},
+	{
+		.name = "inform",
+		.argname = "format",
+		.desc = "Input format (DER or PEM (default))",
+		.type = OPTION_ARG_FORMAT,
+		.opt.value = &sess_id_config.informat,
+	},
+	{
+		.name = "noout",
+		.desc = "Do not output the encoded session info",
+		.type = OPTION_FLAG,
+		.opt.flag = &sess_id_config.noout,
+	},
+	{
+		.name = "out",
+		.argname = "file",
+		.desc = "Output file (default stdout)",
+		.type = OPTION_ARG,
+		.opt.arg = &sess_id_config.outfile,
+	},
+	{
+		.name = "outform",
+		.argname = "format",
+		.desc = "Output format (DER or PEM (default))",
+		.type = OPTION_ARG_FORMAT,
+		.opt.value = &sess_id_config.outformat,
+	},
+	{
+		.name = "text",
+		.desc = "Print various public or private key components in"
+		    " plain text",
+		.type = OPTION_FLAG,
+		.opt.flag = &sess_id_config.text,
+	},
+	{ NULL }
+};
+
+static void
+sess_id_usage(void)
+{
+	fprintf(stderr,
+	    "usage: sess_id [-cert] [-context id] [-in file] [-inform fmt] "
+	    "[-noout]\n"
+	    "    [-out file] [-outform fmt] [-text]\n\n");
+	options_usage(sess_id_options);
+}
+
+static SSL_SESSION *load_sess_id(char *file, int format);
+
+int
+sess_id_main(int argc, char **argv)
+{
+	SSL_SESSION *x = NULL;
+	X509 *peer = NULL;
+	int ret = 1, i;
+	BIO *out = NULL;
+
+	if (single_execution) {
+		if (pledge("stdio rpath wpath cpath", NULL) == -1) {
+			perror("pledge");
+			exit(1);
+		}
+	}
+
+	memset(&sess_id_config, 0, sizeof(sess_id_config));
+
+	sess_id_config.informat = FORMAT_PEM;
+	sess_id_config.outformat = FORMAT_PEM;
+
+	if (options_parse(argc, argv, sess_id_options, NULL, NULL) != 0) {
+		sess_id_usage();
+		return (1);
+	}
+
+	x = load_sess_id(sess_id_config.infile, sess_id_config.informat);
+	if (x == NULL) {
+		goto end;
+	}
+	peer = SSL_SESSION_get0_peer(x);
+
+	if (sess_id_config.context) {
+		size_t ctx_len = strlen(sess_id_config.context);
+		if (ctx_len > SSL_MAX_SID_CTX_LENGTH) {
+			BIO_printf(bio_err, "Context too long\n");
+			goto end;
+		}
+		SSL_SESSION_set1_id_context(x,
+		    (unsigned char *)sess_id_config.context, ctx_len);
+	}
+
+	if (!sess_id_config.noout || sess_id_config.text) {
+		out = BIO_new(BIO_s_file());
+		if (out == NULL) {
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+		if (sess_id_config.outfile == NULL) {
+			BIO_set_fp(out, stdout, BIO_NOCLOSE);
+		} else {
+			if (BIO_write_filename(out, sess_id_config.outfile)
+			    <= 0) {
+				perror(sess_id_config.outfile);
+				goto end;
+			}
+		}
+	}
+	if (sess_id_config.text) {
+		SSL_SESSION_print(out, x);
+
+		if (sess_id_config.cert) {
+			if (peer == NULL)
+				BIO_puts(out, "No certificate present\n");
+			else
+				X509_print(out, peer);
+		}
+	}
+	if (!sess_id_config.noout && !sess_id_config.cert) {
+		if (sess_id_config.outformat == FORMAT_ASN1)
+			i = i2d_SSL_SESSION_bio(out, x);
+		else if (sess_id_config.outformat == FORMAT_PEM)
+			i = PEM_write_bio_SSL_SESSION(out, x);
+		else {
+			BIO_printf(bio_err,
+			    "bad output format specified for outfile\n");
+			goto end;
+		}
+		if (!i) {
+			BIO_printf(bio_err, "unable to write SSL_SESSION\n");
+			goto end;
+		}
+	} else if (!sess_id_config.noout && (peer != NULL)) {
+		/* just print the certificate */
+		if (sess_id_config.outformat == FORMAT_ASN1)
+			i = (int) i2d_X509_bio(out, peer);
+		else if (sess_id_config.outformat == FORMAT_PEM)
+			i = PEM_write_bio_X509(out, peer);
+		else {
+			BIO_printf(bio_err,
+			    "bad output format specified for outfile\n");
+			goto end;
+		}
+		if (!i) {
+			BIO_printf(bio_err, "unable to write X509\n");
+			goto end;
+		}
+	}
+	ret = 0;
+
+end:
+	BIO_free_all(out);
+	SSL_SESSION_free(x);
+
+	return (ret);
+}
+
+static SSL_SESSION *
+load_sess_id(char *infile, int format)
+{
+	SSL_SESSION *x = NULL;
+	BIO *in = NULL;
+
+	in = BIO_new(BIO_s_file());
+	if (in == NULL) {
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+	if (infile == NULL)
+		BIO_set_fp(in, stdin, BIO_NOCLOSE);
+	else {
+		if (BIO_read_filename(in, infile) <= 0) {
+			perror(infile);
+			goto end;
+		}
+	}
+	if (format == FORMAT_ASN1)
+		x = d2i_SSL_SESSION_bio(in, NULL);
+	else if (format == FORMAT_PEM)
+		x = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL);
+	else {
+		BIO_printf(bio_err,
+		    "bad input format specified for input crl\n");
+		goto end;
+	}
+	if (x == NULL) {
+		BIO_printf(bio_err, "unable to load SSL_SESSION\n");
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+end:
+	BIO_free(in);
+	return (x);
+}
diff --git a/crypto/libressl/apps/openssl/smime.c b/crypto/libressl/apps/openssl/smime.c
new file mode 100644
index 0000000000..2f78b98418
--- /dev/null
+++ b/crypto/libressl/apps/openssl/smime.c
@@ -0,0 +1,682 @@
+/* $OpenBSD: smime.c,v 1.6 2015/10/17 07:51:10 semarie Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* S/MIME utility function */
+
+#include 
+#include 
+
+#include "apps.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int save_certs(char *signerfile, STACK_OF(X509) * signers);
+static int smime_cb(int ok, X509_STORE_CTX * ctx);
+
+#define SMIME_OP	0x10
+#define SMIME_IP	0x20
+#define SMIME_SIGNERS	0x40
+#define SMIME_ENCRYPT	(1 | SMIME_OP)
+#define SMIME_DECRYPT	(2 | SMIME_IP)
+#define SMIME_SIGN	(3 | SMIME_OP | SMIME_SIGNERS)
+#define SMIME_VERIFY	(4 | SMIME_IP)
+#define SMIME_PK7OUT	(5 | SMIME_IP | SMIME_OP)
+#define SMIME_RESIGN	(6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
+
+int
+smime_main(int argc, char **argv)
+{
+	int operation = 0;
+	int ret = 0;
+	char **args;
+	const char *inmode = "r", *outmode = "w";
+	char *infile = NULL, *outfile = NULL;
+	char *signerfile = NULL, *recipfile = NULL;
+	STACK_OF(OPENSSL_STRING) * sksigners = NULL, *skkeys = NULL;
+	char *certfile = NULL, *keyfile = NULL, *contfile = NULL;
+	const EVP_CIPHER *cipher = NULL;
+	PKCS7 *p7 = NULL;
+	X509_STORE *store = NULL;
+	X509 *cert = NULL, *recip = NULL, *signer = NULL;
+	EVP_PKEY *key = NULL;
+	STACK_OF(X509) * encerts = NULL, *other = NULL;
+	BIO *in = NULL, *out = NULL, *indata = NULL;
+	int badarg = 0;
+	int flags = PKCS7_DETACHED;
+	char *to = NULL, *from = NULL, *subject = NULL;
+	char *CAfile = NULL, *CApath = NULL;
+	char *passargin = NULL, *passin = NULL;
+	int indef = 0;
+	const EVP_MD *sign_md = NULL;
+	int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
+	int keyform = FORMAT_PEM;
+
+	X509_VERIFY_PARAM *vpm = NULL;
+
+	if (single_execution) {
+		if (pledge("stdio rpath wpath cpath tty", NULL) == -1) {
+			perror("pledge");
+			exit(1);
+		}
+	}
+
+	args = argv + 1;
+	ret = 1;
+
+	while (!badarg && *args && *args[0] == '-') {
+		if (!strcmp(*args, "-encrypt"))
+			operation = SMIME_ENCRYPT;
+		else if (!strcmp(*args, "-decrypt"))
+			operation = SMIME_DECRYPT;
+		else if (!strcmp(*args, "-sign"))
+			operation = SMIME_SIGN;
+		else if (!strcmp(*args, "-resign"))
+			operation = SMIME_RESIGN;
+		else if (!strcmp(*args, "-verify"))
+			operation = SMIME_VERIFY;
+		else if (!strcmp(*args, "-pk7out"))
+			operation = SMIME_PK7OUT;
+#ifndef OPENSSL_NO_DES
+		else if (!strcmp(*args, "-des3"))
+			cipher = EVP_des_ede3_cbc();
+		else if (!strcmp(*args, "-des"))
+			cipher = EVP_des_cbc();
+#endif
+#ifndef OPENSSL_NO_RC2
+		else if (!strcmp(*args, "-rc2-40"))
+			cipher = EVP_rc2_40_cbc();
+		else if (!strcmp(*args, "-rc2-128"))
+			cipher = EVP_rc2_cbc();
+		else if (!strcmp(*args, "-rc2-64"))
+			cipher = EVP_rc2_64_cbc();
+#endif
+#ifndef OPENSSL_NO_AES
+		else if (!strcmp(*args, "-aes128"))
+			cipher = EVP_aes_128_cbc();
+		else if (!strcmp(*args, "-aes192"))
+			cipher = EVP_aes_192_cbc();
+		else if (!strcmp(*args, "-aes256"))
+			cipher = EVP_aes_256_cbc();
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+		else if (!strcmp(*args, "-camellia128"))
+			cipher = EVP_camellia_128_cbc();
+		else if (!strcmp(*args, "-camellia192"))
+			cipher = EVP_camellia_192_cbc();
+		else if (!strcmp(*args, "-camellia256"))
+			cipher = EVP_camellia_256_cbc();
+#endif
+		else if (!strcmp(*args, "-text"))
+			flags |= PKCS7_TEXT;
+		else if (!strcmp(*args, "-nointern"))
+			flags |= PKCS7_NOINTERN;
+		else if (!strcmp(*args, "-noverify"))
+			flags |= PKCS7_NOVERIFY;
+		else if (!strcmp(*args, "-nochain"))
+			flags |= PKCS7_NOCHAIN;
+		else if (!strcmp(*args, "-nocerts"))
+			flags |= PKCS7_NOCERTS;
+		else if (!strcmp(*args, "-noattr"))
+			flags |= PKCS7_NOATTR;
+		else if (!strcmp(*args, "-nodetach"))
+			flags &= ~PKCS7_DETACHED;
+		else if (!strcmp(*args, "-nosmimecap"))
+			flags |= PKCS7_NOSMIMECAP;
+		else if (!strcmp(*args, "-binary"))
+			flags |= PKCS7_BINARY;
+		else if (!strcmp(*args, "-nosigs"))
+			flags |= PKCS7_NOSIGS;
+		else if (!strcmp(*args, "-stream"))
+			indef = 1;
+		else if (!strcmp(*args, "-indef"))
+			indef = 1;
+		else if (!strcmp(*args, "-noindef"))
+			indef = 0;
+		else if (!strcmp(*args, "-nooldmime"))
+			flags |= PKCS7_NOOLDMIMETYPE;
+		else if (!strcmp(*args, "-crlfeol"))
+			flags |= PKCS7_CRLFEOL;
+		else if (!strcmp(*args, "-passin")) {
+			if (!args[1])
+				goto argerr;
+			passargin = *++args;
+		} else if (!strcmp(*args, "-to")) {
+			if (!args[1])
+				goto argerr;
+			to = *++args;
+		} else if (!strcmp(*args, "-from")) {
+			if (!args[1])
+				goto argerr;
+			from = *++args;
+		} else if (!strcmp(*args, "-subject")) {
+			if (!args[1])
+				goto argerr;
+			subject = *++args;
+		} else if (!strcmp(*args, "-signer")) {
+			if (!args[1])
+				goto argerr;
+			/* If previous -signer argument add signer to list */
+
+			if (signerfile) {
+				if (!sksigners)
+					sksigners = sk_OPENSSL_STRING_new_null();
+				sk_OPENSSL_STRING_push(sksigners, signerfile);
+				if (!keyfile)
+					keyfile = signerfile;
+				if (!skkeys)
+					skkeys = sk_OPENSSL_STRING_new_null();
+				sk_OPENSSL_STRING_push(skkeys, keyfile);
+				keyfile = NULL;
+			}
+			signerfile = *++args;
+		} else if (!strcmp(*args, "-recip")) {
+			if (!args[1])
+				goto argerr;
+			recipfile = *++args;
+		} else if (!strcmp(*args, "-md")) {
+			if (!args[1])
+				goto argerr;
+			sign_md = EVP_get_digestbyname(*++args);
+			if (sign_md == NULL) {
+				BIO_printf(bio_err, "Unknown digest %s\n",
+				    *args);
+				goto argerr;
+			}
+		} else if (!strcmp(*args, "-inkey")) {
+			if (!args[1])
+				goto argerr;
+			/* If previous -inkey arument add signer to list */
+			if (keyfile) {
+				if (!signerfile) {
+					BIO_puts(bio_err, "Illegal -inkey without -signer\n");
+					goto argerr;
+				}
+				if (!sksigners)
+					sksigners = sk_OPENSSL_STRING_new_null();
+				sk_OPENSSL_STRING_push(sksigners, signerfile);
+				signerfile = NULL;
+				if (!skkeys)
+					skkeys = sk_OPENSSL_STRING_new_null();
+				sk_OPENSSL_STRING_push(skkeys, keyfile);
+			}
+			keyfile = *++args;
+		} else if (!strcmp(*args, "-keyform")) {
+			if (!args[1])
+				goto argerr;
+			keyform = str2fmt(*++args);
+		} else if (!strcmp(*args, "-certfile")) {
+			if (!args[1])
+				goto argerr;
+			certfile = *++args;
+		} else if (!strcmp(*args, "-CAfile")) {
+			if (!args[1])
+				goto argerr;
+			CAfile = *++args;
+		} else if (!strcmp(*args, "-CApath")) {
+			if (!args[1])
+				goto argerr;
+			CApath = *++args;
+		} else if (!strcmp(*args, "-in")) {
+			if (!args[1])
+				goto argerr;
+			infile = *++args;
+		} else if (!strcmp(*args, "-inform")) {
+			if (!args[1])
+				goto argerr;
+			informat = str2fmt(*++args);
+		} else if (!strcmp(*args, "-outform")) {
+			if (!args[1])
+				goto argerr;
+			outformat = str2fmt(*++args);
+		} else if (!strcmp(*args, "-out")) {
+			if (!args[1])
+				goto argerr;
+			outfile = *++args;
+		} else if (!strcmp(*args, "-content")) {
+			if (!args[1])
+				goto argerr;
+			contfile = *++args;
+		} else if (args_verify(&args, NULL, &badarg, bio_err, &vpm))
+			continue;
+		else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL)
+			badarg = 1;
+		args++;
+	}
+
+	if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) {
+		BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
+		goto argerr;
+	}
+	if (operation & SMIME_SIGNERS) {
+		/* Check to see if any final signer needs to be appended */
+		if (keyfile && !signerfile) {
+			BIO_puts(bio_err, "Illegal -inkey without -signer\n");
+			goto argerr;
+		}
+		if (signerfile) {
+			if (!sksigners)
+				sksigners = sk_OPENSSL_STRING_new_null();
+			sk_OPENSSL_STRING_push(sksigners, signerfile);
+			if (!skkeys)
+				skkeys = sk_OPENSSL_STRING_new_null();
+			if (!keyfile)
+				keyfile = signerfile;
+			sk_OPENSSL_STRING_push(skkeys, keyfile);
+		}
+		if (!sksigners) {
+			BIO_printf(bio_err, "No signer certificate specified\n");
+			badarg = 1;
+		}
+		signerfile = NULL;
+		keyfile = NULL;
+	} else if (operation == SMIME_DECRYPT) {
+		if (!recipfile && !keyfile) {
+			BIO_printf(bio_err, "No recipient certificate or key specified\n");
+			badarg = 1;
+		}
+	} else if (operation == SMIME_ENCRYPT) {
+		if (!*args) {
+			BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
+			badarg = 1;
+		}
+	} else if (!operation)
+		badarg = 1;
+
+	if (badarg) {
+argerr:
+		BIO_printf(bio_err, "Usage smime [options] cert.pem ...\n");
+		BIO_printf(bio_err, "where options are\n");
+		BIO_printf(bio_err, "-encrypt       encrypt message\n");
+		BIO_printf(bio_err, "-decrypt       decrypt encrypted message\n");
+		BIO_printf(bio_err, "-sign          sign message\n");
+		BIO_printf(bio_err, "-verify        verify signed message\n");
+		BIO_printf(bio_err, "-pk7out        output PKCS#7 structure\n");
+#ifndef OPENSSL_NO_DES
+		BIO_printf(bio_err, "-des3          encrypt with triple DES\n");
+		BIO_printf(bio_err, "-des           encrypt with DES\n");
+#endif
+#ifndef OPENSSL_NO_RC2
+		BIO_printf(bio_err, "-rc2-40        encrypt with RC2-40 (default)\n");
+		BIO_printf(bio_err, "-rc2-64        encrypt with RC2-64\n");
+		BIO_printf(bio_err, "-rc2-128       encrypt with RC2-128\n");
+#endif
+#ifndef OPENSSL_NO_AES
+		BIO_printf(bio_err, "-aes128, -aes192, -aes256\n");
+		BIO_printf(bio_err, "               encrypt PEM output with cbc aes\n");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+		BIO_printf(bio_err, "-camellia128, -camellia192, -camellia256\n");
+		BIO_printf(bio_err, "               encrypt PEM output with cbc camellia\n");
+#endif
+		BIO_printf(bio_err, "-nointern      don't search certificates in message for signer\n");
+		BIO_printf(bio_err, "-nosigs        don't verify message signature\n");
+		BIO_printf(bio_err, "-noverify      don't verify signers certificate\n");
+		BIO_printf(bio_err, "-nocerts       don't include signers certificate when signing\n");
+		BIO_printf(bio_err, "-nodetach      use opaque signing\n");
+		BIO_printf(bio_err, "-noattr        don't include any signed attributes\n");
+		BIO_printf(bio_err, "-binary        don't translate message to text\n");
+		BIO_printf(bio_err, "-certfile file other certificates file\n");
+		BIO_printf(bio_err, "-signer file   signer certificate file\n");
+		BIO_printf(bio_err, "-recip  file   recipient certificate file for decryption\n");
+		BIO_printf(bio_err, "-in file       input file\n");
+		BIO_printf(bio_err, "-inform arg    input format SMIME (default), PEM or DER\n");
+		BIO_printf(bio_err, "-inkey file    input private key (if not signer or recipient)\n");
+		BIO_printf(bio_err, "-keyform arg   input private key format (PEM)\n");
+		BIO_printf(bio_err, "-out file      output file\n");
+		BIO_printf(bio_err, "-outform arg   output format SMIME (default), PEM or DER\n");
+		BIO_printf(bio_err, "-content file  supply or override content for detached signature\n");
+		BIO_printf(bio_err, "-to addr       to address\n");
+		BIO_printf(bio_err, "-from ad       from address\n");
+		BIO_printf(bio_err, "-subject s     subject\n");
+		BIO_printf(bio_err, "-text          include or delete text MIME headers\n");
+		BIO_printf(bio_err, "-CApath dir    trusted certificates directory\n");
+		BIO_printf(bio_err, "-CAfile file   trusted certificates file\n");
+		BIO_printf(bio_err, "-crl_check     check revocation status of signer's certificate using CRLs\n");
+		BIO_printf(bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n");
+		BIO_printf(bio_err, "-passin arg    input file pass phrase source\n");
+		BIO_printf(bio_err, "cert.pem       recipient certificate(s) for encryption\n");
+		goto end;
+	}
+
+	if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
+		BIO_printf(bio_err, "Error getting password\n");
+		goto end;
+	}
+	ret = 2;
+
+	if (!(operation & SMIME_SIGNERS))
+		flags &= ~PKCS7_DETACHED;
+
+	if (operation & SMIME_OP) {
+		if (outformat == FORMAT_ASN1)
+			outmode = "wb";
+	} else {
+		if (flags & PKCS7_BINARY)
+			outmode = "wb";
+	}
+
+	if (operation & SMIME_IP) {
+		if (informat == FORMAT_ASN1)
+			inmode = "rb";
+	} else {
+		if (flags & PKCS7_BINARY)
+			inmode = "rb";
+	}
+
+	if (operation == SMIME_ENCRYPT) {
+		if (!cipher) {
+#ifndef OPENSSL_NO_RC2
+			cipher = EVP_rc2_40_cbc();
+#else
+			BIO_printf(bio_err, "No cipher selected\n");
+			goto end;
+#endif
+		}
+		encerts = sk_X509_new_null();
+		while (*args) {
+			if (!(cert = load_cert(bio_err, *args, FORMAT_PEM,
+			    NULL, "recipient certificate file"))) {
+				goto end;
+			}
+			sk_X509_push(encerts, cert);
+			cert = NULL;
+			args++;
+		}
+	}
+	if (certfile) {
+		if (!(other = load_certs(bio_err, certfile, FORMAT_PEM, NULL,
+		    "certificate file"))) {
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+	}
+	if (recipfile && (operation == SMIME_DECRYPT)) {
+		if (!(recip = load_cert(bio_err, recipfile, FORMAT_PEM, NULL,
+		    "recipient certificate file"))) {
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+	}
+	if (operation == SMIME_DECRYPT) {
+		if (!keyfile)
+			keyfile = recipfile;
+	} else if (operation == SMIME_SIGN) {
+		if (!keyfile)
+			keyfile = signerfile;
+	} else
+		keyfile = NULL;
+
+	if (keyfile) {
+		key = load_key(bio_err, keyfile, keyform, 0, passin,
+		    "signing key file");
+		if (!key)
+			goto end;
+	}
+	if (infile) {
+		if (!(in = BIO_new_file(infile, inmode))) {
+			BIO_printf(bio_err,
+			    "Can't open input file %s\n", infile);
+			goto end;
+		}
+	} else
+		in = BIO_new_fp(stdin, BIO_NOCLOSE);
+
+	if (operation & SMIME_IP) {
+		if (informat == FORMAT_SMIME)
+			p7 = SMIME_read_PKCS7(in, &indata);
+		else if (informat == FORMAT_PEM)
+			p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
+		else if (informat == FORMAT_ASN1)
+			p7 = d2i_PKCS7_bio(in, NULL);
+		else {
+			BIO_printf(bio_err, "Bad input format for PKCS#7 file\n");
+			goto end;
+		}
+
+		if (!p7) {
+			BIO_printf(bio_err, "Error reading S/MIME message\n");
+			goto end;
+		}
+		if (contfile) {
+			BIO_free(indata);
+			if (!(indata = BIO_new_file(contfile, "rb"))) {
+				BIO_printf(bio_err, "Can't read content file %s\n", contfile);
+				goto end;
+			}
+		}
+	}
+	if (outfile) {
+		if (!(out = BIO_new_file(outfile, outmode))) {
+			BIO_printf(bio_err,
+			    "Can't open output file %s\n", outfile);
+			goto end;
+		}
+	} else {
+		out = BIO_new_fp(stdout, BIO_NOCLOSE);
+	}
+
+	if (operation == SMIME_VERIFY) {
+		if (!(store = setup_verify(bio_err, CAfile, CApath)))
+			goto end;
+		X509_STORE_set_verify_cb(store, smime_cb);
+		if (vpm)
+			X509_STORE_set1_param(store, vpm);
+	}
+	ret = 3;
+
+	if (operation == SMIME_ENCRYPT) {
+		if (indef)
+			flags |= PKCS7_STREAM;
+		p7 = PKCS7_encrypt(encerts, in, cipher, flags);
+	} else if (operation & SMIME_SIGNERS) {
+		int i;
+		/*
+		 * If detached data content we only enable streaming if
+		 * S/MIME output format.
+		 */
+		if (operation == SMIME_SIGN) {
+			if (flags & PKCS7_DETACHED) {
+				if (outformat == FORMAT_SMIME)
+					flags |= PKCS7_STREAM;
+			} else if (indef)
+				flags |= PKCS7_STREAM;
+			flags |= PKCS7_PARTIAL;
+			p7 = PKCS7_sign(NULL, NULL, other, in, flags);
+			if (!p7)
+				goto end;
+		} else
+			flags |= PKCS7_REUSE_DIGEST;
+		for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) {
+			signerfile = sk_OPENSSL_STRING_value(sksigners, i);
+			keyfile = sk_OPENSSL_STRING_value(skkeys, i);
+			signer = load_cert(bio_err, signerfile, FORMAT_PEM, NULL,
+			    "signer certificate");
+			if (!signer)
+				goto end;
+			key = load_key(bio_err, keyfile, keyform, 0, passin,
+			    "signing key file");
+			if (!key)
+				goto end;
+			if (!PKCS7_sign_add_signer(p7, signer, key,
+				sign_md, flags))
+				goto end;
+			X509_free(signer);
+			signer = NULL;
+			EVP_PKEY_free(key);
+			key = NULL;
+		}
+		/* If not streaming or resigning finalize structure */
+		if ((operation == SMIME_SIGN) && !(flags & PKCS7_STREAM)) {
+			if (!PKCS7_final(p7, in, flags))
+				goto end;
+		}
+	}
+	if (!p7) {
+		BIO_printf(bio_err, "Error creating PKCS#7 structure\n");
+		goto end;
+	}
+	ret = 4;
+	if (operation == SMIME_DECRYPT) {
+		if (!PKCS7_decrypt(p7, key, recip, out, flags)) {
+			BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n");
+			goto end;
+		}
+	} else if (operation == SMIME_VERIFY) {
+		STACK_OF(X509) * signers;
+		if (PKCS7_verify(p7, other, store, indata, out, flags))
+			BIO_printf(bio_err, "Verification successful\n");
+		else {
+			BIO_printf(bio_err, "Verification failure\n");
+			goto end;
+		}
+		signers = PKCS7_get0_signers(p7, other, flags);
+		if (!save_certs(signerfile, signers)) {
+			BIO_printf(bio_err, "Error writing signers to %s\n",
+			    signerfile);
+			ret = 5;
+			goto end;
+		}
+		sk_X509_free(signers);
+	} else if (operation == SMIME_PK7OUT)
+		PEM_write_bio_PKCS7(out, p7);
+	else {
+		if (to)
+			BIO_printf(out, "To: %s\n", to);
+		if (from)
+			BIO_printf(out, "From: %s\n", from);
+		if (subject)
+			BIO_printf(out, "Subject: %s\n", subject);
+		if (outformat == FORMAT_SMIME) {
+			if (operation == SMIME_RESIGN)
+				SMIME_write_PKCS7(out, p7, indata, flags);
+			else
+				SMIME_write_PKCS7(out, p7, in, flags);
+		} else if (outformat == FORMAT_PEM)
+			PEM_write_bio_PKCS7_stream(out, p7, in, flags);
+		else if (outformat == FORMAT_ASN1)
+			i2d_PKCS7_bio_stream(out, p7, in, flags);
+		else {
+			BIO_printf(bio_err, "Bad output format for PKCS#7 file\n");
+			goto end;
+		}
+	}
+	ret = 0;
+end:
+	if (ret)
+		ERR_print_errors(bio_err);
+	sk_X509_pop_free(encerts, X509_free);
+	sk_X509_pop_free(other, X509_free);
+	if (vpm)
+		X509_VERIFY_PARAM_free(vpm);
+	if (sksigners)
+		sk_OPENSSL_STRING_free(sksigners);
+	if (skkeys)
+		sk_OPENSSL_STRING_free(skkeys);
+	X509_STORE_free(store);
+	X509_free(cert);
+	X509_free(recip);
+	X509_free(signer);
+	EVP_PKEY_free(key);
+	PKCS7_free(p7);
+	BIO_free(in);
+	BIO_free(indata);
+	BIO_free_all(out);
+	free(passin);
+
+	return (ret);
+}
+
+static int
+save_certs(char *signerfile, STACK_OF(X509) * signers)
+{
+	int i;
+	BIO *tmp;
+	if (!signerfile)
+		return 1;
+	tmp = BIO_new_file(signerfile, "w");
+	if (!tmp)
+		return 0;
+	for (i = 0; i < sk_X509_num(signers); i++)
+		PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
+	BIO_free(tmp);
+	return 1;
+}
+
+
+/* Minimal callback just to output policy info (if any) */
+
+static int
+smime_cb(int ok, X509_STORE_CTX * ctx)
+{
+	int error;
+
+	error = X509_STORE_CTX_get_error(ctx);
+
+	if ((error != X509_V_ERR_NO_EXPLICIT_POLICY)
+	    && ((error != X509_V_OK) || (ok != 2)))
+		return ok;
+
+	policies_print(NULL, ctx);
+
+	return ok;
+
+}
diff --git a/crypto/libressl/apps/openssl/speed.c b/crypto/libressl/apps/openssl/speed.c
new file mode 100644
index 0000000000..139d8a11ad
--- /dev/null
+++ b/crypto/libressl/apps/openssl/speed.c
@@ -0,0 +1,2158 @@
+/* $OpenBSD: speed.c,v 1.17 2015/10/10 22:28:51 doug Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The ECDH and ECDSA speed test software is originally written by
+ * Sumit Gupta of Sun Microsystems Laboratories.
+ *
+ */
+
+/* most of this code has been pilfered from my libdes speed.c program */
+
+#ifndef OPENSSL_NO_SPEED
+
+#define SECONDS		3
+#define RSA_SECONDS	10
+#define DSA_SECONDS	10
+#define ECDSA_SECONDS   10
+#define ECDH_SECONDS    10
+
+/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */
+/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "apps.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_AES
+#include 
+#endif
+#ifndef OPENSSL_NO_BF
+#include 
+#endif
+#ifndef OPENSSL_NO_CAST
+#include 
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+#include 
+#endif
+#ifndef OPENSSL_NO_DES
+#include 
+#endif
+#include 
+#include 
+#include 
+#ifndef OPENSSL_NO_HMAC
+#include 
+#endif
+#ifndef OPENSSL_NO_IDEA
+#include 
+#endif
+#ifndef OPENSSL_NO_MD4
+#include 
+#endif
+#ifndef OPENSSL_NO_MD5
+#include 
+#endif
+#ifndef OPENSSL_NO_RC2
+#include 
+#endif
+#ifndef OPENSSL_NO_RC4
+#include 
+#endif
+#include 
+#ifndef OPENSSL_NO_RIPEMD
+#include 
+#endif
+#ifndef OPENSSL_NO_SHA
+#include 
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+#include 
+#endif
+
+#include "./testdsa.h"
+#include "./testrsa.h"
+
+#define BUFSIZE	(1024*8+64)
+int run = 0;
+
+static int mr = 0;
+static int usertime = 1;
+
+static double Time_F(int s);
+static void print_message(const char *s, long num, int length);
+static void
+pkey_print_message(const char *str, const char *str2,
+    long num, int bits, int sec);
+static void print_result(int alg, int run_no, int count, double time_used);
+static int do_multi(int multi);
+
+#define ALGOR_NUM	32
+#define SIZE_NUM	5
+#define RSA_NUM		4
+#define DSA_NUM		3
+
+#define EC_NUM       16
+#define MAX_ECDH_SIZE 256
+
+static const char *names[ALGOR_NUM] = {
+	"md2", "md4", "md5", "hmac(md5)", "sha1", "rmd160",
+	"rc4", "des cbc", "des ede3", "idea cbc", "seed cbc",
+	"rc2 cbc", "rc5-32/12 cbc", "blowfish cbc", "cast cbc",
+	"aes-128 cbc", "aes-192 cbc", "aes-256 cbc",
+	"camellia-128 cbc", "camellia-192 cbc", "camellia-256 cbc",
+	"evp", "sha256", "sha512", "whirlpool",
+	"aes-128 ige", "aes-192 ige", "aes-256 ige", "ghash",
+	"aes-128 gcm", "aes-256 gcm", "chacha20 poly1305",
+};
+static double results[ALGOR_NUM][SIZE_NUM];
+static int lengths[SIZE_NUM] = {16, 64, 256, 1024, 8 * 1024};
+static double rsa_results[RSA_NUM][2];
+static double dsa_results[DSA_NUM][2];
+static double ecdsa_results[EC_NUM][2];
+static double ecdh_results[EC_NUM][1];
+
+static void sig_done(int sig);
+
+static void
+sig_done(int sig)
+{
+	signal(SIGALRM, sig_done);
+	run = 0;
+}
+
+#define START	0
+#define STOP	1
+
+
+static double
+Time_F(int s)
+{
+	return app_tminterval(s, usertime);
+}
+
+
+static const int KDF1_SHA1_len = 20;
+static void *
+KDF1_SHA1(const void *in, size_t inlen, void *out, size_t * outlen)
+{
+#ifndef OPENSSL_NO_SHA
+	if (*outlen < SHA_DIGEST_LENGTH)
+		return NULL;
+	else
+		*outlen = SHA_DIGEST_LENGTH;
+	return SHA1(in, inlen, out);
+#else
+	return NULL;
+#endif				/* OPENSSL_NO_SHA */
+}
+
+int
+speed_main(int argc, char **argv)
+{
+	unsigned char *buf = NULL, *buf2 = NULL;
+	int mret = 1;
+	long count = 0, save_count = 0;
+	int i, j, k;
+	long rsa_count;
+	unsigned rsa_num;
+	unsigned char md[EVP_MAX_MD_SIZE];
+#ifndef OPENSSL_NO_MD4
+	unsigned char md4[MD4_DIGEST_LENGTH];
+#endif
+#ifndef OPENSSL_NO_MD5
+	unsigned char md5[MD5_DIGEST_LENGTH];
+	unsigned char hmac[MD5_DIGEST_LENGTH];
+#endif
+#ifndef OPENSSL_NO_SHA
+	unsigned char sha[SHA_DIGEST_LENGTH];
+#ifndef OPENSSL_NO_SHA256
+	unsigned char sha256[SHA256_DIGEST_LENGTH];
+#endif
+#ifndef OPENSSL_NO_SHA512
+	unsigned char sha512[SHA512_DIGEST_LENGTH];
+#endif
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+	unsigned char whirlpool[WHIRLPOOL_DIGEST_LENGTH];
+#endif
+#ifndef OPENSSL_NO_RIPEMD
+	unsigned char rmd160[RIPEMD160_DIGEST_LENGTH];
+#endif
+#ifndef OPENSSL_NO_RC4
+	RC4_KEY rc4_ks;
+#endif
+#ifndef OPENSSL_NO_RC2
+	RC2_KEY rc2_ks;
+#endif
+#ifndef OPENSSL_NO_IDEA
+	IDEA_KEY_SCHEDULE idea_ks;
+#endif
+#ifndef OPENSSL_NO_BF
+	BF_KEY bf_ks;
+#endif
+#ifndef OPENSSL_NO_CAST
+	CAST_KEY cast_ks;
+#endif
+	static const unsigned char key16[16] =
+	{0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
+	0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12};
+#ifndef OPENSSL_NO_AES
+	static const unsigned char key24[24] =
+	{0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
+		0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
+	0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34};
+	static const unsigned char key32[32] =
+	{0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
+		0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
+		0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
+	0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56};
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+	static const unsigned char ckey24[24] =
+	{0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
+		0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
+	0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34};
+	static const unsigned char ckey32[32] =
+	{0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
+		0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
+		0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
+	0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56};
+#endif
+#ifndef OPENSSL_NO_AES
+#define MAX_BLOCK_SIZE 128
+#else
+#define MAX_BLOCK_SIZE 64
+#endif
+	unsigned char DES_iv[8];
+	unsigned char iv[2 * MAX_BLOCK_SIZE / 8];
+#ifndef OPENSSL_NO_DES
+	static DES_cblock key = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
+	static DES_cblock key2 = {0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12};
+	static DES_cblock key3 = {0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34};
+	DES_key_schedule sch;
+	DES_key_schedule sch2;
+	DES_key_schedule sch3;
+#endif
+#ifndef OPENSSL_NO_AES
+	AES_KEY aes_ks1, aes_ks2, aes_ks3;
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+	CAMELLIA_KEY camellia_ks1, camellia_ks2, camellia_ks3;
+#endif
+#define	D_MD2		0
+#define	D_MD4		1
+#define	D_MD5		2
+#define	D_HMAC		3
+#define	D_SHA1		4
+#define D_RMD160	5
+#define	D_RC4		6
+#define	D_CBC_DES	7
+#define	D_EDE3_DES	8
+#define	D_CBC_IDEA	9
+#define	D_CBC_SEED	10
+#define	D_CBC_RC2	11
+#define	D_CBC_RC5	12
+#define	D_CBC_BF	13
+#define	D_CBC_CAST	14
+#define D_CBC_128_AES	15
+#define D_CBC_192_AES	16
+#define D_CBC_256_AES	17
+#define D_CBC_128_CML   18
+#define D_CBC_192_CML   19
+#define D_CBC_256_CML   20
+#define D_EVP		21
+#define D_SHA256	22
+#define D_SHA512	23
+#define D_WHIRLPOOL	24
+#define D_IGE_128_AES   25
+#define D_IGE_192_AES   26
+#define D_IGE_256_AES   27
+#define D_GHASH		28
+#define D_AES_128_GCM	29
+#define D_AES_256_GCM	30
+#define D_CHACHA20_POLY1305	31
+	double d = 0.0;
+	long c[ALGOR_NUM][SIZE_NUM];
+#define	R_DSA_512	0
+#define	R_DSA_1024	1
+#define	R_DSA_2048	2
+#define	R_RSA_512	0
+#define	R_RSA_1024	1
+#define	R_RSA_2048	2
+#define	R_RSA_4096	3
+
+#define R_EC_P160    0
+#define R_EC_P192    1
+#define R_EC_P224    2
+#define R_EC_P256    3
+#define R_EC_P384    4
+#define R_EC_P521    5
+#define R_EC_K163    6
+#define R_EC_K233    7
+#define R_EC_K283    8
+#define R_EC_K409    9
+#define R_EC_K571    10
+#define R_EC_B163    11
+#define R_EC_B233    12
+#define R_EC_B283    13
+#define R_EC_B409    14
+#define R_EC_B571    15
+
+	RSA *rsa_key[RSA_NUM];
+	long rsa_c[RSA_NUM][2];
+	static unsigned int rsa_bits[RSA_NUM] = {512, 1024, 2048, 4096};
+	static unsigned char *rsa_data[RSA_NUM] =
+	{test512, test1024, test2048, test4096};
+	static int rsa_data_length[RSA_NUM] = {
+		sizeof(test512), sizeof(test1024),
+	sizeof(test2048), sizeof(test4096)};
+	DSA *dsa_key[DSA_NUM];
+	long dsa_c[DSA_NUM][2];
+	static unsigned int dsa_bits[DSA_NUM] = {512, 1024, 2048};
+#ifndef OPENSSL_NO_EC
+	/*
+	 * We only test over the following curves as they are representative,
+	 * To add tests over more curves, simply add the curve NID and curve
+	 * name to the following arrays and increase the EC_NUM value
+	 * accordingly.
+	 */
+	static unsigned int test_curves[EC_NUM] =
+	{
+		/* Prime Curves */
+		NID_secp160r1,
+		NID_X9_62_prime192v1,
+		NID_secp224r1,
+		NID_X9_62_prime256v1,
+		NID_secp384r1,
+		NID_secp521r1,
+		/* Binary Curves */
+		NID_sect163k1,
+		NID_sect233k1,
+		NID_sect283k1,
+		NID_sect409k1,
+		NID_sect571k1,
+		NID_sect163r2,
+		NID_sect233r1,
+		NID_sect283r1,
+		NID_sect409r1,
+		NID_sect571r1
+	};
+	static const char *test_curves_names[EC_NUM] =
+	{
+		/* Prime Curves */
+		"secp160r1",
+		"nistp192",
+		"nistp224",
+		"nistp256",
+		"nistp384",
+		"nistp521",
+		/* Binary Curves */
+		"nistk163",
+		"nistk233",
+		"nistk283",
+		"nistk409",
+		"nistk571",
+		"nistb163",
+		"nistb233",
+		"nistb283",
+		"nistb409",
+		"nistb571"
+	};
+	static int test_curves_bits[EC_NUM] =
+	{
+		160, 192, 224, 256, 384, 521,
+		163, 233, 283, 409, 571,
+		163, 233, 283, 409, 571
+	};
+
+#endif
+
+	unsigned char ecdsasig[256];
+	unsigned int ecdsasiglen;
+	EC_KEY *ecdsa[EC_NUM];
+	long ecdsa_c[EC_NUM][2];
+
+	EC_KEY *ecdh_a[EC_NUM], *ecdh_b[EC_NUM];
+	unsigned char secret_a[MAX_ECDH_SIZE], secret_b[MAX_ECDH_SIZE];
+	int secret_size_a, secret_size_b;
+	int ecdh_checks = 0;
+	int secret_idx = 0;
+	long ecdh_c[EC_NUM][2];
+
+	int rsa_doit[RSA_NUM];
+	int dsa_doit[DSA_NUM];
+	int ecdsa_doit[EC_NUM];
+	int ecdh_doit[EC_NUM];
+	int doit[ALGOR_NUM];
+	int pr_header = 0;
+	const EVP_CIPHER *evp_cipher = NULL;
+	const EVP_MD *evp_md = NULL;
+	int decrypt = 0;
+	int multi = 0;
+	const char *errstr = NULL;
+
+	if (single_execution) {
+		if (pledge("stdio proc", NULL) == -1) {
+			perror("pledge");
+			exit(1);
+		}
+	}
+
+	usertime = -1;
+
+	memset(results, 0, sizeof(results));
+	memset(dsa_key, 0, sizeof(dsa_key));
+	for (i = 0; i < EC_NUM; i++)
+		ecdsa[i] = NULL;
+	for (i = 0; i < EC_NUM; i++) {
+		ecdh_a[i] = NULL;
+		ecdh_b[i] = NULL;
+	}
+
+	memset(rsa_key, 0, sizeof(rsa_key));
+	for (i = 0; i < RSA_NUM; i++)
+		rsa_key[i] = NULL;
+
+	if ((buf = malloc(BUFSIZE)) == NULL) {
+		BIO_printf(bio_err, "out of memory\n");
+		goto end;
+	}
+	if ((buf2 = malloc(BUFSIZE)) == NULL) {
+		BIO_printf(bio_err, "out of memory\n");
+		goto end;
+	}
+	memset(c, 0, sizeof(c));
+	memset(DES_iv, 0, sizeof(DES_iv));
+	memset(iv, 0, sizeof(iv));
+
+	for (i = 0; i < ALGOR_NUM; i++)
+		doit[i] = 0;
+	for (i = 0; i < RSA_NUM; i++)
+		rsa_doit[i] = 0;
+	for (i = 0; i < DSA_NUM; i++)
+		dsa_doit[i] = 0;
+	for (i = 0; i < EC_NUM; i++)
+		ecdsa_doit[i] = 0;
+	for (i = 0; i < EC_NUM; i++)
+		ecdh_doit[i] = 0;
+
+
+	j = 0;
+	argc--;
+	argv++;
+	while (argc) {
+		if ((argc > 0) && (strcmp(*argv, "-elapsed") == 0)) {
+			usertime = 0;
+			j--;	/* Otherwise, -elapsed gets confused with an
+				 * algorithm. */
+		} else if ((argc > 0) && (strcmp(*argv, "-evp") == 0)) {
+			argc--;
+			argv++;
+			if (argc == 0) {
+				BIO_printf(bio_err, "no EVP given\n");
+				goto end;
+			}
+			evp_cipher = EVP_get_cipherbyname(*argv);
+			if (!evp_cipher) {
+				evp_md = EVP_get_digestbyname(*argv);
+			}
+			if (!evp_cipher && !evp_md) {
+				BIO_printf(bio_err, "%s is an unknown cipher or digest\n", *argv);
+				goto end;
+			}
+			doit[D_EVP] = 1;
+		} else if (argc > 0 && !strcmp(*argv, "-decrypt")) {
+			decrypt = 1;
+			j--;	/* Otherwise, -elapsed gets confused with an
+				 * algorithm. */
+		}
+		else if ((argc > 0) && (strcmp(*argv, "-multi") == 0)) {
+			argc--;
+			argv++;
+			if (argc == 0) {
+				BIO_printf(bio_err, "no multi count given\n");
+				goto end;
+			}
+			multi = strtonum(argv[0], 1, INT_MAX, &errstr);
+			if (errstr) {
+				BIO_printf(bio_err, "bad multi count: %s", errstr);
+				goto end;
+			}
+			j--;	/* Otherwise, -mr gets confused with an
+				 * algorithm. */
+		}
+		else if (argc > 0 && !strcmp(*argv, "-mr")) {
+			mr = 1;
+			j--;	/* Otherwise, -mr gets confused with an
+				 * algorithm. */
+		} else
+#ifndef OPENSSL_NO_MD4
+		if (strcmp(*argv, "md4") == 0)
+			doit[D_MD4] = 1;
+		else
+#endif
+#ifndef OPENSSL_NO_MD5
+		if (strcmp(*argv, "md5") == 0)
+			doit[D_MD5] = 1;
+		else
+#endif
+#ifndef OPENSSL_NO_MD5
+		if (strcmp(*argv, "hmac") == 0)
+			doit[D_HMAC] = 1;
+		else
+#endif
+#ifndef OPENSSL_NO_SHA
+		if (strcmp(*argv, "sha1") == 0)
+			doit[D_SHA1] = 1;
+		else if (strcmp(*argv, "sha") == 0)
+			doit[D_SHA1] = 1,
+			    doit[D_SHA256] = 1,
+			    doit[D_SHA512] = 1;
+		else
+#ifndef OPENSSL_NO_SHA256
+		if (strcmp(*argv, "sha256") == 0)
+			doit[D_SHA256] = 1;
+		else
+#endif
+#ifndef OPENSSL_NO_SHA512
+		if (strcmp(*argv, "sha512") == 0)
+			doit[D_SHA512] = 1;
+		else
+#endif
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+		if (strcmp(*argv, "whirlpool") == 0)
+			doit[D_WHIRLPOOL] = 1;
+		else
+#endif
+#ifndef OPENSSL_NO_RIPEMD
+		if (strcmp(*argv, "ripemd") == 0)
+			doit[D_RMD160] = 1;
+		else if (strcmp(*argv, "rmd160") == 0)
+			doit[D_RMD160] = 1;
+		else if (strcmp(*argv, "ripemd160") == 0)
+			doit[D_RMD160] = 1;
+		else
+#endif
+#ifndef OPENSSL_NO_RC4
+		if (strcmp(*argv, "rc4") == 0)
+			doit[D_RC4] = 1;
+		else
+#endif
+#ifndef OPENSSL_NO_DES
+		if (strcmp(*argv, "des-cbc") == 0)
+			doit[D_CBC_DES] = 1;
+		else if (strcmp(*argv, "des-ede3") == 0)
+			doit[D_EDE3_DES] = 1;
+		else
+#endif
+#ifndef OPENSSL_NO_AES
+		if (strcmp(*argv, "aes-128-cbc") == 0)
+			doit[D_CBC_128_AES] = 1;
+		else if (strcmp(*argv, "aes-192-cbc") == 0)
+			doit[D_CBC_192_AES] = 1;
+		else if (strcmp(*argv, "aes-256-cbc") == 0)
+			doit[D_CBC_256_AES] = 1;
+		else if (strcmp(*argv, "aes-128-ige") == 0)
+			doit[D_IGE_128_AES] = 1;
+		else if (strcmp(*argv, "aes-192-ige") == 0)
+			doit[D_IGE_192_AES] = 1;
+		else if (strcmp(*argv, "aes-256-ige") == 0)
+			doit[D_IGE_256_AES] = 1;
+		else
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+		if (strcmp(*argv, "camellia-128-cbc") == 0)
+			doit[D_CBC_128_CML] = 1;
+		else if (strcmp(*argv, "camellia-192-cbc") == 0)
+			doit[D_CBC_192_CML] = 1;
+		else if (strcmp(*argv, "camellia-256-cbc") == 0)
+			doit[D_CBC_256_CML] = 1;
+		else
+#endif
+#ifndef RSA_NULL
+		if (strcmp(*argv, "openssl") == 0) {
+			RSA_set_default_method(RSA_PKCS1_SSLeay());
+			j--;
+		} else
+#endif
+		if (strcmp(*argv, "dsa512") == 0)
+			dsa_doit[R_DSA_512] = 2;
+		else if (strcmp(*argv, "dsa1024") == 0)
+			dsa_doit[R_DSA_1024] = 2;
+		else if (strcmp(*argv, "dsa2048") == 0)
+			dsa_doit[R_DSA_2048] = 2;
+		else if (strcmp(*argv, "rsa512") == 0)
+			rsa_doit[R_RSA_512] = 2;
+		else if (strcmp(*argv, "rsa1024") == 0)
+			rsa_doit[R_RSA_1024] = 2;
+		else if (strcmp(*argv, "rsa2048") == 0)
+			rsa_doit[R_RSA_2048] = 2;
+		else if (strcmp(*argv, "rsa4096") == 0)
+			rsa_doit[R_RSA_4096] = 2;
+		else
+#ifndef OPENSSL_NO_RC2
+		if (strcmp(*argv, "rc2-cbc") == 0)
+			doit[D_CBC_RC2] = 1;
+		else if (strcmp(*argv, "rc2") == 0)
+			doit[D_CBC_RC2] = 1;
+		else
+#endif
+#ifndef OPENSSL_NO_IDEA
+		if (strcmp(*argv, "idea-cbc") == 0)
+			doit[D_CBC_IDEA] = 1;
+		else if (strcmp(*argv, "idea") == 0)
+			doit[D_CBC_IDEA] = 1;
+		else
+#endif
+#ifndef OPENSSL_NO_BF
+		if (strcmp(*argv, "bf-cbc") == 0)
+			doit[D_CBC_BF] = 1;
+		else if (strcmp(*argv, "blowfish") == 0)
+			doit[D_CBC_BF] = 1;
+		else if (strcmp(*argv, "bf") == 0)
+			doit[D_CBC_BF] = 1;
+		else
+#endif
+#ifndef OPENSSL_NO_CAST
+		if (strcmp(*argv, "cast-cbc") == 0)
+			doit[D_CBC_CAST] = 1;
+		else if (strcmp(*argv, "cast") == 0)
+			doit[D_CBC_CAST] = 1;
+		else if (strcmp(*argv, "cast5") == 0)
+			doit[D_CBC_CAST] = 1;
+		else
+#endif
+#ifndef OPENSSL_NO_DES
+		if (strcmp(*argv, "des") == 0) {
+			doit[D_CBC_DES] = 1;
+			doit[D_EDE3_DES] = 1;
+		} else
+#endif
+#ifndef OPENSSL_NO_AES
+		if (strcmp(*argv, "aes") == 0) {
+			doit[D_CBC_128_AES] = 1;
+			doit[D_CBC_192_AES] = 1;
+			doit[D_CBC_256_AES] = 1;
+		} else if (strcmp(*argv, "ghash") == 0)
+			doit[D_GHASH] = 1;
+		else if (strcmp(*argv,"aes-128-gcm") == 0)
+			doit[D_AES_128_GCM]=1;
+		else if (strcmp(*argv,"aes-256-gcm") == 0)
+			doit[D_AES_256_GCM]=1;
+		else
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+		if (strcmp(*argv, "camellia") == 0) {
+			doit[D_CBC_128_CML] = 1;
+			doit[D_CBC_192_CML] = 1;
+			doit[D_CBC_256_CML] = 1;
+		} else
+#endif
+#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
+		if (strcmp(*argv,"chacha20-poly1305") == 0)
+			doit[D_CHACHA20_POLY1305]=1;
+		else
+#endif
+		if (strcmp(*argv, "rsa") == 0) {
+			rsa_doit[R_RSA_512] = 1;
+			rsa_doit[R_RSA_1024] = 1;
+			rsa_doit[R_RSA_2048] = 1;
+			rsa_doit[R_RSA_4096] = 1;
+		} else
+		if (strcmp(*argv, "dsa") == 0) {
+			dsa_doit[R_DSA_512] = 1;
+			dsa_doit[R_DSA_1024] = 1;
+			dsa_doit[R_DSA_2048] = 1;
+		} else
+		if (strcmp(*argv, "ecdsap160") == 0)
+			ecdsa_doit[R_EC_P160] = 2;
+		else if (strcmp(*argv, "ecdsap192") == 0)
+			ecdsa_doit[R_EC_P192] = 2;
+		else if (strcmp(*argv, "ecdsap224") == 0)
+			ecdsa_doit[R_EC_P224] = 2;
+		else if (strcmp(*argv, "ecdsap256") == 0)
+			ecdsa_doit[R_EC_P256] = 2;
+		else if (strcmp(*argv, "ecdsap384") == 0)
+			ecdsa_doit[R_EC_P384] = 2;
+		else if (strcmp(*argv, "ecdsap521") == 0)
+			ecdsa_doit[R_EC_P521] = 2;
+		else if (strcmp(*argv, "ecdsak163") == 0)
+			ecdsa_doit[R_EC_K163] = 2;
+		else if (strcmp(*argv, "ecdsak233") == 0)
+			ecdsa_doit[R_EC_K233] = 2;
+		else if (strcmp(*argv, "ecdsak283") == 0)
+			ecdsa_doit[R_EC_K283] = 2;
+		else if (strcmp(*argv, "ecdsak409") == 0)
+			ecdsa_doit[R_EC_K409] = 2;
+		else if (strcmp(*argv, "ecdsak571") == 0)
+			ecdsa_doit[R_EC_K571] = 2;
+		else if (strcmp(*argv, "ecdsab163") == 0)
+			ecdsa_doit[R_EC_B163] = 2;
+		else if (strcmp(*argv, "ecdsab233") == 0)
+			ecdsa_doit[R_EC_B233] = 2;
+		else if (strcmp(*argv, "ecdsab283") == 0)
+			ecdsa_doit[R_EC_B283] = 2;
+		else if (strcmp(*argv, "ecdsab409") == 0)
+			ecdsa_doit[R_EC_B409] = 2;
+		else if (strcmp(*argv, "ecdsab571") == 0)
+			ecdsa_doit[R_EC_B571] = 2;
+		else if (strcmp(*argv, "ecdsa") == 0) {
+			for (i = 0; i < EC_NUM; i++)
+				ecdsa_doit[i] = 1;
+		} else
+		if (strcmp(*argv, "ecdhp160") == 0)
+			ecdh_doit[R_EC_P160] = 2;
+		else if (strcmp(*argv, "ecdhp192") == 0)
+			ecdh_doit[R_EC_P192] = 2;
+		else if (strcmp(*argv, "ecdhp224") == 0)
+			ecdh_doit[R_EC_P224] = 2;
+		else if (strcmp(*argv, "ecdhp256") == 0)
+			ecdh_doit[R_EC_P256] = 2;
+		else if (strcmp(*argv, "ecdhp384") == 0)
+			ecdh_doit[R_EC_P384] = 2;
+		else if (strcmp(*argv, "ecdhp521") == 0)
+			ecdh_doit[R_EC_P521] = 2;
+		else if (strcmp(*argv, "ecdhk163") == 0)
+			ecdh_doit[R_EC_K163] = 2;
+		else if (strcmp(*argv, "ecdhk233") == 0)
+			ecdh_doit[R_EC_K233] = 2;
+		else if (strcmp(*argv, "ecdhk283") == 0)
+			ecdh_doit[R_EC_K283] = 2;
+		else if (strcmp(*argv, "ecdhk409") == 0)
+			ecdh_doit[R_EC_K409] = 2;
+		else if (strcmp(*argv, "ecdhk571") == 0)
+			ecdh_doit[R_EC_K571] = 2;
+		else if (strcmp(*argv, "ecdhb163") == 0)
+			ecdh_doit[R_EC_B163] = 2;
+		else if (strcmp(*argv, "ecdhb233") == 0)
+			ecdh_doit[R_EC_B233] = 2;
+		else if (strcmp(*argv, "ecdhb283") == 0)
+			ecdh_doit[R_EC_B283] = 2;
+		else if (strcmp(*argv, "ecdhb409") == 0)
+			ecdh_doit[R_EC_B409] = 2;
+		else if (strcmp(*argv, "ecdhb571") == 0)
+			ecdh_doit[R_EC_B571] = 2;
+		else if (strcmp(*argv, "ecdh") == 0) {
+			for (i = 0; i < EC_NUM; i++)
+				ecdh_doit[i] = 1;
+		} else
+		{
+			BIO_printf(bio_err, "Error: bad option or value\n");
+			BIO_printf(bio_err, "\n");
+			BIO_printf(bio_err, "Available values:\n");
+#ifndef OPENSSL_NO_MD4
+			BIO_printf(bio_err, "md4      ");
+#endif
+#ifndef OPENSSL_NO_MD5
+			BIO_printf(bio_err, "md5      ");
+#ifndef OPENSSL_NO_HMAC
+			BIO_printf(bio_err, "hmac     ");
+#endif
+#endif
+#ifndef OPENSSL_NO_SHA1
+			BIO_printf(bio_err, "sha1     ");
+#endif
+#ifndef OPENSSL_NO_SHA256
+			BIO_printf(bio_err, "sha256   ");
+#endif
+#ifndef OPENSSL_NO_SHA512
+			BIO_printf(bio_err, "sha512   ");
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+			BIO_printf(bio_err, "whirlpool");
+#endif
+#ifndef OPENSSL_NO_RIPEMD160
+			BIO_printf(bio_err, "rmd160");
+#endif
+#if !defined(OPENSSL_NO_MD2) || \
+    !defined(OPENSSL_NO_MD4) || !defined(OPENSSL_NO_MD5) || \
+    !defined(OPENSSL_NO_SHA1) || !defined(OPENSSL_NO_RIPEMD160) || \
+    !defined(OPENSSL_NO_WHIRLPOOL)
+			BIO_printf(bio_err, "\n");
+#endif
+
+#ifndef OPENSSL_NO_IDEA
+			BIO_printf(bio_err, "idea-cbc ");
+#endif
+#ifndef OPENSSL_NO_RC2
+			BIO_printf(bio_err, "rc2-cbc  ");
+#endif
+#ifndef OPENSSL_NO_BF
+			BIO_printf(bio_err, "bf-cbc   ");
+#endif
+#ifndef OPENSSL_NO_DES
+			BIO_printf(bio_err, "des-cbc  des-ede3\n");
+#endif
+#ifndef OPENSSL_NO_AES
+			BIO_printf(bio_err, "aes-128-cbc aes-192-cbc aes-256-cbc ");
+			BIO_printf(bio_err, "aes-128-ige aes-192-ige aes-256-ige\n");
+			BIO_printf(bio_err, "aes-128-gcm aes-256-gcm ");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+			BIO_printf(bio_err, "\n");
+			BIO_printf(bio_err, "camellia-128-cbc camellia-192-cbc camellia-256-cbc ");
+#endif
+#ifndef OPENSSL_NO_RC4
+			BIO_printf(bio_err, "rc4");
+#endif
+#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
+			BIO_printf(bio_err," chacha20-poly1305");
+#endif
+			BIO_printf(bio_err, "\n");
+
+			BIO_printf(bio_err, "rsa512   rsa1024  rsa2048  rsa4096\n");
+
+			BIO_printf(bio_err, "dsa512   dsa1024  dsa2048\n");
+			BIO_printf(bio_err, "ecdsap160 ecdsap192 ecdsap224 ecdsap256 ecdsap384 ecdsap521\n");
+			BIO_printf(bio_err, "ecdsak163 ecdsak233 ecdsak283 ecdsak409 ecdsak571\n");
+			BIO_printf(bio_err, "ecdsab163 ecdsab233 ecdsab283 ecdsab409 ecdsab571 ecdsa\n");
+			BIO_printf(bio_err, "ecdhp160  ecdhp192  ecdhp224  ecdhp256  ecdhp384  ecdhp521\n");
+			BIO_printf(bio_err, "ecdhk163  ecdhk233  ecdhk283  ecdhk409  ecdhk571\n");
+			BIO_printf(bio_err, "ecdhb163  ecdhb233  ecdhb283  ecdhb409  ecdhb571  ecdh\n");
+
+#ifndef OPENSSL_NO_IDEA
+			BIO_printf(bio_err, "idea     ");
+#endif
+#ifndef OPENSSL_NO_RC2
+			BIO_printf(bio_err, "rc2      ");
+#endif
+#ifndef OPENSSL_NO_DES
+			BIO_printf(bio_err, "des      ");
+#endif
+#ifndef OPENSSL_NO_AES
+			BIO_printf(bio_err, "aes      ");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+			BIO_printf(bio_err, "camellia ");
+#endif
+			BIO_printf(bio_err, "rsa      ");
+#ifndef OPENSSL_NO_BF
+			BIO_printf(bio_err, "blowfish");
+#endif
+#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_SEED) || \
+    !defined(OPENSSL_NO_RC2) || !defined(OPENSSL_NO_DES) || \
+    !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_BF) || \
+    !defined(OPENSSL_NO_AES) || !defined(OPENSSL_NO_CAMELLIA)
+			BIO_printf(bio_err, "\n");
+#endif
+
+			BIO_printf(bio_err, "\n");
+			BIO_printf(bio_err, "Available options:\n");
+			BIO_printf(bio_err, "-elapsed        measure time in real time instead of CPU user time.\n");
+			BIO_printf(bio_err, "-evp e          use EVP e.\n");
+			BIO_printf(bio_err, "-decrypt        time decryption instead of encryption (only EVP).\n");
+			BIO_printf(bio_err, "-mr             produce machine readable output.\n");
+			BIO_printf(bio_err, "-multi n        run n benchmarks in parallel.\n");
+			goto end;
+		}
+		argc--;
+		argv++;
+		j++;
+	}
+
+	if (multi && do_multi(multi))
+		goto show_res;
+
+	if (j == 0) {
+		for (i = 0; i < ALGOR_NUM; i++) {
+			if (i != D_EVP)
+				doit[i] = 1;
+		}
+		for (i = 0; i < RSA_NUM; i++)
+			rsa_doit[i] = 1;
+		for (i = 0; i < DSA_NUM; i++)
+			dsa_doit[i] = 1;
+		for (i = 0; i < EC_NUM; i++)
+			ecdsa_doit[i] = 1;
+		for (i = 0; i < EC_NUM; i++)
+			ecdh_doit[i] = 1;
+	}
+	for (i = 0; i < ALGOR_NUM; i++)
+		if (doit[i])
+			pr_header++;
+
+	if (usertime == 0 && !mr)
+		BIO_printf(bio_err, "You have chosen to measure elapsed time instead of user CPU time.\n");
+
+	for (i = 0; i < RSA_NUM; i++) {
+		const unsigned char *p;
+
+		p = rsa_data[i];
+		rsa_key[i] = d2i_RSAPrivateKey(NULL, &p, rsa_data_length[i]);
+		if (rsa_key[i] == NULL) {
+			BIO_printf(bio_err, "internal error loading RSA key number %d\n", i);
+			goto end;
+		}
+	}
+
+	dsa_key[0] = get_dsa512();
+	dsa_key[1] = get_dsa1024();
+	dsa_key[2] = get_dsa2048();
+
+#ifndef OPENSSL_NO_DES
+	DES_set_key_unchecked(&key, &sch);
+	DES_set_key_unchecked(&key2, &sch2);
+	DES_set_key_unchecked(&key3, &sch3);
+#endif
+#ifndef OPENSSL_NO_AES
+	AES_set_encrypt_key(key16, 128, &aes_ks1);
+	AES_set_encrypt_key(key24, 192, &aes_ks2);
+	AES_set_encrypt_key(key32, 256, &aes_ks3);
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+	Camellia_set_key(key16, 128, &camellia_ks1);
+	Camellia_set_key(ckey24, 192, &camellia_ks2);
+	Camellia_set_key(ckey32, 256, &camellia_ks3);
+#endif
+#ifndef OPENSSL_NO_IDEA
+	idea_set_encrypt_key(key16, &idea_ks);
+#endif
+#ifndef OPENSSL_NO_RC4
+	RC4_set_key(&rc4_ks, 16, key16);
+#endif
+#ifndef OPENSSL_NO_RC2
+	RC2_set_key(&rc2_ks, 16, key16, 128);
+#endif
+#ifndef OPENSSL_NO_BF
+	BF_set_key(&bf_ks, 16, key16);
+#endif
+#ifndef OPENSSL_NO_CAST
+	CAST_set_key(&cast_ks, 16, key16);
+#endif
+	memset(rsa_c, 0, sizeof(rsa_c));
+#define COND(c)	(run && count<0x7fffffff)
+#define COUNT(d) (count)
+	signal(SIGALRM, sig_done);
+
+#ifndef OPENSSL_NO_MD4
+	if (doit[D_MD4]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_MD4], c[D_MD4][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_MD4][j]); count++)
+				EVP_Digest(&(buf[0]), (unsigned long) lengths[j], &(md4[0]), NULL, EVP_md4(), NULL);
+			d = Time_F(STOP);
+			print_result(D_MD4, j, count, d);
+		}
+	}
+#endif
+
+#ifndef OPENSSL_NO_MD5
+	if (doit[D_MD5]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_MD5], c[D_MD5][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_MD5][j]); count++)
+				EVP_Digest(&(buf[0]), (unsigned long) lengths[j], &(md5[0]), NULL, EVP_get_digestbyname("md5"), NULL);
+			d = Time_F(STOP);
+			print_result(D_MD5, j, count, d);
+		}
+	}
+#endif
+
+#if !defined(OPENSSL_NO_MD5) && !defined(OPENSSL_NO_HMAC)
+	if (doit[D_HMAC]) {
+		HMAC_CTX hctx;
+
+		HMAC_CTX_init(&hctx);
+		HMAC_Init_ex(&hctx, (unsigned char *) "This is a key...",
+		    16, EVP_md5(), NULL);
+
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_HMAC], c[D_HMAC][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_HMAC][j]); count++) {
+				HMAC_Init_ex(&hctx, NULL, 0, NULL, NULL);
+				HMAC_Update(&hctx, buf, lengths[j]);
+				HMAC_Final(&hctx, &(hmac[0]), NULL);
+			}
+			d = Time_F(STOP);
+			print_result(D_HMAC, j, count, d);
+		}
+		HMAC_CTX_cleanup(&hctx);
+	}
+#endif
+#ifndef OPENSSL_NO_SHA
+	if (doit[D_SHA1]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_SHA1], c[D_SHA1][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_SHA1][j]); count++)
+				EVP_Digest(buf, (unsigned long) lengths[j], &(sha[0]), NULL, EVP_sha1(), NULL);
+			d = Time_F(STOP);
+			print_result(D_SHA1, j, count, d);
+		}
+	}
+#ifndef OPENSSL_NO_SHA256
+	if (doit[D_SHA256]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_SHA256], c[D_SHA256][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_SHA256][j]); count++)
+				SHA256(buf, lengths[j], sha256);
+			d = Time_F(STOP);
+			print_result(D_SHA256, j, count, d);
+		}
+	}
+#endif
+
+#ifndef OPENSSL_NO_SHA512
+	if (doit[D_SHA512]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_SHA512], c[D_SHA512][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_SHA512][j]); count++)
+				SHA512(buf, lengths[j], sha512);
+			d = Time_F(STOP);
+			print_result(D_SHA512, j, count, d);
+		}
+	}
+#endif
+#endif
+
+#ifndef OPENSSL_NO_WHIRLPOOL
+	if (doit[D_WHIRLPOOL]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_WHIRLPOOL], c[D_WHIRLPOOL][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_WHIRLPOOL][j]); count++)
+				WHIRLPOOL(buf, lengths[j], whirlpool);
+			d = Time_F(STOP);
+			print_result(D_WHIRLPOOL, j, count, d);
+		}
+	}
+#endif
+
+#ifndef OPENSSL_NO_RIPEMD
+	if (doit[D_RMD160]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_RMD160], c[D_RMD160][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_RMD160][j]); count++)
+				EVP_Digest(buf, (unsigned long) lengths[j], &(rmd160[0]), NULL, EVP_ripemd160(), NULL);
+			d = Time_F(STOP);
+			print_result(D_RMD160, j, count, d);
+		}
+	}
+#endif
+#ifndef OPENSSL_NO_RC4
+	if (doit[D_RC4]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_RC4], c[D_RC4][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_RC4][j]); count++)
+				RC4(&rc4_ks, (unsigned int) lengths[j],
+				    buf, buf);
+			d = Time_F(STOP);
+			print_result(D_RC4, j, count, d);
+		}
+	}
+#endif
+#ifndef OPENSSL_NO_DES
+	if (doit[D_CBC_DES]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_CBC_DES], c[D_CBC_DES][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_CBC_DES][j]); count++)
+				DES_ncbc_encrypt(buf, buf, lengths[j], &sch,
+				    &DES_iv, DES_ENCRYPT);
+			d = Time_F(STOP);
+			print_result(D_CBC_DES, j, count, d);
+		}
+	}
+	if (doit[D_EDE3_DES]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_EDE3_DES], c[D_EDE3_DES][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_EDE3_DES][j]); count++)
+				DES_ede3_cbc_encrypt(buf, buf, lengths[j],
+				    &sch, &sch2, &sch3,
+				    &DES_iv, DES_ENCRYPT);
+			d = Time_F(STOP);
+			print_result(D_EDE3_DES, j, count, d);
+		}
+	}
+#endif
+#ifndef OPENSSL_NO_AES
+	if (doit[D_CBC_128_AES]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_CBC_128_AES], c[D_CBC_128_AES][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_CBC_128_AES][j]); count++)
+				AES_cbc_encrypt(buf, buf,
+				    (unsigned long) lengths[j], &aes_ks1,
+				    iv, AES_ENCRYPT);
+			d = Time_F(STOP);
+			print_result(D_CBC_128_AES, j, count, d);
+		}
+	}
+	if (doit[D_CBC_192_AES]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_CBC_192_AES], c[D_CBC_192_AES][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_CBC_192_AES][j]); count++)
+				AES_cbc_encrypt(buf, buf,
+				    (unsigned long) lengths[j], &aes_ks2,
+				    iv, AES_ENCRYPT);
+			d = Time_F(STOP);
+			print_result(D_CBC_192_AES, j, count, d);
+		}
+	}
+	if (doit[D_CBC_256_AES]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_CBC_256_AES], c[D_CBC_256_AES][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_CBC_256_AES][j]); count++)
+				AES_cbc_encrypt(buf, buf,
+				    (unsigned long) lengths[j], &aes_ks3,
+				    iv, AES_ENCRYPT);
+			d = Time_F(STOP);
+			print_result(D_CBC_256_AES, j, count, d);
+		}
+	}
+	if (doit[D_IGE_128_AES]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_IGE_128_AES], c[D_IGE_128_AES][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_IGE_128_AES][j]); count++)
+				AES_ige_encrypt(buf, buf2,
+				    (unsigned long) lengths[j], &aes_ks1,
+				    iv, AES_ENCRYPT);
+			d = Time_F(STOP);
+			print_result(D_IGE_128_AES, j, count, d);
+		}
+	}
+	if (doit[D_IGE_192_AES]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_IGE_192_AES], c[D_IGE_192_AES][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_IGE_192_AES][j]); count++)
+				AES_ige_encrypt(buf, buf2,
+				    (unsigned long) lengths[j], &aes_ks2,
+				    iv, AES_ENCRYPT);
+			d = Time_F(STOP);
+			print_result(D_IGE_192_AES, j, count, d);
+		}
+	}
+	if (doit[D_IGE_256_AES]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_IGE_256_AES], c[D_IGE_256_AES][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_IGE_256_AES][j]); count++)
+				AES_ige_encrypt(buf, buf2,
+				    (unsigned long) lengths[j], &aes_ks3,
+				    iv, AES_ENCRYPT);
+			d = Time_F(STOP);
+			print_result(D_IGE_256_AES, j, count, d);
+		}
+	}
+	if (doit[D_GHASH]) {
+		GCM128_CONTEXT *ctx = CRYPTO_gcm128_new(&aes_ks1, (block128_f) AES_encrypt);
+		CRYPTO_gcm128_setiv(ctx, (unsigned char *) "0123456789ab", 12);
+
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_GHASH], c[D_GHASH][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_GHASH][j]); count++)
+				CRYPTO_gcm128_aad(ctx, buf, lengths[j]);
+			d = Time_F(STOP);
+			print_result(D_GHASH, j, count, d);
+		}
+		CRYPTO_gcm128_release(ctx);
+	}
+	if (doit[D_AES_128_GCM]) {
+		const EVP_AEAD *aead = EVP_aead_aes_128_gcm();
+		static const unsigned char nonce[32] = {0};
+		size_t buf_len, nonce_len;
+		EVP_AEAD_CTX ctx;
+
+		EVP_AEAD_CTX_init(&ctx, aead, key32, EVP_AEAD_key_length(aead),
+		    EVP_AEAD_DEFAULT_TAG_LENGTH, NULL);
+		nonce_len = EVP_AEAD_nonce_length(aead);
+
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_AES_128_GCM],c[D_AES_128_GCM][j],lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_AES_128_GCM][j]); count++)
+				EVP_AEAD_CTX_seal(&ctx, buf, &buf_len, BUFSIZE, nonce,
+				    nonce_len, buf, lengths[j], NULL, 0);
+			d=Time_F(STOP);
+			print_result(D_AES_128_GCM,j,count,d);
+		}
+		EVP_AEAD_CTX_cleanup(&ctx);
+	}
+
+	if (doit[D_AES_256_GCM]) {
+		const EVP_AEAD *aead = EVP_aead_aes_256_gcm();
+		static const unsigned char nonce[32] = {0};
+		size_t buf_len, nonce_len;
+		EVP_AEAD_CTX ctx;
+
+		EVP_AEAD_CTX_init(&ctx, aead, key32, EVP_AEAD_key_length(aead),
+		EVP_AEAD_DEFAULT_TAG_LENGTH, NULL);
+		nonce_len = EVP_AEAD_nonce_length(aead);
+
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_AES_256_GCM],c[D_AES_256_GCM][j],lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_AES_256_GCM][j]); count++)
+				EVP_AEAD_CTX_seal(&ctx, buf, &buf_len, BUFSIZE, nonce,
+				    nonce_len, buf, lengths[j], NULL, 0);
+			d=Time_F(STOP);
+			print_result(D_AES_256_GCM, j, count, d);
+		}
+		EVP_AEAD_CTX_cleanup(&ctx);
+	}
+#endif
+#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
+	if (doit[D_CHACHA20_POLY1305]) {
+		const EVP_AEAD *aead = EVP_aead_chacha20_poly1305();
+		static const unsigned char nonce[32] = {0};
+		size_t buf_len, nonce_len;
+		EVP_AEAD_CTX ctx;
+
+		EVP_AEAD_CTX_init(&ctx, aead, key32, EVP_AEAD_key_length(aead),
+		    EVP_AEAD_DEFAULT_TAG_LENGTH, NULL);
+		nonce_len = EVP_AEAD_nonce_length(aead);
+
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_CHACHA20_POLY1305],
+			    c[D_CHACHA20_POLY1305][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_CHACHA20_POLY1305][j]); count++)
+				EVP_AEAD_CTX_seal(&ctx, buf, &buf_len, BUFSIZE, nonce,
+				    nonce_len, buf, lengths[j], NULL, 0);
+			d=Time_F(STOP);
+			print_result(D_CHACHA20_POLY1305, j, count, d);
+		}
+		EVP_AEAD_CTX_cleanup(&ctx);
+	}
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+	if (doit[D_CBC_128_CML]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_CBC_128_CML], c[D_CBC_128_CML][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_CBC_128_CML][j]); count++)
+				Camellia_cbc_encrypt(buf, buf,
+				    (unsigned long) lengths[j], &camellia_ks1,
+				    iv, CAMELLIA_ENCRYPT);
+			d = Time_F(STOP);
+			print_result(D_CBC_128_CML, j, count, d);
+		}
+	}
+	if (doit[D_CBC_192_CML]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_CBC_192_CML], c[D_CBC_192_CML][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_CBC_192_CML][j]); count++)
+				Camellia_cbc_encrypt(buf, buf,
+				    (unsigned long) lengths[j], &camellia_ks2,
+				    iv, CAMELLIA_ENCRYPT);
+			d = Time_F(STOP);
+			print_result(D_CBC_192_CML, j, count, d);
+		}
+	}
+	if (doit[D_CBC_256_CML]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_CBC_256_CML], c[D_CBC_256_CML][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_CBC_256_CML][j]); count++)
+				Camellia_cbc_encrypt(buf, buf,
+				    (unsigned long) lengths[j], &camellia_ks3,
+				    iv, CAMELLIA_ENCRYPT);
+			d = Time_F(STOP);
+			print_result(D_CBC_256_CML, j, count, d);
+		}
+	}
+#endif
+#ifndef OPENSSL_NO_IDEA
+	if (doit[D_CBC_IDEA]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_CBC_IDEA], c[D_CBC_IDEA][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_CBC_IDEA][j]); count++)
+				idea_cbc_encrypt(buf, buf,
+				    (unsigned long) lengths[j], &idea_ks,
+				    iv, IDEA_ENCRYPT);
+			d = Time_F(STOP);
+			print_result(D_CBC_IDEA, j, count, d);
+		}
+	}
+#endif
+#ifndef OPENSSL_NO_RC2
+	if (doit[D_CBC_RC2]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_CBC_RC2], c[D_CBC_RC2][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_CBC_RC2][j]); count++)
+				RC2_cbc_encrypt(buf, buf,
+				    (unsigned long) lengths[j], &rc2_ks,
+				    iv, RC2_ENCRYPT);
+			d = Time_F(STOP);
+			print_result(D_CBC_RC2, j, count, d);
+		}
+	}
+#endif
+#ifndef OPENSSL_NO_BF
+	if (doit[D_CBC_BF]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_CBC_BF], c[D_CBC_BF][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_CBC_BF][j]); count++)
+				BF_cbc_encrypt(buf, buf,
+				    (unsigned long) lengths[j], &bf_ks,
+				    iv, BF_ENCRYPT);
+			d = Time_F(STOP);
+			print_result(D_CBC_BF, j, count, d);
+		}
+	}
+#endif
+#ifndef OPENSSL_NO_CAST
+	if (doit[D_CBC_CAST]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			print_message(names[D_CBC_CAST], c[D_CBC_CAST][j], lengths[j]);
+			Time_F(START);
+			for (count = 0, run = 1; COND(c[D_CBC_CAST][j]); count++)
+				CAST_cbc_encrypt(buf, buf,
+				    (unsigned long) lengths[j], &cast_ks,
+				    iv, CAST_ENCRYPT);
+			d = Time_F(STOP);
+			print_result(D_CBC_CAST, j, count, d);
+		}
+	}
+#endif
+
+	if (doit[D_EVP]) {
+		for (j = 0; j < SIZE_NUM; j++) {
+			if (evp_cipher) {
+				EVP_CIPHER_CTX ctx;
+				int outl;
+
+				names[D_EVP] = OBJ_nid2ln(evp_cipher->nid);
+				/*
+				 * -O3 -fschedule-insns messes up an
+				 * optimization here!  names[D_EVP] somehow
+				 * becomes NULL
+				 */
+				print_message(names[D_EVP], save_count,
+				    lengths[j]);
+
+				EVP_CIPHER_CTX_init(&ctx);
+				if (decrypt)
+					EVP_DecryptInit_ex(&ctx, evp_cipher, NULL, key16, iv);
+				else
+					EVP_EncryptInit_ex(&ctx, evp_cipher, NULL, key16, iv);
+				EVP_CIPHER_CTX_set_padding(&ctx, 0);
+
+				Time_F(START);
+				if (decrypt)
+					for (count = 0, run = 1; COND(save_count * 4 * lengths[0] / lengths[j]); count++)
+						EVP_DecryptUpdate(&ctx, buf, &outl, buf, lengths[j]);
+				else
+					for (count = 0, run = 1; COND(save_count * 4 * lengths[0] / lengths[j]); count++)
+						EVP_EncryptUpdate(&ctx, buf, &outl, buf, lengths[j]);
+				if (decrypt)
+					EVP_DecryptFinal_ex(&ctx, buf, &outl);
+				else
+					EVP_EncryptFinal_ex(&ctx, buf, &outl);
+				d = Time_F(STOP);
+				EVP_CIPHER_CTX_cleanup(&ctx);
+			}
+			if (evp_md) {
+				names[D_EVP] = OBJ_nid2ln(evp_md->type);
+				print_message(names[D_EVP], save_count,
+				    lengths[j]);
+
+				Time_F(START);
+				for (count = 0, run = 1; COND(save_count * 4 * lengths[0] / lengths[j]); count++)
+					EVP_Digest(buf, lengths[j], &(md[0]), NULL, evp_md, NULL);
+
+				d = Time_F(STOP);
+			}
+			print_result(D_EVP, j, count, d);
+		}
+	}
+	arc4random_buf(buf, 36);
+	for (j = 0; j < RSA_NUM; j++) {
+		int ret;
+		if (!rsa_doit[j])
+			continue;
+		ret = RSA_sign(NID_md5_sha1, buf, 36, buf2, &rsa_num, rsa_key[j]);
+		if (ret == 0) {
+			BIO_printf(bio_err, "RSA sign failure.  No RSA sign will be done.\n");
+			ERR_print_errors(bio_err);
+			rsa_count = 1;
+		} else {
+			pkey_print_message("private", "rsa",
+			    rsa_c[j][0], rsa_bits[j],
+			    RSA_SECONDS);
+/*			RSA_blinding_on(rsa_key[j],NULL); */
+			Time_F(START);
+			for (count = 0, run = 1; COND(rsa_c[j][0]); count++) {
+				ret = RSA_sign(NID_md5_sha1, buf, 36, buf2,
+				    &rsa_num, rsa_key[j]);
+				if (ret == 0) {
+					BIO_printf(bio_err,
+					    "RSA sign failure\n");
+					ERR_print_errors(bio_err);
+					count = 1;
+					break;
+				}
+			}
+			d = Time_F(STOP);
+			BIO_printf(bio_err, mr ? "+R1:%ld:%d:%.2f\n"
+			    : "%ld %d bit private RSA's in %.2fs\n",
+			    count, rsa_bits[j], d);
+			rsa_results[j][0] = d / (double) count;
+			rsa_count = count;
+		}
+
+		ret = RSA_verify(NID_md5_sha1, buf, 36, buf2, rsa_num, rsa_key[j]);
+		if (ret <= 0) {
+			BIO_printf(bio_err, "RSA verify failure.  No RSA verify will be done.\n");
+			ERR_print_errors(bio_err);
+			rsa_doit[j] = 0;
+		} else {
+			pkey_print_message("public", "rsa",
+			    rsa_c[j][1], rsa_bits[j],
+			    RSA_SECONDS);
+			Time_F(START);
+			for (count = 0, run = 1; COND(rsa_c[j][1]); count++) {
+				ret = RSA_verify(NID_md5_sha1, buf, 36, buf2,
+				    rsa_num, rsa_key[j]);
+				if (ret <= 0) {
+					BIO_printf(bio_err,
+					    "RSA verify failure\n");
+					ERR_print_errors(bio_err);
+					count = 1;
+					break;
+				}
+			}
+			d = Time_F(STOP);
+			BIO_printf(bio_err, mr ? "+R2:%ld:%d:%.2f\n"
+			    : "%ld %d bit public RSA's in %.2fs\n",
+			    count, rsa_bits[j], d);
+			rsa_results[j][1] = d / (double) count;
+		}
+
+		if (rsa_count <= 1) {
+			/* if longer than 10s, don't do any more */
+			for (j++; j < RSA_NUM; j++)
+				rsa_doit[j] = 0;
+		}
+	}
+
+	arc4random_buf(buf, 20);
+	for (j = 0; j < DSA_NUM; j++) {
+		unsigned int kk;
+		int ret;
+
+		if (!dsa_doit[j])
+			continue;
+/*		DSA_generate_key(dsa_key[j]); */
+/*		DSA_sign_setup(dsa_key[j],NULL); */
+		ret = DSA_sign(EVP_PKEY_DSA, buf, 20, buf2,
+		    &kk, dsa_key[j]);
+		if (ret == 0) {
+			BIO_printf(bio_err, "DSA sign failure.  No DSA sign will be done.\n");
+			ERR_print_errors(bio_err);
+			rsa_count = 1;
+		} else {
+			pkey_print_message("sign", "dsa",
+			    dsa_c[j][0], dsa_bits[j],
+			    DSA_SECONDS);
+			Time_F(START);
+			for (count = 0, run = 1; COND(dsa_c[j][0]); count++) {
+				ret = DSA_sign(EVP_PKEY_DSA, buf, 20, buf2,
+				    &kk, dsa_key[j]);
+				if (ret == 0) {
+					BIO_printf(bio_err,
+					    "DSA sign failure\n");
+					ERR_print_errors(bio_err);
+					count = 1;
+					break;
+				}
+			}
+			d = Time_F(STOP);
+			BIO_printf(bio_err, mr ? "+R3:%ld:%d:%.2f\n"
+			    : "%ld %d bit DSA signs in %.2fs\n",
+			    count, dsa_bits[j], d);
+			dsa_results[j][0] = d / (double) count;
+			rsa_count = count;
+		}
+
+		ret = DSA_verify(EVP_PKEY_DSA, buf, 20, buf2,
+		    kk, dsa_key[j]);
+		if (ret <= 0) {
+			BIO_printf(bio_err, "DSA verify failure.  No DSA verify will be done.\n");
+			ERR_print_errors(bio_err);
+			dsa_doit[j] = 0;
+		} else {
+			pkey_print_message("verify", "dsa",
+			    dsa_c[j][1], dsa_bits[j],
+			    DSA_SECONDS);
+			Time_F(START);
+			for (count = 0, run = 1; COND(dsa_c[j][1]); count++) {
+				ret = DSA_verify(EVP_PKEY_DSA, buf, 20, buf2,
+				    kk, dsa_key[j]);
+				if (ret <= 0) {
+					BIO_printf(bio_err,
+					    "DSA verify failure\n");
+					ERR_print_errors(bio_err);
+					count = 1;
+					break;
+				}
+			}
+			d = Time_F(STOP);
+			BIO_printf(bio_err, mr ? "+R4:%ld:%d:%.2f\n"
+			    : "%ld %d bit DSA verify in %.2fs\n",
+			    count, dsa_bits[j], d);
+			dsa_results[j][1] = d / (double) count;
+		}
+
+		if (rsa_count <= 1) {
+			/* if longer than 10s, don't do any more */
+			for (j++; j < DSA_NUM; j++)
+				dsa_doit[j] = 0;
+		}
+	}
+
+	for (j = 0; j < EC_NUM; j++) {
+		int ret;
+
+		if (!ecdsa_doit[j])
+			continue;	/* Ignore Curve */
+		ecdsa[j] = EC_KEY_new_by_curve_name(test_curves[j]);
+		if (ecdsa[j] == NULL) {
+			BIO_printf(bio_err, "ECDSA failure.\n");
+			ERR_print_errors(bio_err);
+			rsa_count = 1;
+		} else {
+			EC_KEY_precompute_mult(ecdsa[j], NULL);
+
+			/* Perform ECDSA signature test */
+			EC_KEY_generate_key(ecdsa[j]);
+			ret = ECDSA_sign(0, buf, 20, ecdsasig,
+			    &ecdsasiglen, ecdsa[j]);
+			if (ret == 0) {
+				BIO_printf(bio_err, "ECDSA sign failure.  No ECDSA sign will be done.\n");
+				ERR_print_errors(bio_err);
+				rsa_count = 1;
+			} else {
+				pkey_print_message("sign", "ecdsa",
+				    ecdsa_c[j][0],
+				    test_curves_bits[j],
+				    ECDSA_SECONDS);
+
+				Time_F(START);
+				for (count = 0, run = 1; COND(ecdsa_c[j][0]);
+				    count++) {
+					ret = ECDSA_sign(0, buf, 20,
+					    ecdsasig, &ecdsasiglen,
+					    ecdsa[j]);
+					if (ret == 0) {
+						BIO_printf(bio_err, "ECDSA sign failure\n");
+						ERR_print_errors(bio_err);
+						count = 1;
+						break;
+					}
+				}
+				d = Time_F(STOP);
+
+				BIO_printf(bio_err, mr ? "+R5:%ld:%d:%.2f\n" :
+				    "%ld %d bit ECDSA signs in %.2fs \n",
+				    count, test_curves_bits[j], d);
+				ecdsa_results[j][0] = d / (double) count;
+				rsa_count = count;
+			}
+
+			/* Perform ECDSA verification test */
+			ret = ECDSA_verify(0, buf, 20, ecdsasig,
+			    ecdsasiglen, ecdsa[j]);
+			if (ret != 1) {
+				BIO_printf(bio_err, "ECDSA verify failure.  No ECDSA verify will be done.\n");
+				ERR_print_errors(bio_err);
+				ecdsa_doit[j] = 0;
+			} else {
+				pkey_print_message("verify", "ecdsa",
+				    ecdsa_c[j][1],
+				    test_curves_bits[j],
+				    ECDSA_SECONDS);
+				Time_F(START);
+				for (count = 0, run = 1; COND(ecdsa_c[j][1]); count++) {
+					ret = ECDSA_verify(0, buf, 20, ecdsasig, ecdsasiglen, ecdsa[j]);
+					if (ret != 1) {
+						BIO_printf(bio_err, "ECDSA verify failure\n");
+						ERR_print_errors(bio_err);
+						count = 1;
+						break;
+					}
+				}
+				d = Time_F(STOP);
+				BIO_printf(bio_err, mr ? "+R6:%ld:%d:%.2f\n"
+				    : "%ld %d bit ECDSA verify in %.2fs\n",
+				    count, test_curves_bits[j], d);
+				ecdsa_results[j][1] = d / (double) count;
+			}
+
+			if (rsa_count <= 1) {
+				/* if longer than 10s, don't do any more */
+				for (j++; j < EC_NUM; j++)
+					ecdsa_doit[j] = 0;
+			}
+		}
+	}
+
+	for (j = 0; j < EC_NUM; j++) {
+		if (!ecdh_doit[j])
+			continue;
+		ecdh_a[j] = EC_KEY_new_by_curve_name(test_curves[j]);
+		ecdh_b[j] = EC_KEY_new_by_curve_name(test_curves[j]);
+		if ((ecdh_a[j] == NULL) || (ecdh_b[j] == NULL)) {
+			BIO_printf(bio_err, "ECDH failure.\n");
+			ERR_print_errors(bio_err);
+			rsa_count = 1;
+		} else {
+			/* generate two ECDH key pairs */
+			if (!EC_KEY_generate_key(ecdh_a[j]) ||
+			    !EC_KEY_generate_key(ecdh_b[j])) {
+				BIO_printf(bio_err, "ECDH key generation failure.\n");
+				ERR_print_errors(bio_err);
+				rsa_count = 1;
+			} else {
+				/*
+				 * If field size is not more than 24 octets,
+				 * then use SHA-1 hash of result; otherwise,
+				 * use result (see section 4.8 of
+				 * draft-ietf-tls-ecc-03.txt).
+				 */
+				int field_size, outlen;
+				void *(*kdf) (const void *in, size_t inlen, void *out, size_t * xoutlen);
+				field_size = EC_GROUP_get_degree(EC_KEY_get0_group(ecdh_a[j]));
+				if (field_size <= 24 * 8) {
+					outlen = KDF1_SHA1_len;
+					kdf = KDF1_SHA1;
+				} else {
+					outlen = (field_size + 7) / 8;
+					kdf = NULL;
+				}
+				secret_size_a = ECDH_compute_key(secret_a, outlen,
+				    EC_KEY_get0_public_key(ecdh_b[j]),
+				    ecdh_a[j], kdf);
+				secret_size_b = ECDH_compute_key(secret_b, outlen,
+				    EC_KEY_get0_public_key(ecdh_a[j]),
+				    ecdh_b[j], kdf);
+				if (secret_size_a != secret_size_b)
+					ecdh_checks = 0;
+				else
+					ecdh_checks = 1;
+
+				for (secret_idx = 0;
+				    (secret_idx < secret_size_a)
+				    && (ecdh_checks == 1);
+				    secret_idx++) {
+					if (secret_a[secret_idx] != secret_b[secret_idx])
+						ecdh_checks = 0;
+				}
+
+				if (ecdh_checks == 0) {
+					BIO_printf(bio_err,
+					    "ECDH computations don't match.\n");
+					ERR_print_errors(bio_err);
+					rsa_count = 1;
+				} else {
+					pkey_print_message("", "ecdh",
+					    ecdh_c[j][0],
+					    test_curves_bits[j],
+					    ECDH_SECONDS);
+					Time_F(START);
+					for (count = 0, run = 1;
+					     COND(ecdh_c[j][0]); count++) {
+						ECDH_compute_key(secret_a,
+						    outlen,
+						    EC_KEY_get0_public_key(ecdh_b[j]),
+						    ecdh_a[j], kdf);
+					}
+					d = Time_F(STOP);
+					BIO_printf(bio_err, mr
+					    ? "+R7:%ld:%d:%.2f\n"
+					    : "%ld %d-bit ECDH ops in %.2fs\n",
+					    count, test_curves_bits[j], d);
+					ecdh_results[j][0] = d / (double) count;
+					rsa_count = count;
+				}
+			}
+		}
+
+
+		if (rsa_count <= 1) {
+			/* if longer than 10s, don't do any more */
+			for (j++; j < EC_NUM; j++)
+				ecdh_doit[j] = 0;
+		}
+	}
+show_res:
+	if (!mr) {
+		fprintf(stdout, "%s\n", SSLeay_version(SSLEAY_VERSION));
+		fprintf(stdout, "%s\n", SSLeay_version(SSLEAY_BUILT_ON));
+		printf("options:");
+		printf("%s ", BN_options());
+#ifndef OPENSSL_NO_RC4
+		printf("%s ", RC4_options());
+#endif
+#ifndef OPENSSL_NO_DES
+		printf("%s ", DES_options());
+#endif
+#ifndef OPENSSL_NO_AES
+		printf("%s ", AES_options());
+#endif
+#ifndef OPENSSL_NO_IDEA
+		printf("%s ", idea_options());
+#endif
+#ifndef OPENSSL_NO_BF
+		printf("%s ", BF_options());
+#endif
+		fprintf(stdout, "\n%s\n", SSLeay_version(SSLEAY_CFLAGS));
+	}
+	if (pr_header) {
+		if (mr)
+			fprintf(stdout, "+H");
+		else {
+			fprintf(stdout, "The 'numbers' are in 1000s of bytes per second processed.\n");
+			fprintf(stdout, "type        ");
+		}
+		for (j = 0; j < SIZE_NUM; j++)
+			fprintf(stdout, mr ? ":%d" : "%7d bytes", lengths[j]);
+		fprintf(stdout, "\n");
+	}
+	for (k = 0; k < ALGOR_NUM; k++) {
+		if (!doit[k])
+			continue;
+		if (mr)
+			fprintf(stdout, "+F:%d:%s", k, names[k]);
+		else
+			fprintf(stdout, "%-13s", names[k]);
+		for (j = 0; j < SIZE_NUM; j++) {
+			if (results[k][j] > 10000 && !mr)
+				fprintf(stdout, " %11.2fk", results[k][j] / 1e3);
+			else
+				fprintf(stdout, mr ? ":%.2f" : " %11.2f ", results[k][j]);
+		}
+		fprintf(stdout, "\n");
+	}
+	j = 1;
+	for (k = 0; k < RSA_NUM; k++) {
+		if (!rsa_doit[k])
+			continue;
+		if (j && !mr) {
+			printf("%18ssign    verify    sign/s verify/s\n", " ");
+			j = 0;
+		}
+		if (mr)
+			fprintf(stdout, "+F2:%u:%u:%f:%f\n",
+			    k, rsa_bits[k], rsa_results[k][0],
+			    rsa_results[k][1]);
+		else
+			fprintf(stdout, "rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
+			    rsa_bits[k], rsa_results[k][0], rsa_results[k][1],
+			    1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1]);
+	}
+	j = 1;
+	for (k = 0; k < DSA_NUM; k++) {
+		if (!dsa_doit[k])
+			continue;
+		if (j && !mr) {
+			printf("%18ssign    verify    sign/s verify/s\n", " ");
+			j = 0;
+		}
+		if (mr)
+			fprintf(stdout, "+F3:%u:%u:%f:%f\n",
+			    k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]);
+		else
+			fprintf(stdout, "dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
+			    dsa_bits[k], dsa_results[k][0], dsa_results[k][1],
+			    1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1]);
+	}
+	j = 1;
+	for (k = 0; k < EC_NUM; k++) {
+		if (!ecdsa_doit[k])
+			continue;
+		if (j && !mr) {
+			printf("%30ssign    verify    sign/s verify/s\n", " ");
+			j = 0;
+		}
+		if (mr)
+			fprintf(stdout, "+F4:%u:%u:%f:%f\n",
+			    k, test_curves_bits[k],
+			    ecdsa_results[k][0], ecdsa_results[k][1]);
+		else
+			fprintf(stdout,
+			    "%4u bit ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
+			    test_curves_bits[k],
+			    test_curves_names[k],
+			    ecdsa_results[k][0], ecdsa_results[k][1],
+			    1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1]);
+	}
+
+
+	j = 1;
+	for (k = 0; k < EC_NUM; k++) {
+		if (!ecdh_doit[k])
+			continue;
+		if (j && !mr) {
+			printf("%30sop      op/s\n", " ");
+			j = 0;
+		}
+		if (mr)
+			fprintf(stdout, "+F5:%u:%u:%f:%f\n",
+			    k, test_curves_bits[k],
+			    ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
+
+		else
+			fprintf(stdout, "%4u bit ecdh (%s) %8.4fs %8.1f\n",
+			    test_curves_bits[k],
+			    test_curves_names[k],
+			    ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
+	}
+
+	mret = 0;
+
+end:
+	ERR_print_errors(bio_err);
+	free(buf);
+	free(buf2);
+	for (i = 0; i < RSA_NUM; i++)
+		if (rsa_key[i] != NULL)
+			RSA_free(rsa_key[i]);
+	for (i = 0; i < DSA_NUM; i++)
+		if (dsa_key[i] != NULL)
+			DSA_free(dsa_key[i]);
+
+	for (i = 0; i < EC_NUM; i++)
+		if (ecdsa[i] != NULL)
+			EC_KEY_free(ecdsa[i]);
+	for (i = 0; i < EC_NUM; i++) {
+		if (ecdh_a[i] != NULL)
+			EC_KEY_free(ecdh_a[i]);
+		if (ecdh_b[i] != NULL)
+			EC_KEY_free(ecdh_b[i]);
+	}
+
+
+	return (mret);
+}
+
+static void
+print_message(const char *s, long num, int length)
+{
+	BIO_printf(bio_err, mr ? "+DT:%s:%d:%d\n"
+	    : "Doing %s for %ds on %d size blocks: ", s, SECONDS, length);
+	(void) BIO_flush(bio_err);
+	alarm(SECONDS);
+}
+
+static void
+pkey_print_message(const char *str, const char *str2, long num,
+    int bits, int tm)
+{
+	BIO_printf(bio_err, mr ? "+DTP:%d:%s:%s:%d\n"
+	    : "Doing %d bit %s %s's for %ds: ", bits, str, str2, tm);
+	(void) BIO_flush(bio_err);
+	alarm(tm);
+}
+
+static void
+print_result(int alg, int run_no, int count, double time_used)
+{
+	BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n"
+	    : "%d %s's in %.2fs\n", count, names[alg], time_used);
+	results[alg][run_no] = ((double) count) / time_used * lengths[run_no];
+}
+
+static char *
+sstrsep(char **string, const char *delim)
+{
+	char isdelim[256];
+	char *token = *string;
+
+	if (**string == 0)
+		return NULL;
+
+	memset(isdelim, 0, sizeof isdelim);
+	isdelim[0] = 1;
+
+	while (*delim) {
+		isdelim[(unsigned char) (*delim)] = 1;
+		delim++;
+	}
+
+	while (!isdelim[(unsigned char) (**string)]) {
+		(*string)++;
+	}
+
+	if (**string) {
+		**string = 0;
+		(*string)++;
+	}
+	return token;
+}
+
+static int
+do_multi(int multi)
+{
+	int n;
+	int fd[2];
+	int *fds;
+	static char sep[] = ":";
+	const char *errstr = NULL;
+
+	fds = reallocarray(NULL, multi, sizeof *fds);
+	if (fds == NULL) {
+		fprintf(stderr, "reallocarray failure\n");
+		exit(1);
+	}
+	for (n = 0; n < multi; ++n) {
+		if (pipe(fd) == -1) {
+			fprintf(stderr, "pipe failure\n");
+			exit(1);
+		}
+		fflush(stdout);
+		fflush(stderr);
+		if (fork()) {
+			close(fd[1]);
+			fds[n] = fd[0];
+		} else {
+			close(fd[0]);
+			close(1);
+			if (dup(fd[1]) == -1) {
+				fprintf(stderr, "dup failed\n");
+				exit(1);
+			}
+			close(fd[1]);
+			mr = 1;
+			usertime = 0;
+			free(fds);
+			return 0;
+		}
+		printf("Forked child %d\n", n);
+	}
+
+	/* for now, assume the pipe is long enough to take all the output */
+	for (n = 0; n < multi; ++n) {
+		FILE *f;
+		char buf[1024];
+		char *p;
+
+		f = fdopen(fds[n], "r");
+		while (fgets(buf, sizeof buf, f)) {
+			p = strchr(buf, '\n');
+			if (p)
+				*p = '\0';
+			if (buf[0] != '+') {
+				fprintf(stderr, "Don't understand line '%s' from child %d\n",
+				    buf, n);
+				continue;
+			}
+			printf("Got: %s from %d\n", buf, n);
+			if (!strncmp(buf, "+F:", 3)) {
+				int alg;
+				int j;
+
+				p = buf + 3;
+				alg = strtonum(sstrsep(&p, sep),
+				    0, ALGOR_NUM - 1, &errstr);
+				sstrsep(&p, sep);
+				for (j = 0; j < SIZE_NUM; ++j)
+					results[alg][j] += atof(sstrsep(&p, sep));
+			} else if (!strncmp(buf, "+F2:", 4)) {
+				int k;
+				double d;
+
+				p = buf + 4;
+				k = strtonum(sstrsep(&p, sep),
+				    0, ALGOR_NUM - 1, &errstr);
+				sstrsep(&p, sep);
+
+				d = atof(sstrsep(&p, sep));
+				if (n)
+					rsa_results[k][0] = 1 / (1 / rsa_results[k][0] + 1 / d);
+				else
+					rsa_results[k][0] = d;
+
+				d = atof(sstrsep(&p, sep));
+				if (n)
+					rsa_results[k][1] = 1 / (1 / rsa_results[k][1] + 1 / d);
+				else
+					rsa_results[k][1] = d;
+			} else if (!strncmp(buf, "+F2:", 4)) {
+				int k;
+				double d;
+
+				p = buf + 4;
+				k = strtonum(sstrsep(&p, sep),
+				    0, ALGOR_NUM - 1, &errstr);
+				sstrsep(&p, sep);
+
+				d = atof(sstrsep(&p, sep));
+				if (n)
+					rsa_results[k][0] = 1 / (1 / rsa_results[k][0] + 1 / d);
+				else
+					rsa_results[k][0] = d;
+
+				d = atof(sstrsep(&p, sep));
+				if (n)
+					rsa_results[k][1] = 1 / (1 / rsa_results[k][1] + 1 / d);
+				else
+					rsa_results[k][1] = d;
+			}
+			else if (!strncmp(buf, "+F3:", 4)) {
+				int k;
+				double d;
+
+				p = buf + 4;
+				k = strtonum(sstrsep(&p, sep),
+				    0, ALGOR_NUM - 1, &errstr);
+				sstrsep(&p, sep);
+
+				d = atof(sstrsep(&p, sep));
+				if (n)
+					dsa_results[k][0] = 1 / (1 / dsa_results[k][0] + 1 / d);
+				else
+					dsa_results[k][0] = d;
+
+				d = atof(sstrsep(&p, sep));
+				if (n)
+					dsa_results[k][1] = 1 / (1 / dsa_results[k][1] + 1 / d);
+				else
+					dsa_results[k][1] = d;
+			}
+			else if (!strncmp(buf, "+F4:", 4)) {
+				int k;
+				double d;
+
+				p = buf + 4;
+				k = strtonum(sstrsep(&p, sep),
+				    0, ALGOR_NUM - 1, &errstr);
+				sstrsep(&p, sep);
+
+				d = atof(sstrsep(&p, sep));
+				if (n)
+					ecdsa_results[k][0] = 1 / (1 / ecdsa_results[k][0] + 1 / d);
+				else
+					ecdsa_results[k][0] = d;
+
+				d = atof(sstrsep(&p, sep));
+				if (n)
+					ecdsa_results[k][1] = 1 / (1 / ecdsa_results[k][1] + 1 / d);
+				else
+					ecdsa_results[k][1] = d;
+			}
+
+			else if (!strncmp(buf, "+F5:", 4)) {
+				int k;
+				double d;
+
+				p = buf + 4;
+				k = strtonum(sstrsep(&p, sep),
+				    0, ALGOR_NUM - 1, &errstr);
+				sstrsep(&p, sep);
+
+				d = atof(sstrsep(&p, sep));
+				if (n)
+					ecdh_results[k][0] = 1 / (1 / ecdh_results[k][0] + 1 / d);
+				else
+					ecdh_results[k][0] = d;
+
+			}
+
+			else if (!strncmp(buf, "+H:", 3)) {
+			} else
+				fprintf(stderr, "Unknown type '%s' from child %d\n", buf, n);
+		}
+
+		fclose(f);
+	}
+	free(fds);
+	return 1;
+}
+#endif
diff --git a/crypto/libressl/apps/openssl/spkac.c b/crypto/libressl/apps/openssl/spkac.c
new file mode 100644
index 0000000000..f735023b73
--- /dev/null
+++ b/crypto/libressl/apps/openssl/spkac.c
@@ -0,0 +1,313 @@
+/* $OpenBSD: spkac.c,v 1.7 2015/10/17 07:51:10 semarie Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999. Based on an original idea by Massimiliano Pala
+ * (madwolf@openca.org).
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "apps.h"
+#include "progs.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static struct {
+	char *challenge;
+	char *infile;
+	char *keyfile;
+	int noout;
+	char *outfile;
+	char *passargin;
+	int pubkey;
+	char *spkac;
+	char *spksect;
+	int verify;
+} spkac_config;
+
+static struct option spkac_options[] = {
+	{
+		.name = "challenge",
+		.argname = "string",
+		.desc = "Specify challenge string if SPKAC is generated",
+		.type = OPTION_ARG,
+		.opt.arg = &spkac_config.challenge,
+	},
+	{
+		.name = "in",
+		.argname = "file",
+		.desc = "Input file (default stdin)",
+		.type = OPTION_ARG,
+		.opt.arg = &spkac_config.infile,
+	},
+	{
+		.name = "key",
+		.argname = "file",
+		.desc = "Create SPKAC using private key file",
+		.type = OPTION_ARG,
+		.opt.arg = &spkac_config.keyfile,
+	},
+	{
+		.name = "noout",
+		.desc = "Do not print text version of SPKAC",
+		.type = OPTION_FLAG,
+		.opt.flag = &spkac_config.noout,
+	},
+	{
+		.name = "out",
+		.argname = "file",
+		.desc = "Output file (default stdout)",
+		.type = OPTION_ARG,
+		.opt.arg = &spkac_config.outfile,
+	},
+	{
+		.name = "passin",
+		.argname = "src",
+		.desc = "Input file passphrase source",
+		.type = OPTION_ARG,
+		.opt.arg = &spkac_config.passargin,
+	},
+	{
+		.name = "pubkey",
+		.desc = "Output public key of an SPKAC (not used if creating)",
+		.type = OPTION_FLAG,
+		.opt.flag = &spkac_config.pubkey,
+	},
+	{
+		.name = "spkac",
+		.argname = "name",
+		.desc = "SPKAC name (default \"SPKAC\")",
+		.type = OPTION_ARG,
+		.opt.arg = &spkac_config.spkac,
+	},
+	{
+		.name = "spksect",
+		.argname = "name",
+		.desc = "Name of the section containing SPKAC (default"
+		" \"default\")",
+		.type = OPTION_ARG,
+		.opt.arg = &spkac_config.spksect,
+	},
+	{
+		.name = "verify",
+		.desc = "Verify digital signature on supplied SPKAC",
+		.type = OPTION_FLAG,
+		.opt.flag = &spkac_config.verify,
+	},
+	{ NULL }
+};
+
+static void
+spkac_usage(void)
+{
+	fprintf(stderr,
+	    "usage: spkac [-challenge string] [-in file] "
+	    "[-key file] [-noout]\n"
+	    "    [-out file] [-passin src] [-pubkey] [-spkac name] "
+	    "[-spksect section]\n"
+	    "    [-verify]\n\n");
+	options_usage(spkac_options);
+}
+
+int
+spkac_main(int argc, char **argv)
+{
+	int i, ret = 1;
+	BIO *in = NULL, *out = NULL;
+	char *passin = NULL;
+	char *spkstr = NULL;
+	CONF *conf = NULL;
+	NETSCAPE_SPKI *spki = NULL;
+	EVP_PKEY *pkey = NULL;
+
+	if (single_execution) {
+		if (pledge("stdio rpath wpath cpath tty", NULL) == -1) {
+			perror("pledge");
+			exit(1);
+		}
+	}
+
+	memset(&spkac_config, 0, sizeof(spkac_config));
+	spkac_config.spkac = "SPKAC";
+	spkac_config.spksect = "default";
+
+	if (options_parse(argc, argv, spkac_options, NULL, NULL) != 0) {
+		spkac_usage();
+		return (1);
+	}
+
+	if (!app_passwd(bio_err, spkac_config.passargin, NULL, &passin, NULL)) {
+		BIO_printf(bio_err, "Error getting password\n");
+		goto end;
+	}
+
+	if (spkac_config.keyfile) {
+		pkey = load_key(bio_err,
+		    strcmp(spkac_config.keyfile, "-") ? spkac_config.keyfile
+		    : NULL, FORMAT_PEM, 1, passin, "private key");
+		if (!pkey) {
+			goto end;
+		}
+		spki = NETSCAPE_SPKI_new();
+		if (spkac_config.challenge)
+			ASN1_STRING_set(spki->spkac->challenge,
+			    spkac_config.challenge,
+			    (int) strlen(spkac_config.challenge));
+		NETSCAPE_SPKI_set_pubkey(spki, pkey);
+		NETSCAPE_SPKI_sign(spki, pkey, EVP_md5());
+		spkstr = NETSCAPE_SPKI_b64_encode(spki);
+		if (spkstr == NULL) {
+			BIO_printf(bio_err, "Error encoding SPKAC\n");
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+
+		if (spkac_config.outfile)
+			out = BIO_new_file(spkac_config.outfile, "w");
+		else
+			out = BIO_new_fp(stdout, BIO_NOCLOSE);
+
+		if (!out) {
+			BIO_printf(bio_err, "Error opening output file\n");
+			ERR_print_errors(bio_err);
+		} else {
+			BIO_printf(out, "SPKAC=%s\n", spkstr);
+			ret = 0;
+		}
+		free(spkstr);
+		goto end;
+	}
+	if (spkac_config.infile)
+		in = BIO_new_file(spkac_config.infile, "r");
+	else
+		in = BIO_new_fp(stdin, BIO_NOCLOSE);
+
+	if (!in) {
+		BIO_printf(bio_err, "Error opening input file\n");
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+	conf = NCONF_new(NULL);
+	i = NCONF_load_bio(conf, in, NULL);
+
+	if (!i) {
+		BIO_printf(bio_err, "Error parsing config file\n");
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+	spkstr = NCONF_get_string(conf, spkac_config.spksect,
+	    spkac_config.spkac);
+
+	if (!spkstr) {
+		BIO_printf(bio_err, "Can't find SPKAC called \"%s\"\n",
+		    spkac_config.spkac);
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+	spki = NETSCAPE_SPKI_b64_decode(spkstr, -1);
+
+	if (!spki) {
+		BIO_printf(bio_err, "Error loading SPKAC\n");
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+	if (spkac_config.outfile)
+		out = BIO_new_file(spkac_config.outfile, "w");
+	else {
+		out = BIO_new_fp(stdout, BIO_NOCLOSE);
+	}
+
+	if (!out) {
+		BIO_printf(bio_err, "Error opening output file\n");
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+	if (!spkac_config.noout)
+		NETSCAPE_SPKI_print(out, spki);
+	pkey = NETSCAPE_SPKI_get_pubkey(spki);
+	if (spkac_config.verify) {
+		i = NETSCAPE_SPKI_verify(spki, pkey);
+		if (i > 0)
+			BIO_printf(bio_err, "Signature OK\n");
+		else {
+			BIO_printf(bio_err, "Signature Failure\n");
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+	}
+	if (spkac_config.pubkey)
+		PEM_write_bio_PUBKEY(out, pkey);
+
+	ret = 0;
+
+end:
+	NCONF_free(conf);
+	NETSCAPE_SPKI_free(spki);
+	BIO_free(in);
+	BIO_free_all(out);
+	EVP_PKEY_free(pkey);
+	free(passin);
+
+	return (ret);
+}
diff --git a/crypto/libressl/apps/openssl/testdsa.h b/crypto/libressl/apps/openssl/testdsa.h
new file mode 100644
index 0000000000..0fcdac0f36
--- /dev/null
+++ b/crypto/libressl/apps/openssl/testdsa.h
@@ -0,0 +1,221 @@
+/* $OpenBSD: testdsa.h,v 1.7 2014/06/12 15:49:27 deraadt Exp $ */
+
+DSA *get_dsa512(void);
+DSA *get_dsa1024(void);
+DSA *get_dsa2048(void);
+
+static unsigned char dsa512_priv[] = {
+	0x65, 0xe5, 0xc7, 0x38, 0x60, 0x24, 0xb5, 0x89, 0xd4, 0x9c, 0xeb, 0x4c,
+	0x9c, 0x1d, 0x7a, 0x22, 0xbd, 0xd1, 0xc2, 0xd2,
+};
+static unsigned char dsa512_pub[] = {
+	0x00, 0x95, 0xa7, 0x0d, 0xec, 0x93, 0x68, 0xba, 0x5f, 0xf7, 0x5f, 0x07,
+	0xf2, 0x3b, 0xad, 0x6b, 0x01, 0xdc, 0xbe, 0xec, 0xde, 0x04, 0x7a, 0x3a,
+	0x27, 0xb3, 0xec, 0x49, 0xfd, 0x08, 0x43, 0x3d, 0x7e, 0xa8, 0x2c, 0x5e,
+	0x7b, 0xbb, 0xfc, 0xf4, 0x6e, 0xeb, 0x6c, 0xb0, 0x6e, 0xf8, 0x02, 0x12,
+	0x8c, 0x38, 0x5d, 0x83, 0x56, 0x7d, 0xee, 0x53, 0x05, 0x3e, 0x24, 0x84,
+	0xbe, 0xba, 0x0a, 0x6b, 0xc8,
+};
+static unsigned char dsa512_p[] = {
+	0x9D, 0x1B, 0x69, 0x8E, 0x26, 0xDB, 0xF2, 0x2B, 0x11, 0x70, 0x19, 0x86,
+	0xF6, 0x19, 0xC8, 0xF8, 0x19, 0xF2, 0x18, 0x53, 0x94, 0x46, 0x06, 0xD0,
+	0x62, 0x50, 0x33, 0x4B, 0x02, 0x3C, 0x52, 0x30, 0x03, 0x8B, 0x3B, 0xF9,
+	0x5F, 0xD1, 0x24, 0x06, 0x4F, 0x7B, 0x4C, 0xBA, 0xAA, 0x40, 0x9B, 0xFD,
+	0x96, 0xE4, 0x37, 0x33, 0xBB, 0x2D, 0x5A, 0xD7, 0x5A, 0x11, 0x40, 0x66,
+	0xA2, 0x76, 0x7D, 0x31,
+};
+static unsigned char dsa512_q[] = {
+	0xFB, 0x53, 0xEF, 0x50, 0xB4, 0x40, 0x92, 0x31, 0x56, 0x86, 0x53, 0x7A,
+	0xE8, 0x8B, 0x22, 0x9A, 0x49, 0xFB, 0x71, 0x8F,
+};
+static unsigned char dsa512_g[] = {
+	0x83, 0x3E, 0x88, 0xE5, 0xC5, 0x89, 0x73, 0xCE, 0x3B, 0x6C, 0x01, 0x49,
+	0xBF, 0xB3, 0xC7, 0x9F, 0x0A, 0xEA, 0x44, 0x91, 0xE5, 0x30, 0xAA, 0xD9,
+	0xBE, 0x5B, 0x5F, 0xB7, 0x10, 0xD7, 0x89, 0xB7, 0x8E, 0x74, 0xFB, 0xCF,
+	0x29, 0x1E, 0xEB, 0xA8, 0x2C, 0x54, 0x51, 0xB8, 0x10, 0xDE, 0xA0, 0xCE,
+	0x2F, 0xCC, 0x24, 0x6B, 0x90, 0x77, 0xDE, 0xA2, 0x68, 0xA6, 0x52, 0x12,
+	0xA2, 0x03, 0x9D, 0x20,
+};
+
+DSA *
+get_dsa512()
+{
+	DSA *dsa;
+
+	if ((dsa = DSA_new()) == NULL)
+		return (NULL);
+	dsa->priv_key = BN_bin2bn(dsa512_priv, sizeof(dsa512_priv), NULL);
+	dsa->pub_key = BN_bin2bn(dsa512_pub, sizeof(dsa512_pub), NULL);
+	dsa->p = BN_bin2bn(dsa512_p, sizeof(dsa512_p), NULL);
+	dsa->q = BN_bin2bn(dsa512_q, sizeof(dsa512_q), NULL);
+	dsa->g = BN_bin2bn(dsa512_g, sizeof(dsa512_g), NULL);
+	if ((dsa->priv_key == NULL) || (dsa->pub_key == NULL) ||
+	    (dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
+		return (NULL);
+	return (dsa);
+}
+
+static unsigned char dsa1024_priv[] = {
+	0x7d, 0x21, 0xda, 0xbb, 0x62, 0x15, 0x47, 0x36, 0x07, 0x67, 0x12, 0xe8,
+	0x8c, 0xaa, 0x1c, 0xcd, 0x38, 0x12, 0x61, 0x18,
+};
+static unsigned char dsa1024_pub[] = {
+	0x3c, 0x4e, 0x9c, 0x2a, 0x7f, 0x16, 0xc1, 0x25, 0xeb, 0xac, 0x78, 0x63,
+	0x90, 0x14, 0x8c, 0x8b, 0xf4, 0x68, 0x43, 0x3c, 0x2d, 0xee, 0x65, 0x50,
+	0x7d, 0x9c, 0x8f, 0x8c, 0x8a, 0x51, 0xd6, 0x11, 0x2b, 0x99, 0xaf, 0x1e,
+	0x90, 0x97, 0xb5, 0xd3, 0xa6, 0x20, 0x25, 0xd6, 0xfe, 0x43, 0x02, 0xd5,
+	0x91, 0x7d, 0xa7, 0x8c, 0xdb, 0xc9, 0x85, 0xa3, 0x36, 0x48, 0xf7, 0x68,
+	0xaa, 0x60, 0xb1, 0xf7, 0x05, 0x68, 0x3a, 0xa3, 0x3f, 0xd3, 0x19, 0x82,
+	0xd8, 0x82, 0x7a, 0x77, 0xfb, 0xef, 0xf4, 0x15, 0x0a, 0xeb, 0x06, 0x04,
+	0x7f, 0x53, 0x07, 0x0c, 0xbc, 0xcb, 0x2d, 0x83, 0xdb, 0x3e, 0xd1, 0x28,
+	0xa5, 0xa1, 0x31, 0xe0, 0x67, 0xfa, 0x50, 0xde, 0x9b, 0x07, 0x83, 0x7e,
+	0x2c, 0x0b, 0xc3, 0x13, 0x50, 0x61, 0xe5, 0xad, 0xbd, 0x36, 0xb8, 0x97,
+	0x4e, 0x40, 0x7d, 0xe8, 0x83, 0x0d, 0xbc, 0x4b
+};
+static unsigned char dsa1024_p[] = {
+	0xA7, 0x3F, 0x6E, 0x85, 0xBF, 0x41, 0x6A, 0x29, 0x7D, 0xF0, 0x9F, 0x47,
+	0x19, 0x30, 0x90, 0x9A, 0x09, 0x1D, 0xDA, 0x6A, 0x33, 0x1E, 0xC5, 0x3D,
+	0x86, 0x96, 0xB3, 0x15, 0xE0, 0x53, 0x2E, 0x8F, 0xE0, 0x59, 0x82, 0x73,
+	0x90, 0x3E, 0x75, 0x31, 0x99, 0x47, 0x7A, 0x52, 0xFB, 0x85, 0xE4, 0xD9,
+	0xA6, 0x7B, 0x38, 0x9B, 0x68, 0x8A, 0x84, 0x9B, 0x87, 0xC6, 0x1E, 0xB5,
+	0x7E, 0x86, 0x4B, 0x53, 0x5B, 0x59, 0xCF, 0x71, 0x65, 0x19, 0x88, 0x6E,
+	0xCE, 0x66, 0xAE, 0x6B, 0x88, 0x36, 0xFB, 0xEC, 0x28, 0xDC, 0xC2, 0xD7,
+	0xA5, 0xBB, 0xE5, 0x2C, 0x39, 0x26, 0x4B, 0xDA, 0x9A, 0x70, 0x18, 0x95,
+	0x37, 0x95, 0x10, 0x56, 0x23, 0xF6, 0x15, 0xED, 0xBA, 0x04, 0x5E, 0xDE,
+	0x39, 0x4F, 0xFD, 0xB7, 0x43, 0x1F, 0xB5, 0xA4, 0x65, 0x6F, 0xCD, 0x80,
+	0x11, 0xE4, 0x70, 0x95, 0x5B, 0x50, 0xCD, 0x49,
+};
+static unsigned char dsa1024_q[] = {
+	0xF7, 0x07, 0x31, 0xED, 0xFA, 0x6C, 0x06, 0x03, 0xD5, 0x85, 0x8A, 0x1C,
+	0xAC, 0x9C, 0x65, 0xE7, 0x50, 0x66, 0x65, 0x6F,
+};
+static unsigned char dsa1024_g[] = {
+	0x4D, 0xDF, 0x4C, 0x03, 0xA6, 0x91, 0x8A, 0xF5, 0x19, 0x6F, 0x50, 0x46,
+	0x25, 0x99, 0xE5, 0x68, 0x6F, 0x30, 0xE3, 0x69, 0xE1, 0xE5, 0xB3, 0x5D,
+	0x98, 0xBB, 0x28, 0x86, 0x48, 0xFC, 0xDE, 0x99, 0x04, 0x3F, 0x5F, 0x88,
+	0x0C, 0x9C, 0x73, 0x24, 0x0D, 0x20, 0x5D, 0xB9, 0x2A, 0x9A, 0x3F, 0x18,
+	0x96, 0x27, 0xE4, 0x62, 0x87, 0xC1, 0x7B, 0x74, 0x62, 0x53, 0xFC, 0x61,
+	0x27, 0xA8, 0x7A, 0x91, 0x09, 0x9D, 0xB6, 0xF1, 0x4D, 0x9C, 0x54, 0x0F,
+	0x58, 0x06, 0xEE, 0x49, 0x74, 0x07, 0xCE, 0x55, 0x7E, 0x23, 0xCE, 0x16,
+	0xF6, 0xCA, 0xDC, 0x5A, 0x61, 0x01, 0x7E, 0xC9, 0x71, 0xB5, 0x4D, 0xF6,
+	0xDC, 0x34, 0x29, 0x87, 0x68, 0xF6, 0x5E, 0x20, 0x93, 0xB3, 0xDB, 0xF5,
+	0xE4, 0x09, 0x6C, 0x41, 0x17, 0x95, 0x92, 0xEB, 0x01, 0xB5, 0x73, 0xA5,
+	0x6A, 0x7E, 0xD8, 0x32, 0xED, 0x0E, 0x02, 0xB8,
+};
+
+DSA *
+get_dsa1024()
+{
+	DSA *dsa;
+
+	if ((dsa = DSA_new()) == NULL)
+		return (NULL);
+	dsa->priv_key = BN_bin2bn(dsa1024_priv, sizeof(dsa1024_priv), NULL);
+	dsa->pub_key = BN_bin2bn(dsa1024_pub, sizeof(dsa1024_pub), NULL);
+	dsa->p = BN_bin2bn(dsa1024_p, sizeof(dsa1024_p), NULL);
+	dsa->q = BN_bin2bn(dsa1024_q, sizeof(dsa1024_q), NULL);
+	dsa->g = BN_bin2bn(dsa1024_g, sizeof(dsa1024_g), NULL);
+	if ((dsa->priv_key == NULL) || (dsa->pub_key == NULL) ||
+	    (dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
+		return (NULL);
+	return (dsa);
+}
+
+static unsigned char dsa2048_priv[] = {
+	0x32, 0x67, 0x92, 0xf6, 0xc4, 0xe2, 0xe2, 0xe8, 0xa0, 0x8b, 0x6b, 0x45,
+	0x0c, 0x8a, 0x76, 0xb0, 0xee, 0xcf, 0x91, 0xa7,
+};
+static unsigned char dsa2048_pub[] = {
+	0x17, 0x8f, 0xa8, 0x11, 0x84, 0x92, 0xec, 0x83, 0x47, 0xc7, 0x6a, 0xb0,
+	0x92, 0xaf, 0x5a, 0x20, 0x37, 0xa3, 0x64, 0x79, 0xd2, 0xd0, 0x3d, 0xcd,
+	0xe0, 0x61, 0x88, 0x88, 0x21, 0xcc, 0x74, 0x5d, 0xce, 0x4c, 0x51, 0x47,
+	0xf0, 0xc5, 0x5c, 0x4c, 0x82, 0x7a, 0xaf, 0x72, 0xad, 0xb9, 0xe0, 0x53,
+	0xf2, 0x78, 0xb7, 0xf0, 0xb5, 0x48, 0x7f, 0x8a, 0x3a, 0x18, 0xd1, 0x9f,
+	0x8b, 0x7d, 0xa5, 0x47, 0xb7, 0x95, 0xab, 0x98, 0xf8, 0x7b, 0x74, 0x50,
+	0x56, 0x8e, 0x57, 0xf0, 0xee, 0xf5, 0xb7, 0xba, 0xab, 0x85, 0x86, 0xf9,
+	0x2b, 0xef, 0x41, 0x56, 0xa0, 0xa4, 0x9f, 0xb7, 0x38, 0x00, 0x46, 0x0a,
+	0xa6, 0xf1, 0xfc, 0x1f, 0xd8, 0x4e, 0x85, 0x44, 0x92, 0x43, 0x21, 0x5d,
+	0x6e, 0xcc, 0xc2, 0xcb, 0x26, 0x31, 0x0d, 0x21, 0xc4, 0xbd, 0x8d, 0x24,
+	0xbc, 0xd9, 0x18, 0x19, 0xd7, 0xdc, 0xf1, 0xe7, 0x93, 0x50, 0x48, 0x03,
+	0x2c, 0xae, 0x2e, 0xe7, 0x49, 0x88, 0x5f, 0x93, 0x57, 0x27, 0x99, 0x36,
+	0xb4, 0x20, 0xab, 0xfc, 0xa7, 0x2b, 0xf2, 0xd9, 0x98, 0xd7, 0xd4, 0x34,
+	0x9d, 0x96, 0x50, 0x58, 0x9a, 0xea, 0x54, 0xf3, 0xee, 0xf5, 0x63, 0x14,
+	0xee, 0x85, 0x83, 0x74, 0x76, 0xe1, 0x52, 0x95, 0xc3, 0xf7, 0xeb, 0x04,
+	0x04, 0x7b, 0xa7, 0x28, 0x1b, 0xcc, 0xea, 0x4a, 0x4e, 0x84, 0xda, 0xd8,
+	0x9c, 0x79, 0xd8, 0x9b, 0x66, 0x89, 0x2f, 0xcf, 0xac, 0xd7, 0x79, 0xf9,
+	0xa9, 0xd8, 0x45, 0x13, 0x78, 0xb9, 0x00, 0x14, 0xc9, 0x7e, 0x22, 0x51,
+	0x86, 0x67, 0xb0, 0x9f, 0x26, 0x11, 0x23, 0xc8, 0x38, 0xd7, 0x70, 0x1d,
+	0x15, 0x8e, 0x4d, 0x4f, 0x95, 0x97, 0x40, 0xa1, 0xc2, 0x7e, 0x01, 0x18,
+	0x72, 0xf4, 0x10, 0xe6, 0x8d, 0x52, 0x16, 0x7f, 0xf2, 0xc9, 0xf8, 0x33,
+	0x8b, 0x33, 0xb7, 0xce,
+};
+static unsigned char dsa2048_p[] = {
+	0xA0, 0x25, 0xFA, 0xAD, 0xF4, 0x8E, 0xB9, 0xE5, 0x99, 0xF3, 0x5D, 0x6F,
+	0x4F, 0x83, 0x34, 0xE2, 0x7E, 0xCF, 0x6F, 0xBF, 0x30, 0xAF, 0x6F, 0x81,
+	0xEB, 0xF8, 0xC4, 0x13, 0xD9, 0xA0, 0x5D, 0x8B, 0x5C, 0x8E, 0xDC, 0xC2,
+	0x1D, 0x0B, 0x41, 0x32, 0xB0, 0x1F, 0xFE, 0xEF, 0x0C, 0xC2, 0xA2, 0x7E,
+	0x68, 0x5C, 0x28, 0x21, 0xE9, 0xF5, 0xB1, 0x58, 0x12, 0x63, 0x4C, 0x19,
+	0x4E, 0xFF, 0x02, 0x4B, 0x92, 0xED, 0xD2, 0x07, 0x11, 0x4D, 0x8C, 0x58,
+	0x16, 0x5C, 0x55, 0x8E, 0xAD, 0xA3, 0x67, 0x7D, 0xB9, 0x86, 0x6E, 0x0B,
+	0xE6, 0x54, 0x6F, 0x40, 0xAE, 0x0E, 0x67, 0x4C, 0xF9, 0x12, 0x5B, 0x3C,
+	0x08, 0x7A, 0xF7, 0xFC, 0x67, 0x86, 0x69, 0xE7, 0x0A, 0x94, 0x40, 0xBF,
+	0x8B, 0x76, 0xFE, 0x26, 0xD1, 0xF2, 0xA1, 0x1A, 0x84, 0xA1, 0x43, 0x56,
+	0x28, 0xBC, 0x9A, 0x5F, 0xD7, 0x3B, 0x69, 0x89, 0x8A, 0x36, 0x2C, 0x51,
+	0xDF, 0x12, 0x77, 0x2F, 0x57, 0x7B, 0xA0, 0xAA, 0xDD, 0x7F, 0xA1, 0x62,
+	0x3B, 0x40, 0x7B, 0x68, 0x1A, 0x8F, 0x0D, 0x38, 0xBB, 0x21, 0x5D, 0x18,
+	0xFC, 0x0F, 0x46, 0xF7, 0xA3, 0xB0, 0x1D, 0x23, 0xC3, 0xD2, 0xC7, 0x72,
+	0x51, 0x18, 0xDF, 0x46, 0x95, 0x79, 0xD9, 0xBD, 0xB5, 0x19, 0x02, 0x2C,
+	0x87, 0xDC, 0xE7, 0x57, 0x82, 0x7E, 0xF1, 0x8B, 0x06, 0x3D, 0x00, 0xA5,
+	0x7B, 0x6B, 0x26, 0x27, 0x91, 0x0F, 0x6A, 0x77, 0xE4, 0xD5, 0x04, 0xE4,
+	0x12, 0x2C, 0x42, 0xFF, 0xD2, 0x88, 0xBB, 0xD3, 0x92, 0xA0, 0xF9, 0xC8,
+	0x51, 0x64, 0x14, 0x5C, 0xD8, 0xF9, 0x6C, 0x47, 0x82, 0xB4, 0x1C, 0x7F,
+	0x09, 0xB8, 0xF0, 0x25, 0x83, 0x1D, 0x3F, 0x3F, 0x05, 0xB3, 0x21, 0x0A,
+	0x5D, 0xA7, 0xD8, 0x54, 0xC3, 0x65, 0x7D, 0xC3, 0xB0, 0x1D, 0xBF, 0xAE,
+	0xF8, 0x68, 0xCF, 0x9B,
+};
+static unsigned char dsa2048_q[] = {
+	0x97, 0xE7, 0x33, 0x4D, 0xD3, 0x94, 0x3E, 0x0B, 0xDB, 0x62, 0x74, 0xC6,
+	0xA1, 0x08, 0xDD, 0x19, 0xA3, 0x75, 0x17, 0x1B,
+};
+static unsigned char dsa2048_g[] = {
+	0x2C, 0x78, 0x16, 0x59, 0x34, 0x63, 0xF4, 0xF3, 0x92, 0xFC, 0xB5, 0xA5,
+	0x4F, 0x13, 0xDE, 0x2F, 0x1C, 0xA4, 0x3C, 0xAE, 0xAD, 0x38, 0x3F, 0x7E,
+	0x90, 0xBF, 0x96, 0xA6, 0xAE, 0x25, 0x90, 0x72, 0xF5, 0x8E, 0x80, 0x0C,
+	0x39, 0x1C, 0xD9, 0xEC, 0xBA, 0x90, 0x5B, 0x3A, 0xE8, 0x58, 0x6C, 0x9E,
+	0x30, 0x42, 0x37, 0x02, 0x31, 0x82, 0xBC, 0x6A, 0xDF, 0x6A, 0x09, 0x29,
+	0xE3, 0xC0, 0x46, 0xD1, 0xCB, 0x85, 0xEC, 0x0C, 0x30, 0x5E, 0xEA, 0xC8,
+	0x39, 0x8E, 0x22, 0x9F, 0x22, 0x10, 0xD2, 0x34, 0x61, 0x68, 0x37, 0x3D,
+	0x2E, 0x4A, 0x5B, 0x9A, 0xF5, 0xC1, 0x48, 0xC6, 0xF6, 0xDC, 0x63, 0x1A,
+	0xD3, 0x96, 0x64, 0xBA, 0x34, 0xC9, 0xD1, 0xA0, 0xD1, 0xAE, 0x6C, 0x2F,
+	0x48, 0x17, 0x93, 0x14, 0x43, 0xED, 0xF0, 0x21, 0x30, 0x19, 0xC3, 0x1B,
+	0x5F, 0xDE, 0xA3, 0xF0, 0x70, 0x78, 0x18, 0xE1, 0xA8, 0xE4, 0xEE, 0x2E,
+	0x00, 0xA5, 0xE4, 0xB3, 0x17, 0xC8, 0x0C, 0x7D, 0x6E, 0x42, 0xDC, 0xB7,
+	0x46, 0x00, 0x36, 0x4D, 0xD4, 0x46, 0xAA, 0x3D, 0x3C, 0x46, 0x89, 0x40,
+	0xBF, 0x1D, 0x84, 0x77, 0x0A, 0x75, 0xF3, 0x87, 0x1D, 0x08, 0x4C, 0xA6,
+	0xD1, 0xA9, 0x1C, 0x1E, 0x12, 0x1E, 0xE1, 0xC7, 0x30, 0x28, 0x76, 0xA5,
+	0x7F, 0x6C, 0x85, 0x96, 0x2B, 0x6F, 0xDB, 0x80, 0x66, 0x26, 0xAE, 0xF5,
+	0x93, 0xC7, 0x8E, 0xAE, 0x9A, 0xED, 0xE4, 0xCA, 0x04, 0xEA, 0x3B, 0x72,
+	0xEF, 0xDC, 0x87, 0xED, 0x0D, 0xA5, 0x4C, 0x4A, 0xDD, 0x71, 0x22, 0x64,
+	0x59, 0x69, 0x4E, 0x8E, 0xBF, 0x43, 0xDC, 0xAB, 0x8E, 0x66, 0xBB, 0x01,
+	0xB6, 0xF4, 0xE7, 0xFD, 0xD2, 0xAD, 0x9F, 0x36, 0xC1, 0xA0, 0x29, 0x99,
+	0xD1, 0x96, 0x70, 0x59, 0x06, 0x78, 0x35, 0xBD, 0x65, 0x55, 0x52, 0x9E,
+	0xF8, 0xB2, 0xE5, 0x38,
+};
+
+DSA *
+get_dsa2048()
+{
+	DSA *dsa;
+
+	if ((dsa = DSA_new()) == NULL)
+		return (NULL);
+	dsa->priv_key = BN_bin2bn(dsa2048_priv, sizeof(dsa2048_priv), NULL);
+	dsa->pub_key = BN_bin2bn(dsa2048_pub, sizeof(dsa2048_pub), NULL);
+	dsa->p = BN_bin2bn(dsa2048_p, sizeof(dsa2048_p), NULL);
+	dsa->q = BN_bin2bn(dsa2048_q, sizeof(dsa2048_q), NULL);
+	dsa->g = BN_bin2bn(dsa2048_g, sizeof(dsa2048_g), NULL);
+	if ((dsa->priv_key == NULL) || (dsa->pub_key == NULL) ||
+	    (dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
+		return (NULL);
+	return (dsa);
+}
diff --git a/crypto/libressl/apps/openssl/testrsa.h b/crypto/libressl/apps/openssl/testrsa.h
new file mode 100644
index 0000000000..66e13281f7
--- /dev/null
+++ b/crypto/libressl/apps/openssl/testrsa.h
@@ -0,0 +1,517 @@
+/* $OpenBSD: testrsa.h,v 1.4 2014/06/12 15:49:27 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+static unsigned char test512[] = {
+	0x30, 0x82, 0x01, 0x3a, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00,
+	0xd6, 0x33, 0xb9, 0xc8, 0xfb, 0x4f, 0x3c, 0x7d, 0xc0, 0x01,
+	0x86, 0xd0, 0xe7, 0xa0, 0x55, 0xf2, 0x95, 0x93, 0xcc, 0x4f,
+	0xb7, 0x5b, 0x67, 0x5b, 0x94, 0x68, 0xc9, 0x34, 0x15, 0xde,
+	0xa5, 0x2e, 0x1c, 0x33, 0xc2, 0x6e, 0xfc, 0x34, 0x5e, 0x71,
+	0x13, 0xb7, 0xd6, 0xee, 0xd8, 0xa5, 0x65, 0x05, 0x72, 0x87,
+	0xa8, 0xb0, 0x77, 0xfe, 0x57, 0xf5, 0xfc, 0x5f, 0x55, 0x83,
+	0x87, 0xdd, 0x57, 0x49, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
+	0x41, 0x00, 0xa7, 0xf7, 0x91, 0xc5, 0x0f, 0x84, 0x57, 0xdc,
+	0x07, 0xf7, 0x6a, 0x7f, 0x60, 0x52, 0xb3, 0x72, 0xf1, 0x66,
+	0x1f, 0x7d, 0x97, 0x3b, 0x9e, 0xb6, 0x0a, 0x8f, 0x8c, 0xcf,
+	0x42, 0x23, 0x00, 0x04, 0xd4, 0x28, 0x0e, 0x1c, 0x90, 0xc4,
+	0x11, 0x25, 0x25, 0xa5, 0x93, 0xa5, 0x2f, 0x70, 0x02, 0xdf,
+	0x81, 0x9c, 0x49, 0x03, 0xa0, 0xf8, 0x6d, 0x54, 0x2e, 0x26,
+	0xde, 0xaa, 0x85, 0x59, 0xa8, 0x31, 0x02, 0x21, 0x00, 0xeb,
+	0x47, 0xd7, 0x3b, 0xf6, 0xc3, 0xdd, 0x5a, 0x46, 0xc5, 0xb9,
+	0x2b, 0x9a, 0xa0, 0x09, 0x8f, 0xa6, 0xfb, 0xf3, 0x78, 0x7a,
+	0x33, 0x70, 0x9d, 0x0f, 0x42, 0x6b, 0x13, 0x68, 0x24, 0xd3,
+	0x15, 0x02, 0x21, 0x00, 0xe9, 0x10, 0xb0, 0xb3, 0x0d, 0xe2,
+	0x82, 0x68, 0x77, 0x8a, 0x6e, 0x7c, 0xda, 0xbc, 0x3e, 0x53,
+	0x83, 0xfb, 0xd6, 0x22, 0xe7, 0xb5, 0xae, 0x6e, 0x80, 0xda,
+	0x00, 0x55, 0x97, 0xc1, 0xd0, 0x65, 0x02, 0x20, 0x4c, 0xf8,
+	0x73, 0xb1, 0x6a, 0x49, 0x29, 0x61, 0x1f, 0x46, 0x10, 0x0d,
+	0xf3, 0xc7, 0xe7, 0x58, 0xd7, 0x88, 0x15, 0x5e, 0x94, 0x9b,
+	0xbf, 0x7b, 0xa2, 0x42, 0x58, 0x45, 0x41, 0x0c, 0xcb, 0x01,
+	0x02, 0x20, 0x12, 0x11, 0xba, 0x31, 0x57, 0x9d, 0x3d, 0x11,
+	0x0e, 0x5b, 0x8c, 0x2f, 0x5f, 0xe2, 0x02, 0x4f, 0x05, 0x47,
+	0x8c, 0x15, 0x8e, 0xb3, 0x56, 0x3f, 0xb8, 0xfb, 0xad, 0xd4,
+	0xf4, 0xfc, 0x10, 0xc5, 0x02, 0x20, 0x18, 0xa1, 0x29, 0x99,
+	0x5b, 0xd9, 0xc8, 0xd4, 0xfc, 0x49, 0x7a, 0x2a, 0x21, 0x2c,
+	0x49, 0xe4, 0x4f, 0xeb, 0xef, 0x51, 0xf1, 0xab, 0x6d, 0xfb,
+	0x4b, 0x14, 0xe9, 0x4b, 0x52, 0xb5, 0x82, 0x2c,
+};
+
+static unsigned char test1024[] = {
+	0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81,
+	0x00, 0xdc, 0x98, 0x43, 0xe8, 0x3d, 0x43, 0x5b, 0xe4, 0x05,
+	0xcd, 0xd0, 0xa9, 0x3e, 0xcb, 0x83, 0x75, 0xf6, 0xb5, 0xa5,
+	0x9f, 0x6b, 0xe9, 0x34, 0x41, 0x29, 0x18, 0xfa, 0x6a, 0x55,
+	0x4d, 0x70, 0xfc, 0xec, 0xae, 0x87, 0x38, 0x0a, 0x20, 0xa9,
+	0xc0, 0x45, 0x77, 0x6e, 0x57, 0x60, 0x57, 0xf4, 0xed, 0x96,
+	0x22, 0xcb, 0x8f, 0xe1, 0x33, 0x3a, 0x17, 0x1f, 0xed, 0x37,
+	0xa5, 0x6f, 0xeb, 0xa6, 0xbc, 0x12, 0x80, 0x1d, 0x53, 0xbd,
+	0x70, 0xeb, 0x21, 0x76, 0x3e, 0xc9, 0x2f, 0x1a, 0x45, 0x24,
+	0x82, 0xff, 0xcd, 0x59, 0x32, 0x06, 0x2e, 0x12, 0x3b, 0x23,
+	0x78, 0xed, 0x12, 0x3d, 0xe0, 0x8d, 0xf9, 0x67, 0x4f, 0x37,
+	0x4e, 0x47, 0x02, 0x4c, 0x2d, 0xc0, 0x4f, 0x1f, 0xb3, 0x94,
+	0xe1, 0x41, 0x2e, 0x2d, 0x90, 0x10, 0xfc, 0x82, 0x91, 0x8b,
+	0x0f, 0x22, 0xd4, 0xf2, 0xfc, 0x2c, 0xab, 0x53, 0x55, 0x02,
+	0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x2b, 0xcc, 0x3f,
+	0x8f, 0x58, 0xba, 0x8b, 0x00, 0x16, 0xf6, 0xea, 0x3a, 0xf0,
+	0x30, 0xd0, 0x05, 0x17, 0xda, 0xb0, 0xeb, 0x9a, 0x2d, 0x4f,
+	0x26, 0xb0, 0xd6, 0x38, 0xc1, 0xeb, 0xf5, 0xd8, 0x3d, 0x1f,
+	0x70, 0xf7, 0x7f, 0xf4, 0xe2, 0xcf, 0x51, 0x51, 0x79, 0x88,
+	0xfa, 0xe8, 0x32, 0x0e, 0x7b, 0x2d, 0x97, 0xf2, 0xfa, 0xba,
+	0x27, 0xc5, 0x9c, 0xd9, 0xc5, 0xeb, 0x8a, 0x79, 0x52, 0x3c,
+	0x64, 0x34, 0x7d, 0xc2, 0xcf, 0x28, 0xc7, 0x4e, 0xd5, 0x43,
+	0x0b, 0xd1, 0xa6, 0xca, 0x6d, 0x03, 0x2d, 0x72, 0x23, 0xbc,
+	0x6d, 0x05, 0xfa, 0x16, 0x09, 0x2f, 0x2e, 0x5c, 0xb6, 0xee,
+	0x74, 0xdd, 0xd2, 0x48, 0x8e, 0x36, 0x0c, 0x06, 0x3d, 0x4d,
+	0xe5, 0x10, 0x82, 0xeb, 0x6a, 0xf3, 0x4b, 0x9f, 0xd6, 0xed,
+	0x11, 0xb1, 0x6e, 0xec, 0xf4, 0xfe, 0x8e, 0x75, 0x94, 0x20,
+	0x2f, 0xcb, 0xac, 0x46, 0xf1, 0x02, 0x41, 0x00, 0xf9, 0x8c,
+	0xa3, 0x85, 0xb1, 0xdd, 0x29, 0xaf, 0x65, 0xc1, 0x33, 0xf3,
+	0x95, 0xc5, 0x52, 0x68, 0x0b, 0xd4, 0xf1, 0xe5, 0x0e, 0x02,
+	0x9f, 0x4f, 0xfa, 0x77, 0xdc, 0x46, 0x9e, 0xc7, 0xa6, 0xe4,
+	0x16, 0x29, 0xda, 0xb0, 0x07, 0xcf, 0x5b, 0xa9, 0x12, 0x8a,
+	0xdd, 0x63, 0x0a, 0xde, 0x2e, 0x8c, 0x66, 0x8b, 0x8c, 0xdc,
+	0x19, 0xa3, 0x7e, 0xf4, 0x3b, 0xd0, 0x1a, 0x8c, 0xa4, 0xc2,
+	0xe1, 0xd3, 0x02, 0x41, 0x00, 0xe2, 0x4c, 0x05, 0xf2, 0x04,
+	0x86, 0x4e, 0x61, 0x43, 0xdb, 0xb0, 0xb9, 0x96, 0x86, 0x52,
+	0x2c, 0xca, 0x8d, 0x7b, 0xab, 0x0b, 0x13, 0x0d, 0x7e, 0x38,
+	0x5b, 0xe2, 0x2e, 0x7b, 0x0e, 0xe7, 0x19, 0x99, 0x38, 0xe7,
+	0xf2, 0x21, 0xbd, 0x85, 0x85, 0xe3, 0xfd, 0x28, 0x77, 0x20,
+	0x31, 0x71, 0x2c, 0xd0, 0xff, 0xfb, 0x2e, 0xaf, 0x85, 0xb4,
+	0x86, 0xca, 0xf3, 0xbb, 0xca, 0xaa, 0x0f, 0x95, 0x37, 0x02,
+	0x40, 0x0e, 0x41, 0x9a, 0x95, 0xe8, 0xb3, 0x59, 0xce, 0x4b,
+	0x61, 0xde, 0x35, 0xec, 0x38, 0x79, 0x9c, 0xb8, 0x10, 0x52,
+	0x41, 0x63, 0xab, 0x82, 0xae, 0x6f, 0x00, 0xa9, 0xf4, 0xde,
+	0xdd, 0x49, 0x0b, 0x7e, 0xb8, 0xa5, 0x65, 0xa9, 0x0c, 0x8f,
+	0x8f, 0xf9, 0x1f, 0x35, 0xc6, 0x92, 0xb8, 0x5e, 0xb0, 0x66,
+	0xab, 0x52, 0x40, 0xc0, 0xb6, 0x36, 0x6a, 0x7d, 0x80, 0x46,
+	0x04, 0x02, 0xe5, 0x9f, 0x41, 0x02, 0x41, 0x00, 0xc0, 0xad,
+	0xcc, 0x4e, 0x21, 0xee, 0x1d, 0x24, 0x91, 0xfb, 0xa7, 0x80,
+	0x8d, 0x9a, 0xb6, 0xb3, 0x2e, 0x8f, 0xc2, 0xe1, 0x82, 0xdf,
+	0x69, 0x18, 0xb4, 0x71, 0xff, 0xa6, 0x65, 0xde, 0xed, 0x84,
+	0x8d, 0x42, 0xb7, 0xb3, 0x21, 0x69, 0x56, 0x1c, 0x07, 0x60,
+	0x51, 0x29, 0x04, 0xff, 0x34, 0x06, 0xdd, 0xb9, 0x67, 0x2c,
+	0x7c, 0x04, 0x93, 0x0e, 0x46, 0x15, 0xbb, 0x2a, 0xb7, 0x1b,
+	0xe7, 0x87, 0x02, 0x40, 0x78, 0xda, 0x5d, 0x07, 0x51, 0x0c,
+	0x16, 0x7a, 0x9f, 0x29, 0x20, 0x84, 0x0d, 0x42, 0xfa, 0xd7,
+	0x00, 0xd8, 0x77, 0x7e, 0xb0, 0xb0, 0x6b, 0xd6, 0x5b, 0x53,
+	0xb8, 0x9b, 0x7a, 0xcd, 0xc7, 0x2b, 0xb8, 0x6a, 0x63, 0xa9,
+	0xfb, 0x6f, 0xa4, 0x72, 0xbf, 0x4c, 0x5d, 0x00, 0x14, 0xba,
+	0xfa, 0x59, 0x88, 0xed, 0xe4, 0xe0, 0x8c, 0xa2, 0xec, 0x14,
+	0x7e, 0x2d, 0xe2, 0xf0, 0x46, 0x49, 0x95, 0x45,
+};
+
+static unsigned char test2048[] = {
+	0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01,
+	0x01, 0x00, 0xc0, 0xc0, 0xce, 0x3e, 0x3c, 0x53, 0x67, 0x3f,
+	0x4f, 0xc5, 0x2f, 0xa4, 0xc2, 0x5a, 0x2f, 0x58, 0xfd, 0x27,
+	0x52, 0x6a, 0xe8, 0xcf, 0x4a, 0x73, 0x47, 0x8d, 0x25, 0x0f,
+	0x5f, 0x03, 0x26, 0x78, 0xef, 0xf0, 0x22, 0x12, 0xd3, 0xde,
+	0x47, 0xb2, 0x1c, 0x0b, 0x38, 0x63, 0x1a, 0x6c, 0x85, 0x7a,
+	0x80, 0xc6, 0x8f, 0xa0, 0x41, 0xaf, 0x62, 0xc4, 0x67, 0x32,
+	0x88, 0xf8, 0xa6, 0x9c, 0xf5, 0x23, 0x1d, 0xe4, 0xac, 0x3f,
+	0x29, 0xf9, 0xec, 0xe1, 0x8b, 0x26, 0x03, 0x2c, 0xb2, 0xab,
+	0xf3, 0x7d, 0xb5, 0xca, 0x49, 0xc0, 0x8f, 0x1c, 0xdf, 0x33,
+	0x3a, 0x60, 0xda, 0x3c, 0xb0, 0x16, 0xf8, 0xa9, 0x12, 0x8f,
+	0x64, 0xac, 0x23, 0x0c, 0x69, 0x64, 0x97, 0x5d, 0x99, 0xd4,
+	0x09, 0x83, 0x9b, 0x61, 0xd3, 0xac, 0xf0, 0xde, 0xdd, 0x5e,
+	0x9f, 0x44, 0x94, 0xdb, 0x3a, 0x4d, 0x97, 0xe8, 0x52, 0x29,
+	0xf7, 0xdb, 0x94, 0x07, 0x45, 0x90, 0x78, 0x1e, 0x31, 0x0b,
+	0x80, 0xf7, 0x57, 0xad, 0x1c, 0x79, 0xc5, 0xcb, 0x32, 0xb0,
+	0xce, 0xcd, 0x74, 0xb3, 0xe2, 0x94, 0xc5, 0x78, 0x2f, 0x34,
+	0x1a, 0x45, 0xf7, 0x8c, 0x52, 0xa5, 0xbc, 0x8d, 0xec, 0xd1,
+	0x2f, 0x31, 0x3b, 0xf0, 0x49, 0x59, 0x5e, 0x88, 0x9d, 0x15,
+	0x92, 0x35, 0x32, 0xc1, 0xe7, 0x61, 0xec, 0x50, 0x48, 0x7c,
+	0xba, 0x05, 0xf9, 0xf8, 0xf8, 0xa7, 0x8c, 0x83, 0xe8, 0x66,
+	0x5b, 0xeb, 0xfe, 0xd8, 0x4f, 0xdd, 0x6d, 0x36, 0xc0, 0xb2,
+	0x90, 0x0f, 0xb8, 0x52, 0xf9, 0x04, 0x9b, 0x40, 0x2c, 0x27,
+	0xd6, 0x36, 0x8e, 0xc2, 0x1b, 0x44, 0xf3, 0x92, 0xd5, 0x15,
+	0x9e, 0x9a, 0xbc, 0xf3, 0x7d, 0x03, 0xd7, 0x02, 0x14, 0x20,
+	0xe9, 0x10, 0x92, 0xfd, 0xf9, 0xfc, 0x8f, 0xe5, 0x18, 0xe1,
+	0x95, 0xcc, 0x9e, 0x60, 0xa6, 0xfa, 0x38, 0x4d, 0x02, 0x03,
+	0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x00, 0xc3, 0xc3,
+	0x0d, 0xb4, 0x27, 0x90, 0x8d, 0x4b, 0xbf, 0xb8, 0x84, 0xaa,
+	0xd0, 0xb8, 0xc7, 0x5d, 0x99, 0xbe, 0x55, 0xf6, 0x3e, 0x7c,
+	0x49, 0x20, 0xcb, 0x8a, 0x8e, 0x19, 0x0e, 0x66, 0x24, 0xac,
+	0xaf, 0x03, 0x33, 0x97, 0xeb, 0x95, 0xd5, 0x3b, 0x0f, 0x40,
+	0x56, 0x04, 0x50, 0xd1, 0xe6, 0xbe, 0x84, 0x0b, 0x25, 0xd3,
+	0x9c, 0xe2, 0x83, 0x6c, 0xf5, 0x62, 0x5d, 0xba, 0x2b, 0x7d,
+	0x3d, 0x7a, 0x6c, 0xe1, 0xd2, 0x0e, 0x54, 0x93, 0x80, 0x01,
+	0x91, 0x51, 0x09, 0xe8, 0x5b, 0x8e, 0x47, 0xbd, 0x64, 0xe4,
+	0x0e, 0x03, 0x83, 0x55, 0xcf, 0x5a, 0x37, 0xf0, 0x25, 0xb5,
+	0x7d, 0x21, 0xd7, 0x69, 0xdf, 0x6f, 0xc2, 0xcf, 0x10, 0xc9,
+	0x8a, 0x40, 0x9f, 0x7a, 0x70, 0xc0, 0xe8, 0xe8, 0xc0, 0xe6,
+	0x9a, 0x15, 0x0a, 0x8d, 0x4e, 0x46, 0xcb, 0x7a, 0xdb, 0xb3,
+	0xcb, 0x83, 0x02, 0xc4, 0xf0, 0xab, 0xeb, 0x02, 0x01, 0x0e,
+	0x23, 0xfc, 0x1d, 0xc4, 0xbd, 0xd4, 0xaa, 0x5d, 0x31, 0x46,
+	0x99, 0xce, 0x9e, 0xf8, 0x04, 0x75, 0x10, 0x67, 0xc4, 0x53,
+	0x47, 0x44, 0xfa, 0xc2, 0x25, 0x73, 0x7e, 0xd0, 0x8e, 0x59,
+	0xd1, 0xb2, 0x5a, 0xf4, 0xc7, 0x18, 0x92, 0x2f, 0x39, 0xab,
+	0xcd, 0xa3, 0xb5, 0xc2, 0xb9, 0xc7, 0xb9, 0x1b, 0x9f, 0x48,
+	0xfa, 0x13, 0xc6, 0x98, 0x4d, 0xca, 0x84, 0x9c, 0x06, 0xca,
+	0xe7, 0x89, 0x01, 0x04, 0xc4, 0x6c, 0xfd, 0x29, 0x59, 0x35,
+	0xe7, 0xf3, 0xdd, 0xce, 0x64, 0x59, 0xbf, 0x21, 0x13, 0xa9,
+	0x9f, 0x0e, 0xc5, 0xff, 0xbd, 0x33, 0x00, 0xec, 0xac, 0x6b,
+	0x11, 0xef, 0x51, 0x5e, 0xad, 0x07, 0x15, 0xde, 0xb8, 0x5f,
+	0xc6, 0xb9, 0xa3, 0x22, 0x65, 0x46, 0x83, 0x14, 0xdf, 0xd0,
+	0xf1, 0x44, 0x8a, 0xe1, 0x9c, 0x23, 0x33, 0xb4, 0x97, 0x33,
+	0xe6, 0x6b, 0x81, 0x02, 0x81, 0x81, 0x00, 0xec, 0x12, 0xa7,
+	0x59, 0x74, 0x6a, 0xde, 0x3e, 0xad, 0xd8, 0x36, 0x80, 0x50,
+	0xa2, 0xd5, 0x21, 0x81, 0x07, 0xf1, 0xd0, 0x91, 0xf2, 0x6c,
+	0x12, 0x2f, 0x9d, 0x1a, 0x26, 0xf8, 0x30, 0x65, 0xdf, 0xe8,
+	0xc0, 0x9b, 0x6a, 0x30, 0x98, 0x82, 0x87, 0xec, 0xa2, 0x56,
+	0x87, 0x62, 0x6f, 0xe7, 0x9f, 0xf6, 0x56, 0xe6, 0x71, 0x8f,
+	0x49, 0x86, 0x93, 0x5a, 0x4d, 0x34, 0x58, 0xfe, 0xd9, 0x04,
+	0x13, 0xaf, 0x79, 0xb7, 0xad, 0x11, 0xd1, 0x30, 0x9a, 0x14,
+	0x06, 0xa0, 0xfa, 0xb7, 0x55, 0xdc, 0x6c, 0x5a, 0x4c, 0x2c,
+	0x59, 0x56, 0xf6, 0xe8, 0x9d, 0xaf, 0x0a, 0x78, 0x99, 0x06,
+	0x06, 0x9e, 0xe7, 0x9c, 0x51, 0x55, 0x43, 0xfc, 0x3b, 0x6c,
+	0x0b, 0xbf, 0x2d, 0x41, 0xa7, 0xaf, 0xb7, 0xe0, 0xe8, 0x28,
+	0x18, 0xb4, 0x13, 0xd1, 0xe6, 0x97, 0xd0, 0x9f, 0x6a, 0x80,
+	0xca, 0xdd, 0x1a, 0x7e, 0x15, 0x02, 0x81, 0x81, 0x00, 0xd1,
+	0x06, 0x0c, 0x1f, 0xe3, 0xd0, 0xab, 0xd6, 0xca, 0x7c, 0xbc,
+	0x7d, 0x13, 0x35, 0xce, 0x27, 0xcd, 0xd8, 0x49, 0x51, 0x63,
+	0x64, 0x0f, 0xca, 0x06, 0x12, 0xfc, 0x07, 0x3e, 0xaf, 0x61,
+	0x6d, 0xe2, 0x53, 0x39, 0x27, 0xae, 0xc3, 0x11, 0x9e, 0x94,
+	0x01, 0x4f, 0xe3, 0xf3, 0x67, 0xf9, 0x77, 0xf9, 0xe7, 0x95,
+	0x3a, 0x6f, 0xe2, 0x20, 0x73, 0x3e, 0xa4, 0x7a, 0x28, 0xd4,
+	0x61, 0x97, 0xf6, 0x17, 0xa0, 0x23, 0x10, 0x2b, 0xce, 0x84,
+	0x57, 0x7e, 0x25, 0x1f, 0xf4, 0xa8, 0x54, 0xd2, 0x65, 0x94,
+	0xcc, 0x95, 0x0a, 0xab, 0x30, 0xc1, 0x59, 0x1f, 0x61, 0x8e,
+	0xb9, 0x6b, 0xd7, 0x4e, 0xb9, 0x83, 0x43, 0x79, 0x85, 0x11,
+	0xbc, 0x0f, 0xae, 0x25, 0x20, 0x05, 0xbc, 0xd2, 0x48, 0xa1,
+	0x68, 0x09, 0x84, 0xf6, 0x12, 0x9a, 0x66, 0xb9, 0x2b, 0xbb,
+	0x76, 0x03, 0x17, 0x46, 0x4e, 0x97, 0x59, 0x02, 0x81, 0x80,
+	0x09, 0x4c, 0xfa, 0xd6, 0xe5, 0x65, 0x48, 0x78, 0x43, 0xb5,
+	0x1f, 0x00, 0x93, 0x2c, 0xb7, 0x24, 0xe8, 0xc6, 0x7d, 0x5a,
+	0x70, 0x45, 0x92, 0xc8, 0x6c, 0xa3, 0xcd, 0xe1, 0xf7, 0x29,
+	0x40, 0xfa, 0x3f, 0x5b, 0x47, 0x44, 0x39, 0xc1, 0xe8, 0x72,
+	0x9e, 0x7a, 0x0e, 0xda, 0xaa, 0xa0, 0x2a, 0x09, 0xfd, 0x54,
+	0x93, 0x23, 0xaa, 0x37, 0x85, 0x5b, 0xcc, 0xd4, 0xf9, 0xd8,
+	0xff, 0xc1, 0x61, 0x0d, 0xbd, 0x7e, 0x18, 0x24, 0x73, 0x6d,
+	0x40, 0x72, 0xf1, 0x93, 0x09, 0x48, 0x97, 0x6c, 0x84, 0x90,
+	0xa8, 0x46, 0x14, 0x01, 0x39, 0x11, 0xe5, 0x3c, 0x41, 0x27,
+	0x32, 0x75, 0x24, 0xed, 0xa1, 0xd9, 0x12, 0x29, 0x8a, 0x28,
+	0x71, 0x89, 0x8d, 0xca, 0x30, 0xb0, 0x01, 0xc4, 0x2f, 0x82,
+	0x19, 0x14, 0x4c, 0x70, 0x1c, 0xb8, 0x23, 0x2e, 0xe8, 0x90,
+	0x49, 0x97, 0x92, 0x97, 0x6b, 0x7a, 0x9d, 0xb9, 0x02, 0x81,
+	0x80, 0x0f, 0x0e, 0xa1, 0x76, 0xf6, 0xa1, 0x44, 0x8f, 0xaf,
+	0x7c, 0x76, 0xd3, 0x87, 0xbb, 0xbb, 0x83, 0x10, 0x88, 0x01,
+	0x18, 0x14, 0xd1, 0xd3, 0x75, 0x59, 0x24, 0xaa, 0xf5, 0x16,
+	0xa5, 0xe9, 0x9d, 0xd1, 0xcc, 0xee, 0xf4, 0x15, 0xd9, 0xc5,
+	0x7e, 0x27, 0xe9, 0x44, 0x49, 0x06, 0x72, 0xb9, 0xfc, 0xd3,
+	0x8a, 0xc4, 0x2c, 0x36, 0x7d, 0x12, 0x9b, 0x5a, 0xaa, 0xdc,
+	0x85, 0xee, 0x6e, 0xad, 0x54, 0xb3, 0xf4, 0xfc, 0x31, 0xa1,
+	0x06, 0x3a, 0x70, 0x57, 0x0c, 0xf3, 0x95, 0x5b, 0x3e, 0xe8,
+	0xfd, 0x1a, 0x4f, 0xf6, 0x78, 0x93, 0x46, 0x6a, 0xd7, 0x31,
+	0xb4, 0x84, 0x64, 0x85, 0x09, 0x38, 0x89, 0x92, 0x94, 0x1c,
+	0xbf, 0xe2, 0x3c, 0x2a, 0xe0, 0xff, 0x99, 0xa3, 0xf0, 0x2b,
+	0x31, 0xc2, 0x36, 0xcd, 0x60, 0xbf, 0x9d, 0x2d, 0x74, 0x32,
+	0xe8, 0x9c, 0x93, 0x6e, 0xbb, 0x91, 0x7b, 0xfd, 0xd9, 0x02,
+	0x81, 0x81, 0x00, 0xa2, 0x71, 0x25, 0x38, 0xeb, 0x2a, 0xe9,
+	0x37, 0xcd, 0xfe, 0x44, 0xce, 0x90, 0x3f, 0x52, 0x87, 0x84,
+	0x52, 0x1b, 0xae, 0x8d, 0x22, 0x94, 0xce, 0x38, 0xe6, 0x04,
+	0x88, 0x76, 0x85, 0x9a, 0xd3, 0x14, 0x09, 0xe5, 0x69, 0x9a,
+	0xff, 0x58, 0x92, 0x02, 0x6a, 0x7d, 0x7c, 0x1e, 0x2c, 0xfd,
+	0xa8, 0xca, 0x32, 0x14, 0x4f, 0x0d, 0x84, 0x0d, 0x37, 0x43,
+	0xbf, 0xe4, 0x5d, 0x12, 0xc8, 0x24, 0x91, 0x27, 0x8d, 0x46,
+	0xd9, 0x54, 0x53, 0xe7, 0x62, 0x71, 0xa8, 0x2b, 0x71, 0x41,
+	0x8d, 0x75, 0xf8, 0x3a, 0xa0, 0x61, 0x29, 0x46, 0xa6, 0xe5,
+	0x82, 0xfa, 0x3a, 0xd9, 0x08, 0xfa, 0xfc, 0x63, 0xfd, 0x6b,
+	0x30, 0xbc, 0xf4, 0x4e, 0x9e, 0x8c, 0x25, 0x0c, 0xb6, 0x55,
+	0xe7, 0x3c, 0xd4, 0x4e, 0x0b, 0xfd, 0x8b, 0xc3, 0x0e, 0x1d,
+	0x9c, 0x44, 0x57, 0x8f, 0x1f, 0x86, 0xf7, 0xd5, 0x1b, 0xe4,
+	0x95,
+};
+
+static unsigned char test4096[] = {
+	0x30, 0x82, 0x09, 0x29, 0x02, 0x01, 0x00, 0x02, 0x82, 0x02,
+	0x01, 0x00, 0xc0, 0x71, 0xac, 0x1a, 0x13, 0x88, 0x82, 0x43,
+	0x3b, 0x51, 0x57, 0x71, 0x8d, 0xb6, 0x2b, 0x82, 0x65, 0x21,
+	0x53, 0x5f, 0x28, 0x29, 0x4f, 0x8d, 0x7c, 0x8a, 0xb9, 0x44,
+	0xb3, 0x28, 0x41, 0x4f, 0xd3, 0xfa, 0x6a, 0xf8, 0xb9, 0x28,
+	0x50, 0x39, 0x67, 0x53, 0x2c, 0x3c, 0xd7, 0xcb, 0x96, 0x41,
+	0x40, 0x32, 0xbb, 0xeb, 0x70, 0xae, 0x1f, 0xb0, 0x65, 0xf7,
+	0x3a, 0xd9, 0x22, 0xfd, 0x10, 0xae, 0xbd, 0x02, 0xe2, 0xdd,
+	0xf3, 0xc2, 0x79, 0x3c, 0xc6, 0xfc, 0x75, 0xbb, 0xaf, 0x4e,
+	0x3a, 0x36, 0xc2, 0x4f, 0xea, 0x25, 0xdf, 0x13, 0x16, 0x4b,
+	0x20, 0xfe, 0x4b, 0x69, 0x16, 0xc4, 0x7f, 0x1a, 0x43, 0xa6,
+	0x17, 0x1b, 0xb9, 0x0a, 0xf3, 0x09, 0x86, 0x28, 0x89, 0xcf,
+	0x2c, 0xd0, 0xd4, 0x81, 0xaf, 0xc6, 0x6d, 0xe6, 0x21, 0x8d,
+	0xee, 0xef, 0xea, 0xdc, 0xb7, 0xc6, 0x3b, 0x63, 0x9f, 0x0e,
+	0xad, 0x89, 0x78, 0x23, 0x18, 0xbf, 0x70, 0x7e, 0x84, 0xe0,
+	0x37, 0xec, 0xdb, 0x8e, 0x9c, 0x3e, 0x6a, 0x19, 0xcc, 0x99,
+	0x72, 0xe6, 0xb5, 0x7d, 0x6d, 0xfa, 0xe5, 0xd3, 0xe4, 0x90,
+	0xb5, 0xb2, 0xb2, 0x12, 0x70, 0x4e, 0xca, 0xf8, 0x10, 0xf8,
+	0xa3, 0x14, 0xc2, 0x48, 0x19, 0xeb, 0x60, 0x99, 0xbb, 0x2a,
+	0x1f, 0xb1, 0x7a, 0xb1, 0x3d, 0x24, 0xfb, 0xa0, 0x29, 0xda,
+	0xbd, 0x1b, 0xd7, 0xa4, 0xbf, 0xef, 0x60, 0x2d, 0x22, 0xca,
+	0x65, 0x98, 0xf1, 0xc4, 0xe1, 0xc9, 0x02, 0x6b, 0x16, 0x28,
+	0x2f, 0xa1, 0xaa, 0x79, 0x00, 0xda, 0xdc, 0x7c, 0x43, 0xf7,
+	0x42, 0x3c, 0xa0, 0xef, 0x68, 0xf7, 0xdf, 0xb9, 0x69, 0xfb,
+	0x8e, 0x01, 0xed, 0x01, 0x42, 0xb5, 0x4e, 0x57, 0xa6, 0x26,
+	0xb8, 0xd0, 0x7b, 0x56, 0x6d, 0x03, 0xc6, 0x40, 0x8c, 0x8c,
+	0x2a, 0x55, 0xd7, 0x9c, 0x35, 0x00, 0x94, 0x93, 0xec, 0x03,
+	0xeb, 0x22, 0xef, 0x77, 0xbb, 0x79, 0x13, 0x3f, 0x15, 0xa1,
+	0x8f, 0xca, 0xdf, 0xfd, 0xd3, 0xb8, 0xe1, 0xd4, 0xcc, 0x09,
+	0x3f, 0x3c, 0x2c, 0xdb, 0xd1, 0x49, 0x7f, 0x38, 0x07, 0x83,
+	0x6d, 0xeb, 0x08, 0x66, 0xe9, 0x06, 0x44, 0x12, 0xac, 0x95,
+	0x22, 0x90, 0x23, 0x67, 0xd4, 0x08, 0xcc, 0xf4, 0xb7, 0xdc,
+	0xcc, 0x87, 0xd4, 0xac, 0x69, 0x35, 0x4c, 0xb5, 0x39, 0x36,
+	0xcd, 0xa4, 0xd2, 0x95, 0xca, 0x0d, 0xc5, 0xda, 0xc2, 0xc5,
+	0x22, 0x32, 0x28, 0x08, 0xe3, 0xd2, 0x8b, 0x38, 0x30, 0xdc,
+	0x8c, 0x75, 0x4f, 0x6a, 0xec, 0x7a, 0xac, 0x16, 0x3e, 0xa8,
+	0xd4, 0x6a, 0x45, 0xe1, 0xa8, 0x4f, 0x2e, 0x80, 0x34, 0xaa,
+	0x54, 0x1b, 0x02, 0x95, 0x7d, 0x8a, 0x6d, 0xcc, 0x79, 0xca,
+	0xf2, 0xa4, 0x2e, 0x8d, 0xfb, 0xfe, 0x15, 0x51, 0x10, 0x0e,
+	0x4d, 0x88, 0xb1, 0xc7, 0xf4, 0x79, 0xdb, 0xf0, 0xb4, 0x56,
+	0x44, 0x37, 0xca, 0x5a, 0xc1, 0x8c, 0x48, 0xac, 0xae, 0x48,
+	0x80, 0x83, 0x01, 0x3f, 0xde, 0xd9, 0xd3, 0x2c, 0x51, 0x46,
+	0xb1, 0x41, 0xb6, 0xc6, 0x91, 0x72, 0xf9, 0x83, 0x55, 0x1b,
+	0x8c, 0xba, 0xf3, 0x73, 0xe5, 0x2c, 0x74, 0x50, 0x3a, 0xbe,
+	0xc5, 0x2f, 0xa7, 0xb2, 0x6d, 0x8c, 0x9e, 0x13, 0x77, 0xa3,
+	0x13, 0xcd, 0x6d, 0x8c, 0x45, 0xe1, 0xfc, 0x0b, 0xb7, 0x69,
+	0xe9, 0x27, 0xbc, 0x65, 0xc3, 0xfa, 0x9b, 0xd0, 0xef, 0xfe,
+	0xe8, 0x1f, 0xb3, 0x5e, 0x34, 0xf4, 0x8c, 0xea, 0xfc, 0xd3,
+	0x81, 0xbf, 0x3d, 0x30, 0xb2, 0xb4, 0x01, 0xe8, 0x43, 0x0f,
+	0xba, 0x02, 0x23, 0x42, 0x76, 0x82, 0x31, 0x73, 0x91, 0xed,
+	0x07, 0x46, 0x61, 0x0d, 0x39, 0x83, 0x40, 0xce, 0x7a, 0xd4,
+	0xdb, 0x80, 0x2c, 0x1f, 0x0d, 0xd1, 0x34, 0xd4, 0x92, 0xe3,
+	0xd4, 0xf1, 0xc2, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
+	0x82, 0x02, 0x01, 0x00, 0x97, 0x6c, 0xda, 0x6e, 0xea, 0x4f,
+	0xcf, 0xaf, 0xf7, 0x4c, 0xd9, 0xf1, 0x90, 0x00, 0x77, 0xdb,
+	0xf2, 0x97, 0x76, 0x72, 0xb9, 0xb7, 0x47, 0xd1, 0x9c, 0xdd,
+	0xcb, 0x4a, 0x33, 0x6e, 0xc9, 0x75, 0x76, 0xe6, 0xe4, 0xa5,
+	0x31, 0x8c, 0x77, 0x13, 0xb4, 0x29, 0xcd, 0xf5, 0x52, 0x17,
+	0xef, 0xf3, 0x08, 0x00, 0xe3, 0xbd, 0x2e, 0xbc, 0xd4, 0x52,
+	0x88, 0xe9, 0x30, 0x75, 0x0b, 0x02, 0xf5, 0xcd, 0x89, 0x0c,
+	0x6c, 0x57, 0x19, 0x27, 0x3d, 0x1e, 0x85, 0xb4, 0xc1, 0x2f,
+	0x1d, 0x92, 0x00, 0x5c, 0x76, 0x29, 0x4b, 0xa4, 0xe1, 0x12,
+	0xb3, 0xc8, 0x09, 0xfe, 0x0e, 0x78, 0x72, 0x61, 0xcb, 0x61,
+	0x6f, 0x39, 0x91, 0x95, 0x4e, 0xd5, 0x3e, 0xc7, 0x8f, 0xb8,
+	0xf6, 0x36, 0xfe, 0x9c, 0x93, 0x9a, 0x38, 0x25, 0x7a, 0xf4,
+	0x4a, 0x12, 0xd4, 0xa0, 0x13, 0xbd, 0xf9, 0x1d, 0x12, 0x3e,
+	0x21, 0x39, 0xfb, 0x72, 0xe0, 0x05, 0x3d, 0xc3, 0xe5, 0x50,
+	0xa8, 0x5d, 0x85, 0xa3, 0xea, 0x5f, 0x1c, 0xb2, 0x3f, 0xea,
+	0x6d, 0x03, 0x91, 0x55, 0xd8, 0x19, 0x0a, 0x21, 0x12, 0x16,
+	0xd9, 0x12, 0xc4, 0xe6, 0x07, 0x18, 0x5b, 0x26, 0xa4, 0xae,
+	0xed, 0x2b, 0xb7, 0xa6, 0xed, 0xf8, 0xad, 0xec, 0x77, 0xe6,
+	0x7f, 0x4f, 0x76, 0x00, 0xc0, 0xfa, 0x15, 0x92, 0xb4, 0x2c,
+	0x22, 0xc2, 0xeb, 0x6a, 0xad, 0x14, 0x05, 0xb2, 0xe5, 0x8a,
+	0x9e, 0x85, 0x83, 0xcc, 0x04, 0xf1, 0x56, 0x78, 0x44, 0x5e,
+	0xde, 0xe0, 0x60, 0x1a, 0x65, 0x79, 0x31, 0x23, 0x05, 0xbb,
+	0x01, 0xff, 0xdd, 0x2e, 0xb7, 0xb3, 0xaa, 0x74, 0xe0, 0xa5,
+	0x94, 0xaf, 0x4b, 0xde, 0x58, 0x0f, 0x55, 0xde, 0x33, 0xf6,
+	0xe3, 0xd6, 0x34, 0x36, 0x57, 0xd6, 0x79, 0x91, 0x2e, 0xbe,
+	0x3b, 0xd9, 0x4e, 0xb6, 0x9d, 0x21, 0x5c, 0xd3, 0x48, 0x14,
+	0x7f, 0x4a, 0xc4, 0x60, 0xa9, 0x29, 0xf8, 0x53, 0x7f, 0x88,
+	0x11, 0x2d, 0xb5, 0xc5, 0x2d, 0x6f, 0xee, 0x85, 0x0b, 0xf7,
+	0x8d, 0x9a, 0xbe, 0xb0, 0x42, 0xf2, 0x2e, 0x71, 0xaf, 0x19,
+	0x31, 0x6d, 0xec, 0xcd, 0x6f, 0x2b, 0x23, 0xdf, 0xb4, 0x40,
+	0xaf, 0x2c, 0x0a, 0xc3, 0x1b, 0x7d, 0x7d, 0x03, 0x1d, 0x4b,
+	0xf3, 0xb5, 0xe0, 0x85, 0xd8, 0xdf, 0x91, 0x6b, 0x0a, 0x69,
+	0xf7, 0xf2, 0x69, 0x66, 0x5b, 0xf1, 0xcf, 0x46, 0x7d, 0xe9,
+	0x70, 0xfa, 0x6d, 0x7e, 0x75, 0x4e, 0xa9, 0x77, 0xe6, 0x8c,
+	0x02, 0xf7, 0x14, 0x4d, 0xa5, 0x41, 0x8f, 0x3f, 0xc1, 0x62,
+	0x1e, 0x71, 0x5e, 0x38, 0xb4, 0xd6, 0xe6, 0xe1, 0x4b, 0xc2,
+	0x2c, 0x30, 0x83, 0x81, 0x6f, 0x49, 0x2e, 0x96, 0xe6, 0xc9,
+	0x9a, 0xf7, 0x5d, 0x09, 0xa0, 0x55, 0x02, 0xa5, 0x3a, 0x25,
+	0x23, 0xd0, 0x92, 0xc3, 0xa3, 0xe3, 0x0e, 0x12, 0x2f, 0x4d,
+	0xef, 0xf3, 0x55, 0x5a, 0xbe, 0xe6, 0x19, 0x86, 0x31, 0xab,
+	0x75, 0x9a, 0xd3, 0xf0, 0x2c, 0xc5, 0x41, 0x92, 0xd9, 0x1f,
+	0x5f, 0x11, 0x8c, 0x75, 0x1c, 0x63, 0xd0, 0x02, 0x80, 0x2c,
+	0x68, 0xcb, 0x93, 0xfb, 0x51, 0x73, 0x49, 0xb4, 0x60, 0xda,
+	0xe2, 0x26, 0xaf, 0xa9, 0x46, 0x12, 0xb8, 0xec, 0x50, 0xdd,
+	0x12, 0x06, 0x5f, 0xce, 0x59, 0xe6, 0xf6, 0x1c, 0xe0, 0x54,
+	0x10, 0xad, 0xf6, 0xcd, 0x98, 0xcc, 0x0f, 0xfb, 0xcb, 0x41,
+	0x14, 0x9d, 0xed, 0xe4, 0xb4, 0x74, 0x5f, 0x09, 0x60, 0xc7,
+	0x12, 0xf6, 0x7b, 0x3c, 0x8f, 0xa7, 0x20, 0xbc, 0xe4, 0xb1,
+	0xef, 0xeb, 0xa4, 0x93, 0xc5, 0x06, 0xca, 0x9a, 0x27, 0x9d,
+	0x87, 0xf3, 0xde, 0xca, 0xe5, 0xe7, 0xf6, 0x1c, 0x01, 0x65,
+	0x5b, 0xfb, 0x19, 0x79, 0x6e, 0x08, 0x26, 0xc5, 0xc8, 0x28,
+	0x0e, 0xb6, 0x3b, 0x07, 0x08, 0xc1, 0x02, 0x82, 0x01, 0x01,
+	0x00, 0xe8, 0x1c, 0x73, 0xa6, 0xb8, 0xe0, 0x0e, 0x6d, 0x8d,
+	0x1b, 0xb9, 0x53, 0xed, 0x58, 0x94, 0xe6, 0x1d, 0x60, 0x14,
+	0x5c, 0x76, 0x43, 0xc4, 0x58, 0x19, 0xc4, 0x24, 0xe8, 0xbc,
+	0x1b, 0x3b, 0x0b, 0x13, 0x24, 0x45, 0x54, 0x0e, 0xcc, 0x37,
+	0xf0, 0xe0, 0x63, 0x7d, 0xc3, 0xf7, 0xfb, 0x81, 0x74, 0x81,
+	0xc4, 0x0f, 0x1a, 0x21, 0x48, 0xaf, 0xce, 0xc1, 0xc4, 0x94,
+	0x18, 0x06, 0x44, 0x8d, 0xd3, 0xd2, 0x22, 0x2d, 0x2d, 0x3e,
+	0x5a, 0x31, 0xdc, 0x95, 0x8e, 0xf4, 0x41, 0xfc, 0x58, 0xc9,
+	0x40, 0x92, 0x17, 0x5f, 0xe3, 0xda, 0xac, 0x9e, 0x3f, 0x1c,
+	0x2a, 0x6b, 0x58, 0x5f, 0x48, 0x78, 0x20, 0xb1, 0xaf, 0x24,
+	0x9b, 0x3c, 0x20, 0x8b, 0x93, 0x25, 0x9e, 0xe6, 0x6b, 0xbc,
+	0x13, 0x42, 0x14, 0x6c, 0x36, 0x31, 0xff, 0x7a, 0xd1, 0xc1,
+	0x1a, 0x26, 0x14, 0x7f, 0xa9, 0x76, 0xa7, 0x0c, 0xf8, 0xcc,
+	0xed, 0x07, 0x6a, 0xd2, 0xdf, 0x62, 0xee, 0x0a, 0x7c, 0x84,
+	0xcb, 0x49, 0x90, 0xb2, 0x03, 0x0d, 0xa2, 0x82, 0x06, 0x77,
+	0xf1, 0xcd, 0x67, 0xf2, 0x47, 0x21, 0x02, 0x3f, 0x43, 0x21,
+	0xf0, 0x46, 0x30, 0x62, 0x51, 0x72, 0xb1, 0xe7, 0x48, 0xc6,
+	0x67, 0x12, 0xcd, 0x9e, 0xd6, 0x15, 0xe5, 0x21, 0xed, 0xfa,
+	0x8f, 0x30, 0xa6, 0x41, 0xfe, 0xb6, 0xfa, 0x8f, 0x34, 0x14,
+	0x19, 0xe8, 0x11, 0xf7, 0xa5, 0x77, 0x3e, 0xb7, 0xf9, 0x39,
+	0x07, 0x8c, 0x67, 0x2a, 0xab, 0x7b, 0x08, 0xf8, 0xb0, 0x06,
+	0xa8, 0xea, 0x2f, 0x8f, 0xfa, 0xcc, 0xcc, 0x40, 0xce, 0xf3,
+	0x70, 0x4f, 0x3f, 0x7f, 0xe2, 0x0c, 0xea, 0x76, 0x4a, 0x35,
+	0x4e, 0x47, 0xad, 0x2b, 0xa7, 0x97, 0x5d, 0x74, 0x43, 0x97,
+	0x90, 0xd2, 0xfb, 0xd9, 0xf9, 0x96, 0x01, 0x33, 0x05, 0xed,
+	0x7b, 0x03, 0x05, 0xad, 0xf8, 0x49, 0x03, 0x02, 0x82, 0x01,
+	0x01, 0x00, 0xd4, 0x40, 0x17, 0x66, 0x10, 0x92, 0x95, 0xc8,
+	0xec, 0x62, 0xa9, 0x7a, 0xcb, 0x93, 0x8e, 0xe6, 0x53, 0xd4,
+	0x80, 0x48, 0x27, 0x4b, 0x41, 0xce, 0x61, 0xdf, 0xbf, 0x94,
+	0xa4, 0x3d, 0x71, 0x03, 0x0b, 0xed, 0x25, 0x71, 0x98, 0xa4,
+	0xd6, 0xd5, 0x4a, 0x57, 0xf5, 0x6c, 0x1b, 0xda, 0x21, 0x7d,
+	0x35, 0x45, 0xb3, 0xf3, 0x6a, 0xd9, 0xd3, 0x43, 0xe8, 0x5c,
+	0x54, 0x1c, 0x83, 0x1b, 0xb4, 0x5f, 0xf2, 0x97, 0x24, 0x2e,
+	0xdc, 0x40, 0xde, 0x92, 0x23, 0x59, 0x8e, 0xbc, 0xd2, 0xa1,
+	0xf2, 0xe0, 0x4c, 0xdd, 0x0b, 0xd1, 0xe7, 0xae, 0x65, 0xbc,
+	0xb5, 0xf5, 0x5b, 0x98, 0xe9, 0xd7, 0xc2, 0xb7, 0x0e, 0x55,
+	0x71, 0x0e, 0x3c, 0x0a, 0x24, 0x6b, 0xa6, 0xe6, 0x14, 0x61,
+	0x11, 0xfd, 0x33, 0x42, 0x99, 0x2b, 0x84, 0x77, 0x74, 0x92,
+	0x91, 0xf5, 0x79, 0x79, 0xcf, 0xad, 0x8e, 0x04, 0xef, 0x80,
+	0x1e, 0x57, 0xf4, 0x14, 0xf5, 0x35, 0x09, 0x74, 0xb2, 0x13,
+	0x71, 0x58, 0x6b, 0xea, 0x32, 0x5d, 0xf3, 0xd3, 0x76, 0x48,
+	0x39, 0x10, 0x23, 0x84, 0x9d, 0xbe, 0x92, 0x77, 0x4a, 0xed,
+	0x70, 0x3e, 0x1a, 0xa2, 0x6c, 0xb3, 0x81, 0x00, 0xc3, 0xc9,
+	0xe4, 0x52, 0xc8, 0x24, 0x88, 0x0c, 0x41, 0xad, 0x87, 0x5a,
+	0xea, 0xa3, 0x7a, 0x85, 0x1c, 0x5e, 0x31, 0x7f, 0xc3, 0x35,
+	0xc6, 0xfa, 0x10, 0xc8, 0x75, 0x10, 0xc4, 0x96, 0x99, 0xe7,
+	0xfe, 0x01, 0xb4, 0x74, 0xdb, 0xb4, 0x11, 0xc3, 0xc8, 0x8c,
+	0xf6, 0xf7, 0x3b, 0x66, 0x50, 0xfc, 0xdb, 0xeb, 0xca, 0x47,
+	0x85, 0x89, 0xe1, 0x65, 0xd9, 0x62, 0x34, 0x3c, 0x70, 0xd8,
+	0x2e, 0xb4, 0x2f, 0x65, 0x3c, 0x4a, 0xa6, 0x2a, 0xe7, 0xc7,
+	0xd8, 0x41, 0x8f, 0x8a, 0x43, 0xbf, 0x42, 0xf2, 0x4d, 0xbc,
+	0xfc, 0x9e, 0x27, 0x95, 0xfb, 0x75, 0xff, 0xab, 0x02, 0x82,
+	0x01, 0x00, 0x41, 0x2f, 0x44, 0x57, 0x6d, 0x12, 0x17, 0x5b,
+	0x32, 0xc6, 0xb7, 0x6c, 0x57, 0x7a, 0x8a, 0x0e, 0x79, 0xef,
+	0x72, 0xa8, 0x68, 0xda, 0x2d, 0x38, 0xe4, 0xbb, 0x8d, 0xf6,
+	0x02, 0x65, 0xcf, 0x56, 0x13, 0xe1, 0x1a, 0xcb, 0x39, 0x80,
+	0xa6, 0xb1, 0x32, 0x03, 0x1e, 0xdd, 0xbb, 0x35, 0xd9, 0xac,
+	0x43, 0x89, 0x31, 0x08, 0x90, 0x92, 0x5e, 0x35, 0x3d, 0x7b,
+	0x9c, 0x6f, 0x86, 0xcb, 0x17, 0xdd, 0x85, 0xe4, 0xed, 0x35,
+	0x08, 0x8e, 0xc1, 0xf4, 0x05, 0xd8, 0x68, 0xc6, 0x63, 0x3c,
+	0xf7, 0xff, 0xf7, 0x47, 0x33, 0x39, 0xc5, 0x3e, 0xb7, 0x0e,
+	0x58, 0x35, 0x9d, 0x81, 0xea, 0xf8, 0x6a, 0x2c, 0x1c, 0x5a,
+	0x68, 0x78, 0x64, 0x11, 0x6b, 0xc1, 0x3e, 0x4e, 0x7a, 0xbd,
+	0x84, 0xcb, 0x0f, 0xc2, 0xb6, 0x85, 0x1d, 0xd3, 0x76, 0xc5,
+	0x93, 0x6a, 0x69, 0x89, 0x56, 0x34, 0xdc, 0x4a, 0x9b, 0xbc,
+	0xff, 0xa8, 0x0d, 0x6e, 0x35, 0x9c, 0x60, 0xa7, 0x23, 0x30,
+	0xc7, 0x06, 0x64, 0x39, 0x8b, 0x94, 0x89, 0xee, 0xba, 0x7f,
+	0x60, 0x8d, 0xfa, 0xb6, 0x97, 0x76, 0xdc, 0x51, 0x4a, 0x3c,
+	0xeb, 0x3a, 0x14, 0x2c, 0x20, 0x60, 0x69, 0x4a, 0x86, 0xfe,
+	0x8c, 0x21, 0x84, 0x49, 0x54, 0xb3, 0x20, 0xe1, 0x01, 0x7f,
+	0x58, 0xdf, 0x7f, 0xb5, 0x21, 0x51, 0x8c, 0x47, 0x9f, 0x91,
+	0xeb, 0x97, 0x3e, 0xf2, 0x54, 0xcf, 0x16, 0x46, 0xf9, 0xd9,
+	0xb6, 0xe7, 0x64, 0xc9, 0xd0, 0x54, 0xea, 0x2f, 0xa1, 0xcf,
+	0xa5, 0x7f, 0x28, 0x8d, 0x84, 0xec, 0xd5, 0x39, 0x03, 0x76,
+	0x5b, 0x2d, 0x8e, 0x43, 0xf2, 0x01, 0x24, 0xc9, 0x6f, 0xc0,
+	0xf5, 0x69, 0x6f, 0x7d, 0xb5, 0x85, 0xd2, 0x5f, 0x7f, 0x78,
+	0x40, 0x07, 0x7f, 0x09, 0x15, 0xb5, 0x1f, 0x28, 0x65, 0x10,
+	0xe4, 0x19, 0xa8, 0xc6, 0x9e, 0x8d, 0xdc, 0xcb, 0x02, 0x82,
+	0x01, 0x00, 0x13, 0x01, 0xee, 0x56, 0x80, 0x93, 0x70, 0x00,
+	0x7f, 0x52, 0xd2, 0x94, 0xa1, 0x98, 0x84, 0x4a, 0x92, 0x25,
+	0x4c, 0x9b, 0xa9, 0x91, 0x2e, 0xc2, 0x79, 0xb7, 0x5c, 0xe3,
+	0xc5, 0xd5, 0x8e, 0xc2, 0x54, 0x16, 0x17, 0xad, 0x55, 0x9b,
+	0x25, 0x76, 0x12, 0x63, 0x50, 0x22, 0x2f, 0x58, 0x58, 0x79,
+	0x6b, 0x04, 0xe3, 0xf9, 0x9f, 0x8f, 0x04, 0x41, 0x67, 0x94,
+	0xa5, 0x1f, 0xac, 0x8a, 0x15, 0x9c, 0x26, 0x10, 0x6c, 0xf8,
+	0x19, 0x57, 0x61, 0xd7, 0x3a, 0x7d, 0x31, 0xb0, 0x2d, 0x38,
+	0xbd, 0x94, 0x62, 0xad, 0xc4, 0xfa, 0x36, 0x42, 0x42, 0xf0,
+	0x24, 0x67, 0x65, 0x9d, 0x8b, 0x0b, 0x7c, 0x6f, 0x82, 0x44,
+	0x1a, 0x8c, 0xc8, 0xc9, 0xab, 0xbb, 0x4c, 0x45, 0xfc, 0x7b,
+	0x38, 0xee, 0x30, 0xe1, 0xfc, 0xef, 0x8d, 0xbc, 0x58, 0xdf,
+	0x2b, 0x5d, 0x0d, 0x54, 0xe0, 0x49, 0x4d, 0x97, 0x99, 0x8f,
+	0x22, 0xa8, 0x83, 0xbe, 0x40, 0xbb, 0x50, 0x2e, 0x78, 0x28,
+	0x0f, 0x95, 0x78, 0x8c, 0x8f, 0x98, 0x24, 0x56, 0xc2, 0x97,
+	0xf3, 0x2c, 0x43, 0xd2, 0x03, 0x82, 0x66, 0x81, 0x72, 0x5f,
+	0x53, 0x16, 0xec, 0xb1, 0xb1, 0x04, 0x5e, 0x40, 0x20, 0x48,
+	0x7b, 0x3f, 0x02, 0x97, 0x6a, 0xeb, 0x96, 0x12, 0x21, 0x35,
+	0xfe, 0x1f, 0x47, 0xc0, 0x95, 0xea, 0xc5, 0x8a, 0x08, 0x84,
+	0x4f, 0x5e, 0x63, 0x94, 0x60, 0x0f, 0x71, 0x5b, 0x7f, 0x4a,
+	0xec, 0x4f, 0x60, 0xc6, 0xba, 0x4a, 0x24, 0xf1, 0x20, 0x8b,
+	0xa7, 0x2e, 0x3a, 0xce, 0x8d, 0xe0, 0x27, 0x1d, 0xb5, 0x8e,
+	0xb4, 0x21, 0xc5, 0xe2, 0xa6, 0x16, 0x0a, 0x51, 0x83, 0x55,
+	0x88, 0xd1, 0x30, 0x11, 0x63, 0xd5, 0xd7, 0x8d, 0xae, 0x16,
+	0x12, 0x82, 0xc4, 0x85, 0x00, 0x4e, 0x27, 0x83, 0xa5, 0x7c,
+	0x90, 0x2e, 0xe5, 0xa2, 0xa3, 0xd3, 0x4c, 0x63, 0x02, 0x82,
+	0x01, 0x01, 0x00, 0x86, 0x08, 0x98, 0x98, 0xa5, 0x00, 0x05,
+	0x39, 0x77, 0xd9, 0x66, 0xb3, 0xcf, 0xca, 0xa0, 0x71, 0xb3,
+	0x50, 0xce, 0x3d, 0xb1, 0x93, 0x95, 0x35, 0xc4, 0xd4, 0x2e,
+	0x90, 0xdf, 0x0f, 0xfc, 0x60, 0xc1, 0x94, 0x68, 0x61, 0x43,
+	0xca, 0x9a, 0x23, 0x4a, 0x1e, 0x45, 0x72, 0x99, 0xb5, 0x1e,
+	0x61, 0x8d, 0x77, 0x0f, 0xa0, 0xbb, 0xd7, 0x77, 0xb4, 0x2a,
+	0x15, 0x11, 0x88, 0x2d, 0xb3, 0x56, 0x61, 0x5e, 0x6a, 0xed,
+	0xa4, 0x46, 0x4a, 0x3f, 0x50, 0x11, 0xd6, 0xba, 0xb6, 0xd7,
+	0x95, 0x65, 0x53, 0xc3, 0xa1, 0x8f, 0xe0, 0xa3, 0xf5, 0x1c,
+	0xfd, 0xaf, 0x6e, 0x43, 0xd7, 0x17, 0xa7, 0xd3, 0x81, 0x1b,
+	0xa4, 0xdf, 0xe0, 0x97, 0x8a, 0x46, 0x03, 0xd3, 0x46, 0x0e,
+	0x83, 0x48, 0x4e, 0xd2, 0x02, 0xcb, 0xc0, 0xad, 0x79, 0x95,
+	0x8c, 0x96, 0xba, 0x40, 0x34, 0x11, 0x71, 0x5e, 0xe9, 0x11,
+	0xf9, 0xc5, 0x4a, 0x5e, 0x91, 0x9d, 0xf5, 0x92, 0x4f, 0xeb,
+	0xc6, 0x70, 0x02, 0x2d, 0x3d, 0x04, 0xaa, 0xe9, 0x3a, 0x8e,
+	0xd5, 0xa8, 0xad, 0xf7, 0xce, 0x0d, 0x16, 0xb2, 0xec, 0x0a,
+	0x9c, 0xf5, 0x94, 0x39, 0xb9, 0x8a, 0xfc, 0x1e, 0xf9, 0xcc,
+	0xf2, 0x5f, 0x21, 0x31, 0x74, 0x72, 0x6b, 0x64, 0xae, 0x35,
+	0x61, 0x8d, 0x0d, 0xcb, 0xe7, 0xda, 0x39, 0xca, 0xf3, 0x21,
+	0x66, 0x0b, 0x95, 0xd7, 0x0a, 0x7c, 0xca, 0xa1, 0xa9, 0x5a,
+	0xe8, 0xac, 0xe0, 0x71, 0x54, 0xaf, 0x28, 0xcf, 0xd5, 0x70,
+	0x89, 0xe0, 0xf3, 0x9e, 0x43, 0x6c, 0x8d, 0x7b, 0x99, 0x01,
+	0x68, 0x4d, 0xa1, 0x45, 0x46, 0x0c, 0x43, 0xbc, 0xcc, 0x2c,
+	0xdd, 0xc5, 0x46, 0xc8, 0x4e, 0x0e, 0xbe, 0xed, 0xb9, 0x26,
+	0xab, 0x2e, 0xdb, 0xeb, 0x8f, 0xff, 0xdb, 0xb0, 0xc6, 0x55,
+	0xaf, 0xf8, 0x2a, 0x91, 0x9d, 0x50, 0x44, 0x21, 0x17,
+};
diff --git a/crypto/libressl/apps/openssl/timeouts.h b/crypto/libressl/apps/openssl/timeouts.h
new file mode 100644
index 0000000000..2b3ae38bb4
--- /dev/null
+++ b/crypto/libressl/apps/openssl/timeouts.h
@@ -0,0 +1,67 @@
+/* $OpenBSD: timeouts.h,v 1.3 2014/06/12 15:49:27 deraadt Exp $ */
+/*
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef INCLUDED_TIMEOUTS_H
+#define INCLUDED_TIMEOUTS_H
+
+/* numbers in us */
+#define DGRAM_RCV_TIMEOUT         250000
+#define DGRAM_SND_TIMEOUT         250000
+
+#endif /* ! INCLUDED_TIMEOUTS_H */
diff --git a/crypto/libressl/apps/openssl/ts.c b/crypto/libressl/apps/openssl/ts.c
new file mode 100644
index 0000000000..ac09eb8e9f
--- /dev/null
+++ b/crypto/libressl/apps/openssl/ts.c
@@ -0,0 +1,1090 @@
+/* $OpenBSD: ts.c,v 1.12 2015/10/17 07:51:10 semarie Exp $ */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include "apps.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Length of the nonce of the request in bits (must be a multiple of 8). */
+#define	NONCE_LENGTH		64
+
+/* Macro definitions for the configuration file. */
+#define	ENV_OID_FILE		"oid_file"
+
+/* Local function declarations. */
+
+static ASN1_OBJECT *txt2obj(const char *oid);
+static CONF *load_config_file(const char *configfile);
+
+/* Query related functions. */
+static int query_command(const char *data, char *digest,
+    const EVP_MD * md, const char *policy, int no_nonce,
+    int cert, const char *in, const char *out, int text);
+static BIO *BIO_open_with_default(const char *file, const char *mode,
+    FILE * default_fp);
+static TS_REQ *create_query(BIO * data_bio, char *digest, const EVP_MD * md,
+    const char *policy, int no_nonce, int cert);
+static int create_digest(BIO * input, char *digest,
+    const EVP_MD * md, unsigned char **md_value);
+static ASN1_INTEGER *create_nonce(int bits);
+
+/* Reply related functions. */
+static int reply_command(CONF * conf, char *section,
+    char *queryfile, char *passin, char *inkey,
+    char *signer, char *chain, const char *policy,
+    char *in, int token_in, char *out, int token_out,
+    int text);
+static TS_RESP *read_PKCS7(BIO * in_bio);
+static TS_RESP *create_response(CONF * conf, const char *section,
+    char *queryfile, char *passin, char *inkey,
+    char *signer, char *chain, const char *policy);
+static ASN1_INTEGER *serial_cb(TS_RESP_CTX * ctx, void *data);
+static ASN1_INTEGER *next_serial(const char *serialfile);
+static int save_ts_serial(const char *serialfile, ASN1_INTEGER * serial);
+
+/* Verify related functions. */
+static int verify_command(char *data, char *digest, char *queryfile,
+    char *in, int token_in,
+    char *ca_path, char *ca_file, char *untrusted);
+static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest,
+    char *queryfile,
+    char *ca_path, char *ca_file,
+    char *untrusted);
+static X509_STORE *create_cert_store(char *ca_path, char *ca_file);
+static int verify_cb(int ok, X509_STORE_CTX * ctx);
+
+int
+ts_main(int argc, char **argv)
+{
+	int ret = 1;
+	char *configfile = NULL;
+	char *section = NULL;
+	CONF *conf = NULL;
+	enum mode {
+		CMD_NONE, CMD_QUERY, CMD_REPLY, CMD_VERIFY
+	} mode = CMD_NONE;
+	char *data = NULL;
+	char *digest = NULL;
+	const EVP_MD *md = NULL;
+	char *policy = NULL;
+	int no_nonce = 0;
+	int cert = 0;
+	char *in = NULL;
+	char *out = NULL;
+	int text = 0;
+	char *queryfile = NULL;
+	char *passin = NULL;	/* Password source. */
+	char *password = NULL;	/* Password itself. */
+	char *inkey = NULL;
+	char *signer = NULL;
+	char *chain = NULL;
+	char *ca_path = NULL;
+	char *ca_file = NULL;
+	char *untrusted = NULL;
+	/* Input is ContentInfo instead of TimeStampResp. */
+	int token_in = 0;
+	/* Output is ContentInfo instead of TimeStampResp. */
+	int token_out = 0;
+
+	if (single_execution) {
+		if (pledge("stdio rpath wpath cpath tty", NULL) == -1) {
+			perror("pledge");
+			exit(1);
+		}
+	}
+
+	for (argc--, argv++; argc > 0; argc--, argv++) {
+		if (strcmp(*argv, "-config") == 0) {
+			if (argc-- < 1)
+				goto usage;
+			configfile = *++argv;
+		} else if (strcmp(*argv, "-section") == 0) {
+			if (argc-- < 1)
+				goto usage;
+			section = *++argv;
+		} else if (strcmp(*argv, "-query") == 0) {
+			if (mode != CMD_NONE)
+				goto usage;
+			mode = CMD_QUERY;
+		} else if (strcmp(*argv, "-data") == 0) {
+			if (argc-- < 1)
+				goto usage;
+			data = *++argv;
+		} else if (strcmp(*argv, "-digest") == 0) {
+			if (argc-- < 1)
+				goto usage;
+			digest = *++argv;
+		} else if (strcmp(*argv, "-policy") == 0) {
+			if (argc-- < 1)
+				goto usage;
+			policy = *++argv;
+		} else if (strcmp(*argv, "-no_nonce") == 0) {
+			no_nonce = 1;
+		} else if (strcmp(*argv, "-cert") == 0) {
+			cert = 1;
+		} else if (strcmp(*argv, "-in") == 0) {
+			if (argc-- < 1)
+				goto usage;
+			in = *++argv;
+		} else if (strcmp(*argv, "-token_in") == 0) {
+			token_in = 1;
+		} else if (strcmp(*argv, "-out") == 0) {
+			if (argc-- < 1)
+				goto usage;
+			out = *++argv;
+		} else if (strcmp(*argv, "-token_out") == 0) {
+			token_out = 1;
+		} else if (strcmp(*argv, "-text") == 0) {
+			text = 1;
+		} else if (strcmp(*argv, "-reply") == 0) {
+			if (mode != CMD_NONE)
+				goto usage;
+			mode = CMD_REPLY;
+		} else if (strcmp(*argv, "-queryfile") == 0) {
+			if (argc-- < 1)
+				goto usage;
+			queryfile = *++argv;
+		} else if (strcmp(*argv, "-passin") == 0) {
+			if (argc-- < 1)
+				goto usage;
+			passin = *++argv;
+		} else if (strcmp(*argv, "-inkey") == 0) {
+			if (argc-- < 1)
+				goto usage;
+			inkey = *++argv;
+		} else if (strcmp(*argv, "-signer") == 0) {
+			if (argc-- < 1)
+				goto usage;
+			signer = *++argv;
+		} else if (strcmp(*argv, "-chain") == 0) {
+			if (argc-- < 1)
+				goto usage;
+			chain = *++argv;
+		} else if (strcmp(*argv, "-verify") == 0) {
+			if (mode != CMD_NONE)
+				goto usage;
+			mode = CMD_VERIFY;
+		} else if (strcmp(*argv, "-CApath") == 0) {
+			if (argc-- < 1)
+				goto usage;
+			ca_path = *++argv;
+		} else if (strcmp(*argv, "-CAfile") == 0) {
+			if (argc-- < 1)
+				goto usage;
+			ca_file = *++argv;
+		} else if (strcmp(*argv, "-untrusted") == 0) {
+			if (argc-- < 1)
+				goto usage;
+			untrusted = *++argv;
+		} else if ((md = EVP_get_digestbyname(*argv + 1)) != NULL) {
+			/* empty. */
+		} else
+			goto usage;
+	}
+
+	/* Get the password if required. */
+	if (mode == CMD_REPLY && passin &&
+	    !app_passwd(bio_err, passin, NULL, &password, NULL)) {
+		BIO_printf(bio_err, "Error getting password.\n");
+		goto cleanup;
+	}
+	/*
+	 * Check consistency of parameters and execute the appropriate
+	 * function.
+	 */
+	switch (mode) {
+	case CMD_NONE:
+		goto usage;
+	case CMD_QUERY:
+		/*
+		 * Data file and message imprint cannot be specified at the
+		 * same time.
+		 */
+		ret = data != NULL && digest != NULL;
+		if (ret)
+			goto usage;
+		/* Load the config file for possible policy OIDs. */
+		conf = load_config_file(configfile);
+		ret = !query_command(data, digest, md, policy, no_nonce, cert,
+		    in, out, text);
+		break;
+	case CMD_REPLY:
+		conf = load_config_file(configfile);
+		if (in == NULL) {
+			ret = !(queryfile != NULL && conf != NULL && !token_in);
+			if (ret)
+				goto usage;
+		} else {
+			/* 'in' and 'queryfile' are exclusive. */
+			ret = !(queryfile == NULL);
+			if (ret)
+				goto usage;
+		}
+
+		ret = !reply_command(conf, section, queryfile,
+		    password, inkey, signer, chain, policy,
+		    in, token_in, out, token_out, text);
+		break;
+	case CMD_VERIFY:
+		ret = !(((queryfile && !data && !digest) ||
+		    (!queryfile && data && !digest) ||
+		    (!queryfile && !data && digest)) && in != NULL);
+		if (ret)
+			goto usage;
+
+		ret = !verify_command(data, digest, queryfile, in, token_in,
+		    ca_path, ca_file, untrusted);
+	}
+
+	goto cleanup;
+
+usage:
+	BIO_printf(bio_err, "usage:\n"
+	    "ts -query [-config configfile] "
+	    "[-data file_to_hash] [-digest digest_bytes]"
+	    "[-md4|-md5|-sha1|-ripemd160] "
+	    "[-policy object_id] [-no_nonce] [-cert] "
+	    "[-in request.tsq] [-out request.tsq] [-text]\n");
+	BIO_printf(bio_err, "or\n"
+	    "ts -reply [-config configfile] [-section tsa_section] "
+	    "[-queryfile request.tsq] [-passin password] "
+	    "[-signer tsa_cert.pem] [-inkey private_key.pem] "
+	    "[-chain certs_file.pem] [-policy object_id] "
+	    "[-in response.tsr] [-token_in] "
+	    "[-out response.tsr] [-token_out] [-text]\n");
+	BIO_printf(bio_err, "or\n"
+	    "ts -verify [-data file_to_hash] [-digest digest_bytes] "
+	    "[-queryfile request.tsq] "
+	    "-in response.tsr [-token_in] "
+	    "-CApath ca_path -CAfile ca_file.pem "
+	    "-untrusted cert_file.pem\n");
+
+cleanup:
+	/* Clean up. */
+	NCONF_free(conf);
+	free(password);
+	OBJ_cleanup();
+
+	return (ret);
+}
+
+/*
+ * Configuration file-related function definitions.
+ */
+
+static ASN1_OBJECT *
+txt2obj(const char *oid)
+{
+	ASN1_OBJECT *oid_obj = NULL;
+
+	if (!(oid_obj = OBJ_txt2obj(oid, 0)))
+		BIO_printf(bio_err, "cannot convert %s to OID\n", oid);
+
+	return oid_obj;
+}
+
+static CONF *
+load_config_file(const char *configfile)
+{
+	CONF *conf = NULL;
+	long errorline = -1;
+
+	if (!configfile)
+		configfile = getenv("OPENSSL_CONF");
+
+	if (configfile &&
+	    (!(conf = NCONF_new(NULL)) ||
+	    NCONF_load(conf, configfile, &errorline) <= 0)) {
+		if (errorline <= 0)
+			BIO_printf(bio_err, "error loading the config file "
+			    "'%s'\n", configfile);
+		else
+			BIO_printf(bio_err, "error on line %ld of config file "
+			    "'%s'\n", errorline, configfile);
+	}
+	if (conf != NULL) {
+		const char *p;
+
+		BIO_printf(bio_err, "Using configuration from %s\n",
+		    configfile);
+		p = NCONF_get_string(conf, NULL, ENV_OID_FILE);
+		if (p != NULL) {
+			BIO *oid_bio = BIO_new_file(p, "r");
+			if (!oid_bio)
+				ERR_print_errors(bio_err);
+			else {
+				OBJ_create_objects(oid_bio);
+				BIO_free_all(oid_bio);
+			}
+		} else
+			ERR_clear_error();
+		if (!add_oid_section(bio_err, conf))
+			ERR_print_errors(bio_err);
+	}
+	return conf;
+}
+
+/*
+ * Query-related method definitions.
+ */
+
+static int
+query_command(const char *data, char *digest, const EVP_MD * md,
+    const char *policy, int no_nonce, int cert, const char *in,
+    const char *out, int text)
+{
+	int ret = 0;
+	TS_REQ *query = NULL;
+	BIO *in_bio = NULL;
+	BIO *data_bio = NULL;
+	BIO *out_bio = NULL;
+
+	/* Build query object either from file or from scratch. */
+	if (in != NULL) {
+		if ((in_bio = BIO_new_file(in, "rb")) == NULL)
+			goto end;
+		query = d2i_TS_REQ_bio(in_bio, NULL);
+	} else {
+		/* Open the file if no explicit digest bytes were specified. */
+		if (!digest &&
+		    !(data_bio = BIO_open_with_default(data, "rb", stdin)))
+			goto end;
+		/* Creating the query object. */
+		query = create_query(data_bio, digest, md,
+		    policy, no_nonce, cert);
+		/* Saving the random number generator state. */
+	}
+	if (query == NULL)
+		goto end;
+
+	/* Write query either in ASN.1 or in text format. */
+	if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL)
+		goto end;
+	if (text) {
+		/* Text output. */
+		if (!TS_REQ_print_bio(out_bio, query))
+			goto end;
+	} else {
+		/* ASN.1 output. */
+		if (!i2d_TS_REQ_bio(out_bio, query))
+			goto end;
+	}
+
+	ret = 1;
+
+end:
+	ERR_print_errors(bio_err);
+
+	/* Clean up. */
+	BIO_free_all(in_bio);
+	BIO_free_all(data_bio);
+	BIO_free_all(out_bio);
+	TS_REQ_free(query);
+
+	return ret;
+}
+
+static BIO *
+BIO_open_with_default(const char *file, const char *mode, FILE * default_fp)
+{
+	return file == NULL ? BIO_new_fp(default_fp, BIO_NOCLOSE) :
+	    BIO_new_file(file, mode);
+}
+
+static TS_REQ *
+create_query(BIO * data_bio, char *digest, const EVP_MD * md,
+    const char *policy, int no_nonce, int cert)
+{
+	int ret = 0;
+	TS_REQ *ts_req = NULL;
+	int len;
+	TS_MSG_IMPRINT *msg_imprint = NULL;
+	X509_ALGOR *algo = NULL;
+	unsigned char *data = NULL;
+	ASN1_OBJECT *policy_obj = NULL;
+	ASN1_INTEGER *nonce_asn1 = NULL;
+
+	/* Setting default message digest. */
+	if (!md && !(md = EVP_get_digestbyname("sha1")))
+		goto err;
+
+	/* Creating request object. */
+	if (!(ts_req = TS_REQ_new()))
+		goto err;
+
+	/* Setting version. */
+	if (!TS_REQ_set_version(ts_req, 1))
+		goto err;
+
+	/* Creating and adding MSG_IMPRINT object. */
+	if (!(msg_imprint = TS_MSG_IMPRINT_new()))
+		goto err;
+
+	/* Adding algorithm. */
+	if (!(algo = X509_ALGOR_new()))
+		goto err;
+	if (!(algo->algorithm = OBJ_nid2obj(EVP_MD_type(md))))
+		goto err;
+	if (!(algo->parameter = ASN1_TYPE_new()))
+		goto err;
+	algo->parameter->type = V_ASN1_NULL;
+	if (!TS_MSG_IMPRINT_set_algo(msg_imprint, algo))
+		goto err;
+
+	/* Adding message digest. */
+	if ((len = create_digest(data_bio, digest, md, &data)) == 0)
+		goto err;
+	if (!TS_MSG_IMPRINT_set_msg(msg_imprint, data, len))
+		goto err;
+
+	if (!TS_REQ_set_msg_imprint(ts_req, msg_imprint))
+		goto err;
+
+	/* Setting policy if requested. */
+	if (policy && !(policy_obj = txt2obj(policy)))
+		goto err;
+	if (policy_obj && !TS_REQ_set_policy_id(ts_req, policy_obj))
+		goto err;
+
+	/* Setting nonce if requested. */
+	if (!no_nonce && !(nonce_asn1 = create_nonce(NONCE_LENGTH)))
+		goto err;
+	if (nonce_asn1 && !TS_REQ_set_nonce(ts_req, nonce_asn1))
+		goto err;
+
+	/* Setting certificate request flag if requested. */
+	if (!TS_REQ_set_cert_req(ts_req, cert))
+		goto err;
+
+	ret = 1;
+
+err:
+	if (!ret) {
+		TS_REQ_free(ts_req);
+		ts_req = NULL;
+		BIO_printf(bio_err, "could not create query\n");
+	}
+	TS_MSG_IMPRINT_free(msg_imprint);
+	X509_ALGOR_free(algo);
+	free(data);
+	ASN1_OBJECT_free(policy_obj);
+	ASN1_INTEGER_free(nonce_asn1);
+
+	return ts_req;
+}
+
+static int
+create_digest(BIO * input, char *digest, const EVP_MD * md,
+    unsigned char **md_value)
+{
+	int md_value_len;
+
+	md_value_len = EVP_MD_size(md);
+	if (md_value_len < 0)
+		goto err;
+	if (input) {
+		/* Digest must be computed from an input file. */
+		EVP_MD_CTX md_ctx;
+		unsigned char buffer[4096];
+		int length;
+
+		*md_value = malloc(md_value_len);
+		if (*md_value == 0)
+			goto err;
+
+		EVP_DigestInit(&md_ctx, md);
+		while ((length = BIO_read(input, buffer, sizeof(buffer))) > 0) {
+			EVP_DigestUpdate(&md_ctx, buffer, length);
+		}
+		EVP_DigestFinal(&md_ctx, *md_value, NULL);
+	} else {
+		/* Digest bytes are specified with digest. */
+		long digest_len;
+		*md_value = string_to_hex(digest, &digest_len);
+		if (!*md_value || md_value_len != digest_len) {
+			free(*md_value);
+			*md_value = NULL;
+			BIO_printf(bio_err, "bad digest, %d bytes "
+			    "must be specified\n", md_value_len);
+			goto err;
+		}
+	}
+
+	return md_value_len;
+err:
+	return 0;
+}
+
+static ASN1_INTEGER *
+create_nonce(int bits)
+{
+	unsigned char buf[20];
+	ASN1_INTEGER *nonce = NULL;
+	int len = (bits - 1) / 8 + 1;
+	int i;
+
+	/* Generating random byte sequence. */
+	if (len > (int) sizeof(buf))
+		goto err;
+	arc4random_buf(buf, len);
+
+	/* Find the first non-zero byte and creating ASN1_INTEGER object. */
+	for (i = 0; i < len && !buf[i]; ++i)
+		;
+	if (!(nonce = ASN1_INTEGER_new()))
+		goto err;
+	free(nonce->data);
+	/* Allocate at least one byte. */
+	nonce->length = len - i;
+	if (!(nonce->data = malloc(nonce->length + 1)))
+		goto err;
+	memcpy(nonce->data, buf + i, nonce->length);
+
+	return nonce;
+
+err:
+	BIO_printf(bio_err, "could not create nonce\n");
+	ASN1_INTEGER_free(nonce);
+	return NULL;
+}
+/*
+ * Reply-related method definitions.
+ */
+
+static int
+reply_command(CONF * conf, char *section, char *queryfile,
+    char *passin, char *inkey, char *signer, char *chain, const char *policy,
+    char *in, int token_in, char *out, int token_out, int text)
+{
+	int ret = 0;
+	TS_RESP *response = NULL;
+	BIO *in_bio = NULL;
+	BIO *query_bio = NULL;
+	BIO *inkey_bio = NULL;
+	BIO *signer_bio = NULL;
+	BIO *out_bio = NULL;
+
+	/* Build response object either from response or query. */
+	if (in != NULL) {
+		if ((in_bio = BIO_new_file(in, "rb")) == NULL)
+			goto end;
+		if (token_in) {
+			/*
+			 * We have a ContentInfo (PKCS7) object, add
+			 * 'granted' status info around it.
+			 */
+			response = read_PKCS7(in_bio);
+		} else {
+			/* We have a ready-made TS_RESP object. */
+			response = d2i_TS_RESP_bio(in_bio, NULL);
+		}
+	} else {
+		response = create_response(conf, section, queryfile,
+		    passin, inkey, signer, chain,
+		    policy);
+		if (response)
+			BIO_printf(bio_err, "Response has been generated.\n");
+		else
+			BIO_printf(bio_err, "Response is not generated.\n");
+	}
+	if (response == NULL)
+		goto end;
+
+	/* Write response either in ASN.1 or text format. */
+	if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL)
+		goto end;
+	if (text) {
+		/* Text output. */
+		if (token_out) {
+			TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response);
+			if (!TS_TST_INFO_print_bio(out_bio, tst_info))
+				goto end;
+		} else {
+			if (!TS_RESP_print_bio(out_bio, response))
+				goto end;
+		}
+	} else {
+		/* ASN.1 DER output. */
+		if (token_out) {
+			PKCS7 *token = TS_RESP_get_token(response);
+			if (!i2d_PKCS7_bio(out_bio, token))
+				goto end;
+		} else {
+			if (!i2d_TS_RESP_bio(out_bio, response))
+				goto end;
+		}
+	}
+
+	ret = 1;
+
+end:
+	ERR_print_errors(bio_err);
+
+	/* Clean up. */
+	BIO_free_all(in_bio);
+	BIO_free_all(query_bio);
+	BIO_free_all(inkey_bio);
+	BIO_free_all(signer_bio);
+	BIO_free_all(out_bio);
+	TS_RESP_free(response);
+
+	return ret;
+}
+
+/* Reads a PKCS7 token and adds default 'granted' status info to it. */
+static TS_RESP *
+read_PKCS7(BIO * in_bio)
+{
+	int ret = 0;
+	PKCS7 *token = NULL;
+	TS_TST_INFO *tst_info = NULL;
+	TS_RESP *resp = NULL;
+	TS_STATUS_INFO *si = NULL;
+
+	/* Read PKCS7 object and extract the signed time stamp info. */
+	if (!(token = d2i_PKCS7_bio(in_bio, NULL)))
+		goto end;
+	if (!(tst_info = PKCS7_to_TS_TST_INFO(token)))
+		goto end;
+
+	/* Creating response object. */
+	if (!(resp = TS_RESP_new()))
+		goto end;
+
+	/* Create granted status info. */
+	if (!(si = TS_STATUS_INFO_new()))
+		goto end;
+	if (!(ASN1_INTEGER_set(si->status, TS_STATUS_GRANTED)))
+		goto end;
+	if (!TS_RESP_set_status_info(resp, si))
+		goto end;
+
+	/* Setting encapsulated token. */
+	TS_RESP_set_tst_info(resp, token, tst_info);
+	token = NULL;		/* Ownership is lost. */
+	tst_info = NULL;	/* Ownership is lost. */
+
+	ret = 1;
+end:
+	PKCS7_free(token);
+	TS_TST_INFO_free(tst_info);
+	if (!ret) {
+		TS_RESP_free(resp);
+		resp = NULL;
+	}
+	TS_STATUS_INFO_free(si);
+	return resp;
+}
+
+static TS_RESP *
+create_response(CONF * conf, const char *section,
+    char *queryfile, char *passin, char *inkey,
+    char *signer, char *chain, const char *policy)
+{
+	int ret = 0;
+	TS_RESP *response = NULL;
+	BIO *query_bio = NULL;
+	TS_RESP_CTX *resp_ctx = NULL;
+
+	if (!(query_bio = BIO_new_file(queryfile, "rb")))
+		goto end;
+
+	/* Getting TSA configuration section. */
+	if (!(section = TS_CONF_get_tsa_section(conf, section)))
+		goto end;
+
+	/* Setting up response generation context. */
+	if (!(resp_ctx = TS_RESP_CTX_new()))
+		goto end;
+
+	/* Setting serial number provider callback. */
+	if (!TS_CONF_set_serial(conf, section, serial_cb, resp_ctx))
+		goto end;
+
+	/* Setting TSA signer certificate. */
+	if (!TS_CONF_set_signer_cert(conf, section, signer, resp_ctx))
+		goto end;
+
+	/* Setting TSA signer certificate chain. */
+	if (!TS_CONF_set_certs(conf, section, chain, resp_ctx))
+		goto end;
+
+	/* Setting TSA signer private key. */
+	if (!TS_CONF_set_signer_key(conf, section, inkey, passin, resp_ctx))
+		goto end;
+
+	/* Setting default policy OID. */
+	if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx))
+		goto end;
+
+	/* Setting acceptable policy OIDs. */
+	if (!TS_CONF_set_policies(conf, section, resp_ctx))
+		goto end;
+
+	/* Setting the acceptable one-way hash algorithms. */
+	if (!TS_CONF_set_digests(conf, section, resp_ctx))
+		goto end;
+
+	/* Setting guaranteed time stamp accuracy. */
+	if (!TS_CONF_set_accuracy(conf, section, resp_ctx))
+		goto end;
+
+	/* Setting the precision of the time. */
+	if (!TS_CONF_set_clock_precision_digits(conf, section, resp_ctx))
+		goto end;
+
+	/* Setting the ordering flaf if requested. */
+	if (!TS_CONF_set_ordering(conf, section, resp_ctx))
+		goto end;
+
+	/* Setting the TSA name required flag if requested. */
+	if (!TS_CONF_set_tsa_name(conf, section, resp_ctx))
+		goto end;
+
+	/* Setting the ESS cert id chain flag if requested. */
+	if (!TS_CONF_set_ess_cert_id_chain(conf, section, resp_ctx))
+		goto end;
+
+	/* Creating the response. */
+	if (!(response = TS_RESP_create_response(resp_ctx, query_bio)))
+		goto end;
+
+	ret = 1;
+end:
+	if (!ret) {
+		TS_RESP_free(response);
+		response = NULL;
+	}
+	TS_RESP_CTX_free(resp_ctx);
+	BIO_free_all(query_bio);
+
+	return response;
+}
+
+static ASN1_INTEGER *
+serial_cb(TS_RESP_CTX * ctx, void *data)
+{
+	const char *serial_file = (const char *) data;
+	ASN1_INTEGER *serial = next_serial(serial_file);
+
+	if (!serial) {
+		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+		    "Error during serial number "
+		    "generation.");
+		TS_RESP_CTX_add_failure_info(ctx,
+		    TS_INFO_ADD_INFO_NOT_AVAILABLE);
+	} else
+		save_ts_serial(serial_file, serial);
+
+	return serial;
+}
+
+static ASN1_INTEGER *
+next_serial(const char *serialfile)
+{
+	int ret = 0;
+	BIO *in = NULL;
+	ASN1_INTEGER *serial = NULL;
+	BIGNUM *bn = NULL;
+
+	if (!(serial = ASN1_INTEGER_new()))
+		goto err;
+
+	if (!(in = BIO_new_file(serialfile, "r"))) {
+		ERR_clear_error();
+		BIO_printf(bio_err, "Warning: could not open file %s for "
+		    "reading, using serial number: 1\n", serialfile);
+		if (!ASN1_INTEGER_set(serial, 1))
+			goto err;
+	} else {
+		char buf[1024];
+		if (!a2i_ASN1_INTEGER(in, serial, buf, sizeof(buf))) {
+			BIO_printf(bio_err, "unable to load number from %s\n",
+			    serialfile);
+			goto err;
+		}
+		if (!(bn = ASN1_INTEGER_to_BN(serial, NULL)))
+			goto err;
+		ASN1_INTEGER_free(serial);
+		serial = NULL;
+		if (!BN_add_word(bn, 1))
+			goto err;
+		if (!(serial = BN_to_ASN1_INTEGER(bn, NULL)))
+			goto err;
+	}
+	ret = 1;
+err:
+	if (!ret) {
+		ASN1_INTEGER_free(serial);
+		serial = NULL;
+	}
+	BIO_free_all(in);
+	BN_free(bn);
+	return serial;
+}
+
+static int
+save_ts_serial(const char *serialfile, ASN1_INTEGER * serial)
+{
+	int ret = 0;
+	BIO *out = NULL;
+
+	if (!(out = BIO_new_file(serialfile, "w")))
+		goto err;
+	if (i2a_ASN1_INTEGER(out, serial) <= 0)
+		goto err;
+	if (BIO_puts(out, "\n") <= 0)
+		goto err;
+	ret = 1;
+err:
+	if (!ret)
+		BIO_printf(bio_err, "could not save serial number to %s\n",
+		    serialfile);
+	BIO_free_all(out);
+	return ret;
+}
+
+/*
+ * Verify-related method definitions.
+ */
+
+static int
+verify_command(char *data, char *digest, char *queryfile, char *in,
+    int token_in, char *ca_path, char *ca_file, char *untrusted)
+{
+	BIO *in_bio = NULL;
+	PKCS7 *token = NULL;
+	TS_RESP *response = NULL;
+	TS_VERIFY_CTX *verify_ctx = NULL;
+	int ret = 0;
+
+	/* Decode the token (PKCS7) or response (TS_RESP) files. */
+	if (!(in_bio = BIO_new_file(in, "rb")))
+		goto end;
+	if (token_in) {
+		if (!(token = d2i_PKCS7_bio(in_bio, NULL)))
+			goto end;
+	} else {
+		if (!(response = d2i_TS_RESP_bio(in_bio, NULL)))
+			goto end;
+	}
+
+	if (!(verify_ctx = create_verify_ctx(data, digest, queryfile,
+	    ca_path, ca_file, untrusted)))
+		goto end;
+
+	/* Checking the token or response against the request. */
+	ret = token_in ?
+	    TS_RESP_verify_token(verify_ctx, token) :
+	    TS_RESP_verify_response(verify_ctx, response);
+
+end:
+	printf("Verification: ");
+	if (ret)
+		printf("OK\n");
+	else {
+		printf("FAILED\n");
+		/* Print errors, if there are any. */
+		ERR_print_errors(bio_err);
+	}
+
+	/* Clean up. */
+	BIO_free_all(in_bio);
+	PKCS7_free(token);
+	TS_RESP_free(response);
+	TS_VERIFY_CTX_free(verify_ctx);
+	return ret;
+}
+
+static TS_VERIFY_CTX *
+create_verify_ctx(char *data, char *digest, char *queryfile, char *ca_path,
+    char *ca_file, char *untrusted)
+{
+	TS_VERIFY_CTX *ctx = NULL;
+	BIO *input = NULL;
+	TS_REQ *request = NULL;
+	int ret = 0;
+
+	if (data != NULL || digest != NULL) {
+		if (!(ctx = TS_VERIFY_CTX_new()))
+			goto err;
+		ctx->flags = TS_VFY_VERSION | TS_VFY_SIGNER;
+		if (data != NULL) {
+			ctx->flags |= TS_VFY_DATA;
+			if (!(ctx->data = BIO_new_file(data, "rb")))
+				goto err;
+		} else if (digest != NULL) {
+			long imprint_len;
+			ctx->flags |= TS_VFY_IMPRINT;
+			if (!(ctx->imprint = string_to_hex(digest,
+				    &imprint_len))) {
+				BIO_printf(bio_err, "invalid digest string\n");
+				goto err;
+			}
+			ctx->imprint_len = imprint_len;
+		}
+	} else if (queryfile != NULL) {
+		/*
+		 * The request has just to be read, decoded and converted to
+		 * a verify context object.
+		 */
+		if (!(input = BIO_new_file(queryfile, "rb")))
+			goto err;
+		if (!(request = d2i_TS_REQ_bio(input, NULL)))
+			goto err;
+		if (!(ctx = TS_REQ_to_TS_VERIFY_CTX(request, NULL)))
+			goto err;
+	} else
+		return NULL;
+
+	/* Add the signature verification flag and arguments. */
+	ctx->flags |= TS_VFY_SIGNATURE;
+
+	/* Initialising the X509_STORE object. */
+	if (!(ctx->store = create_cert_store(ca_path, ca_file)))
+		goto err;
+
+	/* Loading untrusted certificates. */
+	if (untrusted && !(ctx->certs = TS_CONF_load_certs(untrusted)))
+		goto err;
+
+	ret = 1;
+err:
+	if (!ret) {
+		TS_VERIFY_CTX_free(ctx);
+		ctx = NULL;
+	}
+	BIO_free_all(input);
+	TS_REQ_free(request);
+	return ctx;
+}
+
+static X509_STORE *
+create_cert_store(char *ca_path, char *ca_file)
+{
+	X509_STORE *cert_ctx = NULL;
+	X509_LOOKUP *lookup = NULL;
+	int i;
+
+	/* Creating the X509_STORE object. */
+	cert_ctx = X509_STORE_new();
+
+	/* Setting the callback for certificate chain verification. */
+	X509_STORE_set_verify_cb(cert_ctx, verify_cb);
+
+	/* Adding a trusted certificate directory source. */
+	if (ca_path) {
+		lookup = X509_STORE_add_lookup(cert_ctx,
+		    X509_LOOKUP_hash_dir());
+		if (lookup == NULL) {
+			BIO_printf(bio_err, "memory allocation failure\n");
+			goto err;
+		}
+		i = X509_LOOKUP_add_dir(lookup, ca_path, X509_FILETYPE_PEM);
+		if (!i) {
+			BIO_printf(bio_err, "Error loading directory %s\n",
+			    ca_path);
+			goto err;
+		}
+	}
+	/* Adding a trusted certificate file source. */
+	if (ca_file) {
+		lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
+		if (lookup == NULL) {
+			BIO_printf(bio_err, "memory allocation failure\n");
+			goto err;
+		}
+		i = X509_LOOKUP_load_file(lookup, ca_file, X509_FILETYPE_PEM);
+		if (!i) {
+			BIO_printf(bio_err, "Error loading file %s\n", ca_file);
+			goto err;
+		}
+	}
+	return cert_ctx;
+err:
+	X509_STORE_free(cert_ctx);
+	return NULL;
+}
+
+static int
+verify_cb(int ok, X509_STORE_CTX * ctx)
+{
+	/*
+	char buf[256];
+
+	if (!ok)
+		{
+		X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),
+				  buf, sizeof(buf));
+		printf("%s\n", buf);
+		printf("error %d at %d depth lookup: %s\n",
+		       ctx->error, ctx->error_depth,
+			X509_verify_cert_error_string(ctx->error));
+		}
+	*/
+
+	return ok;
+}
diff --git a/crypto/libressl/apps/openssl/verify.c b/crypto/libressl/apps/openssl/verify.c
new file mode 100644
index 0000000000..866d114d7f
--- /dev/null
+++ b/crypto/libressl/apps/openssl/verify.c
@@ -0,0 +1,324 @@
+/* $OpenBSD: verify.c,v 1.5 2015/10/10 22:28:51 doug Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include "apps.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int cb(int ok, X509_STORE_CTX * ctx);
+static int check(X509_STORE * ctx, char *file, STACK_OF(X509) * uchain,
+    STACK_OF(X509) * tchain, STACK_OF(X509_CRL) * crls);
+static int v_verbose = 0, vflags = 0;
+
+int
+verify_main(int argc, char **argv)
+{
+	int i, ret = 1, badarg = 0;
+	char *CApath = NULL, *CAfile = NULL;
+	char *untfile = NULL, *trustfile = NULL, *crlfile = NULL;
+	STACK_OF(X509) * untrusted = NULL, *trusted = NULL;
+	STACK_OF(X509_CRL) * crls = NULL;
+	X509_STORE *cert_ctx = NULL;
+	X509_LOOKUP *lookup = NULL;
+	X509_VERIFY_PARAM *vpm = NULL;
+
+	if (single_execution) {
+		if (pledge("stdio rpath", NULL) == -1) {
+			perror("pledge");
+			exit(1);
+		}
+	}
+
+	cert_ctx = X509_STORE_new();
+	if (cert_ctx == NULL)
+		goto end;
+	X509_STORE_set_verify_cb(cert_ctx, cb);
+
+	argc--;
+	argv++;
+	for (;;) {
+		if (argc >= 1) {
+			if (strcmp(*argv, "-CApath") == 0) {
+				if (argc-- < 1)
+					goto end;
+				CApath = *(++argv);
+			} else if (strcmp(*argv, "-CAfile") == 0) {
+				if (argc-- < 1)
+					goto end;
+				CAfile = *(++argv);
+			} else if (args_verify(&argv, &argc, &badarg, bio_err,
+			    &vpm)) {
+				if (badarg)
+					goto end;
+				continue;
+			} else if (strcmp(*argv, "-untrusted") == 0) {
+				if (argc-- < 1)
+					goto end;
+				untfile = *(++argv);
+			} else if (strcmp(*argv, "-trusted") == 0) {
+				if (argc-- < 1)
+					goto end;
+				trustfile = *(++argv);
+			} else if (strcmp(*argv, "-CRLfile") == 0) {
+				if (argc-- < 1)
+					goto end;
+				crlfile = *(++argv);
+			}
+			else if (strcmp(*argv, "-help") == 0)
+				goto end;
+			else if (strcmp(*argv, "-verbose") == 0)
+				v_verbose = 1;
+			else if (argv[0][0] == '-')
+				goto end;
+			else
+				break;
+			argc--;
+			argv++;
+		} else
+			break;
+	}
+
+	if (vpm)
+		X509_STORE_set1_param(cert_ctx, vpm);
+
+	lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
+	if (lookup == NULL)
+		abort();
+	if (CAfile) {
+		i = X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM);
+		if (!i) {
+			BIO_printf(bio_err, "Error loading file %s\n", CAfile);
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+	} else
+		X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
+
+	lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir());
+	if (lookup == NULL)
+		abort();
+	if (CApath) {
+		i = X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM);
+		if (!i) {
+			BIO_printf(bio_err, "Error loading directory %s\n", CApath);
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+	} else
+		X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
+
+	ERR_clear_error();
+
+	if (untfile) {
+		untrusted = load_certs(bio_err, untfile, FORMAT_PEM,
+		    NULL, "untrusted certificates");
+		if (!untrusted)
+			goto end;
+	}
+	if (trustfile) {
+		trusted = load_certs(bio_err, trustfile, FORMAT_PEM,
+		    NULL, "trusted certificates");
+		if (!trusted)
+			goto end;
+	}
+	if (crlfile) {
+		crls = load_crls(bio_err, crlfile, FORMAT_PEM,
+		    NULL, "other CRLs");
+		if (!crls)
+			goto end;
+	}
+	ret = 0;
+	if (argc < 1) {
+		if (1 != check(cert_ctx, NULL, untrusted, trusted, crls))
+			ret = -1;
+	} else {
+		for (i = 0; i < argc; i++)
+			if (1 != check(cert_ctx, argv[i], untrusted, trusted,
+			    crls))
+				ret = -1;
+	}
+
+end:
+	if (ret == 1) {
+		BIO_printf(bio_err, "usage: verify [-verbose] [-CApath path] [-CAfile file] [-purpose purpose] [-crl_check]");
+		BIO_printf(bio_err, " [-attime timestamp]");
+		BIO_printf(bio_err, " cert1 cert2 ...\n");
+
+		BIO_printf(bio_err, "recognized usages:\n");
+		for (i = 0; i < X509_PURPOSE_get_count(); i++) {
+			X509_PURPOSE *ptmp;
+			ptmp = X509_PURPOSE_get0(i);
+			BIO_printf(bio_err, "\t%-10s\t%s\n",
+			    X509_PURPOSE_get0_sname(ptmp),
+			    X509_PURPOSE_get0_name(ptmp));
+		}
+	}
+	if (vpm)
+		X509_VERIFY_PARAM_free(vpm);
+	if (cert_ctx != NULL)
+		X509_STORE_free(cert_ctx);
+	sk_X509_pop_free(untrusted, X509_free);
+	sk_X509_pop_free(trusted, X509_free);
+	sk_X509_CRL_pop_free(crls, X509_CRL_free);
+
+	return (ret < 0 ? 2 : ret);
+}
+
+static int
+check(X509_STORE * ctx, char *file, STACK_OF(X509) * uchain,
+    STACK_OF(X509) * tchain, STACK_OF(X509_CRL) * crls)
+{
+	X509 *x = NULL;
+	int i = 0, ret = 0;
+	X509_STORE_CTX *csc;
+
+	x = load_cert(bio_err, file, FORMAT_PEM, NULL, "certificate file");
+	if (x == NULL)
+		goto end;
+	fprintf(stdout, "%s: ", (file == NULL) ? "stdin" : file);
+
+	csc = X509_STORE_CTX_new();
+	if (csc == NULL) {
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+	X509_STORE_set_flags(ctx, vflags);
+	if (!X509_STORE_CTX_init(csc, ctx, x, uchain)) {
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+	if (tchain)
+		X509_STORE_CTX_trusted_stack(csc, tchain);
+	if (crls)
+		X509_STORE_CTX_set0_crls(csc, crls);
+	i = X509_verify_cert(csc);
+	X509_STORE_CTX_free(csc);
+
+	ret = 0;
+
+end:
+	if (i > 0) {
+		fprintf(stdout, "OK\n");
+		ret = 1;
+	} else
+		ERR_print_errors(bio_err);
+	if (x != NULL)
+		X509_free(x);
+
+	return (ret);
+}
+
+static int
+cb(int ok, X509_STORE_CTX * ctx)
+{
+	int cert_error = X509_STORE_CTX_get_error(ctx);
+	X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
+
+	if (!ok) {
+		if (current_cert) {
+			X509_NAME_print_ex_fp(stdout,
+			    X509_get_subject_name(current_cert),
+			    0, XN_FLAG_ONELINE);
+			printf("\n");
+		}
+		printf("%serror %d at %d depth lookup:%s\n",
+		    X509_STORE_CTX_get0_parent_ctx(ctx) ? "[CRL path]" : "",
+		    cert_error,
+		    X509_STORE_CTX_get_error_depth(ctx),
+		    X509_verify_cert_error_string(cert_error));
+		switch (cert_error) {
+		case X509_V_ERR_NO_EXPLICIT_POLICY:
+			policies_print(NULL, ctx);
+		case X509_V_ERR_CERT_HAS_EXPIRED:
+
+			/*
+			 * since we are just checking the certificates, it is
+			 * ok if they are self signed. But we should still
+			 * warn the user.
+			 */
+
+		case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+			/* Continue after extension errors too */
+		case X509_V_ERR_INVALID_CA:
+		case X509_V_ERR_INVALID_NON_CA:
+		case X509_V_ERR_PATH_LENGTH_EXCEEDED:
+		case X509_V_ERR_INVALID_PURPOSE:
+		case X509_V_ERR_CRL_HAS_EXPIRED:
+		case X509_V_ERR_CRL_NOT_YET_VALID:
+		case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
+			ok = 1;
+
+		}
+
+		return ok;
+
+	}
+	if (cert_error == X509_V_OK && ok == 2)
+		policies_print(NULL, ctx);
+	if (!v_verbose)
+		ERR_clear_error();
+	return (ok);
+}
diff --git a/crypto/libressl/apps/openssl/version.c b/crypto/libressl/apps/openssl/version.c
new file mode 100644
index 0000000000..afaeae6796
--- /dev/null
+++ b/crypto/libressl/apps/openssl/version.c
@@ -0,0 +1,269 @@
+/* $OpenBSD: version.c,v 1.7 2015/10/10 22:28:51 doug Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include "apps.h"
+
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_BF
+#include 
+#endif
+
+#ifndef OPENSSL_NO_DES
+#include 
+#endif
+
+#ifndef OPENSSL_NO_IDEA
+#include 
+#endif
+
+#ifndef OPENSSL_NO_RC4
+#include 
+#endif
+
+static struct {
+	int cflags;
+	int date;
+	int dir;
+	int options;
+	int platform;
+	int version;
+} version_config;
+
+static int
+version_all_opts(void)
+{
+	version_config.cflags = 1;
+	version_config.date = 1;
+	version_config.dir= 1;
+	version_config.options = 1;
+	version_config.platform = 1;
+	version_config.version = 1;
+
+	return (0);
+}
+
+static struct option version_options[] = {
+	{
+		.name = "a",
+		.desc = "All information (same as setting all other flags)",
+		.type = OPTION_FUNC,
+		.opt.func = version_all_opts,
+	},
+	{
+		.name = "b",
+		.desc = "Date the current version of OpenSSL was built",
+		.type = OPTION_FLAG,
+		.opt.flag = &version_config.date,
+	},
+	{
+		.name = "d",
+		.desc = "OPENSSLDIR value",
+		.type = OPTION_FLAG,
+		.opt.flag = &version_config.dir,
+	},
+	{
+		.name = "f",
+		.desc = "Compilation flags",
+		.type = OPTION_FLAG,
+		.opt.flag = &version_config.cflags,
+	},
+	{
+		.name = "o",
+		.desc = "Option information",
+		.type = OPTION_FLAG,
+		.opt.flag = &version_config.options,
+	},
+	{
+		.name = "p",
+		.desc = "Platform settings",
+		.type = OPTION_FLAG,
+		.opt.flag = &version_config.platform,
+	},
+	{
+		.name = "v",
+		.desc = "Current OpenSSL version",
+		.type = OPTION_FLAG,
+		.opt.flag = &version_config.version,
+	},
+	{NULL},
+};
+
+static void
+version_usage(void)
+{
+	fprintf(stderr, "usage: version [-abdfopv]\n");
+	options_usage(version_options);
+}
+
+int
+version_main(int argc, char **argv)
+{
+	if (single_execution) {
+		if (pledge("stdio", NULL) == -1) {
+			perror("pledge");
+			exit(1);
+		}
+	}
+
+	memset(&version_config, 0, sizeof(version_config));
+
+	if (options_parse(argc, argv, version_options, NULL, NULL) != 0) {
+		version_usage();
+		return (1);
+	}
+
+	if (argc == 1)
+		version_config.version = 1;
+
+	if (version_config.version) {
+		if (SSLeay() == SSLEAY_VERSION_NUMBER) {
+			printf("%s\n", SSLeay_version(SSLEAY_VERSION));
+		} else {
+			printf("%s (Library: %s)\n",
+			    OPENSSL_VERSION_TEXT,
+			    SSLeay_version(SSLEAY_VERSION));
+		}
+	}
+	if (version_config.date)
+		printf("%s\n", SSLeay_version(SSLEAY_BUILT_ON));
+	if (version_config.platform)
+		printf("%s\n", SSLeay_version(SSLEAY_PLATFORM));
+	if (version_config.options) {
+		printf("options:  ");
+		printf("%s ", BN_options());
+#ifndef OPENSSL_NO_RC4
+		printf("%s ", RC4_options());
+#endif
+#ifndef OPENSSL_NO_DES
+		printf("%s ", DES_options());
+#endif
+#ifndef OPENSSL_NO_IDEA
+		printf("%s ", idea_options());
+#endif
+#ifndef OPENSSL_NO_BF
+		printf("%s ", BF_options());
+#endif
+		printf("\n");
+	}
+	if (version_config.cflags)
+		printf("%s\n", SSLeay_version(SSLEAY_CFLAGS));
+	if (version_config.dir)
+		printf("%s\n", SSLeay_version(SSLEAY_DIR));
+
+	return (0);
+}
diff --git a/crypto/libressl/apps/openssl/x509.c b/crypto/libressl/apps/openssl/x509.c
new file mode 100644
index 0000000000..9c9faf979c
--- /dev/null
+++ b/crypto/libressl/apps/openssl/x509.c
@@ -0,0 +1,1150 @@
+/* $OpenBSD: x509.c,v 1.11 2015/10/17 07:51:10 semarie Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "apps.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+
+#define	POSTFIX	".srl"
+#define DEF_DAYS	30
+
+static const char *x509_usage[] = {
+	"usage: x509 args\n",
+	" -inform arg     - input format - default PEM (one of DER, NET or PEM)\n",
+	" -outform arg    - output format - default PEM (one of DER, NET or PEM)\n",
+	" -keyform arg    - private key format - default PEM\n",
+	" -CAform arg     - CA format - default PEM\n",
+	" -CAkeyform arg  - CA key format - default PEM\n",
+	" -in arg         - input file - default stdin\n",
+	" -out arg        - output file - default stdout\n",
+	" -passin arg     - private key password source\n",
+	" -serial         - print serial number value\n",
+	" -subject_hash   - print subject hash value\n",
+#ifndef OPENSSL_NO_MD5
+	" -subject_hash_old   - print old-style (MD5) subject hash value\n",
+#endif
+	" -issuer_hash    - print issuer hash value\n",
+#ifndef OPENSSL_NO_MD5
+	" -issuer_hash_old    - print old-style (MD5) issuer hash value\n",
+#endif
+	" -hash           - synonym for -subject_hash\n",
+	" -subject        - print subject DN\n",
+	" -issuer         - print issuer DN\n",
+	" -email          - print email address(es)\n",
+	" -startdate      - notBefore field\n",
+	" -enddate        - notAfter field\n",
+	" -purpose        - print out certificate purposes\n",
+	" -dates          - both Before and After dates\n",
+	" -modulus        - print the RSA key modulus\n",
+	" -pubkey         - output the public key\n",
+	" -fingerprint    - print the certificate fingerprint\n",
+	" -alias          - output certificate alias\n",
+	" -noout          - no certificate output\n",
+	" -ocspid         - print OCSP hash values for the subject name and public key\n",
+	" -ocsp_uri       - print OCSP Responder URL(s)\n",
+	" -trustout       - output a \"trusted\" certificate\n",
+	" -clrtrust       - clear all trusted purposes\n",
+	" -clrreject      - clear all rejected purposes\n",
+	" -addtrust arg   - trust certificate for a given purpose\n",
+	" -addreject arg  - reject certificate for a given purpose\n",
+	" -setalias arg   - set certificate alias\n",
+	" -days arg       - How long till expiry of a signed certificate - def 30 days\n",
+	" -checkend arg   - check whether the cert expires in the next arg seconds\n",
+	"                   exit 1 if so, 0 if not\n",
+	" -signkey arg    - self sign cert with arg\n",
+	" -x509toreq      - output a certification request object\n",
+	" -req            - input is a certificate request, sign and output.\n",
+	" -CA arg         - set the CA certificate, must be PEM format.\n",
+	" -CAkey arg      - set the CA key, must be PEM format\n",
+	"                   missing, it is assumed to be in the CA file.\n",
+	" -CAcreateserial - create serial number file if it does not exist\n",
+	" -CAserial arg   - serial file\n",
+	" -set_serial     - serial number to use\n",
+	" -text           - print the certificate in text form\n",
+	" -C              - print out C code forms\n",
+	" -md5/-sha1      - digest to use\n",
+	" -extfile        - configuration file with X509V3 extensions to add\n",
+	" -extensions     - section from config file with X509V3 extensions to add\n",
+	" -clrext         - delete extensions before signing and input certificate\n",
+	" -nameopt arg    - various certificate name options\n",
+	" -certopt arg    - various certificate text options\n",
+	NULL
+};
+
+static int callb(int ok, X509_STORE_CTX *ctx);
+static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext,
+    const EVP_MD *digest, CONF *conf, char *section);
+static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
+    X509 *x, X509 *xca, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *sigopts,
+    char *serial, int create, int days, int clrext, CONF *conf, char *section,
+    ASN1_INTEGER *sno);
+static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt);
+static int reqfile = 0;
+
+int
+x509_main(int argc, char **argv)
+{
+	int ret = 1;
+	X509_REQ *req = NULL;
+	X509 *x = NULL, *xca = NULL;
+	ASN1_OBJECT *objtmp;
+	STACK_OF(OPENSSL_STRING) *sigopts = NULL;
+	EVP_PKEY *Upkey = NULL, *CApkey = NULL;
+	ASN1_INTEGER *sno = NULL;
+	int i, num, badops = 0;
+	BIO *out = NULL;
+	BIO *STDout = NULL;
+	STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
+	int informat, outformat, keyformat, CAformat, CAkeyformat;
+	char *infile = NULL, *outfile = NULL, *keyfile = NULL, *CAfile = NULL;
+	char *CAkeyfile = NULL, *CAserial = NULL;
+	char *alias = NULL;
+	int text = 0, serial = 0, subject = 0, issuer = 0, startdate = 0,
+	    enddate = 0;
+	int next_serial = 0;
+	int subject_hash = 0, issuer_hash = 0, ocspid = 0;
+#ifndef OPENSSL_NO_MD5
+	int subject_hash_old = 0, issuer_hash_old = 0;
+#endif
+	int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0,
+	    email = 0;
+	int ocsp_uri = 0;
+	int trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0, clrext = 0;
+	int C = 0;
+	int x509req = 0, days = DEF_DAYS, modulus = 0, pubkey = 0;
+	int pprint = 0;
+	const char **pp;
+	X509_STORE *ctx = NULL;
+	X509_REQ *rq = NULL;
+	int fingerprint = 0;
+	char buf[256];
+	const EVP_MD *md_alg, *digest = NULL;
+	CONF *extconf = NULL;
+	char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL;
+	int checkend = 0, checkoffset = 0;
+	unsigned long nmflag = 0, certflag = 0;
+	const char *errstr = NULL;
+
+	if (single_execution) {
+		if (pledge("stdio rpath wpath cpath tty", NULL) == -1) {
+			perror("pledge");
+			exit(1);
+		}
+	}
+
+	reqfile = 0;
+
+	STDout = BIO_new_fp(stdout, BIO_NOCLOSE);
+
+	informat = FORMAT_PEM;
+	outformat = FORMAT_PEM;
+	keyformat = FORMAT_PEM;
+	CAformat = FORMAT_PEM;
+	CAkeyformat = FORMAT_PEM;
+
+	ctx = X509_STORE_new();
+	if (ctx == NULL)
+		goto end;
+	X509_STORE_set_verify_cb(ctx, callb);
+
+	argc--;
+	argv++;
+	num = 0;
+	while (argc >= 1) {
+		if (strcmp(*argv, "-inform") == 0) {
+			if (--argc < 1)
+				goto bad;
+			informat = str2fmt(*(++argv));
+		} else if (strcmp(*argv, "-outform") == 0) {
+			if (--argc < 1)
+				goto bad;
+			outformat = str2fmt(*(++argv));
+		} else if (strcmp(*argv, "-keyform") == 0) {
+			if (--argc < 1)
+				goto bad;
+			keyformat = str2fmt(*(++argv));
+		} else if (strcmp(*argv, "-req") == 0) {
+			reqfile = 1;
+		} else if (strcmp(*argv, "-CAform") == 0) {
+			if (--argc < 1)
+				goto bad;
+			CAformat = str2fmt(*(++argv));
+		} else if (strcmp(*argv, "-CAkeyform") == 0) {
+			if (--argc < 1)
+				goto bad;
+			CAkeyformat = str2fmt(*(++argv));
+		} else if (strcmp(*argv, "-sigopt") == 0) {
+			if (--argc < 1)
+				goto bad;
+			if (!sigopts)
+				sigopts = sk_OPENSSL_STRING_new_null();
+			if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
+				goto bad;
+		} else if (strcmp(*argv, "-days") == 0) {
+			if (--argc < 1)
+				goto bad;
+			days = strtonum(*(++argv), 1, INT_MAX, &errstr);
+			if (errstr) {
+				BIO_printf(bio_err, "bad number of days: %s\n", errstr);
+				goto bad;
+			}
+		} else if (strcmp(*argv, "-passin") == 0) {
+			if (--argc < 1)
+				goto bad;
+			passargin = *(++argv);
+		} else if (strcmp(*argv, "-extfile") == 0) {
+			if (--argc < 1)
+				goto bad;
+			extfile = *(++argv);
+		} else if (strcmp(*argv, "-extensions") == 0) {
+			if (--argc < 1)
+				goto bad;
+			extsect = *(++argv);
+		} else if (strcmp(*argv, "-in") == 0) {
+			if (--argc < 1)
+				goto bad;
+			infile = *(++argv);
+		} else if (strcmp(*argv, "-out") == 0) {
+			if (--argc < 1)
+				goto bad;
+			outfile = *(++argv);
+		} else if (strcmp(*argv, "-signkey") == 0) {
+			if (--argc < 1)
+				goto bad;
+			keyfile = *(++argv);
+			sign_flag = ++num;
+		} else if (strcmp(*argv, "-CA") == 0) {
+			if (--argc < 1)
+				goto bad;
+			CAfile = *(++argv);
+			CA_flag = ++num;
+		} else if (strcmp(*argv, "-CAkey") == 0) {
+			if (--argc < 1)
+				goto bad;
+			CAkeyfile = *(++argv);
+		} else if (strcmp(*argv, "-CAserial") == 0) {
+			if (--argc < 1)
+				goto bad;
+			CAserial = *(++argv);
+		} else if (strcmp(*argv, "-set_serial") == 0) {
+			if (--argc < 1)
+				goto bad;
+			ASN1_INTEGER_free(sno);
+			if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv))))
+				goto bad;
+		} else if (strcmp(*argv, "-addtrust") == 0) {
+			if (--argc < 1)
+				goto bad;
+			if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) {
+				BIO_printf(bio_err,
+				    "Invalid trust object value %s\n", *argv);
+				goto bad;
+			}
+			if (!trust)
+				trust = sk_ASN1_OBJECT_new_null();
+			sk_ASN1_OBJECT_push(trust, objtmp);
+			trustout = 1;
+		} else if (strcmp(*argv, "-addreject") == 0) {
+			if (--argc < 1)
+				goto bad;
+			if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) {
+				BIO_printf(bio_err,
+				    "Invalid reject object value %s\n", *argv);
+				goto bad;
+			}
+			if (!reject)
+				reject = sk_ASN1_OBJECT_new_null();
+			sk_ASN1_OBJECT_push(reject, objtmp);
+			trustout = 1;
+		} else if (strcmp(*argv, "-setalias") == 0) {
+			if (--argc < 1)
+				goto bad;
+			alias = *(++argv);
+			trustout = 1;
+		} else if (strcmp(*argv, "-certopt") == 0) {
+			if (--argc < 1)
+				goto bad;
+			if (!set_cert_ex(&certflag, *(++argv)))
+				goto bad;
+		} else if (strcmp(*argv, "-nameopt") == 0) {
+			if (--argc < 1)
+				goto bad;
+			if (!set_name_ex(&nmflag, *(++argv)))
+				goto bad;
+		}
+		else if (strcmp(*argv, "-C") == 0)
+			C = ++num;
+		else if (strcmp(*argv, "-email") == 0)
+			email = ++num;
+		else if (strcmp(*argv, "-ocsp_uri") == 0)
+			ocsp_uri = ++num;
+		else if (strcmp(*argv, "-serial") == 0)
+			serial = ++num;
+		else if (strcmp(*argv, "-next_serial") == 0)
+			next_serial = ++num;
+		else if (strcmp(*argv, "-modulus") == 0)
+			modulus = ++num;
+		else if (strcmp(*argv, "-pubkey") == 0)
+			pubkey = ++num;
+		else if (strcmp(*argv, "-x509toreq") == 0)
+			x509req = ++num;
+		else if (strcmp(*argv, "-text") == 0)
+			text = ++num;
+		else if (strcmp(*argv, "-hash") == 0 ||
+		    strcmp(*argv, "-subject_hash") == 0)
+			subject_hash = ++num;
+#ifndef OPENSSL_NO_MD5
+		else if (strcmp(*argv, "-subject_hash_old") == 0)
+			subject_hash_old = ++num;
+#endif
+		else if (strcmp(*argv, "-issuer_hash") == 0)
+			issuer_hash = ++num;
+#ifndef OPENSSL_NO_MD5
+		else if (strcmp(*argv, "-issuer_hash_old") == 0)
+			issuer_hash_old = ++num;
+#endif
+		else if (strcmp(*argv, "-subject") == 0)
+			subject = ++num;
+		else if (strcmp(*argv, "-issuer") == 0)
+			issuer = ++num;
+		else if (strcmp(*argv, "-fingerprint") == 0)
+			fingerprint = ++num;
+		else if (strcmp(*argv, "-dates") == 0) {
+			startdate = ++num;
+			enddate = ++num;
+		} else if (strcmp(*argv, "-purpose") == 0)
+			pprint = ++num;
+		else if (strcmp(*argv, "-startdate") == 0)
+			startdate = ++num;
+		else if (strcmp(*argv, "-enddate") == 0)
+			enddate = ++num;
+		else if (strcmp(*argv, "-checkend") == 0) {
+			if (--argc < 1)
+				goto bad;
+			checkoffset = strtonum(*(++argv), 0, INT_MAX, &errstr);
+			if (errstr) {
+				BIO_printf(bio_err, "checkend unusable: %s\n", errstr);
+				goto bad;
+			}
+			checkend = 1;
+		} else if (strcmp(*argv, "-noout") == 0)
+			noout = ++num;
+		else if (strcmp(*argv, "-trustout") == 0)
+			trustout = 1;
+		else if (strcmp(*argv, "-clrtrust") == 0)
+			clrtrust = ++num;
+		else if (strcmp(*argv, "-clrreject") == 0)
+			clrreject = ++num;
+		else if (strcmp(*argv, "-alias") == 0)
+			aliasout = ++num;
+		else if (strcmp(*argv, "-CAcreateserial") == 0)
+			CA_createserial = ++num;
+		else if (strcmp(*argv, "-clrext") == 0)
+			clrext = 1;
+		else if (strcmp(*argv, "-ocspid") == 0)
+			ocspid = ++num;
+		else if ((md_alg = EVP_get_digestbyname(*argv + 1))) {
+			/* ok */
+			digest = md_alg;
+		} else {
+			BIO_printf(bio_err, "unknown option %s\n", *argv);
+			badops = 1;
+			break;
+		}
+		argc--;
+		argv++;
+	}
+
+	if (badops) {
+bad:
+		for (pp = x509_usage; (*pp != NULL); pp++)
+			BIO_printf(bio_err, "%s", *pp);
+		goto end;
+	}
+
+	if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
+		BIO_printf(bio_err, "Error getting password\n");
+		goto end;
+	}
+	if (!X509_STORE_set_default_paths(ctx)) {
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+	if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) {
+		CAkeyfile = CAfile;
+	} else if ((CA_flag) && (CAkeyfile == NULL)) {
+		BIO_printf(bio_err,
+		    "need to specify a CAkey if using the CA command\n");
+		goto end;
+	}
+	if (extfile) {
+		long errorline = -1;
+		X509V3_CTX ctx2;
+		extconf = NCONF_new(NULL);
+		if (!NCONF_load(extconf, extfile, &errorline)) {
+			if (errorline <= 0)
+				BIO_printf(bio_err,
+				    "error loading the config file '%s'\n",
+				    extfile);
+			else
+				BIO_printf(bio_err,
+				    "error on line %ld of config file '%s'\n",
+				    errorline, extfile);
+			goto end;
+		}
+		if (!extsect) {
+			extsect = NCONF_get_string(extconf, "default",
+			    "extensions");
+			if (!extsect) {
+				ERR_clear_error();
+				extsect = "default";
+			}
+		}
+		X509V3_set_ctx_test(&ctx2);
+		X509V3_set_nconf(&ctx2, extconf);
+		if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) {
+			BIO_printf(bio_err,
+			    "Error Loading extension section %s\n",
+			    extsect);
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+	}
+	if (reqfile) {
+		EVP_PKEY *pkey;
+		BIO *in;
+
+		if (!sign_flag && !CA_flag) {
+			BIO_printf(bio_err, "We need a private key to sign with\n");
+			goto end;
+		}
+		in = BIO_new(BIO_s_file());
+		if (in == NULL) {
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+		if (infile == NULL)
+			BIO_set_fp(in, stdin, BIO_NOCLOSE | BIO_FP_TEXT);
+		else {
+			if (BIO_read_filename(in, infile) <= 0) {
+				perror(infile);
+				BIO_free(in);
+				goto end;
+			}
+		}
+		req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
+		BIO_free(in);
+
+		if (req == NULL) {
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+		if ((req->req_info == NULL) ||
+		    (req->req_info->pubkey == NULL) ||
+		    (req->req_info->pubkey->public_key == NULL) ||
+		    (req->req_info->pubkey->public_key->data == NULL)) {
+			BIO_printf(bio_err, "The certificate request appears to corrupted\n");
+			BIO_printf(bio_err, "It does not contain a public key\n");
+			goto end;
+		}
+		if ((pkey = X509_REQ_get_pubkey(req)) == NULL) {
+			BIO_printf(bio_err, "error unpacking public key\n");
+			goto end;
+		}
+		i = X509_REQ_verify(req, pkey);
+		EVP_PKEY_free(pkey);
+		if (i < 0) {
+			BIO_printf(bio_err, "Signature verification error\n");
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+		if (i == 0) {
+			BIO_printf(bio_err, "Signature did not match the certificate request\n");
+			goto end;
+		} else
+			BIO_printf(bio_err, "Signature ok\n");
+
+		print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), nmflag);
+
+		if ((x = X509_new()) == NULL)
+			goto end;
+
+		if (sno == NULL) {
+			sno = ASN1_INTEGER_new();
+			if (!sno || !rand_serial(NULL, sno))
+				goto end;
+			if (!X509_set_serialNumber(x, sno))
+				goto end;
+			ASN1_INTEGER_free(sno);
+			sno = NULL;
+		} else if (!X509_set_serialNumber(x, sno))
+			goto end;
+
+		if (!X509_set_issuer_name(x, req->req_info->subject))
+			goto end;
+		if (!X509_set_subject_name(x, req->req_info->subject))
+			goto end;
+
+		X509_gmtime_adj(X509_get_notBefore(x), 0);
+		X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL);
+
+		pkey = X509_REQ_get_pubkey(req);
+		X509_set_pubkey(x, pkey);
+		EVP_PKEY_free(pkey);
+	} else
+		x = load_cert(bio_err, infile, informat, NULL, "Certificate");
+
+	if (x == NULL)
+		goto end;
+	if (CA_flag) {
+		xca = load_cert(bio_err, CAfile, CAformat, NULL, "CA Certificate");
+		if (xca == NULL)
+			goto end;
+	}
+	if (!noout || text || next_serial) {
+		OBJ_create("2.99999.3",
+		    "SET.ex3", "SET x509v3 extension 3");
+
+		out = BIO_new(BIO_s_file());
+		if (out == NULL) {
+			ERR_print_errors(bio_err);
+			goto end;
+		}
+		if (outfile == NULL) {
+			BIO_set_fp(out, stdout, BIO_NOCLOSE);
+		} else {
+			if (BIO_write_filename(out, outfile) <= 0) {
+				perror(outfile);
+				goto end;
+			}
+		}
+	}
+	if (alias)
+		X509_alias_set1(x, (unsigned char *) alias, -1);
+
+	if (clrtrust)
+		X509_trust_clear(x);
+	if (clrreject)
+		X509_reject_clear(x);
+
+	if (trust) {
+		for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) {
+			objtmp = sk_ASN1_OBJECT_value(trust, i);
+			X509_add1_trust_object(x, objtmp);
+		}
+	}
+	if (reject) {
+		for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) {
+			objtmp = sk_ASN1_OBJECT_value(reject, i);
+			X509_add1_reject_object(x, objtmp);
+		}
+	}
+	if (num) {
+		for (i = 1; i <= num; i++) {
+			if (issuer == i) {
+				print_name(STDout, "issuer= ",
+				    X509_get_issuer_name(x), nmflag);
+			} else if (subject == i) {
+				print_name(STDout, "subject= ",
+				    X509_get_subject_name(x), nmflag);
+			} else if (serial == i) {
+				BIO_printf(STDout, "serial=");
+				i2a_ASN1_INTEGER(STDout,
+				    X509_get_serialNumber(x));
+				BIO_printf(STDout, "\n");
+			} else if (next_serial == i) {
+				BIGNUM *bnser;
+				ASN1_INTEGER *ser;
+				ser = X509_get_serialNumber(x);
+				bnser = ASN1_INTEGER_to_BN(ser, NULL);
+				if (!bnser)
+					goto end;
+				if (!BN_add_word(bnser, 1))
+					goto end;
+				ser = BN_to_ASN1_INTEGER(bnser, NULL);
+				if (!ser)
+					goto end;
+				BN_free(bnser);
+				i2a_ASN1_INTEGER(out, ser);
+				ASN1_INTEGER_free(ser);
+				BIO_puts(out, "\n");
+			} else if ((email == i) || (ocsp_uri == i)) {
+				int j;
+				STACK_OF(OPENSSL_STRING) *emlst;
+				if (email == i)
+					emlst = X509_get1_email(x);
+				else
+					emlst = X509_get1_ocsp(x);
+				for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
+					BIO_printf(STDout, "%s\n",
+					    sk_OPENSSL_STRING_value(emlst, j));
+				X509_email_free(emlst);
+			} else if (aliasout == i) {
+				unsigned char *alstr;
+				alstr = X509_alias_get0(x, NULL);
+				if (alstr)
+					BIO_printf(STDout, "%s\n", alstr);
+				else
+					BIO_puts(STDout, "\n");
+			} else if (subject_hash == i) {
+				BIO_printf(STDout, "%08lx\n", X509_subject_name_hash(x));
+			}
+#ifndef OPENSSL_NO_MD5
+			else if (subject_hash_old == i) {
+				BIO_printf(STDout, "%08lx\n", X509_subject_name_hash_old(x));
+			}
+#endif
+			else if (issuer_hash == i) {
+				BIO_printf(STDout, "%08lx\n", X509_issuer_name_hash(x));
+			}
+#ifndef OPENSSL_NO_MD5
+			else if (issuer_hash_old == i) {
+				BIO_printf(STDout, "%08lx\n", X509_issuer_name_hash_old(x));
+			}
+#endif
+			else if (pprint == i) {
+				X509_PURPOSE *ptmp;
+				int j;
+				BIO_printf(STDout, "Certificate purposes:\n");
+				for (j = 0; j < X509_PURPOSE_get_count(); j++) {
+					ptmp = X509_PURPOSE_get0(j);
+					purpose_print(STDout, x, ptmp);
+				}
+			} else if (modulus == i) {
+				EVP_PKEY *pkey;
+
+				pkey = X509_get_pubkey(x);
+				if (pkey == NULL) {
+					BIO_printf(bio_err, "Modulus=unavailable\n");
+					ERR_print_errors(bio_err);
+					goto end;
+				}
+				BIO_printf(STDout, "Modulus=");
+				if (pkey->type == EVP_PKEY_RSA)
+					BN_print(STDout, pkey->pkey.rsa->n);
+				else
+						if (pkey->type == EVP_PKEY_DSA)
+							BN_print(STDout, pkey->pkey.dsa->pub_key);
+				else
+						BIO_printf(STDout, "Wrong Algorithm type");
+				BIO_printf(STDout, "\n");
+				EVP_PKEY_free(pkey);
+			} else if (pubkey == i) {
+				EVP_PKEY *pkey;
+
+				pkey = X509_get_pubkey(x);
+				if (pkey == NULL) {
+					BIO_printf(bio_err, "Error getting public key\n");
+					ERR_print_errors(bio_err);
+					goto end;
+				}
+				PEM_write_bio_PUBKEY(STDout, pkey);
+				EVP_PKEY_free(pkey);
+			} else if (C == i) {
+				unsigned char *d;
+				char *m;
+				int y, z;
+
+				X509_NAME_oneline(X509_get_subject_name(x),
+				    buf, sizeof buf);
+				BIO_printf(STDout, "/* subject:%s */\n", buf);
+				m = X509_NAME_oneline(
+				    X509_get_issuer_name(x), buf,
+				    sizeof buf);
+				BIO_printf(STDout, "/* issuer :%s */\n", buf);
+
+				z = i2d_X509(x, NULL);
+				m = malloc(z);
+				if (m == NULL) {
+					BIO_printf(bio_err, "out of mem\n");
+					goto end;
+				}
+
+				d = (unsigned char *) m;
+				z = i2d_X509_NAME(X509_get_subject_name(x), &d);
+				BIO_printf(STDout, "unsigned char XXX_subject_name[%d]={\n", z);
+				d = (unsigned char *) m;
+				for (y = 0; y < z; y++) {
+					BIO_printf(STDout, "0x%02X,", d[y]);
+					if ((y & 0x0f) == 0x0f)
+						BIO_printf(STDout, "\n");
+				}
+				if (y % 16 != 0)
+					BIO_printf(STDout, "\n");
+				BIO_printf(STDout, "};\n");
+
+				z = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d);
+				BIO_printf(STDout, "unsigned char XXX_public_key[%d]={\n", z);
+				d = (unsigned char *) m;
+				for (y = 0; y < z; y++) {
+					BIO_printf(STDout, "0x%02X,", d[y]);
+					if ((y & 0x0f) == 0x0f)
+						BIO_printf(STDout, "\n");
+				}
+				if (y % 16 != 0)
+					BIO_printf(STDout, "\n");
+				BIO_printf(STDout, "};\n");
+
+				z = i2d_X509(x, &d);
+				BIO_printf(STDout, "unsigned char XXX_certificate[%d]={\n", z);
+				d = (unsigned char *) m;
+				for (y = 0; y < z; y++) {
+					BIO_printf(STDout, "0x%02X,", d[y]);
+					if ((y & 0x0f) == 0x0f)
+						BIO_printf(STDout, "\n");
+				}
+				if (y % 16 != 0)
+					BIO_printf(STDout, "\n");
+				BIO_printf(STDout, "};\n");
+
+				free(m);
+			} else if (text == i) {
+				X509_print_ex(STDout, x, nmflag, certflag);
+			} else if (startdate == i) {
+				BIO_puts(STDout, "notBefore=");
+				ASN1_TIME_print(STDout, X509_get_notBefore(x));
+				BIO_puts(STDout, "\n");
+			} else if (enddate == i) {
+				BIO_puts(STDout, "notAfter=");
+				ASN1_TIME_print(STDout, X509_get_notAfter(x));
+				BIO_puts(STDout, "\n");
+			} else if (fingerprint == i) {
+				int j;
+				unsigned int n;
+				unsigned char md[EVP_MAX_MD_SIZE];
+				const EVP_MD *fdig = digest;
+
+				if (!fdig)
+					fdig = EVP_sha1();
+
+				if (!X509_digest(x, fdig, md, &n)) {
+					BIO_printf(bio_err, "out of memory\n");
+					goto end;
+				}
+				BIO_printf(STDout, "%s Fingerprint=",
+				    OBJ_nid2sn(EVP_MD_type(fdig)));
+				for (j = 0; j < (int) n; j++) {
+					BIO_printf(STDout, "%02X%c", md[j],
+					    (j + 1 == (int)n) ? '\n' : ':');
+				}
+			}
+			/* should be in the library */
+			else if ((sign_flag == i) && (x509req == 0)) {
+				BIO_printf(bio_err, "Getting Private key\n");
+				if (Upkey == NULL) {
+					Upkey = load_key(bio_err,
+					    keyfile, keyformat, 0,
+					    passin, "Private key");
+					if (Upkey == NULL)
+						goto end;
+				}
+				if (!sign(x, Upkey, days, clrext, digest,
+				    extconf, extsect))
+					goto end;
+			} else if (CA_flag == i) {
+				BIO_printf(bio_err, "Getting CA Private Key\n");
+				if (CAkeyfile != NULL) {
+					CApkey = load_key(bio_err,
+					    CAkeyfile, CAkeyformat,
+					    0, passin, "CA Private Key");
+					if (CApkey == NULL)
+						goto end;
+				}
+				if (!x509_certify(ctx, CAfile, digest, x, xca,
+				    CApkey, sigopts,
+				    CAserial, CA_createserial, days, clrext,
+				    extconf, extsect, sno))
+					goto end;
+			} else if (x509req == i) {
+				EVP_PKEY *pk;
+
+				BIO_printf(bio_err, "Getting request Private Key\n");
+				if (keyfile == NULL) {
+					BIO_printf(bio_err, "no request key file specified\n");
+					goto end;
+				} else {
+					pk = load_key(bio_err,
+					    keyfile, keyformat, 0,
+					    passin, "request key");
+					if (pk == NULL)
+						goto end;
+				}
+
+				BIO_printf(bio_err, "Generating certificate request\n");
+
+				rq = X509_to_X509_REQ(x, pk, digest);
+				EVP_PKEY_free(pk);
+				if (rq == NULL) {
+					ERR_print_errors(bio_err);
+					goto end;
+				}
+				if (!noout) {
+					X509_REQ_print(out, rq);
+					PEM_write_bio_X509_REQ(out, rq);
+				}
+				noout = 1;
+			} else if (ocspid == i) {
+				X509_ocspid_print(out, x);
+			}
+		}
+	}
+	if (checkend) {
+		time_t tcheck = time(NULL) + checkoffset;
+
+		if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0) {
+			BIO_printf(out, "Certificate will expire\n");
+			ret = 1;
+		} else {
+			BIO_printf(out, "Certificate will not expire\n");
+			ret = 0;
+		}
+		goto end;
+	}
+	if (noout) {
+		ret = 0;
+		goto end;
+	}
+	if (outformat == FORMAT_ASN1)
+		i = i2d_X509_bio(out, x);
+	else if (outformat == FORMAT_PEM) {
+		if (trustout)
+			i = PEM_write_bio_X509_AUX(out, x);
+		else
+			i = PEM_write_bio_X509(out, x);
+	} else if (outformat == FORMAT_NETSCAPE) {
+		NETSCAPE_X509 nx;
+		ASN1_OCTET_STRING hdr;
+
+		hdr.data = (unsigned char *) NETSCAPE_CERT_HDR;
+		hdr.length = strlen(NETSCAPE_CERT_HDR);
+		nx.header = &hdr;
+		nx.cert = x;
+
+		i = ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509), out, &nx);
+	} else {
+		BIO_printf(bio_err, "bad output format specified for outfile\n");
+		goto end;
+	}
+	if (!i) {
+		BIO_printf(bio_err, "unable to write certificate\n");
+		ERR_print_errors(bio_err);
+		goto end;
+	}
+	ret = 0;
+
+end:
+	OBJ_cleanup();
+	NCONF_free(extconf);
+	BIO_free_all(out);
+	BIO_free_all(STDout);
+	X509_STORE_free(ctx);
+	X509_REQ_free(req);
+	X509_free(x);
+	X509_free(xca);
+	EVP_PKEY_free(Upkey);
+	EVP_PKEY_free(CApkey);
+	if (sigopts)
+		sk_OPENSSL_STRING_free(sigopts);
+	X509_REQ_free(rq);
+	ASN1_INTEGER_free(sno);
+	sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
+	sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
+	free(passin);
+
+	return (ret);
+}
+
+static ASN1_INTEGER *
+x509_load_serial(char *CAfile, char *serialfile, int create)
+{
+	char *buf = NULL, *p;
+	ASN1_INTEGER *bs = NULL;
+	BIGNUM *serial = NULL;
+	size_t len;
+
+	len = ((serialfile == NULL) ? (strlen(CAfile) + strlen(POSTFIX) + 1) :
+	    (strlen(serialfile))) + 1;
+	buf = malloc(len);
+	if (buf == NULL) {
+		BIO_printf(bio_err, "out of mem\n");
+		goto end;
+	}
+	if (serialfile == NULL) {
+		strlcpy(buf, CAfile, len);
+		for (p = buf; *p; p++)
+			if (*p == '.') {
+				*p = '\0';
+				break;
+			}
+		strlcat(buf, POSTFIX, len);
+	} else
+		strlcpy(buf, serialfile, len);
+
+	serial = load_serial(buf, create, NULL);
+	if (serial == NULL)
+		goto end;
+
+	if (!BN_add_word(serial, 1)) {
+		BIO_printf(bio_err, "add_word failure\n");
+		goto end;
+	}
+	if (!save_serial(buf, NULL, serial, &bs))
+		goto end;
+
+end:
+	free(buf);
+	BN_free(serial);
+
+	return bs;
+}
+
+static int
+x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, X509 *x,
+    X509 *xca, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *sigopts,
+    char *serialfile, int create, int days, int clrext, CONF *conf,
+    char *section, ASN1_INTEGER *sno)
+{
+	int ret = 0;
+	ASN1_INTEGER *bs = NULL;
+	X509_STORE_CTX xsc;
+	EVP_PKEY *upkey;
+
+	upkey = X509_get_pubkey(xca);
+	EVP_PKEY_copy_parameters(upkey, pkey);
+	EVP_PKEY_free(upkey);
+
+	if (!X509_STORE_CTX_init(&xsc, ctx, x, NULL)) {
+		BIO_printf(bio_err, "Error initialising X509 store\n");
+		goto end;
+	}
+	if (sno)
+		bs = sno;
+	else if (!(bs = x509_load_serial(CAfile, serialfile, create)))
+		goto end;
+
+/*	if (!X509_STORE_add_cert(ctx,x)) goto end;*/
+
+	/*
+	 * NOTE: this certificate can/should be self signed, unless it was a
+	 * certificate request in which case it is not.
+	 */
+	X509_STORE_CTX_set_cert(&xsc, x);
+	X509_STORE_CTX_set_flags(&xsc, X509_V_FLAG_CHECK_SS_SIGNATURE);
+	if (!reqfile && X509_verify_cert(&xsc) <= 0)
+		goto end;
+
+	if (!X509_check_private_key(xca, pkey)) {
+		BIO_printf(bio_err, "CA certificate and CA private key do not match\n");
+		goto end;
+	}
+	if (!X509_set_issuer_name(x, X509_get_subject_name(xca)))
+		goto end;
+	if (!X509_set_serialNumber(x, bs))
+		goto end;
+
+	if (X509_gmtime_adj(X509_get_notBefore(x), 0L) == NULL)
+		goto end;
+
+	/* hardwired expired */
+	if (X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL) == NULL)
+		goto end;
+
+	if (clrext) {
+		while (X509_get_ext_count(x) > 0)
+			X509_delete_ext(x, 0);
+	}
+	if (conf) {
+		X509V3_CTX ctx2;
+		X509_set_version(x, 2);	/* version 3 certificate */
+		X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
+		X509V3_set_nconf(&ctx2, conf);
+		if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x))
+			goto end;
+	}
+	if (!do_X509_sign(bio_err, x, pkey, digest, sigopts))
+		goto end;
+	ret = 1;
+end:
+	X509_STORE_CTX_cleanup(&xsc);
+	if (!ret)
+		ERR_print_errors(bio_err);
+	if (!sno)
+		ASN1_INTEGER_free(bs);
+	return ret;
+}
+
+static int
+callb(int ok, X509_STORE_CTX *ctx)
+{
+	int err;
+	X509 *err_cert;
+
+	/*
+	 * it is ok to use a self signed certificate This case will catch
+	 * both the initial ok == 0 and the final ok == 1 calls to this
+	 * function
+	 */
+	err = X509_STORE_CTX_get_error(ctx);
+	if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
+		return 1;
+
+	/*
+	 * BAD we should have gotten an error.  Normally if everything worked
+	 * X509_STORE_CTX_get_error(ctx) will still be set to
+	 * DEPTH_ZERO_SELF_....
+	 */
+	if (ok) {
+		BIO_printf(bio_err, "error with certificate to be certified - should be self signed\n");
+		return 0;
+	} else {
+		err_cert = X509_STORE_CTX_get_current_cert(ctx);
+		print_name(bio_err, NULL, X509_get_subject_name(err_cert), 0);
+		BIO_printf(bio_err, "error with certificate - error %d at depth %d\n%s\n",
+		    err, X509_STORE_CTX_get_error_depth(ctx),
+		    X509_verify_cert_error_string(err));
+		return 1;
+	}
+}
+
+/* self sign */
+static int
+sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest,
+    CONF *conf, char *section)
+{
+
+	EVP_PKEY *pktmp;
+
+	pktmp = X509_get_pubkey(x);
+	EVP_PKEY_copy_parameters(pktmp, pkey);
+	EVP_PKEY_save_parameters(pktmp, 1);
+	EVP_PKEY_free(pktmp);
+
+	if (!X509_set_issuer_name(x, X509_get_subject_name(x)))
+		goto err;
+	if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL)
+		goto err;
+
+	/* Lets just make it 12:00am GMT, Jan 1 1970 */
+	/* memcpy(x->cert_info->validity->notBefore,"700101120000Z",13); */
+	/* 28 days to be certified */
+
+	if (X509_gmtime_adj(X509_get_notAfter(x),
+	    (long) 60 * 60 * 24 * days) == NULL)
+		goto err;
+
+	if (!X509_set_pubkey(x, pkey))
+		goto err;
+	if (clrext) {
+		while (X509_get_ext_count(x) > 0)
+			X509_delete_ext(x, 0);
+	}
+	if (conf) {
+		X509V3_CTX ctx;
+		X509_set_version(x, 2);	/* version 3 certificate */
+		X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0);
+		X509V3_set_nconf(&ctx, conf);
+		if (!X509V3_EXT_add_nconf(conf, &ctx, section, x))
+			goto err;
+	}
+	if (!X509_sign(x, pkey, digest))
+		goto err;
+	return 1;
+
+err:
+	ERR_print_errors(bio_err);
+	return 0;
+}
+
+static int
+purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt)
+{
+	int id, i, idret;
+	char *pname;
+
+	id = X509_PURPOSE_get_id(pt);
+	pname = X509_PURPOSE_get0_name(pt);
+	for (i = 0; i < 2; i++) {
+		idret = X509_check_purpose(cert, id, i);
+		BIO_printf(bio, "%s%s : ", pname, i ? " CA" : "");
+		if (idret == 1)
+			BIO_printf(bio, "Yes\n");
+		else if (idret == 0)
+			BIO_printf(bio, "No\n");
+		else
+			BIO_printf(bio, "Yes (WARNING code=%d)\n", idret);
+	}
+	return 1;
+}
diff --git a/crypto/libressl/apps/openssl/x509v3.cnf b/crypto/libressl/apps/openssl/x509v3.cnf
new file mode 100644
index 0000000000..d12d732855
--- /dev/null
+++ b/crypto/libressl/apps/openssl/x509v3.cnf
@@ -0,0 +1,29 @@
+# default settings
+CERTPATHLEN		= 1
+CERTUSAGE		= digitalSignature,keyCertSign,cRLSign
+EXTCERTUSAGE		= serverAuth,clientAuth
+CERTIP			= 0.0.0.0
+CERTFQDN		= nohost.nodomain
+
+# This section should be referenced when building an x509v3 CA
+# Certificate.
+# The default path length and the key usage can be overridden
+# modified by setting the CERTPATHLEN and CERTUSAGE environment 
+# variables.
+[x509v3_CA]
+basicConstraints=critical,CA:true,pathlen:$ENV::CERTPATHLEN
+keyUsage=$ENV::CERTUSAGE
+
+# This section should be referenced to add an IP Address
+# as an alternate subject name, needed by isakmpd
+# The address must be provided in the CERTIP environment variable
+[x509v3_IPAddr]
+subjectAltName=IP:$ENV::CERTIP
+extendedKeyUsage=$ENV::EXTCERTUSAGE
+
+# This section should be referenced to add a FQDN hostname
+# as an alternate subject name, needed by isakmpd
+# The address must be provided in the CERTFQDN environment variable
+[x509v3_FQDN]
+subjectAltName=DNS:$ENV::CERTFQDN
+extendedKeyUsage=$ENV::EXTCERTUSAGE
diff --git a/crypto/libressl/crypto/VERSION b/crypto/libressl/crypto/VERSION
new file mode 100644
index 0000000000..af1ae57e38
--- /dev/null
+++ b/crypto/libressl/crypto/VERSION
@@ -0,0 +1 @@
+38:0:0
diff --git a/crypto/libressl/crypto/aes/aes-elf-x86_64.s b/crypto/libressl/crypto/aes/aes-elf-x86_64.s
new file mode 100644
index 0000000000..49a0e15327
--- /dev/null
+++ b/crypto/libressl/crypto/aes/aes-elf-x86_64.s
@@ -0,0 +1,2544 @@
+.text	
+.type	_x86_64_AES_encrypt,@function
+.align	16
+_x86_64_AES_encrypt:
+	xorl	0(%r15),%eax
+	xorl	4(%r15),%ebx
+	xorl	8(%r15),%ecx
+	xorl	12(%r15),%edx
+
+	movl	240(%r15),%r13d
+	subl	$1,%r13d
+	jmp	.Lenc_loop
+.align	16
+.Lenc_loop:
+
+	movzbl	%al,%esi
+	movzbl	%bl,%edi
+	movzbl	%cl,%ebp
+	movl	0(%r14,%rsi,8),%r10d
+	movl	0(%r14,%rdi,8),%r11d
+	movl	0(%r14,%rbp,8),%r12d
+
+	movzbl	%bh,%esi
+	movzbl	%ch,%edi
+	movzbl	%dl,%ebp
+	xorl	3(%r14,%rsi,8),%r10d
+	xorl	3(%r14,%rdi,8),%r11d
+	movl	0(%r14,%rbp,8),%r8d
+
+	movzbl	%dh,%esi
+	shrl	$16,%ecx
+	movzbl	%ah,%ebp
+	xorl	3(%r14,%rsi,8),%r12d
+	shrl	$16,%edx
+	xorl	3(%r14,%rbp,8),%r8d
+
+	shrl	$16,%ebx
+	leaq	16(%r15),%r15
+	shrl	$16,%eax
+
+	movzbl	%cl,%esi
+	movzbl	%dl,%edi
+	movzbl	%al,%ebp
+	xorl	2(%r14,%rsi,8),%r10d
+	xorl	2(%r14,%rdi,8),%r11d
+	xorl	2(%r14,%rbp,8),%r12d
+
+	movzbl	%dh,%esi
+	movzbl	%ah,%edi
+	movzbl	%bl,%ebp
+	xorl	1(%r14,%rsi,8),%r10d
+	xorl	1(%r14,%rdi,8),%r11d
+	xorl	2(%r14,%rbp,8),%r8d
+
+	movl	12(%r15),%edx
+	movzbl	%bh,%edi
+	movzbl	%ch,%ebp
+	movl	0(%r15),%eax
+	xorl	1(%r14,%rdi,8),%r12d
+	xorl	1(%r14,%rbp,8),%r8d
+
+	movl	4(%r15),%ebx
+	movl	8(%r15),%ecx
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	xorl	%r12d,%ecx
+	xorl	%r8d,%edx
+	subl	$1,%r13d
+	jnz	.Lenc_loop
+	movzbl	%al,%esi
+	movzbl	%bl,%edi
+	movzbl	%cl,%ebp
+	movzbl	2(%r14,%rsi,8),%r10d
+	movzbl	2(%r14,%rdi,8),%r11d
+	movzbl	2(%r14,%rbp,8),%r12d
+
+	movzbl	%dl,%esi
+	movzbl	%bh,%edi
+	movzbl	%ch,%ebp
+	movzbl	2(%r14,%rsi,8),%r8d
+	movl	0(%r14,%rdi,8),%edi
+	movl	0(%r14,%rbp,8),%ebp
+
+	andl	$65280,%edi
+	andl	$65280,%ebp
+
+	xorl	%edi,%r10d
+	xorl	%ebp,%r11d
+	shrl	$16,%ecx
+
+	movzbl	%dh,%esi
+	movzbl	%ah,%edi
+	shrl	$16,%edx
+	movl	0(%r14,%rsi,8),%esi
+	movl	0(%r14,%rdi,8),%edi
+
+	andl	$65280,%esi
+	andl	$65280,%edi
+	shrl	$16,%ebx
+	xorl	%esi,%r12d
+	xorl	%edi,%r8d
+	shrl	$16,%eax
+
+	movzbl	%cl,%esi
+	movzbl	%dl,%edi
+	movzbl	%al,%ebp
+	movl	0(%r14,%rsi,8),%esi
+	movl	0(%r14,%rdi,8),%edi
+	movl	0(%r14,%rbp,8),%ebp
+
+	andl	$16711680,%esi
+	andl	$16711680,%edi
+	andl	$16711680,%ebp
+
+	xorl	%esi,%r10d
+	xorl	%edi,%r11d
+	xorl	%ebp,%r12d
+
+	movzbl	%bl,%esi
+	movzbl	%dh,%edi
+	movzbl	%ah,%ebp
+	movl	0(%r14,%rsi,8),%esi
+	movl	2(%r14,%rdi,8),%edi
+	movl	2(%r14,%rbp,8),%ebp
+
+	andl	$16711680,%esi
+	andl	$4278190080,%edi
+	andl	$4278190080,%ebp
+
+	xorl	%esi,%r8d
+	xorl	%edi,%r10d
+	xorl	%ebp,%r11d
+
+	movzbl	%bh,%esi
+	movzbl	%ch,%edi
+	movl	16+12(%r15),%edx
+	movl	2(%r14,%rsi,8),%esi
+	movl	2(%r14,%rdi,8),%edi
+	movl	16+0(%r15),%eax
+
+	andl	$4278190080,%esi
+	andl	$4278190080,%edi
+
+	xorl	%esi,%r12d
+	xorl	%edi,%r8d
+
+	movl	16+4(%r15),%ebx
+	movl	16+8(%r15),%ecx
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	xorl	%r12d,%ecx
+	xorl	%r8d,%edx
+.byte	0xf3,0xc3			
+.size	_x86_64_AES_encrypt,.-_x86_64_AES_encrypt
+.type	_x86_64_AES_encrypt_compact,@function
+.align	16
+_x86_64_AES_encrypt_compact:
+	leaq	128(%r14),%r8
+	movl	0-128(%r8),%edi
+	movl	32-128(%r8),%ebp
+	movl	64-128(%r8),%r10d
+	movl	96-128(%r8),%r11d
+	movl	128-128(%r8),%edi
+	movl	160-128(%r8),%ebp
+	movl	192-128(%r8),%r10d
+	movl	224-128(%r8),%r11d
+	jmp	.Lenc_loop_compact
+.align	16
+.Lenc_loop_compact:
+	xorl	0(%r15),%eax
+	xorl	4(%r15),%ebx
+	xorl	8(%r15),%ecx
+	xorl	12(%r15),%edx
+	leaq	16(%r15),%r15
+	movzbl	%al,%r10d
+	movzbl	%bl,%r11d
+	movzbl	%cl,%r12d
+	movzbl	(%r14,%r10,1),%r10d
+	movzbl	(%r14,%r11,1),%r11d
+	movzbl	(%r14,%r12,1),%r12d
+
+	movzbl	%dl,%r8d
+	movzbl	%bh,%esi
+	movzbl	%ch,%edi
+	movzbl	(%r14,%r8,1),%r8d
+	movzbl	(%r14,%rsi,1),%r9d
+	movzbl	(%r14,%rdi,1),%r13d
+
+	movzbl	%dh,%ebp
+	movzbl	%ah,%esi
+	shrl	$16,%ecx
+	movzbl	(%r14,%rbp,1),%ebp
+	movzbl	(%r14,%rsi,1),%esi
+	shrl	$16,%edx
+
+	movzbl	%cl,%edi
+	shll	$8,%r9d
+	shll	$8,%r13d
+	movzbl	(%r14,%rdi,1),%edi
+	xorl	%r9d,%r10d
+	xorl	%r13d,%r11d
+
+	movzbl	%dl,%r9d
+	shrl	$16,%eax
+	shrl	$16,%ebx
+	movzbl	%al,%r13d
+	shll	$8,%ebp
+	shll	$8,%esi
+	movzbl	(%r14,%r9,1),%r9d
+	movzbl	(%r14,%r13,1),%r13d
+	xorl	%ebp,%r12d
+	xorl	%esi,%r8d
+
+	movzbl	%bl,%ebp
+	movzbl	%dh,%esi
+	shll	$16,%edi
+	movzbl	(%r14,%rbp,1),%ebp
+	movzbl	(%r14,%rsi,1),%esi
+	xorl	%edi,%r10d
+
+	movzbl	%ah,%edi
+	shrl	$8,%ecx
+	shrl	$8,%ebx
+	movzbl	(%r14,%rdi,1),%edi
+	movzbl	(%r14,%rcx,1),%edx
+	movzbl	(%r14,%rbx,1),%ecx
+	shll	$16,%r9d
+	shll	$16,%r13d
+	shll	$16,%ebp
+	xorl	%r9d,%r11d
+	xorl	%r13d,%r12d
+	xorl	%ebp,%r8d
+
+	shll	$24,%esi
+	shll	$24,%edi
+	shll	$24,%edx
+	xorl	%esi,%r10d
+	shll	$24,%ecx
+	xorl	%edi,%r11d
+	movl	%r10d,%eax
+	movl	%r11d,%ebx
+	xorl	%r12d,%ecx
+	xorl	%r8d,%edx
+	cmpq	16(%rsp),%r15
+	je	.Lenc_compact_done
+	movl	%eax,%esi
+	movl	%ebx,%edi
+	andl	$2155905152,%esi
+	andl	$2155905152,%edi
+	movl	%esi,%r10d
+	movl	%edi,%r11d
+	shrl	$7,%r10d
+	leal	(%rax,%rax,1),%r8d
+	shrl	$7,%r11d
+	leal	(%rbx,%rbx,1),%r9d
+	subl	%r10d,%esi
+	subl	%r11d,%edi
+	andl	$4278124286,%r8d
+	andl	$4278124286,%r9d
+	andl	$454761243,%esi
+	andl	$454761243,%edi
+	movl	%eax,%r10d
+	movl	%ebx,%r11d
+	xorl	%esi,%r8d
+	xorl	%edi,%r9d
+
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movl	%ecx,%esi
+	movl	%edx,%edi
+	roll	$24,%eax
+	roll	$24,%ebx
+	andl	$2155905152,%esi
+	andl	$2155905152,%edi
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movl	%esi,%r12d
+	movl	%edi,%ebp
+	rorl	$16,%r10d
+	rorl	$16,%r11d
+	shrl	$7,%r12d
+	leal	(%rcx,%rcx,1),%r8d
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	shrl	$7,%ebp
+	leal	(%rdx,%rdx,1),%r9d
+	rorl	$8,%r10d
+	rorl	$8,%r11d
+	subl	%r12d,%esi
+	subl	%ebp,%edi
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+
+	andl	$4278124286,%r8d
+	andl	$4278124286,%r9d
+	andl	$454761243,%esi
+	andl	$454761243,%edi
+	movl	%ecx,%r12d
+	movl	%edx,%ebp
+	xorl	%esi,%r8d
+	xorl	%edi,%r9d
+
+	xorl	%r8d,%ecx
+	xorl	%r9d,%edx
+	roll	$24,%ecx
+	roll	$24,%edx
+	xorl	%r8d,%ecx
+	xorl	%r9d,%edx
+	movl	0(%r14),%esi
+	rorl	$16,%r12d
+	rorl	$16,%ebp
+	movl	64(%r14),%edi
+	xorl	%r12d,%ecx
+	xorl	%ebp,%edx
+	movl	128(%r14),%r8d
+	rorl	$8,%r12d
+	rorl	$8,%ebp
+	movl	192(%r14),%r9d
+	xorl	%r12d,%ecx
+	xorl	%ebp,%edx
+	jmp	.Lenc_loop_compact
+.align	16
+.Lenc_compact_done:
+	xorl	0(%r15),%eax
+	xorl	4(%r15),%ebx
+	xorl	8(%r15),%ecx
+	xorl	12(%r15),%edx
+.byte	0xf3,0xc3			
+.size	_x86_64_AES_encrypt_compact,.-_x86_64_AES_encrypt_compact
+.globl	AES_encrypt
+.type	AES_encrypt,@function
+.align	16
+.globl	asm_AES_encrypt
+.hidden	asm_AES_encrypt
+asm_AES_encrypt:
+AES_encrypt:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+
+
+	movq	%rsp,%r10
+	leaq	-63(%rdx),%rcx
+	andq	$-64,%rsp
+	subq	%rsp,%rcx
+	negq	%rcx
+	andq	$960,%rcx
+	subq	%rcx,%rsp
+	subq	$32,%rsp
+
+	movq	%rsi,16(%rsp)
+	movq	%r10,24(%rsp)
+.Lenc_prologue:
+
+	movq	%rdx,%r15
+	movl	240(%r15),%r13d
+
+	movl	0(%rdi),%eax
+	movl	4(%rdi),%ebx
+	movl	8(%rdi),%ecx
+	movl	12(%rdi),%edx
+
+	shll	$4,%r13d
+	leaq	(%r15,%r13,1),%rbp
+	movq	%r15,(%rsp)
+	movq	%rbp,8(%rsp)
+
+
+	leaq	.LAES_Te+2048(%rip),%r14
+	leaq	768(%rsp),%rbp
+	subq	%r14,%rbp
+	andq	$768,%rbp
+	leaq	(%r14,%rbp,1),%r14
+
+	call	_x86_64_AES_encrypt_compact
+
+	movq	16(%rsp),%r9
+	movq	24(%rsp),%rsi
+	movl	%eax,0(%r9)
+	movl	%ebx,4(%r9)
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+.Lenc_epilogue:
+	.byte	0xf3,0xc3
+.size	AES_encrypt,.-AES_encrypt
+.type	_x86_64_AES_decrypt,@function
+.align	16
+_x86_64_AES_decrypt:
+	xorl	0(%r15),%eax
+	xorl	4(%r15),%ebx
+	xorl	8(%r15),%ecx
+	xorl	12(%r15),%edx
+
+	movl	240(%r15),%r13d
+	subl	$1,%r13d
+	jmp	.Ldec_loop
+.align	16
+.Ldec_loop:
+
+	movzbl	%al,%esi
+	movzbl	%bl,%edi
+	movzbl	%cl,%ebp
+	movl	0(%r14,%rsi,8),%r10d
+	movl	0(%r14,%rdi,8),%r11d
+	movl	0(%r14,%rbp,8),%r12d
+
+	movzbl	%dh,%esi
+	movzbl	%ah,%edi
+	movzbl	%dl,%ebp
+	xorl	3(%r14,%rsi,8),%r10d
+	xorl	3(%r14,%rdi,8),%r11d
+	movl	0(%r14,%rbp,8),%r8d
+
+	movzbl	%bh,%esi
+	shrl	$16,%eax
+	movzbl	%ch,%ebp
+	xorl	3(%r14,%rsi,8),%r12d
+	shrl	$16,%edx
+	xorl	3(%r14,%rbp,8),%r8d
+
+	shrl	$16,%ebx
+	leaq	16(%r15),%r15
+	shrl	$16,%ecx
+
+	movzbl	%cl,%esi
+	movzbl	%dl,%edi
+	movzbl	%al,%ebp
+	xorl	2(%r14,%rsi,8),%r10d
+	xorl	2(%r14,%rdi,8),%r11d
+	xorl	2(%r14,%rbp,8),%r12d
+
+	movzbl	%bh,%esi
+	movzbl	%ch,%edi
+	movzbl	%bl,%ebp
+	xorl	1(%r14,%rsi,8),%r10d
+	xorl	1(%r14,%rdi,8),%r11d
+	xorl	2(%r14,%rbp,8),%r8d
+
+	movzbl	%dh,%esi
+	movl	12(%r15),%edx
+	movzbl	%ah,%ebp
+	xorl	1(%r14,%rsi,8),%r12d
+	movl	0(%r15),%eax
+	xorl	1(%r14,%rbp,8),%r8d
+
+	xorl	%r10d,%eax
+	movl	4(%r15),%ebx
+	movl	8(%r15),%ecx
+	xorl	%r12d,%ecx
+	xorl	%r11d,%ebx
+	xorl	%r8d,%edx
+	subl	$1,%r13d
+	jnz	.Ldec_loop
+	leaq	2048(%r14),%r14
+	movzbl	%al,%esi
+	movzbl	%bl,%edi
+	movzbl	%cl,%ebp
+	movzbl	(%r14,%rsi,1),%r10d
+	movzbl	(%r14,%rdi,1),%r11d
+	movzbl	(%r14,%rbp,1),%r12d
+
+	movzbl	%dl,%esi
+	movzbl	%dh,%edi
+	movzbl	%ah,%ebp
+	movzbl	(%r14,%rsi,1),%r8d
+	movzbl	(%r14,%rdi,1),%edi
+	movzbl	(%r14,%rbp,1),%ebp
+
+	shll	$8,%edi
+	shll	$8,%ebp
+
+	xorl	%edi,%r10d
+	xorl	%ebp,%r11d
+	shrl	$16,%edx
+
+	movzbl	%bh,%esi
+	movzbl	%ch,%edi
+	shrl	$16,%eax
+	movzbl	(%r14,%rsi,1),%esi
+	movzbl	(%r14,%rdi,1),%edi
+
+	shll	$8,%esi
+	shll	$8,%edi
+	shrl	$16,%ebx
+	xorl	%esi,%r12d
+	xorl	%edi,%r8d
+	shrl	$16,%ecx
+
+	movzbl	%cl,%esi
+	movzbl	%dl,%edi
+	movzbl	%al,%ebp
+	movzbl	(%r14,%rsi,1),%esi
+	movzbl	(%r14,%rdi,1),%edi
+	movzbl	(%r14,%rbp,1),%ebp
+
+	shll	$16,%esi
+	shll	$16,%edi
+	shll	$16,%ebp
+
+	xorl	%esi,%r10d
+	xorl	%edi,%r11d
+	xorl	%ebp,%r12d
+
+	movzbl	%bl,%esi
+	movzbl	%bh,%edi
+	movzbl	%ch,%ebp
+	movzbl	(%r14,%rsi,1),%esi
+	movzbl	(%r14,%rdi,1),%edi
+	movzbl	(%r14,%rbp,1),%ebp
+
+	shll	$16,%esi
+	shll	$24,%edi
+	shll	$24,%ebp
+
+	xorl	%esi,%r8d
+	xorl	%edi,%r10d
+	xorl	%ebp,%r11d
+
+	movzbl	%dh,%esi
+	movzbl	%ah,%edi
+	movl	16+12(%r15),%edx
+	movzbl	(%r14,%rsi,1),%esi
+	movzbl	(%r14,%rdi,1),%edi
+	movl	16+0(%r15),%eax
+
+	shll	$24,%esi
+	shll	$24,%edi
+
+	xorl	%esi,%r12d
+	xorl	%edi,%r8d
+
+	movl	16+4(%r15),%ebx
+	movl	16+8(%r15),%ecx
+	leaq	-2048(%r14),%r14
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	xorl	%r12d,%ecx
+	xorl	%r8d,%edx
+.byte	0xf3,0xc3			
+.size	_x86_64_AES_decrypt,.-_x86_64_AES_decrypt
+.type	_x86_64_AES_decrypt_compact,@function
+.align	16
+_x86_64_AES_decrypt_compact:
+	leaq	128(%r14),%r8
+	movl	0-128(%r8),%edi
+	movl	32-128(%r8),%ebp
+	movl	64-128(%r8),%r10d
+	movl	96-128(%r8),%r11d
+	movl	128-128(%r8),%edi
+	movl	160-128(%r8),%ebp
+	movl	192-128(%r8),%r10d
+	movl	224-128(%r8),%r11d
+	jmp	.Ldec_loop_compact
+
+.align	16
+.Ldec_loop_compact:
+	xorl	0(%r15),%eax
+	xorl	4(%r15),%ebx
+	xorl	8(%r15),%ecx
+	xorl	12(%r15),%edx
+	leaq	16(%r15),%r15
+	movzbl	%al,%r10d
+	movzbl	%bl,%r11d
+	movzbl	%cl,%r12d
+	movzbl	(%r14,%r10,1),%r10d
+	movzbl	(%r14,%r11,1),%r11d
+	movzbl	(%r14,%r12,1),%r12d
+
+	movzbl	%dl,%r8d
+	movzbl	%dh,%esi
+	movzbl	%ah,%edi
+	movzbl	(%r14,%r8,1),%r8d
+	movzbl	(%r14,%rsi,1),%r9d
+	movzbl	(%r14,%rdi,1),%r13d
+
+	movzbl	%bh,%ebp
+	movzbl	%ch,%esi
+	shrl	$16,%ecx
+	movzbl	(%r14,%rbp,1),%ebp
+	movzbl	(%r14,%rsi,1),%esi
+	shrl	$16,%edx
+
+	movzbl	%cl,%edi
+	shll	$8,%r9d
+	shll	$8,%r13d
+	movzbl	(%r14,%rdi,1),%edi
+	xorl	%r9d,%r10d
+	xorl	%r13d,%r11d
+
+	movzbl	%dl,%r9d
+	shrl	$16,%eax
+	shrl	$16,%ebx
+	movzbl	%al,%r13d
+	shll	$8,%ebp
+	shll	$8,%esi
+	movzbl	(%r14,%r9,1),%r9d
+	movzbl	(%r14,%r13,1),%r13d
+	xorl	%ebp,%r12d
+	xorl	%esi,%r8d
+
+	movzbl	%bl,%ebp
+	movzbl	%bh,%esi
+	shll	$16,%edi
+	movzbl	(%r14,%rbp,1),%ebp
+	movzbl	(%r14,%rsi,1),%esi
+	xorl	%edi,%r10d
+
+	movzbl	%ch,%edi
+	shll	$16,%r9d
+	shll	$16,%r13d
+	movzbl	(%r14,%rdi,1),%ebx
+	xorl	%r9d,%r11d
+	xorl	%r13d,%r12d
+
+	movzbl	%dh,%edi
+	shrl	$8,%eax
+	shll	$16,%ebp
+	movzbl	(%r14,%rdi,1),%ecx
+	movzbl	(%r14,%rax,1),%edx
+	xorl	%ebp,%r8d
+
+	shll	$24,%esi
+	shll	$24,%ebx
+	shll	$24,%ecx
+	xorl	%esi,%r10d
+	shll	$24,%edx
+	xorl	%r11d,%ebx
+	movl	%r10d,%eax
+	xorl	%r12d,%ecx
+	xorl	%r8d,%edx
+	cmpq	16(%rsp),%r15
+	je	.Ldec_compact_done
+
+	movq	256+0(%r14),%rsi
+	shlq	$32,%rbx
+	shlq	$32,%rdx
+	movq	256+8(%r14),%rdi
+	orq	%rbx,%rax
+	orq	%rdx,%rcx
+	movq	256+16(%r14),%rbp
+	movq	%rax,%rbx
+	movq	%rcx,%rdx
+	andq	%rsi,%rbx
+	andq	%rsi,%rdx
+	movq	%rbx,%r9
+	movq	%rdx,%r12
+	shrq	$7,%r9
+	leaq	(%rax,%rax,1),%r8
+	shrq	$7,%r12
+	leaq	(%rcx,%rcx,1),%r11
+	subq	%r9,%rbx
+	subq	%r12,%rdx
+	andq	%rdi,%r8
+	andq	%rdi,%r11
+	andq	%rbp,%rbx
+	andq	%rbp,%rdx
+	xorq	%r8,%rbx
+	xorq	%r11,%rdx
+	movq	%rbx,%r8
+	movq	%rdx,%r11
+
+	andq	%rsi,%rbx
+	andq	%rsi,%rdx
+	movq	%rbx,%r10
+	movq	%rdx,%r13
+	shrq	$7,%r10
+	leaq	(%r8,%r8,1),%r9
+	shrq	$7,%r13
+	leaq	(%r11,%r11,1),%r12
+	subq	%r10,%rbx
+	subq	%r13,%rdx
+	andq	%rdi,%r9
+	andq	%rdi,%r12
+	andq	%rbp,%rbx
+	andq	%rbp,%rdx
+	xorq	%r9,%rbx
+	xorq	%r12,%rdx
+	movq	%rbx,%r9
+	movq	%rdx,%r12
+
+	andq	%rsi,%rbx
+	andq	%rsi,%rdx
+	movq	%rbx,%r10
+	movq	%rdx,%r13
+	shrq	$7,%r10
+	xorq	%rax,%r8
+	shrq	$7,%r13
+	xorq	%rcx,%r11
+	subq	%r10,%rbx
+	subq	%r13,%rdx
+	leaq	(%r9,%r9,1),%r10
+	leaq	(%r12,%r12,1),%r13
+	xorq	%rax,%r9
+	xorq	%rcx,%r12
+	andq	%rdi,%r10
+	andq	%rdi,%r13
+	andq	%rbp,%rbx
+	andq	%rbp,%rdx
+	xorq	%rbx,%r10
+	xorq	%rdx,%r13
+
+	xorq	%r10,%rax
+	xorq	%r13,%rcx
+	xorq	%r10,%r8
+	xorq	%r13,%r11
+	movq	%rax,%rbx
+	movq	%rcx,%rdx
+	xorq	%r10,%r9
+	xorq	%r13,%r12
+	shrq	$32,%rbx
+	shrq	$32,%rdx
+	xorq	%r8,%r10
+	xorq	%r11,%r13
+	roll	$8,%eax
+	roll	$8,%ecx
+	xorq	%r9,%r10
+	xorq	%r12,%r13
+
+	roll	$8,%ebx
+	roll	$8,%edx
+	xorl	%r10d,%eax
+	xorl	%r13d,%ecx
+	shrq	$32,%r10
+	shrq	$32,%r13
+	xorl	%r10d,%ebx
+	xorl	%r13d,%edx
+
+	movq	%r8,%r10
+	movq	%r11,%r13
+	shrq	$32,%r10
+	shrq	$32,%r13
+	roll	$24,%r8d
+	roll	$24,%r11d
+	roll	$24,%r10d
+	roll	$24,%r13d
+	xorl	%r8d,%eax
+	xorl	%r11d,%ecx
+	movq	%r9,%r8
+	movq	%r12,%r11
+	xorl	%r10d,%ebx
+	xorl	%r13d,%edx
+
+	movq	0(%r14),%rsi
+	shrq	$32,%r8
+	shrq	$32,%r11
+	movq	64(%r14),%rdi
+	roll	$16,%r9d
+	roll	$16,%r12d
+	movq	128(%r14),%rbp
+	roll	$16,%r8d
+	roll	$16,%r11d
+	movq	192(%r14),%r10
+	xorl	%r9d,%eax
+	xorl	%r12d,%ecx
+	movq	256(%r14),%r13
+	xorl	%r8d,%ebx
+	xorl	%r11d,%edx
+	jmp	.Ldec_loop_compact
+.align	16
+.Ldec_compact_done:
+	xorl	0(%r15),%eax
+	xorl	4(%r15),%ebx
+	xorl	8(%r15),%ecx
+	xorl	12(%r15),%edx
+.byte	0xf3,0xc3			
+.size	_x86_64_AES_decrypt_compact,.-_x86_64_AES_decrypt_compact
+.globl	AES_decrypt
+.type	AES_decrypt,@function
+.align	16
+.globl	asm_AES_decrypt
+.hidden	asm_AES_decrypt
+asm_AES_decrypt:
+AES_decrypt:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+
+
+	movq	%rsp,%r10
+	leaq	-63(%rdx),%rcx
+	andq	$-64,%rsp
+	subq	%rsp,%rcx
+	negq	%rcx
+	andq	$960,%rcx
+	subq	%rcx,%rsp
+	subq	$32,%rsp
+
+	movq	%rsi,16(%rsp)
+	movq	%r10,24(%rsp)
+.Ldec_prologue:
+
+	movq	%rdx,%r15
+	movl	240(%r15),%r13d
+
+	movl	0(%rdi),%eax
+	movl	4(%rdi),%ebx
+	movl	8(%rdi),%ecx
+	movl	12(%rdi),%edx
+
+	shll	$4,%r13d
+	leaq	(%r15,%r13,1),%rbp
+	movq	%r15,(%rsp)
+	movq	%rbp,8(%rsp)
+
+
+	leaq	.LAES_Td+2048(%rip),%r14
+	leaq	768(%rsp),%rbp
+	subq	%r14,%rbp
+	andq	$768,%rbp
+	leaq	(%r14,%rbp,1),%r14
+	shrq	$3,%rbp
+	addq	%rbp,%r14
+
+	call	_x86_64_AES_decrypt_compact
+
+	movq	16(%rsp),%r9
+	movq	24(%rsp),%rsi
+	movl	%eax,0(%r9)
+	movl	%ebx,4(%r9)
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+.Ldec_epilogue:
+	.byte	0xf3,0xc3
+.size	AES_decrypt,.-AES_decrypt
+.globl	AES_set_encrypt_key
+.type	AES_set_encrypt_key,@function
+.align	16
+AES_set_encrypt_key:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	subq	$8,%rsp
+.Lenc_key_prologue:
+
+	call	_x86_64_AES_set_encrypt_key
+
+	movq	8(%rsp),%r15
+	movq	16(%rsp),%r14
+	movq	24(%rsp),%r13
+	movq	32(%rsp),%r12
+	movq	40(%rsp),%rbp
+	movq	48(%rsp),%rbx
+	addq	$56,%rsp
+.Lenc_key_epilogue:
+	.byte	0xf3,0xc3
+.size	AES_set_encrypt_key,.-AES_set_encrypt_key
+
+.type	_x86_64_AES_set_encrypt_key,@function
+.align	16
+_x86_64_AES_set_encrypt_key:
+	movl	%esi,%ecx
+	movq	%rdi,%rsi
+	movq	%rdx,%rdi
+
+	testq	$-1,%rsi
+	jz	.Lbadpointer
+	testq	$-1,%rdi
+	jz	.Lbadpointer
+
+	leaq	.LAES_Te(%rip),%rbp
+	leaq	2048+128(%rbp),%rbp
+
+
+	movl	0-128(%rbp),%eax
+	movl	32-128(%rbp),%ebx
+	movl	64-128(%rbp),%r8d
+	movl	96-128(%rbp),%edx
+	movl	128-128(%rbp),%eax
+	movl	160-128(%rbp),%ebx
+	movl	192-128(%rbp),%r8d
+	movl	224-128(%rbp),%edx
+
+	cmpl	$128,%ecx
+	je	.L10rounds
+	cmpl	$192,%ecx
+	je	.L12rounds
+	cmpl	$256,%ecx
+	je	.L14rounds
+	movq	$-2,%rax
+	jmp	.Lexit
+
+.L10rounds:
+	movq	0(%rsi),%rax
+	movq	8(%rsi),%rdx
+	movq	%rax,0(%rdi)
+	movq	%rdx,8(%rdi)
+
+	shrq	$32,%rdx
+	xorl	%ecx,%ecx
+	jmp	.L10shortcut
+.align	4
+.L10loop:
+	movl	0(%rdi),%eax
+	movl	12(%rdi),%edx
+.L10shortcut:
+	movzbl	%dl,%esi
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	movzbl	%dh,%esi
+	shll	$24,%ebx
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	shrl	$16,%edx
+	movzbl	%dl,%esi
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	movzbl	%dh,%esi
+	shll	$8,%ebx
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	shll	$16,%ebx
+	xorl	%ebx,%eax
+
+	xorl	1024-128(%rbp,%rcx,4),%eax
+	movl	%eax,16(%rdi)
+	xorl	4(%rdi),%eax
+	movl	%eax,20(%rdi)
+	xorl	8(%rdi),%eax
+	movl	%eax,24(%rdi)
+	xorl	12(%rdi),%eax
+	movl	%eax,28(%rdi)
+	addl	$1,%ecx
+	leaq	16(%rdi),%rdi
+	cmpl	$10,%ecx
+	jl	.L10loop
+
+	movl	$10,80(%rdi)
+	xorq	%rax,%rax
+	jmp	.Lexit
+
+.L12rounds:
+	movq	0(%rsi),%rax
+	movq	8(%rsi),%rbx
+	movq	16(%rsi),%rdx
+	movq	%rax,0(%rdi)
+	movq	%rbx,8(%rdi)
+	movq	%rdx,16(%rdi)
+
+	shrq	$32,%rdx
+	xorl	%ecx,%ecx
+	jmp	.L12shortcut
+.align	4
+.L12loop:
+	movl	0(%rdi),%eax
+	movl	20(%rdi),%edx
+.L12shortcut:
+	movzbl	%dl,%esi
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	movzbl	%dh,%esi
+	shll	$24,%ebx
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	shrl	$16,%edx
+	movzbl	%dl,%esi
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	movzbl	%dh,%esi
+	shll	$8,%ebx
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	shll	$16,%ebx
+	xorl	%ebx,%eax
+
+	xorl	1024-128(%rbp,%rcx,4),%eax
+	movl	%eax,24(%rdi)
+	xorl	4(%rdi),%eax
+	movl	%eax,28(%rdi)
+	xorl	8(%rdi),%eax
+	movl	%eax,32(%rdi)
+	xorl	12(%rdi),%eax
+	movl	%eax,36(%rdi)
+
+	cmpl	$7,%ecx
+	je	.L12break
+	addl	$1,%ecx
+
+	xorl	16(%rdi),%eax
+	movl	%eax,40(%rdi)
+	xorl	20(%rdi),%eax
+	movl	%eax,44(%rdi)
+
+	leaq	24(%rdi),%rdi
+	jmp	.L12loop
+.L12break:
+	movl	$12,72(%rdi)
+	xorq	%rax,%rax
+	jmp	.Lexit
+
+.L14rounds:
+	movq	0(%rsi),%rax
+	movq	8(%rsi),%rbx
+	movq	16(%rsi),%rcx
+	movq	24(%rsi),%rdx
+	movq	%rax,0(%rdi)
+	movq	%rbx,8(%rdi)
+	movq	%rcx,16(%rdi)
+	movq	%rdx,24(%rdi)
+
+	shrq	$32,%rdx
+	xorl	%ecx,%ecx
+	jmp	.L14shortcut
+.align	4
+.L14loop:
+	movl	0(%rdi),%eax
+	movl	28(%rdi),%edx
+.L14shortcut:
+	movzbl	%dl,%esi
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	movzbl	%dh,%esi
+	shll	$24,%ebx
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	shrl	$16,%edx
+	movzbl	%dl,%esi
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	movzbl	%dh,%esi
+	shll	$8,%ebx
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	shll	$16,%ebx
+	xorl	%ebx,%eax
+
+	xorl	1024-128(%rbp,%rcx,4),%eax
+	movl	%eax,32(%rdi)
+	xorl	4(%rdi),%eax
+	movl	%eax,36(%rdi)
+	xorl	8(%rdi),%eax
+	movl	%eax,40(%rdi)
+	xorl	12(%rdi),%eax
+	movl	%eax,44(%rdi)
+
+	cmpl	$6,%ecx
+	je	.L14break
+	addl	$1,%ecx
+
+	movl	%eax,%edx
+	movl	16(%rdi),%eax
+	movzbl	%dl,%esi
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	movzbl	%dh,%esi
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	shrl	$16,%edx
+	shll	$8,%ebx
+	movzbl	%dl,%esi
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	movzbl	%dh,%esi
+	shll	$16,%ebx
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	shll	$24,%ebx
+	xorl	%ebx,%eax
+
+	movl	%eax,48(%rdi)
+	xorl	20(%rdi),%eax
+	movl	%eax,52(%rdi)
+	xorl	24(%rdi),%eax
+	movl	%eax,56(%rdi)
+	xorl	28(%rdi),%eax
+	movl	%eax,60(%rdi)
+
+	leaq	32(%rdi),%rdi
+	jmp	.L14loop
+.L14break:
+	movl	$14,48(%rdi)
+	xorq	%rax,%rax
+	jmp	.Lexit
+
+.Lbadpointer:
+	movq	$-1,%rax
+.Lexit:
+.byte	0xf3,0xc3			
+.size	_x86_64_AES_set_encrypt_key,.-_x86_64_AES_set_encrypt_key
+.globl	AES_set_decrypt_key
+.type	AES_set_decrypt_key,@function
+.align	16
+AES_set_decrypt_key:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	pushq	%rdx
+.Ldec_key_prologue:
+
+	call	_x86_64_AES_set_encrypt_key
+	movq	(%rsp),%r8
+	cmpl	$0,%eax
+	jne	.Labort
+
+	movl	240(%r8),%r14d
+	xorq	%rdi,%rdi
+	leaq	(%rdi,%r14,4),%rcx
+	movq	%r8,%rsi
+	leaq	(%r8,%rcx,4),%rdi
+.align	4
+.Linvert:
+	movq	0(%rsi),%rax
+	movq	8(%rsi),%rbx
+	movq	0(%rdi),%rcx
+	movq	8(%rdi),%rdx
+	movq	%rax,0(%rdi)
+	movq	%rbx,8(%rdi)
+	movq	%rcx,0(%rsi)
+	movq	%rdx,8(%rsi)
+	leaq	16(%rsi),%rsi
+	leaq	-16(%rdi),%rdi
+	cmpq	%rsi,%rdi
+	jne	.Linvert
+
+	leaq	.LAES_Te+2048+1024(%rip),%rax
+
+	movq	40(%rax),%rsi
+	movq	48(%rax),%rdi
+	movq	56(%rax),%rbp
+
+	movq	%r8,%r15
+	subl	$1,%r14d
+.align	4
+.Lpermute:
+	leaq	16(%r15),%r15
+	movq	0(%r15),%rax
+	movq	8(%r15),%rcx
+	movq	%rax,%rbx
+	movq	%rcx,%rdx
+	andq	%rsi,%rbx
+	andq	%rsi,%rdx
+	movq	%rbx,%r9
+	movq	%rdx,%r12
+	shrq	$7,%r9
+	leaq	(%rax,%rax,1),%r8
+	shrq	$7,%r12
+	leaq	(%rcx,%rcx,1),%r11
+	subq	%r9,%rbx
+	subq	%r12,%rdx
+	andq	%rdi,%r8
+	andq	%rdi,%r11
+	andq	%rbp,%rbx
+	andq	%rbp,%rdx
+	xorq	%r8,%rbx
+	xorq	%r11,%rdx
+	movq	%rbx,%r8
+	movq	%rdx,%r11
+
+	andq	%rsi,%rbx
+	andq	%rsi,%rdx
+	movq	%rbx,%r10
+	movq	%rdx,%r13
+	shrq	$7,%r10
+	leaq	(%r8,%r8,1),%r9
+	shrq	$7,%r13
+	leaq	(%r11,%r11,1),%r12
+	subq	%r10,%rbx
+	subq	%r13,%rdx
+	andq	%rdi,%r9
+	andq	%rdi,%r12
+	andq	%rbp,%rbx
+	andq	%rbp,%rdx
+	xorq	%r9,%rbx
+	xorq	%r12,%rdx
+	movq	%rbx,%r9
+	movq	%rdx,%r12
+
+	andq	%rsi,%rbx
+	andq	%rsi,%rdx
+	movq	%rbx,%r10
+	movq	%rdx,%r13
+	shrq	$7,%r10
+	xorq	%rax,%r8
+	shrq	$7,%r13
+	xorq	%rcx,%r11
+	subq	%r10,%rbx
+	subq	%r13,%rdx
+	leaq	(%r9,%r9,1),%r10
+	leaq	(%r12,%r12,1),%r13
+	xorq	%rax,%r9
+	xorq	%rcx,%r12
+	andq	%rdi,%r10
+	andq	%rdi,%r13
+	andq	%rbp,%rbx
+	andq	%rbp,%rdx
+	xorq	%rbx,%r10
+	xorq	%rdx,%r13
+
+	xorq	%r10,%rax
+	xorq	%r13,%rcx
+	xorq	%r10,%r8
+	xorq	%r13,%r11
+	movq	%rax,%rbx
+	movq	%rcx,%rdx
+	xorq	%r10,%r9
+	xorq	%r13,%r12
+	shrq	$32,%rbx
+	shrq	$32,%rdx
+	xorq	%r8,%r10
+	xorq	%r11,%r13
+	roll	$8,%eax
+	roll	$8,%ecx
+	xorq	%r9,%r10
+	xorq	%r12,%r13
+
+	roll	$8,%ebx
+	roll	$8,%edx
+	xorl	%r10d,%eax
+	xorl	%r13d,%ecx
+	shrq	$32,%r10
+	shrq	$32,%r13
+	xorl	%r10d,%ebx
+	xorl	%r13d,%edx
+
+	movq	%r8,%r10
+	movq	%r11,%r13
+	shrq	$32,%r10
+	shrq	$32,%r13
+	roll	$24,%r8d
+	roll	$24,%r11d
+	roll	$24,%r10d
+	roll	$24,%r13d
+	xorl	%r8d,%eax
+	xorl	%r11d,%ecx
+	movq	%r9,%r8
+	movq	%r12,%r11
+	xorl	%r10d,%ebx
+	xorl	%r13d,%edx
+
+
+	shrq	$32,%r8
+	shrq	$32,%r11
+
+	roll	$16,%r9d
+	roll	$16,%r12d
+
+	roll	$16,%r8d
+	roll	$16,%r11d
+
+	xorl	%r9d,%eax
+	xorl	%r12d,%ecx
+
+	xorl	%r8d,%ebx
+	xorl	%r11d,%edx
+	movl	%eax,0(%r15)
+	movl	%ebx,4(%r15)
+	movl	%ecx,8(%r15)
+	movl	%edx,12(%r15)
+	subl	$1,%r14d
+	jnz	.Lpermute
+
+	xorq	%rax,%rax
+.Labort:
+	movq	8(%rsp),%r15
+	movq	16(%rsp),%r14
+	movq	24(%rsp),%r13
+	movq	32(%rsp),%r12
+	movq	40(%rsp),%rbp
+	movq	48(%rsp),%rbx
+	addq	$56,%rsp
+.Ldec_key_epilogue:
+	.byte	0xf3,0xc3
+.size	AES_set_decrypt_key,.-AES_set_decrypt_key
+.globl	AES_cbc_encrypt
+.type	AES_cbc_encrypt,@function
+.align	16
+
+.globl	asm_AES_cbc_encrypt
+.hidden	asm_AES_cbc_encrypt
+asm_AES_cbc_encrypt:
+AES_cbc_encrypt:
+	cmpq	$0,%rdx
+	je	.Lcbc_epilogue
+	pushfq
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+.Lcbc_prologue:
+
+	cld
+	movl	%r9d,%r9d
+
+	leaq	.LAES_Te(%rip),%r14
+	cmpq	$0,%r9
+	jne	.Lcbc_picked_te
+	leaq	.LAES_Td(%rip),%r14
+.Lcbc_picked_te:
+
+	movl	OPENSSL_ia32cap_P(%rip),%r10d
+	cmpq	$512,%rdx
+	jb	.Lcbc_slow_prologue
+	testq	$15,%rdx
+	jnz	.Lcbc_slow_prologue
+	btl	$28,%r10d
+	jc	.Lcbc_slow_prologue
+
+
+	leaq	-88-248(%rsp),%r15
+	andq	$-64,%r15
+
+
+	movq	%r14,%r10
+	leaq	2304(%r14),%r11
+	movq	%r15,%r12
+	andq	$4095,%r10
+	andq	$4095,%r11
+	andq	$4095,%r12
+
+	cmpq	%r11,%r12
+	jb	.Lcbc_te_break_out
+	subq	%r11,%r12
+	subq	%r12,%r15
+	jmp	.Lcbc_te_ok
+.Lcbc_te_break_out:
+	subq	%r10,%r12
+	andq	$4095,%r12
+	addq	$320,%r12
+	subq	%r12,%r15
+.align	4
+.Lcbc_te_ok:
+
+	xchgq	%rsp,%r15
+
+	movq	%r15,16(%rsp)
+.Lcbc_fast_body:
+	movq	%rdi,24(%rsp)
+	movq	%rsi,32(%rsp)
+	movq	%rdx,40(%rsp)
+	movq	%rcx,48(%rsp)
+	movq	%r8,56(%rsp)
+	movl	$0,80+240(%rsp)
+	movq	%r8,%rbp
+	movq	%r9,%rbx
+	movq	%rsi,%r9
+	movq	%rdi,%r8
+	movq	%rcx,%r15
+
+	movl	240(%r15),%eax
+
+	movq	%r15,%r10
+	subq	%r14,%r10
+	andq	$4095,%r10
+	cmpq	$2304,%r10
+	jb	.Lcbc_do_ecopy
+	cmpq	$4096-248,%r10
+	jb	.Lcbc_skip_ecopy
+.align	4
+.Lcbc_do_ecopy:
+	movq	%r15,%rsi
+	leaq	80(%rsp),%rdi
+	leaq	80(%rsp),%r15
+	movl	$30,%ecx
+.long	0x90A548F3	
+	movl	%eax,(%rdi)
+.Lcbc_skip_ecopy:
+	movq	%r15,0(%rsp)
+
+	movl	$18,%ecx
+.align	4
+.Lcbc_prefetch_te:
+	movq	0(%r14),%r10
+	movq	32(%r14),%r11
+	movq	64(%r14),%r12
+	movq	96(%r14),%r13
+	leaq	128(%r14),%r14
+	subl	$1,%ecx
+	jnz	.Lcbc_prefetch_te
+	leaq	-2304(%r14),%r14
+
+	cmpq	$0,%rbx
+	je	.LFAST_DECRYPT
+
+
+	movl	0(%rbp),%eax
+	movl	4(%rbp),%ebx
+	movl	8(%rbp),%ecx
+	movl	12(%rbp),%edx
+
+.align	4
+.Lcbc_fast_enc_loop:
+	xorl	0(%r8),%eax
+	xorl	4(%r8),%ebx
+	xorl	8(%r8),%ecx
+	xorl	12(%r8),%edx
+	movq	0(%rsp),%r15
+	movq	%r8,24(%rsp)
+
+	call	_x86_64_AES_encrypt
+
+	movq	24(%rsp),%r8
+	movq	40(%rsp),%r10
+	movl	%eax,0(%r9)
+	movl	%ebx,4(%r9)
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+
+	leaq	16(%r8),%r8
+	leaq	16(%r9),%r9
+	subq	$16,%r10
+	testq	$-16,%r10
+	movq	%r10,40(%rsp)
+	jnz	.Lcbc_fast_enc_loop
+	movq	56(%rsp),%rbp
+	movl	%eax,0(%rbp)
+	movl	%ebx,4(%rbp)
+	movl	%ecx,8(%rbp)
+	movl	%edx,12(%rbp)
+
+	jmp	.Lcbc_fast_cleanup
+
+
+.align	16
+.LFAST_DECRYPT:
+	cmpq	%r8,%r9
+	je	.Lcbc_fast_dec_in_place
+
+	movq	%rbp,64(%rsp)
+.align	4
+.Lcbc_fast_dec_loop:
+	movl	0(%r8),%eax
+	movl	4(%r8),%ebx
+	movl	8(%r8),%ecx
+	movl	12(%r8),%edx
+	movq	0(%rsp),%r15
+	movq	%r8,24(%rsp)
+
+	call	_x86_64_AES_decrypt
+
+	movq	64(%rsp),%rbp
+	movq	24(%rsp),%r8
+	movq	40(%rsp),%r10
+	xorl	0(%rbp),%eax
+	xorl	4(%rbp),%ebx
+	xorl	8(%rbp),%ecx
+	xorl	12(%rbp),%edx
+	movq	%r8,%rbp
+
+	subq	$16,%r10
+	movq	%r10,40(%rsp)
+	movq	%rbp,64(%rsp)
+
+	movl	%eax,0(%r9)
+	movl	%ebx,4(%r9)
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+
+	leaq	16(%r8),%r8
+	leaq	16(%r9),%r9
+	jnz	.Lcbc_fast_dec_loop
+	movq	56(%rsp),%r12
+	movq	0(%rbp),%r10
+	movq	8(%rbp),%r11
+	movq	%r10,0(%r12)
+	movq	%r11,8(%r12)
+	jmp	.Lcbc_fast_cleanup
+
+.align	16
+.Lcbc_fast_dec_in_place:
+	movq	0(%rbp),%r10
+	movq	8(%rbp),%r11
+	movq	%r10,0+64(%rsp)
+	movq	%r11,8+64(%rsp)
+.align	4
+.Lcbc_fast_dec_in_place_loop:
+	movl	0(%r8),%eax
+	movl	4(%r8),%ebx
+	movl	8(%r8),%ecx
+	movl	12(%r8),%edx
+	movq	0(%rsp),%r15
+	movq	%r8,24(%rsp)
+
+	call	_x86_64_AES_decrypt
+
+	movq	24(%rsp),%r8
+	movq	40(%rsp),%r10
+	xorl	0+64(%rsp),%eax
+	xorl	4+64(%rsp),%ebx
+	xorl	8+64(%rsp),%ecx
+	xorl	12+64(%rsp),%edx
+
+	movq	0(%r8),%r11
+	movq	8(%r8),%r12
+	subq	$16,%r10
+	jz	.Lcbc_fast_dec_in_place_done
+
+	movq	%r11,0+64(%rsp)
+	movq	%r12,8+64(%rsp)
+
+	movl	%eax,0(%r9)
+	movl	%ebx,4(%r9)
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+
+	leaq	16(%r8),%r8
+	leaq	16(%r9),%r9
+	movq	%r10,40(%rsp)
+	jmp	.Lcbc_fast_dec_in_place_loop
+.Lcbc_fast_dec_in_place_done:
+	movq	56(%rsp),%rdi
+	movq	%r11,0(%rdi)
+	movq	%r12,8(%rdi)
+
+	movl	%eax,0(%r9)
+	movl	%ebx,4(%r9)
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+
+.align	4
+.Lcbc_fast_cleanup:
+	cmpl	$0,80+240(%rsp)
+	leaq	80(%rsp),%rdi
+	je	.Lcbc_exit
+	movl	$30,%ecx
+	xorq	%rax,%rax
+.long	0x90AB48F3	
+
+	jmp	.Lcbc_exit
+
+
+.align	16
+.Lcbc_slow_prologue:
+
+	leaq	-88(%rsp),%rbp
+	andq	$-64,%rbp
+
+	leaq	-88-63(%rcx),%r10
+	subq	%rbp,%r10
+	negq	%r10
+	andq	$960,%r10
+	subq	%r10,%rbp
+
+	xchgq	%rsp,%rbp
+
+	movq	%rbp,16(%rsp)
+.Lcbc_slow_body:
+
+
+
+
+	movq	%r8,56(%rsp)
+	movq	%r8,%rbp
+	movq	%r9,%rbx
+	movq	%rsi,%r9
+	movq	%rdi,%r8
+	movq	%rcx,%r15
+	movq	%rdx,%r10
+
+	movl	240(%r15),%eax
+	movq	%r15,0(%rsp)
+	shll	$4,%eax
+	leaq	(%r15,%rax,1),%rax
+	movq	%rax,8(%rsp)
+
+
+	leaq	2048(%r14),%r14
+	leaq	768-8(%rsp),%rax
+	subq	%r14,%rax
+	andq	$768,%rax
+	leaq	(%r14,%rax,1),%r14
+
+	cmpq	$0,%rbx
+	je	.LSLOW_DECRYPT
+
+
+	testq	$-16,%r10
+	movl	0(%rbp),%eax
+	movl	4(%rbp),%ebx
+	movl	8(%rbp),%ecx
+	movl	12(%rbp),%edx
+	jz	.Lcbc_slow_enc_tail	
+
+.align	4
+.Lcbc_slow_enc_loop:
+	xorl	0(%r8),%eax
+	xorl	4(%r8),%ebx
+	xorl	8(%r8),%ecx
+	xorl	12(%r8),%edx
+	movq	0(%rsp),%r15
+	movq	%r8,24(%rsp)
+	movq	%r9,32(%rsp)
+	movq	%r10,40(%rsp)
+
+	call	_x86_64_AES_encrypt_compact
+
+	movq	24(%rsp),%r8
+	movq	32(%rsp),%r9
+	movq	40(%rsp),%r10
+	movl	%eax,0(%r9)
+	movl	%ebx,4(%r9)
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+
+	leaq	16(%r8),%r8
+	leaq	16(%r9),%r9
+	subq	$16,%r10
+	testq	$-16,%r10
+	jnz	.Lcbc_slow_enc_loop
+	testq	$15,%r10
+	jnz	.Lcbc_slow_enc_tail
+	movq	56(%rsp),%rbp
+	movl	%eax,0(%rbp)
+	movl	%ebx,4(%rbp)
+	movl	%ecx,8(%rbp)
+	movl	%edx,12(%rbp)
+
+	jmp	.Lcbc_exit
+
+.align	4
+.Lcbc_slow_enc_tail:
+	movq	%rax,%r11
+	movq	%rcx,%r12
+	movq	%r10,%rcx
+	movq	%r8,%rsi
+	movq	%r9,%rdi
+.long	0x9066A4F3		
+	movq	$16,%rcx
+	subq	%r10,%rcx
+	xorq	%rax,%rax
+.long	0x9066AAF3		
+	movq	%r9,%r8
+	movq	$16,%r10
+	movq	%r11,%rax
+	movq	%r12,%rcx
+	jmp	.Lcbc_slow_enc_loop	
+
+.align	16
+.LSLOW_DECRYPT:
+	shrq	$3,%rax
+	addq	%rax,%r14
+
+	movq	0(%rbp),%r11
+	movq	8(%rbp),%r12
+	movq	%r11,0+64(%rsp)
+	movq	%r12,8+64(%rsp)
+
+.align	4
+.Lcbc_slow_dec_loop:
+	movl	0(%r8),%eax
+	movl	4(%r8),%ebx
+	movl	8(%r8),%ecx
+	movl	12(%r8),%edx
+	movq	0(%rsp),%r15
+	movq	%r8,24(%rsp)
+	movq	%r9,32(%rsp)
+	movq	%r10,40(%rsp)
+
+	call	_x86_64_AES_decrypt_compact
+
+	movq	24(%rsp),%r8
+	movq	32(%rsp),%r9
+	movq	40(%rsp),%r10
+	xorl	0+64(%rsp),%eax
+	xorl	4+64(%rsp),%ebx
+	xorl	8+64(%rsp),%ecx
+	xorl	12+64(%rsp),%edx
+
+	movq	0(%r8),%r11
+	movq	8(%r8),%r12
+	subq	$16,%r10
+	jc	.Lcbc_slow_dec_partial
+	jz	.Lcbc_slow_dec_done
+
+	movq	%r11,0+64(%rsp)
+	movq	%r12,8+64(%rsp)
+
+	movl	%eax,0(%r9)
+	movl	%ebx,4(%r9)
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+
+	leaq	16(%r8),%r8
+	leaq	16(%r9),%r9
+	jmp	.Lcbc_slow_dec_loop
+.Lcbc_slow_dec_done:
+	movq	56(%rsp),%rdi
+	movq	%r11,0(%rdi)
+	movq	%r12,8(%rdi)
+
+	movl	%eax,0(%r9)
+	movl	%ebx,4(%r9)
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+
+	jmp	.Lcbc_exit
+
+.align	4
+.Lcbc_slow_dec_partial:
+	movq	56(%rsp),%rdi
+	movq	%r11,0(%rdi)
+	movq	%r12,8(%rdi)
+
+	movl	%eax,0+64(%rsp)
+	movl	%ebx,4+64(%rsp)
+	movl	%ecx,8+64(%rsp)
+	movl	%edx,12+64(%rsp)
+
+	movq	%r9,%rdi
+	leaq	64(%rsp),%rsi
+	leaq	16(%r10),%rcx
+.long	0x9066A4F3	
+	jmp	.Lcbc_exit
+
+.align	16
+.Lcbc_exit:
+	movq	16(%rsp),%rsi
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+.Lcbc_popfq:
+	popfq
+.Lcbc_epilogue:
+	.byte	0xf3,0xc3
+.size	AES_cbc_encrypt,.-AES_cbc_encrypt
+.align	64
+.LAES_Te:
+.long	0xa56363c6,0xa56363c6
+.long	0x847c7cf8,0x847c7cf8
+.long	0x997777ee,0x997777ee
+.long	0x8d7b7bf6,0x8d7b7bf6
+.long	0x0df2f2ff,0x0df2f2ff
+.long	0xbd6b6bd6,0xbd6b6bd6
+.long	0xb16f6fde,0xb16f6fde
+.long	0x54c5c591,0x54c5c591
+.long	0x50303060,0x50303060
+.long	0x03010102,0x03010102
+.long	0xa96767ce,0xa96767ce
+.long	0x7d2b2b56,0x7d2b2b56
+.long	0x19fefee7,0x19fefee7
+.long	0x62d7d7b5,0x62d7d7b5
+.long	0xe6abab4d,0xe6abab4d
+.long	0x9a7676ec,0x9a7676ec
+.long	0x45caca8f,0x45caca8f
+.long	0x9d82821f,0x9d82821f
+.long	0x40c9c989,0x40c9c989
+.long	0x877d7dfa,0x877d7dfa
+.long	0x15fafaef,0x15fafaef
+.long	0xeb5959b2,0xeb5959b2
+.long	0xc947478e,0xc947478e
+.long	0x0bf0f0fb,0x0bf0f0fb
+.long	0xecadad41,0xecadad41
+.long	0x67d4d4b3,0x67d4d4b3
+.long	0xfda2a25f,0xfda2a25f
+.long	0xeaafaf45,0xeaafaf45
+.long	0xbf9c9c23,0xbf9c9c23
+.long	0xf7a4a453,0xf7a4a453
+.long	0x967272e4,0x967272e4
+.long	0x5bc0c09b,0x5bc0c09b
+.long	0xc2b7b775,0xc2b7b775
+.long	0x1cfdfde1,0x1cfdfde1
+.long	0xae93933d,0xae93933d
+.long	0x6a26264c,0x6a26264c
+.long	0x5a36366c,0x5a36366c
+.long	0x413f3f7e,0x413f3f7e
+.long	0x02f7f7f5,0x02f7f7f5
+.long	0x4fcccc83,0x4fcccc83
+.long	0x5c343468,0x5c343468
+.long	0xf4a5a551,0xf4a5a551
+.long	0x34e5e5d1,0x34e5e5d1
+.long	0x08f1f1f9,0x08f1f1f9
+.long	0x937171e2,0x937171e2
+.long	0x73d8d8ab,0x73d8d8ab
+.long	0x53313162,0x53313162
+.long	0x3f15152a,0x3f15152a
+.long	0x0c040408,0x0c040408
+.long	0x52c7c795,0x52c7c795
+.long	0x65232346,0x65232346
+.long	0x5ec3c39d,0x5ec3c39d
+.long	0x28181830,0x28181830
+.long	0xa1969637,0xa1969637
+.long	0x0f05050a,0x0f05050a
+.long	0xb59a9a2f,0xb59a9a2f
+.long	0x0907070e,0x0907070e
+.long	0x36121224,0x36121224
+.long	0x9b80801b,0x9b80801b
+.long	0x3de2e2df,0x3de2e2df
+.long	0x26ebebcd,0x26ebebcd
+.long	0x6927274e,0x6927274e
+.long	0xcdb2b27f,0xcdb2b27f
+.long	0x9f7575ea,0x9f7575ea
+.long	0x1b090912,0x1b090912
+.long	0x9e83831d,0x9e83831d
+.long	0x742c2c58,0x742c2c58
+.long	0x2e1a1a34,0x2e1a1a34
+.long	0x2d1b1b36,0x2d1b1b36
+.long	0xb26e6edc,0xb26e6edc
+.long	0xee5a5ab4,0xee5a5ab4
+.long	0xfba0a05b,0xfba0a05b
+.long	0xf65252a4,0xf65252a4
+.long	0x4d3b3b76,0x4d3b3b76
+.long	0x61d6d6b7,0x61d6d6b7
+.long	0xceb3b37d,0xceb3b37d
+.long	0x7b292952,0x7b292952
+.long	0x3ee3e3dd,0x3ee3e3dd
+.long	0x712f2f5e,0x712f2f5e
+.long	0x97848413,0x97848413
+.long	0xf55353a6,0xf55353a6
+.long	0x68d1d1b9,0x68d1d1b9
+.long	0x00000000,0x00000000
+.long	0x2cededc1,0x2cededc1
+.long	0x60202040,0x60202040
+.long	0x1ffcfce3,0x1ffcfce3
+.long	0xc8b1b179,0xc8b1b179
+.long	0xed5b5bb6,0xed5b5bb6
+.long	0xbe6a6ad4,0xbe6a6ad4
+.long	0x46cbcb8d,0x46cbcb8d
+.long	0xd9bebe67,0xd9bebe67
+.long	0x4b393972,0x4b393972
+.long	0xde4a4a94,0xde4a4a94
+.long	0xd44c4c98,0xd44c4c98
+.long	0xe85858b0,0xe85858b0
+.long	0x4acfcf85,0x4acfcf85
+.long	0x6bd0d0bb,0x6bd0d0bb
+.long	0x2aefefc5,0x2aefefc5
+.long	0xe5aaaa4f,0xe5aaaa4f
+.long	0x16fbfbed,0x16fbfbed
+.long	0xc5434386,0xc5434386
+.long	0xd74d4d9a,0xd74d4d9a
+.long	0x55333366,0x55333366
+.long	0x94858511,0x94858511
+.long	0xcf45458a,0xcf45458a
+.long	0x10f9f9e9,0x10f9f9e9
+.long	0x06020204,0x06020204
+.long	0x817f7ffe,0x817f7ffe
+.long	0xf05050a0,0xf05050a0
+.long	0x443c3c78,0x443c3c78
+.long	0xba9f9f25,0xba9f9f25
+.long	0xe3a8a84b,0xe3a8a84b
+.long	0xf35151a2,0xf35151a2
+.long	0xfea3a35d,0xfea3a35d
+.long	0xc0404080,0xc0404080
+.long	0x8a8f8f05,0x8a8f8f05
+.long	0xad92923f,0xad92923f
+.long	0xbc9d9d21,0xbc9d9d21
+.long	0x48383870,0x48383870
+.long	0x04f5f5f1,0x04f5f5f1
+.long	0xdfbcbc63,0xdfbcbc63
+.long	0xc1b6b677,0xc1b6b677
+.long	0x75dadaaf,0x75dadaaf
+.long	0x63212142,0x63212142
+.long	0x30101020,0x30101020
+.long	0x1affffe5,0x1affffe5
+.long	0x0ef3f3fd,0x0ef3f3fd
+.long	0x6dd2d2bf,0x6dd2d2bf
+.long	0x4ccdcd81,0x4ccdcd81
+.long	0x140c0c18,0x140c0c18
+.long	0x35131326,0x35131326
+.long	0x2fececc3,0x2fececc3
+.long	0xe15f5fbe,0xe15f5fbe
+.long	0xa2979735,0xa2979735
+.long	0xcc444488,0xcc444488
+.long	0x3917172e,0x3917172e
+.long	0x57c4c493,0x57c4c493
+.long	0xf2a7a755,0xf2a7a755
+.long	0x827e7efc,0x827e7efc
+.long	0x473d3d7a,0x473d3d7a
+.long	0xac6464c8,0xac6464c8
+.long	0xe75d5dba,0xe75d5dba
+.long	0x2b191932,0x2b191932
+.long	0x957373e6,0x957373e6
+.long	0xa06060c0,0xa06060c0
+.long	0x98818119,0x98818119
+.long	0xd14f4f9e,0xd14f4f9e
+.long	0x7fdcdca3,0x7fdcdca3
+.long	0x66222244,0x66222244
+.long	0x7e2a2a54,0x7e2a2a54
+.long	0xab90903b,0xab90903b
+.long	0x8388880b,0x8388880b
+.long	0xca46468c,0xca46468c
+.long	0x29eeeec7,0x29eeeec7
+.long	0xd3b8b86b,0xd3b8b86b
+.long	0x3c141428,0x3c141428
+.long	0x79dedea7,0x79dedea7
+.long	0xe25e5ebc,0xe25e5ebc
+.long	0x1d0b0b16,0x1d0b0b16
+.long	0x76dbdbad,0x76dbdbad
+.long	0x3be0e0db,0x3be0e0db
+.long	0x56323264,0x56323264
+.long	0x4e3a3a74,0x4e3a3a74
+.long	0x1e0a0a14,0x1e0a0a14
+.long	0xdb494992,0xdb494992
+.long	0x0a06060c,0x0a06060c
+.long	0x6c242448,0x6c242448
+.long	0xe45c5cb8,0xe45c5cb8
+.long	0x5dc2c29f,0x5dc2c29f
+.long	0x6ed3d3bd,0x6ed3d3bd
+.long	0xefacac43,0xefacac43
+.long	0xa66262c4,0xa66262c4
+.long	0xa8919139,0xa8919139
+.long	0xa4959531,0xa4959531
+.long	0x37e4e4d3,0x37e4e4d3
+.long	0x8b7979f2,0x8b7979f2
+.long	0x32e7e7d5,0x32e7e7d5
+.long	0x43c8c88b,0x43c8c88b
+.long	0x5937376e,0x5937376e
+.long	0xb76d6dda,0xb76d6dda
+.long	0x8c8d8d01,0x8c8d8d01
+.long	0x64d5d5b1,0x64d5d5b1
+.long	0xd24e4e9c,0xd24e4e9c
+.long	0xe0a9a949,0xe0a9a949
+.long	0xb46c6cd8,0xb46c6cd8
+.long	0xfa5656ac,0xfa5656ac
+.long	0x07f4f4f3,0x07f4f4f3
+.long	0x25eaeacf,0x25eaeacf
+.long	0xaf6565ca,0xaf6565ca
+.long	0x8e7a7af4,0x8e7a7af4
+.long	0xe9aeae47,0xe9aeae47
+.long	0x18080810,0x18080810
+.long	0xd5baba6f,0xd5baba6f
+.long	0x887878f0,0x887878f0
+.long	0x6f25254a,0x6f25254a
+.long	0x722e2e5c,0x722e2e5c
+.long	0x241c1c38,0x241c1c38
+.long	0xf1a6a657,0xf1a6a657
+.long	0xc7b4b473,0xc7b4b473
+.long	0x51c6c697,0x51c6c697
+.long	0x23e8e8cb,0x23e8e8cb
+.long	0x7cdddda1,0x7cdddda1
+.long	0x9c7474e8,0x9c7474e8
+.long	0x211f1f3e,0x211f1f3e
+.long	0xdd4b4b96,0xdd4b4b96
+.long	0xdcbdbd61,0xdcbdbd61
+.long	0x868b8b0d,0x868b8b0d
+.long	0x858a8a0f,0x858a8a0f
+.long	0x907070e0,0x907070e0
+.long	0x423e3e7c,0x423e3e7c
+.long	0xc4b5b571,0xc4b5b571
+.long	0xaa6666cc,0xaa6666cc
+.long	0xd8484890,0xd8484890
+.long	0x05030306,0x05030306
+.long	0x01f6f6f7,0x01f6f6f7
+.long	0x120e0e1c,0x120e0e1c
+.long	0xa36161c2,0xa36161c2
+.long	0x5f35356a,0x5f35356a
+.long	0xf95757ae,0xf95757ae
+.long	0xd0b9b969,0xd0b9b969
+.long	0x91868617,0x91868617
+.long	0x58c1c199,0x58c1c199
+.long	0x271d1d3a,0x271d1d3a
+.long	0xb99e9e27,0xb99e9e27
+.long	0x38e1e1d9,0x38e1e1d9
+.long	0x13f8f8eb,0x13f8f8eb
+.long	0xb398982b,0xb398982b
+.long	0x33111122,0x33111122
+.long	0xbb6969d2,0xbb6969d2
+.long	0x70d9d9a9,0x70d9d9a9
+.long	0x898e8e07,0x898e8e07
+.long	0xa7949433,0xa7949433
+.long	0xb69b9b2d,0xb69b9b2d
+.long	0x221e1e3c,0x221e1e3c
+.long	0x92878715,0x92878715
+.long	0x20e9e9c9,0x20e9e9c9
+.long	0x49cece87,0x49cece87
+.long	0xff5555aa,0xff5555aa
+.long	0x78282850,0x78282850
+.long	0x7adfdfa5,0x7adfdfa5
+.long	0x8f8c8c03,0x8f8c8c03
+.long	0xf8a1a159,0xf8a1a159
+.long	0x80898909,0x80898909
+.long	0x170d0d1a,0x170d0d1a
+.long	0xdabfbf65,0xdabfbf65
+.long	0x31e6e6d7,0x31e6e6d7
+.long	0xc6424284,0xc6424284
+.long	0xb86868d0,0xb86868d0
+.long	0xc3414182,0xc3414182
+.long	0xb0999929,0xb0999929
+.long	0x772d2d5a,0x772d2d5a
+.long	0x110f0f1e,0x110f0f1e
+.long	0xcbb0b07b,0xcbb0b07b
+.long	0xfc5454a8,0xfc5454a8
+.long	0xd6bbbb6d,0xd6bbbb6d
+.long	0x3a16162c,0x3a16162c
+.byte	0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5
+.byte	0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76
+.byte	0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0
+.byte	0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0
+.byte	0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc
+.byte	0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15
+.byte	0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a
+.byte	0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75
+.byte	0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0
+.byte	0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84
+.byte	0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b
+.byte	0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf
+.byte	0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85
+.byte	0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8
+.byte	0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5
+.byte	0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2
+.byte	0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17
+.byte	0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73
+.byte	0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88
+.byte	0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb
+.byte	0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c
+.byte	0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79
+.byte	0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9
+.byte	0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08
+.byte	0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6
+.byte	0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a
+.byte	0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e
+.byte	0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e
+.byte	0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94
+.byte	0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf
+.byte	0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68
+.byte	0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
+.byte	0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5
+.byte	0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76
+.byte	0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0
+.byte	0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0
+.byte	0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc
+.byte	0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15
+.byte	0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a
+.byte	0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75
+.byte	0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0
+.byte	0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84
+.byte	0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b
+.byte	0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf
+.byte	0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85
+.byte	0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8
+.byte	0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5
+.byte	0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2
+.byte	0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17
+.byte	0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73
+.byte	0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88
+.byte	0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb
+.byte	0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c
+.byte	0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79
+.byte	0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9
+.byte	0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08
+.byte	0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6
+.byte	0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a
+.byte	0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e
+.byte	0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e
+.byte	0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94
+.byte	0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf
+.byte	0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68
+.byte	0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
+.byte	0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5
+.byte	0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76
+.byte	0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0
+.byte	0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0
+.byte	0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc
+.byte	0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15
+.byte	0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a
+.byte	0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75
+.byte	0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0
+.byte	0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84
+.byte	0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b
+.byte	0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf
+.byte	0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85
+.byte	0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8
+.byte	0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5
+.byte	0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2
+.byte	0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17
+.byte	0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73
+.byte	0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88
+.byte	0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb
+.byte	0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c
+.byte	0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79
+.byte	0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9
+.byte	0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08
+.byte	0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6
+.byte	0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a
+.byte	0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e
+.byte	0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e
+.byte	0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94
+.byte	0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf
+.byte	0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68
+.byte	0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
+.byte	0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5
+.byte	0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76
+.byte	0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0
+.byte	0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0
+.byte	0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc
+.byte	0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15
+.byte	0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a
+.byte	0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75
+.byte	0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0
+.byte	0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84
+.byte	0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b
+.byte	0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf
+.byte	0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85
+.byte	0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8
+.byte	0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5
+.byte	0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2
+.byte	0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17
+.byte	0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73
+.byte	0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88
+.byte	0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb
+.byte	0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c
+.byte	0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79
+.byte	0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9
+.byte	0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08
+.byte	0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6
+.byte	0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a
+.byte	0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e
+.byte	0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e
+.byte	0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94
+.byte	0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf
+.byte	0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68
+.byte	0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
+.long	0x00000001, 0x00000002, 0x00000004, 0x00000008
+.long	0x00000010, 0x00000020, 0x00000040, 0x00000080
+.long	0x0000001b, 0x00000036, 0x80808080, 0x80808080
+.long	0xfefefefe, 0xfefefefe, 0x1b1b1b1b, 0x1b1b1b1b
+.align	64
+.LAES_Td:
+.long	0x50a7f451,0x50a7f451
+.long	0x5365417e,0x5365417e
+.long	0xc3a4171a,0xc3a4171a
+.long	0x965e273a,0x965e273a
+.long	0xcb6bab3b,0xcb6bab3b
+.long	0xf1459d1f,0xf1459d1f
+.long	0xab58faac,0xab58faac
+.long	0x9303e34b,0x9303e34b
+.long	0x55fa3020,0x55fa3020
+.long	0xf66d76ad,0xf66d76ad
+.long	0x9176cc88,0x9176cc88
+.long	0x254c02f5,0x254c02f5
+.long	0xfcd7e54f,0xfcd7e54f
+.long	0xd7cb2ac5,0xd7cb2ac5
+.long	0x80443526,0x80443526
+.long	0x8fa362b5,0x8fa362b5
+.long	0x495ab1de,0x495ab1de
+.long	0x671bba25,0x671bba25
+.long	0x980eea45,0x980eea45
+.long	0xe1c0fe5d,0xe1c0fe5d
+.long	0x02752fc3,0x02752fc3
+.long	0x12f04c81,0x12f04c81
+.long	0xa397468d,0xa397468d
+.long	0xc6f9d36b,0xc6f9d36b
+.long	0xe75f8f03,0xe75f8f03
+.long	0x959c9215,0x959c9215
+.long	0xeb7a6dbf,0xeb7a6dbf
+.long	0xda595295,0xda595295
+.long	0x2d83bed4,0x2d83bed4
+.long	0xd3217458,0xd3217458
+.long	0x2969e049,0x2969e049
+.long	0x44c8c98e,0x44c8c98e
+.long	0x6a89c275,0x6a89c275
+.long	0x78798ef4,0x78798ef4
+.long	0x6b3e5899,0x6b3e5899
+.long	0xdd71b927,0xdd71b927
+.long	0xb64fe1be,0xb64fe1be
+.long	0x17ad88f0,0x17ad88f0
+.long	0x66ac20c9,0x66ac20c9
+.long	0xb43ace7d,0xb43ace7d
+.long	0x184adf63,0x184adf63
+.long	0x82311ae5,0x82311ae5
+.long	0x60335197,0x60335197
+.long	0x457f5362,0x457f5362
+.long	0xe07764b1,0xe07764b1
+.long	0x84ae6bbb,0x84ae6bbb
+.long	0x1ca081fe,0x1ca081fe
+.long	0x942b08f9,0x942b08f9
+.long	0x58684870,0x58684870
+.long	0x19fd458f,0x19fd458f
+.long	0x876cde94,0x876cde94
+.long	0xb7f87b52,0xb7f87b52
+.long	0x23d373ab,0x23d373ab
+.long	0xe2024b72,0xe2024b72
+.long	0x578f1fe3,0x578f1fe3
+.long	0x2aab5566,0x2aab5566
+.long	0x0728ebb2,0x0728ebb2
+.long	0x03c2b52f,0x03c2b52f
+.long	0x9a7bc586,0x9a7bc586
+.long	0xa50837d3,0xa50837d3
+.long	0xf2872830,0xf2872830
+.long	0xb2a5bf23,0xb2a5bf23
+.long	0xba6a0302,0xba6a0302
+.long	0x5c8216ed,0x5c8216ed
+.long	0x2b1ccf8a,0x2b1ccf8a
+.long	0x92b479a7,0x92b479a7
+.long	0xf0f207f3,0xf0f207f3
+.long	0xa1e2694e,0xa1e2694e
+.long	0xcdf4da65,0xcdf4da65
+.long	0xd5be0506,0xd5be0506
+.long	0x1f6234d1,0x1f6234d1
+.long	0x8afea6c4,0x8afea6c4
+.long	0x9d532e34,0x9d532e34
+.long	0xa055f3a2,0xa055f3a2
+.long	0x32e18a05,0x32e18a05
+.long	0x75ebf6a4,0x75ebf6a4
+.long	0x39ec830b,0x39ec830b
+.long	0xaaef6040,0xaaef6040
+.long	0x069f715e,0x069f715e
+.long	0x51106ebd,0x51106ebd
+.long	0xf98a213e,0xf98a213e
+.long	0x3d06dd96,0x3d06dd96
+.long	0xae053edd,0xae053edd
+.long	0x46bde64d,0x46bde64d
+.long	0xb58d5491,0xb58d5491
+.long	0x055dc471,0x055dc471
+.long	0x6fd40604,0x6fd40604
+.long	0xff155060,0xff155060
+.long	0x24fb9819,0x24fb9819
+.long	0x97e9bdd6,0x97e9bdd6
+.long	0xcc434089,0xcc434089
+.long	0x779ed967,0x779ed967
+.long	0xbd42e8b0,0xbd42e8b0
+.long	0x888b8907,0x888b8907
+.long	0x385b19e7,0x385b19e7
+.long	0xdbeec879,0xdbeec879
+.long	0x470a7ca1,0x470a7ca1
+.long	0xe90f427c,0xe90f427c
+.long	0xc91e84f8,0xc91e84f8
+.long	0x00000000,0x00000000
+.long	0x83868009,0x83868009
+.long	0x48ed2b32,0x48ed2b32
+.long	0xac70111e,0xac70111e
+.long	0x4e725a6c,0x4e725a6c
+.long	0xfbff0efd,0xfbff0efd
+.long	0x5638850f,0x5638850f
+.long	0x1ed5ae3d,0x1ed5ae3d
+.long	0x27392d36,0x27392d36
+.long	0x64d90f0a,0x64d90f0a
+.long	0x21a65c68,0x21a65c68
+.long	0xd1545b9b,0xd1545b9b
+.long	0x3a2e3624,0x3a2e3624
+.long	0xb1670a0c,0xb1670a0c
+.long	0x0fe75793,0x0fe75793
+.long	0xd296eeb4,0xd296eeb4
+.long	0x9e919b1b,0x9e919b1b
+.long	0x4fc5c080,0x4fc5c080
+.long	0xa220dc61,0xa220dc61
+.long	0x694b775a,0x694b775a
+.long	0x161a121c,0x161a121c
+.long	0x0aba93e2,0x0aba93e2
+.long	0xe52aa0c0,0xe52aa0c0
+.long	0x43e0223c,0x43e0223c
+.long	0x1d171b12,0x1d171b12
+.long	0x0b0d090e,0x0b0d090e
+.long	0xadc78bf2,0xadc78bf2
+.long	0xb9a8b62d,0xb9a8b62d
+.long	0xc8a91e14,0xc8a91e14
+.long	0x8519f157,0x8519f157
+.long	0x4c0775af,0x4c0775af
+.long	0xbbdd99ee,0xbbdd99ee
+.long	0xfd607fa3,0xfd607fa3
+.long	0x9f2601f7,0x9f2601f7
+.long	0xbcf5725c,0xbcf5725c
+.long	0xc53b6644,0xc53b6644
+.long	0x347efb5b,0x347efb5b
+.long	0x7629438b,0x7629438b
+.long	0xdcc623cb,0xdcc623cb
+.long	0x68fcedb6,0x68fcedb6
+.long	0x63f1e4b8,0x63f1e4b8
+.long	0xcadc31d7,0xcadc31d7
+.long	0x10856342,0x10856342
+.long	0x40229713,0x40229713
+.long	0x2011c684,0x2011c684
+.long	0x7d244a85,0x7d244a85
+.long	0xf83dbbd2,0xf83dbbd2
+.long	0x1132f9ae,0x1132f9ae
+.long	0x6da129c7,0x6da129c7
+.long	0x4b2f9e1d,0x4b2f9e1d
+.long	0xf330b2dc,0xf330b2dc
+.long	0xec52860d,0xec52860d
+.long	0xd0e3c177,0xd0e3c177
+.long	0x6c16b32b,0x6c16b32b
+.long	0x99b970a9,0x99b970a9
+.long	0xfa489411,0xfa489411
+.long	0x2264e947,0x2264e947
+.long	0xc48cfca8,0xc48cfca8
+.long	0x1a3ff0a0,0x1a3ff0a0
+.long	0xd82c7d56,0xd82c7d56
+.long	0xef903322,0xef903322
+.long	0xc74e4987,0xc74e4987
+.long	0xc1d138d9,0xc1d138d9
+.long	0xfea2ca8c,0xfea2ca8c
+.long	0x360bd498,0x360bd498
+.long	0xcf81f5a6,0xcf81f5a6
+.long	0x28de7aa5,0x28de7aa5
+.long	0x268eb7da,0x268eb7da
+.long	0xa4bfad3f,0xa4bfad3f
+.long	0xe49d3a2c,0xe49d3a2c
+.long	0x0d927850,0x0d927850
+.long	0x9bcc5f6a,0x9bcc5f6a
+.long	0x62467e54,0x62467e54
+.long	0xc2138df6,0xc2138df6
+.long	0xe8b8d890,0xe8b8d890
+.long	0x5ef7392e,0x5ef7392e
+.long	0xf5afc382,0xf5afc382
+.long	0xbe805d9f,0xbe805d9f
+.long	0x7c93d069,0x7c93d069
+.long	0xa92dd56f,0xa92dd56f
+.long	0xb31225cf,0xb31225cf
+.long	0x3b99acc8,0x3b99acc8
+.long	0xa77d1810,0xa77d1810
+.long	0x6e639ce8,0x6e639ce8
+.long	0x7bbb3bdb,0x7bbb3bdb
+.long	0x097826cd,0x097826cd
+.long	0xf418596e,0xf418596e
+.long	0x01b79aec,0x01b79aec
+.long	0xa89a4f83,0xa89a4f83
+.long	0x656e95e6,0x656e95e6
+.long	0x7ee6ffaa,0x7ee6ffaa
+.long	0x08cfbc21,0x08cfbc21
+.long	0xe6e815ef,0xe6e815ef
+.long	0xd99be7ba,0xd99be7ba
+.long	0xce366f4a,0xce366f4a
+.long	0xd4099fea,0xd4099fea
+.long	0xd67cb029,0xd67cb029
+.long	0xafb2a431,0xafb2a431
+.long	0x31233f2a,0x31233f2a
+.long	0x3094a5c6,0x3094a5c6
+.long	0xc066a235,0xc066a235
+.long	0x37bc4e74,0x37bc4e74
+.long	0xa6ca82fc,0xa6ca82fc
+.long	0xb0d090e0,0xb0d090e0
+.long	0x15d8a733,0x15d8a733
+.long	0x4a9804f1,0x4a9804f1
+.long	0xf7daec41,0xf7daec41
+.long	0x0e50cd7f,0x0e50cd7f
+.long	0x2ff69117,0x2ff69117
+.long	0x8dd64d76,0x8dd64d76
+.long	0x4db0ef43,0x4db0ef43
+.long	0x544daacc,0x544daacc
+.long	0xdf0496e4,0xdf0496e4
+.long	0xe3b5d19e,0xe3b5d19e
+.long	0x1b886a4c,0x1b886a4c
+.long	0xb81f2cc1,0xb81f2cc1
+.long	0x7f516546,0x7f516546
+.long	0x04ea5e9d,0x04ea5e9d
+.long	0x5d358c01,0x5d358c01
+.long	0x737487fa,0x737487fa
+.long	0x2e410bfb,0x2e410bfb
+.long	0x5a1d67b3,0x5a1d67b3
+.long	0x52d2db92,0x52d2db92
+.long	0x335610e9,0x335610e9
+.long	0x1347d66d,0x1347d66d
+.long	0x8c61d79a,0x8c61d79a
+.long	0x7a0ca137,0x7a0ca137
+.long	0x8e14f859,0x8e14f859
+.long	0x893c13eb,0x893c13eb
+.long	0xee27a9ce,0xee27a9ce
+.long	0x35c961b7,0x35c961b7
+.long	0xede51ce1,0xede51ce1
+.long	0x3cb1477a,0x3cb1477a
+.long	0x59dfd29c,0x59dfd29c
+.long	0x3f73f255,0x3f73f255
+.long	0x79ce1418,0x79ce1418
+.long	0xbf37c773,0xbf37c773
+.long	0xeacdf753,0xeacdf753
+.long	0x5baafd5f,0x5baafd5f
+.long	0x146f3ddf,0x146f3ddf
+.long	0x86db4478,0x86db4478
+.long	0x81f3afca,0x81f3afca
+.long	0x3ec468b9,0x3ec468b9
+.long	0x2c342438,0x2c342438
+.long	0x5f40a3c2,0x5f40a3c2
+.long	0x72c31d16,0x72c31d16
+.long	0x0c25e2bc,0x0c25e2bc
+.long	0x8b493c28,0x8b493c28
+.long	0x41950dff,0x41950dff
+.long	0x7101a839,0x7101a839
+.long	0xdeb30c08,0xdeb30c08
+.long	0x9ce4b4d8,0x9ce4b4d8
+.long	0x90c15664,0x90c15664
+.long	0x6184cb7b,0x6184cb7b
+.long	0x70b632d5,0x70b632d5
+.long	0x745c6c48,0x745c6c48
+.long	0x4257b8d0,0x4257b8d0
+.byte	0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38
+.byte	0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb
+.byte	0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87
+.byte	0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb
+.byte	0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d
+.byte	0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e
+.byte	0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2
+.byte	0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25
+.byte	0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16
+.byte	0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92
+.byte	0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda
+.byte	0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84
+.byte	0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a
+.byte	0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06
+.byte	0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02
+.byte	0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b
+.byte	0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea
+.byte	0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73
+.byte	0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85
+.byte	0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e
+.byte	0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89
+.byte	0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b
+.byte	0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20
+.byte	0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4
+.byte	0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31
+.byte	0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f
+.byte	0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d
+.byte	0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef
+.byte	0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0
+.byte	0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61
+.byte	0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26
+.byte	0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
+.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
+.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
+.byte	0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38
+.byte	0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb
+.byte	0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87
+.byte	0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb
+.byte	0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d
+.byte	0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e
+.byte	0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2
+.byte	0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25
+.byte	0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16
+.byte	0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92
+.byte	0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda
+.byte	0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84
+.byte	0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a
+.byte	0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06
+.byte	0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02
+.byte	0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b
+.byte	0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea
+.byte	0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73
+.byte	0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85
+.byte	0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e
+.byte	0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89
+.byte	0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b
+.byte	0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20
+.byte	0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4
+.byte	0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31
+.byte	0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f
+.byte	0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d
+.byte	0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef
+.byte	0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0
+.byte	0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61
+.byte	0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26
+.byte	0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
+.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
+.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
+.byte	0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38
+.byte	0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb
+.byte	0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87
+.byte	0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb
+.byte	0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d
+.byte	0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e
+.byte	0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2
+.byte	0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25
+.byte	0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16
+.byte	0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92
+.byte	0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda
+.byte	0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84
+.byte	0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a
+.byte	0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06
+.byte	0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02
+.byte	0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b
+.byte	0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea
+.byte	0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73
+.byte	0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85
+.byte	0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e
+.byte	0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89
+.byte	0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b
+.byte	0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20
+.byte	0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4
+.byte	0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31
+.byte	0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f
+.byte	0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d
+.byte	0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef
+.byte	0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0
+.byte	0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61
+.byte	0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26
+.byte	0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
+.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
+.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
+.byte	0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38
+.byte	0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb
+.byte	0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87
+.byte	0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb
+.byte	0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d
+.byte	0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e
+.byte	0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2
+.byte	0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25
+.byte	0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16
+.byte	0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92
+.byte	0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda
+.byte	0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84
+.byte	0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a
+.byte	0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06
+.byte	0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02
+.byte	0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b
+.byte	0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea
+.byte	0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73
+.byte	0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85
+.byte	0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e
+.byte	0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89
+.byte	0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b
+.byte	0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20
+.byte	0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4
+.byte	0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31
+.byte	0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f
+.byte	0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d
+.byte	0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef
+.byte	0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0
+.byte	0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61
+.byte	0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26
+.byte	0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
+.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
+.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
+.byte	65,69,83,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align	64
+#if defined(HAVE_GNU_STACK)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/crypto/libressl/crypto/aes/aes-macosx-x86_64.s b/crypto/libressl/crypto/aes/aes-macosx-x86_64.s
new file mode 100644
index 0000000000..f3924d8fb6
--- /dev/null
+++ b/crypto/libressl/crypto/aes/aes-macosx-x86_64.s
@@ -0,0 +1,2541 @@
+.text	
+
+.p2align	4
+_x86_64_AES_encrypt:
+	xorl	0(%r15),%eax
+	xorl	4(%r15),%ebx
+	xorl	8(%r15),%ecx
+	xorl	12(%r15),%edx
+
+	movl	240(%r15),%r13d
+	subl	$1,%r13d
+	jmp	L$enc_loop
+.p2align	4
+L$enc_loop:
+
+	movzbl	%al,%esi
+	movzbl	%bl,%edi
+	movzbl	%cl,%ebp
+	movl	0(%r14,%rsi,8),%r10d
+	movl	0(%r14,%rdi,8),%r11d
+	movl	0(%r14,%rbp,8),%r12d
+
+	movzbl	%bh,%esi
+	movzbl	%ch,%edi
+	movzbl	%dl,%ebp
+	xorl	3(%r14,%rsi,8),%r10d
+	xorl	3(%r14,%rdi,8),%r11d
+	movl	0(%r14,%rbp,8),%r8d
+
+	movzbl	%dh,%esi
+	shrl	$16,%ecx
+	movzbl	%ah,%ebp
+	xorl	3(%r14,%rsi,8),%r12d
+	shrl	$16,%edx
+	xorl	3(%r14,%rbp,8),%r8d
+
+	shrl	$16,%ebx
+	leaq	16(%r15),%r15
+	shrl	$16,%eax
+
+	movzbl	%cl,%esi
+	movzbl	%dl,%edi
+	movzbl	%al,%ebp
+	xorl	2(%r14,%rsi,8),%r10d
+	xorl	2(%r14,%rdi,8),%r11d
+	xorl	2(%r14,%rbp,8),%r12d
+
+	movzbl	%dh,%esi
+	movzbl	%ah,%edi
+	movzbl	%bl,%ebp
+	xorl	1(%r14,%rsi,8),%r10d
+	xorl	1(%r14,%rdi,8),%r11d
+	xorl	2(%r14,%rbp,8),%r8d
+
+	movl	12(%r15),%edx
+	movzbl	%bh,%edi
+	movzbl	%ch,%ebp
+	movl	0(%r15),%eax
+	xorl	1(%r14,%rdi,8),%r12d
+	xorl	1(%r14,%rbp,8),%r8d
+
+	movl	4(%r15),%ebx
+	movl	8(%r15),%ecx
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	xorl	%r12d,%ecx
+	xorl	%r8d,%edx
+	subl	$1,%r13d
+	jnz	L$enc_loop
+	movzbl	%al,%esi
+	movzbl	%bl,%edi
+	movzbl	%cl,%ebp
+	movzbl	2(%r14,%rsi,8),%r10d
+	movzbl	2(%r14,%rdi,8),%r11d
+	movzbl	2(%r14,%rbp,8),%r12d
+
+	movzbl	%dl,%esi
+	movzbl	%bh,%edi
+	movzbl	%ch,%ebp
+	movzbl	2(%r14,%rsi,8),%r8d
+	movl	0(%r14,%rdi,8),%edi
+	movl	0(%r14,%rbp,8),%ebp
+
+	andl	$65280,%edi
+	andl	$65280,%ebp
+
+	xorl	%edi,%r10d
+	xorl	%ebp,%r11d
+	shrl	$16,%ecx
+
+	movzbl	%dh,%esi
+	movzbl	%ah,%edi
+	shrl	$16,%edx
+	movl	0(%r14,%rsi,8),%esi
+	movl	0(%r14,%rdi,8),%edi
+
+	andl	$65280,%esi
+	andl	$65280,%edi
+	shrl	$16,%ebx
+	xorl	%esi,%r12d
+	xorl	%edi,%r8d
+	shrl	$16,%eax
+
+	movzbl	%cl,%esi
+	movzbl	%dl,%edi
+	movzbl	%al,%ebp
+	movl	0(%r14,%rsi,8),%esi
+	movl	0(%r14,%rdi,8),%edi
+	movl	0(%r14,%rbp,8),%ebp
+
+	andl	$16711680,%esi
+	andl	$16711680,%edi
+	andl	$16711680,%ebp
+
+	xorl	%esi,%r10d
+	xorl	%edi,%r11d
+	xorl	%ebp,%r12d
+
+	movzbl	%bl,%esi
+	movzbl	%dh,%edi
+	movzbl	%ah,%ebp
+	movl	0(%r14,%rsi,8),%esi
+	movl	2(%r14,%rdi,8),%edi
+	movl	2(%r14,%rbp,8),%ebp
+
+	andl	$16711680,%esi
+	andl	$4278190080,%edi
+	andl	$4278190080,%ebp
+
+	xorl	%esi,%r8d
+	xorl	%edi,%r10d
+	xorl	%ebp,%r11d
+
+	movzbl	%bh,%esi
+	movzbl	%ch,%edi
+	movl	16+12(%r15),%edx
+	movl	2(%r14,%rsi,8),%esi
+	movl	2(%r14,%rdi,8),%edi
+	movl	16+0(%r15),%eax
+
+	andl	$4278190080,%esi
+	andl	$4278190080,%edi
+
+	xorl	%esi,%r12d
+	xorl	%edi,%r8d
+
+	movl	16+4(%r15),%ebx
+	movl	16+8(%r15),%ecx
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	xorl	%r12d,%ecx
+	xorl	%r8d,%edx
+.byte	0xf3,0xc3			
+
+
+.p2align	4
+_x86_64_AES_encrypt_compact:
+	leaq	128(%r14),%r8
+	movl	0-128(%r8),%edi
+	movl	32-128(%r8),%ebp
+	movl	64-128(%r8),%r10d
+	movl	96-128(%r8),%r11d
+	movl	128-128(%r8),%edi
+	movl	160-128(%r8),%ebp
+	movl	192-128(%r8),%r10d
+	movl	224-128(%r8),%r11d
+	jmp	L$enc_loop_compact
+.p2align	4
+L$enc_loop_compact:
+	xorl	0(%r15),%eax
+	xorl	4(%r15),%ebx
+	xorl	8(%r15),%ecx
+	xorl	12(%r15),%edx
+	leaq	16(%r15),%r15
+	movzbl	%al,%r10d
+	movzbl	%bl,%r11d
+	movzbl	%cl,%r12d
+	movzbl	(%r14,%r10,1),%r10d
+	movzbl	(%r14,%r11,1),%r11d
+	movzbl	(%r14,%r12,1),%r12d
+
+	movzbl	%dl,%r8d
+	movzbl	%bh,%esi
+	movzbl	%ch,%edi
+	movzbl	(%r14,%r8,1),%r8d
+	movzbl	(%r14,%rsi,1),%r9d
+	movzbl	(%r14,%rdi,1),%r13d
+
+	movzbl	%dh,%ebp
+	movzbl	%ah,%esi
+	shrl	$16,%ecx
+	movzbl	(%r14,%rbp,1),%ebp
+	movzbl	(%r14,%rsi,1),%esi
+	shrl	$16,%edx
+
+	movzbl	%cl,%edi
+	shll	$8,%r9d
+	shll	$8,%r13d
+	movzbl	(%r14,%rdi,1),%edi
+	xorl	%r9d,%r10d
+	xorl	%r13d,%r11d
+
+	movzbl	%dl,%r9d
+	shrl	$16,%eax
+	shrl	$16,%ebx
+	movzbl	%al,%r13d
+	shll	$8,%ebp
+	shll	$8,%esi
+	movzbl	(%r14,%r9,1),%r9d
+	movzbl	(%r14,%r13,1),%r13d
+	xorl	%ebp,%r12d
+	xorl	%esi,%r8d
+
+	movzbl	%bl,%ebp
+	movzbl	%dh,%esi
+	shll	$16,%edi
+	movzbl	(%r14,%rbp,1),%ebp
+	movzbl	(%r14,%rsi,1),%esi
+	xorl	%edi,%r10d
+
+	movzbl	%ah,%edi
+	shrl	$8,%ecx
+	shrl	$8,%ebx
+	movzbl	(%r14,%rdi,1),%edi
+	movzbl	(%r14,%rcx,1),%edx
+	movzbl	(%r14,%rbx,1),%ecx
+	shll	$16,%r9d
+	shll	$16,%r13d
+	shll	$16,%ebp
+	xorl	%r9d,%r11d
+	xorl	%r13d,%r12d
+	xorl	%ebp,%r8d
+
+	shll	$24,%esi
+	shll	$24,%edi
+	shll	$24,%edx
+	xorl	%esi,%r10d
+	shll	$24,%ecx
+	xorl	%edi,%r11d
+	movl	%r10d,%eax
+	movl	%r11d,%ebx
+	xorl	%r12d,%ecx
+	xorl	%r8d,%edx
+	cmpq	16(%rsp),%r15
+	je	L$enc_compact_done
+	movl	%eax,%esi
+	movl	%ebx,%edi
+	andl	$2155905152,%esi
+	andl	$2155905152,%edi
+	movl	%esi,%r10d
+	movl	%edi,%r11d
+	shrl	$7,%r10d
+	leal	(%rax,%rax,1),%r8d
+	shrl	$7,%r11d
+	leal	(%rbx,%rbx,1),%r9d
+	subl	%r10d,%esi
+	subl	%r11d,%edi
+	andl	$4278124286,%r8d
+	andl	$4278124286,%r9d
+	andl	$454761243,%esi
+	andl	$454761243,%edi
+	movl	%eax,%r10d
+	movl	%ebx,%r11d
+	xorl	%esi,%r8d
+	xorl	%edi,%r9d
+
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movl	%ecx,%esi
+	movl	%edx,%edi
+	roll	$24,%eax
+	roll	$24,%ebx
+	andl	$2155905152,%esi
+	andl	$2155905152,%edi
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movl	%esi,%r12d
+	movl	%edi,%ebp
+	rorl	$16,%r10d
+	rorl	$16,%r11d
+	shrl	$7,%r12d
+	leal	(%rcx,%rcx,1),%r8d
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	shrl	$7,%ebp
+	leal	(%rdx,%rdx,1),%r9d
+	rorl	$8,%r10d
+	rorl	$8,%r11d
+	subl	%r12d,%esi
+	subl	%ebp,%edi
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+
+	andl	$4278124286,%r8d
+	andl	$4278124286,%r9d
+	andl	$454761243,%esi
+	andl	$454761243,%edi
+	movl	%ecx,%r12d
+	movl	%edx,%ebp
+	xorl	%esi,%r8d
+	xorl	%edi,%r9d
+
+	xorl	%r8d,%ecx
+	xorl	%r9d,%edx
+	roll	$24,%ecx
+	roll	$24,%edx
+	xorl	%r8d,%ecx
+	xorl	%r9d,%edx
+	movl	0(%r14),%esi
+	rorl	$16,%r12d
+	rorl	$16,%ebp
+	movl	64(%r14),%edi
+	xorl	%r12d,%ecx
+	xorl	%ebp,%edx
+	movl	128(%r14),%r8d
+	rorl	$8,%r12d
+	rorl	$8,%ebp
+	movl	192(%r14),%r9d
+	xorl	%r12d,%ecx
+	xorl	%ebp,%edx
+	jmp	L$enc_loop_compact
+.p2align	4
+L$enc_compact_done:
+	xorl	0(%r15),%eax
+	xorl	4(%r15),%ebx
+	xorl	8(%r15),%ecx
+	xorl	12(%r15),%edx
+.byte	0xf3,0xc3			
+
+.globl	_AES_encrypt
+
+.p2align	4
+.globl	_asm_AES_encrypt
+.private_extern	_asm_AES_encrypt
+_asm_AES_encrypt:
+_AES_encrypt:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+
+
+	movq	%rsp,%r10
+	leaq	-63(%rdx),%rcx
+	andq	$-64,%rsp
+	subq	%rsp,%rcx
+	negq	%rcx
+	andq	$960,%rcx
+	subq	%rcx,%rsp
+	subq	$32,%rsp
+
+	movq	%rsi,16(%rsp)
+	movq	%r10,24(%rsp)
+L$enc_prologue:
+
+	movq	%rdx,%r15
+	movl	240(%r15),%r13d
+
+	movl	0(%rdi),%eax
+	movl	4(%rdi),%ebx
+	movl	8(%rdi),%ecx
+	movl	12(%rdi),%edx
+
+	shll	$4,%r13d
+	leaq	(%r15,%r13,1),%rbp
+	movq	%r15,(%rsp)
+	movq	%rbp,8(%rsp)
+
+
+	leaq	L$AES_Te+2048(%rip),%r14
+	leaq	768(%rsp),%rbp
+	subq	%r14,%rbp
+	andq	$768,%rbp
+	leaq	(%r14,%rbp,1),%r14
+
+	call	_x86_64_AES_encrypt_compact
+
+	movq	16(%rsp),%r9
+	movq	24(%rsp),%rsi
+	movl	%eax,0(%r9)
+	movl	%ebx,4(%r9)
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+L$enc_epilogue:
+	.byte	0xf3,0xc3
+
+
+.p2align	4
+_x86_64_AES_decrypt:
+	xorl	0(%r15),%eax
+	xorl	4(%r15),%ebx
+	xorl	8(%r15),%ecx
+	xorl	12(%r15),%edx
+
+	movl	240(%r15),%r13d
+	subl	$1,%r13d
+	jmp	L$dec_loop
+.p2align	4
+L$dec_loop:
+
+	movzbl	%al,%esi
+	movzbl	%bl,%edi
+	movzbl	%cl,%ebp
+	movl	0(%r14,%rsi,8),%r10d
+	movl	0(%r14,%rdi,8),%r11d
+	movl	0(%r14,%rbp,8),%r12d
+
+	movzbl	%dh,%esi
+	movzbl	%ah,%edi
+	movzbl	%dl,%ebp
+	xorl	3(%r14,%rsi,8),%r10d
+	xorl	3(%r14,%rdi,8),%r11d
+	movl	0(%r14,%rbp,8),%r8d
+
+	movzbl	%bh,%esi
+	shrl	$16,%eax
+	movzbl	%ch,%ebp
+	xorl	3(%r14,%rsi,8),%r12d
+	shrl	$16,%edx
+	xorl	3(%r14,%rbp,8),%r8d
+
+	shrl	$16,%ebx
+	leaq	16(%r15),%r15
+	shrl	$16,%ecx
+
+	movzbl	%cl,%esi
+	movzbl	%dl,%edi
+	movzbl	%al,%ebp
+	xorl	2(%r14,%rsi,8),%r10d
+	xorl	2(%r14,%rdi,8),%r11d
+	xorl	2(%r14,%rbp,8),%r12d
+
+	movzbl	%bh,%esi
+	movzbl	%ch,%edi
+	movzbl	%bl,%ebp
+	xorl	1(%r14,%rsi,8),%r10d
+	xorl	1(%r14,%rdi,8),%r11d
+	xorl	2(%r14,%rbp,8),%r8d
+
+	movzbl	%dh,%esi
+	movl	12(%r15),%edx
+	movzbl	%ah,%ebp
+	xorl	1(%r14,%rsi,8),%r12d
+	movl	0(%r15),%eax
+	xorl	1(%r14,%rbp,8),%r8d
+
+	xorl	%r10d,%eax
+	movl	4(%r15),%ebx
+	movl	8(%r15),%ecx
+	xorl	%r12d,%ecx
+	xorl	%r11d,%ebx
+	xorl	%r8d,%edx
+	subl	$1,%r13d
+	jnz	L$dec_loop
+	leaq	2048(%r14),%r14
+	movzbl	%al,%esi
+	movzbl	%bl,%edi
+	movzbl	%cl,%ebp
+	movzbl	(%r14,%rsi,1),%r10d
+	movzbl	(%r14,%rdi,1),%r11d
+	movzbl	(%r14,%rbp,1),%r12d
+
+	movzbl	%dl,%esi
+	movzbl	%dh,%edi
+	movzbl	%ah,%ebp
+	movzbl	(%r14,%rsi,1),%r8d
+	movzbl	(%r14,%rdi,1),%edi
+	movzbl	(%r14,%rbp,1),%ebp
+
+	shll	$8,%edi
+	shll	$8,%ebp
+
+	xorl	%edi,%r10d
+	xorl	%ebp,%r11d
+	shrl	$16,%edx
+
+	movzbl	%bh,%esi
+	movzbl	%ch,%edi
+	shrl	$16,%eax
+	movzbl	(%r14,%rsi,1),%esi
+	movzbl	(%r14,%rdi,1),%edi
+
+	shll	$8,%esi
+	shll	$8,%edi
+	shrl	$16,%ebx
+	xorl	%esi,%r12d
+	xorl	%edi,%r8d
+	shrl	$16,%ecx
+
+	movzbl	%cl,%esi
+	movzbl	%dl,%edi
+	movzbl	%al,%ebp
+	movzbl	(%r14,%rsi,1),%esi
+	movzbl	(%r14,%rdi,1),%edi
+	movzbl	(%r14,%rbp,1),%ebp
+
+	shll	$16,%esi
+	shll	$16,%edi
+	shll	$16,%ebp
+
+	xorl	%esi,%r10d
+	xorl	%edi,%r11d
+	xorl	%ebp,%r12d
+
+	movzbl	%bl,%esi
+	movzbl	%bh,%edi
+	movzbl	%ch,%ebp
+	movzbl	(%r14,%rsi,1),%esi
+	movzbl	(%r14,%rdi,1),%edi
+	movzbl	(%r14,%rbp,1),%ebp
+
+	shll	$16,%esi
+	shll	$24,%edi
+	shll	$24,%ebp
+
+	xorl	%esi,%r8d
+	xorl	%edi,%r10d
+	xorl	%ebp,%r11d
+
+	movzbl	%dh,%esi
+	movzbl	%ah,%edi
+	movl	16+12(%r15),%edx
+	movzbl	(%r14,%rsi,1),%esi
+	movzbl	(%r14,%rdi,1),%edi
+	movl	16+0(%r15),%eax
+
+	shll	$24,%esi
+	shll	$24,%edi
+
+	xorl	%esi,%r12d
+	xorl	%edi,%r8d
+
+	movl	16+4(%r15),%ebx
+	movl	16+8(%r15),%ecx
+	leaq	-2048(%r14),%r14
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	xorl	%r12d,%ecx
+	xorl	%r8d,%edx
+.byte	0xf3,0xc3			
+
+
+.p2align	4
+_x86_64_AES_decrypt_compact:
+	leaq	128(%r14),%r8
+	movl	0-128(%r8),%edi
+	movl	32-128(%r8),%ebp
+	movl	64-128(%r8),%r10d
+	movl	96-128(%r8),%r11d
+	movl	128-128(%r8),%edi
+	movl	160-128(%r8),%ebp
+	movl	192-128(%r8),%r10d
+	movl	224-128(%r8),%r11d
+	jmp	L$dec_loop_compact
+
+.p2align	4
+L$dec_loop_compact:
+	xorl	0(%r15),%eax
+	xorl	4(%r15),%ebx
+	xorl	8(%r15),%ecx
+	xorl	12(%r15),%edx
+	leaq	16(%r15),%r15
+	movzbl	%al,%r10d
+	movzbl	%bl,%r11d
+	movzbl	%cl,%r12d
+	movzbl	(%r14,%r10,1),%r10d
+	movzbl	(%r14,%r11,1),%r11d
+	movzbl	(%r14,%r12,1),%r12d
+
+	movzbl	%dl,%r8d
+	movzbl	%dh,%esi
+	movzbl	%ah,%edi
+	movzbl	(%r14,%r8,1),%r8d
+	movzbl	(%r14,%rsi,1),%r9d
+	movzbl	(%r14,%rdi,1),%r13d
+
+	movzbl	%bh,%ebp
+	movzbl	%ch,%esi
+	shrl	$16,%ecx
+	movzbl	(%r14,%rbp,1),%ebp
+	movzbl	(%r14,%rsi,1),%esi
+	shrl	$16,%edx
+
+	movzbl	%cl,%edi
+	shll	$8,%r9d
+	shll	$8,%r13d
+	movzbl	(%r14,%rdi,1),%edi
+	xorl	%r9d,%r10d
+	xorl	%r13d,%r11d
+
+	movzbl	%dl,%r9d
+	shrl	$16,%eax
+	shrl	$16,%ebx
+	movzbl	%al,%r13d
+	shll	$8,%ebp
+	shll	$8,%esi
+	movzbl	(%r14,%r9,1),%r9d
+	movzbl	(%r14,%r13,1),%r13d
+	xorl	%ebp,%r12d
+	xorl	%esi,%r8d
+
+	movzbl	%bl,%ebp
+	movzbl	%bh,%esi
+	shll	$16,%edi
+	movzbl	(%r14,%rbp,1),%ebp
+	movzbl	(%r14,%rsi,1),%esi
+	xorl	%edi,%r10d
+
+	movzbl	%ch,%edi
+	shll	$16,%r9d
+	shll	$16,%r13d
+	movzbl	(%r14,%rdi,1),%ebx
+	xorl	%r9d,%r11d
+	xorl	%r13d,%r12d
+
+	movzbl	%dh,%edi
+	shrl	$8,%eax
+	shll	$16,%ebp
+	movzbl	(%r14,%rdi,1),%ecx
+	movzbl	(%r14,%rax,1),%edx
+	xorl	%ebp,%r8d
+
+	shll	$24,%esi
+	shll	$24,%ebx
+	shll	$24,%ecx
+	xorl	%esi,%r10d
+	shll	$24,%edx
+	xorl	%r11d,%ebx
+	movl	%r10d,%eax
+	xorl	%r12d,%ecx
+	xorl	%r8d,%edx
+	cmpq	16(%rsp),%r15
+	je	L$dec_compact_done
+
+	movq	256+0(%r14),%rsi
+	shlq	$32,%rbx
+	shlq	$32,%rdx
+	movq	256+8(%r14),%rdi
+	orq	%rbx,%rax
+	orq	%rdx,%rcx
+	movq	256+16(%r14),%rbp
+	movq	%rax,%rbx
+	movq	%rcx,%rdx
+	andq	%rsi,%rbx
+	andq	%rsi,%rdx
+	movq	%rbx,%r9
+	movq	%rdx,%r12
+	shrq	$7,%r9
+	leaq	(%rax,%rax,1),%r8
+	shrq	$7,%r12
+	leaq	(%rcx,%rcx,1),%r11
+	subq	%r9,%rbx
+	subq	%r12,%rdx
+	andq	%rdi,%r8
+	andq	%rdi,%r11
+	andq	%rbp,%rbx
+	andq	%rbp,%rdx
+	xorq	%r8,%rbx
+	xorq	%r11,%rdx
+	movq	%rbx,%r8
+	movq	%rdx,%r11
+
+	andq	%rsi,%rbx
+	andq	%rsi,%rdx
+	movq	%rbx,%r10
+	movq	%rdx,%r13
+	shrq	$7,%r10
+	leaq	(%r8,%r8,1),%r9
+	shrq	$7,%r13
+	leaq	(%r11,%r11,1),%r12
+	subq	%r10,%rbx
+	subq	%r13,%rdx
+	andq	%rdi,%r9
+	andq	%rdi,%r12
+	andq	%rbp,%rbx
+	andq	%rbp,%rdx
+	xorq	%r9,%rbx
+	xorq	%r12,%rdx
+	movq	%rbx,%r9
+	movq	%rdx,%r12
+
+	andq	%rsi,%rbx
+	andq	%rsi,%rdx
+	movq	%rbx,%r10
+	movq	%rdx,%r13
+	shrq	$7,%r10
+	xorq	%rax,%r8
+	shrq	$7,%r13
+	xorq	%rcx,%r11
+	subq	%r10,%rbx
+	subq	%r13,%rdx
+	leaq	(%r9,%r9,1),%r10
+	leaq	(%r12,%r12,1),%r13
+	xorq	%rax,%r9
+	xorq	%rcx,%r12
+	andq	%rdi,%r10
+	andq	%rdi,%r13
+	andq	%rbp,%rbx
+	andq	%rbp,%rdx
+	xorq	%rbx,%r10
+	xorq	%rdx,%r13
+
+	xorq	%r10,%rax
+	xorq	%r13,%rcx
+	xorq	%r10,%r8
+	xorq	%r13,%r11
+	movq	%rax,%rbx
+	movq	%rcx,%rdx
+	xorq	%r10,%r9
+	xorq	%r13,%r12
+	shrq	$32,%rbx
+	shrq	$32,%rdx
+	xorq	%r8,%r10
+	xorq	%r11,%r13
+	roll	$8,%eax
+	roll	$8,%ecx
+	xorq	%r9,%r10
+	xorq	%r12,%r13
+
+	roll	$8,%ebx
+	roll	$8,%edx
+	xorl	%r10d,%eax
+	xorl	%r13d,%ecx
+	shrq	$32,%r10
+	shrq	$32,%r13
+	xorl	%r10d,%ebx
+	xorl	%r13d,%edx
+
+	movq	%r8,%r10
+	movq	%r11,%r13
+	shrq	$32,%r10
+	shrq	$32,%r13
+	roll	$24,%r8d
+	roll	$24,%r11d
+	roll	$24,%r10d
+	roll	$24,%r13d
+	xorl	%r8d,%eax
+	xorl	%r11d,%ecx
+	movq	%r9,%r8
+	movq	%r12,%r11
+	xorl	%r10d,%ebx
+	xorl	%r13d,%edx
+
+	movq	0(%r14),%rsi
+	shrq	$32,%r8
+	shrq	$32,%r11
+	movq	64(%r14),%rdi
+	roll	$16,%r9d
+	roll	$16,%r12d
+	movq	128(%r14),%rbp
+	roll	$16,%r8d
+	roll	$16,%r11d
+	movq	192(%r14),%r10
+	xorl	%r9d,%eax
+	xorl	%r12d,%ecx
+	movq	256(%r14),%r13
+	xorl	%r8d,%ebx
+	xorl	%r11d,%edx
+	jmp	L$dec_loop_compact
+.p2align	4
+L$dec_compact_done:
+	xorl	0(%r15),%eax
+	xorl	4(%r15),%ebx
+	xorl	8(%r15),%ecx
+	xorl	12(%r15),%edx
+.byte	0xf3,0xc3			
+
+.globl	_AES_decrypt
+
+.p2align	4
+.globl	_asm_AES_decrypt
+.private_extern	_asm_AES_decrypt
+_asm_AES_decrypt:
+_AES_decrypt:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+
+
+	movq	%rsp,%r10
+	leaq	-63(%rdx),%rcx
+	andq	$-64,%rsp
+	subq	%rsp,%rcx
+	negq	%rcx
+	andq	$960,%rcx
+	subq	%rcx,%rsp
+	subq	$32,%rsp
+
+	movq	%rsi,16(%rsp)
+	movq	%r10,24(%rsp)
+L$dec_prologue:
+
+	movq	%rdx,%r15
+	movl	240(%r15),%r13d
+
+	movl	0(%rdi),%eax
+	movl	4(%rdi),%ebx
+	movl	8(%rdi),%ecx
+	movl	12(%rdi),%edx
+
+	shll	$4,%r13d
+	leaq	(%r15,%r13,1),%rbp
+	movq	%r15,(%rsp)
+	movq	%rbp,8(%rsp)
+
+
+	leaq	L$AES_Td+2048(%rip),%r14
+	leaq	768(%rsp),%rbp
+	subq	%r14,%rbp
+	andq	$768,%rbp
+	leaq	(%r14,%rbp,1),%r14
+	shrq	$3,%rbp
+	addq	%rbp,%r14
+
+	call	_x86_64_AES_decrypt_compact
+
+	movq	16(%rsp),%r9
+	movq	24(%rsp),%rsi
+	movl	%eax,0(%r9)
+	movl	%ebx,4(%r9)
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+L$dec_epilogue:
+	.byte	0xf3,0xc3
+
+.globl	_AES_set_encrypt_key
+
+.p2align	4
+_AES_set_encrypt_key:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	subq	$8,%rsp
+L$enc_key_prologue:
+
+	call	_x86_64_AES_set_encrypt_key
+
+	movq	8(%rsp),%r15
+	movq	16(%rsp),%r14
+	movq	24(%rsp),%r13
+	movq	32(%rsp),%r12
+	movq	40(%rsp),%rbp
+	movq	48(%rsp),%rbx
+	addq	$56,%rsp
+L$enc_key_epilogue:
+	.byte	0xf3,0xc3
+
+
+
+.p2align	4
+_x86_64_AES_set_encrypt_key:
+	movl	%esi,%ecx
+	movq	%rdi,%rsi
+	movq	%rdx,%rdi
+
+	testq	$-1,%rsi
+	jz	L$badpointer
+	testq	$-1,%rdi
+	jz	L$badpointer
+
+	leaq	L$AES_Te(%rip),%rbp
+	leaq	2048+128(%rbp),%rbp
+
+
+	movl	0-128(%rbp),%eax
+	movl	32-128(%rbp),%ebx
+	movl	64-128(%rbp),%r8d
+	movl	96-128(%rbp),%edx
+	movl	128-128(%rbp),%eax
+	movl	160-128(%rbp),%ebx
+	movl	192-128(%rbp),%r8d
+	movl	224-128(%rbp),%edx
+
+	cmpl	$128,%ecx
+	je	L$10rounds
+	cmpl	$192,%ecx
+	je	L$12rounds
+	cmpl	$256,%ecx
+	je	L$14rounds
+	movq	$-2,%rax
+	jmp	L$exit
+
+L$10rounds:
+	movq	0(%rsi),%rax
+	movq	8(%rsi),%rdx
+	movq	%rax,0(%rdi)
+	movq	%rdx,8(%rdi)
+
+	shrq	$32,%rdx
+	xorl	%ecx,%ecx
+	jmp	L$10shortcut
+.p2align	2
+L$10loop:
+	movl	0(%rdi),%eax
+	movl	12(%rdi),%edx
+L$10shortcut:
+	movzbl	%dl,%esi
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	movzbl	%dh,%esi
+	shll	$24,%ebx
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	shrl	$16,%edx
+	movzbl	%dl,%esi
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	movzbl	%dh,%esi
+	shll	$8,%ebx
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	shll	$16,%ebx
+	xorl	%ebx,%eax
+
+	xorl	1024-128(%rbp,%rcx,4),%eax
+	movl	%eax,16(%rdi)
+	xorl	4(%rdi),%eax
+	movl	%eax,20(%rdi)
+	xorl	8(%rdi),%eax
+	movl	%eax,24(%rdi)
+	xorl	12(%rdi),%eax
+	movl	%eax,28(%rdi)
+	addl	$1,%ecx
+	leaq	16(%rdi),%rdi
+	cmpl	$10,%ecx
+	jl	L$10loop
+
+	movl	$10,80(%rdi)
+	xorq	%rax,%rax
+	jmp	L$exit
+
+L$12rounds:
+	movq	0(%rsi),%rax
+	movq	8(%rsi),%rbx
+	movq	16(%rsi),%rdx
+	movq	%rax,0(%rdi)
+	movq	%rbx,8(%rdi)
+	movq	%rdx,16(%rdi)
+
+	shrq	$32,%rdx
+	xorl	%ecx,%ecx
+	jmp	L$12shortcut
+.p2align	2
+L$12loop:
+	movl	0(%rdi),%eax
+	movl	20(%rdi),%edx
+L$12shortcut:
+	movzbl	%dl,%esi
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	movzbl	%dh,%esi
+	shll	$24,%ebx
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	shrl	$16,%edx
+	movzbl	%dl,%esi
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	movzbl	%dh,%esi
+	shll	$8,%ebx
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	shll	$16,%ebx
+	xorl	%ebx,%eax
+
+	xorl	1024-128(%rbp,%rcx,4),%eax
+	movl	%eax,24(%rdi)
+	xorl	4(%rdi),%eax
+	movl	%eax,28(%rdi)
+	xorl	8(%rdi),%eax
+	movl	%eax,32(%rdi)
+	xorl	12(%rdi),%eax
+	movl	%eax,36(%rdi)
+
+	cmpl	$7,%ecx
+	je	L$12break
+	addl	$1,%ecx
+
+	xorl	16(%rdi),%eax
+	movl	%eax,40(%rdi)
+	xorl	20(%rdi),%eax
+	movl	%eax,44(%rdi)
+
+	leaq	24(%rdi),%rdi
+	jmp	L$12loop
+L$12break:
+	movl	$12,72(%rdi)
+	xorq	%rax,%rax
+	jmp	L$exit
+
+L$14rounds:
+	movq	0(%rsi),%rax
+	movq	8(%rsi),%rbx
+	movq	16(%rsi),%rcx
+	movq	24(%rsi),%rdx
+	movq	%rax,0(%rdi)
+	movq	%rbx,8(%rdi)
+	movq	%rcx,16(%rdi)
+	movq	%rdx,24(%rdi)
+
+	shrq	$32,%rdx
+	xorl	%ecx,%ecx
+	jmp	L$14shortcut
+.p2align	2
+L$14loop:
+	movl	0(%rdi),%eax
+	movl	28(%rdi),%edx
+L$14shortcut:
+	movzbl	%dl,%esi
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	movzbl	%dh,%esi
+	shll	$24,%ebx
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	shrl	$16,%edx
+	movzbl	%dl,%esi
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	movzbl	%dh,%esi
+	shll	$8,%ebx
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	shll	$16,%ebx
+	xorl	%ebx,%eax
+
+	xorl	1024-128(%rbp,%rcx,4),%eax
+	movl	%eax,32(%rdi)
+	xorl	4(%rdi),%eax
+	movl	%eax,36(%rdi)
+	xorl	8(%rdi),%eax
+	movl	%eax,40(%rdi)
+	xorl	12(%rdi),%eax
+	movl	%eax,44(%rdi)
+
+	cmpl	$6,%ecx
+	je	L$14break
+	addl	$1,%ecx
+
+	movl	%eax,%edx
+	movl	16(%rdi),%eax
+	movzbl	%dl,%esi
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	movzbl	%dh,%esi
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	shrl	$16,%edx
+	shll	$8,%ebx
+	movzbl	%dl,%esi
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	movzbl	%dh,%esi
+	shll	$16,%ebx
+	xorl	%ebx,%eax
+
+	movzbl	-128(%rbp,%rsi,1),%ebx
+	shll	$24,%ebx
+	xorl	%ebx,%eax
+
+	movl	%eax,48(%rdi)
+	xorl	20(%rdi),%eax
+	movl	%eax,52(%rdi)
+	xorl	24(%rdi),%eax
+	movl	%eax,56(%rdi)
+	xorl	28(%rdi),%eax
+	movl	%eax,60(%rdi)
+
+	leaq	32(%rdi),%rdi
+	jmp	L$14loop
+L$14break:
+	movl	$14,48(%rdi)
+	xorq	%rax,%rax
+	jmp	L$exit
+
+L$badpointer:
+	movq	$-1,%rax
+L$exit:
+.byte	0xf3,0xc3			
+
+.globl	_AES_set_decrypt_key
+
+.p2align	4
+_AES_set_decrypt_key:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	pushq	%rdx
+L$dec_key_prologue:
+
+	call	_x86_64_AES_set_encrypt_key
+	movq	(%rsp),%r8
+	cmpl	$0,%eax
+	jne	L$abort
+
+	movl	240(%r8),%r14d
+	xorq	%rdi,%rdi
+	leaq	(%rdi,%r14,4),%rcx
+	movq	%r8,%rsi
+	leaq	(%r8,%rcx,4),%rdi
+.p2align	2
+L$invert:
+	movq	0(%rsi),%rax
+	movq	8(%rsi),%rbx
+	movq	0(%rdi),%rcx
+	movq	8(%rdi),%rdx
+	movq	%rax,0(%rdi)
+	movq	%rbx,8(%rdi)
+	movq	%rcx,0(%rsi)
+	movq	%rdx,8(%rsi)
+	leaq	16(%rsi),%rsi
+	leaq	-16(%rdi),%rdi
+	cmpq	%rsi,%rdi
+	jne	L$invert
+
+	leaq	L$AES_Te+2048+1024(%rip),%rax
+
+	movq	40(%rax),%rsi
+	movq	48(%rax),%rdi
+	movq	56(%rax),%rbp
+
+	movq	%r8,%r15
+	subl	$1,%r14d
+.p2align	2
+L$permute:
+	leaq	16(%r15),%r15
+	movq	0(%r15),%rax
+	movq	8(%r15),%rcx
+	movq	%rax,%rbx
+	movq	%rcx,%rdx
+	andq	%rsi,%rbx
+	andq	%rsi,%rdx
+	movq	%rbx,%r9
+	movq	%rdx,%r12
+	shrq	$7,%r9
+	leaq	(%rax,%rax,1),%r8
+	shrq	$7,%r12
+	leaq	(%rcx,%rcx,1),%r11
+	subq	%r9,%rbx
+	subq	%r12,%rdx
+	andq	%rdi,%r8
+	andq	%rdi,%r11
+	andq	%rbp,%rbx
+	andq	%rbp,%rdx
+	xorq	%r8,%rbx
+	xorq	%r11,%rdx
+	movq	%rbx,%r8
+	movq	%rdx,%r11
+
+	andq	%rsi,%rbx
+	andq	%rsi,%rdx
+	movq	%rbx,%r10
+	movq	%rdx,%r13
+	shrq	$7,%r10
+	leaq	(%r8,%r8,1),%r9
+	shrq	$7,%r13
+	leaq	(%r11,%r11,1),%r12
+	subq	%r10,%rbx
+	subq	%r13,%rdx
+	andq	%rdi,%r9
+	andq	%rdi,%r12
+	andq	%rbp,%rbx
+	andq	%rbp,%rdx
+	xorq	%r9,%rbx
+	xorq	%r12,%rdx
+	movq	%rbx,%r9
+	movq	%rdx,%r12
+
+	andq	%rsi,%rbx
+	andq	%rsi,%rdx
+	movq	%rbx,%r10
+	movq	%rdx,%r13
+	shrq	$7,%r10
+	xorq	%rax,%r8
+	shrq	$7,%r13
+	xorq	%rcx,%r11
+	subq	%r10,%rbx
+	subq	%r13,%rdx
+	leaq	(%r9,%r9,1),%r10
+	leaq	(%r12,%r12,1),%r13
+	xorq	%rax,%r9
+	xorq	%rcx,%r12
+	andq	%rdi,%r10
+	andq	%rdi,%r13
+	andq	%rbp,%rbx
+	andq	%rbp,%rdx
+	xorq	%rbx,%r10
+	xorq	%rdx,%r13
+
+	xorq	%r10,%rax
+	xorq	%r13,%rcx
+	xorq	%r10,%r8
+	xorq	%r13,%r11
+	movq	%rax,%rbx
+	movq	%rcx,%rdx
+	xorq	%r10,%r9
+	xorq	%r13,%r12
+	shrq	$32,%rbx
+	shrq	$32,%rdx
+	xorq	%r8,%r10
+	xorq	%r11,%r13
+	roll	$8,%eax
+	roll	$8,%ecx
+	xorq	%r9,%r10
+	xorq	%r12,%r13
+
+	roll	$8,%ebx
+	roll	$8,%edx
+	xorl	%r10d,%eax
+	xorl	%r13d,%ecx
+	shrq	$32,%r10
+	shrq	$32,%r13
+	xorl	%r10d,%ebx
+	xorl	%r13d,%edx
+
+	movq	%r8,%r10
+	movq	%r11,%r13
+	shrq	$32,%r10
+	shrq	$32,%r13
+	roll	$24,%r8d
+	roll	$24,%r11d
+	roll	$24,%r10d
+	roll	$24,%r13d
+	xorl	%r8d,%eax
+	xorl	%r11d,%ecx
+	movq	%r9,%r8
+	movq	%r12,%r11
+	xorl	%r10d,%ebx
+	xorl	%r13d,%edx
+
+
+	shrq	$32,%r8
+	shrq	$32,%r11
+
+	roll	$16,%r9d
+	roll	$16,%r12d
+
+	roll	$16,%r8d
+	roll	$16,%r11d
+
+	xorl	%r9d,%eax
+	xorl	%r12d,%ecx
+
+	xorl	%r8d,%ebx
+	xorl	%r11d,%edx
+	movl	%eax,0(%r15)
+	movl	%ebx,4(%r15)
+	movl	%ecx,8(%r15)
+	movl	%edx,12(%r15)
+	subl	$1,%r14d
+	jnz	L$permute
+
+	xorq	%rax,%rax
+L$abort:
+	movq	8(%rsp),%r15
+	movq	16(%rsp),%r14
+	movq	24(%rsp),%r13
+	movq	32(%rsp),%r12
+	movq	40(%rsp),%rbp
+	movq	48(%rsp),%rbx
+	addq	$56,%rsp
+L$dec_key_epilogue:
+	.byte	0xf3,0xc3
+
+.globl	_AES_cbc_encrypt
+
+.p2align	4
+
+.globl	_asm_AES_cbc_encrypt
+.private_extern	_asm_AES_cbc_encrypt
+_asm_AES_cbc_encrypt:
+_AES_cbc_encrypt:
+	cmpq	$0,%rdx
+	je	L$cbc_epilogue
+	pushfq
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+L$cbc_prologue:
+
+	cld
+	movl	%r9d,%r9d
+
+	leaq	L$AES_Te(%rip),%r14
+	cmpq	$0,%r9
+	jne	L$cbc_picked_te
+	leaq	L$AES_Td(%rip),%r14
+L$cbc_picked_te:
+
+	movl	_OPENSSL_ia32cap_P(%rip),%r10d
+	cmpq	$512,%rdx
+	jb	L$cbc_slow_prologue
+	testq	$15,%rdx
+	jnz	L$cbc_slow_prologue
+	btl	$28,%r10d
+	jc	L$cbc_slow_prologue
+
+
+	leaq	-88-248(%rsp),%r15
+	andq	$-64,%r15
+
+
+	movq	%r14,%r10
+	leaq	2304(%r14),%r11
+	movq	%r15,%r12
+	andq	$4095,%r10
+	andq	$4095,%r11
+	andq	$4095,%r12
+
+	cmpq	%r11,%r12
+	jb	L$cbc_te_break_out
+	subq	%r11,%r12
+	subq	%r12,%r15
+	jmp	L$cbc_te_ok
+L$cbc_te_break_out:
+	subq	%r10,%r12
+	andq	$4095,%r12
+	addq	$320,%r12
+	subq	%r12,%r15
+.p2align	2
+L$cbc_te_ok:
+
+	xchgq	%rsp,%r15
+
+	movq	%r15,16(%rsp)
+L$cbc_fast_body:
+	movq	%rdi,24(%rsp)
+	movq	%rsi,32(%rsp)
+	movq	%rdx,40(%rsp)
+	movq	%rcx,48(%rsp)
+	movq	%r8,56(%rsp)
+	movl	$0,80+240(%rsp)
+	movq	%r8,%rbp
+	movq	%r9,%rbx
+	movq	%rsi,%r9
+	movq	%rdi,%r8
+	movq	%rcx,%r15
+
+	movl	240(%r15),%eax
+
+	movq	%r15,%r10
+	subq	%r14,%r10
+	andq	$4095,%r10
+	cmpq	$2304,%r10
+	jb	L$cbc_do_ecopy
+	cmpq	$4096-248,%r10
+	jb	L$cbc_skip_ecopy
+.p2align	2
+L$cbc_do_ecopy:
+	movq	%r15,%rsi
+	leaq	80(%rsp),%rdi
+	leaq	80(%rsp),%r15
+	movl	$30,%ecx
+.long	0x90A548F3	
+	movl	%eax,(%rdi)
+L$cbc_skip_ecopy:
+	movq	%r15,0(%rsp)
+
+	movl	$18,%ecx
+.p2align	2
+L$cbc_prefetch_te:
+	movq	0(%r14),%r10
+	movq	32(%r14),%r11
+	movq	64(%r14),%r12
+	movq	96(%r14),%r13
+	leaq	128(%r14),%r14
+	subl	$1,%ecx
+	jnz	L$cbc_prefetch_te
+	leaq	-2304(%r14),%r14
+
+	cmpq	$0,%rbx
+	je	L$FAST_DECRYPT
+
+
+	movl	0(%rbp),%eax
+	movl	4(%rbp),%ebx
+	movl	8(%rbp),%ecx
+	movl	12(%rbp),%edx
+
+.p2align	2
+L$cbc_fast_enc_loop:
+	xorl	0(%r8),%eax
+	xorl	4(%r8),%ebx
+	xorl	8(%r8),%ecx
+	xorl	12(%r8),%edx
+	movq	0(%rsp),%r15
+	movq	%r8,24(%rsp)
+
+	call	_x86_64_AES_encrypt
+
+	movq	24(%rsp),%r8
+	movq	40(%rsp),%r10
+	movl	%eax,0(%r9)
+	movl	%ebx,4(%r9)
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+
+	leaq	16(%r8),%r8
+	leaq	16(%r9),%r9
+	subq	$16,%r10
+	testq	$-16,%r10
+	movq	%r10,40(%rsp)
+	jnz	L$cbc_fast_enc_loop
+	movq	56(%rsp),%rbp
+	movl	%eax,0(%rbp)
+	movl	%ebx,4(%rbp)
+	movl	%ecx,8(%rbp)
+	movl	%edx,12(%rbp)
+
+	jmp	L$cbc_fast_cleanup
+
+
+.p2align	4
+L$FAST_DECRYPT:
+	cmpq	%r8,%r9
+	je	L$cbc_fast_dec_in_place
+
+	movq	%rbp,64(%rsp)
+.p2align	2
+L$cbc_fast_dec_loop:
+	movl	0(%r8),%eax
+	movl	4(%r8),%ebx
+	movl	8(%r8),%ecx
+	movl	12(%r8),%edx
+	movq	0(%rsp),%r15
+	movq	%r8,24(%rsp)
+
+	call	_x86_64_AES_decrypt
+
+	movq	64(%rsp),%rbp
+	movq	24(%rsp),%r8
+	movq	40(%rsp),%r10
+	xorl	0(%rbp),%eax
+	xorl	4(%rbp),%ebx
+	xorl	8(%rbp),%ecx
+	xorl	12(%rbp),%edx
+	movq	%r8,%rbp
+
+	subq	$16,%r10
+	movq	%r10,40(%rsp)
+	movq	%rbp,64(%rsp)
+
+	movl	%eax,0(%r9)
+	movl	%ebx,4(%r9)
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+
+	leaq	16(%r8),%r8
+	leaq	16(%r9),%r9
+	jnz	L$cbc_fast_dec_loop
+	movq	56(%rsp),%r12
+	movq	0(%rbp),%r10
+	movq	8(%rbp),%r11
+	movq	%r10,0(%r12)
+	movq	%r11,8(%r12)
+	jmp	L$cbc_fast_cleanup
+
+.p2align	4
+L$cbc_fast_dec_in_place:
+	movq	0(%rbp),%r10
+	movq	8(%rbp),%r11
+	movq	%r10,0+64(%rsp)
+	movq	%r11,8+64(%rsp)
+.p2align	2
+L$cbc_fast_dec_in_place_loop:
+	movl	0(%r8),%eax
+	movl	4(%r8),%ebx
+	movl	8(%r8),%ecx
+	movl	12(%r8),%edx
+	movq	0(%rsp),%r15
+	movq	%r8,24(%rsp)
+
+	call	_x86_64_AES_decrypt
+
+	movq	24(%rsp),%r8
+	movq	40(%rsp),%r10
+	xorl	0+64(%rsp),%eax
+	xorl	4+64(%rsp),%ebx
+	xorl	8+64(%rsp),%ecx
+	xorl	12+64(%rsp),%edx
+
+	movq	0(%r8),%r11
+	movq	8(%r8),%r12
+	subq	$16,%r10
+	jz	L$cbc_fast_dec_in_place_done
+
+	movq	%r11,0+64(%rsp)
+	movq	%r12,8+64(%rsp)
+
+	movl	%eax,0(%r9)
+	movl	%ebx,4(%r9)
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+
+	leaq	16(%r8),%r8
+	leaq	16(%r9),%r9
+	movq	%r10,40(%rsp)
+	jmp	L$cbc_fast_dec_in_place_loop
+L$cbc_fast_dec_in_place_done:
+	movq	56(%rsp),%rdi
+	movq	%r11,0(%rdi)
+	movq	%r12,8(%rdi)
+
+	movl	%eax,0(%r9)
+	movl	%ebx,4(%r9)
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+
+.p2align	2
+L$cbc_fast_cleanup:
+	cmpl	$0,80+240(%rsp)
+	leaq	80(%rsp),%rdi
+	je	L$cbc_exit
+	movl	$30,%ecx
+	xorq	%rax,%rax
+.long	0x90AB48F3	
+
+	jmp	L$cbc_exit
+
+
+.p2align	4
+L$cbc_slow_prologue:
+
+	leaq	-88(%rsp),%rbp
+	andq	$-64,%rbp
+
+	leaq	-88-63(%rcx),%r10
+	subq	%rbp,%r10
+	negq	%r10
+	andq	$960,%r10
+	subq	%r10,%rbp
+
+	xchgq	%rsp,%rbp
+
+	movq	%rbp,16(%rsp)
+L$cbc_slow_body:
+
+
+
+
+	movq	%r8,56(%rsp)
+	movq	%r8,%rbp
+	movq	%r9,%rbx
+	movq	%rsi,%r9
+	movq	%rdi,%r8
+	movq	%rcx,%r15
+	movq	%rdx,%r10
+
+	movl	240(%r15),%eax
+	movq	%r15,0(%rsp)
+	shll	$4,%eax
+	leaq	(%r15,%rax,1),%rax
+	movq	%rax,8(%rsp)
+
+
+	leaq	2048(%r14),%r14
+	leaq	768-8(%rsp),%rax
+	subq	%r14,%rax
+	andq	$768,%rax
+	leaq	(%r14,%rax,1),%r14
+
+	cmpq	$0,%rbx
+	je	L$SLOW_DECRYPT
+
+
+	testq	$-16,%r10
+	movl	0(%rbp),%eax
+	movl	4(%rbp),%ebx
+	movl	8(%rbp),%ecx
+	movl	12(%rbp),%edx
+	jz	L$cbc_slow_enc_tail	
+
+.p2align	2
+L$cbc_slow_enc_loop:
+	xorl	0(%r8),%eax
+	xorl	4(%r8),%ebx
+	xorl	8(%r8),%ecx
+	xorl	12(%r8),%edx
+	movq	0(%rsp),%r15
+	movq	%r8,24(%rsp)
+	movq	%r9,32(%rsp)
+	movq	%r10,40(%rsp)
+
+	call	_x86_64_AES_encrypt_compact
+
+	movq	24(%rsp),%r8
+	movq	32(%rsp),%r9
+	movq	40(%rsp),%r10
+	movl	%eax,0(%r9)
+	movl	%ebx,4(%r9)
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+
+	leaq	16(%r8),%r8
+	leaq	16(%r9),%r9
+	subq	$16,%r10
+	testq	$-16,%r10
+	jnz	L$cbc_slow_enc_loop
+	testq	$15,%r10
+	jnz	L$cbc_slow_enc_tail
+	movq	56(%rsp),%rbp
+	movl	%eax,0(%rbp)
+	movl	%ebx,4(%rbp)
+	movl	%ecx,8(%rbp)
+	movl	%edx,12(%rbp)
+
+	jmp	L$cbc_exit
+
+.p2align	2
+L$cbc_slow_enc_tail:
+	movq	%rax,%r11
+	movq	%rcx,%r12
+	movq	%r10,%rcx
+	movq	%r8,%rsi
+	movq	%r9,%rdi
+.long	0x9066A4F3		
+	movq	$16,%rcx
+	subq	%r10,%rcx
+	xorq	%rax,%rax
+.long	0x9066AAF3		
+	movq	%r9,%r8
+	movq	$16,%r10
+	movq	%r11,%rax
+	movq	%r12,%rcx
+	jmp	L$cbc_slow_enc_loop	
+
+.p2align	4
+L$SLOW_DECRYPT:
+	shrq	$3,%rax
+	addq	%rax,%r14
+
+	movq	0(%rbp),%r11
+	movq	8(%rbp),%r12
+	movq	%r11,0+64(%rsp)
+	movq	%r12,8+64(%rsp)
+
+.p2align	2
+L$cbc_slow_dec_loop:
+	movl	0(%r8),%eax
+	movl	4(%r8),%ebx
+	movl	8(%r8),%ecx
+	movl	12(%r8),%edx
+	movq	0(%rsp),%r15
+	movq	%r8,24(%rsp)
+	movq	%r9,32(%rsp)
+	movq	%r10,40(%rsp)
+
+	call	_x86_64_AES_decrypt_compact
+
+	movq	24(%rsp),%r8
+	movq	32(%rsp),%r9
+	movq	40(%rsp),%r10
+	xorl	0+64(%rsp),%eax
+	xorl	4+64(%rsp),%ebx
+	xorl	8+64(%rsp),%ecx
+	xorl	12+64(%rsp),%edx
+
+	movq	0(%r8),%r11
+	movq	8(%r8),%r12
+	subq	$16,%r10
+	jc	L$cbc_slow_dec_partial
+	jz	L$cbc_slow_dec_done
+
+	movq	%r11,0+64(%rsp)
+	movq	%r12,8+64(%rsp)
+
+	movl	%eax,0(%r9)
+	movl	%ebx,4(%r9)
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+
+	leaq	16(%r8),%r8
+	leaq	16(%r9),%r9
+	jmp	L$cbc_slow_dec_loop
+L$cbc_slow_dec_done:
+	movq	56(%rsp),%rdi
+	movq	%r11,0(%rdi)
+	movq	%r12,8(%rdi)
+
+	movl	%eax,0(%r9)
+	movl	%ebx,4(%r9)
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+
+	jmp	L$cbc_exit
+
+.p2align	2
+L$cbc_slow_dec_partial:
+	movq	56(%rsp),%rdi
+	movq	%r11,0(%rdi)
+	movq	%r12,8(%rdi)
+
+	movl	%eax,0+64(%rsp)
+	movl	%ebx,4+64(%rsp)
+	movl	%ecx,8+64(%rsp)
+	movl	%edx,12+64(%rsp)
+
+	movq	%r9,%rdi
+	leaq	64(%rsp),%rsi
+	leaq	16(%r10),%rcx
+.long	0x9066A4F3	
+	jmp	L$cbc_exit
+
+.p2align	4
+L$cbc_exit:
+	movq	16(%rsp),%rsi
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+L$cbc_popfq:
+	popfq
+L$cbc_epilogue:
+	.byte	0xf3,0xc3
+
+.p2align	6
+L$AES_Te:
+.long	0xa56363c6,0xa56363c6
+.long	0x847c7cf8,0x847c7cf8
+.long	0x997777ee,0x997777ee
+.long	0x8d7b7bf6,0x8d7b7bf6
+.long	0x0df2f2ff,0x0df2f2ff
+.long	0xbd6b6bd6,0xbd6b6bd6
+.long	0xb16f6fde,0xb16f6fde
+.long	0x54c5c591,0x54c5c591
+.long	0x50303060,0x50303060
+.long	0x03010102,0x03010102
+.long	0xa96767ce,0xa96767ce
+.long	0x7d2b2b56,0x7d2b2b56
+.long	0x19fefee7,0x19fefee7
+.long	0x62d7d7b5,0x62d7d7b5
+.long	0xe6abab4d,0xe6abab4d
+.long	0x9a7676ec,0x9a7676ec
+.long	0x45caca8f,0x45caca8f
+.long	0x9d82821f,0x9d82821f
+.long	0x40c9c989,0x40c9c989
+.long	0x877d7dfa,0x877d7dfa
+.long	0x15fafaef,0x15fafaef
+.long	0xeb5959b2,0xeb5959b2
+.long	0xc947478e,0xc947478e
+.long	0x0bf0f0fb,0x0bf0f0fb
+.long	0xecadad41,0xecadad41
+.long	0x67d4d4b3,0x67d4d4b3
+.long	0xfda2a25f,0xfda2a25f
+.long	0xeaafaf45,0xeaafaf45
+.long	0xbf9c9c23,0xbf9c9c23
+.long	0xf7a4a453,0xf7a4a453
+.long	0x967272e4,0x967272e4
+.long	0x5bc0c09b,0x5bc0c09b
+.long	0xc2b7b775,0xc2b7b775
+.long	0x1cfdfde1,0x1cfdfde1
+.long	0xae93933d,0xae93933d
+.long	0x6a26264c,0x6a26264c
+.long	0x5a36366c,0x5a36366c
+.long	0x413f3f7e,0x413f3f7e
+.long	0x02f7f7f5,0x02f7f7f5
+.long	0x4fcccc83,0x4fcccc83
+.long	0x5c343468,0x5c343468
+.long	0xf4a5a551,0xf4a5a551
+.long	0x34e5e5d1,0x34e5e5d1
+.long	0x08f1f1f9,0x08f1f1f9
+.long	0x937171e2,0x937171e2
+.long	0x73d8d8ab,0x73d8d8ab
+.long	0x53313162,0x53313162
+.long	0x3f15152a,0x3f15152a
+.long	0x0c040408,0x0c040408
+.long	0x52c7c795,0x52c7c795
+.long	0x65232346,0x65232346
+.long	0x5ec3c39d,0x5ec3c39d
+.long	0x28181830,0x28181830
+.long	0xa1969637,0xa1969637
+.long	0x0f05050a,0x0f05050a
+.long	0xb59a9a2f,0xb59a9a2f
+.long	0x0907070e,0x0907070e
+.long	0x36121224,0x36121224
+.long	0x9b80801b,0x9b80801b
+.long	0x3de2e2df,0x3de2e2df
+.long	0x26ebebcd,0x26ebebcd
+.long	0x6927274e,0x6927274e
+.long	0xcdb2b27f,0xcdb2b27f
+.long	0x9f7575ea,0x9f7575ea
+.long	0x1b090912,0x1b090912
+.long	0x9e83831d,0x9e83831d
+.long	0x742c2c58,0x742c2c58
+.long	0x2e1a1a34,0x2e1a1a34
+.long	0x2d1b1b36,0x2d1b1b36
+.long	0xb26e6edc,0xb26e6edc
+.long	0xee5a5ab4,0xee5a5ab4
+.long	0xfba0a05b,0xfba0a05b
+.long	0xf65252a4,0xf65252a4
+.long	0x4d3b3b76,0x4d3b3b76
+.long	0x61d6d6b7,0x61d6d6b7
+.long	0xceb3b37d,0xceb3b37d
+.long	0x7b292952,0x7b292952
+.long	0x3ee3e3dd,0x3ee3e3dd
+.long	0x712f2f5e,0x712f2f5e
+.long	0x97848413,0x97848413
+.long	0xf55353a6,0xf55353a6
+.long	0x68d1d1b9,0x68d1d1b9
+.long	0x00000000,0x00000000
+.long	0x2cededc1,0x2cededc1
+.long	0x60202040,0x60202040
+.long	0x1ffcfce3,0x1ffcfce3
+.long	0xc8b1b179,0xc8b1b179
+.long	0xed5b5bb6,0xed5b5bb6
+.long	0xbe6a6ad4,0xbe6a6ad4
+.long	0x46cbcb8d,0x46cbcb8d
+.long	0xd9bebe67,0xd9bebe67
+.long	0x4b393972,0x4b393972
+.long	0xde4a4a94,0xde4a4a94
+.long	0xd44c4c98,0xd44c4c98
+.long	0xe85858b0,0xe85858b0
+.long	0x4acfcf85,0x4acfcf85
+.long	0x6bd0d0bb,0x6bd0d0bb
+.long	0x2aefefc5,0x2aefefc5
+.long	0xe5aaaa4f,0xe5aaaa4f
+.long	0x16fbfbed,0x16fbfbed
+.long	0xc5434386,0xc5434386
+.long	0xd74d4d9a,0xd74d4d9a
+.long	0x55333366,0x55333366
+.long	0x94858511,0x94858511
+.long	0xcf45458a,0xcf45458a
+.long	0x10f9f9e9,0x10f9f9e9
+.long	0x06020204,0x06020204
+.long	0x817f7ffe,0x817f7ffe
+.long	0xf05050a0,0xf05050a0
+.long	0x443c3c78,0x443c3c78
+.long	0xba9f9f25,0xba9f9f25
+.long	0xe3a8a84b,0xe3a8a84b
+.long	0xf35151a2,0xf35151a2
+.long	0xfea3a35d,0xfea3a35d
+.long	0xc0404080,0xc0404080
+.long	0x8a8f8f05,0x8a8f8f05
+.long	0xad92923f,0xad92923f
+.long	0xbc9d9d21,0xbc9d9d21
+.long	0x48383870,0x48383870
+.long	0x04f5f5f1,0x04f5f5f1
+.long	0xdfbcbc63,0xdfbcbc63
+.long	0xc1b6b677,0xc1b6b677
+.long	0x75dadaaf,0x75dadaaf
+.long	0x63212142,0x63212142
+.long	0x30101020,0x30101020
+.long	0x1affffe5,0x1affffe5
+.long	0x0ef3f3fd,0x0ef3f3fd
+.long	0x6dd2d2bf,0x6dd2d2bf
+.long	0x4ccdcd81,0x4ccdcd81
+.long	0x140c0c18,0x140c0c18
+.long	0x35131326,0x35131326
+.long	0x2fececc3,0x2fececc3
+.long	0xe15f5fbe,0xe15f5fbe
+.long	0xa2979735,0xa2979735
+.long	0xcc444488,0xcc444488
+.long	0x3917172e,0x3917172e
+.long	0x57c4c493,0x57c4c493
+.long	0xf2a7a755,0xf2a7a755
+.long	0x827e7efc,0x827e7efc
+.long	0x473d3d7a,0x473d3d7a
+.long	0xac6464c8,0xac6464c8
+.long	0xe75d5dba,0xe75d5dba
+.long	0x2b191932,0x2b191932
+.long	0x957373e6,0x957373e6
+.long	0xa06060c0,0xa06060c0
+.long	0x98818119,0x98818119
+.long	0xd14f4f9e,0xd14f4f9e
+.long	0x7fdcdca3,0x7fdcdca3
+.long	0x66222244,0x66222244
+.long	0x7e2a2a54,0x7e2a2a54
+.long	0xab90903b,0xab90903b
+.long	0x8388880b,0x8388880b
+.long	0xca46468c,0xca46468c
+.long	0x29eeeec7,0x29eeeec7
+.long	0xd3b8b86b,0xd3b8b86b
+.long	0x3c141428,0x3c141428
+.long	0x79dedea7,0x79dedea7
+.long	0xe25e5ebc,0xe25e5ebc
+.long	0x1d0b0b16,0x1d0b0b16
+.long	0x76dbdbad,0x76dbdbad
+.long	0x3be0e0db,0x3be0e0db
+.long	0x56323264,0x56323264
+.long	0x4e3a3a74,0x4e3a3a74
+.long	0x1e0a0a14,0x1e0a0a14
+.long	0xdb494992,0xdb494992
+.long	0x0a06060c,0x0a06060c
+.long	0x6c242448,0x6c242448
+.long	0xe45c5cb8,0xe45c5cb8
+.long	0x5dc2c29f,0x5dc2c29f
+.long	0x6ed3d3bd,0x6ed3d3bd
+.long	0xefacac43,0xefacac43
+.long	0xa66262c4,0xa66262c4
+.long	0xa8919139,0xa8919139
+.long	0xa4959531,0xa4959531
+.long	0x37e4e4d3,0x37e4e4d3
+.long	0x8b7979f2,0x8b7979f2
+.long	0x32e7e7d5,0x32e7e7d5
+.long	0x43c8c88b,0x43c8c88b
+.long	0x5937376e,0x5937376e
+.long	0xb76d6dda,0xb76d6dda
+.long	0x8c8d8d01,0x8c8d8d01
+.long	0x64d5d5b1,0x64d5d5b1
+.long	0xd24e4e9c,0xd24e4e9c
+.long	0xe0a9a949,0xe0a9a949
+.long	0xb46c6cd8,0xb46c6cd8
+.long	0xfa5656ac,0xfa5656ac
+.long	0x07f4f4f3,0x07f4f4f3
+.long	0x25eaeacf,0x25eaeacf
+.long	0xaf6565ca,0xaf6565ca
+.long	0x8e7a7af4,0x8e7a7af4
+.long	0xe9aeae47,0xe9aeae47
+.long	0x18080810,0x18080810
+.long	0xd5baba6f,0xd5baba6f
+.long	0x887878f0,0x887878f0
+.long	0x6f25254a,0x6f25254a
+.long	0x722e2e5c,0x722e2e5c
+.long	0x241c1c38,0x241c1c38
+.long	0xf1a6a657,0xf1a6a657
+.long	0xc7b4b473,0xc7b4b473
+.long	0x51c6c697,0x51c6c697
+.long	0x23e8e8cb,0x23e8e8cb
+.long	0x7cdddda1,0x7cdddda1
+.long	0x9c7474e8,0x9c7474e8
+.long	0x211f1f3e,0x211f1f3e
+.long	0xdd4b4b96,0xdd4b4b96
+.long	0xdcbdbd61,0xdcbdbd61
+.long	0x868b8b0d,0x868b8b0d
+.long	0x858a8a0f,0x858a8a0f
+.long	0x907070e0,0x907070e0
+.long	0x423e3e7c,0x423e3e7c
+.long	0xc4b5b571,0xc4b5b571
+.long	0xaa6666cc,0xaa6666cc
+.long	0xd8484890,0xd8484890
+.long	0x05030306,0x05030306
+.long	0x01f6f6f7,0x01f6f6f7
+.long	0x120e0e1c,0x120e0e1c
+.long	0xa36161c2,0xa36161c2
+.long	0x5f35356a,0x5f35356a
+.long	0xf95757ae,0xf95757ae
+.long	0xd0b9b969,0xd0b9b969
+.long	0x91868617,0x91868617
+.long	0x58c1c199,0x58c1c199
+.long	0x271d1d3a,0x271d1d3a
+.long	0xb99e9e27,0xb99e9e27
+.long	0x38e1e1d9,0x38e1e1d9
+.long	0x13f8f8eb,0x13f8f8eb
+.long	0xb398982b,0xb398982b
+.long	0x33111122,0x33111122
+.long	0xbb6969d2,0xbb6969d2
+.long	0x70d9d9a9,0x70d9d9a9
+.long	0x898e8e07,0x898e8e07
+.long	0xa7949433,0xa7949433
+.long	0xb69b9b2d,0xb69b9b2d
+.long	0x221e1e3c,0x221e1e3c
+.long	0x92878715,0x92878715
+.long	0x20e9e9c9,0x20e9e9c9
+.long	0x49cece87,0x49cece87
+.long	0xff5555aa,0xff5555aa
+.long	0x78282850,0x78282850
+.long	0x7adfdfa5,0x7adfdfa5
+.long	0x8f8c8c03,0x8f8c8c03
+.long	0xf8a1a159,0xf8a1a159
+.long	0x80898909,0x80898909
+.long	0x170d0d1a,0x170d0d1a
+.long	0xdabfbf65,0xdabfbf65
+.long	0x31e6e6d7,0x31e6e6d7
+.long	0xc6424284,0xc6424284
+.long	0xb86868d0,0xb86868d0
+.long	0xc3414182,0xc3414182
+.long	0xb0999929,0xb0999929
+.long	0x772d2d5a,0x772d2d5a
+.long	0x110f0f1e,0x110f0f1e
+.long	0xcbb0b07b,0xcbb0b07b
+.long	0xfc5454a8,0xfc5454a8
+.long	0xd6bbbb6d,0xd6bbbb6d
+.long	0x3a16162c,0x3a16162c
+.byte	0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5
+.byte	0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76
+.byte	0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0
+.byte	0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0
+.byte	0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc
+.byte	0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15
+.byte	0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a
+.byte	0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75
+.byte	0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0
+.byte	0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84
+.byte	0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b
+.byte	0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf
+.byte	0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85
+.byte	0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8
+.byte	0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5
+.byte	0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2
+.byte	0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17
+.byte	0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73
+.byte	0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88
+.byte	0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb
+.byte	0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c
+.byte	0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79
+.byte	0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9
+.byte	0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08
+.byte	0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6
+.byte	0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a
+.byte	0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e
+.byte	0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e
+.byte	0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94
+.byte	0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf
+.byte	0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68
+.byte	0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
+.byte	0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5
+.byte	0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76
+.byte	0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0
+.byte	0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0
+.byte	0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc
+.byte	0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15
+.byte	0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a
+.byte	0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75
+.byte	0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0
+.byte	0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84
+.byte	0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b
+.byte	0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf
+.byte	0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85
+.byte	0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8
+.byte	0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5
+.byte	0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2
+.byte	0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17
+.byte	0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73
+.byte	0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88
+.byte	0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb
+.byte	0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c
+.byte	0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79
+.byte	0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9
+.byte	0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08
+.byte	0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6
+.byte	0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a
+.byte	0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e
+.byte	0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e
+.byte	0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94
+.byte	0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf
+.byte	0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68
+.byte	0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
+.byte	0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5
+.byte	0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76
+.byte	0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0
+.byte	0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0
+.byte	0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc
+.byte	0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15
+.byte	0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a
+.byte	0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75
+.byte	0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0
+.byte	0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84
+.byte	0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b
+.byte	0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf
+.byte	0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85
+.byte	0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8
+.byte	0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5
+.byte	0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2
+.byte	0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17
+.byte	0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73
+.byte	0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88
+.byte	0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb
+.byte	0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c
+.byte	0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79
+.byte	0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9
+.byte	0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08
+.byte	0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6
+.byte	0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a
+.byte	0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e
+.byte	0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e
+.byte	0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94
+.byte	0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf
+.byte	0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68
+.byte	0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
+.byte	0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5
+.byte	0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76
+.byte	0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0
+.byte	0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0
+.byte	0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc
+.byte	0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15
+.byte	0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a
+.byte	0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75
+.byte	0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0
+.byte	0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84
+.byte	0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b
+.byte	0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf
+.byte	0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85
+.byte	0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8
+.byte	0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5
+.byte	0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2
+.byte	0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17
+.byte	0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73
+.byte	0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88
+.byte	0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb
+.byte	0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c
+.byte	0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79
+.byte	0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9
+.byte	0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08
+.byte	0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6
+.byte	0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a
+.byte	0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e
+.byte	0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e
+.byte	0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94
+.byte	0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf
+.byte	0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68
+.byte	0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
+.long	0x00000001, 0x00000002, 0x00000004, 0x00000008
+.long	0x00000010, 0x00000020, 0x00000040, 0x00000080
+.long	0x0000001b, 0x00000036, 0x80808080, 0x80808080
+.long	0xfefefefe, 0xfefefefe, 0x1b1b1b1b, 0x1b1b1b1b
+.p2align	6
+L$AES_Td:
+.long	0x50a7f451,0x50a7f451
+.long	0x5365417e,0x5365417e
+.long	0xc3a4171a,0xc3a4171a
+.long	0x965e273a,0x965e273a
+.long	0xcb6bab3b,0xcb6bab3b
+.long	0xf1459d1f,0xf1459d1f
+.long	0xab58faac,0xab58faac
+.long	0x9303e34b,0x9303e34b
+.long	0x55fa3020,0x55fa3020
+.long	0xf66d76ad,0xf66d76ad
+.long	0x9176cc88,0x9176cc88
+.long	0x254c02f5,0x254c02f5
+.long	0xfcd7e54f,0xfcd7e54f
+.long	0xd7cb2ac5,0xd7cb2ac5
+.long	0x80443526,0x80443526
+.long	0x8fa362b5,0x8fa362b5
+.long	0x495ab1de,0x495ab1de
+.long	0x671bba25,0x671bba25
+.long	0x980eea45,0x980eea45
+.long	0xe1c0fe5d,0xe1c0fe5d
+.long	0x02752fc3,0x02752fc3
+.long	0x12f04c81,0x12f04c81
+.long	0xa397468d,0xa397468d
+.long	0xc6f9d36b,0xc6f9d36b
+.long	0xe75f8f03,0xe75f8f03
+.long	0x959c9215,0x959c9215
+.long	0xeb7a6dbf,0xeb7a6dbf
+.long	0xda595295,0xda595295
+.long	0x2d83bed4,0x2d83bed4
+.long	0xd3217458,0xd3217458
+.long	0x2969e049,0x2969e049
+.long	0x44c8c98e,0x44c8c98e
+.long	0x6a89c275,0x6a89c275
+.long	0x78798ef4,0x78798ef4
+.long	0x6b3e5899,0x6b3e5899
+.long	0xdd71b927,0xdd71b927
+.long	0xb64fe1be,0xb64fe1be
+.long	0x17ad88f0,0x17ad88f0
+.long	0x66ac20c9,0x66ac20c9
+.long	0xb43ace7d,0xb43ace7d
+.long	0x184adf63,0x184adf63
+.long	0x82311ae5,0x82311ae5
+.long	0x60335197,0x60335197
+.long	0x457f5362,0x457f5362
+.long	0xe07764b1,0xe07764b1
+.long	0x84ae6bbb,0x84ae6bbb
+.long	0x1ca081fe,0x1ca081fe
+.long	0x942b08f9,0x942b08f9
+.long	0x58684870,0x58684870
+.long	0x19fd458f,0x19fd458f
+.long	0x876cde94,0x876cde94
+.long	0xb7f87b52,0xb7f87b52
+.long	0x23d373ab,0x23d373ab
+.long	0xe2024b72,0xe2024b72
+.long	0x578f1fe3,0x578f1fe3
+.long	0x2aab5566,0x2aab5566
+.long	0x0728ebb2,0x0728ebb2
+.long	0x03c2b52f,0x03c2b52f
+.long	0x9a7bc586,0x9a7bc586
+.long	0xa50837d3,0xa50837d3
+.long	0xf2872830,0xf2872830
+.long	0xb2a5bf23,0xb2a5bf23
+.long	0xba6a0302,0xba6a0302
+.long	0x5c8216ed,0x5c8216ed
+.long	0x2b1ccf8a,0x2b1ccf8a
+.long	0x92b479a7,0x92b479a7
+.long	0xf0f207f3,0xf0f207f3
+.long	0xa1e2694e,0xa1e2694e
+.long	0xcdf4da65,0xcdf4da65
+.long	0xd5be0506,0xd5be0506
+.long	0x1f6234d1,0x1f6234d1
+.long	0x8afea6c4,0x8afea6c4
+.long	0x9d532e34,0x9d532e34
+.long	0xa055f3a2,0xa055f3a2
+.long	0x32e18a05,0x32e18a05
+.long	0x75ebf6a4,0x75ebf6a4
+.long	0x39ec830b,0x39ec830b
+.long	0xaaef6040,0xaaef6040
+.long	0x069f715e,0x069f715e
+.long	0x51106ebd,0x51106ebd
+.long	0xf98a213e,0xf98a213e
+.long	0x3d06dd96,0x3d06dd96
+.long	0xae053edd,0xae053edd
+.long	0x46bde64d,0x46bde64d
+.long	0xb58d5491,0xb58d5491
+.long	0x055dc471,0x055dc471
+.long	0x6fd40604,0x6fd40604
+.long	0xff155060,0xff155060
+.long	0x24fb9819,0x24fb9819
+.long	0x97e9bdd6,0x97e9bdd6
+.long	0xcc434089,0xcc434089
+.long	0x779ed967,0x779ed967
+.long	0xbd42e8b0,0xbd42e8b0
+.long	0x888b8907,0x888b8907
+.long	0x385b19e7,0x385b19e7
+.long	0xdbeec879,0xdbeec879
+.long	0x470a7ca1,0x470a7ca1
+.long	0xe90f427c,0xe90f427c
+.long	0xc91e84f8,0xc91e84f8
+.long	0x00000000,0x00000000
+.long	0x83868009,0x83868009
+.long	0x48ed2b32,0x48ed2b32
+.long	0xac70111e,0xac70111e
+.long	0x4e725a6c,0x4e725a6c
+.long	0xfbff0efd,0xfbff0efd
+.long	0x5638850f,0x5638850f
+.long	0x1ed5ae3d,0x1ed5ae3d
+.long	0x27392d36,0x27392d36
+.long	0x64d90f0a,0x64d90f0a
+.long	0x21a65c68,0x21a65c68
+.long	0xd1545b9b,0xd1545b9b
+.long	0x3a2e3624,0x3a2e3624
+.long	0xb1670a0c,0xb1670a0c
+.long	0x0fe75793,0x0fe75793
+.long	0xd296eeb4,0xd296eeb4
+.long	0x9e919b1b,0x9e919b1b
+.long	0x4fc5c080,0x4fc5c080
+.long	0xa220dc61,0xa220dc61
+.long	0x694b775a,0x694b775a
+.long	0x161a121c,0x161a121c
+.long	0x0aba93e2,0x0aba93e2
+.long	0xe52aa0c0,0xe52aa0c0
+.long	0x43e0223c,0x43e0223c
+.long	0x1d171b12,0x1d171b12
+.long	0x0b0d090e,0x0b0d090e
+.long	0xadc78bf2,0xadc78bf2
+.long	0xb9a8b62d,0xb9a8b62d
+.long	0xc8a91e14,0xc8a91e14
+.long	0x8519f157,0x8519f157
+.long	0x4c0775af,0x4c0775af
+.long	0xbbdd99ee,0xbbdd99ee
+.long	0xfd607fa3,0xfd607fa3
+.long	0x9f2601f7,0x9f2601f7
+.long	0xbcf5725c,0xbcf5725c
+.long	0xc53b6644,0xc53b6644
+.long	0x347efb5b,0x347efb5b
+.long	0x7629438b,0x7629438b
+.long	0xdcc623cb,0xdcc623cb
+.long	0x68fcedb6,0x68fcedb6
+.long	0x63f1e4b8,0x63f1e4b8
+.long	0xcadc31d7,0xcadc31d7
+.long	0x10856342,0x10856342
+.long	0x40229713,0x40229713
+.long	0x2011c684,0x2011c684
+.long	0x7d244a85,0x7d244a85
+.long	0xf83dbbd2,0xf83dbbd2
+.long	0x1132f9ae,0x1132f9ae
+.long	0x6da129c7,0x6da129c7
+.long	0x4b2f9e1d,0x4b2f9e1d
+.long	0xf330b2dc,0xf330b2dc
+.long	0xec52860d,0xec52860d
+.long	0xd0e3c177,0xd0e3c177
+.long	0x6c16b32b,0x6c16b32b
+.long	0x99b970a9,0x99b970a9
+.long	0xfa489411,0xfa489411
+.long	0x2264e947,0x2264e947
+.long	0xc48cfca8,0xc48cfca8
+.long	0x1a3ff0a0,0x1a3ff0a0
+.long	0xd82c7d56,0xd82c7d56
+.long	0xef903322,0xef903322
+.long	0xc74e4987,0xc74e4987
+.long	0xc1d138d9,0xc1d138d9
+.long	0xfea2ca8c,0xfea2ca8c
+.long	0x360bd498,0x360bd498
+.long	0xcf81f5a6,0xcf81f5a6
+.long	0x28de7aa5,0x28de7aa5
+.long	0x268eb7da,0x268eb7da
+.long	0xa4bfad3f,0xa4bfad3f
+.long	0xe49d3a2c,0xe49d3a2c
+.long	0x0d927850,0x0d927850
+.long	0x9bcc5f6a,0x9bcc5f6a
+.long	0x62467e54,0x62467e54
+.long	0xc2138df6,0xc2138df6
+.long	0xe8b8d890,0xe8b8d890
+.long	0x5ef7392e,0x5ef7392e
+.long	0xf5afc382,0xf5afc382
+.long	0xbe805d9f,0xbe805d9f
+.long	0x7c93d069,0x7c93d069
+.long	0xa92dd56f,0xa92dd56f
+.long	0xb31225cf,0xb31225cf
+.long	0x3b99acc8,0x3b99acc8
+.long	0xa77d1810,0xa77d1810
+.long	0x6e639ce8,0x6e639ce8
+.long	0x7bbb3bdb,0x7bbb3bdb
+.long	0x097826cd,0x097826cd
+.long	0xf418596e,0xf418596e
+.long	0x01b79aec,0x01b79aec
+.long	0xa89a4f83,0xa89a4f83
+.long	0x656e95e6,0x656e95e6
+.long	0x7ee6ffaa,0x7ee6ffaa
+.long	0x08cfbc21,0x08cfbc21
+.long	0xe6e815ef,0xe6e815ef
+.long	0xd99be7ba,0xd99be7ba
+.long	0xce366f4a,0xce366f4a
+.long	0xd4099fea,0xd4099fea
+.long	0xd67cb029,0xd67cb029
+.long	0xafb2a431,0xafb2a431
+.long	0x31233f2a,0x31233f2a
+.long	0x3094a5c6,0x3094a5c6
+.long	0xc066a235,0xc066a235
+.long	0x37bc4e74,0x37bc4e74
+.long	0xa6ca82fc,0xa6ca82fc
+.long	0xb0d090e0,0xb0d090e0
+.long	0x15d8a733,0x15d8a733
+.long	0x4a9804f1,0x4a9804f1
+.long	0xf7daec41,0xf7daec41
+.long	0x0e50cd7f,0x0e50cd7f
+.long	0x2ff69117,0x2ff69117
+.long	0x8dd64d76,0x8dd64d76
+.long	0x4db0ef43,0x4db0ef43
+.long	0x544daacc,0x544daacc
+.long	0xdf0496e4,0xdf0496e4
+.long	0xe3b5d19e,0xe3b5d19e
+.long	0x1b886a4c,0x1b886a4c
+.long	0xb81f2cc1,0xb81f2cc1
+.long	0x7f516546,0x7f516546
+.long	0x04ea5e9d,0x04ea5e9d
+.long	0x5d358c01,0x5d358c01
+.long	0x737487fa,0x737487fa
+.long	0x2e410bfb,0x2e410bfb
+.long	0x5a1d67b3,0x5a1d67b3
+.long	0x52d2db92,0x52d2db92
+.long	0x335610e9,0x335610e9
+.long	0x1347d66d,0x1347d66d
+.long	0x8c61d79a,0x8c61d79a
+.long	0x7a0ca137,0x7a0ca137
+.long	0x8e14f859,0x8e14f859
+.long	0x893c13eb,0x893c13eb
+.long	0xee27a9ce,0xee27a9ce
+.long	0x35c961b7,0x35c961b7
+.long	0xede51ce1,0xede51ce1
+.long	0x3cb1477a,0x3cb1477a
+.long	0x59dfd29c,0x59dfd29c
+.long	0x3f73f255,0x3f73f255
+.long	0x79ce1418,0x79ce1418
+.long	0xbf37c773,0xbf37c773
+.long	0xeacdf753,0xeacdf753
+.long	0x5baafd5f,0x5baafd5f
+.long	0x146f3ddf,0x146f3ddf
+.long	0x86db4478,0x86db4478
+.long	0x81f3afca,0x81f3afca
+.long	0x3ec468b9,0x3ec468b9
+.long	0x2c342438,0x2c342438
+.long	0x5f40a3c2,0x5f40a3c2
+.long	0x72c31d16,0x72c31d16
+.long	0x0c25e2bc,0x0c25e2bc
+.long	0x8b493c28,0x8b493c28
+.long	0x41950dff,0x41950dff
+.long	0x7101a839,0x7101a839
+.long	0xdeb30c08,0xdeb30c08
+.long	0x9ce4b4d8,0x9ce4b4d8
+.long	0x90c15664,0x90c15664
+.long	0x6184cb7b,0x6184cb7b
+.long	0x70b632d5,0x70b632d5
+.long	0x745c6c48,0x745c6c48
+.long	0x4257b8d0,0x4257b8d0
+.byte	0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38
+.byte	0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb
+.byte	0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87
+.byte	0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb
+.byte	0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d
+.byte	0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e
+.byte	0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2
+.byte	0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25
+.byte	0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16
+.byte	0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92
+.byte	0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda
+.byte	0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84
+.byte	0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a
+.byte	0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06
+.byte	0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02
+.byte	0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b
+.byte	0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea
+.byte	0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73
+.byte	0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85
+.byte	0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e
+.byte	0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89
+.byte	0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b
+.byte	0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20
+.byte	0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4
+.byte	0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31
+.byte	0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f
+.byte	0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d
+.byte	0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef
+.byte	0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0
+.byte	0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61
+.byte	0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26
+.byte	0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
+.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
+.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
+.byte	0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38
+.byte	0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb
+.byte	0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87
+.byte	0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb
+.byte	0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d
+.byte	0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e
+.byte	0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2
+.byte	0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25
+.byte	0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16
+.byte	0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92
+.byte	0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda
+.byte	0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84
+.byte	0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a
+.byte	0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06
+.byte	0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02
+.byte	0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b
+.byte	0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea
+.byte	0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73
+.byte	0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85
+.byte	0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e
+.byte	0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89
+.byte	0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b
+.byte	0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20
+.byte	0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4
+.byte	0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31
+.byte	0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f
+.byte	0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d
+.byte	0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef
+.byte	0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0
+.byte	0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61
+.byte	0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26
+.byte	0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
+.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
+.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
+.byte	0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38
+.byte	0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb
+.byte	0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87
+.byte	0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb
+.byte	0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d
+.byte	0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e
+.byte	0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2
+.byte	0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25
+.byte	0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16
+.byte	0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92
+.byte	0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda
+.byte	0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84
+.byte	0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a
+.byte	0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06
+.byte	0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02
+.byte	0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b
+.byte	0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea
+.byte	0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73
+.byte	0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85
+.byte	0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e
+.byte	0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89
+.byte	0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b
+.byte	0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20
+.byte	0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4
+.byte	0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31
+.byte	0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f
+.byte	0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d
+.byte	0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef
+.byte	0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0
+.byte	0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61
+.byte	0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26
+.byte	0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
+.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
+.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
+.byte	0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38
+.byte	0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb
+.byte	0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87
+.byte	0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb
+.byte	0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d
+.byte	0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e
+.byte	0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2
+.byte	0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25
+.byte	0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16
+.byte	0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92
+.byte	0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda
+.byte	0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84
+.byte	0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a
+.byte	0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06
+.byte	0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02
+.byte	0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b
+.byte	0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea
+.byte	0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73
+.byte	0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85
+.byte	0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e
+.byte	0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89
+.byte	0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b
+.byte	0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20
+.byte	0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4
+.byte	0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31
+.byte	0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f
+.byte	0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d
+.byte	0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef
+.byte	0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0
+.byte	0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61
+.byte	0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26
+.byte	0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
+.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
+.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
+.byte	65,69,83,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.p2align	6
diff --git a/crypto/libressl/crypto/aes/aes_cbc.c b/crypto/libressl/crypto/aes/aes_cbc.c
new file mode 100644
index 0000000000..4688cfc9c8
--- /dev/null
+++ b/crypto/libressl/crypto/aes/aes_cbc.c
@@ -0,0 +1,65 @@
+/* $OpenBSD$ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include 
+#include 
+
+void
+AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+    size_t len, const AES_KEY *key, unsigned char *ivec, const int enc)
+{
+	if (enc)
+		CRYPTO_cbc128_encrypt(in, out, len, key, ivec,
+		    (block128_f)AES_encrypt);
+	else
+		CRYPTO_cbc128_decrypt(in, out, len, key, ivec,
+		    (block128_f)AES_decrypt);
+}
diff --git a/crypto/libressl/crypto/aes/aes_cfb.c b/crypto/libressl/crypto/aes/aes_cfb.c
new file mode 100644
index 0000000000..3575780929
--- /dev/null
+++ b/crypto/libressl/crypto/aes/aes_cfb.c
@@ -0,0 +1,84 @@
+/* $OpenBSD$ */
+/* ====================================================================
+ * Copyright (c) 2002-2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include 
+#include 
+
+/* The input and output encrypted as though 128bit cfb mode is being
+ * used.  The extra state information to record how much of the
+ * 128bit block we have used is contained in *num;
+ */
+
+void
+AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, size_t length,
+    const AES_KEY *key, unsigned char *ivec, int *num, const int enc)
+{
+	CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc,
+	    (block128_f)AES_encrypt);
+}
+
+/* N.B. This expects the input to be packed, MS bit first */
+void
+AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, size_t length,
+    const AES_KEY *key, unsigned char *ivec, int *num, const int enc)
+{
+	CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc,
+	    (block128_f)AES_encrypt);
+}
+
+void
+AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, size_t length,
+    const AES_KEY *key, unsigned char *ivec, int *num, const int enc)
+{
+	CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc,
+	    (block128_f)AES_encrypt);
+}
+
diff --git a/crypto/libressl/crypto/aes/aes_core.c b/crypto/libressl/crypto/aes/aes_core.c
new file mode 100644
index 0000000000..d1b7a966b7
--- /dev/null
+++ b/crypto/libressl/crypto/aes/aes_core.c
@@ -0,0 +1,1374 @@
+/* $OpenBSD: aes_core.c,v 1.12 2015/02/10 09:46:30 miod Exp $ */
+/**
+ * rijndael-alg-fst.c
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen 
+ * @author Antoon Bosselaers 
+ * @author Paulo Barreto 
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Note: rewritten a little bit to provide error control and an OpenSSL-
+   compatible API */
+
+#ifndef AES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+
+#include 
+#include 
+#include "aes_locl.h"
+
+#ifndef AES_ASM
+/*
+Te0[x] = S [x].[02, 01, 01, 03];
+Te1[x] = S [x].[03, 02, 01, 01];
+Te2[x] = S [x].[01, 03, 02, 01];
+Te3[x] = S [x].[01, 01, 03, 02];
+
+Td0[x] = Si[x].[0e, 09, 0d, 0b];
+Td1[x] = Si[x].[0b, 0e, 09, 0d];
+Td2[x] = Si[x].[0d, 0b, 0e, 09];
+Td3[x] = Si[x].[09, 0d, 0b, 0e];
+Td4[x] = Si[x].[01];
+*/
+
+static const u32 Te0[256] = {
+	0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+	0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+	0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+	0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+	0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+	0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+	0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+	0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+	0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+	0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+	0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+	0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+	0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+	0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+	0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+	0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+	0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+	0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+	0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+	0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+	0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+	0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+	0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+	0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+	0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+	0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+	0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+	0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+	0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+	0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+	0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+	0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+	0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+	0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+	0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+	0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+	0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+	0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+	0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+	0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+	0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+	0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+	0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+	0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+	0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+	0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+	0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+	0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+	0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+	0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+	0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+	0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+	0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+	0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+	0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+	0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+	0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+	0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+	0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+	0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+	0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+	0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+	0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+	0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+};
+static const u32 Te1[256] = {
+	0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+	0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+	0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+	0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+	0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+	0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+	0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+	0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+	0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+	0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+	0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+	0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+	0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+	0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+	0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+	0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+	0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+	0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+	0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+	0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+	0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+	0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+	0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+	0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+	0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+	0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+	0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+	0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+	0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+	0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+	0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+	0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+	0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+	0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+	0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+	0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+	0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+	0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+	0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+	0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+	0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+	0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+	0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+	0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+	0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+	0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+	0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+	0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+	0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+	0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+	0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+	0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+	0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+	0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+	0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+	0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+	0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+	0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+	0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+	0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+	0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+	0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+	0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+	0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+};
+static const u32 Te2[256] = {
+	0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+	0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+	0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+	0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+	0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+	0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+	0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+	0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+	0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+	0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+	0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+	0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+	0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+	0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+	0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+	0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+	0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+	0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+	0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+	0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+	0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+	0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+	0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+	0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+	0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+	0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+	0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+	0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+	0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+	0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+	0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+	0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+	0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+	0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+	0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+	0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+	0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+	0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+	0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+	0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+	0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+	0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+	0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+	0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+	0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+	0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+	0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+	0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+	0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+	0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+	0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+	0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+	0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+	0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+	0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+	0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+	0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+	0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+	0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+	0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+	0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+	0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+	0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+	0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+};
+static const u32 Te3[256] = {
+	0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+	0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+	0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+	0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+	0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+	0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+	0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+	0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+	0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+	0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+	0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+	0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+	0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+	0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+	0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+	0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+	0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+	0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+	0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+	0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+	0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+	0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+	0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+	0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+	0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+	0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+	0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+	0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+	0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+	0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+	0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+	0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+	0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+	0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+	0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+	0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+	0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+	0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+	0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+	0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+	0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+	0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+	0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+	0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+	0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+	0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+	0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+	0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+	0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+	0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+	0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+	0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+	0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+	0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+	0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+	0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+	0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+	0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+	0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+	0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+	0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+	0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+	0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+	0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+};
+
+static const u32 Td0[256] = {
+	0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
+	0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
+	0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
+	0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
+	0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
+	0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
+	0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
+	0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
+	0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
+	0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
+	0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
+	0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
+	0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
+	0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
+	0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
+	0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
+	0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
+	0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
+	0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
+	0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
+	0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
+	0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
+	0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
+	0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
+	0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
+	0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
+	0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
+	0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
+	0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
+	0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
+	0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
+	0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
+	0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
+	0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
+	0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
+	0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
+	0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
+	0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
+	0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
+	0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
+	0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
+	0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
+	0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
+	0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
+	0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
+	0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
+	0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
+	0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
+	0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
+	0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
+	0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
+	0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
+	0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
+	0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
+	0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
+	0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
+	0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
+	0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
+	0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
+	0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
+	0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
+	0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
+	0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
+	0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
+};
+static const u32 Td1[256] = {
+	0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
+	0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
+	0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
+	0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
+	0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
+	0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
+	0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
+	0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
+	0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
+	0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
+	0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
+	0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
+	0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
+	0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
+	0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
+	0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
+	0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
+	0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
+	0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
+	0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
+	0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
+	0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
+	0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
+	0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
+	0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
+	0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
+	0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
+	0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
+	0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
+	0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
+	0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
+	0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
+	0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
+	0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
+	0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
+	0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
+	0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
+	0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
+	0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
+	0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
+	0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
+	0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
+	0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
+	0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
+	0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
+	0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
+	0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
+	0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
+	0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
+	0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
+	0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
+	0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
+	0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
+	0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
+	0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
+	0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
+	0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
+	0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
+	0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
+	0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
+	0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
+	0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
+	0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
+	0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
+};
+static const u32 Td2[256] = {
+	0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
+	0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
+	0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
+	0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
+	0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
+	0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
+	0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
+	0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
+	0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
+	0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
+	0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
+	0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
+	0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
+	0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
+	0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
+	0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
+	0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
+	0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
+	0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
+	0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
+	0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
+	0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
+	0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
+	0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
+	0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
+	0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
+	0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
+	0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
+	0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
+	0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
+	0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
+	0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
+	0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
+	0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
+	0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
+	0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
+	0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
+	0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
+	0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
+	0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
+	0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
+	0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
+	0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
+	0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
+	0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
+	0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
+	0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
+	0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
+	0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
+	0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
+	0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
+	0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
+	0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
+	0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
+	0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
+	0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
+	0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
+	0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
+	0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
+	0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
+	0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
+	0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
+	0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
+	0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
+};
+static const u32 Td3[256] = {
+	0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
+	0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
+	0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
+	0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
+	0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
+	0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
+	0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
+	0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
+	0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
+	0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
+	0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
+	0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
+	0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
+	0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
+	0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
+	0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
+	0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
+	0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
+	0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
+	0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
+	0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
+	0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
+	0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
+	0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
+	0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
+	0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
+	0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
+	0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
+	0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
+	0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
+	0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
+	0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
+	0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
+	0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
+	0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
+	0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
+	0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
+	0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
+	0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
+	0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
+	0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
+	0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
+	0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
+	0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
+	0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
+	0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
+	0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
+	0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
+	0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
+	0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
+	0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
+	0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
+	0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
+	0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
+	0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
+	0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
+	0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
+	0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
+	0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
+	0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
+	0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
+	0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
+	0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
+	0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
+};
+static const u8 Td4[256] = {
+	0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
+	0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
+	0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
+	0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
+	0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
+	0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
+	0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
+	0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
+	0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
+	0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
+	0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
+	0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
+	0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
+	0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
+	0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
+	0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
+	0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
+	0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
+	0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
+	0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
+	0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
+	0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
+	0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
+	0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
+	0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
+	0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
+	0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
+	0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
+	0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
+	0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
+	0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
+	0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
+};
+static const u32 rcon[] = {
+	0x01000000, 0x02000000, 0x04000000, 0x08000000,
+	0x10000000, 0x20000000, 0x40000000, 0x80000000,
+	0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+
+/**
+ * Expand the cipher key into the encryption key schedule.
+ */
+int
+AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key)
+{
+	u32 *rk;
+	int i = 0;
+	u32 temp;
+
+	if (!userKey || !key)
+		return -1;
+	if (bits != 128 && bits != 192 && bits != 256)
+		return -2;
+
+	rk = key->rd_key;
+
+	if (bits == 128)
+		key->rounds = 10;
+	else if (bits == 192)
+		key->rounds = 12;
+	else
+		key->rounds = 14;
+
+	rk[0] = GETU32(userKey);
+	rk[1] = GETU32(userKey + 4);
+	rk[2] = GETU32(userKey + 8);
+	rk[3] = GETU32(userKey + 12);
+	if (bits == 128) {
+		while (1) {
+			temp = rk[3];
+			rk[4] = rk[0] ^
+			    (Te2[(temp >> 16) & 0xff] & 0xff000000) ^
+			    (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
+			    (Te0[(temp) & 0xff] & 0x0000ff00) ^
+			    (Te1[(temp >> 24)] & 0x000000ff) ^
+			    rcon[i];
+			rk[5] = rk[1] ^ rk[4];
+			rk[6] = rk[2] ^ rk[5];
+			rk[7] = rk[3] ^ rk[6];
+			if (++i == 10) {
+				return 0;
+			}
+			rk += 4;
+		}
+	}
+	rk[4] = GETU32(userKey + 16);
+	rk[5] = GETU32(userKey + 20);
+	if (bits == 192) {
+		while (1) {
+			temp = rk[5];
+			rk[6] = rk[ 0] ^
+			    (Te2[(temp >> 16) & 0xff] & 0xff000000) ^
+			    (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
+			    (Te0[(temp) & 0xff] & 0x0000ff00) ^
+			    (Te1[(temp >> 24)] & 0x000000ff) ^
+			    rcon[i];
+			rk[7] = rk[1] ^ rk[6];
+			rk[8] = rk[2] ^ rk[7];
+			rk[9] = rk[3] ^ rk[8];
+			if (++i == 8) {
+				return 0;
+			}
+			rk[10] = rk[4] ^ rk[9];
+			rk[11] = rk[5] ^ rk[10];
+			rk += 6;
+		}
+	}
+	rk[6] = GETU32(userKey + 24);
+	rk[7] = GETU32(userKey + 28);
+	if (bits == 256) {
+		while (1) {
+			temp = rk[7];
+			rk[8] = rk[0] ^
+			    (Te2[(temp >> 16) & 0xff] & 0xff000000) ^
+			    (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
+			    (Te0[(temp) & 0xff] & 0x0000ff00) ^
+			    (Te1[(temp >> 24)] & 0x000000ff) ^
+			    rcon[i];
+			rk[9] = rk[1] ^ rk[8];
+			rk[10] = rk[2] ^ rk[9];
+			rk[11] = rk[3] ^ rk[10];
+			if (++i == 7) {
+				return 0;
+			}
+			temp = rk[11];
+			rk[12] = rk[4] ^
+			    (Te2[(temp >> 24)] & 0xff000000) ^
+			    (Te3[(temp >> 16) & 0xff] & 0x00ff0000) ^
+			    (Te0[(temp >> 8) & 0xff] & 0x0000ff00) ^
+			    (Te1[(temp) & 0xff] & 0x000000ff);
+			rk[13] = rk[5] ^ rk[12];
+			rk[14] = rk[6] ^ rk[13];
+			rk[15] = rk[7] ^ rk[14];
+
+			rk += 8;
+		}
+	}
+	return 0;
+}
+
+/**
+ * Expand the cipher key into the decryption key schedule.
+ */
+int
+AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key)
+{
+	u32 *rk;
+	int i, j, status;
+	u32 temp;
+
+	/* first, start with an encryption schedule */
+	status = AES_set_encrypt_key(userKey, bits, key);
+	if (status < 0)
+		return status;
+
+	rk = key->rd_key;
+
+	/* invert the order of the round keys: */
+	for (i = 0, j = 4 * (key->rounds); i < j; i += 4, j -= 4) {
+		temp = rk[i];
+		rk[i] = rk[j];
+		rk[j] = temp;
+		temp = rk[i + 1];
+		rk[i + 1] = rk[j + 1];
+		rk[j + 1] = temp;
+		temp = rk[i + 2];
+		rk[i + 2] = rk[j + 2];
+		rk[j + 2] = temp;
+		temp = rk[i + 3];
+		rk[i + 3] = rk[j + 3];
+		rk[j + 3] = temp;
+	}
+	/* apply the inverse MixColumn transform to all round keys but the first and the last: */
+	for (i = 1; i < (key->rounds); i++) {
+		rk += 4;
+		rk[0] =
+		    Td0[Te1[(rk[0] >> 24)] & 0xff] ^
+		    Td1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^
+		    Td2[Te1[(rk[0] >> 8) & 0xff] & 0xff] ^
+		    Td3[Te1[(rk[0]) & 0xff] & 0xff];
+		rk[1] =
+		    Td0[Te1[(rk[1] >> 24)] & 0xff] ^
+		    Td1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^
+		    Td2[Te1[(rk[1] >> 8) & 0xff] & 0xff] ^
+		    Td3[Te1[(rk[1]) & 0xff] & 0xff];
+		rk[2] =
+		    Td0[Te1[(rk[2] >> 24)] & 0xff] ^
+		    Td1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^
+		    Td2[Te1[(rk[2] >> 8) & 0xff] & 0xff] ^
+		    Td3[Te1[(rk[2]) & 0xff] & 0xff];
+		rk[3] =
+		    Td0[Te1[(rk[3] >> 24)] & 0xff] ^
+		    Td1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^
+		    Td2[Te1[(rk[3] >> 8) & 0xff] & 0xff] ^
+		    Td3[Te1[(rk[3]) & 0xff] & 0xff];
+	}
+	return 0;
+}
+
+/*
+ * Encrypt a single block
+ * in and out can overlap
+ */
+void
+AES_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key)
+{
+	const u32 *rk;
+	u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+	int r;
+#endif /* ?FULL_UNROLL */
+
+	rk = key->rd_key;
+
+	/*
+	 * map byte array block to cipher state
+	 * and add initial round key:
+	 */
+	s0 = GETU32(in     ) ^ rk[0];
+	s1 = GETU32(in +  4) ^ rk[1];
+	s2 = GETU32(in +  8) ^ rk[2];
+	s3 = GETU32(in + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+	/* round 1: */
+	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
+	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
+	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
+	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
+	/* round 2: */
+	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
+	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
+	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
+	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
+	/* round 3: */
+	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
+	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
+	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
+	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
+	/* round 4: */
+	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
+	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
+	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
+	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
+	/* round 5: */
+	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
+	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
+	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
+	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
+	/* round 6: */
+	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
+	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
+	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
+	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
+	/* round 7: */
+	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
+	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
+	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
+	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
+	/* round 8: */
+	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
+	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
+	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
+	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
+	/* round 9: */
+	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
+	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
+	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
+	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
+	if (key->rounds > 10) {
+		/* round 10: */
+		s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
+		s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
+		s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
+		s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
+		/* round 11: */
+		t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
+		t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
+		t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
+		t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
+		if (key->rounds > 12) {
+			/* round 12: */
+			s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
+			s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
+			s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
+			s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
+			/* round 13: */
+			t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
+			t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
+			t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
+			t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
+		}
+	}
+	rk += key->rounds << 2;
+#else  /* !FULL_UNROLL */
+    /*
+     * Nr - 1 full rounds:
+     */
+	r = key->rounds >> 1;
+	for (;;) {
+		t0 =
+		    Te0[(s0 >> 24)] ^
+		    Te1[(s1 >> 16) & 0xff] ^
+		    Te2[(s2 >> 8) & 0xff] ^
+		    Te3[(s3) & 0xff] ^
+		    rk[4];
+		t1 =
+		    Te0[(s1 >> 24)] ^
+		    Te1[(s2 >> 16) & 0xff] ^
+		    Te2[(s3 >> 8) & 0xff] ^
+		    Te3[(s0) & 0xff] ^
+		    rk[5];
+		t2 =
+		    Te0[(s2 >> 24)] ^
+		    Te1[(s3 >> 16) & 0xff] ^
+		    Te2[(s0 >> 8) & 0xff] ^
+		    Te3[(s1) & 0xff] ^
+		    rk[6];
+		t3 =
+		    Te0[(s3 >> 24)] ^
+		    Te1[(s0 >> 16) & 0xff] ^
+		    Te2[(s1 >> 8) & 0xff] ^
+		    Te3[(s2) & 0xff] ^
+		    rk[7];
+
+		rk += 8;
+		if (--r == 0) {
+			break;
+		}
+
+		s0 =
+		    Te0[(t0 >> 24)] ^
+		    Te1[(t1 >> 16) & 0xff] ^
+		    Te2[(t2 >> 8) & 0xff] ^
+		    Te3[(t3) & 0xff] ^
+		    rk[0];
+		s1 =
+		    Te0[(t1 >> 24)] ^
+		    Te1[(t2 >> 16) & 0xff] ^
+		    Te2[(t3 >> 8) & 0xff] ^
+		    Te3[(t0) & 0xff] ^
+		    rk[1];
+		s2 =
+		    Te0[(t2 >> 24)] ^
+		    Te1[(t3 >> 16) & 0xff] ^
+		    Te2[(t0 >> 8) & 0xff] ^
+		    Te3[(t1) & 0xff] ^
+		    rk[2];
+		s3 =
+		    Te0[(t3 >> 24)] ^
+		    Te1[(t0 >> 16) & 0xff] ^
+		    Te2[(t1 >> 8) & 0xff] ^
+		    Te3[(t2) & 0xff] ^
+		    rk[3];
+	}
+#endif /* ?FULL_UNROLL */
+	/*
+	 * apply last round and
+	 * map cipher state to byte array block:
+	 */
+	s0 =
+	    (Te2[(t0 >> 24)] & 0xff000000) ^
+	    (Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+	    (Te0[(t2 >> 8) & 0xff] & 0x0000ff00) ^
+	    (Te1[(t3) & 0xff] & 0x000000ff) ^
+	    rk[0];
+	PUTU32(out, s0);
+	s1 =
+	    (Te2[(t1 >> 24)] & 0xff000000) ^
+	    (Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+	    (Te0[(t3 >> 8) & 0xff] & 0x0000ff00) ^
+	    (Te1[(t0) & 0xff] & 0x000000ff) ^
+	    rk[1];
+	PUTU32(out +  4, s1);
+	s2 =
+	    (Te2[(t2 >> 24)] & 0xff000000) ^
+	    (Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+	    (Te0[(t0 >> 8) & 0xff] & 0x0000ff00) ^
+	    (Te1[(t1) & 0xff] & 0x000000ff) ^
+	    rk[2];
+	PUTU32(out +  8, s2);
+	s3 =
+	    (Te2[(t3 >> 24)] & 0xff000000) ^
+	    (Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+	    (Te0[(t1 >> 8) & 0xff] & 0x0000ff00) ^
+	    (Te1[(t2) & 0xff] & 0x000000ff) ^
+	    rk[3];
+	PUTU32(out + 12, s3);
+}
+
+/*
+ * Decrypt a single block
+ * in and out can overlap
+ */
+void
+AES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key)
+{
+	const u32 *rk;
+	u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+	int r;
+#endif /* ?FULL_UNROLL */
+
+	rk = key->rd_key;
+
+	/*
+	 * map byte array block to cipher state
+	 * and add initial round key:
+	 */
+	s0 = GETU32(in) ^ rk[0];
+	s1 = GETU32(in + 4) ^ rk[1];
+	s2 = GETU32(in + 8) ^ rk[2];
+	s3 = GETU32(in + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+	/* round 1: */
+	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
+	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
+	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
+	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
+	/* round 2: */
+	s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
+	s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
+	s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
+	s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
+	/* round 3: */
+	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
+	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
+	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
+	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
+	/* round 4: */
+	s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
+	s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
+	s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
+	s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
+	/* round 5: */
+	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
+	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
+	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
+	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
+	/* round 6: */
+	s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
+	s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
+	s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
+	s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
+	/* round 7: */
+	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
+	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
+	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
+	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
+	/* round 8: */
+	s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
+	s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
+	s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
+	s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
+	/* round 9: */
+	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
+	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
+	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
+	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
+	if (key->rounds > 10) {
+		/* round 10: */
+		s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
+		s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
+		s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
+		s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
+		/* round 11: */
+		t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
+		t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
+		t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
+		t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
+		if (key->rounds > 12) {
+			/* round 12: */
+			s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
+			s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
+			s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
+			s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
+			/* round 13: */
+			t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
+			t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
+			t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
+			t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
+		}
+	}
+	rk += key->rounds << 2;
+#else  /* !FULL_UNROLL */
+    /*
+     * Nr - 1 full rounds:
+     */
+	r = key->rounds >> 1;
+	for (;;) {
+		t0 =
+		    Td0[(s0 >> 24)] ^
+		    Td1[(s3 >> 16) & 0xff] ^
+		    Td2[(s2 >> 8) & 0xff] ^
+		    Td3[(s1) & 0xff] ^
+		    rk[4];
+		t1 =
+		    Td0[(s1 >> 24)] ^
+		    Td1[(s0 >> 16) & 0xff] ^
+		    Td2[(s3 >> 8) & 0xff] ^
+		    Td3[(s2) & 0xff] ^
+		    rk[5];
+		t2 =
+		    Td0[(s2 >> 24)] ^
+		    Td1[(s1 >> 16) & 0xff] ^
+		    Td2[(s0 >> 8) & 0xff] ^
+		    Td3[(s3) & 0xff] ^
+		    rk[6];
+		t3 =
+		    Td0[(s3 >> 24)] ^
+		    Td1[(s2 >> 16) & 0xff] ^
+		    Td2[(s1 >> 8) & 0xff] ^
+		    Td3[(s0) & 0xff] ^
+		    rk[7];
+
+		rk += 8;
+		if (--r == 0) {
+			break;
+		}
+
+		s0 =
+		    Td0[(t0 >> 24)] ^
+		    Td1[(t3 >> 16) & 0xff] ^
+		    Td2[(t2 >> 8) & 0xff] ^
+		    Td3[(t1) & 0xff] ^
+		    rk[0];
+		s1 =
+		    Td0[(t1 >> 24)] ^
+		    Td1[(t0 >> 16) & 0xff] ^
+		    Td2[(t3 >> 8) & 0xff] ^
+		    Td3[(t2) & 0xff] ^
+		    rk[1];
+		s2 =
+		    Td0[(t2 >> 24)] ^
+		    Td1[(t1 >> 16) & 0xff] ^
+		    Td2[(t0 >> 8) & 0xff] ^
+		    Td3[(t3) & 0xff] ^
+		    rk[2];
+		s3 =
+		    Td0[(t3 >> 24)] ^
+		    Td1[(t2 >> 16) & 0xff] ^
+		    Td2[(t1 >> 8) & 0xff] ^
+		    Td3[(t0) & 0xff] ^
+		    rk[3];
+	}
+#endif /* ?FULL_UNROLL */
+    /*
+	 * apply last round and
+	 * map cipher state to byte array block:
+	 */
+	s0 =
+	    (((uint32_t)Td4[(t0 >> 24)]) << 24) ^
+	    (Td4[(t3 >> 16) & 0xff] << 16) ^
+	    (Td4[(t2 >> 8) & 0xff] <<  8) ^
+	    (Td4[(t1) & 0xff]) ^
+	    rk[0];
+	PUTU32(out, s0);
+	s1 =
+	    (((uint32_t)Td4[(t1 >> 24)]) << 24) ^
+	    (Td4[(t0 >> 16) & 0xff] << 16) ^
+	    (Td4[(t3 >> 8) & 0xff] <<  8) ^
+	    (Td4[(t2) & 0xff]) ^
+	    rk[1];
+	PUTU32(out + 4, s1);
+	s2 =
+	    (((uint32_t)Td4[(t2 >> 24)]) << 24) ^
+	    (Td4[(t1 >> 16) & 0xff] << 16) ^
+	    (Td4[(t0 >> 8) & 0xff] <<  8) ^
+	    (Td4[(t3) & 0xff]) ^
+	    rk[2];
+	PUTU32(out + 8, s2);
+	s3 =
+	    (((uint32_t)Td4[(t3 >> 24)]) << 24) ^
+	    (Td4[(t2 >> 16) & 0xff] << 16) ^
+	    (Td4[(t1 >> 8) & 0xff] <<  8) ^
+	    (Td4[(t0) & 0xff]) ^
+	    rk[3];
+	PUTU32(out + 12, s3);
+}
+
+#else /* AES_ASM */
+
+static const u8 Te4[256] = {
+	0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
+	0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
+	0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
+	0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
+	0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
+	0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
+	0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
+	0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
+	0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
+	0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
+	0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
+	0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
+	0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
+	0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
+	0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
+	0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
+	0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
+	0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
+	0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
+	0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
+	0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
+	0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
+	0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
+	0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
+	0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
+	0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
+	0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
+	0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
+	0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
+	0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
+	0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
+	0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
+};
+static const u32 rcon[] = {
+	0x01000000, 0x02000000, 0x04000000, 0x08000000,
+	0x10000000, 0x20000000, 0x40000000, 0x80000000,
+	0x1B000000, 0x36000000,
+	/* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+
+/**
+ * Expand the cipher key into the encryption key schedule.
+ */
+int
+AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key)
+{
+	u32 *rk;
+	int i = 0;
+	u32 temp;
+
+	if (!userKey || !key)
+		return -1;
+	if (bits != 128 && bits != 192 && bits != 256)
+		return -2;
+
+	rk = key->rd_key;
+
+	if (bits == 128)
+		key->rounds = 10;
+	else if (bits == 192)
+		key->rounds = 12;
+	else
+		key->rounds = 14;
+
+	rk[0] = GETU32(userKey);
+	rk[1] = GETU32(userKey +  4);
+	rk[2] = GETU32(userKey +  8);
+	rk[3] = GETU32(userKey + 12);
+	if (bits == 128) {
+		while (1) {
+			temp = rk[3];
+			rk[4] = rk[0] ^
+			    (Te4[(temp >> 16) & 0xff] << 24) ^
+			    (Te4[(temp >> 8) & 0xff] << 16) ^
+			    (Te4[(temp) & 0xff] << 8) ^
+			    (Te4[(temp >> 24)]) ^
+			    rcon[i];
+			rk[5] = rk[1] ^ rk[4];
+			rk[6] = rk[2] ^ rk[5];
+			rk[7] = rk[3] ^ rk[6];
+			if (++i == 10) {
+				return 0;
+			}
+			rk += 4;
+		}
+	}
+	rk[4] = GETU32(userKey + 16);
+	rk[5] = GETU32(userKey + 20);
+	if (bits == 192) {
+		while (1) {
+			temp = rk[5];
+			rk[6] = rk[0] ^
+			    (Te4[(temp >> 16) & 0xff] << 24) ^
+			    (Te4[(temp >> 8) & 0xff] << 16) ^
+			    (Te4[(temp) & 0xff] << 8) ^
+			    (Te4[(temp >> 24)]) ^
+			    rcon[i];
+			rk[7] = rk[1] ^ rk[6];
+			rk[8] = rk[2] ^ rk[7];
+			rk[9] = rk[3] ^ rk[8];
+			if (++i == 8) {
+				return 0;
+			}
+			rk[10] = rk[4] ^ rk[9];
+			rk[11] = rk[5] ^ rk[10];
+			rk += 6;
+		}
+	}
+	rk[6] = GETU32(userKey + 24);
+	rk[7] = GETU32(userKey + 28);
+	if (bits == 256) {
+		while (1) {
+			temp = rk[7];
+			rk[8] = rk[0] ^
+			    (Te4[(temp >> 16) & 0xff] << 24) ^
+			    (Te4[(temp >> 8) & 0xff] << 16) ^
+			    (Te4[(temp) & 0xff] << 8) ^
+			    (Te4[(temp >> 24)]) ^
+			    rcon[i];
+			rk[9] = rk[1] ^ rk[8];
+			rk[10] = rk[2] ^ rk[9];
+			rk[11] = rk[3] ^ rk[10];
+			if (++i == 7) {
+				return 0;
+			}
+			temp = rk[11];
+			rk[12] = rk[4] ^
+			    (Te4[(temp >> 24)] << 24) ^
+			    (Te4[(temp >> 16) & 0xff] << 16) ^
+			    (Te4[(temp >> 8) & 0xff] << 8) ^
+			    (Te4[(temp) & 0xff]);
+			rk[13] = rk[5] ^ rk[12];
+			rk[14] = rk[6] ^ rk[13];
+			rk[15] = rk[7] ^ rk[14];
+
+			rk += 8;
+		}
+	}
+	return 0;
+}
+
+/**
+ * Expand the cipher key into the decryption key schedule.
+ */
+int
+AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+    AES_KEY *key)
+{
+	u32 *rk;
+	int i, j, status;
+	u32 temp;
+
+	/* first, start with an encryption schedule */
+	status = AES_set_encrypt_key(userKey, bits, key);
+	if (status < 0)
+		return status;
+
+	rk = key->rd_key;
+
+	/* invert the order of the round keys: */
+	for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
+		temp = rk[i];
+		rk[i] = rk[j];
+		rk[j] = temp;
+		temp = rk[i + 1];
+		rk[i + 1] = rk[j + 1];
+		rk[j + 1] = temp;
+		temp = rk[i + 2];
+		rk[i + 2] = rk[j + 2];
+		rk[j + 2] = temp;
+		temp = rk[i + 3];
+		rk[i + 3] = rk[j + 3];
+		rk[j + 3] = temp;
+	}
+	/* apply the inverse MixColumn transform to all round keys but the first and the last: */
+	for (i = 1; i < (key->rounds); i++) {
+		rk += 4;
+		for (j = 0; j < 4; j++) {
+			u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
+
+			tp1 = rk[j];
+			m = tp1 & 0x80808080;
+			tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
+			    ((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp2 & 0x80808080;
+			tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
+			    ((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp4 & 0x80808080;
+			tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
+			    ((m - (m >> 7)) & 0x1b1b1b1b);
+			tp9 = tp8 ^ tp1;
+			tpb = tp9 ^ tp2;
+			tpd = tp9 ^ tp4;
+			tpe = tp8 ^ tp4 ^ tp2;
+#if defined(ROTATE)
+			rk[j] = tpe ^ ROTATE(tpd, 16) ^
+			    ROTATE(tp9, 24) ^ ROTATE(tpb, 8);
+#else
+			rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^
+			    (tp9 >> 8) ^ (tp9 << 24) ^
+			    (tpb >> 24) ^ (tpb << 8);
+#endif
+		}
+	}
+	return 0;
+}
+
+#endif /* AES_ASM */
diff --git a/crypto/libressl/crypto/aes/aes_ctr.c b/crypto/libressl/crypto/aes/aes_ctr.c
new file mode 100644
index 0000000000..8f32df979c
--- /dev/null
+++ b/crypto/libressl/crypto/aes/aes_ctr.c
@@ -0,0 +1,62 @@
+/* $OpenBSD$ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include 
+#include 
+
+void
+AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+    size_t length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE],
+    unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num)
+{
+	CRYPTO_ctr128_encrypt(in, out, length, key, ivec, ecount_buf, num,
+	    (block128_f)AES_encrypt);
+}
diff --git a/crypto/libressl/crypto/aes/aes_ecb.c b/crypto/libressl/crypto/aes/aes_ecb.c
new file mode 100644
index 0000000000..cde04b2d6e
--- /dev/null
+++ b/crypto/libressl/crypto/aes/aes_ecb.c
@@ -0,0 +1,69 @@
+/* $OpenBSD: aes_ecb.c,v 1.5 2014/06/12 15:49:27 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#ifndef AES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+
+#include 
+#include "aes_locl.h"
+
+void
+AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
+    const AES_KEY *key, const int enc)
+{
+	if (AES_ENCRYPT == enc)
+		AES_encrypt(in, out, key);
+	else
+		AES_decrypt(in, out, key);
+}
diff --git a/crypto/libressl/crypto/aes/aes_ige.c b/crypto/libressl/crypto/aes/aes_ige.c
new file mode 100644
index 0000000000..588bf9d365
--- /dev/null
+++ b/crypto/libressl/crypto/aes/aes_ige.c
@@ -0,0 +1,194 @@
+/* $OpenBSD: aes_ige.c,v 1.6 2014/07/11 08:44:47 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include 
+#include 
+
+#include "aes_locl.h"
+
+#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long))
+typedef struct {
+	unsigned long data[N_WORDS];
+} aes_block_t;
+
+/* XXX: probably some better way to do this */
+#if defined(__i386__) || defined(__x86_64__)
+#define UNALIGNED_MEMOPS_ARE_FAST 1
+#else
+#define UNALIGNED_MEMOPS_ARE_FAST 0
+#endif
+
+#if UNALIGNED_MEMOPS_ARE_FAST
+#define load_block(d, s)        (d) = *(const aes_block_t *)(s)
+#define store_block(d, s)       *(aes_block_t *)(d) = (s)
+#else
+#define load_block(d, s)        memcpy((d).data, (s), AES_BLOCK_SIZE)
+#define store_block(d, s)       memcpy((d), (s).data, AES_BLOCK_SIZE)
+#endif
+
+/* N.B. The IV for this mode is _twice_ the block size */
+
+void
+AES_ige_encrypt(const unsigned char *in, unsigned char *out, size_t length,
+    const AES_KEY *key, unsigned char *ivec, const int enc)
+{
+	size_t n;
+	size_t len;
+
+	OPENSSL_assert((length % AES_BLOCK_SIZE) == 0);
+
+	len = length / AES_BLOCK_SIZE;
+
+	if (AES_ENCRYPT == enc) {
+		if (in != out && (UNALIGNED_MEMOPS_ARE_FAST ||
+		    ((size_t)in|(size_t)out|(size_t)ivec) %
+		    sizeof(long) == 0)) {
+			aes_block_t *ivp = (aes_block_t *)ivec;
+			aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE);
+
+			while (len) {
+				aes_block_t *inp = (aes_block_t *)in;
+				aes_block_t *outp = (aes_block_t *)out;
+
+				for (n = 0; n < N_WORDS; ++n)
+					outp->data[n] = inp->data[n] ^ ivp->data[n];
+				AES_encrypt((unsigned char *)outp->data, (unsigned char *)outp->data, key);
+				for (n = 0; n < N_WORDS; ++n)
+					outp->data[n] ^= iv2p->data[n];
+				ivp = outp;
+				iv2p = inp;
+				--len;
+				in += AES_BLOCK_SIZE;
+				out += AES_BLOCK_SIZE;
+			}
+			memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
+			memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
+		} else {
+			aes_block_t tmp, tmp2;
+			aes_block_t iv;
+			aes_block_t iv2;
+
+			load_block(iv, ivec);
+			load_block(iv2, ivec + AES_BLOCK_SIZE);
+
+			while (len) {
+				load_block(tmp, in);
+				for (n = 0; n < N_WORDS; ++n)
+					tmp2.data[n] = tmp.data[n] ^ iv.data[n];
+				AES_encrypt((unsigned char *)tmp2.data,
+				    (unsigned char *)tmp2.data, key);
+				for (n = 0; n < N_WORDS; ++n)
+					tmp2.data[n] ^= iv2.data[n];
+				store_block(out, tmp2);
+				iv = tmp2;
+				iv2 = tmp;
+				--len;
+				in += AES_BLOCK_SIZE;
+				out += AES_BLOCK_SIZE;
+			}
+			memcpy(ivec, iv.data, AES_BLOCK_SIZE);
+			memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
+		}
+	} else {
+		if (in != out && (UNALIGNED_MEMOPS_ARE_FAST ||
+		    ((size_t)in|(size_t)out|(size_t)ivec) %
+		    sizeof(long) == 0)) {
+			aes_block_t *ivp = (aes_block_t *)ivec;
+			aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE);
+
+			while (len) {
+				aes_block_t tmp;
+				aes_block_t *inp = (aes_block_t *)in;
+				aes_block_t *outp = (aes_block_t *)out;
+
+				for (n = 0; n < N_WORDS; ++n)
+					tmp.data[n] = inp->data[n] ^ iv2p->data[n];
+				AES_decrypt((unsigned char *)tmp.data,
+				    (unsigned char *)outp->data, key);
+				for (n = 0; n < N_WORDS; ++n)
+					outp->data[n] ^= ivp->data[n];
+				ivp = inp;
+				iv2p = outp;
+				--len;
+				in += AES_BLOCK_SIZE;
+				out += AES_BLOCK_SIZE;
+			}
+			memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
+			memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
+		} else {
+			aes_block_t tmp, tmp2;
+			aes_block_t iv;
+			aes_block_t iv2;
+
+			load_block(iv, ivec);
+			load_block(iv2, ivec + AES_BLOCK_SIZE);
+
+			while (len) {
+				load_block(tmp, in);
+				tmp2 = tmp;
+				for (n = 0; n < N_WORDS; ++n)
+					tmp.data[n] ^= iv2.data[n];
+				AES_decrypt((unsigned char *)tmp.data,
+				    (unsigned char *)tmp.data, key);
+				for (n = 0; n < N_WORDS; ++n)
+					tmp.data[n] ^= iv.data[n];
+				store_block(out, tmp);
+				iv = tmp2;
+				iv2 = tmp;
+				--len;
+				in += AES_BLOCK_SIZE;
+				out += AES_BLOCK_SIZE;
+			}
+			memcpy(ivec, iv.data, AES_BLOCK_SIZE);
+			memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
+		}
+	}
+}
diff --git a/crypto/libressl/crypto/aes/aes_locl.h b/crypto/libressl/crypto/aes/aes_locl.h
new file mode 100644
index 0000000000..0b2152f0da
--- /dev/null
+++ b/crypto/libressl/crypto/aes/aes_locl.h
@@ -0,0 +1,79 @@
+/* $OpenBSD$ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#ifndef HEADER_AES_LOCL_H
+#define HEADER_AES_LOCL_H
+
+#include 
+
+#ifdef OPENSSL_NO_AES
+#error AES is disabled.
+#endif
+
+#include 
+#include 
+#include 
+
+#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] <<  8) ^ ((u32)(pt)[3]))
+#define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >>  8); (ct)[3] = (u8)(st); }
+
+typedef unsigned int u32;
+typedef unsigned short u16;
+typedef unsigned char u8;
+
+#define MAXKC   (256/32)
+#define MAXKB   (256/8)
+#define MAXNR   14
+
+/* This controls loop-unrolling in aes_core.c */
+#undef FULL_UNROLL
+
+#endif /* !HEADER_AES_LOCL_H */
diff --git a/crypto/libressl/crypto/aes/aes_misc.c b/crypto/libressl/crypto/aes/aes_misc.c
new file mode 100644
index 0000000000..e4c0a61a57
--- /dev/null
+++ b/crypto/libressl/crypto/aes/aes_misc.c
@@ -0,0 +1,65 @@
+/* $OpenBSD: aes_misc.c,v 1.9 2014/07/09 09:10:07 miod Exp $ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include 
+#include 
+#include 
+#include "aes_locl.h"
+
+const char *
+AES_options(void)
+{
+#ifdef FULL_UNROLL
+	return "aes(full)";
+#else   
+	return "aes(partial)";
+#endif
+}
diff --git a/crypto/libressl/crypto/aes/aes_ofb.c b/crypto/libressl/crypto/aes/aes_ofb.c
new file mode 100644
index 0000000000..74b7baf656
--- /dev/null
+++ b/crypto/libressl/crypto/aes/aes_ofb.c
@@ -0,0 +1,61 @@
+/* $OpenBSD$ */
+/* ====================================================================
+ * Copyright (c) 2002-2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include 
+#include 
+
+void
+AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, size_t length,
+    const AES_KEY *key, unsigned char *ivec, int *num)
+{
+	CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num,
+	    (block128_f)AES_encrypt);
+}
diff --git a/crypto/libressl/crypto/aes/aes_wrap.c b/crypto/libressl/crypto/aes/aes_wrap.c
new file mode 100644
index 0000000000..e156584872
--- /dev/null
+++ b/crypto/libressl/crypto/aes/aes_wrap.c
@@ -0,0 +1,133 @@
+/* $OpenBSD: aes_wrap.c,v 1.9 2014/07/11 08:44:47 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include 
+
+#include 
+#include 
+
+static const unsigned char default_iv[] = {
+	0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
+};
+
+int
+AES_wrap_key(AES_KEY *key, const unsigned char *iv, unsigned char *out,
+    const unsigned char *in, unsigned int inlen)
+{
+	unsigned char *A, B[16], *R;
+	unsigned int i, j, t;
+	if ((inlen & 0x7) || (inlen < 8))
+		return -1;
+	A = B;
+	t = 1;
+	memcpy(out + 8, in, inlen);
+	if (!iv)
+		iv = default_iv;
+
+	memcpy(A, iv, 8);
+
+	for (j = 0; j < 6; j++) {
+		R = out + 8;
+		for (i = 0; i < inlen; i += 8, t++, R += 8) {
+			memcpy(B + 8, R, 8);
+			AES_encrypt(B, B, key);
+			A[7] ^= (unsigned char)(t & 0xff);
+			if (t > 0xff) {
+				A[6] ^= (unsigned char)((t >> 8) & 0xff);
+				A[5] ^= (unsigned char)((t >> 16) & 0xff);
+				A[4] ^= (unsigned char)((t >> 24) & 0xff);
+			}
+			memcpy(R, B + 8, 8);
+		}
+	}
+	memcpy(out, A, 8);
+	return inlen + 8;
+}
+
+int
+AES_unwrap_key(AES_KEY *key, const unsigned char *iv, unsigned char *out,
+    const unsigned char *in, unsigned int inlen)
+{
+	unsigned char *A, B[16], *R;
+	unsigned int i, j, t;
+	inlen -= 8;
+	if (inlen & 0x7)
+		return -1;
+	if (inlen < 8)
+		return -1;
+	A = B;
+	t = 6 * (inlen >> 3);
+	memcpy(A, in, 8);
+	memcpy(out, in + 8, inlen);
+	for (j = 0; j < 6; j++) {
+		R = out + inlen - 8;
+		for (i = 0; i < inlen; i += 8, t--, R -= 8) {
+			A[7] ^= (unsigned char)(t & 0xff);
+			if (t > 0xff) {
+				A[6] ^= (unsigned char)((t >> 8) & 0xff);
+				A[5] ^= (unsigned char)((t >> 16) & 0xff);
+				A[4] ^= (unsigned char)((t >> 24) & 0xff);
+			}
+			memcpy(B + 8, R, 8);
+			AES_decrypt(B, B, key);
+			memcpy(R, B + 8, 8);
+		}
+	}
+	if (!iv)
+		iv = default_iv;
+	if (memcmp(A, iv, 8)) {
+		explicit_bzero(out, inlen);
+		return 0;
+	}
+	return inlen;
+}
diff --git a/crypto/libressl/crypto/aes/aesni-elf-x86_64.s b/crypto/libressl/crypto/aes/aesni-elf-x86_64.s
new file mode 100644
index 0000000000..016793a844
--- /dev/null
+++ b/crypto/libressl/crypto/aes/aesni-elf-x86_64.s
@@ -0,0 +1,2538 @@
+.text	
+.globl	aesni_encrypt
+.type	aesni_encrypt,@function
+.align	16
+aesni_encrypt:
+	movups	(%rdi),%xmm2
+	movl	240(%rdx),%eax
+	movups	(%rdx),%xmm0
+	movups	16(%rdx),%xmm1
+	leaq	32(%rdx),%rdx
+	xorps	%xmm0,%xmm2
+.Loop_enc1_1:
+	aesenc	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rdx),%xmm1
+	leaq	16(%rdx),%rdx
+	jnz	.Loop_enc1_1	
+	aesenclast	%xmm1,%xmm2
+	movups	%xmm2,(%rsi)
+	.byte	0xf3,0xc3
+.size	aesni_encrypt,.-aesni_encrypt
+
+.globl	aesni_decrypt
+.type	aesni_decrypt,@function
+.align	16
+aesni_decrypt:
+	movups	(%rdi),%xmm2
+	movl	240(%rdx),%eax
+	movups	(%rdx),%xmm0
+	movups	16(%rdx),%xmm1
+	leaq	32(%rdx),%rdx
+	xorps	%xmm0,%xmm2
+.Loop_dec1_2:
+	aesdec	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rdx),%xmm1
+	leaq	16(%rdx),%rdx
+	jnz	.Loop_dec1_2	
+	aesdeclast	%xmm1,%xmm2
+	movups	%xmm2,(%rsi)
+	.byte	0xf3,0xc3
+.size	aesni_decrypt, .-aesni_decrypt
+.type	_aesni_encrypt3,@function
+.align	16
+_aesni_encrypt3:
+	movups	(%rcx),%xmm0
+	shrl	$1,%eax
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+	xorps	%xmm0,%xmm3
+	xorps	%xmm0,%xmm4
+	movups	(%rcx),%xmm0
+
+.Lenc_loop3:
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	decl	%eax
+	aesenc	%xmm1,%xmm4
+	movups	16(%rcx),%xmm1
+	aesenc	%xmm0,%xmm2
+	aesenc	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesenc	%xmm0,%xmm4
+	movups	(%rcx),%xmm0
+	jnz	.Lenc_loop3
+
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	aesenc	%xmm1,%xmm4
+	aesenclast	%xmm0,%xmm2
+	aesenclast	%xmm0,%xmm3
+	aesenclast	%xmm0,%xmm4
+	.byte	0xf3,0xc3
+.size	_aesni_encrypt3,.-_aesni_encrypt3
+.type	_aesni_decrypt3,@function
+.align	16
+_aesni_decrypt3:
+	movups	(%rcx),%xmm0
+	shrl	$1,%eax
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+	xorps	%xmm0,%xmm3
+	xorps	%xmm0,%xmm4
+	movups	(%rcx),%xmm0
+
+.Ldec_loop3:
+	aesdec	%xmm1,%xmm2
+	aesdec	%xmm1,%xmm3
+	decl	%eax
+	aesdec	%xmm1,%xmm4
+	movups	16(%rcx),%xmm1
+	aesdec	%xmm0,%xmm2
+	aesdec	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesdec	%xmm0,%xmm4
+	movups	(%rcx),%xmm0
+	jnz	.Ldec_loop3
+
+	aesdec	%xmm1,%xmm2
+	aesdec	%xmm1,%xmm3
+	aesdec	%xmm1,%xmm4
+	aesdeclast	%xmm0,%xmm2
+	aesdeclast	%xmm0,%xmm3
+	aesdeclast	%xmm0,%xmm4
+	.byte	0xf3,0xc3
+.size	_aesni_decrypt3,.-_aesni_decrypt3
+.type	_aesni_encrypt4,@function
+.align	16
+_aesni_encrypt4:
+	movups	(%rcx),%xmm0
+	shrl	$1,%eax
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+	xorps	%xmm0,%xmm3
+	xorps	%xmm0,%xmm4
+	xorps	%xmm0,%xmm5
+	movups	(%rcx),%xmm0
+
+.Lenc_loop4:
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	decl	%eax
+	aesenc	%xmm1,%xmm4
+	aesenc	%xmm1,%xmm5
+	movups	16(%rcx),%xmm1
+	aesenc	%xmm0,%xmm2
+	aesenc	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesenc	%xmm0,%xmm4
+	aesenc	%xmm0,%xmm5
+	movups	(%rcx),%xmm0
+	jnz	.Lenc_loop4
+
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	aesenc	%xmm1,%xmm4
+	aesenc	%xmm1,%xmm5
+	aesenclast	%xmm0,%xmm2
+	aesenclast	%xmm0,%xmm3
+	aesenclast	%xmm0,%xmm4
+	aesenclast	%xmm0,%xmm5
+	.byte	0xf3,0xc3
+.size	_aesni_encrypt4,.-_aesni_encrypt4
+.type	_aesni_decrypt4,@function
+.align	16
+_aesni_decrypt4:
+	movups	(%rcx),%xmm0
+	shrl	$1,%eax
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+	xorps	%xmm0,%xmm3
+	xorps	%xmm0,%xmm4
+	xorps	%xmm0,%xmm5
+	movups	(%rcx),%xmm0
+
+.Ldec_loop4:
+	aesdec	%xmm1,%xmm2
+	aesdec	%xmm1,%xmm3
+	decl	%eax
+	aesdec	%xmm1,%xmm4
+	aesdec	%xmm1,%xmm5
+	movups	16(%rcx),%xmm1
+	aesdec	%xmm0,%xmm2
+	aesdec	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesdec	%xmm0,%xmm4
+	aesdec	%xmm0,%xmm5
+	movups	(%rcx),%xmm0
+	jnz	.Ldec_loop4
+
+	aesdec	%xmm1,%xmm2
+	aesdec	%xmm1,%xmm3
+	aesdec	%xmm1,%xmm4
+	aesdec	%xmm1,%xmm5
+	aesdeclast	%xmm0,%xmm2
+	aesdeclast	%xmm0,%xmm3
+	aesdeclast	%xmm0,%xmm4
+	aesdeclast	%xmm0,%xmm5
+	.byte	0xf3,0xc3
+.size	_aesni_decrypt4,.-_aesni_decrypt4
+.type	_aesni_encrypt6,@function
+.align	16
+_aesni_encrypt6:
+	movups	(%rcx),%xmm0
+	shrl	$1,%eax
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+	pxor	%xmm0,%xmm3
+	aesenc	%xmm1,%xmm2
+	pxor	%xmm0,%xmm4
+	aesenc	%xmm1,%xmm3
+	pxor	%xmm0,%xmm5
+	aesenc	%xmm1,%xmm4
+	pxor	%xmm0,%xmm6
+	aesenc	%xmm1,%xmm5
+	pxor	%xmm0,%xmm7
+	decl	%eax
+	aesenc	%xmm1,%xmm6
+	movups	(%rcx),%xmm0
+	aesenc	%xmm1,%xmm7
+	jmp	.Lenc_loop6_enter
+.align	16
+.Lenc_loop6:
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	decl	%eax
+	aesenc	%xmm1,%xmm4
+	aesenc	%xmm1,%xmm5
+	aesenc	%xmm1,%xmm6
+	aesenc	%xmm1,%xmm7
+.Lenc_loop6_enter:
+	movups	16(%rcx),%xmm1
+	aesenc	%xmm0,%xmm2
+	aesenc	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesenc	%xmm0,%xmm4
+	aesenc	%xmm0,%xmm5
+	aesenc	%xmm0,%xmm6
+	aesenc	%xmm0,%xmm7
+	movups	(%rcx),%xmm0
+	jnz	.Lenc_loop6
+
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	aesenc	%xmm1,%xmm4
+	aesenc	%xmm1,%xmm5
+	aesenc	%xmm1,%xmm6
+	aesenc	%xmm1,%xmm7
+	aesenclast	%xmm0,%xmm2
+	aesenclast	%xmm0,%xmm3
+	aesenclast	%xmm0,%xmm4
+	aesenclast	%xmm0,%xmm5
+	aesenclast	%xmm0,%xmm6
+	aesenclast	%xmm0,%xmm7
+	.byte	0xf3,0xc3
+.size	_aesni_encrypt6,.-_aesni_encrypt6
+.type	_aesni_decrypt6,@function
+.align	16
+_aesni_decrypt6:
+	movups	(%rcx),%xmm0
+	shrl	$1,%eax
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+	pxor	%xmm0,%xmm3
+	aesdec	%xmm1,%xmm2
+	pxor	%xmm0,%xmm4
+	aesdec	%xmm1,%xmm3
+	pxor	%xmm0,%xmm5
+	aesdec	%xmm1,%xmm4
+	pxor	%xmm0,%xmm6
+	aesdec	%xmm1,%xmm5
+	pxor	%xmm0,%xmm7
+	decl	%eax
+	aesdec	%xmm1,%xmm6
+	movups	(%rcx),%xmm0
+	aesdec	%xmm1,%xmm7
+	jmp	.Ldec_loop6_enter
+.align	16
+.Ldec_loop6:
+	aesdec	%xmm1,%xmm2
+	aesdec	%xmm1,%xmm3
+	decl	%eax
+	aesdec	%xmm1,%xmm4
+	aesdec	%xmm1,%xmm5
+	aesdec	%xmm1,%xmm6
+	aesdec	%xmm1,%xmm7
+.Ldec_loop6_enter:
+	movups	16(%rcx),%xmm1
+	aesdec	%xmm0,%xmm2
+	aesdec	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesdec	%xmm0,%xmm4
+	aesdec	%xmm0,%xmm5
+	aesdec	%xmm0,%xmm6
+	aesdec	%xmm0,%xmm7
+	movups	(%rcx),%xmm0
+	jnz	.Ldec_loop6
+
+	aesdec	%xmm1,%xmm2
+	aesdec	%xmm1,%xmm3
+	aesdec	%xmm1,%xmm4
+	aesdec	%xmm1,%xmm5
+	aesdec	%xmm1,%xmm6
+	aesdec	%xmm1,%xmm7
+	aesdeclast	%xmm0,%xmm2
+	aesdeclast	%xmm0,%xmm3
+	aesdeclast	%xmm0,%xmm4
+	aesdeclast	%xmm0,%xmm5
+	aesdeclast	%xmm0,%xmm6
+	aesdeclast	%xmm0,%xmm7
+	.byte	0xf3,0xc3
+.size	_aesni_decrypt6,.-_aesni_decrypt6
+.type	_aesni_encrypt8,@function
+.align	16
+_aesni_encrypt8:
+	movups	(%rcx),%xmm0
+	shrl	$1,%eax
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+	xorps	%xmm0,%xmm3
+	aesenc	%xmm1,%xmm2
+	pxor	%xmm0,%xmm4
+	aesenc	%xmm1,%xmm3
+	pxor	%xmm0,%xmm5
+	aesenc	%xmm1,%xmm4
+	pxor	%xmm0,%xmm6
+	aesenc	%xmm1,%xmm5
+	pxor	%xmm0,%xmm7
+	decl	%eax
+	aesenc	%xmm1,%xmm6
+	pxor	%xmm0,%xmm8
+	aesenc	%xmm1,%xmm7
+	pxor	%xmm0,%xmm9
+	movups	(%rcx),%xmm0
+	aesenc	%xmm1,%xmm8
+	aesenc	%xmm1,%xmm9
+	movups	16(%rcx),%xmm1
+	jmp	.Lenc_loop8_enter
+.align	16
+.Lenc_loop8:
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	decl	%eax
+	aesenc	%xmm1,%xmm4
+	aesenc	%xmm1,%xmm5
+	aesenc	%xmm1,%xmm6
+	aesenc	%xmm1,%xmm7
+	aesenc	%xmm1,%xmm8
+	aesenc	%xmm1,%xmm9
+	movups	16(%rcx),%xmm1
+.Lenc_loop8_enter:
+	aesenc	%xmm0,%xmm2
+	aesenc	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesenc	%xmm0,%xmm4
+	aesenc	%xmm0,%xmm5
+	aesenc	%xmm0,%xmm6
+	aesenc	%xmm0,%xmm7
+	aesenc	%xmm0,%xmm8
+	aesenc	%xmm0,%xmm9
+	movups	(%rcx),%xmm0
+	jnz	.Lenc_loop8
+
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	aesenc	%xmm1,%xmm4
+	aesenc	%xmm1,%xmm5
+	aesenc	%xmm1,%xmm6
+	aesenc	%xmm1,%xmm7
+	aesenc	%xmm1,%xmm8
+	aesenc	%xmm1,%xmm9
+	aesenclast	%xmm0,%xmm2
+	aesenclast	%xmm0,%xmm3
+	aesenclast	%xmm0,%xmm4
+	aesenclast	%xmm0,%xmm5
+	aesenclast	%xmm0,%xmm6
+	aesenclast	%xmm0,%xmm7
+	aesenclast	%xmm0,%xmm8
+	aesenclast	%xmm0,%xmm9
+	.byte	0xf3,0xc3
+.size	_aesni_encrypt8,.-_aesni_encrypt8
+.type	_aesni_decrypt8,@function
+.align	16
+_aesni_decrypt8:
+	movups	(%rcx),%xmm0
+	shrl	$1,%eax
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+	xorps	%xmm0,%xmm3
+	aesdec	%xmm1,%xmm2
+	pxor	%xmm0,%xmm4
+	aesdec	%xmm1,%xmm3
+	pxor	%xmm0,%xmm5
+	aesdec	%xmm1,%xmm4
+	pxor	%xmm0,%xmm6
+	aesdec	%xmm1,%xmm5
+	pxor	%xmm0,%xmm7
+	decl	%eax
+	aesdec	%xmm1,%xmm6
+	pxor	%xmm0,%xmm8
+	aesdec	%xmm1,%xmm7
+	pxor	%xmm0,%xmm9
+	movups	(%rcx),%xmm0
+	aesdec	%xmm1,%xmm8
+	aesdec	%xmm1,%xmm9
+	movups	16(%rcx),%xmm1
+	jmp	.Ldec_loop8_enter
+.align	16
+.Ldec_loop8:
+	aesdec	%xmm1,%xmm2
+	aesdec	%xmm1,%xmm3
+	decl	%eax
+	aesdec	%xmm1,%xmm4
+	aesdec	%xmm1,%xmm5
+	aesdec	%xmm1,%xmm6
+	aesdec	%xmm1,%xmm7
+	aesdec	%xmm1,%xmm8
+	aesdec	%xmm1,%xmm9
+	movups	16(%rcx),%xmm1
+.Ldec_loop8_enter:
+	aesdec	%xmm0,%xmm2
+	aesdec	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesdec	%xmm0,%xmm4
+	aesdec	%xmm0,%xmm5
+	aesdec	%xmm0,%xmm6
+	aesdec	%xmm0,%xmm7
+	aesdec	%xmm0,%xmm8
+	aesdec	%xmm0,%xmm9
+	movups	(%rcx),%xmm0
+	jnz	.Ldec_loop8
+
+	aesdec	%xmm1,%xmm2
+	aesdec	%xmm1,%xmm3
+	aesdec	%xmm1,%xmm4
+	aesdec	%xmm1,%xmm5
+	aesdec	%xmm1,%xmm6
+	aesdec	%xmm1,%xmm7
+	aesdec	%xmm1,%xmm8
+	aesdec	%xmm1,%xmm9
+	aesdeclast	%xmm0,%xmm2
+	aesdeclast	%xmm0,%xmm3
+	aesdeclast	%xmm0,%xmm4
+	aesdeclast	%xmm0,%xmm5
+	aesdeclast	%xmm0,%xmm6
+	aesdeclast	%xmm0,%xmm7
+	aesdeclast	%xmm0,%xmm8
+	aesdeclast	%xmm0,%xmm9
+	.byte	0xf3,0xc3
+.size	_aesni_decrypt8,.-_aesni_decrypt8
+.globl	aesni_ecb_encrypt
+.type	aesni_ecb_encrypt,@function
+.align	16
+aesni_ecb_encrypt:
+	andq	$-16,%rdx
+	jz	.Lecb_ret
+
+	movl	240(%rcx),%eax
+	movups	(%rcx),%xmm0
+	movq	%rcx,%r11
+	movl	%eax,%r10d
+	testl	%r8d,%r8d
+	jz	.Lecb_decrypt
+
+	cmpq	$128,%rdx
+	jb	.Lecb_enc_tail
+
+	movdqu	(%rdi),%xmm2
+	movdqu	16(%rdi),%xmm3
+	movdqu	32(%rdi),%xmm4
+	movdqu	48(%rdi),%xmm5
+	movdqu	64(%rdi),%xmm6
+	movdqu	80(%rdi),%xmm7
+	movdqu	96(%rdi),%xmm8
+	movdqu	112(%rdi),%xmm9
+	leaq	128(%rdi),%rdi
+	subq	$128,%rdx
+	jmp	.Lecb_enc_loop8_enter
+.align	16
+.Lecb_enc_loop8:
+	movups	%xmm2,(%rsi)
+	movq	%r11,%rcx
+	movdqu	(%rdi),%xmm2
+	movl	%r10d,%eax
+	movups	%xmm3,16(%rsi)
+	movdqu	16(%rdi),%xmm3
+	movups	%xmm4,32(%rsi)
+	movdqu	32(%rdi),%xmm4
+	movups	%xmm5,48(%rsi)
+	movdqu	48(%rdi),%xmm5
+	movups	%xmm6,64(%rsi)
+	movdqu	64(%rdi),%xmm6
+	movups	%xmm7,80(%rsi)
+	movdqu	80(%rdi),%xmm7
+	movups	%xmm8,96(%rsi)
+	movdqu	96(%rdi),%xmm8
+	movups	%xmm9,112(%rsi)
+	leaq	128(%rsi),%rsi
+	movdqu	112(%rdi),%xmm9
+	leaq	128(%rdi),%rdi
+.Lecb_enc_loop8_enter:
+
+	call	_aesni_encrypt8
+
+	subq	$128,%rdx
+	jnc	.Lecb_enc_loop8
+
+	movups	%xmm2,(%rsi)
+	movq	%r11,%rcx
+	movups	%xmm3,16(%rsi)
+	movl	%r10d,%eax
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movups	%xmm6,64(%rsi)
+	movups	%xmm7,80(%rsi)
+	movups	%xmm8,96(%rsi)
+	movups	%xmm9,112(%rsi)
+	leaq	128(%rsi),%rsi
+	addq	$128,%rdx
+	jz	.Lecb_ret
+
+.Lecb_enc_tail:
+	movups	(%rdi),%xmm2
+	cmpq	$32,%rdx
+	jb	.Lecb_enc_one
+	movups	16(%rdi),%xmm3
+	je	.Lecb_enc_two
+	movups	32(%rdi),%xmm4
+	cmpq	$64,%rdx
+	jb	.Lecb_enc_three
+	movups	48(%rdi),%xmm5
+	je	.Lecb_enc_four
+	movups	64(%rdi),%xmm6
+	cmpq	$96,%rdx
+	jb	.Lecb_enc_five
+	movups	80(%rdi),%xmm7
+	je	.Lecb_enc_six
+	movdqu	96(%rdi),%xmm8
+	call	_aesni_encrypt8
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movups	%xmm6,64(%rsi)
+	movups	%xmm7,80(%rsi)
+	movups	%xmm8,96(%rsi)
+	jmp	.Lecb_ret
+.align	16
+.Lecb_enc_one:
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+.Loop_enc1_3:
+	aesenc	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	.Loop_enc1_3	
+	aesenclast	%xmm1,%xmm2
+	movups	%xmm2,(%rsi)
+	jmp	.Lecb_ret
+.align	16
+.Lecb_enc_two:
+	xorps	%xmm4,%xmm4
+	call	_aesni_encrypt3
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	jmp	.Lecb_ret
+.align	16
+.Lecb_enc_three:
+	call	_aesni_encrypt3
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	jmp	.Lecb_ret
+.align	16
+.Lecb_enc_four:
+	call	_aesni_encrypt4
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	jmp	.Lecb_ret
+.align	16
+.Lecb_enc_five:
+	xorps	%xmm7,%xmm7
+	call	_aesni_encrypt6
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movups	%xmm6,64(%rsi)
+	jmp	.Lecb_ret
+.align	16
+.Lecb_enc_six:
+	call	_aesni_encrypt6
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movups	%xmm6,64(%rsi)
+	movups	%xmm7,80(%rsi)
+	jmp	.Lecb_ret
+
+.align	16
+.Lecb_decrypt:
+	cmpq	$128,%rdx
+	jb	.Lecb_dec_tail
+
+	movdqu	(%rdi),%xmm2
+	movdqu	16(%rdi),%xmm3
+	movdqu	32(%rdi),%xmm4
+	movdqu	48(%rdi),%xmm5
+	movdqu	64(%rdi),%xmm6
+	movdqu	80(%rdi),%xmm7
+	movdqu	96(%rdi),%xmm8
+	movdqu	112(%rdi),%xmm9
+	leaq	128(%rdi),%rdi
+	subq	$128,%rdx
+	jmp	.Lecb_dec_loop8_enter
+.align	16
+.Lecb_dec_loop8:
+	movups	%xmm2,(%rsi)
+	movq	%r11,%rcx
+	movdqu	(%rdi),%xmm2
+	movl	%r10d,%eax
+	movups	%xmm3,16(%rsi)
+	movdqu	16(%rdi),%xmm3
+	movups	%xmm4,32(%rsi)
+	movdqu	32(%rdi),%xmm4
+	movups	%xmm5,48(%rsi)
+	movdqu	48(%rdi),%xmm5
+	movups	%xmm6,64(%rsi)
+	movdqu	64(%rdi),%xmm6
+	movups	%xmm7,80(%rsi)
+	movdqu	80(%rdi),%xmm7
+	movups	%xmm8,96(%rsi)
+	movdqu	96(%rdi),%xmm8
+	movups	%xmm9,112(%rsi)
+	leaq	128(%rsi),%rsi
+	movdqu	112(%rdi),%xmm9
+	leaq	128(%rdi),%rdi
+.Lecb_dec_loop8_enter:
+
+	call	_aesni_decrypt8
+
+	movups	(%r11),%xmm0
+	subq	$128,%rdx
+	jnc	.Lecb_dec_loop8
+
+	movups	%xmm2,(%rsi)
+	movq	%r11,%rcx
+	movups	%xmm3,16(%rsi)
+	movl	%r10d,%eax
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movups	%xmm6,64(%rsi)
+	movups	%xmm7,80(%rsi)
+	movups	%xmm8,96(%rsi)
+	movups	%xmm9,112(%rsi)
+	leaq	128(%rsi),%rsi
+	addq	$128,%rdx
+	jz	.Lecb_ret
+
+.Lecb_dec_tail:
+	movups	(%rdi),%xmm2
+	cmpq	$32,%rdx
+	jb	.Lecb_dec_one
+	movups	16(%rdi),%xmm3
+	je	.Lecb_dec_two
+	movups	32(%rdi),%xmm4
+	cmpq	$64,%rdx
+	jb	.Lecb_dec_three
+	movups	48(%rdi),%xmm5
+	je	.Lecb_dec_four
+	movups	64(%rdi),%xmm6
+	cmpq	$96,%rdx
+	jb	.Lecb_dec_five
+	movups	80(%rdi),%xmm7
+	je	.Lecb_dec_six
+	movups	96(%rdi),%xmm8
+	movups	(%rcx),%xmm0
+	call	_aesni_decrypt8
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movups	%xmm6,64(%rsi)
+	movups	%xmm7,80(%rsi)
+	movups	%xmm8,96(%rsi)
+	jmp	.Lecb_ret
+.align	16
+.Lecb_dec_one:
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+.Loop_dec1_4:
+	aesdec	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	.Loop_dec1_4	
+	aesdeclast	%xmm1,%xmm2
+	movups	%xmm2,(%rsi)
+	jmp	.Lecb_ret
+.align	16
+.Lecb_dec_two:
+	xorps	%xmm4,%xmm4
+	call	_aesni_decrypt3
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	jmp	.Lecb_ret
+.align	16
+.Lecb_dec_three:
+	call	_aesni_decrypt3
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	jmp	.Lecb_ret
+.align	16
+.Lecb_dec_four:
+	call	_aesni_decrypt4
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	jmp	.Lecb_ret
+.align	16
+.Lecb_dec_five:
+	xorps	%xmm7,%xmm7
+	call	_aesni_decrypt6
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movups	%xmm6,64(%rsi)
+	jmp	.Lecb_ret
+.align	16
+.Lecb_dec_six:
+	call	_aesni_decrypt6
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movups	%xmm6,64(%rsi)
+	movups	%xmm7,80(%rsi)
+
+.Lecb_ret:
+	.byte	0xf3,0xc3
+.size	aesni_ecb_encrypt,.-aesni_ecb_encrypt
+.globl	aesni_ccm64_encrypt_blocks
+.type	aesni_ccm64_encrypt_blocks,@function
+.align	16
+aesni_ccm64_encrypt_blocks:
+	movl	240(%rcx),%eax
+	movdqu	(%r8),%xmm9
+	movdqa	.Lincrement64(%rip),%xmm6
+	movdqa	.Lbswap_mask(%rip),%xmm7
+
+	shrl	$1,%eax
+	leaq	0(%rcx),%r11
+	movdqu	(%r9),%xmm3
+	movdqa	%xmm9,%xmm2
+	movl	%eax,%r10d
+.byte	102,68,15,56,0,207
+	jmp	.Lccm64_enc_outer
+.align	16
+.Lccm64_enc_outer:
+	movups	(%r11),%xmm0
+	movl	%r10d,%eax
+	movups	(%rdi),%xmm8
+
+	xorps	%xmm0,%xmm2
+	movups	16(%r11),%xmm1
+	xorps	%xmm8,%xmm0
+	leaq	32(%r11),%rcx
+	xorps	%xmm0,%xmm3
+	movups	(%rcx),%xmm0
+
+.Lccm64_enc2_loop:
+	aesenc	%xmm1,%xmm2
+	decl	%eax
+	aesenc	%xmm1,%xmm3
+	movups	16(%rcx),%xmm1
+	aesenc	%xmm0,%xmm2
+	leaq	32(%rcx),%rcx
+	aesenc	%xmm0,%xmm3
+	movups	0(%rcx),%xmm0
+	jnz	.Lccm64_enc2_loop
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	paddq	%xmm6,%xmm9
+	aesenclast	%xmm0,%xmm2
+	aesenclast	%xmm0,%xmm3
+
+	decq	%rdx
+	leaq	16(%rdi),%rdi
+	xorps	%xmm2,%xmm8
+	movdqa	%xmm9,%xmm2
+	movups	%xmm8,(%rsi)
+	leaq	16(%rsi),%rsi
+.byte	102,15,56,0,215
+	jnz	.Lccm64_enc_outer
+
+	movups	%xmm3,(%r9)
+	.byte	0xf3,0xc3
+.size	aesni_ccm64_encrypt_blocks,.-aesni_ccm64_encrypt_blocks
+.globl	aesni_ccm64_decrypt_blocks
+.type	aesni_ccm64_decrypt_blocks,@function
+.align	16
+aesni_ccm64_decrypt_blocks:
+	movl	240(%rcx),%eax
+	movups	(%r8),%xmm9
+	movdqu	(%r9),%xmm3
+	movdqa	.Lincrement64(%rip),%xmm6
+	movdqa	.Lbswap_mask(%rip),%xmm7
+
+	movaps	%xmm9,%xmm2
+	movl	%eax,%r10d
+	movq	%rcx,%r11
+.byte	102,68,15,56,0,207
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+.Loop_enc1_5:
+	aesenc	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	.Loop_enc1_5	
+	aesenclast	%xmm1,%xmm2
+	movups	(%rdi),%xmm8
+	paddq	%xmm6,%xmm9
+	leaq	16(%rdi),%rdi
+	jmp	.Lccm64_dec_outer
+.align	16
+.Lccm64_dec_outer:
+	xorps	%xmm2,%xmm8
+	movdqa	%xmm9,%xmm2
+	movl	%r10d,%eax
+	movups	%xmm8,(%rsi)
+	leaq	16(%rsi),%rsi
+.byte	102,15,56,0,215
+
+	subq	$1,%rdx
+	jz	.Lccm64_dec_break
+
+	movups	(%r11),%xmm0
+	shrl	$1,%eax
+	movups	16(%r11),%xmm1
+	xorps	%xmm0,%xmm8
+	leaq	32(%r11),%rcx
+	xorps	%xmm0,%xmm2
+	xorps	%xmm8,%xmm3
+	movups	(%rcx),%xmm0
+
+.Lccm64_dec2_loop:
+	aesenc	%xmm1,%xmm2
+	decl	%eax
+	aesenc	%xmm1,%xmm3
+	movups	16(%rcx),%xmm1
+	aesenc	%xmm0,%xmm2
+	leaq	32(%rcx),%rcx
+	aesenc	%xmm0,%xmm3
+	movups	0(%rcx),%xmm0
+	jnz	.Lccm64_dec2_loop
+	movups	(%rdi),%xmm8
+	paddq	%xmm6,%xmm9
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	leaq	16(%rdi),%rdi
+	aesenclast	%xmm0,%xmm2
+	aesenclast	%xmm0,%xmm3
+	jmp	.Lccm64_dec_outer
+
+.align	16
+.Lccm64_dec_break:
+
+	movups	(%r11),%xmm0
+	movups	16(%r11),%xmm1
+	xorps	%xmm0,%xmm8
+	leaq	32(%r11),%r11
+	xorps	%xmm8,%xmm3
+.Loop_enc1_6:
+	aesenc	%xmm1,%xmm3
+	decl	%eax
+	movups	(%r11),%xmm1
+	leaq	16(%r11),%r11
+	jnz	.Loop_enc1_6	
+	aesenclast	%xmm1,%xmm3
+	movups	%xmm3,(%r9)
+	.byte	0xf3,0xc3
+.size	aesni_ccm64_decrypt_blocks,.-aesni_ccm64_decrypt_blocks
+.globl	aesni_ctr32_encrypt_blocks
+.type	aesni_ctr32_encrypt_blocks,@function
+.align	16
+aesni_ctr32_encrypt_blocks:
+	cmpq	$1,%rdx
+	je	.Lctr32_one_shortcut
+
+	movdqu	(%r8),%xmm14
+	movdqa	.Lbswap_mask(%rip),%xmm15
+	xorl	%eax,%eax
+.byte	102,69,15,58,22,242,3
+.byte	102,68,15,58,34,240,3
+
+	movl	240(%rcx),%eax
+	bswapl	%r10d
+	pxor	%xmm12,%xmm12
+	pxor	%xmm13,%xmm13
+.byte	102,69,15,58,34,226,0
+	leaq	3(%r10),%r11
+.byte	102,69,15,58,34,235,0
+	incl	%r10d
+.byte	102,69,15,58,34,226,1
+	incq	%r11
+.byte	102,69,15,58,34,235,1
+	incl	%r10d
+.byte	102,69,15,58,34,226,2
+	incq	%r11
+.byte	102,69,15,58,34,235,2
+	movdqa	%xmm12,-40(%rsp)
+.byte	102,69,15,56,0,231
+	movdqa	%xmm13,-24(%rsp)
+.byte	102,69,15,56,0,239
+
+	pshufd	$192,%xmm12,%xmm2
+	pshufd	$128,%xmm12,%xmm3
+	pshufd	$64,%xmm12,%xmm4
+	cmpq	$6,%rdx
+	jb	.Lctr32_tail
+	shrl	$1,%eax
+	movq	%rcx,%r11
+	movl	%eax,%r10d
+	subq	$6,%rdx
+	jmp	.Lctr32_loop6
+
+.align	16
+.Lctr32_loop6:
+	pshufd	$192,%xmm13,%xmm5
+	por	%xmm14,%xmm2
+	movups	(%r11),%xmm0
+	pshufd	$128,%xmm13,%xmm6
+	por	%xmm14,%xmm3
+	movups	16(%r11),%xmm1
+	pshufd	$64,%xmm13,%xmm7
+	por	%xmm14,%xmm4
+	por	%xmm14,%xmm5
+	xorps	%xmm0,%xmm2
+	por	%xmm14,%xmm6
+	por	%xmm14,%xmm7
+
+
+
+
+	pxor	%xmm0,%xmm3
+	aesenc	%xmm1,%xmm2
+	leaq	32(%r11),%rcx
+	pxor	%xmm0,%xmm4
+	aesenc	%xmm1,%xmm3
+	movdqa	.Lincrement32(%rip),%xmm13
+	pxor	%xmm0,%xmm5
+	aesenc	%xmm1,%xmm4
+	movdqa	-40(%rsp),%xmm12
+	pxor	%xmm0,%xmm6
+	aesenc	%xmm1,%xmm5
+	pxor	%xmm0,%xmm7
+	movups	(%rcx),%xmm0
+	decl	%eax
+	aesenc	%xmm1,%xmm6
+	aesenc	%xmm1,%xmm7
+	jmp	.Lctr32_enc_loop6_enter
+.align	16
+.Lctr32_enc_loop6:
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	decl	%eax
+	aesenc	%xmm1,%xmm4
+	aesenc	%xmm1,%xmm5
+	aesenc	%xmm1,%xmm6
+	aesenc	%xmm1,%xmm7
+.Lctr32_enc_loop6_enter:
+	movups	16(%rcx),%xmm1
+	aesenc	%xmm0,%xmm2
+	aesenc	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesenc	%xmm0,%xmm4
+	aesenc	%xmm0,%xmm5
+	aesenc	%xmm0,%xmm6
+	aesenc	%xmm0,%xmm7
+	movups	(%rcx),%xmm0
+	jnz	.Lctr32_enc_loop6
+
+	aesenc	%xmm1,%xmm2
+	paddd	%xmm13,%xmm12
+	aesenc	%xmm1,%xmm3
+	paddd	-24(%rsp),%xmm13
+	aesenc	%xmm1,%xmm4
+	movdqa	%xmm12,-40(%rsp)
+	aesenc	%xmm1,%xmm5
+	movdqa	%xmm13,-24(%rsp)
+	aesenc	%xmm1,%xmm6
+.byte	102,69,15,56,0,231
+	aesenc	%xmm1,%xmm7
+.byte	102,69,15,56,0,239
+
+	aesenclast	%xmm0,%xmm2
+	movups	(%rdi),%xmm8
+	aesenclast	%xmm0,%xmm3
+	movups	16(%rdi),%xmm9
+	aesenclast	%xmm0,%xmm4
+	movups	32(%rdi),%xmm10
+	aesenclast	%xmm0,%xmm5
+	movups	48(%rdi),%xmm11
+	aesenclast	%xmm0,%xmm6
+	movups	64(%rdi),%xmm1
+	aesenclast	%xmm0,%xmm7
+	movups	80(%rdi),%xmm0
+	leaq	96(%rdi),%rdi
+
+	xorps	%xmm2,%xmm8
+	pshufd	$192,%xmm12,%xmm2
+	xorps	%xmm3,%xmm9
+	pshufd	$128,%xmm12,%xmm3
+	movups	%xmm8,(%rsi)
+	xorps	%xmm4,%xmm10
+	pshufd	$64,%xmm12,%xmm4
+	movups	%xmm9,16(%rsi)
+	xorps	%xmm5,%xmm11
+	movups	%xmm10,32(%rsi)
+	xorps	%xmm6,%xmm1
+	movups	%xmm11,48(%rsi)
+	xorps	%xmm7,%xmm0
+	movups	%xmm1,64(%rsi)
+	movups	%xmm0,80(%rsi)
+	leaq	96(%rsi),%rsi
+	movl	%r10d,%eax
+	subq	$6,%rdx
+	jnc	.Lctr32_loop6
+
+	addq	$6,%rdx
+	jz	.Lctr32_done
+	movq	%r11,%rcx
+	leal	1(%rax,%rax,1),%eax
+
+.Lctr32_tail:
+	por	%xmm14,%xmm2
+	movups	(%rdi),%xmm8
+	cmpq	$2,%rdx
+	jb	.Lctr32_one
+
+	por	%xmm14,%xmm3
+	movups	16(%rdi),%xmm9
+	je	.Lctr32_two
+
+	pshufd	$192,%xmm13,%xmm5
+	por	%xmm14,%xmm4
+	movups	32(%rdi),%xmm10
+	cmpq	$4,%rdx
+	jb	.Lctr32_three
+
+	pshufd	$128,%xmm13,%xmm6
+	por	%xmm14,%xmm5
+	movups	48(%rdi),%xmm11
+	je	.Lctr32_four
+
+	por	%xmm14,%xmm6
+	xorps	%xmm7,%xmm7
+
+	call	_aesni_encrypt6
+
+	movups	64(%rdi),%xmm1
+	xorps	%xmm2,%xmm8
+	xorps	%xmm3,%xmm9
+	movups	%xmm8,(%rsi)
+	xorps	%xmm4,%xmm10
+	movups	%xmm9,16(%rsi)
+	xorps	%xmm5,%xmm11
+	movups	%xmm10,32(%rsi)
+	xorps	%xmm6,%xmm1
+	movups	%xmm11,48(%rsi)
+	movups	%xmm1,64(%rsi)
+	jmp	.Lctr32_done
+
+.align	16
+.Lctr32_one_shortcut:
+	movups	(%r8),%xmm2
+	movups	(%rdi),%xmm8
+	movl	240(%rcx),%eax
+.Lctr32_one:
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+.Loop_enc1_7:
+	aesenc	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	.Loop_enc1_7	
+	aesenclast	%xmm1,%xmm2
+	xorps	%xmm2,%xmm8
+	movups	%xmm8,(%rsi)
+	jmp	.Lctr32_done
+
+.align	16
+.Lctr32_two:
+	xorps	%xmm4,%xmm4
+	call	_aesni_encrypt3
+	xorps	%xmm2,%xmm8
+	xorps	%xmm3,%xmm9
+	movups	%xmm8,(%rsi)
+	movups	%xmm9,16(%rsi)
+	jmp	.Lctr32_done
+
+.align	16
+.Lctr32_three:
+	call	_aesni_encrypt3
+	xorps	%xmm2,%xmm8
+	xorps	%xmm3,%xmm9
+	movups	%xmm8,(%rsi)
+	xorps	%xmm4,%xmm10
+	movups	%xmm9,16(%rsi)
+	movups	%xmm10,32(%rsi)
+	jmp	.Lctr32_done
+
+.align	16
+.Lctr32_four:
+	call	_aesni_encrypt4
+	xorps	%xmm2,%xmm8
+	xorps	%xmm3,%xmm9
+	movups	%xmm8,(%rsi)
+	xorps	%xmm4,%xmm10
+	movups	%xmm9,16(%rsi)
+	xorps	%xmm5,%xmm11
+	movups	%xmm10,32(%rsi)
+	movups	%xmm11,48(%rsi)
+
+.Lctr32_done:
+	.byte	0xf3,0xc3
+.size	aesni_ctr32_encrypt_blocks,.-aesni_ctr32_encrypt_blocks
+.globl	aesni_xts_encrypt
+.type	aesni_xts_encrypt,@function
+.align	16
+aesni_xts_encrypt:
+	leaq	-104(%rsp),%rsp
+	movups	(%r9),%xmm15
+	movl	240(%r8),%eax
+	movl	240(%rcx),%r10d
+	movups	(%r8),%xmm0
+	movups	16(%r8),%xmm1
+	leaq	32(%r8),%r8
+	xorps	%xmm0,%xmm15
+.Loop_enc1_8:
+	aesenc	%xmm1,%xmm15
+	decl	%eax
+	movups	(%r8),%xmm1
+	leaq	16(%r8),%r8
+	jnz	.Loop_enc1_8	
+	aesenclast	%xmm1,%xmm15
+	movq	%rcx,%r11
+	movl	%r10d,%eax
+	movq	%rdx,%r9
+	andq	$-16,%rdx
+
+	movdqa	.Lxts_magic(%rip),%xmm8
+	pxor	%xmm14,%xmm14
+	pcmpgtd	%xmm15,%xmm14
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm10
+	paddq	%xmm15,%xmm15
+	pand	%xmm8,%xmm9
+	pcmpgtd	%xmm15,%xmm14
+	pxor	%xmm9,%xmm15
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm11
+	paddq	%xmm15,%xmm15
+	pand	%xmm8,%xmm9
+	pcmpgtd	%xmm15,%xmm14
+	pxor	%xmm9,%xmm15
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm12
+	paddq	%xmm15,%xmm15
+	pand	%xmm8,%xmm9
+	pcmpgtd	%xmm15,%xmm14
+	pxor	%xmm9,%xmm15
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm13
+	paddq	%xmm15,%xmm15
+	pand	%xmm8,%xmm9
+	pcmpgtd	%xmm15,%xmm14
+	pxor	%xmm9,%xmm15
+	subq	$96,%rdx
+	jc	.Lxts_enc_short
+
+	shrl	$1,%eax
+	subl	$1,%eax
+	movl	%eax,%r10d
+	jmp	.Lxts_enc_grandloop
+
+.align	16
+.Lxts_enc_grandloop:
+	pshufd	$19,%xmm14,%xmm9
+	movdqa	%xmm15,%xmm14
+	paddq	%xmm15,%xmm15
+	movdqu	0(%rdi),%xmm2
+	pand	%xmm8,%xmm9
+	movdqu	16(%rdi),%xmm3
+	pxor	%xmm9,%xmm15
+
+	movdqu	32(%rdi),%xmm4
+	pxor	%xmm10,%xmm2
+	movdqu	48(%rdi),%xmm5
+	pxor	%xmm11,%xmm3
+	movdqu	64(%rdi),%xmm6
+	pxor	%xmm12,%xmm4
+	movdqu	80(%rdi),%xmm7
+	leaq	96(%rdi),%rdi
+	pxor	%xmm13,%xmm5
+	movups	(%r11),%xmm0
+	pxor	%xmm14,%xmm6
+	pxor	%xmm15,%xmm7
+
+
+
+	movups	16(%r11),%xmm1
+	pxor	%xmm0,%xmm2
+	pxor	%xmm0,%xmm3
+	movdqa	%xmm10,0(%rsp)
+	aesenc	%xmm1,%xmm2
+	leaq	32(%r11),%rcx
+	pxor	%xmm0,%xmm4
+	movdqa	%xmm11,16(%rsp)
+	aesenc	%xmm1,%xmm3
+	pxor	%xmm0,%xmm5
+	movdqa	%xmm12,32(%rsp)
+	aesenc	%xmm1,%xmm4
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm13,48(%rsp)
+	aesenc	%xmm1,%xmm5
+	pxor	%xmm0,%xmm7
+	movups	(%rcx),%xmm0
+	decl	%eax
+	movdqa	%xmm14,64(%rsp)
+	aesenc	%xmm1,%xmm6
+	movdqa	%xmm15,80(%rsp)
+	aesenc	%xmm1,%xmm7
+	pxor	%xmm14,%xmm14
+	pcmpgtd	%xmm15,%xmm14
+	jmp	.Lxts_enc_loop6_enter
+
+.align	16
+.Lxts_enc_loop6:
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	decl	%eax
+	aesenc	%xmm1,%xmm4
+	aesenc	%xmm1,%xmm5
+	aesenc	%xmm1,%xmm6
+	aesenc	%xmm1,%xmm7
+.Lxts_enc_loop6_enter:
+	movups	16(%rcx),%xmm1
+	aesenc	%xmm0,%xmm2
+	aesenc	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesenc	%xmm0,%xmm4
+	aesenc	%xmm0,%xmm5
+	aesenc	%xmm0,%xmm6
+	aesenc	%xmm0,%xmm7
+	movups	(%rcx),%xmm0
+	jnz	.Lxts_enc_loop6
+
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	paddq	%xmm15,%xmm15
+	aesenc	%xmm1,%xmm2
+	pand	%xmm8,%xmm9
+	aesenc	%xmm1,%xmm3
+	pcmpgtd	%xmm15,%xmm14
+	aesenc	%xmm1,%xmm4
+	pxor	%xmm9,%xmm15
+	aesenc	%xmm1,%xmm5
+	aesenc	%xmm1,%xmm6
+	aesenc	%xmm1,%xmm7
+	movups	16(%rcx),%xmm1
+
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm10
+	paddq	%xmm15,%xmm15
+	aesenc	%xmm0,%xmm2
+	pand	%xmm8,%xmm9
+	aesenc	%xmm0,%xmm3
+	pcmpgtd	%xmm15,%xmm14
+	aesenc	%xmm0,%xmm4
+	pxor	%xmm9,%xmm15
+	aesenc	%xmm0,%xmm5
+	aesenc	%xmm0,%xmm6
+	aesenc	%xmm0,%xmm7
+	movups	32(%rcx),%xmm0
+
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm11
+	paddq	%xmm15,%xmm15
+	aesenc	%xmm1,%xmm2
+	pand	%xmm8,%xmm9
+	aesenc	%xmm1,%xmm3
+	pcmpgtd	%xmm15,%xmm14
+	aesenc	%xmm1,%xmm4
+	pxor	%xmm9,%xmm15
+	aesenc	%xmm1,%xmm5
+	aesenc	%xmm1,%xmm6
+	aesenc	%xmm1,%xmm7
+
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm12
+	paddq	%xmm15,%xmm15
+	aesenclast	%xmm0,%xmm2
+	pand	%xmm8,%xmm9
+	aesenclast	%xmm0,%xmm3
+	pcmpgtd	%xmm15,%xmm14
+	aesenclast	%xmm0,%xmm4
+	pxor	%xmm9,%xmm15
+	aesenclast	%xmm0,%xmm5
+	aesenclast	%xmm0,%xmm6
+	aesenclast	%xmm0,%xmm7
+
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm13
+	paddq	%xmm15,%xmm15
+	xorps	0(%rsp),%xmm2
+	pand	%xmm8,%xmm9
+	xorps	16(%rsp),%xmm3
+	pcmpgtd	%xmm15,%xmm14
+	pxor	%xmm9,%xmm15
+
+	xorps	32(%rsp),%xmm4
+	movups	%xmm2,0(%rsi)
+	xorps	48(%rsp),%xmm5
+	movups	%xmm3,16(%rsi)
+	xorps	64(%rsp),%xmm6
+	movups	%xmm4,32(%rsi)
+	xorps	80(%rsp),%xmm7
+	movups	%xmm5,48(%rsi)
+	movl	%r10d,%eax
+	movups	%xmm6,64(%rsi)
+	movups	%xmm7,80(%rsi)
+	leaq	96(%rsi),%rsi
+	subq	$96,%rdx
+	jnc	.Lxts_enc_grandloop
+
+	leal	3(%rax,%rax,1),%eax
+	movq	%r11,%rcx
+	movl	%eax,%r10d
+
+.Lxts_enc_short:
+	addq	$96,%rdx
+	jz	.Lxts_enc_done
+
+	cmpq	$32,%rdx
+	jb	.Lxts_enc_one
+	je	.Lxts_enc_two
+
+	cmpq	$64,%rdx
+	jb	.Lxts_enc_three
+	je	.Lxts_enc_four
+
+	pshufd	$19,%xmm14,%xmm9
+	movdqa	%xmm15,%xmm14
+	paddq	%xmm15,%xmm15
+	movdqu	(%rdi),%xmm2
+	pand	%xmm8,%xmm9
+	movdqu	16(%rdi),%xmm3
+	pxor	%xmm9,%xmm15
+
+	movdqu	32(%rdi),%xmm4
+	pxor	%xmm10,%xmm2
+	movdqu	48(%rdi),%xmm5
+	pxor	%xmm11,%xmm3
+	movdqu	64(%rdi),%xmm6
+	leaq	80(%rdi),%rdi
+	pxor	%xmm12,%xmm4
+	pxor	%xmm13,%xmm5
+	pxor	%xmm14,%xmm6
+
+	call	_aesni_encrypt6
+
+	xorps	%xmm10,%xmm2
+	movdqa	%xmm15,%xmm10
+	xorps	%xmm11,%xmm3
+	xorps	%xmm12,%xmm4
+	movdqu	%xmm2,(%rsi)
+	xorps	%xmm13,%xmm5
+	movdqu	%xmm3,16(%rsi)
+	xorps	%xmm14,%xmm6
+	movdqu	%xmm4,32(%rsi)
+	movdqu	%xmm5,48(%rsi)
+	movdqu	%xmm6,64(%rsi)
+	leaq	80(%rsi),%rsi
+	jmp	.Lxts_enc_done
+
+.align	16
+.Lxts_enc_one:
+	movups	(%rdi),%xmm2
+	leaq	16(%rdi),%rdi
+	xorps	%xmm10,%xmm2
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+.Loop_enc1_9:
+	aesenc	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	.Loop_enc1_9	
+	aesenclast	%xmm1,%xmm2
+	xorps	%xmm10,%xmm2
+	movdqa	%xmm11,%xmm10
+	movups	%xmm2,(%rsi)
+	leaq	16(%rsi),%rsi
+	jmp	.Lxts_enc_done
+
+.align	16
+.Lxts_enc_two:
+	movups	(%rdi),%xmm2
+	movups	16(%rdi),%xmm3
+	leaq	32(%rdi),%rdi
+	xorps	%xmm10,%xmm2
+	xorps	%xmm11,%xmm3
+
+	call	_aesni_encrypt3
+
+	xorps	%xmm10,%xmm2
+	movdqa	%xmm12,%xmm10
+	xorps	%xmm11,%xmm3
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	leaq	32(%rsi),%rsi
+	jmp	.Lxts_enc_done
+
+.align	16
+.Lxts_enc_three:
+	movups	(%rdi),%xmm2
+	movups	16(%rdi),%xmm3
+	movups	32(%rdi),%xmm4
+	leaq	48(%rdi),%rdi
+	xorps	%xmm10,%xmm2
+	xorps	%xmm11,%xmm3
+	xorps	%xmm12,%xmm4
+
+	call	_aesni_encrypt3
+
+	xorps	%xmm10,%xmm2
+	movdqa	%xmm13,%xmm10
+	xorps	%xmm11,%xmm3
+	xorps	%xmm12,%xmm4
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	leaq	48(%rsi),%rsi
+	jmp	.Lxts_enc_done
+
+.align	16
+.Lxts_enc_four:
+	movups	(%rdi),%xmm2
+	movups	16(%rdi),%xmm3
+	movups	32(%rdi),%xmm4
+	xorps	%xmm10,%xmm2
+	movups	48(%rdi),%xmm5
+	leaq	64(%rdi),%rdi
+	xorps	%xmm11,%xmm3
+	xorps	%xmm12,%xmm4
+	xorps	%xmm13,%xmm5
+
+	call	_aesni_encrypt4
+
+	xorps	%xmm10,%xmm2
+	movdqa	%xmm15,%xmm10
+	xorps	%xmm11,%xmm3
+	xorps	%xmm12,%xmm4
+	movups	%xmm2,(%rsi)
+	xorps	%xmm13,%xmm5
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	leaq	64(%rsi),%rsi
+	jmp	.Lxts_enc_done
+
+.align	16
+.Lxts_enc_done:
+	andq	$15,%r9
+	jz	.Lxts_enc_ret
+	movq	%r9,%rdx
+
+.Lxts_enc_steal:
+	movzbl	(%rdi),%eax
+	movzbl	-16(%rsi),%ecx
+	leaq	1(%rdi),%rdi
+	movb	%al,-16(%rsi)
+	movb	%cl,0(%rsi)
+	leaq	1(%rsi),%rsi
+	subq	$1,%rdx
+	jnz	.Lxts_enc_steal
+
+	subq	%r9,%rsi
+	movq	%r11,%rcx
+	movl	%r10d,%eax
+
+	movups	-16(%rsi),%xmm2
+	xorps	%xmm10,%xmm2
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+.Loop_enc1_10:
+	aesenc	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	.Loop_enc1_10	
+	aesenclast	%xmm1,%xmm2
+	xorps	%xmm10,%xmm2
+	movups	%xmm2,-16(%rsi)
+
+.Lxts_enc_ret:
+	leaq	104(%rsp),%rsp
+.Lxts_enc_epilogue:
+	.byte	0xf3,0xc3
+.size	aesni_xts_encrypt,.-aesni_xts_encrypt
+.globl	aesni_xts_decrypt
+.type	aesni_xts_decrypt,@function
+.align	16
+aesni_xts_decrypt:
+	leaq	-104(%rsp),%rsp
+	movups	(%r9),%xmm15
+	movl	240(%r8),%eax
+	movl	240(%rcx),%r10d
+	movups	(%r8),%xmm0
+	movups	16(%r8),%xmm1
+	leaq	32(%r8),%r8
+	xorps	%xmm0,%xmm15
+.Loop_enc1_11:
+	aesenc	%xmm1,%xmm15
+	decl	%eax
+	movups	(%r8),%xmm1
+	leaq	16(%r8),%r8
+	jnz	.Loop_enc1_11	
+	aesenclast	%xmm1,%xmm15
+	xorl	%eax,%eax
+	testq	$15,%rdx
+	setnz	%al
+	shlq	$4,%rax
+	subq	%rax,%rdx
+
+	movq	%rcx,%r11
+	movl	%r10d,%eax
+	movq	%rdx,%r9
+	andq	$-16,%rdx
+
+	movdqa	.Lxts_magic(%rip),%xmm8
+	pxor	%xmm14,%xmm14
+	pcmpgtd	%xmm15,%xmm14
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm10
+	paddq	%xmm15,%xmm15
+	pand	%xmm8,%xmm9
+	pcmpgtd	%xmm15,%xmm14
+	pxor	%xmm9,%xmm15
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm11
+	paddq	%xmm15,%xmm15
+	pand	%xmm8,%xmm9
+	pcmpgtd	%xmm15,%xmm14
+	pxor	%xmm9,%xmm15
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm12
+	paddq	%xmm15,%xmm15
+	pand	%xmm8,%xmm9
+	pcmpgtd	%xmm15,%xmm14
+	pxor	%xmm9,%xmm15
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm13
+	paddq	%xmm15,%xmm15
+	pand	%xmm8,%xmm9
+	pcmpgtd	%xmm15,%xmm14
+	pxor	%xmm9,%xmm15
+	subq	$96,%rdx
+	jc	.Lxts_dec_short
+
+	shrl	$1,%eax
+	subl	$1,%eax
+	movl	%eax,%r10d
+	jmp	.Lxts_dec_grandloop
+
+.align	16
+.Lxts_dec_grandloop:
+	pshufd	$19,%xmm14,%xmm9
+	movdqa	%xmm15,%xmm14
+	paddq	%xmm15,%xmm15
+	movdqu	0(%rdi),%xmm2
+	pand	%xmm8,%xmm9
+	movdqu	16(%rdi),%xmm3
+	pxor	%xmm9,%xmm15
+
+	movdqu	32(%rdi),%xmm4
+	pxor	%xmm10,%xmm2
+	movdqu	48(%rdi),%xmm5
+	pxor	%xmm11,%xmm3
+	movdqu	64(%rdi),%xmm6
+	pxor	%xmm12,%xmm4
+	movdqu	80(%rdi),%xmm7
+	leaq	96(%rdi),%rdi
+	pxor	%xmm13,%xmm5
+	movups	(%r11),%xmm0
+	pxor	%xmm14,%xmm6
+	pxor	%xmm15,%xmm7
+
+
+
+	movups	16(%r11),%xmm1
+	pxor	%xmm0,%xmm2
+	pxor	%xmm0,%xmm3
+	movdqa	%xmm10,0(%rsp)
+	aesdec	%xmm1,%xmm2
+	leaq	32(%r11),%rcx
+	pxor	%xmm0,%xmm4
+	movdqa	%xmm11,16(%rsp)
+	aesdec	%xmm1,%xmm3
+	pxor	%xmm0,%xmm5
+	movdqa	%xmm12,32(%rsp)
+	aesdec	%xmm1,%xmm4
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm13,48(%rsp)
+	aesdec	%xmm1,%xmm5
+	pxor	%xmm0,%xmm7
+	movups	(%rcx),%xmm0
+	decl	%eax
+	movdqa	%xmm14,64(%rsp)
+	aesdec	%xmm1,%xmm6
+	movdqa	%xmm15,80(%rsp)
+	aesdec	%xmm1,%xmm7
+	pxor	%xmm14,%xmm14
+	pcmpgtd	%xmm15,%xmm14
+	jmp	.Lxts_dec_loop6_enter
+
+.align	16
+.Lxts_dec_loop6:
+	aesdec	%xmm1,%xmm2
+	aesdec	%xmm1,%xmm3
+	decl	%eax
+	aesdec	%xmm1,%xmm4
+	aesdec	%xmm1,%xmm5
+	aesdec	%xmm1,%xmm6
+	aesdec	%xmm1,%xmm7
+.Lxts_dec_loop6_enter:
+	movups	16(%rcx),%xmm1
+	aesdec	%xmm0,%xmm2
+	aesdec	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesdec	%xmm0,%xmm4
+	aesdec	%xmm0,%xmm5
+	aesdec	%xmm0,%xmm6
+	aesdec	%xmm0,%xmm7
+	movups	(%rcx),%xmm0
+	jnz	.Lxts_dec_loop6
+
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	paddq	%xmm15,%xmm15
+	aesdec	%xmm1,%xmm2
+	pand	%xmm8,%xmm9
+	aesdec	%xmm1,%xmm3
+	pcmpgtd	%xmm15,%xmm14
+	aesdec	%xmm1,%xmm4
+	pxor	%xmm9,%xmm15
+	aesdec	%xmm1,%xmm5
+	aesdec	%xmm1,%xmm6
+	aesdec	%xmm1,%xmm7
+	movups	16(%rcx),%xmm1
+
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm10
+	paddq	%xmm15,%xmm15
+	aesdec	%xmm0,%xmm2
+	pand	%xmm8,%xmm9
+	aesdec	%xmm0,%xmm3
+	pcmpgtd	%xmm15,%xmm14
+	aesdec	%xmm0,%xmm4
+	pxor	%xmm9,%xmm15
+	aesdec	%xmm0,%xmm5
+	aesdec	%xmm0,%xmm6
+	aesdec	%xmm0,%xmm7
+	movups	32(%rcx),%xmm0
+
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm11
+	paddq	%xmm15,%xmm15
+	aesdec	%xmm1,%xmm2
+	pand	%xmm8,%xmm9
+	aesdec	%xmm1,%xmm3
+	pcmpgtd	%xmm15,%xmm14
+	aesdec	%xmm1,%xmm4
+	pxor	%xmm9,%xmm15
+	aesdec	%xmm1,%xmm5
+	aesdec	%xmm1,%xmm6
+	aesdec	%xmm1,%xmm7
+
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm12
+	paddq	%xmm15,%xmm15
+	aesdeclast	%xmm0,%xmm2
+	pand	%xmm8,%xmm9
+	aesdeclast	%xmm0,%xmm3
+	pcmpgtd	%xmm15,%xmm14
+	aesdeclast	%xmm0,%xmm4
+	pxor	%xmm9,%xmm15
+	aesdeclast	%xmm0,%xmm5
+	aesdeclast	%xmm0,%xmm6
+	aesdeclast	%xmm0,%xmm7
+
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm13
+	paddq	%xmm15,%xmm15
+	xorps	0(%rsp),%xmm2
+	pand	%xmm8,%xmm9
+	xorps	16(%rsp),%xmm3
+	pcmpgtd	%xmm15,%xmm14
+	pxor	%xmm9,%xmm15
+
+	xorps	32(%rsp),%xmm4
+	movups	%xmm2,0(%rsi)
+	xorps	48(%rsp),%xmm5
+	movups	%xmm3,16(%rsi)
+	xorps	64(%rsp),%xmm6
+	movups	%xmm4,32(%rsi)
+	xorps	80(%rsp),%xmm7
+	movups	%xmm5,48(%rsi)
+	movl	%r10d,%eax
+	movups	%xmm6,64(%rsi)
+	movups	%xmm7,80(%rsi)
+	leaq	96(%rsi),%rsi
+	subq	$96,%rdx
+	jnc	.Lxts_dec_grandloop
+
+	leal	3(%rax,%rax,1),%eax
+	movq	%r11,%rcx
+	movl	%eax,%r10d
+
+.Lxts_dec_short:
+	addq	$96,%rdx
+	jz	.Lxts_dec_done
+
+	cmpq	$32,%rdx
+	jb	.Lxts_dec_one
+	je	.Lxts_dec_two
+
+	cmpq	$64,%rdx
+	jb	.Lxts_dec_three
+	je	.Lxts_dec_four
+
+	pshufd	$19,%xmm14,%xmm9
+	movdqa	%xmm15,%xmm14
+	paddq	%xmm15,%xmm15
+	movdqu	(%rdi),%xmm2
+	pand	%xmm8,%xmm9
+	movdqu	16(%rdi),%xmm3
+	pxor	%xmm9,%xmm15
+
+	movdqu	32(%rdi),%xmm4
+	pxor	%xmm10,%xmm2
+	movdqu	48(%rdi),%xmm5
+	pxor	%xmm11,%xmm3
+	movdqu	64(%rdi),%xmm6
+	leaq	80(%rdi),%rdi
+	pxor	%xmm12,%xmm4
+	pxor	%xmm13,%xmm5
+	pxor	%xmm14,%xmm6
+
+	call	_aesni_decrypt6
+
+	xorps	%xmm10,%xmm2
+	xorps	%xmm11,%xmm3
+	xorps	%xmm12,%xmm4
+	movdqu	%xmm2,(%rsi)
+	xorps	%xmm13,%xmm5
+	movdqu	%xmm3,16(%rsi)
+	xorps	%xmm14,%xmm6
+	movdqu	%xmm4,32(%rsi)
+	pxor	%xmm14,%xmm14
+	movdqu	%xmm5,48(%rsi)
+	pcmpgtd	%xmm15,%xmm14
+	movdqu	%xmm6,64(%rsi)
+	leaq	80(%rsi),%rsi
+	pshufd	$19,%xmm14,%xmm11
+	andq	$15,%r9
+	jz	.Lxts_dec_ret
+
+	movdqa	%xmm15,%xmm10
+	paddq	%xmm15,%xmm15
+	pand	%xmm8,%xmm11
+	pxor	%xmm15,%xmm11
+	jmp	.Lxts_dec_done2
+
+.align	16
+.Lxts_dec_one:
+	movups	(%rdi),%xmm2
+	leaq	16(%rdi),%rdi
+	xorps	%xmm10,%xmm2
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+.Loop_dec1_12:
+	aesdec	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	.Loop_dec1_12	
+	aesdeclast	%xmm1,%xmm2
+	xorps	%xmm10,%xmm2
+	movdqa	%xmm11,%xmm10
+	movups	%xmm2,(%rsi)
+	movdqa	%xmm12,%xmm11
+	leaq	16(%rsi),%rsi
+	jmp	.Lxts_dec_done
+
+.align	16
+.Lxts_dec_two:
+	movups	(%rdi),%xmm2
+	movups	16(%rdi),%xmm3
+	leaq	32(%rdi),%rdi
+	xorps	%xmm10,%xmm2
+	xorps	%xmm11,%xmm3
+
+	call	_aesni_decrypt3
+
+	xorps	%xmm10,%xmm2
+	movdqa	%xmm12,%xmm10
+	xorps	%xmm11,%xmm3
+	movdqa	%xmm13,%xmm11
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	leaq	32(%rsi),%rsi
+	jmp	.Lxts_dec_done
+
+.align	16
+.Lxts_dec_three:
+	movups	(%rdi),%xmm2
+	movups	16(%rdi),%xmm3
+	movups	32(%rdi),%xmm4
+	leaq	48(%rdi),%rdi
+	xorps	%xmm10,%xmm2
+	xorps	%xmm11,%xmm3
+	xorps	%xmm12,%xmm4
+
+	call	_aesni_decrypt3
+
+	xorps	%xmm10,%xmm2
+	movdqa	%xmm13,%xmm10
+	xorps	%xmm11,%xmm3
+	movdqa	%xmm15,%xmm11
+	xorps	%xmm12,%xmm4
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	leaq	48(%rsi),%rsi
+	jmp	.Lxts_dec_done
+
+.align	16
+.Lxts_dec_four:
+	pshufd	$19,%xmm14,%xmm9
+	movdqa	%xmm15,%xmm14
+	paddq	%xmm15,%xmm15
+	movups	(%rdi),%xmm2
+	pand	%xmm8,%xmm9
+	movups	16(%rdi),%xmm3
+	pxor	%xmm9,%xmm15
+
+	movups	32(%rdi),%xmm4
+	xorps	%xmm10,%xmm2
+	movups	48(%rdi),%xmm5
+	leaq	64(%rdi),%rdi
+	xorps	%xmm11,%xmm3
+	xorps	%xmm12,%xmm4
+	xorps	%xmm13,%xmm5
+
+	call	_aesni_decrypt4
+
+	xorps	%xmm10,%xmm2
+	movdqa	%xmm14,%xmm10
+	xorps	%xmm11,%xmm3
+	movdqa	%xmm15,%xmm11
+	xorps	%xmm12,%xmm4
+	movups	%xmm2,(%rsi)
+	xorps	%xmm13,%xmm5
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	leaq	64(%rsi),%rsi
+	jmp	.Lxts_dec_done
+
+.align	16
+.Lxts_dec_done:
+	andq	$15,%r9
+	jz	.Lxts_dec_ret
+.Lxts_dec_done2:
+	movq	%r9,%rdx
+	movq	%r11,%rcx
+	movl	%r10d,%eax
+
+	movups	(%rdi),%xmm2
+	xorps	%xmm11,%xmm2
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+.Loop_dec1_13:
+	aesdec	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	.Loop_dec1_13	
+	aesdeclast	%xmm1,%xmm2
+	xorps	%xmm11,%xmm2
+	movups	%xmm2,(%rsi)
+
+.Lxts_dec_steal:
+	movzbl	16(%rdi),%eax
+	movzbl	(%rsi),%ecx
+	leaq	1(%rdi),%rdi
+	movb	%al,(%rsi)
+	movb	%cl,16(%rsi)
+	leaq	1(%rsi),%rsi
+	subq	$1,%rdx
+	jnz	.Lxts_dec_steal
+
+	subq	%r9,%rsi
+	movq	%r11,%rcx
+	movl	%r10d,%eax
+
+	movups	(%rsi),%xmm2
+	xorps	%xmm10,%xmm2
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+.Loop_dec1_14:
+	aesdec	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	.Loop_dec1_14	
+	aesdeclast	%xmm1,%xmm2
+	xorps	%xmm10,%xmm2
+	movups	%xmm2,(%rsi)
+
+.Lxts_dec_ret:
+	leaq	104(%rsp),%rsp
+.Lxts_dec_epilogue:
+	.byte	0xf3,0xc3
+.size	aesni_xts_decrypt,.-aesni_xts_decrypt
+.globl	aesni_cbc_encrypt
+.type	aesni_cbc_encrypt,@function
+.align	16
+aesni_cbc_encrypt:
+	testq	%rdx,%rdx
+	jz	.Lcbc_ret
+
+	movl	240(%rcx),%r10d
+	movq	%rcx,%r11
+	testl	%r9d,%r9d
+	jz	.Lcbc_decrypt
+
+	movups	(%r8),%xmm2
+	movl	%r10d,%eax
+	cmpq	$16,%rdx
+	jb	.Lcbc_enc_tail
+	subq	$16,%rdx
+	jmp	.Lcbc_enc_loop
+.align	16
+.Lcbc_enc_loop:
+	movups	(%rdi),%xmm3
+	leaq	16(%rdi),%rdi
+
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	xorps	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	xorps	%xmm3,%xmm2
+.Loop_enc1_15:
+	aesenc	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	.Loop_enc1_15	
+	aesenclast	%xmm1,%xmm2
+	movl	%r10d,%eax
+	movq	%r11,%rcx
+	movups	%xmm2,0(%rsi)
+	leaq	16(%rsi),%rsi
+	subq	$16,%rdx
+	jnc	.Lcbc_enc_loop
+	addq	$16,%rdx
+	jnz	.Lcbc_enc_tail
+	movups	%xmm2,(%r8)
+	jmp	.Lcbc_ret
+
+.Lcbc_enc_tail:
+	movq	%rdx,%rcx
+	xchgq	%rdi,%rsi
+.long	0x9066A4F3	
+	movl	$16,%ecx
+	subq	%rdx,%rcx
+	xorl	%eax,%eax
+.long	0x9066AAF3	
+	leaq	-16(%rdi),%rdi
+	movl	%r10d,%eax
+	movq	%rdi,%rsi
+	movq	%r11,%rcx
+	xorq	%rdx,%rdx
+	jmp	.Lcbc_enc_loop	
+
+.align	16
+.Lcbc_decrypt:
+	movups	(%r8),%xmm9
+	movl	%r10d,%eax
+	cmpq	$112,%rdx
+	jbe	.Lcbc_dec_tail
+	shrl	$1,%r10d
+	subq	$112,%rdx
+	movl	%r10d,%eax
+	movaps	%xmm9,-24(%rsp)
+	jmp	.Lcbc_dec_loop8_enter
+.align	16
+.Lcbc_dec_loop8:
+	movaps	%xmm0,-24(%rsp)
+	movups	%xmm9,(%rsi)
+	leaq	16(%rsi),%rsi
+.Lcbc_dec_loop8_enter:
+	movups	(%rcx),%xmm0
+	movups	(%rdi),%xmm2
+	movups	16(%rdi),%xmm3
+	movups	16(%rcx),%xmm1
+
+	leaq	32(%rcx),%rcx
+	movdqu	32(%rdi),%xmm4
+	xorps	%xmm0,%xmm2
+	movdqu	48(%rdi),%xmm5
+	xorps	%xmm0,%xmm3
+	movdqu	64(%rdi),%xmm6
+	aesdec	%xmm1,%xmm2
+	pxor	%xmm0,%xmm4
+	movdqu	80(%rdi),%xmm7
+	aesdec	%xmm1,%xmm3
+	pxor	%xmm0,%xmm5
+	movdqu	96(%rdi),%xmm8
+	aesdec	%xmm1,%xmm4
+	pxor	%xmm0,%xmm6
+	movdqu	112(%rdi),%xmm9
+	aesdec	%xmm1,%xmm5
+	pxor	%xmm0,%xmm7
+	decl	%eax
+	aesdec	%xmm1,%xmm6
+	pxor	%xmm0,%xmm8
+	aesdec	%xmm1,%xmm7
+	pxor	%xmm0,%xmm9
+	movups	(%rcx),%xmm0
+	aesdec	%xmm1,%xmm8
+	aesdec	%xmm1,%xmm9
+	movups	16(%rcx),%xmm1
+
+	call	.Ldec_loop8_enter
+
+	movups	(%rdi),%xmm1
+	movups	16(%rdi),%xmm0
+	xorps	-24(%rsp),%xmm2
+	xorps	%xmm1,%xmm3
+	movups	32(%rdi),%xmm1
+	xorps	%xmm0,%xmm4
+	movups	48(%rdi),%xmm0
+	xorps	%xmm1,%xmm5
+	movups	64(%rdi),%xmm1
+	xorps	%xmm0,%xmm6
+	movups	80(%rdi),%xmm0
+	xorps	%xmm1,%xmm7
+	movups	96(%rdi),%xmm1
+	xorps	%xmm0,%xmm8
+	movups	112(%rdi),%xmm0
+	xorps	%xmm1,%xmm9
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movl	%r10d,%eax
+	movups	%xmm6,64(%rsi)
+	movq	%r11,%rcx
+	movups	%xmm7,80(%rsi)
+	leaq	128(%rdi),%rdi
+	movups	%xmm8,96(%rsi)
+	leaq	112(%rsi),%rsi
+	subq	$128,%rdx
+	ja	.Lcbc_dec_loop8
+
+	movaps	%xmm9,%xmm2
+	movaps	%xmm0,%xmm9
+	addq	$112,%rdx
+	jle	.Lcbc_dec_tail_collected
+	movups	%xmm2,(%rsi)
+	leal	1(%r10,%r10,1),%eax
+	leaq	16(%rsi),%rsi
+.Lcbc_dec_tail:
+	movups	(%rdi),%xmm2
+	movaps	%xmm2,%xmm8
+	cmpq	$16,%rdx
+	jbe	.Lcbc_dec_one
+
+	movups	16(%rdi),%xmm3
+	movaps	%xmm3,%xmm7
+	cmpq	$32,%rdx
+	jbe	.Lcbc_dec_two
+
+	movups	32(%rdi),%xmm4
+	movaps	%xmm4,%xmm6
+	cmpq	$48,%rdx
+	jbe	.Lcbc_dec_three
+
+	movups	48(%rdi),%xmm5
+	cmpq	$64,%rdx
+	jbe	.Lcbc_dec_four
+
+	movups	64(%rdi),%xmm6
+	cmpq	$80,%rdx
+	jbe	.Lcbc_dec_five
+
+	movups	80(%rdi),%xmm7
+	cmpq	$96,%rdx
+	jbe	.Lcbc_dec_six
+
+	movups	96(%rdi),%xmm8
+	movaps	%xmm9,-24(%rsp)
+	call	_aesni_decrypt8
+	movups	(%rdi),%xmm1
+	movups	16(%rdi),%xmm0
+	xorps	-24(%rsp),%xmm2
+	xorps	%xmm1,%xmm3
+	movups	32(%rdi),%xmm1
+	xorps	%xmm0,%xmm4
+	movups	48(%rdi),%xmm0
+	xorps	%xmm1,%xmm5
+	movups	64(%rdi),%xmm1
+	xorps	%xmm0,%xmm6
+	movups	80(%rdi),%xmm0
+	xorps	%xmm1,%xmm7
+	movups	96(%rdi),%xmm9
+	xorps	%xmm0,%xmm8
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movups	%xmm6,64(%rsi)
+	movups	%xmm7,80(%rsi)
+	leaq	96(%rsi),%rsi
+	movaps	%xmm8,%xmm2
+	subq	$112,%rdx
+	jmp	.Lcbc_dec_tail_collected
+.align	16
+.Lcbc_dec_one:
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+.Loop_dec1_16:
+	aesdec	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	.Loop_dec1_16	
+	aesdeclast	%xmm1,%xmm2
+	xorps	%xmm9,%xmm2
+	movaps	%xmm8,%xmm9
+	subq	$16,%rdx
+	jmp	.Lcbc_dec_tail_collected
+.align	16
+.Lcbc_dec_two:
+	xorps	%xmm4,%xmm4
+	call	_aesni_decrypt3
+	xorps	%xmm9,%xmm2
+	xorps	%xmm8,%xmm3
+	movups	%xmm2,(%rsi)
+	movaps	%xmm7,%xmm9
+	movaps	%xmm3,%xmm2
+	leaq	16(%rsi),%rsi
+	subq	$32,%rdx
+	jmp	.Lcbc_dec_tail_collected
+.align	16
+.Lcbc_dec_three:
+	call	_aesni_decrypt3
+	xorps	%xmm9,%xmm2
+	xorps	%xmm8,%xmm3
+	movups	%xmm2,(%rsi)
+	xorps	%xmm7,%xmm4
+	movups	%xmm3,16(%rsi)
+	movaps	%xmm6,%xmm9
+	movaps	%xmm4,%xmm2
+	leaq	32(%rsi),%rsi
+	subq	$48,%rdx
+	jmp	.Lcbc_dec_tail_collected
+.align	16
+.Lcbc_dec_four:
+	call	_aesni_decrypt4
+	xorps	%xmm9,%xmm2
+	movups	48(%rdi),%xmm9
+	xorps	%xmm8,%xmm3
+	movups	%xmm2,(%rsi)
+	xorps	%xmm7,%xmm4
+	movups	%xmm3,16(%rsi)
+	xorps	%xmm6,%xmm5
+	movups	%xmm4,32(%rsi)
+	movaps	%xmm5,%xmm2
+	leaq	48(%rsi),%rsi
+	subq	$64,%rdx
+	jmp	.Lcbc_dec_tail_collected
+.align	16
+.Lcbc_dec_five:
+	xorps	%xmm7,%xmm7
+	call	_aesni_decrypt6
+	movups	16(%rdi),%xmm1
+	movups	32(%rdi),%xmm0
+	xorps	%xmm9,%xmm2
+	xorps	%xmm8,%xmm3
+	xorps	%xmm1,%xmm4
+	movups	48(%rdi),%xmm1
+	xorps	%xmm0,%xmm5
+	movups	64(%rdi),%xmm9
+	xorps	%xmm1,%xmm6
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	leaq	64(%rsi),%rsi
+	movaps	%xmm6,%xmm2
+	subq	$80,%rdx
+	jmp	.Lcbc_dec_tail_collected
+.align	16
+.Lcbc_dec_six:
+	call	_aesni_decrypt6
+	movups	16(%rdi),%xmm1
+	movups	32(%rdi),%xmm0
+	xorps	%xmm9,%xmm2
+	xorps	%xmm8,%xmm3
+	xorps	%xmm1,%xmm4
+	movups	48(%rdi),%xmm1
+	xorps	%xmm0,%xmm5
+	movups	64(%rdi),%xmm0
+	xorps	%xmm1,%xmm6
+	movups	80(%rdi),%xmm9
+	xorps	%xmm0,%xmm7
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movups	%xmm6,64(%rsi)
+	leaq	80(%rsi),%rsi
+	movaps	%xmm7,%xmm2
+	subq	$96,%rdx
+	jmp	.Lcbc_dec_tail_collected
+.align	16
+.Lcbc_dec_tail_collected:
+	andq	$15,%rdx
+	movups	%xmm9,(%r8)
+	jnz	.Lcbc_dec_tail_partial
+	movups	%xmm2,(%rsi)
+	jmp	.Lcbc_dec_ret
+.align	16
+.Lcbc_dec_tail_partial:
+	movaps	%xmm2,-24(%rsp)
+	movq	$16,%rcx
+	movq	%rsi,%rdi
+	subq	%rdx,%rcx
+	leaq	-24(%rsp),%rsi
+.long	0x9066A4F3	
+
+.Lcbc_dec_ret:
+.Lcbc_ret:
+	.byte	0xf3,0xc3
+.size	aesni_cbc_encrypt,.-aesni_cbc_encrypt
+.globl	aesni_set_decrypt_key
+.type	aesni_set_decrypt_key,@function
+.align	16
+aesni_set_decrypt_key:
+	subq	$8,%rsp
+	call	__aesni_set_encrypt_key
+	shll	$4,%esi
+	testl	%eax,%eax
+	jnz	.Ldec_key_ret
+	leaq	16(%rdx,%rsi,1),%rdi
+
+	movups	(%rdx),%xmm0
+	movups	(%rdi),%xmm1
+	movups	%xmm0,(%rdi)
+	movups	%xmm1,(%rdx)
+	leaq	16(%rdx),%rdx
+	leaq	-16(%rdi),%rdi
+
+.Ldec_key_inverse:
+	movups	(%rdx),%xmm0
+	movups	(%rdi),%xmm1
+	aesimc	%xmm0,%xmm0
+	aesimc	%xmm1,%xmm1
+	leaq	16(%rdx),%rdx
+	leaq	-16(%rdi),%rdi
+	movups	%xmm0,16(%rdi)
+	movups	%xmm1,-16(%rdx)
+	cmpq	%rdx,%rdi
+	ja	.Ldec_key_inverse
+
+	movups	(%rdx),%xmm0
+	aesimc	%xmm0,%xmm0
+	movups	%xmm0,(%rdi)
+.Ldec_key_ret:
+	addq	$8,%rsp
+	.byte	0xf3,0xc3
+.LSEH_end_set_decrypt_key:
+.size	aesni_set_decrypt_key,.-aesni_set_decrypt_key
+.globl	aesni_set_encrypt_key
+.type	aesni_set_encrypt_key,@function
+.align	16
+aesni_set_encrypt_key:
+__aesni_set_encrypt_key:
+	subq	$8,%rsp
+	movq	$-1,%rax
+	testq	%rdi,%rdi
+	jz	.Lenc_key_ret
+	testq	%rdx,%rdx
+	jz	.Lenc_key_ret
+
+	movups	(%rdi),%xmm0
+	xorps	%xmm4,%xmm4
+	leaq	16(%rdx),%rax
+	cmpl	$256,%esi
+	je	.L14rounds
+	cmpl	$192,%esi
+	je	.L12rounds
+	cmpl	$128,%esi
+	jne	.Lbad_keybits
+
+.L10rounds:
+	movl	$9,%esi
+	movups	%xmm0,(%rdx)
+	aeskeygenassist	$1,%xmm0,%xmm1
+	call	.Lkey_expansion_128_cold
+	aeskeygenassist	$2,%xmm0,%xmm1
+	call	.Lkey_expansion_128
+	aeskeygenassist	$4,%xmm0,%xmm1
+	call	.Lkey_expansion_128
+	aeskeygenassist	$8,%xmm0,%xmm1
+	call	.Lkey_expansion_128
+	aeskeygenassist	$16,%xmm0,%xmm1
+	call	.Lkey_expansion_128
+	aeskeygenassist	$32,%xmm0,%xmm1
+	call	.Lkey_expansion_128
+	aeskeygenassist	$64,%xmm0,%xmm1
+	call	.Lkey_expansion_128
+	aeskeygenassist	$128,%xmm0,%xmm1
+	call	.Lkey_expansion_128
+	aeskeygenassist	$27,%xmm0,%xmm1
+	call	.Lkey_expansion_128
+	aeskeygenassist	$54,%xmm0,%xmm1
+	call	.Lkey_expansion_128
+	movups	%xmm0,(%rax)
+	movl	%esi,80(%rax)
+	xorl	%eax,%eax
+	jmp	.Lenc_key_ret
+
+.align	16
+.L12rounds:
+	movq	16(%rdi),%xmm2
+	movl	$11,%esi
+	movups	%xmm0,(%rdx)
+	aeskeygenassist	$1,%xmm2,%xmm1
+	call	.Lkey_expansion_192a_cold
+	aeskeygenassist	$2,%xmm2,%xmm1
+	call	.Lkey_expansion_192b
+	aeskeygenassist	$4,%xmm2,%xmm1
+	call	.Lkey_expansion_192a
+	aeskeygenassist	$8,%xmm2,%xmm1
+	call	.Lkey_expansion_192b
+	aeskeygenassist	$16,%xmm2,%xmm1
+	call	.Lkey_expansion_192a
+	aeskeygenassist	$32,%xmm2,%xmm1
+	call	.Lkey_expansion_192b
+	aeskeygenassist	$64,%xmm2,%xmm1
+	call	.Lkey_expansion_192a
+	aeskeygenassist	$128,%xmm2,%xmm1
+	call	.Lkey_expansion_192b
+	movups	%xmm0,(%rax)
+	movl	%esi,48(%rax)
+	xorq	%rax,%rax
+	jmp	.Lenc_key_ret
+
+.align	16
+.L14rounds:
+	movups	16(%rdi),%xmm2
+	movl	$13,%esi
+	leaq	16(%rax),%rax
+	movups	%xmm0,(%rdx)
+	movups	%xmm2,16(%rdx)
+	aeskeygenassist	$1,%xmm2,%xmm1
+	call	.Lkey_expansion_256a_cold
+	aeskeygenassist	$1,%xmm0,%xmm1
+	call	.Lkey_expansion_256b
+	aeskeygenassist	$2,%xmm2,%xmm1
+	call	.Lkey_expansion_256a
+	aeskeygenassist	$2,%xmm0,%xmm1
+	call	.Lkey_expansion_256b
+	aeskeygenassist	$4,%xmm2,%xmm1
+	call	.Lkey_expansion_256a
+	aeskeygenassist	$4,%xmm0,%xmm1
+	call	.Lkey_expansion_256b
+	aeskeygenassist	$8,%xmm2,%xmm1
+	call	.Lkey_expansion_256a
+	aeskeygenassist	$8,%xmm0,%xmm1
+	call	.Lkey_expansion_256b
+	aeskeygenassist	$16,%xmm2,%xmm1
+	call	.Lkey_expansion_256a
+	aeskeygenassist	$16,%xmm0,%xmm1
+	call	.Lkey_expansion_256b
+	aeskeygenassist	$32,%xmm2,%xmm1
+	call	.Lkey_expansion_256a
+	aeskeygenassist	$32,%xmm0,%xmm1
+	call	.Lkey_expansion_256b
+	aeskeygenassist	$64,%xmm2,%xmm1
+	call	.Lkey_expansion_256a
+	movups	%xmm0,(%rax)
+	movl	%esi,16(%rax)
+	xorq	%rax,%rax
+	jmp	.Lenc_key_ret
+
+.align	16
+.Lbad_keybits:
+	movq	$-2,%rax
+.Lenc_key_ret:
+	addq	$8,%rsp
+	.byte	0xf3,0xc3
+.LSEH_end_set_encrypt_key:
+
+.align	16
+.Lkey_expansion_128:
+	movups	%xmm0,(%rax)
+	leaq	16(%rax),%rax
+.Lkey_expansion_128_cold:
+	shufps	$16,%xmm0,%xmm4
+	xorps	%xmm4,%xmm0
+	shufps	$140,%xmm0,%xmm4
+	xorps	%xmm4,%xmm0
+	shufps	$255,%xmm1,%xmm1
+	xorps	%xmm1,%xmm0
+	.byte	0xf3,0xc3
+
+.align	16
+.Lkey_expansion_192a:
+	movups	%xmm0,(%rax)
+	leaq	16(%rax),%rax
+.Lkey_expansion_192a_cold:
+	movaps	%xmm2,%xmm5
+.Lkey_expansion_192b_warm:
+	shufps	$16,%xmm0,%xmm4
+	movdqa	%xmm2,%xmm3
+	xorps	%xmm4,%xmm0
+	shufps	$140,%xmm0,%xmm4
+	pslldq	$4,%xmm3
+	xorps	%xmm4,%xmm0
+	pshufd	$85,%xmm1,%xmm1
+	pxor	%xmm3,%xmm2
+	pxor	%xmm1,%xmm0
+	pshufd	$255,%xmm0,%xmm3
+	pxor	%xmm3,%xmm2
+	.byte	0xf3,0xc3
+
+.align	16
+.Lkey_expansion_192b:
+	movaps	%xmm0,%xmm3
+	shufps	$68,%xmm0,%xmm5
+	movups	%xmm5,(%rax)
+	shufps	$78,%xmm2,%xmm3
+	movups	%xmm3,16(%rax)
+	leaq	32(%rax),%rax
+	jmp	.Lkey_expansion_192b_warm
+
+.align	16
+.Lkey_expansion_256a:
+	movups	%xmm2,(%rax)
+	leaq	16(%rax),%rax
+.Lkey_expansion_256a_cold:
+	shufps	$16,%xmm0,%xmm4
+	xorps	%xmm4,%xmm0
+	shufps	$140,%xmm0,%xmm4
+	xorps	%xmm4,%xmm0
+	shufps	$255,%xmm1,%xmm1
+	xorps	%xmm1,%xmm0
+	.byte	0xf3,0xc3
+
+.align	16
+.Lkey_expansion_256b:
+	movups	%xmm0,(%rax)
+	leaq	16(%rax),%rax
+
+	shufps	$16,%xmm2,%xmm4
+	xorps	%xmm4,%xmm2
+	shufps	$140,%xmm2,%xmm4
+	xorps	%xmm4,%xmm2
+	shufps	$170,%xmm1,%xmm1
+	xorps	%xmm1,%xmm2
+	.byte	0xf3,0xc3
+.size	aesni_set_encrypt_key,.-aesni_set_encrypt_key
+.size	__aesni_set_encrypt_key,.-__aesni_set_encrypt_key
+.align	64
+.Lbswap_mask:
+.byte	15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
+.Lincrement32:
+.long	6,6,6,0
+.Lincrement64:
+.long	1,0,0,0
+.Lxts_magic:
+.long	0x87,0,1,0
+
+.byte	65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69,83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align	64
+#if defined(HAVE_GNU_STACK)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/crypto/libressl/crypto/aes/aesni-macosx-x86_64.s b/crypto/libressl/crypto/aes/aesni-macosx-x86_64.s
new file mode 100644
index 0000000000..befaa412da
--- /dev/null
+++ b/crypto/libressl/crypto/aes/aesni-macosx-x86_64.s
@@ -0,0 +1,2535 @@
+.text	
+.globl	_aesni_encrypt
+
+.p2align	4
+_aesni_encrypt:
+	movups	(%rdi),%xmm2
+	movl	240(%rdx),%eax
+	movups	(%rdx),%xmm0
+	movups	16(%rdx),%xmm1
+	leaq	32(%rdx),%rdx
+	xorps	%xmm0,%xmm2
+L$oop_enc1_1:
+	aesenc	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rdx),%xmm1
+	leaq	16(%rdx),%rdx
+	jnz	L$oop_enc1_1	
+	aesenclast	%xmm1,%xmm2
+	movups	%xmm2,(%rsi)
+	.byte	0xf3,0xc3
+
+
+.globl	_aesni_decrypt
+
+.p2align	4
+_aesni_decrypt:
+	movups	(%rdi),%xmm2
+	movl	240(%rdx),%eax
+	movups	(%rdx),%xmm0
+	movups	16(%rdx),%xmm1
+	leaq	32(%rdx),%rdx
+	xorps	%xmm0,%xmm2
+L$oop_dec1_2:
+	aesdec	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rdx),%xmm1
+	leaq	16(%rdx),%rdx
+	jnz	L$oop_dec1_2	
+	aesdeclast	%xmm1,%xmm2
+	movups	%xmm2,(%rsi)
+	.byte	0xf3,0xc3
+
+
+.p2align	4
+_aesni_encrypt3:
+	movups	(%rcx),%xmm0
+	shrl	$1,%eax
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+	xorps	%xmm0,%xmm3
+	xorps	%xmm0,%xmm4
+	movups	(%rcx),%xmm0
+
+L$enc_loop3:
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	decl	%eax
+	aesenc	%xmm1,%xmm4
+	movups	16(%rcx),%xmm1
+	aesenc	%xmm0,%xmm2
+	aesenc	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesenc	%xmm0,%xmm4
+	movups	(%rcx),%xmm0
+	jnz	L$enc_loop3
+
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	aesenc	%xmm1,%xmm4
+	aesenclast	%xmm0,%xmm2
+	aesenclast	%xmm0,%xmm3
+	aesenclast	%xmm0,%xmm4
+	.byte	0xf3,0xc3
+
+
+.p2align	4
+_aesni_decrypt3:
+	movups	(%rcx),%xmm0
+	shrl	$1,%eax
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+	xorps	%xmm0,%xmm3
+	xorps	%xmm0,%xmm4
+	movups	(%rcx),%xmm0
+
+L$dec_loop3:
+	aesdec	%xmm1,%xmm2
+	aesdec	%xmm1,%xmm3
+	decl	%eax
+	aesdec	%xmm1,%xmm4
+	movups	16(%rcx),%xmm1
+	aesdec	%xmm0,%xmm2
+	aesdec	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesdec	%xmm0,%xmm4
+	movups	(%rcx),%xmm0
+	jnz	L$dec_loop3
+
+	aesdec	%xmm1,%xmm2
+	aesdec	%xmm1,%xmm3
+	aesdec	%xmm1,%xmm4
+	aesdeclast	%xmm0,%xmm2
+	aesdeclast	%xmm0,%xmm3
+	aesdeclast	%xmm0,%xmm4
+	.byte	0xf3,0xc3
+
+
+.p2align	4
+_aesni_encrypt4:
+	movups	(%rcx),%xmm0
+	shrl	$1,%eax
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+	xorps	%xmm0,%xmm3
+	xorps	%xmm0,%xmm4
+	xorps	%xmm0,%xmm5
+	movups	(%rcx),%xmm0
+
+L$enc_loop4:
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	decl	%eax
+	aesenc	%xmm1,%xmm4
+	aesenc	%xmm1,%xmm5
+	movups	16(%rcx),%xmm1
+	aesenc	%xmm0,%xmm2
+	aesenc	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesenc	%xmm0,%xmm4
+	aesenc	%xmm0,%xmm5
+	movups	(%rcx),%xmm0
+	jnz	L$enc_loop4
+
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	aesenc	%xmm1,%xmm4
+	aesenc	%xmm1,%xmm5
+	aesenclast	%xmm0,%xmm2
+	aesenclast	%xmm0,%xmm3
+	aesenclast	%xmm0,%xmm4
+	aesenclast	%xmm0,%xmm5
+	.byte	0xf3,0xc3
+
+
+.p2align	4
+_aesni_decrypt4:
+	movups	(%rcx),%xmm0
+	shrl	$1,%eax
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+	xorps	%xmm0,%xmm3
+	xorps	%xmm0,%xmm4
+	xorps	%xmm0,%xmm5
+	movups	(%rcx),%xmm0
+
+L$dec_loop4:
+	aesdec	%xmm1,%xmm2
+	aesdec	%xmm1,%xmm3
+	decl	%eax
+	aesdec	%xmm1,%xmm4
+	aesdec	%xmm1,%xmm5
+	movups	16(%rcx),%xmm1
+	aesdec	%xmm0,%xmm2
+	aesdec	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesdec	%xmm0,%xmm4
+	aesdec	%xmm0,%xmm5
+	movups	(%rcx),%xmm0
+	jnz	L$dec_loop4
+
+	aesdec	%xmm1,%xmm2
+	aesdec	%xmm1,%xmm3
+	aesdec	%xmm1,%xmm4
+	aesdec	%xmm1,%xmm5
+	aesdeclast	%xmm0,%xmm2
+	aesdeclast	%xmm0,%xmm3
+	aesdeclast	%xmm0,%xmm4
+	aesdeclast	%xmm0,%xmm5
+	.byte	0xf3,0xc3
+
+
+.p2align	4
+_aesni_encrypt6:
+	movups	(%rcx),%xmm0
+	shrl	$1,%eax
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+	pxor	%xmm0,%xmm3
+	aesenc	%xmm1,%xmm2
+	pxor	%xmm0,%xmm4
+	aesenc	%xmm1,%xmm3
+	pxor	%xmm0,%xmm5
+	aesenc	%xmm1,%xmm4
+	pxor	%xmm0,%xmm6
+	aesenc	%xmm1,%xmm5
+	pxor	%xmm0,%xmm7
+	decl	%eax
+	aesenc	%xmm1,%xmm6
+	movups	(%rcx),%xmm0
+	aesenc	%xmm1,%xmm7
+	jmp	L$enc_loop6_enter
+.p2align	4
+L$enc_loop6:
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	decl	%eax
+	aesenc	%xmm1,%xmm4
+	aesenc	%xmm1,%xmm5
+	aesenc	%xmm1,%xmm6
+	aesenc	%xmm1,%xmm7
+L$enc_loop6_enter:
+	movups	16(%rcx),%xmm1
+	aesenc	%xmm0,%xmm2
+	aesenc	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesenc	%xmm0,%xmm4
+	aesenc	%xmm0,%xmm5
+	aesenc	%xmm0,%xmm6
+	aesenc	%xmm0,%xmm7
+	movups	(%rcx),%xmm0
+	jnz	L$enc_loop6
+
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	aesenc	%xmm1,%xmm4
+	aesenc	%xmm1,%xmm5
+	aesenc	%xmm1,%xmm6
+	aesenc	%xmm1,%xmm7
+	aesenclast	%xmm0,%xmm2
+	aesenclast	%xmm0,%xmm3
+	aesenclast	%xmm0,%xmm4
+	aesenclast	%xmm0,%xmm5
+	aesenclast	%xmm0,%xmm6
+	aesenclast	%xmm0,%xmm7
+	.byte	0xf3,0xc3
+
+
+.p2align	4
+_aesni_decrypt6:
+	movups	(%rcx),%xmm0
+	shrl	$1,%eax
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+	pxor	%xmm0,%xmm3
+	aesdec	%xmm1,%xmm2
+	pxor	%xmm0,%xmm4
+	aesdec	%xmm1,%xmm3
+	pxor	%xmm0,%xmm5
+	aesdec	%xmm1,%xmm4
+	pxor	%xmm0,%xmm6
+	aesdec	%xmm1,%xmm5
+	pxor	%xmm0,%xmm7
+	decl	%eax
+	aesdec	%xmm1,%xmm6
+	movups	(%rcx),%xmm0
+	aesdec	%xmm1,%xmm7
+	jmp	L$dec_loop6_enter
+.p2align	4
+L$dec_loop6:
+	aesdec	%xmm1,%xmm2
+	aesdec	%xmm1,%xmm3
+	decl	%eax
+	aesdec	%xmm1,%xmm4
+	aesdec	%xmm1,%xmm5
+	aesdec	%xmm1,%xmm6
+	aesdec	%xmm1,%xmm7
+L$dec_loop6_enter:
+	movups	16(%rcx),%xmm1
+	aesdec	%xmm0,%xmm2
+	aesdec	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesdec	%xmm0,%xmm4
+	aesdec	%xmm0,%xmm5
+	aesdec	%xmm0,%xmm6
+	aesdec	%xmm0,%xmm7
+	movups	(%rcx),%xmm0
+	jnz	L$dec_loop6
+
+	aesdec	%xmm1,%xmm2
+	aesdec	%xmm1,%xmm3
+	aesdec	%xmm1,%xmm4
+	aesdec	%xmm1,%xmm5
+	aesdec	%xmm1,%xmm6
+	aesdec	%xmm1,%xmm7
+	aesdeclast	%xmm0,%xmm2
+	aesdeclast	%xmm0,%xmm3
+	aesdeclast	%xmm0,%xmm4
+	aesdeclast	%xmm0,%xmm5
+	aesdeclast	%xmm0,%xmm6
+	aesdeclast	%xmm0,%xmm7
+	.byte	0xf3,0xc3
+
+
+.p2align	4
+_aesni_encrypt8:
+	movups	(%rcx),%xmm0
+	shrl	$1,%eax
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+	xorps	%xmm0,%xmm3
+	aesenc	%xmm1,%xmm2
+	pxor	%xmm0,%xmm4
+	aesenc	%xmm1,%xmm3
+	pxor	%xmm0,%xmm5
+	aesenc	%xmm1,%xmm4
+	pxor	%xmm0,%xmm6
+	aesenc	%xmm1,%xmm5
+	pxor	%xmm0,%xmm7
+	decl	%eax
+	aesenc	%xmm1,%xmm6
+	pxor	%xmm0,%xmm8
+	aesenc	%xmm1,%xmm7
+	pxor	%xmm0,%xmm9
+	movups	(%rcx),%xmm0
+	aesenc	%xmm1,%xmm8
+	aesenc	%xmm1,%xmm9
+	movups	16(%rcx),%xmm1
+	jmp	L$enc_loop8_enter
+.p2align	4
+L$enc_loop8:
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	decl	%eax
+	aesenc	%xmm1,%xmm4
+	aesenc	%xmm1,%xmm5
+	aesenc	%xmm1,%xmm6
+	aesenc	%xmm1,%xmm7
+	aesenc	%xmm1,%xmm8
+	aesenc	%xmm1,%xmm9
+	movups	16(%rcx),%xmm1
+L$enc_loop8_enter:
+	aesenc	%xmm0,%xmm2
+	aesenc	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesenc	%xmm0,%xmm4
+	aesenc	%xmm0,%xmm5
+	aesenc	%xmm0,%xmm6
+	aesenc	%xmm0,%xmm7
+	aesenc	%xmm0,%xmm8
+	aesenc	%xmm0,%xmm9
+	movups	(%rcx),%xmm0
+	jnz	L$enc_loop8
+
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	aesenc	%xmm1,%xmm4
+	aesenc	%xmm1,%xmm5
+	aesenc	%xmm1,%xmm6
+	aesenc	%xmm1,%xmm7
+	aesenc	%xmm1,%xmm8
+	aesenc	%xmm1,%xmm9
+	aesenclast	%xmm0,%xmm2
+	aesenclast	%xmm0,%xmm3
+	aesenclast	%xmm0,%xmm4
+	aesenclast	%xmm0,%xmm5
+	aesenclast	%xmm0,%xmm6
+	aesenclast	%xmm0,%xmm7
+	aesenclast	%xmm0,%xmm8
+	aesenclast	%xmm0,%xmm9
+	.byte	0xf3,0xc3
+
+
+.p2align	4
+_aesni_decrypt8:
+	movups	(%rcx),%xmm0
+	shrl	$1,%eax
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+	xorps	%xmm0,%xmm3
+	aesdec	%xmm1,%xmm2
+	pxor	%xmm0,%xmm4
+	aesdec	%xmm1,%xmm3
+	pxor	%xmm0,%xmm5
+	aesdec	%xmm1,%xmm4
+	pxor	%xmm0,%xmm6
+	aesdec	%xmm1,%xmm5
+	pxor	%xmm0,%xmm7
+	decl	%eax
+	aesdec	%xmm1,%xmm6
+	pxor	%xmm0,%xmm8
+	aesdec	%xmm1,%xmm7
+	pxor	%xmm0,%xmm9
+	movups	(%rcx),%xmm0
+	aesdec	%xmm1,%xmm8
+	aesdec	%xmm1,%xmm9
+	movups	16(%rcx),%xmm1
+	jmp	L$dec_loop8_enter
+.p2align	4
+L$dec_loop8:
+	aesdec	%xmm1,%xmm2
+	aesdec	%xmm1,%xmm3
+	decl	%eax
+	aesdec	%xmm1,%xmm4
+	aesdec	%xmm1,%xmm5
+	aesdec	%xmm1,%xmm6
+	aesdec	%xmm1,%xmm7
+	aesdec	%xmm1,%xmm8
+	aesdec	%xmm1,%xmm9
+	movups	16(%rcx),%xmm1
+L$dec_loop8_enter:
+	aesdec	%xmm0,%xmm2
+	aesdec	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesdec	%xmm0,%xmm4
+	aesdec	%xmm0,%xmm5
+	aesdec	%xmm0,%xmm6
+	aesdec	%xmm0,%xmm7
+	aesdec	%xmm0,%xmm8
+	aesdec	%xmm0,%xmm9
+	movups	(%rcx),%xmm0
+	jnz	L$dec_loop8
+
+	aesdec	%xmm1,%xmm2
+	aesdec	%xmm1,%xmm3
+	aesdec	%xmm1,%xmm4
+	aesdec	%xmm1,%xmm5
+	aesdec	%xmm1,%xmm6
+	aesdec	%xmm1,%xmm7
+	aesdec	%xmm1,%xmm8
+	aesdec	%xmm1,%xmm9
+	aesdeclast	%xmm0,%xmm2
+	aesdeclast	%xmm0,%xmm3
+	aesdeclast	%xmm0,%xmm4
+	aesdeclast	%xmm0,%xmm5
+	aesdeclast	%xmm0,%xmm6
+	aesdeclast	%xmm0,%xmm7
+	aesdeclast	%xmm0,%xmm8
+	aesdeclast	%xmm0,%xmm9
+	.byte	0xf3,0xc3
+
+.globl	_aesni_ecb_encrypt
+
+.p2align	4
+_aesni_ecb_encrypt:
+	andq	$-16,%rdx
+	jz	L$ecb_ret
+
+	movl	240(%rcx),%eax
+	movups	(%rcx),%xmm0
+	movq	%rcx,%r11
+	movl	%eax,%r10d
+	testl	%r8d,%r8d
+	jz	L$ecb_decrypt
+
+	cmpq	$128,%rdx
+	jb	L$ecb_enc_tail
+
+	movdqu	(%rdi),%xmm2
+	movdqu	16(%rdi),%xmm3
+	movdqu	32(%rdi),%xmm4
+	movdqu	48(%rdi),%xmm5
+	movdqu	64(%rdi),%xmm6
+	movdqu	80(%rdi),%xmm7
+	movdqu	96(%rdi),%xmm8
+	movdqu	112(%rdi),%xmm9
+	leaq	128(%rdi),%rdi
+	subq	$128,%rdx
+	jmp	L$ecb_enc_loop8_enter
+.p2align	4
+L$ecb_enc_loop8:
+	movups	%xmm2,(%rsi)
+	movq	%r11,%rcx
+	movdqu	(%rdi),%xmm2
+	movl	%r10d,%eax
+	movups	%xmm3,16(%rsi)
+	movdqu	16(%rdi),%xmm3
+	movups	%xmm4,32(%rsi)
+	movdqu	32(%rdi),%xmm4
+	movups	%xmm5,48(%rsi)
+	movdqu	48(%rdi),%xmm5
+	movups	%xmm6,64(%rsi)
+	movdqu	64(%rdi),%xmm6
+	movups	%xmm7,80(%rsi)
+	movdqu	80(%rdi),%xmm7
+	movups	%xmm8,96(%rsi)
+	movdqu	96(%rdi),%xmm8
+	movups	%xmm9,112(%rsi)
+	leaq	128(%rsi),%rsi
+	movdqu	112(%rdi),%xmm9
+	leaq	128(%rdi),%rdi
+L$ecb_enc_loop8_enter:
+
+	call	_aesni_encrypt8
+
+	subq	$128,%rdx
+	jnc	L$ecb_enc_loop8
+
+	movups	%xmm2,(%rsi)
+	movq	%r11,%rcx
+	movups	%xmm3,16(%rsi)
+	movl	%r10d,%eax
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movups	%xmm6,64(%rsi)
+	movups	%xmm7,80(%rsi)
+	movups	%xmm8,96(%rsi)
+	movups	%xmm9,112(%rsi)
+	leaq	128(%rsi),%rsi
+	addq	$128,%rdx
+	jz	L$ecb_ret
+
+L$ecb_enc_tail:
+	movups	(%rdi),%xmm2
+	cmpq	$32,%rdx
+	jb	L$ecb_enc_one
+	movups	16(%rdi),%xmm3
+	je	L$ecb_enc_two
+	movups	32(%rdi),%xmm4
+	cmpq	$64,%rdx
+	jb	L$ecb_enc_three
+	movups	48(%rdi),%xmm5
+	je	L$ecb_enc_four
+	movups	64(%rdi),%xmm6
+	cmpq	$96,%rdx
+	jb	L$ecb_enc_five
+	movups	80(%rdi),%xmm7
+	je	L$ecb_enc_six
+	movdqu	96(%rdi),%xmm8
+	call	_aesni_encrypt8
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movups	%xmm6,64(%rsi)
+	movups	%xmm7,80(%rsi)
+	movups	%xmm8,96(%rsi)
+	jmp	L$ecb_ret
+.p2align	4
+L$ecb_enc_one:
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+L$oop_enc1_3:
+	aesenc	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	L$oop_enc1_3	
+	aesenclast	%xmm1,%xmm2
+	movups	%xmm2,(%rsi)
+	jmp	L$ecb_ret
+.p2align	4
+L$ecb_enc_two:
+	xorps	%xmm4,%xmm4
+	call	_aesni_encrypt3
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	jmp	L$ecb_ret
+.p2align	4
+L$ecb_enc_three:
+	call	_aesni_encrypt3
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	jmp	L$ecb_ret
+.p2align	4
+L$ecb_enc_four:
+	call	_aesni_encrypt4
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	jmp	L$ecb_ret
+.p2align	4
+L$ecb_enc_five:
+	xorps	%xmm7,%xmm7
+	call	_aesni_encrypt6
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movups	%xmm6,64(%rsi)
+	jmp	L$ecb_ret
+.p2align	4
+L$ecb_enc_six:
+	call	_aesni_encrypt6
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movups	%xmm6,64(%rsi)
+	movups	%xmm7,80(%rsi)
+	jmp	L$ecb_ret
+
+.p2align	4
+L$ecb_decrypt:
+	cmpq	$128,%rdx
+	jb	L$ecb_dec_tail
+
+	movdqu	(%rdi),%xmm2
+	movdqu	16(%rdi),%xmm3
+	movdqu	32(%rdi),%xmm4
+	movdqu	48(%rdi),%xmm5
+	movdqu	64(%rdi),%xmm6
+	movdqu	80(%rdi),%xmm7
+	movdqu	96(%rdi),%xmm8
+	movdqu	112(%rdi),%xmm9
+	leaq	128(%rdi),%rdi
+	subq	$128,%rdx
+	jmp	L$ecb_dec_loop8_enter
+.p2align	4
+L$ecb_dec_loop8:
+	movups	%xmm2,(%rsi)
+	movq	%r11,%rcx
+	movdqu	(%rdi),%xmm2
+	movl	%r10d,%eax
+	movups	%xmm3,16(%rsi)
+	movdqu	16(%rdi),%xmm3
+	movups	%xmm4,32(%rsi)
+	movdqu	32(%rdi),%xmm4
+	movups	%xmm5,48(%rsi)
+	movdqu	48(%rdi),%xmm5
+	movups	%xmm6,64(%rsi)
+	movdqu	64(%rdi),%xmm6
+	movups	%xmm7,80(%rsi)
+	movdqu	80(%rdi),%xmm7
+	movups	%xmm8,96(%rsi)
+	movdqu	96(%rdi),%xmm8
+	movups	%xmm9,112(%rsi)
+	leaq	128(%rsi),%rsi
+	movdqu	112(%rdi),%xmm9
+	leaq	128(%rdi),%rdi
+L$ecb_dec_loop8_enter:
+
+	call	_aesni_decrypt8
+
+	movups	(%r11),%xmm0
+	subq	$128,%rdx
+	jnc	L$ecb_dec_loop8
+
+	movups	%xmm2,(%rsi)
+	movq	%r11,%rcx
+	movups	%xmm3,16(%rsi)
+	movl	%r10d,%eax
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movups	%xmm6,64(%rsi)
+	movups	%xmm7,80(%rsi)
+	movups	%xmm8,96(%rsi)
+	movups	%xmm9,112(%rsi)
+	leaq	128(%rsi),%rsi
+	addq	$128,%rdx
+	jz	L$ecb_ret
+
+L$ecb_dec_tail:
+	movups	(%rdi),%xmm2
+	cmpq	$32,%rdx
+	jb	L$ecb_dec_one
+	movups	16(%rdi),%xmm3
+	je	L$ecb_dec_two
+	movups	32(%rdi),%xmm4
+	cmpq	$64,%rdx
+	jb	L$ecb_dec_three
+	movups	48(%rdi),%xmm5
+	je	L$ecb_dec_four
+	movups	64(%rdi),%xmm6
+	cmpq	$96,%rdx
+	jb	L$ecb_dec_five
+	movups	80(%rdi),%xmm7
+	je	L$ecb_dec_six
+	movups	96(%rdi),%xmm8
+	movups	(%rcx),%xmm0
+	call	_aesni_decrypt8
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movups	%xmm6,64(%rsi)
+	movups	%xmm7,80(%rsi)
+	movups	%xmm8,96(%rsi)
+	jmp	L$ecb_ret
+.p2align	4
+L$ecb_dec_one:
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+L$oop_dec1_4:
+	aesdec	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	L$oop_dec1_4	
+	aesdeclast	%xmm1,%xmm2
+	movups	%xmm2,(%rsi)
+	jmp	L$ecb_ret
+.p2align	4
+L$ecb_dec_two:
+	xorps	%xmm4,%xmm4
+	call	_aesni_decrypt3
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	jmp	L$ecb_ret
+.p2align	4
+L$ecb_dec_three:
+	call	_aesni_decrypt3
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	jmp	L$ecb_ret
+.p2align	4
+L$ecb_dec_four:
+	call	_aesni_decrypt4
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	jmp	L$ecb_ret
+.p2align	4
+L$ecb_dec_five:
+	xorps	%xmm7,%xmm7
+	call	_aesni_decrypt6
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movups	%xmm6,64(%rsi)
+	jmp	L$ecb_ret
+.p2align	4
+L$ecb_dec_six:
+	call	_aesni_decrypt6
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movups	%xmm6,64(%rsi)
+	movups	%xmm7,80(%rsi)
+
+L$ecb_ret:
+	.byte	0xf3,0xc3
+
+.globl	_aesni_ccm64_encrypt_blocks
+
+.p2align	4
+_aesni_ccm64_encrypt_blocks:
+	movl	240(%rcx),%eax
+	movdqu	(%r8),%xmm9
+	movdqa	L$increment64(%rip),%xmm6
+	movdqa	L$bswap_mask(%rip),%xmm7
+
+	shrl	$1,%eax
+	leaq	0(%rcx),%r11
+	movdqu	(%r9),%xmm3
+	movdqa	%xmm9,%xmm2
+	movl	%eax,%r10d
+.byte	102,68,15,56,0,207
+	jmp	L$ccm64_enc_outer
+.p2align	4
+L$ccm64_enc_outer:
+	movups	(%r11),%xmm0
+	movl	%r10d,%eax
+	movups	(%rdi),%xmm8
+
+	xorps	%xmm0,%xmm2
+	movups	16(%r11),%xmm1
+	xorps	%xmm8,%xmm0
+	leaq	32(%r11),%rcx
+	xorps	%xmm0,%xmm3
+	movups	(%rcx),%xmm0
+
+L$ccm64_enc2_loop:
+	aesenc	%xmm1,%xmm2
+	decl	%eax
+	aesenc	%xmm1,%xmm3
+	movups	16(%rcx),%xmm1
+	aesenc	%xmm0,%xmm2
+	leaq	32(%rcx),%rcx
+	aesenc	%xmm0,%xmm3
+	movups	0(%rcx),%xmm0
+	jnz	L$ccm64_enc2_loop
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	paddq	%xmm6,%xmm9
+	aesenclast	%xmm0,%xmm2
+	aesenclast	%xmm0,%xmm3
+
+	decq	%rdx
+	leaq	16(%rdi),%rdi
+	xorps	%xmm2,%xmm8
+	movdqa	%xmm9,%xmm2
+	movups	%xmm8,(%rsi)
+	leaq	16(%rsi),%rsi
+.byte	102,15,56,0,215
+	jnz	L$ccm64_enc_outer
+
+	movups	%xmm3,(%r9)
+	.byte	0xf3,0xc3
+
+.globl	_aesni_ccm64_decrypt_blocks
+
+.p2align	4
+_aesni_ccm64_decrypt_blocks:
+	movl	240(%rcx),%eax
+	movups	(%r8),%xmm9
+	movdqu	(%r9),%xmm3
+	movdqa	L$increment64(%rip),%xmm6
+	movdqa	L$bswap_mask(%rip),%xmm7
+
+	movaps	%xmm9,%xmm2
+	movl	%eax,%r10d
+	movq	%rcx,%r11
+.byte	102,68,15,56,0,207
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+L$oop_enc1_5:
+	aesenc	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	L$oop_enc1_5	
+	aesenclast	%xmm1,%xmm2
+	movups	(%rdi),%xmm8
+	paddq	%xmm6,%xmm9
+	leaq	16(%rdi),%rdi
+	jmp	L$ccm64_dec_outer
+.p2align	4
+L$ccm64_dec_outer:
+	xorps	%xmm2,%xmm8
+	movdqa	%xmm9,%xmm2
+	movl	%r10d,%eax
+	movups	%xmm8,(%rsi)
+	leaq	16(%rsi),%rsi
+.byte	102,15,56,0,215
+
+	subq	$1,%rdx
+	jz	L$ccm64_dec_break
+
+	movups	(%r11),%xmm0
+	shrl	$1,%eax
+	movups	16(%r11),%xmm1
+	xorps	%xmm0,%xmm8
+	leaq	32(%r11),%rcx
+	xorps	%xmm0,%xmm2
+	xorps	%xmm8,%xmm3
+	movups	(%rcx),%xmm0
+
+L$ccm64_dec2_loop:
+	aesenc	%xmm1,%xmm2
+	decl	%eax
+	aesenc	%xmm1,%xmm3
+	movups	16(%rcx),%xmm1
+	aesenc	%xmm0,%xmm2
+	leaq	32(%rcx),%rcx
+	aesenc	%xmm0,%xmm3
+	movups	0(%rcx),%xmm0
+	jnz	L$ccm64_dec2_loop
+	movups	(%rdi),%xmm8
+	paddq	%xmm6,%xmm9
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	leaq	16(%rdi),%rdi
+	aesenclast	%xmm0,%xmm2
+	aesenclast	%xmm0,%xmm3
+	jmp	L$ccm64_dec_outer
+
+.p2align	4
+L$ccm64_dec_break:
+
+	movups	(%r11),%xmm0
+	movups	16(%r11),%xmm1
+	xorps	%xmm0,%xmm8
+	leaq	32(%r11),%r11
+	xorps	%xmm8,%xmm3
+L$oop_enc1_6:
+	aesenc	%xmm1,%xmm3
+	decl	%eax
+	movups	(%r11),%xmm1
+	leaq	16(%r11),%r11
+	jnz	L$oop_enc1_6	
+	aesenclast	%xmm1,%xmm3
+	movups	%xmm3,(%r9)
+	.byte	0xf3,0xc3
+
+.globl	_aesni_ctr32_encrypt_blocks
+
+.p2align	4
+_aesni_ctr32_encrypt_blocks:
+	cmpq	$1,%rdx
+	je	L$ctr32_one_shortcut
+
+	movdqu	(%r8),%xmm14
+	movdqa	L$bswap_mask(%rip),%xmm15
+	xorl	%eax,%eax
+.byte	102,69,15,58,22,242,3
+.byte	102,68,15,58,34,240,3
+
+	movl	240(%rcx),%eax
+	bswapl	%r10d
+	pxor	%xmm12,%xmm12
+	pxor	%xmm13,%xmm13
+.byte	102,69,15,58,34,226,0
+	leaq	3(%r10),%r11
+.byte	102,69,15,58,34,235,0
+	incl	%r10d
+.byte	102,69,15,58,34,226,1
+	incq	%r11
+.byte	102,69,15,58,34,235,1
+	incl	%r10d
+.byte	102,69,15,58,34,226,2
+	incq	%r11
+.byte	102,69,15,58,34,235,2
+	movdqa	%xmm12,-40(%rsp)
+.byte	102,69,15,56,0,231
+	movdqa	%xmm13,-24(%rsp)
+.byte	102,69,15,56,0,239
+
+	pshufd	$192,%xmm12,%xmm2
+	pshufd	$128,%xmm12,%xmm3
+	pshufd	$64,%xmm12,%xmm4
+	cmpq	$6,%rdx
+	jb	L$ctr32_tail
+	shrl	$1,%eax
+	movq	%rcx,%r11
+	movl	%eax,%r10d
+	subq	$6,%rdx
+	jmp	L$ctr32_loop6
+
+.p2align	4
+L$ctr32_loop6:
+	pshufd	$192,%xmm13,%xmm5
+	por	%xmm14,%xmm2
+	movups	(%r11),%xmm0
+	pshufd	$128,%xmm13,%xmm6
+	por	%xmm14,%xmm3
+	movups	16(%r11),%xmm1
+	pshufd	$64,%xmm13,%xmm7
+	por	%xmm14,%xmm4
+	por	%xmm14,%xmm5
+	xorps	%xmm0,%xmm2
+	por	%xmm14,%xmm6
+	por	%xmm14,%xmm7
+
+
+
+
+	pxor	%xmm0,%xmm3
+	aesenc	%xmm1,%xmm2
+	leaq	32(%r11),%rcx
+	pxor	%xmm0,%xmm4
+	aesenc	%xmm1,%xmm3
+	movdqa	L$increment32(%rip),%xmm13
+	pxor	%xmm0,%xmm5
+	aesenc	%xmm1,%xmm4
+	movdqa	-40(%rsp),%xmm12
+	pxor	%xmm0,%xmm6
+	aesenc	%xmm1,%xmm5
+	pxor	%xmm0,%xmm7
+	movups	(%rcx),%xmm0
+	decl	%eax
+	aesenc	%xmm1,%xmm6
+	aesenc	%xmm1,%xmm7
+	jmp	L$ctr32_enc_loop6_enter
+.p2align	4
+L$ctr32_enc_loop6:
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	decl	%eax
+	aesenc	%xmm1,%xmm4
+	aesenc	%xmm1,%xmm5
+	aesenc	%xmm1,%xmm6
+	aesenc	%xmm1,%xmm7
+L$ctr32_enc_loop6_enter:
+	movups	16(%rcx),%xmm1
+	aesenc	%xmm0,%xmm2
+	aesenc	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesenc	%xmm0,%xmm4
+	aesenc	%xmm0,%xmm5
+	aesenc	%xmm0,%xmm6
+	aesenc	%xmm0,%xmm7
+	movups	(%rcx),%xmm0
+	jnz	L$ctr32_enc_loop6
+
+	aesenc	%xmm1,%xmm2
+	paddd	%xmm13,%xmm12
+	aesenc	%xmm1,%xmm3
+	paddd	-24(%rsp),%xmm13
+	aesenc	%xmm1,%xmm4
+	movdqa	%xmm12,-40(%rsp)
+	aesenc	%xmm1,%xmm5
+	movdqa	%xmm13,-24(%rsp)
+	aesenc	%xmm1,%xmm6
+.byte	102,69,15,56,0,231
+	aesenc	%xmm1,%xmm7
+.byte	102,69,15,56,0,239
+
+	aesenclast	%xmm0,%xmm2
+	movups	(%rdi),%xmm8
+	aesenclast	%xmm0,%xmm3
+	movups	16(%rdi),%xmm9
+	aesenclast	%xmm0,%xmm4
+	movups	32(%rdi),%xmm10
+	aesenclast	%xmm0,%xmm5
+	movups	48(%rdi),%xmm11
+	aesenclast	%xmm0,%xmm6
+	movups	64(%rdi),%xmm1
+	aesenclast	%xmm0,%xmm7
+	movups	80(%rdi),%xmm0
+	leaq	96(%rdi),%rdi
+
+	xorps	%xmm2,%xmm8
+	pshufd	$192,%xmm12,%xmm2
+	xorps	%xmm3,%xmm9
+	pshufd	$128,%xmm12,%xmm3
+	movups	%xmm8,(%rsi)
+	xorps	%xmm4,%xmm10
+	pshufd	$64,%xmm12,%xmm4
+	movups	%xmm9,16(%rsi)
+	xorps	%xmm5,%xmm11
+	movups	%xmm10,32(%rsi)
+	xorps	%xmm6,%xmm1
+	movups	%xmm11,48(%rsi)
+	xorps	%xmm7,%xmm0
+	movups	%xmm1,64(%rsi)
+	movups	%xmm0,80(%rsi)
+	leaq	96(%rsi),%rsi
+	movl	%r10d,%eax
+	subq	$6,%rdx
+	jnc	L$ctr32_loop6
+
+	addq	$6,%rdx
+	jz	L$ctr32_done
+	movq	%r11,%rcx
+	leal	1(%rax,%rax,1),%eax
+
+L$ctr32_tail:
+	por	%xmm14,%xmm2
+	movups	(%rdi),%xmm8
+	cmpq	$2,%rdx
+	jb	L$ctr32_one
+
+	por	%xmm14,%xmm3
+	movups	16(%rdi),%xmm9
+	je	L$ctr32_two
+
+	pshufd	$192,%xmm13,%xmm5
+	por	%xmm14,%xmm4
+	movups	32(%rdi),%xmm10
+	cmpq	$4,%rdx
+	jb	L$ctr32_three
+
+	pshufd	$128,%xmm13,%xmm6
+	por	%xmm14,%xmm5
+	movups	48(%rdi),%xmm11
+	je	L$ctr32_four
+
+	por	%xmm14,%xmm6
+	xorps	%xmm7,%xmm7
+
+	call	_aesni_encrypt6
+
+	movups	64(%rdi),%xmm1
+	xorps	%xmm2,%xmm8
+	xorps	%xmm3,%xmm9
+	movups	%xmm8,(%rsi)
+	xorps	%xmm4,%xmm10
+	movups	%xmm9,16(%rsi)
+	xorps	%xmm5,%xmm11
+	movups	%xmm10,32(%rsi)
+	xorps	%xmm6,%xmm1
+	movups	%xmm11,48(%rsi)
+	movups	%xmm1,64(%rsi)
+	jmp	L$ctr32_done
+
+.p2align	4
+L$ctr32_one_shortcut:
+	movups	(%r8),%xmm2
+	movups	(%rdi),%xmm8
+	movl	240(%rcx),%eax
+L$ctr32_one:
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+L$oop_enc1_7:
+	aesenc	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	L$oop_enc1_7	
+	aesenclast	%xmm1,%xmm2
+	xorps	%xmm2,%xmm8
+	movups	%xmm8,(%rsi)
+	jmp	L$ctr32_done
+
+.p2align	4
+L$ctr32_two:
+	xorps	%xmm4,%xmm4
+	call	_aesni_encrypt3
+	xorps	%xmm2,%xmm8
+	xorps	%xmm3,%xmm9
+	movups	%xmm8,(%rsi)
+	movups	%xmm9,16(%rsi)
+	jmp	L$ctr32_done
+
+.p2align	4
+L$ctr32_three:
+	call	_aesni_encrypt3
+	xorps	%xmm2,%xmm8
+	xorps	%xmm3,%xmm9
+	movups	%xmm8,(%rsi)
+	xorps	%xmm4,%xmm10
+	movups	%xmm9,16(%rsi)
+	movups	%xmm10,32(%rsi)
+	jmp	L$ctr32_done
+
+.p2align	4
+L$ctr32_four:
+	call	_aesni_encrypt4
+	xorps	%xmm2,%xmm8
+	xorps	%xmm3,%xmm9
+	movups	%xmm8,(%rsi)
+	xorps	%xmm4,%xmm10
+	movups	%xmm9,16(%rsi)
+	xorps	%xmm5,%xmm11
+	movups	%xmm10,32(%rsi)
+	movups	%xmm11,48(%rsi)
+
+L$ctr32_done:
+	.byte	0xf3,0xc3
+
+.globl	_aesni_xts_encrypt
+
+.p2align	4
+_aesni_xts_encrypt:
+	leaq	-104(%rsp),%rsp
+	movups	(%r9),%xmm15
+	movl	240(%r8),%eax
+	movl	240(%rcx),%r10d
+	movups	(%r8),%xmm0
+	movups	16(%r8),%xmm1
+	leaq	32(%r8),%r8
+	xorps	%xmm0,%xmm15
+L$oop_enc1_8:
+	aesenc	%xmm1,%xmm15
+	decl	%eax
+	movups	(%r8),%xmm1
+	leaq	16(%r8),%r8
+	jnz	L$oop_enc1_8	
+	aesenclast	%xmm1,%xmm15
+	movq	%rcx,%r11
+	movl	%r10d,%eax
+	movq	%rdx,%r9
+	andq	$-16,%rdx
+
+	movdqa	L$xts_magic(%rip),%xmm8
+	pxor	%xmm14,%xmm14
+	pcmpgtd	%xmm15,%xmm14
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm10
+	paddq	%xmm15,%xmm15
+	pand	%xmm8,%xmm9
+	pcmpgtd	%xmm15,%xmm14
+	pxor	%xmm9,%xmm15
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm11
+	paddq	%xmm15,%xmm15
+	pand	%xmm8,%xmm9
+	pcmpgtd	%xmm15,%xmm14
+	pxor	%xmm9,%xmm15
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm12
+	paddq	%xmm15,%xmm15
+	pand	%xmm8,%xmm9
+	pcmpgtd	%xmm15,%xmm14
+	pxor	%xmm9,%xmm15
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm13
+	paddq	%xmm15,%xmm15
+	pand	%xmm8,%xmm9
+	pcmpgtd	%xmm15,%xmm14
+	pxor	%xmm9,%xmm15
+	subq	$96,%rdx
+	jc	L$xts_enc_short
+
+	shrl	$1,%eax
+	subl	$1,%eax
+	movl	%eax,%r10d
+	jmp	L$xts_enc_grandloop
+
+.p2align	4
+L$xts_enc_grandloop:
+	pshufd	$19,%xmm14,%xmm9
+	movdqa	%xmm15,%xmm14
+	paddq	%xmm15,%xmm15
+	movdqu	0(%rdi),%xmm2
+	pand	%xmm8,%xmm9
+	movdqu	16(%rdi),%xmm3
+	pxor	%xmm9,%xmm15
+
+	movdqu	32(%rdi),%xmm4
+	pxor	%xmm10,%xmm2
+	movdqu	48(%rdi),%xmm5
+	pxor	%xmm11,%xmm3
+	movdqu	64(%rdi),%xmm6
+	pxor	%xmm12,%xmm4
+	movdqu	80(%rdi),%xmm7
+	leaq	96(%rdi),%rdi
+	pxor	%xmm13,%xmm5
+	movups	(%r11),%xmm0
+	pxor	%xmm14,%xmm6
+	pxor	%xmm15,%xmm7
+
+
+
+	movups	16(%r11),%xmm1
+	pxor	%xmm0,%xmm2
+	pxor	%xmm0,%xmm3
+	movdqa	%xmm10,0(%rsp)
+	aesenc	%xmm1,%xmm2
+	leaq	32(%r11),%rcx
+	pxor	%xmm0,%xmm4
+	movdqa	%xmm11,16(%rsp)
+	aesenc	%xmm1,%xmm3
+	pxor	%xmm0,%xmm5
+	movdqa	%xmm12,32(%rsp)
+	aesenc	%xmm1,%xmm4
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm13,48(%rsp)
+	aesenc	%xmm1,%xmm5
+	pxor	%xmm0,%xmm7
+	movups	(%rcx),%xmm0
+	decl	%eax
+	movdqa	%xmm14,64(%rsp)
+	aesenc	%xmm1,%xmm6
+	movdqa	%xmm15,80(%rsp)
+	aesenc	%xmm1,%xmm7
+	pxor	%xmm14,%xmm14
+	pcmpgtd	%xmm15,%xmm14
+	jmp	L$xts_enc_loop6_enter
+
+.p2align	4
+L$xts_enc_loop6:
+	aesenc	%xmm1,%xmm2
+	aesenc	%xmm1,%xmm3
+	decl	%eax
+	aesenc	%xmm1,%xmm4
+	aesenc	%xmm1,%xmm5
+	aesenc	%xmm1,%xmm6
+	aesenc	%xmm1,%xmm7
+L$xts_enc_loop6_enter:
+	movups	16(%rcx),%xmm1
+	aesenc	%xmm0,%xmm2
+	aesenc	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesenc	%xmm0,%xmm4
+	aesenc	%xmm0,%xmm5
+	aesenc	%xmm0,%xmm6
+	aesenc	%xmm0,%xmm7
+	movups	(%rcx),%xmm0
+	jnz	L$xts_enc_loop6
+
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	paddq	%xmm15,%xmm15
+	aesenc	%xmm1,%xmm2
+	pand	%xmm8,%xmm9
+	aesenc	%xmm1,%xmm3
+	pcmpgtd	%xmm15,%xmm14
+	aesenc	%xmm1,%xmm4
+	pxor	%xmm9,%xmm15
+	aesenc	%xmm1,%xmm5
+	aesenc	%xmm1,%xmm6
+	aesenc	%xmm1,%xmm7
+	movups	16(%rcx),%xmm1
+
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm10
+	paddq	%xmm15,%xmm15
+	aesenc	%xmm0,%xmm2
+	pand	%xmm8,%xmm9
+	aesenc	%xmm0,%xmm3
+	pcmpgtd	%xmm15,%xmm14
+	aesenc	%xmm0,%xmm4
+	pxor	%xmm9,%xmm15
+	aesenc	%xmm0,%xmm5
+	aesenc	%xmm0,%xmm6
+	aesenc	%xmm0,%xmm7
+	movups	32(%rcx),%xmm0
+
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm11
+	paddq	%xmm15,%xmm15
+	aesenc	%xmm1,%xmm2
+	pand	%xmm8,%xmm9
+	aesenc	%xmm1,%xmm3
+	pcmpgtd	%xmm15,%xmm14
+	aesenc	%xmm1,%xmm4
+	pxor	%xmm9,%xmm15
+	aesenc	%xmm1,%xmm5
+	aesenc	%xmm1,%xmm6
+	aesenc	%xmm1,%xmm7
+
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm12
+	paddq	%xmm15,%xmm15
+	aesenclast	%xmm0,%xmm2
+	pand	%xmm8,%xmm9
+	aesenclast	%xmm0,%xmm3
+	pcmpgtd	%xmm15,%xmm14
+	aesenclast	%xmm0,%xmm4
+	pxor	%xmm9,%xmm15
+	aesenclast	%xmm0,%xmm5
+	aesenclast	%xmm0,%xmm6
+	aesenclast	%xmm0,%xmm7
+
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm13
+	paddq	%xmm15,%xmm15
+	xorps	0(%rsp),%xmm2
+	pand	%xmm8,%xmm9
+	xorps	16(%rsp),%xmm3
+	pcmpgtd	%xmm15,%xmm14
+	pxor	%xmm9,%xmm15
+
+	xorps	32(%rsp),%xmm4
+	movups	%xmm2,0(%rsi)
+	xorps	48(%rsp),%xmm5
+	movups	%xmm3,16(%rsi)
+	xorps	64(%rsp),%xmm6
+	movups	%xmm4,32(%rsi)
+	xorps	80(%rsp),%xmm7
+	movups	%xmm5,48(%rsi)
+	movl	%r10d,%eax
+	movups	%xmm6,64(%rsi)
+	movups	%xmm7,80(%rsi)
+	leaq	96(%rsi),%rsi
+	subq	$96,%rdx
+	jnc	L$xts_enc_grandloop
+
+	leal	3(%rax,%rax,1),%eax
+	movq	%r11,%rcx
+	movl	%eax,%r10d
+
+L$xts_enc_short:
+	addq	$96,%rdx
+	jz	L$xts_enc_done
+
+	cmpq	$32,%rdx
+	jb	L$xts_enc_one
+	je	L$xts_enc_two
+
+	cmpq	$64,%rdx
+	jb	L$xts_enc_three
+	je	L$xts_enc_four
+
+	pshufd	$19,%xmm14,%xmm9
+	movdqa	%xmm15,%xmm14
+	paddq	%xmm15,%xmm15
+	movdqu	(%rdi),%xmm2
+	pand	%xmm8,%xmm9
+	movdqu	16(%rdi),%xmm3
+	pxor	%xmm9,%xmm15
+
+	movdqu	32(%rdi),%xmm4
+	pxor	%xmm10,%xmm2
+	movdqu	48(%rdi),%xmm5
+	pxor	%xmm11,%xmm3
+	movdqu	64(%rdi),%xmm6
+	leaq	80(%rdi),%rdi
+	pxor	%xmm12,%xmm4
+	pxor	%xmm13,%xmm5
+	pxor	%xmm14,%xmm6
+
+	call	_aesni_encrypt6
+
+	xorps	%xmm10,%xmm2
+	movdqa	%xmm15,%xmm10
+	xorps	%xmm11,%xmm3
+	xorps	%xmm12,%xmm4
+	movdqu	%xmm2,(%rsi)
+	xorps	%xmm13,%xmm5
+	movdqu	%xmm3,16(%rsi)
+	xorps	%xmm14,%xmm6
+	movdqu	%xmm4,32(%rsi)
+	movdqu	%xmm5,48(%rsi)
+	movdqu	%xmm6,64(%rsi)
+	leaq	80(%rsi),%rsi
+	jmp	L$xts_enc_done
+
+.p2align	4
+L$xts_enc_one:
+	movups	(%rdi),%xmm2
+	leaq	16(%rdi),%rdi
+	xorps	%xmm10,%xmm2
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+L$oop_enc1_9:
+	aesenc	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	L$oop_enc1_9	
+	aesenclast	%xmm1,%xmm2
+	xorps	%xmm10,%xmm2
+	movdqa	%xmm11,%xmm10
+	movups	%xmm2,(%rsi)
+	leaq	16(%rsi),%rsi
+	jmp	L$xts_enc_done
+
+.p2align	4
+L$xts_enc_two:
+	movups	(%rdi),%xmm2
+	movups	16(%rdi),%xmm3
+	leaq	32(%rdi),%rdi
+	xorps	%xmm10,%xmm2
+	xorps	%xmm11,%xmm3
+
+	call	_aesni_encrypt3
+
+	xorps	%xmm10,%xmm2
+	movdqa	%xmm12,%xmm10
+	xorps	%xmm11,%xmm3
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	leaq	32(%rsi),%rsi
+	jmp	L$xts_enc_done
+
+.p2align	4
+L$xts_enc_three:
+	movups	(%rdi),%xmm2
+	movups	16(%rdi),%xmm3
+	movups	32(%rdi),%xmm4
+	leaq	48(%rdi),%rdi
+	xorps	%xmm10,%xmm2
+	xorps	%xmm11,%xmm3
+	xorps	%xmm12,%xmm4
+
+	call	_aesni_encrypt3
+
+	xorps	%xmm10,%xmm2
+	movdqa	%xmm13,%xmm10
+	xorps	%xmm11,%xmm3
+	xorps	%xmm12,%xmm4
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	leaq	48(%rsi),%rsi
+	jmp	L$xts_enc_done
+
+.p2align	4
+L$xts_enc_four:
+	movups	(%rdi),%xmm2
+	movups	16(%rdi),%xmm3
+	movups	32(%rdi),%xmm4
+	xorps	%xmm10,%xmm2
+	movups	48(%rdi),%xmm5
+	leaq	64(%rdi),%rdi
+	xorps	%xmm11,%xmm3
+	xorps	%xmm12,%xmm4
+	xorps	%xmm13,%xmm5
+
+	call	_aesni_encrypt4
+
+	xorps	%xmm10,%xmm2
+	movdqa	%xmm15,%xmm10
+	xorps	%xmm11,%xmm3
+	xorps	%xmm12,%xmm4
+	movups	%xmm2,(%rsi)
+	xorps	%xmm13,%xmm5
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	leaq	64(%rsi),%rsi
+	jmp	L$xts_enc_done
+
+.p2align	4
+L$xts_enc_done:
+	andq	$15,%r9
+	jz	L$xts_enc_ret
+	movq	%r9,%rdx
+
+L$xts_enc_steal:
+	movzbl	(%rdi),%eax
+	movzbl	-16(%rsi),%ecx
+	leaq	1(%rdi),%rdi
+	movb	%al,-16(%rsi)
+	movb	%cl,0(%rsi)
+	leaq	1(%rsi),%rsi
+	subq	$1,%rdx
+	jnz	L$xts_enc_steal
+
+	subq	%r9,%rsi
+	movq	%r11,%rcx
+	movl	%r10d,%eax
+
+	movups	-16(%rsi),%xmm2
+	xorps	%xmm10,%xmm2
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+L$oop_enc1_10:
+	aesenc	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	L$oop_enc1_10	
+	aesenclast	%xmm1,%xmm2
+	xorps	%xmm10,%xmm2
+	movups	%xmm2,-16(%rsi)
+
+L$xts_enc_ret:
+	leaq	104(%rsp),%rsp
+L$xts_enc_epilogue:
+	.byte	0xf3,0xc3
+
+.globl	_aesni_xts_decrypt
+
+.p2align	4
+_aesni_xts_decrypt:
+	leaq	-104(%rsp),%rsp
+	movups	(%r9),%xmm15
+	movl	240(%r8),%eax
+	movl	240(%rcx),%r10d
+	movups	(%r8),%xmm0
+	movups	16(%r8),%xmm1
+	leaq	32(%r8),%r8
+	xorps	%xmm0,%xmm15
+L$oop_enc1_11:
+	aesenc	%xmm1,%xmm15
+	decl	%eax
+	movups	(%r8),%xmm1
+	leaq	16(%r8),%r8
+	jnz	L$oop_enc1_11	
+	aesenclast	%xmm1,%xmm15
+	xorl	%eax,%eax
+	testq	$15,%rdx
+	setnz	%al
+	shlq	$4,%rax
+	subq	%rax,%rdx
+
+	movq	%rcx,%r11
+	movl	%r10d,%eax
+	movq	%rdx,%r9
+	andq	$-16,%rdx
+
+	movdqa	L$xts_magic(%rip),%xmm8
+	pxor	%xmm14,%xmm14
+	pcmpgtd	%xmm15,%xmm14
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm10
+	paddq	%xmm15,%xmm15
+	pand	%xmm8,%xmm9
+	pcmpgtd	%xmm15,%xmm14
+	pxor	%xmm9,%xmm15
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm11
+	paddq	%xmm15,%xmm15
+	pand	%xmm8,%xmm9
+	pcmpgtd	%xmm15,%xmm14
+	pxor	%xmm9,%xmm15
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm12
+	paddq	%xmm15,%xmm15
+	pand	%xmm8,%xmm9
+	pcmpgtd	%xmm15,%xmm14
+	pxor	%xmm9,%xmm15
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm13
+	paddq	%xmm15,%xmm15
+	pand	%xmm8,%xmm9
+	pcmpgtd	%xmm15,%xmm14
+	pxor	%xmm9,%xmm15
+	subq	$96,%rdx
+	jc	L$xts_dec_short
+
+	shrl	$1,%eax
+	subl	$1,%eax
+	movl	%eax,%r10d
+	jmp	L$xts_dec_grandloop
+
+.p2align	4
+L$xts_dec_grandloop:
+	pshufd	$19,%xmm14,%xmm9
+	movdqa	%xmm15,%xmm14
+	paddq	%xmm15,%xmm15
+	movdqu	0(%rdi),%xmm2
+	pand	%xmm8,%xmm9
+	movdqu	16(%rdi),%xmm3
+	pxor	%xmm9,%xmm15
+
+	movdqu	32(%rdi),%xmm4
+	pxor	%xmm10,%xmm2
+	movdqu	48(%rdi),%xmm5
+	pxor	%xmm11,%xmm3
+	movdqu	64(%rdi),%xmm6
+	pxor	%xmm12,%xmm4
+	movdqu	80(%rdi),%xmm7
+	leaq	96(%rdi),%rdi
+	pxor	%xmm13,%xmm5
+	movups	(%r11),%xmm0
+	pxor	%xmm14,%xmm6
+	pxor	%xmm15,%xmm7
+
+
+
+	movups	16(%r11),%xmm1
+	pxor	%xmm0,%xmm2
+	pxor	%xmm0,%xmm3
+	movdqa	%xmm10,0(%rsp)
+	aesdec	%xmm1,%xmm2
+	leaq	32(%r11),%rcx
+	pxor	%xmm0,%xmm4
+	movdqa	%xmm11,16(%rsp)
+	aesdec	%xmm1,%xmm3
+	pxor	%xmm0,%xmm5
+	movdqa	%xmm12,32(%rsp)
+	aesdec	%xmm1,%xmm4
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm13,48(%rsp)
+	aesdec	%xmm1,%xmm5
+	pxor	%xmm0,%xmm7
+	movups	(%rcx),%xmm0
+	decl	%eax
+	movdqa	%xmm14,64(%rsp)
+	aesdec	%xmm1,%xmm6
+	movdqa	%xmm15,80(%rsp)
+	aesdec	%xmm1,%xmm7
+	pxor	%xmm14,%xmm14
+	pcmpgtd	%xmm15,%xmm14
+	jmp	L$xts_dec_loop6_enter
+
+.p2align	4
+L$xts_dec_loop6:
+	aesdec	%xmm1,%xmm2
+	aesdec	%xmm1,%xmm3
+	decl	%eax
+	aesdec	%xmm1,%xmm4
+	aesdec	%xmm1,%xmm5
+	aesdec	%xmm1,%xmm6
+	aesdec	%xmm1,%xmm7
+L$xts_dec_loop6_enter:
+	movups	16(%rcx),%xmm1
+	aesdec	%xmm0,%xmm2
+	aesdec	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	aesdec	%xmm0,%xmm4
+	aesdec	%xmm0,%xmm5
+	aesdec	%xmm0,%xmm6
+	aesdec	%xmm0,%xmm7
+	movups	(%rcx),%xmm0
+	jnz	L$xts_dec_loop6
+
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	paddq	%xmm15,%xmm15
+	aesdec	%xmm1,%xmm2
+	pand	%xmm8,%xmm9
+	aesdec	%xmm1,%xmm3
+	pcmpgtd	%xmm15,%xmm14
+	aesdec	%xmm1,%xmm4
+	pxor	%xmm9,%xmm15
+	aesdec	%xmm1,%xmm5
+	aesdec	%xmm1,%xmm6
+	aesdec	%xmm1,%xmm7
+	movups	16(%rcx),%xmm1
+
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm10
+	paddq	%xmm15,%xmm15
+	aesdec	%xmm0,%xmm2
+	pand	%xmm8,%xmm9
+	aesdec	%xmm0,%xmm3
+	pcmpgtd	%xmm15,%xmm14
+	aesdec	%xmm0,%xmm4
+	pxor	%xmm9,%xmm15
+	aesdec	%xmm0,%xmm5
+	aesdec	%xmm0,%xmm6
+	aesdec	%xmm0,%xmm7
+	movups	32(%rcx),%xmm0
+
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm11
+	paddq	%xmm15,%xmm15
+	aesdec	%xmm1,%xmm2
+	pand	%xmm8,%xmm9
+	aesdec	%xmm1,%xmm3
+	pcmpgtd	%xmm15,%xmm14
+	aesdec	%xmm1,%xmm4
+	pxor	%xmm9,%xmm15
+	aesdec	%xmm1,%xmm5
+	aesdec	%xmm1,%xmm6
+	aesdec	%xmm1,%xmm7
+
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm12
+	paddq	%xmm15,%xmm15
+	aesdeclast	%xmm0,%xmm2
+	pand	%xmm8,%xmm9
+	aesdeclast	%xmm0,%xmm3
+	pcmpgtd	%xmm15,%xmm14
+	aesdeclast	%xmm0,%xmm4
+	pxor	%xmm9,%xmm15
+	aesdeclast	%xmm0,%xmm5
+	aesdeclast	%xmm0,%xmm6
+	aesdeclast	%xmm0,%xmm7
+
+	pshufd	$19,%xmm14,%xmm9
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm15,%xmm13
+	paddq	%xmm15,%xmm15
+	xorps	0(%rsp),%xmm2
+	pand	%xmm8,%xmm9
+	xorps	16(%rsp),%xmm3
+	pcmpgtd	%xmm15,%xmm14
+	pxor	%xmm9,%xmm15
+
+	xorps	32(%rsp),%xmm4
+	movups	%xmm2,0(%rsi)
+	xorps	48(%rsp),%xmm5
+	movups	%xmm3,16(%rsi)
+	xorps	64(%rsp),%xmm6
+	movups	%xmm4,32(%rsi)
+	xorps	80(%rsp),%xmm7
+	movups	%xmm5,48(%rsi)
+	movl	%r10d,%eax
+	movups	%xmm6,64(%rsi)
+	movups	%xmm7,80(%rsi)
+	leaq	96(%rsi),%rsi
+	subq	$96,%rdx
+	jnc	L$xts_dec_grandloop
+
+	leal	3(%rax,%rax,1),%eax
+	movq	%r11,%rcx
+	movl	%eax,%r10d
+
+L$xts_dec_short:
+	addq	$96,%rdx
+	jz	L$xts_dec_done
+
+	cmpq	$32,%rdx
+	jb	L$xts_dec_one
+	je	L$xts_dec_two
+
+	cmpq	$64,%rdx
+	jb	L$xts_dec_three
+	je	L$xts_dec_four
+
+	pshufd	$19,%xmm14,%xmm9
+	movdqa	%xmm15,%xmm14
+	paddq	%xmm15,%xmm15
+	movdqu	(%rdi),%xmm2
+	pand	%xmm8,%xmm9
+	movdqu	16(%rdi),%xmm3
+	pxor	%xmm9,%xmm15
+
+	movdqu	32(%rdi),%xmm4
+	pxor	%xmm10,%xmm2
+	movdqu	48(%rdi),%xmm5
+	pxor	%xmm11,%xmm3
+	movdqu	64(%rdi),%xmm6
+	leaq	80(%rdi),%rdi
+	pxor	%xmm12,%xmm4
+	pxor	%xmm13,%xmm5
+	pxor	%xmm14,%xmm6
+
+	call	_aesni_decrypt6
+
+	xorps	%xmm10,%xmm2
+	xorps	%xmm11,%xmm3
+	xorps	%xmm12,%xmm4
+	movdqu	%xmm2,(%rsi)
+	xorps	%xmm13,%xmm5
+	movdqu	%xmm3,16(%rsi)
+	xorps	%xmm14,%xmm6
+	movdqu	%xmm4,32(%rsi)
+	pxor	%xmm14,%xmm14
+	movdqu	%xmm5,48(%rsi)
+	pcmpgtd	%xmm15,%xmm14
+	movdqu	%xmm6,64(%rsi)
+	leaq	80(%rsi),%rsi
+	pshufd	$19,%xmm14,%xmm11
+	andq	$15,%r9
+	jz	L$xts_dec_ret
+
+	movdqa	%xmm15,%xmm10
+	paddq	%xmm15,%xmm15
+	pand	%xmm8,%xmm11
+	pxor	%xmm15,%xmm11
+	jmp	L$xts_dec_done2
+
+.p2align	4
+L$xts_dec_one:
+	movups	(%rdi),%xmm2
+	leaq	16(%rdi),%rdi
+	xorps	%xmm10,%xmm2
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+L$oop_dec1_12:
+	aesdec	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	L$oop_dec1_12	
+	aesdeclast	%xmm1,%xmm2
+	xorps	%xmm10,%xmm2
+	movdqa	%xmm11,%xmm10
+	movups	%xmm2,(%rsi)
+	movdqa	%xmm12,%xmm11
+	leaq	16(%rsi),%rsi
+	jmp	L$xts_dec_done
+
+.p2align	4
+L$xts_dec_two:
+	movups	(%rdi),%xmm2
+	movups	16(%rdi),%xmm3
+	leaq	32(%rdi),%rdi
+	xorps	%xmm10,%xmm2
+	xorps	%xmm11,%xmm3
+
+	call	_aesni_decrypt3
+
+	xorps	%xmm10,%xmm2
+	movdqa	%xmm12,%xmm10
+	xorps	%xmm11,%xmm3
+	movdqa	%xmm13,%xmm11
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	leaq	32(%rsi),%rsi
+	jmp	L$xts_dec_done
+
+.p2align	4
+L$xts_dec_three:
+	movups	(%rdi),%xmm2
+	movups	16(%rdi),%xmm3
+	movups	32(%rdi),%xmm4
+	leaq	48(%rdi),%rdi
+	xorps	%xmm10,%xmm2
+	xorps	%xmm11,%xmm3
+	xorps	%xmm12,%xmm4
+
+	call	_aesni_decrypt3
+
+	xorps	%xmm10,%xmm2
+	movdqa	%xmm13,%xmm10
+	xorps	%xmm11,%xmm3
+	movdqa	%xmm15,%xmm11
+	xorps	%xmm12,%xmm4
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	leaq	48(%rsi),%rsi
+	jmp	L$xts_dec_done
+
+.p2align	4
+L$xts_dec_four:
+	pshufd	$19,%xmm14,%xmm9
+	movdqa	%xmm15,%xmm14
+	paddq	%xmm15,%xmm15
+	movups	(%rdi),%xmm2
+	pand	%xmm8,%xmm9
+	movups	16(%rdi),%xmm3
+	pxor	%xmm9,%xmm15
+
+	movups	32(%rdi),%xmm4
+	xorps	%xmm10,%xmm2
+	movups	48(%rdi),%xmm5
+	leaq	64(%rdi),%rdi
+	xorps	%xmm11,%xmm3
+	xorps	%xmm12,%xmm4
+	xorps	%xmm13,%xmm5
+
+	call	_aesni_decrypt4
+
+	xorps	%xmm10,%xmm2
+	movdqa	%xmm14,%xmm10
+	xorps	%xmm11,%xmm3
+	movdqa	%xmm15,%xmm11
+	xorps	%xmm12,%xmm4
+	movups	%xmm2,(%rsi)
+	xorps	%xmm13,%xmm5
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	leaq	64(%rsi),%rsi
+	jmp	L$xts_dec_done
+
+.p2align	4
+L$xts_dec_done:
+	andq	$15,%r9
+	jz	L$xts_dec_ret
+L$xts_dec_done2:
+	movq	%r9,%rdx
+	movq	%r11,%rcx
+	movl	%r10d,%eax
+
+	movups	(%rdi),%xmm2
+	xorps	%xmm11,%xmm2
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+L$oop_dec1_13:
+	aesdec	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	L$oop_dec1_13	
+	aesdeclast	%xmm1,%xmm2
+	xorps	%xmm11,%xmm2
+	movups	%xmm2,(%rsi)
+
+L$xts_dec_steal:
+	movzbl	16(%rdi),%eax
+	movzbl	(%rsi),%ecx
+	leaq	1(%rdi),%rdi
+	movb	%al,(%rsi)
+	movb	%cl,16(%rsi)
+	leaq	1(%rsi),%rsi
+	subq	$1,%rdx
+	jnz	L$xts_dec_steal
+
+	subq	%r9,%rsi
+	movq	%r11,%rcx
+	movl	%r10d,%eax
+
+	movups	(%rsi),%xmm2
+	xorps	%xmm10,%xmm2
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+L$oop_dec1_14:
+	aesdec	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	L$oop_dec1_14	
+	aesdeclast	%xmm1,%xmm2
+	xorps	%xmm10,%xmm2
+	movups	%xmm2,(%rsi)
+
+L$xts_dec_ret:
+	leaq	104(%rsp),%rsp
+L$xts_dec_epilogue:
+	.byte	0xf3,0xc3
+
+.globl	_aesni_cbc_encrypt
+
+.p2align	4
+_aesni_cbc_encrypt:
+	testq	%rdx,%rdx
+	jz	L$cbc_ret
+
+	movl	240(%rcx),%r10d
+	movq	%rcx,%r11
+	testl	%r9d,%r9d
+	jz	L$cbc_decrypt
+
+	movups	(%r8),%xmm2
+	movl	%r10d,%eax
+	cmpq	$16,%rdx
+	jb	L$cbc_enc_tail
+	subq	$16,%rdx
+	jmp	L$cbc_enc_loop
+.p2align	4
+L$cbc_enc_loop:
+	movups	(%rdi),%xmm3
+	leaq	16(%rdi),%rdi
+
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	xorps	%xmm0,%xmm3
+	leaq	32(%rcx),%rcx
+	xorps	%xmm3,%xmm2
+L$oop_enc1_15:
+	aesenc	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	L$oop_enc1_15	
+	aesenclast	%xmm1,%xmm2
+	movl	%r10d,%eax
+	movq	%r11,%rcx
+	movups	%xmm2,0(%rsi)
+	leaq	16(%rsi),%rsi
+	subq	$16,%rdx
+	jnc	L$cbc_enc_loop
+	addq	$16,%rdx
+	jnz	L$cbc_enc_tail
+	movups	%xmm2,(%r8)
+	jmp	L$cbc_ret
+
+L$cbc_enc_tail:
+	movq	%rdx,%rcx
+	xchgq	%rdi,%rsi
+.long	0x9066A4F3	
+	movl	$16,%ecx
+	subq	%rdx,%rcx
+	xorl	%eax,%eax
+.long	0x9066AAF3	
+	leaq	-16(%rdi),%rdi
+	movl	%r10d,%eax
+	movq	%rdi,%rsi
+	movq	%r11,%rcx
+	xorq	%rdx,%rdx
+	jmp	L$cbc_enc_loop	
+
+.p2align	4
+L$cbc_decrypt:
+	movups	(%r8),%xmm9
+	movl	%r10d,%eax
+	cmpq	$112,%rdx
+	jbe	L$cbc_dec_tail
+	shrl	$1,%r10d
+	subq	$112,%rdx
+	movl	%r10d,%eax
+	movaps	%xmm9,-24(%rsp)
+	jmp	L$cbc_dec_loop8_enter
+.p2align	4
+L$cbc_dec_loop8:
+	movaps	%xmm0,-24(%rsp)
+	movups	%xmm9,(%rsi)
+	leaq	16(%rsi),%rsi
+L$cbc_dec_loop8_enter:
+	movups	(%rcx),%xmm0
+	movups	(%rdi),%xmm2
+	movups	16(%rdi),%xmm3
+	movups	16(%rcx),%xmm1
+
+	leaq	32(%rcx),%rcx
+	movdqu	32(%rdi),%xmm4
+	xorps	%xmm0,%xmm2
+	movdqu	48(%rdi),%xmm5
+	xorps	%xmm0,%xmm3
+	movdqu	64(%rdi),%xmm6
+	aesdec	%xmm1,%xmm2
+	pxor	%xmm0,%xmm4
+	movdqu	80(%rdi),%xmm7
+	aesdec	%xmm1,%xmm3
+	pxor	%xmm0,%xmm5
+	movdqu	96(%rdi),%xmm8
+	aesdec	%xmm1,%xmm4
+	pxor	%xmm0,%xmm6
+	movdqu	112(%rdi),%xmm9
+	aesdec	%xmm1,%xmm5
+	pxor	%xmm0,%xmm7
+	decl	%eax
+	aesdec	%xmm1,%xmm6
+	pxor	%xmm0,%xmm8
+	aesdec	%xmm1,%xmm7
+	pxor	%xmm0,%xmm9
+	movups	(%rcx),%xmm0
+	aesdec	%xmm1,%xmm8
+	aesdec	%xmm1,%xmm9
+	movups	16(%rcx),%xmm1
+
+	call	L$dec_loop8_enter
+
+	movups	(%rdi),%xmm1
+	movups	16(%rdi),%xmm0
+	xorps	-24(%rsp),%xmm2
+	xorps	%xmm1,%xmm3
+	movups	32(%rdi),%xmm1
+	xorps	%xmm0,%xmm4
+	movups	48(%rdi),%xmm0
+	xorps	%xmm1,%xmm5
+	movups	64(%rdi),%xmm1
+	xorps	%xmm0,%xmm6
+	movups	80(%rdi),%xmm0
+	xorps	%xmm1,%xmm7
+	movups	96(%rdi),%xmm1
+	xorps	%xmm0,%xmm8
+	movups	112(%rdi),%xmm0
+	xorps	%xmm1,%xmm9
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movl	%r10d,%eax
+	movups	%xmm6,64(%rsi)
+	movq	%r11,%rcx
+	movups	%xmm7,80(%rsi)
+	leaq	128(%rdi),%rdi
+	movups	%xmm8,96(%rsi)
+	leaq	112(%rsi),%rsi
+	subq	$128,%rdx
+	ja	L$cbc_dec_loop8
+
+	movaps	%xmm9,%xmm2
+	movaps	%xmm0,%xmm9
+	addq	$112,%rdx
+	jle	L$cbc_dec_tail_collected
+	movups	%xmm2,(%rsi)
+	leal	1(%r10,%r10,1),%eax
+	leaq	16(%rsi),%rsi
+L$cbc_dec_tail:
+	movups	(%rdi),%xmm2
+	movaps	%xmm2,%xmm8
+	cmpq	$16,%rdx
+	jbe	L$cbc_dec_one
+
+	movups	16(%rdi),%xmm3
+	movaps	%xmm3,%xmm7
+	cmpq	$32,%rdx
+	jbe	L$cbc_dec_two
+
+	movups	32(%rdi),%xmm4
+	movaps	%xmm4,%xmm6
+	cmpq	$48,%rdx
+	jbe	L$cbc_dec_three
+
+	movups	48(%rdi),%xmm5
+	cmpq	$64,%rdx
+	jbe	L$cbc_dec_four
+
+	movups	64(%rdi),%xmm6
+	cmpq	$80,%rdx
+	jbe	L$cbc_dec_five
+
+	movups	80(%rdi),%xmm7
+	cmpq	$96,%rdx
+	jbe	L$cbc_dec_six
+
+	movups	96(%rdi),%xmm8
+	movaps	%xmm9,-24(%rsp)
+	call	_aesni_decrypt8
+	movups	(%rdi),%xmm1
+	movups	16(%rdi),%xmm0
+	xorps	-24(%rsp),%xmm2
+	xorps	%xmm1,%xmm3
+	movups	32(%rdi),%xmm1
+	xorps	%xmm0,%xmm4
+	movups	48(%rdi),%xmm0
+	xorps	%xmm1,%xmm5
+	movups	64(%rdi),%xmm1
+	xorps	%xmm0,%xmm6
+	movups	80(%rdi),%xmm0
+	xorps	%xmm1,%xmm7
+	movups	96(%rdi),%xmm9
+	xorps	%xmm0,%xmm8
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movups	%xmm6,64(%rsi)
+	movups	%xmm7,80(%rsi)
+	leaq	96(%rsi),%rsi
+	movaps	%xmm8,%xmm2
+	subq	$112,%rdx
+	jmp	L$cbc_dec_tail_collected
+.p2align	4
+L$cbc_dec_one:
+	movups	(%rcx),%xmm0
+	movups	16(%rcx),%xmm1
+	leaq	32(%rcx),%rcx
+	xorps	%xmm0,%xmm2
+L$oop_dec1_16:
+	aesdec	%xmm1,%xmm2
+	decl	%eax
+	movups	(%rcx),%xmm1
+	leaq	16(%rcx),%rcx
+	jnz	L$oop_dec1_16	
+	aesdeclast	%xmm1,%xmm2
+	xorps	%xmm9,%xmm2
+	movaps	%xmm8,%xmm9
+	subq	$16,%rdx
+	jmp	L$cbc_dec_tail_collected
+.p2align	4
+L$cbc_dec_two:
+	xorps	%xmm4,%xmm4
+	call	_aesni_decrypt3
+	xorps	%xmm9,%xmm2
+	xorps	%xmm8,%xmm3
+	movups	%xmm2,(%rsi)
+	movaps	%xmm7,%xmm9
+	movaps	%xmm3,%xmm2
+	leaq	16(%rsi),%rsi
+	subq	$32,%rdx
+	jmp	L$cbc_dec_tail_collected
+.p2align	4
+L$cbc_dec_three:
+	call	_aesni_decrypt3
+	xorps	%xmm9,%xmm2
+	xorps	%xmm8,%xmm3
+	movups	%xmm2,(%rsi)
+	xorps	%xmm7,%xmm4
+	movups	%xmm3,16(%rsi)
+	movaps	%xmm6,%xmm9
+	movaps	%xmm4,%xmm2
+	leaq	32(%rsi),%rsi
+	subq	$48,%rdx
+	jmp	L$cbc_dec_tail_collected
+.p2align	4
+L$cbc_dec_four:
+	call	_aesni_decrypt4
+	xorps	%xmm9,%xmm2
+	movups	48(%rdi),%xmm9
+	xorps	%xmm8,%xmm3
+	movups	%xmm2,(%rsi)
+	xorps	%xmm7,%xmm4
+	movups	%xmm3,16(%rsi)
+	xorps	%xmm6,%xmm5
+	movups	%xmm4,32(%rsi)
+	movaps	%xmm5,%xmm2
+	leaq	48(%rsi),%rsi
+	subq	$64,%rdx
+	jmp	L$cbc_dec_tail_collected
+.p2align	4
+L$cbc_dec_five:
+	xorps	%xmm7,%xmm7
+	call	_aesni_decrypt6
+	movups	16(%rdi),%xmm1
+	movups	32(%rdi),%xmm0
+	xorps	%xmm9,%xmm2
+	xorps	%xmm8,%xmm3
+	xorps	%xmm1,%xmm4
+	movups	48(%rdi),%xmm1
+	xorps	%xmm0,%xmm5
+	movups	64(%rdi),%xmm9
+	xorps	%xmm1,%xmm6
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	leaq	64(%rsi),%rsi
+	movaps	%xmm6,%xmm2
+	subq	$80,%rdx
+	jmp	L$cbc_dec_tail_collected
+.p2align	4
+L$cbc_dec_six:
+	call	_aesni_decrypt6
+	movups	16(%rdi),%xmm1
+	movups	32(%rdi),%xmm0
+	xorps	%xmm9,%xmm2
+	xorps	%xmm8,%xmm3
+	xorps	%xmm1,%xmm4
+	movups	48(%rdi),%xmm1
+	xorps	%xmm0,%xmm5
+	movups	64(%rdi),%xmm0
+	xorps	%xmm1,%xmm6
+	movups	80(%rdi),%xmm9
+	xorps	%xmm0,%xmm7
+	movups	%xmm2,(%rsi)
+	movups	%xmm3,16(%rsi)
+	movups	%xmm4,32(%rsi)
+	movups	%xmm5,48(%rsi)
+	movups	%xmm6,64(%rsi)
+	leaq	80(%rsi),%rsi
+	movaps	%xmm7,%xmm2
+	subq	$96,%rdx
+	jmp	L$cbc_dec_tail_collected
+.p2align	4
+L$cbc_dec_tail_collected:
+	andq	$15,%rdx
+	movups	%xmm9,(%r8)
+	jnz	L$cbc_dec_tail_partial
+	movups	%xmm2,(%rsi)
+	jmp	L$cbc_dec_ret
+.p2align	4
+L$cbc_dec_tail_partial:
+	movaps	%xmm2,-24(%rsp)
+	movq	$16,%rcx
+	movq	%rsi,%rdi
+	subq	%rdx,%rcx
+	leaq	-24(%rsp),%rsi
+.long	0x9066A4F3	
+
+L$cbc_dec_ret:
+L$cbc_ret:
+	.byte	0xf3,0xc3
+
+.globl	_aesni_set_decrypt_key
+
+.p2align	4
+_aesni_set_decrypt_key:
+	subq	$8,%rsp
+	call	__aesni_set_encrypt_key
+	shll	$4,%esi
+	testl	%eax,%eax
+	jnz	L$dec_key_ret
+	leaq	16(%rdx,%rsi,1),%rdi
+
+	movups	(%rdx),%xmm0
+	movups	(%rdi),%xmm1
+	movups	%xmm0,(%rdi)
+	movups	%xmm1,(%rdx)
+	leaq	16(%rdx),%rdx
+	leaq	-16(%rdi),%rdi
+
+L$dec_key_inverse:
+	movups	(%rdx),%xmm0
+	movups	(%rdi),%xmm1
+	aesimc	%xmm0,%xmm0
+	aesimc	%xmm1,%xmm1
+	leaq	16(%rdx),%rdx
+	leaq	-16(%rdi),%rdi
+	movups	%xmm0,16(%rdi)
+	movups	%xmm1,-16(%rdx)
+	cmpq	%rdx,%rdi
+	ja	L$dec_key_inverse
+
+	movups	(%rdx),%xmm0
+	aesimc	%xmm0,%xmm0
+	movups	%xmm0,(%rdi)
+L$dec_key_ret:
+	addq	$8,%rsp
+	.byte	0xf3,0xc3
+L$SEH_end_set_decrypt_key:
+
+.globl	_aesni_set_encrypt_key
+
+.p2align	4
+_aesni_set_encrypt_key:
+__aesni_set_encrypt_key:
+	subq	$8,%rsp
+	movq	$-1,%rax
+	testq	%rdi,%rdi
+	jz	L$enc_key_ret
+	testq	%rdx,%rdx
+	jz	L$enc_key_ret
+
+	movups	(%rdi),%xmm0
+	xorps	%xmm4,%xmm4
+	leaq	16(%rdx),%rax
+	cmpl	$256,%esi
+	je	L$14rounds
+	cmpl	$192,%esi
+	je	L$12rounds
+	cmpl	$128,%esi
+	jne	L$bad_keybits
+
+L$10rounds:
+	movl	$9,%esi
+	movups	%xmm0,(%rdx)
+	aeskeygenassist	$1,%xmm0,%xmm1
+	call	L$key_expansion_128_cold
+	aeskeygenassist	$2,%xmm0,%xmm1
+	call	L$key_expansion_128
+	aeskeygenassist	$4,%xmm0,%xmm1
+	call	L$key_expansion_128
+	aeskeygenassist	$8,%xmm0,%xmm1
+	call	L$key_expansion_128
+	aeskeygenassist	$16,%xmm0,%xmm1
+	call	L$key_expansion_128
+	aeskeygenassist	$32,%xmm0,%xmm1
+	call	L$key_expansion_128
+	aeskeygenassist	$64,%xmm0,%xmm1
+	call	L$key_expansion_128
+	aeskeygenassist	$128,%xmm0,%xmm1
+	call	L$key_expansion_128
+	aeskeygenassist	$27,%xmm0,%xmm1
+	call	L$key_expansion_128
+	aeskeygenassist	$54,%xmm0,%xmm1
+	call	L$key_expansion_128
+	movups	%xmm0,(%rax)
+	movl	%esi,80(%rax)
+	xorl	%eax,%eax
+	jmp	L$enc_key_ret
+
+.p2align	4
+L$12rounds:
+	movq	16(%rdi),%xmm2
+	movl	$11,%esi
+	movups	%xmm0,(%rdx)
+	aeskeygenassist	$1,%xmm2,%xmm1
+	call	L$key_expansion_192a_cold
+	aeskeygenassist	$2,%xmm2,%xmm1
+	call	L$key_expansion_192b
+	aeskeygenassist	$4,%xmm2,%xmm1
+	call	L$key_expansion_192a
+	aeskeygenassist	$8,%xmm2,%xmm1
+	call	L$key_expansion_192b
+	aeskeygenassist	$16,%xmm2,%xmm1
+	call	L$key_expansion_192a
+	aeskeygenassist	$32,%xmm2,%xmm1
+	call	L$key_expansion_192b
+	aeskeygenassist	$64,%xmm2,%xmm1
+	call	L$key_expansion_192a
+	aeskeygenassist	$128,%xmm2,%xmm1
+	call	L$key_expansion_192b
+	movups	%xmm0,(%rax)
+	movl	%esi,48(%rax)
+	xorq	%rax,%rax
+	jmp	L$enc_key_ret
+
+.p2align	4
+L$14rounds:
+	movups	16(%rdi),%xmm2
+	movl	$13,%esi
+	leaq	16(%rax),%rax
+	movups	%xmm0,(%rdx)
+	movups	%xmm2,16(%rdx)
+	aeskeygenassist	$1,%xmm2,%xmm1
+	call	L$key_expansion_256a_cold
+	aeskeygenassist	$1,%xmm0,%xmm1
+	call	L$key_expansion_256b
+	aeskeygenassist	$2,%xmm2,%xmm1
+	call	L$key_expansion_256a
+	aeskeygenassist	$2,%xmm0,%xmm1
+	call	L$key_expansion_256b
+	aeskeygenassist	$4,%xmm2,%xmm1
+	call	L$key_expansion_256a
+	aeskeygenassist	$4,%xmm0,%xmm1
+	call	L$key_expansion_256b
+	aeskeygenassist	$8,%xmm2,%xmm1
+	call	L$key_expansion_256a
+	aeskeygenassist	$8,%xmm0,%xmm1
+	call	L$key_expansion_256b
+	aeskeygenassist	$16,%xmm2,%xmm1
+	call	L$key_expansion_256a
+	aeskeygenassist	$16,%xmm0,%xmm1
+	call	L$key_expansion_256b
+	aeskeygenassist	$32,%xmm2,%xmm1
+	call	L$key_expansion_256a
+	aeskeygenassist	$32,%xmm0,%xmm1
+	call	L$key_expansion_256b
+	aeskeygenassist	$64,%xmm2,%xmm1
+	call	L$key_expansion_256a
+	movups	%xmm0,(%rax)
+	movl	%esi,16(%rax)
+	xorq	%rax,%rax
+	jmp	L$enc_key_ret
+
+.p2align	4
+L$bad_keybits:
+	movq	$-2,%rax
+L$enc_key_ret:
+	addq	$8,%rsp
+	.byte	0xf3,0xc3
+L$SEH_end_set_encrypt_key:
+
+.p2align	4
+L$key_expansion_128:
+	movups	%xmm0,(%rax)
+	leaq	16(%rax),%rax
+L$key_expansion_128_cold:
+	shufps	$16,%xmm0,%xmm4
+	xorps	%xmm4,%xmm0
+	shufps	$140,%xmm0,%xmm4
+	xorps	%xmm4,%xmm0
+	shufps	$255,%xmm1,%xmm1
+	xorps	%xmm1,%xmm0
+	.byte	0xf3,0xc3
+
+.p2align	4
+L$key_expansion_192a:
+	movups	%xmm0,(%rax)
+	leaq	16(%rax),%rax
+L$key_expansion_192a_cold:
+	movaps	%xmm2,%xmm5
+L$key_expansion_192b_warm:
+	shufps	$16,%xmm0,%xmm4
+	movdqa	%xmm2,%xmm3
+	xorps	%xmm4,%xmm0
+	shufps	$140,%xmm0,%xmm4
+	pslldq	$4,%xmm3
+	xorps	%xmm4,%xmm0
+	pshufd	$85,%xmm1,%xmm1
+	pxor	%xmm3,%xmm2
+	pxor	%xmm1,%xmm0
+	pshufd	$255,%xmm0,%xmm3
+	pxor	%xmm3,%xmm2
+	.byte	0xf3,0xc3
+
+.p2align	4
+L$key_expansion_192b:
+	movaps	%xmm0,%xmm3
+	shufps	$68,%xmm0,%xmm5
+	movups	%xmm5,(%rax)
+	shufps	$78,%xmm2,%xmm3
+	movups	%xmm3,16(%rax)
+	leaq	32(%rax),%rax
+	jmp	L$key_expansion_192b_warm
+
+.p2align	4
+L$key_expansion_256a:
+	movups	%xmm2,(%rax)
+	leaq	16(%rax),%rax
+L$key_expansion_256a_cold:
+	shufps	$16,%xmm0,%xmm4
+	xorps	%xmm4,%xmm0
+	shufps	$140,%xmm0,%xmm4
+	xorps	%xmm4,%xmm0
+	shufps	$255,%xmm1,%xmm1
+	xorps	%xmm1,%xmm0
+	.byte	0xf3,0xc3
+
+.p2align	4
+L$key_expansion_256b:
+	movups	%xmm0,(%rax)
+	leaq	16(%rax),%rax
+
+	shufps	$16,%xmm2,%xmm4
+	xorps	%xmm4,%xmm2
+	shufps	$140,%xmm2,%xmm4
+	xorps	%xmm4,%xmm2
+	shufps	$170,%xmm1,%xmm1
+	xorps	%xmm1,%xmm2
+	.byte	0xf3,0xc3
+
+
+.p2align	6
+L$bswap_mask:
+.byte	15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
+L$increment32:
+.long	6,6,6,0
+L$increment64:
+.long	1,0,0,0
+L$xts_magic:
+.long	0x87,0,1,0
+
+.byte	65,69,83,32,102,111,114,32,73,110,116,101,108,32,65,69,83,45,78,73,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.p2align	6
diff --git a/crypto/libressl/crypto/aes/aesni-sha1-elf-x86_64.s b/crypto/libressl/crypto/aes/aesni-sha1-elf-x86_64.s
new file mode 100644
index 0000000000..ae626222e2
--- /dev/null
+++ b/crypto/libressl/crypto/aes/aesni-sha1-elf-x86_64.s
@@ -0,0 +1,1399 @@
+.text	
+
+
+.globl	aesni_cbc_sha1_enc
+.type	aesni_cbc_sha1_enc,@function
+.align	16
+aesni_cbc_sha1_enc:
+
+	movl	OPENSSL_ia32cap_P+0(%rip),%r10d
+	movl	OPENSSL_ia32cap_P+4(%rip),%r11d
+	jmp	aesni_cbc_sha1_enc_ssse3
+	.byte	0xf3,0xc3
+.size	aesni_cbc_sha1_enc,.-aesni_cbc_sha1_enc
+.type	aesni_cbc_sha1_enc_ssse3,@function
+.align	16
+aesni_cbc_sha1_enc_ssse3:
+	movq	8(%rsp),%r10
+
+
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	leaq	-104(%rsp),%rsp
+
+
+	movq	%rdi,%r12
+	movq	%rsi,%r13
+	movq	%rdx,%r14
+	movq	%rcx,%r15
+	movdqu	(%r8),%xmm11
+	movq	%r8,88(%rsp)
+	shlq	$6,%r14
+	subq	%r12,%r13
+	movl	240(%r15),%r8d
+	addq	%r10,%r14
+
+	leaq	K_XX_XX(%rip),%r11
+	movl	0(%r9),%eax
+	movl	4(%r9),%ebx
+	movl	8(%r9),%ecx
+	movl	12(%r9),%edx
+	movl	%ebx,%esi
+	movl	16(%r9),%ebp
+
+	movdqa	64(%r11),%xmm6
+	movdqa	0(%r11),%xmm9
+	movdqu	0(%r10),%xmm0
+	movdqu	16(%r10),%xmm1
+	movdqu	32(%r10),%xmm2
+	movdqu	48(%r10),%xmm3
+.byte	102,15,56,0,198
+	addq	$64,%r10
+.byte	102,15,56,0,206
+.byte	102,15,56,0,214
+.byte	102,15,56,0,222
+	paddd	%xmm9,%xmm0
+	paddd	%xmm9,%xmm1
+	paddd	%xmm9,%xmm2
+	movdqa	%xmm0,0(%rsp)
+	psubd	%xmm9,%xmm0
+	movdqa	%xmm1,16(%rsp)
+	psubd	%xmm9,%xmm1
+	movdqa	%xmm2,32(%rsp)
+	psubd	%xmm9,%xmm2
+	movups	(%r15),%xmm13
+	movups	16(%r15),%xmm14
+	jmp	.Loop_ssse3
+.align	16
+.Loop_ssse3:
+	movdqa	%xmm1,%xmm4
+	addl	0(%rsp),%ebp
+	movups	0(%r12),%xmm12
+	xorps	%xmm13,%xmm12
+	xorps	%xmm12,%xmm11
+	aesenc	%xmm14,%xmm11
+	movups	32(%r15),%xmm15
+	xorl	%edx,%ecx
+	movdqa	%xmm3,%xmm8
+.byte	102,15,58,15,224,8
+	movl	%eax,%edi
+	roll	$5,%eax
+	paddd	%xmm3,%xmm9
+	andl	%ecx,%esi
+	xorl	%edx,%ecx
+	psrldq	$4,%xmm8
+	xorl	%edx,%esi
+	addl	%eax,%ebp
+	pxor	%xmm0,%xmm4
+	rorl	$2,%ebx
+	addl	%esi,%ebp
+	pxor	%xmm2,%xmm8
+	addl	4(%rsp),%edx
+	xorl	%ecx,%ebx
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	pxor	%xmm8,%xmm4
+	andl	%ebx,%edi
+	xorl	%ecx,%ebx
+	movdqa	%xmm9,48(%rsp)
+	xorl	%ecx,%edi
+	aesenc	%xmm15,%xmm11
+	movups	48(%r15),%xmm14
+	addl	%ebp,%edx
+	movdqa	%xmm4,%xmm10
+	movdqa	%xmm4,%xmm8
+	rorl	$7,%eax
+	addl	%edi,%edx
+	addl	8(%rsp),%ecx
+	xorl	%ebx,%eax
+	pslldq	$12,%xmm10
+	paddd	%xmm4,%xmm4
+	movl	%edx,%edi
+	roll	$5,%edx
+	andl	%eax,%esi
+	xorl	%ebx,%eax
+	psrld	$31,%xmm8
+	xorl	%ebx,%esi
+	addl	%edx,%ecx
+	movdqa	%xmm10,%xmm9
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	psrld	$30,%xmm10
+	por	%xmm8,%xmm4
+	addl	12(%rsp),%ebx
+	xorl	%eax,%ebp
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	aesenc	%xmm14,%xmm11
+	movups	64(%r15),%xmm15
+	pslld	$2,%xmm9
+	pxor	%xmm10,%xmm4
+	andl	%ebp,%edi
+	xorl	%eax,%ebp
+	movdqa	0(%r11),%xmm10
+	xorl	%eax,%edi
+	addl	%ecx,%ebx
+	pxor	%xmm9,%xmm4
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	movdqa	%xmm2,%xmm5
+	addl	16(%rsp),%eax
+	xorl	%ebp,%edx
+	movdqa	%xmm4,%xmm9
+.byte	102,15,58,15,233,8
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	paddd	%xmm4,%xmm10
+	andl	%edx,%esi
+	xorl	%ebp,%edx
+	psrldq	$4,%xmm9
+	xorl	%ebp,%esi
+	addl	%ebx,%eax
+	pxor	%xmm1,%xmm5
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	pxor	%xmm3,%xmm9
+	addl	20(%rsp),%ebp
+	aesenc	%xmm15,%xmm11
+	movups	80(%r15),%xmm14
+	xorl	%edx,%ecx
+	movl	%eax,%esi
+	roll	$5,%eax
+	pxor	%xmm9,%xmm5
+	andl	%ecx,%edi
+	xorl	%edx,%ecx
+	movdqa	%xmm10,0(%rsp)
+	xorl	%edx,%edi
+	addl	%eax,%ebp
+	movdqa	%xmm5,%xmm8
+	movdqa	%xmm5,%xmm9
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	addl	24(%rsp),%edx
+	xorl	%ecx,%ebx
+	pslldq	$12,%xmm8
+	paddd	%xmm5,%xmm5
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	andl	%ebx,%esi
+	xorl	%ecx,%ebx
+	psrld	$31,%xmm9
+	xorl	%ecx,%esi
+	aesenc	%xmm14,%xmm11
+	movups	96(%r15),%xmm15
+	addl	%ebp,%edx
+	movdqa	%xmm8,%xmm10
+	rorl	$7,%eax
+	addl	%esi,%edx
+	psrld	$30,%xmm8
+	por	%xmm9,%xmm5
+	addl	28(%rsp),%ecx
+	xorl	%ebx,%eax
+	movl	%edx,%esi
+	roll	$5,%edx
+	pslld	$2,%xmm10
+	pxor	%xmm8,%xmm5
+	andl	%eax,%edi
+	xorl	%ebx,%eax
+	movdqa	16(%r11),%xmm8
+	xorl	%ebx,%edi
+	addl	%edx,%ecx
+	pxor	%xmm10,%xmm5
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	movdqa	%xmm3,%xmm6
+	addl	32(%rsp),%ebx
+	xorl	%eax,%ebp
+	movdqa	%xmm5,%xmm10
+.byte	102,15,58,15,242,8
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	aesenc	%xmm15,%xmm11
+	movups	112(%r15),%xmm14
+	paddd	%xmm5,%xmm8
+	andl	%ebp,%esi
+	xorl	%eax,%ebp
+	psrldq	$4,%xmm10
+	xorl	%eax,%esi
+	addl	%ecx,%ebx
+	pxor	%xmm2,%xmm6
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	pxor	%xmm4,%xmm10
+	addl	36(%rsp),%eax
+	xorl	%ebp,%edx
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	pxor	%xmm10,%xmm6
+	andl	%edx,%edi
+	xorl	%ebp,%edx
+	movdqa	%xmm8,16(%rsp)
+	xorl	%ebp,%edi
+	addl	%ebx,%eax
+	movdqa	%xmm6,%xmm9
+	movdqa	%xmm6,%xmm10
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	addl	40(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	128(%r15),%xmm15
+	xorl	%edx,%ecx
+	pslldq	$12,%xmm9
+	paddd	%xmm6,%xmm6
+	movl	%eax,%edi
+	roll	$5,%eax
+	andl	%ecx,%esi
+	xorl	%edx,%ecx
+	psrld	$31,%xmm10
+	xorl	%edx,%esi
+	addl	%eax,%ebp
+	movdqa	%xmm9,%xmm8
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	psrld	$30,%xmm9
+	por	%xmm10,%xmm6
+	addl	44(%rsp),%edx
+	xorl	%ecx,%ebx
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	pslld	$2,%xmm8
+	pxor	%xmm9,%xmm6
+	andl	%ebx,%edi
+	xorl	%ecx,%ebx
+	movdqa	16(%r11),%xmm9
+	xorl	%ecx,%edi
+	aesenc	%xmm15,%xmm11
+	movups	144(%r15),%xmm14
+	addl	%ebp,%edx
+	pxor	%xmm8,%xmm6
+	rorl	$7,%eax
+	addl	%edi,%edx
+	movdqa	%xmm4,%xmm7
+	addl	48(%rsp),%ecx
+	xorl	%ebx,%eax
+	movdqa	%xmm6,%xmm8
+.byte	102,15,58,15,251,8
+	movl	%edx,%edi
+	roll	$5,%edx
+	paddd	%xmm6,%xmm9
+	andl	%eax,%esi
+	xorl	%ebx,%eax
+	psrldq	$4,%xmm8
+	xorl	%ebx,%esi
+	addl	%edx,%ecx
+	pxor	%xmm3,%xmm7
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	pxor	%xmm5,%xmm8
+	addl	52(%rsp),%ebx
+	xorl	%eax,%ebp
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	aesenc	%xmm14,%xmm11
+	movups	160(%r15),%xmm15
+	pxor	%xmm8,%xmm7
+	andl	%ebp,%edi
+	xorl	%eax,%ebp
+	movdqa	%xmm9,32(%rsp)
+	xorl	%eax,%edi
+	addl	%ecx,%ebx
+	movdqa	%xmm7,%xmm10
+	movdqa	%xmm7,%xmm8
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	addl	56(%rsp),%eax
+	xorl	%ebp,%edx
+	pslldq	$12,%xmm10
+	paddd	%xmm7,%xmm7
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	andl	%edx,%esi
+	xorl	%ebp,%edx
+	psrld	$31,%xmm8
+	xorl	%ebp,%esi
+	addl	%ebx,%eax
+	movdqa	%xmm10,%xmm9
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	psrld	$30,%xmm10
+	por	%xmm8,%xmm7
+	addl	60(%rsp),%ebp
+	cmpl	$11,%r8d
+	jb	.Laesenclast1
+	movups	176(%r15),%xmm14
+	aesenc	%xmm15,%xmm11
+	movups	192(%r15),%xmm15
+	aesenc	%xmm14,%xmm11
+	je	.Laesenclast1
+	movups	208(%r15),%xmm14
+	aesenc	%xmm15,%xmm11
+	movups	224(%r15),%xmm15
+	aesenc	%xmm14,%xmm11
+.Laesenclast1:
+	aesenclast	%xmm15,%xmm11
+	movups	16(%r15),%xmm14
+	xorl	%edx,%ecx
+	movl	%eax,%esi
+	roll	$5,%eax
+	pslld	$2,%xmm9
+	pxor	%xmm10,%xmm7
+	andl	%ecx,%edi
+	xorl	%edx,%ecx
+	movdqa	16(%r11),%xmm10
+	xorl	%edx,%edi
+	addl	%eax,%ebp
+	pxor	%xmm9,%xmm7
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	movdqa	%xmm7,%xmm9
+	addl	0(%rsp),%edx
+	pxor	%xmm4,%xmm0
+.byte	102,68,15,58,15,206,8
+	xorl	%ecx,%ebx
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	pxor	%xmm1,%xmm0
+	andl	%ebx,%esi
+	xorl	%ecx,%ebx
+	movdqa	%xmm10,%xmm8
+	paddd	%xmm7,%xmm10
+	xorl	%ecx,%esi
+	movups	16(%r12),%xmm12
+	xorps	%xmm13,%xmm12
+	movups	%xmm11,0(%r13,%r12,1)
+	xorps	%xmm12,%xmm11
+	aesenc	%xmm14,%xmm11
+	movups	32(%r15),%xmm15
+	addl	%ebp,%edx
+	pxor	%xmm9,%xmm0
+	rorl	$7,%eax
+	addl	%esi,%edx
+	addl	4(%rsp),%ecx
+	xorl	%ebx,%eax
+	movdqa	%xmm0,%xmm9
+	movdqa	%xmm10,48(%rsp)
+	movl	%edx,%esi
+	roll	$5,%edx
+	andl	%eax,%edi
+	xorl	%ebx,%eax
+	pslld	$2,%xmm0
+	xorl	%ebx,%edi
+	addl	%edx,%ecx
+	psrld	$30,%xmm9
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	addl	8(%rsp),%ebx
+	xorl	%eax,%ebp
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	aesenc	%xmm15,%xmm11
+	movups	48(%r15),%xmm14
+	por	%xmm9,%xmm0
+	andl	%ebp,%esi
+	xorl	%eax,%ebp
+	movdqa	%xmm0,%xmm10
+	xorl	%eax,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	addl	12(%rsp),%eax
+	xorl	%ebp,%edx
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	andl	%edx,%edi
+	xorl	%ebp,%edx
+	xorl	%ebp,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	addl	16(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	64(%r15),%xmm15
+	pxor	%xmm5,%xmm1
+.byte	102,68,15,58,15,215,8
+	xorl	%edx,%esi
+	movl	%eax,%edi
+	roll	$5,%eax
+	pxor	%xmm2,%xmm1
+	xorl	%ecx,%esi
+	addl	%eax,%ebp
+	movdqa	%xmm8,%xmm9
+	paddd	%xmm0,%xmm8
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	pxor	%xmm10,%xmm1
+	addl	20(%rsp),%edx
+	xorl	%ecx,%edi
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	movdqa	%xmm1,%xmm10
+	movdqa	%xmm8,0(%rsp)
+	xorl	%ebx,%edi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%edi,%edx
+	pslld	$2,%xmm1
+	addl	24(%rsp),%ecx
+	xorl	%ebx,%esi
+	psrld	$30,%xmm10
+	movl	%edx,%edi
+	roll	$5,%edx
+	xorl	%eax,%esi
+	aesenc	%xmm15,%xmm11
+	movups	80(%r15),%xmm14
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	por	%xmm10,%xmm1
+	addl	28(%rsp),%ebx
+	xorl	%eax,%edi
+	movdqa	%xmm1,%xmm8
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	xorl	%ebp,%edi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	addl	32(%rsp),%eax
+	pxor	%xmm6,%xmm2
+.byte	102,68,15,58,15,192,8
+	xorl	%ebp,%esi
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	pxor	%xmm3,%xmm2
+	xorl	%edx,%esi
+	addl	%ebx,%eax
+	movdqa	32(%r11),%xmm10
+	paddd	%xmm1,%xmm9
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	pxor	%xmm8,%xmm2
+	addl	36(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	96(%r15),%xmm15
+	xorl	%edx,%edi
+	movl	%eax,%esi
+	roll	$5,%eax
+	movdqa	%xmm2,%xmm8
+	movdqa	%xmm9,16(%rsp)
+	xorl	%ecx,%edi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	pslld	$2,%xmm2
+	addl	40(%rsp),%edx
+	xorl	%ecx,%esi
+	psrld	$30,%xmm8
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	xorl	%ebx,%esi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%esi,%edx
+	por	%xmm8,%xmm2
+	addl	44(%rsp),%ecx
+	xorl	%ebx,%edi
+	movdqa	%xmm2,%xmm9
+	movl	%edx,%esi
+	roll	$5,%edx
+	xorl	%eax,%edi
+	aesenc	%xmm15,%xmm11
+	movups	112(%r15),%xmm14
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	addl	48(%rsp),%ebx
+	pxor	%xmm7,%xmm3
+.byte	102,68,15,58,15,201,8
+	xorl	%eax,%esi
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	pxor	%xmm4,%xmm3
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	movdqa	%xmm10,%xmm8
+	paddd	%xmm2,%xmm10
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	pxor	%xmm9,%xmm3
+	addl	52(%rsp),%eax
+	xorl	%ebp,%edi
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	movdqa	%xmm3,%xmm9
+	movdqa	%xmm10,32(%rsp)
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	pslld	$2,%xmm3
+	addl	56(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	128(%r15),%xmm15
+	xorl	%edx,%esi
+	psrld	$30,%xmm9
+	movl	%eax,%edi
+	roll	$5,%eax
+	xorl	%ecx,%esi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	por	%xmm9,%xmm3
+	addl	60(%rsp),%edx
+	xorl	%ecx,%edi
+	movdqa	%xmm3,%xmm10
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	xorl	%ebx,%edi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%edi,%edx
+	addl	0(%rsp),%ecx
+	pxor	%xmm0,%xmm4
+.byte	102,68,15,58,15,210,8
+	xorl	%ebx,%esi
+	movl	%edx,%edi
+	roll	$5,%edx
+	pxor	%xmm5,%xmm4
+	xorl	%eax,%esi
+	aesenc	%xmm15,%xmm11
+	movups	144(%r15),%xmm14
+	addl	%edx,%ecx
+	movdqa	%xmm8,%xmm9
+	paddd	%xmm3,%xmm8
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	pxor	%xmm10,%xmm4
+	addl	4(%rsp),%ebx
+	xorl	%eax,%edi
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	movdqa	%xmm4,%xmm10
+	movdqa	%xmm8,48(%rsp)
+	xorl	%ebp,%edi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	pslld	$2,%xmm4
+	addl	8(%rsp),%eax
+	xorl	%ebp,%esi
+	psrld	$30,%xmm10
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	xorl	%edx,%esi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	por	%xmm10,%xmm4
+	addl	12(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	160(%r15),%xmm15
+	xorl	%edx,%edi
+	movdqa	%xmm4,%xmm8
+	movl	%eax,%esi
+	roll	$5,%eax
+	xorl	%ecx,%edi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	addl	16(%rsp),%edx
+	pxor	%xmm1,%xmm5
+.byte	102,68,15,58,15,195,8
+	xorl	%ecx,%esi
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	pxor	%xmm6,%xmm5
+	xorl	%ebx,%esi
+	addl	%ebp,%edx
+	movdqa	%xmm9,%xmm10
+	paddd	%xmm4,%xmm9
+	rorl	$7,%eax
+	addl	%esi,%edx
+	pxor	%xmm8,%xmm5
+	addl	20(%rsp),%ecx
+	xorl	%ebx,%edi
+	movl	%edx,%esi
+	roll	$5,%edx
+	movdqa	%xmm5,%xmm8
+	movdqa	%xmm9,0(%rsp)
+	xorl	%eax,%edi
+	cmpl	$11,%r8d
+	jb	.Laesenclast2
+	movups	176(%r15),%xmm14
+	aesenc	%xmm15,%xmm11
+	movups	192(%r15),%xmm15
+	aesenc	%xmm14,%xmm11
+	je	.Laesenclast2
+	movups	208(%r15),%xmm14
+	aesenc	%xmm15,%xmm11
+	movups	224(%r15),%xmm15
+	aesenc	%xmm14,%xmm11
+.Laesenclast2:
+	aesenclast	%xmm15,%xmm11
+	movups	16(%r15),%xmm14
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	pslld	$2,%xmm5
+	addl	24(%rsp),%ebx
+	xorl	%eax,%esi
+	psrld	$30,%xmm8
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	por	%xmm8,%xmm5
+	addl	28(%rsp),%eax
+	xorl	%ebp,%edi
+	movdqa	%xmm5,%xmm9
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	movl	%ecx,%edi
+	movups	32(%r12),%xmm12
+	xorps	%xmm13,%xmm12
+	movups	%xmm11,16(%r13,%r12,1)
+	xorps	%xmm12,%xmm11
+	aesenc	%xmm14,%xmm11
+	movups	32(%r15),%xmm15
+	pxor	%xmm2,%xmm6
+.byte	102,68,15,58,15,204,8
+	xorl	%edx,%ecx
+	addl	32(%rsp),%ebp
+	andl	%edx,%edi
+	pxor	%xmm7,%xmm6
+	andl	%ecx,%esi
+	rorl	$7,%ebx
+	movdqa	%xmm10,%xmm8
+	paddd	%xmm5,%xmm10
+	addl	%edi,%ebp
+	movl	%eax,%edi
+	pxor	%xmm9,%xmm6
+	roll	$5,%eax
+	addl	%esi,%ebp
+	xorl	%edx,%ecx
+	addl	%eax,%ebp
+	movdqa	%xmm6,%xmm9
+	movdqa	%xmm10,16(%rsp)
+	movl	%ebx,%esi
+	xorl	%ecx,%ebx
+	addl	36(%rsp),%edx
+	andl	%ecx,%esi
+	pslld	$2,%xmm6
+	andl	%ebx,%edi
+	rorl	$7,%eax
+	psrld	$30,%xmm9
+	addl	%esi,%edx
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	aesenc	%xmm15,%xmm11
+	movups	48(%r15),%xmm14
+	addl	%edi,%edx
+	xorl	%ecx,%ebx
+	addl	%ebp,%edx
+	por	%xmm9,%xmm6
+	movl	%eax,%edi
+	xorl	%ebx,%eax
+	movdqa	%xmm6,%xmm10
+	addl	40(%rsp),%ecx
+	andl	%ebx,%edi
+	andl	%eax,%esi
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	movl	%edx,%edi
+	roll	$5,%edx
+	addl	%esi,%ecx
+	xorl	%ebx,%eax
+	addl	%edx,%ecx
+	movl	%ebp,%esi
+	xorl	%eax,%ebp
+	addl	44(%rsp),%ebx
+	andl	%eax,%esi
+	andl	%ebp,%edi
+	aesenc	%xmm14,%xmm11
+	movups	64(%r15),%xmm15
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	addl	%edi,%ebx
+	xorl	%eax,%ebp
+	addl	%ecx,%ebx
+	movl	%edx,%edi
+	pxor	%xmm3,%xmm7
+.byte	102,68,15,58,15,213,8
+	xorl	%ebp,%edx
+	addl	48(%rsp),%eax
+	andl	%ebp,%edi
+	pxor	%xmm0,%xmm7
+	andl	%edx,%esi
+	rorl	$7,%ecx
+	movdqa	48(%r11),%xmm9
+	paddd	%xmm6,%xmm8
+	addl	%edi,%eax
+	movl	%ebx,%edi
+	pxor	%xmm10,%xmm7
+	roll	$5,%ebx
+	addl	%esi,%eax
+	xorl	%ebp,%edx
+	addl	%ebx,%eax
+	movdqa	%xmm7,%xmm10
+	movdqa	%xmm8,32(%rsp)
+	movl	%ecx,%esi
+	aesenc	%xmm15,%xmm11
+	movups	80(%r15),%xmm14
+	xorl	%edx,%ecx
+	addl	52(%rsp),%ebp
+	andl	%edx,%esi
+	pslld	$2,%xmm7
+	andl	%ecx,%edi
+	rorl	$7,%ebx
+	psrld	$30,%xmm10
+	addl	%esi,%ebp
+	movl	%eax,%esi
+	roll	$5,%eax
+	addl	%edi,%ebp
+	xorl	%edx,%ecx
+	addl	%eax,%ebp
+	por	%xmm10,%xmm7
+	movl	%ebx,%edi
+	xorl	%ecx,%ebx
+	movdqa	%xmm7,%xmm8
+	addl	56(%rsp),%edx
+	andl	%ecx,%edi
+	andl	%ebx,%esi
+	rorl	$7,%eax
+	addl	%edi,%edx
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	aesenc	%xmm14,%xmm11
+	movups	96(%r15),%xmm15
+	addl	%esi,%edx
+	xorl	%ecx,%ebx
+	addl	%ebp,%edx
+	movl	%eax,%esi
+	xorl	%ebx,%eax
+	addl	60(%rsp),%ecx
+	andl	%ebx,%esi
+	andl	%eax,%edi
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	movl	%edx,%esi
+	roll	$5,%edx
+	addl	%edi,%ecx
+	xorl	%ebx,%eax
+	addl	%edx,%ecx
+	movl	%ebp,%edi
+	pxor	%xmm4,%xmm0
+.byte	102,68,15,58,15,198,8
+	xorl	%eax,%ebp
+	addl	0(%rsp),%ebx
+	andl	%eax,%edi
+	pxor	%xmm1,%xmm0
+	andl	%ebp,%esi
+	aesenc	%xmm15,%xmm11
+	movups	112(%r15),%xmm14
+	rorl	$7,%edx
+	movdqa	%xmm9,%xmm10
+	paddd	%xmm7,%xmm9
+	addl	%edi,%ebx
+	movl	%ecx,%edi
+	pxor	%xmm8,%xmm0
+	roll	$5,%ecx
+	addl	%esi,%ebx
+	xorl	%eax,%ebp
+	addl	%ecx,%ebx
+	movdqa	%xmm0,%xmm8
+	movdqa	%xmm9,48(%rsp)
+	movl	%edx,%esi
+	xorl	%ebp,%edx
+	addl	4(%rsp),%eax
+	andl	%ebp,%esi
+	pslld	$2,%xmm0
+	andl	%edx,%edi
+	rorl	$7,%ecx
+	psrld	$30,%xmm8
+	addl	%esi,%eax
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	addl	%edi,%eax
+	xorl	%ebp,%edx
+	addl	%ebx,%eax
+	por	%xmm8,%xmm0
+	movl	%ecx,%edi
+	aesenc	%xmm14,%xmm11
+	movups	128(%r15),%xmm15
+	xorl	%edx,%ecx
+	movdqa	%xmm0,%xmm9
+	addl	8(%rsp),%ebp
+	andl	%edx,%edi
+	andl	%ecx,%esi
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	movl	%eax,%edi
+	roll	$5,%eax
+	addl	%esi,%ebp
+	xorl	%edx,%ecx
+	addl	%eax,%ebp
+	movl	%ebx,%esi
+	xorl	%ecx,%ebx
+	addl	12(%rsp),%edx
+	andl	%ecx,%esi
+	andl	%ebx,%edi
+	rorl	$7,%eax
+	addl	%esi,%edx
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	aesenc	%xmm15,%xmm11
+	movups	144(%r15),%xmm14
+	addl	%edi,%edx
+	xorl	%ecx,%ebx
+	addl	%ebp,%edx
+	movl	%eax,%edi
+	pxor	%xmm5,%xmm1
+.byte	102,68,15,58,15,207,8
+	xorl	%ebx,%eax
+	addl	16(%rsp),%ecx
+	andl	%ebx,%edi
+	pxor	%xmm2,%xmm1
+	andl	%eax,%esi
+	rorl	$7,%ebp
+	movdqa	%xmm10,%xmm8
+	paddd	%xmm0,%xmm10
+	addl	%edi,%ecx
+	movl	%edx,%edi
+	pxor	%xmm9,%xmm1
+	roll	$5,%edx
+	addl	%esi,%ecx
+	xorl	%ebx,%eax
+	addl	%edx,%ecx
+	movdqa	%xmm1,%xmm9
+	movdqa	%xmm10,0(%rsp)
+	movl	%ebp,%esi
+	xorl	%eax,%ebp
+	addl	20(%rsp),%ebx
+	andl	%eax,%esi
+	pslld	$2,%xmm1
+	andl	%ebp,%edi
+	aesenc	%xmm14,%xmm11
+	movups	160(%r15),%xmm15
+	rorl	$7,%edx
+	psrld	$30,%xmm9
+	addl	%esi,%ebx
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	addl	%edi,%ebx
+	xorl	%eax,%ebp
+	addl	%ecx,%ebx
+	por	%xmm9,%xmm1
+	movl	%edx,%edi
+	xorl	%ebp,%edx
+	movdqa	%xmm1,%xmm10
+	addl	24(%rsp),%eax
+	andl	%ebp,%edi
+	andl	%edx,%esi
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	addl	%esi,%eax
+	xorl	%ebp,%edx
+	addl	%ebx,%eax
+	movl	%ecx,%esi
+	cmpl	$11,%r8d
+	jb	.Laesenclast3
+	movups	176(%r15),%xmm14
+	aesenc	%xmm15,%xmm11
+	movups	192(%r15),%xmm15
+	aesenc	%xmm14,%xmm11
+	je	.Laesenclast3
+	movups	208(%r15),%xmm14
+	aesenc	%xmm15,%xmm11
+	movups	224(%r15),%xmm15
+	aesenc	%xmm14,%xmm11
+.Laesenclast3:
+	aesenclast	%xmm15,%xmm11
+	movups	16(%r15),%xmm14
+	xorl	%edx,%ecx
+	addl	28(%rsp),%ebp
+	andl	%edx,%esi
+	andl	%ecx,%edi
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	movl	%eax,%esi
+	roll	$5,%eax
+	addl	%edi,%ebp
+	xorl	%edx,%ecx
+	addl	%eax,%ebp
+	movl	%ebx,%edi
+	pxor	%xmm6,%xmm2
+.byte	102,68,15,58,15,208,8
+	xorl	%ecx,%ebx
+	addl	32(%rsp),%edx
+	andl	%ecx,%edi
+	pxor	%xmm3,%xmm2
+	andl	%ebx,%esi
+	rorl	$7,%eax
+	movdqa	%xmm8,%xmm9
+	paddd	%xmm1,%xmm8
+	addl	%edi,%edx
+	movl	%ebp,%edi
+	pxor	%xmm10,%xmm2
+	roll	$5,%ebp
+	movups	48(%r12),%xmm12
+	xorps	%xmm13,%xmm12
+	movups	%xmm11,32(%r13,%r12,1)
+	xorps	%xmm12,%xmm11
+	aesenc	%xmm14,%xmm11
+	movups	32(%r15),%xmm15
+	addl	%esi,%edx
+	xorl	%ecx,%ebx
+	addl	%ebp,%edx
+	movdqa	%xmm2,%xmm10
+	movdqa	%xmm8,16(%rsp)
+	movl	%eax,%esi
+	xorl	%ebx,%eax
+	addl	36(%rsp),%ecx
+	andl	%ebx,%esi
+	pslld	$2,%xmm2
+	andl	%eax,%edi
+	rorl	$7,%ebp
+	psrld	$30,%xmm10
+	addl	%esi,%ecx
+	movl	%edx,%esi
+	roll	$5,%edx
+	addl	%edi,%ecx
+	xorl	%ebx,%eax
+	addl	%edx,%ecx
+	por	%xmm10,%xmm2
+	movl	%ebp,%edi
+	xorl	%eax,%ebp
+	movdqa	%xmm2,%xmm8
+	addl	40(%rsp),%ebx
+	andl	%eax,%edi
+	andl	%ebp,%esi
+	aesenc	%xmm15,%xmm11
+	movups	48(%r15),%xmm14
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	addl	%esi,%ebx
+	xorl	%eax,%ebp
+	addl	%ecx,%ebx
+	movl	%edx,%esi
+	xorl	%ebp,%edx
+	addl	44(%rsp),%eax
+	andl	%ebp,%esi
+	andl	%edx,%edi
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	addl	%edi,%eax
+	xorl	%ebp,%edx
+	addl	%ebx,%eax
+	addl	48(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	64(%r15),%xmm15
+	pxor	%xmm7,%xmm3
+.byte	102,68,15,58,15,193,8
+	xorl	%edx,%esi
+	movl	%eax,%edi
+	roll	$5,%eax
+	pxor	%xmm4,%xmm3
+	xorl	%ecx,%esi
+	addl	%eax,%ebp
+	movdqa	%xmm9,%xmm10
+	paddd	%xmm2,%xmm9
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	pxor	%xmm8,%xmm3
+	addl	52(%rsp),%edx
+	xorl	%ecx,%edi
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	movdqa	%xmm3,%xmm8
+	movdqa	%xmm9,32(%rsp)
+	xorl	%ebx,%edi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%edi,%edx
+	pslld	$2,%xmm3
+	addl	56(%rsp),%ecx
+	xorl	%ebx,%esi
+	psrld	$30,%xmm8
+	movl	%edx,%edi
+	roll	$5,%edx
+	xorl	%eax,%esi
+	aesenc	%xmm15,%xmm11
+	movups	80(%r15),%xmm14
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	por	%xmm8,%xmm3
+	addl	60(%rsp),%ebx
+	xorl	%eax,%edi
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	xorl	%ebp,%edi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	addl	0(%rsp),%eax
+	paddd	%xmm3,%xmm10
+	xorl	%ebp,%esi
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	xorl	%edx,%esi
+	movdqa	%xmm10,48(%rsp)
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	addl	4(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	96(%r15),%xmm15
+	xorl	%edx,%edi
+	movl	%eax,%esi
+	roll	$5,%eax
+	xorl	%ecx,%edi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	addl	8(%rsp),%edx
+	xorl	%ecx,%esi
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	xorl	%ebx,%esi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%esi,%edx
+	addl	12(%rsp),%ecx
+	xorl	%ebx,%edi
+	movl	%edx,%esi
+	roll	$5,%edx
+	xorl	%eax,%edi
+	aesenc	%xmm15,%xmm11
+	movups	112(%r15),%xmm14
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	cmpq	%r14,%r10
+	je	.Ldone_ssse3
+	movdqa	64(%r11),%xmm6
+	movdqa	0(%r11),%xmm9
+	movdqu	0(%r10),%xmm0
+	movdqu	16(%r10),%xmm1
+	movdqu	32(%r10),%xmm2
+	movdqu	48(%r10),%xmm3
+.byte	102,15,56,0,198
+	addq	$64,%r10
+	addl	16(%rsp),%ebx
+	xorl	%eax,%esi
+.byte	102,15,56,0,206
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	paddd	%xmm9,%xmm0
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	movdqa	%xmm0,0(%rsp)
+	addl	20(%rsp),%eax
+	xorl	%ebp,%edi
+	psubd	%xmm9,%xmm0
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	addl	24(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	128(%r15),%xmm15
+	xorl	%edx,%esi
+	movl	%eax,%edi
+	roll	$5,%eax
+	xorl	%ecx,%esi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	addl	28(%rsp),%edx
+	xorl	%ecx,%edi
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	xorl	%ebx,%edi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%edi,%edx
+	addl	32(%rsp),%ecx
+	xorl	%ebx,%esi
+.byte	102,15,56,0,214
+	movl	%edx,%edi
+	roll	$5,%edx
+	paddd	%xmm9,%xmm1
+	xorl	%eax,%esi
+	aesenc	%xmm15,%xmm11
+	movups	144(%r15),%xmm14
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	movdqa	%xmm1,16(%rsp)
+	addl	36(%rsp),%ebx
+	xorl	%eax,%edi
+	psubd	%xmm9,%xmm1
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	xorl	%ebp,%edi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	addl	40(%rsp),%eax
+	xorl	%ebp,%esi
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	xorl	%edx,%esi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	addl	44(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	160(%r15),%xmm15
+	xorl	%edx,%edi
+	movl	%eax,%esi
+	roll	$5,%eax
+	xorl	%ecx,%edi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	addl	48(%rsp),%edx
+	xorl	%ecx,%esi
+.byte	102,15,56,0,222
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	paddd	%xmm9,%xmm2
+	xorl	%ebx,%esi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%esi,%edx
+	movdqa	%xmm2,32(%rsp)
+	addl	52(%rsp),%ecx
+	xorl	%ebx,%edi
+	psubd	%xmm9,%xmm2
+	movl	%edx,%esi
+	roll	$5,%edx
+	xorl	%eax,%edi
+	cmpl	$11,%r8d
+	jb	.Laesenclast4
+	movups	176(%r15),%xmm14
+	aesenc	%xmm15,%xmm11
+	movups	192(%r15),%xmm15
+	aesenc	%xmm14,%xmm11
+	je	.Laesenclast4
+	movups	208(%r15),%xmm14
+	aesenc	%xmm15,%xmm11
+	movups	224(%r15),%xmm15
+	aesenc	%xmm14,%xmm11
+.Laesenclast4:
+	aesenclast	%xmm15,%xmm11
+	movups	16(%r15),%xmm14
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	addl	56(%rsp),%ebx
+	xorl	%eax,%esi
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	addl	60(%rsp),%eax
+	xorl	%ebp,%edi
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	movups	%xmm11,48(%r13,%r12,1)
+	leaq	64(%r12),%r12
+
+	addl	0(%r9),%eax
+	addl	4(%r9),%esi
+	addl	8(%r9),%ecx
+	addl	12(%r9),%edx
+	movl	%eax,0(%r9)
+	addl	16(%r9),%ebp
+	movl	%esi,4(%r9)
+	movl	%esi,%ebx
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+	movl	%ebp,16(%r9)
+	jmp	.Loop_ssse3
+
+.align	16
+.Ldone_ssse3:
+	addl	16(%rsp),%ebx
+	xorl	%eax,%esi
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	addl	20(%rsp),%eax
+	xorl	%ebp,%edi
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	addl	24(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	128(%r15),%xmm15
+	xorl	%edx,%esi
+	movl	%eax,%edi
+	roll	$5,%eax
+	xorl	%ecx,%esi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	addl	28(%rsp),%edx
+	xorl	%ecx,%edi
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	xorl	%ebx,%edi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%edi,%edx
+	addl	32(%rsp),%ecx
+	xorl	%ebx,%esi
+	movl	%edx,%edi
+	roll	$5,%edx
+	xorl	%eax,%esi
+	aesenc	%xmm15,%xmm11
+	movups	144(%r15),%xmm14
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	addl	36(%rsp),%ebx
+	xorl	%eax,%edi
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	xorl	%ebp,%edi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	addl	40(%rsp),%eax
+	xorl	%ebp,%esi
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	xorl	%edx,%esi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	addl	44(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	160(%r15),%xmm15
+	xorl	%edx,%edi
+	movl	%eax,%esi
+	roll	$5,%eax
+	xorl	%ecx,%edi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	addl	48(%rsp),%edx
+	xorl	%ecx,%esi
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	xorl	%ebx,%esi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%esi,%edx
+	addl	52(%rsp),%ecx
+	xorl	%ebx,%edi
+	movl	%edx,%esi
+	roll	$5,%edx
+	xorl	%eax,%edi
+	cmpl	$11,%r8d
+	jb	.Laesenclast5
+	movups	176(%r15),%xmm14
+	aesenc	%xmm15,%xmm11
+	movups	192(%r15),%xmm15
+	aesenc	%xmm14,%xmm11
+	je	.Laesenclast5
+	movups	208(%r15),%xmm14
+	aesenc	%xmm15,%xmm11
+	movups	224(%r15),%xmm15
+	aesenc	%xmm14,%xmm11
+.Laesenclast5:
+	aesenclast	%xmm15,%xmm11
+	movups	16(%r15),%xmm14
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	addl	56(%rsp),%ebx
+	xorl	%eax,%esi
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	addl	60(%rsp),%eax
+	xorl	%ebp,%edi
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	movups	%xmm11,48(%r13,%r12,1)
+	movq	88(%rsp),%r8
+
+	addl	0(%r9),%eax
+	addl	4(%r9),%esi
+	addl	8(%r9),%ecx
+	movl	%eax,0(%r9)
+	addl	12(%r9),%edx
+	movl	%esi,4(%r9)
+	addl	16(%r9),%ebp
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+	movl	%ebp,16(%r9)
+	movups	%xmm11,(%r8)
+	leaq	104(%rsp),%rsi
+	movq	0(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+.Lepilogue_ssse3:
+	.byte	0xf3,0xc3
+.size	aesni_cbc_sha1_enc_ssse3,.-aesni_cbc_sha1_enc_ssse3
+.align	64
+K_XX_XX:
+.long	0x5a827999,0x5a827999,0x5a827999,0x5a827999	
+.long	0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1	
+.long	0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc	
+.long	0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6	
+.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f	
+
+.byte	65,69,83,78,73,45,67,66,67,43,83,72,65,49,32,115,116,105,116,99,104,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align	64
+#if defined(HAVE_GNU_STACK)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/crypto/libressl/crypto/aes/aesni-sha1-macosx-x86_64.s b/crypto/libressl/crypto/aes/aesni-sha1-macosx-x86_64.s
new file mode 100644
index 0000000000..a2ddd92be9
--- /dev/null
+++ b/crypto/libressl/crypto/aes/aesni-sha1-macosx-x86_64.s
@@ -0,0 +1,1396 @@
+.text	
+
+
+.globl	_aesni_cbc_sha1_enc
+
+.p2align	4
+_aesni_cbc_sha1_enc:
+
+	movl	_OPENSSL_ia32cap_P+0(%rip),%r10d
+	movl	_OPENSSL_ia32cap_P+4(%rip),%r11d
+	jmp	aesni_cbc_sha1_enc_ssse3
+	.byte	0xf3,0xc3
+
+
+.p2align	4
+aesni_cbc_sha1_enc_ssse3:
+	movq	8(%rsp),%r10
+
+
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	leaq	-104(%rsp),%rsp
+
+
+	movq	%rdi,%r12
+	movq	%rsi,%r13
+	movq	%rdx,%r14
+	movq	%rcx,%r15
+	movdqu	(%r8),%xmm11
+	movq	%r8,88(%rsp)
+	shlq	$6,%r14
+	subq	%r12,%r13
+	movl	240(%r15),%r8d
+	addq	%r10,%r14
+
+	leaq	K_XX_XX(%rip),%r11
+	movl	0(%r9),%eax
+	movl	4(%r9),%ebx
+	movl	8(%r9),%ecx
+	movl	12(%r9),%edx
+	movl	%ebx,%esi
+	movl	16(%r9),%ebp
+
+	movdqa	64(%r11),%xmm6
+	movdqa	0(%r11),%xmm9
+	movdqu	0(%r10),%xmm0
+	movdqu	16(%r10),%xmm1
+	movdqu	32(%r10),%xmm2
+	movdqu	48(%r10),%xmm3
+.byte	102,15,56,0,198
+	addq	$64,%r10
+.byte	102,15,56,0,206
+.byte	102,15,56,0,214
+.byte	102,15,56,0,222
+	paddd	%xmm9,%xmm0
+	paddd	%xmm9,%xmm1
+	paddd	%xmm9,%xmm2
+	movdqa	%xmm0,0(%rsp)
+	psubd	%xmm9,%xmm0
+	movdqa	%xmm1,16(%rsp)
+	psubd	%xmm9,%xmm1
+	movdqa	%xmm2,32(%rsp)
+	psubd	%xmm9,%xmm2
+	movups	(%r15),%xmm13
+	movups	16(%r15),%xmm14
+	jmp	L$oop_ssse3
+.p2align	4
+L$oop_ssse3:
+	movdqa	%xmm1,%xmm4
+	addl	0(%rsp),%ebp
+	movups	0(%r12),%xmm12
+	xorps	%xmm13,%xmm12
+	xorps	%xmm12,%xmm11
+	aesenc	%xmm14,%xmm11
+	movups	32(%r15),%xmm15
+	xorl	%edx,%ecx
+	movdqa	%xmm3,%xmm8
+.byte	102,15,58,15,224,8
+	movl	%eax,%edi
+	roll	$5,%eax
+	paddd	%xmm3,%xmm9
+	andl	%ecx,%esi
+	xorl	%edx,%ecx
+	psrldq	$4,%xmm8
+	xorl	%edx,%esi
+	addl	%eax,%ebp
+	pxor	%xmm0,%xmm4
+	rorl	$2,%ebx
+	addl	%esi,%ebp
+	pxor	%xmm2,%xmm8
+	addl	4(%rsp),%edx
+	xorl	%ecx,%ebx
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	pxor	%xmm8,%xmm4
+	andl	%ebx,%edi
+	xorl	%ecx,%ebx
+	movdqa	%xmm9,48(%rsp)
+	xorl	%ecx,%edi
+	aesenc	%xmm15,%xmm11
+	movups	48(%r15),%xmm14
+	addl	%ebp,%edx
+	movdqa	%xmm4,%xmm10
+	movdqa	%xmm4,%xmm8
+	rorl	$7,%eax
+	addl	%edi,%edx
+	addl	8(%rsp),%ecx
+	xorl	%ebx,%eax
+	pslldq	$12,%xmm10
+	paddd	%xmm4,%xmm4
+	movl	%edx,%edi
+	roll	$5,%edx
+	andl	%eax,%esi
+	xorl	%ebx,%eax
+	psrld	$31,%xmm8
+	xorl	%ebx,%esi
+	addl	%edx,%ecx
+	movdqa	%xmm10,%xmm9
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	psrld	$30,%xmm10
+	por	%xmm8,%xmm4
+	addl	12(%rsp),%ebx
+	xorl	%eax,%ebp
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	aesenc	%xmm14,%xmm11
+	movups	64(%r15),%xmm15
+	pslld	$2,%xmm9
+	pxor	%xmm10,%xmm4
+	andl	%ebp,%edi
+	xorl	%eax,%ebp
+	movdqa	0(%r11),%xmm10
+	xorl	%eax,%edi
+	addl	%ecx,%ebx
+	pxor	%xmm9,%xmm4
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	movdqa	%xmm2,%xmm5
+	addl	16(%rsp),%eax
+	xorl	%ebp,%edx
+	movdqa	%xmm4,%xmm9
+.byte	102,15,58,15,233,8
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	paddd	%xmm4,%xmm10
+	andl	%edx,%esi
+	xorl	%ebp,%edx
+	psrldq	$4,%xmm9
+	xorl	%ebp,%esi
+	addl	%ebx,%eax
+	pxor	%xmm1,%xmm5
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	pxor	%xmm3,%xmm9
+	addl	20(%rsp),%ebp
+	aesenc	%xmm15,%xmm11
+	movups	80(%r15),%xmm14
+	xorl	%edx,%ecx
+	movl	%eax,%esi
+	roll	$5,%eax
+	pxor	%xmm9,%xmm5
+	andl	%ecx,%edi
+	xorl	%edx,%ecx
+	movdqa	%xmm10,0(%rsp)
+	xorl	%edx,%edi
+	addl	%eax,%ebp
+	movdqa	%xmm5,%xmm8
+	movdqa	%xmm5,%xmm9
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	addl	24(%rsp),%edx
+	xorl	%ecx,%ebx
+	pslldq	$12,%xmm8
+	paddd	%xmm5,%xmm5
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	andl	%ebx,%esi
+	xorl	%ecx,%ebx
+	psrld	$31,%xmm9
+	xorl	%ecx,%esi
+	aesenc	%xmm14,%xmm11
+	movups	96(%r15),%xmm15
+	addl	%ebp,%edx
+	movdqa	%xmm8,%xmm10
+	rorl	$7,%eax
+	addl	%esi,%edx
+	psrld	$30,%xmm8
+	por	%xmm9,%xmm5
+	addl	28(%rsp),%ecx
+	xorl	%ebx,%eax
+	movl	%edx,%esi
+	roll	$5,%edx
+	pslld	$2,%xmm10
+	pxor	%xmm8,%xmm5
+	andl	%eax,%edi
+	xorl	%ebx,%eax
+	movdqa	16(%r11),%xmm8
+	xorl	%ebx,%edi
+	addl	%edx,%ecx
+	pxor	%xmm10,%xmm5
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	movdqa	%xmm3,%xmm6
+	addl	32(%rsp),%ebx
+	xorl	%eax,%ebp
+	movdqa	%xmm5,%xmm10
+.byte	102,15,58,15,242,8
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	aesenc	%xmm15,%xmm11
+	movups	112(%r15),%xmm14
+	paddd	%xmm5,%xmm8
+	andl	%ebp,%esi
+	xorl	%eax,%ebp
+	psrldq	$4,%xmm10
+	xorl	%eax,%esi
+	addl	%ecx,%ebx
+	pxor	%xmm2,%xmm6
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	pxor	%xmm4,%xmm10
+	addl	36(%rsp),%eax
+	xorl	%ebp,%edx
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	pxor	%xmm10,%xmm6
+	andl	%edx,%edi
+	xorl	%ebp,%edx
+	movdqa	%xmm8,16(%rsp)
+	xorl	%ebp,%edi
+	addl	%ebx,%eax
+	movdqa	%xmm6,%xmm9
+	movdqa	%xmm6,%xmm10
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	addl	40(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	128(%r15),%xmm15
+	xorl	%edx,%ecx
+	pslldq	$12,%xmm9
+	paddd	%xmm6,%xmm6
+	movl	%eax,%edi
+	roll	$5,%eax
+	andl	%ecx,%esi
+	xorl	%edx,%ecx
+	psrld	$31,%xmm10
+	xorl	%edx,%esi
+	addl	%eax,%ebp
+	movdqa	%xmm9,%xmm8
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	psrld	$30,%xmm9
+	por	%xmm10,%xmm6
+	addl	44(%rsp),%edx
+	xorl	%ecx,%ebx
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	pslld	$2,%xmm8
+	pxor	%xmm9,%xmm6
+	andl	%ebx,%edi
+	xorl	%ecx,%ebx
+	movdqa	16(%r11),%xmm9
+	xorl	%ecx,%edi
+	aesenc	%xmm15,%xmm11
+	movups	144(%r15),%xmm14
+	addl	%ebp,%edx
+	pxor	%xmm8,%xmm6
+	rorl	$7,%eax
+	addl	%edi,%edx
+	movdqa	%xmm4,%xmm7
+	addl	48(%rsp),%ecx
+	xorl	%ebx,%eax
+	movdqa	%xmm6,%xmm8
+.byte	102,15,58,15,251,8
+	movl	%edx,%edi
+	roll	$5,%edx
+	paddd	%xmm6,%xmm9
+	andl	%eax,%esi
+	xorl	%ebx,%eax
+	psrldq	$4,%xmm8
+	xorl	%ebx,%esi
+	addl	%edx,%ecx
+	pxor	%xmm3,%xmm7
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	pxor	%xmm5,%xmm8
+	addl	52(%rsp),%ebx
+	xorl	%eax,%ebp
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	aesenc	%xmm14,%xmm11
+	movups	160(%r15),%xmm15
+	pxor	%xmm8,%xmm7
+	andl	%ebp,%edi
+	xorl	%eax,%ebp
+	movdqa	%xmm9,32(%rsp)
+	xorl	%eax,%edi
+	addl	%ecx,%ebx
+	movdqa	%xmm7,%xmm10
+	movdqa	%xmm7,%xmm8
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	addl	56(%rsp),%eax
+	xorl	%ebp,%edx
+	pslldq	$12,%xmm10
+	paddd	%xmm7,%xmm7
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	andl	%edx,%esi
+	xorl	%ebp,%edx
+	psrld	$31,%xmm8
+	xorl	%ebp,%esi
+	addl	%ebx,%eax
+	movdqa	%xmm10,%xmm9
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	psrld	$30,%xmm10
+	por	%xmm8,%xmm7
+	addl	60(%rsp),%ebp
+	cmpl	$11,%r8d
+	jb	L$aesenclast1
+	movups	176(%r15),%xmm14
+	aesenc	%xmm15,%xmm11
+	movups	192(%r15),%xmm15
+	aesenc	%xmm14,%xmm11
+	je	L$aesenclast1
+	movups	208(%r15),%xmm14
+	aesenc	%xmm15,%xmm11
+	movups	224(%r15),%xmm15
+	aesenc	%xmm14,%xmm11
+L$aesenclast1:
+	aesenclast	%xmm15,%xmm11
+	movups	16(%r15),%xmm14
+	xorl	%edx,%ecx
+	movl	%eax,%esi
+	roll	$5,%eax
+	pslld	$2,%xmm9
+	pxor	%xmm10,%xmm7
+	andl	%ecx,%edi
+	xorl	%edx,%ecx
+	movdqa	16(%r11),%xmm10
+	xorl	%edx,%edi
+	addl	%eax,%ebp
+	pxor	%xmm9,%xmm7
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	movdqa	%xmm7,%xmm9
+	addl	0(%rsp),%edx
+	pxor	%xmm4,%xmm0
+.byte	102,68,15,58,15,206,8
+	xorl	%ecx,%ebx
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	pxor	%xmm1,%xmm0
+	andl	%ebx,%esi
+	xorl	%ecx,%ebx
+	movdqa	%xmm10,%xmm8
+	paddd	%xmm7,%xmm10
+	xorl	%ecx,%esi
+	movups	16(%r12),%xmm12
+	xorps	%xmm13,%xmm12
+	movups	%xmm11,0(%r13,%r12,1)
+	xorps	%xmm12,%xmm11
+	aesenc	%xmm14,%xmm11
+	movups	32(%r15),%xmm15
+	addl	%ebp,%edx
+	pxor	%xmm9,%xmm0
+	rorl	$7,%eax
+	addl	%esi,%edx
+	addl	4(%rsp),%ecx
+	xorl	%ebx,%eax
+	movdqa	%xmm0,%xmm9
+	movdqa	%xmm10,48(%rsp)
+	movl	%edx,%esi
+	roll	$5,%edx
+	andl	%eax,%edi
+	xorl	%ebx,%eax
+	pslld	$2,%xmm0
+	xorl	%ebx,%edi
+	addl	%edx,%ecx
+	psrld	$30,%xmm9
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	addl	8(%rsp),%ebx
+	xorl	%eax,%ebp
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	aesenc	%xmm15,%xmm11
+	movups	48(%r15),%xmm14
+	por	%xmm9,%xmm0
+	andl	%ebp,%esi
+	xorl	%eax,%ebp
+	movdqa	%xmm0,%xmm10
+	xorl	%eax,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	addl	12(%rsp),%eax
+	xorl	%ebp,%edx
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	andl	%edx,%edi
+	xorl	%ebp,%edx
+	xorl	%ebp,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	addl	16(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	64(%r15),%xmm15
+	pxor	%xmm5,%xmm1
+.byte	102,68,15,58,15,215,8
+	xorl	%edx,%esi
+	movl	%eax,%edi
+	roll	$5,%eax
+	pxor	%xmm2,%xmm1
+	xorl	%ecx,%esi
+	addl	%eax,%ebp
+	movdqa	%xmm8,%xmm9
+	paddd	%xmm0,%xmm8
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	pxor	%xmm10,%xmm1
+	addl	20(%rsp),%edx
+	xorl	%ecx,%edi
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	movdqa	%xmm1,%xmm10
+	movdqa	%xmm8,0(%rsp)
+	xorl	%ebx,%edi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%edi,%edx
+	pslld	$2,%xmm1
+	addl	24(%rsp),%ecx
+	xorl	%ebx,%esi
+	psrld	$30,%xmm10
+	movl	%edx,%edi
+	roll	$5,%edx
+	xorl	%eax,%esi
+	aesenc	%xmm15,%xmm11
+	movups	80(%r15),%xmm14
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	por	%xmm10,%xmm1
+	addl	28(%rsp),%ebx
+	xorl	%eax,%edi
+	movdqa	%xmm1,%xmm8
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	xorl	%ebp,%edi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	addl	32(%rsp),%eax
+	pxor	%xmm6,%xmm2
+.byte	102,68,15,58,15,192,8
+	xorl	%ebp,%esi
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	pxor	%xmm3,%xmm2
+	xorl	%edx,%esi
+	addl	%ebx,%eax
+	movdqa	32(%r11),%xmm10
+	paddd	%xmm1,%xmm9
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	pxor	%xmm8,%xmm2
+	addl	36(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	96(%r15),%xmm15
+	xorl	%edx,%edi
+	movl	%eax,%esi
+	roll	$5,%eax
+	movdqa	%xmm2,%xmm8
+	movdqa	%xmm9,16(%rsp)
+	xorl	%ecx,%edi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	pslld	$2,%xmm2
+	addl	40(%rsp),%edx
+	xorl	%ecx,%esi
+	psrld	$30,%xmm8
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	xorl	%ebx,%esi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%esi,%edx
+	por	%xmm8,%xmm2
+	addl	44(%rsp),%ecx
+	xorl	%ebx,%edi
+	movdqa	%xmm2,%xmm9
+	movl	%edx,%esi
+	roll	$5,%edx
+	xorl	%eax,%edi
+	aesenc	%xmm15,%xmm11
+	movups	112(%r15),%xmm14
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	addl	48(%rsp),%ebx
+	pxor	%xmm7,%xmm3
+.byte	102,68,15,58,15,201,8
+	xorl	%eax,%esi
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	pxor	%xmm4,%xmm3
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	movdqa	%xmm10,%xmm8
+	paddd	%xmm2,%xmm10
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	pxor	%xmm9,%xmm3
+	addl	52(%rsp),%eax
+	xorl	%ebp,%edi
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	movdqa	%xmm3,%xmm9
+	movdqa	%xmm10,32(%rsp)
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	pslld	$2,%xmm3
+	addl	56(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	128(%r15),%xmm15
+	xorl	%edx,%esi
+	psrld	$30,%xmm9
+	movl	%eax,%edi
+	roll	$5,%eax
+	xorl	%ecx,%esi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	por	%xmm9,%xmm3
+	addl	60(%rsp),%edx
+	xorl	%ecx,%edi
+	movdqa	%xmm3,%xmm10
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	xorl	%ebx,%edi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%edi,%edx
+	addl	0(%rsp),%ecx
+	pxor	%xmm0,%xmm4
+.byte	102,68,15,58,15,210,8
+	xorl	%ebx,%esi
+	movl	%edx,%edi
+	roll	$5,%edx
+	pxor	%xmm5,%xmm4
+	xorl	%eax,%esi
+	aesenc	%xmm15,%xmm11
+	movups	144(%r15),%xmm14
+	addl	%edx,%ecx
+	movdqa	%xmm8,%xmm9
+	paddd	%xmm3,%xmm8
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	pxor	%xmm10,%xmm4
+	addl	4(%rsp),%ebx
+	xorl	%eax,%edi
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	movdqa	%xmm4,%xmm10
+	movdqa	%xmm8,48(%rsp)
+	xorl	%ebp,%edi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	pslld	$2,%xmm4
+	addl	8(%rsp),%eax
+	xorl	%ebp,%esi
+	psrld	$30,%xmm10
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	xorl	%edx,%esi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	por	%xmm10,%xmm4
+	addl	12(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	160(%r15),%xmm15
+	xorl	%edx,%edi
+	movdqa	%xmm4,%xmm8
+	movl	%eax,%esi
+	roll	$5,%eax
+	xorl	%ecx,%edi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	addl	16(%rsp),%edx
+	pxor	%xmm1,%xmm5
+.byte	102,68,15,58,15,195,8
+	xorl	%ecx,%esi
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	pxor	%xmm6,%xmm5
+	xorl	%ebx,%esi
+	addl	%ebp,%edx
+	movdqa	%xmm9,%xmm10
+	paddd	%xmm4,%xmm9
+	rorl	$7,%eax
+	addl	%esi,%edx
+	pxor	%xmm8,%xmm5
+	addl	20(%rsp),%ecx
+	xorl	%ebx,%edi
+	movl	%edx,%esi
+	roll	$5,%edx
+	movdqa	%xmm5,%xmm8
+	movdqa	%xmm9,0(%rsp)
+	xorl	%eax,%edi
+	cmpl	$11,%r8d
+	jb	L$aesenclast2
+	movups	176(%r15),%xmm14
+	aesenc	%xmm15,%xmm11
+	movups	192(%r15),%xmm15
+	aesenc	%xmm14,%xmm11
+	je	L$aesenclast2
+	movups	208(%r15),%xmm14
+	aesenc	%xmm15,%xmm11
+	movups	224(%r15),%xmm15
+	aesenc	%xmm14,%xmm11
+L$aesenclast2:
+	aesenclast	%xmm15,%xmm11
+	movups	16(%r15),%xmm14
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	pslld	$2,%xmm5
+	addl	24(%rsp),%ebx
+	xorl	%eax,%esi
+	psrld	$30,%xmm8
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	por	%xmm8,%xmm5
+	addl	28(%rsp),%eax
+	xorl	%ebp,%edi
+	movdqa	%xmm5,%xmm9
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	movl	%ecx,%edi
+	movups	32(%r12),%xmm12
+	xorps	%xmm13,%xmm12
+	movups	%xmm11,16(%r13,%r12,1)
+	xorps	%xmm12,%xmm11
+	aesenc	%xmm14,%xmm11
+	movups	32(%r15),%xmm15
+	pxor	%xmm2,%xmm6
+.byte	102,68,15,58,15,204,8
+	xorl	%edx,%ecx
+	addl	32(%rsp),%ebp
+	andl	%edx,%edi
+	pxor	%xmm7,%xmm6
+	andl	%ecx,%esi
+	rorl	$7,%ebx
+	movdqa	%xmm10,%xmm8
+	paddd	%xmm5,%xmm10
+	addl	%edi,%ebp
+	movl	%eax,%edi
+	pxor	%xmm9,%xmm6
+	roll	$5,%eax
+	addl	%esi,%ebp
+	xorl	%edx,%ecx
+	addl	%eax,%ebp
+	movdqa	%xmm6,%xmm9
+	movdqa	%xmm10,16(%rsp)
+	movl	%ebx,%esi
+	xorl	%ecx,%ebx
+	addl	36(%rsp),%edx
+	andl	%ecx,%esi
+	pslld	$2,%xmm6
+	andl	%ebx,%edi
+	rorl	$7,%eax
+	psrld	$30,%xmm9
+	addl	%esi,%edx
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	aesenc	%xmm15,%xmm11
+	movups	48(%r15),%xmm14
+	addl	%edi,%edx
+	xorl	%ecx,%ebx
+	addl	%ebp,%edx
+	por	%xmm9,%xmm6
+	movl	%eax,%edi
+	xorl	%ebx,%eax
+	movdqa	%xmm6,%xmm10
+	addl	40(%rsp),%ecx
+	andl	%ebx,%edi
+	andl	%eax,%esi
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	movl	%edx,%edi
+	roll	$5,%edx
+	addl	%esi,%ecx
+	xorl	%ebx,%eax
+	addl	%edx,%ecx
+	movl	%ebp,%esi
+	xorl	%eax,%ebp
+	addl	44(%rsp),%ebx
+	andl	%eax,%esi
+	andl	%ebp,%edi
+	aesenc	%xmm14,%xmm11
+	movups	64(%r15),%xmm15
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	addl	%edi,%ebx
+	xorl	%eax,%ebp
+	addl	%ecx,%ebx
+	movl	%edx,%edi
+	pxor	%xmm3,%xmm7
+.byte	102,68,15,58,15,213,8
+	xorl	%ebp,%edx
+	addl	48(%rsp),%eax
+	andl	%ebp,%edi
+	pxor	%xmm0,%xmm7
+	andl	%edx,%esi
+	rorl	$7,%ecx
+	movdqa	48(%r11),%xmm9
+	paddd	%xmm6,%xmm8
+	addl	%edi,%eax
+	movl	%ebx,%edi
+	pxor	%xmm10,%xmm7
+	roll	$5,%ebx
+	addl	%esi,%eax
+	xorl	%ebp,%edx
+	addl	%ebx,%eax
+	movdqa	%xmm7,%xmm10
+	movdqa	%xmm8,32(%rsp)
+	movl	%ecx,%esi
+	aesenc	%xmm15,%xmm11
+	movups	80(%r15),%xmm14
+	xorl	%edx,%ecx
+	addl	52(%rsp),%ebp
+	andl	%edx,%esi
+	pslld	$2,%xmm7
+	andl	%ecx,%edi
+	rorl	$7,%ebx
+	psrld	$30,%xmm10
+	addl	%esi,%ebp
+	movl	%eax,%esi
+	roll	$5,%eax
+	addl	%edi,%ebp
+	xorl	%edx,%ecx
+	addl	%eax,%ebp
+	por	%xmm10,%xmm7
+	movl	%ebx,%edi
+	xorl	%ecx,%ebx
+	movdqa	%xmm7,%xmm8
+	addl	56(%rsp),%edx
+	andl	%ecx,%edi
+	andl	%ebx,%esi
+	rorl	$7,%eax
+	addl	%edi,%edx
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	aesenc	%xmm14,%xmm11
+	movups	96(%r15),%xmm15
+	addl	%esi,%edx
+	xorl	%ecx,%ebx
+	addl	%ebp,%edx
+	movl	%eax,%esi
+	xorl	%ebx,%eax
+	addl	60(%rsp),%ecx
+	andl	%ebx,%esi
+	andl	%eax,%edi
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	movl	%edx,%esi
+	roll	$5,%edx
+	addl	%edi,%ecx
+	xorl	%ebx,%eax
+	addl	%edx,%ecx
+	movl	%ebp,%edi
+	pxor	%xmm4,%xmm0
+.byte	102,68,15,58,15,198,8
+	xorl	%eax,%ebp
+	addl	0(%rsp),%ebx
+	andl	%eax,%edi
+	pxor	%xmm1,%xmm0
+	andl	%ebp,%esi
+	aesenc	%xmm15,%xmm11
+	movups	112(%r15),%xmm14
+	rorl	$7,%edx
+	movdqa	%xmm9,%xmm10
+	paddd	%xmm7,%xmm9
+	addl	%edi,%ebx
+	movl	%ecx,%edi
+	pxor	%xmm8,%xmm0
+	roll	$5,%ecx
+	addl	%esi,%ebx
+	xorl	%eax,%ebp
+	addl	%ecx,%ebx
+	movdqa	%xmm0,%xmm8
+	movdqa	%xmm9,48(%rsp)
+	movl	%edx,%esi
+	xorl	%ebp,%edx
+	addl	4(%rsp),%eax
+	andl	%ebp,%esi
+	pslld	$2,%xmm0
+	andl	%edx,%edi
+	rorl	$7,%ecx
+	psrld	$30,%xmm8
+	addl	%esi,%eax
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	addl	%edi,%eax
+	xorl	%ebp,%edx
+	addl	%ebx,%eax
+	por	%xmm8,%xmm0
+	movl	%ecx,%edi
+	aesenc	%xmm14,%xmm11
+	movups	128(%r15),%xmm15
+	xorl	%edx,%ecx
+	movdqa	%xmm0,%xmm9
+	addl	8(%rsp),%ebp
+	andl	%edx,%edi
+	andl	%ecx,%esi
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	movl	%eax,%edi
+	roll	$5,%eax
+	addl	%esi,%ebp
+	xorl	%edx,%ecx
+	addl	%eax,%ebp
+	movl	%ebx,%esi
+	xorl	%ecx,%ebx
+	addl	12(%rsp),%edx
+	andl	%ecx,%esi
+	andl	%ebx,%edi
+	rorl	$7,%eax
+	addl	%esi,%edx
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	aesenc	%xmm15,%xmm11
+	movups	144(%r15),%xmm14
+	addl	%edi,%edx
+	xorl	%ecx,%ebx
+	addl	%ebp,%edx
+	movl	%eax,%edi
+	pxor	%xmm5,%xmm1
+.byte	102,68,15,58,15,207,8
+	xorl	%ebx,%eax
+	addl	16(%rsp),%ecx
+	andl	%ebx,%edi
+	pxor	%xmm2,%xmm1
+	andl	%eax,%esi
+	rorl	$7,%ebp
+	movdqa	%xmm10,%xmm8
+	paddd	%xmm0,%xmm10
+	addl	%edi,%ecx
+	movl	%edx,%edi
+	pxor	%xmm9,%xmm1
+	roll	$5,%edx
+	addl	%esi,%ecx
+	xorl	%ebx,%eax
+	addl	%edx,%ecx
+	movdqa	%xmm1,%xmm9
+	movdqa	%xmm10,0(%rsp)
+	movl	%ebp,%esi
+	xorl	%eax,%ebp
+	addl	20(%rsp),%ebx
+	andl	%eax,%esi
+	pslld	$2,%xmm1
+	andl	%ebp,%edi
+	aesenc	%xmm14,%xmm11
+	movups	160(%r15),%xmm15
+	rorl	$7,%edx
+	psrld	$30,%xmm9
+	addl	%esi,%ebx
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	addl	%edi,%ebx
+	xorl	%eax,%ebp
+	addl	%ecx,%ebx
+	por	%xmm9,%xmm1
+	movl	%edx,%edi
+	xorl	%ebp,%edx
+	movdqa	%xmm1,%xmm10
+	addl	24(%rsp),%eax
+	andl	%ebp,%edi
+	andl	%edx,%esi
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	addl	%esi,%eax
+	xorl	%ebp,%edx
+	addl	%ebx,%eax
+	movl	%ecx,%esi
+	cmpl	$11,%r8d
+	jb	L$aesenclast3
+	movups	176(%r15),%xmm14
+	aesenc	%xmm15,%xmm11
+	movups	192(%r15),%xmm15
+	aesenc	%xmm14,%xmm11
+	je	L$aesenclast3
+	movups	208(%r15),%xmm14
+	aesenc	%xmm15,%xmm11
+	movups	224(%r15),%xmm15
+	aesenc	%xmm14,%xmm11
+L$aesenclast3:
+	aesenclast	%xmm15,%xmm11
+	movups	16(%r15),%xmm14
+	xorl	%edx,%ecx
+	addl	28(%rsp),%ebp
+	andl	%edx,%esi
+	andl	%ecx,%edi
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	movl	%eax,%esi
+	roll	$5,%eax
+	addl	%edi,%ebp
+	xorl	%edx,%ecx
+	addl	%eax,%ebp
+	movl	%ebx,%edi
+	pxor	%xmm6,%xmm2
+.byte	102,68,15,58,15,208,8
+	xorl	%ecx,%ebx
+	addl	32(%rsp),%edx
+	andl	%ecx,%edi
+	pxor	%xmm3,%xmm2
+	andl	%ebx,%esi
+	rorl	$7,%eax
+	movdqa	%xmm8,%xmm9
+	paddd	%xmm1,%xmm8
+	addl	%edi,%edx
+	movl	%ebp,%edi
+	pxor	%xmm10,%xmm2
+	roll	$5,%ebp
+	movups	48(%r12),%xmm12
+	xorps	%xmm13,%xmm12
+	movups	%xmm11,32(%r13,%r12,1)
+	xorps	%xmm12,%xmm11
+	aesenc	%xmm14,%xmm11
+	movups	32(%r15),%xmm15
+	addl	%esi,%edx
+	xorl	%ecx,%ebx
+	addl	%ebp,%edx
+	movdqa	%xmm2,%xmm10
+	movdqa	%xmm8,16(%rsp)
+	movl	%eax,%esi
+	xorl	%ebx,%eax
+	addl	36(%rsp),%ecx
+	andl	%ebx,%esi
+	pslld	$2,%xmm2
+	andl	%eax,%edi
+	rorl	$7,%ebp
+	psrld	$30,%xmm10
+	addl	%esi,%ecx
+	movl	%edx,%esi
+	roll	$5,%edx
+	addl	%edi,%ecx
+	xorl	%ebx,%eax
+	addl	%edx,%ecx
+	por	%xmm10,%xmm2
+	movl	%ebp,%edi
+	xorl	%eax,%ebp
+	movdqa	%xmm2,%xmm8
+	addl	40(%rsp),%ebx
+	andl	%eax,%edi
+	andl	%ebp,%esi
+	aesenc	%xmm15,%xmm11
+	movups	48(%r15),%xmm14
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	addl	%esi,%ebx
+	xorl	%eax,%ebp
+	addl	%ecx,%ebx
+	movl	%edx,%esi
+	xorl	%ebp,%edx
+	addl	44(%rsp),%eax
+	andl	%ebp,%esi
+	andl	%edx,%edi
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	addl	%edi,%eax
+	xorl	%ebp,%edx
+	addl	%ebx,%eax
+	addl	48(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	64(%r15),%xmm15
+	pxor	%xmm7,%xmm3
+.byte	102,68,15,58,15,193,8
+	xorl	%edx,%esi
+	movl	%eax,%edi
+	roll	$5,%eax
+	pxor	%xmm4,%xmm3
+	xorl	%ecx,%esi
+	addl	%eax,%ebp
+	movdqa	%xmm9,%xmm10
+	paddd	%xmm2,%xmm9
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	pxor	%xmm8,%xmm3
+	addl	52(%rsp),%edx
+	xorl	%ecx,%edi
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	movdqa	%xmm3,%xmm8
+	movdqa	%xmm9,32(%rsp)
+	xorl	%ebx,%edi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%edi,%edx
+	pslld	$2,%xmm3
+	addl	56(%rsp),%ecx
+	xorl	%ebx,%esi
+	psrld	$30,%xmm8
+	movl	%edx,%edi
+	roll	$5,%edx
+	xorl	%eax,%esi
+	aesenc	%xmm15,%xmm11
+	movups	80(%r15),%xmm14
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	por	%xmm8,%xmm3
+	addl	60(%rsp),%ebx
+	xorl	%eax,%edi
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	xorl	%ebp,%edi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	addl	0(%rsp),%eax
+	paddd	%xmm3,%xmm10
+	xorl	%ebp,%esi
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	xorl	%edx,%esi
+	movdqa	%xmm10,48(%rsp)
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	addl	4(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	96(%r15),%xmm15
+	xorl	%edx,%edi
+	movl	%eax,%esi
+	roll	$5,%eax
+	xorl	%ecx,%edi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	addl	8(%rsp),%edx
+	xorl	%ecx,%esi
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	xorl	%ebx,%esi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%esi,%edx
+	addl	12(%rsp),%ecx
+	xorl	%ebx,%edi
+	movl	%edx,%esi
+	roll	$5,%edx
+	xorl	%eax,%edi
+	aesenc	%xmm15,%xmm11
+	movups	112(%r15),%xmm14
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	cmpq	%r14,%r10
+	je	L$done_ssse3
+	movdqa	64(%r11),%xmm6
+	movdqa	0(%r11),%xmm9
+	movdqu	0(%r10),%xmm0
+	movdqu	16(%r10),%xmm1
+	movdqu	32(%r10),%xmm2
+	movdqu	48(%r10),%xmm3
+.byte	102,15,56,0,198
+	addq	$64,%r10
+	addl	16(%rsp),%ebx
+	xorl	%eax,%esi
+.byte	102,15,56,0,206
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	paddd	%xmm9,%xmm0
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	movdqa	%xmm0,0(%rsp)
+	addl	20(%rsp),%eax
+	xorl	%ebp,%edi
+	psubd	%xmm9,%xmm0
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	addl	24(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	128(%r15),%xmm15
+	xorl	%edx,%esi
+	movl	%eax,%edi
+	roll	$5,%eax
+	xorl	%ecx,%esi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	addl	28(%rsp),%edx
+	xorl	%ecx,%edi
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	xorl	%ebx,%edi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%edi,%edx
+	addl	32(%rsp),%ecx
+	xorl	%ebx,%esi
+.byte	102,15,56,0,214
+	movl	%edx,%edi
+	roll	$5,%edx
+	paddd	%xmm9,%xmm1
+	xorl	%eax,%esi
+	aesenc	%xmm15,%xmm11
+	movups	144(%r15),%xmm14
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	movdqa	%xmm1,16(%rsp)
+	addl	36(%rsp),%ebx
+	xorl	%eax,%edi
+	psubd	%xmm9,%xmm1
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	xorl	%ebp,%edi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	addl	40(%rsp),%eax
+	xorl	%ebp,%esi
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	xorl	%edx,%esi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	addl	44(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	160(%r15),%xmm15
+	xorl	%edx,%edi
+	movl	%eax,%esi
+	roll	$5,%eax
+	xorl	%ecx,%edi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	addl	48(%rsp),%edx
+	xorl	%ecx,%esi
+.byte	102,15,56,0,222
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	paddd	%xmm9,%xmm2
+	xorl	%ebx,%esi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%esi,%edx
+	movdqa	%xmm2,32(%rsp)
+	addl	52(%rsp),%ecx
+	xorl	%ebx,%edi
+	psubd	%xmm9,%xmm2
+	movl	%edx,%esi
+	roll	$5,%edx
+	xorl	%eax,%edi
+	cmpl	$11,%r8d
+	jb	L$aesenclast4
+	movups	176(%r15),%xmm14
+	aesenc	%xmm15,%xmm11
+	movups	192(%r15),%xmm15
+	aesenc	%xmm14,%xmm11
+	je	L$aesenclast4
+	movups	208(%r15),%xmm14
+	aesenc	%xmm15,%xmm11
+	movups	224(%r15),%xmm15
+	aesenc	%xmm14,%xmm11
+L$aesenclast4:
+	aesenclast	%xmm15,%xmm11
+	movups	16(%r15),%xmm14
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	addl	56(%rsp),%ebx
+	xorl	%eax,%esi
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	addl	60(%rsp),%eax
+	xorl	%ebp,%edi
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	movups	%xmm11,48(%r13,%r12,1)
+	leaq	64(%r12),%r12
+
+	addl	0(%r9),%eax
+	addl	4(%r9),%esi
+	addl	8(%r9),%ecx
+	addl	12(%r9),%edx
+	movl	%eax,0(%r9)
+	addl	16(%r9),%ebp
+	movl	%esi,4(%r9)
+	movl	%esi,%ebx
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+	movl	%ebp,16(%r9)
+	jmp	L$oop_ssse3
+
+.p2align	4
+L$done_ssse3:
+	addl	16(%rsp),%ebx
+	xorl	%eax,%esi
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	addl	20(%rsp),%eax
+	xorl	%ebp,%edi
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	addl	24(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	128(%r15),%xmm15
+	xorl	%edx,%esi
+	movl	%eax,%edi
+	roll	$5,%eax
+	xorl	%ecx,%esi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	addl	28(%rsp),%edx
+	xorl	%ecx,%edi
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	xorl	%ebx,%edi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%edi,%edx
+	addl	32(%rsp),%ecx
+	xorl	%ebx,%esi
+	movl	%edx,%edi
+	roll	$5,%edx
+	xorl	%eax,%esi
+	aesenc	%xmm15,%xmm11
+	movups	144(%r15),%xmm14
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	addl	36(%rsp),%ebx
+	xorl	%eax,%edi
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	xorl	%ebp,%edi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	addl	40(%rsp),%eax
+	xorl	%ebp,%esi
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	xorl	%edx,%esi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	addl	44(%rsp),%ebp
+	aesenc	%xmm14,%xmm11
+	movups	160(%r15),%xmm15
+	xorl	%edx,%edi
+	movl	%eax,%esi
+	roll	$5,%eax
+	xorl	%ecx,%edi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	addl	48(%rsp),%edx
+	xorl	%ecx,%esi
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	xorl	%ebx,%esi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%esi,%edx
+	addl	52(%rsp),%ecx
+	xorl	%ebx,%edi
+	movl	%edx,%esi
+	roll	$5,%edx
+	xorl	%eax,%edi
+	cmpl	$11,%r8d
+	jb	L$aesenclast5
+	movups	176(%r15),%xmm14
+	aesenc	%xmm15,%xmm11
+	movups	192(%r15),%xmm15
+	aesenc	%xmm14,%xmm11
+	je	L$aesenclast5
+	movups	208(%r15),%xmm14
+	aesenc	%xmm15,%xmm11
+	movups	224(%r15),%xmm15
+	aesenc	%xmm14,%xmm11
+L$aesenclast5:
+	aesenclast	%xmm15,%xmm11
+	movups	16(%r15),%xmm14
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	addl	56(%rsp),%ebx
+	xorl	%eax,%esi
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	addl	60(%rsp),%eax
+	xorl	%ebp,%edi
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	movups	%xmm11,48(%r13,%r12,1)
+	movq	88(%rsp),%r8
+
+	addl	0(%r9),%eax
+	addl	4(%r9),%esi
+	addl	8(%r9),%ecx
+	movl	%eax,0(%r9)
+	addl	12(%r9),%edx
+	movl	%esi,4(%r9)
+	addl	16(%r9),%ebp
+	movl	%ecx,8(%r9)
+	movl	%edx,12(%r9)
+	movl	%ebp,16(%r9)
+	movups	%xmm11,(%r8)
+	leaq	104(%rsp),%rsi
+	movq	0(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+L$epilogue_ssse3:
+	.byte	0xf3,0xc3
+
+.p2align	6
+K_XX_XX:
+.long	0x5a827999,0x5a827999,0x5a827999,0x5a827999	
+.long	0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1	
+.long	0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc	
+.long	0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6	
+.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f	
+
+.byte	65,69,83,78,73,45,67,66,67,43,83,72,65,49,32,115,116,105,116,99,104,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.p2align	6
diff --git a/crypto/libressl/crypto/aes/bsaes-elf-x86_64.s b/crypto/libressl/crypto/aes/bsaes-elf-x86_64.s
new file mode 100644
index 0000000000..01fe7a9ad6
--- /dev/null
+++ b/crypto/libressl/crypto/aes/bsaes-elf-x86_64.s
@@ -0,0 +1,2501 @@
+.text	
+
+
+
+
+.type	_bsaes_encrypt8,@function
+.align	64
+_bsaes_encrypt8:
+	leaq	.LBS0(%rip),%r11
+
+	movdqa	(%rax),%xmm8
+	leaq	16(%rax),%rax
+	movdqa	80(%r11),%xmm7
+	pxor	%xmm8,%xmm15
+	pxor	%xmm8,%xmm0
+.byte	102,68,15,56,0,255
+	pxor	%xmm8,%xmm1
+.byte	102,15,56,0,199
+	pxor	%xmm8,%xmm2
+.byte	102,15,56,0,207
+	pxor	%xmm8,%xmm3
+.byte	102,15,56,0,215
+	pxor	%xmm8,%xmm4
+.byte	102,15,56,0,223
+	pxor	%xmm8,%xmm5
+.byte	102,15,56,0,231
+	pxor	%xmm8,%xmm6
+.byte	102,15,56,0,239
+.byte	102,15,56,0,247
+_bsaes_encrypt8_bitslice:
+	movdqa	0(%r11),%xmm7
+	movdqa	16(%r11),%xmm8
+	movdqa	%xmm5,%xmm9
+	psrlq	$1,%xmm5
+	movdqa	%xmm3,%xmm10
+	psrlq	$1,%xmm3
+	pxor	%xmm6,%xmm5
+	pxor	%xmm4,%xmm3
+	pand	%xmm7,%xmm5
+	pand	%xmm7,%xmm3
+	pxor	%xmm5,%xmm6
+	psllq	$1,%xmm5
+	pxor	%xmm3,%xmm4
+	psllq	$1,%xmm3
+	pxor	%xmm9,%xmm5
+	pxor	%xmm10,%xmm3
+	movdqa	%xmm1,%xmm9
+	psrlq	$1,%xmm1
+	movdqa	%xmm15,%xmm10
+	psrlq	$1,%xmm15
+	pxor	%xmm2,%xmm1
+	pxor	%xmm0,%xmm15
+	pand	%xmm7,%xmm1
+	pand	%xmm7,%xmm15
+	pxor	%xmm1,%xmm2
+	psllq	$1,%xmm1
+	pxor	%xmm15,%xmm0
+	psllq	$1,%xmm15
+	pxor	%xmm9,%xmm1
+	pxor	%xmm10,%xmm15
+	movdqa	32(%r11),%xmm7
+	movdqa	%xmm4,%xmm9
+	psrlq	$2,%xmm4
+	movdqa	%xmm3,%xmm10
+	psrlq	$2,%xmm3
+	pxor	%xmm6,%xmm4
+	pxor	%xmm5,%xmm3
+	pand	%xmm8,%xmm4
+	pand	%xmm8,%xmm3
+	pxor	%xmm4,%xmm6
+	psllq	$2,%xmm4
+	pxor	%xmm3,%xmm5
+	psllq	$2,%xmm3
+	pxor	%xmm9,%xmm4
+	pxor	%xmm10,%xmm3
+	movdqa	%xmm0,%xmm9
+	psrlq	$2,%xmm0
+	movdqa	%xmm15,%xmm10
+	psrlq	$2,%xmm15
+	pxor	%xmm2,%xmm0
+	pxor	%xmm1,%xmm15
+	pand	%xmm8,%xmm0
+	pand	%xmm8,%xmm15
+	pxor	%xmm0,%xmm2
+	psllq	$2,%xmm0
+	pxor	%xmm15,%xmm1
+	psllq	$2,%xmm15
+	pxor	%xmm9,%xmm0
+	pxor	%xmm10,%xmm15
+	movdqa	%xmm2,%xmm9
+	psrlq	$4,%xmm2
+	movdqa	%xmm1,%xmm10
+	psrlq	$4,%xmm1
+	pxor	%xmm6,%xmm2
+	pxor	%xmm5,%xmm1
+	pand	%xmm7,%xmm2
+	pand	%xmm7,%xmm1
+	pxor	%xmm2,%xmm6
+	psllq	$4,%xmm2
+	pxor	%xmm1,%xmm5
+	psllq	$4,%xmm1
+	pxor	%xmm9,%xmm2
+	pxor	%xmm10,%xmm1
+	movdqa	%xmm0,%xmm9
+	psrlq	$4,%xmm0
+	movdqa	%xmm15,%xmm10
+	psrlq	$4,%xmm15
+	pxor	%xmm4,%xmm0
+	pxor	%xmm3,%xmm15
+	pand	%xmm7,%xmm0
+	pand	%xmm7,%xmm15
+	pxor	%xmm0,%xmm4
+	psllq	$4,%xmm0
+	pxor	%xmm15,%xmm3
+	psllq	$4,%xmm15
+	pxor	%xmm9,%xmm0
+	pxor	%xmm10,%xmm15
+	decl	%r10d
+	jmp	.Lenc_sbox
+.align	16
+.Lenc_loop:
+	pxor	0(%rax),%xmm15
+	pxor	16(%rax),%xmm0
+.byte	102,68,15,56,0,255
+	pxor	32(%rax),%xmm1
+.byte	102,15,56,0,199
+	pxor	48(%rax),%xmm2
+.byte	102,15,56,0,207
+	pxor	64(%rax),%xmm3
+.byte	102,15,56,0,215
+	pxor	80(%rax),%xmm4
+.byte	102,15,56,0,223
+	pxor	96(%rax),%xmm5
+.byte	102,15,56,0,231
+	pxor	112(%rax),%xmm6
+.byte	102,15,56,0,239
+	leaq	128(%rax),%rax
+.byte	102,15,56,0,247
+.Lenc_sbox:
+	pxor	%xmm5,%xmm4
+	pxor	%xmm0,%xmm1
+	pxor	%xmm15,%xmm2
+	pxor	%xmm1,%xmm5
+	pxor	%xmm15,%xmm4
+
+	pxor	%xmm2,%xmm5
+	pxor	%xmm6,%xmm2
+	pxor	%xmm4,%xmm6
+	pxor	%xmm3,%xmm2
+	pxor	%xmm4,%xmm3
+	pxor	%xmm0,%xmm2
+
+	pxor	%xmm6,%xmm1
+	pxor	%xmm4,%xmm0
+	movdqa	%xmm6,%xmm10
+	movdqa	%xmm0,%xmm9
+	movdqa	%xmm4,%xmm8
+	movdqa	%xmm1,%xmm12
+	movdqa	%xmm5,%xmm11
+
+	pxor	%xmm3,%xmm10
+	pxor	%xmm1,%xmm9
+	pxor	%xmm2,%xmm8
+	movdqa	%xmm10,%xmm13
+	pxor	%xmm3,%xmm12
+	movdqa	%xmm9,%xmm7
+	pxor	%xmm15,%xmm11
+	movdqa	%xmm10,%xmm14
+
+	por	%xmm8,%xmm9
+	por	%xmm11,%xmm10
+	pxor	%xmm7,%xmm14
+	pand	%xmm11,%xmm13
+	pxor	%xmm8,%xmm11
+	pand	%xmm8,%xmm7
+	pand	%xmm11,%xmm14
+	movdqa	%xmm2,%xmm11
+	pxor	%xmm15,%xmm11
+	pand	%xmm11,%xmm12
+	pxor	%xmm12,%xmm10
+	pxor	%xmm12,%xmm9
+	movdqa	%xmm6,%xmm12
+	movdqa	%xmm4,%xmm11
+	pxor	%xmm0,%xmm12
+	pxor	%xmm5,%xmm11
+	movdqa	%xmm12,%xmm8
+	pand	%xmm11,%xmm12
+	por	%xmm11,%xmm8
+	pxor	%xmm12,%xmm7
+	pxor	%xmm14,%xmm10
+	pxor	%xmm13,%xmm9
+	pxor	%xmm14,%xmm8
+	movdqa	%xmm1,%xmm11
+	pxor	%xmm13,%xmm7
+	movdqa	%xmm3,%xmm12
+	pxor	%xmm13,%xmm8
+	movdqa	%xmm0,%xmm13
+	pand	%xmm2,%xmm11
+	movdqa	%xmm6,%xmm14
+	pand	%xmm15,%xmm12
+	pand	%xmm4,%xmm13
+	por	%xmm5,%xmm14
+	pxor	%xmm11,%xmm10
+	pxor	%xmm12,%xmm9
+	pxor	%xmm13,%xmm8
+	pxor	%xmm14,%xmm7
+
+
+
+
+
+	movdqa	%xmm10,%xmm11
+	pand	%xmm8,%xmm10
+	pxor	%xmm9,%xmm11
+
+	movdqa	%xmm7,%xmm13
+	movdqa	%xmm11,%xmm14
+	pxor	%xmm10,%xmm13
+	pand	%xmm13,%xmm14
+
+	movdqa	%xmm8,%xmm12
+	pxor	%xmm9,%xmm14
+	pxor	%xmm7,%xmm12
+
+	pxor	%xmm9,%xmm10
+
+	pand	%xmm10,%xmm12
+
+	movdqa	%xmm13,%xmm9
+	pxor	%xmm7,%xmm12
+
+	pxor	%xmm12,%xmm9
+	pxor	%xmm12,%xmm8
+
+	pand	%xmm7,%xmm9
+
+	pxor	%xmm9,%xmm13
+	pxor	%xmm9,%xmm8
+
+	pand	%xmm14,%xmm13
+
+	pxor	%xmm11,%xmm13
+	movdqa	%xmm5,%xmm11
+	movdqa	%xmm4,%xmm7
+	movdqa	%xmm14,%xmm9
+	pxor	%xmm13,%xmm9
+	pand	%xmm5,%xmm9
+	pxor	%xmm4,%xmm5
+	pand	%xmm14,%xmm4
+	pand	%xmm13,%xmm5
+	pxor	%xmm4,%xmm5
+	pxor	%xmm9,%xmm4
+	pxor	%xmm15,%xmm11
+	pxor	%xmm2,%xmm7
+	pxor	%xmm12,%xmm14
+	pxor	%xmm8,%xmm13
+	movdqa	%xmm14,%xmm10
+	movdqa	%xmm12,%xmm9
+	pxor	%xmm13,%xmm10
+	pxor	%xmm8,%xmm9
+	pand	%xmm11,%xmm10
+	pand	%xmm15,%xmm9
+	pxor	%xmm7,%xmm11
+	pxor	%xmm2,%xmm15
+	pand	%xmm14,%xmm7
+	pand	%xmm12,%xmm2
+	pand	%xmm13,%xmm11
+	pand	%xmm8,%xmm15
+	pxor	%xmm11,%xmm7
+	pxor	%xmm2,%xmm15
+	pxor	%xmm10,%xmm11
+	pxor	%xmm9,%xmm2
+	pxor	%xmm11,%xmm5
+	pxor	%xmm11,%xmm15
+	pxor	%xmm7,%xmm4
+	pxor	%xmm7,%xmm2
+
+	movdqa	%xmm6,%xmm11
+	movdqa	%xmm0,%xmm7
+	pxor	%xmm3,%xmm11
+	pxor	%xmm1,%xmm7
+	movdqa	%xmm14,%xmm10
+	movdqa	%xmm12,%xmm9
+	pxor	%xmm13,%xmm10
+	pxor	%xmm8,%xmm9
+	pand	%xmm11,%xmm10
+	pand	%xmm3,%xmm9
+	pxor	%xmm7,%xmm11
+	pxor	%xmm1,%xmm3
+	pand	%xmm14,%xmm7
+	pand	%xmm12,%xmm1
+	pand	%xmm13,%xmm11
+	pand	%xmm8,%xmm3
+	pxor	%xmm11,%xmm7
+	pxor	%xmm1,%xmm3
+	pxor	%xmm10,%xmm11
+	pxor	%xmm9,%xmm1
+	pxor	%xmm12,%xmm14
+	pxor	%xmm8,%xmm13
+	movdqa	%xmm14,%xmm10
+	pxor	%xmm13,%xmm10
+	pand	%xmm6,%xmm10
+	pxor	%xmm0,%xmm6
+	pand	%xmm14,%xmm0
+	pand	%xmm13,%xmm6
+	pxor	%xmm0,%xmm6
+	pxor	%xmm10,%xmm0
+	pxor	%xmm11,%xmm6
+	pxor	%xmm11,%xmm3
+	pxor	%xmm7,%xmm0
+	pxor	%xmm7,%xmm1
+	pxor	%xmm15,%xmm6
+	pxor	%xmm5,%xmm0
+	pxor	%xmm6,%xmm3
+	pxor	%xmm15,%xmm5
+	pxor	%xmm0,%xmm15
+
+	pxor	%xmm4,%xmm0
+	pxor	%xmm1,%xmm4
+	pxor	%xmm2,%xmm1
+	pxor	%xmm4,%xmm2
+	pxor	%xmm4,%xmm3
+
+	pxor	%xmm2,%xmm5
+	decl	%r10d
+	jl	.Lenc_done
+	pshufd	$147,%xmm15,%xmm7
+	pshufd	$147,%xmm0,%xmm8
+	pxor	%xmm7,%xmm15
+	pshufd	$147,%xmm3,%xmm9
+	pxor	%xmm8,%xmm0
+	pshufd	$147,%xmm5,%xmm10
+	pxor	%xmm9,%xmm3
+	pshufd	$147,%xmm2,%xmm11
+	pxor	%xmm10,%xmm5
+	pshufd	$147,%xmm6,%xmm12
+	pxor	%xmm11,%xmm2
+	pshufd	$147,%xmm1,%xmm13
+	pxor	%xmm12,%xmm6
+	pshufd	$147,%xmm4,%xmm14
+	pxor	%xmm13,%xmm1
+	pxor	%xmm14,%xmm4
+
+	pxor	%xmm15,%xmm8
+	pxor	%xmm4,%xmm7
+	pxor	%xmm4,%xmm8
+	pshufd	$78,%xmm15,%xmm15
+	pxor	%xmm0,%xmm9
+	pshufd	$78,%xmm0,%xmm0
+	pxor	%xmm2,%xmm12
+	pxor	%xmm7,%xmm15
+	pxor	%xmm6,%xmm13
+	pxor	%xmm8,%xmm0
+	pxor	%xmm5,%xmm11
+	pshufd	$78,%xmm2,%xmm7
+	pxor	%xmm1,%xmm14
+	pshufd	$78,%xmm6,%xmm8
+	pxor	%xmm3,%xmm10
+	pshufd	$78,%xmm5,%xmm2
+	pxor	%xmm4,%xmm10
+	pshufd	$78,%xmm4,%xmm6
+	pxor	%xmm4,%xmm11
+	pshufd	$78,%xmm1,%xmm5
+	pxor	%xmm11,%xmm7
+	pshufd	$78,%xmm3,%xmm1
+	pxor	%xmm12,%xmm8
+	pxor	%xmm10,%xmm2
+	pxor	%xmm14,%xmm6
+	pxor	%xmm13,%xmm5
+	movdqa	%xmm7,%xmm3
+	pxor	%xmm9,%xmm1
+	movdqa	%xmm8,%xmm4
+	movdqa	48(%r11),%xmm7
+	jnz	.Lenc_loop
+	movdqa	64(%r11),%xmm7
+	jmp	.Lenc_loop
+.align	16
+.Lenc_done:
+	movdqa	0(%r11),%xmm7
+	movdqa	16(%r11),%xmm8
+	movdqa	%xmm1,%xmm9
+	psrlq	$1,%xmm1
+	movdqa	%xmm2,%xmm10
+	psrlq	$1,%xmm2
+	pxor	%xmm4,%xmm1
+	pxor	%xmm6,%xmm2
+	pand	%xmm7,%xmm1
+	pand	%xmm7,%xmm2
+	pxor	%xmm1,%xmm4
+	psllq	$1,%xmm1
+	pxor	%xmm2,%xmm6
+	psllq	$1,%xmm2
+	pxor	%xmm9,%xmm1
+	pxor	%xmm10,%xmm2
+	movdqa	%xmm3,%xmm9
+	psrlq	$1,%xmm3
+	movdqa	%xmm15,%xmm10
+	psrlq	$1,%xmm15
+	pxor	%xmm5,%xmm3
+	pxor	%xmm0,%xmm15
+	pand	%xmm7,%xmm3
+	pand	%xmm7,%xmm15
+	pxor	%xmm3,%xmm5
+	psllq	$1,%xmm3
+	pxor	%xmm15,%xmm0
+	psllq	$1,%xmm15
+	pxor	%xmm9,%xmm3
+	pxor	%xmm10,%xmm15
+	movdqa	32(%r11),%xmm7
+	movdqa	%xmm6,%xmm9
+	psrlq	$2,%xmm6
+	movdqa	%xmm2,%xmm10
+	psrlq	$2,%xmm2
+	pxor	%xmm4,%xmm6
+	pxor	%xmm1,%xmm2
+	pand	%xmm8,%xmm6
+	pand	%xmm8,%xmm2
+	pxor	%xmm6,%xmm4
+	psllq	$2,%xmm6
+	pxor	%xmm2,%xmm1
+	psllq	$2,%xmm2
+	pxor	%xmm9,%xmm6
+	pxor	%xmm10,%xmm2
+	movdqa	%xmm0,%xmm9
+	psrlq	$2,%xmm0
+	movdqa	%xmm15,%xmm10
+	psrlq	$2,%xmm15
+	pxor	%xmm5,%xmm0
+	pxor	%xmm3,%xmm15
+	pand	%xmm8,%xmm0
+	pand	%xmm8,%xmm15
+	pxor	%xmm0,%xmm5
+	psllq	$2,%xmm0
+	pxor	%xmm15,%xmm3
+	psllq	$2,%xmm15
+	pxor	%xmm9,%xmm0
+	pxor	%xmm10,%xmm15
+	movdqa	%xmm5,%xmm9
+	psrlq	$4,%xmm5
+	movdqa	%xmm3,%xmm10
+	psrlq	$4,%xmm3
+	pxor	%xmm4,%xmm5
+	pxor	%xmm1,%xmm3
+	pand	%xmm7,%xmm5
+	pand	%xmm7,%xmm3
+	pxor	%xmm5,%xmm4
+	psllq	$4,%xmm5
+	pxor	%xmm3,%xmm1
+	psllq	$4,%xmm3
+	pxor	%xmm9,%xmm5
+	pxor	%xmm10,%xmm3
+	movdqa	%xmm0,%xmm9
+	psrlq	$4,%xmm0
+	movdqa	%xmm15,%xmm10
+	psrlq	$4,%xmm15
+	pxor	%xmm6,%xmm0
+	pxor	%xmm2,%xmm15
+	pand	%xmm7,%xmm0
+	pand	%xmm7,%xmm15
+	pxor	%xmm0,%xmm6
+	psllq	$4,%xmm0
+	pxor	%xmm15,%xmm2
+	psllq	$4,%xmm15
+	pxor	%xmm9,%xmm0
+	pxor	%xmm10,%xmm15
+	movdqa	(%rax),%xmm7
+	pxor	%xmm7,%xmm3
+	pxor	%xmm7,%xmm5
+	pxor	%xmm7,%xmm2
+	pxor	%xmm7,%xmm6
+	pxor	%xmm7,%xmm1
+	pxor	%xmm7,%xmm4
+	pxor	%xmm7,%xmm15
+	pxor	%xmm7,%xmm0
+	.byte	0xf3,0xc3
+.size	_bsaes_encrypt8,.-_bsaes_encrypt8
+
+.type	_bsaes_decrypt8,@function
+.align	64
+_bsaes_decrypt8:
+	leaq	.LBS0(%rip),%r11
+
+	movdqa	(%rax),%xmm8
+	leaq	16(%rax),%rax
+	movdqa	-48(%r11),%xmm7
+	pxor	%xmm8,%xmm15
+	pxor	%xmm8,%xmm0
+.byte	102,68,15,56,0,255
+	pxor	%xmm8,%xmm1
+.byte	102,15,56,0,199
+	pxor	%xmm8,%xmm2
+.byte	102,15,56,0,207
+	pxor	%xmm8,%xmm3
+.byte	102,15,56,0,215
+	pxor	%xmm8,%xmm4
+.byte	102,15,56,0,223
+	pxor	%xmm8,%xmm5
+.byte	102,15,56,0,231
+	pxor	%xmm8,%xmm6
+.byte	102,15,56,0,239
+.byte	102,15,56,0,247
+	movdqa	0(%r11),%xmm7
+	movdqa	16(%r11),%xmm8
+	movdqa	%xmm5,%xmm9
+	psrlq	$1,%xmm5
+	movdqa	%xmm3,%xmm10
+	psrlq	$1,%xmm3
+	pxor	%xmm6,%xmm5
+	pxor	%xmm4,%xmm3
+	pand	%xmm7,%xmm5
+	pand	%xmm7,%xmm3
+	pxor	%xmm5,%xmm6
+	psllq	$1,%xmm5
+	pxor	%xmm3,%xmm4
+	psllq	$1,%xmm3
+	pxor	%xmm9,%xmm5
+	pxor	%xmm10,%xmm3
+	movdqa	%xmm1,%xmm9
+	psrlq	$1,%xmm1
+	movdqa	%xmm15,%xmm10
+	psrlq	$1,%xmm15
+	pxor	%xmm2,%xmm1
+	pxor	%xmm0,%xmm15
+	pand	%xmm7,%xmm1
+	pand	%xmm7,%xmm15
+	pxor	%xmm1,%xmm2
+	psllq	$1,%xmm1
+	pxor	%xmm15,%xmm0
+	psllq	$1,%xmm15
+	pxor	%xmm9,%xmm1
+	pxor	%xmm10,%xmm15
+	movdqa	32(%r11),%xmm7
+	movdqa	%xmm4,%xmm9
+	psrlq	$2,%xmm4
+	movdqa	%xmm3,%xmm10
+	psrlq	$2,%xmm3
+	pxor	%xmm6,%xmm4
+	pxor	%xmm5,%xmm3
+	pand	%xmm8,%xmm4
+	pand	%xmm8,%xmm3
+	pxor	%xmm4,%xmm6
+	psllq	$2,%xmm4
+	pxor	%xmm3,%xmm5
+	psllq	$2,%xmm3
+	pxor	%xmm9,%xmm4
+	pxor	%xmm10,%xmm3
+	movdqa	%xmm0,%xmm9
+	psrlq	$2,%xmm0
+	movdqa	%xmm15,%xmm10
+	psrlq	$2,%xmm15
+	pxor	%xmm2,%xmm0
+	pxor	%xmm1,%xmm15
+	pand	%xmm8,%xmm0
+	pand	%xmm8,%xmm15
+	pxor	%xmm0,%xmm2
+	psllq	$2,%xmm0
+	pxor	%xmm15,%xmm1
+	psllq	$2,%xmm15
+	pxor	%xmm9,%xmm0
+	pxor	%xmm10,%xmm15
+	movdqa	%xmm2,%xmm9
+	psrlq	$4,%xmm2
+	movdqa	%xmm1,%xmm10
+	psrlq	$4,%xmm1
+	pxor	%xmm6,%xmm2
+	pxor	%xmm5,%xmm1
+	pand	%xmm7,%xmm2
+	pand	%xmm7,%xmm1
+	pxor	%xmm2,%xmm6
+	psllq	$4,%xmm2
+	pxor	%xmm1,%xmm5
+	psllq	$4,%xmm1
+	pxor	%xmm9,%xmm2
+	pxor	%xmm10,%xmm1
+	movdqa	%xmm0,%xmm9
+	psrlq	$4,%xmm0
+	movdqa	%xmm15,%xmm10
+	psrlq	$4,%xmm15
+	pxor	%xmm4,%xmm0
+	pxor	%xmm3,%xmm15
+	pand	%xmm7,%xmm0
+	pand	%xmm7,%xmm15
+	pxor	%xmm0,%xmm4
+	psllq	$4,%xmm0
+	pxor	%xmm15,%xmm3
+	psllq	$4,%xmm15
+	pxor	%xmm9,%xmm0
+	pxor	%xmm10,%xmm15
+	decl	%r10d
+	jmp	.Ldec_sbox
+.align	16
+.Ldec_loop:
+	pxor	0(%rax),%xmm15
+	pxor	16(%rax),%xmm0
+.byte	102,68,15,56,0,255
+	pxor	32(%rax),%xmm1
+.byte	102,15,56,0,199
+	pxor	48(%rax),%xmm2
+.byte	102,15,56,0,207
+	pxor	64(%rax),%xmm3
+.byte	102,15,56,0,215
+	pxor	80(%rax),%xmm4
+.byte	102,15,56,0,223
+	pxor	96(%rax),%xmm5
+.byte	102,15,56,0,231
+	pxor	112(%rax),%xmm6
+.byte	102,15,56,0,239
+	leaq	128(%rax),%rax
+.byte	102,15,56,0,247
+.Ldec_sbox:
+	pxor	%xmm3,%xmm2
+
+	pxor	%xmm6,%xmm3
+	pxor	%xmm6,%xmm1
+	pxor	%xmm3,%xmm5
+	pxor	%xmm5,%xmm6
+	pxor	%xmm6,%xmm0
+
+	pxor	%xmm0,%xmm15
+	pxor	%xmm4,%xmm1
+	pxor	%xmm15,%xmm2
+	pxor	%xmm15,%xmm4
+	pxor	%xmm2,%xmm0
+	movdqa	%xmm2,%xmm10
+	movdqa	%xmm6,%xmm9
+	movdqa	%xmm0,%xmm8
+	movdqa	%xmm3,%xmm12
+	movdqa	%xmm4,%xmm11
+
+	pxor	%xmm15,%xmm10
+	pxor	%xmm3,%xmm9
+	pxor	%xmm5,%xmm8
+	movdqa	%xmm10,%xmm13
+	pxor	%xmm15,%xmm12
+	movdqa	%xmm9,%xmm7
+	pxor	%xmm1,%xmm11
+	movdqa	%xmm10,%xmm14
+
+	por	%xmm8,%xmm9
+	por	%xmm11,%xmm10
+	pxor	%xmm7,%xmm14
+	pand	%xmm11,%xmm13
+	pxor	%xmm8,%xmm11
+	pand	%xmm8,%xmm7
+	pand	%xmm11,%xmm14
+	movdqa	%xmm5,%xmm11
+	pxor	%xmm1,%xmm11
+	pand	%xmm11,%xmm12
+	pxor	%xmm12,%xmm10
+	pxor	%xmm12,%xmm9
+	movdqa	%xmm2,%xmm12
+	movdqa	%xmm0,%xmm11
+	pxor	%xmm6,%xmm12
+	pxor	%xmm4,%xmm11
+	movdqa	%xmm12,%xmm8
+	pand	%xmm11,%xmm12
+	por	%xmm11,%xmm8
+	pxor	%xmm12,%xmm7
+	pxor	%xmm14,%xmm10
+	pxor	%xmm13,%xmm9
+	pxor	%xmm14,%xmm8
+	movdqa	%xmm3,%xmm11
+	pxor	%xmm13,%xmm7
+	movdqa	%xmm15,%xmm12
+	pxor	%xmm13,%xmm8
+	movdqa	%xmm6,%xmm13
+	pand	%xmm5,%xmm11
+	movdqa	%xmm2,%xmm14
+	pand	%xmm1,%xmm12
+	pand	%xmm0,%xmm13
+	por	%xmm4,%xmm14
+	pxor	%xmm11,%xmm10
+	pxor	%xmm12,%xmm9
+	pxor	%xmm13,%xmm8
+	pxor	%xmm14,%xmm7
+
+
+
+
+
+	movdqa	%xmm10,%xmm11
+	pand	%xmm8,%xmm10
+	pxor	%xmm9,%xmm11
+
+	movdqa	%xmm7,%xmm13
+	movdqa	%xmm11,%xmm14
+	pxor	%xmm10,%xmm13
+	pand	%xmm13,%xmm14
+
+	movdqa	%xmm8,%xmm12
+	pxor	%xmm9,%xmm14
+	pxor	%xmm7,%xmm12
+
+	pxor	%xmm9,%xmm10
+
+	pand	%xmm10,%xmm12
+
+	movdqa	%xmm13,%xmm9
+	pxor	%xmm7,%xmm12
+
+	pxor	%xmm12,%xmm9
+	pxor	%xmm12,%xmm8
+
+	pand	%xmm7,%xmm9
+
+	pxor	%xmm9,%xmm13
+	pxor	%xmm9,%xmm8
+
+	pand	%xmm14,%xmm13
+
+	pxor	%xmm11,%xmm13
+	movdqa	%xmm4,%xmm11
+	movdqa	%xmm0,%xmm7
+	movdqa	%xmm14,%xmm9
+	pxor	%xmm13,%xmm9
+	pand	%xmm4,%xmm9
+	pxor	%xmm0,%xmm4
+	pand	%xmm14,%xmm0
+	pand	%xmm13,%xmm4
+	pxor	%xmm0,%xmm4
+	pxor	%xmm9,%xmm0
+	pxor	%xmm1,%xmm11
+	pxor	%xmm5,%xmm7
+	pxor	%xmm12,%xmm14
+	pxor	%xmm8,%xmm13
+	movdqa	%xmm14,%xmm10
+	movdqa	%xmm12,%xmm9
+	pxor	%xmm13,%xmm10
+	pxor	%xmm8,%xmm9
+	pand	%xmm11,%xmm10
+	pand	%xmm1,%xmm9
+	pxor	%xmm7,%xmm11
+	pxor	%xmm5,%xmm1
+	pand	%xmm14,%xmm7
+	pand	%xmm12,%xmm5
+	pand	%xmm13,%xmm11
+	pand	%xmm8,%xmm1
+	pxor	%xmm11,%xmm7
+	pxor	%xmm5,%xmm1
+	pxor	%xmm10,%xmm11
+	pxor	%xmm9,%xmm5
+	pxor	%xmm11,%xmm4
+	pxor	%xmm11,%xmm1
+	pxor	%xmm7,%xmm0
+	pxor	%xmm7,%xmm5
+
+	movdqa	%xmm2,%xmm11
+	movdqa	%xmm6,%xmm7
+	pxor	%xmm15,%xmm11
+	pxor	%xmm3,%xmm7
+	movdqa	%xmm14,%xmm10
+	movdqa	%xmm12,%xmm9
+	pxor	%xmm13,%xmm10
+	pxor	%xmm8,%xmm9
+	pand	%xmm11,%xmm10
+	pand	%xmm15,%xmm9
+	pxor	%xmm7,%xmm11
+	pxor	%xmm3,%xmm15
+	pand	%xmm14,%xmm7
+	pand	%xmm12,%xmm3
+	pand	%xmm13,%xmm11
+	pand	%xmm8,%xmm15
+	pxor	%xmm11,%xmm7
+	pxor	%xmm3,%xmm15
+	pxor	%xmm10,%xmm11
+	pxor	%xmm9,%xmm3
+	pxor	%xmm12,%xmm14
+	pxor	%xmm8,%xmm13
+	movdqa	%xmm14,%xmm10
+	pxor	%xmm13,%xmm10
+	pand	%xmm2,%xmm10
+	pxor	%xmm6,%xmm2
+	pand	%xmm14,%xmm6
+	pand	%xmm13,%xmm2
+	pxor	%xmm6,%xmm2
+	pxor	%xmm10,%xmm6
+	pxor	%xmm11,%xmm2
+	pxor	%xmm11,%xmm15
+	pxor	%xmm7,%xmm6
+	pxor	%xmm7,%xmm3
+	pxor	%xmm6,%xmm0
+	pxor	%xmm4,%xmm5
+
+	pxor	%xmm0,%xmm3
+	pxor	%xmm6,%xmm1
+	pxor	%xmm6,%xmm4
+	pxor	%xmm1,%xmm3
+	pxor	%xmm15,%xmm6
+	pxor	%xmm4,%xmm3
+	pxor	%xmm5,%xmm2
+	pxor	%xmm0,%xmm5
+	pxor	%xmm3,%xmm2
+
+	pxor	%xmm15,%xmm3
+	pxor	%xmm2,%xmm6
+	decl	%r10d
+	jl	.Ldec_done
+
+	pshufd	$78,%xmm15,%xmm7
+	pshufd	$78,%xmm2,%xmm13
+	pxor	%xmm15,%xmm7
+	pshufd	$78,%xmm4,%xmm14
+	pxor	%xmm2,%xmm13
+	pshufd	$78,%xmm0,%xmm8
+	pxor	%xmm4,%xmm14
+	pshufd	$78,%xmm5,%xmm9
+	pxor	%xmm0,%xmm8
+	pshufd	$78,%xmm3,%xmm10
+	pxor	%xmm5,%xmm9
+	pxor	%xmm13,%xmm15
+	pxor	%xmm13,%xmm0
+	pshufd	$78,%xmm1,%xmm11
+	pxor	%xmm3,%xmm10
+	pxor	%xmm7,%xmm5
+	pxor	%xmm8,%xmm3
+	pshufd	$78,%xmm6,%xmm12
+	pxor	%xmm1,%xmm11
+	pxor	%xmm14,%xmm0
+	pxor	%xmm9,%xmm1
+	pxor	%xmm6,%xmm12
+
+	pxor	%xmm14,%xmm5
+	pxor	%xmm13,%xmm3
+	pxor	%xmm13,%xmm1
+	pxor	%xmm10,%xmm6
+	pxor	%xmm11,%xmm2
+	pxor	%xmm14,%xmm1
+	pxor	%xmm14,%xmm6
+	pxor	%xmm12,%xmm4
+	pshufd	$147,%xmm15,%xmm7
+	pshufd	$147,%xmm0,%xmm8
+	pxor	%xmm7,%xmm15
+	pshufd	$147,%xmm5,%xmm9
+	pxor	%xmm8,%xmm0
+	pshufd	$147,%xmm3,%xmm10
+	pxor	%xmm9,%xmm5
+	pshufd	$147,%xmm1,%xmm11
+	pxor	%xmm10,%xmm3
+	pshufd	$147,%xmm6,%xmm12
+	pxor	%xmm11,%xmm1
+	pshufd	$147,%xmm2,%xmm13
+	pxor	%xmm12,%xmm6
+	pshufd	$147,%xmm4,%xmm14
+	pxor	%xmm13,%xmm2
+	pxor	%xmm14,%xmm4
+
+	pxor	%xmm15,%xmm8
+	pxor	%xmm4,%xmm7
+	pxor	%xmm4,%xmm8
+	pshufd	$78,%xmm15,%xmm15
+	pxor	%xmm0,%xmm9
+	pshufd	$78,%xmm0,%xmm0
+	pxor	%xmm1,%xmm12
+	pxor	%xmm7,%xmm15
+	pxor	%xmm6,%xmm13
+	pxor	%xmm8,%xmm0
+	pxor	%xmm3,%xmm11
+	pshufd	$78,%xmm1,%xmm7
+	pxor	%xmm2,%xmm14
+	pshufd	$78,%xmm6,%xmm8
+	pxor	%xmm5,%xmm10
+	pshufd	$78,%xmm3,%xmm1
+	pxor	%xmm4,%xmm10
+	pshufd	$78,%xmm4,%xmm6
+	pxor	%xmm4,%xmm11
+	pshufd	$78,%xmm2,%xmm3
+	pxor	%xmm11,%xmm7
+	pshufd	$78,%xmm5,%xmm2
+	pxor	%xmm12,%xmm8
+	pxor	%xmm1,%xmm10
+	pxor	%xmm14,%xmm6
+	pxor	%xmm3,%xmm13
+	movdqa	%xmm7,%xmm3
+	pxor	%xmm9,%xmm2
+	movdqa	%xmm13,%xmm5
+	movdqa	%xmm8,%xmm4
+	movdqa	%xmm2,%xmm1
+	movdqa	%xmm10,%xmm2
+	movdqa	-16(%r11),%xmm7
+	jnz	.Ldec_loop
+	movdqa	-32(%r11),%xmm7
+	jmp	.Ldec_loop
+.align	16
+.Ldec_done:
+	movdqa	0(%r11),%xmm7
+	movdqa	16(%r11),%xmm8
+	movdqa	%xmm2,%xmm9
+	psrlq	$1,%xmm2
+	movdqa	%xmm1,%xmm10
+	psrlq	$1,%xmm1
+	pxor	%xmm4,%xmm2
+	pxor	%xmm6,%xmm1
+	pand	%xmm7,%xmm2
+	pand	%xmm7,%xmm1
+	pxor	%xmm2,%xmm4
+	psllq	$1,%xmm2
+	pxor	%xmm1,%xmm6
+	psllq	$1,%xmm1
+	pxor	%xmm9,%xmm2
+	pxor	%xmm10,%xmm1
+	movdqa	%xmm5,%xmm9
+	psrlq	$1,%xmm5
+	movdqa	%xmm15,%xmm10
+	psrlq	$1,%xmm15
+	pxor	%xmm3,%xmm5
+	pxor	%xmm0,%xmm15
+	pand	%xmm7,%xmm5
+	pand	%xmm7,%xmm15
+	pxor	%xmm5,%xmm3
+	psllq	$1,%xmm5
+	pxor	%xmm15,%xmm0
+	psllq	$1,%xmm15
+	pxor	%xmm9,%xmm5
+	pxor	%xmm10,%xmm15
+	movdqa	32(%r11),%xmm7
+	movdqa	%xmm6,%xmm9
+	psrlq	$2,%xmm6
+	movdqa	%xmm1,%xmm10
+	psrlq	$2,%xmm1
+	pxor	%xmm4,%xmm6
+	pxor	%xmm2,%xmm1
+	pand	%xmm8,%xmm6
+	pand	%xmm8,%xmm1
+	pxor	%xmm6,%xmm4
+	psllq	$2,%xmm6
+	pxor	%xmm1,%xmm2
+	psllq	$2,%xmm1
+	pxor	%xmm9,%xmm6
+	pxor	%xmm10,%xmm1
+	movdqa	%xmm0,%xmm9
+	psrlq	$2,%xmm0
+	movdqa	%xmm15,%xmm10
+	psrlq	$2,%xmm15
+	pxor	%xmm3,%xmm0
+	pxor	%xmm5,%xmm15
+	pand	%xmm8,%xmm0
+	pand	%xmm8,%xmm15
+	pxor	%xmm0,%xmm3
+	psllq	$2,%xmm0
+	pxor	%xmm15,%xmm5
+	psllq	$2,%xmm15
+	pxor	%xmm9,%xmm0
+	pxor	%xmm10,%xmm15
+	movdqa	%xmm3,%xmm9
+	psrlq	$4,%xmm3
+	movdqa	%xmm5,%xmm10
+	psrlq	$4,%xmm5
+	pxor	%xmm4,%xmm3
+	pxor	%xmm2,%xmm5
+	pand	%xmm7,%xmm3
+	pand	%xmm7,%xmm5
+	pxor	%xmm3,%xmm4
+	psllq	$4,%xmm3
+	pxor	%xmm5,%xmm2
+	psllq	$4,%xmm5
+	pxor	%xmm9,%xmm3
+	pxor	%xmm10,%xmm5
+	movdqa	%xmm0,%xmm9
+	psrlq	$4,%xmm0
+	movdqa	%xmm15,%xmm10
+	psrlq	$4,%xmm15
+	pxor	%xmm6,%xmm0
+	pxor	%xmm1,%xmm15
+	pand	%xmm7,%xmm0
+	pand	%xmm7,%xmm15
+	pxor	%xmm0,%xmm6
+	psllq	$4,%xmm0
+	pxor	%xmm15,%xmm1
+	psllq	$4,%xmm15
+	pxor	%xmm9,%xmm0
+	pxor	%xmm10,%xmm15
+	movdqa	(%rax),%xmm7
+	pxor	%xmm7,%xmm5
+	pxor	%xmm7,%xmm3
+	pxor	%xmm7,%xmm1
+	pxor	%xmm7,%xmm6
+	pxor	%xmm7,%xmm2
+	pxor	%xmm7,%xmm4
+	pxor	%xmm7,%xmm15
+	pxor	%xmm7,%xmm0
+	.byte	0xf3,0xc3
+.size	_bsaes_decrypt8,.-_bsaes_decrypt8
+.type	_bsaes_key_convert,@function
+.align	16
+_bsaes_key_convert:
+	leaq	.Lmasks(%rip),%r11
+	movdqu	(%rcx),%xmm7
+	leaq	16(%rcx),%rcx
+	movdqa	0(%r11),%xmm0
+	movdqa	16(%r11),%xmm1
+	movdqa	32(%r11),%xmm2
+	movdqa	48(%r11),%xmm3
+	movdqa	64(%r11),%xmm4
+	pcmpeqd	%xmm5,%xmm5
+
+	movdqu	(%rcx),%xmm6
+	movdqa	%xmm7,(%rax)
+	leaq	16(%rax),%rax
+	decl	%r10d
+	jmp	.Lkey_loop
+.align	16
+.Lkey_loop:
+.byte	102,15,56,0,244
+
+	movdqa	%xmm0,%xmm8
+	movdqa	%xmm1,%xmm9
+
+	pand	%xmm6,%xmm8
+	pand	%xmm6,%xmm9
+	movdqa	%xmm2,%xmm10
+	pcmpeqb	%xmm0,%xmm8
+	psllq	$4,%xmm0
+	movdqa	%xmm3,%xmm11
+	pcmpeqb	%xmm1,%xmm9
+	psllq	$4,%xmm1
+
+	pand	%xmm6,%xmm10
+	pand	%xmm6,%xmm11
+	movdqa	%xmm0,%xmm12
+	pcmpeqb	%xmm2,%xmm10
+	psllq	$4,%xmm2
+	movdqa	%xmm1,%xmm13
+	pcmpeqb	%xmm3,%xmm11
+	psllq	$4,%xmm3
+
+	movdqa	%xmm2,%xmm14
+	movdqa	%xmm3,%xmm15
+	pxor	%xmm5,%xmm8
+	pxor	%xmm5,%xmm9
+
+	pand	%xmm6,%xmm12
+	pand	%xmm6,%xmm13
+	movdqa	%xmm8,0(%rax)
+	pcmpeqb	%xmm0,%xmm12
+	psrlq	$4,%xmm0
+	movdqa	%xmm9,16(%rax)
+	pcmpeqb	%xmm1,%xmm13
+	psrlq	$4,%xmm1
+	leaq	16(%rcx),%rcx
+
+	pand	%xmm6,%xmm14
+	pand	%xmm6,%xmm15
+	movdqa	%xmm10,32(%rax)
+	pcmpeqb	%xmm2,%xmm14
+	psrlq	$4,%xmm2
+	movdqa	%xmm11,48(%rax)
+	pcmpeqb	%xmm3,%xmm15
+	psrlq	$4,%xmm3
+	movdqu	(%rcx),%xmm6
+
+	pxor	%xmm5,%xmm13
+	pxor	%xmm5,%xmm14
+	movdqa	%xmm12,64(%rax)
+	movdqa	%xmm13,80(%rax)
+	movdqa	%xmm14,96(%rax)
+	movdqa	%xmm15,112(%rax)
+	leaq	128(%rax),%rax
+	decl	%r10d
+	jnz	.Lkey_loop
+
+	movdqa	80(%r11),%xmm7
+
+	.byte	0xf3,0xc3
+.size	_bsaes_key_convert,.-_bsaes_key_convert
+
+.globl	bsaes_cbc_encrypt
+.type	bsaes_cbc_encrypt,@function
+.align	16
+bsaes_cbc_encrypt:
+	cmpl	$0,%r9d
+	jne	asm_AES_cbc_encrypt
+	cmpq	$128,%rdx
+	jb	asm_AES_cbc_encrypt
+
+	movq	%rsp,%rax
+.Lcbc_dec_prologue:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	leaq	-72(%rsp),%rsp
+	movq	%rsp,%rbp
+	movl	240(%rcx),%eax
+	movq	%rdi,%r12
+	movq	%rsi,%r13
+	movq	%rdx,%r14
+	movq	%rcx,%r15
+	movq	%r8,%rbx
+	shrq	$4,%r14
+
+	movl	%eax,%edx
+	shlq	$7,%rax
+	subq	$96,%rax
+	subq	%rax,%rsp
+
+	movq	%rsp,%rax
+	movq	%r15,%rcx
+	movl	%edx,%r10d
+	call	_bsaes_key_convert
+	pxor	(%rsp),%xmm7
+	movdqa	%xmm6,(%rax)
+	movdqa	%xmm7,(%rsp)
+
+	movdqu	(%rbx),%xmm14
+	subq	$8,%r14
+.Lcbc_dec_loop:
+	movdqu	0(%r12),%xmm15
+	movdqu	16(%r12),%xmm0
+	movdqu	32(%r12),%xmm1
+	movdqu	48(%r12),%xmm2
+	movdqu	64(%r12),%xmm3
+	movdqu	80(%r12),%xmm4
+	movq	%rsp,%rax
+	movdqu	96(%r12),%xmm5
+	movl	%edx,%r10d
+	movdqu	112(%r12),%xmm6
+	movdqa	%xmm14,32(%rbp)
+
+	call	_bsaes_decrypt8
+
+	pxor	32(%rbp),%xmm15
+	movdqu	0(%r12),%xmm7
+	movdqu	16(%r12),%xmm8
+	pxor	%xmm7,%xmm0
+	movdqu	32(%r12),%xmm9
+	pxor	%xmm8,%xmm5
+	movdqu	48(%r12),%xmm10
+	pxor	%xmm9,%xmm3
+	movdqu	64(%r12),%xmm11
+	pxor	%xmm10,%xmm1
+	movdqu	80(%r12),%xmm12
+	pxor	%xmm11,%xmm6
+	movdqu	96(%r12),%xmm13
+	pxor	%xmm12,%xmm2
+	movdqu	112(%r12),%xmm14
+	pxor	%xmm13,%xmm4
+	movdqu	%xmm15,0(%r13)
+	leaq	128(%r12),%r12
+	movdqu	%xmm0,16(%r13)
+	movdqu	%xmm5,32(%r13)
+	movdqu	%xmm3,48(%r13)
+	movdqu	%xmm1,64(%r13)
+	movdqu	%xmm6,80(%r13)
+	movdqu	%xmm2,96(%r13)
+	movdqu	%xmm4,112(%r13)
+	leaq	128(%r13),%r13
+	subq	$8,%r14
+	jnc	.Lcbc_dec_loop
+
+	addq	$8,%r14
+	jz	.Lcbc_dec_done
+
+	movdqu	0(%r12),%xmm15
+	movq	%rsp,%rax
+	movl	%edx,%r10d
+	cmpq	$2,%r14
+	jb	.Lcbc_dec_one
+	movdqu	16(%r12),%xmm0
+	je	.Lcbc_dec_two
+	movdqu	32(%r12),%xmm1
+	cmpq	$4,%r14
+	jb	.Lcbc_dec_three
+	movdqu	48(%r12),%xmm2
+	je	.Lcbc_dec_four
+	movdqu	64(%r12),%xmm3
+	cmpq	$6,%r14
+	jb	.Lcbc_dec_five
+	movdqu	80(%r12),%xmm4
+	je	.Lcbc_dec_six
+	movdqu	96(%r12),%xmm5
+	movdqa	%xmm14,32(%rbp)
+	call	_bsaes_decrypt8
+	pxor	32(%rbp),%xmm15
+	movdqu	0(%r12),%xmm7
+	movdqu	16(%r12),%xmm8
+	pxor	%xmm7,%xmm0
+	movdqu	32(%r12),%xmm9
+	pxor	%xmm8,%xmm5
+	movdqu	48(%r12),%xmm10
+	pxor	%xmm9,%xmm3
+	movdqu	64(%r12),%xmm11
+	pxor	%xmm10,%xmm1
+	movdqu	80(%r12),%xmm12
+	pxor	%xmm11,%xmm6
+	movdqu	96(%r12),%xmm14
+	pxor	%xmm12,%xmm2
+	movdqu	%xmm15,0(%r13)
+	movdqu	%xmm0,16(%r13)
+	movdqu	%xmm5,32(%r13)
+	movdqu	%xmm3,48(%r13)
+	movdqu	%xmm1,64(%r13)
+	movdqu	%xmm6,80(%r13)
+	movdqu	%xmm2,96(%r13)
+	jmp	.Lcbc_dec_done
+.align	16
+.Lcbc_dec_six:
+	movdqa	%xmm14,32(%rbp)
+	call	_bsaes_decrypt8
+	pxor	32(%rbp),%xmm15
+	movdqu	0(%r12),%xmm7
+	movdqu	16(%r12),%xmm8
+	pxor	%xmm7,%xmm0
+	movdqu	32(%r12),%xmm9
+	pxor	%xmm8,%xmm5
+	movdqu	48(%r12),%xmm10
+	pxor	%xmm9,%xmm3
+	movdqu	64(%r12),%xmm11
+	pxor	%xmm10,%xmm1
+	movdqu	80(%r12),%xmm14
+	pxor	%xmm11,%xmm6
+	movdqu	%xmm15,0(%r13)
+	movdqu	%xmm0,16(%r13)
+	movdqu	%xmm5,32(%r13)
+	movdqu	%xmm3,48(%r13)
+	movdqu	%xmm1,64(%r13)
+	movdqu	%xmm6,80(%r13)
+	jmp	.Lcbc_dec_done
+.align	16
+.Lcbc_dec_five:
+	movdqa	%xmm14,32(%rbp)
+	call	_bsaes_decrypt8
+	pxor	32(%rbp),%xmm15
+	movdqu	0(%r12),%xmm7
+	movdqu	16(%r12),%xmm8
+	pxor	%xmm7,%xmm0
+	movdqu	32(%r12),%xmm9
+	pxor	%xmm8,%xmm5
+	movdqu	48(%r12),%xmm10
+	pxor	%xmm9,%xmm3
+	movdqu	64(%r12),%xmm14
+	pxor	%xmm10,%xmm1
+	movdqu	%xmm15,0(%r13)
+	movdqu	%xmm0,16(%r13)
+	movdqu	%xmm5,32(%r13)
+	movdqu	%xmm3,48(%r13)
+	movdqu	%xmm1,64(%r13)
+	jmp	.Lcbc_dec_done
+.align	16
+.Lcbc_dec_four:
+	movdqa	%xmm14,32(%rbp)
+	call	_bsaes_decrypt8
+	pxor	32(%rbp),%xmm15
+	movdqu	0(%r12),%xmm7
+	movdqu	16(%r12),%xmm8
+	pxor	%xmm7,%xmm0
+	movdqu	32(%r12),%xmm9
+	pxor	%xmm8,%xmm5
+	movdqu	48(%r12),%xmm14
+	pxor	%xmm9,%xmm3
+	movdqu	%xmm15,0(%r13)
+	movdqu	%xmm0,16(%r13)
+	movdqu	%xmm5,32(%r13)
+	movdqu	%xmm3,48(%r13)
+	jmp	.Lcbc_dec_done
+.align	16
+.Lcbc_dec_three:
+	movdqa	%xmm14,32(%rbp)
+	call	_bsaes_decrypt8
+	pxor	32(%rbp),%xmm15
+	movdqu	0(%r12),%xmm7
+	movdqu	16(%r12),%xmm8
+	pxor	%xmm7,%xmm0
+	movdqu	32(%r12),%xmm14
+	pxor	%xmm8,%xmm5
+	movdqu	%xmm15,0(%r13)
+	movdqu	%xmm0,16(%r13)
+	movdqu	%xmm5,32(%r13)
+	jmp	.Lcbc_dec_done
+.align	16
+.Lcbc_dec_two:
+	movdqa	%xmm14,32(%rbp)
+	call	_bsaes_decrypt8
+	pxor	32(%rbp),%xmm15
+	movdqu	0(%r12),%xmm7
+	movdqu	16(%r12),%xmm14
+	pxor	%xmm7,%xmm0
+	movdqu	%xmm15,0(%r13)
+	movdqu	%xmm0,16(%r13)
+	jmp	.Lcbc_dec_done
+.align	16
+.Lcbc_dec_one:
+	leaq	(%r12),%rdi
+	leaq	32(%rbp),%rsi
+	leaq	(%r15),%rdx
+	call	asm_AES_decrypt		
+	pxor	32(%rbp),%xmm14
+	movdqu	%xmm14,(%r13)
+	movdqa	%xmm15,%xmm14
+
+.Lcbc_dec_done:
+	movdqu	%xmm14,(%rbx)
+	leaq	(%rsp),%rax
+	pxor	%xmm0,%xmm0
+.Lcbc_dec_bzero:
+	movdqa	%xmm0,0(%rax)
+	movdqa	%xmm0,16(%rax)
+	leaq	32(%rax),%rax
+	cmpq	%rax,%rbp
+	ja	.Lcbc_dec_bzero
+
+	leaq	(%rbp),%rsp
+	movq	72(%rsp),%r15
+	movq	80(%rsp),%r14
+	movq	88(%rsp),%r13
+	movq	96(%rsp),%r12
+	movq	104(%rsp),%rbx
+	movq	112(%rsp),%rax
+	leaq	120(%rsp),%rsp
+	movq	%rax,%rbp
+.Lcbc_dec_epilogue:
+	.byte	0xf3,0xc3
+.size	bsaes_cbc_encrypt,.-bsaes_cbc_encrypt
+
+.globl	bsaes_ctr32_encrypt_blocks
+.type	bsaes_ctr32_encrypt_blocks,@function
+.align	16
+bsaes_ctr32_encrypt_blocks:
+	movq	%rsp,%rax
+.Lctr_enc_prologue:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	leaq	-72(%rsp),%rsp
+	movq	%rsp,%rbp
+	movdqu	(%r8),%xmm0
+	movl	240(%rcx),%eax
+	movq	%rdi,%r12
+	movq	%rsi,%r13
+	movq	%rdx,%r14
+	movq	%rcx,%r15
+	movdqa	%xmm0,32(%rbp)
+	cmpq	$8,%rdx
+	jb	.Lctr_enc_short
+
+	movl	%eax,%ebx
+	shlq	$7,%rax
+	subq	$96,%rax
+	subq	%rax,%rsp
+
+	movq	%rsp,%rax
+	movq	%r15,%rcx
+	movl	%ebx,%r10d
+	call	_bsaes_key_convert
+	pxor	%xmm6,%xmm7
+	movdqa	%xmm7,(%rax)
+
+	movdqa	(%rsp),%xmm8
+	leaq	.LADD1(%rip),%r11
+	movdqa	32(%rbp),%xmm15
+	movdqa	-32(%r11),%xmm7
+.byte	102,68,15,56,0,199
+.byte	102,68,15,56,0,255
+	movdqa	%xmm8,(%rsp)
+	jmp	.Lctr_enc_loop
+.align	16
+.Lctr_enc_loop:
+	movdqa	%xmm15,32(%rbp)
+	movdqa	%xmm15,%xmm0
+	movdqa	%xmm15,%xmm1
+	paddd	0(%r11),%xmm0
+	movdqa	%xmm15,%xmm2
+	paddd	16(%r11),%xmm1
+	movdqa	%xmm15,%xmm3
+	paddd	32(%r11),%xmm2
+	movdqa	%xmm15,%xmm4
+	paddd	48(%r11),%xmm3
+	movdqa	%xmm15,%xmm5
+	paddd	64(%r11),%xmm4
+	movdqa	%xmm15,%xmm6
+	paddd	80(%r11),%xmm5
+	paddd	96(%r11),%xmm6
+
+
+
+	movdqa	(%rsp),%xmm8
+	leaq	16(%rsp),%rax
+	movdqa	-16(%r11),%xmm7
+	pxor	%xmm8,%xmm15
+	pxor	%xmm8,%xmm0
+.byte	102,68,15,56,0,255
+	pxor	%xmm8,%xmm1
+.byte	102,15,56,0,199
+	pxor	%xmm8,%xmm2
+.byte	102,15,56,0,207
+	pxor	%xmm8,%xmm3
+.byte	102,15,56,0,215
+	pxor	%xmm8,%xmm4
+.byte	102,15,56,0,223
+	pxor	%xmm8,%xmm5
+.byte	102,15,56,0,231
+	pxor	%xmm8,%xmm6
+.byte	102,15,56,0,239
+	leaq	.LBS0(%rip),%r11
+.byte	102,15,56,0,247
+	movl	%ebx,%r10d
+
+	call	_bsaes_encrypt8_bitslice
+
+	subq	$8,%r14
+	jc	.Lctr_enc_loop_done
+
+	movdqu	0(%r12),%xmm7
+	movdqu	16(%r12),%xmm8
+	movdqu	32(%r12),%xmm9
+	movdqu	48(%r12),%xmm10
+	movdqu	64(%r12),%xmm11
+	movdqu	80(%r12),%xmm12
+	movdqu	96(%r12),%xmm13
+	movdqu	112(%r12),%xmm14
+	leaq	128(%r12),%r12
+	pxor	%xmm15,%xmm7
+	movdqa	32(%rbp),%xmm15
+	pxor	%xmm8,%xmm0
+	movdqu	%xmm7,0(%r13)
+	pxor	%xmm9,%xmm3
+	movdqu	%xmm0,16(%r13)
+	pxor	%xmm10,%xmm5
+	movdqu	%xmm3,32(%r13)
+	pxor	%xmm11,%xmm2
+	movdqu	%xmm5,48(%r13)
+	pxor	%xmm12,%xmm6
+	movdqu	%xmm2,64(%r13)
+	pxor	%xmm13,%xmm1
+	movdqu	%xmm6,80(%r13)
+	pxor	%xmm14,%xmm4
+	movdqu	%xmm1,96(%r13)
+	leaq	.LADD1(%rip),%r11
+	movdqu	%xmm4,112(%r13)
+	leaq	128(%r13),%r13
+	paddd	112(%r11),%xmm15
+	jnz	.Lctr_enc_loop
+
+	jmp	.Lctr_enc_done
+.align	16
+.Lctr_enc_loop_done:
+	addq	$8,%r14
+	movdqu	0(%r12),%xmm7
+	pxor	%xmm7,%xmm15
+	movdqu	%xmm15,0(%r13)
+	cmpq	$2,%r14
+	jb	.Lctr_enc_done
+	movdqu	16(%r12),%xmm8
+	pxor	%xmm8,%xmm0
+	movdqu	%xmm0,16(%r13)
+	je	.Lctr_enc_done
+	movdqu	32(%r12),%xmm9
+	pxor	%xmm9,%xmm3
+	movdqu	%xmm3,32(%r13)
+	cmpq	$4,%r14
+	jb	.Lctr_enc_done
+	movdqu	48(%r12),%xmm10
+	pxor	%xmm10,%xmm5
+	movdqu	%xmm5,48(%r13)
+	je	.Lctr_enc_done
+	movdqu	64(%r12),%xmm11
+	pxor	%xmm11,%xmm2
+	movdqu	%xmm2,64(%r13)
+	cmpq	$6,%r14
+	jb	.Lctr_enc_done
+	movdqu	80(%r12),%xmm12
+	pxor	%xmm12,%xmm6
+	movdqu	%xmm6,80(%r13)
+	je	.Lctr_enc_done
+	movdqu	96(%r12),%xmm13
+	pxor	%xmm13,%xmm1
+	movdqu	%xmm1,96(%r13)
+	jmp	.Lctr_enc_done
+
+.align	16
+.Lctr_enc_short:
+	leaq	32(%rbp),%rdi
+	leaq	48(%rbp),%rsi
+	leaq	(%r15),%rdx
+	call	asm_AES_encrypt
+	movdqu	(%r12),%xmm0
+	leaq	16(%r12),%r12
+	movl	44(%rbp),%eax
+	bswapl	%eax
+	pxor	48(%rbp),%xmm0
+	incl	%eax
+	movdqu	%xmm0,(%r13)
+	bswapl	%eax
+	leaq	16(%r13),%r13
+	movl	%eax,44(%rsp)
+	decq	%r14
+	jnz	.Lctr_enc_short
+
+.Lctr_enc_done:
+	leaq	(%rsp),%rax
+	pxor	%xmm0,%xmm0
+.Lctr_enc_bzero:
+	movdqa	%xmm0,0(%rax)
+	movdqa	%xmm0,16(%rax)
+	leaq	32(%rax),%rax
+	cmpq	%rax,%rbp
+	ja	.Lctr_enc_bzero
+
+	leaq	(%rbp),%rsp
+	movq	72(%rsp),%r15
+	movq	80(%rsp),%r14
+	movq	88(%rsp),%r13
+	movq	96(%rsp),%r12
+	movq	104(%rsp),%rbx
+	movq	112(%rsp),%rax
+	leaq	120(%rsp),%rsp
+	movq	%rax,%rbp
+.Lctr_enc_epilogue:
+	.byte	0xf3,0xc3
+.size	bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks
+.globl	bsaes_xts_encrypt
+.type	bsaes_xts_encrypt,@function
+.align	16
+bsaes_xts_encrypt:
+	movq	%rsp,%rax
+.Lxts_enc_prologue:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	leaq	-72(%rsp),%rsp
+	movq	%rsp,%rbp
+	movq	%rdi,%r12
+	movq	%rsi,%r13
+	movq	%rdx,%r14
+	movq	%rcx,%r15
+
+	leaq	(%r9),%rdi
+	leaq	32(%rbp),%rsi
+	leaq	(%r8),%rdx
+	call	asm_AES_encrypt		
+
+	movl	240(%r15),%eax
+	movq	%r14,%rbx
+
+	movl	%eax,%edx
+	shlq	$7,%rax
+	subq	$96,%rax
+	subq	%rax,%rsp
+
+	movq	%rsp,%rax
+	movq	%r15,%rcx
+	movl	%edx,%r10d
+	call	_bsaes_key_convert
+	pxor	%xmm6,%xmm7
+	movdqa	%xmm7,(%rax)
+
+	andq	$-16,%r14
+	subq	$128,%rsp
+	movdqa	32(%rbp),%xmm6
+
+	pxor	%xmm14,%xmm14
+	movdqa	.Lxts_magic(%rip),%xmm12
+	pcmpgtd	%xmm6,%xmm14
+
+	subq	$128,%r14
+	jc	.Lxts_enc_short
+	jmp	.Lxts_enc_loop
+
+.align	16
+.Lxts_enc_loop:
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm15
+	movdqa	%xmm6,0(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm0
+	movdqa	%xmm6,16(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	0(%r12),%xmm7
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm1
+	movdqa	%xmm6,32(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	16(%r12),%xmm8
+	pxor	%xmm7,%xmm15
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm2
+	movdqa	%xmm6,48(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	32(%r12),%xmm9
+	pxor	%xmm8,%xmm0
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm3
+	movdqa	%xmm6,64(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	48(%r12),%xmm10
+	pxor	%xmm9,%xmm1
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm4
+	movdqa	%xmm6,80(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	64(%r12),%xmm11
+	pxor	%xmm10,%xmm2
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm5
+	movdqa	%xmm6,96(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	80(%r12),%xmm12
+	pxor	%xmm11,%xmm3
+	movdqu	96(%r12),%xmm13
+	pxor	%xmm12,%xmm4
+	movdqu	112(%r12),%xmm14
+	leaq	128(%r12),%r12
+	movdqa	%xmm6,112(%rsp)
+	pxor	%xmm13,%xmm5
+	leaq	128(%rsp),%rax
+	pxor	%xmm14,%xmm6
+	movl	%edx,%r10d
+
+	call	_bsaes_encrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm3
+	movdqu	%xmm0,16(%r13)
+	pxor	48(%rsp),%xmm5
+	movdqu	%xmm3,32(%r13)
+	pxor	64(%rsp),%xmm2
+	movdqu	%xmm5,48(%r13)
+	pxor	80(%rsp),%xmm6
+	movdqu	%xmm2,64(%r13)
+	pxor	96(%rsp),%xmm1
+	movdqu	%xmm6,80(%r13)
+	pxor	112(%rsp),%xmm4
+	movdqu	%xmm1,96(%r13)
+	movdqu	%xmm4,112(%r13)
+	leaq	128(%r13),%r13
+
+	movdqa	112(%rsp),%xmm6
+	pxor	%xmm14,%xmm14
+	movdqa	.Lxts_magic(%rip),%xmm12
+	pcmpgtd	%xmm6,%xmm14
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+
+	subq	$128,%r14
+	jnc	.Lxts_enc_loop
+
+.Lxts_enc_short:
+	addq	$128,%r14
+	jz	.Lxts_enc_done
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm15
+	movdqa	%xmm6,0(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm0
+	movdqa	%xmm6,16(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	0(%r12),%xmm7
+	cmpq	$16,%r14
+	je	.Lxts_enc_1
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm1
+	movdqa	%xmm6,32(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	16(%r12),%xmm8
+	cmpq	$32,%r14
+	je	.Lxts_enc_2
+	pxor	%xmm7,%xmm15
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm2
+	movdqa	%xmm6,48(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	32(%r12),%xmm9
+	cmpq	$48,%r14
+	je	.Lxts_enc_3
+	pxor	%xmm8,%xmm0
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm3
+	movdqa	%xmm6,64(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	48(%r12),%xmm10
+	cmpq	$64,%r14
+	je	.Lxts_enc_4
+	pxor	%xmm9,%xmm1
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm4
+	movdqa	%xmm6,80(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	64(%r12),%xmm11
+	cmpq	$80,%r14
+	je	.Lxts_enc_5
+	pxor	%xmm10,%xmm2
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm5
+	movdqa	%xmm6,96(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	80(%r12),%xmm12
+	cmpq	$96,%r14
+	je	.Lxts_enc_6
+	pxor	%xmm11,%xmm3
+	movdqu	96(%r12),%xmm13
+	pxor	%xmm12,%xmm4
+	movdqa	%xmm6,112(%rsp)
+	leaq	112(%r12),%r12
+	pxor	%xmm13,%xmm5
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_encrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm3
+	movdqu	%xmm0,16(%r13)
+	pxor	48(%rsp),%xmm5
+	movdqu	%xmm3,32(%r13)
+	pxor	64(%rsp),%xmm2
+	movdqu	%xmm5,48(%r13)
+	pxor	80(%rsp),%xmm6
+	movdqu	%xmm2,64(%r13)
+	pxor	96(%rsp),%xmm1
+	movdqu	%xmm6,80(%r13)
+	movdqu	%xmm1,96(%r13)
+	leaq	112(%r13),%r13
+
+	movdqa	112(%rsp),%xmm6
+	jmp	.Lxts_enc_done
+.align	16
+.Lxts_enc_6:
+	pxor	%xmm11,%xmm3
+	leaq	96(%r12),%r12
+	pxor	%xmm12,%xmm4
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_encrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm3
+	movdqu	%xmm0,16(%r13)
+	pxor	48(%rsp),%xmm5
+	movdqu	%xmm3,32(%r13)
+	pxor	64(%rsp),%xmm2
+	movdqu	%xmm5,48(%r13)
+	pxor	80(%rsp),%xmm6
+	movdqu	%xmm2,64(%r13)
+	movdqu	%xmm6,80(%r13)
+	leaq	96(%r13),%r13
+
+	movdqa	96(%rsp),%xmm6
+	jmp	.Lxts_enc_done
+.align	16
+.Lxts_enc_5:
+	pxor	%xmm10,%xmm2
+	leaq	80(%r12),%r12
+	pxor	%xmm11,%xmm3
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_encrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm3
+	movdqu	%xmm0,16(%r13)
+	pxor	48(%rsp),%xmm5
+	movdqu	%xmm3,32(%r13)
+	pxor	64(%rsp),%xmm2
+	movdqu	%xmm5,48(%r13)
+	movdqu	%xmm2,64(%r13)
+	leaq	80(%r13),%r13
+
+	movdqa	80(%rsp),%xmm6
+	jmp	.Lxts_enc_done
+.align	16
+.Lxts_enc_4:
+	pxor	%xmm9,%xmm1
+	leaq	64(%r12),%r12
+	pxor	%xmm10,%xmm2
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_encrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm3
+	movdqu	%xmm0,16(%r13)
+	pxor	48(%rsp),%xmm5
+	movdqu	%xmm3,32(%r13)
+	movdqu	%xmm5,48(%r13)
+	leaq	64(%r13),%r13
+
+	movdqa	64(%rsp),%xmm6
+	jmp	.Lxts_enc_done
+.align	16
+.Lxts_enc_3:
+	pxor	%xmm8,%xmm0
+	leaq	48(%r12),%r12
+	pxor	%xmm9,%xmm1
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_encrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm3
+	movdqu	%xmm0,16(%r13)
+	movdqu	%xmm3,32(%r13)
+	leaq	48(%r13),%r13
+
+	movdqa	48(%rsp),%xmm6
+	jmp	.Lxts_enc_done
+.align	16
+.Lxts_enc_2:
+	pxor	%xmm7,%xmm15
+	leaq	32(%r12),%r12
+	pxor	%xmm8,%xmm0
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_encrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	movdqu	%xmm0,16(%r13)
+	leaq	32(%r13),%r13
+
+	movdqa	32(%rsp),%xmm6
+	jmp	.Lxts_enc_done
+.align	16
+.Lxts_enc_1:
+	pxor	%xmm15,%xmm7
+	leaq	16(%r12),%r12
+	movdqa	%xmm7,32(%rbp)
+	leaq	32(%rbp),%rdi
+	leaq	32(%rbp),%rsi
+	leaq	(%r15),%rdx
+	call	asm_AES_encrypt		
+	pxor	32(%rbp),%xmm15
+
+
+
+
+
+	movdqu	%xmm15,0(%r13)
+	leaq	16(%r13),%r13
+
+	movdqa	16(%rsp),%xmm6
+
+.Lxts_enc_done:
+	andl	$15,%ebx
+	jz	.Lxts_enc_ret
+	movq	%r13,%rdx
+
+.Lxts_enc_steal:
+	movzbl	(%r12),%eax
+	movzbl	-16(%rdx),%ecx
+	leaq	1(%r12),%r12
+	movb	%al,-16(%rdx)
+	movb	%cl,0(%rdx)
+	leaq	1(%rdx),%rdx
+	subl	$1,%ebx
+	jnz	.Lxts_enc_steal
+
+	movdqu	-16(%r13),%xmm15
+	leaq	32(%rbp),%rdi
+	pxor	%xmm6,%xmm15
+	leaq	32(%rbp),%rsi
+	movdqa	%xmm15,32(%rbp)
+	leaq	(%r15),%rdx
+	call	asm_AES_encrypt		
+	pxor	32(%rbp),%xmm6
+	movdqu	%xmm6,-16(%r13)
+
+.Lxts_enc_ret:
+	leaq	(%rsp),%rax
+	pxor	%xmm0,%xmm0
+.Lxts_enc_bzero:
+	movdqa	%xmm0,0(%rax)
+	movdqa	%xmm0,16(%rax)
+	leaq	32(%rax),%rax
+	cmpq	%rax,%rbp
+	ja	.Lxts_enc_bzero
+
+	leaq	(%rbp),%rsp
+	movq	72(%rsp),%r15
+	movq	80(%rsp),%r14
+	movq	88(%rsp),%r13
+	movq	96(%rsp),%r12
+	movq	104(%rsp),%rbx
+	movq	112(%rsp),%rax
+	leaq	120(%rsp),%rsp
+	movq	%rax,%rbp
+.Lxts_enc_epilogue:
+	.byte	0xf3,0xc3
+.size	bsaes_xts_encrypt,.-bsaes_xts_encrypt
+
+.globl	bsaes_xts_decrypt
+.type	bsaes_xts_decrypt,@function
+.align	16
+bsaes_xts_decrypt:
+	movq	%rsp,%rax
+.Lxts_dec_prologue:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	leaq	-72(%rsp),%rsp
+	movq	%rsp,%rbp
+	movq	%rdi,%r12
+	movq	%rsi,%r13
+	movq	%rdx,%r14
+	movq	%rcx,%r15
+
+	leaq	(%r9),%rdi
+	leaq	32(%rbp),%rsi
+	leaq	(%r8),%rdx
+	call	asm_AES_encrypt		
+
+	movl	240(%r15),%eax
+	movq	%r14,%rbx
+
+	movl	%eax,%edx
+	shlq	$7,%rax
+	subq	$96,%rax
+	subq	%rax,%rsp
+
+	movq	%rsp,%rax
+	movq	%r15,%rcx
+	movl	%edx,%r10d
+	call	_bsaes_key_convert
+	pxor	(%rsp),%xmm7
+	movdqa	%xmm6,(%rax)
+	movdqa	%xmm7,(%rsp)
+
+	xorl	%eax,%eax
+	andq	$-16,%r14
+	testl	$15,%ebx
+	setnz	%al
+	shlq	$4,%rax
+	subq	%rax,%r14
+
+	subq	$128,%rsp
+	movdqa	32(%rbp),%xmm6
+
+	pxor	%xmm14,%xmm14
+	movdqa	.Lxts_magic(%rip),%xmm12
+	pcmpgtd	%xmm6,%xmm14
+
+	subq	$128,%r14
+	jc	.Lxts_dec_short
+	jmp	.Lxts_dec_loop
+
+.align	16
+.Lxts_dec_loop:
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm15
+	movdqa	%xmm6,0(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm0
+	movdqa	%xmm6,16(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	0(%r12),%xmm7
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm1
+	movdqa	%xmm6,32(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	16(%r12),%xmm8
+	pxor	%xmm7,%xmm15
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm2
+	movdqa	%xmm6,48(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	32(%r12),%xmm9
+	pxor	%xmm8,%xmm0
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm3
+	movdqa	%xmm6,64(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	48(%r12),%xmm10
+	pxor	%xmm9,%xmm1
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm4
+	movdqa	%xmm6,80(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	64(%r12),%xmm11
+	pxor	%xmm10,%xmm2
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm5
+	movdqa	%xmm6,96(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	80(%r12),%xmm12
+	pxor	%xmm11,%xmm3
+	movdqu	96(%r12),%xmm13
+	pxor	%xmm12,%xmm4
+	movdqu	112(%r12),%xmm14
+	leaq	128(%r12),%r12
+	movdqa	%xmm6,112(%rsp)
+	pxor	%xmm13,%xmm5
+	leaq	128(%rsp),%rax
+	pxor	%xmm14,%xmm6
+	movl	%edx,%r10d
+
+	call	_bsaes_decrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm5
+	movdqu	%xmm0,16(%r13)
+	pxor	48(%rsp),%xmm3
+	movdqu	%xmm5,32(%r13)
+	pxor	64(%rsp),%xmm1
+	movdqu	%xmm3,48(%r13)
+	pxor	80(%rsp),%xmm6
+	movdqu	%xmm1,64(%r13)
+	pxor	96(%rsp),%xmm2
+	movdqu	%xmm6,80(%r13)
+	pxor	112(%rsp),%xmm4
+	movdqu	%xmm2,96(%r13)
+	movdqu	%xmm4,112(%r13)
+	leaq	128(%r13),%r13
+
+	movdqa	112(%rsp),%xmm6
+	pxor	%xmm14,%xmm14
+	movdqa	.Lxts_magic(%rip),%xmm12
+	pcmpgtd	%xmm6,%xmm14
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+
+	subq	$128,%r14
+	jnc	.Lxts_dec_loop
+
+.Lxts_dec_short:
+	addq	$128,%r14
+	jz	.Lxts_dec_done
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm15
+	movdqa	%xmm6,0(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm0
+	movdqa	%xmm6,16(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	0(%r12),%xmm7
+	cmpq	$16,%r14
+	je	.Lxts_dec_1
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm1
+	movdqa	%xmm6,32(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	16(%r12),%xmm8
+	cmpq	$32,%r14
+	je	.Lxts_dec_2
+	pxor	%xmm7,%xmm15
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm2
+	movdqa	%xmm6,48(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	32(%r12),%xmm9
+	cmpq	$48,%r14
+	je	.Lxts_dec_3
+	pxor	%xmm8,%xmm0
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm3
+	movdqa	%xmm6,64(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	48(%r12),%xmm10
+	cmpq	$64,%r14
+	je	.Lxts_dec_4
+	pxor	%xmm9,%xmm1
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm4
+	movdqa	%xmm6,80(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	64(%r12),%xmm11
+	cmpq	$80,%r14
+	je	.Lxts_dec_5
+	pxor	%xmm10,%xmm2
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm5
+	movdqa	%xmm6,96(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	80(%r12),%xmm12
+	cmpq	$96,%r14
+	je	.Lxts_dec_6
+	pxor	%xmm11,%xmm3
+	movdqu	96(%r12),%xmm13
+	pxor	%xmm12,%xmm4
+	movdqa	%xmm6,112(%rsp)
+	leaq	112(%r12),%r12
+	pxor	%xmm13,%xmm5
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_decrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm5
+	movdqu	%xmm0,16(%r13)
+	pxor	48(%rsp),%xmm3
+	movdqu	%xmm5,32(%r13)
+	pxor	64(%rsp),%xmm1
+	movdqu	%xmm3,48(%r13)
+	pxor	80(%rsp),%xmm6
+	movdqu	%xmm1,64(%r13)
+	pxor	96(%rsp),%xmm2
+	movdqu	%xmm6,80(%r13)
+	movdqu	%xmm2,96(%r13)
+	leaq	112(%r13),%r13
+
+	movdqa	112(%rsp),%xmm6
+	jmp	.Lxts_dec_done
+.align	16
+.Lxts_dec_6:
+	pxor	%xmm11,%xmm3
+	leaq	96(%r12),%r12
+	pxor	%xmm12,%xmm4
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_decrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm5
+	movdqu	%xmm0,16(%r13)
+	pxor	48(%rsp),%xmm3
+	movdqu	%xmm5,32(%r13)
+	pxor	64(%rsp),%xmm1
+	movdqu	%xmm3,48(%r13)
+	pxor	80(%rsp),%xmm6
+	movdqu	%xmm1,64(%r13)
+	movdqu	%xmm6,80(%r13)
+	leaq	96(%r13),%r13
+
+	movdqa	96(%rsp),%xmm6
+	jmp	.Lxts_dec_done
+.align	16
+.Lxts_dec_5:
+	pxor	%xmm10,%xmm2
+	leaq	80(%r12),%r12
+	pxor	%xmm11,%xmm3
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_decrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm5
+	movdqu	%xmm0,16(%r13)
+	pxor	48(%rsp),%xmm3
+	movdqu	%xmm5,32(%r13)
+	pxor	64(%rsp),%xmm1
+	movdqu	%xmm3,48(%r13)
+	movdqu	%xmm1,64(%r13)
+	leaq	80(%r13),%r13
+
+	movdqa	80(%rsp),%xmm6
+	jmp	.Lxts_dec_done
+.align	16
+.Lxts_dec_4:
+	pxor	%xmm9,%xmm1
+	leaq	64(%r12),%r12
+	pxor	%xmm10,%xmm2
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_decrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm5
+	movdqu	%xmm0,16(%r13)
+	pxor	48(%rsp),%xmm3
+	movdqu	%xmm5,32(%r13)
+	movdqu	%xmm3,48(%r13)
+	leaq	64(%r13),%r13
+
+	movdqa	64(%rsp),%xmm6
+	jmp	.Lxts_dec_done
+.align	16
+.Lxts_dec_3:
+	pxor	%xmm8,%xmm0
+	leaq	48(%r12),%r12
+	pxor	%xmm9,%xmm1
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_decrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm5
+	movdqu	%xmm0,16(%r13)
+	movdqu	%xmm5,32(%r13)
+	leaq	48(%r13),%r13
+
+	movdqa	48(%rsp),%xmm6
+	jmp	.Lxts_dec_done
+.align	16
+.Lxts_dec_2:
+	pxor	%xmm7,%xmm15
+	leaq	32(%r12),%r12
+	pxor	%xmm8,%xmm0
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_decrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	movdqu	%xmm0,16(%r13)
+	leaq	32(%r13),%r13
+
+	movdqa	32(%rsp),%xmm6
+	jmp	.Lxts_dec_done
+.align	16
+.Lxts_dec_1:
+	pxor	%xmm15,%xmm7
+	leaq	16(%r12),%r12
+	movdqa	%xmm7,32(%rbp)
+	leaq	32(%rbp),%rdi
+	leaq	32(%rbp),%rsi
+	leaq	(%r15),%rdx
+	call	asm_AES_decrypt		
+	pxor	32(%rbp),%xmm15
+
+
+
+
+
+	movdqu	%xmm15,0(%r13)
+	leaq	16(%r13),%r13
+
+	movdqa	16(%rsp),%xmm6
+
+.Lxts_dec_done:
+	andl	$15,%ebx
+	jz	.Lxts_dec_ret
+
+	pxor	%xmm14,%xmm14
+	movdqa	.Lxts_magic(%rip),%xmm12
+	pcmpgtd	%xmm6,%xmm14
+	pshufd	$19,%xmm14,%xmm13
+	movdqa	%xmm6,%xmm5
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	movdqu	(%r12),%xmm15
+	pxor	%xmm13,%xmm6
+
+	leaq	32(%rbp),%rdi
+	pxor	%xmm6,%xmm15
+	leaq	32(%rbp),%rsi
+	movdqa	%xmm15,32(%rbp)
+	leaq	(%r15),%rdx
+	call	asm_AES_decrypt		
+	pxor	32(%rbp),%xmm6
+	movq	%r13,%rdx
+	movdqu	%xmm6,(%r13)
+
+.Lxts_dec_steal:
+	movzbl	16(%r12),%eax
+	movzbl	(%rdx),%ecx
+	leaq	1(%r12),%r12
+	movb	%al,(%rdx)
+	movb	%cl,16(%rdx)
+	leaq	1(%rdx),%rdx
+	subl	$1,%ebx
+	jnz	.Lxts_dec_steal
+
+	movdqu	(%r13),%xmm15
+	leaq	32(%rbp),%rdi
+	pxor	%xmm5,%xmm15
+	leaq	32(%rbp),%rsi
+	movdqa	%xmm15,32(%rbp)
+	leaq	(%r15),%rdx
+	call	asm_AES_decrypt		
+	pxor	32(%rbp),%xmm5
+	movdqu	%xmm5,(%r13)
+
+.Lxts_dec_ret:
+	leaq	(%rsp),%rax
+	pxor	%xmm0,%xmm0
+.Lxts_dec_bzero:
+	movdqa	%xmm0,0(%rax)
+	movdqa	%xmm0,16(%rax)
+	leaq	32(%rax),%rax
+	cmpq	%rax,%rbp
+	ja	.Lxts_dec_bzero
+
+	leaq	(%rbp),%rsp
+	movq	72(%rsp),%r15
+	movq	80(%rsp),%r14
+	movq	88(%rsp),%r13
+	movq	96(%rsp),%r12
+	movq	104(%rsp),%rbx
+	movq	112(%rsp),%rax
+	leaq	120(%rsp),%rsp
+	movq	%rax,%rbp
+.Lxts_dec_epilogue:
+	.byte	0xf3,0xc3
+.size	bsaes_xts_decrypt,.-bsaes_xts_decrypt
+.type	_bsaes_const,@object
+.align	64
+_bsaes_const:
+.LM0ISR:
+.quad	0x0a0e0206070b0f03, 0x0004080c0d010509
+.LISRM0:
+.quad	0x01040b0e0205080f, 0x0306090c00070a0d
+.LISR:
+.quad	0x0504070602010003, 0x0f0e0d0c080b0a09
+.LBS0:
+.quad	0x5555555555555555, 0x5555555555555555
+.LBS1:
+.quad	0x3333333333333333, 0x3333333333333333
+.LBS2:
+.quad	0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f
+.LSR:
+.quad	0x0504070600030201, 0x0f0e0d0c0a09080b
+.LSRM0:
+.quad	0x0304090e00050a0f, 0x01060b0c0207080d
+.LM0SR:
+.quad	0x0a0e02060f03070b, 0x0004080c05090d01
+.LSWPUP:
+.quad	0x0706050403020100, 0x0c0d0e0f0b0a0908
+.LSWPUPM0SR:
+.quad	0x0a0d02060c03070b, 0x0004080f05090e01
+.LADD1:
+.quad	0x0000000000000000, 0x0000000100000000
+.LADD2:
+.quad	0x0000000000000000, 0x0000000200000000
+.LADD3:
+.quad	0x0000000000000000, 0x0000000300000000
+.LADD4:
+.quad	0x0000000000000000, 0x0000000400000000
+.LADD5:
+.quad	0x0000000000000000, 0x0000000500000000
+.LADD6:
+.quad	0x0000000000000000, 0x0000000600000000
+.LADD7:
+.quad	0x0000000000000000, 0x0000000700000000
+.LADD8:
+.quad	0x0000000000000000, 0x0000000800000000
+.Lxts_magic:
+.long	0x87,0,1,0
+.Lmasks:
+.quad	0x0101010101010101, 0x0101010101010101
+.quad	0x0202020202020202, 0x0202020202020202
+.quad	0x0404040404040404, 0x0404040404040404
+.quad	0x0808080808080808, 0x0808080808080808
+.LM0:
+.quad	0x02060a0e03070b0f, 0x0004080c0105090d
+.L63:
+.quad	0x6363636363636363, 0x6363636363636363
+.byte	66,105,116,45,115,108,105,99,101,100,32,65,69,83,32,102,111,114,32,120,56,54,95,54,52,47,83,83,83,69,51,44,32,69,109,105,108,105,97,32,75,195,164,115,112,101,114,44,32,80,101,116,101,114,32,83,99,104,119,97,98,101,44,32,65,110,100,121,32,80,111,108,121,97,107,111,118,0
+.align	64
+.size	_bsaes_const,.-_bsaes_const
+#if defined(HAVE_GNU_STACK)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/crypto/libressl/crypto/aes/bsaes-macosx-x86_64.s b/crypto/libressl/crypto/aes/bsaes-macosx-x86_64.s
new file mode 100644
index 0000000000..dfce084d81
--- /dev/null
+++ b/crypto/libressl/crypto/aes/bsaes-macosx-x86_64.s
@@ -0,0 +1,2498 @@
+.text	
+
+
+
+
+
+.p2align	6
+_bsaes_encrypt8:
+	leaq	L$BS0(%rip),%r11
+
+	movdqa	(%rax),%xmm8
+	leaq	16(%rax),%rax
+	movdqa	80(%r11),%xmm7
+	pxor	%xmm8,%xmm15
+	pxor	%xmm8,%xmm0
+.byte	102,68,15,56,0,255
+	pxor	%xmm8,%xmm1
+.byte	102,15,56,0,199
+	pxor	%xmm8,%xmm2
+.byte	102,15,56,0,207
+	pxor	%xmm8,%xmm3
+.byte	102,15,56,0,215
+	pxor	%xmm8,%xmm4
+.byte	102,15,56,0,223
+	pxor	%xmm8,%xmm5
+.byte	102,15,56,0,231
+	pxor	%xmm8,%xmm6
+.byte	102,15,56,0,239
+.byte	102,15,56,0,247
+_bsaes_encrypt8_bitslice:
+	movdqa	0(%r11),%xmm7
+	movdqa	16(%r11),%xmm8
+	movdqa	%xmm5,%xmm9
+	psrlq	$1,%xmm5
+	movdqa	%xmm3,%xmm10
+	psrlq	$1,%xmm3
+	pxor	%xmm6,%xmm5
+	pxor	%xmm4,%xmm3
+	pand	%xmm7,%xmm5
+	pand	%xmm7,%xmm3
+	pxor	%xmm5,%xmm6
+	psllq	$1,%xmm5
+	pxor	%xmm3,%xmm4
+	psllq	$1,%xmm3
+	pxor	%xmm9,%xmm5
+	pxor	%xmm10,%xmm3
+	movdqa	%xmm1,%xmm9
+	psrlq	$1,%xmm1
+	movdqa	%xmm15,%xmm10
+	psrlq	$1,%xmm15
+	pxor	%xmm2,%xmm1
+	pxor	%xmm0,%xmm15
+	pand	%xmm7,%xmm1
+	pand	%xmm7,%xmm15
+	pxor	%xmm1,%xmm2
+	psllq	$1,%xmm1
+	pxor	%xmm15,%xmm0
+	psllq	$1,%xmm15
+	pxor	%xmm9,%xmm1
+	pxor	%xmm10,%xmm15
+	movdqa	32(%r11),%xmm7
+	movdqa	%xmm4,%xmm9
+	psrlq	$2,%xmm4
+	movdqa	%xmm3,%xmm10
+	psrlq	$2,%xmm3
+	pxor	%xmm6,%xmm4
+	pxor	%xmm5,%xmm3
+	pand	%xmm8,%xmm4
+	pand	%xmm8,%xmm3
+	pxor	%xmm4,%xmm6
+	psllq	$2,%xmm4
+	pxor	%xmm3,%xmm5
+	psllq	$2,%xmm3
+	pxor	%xmm9,%xmm4
+	pxor	%xmm10,%xmm3
+	movdqa	%xmm0,%xmm9
+	psrlq	$2,%xmm0
+	movdqa	%xmm15,%xmm10
+	psrlq	$2,%xmm15
+	pxor	%xmm2,%xmm0
+	pxor	%xmm1,%xmm15
+	pand	%xmm8,%xmm0
+	pand	%xmm8,%xmm15
+	pxor	%xmm0,%xmm2
+	psllq	$2,%xmm0
+	pxor	%xmm15,%xmm1
+	psllq	$2,%xmm15
+	pxor	%xmm9,%xmm0
+	pxor	%xmm10,%xmm15
+	movdqa	%xmm2,%xmm9
+	psrlq	$4,%xmm2
+	movdqa	%xmm1,%xmm10
+	psrlq	$4,%xmm1
+	pxor	%xmm6,%xmm2
+	pxor	%xmm5,%xmm1
+	pand	%xmm7,%xmm2
+	pand	%xmm7,%xmm1
+	pxor	%xmm2,%xmm6
+	psllq	$4,%xmm2
+	pxor	%xmm1,%xmm5
+	psllq	$4,%xmm1
+	pxor	%xmm9,%xmm2
+	pxor	%xmm10,%xmm1
+	movdqa	%xmm0,%xmm9
+	psrlq	$4,%xmm0
+	movdqa	%xmm15,%xmm10
+	psrlq	$4,%xmm15
+	pxor	%xmm4,%xmm0
+	pxor	%xmm3,%xmm15
+	pand	%xmm7,%xmm0
+	pand	%xmm7,%xmm15
+	pxor	%xmm0,%xmm4
+	psllq	$4,%xmm0
+	pxor	%xmm15,%xmm3
+	psllq	$4,%xmm15
+	pxor	%xmm9,%xmm0
+	pxor	%xmm10,%xmm15
+	decl	%r10d
+	jmp	L$enc_sbox
+.p2align	4
+L$enc_loop:
+	pxor	0(%rax),%xmm15
+	pxor	16(%rax),%xmm0
+.byte	102,68,15,56,0,255
+	pxor	32(%rax),%xmm1
+.byte	102,15,56,0,199
+	pxor	48(%rax),%xmm2
+.byte	102,15,56,0,207
+	pxor	64(%rax),%xmm3
+.byte	102,15,56,0,215
+	pxor	80(%rax),%xmm4
+.byte	102,15,56,0,223
+	pxor	96(%rax),%xmm5
+.byte	102,15,56,0,231
+	pxor	112(%rax),%xmm6
+.byte	102,15,56,0,239
+	leaq	128(%rax),%rax
+.byte	102,15,56,0,247
+L$enc_sbox:
+	pxor	%xmm5,%xmm4
+	pxor	%xmm0,%xmm1
+	pxor	%xmm15,%xmm2
+	pxor	%xmm1,%xmm5
+	pxor	%xmm15,%xmm4
+
+	pxor	%xmm2,%xmm5
+	pxor	%xmm6,%xmm2
+	pxor	%xmm4,%xmm6
+	pxor	%xmm3,%xmm2
+	pxor	%xmm4,%xmm3
+	pxor	%xmm0,%xmm2
+
+	pxor	%xmm6,%xmm1
+	pxor	%xmm4,%xmm0
+	movdqa	%xmm6,%xmm10
+	movdqa	%xmm0,%xmm9
+	movdqa	%xmm4,%xmm8
+	movdqa	%xmm1,%xmm12
+	movdqa	%xmm5,%xmm11
+
+	pxor	%xmm3,%xmm10
+	pxor	%xmm1,%xmm9
+	pxor	%xmm2,%xmm8
+	movdqa	%xmm10,%xmm13
+	pxor	%xmm3,%xmm12
+	movdqa	%xmm9,%xmm7
+	pxor	%xmm15,%xmm11
+	movdqa	%xmm10,%xmm14
+
+	por	%xmm8,%xmm9
+	por	%xmm11,%xmm10
+	pxor	%xmm7,%xmm14
+	pand	%xmm11,%xmm13
+	pxor	%xmm8,%xmm11
+	pand	%xmm8,%xmm7
+	pand	%xmm11,%xmm14
+	movdqa	%xmm2,%xmm11
+	pxor	%xmm15,%xmm11
+	pand	%xmm11,%xmm12
+	pxor	%xmm12,%xmm10
+	pxor	%xmm12,%xmm9
+	movdqa	%xmm6,%xmm12
+	movdqa	%xmm4,%xmm11
+	pxor	%xmm0,%xmm12
+	pxor	%xmm5,%xmm11
+	movdqa	%xmm12,%xmm8
+	pand	%xmm11,%xmm12
+	por	%xmm11,%xmm8
+	pxor	%xmm12,%xmm7
+	pxor	%xmm14,%xmm10
+	pxor	%xmm13,%xmm9
+	pxor	%xmm14,%xmm8
+	movdqa	%xmm1,%xmm11
+	pxor	%xmm13,%xmm7
+	movdqa	%xmm3,%xmm12
+	pxor	%xmm13,%xmm8
+	movdqa	%xmm0,%xmm13
+	pand	%xmm2,%xmm11
+	movdqa	%xmm6,%xmm14
+	pand	%xmm15,%xmm12
+	pand	%xmm4,%xmm13
+	por	%xmm5,%xmm14
+	pxor	%xmm11,%xmm10
+	pxor	%xmm12,%xmm9
+	pxor	%xmm13,%xmm8
+	pxor	%xmm14,%xmm7
+
+
+
+
+
+	movdqa	%xmm10,%xmm11
+	pand	%xmm8,%xmm10
+	pxor	%xmm9,%xmm11
+
+	movdqa	%xmm7,%xmm13
+	movdqa	%xmm11,%xmm14
+	pxor	%xmm10,%xmm13
+	pand	%xmm13,%xmm14
+
+	movdqa	%xmm8,%xmm12
+	pxor	%xmm9,%xmm14
+	pxor	%xmm7,%xmm12
+
+	pxor	%xmm9,%xmm10
+
+	pand	%xmm10,%xmm12
+
+	movdqa	%xmm13,%xmm9
+	pxor	%xmm7,%xmm12
+
+	pxor	%xmm12,%xmm9
+	pxor	%xmm12,%xmm8
+
+	pand	%xmm7,%xmm9
+
+	pxor	%xmm9,%xmm13
+	pxor	%xmm9,%xmm8
+
+	pand	%xmm14,%xmm13
+
+	pxor	%xmm11,%xmm13
+	movdqa	%xmm5,%xmm11
+	movdqa	%xmm4,%xmm7
+	movdqa	%xmm14,%xmm9
+	pxor	%xmm13,%xmm9
+	pand	%xmm5,%xmm9
+	pxor	%xmm4,%xmm5
+	pand	%xmm14,%xmm4
+	pand	%xmm13,%xmm5
+	pxor	%xmm4,%xmm5
+	pxor	%xmm9,%xmm4
+	pxor	%xmm15,%xmm11
+	pxor	%xmm2,%xmm7
+	pxor	%xmm12,%xmm14
+	pxor	%xmm8,%xmm13
+	movdqa	%xmm14,%xmm10
+	movdqa	%xmm12,%xmm9
+	pxor	%xmm13,%xmm10
+	pxor	%xmm8,%xmm9
+	pand	%xmm11,%xmm10
+	pand	%xmm15,%xmm9
+	pxor	%xmm7,%xmm11
+	pxor	%xmm2,%xmm15
+	pand	%xmm14,%xmm7
+	pand	%xmm12,%xmm2
+	pand	%xmm13,%xmm11
+	pand	%xmm8,%xmm15
+	pxor	%xmm11,%xmm7
+	pxor	%xmm2,%xmm15
+	pxor	%xmm10,%xmm11
+	pxor	%xmm9,%xmm2
+	pxor	%xmm11,%xmm5
+	pxor	%xmm11,%xmm15
+	pxor	%xmm7,%xmm4
+	pxor	%xmm7,%xmm2
+
+	movdqa	%xmm6,%xmm11
+	movdqa	%xmm0,%xmm7
+	pxor	%xmm3,%xmm11
+	pxor	%xmm1,%xmm7
+	movdqa	%xmm14,%xmm10
+	movdqa	%xmm12,%xmm9
+	pxor	%xmm13,%xmm10
+	pxor	%xmm8,%xmm9
+	pand	%xmm11,%xmm10
+	pand	%xmm3,%xmm9
+	pxor	%xmm7,%xmm11
+	pxor	%xmm1,%xmm3
+	pand	%xmm14,%xmm7
+	pand	%xmm12,%xmm1
+	pand	%xmm13,%xmm11
+	pand	%xmm8,%xmm3
+	pxor	%xmm11,%xmm7
+	pxor	%xmm1,%xmm3
+	pxor	%xmm10,%xmm11
+	pxor	%xmm9,%xmm1
+	pxor	%xmm12,%xmm14
+	pxor	%xmm8,%xmm13
+	movdqa	%xmm14,%xmm10
+	pxor	%xmm13,%xmm10
+	pand	%xmm6,%xmm10
+	pxor	%xmm0,%xmm6
+	pand	%xmm14,%xmm0
+	pand	%xmm13,%xmm6
+	pxor	%xmm0,%xmm6
+	pxor	%xmm10,%xmm0
+	pxor	%xmm11,%xmm6
+	pxor	%xmm11,%xmm3
+	pxor	%xmm7,%xmm0
+	pxor	%xmm7,%xmm1
+	pxor	%xmm15,%xmm6
+	pxor	%xmm5,%xmm0
+	pxor	%xmm6,%xmm3
+	pxor	%xmm15,%xmm5
+	pxor	%xmm0,%xmm15
+
+	pxor	%xmm4,%xmm0
+	pxor	%xmm1,%xmm4
+	pxor	%xmm2,%xmm1
+	pxor	%xmm4,%xmm2
+	pxor	%xmm4,%xmm3
+
+	pxor	%xmm2,%xmm5
+	decl	%r10d
+	jl	L$enc_done
+	pshufd	$147,%xmm15,%xmm7
+	pshufd	$147,%xmm0,%xmm8
+	pxor	%xmm7,%xmm15
+	pshufd	$147,%xmm3,%xmm9
+	pxor	%xmm8,%xmm0
+	pshufd	$147,%xmm5,%xmm10
+	pxor	%xmm9,%xmm3
+	pshufd	$147,%xmm2,%xmm11
+	pxor	%xmm10,%xmm5
+	pshufd	$147,%xmm6,%xmm12
+	pxor	%xmm11,%xmm2
+	pshufd	$147,%xmm1,%xmm13
+	pxor	%xmm12,%xmm6
+	pshufd	$147,%xmm4,%xmm14
+	pxor	%xmm13,%xmm1
+	pxor	%xmm14,%xmm4
+
+	pxor	%xmm15,%xmm8
+	pxor	%xmm4,%xmm7
+	pxor	%xmm4,%xmm8
+	pshufd	$78,%xmm15,%xmm15
+	pxor	%xmm0,%xmm9
+	pshufd	$78,%xmm0,%xmm0
+	pxor	%xmm2,%xmm12
+	pxor	%xmm7,%xmm15
+	pxor	%xmm6,%xmm13
+	pxor	%xmm8,%xmm0
+	pxor	%xmm5,%xmm11
+	pshufd	$78,%xmm2,%xmm7
+	pxor	%xmm1,%xmm14
+	pshufd	$78,%xmm6,%xmm8
+	pxor	%xmm3,%xmm10
+	pshufd	$78,%xmm5,%xmm2
+	pxor	%xmm4,%xmm10
+	pshufd	$78,%xmm4,%xmm6
+	pxor	%xmm4,%xmm11
+	pshufd	$78,%xmm1,%xmm5
+	pxor	%xmm11,%xmm7
+	pshufd	$78,%xmm3,%xmm1
+	pxor	%xmm12,%xmm8
+	pxor	%xmm10,%xmm2
+	pxor	%xmm14,%xmm6
+	pxor	%xmm13,%xmm5
+	movdqa	%xmm7,%xmm3
+	pxor	%xmm9,%xmm1
+	movdqa	%xmm8,%xmm4
+	movdqa	48(%r11),%xmm7
+	jnz	L$enc_loop
+	movdqa	64(%r11),%xmm7
+	jmp	L$enc_loop
+.p2align	4
+L$enc_done:
+	movdqa	0(%r11),%xmm7
+	movdqa	16(%r11),%xmm8
+	movdqa	%xmm1,%xmm9
+	psrlq	$1,%xmm1
+	movdqa	%xmm2,%xmm10
+	psrlq	$1,%xmm2
+	pxor	%xmm4,%xmm1
+	pxor	%xmm6,%xmm2
+	pand	%xmm7,%xmm1
+	pand	%xmm7,%xmm2
+	pxor	%xmm1,%xmm4
+	psllq	$1,%xmm1
+	pxor	%xmm2,%xmm6
+	psllq	$1,%xmm2
+	pxor	%xmm9,%xmm1
+	pxor	%xmm10,%xmm2
+	movdqa	%xmm3,%xmm9
+	psrlq	$1,%xmm3
+	movdqa	%xmm15,%xmm10
+	psrlq	$1,%xmm15
+	pxor	%xmm5,%xmm3
+	pxor	%xmm0,%xmm15
+	pand	%xmm7,%xmm3
+	pand	%xmm7,%xmm15
+	pxor	%xmm3,%xmm5
+	psllq	$1,%xmm3
+	pxor	%xmm15,%xmm0
+	psllq	$1,%xmm15
+	pxor	%xmm9,%xmm3
+	pxor	%xmm10,%xmm15
+	movdqa	32(%r11),%xmm7
+	movdqa	%xmm6,%xmm9
+	psrlq	$2,%xmm6
+	movdqa	%xmm2,%xmm10
+	psrlq	$2,%xmm2
+	pxor	%xmm4,%xmm6
+	pxor	%xmm1,%xmm2
+	pand	%xmm8,%xmm6
+	pand	%xmm8,%xmm2
+	pxor	%xmm6,%xmm4
+	psllq	$2,%xmm6
+	pxor	%xmm2,%xmm1
+	psllq	$2,%xmm2
+	pxor	%xmm9,%xmm6
+	pxor	%xmm10,%xmm2
+	movdqa	%xmm0,%xmm9
+	psrlq	$2,%xmm0
+	movdqa	%xmm15,%xmm10
+	psrlq	$2,%xmm15
+	pxor	%xmm5,%xmm0
+	pxor	%xmm3,%xmm15
+	pand	%xmm8,%xmm0
+	pand	%xmm8,%xmm15
+	pxor	%xmm0,%xmm5
+	psllq	$2,%xmm0
+	pxor	%xmm15,%xmm3
+	psllq	$2,%xmm15
+	pxor	%xmm9,%xmm0
+	pxor	%xmm10,%xmm15
+	movdqa	%xmm5,%xmm9
+	psrlq	$4,%xmm5
+	movdqa	%xmm3,%xmm10
+	psrlq	$4,%xmm3
+	pxor	%xmm4,%xmm5
+	pxor	%xmm1,%xmm3
+	pand	%xmm7,%xmm5
+	pand	%xmm7,%xmm3
+	pxor	%xmm5,%xmm4
+	psllq	$4,%xmm5
+	pxor	%xmm3,%xmm1
+	psllq	$4,%xmm3
+	pxor	%xmm9,%xmm5
+	pxor	%xmm10,%xmm3
+	movdqa	%xmm0,%xmm9
+	psrlq	$4,%xmm0
+	movdqa	%xmm15,%xmm10
+	psrlq	$4,%xmm15
+	pxor	%xmm6,%xmm0
+	pxor	%xmm2,%xmm15
+	pand	%xmm7,%xmm0
+	pand	%xmm7,%xmm15
+	pxor	%xmm0,%xmm6
+	psllq	$4,%xmm0
+	pxor	%xmm15,%xmm2
+	psllq	$4,%xmm15
+	pxor	%xmm9,%xmm0
+	pxor	%xmm10,%xmm15
+	movdqa	(%rax),%xmm7
+	pxor	%xmm7,%xmm3
+	pxor	%xmm7,%xmm5
+	pxor	%xmm7,%xmm2
+	pxor	%xmm7,%xmm6
+	pxor	%xmm7,%xmm1
+	pxor	%xmm7,%xmm4
+	pxor	%xmm7,%xmm15
+	pxor	%xmm7,%xmm0
+	.byte	0xf3,0xc3
+
+
+
+.p2align	6
+_bsaes_decrypt8:
+	leaq	L$BS0(%rip),%r11
+
+	movdqa	(%rax),%xmm8
+	leaq	16(%rax),%rax
+	movdqa	-48(%r11),%xmm7
+	pxor	%xmm8,%xmm15
+	pxor	%xmm8,%xmm0
+.byte	102,68,15,56,0,255
+	pxor	%xmm8,%xmm1
+.byte	102,15,56,0,199
+	pxor	%xmm8,%xmm2
+.byte	102,15,56,0,207
+	pxor	%xmm8,%xmm3
+.byte	102,15,56,0,215
+	pxor	%xmm8,%xmm4
+.byte	102,15,56,0,223
+	pxor	%xmm8,%xmm5
+.byte	102,15,56,0,231
+	pxor	%xmm8,%xmm6
+.byte	102,15,56,0,239
+.byte	102,15,56,0,247
+	movdqa	0(%r11),%xmm7
+	movdqa	16(%r11),%xmm8
+	movdqa	%xmm5,%xmm9
+	psrlq	$1,%xmm5
+	movdqa	%xmm3,%xmm10
+	psrlq	$1,%xmm3
+	pxor	%xmm6,%xmm5
+	pxor	%xmm4,%xmm3
+	pand	%xmm7,%xmm5
+	pand	%xmm7,%xmm3
+	pxor	%xmm5,%xmm6
+	psllq	$1,%xmm5
+	pxor	%xmm3,%xmm4
+	psllq	$1,%xmm3
+	pxor	%xmm9,%xmm5
+	pxor	%xmm10,%xmm3
+	movdqa	%xmm1,%xmm9
+	psrlq	$1,%xmm1
+	movdqa	%xmm15,%xmm10
+	psrlq	$1,%xmm15
+	pxor	%xmm2,%xmm1
+	pxor	%xmm0,%xmm15
+	pand	%xmm7,%xmm1
+	pand	%xmm7,%xmm15
+	pxor	%xmm1,%xmm2
+	psllq	$1,%xmm1
+	pxor	%xmm15,%xmm0
+	psllq	$1,%xmm15
+	pxor	%xmm9,%xmm1
+	pxor	%xmm10,%xmm15
+	movdqa	32(%r11),%xmm7
+	movdqa	%xmm4,%xmm9
+	psrlq	$2,%xmm4
+	movdqa	%xmm3,%xmm10
+	psrlq	$2,%xmm3
+	pxor	%xmm6,%xmm4
+	pxor	%xmm5,%xmm3
+	pand	%xmm8,%xmm4
+	pand	%xmm8,%xmm3
+	pxor	%xmm4,%xmm6
+	psllq	$2,%xmm4
+	pxor	%xmm3,%xmm5
+	psllq	$2,%xmm3
+	pxor	%xmm9,%xmm4
+	pxor	%xmm10,%xmm3
+	movdqa	%xmm0,%xmm9
+	psrlq	$2,%xmm0
+	movdqa	%xmm15,%xmm10
+	psrlq	$2,%xmm15
+	pxor	%xmm2,%xmm0
+	pxor	%xmm1,%xmm15
+	pand	%xmm8,%xmm0
+	pand	%xmm8,%xmm15
+	pxor	%xmm0,%xmm2
+	psllq	$2,%xmm0
+	pxor	%xmm15,%xmm1
+	psllq	$2,%xmm15
+	pxor	%xmm9,%xmm0
+	pxor	%xmm10,%xmm15
+	movdqa	%xmm2,%xmm9
+	psrlq	$4,%xmm2
+	movdqa	%xmm1,%xmm10
+	psrlq	$4,%xmm1
+	pxor	%xmm6,%xmm2
+	pxor	%xmm5,%xmm1
+	pand	%xmm7,%xmm2
+	pand	%xmm7,%xmm1
+	pxor	%xmm2,%xmm6
+	psllq	$4,%xmm2
+	pxor	%xmm1,%xmm5
+	psllq	$4,%xmm1
+	pxor	%xmm9,%xmm2
+	pxor	%xmm10,%xmm1
+	movdqa	%xmm0,%xmm9
+	psrlq	$4,%xmm0
+	movdqa	%xmm15,%xmm10
+	psrlq	$4,%xmm15
+	pxor	%xmm4,%xmm0
+	pxor	%xmm3,%xmm15
+	pand	%xmm7,%xmm0
+	pand	%xmm7,%xmm15
+	pxor	%xmm0,%xmm4
+	psllq	$4,%xmm0
+	pxor	%xmm15,%xmm3
+	psllq	$4,%xmm15
+	pxor	%xmm9,%xmm0
+	pxor	%xmm10,%xmm15
+	decl	%r10d
+	jmp	L$dec_sbox
+.p2align	4
+L$dec_loop:
+	pxor	0(%rax),%xmm15
+	pxor	16(%rax),%xmm0
+.byte	102,68,15,56,0,255
+	pxor	32(%rax),%xmm1
+.byte	102,15,56,0,199
+	pxor	48(%rax),%xmm2
+.byte	102,15,56,0,207
+	pxor	64(%rax),%xmm3
+.byte	102,15,56,0,215
+	pxor	80(%rax),%xmm4
+.byte	102,15,56,0,223
+	pxor	96(%rax),%xmm5
+.byte	102,15,56,0,231
+	pxor	112(%rax),%xmm6
+.byte	102,15,56,0,239
+	leaq	128(%rax),%rax
+.byte	102,15,56,0,247
+L$dec_sbox:
+	pxor	%xmm3,%xmm2
+
+	pxor	%xmm6,%xmm3
+	pxor	%xmm6,%xmm1
+	pxor	%xmm3,%xmm5
+	pxor	%xmm5,%xmm6
+	pxor	%xmm6,%xmm0
+
+	pxor	%xmm0,%xmm15
+	pxor	%xmm4,%xmm1
+	pxor	%xmm15,%xmm2
+	pxor	%xmm15,%xmm4
+	pxor	%xmm2,%xmm0
+	movdqa	%xmm2,%xmm10
+	movdqa	%xmm6,%xmm9
+	movdqa	%xmm0,%xmm8
+	movdqa	%xmm3,%xmm12
+	movdqa	%xmm4,%xmm11
+
+	pxor	%xmm15,%xmm10
+	pxor	%xmm3,%xmm9
+	pxor	%xmm5,%xmm8
+	movdqa	%xmm10,%xmm13
+	pxor	%xmm15,%xmm12
+	movdqa	%xmm9,%xmm7
+	pxor	%xmm1,%xmm11
+	movdqa	%xmm10,%xmm14
+
+	por	%xmm8,%xmm9
+	por	%xmm11,%xmm10
+	pxor	%xmm7,%xmm14
+	pand	%xmm11,%xmm13
+	pxor	%xmm8,%xmm11
+	pand	%xmm8,%xmm7
+	pand	%xmm11,%xmm14
+	movdqa	%xmm5,%xmm11
+	pxor	%xmm1,%xmm11
+	pand	%xmm11,%xmm12
+	pxor	%xmm12,%xmm10
+	pxor	%xmm12,%xmm9
+	movdqa	%xmm2,%xmm12
+	movdqa	%xmm0,%xmm11
+	pxor	%xmm6,%xmm12
+	pxor	%xmm4,%xmm11
+	movdqa	%xmm12,%xmm8
+	pand	%xmm11,%xmm12
+	por	%xmm11,%xmm8
+	pxor	%xmm12,%xmm7
+	pxor	%xmm14,%xmm10
+	pxor	%xmm13,%xmm9
+	pxor	%xmm14,%xmm8
+	movdqa	%xmm3,%xmm11
+	pxor	%xmm13,%xmm7
+	movdqa	%xmm15,%xmm12
+	pxor	%xmm13,%xmm8
+	movdqa	%xmm6,%xmm13
+	pand	%xmm5,%xmm11
+	movdqa	%xmm2,%xmm14
+	pand	%xmm1,%xmm12
+	pand	%xmm0,%xmm13
+	por	%xmm4,%xmm14
+	pxor	%xmm11,%xmm10
+	pxor	%xmm12,%xmm9
+	pxor	%xmm13,%xmm8
+	pxor	%xmm14,%xmm7
+
+
+
+
+
+	movdqa	%xmm10,%xmm11
+	pand	%xmm8,%xmm10
+	pxor	%xmm9,%xmm11
+
+	movdqa	%xmm7,%xmm13
+	movdqa	%xmm11,%xmm14
+	pxor	%xmm10,%xmm13
+	pand	%xmm13,%xmm14
+
+	movdqa	%xmm8,%xmm12
+	pxor	%xmm9,%xmm14
+	pxor	%xmm7,%xmm12
+
+	pxor	%xmm9,%xmm10
+
+	pand	%xmm10,%xmm12
+
+	movdqa	%xmm13,%xmm9
+	pxor	%xmm7,%xmm12
+
+	pxor	%xmm12,%xmm9
+	pxor	%xmm12,%xmm8
+
+	pand	%xmm7,%xmm9
+
+	pxor	%xmm9,%xmm13
+	pxor	%xmm9,%xmm8
+
+	pand	%xmm14,%xmm13
+
+	pxor	%xmm11,%xmm13
+	movdqa	%xmm4,%xmm11
+	movdqa	%xmm0,%xmm7
+	movdqa	%xmm14,%xmm9
+	pxor	%xmm13,%xmm9
+	pand	%xmm4,%xmm9
+	pxor	%xmm0,%xmm4
+	pand	%xmm14,%xmm0
+	pand	%xmm13,%xmm4
+	pxor	%xmm0,%xmm4
+	pxor	%xmm9,%xmm0
+	pxor	%xmm1,%xmm11
+	pxor	%xmm5,%xmm7
+	pxor	%xmm12,%xmm14
+	pxor	%xmm8,%xmm13
+	movdqa	%xmm14,%xmm10
+	movdqa	%xmm12,%xmm9
+	pxor	%xmm13,%xmm10
+	pxor	%xmm8,%xmm9
+	pand	%xmm11,%xmm10
+	pand	%xmm1,%xmm9
+	pxor	%xmm7,%xmm11
+	pxor	%xmm5,%xmm1
+	pand	%xmm14,%xmm7
+	pand	%xmm12,%xmm5
+	pand	%xmm13,%xmm11
+	pand	%xmm8,%xmm1
+	pxor	%xmm11,%xmm7
+	pxor	%xmm5,%xmm1
+	pxor	%xmm10,%xmm11
+	pxor	%xmm9,%xmm5
+	pxor	%xmm11,%xmm4
+	pxor	%xmm11,%xmm1
+	pxor	%xmm7,%xmm0
+	pxor	%xmm7,%xmm5
+
+	movdqa	%xmm2,%xmm11
+	movdqa	%xmm6,%xmm7
+	pxor	%xmm15,%xmm11
+	pxor	%xmm3,%xmm7
+	movdqa	%xmm14,%xmm10
+	movdqa	%xmm12,%xmm9
+	pxor	%xmm13,%xmm10
+	pxor	%xmm8,%xmm9
+	pand	%xmm11,%xmm10
+	pand	%xmm15,%xmm9
+	pxor	%xmm7,%xmm11
+	pxor	%xmm3,%xmm15
+	pand	%xmm14,%xmm7
+	pand	%xmm12,%xmm3
+	pand	%xmm13,%xmm11
+	pand	%xmm8,%xmm15
+	pxor	%xmm11,%xmm7
+	pxor	%xmm3,%xmm15
+	pxor	%xmm10,%xmm11
+	pxor	%xmm9,%xmm3
+	pxor	%xmm12,%xmm14
+	pxor	%xmm8,%xmm13
+	movdqa	%xmm14,%xmm10
+	pxor	%xmm13,%xmm10
+	pand	%xmm2,%xmm10
+	pxor	%xmm6,%xmm2
+	pand	%xmm14,%xmm6
+	pand	%xmm13,%xmm2
+	pxor	%xmm6,%xmm2
+	pxor	%xmm10,%xmm6
+	pxor	%xmm11,%xmm2
+	pxor	%xmm11,%xmm15
+	pxor	%xmm7,%xmm6
+	pxor	%xmm7,%xmm3
+	pxor	%xmm6,%xmm0
+	pxor	%xmm4,%xmm5
+
+	pxor	%xmm0,%xmm3
+	pxor	%xmm6,%xmm1
+	pxor	%xmm6,%xmm4
+	pxor	%xmm1,%xmm3
+	pxor	%xmm15,%xmm6
+	pxor	%xmm4,%xmm3
+	pxor	%xmm5,%xmm2
+	pxor	%xmm0,%xmm5
+	pxor	%xmm3,%xmm2
+
+	pxor	%xmm15,%xmm3
+	pxor	%xmm2,%xmm6
+	decl	%r10d
+	jl	L$dec_done
+
+	pshufd	$78,%xmm15,%xmm7
+	pshufd	$78,%xmm2,%xmm13
+	pxor	%xmm15,%xmm7
+	pshufd	$78,%xmm4,%xmm14
+	pxor	%xmm2,%xmm13
+	pshufd	$78,%xmm0,%xmm8
+	pxor	%xmm4,%xmm14
+	pshufd	$78,%xmm5,%xmm9
+	pxor	%xmm0,%xmm8
+	pshufd	$78,%xmm3,%xmm10
+	pxor	%xmm5,%xmm9
+	pxor	%xmm13,%xmm15
+	pxor	%xmm13,%xmm0
+	pshufd	$78,%xmm1,%xmm11
+	pxor	%xmm3,%xmm10
+	pxor	%xmm7,%xmm5
+	pxor	%xmm8,%xmm3
+	pshufd	$78,%xmm6,%xmm12
+	pxor	%xmm1,%xmm11
+	pxor	%xmm14,%xmm0
+	pxor	%xmm9,%xmm1
+	pxor	%xmm6,%xmm12
+
+	pxor	%xmm14,%xmm5
+	pxor	%xmm13,%xmm3
+	pxor	%xmm13,%xmm1
+	pxor	%xmm10,%xmm6
+	pxor	%xmm11,%xmm2
+	pxor	%xmm14,%xmm1
+	pxor	%xmm14,%xmm6
+	pxor	%xmm12,%xmm4
+	pshufd	$147,%xmm15,%xmm7
+	pshufd	$147,%xmm0,%xmm8
+	pxor	%xmm7,%xmm15
+	pshufd	$147,%xmm5,%xmm9
+	pxor	%xmm8,%xmm0
+	pshufd	$147,%xmm3,%xmm10
+	pxor	%xmm9,%xmm5
+	pshufd	$147,%xmm1,%xmm11
+	pxor	%xmm10,%xmm3
+	pshufd	$147,%xmm6,%xmm12
+	pxor	%xmm11,%xmm1
+	pshufd	$147,%xmm2,%xmm13
+	pxor	%xmm12,%xmm6
+	pshufd	$147,%xmm4,%xmm14
+	pxor	%xmm13,%xmm2
+	pxor	%xmm14,%xmm4
+
+	pxor	%xmm15,%xmm8
+	pxor	%xmm4,%xmm7
+	pxor	%xmm4,%xmm8
+	pshufd	$78,%xmm15,%xmm15
+	pxor	%xmm0,%xmm9
+	pshufd	$78,%xmm0,%xmm0
+	pxor	%xmm1,%xmm12
+	pxor	%xmm7,%xmm15
+	pxor	%xmm6,%xmm13
+	pxor	%xmm8,%xmm0
+	pxor	%xmm3,%xmm11
+	pshufd	$78,%xmm1,%xmm7
+	pxor	%xmm2,%xmm14
+	pshufd	$78,%xmm6,%xmm8
+	pxor	%xmm5,%xmm10
+	pshufd	$78,%xmm3,%xmm1
+	pxor	%xmm4,%xmm10
+	pshufd	$78,%xmm4,%xmm6
+	pxor	%xmm4,%xmm11
+	pshufd	$78,%xmm2,%xmm3
+	pxor	%xmm11,%xmm7
+	pshufd	$78,%xmm5,%xmm2
+	pxor	%xmm12,%xmm8
+	pxor	%xmm1,%xmm10
+	pxor	%xmm14,%xmm6
+	pxor	%xmm3,%xmm13
+	movdqa	%xmm7,%xmm3
+	pxor	%xmm9,%xmm2
+	movdqa	%xmm13,%xmm5
+	movdqa	%xmm8,%xmm4
+	movdqa	%xmm2,%xmm1
+	movdqa	%xmm10,%xmm2
+	movdqa	-16(%r11),%xmm7
+	jnz	L$dec_loop
+	movdqa	-32(%r11),%xmm7
+	jmp	L$dec_loop
+.p2align	4
+L$dec_done:
+	movdqa	0(%r11),%xmm7
+	movdqa	16(%r11),%xmm8
+	movdqa	%xmm2,%xmm9
+	psrlq	$1,%xmm2
+	movdqa	%xmm1,%xmm10
+	psrlq	$1,%xmm1
+	pxor	%xmm4,%xmm2
+	pxor	%xmm6,%xmm1
+	pand	%xmm7,%xmm2
+	pand	%xmm7,%xmm1
+	pxor	%xmm2,%xmm4
+	psllq	$1,%xmm2
+	pxor	%xmm1,%xmm6
+	psllq	$1,%xmm1
+	pxor	%xmm9,%xmm2
+	pxor	%xmm10,%xmm1
+	movdqa	%xmm5,%xmm9
+	psrlq	$1,%xmm5
+	movdqa	%xmm15,%xmm10
+	psrlq	$1,%xmm15
+	pxor	%xmm3,%xmm5
+	pxor	%xmm0,%xmm15
+	pand	%xmm7,%xmm5
+	pand	%xmm7,%xmm15
+	pxor	%xmm5,%xmm3
+	psllq	$1,%xmm5
+	pxor	%xmm15,%xmm0
+	psllq	$1,%xmm15
+	pxor	%xmm9,%xmm5
+	pxor	%xmm10,%xmm15
+	movdqa	32(%r11),%xmm7
+	movdqa	%xmm6,%xmm9
+	psrlq	$2,%xmm6
+	movdqa	%xmm1,%xmm10
+	psrlq	$2,%xmm1
+	pxor	%xmm4,%xmm6
+	pxor	%xmm2,%xmm1
+	pand	%xmm8,%xmm6
+	pand	%xmm8,%xmm1
+	pxor	%xmm6,%xmm4
+	psllq	$2,%xmm6
+	pxor	%xmm1,%xmm2
+	psllq	$2,%xmm1
+	pxor	%xmm9,%xmm6
+	pxor	%xmm10,%xmm1
+	movdqa	%xmm0,%xmm9
+	psrlq	$2,%xmm0
+	movdqa	%xmm15,%xmm10
+	psrlq	$2,%xmm15
+	pxor	%xmm3,%xmm0
+	pxor	%xmm5,%xmm15
+	pand	%xmm8,%xmm0
+	pand	%xmm8,%xmm15
+	pxor	%xmm0,%xmm3
+	psllq	$2,%xmm0
+	pxor	%xmm15,%xmm5
+	psllq	$2,%xmm15
+	pxor	%xmm9,%xmm0
+	pxor	%xmm10,%xmm15
+	movdqa	%xmm3,%xmm9
+	psrlq	$4,%xmm3
+	movdqa	%xmm5,%xmm10
+	psrlq	$4,%xmm5
+	pxor	%xmm4,%xmm3
+	pxor	%xmm2,%xmm5
+	pand	%xmm7,%xmm3
+	pand	%xmm7,%xmm5
+	pxor	%xmm3,%xmm4
+	psllq	$4,%xmm3
+	pxor	%xmm5,%xmm2
+	psllq	$4,%xmm5
+	pxor	%xmm9,%xmm3
+	pxor	%xmm10,%xmm5
+	movdqa	%xmm0,%xmm9
+	psrlq	$4,%xmm0
+	movdqa	%xmm15,%xmm10
+	psrlq	$4,%xmm15
+	pxor	%xmm6,%xmm0
+	pxor	%xmm1,%xmm15
+	pand	%xmm7,%xmm0
+	pand	%xmm7,%xmm15
+	pxor	%xmm0,%xmm6
+	psllq	$4,%xmm0
+	pxor	%xmm15,%xmm1
+	psllq	$4,%xmm15
+	pxor	%xmm9,%xmm0
+	pxor	%xmm10,%xmm15
+	movdqa	(%rax),%xmm7
+	pxor	%xmm7,%xmm5
+	pxor	%xmm7,%xmm3
+	pxor	%xmm7,%xmm1
+	pxor	%xmm7,%xmm6
+	pxor	%xmm7,%xmm2
+	pxor	%xmm7,%xmm4
+	pxor	%xmm7,%xmm15
+	pxor	%xmm7,%xmm0
+	.byte	0xf3,0xc3
+
+
+.p2align	4
+_bsaes_key_convert:
+	leaq	L$masks(%rip),%r11
+	movdqu	(%rcx),%xmm7
+	leaq	16(%rcx),%rcx
+	movdqa	0(%r11),%xmm0
+	movdqa	16(%r11),%xmm1
+	movdqa	32(%r11),%xmm2
+	movdqa	48(%r11),%xmm3
+	movdqa	64(%r11),%xmm4
+	pcmpeqd	%xmm5,%xmm5
+
+	movdqu	(%rcx),%xmm6
+	movdqa	%xmm7,(%rax)
+	leaq	16(%rax),%rax
+	decl	%r10d
+	jmp	L$key_loop
+.p2align	4
+L$key_loop:
+.byte	102,15,56,0,244
+
+	movdqa	%xmm0,%xmm8
+	movdqa	%xmm1,%xmm9
+
+	pand	%xmm6,%xmm8
+	pand	%xmm6,%xmm9
+	movdqa	%xmm2,%xmm10
+	pcmpeqb	%xmm0,%xmm8
+	psllq	$4,%xmm0
+	movdqa	%xmm3,%xmm11
+	pcmpeqb	%xmm1,%xmm9
+	psllq	$4,%xmm1
+
+	pand	%xmm6,%xmm10
+	pand	%xmm6,%xmm11
+	movdqa	%xmm0,%xmm12
+	pcmpeqb	%xmm2,%xmm10
+	psllq	$4,%xmm2
+	movdqa	%xmm1,%xmm13
+	pcmpeqb	%xmm3,%xmm11
+	psllq	$4,%xmm3
+
+	movdqa	%xmm2,%xmm14
+	movdqa	%xmm3,%xmm15
+	pxor	%xmm5,%xmm8
+	pxor	%xmm5,%xmm9
+
+	pand	%xmm6,%xmm12
+	pand	%xmm6,%xmm13
+	movdqa	%xmm8,0(%rax)
+	pcmpeqb	%xmm0,%xmm12
+	psrlq	$4,%xmm0
+	movdqa	%xmm9,16(%rax)
+	pcmpeqb	%xmm1,%xmm13
+	psrlq	$4,%xmm1
+	leaq	16(%rcx),%rcx
+
+	pand	%xmm6,%xmm14
+	pand	%xmm6,%xmm15
+	movdqa	%xmm10,32(%rax)
+	pcmpeqb	%xmm2,%xmm14
+	psrlq	$4,%xmm2
+	movdqa	%xmm11,48(%rax)
+	pcmpeqb	%xmm3,%xmm15
+	psrlq	$4,%xmm3
+	movdqu	(%rcx),%xmm6
+
+	pxor	%xmm5,%xmm13
+	pxor	%xmm5,%xmm14
+	movdqa	%xmm12,64(%rax)
+	movdqa	%xmm13,80(%rax)
+	movdqa	%xmm14,96(%rax)
+	movdqa	%xmm15,112(%rax)
+	leaq	128(%rax),%rax
+	decl	%r10d
+	jnz	L$key_loop
+
+	movdqa	80(%r11),%xmm7
+
+	.byte	0xf3,0xc3
+
+
+.globl	_bsaes_cbc_encrypt
+
+.p2align	4
+_bsaes_cbc_encrypt:
+	cmpl	$0,%r9d
+	jne	_asm_AES_cbc_encrypt
+	cmpq	$128,%rdx
+	jb	_asm_AES_cbc_encrypt
+
+	movq	%rsp,%rax
+L$cbc_dec_prologue:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	leaq	-72(%rsp),%rsp
+	movq	%rsp,%rbp
+	movl	240(%rcx),%eax
+	movq	%rdi,%r12
+	movq	%rsi,%r13
+	movq	%rdx,%r14
+	movq	%rcx,%r15
+	movq	%r8,%rbx
+	shrq	$4,%r14
+
+	movl	%eax,%edx
+	shlq	$7,%rax
+	subq	$96,%rax
+	subq	%rax,%rsp
+
+	movq	%rsp,%rax
+	movq	%r15,%rcx
+	movl	%edx,%r10d
+	call	_bsaes_key_convert
+	pxor	(%rsp),%xmm7
+	movdqa	%xmm6,(%rax)
+	movdqa	%xmm7,(%rsp)
+
+	movdqu	(%rbx),%xmm14
+	subq	$8,%r14
+L$cbc_dec_loop:
+	movdqu	0(%r12),%xmm15
+	movdqu	16(%r12),%xmm0
+	movdqu	32(%r12),%xmm1
+	movdqu	48(%r12),%xmm2
+	movdqu	64(%r12),%xmm3
+	movdqu	80(%r12),%xmm4
+	movq	%rsp,%rax
+	movdqu	96(%r12),%xmm5
+	movl	%edx,%r10d
+	movdqu	112(%r12),%xmm6
+	movdqa	%xmm14,32(%rbp)
+
+	call	_bsaes_decrypt8
+
+	pxor	32(%rbp),%xmm15
+	movdqu	0(%r12),%xmm7
+	movdqu	16(%r12),%xmm8
+	pxor	%xmm7,%xmm0
+	movdqu	32(%r12),%xmm9
+	pxor	%xmm8,%xmm5
+	movdqu	48(%r12),%xmm10
+	pxor	%xmm9,%xmm3
+	movdqu	64(%r12),%xmm11
+	pxor	%xmm10,%xmm1
+	movdqu	80(%r12),%xmm12
+	pxor	%xmm11,%xmm6
+	movdqu	96(%r12),%xmm13
+	pxor	%xmm12,%xmm2
+	movdqu	112(%r12),%xmm14
+	pxor	%xmm13,%xmm4
+	movdqu	%xmm15,0(%r13)
+	leaq	128(%r12),%r12
+	movdqu	%xmm0,16(%r13)
+	movdqu	%xmm5,32(%r13)
+	movdqu	%xmm3,48(%r13)
+	movdqu	%xmm1,64(%r13)
+	movdqu	%xmm6,80(%r13)
+	movdqu	%xmm2,96(%r13)
+	movdqu	%xmm4,112(%r13)
+	leaq	128(%r13),%r13
+	subq	$8,%r14
+	jnc	L$cbc_dec_loop
+
+	addq	$8,%r14
+	jz	L$cbc_dec_done
+
+	movdqu	0(%r12),%xmm15
+	movq	%rsp,%rax
+	movl	%edx,%r10d
+	cmpq	$2,%r14
+	jb	L$cbc_dec_one
+	movdqu	16(%r12),%xmm0
+	je	L$cbc_dec_two
+	movdqu	32(%r12),%xmm1
+	cmpq	$4,%r14
+	jb	L$cbc_dec_three
+	movdqu	48(%r12),%xmm2
+	je	L$cbc_dec_four
+	movdqu	64(%r12),%xmm3
+	cmpq	$6,%r14
+	jb	L$cbc_dec_five
+	movdqu	80(%r12),%xmm4
+	je	L$cbc_dec_six
+	movdqu	96(%r12),%xmm5
+	movdqa	%xmm14,32(%rbp)
+	call	_bsaes_decrypt8
+	pxor	32(%rbp),%xmm15
+	movdqu	0(%r12),%xmm7
+	movdqu	16(%r12),%xmm8
+	pxor	%xmm7,%xmm0
+	movdqu	32(%r12),%xmm9
+	pxor	%xmm8,%xmm5
+	movdqu	48(%r12),%xmm10
+	pxor	%xmm9,%xmm3
+	movdqu	64(%r12),%xmm11
+	pxor	%xmm10,%xmm1
+	movdqu	80(%r12),%xmm12
+	pxor	%xmm11,%xmm6
+	movdqu	96(%r12),%xmm14
+	pxor	%xmm12,%xmm2
+	movdqu	%xmm15,0(%r13)
+	movdqu	%xmm0,16(%r13)
+	movdqu	%xmm5,32(%r13)
+	movdqu	%xmm3,48(%r13)
+	movdqu	%xmm1,64(%r13)
+	movdqu	%xmm6,80(%r13)
+	movdqu	%xmm2,96(%r13)
+	jmp	L$cbc_dec_done
+.p2align	4
+L$cbc_dec_six:
+	movdqa	%xmm14,32(%rbp)
+	call	_bsaes_decrypt8
+	pxor	32(%rbp),%xmm15
+	movdqu	0(%r12),%xmm7
+	movdqu	16(%r12),%xmm8
+	pxor	%xmm7,%xmm0
+	movdqu	32(%r12),%xmm9
+	pxor	%xmm8,%xmm5
+	movdqu	48(%r12),%xmm10
+	pxor	%xmm9,%xmm3
+	movdqu	64(%r12),%xmm11
+	pxor	%xmm10,%xmm1
+	movdqu	80(%r12),%xmm14
+	pxor	%xmm11,%xmm6
+	movdqu	%xmm15,0(%r13)
+	movdqu	%xmm0,16(%r13)
+	movdqu	%xmm5,32(%r13)
+	movdqu	%xmm3,48(%r13)
+	movdqu	%xmm1,64(%r13)
+	movdqu	%xmm6,80(%r13)
+	jmp	L$cbc_dec_done
+.p2align	4
+L$cbc_dec_five:
+	movdqa	%xmm14,32(%rbp)
+	call	_bsaes_decrypt8
+	pxor	32(%rbp),%xmm15
+	movdqu	0(%r12),%xmm7
+	movdqu	16(%r12),%xmm8
+	pxor	%xmm7,%xmm0
+	movdqu	32(%r12),%xmm9
+	pxor	%xmm8,%xmm5
+	movdqu	48(%r12),%xmm10
+	pxor	%xmm9,%xmm3
+	movdqu	64(%r12),%xmm14
+	pxor	%xmm10,%xmm1
+	movdqu	%xmm15,0(%r13)
+	movdqu	%xmm0,16(%r13)
+	movdqu	%xmm5,32(%r13)
+	movdqu	%xmm3,48(%r13)
+	movdqu	%xmm1,64(%r13)
+	jmp	L$cbc_dec_done
+.p2align	4
+L$cbc_dec_four:
+	movdqa	%xmm14,32(%rbp)
+	call	_bsaes_decrypt8
+	pxor	32(%rbp),%xmm15
+	movdqu	0(%r12),%xmm7
+	movdqu	16(%r12),%xmm8
+	pxor	%xmm7,%xmm0
+	movdqu	32(%r12),%xmm9
+	pxor	%xmm8,%xmm5
+	movdqu	48(%r12),%xmm14
+	pxor	%xmm9,%xmm3
+	movdqu	%xmm15,0(%r13)
+	movdqu	%xmm0,16(%r13)
+	movdqu	%xmm5,32(%r13)
+	movdqu	%xmm3,48(%r13)
+	jmp	L$cbc_dec_done
+.p2align	4
+L$cbc_dec_three:
+	movdqa	%xmm14,32(%rbp)
+	call	_bsaes_decrypt8
+	pxor	32(%rbp),%xmm15
+	movdqu	0(%r12),%xmm7
+	movdqu	16(%r12),%xmm8
+	pxor	%xmm7,%xmm0
+	movdqu	32(%r12),%xmm14
+	pxor	%xmm8,%xmm5
+	movdqu	%xmm15,0(%r13)
+	movdqu	%xmm0,16(%r13)
+	movdqu	%xmm5,32(%r13)
+	jmp	L$cbc_dec_done
+.p2align	4
+L$cbc_dec_two:
+	movdqa	%xmm14,32(%rbp)
+	call	_bsaes_decrypt8
+	pxor	32(%rbp),%xmm15
+	movdqu	0(%r12),%xmm7
+	movdqu	16(%r12),%xmm14
+	pxor	%xmm7,%xmm0
+	movdqu	%xmm15,0(%r13)
+	movdqu	%xmm0,16(%r13)
+	jmp	L$cbc_dec_done
+.p2align	4
+L$cbc_dec_one:
+	leaq	(%r12),%rdi
+	leaq	32(%rbp),%rsi
+	leaq	(%r15),%rdx
+	call	_asm_AES_decrypt		
+	pxor	32(%rbp),%xmm14
+	movdqu	%xmm14,(%r13)
+	movdqa	%xmm15,%xmm14
+
+L$cbc_dec_done:
+	movdqu	%xmm14,(%rbx)
+	leaq	(%rsp),%rax
+	pxor	%xmm0,%xmm0
+L$cbc_dec_bzero:
+	movdqa	%xmm0,0(%rax)
+	movdqa	%xmm0,16(%rax)
+	leaq	32(%rax),%rax
+	cmpq	%rax,%rbp
+	ja	L$cbc_dec_bzero
+
+	leaq	(%rbp),%rsp
+	movq	72(%rsp),%r15
+	movq	80(%rsp),%r14
+	movq	88(%rsp),%r13
+	movq	96(%rsp),%r12
+	movq	104(%rsp),%rbx
+	movq	112(%rsp),%rax
+	leaq	120(%rsp),%rsp
+	movq	%rax,%rbp
+L$cbc_dec_epilogue:
+	.byte	0xf3,0xc3
+
+
+.globl	_bsaes_ctr32_encrypt_blocks
+
+.p2align	4
+_bsaes_ctr32_encrypt_blocks:
+	movq	%rsp,%rax
+L$ctr_enc_prologue:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	leaq	-72(%rsp),%rsp
+	movq	%rsp,%rbp
+	movdqu	(%r8),%xmm0
+	movl	240(%rcx),%eax
+	movq	%rdi,%r12
+	movq	%rsi,%r13
+	movq	%rdx,%r14
+	movq	%rcx,%r15
+	movdqa	%xmm0,32(%rbp)
+	cmpq	$8,%rdx
+	jb	L$ctr_enc_short
+
+	movl	%eax,%ebx
+	shlq	$7,%rax
+	subq	$96,%rax
+	subq	%rax,%rsp
+
+	movq	%rsp,%rax
+	movq	%r15,%rcx
+	movl	%ebx,%r10d
+	call	_bsaes_key_convert
+	pxor	%xmm6,%xmm7
+	movdqa	%xmm7,(%rax)
+
+	movdqa	(%rsp),%xmm8
+	leaq	L$ADD1(%rip),%r11
+	movdqa	32(%rbp),%xmm15
+	movdqa	-32(%r11),%xmm7
+.byte	102,68,15,56,0,199
+.byte	102,68,15,56,0,255
+	movdqa	%xmm8,(%rsp)
+	jmp	L$ctr_enc_loop
+.p2align	4
+L$ctr_enc_loop:
+	movdqa	%xmm15,32(%rbp)
+	movdqa	%xmm15,%xmm0
+	movdqa	%xmm15,%xmm1
+	paddd	0(%r11),%xmm0
+	movdqa	%xmm15,%xmm2
+	paddd	16(%r11),%xmm1
+	movdqa	%xmm15,%xmm3
+	paddd	32(%r11),%xmm2
+	movdqa	%xmm15,%xmm4
+	paddd	48(%r11),%xmm3
+	movdqa	%xmm15,%xmm5
+	paddd	64(%r11),%xmm4
+	movdqa	%xmm15,%xmm6
+	paddd	80(%r11),%xmm5
+	paddd	96(%r11),%xmm6
+
+
+
+	movdqa	(%rsp),%xmm8
+	leaq	16(%rsp),%rax
+	movdqa	-16(%r11),%xmm7
+	pxor	%xmm8,%xmm15
+	pxor	%xmm8,%xmm0
+.byte	102,68,15,56,0,255
+	pxor	%xmm8,%xmm1
+.byte	102,15,56,0,199
+	pxor	%xmm8,%xmm2
+.byte	102,15,56,0,207
+	pxor	%xmm8,%xmm3
+.byte	102,15,56,0,215
+	pxor	%xmm8,%xmm4
+.byte	102,15,56,0,223
+	pxor	%xmm8,%xmm5
+.byte	102,15,56,0,231
+	pxor	%xmm8,%xmm6
+.byte	102,15,56,0,239
+	leaq	L$BS0(%rip),%r11
+.byte	102,15,56,0,247
+	movl	%ebx,%r10d
+
+	call	_bsaes_encrypt8_bitslice
+
+	subq	$8,%r14
+	jc	L$ctr_enc_loop_done
+
+	movdqu	0(%r12),%xmm7
+	movdqu	16(%r12),%xmm8
+	movdqu	32(%r12),%xmm9
+	movdqu	48(%r12),%xmm10
+	movdqu	64(%r12),%xmm11
+	movdqu	80(%r12),%xmm12
+	movdqu	96(%r12),%xmm13
+	movdqu	112(%r12),%xmm14
+	leaq	128(%r12),%r12
+	pxor	%xmm15,%xmm7
+	movdqa	32(%rbp),%xmm15
+	pxor	%xmm8,%xmm0
+	movdqu	%xmm7,0(%r13)
+	pxor	%xmm9,%xmm3
+	movdqu	%xmm0,16(%r13)
+	pxor	%xmm10,%xmm5
+	movdqu	%xmm3,32(%r13)
+	pxor	%xmm11,%xmm2
+	movdqu	%xmm5,48(%r13)
+	pxor	%xmm12,%xmm6
+	movdqu	%xmm2,64(%r13)
+	pxor	%xmm13,%xmm1
+	movdqu	%xmm6,80(%r13)
+	pxor	%xmm14,%xmm4
+	movdqu	%xmm1,96(%r13)
+	leaq	L$ADD1(%rip),%r11
+	movdqu	%xmm4,112(%r13)
+	leaq	128(%r13),%r13
+	paddd	112(%r11),%xmm15
+	jnz	L$ctr_enc_loop
+
+	jmp	L$ctr_enc_done
+.p2align	4
+L$ctr_enc_loop_done:
+	addq	$8,%r14
+	movdqu	0(%r12),%xmm7
+	pxor	%xmm7,%xmm15
+	movdqu	%xmm15,0(%r13)
+	cmpq	$2,%r14
+	jb	L$ctr_enc_done
+	movdqu	16(%r12),%xmm8
+	pxor	%xmm8,%xmm0
+	movdqu	%xmm0,16(%r13)
+	je	L$ctr_enc_done
+	movdqu	32(%r12),%xmm9
+	pxor	%xmm9,%xmm3
+	movdqu	%xmm3,32(%r13)
+	cmpq	$4,%r14
+	jb	L$ctr_enc_done
+	movdqu	48(%r12),%xmm10
+	pxor	%xmm10,%xmm5
+	movdqu	%xmm5,48(%r13)
+	je	L$ctr_enc_done
+	movdqu	64(%r12),%xmm11
+	pxor	%xmm11,%xmm2
+	movdqu	%xmm2,64(%r13)
+	cmpq	$6,%r14
+	jb	L$ctr_enc_done
+	movdqu	80(%r12),%xmm12
+	pxor	%xmm12,%xmm6
+	movdqu	%xmm6,80(%r13)
+	je	L$ctr_enc_done
+	movdqu	96(%r12),%xmm13
+	pxor	%xmm13,%xmm1
+	movdqu	%xmm1,96(%r13)
+	jmp	L$ctr_enc_done
+
+.p2align	4
+L$ctr_enc_short:
+	leaq	32(%rbp),%rdi
+	leaq	48(%rbp),%rsi
+	leaq	(%r15),%rdx
+	call	_asm_AES_encrypt
+	movdqu	(%r12),%xmm0
+	leaq	16(%r12),%r12
+	movl	44(%rbp),%eax
+	bswapl	%eax
+	pxor	48(%rbp),%xmm0
+	incl	%eax
+	movdqu	%xmm0,(%r13)
+	bswapl	%eax
+	leaq	16(%r13),%r13
+	movl	%eax,44(%rsp)
+	decq	%r14
+	jnz	L$ctr_enc_short
+
+L$ctr_enc_done:
+	leaq	(%rsp),%rax
+	pxor	%xmm0,%xmm0
+L$ctr_enc_bzero:
+	movdqa	%xmm0,0(%rax)
+	movdqa	%xmm0,16(%rax)
+	leaq	32(%rax),%rax
+	cmpq	%rax,%rbp
+	ja	L$ctr_enc_bzero
+
+	leaq	(%rbp),%rsp
+	movq	72(%rsp),%r15
+	movq	80(%rsp),%r14
+	movq	88(%rsp),%r13
+	movq	96(%rsp),%r12
+	movq	104(%rsp),%rbx
+	movq	112(%rsp),%rax
+	leaq	120(%rsp),%rsp
+	movq	%rax,%rbp
+L$ctr_enc_epilogue:
+	.byte	0xf3,0xc3
+
+.globl	_bsaes_xts_encrypt
+
+.p2align	4
+_bsaes_xts_encrypt:
+	movq	%rsp,%rax
+L$xts_enc_prologue:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	leaq	-72(%rsp),%rsp
+	movq	%rsp,%rbp
+	movq	%rdi,%r12
+	movq	%rsi,%r13
+	movq	%rdx,%r14
+	movq	%rcx,%r15
+
+	leaq	(%r9),%rdi
+	leaq	32(%rbp),%rsi
+	leaq	(%r8),%rdx
+	call	_asm_AES_encrypt		
+
+	movl	240(%r15),%eax
+	movq	%r14,%rbx
+
+	movl	%eax,%edx
+	shlq	$7,%rax
+	subq	$96,%rax
+	subq	%rax,%rsp
+
+	movq	%rsp,%rax
+	movq	%r15,%rcx
+	movl	%edx,%r10d
+	call	_bsaes_key_convert
+	pxor	%xmm6,%xmm7
+	movdqa	%xmm7,(%rax)
+
+	andq	$-16,%r14
+	subq	$128,%rsp
+	movdqa	32(%rbp),%xmm6
+
+	pxor	%xmm14,%xmm14
+	movdqa	L$xts_magic(%rip),%xmm12
+	pcmpgtd	%xmm6,%xmm14
+
+	subq	$128,%r14
+	jc	L$xts_enc_short
+	jmp	L$xts_enc_loop
+
+.p2align	4
+L$xts_enc_loop:
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm15
+	movdqa	%xmm6,0(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm0
+	movdqa	%xmm6,16(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	0(%r12),%xmm7
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm1
+	movdqa	%xmm6,32(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	16(%r12),%xmm8
+	pxor	%xmm7,%xmm15
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm2
+	movdqa	%xmm6,48(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	32(%r12),%xmm9
+	pxor	%xmm8,%xmm0
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm3
+	movdqa	%xmm6,64(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	48(%r12),%xmm10
+	pxor	%xmm9,%xmm1
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm4
+	movdqa	%xmm6,80(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	64(%r12),%xmm11
+	pxor	%xmm10,%xmm2
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm5
+	movdqa	%xmm6,96(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	80(%r12),%xmm12
+	pxor	%xmm11,%xmm3
+	movdqu	96(%r12),%xmm13
+	pxor	%xmm12,%xmm4
+	movdqu	112(%r12),%xmm14
+	leaq	128(%r12),%r12
+	movdqa	%xmm6,112(%rsp)
+	pxor	%xmm13,%xmm5
+	leaq	128(%rsp),%rax
+	pxor	%xmm14,%xmm6
+	movl	%edx,%r10d
+
+	call	_bsaes_encrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm3
+	movdqu	%xmm0,16(%r13)
+	pxor	48(%rsp),%xmm5
+	movdqu	%xmm3,32(%r13)
+	pxor	64(%rsp),%xmm2
+	movdqu	%xmm5,48(%r13)
+	pxor	80(%rsp),%xmm6
+	movdqu	%xmm2,64(%r13)
+	pxor	96(%rsp),%xmm1
+	movdqu	%xmm6,80(%r13)
+	pxor	112(%rsp),%xmm4
+	movdqu	%xmm1,96(%r13)
+	movdqu	%xmm4,112(%r13)
+	leaq	128(%r13),%r13
+
+	movdqa	112(%rsp),%xmm6
+	pxor	%xmm14,%xmm14
+	movdqa	L$xts_magic(%rip),%xmm12
+	pcmpgtd	%xmm6,%xmm14
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+
+	subq	$128,%r14
+	jnc	L$xts_enc_loop
+
+L$xts_enc_short:
+	addq	$128,%r14
+	jz	L$xts_enc_done
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm15
+	movdqa	%xmm6,0(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm0
+	movdqa	%xmm6,16(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	0(%r12),%xmm7
+	cmpq	$16,%r14
+	je	L$xts_enc_1
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm1
+	movdqa	%xmm6,32(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	16(%r12),%xmm8
+	cmpq	$32,%r14
+	je	L$xts_enc_2
+	pxor	%xmm7,%xmm15
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm2
+	movdqa	%xmm6,48(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	32(%r12),%xmm9
+	cmpq	$48,%r14
+	je	L$xts_enc_3
+	pxor	%xmm8,%xmm0
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm3
+	movdqa	%xmm6,64(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	48(%r12),%xmm10
+	cmpq	$64,%r14
+	je	L$xts_enc_4
+	pxor	%xmm9,%xmm1
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm4
+	movdqa	%xmm6,80(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	64(%r12),%xmm11
+	cmpq	$80,%r14
+	je	L$xts_enc_5
+	pxor	%xmm10,%xmm2
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm5
+	movdqa	%xmm6,96(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	80(%r12),%xmm12
+	cmpq	$96,%r14
+	je	L$xts_enc_6
+	pxor	%xmm11,%xmm3
+	movdqu	96(%r12),%xmm13
+	pxor	%xmm12,%xmm4
+	movdqa	%xmm6,112(%rsp)
+	leaq	112(%r12),%r12
+	pxor	%xmm13,%xmm5
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_encrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm3
+	movdqu	%xmm0,16(%r13)
+	pxor	48(%rsp),%xmm5
+	movdqu	%xmm3,32(%r13)
+	pxor	64(%rsp),%xmm2
+	movdqu	%xmm5,48(%r13)
+	pxor	80(%rsp),%xmm6
+	movdqu	%xmm2,64(%r13)
+	pxor	96(%rsp),%xmm1
+	movdqu	%xmm6,80(%r13)
+	movdqu	%xmm1,96(%r13)
+	leaq	112(%r13),%r13
+
+	movdqa	112(%rsp),%xmm6
+	jmp	L$xts_enc_done
+.p2align	4
+L$xts_enc_6:
+	pxor	%xmm11,%xmm3
+	leaq	96(%r12),%r12
+	pxor	%xmm12,%xmm4
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_encrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm3
+	movdqu	%xmm0,16(%r13)
+	pxor	48(%rsp),%xmm5
+	movdqu	%xmm3,32(%r13)
+	pxor	64(%rsp),%xmm2
+	movdqu	%xmm5,48(%r13)
+	pxor	80(%rsp),%xmm6
+	movdqu	%xmm2,64(%r13)
+	movdqu	%xmm6,80(%r13)
+	leaq	96(%r13),%r13
+
+	movdqa	96(%rsp),%xmm6
+	jmp	L$xts_enc_done
+.p2align	4
+L$xts_enc_5:
+	pxor	%xmm10,%xmm2
+	leaq	80(%r12),%r12
+	pxor	%xmm11,%xmm3
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_encrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm3
+	movdqu	%xmm0,16(%r13)
+	pxor	48(%rsp),%xmm5
+	movdqu	%xmm3,32(%r13)
+	pxor	64(%rsp),%xmm2
+	movdqu	%xmm5,48(%r13)
+	movdqu	%xmm2,64(%r13)
+	leaq	80(%r13),%r13
+
+	movdqa	80(%rsp),%xmm6
+	jmp	L$xts_enc_done
+.p2align	4
+L$xts_enc_4:
+	pxor	%xmm9,%xmm1
+	leaq	64(%r12),%r12
+	pxor	%xmm10,%xmm2
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_encrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm3
+	movdqu	%xmm0,16(%r13)
+	pxor	48(%rsp),%xmm5
+	movdqu	%xmm3,32(%r13)
+	movdqu	%xmm5,48(%r13)
+	leaq	64(%r13),%r13
+
+	movdqa	64(%rsp),%xmm6
+	jmp	L$xts_enc_done
+.p2align	4
+L$xts_enc_3:
+	pxor	%xmm8,%xmm0
+	leaq	48(%r12),%r12
+	pxor	%xmm9,%xmm1
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_encrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm3
+	movdqu	%xmm0,16(%r13)
+	movdqu	%xmm3,32(%r13)
+	leaq	48(%r13),%r13
+
+	movdqa	48(%rsp),%xmm6
+	jmp	L$xts_enc_done
+.p2align	4
+L$xts_enc_2:
+	pxor	%xmm7,%xmm15
+	leaq	32(%r12),%r12
+	pxor	%xmm8,%xmm0
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_encrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	movdqu	%xmm0,16(%r13)
+	leaq	32(%r13),%r13
+
+	movdqa	32(%rsp),%xmm6
+	jmp	L$xts_enc_done
+.p2align	4
+L$xts_enc_1:
+	pxor	%xmm15,%xmm7
+	leaq	16(%r12),%r12
+	movdqa	%xmm7,32(%rbp)
+	leaq	32(%rbp),%rdi
+	leaq	32(%rbp),%rsi
+	leaq	(%r15),%rdx
+	call	_asm_AES_encrypt		
+	pxor	32(%rbp),%xmm15
+
+
+
+
+
+	movdqu	%xmm15,0(%r13)
+	leaq	16(%r13),%r13
+
+	movdqa	16(%rsp),%xmm6
+
+L$xts_enc_done:
+	andl	$15,%ebx
+	jz	L$xts_enc_ret
+	movq	%r13,%rdx
+
+L$xts_enc_steal:
+	movzbl	(%r12),%eax
+	movzbl	-16(%rdx),%ecx
+	leaq	1(%r12),%r12
+	movb	%al,-16(%rdx)
+	movb	%cl,0(%rdx)
+	leaq	1(%rdx),%rdx
+	subl	$1,%ebx
+	jnz	L$xts_enc_steal
+
+	movdqu	-16(%r13),%xmm15
+	leaq	32(%rbp),%rdi
+	pxor	%xmm6,%xmm15
+	leaq	32(%rbp),%rsi
+	movdqa	%xmm15,32(%rbp)
+	leaq	(%r15),%rdx
+	call	_asm_AES_encrypt		
+	pxor	32(%rbp),%xmm6
+	movdqu	%xmm6,-16(%r13)
+
+L$xts_enc_ret:
+	leaq	(%rsp),%rax
+	pxor	%xmm0,%xmm0
+L$xts_enc_bzero:
+	movdqa	%xmm0,0(%rax)
+	movdqa	%xmm0,16(%rax)
+	leaq	32(%rax),%rax
+	cmpq	%rax,%rbp
+	ja	L$xts_enc_bzero
+
+	leaq	(%rbp),%rsp
+	movq	72(%rsp),%r15
+	movq	80(%rsp),%r14
+	movq	88(%rsp),%r13
+	movq	96(%rsp),%r12
+	movq	104(%rsp),%rbx
+	movq	112(%rsp),%rax
+	leaq	120(%rsp),%rsp
+	movq	%rax,%rbp
+L$xts_enc_epilogue:
+	.byte	0xf3,0xc3
+
+
+.globl	_bsaes_xts_decrypt
+
+.p2align	4
+_bsaes_xts_decrypt:
+	movq	%rsp,%rax
+L$xts_dec_prologue:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	leaq	-72(%rsp),%rsp
+	movq	%rsp,%rbp
+	movq	%rdi,%r12
+	movq	%rsi,%r13
+	movq	%rdx,%r14
+	movq	%rcx,%r15
+
+	leaq	(%r9),%rdi
+	leaq	32(%rbp),%rsi
+	leaq	(%r8),%rdx
+	call	_asm_AES_encrypt		
+
+	movl	240(%r15),%eax
+	movq	%r14,%rbx
+
+	movl	%eax,%edx
+	shlq	$7,%rax
+	subq	$96,%rax
+	subq	%rax,%rsp
+
+	movq	%rsp,%rax
+	movq	%r15,%rcx
+	movl	%edx,%r10d
+	call	_bsaes_key_convert
+	pxor	(%rsp),%xmm7
+	movdqa	%xmm6,(%rax)
+	movdqa	%xmm7,(%rsp)
+
+	xorl	%eax,%eax
+	andq	$-16,%r14
+	testl	$15,%ebx
+	setnz	%al
+	shlq	$4,%rax
+	subq	%rax,%r14
+
+	subq	$128,%rsp
+	movdqa	32(%rbp),%xmm6
+
+	pxor	%xmm14,%xmm14
+	movdqa	L$xts_magic(%rip),%xmm12
+	pcmpgtd	%xmm6,%xmm14
+
+	subq	$128,%r14
+	jc	L$xts_dec_short
+	jmp	L$xts_dec_loop
+
+.p2align	4
+L$xts_dec_loop:
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm15
+	movdqa	%xmm6,0(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm0
+	movdqa	%xmm6,16(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	0(%r12),%xmm7
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm1
+	movdqa	%xmm6,32(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	16(%r12),%xmm8
+	pxor	%xmm7,%xmm15
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm2
+	movdqa	%xmm6,48(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	32(%r12),%xmm9
+	pxor	%xmm8,%xmm0
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm3
+	movdqa	%xmm6,64(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	48(%r12),%xmm10
+	pxor	%xmm9,%xmm1
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm4
+	movdqa	%xmm6,80(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	64(%r12),%xmm11
+	pxor	%xmm10,%xmm2
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm5
+	movdqa	%xmm6,96(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	80(%r12),%xmm12
+	pxor	%xmm11,%xmm3
+	movdqu	96(%r12),%xmm13
+	pxor	%xmm12,%xmm4
+	movdqu	112(%r12),%xmm14
+	leaq	128(%r12),%r12
+	movdqa	%xmm6,112(%rsp)
+	pxor	%xmm13,%xmm5
+	leaq	128(%rsp),%rax
+	pxor	%xmm14,%xmm6
+	movl	%edx,%r10d
+
+	call	_bsaes_decrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm5
+	movdqu	%xmm0,16(%r13)
+	pxor	48(%rsp),%xmm3
+	movdqu	%xmm5,32(%r13)
+	pxor	64(%rsp),%xmm1
+	movdqu	%xmm3,48(%r13)
+	pxor	80(%rsp),%xmm6
+	movdqu	%xmm1,64(%r13)
+	pxor	96(%rsp),%xmm2
+	movdqu	%xmm6,80(%r13)
+	pxor	112(%rsp),%xmm4
+	movdqu	%xmm2,96(%r13)
+	movdqu	%xmm4,112(%r13)
+	leaq	128(%r13),%r13
+
+	movdqa	112(%rsp),%xmm6
+	pxor	%xmm14,%xmm14
+	movdqa	L$xts_magic(%rip),%xmm12
+	pcmpgtd	%xmm6,%xmm14
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+
+	subq	$128,%r14
+	jnc	L$xts_dec_loop
+
+L$xts_dec_short:
+	addq	$128,%r14
+	jz	L$xts_dec_done
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm15
+	movdqa	%xmm6,0(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm0
+	movdqa	%xmm6,16(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	0(%r12),%xmm7
+	cmpq	$16,%r14
+	je	L$xts_dec_1
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm1
+	movdqa	%xmm6,32(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	16(%r12),%xmm8
+	cmpq	$32,%r14
+	je	L$xts_dec_2
+	pxor	%xmm7,%xmm15
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm2
+	movdqa	%xmm6,48(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	32(%r12),%xmm9
+	cmpq	$48,%r14
+	je	L$xts_dec_3
+	pxor	%xmm8,%xmm0
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm3
+	movdqa	%xmm6,64(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	48(%r12),%xmm10
+	cmpq	$64,%r14
+	je	L$xts_dec_4
+	pxor	%xmm9,%xmm1
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm4
+	movdqa	%xmm6,80(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	64(%r12),%xmm11
+	cmpq	$80,%r14
+	je	L$xts_dec_5
+	pxor	%xmm10,%xmm2
+	pshufd	$19,%xmm14,%xmm13
+	pxor	%xmm14,%xmm14
+	movdqa	%xmm6,%xmm5
+	movdqa	%xmm6,96(%rsp)
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	pcmpgtd	%xmm6,%xmm14
+	pxor	%xmm13,%xmm6
+	movdqu	80(%r12),%xmm12
+	cmpq	$96,%r14
+	je	L$xts_dec_6
+	pxor	%xmm11,%xmm3
+	movdqu	96(%r12),%xmm13
+	pxor	%xmm12,%xmm4
+	movdqa	%xmm6,112(%rsp)
+	leaq	112(%r12),%r12
+	pxor	%xmm13,%xmm5
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_decrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm5
+	movdqu	%xmm0,16(%r13)
+	pxor	48(%rsp),%xmm3
+	movdqu	%xmm5,32(%r13)
+	pxor	64(%rsp),%xmm1
+	movdqu	%xmm3,48(%r13)
+	pxor	80(%rsp),%xmm6
+	movdqu	%xmm1,64(%r13)
+	pxor	96(%rsp),%xmm2
+	movdqu	%xmm6,80(%r13)
+	movdqu	%xmm2,96(%r13)
+	leaq	112(%r13),%r13
+
+	movdqa	112(%rsp),%xmm6
+	jmp	L$xts_dec_done
+.p2align	4
+L$xts_dec_6:
+	pxor	%xmm11,%xmm3
+	leaq	96(%r12),%r12
+	pxor	%xmm12,%xmm4
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_decrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm5
+	movdqu	%xmm0,16(%r13)
+	pxor	48(%rsp),%xmm3
+	movdqu	%xmm5,32(%r13)
+	pxor	64(%rsp),%xmm1
+	movdqu	%xmm3,48(%r13)
+	pxor	80(%rsp),%xmm6
+	movdqu	%xmm1,64(%r13)
+	movdqu	%xmm6,80(%r13)
+	leaq	96(%r13),%r13
+
+	movdqa	96(%rsp),%xmm6
+	jmp	L$xts_dec_done
+.p2align	4
+L$xts_dec_5:
+	pxor	%xmm10,%xmm2
+	leaq	80(%r12),%r12
+	pxor	%xmm11,%xmm3
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_decrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm5
+	movdqu	%xmm0,16(%r13)
+	pxor	48(%rsp),%xmm3
+	movdqu	%xmm5,32(%r13)
+	pxor	64(%rsp),%xmm1
+	movdqu	%xmm3,48(%r13)
+	movdqu	%xmm1,64(%r13)
+	leaq	80(%r13),%r13
+
+	movdqa	80(%rsp),%xmm6
+	jmp	L$xts_dec_done
+.p2align	4
+L$xts_dec_4:
+	pxor	%xmm9,%xmm1
+	leaq	64(%r12),%r12
+	pxor	%xmm10,%xmm2
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_decrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm5
+	movdqu	%xmm0,16(%r13)
+	pxor	48(%rsp),%xmm3
+	movdqu	%xmm5,32(%r13)
+	movdqu	%xmm3,48(%r13)
+	leaq	64(%r13),%r13
+
+	movdqa	64(%rsp),%xmm6
+	jmp	L$xts_dec_done
+.p2align	4
+L$xts_dec_3:
+	pxor	%xmm8,%xmm0
+	leaq	48(%r12),%r12
+	pxor	%xmm9,%xmm1
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_decrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	pxor	32(%rsp),%xmm5
+	movdqu	%xmm0,16(%r13)
+	movdqu	%xmm5,32(%r13)
+	leaq	48(%r13),%r13
+
+	movdqa	48(%rsp),%xmm6
+	jmp	L$xts_dec_done
+.p2align	4
+L$xts_dec_2:
+	pxor	%xmm7,%xmm15
+	leaq	32(%r12),%r12
+	pxor	%xmm8,%xmm0
+	leaq	128(%rsp),%rax
+	movl	%edx,%r10d
+
+	call	_bsaes_decrypt8
+
+	pxor	0(%rsp),%xmm15
+	pxor	16(%rsp),%xmm0
+	movdqu	%xmm15,0(%r13)
+	movdqu	%xmm0,16(%r13)
+	leaq	32(%r13),%r13
+
+	movdqa	32(%rsp),%xmm6
+	jmp	L$xts_dec_done
+.p2align	4
+L$xts_dec_1:
+	pxor	%xmm15,%xmm7
+	leaq	16(%r12),%r12
+	movdqa	%xmm7,32(%rbp)
+	leaq	32(%rbp),%rdi
+	leaq	32(%rbp),%rsi
+	leaq	(%r15),%rdx
+	call	_asm_AES_decrypt		
+	pxor	32(%rbp),%xmm15
+
+
+
+
+
+	movdqu	%xmm15,0(%r13)
+	leaq	16(%r13),%r13
+
+	movdqa	16(%rsp),%xmm6
+
+L$xts_dec_done:
+	andl	$15,%ebx
+	jz	L$xts_dec_ret
+
+	pxor	%xmm14,%xmm14
+	movdqa	L$xts_magic(%rip),%xmm12
+	pcmpgtd	%xmm6,%xmm14
+	pshufd	$19,%xmm14,%xmm13
+	movdqa	%xmm6,%xmm5
+	paddq	%xmm6,%xmm6
+	pand	%xmm12,%xmm13
+	movdqu	(%r12),%xmm15
+	pxor	%xmm13,%xmm6
+
+	leaq	32(%rbp),%rdi
+	pxor	%xmm6,%xmm15
+	leaq	32(%rbp),%rsi
+	movdqa	%xmm15,32(%rbp)
+	leaq	(%r15),%rdx
+	call	_asm_AES_decrypt		
+	pxor	32(%rbp),%xmm6
+	movq	%r13,%rdx
+	movdqu	%xmm6,(%r13)
+
+L$xts_dec_steal:
+	movzbl	16(%r12),%eax
+	movzbl	(%rdx),%ecx
+	leaq	1(%r12),%r12
+	movb	%al,(%rdx)
+	movb	%cl,16(%rdx)
+	leaq	1(%rdx),%rdx
+	subl	$1,%ebx
+	jnz	L$xts_dec_steal
+
+	movdqu	(%r13),%xmm15
+	leaq	32(%rbp),%rdi
+	pxor	%xmm5,%xmm15
+	leaq	32(%rbp),%rsi
+	movdqa	%xmm15,32(%rbp)
+	leaq	(%r15),%rdx
+	call	_asm_AES_decrypt		
+	pxor	32(%rbp),%xmm5
+	movdqu	%xmm5,(%r13)
+
+L$xts_dec_ret:
+	leaq	(%rsp),%rax
+	pxor	%xmm0,%xmm0
+L$xts_dec_bzero:
+	movdqa	%xmm0,0(%rax)
+	movdqa	%xmm0,16(%rax)
+	leaq	32(%rax),%rax
+	cmpq	%rax,%rbp
+	ja	L$xts_dec_bzero
+
+	leaq	(%rbp),%rsp
+	movq	72(%rsp),%r15
+	movq	80(%rsp),%r14
+	movq	88(%rsp),%r13
+	movq	96(%rsp),%r12
+	movq	104(%rsp),%rbx
+	movq	112(%rsp),%rax
+	leaq	120(%rsp),%rsp
+	movq	%rax,%rbp
+L$xts_dec_epilogue:
+	.byte	0xf3,0xc3
+
+
+.p2align	6
+_bsaes_const:
+L$M0ISR:
+.quad	0x0a0e0206070b0f03, 0x0004080c0d010509
+L$ISRM0:
+.quad	0x01040b0e0205080f, 0x0306090c00070a0d
+L$ISR:
+.quad	0x0504070602010003, 0x0f0e0d0c080b0a09
+L$BS0:
+.quad	0x5555555555555555, 0x5555555555555555
+L$BS1:
+.quad	0x3333333333333333, 0x3333333333333333
+L$BS2:
+.quad	0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f
+L$SR:
+.quad	0x0504070600030201, 0x0f0e0d0c0a09080b
+L$SRM0:
+.quad	0x0304090e00050a0f, 0x01060b0c0207080d
+L$M0SR:
+.quad	0x0a0e02060f03070b, 0x0004080c05090d01
+L$SWPUP:
+.quad	0x0706050403020100, 0x0c0d0e0f0b0a0908
+L$SWPUPM0SR:
+.quad	0x0a0d02060c03070b, 0x0004080f05090e01
+L$ADD1:
+.quad	0x0000000000000000, 0x0000000100000000
+L$ADD2:
+.quad	0x0000000000000000, 0x0000000200000000
+L$ADD3:
+.quad	0x0000000000000000, 0x0000000300000000
+L$ADD4:
+.quad	0x0000000000000000, 0x0000000400000000
+L$ADD5:
+.quad	0x0000000000000000, 0x0000000500000000
+L$ADD6:
+.quad	0x0000000000000000, 0x0000000600000000
+L$ADD7:
+.quad	0x0000000000000000, 0x0000000700000000
+L$ADD8:
+.quad	0x0000000000000000, 0x0000000800000000
+L$xts_magic:
+.long	0x87,0,1,0
+L$masks:
+.quad	0x0101010101010101, 0x0101010101010101
+.quad	0x0202020202020202, 0x0202020202020202
+.quad	0x0404040404040404, 0x0404040404040404
+.quad	0x0808080808080808, 0x0808080808080808
+L$M0:
+.quad	0x02060a0e03070b0f, 0x0004080c0105090d
+L$63:
+.quad	0x6363636363636363, 0x6363636363636363
+.byte	66,105,116,45,115,108,105,99,101,100,32,65,69,83,32,102,111,114,32,120,56,54,95,54,52,47,83,83,83,69,51,44,32,69,109,105,108,105,97,32,75,195,164,115,112,101,114,44,32,80,101,116,101,114,32,83,99,104,119,97,98,101,44,32,65,110,100,121,32,80,111,108,121,97,107,111,118,0
+.p2align	6
+
diff --git a/crypto/libressl/crypto/aes/vpaes-elf-x86_64.s b/crypto/libressl/crypto/aes/vpaes-elf-x86_64.s
new file mode 100644
index 0000000000..3f918c05ae
--- /dev/null
+++ b/crypto/libressl/crypto/aes/vpaes-elf-x86_64.s
@@ -0,0 +1,831 @@
+.text	
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+.type	_vpaes_encrypt_core,@function
+.align	16
+_vpaes_encrypt_core:
+	movq	%rdx,%r9
+	movq	$16,%r11
+	movl	240(%rdx),%eax
+	movdqa	%xmm9,%xmm1
+	movdqa	.Lk_ipt(%rip),%xmm2
+	pandn	%xmm0,%xmm1
+	movdqu	(%r9),%xmm5
+	psrld	$4,%xmm1
+	pand	%xmm9,%xmm0
+.byte	102,15,56,0,208
+	movdqa	.Lk_ipt+16(%rip),%xmm0
+.byte	102,15,56,0,193
+	pxor	%xmm5,%xmm2
+	pxor	%xmm2,%xmm0
+	addq	$16,%r9
+	leaq	.Lk_mc_backward(%rip),%r10
+	jmp	.Lenc_entry
+
+.align	16
+.Lenc_loop:
+
+	movdqa	%xmm13,%xmm4
+.byte	102,15,56,0,226
+	pxor	%xmm5,%xmm4
+	movdqa	%xmm12,%xmm0
+.byte	102,15,56,0,195
+	pxor	%xmm4,%xmm0
+	movdqa	%xmm15,%xmm5
+.byte	102,15,56,0,234
+	movdqa	-64(%r11,%r10,1),%xmm1
+	movdqa	%xmm14,%xmm2
+.byte	102,15,56,0,211
+	pxor	%xmm5,%xmm2
+	movdqa	(%r11,%r10,1),%xmm4
+	movdqa	%xmm0,%xmm3
+.byte	102,15,56,0,193
+	addq	$16,%r9
+	pxor	%xmm2,%xmm0
+.byte	102,15,56,0,220
+	addq	$16,%r11
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,193
+	andq	$48,%r11
+	pxor	%xmm3,%xmm0
+	subq	$1,%rax
+
+.Lenc_entry:
+
+	movdqa	%xmm9,%xmm1
+	pandn	%xmm0,%xmm1
+	psrld	$4,%xmm1
+	pand	%xmm9,%xmm0
+	movdqa	%xmm11,%xmm5
+.byte	102,15,56,0,232
+	pxor	%xmm1,%xmm0
+	movdqa	%xmm10,%xmm3
+.byte	102,15,56,0,217
+	pxor	%xmm5,%xmm3
+	movdqa	%xmm10,%xmm4
+.byte	102,15,56,0,224
+	pxor	%xmm5,%xmm4
+	movdqa	%xmm10,%xmm2
+.byte	102,15,56,0,211
+	pxor	%xmm0,%xmm2
+	movdqa	%xmm10,%xmm3
+	movdqu	(%r9),%xmm5
+.byte	102,15,56,0,220
+	pxor	%xmm1,%xmm3
+	jnz	.Lenc_loop
+
+
+	movdqa	-96(%r10),%xmm4
+	movdqa	-80(%r10),%xmm0
+.byte	102,15,56,0,226
+	pxor	%xmm5,%xmm4
+.byte	102,15,56,0,195
+	movdqa	64(%r11,%r10,1),%xmm1
+	pxor	%xmm4,%xmm0
+.byte	102,15,56,0,193
+	.byte	0xf3,0xc3
+.size	_vpaes_encrypt_core,.-_vpaes_encrypt_core
+
+
+
+
+
+
+.type	_vpaes_decrypt_core,@function
+.align	16
+_vpaes_decrypt_core:
+	movq	%rdx,%r9
+	movl	240(%rdx),%eax
+	movdqa	%xmm9,%xmm1
+	movdqa	.Lk_dipt(%rip),%xmm2
+	pandn	%xmm0,%xmm1
+	movq	%rax,%r11
+	psrld	$4,%xmm1
+	movdqu	(%r9),%xmm5
+	shlq	$4,%r11
+	pand	%xmm9,%xmm0
+.byte	102,15,56,0,208
+	movdqa	.Lk_dipt+16(%rip),%xmm0
+	xorq	$48,%r11
+	leaq	.Lk_dsbd(%rip),%r10
+.byte	102,15,56,0,193
+	andq	$48,%r11
+	pxor	%xmm5,%xmm2
+	movdqa	.Lk_mc_forward+48(%rip),%xmm5
+	pxor	%xmm2,%xmm0
+	addq	$16,%r9
+	addq	%r10,%r11
+	jmp	.Ldec_entry
+
+.align	16
+.Ldec_loop:
+
+
+
+	movdqa	-32(%r10),%xmm4
+.byte	102,15,56,0,226
+	pxor	%xmm0,%xmm4
+	movdqa	-16(%r10),%xmm0
+.byte	102,15,56,0,195
+	pxor	%xmm4,%xmm0
+	addq	$16,%r9
+
+.byte	102,15,56,0,197
+	movdqa	0(%r10),%xmm4
+.byte	102,15,56,0,226
+	pxor	%xmm0,%xmm4
+	movdqa	16(%r10),%xmm0
+.byte	102,15,56,0,195
+	pxor	%xmm4,%xmm0
+	subq	$1,%rax
+
+.byte	102,15,56,0,197
+	movdqa	32(%r10),%xmm4
+.byte	102,15,56,0,226
+	pxor	%xmm0,%xmm4
+	movdqa	48(%r10),%xmm0
+.byte	102,15,56,0,195
+	pxor	%xmm4,%xmm0
+
+.byte	102,15,56,0,197
+	movdqa	64(%r10),%xmm4
+.byte	102,15,56,0,226
+	pxor	%xmm0,%xmm4
+	movdqa	80(%r10),%xmm0
+.byte	102,15,56,0,195
+	pxor	%xmm4,%xmm0
+
+.byte	102,15,58,15,237,12
+
+.Ldec_entry:
+
+	movdqa	%xmm9,%xmm1
+	pandn	%xmm0,%xmm1
+	psrld	$4,%xmm1
+	pand	%xmm9,%xmm0
+	movdqa	%xmm11,%xmm2
+.byte	102,15,56,0,208
+	pxor	%xmm1,%xmm0
+	movdqa	%xmm10,%xmm3
+.byte	102,15,56,0,217
+	pxor	%xmm2,%xmm3
+	movdqa	%xmm10,%xmm4
+.byte	102,15,56,0,224
+	pxor	%xmm2,%xmm4
+	movdqa	%xmm10,%xmm2
+.byte	102,15,56,0,211
+	pxor	%xmm0,%xmm2
+	movdqa	%xmm10,%xmm3
+.byte	102,15,56,0,220
+	pxor	%xmm1,%xmm3
+	movdqu	(%r9),%xmm0
+	jnz	.Ldec_loop
+
+
+	movdqa	96(%r10),%xmm4
+.byte	102,15,56,0,226
+	pxor	%xmm0,%xmm4
+	movdqa	112(%r10),%xmm0
+	movdqa	-352(%r11),%xmm2
+.byte	102,15,56,0,195
+	pxor	%xmm4,%xmm0
+.byte	102,15,56,0,194
+	.byte	0xf3,0xc3
+.size	_vpaes_decrypt_core,.-_vpaes_decrypt_core
+
+
+
+
+
+
+.type	_vpaes_schedule_core,@function
+.align	16
+_vpaes_schedule_core:
+
+
+
+
+
+	call	_vpaes_preheat		
+	movdqa	.Lk_rcon(%rip),%xmm8
+	movdqu	(%rdi),%xmm0
+
+
+	movdqa	%xmm0,%xmm3
+	leaq	.Lk_ipt(%rip),%r11
+	call	_vpaes_schedule_transform
+	movdqa	%xmm0,%xmm7
+
+	leaq	.Lk_sr(%rip),%r10
+	testq	%rcx,%rcx
+	jnz	.Lschedule_am_decrypting
+
+
+	movdqu	%xmm0,(%rdx)
+	jmp	.Lschedule_go
+
+.Lschedule_am_decrypting:
+
+	movdqa	(%r8,%r10,1),%xmm1
+.byte	102,15,56,0,217
+	movdqu	%xmm3,(%rdx)
+	xorq	$48,%r8
+
+.Lschedule_go:
+	cmpl	$192,%esi
+	ja	.Lschedule_256
+	je	.Lschedule_192
+
+
+
+
+
+
+
+
+
+
+.Lschedule_128:
+	movl	$10,%esi
+
+.Loop_schedule_128:
+	call	_vpaes_schedule_round
+	decq	%rsi
+	jz	.Lschedule_mangle_last
+	call	_vpaes_schedule_mangle	
+	jmp	.Loop_schedule_128
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+.align	16
+.Lschedule_192:
+	movdqu	8(%rdi),%xmm0
+	call	_vpaes_schedule_transform	
+	movdqa	%xmm0,%xmm6
+	pxor	%xmm4,%xmm4
+	movhlps	%xmm4,%xmm6
+	movl	$4,%esi
+
+.Loop_schedule_192:
+	call	_vpaes_schedule_round
+.byte	102,15,58,15,198,8
+	call	_vpaes_schedule_mangle	
+	call	_vpaes_schedule_192_smear
+	call	_vpaes_schedule_mangle	
+	call	_vpaes_schedule_round
+	decq	%rsi
+	jz	.Lschedule_mangle_last
+	call	_vpaes_schedule_mangle	
+	call	_vpaes_schedule_192_smear
+	jmp	.Loop_schedule_192
+
+
+
+
+
+
+
+
+
+
+
+.align	16
+.Lschedule_256:
+	movdqu	16(%rdi),%xmm0
+	call	_vpaes_schedule_transform	
+	movl	$7,%esi
+
+.Loop_schedule_256:
+	call	_vpaes_schedule_mangle	
+	movdqa	%xmm0,%xmm6
+
+
+	call	_vpaes_schedule_round
+	decq	%rsi
+	jz	.Lschedule_mangle_last
+	call	_vpaes_schedule_mangle	
+
+
+	pshufd	$255,%xmm0,%xmm0
+	movdqa	%xmm7,%xmm5
+	movdqa	%xmm6,%xmm7
+	call	_vpaes_schedule_low_round
+	movdqa	%xmm5,%xmm7
+
+	jmp	.Loop_schedule_256
+
+
+
+
+
+
+
+
+
+
+
+
+.align	16
+.Lschedule_mangle_last:
+
+	leaq	.Lk_deskew(%rip),%r11
+	testq	%rcx,%rcx
+	jnz	.Lschedule_mangle_last_dec
+
+
+	movdqa	(%r8,%r10,1),%xmm1
+.byte	102,15,56,0,193
+	leaq	.Lk_opt(%rip),%r11
+	addq	$32,%rdx
+
+.Lschedule_mangle_last_dec:
+	addq	$-16,%rdx
+	pxor	.Lk_s63(%rip),%xmm0
+	call	_vpaes_schedule_transform 
+	movdqu	%xmm0,(%rdx)
+
+
+	pxor	%xmm0,%xmm0
+	pxor	%xmm1,%xmm1
+	pxor	%xmm2,%xmm2
+	pxor	%xmm3,%xmm3
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	pxor	%xmm6,%xmm6
+	pxor	%xmm7,%xmm7
+	.byte	0xf3,0xc3
+.size	_vpaes_schedule_core,.-_vpaes_schedule_core
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+.type	_vpaes_schedule_192_smear,@function
+.align	16
+_vpaes_schedule_192_smear:
+	pshufd	$128,%xmm6,%xmm0
+	pxor	%xmm0,%xmm6
+	pshufd	$254,%xmm7,%xmm0
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm6,%xmm0
+	pxor	%xmm1,%xmm1
+	movhlps	%xmm1,%xmm6
+	.byte	0xf3,0xc3
+.size	_vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+.type	_vpaes_schedule_round,@function
+.align	16
+_vpaes_schedule_round:
+
+	pxor	%xmm1,%xmm1
+.byte	102,65,15,58,15,200,15
+.byte	102,69,15,58,15,192,15
+	pxor	%xmm1,%xmm7
+
+
+	pshufd	$255,%xmm0,%xmm0
+.byte	102,15,58,15,192,1
+
+
+
+
+_vpaes_schedule_low_round:
+
+	movdqa	%xmm7,%xmm1
+	pslldq	$4,%xmm7
+	pxor	%xmm1,%xmm7
+	movdqa	%xmm7,%xmm1
+	pslldq	$8,%xmm7
+	pxor	%xmm1,%xmm7
+	pxor	.Lk_s63(%rip),%xmm7
+
+
+	movdqa	%xmm9,%xmm1
+	pandn	%xmm0,%xmm1
+	psrld	$4,%xmm1
+	pand	%xmm9,%xmm0
+	movdqa	%xmm11,%xmm2
+.byte	102,15,56,0,208
+	pxor	%xmm1,%xmm0
+	movdqa	%xmm10,%xmm3
+.byte	102,15,56,0,217
+	pxor	%xmm2,%xmm3
+	movdqa	%xmm10,%xmm4
+.byte	102,15,56,0,224
+	pxor	%xmm2,%xmm4
+	movdqa	%xmm10,%xmm2
+.byte	102,15,56,0,211
+	pxor	%xmm0,%xmm2
+	movdqa	%xmm10,%xmm3
+.byte	102,15,56,0,220
+	pxor	%xmm1,%xmm3
+	movdqa	%xmm13,%xmm4
+.byte	102,15,56,0,226
+	movdqa	%xmm12,%xmm0
+.byte	102,15,56,0,195
+	pxor	%xmm4,%xmm0
+
+
+	pxor	%xmm7,%xmm0
+	movdqa	%xmm0,%xmm7
+	.byte	0xf3,0xc3
+.size	_vpaes_schedule_round,.-_vpaes_schedule_round
+
+
+
+
+
+
+
+
+
+
+.type	_vpaes_schedule_transform,@function
+.align	16
+_vpaes_schedule_transform:
+	movdqa	%xmm9,%xmm1
+	pandn	%xmm0,%xmm1
+	psrld	$4,%xmm1
+	pand	%xmm9,%xmm0
+	movdqa	(%r11),%xmm2
+.byte	102,15,56,0,208
+	movdqa	16(%r11),%xmm0
+.byte	102,15,56,0,193
+	pxor	%xmm2,%xmm0
+	.byte	0xf3,0xc3
+.size	_vpaes_schedule_transform,.-_vpaes_schedule_transform
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+.type	_vpaes_schedule_mangle,@function
+.align	16
+_vpaes_schedule_mangle:
+	movdqa	%xmm0,%xmm4
+	movdqa	.Lk_mc_forward(%rip),%xmm5
+	testq	%rcx,%rcx
+	jnz	.Lschedule_mangle_dec
+
+
+	addq	$16,%rdx
+	pxor	.Lk_s63(%rip),%xmm4
+.byte	102,15,56,0,229
+	movdqa	%xmm4,%xmm3
+.byte	102,15,56,0,229
+	pxor	%xmm4,%xmm3
+.byte	102,15,56,0,229
+	pxor	%xmm4,%xmm3
+
+	jmp	.Lschedule_mangle_both
+.align	16
+.Lschedule_mangle_dec:
+
+	leaq	.Lk_dksd(%rip),%r11
+	movdqa	%xmm9,%xmm1
+	pandn	%xmm4,%xmm1
+	psrld	$4,%xmm1
+	pand	%xmm9,%xmm4
+
+	movdqa	0(%r11),%xmm2
+.byte	102,15,56,0,212
+	movdqa	16(%r11),%xmm3
+.byte	102,15,56,0,217
+	pxor	%xmm2,%xmm3
+.byte	102,15,56,0,221
+
+	movdqa	32(%r11),%xmm2
+.byte	102,15,56,0,212
+	pxor	%xmm3,%xmm2
+	movdqa	48(%r11),%xmm3
+.byte	102,15,56,0,217
+	pxor	%xmm2,%xmm3
+.byte	102,15,56,0,221
+
+	movdqa	64(%r11),%xmm2
+.byte	102,15,56,0,212
+	pxor	%xmm3,%xmm2
+	movdqa	80(%r11),%xmm3
+.byte	102,15,56,0,217
+	pxor	%xmm2,%xmm3
+.byte	102,15,56,0,221
+
+	movdqa	96(%r11),%xmm2
+.byte	102,15,56,0,212
+	pxor	%xmm3,%xmm2
+	movdqa	112(%r11),%xmm3
+.byte	102,15,56,0,217
+	pxor	%xmm2,%xmm3
+
+	addq	$-16,%rdx
+
+.Lschedule_mangle_both:
+	movdqa	(%r8,%r10,1),%xmm1
+.byte	102,15,56,0,217
+	addq	$-16,%r8
+	andq	$48,%r8
+	movdqu	%xmm3,(%rdx)
+	.byte	0xf3,0xc3
+.size	_vpaes_schedule_mangle,.-_vpaes_schedule_mangle
+
+
+
+
+.globl	vpaes_set_encrypt_key
+.type	vpaes_set_encrypt_key,@function
+.align	16
+vpaes_set_encrypt_key:
+	movl	%esi,%eax
+	shrl	$5,%eax
+	addl	$5,%eax
+	movl	%eax,240(%rdx)
+
+	movl	$0,%ecx
+	movl	$48,%r8d
+	call	_vpaes_schedule_core
+	xorl	%eax,%eax
+	.byte	0xf3,0xc3
+.size	vpaes_set_encrypt_key,.-vpaes_set_encrypt_key
+
+.globl	vpaes_set_decrypt_key
+.type	vpaes_set_decrypt_key,@function
+.align	16
+vpaes_set_decrypt_key:
+	movl	%esi,%eax
+	shrl	$5,%eax
+	addl	$5,%eax
+	movl	%eax,240(%rdx)
+	shll	$4,%eax
+	leaq	16(%rdx,%rax,1),%rdx
+
+	movl	$1,%ecx
+	movl	%esi,%r8d
+	shrl	$1,%r8d
+	andl	$32,%r8d
+	xorl	$32,%r8d
+	call	_vpaes_schedule_core
+	xorl	%eax,%eax
+	.byte	0xf3,0xc3
+.size	vpaes_set_decrypt_key,.-vpaes_set_decrypt_key
+
+.globl	vpaes_encrypt
+.type	vpaes_encrypt,@function
+.align	16
+vpaes_encrypt:
+	movdqu	(%rdi),%xmm0
+	call	_vpaes_preheat
+	call	_vpaes_encrypt_core
+	movdqu	%xmm0,(%rsi)
+	.byte	0xf3,0xc3
+.size	vpaes_encrypt,.-vpaes_encrypt
+
+.globl	vpaes_decrypt
+.type	vpaes_decrypt,@function
+.align	16
+vpaes_decrypt:
+	movdqu	(%rdi),%xmm0
+	call	_vpaes_preheat
+	call	_vpaes_decrypt_core
+	movdqu	%xmm0,(%rsi)
+	.byte	0xf3,0xc3
+.size	vpaes_decrypt,.-vpaes_decrypt
+.globl	vpaes_cbc_encrypt
+.type	vpaes_cbc_encrypt,@function
+.align	16
+vpaes_cbc_encrypt:
+	xchgq	%rcx,%rdx
+	subq	$16,%rcx
+	jc	.Lcbc_abort
+	movdqu	(%r8),%xmm6
+	subq	%rdi,%rsi
+	call	_vpaes_preheat
+	cmpl	$0,%r9d
+	je	.Lcbc_dec_loop
+	jmp	.Lcbc_enc_loop
+.align	16
+.Lcbc_enc_loop:
+	movdqu	(%rdi),%xmm0
+	pxor	%xmm6,%xmm0
+	call	_vpaes_encrypt_core
+	movdqa	%xmm0,%xmm6
+	movdqu	%xmm0,(%rsi,%rdi,1)
+	leaq	16(%rdi),%rdi
+	subq	$16,%rcx
+	jnc	.Lcbc_enc_loop
+	jmp	.Lcbc_done
+.align	16
+.Lcbc_dec_loop:
+	movdqu	(%rdi),%xmm0
+	movdqa	%xmm0,%xmm7
+	call	_vpaes_decrypt_core
+	pxor	%xmm6,%xmm0
+	movdqa	%xmm7,%xmm6
+	movdqu	%xmm0,(%rsi,%rdi,1)
+	leaq	16(%rdi),%rdi
+	subq	$16,%rcx
+	jnc	.Lcbc_dec_loop
+.Lcbc_done:
+	movdqu	%xmm6,(%r8)
+.Lcbc_abort:
+	.byte	0xf3,0xc3
+.size	vpaes_cbc_encrypt,.-vpaes_cbc_encrypt
+
+
+
+
+
+
+.type	_vpaes_preheat,@function
+.align	16
+_vpaes_preheat:
+	leaq	.Lk_s0F(%rip),%r10
+	movdqa	-32(%r10),%xmm10
+	movdqa	-16(%r10),%xmm11
+	movdqa	0(%r10),%xmm9
+	movdqa	48(%r10),%xmm13
+	movdqa	64(%r10),%xmm12
+	movdqa	80(%r10),%xmm15
+	movdqa	96(%r10),%xmm14
+	.byte	0xf3,0xc3
+.size	_vpaes_preheat,.-_vpaes_preheat
+
+
+
+
+
+.type	_vpaes_consts,@object
+.align	64
+_vpaes_consts:
+.Lk_inv:
+.quad	0x0E05060F0D080180, 0x040703090A0B0C02
+.quad	0x01040A060F0B0780, 0x030D0E0C02050809
+
+.Lk_s0F:
+.quad	0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F
+
+.Lk_ipt:
+.quad	0xC2B2E8985A2A7000, 0xCABAE09052227808
+.quad	0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81
+
+.Lk_sb1:
+.quad	0xB19BE18FCB503E00, 0xA5DF7A6E142AF544
+.quad	0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF
+.Lk_sb2:
+.quad	0xE27A93C60B712400, 0x5EB7E955BC982FCD
+.quad	0x69EB88400AE12900, 0xC2A163C8AB82234A
+.Lk_sbo:
+.quad	0xD0D26D176FBDC700, 0x15AABF7AC502A878
+.quad	0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA
+
+.Lk_mc_forward:
+.quad	0x0407060500030201, 0x0C0F0E0D080B0A09
+.quad	0x080B0A0904070605, 0x000302010C0F0E0D
+.quad	0x0C0F0E0D080B0A09, 0x0407060500030201
+.quad	0x000302010C0F0E0D, 0x080B0A0904070605
+
+.Lk_mc_backward:
+.quad	0x0605040702010003, 0x0E0D0C0F0A09080B
+.quad	0x020100030E0D0C0F, 0x0A09080B06050407
+.quad	0x0E0D0C0F0A09080B, 0x0605040702010003
+.quad	0x0A09080B06050407, 0x020100030E0D0C0F
+
+.Lk_sr:
+.quad	0x0706050403020100, 0x0F0E0D0C0B0A0908
+.quad	0x030E09040F0A0500, 0x0B06010C07020D08
+.quad	0x0F060D040B020900, 0x070E050C030A0108
+.quad	0x0B0E0104070A0D00, 0x0306090C0F020508
+
+.Lk_rcon:
+.quad	0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81
+
+.Lk_s63:
+.quad	0x5B5B5B5B5B5B5B5B, 0x5B5B5B5B5B5B5B5B
+
+.Lk_opt:
+.quad	0xFF9F4929D6B66000, 0xF7974121DEBE6808
+.quad	0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0
+
+.Lk_deskew:
+.quad	0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A
+.quad	0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77
+
+
+
+
+
+.Lk_dksd:
+.quad	0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9
+.quad	0x41C277F4B5368300, 0x5FDC69EAAB289D1E
+.Lk_dksb:
+.quad	0x9A4FCA1F8550D500, 0x03D653861CC94C99
+.quad	0x115BEDA7B6FC4A00, 0xD993256F7E3482C8
+.Lk_dkse:
+.quad	0xD5031CCA1FC9D600, 0x53859A4C994F5086
+.quad	0xA23196054FDC7BE8, 0xCD5EF96A20B31487
+.Lk_dks9:
+.quad	0xB6116FC87ED9A700, 0x4AED933482255BFC
+.quad	0x4576516227143300, 0x8BB89FACE9DAFDCE
+
+
+
+
+
+.Lk_dipt:
+.quad	0x0F505B040B545F00, 0x154A411E114E451A
+.quad	0x86E383E660056500, 0x12771772F491F194
+
+.Lk_dsb9:
+.quad	0x851C03539A86D600, 0xCAD51F504F994CC9
+.quad	0xC03B1789ECD74900, 0x725E2C9EB2FBA565
+.Lk_dsbd:
+.quad	0x7D57CCDFE6B1A200, 0xF56E9B13882A4439
+.quad	0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3
+.Lk_dsbb:
+.quad	0xD022649296B44200, 0x602646F6B0F2D404
+.quad	0xC19498A6CD596700, 0xF3FF0C3E3255AA6B
+.Lk_dsbe:
+.quad	0x46F2929626D4D000, 0x2242600464B4F6B0
+.quad	0x0C55A6CDFFAAC100, 0x9467F36B98593E32
+.Lk_dsbo:
+.quad	0x1387EA537EF94000, 0xC7AA6DB9D4943E2D
+.quad	0x12D7560F93441D00, 0xCA4B8159D8C58E9C
+.byte	86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105,111,110,32,65,69,83,32,102,111,114,32,120,56,54,95,54,52,47,83,83,83,69,51,44,32,77,105,107,101,32,72,97,109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105,118,101,114,115,105,116,121,41,0
+.align	64
+.size	_vpaes_consts,.-_vpaes_consts
+#if defined(HAVE_GNU_STACK)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/crypto/libressl/crypto/aes/vpaes-macosx-x86_64.s b/crypto/libressl/crypto/aes/vpaes-macosx-x86_64.s
new file mode 100644
index 0000000000..36b00dddcc
--- /dev/null
+++ b/crypto/libressl/crypto/aes/vpaes-macosx-x86_64.s
@@ -0,0 +1,828 @@
+.text	
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+.p2align	4
+_vpaes_encrypt_core:
+	movq	%rdx,%r9
+	movq	$16,%r11
+	movl	240(%rdx),%eax
+	movdqa	%xmm9,%xmm1
+	movdqa	L$k_ipt(%rip),%xmm2
+	pandn	%xmm0,%xmm1
+	movdqu	(%r9),%xmm5
+	psrld	$4,%xmm1
+	pand	%xmm9,%xmm0
+.byte	102,15,56,0,208
+	movdqa	L$k_ipt+16(%rip),%xmm0
+.byte	102,15,56,0,193
+	pxor	%xmm5,%xmm2
+	pxor	%xmm2,%xmm0
+	addq	$16,%r9
+	leaq	L$k_mc_backward(%rip),%r10
+	jmp	L$enc_entry
+
+.p2align	4
+L$enc_loop:
+
+	movdqa	%xmm13,%xmm4
+.byte	102,15,56,0,226
+	pxor	%xmm5,%xmm4
+	movdqa	%xmm12,%xmm0
+.byte	102,15,56,0,195
+	pxor	%xmm4,%xmm0
+	movdqa	%xmm15,%xmm5
+.byte	102,15,56,0,234
+	movdqa	-64(%r11,%r10,1),%xmm1
+	movdqa	%xmm14,%xmm2
+.byte	102,15,56,0,211
+	pxor	%xmm5,%xmm2
+	movdqa	(%r11,%r10,1),%xmm4
+	movdqa	%xmm0,%xmm3
+.byte	102,15,56,0,193
+	addq	$16,%r9
+	pxor	%xmm2,%xmm0
+.byte	102,15,56,0,220
+	addq	$16,%r11
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,193
+	andq	$48,%r11
+	pxor	%xmm3,%xmm0
+	subq	$1,%rax
+
+L$enc_entry:
+
+	movdqa	%xmm9,%xmm1
+	pandn	%xmm0,%xmm1
+	psrld	$4,%xmm1
+	pand	%xmm9,%xmm0
+	movdqa	%xmm11,%xmm5
+.byte	102,15,56,0,232
+	pxor	%xmm1,%xmm0
+	movdqa	%xmm10,%xmm3
+.byte	102,15,56,0,217
+	pxor	%xmm5,%xmm3
+	movdqa	%xmm10,%xmm4
+.byte	102,15,56,0,224
+	pxor	%xmm5,%xmm4
+	movdqa	%xmm10,%xmm2
+.byte	102,15,56,0,211
+	pxor	%xmm0,%xmm2
+	movdqa	%xmm10,%xmm3
+	movdqu	(%r9),%xmm5
+.byte	102,15,56,0,220
+	pxor	%xmm1,%xmm3
+	jnz	L$enc_loop
+
+
+	movdqa	-96(%r10),%xmm4
+	movdqa	-80(%r10),%xmm0
+.byte	102,15,56,0,226
+	pxor	%xmm5,%xmm4
+.byte	102,15,56,0,195
+	movdqa	64(%r11,%r10,1),%xmm1
+	pxor	%xmm4,%xmm0
+.byte	102,15,56,0,193
+	.byte	0xf3,0xc3
+
+
+
+
+
+
+
+
+.p2align	4
+_vpaes_decrypt_core:
+	movq	%rdx,%r9
+	movl	240(%rdx),%eax
+	movdqa	%xmm9,%xmm1
+	movdqa	L$k_dipt(%rip),%xmm2
+	pandn	%xmm0,%xmm1
+	movq	%rax,%r11
+	psrld	$4,%xmm1
+	movdqu	(%r9),%xmm5
+	shlq	$4,%r11
+	pand	%xmm9,%xmm0
+.byte	102,15,56,0,208
+	movdqa	L$k_dipt+16(%rip),%xmm0
+	xorq	$48,%r11
+	leaq	L$k_dsbd(%rip),%r10
+.byte	102,15,56,0,193
+	andq	$48,%r11
+	pxor	%xmm5,%xmm2
+	movdqa	L$k_mc_forward+48(%rip),%xmm5
+	pxor	%xmm2,%xmm0
+	addq	$16,%r9
+	addq	%r10,%r11
+	jmp	L$dec_entry
+
+.p2align	4
+L$dec_loop:
+
+
+
+	movdqa	-32(%r10),%xmm4
+.byte	102,15,56,0,226
+	pxor	%xmm0,%xmm4
+	movdqa	-16(%r10),%xmm0
+.byte	102,15,56,0,195
+	pxor	%xmm4,%xmm0
+	addq	$16,%r9
+
+.byte	102,15,56,0,197
+	movdqa	0(%r10),%xmm4
+.byte	102,15,56,0,226
+	pxor	%xmm0,%xmm4
+	movdqa	16(%r10),%xmm0
+.byte	102,15,56,0,195
+	pxor	%xmm4,%xmm0
+	subq	$1,%rax
+
+.byte	102,15,56,0,197
+	movdqa	32(%r10),%xmm4
+.byte	102,15,56,0,226
+	pxor	%xmm0,%xmm4
+	movdqa	48(%r10),%xmm0
+.byte	102,15,56,0,195
+	pxor	%xmm4,%xmm0
+
+.byte	102,15,56,0,197
+	movdqa	64(%r10),%xmm4
+.byte	102,15,56,0,226
+	pxor	%xmm0,%xmm4
+	movdqa	80(%r10),%xmm0
+.byte	102,15,56,0,195
+	pxor	%xmm4,%xmm0
+
+.byte	102,15,58,15,237,12
+
+L$dec_entry:
+
+	movdqa	%xmm9,%xmm1
+	pandn	%xmm0,%xmm1
+	psrld	$4,%xmm1
+	pand	%xmm9,%xmm0
+	movdqa	%xmm11,%xmm2
+.byte	102,15,56,0,208
+	pxor	%xmm1,%xmm0
+	movdqa	%xmm10,%xmm3
+.byte	102,15,56,0,217
+	pxor	%xmm2,%xmm3
+	movdqa	%xmm10,%xmm4
+.byte	102,15,56,0,224
+	pxor	%xmm2,%xmm4
+	movdqa	%xmm10,%xmm2
+.byte	102,15,56,0,211
+	pxor	%xmm0,%xmm2
+	movdqa	%xmm10,%xmm3
+.byte	102,15,56,0,220
+	pxor	%xmm1,%xmm3
+	movdqu	(%r9),%xmm0
+	jnz	L$dec_loop
+
+
+	movdqa	96(%r10),%xmm4
+.byte	102,15,56,0,226
+	pxor	%xmm0,%xmm4
+	movdqa	112(%r10),%xmm0
+	movdqa	-352(%r11),%xmm2
+.byte	102,15,56,0,195
+	pxor	%xmm4,%xmm0
+.byte	102,15,56,0,194
+	.byte	0xf3,0xc3
+
+
+
+
+
+
+
+
+.p2align	4
+_vpaes_schedule_core:
+
+
+
+
+
+	call	_vpaes_preheat		
+	movdqa	L$k_rcon(%rip),%xmm8
+	movdqu	(%rdi),%xmm0
+
+
+	movdqa	%xmm0,%xmm3
+	leaq	L$k_ipt(%rip),%r11
+	call	_vpaes_schedule_transform
+	movdqa	%xmm0,%xmm7
+
+	leaq	L$k_sr(%rip),%r10
+	testq	%rcx,%rcx
+	jnz	L$schedule_am_decrypting
+
+
+	movdqu	%xmm0,(%rdx)
+	jmp	L$schedule_go
+
+L$schedule_am_decrypting:
+
+	movdqa	(%r8,%r10,1),%xmm1
+.byte	102,15,56,0,217
+	movdqu	%xmm3,(%rdx)
+	xorq	$48,%r8
+
+L$schedule_go:
+	cmpl	$192,%esi
+	ja	L$schedule_256
+	je	L$schedule_192
+
+
+
+
+
+
+
+
+
+
+L$schedule_128:
+	movl	$10,%esi
+
+L$oop_schedule_128:
+	call	_vpaes_schedule_round
+	decq	%rsi
+	jz	L$schedule_mangle_last
+	call	_vpaes_schedule_mangle	
+	jmp	L$oop_schedule_128
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+.p2align	4
+L$schedule_192:
+	movdqu	8(%rdi),%xmm0
+	call	_vpaes_schedule_transform	
+	movdqa	%xmm0,%xmm6
+	pxor	%xmm4,%xmm4
+	movhlps	%xmm4,%xmm6
+	movl	$4,%esi
+
+L$oop_schedule_192:
+	call	_vpaes_schedule_round
+.byte	102,15,58,15,198,8
+	call	_vpaes_schedule_mangle	
+	call	_vpaes_schedule_192_smear
+	call	_vpaes_schedule_mangle	
+	call	_vpaes_schedule_round
+	decq	%rsi
+	jz	L$schedule_mangle_last
+	call	_vpaes_schedule_mangle	
+	call	_vpaes_schedule_192_smear
+	jmp	L$oop_schedule_192
+
+
+
+
+
+
+
+
+
+
+
+.p2align	4
+L$schedule_256:
+	movdqu	16(%rdi),%xmm0
+	call	_vpaes_schedule_transform	
+	movl	$7,%esi
+
+L$oop_schedule_256:
+	call	_vpaes_schedule_mangle	
+	movdqa	%xmm0,%xmm6
+
+
+	call	_vpaes_schedule_round
+	decq	%rsi
+	jz	L$schedule_mangle_last
+	call	_vpaes_schedule_mangle	
+
+
+	pshufd	$255,%xmm0,%xmm0
+	movdqa	%xmm7,%xmm5
+	movdqa	%xmm6,%xmm7
+	call	_vpaes_schedule_low_round
+	movdqa	%xmm5,%xmm7
+
+	jmp	L$oop_schedule_256
+
+
+
+
+
+
+
+
+
+
+
+
+.p2align	4
+L$schedule_mangle_last:
+
+	leaq	L$k_deskew(%rip),%r11
+	testq	%rcx,%rcx
+	jnz	L$schedule_mangle_last_dec
+
+
+	movdqa	(%r8,%r10,1),%xmm1
+.byte	102,15,56,0,193
+	leaq	L$k_opt(%rip),%r11
+	addq	$32,%rdx
+
+L$schedule_mangle_last_dec:
+	addq	$-16,%rdx
+	pxor	L$k_s63(%rip),%xmm0
+	call	_vpaes_schedule_transform 
+	movdqu	%xmm0,(%rdx)
+
+
+	pxor	%xmm0,%xmm0
+	pxor	%xmm1,%xmm1
+	pxor	%xmm2,%xmm2
+	pxor	%xmm3,%xmm3
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	pxor	%xmm6,%xmm6
+	pxor	%xmm7,%xmm7
+	.byte	0xf3,0xc3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+.p2align	4
+_vpaes_schedule_192_smear:
+	pshufd	$128,%xmm6,%xmm0
+	pxor	%xmm0,%xmm6
+	pshufd	$254,%xmm7,%xmm0
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm6,%xmm0
+	pxor	%xmm1,%xmm1
+	movhlps	%xmm1,%xmm6
+	.byte	0xf3,0xc3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+.p2align	4
+_vpaes_schedule_round:
+
+	pxor	%xmm1,%xmm1
+.byte	102,65,15,58,15,200,15
+.byte	102,69,15,58,15,192,15
+	pxor	%xmm1,%xmm7
+
+
+	pshufd	$255,%xmm0,%xmm0
+.byte	102,15,58,15,192,1
+
+
+
+
+_vpaes_schedule_low_round:
+
+	movdqa	%xmm7,%xmm1
+	pslldq	$4,%xmm7
+	pxor	%xmm1,%xmm7
+	movdqa	%xmm7,%xmm1
+	pslldq	$8,%xmm7
+	pxor	%xmm1,%xmm7
+	pxor	L$k_s63(%rip),%xmm7
+
+
+	movdqa	%xmm9,%xmm1
+	pandn	%xmm0,%xmm1
+	psrld	$4,%xmm1
+	pand	%xmm9,%xmm0
+	movdqa	%xmm11,%xmm2
+.byte	102,15,56,0,208
+	pxor	%xmm1,%xmm0
+	movdqa	%xmm10,%xmm3
+.byte	102,15,56,0,217
+	pxor	%xmm2,%xmm3
+	movdqa	%xmm10,%xmm4
+.byte	102,15,56,0,224
+	pxor	%xmm2,%xmm4
+	movdqa	%xmm10,%xmm2
+.byte	102,15,56,0,211
+	pxor	%xmm0,%xmm2
+	movdqa	%xmm10,%xmm3
+.byte	102,15,56,0,220
+	pxor	%xmm1,%xmm3
+	movdqa	%xmm13,%xmm4
+.byte	102,15,56,0,226
+	movdqa	%xmm12,%xmm0
+.byte	102,15,56,0,195
+	pxor	%xmm4,%xmm0
+
+
+	pxor	%xmm7,%xmm0
+	movdqa	%xmm0,%xmm7
+	.byte	0xf3,0xc3
+
+
+
+
+
+
+
+
+
+
+
+
+.p2align	4
+_vpaes_schedule_transform:
+	movdqa	%xmm9,%xmm1
+	pandn	%xmm0,%xmm1
+	psrld	$4,%xmm1
+	pand	%xmm9,%xmm0
+	movdqa	(%r11),%xmm2
+.byte	102,15,56,0,208
+	movdqa	16(%r11),%xmm0
+.byte	102,15,56,0,193
+	pxor	%xmm2,%xmm0
+	.byte	0xf3,0xc3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+.p2align	4
+_vpaes_schedule_mangle:
+	movdqa	%xmm0,%xmm4
+	movdqa	L$k_mc_forward(%rip),%xmm5
+	testq	%rcx,%rcx
+	jnz	L$schedule_mangle_dec
+
+
+	addq	$16,%rdx
+	pxor	L$k_s63(%rip),%xmm4
+.byte	102,15,56,0,229
+	movdqa	%xmm4,%xmm3
+.byte	102,15,56,0,229
+	pxor	%xmm4,%xmm3
+.byte	102,15,56,0,229
+	pxor	%xmm4,%xmm3
+
+	jmp	L$schedule_mangle_both
+.p2align	4
+L$schedule_mangle_dec:
+
+	leaq	L$k_dksd(%rip),%r11
+	movdqa	%xmm9,%xmm1
+	pandn	%xmm4,%xmm1
+	psrld	$4,%xmm1
+	pand	%xmm9,%xmm4
+
+	movdqa	0(%r11),%xmm2
+.byte	102,15,56,0,212
+	movdqa	16(%r11),%xmm3
+.byte	102,15,56,0,217
+	pxor	%xmm2,%xmm3
+.byte	102,15,56,0,221
+
+	movdqa	32(%r11),%xmm2
+.byte	102,15,56,0,212
+	pxor	%xmm3,%xmm2
+	movdqa	48(%r11),%xmm3
+.byte	102,15,56,0,217
+	pxor	%xmm2,%xmm3
+.byte	102,15,56,0,221
+
+	movdqa	64(%r11),%xmm2
+.byte	102,15,56,0,212
+	pxor	%xmm3,%xmm2
+	movdqa	80(%r11),%xmm3
+.byte	102,15,56,0,217
+	pxor	%xmm2,%xmm3
+.byte	102,15,56,0,221
+
+	movdqa	96(%r11),%xmm2
+.byte	102,15,56,0,212
+	pxor	%xmm3,%xmm2
+	movdqa	112(%r11),%xmm3
+.byte	102,15,56,0,217
+	pxor	%xmm2,%xmm3
+
+	addq	$-16,%rdx
+
+L$schedule_mangle_both:
+	movdqa	(%r8,%r10,1),%xmm1
+.byte	102,15,56,0,217
+	addq	$-16,%r8
+	andq	$48,%r8
+	movdqu	%xmm3,(%rdx)
+	.byte	0xf3,0xc3
+
+
+
+
+
+.globl	_vpaes_set_encrypt_key
+
+.p2align	4
+_vpaes_set_encrypt_key:
+	movl	%esi,%eax
+	shrl	$5,%eax
+	addl	$5,%eax
+	movl	%eax,240(%rdx)
+
+	movl	$0,%ecx
+	movl	$48,%r8d
+	call	_vpaes_schedule_core
+	xorl	%eax,%eax
+	.byte	0xf3,0xc3
+
+
+.globl	_vpaes_set_decrypt_key
+
+.p2align	4
+_vpaes_set_decrypt_key:
+	movl	%esi,%eax
+	shrl	$5,%eax
+	addl	$5,%eax
+	movl	%eax,240(%rdx)
+	shll	$4,%eax
+	leaq	16(%rdx,%rax,1),%rdx
+
+	movl	$1,%ecx
+	movl	%esi,%r8d
+	shrl	$1,%r8d
+	andl	$32,%r8d
+	xorl	$32,%r8d
+	call	_vpaes_schedule_core
+	xorl	%eax,%eax
+	.byte	0xf3,0xc3
+
+
+.globl	_vpaes_encrypt
+
+.p2align	4
+_vpaes_encrypt:
+	movdqu	(%rdi),%xmm0
+	call	_vpaes_preheat
+	call	_vpaes_encrypt_core
+	movdqu	%xmm0,(%rsi)
+	.byte	0xf3,0xc3
+
+
+.globl	_vpaes_decrypt
+
+.p2align	4
+_vpaes_decrypt:
+	movdqu	(%rdi),%xmm0
+	call	_vpaes_preheat
+	call	_vpaes_decrypt_core
+	movdqu	%xmm0,(%rsi)
+	.byte	0xf3,0xc3
+
+.globl	_vpaes_cbc_encrypt
+
+.p2align	4
+_vpaes_cbc_encrypt:
+	xchgq	%rcx,%rdx
+	subq	$16,%rcx
+	jc	L$cbc_abort
+	movdqu	(%r8),%xmm6
+	subq	%rdi,%rsi
+	call	_vpaes_preheat
+	cmpl	$0,%r9d
+	je	L$cbc_dec_loop
+	jmp	L$cbc_enc_loop
+.p2align	4
+L$cbc_enc_loop:
+	movdqu	(%rdi),%xmm0
+	pxor	%xmm6,%xmm0
+	call	_vpaes_encrypt_core
+	movdqa	%xmm0,%xmm6
+	movdqu	%xmm0,(%rsi,%rdi,1)
+	leaq	16(%rdi),%rdi
+	subq	$16,%rcx
+	jnc	L$cbc_enc_loop
+	jmp	L$cbc_done
+.p2align	4
+L$cbc_dec_loop:
+	movdqu	(%rdi),%xmm0
+	movdqa	%xmm0,%xmm7
+	call	_vpaes_decrypt_core
+	pxor	%xmm6,%xmm0
+	movdqa	%xmm7,%xmm6
+	movdqu	%xmm0,(%rsi,%rdi,1)
+	leaq	16(%rdi),%rdi
+	subq	$16,%rcx
+	jnc	L$cbc_dec_loop
+L$cbc_done:
+	movdqu	%xmm6,(%r8)
+L$cbc_abort:
+	.byte	0xf3,0xc3
+
+
+
+
+
+
+
+
+.p2align	4
+_vpaes_preheat:
+	leaq	L$k_s0F(%rip),%r10
+	movdqa	-32(%r10),%xmm10
+	movdqa	-16(%r10),%xmm11
+	movdqa	0(%r10),%xmm9
+	movdqa	48(%r10),%xmm13
+	movdqa	64(%r10),%xmm12
+	movdqa	80(%r10),%xmm15
+	movdqa	96(%r10),%xmm14
+	.byte	0xf3,0xc3
+
+
+
+
+
+
+
+.p2align	6
+_vpaes_consts:
+L$k_inv:
+.quad	0x0E05060F0D080180, 0x040703090A0B0C02
+.quad	0x01040A060F0B0780, 0x030D0E0C02050809
+
+L$k_s0F:
+.quad	0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F
+
+L$k_ipt:
+.quad	0xC2B2E8985A2A7000, 0xCABAE09052227808
+.quad	0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81
+
+L$k_sb1:
+.quad	0xB19BE18FCB503E00, 0xA5DF7A6E142AF544
+.quad	0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF
+L$k_sb2:
+.quad	0xE27A93C60B712400, 0x5EB7E955BC982FCD
+.quad	0x69EB88400AE12900, 0xC2A163C8AB82234A
+L$k_sbo:
+.quad	0xD0D26D176FBDC700, 0x15AABF7AC502A878
+.quad	0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA
+
+L$k_mc_forward:
+.quad	0x0407060500030201, 0x0C0F0E0D080B0A09
+.quad	0x080B0A0904070605, 0x000302010C0F0E0D
+.quad	0x0C0F0E0D080B0A09, 0x0407060500030201
+.quad	0x000302010C0F0E0D, 0x080B0A0904070605
+
+L$k_mc_backward:
+.quad	0x0605040702010003, 0x0E0D0C0F0A09080B
+.quad	0x020100030E0D0C0F, 0x0A09080B06050407
+.quad	0x0E0D0C0F0A09080B, 0x0605040702010003
+.quad	0x0A09080B06050407, 0x020100030E0D0C0F
+
+L$k_sr:
+.quad	0x0706050403020100, 0x0F0E0D0C0B0A0908
+.quad	0x030E09040F0A0500, 0x0B06010C07020D08
+.quad	0x0F060D040B020900, 0x070E050C030A0108
+.quad	0x0B0E0104070A0D00, 0x0306090C0F020508
+
+L$k_rcon:
+.quad	0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81
+
+L$k_s63:
+.quad	0x5B5B5B5B5B5B5B5B, 0x5B5B5B5B5B5B5B5B
+
+L$k_opt:
+.quad	0xFF9F4929D6B66000, 0xF7974121DEBE6808
+.quad	0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0
+
+L$k_deskew:
+.quad	0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A
+.quad	0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77
+
+
+
+
+
+L$k_dksd:
+.quad	0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9
+.quad	0x41C277F4B5368300, 0x5FDC69EAAB289D1E
+L$k_dksb:
+.quad	0x9A4FCA1F8550D500, 0x03D653861CC94C99
+.quad	0x115BEDA7B6FC4A00, 0xD993256F7E3482C8
+L$k_dkse:
+.quad	0xD5031CCA1FC9D600, 0x53859A4C994F5086
+.quad	0xA23196054FDC7BE8, 0xCD5EF96A20B31487
+L$k_dks9:
+.quad	0xB6116FC87ED9A700, 0x4AED933482255BFC
+.quad	0x4576516227143300, 0x8BB89FACE9DAFDCE
+
+
+
+
+
+L$k_dipt:
+.quad	0x0F505B040B545F00, 0x154A411E114E451A
+.quad	0x86E383E660056500, 0x12771772F491F194
+
+L$k_dsb9:
+.quad	0x851C03539A86D600, 0xCAD51F504F994CC9
+.quad	0xC03B1789ECD74900, 0x725E2C9EB2FBA565
+L$k_dsbd:
+.quad	0x7D57CCDFE6B1A200, 0xF56E9B13882A4439
+.quad	0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3
+L$k_dsbb:
+.quad	0xD022649296B44200, 0x602646F6B0F2D404
+.quad	0xC19498A6CD596700, 0xF3FF0C3E3255AA6B
+L$k_dsbe:
+.quad	0x46F2929626D4D000, 0x2242600464B4F6B0
+.quad	0x0C55A6CDFFAAC100, 0x9467F36B98593E32
+L$k_dsbo:
+.quad	0x1387EA537EF94000, 0xC7AA6DB9D4943E2D
+.quad	0x12D7560F93441D00, 0xCA4B8159D8C58E9C
+.byte	86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105,111,110,32,65,69,83,32,102,111,114,32,120,56,54,95,54,52,47,83,83,83,69,51,44,32,77,105,107,101,32,72,97,109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105,118,101,114,115,105,116,121,41,0
+.p2align	6
+
diff --git a/crypto/libressl/crypto/asn1/a_bitstr.c b/crypto/libressl/crypto/asn1/a_bitstr.c
new file mode 100644
index 0000000000..0afa7ed89e
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_bitstr.c
@@ -0,0 +1,259 @@
+/* $OpenBSD: a_bitstr.c,v 1.22 2015/07/29 14:58:34 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+
+int
+ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
+{
+	return ASN1_STRING_set(x, d, len);
+}
+
+int
+i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
+{
+	int ret, j, bits, len;
+	unsigned char *p, *d;
+
+	if (a == NULL)
+		return (0);
+
+	len = a->length;
+
+	if (len > 0) {
+		if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) {
+			bits = (int)a->flags & 0x07;
+		} else {
+			for (; len > 0; len--) {
+				if (a->data[len - 1])
+					break;
+			}
+			j = a->data[len - 1];
+			if (j & 0x01)
+				bits = 0;
+			else if (j & 0x02)
+				bits = 1;
+			else if (j & 0x04)
+				bits = 2;
+			else if (j & 0x08)
+				bits = 3;
+			else if (j & 0x10)
+				bits = 4;
+			else if (j & 0x20)
+				bits = 5;
+			else if (j & 0x40)
+				bits = 6;
+			else if (j & 0x80)
+				bits = 7;
+			else
+				bits = 0; /* should not happen */
+		}
+	} else
+		bits = 0;
+
+	ret = 1 + len;
+	if (pp == NULL)
+		return (ret);
+
+	p= *pp;
+
+	*(p++) = (unsigned char)bits;
+	d = a->data;
+	memcpy(p, d, len);
+	p += len;
+	if (len > 0)
+		p[-1]&=(0xff << bits);
+	*pp = p;
+	return (ret);
+}
+
+ASN1_BIT_STRING *
+c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, const unsigned char **pp, long len)
+{
+	ASN1_BIT_STRING *ret = NULL;
+	const unsigned char *p;
+	unsigned char *s;
+	int i;
+
+	if (len < 1) {
+		i = ASN1_R_STRING_TOO_SHORT;
+		goto err;
+	}
+
+	if ((a == NULL) || ((*a) == NULL)) {
+		if ((ret = ASN1_BIT_STRING_new()) == NULL)
+			return (NULL);
+	} else
+		ret = (*a);
+
+	p = *pp;
+	i = *(p++);
+	/* We do this to preserve the settings.  If we modify
+	 * the settings, via the _set_bit function, we will recalculate
+	 * on output */
+	ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
+	ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */
+
+	if (len-- > 1) /* using one because of the bits left byte */
+	{
+		s = malloc(len);
+		if (s == NULL) {
+			i = ERR_R_MALLOC_FAILURE;
+			goto err;
+		}
+		memcpy(s, p, len);
+		s[len - 1] &= (0xff << i);
+		p += len;
+	} else
+		s = NULL;
+
+	ret->length = (int)len;
+	free(ret->data);
+	ret->data = s;
+	ret->type = V_ASN1_BIT_STRING;
+	if (a != NULL)
+		(*a) = ret;
+	*pp = p;
+	return (ret);
+
+err:
+	ASN1err(ASN1_F_C2I_ASN1_BIT_STRING, i);
+	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+		ASN1_BIT_STRING_free(ret);
+	return (NULL);
+}
+
+/* These next 2 functions from Goetz Babin-Ebell 
+ */
+int
+ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
+{
+	int w, v, iv;
+	unsigned char *c;
+
+	w = n/8;
+	v = 1 << (7 - (n & 0x07));
+	iv = ~v;
+	if (!value)
+		v = 0;
+
+	if (a == NULL)
+		return 0;
+
+	a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */
+
+	if ((a->length < (w + 1)) || (a->data == NULL)) {
+		if (!value)
+			return(1); /* Don't need to set */
+		c = OPENSSL_realloc_clean(a->data, a->length, w + 1);
+		if (c == NULL) {
+			ASN1err(ASN1_F_ASN1_BIT_STRING_SET_BIT, ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		if (w + 1 - a->length > 0)
+			memset(c + a->length, 0, w + 1 - a->length);
+		a->data = c;
+		a->length = w + 1;
+	}
+	a->data[w] = ((a->data[w]) & iv) | v;
+	while ((a->length > 0) && (a->data[a->length - 1] == 0))
+		a->length--;
+
+	return (1);
+}
+
+int
+ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
+{
+	int w, v;
+
+	w = n / 8;
+	v = 1 << (7 - (n & 0x07));
+	if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL))
+		return (0);
+	return ((a->data[w] & v) != 0);
+}
+
+/*
+ * Checks if the given bit string contains only bits specified by
+ * the flags vector. Returns 0 if there is at least one bit set in 'a'
+ * which is not specified in 'flags', 1 otherwise.
+ * 'len' is the length of 'flags'.
+ */
+int
+ASN1_BIT_STRING_check(ASN1_BIT_STRING *a, unsigned char *flags, int flags_len)
+{
+	int i, ok;
+
+	/* Check if there is one bit set at all. */
+	if (!a || !a->data)
+		return 1;
+
+	/* Check each byte of the internal representation of the bit string. */
+	ok = 1;
+	for (i = 0; i < a->length && ok; ++i) {
+		unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
+		/* We are done if there is an unneeded bit set. */
+		ok = (a->data[i] & mask) == 0;
+	}
+	return ok;
+}
diff --git a/crypto/libressl/crypto/asn1/a_bool.c b/crypto/libressl/crypto/asn1/a_bool.c
new file mode 100644
index 0000000000..58eb995440
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_bool.c
@@ -0,0 +1,115 @@
+/* $OpenBSD: a_bool.c,v 1.6 2014/06/12 15:49:27 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+
+int
+i2d_ASN1_BOOLEAN(int a, unsigned char **pp)
+{
+	int r;
+	unsigned char *p;
+
+	r = ASN1_object_size(0, 1, V_ASN1_BOOLEAN);
+	if (pp == NULL)
+		return (r);
+	p = *pp;
+
+	ASN1_put_object(&p, 0, 1, V_ASN1_BOOLEAN, V_ASN1_UNIVERSAL);
+	*(p++) = (unsigned char)a;
+	*pp = p;
+	return (r);
+}
+
+int
+d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length)
+{
+	int ret = -1;
+	const unsigned char *p;
+	long len;
+	int inf, tag, xclass;
+	int i = 0;
+
+	p = *pp;
+	inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+	if (inf & 0x80) {
+		i = ASN1_R_BAD_OBJECT_HEADER;
+		goto err;
+	}
+
+	if (tag != V_ASN1_BOOLEAN) {
+		i = ASN1_R_EXPECTING_A_BOOLEAN;
+		goto err;
+	}
+
+	if (len != 1) {
+		i = ASN1_R_BOOLEAN_IS_WRONG_LENGTH;
+		goto err;
+	}
+	ret = (int)*(p++);
+	if (a != NULL)
+		(*a) = ret;
+	*pp = p;
+	return (ret);
+
+err:
+	ASN1err(ASN1_F_D2I_ASN1_BOOLEAN, i);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/asn1/a_bytes.c b/crypto/libressl/crypto/asn1/a_bytes.c
new file mode 100644
index 0000000000..9ec4f5b2e5
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_bytes.c
@@ -0,0 +1,306 @@
+/* $OpenBSD: a_bytes.c,v 1.17 2014/07/10 13:58:22 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c);
+/* type is a 'bitmap' of acceptable string types.
+ */
+ASN1_STRING *
+d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
+    long length, int type)
+{
+	ASN1_STRING *ret = NULL;
+	const unsigned char *p;
+	unsigned char *s;
+	long len;
+	int inf, tag, xclass;
+	int i = 0;
+
+	p = *pp;
+	inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+	if (inf & 0x80)
+		goto err;
+
+	if (tag >= 32) {
+		i = ASN1_R_TAG_VALUE_TOO_HIGH;
+		goto err;
+	}
+	if (!(ASN1_tag2bit(tag) & type)) {
+		i = ASN1_R_WRONG_TYPE;
+		goto err;
+	}
+
+	/* If a bit-string, exit early */
+	if (tag == V_ASN1_BIT_STRING)
+		return (d2i_ASN1_BIT_STRING(a, pp, length));
+
+	if ((a == NULL) || ((*a) == NULL)) {
+		if ((ret = ASN1_STRING_new()) == NULL)
+			return (NULL);
+	} else
+		ret = (*a);
+
+	if (len != 0) {
+		s = malloc(len + 1);
+		if (s == NULL) {
+			i = ERR_R_MALLOC_FAILURE;
+			goto err;
+		}
+		memcpy(s, p, len);
+		s[len]='\0';
+		p += len;
+	} else
+		s = NULL;
+
+	free(ret->data);
+	ret->length = (int)len;
+	ret->data = s;
+	ret->type = tag;
+	if (a != NULL)
+		(*a) = ret;
+	*pp = p;
+	return (ret);
+
+err:
+	ASN1err(ASN1_F_D2I_ASN1_TYPE_BYTES, i);
+	if (a == NULL || *a != ret)
+		ASN1_STRING_free(ret);
+	return (NULL);
+}
+
+int
+i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass)
+{
+	int ret, r, constructed;
+	unsigned char *p;
+
+	if (a == NULL)
+		return (0);
+
+	if (tag == V_ASN1_BIT_STRING)
+		return (i2d_ASN1_BIT_STRING(a, pp));
+
+	ret = a->length;
+	r = ASN1_object_size(0, ret, tag);
+	if (pp == NULL)
+		return (r);
+	p = *pp;
+
+	if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET))
+		constructed = 1;
+	else
+		constructed = 0;
+	ASN1_put_object(&p, constructed, ret, tag, xclass);
+	memcpy(p, a->data, a->length);
+	p += a->length;
+	*pp = p;
+	return (r);
+}
+
+ASN1_STRING *
+d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
+    long length, int Ptag, int Pclass)
+{
+	ASN1_STRING *ret = NULL;
+	const unsigned char *p;
+	unsigned char *s;
+	long len;
+	int inf, tag, xclass;
+	int i = 0;
+
+	if ((a == NULL) || ((*a) == NULL)) {
+		if ((ret = ASN1_STRING_new()) == NULL)
+			return (NULL);
+	} else
+		ret = (*a);
+
+	p= *pp;
+	inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+	if (inf & 0x80) {
+		i = ASN1_R_BAD_OBJECT_HEADER;
+		goto err;
+	}
+
+	if (tag != Ptag) {
+		i = ASN1_R_WRONG_TAG;
+		goto err;
+	}
+
+	if (inf & V_ASN1_CONSTRUCTED) {
+		ASN1_const_CTX c;
+
+		c.pp = pp;
+		c.p = p;
+		c.inf = inf;
+		c.slen = len;
+		c.tag = Ptag;
+		c.xclass = Pclass;
+		c.max = (length == 0) ? 0 : (p + length);
+		if (!asn1_collate_primitive(ret, &c))
+			goto err;
+		else {
+			p = c.p;
+		}
+	} else {
+		if (len != 0) {
+			if ((ret->length < len) || (ret->data == NULL)) {
+				free(ret->data);
+				ret->data = NULL;
+				s = malloc(len + 1);
+				if (s == NULL) {
+					i = ERR_R_MALLOC_FAILURE;
+					goto err;
+				}
+			} else
+				s = ret->data;
+			memcpy(s, p, len);
+			s[len] = '\0';
+			p += len;
+		} else {
+			s = NULL;
+			free(ret->data);
+		}
+
+		ret->length = (int)len;
+		ret->data = s;
+		ret->type = Ptag;
+	}
+
+	if (a != NULL)
+		(*a) = ret;
+	*pp = p;
+	return (ret);
+
+err:
+	if (a == NULL || *a != ret)
+		ASN1_STRING_free(ret);
+	ASN1err(ASN1_F_D2I_ASN1_BYTES, i);
+	return (NULL);
+}
+
+
+/* We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse
+ * them into the one structure that is then returned */
+/* There have been a few bug fixes for this function from
+ * Paul Keogh , many thanks to him */
+static int
+asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c)
+{
+	ASN1_STRING *os = NULL;
+	BUF_MEM b;
+	int num;
+
+	b.length = 0;
+	b.max = 0;
+	b.data = NULL;
+
+	if (a == NULL) {
+		c->error = ERR_R_PASSED_NULL_PARAMETER;
+		goto err;
+	}
+
+	num = 0;
+	for (;;) {
+		if (c->inf & 1) {
+			c->eos = ASN1_const_check_infinite_end(&c->p,
+			    (long)(c->max - c->p));
+			if (c->eos)
+				break;
+		} else {
+			if (c->slen <= 0)
+				break;
+		}
+
+		c->q = c->p;
+		if (d2i_ASN1_bytes(&os, &c->p, c->max - c->p, c->tag,
+		    c->xclass) == NULL) {
+			c->error = ERR_R_ASN1_LIB;
+			goto err;
+		}
+
+		if (!BUF_MEM_grow_clean(&b, num + os->length)) {
+			c->error = ERR_R_BUF_LIB;
+			goto err;
+		}
+		memcpy(&(b.data[num]), os->data, os->length);
+		if (!(c->inf & 1))
+			c->slen -= (c->p - c->q);
+		num += os->length;
+	}
+
+	if (!asn1_const_Finish(c))
+		goto err;
+
+	a->length = num;
+	free(a->data);
+	a->data = (unsigned char *)b.data;
+	ASN1_STRING_free(os);
+	return (1);
+
+err:
+	ASN1err(ASN1_F_ASN1_COLLATE_PRIMITIVE, c->error);
+	ASN1_STRING_free(os);
+	free(b.data);
+	return (0);
+}
diff --git a/crypto/libressl/crypto/asn1/a_d2i_fp.c b/crypto/libressl/crypto/asn1/a_d2i_fp.c
new file mode 100644
index 0000000000..94899cebef
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_d2i_fp.c
@@ -0,0 +1,296 @@
+/* $OpenBSD: a_d2i_fp.c,v 1.14 2016/05/04 14:58:09 tedu Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb);
+
+#ifndef NO_OLD_ASN1
+
+void *
+ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x)
+{
+	BIO *b;
+	void *ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL) {
+		ASN1err(ASN1_F_ASN1_D2I_FP, ERR_R_BUF_LIB);
+		return (NULL);
+	}
+	BIO_set_fp(b, in, BIO_NOCLOSE);
+	ret = ASN1_d2i_bio(xnew, d2i, b, x);
+	BIO_free(b);
+	return (ret);
+}
+
+void *
+ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x)
+{
+	BUF_MEM *b = NULL;
+	const unsigned char *p;
+	void *ret = NULL;
+	int len;
+
+	len = asn1_d2i_read_bio(in, &b);
+	if (len < 0)
+		goto err;
+
+	p = (unsigned char *)b->data;
+	ret = d2i(x, &p, len);
+
+err:
+	if (b != NULL)
+		BUF_MEM_free(b);
+	return (ret);
+}
+
+#endif
+
+void *
+ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x)
+{
+	BUF_MEM *b = NULL;
+	const unsigned char *p;
+	void *ret = NULL;
+	int len;
+
+	len = asn1_d2i_read_bio(in, &b);
+	if (len < 0)
+		goto err;
+
+	p = (const unsigned char *)b->data;
+	ret = ASN1_item_d2i(x, &p, len, it);
+
+err:
+	if (b != NULL)
+		BUF_MEM_free(b);
+	return (ret);
+}
+
+void *
+ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
+{
+	BIO *b;
+	char *ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL) {
+		ASN1err(ASN1_F_ASN1_ITEM_D2I_FP, ERR_R_BUF_LIB);
+		return (NULL);
+	}
+	BIO_set_fp(b, in, BIO_NOCLOSE);
+	ret = ASN1_item_d2i_bio(it, b, x);
+	BIO_free(b);
+	return (ret);
+}
+
+#define HEADER_SIZE   8
+#define ASN1_CHUNK_INITIAL_SIZE (16 * 1024)
+static int
+asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
+{
+	BUF_MEM *b;
+	unsigned char *p;
+	int i;
+	ASN1_const_CTX c;
+	size_t want = HEADER_SIZE;
+	int eos = 0;
+	size_t off = 0;
+	size_t len = 0;
+
+	b = BUF_MEM_new();
+	if (b == NULL) {
+		ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
+		return -1;
+	}
+
+	ERR_clear_error();
+	for (;;) {
+		if (want >= (len - off)) {
+			want -= (len - off);
+
+			if (len + want < len ||
+			    !BUF_MEM_grow_clean(b, len + want)) {
+				ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
+				    ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+			i = BIO_read(in, &(b->data[len]), want);
+			if ((i < 0) && ((len - off) == 0)) {
+				ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
+				    ASN1_R_NOT_ENOUGH_DATA);
+				goto err;
+			}
+			if (i > 0) {
+				if (len + i < len) {
+					ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
+					    ASN1_R_TOO_LONG);
+					goto err;
+				}
+				len += i;
+			}
+		}
+		/* else data already loaded */
+
+		p = (unsigned char *) & (b->data[off]);
+		c.p = p;
+		c.inf = ASN1_get_object(&(c.p), &(c.slen), &(c.tag),
+		    &(c.xclass), len - off);
+		if (c.inf & 0x80) {
+			unsigned long e;
+
+			e = ERR_GET_REASON(ERR_peek_error());
+			if (e != ASN1_R_TOO_LONG)
+				goto err;
+			else
+				ERR_clear_error(); /* clear error */
+		}
+		i = c.p - p;	/* header length */
+		off += i;	/* end of data */
+
+		if (c.inf & 1) {
+			/* no data body so go round again */
+			eos++;
+			if (eos < 0) {
+				ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
+				    ASN1_R_HEADER_TOO_LONG);
+				goto err;
+			}
+			want = HEADER_SIZE;
+		} else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC)) {
+			/* eos value, so go back and read another header */
+			eos--;
+			if (eos <= 0)
+				break;
+			else
+				want = HEADER_SIZE;
+		} else {
+			/* suck in c.slen bytes of data */
+			want = c.slen;
+			if (want > (len - off)) {
+				size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE;
+
+				want -= (len - off);
+				if (want > INT_MAX /* BIO_read takes an int length */ ||
+				    len+want < len) {
+					ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
+					    ASN1_R_TOO_LONG);
+					goto err;
+				}
+				while (want > 0) {
+					/*
+					 * Read content in chunks of increasing size
+					 * so we can return an error for EOF without
+					 * having to allocate the entire content length
+					 * in one go.
+					 */
+					size_t chunk = want > chunk_max ? chunk_max : want;
+
+					if (!BUF_MEM_grow_clean(b, len + chunk)) {
+						ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
+						    ERR_R_MALLOC_FAILURE);
+						goto err;
+					}
+					want -= chunk;
+					while (chunk > 0) {
+						i = BIO_read(in, &(b->data[len]), chunk);
+						if (i <= 0) {
+							ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
+							    ASN1_R_NOT_ENOUGH_DATA);
+							goto err;
+						}
+						/*
+						 * This can't overflow because |len+want|
+						 * didn't overflow.
+						 */
+						len += i;
+						chunk -= i;
+					}
+					if (chunk_max < INT_MAX/2)
+						chunk_max *= 2;
+				}
+			}
+			if (off + c.slen < off) {
+				ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
+				goto err;
+			}
+			off += c.slen;
+			if (eos <= 0) {
+				break;
+			} else
+				want = HEADER_SIZE;
+		}
+	}
+
+	if (off > INT_MAX) {
+		ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
+		goto err;
+	}
+
+	*pb = b;
+	return off;
+
+err:
+	if (b != NULL)
+		BUF_MEM_free(b);
+	return -1;
+}
diff --git a/crypto/libressl/crypto/asn1/a_digest.c b/crypto/libressl/crypto/asn1/a_digest.c
new file mode 100644
index 0000000000..320a71cbff
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_digest.c
@@ -0,0 +1,84 @@
+/* $OpenBSD: a_digest.c,v 1.14 2014/06/24 19:37:58 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+int
+ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
+    unsigned char *md, unsigned int *len)
+{
+	int i;
+	unsigned char *str = NULL;
+
+	i = ASN1_item_i2d(asn, &str, it);
+	if (!str)
+		return (0);
+
+	if (!EVP_Digest(str, i, md, len, type, NULL))
+		return 0;
+	free(str);
+	return (1);
+}
diff --git a/crypto/libressl/crypto/asn1/a_dup.c b/crypto/libressl/crypto/asn1/a_dup.c
new file mode 100644
index 0000000000..3fc5056ea1
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_dup.c
@@ -0,0 +1,118 @@
+/* $OpenBSD: a_dup.c,v 1.12 2014/06/12 15:49:27 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+
+#ifndef NO_OLD_ASN1
+
+void *
+ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
+{
+	unsigned char *b, *p;
+	const unsigned char *p2;
+	int i;
+	char *ret;
+
+	if (x == NULL)
+		return (NULL);
+
+	i = i2d(x, NULL);
+	b = malloc(i + 10);
+	if (b == NULL) {
+		ASN1err(ASN1_F_ASN1_DUP, ERR_R_MALLOC_FAILURE);
+		return (NULL);
+	}
+	p = b;
+	i = i2d(x, &p);
+	p2 = b;
+	ret = d2i(NULL, &p2, i);
+	free(b);
+	return (ret);
+}
+
+#endif
+
+/* ASN1_ITEM version of dup: this follows the model above except we don't need
+ * to allocate the buffer. At some point this could be rewritten to directly dup
+ * the underlying structure instead of doing and encode and decode.
+ */
+
+void *
+ASN1_item_dup(const ASN1_ITEM *it, void *x)
+{
+	unsigned char *b = NULL;
+	const unsigned char *p;
+	long i;
+	void *ret;
+
+	if (x == NULL)
+		return (NULL);
+
+	i = ASN1_item_i2d(x, &b, it);
+	if (b == NULL) {
+		ASN1err(ASN1_F_ASN1_ITEM_DUP, ERR_R_MALLOC_FAILURE);
+		return (NULL);
+	}
+	p = b;
+	ret = ASN1_item_d2i(NULL, &p, i, it);
+	free(b);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/asn1/a_enum.c b/crypto/libressl/crypto/asn1/a_enum.c
new file mode 100644
index 0000000000..90d465bd30
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_enum.c
@@ -0,0 +1,189 @@
+/* $OpenBSD: a_enum.c,v 1.16 2014/09/21 12:17:42 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+/*
+ * Code for ENUMERATED type: identical to INTEGER apart from a different tag.
+ * for comments on encoding see a_int.c
+ */
+
+int
+ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
+{
+	int j, k;
+	unsigned int i;
+	unsigned char buf[sizeof(long) + 1];
+	long d;
+
+	a->type = V_ASN1_ENUMERATED;
+	if (a->length < (int)(sizeof(long) + 1)) {
+		free(a->data);
+		a->data = calloc(1, sizeof(long) + 1);
+	}
+	if (a->data == NULL) {
+		ASN1err(ASN1_F_ASN1_ENUMERATED_SET, ERR_R_MALLOC_FAILURE);
+		return (0);
+	}
+	d = v;
+	if (d < 0) {
+		d = -d;
+		a->type = V_ASN1_NEG_ENUMERATED;
+	}
+
+	for (i = 0; i < sizeof(long); i++) {
+		if (d == 0)
+			break;
+		buf[i] = (int)d & 0xff;
+		d >>= 8;
+	}
+	j = 0;
+	for (k = i - 1; k >= 0; k--)
+		a->data[j++] = buf[k];
+	a->length = j;
+	return (1);
+}
+
+long
+ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
+{
+	int neg = 0, i;
+	long r = 0;
+
+	if (a == NULL)
+		return (0L);
+	i = a->type;
+	if (i == V_ASN1_NEG_ENUMERATED)
+		neg = 1;
+	else if (i != V_ASN1_ENUMERATED)
+		return -1;
+
+	if (a->length > (int)sizeof(long)) {
+		/* hmm... a bit ugly */
+		return -1;
+	}
+	if (a->data == NULL)
+		return 0;
+
+	for (i = 0; i < a->length; i++) {
+		r <<= 8;
+		r |= (unsigned char)a->data[i];
+	}
+	if (neg)
+		r = -r;
+	return (r);
+}
+
+ASN1_ENUMERATED *
+BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
+{
+	ASN1_ENUMERATED *ret;
+	int len, j;
+
+	if (ai == NULL)
+		ret = ASN1_ENUMERATED_new();
+	else
+		ret = ai;
+	if (ret == NULL) {
+		ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED, ERR_R_NESTED_ASN1_ERROR);
+		goto err;
+	}
+	if (BN_is_negative(bn))
+		ret->type = V_ASN1_NEG_ENUMERATED;
+	else
+		ret->type = V_ASN1_ENUMERATED;
+	j = BN_num_bits(bn);
+	len = ((j == 0) ? 0 : ((j / 8) + 1));
+	if (ret->length < len + 4) {
+		unsigned char *new_data = realloc(ret->data, len + 4);
+		if (!new_data) {
+			ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		ret->data = new_data;
+	}
+	ret->length = BN_bn2bin(bn, ret->data);
+
+	/* Correct zero case */
+	if (!ret->length) {
+		ret->data[0] = 0;
+		ret->length = 1;
+	}
+	return (ret);
+
+err:
+	if (ret != ai)
+		ASN1_ENUMERATED_free(ret);
+	return (NULL);
+}
+
+BIGNUM *
+ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
+{
+	BIGNUM *ret;
+
+	if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
+		ASN1err(ASN1_F_ASN1_ENUMERATED_TO_BN, ASN1_R_BN_LIB);
+	else if (ai->type == V_ASN1_NEG_ENUMERATED)
+		BN_set_negative(ret, 1);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/asn1/a_i2d_fp.c b/crypto/libressl/crypto/asn1/a_i2d_fp.c
new file mode 100644
index 0000000000..9a3e5917be
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_i2d_fp.c
@@ -0,0 +1,158 @@
+/* $OpenBSD: a_i2d_fp.c,v 1.13 2014/06/12 15:49:27 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+#ifndef NO_OLD_ASN1
+
+int
+ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
+{
+	BIO *b;
+	int ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL) {
+		ASN1err(ASN1_F_ASN1_I2D_FP, ERR_R_BUF_LIB);
+		return (0);
+	}
+	BIO_set_fp(b, out, BIO_NOCLOSE);
+	ret = ASN1_i2d_bio(i2d, b, x);
+	BIO_free(b);
+	return (ret);
+}
+
+int
+ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x)
+{
+	char *b;
+	unsigned char *p;
+	int i, j = 0, n, ret = 1;
+
+	n = i2d(x, NULL);
+	b = malloc(n);
+	if (b == NULL) {
+		ASN1err(ASN1_F_ASN1_I2D_BIO, ERR_R_MALLOC_FAILURE);
+		return (0);
+	}
+
+	p = (unsigned char *)b;
+	i2d(x, &p);
+
+	for (;;) {
+		i = BIO_write(out, &(b[j]), n);
+		if (i == n)
+			break;
+		if (i <= 0) {
+			ret = 0;
+			break;
+		}
+		j += i;
+		n -= i;
+	}
+	free(b);
+	return (ret);
+}
+
+#endif
+
+int
+ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
+{
+	BIO *b;
+	int ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL) {
+		ASN1err(ASN1_F_ASN1_ITEM_I2D_FP, ERR_R_BUF_LIB);
+		return (0);
+	}
+	BIO_set_fp(b, out, BIO_NOCLOSE);
+	ret = ASN1_item_i2d_bio(it, b, x);
+	BIO_free(b);
+	return (ret);
+}
+
+int
+ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
+{
+	unsigned char *b = NULL;
+	int i, j = 0, n, ret = 1;
+
+	n = ASN1_item_i2d(x, &b, it);
+	if (b == NULL) {
+		ASN1err(ASN1_F_ASN1_ITEM_I2D_BIO, ERR_R_MALLOC_FAILURE);
+		return (0);
+	}
+
+	for (;;) {
+		i = BIO_write(out, &(b[j]), n);
+		if (i == n)
+			break;
+		if (i <= 0) {
+			ret = 0;
+			break;
+		}
+		j += i;
+		n -= i;
+	}
+	free(b);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/asn1/a_int.c b/crypto/libressl/crypto/asn1/a_int.c
new file mode 100644
index 0000000000..135cf1c463
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_int.c
@@ -0,0 +1,461 @@
+/* $OpenBSD: a_int.c,v 1.28 2015/07/29 14:58:34 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+ASN1_INTEGER *
+ASN1_INTEGER_dup(const ASN1_INTEGER *x)
+{
+	return ASN1_STRING_dup(x);
+}
+
+int
+ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
+{
+	int neg, ret;
+
+	/* Compare signs */
+	neg = x->type & V_ASN1_NEG;
+	if (neg != (y->type & V_ASN1_NEG)) {
+		if (neg)
+			return -1;
+		else
+			return 1;
+	}
+
+	ret = ASN1_STRING_cmp(x, y);
+
+	if (neg)
+		return -ret;
+	else
+		return ret;
+}
+
+
+/*
+ * This converts an ASN1 INTEGER into its content encoding.
+ * The internal representation is an ASN1_STRING whose data is a big endian
+ * representation of the value, ignoring the sign. The sign is determined by
+ * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative.
+ *
+ * Positive integers are no problem: they are almost the same as the DER
+ * encoding, except if the first byte is >= 0x80 we need to add a zero pad.
+ *
+ * Negative integers are a bit trickier...
+ * The DER representation of negative integers is in 2s complement form.
+ * The internal form is converted by complementing each octet and finally
+ * adding one to the result. This can be done less messily with a little trick.
+ * If the internal form has trailing zeroes then they will become FF by the
+ * complement and 0 by the add one (due to carry) so just copy as many trailing
+ * zeros to the destination as there are in the source. The carry will add one
+ * to the last none zero octet: so complement this octet and add one and finally
+ * complement any left over until you get to the start of the string.
+ *
+ * Padding is a little trickier too. If the first bytes is > 0x80 then we pad
+ * with 0xff. However if the first byte is 0x80 and one of the following bytes
+ * is non-zero we pad with 0xff. The reason for this distinction is that 0x80
+ * followed by optional zeros isn't padded.
+ */
+
+int
+i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
+{
+	int pad = 0, ret, i, neg;
+	unsigned char *p, *n, pb = 0;
+
+	if (a == NULL)
+		return (0);
+	neg = a->type & V_ASN1_NEG;
+	if (a->length == 0)
+		ret = 1;
+	else {
+		ret = a->length;
+		i = a->data[0];
+		if (!neg && (i > 127)) {
+			pad = 1;
+			pb = 0;
+		} else if (neg) {
+			if (i > 128) {
+				pad = 1;
+				pb = 0xFF;
+			} else if (i == 128) {
+				/*
+				 * Special case: if any other bytes non zero we pad:
+				 * otherwise we don't.
+				 */
+				for (i = 1; i < a->length; i++) if (a->data[i]) {
+					pad = 1;
+					pb = 0xFF;
+					break;
+				}
+			}
+		}
+		ret += pad;
+	}
+	if (pp == NULL)
+		return (ret);
+	p= *pp;
+
+	if (pad)
+		*(p++) = pb;
+	if (a->length == 0)
+		*(p++) = 0;
+	else if (!neg)
+		memcpy(p, a->data, a->length);
+	else {
+		/* Begin at the end of the encoding */
+		n = a->data + a->length - 1;
+		p += a->length - 1;
+		i = a->length;
+		/* Copy zeros to destination as long as source is zero */
+		while (!*n) {
+			*(p--) = 0;
+			n--;
+			i--;
+		}
+		/* Complement and increment next octet */
+		*(p--) = ((*(n--)) ^ 0xff) + 1;
+		i--;
+		/* Complement any octets left */
+		for (; i > 0; i--)
+			*(p--) = *(n--) ^ 0xff;
+	}
+
+	*pp += ret;
+	return (ret);
+}
+
+/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
+
+ASN1_INTEGER *
+c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, long len)
+{
+	ASN1_INTEGER *ret = NULL;
+	const unsigned char *p, *pend;
+	unsigned char *to, *s;
+	int i;
+
+	if ((a == NULL) || ((*a) == NULL)) {
+		if ((ret = ASN1_INTEGER_new()) == NULL)
+			return (NULL);
+	} else
+		ret = (*a);
+
+	p = *pp;
+	pend = p + len;
+
+	/* We must malloc stuff, even for 0 bytes otherwise it
+	 * signifies a missing NULL parameter. */
+	s = malloc(len + 1);
+	if (s == NULL) {
+		i = ERR_R_MALLOC_FAILURE;
+		goto err;
+	}
+	to = s;
+	if (!len) {
+		/* Strictly speaking this is an illegal INTEGER but we
+		 * tolerate it.
+		 */
+		ret->type = V_ASN1_INTEGER;
+	} else if (*p & 0x80) /* a negative number */ {
+		ret->type = V_ASN1_NEG_INTEGER;
+		if ((*p == 0xff) && (len != 1)) {
+			p++;
+			len--;
+		}
+		i = len;
+		p += i - 1;
+		to += i - 1;
+		while((!*p) && i) {
+			*(to--) = 0;
+			i--;
+			p--;
+		}
+		/* Special case: if all zeros then the number will be of
+		 * the form FF followed by n zero bytes: this corresponds to
+		 * 1 followed by n zero bytes. We've already written n zeros
+		 * so we just append an extra one and set the first byte to
+		 * a 1. This is treated separately because it is the only case
+		 * where the number of bytes is larger than len.
+		 */
+		if (!i) {
+			*s = 1;
+			s[len] = 0;
+			len++;
+		} else {
+			*(to--) = (*(p--) ^ 0xff) + 1;
+			i--;
+			for (; i > 0; i--)
+				*(to--) = *(p--) ^ 0xff;
+		}
+	} else {
+		ret->type = V_ASN1_INTEGER;
+		if ((*p == 0) && (len != 1)) {
+			p++;
+			len--;
+		}
+		memcpy(s, p, len);
+	}
+
+	free(ret->data);
+	ret->data = s;
+	ret->length = (int)len;
+	if (a != NULL)
+		(*a) = ret;
+	*pp = pend;
+	return (ret);
+
+err:
+	ASN1err(ASN1_F_C2I_ASN1_INTEGER, i);
+	if (a == NULL || *a != ret)
+		ASN1_INTEGER_free(ret);
+	return (NULL);
+}
+
+
+/* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of
+ * ASN1 integers: some broken software can encode a positive INTEGER
+ * with its MSB set as negative (it doesn't add a padding zero).
+ */
+
+ASN1_INTEGER *
+d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length)
+{
+	ASN1_INTEGER *ret = NULL;
+	const unsigned char *p;
+	unsigned char *s;
+	long len;
+	int inf, tag, xclass;
+	int i;
+
+	if ((a == NULL) || ((*a) == NULL)) {
+		if ((ret = ASN1_INTEGER_new()) == NULL)
+			return (NULL);
+	} else
+		ret = (*a);
+
+	p = *pp;
+	inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+	if (inf & 0x80) {
+		i = ASN1_R_BAD_OBJECT_HEADER;
+		goto err;
+	}
+
+	if (tag != V_ASN1_INTEGER) {
+		i = ASN1_R_EXPECTING_AN_INTEGER;
+		goto err;
+	}
+
+	/* We must malloc stuff, even for 0 bytes otherwise it
+	 * signifies a missing NULL parameter. */
+	s = malloc(len + 1);
+	if (s == NULL) {
+		i = ERR_R_MALLOC_FAILURE;
+		goto err;
+	}
+	ret->type = V_ASN1_INTEGER;
+	if (len) {
+		if ((*p == 0) && (len != 1)) {
+			p++;
+			len--;
+		}
+		memcpy(s, p, len);
+		p += len;
+	}
+
+	free(ret->data);
+	ret->data = s;
+	ret->length = (int)len;
+	if (a != NULL)
+		(*a) = ret;
+	*pp = p;
+	return (ret);
+
+err:
+	ASN1err(ASN1_F_D2I_ASN1_UINTEGER, i);
+	if (a == NULL || *a != ret)
+		ASN1_INTEGER_free(ret);
+	return (NULL);
+}
+
+int
+ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
+{
+	int j, k;
+	unsigned int i;
+	unsigned char buf[sizeof(long) + 1];
+	long d;
+
+	a->type = V_ASN1_INTEGER;
+	/* XXX ssl/ssl_asn1.c:i2d_SSL_SESSION() depends upon this bound vae */
+	if (a->length < (int)(sizeof(long) + 1)) {
+		free(a->data);
+		a->data = calloc(1, sizeof(long) + 1);
+	}
+	if (a->data == NULL) {
+		ASN1err(ASN1_F_ASN1_INTEGER_SET, ERR_R_MALLOC_FAILURE);
+		return (0);
+	}
+	d = v;
+	if (d < 0) {
+		d = -d;
+		a->type = V_ASN1_NEG_INTEGER;
+	}
+
+	for (i = 0; i < sizeof(long); i++) {
+		if (d == 0)
+			break;
+		buf[i] = (int)d & 0xff;
+		d >>= 8;
+	}
+	j = 0;
+	for (k = i - 1; k >= 0; k--)
+		a->data[j++] = buf[k];
+	a->length = j;
+	return (1);
+}
+
+long
+ASN1_INTEGER_get(const ASN1_INTEGER *a)
+{
+	int neg = 0, i;
+	long r = 0;
+
+	if (a == NULL)
+		return (0L);
+	i = a->type;
+	if (i == V_ASN1_NEG_INTEGER)
+		neg = 1;
+	else if (i != V_ASN1_INTEGER)
+		return -1;
+
+	if (a->length > (int)sizeof(long)) {
+		/* hmm... a bit ugly, return all ones */
+		return -1;
+	}
+	if (a->data == NULL)
+		return 0;
+
+	for (i = 0; i < a->length; i++) {
+		r <<= 8;
+		r |= (unsigned char)a->data[i];
+	}
+	if (neg)
+		r = -r;
+	return (r);
+}
+
+ASN1_INTEGER *
+BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
+{
+	ASN1_INTEGER *ret;
+	int len, j;
+
+	if (ai == NULL)
+		ret = ASN1_INTEGER_new();
+	else
+		ret = ai;
+	if (ret == NULL) {
+		ASN1err(ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_NESTED_ASN1_ERROR);
+		goto err;
+	}
+	if (BN_is_negative(bn))
+		ret->type = V_ASN1_NEG_INTEGER;
+	else
+		ret->type = V_ASN1_INTEGER;
+	j = BN_num_bits(bn);
+	len = ((j == 0) ? 0 : ((j / 8) + 1));
+	if (ret->length < len + 4) {
+		unsigned char *new_data = realloc(ret->data, len + 4);
+		if (!new_data) {
+			ASN1err(ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		ret->data = new_data;
+	}
+	ret->length = BN_bn2bin(bn, ret->data);
+
+	/* Correct zero case */
+	if (!ret->length) {
+		ret->data[0] = 0;
+		ret->length = 1;
+	}
+	return (ret);
+
+err:
+	if (ret != ai)
+		ASN1_INTEGER_free(ret);
+	return (NULL);
+}
+
+BIGNUM *
+ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
+{
+	BIGNUM *ret;
+
+	if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
+		ASN1err(ASN1_F_ASN1_INTEGER_TO_BN, ASN1_R_BN_LIB);
+	else if (ai->type == V_ASN1_NEG_INTEGER)
+		BN_set_negative(ret, 1);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/asn1/a_mbstr.c b/crypto/libressl/crypto/asn1/a_mbstr.c
new file mode 100644
index 0000000000..1080a8f297
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_mbstr.c
@@ -0,0 +1,453 @@
+/* $OpenBSD: a_mbstr.c,v 1.21 2014/10/12 20:47:12 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "asn1_locl.h"
+
+static int traverse_string(const unsigned char *p, int len, int inform,
+    int (*rfunc)(unsigned long value, void *in), void *arg);
+static int in_utf8(unsigned long value, void *arg);
+static int out_utf8(unsigned long value, void *arg);
+static int type_str(unsigned long value, void *arg);
+static int cpy_asc(unsigned long value, void *arg);
+static int cpy_bmp(unsigned long value, void *arg);
+static int cpy_univ(unsigned long value, void *arg);
+static int cpy_utf8(unsigned long value, void *arg);
+static int is_printable(unsigned long value);
+
+/* These functions take a string in UTF8, ASCII or multibyte form and
+ * a mask of permissible ASN1 string types. It then works out the minimal
+ * type (using the order Printable < IA5 < T61 < BMP < Universal < UTF8)
+ * and creates a string of the correct type with the supplied data.
+ * Yes this is horrible: it has to be :-(
+ * The 'ncopy' form checks minimum and maximum size limits too.
+ */
+
+int
+ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
+    int inform, unsigned long mask)
+{
+	return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
+}
+
+int
+ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
+    int inform, unsigned long mask, long minsize, long maxsize)
+{
+	int str_type;
+	int ret;
+	char free_out;
+	int outform, outlen = 0;
+	ASN1_STRING *dest;
+	unsigned char *p;
+	int nchar;
+	int (*cpyfunc)(unsigned long, void *) = NULL;
+
+	if (len < 0)
+		len = strlen((const char *)in);
+	if (!mask)
+		mask = DIRSTRING_TYPE;
+
+	/* First do a string check and work out the number of characters */
+	switch (inform) {
+	case MBSTRING_BMP:
+		if (len & 1) {
+			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
+			    ASN1_R_INVALID_BMPSTRING_LENGTH);
+			return -1;
+		}
+		nchar = len >> 1;
+		break;
+
+	case MBSTRING_UNIV:
+		if (len & 3) {
+			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
+			    ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
+			return -1;
+		}
+		nchar = len >> 2;
+		break;
+
+	case MBSTRING_UTF8:
+		nchar = 0;
+		/* This counts the characters and does utf8 syntax checking */
+		ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
+		if (ret < 0) {
+			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
+			    ASN1_R_INVALID_UTF8STRING);
+			return -1;
+		}
+		break;
+
+	case MBSTRING_ASC:
+		nchar = len;
+		break;
+
+	default:
+		ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT);
+		return -1;
+	}
+
+	if ((minsize > 0) && (nchar < minsize)) {
+		ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT);
+		ERR_asprintf_error_data("minsize=%ld", minsize);
+		return -1;
+	}
+
+	if ((maxsize > 0) && (nchar > maxsize)) {
+		ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG);
+		ERR_asprintf_error_data("maxsize=%ld", maxsize);
+		return -1;
+	}
+
+	/* Now work out minimal type (if any) */
+	if (traverse_string(in, len, inform, type_str, &mask) < 0) {
+		ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS);
+		return -1;
+	}
+
+
+	/* Now work out output format and string type */
+	outform = MBSTRING_ASC;
+	if (mask & B_ASN1_PRINTABLESTRING)
+		str_type = V_ASN1_PRINTABLESTRING;
+	else if (mask & B_ASN1_IA5STRING)
+		str_type = V_ASN1_IA5STRING;
+	else if (mask & B_ASN1_T61STRING)
+		str_type = V_ASN1_T61STRING;
+	else if (mask & B_ASN1_BMPSTRING) {
+		str_type = V_ASN1_BMPSTRING;
+		outform = MBSTRING_BMP;
+	} else if (mask & B_ASN1_UNIVERSALSTRING) {
+		str_type = V_ASN1_UNIVERSALSTRING;
+		outform = MBSTRING_UNIV;
+	} else {
+		str_type = V_ASN1_UTF8STRING;
+		outform = MBSTRING_UTF8;
+	}
+	if (!out)
+		return str_type;
+	if (*out) {
+		free_out = 0;
+		dest = *out;
+		if (dest->data) {
+			dest->length = 0;
+			free(dest->data);
+			dest->data = NULL;
+		}
+		dest->type = str_type;
+	} else {
+		free_out = 1;
+		dest = ASN1_STRING_type_new(str_type);
+		if (!dest) {
+			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
+			    ERR_R_MALLOC_FAILURE);
+			return -1;
+		}
+		*out = dest;
+	}
+	/* If both the same type just copy across */
+	if (inform == outform) {
+		if (!ASN1_STRING_set(dest, in, len)) {
+			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
+			    ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		return str_type;
+	}
+
+	/* Work out how much space the destination will need */
+	switch (outform) {
+	case MBSTRING_ASC:
+		outlen = nchar;
+		cpyfunc = cpy_asc;
+		break;
+
+	case MBSTRING_BMP:
+		outlen = nchar << 1;
+		cpyfunc = cpy_bmp;
+		break;
+
+	case MBSTRING_UNIV:
+		outlen = nchar << 2;
+		cpyfunc = cpy_univ;
+		break;
+
+	case MBSTRING_UTF8:
+		outlen = 0;
+		if (traverse_string(in, len, inform, out_utf8, &outlen) < 0) {
+			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
+			    ASN1_R_ILLEGAL_CHARACTERS);
+			goto err;
+		}
+		cpyfunc = cpy_utf8;
+		break;
+	}
+	if (!(p = malloc(outlen + 1))) {
+		ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	dest->length = outlen;
+	dest->data = p;
+	p[outlen] = 0;
+	traverse_string(in, len, inform, cpyfunc, &p);
+	return str_type;
+
+err:
+	if (free_out) {
+		ASN1_STRING_free(dest);
+		*out = NULL;
+	}
+	return -1;
+}
+
+/* This function traverses a string and passes the value of each character
+ * to an optional function along with a void * argument.
+ */
+
+static int
+traverse_string(const unsigned char *p, int len, int inform,
+    int (*rfunc)(unsigned long value, void *in), void *arg)
+{
+	unsigned long value;
+	int ret;
+
+	while (len) {
+		switch (inform) {
+		case MBSTRING_ASC:
+			value = *p++;
+			len--;
+			break;
+		case MBSTRING_BMP:
+			value = *p++ << 8;
+			value |= *p++;
+			/* BMP is explictly defined to not support surrogates */
+			if (UNICODE_IS_SURROGATE(value))
+				return -1;
+			len -= 2;
+			break;
+		case MBSTRING_UNIV:
+			value = (unsigned long)*p++ << 24;
+			value |= *p++ << 16;
+			value |= *p++ << 8;
+			value |= *p++;
+			if (value > UNICODE_MAX || UNICODE_IS_SURROGATE(value))
+				return -1;
+			len -= 4;
+			break;
+		default:
+			ret = UTF8_getc(p, len, &value);
+			if (ret < 0)
+				return -1;
+			len -= ret;
+			p += ret;
+			break;
+		}
+		if (rfunc) {
+			ret = rfunc(value, arg);
+			if (ret <= 0)
+				return ret;
+		}
+	}
+	return 1;
+}
+
+/* Various utility functions for traverse_string */
+
+/* Just count number of characters */
+
+static int
+in_utf8(unsigned long value, void *arg)
+{
+	int *nchar;
+
+	nchar = arg;
+	(*nchar)++;
+	return 1;
+}
+
+/* Determine size of output as a UTF8 String */
+
+static int
+out_utf8(unsigned long value, void *arg)
+{
+	int *outlen;
+	int ret;
+
+	outlen = arg;
+	ret = UTF8_putc(NULL, -1, value);
+	if (ret < 0)
+		return ret;
+	*outlen += ret;
+	return 1;
+}
+
+/* Determine the "type" of a string: check each character against a
+ * supplied "mask".
+ */
+
+static int
+type_str(unsigned long value, void *arg)
+{
+	unsigned long types;
+
+	types = *((unsigned long *)arg);
+	if ((types & B_ASN1_PRINTABLESTRING) && !is_printable(value))
+		types &= ~B_ASN1_PRINTABLESTRING;
+	if ((types & B_ASN1_IA5STRING) && (value > 127))
+		types &= ~B_ASN1_IA5STRING;
+	if ((types & B_ASN1_T61STRING) && (value > 0xff))
+		types &= ~B_ASN1_T61STRING;
+	if ((types & B_ASN1_BMPSTRING) && (value > 0xffff))
+		types &= ~B_ASN1_BMPSTRING;
+	if (!types)
+		return -1;
+	*((unsigned long *)arg) = types;
+	return 1;
+}
+
+/* Copy one byte per character ASCII like strings */
+
+static int
+cpy_asc(unsigned long value, void *arg)
+{
+	unsigned char **p, *q;
+
+	p = arg;
+	q = *p;
+	*q = value;
+	(*p)++;
+	return 1;
+}
+
+/* Copy two byte per character BMPStrings */
+
+static int
+cpy_bmp(unsigned long value, void *arg)
+{
+	unsigned char **p, *q;
+
+	p = arg;
+	q = *p;
+	*q++ = (value >> 8) & 0xff;
+	*q = value & 0xff;
+	*p += 2;
+	return 1;
+}
+
+/* Copy four byte per character UniversalStrings */
+
+static int
+cpy_univ(unsigned long value, void *arg)
+{
+	unsigned char **p, *q;
+
+	p = arg;
+	q = *p;
+	*q++ = (value >> 24) & 0xff;
+	*q++ = (value >> 16) & 0xff;
+	*q++ = (value >> 8) & 0xff;
+	*q = value & 0xff;
+	*p += 4;
+	return 1;
+}
+
+/* Copy to a UTF8String */
+
+static int
+cpy_utf8(unsigned long value, void *arg)
+{
+	unsigned char **p;
+
+	int ret;
+	p = arg;
+	/* We already know there is enough room so pass 0xff as the length */
+	ret = UTF8_putc(*p, 0xff, value);
+	*p += ret;
+	return 1;
+}
+
+/* Return 1 if the character is permitted in a PrintableString */
+static int
+is_printable(unsigned long value)
+{
+	int ch;
+
+	if (value > 0x7f)
+		return 0;
+	ch = (int)value;
+
+	/* Note: we can't use 'isalnum' because certain accented
+	 * characters may count as alphanumeric in some environments.
+	 */
+	if ((ch >= 'a') && (ch <= 'z'))
+		return 1;
+	if ((ch >= 'A') && (ch <= 'Z'))
+		return 1;
+	if ((ch >= '0') && (ch <= '9'))
+		return 1;
+	if ((ch == ' ') || strchr("'()+,-./:=?", ch))
+		return 1;
+	return 0;
+}
diff --git a/crypto/libressl/crypto/asn1/a_object.c b/crypto/libressl/crypto/asn1/a_object.c
new file mode 100644
index 0000000000..606f752787
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_object.c
@@ -0,0 +1,410 @@
+/* $OpenBSD: a_object.c,v 1.25 2016/03/06 18:05:00 beck Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+int
+i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
+{
+	unsigned char *p;
+	int objsize;
+
+	if ((a == NULL) || (a->data == NULL))
+		return (0);
+
+	objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
+	if (pp == NULL)
+		return objsize;
+
+	p = *pp;
+	ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
+	memcpy(p, a->data, a->length);
+	p += a->length;
+
+	*pp = p;
+	return (objsize);
+}
+
+int
+a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
+{
+	int i, first, len = 0, c, use_bn;
+	char ftmp[24], *tmp = ftmp;
+	int tmpsize = sizeof ftmp;
+	const char *p;
+	unsigned long l;
+	BIGNUM *bl = NULL;
+
+	if (num == 0)
+		return (0);
+	else if (num == -1)
+		num = strlen(buf);
+
+	p = buf;
+	c = *(p++);
+	num--;
+	if ((c >= '0') && (c <= '2')) {
+		first= c-'0';
+	} else {
+		ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE);
+		goto err;
+	}
+
+	if (num <= 0) {
+		ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER);
+		goto err;
+	}
+	c = *(p++);
+	num--;
+	for (;;) {
+		if (num <= 0)
+			break;
+		if ((c != '.') && (c != ' ')) {
+			ASN1err(ASN1_F_A2D_ASN1_OBJECT,
+			    ASN1_R_INVALID_SEPARATOR);
+			goto err;
+		}
+		l = 0;
+		use_bn = 0;
+		for (;;) {
+			if (num <= 0)
+				break;
+			num--;
+			c = *(p++);
+			if ((c == ' ') || (c == '.'))
+				break;
+			if ((c < '0') || (c > '9')) {
+				ASN1err(ASN1_F_A2D_ASN1_OBJECT,
+				    ASN1_R_INVALID_DIGIT);
+				goto err;
+			}
+			if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) {
+				use_bn = 1;
+				if (!bl)
+					bl = BN_new();
+				if (!bl || !BN_set_word(bl, l))
+					goto err;
+			}
+			if (use_bn) {
+				if (!BN_mul_word(bl, 10L) ||
+				    !BN_add_word(bl, c-'0'))
+					goto err;
+			} else
+				l = l * 10L + (long)(c - '0');
+		}
+		if (len == 0) {
+			if ((first < 2) && (l >= 40)) {
+				ASN1err(ASN1_F_A2D_ASN1_OBJECT,
+				    ASN1_R_SECOND_NUMBER_TOO_LARGE);
+				goto err;
+			}
+			if (use_bn) {
+				if (!BN_add_word(bl, first * 40))
+					goto err;
+			} else
+				l += (long)first * 40;
+		}
+		i = 0;
+		if (use_bn) {
+			int blsize;
+			blsize = BN_num_bits(bl);
+			blsize = (blsize + 6) / 7;
+			if (blsize > tmpsize) {
+				if (tmp != ftmp)
+					free(tmp);
+				tmpsize = blsize + 32;
+				tmp = malloc(tmpsize);
+				if (!tmp)
+					goto err;
+			}
+			while (blsize--)
+				tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
+		} else {
+
+			for (;;) {
+				tmp[i++] = (unsigned char)l & 0x7f;
+				l >>= 7L;
+				if (l == 0L)
+					break;
+			}
+
+		}
+		if (out != NULL) {
+			if (len + i > olen) {
+				ASN1err(ASN1_F_A2D_ASN1_OBJECT,
+				    ASN1_R_BUFFER_TOO_SMALL);
+				goto err;
+			}
+			while (--i > 0)
+				out[len++] = tmp[i]|0x80;
+			out[len++] = tmp[0];
+		} else
+			len += i;
+	}
+	if (tmp != ftmp)
+		free(tmp);
+	BN_free(bl);
+	return (len);
+
+err:
+	if (tmp != ftmp)
+		free(tmp);
+	BN_free(bl);
+	return (0);
+}
+
+int
+i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
+{
+	return OBJ_obj2txt(buf, buf_len, a, 0);
+}
+
+int
+i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
+{
+	char *tmp = NULL;
+	size_t tlen = 256;
+	int i = -1;
+
+	if ((a == NULL) || (a->data == NULL))
+		return(BIO_write(bp, "NULL", 4));
+	if ((tmp = malloc(tlen)) == NULL)
+		return -1;
+	i = i2t_ASN1_OBJECT(tmp, tlen, a);
+	if (i > (int)(tlen - 1)) {
+		explicit_bzero(tmp, tlen);
+		free(tmp);
+		if ((tmp = malloc(i + 1)) == NULL)
+			return -1;
+		tlen = i + 1;
+		i = i2t_ASN1_OBJECT(tmp, tlen, a);
+	}
+	if (i <= 0)
+		i = BIO_write(bp, "", 9);
+	else
+		i = BIO_write(bp, tmp, i);
+	explicit_bzero(tmp, tlen);
+	free(tmp);
+	return (i);
+}
+
+ASN1_OBJECT *
+d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, long length)
+{
+	const unsigned char *p;
+	long len;
+	int tag, xclass;
+	int inf, i;
+	ASN1_OBJECT *ret = NULL;
+
+	p = *pp;
+	inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+	if (inf & 0x80) {
+		i = ASN1_R_BAD_OBJECT_HEADER;
+		goto err;
+	}
+
+	if (tag != V_ASN1_OBJECT) {
+		i = ASN1_R_EXPECTING_AN_OBJECT;
+		goto err;
+	}
+	ret = c2i_ASN1_OBJECT(a, &p, len);
+	if (ret)
+		*pp = p;
+	return ret;
+
+err:
+	ASN1err(ASN1_F_D2I_ASN1_OBJECT, i);
+	return (NULL);
+}
+
+ASN1_OBJECT *
+c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, long len)
+{
+	ASN1_OBJECT *ret = NULL;
+	const unsigned char *p;
+	unsigned char *data;
+	int i, length;
+
+	/*
+	 * Sanity check OID encoding:
+	 * - need at least one content octet
+	 * - MSB must be clear in the last octet
+	 * - can't have leading 0x80 in subidentifiers, see: X.690 8.19.2
+	 */
+	if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
+	    p[len - 1] & 0x80) {
+		ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
+		return (NULL);
+	}
+
+	/* Now 0 < len <= INT_MAX, so the cast is safe. */
+	length = (int)len;
+	for (i = 0; i < length; i++, p++) {
+		if (*p == 0x80 && (!i || !(p[-1] & 0x80))) {
+			ASN1err(ASN1_F_C2I_ASN1_OBJECT,
+			    ASN1_R_INVALID_OBJECT_ENCODING);
+			return NULL;
+		}
+	}
+
+	/* only the ASN1_OBJECTs from the 'table' will have values
+	 * for ->sn or ->ln */
+	if ((a == NULL) || ((*a) == NULL) ||
+	    !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
+		if ((ret = ASN1_OBJECT_new()) == NULL)
+			return (NULL);
+	} else
+		ret = (*a);
+
+	p = *pp;
+	/* detach data from object */
+	data = (unsigned char *)ret->data;
+	if (data != NULL)
+		explicit_bzero(data, ret->length);
+	free(data);
+	data = malloc(length);
+	if (data == NULL) {
+		i = ERR_R_MALLOC_FAILURE;
+		goto err;
+	}
+	ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+	memcpy(data, p, length);
+	/* reattach data to object, after which it remains const */
+	ret->data = data;
+	ret->length = length;
+	ret->sn = NULL;
+	ret->ln = NULL;
+	/* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
+	p += length;
+
+	if (a != NULL)
+		(*a) = ret;
+	*pp = p;
+	return (ret);
+
+err:
+	ASN1err(ASN1_F_C2I_ASN1_OBJECT, i);
+	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
+		ASN1_OBJECT_free(ret);
+	return (NULL);
+}
+
+ASN1_OBJECT *
+ASN1_OBJECT_new(void)
+{
+	ASN1_OBJECT *ret;
+
+	ret = malloc(sizeof(ASN1_OBJECT));
+	if (ret == NULL) {
+		ASN1err(ASN1_F_ASN1_OBJECT_NEW, ERR_R_MALLOC_FAILURE);
+		return (NULL);
+	}
+	ret->length = 0;
+	ret->data = NULL;
+	ret->nid = 0;
+	ret->sn = NULL;
+	ret->ln = NULL;
+	ret->flags = ASN1_OBJECT_FLAG_DYNAMIC;
+	return (ret);
+}
+
+void
+ASN1_OBJECT_free(ASN1_OBJECT *a)
+{
+	if (a == NULL)
+		return;
+	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) {
+		free((void *)a->sn);
+		free((void *)a->ln);
+		a->sn = a->ln = NULL;
+	}
+	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) {
+		if (a->data != NULL)
+			explicit_bzero((void *)a->data, a->length);
+		free((void *)a->data);
+		a->data = NULL;
+		a->length = 0;
+	}
+	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
+		free(a);
+}
+
+ASN1_OBJECT *
+ASN1_OBJECT_create(int nid, unsigned char *data, int len,
+    const char *sn, const char *ln)
+{
+	ASN1_OBJECT o;
+
+	o.sn = sn;
+	o.ln = ln;
+	o.data = data;
+	o.nid = nid;
+	o.length = len;
+	o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
+	    ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+	return (OBJ_dup(&o));
+}
diff --git a/crypto/libressl/crypto/asn1/a_octet.c b/crypto/libressl/crypto/asn1/a_octet.c
new file mode 100644
index 0000000000..2d8a73d631
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_octet.c
@@ -0,0 +1,79 @@
+/* $OpenBSD: a_octet.c,v 1.9 2014/07/11 08:44:47 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+ASN1_OCTET_STRING *
+ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x)
+{
+	return ASN1_STRING_dup(x);
+}
+
+int
+ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b)
+{
+	return ASN1_STRING_cmp(a, b);
+}
+
+int
+ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, int len)
+{
+	return ASN1_STRING_set(x, d, len);
+}
diff --git a/crypto/libressl/crypto/asn1/a_print.c b/crypto/libressl/crypto/asn1/a_print.c
new file mode 100644
index 0000000000..6f005ced68
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_print.c
@@ -0,0 +1,125 @@
+/* $OpenBSD: a_print.c,v 1.10 2014/06/12 15:49:27 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+int
+ASN1_PRINTABLE_type(const unsigned char *s, int len)
+{
+	int c;
+	int ia5 = 0;
+	int t61 = 0;
+
+	if (len <= 0)
+		len = -1;
+	if (s == NULL)
+		return (V_ASN1_PRINTABLESTRING);
+
+	while ((*s) && (len-- != 0)) {
+		c= *(s++);
+		if (!(((c >= 'a') && (c <= 'z')) ||
+		    ((c >= 'A') && (c <= 'Z')) ||
+		    (c == ' ') ||
+		    ((c >= '0') && (c <= '9')) ||
+		    (c == ' ') || (c == '\'') ||
+		    (c == '(') || (c == ')') ||
+		    (c == '+') || (c == ',') ||
+		    (c == '-') || (c == '.') ||
+		    (c == '/') || (c == ':') ||
+		    (c == '=') || (c == '?')))
+			ia5 = 1;
+		if (c & 0x80)
+			t61 = 1;
+	}
+	if (t61)
+		return (V_ASN1_T61STRING);
+	if (ia5)
+		return (V_ASN1_IA5STRING);
+	return (V_ASN1_PRINTABLESTRING);
+}
+
+int
+ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s)
+{
+	int i;
+	unsigned char *p;
+
+	if (s->type != V_ASN1_UNIVERSALSTRING)
+		return (0);
+	if ((s->length % 4) != 0)
+		return (0);
+	p = s->data;
+	for (i = 0; i < s->length; i += 4) {
+		if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0'))
+			break;
+		else
+			p += 4;
+	}
+	if (i < s->length)
+		return (0);
+	p = s->data;
+	for (i = 3; i < s->length; i += 4) {
+		*(p++) = s->data[i];
+	}
+	*(p) = '\0';
+	s->length /= 4;
+	s->type = ASN1_PRINTABLE_type(s->data, s->length);
+	return (1);
+}
diff --git a/crypto/libressl/crypto/asn1/a_set.c b/crypto/libressl/crypto/asn1/a_set.c
new file mode 100644
index 0000000000..4a14d3fd09
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_set.c
@@ -0,0 +1,237 @@
+/* $OpenBSD: a_set.c,v 1.16 2014/07/11 08:44:47 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+
+#ifndef NO_ASN1_OLD
+
+typedef struct {
+	unsigned char *pbData;
+	int cbData;
+} MYBLOB;
+
+/* SetBlobCmp
+ * This function compares two elements of SET_OF block
+ */
+static int
+SetBlobCmp(const void *elem1, const void *elem2)
+{
+	const MYBLOB *b1 = (const MYBLOB *)elem1;
+	const MYBLOB *b2 = (const MYBLOB *)elem2;
+	int r;
+
+	r = memcmp(b1->pbData, b2->pbData,
+	    b1->cbData < b2->cbData ? b1->cbData : b2->cbData);
+	if (r != 0)
+		return r;
+	return b1->cbData - b2->cbData;
+}
+
+/* int is_set:  if TRUE, then sort the contents (i.e. it isn't a SEQUENCE) */
+int
+i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp, i2d_of_void *i2d,
+    int ex_tag, int ex_class, int is_set)
+{
+	int ret = 0, r;
+	int i;
+	unsigned char *p;
+	unsigned char *pStart, *pTempMem;
+	MYBLOB *rgSetBlob;
+	int totSize;
+
+	if (a == NULL)
+		return 0;
+	for (i = sk_OPENSSL_BLOCK_num(a) - 1; i >= 0; i--)
+		ret += i2d(sk_OPENSSL_BLOCK_value(a, i), NULL);
+	r = ASN1_object_size(1, ret, ex_tag);
+	if (pp == NULL)
+		return r;
+
+	p = *pp;
+	ASN1_put_object(&p, 1, ret, ex_tag, ex_class);
+
+	/* Modified by gp@nsj.co.jp */
+	/* And then again by Ben */
+	/* And again by Steve */
+
+	if (!is_set || (sk_OPENSSL_BLOCK_num(a) < 2)) {
+		for (i = 0; i < sk_OPENSSL_BLOCK_num(a); i++)
+			i2d(sk_OPENSSL_BLOCK_value(a, i), &p);
+
+		*pp = p;
+		return r;
+	}
+
+	pStart  = p;	/* Catch the beg of Setblobs*/
+	/* In this array we will store the SET blobs */
+	rgSetBlob = reallocarray(NULL, sk_OPENSSL_BLOCK_num(a), sizeof(MYBLOB));
+	if (rgSetBlob == NULL) {
+		ASN1err(ASN1_F_I2D_ASN1_SET, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+
+	for (i = 0; i < sk_OPENSSL_BLOCK_num(a); i++) {
+		rgSetBlob[i].pbData = p;	/* catch each set encode blob */
+		i2d(sk_OPENSSL_BLOCK_value(a, i), &p);
+		/* Length of this SetBlob */
+		rgSetBlob[i].cbData = p - rgSetBlob[i].pbData;
+	}
+	*pp = p;
+	totSize = p - pStart;	/* This is the total size of all set blobs */
+
+	/* Now we have to sort the blobs. I am using a simple algo.
+	 * Sort ptrs
+	 * Copy to temp-mem
+	 * Copy from temp-mem to user-mem
+	 */
+	qsort(rgSetBlob, sk_OPENSSL_BLOCK_num(a), sizeof(MYBLOB), SetBlobCmp);
+	if ((pTempMem = malloc(totSize)) == NULL) {
+		free(rgSetBlob);
+		ASN1err(ASN1_F_I2D_ASN1_SET, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+
+	/* Copy to temp mem */
+	p = pTempMem;
+	for (i = 0; i < sk_OPENSSL_BLOCK_num(a); ++i) {
+		memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData);
+		p += rgSetBlob[i].cbData;
+	}
+
+	/* Copy back to user mem*/
+	memcpy(pStart, pTempMem, totSize);
+	free(pTempMem);
+	free(rgSetBlob);
+
+	return r;
+}
+
+STACK_OF(OPENSSL_BLOCK) *
+d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a, const unsigned char **pp, long length,
+    d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK), int ex_tag,
+    int ex_class)
+{
+	ASN1_const_CTX c;
+	STACK_OF(OPENSSL_BLOCK) *ret = NULL;
+
+	if (a == NULL || (*a) == NULL) {
+		if ((ret = sk_OPENSSL_BLOCK_new_null()) == NULL) {
+			ASN1err(ASN1_F_D2I_ASN1_SET, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+	} else
+		ret = *a;
+
+	c.p = *pp;
+	c.max = (length == 0) ? 0 : (c.p + length);
+
+	c.inf = ASN1_get_object(&c.p, &c.slen, &c.tag, &c.xclass, c.max - c.p);
+	if (c.inf & 0x80)
+		goto err;
+	if (ex_class != c.xclass) {
+		ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_BAD_CLASS);
+		goto err;
+	}
+	if (ex_tag != c.tag) {
+		ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_BAD_TAG);
+		goto err;
+	}
+	if (c.slen + c.p > c.max) {
+		ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_LENGTH_ERROR);
+		goto err;
+	}
+	/* check for infinite constructed - it can be as long
+	 * as the amount of data passed to us */
+	if (c.inf == (V_ASN1_CONSTRUCTED + 1))
+		c.slen = length + *pp - c.p;
+	c.max = c.p + c.slen;
+
+	while (c.p < c.max) {
+		char *s;
+
+		if (M_ASN1_D2I_end_sequence())
+			break;
+		if ((s = d2i(NULL, &c.p, c.slen)) == NULL) {
+			ASN1err(ASN1_F_D2I_ASN1_SET,
+			    ASN1_R_ERROR_PARSING_SET_ELEMENT);
+			asn1_add_error(*pp, (int)(c.p - *pp));
+			goto err;
+		}
+		if (!sk_OPENSSL_BLOCK_push(ret, s))
+			goto err;
+	}
+	if (a != NULL)
+		*a = ret;
+	*pp = c.p;
+	return ret;
+
+err:
+	if (a == NULL || *a != ret) {
+		if (free_func != NULL)
+			sk_OPENSSL_BLOCK_pop_free(ret, free_func);
+		else
+			sk_OPENSSL_BLOCK_free(ret);
+	}
+	return NULL;
+}
+
+#endif
diff --git a/crypto/libressl/crypto/asn1/a_sign.c b/crypto/libressl/crypto/asn1/a_sign.c
new file mode 100644
index 0000000000..d1259b22ef
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_sign.c
@@ -0,0 +1,241 @@
+/* $OpenBSD: a_sign.c,v 1.20 2015/07/19 18:29:31 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "asn1_locl.h"
+
+int
+ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
+    ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey, const EVP_MD *type)
+{
+	EVP_MD_CTX ctx;
+	EVP_MD_CTX_init(&ctx);
+	if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey)) {
+		EVP_MD_CTX_cleanup(&ctx);
+		return 0;
+	}
+	return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx);
+}
+
+
+int
+ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
+    ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx)
+{
+	const EVP_MD *type;
+	EVP_PKEY *pkey;
+	unsigned char *buf_in = NULL, *buf_out = NULL;
+	size_t inl = 0, outl = 0, outll = 0;
+	int signid, paramtype;
+	int rv;
+
+	type = EVP_MD_CTX_md(ctx);
+	pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
+
+	if (!type || !pkey) {
+		ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
+		    ASN1_R_CONTEXT_NOT_INITIALISED);
+		return 0;
+	}
+
+	if (pkey->ameth->item_sign) {
+		rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2,
+		    signature);
+		if (rv == 1)
+			outl = signature->length;
+		/* Return value meanings:
+		 * <=0: error.
+		 *   1: method does everything.
+		 *   2: carry on as normal.
+		 *   3: ASN1 method sets algorithm identifiers: just sign.
+		 */
+		if (rv <= 0)
+			ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
+		if (rv <= 1)
+			goto err;
+	} else
+		rv = 2;
+
+	if (rv == 2) {
+		if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) {
+			if (!pkey->ameth ||
+			    !OBJ_find_sigid_by_algs(&signid,
+				EVP_MD_nid(type), pkey->ameth->pkey_id)) {
+				ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
+				    ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
+				return 0;
+			}
+		} else
+			signid = type->pkey_type;
+
+		if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
+			paramtype = V_ASN1_NULL;
+		else
+			paramtype = V_ASN1_UNDEF;
+
+		if (algor1)
+			X509_ALGOR_set0(algor1,
+			    OBJ_nid2obj(signid), paramtype, NULL);
+		if (algor2)
+			X509_ALGOR_set0(algor2,
+			    OBJ_nid2obj(signid), paramtype, NULL);
+
+	}
+
+	inl = ASN1_item_i2d(asn, &buf_in, it);
+	outll = outl = EVP_PKEY_size(pkey);
+	buf_out = malloc(outl);
+	if ((buf_in == NULL) || (buf_out == NULL)) {
+		outl = 0;
+		ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	if (!EVP_DigestSignUpdate(ctx, buf_in, inl) ||
+	    !EVP_DigestSignFinal(ctx, buf_out, &outl)) {
+		outl = 0;
+		ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
+		goto err;
+	}
+	free(signature->data);
+	signature->data = buf_out;
+	buf_out = NULL;
+	signature->length = outl;
+	/* In the interests of compatibility, I'll make sure that
+	 * the bit string has a 'not-used bits' value of 0
+	 */
+	signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
+	signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+
+err:
+	EVP_MD_CTX_cleanup(ctx);
+	if (buf_in != NULL) {
+		explicit_bzero((char *)buf_in, inl);
+		free(buf_in);
+	}
+	if (buf_out != NULL) {
+		explicit_bzero((char *)buf_out, outll);
+		free(buf_out);
+	}
+	return (outl);
+}
diff --git a/crypto/libressl/crypto/asn1/a_strex.c b/crypto/libressl/crypto/asn1/a_strex.c
new file mode 100644
index 0000000000..b9ac9ee956
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_strex.c
@@ -0,0 +1,646 @@
+/* $OpenBSD: a_strex.c,v 1.24 2014/07/11 08:44:47 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include "asn1_locl.h"
+
+#include "charmap.h"
+
+/* ASN1_STRING_print_ex() and X509_NAME_print_ex().
+ * Enhanced string and name printing routines handling
+ * multibyte characters, RFC2253 and a host of other
+ * options.
+ */
+
+#define CHARTYPE_BS_ESC		(ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253)
+
+#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \
+		  ASN1_STRFLGS_ESC_QUOTE | \
+		  ASN1_STRFLGS_ESC_CTRL | \
+		  ASN1_STRFLGS_ESC_MSB)
+
+
+/* Three IO functions for sending data to memory, a BIO and
+ * and a FILE pointer.
+ */
+static int
+send_bio_chars(void *arg, const void *buf, int len)
+{
+	if (!arg)
+		return 1;
+	if (BIO_write(arg, buf, len) != len)
+		return 0;
+	return 1;
+}
+
+static int
+send_fp_chars(void *arg, const void *buf, int len)
+{
+	if (!arg)
+		return 1;
+	if (fwrite(buf, 1, (size_t)len, arg) != (size_t)len)
+		return 0;
+	return 1;
+}
+
+typedef int char_io(void *arg, const void *buf, int len);
+
+/* This function handles display of
+ * strings, one character at a time.
+ * It is passed an unsigned long for each
+ * character because it could come from 2 or even
+ * 4 byte forms.
+ */
+
+static int
+do_esc_char(unsigned long c, unsigned char flags, char *do_quotes,
+    char_io *io_ch, void *arg)
+{
+	unsigned char chflgs, chtmp;
+	char tmphex[sizeof(long) * 2 + 3];
+
+	if (c > 0xffffffffL)
+		return -1;
+	if (c > 0xffff) {
+		snprintf(tmphex, sizeof tmphex, "\\W%08lX", c);
+		if (!io_ch(arg, tmphex, 10))
+			return -1;
+		return 10;
+	}
+	if (c > 0xff) {
+		snprintf(tmphex, sizeof tmphex, "\\U%04lX", c);
+		if (!io_ch(arg, tmphex, 6))
+			return -1;
+		return 6;
+	}
+	chtmp = (unsigned char)c;
+	if (chtmp > 0x7f)
+		chflgs = flags & ASN1_STRFLGS_ESC_MSB;
+	else
+		chflgs = char_type[chtmp] & flags;
+	if (chflgs & CHARTYPE_BS_ESC) {
+		/* If we don't escape with quotes, signal we need quotes */
+		if (chflgs & ASN1_STRFLGS_ESC_QUOTE) {
+			if (do_quotes)
+				*do_quotes = 1;
+			if (!io_ch(arg, &chtmp, 1))
+				return -1;
+			return 1;
+		}
+		if (!io_ch(arg, "\\", 1))
+			return -1;
+		if (!io_ch(arg, &chtmp, 1))
+			return -1;
+		return 2;
+	}
+	if (chflgs & (ASN1_STRFLGS_ESC_CTRL|ASN1_STRFLGS_ESC_MSB)) {
+		snprintf(tmphex, sizeof tmphex, "\\%02X", chtmp);
+		if (!io_ch(arg, tmphex, 3))
+			return -1;
+		return 3;
+	}
+	/* If we get this far and do any escaping at all must escape
+	 * the escape character itself: backslash.
+	 */
+	if (chtmp == '\\' && flags & ESC_FLAGS) {
+		if (!io_ch(arg, "\\\\", 2))
+			return -1;
+		return 2;
+	}
+	if (!io_ch(arg, &chtmp, 1))
+		return -1;
+	return 1;
+}
+
+#define BUF_TYPE_WIDTH_MASK	0x7
+#define BUF_TYPE_CONVUTF8	0x8
+
+/* This function sends each character in a buffer to
+ * do_esc_char(). It interprets the content formats
+ * and converts to or from UTF8 as appropriate.
+ */
+
+static int
+do_buf(unsigned char *buf, int buflen, int type, unsigned char flags,
+    char *quotes, char_io *io_ch, void *arg)
+{
+	int i, outlen, len;
+	unsigned char orflags, *p, *q;
+	unsigned long c;
+
+	p = buf;
+	q = buf + buflen;
+	outlen = 0;
+	while (p != q) {
+		if (p == buf && flags & ASN1_STRFLGS_ESC_2253)
+			orflags = CHARTYPE_FIRST_ESC_2253;
+		else
+			orflags = 0;
+		switch (type & BUF_TYPE_WIDTH_MASK) {
+		case 4:
+			c = ((unsigned long)*p++) << 24;
+			c |= ((unsigned long)*p++) << 16;
+			c |= ((unsigned long)*p++) << 8;
+			c |= *p++;
+			if (c > UNICODE_MAX || UNICODE_IS_SURROGATE(c))
+				return -1;
+			break;
+
+		case 2:
+			c = ((unsigned long)*p++) << 8;
+			c |= *p++;
+			if (UNICODE_IS_SURROGATE(c))
+				return -1;
+			break;
+
+		case 1:
+			c = *p++;
+			break;
+
+		case 0:
+			i = UTF8_getc(p, q - p, &c);
+			if (i < 0)
+				return -1;	/* Invalid UTF8String */
+			p += i;
+			break;
+		default:
+			return -1;		/* invalid width */
+		}
+		if (p == q && flags & ASN1_STRFLGS_ESC_2253)
+			orflags = CHARTYPE_LAST_ESC_2253;
+		if (type & BUF_TYPE_CONVUTF8) {
+			unsigned char utfbuf[6];
+			int utflen;
+
+			utflen = UTF8_putc(utfbuf, sizeof utfbuf, c);
+			if (utflen < 0)
+				return -1;
+			for (i = 0; i < utflen; i++) {
+				/* We don't need to worry about setting orflags correctly
+				 * because if utflen==1 its value will be correct anyway
+				 * otherwise each character will be > 0x7f and so the
+				 * character will never be escaped on first and last.
+				 */
+				len = do_esc_char(utfbuf[i],
+				    (unsigned char)(flags | orflags), quotes,
+				    io_ch, arg);
+				if (len < 0)
+					return -1;
+				outlen += len;
+			}
+		} else {
+			len = do_esc_char(c, (unsigned char)(flags | orflags),
+			    quotes, io_ch, arg);
+			if (len < 0)
+				return -1;
+			outlen += len;
+		}
+	}
+	return outlen;
+}
+
+/* This function hex dumps a buffer of characters */
+
+static int
+do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf, int buflen)
+{
+	static const char hexdig[] = "0123456789ABCDEF";
+	unsigned char *p, *q;
+	char hextmp[2];
+	if (arg) {
+		p = buf;
+		q = buf + buflen;
+		while (p != q) {
+			hextmp[0] = hexdig[*p >> 4];
+			hextmp[1] = hexdig[*p & 0xf];
+			if (!io_ch(arg, hextmp, 2))
+				return -1;
+			p++;
+		}
+	}
+	return buflen << 1;
+}
+
+/* "dump" a string. This is done when the type is unknown,
+ * or the flags request it. We can either dump the content
+ * octets or the entire DER encoding. This uses the RFC2253
+ * #01234 format.
+ */
+
+static int
+do_dump(unsigned long lflags, char_io *io_ch, void *arg, ASN1_STRING *str)
+{
+	/* Placing the ASN1_STRING in a temp ASN1_TYPE allows
+	 * the DER encoding to readily obtained
+	 */
+	ASN1_TYPE t;
+	unsigned char *der_buf, *p;
+	int outlen, der_len;
+
+	if (!io_ch(arg, "#", 1))
+		return -1;
+	/* If we don't dump DER encoding just dump content octets */
+	if (!(lflags & ASN1_STRFLGS_DUMP_DER)) {
+		outlen = do_hex_dump(io_ch, arg, str->data, str->length);
+		if (outlen < 0)
+			return -1;
+		return outlen + 1;
+	}
+	t.type = str->type;
+	t.value.ptr = (char *)str;
+	der_len = i2d_ASN1_TYPE(&t, NULL);
+	der_buf = malloc(der_len);
+	if (!der_buf)
+		return -1;
+	p = der_buf;
+	i2d_ASN1_TYPE(&t, &p);
+	outlen = do_hex_dump(io_ch, arg, der_buf, der_len);
+	free(der_buf);
+	if (outlen < 0)
+		return -1;
+	return outlen + 1;
+}
+
+/* Lookup table to convert tags to character widths,
+ * 0 = UTF8 encoded, -1 is used for non string types
+ * otherwise it is the number of bytes per character
+ */
+
+static const signed char tag2nbyte[] = {
+	-1, -1, -1, -1, -1,	/* 0-4 */
+	-1, -1, -1, -1, -1,	/* 5-9 */
+	-1, -1, 0, -1,		/* 10-13 */
+	-1, -1, -1, -1,		/* 15-17 */
+	-1, 1, 1,		/* 18-20 */
+	-1, 1, 1, 1,		/* 21-24 */
+	-1, 1, -1,		/* 25-27 */
+	4, -1, 2		/* 28-30 */
+};
+
+/* This is the main function, print out an
+ * ASN1_STRING taking note of various escape
+ * and display options. Returns number of
+ * characters written or -1 if an error
+ * occurred.
+ */
+
+static int
+do_print_ex(char_io *io_ch, void *arg, unsigned long lflags, ASN1_STRING *str)
+{
+	int outlen, len;
+	int type;
+	char quotes;
+	unsigned char flags;
+
+	quotes = 0;
+	/* Keep a copy of escape flags */
+	flags = (unsigned char)(lflags & ESC_FLAGS);
+	type = str->type;
+	outlen = 0;
+
+	if (lflags & ASN1_STRFLGS_SHOW_TYPE) {
+		const char *tagname;
+		tagname = ASN1_tag2str(type);
+		outlen += strlen(tagname);
+		if (!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1))
+			return -1;
+		outlen++;
+	}
+
+	/* Decide what to do with type, either dump content or display it */
+
+	/* Dump everything */
+	if (lflags & ASN1_STRFLGS_DUMP_ALL)
+		type = -1;
+	/* Ignore the string type */
+	else if (lflags & ASN1_STRFLGS_IGNORE_TYPE)
+		type = 1;
+	else {
+		/* Else determine width based on type */
+		if ((type > 0) && (type < 31))
+			type = tag2nbyte[type];
+		else
+			type = -1;
+		if ((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN))
+			type = 1;
+	}
+
+	if (type == -1) {
+		len = do_dump(lflags, io_ch, arg, str);
+		if (len < 0)
+			return -1;
+		outlen += len;
+		return outlen;
+	}
+
+	if (lflags & ASN1_STRFLGS_UTF8_CONVERT) {
+		/* Note: if string is UTF8 and we want
+		 * to convert to UTF8 then we just interpret
+		 * it as 1 byte per character to avoid converting
+		 * twice.
+		 */
+		if (!type)
+			type = 1;
+		else
+			type |= BUF_TYPE_CONVUTF8;
+	}
+
+	len = do_buf(str->data, str->length, type, flags, "es, io_ch, NULL);
+	if (len < 0)
+		return -1;
+	outlen += len;
+	if (quotes)
+		outlen += 2;
+	if (!arg)
+		return outlen;
+	if (quotes && !io_ch(arg, "\"", 1))
+		return -1;
+	if (do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0)
+		return -1;
+	if (quotes && !io_ch(arg, "\"", 1))
+		return -1;
+	return outlen;
+}
+
+/* Used for line indenting: print 'indent' spaces */
+
+static int
+do_indent(char_io *io_ch, void *arg, int indent)
+{
+	int i;
+	for (i = 0; i < indent; i++)
+		if (!io_ch(arg, " ", 1))
+			return 0;
+	return 1;
+}
+
+#define FN_WIDTH_LN	25
+#define FN_WIDTH_SN	10
+
+static int
+do_name_ex(char_io *io_ch, void *arg, X509_NAME *n, int indent,
+    unsigned long flags)
+{
+	int i, prev = -1, orflags, cnt;
+	int fn_opt, fn_nid;
+	ASN1_OBJECT *fn;
+	ASN1_STRING *val;
+	X509_NAME_ENTRY *ent;
+	char objtmp[80];
+	const char *objbuf;
+	int outlen, len;
+	char *sep_dn, *sep_mv, *sep_eq;
+	int sep_dn_len, sep_mv_len, sep_eq_len;
+
+	if (indent < 0)
+		indent = 0;
+	outlen = indent;
+	if (!do_indent(io_ch, arg, indent))
+		return -1;
+
+	switch (flags & XN_FLAG_SEP_MASK) {
+	case XN_FLAG_SEP_MULTILINE:
+		sep_dn = "\n";
+		sep_dn_len = 1;
+		sep_mv = " + ";
+		sep_mv_len = 3;
+		break;
+
+	case XN_FLAG_SEP_COMMA_PLUS:
+		sep_dn = ",";
+		sep_dn_len = 1;
+		sep_mv = "+";
+		sep_mv_len = 1;
+		indent = 0;
+		break;
+
+	case XN_FLAG_SEP_CPLUS_SPC:
+		sep_dn = ", ";
+		sep_dn_len = 2;
+		sep_mv = " + ";
+		sep_mv_len = 3;
+		indent = 0;
+		break;
+
+	case XN_FLAG_SEP_SPLUS_SPC:
+		sep_dn = "; ";
+		sep_dn_len = 2;
+		sep_mv = " + ";
+		sep_mv_len = 3;
+		indent = 0;
+		break;
+
+	default:
+		return -1;
+	}
+
+	if (flags & XN_FLAG_SPC_EQ) {
+		sep_eq = " = ";
+		sep_eq_len = 3;
+	} else {
+		sep_eq = "=";
+		sep_eq_len = 1;
+	}
+
+	fn_opt = flags & XN_FLAG_FN_MASK;
+
+	cnt = X509_NAME_entry_count(n);
+	for (i = 0; i < cnt; i++) {
+		if (flags & XN_FLAG_DN_REV)
+			ent = X509_NAME_get_entry(n, cnt - i - 1);
+		else
+			ent = X509_NAME_get_entry(n, i);
+		if (prev != -1) {
+			if (prev == ent->set) {
+				if (!io_ch(arg, sep_mv, sep_mv_len))
+					return -1;
+				outlen += sep_mv_len;
+			} else {
+				if (!io_ch(arg, sep_dn, sep_dn_len))
+					return -1;
+				outlen += sep_dn_len;
+				if (!do_indent(io_ch, arg, indent))
+					return -1;
+				outlen += indent;
+			}
+		}
+		prev = ent->set;
+		fn = X509_NAME_ENTRY_get_object(ent);
+		val = X509_NAME_ENTRY_get_data(ent);
+		fn_nid = OBJ_obj2nid(fn);
+		if (fn_opt != XN_FLAG_FN_NONE) {
+			int objlen, fld_len;
+			if ((fn_opt == XN_FLAG_FN_OID) ||
+			    (fn_nid == NID_undef)) {
+				OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1);
+				fld_len = 0; /* XXX: what should this be? */
+				objbuf = objtmp;
+			} else {
+				if (fn_opt == XN_FLAG_FN_SN) {
+					fld_len = FN_WIDTH_SN;
+					objbuf = OBJ_nid2sn(fn_nid);
+				} else if (fn_opt == XN_FLAG_FN_LN) {
+					fld_len = FN_WIDTH_LN;
+					objbuf = OBJ_nid2ln(fn_nid);
+				} else {
+					fld_len = 0; /* XXX: what should this be? */
+					objbuf = "";
+				}
+			}
+			objlen = strlen(objbuf);
+			if (!io_ch(arg, objbuf, objlen))
+				return -1;
+			if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) {
+				if (!do_indent(io_ch, arg, fld_len - objlen))
+					return -1;
+				outlen += fld_len - objlen;
+			}
+			if (!io_ch(arg, sep_eq, sep_eq_len))
+				return -1;
+			outlen += objlen + sep_eq_len;
+		}
+		/* If the field name is unknown then fix up the DER dump
+		 * flag. We might want to limit this further so it will
+ 		 * DER dump on anything other than a few 'standard' fields.
+		 */
+		if ((fn_nid == NID_undef) &&
+		    (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS))
+			orflags = ASN1_STRFLGS_DUMP_ALL;
+		else
+			orflags = 0;
+
+		len = do_print_ex(io_ch, arg, flags | orflags, val);
+		if (len < 0)
+			return -1;
+		outlen += len;
+	}
+	return outlen;
+}
+
+/* Wrappers round the main functions */
+
+int
+X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags)
+{
+	if (flags == XN_FLAG_COMPAT)
+		return X509_NAME_print(out, nm, indent);
+	return do_name_ex(send_bio_chars, out, nm, indent, flags);
+}
+
+int
+X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags)
+{
+	if (flags == XN_FLAG_COMPAT) {
+		BIO *btmp;
+		int ret;
+		btmp = BIO_new_fp(fp, BIO_NOCLOSE);
+		if (!btmp)
+			return -1;
+		ret = X509_NAME_print(btmp, nm, indent);
+		BIO_free(btmp);
+		return ret;
+	}
+	return do_name_ex(send_fp_chars, fp, nm, indent, flags);
+}
+
+int
+ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags)
+{
+	return do_print_ex(send_bio_chars, out, flags, str);
+}
+
+int
+ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags)
+{
+	return do_print_ex(send_fp_chars, fp, flags, str);
+}
+
+/* Utility function: convert any string type to UTF8, returns number of bytes
+ * in output string or a negative error code
+ */
+
+int
+ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in)
+{
+	ASN1_STRING stmp, *str = &stmp;
+	int mbflag, type, ret;
+
+	if (!in)
+		return -1;
+	type = in->type;
+	if ((type < 0) || (type > 30))
+		return -1;
+	mbflag = tag2nbyte[type];
+	if (mbflag == -1)
+		return -1;
+	mbflag |= MBSTRING_FLAG;
+	stmp.data = NULL;
+	stmp.length = 0;
+	ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag,
+	    B_ASN1_UTF8STRING);
+	if (ret < 0)
+		return ret;
+	*out = stmp.data;
+	return stmp.length;
+}
diff --git a/crypto/libressl/crypto/asn1/a_strnid.c b/crypto/libressl/crypto/asn1/a_strnid.c
new file mode 100644
index 0000000000..3ff050e28c
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_strnid.c
@@ -0,0 +1,292 @@
+/* $OpenBSD: a_strnid.c,v 1.18 2014/10/28 05:46:55 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
+static void st_free(ASN1_STRING_TABLE *tbl);
+static int sk_table_cmp(const ASN1_STRING_TABLE * const *a,
+    const ASN1_STRING_TABLE * const *b);
+
+
+/* This is the global mask for the mbstring functions: this is use to
+ * mask out certain types (such as BMPString and UTF8String) because
+ * certain software (e.g. Netscape) has problems with them.
+ */
+
+static unsigned long global_mask = B_ASN1_UTF8STRING;
+
+void
+ASN1_STRING_set_default_mask(unsigned long mask)
+{
+	global_mask = mask;
+}
+
+unsigned long
+ASN1_STRING_get_default_mask(void)
+{
+	return global_mask;
+}
+
+/* This function sets the default to various "flavours" of configuration.
+ * based on an ASCII string. Currently this is:
+ * MASK:XXXX : a numerical mask value.
+ * nobmp : Don't use BMPStrings (just Printable, T61).
+ * pkix : PKIX recommendation in RFC2459.
+ * utf8only : only use UTF8Strings (RFC2459 recommendation for 2004).
+ * default:   the default value, Printable, T61, BMP.
+ */
+
+int
+ASN1_STRING_set_default_mask_asc(const char *p)
+{
+	unsigned long mask;
+	char *end;
+
+	if (!strncmp(p, "MASK:", 5)) {
+		if (!p[5])
+			return 0;
+		mask = strtoul(p + 5, &end, 0);
+		if (*end)
+			return 0;
+	} else if (!strcmp(p, "nombstr"))
+		mask = ~((unsigned long)(B_ASN1_BMPSTRING|B_ASN1_UTF8STRING));
+	else if (!strcmp(p, "pkix"))
+		mask = ~((unsigned long)B_ASN1_T61STRING);
+	else if (!strcmp(p, "utf8only"))
+		mask = B_ASN1_UTF8STRING;
+	else if (!strcmp(p, "default"))
+		mask = 0xFFFFFFFFL;
+	else
+		return 0;
+	ASN1_STRING_set_default_mask(mask);
+	return 1;
+}
+
+/* The following function generates an ASN1_STRING based on limits in a table.
+ * Frequently the types and length of an ASN1_STRING are restricted by a
+ * corresponding OID. For example certificates and certificate requests.
+ */
+
+ASN1_STRING *
+ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in, int inlen,
+    int inform, int nid)
+{
+	ASN1_STRING_TABLE *tbl;
+	ASN1_STRING *str = NULL;
+	unsigned long mask;
+	int ret;
+	if (!out)
+		out = &str;
+	tbl = ASN1_STRING_TABLE_get(nid);
+	if (tbl) {
+		mask = tbl->mask;
+		if (!(tbl->flags & STABLE_NO_MASK))
+			mask &= global_mask;
+		ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
+		    tbl->minsize, tbl->maxsize);
+	} else
+		ret = ASN1_mbstring_copy(out, in, inlen, inform,
+		    DIRSTRING_TYPE & global_mask);
+	if (ret <= 0)
+		return NULL;
+	return *out;
+}
+
+/* Now the tables and helper functions for the string table:
+ */
+
+/* size limits: this stuff is taken straight from RFC3280 */
+
+#define ub_name				32768
+#define ub_common_name			64
+#define ub_locality_name		128
+#define ub_state_name			128
+#define ub_organization_name		64
+#define ub_organization_unit_name	64
+#define ub_title			64
+#define ub_email_address		128
+#define ub_serial_number		64
+
+
+/* This table must be kept in NID order */
+
+static const ASN1_STRING_TABLE tbl_standard[] = {
+	{NID_commonName,		1, ub_common_name, DIRSTRING_TYPE, 0},
+	{NID_countryName,		2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
+	{NID_localityName,		1, ub_locality_name, DIRSTRING_TYPE, 0},
+	{NID_stateOrProvinceName,	1, ub_state_name, DIRSTRING_TYPE, 0},
+	{NID_organizationName,		1, ub_organization_name, DIRSTRING_TYPE, 0},
+	{NID_organizationalUnitName,	1, ub_organization_unit_name, DIRSTRING_TYPE, 0},
+	{NID_pkcs9_emailAddress,	1, ub_email_address, B_ASN1_IA5STRING, STABLE_NO_MASK},
+	{NID_pkcs9_unstructuredName,	1, -1, PKCS9STRING_TYPE, 0},
+	{NID_pkcs9_challengePassword,	1, -1, PKCS9STRING_TYPE, 0},
+	{NID_pkcs9_unstructuredAddress,	1, -1, DIRSTRING_TYPE, 0},
+	{NID_givenName,			1, ub_name, DIRSTRING_TYPE, 0},
+	{NID_surname,			1, ub_name, DIRSTRING_TYPE, 0},
+	{NID_initials,			1, ub_name, DIRSTRING_TYPE, 0},
+	{NID_serialNumber,		1, ub_serial_number, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
+	{NID_friendlyName,		-1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
+	{NID_name,			1, ub_name, DIRSTRING_TYPE, 0},
+	{NID_dnQualifier,		-1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
+	{NID_domainComponent,		1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
+	{NID_ms_csp_name,		-1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}
+};
+
+static int
+sk_table_cmp(const ASN1_STRING_TABLE * const *a,
+    const ASN1_STRING_TABLE * const *b)
+{
+	return (*a)->nid - (*b)->nid;
+}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
+
+static int
+table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b)
+{
+	return a->nid - b->nid;
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
+
+ASN1_STRING_TABLE *
+ASN1_STRING_TABLE_get(int nid)
+{
+	int idx;
+	ASN1_STRING_TABLE *ttmp;
+	ASN1_STRING_TABLE fnd;
+
+	fnd.nid = nid;
+	ttmp = OBJ_bsearch_table(&fnd, tbl_standard,
+	    sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE));
+	if (ttmp)
+		return ttmp;
+	if (!stable)
+		return NULL;
+	idx = sk_ASN1_STRING_TABLE_find(stable, &fnd);
+	if (idx < 0)
+		return NULL;
+	return sk_ASN1_STRING_TABLE_value(stable, idx);
+}
+
+int
+ASN1_STRING_TABLE_add(int nid, long minsize, long maxsize, unsigned long mask,
+    unsigned long flags)
+{
+	ASN1_STRING_TABLE *tmp;
+	char new_nid = 0;
+
+	flags &= ~STABLE_FLAGS_MALLOC;
+	if (!stable)
+		stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
+	if (!stable) {
+		ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	if (!(tmp = ASN1_STRING_TABLE_get(nid))) {
+		tmp = malloc(sizeof(ASN1_STRING_TABLE));
+		if (!tmp) {
+			ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD,
+			    ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		tmp->flags = flags | STABLE_FLAGS_MALLOC;
+		tmp->nid = nid;
+		new_nid = 1;
+	} else tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
+		if (minsize != -1)
+		tmp->minsize = minsize;
+	if (maxsize != -1)
+		tmp->maxsize = maxsize;
+	tmp->mask = mask;
+	if (new_nid) {
+		if (sk_ASN1_STRING_TABLE_push(stable, tmp) == 0) {
+			free(tmp);
+			ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD,
+			    ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+	}
+	return 1;
+}
+
+void
+ASN1_STRING_TABLE_cleanup(void)
+{
+	STACK_OF(ASN1_STRING_TABLE) *tmp;
+
+	tmp = stable;
+	if (!tmp)
+		return;
+	stable = NULL;
+	sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
+}
+
+static void
+st_free(ASN1_STRING_TABLE *tbl)
+{
+	if (tbl->flags & STABLE_FLAGS_MALLOC)
+		free(tbl);
+}
diff --git a/crypto/libressl/crypto/asn1/a_time.c b/crypto/libressl/crypto/asn1/a_time.c
new file mode 100644
index 0000000000..63c4a2b2dd
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_time.c
@@ -0,0 +1,107 @@
+/* $OpenBSD: a_time.c,v 1.26 2015/10/02 15:04:45 beck Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* This is an implementation of the ASN1 Time structure which is:
+ *    Time ::= CHOICE {
+ *      utcTime        UTCTime,
+ *      generalTime    GeneralizedTime }
+ * written by Steve Henson.
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "o_time.h"
+#include "asn1_locl.h"
+
+const ASN1_ITEM ASN1_TIME_it = {
+	.itype = ASN1_ITYPE_MSTRING,
+	.utype = B_ASN1_TIME,
+	.templates = NULL,
+	.tcount = 0,
+	.funcs = NULL,
+	.size = sizeof(ASN1_STRING),
+	.sname = "ASN1_TIME",
+};
+
+
+ASN1_TIME *
+d2i_ASN1_TIME(ASN1_TIME **a, const unsigned char **in, long len)
+{
+	return (ASN1_TIME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ASN1_TIME_it);
+}
+
+int
+i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_TIME_it);
+}
+
+ASN1_TIME *
+ASN1_TIME_new(void)
+{
+	return (ASN1_TIME *)ASN1_item_new(&ASN1_TIME_it);
+}
+
+void
+ASN1_TIME_free(ASN1_TIME *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ASN1_TIME_it);
+}
diff --git a/crypto/libressl/crypto/asn1/a_time_tm.c b/crypto/libressl/crypto/asn1/a_time_tm.c
new file mode 100644
index 0000000000..3f2f8b8099
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_time_tm.c
@@ -0,0 +1,446 @@
+/* $OpenBSD: a_time_tm.c,v 1.8 2015/10/22 15:38:05 jsing Exp $ */
+/*
+ * Copyright (c) 2015 Bob Beck 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "o_time.h"
+
+#define RFC5280 0
+#define GENTIME_LENGTH 15
+#define UTCTIME_LENGTH 13
+
+int
+asn1_tm_cmp(struct tm *tm1, struct tm *tm2) {
+	if (tm1->tm_year < tm2->tm_year)
+		return (-1);
+	if (tm1->tm_year > tm2->tm_year)
+		return (1);
+	if (tm1->tm_mon < tm2->tm_mon)
+		return (-1);
+	if (tm1->tm_mon > tm2->tm_mon)
+		return (1);
+	if (tm1->tm_mday < tm2->tm_mday)
+		return (-1);
+	if (tm1->tm_mday > tm2->tm_mday)
+		return (1);
+	if (tm1->tm_hour < tm2->tm_hour)
+		return (-1);
+	if (tm1->tm_hour > tm2->tm_hour)
+		return (1);
+	if (tm1->tm_min < tm2->tm_min)
+		return (-1);
+	if (tm1->tm_min > tm2->tm_min)
+		return (1);
+	if (tm1->tm_sec < tm2->tm_sec)
+		return (-1);
+	if (tm1->tm_sec > tm2->tm_sec)
+		return (1);
+	return 0;
+}
+
+/* Format a time as an RFC 5280 format Generalized time */
+char *
+gentime_string_from_tm(struct tm *tm)
+{
+	char *ret = NULL;
+	int year;
+
+	year = tm->tm_year + 1900;
+	if (year < 0 || year > 9999)
+		return (NULL);
+
+	if (asprintf(&ret, "%04u%02u%02u%02u%02u%02uZ", year,
+	    tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min,
+	    tm->tm_sec) == -1)
+		ret = NULL;
+
+	return (ret);
+}
+
+/* Format a time as an RFC 5280 format UTC time */
+char *
+utctime_string_from_tm(struct tm *tm)
+{
+	char *ret = NULL;
+
+	if (tm->tm_year >= 150 || tm->tm_year < 50)
+		return (NULL);
+
+	if (asprintf(&ret, "%02u%02u%02u%02u%02u%02uZ",
+	    tm->tm_year % 100,  tm->tm_mon + 1, tm->tm_mday,
+	    tm->tm_hour, tm->tm_min, tm->tm_sec) == -1)
+		ret = NULL;
+
+	return (ret);
+}
+
+/* Format a time correctly for an X509 object as per RFC 5280 */
+char *
+rfc5280_string_from_tm(struct tm *tm)
+{
+	char *ret = NULL;
+	int year;
+
+	year = tm->tm_year + 1900;
+	if (year < 1950 || year > 9999)
+		return (NULL);
+
+	if (year < 2050)
+		ret = utctime_string_from_tm(tm);
+	else
+		ret = gentime_string_from_tm(tm);
+
+	return (ret);
+}
+
+/*
+ * Parse an RFC 5280 format ASN.1 time string.
+ *
+ * mode must be:
+ * 0 if we expect to parse a time as specified in RFC 5280 from an X509 object.
+ * V_ASN1_UTCTIME if we wish to parse on RFC5280 format UTC time.
+ * V_ASN1_GENERALIZEDTIME if we wish to parse an RFC5280 format Generalized time.
+ *
+ * Returns:
+ * -1 if the string was invalid.
+ * V_ASN1_UTCTIME if the string validated as a UTC time string.
+ * V_ASN1_GENERALIZEDTIME if the string validated as a Generalized time string.
+ *
+ * Fills in *tm with the corresponding time if tm is non NULL.
+ */
+#define	ATOI2(ar)	((ar) += 2, ((ar)[-2] - '0') * 10 + ((ar)[-1] - '0'))
+int
+asn1_time_parse(const char *bytes, size_t len, struct tm *tm, int mode)
+{
+	size_t i;
+	int type = 0;
+	struct tm ltm;
+	struct tm *lt;
+	const char *p;
+
+	if (bytes == NULL)
+		return (-1);
+
+	/* Constrain to valid lengths. */
+	if (len != UTCTIME_LENGTH && len != GENTIME_LENGTH)
+		return (-1);
+
+	lt = tm;
+	if (lt == NULL) {
+		memset(<m, 0, sizeof(ltm));
+		lt = <m;
+	}
+
+	/* Timezone is required and must be GMT (Zulu). */
+	if (bytes[len - 1] != 'Z')
+		return (-1);
+
+	/* Make sure everything else is digits. */
+	for (i = 0; i < len - 1; i++) {
+		if (isdigit((unsigned char)bytes[i]))
+			continue;
+		return (-1);
+	}
+
+	/*
+	 * Validate and convert the time
+	 */
+	p = bytes;
+	switch (len) {
+	case GENTIME_LENGTH:
+		if (mode == V_ASN1_UTCTIME)
+			return (-1);
+		lt->tm_year = (ATOI2(p) * 100) - 1900;	/* cc */
+		type = V_ASN1_GENERALIZEDTIME;
+		/* FALLTHROUGH */
+	case UTCTIME_LENGTH:
+		if (type == 0) {
+			if (mode == V_ASN1_GENERALIZEDTIME)
+				return (-1);
+			type = V_ASN1_UTCTIME;
+		}
+		lt->tm_year += ATOI2(p);		/* yy */
+		if (type == V_ASN1_UTCTIME) {
+			if (lt->tm_year < 50)
+				lt->tm_year += 100;
+		}
+		lt->tm_mon = ATOI2(p) - 1;		/* mm */
+		if (lt->tm_mon < 0 || lt->tm_mon > 11)
+			return (-1);
+		lt->tm_mday = ATOI2(p);			/* dd */
+		if (lt->tm_mday < 1 || lt->tm_mday > 31)
+			return (-1);
+		lt->tm_hour = ATOI2(p);			/* HH */
+		if (lt->tm_hour < 0 || lt->tm_hour > 23)
+			return (-1);
+		lt->tm_min = ATOI2(p);			/* MM */
+		if (lt->tm_min < 0 || lt->tm_min > 59)
+			return (-1);
+		lt->tm_sec = ATOI2(p);			/* SS */
+		/* Leap second 60 is not accepted. Reconsider later? */
+		if (lt->tm_sec < 0 || lt->tm_sec > 59)
+			return (-1);
+		break;
+	default:
+		return (-1);
+	}
+
+	return (type);
+}
+
+/*
+ * ASN1_TIME generic functions.
+ */
+
+static int
+ASN1_TIME_set_string_internal(ASN1_TIME *s, const char *str, int mode)
+{
+	int type;
+	char *tmp;
+
+	if ((type = asn1_time_parse(str, strlen(str), NULL, mode)) == -1)
+		return (0);
+	if (mode != 0 && mode != type)
+		return (0);
+
+	if (s == NULL)
+		return (1);
+
+	if ((tmp = strdup(str)) == NULL)
+		return (0);
+	free(s->data);
+	s->data = tmp;
+	s->length = strlen(tmp);
+	s->type = type;
+
+	return (1);
+}
+
+static ASN1_TIME *
+ASN1_TIME_adj_internal(ASN1_TIME *s, time_t t, int offset_day, long offset_sec,
+    int mode)
+{
+	int allocated = 0;
+	struct tm tm;
+	size_t len;
+	char * p;
+
+ 	if (gmtime_r(&t, &tm) == NULL)
+ 		return (NULL);
+
+	if (offset_day || offset_sec) {
+		if (!OPENSSL_gmtime_adj(&tm, offset_day, offset_sec))
+			return (NULL);
+	}
+
+	switch (mode) {
+	case V_ASN1_UTCTIME:
+		p = utctime_string_from_tm(&tm);
+		break;
+	case V_ASN1_GENERALIZEDTIME:
+		p = gentime_string_from_tm(&tm);
+		break;
+	case RFC5280:
+		p = rfc5280_string_from_tm(&tm);
+		break;
+	default:
+		return (NULL);
+	}
+	if (p == NULL) {
+		ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ,
+		    ASN1_R_ILLEGAL_TIME_VALUE);
+		return (NULL);
+	}
+
+	if (s == NULL) {
+		if ((s = ASN1_TIME_new()) == NULL)
+			return (NULL);
+		allocated = 1;
+	}
+
+	len = strlen(p);
+	switch (len) {
+	case GENTIME_LENGTH:
+		s->type = V_ASN1_GENERALIZEDTIME;
+		break;
+ 	case UTCTIME_LENGTH:
+		s->type = V_ASN1_UTCTIME;
+		break;
+	default:
+		if (allocated)
+			ASN1_TIME_free(s);
+		free(p);
+		return (NULL);
+	}
+	free(s->data);
+	s->data = p;
+	s->length = len;
+	return (s);
+}
+
+ASN1_TIME *
+ASN1_TIME_set(ASN1_TIME *s, time_t t)
+{
+	return (ASN1_TIME_adj(s, t, 0, 0));
+}
+
+ASN1_TIME *
+ASN1_TIME_adj(ASN1_TIME *s, time_t t, int offset_day, long offset_sec)
+{
+	return (ASN1_TIME_adj_internal(s, t, offset_day, offset_sec, RFC5280));
+}
+
+int
+ASN1_TIME_check(ASN1_TIME *t)
+{
+	if (t->type != V_ASN1_GENERALIZEDTIME && t->type != V_ASN1_UTCTIME)
+		return (0);
+	return (t->type == asn1_time_parse(t->data, t->length, NULL, t->type));
+}
+
+ASN1_GENERALIZEDTIME *
+ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out)
+{
+	ASN1_GENERALIZEDTIME *tmp = NULL;
+	struct tm tm;
+	char *str;
+
+	if (t->type != V_ASN1_GENERALIZEDTIME && t->type != V_ASN1_UTCTIME)
+		return (NULL);
+
+	memset(&tm, 0, sizeof(tm));
+	if (t->type != asn1_time_parse(t->data, t->length, &tm, t->type))
+		return (NULL);
+	if ((str = gentime_string_from_tm(&tm)) == NULL)
+		return (NULL);
+
+	if (out != NULL)
+		tmp = *out;
+	if (tmp == NULL && (tmp = ASN1_GENERALIZEDTIME_new()) == NULL) {
+		free(str);
+		return (NULL);
+	}
+	if (out != NULL)
+		*out = tmp;
+
+	free(tmp->data);
+	tmp->data = str;
+	tmp->length = strlen(str);
+	return (tmp);
+}
+
+int
+ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
+{
+	return (ASN1_TIME_set_string_internal(s, str, 0));
+}
+
+/*
+ * ASN1_UTCTIME wrappers
+ */
+
+int
+ASN1_UTCTIME_check(ASN1_UTCTIME *d)
+{
+	if (d->type != V_ASN1_UTCTIME)
+		return (0);
+	return (d->type == asn1_time_parse(d->data, d->length, NULL, d->type));
+}
+
+int
+ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str)
+{
+	if (s != NULL && s->type != V_ASN1_UTCTIME)
+		return (0);
+	return (ASN1_TIME_set_string_internal(s, str, V_ASN1_UTCTIME));
+}
+
+ASN1_UTCTIME *
+ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t)
+{
+	return (ASN1_UTCTIME_adj(s, t, 0, 0));
+}
+
+ASN1_UTCTIME *
+ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, int offset_day, long offset_sec)
+{
+	return (ASN1_TIME_adj_internal(s, t, offset_day, offset_sec,
+	    V_ASN1_UTCTIME));
+}
+
+int
+ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t2)
+{
+	struct tm tm1, tm2;
+
+	/*
+	 * This function has never handled failure conditions properly
+	 * and should be deprecated. The OpenSSL version used to
+	 * simply follow NULL pointers on failure. BoringSSL and
+	 * OpenSSL now make it return -2 on failure.
+	 *
+	 * The danger is that users of this function will not
+	 * differentiate the -2 failure case from t1 < t2.
+	 */
+	if (asn1_time_parse(s->data, s->length, &tm1, V_ASN1_UTCTIME) == -1)
+		return (-2); /* XXX */
+
+	if (gmtime_r(&t2, &tm2) == NULL)
+		return (-2); /* XXX */
+
+	return asn1_tm_cmp(&tm1, &tm2);
+}
+
+/*
+ * ASN1_GENERALIZEDTIME wrappers
+ */
+
+int
+ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d)
+{
+	if (d->type != V_ASN1_GENERALIZEDTIME)
+		return (0);
+	return (d->type == asn1_time_parse(d->data, d->length, NULL, d->type));
+}
+
+int
+ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str)
+{
+	if (s != NULL && s->type != V_ASN1_GENERALIZEDTIME)
+		return (0);
+	return (ASN1_TIME_set_string_internal(s, str, V_ASN1_GENERALIZEDTIME));
+}
+
+ASN1_GENERALIZEDTIME *
+ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, time_t t)
+{
+	return (ASN1_GENERALIZEDTIME_adj(s, t, 0, 0));
+}
+
+ASN1_GENERALIZEDTIME *
+ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, time_t t, int offset_day,
+    long offset_sec)
+{
+	return (ASN1_TIME_adj_internal(s, t, offset_day, offset_sec,
+	    V_ASN1_GENERALIZEDTIME));
+}
diff --git a/crypto/libressl/crypto/asn1/a_type.c b/crypto/libressl/crypto/asn1/a_type.c
new file mode 100644
index 0000000000..4186667a3a
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_type.c
@@ -0,0 +1,156 @@
+/* $OpenBSD: a_type.c,v 1.18 2016/05/04 14:53:29 tedu Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+
+int
+ASN1_TYPE_get(ASN1_TYPE *a)
+{
+	if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
+		return (a->type);
+	else
+		return (0);
+}
+
+void
+ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value)
+{
+	if (a->value.ptr != NULL) {
+		ASN1_TYPE **tmp_a = &a;
+		ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL);
+	}
+	a->type = type;
+	if (type == V_ASN1_BOOLEAN)
+		a->value.boolean = value ? 0xff : 0;
+	else
+		a->value.ptr = value;
+}
+
+int
+ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
+{
+	if (!value || (type == V_ASN1_BOOLEAN)) {
+		void *p = (void *)value;
+		ASN1_TYPE_set(a, type, p);
+	} else if (type == V_ASN1_OBJECT) {
+		ASN1_OBJECT *odup;
+		odup = OBJ_dup(value);
+		if (!odup)
+			return 0;
+		ASN1_TYPE_set(a, type, odup);
+	} else {
+		ASN1_STRING *sdup;
+		sdup = ASN1_STRING_dup(value);
+		if (!sdup)
+			return 0;
+		ASN1_TYPE_set(a, type, sdup);
+	}
+	return 1;
+}
+
+/* Returns 0 if they are equal, != 0 otherwise. */
+int
+ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b)
+{
+	int result = -1;
+
+	if (!a || !b || a->type != b->type)
+		return -1;
+
+	switch (a->type) {
+	case V_ASN1_OBJECT:
+		result = OBJ_cmp(a->value.object, b->value.object);
+		break;
+	case V_ASN1_BOOLEAN:
+		result = a->value.boolean - b->value.boolean;
+		break;
+	case V_ASN1_NULL:
+		result = 0;	/* They do not have content. */
+		break;
+
+	case V_ASN1_INTEGER:
+	case V_ASN1_ENUMERATED:
+	case V_ASN1_BIT_STRING:
+	case V_ASN1_OCTET_STRING:
+	case V_ASN1_SEQUENCE:
+	case V_ASN1_SET:
+	case V_ASN1_NUMERICSTRING:
+	case V_ASN1_PRINTABLESTRING:
+	case V_ASN1_T61STRING:
+	case V_ASN1_VIDEOTEXSTRING:
+	case V_ASN1_IA5STRING:
+	case V_ASN1_UTCTIME:
+	case V_ASN1_GENERALIZEDTIME:
+	case V_ASN1_GRAPHICSTRING:
+	case V_ASN1_VISIBLESTRING:
+	case V_ASN1_GENERALSTRING:
+	case V_ASN1_UNIVERSALSTRING:
+	case V_ASN1_BMPSTRING:
+	case V_ASN1_UTF8STRING:
+	case V_ASN1_OTHER:
+	default:
+		result = ASN1_STRING_cmp((ASN1_STRING *)a->value.ptr,
+		    (ASN1_STRING *)b->value.ptr);
+		break;
+	}
+
+	return result;
+}
diff --git a/crypto/libressl/crypto/asn1/a_utf8.c b/crypto/libressl/crypto/asn1/a_utf8.c
new file mode 100644
index 0000000000..371de59579
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_utf8.c
@@ -0,0 +1,199 @@
+/* $OpenBSD: a_utf8.c,v 1.7 2014/06/12 15:49:27 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include "asn1_locl.h"
+
+/* UTF8 utilities */
+
+/*
+ * This parses a UTF8 string one character at a time. It is passed a pointer
+ * to the string and the length of the string. It sets 'value' to the value of
+ * the current character. It returns the number of characters read or a
+ * negative error code:
+ * -1 = string too short
+ * -2 = illegal character
+ * -3 = subsequent characters not of the form 10xxxxxx
+ * -4 = character encoded incorrectly (not minimal length).
+ */
+
+int
+UTF8_getc(const unsigned char *str, int len, unsigned long *val)
+{
+	const unsigned char *p;
+	unsigned long value;
+	int ret;
+	if (len <= 0)
+		return 0;
+	p = str;
+
+	/* Check syntax and work out the encoded value (if correct) */
+	if ((*p & 0x80) == 0) {
+		value = *p++ & 0x7f;
+		ret = 1;
+	} else if ((*p & 0xe0) == 0xc0) {
+		if (*p < 0xc2)
+			return -2;
+		if (len < 2)
+			return -1;
+		if ((p[1] & 0xc0) != 0x80)
+			return -3;
+		value = (*p++ & 0x1f) << 6;
+		value |= *p++ & 0x3f;
+		if (value < 0x80)
+			return -4;
+		ret = 2;
+	} else if ((*p & 0xf0) == 0xe0) {
+		if (len < 3)
+			return -1;
+		if (((p[1] & 0xc0) != 0x80) ||
+		    ((p[2] & 0xc0) != 0x80))
+			return -3;
+		value = (*p++ & 0xf) << 12;
+		value |= (*p++ & 0x3f) << 6;
+		value |= *p++ & 0x3f;
+		if (value < 0x800)
+			return -4;
+		/* surrogate pair code points are not valid */
+		if (value >= 0xd800 && value < 0xe000)
+			return -2;
+		ret = 3;
+	} else if ((*p & 0xf8) == 0xf0 && (*p < 0xf5)) {
+		if (len < 4)
+			return -1;
+		if (((p[1] & 0xc0) != 0x80) ||
+		    ((p[2] & 0xc0) != 0x80) ||
+		    ((p[3] & 0xc0) != 0x80))
+			return -3;
+		value = ((unsigned long)(*p++ & 0x7)) << 18;
+		value |= (*p++ & 0x3f) << 12;
+		value |= (*p++ & 0x3f) << 6;
+		value |= *p++ & 0x3f;
+		if (value < 0x10000)
+			return -4;
+		if (value > UNICODE_MAX)
+			return -2;
+		ret = 4;
+	} else
+		return -2;
+	*val = value;
+	return ret;
+}
+
+/* This takes a Unicode code point 'value' and writes its UTF-8 encoded form
+ * in 'str' where 'str' is a buffer of at least length 'len'.  If 'str'
+ * is NULL, then nothing is written and just the return code is determined.
+
+ * Returns less than zero on error:
+ *  -1 if 'str' is not NULL and 'len' is too small
+ *  -2 if 'value' is an invalid character (surrogate or out-of-range)
+ *
+ * Otherwise, returns the number of bytes in 'value's encoded form
+ * (i.e., the number of bytes written to 'str' when it's not NULL).
+ *
+ * It will need at most 4 characters.
+ */
+
+int
+UTF8_putc(unsigned char *str, int len, unsigned long value)
+{
+	if (value < 0x80) {
+		if (str != NULL) {
+			if (len < 1)
+				return -1;
+			str[0] = (unsigned char)value;
+		}
+		return 1;
+	}
+	if (value < 0x800) {
+		if (str != NULL) {
+			if (len < 2)
+				return -1;
+			str[0] = (unsigned char)(((value >> 6) & 0x1f) | 0xc0);
+			str[1] = (unsigned char)((value & 0x3f) | 0x80);
+		}
+		return 2;
+	}
+	if (value < 0x10000) {
+		if (UNICODE_IS_SURROGATE(value))
+			return -2;
+		if (str != NULL) {
+			if (len < 3)
+				return -1;
+			str[0] = (unsigned char)(((value >> 12) & 0xf) | 0xe0);
+			str[1] = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+			str[2] = (unsigned char)((value & 0x3f) | 0x80);
+		}
+		return 3;
+	}
+	if (value <= UNICODE_MAX) {
+		if (str != NULL) {
+			if (len < 4)
+				return -1;
+			str[0] = (unsigned char)(((value >> 18) & 0x7) | 0xf0);
+			str[1] = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+			str[2] = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+			str[3] = (unsigned char)((value & 0x3f) | 0x80);
+		}
+		return 4;
+	}
+	return -2;
+}
diff --git a/crypto/libressl/crypto/asn1/a_verify.c b/crypto/libressl/crypto/asn1/a_verify.c
new file mode 100644
index 0000000000..71f67a115c
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/a_verify.c
@@ -0,0 +1,173 @@
+/* $OpenBSD: a_verify.c,v 1.21 2015/01/28 04:14:31 beck Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "asn1_locl.h"
+
+int
+ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
+    ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
+{
+	EVP_MD_CTX ctx;
+	unsigned char *buf_in = NULL;
+	int ret = -1, inl;
+
+	int mdnid, pknid;
+
+	if (!pkey) {
+		ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
+		return -1;
+	}
+
+	if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
+	{
+		ASN1err(ASN1_F_ASN1_VERIFY,
+		    ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
+		return -1;
+	}
+
+	EVP_MD_CTX_init(&ctx);
+
+	/* Convert signature OID into digest and public key OIDs */
+	if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) {
+		ASN1err(ASN1_F_ASN1_ITEM_VERIFY,
+		    ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
+		goto err;
+	}
+	if (mdnid == NID_undef) {
+		if (!pkey->ameth || !pkey->ameth->item_verify) {
+			ASN1err(ASN1_F_ASN1_ITEM_VERIFY,
+			    ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
+			goto err;
+		}
+		ret = pkey->ameth->item_verify(&ctx, it, asn, a,
+		    signature, pkey);
+		/* Return value of 2 means carry on, anything else means we
+		 * exit straight away: either a fatal error of the underlying
+		 * verification routine handles all verification.
+		 */
+		if (ret != 2)
+			goto err;
+		ret = -1;
+	} else {
+		const EVP_MD *type;
+		type = EVP_get_digestbynid(mdnid);
+		if (type == NULL) {
+			ASN1err(ASN1_F_ASN1_ITEM_VERIFY,
+			    ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+			goto err;
+		}
+
+		/* Check public key OID matches public key type */
+		if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) {
+			ASN1err(ASN1_F_ASN1_ITEM_VERIFY,
+			    ASN1_R_WRONG_PUBLIC_KEY_TYPE);
+			goto err;
+		}
+
+		if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey)) {
+			ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
+			ret = 0;
+			goto err;
+		}
+
+	}
+
+	inl = ASN1_item_i2d(asn, &buf_in, it);
+
+	if (buf_in == NULL) {
+		ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	if (!EVP_DigestVerifyUpdate(&ctx, buf_in, inl)) {
+		ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
+		ret = 0;
+		goto err;
+	}
+
+	explicit_bzero(buf_in, (unsigned int)inl);
+	free(buf_in);
+
+	if (EVP_DigestVerifyFinal(&ctx, signature->data,
+	    (size_t)signature->length) <= 0) {
+		ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
+		ret = 0;
+		goto err;
+	}
+	/* we don't need to zero the 'ctx' because we just checked
+	 * public information */
+	/* memset(&ctx,0,sizeof(ctx)); */
+	ret = 1;
+
+err:
+	EVP_MD_CTX_cleanup(&ctx);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/asn1/ameth_lib.c b/crypto/libressl/crypto/asn1/ameth_lib.c
new file mode 100644
index 0000000000..56ff3ec71e
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/ameth_lib.c
@@ -0,0 +1,457 @@
+/* $OpenBSD: ameth_lib.c,v 1.14 2014/07/13 16:03:09 beck Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+
+#include "asn1_locl.h"
+
+extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
+extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[];
+extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD gostr01_asn1_meths[];
+extern const EVP_PKEY_ASN1_METHOD gostimit_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth;
+
+/* Keep this sorted in type order !! */
+static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
+#ifndef OPENSSL_NO_RSA
+	&rsa_asn1_meths[0],
+	&rsa_asn1_meths[1],
+#endif
+#ifndef OPENSSL_NO_DH
+	&dh_asn1_meth,
+#endif
+#ifndef OPENSSL_NO_DSA
+	&dsa_asn1_meths[0],
+	&dsa_asn1_meths[1],
+	&dsa_asn1_meths[2],
+	&dsa_asn1_meths[3],
+	&dsa_asn1_meths[4],
+#endif
+#ifndef OPENSSL_NO_EC
+	&eckey_asn1_meth,
+#endif
+#ifndef OPENSSL_NO_GOST
+	&gostr01_asn1_meths[0],
+	&gostimit_asn1_meth,
+#endif
+	&hmac_asn1_meth,
+	&cmac_asn1_meth,
+#ifndef OPENSSL_NO_GOST
+	&gostr01_asn1_meths[1],
+	&gostr01_asn1_meths[2],
+#endif
+};
+
+typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
+DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD)
+static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL;
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
+    const EVP_PKEY_ASN1_METHOD *, ameth);
+
+static int
+ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *a,
+    const EVP_PKEY_ASN1_METHOD * const *b)
+{
+	return ((*a)->pkey_id - (*b)->pkey_id);
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
+    const EVP_PKEY_ASN1_METHOD *, ameth);
+
+int
+EVP_PKEY_asn1_get_count(void)
+{
+	int num = sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *);
+	if (app_methods)
+		num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
+	return num;
+}
+
+const EVP_PKEY_ASN1_METHOD *
+EVP_PKEY_asn1_get0(int idx)
+{
+	int num = sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *);
+	if (idx < 0)
+		return NULL;
+	if (idx < num)
+		return standard_methods[idx];
+	idx -= num;
+	return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
+}
+
+static const EVP_PKEY_ASN1_METHOD *
+pkey_asn1_find(int type)
+{
+	EVP_PKEY_ASN1_METHOD tmp;
+	const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
+	tmp.pkey_id = type;
+	if (app_methods) {
+		int idx;
+		idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
+		if (idx >= 0)
+			return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
+	}
+	ret = OBJ_bsearch_ameth(&t, standard_methods,
+	    sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *));
+	if (!ret || !*ret)
+		return NULL;
+	return *ret;
+}
+
+/* Find an implementation of an ASN1 algorithm. If 'pe' is not NULL
+ * also search through engines and set *pe to a functional reference
+ * to the engine implementing 'type' or NULL if no engine implements
+ * it.
+ */
+
+const EVP_PKEY_ASN1_METHOD *
+EVP_PKEY_asn1_find(ENGINE **pe, int type)
+{
+	const EVP_PKEY_ASN1_METHOD *t;
+
+	for (;;) {
+		t = pkey_asn1_find(type);
+		if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
+			break;
+		type = t->pkey_base_id;
+	}
+	if (pe) {
+#ifndef OPENSSL_NO_ENGINE
+		ENGINE *e;
+		/* type will contain the final unaliased type */
+		e = ENGINE_get_pkey_asn1_meth_engine(type);
+		if (e) {
+			*pe = e;
+			return ENGINE_get_pkey_asn1_meth(e, type);
+		}
+#endif
+		*pe = NULL;
+	}
+	return t;
+}
+
+const EVP_PKEY_ASN1_METHOD *
+EVP_PKEY_asn1_find_str(ENGINE **pe, const char *str, int len)
+{
+	int i;
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	if (len == -1)
+		len = strlen(str);
+	if (pe) {
+#ifndef OPENSSL_NO_ENGINE
+		ENGINE *e;
+		ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
+		if (ameth) {
+			/* Convert structural into
+			 * functional reference
+			 */
+			if (!ENGINE_init(e))
+				ameth = NULL;
+			ENGINE_free(e);
+			*pe = e;
+			return ameth;
+		}
+#endif
+		*pe = NULL;
+	}
+	for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
+		ameth = EVP_PKEY_asn1_get0(i);
+		if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
+			continue;
+		if (((int)strlen(ameth->pem_str) == len) &&
+		    !strncasecmp(ameth->pem_str, str, len))
+			return ameth;
+	}
+	return NULL;
+}
+
+int
+EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
+{
+	if (app_methods == NULL) {
+		app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
+		if (!app_methods)
+			return 0;
+	}
+	if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
+		return 0;
+	sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
+	return 1;
+}
+
+int
+EVP_PKEY_asn1_add_alias(int to, int from)
+{
+	EVP_PKEY_ASN1_METHOD *ameth;
+
+	ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
+	if (!ameth)
+		return 0;
+	ameth->pkey_base_id = to;
+	if (!EVP_PKEY_asn1_add0(ameth)) {
+		EVP_PKEY_asn1_free(ameth);
+		return 0;
+	}
+	return 1;
+}
+
+int
+EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, int *ppkey_flags,
+    const char **pinfo, const char **ppem_str,
+    const EVP_PKEY_ASN1_METHOD *ameth)
+{
+	if (!ameth)
+		return 0;
+	if (ppkey_id)
+		*ppkey_id = ameth->pkey_id;
+	if (ppkey_base_id)
+		*ppkey_base_id = ameth->pkey_base_id;
+	if (ppkey_flags)
+		*ppkey_flags = ameth->pkey_flags;
+	if (pinfo)
+		*pinfo = ameth->info;
+	if (ppem_str)
+		*ppem_str = ameth->pem_str;
+	return 1;
+}
+
+const EVP_PKEY_ASN1_METHOD*
+EVP_PKEY_get0_asn1(EVP_PKEY *pkey)
+{
+	return pkey->ameth;
+}
+
+EVP_PKEY_ASN1_METHOD*
+EVP_PKEY_asn1_new(int id, int flags, const char *pem_str, const char *info)
+{
+	EVP_PKEY_ASN1_METHOD *ameth;
+
+	ameth = calloc(1, sizeof(EVP_PKEY_ASN1_METHOD));
+	if (!ameth)
+		return NULL;
+
+	ameth->pkey_id = id;
+	ameth->pkey_base_id = id;
+	ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
+
+	if (info) {
+		ameth->info = strdup(info);
+		if (!ameth->info)
+			goto err;
+	} else
+		ameth->info = NULL;
+
+	if (pem_str) {
+		ameth->pem_str = strdup(pem_str);
+		if (!ameth->pem_str)
+			goto err;
+	} else
+		ameth->pem_str = NULL;
+
+	ameth->pub_decode = 0;
+	ameth->pub_encode = 0;
+	ameth->pub_cmp = 0;
+	ameth->pub_print = 0;
+
+	ameth->priv_decode = 0;
+	ameth->priv_encode = 0;
+	ameth->priv_print = 0;
+
+	ameth->old_priv_encode = 0;
+	ameth->old_priv_decode = 0;
+
+	ameth->item_verify = 0;
+	ameth->item_sign = 0;
+
+	ameth->pkey_size = 0;
+	ameth->pkey_bits = 0;
+
+	ameth->param_decode = 0;
+	ameth->param_encode = 0;
+	ameth->param_missing = 0;
+	ameth->param_copy = 0;
+	ameth->param_cmp = 0;
+	ameth->param_print = 0;
+
+	ameth->pkey_free = 0;
+	ameth->pkey_ctrl = 0;
+
+	return ameth;
+
+err:
+	EVP_PKEY_asn1_free(ameth);
+	return NULL;
+}
+
+void
+EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, const EVP_PKEY_ASN1_METHOD *src)
+{
+	dst->pub_decode = src->pub_decode;
+	dst->pub_encode = src->pub_encode;
+	dst->pub_cmp = src->pub_cmp;
+	dst->pub_print = src->pub_print;
+
+	dst->priv_decode = src->priv_decode;
+	dst->priv_encode = src->priv_encode;
+	dst->priv_print = src->priv_print;
+
+	dst->old_priv_encode = src->old_priv_encode;
+	dst->old_priv_decode = src->old_priv_decode;
+
+	dst->pkey_size = src->pkey_size;
+	dst->pkey_bits = src->pkey_bits;
+
+	dst->param_decode = src->param_decode;
+	dst->param_encode = src->param_encode;
+	dst->param_missing = src->param_missing;
+	dst->param_copy = src->param_copy;
+	dst->param_cmp = src->param_cmp;
+	dst->param_print = src->param_print;
+
+	dst->pkey_free = src->pkey_free;
+	dst->pkey_ctrl = src->pkey_ctrl;
+
+	dst->item_sign = src->item_sign;
+	dst->item_verify = src->item_verify;
+}
+
+void
+EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
+{
+	if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC)) {
+		free(ameth->pem_str);
+		free(ameth->info);
+		free(ameth);
+	}
+}
+
+void
+EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
+    int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub),
+    int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk),
+    int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
+    int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+	ASN1_PCTX *pctx),
+    int (*pkey_size)(const EVP_PKEY *pk),
+    int (*pkey_bits)(const EVP_PKEY *pk))
+{
+	ameth->pub_decode = pub_decode;
+	ameth->pub_encode = pub_encode;
+	ameth->pub_cmp = pub_cmp;
+	ameth->pub_print = pub_print;
+	ameth->pkey_size = pkey_size;
+	ameth->pkey_bits = pkey_bits;
+}
+
+void
+EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
+    int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf),
+    int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk),
+    int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+	ASN1_PCTX *pctx))
+{
+	ameth->priv_decode = priv_decode;
+	ameth->priv_encode = priv_encode;
+	ameth->priv_print = priv_print;
+}
+
+void
+EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
+    int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder, int derlen),
+    int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder),
+    int (*param_missing)(const EVP_PKEY *pk),
+    int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from),
+    int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
+    int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+	ASN1_PCTX *pctx))
+{
+	ameth->param_decode = param_decode;
+	ameth->param_encode = param_encode;
+	ameth->param_missing = param_missing;
+	ameth->param_copy = param_copy;
+	ameth->param_cmp = param_cmp;
+	ameth->param_print = param_print;
+}
+
+void
+EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
+    void (*pkey_free)(EVP_PKEY *pkey))
+{
+	ameth->pkey_free = pkey_free;
+}
+
+void
+EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
+    int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2))
+{
+	ameth->pkey_ctrl = pkey_ctrl;
+}
diff --git a/crypto/libressl/crypto/asn1/asn1_err.c b/crypto/libressl/crypto/asn1/asn1_err.c
new file mode 100644
index 0000000000..aa1f9c0b11
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/asn1_err.c
@@ -0,0 +1,333 @@
+/* $OpenBSD$ */
+/* ====================================================================
+ * Copyright (c) 1999-2011 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ASN1,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ASN1,0,reason)
+
+static ERR_STRING_DATA ASN1_str_functs[] = {
+	{ERR_FUNC(ASN1_F_A2D_ASN1_OBJECT), "a2d_ASN1_OBJECT"},
+	{ERR_FUNC(ASN1_F_A2I_ASN1_ENUMERATED), "a2i_ASN1_ENUMERATED"},
+	{ERR_FUNC(ASN1_F_A2I_ASN1_INTEGER), "a2i_ASN1_INTEGER"},
+	{ERR_FUNC(ASN1_F_A2I_ASN1_STRING), "a2i_ASN1_STRING"},
+	{ERR_FUNC(ASN1_F_APPEND_EXP), "APPEND_EXP"},
+	{ERR_FUNC(ASN1_F_ASN1_BIT_STRING_SET_BIT), "ASN1_BIT_STRING_set_bit"},
+	{ERR_FUNC(ASN1_F_ASN1_CB), "ASN1_CB"},
+	{ERR_FUNC(ASN1_F_ASN1_CHECK_TLEN), "ASN1_CHECK_TLEN"},
+	{ERR_FUNC(ASN1_F_ASN1_COLLATE_PRIMITIVE), "ASN1_COLLATE_PRIMITIVE"},
+	{ERR_FUNC(ASN1_F_ASN1_COLLECT), "ASN1_COLLECT"},
+	{ERR_FUNC(ASN1_F_ASN1_D2I_EX_PRIMITIVE), "ASN1_D2I_EX_PRIMITIVE"},
+	{ERR_FUNC(ASN1_F_ASN1_D2I_FP), "ASN1_d2i_fp"},
+	{ERR_FUNC(ASN1_F_ASN1_D2I_READ_BIO), "ASN1_D2I_READ_BIO"},
+	{ERR_FUNC(ASN1_F_ASN1_DIGEST), "ASN1_digest"},
+	{ERR_FUNC(ASN1_F_ASN1_DO_ADB), "ASN1_DO_ADB"},
+	{ERR_FUNC(ASN1_F_ASN1_DUP), "ASN1_dup"},
+	{ERR_FUNC(ASN1_F_ASN1_ENUMERATED_SET), "ASN1_ENUMERATED_set"},
+	{ERR_FUNC(ASN1_F_ASN1_ENUMERATED_TO_BN), "ASN1_ENUMERATED_to_BN"},
+	{ERR_FUNC(ASN1_F_ASN1_EX_C2I), "ASN1_EX_C2I"},
+	{ERR_FUNC(ASN1_F_ASN1_FIND_END), "ASN1_FIND_END"},
+	{ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_ADJ), "ASN1_GENERALIZEDTIME_adj"},
+	{ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_SET), "ASN1_GENERALIZEDTIME_set"},
+	{ERR_FUNC(ASN1_F_ASN1_GENERATE_V3), "ASN1_generate_v3"},
+	{ERR_FUNC(ASN1_F_ASN1_GET_OBJECT), "ASN1_get_object"},
+	{ERR_FUNC(ASN1_F_ASN1_HEADER_NEW), "ASN1_HEADER_NEW"},
+	{ERR_FUNC(ASN1_F_ASN1_I2D_BIO), "ASN1_i2d_bio"},
+	{ERR_FUNC(ASN1_F_ASN1_I2D_FP), "ASN1_i2d_fp"},
+	{ERR_FUNC(ASN1_F_ASN1_INTEGER_SET), "ASN1_INTEGER_set"},
+	{ERR_FUNC(ASN1_F_ASN1_INTEGER_TO_BN), "ASN1_INTEGER_to_BN"},
+	{ERR_FUNC(ASN1_F_ASN1_ITEM_D2I_FP), "ASN1_item_d2i_fp"},
+	{ERR_FUNC(ASN1_F_ASN1_ITEM_DUP), "ASN1_item_dup"},
+	{ERR_FUNC(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW), "ASN1_ITEM_EX_COMBINE_NEW"},
+	{ERR_FUNC(ASN1_F_ASN1_ITEM_EX_D2I), "ASN1_ITEM_EX_D2I"},
+	{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_BIO), "ASN1_item_i2d_bio"},
+	{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP), "ASN1_item_i2d_fp"},
+	{ERR_FUNC(ASN1_F_ASN1_ITEM_PACK), "ASN1_item_pack"},
+	{ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN), "ASN1_item_sign"},
+	{ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN_CTX), "ASN1_item_sign_ctx"},
+	{ERR_FUNC(ASN1_F_ASN1_ITEM_UNPACK), "ASN1_item_unpack"},
+	{ERR_FUNC(ASN1_F_ASN1_ITEM_VERIFY), "ASN1_item_verify"},
+	{ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY), "ASN1_mbstring_ncopy"},
+	{ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW), "ASN1_OBJECT_new"},
+	{ERR_FUNC(ASN1_F_ASN1_OUTPUT_DATA), "ASN1_OUTPUT_DATA"},
+	{ERR_FUNC(ASN1_F_ASN1_PACK_STRING), "ASN1_pack_string"},
+	{ERR_FUNC(ASN1_F_ASN1_PCTX_NEW), "ASN1_PCTX_new"},
+	{ERR_FUNC(ASN1_F_ASN1_PKCS5_PBE_SET), "ASN1_PKCS5_PBE_SET"},
+	{ERR_FUNC(ASN1_F_ASN1_SEQ_PACK), "ASN1_seq_pack"},
+	{ERR_FUNC(ASN1_F_ASN1_SEQ_UNPACK), "ASN1_seq_unpack"},
+	{ERR_FUNC(ASN1_F_ASN1_SIGN), "ASN1_sign"},
+	{ERR_FUNC(ASN1_F_ASN1_STR2TYPE), "ASN1_STR2TYPE"},
+	{ERR_FUNC(ASN1_F_ASN1_STRING_SET), "ASN1_STRING_set"},
+	{ERR_FUNC(ASN1_F_ASN1_STRING_TABLE_ADD), "ASN1_STRING_TABLE_add"},
+	{ERR_FUNC(ASN1_F_ASN1_STRING_TYPE_NEW), "ASN1_STRING_type_new"},
+	{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_EX_D2I), "ASN1_TEMPLATE_EX_D2I"},
+	{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NEW), "ASN1_TEMPLATE_NEW"},
+	{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I), "ASN1_TEMPLATE_NOEXP_D2I"},
+	{ERR_FUNC(ASN1_F_ASN1_TIME_ADJ), "ASN1_TIME_adj"},
+	{ERR_FUNC(ASN1_F_ASN1_TIME_SET), "ASN1_TIME_set"},
+	{ERR_FUNC(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING), "ASN1_TYPE_get_int_octetstring"},
+	{ERR_FUNC(ASN1_F_ASN1_TYPE_GET_OCTETSTRING), "ASN1_TYPE_get_octetstring"},
+	{ERR_FUNC(ASN1_F_ASN1_UNPACK_STRING), "ASN1_unpack_string"},
+	{ERR_FUNC(ASN1_F_ASN1_UTCTIME_ADJ), "ASN1_UTCTIME_adj"},
+	{ERR_FUNC(ASN1_F_ASN1_UTCTIME_SET), "ASN1_UTCTIME_set"},
+	{ERR_FUNC(ASN1_F_ASN1_VERIFY), "ASN1_verify"},
+	{ERR_FUNC(ASN1_F_B64_READ_ASN1), "B64_READ_ASN1"},
+	{ERR_FUNC(ASN1_F_B64_WRITE_ASN1), "B64_WRITE_ASN1"},
+	{ERR_FUNC(ASN1_F_BIO_NEW_NDEF), "BIO_new_NDEF"},
+	{ERR_FUNC(ASN1_F_BITSTR_CB), "BITSTR_CB"},
+	{ERR_FUNC(ASN1_F_BN_TO_ASN1_ENUMERATED), "BN_to_ASN1_ENUMERATED"},
+	{ERR_FUNC(ASN1_F_BN_TO_ASN1_INTEGER), "BN_to_ASN1_INTEGER"},
+	{ERR_FUNC(ASN1_F_C2I_ASN1_BIT_STRING), "c2i_ASN1_BIT_STRING"},
+	{ERR_FUNC(ASN1_F_C2I_ASN1_INTEGER), "c2i_ASN1_INTEGER"},
+	{ERR_FUNC(ASN1_F_C2I_ASN1_OBJECT), "c2i_ASN1_OBJECT"},
+	{ERR_FUNC(ASN1_F_COLLECT_DATA), "COLLECT_DATA"},
+	{ERR_FUNC(ASN1_F_D2I_ASN1_BIT_STRING), "D2I_ASN1_BIT_STRING"},
+	{ERR_FUNC(ASN1_F_D2I_ASN1_BOOLEAN), "d2i_ASN1_BOOLEAN"},
+	{ERR_FUNC(ASN1_F_D2I_ASN1_BYTES), "d2i_ASN1_bytes"},
+	{ERR_FUNC(ASN1_F_D2I_ASN1_GENERALIZEDTIME), "D2I_ASN1_GENERALIZEDTIME"},
+	{ERR_FUNC(ASN1_F_D2I_ASN1_HEADER), "D2I_ASN1_HEADER"},
+	{ERR_FUNC(ASN1_F_D2I_ASN1_INTEGER), "D2I_ASN1_INTEGER"},
+	{ERR_FUNC(ASN1_F_D2I_ASN1_OBJECT), "d2i_ASN1_OBJECT"},
+	{ERR_FUNC(ASN1_F_D2I_ASN1_SET), "d2i_ASN1_SET"},
+	{ERR_FUNC(ASN1_F_D2I_ASN1_TYPE_BYTES), "d2i_ASN1_type_bytes"},
+	{ERR_FUNC(ASN1_F_D2I_ASN1_UINTEGER), "d2i_ASN1_UINTEGER"},
+	{ERR_FUNC(ASN1_F_D2I_ASN1_UTCTIME), "D2I_ASN1_UTCTIME"},
+	{ERR_FUNC(ASN1_F_D2I_AUTOPRIVATEKEY), "d2i_AutoPrivateKey"},
+	{ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA), "d2i_Netscape_RSA"},
+	{ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA_2), "D2I_NETSCAPE_RSA_2"},
+	{ERR_FUNC(ASN1_F_D2I_PRIVATEKEY), "d2i_PrivateKey"},
+	{ERR_FUNC(ASN1_F_D2I_PUBLICKEY), "d2i_PublicKey"},
+	{ERR_FUNC(ASN1_F_D2I_RSA_NET), "d2i_RSA_NET"},
+	{ERR_FUNC(ASN1_F_D2I_RSA_NET_2), "D2I_RSA_NET_2"},
+	{ERR_FUNC(ASN1_F_D2I_X509), "D2I_X509"},
+	{ERR_FUNC(ASN1_F_D2I_X509_CINF), "D2I_X509_CINF"},
+	{ERR_FUNC(ASN1_F_D2I_X509_PKEY), "d2i_X509_PKEY"},
+	{ERR_FUNC(ASN1_F_I2D_ASN1_BIO_STREAM), "i2d_ASN1_bio_stream"},
+	{ERR_FUNC(ASN1_F_I2D_ASN1_SET), "i2d_ASN1_SET"},
+	{ERR_FUNC(ASN1_F_I2D_ASN1_TIME), "I2D_ASN1_TIME"},
+	{ERR_FUNC(ASN1_F_I2D_DSA_PUBKEY), "i2d_DSA_PUBKEY"},
+	{ERR_FUNC(ASN1_F_I2D_EC_PUBKEY), "i2d_EC_PUBKEY"},
+	{ERR_FUNC(ASN1_F_I2D_PRIVATEKEY), "i2d_PrivateKey"},
+	{ERR_FUNC(ASN1_F_I2D_PUBLICKEY), "i2d_PublicKey"},
+	{ERR_FUNC(ASN1_F_I2D_RSA_NET), "i2d_RSA_NET"},
+	{ERR_FUNC(ASN1_F_I2D_RSA_PUBKEY), "i2d_RSA_PUBKEY"},
+	{ERR_FUNC(ASN1_F_LONG_C2I), "LONG_C2I"},
+	{ERR_FUNC(ASN1_F_OID_MODULE_INIT), "OID_MODULE_INIT"},
+	{ERR_FUNC(ASN1_F_PARSE_TAGGING), "PARSE_TAGGING"},
+	{ERR_FUNC(ASN1_F_PKCS5_PBE2_SET_IV), "PKCS5_pbe2_set_iv"},
+	{ERR_FUNC(ASN1_F_PKCS5_PBE_SET), "PKCS5_pbe_set"},
+	{ERR_FUNC(ASN1_F_PKCS5_PBE_SET0_ALGOR), "PKCS5_pbe_set0_algor"},
+	{ERR_FUNC(ASN1_F_PKCS5_PBKDF2_SET), "PKCS5_pbkdf2_set"},
+	{ERR_FUNC(ASN1_F_SMIME_READ_ASN1), "SMIME_read_ASN1"},
+	{ERR_FUNC(ASN1_F_SMIME_TEXT), "SMIME_text"},
+	{ERR_FUNC(ASN1_F_X509_CINF_NEW), "X509_CINF_NEW"},
+	{ERR_FUNC(ASN1_F_X509_CRL_ADD0_REVOKED), "X509_CRL_add0_revoked"},
+	{ERR_FUNC(ASN1_F_X509_INFO_NEW), "X509_INFO_new"},
+	{ERR_FUNC(ASN1_F_X509_NAME_ENCODE), "X509_NAME_ENCODE"},
+	{ERR_FUNC(ASN1_F_X509_NAME_EX_D2I), "X509_NAME_EX_D2I"},
+	{ERR_FUNC(ASN1_F_X509_NAME_EX_NEW), "X509_NAME_EX_NEW"},
+	{ERR_FUNC(ASN1_F_X509_NEW), "X509_NEW"},
+	{ERR_FUNC(ASN1_F_X509_PKEY_NEW), "X509_PKEY_new"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA ASN1_str_reasons[] = {
+	{ERR_REASON(ASN1_R_ADDING_OBJECT)        , "adding object"},
+	{ERR_REASON(ASN1_R_ASN1_PARSE_ERROR)     , "asn1 parse error"},
+	{ERR_REASON(ASN1_R_ASN1_SIG_PARSE_ERROR) , "asn1 sig parse error"},
+	{ERR_REASON(ASN1_R_AUX_ERROR)            , "aux error"},
+	{ERR_REASON(ASN1_R_BAD_CLASS)            , "bad class"},
+	{ERR_REASON(ASN1_R_BAD_OBJECT_HEADER)    , "bad object header"},
+	{ERR_REASON(ASN1_R_BAD_PASSWORD_READ)    , "bad password read"},
+	{ERR_REASON(ASN1_R_BAD_TAG)              , "bad tag"},
+	{ERR_REASON(ASN1_R_BMPSTRING_IS_WRONG_LENGTH), "bmpstring is wrong length"},
+	{ERR_REASON(ASN1_R_BN_LIB)               , "bn lib"},
+	{ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH), "boolean is wrong length"},
+	{ERR_REASON(ASN1_R_BUFFER_TOO_SMALL)     , "buffer too small"},
+	{ERR_REASON(ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER), "cipher has no object identifier"},
+	{ERR_REASON(ASN1_R_CONTEXT_NOT_INITIALISED), "context not initialised"},
+	{ERR_REASON(ASN1_R_DATA_IS_WRONG)        , "data is wrong"},
+	{ERR_REASON(ASN1_R_DECODE_ERROR)         , "decode error"},
+	{ERR_REASON(ASN1_R_DECODING_ERROR)       , "decoding error"},
+	{ERR_REASON(ASN1_R_DEPTH_EXCEEDED)       , "depth exceeded"},
+	{ERR_REASON(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED), "digest and key type not supported"},
+	{ERR_REASON(ASN1_R_ENCODE_ERROR)         , "encode error"},
+	{ERR_REASON(ASN1_R_ERROR_GETTING_TIME)   , "error getting time"},
+	{ERR_REASON(ASN1_R_ERROR_LOADING_SECTION), "error loading section"},
+	{ERR_REASON(ASN1_R_ERROR_PARSING_SET_ELEMENT), "error parsing set element"},
+	{ERR_REASON(ASN1_R_ERROR_SETTING_CIPHER_PARAMS), "error setting cipher params"},
+	{ERR_REASON(ASN1_R_EXPECTING_AN_INTEGER) , "expecting an integer"},
+	{ERR_REASON(ASN1_R_EXPECTING_AN_OBJECT)  , "expecting an object"},
+	{ERR_REASON(ASN1_R_EXPECTING_A_BOOLEAN)  , "expecting a boolean"},
+	{ERR_REASON(ASN1_R_EXPECTING_A_TIME)     , "expecting a time"},
+	{ERR_REASON(ASN1_R_EXPLICIT_LENGTH_MISMATCH), "explicit length mismatch"},
+	{ERR_REASON(ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED), "explicit tag not constructed"},
+	{ERR_REASON(ASN1_R_FIELD_MISSING)        , "field missing"},
+	{ERR_REASON(ASN1_R_FIRST_NUM_TOO_LARGE)  , "first num too large"},
+	{ERR_REASON(ASN1_R_HEADER_TOO_LONG)      , "header too long"},
+	{ERR_REASON(ASN1_R_ILLEGAL_BITSTRING_FORMAT), "illegal bitstring format"},
+	{ERR_REASON(ASN1_R_ILLEGAL_BOOLEAN)      , "illegal boolean"},
+	{ERR_REASON(ASN1_R_ILLEGAL_CHARACTERS)   , "illegal characters"},
+	{ERR_REASON(ASN1_R_ILLEGAL_FORMAT)       , "illegal format"},
+	{ERR_REASON(ASN1_R_ILLEGAL_HEX)          , "illegal hex"},
+	{ERR_REASON(ASN1_R_ILLEGAL_IMPLICIT_TAG) , "illegal implicit tag"},
+	{ERR_REASON(ASN1_R_ILLEGAL_INTEGER)      , "illegal integer"},
+	{ERR_REASON(ASN1_R_ILLEGAL_NESTED_TAGGING), "illegal nested tagging"},
+	{ERR_REASON(ASN1_R_ILLEGAL_NULL)         , "illegal null"},
+	{ERR_REASON(ASN1_R_ILLEGAL_NULL_VALUE)   , "illegal null value"},
+	{ERR_REASON(ASN1_R_ILLEGAL_OBJECT)       , "illegal object"},
+	{ERR_REASON(ASN1_R_ILLEGAL_OPTIONAL_ANY) , "illegal optional any"},
+	{ERR_REASON(ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE), "illegal options on item template"},
+	{ERR_REASON(ASN1_R_ILLEGAL_TAGGED_ANY)   , "illegal tagged any"},
+	{ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE)   , "illegal time value"},
+	{ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT), "integer not ascii format"},
+	{ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG), "integer too large for long"},
+	{ERR_REASON(ASN1_R_INVALID_BIT_STRING_BITS_LEFT), "invalid bit string bits left"},
+	{ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH), "invalid bmpstring length"},
+	{ERR_REASON(ASN1_R_INVALID_DIGIT)        , "invalid digit"},
+	{ERR_REASON(ASN1_R_INVALID_MIME_TYPE)    , "invalid mime type"},
+	{ERR_REASON(ASN1_R_INVALID_MODIFIER)     , "invalid modifier"},
+	{ERR_REASON(ASN1_R_INVALID_NUMBER)       , "invalid number"},
+	{ERR_REASON(ASN1_R_INVALID_OBJECT_ENCODING), "invalid object encoding"},
+	{ERR_REASON(ASN1_R_INVALID_SEPARATOR)    , "invalid separator"},
+	{ERR_REASON(ASN1_R_INVALID_TIME_FORMAT)  , "invalid time format"},
+	{ERR_REASON(ASN1_R_INVALID_UNIVERSALSTRING_LENGTH), "invalid universalstring length"},
+	{ERR_REASON(ASN1_R_INVALID_UTF8STRING)   , "invalid utf8string"},
+	{ERR_REASON(ASN1_R_IV_TOO_LARGE)         , "iv too large"},
+	{ERR_REASON(ASN1_R_LENGTH_ERROR)         , "length error"},
+	{ERR_REASON(ASN1_R_LIST_ERROR)           , "list error"},
+	{ERR_REASON(ASN1_R_MIME_NO_CONTENT_TYPE) , "mime no content type"},
+	{ERR_REASON(ASN1_R_MIME_PARSE_ERROR)     , "mime parse error"},
+	{ERR_REASON(ASN1_R_MIME_SIG_PARSE_ERROR) , "mime sig parse error"},
+	{ERR_REASON(ASN1_R_MISSING_EOC)          , "missing eoc"},
+	{ERR_REASON(ASN1_R_MISSING_SECOND_NUMBER), "missing second number"},
+	{ERR_REASON(ASN1_R_MISSING_VALUE)        , "missing value"},
+	{ERR_REASON(ASN1_R_MSTRING_NOT_UNIVERSAL), "mstring not universal"},
+	{ERR_REASON(ASN1_R_MSTRING_WRONG_TAG)    , "mstring wrong tag"},
+	{ERR_REASON(ASN1_R_NESTED_ASN1_STRING)   , "nested asn1 string"},
+	{ERR_REASON(ASN1_R_NON_HEX_CHARACTERS)   , "non hex characters"},
+	{ERR_REASON(ASN1_R_NOT_ASCII_FORMAT)     , "not ascii format"},
+	{ERR_REASON(ASN1_R_NOT_ENOUGH_DATA)      , "not enough data"},
+	{ERR_REASON(ASN1_R_NO_CONTENT_TYPE)      , "no content type"},
+	{ERR_REASON(ASN1_R_NO_DEFAULT_DIGEST)    , "no default digest"},
+	{ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE), "no matching choice type"},
+	{ERR_REASON(ASN1_R_NO_MULTIPART_BODY_FAILURE), "no multipart body failure"},
+	{ERR_REASON(ASN1_R_NO_MULTIPART_BOUNDARY), "no multipart boundary"},
+	{ERR_REASON(ASN1_R_NO_SIG_CONTENT_TYPE)  , "no sig content type"},
+	{ERR_REASON(ASN1_R_NULL_IS_WRONG_LENGTH) , "null is wrong length"},
+	{ERR_REASON(ASN1_R_OBJECT_NOT_ASCII_FORMAT), "object not ascii format"},
+	{ERR_REASON(ASN1_R_ODD_NUMBER_OF_CHARS)  , "odd number of chars"},
+	{ERR_REASON(ASN1_R_PRIVATE_KEY_HEADER_MISSING), "private key header missing"},
+	{ERR_REASON(ASN1_R_SECOND_NUMBER_TOO_LARGE), "second number too large"},
+	{ERR_REASON(ASN1_R_SEQUENCE_LENGTH_MISMATCH), "sequence length mismatch"},
+	{ERR_REASON(ASN1_R_SEQUENCE_NOT_CONSTRUCTED), "sequence not constructed"},
+	{ERR_REASON(ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG), "sequence or set needs config"},
+	{ERR_REASON(ASN1_R_SHORT_LINE)           , "short line"},
+	{ERR_REASON(ASN1_R_SIG_INVALID_MIME_TYPE), "sig invalid mime type"},
+	{ERR_REASON(ASN1_R_STREAMING_NOT_SUPPORTED), "streaming not supported"},
+	{ERR_REASON(ASN1_R_STRING_TOO_LONG)      , "string too long"},
+	{ERR_REASON(ASN1_R_STRING_TOO_SHORT)     , "string too short"},
+	{ERR_REASON(ASN1_R_TAG_VALUE_TOO_HIGH)   , "tag value too high"},
+	{ERR_REASON(ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD), "the asn1 object identifier is not known for this md"},
+	{ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT), "time not ascii format"},
+	{ERR_REASON(ASN1_R_TOO_LONG)             , "too long"},
+	{ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED) , "type not constructed"},
+	{ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY), "unable to decode rsa key"},
+	{ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY), "unable to decode rsa private key"},
+	{ERR_REASON(ASN1_R_UNEXPECTED_EOC)       , "unexpected eoc"},
+	{ERR_REASON(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH), "universalstring is wrong length"},
+	{ERR_REASON(ASN1_R_UNKNOWN_FORMAT)       , "unknown format"},
+	{ERR_REASON(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM), "unknown message digest algorithm"},
+	{ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE)  , "unknown object type"},
+	{ERR_REASON(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE), "unknown public key type"},
+	{ERR_REASON(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM), "unknown signature algorithm"},
+	{ERR_REASON(ASN1_R_UNKNOWN_TAG)          , "unknown tag"},
+	{ERR_REASON(ASN1_R_UNKOWN_FORMAT)        , "unknown format"},
+	{ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE), "unsupported any defined by type"},
+	{ERR_REASON(ASN1_R_UNSUPPORTED_CIPHER)   , "unsupported cipher"},
+	{ERR_REASON(ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM), "unsupported encryption algorithm"},
+	{ERR_REASON(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE), "unsupported public key type"},
+	{ERR_REASON(ASN1_R_UNSUPPORTED_TYPE)     , "unsupported type"},
+	{ERR_REASON(ASN1_R_WRONG_PUBLIC_KEY_TYPE), "wrong public key type"},
+	{ERR_REASON(ASN1_R_WRONG_TAG)            , "wrong tag"},
+	{ERR_REASON(ASN1_R_WRONG_TYPE)           , "wrong type"},
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_ASN1_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(ASN1_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, ASN1_str_functs);
+		ERR_load_strings(0, ASN1_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/asn1/asn1_gen.c b/crypto/libressl/crypto/asn1/asn1_gen.c
new file mode 100644
index 0000000000..e2b568c841
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/asn1_gen.c
@@ -0,0 +1,811 @@
+/* $OpenBSD: asn1_gen.c,v 1.14 2015/07/18 14:40:59 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+#define ASN1_GEN_FLAG		0x10000
+#define ASN1_GEN_FLAG_IMP	(ASN1_GEN_FLAG|1)
+#define ASN1_GEN_FLAG_EXP	(ASN1_GEN_FLAG|2)
+#define ASN1_GEN_FLAG_TAG	(ASN1_GEN_FLAG|3)
+#define ASN1_GEN_FLAG_BITWRAP	(ASN1_GEN_FLAG|4)
+#define ASN1_GEN_FLAG_OCTWRAP	(ASN1_GEN_FLAG|5)
+#define ASN1_GEN_FLAG_SEQWRAP	(ASN1_GEN_FLAG|6)
+#define ASN1_GEN_FLAG_SETWRAP	(ASN1_GEN_FLAG|7)
+#define ASN1_GEN_FLAG_FORMAT	(ASN1_GEN_FLAG|8)
+
+#define ASN1_GEN_STR(str,val){str, sizeof(str) - 1, val}
+
+#define ASN1_FLAG_EXP_MAX	20
+
+/* Input formats */
+
+/* ASCII: default */
+#define ASN1_GEN_FORMAT_ASCII	1
+/* UTF8 */
+#define ASN1_GEN_FORMAT_UTF8	2
+/* Hex */
+#define ASN1_GEN_FORMAT_HEX	3
+/* List of bits */
+#define ASN1_GEN_FORMAT_BITLIST	4
+
+struct tag_name_st {
+	const char *strnam;
+	int len;
+	int tag;
+};
+
+typedef struct {
+	int exp_tag;
+	int exp_class;
+	int exp_constructed;
+	int exp_pad;
+	long exp_len;
+} tag_exp_type;
+
+typedef struct {
+	int imp_tag;
+	int imp_class;
+	int utype;
+	int format;
+	const char *str;
+	tag_exp_type exp_list[ASN1_FLAG_EXP_MAX];
+	int exp_count;
+} tag_exp_arg;
+
+static int bitstr_cb(const char *elem, int len, void *bitstr);
+static int asn1_cb(const char *elem, int len, void *bitstr);
+static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class,
+    int exp_constructed, int exp_pad, int imp_ok);
+static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass);
+static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf);
+static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype);
+static int asn1_str2tag(const char *tagstr, int len);
+
+ASN1_TYPE *
+ASN1_generate_nconf(char *str, CONF *nconf)
+{
+	X509V3_CTX cnf;
+
+	if (!nconf)
+		return ASN1_generate_v3(str, NULL);
+
+	X509V3_set_nconf(&cnf, nconf);
+	return ASN1_generate_v3(str, &cnf);
+}
+
+ASN1_TYPE *
+ASN1_generate_v3(char *str, X509V3_CTX *cnf)
+{
+	ASN1_TYPE *ret;
+	tag_exp_arg asn1_tags;
+	tag_exp_type *etmp;
+
+	int i, len;
+
+	unsigned char *orig_der = NULL, *new_der = NULL;
+	const unsigned char *cpy_start;
+	unsigned char *p;
+	const unsigned char *cp;
+	int cpy_len;
+	long hdr_len = 0;
+	int hdr_constructed = 0, hdr_tag, hdr_class;
+	int r;
+
+	asn1_tags.imp_tag = -1;
+	asn1_tags.imp_class = -1;
+	asn1_tags.format = ASN1_GEN_FORMAT_ASCII;
+	asn1_tags.exp_count = 0;
+	if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0)
+		return NULL;
+
+	if ((asn1_tags.utype == V_ASN1_SEQUENCE) ||
+	    (asn1_tags.utype == V_ASN1_SET)) {
+		if (!cnf) {
+			ASN1err(ASN1_F_ASN1_GENERATE_V3,
+			    ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
+			return NULL;
+		}
+		ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
+	} else
+		ret = asn1_str2type(asn1_tags.str, asn1_tags.format,
+		    asn1_tags.utype);
+
+	if (!ret)
+		return NULL;
+
+	/* If no tagging return base type */
+	if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0))
+		return ret;
+
+	/* Generate the encoding */
+	cpy_len = i2d_ASN1_TYPE(ret, &orig_der);
+	ASN1_TYPE_free(ret);
+	ret = NULL;
+	/* Set point to start copying for modified encoding */
+	cpy_start = orig_der;
+
+	/* Do we need IMPLICIT tagging? */
+	if (asn1_tags.imp_tag != -1) {
+		/* If IMPLICIT we will replace the underlying tag */
+		/* Skip existing tag+len */
+		r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag,
+		    &hdr_class, cpy_len);
+		if (r & 0x80)
+			goto err;
+		/* Update copy length */
+		cpy_len -= cpy_start - orig_der;
+		/* For IMPLICIT tagging the length should match the
+		 * original length and constructed flag should be
+		 * consistent.
+		 */
+		if (r & 0x1) {
+			/* Indefinite length constructed */
+			hdr_constructed = 2;
+			hdr_len = 0;
+		} else
+			/* Just retain constructed flag */
+			hdr_constructed = r & V_ASN1_CONSTRUCTED;
+		/* Work out new length with IMPLICIT tag: ignore constructed
+		 * because it will mess up if indefinite length
+		 */
+		len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag);
+	} else
+		len = cpy_len;
+
+	/* Work out length in any EXPLICIT, starting from end */
+
+	for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1;
+	    i < asn1_tags.exp_count; i++, etmp--) {
+		/* Content length: number of content octets + any padding */
+		len += etmp->exp_pad;
+		etmp->exp_len = len;
+		/* Total object length: length including new header */
+		len = ASN1_object_size(0, len, etmp->exp_tag);
+	}
+
+	/* Allocate buffer for new encoding */
+
+	new_der = malloc(len);
+	if (!new_der)
+		goto err;
+
+	/* Generate tagged encoding */
+	p = new_der;
+
+	/* Output explicit tags first */
+	for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count;
+	    i++, etmp++) {
+		ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len,
+		    etmp->exp_tag, etmp->exp_class);
+		if (etmp->exp_pad)
+			*p++ = 0;
+	}
+
+	/* If IMPLICIT, output tag */
+
+	if (asn1_tags.imp_tag != -1) {
+		if (asn1_tags.imp_class == V_ASN1_UNIVERSAL &&
+		    (asn1_tags.imp_tag == V_ASN1_SEQUENCE ||
+		    asn1_tags.imp_tag == V_ASN1_SET))
+			hdr_constructed = V_ASN1_CONSTRUCTED;
+		ASN1_put_object(&p, hdr_constructed, hdr_len,
+		    asn1_tags.imp_tag, asn1_tags.imp_class);
+	}
+
+	/* Copy across original encoding */
+	memcpy(p, cpy_start, cpy_len);
+
+	cp = new_der;
+
+	/* Obtain new ASN1_TYPE structure */
+	ret = d2i_ASN1_TYPE(NULL, &cp, len);
+
+err:
+	free(orig_der);
+	free(new_der);
+
+	return ret;
+}
+
+static int
+asn1_cb(const char *elem, int len, void *bitstr)
+{
+	tag_exp_arg *arg = bitstr;
+	int i;
+	int utype;
+	int vlen = 0;
+	const char *p, *vstart = NULL;
+
+	int tmp_tag, tmp_class;
+
+	for (i = 0, p = elem; i < len; p++, i++) {
+		/* Look for the ':' in name value pairs */
+		if (*p == ':') {
+			vstart = p + 1;
+			vlen = len - (vstart - elem);
+			len = p - elem;
+			break;
+		}
+	}
+
+	utype = asn1_str2tag(elem, len);
+
+	if (utype == -1) {
+		ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG);
+		ERR_asprintf_error_data("tag=%s", elem);
+		return -1;
+	}
+
+	/* If this is not a modifier mark end of string and exit */
+	if (!(utype & ASN1_GEN_FLAG)) {
+		arg->utype = utype;
+		arg->str = vstart;
+		/* If no value and not end of string, error */
+		if (!vstart && elem[len]) {
+			ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE);
+			return -1;
+		}
+		return 0;
+	}
+
+	switch (utype) {
+
+	case ASN1_GEN_FLAG_IMP:
+		/* Check for illegal multiple IMPLICIT tagging */
+		if (arg->imp_tag != -1) {
+			ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING);
+			return -1;
+		}
+		if (!parse_tagging(vstart, vlen, &arg->imp_tag,
+		    &arg->imp_class))
+			return -1;
+		break;
+
+	case ASN1_GEN_FLAG_EXP:
+		if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class))
+			return -1;
+		if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0))
+			return -1;
+		break;
+
+	case ASN1_GEN_FLAG_SEQWRAP:
+		if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1))
+			return -1;
+		break;
+
+	case ASN1_GEN_FLAG_SETWRAP:
+		if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1))
+			return -1;
+		break;
+
+	case ASN1_GEN_FLAG_BITWRAP:
+		if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1))
+			return -1;
+		break;
+
+	case ASN1_GEN_FLAG_OCTWRAP:
+		if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1))
+			return -1;
+		break;
+
+	case ASN1_GEN_FLAG_FORMAT:
+		if (vstart == NULL) {
+			ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_FORMAT);
+			return -1;
+		}
+		if (!strncmp(vstart, "ASCII", 5))
+			arg->format = ASN1_GEN_FORMAT_ASCII;
+		else if (!strncmp(vstart, "UTF8", 4))
+			arg->format = ASN1_GEN_FORMAT_UTF8;
+		else if (!strncmp(vstart, "HEX", 3))
+			arg->format = ASN1_GEN_FORMAT_HEX;
+		else if (!strncmp(vstart, "BITLIST", 7))
+			arg->format = ASN1_GEN_FORMAT_BITLIST;
+		else {
+			ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKOWN_FORMAT);
+			return -1;
+		}
+		break;
+
+	}
+
+	return 1;
+}
+
+static int
+parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
+{
+	long tag_num;
+	char *eptr;
+
+	if (!vstart)
+		return 0;
+	tag_num = strtoul(vstart, &eptr, 10);
+	/* Check we haven't gone past max length: should be impossible */
+	if (eptr && *eptr && (eptr > vstart + vlen))
+		return 0;
+	if (tag_num < 0) {
+		ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER);
+		return 0;
+	}
+	*ptag = tag_num;
+	/* If we have non numeric characters, parse them */
+	if (eptr)
+		vlen -= eptr - vstart;
+	else
+		vlen = 0;
+	if (vlen) {
+		switch (*eptr) {
+
+		case 'U':
+			*pclass = V_ASN1_UNIVERSAL;
+			break;
+
+		case 'A':
+			*pclass = V_ASN1_APPLICATION;
+			break;
+
+		case 'P':
+			*pclass = V_ASN1_PRIVATE;
+			break;
+
+		case 'C':
+			*pclass = V_ASN1_CONTEXT_SPECIFIC;
+			break;
+
+		default:
+			ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER);
+			ERR_asprintf_error_data("Char=%c", *eptr);
+			return 0;
+			break;
+
+		}
+	} else
+		*pclass = V_ASN1_CONTEXT_SPECIFIC;
+
+	return 1;
+
+}
+
+/* Handle multiple types: SET and SEQUENCE */
+
+static ASN1_TYPE *
+asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
+{
+	ASN1_TYPE *ret = NULL;
+	STACK_OF(ASN1_TYPE) *sk = NULL;
+	STACK_OF(CONF_VALUE) *sect = NULL;
+	unsigned char *der = NULL;
+	int derlen;
+	int i;
+	sk = sk_ASN1_TYPE_new_null();
+	if (!sk)
+		goto bad;
+	if (section) {
+		if (!cnf)
+			goto bad;
+		sect = X509V3_get_section(cnf, (char *)section);
+		if (!sect)
+			goto bad;
+		for (i = 0; i < sk_CONF_VALUE_num(sect); i++) {
+			ASN1_TYPE *typ = ASN1_generate_v3(
+			    sk_CONF_VALUE_value(sect, i)->value, cnf);
+			if (!typ)
+				goto bad;
+			if (!sk_ASN1_TYPE_push(sk, typ))
+				goto bad;
+		}
+	}
+
+	/* Now we has a STACK of the components, convert to the correct form */
+
+	if (utype == V_ASN1_SET)
+		derlen = i2d_ASN1_SET_ANY(sk, &der);
+	else
+		derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);
+
+	if (derlen < 0)
+		goto bad;
+
+	if (!(ret = ASN1_TYPE_new()))
+		goto bad;
+
+	if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype)))
+		goto bad;
+
+	ret->type = utype;
+
+	ret->value.asn1_string->data = der;
+	ret->value.asn1_string->length = derlen;
+
+	der = NULL;
+
+bad:
+	free(der);
+	if (sk)
+		sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
+	if (sect)
+		X509V3_section_free(cnf, sect);
+
+	return ret;
+}
+
+static int
+append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed,
+    int exp_pad, int imp_ok)
+{
+	tag_exp_type *exp_tmp;
+
+	/* Can only have IMPLICIT if permitted */
+	if ((arg->imp_tag != -1) && !imp_ok) {
+		ASN1err(ASN1_F_APPEND_EXP, ASN1_R_ILLEGAL_IMPLICIT_TAG);
+		return 0;
+	}
+
+	if (arg->exp_count == ASN1_FLAG_EXP_MAX) {
+		ASN1err(ASN1_F_APPEND_EXP, ASN1_R_DEPTH_EXCEEDED);
+		return 0;
+	}
+
+	exp_tmp = &arg->exp_list[arg->exp_count++];
+
+	/* If IMPLICIT set tag to implicit value then
+	 * reset implicit tag since it has been used.
+	 */
+	if (arg->imp_tag != -1) {
+		exp_tmp->exp_tag = arg->imp_tag;
+		exp_tmp->exp_class = arg->imp_class;
+		arg->imp_tag = -1;
+		arg->imp_class = -1;
+	} else {
+		exp_tmp->exp_tag = exp_tag;
+		exp_tmp->exp_class = exp_class;
+	}
+	exp_tmp->exp_constructed = exp_constructed;
+	exp_tmp->exp_pad = exp_pad;
+
+	return 1;
+}
+
+static int
+asn1_str2tag(const char *tagstr, int len)
+{
+	unsigned int i;
+	static const struct tag_name_st *tntmp, tnst [] = {
+		ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN),
+		ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN),
+		ASN1_GEN_STR("NULL", V_ASN1_NULL),
+		ASN1_GEN_STR("INT", V_ASN1_INTEGER),
+		ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER),
+		ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED),
+		ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED),
+		ASN1_GEN_STR("OID", V_ASN1_OBJECT),
+		ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT),
+		ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME),
+		ASN1_GEN_STR("UTC", V_ASN1_UTCTIME),
+		ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME),
+		ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME),
+		ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING),
+		ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING),
+		ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING),
+		ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING),
+		ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING),
+		ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING),
+		ASN1_GEN_STR("IA5", V_ASN1_IA5STRING),
+		ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING),
+		ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING),
+		ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING),
+		ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING),
+		ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING),
+		ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING),
+		ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING),
+		ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING),
+		ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING),
+		ASN1_GEN_STR("T61", V_ASN1_T61STRING),
+		ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING),
+		ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING),
+		ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING),
+		ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING),
+		ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING),
+		ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING),
+
+		/* Special cases */
+		ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE),
+		ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE),
+		ASN1_GEN_STR("SET", V_ASN1_SET),
+		/* type modifiers */
+		/* Explicit tag */
+		ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP),
+		ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP),
+		/* Implicit tag */
+		ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP),
+		ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP),
+		/* OCTET STRING wrapper */
+		ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP),
+		/* SEQUENCE wrapper */
+		ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP),
+		/* SET wrapper */
+		ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP),
+		/* BIT STRING wrapper */
+		ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP),
+		ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT),
+		ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT),
+	};
+
+	if (len == -1)
+		len = strlen(tagstr);
+
+	tntmp = tnst;
+	for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st);
+	    i++, tntmp++) {
+		if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len))
+			return tntmp->tag;
+	}
+
+	return -1;
+}
+
+static ASN1_TYPE *
+asn1_str2type(const char *str, int format, int utype)
+{
+	ASN1_TYPE *atmp = NULL;
+	CONF_VALUE vtmp;
+	unsigned char *rdata;
+	long rdlen;
+	int no_unused = 1;
+
+	if (!(atmp = ASN1_TYPE_new())) {
+		ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+
+	if (!str)
+		str = "";
+
+	switch (utype) {
+
+	case V_ASN1_NULL:
+		if (str && *str) {
+			ASN1err(ASN1_F_ASN1_STR2TYPE,
+			    ASN1_R_ILLEGAL_NULL_VALUE);
+			goto bad_form;
+		}
+		break;
+
+	case V_ASN1_BOOLEAN:
+		if (format != ASN1_GEN_FORMAT_ASCII) {
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT);
+			goto bad_form;
+		}
+		vtmp.name = NULL;
+		vtmp.section = NULL;
+		vtmp.value = (char *)str;
+		if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) {
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN);
+			goto bad_str;
+		}
+		break;
+
+	case V_ASN1_INTEGER:
+	case V_ASN1_ENUMERATED:
+		if (format != ASN1_GEN_FORMAT_ASCII) {
+			ASN1err(ASN1_F_ASN1_STR2TYPE,
+			    ASN1_R_INTEGER_NOT_ASCII_FORMAT);
+			goto bad_form;
+		}
+		if (!(atmp->value.integer =
+		    s2i_ASN1_INTEGER(NULL, (char *)str))) {
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER);
+			goto bad_str;
+		}
+		break;
+
+	case V_ASN1_OBJECT:
+		if (format != ASN1_GEN_FORMAT_ASCII) {
+			ASN1err(ASN1_F_ASN1_STR2TYPE,
+			    ASN1_R_OBJECT_NOT_ASCII_FORMAT);
+			goto bad_form;
+		}
+		if (!(atmp->value.object = OBJ_txt2obj(str, 0))) {
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT);
+			goto bad_str;
+		}
+		break;
+
+	case V_ASN1_UTCTIME:
+	case V_ASN1_GENERALIZEDTIME:
+		if (format != ASN1_GEN_FORMAT_ASCII) {
+			ASN1err(ASN1_F_ASN1_STR2TYPE,
+			    ASN1_R_TIME_NOT_ASCII_FORMAT);
+			goto bad_form;
+		}
+		if (!(atmp->value.asn1_string = ASN1_STRING_new())) {
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+			goto bad_str;
+		}
+		if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) {
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+			goto bad_str;
+		}
+		atmp->value.asn1_string->type = utype;
+		if (!ASN1_TIME_check(atmp->value.asn1_string)) {
+			ASN1err(ASN1_F_ASN1_STR2TYPE,
+			    ASN1_R_ILLEGAL_TIME_VALUE);
+			goto bad_str;
+		}
+		break;
+
+	case V_ASN1_BMPSTRING:
+	case V_ASN1_PRINTABLESTRING:
+	case V_ASN1_IA5STRING:
+	case V_ASN1_T61STRING:
+	case V_ASN1_UTF8STRING:
+	case V_ASN1_VISIBLESTRING:
+	case V_ASN1_UNIVERSALSTRING:
+	case V_ASN1_GENERALSTRING:
+	case V_ASN1_NUMERICSTRING:
+
+		if (format == ASN1_GEN_FORMAT_ASCII)
+			format = MBSTRING_ASC;
+		else if (format == ASN1_GEN_FORMAT_UTF8)
+			format = MBSTRING_UTF8;
+		else {
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT);
+			goto bad_form;
+		}
+
+		if (ASN1_mbstring_copy(&atmp->value.asn1_string,
+		    (unsigned char *)str, -1, format,
+		    ASN1_tag2bit(utype)) <= 0) {
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+			goto bad_str;
+		}
+		break;
+
+	case V_ASN1_BIT_STRING:
+	case V_ASN1_OCTET_STRING:
+		if (!(atmp->value.asn1_string = ASN1_STRING_new())) {
+			ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+			goto bad_form;
+		}
+
+		if (format == ASN1_GEN_FORMAT_HEX) {
+
+			if (!(rdata = string_to_hex((char *)str, &rdlen))) {
+				ASN1err(ASN1_F_ASN1_STR2TYPE,
+				    ASN1_R_ILLEGAL_HEX);
+				goto bad_str;
+			}
+
+			atmp->value.asn1_string->data = rdata;
+			atmp->value.asn1_string->length = rdlen;
+			atmp->value.asn1_string->type = utype;
+
+		} else if (format == ASN1_GEN_FORMAT_ASCII) {
+			if (ASN1_STRING_set(atmp->value.asn1_string, str,
+			    -1) == 0) {
+				ASN1err(ASN1_F_ASN1_STR2TYPE,
+				    ERR_R_MALLOC_FAILURE);
+				goto bad_str;
+			}
+		} else if ((format == ASN1_GEN_FORMAT_BITLIST) &&
+		    (utype == V_ASN1_BIT_STRING)) {
+			if (!CONF_parse_list(str, ',', 1, bitstr_cb,
+			    atmp->value.bit_string)) {
+				ASN1err(ASN1_F_ASN1_STR2TYPE,
+				    ASN1_R_LIST_ERROR);
+				goto bad_str;
+			}
+			no_unused = 0;
+
+		} else {
+			ASN1err(ASN1_F_ASN1_STR2TYPE,
+			    ASN1_R_ILLEGAL_BITSTRING_FORMAT);
+			goto bad_form;
+		}
+
+		if ((utype == V_ASN1_BIT_STRING) && no_unused) {
+			atmp->value.asn1_string->flags &=
+			    ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+			atmp->value.asn1_string->flags |=
+			    ASN1_STRING_FLAG_BITS_LEFT;
+		}
+
+		break;
+
+	default:
+		ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE);
+		goto bad_str;
+		break;
+	}
+
+	atmp->type = utype;
+	return atmp;
+
+bad_str:
+	ERR_asprintf_error_data("string=%s", str);
+bad_form:
+	ASN1_TYPE_free(atmp);
+	return NULL;
+}
+
+static int
+bitstr_cb(const char *elem, int len, void *bitstr)
+{
+	long bitnum;
+	char *eptr;
+
+	if (!elem)
+		return 0;
+	bitnum = strtoul(elem, &eptr, 10);
+	if (eptr && *eptr && (eptr != elem + len))
+		return 0;
+	if (bitnum < 0) {
+		ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER);
+		return 0;
+	}
+	if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) {
+		ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	return 1;
+}
diff --git a/crypto/libressl/crypto/asn1/asn1_lib.c b/crypto/libressl/crypto/asn1/asn1_lib.c
new file mode 100644
index 0000000000..9add84e61d
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/asn1_lib.c
@@ -0,0 +1,490 @@
+/* $OpenBSD: asn1_lib.c,v 1.36 2015/07/29 14:53:20 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, int max);
+static void asn1_put_length(unsigned char **pp, int length);
+
+static int
+_asn1_check_infinite_end(const unsigned char **p, long len)
+{
+	/* If there is 0 or 1 byte left, the length check should pick
+	 * things up */
+	if (len <= 0)
+		return (1);
+	else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) {
+		(*p) += 2;
+		return (1);
+	}
+	return (0);
+}
+
+int
+ASN1_check_infinite_end(unsigned char **p, long len)
+{
+	return _asn1_check_infinite_end((const unsigned char **)p, len);
+}
+
+int
+ASN1_const_check_infinite_end(const unsigned char **p, long len)
+{
+	return _asn1_check_infinite_end(p, len);
+}
+
+int
+ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
+    int *pclass, long omax)
+{
+	int i, ret;
+	long l;
+	const unsigned char *p= *pp;
+	int tag, xclass, inf;
+	long max = omax;
+
+	if (!max)
+		goto err;
+	ret = (*p & V_ASN1_CONSTRUCTED);
+	xclass = (*p & V_ASN1_PRIVATE);
+	i= *p & V_ASN1_PRIMITIVE_TAG;
+	if (i == V_ASN1_PRIMITIVE_TAG) {		/* high-tag */
+		p++;
+		if (--max == 0)
+			goto err;
+		l = 0;
+		while (*p & 0x80) {
+			l <<= 7L;
+			l |= *(p++) & 0x7f;
+			if (--max == 0)
+				goto err;
+			if (l > (INT_MAX >> 7L))
+				goto err;
+		}
+		l <<= 7L;
+		l |= *(p++) & 0x7f;
+		tag = (int)l;
+		if (--max == 0)
+			goto err;
+	} else {
+		tag = i;
+		p++;
+		if (--max == 0)
+			goto err;
+	}
+	*ptag = tag;
+	*pclass = xclass;
+	if (!asn1_get_length(&p, &inf, plength, (int)max))
+		goto err;
+
+	if (inf && !(ret & V_ASN1_CONSTRUCTED))
+		goto err;
+
+	if (*plength > (omax - (p - *pp))) {
+		ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_TOO_LONG);
+		/* Set this so that even if things are not long enough
+		 * the values are set correctly */
+		ret |= 0x80;
+	}
+	*pp = p;
+	return (ret | inf);
+
+err:
+	ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_HEADER_TOO_LONG);
+	return (0x80);
+}
+
+static int
+asn1_get_length(const unsigned char **pp, int *inf, long *rl, int max)
+{
+	const unsigned char *p= *pp;
+	unsigned long ret = 0;
+	unsigned int i;
+
+	if (max-- < 1)
+		return (0);
+	if (*p == 0x80) {
+		*inf = 1;
+		ret = 0;
+		p++;
+	} else {
+		*inf = 0;
+		i= *p & 0x7f;
+		if (*(p++) & 0x80) {
+			if (max < (int)i)
+				return (0);
+			/* skip leading zeroes */
+			while (i && *p == 0) {
+				p++;
+				i--;
+			}
+			if (i > sizeof(long))
+				return 0;
+			while (i-- > 0) {
+				ret <<= 8L;
+				ret |= *(p++);
+			}
+		} else
+			ret = i;
+	}
+	if (ret > LONG_MAX)
+		return 0;
+	*pp = p;
+	*rl = (long)ret;
+	return (1);
+}
+
+/* class 0 is constructed
+ * constructed == 2 for indefinite length constructed */
+void
+ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
+    int xclass)
+{
+	unsigned char *p= *pp;
+	int i, ttag;
+
+	i = (constructed) ? V_ASN1_CONSTRUCTED : 0;
+	i |= (xclass & V_ASN1_PRIVATE);
+	if (tag < 31)
+		*(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG);
+	else {
+		*(p++) = i | V_ASN1_PRIMITIVE_TAG;
+		for(i = 0, ttag = tag; ttag > 0; i++)
+			ttag >>= 7;
+		ttag = i;
+		while (i-- > 0) {
+			p[i] = tag & 0x7f;
+			if (i != (ttag - 1))
+				p[i] |= 0x80;
+			tag >>= 7;
+		}
+		p += ttag;
+	}
+	if (constructed == 2)
+		*(p++) = 0x80;
+	else
+		asn1_put_length(&p, length);
+	*pp = p;
+}
+
+int
+ASN1_put_eoc(unsigned char **pp)
+{
+	unsigned char *p = *pp;
+
+	*p++ = 0;
+	*p++ = 0;
+	*pp = p;
+	return 2;
+}
+
+static void
+asn1_put_length(unsigned char **pp, int length)
+{
+	unsigned char *p= *pp;
+
+	int i, l;
+	if (length <= 127)
+		*(p++) = (unsigned char)length;
+	else {
+		l = length;
+		for (i = 0; l > 0; i++)
+			l >>= 8;
+		*(p++) = i | 0x80;
+		l = i;
+		while (i-- > 0) {
+			p[i] = length & 0xff;
+			length >>= 8;
+		}
+		p += l;
+	}
+	*pp = p;
+}
+
+int
+ASN1_object_size(int constructed, int length, int tag)
+{
+	int ret;
+
+	ret = length;
+	ret++;
+	if (tag >= 31) {
+		while (tag > 0) {
+			tag >>= 7;
+			ret++;
+		}
+	}
+	if (constructed == 2)
+		return ret + 3;
+	ret++;
+	if (length > 127) {
+		while (length > 0) {
+			length >>= 8;
+			ret++;
+		}
+	}
+	return (ret);
+}
+
+static int
+_asn1_Finish(ASN1_const_CTX *c)
+{
+	if ((c->inf == (1|V_ASN1_CONSTRUCTED)) && (!c->eos)) {
+		if (!ASN1_const_check_infinite_end(&c->p, c->slen)) {
+			c->error = ERR_R_MISSING_ASN1_EOS;
+			return (0);
+		}
+	}
+	if (((c->slen != 0) && !(c->inf & 1)) ||
+	    ((c->slen < 0) && (c->inf & 1))) {
+		c->error = ERR_R_ASN1_LENGTH_MISMATCH;
+		return (0);
+	}
+	return (1);
+}
+
+int
+asn1_Finish(ASN1_CTX *c)
+{
+	return _asn1_Finish((ASN1_const_CTX *)c);
+}
+
+int
+asn1_const_Finish(ASN1_const_CTX *c)
+{
+	return _asn1_Finish(c);
+}
+
+int
+asn1_GetSequence(ASN1_const_CTX *c, long *length)
+{
+	const unsigned char *q;
+
+	q = c->p;
+	c->inf = ASN1_get_object(&(c->p), &(c->slen), &(c->tag), &(c->xclass),
+	    *length);
+	if (c->inf & 0x80) {
+		c->error = ERR_R_BAD_GET_ASN1_OBJECT_CALL;
+		return (0);
+	}
+	if (c->tag != V_ASN1_SEQUENCE) {
+		c->error = ERR_R_EXPECTING_AN_ASN1_SEQUENCE;
+		return (0);
+	}
+	(*length) -= (c->p - q);
+	if (c->max && (*length < 0)) {
+		c->error = ERR_R_ASN1_LENGTH_MISMATCH;
+		return (0);
+	}
+	if (c->inf == (1|V_ASN1_CONSTRUCTED))
+		c->slen= *length+ *(c->pp) - c->p;
+	c->eos = 0;
+	return (1);
+}
+
+int
+ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
+{
+	if (str == NULL)
+		return 0;
+	dst->type = str->type;
+	if (!ASN1_STRING_set(dst, str->data, str->length))
+		return 0;
+	dst->flags = str->flags;
+	return 1;
+}
+
+ASN1_STRING *
+ASN1_STRING_dup(const ASN1_STRING *str)
+{
+	ASN1_STRING *ret;
+
+	if (!str)
+		return NULL;
+	ret = ASN1_STRING_new();
+	if (!ret)
+		return NULL;
+	if (!ASN1_STRING_copy(ret, str)) {
+		ASN1_STRING_free(ret);
+		return NULL;
+	}
+	return ret;
+}
+
+int
+ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
+{
+	const char *data = _data;
+
+	if (len < 0) {
+		if (data == NULL)
+			return (0);
+		else
+			len = strlen(data);
+	}
+	if ((str->length < len) || (str->data == NULL)) {
+		unsigned char *tmp;
+		tmp = realloc(str->data, len + 1);
+		if (tmp == NULL) {
+			ASN1err(ASN1_F_ASN1_STRING_SET, ERR_R_MALLOC_FAILURE);
+			return (0);
+		}
+		str->data = tmp;
+	}
+	str->length = len;
+	if (data != NULL) {
+		memmove(str->data, data, len);
+	}
+	str->data[str->length]='\0';
+	return (1);
+}
+
+void
+ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
+{
+	if (str->data != NULL)
+		explicit_bzero(str->data, str->length);
+	free(str->data);
+	str->data = data;
+	str->length = len;
+}
+
+ASN1_STRING *
+ASN1_STRING_new(void)
+{
+	return (ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
+}
+
+ASN1_STRING *
+ASN1_STRING_type_new(int type)
+{
+	ASN1_STRING *ret;
+
+	ret = malloc(sizeof(ASN1_STRING));
+	if (ret == NULL) {
+		ASN1err(ASN1_F_ASN1_STRING_TYPE_NEW, ERR_R_MALLOC_FAILURE);
+		return (NULL);
+	}
+	ret->length = 0;
+	ret->type = type;
+	ret->data = NULL;
+	ret->flags = 0;
+	return (ret);
+}
+
+void
+ASN1_STRING_free(ASN1_STRING *a)
+{
+	if (a == NULL)
+		return;
+	if (a->data != NULL && !(a->flags & ASN1_STRING_FLAG_NDEF)) {
+		explicit_bzero(a->data, a->length);
+		free(a->data);
+	}
+	free(a);
+}
+
+int
+ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
+{
+	int i;
+
+	i = (a->length - b->length);
+	if (i == 0) {
+		i = memcmp(a->data, b->data, a->length);
+		if (i == 0)
+			return (a->type - b->type);
+		else
+			return (i);
+	} else
+		return (i);
+}
+
+void
+asn1_add_error(const unsigned char *address, int offset)
+{
+	ERR_asprintf_error_data("offset=%d", offset);
+}
+
+int
+ASN1_STRING_length(const ASN1_STRING *x)
+{
+	return (x->length);
+}
+
+void
+ASN1_STRING_length_set(ASN1_STRING *x, int len)
+{
+	x->length = len;
+}
+
+int
+ASN1_STRING_type(ASN1_STRING *x)
+{
+	return (x->type);
+}
+
+unsigned char *
+ASN1_STRING_data(ASN1_STRING *x)
+{
+	return (x->data);
+}
diff --git a/crypto/libressl/crypto/asn1/asn1_locl.h b/crypto/libressl/crypto/asn1/asn1_locl.h
new file mode 100644
index 0000000000..350407c250
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/asn1_locl.h
@@ -0,0 +1,151 @@
+/* $OpenBSD: asn1_locl.h,v 1.6 2015/10/02 15:04:45 beck Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Internal ASN1 structures and functions: not for application use */
+
+/* ASN1 print context structure */
+
+struct asn1_pctx_st {
+	unsigned long flags;
+	unsigned long nm_flags;
+	unsigned long cert_flags;
+	unsigned long oid_flags;
+	unsigned long str_flags;
+} /* ASN1_PCTX */;
+
+/* ASN1 public key method structure */
+
+struct evp_pkey_asn1_method_st {
+	int pkey_id;
+	int pkey_base_id;
+	unsigned long pkey_flags;
+
+	char *pem_str;
+	char *info;
+
+	int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub);
+	int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk);
+	int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
+	int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+	    ASN1_PCTX *pctx);
+
+	int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf);
+	int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk);
+	int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+	    ASN1_PCTX *pctx);
+
+	int (*pkey_size)(const EVP_PKEY *pk);
+	int (*pkey_bits)(const EVP_PKEY *pk);
+
+	int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder,
+	    int derlen);
+	int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder);
+	int (*param_missing)(const EVP_PKEY *pk);
+	int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from);
+	int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
+	int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+	    ASN1_PCTX *pctx);
+	int (*sig_print)(BIO *out, const X509_ALGOR *sigalg,
+	    const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx);
+
+	void (*pkey_free)(EVP_PKEY *pkey);
+	int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2);
+
+	/* Legacy functions for old PEM */
+
+	int (*old_priv_decode)(EVP_PKEY *pkey, const unsigned char **pder,
+	    int derlen);
+	int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder);
+	/* Custom ASN1 signature verification */
+	int (*item_verify)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+	    X509_ALGOR *a, ASN1_BIT_STRING *sig, EVP_PKEY *pkey);
+	int (*item_sign)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+	    X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig);
+
+} /* EVP_PKEY_ASN1_METHOD */;
+
+/* Method to handle CRL access.
+ * In general a CRL could be very large (several Mb) and can consume large
+ * amounts of resources if stored in memory by multiple processes.
+ * This method allows general CRL operations to be redirected to more
+ * efficient callbacks: for example a CRL entry database.
+ */
+
+#define X509_CRL_METHOD_DYNAMIC		1
+
+struct x509_crl_method_st {
+	int flags;
+	int (*crl_init)(X509_CRL *crl);
+	int (*crl_free)(X509_CRL *crl);
+	int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
+	    ASN1_INTEGER *ser, X509_NAME *issuer);
+	int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk);
+};
+
+/*
+ * Unicode codepoint constants
+ */
+#define	UNICODE_MAX		0x10FFFF
+#define	UNICODE_SURROGATE_MIN	0x00D800
+#define	UNICODE_SURROGATE_MAX	0x00DFFF
+
+#define	UNICODE_IS_SURROGATE(x) \
+	((x) >= UNICODE_SURROGATE_MIN && (x) <= UNICODE_SURROGATE_MAX)
+
+int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
+int UTF8_putc(unsigned char *str, int len, unsigned long value);
diff --git a/crypto/libressl/crypto/asn1/asn1_par.c b/crypto/libressl/crypto/asn1/asn1_par.c
new file mode 100644
index 0000000000..07935771c8
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/asn1_par.c
@@ -0,0 +1,397 @@
+/* $OpenBSD: asn1_par.c,v 1.24 2015/09/30 18:41:06 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
+    int indent);
+static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
+    int offset, int depth, int indent, int dump);
+
+static int
+asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
+    int indent)
+{
+	char str[128];
+	const char *p;
+
+	if (constructed & V_ASN1_CONSTRUCTED)
+		p="cons: ";
+	else
+		p="prim: ";
+	if (BIO_write(bp, p, 6) < 6)
+		goto err;
+	BIO_indent(bp, indent, 128);
+
+	p = str;
+	if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
+		snprintf(str, sizeof str, "priv [ %d ] ", tag);
+	else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
+		snprintf(str, sizeof str, "cont [ %d ]", tag);
+	else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
+		snprintf(str, sizeof str, "appl [ %d ]", tag);
+	else if (tag > 30)
+		snprintf(str, sizeof str, "", tag);
+	else
+		p = ASN1_tag2str(tag);
+
+	if (BIO_printf(bp, "%-18s", p) <= 0)
+		goto err;
+	return (1);
+err:
+	return (0);
+}
+
+int
+ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent)
+{
+	return (asn1_parse2(bp, &pp, len, 0, 0, indent, 0));
+}
+
+int
+ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, int dump)
+{
+	return (asn1_parse2(bp, &pp, len, 0, 0, indent, dump));
+}
+
+static int
+asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset,
+    int depth, int indent, int dump)
+{
+	const unsigned char *p, *ep, *tot, *op, *opp;
+	long len;
+	int tag, xclass, ret = 0;
+	int nl, hl, j, r;
+	ASN1_OBJECT *o = NULL;
+	ASN1_OCTET_STRING *os = NULL;
+	/* ASN1_BMPSTRING *bmp=NULL;*/
+	int dump_indent;
+
+	dump_indent = 6;	/* Because we know BIO_dump_indent() */
+	p = *pp;
+	tot = p + length;
+	op = p - 1;
+	while ((p < tot) && (op < p)) {
+		op = p;
+		j = ASN1_get_object(&p, &len, &tag, &xclass, length);
+
+		if (j & 0x80) {
+			if (BIO_write(bp, "Error in encoding\n", 18) <= 0)
+				goto end;
+			ret = 0;
+			goto end;
+		}
+		hl = (p - op);
+		length -= hl;
+		/* if j == 0x21 it is a constructed indefinite length object */
+		if (BIO_printf(bp, "%5ld:", (long)offset +
+		    (long)(op - *pp)) <= 0)
+		    goto end;
+
+		if (j != (V_ASN1_CONSTRUCTED | 1)) {
+			if (BIO_printf(bp, "d=%-2d hl=%ld l=%4ld ",
+			    depth, (long)hl, len) <= 0)
+				goto end;
+		} else {
+			if (BIO_printf(bp, "d=%-2d hl=%ld l=inf  ",
+			    depth, (long)hl) <= 0)
+				goto end;
+		}
+		if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0))
+			goto end;
+		if (j & V_ASN1_CONSTRUCTED) {
+			ep = p + len;
+			if (BIO_write(bp, "\n", 1) <= 0)
+				goto end;
+			if (len > length) {
+				BIO_printf(bp, "length is greater than %ld\n",
+				    length);
+				ret = 0;
+				goto end;
+			}
+			if ((j == 0x21) && (len == 0)) {
+				for (;;) {
+					r = asn1_parse2(bp, &p, (long)(tot - p),
+					    offset + (p - *pp), depth + 1,
+					    indent, dump);
+					if (r == 0) {
+						ret = 0;
+						goto end;
+					}
+					if ((r == 2) || (p >= tot))
+						break;
+				}
+			} else
+				while (p < ep) {
+					r = asn1_parse2(bp, &p, (long)len,
+					    offset + (p - *pp), depth + 1,
+					    indent, dump);
+					if (r == 0) {
+						ret = 0;
+						goto end;
+					}
+				}
+		} else if (xclass != 0) {
+			p += len;
+			if (BIO_write(bp, "\n", 1) <= 0)
+				goto end;
+		} else {
+			nl = 0;
+			if ((tag == V_ASN1_PRINTABLESTRING) ||
+			    (tag == V_ASN1_T61STRING) ||
+			    (tag == V_ASN1_IA5STRING) ||
+			    (tag == V_ASN1_VISIBLESTRING) ||
+			    (tag == V_ASN1_NUMERICSTRING) ||
+			    (tag == V_ASN1_UTF8STRING) ||
+			    (tag == V_ASN1_UTCTIME) ||
+			    (tag == V_ASN1_GENERALIZEDTIME)) {
+				if (BIO_write(bp, ":", 1) <= 0)
+					goto end;
+				if ((len > 0) &&
+				    BIO_write(bp, (const char *)p, (int)len) !=
+				    (int)len)
+					goto end;
+			} else if (tag == V_ASN1_OBJECT) {
+				opp = op;
+				if (d2i_ASN1_OBJECT(&o, &opp, len + hl) !=
+				    NULL) {
+					if (BIO_write(bp, ":", 1) <= 0)
+						goto end;
+					i2a_ASN1_OBJECT(bp, o);
+				} else {
+					if (BIO_write(bp, ":BAD OBJECT",
+					    11) <= 0)
+						goto end;
+				}
+			} else if (tag == V_ASN1_BOOLEAN) {
+				int ii;
+
+				opp = op;
+				ii = d2i_ASN1_BOOLEAN(NULL, &opp, len + hl);
+				if (ii < 0) {
+					if (BIO_write(bp, "Bad boolean\n",
+					    12) <= 0)
+						goto end;
+				}
+				BIO_printf(bp, ":%d", ii);
+			} else if (tag == V_ASN1_BMPSTRING) {
+				/* do the BMP thang */
+			} else if (tag == V_ASN1_OCTET_STRING) {
+				int i, printable = 1;
+
+				opp = op;
+				os = d2i_ASN1_OCTET_STRING(NULL, &opp, len + hl);
+				if (os != NULL && os->length > 0) {
+					opp = os->data;
+					/* testing whether the octet string is
+					 * printable */
+					for (i = 0; i < os->length; i++) {
+						if (((opp[i] < ' ') &&
+						    (opp[i] != '\n') &&
+						    (opp[i] != '\r') &&
+						    (opp[i] != '\t')) ||
+						    (opp[i] > '~')) {
+							printable = 0;
+							break;
+						}
+					}
+					if (printable) {
+						/* printable string */
+						if (BIO_write(bp, ":", 1) <= 0)
+							goto end;
+						if (BIO_write(bp, (const char *)opp,
+							    os->length) <= 0)
+							goto end;
+					} else if (!dump) {
+						/* not printable => print octet string
+						 * as hex dump */
+						if (BIO_write(bp, "[HEX DUMP]:", 11) <= 0)
+							goto end;
+						for (i = 0; i < os->length; i++) {
+							if (BIO_printf(bp,
+							    "%02X", opp[i]) <= 0)
+								goto end;
+						}
+					} else {
+						/* print the normal dump */
+						if (!nl) {
+							if (BIO_write(bp, "\n", 1) <= 0)
+								goto end;
+						}
+						if (BIO_dump_indent(bp,
+						    (const char *)opp,
+						    ((dump == -1 || dump >
+						    os->length) ? os->length : dump),
+						    dump_indent) <= 0)
+							goto end;
+						nl = 1;
+					}
+				}
+				ASN1_OCTET_STRING_free(os);
+				os = NULL;
+			} else if (tag == V_ASN1_INTEGER) {
+				ASN1_INTEGER *bs;
+				int i;
+
+				opp = op;
+				bs = d2i_ASN1_INTEGER(NULL, &opp, len + hl);
+				if (bs != NULL) {
+					if (BIO_write(bp, ":", 1) <= 0)
+						goto end;
+					if (bs->type == V_ASN1_NEG_INTEGER)
+						if (BIO_write(bp, "-", 1) <= 0)
+							goto end;
+					for (i = 0; i < bs->length; i++) {
+						if (BIO_printf(bp, "%02X",
+						    bs->data[i]) <= 0)
+							goto end;
+					}
+					if (bs->length == 0) {
+						if (BIO_write(bp, "00", 2) <= 0)
+							goto end;
+					}
+				} else {
+					if (BIO_write(bp, "BAD INTEGER", 11) <= 0)
+						goto end;
+				}
+				ASN1_INTEGER_free(bs);
+			} else if (tag == V_ASN1_ENUMERATED) {
+				ASN1_ENUMERATED *bs;
+				int i;
+
+				opp = op;
+				bs = d2i_ASN1_ENUMERATED(NULL, &opp, len + hl);
+				if (bs != NULL) {
+					if (BIO_write(bp, ":", 1) <= 0)
+						goto end;
+					if (bs->type == V_ASN1_NEG_ENUMERATED)
+						if (BIO_write(bp, "-", 1) <= 0)
+							goto end;
+					for (i = 0; i < bs->length; i++) {
+						if (BIO_printf(bp, "%02X",
+						    bs->data[i]) <= 0)
+							goto end;
+					}
+					if (bs->length == 0) {
+						if (BIO_write(bp, "00", 2) <= 0)
+							goto end;
+					}
+				} else {
+					if (BIO_write(bp, "BAD ENUMERATED", 14) <= 0)
+						goto end;
+				}
+				ASN1_ENUMERATED_free(bs);
+			} else if (len > 0 && dump) {
+				if (!nl) {
+					if (BIO_write(bp, "\n", 1) <= 0)
+						goto end;
+				}
+				if (BIO_dump_indent(bp, (const char *)p,
+				    ((dump == -1 || dump > len) ? len : dump),
+				    dump_indent) <= 0)
+					goto end;
+				nl = 1;
+			}
+
+			if (!nl) {
+				if (BIO_write(bp, "\n", 1) <= 0)
+					goto end;
+			}
+			p += len;
+			if ((tag == V_ASN1_EOC) && (xclass == 0)) {
+				ret = 2; /* End of sequence */
+				goto end;
+			}
+		}
+		length -= len;
+	}
+	ret = 1;
+
+end:
+	if (o != NULL)
+		ASN1_OBJECT_free(o);
+	ASN1_OCTET_STRING_free(os);
+	*pp = p;
+	return (ret);
+}
+
+const char *
+ASN1_tag2str(int tag)
+{
+	static const char * const tag2str[] = {
+		"EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */
+		"NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
+		"ENUMERATED", "", "UTF8STRING", "", 	    /* 10-13 */
+		"", "", "SEQUENCE", "SET", 		    /* 15-17 */
+		"NUMERICSTRING", "PRINTABLESTRING", "T61STRING",	    /* 18-20 */
+		"VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME", /* 21-24 */
+		"GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING",	    /* 25-27 */
+		"UNIVERSALSTRING", "", "BMPSTRING"		    /* 28-30 */
+	};
+
+	if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
+		tag &= ~0x100;
+
+	if (tag < 0 || tag > 30)
+		return "(unknown)";
+	return tag2str[tag];
+}
diff --git a/crypto/libressl/crypto/asn1/asn_mime.c b/crypto/libressl/crypto/asn1/asn_mime.c
new file mode 100644
index 0000000000..f0a94d8783
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/asn_mime.c
@@ -0,0 +1,1019 @@
+/* $OpenBSD: asn_mime.c,v 1.25 2015/02/10 11:22:21 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2008 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include "asn1_locl.h"
+
+/* Generalised MIME like utilities for streaming ASN1. Although many
+ * have a PKCS7/CMS like flavour others are more general purpose.
+ */
+
+/* MIME format structures
+ * Note that all are translated to lower case apart from
+ * parameter values. Quotes are stripped off
+ */
+
+typedef struct {
+	char *param_name;		/* Param name e.g. "micalg" */
+	char *param_value;		/* Param value e.g. "sha1" */
+} MIME_PARAM;
+
+DECLARE_STACK_OF(MIME_PARAM)
+
+typedef struct {
+	char *name;			/* Name of line e.g. "content-type" */
+	char *value;			/* Value of line e.g. "text/plain" */
+	STACK_OF(MIME_PARAM) *params;	/* Zero or more parameters */
+} MIME_HEADER;
+
+DECLARE_STACK_OF(MIME_HEADER)
+
+static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
+    const ASN1_ITEM *it);
+static char * strip_ends(char *name);
+static char * strip_start(char *name);
+static char * strip_end(char *name);
+static MIME_HEADER *mime_hdr_new(char *name, char *value);
+static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value);
+static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio);
+static int mime_hdr_cmp(const MIME_HEADER * const *a,
+    const MIME_HEADER * const *b);
+static int mime_param_cmp(const MIME_PARAM * const *a,
+    const MIME_PARAM * const *b);
+static void mime_param_free(MIME_PARAM *param);
+static int mime_bound_check(char *line, int linelen, char *bound, int blen);
+static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret);
+static int strip_eol(char *linebuf, int *plen);
+static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name);
+static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name);
+static void mime_hdr_free(MIME_HEADER *hdr);
+
+#define MAX_SMLEN 1024
+#define mime_debug(x) /* x */
+
+/* Output an ASN1 structure in BER format streaming if necessary */
+
+int
+i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+    const ASN1_ITEM *it)
+{
+	/* If streaming create stream BIO and copy all content through it */
+	if (flags & SMIME_STREAM) {
+		BIO *bio, *tbio;
+		bio = BIO_new_NDEF(out, val, it);
+		if (!bio) {
+			ASN1err(ASN1_F_I2D_ASN1_BIO_STREAM,
+			    ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		SMIME_crlf_copy(in, bio, flags);
+		(void)BIO_flush(bio);
+		/* Free up successive BIOs until we hit the old output BIO */
+		do {
+			tbio = BIO_pop(bio);
+			BIO_free(bio);
+			bio = tbio;
+		} while (bio != out);
+	}
+	/* else just write out ASN1 structure which will have all content
+	 * stored internally
+	 */
+	else
+		ASN1_item_i2d_bio(it, out, val);
+	return 1;
+}
+
+/* Base 64 read and write of ASN1 structure */
+
+static int
+B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+    const ASN1_ITEM *it)
+{
+	BIO *b64;
+	int r;
+
+	b64 = BIO_new(BIO_f_base64());
+	if (!b64) {
+		ASN1err(ASN1_F_B64_WRITE_ASN1, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	/* prepend the b64 BIO so all data is base64 encoded.
+	 */
+	out = BIO_push(b64, out);
+	r = i2d_ASN1_bio_stream(out, val, in, flags, it);
+	(void)BIO_flush(out);
+	BIO_pop(out);
+	BIO_free(b64);
+	return r;
+}
+
+/* Streaming ASN1 PEM write */
+
+int
+PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+    const char *hdr, const ASN1_ITEM *it)
+{
+	int r;
+
+	BIO_printf(out, "-----BEGIN %s-----\n", hdr);
+	r = B64_write_ASN1(out, val, in, flags, it);
+	BIO_printf(out, "-----END %s-----\n", hdr);
+	return r;
+}
+
+static ASN1_VALUE *
+b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
+{
+	BIO *b64;
+	ASN1_VALUE *val;
+	if (!(b64 = BIO_new(BIO_f_base64()))) {
+		ASN1err(ASN1_F_B64_READ_ASN1, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	bio = BIO_push(b64, bio);
+	val = ASN1_item_d2i_bio(it, bio, NULL);
+	if (!val)
+		ASN1err(ASN1_F_B64_READ_ASN1, ASN1_R_DECODE_ERROR);
+	(void)BIO_flush(bio);
+	bio = BIO_pop(bio);
+	BIO_free(b64);
+	return val;
+}
+
+/* Generate the MIME "micalg" parameter from RFC3851, RFC4490 */
+
+static int
+asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
+{
+	const EVP_MD *md;
+	int i, have_unknown = 0, write_comma, ret = 0, md_nid;
+
+	have_unknown = 0;
+	write_comma = 0;
+	for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++) {
+		if (write_comma)
+			BIO_write(out, ",", 1);
+		write_comma = 1;
+		md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm);
+		md = EVP_get_digestbynid(md_nid);
+		if (md && md->md_ctrl) {
+			int rv;
+			char *micstr;
+			rv = md->md_ctrl(NULL, EVP_MD_CTRL_MICALG, 0, &micstr);
+			if (rv > 0) {
+				BIO_puts(out, micstr);
+				free(micstr);
+				continue;
+			}
+			if (rv != -2)
+				goto err;
+		}
+		switch (md_nid) {
+		case NID_sha1:
+			BIO_puts(out, "sha1");
+			break;
+
+		case NID_md5:
+			BIO_puts(out, "md5");
+			break;
+
+		case NID_sha256:
+			BIO_puts(out, "sha-256");
+			break;
+
+		case NID_sha384:
+			BIO_puts(out, "sha-384");
+			break;
+
+		case NID_sha512:
+			BIO_puts(out, "sha-512");
+			break;
+
+		case NID_id_GostR3411_94:
+			BIO_puts(out, "gostr3411-94");
+			goto err;
+			break;
+
+		default:
+			if (have_unknown)
+				write_comma = 0;
+			else {
+				BIO_puts(out, "unknown");
+				have_unknown = 1;
+			}
+			break;
+
+		}
+	}
+
+	ret = 1;
+
+err:
+	return ret;
+}
+
+/* SMIME sender */
+
+int
+SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
+    int ctype_nid, int econt_nid, STACK_OF(X509_ALGOR) *mdalgs,
+    const ASN1_ITEM *it)
+{
+	char bound[33], c;
+	int i;
+	const char *mime_prefix, *mime_eol, *cname = "smime.p7m";
+	const char *msg_type = NULL;
+
+	if (flags & SMIME_OLDMIME)
+		mime_prefix = "application/x-pkcs7-";
+	else
+		mime_prefix = "application/pkcs7-";
+
+	if (flags & SMIME_CRLFEOL)
+		mime_eol = "\r\n";
+	else
+		mime_eol = "\n";
+	if ((flags & SMIME_DETACHED) && data) {
+		/* We want multipart/signed */
+		/* Generate a random boundary */
+		arc4random_buf(bound, 32);
+		for (i = 0; i < 32; i++) {
+			c = bound[i] & 0xf;
+			if (c < 10)
+				c += '0';
+			else
+				c += 'A' - 10;
+			bound[i] = c;
+		}
+		bound[32] = 0;
+		BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
+		BIO_printf(bio, "Content-Type: multipart/signed;");
+		BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix);
+		BIO_puts(bio, " micalg=\"");
+		asn1_write_micalg(bio, mdalgs);
+		BIO_printf(bio, "\"; boundary=\"----%s\"%s%s",
+		    bound, mime_eol, mime_eol);
+		BIO_printf(bio, "This is an S/MIME signed message%s%s",
+		    mime_eol, mime_eol);
+		/* Now write out the first part */
+		BIO_printf(bio, "------%s%s", bound, mime_eol);
+		if (!asn1_output_data(bio, data, val, flags, it))
+			return 0;
+		BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol);
+
+		/* Headers for signature */
+
+		BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix);
+		BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol);
+		BIO_printf(bio, "Content-Transfer-Encoding: base64%s",
+		    mime_eol);
+		BIO_printf(bio, "Content-Disposition: attachment;");
+		BIO_printf(bio, " filename=\"smime.p7s\"%s%s",
+		    mime_eol, mime_eol);
+		B64_write_ASN1(bio, val, NULL, 0, it);
+		BIO_printf(bio, "%s------%s--%s%s", mime_eol, bound,
+		    mime_eol, mime_eol);
+		return 1;
+	}
+
+	/* Determine smime-type header */
+
+	if (ctype_nid == NID_pkcs7_enveloped)
+		msg_type = "enveloped-data";
+	else if (ctype_nid == NID_pkcs7_signed) {
+		if (econt_nid == NID_id_smime_ct_receipt)
+			msg_type = "signed-receipt";
+		else if (sk_X509_ALGOR_num(mdalgs) >= 0)
+			msg_type = "signed-data";
+		else
+			msg_type = "certs-only";
+	} else if (ctype_nid == NID_id_smime_ct_compressedData) {
+		msg_type = "compressed-data";
+		cname = "smime.p7z";
+	}
+	/* MIME headers */
+	BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
+	BIO_printf(bio, "Content-Disposition: attachment;");
+	BIO_printf(bio, " filename=\"%s\"%s", cname, mime_eol);
+	BIO_printf(bio, "Content-Type: %smime;", mime_prefix);
+	if (msg_type)
+		BIO_printf(bio, " smime-type=%s;", msg_type);
+	BIO_printf(bio, " name=\"%s\"%s", cname, mime_eol);
+	BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s",
+	    mime_eol, mime_eol);
+	if (!B64_write_ASN1(bio, val, data, flags, it))
+		return 0;
+	BIO_printf(bio, "%s", mime_eol);
+	return 1;
+}
+
+/* Handle output of ASN1 data */
+
+
+static int
+asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
+    const ASN1_ITEM *it)
+{
+	BIO *tmpbio;
+	const ASN1_AUX *aux = it->funcs;
+	ASN1_STREAM_ARG sarg;
+	int rv = 1;
+
+	/* If data is not deteched or resigning then the output BIO is
+	 * already set up to finalise when it is written through.
+	 */
+	if (!(flags & SMIME_DETACHED) || (flags & PKCS7_REUSE_DIGEST)) {
+		SMIME_crlf_copy(data, out, flags);
+		return 1;
+	}
+
+	if (!aux || !aux->asn1_cb) {
+		ASN1err(ASN1_F_ASN1_OUTPUT_DATA,
+		    ASN1_R_STREAMING_NOT_SUPPORTED);
+		return 0;
+	}
+
+	sarg.out = out;
+	sarg.ndef_bio = NULL;
+	sarg.boundary = NULL;
+
+	/* Let ASN1 code prepend any needed BIOs */
+
+	if (aux->asn1_cb(ASN1_OP_DETACHED_PRE, &val, it, &sarg) <= 0)
+		return 0;
+
+	/* Copy data across, passing through filter BIOs for processing */
+	SMIME_crlf_copy(data, sarg.ndef_bio, flags);
+
+	/* Finalize structure */
+	if (aux->asn1_cb(ASN1_OP_DETACHED_POST, &val, it, &sarg) <= 0)
+		rv = 0;
+
+	/* Now remove any digests prepended to the BIO */
+
+	while (sarg.ndef_bio != out) {
+		tmpbio = BIO_pop(sarg.ndef_bio);
+		BIO_free(sarg.ndef_bio);
+		sarg.ndef_bio = tmpbio;
+	}
+
+	return rv;
+}
+
+/* SMIME reader: handle multipart/signed and opaque signing.
+ * in multipart case the content is placed in a memory BIO
+ * pointed to by "bcont". In opaque this is set to NULL
+ */
+
+ASN1_VALUE *
+SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
+{
+	BIO *asnin;
+	STACK_OF(MIME_HEADER) *headers = NULL;
+	STACK_OF(BIO) *parts = NULL;
+	MIME_HEADER *hdr;
+	MIME_PARAM *prm;
+	ASN1_VALUE *val;
+	int ret;
+
+	if (bcont)
+		*bcont = NULL;
+
+	if (!(headers = mime_parse_hdr(bio))) {
+		ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_PARSE_ERROR);
+		return NULL;
+	}
+
+	if (!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
+		sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+		ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_CONTENT_TYPE);
+		return NULL;
+	}
+
+	/* Handle multipart/signed */
+
+	if (!strcmp(hdr->value, "multipart/signed")) {
+		/* Split into two parts */
+		prm = mime_param_find(hdr, "boundary");
+		if (!prm || !prm->param_value) {
+			sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+			ASN1err(ASN1_F_SMIME_READ_ASN1,
+			    ASN1_R_NO_MULTIPART_BOUNDARY);
+			return NULL;
+		}
+		ret = multi_split(bio, prm->param_value, &parts);
+		sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+		if (!ret || (sk_BIO_num(parts) != 2) ) {
+			ASN1err(ASN1_F_SMIME_READ_ASN1,
+			    ASN1_R_NO_MULTIPART_BODY_FAILURE);
+			sk_BIO_pop_free(parts, BIO_vfree);
+			return NULL;
+		}
+
+		/* Parse the signature piece */
+		asnin = sk_BIO_value(parts, 1);
+
+		if (!(headers = mime_parse_hdr(asnin))) {
+			ASN1err(ASN1_F_SMIME_READ_ASN1,
+			    ASN1_R_MIME_SIG_PARSE_ERROR);
+			sk_BIO_pop_free(parts, BIO_vfree);
+			return NULL;
+		}
+
+		/* Get content type */
+
+		if (!(hdr = mime_hdr_find(headers, "content-type")) ||
+		    !hdr->value) {
+			sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+			sk_BIO_pop_free(parts, BIO_vfree);
+			ASN1err(ASN1_F_SMIME_READ_ASN1,
+			    ASN1_R_NO_SIG_CONTENT_TYPE);
+			return NULL;
+		}
+
+		if (strcmp(hdr->value, "application/x-pkcs7-signature") &&
+		    strcmp(hdr->value, "application/pkcs7-signature")) {
+			ASN1err(ASN1_F_SMIME_READ_ASN1,
+			    ASN1_R_SIG_INVALID_MIME_TYPE);
+			ERR_asprintf_error_data("type: %s", hdr->value);
+			sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+			sk_BIO_pop_free(parts, BIO_vfree);
+			return NULL;
+		}
+		sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+		/* Read in ASN1 */
+		if (!(val = b64_read_asn1(asnin, it))) {
+			ASN1err(ASN1_F_SMIME_READ_ASN1,
+			    ASN1_R_ASN1_SIG_PARSE_ERROR);
+			sk_BIO_pop_free(parts, BIO_vfree);
+			return NULL;
+		}
+
+		if (bcont) {
+			*bcont = sk_BIO_value(parts, 0);
+			BIO_free(asnin);
+			sk_BIO_free(parts);
+		} else sk_BIO_pop_free(parts, BIO_vfree);
+			return val;
+	}
+
+	/* OK, if not multipart/signed try opaque signature */
+
+	if (strcmp (hdr->value, "application/x-pkcs7-mime") &&
+	    strcmp (hdr->value, "application/pkcs7-mime")) {
+		ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_INVALID_MIME_TYPE);
+		ERR_asprintf_error_data("type: %s", hdr->value);
+		sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+		return NULL;
+	}
+
+	sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+
+	if (!(val = b64_read_asn1(bio, it))) {
+		ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_PARSE_ERROR);
+		return NULL;
+	}
+	return val;
+}
+
+/* Copy text from one BIO to another making the output CRLF at EOL */
+int
+SMIME_crlf_copy(BIO *in, BIO *out, int flags)
+{
+	BIO *bf;
+	char eol;
+	int len;
+	char linebuf[MAX_SMLEN];
+
+	/* Buffer output so we don't write one line at a time. This is
+	 * useful when streaming as we don't end up with one OCTET STRING
+	 * per line.
+	 */
+	bf = BIO_new(BIO_f_buffer());
+	if (!bf)
+		return 0;
+	out = BIO_push(bf, out);
+	if (flags & SMIME_BINARY) {
+		while ((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0)
+			BIO_write(out, linebuf, len);
+	} else {
+		if (flags & SMIME_TEXT)
+			BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
+		while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) {
+			eol = strip_eol(linebuf, &len);
+			if (len)
+				BIO_write(out, linebuf, len);
+			if (eol)
+				BIO_write(out, "\r\n", 2);
+		}
+	}
+	(void)BIO_flush(out);
+	BIO_pop(out);
+	BIO_free(bf);
+	return 1;
+}
+
+/* Strip off headers if they are text/plain */
+int
+SMIME_text(BIO *in, BIO *out)
+{
+	char iobuf[4096];
+	int len;
+	STACK_OF(MIME_HEADER) *headers;
+	MIME_HEADER *hdr;
+
+	if (!(headers = mime_parse_hdr(in))) {
+		ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_PARSE_ERROR);
+		return 0;
+	}
+	if (!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
+		ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_NO_CONTENT_TYPE);
+		sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+		return 0;
+	}
+	if (strcmp (hdr->value, "text/plain")) {
+		ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_INVALID_MIME_TYPE);
+		ERR_asprintf_error_data("type: %s", hdr->value);
+		sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+		return 0;
+	}
+	sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+	while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0)
+		BIO_write(out, iobuf, len);
+	if (len < 0)
+		return 0;
+	return 1;
+}
+
+/*
+ * Split a multipart/XXX message body into component parts: result is
+ * canonical parts in a STACK of bios
+ */
+static int
+multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
+{
+	char linebuf[MAX_SMLEN];
+	int len, blen;
+	int eol = 0, next_eol = 0;
+	BIO *bpart = NULL;
+	STACK_OF(BIO) *parts;
+	char state, part, first;
+
+	blen = strlen(bound);
+	part = 0;
+	state = 0;
+	first = 1;
+	parts = sk_BIO_new_null();
+	*ret = parts;
+	if (parts == NULL)
+		return 0;
+	while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
+		state = mime_bound_check(linebuf, len, bound, blen);
+		if (state == 1) {
+			first = 1;
+			part++;
+		} else if (state == 2) {
+			if (sk_BIO_push(parts, bpart) == 0)
+				return 0;
+			return 1;
+		} else if (part) {
+			/* Strip CR+LF from linebuf */
+			next_eol = strip_eol(linebuf, &len);
+			if (first) {
+				first = 0;
+				if (bpart != NULL) {
+					if (sk_BIO_push(parts, bpart) == 0)
+						return 0;
+				}
+				bpart = BIO_new(BIO_s_mem());
+				if (bpart == NULL)
+					return 0;
+				BIO_set_mem_eof_return(bpart, 0);
+			} else if (eol)
+				BIO_write(bpart, "\r\n", 2);
+			eol = next_eol;
+			if (len)
+				BIO_write(bpart, linebuf, len);
+		}
+	}
+	BIO_free(bpart);
+	return 0;
+}
+
+/* This is the big one: parse MIME header lines up to message body */
+
+#define MIME_INVALID	0
+#define MIME_START	1
+#define MIME_TYPE	2
+#define MIME_NAME	3
+#define MIME_VALUE	4
+#define MIME_QUOTE	5
+#define MIME_COMMENT	6
+
+
+static
+STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
+{
+	char *p, *q, c;
+	char *ntmp;
+	char linebuf[MAX_SMLEN];
+	MIME_HEADER *mhdr = NULL;
+	STACK_OF(MIME_HEADER) *headers;
+	int len, state, save_state = 0;
+
+	headers = sk_MIME_HEADER_new(mime_hdr_cmp);
+	if (!headers)
+		return NULL;
+	while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
+		/* If whitespace at line start then continuation line */
+		if (mhdr && isspace((unsigned char)linebuf[0]))
+			state = MIME_NAME;
+		else
+			state = MIME_START;
+		ntmp = NULL;
+
+		/* Go through all characters */
+		for (p = linebuf, q = linebuf;
+		    (c = *p) && (c != '\r') && (c != '\n'); p++) {
+
+			/* State machine to handle MIME headers
+			 * if this looks horrible that's because it *is*
+			 */
+
+			switch (state) {
+			case MIME_START:
+				if (c == ':') {
+					state = MIME_TYPE;
+					*p = 0;
+					ntmp = strip_ends(q);
+					q = p + 1;
+				}
+				break;
+
+			case MIME_TYPE:
+				if (c == ';') {
+					mime_debug("Found End Value\n");
+					*p = 0;
+					mhdr = mime_hdr_new(ntmp,
+					    strip_ends(q));
+					if (mhdr == NULL)
+						goto merr;
+					if (sk_MIME_HEADER_push(headers,
+					    mhdr) == 0)
+						goto merr;
+					ntmp = NULL;
+					q = p + 1;
+					state = MIME_NAME;
+				} else if (c == '(') {
+					save_state = state;
+					state = MIME_COMMENT;
+				}
+				break;
+
+			case MIME_COMMENT:
+				if (c == ')') {
+					state = save_state;
+				}
+				break;
+
+			case MIME_NAME:
+				if (c == '=') {
+					state = MIME_VALUE;
+					*p = 0;
+					ntmp = strip_ends(q);
+					q = p + 1;
+				}
+				break;
+
+			case MIME_VALUE:
+				if (c == ';') {
+					state = MIME_NAME;
+					*p = 0;
+					mime_hdr_addparam(mhdr, ntmp,
+					    strip_ends(q));
+					ntmp = NULL;
+					q = p + 1;
+				} else if (c == '"') {
+					mime_debug("Found Quote\n");
+					state = MIME_QUOTE;
+				} else if (c == '(') {
+					save_state = state;
+					state = MIME_COMMENT;
+				}
+				break;
+
+			case MIME_QUOTE:
+				if (c == '"') {
+					mime_debug("Found Match Quote\n");
+					state = MIME_VALUE;
+				}
+				break;
+			}
+		}
+
+		if (state == MIME_TYPE) {
+			mhdr = mime_hdr_new(ntmp, strip_ends(q));
+			if (mhdr == NULL)
+				goto merr;
+			if (sk_MIME_HEADER_push(headers, mhdr) == 0)
+				goto merr;
+		} else if (state == MIME_VALUE)
+			mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
+
+		if (p == linebuf)
+			break;	/* Blank line means end of headers */
+	}
+
+	return headers;
+
+merr:
+	if (mhdr != NULL)
+		mime_hdr_free(mhdr);
+	sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+	return NULL;
+}
+
+static char *
+strip_ends(char *name)
+{
+	return strip_end(strip_start(name));
+}
+
+/* Strip a parameter of whitespace from start of param */
+static char *
+strip_start(char *name)
+{
+	char *p, c;
+
+	/* Look for first non white space or quote */
+	for (p = name; (c = *p); p++) {
+		if (c == '"') {
+			/* Next char is start of string if non null */
+			if (p[1])
+				return p + 1;
+			/* Else null string */
+			return NULL;
+		}
+		if (!isspace((unsigned char)c))
+			return p;
+	}
+	return NULL;
+}
+
+/* As above but strip from end of string : maybe should handle brackets? */
+static char *
+strip_end(char *name)
+{
+	char *p, c;
+
+	if (!name)
+		return NULL;
+
+	/* Look for first non white space or quote */
+	for (p = name + strlen(name) - 1; p >= name; p--) {
+		c = *p;
+		if (c == '"') {
+			if (p - 1 == name)
+				return NULL;
+			*p = 0;
+			return name;
+		}
+		if (isspace((unsigned char)c))
+			*p = 0;
+		else
+			return name;
+	}
+	return NULL;
+}
+
+static MIME_HEADER *
+mime_hdr_new(char *name, char *value)
+{
+	MIME_HEADER *mhdr;
+	char *tmpname = NULL, *tmpval = NULL, *p;
+
+	if (name) {
+		if (!(tmpname = strdup(name)))
+			goto err;
+		for (p = tmpname; *p; p++)
+			*p = tolower((unsigned char)*p);
+	}
+	if (value) {
+		if (!(tmpval = strdup(value)))
+			goto err;
+		for (p = tmpval; *p; p++)
+			*p = tolower((unsigned char)*p);
+	}
+	mhdr = malloc(sizeof(MIME_HEADER));
+	if (!mhdr)
+		goto err;
+	mhdr->name = tmpname;
+	mhdr->value = tmpval;
+	if (!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp))) {
+		free(mhdr);
+		goto err;
+	}
+	return mhdr;
+err:
+	free(tmpname);
+	free(tmpval);
+	return NULL;
+}
+
+static int
+mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
+{
+	char *tmpname = NULL, *tmpval = NULL, *p;
+	MIME_PARAM *mparam;
+
+	if (name) {
+		tmpname = strdup(name);
+		if (!tmpname)
+			goto err;
+		for (p = tmpname; *p; p++)
+			*p = tolower((unsigned char)*p);
+	}
+	if (value) {
+		tmpval = strdup(value);
+		if (!tmpval)
+			goto err;
+	}
+	/* Parameter values are case sensitive so leave as is */
+	mparam = malloc(sizeof(MIME_PARAM));
+	if (!mparam)
+		goto err;
+	mparam->param_name = tmpname;
+	mparam->param_value = tmpval;
+	if (sk_MIME_PARAM_push(mhdr->params, mparam) == 0) {
+		free(mparam);
+		goto err;
+	}
+	return 1;
+err:
+	free(tmpname);
+	free(tmpval);
+	return 0;
+}
+
+static int
+mime_hdr_cmp(const MIME_HEADER * const *a, const MIME_HEADER * const *b)
+{
+	if (!(*a)->name || !(*b)->name)
+		return !!(*a)->name - !!(*b)->name;
+	return (strcmp((*a)->name, (*b)->name));
+}
+
+static int
+mime_param_cmp(const MIME_PARAM * const *a, const MIME_PARAM * const *b)
+{
+	if (!(*a)->param_name || !(*b)->param_name)
+		return !!(*a)->param_name - !!(*b)->param_name;
+	return (strcmp((*a)->param_name, (*b)->param_name));
+}
+
+/* Find a header with a given name (if possible) */
+
+static MIME_HEADER *
+mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name)
+{
+	MIME_HEADER htmp;
+	int idx;
+	htmp.name = name;
+	idx = sk_MIME_HEADER_find(hdrs, &htmp);
+	if (idx < 0)
+		return NULL;
+	return sk_MIME_HEADER_value(hdrs, idx);
+}
+
+static MIME_PARAM *
+mime_param_find(MIME_HEADER *hdr, char *name)
+{
+	MIME_PARAM param;
+	int idx;
+	param.param_name = name;
+	idx = sk_MIME_PARAM_find(hdr->params, ¶m);
+	if (idx < 0)
+		return NULL;
+	return sk_MIME_PARAM_value(hdr->params, idx);
+}
+
+static void
+mime_hdr_free(MIME_HEADER *hdr)
+{
+	free(hdr->name);
+	free(hdr->value);
+	if (hdr->params)
+		sk_MIME_PARAM_pop_free(hdr->params, mime_param_free);
+	free(hdr);
+}
+
+static void
+mime_param_free(MIME_PARAM *param)
+{
+	free(param->param_name);
+	free(param->param_value);
+	free(param);
+}
+
+/* Check for a multipart boundary. Returns:
+ * 0 : no boundary
+ * 1 : part boundary
+ * 2 : final boundary
+ */
+static int
+mime_bound_check(char *line, int linelen, char *bound, int blen)
+{
+	if (linelen == -1)
+		linelen = strlen(line);
+	if (blen == -1)
+		blen = strlen(bound);
+	/* Quickly eliminate if line length too short */
+	if (blen + 2 > linelen)
+		return 0;
+	/* Check for part boundary */
+	if (!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) {
+		if (!strncmp(line + blen + 2, "--", 2))
+			return 2;
+		else
+			return 1;
+	}
+	return 0;
+}
+
+static int
+strip_eol(char *linebuf, int *plen)
+{
+	int len = *plen;
+	char *p, c;
+	int is_eol = 0;
+
+	for (p = linebuf + len - 1; len > 0; len--, p--) {
+		c = *p;
+		if (c == '\n')
+			is_eol = 1;
+		else if (c != '\r')
+			break;
+	}
+	*plen = len;
+	return is_eol;
+}
diff --git a/crypto/libressl/crypto/asn1/asn_moid.c b/crypto/libressl/crypto/asn1/asn_moid.c
new file mode 100644
index 0000000000..2e900536e2
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/asn_moid.c
@@ -0,0 +1,158 @@
+/* $OpenBSD: asn_moid.c,v 1.11 2014/07/10 13:58:22 jsing Exp $ */
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001-2004 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+/* Simple ASN1 OID module: add all objects in a given section */
+
+static int do_create(char *value, char *name);
+
+static int
+oid_module_init(CONF_IMODULE *md, const CONF *cnf)
+{
+	int i;
+	const char *oid_section;
+	STACK_OF(CONF_VALUE) *sktmp;
+	CONF_VALUE *oval;
+
+	oid_section = CONF_imodule_get_value(md);
+	if (!(sktmp = NCONF_get_section(cnf, oid_section))) {
+		ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION);
+		return 0;
+	}
+	for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
+		oval = sk_CONF_VALUE_value(sktmp, i);
+		if (!do_create(oval->value, oval->name)) {
+			ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ADDING_OBJECT);
+			return 0;
+		}
+	}
+	return 1;
+}
+
+static void
+oid_module_finish(CONF_IMODULE *md)
+{
+	OBJ_cleanup();
+}
+
+void
+ASN1_add_oid_module(void)
+{
+	CONF_module_add("oid_section", oid_module_init, oid_module_finish);
+}
+
+/* Create an OID based on a name value pair. Accept two formats.
+ * shortname = 1.2.3.4
+ * shortname = some long name, 1.2.3.4
+ */
+
+static int
+do_create(char *value, char *name)
+{
+	int nid;
+	ASN1_OBJECT *oid;
+	char *ln, *ostr, *p, *lntmp;
+
+	p = strrchr(value, ',');
+	if (!p) {
+		ln = name;
+		ostr = value;
+	} else {
+		ln = NULL;
+		ostr = p + 1;
+		if (!*ostr)
+			return 0;
+		while (isspace((unsigned char)*ostr))
+			ostr++;
+	}
+
+	nid = OBJ_create(ostr, name, ln);
+
+	if (nid == NID_undef)
+		return 0;
+
+	if (p) {
+		ln = value;
+		while (isspace((unsigned char)*ln))
+			ln++;
+		p--;
+		while (isspace((unsigned char)*p)) {
+			if (p == ln)
+				return 0;
+			p--;
+		}
+		p++;
+		lntmp = malloc((p - ln) + 1);
+		if (lntmp == NULL)
+			return 0;
+		memcpy(lntmp, ln, p - ln);
+		lntmp[p - ln] = 0;
+		oid = OBJ_nid2obj(nid);
+		oid->ln = lntmp;
+	}
+
+	return 1;
+}
diff --git a/crypto/libressl/crypto/asn1/asn_pack.c b/crypto/libressl/crypto/asn1/asn_pack.c
new file mode 100644
index 0000000000..70b9f55364
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/asn_pack.c
@@ -0,0 +1,215 @@
+/* $OpenBSD: asn_pack.c,v 1.14 2014/07/11 13:41:59 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+
+#ifndef NO_ASN1_OLD
+
+/* ASN1 packing and unpacking functions */
+
+/* Turn an ASN1 encoded SEQUENCE OF into a STACK of structures */
+
+STACK_OF(OPENSSL_BLOCK) *
+ASN1_seq_unpack(const unsigned char *buf, int len, d2i_of_void *d2i,
+    void (*free_func)(OPENSSL_BLOCK))
+{
+	STACK_OF(OPENSSL_BLOCK) *sk;
+	const unsigned char *pbuf;
+
+	pbuf = buf;
+	if (!(sk = d2i_ASN1_SET(NULL, &pbuf, len, d2i, free_func,
+					V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL)))
+		ASN1err(ASN1_F_ASN1_SEQ_UNPACK,ASN1_R_DECODE_ERROR);
+	return sk;
+}
+
+/* Turn a STACK structures into an ASN1 encoded SEQUENCE OF structure in a
+ * OPENSSL_malloc'ed buffer
+ */
+
+unsigned char *
+ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
+    unsigned char **buf, int *len)
+{
+	int safelen;
+	unsigned char *safe, *p;
+
+	if (!(safelen = i2d_ASN1_SET(safes, NULL, i2d, V_ASN1_SEQUENCE,
+					      V_ASN1_UNIVERSAL, IS_SEQUENCE))) {
+		ASN1err(ASN1_F_ASN1_SEQ_PACK,ASN1_R_ENCODE_ERROR);
+		return NULL;
+	}
+	if (!(safe = malloc(safelen))) {
+		ASN1err(ASN1_F_ASN1_SEQ_PACK,ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	p = safe;
+	i2d_ASN1_SET(safes, &p, i2d, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL,
+								 IS_SEQUENCE);
+	if (len)
+		*len = safelen;
+	if (buf)
+		*buf = safe;
+	return safe;
+}
+
+/* Extract an ASN1 object from an ASN1_STRING */
+
+void *
+ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i)
+{
+	const unsigned char *p;
+	char *ret;
+
+	p = oct->data;
+	if (!(ret = d2i(NULL, &p, oct->length)))
+		ASN1err(ASN1_F_ASN1_UNPACK_STRING,ASN1_R_DECODE_ERROR);
+	return ret;
+}
+
+/* Pack an ASN1 object into an ASN1_STRING */
+
+ASN1_STRING *
+ASN1_pack_string(void *obj, i2d_of_void *i2d, ASN1_STRING **oct)
+{
+	unsigned char *p;
+	ASN1_STRING *octmp;
+
+	if (!oct || !*oct) {
+		if (!(octmp = ASN1_STRING_new())) {
+			ASN1err(ASN1_F_ASN1_PACK_STRING,ERR_R_MALLOC_FAILURE);
+			return NULL;
+		}
+	} else
+		octmp = *oct;
+		
+	if (!(octmp->length = i2d(obj, NULL))) {
+		ASN1err(ASN1_F_ASN1_PACK_STRING,ASN1_R_ENCODE_ERROR);
+		goto err;
+	}
+	if (!(p = malloc (octmp->length))) {
+		ASN1err(ASN1_F_ASN1_PACK_STRING,ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	octmp->data = p;
+	i2d (obj, &p);
+	if (oct)
+		*oct = octmp;
+	return octmp;
+err:
+	if (!oct || octmp != *oct) {
+		ASN1_STRING_free(octmp);
+		if (oct)
+			*oct = NULL;
+	}
+	return NULL;
+}
+
+#endif
+
+/* ASN1_ITEM versions of the above */
+
+ASN1_STRING *
+ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
+{
+	ASN1_STRING *octmp;
+
+	if (!oct || !*oct) {
+		if (!(octmp = ASN1_STRING_new ())) {
+			ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE);
+			return NULL;
+		}
+	} else
+		octmp = *oct;
+
+	free(octmp->data);
+	octmp->data = NULL;
+
+	if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) {
+		ASN1err(ASN1_F_ASN1_ITEM_PACK, ASN1_R_ENCODE_ERROR);
+		goto err;
+	}
+	if (!octmp->data) {
+		ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	if (oct)
+		*oct = octmp;
+	return octmp;
+err:
+	if (!oct || octmp != *oct)
+		ASN1_STRING_free(octmp);
+	return NULL;
+}
+
+/* Extract an ASN1 object from an ASN1_STRING */
+
+void *
+ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it)
+{
+	const unsigned char *p;
+	void *ret;
+
+	p = oct->data;
+	if (!(ret = ASN1_item_d2i(NULL, &p, oct->length, it)))
+		ASN1err(ASN1_F_ASN1_ITEM_UNPACK, ASN1_R_DECODE_ERROR);
+	return ret;
+}
diff --git a/crypto/libressl/crypto/asn1/bio_asn1.c b/crypto/libressl/crypto/asn1/bio_asn1.c
new file mode 100644
index 0000000000..ae86708a21
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/bio_asn1.c
@@ -0,0 +1,496 @@
+/* $OpenBSD: bio_asn1.c,v 1.11 2015/02/10 09:52:35 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Experimental ASN1 BIO. When written through the data is converted
+ * to an ASN1 string type: default is OCTET STRING. Additional functions
+ * can be provided to add prefix and suffix data.
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+
+/* Must be large enough for biggest tag+length */
+#define DEFAULT_ASN1_BUF_SIZE 20
+
+typedef enum {
+	ASN1_STATE_START,
+	ASN1_STATE_PRE_COPY,
+	ASN1_STATE_HEADER,
+	ASN1_STATE_HEADER_COPY,
+	ASN1_STATE_DATA_COPY,
+	ASN1_STATE_POST_COPY,
+	ASN1_STATE_DONE
+} asn1_bio_state_t;
+
+typedef struct BIO_ASN1_EX_FUNCS_st {
+	asn1_ps_func	*ex_func;
+	asn1_ps_func	*ex_free_func;
+} BIO_ASN1_EX_FUNCS;
+
+typedef struct BIO_ASN1_BUF_CTX_t {
+	/* Internal state */
+	asn1_bio_state_t state;
+	/* Internal buffer */
+	unsigned char *buf;
+	/* Size of buffer */
+	int bufsize;
+	/* Current position in buffer */
+	int bufpos;
+	/* Current buffer length */
+	int buflen;
+	/* Amount of data to copy */
+	int copylen;
+	/* Class and tag to use */
+	int asn1_class, asn1_tag;
+	asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
+	/* Extra buffer for prefix and suffix data */
+	unsigned char *ex_buf;
+	int ex_len;
+	int ex_pos;
+	void *ex_arg;
+} BIO_ASN1_BUF_CTX;
+
+
+static int asn1_bio_write(BIO *h, const char *buf, int num);
+static int asn1_bio_read(BIO *h, char *buf, int size);
+static int asn1_bio_puts(BIO *h, const char *str);
+static int asn1_bio_gets(BIO *h, char *str, int size);
+static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int asn1_bio_new(BIO *h);
+static int asn1_bio_free(BIO *data);
+static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+
+static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
+static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+    asn1_ps_func *cleanup, asn1_bio_state_t next);
+static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+    asn1_ps_func *setup, asn1_bio_state_t ex_state,
+    asn1_bio_state_t other_state);
+
+static BIO_METHOD methods_asn1 = {
+	.type = BIO_TYPE_ASN1,
+	.name = "asn1",
+	.bwrite = asn1_bio_write,
+	.bread = asn1_bio_read,
+	.bputs = asn1_bio_puts,
+	.bgets = asn1_bio_gets,
+	.ctrl = asn1_bio_ctrl,
+	.create = asn1_bio_new,
+	.destroy = asn1_bio_free,
+	.callback_ctrl = asn1_bio_callback_ctrl
+};
+
+BIO_METHOD *
+BIO_f_asn1(void)
+{
+	return (&methods_asn1);
+}
+
+static int
+asn1_bio_new(BIO *b)
+{
+	BIO_ASN1_BUF_CTX *ctx;
+	ctx = malloc(sizeof(BIO_ASN1_BUF_CTX));
+	if (!ctx)
+		return 0;
+	if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) {
+		free(ctx);
+		return 0;
+	}
+	b->init = 1;
+	b->ptr = (char *)ctx;
+	b->flags = 0;
+	return 1;
+}
+
+static int
+asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
+{
+	ctx->buf = malloc(size);
+	if (!ctx->buf)
+		return 0;
+	ctx->bufsize = size;
+	ctx->bufpos = 0;
+	ctx->buflen = 0;
+	ctx->copylen = 0;
+	ctx->asn1_class = V_ASN1_UNIVERSAL;
+	ctx->asn1_tag = V_ASN1_OCTET_STRING;
+	ctx->ex_buf = NULL;
+	ctx->ex_pos = 0;
+	ctx->ex_len = 0;
+	ctx->state = ASN1_STATE_START;
+	return 1;
+}
+
+static int
+asn1_bio_free(BIO *b)
+{
+	BIO_ASN1_BUF_CTX *ctx;
+
+	ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
+	if (ctx == NULL)
+		return 0;
+	free(ctx->buf);
+	free(ctx);
+	b->init = 0;
+	b->ptr = NULL;
+	b->flags = 0;
+	return 1;
+}
+
+static int
+asn1_bio_write(BIO *b, const char *in , int inl)
+{
+	BIO_ASN1_BUF_CTX *ctx;
+	int wrmax, wrlen, ret, buflen;
+	unsigned char *p;
+
+	if (!in || (inl < 0) || (b->next_bio == NULL))
+		return 0;
+	ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
+	if (ctx == NULL)
+		return 0;
+
+	wrlen = 0;
+	ret = -1;
+
+	for (;;) {
+		switch (ctx->state) {
+
+			/* Setup prefix data, call it */
+		case ASN1_STATE_START:
+			if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
+				    ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
+				return 0;
+			break;
+
+			/* Copy any pre data first */
+		case ASN1_STATE_PRE_COPY:
+			ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
+			    ASN1_STATE_HEADER);
+			if (ret <= 0)
+				goto done;
+			break;
+
+		case ASN1_STATE_HEADER:
+			buflen = ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
+			if (buflen <= 0 || buflen > ctx->bufsize)
+				return -1;
+			ctx->buflen = buflen;
+			p = ctx->buf;
+			ASN1_put_object(&p, 0, inl,
+			    ctx->asn1_tag, ctx->asn1_class);
+			ctx->copylen = inl;
+			ctx->state = ASN1_STATE_HEADER_COPY;
+			break;
+
+		case ASN1_STATE_HEADER_COPY:
+			ret = BIO_write(b->next_bio,
+			    ctx->buf + ctx->bufpos, ctx->buflen);
+			if (ret <= 0)
+				goto done;
+
+			ctx->buflen -= ret;
+			if (ctx->buflen)
+				ctx->bufpos += ret;
+			else {
+				ctx->bufpos = 0;
+				ctx->state = ASN1_STATE_DATA_COPY;
+			}
+			break;
+
+		case ASN1_STATE_DATA_COPY:
+
+			if (inl > ctx->copylen)
+				wrmax = ctx->copylen;
+			else
+				wrmax = inl;
+			ret = BIO_write(b->next_bio, in, wrmax);
+			if (ret <= 0)
+				break;
+			wrlen += ret;
+			ctx->copylen -= ret;
+			in += ret;
+			inl -= ret;
+
+			if (ctx->copylen == 0)
+				ctx->state = ASN1_STATE_HEADER;
+			if (inl == 0)
+				goto done;
+			break;
+
+		default:
+			BIO_clear_retry_flags(b);
+			return 0;
+		}
+
+	}
+
+done:
+	BIO_clear_retry_flags(b);
+	BIO_copy_next_retry(b);
+
+	return (wrlen > 0) ? wrlen : ret;
+}
+
+static int
+asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, asn1_ps_func *cleanup,
+    asn1_bio_state_t next)
+{
+	int ret;
+
+	if (ctx->ex_len <= 0)
+		return 1;
+	for (;;) {
+		ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos,
+		    ctx->ex_len);
+		if (ret <= 0)
+			break;
+		ctx->ex_len -= ret;
+		if (ctx->ex_len > 0)
+			ctx->ex_pos += ret;
+		else {
+			if (cleanup)
+				cleanup(b, &ctx->ex_buf, &ctx->ex_len,
+				    &ctx->ex_arg);
+			ctx->state = next;
+			ctx->ex_pos = 0;
+			break;
+		}
+	}
+	return ret;
+}
+
+static int
+asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, asn1_ps_func *setup,
+    asn1_bio_state_t ex_state, asn1_bio_state_t other_state)
+{
+	if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg)) {
+		BIO_clear_retry_flags(b);
+		return 0;
+	}
+	if (ctx->ex_len > 0)
+		ctx->state = ex_state;
+	else
+		ctx->state = other_state;
+	return 1;
+}
+
+static int
+asn1_bio_read(BIO *b, char *in , int inl)
+{
+	if (!b->next_bio)
+		return 0;
+	return BIO_read(b->next_bio, in , inl);
+}
+
+static int
+asn1_bio_puts(BIO *b, const char *str)
+{
+	return asn1_bio_write(b, str, strlen(str));
+}
+
+static int
+asn1_bio_gets(BIO *b, char *str, int size)
+{
+	if (!b->next_bio)
+		return 0;
+	return BIO_gets(b->next_bio, str , size);
+}
+
+static long
+asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+	if (b->next_bio == NULL)
+		return (0);
+	return BIO_callback_ctrl(b->next_bio, cmd, fp);
+}
+
+static long
+asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
+{
+	BIO_ASN1_BUF_CTX *ctx;
+	BIO_ASN1_EX_FUNCS *ex_func;
+	long ret = 1;
+
+	ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
+	if (ctx == NULL)
+		return 0;
+	switch (cmd) {
+
+	case BIO_C_SET_PREFIX:
+		ex_func = arg2;
+		ctx->prefix = ex_func->ex_func;
+		ctx->prefix_free = ex_func->ex_free_func;
+		break;
+
+	case BIO_C_GET_PREFIX:
+		ex_func = arg2;
+		ex_func->ex_func = ctx->prefix;
+		ex_func->ex_free_func = ctx->prefix_free;
+		break;
+
+	case BIO_C_SET_SUFFIX:
+		ex_func = arg2;
+		ctx->suffix = ex_func->ex_func;
+		ctx->suffix_free = ex_func->ex_free_func;
+		break;
+
+	case BIO_C_GET_SUFFIX:
+		ex_func = arg2;
+		ex_func->ex_func = ctx->suffix;
+		ex_func->ex_free_func = ctx->suffix_free;
+		break;
+
+	case BIO_C_SET_EX_ARG:
+		ctx->ex_arg = arg2;
+		break;
+
+	case BIO_C_GET_EX_ARG:
+		*(void **)arg2 = ctx->ex_arg;
+		break;
+
+	case BIO_CTRL_FLUSH:
+		if (!b->next_bio)
+			return 0;
+
+		/* Call post function if possible */
+		if (ctx->state == ASN1_STATE_HEADER) {
+			if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
+			    ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
+				return 0;
+		}
+
+		if (ctx->state == ASN1_STATE_POST_COPY) {
+			ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
+			    ASN1_STATE_DONE);
+			if (ret <= 0)
+				return ret;
+		}
+
+		if (ctx->state == ASN1_STATE_DONE)
+			return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
+		else {
+			BIO_clear_retry_flags(b);
+			return 0;
+		}
+		break;
+
+
+	default:
+		if (!b->next_bio)
+			return 0;
+		return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
+
+	}
+
+	return ret;
+}
+
+static int
+asn1_bio_set_ex(BIO *b, int cmd, asn1_ps_func *ex_func, asn1_ps_func
+    *ex_free_func)
+{
+	BIO_ASN1_EX_FUNCS extmp;
+
+	extmp.ex_func = ex_func;
+	extmp.ex_free_func = ex_free_func;
+	return BIO_ctrl(b, cmd, 0, &extmp);
+}
+
+static int
+asn1_bio_get_ex(BIO *b, int cmd, asn1_ps_func **ex_func,
+    asn1_ps_func **ex_free_func)
+{
+	BIO_ASN1_EX_FUNCS extmp;
+	int ret;
+
+	ret = BIO_ctrl(b, cmd, 0, &extmp);
+	if (ret > 0) {
+		*ex_func = extmp.ex_func;
+		*ex_free_func = extmp.ex_free_func;
+	}
+	return ret;
+}
+
+int
+BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, asn1_ps_func *prefix_free)
+{
+	return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
+}
+
+int
+BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, asn1_ps_func **pprefix_free)
+{
+	return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
+}
+
+int
+BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, asn1_ps_func *suffix_free)
+{
+	return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
+}
+
+int
+BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_func **psuffix_free)
+{
+	return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
+}
diff --git a/crypto/libressl/crypto/asn1/bio_ndef.c b/crypto/libressl/crypto/asn1/bio_ndef.c
new file mode 100644
index 0000000000..589b6d72ae
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/bio_ndef.c
@@ -0,0 +1,243 @@
+/* $OpenBSD: bio_ndef.c,v 1.8 2014/06/12 15:49:27 deraadt Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+/* Experimental NDEF ASN1 BIO support routines */
+
+/* The usage is quite simple, initialize an ASN1 structure,
+ * get a BIO from it then any data written through the BIO
+ * will end up translated to approptiate format on the fly.
+ * The data is streamed out and does *not* need to be
+ * all held in memory at once.
+ *
+ * When the BIO is flushed the output is finalized and any
+ * signatures etc written out.
+ *
+ * The BIO is a 'proper' BIO and can handle non blocking I/O
+ * correctly.
+ *
+ * The usage is simple. The implementation is *not*...
+ */
+
+/* BIO support data stored in the ASN1 BIO ex_arg */
+
+typedef struct ndef_aux_st {
+	/* ASN1 structure this BIO refers to */
+	ASN1_VALUE *val;
+	const ASN1_ITEM *it;
+	/* Top of the BIO chain */
+	BIO *ndef_bio;
+	/* Output BIO */
+	BIO *out;
+	/* Boundary where content is inserted */
+	unsigned char **boundary;
+	/* DER buffer start */
+	unsigned char *derbuf;
+} NDEF_SUPPORT;
+
+static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+
+BIO *
+BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
+{
+	NDEF_SUPPORT *ndef_aux = NULL;
+	BIO *asn_bio = NULL;
+	const ASN1_AUX *aux = it->funcs;
+	ASN1_STREAM_ARG sarg;
+
+	if (!aux || !aux->asn1_cb) {
+		ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
+		return NULL;
+	}
+	ndef_aux = malloc(sizeof(NDEF_SUPPORT));
+	asn_bio = BIO_new(BIO_f_asn1());
+
+	/* ASN1 bio needs to be next to output BIO */
+
+	out = BIO_push(asn_bio, out);
+
+	if (!ndef_aux || !asn_bio || !out)
+		goto err;
+
+	BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
+	BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
+
+	/* Now let callback prepend any digest, cipher etc BIOs
+	 * ASN1 structure needs.
+	 */
+
+	sarg.out = out;
+	sarg.ndef_bio = NULL;
+	sarg.boundary = NULL;
+
+	if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
+		goto err;
+
+	ndef_aux->val = val;
+	ndef_aux->it = it;
+	ndef_aux->ndef_bio = sarg.ndef_bio;
+	ndef_aux->boundary = sarg.boundary;
+	ndef_aux->out = out;
+
+	BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
+
+	return sarg.ndef_bio;
+
+err:
+	BIO_free(asn_bio);
+	free(ndef_aux);
+	return NULL;
+}
+
+static int
+ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+{
+	NDEF_SUPPORT *ndef_aux;
+	unsigned char *p;
+	int derlen;
+
+	if (!parg)
+		return 0;
+
+	ndef_aux = *(NDEF_SUPPORT **)parg;
+
+	derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+	p = malloc(derlen);
+	ndef_aux->derbuf = p;
+	*pbuf = p;
+	derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
+
+	if (!*ndef_aux->boundary)
+		return 0;
+
+	*plen = *ndef_aux->boundary - *pbuf;
+
+	return 1;
+}
+
+static int
+ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+{
+	NDEF_SUPPORT *ndef_aux;
+
+	if (!parg)
+		return 0;
+
+	ndef_aux = *(NDEF_SUPPORT **)parg;
+
+	free(ndef_aux->derbuf);
+
+	ndef_aux->derbuf = NULL;
+	*pbuf = NULL;
+	*plen = 0;
+	return 1;
+}
+
+static int
+ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+{
+	NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
+	if (!ndef_prefix_free(b, pbuf, plen, parg))
+		return 0;
+	free(*pndef_aux);
+	*pndef_aux = NULL;
+	return 1;
+}
+
+static int
+ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+{
+	NDEF_SUPPORT *ndef_aux;
+	unsigned char *p;
+	int derlen;
+	const ASN1_AUX *aux;
+	ASN1_STREAM_ARG sarg;
+
+	if (!parg)
+		return 0;
+
+	ndef_aux = *(NDEF_SUPPORT **)parg;
+
+	aux = ndef_aux->it->funcs;
+
+	/* Finalize structures */
+	sarg.ndef_bio = ndef_aux->ndef_bio;
+	sarg.out = ndef_aux->out;
+	sarg.boundary = ndef_aux->boundary;
+	if (aux->asn1_cb(ASN1_OP_STREAM_POST,
+	    &ndef_aux->val, ndef_aux->it, &sarg) <= 0)
+		return 0;
+
+	derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+	p = malloc(derlen);
+	ndef_aux->derbuf = p;
+	*pbuf = p;
+	derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
+
+	if (!*ndef_aux->boundary)
+		return 0;
+	*pbuf = *ndef_aux->boundary;
+	*plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
+
+	return 1;
+}
diff --git a/crypto/libressl/crypto/asn1/charmap.h b/crypto/libressl/crypto/asn1/charmap.h
new file mode 100644
index 0000000000..5b9f21e4bf
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/charmap.h
@@ -0,0 +1,15 @@
+/* $OpenBSD$ */
+/* Auto generated with chartype.pl script.
+ * Mask of various character properties
+ */
+
+static const unsigned char char_type[] = {
+	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+	120, 0, 1, 40, 0, 0, 0, 16, 16, 16, 0, 25, 25, 16, 16, 16,
+	16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 9, 9, 16, 9, 16,
+	0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+	16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 0, 0, 0,
+	0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+	16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 2
+};
diff --git a/crypto/libressl/crypto/asn1/d2i_pr.c b/crypto/libressl/crypto/asn1/d2i_pr.c
new file mode 100644
index 0000000000..687947b79e
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/d2i_pr.c
@@ -0,0 +1,170 @@
+/* $OpenBSD: d2i_pr.c,v 1.13 2015/02/11 03:19:37 doug Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+
+#include "asn1_locl.h"
+
+EVP_PKEY *
+d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, long length)
+{
+	EVP_PKEY *ret;
+
+	if ((a == NULL) || (*a == NULL)) {
+		if ((ret = EVP_PKEY_new()) == NULL) {
+			ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_EVP_LIB);
+			return (NULL);
+		}
+	} else {
+		ret = *a;
+#ifndef OPENSSL_NO_ENGINE
+		if (ret->engine) {
+			ENGINE_finish(ret->engine);
+			ret->engine = NULL;
+		}
+#endif
+	}
+
+	if (!EVP_PKEY_set_type(ret, type)) {
+		ASN1err(ASN1_F_D2I_PRIVATEKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
+		goto err;
+	}
+
+	if (!ret->ameth->old_priv_decode ||
+	    !ret->ameth->old_priv_decode(ret, pp, length)) {
+		if (ret->ameth->priv_decode) {
+			PKCS8_PRIV_KEY_INFO *p8 = NULL;
+			p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, pp, length);
+			if (!p8)
+				goto err;
+			EVP_PKEY_free(ret);
+			ret = EVP_PKCS82PKEY(p8);
+			PKCS8_PRIV_KEY_INFO_free(p8);
+		} else {
+			ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
+			goto err;
+		}
+	}
+	if (a != NULL)
+		(*a) = ret;
+	return (ret);
+
+err:
+	if (a == NULL || *a != ret)
+		EVP_PKEY_free(ret);
+	return (NULL);
+}
+
+/* This works like d2i_PrivateKey() except it automatically works out the type */
+
+EVP_PKEY *
+d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, long length)
+{
+	STACK_OF(ASN1_TYPE) *inkey;
+	const unsigned char *p;
+	int keytype;
+
+	p = *pp;
+	/* Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE):
+	 * by analyzing it we can determine the passed structure: this
+	 * assumes the input is surrounded by an ASN1 SEQUENCE.
+	 */
+	inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
+	/* Since we only need to discern "traditional format" RSA and DSA
+	 * keys we can just count the elements.
+         */
+	if (sk_ASN1_TYPE_num(inkey) == 6)
+		keytype = EVP_PKEY_DSA;
+	else if (sk_ASN1_TYPE_num(inkey) == 4)
+		keytype = EVP_PKEY_EC;
+	else if (sk_ASN1_TYPE_num(inkey) == 3)  {
+		/* This seems to be PKCS8, not traditional format */
+		PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(
+		    NULL, pp, length);
+		EVP_PKEY *ret;
+
+		sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
+		if (!p8) {
+			ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,
+			    ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+			return NULL;
+		}
+		ret = EVP_PKCS82PKEY(p8);
+		PKCS8_PRIV_KEY_INFO_free(p8);
+		if (a) {
+			*a = ret;
+		}
+		return ret;
+	} else
+		keytype = EVP_PKEY_RSA;
+	sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
+	return d2i_PrivateKey(keytype, a, pp, length);
+}
diff --git a/crypto/libressl/crypto/asn1/d2i_pu.c b/crypto/libressl/crypto/asn1/d2i_pu.c
new file mode 100644
index 0000000000..b1f69bf5b6
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/d2i_pu.c
@@ -0,0 +1,136 @@
+/* $OpenBSD: d2i_pu.c,v 1.12 2014/07/11 08:44:47 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_DSA
+#include 
+#endif
+#ifndef OPENSSL_NO_EC
+#include 
+#endif
+#ifndef OPENSSL_NO_RSA
+#include 
+#endif
+
+EVP_PKEY *
+d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, long length)
+{
+	EVP_PKEY *ret;
+
+	if ((a == NULL) || (*a == NULL)) {
+		if ((ret = EVP_PKEY_new()) == NULL) {
+			ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB);
+			return (NULL);
+		}
+	} else
+		ret = *a;
+
+	if (!EVP_PKEY_set_type(ret, type)) {
+		ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB);
+		goto err;
+	}
+
+	switch (EVP_PKEY_id(ret)) {
+#ifndef OPENSSL_NO_RSA
+	case EVP_PKEY_RSA:
+		if ((ret->pkey.rsa = d2i_RSAPublicKey(NULL, pp, length)) ==
+		    NULL) {
+			ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
+			goto err;
+		}
+		break;
+#endif
+#ifndef OPENSSL_NO_DSA
+	case EVP_PKEY_DSA:
+		if (!d2i_DSAPublicKey(&(ret->pkey.dsa), pp, length)) {
+			ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
+			goto err;
+		}
+		break;
+#endif
+#ifndef OPENSSL_NO_EC
+	case EVP_PKEY_EC:
+		if (!o2i_ECPublicKey(&(ret->pkey.ec), pp, length)) {
+			ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
+			goto err;
+		}
+		break;
+#endif
+	default:
+		ASN1err(ASN1_F_D2I_PUBLICKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
+		goto err;
+		/* break; */
+	}
+	if (a != NULL)
+		(*a) = ret;
+	return (ret);
+
+err:
+	if (a == NULL || *a != ret)
+		EVP_PKEY_free(ret);
+	return (NULL);
+}
diff --git a/crypto/libressl/crypto/asn1/evp_asn1.c b/crypto/libressl/crypto/asn1/evp_asn1.c
new file mode 100644
index 0000000000..325ddccee7
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/evp_asn1.c
@@ -0,0 +1,201 @@
+/* $OpenBSD: evp_asn1.c,v 1.17 2015/09/30 18:41:06 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+int
+ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len)
+{
+	ASN1_STRING *os;
+
+	if ((os = ASN1_OCTET_STRING_new()) == NULL)
+		return (0);
+	if (!ASN1_STRING_set(os, data, len)) {
+		ASN1_OCTET_STRING_free(os);
+		return (0);
+	}
+	ASN1_TYPE_set(a, V_ASN1_OCTET_STRING, os);
+	return (1);
+}
+
+/* int max_len:  for returned value    */
+int
+ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data, int max_len)
+{
+	int ret, num;
+	unsigned char *p;
+
+	if ((a->type != V_ASN1_OCTET_STRING) ||
+	    (a->value.octet_string == NULL)) {
+		ASN1err(ASN1_F_ASN1_TYPE_GET_OCTETSTRING, ASN1_R_DATA_IS_WRONG);
+		return (-1);
+	}
+	p = ASN1_STRING_data(a->value.octet_string);
+	ret = ASN1_STRING_length(a->value.octet_string);
+	if (ret < max_len)
+		num = ret;
+	else
+		num = max_len;
+	memcpy(data, p, num);
+	return (ret);
+}
+
+int
+ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, unsigned char *data,
+    int len)
+{
+	int n, size;
+	ASN1_OCTET_STRING os, *osp;
+	ASN1_INTEGER in;
+	unsigned char *p;
+	unsigned char buf[32]; /* when they have 256bit longs,
+				* I'll be in trouble */
+	in.data = buf;
+	in.length = 32;
+	os.data = data;
+	os.type = V_ASN1_OCTET_STRING;
+	os.length = len;
+	ASN1_INTEGER_set(&in, num);
+	n = i2d_ASN1_INTEGER(&in, NULL);
+	n += i2d_ASN1_bytes((ASN1_STRING *)&os, NULL, V_ASN1_OCTET_STRING,
+	    V_ASN1_UNIVERSAL);
+
+	size = ASN1_object_size(1, n, V_ASN1_SEQUENCE);
+
+	if ((osp = ASN1_STRING_new()) == NULL)
+		return (0);
+	/* Grow the 'string' */
+	if (!ASN1_STRING_set(osp, NULL, size)) {
+		ASN1_STRING_free(osp);
+		return (0);
+	}
+
+	ASN1_STRING_length_set(osp, size);
+	p = ASN1_STRING_data(osp);
+
+	ASN1_put_object(&p, 1,n, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
+	i2d_ASN1_INTEGER(&in, &p);
+	i2d_ASN1_bytes((ASN1_STRING *)&os, &p, V_ASN1_OCTET_STRING,
+	    V_ASN1_UNIVERSAL);
+
+	ASN1_TYPE_set(a, V_ASN1_SEQUENCE, osp);
+	return (1);
+}
+
+/* we return the actual length..., num may be missing, in which
+ * case, set it to zero */
+/* int max_len:  for returned value    */
+int
+ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num, unsigned char *data,
+    int max_len)
+{
+	int ret = -1, n;
+	ASN1_INTEGER *ai = NULL;
+	ASN1_OCTET_STRING *os = NULL;
+	const unsigned char *p;
+	long length;
+	ASN1_const_CTX c;
+
+	if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL)) {
+		goto err;
+	}
+	p = ASN1_STRING_data(a->value.sequence);
+	length = ASN1_STRING_length(a->value.sequence);
+
+	c.pp = &p;
+	c.p = p;
+	c.max = p + length;
+	c.error = ASN1_R_DATA_IS_WRONG;
+
+	M_ASN1_D2I_start_sequence();
+	c.q = c.p;
+	if ((ai = d2i_ASN1_INTEGER(NULL, &c.p, c.slen)) == NULL)
+		goto err;
+	c.slen -= (c.p - c.q);
+	c.q = c.p;
+	if ((os = d2i_ASN1_OCTET_STRING(NULL, &c.p, c.slen)) == NULL)
+		goto err;
+	c.slen -= (c.p - c.q);
+	if (!M_ASN1_D2I_end_sequence())
+		goto err;
+
+	if (num != NULL)
+		*num = ASN1_INTEGER_get(ai);
+
+	ret = ASN1_STRING_length(os);
+	if (max_len > ret)
+		n = ret;
+	else
+		n = max_len;
+
+	if (data != NULL)
+		memcpy(data, ASN1_STRING_data(os), n);
+	if (0) {
+err:
+		ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING,
+		    ASN1_R_DATA_IS_WRONG);
+	}
+	ASN1_OCTET_STRING_free(os);
+	ASN1_INTEGER_free(ai);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/asn1/f_enum.c b/crypto/libressl/crypto/asn1/f_enum.c
new file mode 100644
index 0000000000..e5b270cd34
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/f_enum.c
@@ -0,0 +1,201 @@
+/* $OpenBSD: f_enum.c,v 1.13 2014/07/10 21:58:08 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+/* Based on a_int.c: equivalent ENUMERATED functions */
+
+int
+i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a)
+{
+	int i, n = 0;
+	static const char h[] = "0123456789ABCDEF";
+	char buf[2];
+
+	if (a == NULL)
+		return (0);
+
+	if (a->length == 0) {
+		if (BIO_write(bp, "00", 2) != 2)
+			goto err;
+		n = 2;
+	} else {
+		for (i = 0; i < a->length; i++) {
+			if ((i != 0) && (i % 35 == 0)) {
+				if (BIO_write(bp, "\\\n", 2) != 2)
+					goto err;
+				n += 2;
+			}
+			buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
+			buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
+			if (BIO_write(bp, buf, 2) != 2)
+				goto err;
+			n += 2;
+		}
+	}
+	return (n);
+
+err:
+	return (-1);
+}
+
+int
+a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
+{
+	int ret = 0;
+	int i, j,k, m,n, again, bufsize;
+	unsigned char *s = NULL, *sp;
+	unsigned char *bufp;
+	int first = 1;
+	size_t num = 0, slen = 0;
+
+	bs->type = V_ASN1_ENUMERATED;
+
+	bufsize = BIO_gets(bp, buf, size);
+	for (;;) {
+		if (bufsize < 1)
+			goto err_sl;
+		i = bufsize;
+		if (buf[i-1] == '\n')
+			buf[--i] = '\0';
+		if (i == 0)
+			goto err_sl;
+		if (buf[i-1] == '\r')
+			buf[--i] = '\0';
+		if (i == 0)
+			goto err_sl;
+		again = (buf[i - 1] == '\\');
+
+		for (j = 0; j < i; j++) {
+			if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
+			    ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
+			    ((buf[j] >= 'A') && (buf[j] <= 'F')))) {
+				i = j;
+				break;
+			}
+		}
+		buf[i] = '\0';
+		/* We have now cleared all the crap off the end of the
+		 * line */
+		if (i < 2)
+			goto err_sl;
+
+		bufp = (unsigned char *)buf;
+		if (first) {
+			first = 0;
+			if ((bufp[0] == '0') && (buf[1] == '0')) {
+				bufp += 2;
+				i -= 2;
+			}
+		}
+		k = 0;
+		i -= again;
+		if (i % 2 != 0) {
+			ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,
+			    ASN1_R_ODD_NUMBER_OF_CHARS);
+			goto err;
+		}
+		i /= 2;
+		if (num + i > slen) {
+			sp = realloc(s, num + i);
+			if (sp == NULL) {
+				ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,
+				    ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+			s = sp;
+			slen = num + i;
+		}
+		for (j = 0; j < i; j++, k += 2) {
+			for (n = 0; n < 2; n++) {
+				m = bufp[k + n];
+				if ((m >= '0') && (m <= '9'))
+					m -= '0';
+				else if ((m >= 'a') && (m <= 'f'))
+					m = m - 'a' + 10;
+				else if ((m >= 'A') && (m <= 'F'))
+					m = m - 'A' + 10;
+				else {
+					ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,
+					    ASN1_R_NON_HEX_CHARACTERS);
+					goto err;
+				}
+				s[num + j] <<= 4;
+				s[num + j] |= m;
+			}
+		}
+		num += i;
+		if (again)
+			bufsize = BIO_gets(bp, buf, size);
+		else
+			break;
+	}
+	bs->length = num;
+	bs->data = s;
+	return (1);
+
+err_sl:
+	ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ASN1_R_SHORT_LINE);
+err:
+	free(s);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/asn1/f_int.c b/crypto/libressl/crypto/asn1/f_int.c
new file mode 100644
index 0000000000..7b30dff86a
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/f_int.c
@@ -0,0 +1,204 @@
+/* $OpenBSD: f_int.c,v 1.16 2014/06/12 15:49:27 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+int
+i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a)
+{
+	int i, n = 0;
+	static const char h[] = "0123456789ABCDEF";
+	char buf[2];
+
+	if (a == NULL)
+		return (0);
+
+	if (a->type & V_ASN1_NEG) {
+		if (BIO_write(bp, "-", 1) != 1)
+			goto err;
+		n = 1;
+	}
+
+	if (a->length == 0) {
+		if (BIO_write(bp, "00", 2) != 2)
+			goto err;
+		n += 2;
+	} else {
+		for (i = 0; i < a->length; i++) {
+			if ((i != 0) && (i % 35 == 0)) {
+				if (BIO_write(bp, "\\\n", 2) != 2)
+					goto err;
+				n += 2;
+			}
+			buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
+			buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
+			if (BIO_write(bp, buf, 2) != 2)
+				goto err;
+			n += 2;
+		}
+	}
+	return (n);
+
+err:
+	return (-1);
+}
+
+int
+a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
+{
+	int ret = 0;
+	int i, j,k, m,n, again, bufsize;
+	unsigned char *s = NULL, *sp;
+	unsigned char *bufp;
+	int num = 0, slen = 0, first = 1;
+
+	bs->type = V_ASN1_INTEGER;
+
+	bufsize = BIO_gets(bp, buf, size);
+	for (;;) {
+		if (bufsize < 1)
+			goto err_sl;
+		i = bufsize;
+		if (buf[i - 1] == '\n')
+			buf[--i] = '\0';
+		if (i == 0)
+			goto err_sl;
+		if (buf[i - 1] == '\r')
+			buf[--i] = '\0';
+		if (i == 0)
+			goto err_sl;
+		again = (buf[i - 1] == '\\');
+
+		for (j = 0; j < i; j++) {
+			if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
+			    ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
+			    ((buf[j] >= 'A') && (buf[j] <= 'F')))) {
+				i = j;
+				break;
+			}
+		}
+		buf[i] = '\0';
+		/* We have now cleared all the crap off the end of the
+		 * line */
+		if (i < 2)
+			goto err_sl;
+
+		bufp = (unsigned char *)buf;
+		if (first) {
+			first = 0;
+			if ((bufp[0] == '0') && (buf[1] == '0')) {
+				bufp += 2;
+				i -= 2;
+			}
+		}
+		k = 0;
+		i -= again;
+		if (i % 2 != 0) {
+			ASN1err(ASN1_F_A2I_ASN1_INTEGER,
+			    ASN1_R_ODD_NUMBER_OF_CHARS);
+			goto err;
+		}
+		i /= 2;
+		if (num + i > slen) {
+			sp = OPENSSL_realloc_clean(s, slen, num + i);
+			if (sp == NULL) {
+				ASN1err(ASN1_F_A2I_ASN1_INTEGER,
+				    ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+			s = sp;
+			slen = num + i;
+		}
+		for (j = 0; j < i; j++, k += 2) {
+			for (n = 0; n < 2; n++) {
+				m = bufp[k + n];
+				if ((m >= '0') && (m <= '9'))
+					m -= '0';
+				else if ((m >= 'a') && (m <= 'f'))
+					m = m - 'a' + 10;
+				else if ((m >= 'A') && (m <= 'F'))
+					m = m - 'A' + 10;
+				else {
+					ASN1err(ASN1_F_A2I_ASN1_INTEGER,
+					    ASN1_R_NON_HEX_CHARACTERS);
+					goto err;
+				}
+				s[num + j] <<= 4;
+				s[num + j] |= m;
+			}
+		}
+		num += i;
+		if (again)
+			bufsize = BIO_gets(bp, buf, size);
+		else
+			break;
+	}
+	bs->length = num;
+	bs->data = s;
+	return (1);
+
+err_sl:
+	ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_SHORT_LINE);
+err:
+	free(s);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/asn1/f_string.c b/crypto/libressl/crypto/asn1/f_string.c
new file mode 100644
index 0000000000..ed8f465afd
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/f_string.c
@@ -0,0 +1,197 @@
+/* $OpenBSD: f_string.c,v 1.15 2014/07/10 21:58:08 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+int
+i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type)
+{
+	int i, n = 0;
+	static const char h[] = "0123456789ABCDEF";
+	char buf[2];
+
+	if (a == NULL)
+		return (0);
+
+	if (a->length == 0) {
+		if (BIO_write(bp, "0", 1) != 1)
+			goto err;
+		n = 1;
+	} else {
+		for (i = 0; i < a->length; i++) {
+			if ((i != 0) && (i % 35 == 0)) {
+				if (BIO_write(bp, "\\\n", 2) != 2)
+					goto err;
+				n += 2;
+			}
+			buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
+			buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
+			if (BIO_write(bp, buf, 2) != 2)
+				goto err;
+			n += 2;
+		}
+	}
+	return (n);
+
+err:
+	return (-1);
+}
+
+int
+a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
+{
+	int ret = 0;
+	int i, j, k, m, n, again, bufsize;
+	unsigned char *s = NULL, *sp;
+	unsigned char *bufp;
+	int first = 1;
+	size_t num = 0, slen = 0;
+
+	bufsize = BIO_gets(bp, buf, size);
+	for (;;) {
+		if (bufsize < 1) {
+			if (first)
+				break;
+			else
+				goto err_sl;
+		}
+		first = 0;
+
+		i = bufsize;
+		if (buf[i-1] == '\n')
+			buf[--i] = '\0';
+		if (i == 0)
+			goto err_sl;
+		if (buf[i-1] == '\r')
+			buf[--i] = '\0';
+		if (i == 0)
+			goto err_sl;
+		again = (buf[i - 1] == '\\');
+
+		for (j = i - 1; j > 0; j--) {
+			if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
+			    ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
+			    ((buf[j] >= 'A') && (buf[j] <= 'F')))) {
+				i = j;
+				break;
+			}
+		}
+		buf[i] = '\0';
+		/* We have now cleared all the crap off the end of the
+		 * line */
+		if (i < 2)
+			goto err_sl;
+
+		bufp = (unsigned char *)buf;
+
+		k = 0;
+		i -= again;
+		if (i % 2 != 0) {
+			ASN1err(ASN1_F_A2I_ASN1_STRING,
+			    ASN1_R_ODD_NUMBER_OF_CHARS);
+			goto err;
+		}
+		i /= 2;
+		if (num + i > slen) {
+			sp = realloc(s, num + i);
+			if (sp == NULL) {
+				ASN1err(ASN1_F_A2I_ASN1_STRING,
+				    ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+			s = sp;
+			slen = num + i;
+		}
+		for (j = 0; j < i; j++, k += 2) {
+			for (n = 0; n < 2; n++) {
+				m = bufp[k + n];
+				if ((m >= '0') && (m <= '9'))
+					m -= '0';
+				else if ((m >= 'a') && (m <= 'f'))
+					m = m - 'a' + 10;
+				else if ((m >= 'A') && (m <= 'F'))
+					m = m - 'A' + 10;
+				else {
+					ASN1err(ASN1_F_A2I_ASN1_STRING,
+					    ASN1_R_NON_HEX_CHARACTERS);
+					goto err;
+				}
+				s[num + j] <<= 4;
+				s[num + j] |= m;
+			}
+		}
+		num += i;
+		if (again)
+			bufsize = BIO_gets(bp, buf, size);
+		else
+			break;
+	}
+	bs->length = num;
+	bs->data = s;
+	return (1);
+
+err_sl:
+	ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_SHORT_LINE);
+err:
+	free(s);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/asn1/i2d_pr.c b/crypto/libressl/crypto/asn1/i2d_pr.c
new file mode 100644
index 0000000000..54274f92c8
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/i2d_pr.c
@@ -0,0 +1,81 @@
+/* $OpenBSD: i2d_pr.c,v 1.9 2014/06/12 15:49:27 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include "asn1_locl.h"
+
+int
+i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
+{
+	if (a->ameth && a->ameth->old_priv_encode) {
+		return a->ameth->old_priv_encode(a, pp);
+	}
+	if (a->ameth && a->ameth->priv_encode) {
+		PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a);
+		int ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp);
+		PKCS8_PRIV_KEY_INFO_free(p8);
+		return ret;
+	}
+	ASN1err(ASN1_F_I2D_PRIVATEKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+	return (-1);
+}
diff --git a/crypto/libressl/crypto/asn1/i2d_pu.c b/crypto/libressl/crypto/asn1/i2d_pu.c
new file mode 100644
index 0000000000..1f4909f207
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/i2d_pu.c
@@ -0,0 +1,98 @@
+/* $OpenBSD: i2d_pu.c,v 1.9 2014/07/10 22:45:56 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_DSA
+#include 
+#endif
+#ifndef OPENSSL_NO_EC
+#include 
+#endif
+#ifndef OPENSSL_NO_RSA
+#include 
+#endif
+
+int
+i2d_PublicKey(EVP_PKEY *a, unsigned char **pp)
+{
+	switch (a->type) {
+#ifndef OPENSSL_NO_RSA
+	case EVP_PKEY_RSA:
+		return (i2d_RSAPublicKey(a->pkey.rsa, pp));
+#endif
+#ifndef OPENSSL_NO_DSA
+	case EVP_PKEY_DSA:
+		return (i2d_DSAPublicKey(a->pkey.dsa, pp));
+#endif
+#ifndef OPENSSL_NO_EC
+	case EVP_PKEY_EC:
+		return (i2o_ECPublicKey(a->pkey.ec, pp));
+#endif
+	default:
+		ASN1err(ASN1_F_I2D_PUBLICKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+		return (-1);
+	}
+}
diff --git a/crypto/libressl/crypto/asn1/n_pkey.c b/crypto/libressl/crypto/asn1/n_pkey.c
new file mode 100644
index 0000000000..4fe9f8612a
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/n_pkey.c
@@ -0,0 +1,434 @@
+/* $OpenBSD: n_pkey.c,v 1.29 2015/10/16 15:12:30 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_RSA
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_RC4
+
+typedef struct netscape_pkey_st {
+	long version;
+	X509_ALGOR *algor;
+	ASN1_OCTET_STRING *private_key;
+} NETSCAPE_PKEY;
+
+typedef struct netscape_encrypted_pkey_st {
+	ASN1_OCTET_STRING *os;
+	/* This is the same structure as DigestInfo so use it:
+	 * although this isn't really anything to do with
+	 * digests.
+	 */
+	X509_SIG *enckey;
+} NETSCAPE_ENCRYPTED_PKEY;
+
+
+static const ASN1_AUX NETSCAPE_ENCRYPTED_PKEY_aux = {
+	.flags = ASN1_AFLG_BROKEN,
+};
+static const ASN1_TEMPLATE NETSCAPE_ENCRYPTED_PKEY_seq_tt[] = {
+	{
+		.offset = offsetof(NETSCAPE_ENCRYPTED_PKEY, os),
+		.field_name = "os",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+	{
+		.offset = offsetof(NETSCAPE_ENCRYPTED_PKEY, enckey),
+		.field_name = "enckey",
+		.item = &X509_SIG_it,
+	},
+};
+
+const ASN1_ITEM NETSCAPE_ENCRYPTED_PKEY_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = NETSCAPE_ENCRYPTED_PKEY_seq_tt,
+	.tcount = sizeof(NETSCAPE_ENCRYPTED_PKEY_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &NETSCAPE_ENCRYPTED_PKEY_aux,
+	.size = sizeof(NETSCAPE_ENCRYPTED_PKEY),
+	.sname = "NETSCAPE_ENCRYPTED_PKEY",
+};
+
+NETSCAPE_ENCRYPTED_PKEY *NETSCAPE_ENCRYPTED_PKEY_new(void);
+void NETSCAPE_ENCRYPTED_PKEY_free(NETSCAPE_ENCRYPTED_PKEY *a);
+NETSCAPE_ENCRYPTED_PKEY *d2i_NETSCAPE_ENCRYPTED_PKEY(NETSCAPE_ENCRYPTED_PKEY **a, const unsigned char **in, long len);
+int i2d_NETSCAPE_ENCRYPTED_PKEY(const NETSCAPE_ENCRYPTED_PKEY *a, unsigned char **out);
+
+NETSCAPE_ENCRYPTED_PKEY *
+d2i_NETSCAPE_ENCRYPTED_PKEY(NETSCAPE_ENCRYPTED_PKEY **a, const unsigned char **in, long len)
+{
+	return (NETSCAPE_ENCRYPTED_PKEY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &NETSCAPE_ENCRYPTED_PKEY_it);
+}
+
+int
+i2d_NETSCAPE_ENCRYPTED_PKEY(const NETSCAPE_ENCRYPTED_PKEY *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &NETSCAPE_ENCRYPTED_PKEY_it);
+}
+
+NETSCAPE_ENCRYPTED_PKEY *
+NETSCAPE_ENCRYPTED_PKEY_new(void)
+{
+	return (NETSCAPE_ENCRYPTED_PKEY *)ASN1_item_new(&NETSCAPE_ENCRYPTED_PKEY_it);
+}
+
+void
+NETSCAPE_ENCRYPTED_PKEY_free(NETSCAPE_ENCRYPTED_PKEY *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &NETSCAPE_ENCRYPTED_PKEY_it);
+}
+
+static const ASN1_TEMPLATE NETSCAPE_PKEY_seq_tt[] = {
+	{
+		.offset = offsetof(NETSCAPE_PKEY, version),
+		.field_name = "version",
+		.item = &LONG_it,
+	},
+	{
+		.offset = offsetof(NETSCAPE_PKEY, algor),
+		.field_name = "algor",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.offset = offsetof(NETSCAPE_PKEY, private_key),
+		.field_name = "private_key",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+};
+
+const ASN1_ITEM NETSCAPE_PKEY_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = NETSCAPE_PKEY_seq_tt,
+	.tcount = sizeof(NETSCAPE_PKEY_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.size = sizeof(NETSCAPE_PKEY),
+	.sname = "NETSCAPE_PKEY",
+};
+
+NETSCAPE_PKEY *NETSCAPE_PKEY_new(void);
+void NETSCAPE_PKEY_free(NETSCAPE_PKEY *a);
+NETSCAPE_PKEY *d2i_NETSCAPE_PKEY(NETSCAPE_PKEY **a, const unsigned char **in, long len);
+int i2d_NETSCAPE_PKEY(const NETSCAPE_PKEY *a, unsigned char **out);
+
+NETSCAPE_PKEY *
+d2i_NETSCAPE_PKEY(NETSCAPE_PKEY **a, const unsigned char **in, long len)
+{
+	return (NETSCAPE_PKEY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &NETSCAPE_PKEY_it);
+}
+
+int
+i2d_NETSCAPE_PKEY(const NETSCAPE_PKEY *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &NETSCAPE_PKEY_it);
+}
+
+NETSCAPE_PKEY *
+NETSCAPE_PKEY_new(void)
+{
+	return (NETSCAPE_PKEY *)ASN1_item_new(&NETSCAPE_PKEY_it);
+}
+
+void
+NETSCAPE_PKEY_free(NETSCAPE_PKEY *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &NETSCAPE_PKEY_it);
+}
+
+static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
+    int (*cb)(char *buf, int len, const char *prompt, int verify), int sgckey);
+
+int
+i2d_Netscape_RSA(const RSA *a, unsigned char **pp,
+    int (*cb)(char *buf, int len, const char *prompt, int verify))
+{
+	return i2d_RSA_NET(a, pp, cb, 0);
+}
+
+int
+i2d_RSA_NET(const RSA *a, unsigned char **pp,
+    int (*cb)(char *buf, int len, const char *prompt, int verify), int sgckey)
+{
+	int i, j, ret = 0;
+	int rsalen, pkeylen, olen;
+	NETSCAPE_PKEY *pkey = NULL;
+	NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
+	unsigned char buf[256], *zz;
+	unsigned char key[EVP_MAX_KEY_LENGTH];
+	EVP_CIPHER_CTX ctx;
+	EVP_CIPHER_CTX_init(&ctx);
+
+	if (a == NULL)
+		return (0);
+
+	if ((pkey = NETSCAPE_PKEY_new()) == NULL)
+		goto err;
+	if ((enckey = NETSCAPE_ENCRYPTED_PKEY_new()) == NULL)
+		goto err;
+	pkey->version = 0;
+
+	pkey->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
+	if ((pkey->algor->parameter = ASN1_TYPE_new()) == NULL)
+		goto err;
+	pkey->algor->parameter->type = V_ASN1_NULL;
+
+	rsalen = i2d_RSAPrivateKey(a, NULL);
+
+	/* Fake some octet strings just for the initial length
+	 * calculation.
+ 	 */
+	pkey->private_key->length = rsalen;
+	pkeylen = i2d_NETSCAPE_PKEY(pkey, NULL);
+	enckey->enckey->digest->length = pkeylen;
+	enckey->os->length = 11;	/* "private-key" */
+	enckey->enckey->algor->algorithm = OBJ_nid2obj(NID_rc4);
+	if ((enckey->enckey->algor->parameter = ASN1_TYPE_new()) == NULL)
+		goto err;
+	enckey->enckey->algor->parameter->type = V_ASN1_NULL;
+
+	if (pp == NULL) {
+		olen = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, NULL);
+		NETSCAPE_PKEY_free(pkey);
+		NETSCAPE_ENCRYPTED_PKEY_free(enckey);
+		return olen;
+	}
+
+	/* Since its RC4 encrypted length is actual length */
+	if ((zz = malloc(rsalen)) == NULL) {
+		ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	pkey->private_key->data = zz;
+	/* Write out private key encoding */
+	i2d_RSAPrivateKey(a, &zz);
+
+	if ((zz = malloc(pkeylen)) == NULL) {
+		ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	if (!ASN1_STRING_set(enckey->os, "private-key", -1)) {
+		ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	enckey->enckey->digest->data = zz;
+	i2d_NETSCAPE_PKEY(pkey, &zz);
+
+	/* Wipe the private key encoding */
+	explicit_bzero(pkey->private_key->data, rsalen);
+
+	if (cb == NULL)
+		cb = EVP_read_pw_string;
+	i = cb((char *)buf, sizeof(buf), "Enter Private Key password:", 1);
+	if (i != 0) {
+		ASN1err(ASN1_F_I2D_RSA_NET, ASN1_R_BAD_PASSWORD_READ);
+		goto err;
+	}
+	i = strlen((char *)buf);
+	/* If the key is used for SGC the algorithm is modified a little. */
+	if (sgckey) {
+		if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
+			goto err;
+		memcpy(buf + 16, "SGCKEYSALT", 10);
+		i = 26;
+	}
+
+	if (!EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i,1, key, NULL))
+		goto err;
+	explicit_bzero(buf, sizeof(buf));
+
+	/* Encrypt private key in place */
+	zz = enckey->enckey->digest->data;
+	if (!EVP_EncryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL))
+		goto err;
+	if (!EVP_EncryptUpdate(&ctx, zz, &i, zz, pkeylen))
+		goto err;
+	if (!EVP_EncryptFinal_ex(&ctx, zz + i, &j))
+		goto err;
+
+	ret = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, pp);
+err:
+	EVP_CIPHER_CTX_cleanup(&ctx);
+	NETSCAPE_ENCRYPTED_PKEY_free(enckey);
+	NETSCAPE_PKEY_free(pkey);
+	return (ret);
+}
+
+
+RSA *
+d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
+    int (*cb)(char *buf, int len, const char *prompt, int verify))
+{
+	return d2i_RSA_NET(a, pp, length, cb, 0);
+}
+
+RSA *
+d2i_RSA_NET(RSA **a, const unsigned char **pp, long length,
+    int (*cb)(char *buf, int len, const char *prompt, int verify), int sgckey)
+{
+	RSA *ret = NULL;
+	const unsigned char *p;
+	NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
+
+	p = *pp;
+
+	enckey = d2i_NETSCAPE_ENCRYPTED_PKEY(NULL, &p, length);
+	if (!enckey) {
+		ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_DECODING_ERROR);
+		return NULL;
+	}
+
+	/* XXX 11 == strlen("private-key") */
+	if (enckey->os->length != 11 ||
+	    memcmp("private-key", enckey->os->data, 11) != 0) {
+		ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_PRIVATE_KEY_HEADER_MISSING);
+		goto err;
+	}
+	if (OBJ_obj2nid(enckey->enckey->algor->algorithm) != NID_rc4) {
+		ASN1err(ASN1_F_D2I_RSA_NET,
+		    ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM);
+		goto err;
+	}
+	if (cb == NULL)
+		cb = EVP_read_pw_string;
+	if ((ret = d2i_RSA_NET_2(a, enckey->enckey->digest, cb,
+	    sgckey)) == NULL)
+		goto err;
+
+	*pp = p;
+
+err:
+	NETSCAPE_ENCRYPTED_PKEY_free(enckey);
+	return ret;
+
+}
+
+static RSA *
+d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
+    int (*cb)(char *buf, int len, const char *prompt, int verify), int sgckey)
+{
+	NETSCAPE_PKEY *pkey = NULL;
+	RSA *ret = NULL;
+	int i, j;
+	unsigned char buf[256];
+	const unsigned char *zz;
+	unsigned char key[EVP_MAX_KEY_LENGTH];
+	EVP_CIPHER_CTX ctx;
+	EVP_CIPHER_CTX_init(&ctx);
+
+	i=cb((char *)buf, sizeof(buf), "Enter Private Key password:",0);
+	if (i != 0) {
+		ASN1err(ASN1_F_D2I_RSA_NET_2, ASN1_R_BAD_PASSWORD_READ);
+		goto err;
+	}
+
+	i = strlen((char *)buf);
+	if (sgckey){
+		if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
+			goto err;
+		memcpy(buf + 16, "SGCKEYSALT", 10);
+		i = 26;
+	}
+
+	if (!EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i,1, key, NULL))
+		goto err;
+	explicit_bzero(buf, sizeof(buf));
+
+	if (!EVP_DecryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL))
+		goto err;
+	if (!EVP_DecryptUpdate(&ctx, os->data, &i, os->data, os->length))
+		goto err;
+	if (!EVP_DecryptFinal_ex(&ctx, &(os->data[i]), &j))
+		goto err;
+	os->length = i + j;
+
+	zz = os->data;
+
+	if ((pkey = d2i_NETSCAPE_PKEY(NULL, &zz, os->length)) == NULL) {
+		ASN1err(ASN1_F_D2I_RSA_NET_2,
+		    ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY);
+		goto err;
+	}
+
+	zz = pkey->private_key->data;
+	if ((ret = d2i_RSAPrivateKey(a, &zz,
+	    pkey->private_key->length)) == NULL) {
+		ASN1err(ASN1_F_D2I_RSA_NET_2, ASN1_R_UNABLE_TO_DECODE_RSA_KEY);
+		goto err;
+	}
+
+err:
+	EVP_CIPHER_CTX_cleanup(&ctx);
+	NETSCAPE_PKEY_free(pkey);
+	return (ret);
+}
+
+#endif /* OPENSSL_NO_RC4 */
+
+#endif
diff --git a/crypto/libressl/crypto/asn1/nsseq.c b/crypto/libressl/crypto/asn1/nsseq.c
new file mode 100644
index 0000000000..a1fe8ad595
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/nsseq.c
@@ -0,0 +1,129 @@
+/* $OpenBSD: nsseq.c,v 1.9 2015/02/11 03:39:51 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int
+nsseq_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
+{
+	if (operation == ASN1_OP_NEW_POST) {
+		NETSCAPE_CERT_SEQUENCE *nsseq;
+		nsseq = (NETSCAPE_CERT_SEQUENCE *)*pval;
+		nsseq->type = OBJ_nid2obj(NID_netscape_cert_sequence);
+	}
+	return 1;
+}
+
+/* Netscape certificate sequence structure */
+
+static const ASN1_AUX NETSCAPE_CERT_SEQUENCE_aux = {
+	.asn1_cb = nsseq_cb,
+};
+static const ASN1_TEMPLATE NETSCAPE_CERT_SEQUENCE_seq_tt[] = {
+	{
+		.offset = offsetof(NETSCAPE_CERT_SEQUENCE, type),
+		.field_name = "type",
+		.item = &ASN1_OBJECT_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
+		.offset = offsetof(NETSCAPE_CERT_SEQUENCE, certs),
+		.field_name = "certs",
+		.item = &X509_it,
+	},
+};
+
+const ASN1_ITEM NETSCAPE_CERT_SEQUENCE_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = NETSCAPE_CERT_SEQUENCE_seq_tt,
+	.tcount = sizeof(NETSCAPE_CERT_SEQUENCE_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &NETSCAPE_CERT_SEQUENCE_aux,
+	.size = sizeof(NETSCAPE_CERT_SEQUENCE),
+	.sname = "NETSCAPE_CERT_SEQUENCE",
+};
+
+
+NETSCAPE_CERT_SEQUENCE *
+d2i_NETSCAPE_CERT_SEQUENCE(NETSCAPE_CERT_SEQUENCE **a, const unsigned char **in, long len)
+{
+	return (NETSCAPE_CERT_SEQUENCE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &NETSCAPE_CERT_SEQUENCE_it);
+}
+
+int
+i2d_NETSCAPE_CERT_SEQUENCE(NETSCAPE_CERT_SEQUENCE *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &NETSCAPE_CERT_SEQUENCE_it);
+}
+
+NETSCAPE_CERT_SEQUENCE *
+NETSCAPE_CERT_SEQUENCE_new(void)
+{
+	return (NETSCAPE_CERT_SEQUENCE *)ASN1_item_new(&NETSCAPE_CERT_SEQUENCE_it);
+}
+
+void
+NETSCAPE_CERT_SEQUENCE_free(NETSCAPE_CERT_SEQUENCE *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &NETSCAPE_CERT_SEQUENCE_it);
+}
diff --git a/crypto/libressl/crypto/asn1/p5_pbe.c b/crypto/libressl/crypto/asn1/p5_pbe.c
new file mode 100644
index 0000000000..1befa58097
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/p5_pbe.c
@@ -0,0 +1,186 @@
+/* $OpenBSD: p5_pbe.c,v 1.19 2015/02/11 03:39:51 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+/* PKCS#5 password based encryption structure */
+
+static const ASN1_TEMPLATE PBEPARAM_seq_tt[] = {
+	{
+		.offset = offsetof(PBEPARAM, salt),
+		.field_name = "salt",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+	{
+		.offset = offsetof(PBEPARAM, iter),
+		.field_name = "iter",
+		.item = &ASN1_INTEGER_it,
+	},
+};
+
+const ASN1_ITEM PBEPARAM_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = PBEPARAM_seq_tt,
+	.tcount = sizeof(PBEPARAM_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.size = sizeof(PBEPARAM),
+	.sname = "PBEPARAM",
+};
+
+
+PBEPARAM *
+d2i_PBEPARAM(PBEPARAM **a, const unsigned char **in, long len)
+{
+	return (PBEPARAM *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &PBEPARAM_it);
+}
+
+int
+i2d_PBEPARAM(PBEPARAM *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PBEPARAM_it);
+}
+
+PBEPARAM *
+PBEPARAM_new(void)
+{
+	return (PBEPARAM *)ASN1_item_new(&PBEPARAM_it);
+}
+
+void
+PBEPARAM_free(PBEPARAM *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &PBEPARAM_it);
+}
+
+
+/* Set an algorithm identifier for a PKCS#5 PBE algorithm */
+
+int
+PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
+    const unsigned char *salt, int saltlen)
+{
+	PBEPARAM *pbe = NULL;
+	ASN1_STRING *pbe_str = NULL;
+	unsigned char *sstr;
+
+	pbe = PBEPARAM_new();
+	if (!pbe) {
+		ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	if (iter <= 0)
+		iter = PKCS5_DEFAULT_ITER;
+	if (!ASN1_INTEGER_set(pbe->iter, iter)) {
+		ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	if (!saltlen)
+		saltlen = PKCS5_SALT_LEN;
+	if (!ASN1_STRING_set(pbe->salt, NULL, saltlen)) {
+		ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	sstr = ASN1_STRING_data(pbe->salt);
+	if (salt)
+		memcpy(sstr, salt, saltlen);
+	else
+		arc4random_buf(sstr, saltlen);
+
+	if (!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) {
+		ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	PBEPARAM_free(pbe);
+	pbe = NULL;
+
+	if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str))
+		return 1;
+
+err:
+	if (pbe != NULL)
+		PBEPARAM_free(pbe);
+	ASN1_STRING_free(pbe_str);
+	return 0;
+}
+
+/* Return an algorithm identifier for a PKCS#5 PBE algorithm */
+
+X509_ALGOR *
+PKCS5_pbe_set(int alg, int iter, const unsigned char *salt, int saltlen)
+{
+	X509_ALGOR *ret;
+	ret = X509_ALGOR_new();
+	if (!ret) {
+		ASN1err(ASN1_F_PKCS5_PBE_SET, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+
+	if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen))
+		return ret;
+
+	X509_ALGOR_free(ret);
+	return NULL;
+}
diff --git a/crypto/libressl/crypto/asn1/p5_pbev2.c b/crypto/libressl/crypto/asn1/p5_pbev2.c
new file mode 100644
index 0000000000..8fd3670fe1
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/p5_pbev2.c
@@ -0,0 +1,374 @@
+/* $OpenBSD: p5_pbev2.c,v 1.22 2015/09/30 17:30:15 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999-2004.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+/* PKCS#5 v2.0 password based encryption structures */
+
+static const ASN1_TEMPLATE PBE2PARAM_seq_tt[] = {
+	{
+		.offset = offsetof(PBE2PARAM, keyfunc),
+		.field_name = "keyfunc",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.offset = offsetof(PBE2PARAM, encryption),
+		.field_name = "encryption",
+		.item = &X509_ALGOR_it,
+	},
+};
+
+const ASN1_ITEM PBE2PARAM_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = PBE2PARAM_seq_tt,
+	.tcount = sizeof(PBE2PARAM_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.size = sizeof(PBE2PARAM),
+	.sname = "PBE2PARAM",
+};
+
+
+PBE2PARAM *
+d2i_PBE2PARAM(PBE2PARAM **a, const unsigned char **in, long len)
+{
+	return (PBE2PARAM *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &PBE2PARAM_it);
+}
+
+int
+i2d_PBE2PARAM(PBE2PARAM *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PBE2PARAM_it);
+}
+
+PBE2PARAM *
+PBE2PARAM_new(void)
+{
+	return (PBE2PARAM *)ASN1_item_new(&PBE2PARAM_it);
+}
+
+void
+PBE2PARAM_free(PBE2PARAM *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &PBE2PARAM_it);
+}
+
+static const ASN1_TEMPLATE PBKDF2PARAM_seq_tt[] = {
+	{
+		.offset = offsetof(PBKDF2PARAM, salt),
+		.field_name = "salt",
+		.item = &ASN1_ANY_it,
+	},
+	{
+		.offset = offsetof(PBKDF2PARAM, iter),
+		.field_name = "iter",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.offset = offsetof(PBKDF2PARAM, keylength),
+		.field_name = "keylength",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.offset = offsetof(PBKDF2PARAM, prf),
+		.field_name = "prf",
+		.item = &X509_ALGOR_it,
+	},
+};
+
+const ASN1_ITEM PBKDF2PARAM_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = PBKDF2PARAM_seq_tt,
+	.tcount = sizeof(PBKDF2PARAM_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.size = sizeof(PBKDF2PARAM),
+	.sname = "PBKDF2PARAM",
+};
+
+
+PBKDF2PARAM *
+d2i_PBKDF2PARAM(PBKDF2PARAM **a, const unsigned char **in, long len)
+{
+	return (PBKDF2PARAM *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &PBKDF2PARAM_it);
+}
+
+int
+i2d_PBKDF2PARAM(PBKDF2PARAM *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PBKDF2PARAM_it);
+}
+
+PBKDF2PARAM *
+PBKDF2PARAM_new(void)
+{
+	return (PBKDF2PARAM *)ASN1_item_new(&PBKDF2PARAM_it);
+}
+
+void
+PBKDF2PARAM_free(PBKDF2PARAM *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &PBKDF2PARAM_it);
+}
+
+/* Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm:
+ * yes I know this is horrible!
+ *
+ * Extended version to allow application supplied PRF NID and IV.
+ */
+
+X509_ALGOR *
+PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, unsigned char *salt,
+    int saltlen, unsigned char *aiv, int prf_nid)
+{
+	X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
+	int alg_nid, keylen;
+	EVP_CIPHER_CTX ctx;
+	unsigned char iv[EVP_MAX_IV_LENGTH];
+	PBE2PARAM *pbe2 = NULL;
+	ASN1_OBJECT *obj;
+
+	alg_nid = EVP_CIPHER_type(cipher);
+	if (alg_nid == NID_undef) {
+		ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
+		ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
+		goto err;
+	}
+	obj = OBJ_nid2obj(alg_nid);
+
+	if (!(pbe2 = PBE2PARAM_new()))
+		goto merr;
+
+	/* Setup the AlgorithmIdentifier for the encryption scheme */
+	scheme = pbe2->encryption;
+
+	scheme->algorithm = obj;
+	if (!(scheme->parameter = ASN1_TYPE_new()))
+		goto merr;
+
+	/* Create random IV */
+	if (EVP_CIPHER_iv_length(cipher)) {
+		if (aiv)
+			memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
+		else
+			arc4random_buf(iv, EVP_CIPHER_iv_length(cipher));
+	}
+
+	EVP_CIPHER_CTX_init(&ctx);
+
+	/* Dummy cipherinit to just setup the IV, and PRF */
+	if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0))
+		goto err;
+	if (EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
+		ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
+		ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
+		EVP_CIPHER_CTX_cleanup(&ctx);
+		goto err;
+	}
+	/* If prf NID unspecified see if cipher has a preference.
+	 * An error is OK here: just means use default PRF.
+	 */
+	if ((prf_nid == -1) &&
+	    EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) {
+		ERR_clear_error();
+		prf_nid = NID_hmacWithSHA1;
+	}
+	EVP_CIPHER_CTX_cleanup(&ctx);
+
+	/* If its RC2 then we'd better setup the key length */
+
+	if (alg_nid == NID_rc2_cbc)
+		keylen = EVP_CIPHER_key_length(cipher);
+	else
+		keylen = -1;
+
+	/* Setup keyfunc */
+
+	X509_ALGOR_free(pbe2->keyfunc);
+
+	pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen);
+
+	if (!pbe2->keyfunc)
+		goto merr;
+
+	/* Now set up top level AlgorithmIdentifier */
+
+	if (!(ret = X509_ALGOR_new()))
+		goto merr;
+	if (!(ret->parameter = ASN1_TYPE_new()))
+		goto merr;
+
+	ret->algorithm = OBJ_nid2obj(NID_pbes2);
+
+	/* Encode PBE2PARAM into parameter */
+
+	if (!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM),
+		&ret->parameter->value.sequence)) goto merr;
+	ret->parameter->type = V_ASN1_SEQUENCE;
+
+	PBE2PARAM_free(pbe2);
+	pbe2 = NULL;
+
+	return ret;
+
+merr:
+	ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ERR_R_MALLOC_FAILURE);
+
+err:
+	PBE2PARAM_free(pbe2);
+	/* Note 'scheme' is freed as part of pbe2 */
+	X509_ALGOR_free(kalg);
+	X509_ALGOR_free(ret);
+
+	return NULL;
+}
+
+X509_ALGOR *
+PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, unsigned char *salt,
+    int saltlen)
+{
+	return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1);
+}
+
+X509_ALGOR *
+PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, int prf_nid,
+    int keylen)
+{
+	X509_ALGOR *keyfunc = NULL;
+	PBKDF2PARAM *kdf = NULL;
+	ASN1_OCTET_STRING *osalt = NULL;
+
+	if (!(kdf = PBKDF2PARAM_new()))
+		goto merr;
+	if (!(osalt = ASN1_OCTET_STRING_new()))
+		goto merr;
+
+	kdf->salt->value.octet_string = osalt;
+	kdf->salt->type = V_ASN1_OCTET_STRING;
+
+	if (!saltlen)
+		saltlen = PKCS5_SALT_LEN;
+	if (!(osalt->data = malloc (saltlen)))
+		goto merr;
+
+	osalt->length = saltlen;
+
+	if (salt)
+		memcpy (osalt->data, salt, saltlen);
+	else
+		arc4random_buf(osalt->data, saltlen);
+
+	if (iter <= 0)
+		iter = PKCS5_DEFAULT_ITER;
+
+	if (!ASN1_INTEGER_set(kdf->iter, iter))
+		goto merr;
+
+	/* If have a key len set it up */
+
+	if (keylen > 0) {
+		if (!(kdf->keylength = ASN1_INTEGER_new()))
+			goto merr;
+		if (!ASN1_INTEGER_set(kdf->keylength, keylen))
+			goto merr;
+	}
+
+	/* prf can stay NULL if we are using hmacWithSHA1 */
+	if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1) {
+		kdf->prf = X509_ALGOR_new();
+		if (!kdf->prf)
+			goto merr;
+		X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid),
+		V_ASN1_NULL, NULL);
+	}
+
+	/* Finally setup the keyfunc structure */
+
+	keyfunc = X509_ALGOR_new();
+	if (!keyfunc)
+		goto merr;
+
+	keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);
+
+	/* Encode PBKDF2PARAM into parameter of pbe2 */
+
+	if (!(keyfunc->parameter = ASN1_TYPE_new()))
+		goto merr;
+
+	if (!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM),
+		&keyfunc->parameter->value.sequence))
+		goto merr;
+	keyfunc->parameter->type = V_ASN1_SEQUENCE;
+
+	PBKDF2PARAM_free(kdf);
+	return keyfunc;
+
+merr:
+	ASN1err(ASN1_F_PKCS5_PBKDF2_SET, ERR_R_MALLOC_FAILURE);
+	PBKDF2PARAM_free(kdf);
+	X509_ALGOR_free(keyfunc);
+	return NULL;
+}
diff --git a/crypto/libressl/crypto/asn1/p8_pkey.c b/crypto/libressl/crypto/asn1/p8_pkey.c
new file mode 100644
index 0000000000..9bbc6cb8b1
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/p8_pkey.c
@@ -0,0 +1,201 @@
+/* $OpenBSD: p8_pkey.c,v 1.16 2015/07/16 18:21:57 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+
+/* Minor tweak to operation: zero private key data */
+static int
+pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
+{
+	/* Since the structure must still be valid use ASN1_OP_FREE_PRE */
+	if (operation == ASN1_OP_FREE_PRE) {
+		PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval;
+		if (key->pkey != NULL &&
+		    key->pkey->type == V_ASN1_OCTET_STRING &&
+		    key->pkey->value.octet_string != NULL)
+			explicit_bzero(key->pkey->value.octet_string->data,
+			    key->pkey->value.octet_string->length);
+	}
+	return 1;
+}
+
+static const ASN1_AUX PKCS8_PRIV_KEY_INFO_aux = {
+	.asn1_cb = pkey_cb,
+};
+static const ASN1_TEMPLATE PKCS8_PRIV_KEY_INFO_seq_tt[] = {
+	{
+		.offset = offsetof(PKCS8_PRIV_KEY_INFO, version),
+		.field_name = "version",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.offset = offsetof(PKCS8_PRIV_KEY_INFO, pkeyalg),
+		.field_name = "pkeyalg",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.offset = offsetof(PKCS8_PRIV_KEY_INFO, pkey),
+		.field_name = "pkey",
+		.item = &ASN1_ANY_it,
+	},
+	{
+		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
+		.offset = offsetof(PKCS8_PRIV_KEY_INFO, attributes),
+		.field_name = "attributes",
+		.item = &X509_ATTRIBUTE_it,
+	},
+};
+
+const ASN1_ITEM PKCS8_PRIV_KEY_INFO_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = PKCS8_PRIV_KEY_INFO_seq_tt,
+	.tcount = sizeof(PKCS8_PRIV_KEY_INFO_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &PKCS8_PRIV_KEY_INFO_aux,
+	.size = sizeof(PKCS8_PRIV_KEY_INFO),
+	.sname = "PKCS8_PRIV_KEY_INFO",
+};
+
+
+PKCS8_PRIV_KEY_INFO *
+d2i_PKCS8_PRIV_KEY_INFO(PKCS8_PRIV_KEY_INFO **a, const unsigned char **in, long len)
+{
+	return (PKCS8_PRIV_KEY_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &PKCS8_PRIV_KEY_INFO_it);
+}
+
+int
+i2d_PKCS8_PRIV_KEY_INFO(PKCS8_PRIV_KEY_INFO *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS8_PRIV_KEY_INFO_it);
+}
+
+PKCS8_PRIV_KEY_INFO *
+PKCS8_PRIV_KEY_INFO_new(void)
+{
+	return (PKCS8_PRIV_KEY_INFO *)ASN1_item_new(&PKCS8_PRIV_KEY_INFO_it);
+}
+
+void
+PKCS8_PRIV_KEY_INFO_free(PKCS8_PRIV_KEY_INFO *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &PKCS8_PRIV_KEY_INFO_it);
+}
+
+int
+PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, int version,
+    int ptype, void *pval, unsigned char *penc, int penclen)
+{
+	unsigned char **ppenc = NULL;
+
+	if (version >= 0) {
+		if (!ASN1_INTEGER_set(priv->version, version))
+			return 0;
+	}
+	if (penc) {
+		int pmtype;
+		ASN1_OCTET_STRING *oct;
+		oct = ASN1_OCTET_STRING_new();
+		if (!oct)
+			return 0;
+		oct->data = penc;
+		ppenc = &oct->data;
+		oct->length = penclen;
+		if (priv->broken == PKCS8_NO_OCTET)
+			pmtype = V_ASN1_SEQUENCE;
+		else
+			pmtype = V_ASN1_OCTET_STRING;
+		ASN1_TYPE_set(priv->pkey, pmtype, oct);
+	}
+	if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval)) {
+		/* If call fails do not swallow 'enc' */
+		if (ppenc)
+			*ppenc = NULL;
+		return 0;
+	}
+	return 1;
+}
+
+int
+PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, const unsigned char **pk, int *ppklen,
+    X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8)
+{
+	if (ppkalg)
+		*ppkalg = p8->pkeyalg->algorithm;
+	if (p8->pkey->type == V_ASN1_OCTET_STRING) {
+		p8->broken = PKCS8_OK;
+		if (pk) {
+			*pk = p8->pkey->value.octet_string->data;
+			*ppklen = p8->pkey->value.octet_string->length;
+		}
+	} else if (p8->pkey->type == V_ASN1_SEQUENCE) {
+		p8->broken = PKCS8_NO_OCTET;
+		if (pk) {
+			*pk = p8->pkey->value.sequence->data;
+			*ppklen = p8->pkey->value.sequence->length;
+		}
+	} else
+		return 0;
+	if (pa)
+		*pa = p8->pkeyalg;
+	return 1;
+}
diff --git a/crypto/libressl/crypto/asn1/t_bitst.c b/crypto/libressl/crypto/asn1/t_bitst.c
new file mode 100644
index 0000000000..82c1919e07
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/t_bitst.c
@@ -0,0 +1,112 @@
+/* $OpenBSD: t_bitst.c,v 1.6 2014/07/10 13:58:22 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+
+int
+ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
+    BIT_STRING_BITNAME *tbl, int indent)
+{
+	BIT_STRING_BITNAME *bnam;
+	char first = 1;
+
+	BIO_printf(out, "%*s", indent, "");
+	for (bnam = tbl; bnam->lname; bnam++) {
+		if (ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
+			if (!first)
+				BIO_puts(out, ", ");
+			BIO_puts(out, bnam->lname);
+			first = 0;
+		}
+	}
+	BIO_puts(out, "\n");
+	return 1;
+}
+
+int
+ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
+    BIT_STRING_BITNAME *tbl)
+{
+	int bitnum;
+
+	bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
+	if (bitnum < 0)
+		return 0;
+	if (bs) {
+		if (!ASN1_BIT_STRING_set_bit(bs, bitnum, value))
+			return 0;
+	}
+	return 1;
+}
+
+int
+ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl)
+{
+	BIT_STRING_BITNAME *bnam;
+
+	for (bnam = tbl; bnam->lname; bnam++) {
+		if (!strcmp(bnam->sname, name) ||
+		    !strcmp(bnam->lname, name))
+			return bnam->bitnum;
+	}
+	return -1;
+}
diff --git a/crypto/libressl/crypto/asn1/t_crl.c b/crypto/libressl/crypto/asn1/t_crl.c
new file mode 100644
index 0000000000..d5483f7a1a
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/t_crl.c
@@ -0,0 +1,140 @@
+/* $OpenBSD: t_crl.c,v 1.15 2014/07/11 08:44:47 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+int
+X509_CRL_print_fp(FILE *fp, X509_CRL *x)
+{
+	BIO *b;
+	int ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL) {
+		X509err(X509_F_X509_CRL_PRINT_FP, ERR_R_BUF_LIB);
+		return (0);
+	}
+	BIO_set_fp(b, fp, BIO_NOCLOSE);
+	ret = X509_CRL_print(b, x);
+	BIO_free(b);
+	return (ret);
+}
+
+int
+X509_CRL_print(BIO *out, X509_CRL *x)
+{
+	STACK_OF(X509_REVOKED) *rev;
+	X509_REVOKED *r;
+	long l;
+	int i;
+	char *p;
+
+	BIO_printf(out, "Certificate Revocation List (CRL):\n");
+	l = X509_CRL_get_version(x);
+	BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l + 1, l);
+	i = OBJ_obj2nid(x->sig_alg->algorithm);
+	if (X509_signature_print(out, x->sig_alg, NULL) == 0)
+		goto err;
+	p = X509_NAME_oneline(X509_CRL_get_issuer(x), NULL, 0);
+	if (p == NULL)
+		goto err;
+	BIO_printf(out, "%8sIssuer: %s\n", "", p);
+	free(p);
+	BIO_printf(out, "%8sLast Update: ", "");
+	ASN1_TIME_print(out, X509_CRL_get_lastUpdate(x));
+	BIO_printf(out, "\n%8sNext Update: ", "");
+	if (X509_CRL_get_nextUpdate(x))
+		ASN1_TIME_print(out, X509_CRL_get_nextUpdate(x));
+	else
+		BIO_printf(out, "NONE");
+	BIO_printf(out, "\n");
+
+	X509V3_extensions_print(out, "CRL extensions",
+	    x->crl->extensions, 0, 8);
+
+	rev = X509_CRL_get_REVOKED(x);
+
+	if (sk_X509_REVOKED_num(rev) > 0)
+		BIO_printf(out, "Revoked Certificates:\n");
+	else
+		BIO_printf(out, "No Revoked Certificates.\n");
+
+	for (i = 0; i < sk_X509_REVOKED_num(rev); i++) {
+		r = sk_X509_REVOKED_value(rev, i);
+		BIO_printf(out, "    Serial Number: ");
+		i2a_ASN1_INTEGER(out, r->serialNumber);
+		BIO_printf(out, "\n        Revocation Date: ");
+		ASN1_TIME_print(out, r->revocationDate);
+		BIO_printf(out, "\n");
+		X509V3_extensions_print(out, "CRL entry extensions",
+		    r->extensions, 0, 8);
+	}
+	if (X509_signature_print(out, x->sig_alg, x->signature) == 0)
+		goto err;
+
+	return 1;
+
+err:
+	return 0;
+}
diff --git a/crypto/libressl/crypto/asn1/t_pkey.c b/crypto/libressl/crypto/asn1/t_pkey.c
new file mode 100644
index 0000000000..763a230a79
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/t_pkey.c
@@ -0,0 +1,114 @@
+/* $OpenBSD: t_pkey.c,v 1.15 2014/06/12 15:49:27 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+int
+ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
+    unsigned char *buf, int off)
+{
+	int n, i;
+	const char *neg;
+
+	if (num == NULL)
+		return (1);
+	neg = (BN_is_negative(num)) ? "-" : "";
+	if (!BIO_indent(bp, off, 128))
+		return 0;
+	if (BN_is_zero(num)) {
+		if (BIO_printf(bp, "%s 0\n", number) <= 0)
+			return 0;
+		return 1;
+	}
+
+	if (BN_num_bytes(num) <= BN_BYTES) {
+		if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg,
+		    (unsigned long)num->d[0], neg,
+		    (unsigned long)num->d[0]) <= 0)
+			return (0);
+	} else {
+		buf[0] = 0;
+		if (BIO_printf(bp, "%s%s", number,
+		    (neg[0] == '-') ? " (Negative)" : "") <= 0)
+			return (0);
+		n = BN_bn2bin(num, &buf[1]);
+
+		if (buf[1] & 0x80)
+			n++;
+		else
+			buf++;
+
+		for (i = 0; i < n; i++) {
+			if ((i % 15) == 0) {
+				if (BIO_puts(bp, "\n") <= 0 ||
+				    !BIO_indent(bp, off + 4, 128))
+					return 0;
+			}
+			if (BIO_printf(bp, "%02x%s", buf[i],
+			    ((i + 1) == n) ? "" : ":") <= 0)
+				return (0);
+		}
+		if (BIO_write(bp, "\n", 1) <= 0)
+			return (0);
+	}
+	return (1);
+}
diff --git a/crypto/libressl/crypto/asn1/t_req.c b/crypto/libressl/crypto/asn1/t_req.c
new file mode 100644
index 0000000000..b7f54a3010
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/t_req.c
@@ -0,0 +1,267 @@
+/* $OpenBSD: t_req.c,v 1.17 2014/07/11 08:44:47 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_DSA
+#include 
+#endif
+#ifndef OPENSSL_NO_RSA
+#include 
+#endif
+
+int
+X509_REQ_print_fp(FILE *fp, X509_REQ *x)
+{
+	BIO *b;
+	int ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL) {
+		X509err(X509_F_X509_REQ_PRINT_FP, ERR_R_BUF_LIB);
+		return (0);
+	}
+	BIO_set_fp(b, fp, BIO_NOCLOSE);
+	ret = X509_REQ_print(b, x);
+	BIO_free(b);
+	return (ret);
+}
+
+int
+X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,
+    unsigned long cflag)
+{
+	unsigned long l;
+	int i;
+	const char *neg;
+	X509_REQ_INFO *ri;
+	EVP_PKEY *pkey;
+	STACK_OF(X509_ATTRIBUTE) *sk;
+	STACK_OF(X509_EXTENSION) *exts;
+	char mlch = ' ';
+	int nmindent = 0;
+
+	if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
+		mlch = '\n';
+		nmindent = 12;
+	}
+
+	if (nmflags == X509_FLAG_COMPAT)
+		nmindent = 16;
+
+	ri = x->req_info;
+	if (!(cflag & X509_FLAG_NO_HEADER)) {
+		if (BIO_write(bp, "Certificate Request:\n", 21) <= 0)
+			goto err;
+		if (BIO_write(bp, "    Data:\n", 10) <= 0)
+
+			goto err;
+	}
+	if (!(cflag & X509_FLAG_NO_VERSION)) {
+		neg = (ri->version->type == V_ASN1_NEG_INTEGER) ? "-" : "";
+		l = 0;
+		for (i = 0; i < ri->version->length; i++) {
+			l <<= 8;
+			l += ri->version->data[i];
+		}
+		if (BIO_printf(bp, "%8sVersion: %s%lu (%s0x%lx)\n", "", neg,
+		    l, neg, l) <= 0)
+			goto err;
+	}
+	if (!(cflag & X509_FLAG_NO_SUBJECT)) {
+		if (BIO_printf(bp, "        Subject:%c", mlch) <= 0)
+			goto err;
+		if (X509_NAME_print_ex(bp, ri->subject, nmindent, nmflags) < 0)
+			goto err;
+		if (BIO_write(bp, "\n", 1) <= 0)
+			goto err;
+	}
+	if (!(cflag & X509_FLAG_NO_PUBKEY)) {
+		if (BIO_write(bp, "        Subject Public Key Info:\n",
+		    33) <= 0)
+			goto err;
+		if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
+			goto err;
+		if (i2a_ASN1_OBJECT(bp, ri->pubkey->algor->algorithm) <= 0)
+			goto err;
+		if (BIO_puts(bp, "\n") <= 0)
+			goto err;
+
+		pkey = X509_REQ_get_pubkey(x);
+		if (pkey == NULL) {
+			BIO_printf(bp, "%12sUnable to load Public Key\n", "");
+			ERR_print_errors(bp);
+		} else {
+			EVP_PKEY_print_public(bp, pkey, 16, NULL);
+			EVP_PKEY_free(pkey);
+		}
+	}
+
+	if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) {
+		/* may not be */
+		if (BIO_printf(bp, "%8sAttributes:\n", "") <= 0)
+			goto err;
+
+		sk = x->req_info->attributes;
+		if (sk_X509_ATTRIBUTE_num(sk) == 0) {
+			if (BIO_printf(bp, "%12sa0:00\n", "") <= 0)
+				goto err;
+		} else {
+			for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
+				ASN1_TYPE *at;
+				X509_ATTRIBUTE *a;
+				ASN1_BIT_STRING *bs = NULL;
+				ASN1_TYPE *t;
+				int j, type = 0, count = 1, ii = 0;
+
+				a = sk_X509_ATTRIBUTE_value(sk, i);
+				if (X509_REQ_extension_nid(
+				    OBJ_obj2nid(a->object)))
+					continue;
+				if (BIO_printf(bp, "%12s", "") <= 0)
+					goto err;
+				if ((j = i2a_ASN1_OBJECT(bp, a->object)) > 0) {
+					if (a->single) {
+						t = a->value.single;
+						type = t->type;
+						bs = t->value.bit_string;
+					} else {
+						ii = 0;
+						count = sk_ASN1_TYPE_num(
+						    a->value.set);
+get_next:
+						at = sk_ASN1_TYPE_value(
+						    a->value.set, ii);
+						type = at->type;
+						bs = at->value.asn1_string;
+					}
+				}
+				for (j = 25 - j; j > 0; j--)
+					if (BIO_write(bp, " ", 1) != 1)
+						goto err;
+				if (BIO_puts(bp, ":") <= 0)
+					goto err;
+				if ((type == V_ASN1_PRINTABLESTRING) ||
+				    (type == V_ASN1_T61STRING) ||
+				    (type == V_ASN1_IA5STRING)) {
+					if (BIO_write(bp, (char *)bs->data,
+					    bs->length) != bs->length)
+						goto err;
+					BIO_puts(bp, "\n");
+				} else {
+					BIO_puts(bp,
+					    "unable to print attribute\n");
+				}
+				if (++ii < count)
+					goto get_next;
+			}
+		}
+	}
+	if (!(cflag & X509_FLAG_NO_EXTENSIONS)) {
+		exts = X509_REQ_get_extensions(x);
+		if (exts) {
+			BIO_printf(bp, "%8sRequested Extensions:\n", "");
+			for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
+				ASN1_OBJECT *obj;
+				X509_EXTENSION *ex;
+				int j;
+				ex = sk_X509_EXTENSION_value(exts, i);
+				if (BIO_printf(bp, "%12s", "") <= 0)
+					goto err;
+				obj = X509_EXTENSION_get_object(ex);
+				i2a_ASN1_OBJECT(bp, obj);
+				j = X509_EXTENSION_get_critical(ex);
+				if (BIO_printf(bp, ": %s\n",
+				    j ? "critical" : "") <= 0)
+					goto err;
+				if (!X509V3_EXT_print(bp, ex, cflag, 16)) {
+					BIO_printf(bp, "%16s", "");
+					ASN1_STRING_print(bp, ex->value);
+				}
+				if (BIO_write(bp, "\n", 1) <= 0)
+					goto err;
+			}
+			sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+		}
+	}
+
+	if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
+		if (!X509_signature_print(bp, x->sig_alg, x->signature))
+			goto err;
+	}
+
+	return (1);
+
+err:
+	X509err(X509_F_X509_REQ_PRINT_EX, ERR_R_BUF_LIB);
+	return (0);
+}
+
+int
+X509_REQ_print(BIO *bp, X509_REQ *x)
+{
+	return X509_REQ_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+}
diff --git a/crypto/libressl/crypto/asn1/t_spki.c b/crypto/libressl/crypto/asn1/t_spki.c
new file mode 100644
index 0000000000..408de2a65a
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/t_spki.c
@@ -0,0 +1,112 @@
+/* $OpenBSD: t_spki.c,v 1.10 2014/07/10 22:45:56 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_DSA
+#include 
+#endif
+#ifndef OPENSSL_NO_RSA
+#include 
+#endif
+
+/* Print out an SPKI */
+
+int
+NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki)
+{
+	EVP_PKEY *pkey;
+	ASN1_IA5STRING *chal;
+	int i, n;
+	char *s;
+
+	BIO_printf(out, "Netscape SPKI:\n");
+	i = OBJ_obj2nid(spki->spkac->pubkey->algor->algorithm);
+	BIO_printf(out, "  Public Key Algorithm: %s\n",
+	    (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
+	pkey = X509_PUBKEY_get(spki->spkac->pubkey);
+	if (!pkey)
+		BIO_printf(out, "  Unable to load public key\n");
+	else {
+		EVP_PKEY_print_public(out, pkey, 4, NULL);
+		EVP_PKEY_free(pkey);
+	}
+	chal = spki->spkac->challenge;
+	if (chal->length)
+		BIO_printf(out, "  Challenge String: %s\n", chal->data);
+	i = OBJ_obj2nid(spki->sig_algor->algorithm);
+	BIO_printf(out, "  Signature Algorithm: %s",
+	    (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
+
+	n = spki->signature->length;
+	s = (char *)spki->signature->data;
+	for (i = 0; i < n; i++) {
+		if ((i % 18) == 0)
+			BIO_write(out, "\n      ", 7);
+		BIO_printf(out, "%02x%s", (unsigned char)s[i],
+		    ((i + 1) == n) ? "" : ":");
+	}
+	BIO_write(out, "\n", 1);
+	return 1;
+}
diff --git a/crypto/libressl/crypto/asn1/t_x509.c b/crypto/libressl/crypto/asn1/t_x509.c
new file mode 100644
index 0000000000..8b4e7fa4d2
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/t_x509.c
@@ -0,0 +1,537 @@
+/* $OpenBSD: t_x509.c,v 1.25 2014/07/12 16:33:25 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_DSA
+#include 
+#endif
+#ifndef OPENSSL_NO_EC
+#include 
+#endif
+#ifndef OPENSSL_NO_RSA
+#include 
+#endif
+
+#include "asn1_locl.h"
+
+int
+X509_print_fp(FILE *fp, X509 *x)
+{
+	return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+}
+
+int
+X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, unsigned long cflag)
+{
+	BIO *b;
+	int ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL) {
+		X509err(X509_F_X509_PRINT_EX_FP, ERR_R_BUF_LIB);
+		return (0);
+	}
+	BIO_set_fp(b, fp, BIO_NOCLOSE);
+	ret = X509_print_ex(b, x, nmflag, cflag);
+	BIO_free(b);
+	return (ret);
+}
+
+int
+X509_print(BIO *bp, X509 *x)
+{
+	return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+}
+
+int
+X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
+{
+	long l;
+	int ret = 0, i;
+	char *m = NULL, mlch = ' ';
+	int nmindent = 0;
+	X509_CINF *ci;
+	ASN1_INTEGER *bs;
+	EVP_PKEY *pkey = NULL;
+	const char *neg;
+
+	if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
+		mlch = '\n';
+		nmindent = 12;
+	}
+
+	if (nmflags == X509_FLAG_COMPAT)
+		nmindent = 16;
+
+	ci = x->cert_info;
+	if (!(cflag & X509_FLAG_NO_HEADER)) {
+		if (BIO_write(bp, "Certificate:\n", 13) <= 0)
+			goto err;
+		if (BIO_write(bp, "    Data:\n", 10) <= 0)
+			goto err;
+	}
+	if (!(cflag & X509_FLAG_NO_VERSION)) {
+		l = X509_get_version(x);
+		if (BIO_printf(bp, "%8sVersion: %lu (0x%lx)\n",
+		    "", l + 1, l) <= 0)
+			goto err;
+	}
+	if (!(cflag & X509_FLAG_NO_SERIAL)) {
+		if (BIO_write(bp, "        Serial Number:", 22) <= 0)
+			goto err;
+
+		bs = X509_get_serialNumber(x);
+		if (bs->length <= (int)sizeof(long)) {
+			l = ASN1_INTEGER_get(bs);
+			if (bs->type == V_ASN1_NEG_INTEGER) {
+				l = -l;
+				neg = "-";
+			} else
+				neg = "";
+			if (BIO_printf(bp, " %s%lu (%s0x%lx)\n",
+			    neg, l, neg, l) <= 0)
+				goto err;
+		} else {
+			neg = (bs->type == V_ASN1_NEG_INTEGER) ?
+			    " (Negative)" : "";
+			if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0)
+				goto err;
+			for (i = 0; i < bs->length; i++) {
+				if (BIO_printf(bp, "%02x%c", bs->data[i],
+				    ((i + 1 == bs->length) ? '\n' : ':')) <= 0)
+					goto err;
+			}
+		}
+
+	}
+
+	if (!(cflag & X509_FLAG_NO_SIGNAME)) {
+		if (X509_signature_print(bp, x->sig_alg, NULL) <= 0)
+			goto err;
+	}
+
+	if (!(cflag & X509_FLAG_NO_ISSUER)) {
+		if (BIO_printf(bp, "        Issuer:%c", mlch) <= 0)
+			goto err;
+		if (X509_NAME_print_ex(bp, X509_get_issuer_name(x),
+		    nmindent, nmflags) < 0)
+			goto err;
+		if (BIO_write(bp, "\n", 1) <= 0)
+			goto err;
+	}
+	if (!(cflag & X509_FLAG_NO_VALIDITY)) {
+		if (BIO_write(bp, "        Validity\n", 17) <= 0)
+			goto err;
+		if (BIO_write(bp, "            Not Before: ", 24) <= 0)
+			goto err;
+		if (!ASN1_TIME_print(bp, X509_get_notBefore(x)))
+			goto err;
+		if (BIO_write(bp, "\n            Not After : ", 25) <= 0)
+			goto err;
+		if (!ASN1_TIME_print(bp, X509_get_notAfter(x)))
+			goto err;
+		if (BIO_write(bp, "\n", 1) <= 0)
+			goto err;
+	}
+	if (!(cflag & X509_FLAG_NO_SUBJECT)) {
+		if (BIO_printf(bp, "        Subject:%c", mlch) <= 0)
+			goto err;
+		if (X509_NAME_print_ex(bp, X509_get_subject_name(x),
+		    nmindent, nmflags) < 0)
+			goto err;
+		if (BIO_write(bp, "\n", 1) <= 0)
+			goto err;
+	}
+	if (!(cflag & X509_FLAG_NO_PUBKEY)) {
+		if (BIO_write(bp, "        Subject Public Key Info:\n",
+		    33) <= 0)
+			goto err;
+		if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
+			goto err;
+		if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0)
+			goto err;
+		if (BIO_puts(bp, "\n") <= 0)
+			goto err;
+
+		pkey = X509_get_pubkey(x);
+		if (pkey == NULL) {
+			BIO_printf(bp, "%12sUnable to load Public Key\n", "");
+			ERR_print_errors(bp);
+		} else {
+			EVP_PKEY_print_public(bp, pkey, 16, NULL);
+			EVP_PKEY_free(pkey);
+		}
+	}
+
+	if (!(cflag & X509_FLAG_NO_EXTENSIONS))
+		X509V3_extensions_print(bp, "X509v3 extensions",
+		    ci->extensions, cflag, 8);
+
+	if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
+		if (X509_signature_print(bp, x->sig_alg, x->signature) <= 0)
+			goto err;
+	}
+	if (!(cflag & X509_FLAG_NO_AUX)) {
+		if (!X509_CERT_AUX_print(bp, x->aux, 0))
+			goto err;
+	}
+	ret = 1;
+
+err:
+	free(m);
+	return (ret);
+}
+
+int X509_ocspid_print (BIO *bp, X509 *x)
+{
+	unsigned char *der = NULL;
+	unsigned char *dertmp;
+	int derlen;
+	int i;
+	unsigned char SHA1md[SHA_DIGEST_LENGTH];
+
+	/* display the hash of the subject as it would appear
+	   in OCSP requests */
+	if (BIO_printf(bp, "        Subject OCSP hash: ") <= 0)
+		goto err;
+	derlen = i2d_X509_NAME(x->cert_info->subject, NULL);
+	if ((der = dertmp = malloc(derlen)) == NULL)
+		goto err;
+	i2d_X509_NAME(x->cert_info->subject, &dertmp);
+
+	if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
+		goto err;
+	for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
+		if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
+			goto err;
+	}
+	free (der);
+	der = NULL;
+
+	/* display the hash of the public key as it would appear
+	   in OCSP requests */
+	if (BIO_printf(bp, "\n        Public key OCSP hash: ") <= 0)
+		goto err;
+
+	if (!EVP_Digest(x->cert_info->key->public_key->data,
+	    x->cert_info->key->public_key->length,
+	    SHA1md, NULL, EVP_sha1(), NULL))
+		goto err;
+	for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
+		if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
+			goto err;
+	}
+	BIO_printf(bp, "\n");
+
+	return (1);
+
+err:
+	free(der);
+	return (0);
+}
+
+int
+X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent)
+{
+	const unsigned char *s;
+	int i, n;
+
+	n = sig->length;
+	s = sig->data;
+	for (i = 0; i < n; i++) {
+		if ((i % 18) == 0) {
+			if (BIO_write(bp, "\n", 1) <= 0)
+				return 0;
+			if (BIO_indent(bp, indent, indent) <= 0)
+				return 0;
+		}
+		if (BIO_printf(bp, "%02x%s", s[i],
+		    ((i + 1) == n) ? "" : ":") <= 0)
+			return 0;
+	}
+	if (BIO_write(bp, "\n", 1) != 1)
+		return 0;
+
+	return 1;
+}
+
+int
+X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig)
+{
+	int sig_nid;
+	if (BIO_puts(bp, "    Signature Algorithm: ") <= 0)
+		return 0;
+	if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0)
+		return 0;
+
+	sig_nid = OBJ_obj2nid(sigalg->algorithm);
+	if (sig_nid != NID_undef) {
+		int pkey_nid, dig_nid;
+		const EVP_PKEY_ASN1_METHOD *ameth;
+		if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid)) {
+			ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
+			if (ameth && ameth->sig_print)
+				return ameth->sig_print(bp, sigalg, sig, 9, 0);
+		}
+	}
+	if (sig)
+		return X509_signature_dump(bp, sig, 9);
+	else if (BIO_puts(bp, "\n") <= 0)
+		return 0;
+	return 1;
+}
+
+int
+ASN1_STRING_print(BIO *bp, const ASN1_STRING *v)
+{
+	int i, n;
+	char buf[80];
+	const char *p;
+
+	if (v == NULL)
+		return (0);
+	n = 0;
+	p = (const char *)v->data;
+	for (i = 0; i < v->length; i++) {
+		if ((p[i] > '~') || ((p[i] < ' ') &&
+		    (p[i] != '\n') && (p[i] != '\r')))
+			buf[n] = '.';
+		else
+			buf[n] = p[i];
+		n++;
+		if (n >= 80) {
+			if (BIO_write(bp, buf, n) <= 0)
+				return (0);
+			n = 0;
+		}
+	}
+	if (n > 0)
+		if (BIO_write(bp, buf, n) <= 0)
+			return (0);
+	return (1);
+}
+
+int
+ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm)
+{
+	if (tm->type == V_ASN1_UTCTIME)
+		return ASN1_UTCTIME_print(bp, tm);
+	if (tm->type == V_ASN1_GENERALIZEDTIME)
+		return ASN1_GENERALIZEDTIME_print(bp, tm);
+	BIO_write(bp, "Bad time value", 14);
+	return (0);
+}
+
+static const char *mon[12] = {
+	"Jan", "Feb", "Mar", "Apr", "May", "Jun", 
+	"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+int
+ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm)
+{
+	char *v;
+	int gmt = 0;
+	int i;
+	int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
+	char *f = NULL;
+	int f_len = 0;
+
+	i = tm->length;
+	v = (char *)tm->data;
+
+	if (i < 12)
+		goto err;
+	if (v[i-1] == 'Z')
+		gmt = 1;
+	for (i = 0; i < 12; i++)
+		if ((v[i] > '9') || (v[i] < '0'))
+			goto err;
+	y = (v[0] - '0') * 1000 + (v[1] - '0') * 100 +
+	    (v[2] - '0') * 10 + (v[3] - '0');
+	M = (v[4] - '0') * 10 + (v[5] - '0');
+	if ((M > 12) || (M < 1))
+		goto err;
+	d = (v[6] - '0') * 10 + (v[7] - '0');
+	h = (v[8] - '0') * 10 + (v[9] - '0');
+	m = (v[10] - '0') * 10 + (v[11] - '0');
+	if (tm->length >= 14 &&
+	    (v[12] >= '0') && (v[12] <= '9') &&
+	    (v[13] >= '0') && (v[13] <= '9')) {
+		s =  (v[12] - '0') * 10 + (v[13] - '0');
+		/* Check for fractions of seconds. */
+		if (tm->length >= 15 && v[14] == '.') {
+			int l = tm->length;
+			f = &v[14];	/* The decimal point. */
+			f_len = 1;
+			while (14 + f_len < l && f[f_len] >= '0' &&
+			    f[f_len] <= '9')
+				++f_len;
+		}
+	}
+
+	if (BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s",
+	    mon[M - 1], d, h, m, s, f_len, f, y, (gmt) ? " GMT" : "") <= 0)
+		return (0);
+	else
+		return (1);
+
+err:
+	BIO_write(bp, "Bad time value", 14);
+	return (0);
+}
+
+int
+ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm)
+{
+	const char *v;
+	int gmt = 0;
+	int i;
+	int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
+
+	i = tm->length;
+	v = (const char *)tm->data;
+
+	if (i < 10)
+		goto err;
+	if (v[i-1] == 'Z')
+		gmt = 1;
+	for (i = 0; i < 10; i++)
+		if ((v[i] > '9') || (v[i] < '0'))
+			goto err;
+	y = (v[0] - '0') * 10 + (v[1] - '0');
+	if (y < 50)
+		y += 100;
+	M = (v[2] - '0') * 10 + (v[3] - '0');
+	if ((M > 12) || (M < 1))
+		goto err;
+	d = (v[4] - '0') * 10 + (v[5] - '0');
+	h = (v[6] - '0') * 10 + (v[7] - '0');
+	m = (v[8] - '0') * 10 + (v[9] - '0');
+	if (tm->length >=12 &&
+	    (v[10] >= '0') && (v[10] <= '9') &&
+	    (v[11] >= '0') && (v[11] <= '9'))
+		s = (v[10] - '0') * 10 + (v[11] - '0');
+
+	if (BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s",
+	    mon[M - 1], d, h, m, s, y + 1900, (gmt) ? " GMT" : "") <= 0)
+		return (0);
+	else
+		return (1);
+
+err:
+	BIO_write(bp, "Bad time value", 14);
+	return (0);
+}
+
+int
+X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
+{
+	char *s, *c, *b;
+	int ret = 0, l, i;
+
+	l = 80 - 2 - obase;
+
+	b = X509_NAME_oneline(name, NULL, 0);
+	if (b == NULL)
+		return 0;
+	if (*b == '\0') {
+		free(b);
+		return 1;
+	}
+	s = b + 1; /* skip the first slash */
+
+	c = s;
+	for (;;) {
+		if (((*s == '/') &&
+		    ((s[1] >= 'A') && (s[1] <= 'Z') &&
+		    ((s[2] == '=') || ((s[2] >= 'A') && (s[2] <= 'Z') &&
+		    (s[3] == '='))))) || (*s == '\0')) {
+			i = s - c;
+			if (BIO_write(bp, c, i) != i)
+				goto err;
+			c = s + 1;	/* skip following slash */
+			if (*s != '\0') {
+				if (BIO_write(bp, ", ", 2) != 2)
+					goto err;
+			}
+			l--;
+		}
+		if (*s == '\0')
+			break;
+		s++;
+		l--;
+	}
+
+	ret = 1;
+	if (0) {
+err:
+		X509err(X509_F_X509_NAME_PRINT, ERR_R_BUF_LIB);
+	}
+	free(b);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/asn1/t_x509a.c b/crypto/libressl/crypto/asn1/t_x509a.c
new file mode 100644
index 0000000000..d3a01640ef
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/t_x509a.c
@@ -0,0 +1,118 @@
+/* $OpenBSD: t_x509a.c,v 1.7 2014/06/12 15:49:27 deraadt Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+/* X509_CERT_AUX and string set routines
+ */
+
+int
+X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent)
+{
+	char oidstr[80], first;
+	int i;
+	if (!aux)
+		return 1;
+	if (aux->trust) {
+		first = 1;
+		BIO_printf(out, "%*sTrusted Uses:\n%*s",
+		    indent, "", indent + 2, "");
+		for (i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) {
+			if (!first)
+				BIO_puts(out, ", ");
+			else
+				first = 0;
+			OBJ_obj2txt(oidstr, sizeof oidstr,
+			    sk_ASN1_OBJECT_value(aux->trust, i), 0);
+			BIO_puts(out, oidstr);
+		}
+		BIO_puts(out, "\n");
+	} else
+		BIO_printf(out, "%*sNo Trusted Uses.\n", indent, "");
+	if (aux->reject) {
+		first = 1;
+		BIO_printf(out, "%*sRejected Uses:\n%*s",
+		    indent, "", indent + 2, "");
+		for (i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) {
+			if (!first)
+				BIO_puts(out, ", ");
+			else
+				first = 0;
+			OBJ_obj2txt(oidstr, sizeof oidstr,
+			    sk_ASN1_OBJECT_value(aux->reject, i), 0);
+			BIO_puts(out, oidstr);
+		}
+		BIO_puts(out, "\n");
+	} else
+		BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
+	if (aux->alias)
+		BIO_printf(out, "%*sAlias: %s\n", indent, "",
+		    aux->alias->data);
+	if (aux->keyid) {
+		BIO_printf(out, "%*sKey Id: ", indent, "");
+		for (i = 0; i < aux->keyid->length; i++)
+			BIO_printf(out, "%s%02X", i ? ":" : "",
+			    aux->keyid->data[i]);
+		BIO_write(out, "\n", 1);
+	}
+	return 1;
+}
diff --git a/crypto/libressl/crypto/asn1/tasn_dec.c b/crypto/libressl/crypto/asn1/tasn_dec.c
new file mode 100644
index 0000000000..462376fa04
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/tasn_dec.c
@@ -0,0 +1,1188 @@
+/* $OpenBSD: tasn_dec.c,v 1.31 2016/05/04 14:53:29 tedu Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int asn1_check_eoc(const unsigned char **in, long len);
+static int asn1_find_end(const unsigned char **in, long len, char inf);
+
+static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
+    char inf, int tag, int aclass, int depth);
+
+static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen);
+
+static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
+    char *inf, char *cst, const unsigned char **in, long len, int exptag,
+    int expclass, char opt, ASN1_TLC *ctx);
+
+static int asn1_template_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
+    long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx);
+static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in,
+    long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx);
+static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in,
+    long len, const ASN1_ITEM *it, int tag, int aclass, char opt,
+    ASN1_TLC *ctx);
+
+/* Table to convert tags to bit values, used for MSTRING type */
+static const unsigned long tag2bit[32] = {
+	0,	0,	0,	B_ASN1_BIT_STRING,	/* tags  0 -  3 */
+	B_ASN1_OCTET_STRING,	0,	0,		B_ASN1_UNKNOWN,/* tags  4- 7 */
+	B_ASN1_UNKNOWN,	B_ASN1_UNKNOWN,	B_ASN1_UNKNOWN,	B_ASN1_UNKNOWN,/* tags  8-11 */
+	B_ASN1_UTF8STRING,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,/* tags 12-15 */
+	B_ASN1_SEQUENCE,0,B_ASN1_NUMERICSTRING,B_ASN1_PRINTABLESTRING, /* tags 16-19 */
+	B_ASN1_T61STRING,B_ASN1_VIDEOTEXSTRING,B_ASN1_IA5STRING,       /* tags 20-22 */
+	B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME,			       /* tags 23-24 */
+	B_ASN1_GRAPHICSTRING,B_ASN1_ISO64STRING,B_ASN1_GENERALSTRING,  /* tags 25-27 */
+	B_ASN1_UNIVERSALSTRING,B_ASN1_UNKNOWN,B_ASN1_BMPSTRING,B_ASN1_UNKNOWN, /* tags 28-31 */
+};
+
+unsigned long
+ASN1_tag2bit(int tag)
+{
+	if ((tag < 0) || (tag > 30))
+		return 0;
+	return tag2bit[tag];
+}
+
+/* Macro to initialize and invalidate the cache */
+
+#define asn1_tlc_clear(c)	if (c) (c)->valid = 0
+/* Version to avoid compiler warning about 'c' always non-NULL */
+#define asn1_tlc_clear_nc(c)	(c)->valid = 0
+
+/* Decode an ASN1 item, this currently behaves just
+ * like a standard 'd2i' function. 'in' points to
+ * a buffer to read the data from, in future we will
+ * have more advanced versions that can input data
+ * a piece at a time and this will simply be a special
+ * case.
+ */
+
+ASN1_VALUE *
+ASN1_item_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
+    const ASN1_ITEM *it)
+{
+	ASN1_TLC c;
+	ASN1_VALUE *ptmpval = NULL;
+
+	if (!pval)
+		pval = &ptmpval;
+	asn1_tlc_clear_nc(&c);
+	if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0)
+		return *pval;
+	return NULL;
+}
+
+int
+ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
+    const ASN1_TEMPLATE *tt)
+{
+	ASN1_TLC c;
+
+	asn1_tlc_clear_nc(&c);
+	return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
+}
+
+
+/* Decode an item, taking care of IMPLICIT tagging, if any.
+ * If 'opt' set and tag mismatch return -1 to handle OPTIONAL
+ */
+
+int
+ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
+    const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx)
+{
+	const ASN1_TEMPLATE *tt, *errtt = NULL;
+	const ASN1_EXTERN_FUNCS *ef;
+	const ASN1_AUX *aux = it->funcs;
+	ASN1_aux_cb *asn1_cb;
+	const unsigned char *p = NULL, *q;
+	unsigned char oclass;
+	char seq_eoc, seq_nolen, cst, isopt;
+	long tmplen;
+	int i;
+	int otag;
+	int ret = 0;
+	ASN1_VALUE **pchptr;
+	int combine;
+
+	combine = aclass & ASN1_TFLG_COMBINE;
+	aclass &= ~ASN1_TFLG_COMBINE;
+
+	if (!pval)
+		return 0;
+
+	if (aux && aux->asn1_cb)
+		asn1_cb = aux->asn1_cb;
+	else
+		asn1_cb = 0;
+
+	switch (it->itype) {
+	case ASN1_ITYPE_PRIMITIVE:
+		if (it->templates) {
+			/* tagging or OPTIONAL is currently illegal on an item
+			 * template because the flags can't get passed down.
+			 * In practice this isn't a problem: we include the
+			 * relevant flags from the item template in the
+			 * template itself.
+			 */
+			if ((tag != -1) || opt) {
+				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+				    ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
+				goto err;
+			}
+			return asn1_template_ex_d2i(pval, in, len,
+			    it->templates, opt, ctx);
+		}
+		return asn1_d2i_ex_primitive(pval, in, len, it,
+		    tag, aclass, opt, ctx);
+		break;
+
+	case ASN1_ITYPE_MSTRING:
+		p = *in;
+		/* Just read in tag and class */
+		ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
+		    &p, len, -1, 0, 1, ctx);
+		if (!ret) {
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+			    ERR_R_NESTED_ASN1_ERROR);
+			goto err;
+		}
+
+		/* Must be UNIVERSAL class */
+		if (oclass != V_ASN1_UNIVERSAL) {
+			/* If OPTIONAL, assume this is OK */
+			if (opt)
+				return -1;
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+			    ASN1_R_MSTRING_NOT_UNIVERSAL);
+			goto err;
+		}
+		/* Check tag matches bit map */
+		if (!(ASN1_tag2bit(otag) & it->utype)) {
+			/* If OPTIONAL, assume this is OK */
+			if (opt)
+				return -1;
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+			    ASN1_R_MSTRING_WRONG_TAG);
+			goto err;
+		}
+		return asn1_d2i_ex_primitive(pval, in, len,
+		    it, otag, 0, 0, ctx);
+
+	case ASN1_ITYPE_EXTERN:
+		/* Use new style d2i */
+		ef = it->funcs;
+		return ef->asn1_ex_d2i(pval, in, len,
+		    it, tag, aclass, opt, ctx);
+
+	case ASN1_ITYPE_CHOICE:
+		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
+			goto auxerr;
+
+		if (*pval) {
+			/* Free up and zero CHOICE value if initialised */
+			i = asn1_get_choice_selector(pval, it);
+			if ((i >= 0) && (i < it->tcount)) {
+				tt = it->templates + i;
+				pchptr = asn1_get_field_ptr(pval, tt);
+				ASN1_template_free(pchptr, tt);
+				asn1_set_choice_selector(pval, -1, it);
+			}
+		} else if (!ASN1_item_ex_new(pval, it)) {
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+			    ERR_R_NESTED_ASN1_ERROR);
+			goto err;
+		}
+		/* CHOICE type, try each possibility in turn */
+		p = *in;
+		for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+			pchptr = asn1_get_field_ptr(pval, tt);
+			/* We mark field as OPTIONAL so its absence
+			 * can be recognised.
+			 */
+			ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx);
+			/* If field not present, try the next one */
+			if (ret == -1)
+				continue;
+			/* If positive return, read OK, break loop */
+			if (ret > 0)
+				break;
+			/* Otherwise must be an ASN1 parsing error */
+			errtt = tt;
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+			    ERR_R_NESTED_ASN1_ERROR);
+			goto err;
+		}
+
+		/* Did we fall off the end without reading anything? */
+		if (i == it->tcount) {
+			/* If OPTIONAL, this is OK */
+			if (opt) {
+				/* Free and zero it */
+				ASN1_item_ex_free(pval, it);
+				return -1;
+			}
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+			    ASN1_R_NO_MATCHING_CHOICE_TYPE);
+			goto err;
+		}
+
+		asn1_set_choice_selector(pval, i, it);
+		*in = p;
+		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
+			goto auxerr;
+		return 1;
+
+	case ASN1_ITYPE_NDEF_SEQUENCE:
+	case ASN1_ITYPE_SEQUENCE:
+		p = *in;
+		tmplen = len;
+
+		/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
+		if (tag == -1) {
+			tag = V_ASN1_SEQUENCE;
+			aclass = V_ASN1_UNIVERSAL;
+		}
+		/* Get SEQUENCE length and update len, p */
+		ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst,
+		    &p, len, tag, aclass, opt, ctx);
+		if (!ret) {
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+			    ERR_R_NESTED_ASN1_ERROR);
+			goto err;
+		} else if (ret == -1)
+			return -1;
+		if (aux && (aux->flags & ASN1_AFLG_BROKEN)) {
+			len = tmplen - (p - *in);
+			seq_nolen = 1;
+		}
+		/* If indefinite we don't do a length check */
+		else
+			seq_nolen = seq_eoc;
+		if (!cst) {
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+			    ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
+			goto err;
+		}
+
+		if (!*pval && !ASN1_item_ex_new(pval, it)) {
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+			    ERR_R_NESTED_ASN1_ERROR);
+			goto err;
+		}
+
+		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
+			goto auxerr;
+
+		/* Free up and zero any ADB found */
+		for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+			if (tt->flags & ASN1_TFLG_ADB_MASK) {
+				const ASN1_TEMPLATE *seqtt;
+				ASN1_VALUE **pseqval;
+				seqtt = asn1_do_adb(pval, tt, 1);
+				if (!seqtt)
+					goto err;
+				pseqval = asn1_get_field_ptr(pval, seqtt);
+				ASN1_template_free(pseqval, seqtt);
+			}
+		}
+
+		/* Get each field entry */
+		for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+			const ASN1_TEMPLATE *seqtt;
+			ASN1_VALUE **pseqval;
+			seqtt = asn1_do_adb(pval, tt, 1);
+			if (!seqtt)
+				goto err;
+			pseqval = asn1_get_field_ptr(pval, seqtt);
+			/* Have we ran out of data? */
+			if (!len)
+				break;
+			q = p;
+			if (asn1_check_eoc(&p, len)) {
+				if (!seq_eoc) {
+					ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+					    ASN1_R_UNEXPECTED_EOC);
+					goto err;
+				}
+				len -= p - q;
+				seq_eoc = 0;
+				q = p;
+				break;
+			}
+			/* This determines the OPTIONAL flag value. The field
+			 * cannot be omitted if it is the last of a SEQUENCE
+			 * and there is still data to be read. This isn't
+			 * strictly necessary but it increases efficiency in
+			 * some cases.
+			 */
+			if (i == (it->tcount - 1))
+				isopt = 0;
+			else
+				isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);
+			/* attempt to read in field, allowing each to be
+			 * OPTIONAL */
+
+			ret = asn1_template_ex_d2i(pseqval, &p, len,
+			    seqtt, isopt, ctx);
+			if (!ret) {
+				errtt = seqtt;
+				goto err;
+			} else if (ret == -1) {
+				/* OPTIONAL component absent.
+				 * Free and zero the field.
+				 */
+				ASN1_template_free(pseqval, seqtt);
+				continue;
+			}
+			/* Update length */
+			len -= p - q;
+		}
+
+		/* Check for EOC if expecting one */
+		if (seq_eoc && !asn1_check_eoc(&p, len)) {
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC);
+			goto err;
+		}
+		/* Check all data read */
+		if (!seq_nolen && len) {
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+			    ASN1_R_SEQUENCE_LENGTH_MISMATCH);
+			goto err;
+		}
+
+		/* If we get here we've got no more data in the SEQUENCE,
+		 * however we may not have read all fields so check all
+		 * remaining are OPTIONAL and clear any that are.
+		 */
+		for (; i < it->tcount; tt++, i++) {
+			const ASN1_TEMPLATE *seqtt;
+			seqtt = asn1_do_adb(pval, tt, 1);
+			if (!seqtt)
+				goto err;
+			if (seqtt->flags & ASN1_TFLG_OPTIONAL) {
+				ASN1_VALUE **pseqval;
+				pseqval = asn1_get_field_ptr(pval, seqtt);
+				ASN1_template_free(pseqval, seqtt);
+			} else {
+				errtt = seqtt;
+				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
+				    ASN1_R_FIELD_MISSING);
+				goto err;
+			}
+		}
+		/* Save encoding */
+		if (!asn1_enc_save(pval, *in, p - *in, it)) {
+			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_MALLOC_FAILURE);
+			goto auxerr;
+		}
+		*in = p;
+		if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
+			goto auxerr;
+		return 1;
+
+	default:
+		return 0;
+	}
+
+auxerr:
+	ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR);
+err:
+	if (combine == 0)
+		ASN1_item_ex_free(pval, it);
+	if (errtt)
+		ERR_asprintf_error_data("Field=%s, Type=%s", errtt->field_name,
+		    it->sname);
+	else
+		ERR_asprintf_error_data("Type=%s", it->sname);
+	return 0;
+}
+
+/* Templates are handled with two separate functions.
+ * One handles any EXPLICIT tag and the other handles the rest.
+ */
+
+static int
+asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long inlen,
+    const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx)
+{
+	int flags, aclass;
+	int ret;
+	long len;
+	const unsigned char *p, *q;
+	char exp_eoc;
+
+	if (!val)
+		return 0;
+	flags = tt->flags;
+	aclass = flags & ASN1_TFLG_TAG_CLASS;
+
+	p = *in;
+
+	/* Check if EXPLICIT tag expected */
+	if (flags & ASN1_TFLG_EXPTAG) {
+		char cst;
+		/* Need to work out amount of data available to the inner
+		 * content and where it starts: so read in EXPLICIT header to
+		 * get the info.
+		 */
+		ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst,
+		    &p, inlen, tt->tag, aclass, opt, ctx);
+		q = p;
+		if (!ret) {
+			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
+			    ERR_R_NESTED_ASN1_ERROR);
+			return 0;
+		} else if (ret == -1)
+			return -1;
+		if (!cst) {
+			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
+			    ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
+			return 0;
+		}
+		/* We've found the field so it can't be OPTIONAL now */
+		ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);
+		if (!ret) {
+			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
+			    ERR_R_NESTED_ASN1_ERROR);
+			return 0;
+		}
+		/* We read the field in OK so update length */
+		len -= p - q;
+		if (exp_eoc) {
+			/* If NDEF we must have an EOC here */
+			if (!asn1_check_eoc(&p, len)) {
+				ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
+				    ASN1_R_MISSING_EOC);
+				goto err;
+			}
+		} else {
+			/* Otherwise we must hit the EXPLICIT tag end or its
+			 * an error */
+			if (len) {
+				ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
+				    ASN1_R_EXPLICIT_LENGTH_MISMATCH);
+				goto err;
+			}
+		}
+	} else
+		return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx);
+
+	*in = p;
+	return 1;
+
+err:
+	ASN1_template_free(val, tt);
+	return 0;
+}
+
+static int
+asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len,
+    const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx)
+{
+	int flags, aclass;
+	int ret;
+	const unsigned char *p, *q;
+
+	if (!val)
+		return 0;
+	flags = tt->flags;
+	aclass = flags & ASN1_TFLG_TAG_CLASS;
+
+	p = *in;
+	q = p;
+
+	if (flags & ASN1_TFLG_SK_MASK) {
+		/* SET OF, SEQUENCE OF */
+		int sktag, skaclass;
+		char sk_eoc;
+		/* First work out expected inner tag value */
+		if (flags & ASN1_TFLG_IMPTAG) {
+			sktag = tt->tag;
+			skaclass = aclass;
+		} else {
+			skaclass = V_ASN1_UNIVERSAL;
+			if (flags & ASN1_TFLG_SET_OF)
+				sktag = V_ASN1_SET;
+			else
+				sktag = V_ASN1_SEQUENCE;
+		}
+		/* Get the tag */
+		ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL,
+		    &p, len, sktag, skaclass, opt, ctx);
+		if (!ret) {
+			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+			    ERR_R_NESTED_ASN1_ERROR);
+			return 0;
+		} else if (ret == -1)
+			return -1;
+		if (!*val)
+			*val = (ASN1_VALUE *)sk_new_null();
+		else {
+			/* We've got a valid STACK: free up any items present */
+			STACK_OF(ASN1_VALUE) *sktmp =
+			    (STACK_OF(ASN1_VALUE) *)*val;
+			ASN1_VALUE *vtmp;
+			while (sk_ASN1_VALUE_num(sktmp) > 0) {
+				vtmp = sk_ASN1_VALUE_pop(sktmp);
+				ASN1_item_ex_free(&vtmp,
+				    ASN1_ITEM_ptr(tt->item));
+			}
+		}
+
+		if (!*val) {
+			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+			    ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+
+		/* Read as many items as we can */
+		while (len > 0) {
+			ASN1_VALUE *skfield;
+			q = p;
+			/* See if EOC found */
+			if (asn1_check_eoc(&p, len)) {
+				if (!sk_eoc) {
+					ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+					    ASN1_R_UNEXPECTED_EOC);
+					goto err;
+				}
+				len -= p - q;
+				sk_eoc = 0;
+				break;
+			}
+			skfield = NULL;
+			if (!ASN1_item_ex_d2i(&skfield, &p, len,
+			    ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) {
+				ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+				    ERR_R_NESTED_ASN1_ERROR);
+				goto err;
+			}
+			len -= p - q;
+			if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val,
+			    skfield)) {
+				ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+				    ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+		}
+		if (sk_eoc) {
+			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+			    ASN1_R_MISSING_EOC);
+			goto err;
+		}
+	} else if (flags & ASN1_TFLG_IMPTAG) {
+		/* IMPLICIT tagging */
+		ret = ASN1_item_ex_d2i(val, &p, len,
+		    ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx);
+		if (!ret) {
+			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+			    ERR_R_NESTED_ASN1_ERROR);
+			goto err;
+		} else if (ret == -1)
+			return -1;
+	} else {
+		/* Nothing special */
+		ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
+		    -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx);
+		if (!ret) {
+			ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+			    ERR_R_NESTED_ASN1_ERROR);
+			goto err;
+		} else if (ret == -1)
+			return -1;
+	}
+
+	*in = p;
+	return 1;
+
+err:
+	ASN1_template_free(val, tt);
+	return 0;
+}
+
+static int
+asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen,
+    const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx)
+{
+	int ret = 0, utype;
+	long plen;
+	char cst, inf, free_cont = 0;
+	const unsigned char *p;
+	BUF_MEM buf;
+	const unsigned char *cont = NULL;
+	long len;
+
+	buf.length = 0;
+	buf.max = 0;
+	buf.data = NULL;
+
+	if (!pval) {
+		ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL);
+		return 0; /* Should never happen */
+	}
+
+	if (it->itype == ASN1_ITYPE_MSTRING) {
+		utype = tag;
+		tag = -1;
+	} else
+		utype = it->utype;
+
+	if (utype == V_ASN1_ANY) {
+		/* If type is ANY need to figure out type from tag */
+		unsigned char oclass;
+		if (tag >= 0) {
+			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
+			    ASN1_R_ILLEGAL_TAGGED_ANY);
+			return 0;
+		}
+		if (opt) {
+			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
+			    ASN1_R_ILLEGAL_OPTIONAL_ANY);
+			return 0;
+		}
+		p = *in;
+		ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL,
+		    &p, inlen, -1, 0, 0, ctx);
+		if (!ret) {
+			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
+			    ERR_R_NESTED_ASN1_ERROR);
+			return 0;
+		}
+		if (oclass != V_ASN1_UNIVERSAL)
+			utype = V_ASN1_OTHER;
+	}
+	if (tag == -1) {
+		tag = utype;
+		aclass = V_ASN1_UNIVERSAL;
+	}
+	p = *in;
+	/* Check header */
+	ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst,
+	    &p, inlen, tag, aclass, opt, ctx);
+	if (!ret) {
+		ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
+		return 0;
+	} else if (ret == -1)
+		return -1;
+	ret = 0;
+	/* SEQUENCE, SET and "OTHER" are left in encoded form */
+	if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) ||
+	    (utype == V_ASN1_OTHER)) {
+		/* Clear context cache for type OTHER because the auto clear
+		 * when we have a exact match wont work
+		 */
+		if (utype == V_ASN1_OTHER) {
+			asn1_tlc_clear(ctx);
+		}
+		/* SEQUENCE and SET must be constructed */
+		else if (!cst) {
+			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
+			    ASN1_R_TYPE_NOT_CONSTRUCTED);
+			return 0;
+		}
+
+		cont = *in;
+		/* If indefinite length constructed find the real end */
+		if (inf) {
+			if (!asn1_find_end(&p, plen, inf))
+				goto err;
+			len = p - cont;
+		} else {
+			len = p - cont + plen;
+			p += plen;
+			buf.data = NULL;
+		}
+	} else if (cst) {
+		/* Should really check the internal tags are correct but
+		 * some things may get this wrong. The relevant specs
+		 * say that constructed string types should be OCTET STRINGs
+		 * internally irrespective of the type. So instead just check
+		 * for UNIVERSAL class and ignore the tag.
+		 */
+		if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) {
+			free_cont = 1;
+			goto err;
+		}
+		len = buf.length;
+		/* Append a final null to string */
+		if (!BUF_MEM_grow_clean(&buf, len + 1)) {
+			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
+			    ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		buf.data[len] = 0;
+		cont = (const unsigned char *)buf.data;
+		free_cont = 1;
+	} else {
+		cont = p;
+		len = plen;
+		p += plen;
+	}
+
+	/* We now have content length and type: translate into a structure */
+	if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it))
+		goto err;
+
+	*in = p;
+	ret = 1;
+
+err:
+	if (free_cont && buf.data)
+		free(buf.data);
+	return ret;
+}
+
+/* Translate ASN1 content octets into a structure */
+
+int
+asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
+    char *free_cont, const ASN1_ITEM *it)
+{
+	ASN1_VALUE **opval = NULL;
+	ASN1_STRING *stmp;
+	ASN1_TYPE *typ = NULL;
+	int ret = 0;
+	const ASN1_PRIMITIVE_FUNCS *pf;
+	ASN1_INTEGER **tint;
+
+	pf = it->funcs;
+
+	if (pf && pf->prim_c2i)
+		return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
+	/* If ANY type clear type and set pointer to internal value */
+	if (it->utype == V_ASN1_ANY) {
+		if (!*pval) {
+			typ = ASN1_TYPE_new();
+			if (typ == NULL)
+				goto err;
+			*pval = (ASN1_VALUE *)typ;
+		} else
+			typ = (ASN1_TYPE *)*pval;
+
+		if (utype != typ->type)
+			ASN1_TYPE_set(typ, utype, NULL);
+		opval = pval;
+		pval = &typ->value.asn1_value;
+	}
+	switch (utype) {
+	case V_ASN1_OBJECT:
+		if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
+			goto err;
+		break;
+
+	case V_ASN1_NULL:
+		if (len) {
+			ASN1err(ASN1_F_ASN1_EX_C2I,
+			    ASN1_R_NULL_IS_WRONG_LENGTH);
+			goto err;
+		}
+		*pval = (ASN1_VALUE *)1;
+		break;
+
+	case V_ASN1_BOOLEAN:
+		if (len != 1) {
+			ASN1err(ASN1_F_ASN1_EX_C2I,
+			    ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
+			goto err;
+		} else {
+			ASN1_BOOLEAN *tbool;
+			tbool = (ASN1_BOOLEAN *)pval;
+			*tbool = *cont;
+		}
+		break;
+
+	case V_ASN1_BIT_STRING:
+		if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len))
+			goto err;
+		break;
+
+	case V_ASN1_INTEGER:
+	case V_ASN1_ENUMERATED:
+		tint = (ASN1_INTEGER **)pval;
+		if (!c2i_ASN1_INTEGER(tint, &cont, len))
+			goto err;
+		/* Fixup type to match the expected form */
+		(*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
+		break;
+
+	case V_ASN1_OCTET_STRING:
+	case V_ASN1_NUMERICSTRING:
+	case V_ASN1_PRINTABLESTRING:
+	case V_ASN1_T61STRING:
+	case V_ASN1_VIDEOTEXSTRING:
+	case V_ASN1_IA5STRING:
+	case V_ASN1_UTCTIME:
+	case V_ASN1_GENERALIZEDTIME:
+	case V_ASN1_GRAPHICSTRING:
+	case V_ASN1_VISIBLESTRING:
+	case V_ASN1_GENERALSTRING:
+	case V_ASN1_UNIVERSALSTRING:
+	case V_ASN1_BMPSTRING:
+	case V_ASN1_UTF8STRING:
+	case V_ASN1_OTHER:
+	case V_ASN1_SET:
+	case V_ASN1_SEQUENCE:
+	default:
+		if (utype == V_ASN1_BMPSTRING && (len & 1)) {
+			ASN1err(ASN1_F_ASN1_EX_C2I,
+			    ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
+			goto err;
+		}
+		if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) {
+			ASN1err(ASN1_F_ASN1_EX_C2I,
+			    ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
+			goto err;
+		}
+		/* All based on ASN1_STRING and handled the same */
+		if (!*pval) {
+			stmp = ASN1_STRING_type_new(utype);
+			if (!stmp) {
+				ASN1err(ASN1_F_ASN1_EX_C2I,
+				    ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+			*pval = (ASN1_VALUE *)stmp;
+		} else {
+			stmp = (ASN1_STRING *)*pval;
+			stmp->type = utype;
+		}
+		/* If we've already allocated a buffer use it */
+		if (*free_cont) {
+			free(stmp->data);
+			stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */
+			stmp->length = len;
+			*free_cont = 0;
+		} else {
+			if (!ASN1_STRING_set(stmp, cont, len)) {
+				ASN1err(ASN1_F_ASN1_EX_C2I,
+				    ERR_R_MALLOC_FAILURE);
+				ASN1_STRING_free(stmp);
+				*pval = NULL;
+				goto err;
+			}
+		}
+		break;
+	}
+	/* If ASN1_ANY and NULL type fix up value */
+	if (typ && (utype == V_ASN1_NULL))
+		typ->value.ptr = NULL;
+
+	ret = 1;
+
+err:
+	if (!ret) {
+		ASN1_TYPE_free(typ);
+		if (opval)
+			*opval = NULL;
+	}
+	return ret;
+}
+
+
+/* This function finds the end of an ASN1 structure when passed its maximum
+ * length, whether it is indefinite length and a pointer to the content.
+ * This is more efficient than calling asn1_collect because it does not
+ * recurse on each indefinite length header.
+ */
+
+static int
+asn1_find_end(const unsigned char **in, long len, char inf)
+{
+	int expected_eoc;
+	long plen;
+	const unsigned char *p = *in, *q;
+
+	/* If not indefinite length constructed just add length */
+	if (inf == 0) {
+		*in += len;
+		return 1;
+	}
+	expected_eoc = 1;
+	/* Indefinite length constructed form. Find the end when enough EOCs
+	 * are found. If more indefinite length constructed headers
+	 * are encountered increment the expected eoc count otherwise just
+	 * skip to the end of the data.
+	 */
+	while (len > 0) {
+		if (asn1_check_eoc(&p, len)) {
+			expected_eoc--;
+			if (expected_eoc == 0)
+				break;
+			len -= 2;
+			continue;
+		}
+		q = p;
+		/* Just read in a header: only care about the length */
+		if (!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
+		    -1, 0, 0, NULL)) {
+			ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR);
+			return 0;
+		}
+		if (inf)
+			expected_eoc++;
+		else
+			p += plen;
+		len -= p - q;
+	}
+	if (expected_eoc) {
+		ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC);
+		return 0;
+	}
+	*in = p;
+	return 1;
+}
+/* This function collects the asn1 data from a constructred string
+ * type into a buffer. The values of 'in' and 'len' should refer
+ * to the contents of the constructed type and 'inf' should be set
+ * if it is indefinite length.
+ */
+
+#ifndef ASN1_MAX_STRING_NEST
+/* This determines how many levels of recursion are permitted in ASN1
+ * string types. If it is not limited stack overflows can occur. If set
+ * to zero no recursion is allowed at all. Although zero should be adequate
+ * examples exist that require a value of 1. So 5 should be more than enough.
+ */
+#define ASN1_MAX_STRING_NEST 5
+#endif
+
+static int
+asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, char inf,
+    int tag, int aclass, int depth)
+{
+	const unsigned char *p, *q;
+	long plen;
+	char cst, ininf;
+
+	p = *in;
+	inf &= 1;
+	/* If no buffer and not indefinite length constructed just pass over
+	 * the encoded data */
+	if (!buf && !inf) {
+		*in += len;
+		return 1;
+	}
+	while (len > 0) {
+		q = p;
+		/* Check for EOC */
+		if (asn1_check_eoc(&p, len)) {
+			/* EOC is illegal outside indefinite length
+			 * constructed form */
+			if (!inf) {
+				ASN1err(ASN1_F_ASN1_COLLECT,
+				    ASN1_R_UNEXPECTED_EOC);
+				return 0;
+			}
+			inf = 0;
+			break;
+		}
+
+		if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
+		    len, tag, aclass, 0, NULL)) {
+			ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR);
+			return 0;
+		}
+
+		/* If indefinite length constructed update max length */
+		if (cst) {
+			if (depth >= ASN1_MAX_STRING_NEST) {
+				ASN1err(ASN1_F_ASN1_COLLECT,
+				    ASN1_R_NESTED_ASN1_STRING);
+				return 0;
+			}
+			if (!asn1_collect(buf, &p, plen, ininf, tag, aclass,
+			    depth + 1))
+				return 0;
+		} else if (plen && !collect_data(buf, &p, plen))
+			return 0;
+		len -= p - q;
+	}
+	if (inf) {
+		ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC);
+		return 0;
+	}
+	*in = p;
+	return 1;
+}
+
+static int
+collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
+{
+	int len;
+	if (buf) {
+		len = buf->length;
+		if (!BUF_MEM_grow_clean(buf, len + plen)) {
+			ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		memcpy(buf->data + len, *p, plen);
+	}
+	*p += plen;
+	return 1;
+}
+
+/* Check for ASN1 EOC and swallow it if found */
+
+static int
+asn1_check_eoc(const unsigned char **in, long len)
+{
+	const unsigned char *p;
+
+	if (len < 2)
+		return 0;
+	p = *in;
+	if (!p[0] && !p[1]) {
+		*in += 2;
+		return 1;
+	}
+	return 0;
+}
+
+/* Check an ASN1 tag and length: a bit like ASN1_get_object
+ * but it sets the length for indefinite length constructed
+ * form, we don't know the exact length but we can set an
+ * upper bound to the amount of data available minus the
+ * header length just read.
+ */
+
+static int
+asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf,
+    char *cst, const unsigned char **in, long len, int exptag, int expclass,
+    char opt, ASN1_TLC *ctx)
+{
+	int i;
+	int ptag, pclass;
+	long plen;
+	const unsigned char *p, *q;
+
+	p = *in;
+	q = p;
+
+	if (ctx && ctx->valid) {
+		i = ctx->ret;
+		plen = ctx->plen;
+		pclass = ctx->pclass;
+		ptag = ctx->ptag;
+		p += ctx->hdrlen;
+	} else {
+		i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
+		if (ctx) {
+			ctx->ret = i;
+			ctx->plen = plen;
+			ctx->pclass = pclass;
+			ctx->ptag = ptag;
+			ctx->hdrlen = p - q;
+			ctx->valid = 1;
+			/* If definite length, and no error, length +
+			 * header can't exceed total amount of data available.
+			 */
+			if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) {
+				ASN1err(ASN1_F_ASN1_CHECK_TLEN,
+				    ASN1_R_TOO_LONG);
+				asn1_tlc_clear(ctx);
+				return 0;
+			}
+		}
+	}
+
+	if (i & 0x80) {
+		ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER);
+		asn1_tlc_clear(ctx);
+		return 0;
+	}
+	if (exptag >= 0) {
+		if ((exptag != ptag) || (expclass != pclass)) {
+			/* If type is OPTIONAL, not an error:
+			 * indicate missing type.
+			 */
+			if (opt)
+				return -1;
+			asn1_tlc_clear(ctx);
+			ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG);
+			return 0;
+		}
+		/* We have a tag and class match:
+		 * assume we are going to do something with it */
+		asn1_tlc_clear(ctx);
+	}
+
+	if (i & 1)
+		plen = len - (p - q);
+	if (inf)
+		*inf = i & 1;
+	if (cst)
+		*cst = i & V_ASN1_CONSTRUCTED;
+	if (olen)
+		*olen = plen;
+	if (oclass)
+		*oclass = pclass;
+	if (otag)
+		*otag = ptag;
+
+	*in = p;
+	return 1;
+}
diff --git a/crypto/libressl/crypto/asn1/tasn_enc.c b/crypto/libressl/crypto/asn1/tasn_enc.c
new file mode 100644
index 0000000000..26eed481cf
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/tasn_enc.c
@@ -0,0 +1,652 @@
+/* $OpenBSD: tasn_enc.c,v 1.19 2016/05/04 14:53:29 tedu Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2004 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
+    const ASN1_ITEM *it, int tag, int aclass);
+static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
+    int skcontlen, const ASN1_ITEM *item, int do_sort, int iclass);
+static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+    const ASN1_TEMPLATE *tt, int tag, int aclass);
+static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
+    const ASN1_ITEM *it, int flags);
+static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
+    const ASN1_ITEM *it);
+
+/* Top level i2d equivalents: the 'ndef' variant instructs the encoder
+ * to use indefinite length constructed encoding, where appropriate
+ */
+
+int
+ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
+{
+	return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
+}
+
+int
+ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
+{
+	return asn1_item_flags_i2d(val, out, it, 0);
+}
+
+/* Encode an ASN1 item, this is use by the
+ * standard 'i2d' function. 'out' points to
+ * a buffer to output the data to.
+ *
+ * The new i2d has one additional feature. If the output
+ * buffer is NULL (i.e. *out == NULL) then a buffer is
+ * allocated and populated with the encoding.
+ */
+
+static int
+asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it,
+    int flags)
+{
+	if (out && !*out) {
+		unsigned char *p, *buf;
+		int len;
+		len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
+		if (len <= 0)
+			return len;
+		buf = malloc(len);
+		if (!buf)
+			return -1;
+		p = buf;
+		ASN1_item_ex_i2d(&val, &p, it, -1, flags);
+		*out = buf;
+		return len;
+	}
+
+	return ASN1_item_ex_i2d(&val, out, it, -1, flags);
+}
+
+/* Encode an item, taking care of IMPLICIT tagging (if any).
+ * This function performs the normal item handling: it can be
+ * used in external types.
+ */
+
+int
+ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it,
+    int tag, int aclass)
+{
+	const ASN1_TEMPLATE *tt = NULL;
+	int i, seqcontlen, seqlen, ndef = 1;
+	const ASN1_EXTERN_FUNCS *ef;
+	const ASN1_AUX *aux = it->funcs;
+	ASN1_aux_cb *asn1_cb = NULL;
+
+	if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
+		return 0;
+
+	if (aux && aux->asn1_cb)
+		asn1_cb = aux->asn1_cb;
+
+	switch (it->itype) {
+
+	case ASN1_ITYPE_PRIMITIVE:
+		if (it->templates)
+			return asn1_template_ex_i2d(pval, out, it->templates,
+			    tag, aclass);
+		return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
+		break;
+
+	case ASN1_ITYPE_MSTRING:
+		return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
+
+	case ASN1_ITYPE_CHOICE:
+		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
+			return 0;
+		i = asn1_get_choice_selector(pval, it);
+		if ((i >= 0) && (i < it->tcount)) {
+			ASN1_VALUE **pchval;
+			const ASN1_TEMPLATE *chtt;
+			chtt = it->templates + i;
+			pchval = asn1_get_field_ptr(pval, chtt);
+			return asn1_template_ex_i2d(pchval, out, chtt,
+			    -1, aclass);
+		}
+		/* Fixme: error condition if selector out of range */
+		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
+			return 0;
+		break;
+
+	case ASN1_ITYPE_EXTERN:
+		/* If new style i2d it does all the work */
+		ef = it->funcs;
+		return ef->asn1_ex_i2d(pval, out, it, tag, aclass);
+
+	case ASN1_ITYPE_NDEF_SEQUENCE:
+		/* Use indefinite length constructed if requested */
+		if (aclass & ASN1_TFLG_NDEF)
+			ndef = 2;
+		/* fall through */
+
+	case ASN1_ITYPE_SEQUENCE:
+		i = asn1_enc_restore(&seqcontlen, out, pval, it);
+		/* An error occurred */
+		if (i < 0)
+			return 0;
+		/* We have a valid cached encoding... */
+		if (i > 0)
+			return seqcontlen;
+		/* Otherwise carry on */
+		seqcontlen = 0;
+		/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
+		if (tag == -1) {
+			tag = V_ASN1_SEQUENCE;
+			/* Retain any other flags in aclass */
+			aclass = (aclass & ~ASN1_TFLG_TAG_CLASS) |
+			    V_ASN1_UNIVERSAL;
+		}
+		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
+			return 0;
+		/* First work out sequence content length */
+		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+			const ASN1_TEMPLATE *seqtt;
+			ASN1_VALUE **pseqval;
+			seqtt = asn1_do_adb(pval, tt, 1);
+			if (!seqtt)
+				return 0;
+			pseqval = asn1_get_field_ptr(pval, seqtt);
+			/* FIXME: check for errors in enhanced version */
+			seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,
+			    -1, aclass);
+		}
+
+		seqlen = ASN1_object_size(ndef, seqcontlen, tag);
+		if (!out)
+			return seqlen;
+		/* Output SEQUENCE header */
+		ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
+		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+			const ASN1_TEMPLATE *seqtt;
+			ASN1_VALUE **pseqval;
+			seqtt = asn1_do_adb(pval, tt, 1);
+			if (!seqtt)
+				return 0;
+			pseqval = asn1_get_field_ptr(pval, seqtt);
+			/* FIXME: check for errors in enhanced version */
+			asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
+		}
+		if (ndef == 2)
+			ASN1_put_eoc(out);
+		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
+			return 0;
+		return seqlen;
+
+	default:
+		return 0;
+
+	}
+	return 0;
+}
+
+int
+ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out,
+    const ASN1_TEMPLATE *tt)
+{
+	return asn1_template_ex_i2d(pval, out, tt, -1, 0);
+}
+
+static int
+asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+    const ASN1_TEMPLATE *tt, int tag, int iclass)
+{
+	int i, ret, flags, ttag, tclass, ndef;
+	flags = tt->flags;
+	/* Work out tag and class to use: tagging may come
+	 * either from the template or the arguments, not both
+	 * because this would create ambiguity. Additionally
+	 * the iclass argument may contain some additional flags
+	 * which should be noted and passed down to other levels.
+	 */
+	if (flags & ASN1_TFLG_TAG_MASK) {
+		/* Error if argument and template tagging */
+		if (tag != -1)
+			/* FIXME: error code here */
+			return -1;
+		/* Get tagging from template */
+		ttag = tt->tag;
+		tclass = flags & ASN1_TFLG_TAG_CLASS;
+	} else if (tag != -1) {
+		/* No template tagging, get from arguments */
+		ttag = tag;
+		tclass = iclass & ASN1_TFLG_TAG_CLASS;
+	} else {
+		ttag = -1;
+		tclass = 0;
+	}
+	/*
+	 * Remove any class mask from iflag.
+	 */
+	iclass &= ~ASN1_TFLG_TAG_CLASS;
+
+	/* At this point 'ttag' contains the outer tag to use,
+	 * 'tclass' is the class and iclass is any flags passed
+	 * to this function.
+	 */
+
+	/* if template and arguments require ndef, use it */
+	if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))
+		ndef = 2;
+	else
+		ndef = 1;
+
+	if (flags & ASN1_TFLG_SK_MASK) {
+		/* SET OF, SEQUENCE OF */
+		STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
+		int isset, sktag, skaclass;
+		int skcontlen, sklen;
+		ASN1_VALUE *skitem;
+
+		if (!*pval)
+			return 0;
+
+		if (flags & ASN1_TFLG_SET_OF) {
+			isset = 1;
+			/* 2 means we reorder */
+			if (flags & ASN1_TFLG_SEQUENCE_OF)
+				isset = 2;
+		} else
+			isset = 0;
+
+		/* Work out inner tag value: if EXPLICIT
+		 * or no tagging use underlying type.
+		 */
+		if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) {
+			sktag = ttag;
+			skaclass = tclass;
+		} else {
+			skaclass = V_ASN1_UNIVERSAL;
+			if (isset)
+				sktag = V_ASN1_SET;
+			else
+				sktag = V_ASN1_SEQUENCE;
+		}
+
+		/* Determine total length of items */
+		skcontlen = 0;
+		for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
+			skitem = sk_ASN1_VALUE_value(sk, i);
+			skcontlen += ASN1_item_ex_i2d(&skitem, NULL,
+			    ASN1_ITEM_ptr(tt->item), -1, iclass);
+		}
+		sklen = ASN1_object_size(ndef, skcontlen, sktag);
+		/* If EXPLICIT need length of surrounding tag */
+		if (flags & ASN1_TFLG_EXPTAG)
+			ret = ASN1_object_size(ndef, sklen, ttag);
+		else
+			ret = sklen;
+
+		if (!out)
+			return ret;
+
+		/* Now encode this lot... */
+		/* EXPLICIT tag */
+		if (flags & ASN1_TFLG_EXPTAG)
+			ASN1_put_object(out, ndef, sklen, ttag, tclass);
+		/* SET or SEQUENCE and IMPLICIT tag */
+		ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
+		/* And the stuff itself */
+		asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item),
+		    isset, iclass);
+		if (ndef == 2) {
+			ASN1_put_eoc(out);
+			if (flags & ASN1_TFLG_EXPTAG)
+				ASN1_put_eoc(out);
+		}
+
+		return ret;
+	}
+
+	if (flags & ASN1_TFLG_EXPTAG) {
+		/* EXPLICIT tagging */
+		/* Find length of tagged item */
+		i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item),
+		    -1, iclass);
+		if (!i)
+			return 0;
+		/* Find length of EXPLICIT tag */
+		ret = ASN1_object_size(ndef, i, ttag);
+		if (out) {
+			/* Output tag and item */
+			ASN1_put_object(out, ndef, i, ttag, tclass);
+			ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
+			    -1, iclass);
+			if (ndef == 2)
+				ASN1_put_eoc(out);
+		}
+		return ret;
+	}
+
+	/* Either normal or IMPLICIT tagging: combine class and flags */
+	return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
+	    ttag, tclass | iclass);
+}
+
+/* Temporary structure used to hold DER encoding of items for SET OF */
+
+typedef	struct {
+	unsigned char *data;
+	int length;
+	ASN1_VALUE *field;
+} DER_ENC;
+
+static int
+der_cmp(const void *a, const void *b)
+{
+	const DER_ENC *d1 = a, *d2 = b;
+	int cmplen, i;
+
+	cmplen = (d1->length < d2->length) ? d1->length : d2->length;
+	i = memcmp(d1->data, d2->data, cmplen);
+	if (i)
+		return i;
+	return d1->length - d2->length;
+}
+
+/* Output the content octets of SET OF or SEQUENCE OF */
+
+static int
+asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, int skcontlen,
+    const ASN1_ITEM *item, int do_sort, int iclass)
+{
+	int i;
+	ASN1_VALUE *skitem;
+	unsigned char *tmpdat = NULL, *p = NULL;
+	DER_ENC *derlst = NULL, *tder;
+
+	if (do_sort) {
+		/* Don't need to sort less than 2 items */
+		if (sk_ASN1_VALUE_num(sk) < 2)
+			do_sort = 0;
+		else {
+			derlst = reallocarray(NULL, sk_ASN1_VALUE_num(sk),
+			    sizeof(*derlst));
+			tmpdat = malloc(skcontlen);
+			if (!derlst || !tmpdat) {
+				free(derlst);
+				free(tmpdat);
+				return 0;
+			}
+		}
+	}
+	/* If not sorting just output each item */
+	if (!do_sort) {
+		for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
+			skitem = sk_ASN1_VALUE_value(sk, i);
+			ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
+		}
+		return 1;
+	}
+	p = tmpdat;
+
+	/* Doing sort: build up a list of each member's DER encoding */
+	for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
+		skitem = sk_ASN1_VALUE_value(sk, i);
+		tder->data = p;
+		tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
+		tder->field = skitem;
+	}
+
+	/* Now sort them */
+	qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
+	/* Output sorted DER encoding */
+	p = *out;
+	for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
+		memcpy(p, tder->data, tder->length);
+		p += tder->length;
+	}
+	*out = p;
+	/* If do_sort is 2 then reorder the STACK */
+	if (do_sort == 2) {
+		for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
+			(void)sk_ASN1_VALUE_set(sk, i, tder->field);
+	}
+	free(derlst);
+	free(tmpdat);
+	return 1;
+}
+
+static int
+asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
+    const ASN1_ITEM *it, int tag, int aclass)
+{
+	int len;
+	int utype;
+	int usetag;
+	int ndef = 0;
+
+	utype = it->utype;
+
+	/* Get length of content octets and maybe find
+	 * out the underlying type.
+	 */
+
+	len = asn1_ex_i2c(pval, NULL, &utype, it);
+
+	/* If SEQUENCE, SET or OTHER then header is
+	 * included in pseudo content octets so don't
+	 * include tag+length. We need to check here
+	 * because the call to asn1_ex_i2c() could change
+	 * utype.
+	 */
+	if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) ||
+	    (utype == V_ASN1_OTHER))
+		usetag = 0;
+	else
+		usetag = 1;
+
+	/* -1 means omit type */
+	if (len == -1)
+		return 0;
+
+	/* -2 return is special meaning use ndef */
+	if (len == -2) {
+		ndef = 2;
+		len = 0;
+	}
+
+	/* If not implicitly tagged get tag from underlying type */
+	if (tag == -1)
+		tag = utype;
+
+	/* Output tag+length followed by content octets */
+	if (out) {
+		if (usetag)
+			ASN1_put_object(out, ndef, len, tag, aclass);
+		asn1_ex_i2c(pval, *out, &utype, it);
+		if (ndef)
+			ASN1_put_eoc(out);
+		else
+			*out += len;
+	}
+
+	if (usetag)
+		return ASN1_object_size(ndef, len, tag);
+	return len;
+}
+
+/* Produce content octets from a structure */
+
+static int
+asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
+    const ASN1_ITEM *it)
+{
+	ASN1_BOOLEAN *tbool = NULL;
+	ASN1_STRING *strtmp;
+	ASN1_OBJECT *otmp;
+	int utype;
+	const unsigned char *cont;
+	unsigned char c;
+	int len;
+	const ASN1_PRIMITIVE_FUNCS *pf;
+
+	pf = it->funcs;
+	if (pf && pf->prim_i2c)
+		return pf->prim_i2c(pval, cout, putype, it);
+
+	/* Should type be omitted? */
+	if ((it->itype != ASN1_ITYPE_PRIMITIVE) ||
+	    (it->utype != V_ASN1_BOOLEAN)) {
+		if (!*pval)
+			return -1;
+	}
+
+	if (it->itype == ASN1_ITYPE_MSTRING) {
+		/* If MSTRING type set the underlying type */
+		strtmp = (ASN1_STRING *)*pval;
+		utype = strtmp->type;
+		*putype = utype;
+	} else if (it->utype == V_ASN1_ANY) {
+		/* If ANY set type and pointer to value */
+		ASN1_TYPE *typ;
+		typ = (ASN1_TYPE *)*pval;
+		utype = typ->type;
+		*putype = utype;
+		pval = &typ->value.asn1_value;
+	} else
+		utype = *putype;
+
+	switch (utype) {
+	case V_ASN1_OBJECT:
+		otmp = (ASN1_OBJECT *)*pval;
+		cont = otmp->data;
+		len = otmp->length;
+		break;
+
+	case V_ASN1_NULL:
+		cont = NULL;
+		len = 0;
+		break;
+
+	case V_ASN1_BOOLEAN:
+		tbool = (ASN1_BOOLEAN *)pval;
+		if (*tbool == -1)
+			return -1;
+		if (it->utype != V_ASN1_ANY) {
+			/* Default handling if value == size field then omit */
+			if (*tbool && (it->size > 0))
+				return -1;
+			if (!*tbool && !it->size)
+				return -1;
+		}
+		c = (unsigned char)*tbool;
+		cont = &c;
+		len = 1;
+		break;
+
+	case V_ASN1_BIT_STRING:
+		return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
+		    cout ? &cout : NULL);
+		break;
+
+	case V_ASN1_INTEGER:
+	case V_ASN1_ENUMERATED:
+		/* These are all have the same content format
+		 * as ASN1_INTEGER
+		 */
+		return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval,
+		    cout ? &cout : NULL);
+		break;
+
+	case V_ASN1_OCTET_STRING:
+	case V_ASN1_NUMERICSTRING:
+	case V_ASN1_PRINTABLESTRING:
+	case V_ASN1_T61STRING:
+	case V_ASN1_VIDEOTEXSTRING:
+	case V_ASN1_IA5STRING:
+	case V_ASN1_UTCTIME:
+	case V_ASN1_GENERALIZEDTIME:
+	case V_ASN1_GRAPHICSTRING:
+	case V_ASN1_VISIBLESTRING:
+	case V_ASN1_GENERALSTRING:
+	case V_ASN1_UNIVERSALSTRING:
+	case V_ASN1_BMPSTRING:
+	case V_ASN1_UTF8STRING:
+	case V_ASN1_SEQUENCE:
+	case V_ASN1_SET:
+	default:
+		/* All based on ASN1_STRING and handled the same */
+		strtmp = (ASN1_STRING *)*pval;
+		/* Special handling for NDEF */
+		if ((it->size == ASN1_TFLG_NDEF) &&
+		    (strtmp->flags & ASN1_STRING_FLAG_NDEF)) {
+			if (cout) {
+				strtmp->data = cout;
+				strtmp->length = 0;
+			}
+			/* Special return code */
+			return -2;
+		}
+		cont = strtmp->data;
+		len = strtmp->length;
+
+		break;
+
+	}
+	if (cout && len)
+		memcpy(cout, cont, len);
+	return len;
+}
diff --git a/crypto/libressl/crypto/asn1/tasn_fre.c b/crypto/libressl/crypto/asn1/tasn_fre.c
new file mode 100644
index 0000000000..5f0af0642c
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/tasn_fre.c
@@ -0,0 +1,243 @@
+/* $OpenBSD: tasn_fre.c,v 1.13 2015/02/14 13:32:46 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include 
+#include 
+#include 
+#include 
+
+static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
+    int combine);
+
+/* Free up an ASN1 structure */
+
+void
+ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
+{
+	asn1_item_combine_free(&val, it, 0);
+}
+
+void
+ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+	asn1_item_combine_free(pval, it, 0);
+}
+
+static void
+asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
+{
+	const ASN1_TEMPLATE *tt = NULL, *seqtt;
+	const ASN1_EXTERN_FUNCS *ef;
+	const ASN1_AUX *aux = it->funcs;
+	ASN1_aux_cb *asn1_cb = NULL;
+	int i;
+
+	if (pval == NULL || *pval == NULL)
+		return;
+
+	if (aux != NULL && aux->asn1_cb != NULL)
+		asn1_cb = aux->asn1_cb;
+
+	switch (it->itype) {
+	case ASN1_ITYPE_PRIMITIVE:
+		if (it->templates)
+			ASN1_template_free(pval, it->templates);
+		else
+			ASN1_primitive_free(pval, it);
+		break;
+
+	case ASN1_ITYPE_MSTRING:
+		ASN1_primitive_free(pval, it);
+		break;
+
+	case ASN1_ITYPE_CHOICE:
+		if (asn1_cb) {
+			i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
+			if (i == 2)
+				return;
+		}
+		i = asn1_get_choice_selector(pval, it);
+		if ((i >= 0) && (i < it->tcount)) {
+			ASN1_VALUE **pchval;
+			tt = it->templates + i;
+			pchval = asn1_get_field_ptr(pval, tt);
+			ASN1_template_free(pchval, tt);
+		}
+		if (asn1_cb)
+			asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
+		if (!combine) {
+			free(*pval);
+			*pval = NULL;
+		}
+		break;
+
+	case ASN1_ITYPE_EXTERN:
+		ef = it->funcs;
+		if (ef && ef->asn1_ex_free)
+			ef->asn1_ex_free(pval, it);
+		break;
+
+	case ASN1_ITYPE_NDEF_SEQUENCE:
+	case ASN1_ITYPE_SEQUENCE:
+		if (asn1_do_lock(pval, -1, it) > 0)
+			return;
+		if (asn1_cb) {
+			i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
+			if (i == 2)
+				return;
+		}
+		asn1_enc_free(pval, it);
+		/* If we free up as normal we will invalidate any
+		 * ANY DEFINED BY field and we wont be able to
+		 * determine the type of the field it defines. So
+		 * free up in reverse order.
+		 */
+		tt = it->templates + it->tcount - 1;
+		for (i = 0; i < it->tcount; tt--, i++) {
+			ASN1_VALUE **pseqval;
+			seqtt = asn1_do_adb(pval, tt, 0);
+			if (!seqtt)
+				continue;
+			pseqval = asn1_get_field_ptr(pval, seqtt);
+			ASN1_template_free(pseqval, seqtt);
+		}
+		if (asn1_cb)
+			asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
+		if (!combine) {
+			free(*pval);
+			*pval = NULL;
+		}
+		break;
+	}
+}
+
+void
+ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+{
+	int i;
+	if (tt->flags & ASN1_TFLG_SK_MASK) {
+		STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
+		for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
+			ASN1_VALUE *vtmp;
+			vtmp = sk_ASN1_VALUE_value(sk, i);
+			asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item),
+			    0);
+		}
+		sk_ASN1_VALUE_free(sk);
+		*pval = NULL;
+	} else
+		asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item),
+		    tt->flags & ASN1_TFLG_COMBINE);
+}
+
+void
+ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+	int utype;
+	if (it) {
+		const ASN1_PRIMITIVE_FUNCS *pf;
+		pf = it->funcs;
+		if (pf && pf->prim_free) {
+			pf->prim_free(pval, it);
+			return;
+		}
+	}
+	/* Special case: if 'it' is NULL free contents of ASN1_TYPE */
+	if (!it) {
+		ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
+		utype = typ->type;
+		pval = &typ->value.asn1_value;
+		if (!*pval)
+			return;
+	} else if (it->itype == ASN1_ITYPE_MSTRING) {
+		utype = -1;
+		if (!*pval)
+			return;
+	} else {
+		utype = it->utype;
+		if ((utype != V_ASN1_BOOLEAN) && !*pval)
+			return;
+	}
+
+	switch (utype) {
+	case V_ASN1_OBJECT:
+		ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
+		break;
+
+	case V_ASN1_BOOLEAN:
+		if (it)
+			*(ASN1_BOOLEAN *)pval = it->size;
+		else
+			*(ASN1_BOOLEAN *)pval = -1;
+		return;
+
+	case V_ASN1_NULL:
+		break;
+
+	case V_ASN1_ANY:
+		ASN1_primitive_free(pval, NULL);
+		free(*pval);
+		break;
+
+	default:
+		ASN1_STRING_free((ASN1_STRING *)*pval);
+		break;
+	}
+	*pval = NULL;
+}
diff --git a/crypto/libressl/crypto/asn1/tasn_new.c b/crypto/libressl/crypto/asn1/tasn_new.c
new file mode 100644
index 0000000000..a57c693d18
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/tasn_new.c
@@ -0,0 +1,374 @@
+/* $OpenBSD: tasn_new.c,v 1.14 2015/02/14 15:23:57 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2004 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
+    int combine);
+static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+ASN1_VALUE *
+ASN1_item_new(const ASN1_ITEM *it)
+{
+	ASN1_VALUE *ret = NULL;
+	if (ASN1_item_ex_new(&ret, it) > 0)
+		return ret;
+	return NULL;
+}
+
+/* Allocate an ASN1 structure */
+
+int
+ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+	return asn1_item_ex_combine_new(pval, it, 0);
+}
+
+static int
+asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
+{
+	const ASN1_TEMPLATE *tt = NULL;
+	const ASN1_EXTERN_FUNCS *ef;
+	const ASN1_AUX *aux = it->funcs;
+	ASN1_aux_cb *asn1_cb = NULL;
+	ASN1_VALUE **pseqval;
+	int i;
+
+	if (aux != NULL && aux->asn1_cb != NULL)
+		asn1_cb = aux->asn1_cb;
+
+	if (!combine)
+		*pval = NULL;
+
+#ifdef CRYPTO_MDEBUG
+	if (it->sname)
+		CRYPTO_push_info(it->sname);
+#endif
+
+	switch (it->itype) {
+	case ASN1_ITYPE_EXTERN:
+		ef = it->funcs;
+		if (ef && ef->asn1_ex_new) {
+			if (!ef->asn1_ex_new(pval, it))
+				goto memerr;
+		}
+		break;
+
+	case ASN1_ITYPE_PRIMITIVE:
+		if (it->templates) {
+			if (!ASN1_template_new(pval, it->templates))
+				goto memerr;
+		} else if (!ASN1_primitive_new(pval, it))
+			goto memerr;
+		break;
+
+	case ASN1_ITYPE_MSTRING:
+		if (!ASN1_primitive_new(pval, it))
+			goto memerr;
+		break;
+
+	case ASN1_ITYPE_CHOICE:
+		if (asn1_cb) {
+			i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
+			if (!i)
+				goto auxerr;
+			if (i == 2) {
+#ifdef CRYPTO_MDEBUG
+				if (it->sname)
+					CRYPTO_pop_info();
+#endif
+				return 1;
+			}
+		}
+		if (!combine) {
+			*pval = calloc(1, it->size);
+			if (!*pval)
+				goto memerr;
+		}
+		asn1_set_choice_selector(pval, -1, it);
+		if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
+			goto auxerr;
+		break;
+
+	case ASN1_ITYPE_NDEF_SEQUENCE:
+	case ASN1_ITYPE_SEQUENCE:
+		if (asn1_cb) {
+			i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
+			if (!i)
+				goto auxerr;
+			if (i == 2) {
+#ifdef CRYPTO_MDEBUG
+				if (it->sname)
+					CRYPTO_pop_info();
+#endif
+				return 1;
+			}
+		}
+		if (!combine) {
+			*pval = calloc(1, it->size);
+			if (!*pval)
+				goto memerr;
+			asn1_do_lock(pval, 0, it);
+			asn1_enc_init(pval, it);
+		}
+		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+			pseqval = asn1_get_field_ptr(pval, tt);
+			if (!ASN1_template_new(pseqval, tt))
+				goto memerr;
+		}
+		if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
+			goto auxerr;
+		break;
+	}
+#ifdef CRYPTO_MDEBUG
+	if (it->sname)
+		CRYPTO_pop_info();
+#endif
+	return 1;
+
+memerr:
+	ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE);
+#ifdef CRYPTO_MDEBUG
+	if (it->sname)
+		CRYPTO_pop_info();
+#endif
+	return 0;
+
+auxerr:
+	ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR);
+	ASN1_item_ex_free(pval, it);
+#ifdef CRYPTO_MDEBUG
+	if (it->sname)
+		CRYPTO_pop_info();
+#endif
+	return 0;
+
+}
+
+static void
+asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+	const ASN1_EXTERN_FUNCS *ef;
+
+	switch (it->itype) {
+	case ASN1_ITYPE_EXTERN:
+		ef = it->funcs;
+		if (ef && ef->asn1_ex_clear)
+			ef->asn1_ex_clear(pval, it);
+		else
+			*pval = NULL;
+		break;
+
+	case ASN1_ITYPE_PRIMITIVE:
+		if (it->templates)
+			asn1_template_clear(pval, it->templates);
+		else
+			asn1_primitive_clear(pval, it);
+		break;
+
+	case ASN1_ITYPE_MSTRING:
+		asn1_primitive_clear(pval, it);
+		break;
+
+	case ASN1_ITYPE_CHOICE:
+	case ASN1_ITYPE_SEQUENCE:
+	case ASN1_ITYPE_NDEF_SEQUENCE:
+		*pval = NULL;
+		break;
+	}
+}
+
+int
+ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+{
+	const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
+	int ret;
+
+	if (tt->flags & ASN1_TFLG_OPTIONAL) {
+		asn1_template_clear(pval, tt);
+		return 1;
+	}
+	/* If ANY DEFINED BY nothing to do */
+
+	if (tt->flags & ASN1_TFLG_ADB_MASK) {
+		*pval = NULL;
+		return 1;
+	}
+#ifdef CRYPTO_MDEBUG
+	if (tt->field_name)
+		CRYPTO_push_info(tt->field_name);
+#endif
+	/* If SET OF or SEQUENCE OF, its a STACK */
+	if (tt->flags & ASN1_TFLG_SK_MASK) {
+		STACK_OF(ASN1_VALUE) *skval;
+		skval = sk_ASN1_VALUE_new_null();
+		if (!skval) {
+			ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE);
+			ret = 0;
+			goto done;
+		}
+		*pval = (ASN1_VALUE *)skval;
+		ret = 1;
+		goto done;
+	}
+	/* Otherwise pass it back to the item routine */
+	ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
+done:
+#ifdef CRYPTO_MDEBUG
+	if (it->sname)
+		CRYPTO_pop_info();
+#endif
+	return ret;
+}
+
+static void
+asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+{
+	/* If ADB or STACK just NULL the field */
+	if (tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK))
+		*pval = NULL;
+	else
+		asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
+}
+
+
+/* NB: could probably combine most of the real XXX_new() behaviour and junk
+ * all the old functions.
+ */
+
+int
+ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+	ASN1_TYPE *typ;
+	ASN1_STRING *str;
+	int utype;
+
+	if (it && it->funcs) {
+		const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
+		if (pf->prim_new)
+			return pf->prim_new(pval, it);
+	}
+
+	if (!it || (it->itype == ASN1_ITYPE_MSTRING))
+		utype = V_ASN1_UNDEF;
+	else
+		utype = it->utype;
+	switch (utype) {
+	case V_ASN1_OBJECT:
+		*pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
+		return 1;
+
+	case V_ASN1_BOOLEAN:
+		*(ASN1_BOOLEAN *)pval = it->size;
+		return 1;
+
+	case V_ASN1_NULL:
+		*pval = (ASN1_VALUE *)1;
+		return 1;
+
+	case V_ASN1_ANY:
+		typ = malloc(sizeof(ASN1_TYPE));
+		if (typ != NULL) {
+			typ->value.ptr = NULL;
+			typ->type = V_ASN1_UNDEF;
+		}
+		*pval = (ASN1_VALUE *)typ;
+		break;
+
+	default:
+		str = ASN1_STRING_type_new(utype);
+		if (it != NULL && it->itype == ASN1_ITYPE_MSTRING &&
+		    str != NULL)
+			str->flags |= ASN1_STRING_FLAG_MSTRING;
+		*pval = (ASN1_VALUE *)str;
+		break;
+	}
+	if (*pval)
+		return 1;
+	return 0;
+}
+
+static void
+asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+	int utype;
+	if (it && it->funcs) {
+		const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
+		if (pf->prim_clear)
+			pf->prim_clear(pval, it);
+		else
+			*pval = NULL;
+		return;
+	}
+	if (!it || (it->itype == ASN1_ITYPE_MSTRING))
+		utype = V_ASN1_UNDEF;
+	else
+		utype = it->utype;
+	if (utype == V_ASN1_BOOLEAN)
+		*(ASN1_BOOLEAN *)pval = it->size;
+	else
+		*pval = NULL;
+}
diff --git a/crypto/libressl/crypto/asn1/tasn_prn.c b/crypto/libressl/crypto/asn1/tasn_prn.c
new file mode 100644
index 0000000000..f8f3737072
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/tasn_prn.c
@@ -0,0 +1,596 @@
+/* $OpenBSD: tasn_prn.c,v 1.13 2015/02/14 15:15:27 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000,2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "asn1_locl.h"
+
+/* Print routines.
+ */
+
+/* ASN1_PCTX routines */
+
+ASN1_PCTX default_pctx = {
+	ASN1_PCTX_FLAGS_SHOW_ABSENT,	/* flags */
+	0,				/* nm_flags */
+	0,				/* cert_flags */
+	0,				/* oid_flags */
+	0				/* str_flags */
+};
+
+
+ASN1_PCTX *
+ASN1_PCTX_new(void)
+{
+	ASN1_PCTX *ret;
+	ret = malloc(sizeof(ASN1_PCTX));
+	if (ret == NULL) {
+		ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	ret->flags = 0;
+	ret->nm_flags = 0;
+	ret->cert_flags = 0;
+	ret->oid_flags = 0;
+	ret->str_flags = 0;
+	return ret;
+}
+
+void
+ASN1_PCTX_free(ASN1_PCTX *p)
+{
+	free(p);
+}
+
+unsigned long
+ASN1_PCTX_get_flags(ASN1_PCTX *p)
+{
+	return p->flags;
+}
+
+void
+ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
+{
+	p->flags = flags;
+}
+
+unsigned long
+ASN1_PCTX_get_nm_flags(ASN1_PCTX *p)
+{
+	return p->nm_flags;
+}
+
+void
+ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
+{
+	p->nm_flags = flags;
+}
+
+unsigned long
+ASN1_PCTX_get_cert_flags(ASN1_PCTX *p)
+{
+	return p->cert_flags;
+}
+
+void
+ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
+{
+	p->cert_flags = flags;
+}
+
+unsigned long
+ASN1_PCTX_get_oid_flags(ASN1_PCTX *p)
+{
+	return p->oid_flags;
+}
+
+void
+ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
+{
+	p->oid_flags = flags;
+}
+
+unsigned long
+ASN1_PCTX_get_str_flags(ASN1_PCTX *p)
+{
+	return p->str_flags;
+}
+
+void
+ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
+{
+	p->str_flags = flags;
+}
+
+/* Main print routines */
+
+static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+    const ASN1_ITEM *it, const char *fname, const char *sname, int nohdr,
+    const ASN1_PCTX *pctx);
+
+int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+    const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
+
+static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
+    const ASN1_ITEM *it, int indent, const char *fname, const char *sname,
+    const ASN1_PCTX *pctx);
+
+static int asn1_print_fsname(BIO *out, int indent, const char *fname,
+    const char *sname, const ASN1_PCTX *pctx);
+
+int
+ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, const ASN1_ITEM *it,
+    const ASN1_PCTX *pctx)
+{
+	const char *sname;
+
+	if (pctx == NULL)
+		pctx = &default_pctx;
+	if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
+		sname = NULL;
+	else
+		sname = it->sname;
+	return asn1_item_print_ctx(out, &ifld, indent, it, NULL, sname,
+	    0, pctx);
+}
+
+static int
+asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, const ASN1_ITEM *it,
+    const char *fname, const char *sname, int nohdr, const ASN1_PCTX *pctx)
+{
+	const ASN1_TEMPLATE *tt;
+	const ASN1_EXTERN_FUNCS *ef;
+	ASN1_VALUE **tmpfld;
+	const ASN1_AUX *aux = it->funcs;
+	ASN1_aux_cb *asn1_cb;
+	ASN1_PRINT_ARG parg;
+	int i;
+
+	if (aux && aux->asn1_cb) {
+		parg.out = out;
+		parg.indent = indent;
+		parg.pctx = pctx;
+		asn1_cb = aux->asn1_cb;
+	} else
+		asn1_cb = NULL;
+
+	if (*fld == NULL) {
+		if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) {
+			if (!nohdr &&
+			    !asn1_print_fsname(out, indent, fname, sname, pctx))
+				return 0;
+			if (BIO_puts(out, "\n") <= 0)
+				return 0;
+		}
+		return 1;
+	}
+
+	switch (it->itype) {
+	case ASN1_ITYPE_PRIMITIVE:
+		if (it->templates) {
+			if (!asn1_template_print_ctx(out, fld, indent,
+			    it->templates, pctx))
+				return 0;
+		}
+		/* fall thru */
+	case ASN1_ITYPE_MSTRING:
+		if (!asn1_primitive_print(out, fld, it,
+		    indent, fname, sname, pctx))
+			return 0;
+		break;
+
+	case ASN1_ITYPE_EXTERN:
+		if (!nohdr &&
+		    !asn1_print_fsname(out, indent, fname, sname, pctx))
+			return 0;
+		/* Use new style print routine if possible */
+		ef = it->funcs;
+		if (ef && ef->asn1_ex_print) {
+			i = ef->asn1_ex_print(out, fld, indent, "", pctx);
+			if (!i)
+				return 0;
+			if ((i == 2) && (BIO_puts(out, "\n") <= 0))
+				return 0;
+			return 1;
+		} else if (sname &&
+		    BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
+			return 0;
+		break;
+
+	case ASN1_ITYPE_CHOICE:
+		/* CHOICE type, get selector */
+		i = asn1_get_choice_selector(fld, it);
+		/* This should never happen... */
+		if ((i < 0) || (i >= it->tcount)) {
+			if (BIO_printf(out,
+			    "ERROR: selector [%d] invalid\n", i) <= 0)
+				return 0;
+			return 1;
+		}
+		tt = it->templates + i;
+		tmpfld = asn1_get_field_ptr(fld, tt);
+		if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
+			return 0;
+		break;
+
+	case ASN1_ITYPE_SEQUENCE:
+	case ASN1_ITYPE_NDEF_SEQUENCE:
+		if (!nohdr &&
+		    !asn1_print_fsname(out, indent, fname, sname, pctx))
+			return 0;
+		if (fname || sname) {
+			if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
+				if (BIO_puts(out, " {\n") <= 0)
+					return 0;
+			} else {
+				if (BIO_puts(out, "\n") <= 0)
+					return 0;
+			}
+		}
+
+		if (asn1_cb) {
+			i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
+			if (i == 0)
+				return 0;
+			if (i == 2)
+				return 1;
+		}
+
+		/* Print each field entry */
+		for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+			const ASN1_TEMPLATE *seqtt;
+
+			seqtt = asn1_do_adb(fld, tt, 1);
+			if (seqtt == NULL)
+				return 0;
+			tmpfld = asn1_get_field_ptr(fld, seqtt);
+			if (!asn1_template_print_ctx(out, tmpfld, indent + 2,
+			    seqtt, pctx))
+				return 0;
+		}
+		if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
+			if (BIO_printf(out, "%*s}\n", indent, "") < 0)
+				return 0;
+		}
+
+		if (asn1_cb) {
+			i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
+			if (i == 0)
+				return 0;
+		}
+		break;
+
+	default:
+		BIO_printf(out, "Unprocessed type %d\n", it->itype);
+		return 0;
+	}
+
+	return 1;
+}
+
+int
+asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+    const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
+{
+	int i, flags;
+	const char *sname, *fname;
+
+	flags = tt->flags;
+	if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
+		sname = ASN1_ITEM_ptr(tt->item)->sname;
+	else
+		sname = NULL;
+	if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
+		fname = NULL;
+	else
+		fname = tt->field_name;
+	if (flags & ASN1_TFLG_SK_MASK) {
+		char *tname;
+		ASN1_VALUE *skitem;
+		STACK_OF(ASN1_VALUE) *stack;
+
+		/* SET OF, SEQUENCE OF */
+		if (fname) {
+			if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) {
+				if (flags & ASN1_TFLG_SET_OF)
+					tname = "SET";
+				else
+					tname = "SEQUENCE";
+				if (BIO_printf(out, "%*s%s OF %s {\n",
+				    indent, "", tname, tt->field_name) <= 0)
+					return 0;
+			} else if (BIO_printf(out, "%*s%s:\n", indent, "",
+			    fname) <= 0)
+				return 0;
+		}
+		stack = (STACK_OF(ASN1_VALUE) *)*fld;
+		for (i = 0; i < sk_ASN1_VALUE_num(stack); i++) {
+			if ((i > 0) && (BIO_puts(out, "\n") <= 0))
+				return 0;
+			skitem = sk_ASN1_VALUE_value(stack, i);
+			if (!asn1_item_print_ctx(out, &skitem, indent + 2,
+			    ASN1_ITEM_ptr(tt->item), NULL, NULL, 1, pctx))
+				return 0;
+		}
+		if (!i && BIO_printf(out, "%*s\n", indent + 2, "") <= 0)
+			return 0;
+		if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
+			if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
+				return 0;
+		}
+		return 1;
+	}
+	return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
+	    fname, sname, 0, pctx);
+}
+
+static int
+asn1_print_fsname(BIO *out, int indent, const char *fname, const char *sname,
+    const ASN1_PCTX *pctx)
+{
+	static char spaces[] = "                    ";
+	const int nspaces = sizeof(spaces) - 1;
+
+	while (indent > nspaces) {
+		if (BIO_write(out, spaces, nspaces) != nspaces)
+			return 0;
+		indent -= nspaces;
+	}
+	if (BIO_write(out, spaces, indent) != indent)
+		return 0;
+	if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
+		sname = NULL;
+	if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
+		fname = NULL;
+	if (!sname && !fname)
+		return 1;
+	if (fname) {
+		if (BIO_puts(out, fname) <= 0)
+			return 0;
+	}
+	if (sname) {
+		if (fname) {
+			if (BIO_printf(out, " (%s)", sname) <= 0)
+				return 0;
+		} else {
+			if (BIO_puts(out, sname) <= 0)
+				return 0;
+		}
+	}
+	if (BIO_write(out, ": ", 2) != 2)
+		return 0;
+	return 1;
+}
+
+static int
+asn1_print_boolean_ctx(BIO *out, int boolval, const ASN1_PCTX *pctx)
+{
+	const char *str;
+	switch (boolval) {
+	case -1:
+		str = "BOOL ABSENT";
+		break;
+
+	case 0:
+		str = "FALSE";
+		break;
+
+	default:
+		str = "TRUE";
+		break;
+
+	}
+
+	if (BIO_puts(out, str) <= 0)
+		return 0;
+	return 1;
+
+}
+
+static int
+asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str, const ASN1_PCTX *pctx)
+{
+	char *s;
+	int ret = 1;
+	s = i2s_ASN1_INTEGER(NULL, str);
+	if (BIO_puts(out, s) <= 0)
+		ret = 0;
+	free(s);
+	return ret;
+}
+
+static int
+asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid, const ASN1_PCTX *pctx)
+{
+	char objbuf[80];
+	const char *ln;
+	ln = OBJ_nid2ln(OBJ_obj2nid(oid));
+	if (!ln)
+		ln = "";
+	OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1);
+	if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
+		return 0;
+	return 1;
+}
+
+static int
+asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent,
+    const ASN1_PCTX *pctx)
+{
+	if (str->type == V_ASN1_BIT_STRING) {
+		if (BIO_printf(out, " (%ld unused bits)\n",
+		    str->flags & 0x7) <= 0)
+			return 0;
+	} else if (BIO_puts(out, "\n") <= 0)
+		return 0;
+	if ((str->length > 0) &&
+	    BIO_dump_indent(out, (char *)str->data, str->length,
+	    indent + 2) <= 0)
+		return 0;
+	return 1;
+}
+
+static int
+asn1_primitive_print(BIO *out, ASN1_VALUE **fld, const ASN1_ITEM *it,
+    int indent, const char *fname, const char *sname, const ASN1_PCTX *pctx)
+{
+	long utype;
+	ASN1_STRING *str;
+	int ret = 1, needlf = 1;
+	const char *pname;
+	const ASN1_PRIMITIVE_FUNCS *pf;
+
+	pf = it->funcs;
+	if (!asn1_print_fsname(out, indent, fname, sname, pctx))
+		return 0;
+	if (pf && pf->prim_print)
+		return pf->prim_print(out, fld, it, indent, pctx);
+	str = (ASN1_STRING *)*fld;
+	if (it->itype == ASN1_ITYPE_MSTRING)
+		utype = str->type & ~V_ASN1_NEG;
+	else
+		utype = it->utype;
+	if (utype == V_ASN1_ANY) {
+		ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
+		utype = atype->type;
+		fld = &atype->value.asn1_value;
+		str = (ASN1_STRING *)*fld;
+		if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
+			pname = NULL;
+		else
+			pname = ASN1_tag2str(utype);
+	} else {
+		if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
+			pname = ASN1_tag2str(utype);
+		else
+			pname = NULL;
+	}
+
+	if (utype == V_ASN1_NULL) {
+		if (BIO_puts(out, "NULL\n") <= 0)
+			return 0;
+		return 1;
+	}
+
+	if (pname) {
+		if (BIO_puts(out, pname) <= 0)
+			return 0;
+		if (BIO_puts(out, ":") <= 0)
+			return 0;
+	}
+
+	switch (utype) {
+	case V_ASN1_BOOLEAN:
+		{
+			int boolval = *(int *)fld;
+			if (boolval == -1)
+				boolval = it->size;
+			ret = asn1_print_boolean_ctx(out, boolval, pctx);
+		}
+		break;
+
+	case V_ASN1_INTEGER:
+	case V_ASN1_ENUMERATED:
+		ret = asn1_print_integer_ctx(out, str, pctx);
+		break;
+
+	case V_ASN1_UTCTIME:
+		ret = ASN1_UTCTIME_print(out, str);
+		break;
+
+	case V_ASN1_GENERALIZEDTIME:
+		ret = ASN1_GENERALIZEDTIME_print(out, str);
+		break;
+
+	case V_ASN1_OBJECT:
+		ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx);
+		break;
+
+	case V_ASN1_OCTET_STRING:
+	case V_ASN1_BIT_STRING:
+		ret = asn1_print_obstring_ctx(out, str, indent, pctx);
+		needlf = 0;
+		break;
+
+	case V_ASN1_SEQUENCE:
+	case V_ASN1_SET:
+	case V_ASN1_OTHER:
+		if (BIO_puts(out, "\n") <= 0)
+			return 0;
+		if (ASN1_parse_dump(out, str->data, str->length,
+		    indent, 0) <= 0)
+			ret = 0;
+		needlf = 0;
+		break;
+
+	default:
+		ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
+	}
+	if (!ret)
+		return 0;
+	if (needlf && BIO_puts(out, "\n") <= 0)
+		return 0;
+	return 1;
+}
diff --git a/crypto/libressl/crypto/asn1/tasn_typ.c b/crypto/libressl/crypto/asn1/tasn_typ.c
new file mode 100644
index 0000000000..2ac53489e3
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/tasn_typ.c
@@ -0,0 +1,799 @@
+/* $OpenBSD: tasn_typ.c,v 1.12 2015/07/24 13:49:58 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include 
+#include 
+#include 
+
+/* Declarations for string types */
+
+const ASN1_ITEM ASN1_INTEGER_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_INTEGER,
+	.sname = "ASN1_INTEGER",
+};
+
+ASN1_INTEGER *
+d2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **in, long len)
+{
+	return (ASN1_INTEGER *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ASN1_INTEGER_it);
+}
+
+int
+i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_INTEGER_it);
+}
+
+ASN1_INTEGER *
+ASN1_INTEGER_new(void)
+{
+	return (ASN1_INTEGER *)ASN1_item_new(&ASN1_INTEGER_it);
+}
+
+void
+ASN1_INTEGER_free(ASN1_INTEGER *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ASN1_INTEGER_it);
+}
+
+
+const ASN1_ITEM ASN1_ENUMERATED_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_ENUMERATED,
+	.sname = "ASN1_ENUMERATED",
+};
+
+ASN1_ENUMERATED *
+d2i_ASN1_ENUMERATED(ASN1_ENUMERATED **a, const unsigned char **in, long len)
+{
+	return (ASN1_ENUMERATED *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ASN1_ENUMERATED_it);
+}
+
+int
+i2d_ASN1_ENUMERATED(ASN1_ENUMERATED *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_ENUMERATED_it);
+}
+
+ASN1_ENUMERATED *
+ASN1_ENUMERATED_new(void)
+{
+	return (ASN1_ENUMERATED *)ASN1_item_new(&ASN1_ENUMERATED_it);
+}
+
+void
+ASN1_ENUMERATED_free(ASN1_ENUMERATED *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ASN1_ENUMERATED_it);
+}
+
+
+const ASN1_ITEM ASN1_BIT_STRING_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_BIT_STRING,
+	.sname = "ASN1_BIT_STRING",
+};
+
+ASN1_BIT_STRING *
+d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, const unsigned char **in, long len)
+{
+	return (ASN1_BIT_STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ASN1_BIT_STRING_it);
+}
+
+int
+i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_BIT_STRING_it);
+}
+
+ASN1_BIT_STRING *
+ASN1_BIT_STRING_new(void)
+{
+	return (ASN1_BIT_STRING *)ASN1_item_new(&ASN1_BIT_STRING_it);
+}
+
+void
+ASN1_BIT_STRING_free(ASN1_BIT_STRING *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ASN1_BIT_STRING_it);
+}
+
+
+const ASN1_ITEM ASN1_OCTET_STRING_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_OCTET_STRING,
+	.sname = "ASN1_OCTET_STRING",
+};
+
+ASN1_OCTET_STRING *
+d2i_ASN1_OCTET_STRING(ASN1_OCTET_STRING **a, const unsigned char **in, long len)
+{
+	return (ASN1_OCTET_STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ASN1_OCTET_STRING_it);
+}
+
+int
+i2d_ASN1_OCTET_STRING(ASN1_OCTET_STRING *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_OCTET_STRING_it);
+}
+
+ASN1_OCTET_STRING *
+ASN1_OCTET_STRING_new(void)
+{
+	return (ASN1_OCTET_STRING *)ASN1_item_new(&ASN1_OCTET_STRING_it);
+}
+
+void
+ASN1_OCTET_STRING_free(ASN1_OCTET_STRING *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ASN1_OCTET_STRING_it);
+}
+
+
+const ASN1_ITEM ASN1_NULL_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_NULL,
+	.sname = "ASN1_NULL",
+};
+
+ASN1_NULL *
+d2i_ASN1_NULL(ASN1_NULL **a, const unsigned char **in, long len)
+{
+	return (ASN1_NULL *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ASN1_NULL_it);
+}
+
+int
+i2d_ASN1_NULL(ASN1_NULL *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_NULL_it);
+}
+
+ASN1_NULL *
+ASN1_NULL_new(void)
+{
+	return (ASN1_NULL *)ASN1_item_new(&ASN1_NULL_it);
+}
+
+void
+ASN1_NULL_free(ASN1_NULL *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ASN1_NULL_it);
+}
+
+
+const ASN1_ITEM ASN1_OBJECT_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_OBJECT,
+	.sname = "ASN1_OBJECT",
+};
+
+
+const ASN1_ITEM ASN1_UTF8STRING_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_UTF8STRING,
+	.sname = "ASN1_UTF8STRING",
+};
+
+ASN1_UTF8STRING *
+d2i_ASN1_UTF8STRING(ASN1_UTF8STRING **a, const unsigned char **in, long len)
+{
+	return (ASN1_UTF8STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ASN1_UTF8STRING_it);
+}
+
+int
+i2d_ASN1_UTF8STRING(ASN1_UTF8STRING *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_UTF8STRING_it);
+}
+
+ASN1_UTF8STRING *
+ASN1_UTF8STRING_new(void)
+{
+	return (ASN1_UTF8STRING *)ASN1_item_new(&ASN1_UTF8STRING_it);
+}
+
+void
+ASN1_UTF8STRING_free(ASN1_UTF8STRING *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ASN1_UTF8STRING_it);
+}
+
+
+const ASN1_ITEM ASN1_PRINTABLESTRING_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_PRINTABLESTRING,
+	.sname = "ASN1_PRINTABLESTRING",
+};
+
+ASN1_PRINTABLESTRING *
+d2i_ASN1_PRINTABLESTRING(ASN1_PRINTABLESTRING **a, const unsigned char **in,
+    long len)
+{
+	return (ASN1_PRINTABLESTRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ASN1_PRINTABLESTRING_it);
+}
+
+int
+i2d_ASN1_PRINTABLESTRING(ASN1_PRINTABLESTRING *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_PRINTABLESTRING_it);
+}
+
+ASN1_PRINTABLESTRING *
+ASN1_PRINTABLESTRING_new(void)
+{
+	return (ASN1_PRINTABLESTRING *)ASN1_item_new(&ASN1_PRINTABLESTRING_it);
+}
+
+void
+ASN1_PRINTABLESTRING_free(ASN1_PRINTABLESTRING *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ASN1_PRINTABLESTRING_it);
+}
+
+
+const ASN1_ITEM ASN1_T61STRING_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_T61STRING,
+	.sname = "ASN1_T61STRING",
+};
+
+ASN1_T61STRING *
+d2i_ASN1_T61STRING(ASN1_T61STRING **a, const unsigned char **in, long len)
+{
+	return (ASN1_T61STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ASN1_T61STRING_it);
+}
+
+int
+i2d_ASN1_T61STRING(ASN1_T61STRING *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_T61STRING_it);
+}
+
+ASN1_T61STRING *
+ASN1_T61STRING_new(void)
+{
+	return (ASN1_T61STRING *)ASN1_item_new(&ASN1_T61STRING_it);
+}
+
+void
+ASN1_T61STRING_free(ASN1_T61STRING *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ASN1_T61STRING_it);
+}
+
+
+const ASN1_ITEM ASN1_IA5STRING_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_IA5STRING,
+	.sname = "ASN1_IA5STRING",
+};
+
+ASN1_IA5STRING *
+d2i_ASN1_IA5STRING(ASN1_IA5STRING **a, const unsigned char **in, long len)
+{
+	return (ASN1_IA5STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ASN1_IA5STRING_it);
+}
+
+int
+i2d_ASN1_IA5STRING(ASN1_IA5STRING *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_IA5STRING_it);
+}
+
+ASN1_IA5STRING *
+ASN1_IA5STRING_new(void)
+{
+	return (ASN1_IA5STRING *)ASN1_item_new(&ASN1_IA5STRING_it);
+}
+
+void
+ASN1_IA5STRING_free(ASN1_IA5STRING *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ASN1_IA5STRING_it);
+}
+
+
+const ASN1_ITEM ASN1_GENERALSTRING_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_GENERALSTRING,
+	.sname = "ASN1_GENERALSTRING",
+};
+
+ASN1_GENERALSTRING *
+d2i_ASN1_GENERALSTRING(ASN1_GENERALSTRING **a, const unsigned char **in,
+    long len)
+{
+	return (ASN1_GENERALSTRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ASN1_GENERALSTRING_it);
+}
+
+int
+i2d_ASN1_GENERALSTRING(ASN1_GENERALSTRING *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_GENERALSTRING_it);
+}
+
+ASN1_GENERALSTRING *
+ASN1_GENERALSTRING_new(void)
+{
+	return (ASN1_GENERALSTRING *)ASN1_item_new(&ASN1_GENERALSTRING_it);
+}
+
+void
+ASN1_GENERALSTRING_free(ASN1_GENERALSTRING *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ASN1_GENERALSTRING_it);
+}
+
+
+const ASN1_ITEM ASN1_UTCTIME_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_UTCTIME,
+	.sname = "ASN1_UTCTIME",
+};
+
+ASN1_UTCTIME *
+d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, const unsigned char **in, long len)
+{
+	return (ASN1_UTCTIME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ASN1_UTCTIME_it);
+}
+
+int
+i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_UTCTIME_it);
+}
+
+ASN1_UTCTIME *
+ASN1_UTCTIME_new(void)
+{
+	return (ASN1_UTCTIME *)ASN1_item_new(&ASN1_UTCTIME_it);
+}
+
+void
+ASN1_UTCTIME_free(ASN1_UTCTIME *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ASN1_UTCTIME_it);
+}
+
+
+const ASN1_ITEM ASN1_GENERALIZEDTIME_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_GENERALIZEDTIME,
+	.sname = "ASN1_GENERALIZEDTIME",
+};
+
+ASN1_GENERALIZEDTIME *
+d2i_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME **a, const unsigned char **in,
+    long len)
+{
+	return (ASN1_GENERALIZEDTIME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ASN1_GENERALIZEDTIME_it);
+}
+
+int
+i2d_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_GENERALIZEDTIME_it);
+}
+
+ASN1_GENERALIZEDTIME *
+ASN1_GENERALIZEDTIME_new(void)
+{
+	return (ASN1_GENERALIZEDTIME *)ASN1_item_new(&ASN1_GENERALIZEDTIME_it);
+}
+
+void
+ASN1_GENERALIZEDTIME_free(ASN1_GENERALIZEDTIME *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ASN1_GENERALIZEDTIME_it);
+}
+
+
+const ASN1_ITEM ASN1_VISIBLESTRING_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_VISIBLESTRING,
+	.sname = "ASN1_VISIBLESTRING",
+};
+
+ASN1_VISIBLESTRING *
+d2i_ASN1_VISIBLESTRING(ASN1_VISIBLESTRING **a, const unsigned char **in,
+    long len)
+{
+	return (ASN1_VISIBLESTRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ASN1_VISIBLESTRING_it);
+}
+
+int
+i2d_ASN1_VISIBLESTRING(ASN1_VISIBLESTRING *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_VISIBLESTRING_it);
+}
+
+ASN1_VISIBLESTRING *
+ASN1_VISIBLESTRING_new(void)
+{
+	return (ASN1_VISIBLESTRING *)ASN1_item_new(&ASN1_VISIBLESTRING_it);
+}
+
+void
+ASN1_VISIBLESTRING_free(ASN1_VISIBLESTRING *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ASN1_VISIBLESTRING_it);
+}
+
+
+const ASN1_ITEM ASN1_UNIVERSALSTRING_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_UNIVERSALSTRING,
+	.sname = "ASN1_UNIVERSALSTRING",
+};
+
+ASN1_UNIVERSALSTRING *
+d2i_ASN1_UNIVERSALSTRING(ASN1_UNIVERSALSTRING **a, const unsigned char **in,
+    long len)
+{
+	return (ASN1_UNIVERSALSTRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ASN1_UNIVERSALSTRING_it);
+}
+
+int
+i2d_ASN1_UNIVERSALSTRING(ASN1_UNIVERSALSTRING *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_UNIVERSALSTRING_it);
+}
+
+ASN1_UNIVERSALSTRING *
+ASN1_UNIVERSALSTRING_new(void)
+{
+	return (ASN1_UNIVERSALSTRING *)ASN1_item_new(&ASN1_UNIVERSALSTRING_it);
+}
+
+void
+ASN1_UNIVERSALSTRING_free(ASN1_UNIVERSALSTRING *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ASN1_UNIVERSALSTRING_it);
+}
+
+
+const ASN1_ITEM ASN1_BMPSTRING_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_BMPSTRING,
+	.sname = "ASN1_BMPSTRING",
+};
+
+ASN1_BMPSTRING *
+d2i_ASN1_BMPSTRING(ASN1_BMPSTRING **a, const unsigned char **in, long len)
+{
+	return (ASN1_BMPSTRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ASN1_BMPSTRING_it);
+}
+
+int
+i2d_ASN1_BMPSTRING(ASN1_BMPSTRING *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_BMPSTRING_it);
+}
+
+ASN1_BMPSTRING *
+ASN1_BMPSTRING_new(void)
+{
+	return (ASN1_BMPSTRING *)ASN1_item_new(&ASN1_BMPSTRING_it);
+}
+
+void
+ASN1_BMPSTRING_free(ASN1_BMPSTRING *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ASN1_BMPSTRING_it);
+}
+
+
+const ASN1_ITEM ASN1_ANY_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_ANY,
+	.sname = "ASN1_ANY",
+};
+
+/* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */
+
+const ASN1_ITEM ASN1_SEQUENCE_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_SEQUENCE,
+	.sname = "ASN1_SEQUENCE",
+};
+
+
+ASN1_TYPE *
+d2i_ASN1_TYPE(ASN1_TYPE **a, const unsigned char **in, long len)
+{
+	return (ASN1_TYPE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ASN1_ANY_it);
+}
+
+int
+i2d_ASN1_TYPE(ASN1_TYPE *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_ANY_it);
+}
+
+ASN1_TYPE *
+ASN1_TYPE_new(void)
+{
+	return (ASN1_TYPE *)ASN1_item_new(&ASN1_ANY_it);
+}
+
+void
+ASN1_TYPE_free(ASN1_TYPE *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ASN1_ANY_it);
+}
+
+/* Multistring types */
+
+
+const ASN1_ITEM ASN1_PRINTABLE_it = {
+	.itype = ASN1_ITYPE_MSTRING,
+	.utype = B_ASN1_PRINTABLE,
+	.templates = NULL,
+	.tcount = 0,
+	.funcs = NULL,
+	.size = sizeof(ASN1_STRING),
+	.sname = "ASN1_PRINTABLE",
+};
+
+ASN1_STRING *
+d2i_ASN1_PRINTABLE(ASN1_STRING **a, const unsigned char **in, long len)
+{
+	return (ASN1_STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ASN1_PRINTABLE_it);
+}
+
+int
+i2d_ASN1_PRINTABLE(ASN1_STRING *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_PRINTABLE_it);
+}
+
+ASN1_STRING *
+ASN1_PRINTABLE_new(void)
+{
+	return (ASN1_STRING *)ASN1_item_new(&ASN1_PRINTABLE_it);
+}
+
+void
+ASN1_PRINTABLE_free(ASN1_STRING *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ASN1_PRINTABLE_it);
+}
+
+
+const ASN1_ITEM DISPLAYTEXT_it = {
+	.itype = ASN1_ITYPE_MSTRING,
+	.utype = B_ASN1_DISPLAYTEXT,
+	.templates = NULL,
+	.tcount = 0,
+	.funcs = NULL,
+	.size = sizeof(ASN1_STRING),
+	.sname = "DISPLAYTEXT",
+};
+
+ASN1_STRING *
+d2i_DISPLAYTEXT(ASN1_STRING **a, const unsigned char **in, long len)
+{
+	return (ASN1_STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &DISPLAYTEXT_it);
+}
+
+int
+i2d_DISPLAYTEXT(ASN1_STRING *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &DISPLAYTEXT_it);
+}
+
+ASN1_STRING *
+DISPLAYTEXT_new(void)
+{
+	return (ASN1_STRING *)ASN1_item_new(&DISPLAYTEXT_it);
+}
+
+void
+DISPLAYTEXT_free(ASN1_STRING *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &DISPLAYTEXT_it);
+}
+
+
+const ASN1_ITEM DIRECTORYSTRING_it = {
+	.itype = ASN1_ITYPE_MSTRING,
+	.utype = B_ASN1_DIRECTORYSTRING,
+	.templates = NULL,
+	.tcount = 0,
+	.funcs = NULL,
+	.size = sizeof(ASN1_STRING),
+	.sname = "DIRECTORYSTRING",
+};
+
+ASN1_STRING *
+d2i_DIRECTORYSTRING(ASN1_STRING **a, const unsigned char **in, long len)
+{
+	return (ASN1_STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &DIRECTORYSTRING_it);
+}
+
+int
+i2d_DIRECTORYSTRING(ASN1_STRING *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &DIRECTORYSTRING_it);
+}
+
+ASN1_STRING *
+DIRECTORYSTRING_new(void)
+{
+	return (ASN1_STRING *)ASN1_item_new(&DIRECTORYSTRING_it);
+}
+
+void
+DIRECTORYSTRING_free(ASN1_STRING *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &DIRECTORYSTRING_it);
+}
+
+/* Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE */
+
+const ASN1_ITEM ASN1_BOOLEAN_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_BOOLEAN,
+	.size = -1,
+	.sname = "ASN1_BOOLEAN",
+};
+
+const ASN1_ITEM ASN1_TBOOLEAN_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_BOOLEAN,
+	.size = 1,
+	.sname = "ASN1_TBOOLEAN",
+};
+
+const ASN1_ITEM ASN1_FBOOLEAN_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_BOOLEAN,
+	.size = 0,
+	.sname = "ASN1_FBOOLEAN",
+};
+
+/* Special, OCTET STRING with indefinite length constructed support */
+
+const ASN1_ITEM ASN1_OCTET_STRING_NDEF_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_OCTET_STRING,
+	.size = ASN1_TFLG_NDEF,
+	.sname = "ASN1_OCTET_STRING_NDEF",
+};
+
+static const ASN1_TEMPLATE ASN1_SEQUENCE_ANY_item_tt = {
+	.flags = ASN1_TFLG_SEQUENCE_OF,
+	.tag = 0,
+	.offset = 0,
+	.field_name = "ASN1_SEQUENCE_ANY",
+	.item = &ASN1_ANY_it,
+};
+
+const ASN1_ITEM ASN1_SEQUENCE_ANY_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = -1,
+	.templates = &ASN1_SEQUENCE_ANY_item_tt,
+	.tcount = 0,
+	.funcs = NULL,
+	.size = 0,
+	.sname = "ASN1_SEQUENCE_ANY",
+};
+
+static const ASN1_TEMPLATE ASN1_SET_ANY_item_tt = {
+	.flags = ASN1_TFLG_SET_OF,
+	.tag = 0,
+	.offset = 0,
+	.field_name = "ASN1_SET_ANY",
+	.item = &ASN1_ANY_it,
+};
+
+const ASN1_ITEM ASN1_SET_ANY_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = -1,
+	.templates = &ASN1_SET_ANY_item_tt,
+	.tcount = 0,
+	.funcs = NULL,
+	.size = 0,
+	.sname = "ASN1_SET_ANY",
+};
+
+
+ASN1_SEQUENCE_ANY *
+d2i_ASN1_SEQUENCE_ANY(ASN1_SEQUENCE_ANY **a, const unsigned char **in, long len)
+{
+	return (ASN1_SEQUENCE_ANY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ASN1_SEQUENCE_ANY_it);
+}
+
+int
+i2d_ASN1_SEQUENCE_ANY(const ASN1_SEQUENCE_ANY *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_SEQUENCE_ANY_it);
+}
+
+ASN1_SEQUENCE_ANY *
+d2i_ASN1_SET_ANY(ASN1_SEQUENCE_ANY **a, const unsigned char **in, long len)
+{
+	return (ASN1_SEQUENCE_ANY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ASN1_SET_ANY_it);
+}
+
+int
+i2d_ASN1_SET_ANY(const ASN1_SEQUENCE_ANY *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_SET_ANY_it);
+}
diff --git a/crypto/libressl/crypto/asn1/tasn_utl.c b/crypto/libressl/crypto/asn1/tasn_utl.c
new file mode 100644
index 0000000000..696545bc78
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/tasn_utl.c
@@ -0,0 +1,281 @@
+/* $OpenBSD: tasn_utl.c,v 1.10 2014/06/12 15:49:27 deraadt Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2004 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Utility functions for manipulating fields and offsets */
+
+/* Add 'offset' to 'addr' */
+#define offset2ptr(addr, offset) (void *)(((char *) addr) + offset)
+
+/* Given an ASN1_ITEM CHOICE type return
+ * the selector value
+ */
+
+int
+asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+	int *sel = offset2ptr(*pval, it->utype);
+	return *sel;
+}
+
+/* Given an ASN1_ITEM CHOICE type set
+ * the selector value, return old value.
+ */
+
+int
+asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it)
+{
+	int *sel, ret;
+	sel = offset2ptr(*pval, it->utype);
+	ret = *sel;
+	*sel = value;
+	return ret;
+}
+
+/* Do reference counting. The value 'op' decides what to do.
+ * if it is +1 then the count is incremented. If op is 0 count is
+ * set to 1. If op is -1 count is decremented and the return value
+ * is the current refrence count or 0 if no reference count exists.
+ */
+
+int
+asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
+{
+	const ASN1_AUX *aux;
+	int *lck, ret;
+
+	if ((it->itype != ASN1_ITYPE_SEQUENCE) &&
+	    (it->itype != ASN1_ITYPE_NDEF_SEQUENCE))
+		return 0;
+	aux = it->funcs;
+	if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT))
+		return 0;
+	lck = offset2ptr(*pval, aux->ref_offset);
+	if (op == 0) {
+		*lck = 1;
+		return 1;
+	}
+	ret = CRYPTO_add(lck, op, aux->ref_lock);
+	return ret;
+}
+
+static ASN1_ENCODING *
+asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+	const ASN1_AUX *aux;
+
+	if (!pval || !*pval)
+		return NULL;
+	aux = it->funcs;
+	if (!aux || !(aux->flags & ASN1_AFLG_ENCODING))
+		return NULL;
+	return offset2ptr(*pval, aux->enc_offset);
+}
+
+void
+asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+	ASN1_ENCODING *enc;
+
+	enc = asn1_get_enc_ptr(pval, it);
+	if (enc) {
+		enc->enc = NULL;
+		enc->len = 0;
+		enc->modified = 1;
+	}
+}
+
+void
+asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+	ASN1_ENCODING *enc;
+
+	enc = asn1_get_enc_ptr(pval, it);
+	if (enc) {
+		free(enc->enc);
+		enc->enc = NULL;
+		enc->len = 0;
+		enc->modified = 1;
+	}
+}
+
+int
+asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
+    const ASN1_ITEM *it)
+{
+	ASN1_ENCODING *enc;
+
+	enc = asn1_get_enc_ptr(pval, it);
+	if (!enc)
+		return 1;
+
+	free(enc->enc);
+	enc->enc = malloc(inlen);
+	if (!enc->enc)
+		return 0;
+	memcpy(enc->enc, in, inlen);
+	enc->len = inlen;
+	enc->modified = 0;
+
+	return 1;
+}
+
+int
+asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
+    const ASN1_ITEM *it)
+{
+	ASN1_ENCODING *enc;
+
+	enc = asn1_get_enc_ptr(pval, it);
+	if (!enc || enc->modified)
+		return 0;
+	if (out) {
+		memcpy(*out, enc->enc, enc->len);
+		*out += enc->len;
+	}
+	if (len)
+		*len = enc->len;
+	return 1;
+}
+
+/* Given an ASN1_TEMPLATE get a pointer to a field */
+ASN1_VALUE **
+asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+{
+	ASN1_VALUE **pvaltmp;
+
+	if (tt->flags & ASN1_TFLG_COMBINE)
+		return pval;
+	pvaltmp = offset2ptr(*pval, tt->offset);
+	/* NOTE for BOOLEAN types the field is just a plain
+ 	 * int so we can't return int **, so settle for
+	 * (int *).
+	 */
+	return pvaltmp;
+}
+
+/* Handle ANY DEFINED BY template, find the selector, look up
+ * the relevant ASN1_TEMPLATE in the table and return it.
+ */
+
+const ASN1_TEMPLATE *
+asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr)
+{
+	const ASN1_ADB *adb;
+	const ASN1_ADB_TABLE *atbl;
+	long selector;
+	ASN1_VALUE **sfld;
+	int i;
+
+	if (!(tt->flags & ASN1_TFLG_ADB_MASK))
+		return tt;
+
+	/* Else ANY DEFINED BY ... get the table */
+	adb = (const ASN1_ADB *)tt->item;
+
+	/* Get the selector field */
+	sfld = offset2ptr(*pval, adb->offset);
+
+	/* Check if NULL */
+	if (!sfld) {
+		if (!adb->null_tt)
+			goto err;
+		return adb->null_tt;
+	}
+
+	/* Convert type to a long:
+	 * NB: don't check for NID_undef here because it
+	 * might be a legitimate value in the table
+	 */
+	if (tt->flags & ASN1_TFLG_ADB_OID)
+		selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld);
+	else
+		selector = ASN1_INTEGER_get((ASN1_INTEGER *)*sfld);
+
+	/* Try to find matching entry in table
+	 * Maybe should check application types first to
+	 * allow application override? Might also be useful
+	 * to have a flag which indicates table is sorted and
+	 * we can do a binary search. For now stick to a
+	 * linear search.
+	 */
+
+	for (atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++)
+		if (atbl->value == selector)
+			return &atbl->tt;
+
+	/* FIXME: need to search application table too */
+
+	/* No match, return default type */
+	if (!adb->default_tt)
+		goto err;
+	return adb->default_tt;
+
+err:
+	/* FIXME: should log the value or OID of unsupported type */
+	if (nullerr)
+		ASN1err(ASN1_F_ASN1_DO_ADB,
+		    ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
+	return NULL;
+}
diff --git a/crypto/libressl/crypto/asn1/x_algor.c b/crypto/libressl/crypto/asn1/x_algor.c
new file mode 100644
index 0000000000..01ea128f0f
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/x_algor.c
@@ -0,0 +1,222 @@
+/* $OpenBSD: x_algor.c,v 1.20 2015/02/11 04:00:39 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+static const ASN1_TEMPLATE X509_ALGOR_seq_tt[] = {
+	{
+		.offset = offsetof(X509_ALGOR, algorithm),
+		.field_name = "algorithm",
+		.item = &ASN1_OBJECT_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.offset = offsetof(X509_ALGOR, parameter),
+		.field_name = "parameter",
+		.item = &ASN1_ANY_it,
+	},
+};
+
+const ASN1_ITEM X509_ALGOR_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = X509_ALGOR_seq_tt,
+	.tcount = sizeof(X509_ALGOR_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.size = sizeof(X509_ALGOR),
+	.sname = "X509_ALGOR",
+};
+
+static const ASN1_TEMPLATE X509_ALGORS_item_tt = {
+	.flags = ASN1_TFLG_SEQUENCE_OF,
+	.tag = 0,
+	.offset = 0,
+	.field_name = "algorithms",
+	.item = &X509_ALGOR_it,
+};
+
+const ASN1_ITEM X509_ALGORS_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = -1,
+	.templates = &X509_ALGORS_item_tt,
+	.tcount = 0,
+	.funcs = NULL,
+	.size = 0,
+	.sname = "X509_ALGORS",
+};
+
+
+X509_ALGOR *
+d2i_X509_ALGOR(X509_ALGOR **a, const unsigned char **in, long len)
+{
+	return (X509_ALGOR *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &X509_ALGOR_it);
+}
+
+int
+i2d_X509_ALGOR(X509_ALGOR *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_ALGOR_it);
+}
+
+X509_ALGOR *
+X509_ALGOR_new(void)
+{
+	return (X509_ALGOR *)ASN1_item_new(&X509_ALGOR_it);
+}
+
+void
+X509_ALGOR_free(X509_ALGOR *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &X509_ALGOR_it);
+}
+
+X509_ALGORS *
+d2i_X509_ALGORS(X509_ALGORS **a, const unsigned char **in, long len)
+{
+	return (X509_ALGORS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &X509_ALGORS_it);
+}
+
+int
+i2d_X509_ALGORS(X509_ALGORS *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_ALGORS_it);
+}
+
+X509_ALGOR *
+X509_ALGOR_dup(X509_ALGOR *x)
+{
+	return ASN1_item_dup(&X509_ALGOR_it, x);
+}
+
+int
+X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval)
+{
+	if (!alg)
+		return 0;
+	if (ptype != V_ASN1_UNDEF) {
+		if (alg->parameter == NULL)
+			alg->parameter = ASN1_TYPE_new();
+		if (alg->parameter == NULL)
+			return 0;
+	}
+	if (alg) {
+		if (alg->algorithm)
+			ASN1_OBJECT_free(alg->algorithm);
+		alg->algorithm = aobj;
+	}
+	if (ptype == 0)
+		return 1;
+	if (ptype == V_ASN1_UNDEF) {
+		if (alg->parameter) {
+			ASN1_TYPE_free(alg->parameter);
+			alg->parameter = NULL;
+		}
+	} else
+		ASN1_TYPE_set(alg->parameter, ptype, pval);
+	return 1;
+}
+
+void
+X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
+    X509_ALGOR *algor)
+{
+	if (paobj)
+		*paobj = algor->algorithm;
+	if (pptype) {
+		if (algor->parameter == NULL) {
+			*pptype = V_ASN1_UNDEF;
+			return;
+		} else
+			*pptype = algor->parameter->type;
+		if (ppval)
+			*ppval = algor->parameter->value.ptr;
+	}
+}
+
+/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
+
+void
+X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
+{
+	int param_type;
+
+	if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
+		param_type = V_ASN1_UNDEF;
+	else
+		param_type = V_ASN1_NULL;
+
+	X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
+}
+
+/* Returns 0 if they are equal, != 0 otherwise. */
+int
+X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
+{
+	int rv = OBJ_cmp(a->algorithm, b->algorithm);
+	if (!rv) {
+		if (!a->parameter && !b->parameter)
+			rv = 0;
+		else
+			rv = ASN1_TYPE_cmp(a->parameter, b->parameter);
+	}
+	return(rv);
+}
diff --git a/crypto/libressl/crypto/asn1/x_attrib.c b/crypto/libressl/crypto/asn1/x_attrib.c
new file mode 100644
index 0000000000..e67a3dd414
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/x_attrib.c
@@ -0,0 +1,198 @@
+/* $OpenBSD: x_attrib.c,v 1.12 2015/02/10 05:25:45 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+/* X509_ATTRIBUTE: this has the following form:
+ *
+ * typedef struct x509_attributes_st
+ *	{
+ *	ASN1_OBJECT *object;
+ *	int single;
+ *	union	{
+ *		char		*ptr;
+ * 		STACK_OF(ASN1_TYPE) *set;
+ * 		ASN1_TYPE	*single;
+ *		} value;
+ *	} X509_ATTRIBUTE;
+ *
+ * this needs some extra thought because the CHOICE type is
+ * merged with the main structure and because the value can
+ * be anything at all we *must* try the SET OF first because
+ * the ASN1_ANY type will swallow anything including the whole
+ * SET OF structure.
+ */
+
+static const ASN1_TEMPLATE X509_ATTRIBUTE_SET_ch_tt[] = {
+	{
+		.flags = ASN1_TFLG_SET_OF,
+		.tag = 0,
+		.offset = offsetof(X509_ATTRIBUTE, value.set),
+		.field_name = "value.set",
+		.item = &ASN1_ANY_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(X509_ATTRIBUTE, value.single),
+		.field_name = "value.single",
+		.item = &ASN1_ANY_it,
+	},
+};
+
+const ASN1_ITEM X509_ATTRIBUTE_SET_it = {
+	.itype = ASN1_ITYPE_CHOICE,
+	.utype = offsetof(X509_ATTRIBUTE, single),
+	.templates = X509_ATTRIBUTE_SET_ch_tt,
+	.tcount = sizeof(X509_ATTRIBUTE_SET_ch_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(X509_ATTRIBUTE),
+	.sname = "X509_ATTRIBUTE",
+};
+
+static const ASN1_TEMPLATE X509_ATTRIBUTE_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(X509_ATTRIBUTE, object),
+		.field_name = "object",
+		.item = &ASN1_OBJECT_it,
+	},
+	/* CHOICE type merged with parent */
+	{
+		.flags = 0 | ASN1_TFLG_COMBINE,
+		.tag = 0,
+		.offset = 0,
+		.field_name = NULL,
+		.item = &X509_ATTRIBUTE_SET_it,
+	},
+};
+
+const ASN1_ITEM X509_ATTRIBUTE_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = X509_ATTRIBUTE_seq_tt,
+	.tcount = sizeof(X509_ATTRIBUTE_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(X509_ATTRIBUTE),
+	.sname = "X509_ATTRIBUTE",
+};
+
+
+X509_ATTRIBUTE *
+d2i_X509_ATTRIBUTE(X509_ATTRIBUTE **a, const unsigned char **in, long len)
+{
+	return (X509_ATTRIBUTE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &X509_ATTRIBUTE_it);
+}
+
+int
+i2d_X509_ATTRIBUTE(X509_ATTRIBUTE *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_ATTRIBUTE_it);
+}
+
+X509_ATTRIBUTE *
+X509_ATTRIBUTE_new(void)
+{
+	return (X509_ATTRIBUTE *)ASN1_item_new(&X509_ATTRIBUTE_it);
+}
+
+void
+X509_ATTRIBUTE_free(X509_ATTRIBUTE *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &X509_ATTRIBUTE_it);
+}
+
+X509_ATTRIBUTE *
+X509_ATTRIBUTE_dup(X509_ATTRIBUTE *x)
+{
+	return ASN1_item_dup(&X509_ATTRIBUTE_it, x);
+}
+
+X509_ATTRIBUTE *
+X509_ATTRIBUTE_create(int nid, int atrtype, void *value)
+{
+	X509_ATTRIBUTE *ret = NULL;
+	ASN1_TYPE *val = NULL;
+
+	if ((ret = X509_ATTRIBUTE_new()) == NULL)
+		return (NULL);
+	ret->object = OBJ_nid2obj(nid);
+	ret->single = 0;
+	if ((ret->value.set = sk_ASN1_TYPE_new_null()) == NULL)
+		goto err;
+	if ((val = ASN1_TYPE_new()) == NULL)
+		goto err;
+	if (!sk_ASN1_TYPE_push(ret->value.set, val))
+		goto err;
+
+	ASN1_TYPE_set(val, atrtype, value);
+	return (ret);
+
+err:
+	if (ret != NULL)
+		X509_ATTRIBUTE_free(ret);
+	if (val != NULL)
+		ASN1_TYPE_free(val);
+	return (NULL);
+}
diff --git a/crypto/libressl/crypto/asn1/x_bignum.c b/crypto/libressl/crypto/asn1/x_bignum.c
new file mode 100644
index 0000000000..38c391a663
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/x_bignum.c
@@ -0,0 +1,167 @@
+/* $OpenBSD: x_bignum.c,v 1.7 2014/07/12 16:42:47 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+
+/*
+ * Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER as a
+ * BIGNUM directly. Currently it ignores the sign which isn't a problem since
+ * all BIGNUMs used are non negative and anything that looks negative is
+ * normally due to an encoding error.
+ */
+
+static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+    const ASN1_ITEM *it);
+static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+    int utype, char *free_cont, const ASN1_ITEM *it);
+
+static ASN1_PRIMITIVE_FUNCS bignum_pf = {
+	NULL,
+	0,
+	bn_new,
+	bn_free,
+	0,
+	bn_c2i,
+	bn_i2c
+};
+
+const ASN1_ITEM BIGNUM_it = {
+        .itype = ASN1_ITYPE_PRIMITIVE,
+        .utype = V_ASN1_INTEGER,
+        .templates = NULL,
+        .tcount = 0,
+        .funcs = &bignum_pf,
+        .size = 0,
+        .sname = "BIGNUM",
+};
+
+const ASN1_ITEM CBIGNUM_it = {
+        .itype = ASN1_ITYPE_PRIMITIVE,
+        .utype = V_ASN1_INTEGER,
+        .templates = NULL,
+        .tcount = 0,
+        .funcs = &bignum_pf,
+        .size = 0,
+        .sname = "BIGNUM",
+};
+
+static int
+bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+	*pval = (ASN1_VALUE *)BN_new();
+	if (*pval)
+		return 1;
+	else
+		return 0;
+}
+
+static void
+bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+	if (*pval == NULL)
+		return;
+	BN_clear_free((BIGNUM *)*pval);
+	*pval = NULL;
+}
+
+static int
+bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it)
+{
+	BIGNUM *bn;
+	int pad, len;
+
+	if (*pval == NULL)
+		return -1;
+	bn = (BIGNUM *)*pval;
+	/* If MSB set in an octet we need a padding byte */
+	if (BN_num_bits(bn) & 0x7)
+		pad = 0;
+	else
+		pad = 1;
+	if (cont) {
+		if (pad)
+			*cont++ = 0;
+		len = BN_bn2bin(bn, cont);
+	} else
+		len = BN_num_bytes(bn);
+	return pad + len;
+}
+
+static int
+bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
+    char *free_cont, const ASN1_ITEM *it)
+{
+	BIGNUM *bn;
+
+	if (*pval == NULL) {
+		if (bn_new(pval, it) == 0)
+			return 0;
+	}
+	bn = (BIGNUM *)*pval;
+	if (!BN_bin2bn(cont, len, bn)) {
+		bn_free(pval, it);
+		return 0;
+	}
+	return 1;
+}
diff --git a/crypto/libressl/crypto/asn1/x_crl.c b/crypto/libressl/crypto/asn1/x_crl.c
new file mode 100644
index 0000000000..eab84ab639
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/x_crl.c
@@ -0,0 +1,687 @@
+/* $OpenBSD: x_crl.c,v 1.24 2015/02/11 04:00:39 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include "asn1_locl.h"
+
+static int X509_REVOKED_cmp(const X509_REVOKED * const *a,
+    const X509_REVOKED * const *b);
+static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
+
+static const ASN1_TEMPLATE X509_REVOKED_seq_tt[] = {
+	{
+		.offset = offsetof(X509_REVOKED, serialNumber),
+		.field_name = "serialNumber",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.offset = offsetof(X509_REVOKED, revocationDate),
+		.field_name = "revocationDate",
+		.item = &ASN1_TIME_it,
+	},
+	{
+		.flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
+		.offset = offsetof(X509_REVOKED, extensions),
+		.field_name = "extensions",
+		.item = &X509_EXTENSION_it,
+	},
+};
+
+const ASN1_ITEM X509_REVOKED_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = X509_REVOKED_seq_tt,
+	.tcount = sizeof(X509_REVOKED_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.size = sizeof(X509_REVOKED),
+	.sname = "X509_REVOKED",
+};
+
+static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r);
+static int def_crl_lookup(X509_CRL *crl, X509_REVOKED **ret,
+    ASN1_INTEGER *serial, X509_NAME *issuer);
+
+static X509_CRL_METHOD int_crl_meth = {
+	.crl_lookup = def_crl_lookup,
+	.crl_verify = def_crl_verify
+};
+
+static const X509_CRL_METHOD *default_crl_method = &int_crl_meth;
+
+/* The X509_CRL_INFO structure needs a bit of customisation.
+ * Since we cache the original encoding the signature wont be affected by
+ * reordering of the revoked field.
+ */
+static int
+crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
+{
+	X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
+
+	if (!a || !a->revoked)
+		return 1;
+	switch (operation) {
+		/* Just set cmp function here. We don't sort because that
+		 * would affect the output of X509_CRL_print().
+		 */
+	case ASN1_OP_D2I_POST:
+		(void)sk_X509_REVOKED_set_cmp_func(a->revoked, X509_REVOKED_cmp);
+		break;
+	}
+	return 1;
+}
+
+
+static const ASN1_AUX X509_CRL_INFO_aux = {
+	.flags = ASN1_AFLG_ENCODING,
+	.asn1_cb = crl_inf_cb,
+	.enc_offset = offsetof(X509_CRL_INFO, enc),
+};
+static const ASN1_TEMPLATE X509_CRL_INFO_seq_tt[] = {
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.offset = offsetof(X509_CRL_INFO, version),
+		.field_name = "version",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.offset = offsetof(X509_CRL_INFO, sig_alg),
+		.field_name = "sig_alg",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.offset = offsetof(X509_CRL_INFO, issuer),
+		.field_name = "issuer",
+		.item = &X509_NAME_it,
+	},
+	{
+		.offset = offsetof(X509_CRL_INFO, lastUpdate),
+		.field_name = "lastUpdate",
+		.item = &ASN1_TIME_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.offset = offsetof(X509_CRL_INFO, nextUpdate),
+		.field_name = "nextUpdate",
+		.item = &ASN1_TIME_it,
+	},
+	{
+		.flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
+		.offset = offsetof(X509_CRL_INFO, revoked),
+		.field_name = "revoked",
+		.item = &X509_REVOKED_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
+		.offset = offsetof(X509_CRL_INFO, extensions),
+		.field_name = "extensions",
+		.item = &X509_EXTENSION_it,
+	},
+};
+
+const ASN1_ITEM X509_CRL_INFO_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = X509_CRL_INFO_seq_tt,
+	.tcount = sizeof(X509_CRL_INFO_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &X509_CRL_INFO_aux,
+	.size = sizeof(X509_CRL_INFO),
+	.sname = "X509_CRL_INFO",
+};
+
+/* Set CRL entry issuer according to CRL certificate issuer extension.
+ * Check for unhandled critical CRL entry extensions.
+ */
+
+static int
+crl_set_issuers(X509_CRL *crl)
+{
+	int i, j;
+	GENERAL_NAMES *gens, *gtmp;
+	STACK_OF(X509_REVOKED) *revoked;
+
+	revoked = X509_CRL_get_REVOKED(crl);
+
+	gens = NULL;
+	for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) {
+		X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
+		STACK_OF(X509_EXTENSION) *exts;
+		ASN1_ENUMERATED *reason;
+		X509_EXTENSION *ext;
+		gtmp = X509_REVOKED_get_ext_d2i(rev, NID_certificate_issuer,
+		    &j, NULL);
+		if (!gtmp && (j != -1)) {
+			crl->flags |= EXFLAG_INVALID;
+			return 1;
+		}
+
+		if (gtmp) {
+			gens = gtmp;
+			if (!crl->issuers) {
+				crl->issuers = sk_GENERAL_NAMES_new_null();
+				if (!crl->issuers)
+					return 0;
+			}
+			if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
+				return 0;
+		}
+		rev->issuer = gens;
+
+		reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason,
+		    &j, NULL);
+		if (!reason && (j != -1)) {
+			crl->flags |= EXFLAG_INVALID;
+			return 1;
+		}
+
+		if (reason) {
+			rev->reason = ASN1_ENUMERATED_get(reason);
+			ASN1_ENUMERATED_free(reason);
+		} else
+			rev->reason = CRL_REASON_NONE;
+
+		/* Check for critical CRL entry extensions */
+
+		exts = rev->extensions;
+
+		for (j = 0; j < sk_X509_EXTENSION_num(exts); j++) {
+			ext = sk_X509_EXTENSION_value(exts, j);
+			if (ext->critical > 0) {
+				if (OBJ_obj2nid(ext->object) ==
+				    NID_certificate_issuer)
+					continue;
+				crl->flags |= EXFLAG_CRITICAL;
+				break;
+			}
+		}
+	}
+
+	return 1;
+}
+
+/* The X509_CRL structure needs a bit of customisation. Cache some extensions
+ * and hash of the whole CRL.
+ */
+static int
+crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
+{
+	X509_CRL *crl = (X509_CRL *)*pval;
+	STACK_OF(X509_EXTENSION) *exts;
+	X509_EXTENSION *ext;
+	int idx;
+	int rc = 1;
+
+	switch (operation) {
+	case ASN1_OP_NEW_POST:
+		crl->idp = NULL;
+		crl->akid = NULL;
+		crl->flags = 0;
+		crl->idp_flags = 0;
+		crl->idp_reasons = CRLDP_ALL_REASONS;
+		crl->meth = default_crl_method;
+		crl->meth_data = NULL;
+		crl->issuers = NULL;
+		crl->crl_number = NULL;
+		crl->base_crl_number = NULL;
+		break;
+
+	case ASN1_OP_D2I_POST:
+#ifndef OPENSSL_NO_SHA
+		X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
+#endif
+		crl->idp = X509_CRL_get_ext_d2i(crl,
+		    NID_issuing_distribution_point, NULL, NULL);
+		if (crl->idp)
+			setup_idp(crl, crl->idp);
+
+		crl->akid = X509_CRL_get_ext_d2i(crl,
+		    NID_authority_key_identifier, NULL, NULL);
+
+		crl->crl_number = X509_CRL_get_ext_d2i(crl,
+		    NID_crl_number, NULL, NULL);
+
+		crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
+		    NID_delta_crl, NULL, NULL);
+		/* Delta CRLs must have CRL number */
+		if (crl->base_crl_number && !crl->crl_number)
+			crl->flags |= EXFLAG_INVALID;
+
+		/* See if we have any unhandled critical CRL extensions and
+		 * indicate this in a flag. We only currently handle IDP,
+		 * AKID and deltas, so anything else critical sets the flag.
+		 *
+		 * This code accesses the X509_CRL structure directly:
+		 * applications shouldn't do this.
+		 */
+
+		exts = crl->crl->extensions;
+
+		for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) {
+			int nid;
+			ext = sk_X509_EXTENSION_value(exts, idx);
+			nid = OBJ_obj2nid(ext->object);
+			if (nid == NID_freshest_crl)
+				crl->flags |= EXFLAG_FRESHEST;
+			if (ext->critical > 0) {
+				/* We handle IDP, AKID and deltas */
+				if (nid == NID_issuing_distribution_point ||
+				    nid == NID_authority_key_identifier ||
+				    nid == NID_delta_crl)
+					break;
+				crl->flags |= EXFLAG_CRITICAL;
+				break;
+			}
+		}
+
+		if (!crl_set_issuers(crl))
+			return 0;
+
+		if (crl->meth->crl_init) {
+			if (crl->meth->crl_init(crl) == 0)
+				return 0;
+		}
+		break;
+
+	case ASN1_OP_FREE_POST:
+		if (crl->meth->crl_free) {
+			if (!crl->meth->crl_free(crl))
+				rc = 0;
+		}
+		if (crl->akid)
+			AUTHORITY_KEYID_free(crl->akid);
+		if (crl->idp)
+			ISSUING_DIST_POINT_free(crl->idp);
+		ASN1_INTEGER_free(crl->crl_number);
+		ASN1_INTEGER_free(crl->base_crl_number);
+		sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
+		break;
+	}
+	return rc;
+}
+
+/* Convert IDP into a more convenient form */
+
+static void
+setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
+{
+	int idp_only = 0;
+
+	/* Set various flags according to IDP */
+	crl->idp_flags |= IDP_PRESENT;
+	if (idp->onlyuser > 0) {
+		idp_only++;
+		crl->idp_flags |= IDP_ONLYUSER;
+	}
+	if (idp->onlyCA > 0) {
+		idp_only++;
+		crl->idp_flags |= IDP_ONLYCA;
+	}
+	if (idp->onlyattr > 0) {
+		idp_only++;
+		crl->idp_flags |= IDP_ONLYATTR;
+	}
+
+	if (idp_only > 1)
+		crl->idp_flags |= IDP_INVALID;
+
+	if (idp->indirectCRL > 0)
+		crl->idp_flags |= IDP_INDIRECT;
+
+	if (idp->onlysomereasons) {
+		crl->idp_flags |= IDP_REASONS;
+		if (idp->onlysomereasons->length > 0)
+			crl->idp_reasons = idp->onlysomereasons->data[0];
+		if (idp->onlysomereasons->length > 1)
+			crl->idp_reasons |=
+			    (idp->onlysomereasons->data[1] << 8);
+		crl->idp_reasons &= CRLDP_ALL_REASONS;
+	}
+
+	DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
+}
+
+static const ASN1_AUX X509_CRL_aux = {
+	.app_data = NULL,
+	.flags = ASN1_AFLG_REFCOUNT,
+	.ref_offset = offsetof(X509_CRL, references),
+	.ref_lock = CRYPTO_LOCK_X509_CRL,
+	.asn1_cb = crl_cb,
+};
+static const ASN1_TEMPLATE X509_CRL_seq_tt[] = {
+	{
+		.offset = offsetof(X509_CRL, crl),
+		.field_name = "crl",
+		.item = &X509_CRL_INFO_it,
+	},
+	{
+		.offset = offsetof(X509_CRL, sig_alg),
+		.field_name = "sig_alg",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.offset = offsetof(X509_CRL, signature),
+		.field_name = "signature",
+		.item = &ASN1_BIT_STRING_it,
+	},
+};
+
+const ASN1_ITEM X509_CRL_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = X509_CRL_seq_tt,
+	.tcount = sizeof(X509_CRL_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &X509_CRL_aux,
+	.size = sizeof(X509_CRL),
+	.sname = "X509_CRL",
+};
+
+
+X509_REVOKED *
+d2i_X509_REVOKED(X509_REVOKED **a, const unsigned char **in, long len)
+{
+	return (X509_REVOKED *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &X509_REVOKED_it);
+}
+
+int
+i2d_X509_REVOKED(X509_REVOKED *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_REVOKED_it);
+}
+
+X509_REVOKED *
+X509_REVOKED_new(void)
+{
+	return (X509_REVOKED *)ASN1_item_new(&X509_REVOKED_it);
+}
+
+void
+X509_REVOKED_free(X509_REVOKED *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &X509_REVOKED_it);
+}
+
+X509_CRL_INFO *
+d2i_X509_CRL_INFO(X509_CRL_INFO **a, const unsigned char **in, long len)
+{
+	return (X509_CRL_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &X509_CRL_INFO_it);
+}
+
+int
+i2d_X509_CRL_INFO(X509_CRL_INFO *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_CRL_INFO_it);
+}
+
+X509_CRL_INFO *
+X509_CRL_INFO_new(void)
+{
+	return (X509_CRL_INFO *)ASN1_item_new(&X509_CRL_INFO_it);
+}
+
+void
+X509_CRL_INFO_free(X509_CRL_INFO *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &X509_CRL_INFO_it);
+}
+
+X509_CRL *
+d2i_X509_CRL(X509_CRL **a, const unsigned char **in, long len)
+{
+	return (X509_CRL *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &X509_CRL_it);
+}
+
+int
+i2d_X509_CRL(X509_CRL *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_CRL_it);
+}
+
+X509_CRL *
+X509_CRL_new(void)
+{
+	return (X509_CRL *)ASN1_item_new(&X509_CRL_it);
+}
+
+void
+X509_CRL_free(X509_CRL *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &X509_CRL_it);
+}
+
+X509_CRL *
+X509_CRL_dup(X509_CRL *x)
+{
+	return ASN1_item_dup(&X509_CRL_it, x);
+}
+
+static int
+X509_REVOKED_cmp(const X509_REVOKED * const *a, const X509_REVOKED * const *b)
+{
+	return(ASN1_STRING_cmp(
+	    (ASN1_STRING *)(*a)->serialNumber,
+	    (ASN1_STRING *)(*b)->serialNumber));
+}
+
+int
+X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)
+{
+	X509_CRL_INFO *inf;
+
+	inf = crl->crl;
+	if (!inf->revoked)
+		inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp);
+	if (!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) {
+		ASN1err(ASN1_F_X509_CRL_ADD0_REVOKED, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	inf->enc.modified = 1;
+	return 1;
+}
+
+int
+X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r)
+{
+	if (crl->meth->crl_verify)
+		return crl->meth->crl_verify(crl, r);
+	return 0;
+}
+
+int
+X509_CRL_get0_by_serial(X509_CRL *crl, X509_REVOKED **ret,
+    ASN1_INTEGER *serial)
+{
+	if (crl->meth->crl_lookup)
+		return crl->meth->crl_lookup(crl, ret, serial, NULL);
+	return 0;
+}
+
+int
+X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x)
+{
+	if (crl->meth->crl_lookup)
+		return crl->meth->crl_lookup(crl, ret,
+		    X509_get_serialNumber(x), X509_get_issuer_name(x));
+	return 0;
+}
+
+static int
+def_crl_verify(X509_CRL *crl, EVP_PKEY *r)
+{
+	return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
+	    crl->sig_alg, crl->signature, crl->crl, r));
+}
+
+static int
+crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm, X509_REVOKED *rev)
+{
+	int i;
+
+	if (!rev->issuer) {
+		if (!nm)
+			return 1;
+		if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
+			return 1;
+		return 0;
+	}
+
+	if (!nm)
+		nm = X509_CRL_get_issuer(crl);
+
+	for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) {
+		GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
+		if (gen->type != GEN_DIRNAME)
+			continue;
+		if (!X509_NAME_cmp(nm, gen->d.directoryName))
+			return 1;
+	}
+	return 0;
+
+}
+
+static int
+def_crl_lookup(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *serial,
+    X509_NAME *issuer)
+{
+	X509_REVOKED rtmp, *rev;
+	int idx;
+
+	rtmp.serialNumber = serial;
+	/* Sort revoked into serial number order if not already sorted.
+	 * Do this under a lock to avoid race condition.
+ 	 */
+	if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) {
+		CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL);
+		sk_X509_REVOKED_sort(crl->crl->revoked);
+		CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL);
+	}
+	idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp);
+	if (idx < 0)
+		return 0;
+	/* Need to look for matching name */
+	for (; idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++) {
+		rev = sk_X509_REVOKED_value(crl->crl->revoked, idx);
+		if (ASN1_INTEGER_cmp(rev->serialNumber, serial))
+			return 0;
+		if (crl_revoked_issuer_match(crl, issuer, rev)) {
+			if (ret)
+				*ret = rev;
+			if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
+				return 2;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+void
+X509_CRL_set_default_method(const X509_CRL_METHOD *meth)
+{
+	if (meth == NULL)
+		default_crl_method = &int_crl_meth;
+	else
+		default_crl_method = meth;
+}
+
+X509_CRL_METHOD *
+X509_CRL_METHOD_new(int (*crl_init)(X509_CRL *crl),
+    int (*crl_free)(X509_CRL *crl),
+    int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
+    ASN1_INTEGER *ser, X509_NAME *issuer),
+    int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk))
+{
+	X509_CRL_METHOD *m;
+
+	m = malloc(sizeof(X509_CRL_METHOD));
+	if (!m)
+		return NULL;
+	m->crl_init = crl_init;
+	m->crl_free = crl_free;
+	m->crl_lookup = crl_lookup;
+	m->crl_verify = crl_verify;
+	m->flags = X509_CRL_METHOD_DYNAMIC;
+	return m;
+}
+
+void
+X509_CRL_METHOD_free(X509_CRL_METHOD *m)
+{
+	if (!(m->flags & X509_CRL_METHOD_DYNAMIC))
+		return;
+	free(m);
+}
+
+void
+X509_CRL_set_meth_data(X509_CRL *crl, void *dat)
+{
+	crl->meth_data = dat;
+}
+
+void *
+X509_CRL_get_meth_data(X509_CRL *crl)
+{
+	return crl->meth_data;
+}
diff --git a/crypto/libressl/crypto/asn1/x_exten.c b/crypto/libressl/crypto/asn1/x_exten.c
new file mode 100644
index 0000000000..66723d4967
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/x_exten.c
@@ -0,0 +1,153 @@
+/* $OpenBSD: x_exten.c,v 1.15 2015/02/11 04:00:39 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+static const ASN1_TEMPLATE X509_EXTENSION_seq_tt[] = {
+	{
+		.offset = offsetof(X509_EXTENSION, object),
+		.field_name = "object",
+		.item = &ASN1_OBJECT_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.offset = offsetof(X509_EXTENSION, critical),
+		.field_name = "critical",
+		.item = &ASN1_BOOLEAN_it,
+	},
+	{
+		.offset = offsetof(X509_EXTENSION, value),
+		.field_name = "value",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+};
+
+const ASN1_ITEM X509_EXTENSION_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = X509_EXTENSION_seq_tt,
+	.tcount = sizeof(X509_EXTENSION_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.size = sizeof(X509_EXTENSION),
+	.sname = "X509_EXTENSION",
+};
+
+static const ASN1_TEMPLATE X509_EXTENSIONS_item_tt = {
+	.flags = ASN1_TFLG_SEQUENCE_OF,
+	.tag = 0,
+	.offset = 0,
+	.field_name = "Extension",
+	.item = &X509_EXTENSION_it,
+};
+
+const ASN1_ITEM X509_EXTENSIONS_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = -1,
+	.templates = &X509_EXTENSIONS_item_tt,
+	.tcount = 0,
+	.funcs = NULL,
+	.size = 0,
+	.sname = "X509_EXTENSIONS",
+};
+
+
+X509_EXTENSION *
+d2i_X509_EXTENSION(X509_EXTENSION **a, const unsigned char **in, long len)
+{
+	return (X509_EXTENSION *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &X509_EXTENSION_it);
+}
+
+int
+i2d_X509_EXTENSION(X509_EXTENSION *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_EXTENSION_it);
+}
+
+X509_EXTENSION *
+X509_EXTENSION_new(void)
+{
+	return (X509_EXTENSION *)ASN1_item_new(&X509_EXTENSION_it);
+}
+
+void
+X509_EXTENSION_free(X509_EXTENSION *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &X509_EXTENSION_it);
+}
+
+X509_EXTENSIONS *
+d2i_X509_EXTENSIONS(X509_EXTENSIONS **a, const unsigned char **in, long len)
+{
+	return (X509_EXTENSIONS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &X509_EXTENSIONS_it);
+}
+
+int
+i2d_X509_EXTENSIONS(X509_EXTENSIONS *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_EXTENSIONS_it);
+}
+
+X509_EXTENSION *
+X509_EXTENSION_dup(X509_EXTENSION *x)
+{
+	return ASN1_item_dup(&X509_EXTENSION_it, x);
+}
diff --git a/crypto/libressl/crypto/asn1/x_info.c b/crypto/libressl/crypto/asn1/x_info.c
new file mode 100644
index 0000000000..ff24f08c3f
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/x_info.c
@@ -0,0 +1,107 @@
+/* $OpenBSD: x_info.c,v 1.15 2015/02/10 11:22:21 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+X509_INFO *
+X509_INFO_new(void)
+{
+	X509_INFO *ret = NULL;
+
+	ret = malloc(sizeof(X509_INFO));
+	if (ret == NULL) {
+		ASN1err(ASN1_F_X509_INFO_NEW, ERR_R_MALLOC_FAILURE);
+		return (NULL);
+	}
+
+	ret->enc_cipher.cipher = NULL;
+	ret->enc_len = 0;
+	ret->enc_data = NULL;
+
+	ret->references = 1;
+	ret->x509 = NULL;
+	ret->crl = NULL;
+	ret->x_pkey = NULL;
+	return (ret);
+}
+
+void
+X509_INFO_free(X509_INFO *x)
+{
+	int i;
+
+	if (x == NULL)
+		return;
+
+	i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_X509_INFO);
+	if (i > 0)
+		return;
+
+	X509_free(x->x509);
+	if (x->crl != NULL)
+		X509_CRL_free(x->crl);
+	if (x->x_pkey != NULL)
+		X509_PKEY_free(x->x_pkey);
+	free(x->enc_data);
+	free(x);
+}
diff --git a/crypto/libressl/crypto/asn1/x_long.c b/crypto/libressl/crypto/asn1/x_long.c
new file mode 100644
index 0000000000..0e43e6a73e
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/x_long.c
@@ -0,0 +1,210 @@
+/* $OpenBSD: x_long.c,v 1.9 2014/07/11 08:44:47 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+/* Custom primitive type for long handling. This converts between an ASN1_INTEGER
+ * and a long directly.
+ */
+
+
+static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
+static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
+static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx);
+
+static ASN1_PRIMITIVE_FUNCS long_pf = {
+	NULL, 0,
+	long_new,
+	long_free,
+	long_free,	/* Clear should set to initial value */
+	long_c2i,
+	long_i2c,
+	long_print
+};
+
+const ASN1_ITEM LONG_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_INTEGER,
+	.templates = NULL,
+	.tcount = 0,
+	.funcs = &long_pf,
+	.size = ASN1_LONG_UNDEF,
+	.sname = "LONG",
+};
+
+const ASN1_ITEM ZLONG_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = V_ASN1_INTEGER,
+	.templates = NULL,
+	.tcount = 0,
+	.funcs = &long_pf,
+	.size = 0,
+	.sname = "ZLONG",
+};
+
+static int
+long_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+	*(long *)pval = it->size;
+	return 1;
+}
+
+static void
+long_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+	*(long *)pval = it->size;
+}
+
+static int
+long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+    const ASN1_ITEM *it)
+{
+	long ltmp;
+	unsigned long utmp;
+	int clen, pad, i;
+	/* this exists to bypass broken gcc optimization */
+	char *cp = (char *)pval;
+
+	/* use memcpy, because we may not be long aligned */
+	memcpy(<mp, cp, sizeof(long));
+
+	if (ltmp == it->size)
+		return -1;
+	/* Convert the long to positive: we subtract one if negative so
+	 * we can cleanly handle the padding if only the MSB of the leading
+	 * octet is set.
+	 */
+	if (ltmp < 0)
+		utmp = -ltmp - 1;
+	else
+		utmp = ltmp;
+	clen = BN_num_bits_word(utmp);
+	/* If MSB of leading octet set we need to pad */
+	if (!(clen & 0x7))
+		pad = 1;
+	else
+		pad = 0;
+
+	/* Convert number of bits to number of octets */
+	clen = (clen + 7) >> 3;
+
+	if (cont) {
+		if (pad)
+			*cont++ = (ltmp < 0) ? 0xff : 0;
+		for (i = clen - 1; i >= 0; i--) {
+			cont[i] = (unsigned char)(utmp & 0xff);
+			if (ltmp < 0)
+				cont[i] ^= 0xff;
+			utmp >>= 8;
+		}
+	}
+	return clen + pad;
+}
+
+static int
+long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
+    char *free_cont, const ASN1_ITEM *it)
+{
+	int neg, i;
+	long ltmp;
+	unsigned long utmp = 0;
+	char *cp = (char *)pval;
+	if (len > (int)sizeof(long)) {
+		ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+		return 0;
+	}
+	/* Is it negative? */
+	if (len && (cont[0] & 0x80))
+		neg = 1;
+	else
+		neg = 0;
+	utmp = 0;
+	for (i = 0; i < len; i++) {
+		utmp <<= 8;
+		if (neg)
+			utmp |= cont[i] ^ 0xff;
+		else
+			utmp |= cont[i];
+	}
+	ltmp = (long)utmp;
+	if (neg) {
+		ltmp++;
+		ltmp = -ltmp;
+	}
+	if (ltmp == it->size) {
+		ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+		return 0;
+	}
+	memcpy(cp, <mp, sizeof(long));
+	return 1;
+}
+
+static int
+long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent,
+    const ASN1_PCTX *pctx)
+{
+	return BIO_printf(out, "%ld\n", *(long *)pval);
+}
diff --git a/crypto/libressl/crypto/asn1/x_name.c b/crypto/libressl/crypto/asn1/x_name.c
new file mode 100644
index 0000000000..a7ce6d4f77
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/x_name.c
@@ -0,0 +1,642 @@
+/* $OpenBSD: x_name.c,v 1.30 2015/07/15 17:41:56 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include "asn1_locl.h"
+
+typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
+DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
+
+static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in,
+    long len, const ASN1_ITEM *it, int tag, int aclass, char opt,
+    ASN1_TLC *ctx);
+
+static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
+    const ASN1_ITEM *it, int tag, int aclass);
+static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
+static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
+
+static int x509_name_encode(X509_NAME *a);
+static int x509_name_canon(X509_NAME *a);
+static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in);
+static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname,
+    unsigned char **in);
+
+static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, int indent,
+    const char *fname, const ASN1_PCTX *pctx);
+
+static const ASN1_TEMPLATE X509_NAME_ENTRY_seq_tt[] = {
+	{
+		.offset = offsetof(X509_NAME_ENTRY, object),
+		.field_name = "object",
+		.item = &ASN1_OBJECT_it,
+	},
+	{
+		.offset = offsetof(X509_NAME_ENTRY, value),
+		.field_name = "value",
+		.item = &ASN1_PRINTABLE_it,
+	},
+};
+
+const ASN1_ITEM X509_NAME_ENTRY_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = X509_NAME_ENTRY_seq_tt,
+	.tcount = sizeof(X509_NAME_ENTRY_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.size = sizeof(X509_NAME_ENTRY),
+	.sname = "X509_NAME_ENTRY",
+};
+
+
+X509_NAME_ENTRY *
+d2i_X509_NAME_ENTRY(X509_NAME_ENTRY **a, const unsigned char **in, long len)
+{
+	return (X509_NAME_ENTRY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &X509_NAME_ENTRY_it);
+}
+
+int
+i2d_X509_NAME_ENTRY(X509_NAME_ENTRY *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_NAME_ENTRY_it);
+}
+
+X509_NAME_ENTRY *
+X509_NAME_ENTRY_new(void)
+{
+	return (X509_NAME_ENTRY *)ASN1_item_new(&X509_NAME_ENTRY_it);
+}
+
+void
+X509_NAME_ENTRY_free(X509_NAME_ENTRY *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &X509_NAME_ENTRY_it);
+}
+
+X509_NAME_ENTRY *
+X509_NAME_ENTRY_dup(X509_NAME_ENTRY *x)
+{
+	return ASN1_item_dup(&X509_NAME_ENTRY_it, x);
+}
+
+/* For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY }
+ * so declare two template wrappers for this
+ */
+
+static const ASN1_TEMPLATE X509_NAME_ENTRIES_item_tt = {
+	.flags = ASN1_TFLG_SET_OF,
+	.tag = 0,
+	.offset = 0,
+	.field_name = "RDNS",
+	.item = &X509_NAME_ENTRY_it,
+};
+
+const ASN1_ITEM X509_NAME_ENTRIES_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = -1,
+	.templates = &X509_NAME_ENTRIES_item_tt,
+	.tcount = 0,
+	.funcs = NULL,
+	.size = 0,
+	.sname = "X509_NAME_ENTRIES",
+};
+
+static const ASN1_TEMPLATE X509_NAME_INTERNAL_item_tt = {
+	.flags = ASN1_TFLG_SEQUENCE_OF,
+	.tag = 0,
+	.offset = 0,
+	.field_name = "Name",
+	.item = &X509_NAME_ENTRIES_it,
+};
+
+const ASN1_ITEM X509_NAME_INTERNAL_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = -1,
+	.templates = &X509_NAME_INTERNAL_item_tt,
+	.tcount = 0,
+	.funcs = NULL,
+	.size = 0,
+	.sname = "X509_NAME_INTERNAL",
+};
+
+/* Normally that's where it would end: we'd have two nested STACK structures
+ * representing the ASN1. Unfortunately X509_NAME uses a completely different
+ * form and caches encodings so we have to process the internal form and convert
+ * to the external form.
+ */
+
+const ASN1_EXTERN_FUNCS x509_name_ff = {
+	NULL,
+	x509_name_ex_new,
+	x509_name_ex_free,
+	0,	/* Default clear behaviour is OK */
+	x509_name_ex_d2i,
+	x509_name_ex_i2d,
+	x509_name_ex_print
+};
+
+const ASN1_ITEM X509_NAME_it = {
+	.itype = ASN1_ITYPE_EXTERN,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = NULL,
+	.tcount = 0,
+	.funcs = &x509_name_ff,
+	.size = 0,
+	.sname = "X509_NAME",
+};
+
+X509_NAME *
+d2i_X509_NAME(X509_NAME **a, const unsigned char **in, long len)
+{
+	return (X509_NAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &X509_NAME_it);
+}
+
+int
+i2d_X509_NAME(X509_NAME *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_NAME_it);
+}
+
+X509_NAME *
+X509_NAME_new(void)
+{
+	return (X509_NAME *)ASN1_item_new(&X509_NAME_it);
+}
+
+void
+X509_NAME_free(X509_NAME *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &X509_NAME_it);
+}
+
+X509_NAME *
+X509_NAME_dup(X509_NAME *x)
+{
+	return ASN1_item_dup(&X509_NAME_it, x);
+}
+
+static int
+x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
+{
+	X509_NAME *ret = NULL;
+
+	ret = malloc(sizeof(X509_NAME));
+	if (!ret)
+		goto memerr;
+	if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL)
+		goto memerr;
+	if ((ret->bytes = BUF_MEM_new()) == NULL)
+		goto memerr;
+	ret->canon_enc = NULL;
+	ret->canon_enclen = 0;
+	ret->modified = 1;
+	*val = (ASN1_VALUE *)ret;
+	return 1;
+
+memerr:
+	ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE);
+	if (ret) {
+		if (ret->entries)
+			sk_X509_NAME_ENTRY_free(ret->entries);
+		free(ret);
+	}
+	return 0;
+}
+
+static void
+x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+	X509_NAME *a;
+
+	if (!pval || !*pval)
+		return;
+	a = (X509_NAME *)*pval;
+
+	BUF_MEM_free(a->bytes);
+	sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free);
+	free(a->canon_enc);
+	free(a);
+	*pval = NULL;
+}
+
+static int
+x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len,
+    const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx)
+{
+	const unsigned char *p = *in, *q;
+	union {
+		STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
+		ASN1_VALUE *a;
+	} intname = {NULL};
+	union {
+		X509_NAME *x;
+		ASN1_VALUE *a;
+	} nm = {NULL};
+	int i, j, ret;
+	STACK_OF(X509_NAME_ENTRY) *entries;
+	X509_NAME_ENTRY *entry;
+	q = p;
+
+	/* Get internal representation of Name */
+	ret = ASN1_item_ex_d2i(&intname.a, &p, len,
+	    ASN1_ITEM_rptr(X509_NAME_INTERNAL), tag, aclass, opt, ctx);
+
+	if (ret <= 0)
+		return ret;
+
+	if (*val)
+		x509_name_ex_free(val, NULL);
+	if (!x509_name_ex_new(&nm.a, NULL))
+		goto err;
+	/* We've decoded it: now cache encoding */
+	if (!BUF_MEM_grow(nm.x->bytes, p - q))
+		goto err;
+	memcpy(nm.x->bytes->data, q, p - q);
+
+	/* Convert internal representation to X509_NAME structure */
+	for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
+		entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
+		for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
+			entry = sk_X509_NAME_ENTRY_value(entries, j);
+			entry->set = i;
+			if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
+				goto err;
+		}
+		sk_X509_NAME_ENTRY_free(entries);
+	}
+	sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
+	ret = x509_name_canon(nm.x);
+	if (!ret)
+		goto err;
+	nm.x->modified = 0;
+	*val = nm.a;
+	*in = p;
+	return ret;
+
+err:
+	if (nm.x != NULL)
+		X509_NAME_free(nm.x);
+	ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+	return 0;
+}
+
+static int
+x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it,
+    int tag, int aclass)
+{
+	int ret;
+	X509_NAME *a = (X509_NAME *)*val;
+
+	if (a->modified) {
+		ret = x509_name_encode(a);
+		if (ret < 0)
+			return ret;
+		ret = x509_name_canon(a);
+		if (ret < 0)
+			return ret;
+	}
+	ret = a->bytes->length;
+	if (out != NULL) {
+		memcpy(*out, a->bytes->data, ret);
+		*out += ret;
+	}
+	return ret;
+}
+
+static void
+local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
+{
+	sk_X509_NAME_ENTRY_free(ne);
+}
+
+static void
+local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
+{
+	sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
+}
+
+static int
+x509_name_encode(X509_NAME *a)
+{
+	union {
+		STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
+		ASN1_VALUE *a;
+	} intname = {NULL};
+	int len;
+	unsigned char *p;
+	STACK_OF(X509_NAME_ENTRY) *entries = NULL;
+	X509_NAME_ENTRY *entry;
+	int i, set = -1;
+
+	intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
+	if (!intname.s)
+		goto memerr;
+	for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
+		entry = sk_X509_NAME_ENTRY_value(a->entries, i);
+		if (entry->set != set) {
+			entries = sk_X509_NAME_ENTRY_new_null();
+			if (!entries)
+				goto memerr;
+			if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s,
+			    entries))
+				goto memerr;
+			set = entry->set;
+		}
+		if (entries == NULL /* if entry->set is bogusly -1 */ ||
+		    !sk_X509_NAME_ENTRY_push(entries, entry))
+			goto memerr;
+	}
+	len = ASN1_item_ex_i2d(&intname.a, NULL,
+	    ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
+	if (!BUF_MEM_grow(a->bytes, len))
+		goto memerr;
+	p = (unsigned char *)a->bytes->data;
+	ASN1_item_ex_i2d(&intname.a, &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
+	    -1, -1);
+	sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+	    local_sk_X509_NAME_ENTRY_free);
+	a->modified = 0;
+	return len;
+
+memerr:
+	sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+	    local_sk_X509_NAME_ENTRY_free);
+	ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE);
+	return -1;
+}
+
+static int
+x509_name_ex_print(BIO *out, ASN1_VALUE **pval, int indent, const char *fname,
+    const ASN1_PCTX *pctx)
+{
+	if (X509_NAME_print_ex(out, (X509_NAME *)*pval, indent,
+	    pctx->nm_flags) <= 0)
+		return 0;
+	return 2;
+}
+
+/* This function generates the canonical encoding of the Name structure.
+ * In it all strings are converted to UTF8, leading, trailing and
+ * multiple spaces collapsed, converted to lower case and the leading
+ * SEQUENCE header removed.
+ *
+ * In future we could also normalize the UTF8 too.
+ *
+ * By doing this comparison of Name structures can be rapidly
+ * performed by just using memcmp() of the canonical encoding.
+ * By omitting the leading SEQUENCE name constraints of type
+ * dirName can also be checked with a simple memcmp().
+ */
+
+static int
+x509_name_canon(X509_NAME *a)
+{
+	unsigned char *p;
+	STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
+	STACK_OF(X509_NAME_ENTRY) *entries = NULL;
+	X509_NAME_ENTRY *entry, *tmpentry = NULL;
+	int i, len, set = -1, ret = 0;
+
+	if (a->canon_enc) {
+		free(a->canon_enc);
+		a->canon_enc = NULL;
+	}
+	/* Special case: empty X509_NAME => null encoding */
+	if (sk_X509_NAME_ENTRY_num(a->entries) == 0) {
+		a->canon_enclen = 0;
+		return 1;
+	}
+	intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
+	if (!intname)
+		goto err;
+	for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
+		entry = sk_X509_NAME_ENTRY_value(a->entries, i);
+		if (entry->set != set) {
+			entries = sk_X509_NAME_ENTRY_new_null();
+			if (!entries)
+				goto err;
+			if (sk_STACK_OF_X509_NAME_ENTRY_push(intname,
+			    entries) == 0) {
+				sk_X509_NAME_ENTRY_free(entries);
+				goto err;
+			}
+			set = entry->set;
+		}
+		tmpentry = X509_NAME_ENTRY_new();
+		if (tmpentry == NULL)
+			goto err;
+		tmpentry->object = OBJ_dup(entry->object);
+		if (tmpentry->object == NULL)
+			goto err;
+		if (!asn1_string_canon(tmpentry->value, entry->value))
+			goto err;
+		if (entries == NULL /* if entry->set is bogusly -1 */ ||
+		    !sk_X509_NAME_ENTRY_push(entries, tmpentry))
+			goto err;
+		tmpentry = NULL;
+	}
+
+	/* Finally generate encoding */
+	len = i2d_name_canon(intname, NULL);
+	if (len < 0)
+		goto err;
+	p = malloc(len);
+	if (p == NULL)
+		goto err;
+	a->canon_enc = p;
+	a->canon_enclen = len;
+	i2d_name_canon(intname, &p);
+	ret = 1;
+
+err:
+	if (tmpentry)
+		X509_NAME_ENTRY_free(tmpentry);
+	if (intname)
+		sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
+		    local_sk_X509_NAME_ENTRY_pop_free);
+	return ret;
+}
+
+/* Bitmap of all the types of string that will be canonicalized. */
+
+#define ASN1_MASK_CANON	\
+	(B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
+	| B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
+	| B_ASN1_VISIBLESTRING)
+
+
+static int
+asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in)
+{
+	unsigned char *to, *from;
+	int len, i;
+
+	/* If type not in bitmask just copy string across */
+	if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) {
+		if (!ASN1_STRING_copy(out, in))
+			return 0;
+		return 1;
+	}
+
+	out->type = V_ASN1_UTF8STRING;
+	out->length = ASN1_STRING_to_UTF8(&out->data, in);
+	if (out->length == -1)
+		return 0;
+
+	to = out->data;
+	from = to;
+
+	len = out->length;
+
+	/* Convert string in place to canonical form.
+	 * Ultimately we may need to handle a wider range of characters
+	 * but for now ignore anything with MSB set and rely on the
+	 * isspace() and tolower() functions.
+	 */
+
+	/* Ignore leading spaces */
+	while ((len > 0) && !(*from & 0x80) && isspace(*from)) {
+		from++;
+		len--;
+	}
+
+	to = from + len - 1;
+
+	/* Ignore trailing spaces */
+	while ((len > 0) && !(*to & 0x80) && isspace(*to)) {
+		to--;
+		len--;
+	}
+
+	to = out->data;
+
+	i = 0;
+	while (i < len) {
+		/* If MSB set just copy across */
+		if (*from & 0x80) {
+			*to++ = *from++;
+			i++;
+		}
+		/* Collapse multiple spaces */
+		else if (isspace(*from)) {
+			/* Copy one space across */
+			*to++ = ' ';
+			/* Ignore subsequent spaces. Note: don't need to
+			 * check len here because we know the last
+			 * character is a non-space so we can't overflow.
+			 */
+			do {
+				from++;
+				i++;
+			} while (!(*from & 0x80) && isspace(*from));
+		} else {
+			*to++ = tolower(*from);
+			from++;
+			i++;
+		}
+	}
+
+	out->length = to - out->data;
+
+	return 1;
+}
+
+static int
+i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname, unsigned char **in)
+{
+	int i, len, ltmp;
+	ASN1_VALUE *v;
+	STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
+
+	len = 0;
+	for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) {
+		v = sk_ASN1_VALUE_value(intname, i);
+		ltmp = ASN1_item_ex_i2d(&v, in,
+		    ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
+		if (ltmp < 0)
+			return ltmp;
+		len += ltmp;
+	}
+	return len;
+}
+
+int
+X509_NAME_set(X509_NAME **xn, X509_NAME *name)
+{
+	X509_NAME *in;
+
+	if (!xn || !name)
+		return (0);
+
+	if (*xn != name) {
+		in = X509_NAME_dup(name);
+		if (in != NULL) {
+			X509_NAME_free(*xn);
+			*xn = in;
+		}
+	}
+	return (*xn != NULL);
+}
diff --git a/crypto/libressl/crypto/asn1/x_nx509.c b/crypto/libressl/crypto/asn1/x_nx509.c
new file mode 100644
index 0000000000..c6b9e21c91
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/x_nx509.c
@@ -0,0 +1,113 @@
+/* $OpenBSD: x_nx509.c,v 1.5 2015/02/11 03:39:51 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+/* Old netscape certificate wrapper format */
+
+static const ASN1_TEMPLATE NETSCAPE_X509_seq_tt[] = {
+	{
+		.offset = offsetof(NETSCAPE_X509, header),
+		.field_name = "header",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.offset = offsetof(NETSCAPE_X509, cert),
+		.field_name = "cert",
+		.item = &X509_it,
+	},
+};
+
+const ASN1_ITEM NETSCAPE_X509_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = NETSCAPE_X509_seq_tt,
+	.tcount = sizeof(NETSCAPE_X509_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.size = sizeof(NETSCAPE_X509),
+	.sname = "NETSCAPE_X509",
+};
+
+
+NETSCAPE_X509 *
+d2i_NETSCAPE_X509(NETSCAPE_X509 **a, const unsigned char **in, long len)
+{
+	return (NETSCAPE_X509 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &NETSCAPE_X509_it);
+}
+
+int
+i2d_NETSCAPE_X509(NETSCAPE_X509 *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &NETSCAPE_X509_it);
+}
+
+NETSCAPE_X509 *
+NETSCAPE_X509_new(void)
+{
+	return (NETSCAPE_X509 *)ASN1_item_new(&NETSCAPE_X509_it);
+}
+
+void
+NETSCAPE_X509_free(NETSCAPE_X509 *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &NETSCAPE_X509_it);
+}
diff --git a/crypto/libressl/crypto/asn1/x_pkey.c b/crypto/libressl/crypto/asn1/x_pkey.c
new file mode 100644
index 0000000000..4b59561f0d
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/x_pkey.c
@@ -0,0 +1,121 @@
+/* $OpenBSD: x_pkey.c,v 1.18 2015/07/27 12:53:56 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+X509_PKEY *
+X509_PKEY_new(void)
+{
+	X509_PKEY *ret = NULL;
+
+	if ((ret = malloc(sizeof(X509_PKEY))) == NULL) {
+		ASN1err(ASN1_F_X509_PKEY_NEW, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	ret->version = 0;
+	if ((ret->enc_algor = X509_ALGOR_new()) == NULL) {
+		ASN1err(ASN1_F_X509_PKEY_NEW, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	if ((ret->enc_pkey = ASN1_OCTET_STRING_new()) == NULL) {
+		ASN1err(ASN1_F_X509_PKEY_NEW, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	ret->dec_pkey = NULL;
+	ret->key_length = 0;
+	ret->key_data = NULL;
+	ret->key_free = 0;
+	ret->cipher.cipher = NULL;
+	memset(ret->cipher.iv, 0, EVP_MAX_IV_LENGTH);
+	ret->references = 1;
+	return (ret);
+
+err:
+	if (ret) {
+		X509_ALGOR_free(ret->enc_algor);
+		free(ret);
+	}
+	return NULL;
+}
+
+void
+X509_PKEY_free(X509_PKEY *x)
+{
+	int i;
+
+	if (x == NULL)
+		return;
+
+	i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_X509_PKEY);
+	if (i > 0)
+		return;
+
+	if (x->enc_algor != NULL)
+		X509_ALGOR_free(x->enc_algor);
+	ASN1_OCTET_STRING_free(x->enc_pkey);
+	EVP_PKEY_free(x->dec_pkey);
+	if ((x->key_data != NULL) && (x->key_free))
+		free(x->key_data);
+	free(x);
+}
diff --git a/crypto/libressl/crypto/asn1/x_pubkey.c b/crypto/libressl/crypto/asn1/x_pubkey.c
new file mode 100644
index 0000000000..bc1d30d22f
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/x_pubkey.c
@@ -0,0 +1,430 @@
+/* $OpenBSD: x_pubkey.c,v 1.24 2015/02/11 03:39:51 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_DSA
+#include 
+#endif
+#ifndef OPENSSL_NO_RSA
+#include 
+#endif
+
+#include "asn1_locl.h"
+
+/* Minor tweak to operation: free up EVP_PKEY */
+static int
+pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
+{
+	if (operation == ASN1_OP_FREE_POST) {
+		X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
+		EVP_PKEY_free(pubkey->pkey);
+	}
+	return 1;
+}
+
+static const ASN1_AUX X509_PUBKEY_aux = {
+	.asn1_cb = pubkey_cb,
+};
+static const ASN1_TEMPLATE X509_PUBKEY_seq_tt[] = {
+	{
+		.offset = offsetof(X509_PUBKEY, algor),
+		.field_name = "algor",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.offset = offsetof(X509_PUBKEY, public_key),
+		.field_name = "public_key",
+		.item = &ASN1_BIT_STRING_it,
+	},
+};
+
+const ASN1_ITEM X509_PUBKEY_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = X509_PUBKEY_seq_tt,
+	.tcount = sizeof(X509_PUBKEY_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &X509_PUBKEY_aux,
+	.size = sizeof(X509_PUBKEY),
+	.sname = "X509_PUBKEY",
+};
+
+
+X509_PUBKEY *
+d2i_X509_PUBKEY(X509_PUBKEY **a, const unsigned char **in, long len)
+{
+	return (X509_PUBKEY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &X509_PUBKEY_it);
+}
+
+int
+i2d_X509_PUBKEY(X509_PUBKEY *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_PUBKEY_it);
+}
+
+X509_PUBKEY *
+X509_PUBKEY_new(void)
+{
+	return (X509_PUBKEY *)ASN1_item_new(&X509_PUBKEY_it);
+}
+
+void
+X509_PUBKEY_free(X509_PUBKEY *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &X509_PUBKEY_it);
+}
+
+int
+X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
+{
+	X509_PUBKEY *pk = NULL;
+
+	if (x == NULL)
+		return (0);
+	if ((pk = X509_PUBKEY_new()) == NULL)
+		goto error;
+
+	if (pkey->ameth) {
+		if (pkey->ameth->pub_encode) {
+			if (!pkey->ameth->pub_encode(pk, pkey)) {
+				X509err(X509_F_X509_PUBKEY_SET,
+				    X509_R_PUBLIC_KEY_ENCODE_ERROR);
+				goto error;
+			}
+		} else {
+			X509err(X509_F_X509_PUBKEY_SET,
+			    X509_R_METHOD_NOT_SUPPORTED);
+			goto error;
+		}
+	} else {
+		X509err(X509_F_X509_PUBKEY_SET, X509_R_UNSUPPORTED_ALGORITHM);
+		goto error;
+	}
+
+	if (*x != NULL)
+		X509_PUBKEY_free(*x);
+
+	*x = pk;
+
+	return 1;
+
+error:
+	if (pk != NULL)
+		X509_PUBKEY_free(pk);
+	return 0;
+}
+
+EVP_PKEY *
+X509_PUBKEY_get(X509_PUBKEY *key)
+{
+	EVP_PKEY *ret = NULL;
+
+	if (key == NULL)
+		goto error;
+
+	if (key->pkey != NULL) {
+		CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+		return key->pkey;
+	}
+
+	if (key->public_key == NULL)
+		goto error;
+
+	if ((ret = EVP_PKEY_new()) == NULL) {
+		X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
+		goto error;
+	}
+
+	if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm))) {
+		X509err(X509_F_X509_PUBKEY_GET, X509_R_UNSUPPORTED_ALGORITHM);
+		goto error;
+	}
+
+	if (ret->ameth->pub_decode) {
+		if (!ret->ameth->pub_decode(ret, key)) {
+			X509err(X509_F_X509_PUBKEY_GET,
+			    X509_R_PUBLIC_KEY_DECODE_ERROR);
+			goto error;
+		}
+	} else {
+		X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED);
+		goto error;
+	}
+
+	/* Check to see if another thread set key->pkey first */
+	CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
+	if (key->pkey) {
+		CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
+		EVP_PKEY_free(ret);
+		ret = key->pkey;
+	} else {
+		key->pkey = ret;
+		CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
+	}
+	CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
+
+	return ret;
+
+error:
+	EVP_PKEY_free(ret);
+	return (NULL);
+}
+
+/* Now two pseudo ASN1 routines that take an EVP_PKEY structure
+ * and encode or decode as X509_PUBKEY
+ */
+
+EVP_PKEY *
+d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length)
+{
+	X509_PUBKEY *xpk;
+	EVP_PKEY *pktmp;
+	xpk = d2i_X509_PUBKEY(NULL, pp, length);
+	if (!xpk)
+		return NULL;
+	pktmp = X509_PUBKEY_get(xpk);
+	X509_PUBKEY_free(xpk);
+	if (!pktmp)
+		return NULL;
+	if (a) {
+		EVP_PKEY_free(*a);
+		*a = pktmp;
+	}
+	return pktmp;
+}
+
+int
+i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
+{
+	X509_PUBKEY *xpk = NULL;
+	int ret;
+	if (!a)
+		return 0;
+	if (!X509_PUBKEY_set(&xpk, a))
+		return 0;
+	ret = i2d_X509_PUBKEY(xpk, pp);
+	X509_PUBKEY_free(xpk);
+	return ret;
+}
+
+/* The following are equivalents but which return RSA and DSA
+ * keys
+ */
+#ifndef OPENSSL_NO_RSA
+RSA *
+d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length)
+{
+	EVP_PKEY *pkey;
+	RSA *key;
+	const unsigned char *q;
+	q = *pp;
+	pkey = d2i_PUBKEY(NULL, &q, length);
+	if (!pkey)
+		return NULL;
+	key = EVP_PKEY_get1_RSA(pkey);
+	EVP_PKEY_free(pkey);
+	if (!key)
+		return NULL;
+	*pp = q;
+	if (a) {
+		RSA_free(*a);
+		*a = key;
+	}
+	return key;
+}
+
+int
+i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
+{
+	EVP_PKEY *pktmp;
+	int ret;
+	if (!a)
+		return 0;
+	pktmp = EVP_PKEY_new();
+	if (!pktmp) {
+		ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	EVP_PKEY_set1_RSA(pktmp, a);
+	ret = i2d_PUBKEY(pktmp, pp);
+	EVP_PKEY_free(pktmp);
+	return ret;
+}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+DSA *
+d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length)
+{
+	EVP_PKEY *pkey;
+	DSA *key;
+	const unsigned char *q;
+	q = *pp;
+	pkey = d2i_PUBKEY(NULL, &q, length);
+	if (!pkey)
+		return NULL;
+	key = EVP_PKEY_get1_DSA(pkey);
+	EVP_PKEY_free(pkey);
+	if (!key)
+		return NULL;
+	*pp = q;
+	if (a) {
+		DSA_free(*a);
+		*a = key;
+	}
+	return key;
+}
+
+int
+i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
+{
+	EVP_PKEY *pktmp;
+	int ret;
+	if (!a)
+		return 0;
+	pktmp = EVP_PKEY_new();
+	if (!pktmp) {
+		ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	EVP_PKEY_set1_DSA(pktmp, a);
+	ret = i2d_PUBKEY(pktmp, pp);
+	EVP_PKEY_free(pktmp);
+	return ret;
+}
+#endif
+
+#ifndef OPENSSL_NO_EC
+EC_KEY *
+d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
+{
+	EVP_PKEY *pkey;
+	EC_KEY *key;
+	const unsigned char *q;
+	q = *pp;
+	pkey = d2i_PUBKEY(NULL, &q, length);
+	if (!pkey)
+		return (NULL);
+	key = EVP_PKEY_get1_EC_KEY(pkey);
+	EVP_PKEY_free(pkey);
+	if (!key)
+		return (NULL);
+	*pp = q;
+	if (a) {
+		EC_KEY_free(*a);
+		*a = key;
+	}
+	return (key);
+}
+
+int
+i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
+{
+	EVP_PKEY *pktmp;
+	int ret;
+	if (!a)
+		return (0);
+	if ((pktmp = EVP_PKEY_new()) == NULL) {
+		ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
+		return (0);
+	}
+	EVP_PKEY_set1_EC_KEY(pktmp, a);
+	ret = i2d_PUBKEY(pktmp, pp);
+	EVP_PKEY_free(pktmp);
+	return (ret);
+}
+#endif
+
+int
+X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, int ptype,
+    void *pval, unsigned char *penc, int penclen)
+{
+	if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
+		return 0;
+	if (penc) {
+		free(pub->public_key->data);
+		pub->public_key->data = penc;
+		pub->public_key->length = penclen;
+		/* Set number of unused bits to zero */
+		pub->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
+		pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+	}
+	return 1;
+}
+
+int
+X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, const unsigned char **pk,
+    int *ppklen, X509_ALGOR **pa, X509_PUBKEY *pub)
+{
+	if (ppkalg)
+		*ppkalg = pub->algor->algorithm;
+	if (pk) {
+		*pk = pub->public_key->data;
+		*ppklen = pub->public_key->length;
+	}
+	if (pa)
+		*pa = pub->algor;
+	return 1;
+}
diff --git a/crypto/libressl/crypto/asn1/x_req.c b/crypto/libressl/crypto/asn1/x_req.c
new file mode 100644
index 0000000000..99c935622f
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/x_req.c
@@ -0,0 +1,227 @@
+/* $OpenBSD: x_req.c,v 1.14 2015/02/11 03:39:51 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+
+/* X509_REQ_INFO is handled in an unusual way to get round
+ * invalid encodings. Some broken certificate requests don't
+ * encode the attributes field if it is empty. This is in
+ * violation of PKCS#10 but we need to tolerate it. We do
+ * this by making the attributes field OPTIONAL then using
+ * the callback to initialise it to an empty STACK.
+ *
+ * This means that the field will be correctly encoded unless
+ * we NULL out the field.
+ *
+ * As a result we no longer need the req_kludge field because
+ * the information is now contained in the attributes field:
+ * 1. If it is NULL then it's the invalid omission.
+ * 2. If it is empty it is the correct encoding.
+ * 3. If it is not empty then some attributes are present.
+ *
+ */
+
+static int
+rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
+{
+	X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval;
+
+	if (operation == ASN1_OP_NEW_POST) {
+		rinf->attributes = sk_X509_ATTRIBUTE_new_null();
+		if (!rinf->attributes)
+			return 0;
+	}
+	return 1;
+}
+
+static const ASN1_AUX X509_REQ_INFO_aux = {
+	.flags = ASN1_AFLG_ENCODING,
+	.asn1_cb = rinf_cb,
+	.enc_offset = offsetof(X509_REQ_INFO, enc),
+};
+static const ASN1_TEMPLATE X509_REQ_INFO_seq_tt[] = {
+	{
+		.offset = offsetof(X509_REQ_INFO, version),
+		.field_name = "version",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.offset = offsetof(X509_REQ_INFO, subject),
+		.field_name = "subject",
+		.item = &X509_NAME_it,
+	},
+	{
+		.offset = offsetof(X509_REQ_INFO, pubkey),
+		.field_name = "pubkey",
+		.item = &X509_PUBKEY_it,
+	},
+	/* This isn't really OPTIONAL but it gets round invalid
+	 * encodings
+	 */
+	{
+		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
+		.offset = offsetof(X509_REQ_INFO, attributes),
+		.field_name = "attributes",
+		.item = &X509_ATTRIBUTE_it,
+	},
+};
+
+const ASN1_ITEM X509_REQ_INFO_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = X509_REQ_INFO_seq_tt,
+	.tcount = sizeof(X509_REQ_INFO_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &X509_REQ_INFO_aux,
+	.size = sizeof(X509_REQ_INFO),
+	.sname = "X509_REQ_INFO",
+};
+
+
+X509_REQ_INFO *
+d2i_X509_REQ_INFO(X509_REQ_INFO **a, const unsigned char **in, long len)
+{
+	return (X509_REQ_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &X509_REQ_INFO_it);
+}
+
+int
+i2d_X509_REQ_INFO(X509_REQ_INFO *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_REQ_INFO_it);
+}
+
+X509_REQ_INFO *
+X509_REQ_INFO_new(void)
+{
+	return (X509_REQ_INFO *)ASN1_item_new(&X509_REQ_INFO_it);
+}
+
+void
+X509_REQ_INFO_free(X509_REQ_INFO *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &X509_REQ_INFO_it);
+}
+
+static const ASN1_AUX X509_REQ_aux = {
+	.app_data = NULL,
+	.flags = ASN1_AFLG_REFCOUNT,
+	.ref_offset = offsetof(X509_REQ, references),
+	.ref_lock = CRYPTO_LOCK_X509_REQ,
+};
+static const ASN1_TEMPLATE X509_REQ_seq_tt[] = {
+	{
+		.offset = offsetof(X509_REQ, req_info),
+		.field_name = "req_info",
+		.item = &X509_REQ_INFO_it,
+	},
+	{
+		.offset = offsetof(X509_REQ, sig_alg),
+		.field_name = "sig_alg",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.offset = offsetof(X509_REQ, signature),
+		.field_name = "signature",
+		.item = &ASN1_BIT_STRING_it,
+	},
+};
+
+const ASN1_ITEM X509_REQ_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = X509_REQ_seq_tt,
+	.tcount = sizeof(X509_REQ_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &X509_REQ_aux,
+	.size = sizeof(X509_REQ),
+	.sname = "X509_REQ",
+};
+
+
+X509_REQ *
+d2i_X509_REQ(X509_REQ **a, const unsigned char **in, long len)
+{
+	return (X509_REQ *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &X509_REQ_it);
+}
+
+int
+i2d_X509_REQ(X509_REQ *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_REQ_it);
+}
+
+X509_REQ *
+X509_REQ_new(void)
+{
+	return (X509_REQ *)ASN1_item_new(&X509_REQ_it);
+}
+
+void
+X509_REQ_free(X509_REQ *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &X509_REQ_it);
+}
+
+X509_REQ *
+X509_REQ_dup(X509_REQ *x)
+{
+	return ASN1_item_dup(&X509_REQ_it, x);
+}
diff --git a/crypto/libressl/crypto/asn1/x_sig.c b/crypto/libressl/crypto/asn1/x_sig.c
new file mode 100644
index 0000000000..7d62c7885c
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/x_sig.c
@@ -0,0 +1,110 @@
+/* $OpenBSD: x_sig.c,v 1.10 2015/02/11 03:39:51 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+
+static const ASN1_TEMPLATE X509_SIG_seq_tt[] = {
+	{
+		.offset = offsetof(X509_SIG, algor),
+		.field_name = "algor",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.offset = offsetof(X509_SIG, digest),
+		.field_name = "digest",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+};
+
+const ASN1_ITEM X509_SIG_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = X509_SIG_seq_tt,
+	.tcount = sizeof(X509_SIG_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.size = sizeof(X509_SIG),
+	.sname = "X509_SIG",
+};
+
+
+X509_SIG *
+d2i_X509_SIG(X509_SIG **a, const unsigned char **in, long len)
+{
+	return (X509_SIG *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &X509_SIG_it);
+}
+
+int
+i2d_X509_SIG(X509_SIG *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_SIG_it);
+}
+
+X509_SIG *
+X509_SIG_new(void)
+{
+	return (X509_SIG *)ASN1_item_new(&X509_SIG_it);
+}
+
+void
+X509_SIG_free(X509_SIG *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &X509_SIG_it);
+}
diff --git a/crypto/libressl/crypto/asn1/x_spki.c b/crypto/libressl/crypto/asn1/x_spki.c
new file mode 100644
index 0000000000..13c4df8857
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/x_spki.c
@@ -0,0 +1,174 @@
+/* $OpenBSD: x_spki.c,v 1.10 2015/02/11 03:39:51 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+ /* This module was send to me my Pat Richards  who
+  * wrote it.  It is under my Copyright with his permission
+  */
+
+#include 
+
+#include 
+#include 
+
+static const ASN1_TEMPLATE NETSCAPE_SPKAC_seq_tt[] = {
+	{
+		.offset = offsetof(NETSCAPE_SPKAC, pubkey),
+		.field_name = "pubkey",
+		.item = &X509_PUBKEY_it,
+	},
+	{
+		.offset = offsetof(NETSCAPE_SPKAC, challenge),
+		.field_name = "challenge",
+		.item = &ASN1_IA5STRING_it,
+	},
+};
+
+const ASN1_ITEM NETSCAPE_SPKAC_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = NETSCAPE_SPKAC_seq_tt,
+	.tcount = sizeof(NETSCAPE_SPKAC_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.size = sizeof(NETSCAPE_SPKAC),
+	.sname = "NETSCAPE_SPKAC",
+};
+
+
+NETSCAPE_SPKAC *
+d2i_NETSCAPE_SPKAC(NETSCAPE_SPKAC **a, const unsigned char **in, long len)
+{
+	return (NETSCAPE_SPKAC *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &NETSCAPE_SPKAC_it);
+}
+
+int
+i2d_NETSCAPE_SPKAC(NETSCAPE_SPKAC *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &NETSCAPE_SPKAC_it);
+}
+
+NETSCAPE_SPKAC *
+NETSCAPE_SPKAC_new(void)
+{
+	return (NETSCAPE_SPKAC *)ASN1_item_new(&NETSCAPE_SPKAC_it);
+}
+
+void
+NETSCAPE_SPKAC_free(NETSCAPE_SPKAC *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &NETSCAPE_SPKAC_it);
+}
+
+static const ASN1_TEMPLATE NETSCAPE_SPKI_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(NETSCAPE_SPKI, spkac),
+		.field_name = "spkac",
+		.item = &NETSCAPE_SPKAC_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(NETSCAPE_SPKI, sig_algor),
+		.field_name = "sig_algor",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(NETSCAPE_SPKI, signature),
+		.field_name = "signature",
+		.item = &ASN1_BIT_STRING_it,
+	},
+};
+
+const ASN1_ITEM NETSCAPE_SPKI_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = NETSCAPE_SPKI_seq_tt,
+	.tcount = sizeof(NETSCAPE_SPKI_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(NETSCAPE_SPKI),
+	.sname = "NETSCAPE_SPKI",
+};
+
+
+NETSCAPE_SPKI *
+d2i_NETSCAPE_SPKI(NETSCAPE_SPKI **a, const unsigned char **in, long len)
+{
+	return (NETSCAPE_SPKI *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &NETSCAPE_SPKI_it);
+}
+
+int
+i2d_NETSCAPE_SPKI(NETSCAPE_SPKI *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &NETSCAPE_SPKI_it);
+}
+
+NETSCAPE_SPKI *
+NETSCAPE_SPKI_new(void)
+{
+	return (NETSCAPE_SPKI *)ASN1_item_new(&NETSCAPE_SPKI_it);
+}
+
+void
+NETSCAPE_SPKI_free(NETSCAPE_SPKI *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &NETSCAPE_SPKI_it);
+}
diff --git a/crypto/libressl/crypto/asn1/x_val.c b/crypto/libressl/crypto/asn1/x_val.c
new file mode 100644
index 0000000000..feeff6e276
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/x_val.c
@@ -0,0 +1,110 @@
+/* $OpenBSD: x_val.c,v 1.10 2015/02/11 03:39:51 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+
+static const ASN1_TEMPLATE X509_VAL_seq_tt[] = {
+	{
+		.offset = offsetof(X509_VAL, notBefore),
+		.field_name = "notBefore",
+		.item = &ASN1_TIME_it,
+	},
+	{
+		.offset = offsetof(X509_VAL, notAfter),
+		.field_name = "notAfter",
+		.item = &ASN1_TIME_it,
+	},
+};
+
+const ASN1_ITEM X509_VAL_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = X509_VAL_seq_tt,
+	.tcount = sizeof(X509_VAL_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.size = sizeof(X509_VAL),
+	.sname = "X509_VAL",
+};
+
+
+X509_VAL *
+d2i_X509_VAL(X509_VAL **a, const unsigned char **in, long len)
+{
+	return (X509_VAL *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &X509_VAL_it);
+}
+
+int
+i2d_X509_VAL(X509_VAL *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_VAL_it);
+}
+
+X509_VAL *
+X509_VAL_new(void)
+{
+	return (X509_VAL *)ASN1_item_new(&X509_VAL_it);
+}
+
+void
+X509_VAL_free(X509_VAL *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &X509_VAL_it);
+}
diff --git a/crypto/libressl/crypto/asn1/x_x509.c b/crypto/libressl/crypto/asn1/x_x509.c
new file mode 100644
index 0000000000..e0533a4ebb
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/x_x509.c
@@ -0,0 +1,346 @@
+/* $OpenBSD: x_x509.c,v 1.23 2015/02/11 04:00:39 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+static const ASN1_AUX X509_CINF_aux = {
+	.flags = ASN1_AFLG_ENCODING,
+	.enc_offset = offsetof(X509_CINF, enc),
+};
+static const ASN1_TEMPLATE X509_CINF_seq_tt[] = {
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.offset = offsetof(X509_CINF, version),
+		.field_name = "version",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.offset = offsetof(X509_CINF, serialNumber),
+		.field_name = "serialNumber",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.offset = offsetof(X509_CINF, signature),
+		.field_name = "signature",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.offset = offsetof(X509_CINF, issuer),
+		.field_name = "issuer",
+		.item = &X509_NAME_it,
+	},
+	{
+		.offset = offsetof(X509_CINF, validity),
+		.field_name = "validity",
+		.item = &X509_VAL_it,
+	},
+	{
+		.offset = offsetof(X509_CINF, subject),
+		.field_name = "subject",
+		.item = &X509_NAME_it,
+	},
+	{
+		.offset = offsetof(X509_CINF, key),
+		.field_name = "key",
+		.item = &X509_PUBKEY_it,
+	},
+	{
+		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 1,
+		.offset = offsetof(X509_CINF, issuerUID),
+		.field_name = "issuerUID",
+		.item = &ASN1_BIT_STRING_it,
+	},
+	{
+		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 2,
+		.offset = offsetof(X509_CINF, subjectUID),
+		.field_name = "subjectUID",
+		.item = &ASN1_BIT_STRING_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF |
+		    ASN1_TFLG_OPTIONAL,
+		.tag = 3,
+		.offset = offsetof(X509_CINF, extensions),
+		.field_name = "extensions",
+		.item = &X509_EXTENSION_it,
+	},
+};
+
+const ASN1_ITEM X509_CINF_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = X509_CINF_seq_tt,
+	.tcount = sizeof(X509_CINF_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &X509_CINF_aux,
+	.size = sizeof(X509_CINF),
+	.sname = "X509_CINF",
+};
+
+
+X509_CINF *
+d2i_X509_CINF(X509_CINF **a, const unsigned char **in, long len)
+{
+	return (X509_CINF *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &X509_CINF_it);
+}
+
+int
+i2d_X509_CINF(X509_CINF *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_CINF_it);
+}
+
+X509_CINF *
+X509_CINF_new(void)
+{
+	return (X509_CINF *)ASN1_item_new(&X509_CINF_it);
+}
+
+void
+X509_CINF_free(X509_CINF *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &X509_CINF_it);
+}
+/* X509 top level structure needs a bit of customisation */
+
+extern void policy_cache_free(X509_POLICY_CACHE *cache);
+
+static int
+x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
+{
+	X509 *ret = (X509 *)*pval;
+
+	switch (operation) {
+
+	case ASN1_OP_NEW_POST:
+		ret->valid = 0;
+		ret->name = NULL;
+		ret->ex_flags = 0;
+		ret->ex_pathlen = -1;
+		ret->skid = NULL;
+		ret->akid = NULL;
+		ret->aux = NULL;
+		ret->crldp = NULL;
+		CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
+		break;
+
+	case ASN1_OP_D2I_POST:
+		free(ret->name);
+		ret->name = X509_NAME_oneline(ret->cert_info->subject, NULL, 0);
+		break;
+
+	case ASN1_OP_FREE_POST:
+		CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
+		X509_CERT_AUX_free(ret->aux);
+		ASN1_OCTET_STRING_free(ret->skid);
+		AUTHORITY_KEYID_free(ret->akid);
+		CRL_DIST_POINTS_free(ret->crldp);
+		policy_cache_free(ret->policy_cache);
+		GENERAL_NAMES_free(ret->altname);
+		NAME_CONSTRAINTS_free(ret->nc);
+		free(ret->name);
+		ret->name = NULL;
+		break;
+	}
+
+	return 1;
+}
+
+static const ASN1_AUX X509_aux = {
+	.app_data = NULL,
+	.flags = ASN1_AFLG_REFCOUNT,
+	.ref_offset = offsetof(X509, references),
+	.ref_lock = CRYPTO_LOCK_X509,
+	.asn1_cb = x509_cb,
+};
+static const ASN1_TEMPLATE X509_seq_tt[] = {
+	{
+		.offset = offsetof(X509, cert_info),
+		.field_name = "cert_info",
+		.item = &X509_CINF_it,
+	},
+	{
+		.offset = offsetof(X509, sig_alg),
+		.field_name = "sig_alg",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.offset = offsetof(X509, signature),
+		.field_name = "signature",
+		.item = &ASN1_BIT_STRING_it,
+	},
+};
+
+const ASN1_ITEM X509_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = X509_seq_tt,
+	.tcount = sizeof(X509_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &X509_aux,
+	.size = sizeof(X509),
+	.sname = "X509",
+};
+
+
+X509 *
+d2i_X509(X509 **a, const unsigned char **in, long len)
+{
+	return (X509 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &X509_it);
+}
+
+int
+i2d_X509(X509 *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_it);
+}
+
+X509 *
+X509_new(void)
+{
+	return (X509 *)ASN1_item_new(&X509_it);
+}
+
+void
+X509_free(X509 *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &X509_it);
+}
+
+X509 *
+X509_dup(X509 *x)
+{
+	return ASN1_item_dup(&X509_it, x);
+}
+
+int
+X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+    CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+{
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509, argl, argp,
+	    new_func, dup_func, free_func);
+}
+
+int
+X509_set_ex_data(X509 *r, int idx, void *arg)
+{
+	return (CRYPTO_set_ex_data(&r->ex_data, idx, arg));
+}
+
+void *
+X509_get_ex_data(X509 *r, int idx)
+{
+	return (CRYPTO_get_ex_data(&r->ex_data, idx));
+}
+
+/* X509_AUX ASN1 routines. X509_AUX is the name given to
+ * a certificate with extra info tagged on the end. Since these
+ * functions set how a certificate is trusted they should only
+ * be used when the certificate comes from a reliable source
+ * such as local storage.
+ *
+ */
+
+X509 *
+d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
+{
+	const unsigned char *q;
+	X509 *ret;
+
+	/* Save start position */
+	q = *pp;
+	ret = d2i_X509(NULL, pp, length);
+	/* If certificate unreadable then forget it */
+	if (!ret)
+		return NULL;
+	/* update length */
+	length -= *pp - q;
+	if (length > 0) {
+		if (!d2i_X509_CERT_AUX(&ret->aux, pp, length))
+			goto err;
+	}
+	if (a != NULL) {
+		X509_free(*a);
+		*a = ret;
+	}
+	return ret;
+
+err:
+	X509_free(ret);
+	return NULL;
+}
+
+int
+i2d_X509_AUX(X509 *a, unsigned char **pp)
+{
+	int length;
+
+	length = i2d_X509(a, pp);
+	if (a)
+		length += i2d_X509_CERT_AUX(a->aux, pp);
+	return length;
+}
diff --git a/crypto/libressl/crypto/asn1/x_x509a.c b/crypto/libressl/crypto/asn1/x_x509a.c
new file mode 100644
index 0000000000..dee270e75e
--- /dev/null
+++ b/crypto/libressl/crypto/asn1/x_x509a.c
@@ -0,0 +1,325 @@
+/* $OpenBSD: x_x509a.c,v 1.13 2015/02/11 04:00:39 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+/* X509_CERT_AUX routines. These are used to encode additional
+ * user modifiable data about a certificate. This data is
+ * appended to the X509 encoding when the *_X509_AUX routines
+ * are used. This means that the "traditional" X509 routines
+ * will simply ignore the extra data.
+ */
+
+static X509_CERT_AUX *aux_get(X509 *x);
+
+static const ASN1_TEMPLATE X509_CERT_AUX_seq_tt[] = {
+	{
+		.flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
+		.offset = offsetof(X509_CERT_AUX, trust),
+		.field_name = "trust",
+		.item = &ASN1_OBJECT_it,
+	},
+	{
+		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF |
+		    ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(X509_CERT_AUX, reject),
+		.field_name = "reject",
+		.item = &ASN1_OBJECT_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.offset = offsetof(X509_CERT_AUX, alias),
+		.field_name = "alias",
+		.item = &ASN1_UTF8STRING_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.offset = offsetof(X509_CERT_AUX, keyid),
+		.field_name = "keyid",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+	{
+		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF |
+		    ASN1_TFLG_OPTIONAL,
+		.tag = 1,
+		.offset = offsetof(X509_CERT_AUX, other),
+		.field_name = "other",
+		.item = &X509_ALGOR_it,
+	},
+};
+
+const ASN1_ITEM X509_CERT_AUX_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = X509_CERT_AUX_seq_tt,
+	.tcount = sizeof(X509_CERT_AUX_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.size = sizeof(X509_CERT_AUX),
+	.sname = "X509_CERT_AUX",
+};
+
+
+X509_CERT_AUX *
+d2i_X509_CERT_AUX(X509_CERT_AUX **a, const unsigned char **in, long len)
+{
+	return (X509_CERT_AUX *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &X509_CERT_AUX_it);
+}
+
+int
+i2d_X509_CERT_AUX(X509_CERT_AUX *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_CERT_AUX_it);
+}
+
+X509_CERT_AUX *
+X509_CERT_AUX_new(void)
+{
+	return (X509_CERT_AUX *)ASN1_item_new(&X509_CERT_AUX_it);
+}
+
+void
+X509_CERT_AUX_free(X509_CERT_AUX *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &X509_CERT_AUX_it);
+}
+
+static X509_CERT_AUX *
+aux_get(X509 *x)
+{
+	if (!x)
+		return NULL;
+	if (!x->aux && !(x->aux = X509_CERT_AUX_new()))
+		return NULL;
+	return x->aux;
+}
+
+int
+X509_alias_set1(X509 *x, unsigned char *name, int len)
+{
+	X509_CERT_AUX *aux;
+	if (!name) {
+		if (!x || !x->aux || !x->aux->alias)
+			return 1;
+		ASN1_UTF8STRING_free(x->aux->alias);
+		x->aux->alias = NULL;
+		return 1;
+	}
+	if (!(aux = aux_get(x)))
+		return 0;
+	if (!aux->alias && !(aux->alias = ASN1_UTF8STRING_new()))
+		return 0;
+	return ASN1_STRING_set(aux->alias, name, len);
+}
+
+int
+X509_keyid_set1(X509 *x, unsigned char *id, int len)
+{
+	X509_CERT_AUX *aux;
+	if (!id) {
+		if (!x || !x->aux || !x->aux->keyid)
+			return 1;
+		ASN1_OCTET_STRING_free(x->aux->keyid);
+		x->aux->keyid = NULL;
+		return 1;
+	}
+	if (!(aux = aux_get(x)))
+		return 0;
+	if (!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new()))
+		return 0;
+	return ASN1_STRING_set(aux->keyid, id, len);
+}
+
+unsigned char *
+X509_alias_get0(X509 *x, int *len)
+{
+	if (!x->aux || !x->aux->alias)
+		return NULL;
+	if (len)
+		*len = x->aux->alias->length;
+	return x->aux->alias->data;
+}
+
+unsigned char *
+X509_keyid_get0(X509 *x, int *len)
+{
+	if (!x->aux || !x->aux->keyid)
+		return NULL;
+	if (len)
+		*len = x->aux->keyid->length;
+	return x->aux->keyid->data;
+}
+
+int
+X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj)
+{
+	X509_CERT_AUX *aux;
+	ASN1_OBJECT *objtmp;
+	int rc;
+
+	if (!(objtmp = OBJ_dup(obj)))
+		return 0;
+	if (!(aux = aux_get(x)))
+		goto err;
+	if (!aux->trust && !(aux->trust = sk_ASN1_OBJECT_new_null()))
+		goto err;
+	rc = sk_ASN1_OBJECT_push(aux->trust, objtmp);
+	if (rc != 0)
+		return rc;
+
+err:
+	ASN1_OBJECT_free(objtmp);
+	return 0;
+}
+
+int
+X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj)
+{
+	X509_CERT_AUX *aux;
+	ASN1_OBJECT *objtmp;
+	int rc;
+
+	if (!(objtmp = OBJ_dup(obj)))
+		return 0;
+	if (!(aux = aux_get(x)))
+		goto err;
+	if (!aux->reject && !(aux->reject = sk_ASN1_OBJECT_new_null()))
+		goto err;
+	rc = sk_ASN1_OBJECT_push(aux->reject, objtmp);
+	if (rc != 0)
+		return rc;
+
+err:
+	ASN1_OBJECT_free(objtmp);
+	return 0;
+}
+
+void
+X509_trust_clear(X509 *x)
+{
+	if (x->aux && x->aux->trust) {
+		sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free);
+		x->aux->trust = NULL;
+	}
+}
+
+void
+X509_reject_clear(X509 *x)
+{
+	if (x->aux && x->aux->reject) {
+		sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free);
+		x->aux->reject = NULL;
+	}
+}
+
+static const ASN1_TEMPLATE X509_CERT_PAIR_seq_tt[] = {
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(X509_CERT_PAIR, forward),
+		.field_name = "forward",
+		.item = &X509_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 1,
+		.offset = offsetof(X509_CERT_PAIR, reverse),
+		.field_name = "reverse",
+		.item = &X509_it,
+	},
+};
+
+const ASN1_ITEM X509_CERT_PAIR_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = X509_CERT_PAIR_seq_tt,
+	.tcount = sizeof(X509_CERT_PAIR_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(X509_CERT_PAIR),
+	.sname = "X509_CERT_PAIR",
+};
+
+
+X509_CERT_PAIR *
+d2i_X509_CERT_PAIR(X509_CERT_PAIR **a, const unsigned char **in, long len)
+{
+	return (X509_CERT_PAIR *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &X509_CERT_PAIR_it);
+}
+
+int
+i2d_X509_CERT_PAIR(X509_CERT_PAIR *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_CERT_PAIR_it);
+}
+
+X509_CERT_PAIR *
+X509_CERT_PAIR_new(void)
+{
+	return (X509_CERT_PAIR *)ASN1_item_new(&X509_CERT_PAIR_it);
+}
+
+void
+X509_CERT_PAIR_free(X509_CERT_PAIR *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &X509_CERT_PAIR_it);
+}
diff --git a/crypto/libressl/crypto/bf/bf_cfb64.c b/crypto/libressl/crypto/bf/bf_cfb64.c
new file mode 100644
index 0000000000..ded1b163fa
--- /dev/null
+++ b/crypto/libressl/crypto/bf/bf_cfb64.c
@@ -0,0 +1,121 @@
+/* $OpenBSD: bf_cfb64.c,v 1.4 2014/06/12 15:49:28 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include "bf_locl.h"
+
+/* The input and output encrypted as though 64bit cfb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+
+void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, long length,
+	     const BF_KEY *schedule, unsigned char *ivec, int *num, int encrypt)
+	{
+	BF_LONG v0,v1,t;
+	int n= *num;
+	long l=length;
+	BF_LONG ti[2];
+	unsigned char *iv,c,cc;
+
+	iv=(unsigned char *)ivec;
+	if (encrypt)
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				n2l(iv,v0); ti[0]=v0;
+				n2l(iv,v1); ti[1]=v1;
+				BF_encrypt((BF_LONG *)ti,schedule);
+				iv=(unsigned char *)ivec;
+				t=ti[0]; l2n(t,iv);
+				t=ti[1]; l2n(t,iv);
+				iv=(unsigned char *)ivec;
+				}
+			c= *(in++)^iv[n];
+			*(out++)=c;
+			iv[n]=c;
+			n=(n+1)&0x07;
+			}
+		}
+	else
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				n2l(iv,v0); ti[0]=v0;
+				n2l(iv,v1); ti[1]=v1;
+				BF_encrypt((BF_LONG *)ti,schedule);
+				iv=(unsigned char *)ivec;
+				t=ti[0]; l2n(t,iv);
+				t=ti[1]; l2n(t,iv);
+				iv=(unsigned char *)ivec;
+				}
+			cc= *(in++);
+			c=iv[n];
+			iv[n]=cc;
+			*(out++)=c^cc;
+			n=(n+1)&0x07;
+			}
+		}
+	v0=v1=ti[0]=ti[1]=t=c=cc=0;
+	*num=n;
+	}
+
diff --git a/crypto/libressl/crypto/bf/bf_ecb.c b/crypto/libressl/crypto/bf/bf_ecb.c
new file mode 100644
index 0000000000..b3e3886cc8
--- /dev/null
+++ b/crypto/libressl/crypto/bf/bf_ecb.c
@@ -0,0 +1,94 @@
+/* $OpenBSD: bf_ecb.c,v 1.5 2014/06/12 15:49:28 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include "bf_locl.h"
+#include 
+
+/* Blowfish as implemented from 'Blowfish: Springer-Verlag paper'
+ * (From LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION,
+ * CAMBRIDGE SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993)
+ */
+
+const char *BF_options(void)
+	{
+#ifdef BF_PTR
+	return("blowfish(ptr)");
+#elif defined(BF_PTR2)
+	return("blowfish(ptr2)");
+#else
+	return("blowfish(idx)");
+#endif
+	}
+
+void BF_ecb_encrypt(const unsigned char *in, unsigned char *out,
+	     const BF_KEY *key, int encrypt)
+	{
+	BF_LONG l,d[2];
+
+	n2l(in,l); d[0]=l;
+	n2l(in,l); d[1]=l;
+	if (encrypt)
+		BF_encrypt(d,key);
+	else
+		BF_decrypt(d,key);
+	l=d[0]; l2n(l,out);
+	l=d[1]; l2n(l,out);
+	l=d[0]=d[1]=0;
+	}
+
diff --git a/crypto/libressl/crypto/bf/bf_enc.c b/crypto/libressl/crypto/bf/bf_enc.c
new file mode 100644
index 0000000000..31fcaccc8b
--- /dev/null
+++ b/crypto/libressl/crypto/bf/bf_enc.c
@@ -0,0 +1,306 @@
+/* $OpenBSD: bf_enc.c,v 1.5 2014/06/12 15:49:28 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include "bf_locl.h"
+
+/* Blowfish as implemented from 'Blowfish: Springer-Verlag paper'
+ * (From LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION,
+ * CAMBRIDGE SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993)
+ */
+
+#if (BF_ROUNDS != 16) && (BF_ROUNDS != 20)
+#error If you set BF_ROUNDS to some value other than 16 or 20, you will have \
+to modify the code.
+#endif
+
+void BF_encrypt(BF_LONG *data, const BF_KEY *key)
+	{
+#ifndef BF_PTR2
+	BF_LONG l,r;
+	const BF_LONG *p,*s;
+
+	p=key->P;
+	s= &(key->S[0]);
+	l=data[0];
+	r=data[1];
+
+	l^=p[0];
+	BF_ENC(r,l,s,p[ 1]);
+	BF_ENC(l,r,s,p[ 2]);
+	BF_ENC(r,l,s,p[ 3]);
+	BF_ENC(l,r,s,p[ 4]);
+	BF_ENC(r,l,s,p[ 5]);
+	BF_ENC(l,r,s,p[ 6]);
+	BF_ENC(r,l,s,p[ 7]);
+	BF_ENC(l,r,s,p[ 8]);
+	BF_ENC(r,l,s,p[ 9]);
+	BF_ENC(l,r,s,p[10]);
+	BF_ENC(r,l,s,p[11]);
+	BF_ENC(l,r,s,p[12]);
+	BF_ENC(r,l,s,p[13]);
+	BF_ENC(l,r,s,p[14]);
+	BF_ENC(r,l,s,p[15]);
+	BF_ENC(l,r,s,p[16]);
+#if BF_ROUNDS == 20
+	BF_ENC(r,l,s,p[17]);
+	BF_ENC(l,r,s,p[18]);
+	BF_ENC(r,l,s,p[19]);
+	BF_ENC(l,r,s,p[20]);
+#endif
+	r^=p[BF_ROUNDS+1];
+
+	data[1]=l&0xffffffffL;
+	data[0]=r&0xffffffffL;
+#else
+	BF_LONG l,r,t,*k;
+
+	l=data[0];
+	r=data[1];
+	k=(BF_LONG*)key;
+
+	l^=k[0];
+	BF_ENC(r,l,k, 1);
+	BF_ENC(l,r,k, 2);
+	BF_ENC(r,l,k, 3);
+	BF_ENC(l,r,k, 4);
+	BF_ENC(r,l,k, 5);
+	BF_ENC(l,r,k, 6);
+	BF_ENC(r,l,k, 7);
+	BF_ENC(l,r,k, 8);
+	BF_ENC(r,l,k, 9);
+	BF_ENC(l,r,k,10);
+	BF_ENC(r,l,k,11);
+	BF_ENC(l,r,k,12);
+	BF_ENC(r,l,k,13);
+	BF_ENC(l,r,k,14);
+	BF_ENC(r,l,k,15);
+	BF_ENC(l,r,k,16);
+#if BF_ROUNDS == 20
+	BF_ENC(r,l,k,17);
+	BF_ENC(l,r,k,18);
+	BF_ENC(r,l,k,19);
+	BF_ENC(l,r,k,20);
+#endif
+	r^=k[BF_ROUNDS+1];
+
+	data[1]=l&0xffffffffL;
+	data[0]=r&0xffffffffL;
+#endif
+	}
+
+#ifndef BF_DEFAULT_OPTIONS
+
+void BF_decrypt(BF_LONG *data, const BF_KEY *key)
+	{
+#ifndef BF_PTR2
+	BF_LONG l,r;
+	const BF_LONG *p,*s;
+
+	p=key->P;
+	s= &(key->S[0]);
+	l=data[0];
+	r=data[1];
+
+	l^=p[BF_ROUNDS+1];
+#if BF_ROUNDS == 20
+	BF_ENC(r,l,s,p[20]);
+	BF_ENC(l,r,s,p[19]);
+	BF_ENC(r,l,s,p[18]);
+	BF_ENC(l,r,s,p[17]);
+#endif
+	BF_ENC(r,l,s,p[16]);
+	BF_ENC(l,r,s,p[15]);
+	BF_ENC(r,l,s,p[14]);
+	BF_ENC(l,r,s,p[13]);
+	BF_ENC(r,l,s,p[12]);
+	BF_ENC(l,r,s,p[11]);
+	BF_ENC(r,l,s,p[10]);
+	BF_ENC(l,r,s,p[ 9]);
+	BF_ENC(r,l,s,p[ 8]);
+	BF_ENC(l,r,s,p[ 7]);
+	BF_ENC(r,l,s,p[ 6]);
+	BF_ENC(l,r,s,p[ 5]);
+	BF_ENC(r,l,s,p[ 4]);
+	BF_ENC(l,r,s,p[ 3]);
+	BF_ENC(r,l,s,p[ 2]);
+	BF_ENC(l,r,s,p[ 1]);
+	r^=p[0];
+
+	data[1]=l&0xffffffffL;
+	data[0]=r&0xffffffffL;
+#else
+	BF_LONG l,r,t,*k;
+
+	l=data[0];
+	r=data[1];
+	k=(BF_LONG *)key;
+
+	l^=k[BF_ROUNDS+1];
+#if BF_ROUNDS == 20
+	BF_ENC(r,l,k,20);
+	BF_ENC(l,r,k,19);
+	BF_ENC(r,l,k,18);
+	BF_ENC(l,r,k,17);
+#endif
+	BF_ENC(r,l,k,16);
+	BF_ENC(l,r,k,15);
+	BF_ENC(r,l,k,14);
+	BF_ENC(l,r,k,13);
+	BF_ENC(r,l,k,12);
+	BF_ENC(l,r,k,11);
+	BF_ENC(r,l,k,10);
+	BF_ENC(l,r,k, 9);
+	BF_ENC(r,l,k, 8);
+	BF_ENC(l,r,k, 7);
+	BF_ENC(r,l,k, 6);
+	BF_ENC(l,r,k, 5);
+	BF_ENC(r,l,k, 4);
+	BF_ENC(l,r,k, 3);
+	BF_ENC(r,l,k, 2);
+	BF_ENC(l,r,k, 1);
+	r^=k[0];
+
+	data[1]=l&0xffffffffL;
+	data[0]=r&0xffffffffL;
+#endif
+	}
+
+void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+	     const BF_KEY *schedule, unsigned char *ivec, int encrypt)
+	{
+	BF_LONG tin0,tin1;
+	BF_LONG tout0,tout1,xor0,xor1;
+	long l=length;
+	BF_LONG tin[2];
+
+	if (encrypt)
+		{
+		n2l(ivec,tout0);
+		n2l(ivec,tout1);
+		ivec-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			n2l(in,tin0);
+			n2l(in,tin1);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			BF_encrypt(tin,schedule);
+			tout0=tin[0];
+			tout1=tin[1];
+			l2n(tout0,out);
+			l2n(tout1,out);
+			}
+		if (l != -8)
+			{
+			n2ln(in,tin0,tin1,l+8);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			BF_encrypt(tin,schedule);
+			tout0=tin[0];
+			tout1=tin[1];
+			l2n(tout0,out);
+			l2n(tout1,out);
+			}
+		l2n(tout0,ivec);
+		l2n(tout1,ivec);
+		}
+	else
+		{
+		n2l(ivec,xor0);
+		n2l(ivec,xor1);
+		ivec-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			n2l(in,tin0);
+			n2l(in,tin1);
+			tin[0]=tin0;
+			tin[1]=tin1;
+			BF_decrypt(tin,schedule);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2n(tout0,out);
+			l2n(tout1,out);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		if (l != -8)
+			{
+			n2l(in,tin0);
+			n2l(in,tin1);
+			tin[0]=tin0;
+			tin[1]=tin1;
+			BF_decrypt(tin,schedule);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2nn(tout0,tout1,out,l+8);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		l2n(xor0,ivec);
+		l2n(xor1,ivec);
+		}
+	tin0=tin1=tout0=tout1=xor0=xor1=0;
+	tin[0]=tin[1]=0;
+	}
+
+#endif
diff --git a/crypto/libressl/crypto/bf/bf_locl.h b/crypto/libressl/crypto/bf/bf_locl.h
new file mode 100644
index 0000000000..5692de4cbb
--- /dev/null
+++ b/crypto/libressl/crypto/bf/bf_locl.h
@@ -0,0 +1,219 @@
+/* $OpenBSD$ */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BF_LOCL_H
+#define HEADER_BF_LOCL_H
+#include  /* BF_PTR, BF_PTR2 */
+
+#undef c2l
+#define c2l(c,l)	(l =((unsigned long)(*((c)++)))    , \
+			 l|=((unsigned long)(*((c)++)))<< 8L, \
+			 l|=((unsigned long)(*((c)++)))<<16L, \
+			 l|=((unsigned long)(*((c)++)))<<24L)
+
+/* NOTE - c is not incremented as per c2l */
+#undef c2ln
+#define c2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
+			case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
+			case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
+			case 5: l2|=((unsigned long)(*(--(c))));     \
+			case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
+			case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
+			case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
+			case 1: l1|=((unsigned long)(*(--(c))));     \
+				} \
+			}
+
+#undef l2c
+#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+#undef l2cn
+#define l2cn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
+				} \
+			}
+
+/* NOTE - c is not incremented as per n2l */
+#define n2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))    ; \
+			case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
+			case 6: l2|=((unsigned long)(*(--(c))))<<16; \
+			case 5: l2|=((unsigned long)(*(--(c))))<<24; \
+			case 4: l1 =((unsigned long)(*(--(c))))    ; \
+			case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
+			case 2: l1|=((unsigned long)(*(--(c))))<<16; \
+			case 1: l1|=((unsigned long)(*(--(c))))<<24; \
+				} \
+			}
+
+/* NOTE - c is not incremented as per l2n */
+#define l2nn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+				} \
+			}
+
+#undef n2l
+#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
+                         l|=((unsigned long)(*((c)++)))<<16L, \
+                         l|=((unsigned long)(*((c)++)))<< 8L, \
+                         l|=((unsigned long)(*((c)++))))
+
+#undef l2n
+#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)     )&0xff))
+
+/* This is actually a big endian algorithm, the most significant byte
+ * is used to lookup array 0 */
+
+#if defined(BF_PTR2)
+
+/*
+ * This is basically a special Intel version. Point is that Intel
+ * doesn't have many registers, but offers a reach choice of addressing
+ * modes. So we spare some registers by directly traversing BF_KEY
+ * structure and hiring the most decorated addressing mode. The code
+ * generated by EGCS is *perfectly* competitive with assembler
+ * implementation!
+ */
+#define BF_ENC(LL,R,KEY,Pi) (\
+	LL^=KEY[Pi], \
+	t=  KEY[BF_ROUNDS+2 +   0 + ((R>>24)&0xFF)], \
+	t+= KEY[BF_ROUNDS+2 + 256 + ((R>>16)&0xFF)], \
+	t^= KEY[BF_ROUNDS+2 + 512 + ((R>>8 )&0xFF)], \
+	t+= KEY[BF_ROUNDS+2 + 768 + ((R    )&0xFF)], \
+	LL^=t \
+	)
+
+#elif defined(BF_PTR)
+
+#ifndef BF_LONG_LOG2
+#define BF_LONG_LOG2  2       /* default to BF_LONG being 32 bits */
+#endif
+#define BF_M  (0xFF<>BF_i)&BF_M gets folded into a single instruction, namely
+ * rlwinm. So let'em double-check if their compiler does it.
+ */
+
+#define BF_ENC(LL,R,S,P) ( \
+	LL^=P, \
+	LL^= (((*(BF_LONG *)((unsigned char *)&(S[  0])+((R>>BF_0)&BF_M))+ \
+		*(BF_LONG *)((unsigned char *)&(S[256])+((R>>BF_1)&BF_M)))^ \
+		*(BF_LONG *)((unsigned char *)&(S[512])+((R>>BF_2)&BF_M)))+ \
+		*(BF_LONG *)((unsigned char *)&(S[768])+((R<>24)&0xff)] + \
+		S[0x0100+((int)(R>>16)&0xff)])^ \
+		S[0x0200+((int)(R>> 8)&0xff)])+ \
+		S[0x0300+((int)(R    )&0xff)])&0xffffffffL \
+	)
+#endif
+
+#endif
diff --git a/crypto/libressl/crypto/bf/bf_ofb64.c b/crypto/libressl/crypto/bf/bf_ofb64.c
new file mode 100644
index 0000000000..a76dd92093
--- /dev/null
+++ b/crypto/libressl/crypto/bf/bf_ofb64.c
@@ -0,0 +1,110 @@
+/* $OpenBSD: bf_ofb64.c,v 1.4 2014/06/12 15:49:28 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include "bf_locl.h"
+
+/* The input and output encrypted as though 64bit ofb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, long length,
+	     const BF_KEY *schedule, unsigned char *ivec, int *num)
+	{
+	BF_LONG v0,v1,t;
+	int n= *num;
+	long l=length;
+	unsigned char d[8];
+	char *dp;
+	BF_LONG ti[2];
+	unsigned char *iv;
+	int save=0;
+
+	iv=(unsigned char *)ivec;
+	n2l(iv,v0);
+	n2l(iv,v1);
+	ti[0]=v0;
+	ti[1]=v1;
+	dp=(char *)d;
+	l2n(v0,dp);
+	l2n(v1,dp);
+	while (l--)
+		{
+		if (n == 0)
+			{
+			BF_encrypt((BF_LONG *)ti,schedule);
+			dp=(char *)d;
+			t=ti[0]; l2n(t,dp);
+			t=ti[1]; l2n(t,dp);
+			save++;
+			}
+		*(out++)= *(in++)^d[n];
+		n=(n+1)&0x07;
+		}
+	if (save)
+		{
+		v0=ti[0];
+		v1=ti[1];
+		iv=(unsigned char *)ivec;
+		l2n(v0,iv);
+		l2n(v1,iv);
+		}
+	t=v0=v1=ti[0]=ti[1]=0;
+	*num=n;
+	}
+
diff --git a/crypto/libressl/crypto/bf/bf_pi.h b/crypto/libressl/crypto/bf/bf_pi.h
new file mode 100644
index 0000000000..c4bfad7fca
--- /dev/null
+++ b/crypto/libressl/crypto/bf/bf_pi.h
@@ -0,0 +1,325 @@
+/* $OpenBSD$ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+static const BF_KEY bf_init= {
+	{
+	0x243f6a88L, 0x85a308d3L, 0x13198a2eL, 0x03707344L,
+	0xa4093822L, 0x299f31d0L, 0x082efa98L, 0xec4e6c89L,
+	0x452821e6L, 0x38d01377L, 0xbe5466cfL, 0x34e90c6cL,
+	0xc0ac29b7L, 0xc97c50ddL, 0x3f84d5b5L, 0xb5470917L,
+	0x9216d5d9L, 0x8979fb1b
+	},{
+	0xd1310ba6L, 0x98dfb5acL, 0x2ffd72dbL, 0xd01adfb7L, 
+	0xb8e1afedL, 0x6a267e96L, 0xba7c9045L, 0xf12c7f99L, 
+	0x24a19947L, 0xb3916cf7L, 0x0801f2e2L, 0x858efc16L, 
+	0x636920d8L, 0x71574e69L, 0xa458fea3L, 0xf4933d7eL, 
+	0x0d95748fL, 0x728eb658L, 0x718bcd58L, 0x82154aeeL, 
+	0x7b54a41dL, 0xc25a59b5L, 0x9c30d539L, 0x2af26013L, 
+	0xc5d1b023L, 0x286085f0L, 0xca417918L, 0xb8db38efL, 
+	0x8e79dcb0L, 0x603a180eL, 0x6c9e0e8bL, 0xb01e8a3eL, 
+	0xd71577c1L, 0xbd314b27L, 0x78af2fdaL, 0x55605c60L, 
+	0xe65525f3L, 0xaa55ab94L, 0x57489862L, 0x63e81440L, 
+	0x55ca396aL, 0x2aab10b6L, 0xb4cc5c34L, 0x1141e8ceL, 
+	0xa15486afL, 0x7c72e993L, 0xb3ee1411L, 0x636fbc2aL, 
+	0x2ba9c55dL, 0x741831f6L, 0xce5c3e16L, 0x9b87931eL, 
+	0xafd6ba33L, 0x6c24cf5cL, 0x7a325381L, 0x28958677L, 
+	0x3b8f4898L, 0x6b4bb9afL, 0xc4bfe81bL, 0x66282193L, 
+	0x61d809ccL, 0xfb21a991L, 0x487cac60L, 0x5dec8032L, 
+	0xef845d5dL, 0xe98575b1L, 0xdc262302L, 0xeb651b88L, 
+	0x23893e81L, 0xd396acc5L, 0x0f6d6ff3L, 0x83f44239L, 
+	0x2e0b4482L, 0xa4842004L, 0x69c8f04aL, 0x9e1f9b5eL, 
+	0x21c66842L, 0xf6e96c9aL, 0x670c9c61L, 0xabd388f0L, 
+	0x6a51a0d2L, 0xd8542f68L, 0x960fa728L, 0xab5133a3L, 
+	0x6eef0b6cL, 0x137a3be4L, 0xba3bf050L, 0x7efb2a98L, 
+	0xa1f1651dL, 0x39af0176L, 0x66ca593eL, 0x82430e88L, 
+	0x8cee8619L, 0x456f9fb4L, 0x7d84a5c3L, 0x3b8b5ebeL, 
+	0xe06f75d8L, 0x85c12073L, 0x401a449fL, 0x56c16aa6L, 
+	0x4ed3aa62L, 0x363f7706L, 0x1bfedf72L, 0x429b023dL, 
+	0x37d0d724L, 0xd00a1248L, 0xdb0fead3L, 0x49f1c09bL, 
+	0x075372c9L, 0x80991b7bL, 0x25d479d8L, 0xf6e8def7L, 
+	0xe3fe501aL, 0xb6794c3bL, 0x976ce0bdL, 0x04c006baL, 
+	0xc1a94fb6L, 0x409f60c4L, 0x5e5c9ec2L, 0x196a2463L, 
+	0x68fb6fafL, 0x3e6c53b5L, 0x1339b2ebL, 0x3b52ec6fL, 
+	0x6dfc511fL, 0x9b30952cL, 0xcc814544L, 0xaf5ebd09L, 
+	0xbee3d004L, 0xde334afdL, 0x660f2807L, 0x192e4bb3L, 
+	0xc0cba857L, 0x45c8740fL, 0xd20b5f39L, 0xb9d3fbdbL, 
+	0x5579c0bdL, 0x1a60320aL, 0xd6a100c6L, 0x402c7279L, 
+	0x679f25feL, 0xfb1fa3ccL, 0x8ea5e9f8L, 0xdb3222f8L, 
+	0x3c7516dfL, 0xfd616b15L, 0x2f501ec8L, 0xad0552abL, 
+	0x323db5faL, 0xfd238760L, 0x53317b48L, 0x3e00df82L, 
+	0x9e5c57bbL, 0xca6f8ca0L, 0x1a87562eL, 0xdf1769dbL, 
+	0xd542a8f6L, 0x287effc3L, 0xac6732c6L, 0x8c4f5573L, 
+	0x695b27b0L, 0xbbca58c8L, 0xe1ffa35dL, 0xb8f011a0L, 
+	0x10fa3d98L, 0xfd2183b8L, 0x4afcb56cL, 0x2dd1d35bL, 
+	0x9a53e479L, 0xb6f84565L, 0xd28e49bcL, 0x4bfb9790L, 
+	0xe1ddf2daL, 0xa4cb7e33L, 0x62fb1341L, 0xcee4c6e8L, 
+	0xef20cadaL, 0x36774c01L, 0xd07e9efeL, 0x2bf11fb4L, 
+	0x95dbda4dL, 0xae909198L, 0xeaad8e71L, 0x6b93d5a0L, 
+	0xd08ed1d0L, 0xafc725e0L, 0x8e3c5b2fL, 0x8e7594b7L, 
+	0x8ff6e2fbL, 0xf2122b64L, 0x8888b812L, 0x900df01cL, 
+	0x4fad5ea0L, 0x688fc31cL, 0xd1cff191L, 0xb3a8c1adL, 
+	0x2f2f2218L, 0xbe0e1777L, 0xea752dfeL, 0x8b021fa1L, 
+	0xe5a0cc0fL, 0xb56f74e8L, 0x18acf3d6L, 0xce89e299L, 
+	0xb4a84fe0L, 0xfd13e0b7L, 0x7cc43b81L, 0xd2ada8d9L, 
+	0x165fa266L, 0x80957705L, 0x93cc7314L, 0x211a1477L, 
+	0xe6ad2065L, 0x77b5fa86L, 0xc75442f5L, 0xfb9d35cfL, 
+	0xebcdaf0cL, 0x7b3e89a0L, 0xd6411bd3L, 0xae1e7e49L, 
+	0x00250e2dL, 0x2071b35eL, 0x226800bbL, 0x57b8e0afL, 
+	0x2464369bL, 0xf009b91eL, 0x5563911dL, 0x59dfa6aaL, 
+	0x78c14389L, 0xd95a537fL, 0x207d5ba2L, 0x02e5b9c5L, 
+	0x83260376L, 0x6295cfa9L, 0x11c81968L, 0x4e734a41L, 
+	0xb3472dcaL, 0x7b14a94aL, 0x1b510052L, 0x9a532915L, 
+	0xd60f573fL, 0xbc9bc6e4L, 0x2b60a476L, 0x81e67400L, 
+	0x08ba6fb5L, 0x571be91fL, 0xf296ec6bL, 0x2a0dd915L, 
+	0xb6636521L, 0xe7b9f9b6L, 0xff34052eL, 0xc5855664L, 
+	0x53b02d5dL, 0xa99f8fa1L, 0x08ba4799L, 0x6e85076aL, 
+	0x4b7a70e9L, 0xb5b32944L, 0xdb75092eL, 0xc4192623L, 
+	0xad6ea6b0L, 0x49a7df7dL, 0x9cee60b8L, 0x8fedb266L, 
+	0xecaa8c71L, 0x699a17ffL, 0x5664526cL, 0xc2b19ee1L, 
+	0x193602a5L, 0x75094c29L, 0xa0591340L, 0xe4183a3eL, 
+	0x3f54989aL, 0x5b429d65L, 0x6b8fe4d6L, 0x99f73fd6L, 
+	0xa1d29c07L, 0xefe830f5L, 0x4d2d38e6L, 0xf0255dc1L, 
+	0x4cdd2086L, 0x8470eb26L, 0x6382e9c6L, 0x021ecc5eL, 
+	0x09686b3fL, 0x3ebaefc9L, 0x3c971814L, 0x6b6a70a1L, 
+	0x687f3584L, 0x52a0e286L, 0xb79c5305L, 0xaa500737L, 
+	0x3e07841cL, 0x7fdeae5cL, 0x8e7d44ecL, 0x5716f2b8L, 
+	0xb03ada37L, 0xf0500c0dL, 0xf01c1f04L, 0x0200b3ffL, 
+	0xae0cf51aL, 0x3cb574b2L, 0x25837a58L, 0xdc0921bdL, 
+	0xd19113f9L, 0x7ca92ff6L, 0x94324773L, 0x22f54701L, 
+	0x3ae5e581L, 0x37c2dadcL, 0xc8b57634L, 0x9af3dda7L, 
+	0xa9446146L, 0x0fd0030eL, 0xecc8c73eL, 0xa4751e41L, 
+	0xe238cd99L, 0x3bea0e2fL, 0x3280bba1L, 0x183eb331L, 
+	0x4e548b38L, 0x4f6db908L, 0x6f420d03L, 0xf60a04bfL, 
+	0x2cb81290L, 0x24977c79L, 0x5679b072L, 0xbcaf89afL, 
+	0xde9a771fL, 0xd9930810L, 0xb38bae12L, 0xdccf3f2eL, 
+	0x5512721fL, 0x2e6b7124L, 0x501adde6L, 0x9f84cd87L, 
+	0x7a584718L, 0x7408da17L, 0xbc9f9abcL, 0xe94b7d8cL, 
+	0xec7aec3aL, 0xdb851dfaL, 0x63094366L, 0xc464c3d2L, 
+	0xef1c1847L, 0x3215d908L, 0xdd433b37L, 0x24c2ba16L, 
+	0x12a14d43L, 0x2a65c451L, 0x50940002L, 0x133ae4ddL, 
+	0x71dff89eL, 0x10314e55L, 0x81ac77d6L, 0x5f11199bL, 
+	0x043556f1L, 0xd7a3c76bL, 0x3c11183bL, 0x5924a509L, 
+	0xf28fe6edL, 0x97f1fbfaL, 0x9ebabf2cL, 0x1e153c6eL, 
+	0x86e34570L, 0xeae96fb1L, 0x860e5e0aL, 0x5a3e2ab3L, 
+	0x771fe71cL, 0x4e3d06faL, 0x2965dcb9L, 0x99e71d0fL, 
+	0x803e89d6L, 0x5266c825L, 0x2e4cc978L, 0x9c10b36aL, 
+	0xc6150ebaL, 0x94e2ea78L, 0xa5fc3c53L, 0x1e0a2df4L, 
+	0xf2f74ea7L, 0x361d2b3dL, 0x1939260fL, 0x19c27960L, 
+	0x5223a708L, 0xf71312b6L, 0xebadfe6eL, 0xeac31f66L, 
+	0xe3bc4595L, 0xa67bc883L, 0xb17f37d1L, 0x018cff28L, 
+	0xc332ddefL, 0xbe6c5aa5L, 0x65582185L, 0x68ab9802L, 
+	0xeecea50fL, 0xdb2f953bL, 0x2aef7dadL, 0x5b6e2f84L, 
+	0x1521b628L, 0x29076170L, 0xecdd4775L, 0x619f1510L, 
+	0x13cca830L, 0xeb61bd96L, 0x0334fe1eL, 0xaa0363cfL, 
+	0xb5735c90L, 0x4c70a239L, 0xd59e9e0bL, 0xcbaade14L, 
+	0xeecc86bcL, 0x60622ca7L, 0x9cab5cabL, 0xb2f3846eL, 
+	0x648b1eafL, 0x19bdf0caL, 0xa02369b9L, 0x655abb50L, 
+	0x40685a32L, 0x3c2ab4b3L, 0x319ee9d5L, 0xc021b8f7L, 
+	0x9b540b19L, 0x875fa099L, 0x95f7997eL, 0x623d7da8L, 
+	0xf837889aL, 0x97e32d77L, 0x11ed935fL, 0x16681281L, 
+	0x0e358829L, 0xc7e61fd6L, 0x96dedfa1L, 0x7858ba99L, 
+	0x57f584a5L, 0x1b227263L, 0x9b83c3ffL, 0x1ac24696L, 
+	0xcdb30aebL, 0x532e3054L, 0x8fd948e4L, 0x6dbc3128L, 
+	0x58ebf2efL, 0x34c6ffeaL, 0xfe28ed61L, 0xee7c3c73L, 
+	0x5d4a14d9L, 0xe864b7e3L, 0x42105d14L, 0x203e13e0L, 
+	0x45eee2b6L, 0xa3aaabeaL, 0xdb6c4f15L, 0xfacb4fd0L, 
+	0xc742f442L, 0xef6abbb5L, 0x654f3b1dL, 0x41cd2105L, 
+	0xd81e799eL, 0x86854dc7L, 0xe44b476aL, 0x3d816250L, 
+	0xcf62a1f2L, 0x5b8d2646L, 0xfc8883a0L, 0xc1c7b6a3L, 
+	0x7f1524c3L, 0x69cb7492L, 0x47848a0bL, 0x5692b285L, 
+	0x095bbf00L, 0xad19489dL, 0x1462b174L, 0x23820e00L, 
+	0x58428d2aL, 0x0c55f5eaL, 0x1dadf43eL, 0x233f7061L, 
+	0x3372f092L, 0x8d937e41L, 0xd65fecf1L, 0x6c223bdbL, 
+	0x7cde3759L, 0xcbee7460L, 0x4085f2a7L, 0xce77326eL, 
+	0xa6078084L, 0x19f8509eL, 0xe8efd855L, 0x61d99735L, 
+	0xa969a7aaL, 0xc50c06c2L, 0x5a04abfcL, 0x800bcadcL, 
+	0x9e447a2eL, 0xc3453484L, 0xfdd56705L, 0x0e1e9ec9L, 
+	0xdb73dbd3L, 0x105588cdL, 0x675fda79L, 0xe3674340L, 
+	0xc5c43465L, 0x713e38d8L, 0x3d28f89eL, 0xf16dff20L, 
+	0x153e21e7L, 0x8fb03d4aL, 0xe6e39f2bL, 0xdb83adf7L, 
+	0xe93d5a68L, 0x948140f7L, 0xf64c261cL, 0x94692934L, 
+	0x411520f7L, 0x7602d4f7L, 0xbcf46b2eL, 0xd4a20068L, 
+	0xd4082471L, 0x3320f46aL, 0x43b7d4b7L, 0x500061afL, 
+	0x1e39f62eL, 0x97244546L, 0x14214f74L, 0xbf8b8840L, 
+	0x4d95fc1dL, 0x96b591afL, 0x70f4ddd3L, 0x66a02f45L, 
+	0xbfbc09ecL, 0x03bd9785L, 0x7fac6dd0L, 0x31cb8504L, 
+	0x96eb27b3L, 0x55fd3941L, 0xda2547e6L, 0xabca0a9aL, 
+	0x28507825L, 0x530429f4L, 0x0a2c86daL, 0xe9b66dfbL, 
+	0x68dc1462L, 0xd7486900L, 0x680ec0a4L, 0x27a18deeL, 
+	0x4f3ffea2L, 0xe887ad8cL, 0xb58ce006L, 0x7af4d6b6L, 
+	0xaace1e7cL, 0xd3375fecL, 0xce78a399L, 0x406b2a42L, 
+	0x20fe9e35L, 0xd9f385b9L, 0xee39d7abL, 0x3b124e8bL, 
+	0x1dc9faf7L, 0x4b6d1856L, 0x26a36631L, 0xeae397b2L, 
+	0x3a6efa74L, 0xdd5b4332L, 0x6841e7f7L, 0xca7820fbL, 
+	0xfb0af54eL, 0xd8feb397L, 0x454056acL, 0xba489527L, 
+	0x55533a3aL, 0x20838d87L, 0xfe6ba9b7L, 0xd096954bL, 
+	0x55a867bcL, 0xa1159a58L, 0xcca92963L, 0x99e1db33L, 
+	0xa62a4a56L, 0x3f3125f9L, 0x5ef47e1cL, 0x9029317cL, 
+	0xfdf8e802L, 0x04272f70L, 0x80bb155cL, 0x05282ce3L, 
+	0x95c11548L, 0xe4c66d22L, 0x48c1133fL, 0xc70f86dcL, 
+	0x07f9c9eeL, 0x41041f0fL, 0x404779a4L, 0x5d886e17L, 
+	0x325f51ebL, 0xd59bc0d1L, 0xf2bcc18fL, 0x41113564L, 
+	0x257b7834L, 0x602a9c60L, 0xdff8e8a3L, 0x1f636c1bL, 
+	0x0e12b4c2L, 0x02e1329eL, 0xaf664fd1L, 0xcad18115L, 
+	0x6b2395e0L, 0x333e92e1L, 0x3b240b62L, 0xeebeb922L, 
+	0x85b2a20eL, 0xe6ba0d99L, 0xde720c8cL, 0x2da2f728L, 
+	0xd0127845L, 0x95b794fdL, 0x647d0862L, 0xe7ccf5f0L, 
+	0x5449a36fL, 0x877d48faL, 0xc39dfd27L, 0xf33e8d1eL, 
+	0x0a476341L, 0x992eff74L, 0x3a6f6eabL, 0xf4f8fd37L, 
+	0xa812dc60L, 0xa1ebddf8L, 0x991be14cL, 0xdb6e6b0dL, 
+	0xc67b5510L, 0x6d672c37L, 0x2765d43bL, 0xdcd0e804L, 
+	0xf1290dc7L, 0xcc00ffa3L, 0xb5390f92L, 0x690fed0bL, 
+	0x667b9ffbL, 0xcedb7d9cL, 0xa091cf0bL, 0xd9155ea3L, 
+	0xbb132f88L, 0x515bad24L, 0x7b9479bfL, 0x763bd6ebL, 
+	0x37392eb3L, 0xcc115979L, 0x8026e297L, 0xf42e312dL, 
+	0x6842ada7L, 0xc66a2b3bL, 0x12754cccL, 0x782ef11cL, 
+	0x6a124237L, 0xb79251e7L, 0x06a1bbe6L, 0x4bfb6350L, 
+	0x1a6b1018L, 0x11caedfaL, 0x3d25bdd8L, 0xe2e1c3c9L, 
+	0x44421659L, 0x0a121386L, 0xd90cec6eL, 0xd5abea2aL, 
+	0x64af674eL, 0xda86a85fL, 0xbebfe988L, 0x64e4c3feL, 
+	0x9dbc8057L, 0xf0f7c086L, 0x60787bf8L, 0x6003604dL, 
+	0xd1fd8346L, 0xf6381fb0L, 0x7745ae04L, 0xd736fcccL, 
+	0x83426b33L, 0xf01eab71L, 0xb0804187L, 0x3c005e5fL, 
+	0x77a057beL, 0xbde8ae24L, 0x55464299L, 0xbf582e61L, 
+	0x4e58f48fL, 0xf2ddfda2L, 0xf474ef38L, 0x8789bdc2L, 
+	0x5366f9c3L, 0xc8b38e74L, 0xb475f255L, 0x46fcd9b9L, 
+	0x7aeb2661L, 0x8b1ddf84L, 0x846a0e79L, 0x915f95e2L, 
+	0x466e598eL, 0x20b45770L, 0x8cd55591L, 0xc902de4cL, 
+	0xb90bace1L, 0xbb8205d0L, 0x11a86248L, 0x7574a99eL, 
+	0xb77f19b6L, 0xe0a9dc09L, 0x662d09a1L, 0xc4324633L, 
+	0xe85a1f02L, 0x09f0be8cL, 0x4a99a025L, 0x1d6efe10L, 
+	0x1ab93d1dL, 0x0ba5a4dfL, 0xa186f20fL, 0x2868f169L, 
+	0xdcb7da83L, 0x573906feL, 0xa1e2ce9bL, 0x4fcd7f52L, 
+	0x50115e01L, 0xa70683faL, 0xa002b5c4L, 0x0de6d027L, 
+	0x9af88c27L, 0x773f8641L, 0xc3604c06L, 0x61a806b5L, 
+	0xf0177a28L, 0xc0f586e0L, 0x006058aaL, 0x30dc7d62L, 
+	0x11e69ed7L, 0x2338ea63L, 0x53c2dd94L, 0xc2c21634L, 
+	0xbbcbee56L, 0x90bcb6deL, 0xebfc7da1L, 0xce591d76L, 
+	0x6f05e409L, 0x4b7c0188L, 0x39720a3dL, 0x7c927c24L, 
+	0x86e3725fL, 0x724d9db9L, 0x1ac15bb4L, 0xd39eb8fcL, 
+	0xed545578L, 0x08fca5b5L, 0xd83d7cd3L, 0x4dad0fc4L, 
+	0x1e50ef5eL, 0xb161e6f8L, 0xa28514d9L, 0x6c51133cL, 
+	0x6fd5c7e7L, 0x56e14ec4L, 0x362abfceL, 0xddc6c837L, 
+	0xd79a3234L, 0x92638212L, 0x670efa8eL, 0x406000e0L, 
+	0x3a39ce37L, 0xd3faf5cfL, 0xabc27737L, 0x5ac52d1bL, 
+	0x5cb0679eL, 0x4fa33742L, 0xd3822740L, 0x99bc9bbeL, 
+	0xd5118e9dL, 0xbf0f7315L, 0xd62d1c7eL, 0xc700c47bL, 
+	0xb78c1b6bL, 0x21a19045L, 0xb26eb1beL, 0x6a366eb4L, 
+	0x5748ab2fL, 0xbc946e79L, 0xc6a376d2L, 0x6549c2c8L, 
+	0x530ff8eeL, 0x468dde7dL, 0xd5730a1dL, 0x4cd04dc6L, 
+	0x2939bbdbL, 0xa9ba4650L, 0xac9526e8L, 0xbe5ee304L, 
+	0xa1fad5f0L, 0x6a2d519aL, 0x63ef8ce2L, 0x9a86ee22L, 
+	0xc089c2b8L, 0x43242ef6L, 0xa51e03aaL, 0x9cf2d0a4L, 
+	0x83c061baL, 0x9be96a4dL, 0x8fe51550L, 0xba645bd6L, 
+	0x2826a2f9L, 0xa73a3ae1L, 0x4ba99586L, 0xef5562e9L, 
+	0xc72fefd3L, 0xf752f7daL, 0x3f046f69L, 0x77fa0a59L, 
+	0x80e4a915L, 0x87b08601L, 0x9b09e6adL, 0x3b3ee593L, 
+	0xe990fd5aL, 0x9e34d797L, 0x2cf0b7d9L, 0x022b8b51L, 
+	0x96d5ac3aL, 0x017da67dL, 0xd1cf3ed6L, 0x7c7d2d28L, 
+	0x1f9f25cfL, 0xadf2b89bL, 0x5ad6b472L, 0x5a88f54cL, 
+	0xe029ac71L, 0xe019a5e6L, 0x47b0acfdL, 0xed93fa9bL, 
+	0xe8d3c48dL, 0x283b57ccL, 0xf8d56629L, 0x79132e28L, 
+	0x785f0191L, 0xed756055L, 0xf7960e44L, 0xe3d35e8cL, 
+	0x15056dd4L, 0x88f46dbaL, 0x03a16125L, 0x0564f0bdL, 
+	0xc3eb9e15L, 0x3c9057a2L, 0x97271aecL, 0xa93a072aL, 
+	0x1b3f6d9bL, 0x1e6321f5L, 0xf59c66fbL, 0x26dcf319L, 
+	0x7533d928L, 0xb155fdf5L, 0x03563482L, 0x8aba3cbbL, 
+	0x28517711L, 0xc20ad9f8L, 0xabcc5167L, 0xccad925fL, 
+	0x4de81751L, 0x3830dc8eL, 0x379d5862L, 0x9320f991L, 
+	0xea7a90c2L, 0xfb3e7bceL, 0x5121ce64L, 0x774fbe32L, 
+	0xa8b6e37eL, 0xc3293d46L, 0x48de5369L, 0x6413e680L, 
+	0xa2ae0810L, 0xdd6db224L, 0x69852dfdL, 0x09072166L, 
+	0xb39a460aL, 0x6445c0ddL, 0x586cdecfL, 0x1c20c8aeL, 
+	0x5bbef7ddL, 0x1b588d40L, 0xccd2017fL, 0x6bb4e3bbL, 
+	0xdda26a7eL, 0x3a59ff45L, 0x3e350a44L, 0xbcb4cdd5L, 
+	0x72eacea8L, 0xfa6484bbL, 0x8d6612aeL, 0xbf3c6f47L, 
+	0xd29be463L, 0x542f5d9eL, 0xaec2771bL, 0xf64e6370L, 
+	0x740e0d8dL, 0xe75b1357L, 0xf8721671L, 0xaf537d5dL, 
+	0x4040cb08L, 0x4eb4e2ccL, 0x34d2466aL, 0x0115af84L, 
+	0xe1b00428L, 0x95983a1dL, 0x06b89fb4L, 0xce6ea048L, 
+	0x6f3f3b82L, 0x3520ab82L, 0x011a1d4bL, 0x277227f8L, 
+	0x611560b1L, 0xe7933fdcL, 0xbb3a792bL, 0x344525bdL, 
+	0xa08839e1L, 0x51ce794bL, 0x2f32c9b7L, 0xa01fbac9L, 
+	0xe01cc87eL, 0xbcc7d1f6L, 0xcf0111c3L, 0xa1e8aac7L, 
+	0x1a908749L, 0xd44fbd9aL, 0xd0dadecbL, 0xd50ada38L, 
+	0x0339c32aL, 0xc6913667L, 0x8df9317cL, 0xe0b12b4fL, 
+	0xf79e59b7L, 0x43f5bb3aL, 0xf2d519ffL, 0x27d9459cL, 
+	0xbf97222cL, 0x15e6fc2aL, 0x0f91fc71L, 0x9b941525L, 
+	0xfae59361L, 0xceb69cebL, 0xc2a86459L, 0x12baa8d1L, 
+	0xb6c1075eL, 0xe3056a0cL, 0x10d25065L, 0xcb03a442L, 
+	0xe0ec6e0eL, 0x1698db3bL, 0x4c98a0beL, 0x3278e964L, 
+	0x9f1f9532L, 0xe0d392dfL, 0xd3a0342bL, 0x8971f21eL, 
+	0x1b0a7441L, 0x4ba3348cL, 0xc5be7120L, 0xc37632d8L, 
+	0xdf359f8dL, 0x9b992f2eL, 0xe60b6f47L, 0x0fe3f11dL, 
+	0xe54cda54L, 0x1edad891L, 0xce6279cfL, 0xcd3e7e6fL, 
+	0x1618b166L, 0xfd2c1d05L, 0x848fd2c5L, 0xf6fb2299L, 
+	0xf523f357L, 0xa6327623L, 0x93a83531L, 0x56cccd02L, 
+	0xacf08162L, 0x5a75ebb5L, 0x6e163697L, 0x88d273ccL, 
+	0xde966292L, 0x81b949d0L, 0x4c50901bL, 0x71c65614L, 
+	0xe6c6c7bdL, 0x327a140aL, 0x45e1d006L, 0xc3f27b9aL, 
+	0xc9aa53fdL, 0x62a80f00L, 0xbb25bfe2L, 0x35bdd2f6L, 
+	0x71126905L, 0xb2040222L, 0xb6cbcf7cL, 0xcd769c2bL, 
+	0x53113ec0L, 0x1640e3d3L, 0x38abbd60L, 0x2547adf0L, 
+	0xba38209cL, 0xf746ce76L, 0x77afa1c5L, 0x20756060L, 
+	0x85cbfe4eL, 0x8ae88dd8L, 0x7aaaf9b0L, 0x4cf9aa7eL, 
+	0x1948c25cL, 0x02fb8a8cL, 0x01c36ae4L, 0xd6ebe1f9L, 
+	0x90d4f869L, 0xa65cdea0L, 0x3f09252dL, 0xc208e69fL, 
+	0xb74e6132L, 0xce77e25bL, 0x578fdfe3L, 0x3ac372e6L, 
+	}
+	};
+
diff --git a/crypto/libressl/crypto/bf/bf_skey.c b/crypto/libressl/crypto/bf/bf_skey.c
new file mode 100644
index 0000000000..94f0316f56
--- /dev/null
+++ b/crypto/libressl/crypto/bf/bf_skey.c
@@ -0,0 +1,117 @@
+/* $OpenBSD$ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include "bf_locl.h"
+#include "bf_pi.h"
+
+void BF_set_key(BF_KEY *key, int len, const unsigned char *data)
+	{
+	int i;
+	BF_LONG *p,ri,in[2];
+	const unsigned char *d,*end;
+
+
+	memcpy(key,&bf_init,sizeof(BF_KEY));
+	p=key->P;
+
+	if (len > ((BF_ROUNDS+2)*4)) len=(BF_ROUNDS+2)*4;
+
+	d=data;
+	end= &(data[len]);
+	for (i=0; i<(BF_ROUNDS+2); i++)
+		{
+		ri= *(d++);
+		if (d >= end) d=data;
+
+		ri<<=8;
+		ri|= *(d++);
+		if (d >= end) d=data;
+
+		ri<<=8;
+		ri|= *(d++);
+		if (d >= end) d=data;
+
+		ri<<=8;
+		ri|= *(d++);
+		if (d >= end) d=data;
+
+		p[i]^=ri;
+		}
+
+	in[0]=0L;
+	in[1]=0L;
+	for (i=0; i<(BF_ROUNDS+2); i+=2)
+		{
+		BF_encrypt(in,key);
+		p[i  ]=in[0];
+		p[i+1]=in[1];
+		}
+
+	p=key->S;
+	for (i=0; i<4*256; i+=2)
+		{
+		BF_encrypt(in,key);
+		p[i  ]=in[0];
+		p[i+1]=in[1];
+		}
+	}
+
diff --git a/crypto/libressl/crypto/bio/b_dump.c b/crypto/libressl/crypto/bio/b_dump.c
new file mode 100644
index 0000000000..628d811388
--- /dev/null
+++ b/crypto/libressl/crypto/bio/b_dump.c
@@ -0,0 +1,182 @@
+/* $OpenBSD: b_dump.c,v 1.20 2014/11/11 19:26:12 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/*
+ * Stolen from tjh's ssl/ssl_trc.c stuff.
+ */
+
+#include 
+#include 
+
+#include 
+
+#define TRUNCATE
+#define DUMP_WIDTH	16
+#define DUMP_WIDTH_LESS_INDENT(i) (DUMP_WIDTH - ((i - (i > 6 ? 6 : i) + 3) / 4))
+
+int
+BIO_dump_cb(int (*cb)(const void *data, size_t len, void *u),
+    void *u, const char *s, int len)
+{
+	return BIO_dump_indent_cb(cb, u, s, len, 0);
+}
+
+int
+BIO_dump_indent_cb(int (*cb)(const void *data, size_t len, void *u),
+    void *u, const char *s, int len, int indent)
+{
+	int ret = 0;
+	char buf[288 + 1], tmp[20], str[128 + 1];
+	int i, j, rows, trc;
+	unsigned char ch;
+	int dump_width;
+
+	trc = 0;
+
+#ifdef TRUNCATE
+	for (; (len > 0) && ((s[len - 1] == ' ') || (s[len - 1] == '\0')); len--)
+		trc++;
+#endif
+
+	if (indent < 0)
+		indent = 0;
+	if (indent) {
+		if (indent > 128)
+			indent = 128;
+		memset(str, ' ', indent);
+	}
+	str[indent] = '\0';
+
+	dump_width = DUMP_WIDTH_LESS_INDENT(indent);
+	rows = (len / dump_width);
+	if ((rows * dump_width) < len)
+		rows++;
+	for (i = 0; i < rows; i++) {
+		strlcpy(buf, str, sizeof buf);
+		snprintf(tmp, sizeof tmp, "%04x - ", i*dump_width);
+		strlcat(buf, tmp, sizeof buf);
+		for (j = 0; j < dump_width; j++) {
+			if (((i*dump_width) + j) >= len) {
+				strlcat(buf, "   ", sizeof buf);
+			} else {
+				ch = ((unsigned char)*(s + i*dump_width + j)) & 0xff;
+				snprintf(tmp, sizeof tmp, "%02x%c", ch,
+				    j == 7 ? '-' : ' ');
+				strlcat(buf, tmp, sizeof buf);
+			}
+		}
+		strlcat(buf, "  ", sizeof buf);
+		for (j = 0; j < dump_width; j++) {
+			if (((i*dump_width) + j) >= len)
+				break;
+			ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff;
+			snprintf(tmp, sizeof tmp, "%c",
+			    ((ch >= ' ') && (ch <= '~')) ? ch : '.');
+			strlcat(buf, tmp, sizeof buf);
+		}
+		strlcat(buf, "\n", sizeof buf);
+		/* if this is the last call then update the ddt_dump thing so
+		 * that we will move the selection point in the debug window
+		 */
+		ret += cb((void *)buf, strlen(buf), u);
+	}
+#ifdef TRUNCATE
+	if (trc > 0) {
+		snprintf(buf, sizeof buf, "%s%04x - \n",
+		    str, len + trc);
+		ret += cb((void *)buf, strlen(buf), u);
+	}
+#endif
+	return (ret);
+}
+
+static int
+write_fp(const void *data, size_t len, void *fp)
+{
+	return fwrite(data, 1, len, fp);
+}
+
+int
+BIO_dump_fp(FILE *fp, const char *s, int len)
+{
+	return BIO_dump_cb(write_fp, fp, s, len);
+}
+
+int
+BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent)
+{
+	return BIO_dump_indent_cb(write_fp, fp, s, len, indent);
+}
+
+static int
+write_bio(const void *data, size_t len, void *bp)
+{
+	return BIO_write((BIO *)bp, (const char *)data, len);
+}
+
+int
+BIO_dump(BIO *bp, const char *s, int len)
+{
+	return BIO_dump_cb(write_bio, bp, s, len);
+}
+
+int
+BIO_dump_indent(BIO *bp, const char *s, int len, int indent)
+{
+	return BIO_dump_indent_cb(write_bio, bp, s, len, indent);
+}
diff --git a/crypto/libressl/crypto/bio/b_posix.c b/crypto/libressl/crypto/bio/b_posix.c
new file mode 100644
index 0000000000..ed18725709
--- /dev/null
+++ b/crypto/libressl/crypto/bio/b_posix.c
@@ -0,0 +1,88 @@
+/* $OpenBSD: b_sock.c,v 1.58 2014/10/13 02:49:53 bcook Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/*
+ * Functions that need to be overridden by non-POSIX operating systems.
+ */
+
+#include 
+#include 
+
+#include 
+
+int
+BIO_sock_init(void)
+{
+	return (1);
+}
+
+void
+BIO_sock_cleanup(void)
+{
+}
+
+int
+BIO_socket_nbio(int s, int mode)
+{
+	int flags = fcntl(s, F_GETFD);
+	if (mode && !(flags & O_NONBLOCK))
+		return (fcntl(s, F_SETFL, flags | O_NONBLOCK) != -1);
+	else if (!mode && (flags & O_NONBLOCK))
+		return (fcntl(s, F_SETFL, flags & ~O_NONBLOCK) != -1);
+	return (1);
+}
diff --git a/crypto/libressl/crypto/bio/b_print.c b/crypto/libressl/crypto/bio/b_print.c
new file mode 100644
index 0000000000..cbbf8fa5c6
--- /dev/null
+++ b/crypto/libressl/crypto/bio/b_print.c
@@ -0,0 +1,109 @@
+/* $OpenBSD: b_print.c,v 1.24 2014/06/11 15:40:52 jsing Exp $ */
+
+/* Theo de Raadt places this file in the public domain. */
+
+#include 
+
+int
+BIO_printf(BIO *bio, const char *format, ...)
+{
+	va_list args;
+	int ret;
+
+	va_start(args, format);
+	ret = BIO_vprintf(bio, format, args);
+	va_end(args);
+	return (ret);
+}
+
+#ifdef HAVE_FUNOPEN
+static int
+_BIO_write(void *cookie, const char *buf, int nbytes)
+{
+	return BIO_write(cookie, buf, nbytes);
+}
+
+int
+BIO_vprintf(BIO *bio, const char *format, va_list args)
+{
+	int ret;
+	FILE *fp;
+
+	fp = funopen(bio, NULL, &_BIO_write, NULL, NULL);
+	if (fp == NULL) {
+		ret = -1;
+		goto fail;
+	}
+	ret = vfprintf(fp, format, args);
+	fclose(fp);
+fail:
+	return (ret);
+}
+
+#else /* !HAVE_FUNOPEN */
+
+int
+BIO_vprintf(BIO *bio, const char *format, va_list args)
+{
+	int ret;
+	char *buf = NULL;
+
+	ret = vasprintf(&buf, format, args);
+	if (buf == NULL) {
+		ret = -1;
+		goto fail;
+	}
+	BIO_write(bio, buf, ret);
+	free(buf);
+fail:
+	return (ret);
+}
+
+#endif /* HAVE_FUNOPEN */
+
+/*
+ * BIO_snprintf and BIO_vsnprintf return -1 for overflow,
+ * due to the history of this API.  Justification:
+ *
+ * Traditional snprintf surfaced in 4.4BSD, and returned
+ * "number of bytes wanted". Solaris and Windows opted to
+ * return -1.  A draft standard was written which returned -1.
+ * Due to the large volume of code already using the first
+ * semantics, the draft was repaired before standardization to
+ * specify "number of bytes wanted" plus "-1 for character conversion
+ * style errors".  Solaris adapted to this rule, but Windows stuck
+ * with -1.
+ *
+ * Original OpenSSL comment which is full of lies:
+ *
+ * "In case of truncation, return -1 like traditional snprintf.
+ * (Current drafts for ISO/IEC 9899 say snprintf should return
+ * the number of characters that would have been written,
+ * had the buffer been large enough.)"
+ */
+int
+BIO_snprintf(char *buf, size_t n, const char *format, ...)
+{
+	va_list args;
+	int ret;
+
+	va_start(args, format);
+	ret = vsnprintf(buf, n, format, args);
+	va_end(args);
+
+	if (ret >= n || ret == -1)
+		return (-1);
+	return (ret);
+}
+
+int
+BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
+{
+	int ret;
+
+	ret = vsnprintf(buf, n, format, args);
+
+	if (ret >= n || ret == -1)
+		return (-1);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/bio/b_sock.c b/crypto/libressl/crypto/bio/b_sock.c
new file mode 100644
index 0000000000..0290fb9439
--- /dev/null
+++ b/crypto/libressl/crypto/bio/b_sock.c
@@ -0,0 +1,444 @@
+/* $OpenBSD: b_sock.c,v 1.60 2014/12/03 21:55:51 bcook Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+int
+BIO_get_host_ip(const char *str, unsigned char *ip)
+{
+	int i;
+	int err = 1;
+	struct hostent *he;
+
+	if (inet_pton(AF_INET, str, ip) == 1)
+		return (1);
+
+	/* do a gethostbyname */
+	CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
+	he = BIO_gethostbyname(str);
+	if (he == NULL) {
+		BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_BAD_HOSTNAME_LOOKUP);
+		goto err;
+	}
+
+	if (he->h_addrtype != AF_INET) {
+		BIOerr(BIO_F_BIO_GET_HOST_IP,
+		    BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
+		goto err;
+	}
+	for (i = 0; i < 4; i++)
+		ip[i] = he->h_addr_list[0][i];
+	err = 0;
+
+err:
+	CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
+	if (err) {
+		ERR_asprintf_error_data("host=%s", str);
+		return 0;
+	} else
+		return 1;
+}
+
+int
+BIO_get_port(const char *str, unsigned short *port_ptr)
+{
+	struct addrinfo *res = NULL;
+	struct addrinfo hints = {
+		.ai_family = AF_UNSPEC,
+		.ai_socktype = SOCK_STREAM,
+		.ai_flags = AI_PASSIVE,
+	};
+	long port;
+	char *ep;
+
+	if (str == NULL) {
+		BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_SPECIFIED);
+		return (0);
+	}
+
+	errno = 0;
+	port = strtol(str, &ep, 10);
+	if (str[0] != '\0' && *ep == '\0') {
+		if (errno == ERANGE && (port == LONG_MAX || port == LONG_MIN)) {
+			BIOerr(BIO_F_BIO_GET_PORT, BIO_R_INVALID_PORT_NUMBER);
+			return (0);
+		}
+		if (port < 0 || port > 65535) {
+			BIOerr(BIO_F_BIO_GET_PORT, BIO_R_INVALID_PORT_NUMBER);
+			return (0);
+		}
+		goto done;
+	}
+
+	if (getaddrinfo(NULL, str, &hints, &res) == 0) {
+		port = ntohs(((struct sockaddr_in *)(res->ai_addr))->sin_port);
+		goto done;
+	}
+
+	if (strcmp(str, "http") == 0)
+		port = 80;
+	else if (strcmp(str, "telnet") == 0)
+		port = 23;
+	else if (strcmp(str, "socks") == 0)
+		port = 1080;
+	else if (strcmp(str, "https") == 0)
+		port = 443;
+	else if (strcmp(str, "ssl") == 0)
+		port = 443;
+	else if (strcmp(str, "ftp") == 0)
+		port = 21;
+	else if (strcmp(str, "gopher") == 0)
+		port = 70;
+	else {
+		SYSerr(SYS_F_GETSERVBYNAME, errno);
+		ERR_asprintf_error_data("service='%s'", str);
+		return (0);
+	}
+
+done:
+	if (res)
+		freeaddrinfo(res);
+	*port_ptr = (unsigned short)port;
+	return (1);
+}
+
+int
+BIO_sock_error(int sock)
+{
+	socklen_t len;
+	int err;
+
+	len = sizeof(err);
+	if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &len) != 0)
+		return (1);
+	return (err);
+}
+
+struct hostent *
+BIO_gethostbyname(const char *name)
+{
+	return gethostbyname(name);
+}
+
+int
+BIO_socket_ioctl(int fd, long type, void *arg)
+{
+	int ret;
+
+	ret = ioctl(fd, type, arg);
+	if (ret < 0)
+		SYSerr(SYS_F_IOCTLSOCKET, errno);
+	return (ret);
+}
+
+int
+BIO_get_accept_socket(char *host, int bind_mode)
+{
+	int ret = 0;
+	union {
+		struct sockaddr sa;
+		struct sockaddr_in sa_in;
+		struct sockaddr_in6 sa_in6;
+	} server, client;
+	int s = -1, cs, addrlen;
+	unsigned char ip[4];
+	unsigned short port;
+	char *str = NULL, *e;
+	char *h, *p;
+	unsigned long l;
+	int err_num;
+
+	if (host == NULL || (str = strdup(host)) == NULL)
+		return (-1);
+
+	h = p = NULL;
+	h = str;
+	for (e = str; *e; e++) {
+		if (*e == ':') {
+			p = e;
+		} else if (*e == '/') {
+			*e = '\0';
+			break;
+		}
+	}
+	/* points at last ':', '::port' is special [see below] */
+	if (p)
+		*p++ = '\0';
+	else
+		p = h, h = NULL;
+
+	do {
+		struct addrinfo *res, hint;
+
+		/*
+		 * '::port' enforces IPv6 wildcard listener. Some OSes,
+		 * e.g. Solaris, default to IPv6 without any hint. Also
+		 * note that commonly IPv6 wildchard socket can service
+		 * IPv4 connections just as well...
+		 */
+		memset(&hint, 0, sizeof(hint));
+		hint.ai_flags = AI_PASSIVE;
+		if (h) {
+			if (strchr(h, ':')) {
+				if (h[1] == '\0')
+					h = NULL;
+				hint.ai_family = AF_INET6;
+			} else if (h[0] == '*' && h[1] == '\0') {
+				hint.ai_family = AF_INET;
+				h = NULL;
+			}
+		}
+
+		if (getaddrinfo(h, p, &hint, &res))
+			break;
+
+		addrlen = res->ai_addrlen <= sizeof(server) ?
+		    res->ai_addrlen : sizeof(server);
+		memcpy(&server, res->ai_addr, addrlen);
+
+		freeaddrinfo(res);
+		goto again;
+	} while (0);
+
+	if (!BIO_get_port(p, &port))
+		goto err;
+
+	memset((char *)&server, 0, sizeof(server));
+	server.sa_in.sin_family = AF_INET;
+	server.sa_in.sin_port = htons(port);
+	addrlen = sizeof(server.sa_in);
+
+	if (h == NULL || strcmp(h, "*") == 0)
+		server.sa_in.sin_addr.s_addr = INADDR_ANY;
+	else {
+		if (!BIO_get_host_ip(h, &(ip[0])))
+			goto err;
+		l = (unsigned long)((unsigned long)ip[0]<<24L)|
+		    ((unsigned long)ip[1]<<16L)|
+		    ((unsigned long)ip[2]<< 8L)|
+		    ((unsigned long)ip[3]);
+		server.sa_in.sin_addr.s_addr = htonl(l);
+	}
+
+again:
+	s = socket(server.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
+	if (s == -1) {
+		SYSerr(SYS_F_SOCKET, errno);
+		ERR_asprintf_error_data("port='%s'", host);
+		BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,
+		    BIO_R_UNABLE_TO_CREATE_SOCKET);
+		goto err;
+	}
+
+	if (bind_mode == BIO_BIND_REUSEADDR) {
+		int i = 1;
+
+		ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
+		bind_mode = BIO_BIND_NORMAL;
+	}
+	if (bind(s, &server.sa, addrlen) == -1) {
+		err_num = errno;
+		if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) &&
+		    (err_num == EADDRINUSE)) {
+			client = server;
+			if (h == NULL || strcmp(h, "*") == 0) {
+				if (client.sa.sa_family == AF_INET6) {
+					memset(&client.sa_in6.sin6_addr, 0,
+					    sizeof(client.sa_in6.sin6_addr));
+					client.sa_in6.sin6_addr.s6_addr[15] = 1;
+				} else if (client.sa.sa_family == AF_INET) {
+					client.sa_in.sin_addr.s_addr =
+					    htonl(0x7F000001);
+				} else
+					goto err;
+			}
+			cs = socket(client.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
+			if (cs != -1) {
+				int ii;
+				ii = connect(cs, &client.sa, addrlen);
+				close(cs);
+				if (ii == -1) {
+					bind_mode = BIO_BIND_REUSEADDR;
+					close(s);
+					goto again;
+				}
+				/* else error */
+			}
+			/* else error */
+		}
+		SYSerr(SYS_F_BIND, err_num);
+		ERR_asprintf_error_data("port='%s'", host);
+		BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,
+		    BIO_R_UNABLE_TO_BIND_SOCKET);
+		goto err;
+	}
+	if (listen(s, SOMAXCONN) == -1) {
+		SYSerr(SYS_F_BIND, errno);
+		ERR_asprintf_error_data("port='%s'", host);
+		BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET,
+		    BIO_R_UNABLE_TO_LISTEN_SOCKET);
+		goto err;
+	}
+	ret = 1;
+err:
+	free(str);
+	if ((ret == 0) && (s != -1)) {
+		close(s);
+		s = -1;
+	}
+	return (s);
+}
+
+int
+BIO_accept(int sock, char **addr)
+{
+	int ret = -1;
+	unsigned long l;
+	unsigned short port;
+	char *p, *tmp;
+
+	struct {
+		socklen_t len;
+		union {
+			struct sockaddr sa;
+			struct sockaddr_in sa_in;
+			struct sockaddr_in6 sa_in6;
+		} from;
+	} sa;
+
+	sa.len = sizeof(sa.from);
+	memset(&sa.from, 0, sizeof(sa.from));
+	ret = accept(sock, &sa.from.sa, &sa.len);
+	if (ret == -1) {
+		if (BIO_sock_should_retry(ret))
+			return -2;
+		SYSerr(SYS_F_ACCEPT, errno);
+		BIOerr(BIO_F_BIO_ACCEPT, BIO_R_ACCEPT_ERROR);
+		goto end;
+	}
+
+	if (addr == NULL)
+		goto end;
+
+	do {
+		char   h[NI_MAXHOST], s[NI_MAXSERV];
+		size_t nl;
+
+		if (getnameinfo(&sa.from.sa, sa.len, h, sizeof(h),
+		    s, sizeof(s), NI_NUMERICHOST|NI_NUMERICSERV))
+			break;
+		nl = strlen(h) + strlen(s) + 2;
+		p = *addr;
+		if (p)
+			*p = '\0';
+		if (!(tmp = realloc(p, nl))) {
+			close(ret);
+			ret = -1;
+			free(p);
+			*addr = NULL;
+			BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE);
+			goto end;
+		}
+		p = tmp;
+		*addr = p;
+		snprintf(*addr, nl, "%s:%s", h, s);
+		goto end;
+	} while (0);
+	if (sa.from.sa.sa_family != AF_INET)
+		goto end;
+	l = ntohl(sa.from.sa_in.sin_addr.s_addr);
+	port = ntohs(sa.from.sa_in.sin_port);
+	if (*addr == NULL) {
+		if ((p = malloc(24)) == NULL) {
+			close(ret);
+			ret = -1;
+			BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE);
+			goto end;
+		}
+		*addr = p;
+	}
+	snprintf(*addr, 24, "%d.%d.%d.%d:%d",
+	    (unsigned char)(l >> 24L) & 0xff, (unsigned char)(l >> 16L) & 0xff,
+	    (unsigned char)(l >> 8L) & 0xff, (unsigned char)(l) & 0xff, port);
+
+end:
+	return (ret);
+}
+
+int
+BIO_set_tcp_ndelay(int s, int on)
+{
+	return (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) == 0);
+}
diff --git a/crypto/libressl/crypto/bio/b_win.c b/crypto/libressl/crypto/bio/b_win.c
new file mode 100644
index 0000000000..b8d01ae20f
--- /dev/null
+++ b/crypto/libressl/crypto/bio/b_win.c
@@ -0,0 +1,54 @@
+/*
+ * Public domain
+ *
+ * Dongsheng Song 
+ * Brent Cook 
+ */
+
+#include 
+
+#include 
+#include 
+
+int
+BIO_sock_init(void)
+{
+	/*
+	 * WSAStartup loads the winsock .dll and initializes the networking
+	 * stack on Windows, or simply increases the reference count.
+	 */
+	static struct WSAData wsa_state = {0};
+	WORD version_requested = MAKEWORD(2, 2);
+	static int wsa_init_done = 0;
+	if (!wsa_init_done) {
+		if (WSAStartup(version_requested, &wsa_state) != 0) {
+			int err = WSAGetLastError();
+			SYSerr(SYS_F_WSASTARTUP, err);
+			BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP);
+			return (-1);
+		}
+		wsa_init_done = 1;
+	}
+ 	return (1);
+}
+
+void
+BIO_sock_cleanup(void)
+{
+	/*
+	 * We could call WSACleanup here, but it is easy to get it wrong. Since
+	 * this API provides no way to even tell if it failed, there is no safe
+	 * way to expose that functionality here.
+	 *
+	 * The cost of leaving the networking DLLs loaded may have been large
+	 * during the Windows 3.1/win32s era, but it is small in modern
+	 * contexts, so don't bother.
+	 */
+}
+
+int
+BIO_socket_nbio(int s, int mode)
+{
+	u_long value = mode;
+	return ioctlsocket(s, FIONBIO, &value) != SOCKET_ERROR;
+}
diff --git a/crypto/libressl/crypto/bio/bf_buff.c b/crypto/libressl/crypto/bio/bf_buff.c
new file mode 100644
index 0000000000..42df351952
--- /dev/null
+++ b/crypto/libressl/crypto/bio/bf_buff.c
@@ -0,0 +1,520 @@
+/* $OpenBSD: bf_buff.c,v 1.22 2015/07/19 01:18:17 beck Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+static int buffer_write(BIO *h, const char *buf, int num);
+static int buffer_read(BIO *h, char *buf, int size);
+static int buffer_puts(BIO *h, const char *str);
+static int buffer_gets(BIO *h, char *str, int size);
+static long buffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int buffer_new(BIO *h);
+static int buffer_free(BIO *data);
+static long buffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+#define DEFAULT_BUFFER_SIZE	4096
+
+static BIO_METHOD methods_buffer = {
+	.type = BIO_TYPE_BUFFER,
+	.name = "buffer",
+	.bwrite = buffer_write,
+	.bread = buffer_read,
+	.bputs = buffer_puts,
+	.bgets = buffer_gets,
+	.ctrl = buffer_ctrl,
+	.create = buffer_new,
+	.destroy = buffer_free,
+	.callback_ctrl = buffer_callback_ctrl
+};
+
+BIO_METHOD *
+BIO_f_buffer(void)
+{
+	return (&methods_buffer);
+}
+
+static int
+buffer_new(BIO *bi)
+{
+	BIO_F_BUFFER_CTX *ctx;
+
+	ctx = malloc(sizeof(BIO_F_BUFFER_CTX));
+	if (ctx == NULL)
+		return (0);
+	ctx->ibuf = malloc(DEFAULT_BUFFER_SIZE);
+	if (ctx->ibuf == NULL) {
+		free(ctx);
+		return (0);
+	}
+	ctx->obuf = malloc(DEFAULT_BUFFER_SIZE);
+	if (ctx->obuf == NULL) {
+		free(ctx->ibuf);
+		free(ctx);
+		return (0);
+	}
+	ctx->ibuf_size = DEFAULT_BUFFER_SIZE;
+	ctx->obuf_size = DEFAULT_BUFFER_SIZE;
+	ctx->ibuf_len = 0;
+	ctx->ibuf_off = 0;
+	ctx->obuf_len = 0;
+	ctx->obuf_off = 0;
+
+	bi->init = 1;
+	bi->ptr = (char *)ctx;
+	bi->flags = 0;
+	return (1);
+}
+
+static int
+buffer_free(BIO *a)
+{
+	BIO_F_BUFFER_CTX *b;
+
+	if (a == NULL)
+		return (0);
+	b = (BIO_F_BUFFER_CTX *)a->ptr;
+	free(b->ibuf);
+	free(b->obuf);
+	free(a->ptr);
+	a->ptr = NULL;
+	a->init = 0;
+	a->flags = 0;
+	return (1);
+}
+
+static int
+buffer_read(BIO *b, char *out, int outl)
+{
+	int i, num = 0;
+	BIO_F_BUFFER_CTX *ctx;
+
+	if (out == NULL)
+		return (0);
+	ctx = (BIO_F_BUFFER_CTX *)b->ptr;
+
+	if ((ctx == NULL) || (b->next_bio == NULL))
+		return (0);
+	num = 0;
+	BIO_clear_retry_flags(b);
+
+start:
+	i = ctx->ibuf_len;
+	/* If there is stuff left over, grab it */
+	if (i != 0) {
+		if (i > outl)
+			i = outl;
+		memcpy(out, &(ctx->ibuf[ctx->ibuf_off]), i);
+		ctx->ibuf_off += i;
+		ctx->ibuf_len -= i;
+		num += i;
+		if (outl == i)
+			return (num);
+		outl -= i;
+		out += i;
+	}
+
+	/* We may have done a partial read. try to do more.
+	 * We have nothing in the buffer.
+	 * If we get an error and have read some data, just return it
+	 * and let them retry to get the error again.
+	 * copy direct to parent address space */
+	if (outl > ctx->ibuf_size) {
+		for (;;) {
+			i = BIO_read(b->next_bio, out, outl);
+			if (i <= 0) {
+				BIO_copy_next_retry(b);
+				if (i < 0)
+					return ((num > 0) ? num : i);
+				if (i == 0)
+					return (num);
+			}
+			num += i;
+			if (outl == i)
+				return (num);
+			out += i;
+			outl -= i;
+		}
+	}
+	/* else */
+
+	/* we are going to be doing some buffering */
+	i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size);
+	if (i <= 0) {
+		BIO_copy_next_retry(b);
+		if (i < 0)
+			return ((num > 0) ? num : i);
+		if (i == 0)
+			return (num);
+	}
+	ctx->ibuf_off = 0;
+	ctx->ibuf_len = i;
+
+	/* Lets re-read using ourselves :-) */
+	goto start;
+}
+
+static int
+buffer_write(BIO *b, const char *in, int inl)
+{
+	int i, num = 0;
+	BIO_F_BUFFER_CTX *ctx;
+
+	if ((in == NULL) || (inl <= 0))
+		return (0);
+	ctx = (BIO_F_BUFFER_CTX *)b->ptr;
+	if ((ctx == NULL) || (b->next_bio == NULL))
+		return (0);
+
+	BIO_clear_retry_flags(b);
+start:
+	i = ctx->obuf_size - (ctx->obuf_len + ctx->obuf_off);
+	/* add to buffer and return */
+	if (i >= inl) {
+		memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, inl);
+		ctx->obuf_len += inl;
+		return (num + inl);
+	}
+	/* else */
+	/* stuff already in buffer, so add to it first, then flush */
+	if (ctx->obuf_len != 0) {
+		if (i > 0) /* lets fill it up if we can */
+		{
+			memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, i);
+			in += i;
+			inl -= i;
+			num += i;
+			ctx->obuf_len += i;
+		}
+		/* we now have a full buffer needing flushing */
+		for (;;) {
+			i = BIO_write(b->next_bio, &(ctx->obuf[ctx->obuf_off]),
+			    ctx->obuf_len);
+			if (i <= 0) {
+				BIO_copy_next_retry(b);
+
+				if (i < 0)
+					return ((num > 0) ? num : i);
+				if (i == 0)
+					return (num);
+			}
+			ctx->obuf_off += i;
+			ctx->obuf_len -= i;
+			if (ctx->obuf_len == 0)
+				break;
+		}
+	}
+	/* we only get here if the buffer has been flushed and we
+	 * still have stuff to write */
+	ctx->obuf_off = 0;
+
+	/* we now have inl bytes to write */
+	while (inl >= ctx->obuf_size) {
+		i = BIO_write(b->next_bio, in, inl);
+		if (i <= 0) {
+			BIO_copy_next_retry(b);
+			if (i < 0)
+				return ((num > 0) ? num : i);
+			if (i == 0)
+				return (num);
+		}
+		num += i;
+		in += i;
+		inl -= i;
+		if (inl == 0)
+			return (num);
+	}
+
+	/* copy the rest into the buffer since we have only a small
+	 * amount left */
+	goto start;
+}
+
+static long
+buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+	BIO *dbio;
+	BIO_F_BUFFER_CTX *ctx;
+	long ret = 1;
+	char *p1, *p2;
+	int r, i, *ip;
+	int ibs, obs;
+
+	ctx = (BIO_F_BUFFER_CTX *)b->ptr;
+
+	switch (cmd) {
+	case BIO_CTRL_RESET:
+		ctx->ibuf_off = 0;
+		ctx->ibuf_len = 0;
+		ctx->obuf_off = 0;
+		ctx->obuf_len = 0;
+		if (b->next_bio == NULL)
+			return (0);
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		break;
+	case BIO_CTRL_INFO:
+		ret = (long)ctx->obuf_len;
+		break;
+	case BIO_C_GET_BUFF_NUM_LINES:
+		ret = 0;
+		p1 = ctx->ibuf;
+		for (i = 0; i < ctx->ibuf_len; i++) {
+			if (p1[ctx->ibuf_off + i] == '\n')
+				ret++;
+		}
+		break;
+	case BIO_CTRL_WPENDING:
+		ret = (long)ctx->obuf_len;
+		if (ret == 0) {
+			if (b->next_bio == NULL)
+				return (0);
+			ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		}
+		break;
+	case BIO_CTRL_PENDING:
+		ret = (long)ctx->ibuf_len;
+		if (ret == 0) {
+			if (b->next_bio == NULL)
+				return (0);
+			ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		}
+		break;
+	case BIO_C_SET_BUFF_READ_DATA:
+		if (num > ctx->ibuf_size) {
+			p1 = malloc(num);
+			if (p1 == NULL)
+				goto malloc_error;
+			free(ctx->ibuf);
+			ctx->ibuf = p1;
+		}
+		ctx->ibuf_off = 0;
+		ctx->ibuf_len = (int)num;
+		memcpy(ctx->ibuf, ptr, num);
+		ret = 1;
+		break;
+	case BIO_C_SET_BUFF_SIZE:
+		if (ptr != NULL) {
+			ip = (int *)ptr;
+			if (*ip == 0) {
+				ibs = (int)num;
+				obs = ctx->obuf_size;
+			}
+			else /* if (*ip == 1) */
+			{
+				ibs = ctx->ibuf_size;
+				obs = (int)num;
+			}
+		} else {
+			ibs = (int)num;
+			obs = (int)num;
+		}
+		p1 = ctx->ibuf;
+		p2 = ctx->obuf;
+		if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size)) {
+			p1 = malloc(num);
+			if (p1 == NULL)
+				goto malloc_error;
+		}
+		if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size)) {
+			p2 = malloc(num);
+			if (p2 == NULL) {
+				if (p1 != ctx->ibuf)
+					free(p1);
+				goto malloc_error;
+			}
+		}
+		if (ctx->ibuf != p1) {
+			free(ctx->ibuf);
+			ctx->ibuf = p1;
+			ctx->ibuf_off = 0;
+			ctx->ibuf_len = 0;
+			ctx->ibuf_size = ibs;
+		}
+		if (ctx->obuf != p2) {
+			free(ctx->obuf);
+			ctx->obuf = p2;
+			ctx->obuf_off = 0;
+			ctx->obuf_len = 0;
+			ctx->obuf_size = obs;
+		}
+		break;
+	case BIO_C_DO_STATE_MACHINE:
+		if (b->next_bio == NULL)
+			return (0);
+		BIO_clear_retry_flags(b);
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		BIO_copy_next_retry(b);
+		break;
+
+	case BIO_CTRL_FLUSH:
+		if (b->next_bio == NULL)
+			return (0);
+		if (ctx->obuf_len <= 0) {
+			ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+			break;
+		}
+
+		for (;;) {
+			BIO_clear_retry_flags(b);
+			if (ctx->obuf_len > 0) {
+				r = BIO_write(b->next_bio,
+				    &(ctx->obuf[ctx->obuf_off]),
+				    ctx->obuf_len);
+				BIO_copy_next_retry(b);
+				if (r <= 0)
+					return ((long)r);
+				ctx->obuf_off += r;
+				ctx->obuf_len -= r;
+			} else {
+				ctx->obuf_len = 0;
+				ctx->obuf_off = 0;
+				break;
+			}
+		}
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		break;
+	case BIO_CTRL_DUP:
+		dbio = (BIO *)ptr;
+		if (!BIO_set_read_buffer_size(dbio, ctx->ibuf_size) ||
+		    !BIO_set_write_buffer_size(dbio, ctx->obuf_size))
+			ret = 0;
+		break;
+	default:
+		if (b->next_bio == NULL)
+			return (0);
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		break;
+	}
+	return (ret);
+malloc_error:
+	BIOerr(BIO_F_BUFFER_CTRL, ERR_R_MALLOC_FAILURE);
+	return (0);
+}
+
+static long
+buffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+	long ret = 1;
+
+	if (b->next_bio == NULL)
+		return (0);
+	switch (cmd) {
+	default:
+		ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+		break;
+	}
+	return (ret);
+}
+
+static int
+buffer_gets(BIO *b, char *buf, int size)
+{
+	BIO_F_BUFFER_CTX *ctx;
+	int num = 0, i, flag;
+	char *p;
+
+	ctx = (BIO_F_BUFFER_CTX *)b->ptr;
+	size--; /* reserve space for a '\0' */
+	BIO_clear_retry_flags(b);
+
+	for (;;) {
+		if (ctx->ibuf_len > 0) {
+			p = &(ctx->ibuf[ctx->ibuf_off]);
+			flag = 0;
+			for (i = 0; (i < ctx->ibuf_len) && (i < size); i++) {
+				*(buf++) = p[i];
+				if (p[i] == '\n') {
+					flag = 1;
+					i++;
+					break;
+				}
+			}
+			num += i;
+			size -= i;
+			ctx->ibuf_len -= i;
+			ctx->ibuf_off += i;
+			if (flag || size == 0) {
+				*buf = '\0';
+				return (num);
+			}
+		}
+		else	/* read another chunk */
+		{
+			i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size);
+			if (i <= 0) {
+				BIO_copy_next_retry(b);
+				*buf = '\0';
+				if (i < 0)
+					return ((num > 0) ? num : i);
+				if (i == 0)
+					return (num);
+			}
+			ctx->ibuf_len = i;
+			ctx->ibuf_off = 0;
+		}
+	}
+}
+
+static int
+buffer_puts(BIO *b, const char *str)
+{
+	return (buffer_write(b, str, strlen(str)));
+}
diff --git a/crypto/libressl/crypto/bio/bf_nbio.c b/crypto/libressl/crypto/bio/bf_nbio.c
new file mode 100644
index 0000000000..c62d8a5b26
--- /dev/null
+++ b/crypto/libressl/crypto/bio/bf_nbio.c
@@ -0,0 +1,252 @@
+/* $OpenBSD: bf_nbio.c,v 1.18 2014/10/22 13:02:03 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+/* BIO_put and BIO_get both add to the digest,
+ * BIO_gets returns the digest */
+
+static int nbiof_write(BIO *h, const char *buf, int num);
+static int nbiof_read(BIO *h, char *buf, int size);
+static int nbiof_puts(BIO *h, const char *str);
+static int nbiof_gets(BIO *h, char *str, int size);
+static long nbiof_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int nbiof_new(BIO *h);
+static int nbiof_free(BIO *data);
+static long nbiof_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+
+typedef struct nbio_test_st {
+	/* only set if we sent a 'should retry' error */
+	int lrn;
+	int lwn;
+} NBIO_TEST;
+
+static BIO_METHOD methods_nbiof = {
+	.type = BIO_TYPE_NBIO_TEST,
+	.name = "non-blocking IO test filter",
+	.bwrite = nbiof_write,
+	.bread = nbiof_read,
+	.bputs = nbiof_puts,
+	.bgets = nbiof_gets,
+	.ctrl = nbiof_ctrl,
+	.create = nbiof_new,
+	.destroy = nbiof_free,
+	.callback_ctrl = nbiof_callback_ctrl
+};
+
+BIO_METHOD *
+BIO_f_nbio_test(void)
+{
+	return (&methods_nbiof);
+}
+
+static int
+nbiof_new(BIO *bi)
+{
+	NBIO_TEST *nt;
+
+	if (!(nt = malloc(sizeof(NBIO_TEST))))
+		return (0);
+	nt->lrn = -1;
+	nt->lwn = -1;
+	bi->ptr = (char *)nt;
+	bi->init = 1;
+	bi->flags = 0;
+	return (1);
+}
+
+static int
+nbiof_free(BIO *a)
+{
+	if (a == NULL)
+		return (0);
+	free(a->ptr);
+	a->ptr = NULL;
+	a->init = 0;
+	a->flags = 0;
+	return (1);
+}
+
+static int
+nbiof_read(BIO *b, char *out, int outl)
+{
+	int ret = 0;
+	int num;
+	unsigned char n;
+
+	if (out == NULL)
+		return (0);
+	if (b->next_bio == NULL)
+		return (0);
+
+	BIO_clear_retry_flags(b);
+
+	arc4random_buf(&n, 1);
+	num = (n & 0x07);
+
+	if (outl > num)
+		outl = num;
+
+	if (num == 0) {
+		ret = -1;
+		BIO_set_retry_read(b);
+	} else {
+		ret = BIO_read(b->next_bio, out, outl);
+		if (ret < 0)
+			BIO_copy_next_retry(b);
+	}
+	return (ret);
+}
+
+static int
+nbiof_write(BIO *b, const char *in, int inl)
+{
+	NBIO_TEST *nt;
+	int ret = 0;
+	int num;
+	unsigned char n;
+
+	if ((in == NULL) || (inl <= 0))
+		return (0);
+	if (b->next_bio == NULL)
+		return (0);
+	nt = (NBIO_TEST *)b->ptr;
+
+	BIO_clear_retry_flags(b);
+
+	if (nt->lwn > 0) {
+		num = nt->lwn;
+		nt->lwn = 0;
+	} else {
+		arc4random_buf(&n, 1);
+		num = (n&7);
+	}
+
+	if (inl > num)
+		inl = num;
+
+	if (num == 0) {
+		ret = -1;
+		BIO_set_retry_write(b);
+	} else {
+		ret = BIO_write(b->next_bio, in, inl);
+		if (ret < 0) {
+			BIO_copy_next_retry(b);
+			nt->lwn = inl;
+		}
+	}
+	return (ret);
+}
+
+static long
+nbiof_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+	long ret;
+
+	if (b->next_bio == NULL)
+		return (0);
+	switch (cmd) {
+	case BIO_C_DO_STATE_MACHINE:
+		BIO_clear_retry_flags(b);
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		BIO_copy_next_retry(b);
+		break;
+	case BIO_CTRL_DUP:
+		ret = 0L;
+		break;
+	default:
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		break;
+	}
+	return (ret);
+}
+
+static long
+nbiof_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+	long ret = 1;
+
+	if (b->next_bio == NULL)
+		return (0);
+	switch (cmd) {
+	default:
+		ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+		break;
+	}
+	return (ret);
+}
+
+static int
+nbiof_gets(BIO *bp, char *buf, int size)
+{
+	if (bp->next_bio == NULL)
+		return (0);
+	return (BIO_gets(bp->next_bio, buf, size));
+}
+
+static int
+nbiof_puts(BIO *bp, const char *str)
+{
+	if (bp->next_bio == NULL)
+		return (0);
+	return (BIO_puts(bp->next_bio, str));
+}
diff --git a/crypto/libressl/crypto/bio/bf_null.c b/crypto/libressl/crypto/bio/bf_null.c
new file mode 100644
index 0000000000..e25b40ac19
--- /dev/null
+++ b/crypto/libressl/crypto/bio/bf_null.c
@@ -0,0 +1,196 @@
+/* $OpenBSD: bf_null.c,v 1.10 2014/06/12 15:49:28 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+
+/* BIO_put and BIO_get both add to the digest,
+ * BIO_gets returns the digest */
+
+static int nullf_write(BIO *h, const char *buf, int num);
+static int nullf_read(BIO *h, char *buf, int size);
+static int nullf_puts(BIO *h, const char *str);
+static int nullf_gets(BIO *h, char *str, int size);
+static long nullf_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int nullf_new(BIO *h);
+static int nullf_free(BIO *data);
+static long nullf_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+
+static BIO_METHOD methods_nullf = {
+	.type = BIO_TYPE_NULL_FILTER,
+	.name = "NULL filter",
+	.bwrite = nullf_write,
+	.bread = nullf_read,
+	.bputs = nullf_puts,
+	.bgets = nullf_gets,
+	.ctrl = nullf_ctrl,
+	.create = nullf_new,
+	.destroy = nullf_free,
+	.callback_ctrl = nullf_callback_ctrl
+};
+
+BIO_METHOD *
+BIO_f_null(void)
+{
+	return (&methods_nullf);
+}
+
+static int
+nullf_new(BIO *bi)
+{
+	bi->init = 1;
+	bi->ptr = NULL;
+	bi->flags = 0;
+	return (1);
+}
+
+static int
+nullf_free(BIO *a)
+{
+	if (a == NULL)
+		return (0);
+/*	a->ptr=NULL;
+	a->init=0;
+	a->flags=0;*/
+	return (1);
+}
+
+static int
+nullf_read(BIO *b, char *out, int outl)
+{
+	int ret = 0;
+
+	if (out == NULL)
+		return (0);
+	if (b->next_bio == NULL)
+		return (0);
+	ret = BIO_read(b->next_bio, out, outl);
+	BIO_clear_retry_flags(b);
+	BIO_copy_next_retry(b);
+	return (ret);
+}
+
+static int
+nullf_write(BIO *b, const char *in, int inl)
+{
+	int ret = 0;
+
+	if ((in == NULL) || (inl <= 0))
+		return (0);
+	if (b->next_bio == NULL)
+		return (0);
+	ret = BIO_write(b->next_bio, in, inl);
+	BIO_clear_retry_flags(b);
+	BIO_copy_next_retry(b);
+	return (ret);
+}
+
+static long
+nullf_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+	long ret;
+
+	if (b->next_bio == NULL)
+		return (0);
+	switch (cmd) {
+	case BIO_C_DO_STATE_MACHINE:
+		BIO_clear_retry_flags(b);
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		BIO_copy_next_retry(b);
+		break;
+	case BIO_CTRL_DUP:
+		ret = 0L;
+		break;
+	default:
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+	}
+	return (ret);
+}
+
+static long
+nullf_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+	long ret = 1;
+
+	if (b->next_bio == NULL)
+		return (0);
+	switch (cmd) {
+	default:
+		ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+		break;
+	}
+	return (ret);
+}
+
+static int
+nullf_gets(BIO *bp, char *buf, int size)
+{
+	if (bp->next_bio == NULL)
+		return (0);
+	return (BIO_gets(bp->next_bio, buf, size));
+}
+
+static int
+nullf_puts(BIO *bp, const char *str)
+{
+	if (bp->next_bio == NULL)
+		return (0);
+	return (BIO_puts(bp->next_bio, str));
+}
diff --git a/crypto/libressl/crypto/bio/bio_cb.c b/crypto/libressl/crypto/bio/bio_cb.c
new file mode 100644
index 0000000000..9c0bb67ba4
--- /dev/null
+++ b/crypto/libressl/crypto/bio/bio_cb.c
@@ -0,0 +1,145 @@
+/* $OpenBSD: bio_cb.c,v 1.15 2014/07/11 08:44:47 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+long
+BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi, long argl,
+    long ret)
+{
+	BIO *b;
+	char buf[256];
+	char *p;
+	long r = 1;
+	size_t p_maxlen;
+
+	if (BIO_CB_RETURN & cmd)
+		r = ret;
+
+	snprintf(buf, sizeof buf, "BIO[%p]:", bio);
+	p = &(buf[14]);
+	p_maxlen = sizeof buf - 14;
+	switch (cmd) {
+	case BIO_CB_FREE:
+		snprintf(p, p_maxlen, "Free - %s\n", bio->method->name);
+		break;
+	case BIO_CB_READ:
+		if (bio->method->type & BIO_TYPE_DESCRIPTOR)
+			snprintf(p, p_maxlen,
+			    "read(%d,%lu) - %s fd=%d\n",
+			    bio->num, (unsigned long)argi,
+			    bio->method->name, bio->num);
+		else
+			snprintf(p, p_maxlen, "read(%d,%lu) - %s\n",
+			    bio->num, (unsigned long)argi, bio->method->name);
+		break;
+	case BIO_CB_WRITE:
+		if (bio->method->type & BIO_TYPE_DESCRIPTOR)
+			snprintf(p, p_maxlen,
+			    "write(%d,%lu) - %s fd=%d\n",
+			    bio->num, (unsigned long)argi,
+			    bio->method->name, bio->num);
+		else
+			snprintf(p, p_maxlen, "write(%d,%lu) - %s\n",
+			    bio->num, (unsigned long)argi, bio->method->name);
+		break;
+	case BIO_CB_PUTS:
+		snprintf(p, p_maxlen,
+		    "puts() - %s\n", bio->method->name);
+		break;
+	case BIO_CB_GETS:
+		snprintf(p, p_maxlen, "gets(%lu) - %s\n",
+		    (unsigned long)argi, bio->method->name);
+		break;
+	case BIO_CB_CTRL:
+		snprintf(p, p_maxlen, "ctrl(%lu) - %s\n",
+		    (unsigned long)argi, bio->method->name);
+		break;
+	case BIO_CB_RETURN|BIO_CB_READ:
+		snprintf(p, p_maxlen, "read return %ld\n", ret);
+		break;
+	case BIO_CB_RETURN|BIO_CB_WRITE:
+		snprintf(p, p_maxlen, "write return %ld\n", ret);
+		break;
+	case BIO_CB_RETURN|BIO_CB_GETS:
+		snprintf(p, p_maxlen, "gets return %ld\n", ret);
+		break;
+	case BIO_CB_RETURN|BIO_CB_PUTS:
+		snprintf(p, p_maxlen, "puts return %ld\n", ret);
+		break;
+	case BIO_CB_RETURN|BIO_CB_CTRL:
+		snprintf(p, p_maxlen, "ctrl return %ld\n", ret);
+		break;
+	default:
+		snprintf(p, p_maxlen,
+		    "bio callback - unknown type (%d)\n", cmd);
+		break;
+	}
+
+	b = (BIO *)bio->cb_arg;
+	if (b != NULL)
+		BIO_write(b, buf, strlen(buf));
+	else
+		fputs(buf, stderr);
+	return (r);
+}
diff --git a/crypto/libressl/crypto/bio/bio_err.c b/crypto/libressl/crypto/bio/bio_err.c
new file mode 100644
index 0000000000..bffd8ff998
--- /dev/null
+++ b/crypto/libressl/crypto/bio/bio_err.c
@@ -0,0 +1,156 @@
+/* $OpenBSD: bio_err.c,v 1.15 2014/06/22 14:41:10 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2011 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_BIO,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_BIO,0,reason)
+
+static ERR_STRING_DATA BIO_str_functs[] = {
+	{ERR_FUNC(BIO_F_ACPT_STATE),	"ACPT_STATE"},
+	{ERR_FUNC(BIO_F_BIO_ACCEPT),	"BIO_accept"},
+	{ERR_FUNC(BIO_F_BIO_BER_GET_HEADER),	"BIO_BER_GET_HEADER"},
+	{ERR_FUNC(BIO_F_BIO_CALLBACK_CTRL),	"BIO_callback_ctrl"},
+	{ERR_FUNC(BIO_F_BIO_CTRL),	"BIO_ctrl"},
+	{ERR_FUNC(BIO_F_BIO_GETHOSTBYNAME),	"BIO_gethostbyname"},
+	{ERR_FUNC(BIO_F_BIO_GETS),	"BIO_gets"},
+	{ERR_FUNC(BIO_F_BIO_GET_ACCEPT_SOCKET),	"BIO_get_accept_socket"},
+	{ERR_FUNC(BIO_F_BIO_GET_HOST_IP),	"BIO_get_host_ip"},
+	{ERR_FUNC(BIO_F_BIO_GET_PORT),	"BIO_get_port"},
+	{ERR_FUNC(BIO_F_BIO_MAKE_PAIR),	"BIO_MAKE_PAIR"},
+	{ERR_FUNC(BIO_F_BIO_NEW),	"BIO_new"},
+	{ERR_FUNC(BIO_F_BIO_NEW_FILE),	"BIO_new_file"},
+	{ERR_FUNC(BIO_F_BIO_NEW_MEM_BUF),	"BIO_new_mem_buf"},
+	{ERR_FUNC(BIO_F_BIO_NREAD),	"BIO_nread"},
+	{ERR_FUNC(BIO_F_BIO_NREAD0),	"BIO_nread0"},
+	{ERR_FUNC(BIO_F_BIO_NWRITE),	"BIO_nwrite"},
+	{ERR_FUNC(BIO_F_BIO_NWRITE0),	"BIO_nwrite0"},
+	{ERR_FUNC(BIO_F_BIO_PUTS),	"BIO_puts"},
+	{ERR_FUNC(BIO_F_BIO_READ),	"BIO_read"},
+	{ERR_FUNC(BIO_F_BIO_SOCK_INIT),	"BIO_sock_init"},
+	{ERR_FUNC(BIO_F_BIO_WRITE),	"BIO_write"},
+	{ERR_FUNC(BIO_F_BUFFER_CTRL),	"BUFFER_CTRL"},
+	{ERR_FUNC(BIO_F_CONN_CTRL),	"CONN_CTRL"},
+	{ERR_FUNC(BIO_F_CONN_STATE),	"CONN_STATE"},
+	{ERR_FUNC(BIO_F_DGRAM_SCTP_READ),	"DGRAM_SCTP_READ"},
+	{ERR_FUNC(BIO_F_FILE_CTRL),	"FILE_CTRL"},
+	{ERR_FUNC(BIO_F_FILE_READ),	"FILE_READ"},
+	{ERR_FUNC(BIO_F_LINEBUFFER_CTRL),	"LINEBUFFER_CTRL"},
+	{ERR_FUNC(BIO_F_MEM_READ),	"MEM_READ"},
+	{ERR_FUNC(BIO_F_MEM_WRITE),	"MEM_WRITE"},
+	{ERR_FUNC(BIO_F_SSL_NEW),	"SSL_new"},
+	{ERR_FUNC(BIO_F_WSASTARTUP),	"WSASTARTUP"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA BIO_str_reasons[] = {
+	{ERR_REASON(BIO_R_ACCEPT_ERROR)          , "accept error"},
+	{ERR_REASON(BIO_R_BAD_FOPEN_MODE)        , "bad fopen mode"},
+	{ERR_REASON(BIO_R_BAD_HOSTNAME_LOOKUP)   , "bad hostname lookup"},
+	{ERR_REASON(BIO_R_BROKEN_PIPE)           , "broken pipe"},
+	{ERR_REASON(BIO_R_CONNECT_ERROR)         , "connect error"},
+	{ERR_REASON(BIO_R_EOF_ON_MEMORY_BIO)     , "EOF on memory BIO"},
+	{ERR_REASON(BIO_R_ERROR_SETTING_NBIO)    , "error setting nbio"},
+	{ERR_REASON(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET), "error setting nbio on accepted socket"},
+	{ERR_REASON(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET), "error setting nbio on accept socket"},
+	{ERR_REASON(BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET), "gethostbyname addr is not af inet"},
+	{ERR_REASON(BIO_R_INVALID_ARGUMENT)      , "invalid argument"},
+	{ERR_REASON(BIO_R_INVALID_IP_ADDRESS)    , "invalid ip address"},
+	{ERR_REASON(BIO_R_INVALID_PORT_NUMBER)   , "invalid port number"},
+	{ERR_REASON(BIO_R_IN_USE)                , "in use"},
+	{ERR_REASON(BIO_R_KEEPALIVE)             , "keepalive"},
+	{ERR_REASON(BIO_R_NBIO_CONNECT_ERROR)    , "nbio connect error"},
+	{ERR_REASON(BIO_R_NO_ACCEPT_PORT_SPECIFIED), "no accept port specified"},
+	{ERR_REASON(BIO_R_NO_HOSTNAME_SPECIFIED) , "no hostname specified"},
+	{ERR_REASON(BIO_R_NO_PORT_DEFINED)       , "no port defined"},
+	{ERR_REASON(BIO_R_NO_PORT_SPECIFIED)     , "no port specified"},
+	{ERR_REASON(BIO_R_NO_SUCH_FILE)          , "no such file"},
+	{ERR_REASON(BIO_R_NULL_PARAMETER)        , "null parameter"},
+	{ERR_REASON(BIO_R_TAG_MISMATCH)          , "tag mismatch"},
+	{ERR_REASON(BIO_R_UNABLE_TO_BIND_SOCKET) , "unable to bind socket"},
+	{ERR_REASON(BIO_R_UNABLE_TO_CREATE_SOCKET), "unable to create socket"},
+	{ERR_REASON(BIO_R_UNABLE_TO_LISTEN_SOCKET), "unable to listen socket"},
+	{ERR_REASON(BIO_R_UNINITIALIZED)         , "uninitialized"},
+	{ERR_REASON(BIO_R_UNSUPPORTED_METHOD)    , "unsupported method"},
+	{ERR_REASON(BIO_R_WRITE_TO_READ_ONLY_BIO), "write to read only BIO"},
+	{ERR_REASON(BIO_R_WSASTARTUP)            , "WSAStartup"},
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_BIO_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(BIO_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, BIO_str_functs);
+		ERR_load_strings(0, BIO_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/bio/bio_lib.c b/crypto/libressl/crypto/bio/bio_lib.c
new file mode 100644
index 0000000000..15828a5c4b
--- /dev/null
+++ b/crypto/libressl/crypto/bio/bio_lib.c
@@ -0,0 +1,624 @@
+/* $OpenBSD: bio_lib.c,v 1.21 2014/07/25 06:05:32 doug Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+BIO *
+BIO_new(BIO_METHOD *method)
+{
+	BIO *ret = NULL;
+
+	ret = malloc(sizeof(BIO));
+	if (ret == NULL) {
+		BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE);
+		return (NULL);
+	}
+	if (!BIO_set(ret, method)) {
+		free(ret);
+		ret = NULL;
+	}
+	return (ret);
+}
+
+int
+BIO_set(BIO *bio, BIO_METHOD *method)
+{
+	bio->method = method;
+	bio->callback = NULL;
+	bio->cb_arg = NULL;
+	bio->init = 0;
+	bio->shutdown = 1;
+	bio->flags = 0;
+	bio->retry_reason = 0;
+	bio->num = 0;
+	bio->ptr = NULL;
+	bio->prev_bio = NULL;
+	bio->next_bio = NULL;
+	bio->references = 1;
+	bio->num_read = 0L;
+	bio->num_write = 0L;
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
+	if (method->create != NULL)
+		if (!method->create(bio)) {
+			CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio,
+			    &bio->ex_data);
+			return (0);
+		}
+	return (1);
+}
+
+int
+BIO_free(BIO *a)
+{
+	int i;
+
+	if (a == NULL)
+		return (0);
+
+	i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_BIO);
+	if (i > 0)
+		return (1);
+	if ((a->callback != NULL) &&
+	    ((i = (int)a->callback(a, BIO_CB_FREE, NULL, 0, 0L, 1L)) <= 0))
+		return (i);
+
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
+
+	if (a->method != NULL && a->method->destroy != NULL)
+		a->method->destroy(a);
+	free(a);
+	return (1);
+}
+
+void
+BIO_vfree(BIO *a)
+{
+	BIO_free(a);
+}
+
+void
+BIO_clear_flags(BIO *b, int flags)
+{
+	b->flags &= ~flags;
+}
+
+int
+BIO_test_flags(const BIO *b, int flags)
+{
+	return (b->flags & flags);
+}
+
+void
+BIO_set_flags(BIO *b, int flags)
+{
+	b->flags |= flags;
+}
+
+long
+(*BIO_get_callback(const BIO *b))(struct bio_st *, int, const char *, int,
+    long, long)
+{
+	return b->callback;
+}
+
+void
+BIO_set_callback(BIO *b, long (*cb)(struct bio_st *, int, const char *, int,
+    long, long))
+{
+	b->callback = cb;
+}
+
+void
+BIO_set_callback_arg(BIO *b, char *arg)
+{
+	b->cb_arg = arg;
+}
+
+char *
+BIO_get_callback_arg(const BIO *b)
+{
+	return b->cb_arg;
+}
+
+const char *
+BIO_method_name(const BIO *b)
+{
+	return b->method->name;
+}
+
+int
+BIO_method_type(const BIO *b)
+{
+	return b->method->type;
+}
+
+int
+BIO_read(BIO *b, void *out, int outl)
+{
+	int i;
+	long (*cb)(BIO *, int, const char *, int, long, long);
+
+	if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) {
+		BIOerr(BIO_F_BIO_READ, BIO_R_UNSUPPORTED_METHOD);
+		return (-2);
+	}
+
+	cb = b->callback;
+	if ((cb != NULL) &&
+	    ((i = (int)cb(b, BIO_CB_READ, out, outl, 0L, 1L)) <= 0))
+		return (i);
+
+	if (!b->init) {
+		BIOerr(BIO_F_BIO_READ, BIO_R_UNINITIALIZED);
+		return (-2);
+	}
+
+	i = b->method->bread(b, out, outl);
+
+	if (i > 0)
+		b->num_read += (unsigned long)i;
+
+	if (cb != NULL)
+		i = (int)cb(b, BIO_CB_READ|BIO_CB_RETURN, out, outl,
+		    0L, (long)i);
+	return (i);
+}
+
+int
+BIO_write(BIO *b, const void *in, int inl)
+{
+	int i;
+	long (*cb)(BIO *, int, const char *, int, long, long);
+
+	if (b == NULL)
+		return (0);
+
+	cb = b->callback;
+	if ((b->method == NULL) || (b->method->bwrite == NULL)) {
+		BIOerr(BIO_F_BIO_WRITE, BIO_R_UNSUPPORTED_METHOD);
+		return (-2);
+	}
+
+	if ((cb != NULL) &&
+	    ((i = (int)cb(b, BIO_CB_WRITE, in, inl, 0L, 1L)) <= 0))
+		return (i);
+
+	if (!b->init) {
+		BIOerr(BIO_F_BIO_WRITE, BIO_R_UNINITIALIZED);
+		return (-2);
+	}
+
+	i = b->method->bwrite(b, in, inl);
+
+	if (i > 0)
+		b->num_write += (unsigned long)i;
+
+	if (cb != NULL)
+		i = (int)cb(b, BIO_CB_WRITE|BIO_CB_RETURN, in, inl,
+		    0L, (long)i);
+	return (i);
+}
+
+int
+BIO_puts(BIO *b, const char *in)
+{
+	int i;
+	long (*cb)(BIO *, int, const char *, int, long, long);
+
+	if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) {
+		BIOerr(BIO_F_BIO_PUTS, BIO_R_UNSUPPORTED_METHOD);
+		return (-2);
+	}
+
+	cb = b->callback;
+
+	if ((cb != NULL) &&
+	    ((i = (int)cb(b, BIO_CB_PUTS, in, 0, 0L, 1L)) <= 0))
+		return (i);
+
+	if (!b->init) {
+		BIOerr(BIO_F_BIO_PUTS, BIO_R_UNINITIALIZED);
+		return (-2);
+	}
+
+	i = b->method->bputs(b, in);
+
+	if (i > 0)
+		b->num_write += (unsigned long)i;
+
+	if (cb != NULL)
+		i = (int)cb(b, BIO_CB_PUTS|BIO_CB_RETURN, in, 0, 0L, (long)i);
+	return (i);
+}
+
+int
+BIO_gets(BIO *b, char *in, int inl)
+{
+	int i;
+	long (*cb)(BIO *, int, const char *, int, long, long);
+
+	if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) {
+		BIOerr(BIO_F_BIO_GETS, BIO_R_UNSUPPORTED_METHOD);
+		return (-2);
+	}
+
+	cb = b->callback;
+
+	if ((cb != NULL) &&
+	    ((i = (int)cb(b, BIO_CB_GETS, in, inl, 0L, 1L)) <= 0))
+		return (i);
+
+	if (!b->init) {
+		BIOerr(BIO_F_BIO_GETS, BIO_R_UNINITIALIZED);
+		return (-2);
+	}
+
+	i = b->method->bgets(b, in, inl);
+
+	if (cb != NULL)
+		i = (int)cb(b, BIO_CB_GETS|BIO_CB_RETURN, in, inl, 0L, (long)i);
+	return (i);
+}
+
+int
+BIO_indent(BIO *b, int indent, int max)
+{
+	if (indent < 0)
+		indent = 0;
+	if (indent > max)
+		indent = max;
+	while (indent--)
+		if (BIO_puts(b, " ") != 1)
+			return 0;
+	return 1;
+}
+
+long
+BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
+{
+	int i;
+
+	i = iarg;
+	return (BIO_ctrl(b, cmd, larg, (char *)&i));
+}
+
+char *
+BIO_ptr_ctrl(BIO *b, int cmd, long larg)
+{
+	char *p = NULL;
+
+	if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0)
+		return (NULL);
+	else
+		return (p);
+}
+
+long
+BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
+{
+	long ret;
+	long (*cb)(BIO *, int, const char *, int, long, long);
+
+	if (b == NULL)
+		return (0);
+
+	if ((b->method == NULL) || (b->method->ctrl == NULL)) {
+		BIOerr(BIO_F_BIO_CTRL, BIO_R_UNSUPPORTED_METHOD);
+		return (-2);
+	}
+
+	cb = b->callback;
+
+	if ((cb != NULL) &&
+	    ((ret = cb(b, BIO_CB_CTRL, parg, cmd, larg, 1L)) <= 0))
+		return (ret);
+
+	ret = b->method->ctrl(b, cmd, larg, parg);
+
+	if (cb != NULL)
+		ret = cb(b, BIO_CB_CTRL|BIO_CB_RETURN, parg, cmd, larg, ret);
+	return (ret);
+}
+
+long
+BIO_callback_ctrl(BIO *b, int cmd,
+    void (*fp)(struct bio_st *, int, const char *, int, long, long))
+{
+	long ret;
+	long (*cb)(BIO *, int, const char *, int, long, long);
+
+	if (b == NULL)
+		return (0);
+
+	if ((b->method == NULL) || (b->method->callback_ctrl == NULL)) {
+		BIOerr(BIO_F_BIO_CALLBACK_CTRL, BIO_R_UNSUPPORTED_METHOD);
+		return (-2);
+	}
+
+	cb = b->callback;
+
+	if ((cb != NULL) &&
+	    ((ret = cb(b, BIO_CB_CTRL, (void *)&fp, cmd, 0, 1L)) <= 0))
+		return (ret);
+
+	ret = b->method->callback_ctrl(b, cmd, fp);
+
+	if (cb != NULL)
+		ret = cb(b, BIO_CB_CTRL|BIO_CB_RETURN, (void *)&fp, cmd, 0, ret);
+	return (ret);
+}
+
+/* It is unfortunate to duplicate in functions what the BIO_(w)pending macros
+ * do; but those macros have inappropriate return type, and for interfacing
+ * from other programming languages, C macros aren't much of a help anyway. */
+size_t
+BIO_ctrl_pending(BIO *bio)
+{
+	return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
+}
+
+size_t
+BIO_ctrl_wpending(BIO *bio)
+{
+	return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
+}
+
+
+/* put the 'bio' on the end of b's list of operators */
+BIO *
+BIO_push(BIO *b, BIO *bio)
+{
+	BIO *lb;
+
+	if (b == NULL)
+		return (bio);
+	lb = b;
+	while (lb->next_bio != NULL)
+		lb = lb->next_bio;
+	lb->next_bio = bio;
+	if (bio != NULL)
+		bio->prev_bio = lb;
+	/* called to do internal processing */
+	BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb);
+	return (b);
+}
+
+/* Remove the first and return the rest */
+BIO *
+BIO_pop(BIO *b)
+{
+	BIO *ret;
+
+	if (b == NULL)
+		return (NULL);
+	ret = b->next_bio;
+
+	BIO_ctrl(b, BIO_CTRL_POP, 0, b);
+
+	if (b->prev_bio != NULL)
+		b->prev_bio->next_bio = b->next_bio;
+	if (b->next_bio != NULL)
+		b->next_bio->prev_bio = b->prev_bio;
+
+	b->next_bio = NULL;
+	b->prev_bio = NULL;
+	return (ret);
+}
+
+BIO *
+BIO_get_retry_BIO(BIO *bio, int *reason)
+{
+	BIO *b, *last;
+
+	b = last = bio;
+	for (;;) {
+		if (!BIO_should_retry(b))
+			break;
+		last = b;
+		b = b->next_bio;
+		if (b == NULL)
+			break;
+	}
+	if (reason != NULL)
+		*reason = last->retry_reason;
+	return (last);
+}
+
+int
+BIO_get_retry_reason(BIO *bio)
+{
+	return (bio->retry_reason);
+}
+
+BIO *
+BIO_find_type(BIO *bio, int type)
+{
+	int mt, mask;
+
+	if (!bio)
+		return NULL;
+	mask = type & 0xff;
+	do {
+		if (bio->method != NULL) {
+			mt = bio->method->type;
+			if (!mask) {
+				if (mt & type)
+					return (bio);
+			} else if (mt == type)
+				return (bio);
+		}
+		bio = bio->next_bio;
+	} while (bio != NULL);
+	return (NULL);
+}
+
+BIO *
+BIO_next(BIO *b)
+{
+	if (!b)
+		return NULL;
+	return b->next_bio;
+}
+
+void
+BIO_free_all(BIO *bio)
+{
+	BIO *b;
+	int ref;
+
+	while (bio != NULL) {
+		b = bio;
+		ref = b->references;
+		bio = bio->next_bio;
+		BIO_free(b);
+		/* Since ref count > 1, don't free anyone else. */
+		if (ref > 1)
+			break;
+	}
+}
+
+BIO *
+BIO_dup_chain(BIO *in)
+{
+	BIO *ret = NULL, *eoc = NULL, *bio, *new_bio;
+
+	for (bio = in; bio != NULL; bio = bio->next_bio) {
+		if ((new_bio = BIO_new(bio->method)) == NULL)
+			goto err;
+		new_bio->callback = bio->callback;
+		new_bio->cb_arg = bio->cb_arg;
+		new_bio->init = bio->init;
+		new_bio->shutdown = bio->shutdown;
+		new_bio->flags = bio->flags;
+
+		/* This will let SSL_s_sock() work with stdin/stdout */
+		new_bio->num = bio->num;
+
+		if (!BIO_dup_state(bio, (char *)new_bio)) {
+			BIO_free(new_bio);
+			goto err;
+		}
+
+		/* copy app data */
+		if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO,
+		    &new_bio->ex_data, &bio->ex_data))
+			goto err;
+
+		if (ret == NULL) {
+			eoc = new_bio;
+			ret = eoc;
+		} else {
+			BIO_push(eoc, new_bio);
+			eoc = new_bio;
+		}
+	}
+	return (ret);
+err:
+	BIO_free(ret);
+	return (NULL);
+
+}
+
+void
+BIO_copy_next_retry(BIO *b)
+{
+	BIO_set_flags(b, BIO_get_retry_flags(b->next_bio));
+	b->retry_reason = b->next_bio->retry_reason;
+}
+
+int
+BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+    CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+{
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, argl, argp,
+	    new_func, dup_func, free_func);
+}
+
+int
+BIO_set_ex_data(BIO *bio, int idx, void *data)
+{
+	return (CRYPTO_set_ex_data(&(bio->ex_data), idx, data));
+}
+
+void *
+BIO_get_ex_data(BIO *bio, int idx)
+{
+	return (CRYPTO_get_ex_data(&(bio->ex_data), idx));
+}
+
+unsigned long
+BIO_number_read(BIO *bio)
+{
+	if (bio)
+		return bio->num_read;
+	return 0;
+}
+
+unsigned long
+BIO_number_written(BIO *bio)
+{
+	if (bio)
+		return bio->num_write;
+	return 0;
+}
diff --git a/crypto/libressl/crypto/bio/bss_acpt.c b/crypto/libressl/crypto/bio/bss_acpt.c
new file mode 100644
index 0000000000..84c89f5416
--- /dev/null
+++ b/crypto/libressl/crypto/bio/bss_acpt.c
@@ -0,0 +1,453 @@
+/* $OpenBSD: bss_acpt.c,v 1.25 2014/07/25 06:05:32 doug Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#define SOCKET_PROTOCOL IPPROTO_TCP
+
+typedef struct bio_accept_st {
+	int state;
+	char *param_addr;
+
+	int accept_sock;
+	int accept_nbio;
+
+	char *addr;
+	int nbio;
+	/* If 0, it means normal, if 1, do a connect on bind failure,
+	 * and if there is no-one listening, bind with SO_REUSEADDR.
+	 * If 2, always use SO_REUSEADDR. */
+	int bind_mode;
+	BIO *bio_chain;
+} BIO_ACCEPT;
+
+static int acpt_write(BIO *h, const char *buf, int num);
+static int acpt_read(BIO *h, char *buf, int size);
+static int acpt_puts(BIO *h, const char *str);
+static long acpt_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int acpt_new(BIO *h);
+static int acpt_free(BIO *data);
+static int acpt_state(BIO *b, BIO_ACCEPT *c);
+static void acpt_close_socket(BIO *data);
+static BIO_ACCEPT *BIO_ACCEPT_new(void );
+static void BIO_ACCEPT_free(BIO_ACCEPT *a);
+
+#define ACPT_S_BEFORE			1
+#define ACPT_S_GET_ACCEPT_SOCKET	2
+#define ACPT_S_OK			3
+
+static BIO_METHOD methods_acceptp = {
+	.type = BIO_TYPE_ACCEPT,
+	.name = "socket accept",
+	.bwrite = acpt_write,
+	.bread = acpt_read,
+	.bputs = acpt_puts,
+	.ctrl = acpt_ctrl,
+	.create = acpt_new,
+	.destroy = acpt_free
+};
+
+BIO_METHOD *
+BIO_s_accept(void)
+{
+	return (&methods_acceptp);
+}
+
+static int
+acpt_new(BIO *bi)
+{
+	BIO_ACCEPT *ba;
+
+	bi->init = 0;
+	bi->num = -1;
+	bi->flags = 0;
+	if ((ba = BIO_ACCEPT_new()) == NULL)
+		return (0);
+	bi->ptr = (char *)ba;
+	ba->state = ACPT_S_BEFORE;
+	bi->shutdown = 1;
+	return (1);
+}
+
+static BIO_ACCEPT *
+BIO_ACCEPT_new(void)
+{
+	BIO_ACCEPT *ret;
+
+	if ((ret = calloc(1, sizeof(BIO_ACCEPT))) == NULL)
+		return (NULL);
+	ret->accept_sock = -1;
+	ret->bind_mode = BIO_BIND_NORMAL;
+	return (ret);
+}
+
+static void
+BIO_ACCEPT_free(BIO_ACCEPT *a)
+{
+	if (a == NULL)
+		return;
+
+	free(a->param_addr);
+	free(a->addr);
+	BIO_free(a->bio_chain);
+	free(a);
+}
+
+static void
+acpt_close_socket(BIO *bio)
+{
+	BIO_ACCEPT *c;
+
+	c = (BIO_ACCEPT *)bio->ptr;
+	if (c->accept_sock != -1) {
+		shutdown(c->accept_sock, SHUT_RDWR);
+		close(c->accept_sock);
+		c->accept_sock = -1;
+		bio->num = -1;
+	}
+}
+
+static int
+acpt_free(BIO *a)
+{
+	BIO_ACCEPT *data;
+
+	if (a == NULL)
+		return (0);
+	data = (BIO_ACCEPT *)a->ptr;
+
+	if (a->shutdown) {
+		acpt_close_socket(a);
+		BIO_ACCEPT_free(data);
+		a->ptr = NULL;
+		a->flags = 0;
+		a->init = 0;
+	}
+	return (1);
+}
+
+static int
+acpt_state(BIO *b, BIO_ACCEPT *c)
+{
+	BIO *bio = NULL, *dbio;
+	int s = -1;
+	int i;
+
+again:
+	switch (c->state) {
+	case ACPT_S_BEFORE:
+		if (c->param_addr == NULL) {
+			BIOerr(BIO_F_ACPT_STATE, BIO_R_NO_ACCEPT_PORT_SPECIFIED);
+			return (-1);
+		}
+		s = BIO_get_accept_socket(c->param_addr, c->bind_mode);
+		if (s == -1)
+			return (-1);
+
+		if (c->accept_nbio) {
+			if (!BIO_socket_nbio(s, 1)) {
+				close(s);
+				BIOerr(BIO_F_ACPT_STATE, BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET);
+				return (-1);
+			}
+		}
+		c->accept_sock = s;
+		b->num = s;
+		c->state = ACPT_S_GET_ACCEPT_SOCKET;
+		return (1);
+		/* break; */
+	case ACPT_S_GET_ACCEPT_SOCKET:
+		if (b->next_bio != NULL) {
+			c->state = ACPT_S_OK;
+			goto again;
+		}
+		BIO_clear_retry_flags(b);
+		b->retry_reason = 0;
+		i = BIO_accept(c->accept_sock, &(c->addr));
+
+		/* -2 return means we should retry */
+		if (i == -2) {
+			BIO_set_retry_special(b);
+			b->retry_reason = BIO_RR_ACCEPT;
+			return -1;
+		}
+
+		if (i < 0)
+			return (i);
+
+		bio = BIO_new_socket(i, BIO_CLOSE);
+		if (bio == NULL)
+			goto err;
+
+		BIO_set_callback(bio, BIO_get_callback(b));
+		BIO_set_callback_arg(bio, BIO_get_callback_arg(b));
+
+		if (c->nbio) {
+			if (!BIO_socket_nbio(i, 1)) {
+				BIOerr(BIO_F_ACPT_STATE, BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET);
+				goto err;
+			}
+		}
+
+		/* If the accept BIO has an bio_chain, we dup it and
+		 * put the new socket at the end. */
+		if (c->bio_chain != NULL) {
+			if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL)
+				goto err;
+			if (!BIO_push(dbio, bio)) goto err;
+				bio = dbio;
+		}
+		if (BIO_push(b, bio)
+			== NULL) goto err;
+
+		c->state = ACPT_S_OK;
+		return (1);
+
+err:
+		if (bio != NULL)
+			BIO_free(bio);
+		return (0);
+		/* break; */
+	case ACPT_S_OK:
+		if (b->next_bio == NULL) {
+			c->state = ACPT_S_GET_ACCEPT_SOCKET;
+			goto again;
+		}
+		return (1);
+		/* break; */
+	default:
+		return (0);
+		/* break; */
+	}
+}
+
+static int
+acpt_read(BIO *b, char *out, int outl)
+{
+	int ret = 0;
+	BIO_ACCEPT *data;
+
+	BIO_clear_retry_flags(b);
+	data = (BIO_ACCEPT *)b->ptr;
+
+	while (b->next_bio == NULL) {
+		ret = acpt_state(b, data);
+		if (ret <= 0)
+			return (ret);
+	}
+
+	ret = BIO_read(b->next_bio, out, outl);
+	BIO_copy_next_retry(b);
+	return (ret);
+}
+
+static int
+acpt_write(BIO *b, const char *in, int inl)
+{
+	int ret;
+	BIO_ACCEPT *data;
+
+	BIO_clear_retry_flags(b);
+	data = (BIO_ACCEPT *)b->ptr;
+
+	while (b->next_bio == NULL) {
+		ret = acpt_state(b, data);
+		if (ret <= 0)
+			return (ret);
+	}
+
+	ret = BIO_write(b->next_bio, in, inl);
+	BIO_copy_next_retry(b);
+	return (ret);
+}
+
+static long
+acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+	int *ip;
+	long ret = 1;
+	BIO_ACCEPT *data;
+	char **pp;
+
+	data = (BIO_ACCEPT *)b->ptr;
+
+	switch (cmd) {
+	case BIO_CTRL_RESET:
+		ret = 0;
+		data->state = ACPT_S_BEFORE;
+		acpt_close_socket(b);
+		b->flags = 0;
+		break;
+	case BIO_C_DO_STATE_MACHINE:
+		/* use this one to start the connection */
+		ret = (long)acpt_state(b, data);
+		break;
+	case BIO_C_SET_ACCEPT:
+		if (ptr != NULL) {
+			if (num == 0) {
+				b->init = 1;
+				free(data->param_addr);
+				data->param_addr = strdup(ptr);
+			} else if (num == 1) {
+				data->accept_nbio = (ptr != NULL);
+			} else if (num == 2) {
+				BIO_free(data->bio_chain);
+				data->bio_chain = (BIO *)ptr;
+			}
+		}
+		break;
+	case BIO_C_SET_NBIO:
+		data->nbio = (int)num;
+		break;
+	case BIO_C_SET_FD:
+		b->init = 1;
+		b->num= *((int *)ptr);
+		data->accept_sock = b->num;
+		data->state = ACPT_S_GET_ACCEPT_SOCKET;
+		b->shutdown = (int)num;
+		b->init = 1;
+		break;
+	case BIO_C_GET_FD:
+		if (b->init) {
+			ip = (int *)ptr;
+			if (ip != NULL)
+				*ip = data->accept_sock;
+			ret = data->accept_sock;
+		} else
+			ret = -1;
+		break;
+	case BIO_C_GET_ACCEPT:
+		if (b->init) {
+			if (ptr != NULL) {
+				pp = (char **)ptr;
+				*pp = data->param_addr;
+			} else
+				ret = -1;
+		} else
+			ret = -1;
+		break;
+	case BIO_CTRL_GET_CLOSE:
+		ret = b->shutdown;
+		break;
+	case BIO_CTRL_SET_CLOSE:
+		b->shutdown = (int)num;
+		break;
+	case BIO_CTRL_PENDING:
+	case BIO_CTRL_WPENDING:
+		ret = 0;
+		break;
+	case BIO_CTRL_FLUSH:
+		break;
+	case BIO_C_SET_BIND_MODE:
+		data->bind_mode = (int)num;
+		break;
+	case BIO_C_GET_BIND_MODE:
+		ret = (long)data->bind_mode;
+		break;
+	case BIO_CTRL_DUP:
+/*		dbio=(BIO *)ptr;
+		if (data->param_port) EAY EAY
+			BIO_set_port(dbio,data->param_port);
+		if (data->param_hostname)
+			BIO_set_hostname(dbio,data->param_hostname);
+		BIO_set_nbio(dbio,data->nbio);
+*/
+		break;
+
+	default:
+		ret = 0;
+		break;
+	}
+	return (ret);
+}
+
+static int
+acpt_puts(BIO *bp, const char *str)
+{
+	int n, ret;
+
+	n = strlen(str);
+	ret = acpt_write(bp, str, n);
+	return (ret);
+}
+
+BIO *
+BIO_new_accept(char *str)
+{
+	BIO *ret;
+
+	ret = BIO_new(BIO_s_accept());
+	if (ret == NULL)
+		return (NULL);
+	if (BIO_set_accept_port(ret, str))
+		return (ret);
+	else {
+		BIO_free(ret);
+		return (NULL);
+	}
+}
+
diff --git a/crypto/libressl/crypto/bio/bss_bio.c b/crypto/libressl/crypto/bio/bss_bio.c
new file mode 100644
index 0000000000..6362987c89
--- /dev/null
+++ b/crypto/libressl/crypto/bio/bss_bio.c
@@ -0,0 +1,883 @@
+/* $OpenBSD: bss_bio.c,v 1.21 2015/10/30 15:45:57 miod Exp $ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Special method for a BIO where the other endpoint is also a BIO
+ * of this kind, handled by the same thread (i.e. the "peer" is actually
+ * ourselves, wearing a different hat).
+ * Such "BIO pairs" are mainly for using the SSL library with I/O interfaces
+ * for which no specific BIO method is available.
+ * See ssl/ssltest.c for some hints on how this can be used. */
+
+/* BIO_DEBUG implies BIO_PAIR_DEBUG */
+#ifdef BIO_DEBUG
+# ifndef BIO_PAIR_DEBUG
+#  define BIO_PAIR_DEBUG
+# endif
+#endif
+
+/* disable assert() unless BIO_PAIR_DEBUG has been defined */
+#ifndef BIO_PAIR_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+static int bio_new(BIO *bio);
+static int bio_free(BIO *bio);
+static int bio_read(BIO *bio, char *buf, int size);
+static int bio_write(BIO *bio, const char *buf, int num);
+static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
+static int bio_puts(BIO *bio, const char *str);
+
+static int bio_make_pair(BIO *bio1, BIO *bio2);
+static void bio_destroy_pair(BIO *bio);
+
+static BIO_METHOD methods_biop = {
+	.type = BIO_TYPE_BIO,
+	.name = "BIO pair",
+	.bwrite = bio_write,
+	.bread = bio_read,
+	.bputs = bio_puts,
+	.ctrl = bio_ctrl,
+	.create = bio_new,
+	.destroy = bio_free
+};
+
+BIO_METHOD *
+BIO_s_bio(void)
+{
+	return &methods_biop;
+}
+
+struct bio_bio_st {
+	BIO *peer;	/* NULL if buf == NULL.
+			 * If peer != NULL, then peer->ptr is also a bio_bio_st,
+			 * and its "peer" member points back to us.
+			 * peer != NULL iff init != 0 in the BIO. */
+
+	/* This is for what we write (i.e. reading uses peer's struct): */
+	int closed;	/* valid iff peer != NULL */
+	size_t len;	/* valid iff buf != NULL; 0 if peer == NULL */
+	size_t offset;	/* valid iff buf != NULL; 0 if len == 0 */
+	size_t size;
+	char *buf;      /* "size" elements (if != NULL) */
+
+	size_t request; /* valid iff peer != NULL; 0 if len != 0,
+			 * otherwise set by peer to number of bytes
+			 * it (unsuccessfully) tried to read,
+	                 * never more than buffer space (size-len) warrants. */
+};
+
+static int
+bio_new(BIO *bio)
+{
+	struct bio_bio_st *b;
+
+	b = malloc(sizeof *b);
+	if (b == NULL)
+		return 0;
+
+	b->peer = NULL;
+	b->size = 17 * 1024; /* enough for one TLS record (just a default) */
+	b->buf = NULL;
+
+	bio->ptr = b;
+	return 1;
+}
+
+static int
+bio_free(BIO *bio)
+{
+	struct bio_bio_st *b;
+
+	if (bio == NULL)
+		return 0;
+	b = bio->ptr;
+
+	assert(b != NULL);
+
+	if (b->peer)
+		bio_destroy_pair(bio);
+
+	free(b->buf);
+	free(b);
+	return 1;
+}
+
+
+
+static int
+bio_read(BIO *bio, char *buf, int size_)
+{
+	size_t size = size_;
+	size_t rest;
+	struct bio_bio_st *b, *peer_b;
+
+	BIO_clear_retry_flags(bio);
+
+	if (!bio->init)
+		return 0;
+
+	b = bio->ptr;
+	assert(b != NULL);
+	assert(b->peer != NULL);
+	peer_b = b->peer->ptr;
+	assert(peer_b != NULL);
+	assert(peer_b->buf != NULL);
+
+	peer_b->request = 0; /* will be set in "retry_read" situation */
+
+	if (buf == NULL || size == 0)
+		return 0;
+
+	if (peer_b->len == 0) {
+		if (peer_b->closed)
+			return 0; /* writer has closed, and no data is left */
+		else {
+			BIO_set_retry_read(bio); /* buffer is empty */
+			if (size <= peer_b->size)
+				peer_b->request = size;
+			else
+				/* don't ask for more than the peer can
+				 * deliver in one write */
+				peer_b->request = peer_b->size;
+			return -1;
+		}
+	}
+
+	/* we can read */
+	if (peer_b->len < size)
+		size = peer_b->len;
+
+	/* now read "size" bytes */
+
+	rest = size;
+
+	assert(rest > 0);
+	do /* one or two iterations */
+	{
+		size_t chunk;
+
+		assert(rest <= peer_b->len);
+		if (peer_b->offset + rest <= peer_b->size)
+			chunk = rest;
+		else
+			/* wrap around ring buffer */
+			chunk = peer_b->size - peer_b->offset;
+		assert(peer_b->offset + chunk <= peer_b->size);
+
+		memcpy(buf, peer_b->buf + peer_b->offset, chunk);
+
+		peer_b->len -= chunk;
+		if (peer_b->len) {
+			peer_b->offset += chunk;
+			assert(peer_b->offset <= peer_b->size);
+			if (peer_b->offset == peer_b->size)
+				peer_b->offset = 0;
+			buf += chunk;
+		} else {
+			/* buffer now empty, no need to advance "buf" */
+			assert(chunk == rest);
+			peer_b->offset = 0;
+		}
+		rest -= chunk;
+	} while (rest);
+
+	return size;
+}
+
+/* non-copying interface: provide pointer to available data in buffer
+ *    bio_nread0:  return number of available bytes
+ *    bio_nread:   also advance index
+ * (example usage:  bio_nread0(), read from buffer, bio_nread()
+ *  or just         bio_nread(), read from buffer)
+ */
+/* WARNING: The non-copying interface is largely untested as of yet
+ * and may contain bugs. */
+static ssize_t
+bio_nread0(BIO *bio, char **buf)
+{
+	struct bio_bio_st *b, *peer_b;
+	ssize_t num;
+
+	BIO_clear_retry_flags(bio);
+
+	if (!bio->init)
+		return 0;
+
+	b = bio->ptr;
+	assert(b != NULL);
+	assert(b->peer != NULL);
+	peer_b = b->peer->ptr;
+	assert(peer_b != NULL);
+	assert(peer_b->buf != NULL);
+
+	peer_b->request = 0;
+
+	if (peer_b->len == 0) {
+		char dummy;
+
+		/* avoid code duplication -- nothing available for reading */
+		return bio_read(bio, &dummy, 1); /* returns 0 or -1 */
+	}
+
+	num = peer_b->len;
+	if (peer_b->size < peer_b->offset + num)
+		/* no ring buffer wrap-around for non-copying interface */
+		num = peer_b->size - peer_b->offset;
+	assert(num > 0);
+
+	if (buf != NULL)
+		*buf = peer_b->buf + peer_b->offset;
+	return num;
+}
+
+static ssize_t
+bio_nread(BIO *bio, char **buf, size_t num_)
+{
+	struct bio_bio_st *b, *peer_b;
+	ssize_t num, available;
+
+	if (num_ > SSIZE_MAX)
+		num = SSIZE_MAX;
+	else
+		num = (ssize_t)num_;
+
+	available = bio_nread0(bio, buf);
+	if (num > available)
+		num = available;
+	if (num <= 0)
+		return num;
+
+	b = bio->ptr;
+	peer_b = b->peer->ptr;
+
+	peer_b->len -= num;
+	if (peer_b->len) {
+		peer_b->offset += num;
+		assert(peer_b->offset <= peer_b->size);
+		if (peer_b->offset == peer_b->size)
+			peer_b->offset = 0;
+	} else
+		peer_b->offset = 0;
+
+	return num;
+}
+
+
+static int
+bio_write(BIO *bio, const char *buf, int num_)
+{
+	size_t num = num_;
+	size_t rest;
+	struct bio_bio_st *b;
+
+	BIO_clear_retry_flags(bio);
+
+	if (!bio->init || buf == NULL || num == 0)
+		return 0;
+
+	b = bio->ptr;
+
+	assert(b != NULL);
+	assert(b->peer != NULL);
+	assert(b->buf != NULL);
+
+	b->request = 0;
+	if (b->closed) {
+		/* we already closed */
+		BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE);
+		return -1;
+	}
+
+	assert(b->len <= b->size);
+
+	if (b->len == b->size) {
+		BIO_set_retry_write(bio); /* buffer is full */
+		return -1;
+	}
+
+	/* we can write */
+	if (num > b->size - b->len)
+		num = b->size - b->len;
+
+	/* now write "num" bytes */
+
+	rest = num;
+
+	assert(rest > 0);
+	do /* one or two iterations */
+	{
+		size_t write_offset;
+		size_t chunk;
+
+		assert(b->len + rest <= b->size);
+
+		write_offset = b->offset + b->len;
+		if (write_offset >= b->size)
+			write_offset -= b->size;
+		/* b->buf[write_offset] is the first byte we can write to. */
+
+		if (write_offset + rest <= b->size)
+			chunk = rest;
+		else
+			/* wrap around ring buffer */
+			chunk = b->size - write_offset;
+
+		memcpy(b->buf + write_offset, buf, chunk);
+
+		b->len += chunk;
+
+		assert(b->len <= b->size);
+
+		rest -= chunk;
+		buf += chunk;
+	} while (rest);
+
+	return num;
+}
+
+/* non-copying interface: provide pointer to region to write to
+ *   bio_nwrite0:  check how much space is available
+ *   bio_nwrite:   also increase length
+ * (example usage:  bio_nwrite0(), write to buffer, bio_nwrite()
+ *  or just         bio_nwrite(), write to buffer)
+ */
+static ssize_t
+bio_nwrite0(BIO *bio, char **buf)
+{
+	struct bio_bio_st *b;
+	size_t num;
+	size_t write_offset;
+
+	BIO_clear_retry_flags(bio);
+
+	if (!bio->init)
+		return 0;
+
+	b = bio->ptr;
+
+	assert(b != NULL);
+	assert(b->peer != NULL);
+	assert(b->buf != NULL);
+
+	b->request = 0;
+	if (b->closed) {
+		BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE);
+		return -1;
+	}
+
+	assert(b->len <= b->size);
+
+	if (b->len == b->size) {
+		BIO_set_retry_write(bio);
+		return -1;
+	}
+
+	num = b->size - b->len;
+	write_offset = b->offset + b->len;
+	if (write_offset >= b->size)
+		write_offset -= b->size;
+	if (write_offset + num > b->size)
+		/* no ring buffer wrap-around for non-copying interface
+		 * (to fulfil the promise by BIO_ctrl_get_write_guarantee,
+		 * BIO_nwrite may have to be called twice) */
+		num = b->size - write_offset;
+
+	if (buf != NULL)
+		*buf = b->buf + write_offset;
+	assert(write_offset + num <= b->size);
+
+	return num;
+}
+
+static ssize_t
+bio_nwrite(BIO *bio, char **buf, size_t num_)
+{
+	struct bio_bio_st *b;
+	ssize_t num, space;
+
+	if (num_ > SSIZE_MAX)
+		num = SSIZE_MAX;
+	else
+		num = (ssize_t)num_;
+
+	space = bio_nwrite0(bio, buf);
+	if (num > space)
+		num = space;
+	if (num <= 0)
+		return num;
+	b = bio->ptr;
+	assert(b != NULL);
+	b->len += num;
+	assert(b->len <= b->size);
+
+	return num;
+}
+
+
+static long
+bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
+{
+	long ret;
+	struct bio_bio_st *b = bio->ptr;
+
+	assert(b != NULL);
+
+	switch (cmd) {
+		/* specific CTRL codes */
+
+	case BIO_C_SET_WRITE_BUF_SIZE:
+		if (b->peer) {
+			BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE);
+			ret = 0;
+		} else if (num == 0) {
+			BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT);
+			ret = 0;
+		} else {
+			size_t new_size = num;
+
+			if (b->size != new_size) {
+				free(b->buf);
+				b->buf = NULL;
+				b->size = new_size;
+			}
+			ret = 1;
+		}
+		break;
+
+	case BIO_C_GET_WRITE_BUF_SIZE:
+		ret = (long) b->size;
+		break;
+
+	case BIO_C_MAKE_BIO_PAIR:
+		{
+			BIO *other_bio = ptr;
+
+			if (bio_make_pair(bio, other_bio))
+				ret = 1;
+			else
+				ret = 0;
+		}
+		break;
+
+	case BIO_C_DESTROY_BIO_PAIR:
+		/* Affects both BIOs in the pair -- call just once!
+		 * Or let BIO_free(bio1); BIO_free(bio2); do the job. */
+		bio_destroy_pair(bio);
+		ret = 1;
+		break;
+
+	case BIO_C_GET_WRITE_GUARANTEE:
+		/* How many bytes can the caller feed to the next write
+		 * without having to keep any? */
+		if (b->peer == NULL || b->closed)
+			ret = 0;
+		else
+			ret = (long) b->size - b->len;
+		break;
+
+	case BIO_C_GET_READ_REQUEST:
+		/* If the peer unsuccessfully tried to read, how many bytes
+		 * were requested?  (As with BIO_CTRL_PENDING, that number
+		 * can usually be treated as boolean.) */
+		ret = (long) b->request;
+		break;
+
+	case BIO_C_RESET_READ_REQUEST:
+		/* Reset request.  (Can be useful after read attempts
+		 * at the other side that are meant to be non-blocking,
+		 * e.g. when probing SSL_read to see if any data is
+		 * available.) */
+		b->request = 0;
+		ret = 1;
+		break;
+
+	case BIO_C_SHUTDOWN_WR:
+		/* similar to shutdown(..., SHUT_WR) */
+		b->closed = 1;
+		ret = 1;
+		break;
+
+	case BIO_C_NREAD0:
+		/* prepare for non-copying read */
+		ret = (long) bio_nread0(bio, ptr);
+		break;
+
+	case BIO_C_NREAD:
+		/* non-copying read */
+		ret = (long) bio_nread(bio, ptr, (size_t) num);
+		break;
+
+	case BIO_C_NWRITE0:
+		/* prepare for non-copying write */
+		ret = (long) bio_nwrite0(bio, ptr);
+		break;
+
+	case BIO_C_NWRITE:
+		/* non-copying write */
+		ret = (long) bio_nwrite(bio, ptr, (size_t) num);
+		break;
+
+
+		/* standard CTRL codes follow */
+
+	case BIO_CTRL_RESET:
+		if (b->buf != NULL) {
+			b->len = 0;
+			b->offset = 0;
+		}
+		ret = 0;
+		break;
+
+
+	case BIO_CTRL_GET_CLOSE:
+		ret = bio->shutdown;
+		break;
+
+	case BIO_CTRL_SET_CLOSE:
+		bio->shutdown = (int) num;
+		ret = 1;
+		break;
+
+	case BIO_CTRL_PENDING:
+		if (b->peer != NULL) {
+			struct bio_bio_st *peer_b = b->peer->ptr;
+
+			ret = (long) peer_b->len;
+		} else
+			ret = 0;
+		break;
+
+	case BIO_CTRL_WPENDING:
+		if (b->buf != NULL)
+			ret = (long) b->len;
+		else
+			ret = 0;
+		break;
+
+	case BIO_CTRL_DUP:
+		/* See BIO_dup_chain for circumstances we have to expect. */
+		{
+			BIO *other_bio = ptr;
+			struct bio_bio_st *other_b;
+
+			assert(other_bio != NULL);
+			other_b = other_bio->ptr;
+			assert(other_b != NULL);
+
+			assert(other_b->buf == NULL); /* other_bio is always fresh */
+
+			other_b->size = b->size;
+		}
+
+		ret = 1;
+		break;
+
+	case BIO_CTRL_FLUSH:
+		ret = 1;
+		break;
+
+	case BIO_CTRL_EOF:
+		{
+			BIO *other_bio = ptr;
+
+			if (other_bio) {
+				struct bio_bio_st *other_b = other_bio->ptr;
+
+				assert(other_b != NULL);
+				ret = other_b->len == 0 && other_b->closed;
+			} else
+				ret = 1;
+		}
+		break;
+
+	default:
+		ret = 0;
+	}
+	return ret;
+}
+
+static int
+bio_puts(BIO *bio, const char *str)
+{
+	return bio_write(bio, str, strlen(str));
+}
+
+
+static int
+bio_make_pair(BIO *bio1, BIO *bio2)
+{
+	struct bio_bio_st *b1, *b2;
+
+	assert(bio1 != NULL);
+	assert(bio2 != NULL);
+
+	b1 = bio1->ptr;
+	b2 = bio2->ptr;
+
+	if (b1->peer != NULL || b2->peer != NULL) {
+		BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE);
+		return 0;
+	}
+
+	if (b1->buf == NULL) {
+		b1->buf = malloc(b1->size);
+		if (b1->buf == NULL) {
+			BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		b1->len = 0;
+		b1->offset = 0;
+	}
+
+	if (b2->buf == NULL) {
+		b2->buf = malloc(b2->size);
+		if (b2->buf == NULL) {
+			BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		b2->len = 0;
+		b2->offset = 0;
+	}
+
+	b1->peer = bio2;
+	b1->closed = 0;
+	b1->request = 0;
+	b2->peer = bio1;
+	b2->closed = 0;
+	b2->request = 0;
+
+	bio1->init = 1;
+	bio2->init = 1;
+
+	return 1;
+}
+
+static void
+bio_destroy_pair(BIO *bio)
+{
+	struct bio_bio_st *b = bio->ptr;
+
+	if (b != NULL) {
+		BIO *peer_bio = b->peer;
+
+		if (peer_bio != NULL) {
+			struct bio_bio_st *peer_b = peer_bio->ptr;
+
+			assert(peer_b != NULL);
+			assert(peer_b->peer == bio);
+
+			peer_b->peer = NULL;
+			peer_bio->init = 0;
+			assert(peer_b->buf != NULL);
+			peer_b->len = 0;
+			peer_b->offset = 0;
+
+			b->peer = NULL;
+			bio->init = 0;
+			assert(b->buf != NULL);
+			b->len = 0;
+			b->offset = 0;
+		}
+	}
+}
+
+
+/* Exported convenience functions */
+int
+BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, BIO **bio2_p, size_t writebuf2)
+{
+	BIO *bio1 = NULL, *bio2 = NULL;
+	long r;
+	int ret = 0;
+
+	bio1 = BIO_new(BIO_s_bio());
+	if (bio1 == NULL)
+		goto err;
+	bio2 = BIO_new(BIO_s_bio());
+	if (bio2 == NULL)
+		goto err;
+
+	if (writebuf1) {
+		r = BIO_set_write_buf_size(bio1, writebuf1);
+		if (!r)
+			goto err;
+	}
+	if (writebuf2) {
+		r = BIO_set_write_buf_size(bio2, writebuf2);
+		if (!r)
+			goto err;
+	}
+
+	r = BIO_make_bio_pair(bio1, bio2);
+	if (!r)
+		goto err;
+	ret = 1;
+
+	err:
+	if (ret == 0) {
+		if (bio1) {
+			BIO_free(bio1);
+			bio1 = NULL;
+		}
+		if (bio2) {
+			BIO_free(bio2);
+			bio2 = NULL;
+		}
+	}
+
+	*bio1_p = bio1;
+	*bio2_p = bio2;
+	return ret;
+}
+
+size_t
+BIO_ctrl_get_write_guarantee(BIO *bio)
+{
+	return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
+}
+
+size_t
+BIO_ctrl_get_read_request(BIO *bio)
+{
+	return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
+}
+
+int
+BIO_ctrl_reset_read_request(BIO *bio)
+{
+	return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
+}
+
+
+/* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
+ * (conceivably some other BIOs could allow non-copying reads and writes too.)
+ */
+int
+BIO_nread0(BIO *bio, char **buf)
+{
+	long ret;
+
+	if (!bio->init) {
+		BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED);
+		return -2;
+	}
+
+	ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf);
+	if (ret > INT_MAX)
+		return INT_MAX;
+	else
+		return (int) ret;
+}
+
+int
+BIO_nread(BIO *bio, char **buf, int num)
+{
+	int ret;
+
+	if (!bio->init) {
+		BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED);
+		return -2;
+	}
+
+	ret = (int) BIO_ctrl(bio, BIO_C_NREAD, num, buf);
+	if (ret > 0)
+		bio->num_read += ret;
+	return ret;
+}
+
+int
+BIO_nwrite0(BIO *bio, char **buf)
+{
+	long ret;
+
+	if (!bio->init) {
+		BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED);
+		return -2;
+	}
+
+	ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf);
+	if (ret > INT_MAX)
+		return INT_MAX;
+	else
+		return (int) ret;
+}
+
+int
+BIO_nwrite(BIO *bio, char **buf, int num)
+{
+	int ret;
+
+	if (!bio->init) {
+		BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED);
+		return -2;
+	}
+
+	ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
+	if (ret > 0)
+		bio->num_write += ret;
+	return ret;
+}
diff --git a/crypto/libressl/crypto/bio/bss_conn.c b/crypto/libressl/crypto/bio/bss_conn.c
new file mode 100644
index 0000000000..e3194a53a0
--- /dev/null
+++ b/crypto/libressl/crypto/bio/bss_conn.c
@@ -0,0 +1,604 @@
+/* $OpenBSD: bss_conn.c,v 1.31 2014/11/21 18:15:40 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#define SOCKET_PROTOCOL IPPROTO_TCP
+
+typedef struct bio_connect_st {
+	int state;
+
+	char *param_hostname;
+	char *param_port;
+	int nbio;
+
+	unsigned char ip[4];
+	unsigned short port;
+
+	struct sockaddr_in them;
+
+	/* int socket; this will be kept in bio->num so that it is
+	 * compatible with the bss_sock bio */ 
+
+	/* called when the connection is initially made
+	 *  callback(BIO,state,ret);  The callback should return
+	 * 'ret'.  state is for compatibility with the ssl info_callback */
+	int (*info_callback)(const BIO *bio, int state, int ret);
+} BIO_CONNECT;
+
+static int conn_write(BIO *h, const char *buf, int num);
+static int conn_read(BIO *h, char *buf, int size);
+static int conn_puts(BIO *h, const char *str);
+static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int conn_new(BIO *h);
+static int conn_free(BIO *data);
+static long conn_callback_ctrl(BIO *h, int cmd, bio_info_cb *);
+
+static int conn_state(BIO *b, BIO_CONNECT *c);
+static void conn_close_socket(BIO *data);
+BIO_CONNECT *BIO_CONNECT_new(void);
+void BIO_CONNECT_free(BIO_CONNECT *a);
+
+static BIO_METHOD methods_connectp = {
+	.type = BIO_TYPE_CONNECT,
+	.name = "socket connect",
+	.bwrite = conn_write,
+	.bread = conn_read,
+	.bputs = conn_puts,
+	.ctrl = conn_ctrl,
+	.create = conn_new,
+	.destroy = conn_free,
+	.callback_ctrl = conn_callback_ctrl
+};
+
+static int
+conn_state(BIO *b, BIO_CONNECT *c)
+{
+	int ret = -1, i;
+	unsigned long l;
+	char *p, *q;
+	int (*cb)(const BIO *, int, int) = NULL;
+
+	if (c->info_callback != NULL)
+		cb = c->info_callback;
+
+	for (;;) {
+		switch (c->state) {
+		case BIO_CONN_S_BEFORE:
+			p = c->param_hostname;
+			if (p == NULL) {
+				BIOerr(BIO_F_CONN_STATE, BIO_R_NO_HOSTNAME_SPECIFIED);
+				goto exit_loop;
+			}
+			for (; *p != '\0'; p++) {
+				if ((*p == ':') || (*p == '/'))
+				break;
+			}
+
+			i= *p;
+			if ((i == ':') || (i == '/')) {
+				*(p++) = '\0';
+				if (i == ':') {
+					for (q = p; *q; q++)
+						if (*q == '/') {
+							*q = '\0';
+							break;
+						}
+					free(c->param_port);
+					c->param_port = strdup(p);
+				}
+			}
+
+			if (c->param_port == NULL) {
+				BIOerr(BIO_F_CONN_STATE, BIO_R_NO_PORT_SPECIFIED);
+				ERR_asprintf_error_data("host=%s",
+				    c->param_hostname);
+				goto exit_loop;
+			}
+			c->state = BIO_CONN_S_GET_IP;
+			break;
+
+		case BIO_CONN_S_GET_IP:
+			if (BIO_get_host_ip(c->param_hostname, &(c->ip[0])) <= 0)
+				goto exit_loop;
+			c->state = BIO_CONN_S_GET_PORT;
+			break;
+
+		case BIO_CONN_S_GET_PORT:
+			if (c->param_port == NULL) {
+				/* abort(); */
+				goto exit_loop;
+			} else if (BIO_get_port(c->param_port, &c->port) <= 0)
+				goto exit_loop;
+			c->state = BIO_CONN_S_CREATE_SOCKET;
+			break;
+
+		case BIO_CONN_S_CREATE_SOCKET:
+			/* now setup address */
+			memset((char *)&c->them, 0, sizeof(c->them));
+			c->them.sin_family = AF_INET;
+			c->them.sin_port = htons((unsigned short)c->port);
+			l = (unsigned long)
+			    ((unsigned long)c->ip[0] << 24L)|
+			    ((unsigned long)c->ip[1] << 16L)|
+			    ((unsigned long)c->ip[2] << 8L)|
+			    ((unsigned long)c->ip[3]);
+			c->them.sin_addr.s_addr = htonl(l);
+			c->state = BIO_CONN_S_CREATE_SOCKET;
+
+			ret = socket(AF_INET, SOCK_STREAM, SOCKET_PROTOCOL);
+			if (ret == -1) {
+				SYSerr(SYS_F_SOCKET, errno);
+				ERR_asprintf_error_data("host=%s:%s",
+				    c->param_hostname, c->param_port);
+				BIOerr(BIO_F_CONN_STATE,
+				    BIO_R_UNABLE_TO_CREATE_SOCKET);
+				goto exit_loop;
+			}
+			b->num = ret;
+			c->state = BIO_CONN_S_NBIO;
+			break;
+
+		case BIO_CONN_S_NBIO:
+			if (c->nbio) {
+				if (!BIO_socket_nbio(b->num, 1)) {
+					BIOerr(BIO_F_CONN_STATE,
+					    BIO_R_ERROR_SETTING_NBIO);
+					ERR_asprintf_error_data("host=%s:%s",
+					    c->param_hostname, c->param_port);
+					goto exit_loop;
+				}
+			}
+			c->state = BIO_CONN_S_CONNECT;
+
+#if defined(SO_KEEPALIVE)
+			i = 1;
+			i = setsockopt(b->num, SOL_SOCKET, SO_KEEPALIVE, &i, sizeof(i));
+			if (i < 0) {
+				SYSerr(SYS_F_SOCKET, errno);
+				ERR_asprintf_error_data("host=%s:%s",
+				    c->param_hostname, c->param_port);
+				BIOerr(BIO_F_CONN_STATE, BIO_R_KEEPALIVE);
+				goto exit_loop;
+			}
+#endif
+			break;
+
+		case BIO_CONN_S_CONNECT:
+			BIO_clear_retry_flags(b);
+			ret = connect(b->num,
+			(struct sockaddr *)&c->them,
+			sizeof(c->them));
+			b->retry_reason = 0;
+			if (ret < 0) {
+				if (BIO_sock_should_retry(ret)) {
+					BIO_set_retry_special(b);
+					c->state = BIO_CONN_S_BLOCKED_CONNECT;
+					b->retry_reason = BIO_RR_CONNECT;
+				} else {
+					SYSerr(SYS_F_CONNECT, errno);
+					ERR_asprintf_error_data("host=%s:%s",
+					    c->param_hostname, c->param_port);
+					BIOerr(BIO_F_CONN_STATE,
+					    BIO_R_CONNECT_ERROR);
+				}
+				goto exit_loop;
+			} else
+				c->state = BIO_CONN_S_OK;
+			break;
+
+		case BIO_CONN_S_BLOCKED_CONNECT:
+			i = BIO_sock_error(b->num);
+			if (i) {
+				BIO_clear_retry_flags(b);
+				SYSerr(SYS_F_CONNECT, i);
+				ERR_asprintf_error_data("host=%s:%s",
+				    c->param_hostname, c->param_port);
+				BIOerr(BIO_F_CONN_STATE,
+				    BIO_R_NBIO_CONNECT_ERROR);
+				ret = 0;
+				goto exit_loop;
+			} else
+				c->state = BIO_CONN_S_OK;
+			break;
+
+		case BIO_CONN_S_OK:
+			ret = 1;
+			goto exit_loop;
+		default:
+			/* abort(); */
+			goto exit_loop;
+		}
+
+		if (cb != NULL) {
+			if (!(ret = cb((BIO *)b, c->state, ret)))
+				goto end;
+		}
+	}
+
+	/* Loop does not exit */
+exit_loop:
+	if (cb != NULL)
+		ret = cb((BIO *)b, c->state, ret);
+end:
+	return (ret);
+}
+
+BIO_CONNECT *
+BIO_CONNECT_new(void)
+{
+	BIO_CONNECT *ret;
+
+	if ((ret = malloc(sizeof(BIO_CONNECT))) == NULL)
+		return (NULL);
+	ret->state = BIO_CONN_S_BEFORE;
+	ret->param_hostname = NULL;
+	ret->param_port = NULL;
+	ret->info_callback = NULL;
+	ret->nbio = 0;
+	ret->ip[0] = 0;
+	ret->ip[1] = 0;
+	ret->ip[2] = 0;
+	ret->ip[3] = 0;
+	ret->port = 0;
+	memset((char *)&ret->them, 0, sizeof(ret->them));
+	return (ret);
+}
+
+void
+BIO_CONNECT_free(BIO_CONNECT *a)
+{
+	if (a == NULL)
+		return;
+
+	free(a->param_hostname);
+	free(a->param_port);
+	free(a);
+}
+
+BIO_METHOD *
+BIO_s_connect(void)
+{
+	return (&methods_connectp);
+}
+
+static int
+conn_new(BIO *bi)
+{
+	bi->init = 0;
+	bi->num = -1;
+	bi->flags = 0;
+	if ((bi->ptr = (char *)BIO_CONNECT_new()) == NULL)
+		return (0);
+	else
+		return (1);
+}
+
+static void
+conn_close_socket(BIO *bio)
+{
+	BIO_CONNECT *c;
+
+	c = (BIO_CONNECT *)bio->ptr;
+	if (bio->num != -1) {
+		/* Only do a shutdown if things were established */
+		if (c->state == BIO_CONN_S_OK)
+			shutdown(bio->num, SHUT_RDWR);
+		close(bio->num);
+		bio->num = -1;
+	}
+}
+
+static int
+conn_free(BIO *a)
+{
+	BIO_CONNECT *data;
+
+	if (a == NULL)
+		return (0);
+	data = (BIO_CONNECT *)a->ptr;
+
+	if (a->shutdown) {
+		conn_close_socket(a);
+		BIO_CONNECT_free(data);
+		a->ptr = NULL;
+		a->flags = 0;
+		a->init = 0;
+	}
+	return (1);
+}
+
+static int
+conn_read(BIO *b, char *out, int outl)
+{
+	int ret = 0;
+	BIO_CONNECT *data;
+
+	data = (BIO_CONNECT *)b->ptr;
+	if (data->state != BIO_CONN_S_OK) {
+		ret = conn_state(b, data);
+		if (ret <= 0)
+			return (ret);
+	}
+
+	if (out != NULL) {
+		errno = 0;
+		ret = read(b->num, out, outl);
+		BIO_clear_retry_flags(b);
+		if (ret <= 0) {
+			if (BIO_sock_should_retry(ret))
+				BIO_set_retry_read(b);
+		}
+	}
+	return (ret);
+}
+
+static int
+conn_write(BIO *b, const char *in, int inl)
+{
+	int ret;
+	BIO_CONNECT *data;
+
+	data = (BIO_CONNECT *)b->ptr;
+	if (data->state != BIO_CONN_S_OK) {
+		ret = conn_state(b, data);
+		if (ret <= 0)
+			return (ret);
+	}
+
+	errno = 0;
+	ret = write(b->num, in, inl);
+	BIO_clear_retry_flags(b);
+	if (ret <= 0) {
+		if (BIO_sock_should_retry(ret))
+			BIO_set_retry_write(b);
+	}
+	return (ret);
+}
+
+static long
+conn_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+	BIO *dbio;
+	int *ip;
+	const char **pptr;
+	long ret = 1;
+	BIO_CONNECT *data;
+
+	data = (BIO_CONNECT *)b->ptr;
+
+	switch (cmd) {
+	case BIO_CTRL_RESET:
+		ret = 0;
+		data->state = BIO_CONN_S_BEFORE;
+		conn_close_socket(b);
+		b->flags = 0;
+		break;
+	case BIO_C_DO_STATE_MACHINE:
+		/* use this one to start the connection */
+		if (data->state != BIO_CONN_S_OK)
+			ret = (long)conn_state(b, data);
+		else
+			ret = 1;
+		break;
+	case BIO_C_GET_CONNECT:
+		if (ptr != NULL) {
+			pptr = (const char **)ptr;
+			if (num == 0) {
+				*pptr = data->param_hostname;
+
+			} else if (num == 1) {
+				*pptr = data->param_port;
+			} else if (num == 2) {
+				*pptr = (char *)&(data->ip[0]);
+			} else if (num == 3) {
+				*((int *)ptr) = data->port;
+			}
+			if ((!b->init) || (ptr == NULL))
+				*pptr = "not initialized";
+			ret = 1;
+		}
+		break;
+	case BIO_C_SET_CONNECT:
+		if (ptr != NULL) {
+			b->init = 1;
+			if (num == 0) {
+				free(data->param_hostname);
+				data->param_hostname = strdup(ptr);
+			} else if (num == 1) {
+				free(data->param_port);
+				data->param_port = strdup(ptr);
+			} else if (num == 2) {
+				unsigned char *p = ptr;
+				free(data->param_hostname);
+				if (asprintf(&data->param_hostname,
+					"%u.%u.%u.%u", p[0], p[1],
+					p[2], p[3]) == -1)
+					data->param_hostname = NULL;
+				memcpy(&(data->ip[0]), ptr, 4);
+			} else if (num == 3) {
+				free(data->param_port);
+				data->port= *(int *)ptr;
+				if (asprintf(&data->param_port, "%d",
+					data->port) == -1)
+					data->param_port = NULL;
+			}
+		}
+		break;
+	case BIO_C_SET_NBIO:
+		data->nbio = (int)num;
+		break;
+	case BIO_C_GET_FD:
+		if (b->init) {
+			ip = (int *)ptr;
+			if (ip != NULL)
+				*ip = b->num;
+			ret = b->num;
+		} else
+			ret = -1;
+		break;
+	case BIO_CTRL_GET_CLOSE:
+		ret = b->shutdown;
+		break;
+	case BIO_CTRL_SET_CLOSE:
+		b->shutdown = (int)num;
+		break;
+	case BIO_CTRL_PENDING:
+	case BIO_CTRL_WPENDING:
+		ret = 0;
+		break;
+	case BIO_CTRL_FLUSH:
+		break;
+	case BIO_CTRL_DUP:
+		{
+			dbio = (BIO *)ptr;
+			if (data->param_port)
+				BIO_set_conn_port(dbio, data->param_port);
+			if (data->param_hostname)
+				BIO_set_conn_hostname(dbio,
+				    data->param_hostname);
+			BIO_set_nbio(dbio, data->nbio);
+			/* FIXME: the cast of the function seems unlikely to be a good idea */
+			(void)BIO_set_info_callback(dbio,
+			    (bio_info_cb *)data->info_callback);
+		}
+		break;
+	case BIO_CTRL_SET_CALLBACK:
+		{
+#if 0 /* FIXME: Should this be used?  -- Richard Levitte */
+			BIOerr(BIO_F_CONN_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+			ret = -1;
+#else
+			ret = 0;
+#endif
+		}
+		break;
+	case BIO_CTRL_GET_CALLBACK:
+		{
+			int (**fptr)(const BIO *bio, int state, int xret);
+
+			fptr = (int (**)(const BIO *bio, int state, int xret))ptr;
+			*fptr = data->info_callback;
+		}
+		break;
+	default:
+		ret = 0;
+		break;
+	}
+	return (ret);
+}
+
+static long
+conn_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+	long ret = 1;
+	BIO_CONNECT *data;
+
+	data = (BIO_CONNECT *)b->ptr;
+
+	switch (cmd) {
+	case BIO_CTRL_SET_CALLBACK:
+		{
+			data->info_callback = (int (*)(const struct bio_st *, int, int))fp;
+		}
+		break;
+	default:
+		ret = 0;
+		break;
+	}
+	return (ret);
+}
+
+static int
+conn_puts(BIO *bp, const char *str)
+{
+	int n, ret;
+
+	n = strlen(str);
+	ret = conn_write(bp, str, n);
+	return (ret);
+}
+
+BIO *
+BIO_new_connect(char *str)
+{
+	BIO *ret;
+
+	ret = BIO_new(BIO_s_connect());
+	if (ret == NULL)
+		return (NULL);
+	if (BIO_set_conn_hostname(ret, str))
+		return (ret);
+	else {
+		BIO_free(ret);
+		return (NULL);
+	}
+}
+
diff --git a/crypto/libressl/crypto/bio/bss_dgram.c b/crypto/libressl/crypto/bio/bss_dgram.c
new file mode 100644
index 0000000000..d510ed83a6
--- /dev/null
+++ b/crypto/libressl/crypto/bio/bss_dgram.c
@@ -0,0 +1,658 @@
+/* $OpenBSD: bss_dgram.c,v 1.40 2015/02/09 10:55:33 jsing Exp $ */
+/* 
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_DGRAM
+
+
+static int dgram_write(BIO *h, const char *buf, int num);
+static int dgram_read(BIO *h, char *buf, int size);
+static int dgram_puts(BIO *h, const char *str);
+static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int dgram_new(BIO *h);
+static int dgram_free(BIO *data);
+static int dgram_clear(BIO *bio);
+
+
+static int BIO_dgram_should_retry(int s);
+
+static BIO_METHOD methods_dgramp = {
+	.type = BIO_TYPE_DGRAM,
+	.name = "datagram socket",
+	.bwrite = dgram_write,
+	.bread = dgram_read,
+	.bputs = dgram_puts,
+	.ctrl = dgram_ctrl,
+	.create = dgram_new,
+	.destroy = dgram_free
+};
+
+
+typedef struct bio_dgram_data_st {
+	union {
+		struct sockaddr sa;
+		struct sockaddr_in sa_in;
+		struct sockaddr_in6 sa_in6;
+	} peer;
+	unsigned int connected;
+	unsigned int _errno;
+	unsigned int mtu;
+	struct timeval next_timeout;
+	struct timeval socket_timeout;
+} bio_dgram_data;
+
+
+BIO_METHOD *
+BIO_s_datagram(void)
+{
+	return (&methods_dgramp);
+}
+
+BIO *
+BIO_new_dgram(int fd, int close_flag)
+{
+	BIO *ret;
+
+	ret = BIO_new(BIO_s_datagram());
+	if (ret == NULL)
+		return (NULL);
+	BIO_set_fd(ret, fd, close_flag);
+	return (ret);
+}
+
+static int
+dgram_new(BIO *bi)
+{
+	bio_dgram_data *data = NULL;
+
+	bi->init = 0;
+	bi->num = 0;
+	data = calloc(1, sizeof(bio_dgram_data));
+	if (data == NULL)
+		return 0;
+	bi->ptr = data;
+
+	bi->flags = 0;
+	return (1);
+}
+
+static int
+dgram_free(BIO *a)
+{
+	bio_dgram_data *data;
+
+	if (a == NULL)
+		return (0);
+	if (!dgram_clear(a))
+		return 0;
+
+	data = (bio_dgram_data *)a->ptr;
+	free(data);
+
+	return (1);
+}
+
+static int
+dgram_clear(BIO *a)
+{
+	if (a == NULL)
+		return (0);
+	if (a->shutdown) {
+		if (a->init) {
+			shutdown(a->num, SHUT_RDWR);
+			close(a->num);
+		}
+		a->init = 0;
+		a->flags = 0;
+	}
+	return (1);
+}
+
+static void
+dgram_adjust_rcv_timeout(BIO *b)
+{
+#if defined(SO_RCVTIMEO)
+	bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+
+	/* Is a timer active? */
+	if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
+		struct timeval timenow, timeleft;
+
+		/* Read current socket timeout */
+		socklen_t sz = sizeof(data->socket_timeout);
+		if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+		    &(data->socket_timeout), &sz) < 0) {
+			perror("getsockopt");
+		}
+
+		/* Get current time */
+		gettimeofday(&timenow, NULL);
+
+		/* Calculate time left until timer expires */
+		memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval));
+		timeleft.tv_sec -= timenow.tv_sec;
+		timeleft.tv_usec -= timenow.tv_usec;
+		if (timeleft.tv_usec < 0) {
+			timeleft.tv_sec--;
+			timeleft.tv_usec += 1000000;
+		}
+
+		if (timeleft.tv_sec < 0) {
+			timeleft.tv_sec = 0;
+			timeleft.tv_usec = 1;
+		}
+
+		/* Adjust socket timeout if next handhake message timer
+		 * will expire earlier.
+		 */
+		if ((data->socket_timeout.tv_sec == 0 &&
+		    data->socket_timeout.tv_usec == 0) ||
+		    (data->socket_timeout.tv_sec > timeleft.tv_sec) ||
+		    (data->socket_timeout.tv_sec == timeleft.tv_sec &&
+		    data->socket_timeout.tv_usec >= timeleft.tv_usec)) {
+			if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+			    &timeleft, sizeof(struct timeval)) < 0) {
+				perror("setsockopt");
+			}
+		}
+	}
+#endif
+}
+
+static void
+dgram_reset_rcv_timeout(BIO *b)
+{
+#if defined(SO_RCVTIMEO)
+	bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+
+	/* Is a timer active? */
+	if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
+		if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+		    &(data->socket_timeout), sizeof(struct timeval)) < 0) {
+			perror("setsockopt");
+		}
+	}
+#endif
+}
+
+static int
+dgram_read(BIO *b, char *out, int outl)
+{
+	int ret = 0;
+	bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+
+	struct	{
+		socklen_t len;
+		union	{
+			struct sockaddr sa;
+			struct sockaddr_in sa_in;
+			struct sockaddr_in6 sa_in6;
+		} peer;
+	} sa;
+
+	sa.len = sizeof(sa.peer);
+
+	if (out != NULL) {
+		errno = 0;
+		memset(&sa.peer, 0, sizeof(sa.peer));
+		dgram_adjust_rcv_timeout(b);
+		ret = recvfrom(b->num, out, outl, 0, &sa.peer.sa, &sa.len);
+
+		if (! data->connected  && ret >= 0)
+			BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer);
+
+		BIO_clear_retry_flags(b);
+		if (ret < 0) {
+			if (BIO_dgram_should_retry(ret)) {
+				BIO_set_retry_read(b);
+				data->_errno = errno;
+			}
+		}
+
+		dgram_reset_rcv_timeout(b);
+	}
+	return (ret);
+}
+
+static int
+dgram_write(BIO *b, const char *in, int inl)
+{
+	int ret;
+	bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+	errno = 0;
+
+	if (data->connected)
+		ret = write(b->num, in, inl);
+	else {
+		int peerlen = sizeof(data->peer);
+
+		if (data->peer.sa.sa_family == AF_INET)
+			peerlen = sizeof(data->peer.sa_in);
+		else if (data->peer.sa.sa_family == AF_INET6)
+			peerlen = sizeof(data->peer.sa_in6);
+		ret = sendto(b->num, in, inl, 0, &data->peer.sa, peerlen);
+	}
+
+	BIO_clear_retry_flags(b);
+	if (ret <= 0) {
+		if (BIO_dgram_should_retry(ret)) {
+			BIO_set_retry_write(b);
+
+			data->_errno = errno;
+			/*
+			 * higher layers are responsible for querying MTU,
+			 * if necessary
+			 */
+		}
+	}
+	return (ret);
+}
+
+static long
+dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+	long ret = 1;
+	int *ip;
+	struct sockaddr *to = NULL;
+	bio_dgram_data *data = NULL;
+#if (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
+	int sockopt_val = 0;
+	socklen_t sockopt_len;	/* assume that system supporting IP_MTU is
+				 * modern enough to define socklen_t */
+	socklen_t addr_len;
+	union	{
+		struct sockaddr	sa;
+		struct sockaddr_in s4;
+		struct sockaddr_in6 s6;
+	} addr;
+#endif
+
+	data = (bio_dgram_data *)b->ptr;
+
+	switch (cmd) {
+	case BIO_CTRL_RESET:
+		num = 0;
+	case BIO_C_FILE_SEEK:
+		ret = 0;
+		break;
+	case BIO_C_FILE_TELL:
+	case BIO_CTRL_INFO:
+		ret = 0;
+		break;
+	case BIO_C_SET_FD:
+		dgram_clear(b);
+		b->num= *((int *)ptr);
+		b->shutdown = (int)num;
+		b->init = 1;
+		break;
+	case BIO_C_GET_FD:
+		if (b->init) {
+			ip = (int *)ptr;
+			if (ip != NULL)
+				*ip = b->num;
+			ret = b->num;
+		} else
+			ret = -1;
+		break;
+	case BIO_CTRL_GET_CLOSE:
+		ret = b->shutdown;
+		break;
+	case BIO_CTRL_SET_CLOSE:
+		b->shutdown = (int)num;
+		break;
+	case BIO_CTRL_PENDING:
+	case BIO_CTRL_WPENDING:
+		ret = 0;
+		break;
+	case BIO_CTRL_DUP:
+	case BIO_CTRL_FLUSH:
+		ret = 1;
+		break;
+	case BIO_CTRL_DGRAM_CONNECT:
+		to = (struct sockaddr *)ptr;
+		switch (to->sa_family) {
+		case AF_INET:
+			memcpy(&data->peer, to, sizeof(data->peer.sa_in));
+			break;
+		case AF_INET6:
+			memcpy(&data->peer, to, sizeof(data->peer.sa_in6));
+			break;
+		default:
+			memcpy(&data->peer, to, sizeof(data->peer.sa));
+			break;
+		}
+		break;
+		/* (Linux)kernel sets DF bit on outgoing IP packets */
+	case BIO_CTRL_DGRAM_MTU_DISCOVER:
+#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
+		addr_len = (socklen_t)sizeof(addr);
+		memset((void *)&addr, 0, sizeof(addr));
+		if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
+			ret = 0;
+			break;
+		}
+		switch (addr.sa.sa_family) {
+		case AF_INET:
+			sockopt_val = IP_PMTUDISC_DO;
+			ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
+			    &sockopt_val, sizeof(sockopt_val));
+			if (ret < 0)
+				perror("setsockopt");
+			break;
+#if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
+		case AF_INET6:
+			sockopt_val = IPV6_PMTUDISC_DO;
+			ret = setsockopt(b->num, IPPROTO_IPV6,
+			    IPV6_MTU_DISCOVER, &sockopt_val,
+			    sizeof(sockopt_val));
+			if (ret < 0)
+				perror("setsockopt");
+			break;
+#endif
+		default:
+			ret = -1;
+			break;
+		}
+#else
+		ret = -1;
+#endif
+		break;
+	case BIO_CTRL_DGRAM_QUERY_MTU:
+#if defined(IP_MTU)
+		addr_len = (socklen_t)sizeof(addr);
+		memset((void *)&addr, 0, sizeof(addr));
+		if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
+			ret = 0;
+			break;
+		}
+		sockopt_len = sizeof(sockopt_val);
+		switch (addr.sa.sa_family) {
+		case AF_INET:
+			ret = getsockopt(b->num, IPPROTO_IP, IP_MTU,
+			    &sockopt_val, &sockopt_len);
+			if (ret < 0 || sockopt_val < 0) {
+				ret = 0;
+			} else {
+				/* we assume that the transport protocol is UDP and no
+				 * IP options are used.
+				 */
+				data->mtu = sockopt_val - 8 - 20;
+				ret = data->mtu;
+			}
+			break;
+#if defined(IPV6_MTU)
+		case AF_INET6:
+			ret = getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU,
+			    &sockopt_val, &sockopt_len);
+			if (ret < 0 || sockopt_val < 0) {
+				ret = 0;
+			} else {
+				/* we assume that the transport protocol is UDP and no
+				 * IPV6 options are used.
+				 */
+				data->mtu = sockopt_val - 8 - 40;
+				ret = data->mtu;
+			}
+			break;
+#endif
+default:
+			ret = 0;
+			break;
+		}
+#else
+		ret = 0;
+#endif
+		break;
+	case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
+		switch (data->peer.sa.sa_family) {
+		case AF_INET:
+			ret = 576 - 20 - 8;
+			break;
+		case AF_INET6:
+#ifdef IN6_IS_ADDR_V4MAPPED
+			if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr))
+				ret = 576 - 20 - 8;
+			else
+#endif
+				ret = 1280 - 40 - 8;
+			break;
+		default:
+			ret = 576 - 20 - 8;
+			break;
+		}
+		break;
+	case BIO_CTRL_DGRAM_GET_MTU:
+		return data->mtu;
+		break;
+	case BIO_CTRL_DGRAM_SET_MTU:
+		data->mtu = num;
+		ret = num;
+		break;
+	case BIO_CTRL_DGRAM_SET_CONNECTED:
+		to = (struct sockaddr *)ptr;
+
+		if (to != NULL) {
+			data->connected = 1;
+			switch (to->sa_family) {
+			case AF_INET:
+				memcpy(&data->peer, to, sizeof(data->peer.sa_in));
+				break;
+			case AF_INET6:
+				memcpy(&data->peer, to, sizeof(data->peer.sa_in6));
+				break;
+			default:
+				memcpy(&data->peer, to, sizeof(data->peer.sa));
+				break;
+			}
+		} else {
+			data->connected = 0;
+			memset(&(data->peer), 0, sizeof(data->peer));
+		}
+		break;
+	case BIO_CTRL_DGRAM_GET_PEER:
+		switch (data->peer.sa.sa_family) {
+		case AF_INET:
+			ret = sizeof(data->peer.sa_in);
+			break;
+		case AF_INET6:
+			ret = sizeof(data->peer.sa_in6);
+			break;
+		default:
+			ret = sizeof(data->peer.sa);
+			break;
+		}
+		if (num == 0 || num > ret)
+			num = ret;
+		memcpy(ptr, &data->peer, (ret = num));
+		break;
+	case BIO_CTRL_DGRAM_SET_PEER:
+		to = (struct sockaddr *) ptr;
+		switch (to->sa_family) {
+		case AF_INET:
+			memcpy(&data->peer, to, sizeof(data->peer.sa_in));
+			break;
+		case AF_INET6:
+			memcpy(&data->peer, to, sizeof(data->peer.sa_in6));
+			break;
+		default:
+			memcpy(&data->peer, to, sizeof(data->peer.sa));
+			break;
+		}
+		break;
+	case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
+		memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
+		break;
+#if defined(SO_RCVTIMEO)
+	case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
+		if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
+		    sizeof(struct timeval)) < 0) {
+			perror("setsockopt");
+			ret = -1;
+		}
+		break;
+	case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
+		{
+			socklen_t sz = sizeof(struct timeval);
+			if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+			    ptr, &sz) < 0) {
+				perror("getsockopt");
+				ret = -1;
+			} else
+				ret = sz;
+		}
+		break;
+#endif
+#if defined(SO_SNDTIMEO)
+	case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
+		if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
+		    sizeof(struct timeval)) < 0) {
+			perror("setsockopt");
+			ret = -1;
+		}
+		break;
+	case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
+		{
+			socklen_t sz = sizeof(struct timeval);
+			if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
+			    ptr, &sz) < 0) {
+				perror("getsockopt");
+				ret = -1;
+			} else
+				ret = sz;
+		}
+		break;
+#endif
+	case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
+		/* fall-through */
+	case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
+		if (data->_errno == EAGAIN) {
+			ret = 1;
+			data->_errno = 0;
+		} else
+			ret = 0;
+		break;
+#ifdef EMSGSIZE
+	case BIO_CTRL_DGRAM_MTU_EXCEEDED:
+		if (data->_errno == EMSGSIZE) {
+			ret = 1;
+			data->_errno = 0;
+		} else
+			ret = 0;
+		break;
+#endif
+	default:
+		ret = 0;
+		break;
+	}
+	return (ret);
+}
+
+static int
+dgram_puts(BIO *bp, const char *str)
+{
+	int n, ret;
+
+	n = strlen(str);
+	ret = dgram_write(bp, str, n);
+	return (ret);
+}
+
+
+static int
+BIO_dgram_should_retry(int i)
+{
+	int err;
+
+	if ((i == 0) || (i == -1)) {
+		err = errno;
+		return (BIO_dgram_non_fatal_error(err));
+	}
+	return (0);
+}
+
+int
+BIO_dgram_non_fatal_error(int err)
+{
+	switch (err) {
+	case EINTR:
+	case EAGAIN:
+	case EINPROGRESS:
+	case EALREADY:
+		return (1);
+	default:
+		break;
+	}
+	return (0);
+}
+
+#endif
diff --git a/crypto/libressl/crypto/bio/bss_fd.c b/crypto/libressl/crypto/bio/bss_fd.c
new file mode 100644
index 0000000000..c86dcc9a28
--- /dev/null
+++ b/crypto/libressl/crypto/bio/bss_fd.c
@@ -0,0 +1,267 @@
+/* $OpenBSD: bss_fd.c,v 1.17 2014/07/11 08:44:47 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+
+static int fd_write(BIO *h, const char *buf, int num);
+static int fd_read(BIO *h, char *buf, int size);
+static int fd_puts(BIO *h, const char *str);
+static int fd_gets(BIO *h, char *buf, int size);
+static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int fd_new(BIO *h);
+static int fd_free(BIO *data);
+int BIO_fd_should_retry(int s);
+
+static BIO_METHOD methods_fdp = {
+	.type = BIO_TYPE_FD,
+	.name = "file descriptor",
+	.bwrite = fd_write,
+	.bread = fd_read,
+	.bputs = fd_puts,
+	.bgets = fd_gets,
+	.ctrl = fd_ctrl,
+	.create = fd_new,
+	.destroy = fd_free
+};
+
+BIO_METHOD *
+BIO_s_fd(void)
+{
+	return (&methods_fdp);
+}
+
+BIO *
+BIO_new_fd(int fd, int close_flag)
+{
+	BIO *ret;
+	ret = BIO_new(BIO_s_fd());
+	if (ret == NULL)
+		return (NULL);
+	BIO_set_fd(ret, fd, close_flag);
+	return (ret);
+}
+
+static int
+fd_new(BIO *bi)
+{
+	bi->init = 0;
+	bi->num = -1;
+	bi->ptr = NULL;
+	bi->flags=0;
+	return (1);
+}
+
+static int
+fd_free(BIO *a)
+{
+	if (a == NULL)
+		return (0);
+	if (a->shutdown) {
+		if (a->init) {
+			close(a->num);
+		}
+		a->init = 0;
+		a->flags = 0;
+	}
+	return (1);
+}
+
+static int
+fd_read(BIO *b, char *out, int outl)
+{
+	int ret = 0;
+
+	if (out != NULL) {
+		errno = 0;
+		ret = read(b->num, out, outl);
+		BIO_clear_retry_flags(b);
+		if (ret <= 0) {
+			if (BIO_fd_should_retry(ret))
+				BIO_set_retry_read(b);
+		}
+	}
+	return (ret);
+}
+
+static int
+fd_write(BIO *b, const char *in, int inl)
+{
+	int ret;
+	errno = 0;
+	ret = write(b->num, in, inl);
+	BIO_clear_retry_flags(b);
+	if (ret <= 0) {
+		if (BIO_fd_should_retry(ret))
+			BIO_set_retry_write(b);
+	}
+	return (ret);
+}
+
+static long
+fd_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+	long ret = 1;
+	int *ip;
+
+	switch (cmd) {
+	case BIO_CTRL_RESET:
+		num = 0;
+	case BIO_C_FILE_SEEK:
+		ret = (long)lseek(b->num, num, 0);
+		break;
+	case BIO_C_FILE_TELL:
+	case BIO_CTRL_INFO:
+		ret = (long)lseek(b->num, 0, 1);
+		break;
+	case BIO_C_SET_FD:
+		fd_free(b);
+		b->num= *((int *)ptr);
+		b->shutdown = (int)num;
+		b->init = 1;
+		break;
+	case BIO_C_GET_FD:
+		if (b->init) {
+			ip = (int *)ptr;
+			if (ip != NULL)
+				*ip = b->num;
+			ret = b->num;
+		} else
+			ret = -1;
+		break;
+	case BIO_CTRL_GET_CLOSE:
+		ret = b->shutdown;
+		break;
+	case BIO_CTRL_SET_CLOSE:
+		b->shutdown = (int)num;
+		break;
+	case BIO_CTRL_PENDING:
+	case BIO_CTRL_WPENDING:
+		ret = 0;
+		break;
+	case BIO_CTRL_DUP:
+	case BIO_CTRL_FLUSH:
+		ret = 1;
+		break;
+	default:
+		ret = 0;
+		break;
+	}
+	return (ret);
+}
+
+static int
+fd_puts(BIO *bp, const char *str)
+{
+	int n, ret;
+
+	n = strlen(str);
+	ret = fd_write(bp, str, n);
+	return (ret);
+}
+
+static int
+fd_gets(BIO *bp, char *buf, int size)
+{
+	int ret = 0;
+	char *ptr = buf;
+	char *end = buf + size - 1;
+
+	while ((ptr < end) && (fd_read(bp, ptr, 1) > 0) && (ptr[0] != '\n'))
+		ptr++;
+
+	ptr[0] = '\0';
+
+	if (buf[0] != '\0')
+		ret = strlen(buf);
+	return (ret);
+}
+
+int
+BIO_fd_should_retry(int i)
+{
+	int err;
+
+	if ((i == 0) || (i == -1)) {
+		err = errno;
+		return (BIO_fd_non_fatal_error(err));
+	}
+	return (0);
+}
+
+int
+BIO_fd_non_fatal_error(int err)
+{
+	switch (err) {
+	case ENOTCONN:
+	case EINTR:
+	case EAGAIN:
+	case EINPROGRESS:
+	case EALREADY:
+		return (1);
+	default:
+		break;
+	}
+	return (0);
+}
diff --git a/crypto/libressl/crypto/bio/bss_file.c b/crypto/libressl/crypto/bio/bss_file.c
new file mode 100644
index 0000000000..ad77b5b712
--- /dev/null
+++ b/crypto/libressl/crypto/bio/bss_file.c
@@ -0,0 +1,320 @@
+/* $OpenBSD: bss_file.c,v 1.30 2014/07/11 08:44:47 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/*
+ * 03-Dec-1997	rdenny@dc3.com  Fix bug preventing use of stdin/stdout
+ *		with binary data (e.g. asn1parse -inform DER < xxx) under
+ *		Windows
+ */
+
+#ifndef HEADER_BSS_FILE_C
+#define HEADER_BSS_FILE_C
+
+#if defined(__linux) || defined(__sun) || defined(__hpux)
+/* Following definition aliases fopen to fopen64 on above mentioned
+ * platforms. This makes it possible to open and sequentially access
+ * files larger than 2GB from 32-bit application. It does not allow to
+ * traverse them beyond 2GB with fseek/ftell, but on the other hand *no*
+ * 32-bit platform permits that, not with fseek/ftell. Not to mention
+ * that breaking 2GB limit for seeking would require surgery to *our*
+ * API. But sequential access suffices for practical cases when you
+ * can run into large files, such as fingerprinting, so we can let API
+ * alone. For reference, the list of 32-bit platforms which allow for
+ * sequential access of large files without extra "magic" comprise *BSD,
+ * Darwin, IRIX...
+ */
+#ifndef _FILE_OFFSET_BITS
+#define _FILE_OFFSET_BITS 64
+#endif
+#endif
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+static int file_write(BIO *h, const char *buf, int num);
+static int file_read(BIO *h, char *buf, int size);
+static int file_puts(BIO *h, const char *str);
+static int file_gets(BIO *h, char *str, int size);
+static long file_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int file_new(BIO *h);
+static int file_free(BIO *data);
+
+static BIO_METHOD methods_filep = {
+	.type = BIO_TYPE_FILE,
+	.name = "FILE pointer",
+	.bwrite = file_write,
+	.bread = file_read,
+	.bputs = file_puts,
+	.bgets = file_gets,
+	.ctrl = file_ctrl,
+	.create = file_new,
+	.destroy = file_free
+};
+
+BIO *
+BIO_new_file(const char *filename, const char *mode)
+{
+	BIO  *ret;
+	FILE *file = NULL;
+
+	file = fopen(filename, mode);
+
+	if (file == NULL) {
+		SYSerr(SYS_F_FOPEN, errno);
+		ERR_asprintf_error_data("fopen('%s', '%s')", filename, mode);
+		if (errno == ENOENT)
+			BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE);
+		else
+			BIOerr(BIO_F_BIO_NEW_FILE, ERR_R_SYS_LIB);
+		return (NULL);
+	}
+	if ((ret = BIO_new(BIO_s_file())) == NULL) {
+		fclose(file);
+		return (NULL);
+	}
+
+	BIO_set_fp(ret, file, BIO_CLOSE);
+	return (ret);
+}
+
+BIO *
+BIO_new_fp(FILE *stream, int close_flag)
+{
+	BIO *ret;
+
+	if ((ret = BIO_new(BIO_s_file())) == NULL)
+		return (NULL);
+
+	BIO_set_fp(ret, stream, close_flag);
+	return (ret);
+}
+
+BIO_METHOD *
+BIO_s_file(void)
+{
+	return (&methods_filep);
+}
+
+static int
+file_new(BIO *bi)
+{
+	bi->init = 0;
+	bi->num = 0;
+	bi->ptr = NULL;
+	bi->flags=0;
+	return (1);
+}
+
+static int
+file_free(BIO *a)
+{
+	if (a == NULL)
+		return (0);
+	if (a->shutdown) {
+		if ((a->init) && (a->ptr != NULL)) {
+			fclose (a->ptr);
+			a->ptr = NULL;
+			a->flags = 0;
+		}
+		a->init = 0;
+	}
+	return (1);
+}
+
+static int
+file_read(BIO *b, char *out, int outl)
+{
+	int ret = 0;
+
+	if (b->init && out != NULL) {
+		ret = fread(out, 1, outl, (FILE *)b->ptr);
+		if (ret == 0 && ferror((FILE *)b->ptr)) {
+			SYSerr(SYS_F_FREAD, errno);
+			BIOerr(BIO_F_FILE_READ, ERR_R_SYS_LIB);
+			ret = -1;
+		}
+	}
+	return (ret);
+}
+
+static int
+file_write(BIO *b, const char *in, int inl)
+{
+	int ret = 0;
+
+	if (b->init && in != NULL)
+		ret = fwrite(in, 1, inl, (FILE *)b->ptr);
+	return (ret);
+}
+
+static long
+file_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+	long ret = 1;
+	FILE *fp = (FILE *)b->ptr;
+	FILE **fpp;
+	char p[4];
+
+	switch (cmd) {
+	case BIO_C_FILE_SEEK:
+	case BIO_CTRL_RESET:
+		ret = (long)fseek(fp, num, 0);
+		break;
+	case BIO_CTRL_EOF:
+		ret = (long)feof(fp);
+		break;
+	case BIO_C_FILE_TELL:
+	case BIO_CTRL_INFO:
+		ret = ftell(fp);
+		break;
+	case BIO_C_SET_FILE_PTR:
+		file_free(b);
+		b->shutdown = (int)num&BIO_CLOSE;
+		b->ptr = ptr;
+		b->init = 1;
+		break;
+	case BIO_C_SET_FILENAME:
+		file_free(b);
+		b->shutdown = (int)num&BIO_CLOSE;
+		if (num & BIO_FP_APPEND) {
+			if (num & BIO_FP_READ)
+				strlcpy(p, "a+", sizeof p);
+			else	strlcpy(p, "a", sizeof p);
+		} else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE))
+			strlcpy(p, "r+", sizeof p);
+		else if (num & BIO_FP_WRITE)
+			strlcpy(p, "w", sizeof p);
+		else if (num & BIO_FP_READ)
+			strlcpy(p, "r", sizeof p);
+		else {
+			BIOerr(BIO_F_FILE_CTRL, BIO_R_BAD_FOPEN_MODE);
+			ret = 0;
+			break;
+		}
+		fp = fopen(ptr, p);
+		if (fp == NULL) {
+			SYSerr(SYS_F_FOPEN, errno);
+			ERR_asprintf_error_data("fopen('%s', '%s')", ptr, p);
+			BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB);
+			ret = 0;
+			break;
+		}
+		b->ptr = fp;
+		b->init = 1;
+		break;
+	case BIO_C_GET_FILE_PTR:
+		/* the ptr parameter is actually a FILE ** in this case. */
+		if (ptr != NULL) {
+			fpp = (FILE **)ptr;
+			*fpp = (FILE *)b->ptr;
+		}
+		break;
+	case BIO_CTRL_GET_CLOSE:
+		ret = (long)b->shutdown;
+		break;
+	case BIO_CTRL_SET_CLOSE:
+		b->shutdown = (int)num;
+		break;
+	case BIO_CTRL_FLUSH:
+		fflush((FILE *)b->ptr);
+		break;
+	case BIO_CTRL_DUP:
+		ret = 1;
+		break;
+
+	case BIO_CTRL_WPENDING:
+	case BIO_CTRL_PENDING:
+	case BIO_CTRL_PUSH:
+	case BIO_CTRL_POP:
+	default:
+		ret = 0;
+		break;
+	}
+	return (ret);
+}
+
+static int
+file_gets(BIO *bp, char *buf, int size)
+{
+	int ret = 0;
+
+	buf[0] = '\0';
+	if (!fgets(buf, size,(FILE *)bp->ptr))
+		goto err;
+	if (buf[0] != '\0')
+		ret = strlen(buf);
+err:
+	return (ret);
+}
+
+static int
+file_puts(BIO *bp, const char *str)
+{
+	int n, ret;
+
+	n = strlen(str);
+	ret = file_write(bp, str, n);
+	return (ret);
+}
+
+
+#endif /* HEADER_BSS_FILE_C */
diff --git a/crypto/libressl/crypto/bio/bss_log.c b/crypto/libressl/crypto/bio/bss_log.c
new file mode 100644
index 0000000000..c6c8c497f3
--- /dev/null
+++ b/crypto/libressl/crypto/bio/bss_log.c
@@ -0,0 +1,213 @@
+/* $OpenBSD: bss_log.c,v 1.20 2014/07/10 13:58:22 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/*
+	Why BIO_s_log?
+
+	BIO_s_log is useful for system daemons (or services under NT).
+	It is one-way BIO, it sends all stuff to syslogd (on system that
+	commonly use that), or event log (on NT), or OPCOM (on OpenVMS).
+
+*/
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#ifndef NO_SYSLOG
+
+static int slg_write(BIO *h, const char *buf, int num);
+static int slg_puts(BIO *h, const char *str);
+static long slg_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int slg_new(BIO *h);
+static int slg_free(BIO *data);
+static void xopenlog(BIO* bp, char* name, int level);
+static void xsyslog(BIO* bp, int priority, const char* string);
+static void xcloselog(BIO* bp);
+
+static BIO_METHOD methods_slg = {
+	.type = BIO_TYPE_MEM,
+	.name = "syslog",
+	.bwrite = slg_write,
+	.bputs = slg_puts,
+	.ctrl = slg_ctrl,
+	.create = slg_new,
+	.destroy = slg_free
+};
+
+BIO_METHOD *
+BIO_s_log(void)
+{
+	return (&methods_slg);
+}
+
+static int
+slg_new(BIO *bi)
+{
+	bi->init = 1;
+	bi->num = 0;
+	bi->ptr = NULL;
+	xopenlog(bi, "application", LOG_DAEMON);
+	return (1);
+}
+
+static int
+slg_free(BIO *a)
+{
+	if (a == NULL)
+		return (0);
+	xcloselog(a);
+	return (1);
+}
+
+static int
+slg_write(BIO *b, const char *in, int inl)
+{
+	int ret = inl;
+	char* buf;
+	char* pp;
+	int priority, i;
+	static const struct {
+		int strl;
+		char str[10];
+		int log_level;
+	}
+	mapping[] = {
+		{ 6, "PANIC ", LOG_EMERG },
+		{ 6, "EMERG ", LOG_EMERG },
+		{ 4, "EMR ", LOG_EMERG },
+		{ 6, "ALERT ", LOG_ALERT },
+		{ 4, "ALR ", LOG_ALERT },
+		{ 5, "CRIT ", LOG_CRIT },
+		{ 4, "CRI ", LOG_CRIT },
+		{ 6, "ERROR ", LOG_ERR },
+		{ 4, "ERR ", LOG_ERR },
+		{ 8, "WARNING ", LOG_WARNING },
+		{ 5, "WARN ", LOG_WARNING },
+		{ 4, "WAR ", LOG_WARNING },
+		{ 7, "NOTICE ", LOG_NOTICE },
+		{ 5, "NOTE ", LOG_NOTICE },
+		{ 4, "NOT ", LOG_NOTICE },
+		{ 5, "INFO ", LOG_INFO },
+		{ 4, "INF ", LOG_INFO },
+		{ 6, "DEBUG ", LOG_DEBUG },
+		{ 4, "DBG ", LOG_DEBUG },
+		{ 0, "", LOG_ERR } /* The default */
+	};
+
+	if ((buf = malloc(inl + 1)) == NULL) {
+		return (0);
+	}
+	strlcpy(buf, in, inl + 1);
+	i = 0;
+	while (strncmp(buf, mapping[i].str, mapping[i].strl) != 0)
+		i++;
+	priority = mapping[i].log_level;
+	pp = buf + mapping[i].strl;
+
+	xsyslog(b, priority, pp);
+
+	free(buf);
+	return (ret);
+}
+
+static long
+slg_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+	switch (cmd) {
+	case BIO_CTRL_SET:
+		xcloselog(b);
+		xopenlog(b, ptr, num);
+		break;
+	default:
+		break;
+	}
+	return (0);
+}
+
+static int
+slg_puts(BIO *bp, const char *str)
+{
+	int n, ret;
+
+	n = strlen(str);
+	ret = slg_write(bp, str, n);
+	return (ret);
+}
+
+
+static void
+xopenlog(BIO* bp, char* name, int level)
+{
+	openlog(name, LOG_PID|LOG_CONS, level);
+}
+
+static void
+xsyslog(BIO *bp, int priority, const char *string)
+{
+	syslog(priority, "%s", string);
+}
+
+static void
+xcloselog(BIO* bp)
+{
+	closelog();
+}
+
+#endif /* NO_SYSLOG */
diff --git a/crypto/libressl/crypto/bio/bss_mem.c b/crypto/libressl/crypto/bio/bss_mem.c
new file mode 100644
index 0000000000..4f6162c83c
--- /dev/null
+++ b/crypto/libressl/crypto/bio/bss_mem.c
@@ -0,0 +1,321 @@
+/* $OpenBSD: bss_mem.c,v 1.13 2014/07/11 08:44:47 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+static int mem_write(BIO *h, const char *buf, int num);
+static int mem_read(BIO *h, char *buf, int size);
+static int mem_puts(BIO *h, const char *str);
+static int mem_gets(BIO *h, char *str, int size);
+static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int mem_new(BIO *h);
+static int mem_free(BIO *data);
+
+static BIO_METHOD mem_method = {
+	.type = BIO_TYPE_MEM,
+	.name = "memory buffer",
+	.bwrite = mem_write,
+	.bread = mem_read,
+	.bputs = mem_puts,
+	.bgets = mem_gets,
+	.ctrl = mem_ctrl,
+	.create = mem_new,
+	.destroy = mem_free
+};
+
+/* bio->num is used to hold the value to return on 'empty', if it is
+ * 0, should_retry is not set */
+
+BIO_METHOD *
+BIO_s_mem(void)
+{
+	return (&mem_method);
+}
+
+BIO *
+BIO_new_mem_buf(void *buf, int len)
+{
+	BIO *ret;
+	BUF_MEM *b;
+	size_t sz;
+
+	if (!buf) {
+		BIOerr(BIO_F_BIO_NEW_MEM_BUF, BIO_R_NULL_PARAMETER);
+		return NULL;
+	}
+	sz = (len < 0) ? strlen(buf) : (size_t)len;
+	if (!(ret = BIO_new(BIO_s_mem())))
+		return NULL;
+	b = (BUF_MEM *)ret->ptr;
+	b->data = buf;
+	b->length = sz;
+	b->max = sz;
+	ret->flags |= BIO_FLAGS_MEM_RDONLY;
+	/* Since this is static data retrying wont help */
+	ret->num = 0;
+	return ret;
+}
+
+static int
+mem_new(BIO *bi)
+{
+	BUF_MEM *b;
+
+	if ((b = BUF_MEM_new()) == NULL)
+		return (0);
+	bi->shutdown = 1;
+	bi->init = 1;
+	bi->num = -1;
+	bi->ptr = (char *)b;
+	return (1);
+}
+
+static int
+mem_free(BIO *a)
+{
+	if (a == NULL)
+		return (0);
+	if (a->shutdown) {
+		if ((a->init) && (a->ptr != NULL)) {
+			BUF_MEM *b;
+			b = (BUF_MEM *)a->ptr;
+			if (a->flags & BIO_FLAGS_MEM_RDONLY)
+				b->data = NULL;
+			BUF_MEM_free(b);
+			a->ptr = NULL;
+		}
+	}
+	return (1);
+}
+
+static int
+mem_read(BIO *b, char *out, int outl)
+{
+	int ret = -1;
+	BUF_MEM *bm;
+
+	bm = (BUF_MEM *)b->ptr;
+	BIO_clear_retry_flags(b);
+	ret = (outl >=0 && (size_t)outl > bm->length) ? (int)bm->length : outl;
+	if ((out != NULL) && (ret > 0)) {
+		memcpy(out, bm->data, ret);
+		bm->length -= ret;
+		if (b->flags & BIO_FLAGS_MEM_RDONLY)
+			bm->data += ret;
+		else {
+			memmove(&(bm->data[0]), &(bm->data[ret]), bm->length);
+		}
+	} else if (bm->length == 0) {
+		ret = b->num;
+		if (ret != 0)
+			BIO_set_retry_read(b);
+	}
+	return (ret);
+}
+
+static int
+mem_write(BIO *b, const char *in, int inl)
+{
+	int ret = -1;
+	int blen;
+	BUF_MEM *bm;
+
+	bm = (BUF_MEM *)b->ptr;
+	if (in == NULL) {
+		BIOerr(BIO_F_MEM_WRITE, BIO_R_NULL_PARAMETER);
+		goto end;
+	}
+
+	if (b->flags & BIO_FLAGS_MEM_RDONLY) {
+		BIOerr(BIO_F_MEM_WRITE, BIO_R_WRITE_TO_READ_ONLY_BIO);
+		goto end;
+	}
+
+	BIO_clear_retry_flags(b);
+	blen = bm->length;
+	if (BUF_MEM_grow_clean(bm, blen + inl) != (blen + inl))
+		goto end;
+	memcpy(&(bm->data[blen]), in, inl);
+	ret = inl;
+end:
+	return (ret);
+}
+
+static long
+mem_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+	long ret = 1;
+	char **pptr;
+
+	BUF_MEM *bm = (BUF_MEM *)b->ptr;
+
+	switch (cmd) {
+	case BIO_CTRL_RESET:
+		if (bm->data != NULL) {
+			/* For read only case reset to the start again */
+			if (b->flags & BIO_FLAGS_MEM_RDONLY) {
+				bm->data -= bm->max - bm->length;
+				bm->length = bm->max;
+			} else {
+				memset(bm->data, 0, bm->max);
+				bm->length = 0;
+			}
+		}
+		break;
+	case BIO_CTRL_EOF:
+		ret = (long)(bm->length == 0);
+		break;
+	case BIO_C_SET_BUF_MEM_EOF_RETURN:
+		b->num = (int)num;
+		break;
+	case BIO_CTRL_INFO:
+		ret = (long)bm->length;
+		if (ptr != NULL) {
+			pptr = (char **)ptr;
+			*pptr = (char *)&(bm->data[0]);
+		}
+		break;
+	case BIO_C_SET_BUF_MEM:
+		mem_free(b);
+		b->shutdown = (int)num;
+		b->ptr = ptr;
+		break;
+	case BIO_C_GET_BUF_MEM_PTR:
+		if (ptr != NULL) {
+			pptr = (char **)ptr;
+			*pptr = (char *)bm;
+		}
+		break;
+	case BIO_CTRL_GET_CLOSE:
+		ret = (long)b->shutdown;
+		break;
+	case BIO_CTRL_SET_CLOSE:
+		b->shutdown = (int)num;
+		break;
+
+	case BIO_CTRL_WPENDING:
+		ret = 0L;
+		break;
+	case BIO_CTRL_PENDING:
+		ret = (long)bm->length;
+		break;
+	case BIO_CTRL_DUP:
+	case BIO_CTRL_FLUSH:
+		ret = 1;
+		break;
+	case BIO_CTRL_PUSH:
+	case BIO_CTRL_POP:
+	default:
+		ret = 0;
+		break;
+	}
+	return (ret);
+}
+
+static int
+mem_gets(BIO *bp, char *buf, int size)
+{
+	int i, j;
+	int ret = -1;
+	char *p;
+	BUF_MEM *bm = (BUF_MEM *)bp->ptr;
+
+	BIO_clear_retry_flags(bp);
+	j = bm->length;
+	if ((size - 1) < j)
+		j = size - 1;
+	if (j <= 0) {
+		*buf = '\0';
+		return 0;
+	}
+	p = bm->data;
+	for (i = 0; i < j; i++) {
+		if (p[i] == '\n') {
+			i++;
+			break;
+		}
+	}
+
+	/*
+	 * i is now the max num of bytes to copy, either j or up to
+	 * and including the first newline
+	 */ 
+
+	i = mem_read(bp, buf, i);
+	if (i > 0)
+		buf[i] = '\0';
+	ret = i;
+	return (ret);
+}
+
+static int
+mem_puts(BIO *bp, const char *str)
+{
+	int n, ret;
+
+	n = strlen(str);
+	ret = mem_write(bp, str, n);
+	/* memory semantics is that it will always work */
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/bio/bss_null.c b/crypto/libressl/crypto/bio/bss_null.c
new file mode 100644
index 0000000000..bf4388e26e
--- /dev/null
+++ b/crypto/libressl/crypto/bio/bss_null.c
@@ -0,0 +1,158 @@
+/* $OpenBSD: bss_null.c,v 1.9 2014/07/10 13:58:22 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+static int null_write(BIO *h, const char *buf, int num);
+static int null_read(BIO *h, char *buf, int size);
+static int null_puts(BIO *h, const char *str);
+static int null_gets(BIO *h, char *str, int size);
+static long null_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int null_new(BIO *h);
+static int null_free(BIO *data);
+
+static BIO_METHOD null_method = {
+	.type = BIO_TYPE_NULL,
+	.name = "NULL",
+	.bwrite = null_write,
+	.bread = null_read,
+	.bputs = null_puts,
+	.bgets = null_gets,
+	.ctrl = null_ctrl,
+	.create = null_new,
+	.destroy = null_free
+};
+
+BIO_METHOD *
+BIO_s_null(void)
+{
+	return (&null_method);
+}
+
+static int
+null_new(BIO *bi)
+{
+	bi->init = 1;
+	bi->num = 0;
+	bi->ptr = (NULL);
+	return (1);
+}
+
+static int
+null_free(BIO *a)
+{
+	if (a == NULL)
+		return (0);
+	return (1);
+}
+
+static int
+null_read(BIO *b, char *out, int outl)
+{
+	return (0);
+}
+
+static int
+null_write(BIO *b, const char *in, int inl)
+{
+	return (inl);
+}
+
+static long
+null_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+	long ret = 1;
+
+	switch (cmd) {
+	case BIO_CTRL_RESET:
+	case BIO_CTRL_EOF:
+	case BIO_CTRL_SET:
+	case BIO_CTRL_SET_CLOSE:
+	case BIO_CTRL_FLUSH:
+	case BIO_CTRL_DUP:
+		ret = 1;
+		break;
+	case BIO_CTRL_GET_CLOSE:
+	case BIO_CTRL_INFO:
+	case BIO_CTRL_GET:
+	case BIO_CTRL_PENDING:
+	case BIO_CTRL_WPENDING:
+	default:
+		ret = 0;
+		break;
+	}
+	return (ret);
+}
+
+static int
+null_gets(BIO *bp, char *buf, int size)
+{
+	return (0);
+}
+
+static int
+null_puts(BIO *bp, const char *str)
+{
+	if (str == NULL)
+		return (0);
+	return (strlen(str));
+}
diff --git a/crypto/libressl/crypto/bio/bss_sock.c b/crypto/libressl/crypto/bio/bss_sock.c
new file mode 100644
index 0000000000..b38e80cd03
--- /dev/null
+++ b/crypto/libressl/crypto/bio/bss_sock.c
@@ -0,0 +1,239 @@
+/* $OpenBSD: bss_sock.c,v 1.22 2014/07/10 13:58:22 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+static int sock_write(BIO *h, const char *buf, int num);
+static int sock_read(BIO *h, char *buf, int size);
+static int sock_puts(BIO *h, const char *str);
+static long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int sock_new(BIO *h);
+static int sock_free(BIO *data);
+int BIO_sock_should_retry(int s);
+
+static BIO_METHOD methods_sockp = {
+	.type = BIO_TYPE_SOCKET,
+	.name = "socket",
+	.bwrite = sock_write,
+	.bread = sock_read,
+	.bputs = sock_puts,
+	.ctrl = sock_ctrl,
+	.create = sock_new,
+	.destroy = sock_free
+};
+
+BIO_METHOD *
+BIO_s_socket(void)
+{
+	return (&methods_sockp);
+}
+
+BIO *
+BIO_new_socket(int fd, int close_flag)
+{
+	BIO *ret;
+
+	ret = BIO_new(BIO_s_socket());
+	if (ret == NULL)
+		return (NULL);
+	BIO_set_fd(ret, fd, close_flag);
+	return (ret);
+}
+
+static int
+sock_new(BIO *bi)
+{
+	bi->init = 0;
+	bi->num = 0;
+	bi->ptr = NULL;
+	bi->flags = 0;
+	return (1);
+}
+
+static int
+sock_free(BIO *a)
+{
+	if (a == NULL)
+		return (0);
+	if (a->shutdown) {
+		if (a->init) {
+			shutdown(a->num, SHUT_RDWR);
+			close(a->num);
+		}
+		a->init = 0;
+		a->flags = 0;
+	}
+	return (1);
+}
+
+static int
+sock_read(BIO *b, char *out, int outl)
+{
+	int ret = 0;
+
+	if (out != NULL) {
+		errno = 0;
+		ret = read(b->num, out, outl);
+		BIO_clear_retry_flags(b);
+		if (ret <= 0) {
+			if (BIO_sock_should_retry(ret))
+				BIO_set_retry_read(b);
+		}
+	}
+	return (ret);
+}
+
+static int
+sock_write(BIO *b, const char *in, int inl)
+{
+	int ret;
+
+	errno = 0;
+	ret = write(b->num, in, inl);
+	BIO_clear_retry_flags(b);
+	if (ret <= 0) {
+		if (BIO_sock_should_retry(ret))
+			BIO_set_retry_write(b);
+	}
+	return (ret);
+}
+
+static long
+sock_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+	long ret = 1;
+	int *ip;
+
+	switch (cmd) {
+	case BIO_C_SET_FD:
+		sock_free(b);
+		b->num= *((int *)ptr);
+		b->shutdown = (int)num;
+		b->init = 1;
+		break;
+	case BIO_C_GET_FD:
+		if (b->init) {
+			ip = (int *)ptr;
+			if (ip != NULL)
+				*ip = b->num;
+			ret = b->num;
+		} else
+			ret = -1;
+		break;
+	case BIO_CTRL_GET_CLOSE:
+		ret = b->shutdown;
+		break;
+	case BIO_CTRL_SET_CLOSE:
+		b->shutdown = (int)num;
+		break;
+	case BIO_CTRL_DUP:
+	case BIO_CTRL_FLUSH:
+		ret = 1;
+		break;
+	default:
+		ret = 0;
+		break;
+	}
+	return (ret);
+}
+
+static int
+sock_puts(BIO *bp, const char *str)
+{
+	int n, ret;
+
+	n = strlen(str);
+	ret = sock_write(bp, str, n);
+	return (ret);
+}
+
+int
+BIO_sock_should_retry(int i)
+{
+	int err;
+
+	if ((i == 0) || (i == -1)) {
+		err = errno;
+		return (BIO_sock_non_fatal_error(err));
+	}
+	return (0);
+}
+
+int
+BIO_sock_non_fatal_error(int err)
+{
+	switch (err) {
+	case ENOTCONN:
+	case EINTR:
+	case EAGAIN:
+	case EINPROGRESS:
+	case EALREADY:
+		return (1);
+	default:
+		break;
+	}
+	return (0);
+}
+
diff --git a/crypto/libressl/crypto/bn/bn_add.c b/crypto/libressl/crypto/bn/bn_add.c
new file mode 100644
index 0000000000..6632873496
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_add.c
@@ -0,0 +1,313 @@
+/* $OpenBSD: bn_add.c,v 1.9 2014/07/11 08:44:47 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include "bn_lcl.h"
+
+/* r can == a or b */
+int
+BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+{
+	const BIGNUM *tmp;
+	int a_neg = a->neg, ret;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	/*  a +  b	a+b
+	 *  a + -b	a-b
+	 * -a +  b	b-a
+	 * -a + -b	-(a+b)
+	 */
+	if (a_neg ^ b->neg) {
+		/* only one is negative */
+		if (a_neg)
+				{ tmp = a;
+			a = b;
+			b = tmp;
+		}
+
+		/* we are now a - b */
+
+		if (BN_ucmp(a, b) < 0) {
+			if (!BN_usub(r, b, a))
+				return (0);
+			r->neg = 1;
+		} else {
+			if (!BN_usub(r, a, b))
+				return (0);
+			r->neg = 0;
+		}
+		return (1);
+	}
+
+	ret = BN_uadd(r, a, b);
+	r->neg = a_neg;
+	bn_check_top(r);
+	return ret;
+}
+
+/* unsigned add of b to a */
+int
+BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+{
+	int max, min, dif;
+	BN_ULONG *ap, *bp, *rp, carry, t1, t2;
+	const BIGNUM *tmp;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	if (a->top < b->top) {
+		tmp = a;
+		a = b;
+		b = tmp;
+	}
+	max = a->top;
+	min = b->top;
+	dif = max - min;
+
+	if (bn_wexpand(r, max + 1) == NULL)
+		return 0;
+
+	r->top = max;
+
+	ap = a->d;
+	bp = b->d;
+	rp = r->d;
+
+	carry = bn_add_words(rp, ap, bp, min);
+	rp += min;
+	ap += min;
+	bp += min;
+
+	if (carry) {
+		while (dif) {
+			dif--;
+			t1 = *(ap++);
+			t2 = (t1 + 1) & BN_MASK2;
+			*(rp++) = t2;
+			if (t2) {
+				carry = 0;
+				break;
+			}
+		}
+		if (carry) {
+			/* carry != 0 => dif == 0 */
+			*rp = 1;
+			r->top++;
+		}
+	}
+	if (dif && rp != ap)
+		while (dif--)
+			/* copy remaining words if ap != rp */
+			*(rp++) = *(ap++);
+	r->neg = 0;
+	bn_check_top(r);
+	return 1;
+}
+
+/* unsigned subtraction of b from a, a must be larger than b. */
+int
+BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+{
+	int max, min, dif;
+	BN_ULONG t1, t2, *ap, *bp, *rp;
+	int i, carry;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	max = a->top;
+	min = b->top;
+	dif = max - min;
+
+	if (dif < 0)	/* hmm... should not be happening */
+	{
+		BNerr(BN_F_BN_USUB, BN_R_ARG2_LT_ARG3);
+		return (0);
+	}
+
+	if (bn_wexpand(r, max) == NULL)
+		return (0);
+
+	ap = a->d;
+	bp = b->d;
+	rp = r->d;
+
+#if 1
+	carry = 0;
+	for (i = min; i != 0; i--) {
+		t1= *(ap++);
+		t2= *(bp++);
+		if (carry) {
+			carry = (t1 <= t2);
+			t1 = (t1 - t2 - 1)&BN_MASK2;
+		} else {
+			carry = (t1 < t2);
+			t1 = (t1 - t2)&BN_MASK2;
+		}
+		*(rp++) = t1&BN_MASK2;
+	}
+#else
+	carry = bn_sub_words(rp, ap, bp, min);
+	ap += min;
+	bp += min;
+	rp += min;
+#endif
+	if (carry) /* subtracted */
+	{
+		if (!dif)
+			/* error: a < b */
+			return 0;
+		while (dif) {
+			dif--;
+			t1 = *(ap++);
+			t2 = (t1 - 1)&BN_MASK2;
+			*(rp++) = t2;
+			if (t1)
+				break;
+		}
+	}
+#if 0
+	memcpy(rp, ap, sizeof(*rp)*(max - i));
+#else
+	if (rp != ap) {
+		for (;;) {
+			if (!dif--)
+				break;
+			rp[0] = ap[0];
+			if (!dif--)
+				break;
+			rp[1] = ap[1];
+			if (!dif--)
+				break;
+			rp[2] = ap[2];
+			if (!dif--)
+				break;
+			rp[3] = ap[3];
+			rp += 4;
+			ap += 4;
+		}
+	}
+#endif
+
+	r->top = max;
+	r->neg = 0;
+	bn_correct_top(r);
+	return (1);
+}
+
+int
+BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+{
+	int max;
+	int add = 0, neg = 0;
+	const BIGNUM *tmp;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	/*  a -  b	a-b
+	 *  a - -b	a+b
+	 * -a -  b	-(a+b)
+	 * -a - -b	b-a
+	 */
+	if (a->neg) {
+		if (b->neg) {
+			tmp = a;
+			a = b;
+			b = tmp;
+		} else {
+			add = 1;
+			neg = 1;
+		}
+	} else {
+		if (b->neg) {
+			add = 1;
+			neg = 0;
+		}
+	}
+
+	if (add) {
+		if (!BN_uadd(r, a, b))
+			return (0);
+		r->neg = neg;
+		return (1);
+	}
+
+	/* We are actually doing a - b :-) */
+
+	max = (a->top > b->top) ? a->top : b->top;
+	if (bn_wexpand(r, max) == NULL)
+		return (0);
+	if (BN_ucmp(a, b) < 0) {
+		if (!BN_usub(r, b, a))
+			return (0);
+		r->neg = 1;
+	} else {
+		if (!BN_usub(r, a, b))
+			return (0);
+		r->neg = 0;
+	}
+	bn_check_top(r);
+	return (1);
+}
diff --git a/crypto/libressl/crypto/bn/bn_asm.c b/crypto/libressl/crypto/bn/bn_asm.c
new file mode 100644
index 0000000000..d1d637de72
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_asm.c
@@ -0,0 +1,1098 @@
+/* $OpenBSD: bn_asm.c,v 1.13 2014/07/11 08:44:47 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef BN_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
+#include 
+#include 
+
+#include 
+
+#include "bn_lcl.h"
+
+#if defined(BN_LLONG) || defined(BN_UMULT_HIGH)
+
+BN_ULONG
+bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
+{
+	BN_ULONG c1 = 0;
+
+	assert(num >= 0);
+	if (num <= 0)
+		return (c1);
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (num & ~3) {
+		mul_add(rp[0], ap[0], w, c1);
+		mul_add(rp[1], ap[1], w, c1);
+		mul_add(rp[2], ap[2], w, c1);
+		mul_add(rp[3], ap[3], w, c1);
+		ap += 4;
+		rp += 4;
+		num -= 4;
+	}
+#endif
+	while (num) {
+		mul_add(rp[0], ap[0], w, c1);
+		ap++;
+		rp++;
+		num--;
+	}
+
+	return (c1);
+}
+
+BN_ULONG
+bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
+{
+	BN_ULONG c1 = 0;
+
+	assert(num >= 0);
+	if (num <= 0)
+		return (c1);
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (num & ~3) {
+		mul(rp[0], ap[0], w, c1);
+		mul(rp[1], ap[1], w, c1);
+		mul(rp[2], ap[2], w, c1);
+		mul(rp[3], ap[3], w, c1);
+		ap += 4;
+		rp += 4;
+		num -= 4;
+	}
+#endif
+	while (num) {
+		mul(rp[0], ap[0], w, c1);
+		ap++;
+		rp++;
+		num--;
+	}
+	return (c1);
+}
+
+void
+bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
+{
+	assert(n >= 0);
+	if (n <= 0)
+		return;
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (n & ~3) {
+		sqr(r[0], r[1], a[0]);
+		sqr(r[2], r[3], a[1]);
+		sqr(r[4], r[5], a[2]);
+		sqr(r[6], r[7], a[3]);
+		a += 4;
+		r += 8;
+		n -= 4;
+	}
+#endif
+	while (n) {
+		sqr(r[0], r[1], a[0]);
+		a++;
+		r += 2;
+		n--;
+	}
+}
+
+#else /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
+
+BN_ULONG
+bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
+{
+	BN_ULONG c = 0;
+	BN_ULONG bl, bh;
+
+	assert(num >= 0);
+	if (num <= 0)
+		return ((BN_ULONG)0);
+
+	bl = LBITS(w);
+	bh = HBITS(w);
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (num & ~3) {
+		mul_add(rp[0], ap[0], bl, bh, c);
+		mul_add(rp[1], ap[1], bl, bh, c);
+		mul_add(rp[2], ap[2], bl, bh, c);
+		mul_add(rp[3], ap[3], bl, bh, c);
+		ap += 4;
+		rp += 4;
+		num -= 4;
+	}
+#endif
+	while (num) {
+		mul_add(rp[0], ap[0], bl, bh, c);
+		ap++;
+		rp++;
+		num--;
+	}
+	return (c);
+}
+
+BN_ULONG
+bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
+{
+	BN_ULONG carry = 0;
+	BN_ULONG bl, bh;
+
+	assert(num >= 0);
+	if (num <= 0)
+		return ((BN_ULONG)0);
+
+	bl = LBITS(w);
+	bh = HBITS(w);
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (num & ~3) {
+		mul(rp[0], ap[0], bl, bh, carry);
+		mul(rp[1], ap[1], bl, bh, carry);
+		mul(rp[2], ap[2], bl, bh, carry);
+		mul(rp[3], ap[3], bl, bh, carry);
+		ap += 4;
+		rp += 4;
+		num -= 4;
+	}
+#endif
+	while (num) {
+		mul(rp[0], ap[0], bl, bh, carry);
+		ap++;
+		rp++;
+		num--;
+	}
+	return (carry);
+}
+
+void
+bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
+{
+	assert(n >= 0);
+	if (n <= 0)
+		return;
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (n & ~3) {
+		sqr64(r[0], r[1], a[0]);
+		sqr64(r[2], r[3], a[1]);
+		sqr64(r[4], r[5], a[2]);
+		sqr64(r[6], r[7], a[3]);
+		a += 4;
+		r += 8;
+		n -= 4;
+	}
+#endif
+	while (n) {
+		sqr64(r[0], r[1], a[0]);
+		a++;
+		r += 2;
+		n--;
+	}
+}
+
+#endif /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
+
+#if defined(BN_LLONG) && defined(BN_DIV2W)
+
+BN_ULONG
+bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+{
+	return ((BN_ULONG)(((((BN_ULLONG)h) << BN_BITS2)|l)/(BN_ULLONG)d));
+}
+
+#else
+
+/* Divide h,l by d and return the result. */
+/* I need to test this some more :-( */
+BN_ULONG
+bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+{
+	BN_ULONG dh, dl, q,ret = 0, th, tl, t;
+	int i, count = 2;
+
+	if (d == 0)
+		return (BN_MASK2);
+
+	i = BN_num_bits_word(d);
+	assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i));
+
+	i = BN_BITS2 - i;
+	if (h >= d)
+		h -= d;
+
+	if (i) {
+		d <<= i;
+		h = (h << i) | (l >> (BN_BITS2 - i));
+		l <<= i;
+	}
+	dh = (d & BN_MASK2h) >> BN_BITS4;
+	dl = (d & BN_MASK2l);
+	for (;;) {
+		if ((h >> BN_BITS4) == dh)
+			q = BN_MASK2l;
+		else
+			q = h / dh;
+
+		th = q * dh;
+		tl = dl * q;
+		for (;;) {
+			t = h - th;
+			if ((t & BN_MASK2h) ||
+			    ((tl) <= (
+			    (t << BN_BITS4) |
+			    ((l & BN_MASK2h) >> BN_BITS4))))
+				break;
+			q--;
+			th -= dh;
+			tl -= dl;
+		}
+		t = (tl >> BN_BITS4);
+		tl = (tl << BN_BITS4) & BN_MASK2h;
+		th += t;
+
+		if (l < tl)
+			th++;
+		l -= tl;
+		if (h < th) {
+			h += d;
+			q--;
+		}
+		h -= th;
+
+		if (--count == 0)
+			break;
+
+		ret = q << BN_BITS4;
+		h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2;
+		l = (l & BN_MASK2l) << BN_BITS4;
+	}
+	ret |= q;
+	return (ret);
+}
+#endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */
+
+#ifdef BN_LLONG
+BN_ULONG
+bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
+{
+	BN_ULLONG ll = 0;
+
+	assert(n >= 0);
+	if (n <= 0)
+		return ((BN_ULONG)0);
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (n & ~3) {
+		ll += (BN_ULLONG)a[0] + b[0];
+		r[0] = (BN_ULONG)ll & BN_MASK2;
+		ll >>= BN_BITS2;
+		ll += (BN_ULLONG)a[1] + b[1];
+		r[1] = (BN_ULONG)ll & BN_MASK2;
+		ll >>= BN_BITS2;
+		ll += (BN_ULLONG)a[2] + b[2];
+		r[2] = (BN_ULONG)ll & BN_MASK2;
+		ll >>= BN_BITS2;
+		ll += (BN_ULLONG)a[3] + b[3];
+		r[3] = (BN_ULONG)ll & BN_MASK2;
+		ll >>= BN_BITS2;
+		a += 4;
+		b += 4;
+		r += 4;
+		n -= 4;
+	}
+#endif
+	while (n) {
+		ll += (BN_ULLONG)a[0] + b[0];
+		r[0] = (BN_ULONG)ll & BN_MASK2;
+		ll >>= BN_BITS2;
+		a++;
+		b++;
+		r++;
+		n--;
+	}
+	return ((BN_ULONG)ll);
+}
+#else /* !BN_LLONG */
+BN_ULONG
+bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
+{
+	BN_ULONG c, l, t;
+
+	assert(n >= 0);
+	if (n <= 0)
+		return ((BN_ULONG)0);
+
+	c = 0;
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (n & ~3) {
+		t = a[0];
+		t = (t + c) & BN_MASK2;
+		c = (t < c);
+		l = (t + b[0]) & BN_MASK2;
+		c += (l < t);
+		r[0] = l;
+		t = a[1];
+		t = (t + c) & BN_MASK2;
+		c = (t < c);
+		l = (t + b[1]) & BN_MASK2;
+		c += (l < t);
+		r[1] = l;
+		t = a[2];
+		t = (t + c) & BN_MASK2;
+		c = (t < c);
+		l = (t + b[2]) & BN_MASK2;
+		c += (l < t);
+		r[2] = l;
+		t = a[3];
+		t = (t + c) & BN_MASK2;
+		c = (t < c);
+		l = (t + b[3]) & BN_MASK2;
+		c += (l < t);
+		r[3] = l;
+		a += 4;
+		b += 4;
+		r += 4;
+		n -= 4;
+	}
+#endif
+	while (n) {
+		t = a[0];
+		t = (t + c) & BN_MASK2;
+		c = (t < c);
+		l = (t + b[0]) & BN_MASK2;
+		c += (l < t);
+		r[0] = l;
+		a++;
+		b++;
+		r++;
+		n--;
+	}
+	return ((BN_ULONG)c);
+}
+#endif /* !BN_LLONG */
+
+BN_ULONG
+bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
+{
+	BN_ULONG t1, t2;
+	int c = 0;
+
+	assert(n >= 0);
+	if (n <= 0)
+		return ((BN_ULONG)0);
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+	while (n&~3) {
+		t1 = a[0];
+		t2 = b[0];
+		r[0] = (t1 - t2 - c) & BN_MASK2;
+		if (t1 != t2)
+			c = (t1 < t2);
+		t1 = a[1];
+		t2 = b[1];
+		r[1] = (t1 - t2 - c) & BN_MASK2;
+		if (t1 != t2)
+			c = (t1 < t2);
+		t1 = a[2];
+		t2 = b[2];
+		r[2] = (t1 - t2 - c) & BN_MASK2;
+		if (t1 != t2)
+			c = (t1 < t2);
+		t1 = a[3];
+		t2 = b[3];
+		r[3] = (t1 - t2 - c) & BN_MASK2;
+		if (t1 != t2)
+			c = (t1 < t2);
+		a += 4;
+		b += 4;
+		r += 4;
+		n -= 4;
+	}
+#endif
+	while (n) {
+		t1 = a[0];
+		t2 = b[0];
+		r[0] = (t1 - t2 - c) & BN_MASK2;
+		if (t1 != t2)
+			c = (t1 < t2);
+		a++;
+		b++;
+		r++;
+		n--;
+	}
+	return (c);
+}
+
+#if defined(BN_MUL_COMBA) && !defined(OPENSSL_SMALL_FOOTPRINT)
+
+#undef bn_mul_comba8
+#undef bn_mul_comba4
+#undef bn_sqr_comba8
+#undef bn_sqr_comba4
+
+/* mul_add_c(a,b,c0,c1,c2)  -- c+=a*b for three word number c=(c2,c1,c0) */
+/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */
+/* sqr_add_c(a,i,c0,c1,c2)  -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
+/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
+
+#ifdef BN_LLONG
+/*
+ * Keep in mind that additions to multiplication result can not
+ * overflow, because its high half cannot be all-ones.
+ */
+#define mul_add_c(a,b,c0,c1,c2)		do {	\
+	BN_ULONG hi;				\
+	BN_ULLONG t = (BN_ULLONG)(a)*(b);	\
+	t += c0;		/* no carry */	\
+	c0 = (BN_ULONG)Lw(t);			\
+	hi = (BN_ULONG)Hw(t);			\
+	c1 = (c1+hi)&BN_MASK2; if (c1= np[num - 1]) {
+		c0 = bn_sub_words(rp, tp, np, num);
+		if (tp[num] != 0 || c0 == 0) {
+			goto out;
+		}
+	}
+	memcpy(rp, tp, num * sizeof(BN_ULONG));
+out:
+	explicit_bzero(tp, (num + 2) * sizeof(BN_ULONG));
+	free(tp);
+	return 1;
+}
+#else
+/*
+ * Return value of 0 indicates that multiplication/convolution was not
+ * performed to signal the caller to fall down to alternative/original
+ * code-path.
+ */
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num)
+	{	return 0;
+}
+#endif /* OPENSSL_BN_ASM_MONT */
+#endif
+
+#else /* !BN_MUL_COMBA */
+
+/* hmm... is it faster just to do a multiply? */
+#undef bn_sqr_comba4
+void
+bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
+{
+	BN_ULONG t[8];
+	bn_sqr_normal(r, a, 4, t);
+}
+
+#undef bn_sqr_comba8
+void
+bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
+{
+	BN_ULONG t[16];
+	bn_sqr_normal(r, a, 8, t);
+}
+
+void
+bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+{
+	r[4] = bn_mul_words(&(r[0]), a, 4, b[0]);
+	r[5] = bn_mul_add_words(&(r[1]), a, 4, b[1]);
+	r[6] = bn_mul_add_words(&(r[2]), a, 4, b[2]);
+	r[7] = bn_mul_add_words(&(r[3]), a, 4, b[3]);
+}
+
+void
+bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+{
+	r[8] = bn_mul_words(&(r[0]), a, 8, b[0]);
+	r[9] = bn_mul_add_words(&(r[1]), a, 8, b[1]);
+	r[10] = bn_mul_add_words(&(r[2]), a, 8, b[2]);
+	r[11] = bn_mul_add_words(&(r[3]), a, 8, b[3]);
+	r[12] = bn_mul_add_words(&(r[4]), a, 8, b[4]);
+	r[13] = bn_mul_add_words(&(r[5]), a, 8, b[5]);
+	r[14] = bn_mul_add_words(&(r[6]), a, 8, b[6]);
+	r[15] = bn_mul_add_words(&(r[7]), a, 8, b[7]);
+}
+
+#ifdef OPENSSL_NO_ASM
+#ifdef OPENSSL_BN_ASM_MONT
+int
+bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+    const BN_ULONG *np, const BN_ULONG *n0p, int num)
+{
+	BN_ULONG c0, c1, *tp, n0 = *n0p;
+	int i = 0, j;
+
+	tp = calloc(NULL, num + 2, sizeof(BN_ULONG));
+	if (tp == NULL)
+		return 0;
+
+	for (i = 0; i < num; i++) {
+		c0 = bn_mul_add_words(tp, ap, num, bp[i]);
+		c1 = (tp[num] + c0) & BN_MASK2;
+		tp[num] = c1;
+		tp[num + 1] = (c1 < c0 ? 1 : 0);
+
+		c0 = bn_mul_add_words(tp, np, num, tp[0] * n0);
+		c1 = (tp[num] + c0) & BN_MASK2;
+		tp[num] = c1;
+		tp[num + 1] += (c1 < c0 ? 1 : 0);
+		for (j = 0; j <= num; j++)
+			tp[j] = tp[j + 1];
+	}
+
+	if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) {
+		c0 = bn_sub_words(rp, tp, np, num);
+		if (tp[num] != 0 || c0 == 0) {
+			goto out;
+		}
+	}
+	memcpy(rp, tp, num * sizeof(BN_ULONG));
+out:
+	explicit_bzero(tp, (num + 2) * sizeof(BN_ULONG));
+	free(tp);
+	return 1;
+}
+#else
+int
+bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+    const BN_ULONG *np, const BN_ULONG *n0, int num)
+{
+	return 0;
+}
+#endif /* OPENSSL_BN_ASM_MONT */
+#endif
+
+#endif /* !BN_MUL_COMBA */
diff --git a/crypto/libressl/crypto/bn/bn_blind.c b/crypto/libressl/crypto/bn/bn_blind.c
new file mode 100644
index 0000000000..46f2205976
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_blind.c
@@ -0,0 +1,388 @@
+/* $OpenBSD: bn_blind.c,v 1.13 2014/07/11 08:44:47 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+
+#include "bn_lcl.h"
+
+#define BN_BLINDING_COUNTER	32
+
+struct bn_blinding_st {
+	BIGNUM *A;
+	BIGNUM *Ai;
+	BIGNUM *e;
+	BIGNUM *mod; /* just a reference */
+#ifndef OPENSSL_NO_DEPRECATED
+	unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b;
+				  * used only by crypto/rsa/rsa_eay.c, rsa_lib.c */
+#endif
+	CRYPTO_THREADID tid;
+	int counter;
+	unsigned long flags;
+	BN_MONT_CTX *m_ctx;
+	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+};
+
+BN_BLINDING *
+BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
+{
+	BN_BLINDING *ret = NULL;
+
+	bn_check_top(mod);
+
+	if ((ret = calloc(1, sizeof(BN_BLINDING))) == NULL) {
+		BNerr(BN_F_BN_BLINDING_NEW, ERR_R_MALLOC_FAILURE);
+		return (NULL);
+	}
+	if (A != NULL) {
+		if ((ret->A = BN_dup(A))  == NULL)
+			goto err;
+	}
+	if (Ai != NULL) {
+		if ((ret->Ai = BN_dup(Ai)) == NULL)
+			goto err;
+	}
+
+	/* save a copy of mod in the BN_BLINDING structure */
+	if ((ret->mod = BN_dup(mod)) == NULL)
+		goto err;
+	if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0)
+		BN_set_flags(ret->mod, BN_FLG_CONSTTIME);
+
+	/* Set the counter to the special value -1
+	 * to indicate that this is never-used fresh blinding
+	 * that does not need updating before first use. */
+	ret->counter = -1;
+	CRYPTO_THREADID_current(&ret->tid);
+	return (ret);
+
+err:
+	if (ret != NULL)
+		BN_BLINDING_free(ret);
+	return (NULL);
+}
+
+void
+BN_BLINDING_free(BN_BLINDING *r)
+{
+	if (r == NULL)
+		return;
+
+	BN_clear_free(r->A);
+	BN_clear_free(r->Ai);
+	BN_clear_free(r->e);
+	BN_clear_free(r->mod);
+	free(r);
+}
+
+int
+BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx)
+{
+	int ret = 0;
+
+	if ((b->A == NULL) || (b->Ai == NULL)) {
+		BNerr(BN_F_BN_BLINDING_UPDATE, BN_R_NOT_INITIALIZED);
+		goto err;
+	}
+
+	if (b->counter == -1)
+		b->counter = 0;
+
+	if (++b->counter == BN_BLINDING_COUNTER && b->e != NULL &&
+	    !(b->flags & BN_BLINDING_NO_RECREATE)) {
+		/* re-create blinding parameters */
+		if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL))
+			goto err;
+	} else if (!(b->flags & BN_BLINDING_NO_UPDATE)) {
+		if (!BN_mod_mul(b->A, b->A, b->A, b->mod, ctx))
+			goto err;
+		if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx))
+			goto err;
+	}
+
+	ret = 1;
+
+err:
+	if (b->counter == BN_BLINDING_COUNTER)
+		b->counter = 0;
+	return (ret);
+}
+
+int
+BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
+{
+	return BN_BLINDING_convert_ex(n, NULL, b, ctx);
+}
+
+int
+BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
+{
+	int ret = 1;
+
+	bn_check_top(n);
+
+	if ((b->A == NULL) || (b->Ai == NULL)) {
+		BNerr(BN_F_BN_BLINDING_CONVERT_EX, BN_R_NOT_INITIALIZED);
+		return (0);
+	}
+
+	if (b->counter == -1)
+		/* Fresh blinding, doesn't need updating. */
+		b->counter = 0;
+	else if (!BN_BLINDING_update(b, ctx))
+		return (0);
+
+	if (r != NULL) {
+		if (!BN_copy(r, b->Ai))
+			ret = 0;
+	}
+
+	if (!BN_mod_mul(n, n,b->A, b->mod, ctx))
+		ret = 0;
+
+	return ret;
+}
+
+int
+BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
+{
+	return BN_BLINDING_invert_ex(n, NULL, b, ctx);
+}
+
+int
+BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
+{
+	int ret;
+
+	bn_check_top(n);
+
+	if (r != NULL)
+		ret = BN_mod_mul(n, n, r, b->mod, ctx);
+	else {
+		if (b->Ai == NULL) {
+			BNerr(BN_F_BN_BLINDING_INVERT_EX, BN_R_NOT_INITIALIZED);
+			return (0);
+		}
+		ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx);
+	}
+
+	bn_check_top(n);
+	return (ret);
+}
+
+#ifndef OPENSSL_NO_DEPRECATED
+unsigned long
+BN_BLINDING_get_thread_id(const BN_BLINDING *b)
+{
+	return b->thread_id;
+}
+
+void
+BN_BLINDING_set_thread_id(BN_BLINDING *b, unsigned long n)
+{
+	b->thread_id = n;
+}
+#endif
+
+CRYPTO_THREADID *
+BN_BLINDING_thread_id(BN_BLINDING *b)
+{
+	return &b->tid;
+}
+
+unsigned long
+BN_BLINDING_get_flags(const BN_BLINDING *b)
+{
+	return b->flags;
+}
+
+void
+BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags)
+{
+	b->flags = flags;
+}
+
+BN_BLINDING *
+BN_BLINDING_create_param(BN_BLINDING *b, const BIGNUM *e, BIGNUM *m,
+    BN_CTX *ctx, int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx), BN_MONT_CTX *m_ctx)
+{
+	int    retry_counter = 32;
+	BN_BLINDING *ret = NULL;
+
+	if (b == NULL)
+		ret = BN_BLINDING_new(NULL, NULL, m);
+	else
+		ret = b;
+
+	if (ret == NULL)
+		goto err;
+
+	if (ret->A  == NULL && (ret->A = BN_new()) == NULL)
+		goto err;
+	if (ret->Ai == NULL && (ret->Ai = BN_new()) == NULL)
+		goto err;
+
+	if (e != NULL) {
+		BN_free(ret->e);
+		ret->e = BN_dup(e);
+	}
+	if (ret->e == NULL)
+		goto err;
+
+	if (bn_mod_exp != NULL)
+		ret->bn_mod_exp = bn_mod_exp;
+	if (m_ctx != NULL)
+		ret->m_ctx = m_ctx;
+
+	do {
+		if (!BN_rand_range(ret->A, ret->mod))
+			goto err;
+		if (BN_mod_inverse(ret->Ai, ret->A, ret->mod, ctx) == NULL) {
+			/* this should almost never happen for good RSA keys */
+			unsigned long error = ERR_peek_last_error();
+			if (ERR_GET_REASON(error) == BN_R_NO_INVERSE) {
+				if (retry_counter-- == 0) {
+					BNerr(BN_F_BN_BLINDING_CREATE_PARAM,
+					    BN_R_TOO_MANY_ITERATIONS);
+					goto err;
+				}
+				ERR_clear_error();
+			} else
+				goto err;
+		} else
+			break;
+	} while (1);
+
+	if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL) {
+		if (!ret->bn_mod_exp(ret->A, ret->A, ret->e, ret->mod,
+		    ctx, ret->m_ctx))
+			goto err;
+	} else {
+		if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx))
+			goto err;
+	}
+
+	return ret;
+
+err:
+	if (b == NULL && ret != NULL) {
+		BN_BLINDING_free(ret);
+		ret = NULL;
+	}
+
+	return ret;
+}
diff --git a/crypto/libressl/crypto/bn/bn_const.c b/crypto/libressl/crypto/bn/bn_const.c
new file mode 100644
index 0000000000..0c5b88b40e
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_const.c
@@ -0,0 +1,409 @@
+/* $OpenBSD$ */
+/* Insert boilerplate */
+
+#include 
+
+/* "First Oakley Default Group" from RFC2409, section 6.1.
+ *
+ * The prime is: 2^768 - 2 ^704 - 1 + 2^64 * { [2^638 pi] + 149686 }
+ *
+ * RFC2409 specifies a generator of 2.
+ * RFC2412 specifies a generator of of 22.
+ */
+
+BIGNUM *
+get_rfc2409_prime_768(BIGNUM *bn)
+{
+	static const unsigned char RFC2409_PRIME_768[] = {
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
+		0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+		0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
+		0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+		0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
+		0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+		0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
+		0xA6, 0x3A, 0x36, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	};
+	return BN_bin2bn(RFC2409_PRIME_768, sizeof(RFC2409_PRIME_768), bn);
+}
+
+/* "Second Oakley Default Group" from RFC2409, section 6.2.
+ *
+ * The prime is: 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }.
+ *
+ * RFC2409 specifies a generator of 2.
+ * RFC2412 specifies a generator of 22.
+ */
+
+BIGNUM *
+get_rfc2409_prime_1024(BIGNUM *bn)
+{
+	static const unsigned char RFC2409_PRIME_1024[] = {
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
+		0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+		0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
+		0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+		0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
+		0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+		0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
+		0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+		0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
+		0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	};
+	return BN_bin2bn(RFC2409_PRIME_1024, sizeof(RFC2409_PRIME_1024), bn);
+}
+
+/* "1536-bit MODP Group" from RFC3526, Section 2.
+ *
+ * The prime is: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 }
+ *
+ * RFC3526 specifies a generator of 2.
+ * RFC2312 specifies a generator of 22.
+ */
+
+BIGNUM *
+get_rfc3526_prime_1536(BIGNUM *bn)
+{
+	static const unsigned char RFC3526_PRIME_1536[] = {
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
+		0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+		0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
+		0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+		0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
+		0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+		0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
+		0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+		0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
+		0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+		0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
+		0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+		0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
+		0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+		0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
+		0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	};
+	return BN_bin2bn(RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536), bn);
+}
+
+/* "2048-bit MODP Group" from RFC3526, Section 3.
+ *
+ * The prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *
+get_rfc3526_prime_2048(BIGNUM *bn)
+{
+	static const unsigned char RFC3526_PRIME_2048[] = {
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
+		0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+		0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
+		0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+		0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
+		0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+		0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
+		0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+		0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
+		0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+		0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
+		0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+		0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
+		0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+		0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
+		0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+		0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
+		0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+		0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
+		0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+		0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF,
+	};
+	return BN_bin2bn(RFC3526_PRIME_2048, sizeof(RFC3526_PRIME_2048), bn);
+}
+
+/* "3072-bit MODP Group" from RFC3526, Section 4.
+ *
+ * The prime is: 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *
+get_rfc3526_prime_3072(BIGNUM *bn)
+{
+	static const unsigned char RFC3526_PRIME_3072[] = {
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
+		0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+		0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
+		0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+		0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
+		0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+		0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
+		0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+		0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
+		0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+		0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
+		0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+		0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
+		0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+		0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
+		0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+		0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
+		0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+		0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
+		0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+		0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
+		0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+		0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
+		0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+		0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
+		0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+		0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
+		0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+		0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
+		0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+		0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
+		0xA9, 0x3A, 0xD2, 0xCA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	};
+	return BN_bin2bn(RFC3526_PRIME_3072, sizeof(RFC3526_PRIME_3072), bn);
+}
+
+/* "4096-bit MODP Group" from RFC3526, Section 5.
+ *
+ * The prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *
+get_rfc3526_prime_4096(BIGNUM *bn)
+{
+	static const unsigned char RFC3526_PRIME_4096[] = {
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
+		0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+		0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
+		0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+		0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
+		0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+		0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
+		0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+		0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
+		0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+		0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
+		0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+		0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
+		0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+		0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
+		0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+		0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
+		0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+		0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
+		0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+		0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
+		0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+		0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
+		0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+		0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
+		0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+		0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
+		0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+		0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
+		0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+		0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
+		0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
+		0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,
+		0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
+		0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,
+		0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
+		0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,
+		0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
+		0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,
+		0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
+		0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,
+		0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	};
+	return BN_bin2bn(RFC3526_PRIME_4096, sizeof(RFC3526_PRIME_4096), bn);
+}
+
+/* "6144-bit MODP Group" from RFC3526, Section 6.
+ *
+ * The prime is: 2^6144 - 2^6080 - 1 + 2^64 * { [2^6014 pi] + 929484 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *
+get_rfc3526_prime_6144(BIGNUM *bn)
+{
+	static const unsigned char RFC3526_PRIME_6144[] = {
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
+		0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+		0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
+		0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+		0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
+		0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+		0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
+		0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+		0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
+		0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+		0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
+		0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+		0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
+		0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+		0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
+		0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+		0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
+		0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+		0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
+		0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+		0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
+		0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+		0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
+		0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+		0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
+		0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+		0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
+		0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+		0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
+		0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+		0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
+		0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
+		0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,
+		0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
+		0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,
+		0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
+		0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,
+		0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
+		0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,
+		0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
+		0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,
+		0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92,
+		0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, 0xC1, 0xD4, 0xDC, 0xB2,
+		0x60, 0x26, 0x46, 0xDE, 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD,
+		0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, 0xE5, 0xDB, 0x38, 0x2F,
+		0x41, 0x30, 0x01, 0xAE, 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31,
+		0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, 0xDA, 0x3E, 0xDB, 0xEB,
+		0xCF, 0x9B, 0x14, 0xED, 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B,
+		0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, 0x33, 0x20, 0x51, 0x51,
+		0x2B, 0xD7, 0xAF, 0x42, 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF,
+		0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, 0xF0, 0x32, 0xEA, 0x15,
+		0xD1, 0x72, 0x1D, 0x03, 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6,
+		0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, 0xB5, 0xA8, 0x40, 0x31,
+		0x90, 0x0B, 0x1C, 0x9E, 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3,
+		0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, 0x0F, 0x1D, 0x45, 0xB7,
+		0xFF, 0x58, 0x5A, 0xC5, 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA,
+		0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, 0x14, 0xCC, 0x5E, 0xD2,
+		0x0F, 0x80, 0x37, 0xE0, 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28,
+		0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, 0xF5, 0x50, 0xAA, 0x3D,
+		0x8A, 0x1F, 0xBF, 0xF0, 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C,
+		0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, 0x38, 0x7F, 0xE8, 0xD7,
+		0x6E, 0x3C, 0x04, 0x68, 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE,
+		0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, 0xE6, 0x94, 0xF9, 0x1E,
+		0x6D, 0xCC, 0x40, 0x24, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	};
+	return BN_bin2bn(RFC3526_PRIME_6144, sizeof(RFC3526_PRIME_6144), bn);
+}
+
+/* "8192-bit MODP Group" from RFC3526, Section 7.
+ *
+ * The prime is: 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *
+get_rfc3526_prime_8192(BIGNUM *bn)
+{
+	static const unsigned char RFC3526_PRIME_8192[] = {
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
+		0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+		0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
+		0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+		0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
+		0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+		0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
+		0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+		0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
+		0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+		0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
+		0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+		0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
+		0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+		0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
+		0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+		0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
+		0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+		0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
+		0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+		0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
+		0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+		0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
+		0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+		0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
+		0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+		0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
+		0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+		0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
+		0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+		0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
+		0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
+		0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,
+		0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
+		0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,
+		0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
+		0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,
+		0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
+		0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,
+		0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
+		0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,
+		0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92,
+		0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, 0xC1, 0xD4, 0xDC, 0xB2,
+		0x60, 0x26, 0x46, 0xDE, 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD,
+		0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, 0xE5, 0xDB, 0x38, 0x2F,
+		0x41, 0x30, 0x01, 0xAE, 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31,
+		0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, 0xDA, 0x3E, 0xDB, 0xEB,
+		0xCF, 0x9B, 0x14, 0xED, 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B,
+		0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, 0x33, 0x20, 0x51, 0x51,
+		0x2B, 0xD7, 0xAF, 0x42, 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF,
+		0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, 0xF0, 0x32, 0xEA, 0x15,
+		0xD1, 0x72, 0x1D, 0x03, 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6,
+		0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, 0xB5, 0xA8, 0x40, 0x31,
+		0x90, 0x0B, 0x1C, 0x9E, 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3,
+		0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, 0x0F, 0x1D, 0x45, 0xB7,
+		0xFF, 0x58, 0x5A, 0xC5, 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA,
+		0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, 0x14, 0xCC, 0x5E, 0xD2,
+		0x0F, 0x80, 0x37, 0xE0, 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28,
+		0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, 0xF5, 0x50, 0xAA, 0x3D,
+		0x8A, 0x1F, 0xBF, 0xF0, 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C,
+		0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, 0x38, 0x7F, 0xE8, 0xD7,
+		0x6E, 0x3C, 0x04, 0x68, 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE,
+		0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, 0xE6, 0x94, 0xF9, 0x1E,
+		0x6D, 0xBE, 0x11, 0x59, 0x74, 0xA3, 0x92, 0x6F, 0x12, 0xFE, 0xE5, 0xE4,
+		0x38, 0x77, 0x7C, 0xB6, 0xA9, 0x32, 0xDF, 0x8C, 0xD8, 0xBE, 0xC4, 0xD0,
+		0x73, 0xB9, 0x31, 0xBA, 0x3B, 0xC8, 0x32, 0xB6, 0x8D, 0x9D, 0xD3, 0x00,
+		0x74, 0x1F, 0xA7, 0xBF, 0x8A, 0xFC, 0x47, 0xED, 0x25, 0x76, 0xF6, 0x93,
+		0x6B, 0xA4, 0x24, 0x66, 0x3A, 0xAB, 0x63, 0x9C, 0x5A, 0xE4, 0xF5, 0x68,
+		0x34, 0x23, 0xB4, 0x74, 0x2B, 0xF1, 0xC9, 0x78, 0x23, 0x8F, 0x16, 0xCB,
+		0xE3, 0x9D, 0x65, 0x2D, 0xE3, 0xFD, 0xB8, 0xBE, 0xFC, 0x84, 0x8A, 0xD9,
+		0x22, 0x22, 0x2E, 0x04, 0xA4, 0x03, 0x7C, 0x07, 0x13, 0xEB, 0x57, 0xA8,
+		0x1A, 0x23, 0xF0, 0xC7, 0x34, 0x73, 0xFC, 0x64, 0x6C, 0xEA, 0x30, 0x6B,
+		0x4B, 0xCB, 0xC8, 0x86, 0x2F, 0x83, 0x85, 0xDD, 0xFA, 0x9D, 0x4B, 0x7F,
+		0xA2, 0xC0, 0x87, 0xE8, 0x79, 0x68, 0x33, 0x03, 0xED, 0x5B, 0xDD, 0x3A,
+		0x06, 0x2B, 0x3C, 0xF5, 0xB3, 0xA2, 0x78, 0xA6, 0x6D, 0x2A, 0x13, 0xF8,
+		0x3F, 0x44, 0xF8, 0x2D, 0xDF, 0x31, 0x0E, 0xE0, 0x74, 0xAB, 0x6A, 0x36,
+		0x45, 0x97, 0xE8, 0x99, 0xA0, 0x25, 0x5D, 0xC1, 0x64, 0xF3, 0x1C, 0xC5,
+		0x08, 0x46, 0x85, 0x1D, 0xF9, 0xAB, 0x48, 0x19, 0x5D, 0xED, 0x7E, 0xA1,
+		0xB1, 0xD5, 0x10, 0xBD, 0x7E, 0xE7, 0x4D, 0x73, 0xFA, 0xF3, 0x6B, 0xC3,
+		0x1E, 0xCF, 0xA2, 0x68, 0x35, 0x90, 0x46, 0xF4, 0xEB, 0x87, 0x9F, 0x92,
+		0x40, 0x09, 0x43, 0x8B, 0x48, 0x1C, 0x6C, 0xD7, 0x88, 0x9A, 0x00, 0x2E,
+		0xD5, 0xEE, 0x38, 0x2B, 0xC9, 0x19, 0x0D, 0xA6, 0xFC, 0x02, 0x6E, 0x47,
+		0x95, 0x58, 0xE4, 0x47, 0x56, 0x77, 0xE9, 0xAA, 0x9E, 0x30, 0x50, 0xE2,
+		0x76, 0x56, 0x94, 0xDF, 0xC8, 0x1F, 0x56, 0xE8, 0x80, 0xB9, 0x6E, 0x71,
+		0x60, 0xC9, 0x80, 0xDD, 0x98, 0xED, 0xD3, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF,
+	};
+	return BN_bin2bn(RFC3526_PRIME_8192, sizeof(RFC3526_PRIME_8192), bn);
+}
diff --git a/crypto/libressl/crypto/bn/bn_ctx.c b/crypto/libressl/crypto/bn/bn_ctx.c
new file mode 100644
index 0000000000..2723e6a835
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_ctx.c
@@ -0,0 +1,478 @@
+/* $OpenBSD: bn_ctx.c,v 1.13 2014/07/11 08:44:47 jsing Exp $ */
+/* Written by Ulf Moeller for the OpenSSL project. */
+/* ====================================================================
+ * Copyright (c) 1998-2004 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#if !defined(BN_CTX_DEBUG) && !defined(BN_DEBUG)
+#ifndef NDEBUG
+#define NDEBUG
+#endif
+#endif
+
+#include 
+#include 
+
+#include 
+
+#include 
+
+#include "bn_lcl.h"
+
+/* TODO list
+ *
+ * 1. Check a bunch of "(words+1)" type hacks in various bignum functions and
+ * check they can be safely removed.
+ *  - Check +1 and other ugliness in BN_from_montgomery()
+ *
+ * 2. Consider allowing a BN_new_ex() that, at least, lets you specify an
+ * appropriate 'block' size that will be honoured by bn_expand_internal() to
+ * prevent piddly little reallocations. OTOH, profiling bignum expansions in
+ * BN_CTX doesn't show this to be a big issue.
+ */
+
+/* How many bignums are in each "pool item"; */
+#define BN_CTX_POOL_SIZE	16
+/* The stack frame info is resizing, set a first-time expansion size; */
+#define BN_CTX_START_FRAMES	32
+
+/***********/
+/* BN_POOL */
+/***********/
+
+/* A bundle of bignums that can be linked with other bundles */
+typedef struct bignum_pool_item {
+	/* The bignum values */
+	BIGNUM vals[BN_CTX_POOL_SIZE];
+	/* Linked-list admin */
+	struct bignum_pool_item *prev, *next;
+} BN_POOL_ITEM;
+
+/* A linked-list of bignums grouped in bundles */
+typedef struct bignum_pool {
+	/* Linked-list admin */
+	BN_POOL_ITEM *head, *current, *tail;
+	/* Stack depth and allocation size */
+	unsigned used, size;
+} BN_POOL;
+
+static void		BN_POOL_init(BN_POOL *);
+static void		BN_POOL_finish(BN_POOL *);
+#ifndef OPENSSL_NO_DEPRECATED
+static void		BN_POOL_reset(BN_POOL *);
+#endif
+static BIGNUM *		BN_POOL_get(BN_POOL *);
+static void		BN_POOL_release(BN_POOL *, unsigned int);
+
+/************/
+/* BN_STACK */
+/************/
+
+/* A wrapper to manage the "stack frames" */
+typedef struct bignum_ctx_stack {
+	/* Array of indexes into the bignum stack */
+	unsigned int *indexes;
+	/* Number of stack frames, and the size of the allocated array */
+	unsigned int depth, size;
+} BN_STACK;
+
+static void		BN_STACK_init(BN_STACK *);
+static void		BN_STACK_finish(BN_STACK *);
+#ifndef OPENSSL_NO_DEPRECATED
+static void		BN_STACK_reset(BN_STACK *);
+#endif
+static int		BN_STACK_push(BN_STACK *, unsigned int);
+static unsigned int	BN_STACK_pop(BN_STACK *);
+
+/**********/
+/* BN_CTX */
+/**********/
+
+/* The opaque BN_CTX type */
+struct bignum_ctx {
+	/* The bignum bundles */
+	BN_POOL pool;
+	/* The "stack frames", if you will */
+	BN_STACK stack;
+	/* The number of bignums currently assigned */
+	unsigned int used;
+	/* Depth of stack overflow */
+	int err_stack;
+	/* Block "gets" until an "end" (compatibility behaviour) */
+	int too_many;
+};
+
+/* Enable this to find BN_CTX bugs */
+#ifdef BN_CTX_DEBUG
+static const char *ctxdbg_cur = NULL;
+
+static void
+ctxdbg(BN_CTX *ctx)
+{
+	unsigned int bnidx = 0, fpidx = 0;
+	BN_POOL_ITEM *item = ctx->pool.head;
+	BN_STACK *stack = &ctx->stack;
+
+	fprintf(stderr, "(%08x): ", (unsigned int)ctx);
+	while (bnidx < ctx->used) {
+		fprintf(stderr, "%03x ",
+		    item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax);
+		if (!(bnidx % BN_CTX_POOL_SIZE))
+			item = item->next;
+	}
+	fprintf(stderr, "\n");
+	bnidx = 0;
+	fprintf(stderr, "          : ");
+	while (fpidx < stack->depth) {
+		while (bnidx++ < stack->indexes[fpidx])
+			fprintf(stderr, "    ");
+		fprintf(stderr, "^^^ ");
+		bnidx++;
+		fpidx++;
+	}
+	fprintf(stderr, "\n");
+}
+#define CTXDBG_ENTRY(str, ctx) \
+	do { \
+		ctxdbg_cur = (str); \
+		fprintf(stderr, "Starting %s\n", ctxdbg_cur); \
+		ctxdbg(ctx); \
+	} while(0)
+
+#define CTXDBG_EXIT(ctx) \
+	do { \
+		fprintf(stderr, "Ending %s\n", ctxdbg_cur); \
+		ctxdbg(ctx); \
+	} while(0)
+
+#define CTXDBG_RET(ctx,ret)
+#else
+#define CTXDBG_ENTRY(str, ctx)
+#define CTXDBG_EXIT(ctx)
+#define CTXDBG_RET(ctx,ret)
+#endif
+
+/* This function is an evil legacy and should not be used. This implementation
+ * is WYSIWYG, though I've done my best. */
+#ifndef OPENSSL_NO_DEPRECATED
+void
+BN_CTX_init(BN_CTX *ctx)
+{
+	/* Assume the caller obtained the context via BN_CTX_new() and so is
+	 * trying to reset it for use. Nothing else makes sense, least of all
+	 * binary compatibility from a time when they could declare a static
+	 * variable. */
+	BN_POOL_reset(&ctx->pool);
+	BN_STACK_reset(&ctx->stack);
+	ctx->used = 0;
+	ctx->err_stack = 0;
+	ctx->too_many = 0;
+}
+#endif
+
+BN_CTX *
+BN_CTX_new(void)
+{
+	BN_CTX *ret = malloc(sizeof(BN_CTX));
+	if (!ret) {
+		BNerr(BN_F_BN_CTX_NEW, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+
+	/* Initialise the structure */
+	BN_POOL_init(&ret->pool);
+	BN_STACK_init(&ret->stack);
+	ret->used = 0;
+	ret->err_stack = 0;
+	ret->too_many = 0;
+	return ret;
+}
+
+void
+BN_CTX_free(BN_CTX *ctx)
+{
+	if (ctx == NULL)
+		return;
+#ifdef BN_CTX_DEBUG
+	{
+		BN_POOL_ITEM *pool = ctx->pool.head;
+		fprintf(stderr, "BN_CTX_free, stack-size=%d, pool-bignums=%d\n",
+		    ctx->stack.size, ctx->pool.size);
+		fprintf(stderr, "dmaxs: ");
+		while (pool) {
+			unsigned loop = 0;
+			while (loop < BN_CTX_POOL_SIZE)
+				fprintf(stderr, "%02x ",
+				    pool->vals[loop++].dmax);
+			pool = pool->next;
+		}
+		fprintf(stderr, "\n");
+	}
+#endif
+	BN_STACK_finish(&ctx->stack);
+	BN_POOL_finish(&ctx->pool);
+	free(ctx);
+}
+
+void
+BN_CTX_start(BN_CTX *ctx)
+{
+	CTXDBG_ENTRY("BN_CTX_start", ctx);
+
+	/* If we're already overflowing ... */
+	if (ctx->err_stack || ctx->too_many)
+		ctx->err_stack++;
+	/* (Try to) get a new frame pointer */
+	else if (!BN_STACK_push(&ctx->stack, ctx->used)) {
+		BNerr(BN_F_BN_CTX_START, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
+		ctx->err_stack++;
+	}
+	CTXDBG_EXIT(ctx);
+}
+
+void
+BN_CTX_end(BN_CTX *ctx)
+{
+	CTXDBG_ENTRY("BN_CTX_end", ctx);
+
+	if (ctx->err_stack)
+		ctx->err_stack--;
+	else {
+		unsigned int fp = BN_STACK_pop(&ctx->stack);
+		/* Does this stack frame have anything to release? */
+		if (fp < ctx->used)
+			BN_POOL_release(&ctx->pool, ctx->used - fp);
+		ctx->used = fp;
+		/* Unjam "too_many" in case "get" had failed */
+		ctx->too_many = 0;
+	}
+	CTXDBG_EXIT(ctx);
+}
+
+BIGNUM *
+BN_CTX_get(BN_CTX *ctx)
+{
+	BIGNUM *ret;
+
+	CTXDBG_ENTRY("BN_CTX_get", ctx);
+
+	if (ctx->err_stack || ctx->too_many)
+		return NULL;
+	if ((ret = BN_POOL_get(&ctx->pool)) == NULL) {
+		/* Setting too_many prevents repeated "get" attempts from
+		 * cluttering the error stack. */
+		ctx->too_many = 1;
+		BNerr(BN_F_BN_CTX_GET, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
+		return NULL;
+	}
+	/* OK, make sure the returned bignum is "zero" */
+	BN_zero(ret);
+	ctx->used++;
+	CTXDBG_RET(ctx, ret);
+	return ret;
+}
+
+/************/
+/* BN_STACK */
+/************/
+
+static void
+BN_STACK_init(BN_STACK *st)
+{
+	st->indexes = NULL;
+	st->depth = st->size = 0;
+}
+
+static void
+BN_STACK_finish(BN_STACK *st)
+{
+	if (st->size)
+		free(st->indexes);
+}
+
+#ifndef OPENSSL_NO_DEPRECATED
+static void
+BN_STACK_reset(BN_STACK *st)
+{
+	st->depth = 0;
+}
+#endif
+
+static int
+BN_STACK_push(BN_STACK *st, unsigned int idx)
+{
+	if (st->depth == st->size)
+		/* Need to expand */
+	{
+		unsigned int newsize = (st->size ?
+		    (st->size * 3 / 2) : BN_CTX_START_FRAMES);
+		unsigned int *newitems = reallocarray(NULL,
+		    newsize, sizeof(unsigned int));
+		if (!newitems)
+			return 0;
+		if (st->depth)
+			memcpy(newitems, st->indexes, st->depth *
+			    sizeof(unsigned int));
+		if (st->size)
+			free(st->indexes);
+		st->indexes = newitems;
+		st->size = newsize;
+	}
+	st->indexes[(st->depth)++] = idx;
+	return 1;
+}
+
+static unsigned int
+BN_STACK_pop(BN_STACK *st)
+{
+	return st->indexes[--(st->depth)];
+}
+
+/***********/
+/* BN_POOL */
+/***********/
+
+static void
+BN_POOL_init(BN_POOL *p)
+{
+	p->head = p->current = p->tail = NULL;
+	p->used = p->size = 0;
+}
+
+static void
+BN_POOL_finish(BN_POOL *p)
+{
+	while (p->head) {
+		unsigned int loop = 0;
+		BIGNUM *bn = p->head->vals;
+		while (loop++ < BN_CTX_POOL_SIZE) {
+			if (bn->d)
+				BN_clear_free(bn);
+			bn++;
+		}
+		p->current = p->head->next;
+		free(p->head);
+		p->head = p->current;
+	}
+}
+
+#ifndef OPENSSL_NO_DEPRECATED
+static void
+BN_POOL_reset(BN_POOL *p)
+{
+	BN_POOL_ITEM *item = p->head;
+	while (item) {
+		unsigned int loop = 0;
+		BIGNUM *bn = item->vals;
+		while (loop++ < BN_CTX_POOL_SIZE) {
+			if (bn->d)
+				BN_clear(bn);
+			bn++;
+		}
+		item = item->next;
+	}
+	p->current = p->head;
+	p->used = 0;
+}
+#endif
+
+static BIGNUM *
+BN_POOL_get(BN_POOL *p)
+{
+	if (p->used == p->size) {
+		BIGNUM *bn;
+		unsigned int loop = 0;
+		BN_POOL_ITEM *item = malloc(sizeof(BN_POOL_ITEM));
+		if (!item)
+			return NULL;
+		/* Initialise the structure */
+		bn = item->vals;
+		while (loop++ < BN_CTX_POOL_SIZE)
+			BN_init(bn++);
+		item->prev = p->tail;
+		item->next = NULL;
+		/* Link it in */
+		if (!p->head)
+			p->head = p->current = p->tail = item;
+		else {
+			p->tail->next = item;
+			p->tail = item;
+			p->current = item;
+		}
+		p->size += BN_CTX_POOL_SIZE;
+		p->used++;
+		/* Return the first bignum from the new pool */
+		return item->vals;
+	}
+	if (!p->used)
+		p->current = p->head;
+	else if ((p->used % BN_CTX_POOL_SIZE) == 0)
+		p->current = p->current->next;
+	return p->current->vals + ((p->used++) % BN_CTX_POOL_SIZE);
+}
+
+static void
+BN_POOL_release(BN_POOL *p, unsigned int num)
+{
+	unsigned int offset = (p->used - 1) % BN_CTX_POOL_SIZE;
+
+	p->used -= num;
+	while (num--) {
+		bn_check_top(p->current->vals + offset);
+		if (!offset) {
+			offset = BN_CTX_POOL_SIZE - 1;
+			p->current = p->current->prev;
+		} else
+			offset--;
+	}
+}
diff --git a/crypto/libressl/crypto/bn/bn_depr.c b/crypto/libressl/crypto/bn/bn_depr.c
new file mode 100644
index 0000000000..a4d4fc3f1b
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_depr.c
@@ -0,0 +1,115 @@
+/* $OpenBSD: bn_depr.c,v 1.6 2014/07/11 08:44:47 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Support for deprecated functions goes here - static linkage will only slurp
+ * this code if applications are using them directly. */
+
+#include 
+#include 
+
+#include 
+
+#include "bn_lcl.h"
+
+#ifndef OPENSSL_NO_DEPRECATED
+BIGNUM *
+BN_generate_prime(BIGNUM *ret, int bits, int safe, const BIGNUM *add,
+    const BIGNUM *rem, void (*callback)(int, int, void *), void *cb_arg)
+{
+	BN_GENCB cb;
+	BIGNUM *rnd = NULL;
+	int found = 0;
+
+	BN_GENCB_set_old(&cb, callback, cb_arg);
+
+	if (ret == NULL) {
+		if ((rnd = BN_new()) == NULL)
+			goto err;
+	} else
+		rnd = ret;
+	if (!BN_generate_prime_ex(rnd, bits, safe, add, rem, &cb))
+		goto err;
+
+	/* we have a prime :-) */
+	found = 1;
+
+err:
+	if (!found && (ret == NULL) && (rnd != NULL))
+		BN_free(rnd);
+	return (found ? rnd : NULL);
+}
+
+int
+BN_is_prime(const BIGNUM *a, int checks, void (*callback)(int, int, void *),
+    BN_CTX *ctx_passed, void *cb_arg)
+{
+	BN_GENCB cb;
+
+	BN_GENCB_set_old(&cb, callback, cb_arg);
+	return BN_is_prime_ex(a, checks, ctx_passed, &cb);
+}
+
+int
+BN_is_prime_fasttest(const BIGNUM *a, int checks,
+    void (*callback)(int, int, void *), BN_CTX *ctx_passed, void *cb_arg,
+    int do_trial_division)
+{
+	BN_GENCB cb;
+
+	BN_GENCB_set_old(&cb, callback, cb_arg);
+	return BN_is_prime_fasttest_ex(a, checks, ctx_passed,
+	    do_trial_division, &cb);
+}
+#endif
diff --git a/crypto/libressl/crypto/bn/bn_div.c b/crypto/libressl/crypto/bn/bn_div.c
new file mode 100644
index 0000000000..fcf844fe2b
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_div.c
@@ -0,0 +1,381 @@
+/* $OpenBSD: bn_div.c,v 1.22 2014/07/11 08:44:47 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+#include "bn_lcl.h"
+
+#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) \
+    && !defined(BN_DIV3W)
+# if defined(__GNUC__) && __GNUC__>=2
+#  if defined(__i386) || defined (__i386__)
+   /*
+    * There were two reasons for implementing this template:
+    * - GNU C generates a call to a function (__udivdi3 to be exact)
+    *   in reply to ((((BN_ULLONG)n0)<
+    */
+#undef bn_div_words
+#  define bn_div_words(n0,n1,d0)		\
+	({  asm volatile (			\
+		"divl	%4"			\
+		: "=a"(q), "=d"(rem)		\
+		: "a"(n1), "d"(n0), "g"(d0)	\
+		: "cc");			\
+	    q;					\
+	})
+#  define REMAINDER_IS_ALREADY_CALCULATED
+#  elif defined(__x86_64)
+   /*
+    * Same story here, but it's 128-bit by 64-bit division. Wow!
+    *					
+    */
+#  undef bn_div_words
+#  define bn_div_words(n0,n1,d0)		\
+	({  asm volatile (			\
+		"divq	%4"			\
+		: "=a"(q), "=d"(rem)		\
+		: "a"(n1), "d"(n0), "g"(d0)	\
+		: "cc");			\
+	    q;					\
+	})
+#  define REMAINDER_IS_ALREADY_CALCULATED
+#  endif /* __ */
+# endif /* __GNUC__ */
+#endif /* OPENSSL_NO_ASM */
+
+
+/* BN_div computes  dv := num / divisor,  rounding towards
+ * zero, and sets up rm  such that  dv*divisor + rm = num  holds.
+ * Thus:
+ *     dv->neg == num->neg ^ divisor->neg  (unless the result is zero)
+ *     rm->neg == num->neg                 (unless the remainder is zero)
+ * If 'dv' or 'rm' is NULL, the respective value is not returned.
+ */
+int
+BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
+    BN_CTX *ctx)
+{
+	int norm_shift, i, loop;
+	BIGNUM *tmp, wnum, *snum, *sdiv, *res;
+	BN_ULONG *resp, *wnump;
+	BN_ULONG d0, d1;
+	int num_n, div_n;
+	int no_branch = 0;
+
+	/* Invalid zero-padding would have particularly bad consequences
+	 * in the case of 'num', so don't just rely on bn_check_top() for this one
+	 * (bn_check_top() works only for BN_DEBUG builds) */
+	if (num->top > 0 && num->d[num->top - 1] == 0) {
+		BNerr(BN_F_BN_DIV, BN_R_NOT_INITIALIZED);
+		return 0;
+	}
+
+	bn_check_top(num);
+
+	if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0) ||
+	    (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0)) {
+		no_branch = 1;
+	}
+
+	bn_check_top(dv);
+	bn_check_top(rm);
+	/* bn_check_top(num); */ /* 'num' has been checked already */
+	bn_check_top(divisor);
+
+	if (BN_is_zero(divisor)) {
+		BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO);
+		return (0);
+	}
+
+	if (!no_branch && BN_ucmp(num, divisor) < 0) {
+		if (rm != NULL) {
+			if (BN_copy(rm, num) == NULL)
+				return (0);
+		}
+		if (dv != NULL)
+			BN_zero(dv);
+		return (1);
+	}
+
+	BN_CTX_start(ctx);
+	tmp = BN_CTX_get(ctx);
+	snum = BN_CTX_get(ctx);
+	sdiv = BN_CTX_get(ctx);
+	if (dv == NULL)
+		res = BN_CTX_get(ctx);
+	else
+		res = dv;
+	if (tmp == NULL || snum == NULL || sdiv == NULL || res == NULL)
+		goto err;
+
+	/* First we normalise the numbers */
+	norm_shift = BN_BITS2 - ((BN_num_bits(divisor)) % BN_BITS2);
+	if (!(BN_lshift(sdiv, divisor, norm_shift)))
+		goto err;
+	sdiv->neg = 0;
+	norm_shift += BN_BITS2;
+	if (!(BN_lshift(snum, num, norm_shift)))
+		goto err;
+	snum->neg = 0;
+
+	if (no_branch) {
+		/* Since we don't know whether snum is larger than sdiv,
+		 * we pad snum with enough zeroes without changing its
+		 * value.
+		 */
+		if (snum->top <= sdiv->top + 1) {
+			if (bn_wexpand(snum, sdiv->top + 2) == NULL)
+				goto err;
+			for (i = snum->top; i < sdiv->top + 2; i++)
+				snum->d[i] = 0;
+			snum->top = sdiv->top + 2;
+		} else {
+			if (bn_wexpand(snum, snum->top + 1) == NULL)
+				goto err;
+			snum->d[snum->top] = 0;
+			snum->top ++;
+		}
+	}
+
+	div_n = sdiv->top;
+	num_n = snum->top;
+	loop = num_n - div_n;
+	/* Lets setup a 'window' into snum
+	 * This is the part that corresponds to the current
+	 * 'area' being divided */
+	wnum.neg = 0;
+	wnum.d = &(snum->d[loop]);
+	wnum.top = div_n;
+	/* only needed when BN_ucmp messes up the values between top and max */
+	wnum.dmax  = snum->dmax - loop; /* so we don't step out of bounds */
+	wnum.flags = snum->flags | BN_FLG_STATIC_DATA;
+
+	/* Get the top 2 words of sdiv */
+	/* div_n=sdiv->top; */
+	d0 = sdiv->d[div_n - 1];
+	d1 = (div_n == 1) ? 0 : sdiv->d[div_n - 2];
+
+	/* pointer to the 'top' of snum */
+	wnump = &(snum->d[num_n - 1]);
+
+	/* Setup to 'res' */
+	res->neg = (num->neg ^ divisor->neg);
+	if (!bn_wexpand(res, (loop + 1)))
+		goto err;
+	res->top = loop - no_branch;
+	resp = &(res->d[loop - 1]);
+
+	/* space for temp */
+	if (!bn_wexpand(tmp, (div_n + 1)))
+		goto err;
+
+	if (!no_branch) {
+		if (BN_ucmp(&wnum, sdiv) >= 0) {
+			/* If BN_DEBUG_RAND is defined BN_ucmp changes (via
+			 * bn_pollute) the const bignum arguments =>
+			 * clean the values between top and max again */
+			bn_clear_top2max(&wnum);
+			bn_sub_words(wnum.d, wnum.d, sdiv->d, div_n);
+			*resp = 1;
+		} else
+			res->top--;
+	}
+
+	/* if res->top == 0 then clear the neg value otherwise decrease
+	 * the resp pointer */
+	if (res->top == 0)
+		res->neg = 0;
+	else
+		resp--;
+
+	for (i = 0; i < loop - 1; i++, wnump--, resp--) {
+		BN_ULONG q, l0;
+		/* the first part of the loop uses the top two words of
+		 * snum and sdiv to calculate a BN_ULONG q such that
+		 * | wnum - sdiv * q | < sdiv */
+#if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM)
+		BN_ULONG bn_div_3_words(BN_ULONG*, BN_ULONG, BN_ULONG);
+		q = bn_div_3_words(wnump, d1, d0);
+#else
+		BN_ULONG n0, n1, rem = 0;
+
+		n0 = wnump[0];
+		n1 = wnump[-1];
+		if (n0 == d0)
+			q = BN_MASK2;
+		else 			/* n0 < d0 */
+		{
+#ifdef BN_LLONG
+			BN_ULLONG t2;
+
+#if defined(BN_DIV2W) && !defined(bn_div_words)
+			q = (BN_ULONG)(((((BN_ULLONG)n0) << BN_BITS2)|n1)/d0);
+#else
+			q = bn_div_words(n0, n1, d0);
+#endif
+
+#ifndef REMAINDER_IS_ALREADY_CALCULATED
+			/*
+			 * rem doesn't have to be BN_ULLONG. The least we
+			 * know it's less that d0, isn't it?
+			 */
+			rem = (n1 - q * d0) & BN_MASK2;
+#endif
+			t2 = (BN_ULLONG)d1*q;
+
+			for (;;) {
+				if (t2 <= ((((BN_ULLONG)rem) << BN_BITS2) |
+				    wnump[-2]))
+					break;
+				q--;
+				rem += d0;
+				if (rem < d0) break; /* don't let rem overflow */
+					t2 -= d1;
+			}
+#else /* !BN_LLONG */
+			BN_ULONG t2l, t2h;
+
+			q = bn_div_words(n0, n1, d0);
+#ifndef REMAINDER_IS_ALREADY_CALCULATED
+			rem = (n1 - q*d0)&BN_MASK2;
+#endif
+
+#if defined(BN_UMULT_LOHI)
+			BN_UMULT_LOHI(t2l, t2h, d1, q);
+#elif defined(BN_UMULT_HIGH)
+			t2l = d1 * q;
+			t2h = BN_UMULT_HIGH(d1, q);
+#else
+			{
+				BN_ULONG ql, qh;
+				t2l = LBITS(d1);
+				t2h = HBITS(d1);
+				ql = LBITS(q);
+				qh = HBITS(q);
+				mul64(t2l, t2h, ql, qh); /* t2=(BN_ULLONG)d1*q; */
+			}
+#endif
+
+			for (;;) {
+				if ((t2h < rem) ||
+				    ((t2h == rem) && (t2l <= wnump[-2])))
+					break;
+				q--;
+				rem += d0;
+				if (rem < d0)
+					break; /* don't let rem overflow */
+				if (t2l < d1)
+					t2h--;
+				t2l -= d1;
+			}
+#endif /* !BN_LLONG */
+		}
+#endif /* !BN_DIV3W */
+
+		l0 = bn_mul_words(tmp->d, sdiv->d, div_n, q);
+		tmp->d[div_n] = l0;
+		wnum.d--;
+		/* ingore top values of the bignums just sub the two
+		 * BN_ULONG arrays with bn_sub_words */
+		if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n + 1)) {
+			/* Note: As we have considered only the leading
+			 * two BN_ULONGs in the calculation of q, sdiv * q
+			 * might be greater than wnum (but then (q-1) * sdiv
+			 * is less or equal than wnum)
+			 */
+			q--;
+			if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n))
+				/* we can't have an overflow here (assuming
+				 * that q != 0, but if q == 0 then tmp is
+				 * zero anyway) */
+				(*wnump)++;
+		}
+		/* store part of the result */
+		*resp = q;
+	}
+	bn_correct_top(snum);
+	if (rm != NULL) {
+		/* Keep a copy of the neg flag in num because if rm==num
+		 * BN_rshift() will overwrite it.
+		 */
+		int neg = num->neg;
+		BN_rshift(rm, snum, norm_shift);
+		if (!BN_is_zero(rm))
+			rm->neg = neg;
+		bn_check_top(rm);
+	}
+	if (no_branch)
+		bn_correct_top(res);
+	BN_CTX_end(ctx);
+	return (1);
+
+err:
+	bn_check_top(rm);
+	BN_CTX_end(ctx);
+	return (0);
+}
diff --git a/crypto/libressl/crypto/bn/bn_err.c b/crypto/libressl/crypto/bn/bn_err.c
new file mode 100644
index 0000000000..fb4bf34139
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_err.c
@@ -0,0 +1,152 @@
+/* $OpenBSD: bn_err.c,v 1.12 2014/07/10 22:45:56 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_BN,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_BN,0,reason)
+
+static ERR_STRING_DATA BN_str_functs[]= {
+	{ERR_FUNC(BN_F_BNRAND),	"BNRAND"},
+	{ERR_FUNC(BN_F_BN_BLINDING_CONVERT_EX),	"BN_BLINDING_convert_ex"},
+	{ERR_FUNC(BN_F_BN_BLINDING_CREATE_PARAM),	"BN_BLINDING_create_param"},
+	{ERR_FUNC(BN_F_BN_BLINDING_INVERT_EX),	"BN_BLINDING_invert_ex"},
+	{ERR_FUNC(BN_F_BN_BLINDING_NEW),	"BN_BLINDING_new"},
+	{ERR_FUNC(BN_F_BN_BLINDING_UPDATE),	"BN_BLINDING_update"},
+	{ERR_FUNC(BN_F_BN_BN2DEC),	"BN_bn2dec"},
+	{ERR_FUNC(BN_F_BN_BN2HEX),	"BN_bn2hex"},
+	{ERR_FUNC(BN_F_BN_CTX_GET),	"BN_CTX_get"},
+	{ERR_FUNC(BN_F_BN_CTX_NEW),	"BN_CTX_new"},
+	{ERR_FUNC(BN_F_BN_CTX_START),	"BN_CTX_start"},
+	{ERR_FUNC(BN_F_BN_DIV),	"BN_div"},
+	{ERR_FUNC(BN_F_BN_DIV_NO_BRANCH),	"BN_div_no_branch"},
+	{ERR_FUNC(BN_F_BN_DIV_RECP),	"BN_div_recp"},
+	{ERR_FUNC(BN_F_BN_EXP),	"BN_exp"},
+	{ERR_FUNC(BN_F_BN_EXPAND2),	"bn_expand2"},
+	{ERR_FUNC(BN_F_BN_EXPAND_INTERNAL),	"BN_EXPAND_INTERNAL"},
+	{ERR_FUNC(BN_F_BN_GENERATE_PRIME_EX),	"BN_generate_prime_ex"},
+	{ERR_FUNC(BN_F_BN_GF2M_MOD),	"BN_GF2m_mod"},
+	{ERR_FUNC(BN_F_BN_GF2M_MOD_EXP),	"BN_GF2m_mod_exp"},
+	{ERR_FUNC(BN_F_BN_GF2M_MOD_MUL),	"BN_GF2m_mod_mul"},
+	{ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD),	"BN_GF2m_mod_solve_quad"},
+	{ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR),	"BN_GF2m_mod_solve_quad_arr"},
+	{ERR_FUNC(BN_F_BN_GF2M_MOD_SQR),	"BN_GF2m_mod_sqr"},
+	{ERR_FUNC(BN_F_BN_GF2M_MOD_SQRT),	"BN_GF2m_mod_sqrt"},
+	{ERR_FUNC(BN_F_BN_MOD_EXP2_MONT),	"BN_mod_exp2_mont"},
+	{ERR_FUNC(BN_F_BN_MOD_EXP_MONT),	"BN_mod_exp_mont"},
+	{ERR_FUNC(BN_F_BN_MOD_EXP_MONT_CONSTTIME),	"BN_mod_exp_mont_consttime"},
+	{ERR_FUNC(BN_F_BN_MOD_EXP_MONT_WORD),	"BN_mod_exp_mont_word"},
+	{ERR_FUNC(BN_F_BN_MOD_EXP_RECP),	"BN_mod_exp_recp"},
+	{ERR_FUNC(BN_F_BN_MOD_EXP_SIMPLE),	"BN_mod_exp_simple"},
+	{ERR_FUNC(BN_F_BN_MOD_INVERSE),	"BN_mod_inverse"},
+	{ERR_FUNC(BN_F_BN_MOD_INVERSE_NO_BRANCH),	"BN_mod_inverse_no_branch"},
+	{ERR_FUNC(BN_F_BN_MOD_LSHIFT_QUICK),	"BN_mod_lshift_quick"},
+	{ERR_FUNC(BN_F_BN_MOD_MUL_RECIPROCAL),	"BN_mod_mul_reciprocal"},
+	{ERR_FUNC(BN_F_BN_MOD_SQRT),	"BN_mod_sqrt"},
+	{ERR_FUNC(BN_F_BN_MPI2BN),	"BN_mpi2bn"},
+	{ERR_FUNC(BN_F_BN_NEW),	"BN_new"},
+	{ERR_FUNC(BN_F_BN_RAND),	"BN_rand"},
+	{ERR_FUNC(BN_F_BN_RAND_RANGE),	"BN_rand_range"},
+	{ERR_FUNC(BN_F_BN_USUB),	"BN_usub"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA BN_str_reasons[]= {
+	{ERR_REASON(BN_R_ARG2_LT_ARG3)           , "arg2 lt arg3"},
+	{ERR_REASON(BN_R_BAD_RECIPROCAL)         , "bad reciprocal"},
+	{ERR_REASON(BN_R_BIGNUM_TOO_LONG)        , "bignum too long"},
+	{ERR_REASON(BN_R_BITS_TOO_SMALL)         , "bits too small"},
+	{ERR_REASON(BN_R_CALLED_WITH_EVEN_MODULUS), "called with even modulus"},
+	{ERR_REASON(BN_R_DIV_BY_ZERO)            , "div by zero"},
+	{ERR_REASON(BN_R_ENCODING_ERROR)         , "encoding error"},
+	{ERR_REASON(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA), "expand on static bignum data"},
+	{ERR_REASON(BN_R_INPUT_NOT_REDUCED)      , "input not reduced"},
+	{ERR_REASON(BN_R_INVALID_LENGTH)         , "invalid length"},
+	{ERR_REASON(BN_R_INVALID_RANGE)          , "invalid range"},
+	{ERR_REASON(BN_R_NOT_A_SQUARE)           , "not a square"},
+	{ERR_REASON(BN_R_NOT_INITIALIZED)        , "not initialized"},
+	{ERR_REASON(BN_R_NO_INVERSE)             , "no inverse"},
+	{ERR_REASON(BN_R_NO_SOLUTION)            , "no solution"},
+	{ERR_REASON(BN_R_P_IS_NOT_PRIME)         , "p is not prime"},
+	{ERR_REASON(BN_R_TOO_MANY_ITERATIONS)    , "too many iterations"},
+	{ERR_REASON(BN_R_TOO_MANY_TEMPORARY_VARIABLES), "too many temporary variables"},
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_BN_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(BN_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, BN_str_functs);
+		ERR_load_strings(0, BN_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/bn/bn_exp.c b/crypto/libressl/crypto/bn/bn_exp.c
new file mode 100644
index 0000000000..e6becc8887
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_exp.c
@@ -0,0 +1,1097 @@
+/* $OpenBSD: bn_exp.c,v 1.22 2015/03/21 08:05:20 doug Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+
+#include "bn_lcl.h"
+
+/* maximum precomputation table size for *variable* sliding windows */
+#define TABLE_SIZE	32
+
+/* this one works - simple but works */
+int
+BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+{
+	int i, bits, ret = 0;
+	BIGNUM *v, *rr;
+
+	if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
+		/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
+		BNerr(BN_F_BN_EXP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return -1;
+	}
+
+	BN_CTX_start(ctx);
+	if ((r == a) || (r == p))
+		rr = BN_CTX_get(ctx);
+	else
+		rr = r;
+	v = BN_CTX_get(ctx);
+	if (rr == NULL || v == NULL)
+		goto err;
+
+	if (BN_copy(v, a) == NULL)
+		goto err;
+	bits = BN_num_bits(p);
+
+	if (BN_is_odd(p)) {
+		if (BN_copy(rr, a) == NULL)
+			goto err;
+	} else {
+		if (!BN_one(rr))
+			goto err;
+	}
+
+	for (i = 1; i < bits; i++) {
+		if (!BN_sqr(v, v, ctx))
+			goto err;
+		if (BN_is_bit_set(p, i)) {
+			if (!BN_mul(rr, rr, v, ctx))
+				goto err;
+		}
+	}
+	ret = 1;
+
+err:
+	if (r != rr && rr != NULL)
+		BN_copy(r, rr);
+	BN_CTX_end(ctx);
+	bn_check_top(r);
+	return (ret);
+}
+
+int
+BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
+    BN_CTX *ctx)
+{
+	int ret;
+
+	bn_check_top(a);
+	bn_check_top(p);
+	bn_check_top(m);
+
+	/* For even modulus  m = 2^k*m_odd,  it might make sense to compute
+	 * a^p mod m_odd  and  a^p mod 2^k  separately (with Montgomery
+	 * exponentiation for the odd part), using appropriate exponent
+	 * reductions, and combine the results using the CRT.
+	 *
+	 * For now, we use Montgomery only if the modulus is odd; otherwise,
+	 * exponentiation using the reciprocal-based quick remaindering
+	 * algorithm is used.
+	 *
+	 * (Timing obtained with expspeed.c [computations  a^p mod m
+	 * where  a, p, m  are of the same length: 256, 512, 1024, 2048,
+	 * 4096, 8192 bits], compared to the running time of the
+	 * standard algorithm:
+	 *
+	 *   BN_mod_exp_mont   33 .. 40 %  [AMD K6-2, Linux, debug configuration]
+         *                     55 .. 77 %  [UltraSparc processor, but
+	 *                                  debug-solaris-sparcv8-gcc conf.]
+	 *
+	 *   BN_mod_exp_recp   50 .. 70 %  [AMD K6-2, Linux, debug configuration]
+	 *                     62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc]
+	 *
+	 * On the Sparc, BN_mod_exp_recp was faster than BN_mod_exp_mont
+	 * at 2048 and more bits, but at 512 and 1024 bits, it was
+	 * slower even than the standard algorithm!
+	 *
+	 * "Real" timings [linux-elf, solaris-sparcv9-gcc configurations]
+	 * should be obtained when the new Montgomery reduction code
+	 * has been integrated into OpenSSL.)
+	 */
+
+#define MONT_MUL_MOD
+#define MONT_EXP_WORD
+#define RECP_MUL_MOD
+
+#ifdef MONT_MUL_MOD
+	/* I have finally been able to take out this pre-condition of
+	 * the top bit being set.  It was caused by an error in BN_div
+	 * with negatives.  There was also another problem when for a^b%m
+	 * a >= m.  eay 07-May-97 */
+/*	if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */
+
+	if (BN_is_odd(m)) {
+#  ifdef MONT_EXP_WORD
+		if (a->top == 1 && !a->neg &&
+		    (BN_get_flags(p, BN_FLG_CONSTTIME) == 0)) {
+			BN_ULONG A = a->d[0];
+			ret = BN_mod_exp_mont_word(r, A,p, m,ctx, NULL);
+		} else
+#  endif
+			ret = BN_mod_exp_mont(r, a,p, m,ctx, NULL);
+	} else
+#endif
+#ifdef RECP_MUL_MOD
+	{
+		ret = BN_mod_exp_recp(r, a,p, m, ctx);
+	}
+#else
+	{
+		ret = BN_mod_exp_simple(r, a,p, m, ctx);
+	}
+#endif
+
+	bn_check_top(r);
+	return (ret);
+}
+
+int
+BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
+    BN_CTX *ctx)
+{
+	int i, j, bits, ret = 0, wstart, wend, window, wvalue;
+	int start = 1;
+	BIGNUM *aa;
+	/* Table of variables obtained from 'ctx' */
+	BIGNUM *val[TABLE_SIZE];
+	BN_RECP_CTX recp;
+
+	if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
+		/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
+		BNerr(BN_F_BN_MOD_EXP_RECP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return -1;
+	}
+
+	bits = BN_num_bits(p);
+
+	if (bits == 0) {
+		ret = BN_one(r);
+		return ret;
+	}
+
+	BN_CTX_start(ctx);
+	if ((aa = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((val[0] = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	BN_RECP_CTX_init(&recp);
+	if (m->neg) {
+		/* ignore sign of 'm' */
+		if (!BN_copy(aa, m))
+			goto err;
+		aa->neg = 0;
+		if (BN_RECP_CTX_set(&recp, aa, ctx) <= 0)
+			goto err;
+	} else {
+		if (BN_RECP_CTX_set(&recp, m, ctx) <= 0)
+			goto err;
+	}
+
+	if (!BN_nnmod(val[0], a, m, ctx))
+		goto err;		/* 1 */
+	if (BN_is_zero(val[0])) {
+		BN_zero(r);
+		ret = 1;
+		goto err;
+	}
+
+	window = BN_window_bits_for_exponent_size(bits);
+	if (window > 1) {
+		if (!BN_mod_mul_reciprocal(aa, val[0], val[0], &recp, ctx))
+			goto err;				/* 2 */
+		j = 1 << (window - 1);
+		for (i = 1; i < j; i++) {
+			if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
+			    !BN_mod_mul_reciprocal(val[i], val[i - 1],
+			    aa, &recp, ctx))
+				goto err;
+		}
+	}
+
+	start = 1;		/* This is used to avoid multiplication etc
+				 * when there is only the value '1' in the
+				 * buffer. */
+	wvalue = 0;		/* The 'value' of the window */
+	wstart = bits - 1;	/* The top bit of the window */
+	wend = 0;		/* The bottom bit of the window */
+
+	if (!BN_one(r))
+		goto err;
+
+	for (;;) {
+		if (BN_is_bit_set(p, wstart) == 0) {
+			if (!start)
+				if (!BN_mod_mul_reciprocal(r, r,r, &recp, ctx))
+					goto err;
+			if (wstart == 0)
+				break;
+			wstart--;
+			continue;
+		}
+		/* We now have wstart on a 'set' bit, we now need to work out
+		 * how bit a window to do.  To do this we need to scan
+		 * forward until the last set bit before the end of the
+		 * window */
+		j = wstart;
+		wvalue = 1;
+		wend = 0;
+		for (i = 1; i < window; i++) {
+			if (wstart - i < 0)
+				break;
+			if (BN_is_bit_set(p, wstart - i)) {
+				wvalue <<= (i - wend);
+				wvalue |= 1;
+				wend = i;
+			}
+		}
+
+		/* wend is the size of the current window */
+		j = wend + 1;
+		/* add the 'bytes above' */
+		if (!start)
+			for (i = 0; i < j; i++) {
+				if (!BN_mod_mul_reciprocal(r, r,r, &recp, ctx))
+					goto err;
+			}
+
+		/* wvalue will be an odd number < 2^window */
+		if (!BN_mod_mul_reciprocal(r, r,val[wvalue >> 1], &recp, ctx))
+			goto err;
+
+		/* move the 'window' down further */
+		wstart -= wend + 1;
+		wvalue = 0;
+		start = 0;
+		if (wstart < 0)
+			break;
+	}
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	BN_RECP_CTX_free(&recp);
+	bn_check_top(r);
+	return (ret);
+}
+
+int
+BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
+    BN_CTX *ctx, BN_MONT_CTX *in_mont)
+{
+	int i, j, bits, ret = 0, wstart, wend, window, wvalue;
+	int start = 1;
+	BIGNUM *d, *r;
+	const BIGNUM *aa;
+	/* Table of variables obtained from 'ctx' */
+	BIGNUM *val[TABLE_SIZE];
+	BN_MONT_CTX *mont = NULL;
+
+	if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
+		return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
+	}
+
+	bn_check_top(a);
+	bn_check_top(p);
+	bn_check_top(m);
+
+	if (!BN_is_odd(m)) {
+		BNerr(BN_F_BN_MOD_EXP_MONT, BN_R_CALLED_WITH_EVEN_MODULUS);
+		return (0);
+	}
+	bits = BN_num_bits(p);
+	if (bits == 0) {
+		ret = BN_one(rr);
+		return ret;
+	}
+
+	BN_CTX_start(ctx);
+	if ((d = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((r = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((val[0] = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	/* If this is not done, things will break in the montgomery
+	 * part */
+
+	if (in_mont != NULL)
+		mont = in_mont;
+	else {
+		if ((mont = BN_MONT_CTX_new()) == NULL)
+			goto err;
+		if (!BN_MONT_CTX_set(mont, m, ctx))
+			goto err;
+	}
+
+	if (a->neg || BN_ucmp(a, m) >= 0) {
+		if (!BN_nnmod(val[0], a,m, ctx))
+			goto err;
+		aa = val[0];
+	} else
+		aa = a;
+	if (BN_is_zero(aa)) {
+		BN_zero(rr);
+		ret = 1;
+		goto err;
+	}
+	if (!BN_to_montgomery(val[0], aa, mont, ctx))
+		goto err; /* 1 */
+
+	window = BN_window_bits_for_exponent_size(bits);
+	if (window > 1) {
+		if (!BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx))
+			goto err; /* 2 */
+		j = 1 << (window - 1);
+		for (i = 1; i < j; i++) {
+			if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
+			    !BN_mod_mul_montgomery(val[i], val[i - 1],
+			    d, mont, ctx))
+				goto err;
+		}
+	}
+
+	start = 1;		/* This is used to avoid multiplication etc
+				 * when there is only the value '1' in the
+				 * buffer. */
+	wvalue = 0;		/* The 'value' of the window */
+	wstart = bits - 1;	/* The top bit of the window */
+	wend = 0;		/* The bottom bit of the window */
+
+	if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
+		goto err;
+	for (;;) {
+		if (BN_is_bit_set(p, wstart) == 0) {
+			if (!start) {
+				if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
+					goto err;
+			}
+			if (wstart == 0)
+				break;
+			wstart--;
+			continue;
+		}
+		/* We now have wstart on a 'set' bit, we now need to work out
+		 * how bit a window to do.  To do this we need to scan
+		 * forward until the last set bit before the end of the
+		 * window */
+		j = wstart;
+		wvalue = 1;
+		wend = 0;
+		for (i = 1; i < window; i++) {
+			if (wstart - i < 0)
+				break;
+			if (BN_is_bit_set(p, wstart - i)) {
+				wvalue <<= (i - wend);
+				wvalue |= 1;
+				wend = i;
+			}
+		}
+
+		/* wend is the size of the current window */
+		j = wend + 1;
+		/* add the 'bytes above' */
+		if (!start)
+			for (i = 0; i < j; i++) {
+				if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
+					goto err;
+			}
+
+		/* wvalue will be an odd number < 2^window */
+		if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx))
+			goto err;
+
+		/* move the 'window' down further */
+		wstart -= wend + 1;
+		wvalue = 0;
+		start = 0;
+		if (wstart < 0)
+			break;
+	}
+	if (!BN_from_montgomery(rr, r,mont, ctx))
+		goto err;
+	ret = 1;
+
+err:
+	if ((in_mont == NULL) && (mont != NULL))
+		BN_MONT_CTX_free(mont);
+	BN_CTX_end(ctx);
+	bn_check_top(rr);
+	return (ret);
+}
+
+
+/* BN_mod_exp_mont_consttime() stores the precomputed powers in a specific layout
+ * so that accessing any of these table values shows the same access pattern as far
+ * as cache lines are concerned.  The following functions are used to transfer a BIGNUM
+ * from/to that table. */
+
+static int
+MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top, unsigned char *buf,
+    int idx, int width)
+{
+	size_t i, j;
+
+	if (top > b->top)
+		top = b->top; /* this works because 'buf' is explicitly zeroed */
+	for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) {
+		buf[j] = ((unsigned char*)b->d)[i];
+	}
+
+	return 1;
+}
+
+static int
+MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, unsigned char *buf, int idx,
+    int width)
+{
+	size_t i, j;
+
+	if (bn_wexpand(b, top) == NULL)
+		return 0;
+
+	for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) {
+		((unsigned char*)b->d)[i] = buf[j];
+	}
+
+	b->top = top;
+	bn_correct_top(b);
+	return 1;
+}
+
+/* Given a pointer value, compute the next address that is a cache line multiple. */
+#define MOD_EXP_CTIME_ALIGN(x_) \
+	((unsigned char*)(x_) + (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - (((size_t)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK))))
+
+/* This variant of BN_mod_exp_mont() uses fixed windows and the special
+ * precomputation memory layout to limit data-dependency to a minimum
+ * to protect secret exponents (cf. the hyper-threading timing attacks
+ * pointed out by Colin Percival,
+ * http://www.daemonology.net/hyperthreading-considered-harmful/)
+ */
+int
+BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+{
+	int i, bits, ret = 0, window, wvalue;
+	int top;
+	BN_MONT_CTX *mont = NULL;
+	int numPowers;
+	unsigned char *powerbufFree = NULL;
+	int powerbufLen = 0;
+	unsigned char *powerbuf = NULL;
+	BIGNUM tmp, am;
+
+	bn_check_top(a);
+	bn_check_top(p);
+	bn_check_top(m);
+
+	top = m->top;
+
+	if (!(m->d[0] & 1)) {
+		BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME,
+		    BN_R_CALLED_WITH_EVEN_MODULUS);
+		return (0);
+	}
+	bits = BN_num_bits(p);
+	if (bits == 0) {
+		ret = BN_one(rr);
+		return ret;
+	}
+
+	BN_CTX_start(ctx);
+
+	/* Allocate a montgomery context if it was not supplied by the caller.
+	 * If this is not done, things will break in the montgomery part.
+ 	 */
+	if (in_mont != NULL)
+		mont = in_mont;
+	else {
+		if ((mont = BN_MONT_CTX_new()) == NULL)
+			goto err;
+		if (!BN_MONT_CTX_set(mont, m, ctx))
+			goto err;
+	}
+
+	/* Get the window size to use with size of p. */
+	window = BN_window_bits_for_ctime_exponent_size(bits);
+#if defined(OPENSSL_BN_ASM_MONT5)
+	if (window == 6 && bits <= 1024)
+		window = 5;	/* ~5% improvement of 2048-bit RSA sign */
+#endif
+
+	/* Allocate a buffer large enough to hold all of the pre-computed
+	 * powers of am, am itself and tmp.
+	 */
+	numPowers = 1 << window;
+	powerbufLen = sizeof(m->d[0]) * (top * numPowers +
+	    ((2*top) > numPowers ? (2*top) : numPowers));
+	if ((powerbufFree = malloc(powerbufLen +
+	    MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL)
+		goto err;
+
+	powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree);
+	memset(powerbuf, 0, powerbufLen);
+
+	/* lay down tmp and am right after powers table */
+	tmp.d = (BN_ULONG *)(powerbuf + sizeof(m->d[0]) * top * numPowers);
+	am.d = tmp.d + top;
+	tmp.top = am.top = 0;
+	tmp.dmax = am.dmax = top;
+	tmp.neg = am.neg = 0;
+	tmp.flags = am.flags = BN_FLG_STATIC_DATA;
+
+	/* prepare a^0 in Montgomery domain */
+#if 1
+	if (!BN_to_montgomery(&tmp, BN_value_one(), mont, ctx))
+		goto err;
+#else
+	tmp.d[0] = (0 - m - >d[0]) & BN_MASK2;	/* 2^(top*BN_BITS2) - m */
+	for (i = 1; i < top; i++)
+		tmp.d[i] = (~m->d[i]) & BN_MASK2;
+	tmp.top = top;
+#endif
+
+	/* prepare a^1 in Montgomery domain */
+	if (a->neg || BN_ucmp(a, m) >= 0) {
+		if (!BN_mod(&am, a,m, ctx))
+			goto err;
+		if (!BN_to_montgomery(&am, &am, mont, ctx))
+			goto err;
+	} else if (!BN_to_montgomery(&am, a,mont, ctx))
+		goto err;
+
+#if defined(OPENSSL_BN_ASM_MONT5)
+	/* This optimization uses ideas from http://eprint.iacr.org/2011/239,
+	 * specifically optimization of cache-timing attack countermeasures
+	 * and pre-computation optimization. */
+
+	/* Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as
+	 * 512-bit RSA is hardly relevant, we omit it to spare size... */
+	if (window == 5 && top > 1) {
+		void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap,
+		    const void *table, const BN_ULONG *np,
+		    const BN_ULONG *n0, int num, int power);
+		void bn_scatter5(const BN_ULONG *inp, size_t num,
+		    void *table, size_t power);
+		void bn_gather5(BN_ULONG *out, size_t num,
+		    void *table, size_t power);
+
+		BN_ULONG *np = mont->N.d, *n0 = mont->n0;
+
+		/* BN_to_montgomery can contaminate words above .top
+		 * [in BN_DEBUG[_DEBUG] build]... */
+		for (i = am.top; i < top; i++)
+			am.d[i] = 0;
+		for (i = tmp.top; i < top; i++)
+			tmp.d[i] = 0;
+
+		bn_scatter5(tmp.d, top, powerbuf, 0);
+		bn_scatter5(am.d, am.top, powerbuf, 1);
+		bn_mul_mont(tmp.d, am.d, am.d, np, n0, top);
+		bn_scatter5(tmp.d, top, powerbuf, 2);
+
+#if 0
+		for (i = 3; i < 32; i++) {
+			/* Calculate a^i = a^(i-1) * a */
+			bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np,
+			    n0, top, i - 1);
+			bn_scatter5(tmp.d, top, powerbuf, i);
+		}
+#else
+		/* same as above, but uses squaring for 1/2 of operations */
+		for (i = 4; i < 32; i*=2) {
+			bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+			bn_scatter5(tmp.d, top, powerbuf, i);
+		}
+		for (i = 3; i < 8; i += 2) {
+			int j;
+			bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np,
+			    n0, top, i - 1);
+			bn_scatter5(tmp.d, top, powerbuf, i);
+			for (j = 2 * i; j < 32; j *= 2) {
+				bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+				bn_scatter5(tmp.d, top, powerbuf, j);
+			}
+		}
+		for (; i < 16; i += 2) {
+			bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np,
+			    n0, top, i - 1);
+			bn_scatter5(tmp.d, top, powerbuf, i);
+			bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+			bn_scatter5(tmp.d, top, powerbuf, 2*i);
+		}
+		for (; i < 32; i += 2) {
+			bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np,
+			    n0, top, i - 1);
+			bn_scatter5(tmp.d, top, powerbuf, i);
+		}
+#endif
+		bits--;
+		for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--)
+			wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+		bn_gather5(tmp.d, top, powerbuf, wvalue);
+
+		/* Scan the exponent one window at a time starting from the most
+		 * significant bits.
+		 */
+		while (bits >= 0) {
+			for (wvalue = 0, i = 0; i < 5; i++, bits--)
+				wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+
+			bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+			bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+			bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+			bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+			bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+			bn_mul_mont_gather5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue);
+		}
+
+		tmp.top = top;
+		bn_correct_top(&tmp);
+	} else
+#endif
+	{
+		if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0,
+		    numPowers))
+			goto err;
+		if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am,  top, powerbuf, 1,
+		    numPowers))
+			goto err;
+
+		/* If the window size is greater than 1, then calculate
+		 * val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1)
+		 * (even powers could instead be computed as (a^(i/2))^2
+		 * to use the slight performance advantage of sqr over mul).
+		 */
+		if (window > 1) {
+			if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx))
+				goto err;
+			if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf,
+			    2, numPowers))
+				goto err;
+			for (i = 3; i < numPowers; i++) {
+				/* Calculate a^i = a^(i-1) * a */
+				if (!BN_mod_mul_montgomery(&tmp, &am, &tmp,
+				    mont, ctx))
+					goto err;
+				if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top,
+				    powerbuf, i, numPowers))
+					goto err;
+			}
+		}
+
+		bits--;
+		for (wvalue = 0, i = bits % window; i >= 0; i--, bits--)
+			wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+		if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp, top, powerbuf,
+		    wvalue, numPowers))
+			goto err;
+
+		/* Scan the exponent one window at a time starting from the most
+		 * significant bits.
+		 */
+		while (bits >= 0) {
+			wvalue = 0; /* The 'value' of the window */
+
+			/* Scan the window, squaring the result as we go */
+			for (i = 0; i < window; i++, bits--) {
+				if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp,
+				    mont, ctx))
+					goto err;
+				wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+			}
+
+			/* Fetch the appropriate pre-computed value from the pre-buf */
+			if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf,
+			    wvalue, numPowers))
+				goto err;
+
+			/* Multiply the result into the intermediate result */
+			if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx))
+				goto err;
+		}
+	}
+
+	/* Convert the final result from montgomery to standard format */
+	if (!BN_from_montgomery(rr, &tmp, mont, ctx))
+		goto err;
+	ret = 1;
+
+err:
+	if ((in_mont == NULL) && (mont != NULL))
+		BN_MONT_CTX_free(mont);
+	if (powerbuf != NULL) {
+		explicit_bzero(powerbuf, powerbufLen);
+		free(powerbufFree);
+	}
+	BN_CTX_end(ctx);
+	return (ret);
+}
+
+int
+BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, const BIGNUM *m,
+    BN_CTX *ctx, BN_MONT_CTX *in_mont)
+{
+	BN_MONT_CTX *mont = NULL;
+	int b, bits, ret = 0;
+	int r_is_one;
+	BN_ULONG w, next_w;
+	BIGNUM *d, *r, *t;
+	BIGNUM *swap_tmp;
+
+#define BN_MOD_MUL_WORD(r, w, m) \
+		(BN_mul_word(r, (w)) && \
+		(/* BN_ucmp(r, (m)) < 0 ? 1 :*/  \
+			(BN_mod(t, r, m, ctx) && (swap_tmp = r, r = t, t = swap_tmp, 1))))
+		/* BN_MOD_MUL_WORD is only used with 'w' large,
+		 * so the BN_ucmp test is probably more overhead
+		 * than always using BN_mod (which uses BN_copy if
+		 * a similar test returns true). */
+		/* We can use BN_mod and do not need BN_nnmod because our
+		 * accumulator is never negative (the result of BN_mod does
+		 * not depend on the sign of the modulus).
+		 */
+#define BN_TO_MONTGOMERY_WORD(r, w, mont) \
+		(BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx))
+
+	if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
+		/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
+		BNerr(BN_F_BN_MOD_EXP_MONT_WORD,
+		    ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return -1;
+	}
+
+	bn_check_top(p);
+	bn_check_top(m);
+
+	if (!BN_is_odd(m)) {
+		BNerr(BN_F_BN_MOD_EXP_MONT_WORD, BN_R_CALLED_WITH_EVEN_MODULUS);
+		return (0);
+	}
+	if (m->top == 1)
+		a %= m->d[0]; /* make sure that 'a' is reduced */
+
+	bits = BN_num_bits(p);
+	if (bits == 0) {
+		ret = BN_one(rr);
+		return ret;
+	}
+	if (a == 0) {
+		BN_zero(rr);
+		ret = 1;
+		return ret;
+	}
+
+	BN_CTX_start(ctx);
+	if ((d = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((r = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((t = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (in_mont != NULL)
+		mont = in_mont;
+	else {
+		if ((mont = BN_MONT_CTX_new()) == NULL)
+			goto err;
+		if (!BN_MONT_CTX_set(mont, m, ctx))
+			goto err;
+	}
+
+	r_is_one = 1; /* except for Montgomery factor */
+
+	/* bits-1 >= 0 */
+
+	/* The result is accumulated in the product r*w. */
+	w = a; /* bit 'bits-1' of 'p' is always set */
+	for (b = bits - 2; b >= 0; b--) {
+		/* First, square r*w. */
+		next_w = w * w;
+		if ((next_w / w) != w) /* overflow */
+		{
+			if (r_is_one) {
+				if (!BN_TO_MONTGOMERY_WORD(r, w, mont))
+					goto err;
+				r_is_one = 0;
+			} else {
+				if (!BN_MOD_MUL_WORD(r, w, m))
+					goto err;
+			}
+			next_w = 1;
+		}
+		w = next_w;
+		if (!r_is_one) {
+			if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
+				goto err;
+		}
+
+		/* Second, multiply r*w by 'a' if exponent bit is set. */
+		if (BN_is_bit_set(p, b)) {
+			next_w = w * a;
+			if ((next_w / a) != w) /* overflow */
+			{
+				if (r_is_one) {
+					if (!BN_TO_MONTGOMERY_WORD(r, w, mont))
+						goto err;
+					r_is_one = 0;
+				} else {
+					if (!BN_MOD_MUL_WORD(r, w, m))
+						goto err;
+				}
+				next_w = a;
+			}
+			w = next_w;
+		}
+	}
+
+	/* Finally, set r:=r*w. */
+	if (w != 1) {
+		if (r_is_one) {
+			if (!BN_TO_MONTGOMERY_WORD(r, w, mont))
+				goto err;
+			r_is_one = 0;
+		} else {
+			if (!BN_MOD_MUL_WORD(r, w, m))
+				goto err;
+		}
+	}
+
+	if (r_is_one) /* can happen only if a == 1*/
+	{
+		if (!BN_one(rr))
+			goto err;
+	} else {
+		if (!BN_from_montgomery(rr, r, mont, ctx))
+			goto err;
+	}
+	ret = 1;
+
+err:
+	if ((in_mont == NULL) && (mont != NULL))
+		BN_MONT_CTX_free(mont);
+	BN_CTX_end(ctx);
+	bn_check_top(rr);
+	return (ret);
+}
+
+
+/* The old fallback, simple version :-) */
+int
+BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
+    BN_CTX *ctx)
+{
+	int i, j,bits, ret = 0, wstart, wend, window, wvalue;
+	int start = 1;
+	BIGNUM *d;
+	/* Table of variables obtained from 'ctx' */
+	BIGNUM *val[TABLE_SIZE];
+
+	if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
+		/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
+		BNerr(BN_F_BN_MOD_EXP_SIMPLE,
+		    ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return -1;
+	}
+
+	bits = BN_num_bits(p);
+
+	if (bits == 0) {
+		ret = BN_one(r);
+		return ret;
+	}
+
+	BN_CTX_start(ctx);
+	if ((d = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((val[0] = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!BN_nnmod(val[0],a,m,ctx))
+		goto err;		/* 1 */
+	if (BN_is_zero(val[0])) {
+		BN_zero(r);
+		ret = 1;
+		goto err;
+	}
+
+	window = BN_window_bits_for_exponent_size(bits);
+	if (window > 1) {
+		if (!BN_mod_mul(d, val[0], val[0], m, ctx))
+			goto err;				/* 2 */
+		j = 1 << (window - 1);
+		for (i = 1; i < j; i++) {
+			if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
+			    !BN_mod_mul(val[i], val[i - 1], d,m, ctx))
+				goto err;
+		}
+	}
+
+	start = 1;		/* This is used to avoid multiplication etc
+				 * when there is only the value '1' in the
+				 * buffer. */
+	wvalue = 0;		/* The 'value' of the window */
+	wstart = bits - 1;	/* The top bit of the window */
+	wend = 0;		/* The bottom bit of the window */
+
+	if (!BN_one(r))
+		goto err;
+
+	for (;;) {
+		if (BN_is_bit_set(p, wstart) == 0) {
+			if (!start)
+				if (!BN_mod_mul(r, r, r, m, ctx))
+					goto err;
+			if (wstart == 0)
+				break;
+			wstart--;
+			continue;
+		}
+		/* We now have wstart on a 'set' bit, we now need to work out
+		 * how bit a window to do.  To do this we need to scan
+		 * forward until the last set bit before the end of the
+		 * window */
+		j = wstart;
+		wvalue = 1;
+		wend = 0;
+		for (i = 1; i < window; i++) {
+			if (wstart - i < 0)
+				break;
+			if (BN_is_bit_set(p, wstart - i)) {
+				wvalue <<= (i - wend);
+				wvalue |= 1;
+				wend = i;
+			}
+		}
+
+		/* wend is the size of the current window */
+		j = wend + 1;
+		/* add the 'bytes above' */
+		if (!start)
+			for (i = 0; i < j; i++) {
+				if (!BN_mod_mul(r, r, r, m, ctx))
+					goto err;
+			}
+
+		/* wvalue will be an odd number < 2^window */
+		if (!BN_mod_mul(r, r, val[wvalue >> 1], m, ctx))
+			goto err;
+
+		/* move the 'window' down further */
+		wstart -= wend + 1;
+		wvalue = 0;
+		start = 0;
+		if (wstart < 0)
+			break;
+	}
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	bn_check_top(r);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/bn/bn_exp2.c b/crypto/libressl/crypto/bn/bn_exp2.c
new file mode 100644
index 0000000000..883fe3c863
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_exp2.c
@@ -0,0 +1,308 @@
+/* $OpenBSD: bn_exp2.c,v 1.9 2014/07/11 08:44:47 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include "bn_lcl.h"
+
+#define TABLE_SIZE	32
+
+int
+BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
+    const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m, BN_CTX *ctx,
+    BN_MONT_CTX *in_mont)
+{
+	int i, j, bits, b, bits1, bits2, ret = 0, wpos1, wpos2, window1, window2, wvalue1, wvalue2;
+	int r_is_one = 1;
+	BIGNUM *d, *r;
+	const BIGNUM *a_mod_m;
+	/* Tables of variables obtained from 'ctx' */
+	BIGNUM *val1[TABLE_SIZE], *val2[TABLE_SIZE];
+	BN_MONT_CTX *mont = NULL;
+
+	bn_check_top(a1);
+	bn_check_top(p1);
+	bn_check_top(a2);
+	bn_check_top(p2);
+	bn_check_top(m);
+
+	if (!(m->d[0] & 1)) {
+		BNerr(BN_F_BN_MOD_EXP2_MONT, BN_R_CALLED_WITH_EVEN_MODULUS);
+		return (0);
+	}
+	bits1 = BN_num_bits(p1);
+	bits2 = BN_num_bits(p2);
+	if ((bits1 == 0) && (bits2 == 0)) {
+		ret = BN_one(rr);
+		return ret;
+	}
+
+	bits = (bits1 > bits2) ? bits1 : bits2;
+
+	BN_CTX_start(ctx);
+	if ((d = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((r = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((val1[0] = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((val2[0] = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (in_mont != NULL)
+		mont = in_mont;
+	else {
+		if ((mont = BN_MONT_CTX_new()) == NULL)
+			goto err;
+		if (!BN_MONT_CTX_set(mont, m, ctx))
+			goto err;
+	}
+
+	window1 = BN_window_bits_for_exponent_size(bits1);
+	window2 = BN_window_bits_for_exponent_size(bits2);
+
+	/*
+	 * Build table for a1:   val1[i] := a1^(2*i + 1) mod m  for i = 0 .. 2^(window1-1)
+	 */
+	if (a1->neg || BN_ucmp(a1, m) >= 0) {
+		if (!BN_mod(val1[0], a1, m, ctx))
+			goto err;
+		a_mod_m = val1[0];
+	} else
+		a_mod_m = a1;
+	if (BN_is_zero(a_mod_m)) {
+		BN_zero(rr);
+		ret = 1;
+		goto err;
+	}
+
+	if (!BN_to_montgomery(val1[0], a_mod_m, mont, ctx))
+		goto err;
+	if (window1 > 1) {
+		if (!BN_mod_mul_montgomery(d, val1[0], val1[0], mont, ctx))
+			goto err;
+
+		j = 1 << (window1 - 1);
+		for (i = 1; i < j; i++) {
+			if (((val1[i] = BN_CTX_get(ctx)) == NULL) ||
+			    !BN_mod_mul_montgomery(val1[i], val1[i - 1],
+			    d, mont, ctx))
+				goto err;
+		}
+	}
+
+
+	/*
+	 * Build table for a2:   val2[i] := a2^(2*i + 1) mod m  for i = 0 .. 2^(window2-1)
+	 */
+	if (a2->neg || BN_ucmp(a2, m) >= 0) {
+		if (!BN_mod(val2[0], a2, m, ctx))
+			goto err;
+		a_mod_m = val2[0];
+	} else
+		a_mod_m = a2;
+	if (BN_is_zero(a_mod_m)) {
+		BN_zero(rr);
+		ret = 1;
+		goto err;
+	}
+	if (!BN_to_montgomery(val2[0], a_mod_m, mont, ctx))
+		goto err;
+	if (window2 > 1) {
+		if (!BN_mod_mul_montgomery(d, val2[0], val2[0], mont, ctx))
+			goto err;
+
+		j = 1 << (window2 - 1);
+		for (i = 1; i < j; i++) {
+			if (((val2[i] = BN_CTX_get(ctx)) == NULL) ||
+			    !BN_mod_mul_montgomery(val2[i], val2[i - 1],
+			    d, mont, ctx))
+				goto err;
+		}
+	}
+
+
+	/* Now compute the power product, using independent windows. */
+	r_is_one = 1;
+	wvalue1 = 0;  /* The 'value' of the first window */
+	wvalue2 = 0;  /* The 'value' of the second window */
+	wpos1 = 0;    /* If wvalue1 > 0, the bottom bit of the first window */
+	wpos2 = 0;    /* If wvalue2 > 0, the bottom bit of the second window */
+
+	if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
+		goto err;
+	for (b = bits - 1; b >= 0; b--) {
+		if (!r_is_one) {
+			if (!BN_mod_mul_montgomery(r, r,r, mont, ctx))
+				goto err;
+		}
+
+		if (!wvalue1)
+			if (BN_is_bit_set(p1, b)) {
+			/* consider bits b-window1+1 .. b for this window */
+			i = b - window1 + 1;
+			while (!BN_is_bit_set(p1, i)) /* works for i<0 */
+				i++;
+			wpos1 = i;
+			wvalue1 = 1;
+			for (i = b - 1; i >= wpos1; i--) {
+				wvalue1 <<= 1;
+				if (BN_is_bit_set(p1, i))
+					wvalue1++;
+			}
+		}
+
+		if (!wvalue2)
+			if (BN_is_bit_set(p2, b)) {
+			/* consider bits b-window2+1 .. b for this window */
+			i = b - window2 + 1;
+			while (!BN_is_bit_set(p2, i))
+				i++;
+			wpos2 = i;
+			wvalue2 = 1;
+			for (i = b - 1; i >= wpos2; i--) {
+				wvalue2 <<= 1;
+				if (BN_is_bit_set(p2, i))
+					wvalue2++;
+			}
+		}
+
+		if (wvalue1 && b == wpos1) {
+			/* wvalue1 is odd and < 2^window1 */
+			if (!BN_mod_mul_montgomery(r, r, val1[wvalue1 >> 1],
+			    mont, ctx))
+				goto err;
+			wvalue1 = 0;
+			r_is_one = 0;
+		}
+
+		if (wvalue2 && b == wpos2) {
+			/* wvalue2 is odd and < 2^window2 */
+			if (!BN_mod_mul_montgomery(r, r, val2[wvalue2 >> 1],
+			    mont, ctx))
+				goto err;
+			wvalue2 = 0;
+			r_is_one = 0;
+		}
+	}
+	if (!BN_from_montgomery(rr, r,mont, ctx))
+		goto err;
+	ret = 1;
+
+err:
+	if ((in_mont == NULL) && (mont != NULL))
+		BN_MONT_CTX_free(mont);
+	BN_CTX_end(ctx);
+	bn_check_top(rr);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/bn/bn_gcd.c b/crypto/libressl/crypto/bn/bn_gcd.c
new file mode 100644
index 0000000000..0c21472c29
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_gcd.c
@@ -0,0 +1,688 @@
+/* $OpenBSD: bn_gcd.c,v 1.9 2014/07/11 08:44:47 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include "bn_lcl.h"
+
+static BIGNUM *euclid(BIGNUM *a, BIGNUM *b);
+
+int
+BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
+{
+	BIGNUM *a, *b, *t;
+	int ret = 0;
+
+	bn_check_top(in_a);
+	bn_check_top(in_b);
+
+	BN_CTX_start(ctx);
+	if ((a = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((b = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (BN_copy(a, in_a) == NULL)
+		goto err;
+	if (BN_copy(b, in_b) == NULL)
+		goto err;
+	a->neg = 0;
+	b->neg = 0;
+
+	if (BN_cmp(a, b) < 0) {
+		t = a;
+		a = b;
+		b = t;
+	}
+	t = euclid(a, b);
+	if (t == NULL)
+		goto err;
+
+	if (BN_copy(r, t) == NULL)
+		goto err;
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	bn_check_top(r);
+	return (ret);
+}
+
+static BIGNUM *
+euclid(BIGNUM *a, BIGNUM *b)
+{
+	BIGNUM *t;
+	int shifts = 0;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	/* 0 <= b <= a */
+	while (!BN_is_zero(b)) {
+		/* 0 < b <= a */
+
+		if (BN_is_odd(a)) {
+			if (BN_is_odd(b)) {
+				if (!BN_sub(a, a, b))
+					goto err;
+				if (!BN_rshift1(a, a))
+					goto err;
+				if (BN_cmp(a, b) < 0) {
+					t = a;
+					a = b;
+					b = t;
+				}
+			}
+			else		/* a odd - b even */
+			{
+				if (!BN_rshift1(b, b))
+					goto err;
+				if (BN_cmp(a, b) < 0) {
+					t = a;
+					a = b;
+					b = t;
+				}
+			}
+		}
+		else			/* a is even */
+		{
+			if (BN_is_odd(b)) {
+				if (!BN_rshift1(a, a))
+					goto err;
+				if (BN_cmp(a, b) < 0) {
+					t = a;
+					a = b;
+					b = t;
+				}
+			}
+			else		/* a even - b even */
+			{
+				if (!BN_rshift1(a, a))
+					goto err;
+				if (!BN_rshift1(b, b))
+					goto err;
+				shifts++;
+			}
+		}
+		/* 0 <= b <= a */
+	}
+
+	if (shifts) {
+		if (!BN_lshift(a, a, shifts))
+			goto err;
+	}
+	bn_check_top(a);
+	return (a);
+
+err:
+	return (NULL);
+}
+
+
+/* solves ax == 1 (mod n) */
+static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, const BIGNUM *a,
+    const BIGNUM *n, BN_CTX *ctx);
+
+BIGNUM *
+BN_mod_inverse(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
+{
+	BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
+	BIGNUM *ret = NULL;
+	int sign;
+
+	if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) ||
+	    (BN_get_flags(n, BN_FLG_CONSTTIME) != 0)) {
+		return BN_mod_inverse_no_branch(in, a, n, ctx);
+	}
+
+	bn_check_top(a);
+	bn_check_top(n);
+
+	BN_CTX_start(ctx);
+	if ((A = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((B = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((X = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((D = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((M = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((Y = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((T = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (in == NULL)
+		R = BN_new();
+	else
+		R = in;
+	if (R == NULL)
+		goto err;
+
+	BN_one(X);
+	BN_zero(Y);
+	if (BN_copy(B, a) == NULL)
+		goto err;
+	if (BN_copy(A, n) == NULL)
+		goto err;
+	A->neg = 0;
+	if (B->neg || (BN_ucmp(B, A) >= 0)) {
+		if (!BN_nnmod(B, B, A, ctx))
+			goto err;
+	}
+	sign = -1;
+	/* From  B = a mod |n|,  A = |n|  it follows that
+	 *
+	 *      0 <= B < A,
+	 *     -sign*X*a  ==  B   (mod |n|),
+	 *      sign*Y*a  ==  A   (mod |n|).
+	 */
+
+	if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) {
+		/* Binary inversion algorithm; requires odd modulus.
+		 * This is faster than the general algorithm if the modulus
+		 * is sufficiently small (about 400 .. 500 bits on 32-bit
+		 * sytems, but much more on 64-bit systems) */
+		int shift;
+
+		while (!BN_is_zero(B)) {
+			/*
+			 *      0 < B < |n|,
+			 *      0 < A <= |n|,
+			 * (1) -sign*X*a  ==  B   (mod |n|),
+			 * (2)  sign*Y*a  ==  A   (mod |n|)
+			 */
+
+			/* Now divide  B  by the maximum possible power of two in the integers,
+			 * and divide  X  by the same value mod |n|.
+			 * When we're done, (1) still holds. */
+			shift = 0;
+			while (!BN_is_bit_set(B, shift)) /* note that 0 < B */
+			{
+				shift++;
+
+				if (BN_is_odd(X)) {
+					if (!BN_uadd(X, X, n))
+						goto err;
+				}
+				/* now X is even, so we can easily divide it by two */
+				if (!BN_rshift1(X, X))
+					goto err;
+			}
+			if (shift > 0) {
+				if (!BN_rshift(B, B, shift))
+					goto err;
+			}
+
+
+			/* Same for  A  and  Y.  Afterwards, (2) still holds. */
+			shift = 0;
+			while (!BN_is_bit_set(A, shift)) /* note that 0 < A */
+			{
+				shift++;
+
+				if (BN_is_odd(Y)) {
+					if (!BN_uadd(Y, Y, n))
+						goto err;
+				}
+				/* now Y is even */
+				if (!BN_rshift1(Y, Y))
+					goto err;
+			}
+			if (shift > 0) {
+				if (!BN_rshift(A, A, shift))
+					goto err;
+			}
+
+
+			/* We still have (1) and (2).
+			 * Both  A  and  B  are odd.
+			 * The following computations ensure that
+			 *
+			 *     0 <= B < |n|,
+			 *      0 < A < |n|,
+			 * (1) -sign*X*a  ==  B   (mod |n|),
+			 * (2)  sign*Y*a  ==  A   (mod |n|),
+			 *
+			 * and that either  A  or  B  is even in the next iteration.
+			 */
+			if (BN_ucmp(B, A) >= 0) {
+				/* -sign*(X + Y)*a == B - A  (mod |n|) */
+				if (!BN_uadd(X, X, Y))
+					goto err;
+				/* NB: we could use BN_mod_add_quick(X, X, Y, n), but that
+				 * actually makes the algorithm slower */
+				if (!BN_usub(B, B, A))
+					goto err;
+			} else {
+				/*  sign*(X + Y)*a == A - B  (mod |n|) */
+				if (!BN_uadd(Y, Y, X))
+					goto err;
+				/* as above, BN_mod_add_quick(Y, Y, X, n) would slow things down */
+				if (!BN_usub(A, A, B))
+					goto err;
+			}
+		}
+	} else {
+		/* general inversion algorithm */
+
+		while (!BN_is_zero(B)) {
+			BIGNUM *tmp;
+
+			/*
+			 *      0 < B < A,
+			 * (*) -sign*X*a  ==  B   (mod |n|),
+			 *      sign*Y*a  ==  A   (mod |n|)
+			 */
+
+			/* (D, M) := (A/B, A%B) ... */
+			if (BN_num_bits(A) == BN_num_bits(B)) {
+				if (!BN_one(D))
+					goto err;
+				if (!BN_sub(M, A, B))
+					goto err;
+			} else if (BN_num_bits(A) == BN_num_bits(B) + 1) {
+				/* A/B is 1, 2, or 3 */
+				if (!BN_lshift1(T, B))
+					goto err;
+				if (BN_ucmp(A, T) < 0) {
+					/* A < 2*B, so D=1 */
+					if (!BN_one(D))
+						goto err;
+					if (!BN_sub(M, A, B))
+						goto err;
+				} else {
+					/* A >= 2*B, so D=2 or D=3 */
+					if (!BN_sub(M, A, T))
+						goto err;
+					if (!BN_add(D,T,B)) goto err; /* use D (:= 3*B) as temp */
+						if (BN_ucmp(A, D) < 0) {
+						/* A < 3*B, so D=2 */
+						if (!BN_set_word(D, 2))
+							goto err;
+						/* M (= A - 2*B) already has the correct value */
+					} else {
+						/* only D=3 remains */
+						if (!BN_set_word(D, 3))
+							goto err;
+						/* currently  M = A - 2*B,  but we need  M = A - 3*B */
+						if (!BN_sub(M, M, B))
+							goto err;
+					}
+				}
+			} else {
+				if (!BN_div(D, M, A, B, ctx))
+					goto err;
+			}
+
+			/* Now
+			 *      A = D*B + M;
+			 * thus we have
+			 * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
+			 */
+			tmp = A; /* keep the BIGNUM object, the value does not matter */
+
+			/* (A, B) := (B, A mod B) ... */
+			A = B;
+			B = M;
+			/* ... so we have  0 <= B < A  again */
+
+			/* Since the former  M  is now  B  and the former  B  is now  A,
+			 * (**) translates into
+			 *       sign*Y*a  ==  D*A + B    (mod |n|),
+			 * i.e.
+			 *       sign*Y*a - D*A  ==  B    (mod |n|).
+			 * Similarly, (*) translates into
+			 *      -sign*X*a  ==  A          (mod |n|).
+			 *
+			 * Thus,
+			 *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
+			 * i.e.
+			 *        sign*(Y + D*X)*a  ==  B  (mod |n|).
+			 *
+			 * So if we set  (X, Y, sign) := (Y + D*X, X, -sign),  we arrive back at
+			 *      -sign*X*a  ==  B   (mod |n|),
+			 *       sign*Y*a  ==  A   (mod |n|).
+			 * Note that  X  and  Y  stay non-negative all the time.
+			 */
+
+			/* most of the time D is very small, so we can optimize tmp := D*X+Y */
+			if (BN_is_one(D)) {
+				if (!BN_add(tmp, X, Y))
+					goto err;
+			} else {
+				if (BN_is_word(D, 2)) {
+					if (!BN_lshift1(tmp, X))
+						goto err;
+				} else if (BN_is_word(D, 4)) {
+					if (!BN_lshift(tmp, X, 2))
+						goto err;
+				} else if (D->top == 1) {
+					if (!BN_copy(tmp, X))
+						goto err;
+					if (!BN_mul_word(tmp, D->d[0]))
+						goto err;
+				} else {
+					if (!BN_mul(tmp, D,X, ctx))
+						goto err;
+				}
+				if (!BN_add(tmp, tmp, Y))
+					goto err;
+			}
+
+			M = Y; /* keep the BIGNUM object, the value does not matter */
+			Y = X;
+			X = tmp;
+			sign = -sign;
+		}
+	}
+
+	/*
+	 * The while loop (Euclid's algorithm) ends when
+	 *      A == gcd(a,n);
+	 * we have
+	 *       sign*Y*a  ==  A  (mod |n|),
+	 * where  Y  is non-negative.
+	 */
+
+	if (sign < 0) {
+		if (!BN_sub(Y, n, Y))
+			goto err;
+	}
+	/* Now  Y*a  ==  A  (mod |n|).  */
+
+	if (BN_is_one(A)) {
+		/* Y*a == 1  (mod |n|) */
+		if (!Y->neg && BN_ucmp(Y, n) < 0) {
+			if (!BN_copy(R, Y))
+				goto err;
+		} else {
+			if (!BN_nnmod(R, Y,n, ctx))
+				goto err;
+		}
+	} else {
+		BNerr(BN_F_BN_MOD_INVERSE, BN_R_NO_INVERSE);
+		goto err;
+	}
+	ret = R;
+
+err:
+	if ((ret == NULL) && (in == NULL))
+		BN_free(R);
+	BN_CTX_end(ctx);
+	bn_check_top(ret);
+	return (ret);
+}
+
+
+/* BN_mod_inverse_no_branch is a special version of BN_mod_inverse.
+ * It does not contain branches that may leak sensitive information.
+ */
+static BIGNUM *
+BN_mod_inverse_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n,
+    BN_CTX *ctx)
+{
+	BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
+	BIGNUM local_A, local_B;
+	BIGNUM *pA, *pB;
+	BIGNUM *ret = NULL;
+	int sign;
+
+	bn_check_top(a);
+	bn_check_top(n);
+
+	BN_CTX_start(ctx);
+	if ((A = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((B = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((X = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((D = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((M = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((Y = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((T = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (in == NULL)
+		R = BN_new();
+	else
+		R = in;
+	if (R == NULL)
+		goto err;
+
+	BN_one(X);
+	BN_zero(Y);
+	if (BN_copy(B, a) == NULL)
+		goto err;
+	if (BN_copy(A, n) == NULL)
+		goto err;
+	A->neg = 0;
+
+	if (B->neg || (BN_ucmp(B, A) >= 0)) {
+		/* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
+	 	 * BN_div_no_branch will be called eventually.
+	 	 */
+		pB = &local_B;
+		BN_with_flags(pB, B, BN_FLG_CONSTTIME);
+		if (!BN_nnmod(B, pB, A, ctx))
+			goto err;
+	}
+	sign = -1;
+	/* From  B = a mod |n|,  A = |n|  it follows that
+	 *
+	 *      0 <= B < A,
+	 *     -sign*X*a  ==  B   (mod |n|),
+	 *      sign*Y*a  ==  A   (mod |n|).
+	 */
+
+	while (!BN_is_zero(B)) {
+		BIGNUM *tmp;
+
+		/*
+		 *      0 < B < A,
+		 * (*) -sign*X*a  ==  B   (mod |n|),
+		 *      sign*Y*a  ==  A   (mod |n|)
+		 */
+
+		/* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
+	 	 * BN_div_no_branch will be called eventually.
+	 	 */
+		pA = &local_A;
+		BN_with_flags(pA, A, BN_FLG_CONSTTIME);
+
+		/* (D, M) := (A/B, A%B) ... */
+		if (!BN_div(D, M, pA, B, ctx))
+			goto err;
+
+		/* Now
+		 *      A = D*B + M;
+		 * thus we have
+		 * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
+		 */
+		tmp = A; /* keep the BIGNUM object, the value does not matter */
+
+		/* (A, B) := (B, A mod B) ... */
+		A = B;
+		B = M;
+		/* ... so we have  0 <= B < A  again */
+
+		/* Since the former  M  is now  B  and the former  B  is now  A,
+		 * (**) translates into
+		 *       sign*Y*a  ==  D*A + B    (mod |n|),
+		 * i.e.
+		 *       sign*Y*a - D*A  ==  B    (mod |n|).
+		 * Similarly, (*) translates into
+		 *      -sign*X*a  ==  A          (mod |n|).
+		 *
+		 * Thus,
+		 *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
+		 * i.e.
+		 *        sign*(Y + D*X)*a  ==  B  (mod |n|).
+		 *
+		 * So if we set  (X, Y, sign) := (Y + D*X, X, -sign),  we arrive back at
+		 *      -sign*X*a  ==  B   (mod |n|),
+		 *       sign*Y*a  ==  A   (mod |n|).
+		 * Note that  X  and  Y  stay non-negative all the time.
+		 */
+
+		if (!BN_mul(tmp, D, X, ctx))
+			goto err;
+		if (!BN_add(tmp, tmp, Y))
+			goto err;
+
+		M = Y; /* keep the BIGNUM object, the value does not matter */
+		Y = X;
+		X = tmp;
+		sign = -sign;
+	}
+
+	/*
+	 * The while loop (Euclid's algorithm) ends when
+	 *      A == gcd(a,n);
+	 * we have
+	 *       sign*Y*a  ==  A  (mod |n|),
+	 * where  Y  is non-negative.
+	 */
+
+	if (sign < 0) {
+		if (!BN_sub(Y, n, Y))
+			goto err;
+	}
+	/* Now  Y*a  ==  A  (mod |n|).  */
+
+	if (BN_is_one(A)) {
+		/* Y*a == 1  (mod |n|) */
+		if (!Y->neg && BN_ucmp(Y, n) < 0) {
+			if (!BN_copy(R, Y))
+				goto err;
+		} else {
+			if (!BN_nnmod(R, Y, n, ctx))
+				goto err;
+		}
+	} else {
+		BNerr(BN_F_BN_MOD_INVERSE_NO_BRANCH, BN_R_NO_INVERSE);
+		goto err;
+	}
+	ret = R;
+
+err:
+	if ((ret == NULL) && (in == NULL))
+		BN_free(R);
+	BN_CTX_end(ctx);
+	bn_check_top(ret);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/bn/bn_gf2m.c b/crypto/libressl/crypto/bn/bn_gf2m.c
new file mode 100644
index 0000000000..714e303370
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_gf2m.c
@@ -0,0 +1,1323 @@
+/* $OpenBSD: bn_gf2m.c,v 1.20 2015/06/11 15:55:28 jsing Exp $ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * In addition, Sun covenants to all licensees who provide a reciprocal
+ * covenant with respect to their own patents if any, not to sue under
+ * current and future patent claims necessarily infringed by the making,
+ * using, practicing, selling, offering for sale and/or otherwise
+ * disposing of the ECC Code as delivered hereunder (or portions thereof),
+ * provided that such covenant shall not apply:
+ *  1) for code that a licensee deletes from the ECC Code;
+ *  2) separates from the ECC Code; or
+ *  3) for infringements caused by:
+ *       i) the modification of the ECC Code or
+ *      ii) the combination of the ECC Code with other software or
+ *          devices where such combination causes the infringement.
+ *
+ * The software is originally written by Sheueling Chang Shantz and
+ * Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+/* NOTE: This file is licensed pursuant to the OpenSSL license below
+ * and may be modified; but after modifications, the above covenant
+ * may no longer apply!  In such cases, the corresponding paragraph
+ * ["In addition, Sun covenants ... causes the infringement."] and
+ * this note can be edited out; but please keep the Sun copyright
+ * notice and attribution. */
+
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+
+#include 
+
+#include "bn_lcl.h"
+
+#ifndef OPENSSL_NO_EC2M
+
+/* Maximum number of iterations before BN_GF2m_mod_solve_quad_arr should fail. */
+#define MAX_ITERATIONS 50
+
+static const BN_ULONG SQR_tb[16] =
+	{     0,     1,     4,     5,    16,    17,    20,    21,
+64,    65,    68,    69,    80,    81,    84,    85 };
+/* Platform-specific macros to accelerate squaring. */
+#ifdef _LP64
+#define SQR1(w) \
+    SQR_tb[(w) >> 60 & 0xF] << 56 | SQR_tb[(w) >> 56 & 0xF] << 48 | \
+    SQR_tb[(w) >> 52 & 0xF] << 40 | SQR_tb[(w) >> 48 & 0xF] << 32 | \
+    SQR_tb[(w) >> 44 & 0xF] << 24 | SQR_tb[(w) >> 40 & 0xF] << 16 | \
+    SQR_tb[(w) >> 36 & 0xF] <<  8 | SQR_tb[(w) >> 32 & 0xF]
+#define SQR0(w) \
+    SQR_tb[(w) >> 28 & 0xF] << 56 | SQR_tb[(w) >> 24 & 0xF] << 48 | \
+    SQR_tb[(w) >> 20 & 0xF] << 40 | SQR_tb[(w) >> 16 & 0xF] << 32 | \
+    SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >>  8 & 0xF] << 16 | \
+    SQR_tb[(w) >>  4 & 0xF] <<  8 | SQR_tb[(w)       & 0xF]
+#else
+#define SQR1(w) \
+    SQR_tb[(w) >> 28 & 0xF] << 24 | SQR_tb[(w) >> 24 & 0xF] << 16 | \
+    SQR_tb[(w) >> 20 & 0xF] <<  8 | SQR_tb[(w) >> 16 & 0xF]
+#define SQR0(w) \
+    SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >>  8 & 0xF] << 16 | \
+    SQR_tb[(w) >>  4 & 0xF] <<  8 | SQR_tb[(w)       & 0xF]
+#endif
+
+#if !defined(OPENSSL_BN_ASM_GF2m)
+/* Product of two polynomials a, b each with degree < BN_BITS2 - 1,
+ * result is a polynomial r with degree < 2 * BN_BITS - 1
+ * The caller MUST ensure that the variables have the right amount
+ * of space allocated.
+ */
+static void
+bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b)
+{
+#ifndef _LP64
+	BN_ULONG h, l, s;
+	BN_ULONG tab[8], top2b = a >> 30;
+	BN_ULONG a1, a2, a4;
+
+	a1 = a & (0x3FFFFFFF);
+	a2 = a1 << 1;
+	a4 = a2 << 1;
+
+	tab[0] = 0;
+	tab[1] = a1;
+	tab[2] = a2;
+	tab[3] = a1 ^ a2;
+	tab[4] = a4;
+	tab[5] = a1 ^ a4;
+	tab[6] = a2 ^ a4;
+	tab[7] = a1 ^ a2 ^ a4;
+
+	s = tab[b & 0x7];
+	l = s;
+	s = tab[b >> 3 & 0x7];
+	l ^= s << 3;
+	h = s >> 29;
+	s = tab[b >> 6 & 0x7];
+	l ^= s <<  6;
+	h ^= s >> 26;
+	s = tab[b >> 9 & 0x7];
+	l ^= s <<  9;
+	h ^= s >> 23;
+	s = tab[b >> 12 & 0x7];
+	l ^= s << 12;
+	h ^= s >> 20;
+	s = tab[b >> 15 & 0x7];
+	l ^= s << 15;
+	h ^= s >> 17;
+	s = tab[b >> 18 & 0x7];
+	l ^= s << 18;
+	h ^= s >> 14;
+	s = tab[b >> 21 & 0x7];
+	l ^= s << 21;
+	h ^= s >> 11;
+	s = tab[b >> 24 & 0x7];
+	l ^= s << 24;
+	h ^= s >>  8;
+	s = tab[b >> 27 & 0x7];
+	l ^= s << 27;
+	h ^= s >>  5;
+	s = tab[b >> 30];
+	l ^= s << 30;
+	h ^= s >> 2;
+
+	/* compensate for the top two bits of a */
+	if (top2b & 01) {
+		l ^= b << 30;
+		h ^= b >> 2;
+	}
+	if (top2b & 02) {
+		l ^= b << 31;
+		h ^= b >> 1;
+	}
+
+	*r1 = h;
+	*r0 = l;
+#else
+	BN_ULONG h, l, s;
+	BN_ULONG tab[16], top3b = a >> 61;
+	BN_ULONG a1, a2, a4, a8;
+
+	a1 = a & (0x1FFFFFFFFFFFFFFFULL);
+	a2 = a1 << 1;
+	a4 = a2 << 1;
+	a8 = a4 << 1;
+
+	tab[0] = 0;
+	tab[1] = a1;
+	tab[2] = a2;
+	tab[3] = a1 ^ a2;
+	tab[4] = a4;
+	tab[5] = a1 ^ a4;
+	tab[6] = a2 ^ a4;
+	tab[7] = a1 ^ a2 ^ a4;
+	tab[8] = a8;
+	tab[9] = a1 ^ a8;
+	tab[10] = a2 ^ a8;
+	tab[11] = a1 ^ a2 ^ a8;
+	tab[12] = a4 ^ a8;
+	tab[13] = a1 ^ a4 ^ a8;
+	tab[14] = a2 ^ a4 ^ a8;
+	tab[15] = a1 ^ a2 ^ a4 ^ a8;
+
+	s = tab[b & 0xF];
+	l = s;
+	s = tab[b >> 4 & 0xF];
+	l ^= s << 4;
+	h = s >> 60;
+	s = tab[b >> 8 & 0xF];
+	l ^= s << 8;
+	h ^= s >> 56;
+	s = tab[b >> 12 & 0xF];
+	l ^= s << 12;
+	h ^= s >> 52;
+	s = tab[b >> 16 & 0xF];
+	l ^= s << 16;
+	h ^= s >> 48;
+	s = tab[b >> 20 & 0xF];
+	l ^= s << 20;
+	h ^= s >> 44;
+	s = tab[b >> 24 & 0xF];
+	l ^= s << 24;
+	h ^= s >> 40;
+	s = tab[b >> 28 & 0xF];
+	l ^= s << 28;
+	h ^= s >> 36;
+	s = tab[b >> 32 & 0xF];
+	l ^= s << 32;
+	h ^= s >> 32;
+	s = tab[b >> 36 & 0xF];
+	l ^= s << 36;
+	h ^= s >> 28;
+	s = tab[b >> 40 & 0xF];
+	l ^= s << 40;
+	h ^= s >> 24;
+	s = tab[b >> 44 & 0xF];
+	l ^= s << 44;
+	h ^= s >> 20;
+	s = tab[b >> 48 & 0xF];
+	l ^= s << 48;
+	h ^= s >> 16;
+	s = tab[b >> 52 & 0xF];
+	l ^= s << 52;
+	h ^= s >> 12;
+	s = tab[b >> 56 & 0xF];
+	l ^= s << 56;
+	h ^= s >>  8;
+	s = tab[b >> 60];
+	l ^= s << 60;
+	h ^= s >>  4;
+
+	/* compensate for the top three bits of a */
+	if (top3b & 01) {
+		l ^= b << 61;
+		h ^= b >> 3;
+	}
+	if (top3b & 02) {
+		l ^= b << 62;
+		h ^= b >> 2;
+	}
+	if (top3b & 04) {
+		l ^= b << 63;
+		h ^= b >> 1;
+	}
+
+	*r1 = h;
+	*r0 = l;
+#endif
+}
+
+/* Product of two polynomials a, b each with degree < 2 * BN_BITS2 - 1,
+ * result is a polynomial r with degree < 4 * BN_BITS2 - 1
+ * The caller MUST ensure that the variables have the right amount
+ * of space allocated.
+ */
+static void
+bn_GF2m_mul_2x2(BN_ULONG *r, const BN_ULONG a1, const BN_ULONG a0,
+    const BN_ULONG b1, const BN_ULONG b0)
+{
+	BN_ULONG m1, m0;
+
+	/* r[3] = h1, r[2] = h0; r[1] = l1; r[0] = l0 */
+	bn_GF2m_mul_1x1(r + 3, r + 2, a1, b1);
+	bn_GF2m_mul_1x1(r + 1, r, a0, b0);
+	bn_GF2m_mul_1x1(&m1, &m0, a0 ^ a1, b0 ^ b1);
+	/* Correction on m1 ^= l1 ^ h1; m0 ^= l0 ^ h0; */
+	r[2] ^= m1 ^ r[1] ^ r[3];  /* h0 ^= m1 ^ l1 ^ h1; */
+	r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0;  /* l1 ^= l0 ^ h0 ^ m0; */
+}
+#else
+void bn_GF2m_mul_2x2(BN_ULONG *r, BN_ULONG a1, BN_ULONG a0, BN_ULONG b1,
+    BN_ULONG b0);
+#endif
+
+/* Add polynomials a and b and store result in r; r could be a or b, a and b
+ * could be equal; r is the bitwise XOR of a and b.
+ */
+int
+BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+{
+	int i;
+	const BIGNUM *at, *bt;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	if (a->top < b->top) {
+		at = b;
+		bt = a;
+	} else {
+		at = a;
+		bt = b;
+	}
+
+	if (bn_wexpand(r, at->top) == NULL)
+		return 0;
+
+	for (i = 0; i < bt->top; i++) {
+		r->d[i] = at->d[i] ^ bt->d[i];
+	}
+	for (; i < at->top; i++) {
+		r->d[i] = at->d[i];
+	}
+
+	r->top = at->top;
+	bn_correct_top(r);
+
+	return 1;
+}
+
+
+/* Some functions allow for representation of the irreducible polynomials
+ * as an int[], say p.  The irreducible f(t) is then of the form:
+ *     t^p[0] + t^p[1] + ... + t^p[k]
+ * where m = p[0] > p[1] > ... > p[k] = 0.
+ */
+
+
+/* Performs modular reduction of a and store result in r.  r could be a. */
+int
+BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[])
+{
+	int j, k;
+	int n, dN, d0, d1;
+	BN_ULONG zz, *z;
+
+	bn_check_top(a);
+
+	if (!p[0]) {
+		/* reduction mod 1 => return 0 */
+		BN_zero(r);
+		return 1;
+	}
+
+	/* Since the algorithm does reduction in the r value, if a != r, copy
+	 * the contents of a into r so we can do reduction in r.
+	 */
+	if (a != r) {
+		if (!bn_wexpand(r, a->top))
+			return 0;
+		for (j = 0; j < a->top; j++) {
+			r->d[j] = a->d[j];
+		}
+		r->top = a->top;
+	}
+	z = r->d;
+
+	/* start reduction */
+	dN = p[0] / BN_BITS2;
+	for (j = r->top - 1; j > dN; ) {
+		zz = z[j];
+		if (z[j] == 0) {
+			j--;
+			continue;
+		}
+		z[j] = 0;
+
+		for (k = 1; p[k] != 0; k++) {
+			/* reducing component t^p[k] */
+			n = p[0] - p[k];
+			d0 = n % BN_BITS2;
+			d1 = BN_BITS2 - d0;
+			n /= BN_BITS2;
+			z[j - n] ^= (zz >> d0);
+			if (d0)
+				z[j - n - 1] ^= (zz << d1);
+		}
+
+		/* reducing component t^0 */
+		n = dN;
+		d0 = p[0] % BN_BITS2;
+		d1 = BN_BITS2 - d0;
+		z[j - n] ^= (zz >> d0);
+		if (d0)
+			z[j - n - 1] ^= (zz << d1);
+	}
+
+	/* final round of reduction */
+	while (j == dN) {
+
+		d0 = p[0] % BN_BITS2;
+		zz = z[dN] >> d0;
+		if (zz == 0)
+			break;
+		d1 = BN_BITS2 - d0;
+
+		/* clear up the top d1 bits */
+		if (d0)
+			z[dN] = (z[dN] << d1) >> d1;
+		else
+			z[dN] = 0;
+		z[0] ^= zz; /* reduction t^0 component */
+
+		for (k = 1; p[k] != 0; k++) {
+			BN_ULONG tmp_ulong;
+
+			/* reducing component t^p[k]*/
+			n = p[k] / BN_BITS2;
+			d0 = p[k] % BN_BITS2;
+			d1 = BN_BITS2 - d0;
+			z[n] ^= (zz << d0);
+			tmp_ulong = zz >> d1;
+			if (d0 && tmp_ulong)
+				z[n + 1] ^= tmp_ulong;
+		}
+
+
+	}
+
+	bn_correct_top(r);
+	return 1;
+}
+
+/* Performs modular reduction of a by p and store result in r.  r could be a.
+ *
+ * This function calls down to the BN_GF2m_mod_arr implementation; this wrapper
+ * function is only provided for convenience; for best performance, use the
+ * BN_GF2m_mod_arr function.
+ */
+int
+BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p)
+{
+	int ret = 0;
+	int arr[6];
+
+	bn_check_top(a);
+	bn_check_top(p);
+	ret = BN_GF2m_poly2arr(p, arr, sizeof(arr) / sizeof(arr[0]));
+	if (!ret || ret > (int)(sizeof(arr) / sizeof(arr[0]))) {
+		BNerr(BN_F_BN_GF2M_MOD, BN_R_INVALID_LENGTH);
+		return 0;
+	}
+	ret = BN_GF2m_mod_arr(r, a, arr);
+	bn_check_top(r);
+	return ret;
+}
+
+
+/* Compute the product of two polynomials a and b, reduce modulo p, and store
+ * the result in r.  r could be a or b; a could be b.
+ */
+int
+BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const int p[],
+    BN_CTX *ctx)
+{
+	int zlen, i, j, k, ret = 0;
+	BIGNUM *s;
+	BN_ULONG x1, x0, y1, y0, zz[4];
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	if (a == b) {
+		return BN_GF2m_mod_sqr_arr(r, a, p, ctx);
+	}
+
+	BN_CTX_start(ctx);
+	if ((s = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	zlen = a->top + b->top + 4;
+	if (!bn_wexpand(s, zlen))
+		goto err;
+	s->top = zlen;
+
+	for (i = 0; i < zlen; i++)
+		s->d[i] = 0;
+
+	for (j = 0; j < b->top; j += 2) {
+		y0 = b->d[j];
+		y1 = ((j + 1) == b->top) ? 0 : b->d[j + 1];
+		for (i = 0; i < a->top; i += 2) {
+			x0 = a->d[i];
+			x1 = ((i + 1) == a->top) ? 0 : a->d[i + 1];
+			bn_GF2m_mul_2x2(zz, x1, x0, y1, y0);
+			for (k = 0; k < 4; k++)
+				s->d[i + j + k] ^= zz[k];
+		}
+	}
+
+	bn_correct_top(s);
+	if (BN_GF2m_mod_arr(r, s, p))
+		ret = 1;
+	bn_check_top(r);
+
+err:
+	BN_CTX_end(ctx);
+	return ret;
+}
+
+/* Compute the product of two polynomials a and b, reduce modulo p, and store
+ * the result in r.  r could be a or b; a could equal b.
+ *
+ * This function calls down to the BN_GF2m_mod_mul_arr implementation; this wrapper
+ * function is only provided for convenience; for best performance, use the
+ * BN_GF2m_mod_mul_arr function.
+ */
+int
+BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p,
+    BN_CTX *ctx)
+{
+	int ret = 0;
+	const int max = BN_num_bits(p) + 1;
+	int *arr = NULL;
+
+	bn_check_top(a);
+	bn_check_top(b);
+	bn_check_top(p);
+	if ((arr = reallocarray(NULL, max, sizeof(int))) == NULL)
+		goto err;
+	ret = BN_GF2m_poly2arr(p, arr, max);
+	if (!ret || ret > max) {
+		BNerr(BN_F_BN_GF2M_MOD_MUL, BN_R_INVALID_LENGTH);
+		goto err;
+	}
+	ret = BN_GF2m_mod_mul_arr(r, a, b, arr, ctx);
+	bn_check_top(r);
+
+err:
+	free(arr);
+	return ret;
+}
+
+
+/* Square a, reduce the result mod p, and store it in a.  r could be a. */
+int
+BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], BN_CTX *ctx)
+{
+	int i, ret = 0;
+	BIGNUM *s;
+
+	bn_check_top(a);
+	BN_CTX_start(ctx);
+	if ((s = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if (!bn_wexpand(s, 2 * a->top))
+		goto err;
+
+	for (i = a->top - 1; i >= 0; i--) {
+		s->d[2 * i + 1] = SQR1(a->d[i]);
+		s->d[2 * i] = SQR0(a->d[i]);
+	}
+
+	s->top = 2 * a->top;
+	bn_correct_top(s);
+	if (!BN_GF2m_mod_arr(r, s, p))
+		goto err;
+	bn_check_top(r);
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	return ret;
+}
+
+/* Square a, reduce the result mod p, and store it in a.  r could be a.
+ *
+ * This function calls down to the BN_GF2m_mod_sqr_arr implementation; this wrapper
+ * function is only provided for convenience; for best performance, use the
+ * BN_GF2m_mod_sqr_arr function.
+ */
+int
+BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+{
+	int ret = 0;
+	const int max = BN_num_bits(p) + 1;
+	int *arr = NULL;
+
+	bn_check_top(a);
+	bn_check_top(p);
+	if ((arr = reallocarray(NULL, max, sizeof(int))) == NULL)
+		goto err;
+	ret = BN_GF2m_poly2arr(p, arr, max);
+	if (!ret || ret > max) {
+		BNerr(BN_F_BN_GF2M_MOD_SQR, BN_R_INVALID_LENGTH);
+		goto err;
+	}
+	ret = BN_GF2m_mod_sqr_arr(r, a, arr, ctx);
+	bn_check_top(r);
+
+err:
+	free(arr);
+	return ret;
+}
+
+
+/* Invert a, reduce modulo p, and store the result in r. r could be a.
+ * Uses Modified Almost Inverse Algorithm (Algorithm 10) from
+ *     Hankerson, D., Hernandez, J.L., and Menezes, A.  "Software Implementation
+ *     of Elliptic Curve Cryptography Over Binary Fields".
+ */
+int
+BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+{
+	BIGNUM *b, *c = NULL, *u = NULL, *v = NULL, *tmp;
+	int ret = 0;
+
+	bn_check_top(a);
+	bn_check_top(p);
+
+	BN_CTX_start(ctx);
+
+	if ((b = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((c = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((u = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((v = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!BN_GF2m_mod(u, a, p))
+		goto err;
+	if (BN_is_zero(u))
+		goto err;
+
+	if (!BN_copy(v, p))
+		goto err;
+#if 0
+	if (!BN_one(b))
+		goto err;
+
+	while (1) {
+		while (!BN_is_odd(u)) {
+			if (BN_is_zero(u))
+				goto err;
+			if (!BN_rshift1(u, u))
+				goto err;
+			if (BN_is_odd(b)) {
+				if (!BN_GF2m_add(b, b, p))
+					goto err;
+			}
+			if (!BN_rshift1(b, b))
+				goto err;
+		}
+
+		if (BN_abs_is_word(u, 1))
+			break;
+
+		if (BN_num_bits(u) < BN_num_bits(v)) {
+			tmp = u;
+			u = v;
+			v = tmp;
+			tmp = b;
+			b = c;
+			c = tmp;
+		}
+
+		if (!BN_GF2m_add(u, u, v))
+			goto err;
+		if (!BN_GF2m_add(b, b, c))
+			goto err;
+	}
+#else
+	{
+		int i,	ubits = BN_num_bits(u),
+		vbits = BN_num_bits(v),	/* v is copy of p */
+		top = p->top;
+		BN_ULONG *udp, *bdp, *vdp, *cdp;
+
+		if (!bn_wexpand(u, top))
+                        goto err;
+		udp = u->d;
+		for (i = u->top; i < top; i++)
+			udp[i] = 0;
+		u->top = top;
+		if (!bn_wexpand(b, top))
+                        goto err;
+		bdp = b->d;
+		bdp[0] = 1;
+		for (i = 1; i < top; i++)
+			bdp[i] = 0;
+		b->top = top;
+		if (!bn_wexpand(c, top))
+                        goto err;
+		cdp = c->d;
+		for (i = 0; i < top; i++)
+			cdp[i] = 0;
+		c->top = top;
+		vdp = v->d;	/* It pays off to "cache" *->d pointers, because
+				 * it allows optimizer to be more aggressive.
+				 * But we don't have to "cache" p->d, because *p
+				 * is declared 'const'... */
+		while (1) {
+			while (ubits && !(udp[0]&1)) {
+				BN_ULONG u0, u1, b0, b1, mask;
+
+				u0 = udp[0];
+				b0 = bdp[0];
+				mask = (BN_ULONG)0 - (b0 & 1);
+				b0  ^= p->d[0] & mask;
+				for (i = 0; i < top - 1; i++) {
+					u1 = udp[i + 1];
+					udp[i] = ((u0 >> 1) |
+					    (u1 << (BN_BITS2 - 1))) & BN_MASK2;
+					u0 = u1;
+					b1 = bdp[i + 1] ^ (p->d[i + 1] & mask);
+					bdp[i] = ((b0 >> 1) |
+					    (b1 << (BN_BITS2 - 1))) & BN_MASK2;
+					b0 = b1;
+				}
+				udp[i] = u0 >> 1;
+				bdp[i] = b0 >> 1;
+				ubits--;
+			}
+
+			if (ubits <= BN_BITS2) {
+				/* See if poly was reducible. */
+				if (udp[0] == 0)
+					goto err;
+				if (udp[0] == 1)
+					break;
+			}
+
+			if (ubits < vbits) {
+				i = ubits;
+				ubits = vbits;
+				vbits = i;
+				tmp = u;
+				u = v;
+				v = tmp;
+				tmp = b;
+				b = c;
+				c = tmp;
+				udp = vdp;
+				vdp = v->d;
+				bdp = cdp;
+				cdp = c->d;
+			}
+			for (i = 0; i < top; i++) {
+				udp[i] ^= vdp[i];
+				bdp[i] ^= cdp[i];
+			}
+			if (ubits == vbits) {
+				BN_ULONG ul;
+				int utop = (ubits - 1) / BN_BITS2;
+
+				while ((ul = udp[utop]) == 0 && utop)
+					utop--;
+				ubits = utop*BN_BITS2 + BN_num_bits_word(ul);
+			}
+		}
+		bn_correct_top(b);
+	}
+#endif
+
+	if (!BN_copy(r, b))
+		goto err;
+	bn_check_top(r);
+	ret = 1;
+
+err:
+#ifdef BN_DEBUG /* BN_CTX_end would complain about the expanded form */
+	bn_correct_top(c);
+	bn_correct_top(u);
+	bn_correct_top(v);
+#endif
+	BN_CTX_end(ctx);
+	return ret;
+}
+
+/* Invert xx, reduce modulo p, and store the result in r. r could be xx.
+ *
+ * This function calls down to the BN_GF2m_mod_inv implementation; this wrapper
+ * function is only provided for convenience; for best performance, use the
+ * BN_GF2m_mod_inv function.
+ */
+int
+BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const int p[], BN_CTX *ctx)
+{
+	BIGNUM *field;
+	int ret = 0;
+
+	bn_check_top(xx);
+	BN_CTX_start(ctx);
+	if ((field = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if (!BN_GF2m_arr2poly(p, field))
+		goto err;
+
+	ret = BN_GF2m_mod_inv(r, xx, field, ctx);
+	bn_check_top(r);
+
+err:
+	BN_CTX_end(ctx);
+	return ret;
+}
+
+
+#ifndef OPENSSL_SUN_GF2M_DIV
+/* Divide y by x, reduce modulo p, and store the result in r. r could be x
+ * or y, x could equal y.
+ */
+int
+BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p,
+    BN_CTX *ctx)
+{
+	BIGNUM *xinv = NULL;
+	int ret = 0;
+
+	bn_check_top(y);
+	bn_check_top(x);
+	bn_check_top(p);
+
+	BN_CTX_start(ctx);
+	if ((xinv = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!BN_GF2m_mod_inv(xinv, x, p, ctx))
+		goto err;
+	if (!BN_GF2m_mod_mul(r, y, xinv, p, ctx))
+		goto err;
+	bn_check_top(r);
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	return ret;
+}
+#else
+/* Divide y by x, reduce modulo p, and store the result in r. r could be x
+ * or y, x could equal y.
+ * Uses algorithm Modular_Division_GF(2^m) from
+ *     Chang-Shantz, S.  "From Euclid's GCD to Montgomery Multiplication to
+ *     the Great Divide".
+ */
+int
+BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p,
+    BN_CTX *ctx)
+{
+	BIGNUM *a, *b, *u, *v;
+	int ret = 0;
+
+	bn_check_top(y);
+	bn_check_top(x);
+	bn_check_top(p);
+
+	BN_CTX_start(ctx);
+
+	if ((a = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((b = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((u = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((v = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	/* reduce x and y mod p */
+	if (!BN_GF2m_mod(u, y, p))
+		goto err;
+	if (!BN_GF2m_mod(a, x, p))
+		goto err;
+	if (!BN_copy(b, p))
+		goto err;
+
+	while (!BN_is_odd(a)) {
+		if (!BN_rshift1(a, a))
+			goto err;
+		if (BN_is_odd(u))
+			if (!BN_GF2m_add(u, u, p))
+				goto err;
+		if (!BN_rshift1(u, u))
+			goto err;
+	}
+
+	do {
+		if (BN_GF2m_cmp(b, a) > 0) {
+			if (!BN_GF2m_add(b, b, a))
+				goto err;
+			if (!BN_GF2m_add(v, v, u))
+				goto err;
+			do {
+				if (!BN_rshift1(b, b))
+					goto err;
+				if (BN_is_odd(v))
+					if (!BN_GF2m_add(v, v, p))
+						goto err;
+				if (!BN_rshift1(v, v))
+					goto err;
+			} while (!BN_is_odd(b));
+		} else if (BN_abs_is_word(a, 1))
+			break;
+		else {
+			if (!BN_GF2m_add(a, a, b))
+				goto err;
+			if (!BN_GF2m_add(u, u, v))
+				goto err;
+			do {
+				if (!BN_rshift1(a, a))
+					goto err;
+				if (BN_is_odd(u))
+					if (!BN_GF2m_add(u, u, p))
+						goto err;
+				if (!BN_rshift1(u, u))
+					goto err;
+			} while (!BN_is_odd(a));
+		}
+	} while (1);
+
+	if (!BN_copy(r, u))
+		goto err;
+	bn_check_top(r);
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	return ret;
+}
+#endif
+
+/* Divide yy by xx, reduce modulo p, and store the result in r. r could be xx
+ * or yy, xx could equal yy.
+ *
+ * This function calls down to the BN_GF2m_mod_div implementation; this wrapper
+ * function is only provided for convenience; for best performance, use the
+ * BN_GF2m_mod_div function.
+ */
+int
+BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx,
+    const int p[], BN_CTX *ctx)
+{
+	BIGNUM *field;
+	int ret = 0;
+
+	bn_check_top(yy);
+	bn_check_top(xx);
+
+	BN_CTX_start(ctx);
+	if ((field = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if (!BN_GF2m_arr2poly(p, field))
+		goto err;
+
+	ret = BN_GF2m_mod_div(r, yy, xx, field, ctx);
+	bn_check_top(r);
+
+err:
+	BN_CTX_end(ctx);
+	return ret;
+}
+
+
+/* Compute the bth power of a, reduce modulo p, and store
+ * the result in r.  r could be a.
+ * Uses simple square-and-multiply algorithm A.5.1 from IEEE P1363.
+ */
+int
+BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const int p[],
+    BN_CTX *ctx)
+{
+	int ret = 0, i, n;
+	BIGNUM *u;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	if (BN_is_zero(b))
+		return (BN_one(r));
+
+	if (BN_abs_is_word(b, 1))
+		return (BN_copy(r, a) != NULL);
+
+	BN_CTX_start(ctx);
+	if ((u = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!BN_GF2m_mod_arr(u, a, p))
+		goto err;
+
+	n = BN_num_bits(b) - 1;
+	for (i = n - 1; i >= 0; i--) {
+		if (!BN_GF2m_mod_sqr_arr(u, u, p, ctx))
+			goto err;
+		if (BN_is_bit_set(b, i)) {
+			if (!BN_GF2m_mod_mul_arr(u, u, a, p, ctx))
+				goto err;
+		}
+	}
+	if (!BN_copy(r, u))
+		goto err;
+	bn_check_top(r);
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	return ret;
+}
+
+/* Compute the bth power of a, reduce modulo p, and store
+ * the result in r.  r could be a.
+ *
+ * This function calls down to the BN_GF2m_mod_exp_arr implementation; this wrapper
+ * function is only provided for convenience; for best performance, use the
+ * BN_GF2m_mod_exp_arr function.
+ */
+int
+BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p,
+    BN_CTX *ctx)
+{
+	int ret = 0;
+	const int max = BN_num_bits(p) + 1;
+	int *arr = NULL;
+
+	bn_check_top(a);
+	bn_check_top(b);
+	bn_check_top(p);
+	if ((arr = reallocarray(NULL, max, sizeof(int))) == NULL)
+		goto err;
+	ret = BN_GF2m_poly2arr(p, arr, max);
+	if (!ret || ret > max) {
+		BNerr(BN_F_BN_GF2M_MOD_EXP, BN_R_INVALID_LENGTH);
+		goto err;
+	}
+	ret = BN_GF2m_mod_exp_arr(r, a, b, arr, ctx);
+	bn_check_top(r);
+
+err:
+	free(arr);
+	return ret;
+}
+
+/* Compute the square root of a, reduce modulo p, and store
+ * the result in r.  r could be a.
+ * Uses exponentiation as in algorithm A.4.1 from IEEE P1363.
+ */
+int
+BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const int p[], BN_CTX *ctx)
+{
+	int ret = 0;
+	BIGNUM *u;
+
+	bn_check_top(a);
+
+	if (!p[0]) {
+		/* reduction mod 1 => return 0 */
+		BN_zero(r);
+		return 1;
+	}
+
+	BN_CTX_start(ctx);
+	if ((u = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!BN_set_bit(u, p[0] - 1))
+		goto err;
+	ret = BN_GF2m_mod_exp_arr(r, a, u, p, ctx);
+	bn_check_top(r);
+
+err:
+	BN_CTX_end(ctx);
+	return ret;
+}
+
+/* Compute the square root of a, reduce modulo p, and store
+ * the result in r.  r could be a.
+ *
+ * This function calls down to the BN_GF2m_mod_sqrt_arr implementation; this wrapper
+ * function is only provided for convenience; for best performance, use the
+ * BN_GF2m_mod_sqrt_arr function.
+ */
+int
+BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+{
+	int ret = 0;
+	const int max = BN_num_bits(p) + 1;
+	int *arr = NULL;
+	bn_check_top(a);
+	bn_check_top(p);
+	if ((arr = reallocarray(NULL, max, sizeof(int))) == NULL)
+		goto err;
+	ret = BN_GF2m_poly2arr(p, arr, max);
+	if (!ret || ret > max) {
+		BNerr(BN_F_BN_GF2M_MOD_SQRT, BN_R_INVALID_LENGTH);
+		goto err;
+	}
+	ret = BN_GF2m_mod_sqrt_arr(r, a, arr, ctx);
+	bn_check_top(r);
+
+err:
+	free(arr);
+	return ret;
+}
+
+/* Find r such that r^2 + r = a mod p.  r could be a. If no r exists returns 0.
+ * Uses algorithms A.4.7 and A.4.6 from IEEE P1363.
+ */
+int
+BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const int p[],
+    BN_CTX *ctx)
+{
+	int ret = 0, count = 0, j;
+	BIGNUM *a, *z, *rho, *w, *w2, *tmp;
+
+	bn_check_top(a_);
+
+	if (!p[0]) {
+		/* reduction mod 1 => return 0 */
+		BN_zero(r);
+		return 1;
+	}
+
+	BN_CTX_start(ctx);
+	if ((a = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((z = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((w = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!BN_GF2m_mod_arr(a, a_, p))
+		goto err;
+
+	if (BN_is_zero(a)) {
+		BN_zero(r);
+		ret = 1;
+		goto err;
+	}
+
+	if (p[0] & 0x1) /* m is odd */
+	{
+		/* compute half-trace of a */
+		if (!BN_copy(z, a))
+			goto err;
+		for (j = 1; j <= (p[0] - 1) / 2; j++) {
+			if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx))
+				goto err;
+			if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx))
+				goto err;
+			if (!BN_GF2m_add(z, z, a))
+				goto err;
+		}
+
+	}
+	else /* m is even */
+	{
+		if ((rho = BN_CTX_get(ctx)) == NULL)
+			goto err;
+		if ((w2 = BN_CTX_get(ctx)) == NULL)
+			goto err;
+		if ((tmp = BN_CTX_get(ctx)) == NULL)
+			goto err;
+		do {
+			if (!BN_rand(rho, p[0], 0, 0))
+				goto err;
+			if (!BN_GF2m_mod_arr(rho, rho, p))
+				goto err;
+			BN_zero(z);
+			if (!BN_copy(w, rho))
+				goto err;
+			for (j = 1; j <= p[0] - 1; j++) {
+				if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx))
+					goto err;
+				if (!BN_GF2m_mod_sqr_arr(w2, w, p, ctx))
+					goto err;
+				if (!BN_GF2m_mod_mul_arr(tmp, w2, a, p, ctx))
+					goto err;
+				if (!BN_GF2m_add(z, z, tmp))
+					goto err;
+				if (!BN_GF2m_add(w, w2, rho))
+					goto err;
+			}
+			count++;
+		} while (BN_is_zero(w) && (count < MAX_ITERATIONS));
+		if (BN_is_zero(w)) {
+			BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR,
+			    BN_R_TOO_MANY_ITERATIONS);
+			goto err;
+		}
+	}
+
+	if (!BN_GF2m_mod_sqr_arr(w, z, p, ctx))
+		goto err;
+	if (!BN_GF2m_add(w, z, w))
+		goto err;
+	if (BN_GF2m_cmp(w, a)) {
+		BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_NO_SOLUTION);
+		goto err;
+	}
+
+	if (!BN_copy(r, z))
+		goto err;
+	bn_check_top(r);
+
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	return ret;
+}
+
+/* Find r such that r^2 + r = a mod p.  r could be a. If no r exists returns 0.
+ *
+ * This function calls down to the BN_GF2m_mod_solve_quad_arr implementation; this wrapper
+ * function is only provided for convenience; for best performance, use the
+ * BN_GF2m_mod_solve_quad_arr function.
+ */
+int
+BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+{
+	int ret = 0;
+	const int max = BN_num_bits(p) + 1;
+	int *arr = NULL;
+
+	bn_check_top(a);
+	bn_check_top(p);
+	if ((arr = reallocarray(NULL, max, sizeof(int))) == NULL)
+		goto err;
+	ret = BN_GF2m_poly2arr(p, arr, max);
+	if (!ret || ret > max) {
+		BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD, BN_R_INVALID_LENGTH);
+		goto err;
+	}
+	ret = BN_GF2m_mod_solve_quad_arr(r, a, arr, ctx);
+	bn_check_top(r);
+
+err:
+	free(arr);
+	return ret;
+}
+
+/* Convert the bit-string representation of a polynomial
+ * ( \sum_{i=0}^n a_i * x^i) into an array of integers corresponding
+ * to the bits with non-zero coefficient.  Array is terminated with -1.
+ * Up to max elements of the array will be filled.  Return value is total
+ * number of array elements that would be filled if array was large enough.
+ */
+int
+BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max)
+{
+	int i, j, k = 0;
+	BN_ULONG mask;
+
+	if (BN_is_zero(a))
+		return 0;
+
+	for (i = a->top - 1; i >= 0; i--) {
+		if (!a->d[i])
+			/* skip word if a->d[i] == 0 */
+			continue;
+		mask = BN_TBIT;
+		for (j = BN_BITS2 - 1; j >= 0; j--) {
+			if (a->d[i] & mask) {
+				if (k < max)
+					p[k] = BN_BITS2 * i + j;
+				k++;
+			}
+			mask >>= 1;
+		}
+	}
+
+	if (k < max) {
+		p[k] = -1;
+		k++;
+	}
+
+	return k;
+}
+
+/* Convert the coefficient array representation of a polynomial to a
+ * bit-string.  The array must be terminated by -1.
+ */
+int
+BN_GF2m_arr2poly(const int p[], BIGNUM *a)
+{
+	int i;
+
+	bn_check_top(a);
+	BN_zero(a);
+	for (i = 0; p[i] != -1; i++) {
+		if (BN_set_bit(a, p[i]) == 0)
+			return 0;
+	}
+	bn_check_top(a);
+
+	return 1;
+}
+
+#endif
diff --git a/crypto/libressl/crypto/bn/bn_kron.c b/crypto/libressl/crypto/bn/bn_kron.c
new file mode 100644
index 0000000000..87eb2c0fbd
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_kron.c
@@ -0,0 +1,185 @@
+/* $OpenBSD: bn_kron.c,v 1.5 2014/07/11 08:44:48 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "bn_lcl.h"
+
+/* least significant word */
+#define BN_lsw(n) (((n)->top == 0) ? (BN_ULONG) 0 : (n)->d[0])
+
+/* Returns -2 for errors because both -1 and 0 are valid results. */
+int
+BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+{
+	int i;
+	int ret = -2; /* avoid 'uninitialized' warning */
+	int err = 0;
+	BIGNUM *A, *B, *tmp;
+
+	/* In 'tab', only odd-indexed entries are relevant:
+	 * For any odd BIGNUM n,
+	 *     tab[BN_lsw(n) & 7]
+	 * is $(-1)^{(n^2-1)/8}$ (using TeX notation).
+	 * Note that the sign of n does not matter.
+	 */
+	static const int tab[8] = {0, 1, 0, -1, 0, -1, 0, 1};
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	BN_CTX_start(ctx);
+	if ((A = BN_CTX_get(ctx)) == NULL)
+		goto end;
+	if ((B = BN_CTX_get(ctx)) == NULL)
+		goto end;
+
+	err = !BN_copy(A, a);
+	if (err)
+		goto end;
+	err = !BN_copy(B, b);
+	if (err)
+		goto end;
+
+	/*
+	 * Kronecker symbol, imlemented according to Henri Cohen,
+	 * "A Course in Computational Algebraic Number Theory"
+	 * (algorithm 1.4.10).
+	 */
+
+	/* Cohen's step 1: */
+
+	if (BN_is_zero(B)) {
+		ret = BN_abs_is_word(A, 1);
+		goto end;
+	}
+
+	/* Cohen's step 2: */
+
+	if (!BN_is_odd(A) && !BN_is_odd(B)) {
+		ret = 0;
+		goto end;
+	}
+
+	/* now  B  is non-zero */
+	i = 0;
+	while (!BN_is_bit_set(B, i))
+		i++;
+	err = !BN_rshift(B, B, i);
+	if (err)
+		goto end;
+	if (i & 1) {
+		/* i is odd */
+		/* (thus  B  was even, thus  A  must be odd!)  */
+
+		/* set 'ret' to $(-1)^{(A^2-1)/8}$ */
+		ret = tab[BN_lsw(A) & 7];
+	} else {
+		/* i is even */
+		ret = 1;
+	}
+
+	if (B->neg) {
+		B->neg = 0;
+		if (A->neg)
+			ret = -ret;
+	}
+
+	/* now  B  is positive and odd, so what remains to be done is
+	 * to compute the Jacobi symbol  (A/B)  and multiply it by 'ret' */
+
+	while (1) {
+		/* Cohen's step 3: */
+
+		/*  B  is positive and odd */
+
+		if (BN_is_zero(A)) {
+			ret = BN_is_one(B) ? ret : 0;
+			goto end;
+		}
+
+		/* now  A  is non-zero */
+		i = 0;
+		while (!BN_is_bit_set(A, i))
+			i++;
+		err = !BN_rshift(A, A, i);
+		if (err)
+			goto end;
+		if (i & 1) {
+			/* i is odd */
+			/* multiply 'ret' by  $(-1)^{(B^2-1)/8}$ */
+			ret = ret * tab[BN_lsw(B) & 7];
+		}
+
+		/* Cohen's step 4: */
+		/* multiply 'ret' by  $(-1)^{(A-1)(B-1)/4}$ */
+		if ((A->neg ? ~BN_lsw(A) : BN_lsw(A)) & BN_lsw(B) & 2)
+			ret = -ret;
+
+		/* (A, B) := (B mod |A|, |A|) */
+		err = !BN_nnmod(B, B, A, ctx);
+		if (err)
+			goto end;
+		tmp = A;
+		A = B;
+		B = tmp;
+		tmp->neg = 0;
+	}
+
+end:
+	BN_CTX_end(ctx);
+	if (err)
+		return -2;
+	else
+		return ret;
+}
diff --git a/crypto/libressl/crypto/bn/bn_lcl.h b/crypto/libressl/crypto/bn/bn_lcl.h
new file mode 100644
index 0000000000..a8e02072a9
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_lcl.h
@@ -0,0 +1,484 @@
+/* $OpenBSD: bn_lcl.h,v 1.21 2014/10/28 07:35:58 jsg Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_BN_LCL_H
+#define HEADER_BN_LCL_H
+
+#include 
+
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions
+ *
+ *
+ * For window size 'w' (w >= 2) and a random 'b' bits exponent,
+ * the number of multiplications is a constant plus on average
+ *
+ *    2^(w-1) + (b-w)/(w+1);
+ *
+ * here  2^(w-1)  is for precomputing the table (we actually need
+ * entries only for windows that have the lowest bit set), and
+ * (b-w)/(w+1)  is an approximation for the expected number of
+ * w-bit windows, not counting the first one.
+ *
+ * Thus we should use
+ *
+ *    w >= 6  if        b > 671
+ *     w = 5  if  671 > b > 239
+ *     w = 4  if  239 > b >  79
+ *     w = 3  if   79 > b >  23
+ *    w <= 2  if   23 > b
+ *
+ * (with draws in between).  Very small exponents are often selected
+ * with low Hamming weight, so we use  w = 1  for b <= 23.
+ */
+#define BN_window_bits_for_exponent_size(b) \
+		((b) > 671 ? 6 : \
+		 (b) > 239 ? 5 : \
+		 (b) >  79 ? 4 : \
+		 (b) >  23 ? 3 : 1)
+
+
+/* BN_mod_exp_mont_consttime is based on the assumption that the
+ * L1 data cache line width of the target processor is at least
+ * the following value.
+ */
+#define MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH	( 64 )
+#define MOD_EXP_CTIME_MIN_CACHE_LINE_MASK	(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - 1)
+
+/* Window sizes optimized for fixed window size modular exponentiation
+ * algorithm (BN_mod_exp_mont_consttime).
+ *
+ * To achieve the security goals of BN_mode_exp_mont_consttime, the
+ * maximum size of the window must not exceed
+ * log_2(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH).
+ *
+ * Window size thresholds are defined for cache line sizes of 32 and 64,
+ * cache line sizes where log_2(32)=5 and log_2(64)=6 respectively. A
+ * window size of 7 should only be used on processors that have a 128
+ * byte or greater cache line size.
+ */
+#if MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 64
+
+#  define BN_window_bits_for_ctime_exponent_size(b) \
+		((b) > 937 ? 6 : \
+		 (b) > 306 ? 5 : \
+		 (b) >  89 ? 4 : \
+		 (b) >  22 ? 3 : 1)
+#  define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE	(6)
+
+#elif MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 32
+
+#  define BN_window_bits_for_ctime_exponent_size(b) \
+		((b) > 306 ? 5 : \
+		 (b) >  89 ? 4 : \
+		 (b) >  22 ? 3 : 1)
+#  define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE	(5)
+
+#endif
+
+
+/* Pentium pro 16,16,16,32,64 */
+/* Alpha       16,16,16,16.64 */
+#define BN_MULL_SIZE_NORMAL			(16) /* 32 */
+#define BN_MUL_RECURSIVE_SIZE_NORMAL		(16) /* 32 less than */
+#define BN_SQR_RECURSIVE_SIZE_NORMAL		(16) /* 32 */
+#define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL	(32) /* 32 */
+#define BN_MONT_CTX_SET_SIZE_WORD		(64) /* 32 */
+
+#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+/*
+ * BN_UMULT_HIGH section.
+ *
+ * No, I'm not trying to overwhelm you when stating that the
+ * product of N-bit numbers is 2*N bits wide:-) No, I don't expect
+ * you to be impressed when I say that if the compiler doesn't
+ * support 2*N integer type, then you have to replace every N*N
+ * multiplication with 4 (N/2)*(N/2) accompanied by some shifts
+ * and additions which unavoidably results in severe performance
+ * penalties. Of course provided that the hardware is capable of
+ * producing 2*N result... That's when you normally start
+ * considering assembler implementation. However! It should be
+ * pointed out that some CPUs (most notably Alpha, PowerPC and
+ * upcoming IA-64 family:-) provide *separate* instruction
+ * calculating the upper half of the product placing the result
+ * into a general purpose register. Now *if* the compiler supports
+ * inline assembler, then it's not impossible to implement the
+ * "bignum" routines (and have the compiler optimize 'em)
+ * exhibiting "native" performance in C. That's what BN_UMULT_HIGH
+ * macro is about:-)
+ *
+ *					
+ */
+# if defined(__alpha)
+#  if defined(__GNUC__) && __GNUC__>=2
+#   define BN_UMULT_HIGH(a,b)	({	\
+	BN_ULONG ret;		\
+	asm ("umulh	%1,%2,%0"	\
+	     : "=r"(ret)		\
+	     : "r"(a), "r"(b));		\
+	ret;			})
+#  endif	/* compiler */
+# elif defined(_ARCH_PPC) && defined(_LP64)
+#  if defined(__GNUC__) && __GNUC__>=2
+#   define BN_UMULT_HIGH(a,b)	({	\
+	BN_ULONG ret;		\
+	asm ("mulhdu	%0,%1,%2"	\
+	     : "=r"(ret)		\
+	     : "r"(a), "r"(b));		\
+	ret;			})
+#  endif	/* compiler */
+# elif defined(__x86_64) || defined(__x86_64__)
+#  if defined(__GNUC__) && __GNUC__>=2
+#   define BN_UMULT_HIGH(a,b)	({	\
+	BN_ULONG ret,discard;	\
+	asm ("mulq	%3"		\
+	     : "=a"(discard),"=d"(ret)	\
+	     : "a"(a), "g"(b)		\
+	     : "cc");			\
+	ret;			})
+#   define BN_UMULT_LOHI(low,high,a,b)	\
+	asm ("mulq	%3"		\
+		: "=a"(low),"=d"(high)	\
+		: "a"(a),"g"(b)		\
+		: "cc");
+#  endif
+# elif defined(__mips) && defined(_LP64)
+#  if defined(__GNUC__) && __GNUC__>=2
+#   if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) /* "h" constraint is no more since 4.4 */
+#     define BN_UMULT_HIGH(a,b)		 (((__uint128_t)(a)*(b))>>64)
+#     define BN_UMULT_LOHI(low,high,a,b) ({	\
+	__uint128_t ret=(__uint128_t)(a)*(b);	\
+	(high)=ret>>64; (low)=ret;	 })
+#   else
+#     define BN_UMULT_HIGH(a,b)	({	\
+	BN_ULONG ret;		\
+	asm ("dmultu	%1,%2"		\
+	     : "=h"(ret)		\
+	     : "r"(a), "r"(b) : "l");	\
+	ret;			})
+#     define BN_UMULT_LOHI(low,high,a,b)\
+	asm ("dmultu	%2,%3"		\
+	     : "=l"(low),"=h"(high)	\
+	     : "r"(a), "r"(b));
+#    endif
+#  endif
+# endif		/* cpu */
+#endif		/* OPENSSL_NO_ASM */
+
+/*************************************************************
+ * Using the long long type
+ */
+#define Lw(t)    (((BN_ULONG)(t))&BN_MASK2)
+#define Hw(t)    (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
+
+#ifdef BN_DEBUG_RAND
+#define bn_clear_top2max(a) \
+	{ \
+	int      ind = (a)->dmax - (a)->top; \
+	BN_ULONG *ftl = &(a)->d[(a)->top-1]; \
+	for (; ind != 0; ind--) \
+		*(++ftl) = 0x0; \
+	}
+#else
+#define bn_clear_top2max(a)
+#endif
+
+#ifdef BN_LLONG
+#define mul_add(r,a,w,c) { \
+	BN_ULLONG t; \
+	t=(BN_ULLONG)w * (a) + (r) + (c); \
+	(r)= Lw(t); \
+	(c)= Hw(t); \
+	}
+
+#define mul(r,a,w,c) { \
+	BN_ULLONG t; \
+	t=(BN_ULLONG)w * (a) + (c); \
+	(r)= Lw(t); \
+	(c)= Hw(t); \
+	}
+
+#define sqr(r0,r1,a) { \
+	BN_ULLONG t; \
+	t=(BN_ULLONG)(a)*(a); \
+	(r0)=Lw(t); \
+	(r1)=Hw(t); \
+	}
+
+#elif defined(BN_UMULT_LOHI)
+#define mul_add(r,a,w,c) {		\
+	BN_ULONG high,low,ret,tmp=(a);	\
+	ret =  (r);			\
+	BN_UMULT_LOHI(low,high,w,tmp);	\
+	ret += (c);			\
+	(c) =  (ret<(c))?1:0;		\
+	(c) += high;			\
+	ret += low;			\
+	(c) += (ret>BN_BITS4)&BN_MASK2l)
+#define	L2HBITS(a)	(((a)<>(BN_BITS4-1); \
+	m =(m&BN_MASK2l)<<(BN_BITS4+1); \
+	l=(l+m)&BN_MASK2; if (l < m) h++; \
+	(lo)=l; \
+	(ho)=h; \
+	}
+
+#define mul_add(r,a,bl,bh,c) { \
+	BN_ULONG l,h; \
+ \
+	h= (a); \
+	l=LBITS(h); \
+	h=HBITS(h); \
+	mul64(l,h,(bl),(bh)); \
+ \
+	/* non-multiply part */ \
+	l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
+	(c)=(r); \
+	l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
+	(c)=h&BN_MASK2; \
+	(r)=l; \
+	}
+
+#define mul(r,a,bl,bh,c) { \
+	BN_ULONG l,h; \
+ \
+	h= (a); \
+	l=LBITS(h); \
+	h=HBITS(h); \
+	mul64(l,h,(bl),(bh)); \
+ \
+	/* non-multiply part */ \
+	l+=(c); if ((l&BN_MASK2) < (c)) h++; \
+	(c)=h&BN_MASK2; \
+	(r)=l&BN_MASK2; \
+	}
+#endif /* !BN_LLONG */
+
+	void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb);
+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
+void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp);
+void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a);
+void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a);
+int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n);
+int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
+    int cl, int dl);
+void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
+    int dna, int dnb, BN_ULONG *t);
+void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b,
+    int n, int tna, int tnb, BN_ULONG *t);
+void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t);
+void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n);
+void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
+    BN_ULONG *t);
+void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
+    BN_ULONG *t);
+BN_ULONG bn_add_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
+    int cl, int dl);
+BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
+    int cl, int dl);
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/crypto/libressl/crypto/bn/bn_lib.c b/crypto/libressl/crypto/bn/bn_lib.c
new file mode 100644
index 0000000000..ebae435074
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_lib.c
@@ -0,0 +1,895 @@
+/* $OpenBSD: bn_lib.c,v 1.35 2016/03/04 16:23:30 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef BN_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+
+#include "bn_lcl.h"
+
+/* This stuff appears to be completely unused, so is deprecated */
+#ifndef OPENSSL_NO_DEPRECATED
+/* For a 32 bit machine
+ * 2 -   4 ==  128
+ * 3 -   8 ==  256
+ * 4 -  16 ==  512
+ * 5 -  32 == 1024
+ * 6 -  64 == 2048
+ * 7 - 128 == 4096
+ * 8 - 256 == 8192
+ */
+static int bn_limit_bits = 0;
+static int bn_limit_num = 8;        /* (1<= 0) {
+		if (mult > (int)(sizeof(int) * 8) - 1)
+			mult = sizeof(int) * 8 - 1;
+		bn_limit_bits = mult;
+		bn_limit_num = 1 << mult;
+	}
+	if (high >= 0) {
+		if (high > (int)(sizeof(int) * 8) - 1)
+			high = sizeof(int) * 8 - 1;
+		bn_limit_bits_high = high;
+		bn_limit_num_high = 1 << high;
+	}
+	if (low >= 0) {
+		if (low > (int)(sizeof(int) * 8) - 1)
+			low = sizeof(int) * 8 - 1;
+		bn_limit_bits_low = low;
+		bn_limit_num_low = 1 << low;
+	}
+	if (mont >= 0) {
+		if (mont > (int)(sizeof(int) * 8) - 1)
+			mont = sizeof(int) * 8 - 1;
+		bn_limit_bits_mont = mont;
+		bn_limit_num_mont = 1 << mont;
+	}
+}
+
+int
+BN_get_params(int which)
+{
+	if (which == 0)
+		return (bn_limit_bits);
+	else if (which == 1)
+		return (bn_limit_bits_high);
+	else if (which == 2)
+		return (bn_limit_bits_low);
+	else if (which == 3)
+		return (bn_limit_bits_mont);
+	else
+		return (0);
+}
+#endif
+
+const BIGNUM *
+BN_value_one(void)
+{
+	static const BN_ULONG data_one = 1L;
+	static const BIGNUM const_one = {
+		(BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA
+	};
+
+	return (&const_one);
+}
+
+int
+BN_num_bits_word(BN_ULONG l)
+{
+	static const unsigned char bits[256] = {
+		0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+		5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+		8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,  8, 8, 8, 8,
+		8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+		8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+		8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+		8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+		8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+		8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+		8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+	};
+
+#ifdef _LP64
+	if (l & 0xffffffff00000000L) {
+		if (l & 0xffff000000000000L) {
+			if (l & 0xff00000000000000L) {
+				return (bits[(int)(l >> 56)] + 56);
+			} else
+				return (bits[(int)(l >> 48)] + 48);
+		} else {
+			if (l & 0x0000ff0000000000L) {
+				return (bits[(int)(l >> 40)] + 40);
+			} else
+				return (bits[(int)(l >> 32)] + 32);
+		}
+	} else
+#endif
+	{
+		if (l & 0xffff0000L) {
+			if (l & 0xff000000L)
+				return (bits[(int)(l >> 24L)] + 24);
+			else
+				return (bits[(int)(l >> 16L)] + 16);
+		} else {
+			if (l & 0xff00L)
+				return (bits[(int)(l >> 8)] + 8);
+			else
+				return (bits[(int)(l)]);
+		}
+	}
+}
+
+int
+BN_num_bits(const BIGNUM *a)
+{
+	int i = a->top - 1;
+
+	bn_check_top(a);
+
+	if (BN_is_zero(a))
+		return 0;
+	return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));
+}
+
+void
+BN_clear_free(BIGNUM *a)
+{
+	int i;
+
+	if (a == NULL)
+		return;
+	bn_check_top(a);
+	if (a->d != NULL && !(BN_get_flags(a, BN_FLG_STATIC_DATA))) {
+		explicit_bzero(a->d, a->dmax * sizeof(a->d[0]));
+		free(a->d);
+	}
+	i = BN_get_flags(a, BN_FLG_MALLOCED);
+	explicit_bzero(a, sizeof(BIGNUM));
+	if (i)
+		free(a);
+}
+
+void
+BN_free(BIGNUM *a)
+{
+	BN_clear_free(a);
+}
+
+void
+BN_init(BIGNUM *a)
+{
+	memset(a, 0, sizeof(BIGNUM));
+	bn_check_top(a);
+}
+
+BIGNUM *
+BN_new(void)
+{
+	BIGNUM *ret;
+
+	if ((ret = malloc(sizeof(BIGNUM))) == NULL) {
+		BNerr(BN_F_BN_NEW, ERR_R_MALLOC_FAILURE);
+		return (NULL);
+	}
+	ret->flags = BN_FLG_MALLOCED;
+	ret->top = 0;
+	ret->neg = 0;
+	ret->dmax = 0;
+	ret->d = NULL;
+	bn_check_top(ret);
+	return (ret);
+}
+
+/* This is used both by bn_expand2() and bn_dup_expand() */
+/* The caller MUST check that words > b->dmax before calling this */
+static BN_ULONG *
+bn_expand_internal(const BIGNUM *b, int words)
+{
+	BN_ULONG *A, *a = NULL;
+	const BN_ULONG *B;
+	int i;
+
+	bn_check_top(b);
+
+	if (words > (INT_MAX/(4*BN_BITS2))) {
+		BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_BIGNUM_TOO_LONG);
+		return NULL;
+	}
+	if (BN_get_flags(b, BN_FLG_STATIC_DATA)) {
+		BNerr(BN_F_BN_EXPAND_INTERNAL,
+		    BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
+		return (NULL);
+	}
+	a = A = reallocarray(NULL, words, sizeof(BN_ULONG));
+	if (A == NULL) {
+		BNerr(BN_F_BN_EXPAND_INTERNAL, ERR_R_MALLOC_FAILURE);
+		return (NULL);
+	}
+#if 1
+	B = b->d;
+	/* Check if the previous number needs to be copied */
+	if (B != NULL) {
+		for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) {
+			/*
+			 * The fact that the loop is unrolled
+			 * 4-wise is a tribute to Intel. It's
+			 * the one that doesn't have enough
+			 * registers to accommodate more data.
+			 * I'd unroll it 8-wise otherwise:-)
+			 *
+			 *		
+			 */
+			BN_ULONG a0, a1, a2, a3;
+			a0 = B[0];
+			a1 = B[1];
+			a2 = B[2];
+			a3 = B[3];
+			A[0] = a0;
+			A[1] = a1;
+			A[2] = a2;
+			A[3] = a3;
+		}
+		switch (b->top & 3) {
+		case 3:
+			A[2] = B[2];
+		case 2:
+			A[1] = B[1];
+		case 1:
+			A[0] = B[0];
+		}
+	}
+
+#else
+	memset(A, 0, sizeof(BN_ULONG) * words);
+	memcpy(A, b->d, sizeof(b->d[0]) * b->top);
+#endif
+
+	return (a);
+}
+
+/* This is an internal function that can be used instead of bn_expand2()
+ * when there is a need to copy BIGNUMs instead of only expanding the
+ * data part, while still expanding them.
+ * Especially useful when needing to expand BIGNUMs that are declared
+ * 'const' and should therefore not be changed.
+ * The reason to use this instead of a BN_dup() followed by a bn_expand2()
+ * is memory allocation overhead.  A BN_dup() followed by a bn_expand2()
+ * will allocate new memory for the BIGNUM data twice, and free it once,
+ * while bn_dup_expand() makes sure allocation is made only once.
+ */
+
+#ifndef OPENSSL_NO_DEPRECATED
+BIGNUM *
+bn_dup_expand(const BIGNUM *b, int words)
+{
+	BIGNUM *r = NULL;
+
+	bn_check_top(b);
+
+	/* This function does not work if
+	 *      words <= b->dmax && top < words
+	 * because BN_dup() does not preserve 'dmax'!
+	 * (But bn_dup_expand() is not used anywhere yet.)
+	 */
+
+	if (words > b->dmax) {
+		BN_ULONG *a = bn_expand_internal(b, words);
+
+		if (a) {
+			r = BN_new();
+			if (r) {
+				r->top = b->top;
+				r->dmax = words;
+				r->neg = b->neg;
+				r->d = a;
+			} else {
+				/* r == NULL, BN_new failure */
+				free(a);
+			}
+		}
+		/* If a == NULL, there was an error in allocation in
+		   bn_expand_internal(), and NULL should be returned */
+	} else {
+		r = BN_dup(b);
+	}
+
+	bn_check_top(r);
+	return r;
+}
+#endif
+
+/* This is an internal function that should not be used in applications.
+ * It ensures that 'b' has enough room for a 'words' word number
+ * and initialises any unused part of b->d with leading zeros.
+ * It is mostly used by the various BIGNUM routines. If there is an error,
+ * NULL is returned. If not, 'b' is returned. */
+
+BIGNUM *
+bn_expand2(BIGNUM *b, int words)
+{
+	bn_check_top(b);
+
+	if (words > b->dmax) {
+		BN_ULONG *a = bn_expand_internal(b, words);
+		if (!a)
+			return NULL;
+		if (b->d) {
+			explicit_bzero(b->d, b->dmax * sizeof(b->d[0]));
+			free(b->d);
+		}
+		b->d = a;
+		b->dmax = words;
+	}
+
+/* None of this should be necessary because of what b->top means! */
+#if 0
+	/* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */
+	if (b->top < b->dmax) {
+		int i;
+		BN_ULONG *A = &(b->d[b->top]);
+		for (i = (b->dmax - b->top) >> 3; i > 0; i--, A += 8) {
+			A[0] = 0;
+			A[1] = 0;
+			A[2] = 0;
+			A[3] = 0;
+			A[4] = 0;
+			A[5] = 0;
+			A[6] = 0;
+			A[7] = 0;
+		}
+		for (i = (b->dmax - b->top)&7; i > 0; i--, A++)
+			A[0] = 0;
+		assert(A == &(b->d[b->dmax]));
+	}
+#endif
+	bn_check_top(b);
+	return b;
+}
+
+BIGNUM *
+BN_dup(const BIGNUM *a)
+{
+	BIGNUM *t;
+
+	if (a == NULL)
+		return NULL;
+	bn_check_top(a);
+
+	t = BN_new();
+	if (t == NULL)
+		return NULL;
+	if (!BN_copy(t, a)) {
+		BN_free(t);
+		return NULL;
+	}
+	bn_check_top(t);
+	return t;
+}
+
+BIGNUM *
+BN_copy(BIGNUM *a, const BIGNUM *b)
+{
+	int i;
+	BN_ULONG *A;
+	const BN_ULONG *B;
+
+	bn_check_top(b);
+
+	if (a == b)
+		return (a);
+	if (bn_wexpand(a, b->top) == NULL)
+		return (NULL);
+
+#if 1
+	A = a->d;
+	B = b->d;
+	for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) {
+		BN_ULONG a0, a1, a2, a3;
+		a0 = B[0];
+		a1 = B[1];
+		a2 = B[2];
+		a3 = B[3];
+		A[0] = a0;
+		A[1] = a1;
+		A[2] = a2;
+		A[3] = a3;
+	}
+	switch (b->top & 3) {
+	case 3:
+		A[2] = B[2];
+	case 2:
+		A[1] = B[1];
+	case 1:
+		A[0] = B[0];
+	}
+#else
+	memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);
+#endif
+
+	a->top = b->top;
+	a->neg = b->neg;
+	bn_check_top(a);
+	return (a);
+}
+
+void
+BN_swap(BIGNUM *a, BIGNUM *b)
+{
+	int flags_old_a, flags_old_b;
+	BN_ULONG *tmp_d;
+	int tmp_top, tmp_dmax, tmp_neg;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	flags_old_a = a->flags;
+	flags_old_b = b->flags;
+
+	tmp_d = a->d;
+	tmp_top = a->top;
+	tmp_dmax = a->dmax;
+	tmp_neg = a->neg;
+
+	a->d = b->d;
+	a->top = b->top;
+	a->dmax = b->dmax;
+	a->neg = b->neg;
+
+	b->d = tmp_d;
+	b->top = tmp_top;
+	b->dmax = tmp_dmax;
+	b->neg = tmp_neg;
+
+	a->flags = (flags_old_a & BN_FLG_MALLOCED) |
+	    (flags_old_b & BN_FLG_STATIC_DATA);
+	b->flags = (flags_old_b & BN_FLG_MALLOCED) |
+	    (flags_old_a & BN_FLG_STATIC_DATA);
+	bn_check_top(a);
+	bn_check_top(b);
+}
+
+void
+BN_clear(BIGNUM *a)
+{
+	bn_check_top(a);
+	if (a->d != NULL)
+		memset(a->d, 0, a->dmax * sizeof(a->d[0]));
+	a->top = 0;
+	a->neg = 0;
+}
+
+BN_ULONG
+BN_get_word(const BIGNUM *a)
+{
+	if (a->top > 1)
+		return BN_MASK2;
+	else if (a->top == 1)
+		return a->d[0];
+	/* a->top == 0 */
+	return 0;
+}
+
+BIGNUM *
+bn_expand(BIGNUM *a, int bits)
+{
+	if (bits > (INT_MAX - BN_BITS2 + 1))
+		return (NULL);
+
+	if (((bits + BN_BITS2 - 1) / BN_BITS2) <= a->dmax)
+		return (a);
+
+	return bn_expand2(a, (bits + BN_BITS2 - 1) / BN_BITS2);
+}
+
+int
+BN_set_word(BIGNUM *a, BN_ULONG w)
+{
+	bn_check_top(a);
+	if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL)
+		return (0);
+	a->neg = 0;
+	a->d[0] = w;
+	a->top = (w ? 1 : 0);
+	bn_check_top(a);
+	return (1);
+}
+
+BIGNUM *
+BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
+{
+	unsigned int i, m;
+	unsigned int n;
+	BN_ULONG l;
+	BIGNUM *bn = NULL;
+
+	if (ret == NULL)
+		ret = bn = BN_new();
+	if (ret == NULL)
+		return (NULL);
+	bn_check_top(ret);
+	l = 0;
+	n = len;
+	if (n == 0) {
+		ret->top = 0;
+		return (ret);
+	}
+	i = ((n - 1) / BN_BYTES) + 1;
+	m = ((n - 1) % (BN_BYTES));
+	if (bn_wexpand(ret, (int)i) == NULL) {
+		BN_free(bn);
+		return NULL;
+	}
+	ret->top = i;
+	ret->neg = 0;
+	while (n--) {
+		l = (l << 8L) | *(s++);
+		if (m-- == 0) {
+			ret->d[--i] = l;
+			l = 0;
+			m = BN_BYTES - 1;
+		}
+	}
+	/* need to call this due to clear byte at top if avoiding
+	 * having the top bit set (-ve number) */
+	bn_correct_top(ret);
+	return (ret);
+}
+
+/* ignore negative */
+int
+BN_bn2bin(const BIGNUM *a, unsigned char *to)
+{
+	int n, i;
+	BN_ULONG l;
+
+	bn_check_top(a);
+	n = i=BN_num_bytes(a);
+	while (i--) {
+		l = a->d[i / BN_BYTES];
+		*(to++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff;
+	}
+	return (n);
+}
+
+int
+BN_ucmp(const BIGNUM *a, const BIGNUM *b)
+{
+	int i;
+	BN_ULONG t1, t2, *ap, *bp;
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	i = a->top - b->top;
+	if (i != 0)
+		return (i);
+	ap = a->d;
+	bp = b->d;
+	for (i = a->top - 1; i >= 0; i--) {
+		t1 = ap[i];
+		t2 = bp[i];
+		if (t1 != t2)
+			return ((t1 > t2) ? 1 : -1);
+	}
+	return (0);
+}
+
+int
+BN_cmp(const BIGNUM *a, const BIGNUM *b)
+{
+	int i;
+	int gt, lt;
+	BN_ULONG t1, t2;
+
+	if ((a == NULL) || (b == NULL)) {
+		if (a != NULL)
+			return (-1);
+		else if (b != NULL)
+			return (1);
+		else
+			return (0);
+	}
+
+	bn_check_top(a);
+	bn_check_top(b);
+
+	if (a->neg != b->neg) {
+		if (a->neg)
+			return (-1);
+		else
+			return (1);
+	}
+	if (a->neg == 0) {
+		gt = 1;
+		lt = -1;
+	} else {
+		gt = -1;
+		lt = 1;
+	}
+
+	if (a->top > b->top)
+		return (gt);
+	if (a->top < b->top)
+		return (lt);
+	for (i = a->top - 1; i >= 0; i--) {
+		t1 = a->d[i];
+		t2 = b->d[i];
+		if (t1 > t2)
+			return (gt);
+		if (t1 < t2)
+			return (lt);
+	}
+	return (0);
+}
+
+int
+BN_set_bit(BIGNUM *a, int n)
+{
+	int i, j, k;
+
+	if (n < 0)
+		return 0;
+
+	i = n / BN_BITS2;
+	j = n % BN_BITS2;
+	if (a->top <= i) {
+		if (bn_wexpand(a, i + 1) == NULL)
+			return (0);
+		for (k = a->top; k < i + 1; k++)
+			a->d[k] = 0;
+		a->top = i + 1;
+	}
+
+	a->d[i] |= (((BN_ULONG)1) << j);
+	bn_check_top(a);
+	return (1);
+}
+
+int
+BN_clear_bit(BIGNUM *a, int n)
+{
+	int i, j;
+
+	bn_check_top(a);
+	if (n < 0)
+		return 0;
+
+	i = n / BN_BITS2;
+	j = n % BN_BITS2;
+	if (a->top <= i)
+		return (0);
+
+	a->d[i] &= (~(((BN_ULONG)1) << j));
+	bn_correct_top(a);
+	return (1);
+}
+
+int
+BN_is_bit_set(const BIGNUM *a, int n)
+{
+	int i, j;
+
+	bn_check_top(a);
+	if (n < 0)
+		return 0;
+	i = n / BN_BITS2;
+	j = n % BN_BITS2;
+	if (a->top <= i)
+		return 0;
+	return (int)(((a->d[i]) >> j) & ((BN_ULONG)1));
+}
+
+int
+BN_mask_bits(BIGNUM *a, int n)
+{
+	int b, w;
+
+	bn_check_top(a);
+	if (n < 0)
+		return 0;
+
+	w = n / BN_BITS2;
+	b = n % BN_BITS2;
+	if (w >= a->top)
+		return 0;
+	if (b == 0)
+		a->top = w;
+	else {
+		a->top = w + 1;
+		a->d[w] &= ~(BN_MASK2 << b);
+	}
+	bn_correct_top(a);
+	return (1);
+}
+
+void
+BN_set_negative(BIGNUM *a, int b)
+{
+	if (b && !BN_is_zero(a))
+		a->neg = 1;
+	else
+		a->neg = 0;
+}
+
+int
+bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
+{
+	int i;
+	BN_ULONG aa, bb;
+
+	aa = a[n - 1];
+	bb = b[n - 1];
+	if (aa != bb)
+		return ((aa > bb) ? 1 : -1);
+	for (i = n - 2; i >= 0; i--) {
+		aa = a[i];
+		bb = b[i];
+		if (aa != bb)
+			return ((aa > bb) ? 1 : -1);
+	}
+	return (0);
+}
+
+/* Here follows a specialised variants of bn_cmp_words().  It has the
+   property of performing the operation on arrays of different sizes.
+   The sizes of those arrays is expressed through cl, which is the
+   common length ( basicall, min(len(a),len(b)) ), and dl, which is the
+   delta between the two lengths, calculated as len(a)-len(b).
+   All lengths are the number of BN_ULONGs...  */
+
+int
+bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl)
+{
+	int n, i;
+
+	n = cl - 1;
+
+	if (dl < 0) {
+		for (i = dl; i < 0; i++) {
+			if (b[n - i] != 0)
+				return -1; /* a < b */
+		}
+	}
+	if (dl > 0) {
+		for (i = dl; i > 0; i--) {
+			if (a[n + i] != 0)
+				return 1; /* a > b */
+		}
+	}
+	return bn_cmp_words(a, b, cl);
+}
+
+/*
+ * Constant-time conditional swap of a and b.
+ * a and b are swapped if condition is not 0.  The code assumes that at most one bit of condition is set.
+ * nwords is the number of words to swap.  The code assumes that at least nwords are allocated in both a and b,
+ * and that no more than nwords are used by either a or b.
+ * a and b cannot be the same number
+ */
+void
+BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
+{
+	BN_ULONG t;
+	int i;
+
+	bn_wcheck_size(a, nwords);
+	bn_wcheck_size(b, nwords);
+
+	assert(a != b);
+	assert((condition & (condition - 1)) == 0);
+	assert(sizeof(BN_ULONG) >= sizeof(int));
+
+	condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1;
+
+	t = (a->top^b->top) & condition;
+	a->top ^= t;
+	b->top ^= t;
+
+#define BN_CONSTTIME_SWAP(ind) \
+	do { \
+		t = (a->d[ind] ^ b->d[ind]) & condition; \
+		a->d[ind] ^= t; \
+		b->d[ind] ^= t; \
+	} while (0)
+
+
+	switch (nwords) {
+	default:
+		for (i = 10; i < nwords; i++)
+			BN_CONSTTIME_SWAP(i);
+		/* Fallthrough */
+	case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */
+	case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */
+	case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */
+	case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */
+	case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */
+	case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */
+	case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */
+	case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */
+	case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */
+	case 1:
+		BN_CONSTTIME_SWAP(0);
+	}
+#undef BN_CONSTTIME_SWAP
+}
diff --git a/crypto/libressl/crypto/bn/bn_mod.c b/crypto/libressl/crypto/bn/bn_mod.c
new file mode 100644
index 0000000000..442acace8b
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_mod.c
@@ -0,0 +1,305 @@
+/* $OpenBSD: bn_mod.c,v 1.8 2014/07/11 08:44:48 jsing Exp $ */
+/* Includes code written by Lenka Fibikova 
+ * for the OpenSSL project. */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include "bn_lcl.h"
+
+int
+BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
+{
+	/* like BN_mod, but returns non-negative remainder
+	 * (i.e.,  0 <= r < |d|  always holds) */
+
+	if (!(BN_mod(r, m,d, ctx)))
+		return 0;
+	if (!r->neg)
+		return 1;
+	/* now   -|d| < r < 0,  so we have to set  r := r + |d| */
+	return (d->neg ? BN_sub : BN_add)(r, r, d);
+}
+
+int
+BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+    BN_CTX *ctx)
+{
+	if (!BN_add(r, a, b))
+		return 0;
+	return BN_nnmod(r, r, m, ctx);
+}
+
+/* BN_mod_add variant that may be used if both  a  and  b  are non-negative
+ * and less than  m */
+int
+BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m)
+{
+	if (!BN_uadd(r, a, b))
+		return 0;
+	if (BN_ucmp(r, m) >= 0)
+		return BN_usub(r, r, m);
+	return 1;
+}
+
+int
+BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+    BN_CTX *ctx)
+{
+	if (!BN_sub(r, a, b))
+		return 0;
+	return BN_nnmod(r, r, m, ctx);
+}
+
+/* BN_mod_sub variant that may be used if both  a  and  b  are non-negative
+ * and less than  m */
+int
+BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m)
+{
+	if (!BN_sub(r, a, b))
+		return 0;
+	if (r->neg)
+		return BN_add(r, r, m);
+	return 1;
+}
+
+/* slow but works */
+int
+BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+    BN_CTX *ctx)
+{
+	BIGNUM *t;
+	int ret = 0;
+
+	bn_check_top(a);
+	bn_check_top(b);
+	bn_check_top(m);
+
+	BN_CTX_start(ctx);
+	if ((t = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if (a == b) {
+		if (!BN_sqr(t, a, ctx))
+			goto err;
+	} else {
+		if (!BN_mul(t, a,b, ctx))
+			goto err;
+	}
+	if (!BN_nnmod(r, t,m, ctx))
+		goto err;
+	bn_check_top(r);
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	return (ret);
+}
+
+int
+BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
+{
+	if (!BN_sqr(r, a, ctx))
+		return 0;
+	/* r->neg == 0,  thus we don't need BN_nnmod */
+	return BN_mod(r, r, m, ctx);
+}
+
+int
+BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
+{
+	if (!BN_lshift1(r, a))
+		return 0;
+	bn_check_top(r);
+	return BN_nnmod(r, r, m, ctx);
+}
+
+/* BN_mod_lshift1 variant that may be used if  a  is non-negative
+ * and less than  m */
+int
+BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m)
+{
+	if (!BN_lshift1(r, a))
+		return 0;
+	bn_check_top(r);
+	if (BN_cmp(r, m) >= 0)
+		return BN_sub(r, r, m);
+	return 1;
+}
+
+int
+BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx)
+{
+	BIGNUM *abs_m = NULL;
+	int ret;
+
+	if (!BN_nnmod(r, a, m, ctx))
+		return 0;
+
+	if (m->neg) {
+		abs_m = BN_dup(m);
+		if (abs_m == NULL)
+			return 0;
+		abs_m->neg = 0;
+	}
+
+	ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m));
+	bn_check_top(r);
+
+	BN_free(abs_m);
+	return ret;
+}
+
+/* BN_mod_lshift variant that may be used if  a  is non-negative
+ * and less than  m */
+int
+BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m)
+{
+	if (r != a) {
+		if (BN_copy(r, a) == NULL)
+			return 0;
+	}
+
+	while (n > 0) {
+		int max_shift;
+
+		/* 0 < r < m */
+		max_shift = BN_num_bits(m) - BN_num_bits(r);
+		/* max_shift >= 0 */
+
+		if (max_shift < 0) {
+			BNerr(BN_F_BN_MOD_LSHIFT_QUICK, BN_R_INPUT_NOT_REDUCED);
+			return 0;
+		}
+
+		if (max_shift > n)
+			max_shift = n;
+
+		if (max_shift) {
+			if (!BN_lshift(r, r, max_shift))
+				return 0;
+			n -= max_shift;
+		} else {
+			if (!BN_lshift1(r, r))
+				return 0;
+			--n;
+		}
+
+		/* BN_num_bits(r) <= BN_num_bits(m) */
+
+		if (BN_cmp(r, m) >= 0) {
+			if (!BN_sub(r, r, m))
+				return 0;
+		}
+	}
+	bn_check_top(r);
+
+	return 1;
+}
diff --git a/crypto/libressl/crypto/bn/bn_mont.c b/crypto/libressl/crypto/bn/bn_mont.c
new file mode 100644
index 0000000000..a2cc05cc72
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_mont.c
@@ -0,0 +1,538 @@
+/* $OpenBSD: bn_mont.c,v 1.23 2014/07/11 08:44:48 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/*
+ * Details about Montgomery multiplication algorithms can be found at
+ * http://security.ece.orst.edu/publications.html, e.g.
+ * http://security.ece.orst.edu/koc/papers/j37acmon.pdf and
+ * sections 3.8 and 4.2 in http://security.ece.orst.edu/koc/papers/r01rsasw.pdf
+ */
+
+#include 
+#include 
+
+#include "bn_lcl.h"
+
+#define MONT_WORD /* use the faster word-based algorithm */
+
+#ifdef MONT_WORD
+static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont);
+#endif
+
+int
+BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+    BN_MONT_CTX *mont, BN_CTX *ctx)
+{
+	BIGNUM *tmp;
+	int ret = 0;
+#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD)
+	int num = mont->N.top;
+
+	if (num > 1 && a->top == num && b->top == num) {
+		if (bn_wexpand(r, num) == NULL)
+			return (0);
+		if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) {
+			r->neg = a->neg^b->neg;
+			r->top = num;
+			bn_correct_top(r);
+			return (1);
+		}
+	}
+#endif
+
+	BN_CTX_start(ctx);
+	if ((tmp = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	bn_check_top(tmp);
+	if (a == b) {
+		if (!BN_sqr(tmp, a, ctx))
+			goto err;
+	} else {
+		if (!BN_mul(tmp, a,b, ctx))
+			goto err;
+	}
+	/* reduce from aRR to aR */
+#ifdef MONT_WORD
+	if (!BN_from_montgomery_word(r, tmp, mont))
+		goto err;
+#else
+	if (!BN_from_montgomery(r, tmp, mont, ctx))
+		goto err;
+#endif
+	bn_check_top(r);
+	ret = 1;
+err:
+	BN_CTX_end(ctx);
+	return (ret);
+}
+
+#ifdef MONT_WORD
+static int
+BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
+{
+	BIGNUM *n;
+	BN_ULONG *ap, *np, *rp, n0, v, carry;
+	int nl, max, i;
+
+	n = &(mont->N);
+	nl = n->top;
+	if (nl == 0) {
+		ret->top = 0;
+		return (1);
+	}
+
+	max = (2 * nl); /* carry is stored separately */
+	if (bn_wexpand(r, max) == NULL)
+		return (0);
+
+	r->neg ^= n->neg;
+	np = n->d;
+	rp = r->d;
+
+	/* clear the top words of T */
+#if 1
+	for (i=r->top; itop]), 0, (max - r->top) * sizeof(BN_ULONG));
+#endif
+
+	r->top = max;
+	n0 = mont->n0[0];
+
+#ifdef BN_COUNT
+	fprintf(stderr, "word BN_from_montgomery_word %d * %d\n", nl, nl);
+#endif
+	for (carry = 0, i = 0; i < nl; i++, rp++) {
+		v = bn_mul_add_words(rp, np, nl, (rp[0] * n0) & BN_MASK2);
+		v = (v + carry + rp[nl]) & BN_MASK2;
+		carry |= (v != rp[nl]);
+		carry &= (v <= rp[nl]);
+		rp[nl] = v;
+	}
+
+	if (bn_wexpand(ret, nl) == NULL)
+		return (0);
+	ret->top = nl;
+	ret->neg = r->neg;
+
+	rp = ret->d;
+	ap = &(r->d[nl]);
+
+#define BRANCH_FREE 1
+#if BRANCH_FREE
+	{
+		BN_ULONG *nrp;
+		size_t m;
+
+		v = bn_sub_words(rp, ap, np, nl) - carry;
+		/* if subtraction result is real, then
+		 * trick unconditional memcpy below to perform in-place
+		 * "refresh" instead of actual copy. */
+		m = (0 - (size_t)v);
+		nrp = (BN_ULONG *)(((uintptr_t)rp & ~m)|((uintptr_t)ap & m));
+
+		for (i = 0, nl -= 4; i < nl; i += 4) {
+			BN_ULONG t1, t2, t3, t4;
+
+			t1 = nrp[i + 0];
+			t2 = nrp[i + 1];
+			t3 = nrp[i + 2];
+			ap[i + 0] = 0;
+			t4 = nrp[i + 3];
+			ap[i + 1] = 0;
+			rp[i + 0] = t1;
+			ap[i + 2] = 0;
+			rp[i + 1] = t2;
+			ap[i + 3] = 0;
+			rp[i + 2] = t3;
+			rp[i + 3] = t4;
+		}
+		for (nl += 4; i < nl; i++)
+			rp[i] = nrp[i], ap[i] = 0;
+	}
+#else
+	if (bn_sub_words (rp, ap, np, nl) - carry)
+		memcpy(rp, ap, nl*sizeof(BN_ULONG));
+#endif
+	bn_correct_top(r);
+	bn_correct_top(ret);
+	bn_check_top(ret);
+
+	return (1);
+}
+#endif	/* MONT_WORD */
+
+int
+BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx)
+{
+	int retn = 0;
+#ifdef MONT_WORD
+	BIGNUM *t;
+
+	BN_CTX_start(ctx);
+	if ((t = BN_CTX_get(ctx)) && BN_copy(t, a))
+		retn = BN_from_montgomery_word(ret, t, mont);
+	BN_CTX_end(ctx);
+#else /* !MONT_WORD */
+	BIGNUM *t1, *t2;
+
+	BN_CTX_start(ctx);
+	if ((t1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((t2 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!BN_copy(t1, a))
+		goto err;
+	BN_mask_bits(t1, mont->ri);
+
+	if (!BN_mul(t2, t1, &mont->Ni, ctx))
+		goto err;
+	BN_mask_bits(t2, mont->ri);
+
+	if (!BN_mul(t1, t2, &mont->N, ctx))
+		goto err;
+	if (!BN_add(t2, a, t1))
+		goto err;
+	if (!BN_rshift(ret, t2, mont->ri))
+		goto err;
+
+	if (BN_ucmp(ret, &(mont->N)) >= 0) {
+		if (!BN_usub(ret, ret, &(mont->N)))
+			goto err;
+	}
+	retn = 1;
+	bn_check_top(ret);
+
+err:
+	BN_CTX_end(ctx);
+#endif /* MONT_WORD */
+	return (retn);
+}
+
+BN_MONT_CTX *
+BN_MONT_CTX_new(void)
+{
+	BN_MONT_CTX *ret;
+
+	if ((ret = malloc(sizeof(BN_MONT_CTX))) == NULL)
+		return (NULL);
+
+	BN_MONT_CTX_init(ret);
+	ret->flags = BN_FLG_MALLOCED;
+	return (ret);
+}
+
+void
+BN_MONT_CTX_init(BN_MONT_CTX *ctx)
+{
+	ctx->ri = 0;
+	BN_init(&(ctx->RR));
+	BN_init(&(ctx->N));
+	BN_init(&(ctx->Ni));
+	ctx->n0[0] = ctx->n0[1] = 0;
+	ctx->flags = 0;
+}
+
+void
+BN_MONT_CTX_free(BN_MONT_CTX *mont)
+{
+	if (mont == NULL)
+		return;
+
+	BN_clear_free(&(mont->RR));
+	BN_clear_free(&(mont->N));
+	BN_clear_free(&(mont->Ni));
+	if (mont->flags & BN_FLG_MALLOCED)
+		free(mont);
+}
+
+int
+BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
+{
+	int ret = 0;
+	BIGNUM *Ri, *R;
+
+	BN_CTX_start(ctx);
+	if ((Ri = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	R = &(mont->RR);				/* grab RR as a temp */
+	if (!BN_copy(&(mont->N), mod))
+		 goto err;				/* Set N */
+	mont->N.neg = 0;
+
+#ifdef MONT_WORD
+	{
+		BIGNUM tmod;
+		BN_ULONG buf[2];
+
+		BN_init(&tmod);
+		tmod.d = buf;
+		tmod.dmax = 2;
+		tmod.neg = 0;
+
+		mont->ri = (BN_num_bits(mod) +
+		    (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2;
+
+#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)
+		/* Only certain BN_BITS2<=32 platforms actually make use of
+		 * n0[1], and we could use the #else case (with a shorter R
+		 * value) for the others.  However, currently only the assembler
+		 * files do know which is which. */
+
+		BN_zero(R);
+		if (!(BN_set_bit(R, 2 * BN_BITS2)))
+			goto err;
+
+		tmod.top = 0;
+		if ((buf[0] = mod->d[0]))
+			tmod.top = 1;
+		if ((buf[1] = mod->top > 1 ? mod->d[1] : 0))
+			tmod.top = 2;
+
+		if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL)
+			goto err;
+		if (!BN_lshift(Ri, Ri, 2 * BN_BITS2))
+			goto err; /* R*Ri */
+		if (!BN_is_zero(Ri)) {
+			if (!BN_sub_word(Ri, 1))
+				goto err;
+		}
+		else /* if N mod word size == 1 */
+		{
+			if (bn_expand(Ri, (int)sizeof(BN_ULONG) * 2) == NULL)
+				goto err;
+			/* Ri-- (mod double word size) */
+			Ri->neg = 0;
+			Ri->d[0] = BN_MASK2;
+			Ri->d[1] = BN_MASK2;
+			Ri->top = 2;
+		}
+		if (!BN_div(Ri, NULL, Ri, &tmod, ctx))
+			goto err;
+		/* Ni = (R*Ri-1)/N,
+		 * keep only couple of least significant words: */
+		mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
+		mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0;
+#else
+		BN_zero(R);
+		if (!(BN_set_bit(R, BN_BITS2)))
+			goto err;	/* R */
+
+		buf[0] = mod->d[0]; /* tmod = N mod word size */
+		buf[1] = 0;
+		tmod.top = buf[0] != 0 ? 1 : 0;
+		/* Ri = R^-1 mod N*/
+		if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL)
+			goto err;
+		if (!BN_lshift(Ri, Ri, BN_BITS2))
+			goto err; /* R*Ri */
+		if (!BN_is_zero(Ri)) {
+			if (!BN_sub_word(Ri, 1))
+				goto err;
+		}
+		else /* if N mod word size == 1 */
+		{
+			if (!BN_set_word(Ri, BN_MASK2))
+				goto err;  /* Ri-- (mod word size) */
+		}
+		if (!BN_div(Ri, NULL, Ri, &tmod, ctx))
+			goto err;
+		/* Ni = (R*Ri-1)/N,
+		 * keep only least significant word: */
+		mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
+		mont->n0[1] = 0;
+#endif
+	}
+#else /* !MONT_WORD */
+	{ /* bignum version */
+		mont->ri = BN_num_bits(&mont->N);
+		BN_zero(R);
+		if (!BN_set_bit(R, mont->ri))
+			goto err;  /* R = 2^ri */
+		/* Ri = R^-1 mod N*/
+		if ((BN_mod_inverse(Ri, R, &mont->N, ctx)) == NULL)
+			goto err;
+		if (!BN_lshift(Ri, Ri, mont->ri))
+			goto err; /* R*Ri */
+		if (!BN_sub_word(Ri, 1))
+			goto err;
+		/* Ni = (R*Ri-1) / N */
+		if (!BN_div(&(mont->Ni), NULL, Ri, &mont->N, ctx))
+			goto err;
+	}
+#endif
+
+	/* setup RR for conversions */
+	BN_zero(&(mont->RR));
+	if (!BN_set_bit(&(mont->RR), mont->ri*2))
+		goto err;
+	if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx))
+		goto err;
+
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	return ret;
+}
+
+BN_MONT_CTX *
+BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from)
+{
+	if (to == from)
+		return (to);
+
+	if (!BN_copy(&(to->RR), &(from->RR)))
+		return NULL;
+	if (!BN_copy(&(to->N), &(from->N)))
+		return NULL;
+	if (!BN_copy(&(to->Ni), &(from->Ni)))
+		return NULL;
+	to->ri = from->ri;
+	to->n0[0] = from->n0[0];
+	to->n0[1] = from->n0[1];
+	return (to);
+}
+
+BN_MONT_CTX *
+BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, const BIGNUM *mod,
+    BN_CTX *ctx)
+{
+	int got_write_lock = 0;
+	BN_MONT_CTX *ret;
+
+	CRYPTO_r_lock(lock);
+	if (!*pmont) {
+		CRYPTO_r_unlock(lock);
+		CRYPTO_w_lock(lock);
+		got_write_lock = 1;
+
+		if (!*pmont) {
+			ret = BN_MONT_CTX_new();
+			if (ret && !BN_MONT_CTX_set(ret, mod, ctx))
+				BN_MONT_CTX_free(ret);
+			else
+				*pmont = ret;
+		}
+	}
+
+	ret = *pmont;
+
+	if (got_write_lock)
+		CRYPTO_w_unlock(lock);
+	else
+		CRYPTO_r_unlock(lock);
+
+	return ret;
+}
diff --git a/crypto/libressl/crypto/bn/bn_mpi.c b/crypto/libressl/crypto/bn/bn_mpi.c
new file mode 100644
index 0000000000..ce1ef003b8
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_mpi.c
@@ -0,0 +1,132 @@
+/* $OpenBSD: bn_mpi.c,v 1.6 2014/06/12 15:49:28 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include "bn_lcl.h"
+
+int
+BN_bn2mpi(const BIGNUM *a, unsigned char *d)
+{
+	int bits;
+	int num = 0;
+	int ext = 0;
+	long l;
+
+	bits = BN_num_bits(a);
+	num = (bits + 7) / 8;
+	if (bits > 0) {
+		ext = ((bits & 0x07) == 0);
+	}
+	if (d == NULL)
+		return (num + 4 + ext);
+
+	l = num + ext;
+	d[0] = (unsigned char)(l >> 24) & 0xff;
+	d[1] = (unsigned char)(l >> 16) & 0xff;
+	d[2] = (unsigned char)(l >> 8) & 0xff;
+	d[3] = (unsigned char)(l) & 0xff;
+	if (ext)
+		d[4] = 0;
+	num = BN_bn2bin(a, &(d[4 + ext]));
+	if (a->neg)
+		d[4] |= 0x80;
+	return (num + 4 + ext);
+}
+
+BIGNUM *
+BN_mpi2bn(const unsigned char *d, int n, BIGNUM *a)
+{
+	long len;
+	int neg = 0;
+
+	if (n < 4) {
+		BNerr(BN_F_BN_MPI2BN, BN_R_INVALID_LENGTH);
+		return (NULL);
+	}
+	len = ((long)d[0] << 24) | ((long)d[1] << 16) | ((int)d[2] << 8) |
+	    (int)d[3];
+	if ((len + 4) != n) {
+		BNerr(BN_F_BN_MPI2BN, BN_R_ENCODING_ERROR);
+		return (NULL);
+	}
+
+	if (a == NULL)
+		a = BN_new();
+	if (a == NULL)
+		return (NULL);
+
+	if (len == 0) {
+		a->neg = 0;
+		a->top = 0;
+		return (a);
+	}
+	d += 4;
+	if ((*d) & 0x80)
+		neg = 1;
+	if (BN_bin2bn(d, (int)len, a) == NULL)
+		return (NULL);
+	a->neg = neg;
+	if (neg) {
+		BN_clear_bit(a, BN_num_bits(a) - 1);
+	}
+	bn_check_top(a);
+	return (a);
+}
diff --git a/crypto/libressl/crypto/bn/bn_mul.c b/crypto/libressl/crypto/bn/bn_mul.c
new file mode 100644
index 0000000000..17a0376b38
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_mul.c
@@ -0,0 +1,1171 @@
+/* $OpenBSD: bn_mul.c,v 1.19 2014/07/11 08:44:48 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef BN_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include "bn_lcl.h"
+
+#if defined(OPENSSL_NO_ASM) || !defined(OPENSSL_BN_ASM_PART_WORDS)
+/* Here follows specialised variants of bn_add_words() and
+   bn_sub_words().  They have the property performing operations on
+   arrays of different sizes.  The sizes of those arrays is expressed through
+   cl, which is the common length ( basicall, min(len(a),len(b)) ), and dl,
+   which is the delta between the two lengths, calculated as len(a)-len(b).
+   All lengths are the number of BN_ULONGs...  For the operations that require
+   a result array as parameter, it must have the length cl+abs(dl).
+   These functions should probably end up in bn_asm.c as soon as there are
+   assembler counterparts for the systems that use assembler files.  */
+
+BN_ULONG
+bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int cl,
+    int dl)
+{
+	BN_ULONG c, t;
+
+	assert(cl >= 0);
+	c = bn_sub_words(r, a, b, cl);
+
+	if (dl == 0)
+		return c;
+
+	r += cl;
+	a += cl;
+	b += cl;
+
+	if (dl < 0) {
+#ifdef BN_COUNT
+		fprintf(stderr,
+		    "  bn_sub_part_words %d + %d (dl < 0, c = %d)\n",
+		    cl, dl, c);
+#endif
+		for (;;) {
+			t = b[0];
+			r[0] = (0 - t - c) & BN_MASK2;
+			if (t != 0)
+				c = 1;
+			if (++dl >= 0)
+				break;
+
+			t = b[1];
+			r[1] = (0 - t - c) & BN_MASK2;
+			if (t != 0)
+				c = 1;
+			if (++dl >= 0)
+				break;
+
+			t = b[2];
+			r[2] = (0 - t - c) & BN_MASK2;
+			if (t != 0)
+				c = 1;
+			if (++dl >= 0)
+				break;
+
+			t = b[3];
+			r[3] = (0 - t - c) & BN_MASK2;
+			if (t != 0)
+				c = 1;
+			if (++dl >= 0)
+				break;
+
+			b += 4;
+			r += 4;
+		}
+	} else {
+		int save_dl = dl;
+#ifdef BN_COUNT
+		fprintf(stderr,
+		    "  bn_sub_part_words %d + %d (dl > 0, c = %d)\n",
+		    cl, dl, c);
+#endif
+		while (c) {
+			t = a[0];
+			r[0] = (t - c) & BN_MASK2;
+			if (t != 0)
+				c = 0;
+			if (--dl <= 0)
+				break;
+
+			t = a[1];
+			r[1] = (t - c) & BN_MASK2;
+			if (t != 0)
+				c = 0;
+			if (--dl <= 0)
+				break;
+
+			t = a[2];
+			r[2] = (t - c) & BN_MASK2;
+			if (t != 0)
+				c = 0;
+			if (--dl <= 0)
+				break;
+
+			t = a[3];
+			r[3] = (t - c) & BN_MASK2;
+			if (t != 0)
+				c = 0;
+			if (--dl <= 0)
+				break;
+
+			save_dl = dl;
+			a += 4;
+			r += 4;
+		}
+		if (dl > 0) {
+#ifdef BN_COUNT
+			fprintf(stderr,
+			    "  bn_sub_part_words %d + %d (dl > 0, c == 0)\n",
+			    cl, dl);
+#endif
+			if (save_dl > dl) {
+				switch (save_dl - dl) {
+				case 1:
+					r[1] = a[1];
+					if (--dl <= 0)
+						break;
+				case 2:
+					r[2] = a[2];
+					if (--dl <= 0)
+						break;
+				case 3:
+					r[3] = a[3];
+					if (--dl <= 0)
+						break;
+				}
+				a += 4;
+				r += 4;
+			}
+		}
+		if (dl > 0) {
+#ifdef BN_COUNT
+			fprintf(stderr,
+			    "  bn_sub_part_words %d + %d (dl > 0, copy)\n",
+			    cl, dl);
+#endif
+			for (;;) {
+				r[0] = a[0];
+				if (--dl <= 0)
+					break;
+				r[1] = a[1];
+				if (--dl <= 0)
+					break;
+				r[2] = a[2];
+				if (--dl <= 0)
+					break;
+				r[3] = a[3];
+				if (--dl <= 0)
+					break;
+
+				a += 4;
+				r += 4;
+			}
+		}
+	}
+	return c;
+}
+#endif
+
+BN_ULONG
+bn_add_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int cl,
+    int dl)
+{
+	BN_ULONG c, l, t;
+
+	assert(cl >= 0);
+	c = bn_add_words(r, a, b, cl);
+
+	if (dl == 0)
+		return c;
+
+	r += cl;
+	a += cl;
+	b += cl;
+
+	if (dl < 0) {
+		int save_dl = dl;
+#ifdef BN_COUNT
+		fprintf(stderr,
+		    "  bn_add_part_words %d + %d (dl < 0, c = %d)\n",
+		    cl, dl, c);
+#endif
+		while (c) {
+			l = (c + b[0]) & BN_MASK2;
+			c = (l < c);
+			r[0] = l;
+			if (++dl >= 0)
+				break;
+
+			l = (c + b[1]) & BN_MASK2;
+			c = (l < c);
+			r[1] = l;
+			if (++dl >= 0)
+				break;
+
+			l = (c + b[2]) & BN_MASK2;
+			c = (l < c);
+			r[2] = l;
+			if (++dl >= 0)
+				break;
+
+			l = (c + b[3]) & BN_MASK2;
+			c = (l < c);
+			r[3] = l;
+			if (++dl >= 0)
+				break;
+
+			save_dl = dl;
+			b += 4;
+			r += 4;
+		}
+		if (dl < 0) {
+#ifdef BN_COUNT
+			fprintf(stderr,
+			    "  bn_add_part_words %d + %d (dl < 0, c == 0)\n",
+			    cl, dl);
+#endif
+			if (save_dl < dl) {
+				switch (dl - save_dl) {
+				case 1:
+					r[1] = b[1];
+					if (++dl >= 0)
+						break;
+				case 2:
+					r[2] = b[2];
+					if (++dl >= 0)
+						break;
+				case 3:
+					r[3] = b[3];
+					if (++dl >= 0)
+						break;
+				}
+				b += 4;
+				r += 4;
+			}
+		}
+		if (dl < 0) {
+#ifdef BN_COUNT
+			fprintf(stderr,
+			    "  bn_add_part_words %d + %d (dl < 0, copy)\n",
+			    cl, dl);
+#endif
+			for (;;) {
+				r[0] = b[0];
+				if (++dl >= 0)
+					break;
+				r[1] = b[1];
+				if (++dl >= 0)
+					break;
+				r[2] = b[2];
+				if (++dl >= 0)
+					break;
+				r[3] = b[3];
+				if (++dl >= 0)
+					break;
+
+				b += 4;
+				r += 4;
+			}
+		}
+	} else {
+		int save_dl = dl;
+#ifdef BN_COUNT
+		fprintf(stderr,
+		    "  bn_add_part_words %d + %d (dl > 0)\n", cl, dl);
+#endif
+		while (c) {
+			t = (a[0] + c) & BN_MASK2;
+			c = (t < c);
+			r[0] = t;
+			if (--dl <= 0)
+				break;
+
+			t = (a[1] + c) & BN_MASK2;
+			c = (t < c);
+			r[1] = t;
+			if (--dl <= 0)
+				break;
+
+			t = (a[2] + c) & BN_MASK2;
+			c = (t < c);
+			r[2] = t;
+			if (--dl <= 0)
+				break;
+
+			t = (a[3] + c) & BN_MASK2;
+			c = (t < c);
+			r[3] = t;
+			if (--dl <= 0)
+				break;
+
+			save_dl = dl;
+			a += 4;
+			r += 4;
+		}
+#ifdef BN_COUNT
+		fprintf(stderr,
+		    "  bn_add_part_words %d + %d (dl > 0, c == 0)\n", cl, dl);
+#endif
+		if (dl > 0) {
+			if (save_dl > dl) {
+				switch (save_dl - dl) {
+				case 1:
+					r[1] = a[1];
+					if (--dl <= 0)
+						break;
+				case 2:
+					r[2] = a[2];
+					if (--dl <= 0)
+						break;
+				case 3:
+					r[3] = a[3];
+					if (--dl <= 0)
+						break;
+				}
+				a += 4;
+				r += 4;
+			}
+		}
+		if (dl > 0) {
+#ifdef BN_COUNT
+			fprintf(stderr,
+			    "  bn_add_part_words %d + %d (dl > 0, copy)\n",
+			    cl, dl);
+#endif
+			for (;;) {
+				r[0] = a[0];
+				if (--dl <= 0)
+					break;
+				r[1] = a[1];
+				if (--dl <= 0)
+					break;
+				r[2] = a[2];
+				if (--dl <= 0)
+					break;
+				r[3] = a[3];
+				if (--dl <= 0)
+					break;
+
+				a += 4;
+				r += 4;
+			}
+		}
+	}
+	return c;
+}
+
+#ifdef BN_RECURSION
+/* Karatsuba recursive multiplication algorithm
+ * (cf. Knuth, The Art of Computer Programming, Vol. 2) */
+
+/* r is 2*n2 words in size,
+ * a and b are both n2 words in size.
+ * n2 must be a power of 2.
+ * We multiply and return the result.
+ * t must be 2*n2 words in size
+ * We calculate
+ * a[0]*b[0]
+ * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
+ * a[1]*b[1]
+ */
+/* dnX may not be positive, but n2/2+dnX has to be */
+void
+bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, int dna,
+    int dnb, BN_ULONG *t)
+{
+	int n = n2 / 2, c1, c2;
+	int tna = n + dna, tnb = n + dnb;
+	unsigned int neg, zero;
+	BN_ULONG ln, lo, *p;
+
+# ifdef BN_COUNT
+	fprintf(stderr, " bn_mul_recursive %d%+d * %d%+d\n",n2,dna,n2,dnb);
+# endif
+# ifdef BN_MUL_COMBA
+#  if 0
+	if (n2 == 4) {
+		bn_mul_comba4(r, a, b);
+		return;
+	}
+#  endif
+	/* Only call bn_mul_comba 8 if n2 == 8 and the
+	 * two arrays are complete [steve]
+	 */
+	if (n2 == 8 && dna == 0 && dnb == 0) {
+		bn_mul_comba8(r, a, b);
+		return;
+	}
+# endif /* BN_MUL_COMBA */
+	/* Else do normal multiply */
+	if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) {
+		bn_mul_normal(r, a, n2 + dna, b, n2 + dnb);
+		if ((dna + dnb) < 0)
+			memset(&r[2*n2 + dna + dnb], 0,
+			    sizeof(BN_ULONG) * -(dna + dnb));
+		return;
+	}
+	/* r=(a[0]-a[1])*(b[1]-b[0]) */
+	c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);
+	c2 = bn_cmp_part_words(&(b[n]), b,tnb, tnb - n);
+	zero = neg = 0;
+	switch (c1 * 3 + c2) {
+	case -4:
+		bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
+		bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
+		break;
+	case -3:
+		zero = 1;
+		break;
+	case -2:
+		bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
+		bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */
+		neg = 1;
+		break;
+	case -1:
+	case 0:
+	case 1:
+		zero = 1;
+		break;
+	case 2:
+		bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */
+		bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
+		neg = 1;
+		break;
+	case 3:
+		zero = 1;
+		break;
+	case 4:
+		bn_sub_part_words(t, a, &(a[n]), tna, n - tna);
+		bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n);
+		break;
+	}
+
+# ifdef BN_MUL_COMBA
+	if (n == 4 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba4 could take
+					       extra args to do this well */
+	{
+		if (!zero)
+			bn_mul_comba4(&(t[n2]), t, &(t[n]));
+		else
+			memset(&(t[n2]), 0, 8 * sizeof(BN_ULONG));
+
+		bn_mul_comba4(r, a, b);
+		bn_mul_comba4(&(r[n2]), &(a[n]), &(b[n]));
+	} else if (n == 8 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba8 could
+						    take extra args to do this
+						    well */
+	{
+		if (!zero)
+			bn_mul_comba8(&(t[n2]), t, &(t[n]));
+		else
+			memset(&(t[n2]), 0, 16 * sizeof(BN_ULONG));
+
+		bn_mul_comba8(r, a, b);
+		bn_mul_comba8(&(r[n2]), &(a[n]), &(b[n]));
+	} else
+# endif /* BN_MUL_COMBA */
+	{
+		p = &(t[n2 * 2]);
+		if (!zero)
+			bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);
+		else
+			memset(&(t[n2]), 0, n2 * sizeof(BN_ULONG));
+		bn_mul_recursive(r, a, b, n, 0, 0, p);
+		bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]), n, dna, dnb, p);
+	}
+
+	/* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
+	 * r[10] holds (a[0]*b[0])
+	 * r[32] holds (b[1]*b[1])
+	 */
+
+	c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
+
+	if (neg) /* if t[32] is negative */
+	{
+		c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
+	} else {
+		/* Might have a carry */
+		c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));
+	}
+
+	/* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
+	 * r[10] holds (a[0]*b[0])
+	 * r[32] holds (b[1]*b[1])
+	 * c1 holds the carry bits
+	 */
+	c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
+	if (c1) {
+		p = &(r[n + n2]);
+		lo= *p;
+		ln = (lo + c1) & BN_MASK2;
+		*p = ln;
+
+		/* The overflow will stop before we over write
+		 * words we should not overwrite */
+		if (ln < (BN_ULONG)c1) {
+			do {
+				p++;
+				lo= *p;
+				ln = (lo + 1) & BN_MASK2;
+				*p = ln;
+			} while (ln == 0);
+		}
+	}
+}
+
+/* n+tn is the word length
+ * t needs to be n*4 is size, as does r */
+/* tnX may not be negative but less than n */
+void
+bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n, int tna,
+    int tnb, BN_ULONG *t)
+{
+	int i, j, n2 = n * 2;
+	int c1, c2, neg;
+	BN_ULONG ln, lo, *p;
+
+# ifdef BN_COUNT
+	fprintf(stderr, " bn_mul_part_recursive (%d%+d) * (%d%+d)\n",
+	    n, tna, n, tnb);
+# endif
+	if (n < 8) {
+		bn_mul_normal(r, a, n + tna, b, n + tnb);
+		return;
+	}
+
+	/* r=(a[0]-a[1])*(b[1]-b[0]) */
+	c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);
+	c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n);
+	neg = 0;
+	switch (c1 * 3 + c2) {
+	case -4:
+		bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
+		bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
+		break;
+	case -3:
+		/* break; */
+	case -2:
+		bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
+		bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */
+		neg = 1;
+		break;
+	case -1:
+	case 0:
+	case 1:
+		/* break; */
+	case 2:
+		bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */
+		bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
+		neg = 1;
+		break;
+	case 3:
+		/* break; */
+	case 4:
+		bn_sub_part_words(t, a, &(a[n]), tna, n - tna);
+		bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n);
+		break;
+	}
+		/* The zero case isn't yet implemented here. The speedup
+		   would probably be negligible. */
+# if 0
+	if (n == 4) {
+		bn_mul_comba4(&(t[n2]), t, &(t[n]));
+		bn_mul_comba4(r, a, b);
+		bn_mul_normal(&(r[n2]), &(a[n]), tn, &(b[n]), tn);
+		memset(&(r[n2 + tn * 2]), 0, sizeof(BN_ULONG) * (n2 - tn * 2));
+	} else
+# endif
+		if (n == 8) {
+		bn_mul_comba8(&(t[n2]), t, &(t[n]));
+		bn_mul_comba8(r, a, b);
+		bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb);
+		memset(&(r[n2 + tna + tnb]), 0,
+		    sizeof(BN_ULONG) * (n2 - tna - tnb));
+	} else {
+		p = &(t[n2*2]);
+		bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);
+		bn_mul_recursive(r, a, b, n, 0, 0, p);
+		i = n / 2;
+		/* If there is only a bottom half to the number,
+		 * just do it */
+		if (tna > tnb)
+			j = tna - i;
+		else
+			j = tnb - i;
+		if (j == 0) {
+			bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]),
+			    i, tna - i, tnb - i, p);
+			memset(&(r[n2 + i * 2]), 0,
+			    sizeof(BN_ULONG) * (n2 - i * 2));
+		}
+		else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */
+		{
+			bn_mul_part_recursive(&(r[n2]), &(a[n]), &(b[n]),
+			    i, tna - i, tnb - i, p);
+			memset(&(r[n2 + tna + tnb]), 0,
+			    sizeof(BN_ULONG) * (n2 - tna - tnb));
+		}
+		else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
+		{
+			memset(&(r[n2]), 0, sizeof(BN_ULONG) * n2);
+			if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL &&
+			    tnb < BN_MUL_RECURSIVE_SIZE_NORMAL) {
+				bn_mul_normal(&(r[n2]), &(a[n]), tna,
+				    &(b[n]), tnb);
+			} else {
+				for (;;) {
+					i /= 2;
+					/* these simplified conditions work
+					 * exclusively because difference
+					 * between tna and tnb is 1 or 0 */
+					if (i < tna || i < tnb) {
+						bn_mul_part_recursive(&(r[n2]),
+						    &(a[n]), &(b[n]), i,
+						    tna - i, tnb - i, p);
+						break;
+					} else if (i == tna || i == tnb) {
+						bn_mul_recursive(&(r[n2]),
+						    &(a[n]), &(b[n]), i,
+						    tna - i, tnb - i, p);
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	/* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
+	 * r[10] holds (a[0]*b[0])
+	 * r[32] holds (b[1]*b[1])
+	 */
+
+	c1 = (int)(bn_add_words(t, r,&(r[n2]), n2));
+
+	if (neg) /* if t[32] is negative */
+	{
+		c1 -= (int)(bn_sub_words(&(t[n2]), t,&(t[n2]), n2));
+	} else {
+		/* Might have a carry */
+		c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));
+	}
+
+	/* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
+	 * r[10] holds (a[0]*b[0])
+	 * r[32] holds (b[1]*b[1])
+	 * c1 holds the carry bits
+	 */
+	c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
+	if (c1) {
+		p = &(r[n + n2]);
+		lo= *p;
+		ln = (lo + c1)&BN_MASK2;
+		*p = ln;
+
+		/* The overflow will stop before we over write
+		 * words we should not overwrite */
+		if (ln < (BN_ULONG)c1) {
+			do {
+				p++;
+				lo= *p;
+				ln = (lo + 1) & BN_MASK2;
+				*p = ln;
+			} while (ln == 0);
+		}
+	}
+}
+
+/* a and b must be the same size, which is n2.
+ * r needs to be n2 words and t needs to be n2*2
+ */
+void
+bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, BN_ULONG *t)
+{
+	int n = n2 / 2;
+
+# ifdef BN_COUNT
+	fprintf(stderr, " bn_mul_low_recursive %d * %d\n",n2,n2);
+# endif
+
+	bn_mul_recursive(r, a, b, n, 0, 0, &(t[0]));
+	if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL) {
+		bn_mul_low_recursive(&(t[0]), &(a[0]), &(b[n]), n, &(t[n2]));
+		bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
+		bn_mul_low_recursive(&(t[0]), &(a[n]), &(b[0]), n, &(t[n2]));
+		bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
+	} else {
+		bn_mul_low_normal(&(t[0]), &(a[0]), &(b[n]), n);
+		bn_mul_low_normal(&(t[n]), &(a[n]), &(b[0]), n);
+		bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
+		bn_add_words(&(r[n]), &(r[n]), &(t[n]), n);
+	}
+}
+
+/* a and b must be the same size, which is n2.
+ * r needs to be n2 words and t needs to be n2*2
+ * l is the low words of the output.
+ * t needs to be n2*3
+ */
+void
+bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
+    BN_ULONG *t)
+{
+	int i, n;
+	int c1, c2;
+	int neg, oneg, zero;
+	BN_ULONG ll, lc, *lp, *mp;
+
+# ifdef BN_COUNT
+	fprintf(stderr, " bn_mul_high %d * %d\n",n2,n2);
+# endif
+	n = n2 / 2;
+
+	/* Calculate (al-ah)*(bh-bl) */
+	neg = zero = 0;
+	c1 = bn_cmp_words(&(a[0]), &(a[n]), n);
+	c2 = bn_cmp_words(&(b[n]), &(b[0]), n);
+	switch (c1 * 3 + c2) {
+	case -4:
+		bn_sub_words(&(r[0]), &(a[n]), &(a[0]), n);
+		bn_sub_words(&(r[n]), &(b[0]), &(b[n]), n);
+		break;
+	case -3:
+		zero = 1;
+		break;
+	case -2:
+		bn_sub_words(&(r[0]), &(a[n]), &(a[0]), n);
+		bn_sub_words(&(r[n]), &(b[n]), &(b[0]), n);
+		neg = 1;
+		break;
+	case -1:
+	case 0:
+	case 1:
+		zero = 1;
+		break;
+	case 2:
+		bn_sub_words(&(r[0]), &(a[0]), &(a[n]), n);
+		bn_sub_words(&(r[n]), &(b[0]), &(b[n]), n);
+		neg = 1;
+		break;
+	case 3:
+		zero = 1;
+		break;
+	case 4:
+		bn_sub_words(&(r[0]), &(a[0]), &(a[n]), n);
+		bn_sub_words(&(r[n]), &(b[n]), &(b[0]), n);
+		break;
+	}
+
+	oneg = neg;
+	/* t[10] = (a[0]-a[1])*(b[1]-b[0]) */
+	/* r[10] = (a[1]*b[1]) */
+# ifdef BN_MUL_COMBA
+	if (n == 8) {
+		bn_mul_comba8(&(t[0]), &(r[0]), &(r[n]));
+		bn_mul_comba8(r, &(a[n]), &(b[n]));
+	} else
+# endif
+	{
+		bn_mul_recursive(&(t[0]), &(r[0]), &(r[n]), n, 0, 0, &(t[n2]));
+		bn_mul_recursive(r, &(a[n]), &(b[n]), n, 0, 0, &(t[n2]));
+	}
+
+	/* s0 == low(al*bl)
+	 * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl)
+	 * We know s0 and s1 so the only unknown is high(al*bl)
+	 * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl))
+	 * high(al*bl) == s1 - (r[0]+l[0]+t[0])
+	 */
+	if (l != NULL) {
+		lp = &(t[n2 + n]);
+		c1 = (int)(bn_add_words(lp, &(r[0]), &(l[0]), n));
+	} else {
+		c1 = 0;
+		lp = &(r[0]);
+	}
+
+	if (neg)
+		neg = (int)(bn_sub_words(&(t[n2]), lp, &(t[0]), n));
+	else {
+		bn_add_words(&(t[n2]), lp, &(t[0]), n);
+		neg = 0;
+	}
+
+	if (l != NULL) {
+		bn_sub_words(&(t[n2 + n]), &(l[n]), &(t[n2]), n);
+	} else {
+		lp = &(t[n2 + n]);
+		mp = &(t[n2]);
+		for (i = 0; i < n; i++)
+			lp[i] = ((~mp[i]) + 1) & BN_MASK2;
+	}
+
+	/* s[0] = low(al*bl)
+	 * t[3] = high(al*bl)
+	 * t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign
+	 * r[10] = (a[1]*b[1])
+	 */
+	/* R[10] = al*bl
+	 * R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0])
+	 * R[32] = ah*bh
+	 */
+	/* R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow)
+	 * R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow)
+	 * R[3]=r[1]+(carry/borrow)
+	 */
+	if (l != NULL) {
+		lp = &(t[n2]);
+		c1 = (int)(bn_add_words(lp, &(t[n2 + n]), &(l[0]), n));
+	} else {
+		lp = &(t[n2 + n]);
+		c1 = 0;
+	}
+	c1 += (int)(bn_add_words(&(t[n2]), lp, &(r[0]), n));
+	if (oneg)
+		c1 -= (int)(bn_sub_words(&(t[n2]), &(t[n2]), &(t[0]), n));
+	else
+		c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), &(t[0]), n));
+
+	c2 = (int)(bn_add_words(&(r[0]), &(r[0]), &(t[n2 + n]), n));
+	c2 += (int)(bn_add_words(&(r[0]), &(r[0]), &(r[n]), n));
+	if (oneg)
+		c2 -= (int)(bn_sub_words(&(r[0]), &(r[0]), &(t[n]), n));
+	else
+		c2 += (int)(bn_add_words(&(r[0]), &(r[0]), &(t[n]), n));
+
+	if (c1 != 0) /* Add starting at r[0], could be +ve or -ve */
+	{
+		i = 0;
+		if (c1 > 0) {
+			lc = c1;
+			do {
+				ll = (r[i] + lc) & BN_MASK2;
+				r[i++] = ll;
+				lc = (lc > ll);
+			} while (lc);
+		} else {
+			lc = -c1;
+			do {
+				ll = r[i];
+				r[i++] = (ll - lc) & BN_MASK2;
+				lc = (lc > ll);
+			} while (lc);
+		}
+	}
+	if (c2 != 0) /* Add starting at r[1] */
+	{
+		i = n;
+		if (c2 > 0) {
+			lc = c2;
+			do {
+				ll = (r[i] + lc) & BN_MASK2;
+				r[i++] = ll;
+				lc = (lc > ll);
+			} while (lc);
+		} else {
+			lc = -c2;
+			do {
+				ll = r[i];
+				r[i++] = (ll - lc) & BN_MASK2;
+				lc = (lc > ll);
+			} while (lc);
+		}
+	}
+}
+#endif /* BN_RECURSION */
+
+int
+BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+{
+	int ret = 0;
+	int top, al, bl;
+	BIGNUM *rr;
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+	int i;
+#endif
+#ifdef BN_RECURSION
+	BIGNUM *t = NULL;
+	int j = 0, k;
+#endif
+
+#ifdef BN_COUNT
+	fprintf(stderr, "BN_mul %d * %d\n",a->top,b->top);
+#endif
+
+	bn_check_top(a);
+	bn_check_top(b);
+	bn_check_top(r);
+
+	al = a->top;
+	bl = b->top;
+
+	if ((al == 0) || (bl == 0)) {
+		BN_zero(r);
+		return (1);
+	}
+	top = al + bl;
+
+	BN_CTX_start(ctx);
+	if ((r == a) || (r == b)) {
+		if ((rr = BN_CTX_get(ctx)) == NULL)
+			goto err;
+	} else
+		rr = r;
+	rr->neg = a->neg ^ b->neg;
+
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+	i = al - bl;
+#endif
+#ifdef BN_MUL_COMBA
+	if (i == 0) {
+# if 0
+		if (al == 4) {
+			if (bn_wexpand(rr, 8) == NULL)
+				goto err;
+			rr->top = 8;
+			bn_mul_comba4(rr->d, a->d, b->d);
+			goto end;
+		}
+# endif
+		if (al == 8) {
+			if (bn_wexpand(rr, 16) == NULL)
+				goto err;
+			rr->top = 16;
+			bn_mul_comba8(rr->d, a->d, b->d);
+			goto end;
+		}
+	}
+#endif /* BN_MUL_COMBA */
+#ifdef BN_RECURSION
+	if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) {
+		if (i >= -1 && i <= 1) {
+			/* Find out the power of two lower or equal
+			   to the longest of the two numbers */
+			if (i >= 0) {
+				j = BN_num_bits_word((BN_ULONG)al);
+			}
+			if (i == -1) {
+				j = BN_num_bits_word((BN_ULONG)bl);
+			}
+			j = 1 << (j - 1);
+			assert(j <= al || j <= bl);
+			k = j + j;
+			if ((t = BN_CTX_get(ctx)) == NULL)
+				goto err;
+			if (al > j || bl > j) {
+				if (bn_wexpand(t, k * 4) == NULL)
+					goto err;
+				if (bn_wexpand(rr, k * 4) == NULL)
+					goto err;
+				bn_mul_part_recursive(rr->d, a->d, b->d,
+				    j, al - j, bl - j, t->d);
+			}
+			else	/* al <= j || bl <= j */
+			{
+				if (bn_wexpand(t, k * 2) == NULL)
+					goto err;
+				if (bn_wexpand(rr, k * 2) == NULL)
+					goto err;
+				bn_mul_recursive(rr->d, a->d, b->d,
+				    j, al - j, bl - j, t->d);
+			}
+			rr->top = top;
+			goto end;
+		}
+#if 0
+		if (i == 1 && !BN_get_flags(b, BN_FLG_STATIC_DATA)) {
+			BIGNUM *tmp_bn = (BIGNUM *)b;
+			if (bn_wexpand(tmp_bn, al) == NULL)
+				goto err;
+			tmp_bn->d[bl] = 0;
+			bl++;
+			i--;
+		} else if (i == -1 && !BN_get_flags(a, BN_FLG_STATIC_DATA)) {
+			BIGNUM *tmp_bn = (BIGNUM *)a;
+			if (bn_wexpand(tmp_bn, bl) == NULL)
+				goto err;
+			tmp_bn->d[al] = 0;
+			al++;
+			i++;
+		}
+		if (i == 0) {
+			/* symmetric and > 4 */
+			/* 16 or larger */
+			j = BN_num_bits_word((BN_ULONG)al);
+			j = 1 << (j - 1);
+			k = j + j;
+			if ((t = BN_CTX_get(ctx)) == NULL)
+				goto err;
+			if (al == j) /* exact multiple */
+			{
+				if (bn_wexpand(t, k * 2) == NULL)
+					goto err;
+				if (bn_wexpand(rr, k * 2) == NULL)
+					goto err;
+				bn_mul_recursive(rr->d, a->d, b->d, al, t->d);
+			} else {
+				if (bn_wexpand(t, k * 4) == NULL)
+					goto err;
+				if (bn_wexpand(rr, k * 4) == NULL)
+					goto err;
+				bn_mul_part_recursive(rr->d, a->d, b->d,
+				    al - j, j, t->d);
+			}
+			rr->top = top;
+			goto end;
+		}
+#endif
+	}
+#endif /* BN_RECURSION */
+	if (bn_wexpand(rr, top) == NULL)
+		goto err;
+	rr->top = top;
+	bn_mul_normal(rr->d, a->d, al, b->d, bl);
+
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+end:
+#endif
+	bn_correct_top(rr);
+	if (r != rr)
+		BN_copy(r, rr);
+	ret = 1;
+err:
+	bn_check_top(r);
+	BN_CTX_end(ctx);
+	return (ret);
+}
+
+void
+bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
+{
+	BN_ULONG *rr;
+
+#ifdef BN_COUNT
+	fprintf(stderr, " bn_mul_normal %d * %d\n", na, nb);
+#endif
+
+	if (na < nb) {
+		int itmp;
+		BN_ULONG *ltmp;
+
+		itmp = na;
+		na = nb;
+		nb = itmp;
+		ltmp = a;
+		a = b;
+		b = ltmp;
+
+	}
+	rr = &(r[na]);
+	if (nb <= 0) {
+		(void)bn_mul_words(r, a, na, 0);
+		return;
+	} else
+		rr[0] = bn_mul_words(r, a, na, b[0]);
+
+	for (;;) {
+		if (--nb <= 0)
+			return;
+		rr[1] = bn_mul_add_words(&(r[1]), a, na, b[1]);
+		if (--nb <= 0)
+			return;
+		rr[2] = bn_mul_add_words(&(r[2]), a, na, b[2]);
+		if (--nb <= 0)
+			return;
+		rr[3] = bn_mul_add_words(&(r[3]), a, na, b[3]);
+		if (--nb <= 0)
+			return;
+		rr[4] = bn_mul_add_words(&(r[4]), a, na, b[4]);
+		rr += 4;
+		r += 4;
+		b += 4;
+	}
+}
+
+void
+bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+{
+#ifdef BN_COUNT
+	fprintf(stderr, " bn_mul_low_normal %d * %d\n", n, n);
+#endif
+	bn_mul_words(r, a, n, b[0]);
+
+	for (;;) {
+		if (--n <= 0)
+			return;
+		bn_mul_add_words(&(r[1]), a, n, b[1]);
+		if (--n <= 0)
+			return;
+		bn_mul_add_words(&(r[2]), a, n, b[2]);
+		if (--n <= 0)
+			return;
+		bn_mul_add_words(&(r[3]), a, n, b[3]);
+		if (--n <= 0)
+			return;
+		bn_mul_add_words(&(r[4]), a, n, b[4]);
+		r += 4;
+		b += 4;
+	}
+}
diff --git a/crypto/libressl/crypto/bn/bn_nist.c b/crypto/libressl/crypto/bn/bn_nist.c
new file mode 100644
index 0000000000..93b5b7ef0e
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_nist.c
@@ -0,0 +1,1273 @@
+/* $OpenBSD: bn_nist.c,v 1.17 2016/07/17 22:01:01 bcook Exp $ */
+/*
+ * Written by Nils Larsch for the OpenSSL project
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+
+#include "bn_lcl.h"
+
+#define BN_NIST_192_TOP	(192+BN_BITS2-1)/BN_BITS2
+#define BN_NIST_224_TOP	(224+BN_BITS2-1)/BN_BITS2
+#define BN_NIST_256_TOP	(256+BN_BITS2-1)/BN_BITS2
+#define BN_NIST_384_TOP	(384+BN_BITS2-1)/BN_BITS2
+#define BN_NIST_521_TOP	(521+BN_BITS2-1)/BN_BITS2
+
+/* pre-computed tables are "carry-less" values of modulus*(i+1) */
+#if BN_BITS2 == 64
+static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
+	{0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFFULL},
+	{0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL},
+	{0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFCULL, 0xFFFFFFFFFFFFFFFFULL}
+};
+static const BN_ULONG _nist_p_192_sqr[] = {
+	0x0000000000000001ULL, 0x0000000000000002ULL, 0x0000000000000001ULL,
+	0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL
+};
+static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
+	{
+		0x0000000000000001ULL, 0xFFFFFFFF00000000ULL,
+		0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL
+	},
+	{
+		0x0000000000000002ULL, 0xFFFFFFFE00000000ULL,
+		0xFFFFFFFFFFFFFFFFULL, 0x00000001FFFFFFFFULL
+	} /* this one is "carry-full" */
+};
+static const BN_ULONG _nist_p_224_sqr[] = {
+	0x0000000000000001ULL, 0xFFFFFFFE00000000ULL,
+	0xFFFFFFFFFFFFFFFFULL, 0x0000000200000000ULL,
+	0x0000000000000000ULL, 0xFFFFFFFFFFFFFFFEULL,
+	0xFFFFFFFFFFFFFFFFULL
+};
+static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
+	{
+		0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL,
+		0x0000000000000000ULL, 0xFFFFFFFF00000001ULL
+	},
+	{
+		0xFFFFFFFFFFFFFFFEULL, 0x00000001FFFFFFFFULL,
+		0x0000000000000000ULL, 0xFFFFFFFE00000002ULL
+	},
+	{
+		0xFFFFFFFFFFFFFFFDULL, 0x00000002FFFFFFFFULL,
+		0x0000000000000000ULL, 0xFFFFFFFD00000003ULL
+	},
+	{
+		0xFFFFFFFFFFFFFFFCULL, 0x00000003FFFFFFFFULL,
+		0x0000000000000000ULL, 0xFFFFFFFC00000004ULL
+	},
+	{
+		0xFFFFFFFFFFFFFFFBULL, 0x00000004FFFFFFFFULL,
+		0x0000000000000000ULL, 0xFFFFFFFB00000005ULL
+	},
+};
+static const BN_ULONG _nist_p_256_sqr[] = {
+	0x0000000000000001ULL, 0xFFFFFFFE00000000ULL,
+	0xFFFFFFFFFFFFFFFFULL, 0x00000001FFFFFFFEULL,
+	0x00000001FFFFFFFEULL, 0x00000001FFFFFFFEULL,
+	0xFFFFFFFE00000001ULL, 0xFFFFFFFE00000002ULL
+};
+static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
+	{
+		0x00000000FFFFFFFFULL, 0xFFFFFFFF00000000ULL,
+		0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFFULL,
+		0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL
+	},
+	{
+		0x00000001FFFFFFFEULL, 0xFFFFFFFE00000000ULL,
+		0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL,
+		0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL
+	},
+	{
+		0x00000002FFFFFFFDULL, 0xFFFFFFFD00000000ULL,
+		0xFFFFFFFFFFFFFFFCULL, 0xFFFFFFFFFFFFFFFFULL,
+		0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL
+	},
+	{
+		0x00000003FFFFFFFCULL, 0xFFFFFFFC00000000ULL,
+		0xFFFFFFFFFFFFFFFBULL, 0xFFFFFFFFFFFFFFFFULL,
+		0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL
+	},
+	{
+		0x00000004FFFFFFFBULL, 0xFFFFFFFB00000000ULL,
+		0xFFFFFFFFFFFFFFFAULL, 0xFFFFFFFFFFFFFFFFULL,
+		0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL
+	},
+};
+static const BN_ULONG _nist_p_384_sqr[] = {
+	0xFFFFFFFE00000001ULL, 0x0000000200000000ULL, 0xFFFFFFFE00000000ULL,
+	0x0000000200000000ULL, 0x0000000000000001ULL, 0x0000000000000000ULL,
+	0x00000001FFFFFFFEULL, 0xFFFFFFFE00000000ULL, 0xFFFFFFFFFFFFFFFDULL,
+	0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL
+};
+static const BN_ULONG _nist_p_521[] = {
+	0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+	0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+	0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0x00000000000001FFULL
+};
+static const BN_ULONG _nist_p_521_sqr[] = {
+	0x0000000000000001ULL, 0x0000000000000000ULL, 0x0000000000000000ULL,
+	0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL,
+	0x0000000000000000ULL, 0x0000000000000000ULL, 0xFFFFFFFFFFFFFC00ULL,
+	0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+	0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+	0xFFFFFFFFFFFFFFFFULL, 0x000000000003FFFFULL
+};
+#elif BN_BITS2 == 32
+static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
+	{
+		0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
+		0xFFFFFFFF, 0xFFFFFFFF
+	},
+	{
+		0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF,
+		0xFFFFFFFF, 0xFFFFFFFF
+	},
+	{
+		0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFC, 0xFFFFFFFF,
+		0xFFFFFFFF, 0xFFFFFFFF
+	}
+};
+static const BN_ULONG _nist_p_192_sqr[] = {
+	0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001, 0x00000000,
+	0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
+	{
+		0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF,
+		0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+	},
+	{
+		0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE,
+		0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+	}
+};
+static const BN_ULONG _nist_p_224_sqr[] = {
+	0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE,
+	0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000002,
+	0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF,
+	0xFFFFFFFF, 0xFFFFFFFF
+};
+static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
+	{
+		0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
+		0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF
+	},
+	{
+		0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001,
+		0x00000000, 0x00000000, 0x00000002, 0xFFFFFFFE
+	},
+	{
+		0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002,
+		0x00000000, 0x00000000, 0x00000003, 0xFFFFFFFD
+	},
+	{
+		0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003,
+		0x00000000, 0x00000000, 0x00000004, 0xFFFFFFFC
+	},
+	{
+		0xFFFFFFFB, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000004,
+		0x00000000, 0x00000000, 0x00000005, 0xFFFFFFFB
+	},
+};
+static const BN_ULONG _nist_p_256_sqr[] = {
+	0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE,
+	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001,
+	0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001,
+	0x00000001, 0xFFFFFFFE, 0x00000002, 0xFFFFFFFE
+};
+static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
+	{
+		0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF,
+		0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+		0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+	},
+	{
+		0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE,
+		0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+		0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+	},
+	{
+		0xFFFFFFFD, 0x00000002, 0x00000000, 0xFFFFFFFD,
+		0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+		0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+	},
+	{
+		0xFFFFFFFC, 0x00000003, 0x00000000, 0xFFFFFFFC,
+		0xFFFFFFFB, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+		0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+	},
+	{
+		0xFFFFFFFB, 0x00000004, 0x00000000, 0xFFFFFFFB,
+		0xFFFFFFFA, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+		0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+	},
+};
+static const BN_ULONG _nist_p_384_sqr[] = {
+	0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, 0xFFFFFFFE,
+	0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+	0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF,
+	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+static const BN_ULONG _nist_p_521[] = {
+	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+	0xFFFFFFFF, 0x000001FF
+};
+static const BN_ULONG _nist_p_521_sqr[] = {
+	0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFC00, 0xFFFFFFFF,
+	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+	0xFFFFFFFF, 0xFFFFFFFF, 0x0003FFFF
+};
+#else
+#error "unsupported BN_BITS2"
+#endif
+
+static const BIGNUM _bignum_nist_p_192 = {
+	(BN_ULONG *)_nist_p_192[0],
+	BN_NIST_192_TOP,
+	BN_NIST_192_TOP,
+	0,
+	BN_FLG_STATIC_DATA
+};
+
+static const BIGNUM _bignum_nist_p_224 = {
+	(BN_ULONG *)_nist_p_224[0],
+	BN_NIST_224_TOP,
+	BN_NIST_224_TOP,
+	0,
+	BN_FLG_STATIC_DATA
+};
+
+static const BIGNUM _bignum_nist_p_256 = {
+	(BN_ULONG *)_nist_p_256[0],
+	BN_NIST_256_TOP,
+	BN_NIST_256_TOP,
+	0,
+	BN_FLG_STATIC_DATA
+};
+
+static const BIGNUM _bignum_nist_p_384 = {
+	(BN_ULONG *)_nist_p_384[0],
+	BN_NIST_384_TOP,
+	BN_NIST_384_TOP,
+	0,
+	BN_FLG_STATIC_DATA
+};
+
+static const BIGNUM _bignum_nist_p_521 = {
+	(BN_ULONG *)_nist_p_521,
+	BN_NIST_521_TOP,
+	BN_NIST_521_TOP,
+	0,
+	BN_FLG_STATIC_DATA
+};
+
+
+const BIGNUM *
+BN_get0_nist_prime_192(void)
+{
+	return &_bignum_nist_p_192;
+}
+
+const BIGNUM *
+BN_get0_nist_prime_224(void)
+{
+	return &_bignum_nist_p_224;
+}
+
+const BIGNUM *
+BN_get0_nist_prime_256(void)
+{
+	return &_bignum_nist_p_256;
+}
+
+const BIGNUM *
+BN_get0_nist_prime_384(void)
+{
+	return &_bignum_nist_p_384;
+}
+
+const BIGNUM *
+BN_get0_nist_prime_521(void)
+{
+	return &_bignum_nist_p_521;
+}
+
+static void
+nist_cp_bn_0(BN_ULONG *dst, const BN_ULONG *src, int top, int max)
+{
+	int i;
+
+#ifdef BN_DEBUG
+	OPENSSL_assert(top <= max);
+#endif
+	for (i = 0; i < top; i++)
+		dst[i] = src[i];
+	for (; i < max; i++)
+		dst[i] = 0;
+}
+
+static void nist_cp_bn(BN_ULONG *dst, const BN_ULONG *src, int top)
+{
+	int i;
+
+	for (i = 0; i < top; i++)
+		dst[i] = src[i];
+}
+
+#if BN_BITS2 == 64
+#define bn_cp_64(to, n, from, m)	(to)[n] = (m>=0)?((from)[m]):0;
+#define bn_64_set_0(to, n)		(to)[n] = (BN_ULONG)0;
+/*
+ * two following macros are implemented under assumption that they
+ * are called in a sequence with *ascending* n, i.e. as they are...
+ */
+#define bn_cp_32_naked(to, n, from, m)	(((n)&1)?(to[(n)/2]|=((m)&1)?(from[(m)/2]&BN_MASK2h):(from[(m)/2]<<32))\
+						:(to[(n)/2] =((m)&1)?(from[(m)/2]>>32):(from[(m)/2]&BN_MASK2l)))
+#define bn_32_set_0(to, n)		(((n)&1)?(to[(n)/2]&=BN_MASK2l):(to[(n)/2]=0));
+#define bn_cp_32(to,n,from,m)		((m)>=0)?bn_cp_32_naked(to,n,from,m):bn_32_set_0(to,n)
+# if BYTE_ORDER == LITTLE_ENDIAN
+#  if defined(_LP64)
+#   define NIST_INT64 long
+#  else
+#   define NIST_INT64 long long
+#  endif
+# endif
+#else
+#define bn_cp_64(to, n, from, m) \
+	{ \
+	bn_cp_32(to, (n)*2, from, (m)*2); \
+	bn_cp_32(to, (n)*2+1, from, (m)*2+1); \
+	}
+#define bn_64_set_0(to, n) \
+	{ \
+	bn_32_set_0(to, (n)*2); \
+	bn_32_set_0(to, (n)*2+1); \
+	}
+#define bn_cp_32(to, n, from, m)	(to)[n] = (m>=0)?((from)[m]):0;
+#define bn_32_set_0(to, n)		(to)[n] = (BN_ULONG)0;
+# if defined(BN_LLONG)
+#  define NIST_INT64 long long
+# endif
+#endif /* BN_BITS2 != 64 */
+
+#define nist_set_192(to, from, a1, a2, a3) \
+	{ \
+	bn_cp_64(to, 0, from, (a3) - 3) \
+	bn_cp_64(to, 1, from, (a2) - 3) \
+	bn_cp_64(to, 2, from, (a1) - 3) \
+	}
+
+int
+BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
+{
+	int top = a->top, i;
+	int carry;
+	BN_ULONG *r_d, *a_d = a->d;
+	union {
+		BN_ULONG bn[BN_NIST_192_TOP];
+		unsigned int ui[BN_NIST_192_TOP *
+		    sizeof(BN_ULONG) / sizeof(unsigned int)];
+	} buf;
+	BN_ULONG c_d[BN_NIST_192_TOP], *res;
+	uintptr_t mask;
+	static const BIGNUM _bignum_nist_p_192_sqr = {
+		(BN_ULONG *)_nist_p_192_sqr,
+		sizeof(_nist_p_192_sqr) / sizeof(_nist_p_192_sqr[0]),
+		sizeof(_nist_p_192_sqr) / sizeof(_nist_p_192_sqr[0]),
+		0,
+		BN_FLG_STATIC_DATA
+	};
+
+	field = &_bignum_nist_p_192; /* just to make sure */
+
+	if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_192_sqr) >= 0)
+		return BN_nnmod(r, a, field, ctx);
+
+	i = BN_ucmp(field, a);
+	if (i == 0) {
+		BN_zero(r);
+		return 1;
+	} else if (i > 0)
+		return (r == a) ? 1 : (BN_copy(r , a) != NULL);
+
+	if (r != a) {
+		if (!bn_wexpand(r, BN_NIST_192_TOP))
+			return 0;
+		r_d = r->d;
+		nist_cp_bn(r_d, a_d, BN_NIST_192_TOP);
+	} else
+		r_d = a_d;
+
+	nist_cp_bn_0(buf.bn, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP,
+	    BN_NIST_192_TOP);
+
+#if defined(NIST_INT64)
+	{
+		NIST_INT64 acc;	/* accumulator */
+		unsigned int *rp = (unsigned int *)r_d;
+		const unsigned int *bp = (const unsigned int *)buf.ui;
+
+		acc = rp[0];
+		acc += bp[3 * 2 - 6];
+		acc += bp[5 * 2 - 6];
+		rp[0] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[1];
+		acc += bp[3 * 2 - 5];
+		acc += bp[5 * 2 - 5];
+		rp[1] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[2];
+		acc += bp[3 * 2 - 6];
+		acc += bp[4 * 2 - 6];
+		acc += bp[5 * 2 - 6];
+		rp[2] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[3];
+		acc += bp[3 * 2 - 5];
+		acc += bp[4 * 2 - 5];
+		acc += bp[5 * 2 - 5];
+		rp[3] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[4];
+		acc += bp[4 * 2 - 6];
+		acc += bp[5 * 2 - 6];
+		rp[4] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[5];
+		acc += bp[4 * 2 - 5];
+		acc += bp[5 * 2 - 5];
+		rp[5] = (unsigned int)acc;
+
+		carry = (int)(acc >> 32);
+	}
+#else
+	{
+		BN_ULONG t_d[BN_NIST_192_TOP] = {0};
+
+		nist_set_192(t_d, buf.bn, 0, 3, 3);
+		carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
+		nist_set_192(t_d, buf.bn, 4, 4, 0);
+		carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
+		nist_set_192(t_d, buf.bn, 5, 5, 5)
+		carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
+	}
+#endif
+	if (carry > 0)
+		carry = (int)bn_sub_words(r_d, r_d, _nist_p_192[carry - 1],
+		    BN_NIST_192_TOP);
+	else
+		carry = 1;
+
+	/*
+	 * we need 'if (carry==0 || result>=modulus) result-=modulus;'
+	 * as comparison implies subtraction, we can write
+	 * 'tmp=result-modulus; if (!carry || !borrow) result=tmp;'
+	 * this is what happens below, but without explicit if:-) a.
+	 */
+	mask = 0 - (uintptr_t)bn_sub_words(c_d, r_d, _nist_p_192[0],
+	    BN_NIST_192_TOP);
+	mask &= 0 - (uintptr_t)carry;
+	res = c_d;
+	res = (BN_ULONG *)(((uintptr_t)res & ~mask) | ((uintptr_t)r_d & mask));
+	nist_cp_bn(r_d, res, BN_NIST_192_TOP);
+	r->top = BN_NIST_192_TOP;
+	bn_correct_top(r);
+
+	return 1;
+}
+
+typedef BN_ULONG (*bn_addsub_f)(BN_ULONG *, const BN_ULONG *,
+    const BN_ULONG *, int);
+
+#define nist_set_224(to, from, a1, a2, a3, a4, a5, a6, a7) \
+	{ \
+	bn_cp_32(to, 0, from, (a7) - 7) \
+	bn_cp_32(to, 1, from, (a6) - 7) \
+	bn_cp_32(to, 2, from, (a5) - 7) \
+	bn_cp_32(to, 3, from, (a4) - 7) \
+	bn_cp_32(to, 4, from, (a3) - 7) \
+	bn_cp_32(to, 5, from, (a2) - 7) \
+	bn_cp_32(to, 6, from, (a1) - 7) \
+	}
+
+int
+BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
+{
+	int top = a->top, i;
+	int carry;
+	BN_ULONG *r_d, *a_d = a->d;
+	union {
+		BN_ULONG bn[BN_NIST_224_TOP];
+		unsigned int ui[BN_NIST_224_TOP *
+		    sizeof(BN_ULONG) / sizeof(unsigned int)];
+	} buf;
+	BN_ULONG c_d[BN_NIST_224_TOP], *res;
+	uintptr_t mask;
+	union {
+		bn_addsub_f f;
+		uintptr_t p;
+	} u;
+	static const BIGNUM _bignum_nist_p_224_sqr = {
+		(BN_ULONG *)_nist_p_224_sqr,
+		sizeof(_nist_p_224_sqr) / sizeof(_nist_p_224_sqr[0]),
+		sizeof(_nist_p_224_sqr) / sizeof(_nist_p_224_sqr[0]),
+		0,
+		BN_FLG_STATIC_DATA
+	};
+
+	field = &_bignum_nist_p_224; /* just to make sure */
+
+	if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_224_sqr) >= 0)
+		return BN_nnmod(r, a, field, ctx);
+
+	i = BN_ucmp(field, a);
+	if (i == 0) {
+		BN_zero(r);
+		return 1;
+	} else if (i > 0)
+		return (r == a) ? 1 : (BN_copy(r, a) != NULL);
+
+	if (r != a) {
+		if (!bn_wexpand(r, BN_NIST_224_TOP))
+			return 0;
+		r_d = r->d;
+		nist_cp_bn(r_d, a_d, BN_NIST_224_TOP);
+	} else
+		r_d = a_d;
+
+	memset(&buf, 0, sizeof(buf));
+
+#if BN_BITS2==64
+	/* copy upper 256 bits of 448 bit number ... */
+	nist_cp_bn_0(c_d, a_d + (BN_NIST_224_TOP - 1),
+	    top - (BN_NIST_224_TOP - 1), BN_NIST_224_TOP);
+	/* ... and right shift by 32 to obtain upper 224 bits */
+	nist_set_224(buf.bn, c_d, 14, 13, 12, 11, 10, 9, 8);
+	/* truncate lower part to 224 bits too */
+	r_d[BN_NIST_224_TOP - 1] &= BN_MASK2l;
+#else
+	nist_cp_bn_0(buf.bn, a_d + BN_NIST_224_TOP,
+	    top - BN_NIST_224_TOP, BN_NIST_224_TOP);
+#endif
+
+#if defined(NIST_INT64) && BN_BITS2!=64
+	{
+		NIST_INT64 acc;	/* accumulator */
+		unsigned int *rp = (unsigned int *)r_d;
+		const unsigned int *bp = (const unsigned int *)buf.ui;
+
+		acc = rp[0];
+		acc -= bp[7 - 7];
+		acc -= bp[11 - 7];
+		rp[0] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[1];
+		acc -= bp[8 - 7];
+		acc -= bp[12 - 7];
+		rp[1] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[2];
+		acc -= bp[9 - 7];
+		acc -= bp[13 - 7];
+		rp[2] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[3];
+		acc += bp[7 - 7];
+		acc += bp[11 - 7];
+		acc -= bp[10 - 7];
+		rp[3] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[4];
+		acc += bp[8 - 7];
+		acc += bp[12 - 7];
+		acc -= bp[11 - 7];
+		rp[4] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[5];
+		acc += bp[9 - 7];
+		acc += bp[13 - 7];
+		acc -= bp[12 - 7];
+		rp[5] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[6];
+		acc += bp[10 - 7];
+		acc -= bp[13 - 7];
+		rp[6] = (unsigned int)acc;
+
+		carry = (int)(acc >> 32);
+# if BN_BITS2==64
+		rp[7] = carry;
+# endif
+	}
+#else
+	{
+		BN_ULONG t_d[BN_NIST_224_TOP] = {0};
+
+		nist_set_224(t_d, buf.bn, 10, 9, 8, 7, 0, 0, 0);
+		carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
+		nist_set_224(t_d, buf.bn, 0, 13, 12, 11, 0, 0, 0);
+		carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
+		nist_set_224(t_d, buf.bn, 13, 12, 11, 10, 9, 8, 7);
+		carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
+		nist_set_224(t_d, buf.bn, 0, 0, 0, 0, 13, 12, 11);
+		carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
+
+#if BN_BITS2==64
+		carry = (int)(r_d[BN_NIST_224_TOP - 1] >> 32);
+#endif
+	}
+#endif
+	u.f = bn_sub_words;
+	if (carry > 0) {
+		carry = (int)bn_sub_words(r_d, r_d, _nist_p_224[carry - 1],
+		    BN_NIST_224_TOP);
+#if BN_BITS2==64
+		carry = (int)(~(r_d[BN_NIST_224_TOP - 1] >> 32)) & 1;
+#endif
+	} else if (carry < 0) {
+		/* it's a bit more complicated logic in this case.
+		 * if bn_add_words yields no carry, then result
+		 * has to be adjusted by unconditionally *adding*
+		 * the modulus. but if it does, then result has
+		 * to be compared to the modulus and conditionally
+		 * adjusted by *subtracting* the latter. */
+		carry = (int)bn_add_words(r_d, r_d, _nist_p_224[-carry - 1],
+		    BN_NIST_224_TOP);
+		mask = 0 - (uintptr_t)carry;
+		u.p = ((uintptr_t)bn_sub_words & mask) |
+		    ((uintptr_t)bn_add_words & ~mask);
+	} else
+		carry = 1;
+
+	/* otherwise it's effectively same as in BN_nist_mod_192... */
+	mask = 0 - (uintptr_t)(*u.f)(c_d, r_d, _nist_p_224[0], BN_NIST_224_TOP);
+	mask &= 0 - (uintptr_t)carry;
+	res = c_d;
+	res = (BN_ULONG *)(((uintptr_t)res & ~mask) | ((uintptr_t)r_d & mask));
+	nist_cp_bn(r_d, res, BN_NIST_224_TOP);
+	r->top = BN_NIST_224_TOP;
+	bn_correct_top(r);
+
+	return 1;
+}
+
+#define nist_set_256(to, from, a1, a2, a3, a4, a5, a6, a7, a8) \
+	{ \
+	bn_cp_32(to, 0, from, (a8) - 8) \
+	bn_cp_32(to, 1, from, (a7) - 8) \
+	bn_cp_32(to, 2, from, (a6) - 8) \
+	bn_cp_32(to, 3, from, (a5) - 8) \
+	bn_cp_32(to, 4, from, (a4) - 8) \
+	bn_cp_32(to, 5, from, (a3) - 8) \
+	bn_cp_32(to, 6, from, (a2) - 8) \
+	bn_cp_32(to, 7, from, (a1) - 8) \
+	}
+
+int
+BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
+{
+	int i, top = a->top;
+	int carry = 0;
+	BN_ULONG *a_d = a->d, *r_d;
+	union {
+		BN_ULONG bn[BN_NIST_256_TOP];
+		unsigned int ui[BN_NIST_256_TOP *
+		    sizeof(BN_ULONG) / sizeof(unsigned int)];
+	} buf;
+	BN_ULONG c_d[BN_NIST_256_TOP] = {0}, *res;
+	uintptr_t mask;
+	union {
+		bn_addsub_f f;
+		uintptr_t p;
+	} u;
+	static const BIGNUM _bignum_nist_p_256_sqr = {
+		(BN_ULONG *)_nist_p_256_sqr,
+		sizeof(_nist_p_256_sqr) / sizeof(_nist_p_256_sqr[0]),
+		sizeof(_nist_p_256_sqr) / sizeof(_nist_p_256_sqr[0]),
+		0,
+		BN_FLG_STATIC_DATA
+	};
+
+	field = &_bignum_nist_p_256; /* just to make sure */
+
+	if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_256_sqr) >= 0)
+		return BN_nnmod(r, a, field, ctx);
+
+	i = BN_ucmp(field, a);
+	if (i == 0) {
+		BN_zero(r);
+		return 1;
+	} else if (i > 0)
+		return (r == a) ? 1 : (BN_copy(r, a) != NULL);
+
+	if (r != a) {
+		if (!bn_wexpand(r, BN_NIST_256_TOP))
+			return 0;
+		r_d = r->d;
+		nist_cp_bn(r_d, a_d, BN_NIST_256_TOP);
+	} else
+		r_d = a_d;
+
+	nist_cp_bn_0(buf.bn, a_d + BN_NIST_256_TOP,
+	    top - BN_NIST_256_TOP, BN_NIST_256_TOP);
+
+#if defined(NIST_INT64)
+	{
+		NIST_INT64 acc;	/* accumulator */
+		unsigned int *rp = (unsigned int *)r_d;
+		const unsigned int *bp = (const unsigned int *)buf.ui;
+
+		acc = rp[0];
+		acc += bp[8 - 8];
+		acc += bp[9 - 8];
+		acc -= bp[11 - 8];
+		acc -= bp[12 - 8];
+		acc -= bp[13 - 8];
+		acc -= bp[14 - 8];
+		rp[0] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[1];
+		acc += bp[9 - 8];
+		acc += bp[10 - 8];
+		acc -= bp[12 - 8];
+		acc -= bp[13 - 8];
+		acc -= bp[14 - 8];
+		acc -= bp[15 - 8];
+		rp[1] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[2];
+		acc += bp[10 - 8];
+		acc += bp[11 - 8];
+		acc -= bp[13 - 8];
+		acc -= bp[14 - 8];
+		acc -= bp[15 - 8];
+		rp[2] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[3];
+		acc += bp[11 - 8];
+		acc += bp[11 - 8];
+		acc += bp[12 - 8];
+		acc += bp[12 - 8];
+		acc += bp[13 - 8];
+		acc -= bp[15 - 8];
+		acc -= bp[8 - 8];
+		acc -= bp[9 - 8];
+		rp[3] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[4];
+		acc += bp[12 - 8];
+		acc += bp[12 - 8];
+		acc += bp[13 - 8];
+		acc += bp[13 - 8];
+		acc += bp[14 - 8];
+		acc -= bp[9 - 8];
+		acc -= bp[10 - 8];
+		rp[4] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[5];
+		acc += bp[13 - 8];
+		acc += bp[13 - 8];
+		acc += bp[14 - 8];
+		acc += bp[14 - 8];
+		acc += bp[15 - 8];
+		acc -= bp[10 - 8];
+		acc -= bp[11 - 8];
+		rp[5] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[6];
+		acc += bp[14 - 8];
+		acc += bp[14 - 8];
+		acc += bp[15 - 8];
+		acc += bp[15 - 8];
+		acc += bp[14 - 8];
+		acc += bp[13 - 8];
+		acc -= bp[8 - 8];
+		acc -= bp[9 - 8];
+		rp[6] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[7];
+		acc += bp[15 - 8];
+		acc += bp[15 - 8];
+		acc += bp[15 - 8];
+		acc += bp[8 - 8];
+		acc -= bp[10 - 8];
+		acc -= bp[11 - 8];
+		acc -= bp[12 - 8];
+		acc -= bp[13 - 8];
+		rp[7] = (unsigned int)acc;
+
+		carry = (int)(acc >> 32);
+	}
+#else
+	{
+		BN_ULONG t_d[BN_NIST_256_TOP] = {0};
+
+		/*S1*/
+		nist_set_256(t_d, buf.bn, 15, 14, 13, 12, 11, 0, 0, 0);
+		/*S2*/
+		nist_set_256(c_d, buf.bn, 0, 15, 14, 13, 12, 0, 0, 0);
+		carry = (int)bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP);
+		/* left shift */
+		{
+			BN_ULONG *ap, t, c;
+			ap = t_d;
+			c = 0;
+			for (i = BN_NIST_256_TOP; i != 0; --i) {
+				t = *ap;
+				*(ap++) = ((t << 1) | c) & BN_MASK2;
+				c = (t & BN_TBIT) ? 1 : 0;
+			}
+			carry <<= 1;
+			carry |= c;
+		}
+		carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+		/*S3*/
+		nist_set_256(t_d, buf.bn, 15, 14, 0, 0, 0, 10, 9, 8);
+		carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+		/*S4*/
+		nist_set_256(t_d, buf.bn, 8, 13, 15, 14, 13, 11, 10, 9);
+		carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+		/*D1*/
+		nist_set_256(t_d, buf.bn, 10, 8, 0, 0, 0, 13, 12, 11);
+		carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+		/*D2*/
+		nist_set_256(t_d, buf.bn, 11, 9, 0, 0, 15, 14, 13, 12);
+		carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+		/*D3*/
+		nist_set_256(t_d, buf.bn, 12, 0, 10, 9, 8, 15, 14, 13);
+		carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+		/*D4*/
+		nist_set_256(t_d, buf.bn, 13, 0, 11, 10, 9, 0, 15, 14);
+		carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+
+	}
+#endif
+	/* see BN_nist_mod_224 for explanation */
+	u.f = bn_sub_words;
+	if (carry > 0)
+		carry = (int)bn_sub_words(r_d, r_d, _nist_p_256[carry - 1],
+		    BN_NIST_256_TOP);
+	else if (carry < 0) {
+		carry = (int)bn_add_words(r_d, r_d, _nist_p_256[-carry - 1],
+		    BN_NIST_256_TOP);
+		mask = 0 - (uintptr_t)carry;
+		u.p = ((uintptr_t)bn_sub_words & mask) |
+		    ((uintptr_t)bn_add_words & ~mask);
+	} else
+		carry = 1;
+
+	mask = 0 - (uintptr_t)(*u.f)(c_d, r_d, _nist_p_256[0], BN_NIST_256_TOP);
+	mask &= 0 - (uintptr_t)carry;
+	res = c_d;
+	res = (BN_ULONG *)(((uintptr_t)res & ~mask) | ((uintptr_t)r_d & mask));
+	nist_cp_bn(r_d, res, BN_NIST_256_TOP);
+	r->top = BN_NIST_256_TOP;
+	bn_correct_top(r);
+
+	return 1;
+}
+
+#define nist_set_384(to,from,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \
+	{ \
+	bn_cp_32(to, 0, from,  (a12) - 12) \
+	bn_cp_32(to, 1, from,  (a11) - 12) \
+	bn_cp_32(to, 2, from,  (a10) - 12) \
+	bn_cp_32(to, 3, from,  (a9) - 12)  \
+	bn_cp_32(to, 4, from,  (a8) - 12)  \
+	bn_cp_32(to, 5, from,  (a7) - 12)  \
+	bn_cp_32(to, 6, from,  (a6) - 12)  \
+	bn_cp_32(to, 7, from,  (a5) - 12)  \
+	bn_cp_32(to, 8, from,  (a4) - 12)  \
+	bn_cp_32(to, 9, from,  (a3) - 12)  \
+	bn_cp_32(to, 10, from, (a2) - 12)  \
+	bn_cp_32(to, 11, from, (a1) - 12)  \
+	}
+
+int
+BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
+{
+	int i, top = a->top;
+	int carry = 0;
+	BN_ULONG *r_d, *a_d = a->d;
+	union {
+		BN_ULONG bn[BN_NIST_384_TOP];
+		unsigned int ui[BN_NIST_384_TOP *
+		    sizeof(BN_ULONG) / sizeof(unsigned int)];
+	} buf;
+	BN_ULONG c_d[BN_NIST_384_TOP], *res;
+	uintptr_t mask;
+	union {
+		bn_addsub_f f;
+		uintptr_t p;
+	} u;
+	static const BIGNUM _bignum_nist_p_384_sqr = {
+		(BN_ULONG *)_nist_p_384_sqr,
+		sizeof(_nist_p_384_sqr) / sizeof(_nist_p_384_sqr[0]),
+		sizeof(_nist_p_384_sqr) / sizeof(_nist_p_384_sqr[0]),
+		0,
+		BN_FLG_STATIC_DATA
+	};
+
+	field = &_bignum_nist_p_384; /* just to make sure */
+
+	if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_384_sqr) >= 0)
+		return BN_nnmod(r, a, field, ctx);
+
+	i = BN_ucmp(field, a);
+	if (i == 0) {
+		BN_zero(r);
+		return 1;
+	} else if (i > 0)
+		return (r == a) ? 1 : (BN_copy(r, a) != NULL);
+
+	if (r != a) {
+		if (!bn_wexpand(r, BN_NIST_384_TOP))
+			return 0;
+		r_d = r->d;
+		nist_cp_bn(r_d, a_d, BN_NIST_384_TOP);
+	} else
+		r_d = a_d;
+
+	nist_cp_bn_0(buf.bn, a_d + BN_NIST_384_TOP,
+	    top - BN_NIST_384_TOP, BN_NIST_384_TOP);
+
+#if defined(NIST_INT64)
+	{
+		NIST_INT64 acc;	/* accumulator */
+		unsigned int *rp = (unsigned int *)r_d;
+		const unsigned int *bp = (const unsigned int *)buf.ui;
+
+		acc = rp[0];
+		acc += bp[12 - 12];
+		acc += bp[21 - 12];
+		acc += bp[20 - 12];
+		acc -= bp[23 - 12];
+		rp[0] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[1];
+		acc += bp[13 - 12];
+		acc += bp[22 - 12];
+		acc += bp[23 - 12];
+		acc -= bp[12 - 12];
+		acc -= bp[20 - 12];
+		rp[1] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[2];
+		acc += bp[14 - 12];
+		acc += bp[23 - 12];
+		acc -= bp[13 - 12];
+		acc -= bp[21 - 12];
+		rp[2] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[3];
+		acc += bp[15 - 12];
+		acc += bp[12 - 12];
+		acc += bp[20 - 12];
+		acc += bp[21 - 12];
+		acc -= bp[14 - 12];
+		acc -= bp[22 - 12];
+		acc -= bp[23 - 12];
+		rp[3] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[4];
+		acc += bp[21 - 12];
+		acc += bp[21 - 12];
+		acc += bp[16 - 12];
+		acc += bp[13 - 12];
+		acc += bp[12 - 12];
+		acc += bp[20 - 12];
+		acc += bp[22 - 12];
+		acc -= bp[15 - 12];
+		acc -= bp[23 - 12];
+		acc -= bp[23 - 12];
+		rp[4] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[5];
+		acc += bp[22 - 12];
+		acc += bp[22 - 12];
+		acc += bp[17 - 12];
+		acc += bp[14 - 12];
+		acc += bp[13 - 12];
+		acc += bp[21 - 12];
+		acc += bp[23 - 12];
+		acc -= bp[16 - 12];
+		rp[5] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[6];
+		acc += bp[23 - 12];
+		acc += bp[23 - 12];
+		acc += bp[18 - 12];
+		acc += bp[15 - 12];
+		acc += bp[14 - 12];
+		acc += bp[22 - 12];
+		acc -= bp[17 - 12];
+		rp[6] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[7];
+		acc += bp[19 - 12];
+		acc += bp[16 - 12];
+		acc += bp[15 - 12];
+		acc += bp[23 - 12];
+		acc -= bp[18 - 12];
+		rp[7] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[8];
+		acc += bp[20 - 12];
+		acc += bp[17 - 12];
+		acc += bp[16 - 12];
+		acc -= bp[19 - 12];
+		rp[8] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[9];
+		acc += bp[21 - 12];
+		acc += bp[18 - 12];
+		acc += bp[17 - 12];
+		acc -= bp[20 - 12];
+		rp[9] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[10];
+		acc += bp[22 - 12];
+		acc += bp[19 - 12];
+		acc += bp[18 - 12];
+		acc -= bp[21 - 12];
+		rp[10] = (unsigned int)acc;
+		acc >>= 32;
+
+		acc += rp[11];
+		acc += bp[23 - 12];
+		acc += bp[20 - 12];
+		acc += bp[19 - 12];
+		acc -= bp[22 - 12];
+		rp[11] = (unsigned int)acc;
+
+		carry = (int)(acc >> 32);
+	}
+#else
+	{
+		BN_ULONG t_d[BN_NIST_384_TOP] = {0};
+
+		/*S1*/
+		nist_set_256(t_d, buf.bn, 0, 0, 0, 0, 0, 23 - 4, 22 - 4,
+		    21 - 4);
+		/* left shift */
+		{
+			BN_ULONG *ap, t, c;
+			ap = t_d;
+			c = 0;
+			for (i = 3; i != 0; --i) {
+				t= *ap;
+				*(ap++) = ((t << 1)|c) & BN_MASK2;
+				c = (t & BN_TBIT) ? 1 : 0;
+			}
+			*ap = c;
+		}
+		carry = (int)bn_add_words(r_d + (128 / BN_BITS2),
+		    r_d + (128 / BN_BITS2), t_d, BN_NIST_256_TOP);
+		/*S2 */
+		carry += (int)bn_add_words(r_d, r_d, buf.bn, BN_NIST_384_TOP);
+		/*S3*/
+		nist_set_384(t_d, buf.bn, 20, 19, 18, 17, 16, 15, 14, 13, 12,
+		    23, 22, 21);
+		carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+		/*S4*/
+		nist_set_384(t_d, buf.bn, 19, 18, 17, 16, 15, 14, 13, 12, 20,
+		    0, 23, 0);
+		carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+		/*S5*/
+		nist_set_384(t_d, buf.bn, 0,0, 0,0, 23, 22, 21, 20, 0,0, 0, 0);
+		carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+		/*S6*/
+		nist_set_384(t_d, buf.bn, 0,0, 0,0, 0,0, 23, 22, 21, 0,0, 20);
+		carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+		/*D1*/
+		nist_set_384(t_d, buf.bn, 22, 21, 20, 19, 18, 17, 16, 15, 14,
+		    13, 12, 23);
+		carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+		/*D2*/
+		nist_set_384(t_d, buf.bn, 0,0, 0,0, 0,0, 0,23, 22, 21, 20, 0);
+		carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+		/*D3*/
+		nist_set_384(t_d, buf.bn, 0,0, 0,0, 0,0, 0,23, 23, 0,0, 0);
+		carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+
+	}
+#endif
+	/* see BN_nist_mod_224 for explanation */
+	u.f = bn_sub_words;
+	if (carry > 0)
+		carry = (int)bn_sub_words(r_d, r_d, _nist_p_384[carry - 1],
+		    BN_NIST_384_TOP);
+	else if (carry < 0) {
+		carry = (int)bn_add_words(r_d, r_d, _nist_p_384[-carry - 1],
+		    BN_NIST_384_TOP);
+		mask = 0 - (uintptr_t)carry;
+		u.p = ((uintptr_t)bn_sub_words & mask) |
+		    ((uintptr_t)bn_add_words & ~mask);
+	} else
+		carry = 1;
+
+	mask = 0 - (uintptr_t)(*u.f)(c_d, r_d, _nist_p_384[0], BN_NIST_384_TOP);
+	mask &= 0 - (uintptr_t)carry;
+	res = c_d;
+	res = (BN_ULONG *)(((uintptr_t)res & ~mask) | ((uintptr_t)r_d & mask));
+	nist_cp_bn(r_d, res, BN_NIST_384_TOP);
+	r->top = BN_NIST_384_TOP;
+	bn_correct_top(r);
+
+	return 1;
+}
+
+#define BN_NIST_521_RSHIFT	(521%BN_BITS2)
+#define BN_NIST_521_LSHIFT	(BN_BITS2-BN_NIST_521_RSHIFT)
+#define BN_NIST_521_TOP_MASK	((BN_ULONG)BN_MASK2>>BN_NIST_521_LSHIFT)
+
+int
+BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
+{
+	int top = a->top, i;
+	BN_ULONG *r_d, *a_d = a->d, t_d[BN_NIST_521_TOP], val, tmp, *res;
+	uintptr_t mask;
+	static const BIGNUM _bignum_nist_p_521_sqr = {
+		(BN_ULONG *)_nist_p_521_sqr,
+		sizeof(_nist_p_521_sqr) / sizeof(_nist_p_521_sqr[0]),
+		sizeof(_nist_p_521_sqr) / sizeof(_nist_p_521_sqr[0]),
+		0,
+		BN_FLG_STATIC_DATA
+	};
+
+	field = &_bignum_nist_p_521; /* just to make sure */
+
+	if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_521_sqr) >= 0)
+		return BN_nnmod(r, a, field, ctx);
+
+	i = BN_ucmp(field, a);
+	if (i == 0) {
+		BN_zero(r);
+		return 1;
+	} else if (i > 0)
+		return (r == a) ? 1 : (BN_copy(r, a) != NULL);
+
+	if (r != a) {
+		if (!bn_wexpand(r, BN_NIST_521_TOP))
+			return 0;
+		r_d = r->d;
+		nist_cp_bn(r_d, a_d, BN_NIST_521_TOP);
+	} else
+		r_d = a_d;
+
+	/* upper 521 bits, copy ... */
+	nist_cp_bn_0(t_d, a_d + (BN_NIST_521_TOP - 1),
+	    top - (BN_NIST_521_TOP - 1), BN_NIST_521_TOP);
+	/* ... and right shift */
+	for (val = t_d[0], i = 0; i < BN_NIST_521_TOP - 1; i++) {
+		tmp = val >> BN_NIST_521_RSHIFT;
+		val = t_d[i + 1];
+		t_d[i] = (tmp | val << BN_NIST_521_LSHIFT) & BN_MASK2;
+	}
+	t_d[i] = val >> BN_NIST_521_RSHIFT;
+	/* lower 521 bits */
+	r_d[i] &= BN_NIST_521_TOP_MASK;
+
+	bn_add_words(r_d, r_d, t_d, BN_NIST_521_TOP);
+	mask = 0 - (uintptr_t)bn_sub_words(t_d, r_d, _nist_p_521,
+	    BN_NIST_521_TOP);
+	res = t_d;
+	res = (BN_ULONG *)(((uintptr_t)res & ~mask) | ((uintptr_t)r_d & mask));
+	nist_cp_bn(r_d, res, BN_NIST_521_TOP);
+	r->top = BN_NIST_521_TOP;
+	bn_correct_top(r);
+
+	return 1;
+}
diff --git a/crypto/libressl/crypto/bn/bn_prime.c b/crypto/libressl/crypto/bn/bn_prime.c
new file mode 100644
index 0000000000..63377eb39e
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_prime.c
@@ -0,0 +1,546 @@
+/* $OpenBSD: bn_prime.c,v 1.14 2015/10/21 19:02:22 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+
+#include "bn_lcl.h"
+
+/* NB: these functions have been "upgraded", the deprecated versions (which are
+ * compatibility wrappers using these functions) are in bn_depr.c.
+ * - Geoff
+ */
+
+/* The quick sieve algorithm approach to weeding out primes is
+ * Philip Zimmermann's, as implemented in PGP.  I have had a read of
+ * his comments and implemented my own version.
+ */
+#include "bn_prime.h"
+
+static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
+    const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont);
+static int probable_prime(BIGNUM *rnd, int bits);
+static int probable_prime_dh(BIGNUM *rnd, int bits,
+    const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
+static int probable_prime_dh_safe(BIGNUM *rnd, int bits,
+    const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
+
+int
+BN_GENCB_call(BN_GENCB *cb, int a, int b)
+{
+	/* No callback means continue */
+	if (!cb)
+		return 1;
+	switch (cb->ver) {
+	case 1:
+		/* Deprecated-style callbacks */
+		if (!cb->cb.cb_1)
+			return 1;
+		cb->cb.cb_1(a, b, cb->arg);
+		return 1;
+	case 2:
+		/* New-style callbacks */
+		return cb->cb.cb_2(a, b, cb);
+	default:
+		break;
+	}
+	/* Unrecognised callback type */
+	return 0;
+}
+
+int
+BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add,
+    const BIGNUM *rem, BN_GENCB *cb)
+{
+	BIGNUM *t;
+	int found = 0;
+	int i, j, c1 = 0;
+	BN_CTX *ctx;
+	int checks;
+
+	if (bits < 2 || (bits == 2 && safe)) {
+		/*
+		 * There are no prime numbers smaller than 2, and the smallest
+		 * safe prime (7) spans three bits.
+		 */
+		BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL);
+		return 0;
+	}
+
+	ctx = BN_CTX_new();
+	if (ctx == NULL)
+		goto err;
+	BN_CTX_start(ctx);
+	if ((t = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	checks = BN_prime_checks_for_size(bits);
+
+loop:
+	/* make a random number and set the top and bottom bits */
+	if (add == NULL) {
+		if (!probable_prime(ret, bits))
+			goto err;
+	} else {
+		if (safe) {
+			if (!probable_prime_dh_safe(ret, bits, add, rem, ctx))
+				goto err;
+		} else {
+			if (!probable_prime_dh(ret, bits, add, rem, ctx))
+				goto err;
+		}
+	}
+	/* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */
+	if (!BN_GENCB_call(cb, 0, c1++))
+		/* aborted */
+		goto err;
+
+	if (!safe) {
+		i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb);
+		if (i == -1)
+			goto err;
+		if (i == 0)
+			goto loop;
+	} else {
+		/* for "safe prime" generation,
+		 * check that (p-1)/2 is prime.
+		 * Since a prime is odd, We just
+		 * need to divide by 2 */
+		if (!BN_rshift1(t, ret))
+			goto err;
+
+		for (i = 0; i < checks; i++) {
+			j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, cb);
+			if (j == -1)
+				goto err;
+			if (j == 0)
+				goto loop;
+
+			j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, cb);
+			if (j == -1)
+				goto err;
+			if (j == 0)
+				goto loop;
+
+			if (!BN_GENCB_call(cb, 2, c1 - 1))
+				goto err;
+			/* We have a safe prime test pass */
+		}
+	}
+	/* we have a prime :-) */
+	found = 1;
+
+err:
+	if (ctx != NULL) {
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+	}
+	bn_check_top(ret);
+	return found;
+}
+
+int
+BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, BN_GENCB *cb)
+{
+	return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb);
+}
+
+int
+BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
+    int do_trial_division, BN_GENCB *cb)
+{
+	int i, j, ret = -1;
+	int k;
+	BN_CTX *ctx = NULL;
+	BIGNUM *A1, *A1_odd, *check; /* taken from ctx */
+	BN_MONT_CTX *mont = NULL;
+	const BIGNUM *A = NULL;
+
+	if (BN_cmp(a, BN_value_one()) <= 0)
+		return 0;
+
+	if (checks == BN_prime_checks)
+		checks = BN_prime_checks_for_size(BN_num_bits(a));
+
+	/* first look for small factors */
+	if (!BN_is_odd(a))
+		/* a is even => a is prime if and only if a == 2 */
+		return BN_is_word(a, 2);
+	if (do_trial_division) {
+		for (i = 1; i < NUMPRIMES; i++) {
+			BN_ULONG mod = BN_mod_word(a, primes[i]);
+			if (mod == (BN_ULONG)-1)
+				goto err;
+			if (mod == 0)
+				return 0;
+		}
+		if (!BN_GENCB_call(cb, 1, -1))
+			goto err;
+	}
+
+	if (ctx_passed != NULL)
+		ctx = ctx_passed;
+	else if ((ctx = BN_CTX_new()) == NULL)
+		goto err;
+	BN_CTX_start(ctx);
+
+	/* A := abs(a) */
+	if (a->neg) {
+		BIGNUM *t;
+		if ((t = BN_CTX_get(ctx)) == NULL)
+			goto err;
+		BN_copy(t, a);
+		t->neg = 0;
+		A = t;
+	} else
+		A = a;
+	if ((A1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((A1_odd = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((check = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	/* compute A1 := A - 1 */
+	if (!BN_copy(A1, A))
+		goto err;
+	if (!BN_sub_word(A1, 1))
+		goto err;
+	if (BN_is_zero(A1)) {
+		ret = 0;
+		goto err;
+	}
+
+	/* write  A1  as  A1_odd * 2^k */
+	k = 1;
+	while (!BN_is_bit_set(A1, k))
+		k++;
+	if (!BN_rshift(A1_odd, A1, k))
+		goto err;
+
+	/* Montgomery setup for computations mod A */
+	mont = BN_MONT_CTX_new();
+	if (mont == NULL)
+		goto err;
+	if (!BN_MONT_CTX_set(mont, A, ctx))
+		goto err;
+
+	for (i = 0; i < checks; i++) {
+		if (!BN_pseudo_rand_range(check, A1))
+			goto err;
+		if (!BN_add_word(check, 1))
+			goto err;
+		/* now 1 <= check < A */
+
+		j = witness(check, A, A1, A1_odd, k, ctx, mont);
+		if (j == -1)
+			goto err;
+		if (j) {
+			ret = 0;
+			goto err;
+		}
+		if (!BN_GENCB_call(cb, 1, i))
+			goto err;
+	}
+	ret = 1;
+
+err:
+	if (ctx != NULL) {
+		BN_CTX_end(ctx);
+		if (ctx_passed == NULL)
+			BN_CTX_free(ctx);
+	}
+	BN_MONT_CTX_free(mont);
+
+	return (ret);
+}
+
+static int
+witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, const BIGNUM *a1_odd,
+    int k, BN_CTX *ctx, BN_MONT_CTX *mont)
+{
+	if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont))
+		/* w := w^a1_odd mod a */
+		return -1;
+	if (BN_is_one(w))
+		return 0; /* probably prime */
+	if (BN_cmp(w, a1) == 0)
+		return 0; /* w == -1 (mod a),  'a' is probably prime */
+	while (--k) {
+		if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */
+			return -1;
+		if (BN_is_one(w))
+			return 1; /* 'a' is composite, otherwise a previous 'w' would
+			           * have been == -1 (mod 'a') */
+		if (BN_cmp(w, a1) == 0)
+			return 0; /* w == -1 (mod a), 'a' is probably prime */
+	}
+	/* If we get here, 'w' is the (a-1)/2-th power of the original 'w',
+	 * and it is neither -1 nor +1 -- so 'a' cannot be prime */
+	bn_check_top(w);
+	return 1;
+}
+
+static int
+probable_prime(BIGNUM *rnd, int bits)
+{
+	int i;
+	prime_t mods[NUMPRIMES];
+	BN_ULONG delta, maxdelta;
+
+again:
+	if (!BN_rand(rnd, bits, 1, 1))
+		return (0);
+	/* we now have a random number 'rand' to test. */
+	for (i = 1; i < NUMPRIMES; i++) {
+		BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]);
+		if (mod == (BN_ULONG)-1)
+			return (0);
+		mods[i] = (prime_t)mod;
+	}
+	maxdelta = BN_MASK2 - primes[NUMPRIMES - 1];
+	delta = 0;
+loop:
+	for (i = 1; i < NUMPRIMES; i++) {
+		/* check that rnd is not a prime and also
+		 * that gcd(rnd-1,primes) == 1 (except for 2) */
+		if (((mods[i] + delta) % primes[i]) <= 1) {
+			delta += 2;
+			if (delta > maxdelta)
+				goto again;
+			goto loop;
+		}
+	}
+	if (!BN_add_word(rnd, delta))
+		return (0);
+	bn_check_top(rnd);
+	return (1);
+}
+
+static int
+probable_prime_dh(BIGNUM *rnd, int bits, const BIGNUM *add, const BIGNUM *rem,
+    BN_CTX *ctx)
+{
+	int i, ret = 0;
+	BIGNUM *t1;
+
+	BN_CTX_start(ctx);
+	if ((t1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!BN_rand(rnd, bits, 0, 1))
+		goto err;
+
+	/* we need ((rnd-rem) % add) == 0 */
+
+	if (!BN_mod(t1, rnd, add, ctx))
+		goto err;
+	if (!BN_sub(rnd, rnd, t1))
+		goto err;
+	if (rem == NULL) {
+		if (!BN_add_word(rnd, 1))
+			goto err;
+	} else {
+		if (!BN_add(rnd, rnd, rem))
+			goto err;
+	}
+
+	/* we now have a random number 'rand' to test. */
+
+loop:
+	for (i = 1; i < NUMPRIMES; i++) {
+		/* check that rnd is a prime */
+		BN_LONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]);
+		if (mod == (BN_ULONG)-1)
+			goto err;
+		if (mod <= 1) {
+			if (!BN_add(rnd, rnd, add))
+				goto err;
+			goto loop;
+		}
+	}
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	bn_check_top(rnd);
+	return (ret);
+}
+
+static int
+probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
+    const BIGNUM *rem, BN_CTX *ctx)
+{
+	int i, ret = 0;
+	BIGNUM *t1, *qadd, *q;
+
+	bits--;
+	BN_CTX_start(ctx);
+	if ((t1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((q = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((qadd = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!BN_rshift1(qadd, padd))
+		goto err;
+
+	if (!BN_rand(q, bits, 0, 1))
+		goto err;
+
+	/* we need ((rnd-rem) % add) == 0 */
+	if (!BN_mod(t1, q,qadd, ctx))
+		goto err;
+	if (!BN_sub(q, q, t1))
+		goto err;
+	if (rem == NULL) {
+		if (!BN_add_word(q, 1))
+			goto err;
+	} else {
+		if (!BN_rshift1(t1, rem))
+			goto err;
+		if (!BN_add(q, q, t1))
+			goto err;
+	}
+
+	/* we now have a random number 'rand' to test. */
+	if (!BN_lshift1(p, q))
+		goto err;
+	if (!BN_add_word(p, 1))
+		goto err;
+
+loop:
+	for (i = 1; i < NUMPRIMES; i++) {
+		/* check that p and q are prime */
+		/* check that for p and q
+		 * gcd(p-1,primes) == 1 (except for 2) */
+		BN_ULONG pmod = BN_mod_word(p, (BN_ULONG)primes[i]);
+		BN_ULONG qmod = BN_mod_word(q, (BN_ULONG)primes[i]);
+		if (pmod == (BN_ULONG)-1 || qmod == (BN_ULONG)-1)
+			goto err;
+		if (pmod == 0 || qmod == 0) {
+			if (!BN_add(p, p, padd))
+				goto err;
+			if (!BN_add(q, q, qadd))
+				goto err;
+			goto loop;
+		}
+	}
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	bn_check_top(p);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/bn/bn_prime.h b/crypto/libressl/crypto/bn/bn_prime.h
new file mode 100644
index 0000000000..542263984c
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_prime.h
@@ -0,0 +1,319 @@
+/* $OpenBSD$ */
+/* Auto generated by bn_prime.pl */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#define NUMPRIMES 2048
+typedef unsigned short prime_t;
+static const prime_t primes[NUMPRIMES] = {
+	2,   3,   5,   7,  11,  13,  17,  19,
+	23,  29,  31,  37,  41,  43,  47,  53,
+	59,  61,  67,  71,  73,  79,  83,  89,
+	97, 101, 103, 107, 109, 113, 127, 131,
+	137, 139, 149, 151, 157, 163, 167, 173,
+	179, 181, 191, 193, 197, 199, 211, 223,
+	227, 229, 233, 239, 241, 251, 257, 263,
+	269, 271, 277, 281, 283, 293, 307, 311,
+	313, 317, 331, 337, 347, 349, 353, 359,
+	367, 373, 379, 383, 389, 397, 401, 409,
+	419, 421, 431, 433, 439, 443, 449, 457,
+	461, 463, 467, 479, 487, 491, 499, 503,
+	509, 521, 523, 541, 547, 557, 563, 569,
+	571, 577, 587, 593, 599, 601, 607, 613,
+	617, 619, 631, 641, 643, 647, 653, 659,
+	661, 673, 677, 683, 691, 701, 709, 719,
+	727, 733, 739, 743, 751, 757, 761, 769,
+	773, 787, 797, 809, 811, 821, 823, 827,
+	829, 839, 853, 857, 859, 863, 877, 881,
+	883, 887, 907, 911, 919, 929, 937, 941,
+	947, 953, 967, 971, 977, 983, 991, 997,
+	1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049,
+	1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097,
+	1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163,
+	1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223,
+	1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283,
+	1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321,
+	1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423,
+	1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459,
+	1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,
+	1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571,
+	1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619,
+	1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693,
+	1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747,
+	1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811,
+	1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877,
+	1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949,
+	1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003,
+	2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069,
+	2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129,
+	2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203,
+	2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267,
+	2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311,
+	2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377,
+	2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423,
+	2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503,
+	2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579,
+	2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657,
+	2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693,
+	2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741,
+	2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801,
+	2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861,
+	2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939,
+	2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011,
+	3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079,
+	3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167,
+	3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221,
+	3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301,
+	3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347,
+	3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413,
+	3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491,
+	3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541,
+	3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607,
+	3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671,
+	3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727,
+	3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797,
+	3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863,
+	3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923,
+	3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003,
+	4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057,
+	4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129,
+	4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211,
+	4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259,
+	4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337,
+	4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409,
+	4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481,
+	4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547,
+	4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621,
+	4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673,
+	4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751,
+	4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813,
+	4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909,
+	4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967,
+	4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011,
+	5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087,
+	5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167,
+	5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233,
+	5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309,
+	5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399,
+	5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443,
+	5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507,
+	5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573,
+	5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653,
+	5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711,
+	5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791,
+	5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849,
+	5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897,
+	5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007,
+	6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073,
+	6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133,
+	6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211,
+	6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271,
+	6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329,
+	6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379,
+	6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473,
+	6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563,
+	6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637,
+	6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701,
+	6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779,
+	6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833,
+	6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907,
+	6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971,
+	6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027,
+	7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121,
+	7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207,
+	7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253,
+	7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349,
+	7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457,
+	7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517,
+	7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561,
+	7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621,
+	7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691,
+	7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757,
+	7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853,
+	7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919,
+	7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009,
+	8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087,
+	8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161,
+	8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231,
+	8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291,
+	8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369,
+	8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443,
+	8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537,
+	8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609,
+	8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677,
+	8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731,
+	8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803,
+	8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861,
+	8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941,
+	8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011,
+	9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091,
+	9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161,
+	9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227,
+	9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311,
+	9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377,
+	9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433,
+	9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491,
+	9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587,
+	9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649,
+	9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733,
+	9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791,
+	9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857,
+	9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929,
+	9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037,
+	10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099,
+	10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163,
+	10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247,
+	10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303,
+	10313, 10321, 10331, 10333, 10337, 10343, 10357, 10369,
+	10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459,
+	10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531,
+	10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627,
+	10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691,
+	10709, 10711, 10723, 10729, 10733, 10739, 10753, 10771,
+	10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859,
+	10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937,
+	10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003,
+	11027, 11047, 11057, 11059, 11069, 11071, 11083, 11087,
+	11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161,
+	11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251,
+	11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317,
+	11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399,
+	11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483,
+	11489, 11491, 11497, 11503, 11519, 11527, 11549, 11551,
+	11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657,
+	11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731,
+	11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813,
+	11821, 11827, 11831, 11833, 11839, 11863, 11867, 11887,
+	11897, 11903, 11909, 11923, 11927, 11933, 11939, 11941,
+	11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011,
+	12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101,
+	12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161,
+	12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251,
+	12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323,
+	12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401,
+	12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473,
+	12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527,
+	12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589,
+	12601, 12611, 12613, 12619, 12637, 12641, 12647, 12653,
+	12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739,
+	12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821,
+	12823, 12829, 12841, 12853, 12889, 12893, 12899, 12907,
+	12911, 12917, 12919, 12923, 12941, 12953, 12959, 12967,
+	12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033,
+	13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109,
+	13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177,
+	13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259,
+	13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337,
+	13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421,
+	13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499,
+	13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597,
+	13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681,
+	13687, 13691, 13693, 13697, 13709, 13711, 13721, 13723,
+	13729, 13751, 13757, 13759, 13763, 13781, 13789, 13799,
+	13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879,
+	13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933,
+	13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033,
+	14051, 14057, 14071, 14081, 14083, 14087, 14107, 14143,
+	14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221,
+	14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323,
+	14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407,
+	14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461,
+	14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549,
+	14551, 14557, 14561, 14563, 14591, 14593, 14621, 14627,
+	14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699,
+	14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753,
+	14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821,
+	14827, 14831, 14843, 14851, 14867, 14869, 14879, 14887,
+	14891, 14897, 14923, 14929, 14939, 14947, 14951, 14957,
+	14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073,
+	15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137,
+	15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217,
+	15227, 15233, 15241, 15259, 15263, 15269, 15271, 15277,
+	15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331,
+	15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401,
+	15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473,
+	15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569,
+	15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643,
+	15647, 15649, 15661, 15667, 15671, 15679, 15683, 15727,
+	15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773,
+	15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859,
+	15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919,
+	15923, 15937, 15959, 15971, 15973, 15991, 16001, 16007,
+	16033, 16057, 16061, 16063, 16067, 16069, 16073, 16087,
+	16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183,
+	16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249,
+	16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349,
+	16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427,
+	16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493,
+	16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603,
+	16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661,
+	16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747,
+	16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843,
+	16871, 16879, 16883, 16889, 16901, 16903, 16921, 16927,
+	16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993,
+	17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053,
+	17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159,
+	17167, 17183, 17189, 17191, 17203, 17207, 17209, 17231,
+	17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327,
+	17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389,
+	17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467,
+	17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519,
+	17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599,
+	17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683,
+	17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783,
+	17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863,
+};
diff --git a/crypto/libressl/crypto/bn/bn_print.c b/crypto/libressl/crypto/bn/bn_print.c
new file mode 100644
index 0000000000..8df23a7836
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_print.c
@@ -0,0 +1,407 @@
+/* $OpenBSD: bn_print.c,v 1.28 2015/09/28 18:58:33 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include "bn_lcl.h"
+
+static const char Hex[]="0123456789ABCDEF";
+
+/* Must 'free' the returned data */
+char *
+BN_bn2hex(const BIGNUM *a)
+{
+	int i, j, v, z = 0;
+	char *buf;
+	char *p;
+
+	buf = malloc(BN_is_negative(a) + a->top * BN_BYTES * 2 + 2);
+	if (buf == NULL) {
+		BNerr(BN_F_BN_BN2HEX, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	p = buf;
+	if (BN_is_negative(a))
+		*p++ = '-';
+	if (BN_is_zero(a))
+		*p++ = '0';
+	for (i = a->top - 1; i >=0; i--) {
+		for (j = BN_BITS2 - 8; j >= 0; j -= 8) {
+			/* strip leading zeros */
+			v = ((int)(a->d[i] >> (long)j)) & 0xff;
+			if (z || (v != 0)) {
+				*p++ = Hex[v >> 4];
+				*p++ = Hex[v & 0x0f];
+				z = 1;
+			}
+		}
+	}
+	*p = '\0';
+
+err:
+	return (buf);
+}
+
+/* Must 'free' the returned data */
+char *
+BN_bn2dec(const BIGNUM *a)
+{
+	int i = 0, num, ok = 0;
+	char *buf = NULL;
+	char *p;
+	BIGNUM *t = NULL;
+	BN_ULONG *bn_data = NULL, *lp;
+
+	if (BN_is_zero(a)) {
+		buf = malloc(BN_is_negative(a) + 2);
+		if (buf == NULL) {
+			BNerr(BN_F_BN_BN2DEC, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		p = buf;
+		if (BN_is_negative(a))
+			*p++ = '-';
+		*p++ = '0';
+		*p++ = '\0';
+		return (buf);
+	}
+
+	/* get an upper bound for the length of the decimal integer
+	 * num <= (BN_num_bits(a) + 1) * log(2)
+	 *     <= 3 * BN_num_bits(a) * 0.1001 + log(2) + 1     (rounding error)
+	 *     <= BN_num_bits(a)/10 + BN_num_bits/1000 + 1 + 1
+	 */
+	i = BN_num_bits(a) * 3;
+	num = (i / 10 + i / 1000 + 1) + 1;
+	bn_data = reallocarray(NULL, num / BN_DEC_NUM + 1, sizeof(BN_ULONG));
+	buf = malloc(num + 3);
+	if ((buf == NULL) || (bn_data == NULL)) {
+		BNerr(BN_F_BN_BN2DEC, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	if ((t = BN_dup(a)) == NULL)
+		goto err;
+
+#define BUF_REMAIN (num+3 - (size_t)(p - buf))
+	p = buf;
+	lp = bn_data;
+	if (BN_is_negative(t))
+		*p++ = '-';
+
+	i = 0;
+	while (!BN_is_zero(t)) {
+		*lp = BN_div_word(t, BN_DEC_CONV);
+		lp++;
+	}
+	lp--;
+	/* We now have a series of blocks, BN_DEC_NUM chars
+	 * in length, where the last one needs truncation.
+	 * The blocks need to be reversed in order. */
+	snprintf(p, BUF_REMAIN, BN_DEC_FMT1, *lp);
+	while (*p)
+		p++;
+	while (lp != bn_data) {
+		lp--;
+		snprintf(p, BUF_REMAIN, BN_DEC_FMT2, *lp);
+		while (*p)
+			p++;
+	}
+	ok = 1;
+
+err:
+	free(bn_data);
+	BN_free(t);
+	if (!ok && buf) {
+		free(buf);
+		buf = NULL;
+	}
+
+	return (buf);
+}
+
+int
+BN_hex2bn(BIGNUM **bn, const char *a)
+{
+	BIGNUM *ret = NULL;
+	BN_ULONG l = 0;
+	int neg = 0, h, m, i,j, k, c;
+	int num;
+
+	if ((a == NULL) || (*a == '\0'))
+		return (0);
+
+	if (*a == '-') {
+		neg = 1;
+		a++;
+	}
+
+	for (i = 0; i <= (INT_MAX / 4) && isxdigit((unsigned char)a[i]); i++)
+		;
+	if (i > INT_MAX / 4)
+		goto err;
+
+	num = i + neg;
+	if (bn == NULL)
+		return (num);
+
+	/* a is the start of the hex digits, and it is 'i' long */
+	if (*bn == NULL) {
+		if ((ret = BN_new()) == NULL)
+			return (0);
+	} else {
+		ret= *bn;
+		BN_zero(ret);
+	}
+
+	/* i is the number of hex digits */
+	if (bn_expand(ret, i * 4) == NULL)
+		goto err;
+
+	j = i; /* least significant 'hex' */
+	m = 0;
+	h = 0;
+	while (j > 0) {
+		m = ((BN_BYTES*2) <= j) ? (BN_BYTES * 2) : j;
+		l = 0;
+		for (;;) {
+			c = a[j - m];
+			if ((c >= '0') && (c <= '9'))
+				k = c - '0';
+			else if ((c >= 'a') && (c <= 'f'))
+				k = c - 'a' + 10;
+			else if ((c >= 'A') && (c <= 'F'))
+				k = c - 'A' + 10;
+			else
+				k = 0; /* paranoia */
+			l = (l << 4) | k;
+
+			if (--m <= 0) {
+				ret->d[h++] = l;
+				break;
+			}
+		}
+		j -= (BN_BYTES * 2);
+	}
+	ret->top = h;
+	bn_correct_top(ret);
+	ret->neg = neg;
+
+	*bn = ret;
+	bn_check_top(ret);
+	return (num);
+
+err:
+	if (*bn == NULL)
+		BN_free(ret);
+	return (0);
+}
+
+int
+BN_dec2bn(BIGNUM **bn, const char *a)
+{
+	BIGNUM *ret = NULL;
+	BN_ULONG l = 0;
+	int neg = 0, i, j;
+	int num;
+
+	if ((a == NULL) || (*a == '\0'))
+		return (0);
+	if (*a == '-') {
+		neg = 1;
+		a++;
+	}
+
+	for (i = 0; i <= (INT_MAX / 4) && isdigit((unsigned char)a[i]); i++)
+		;
+	if (i > INT_MAX / 4)
+		goto err;
+
+	num = i + neg;
+	if (bn == NULL)
+		return (num);
+
+	/* a is the start of the digits, and it is 'i' long.
+	 * We chop it into BN_DEC_NUM digits at a time */
+	if (*bn == NULL) {
+		if ((ret = BN_new()) == NULL)
+			return (0);
+	} else {
+		ret = *bn;
+		BN_zero(ret);
+	}
+
+	/* i is the number of digits, a bit of an over expand */
+	if (bn_expand(ret, i * 4) == NULL)
+		goto err;
+
+	j = BN_DEC_NUM - (i % BN_DEC_NUM);
+	if (j == BN_DEC_NUM)
+		j = 0;
+	l = 0;
+	while (*a) {
+		l *= 10;
+		l += *a - '0';
+		a++;
+		if (++j == BN_DEC_NUM) {
+			BN_mul_word(ret, BN_DEC_CONV);
+			BN_add_word(ret, l);
+			l = 0;
+			j = 0;
+		}
+	}
+	ret->neg = neg;
+
+	bn_correct_top(ret);
+	*bn = ret;
+	bn_check_top(ret);
+	return (num);
+
+err:
+	if (*bn == NULL)
+		BN_free(ret);
+	return (0);
+}
+
+int
+BN_asc2bn(BIGNUM **bn, const char *a)
+{
+	const char *p = a;
+	if (*p == '-')
+		p++;
+
+	if (p[0] == '0' && (p[1] == 'X' || p[1] == 'x')) {
+		if (!BN_hex2bn(bn, p + 2))
+			return 0;
+	} else {
+		if (!BN_dec2bn(bn, p))
+			return 0;
+	}
+	if (*a == '-')
+		(*bn)->neg = 1;
+	return 1;
+}
+
+#ifndef OPENSSL_NO_BIO
+int
+BN_print_fp(FILE *fp, const BIGNUM *a)
+{
+	BIO *b;
+	int ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL)
+		return (0);
+	BIO_set_fp(b, fp, BIO_NOCLOSE);
+	ret = BN_print(b, a);
+	BIO_free(b);
+	return (ret);
+}
+
+int
+BN_print(BIO *bp, const BIGNUM *a)
+{
+	int i, j, v, z = 0;
+	int ret = 0;
+
+	if ((a->neg) && (BIO_write(bp, "-", 1) != 1))
+		goto end;
+	if (BN_is_zero(a) && (BIO_write(bp, "0", 1) != 1))
+		goto end;
+	for (i = a->top - 1; i >= 0; i--) {
+		for (j = BN_BITS2 - 4; j >= 0; j -= 4) {
+			/* strip leading zeros */
+			v = ((int)(a->d[i] >> (long)j)) & 0x0f;
+			if (z || (v != 0)) {
+				if (BIO_write(bp, &(Hex[v]), 1) != 1)
+					goto end;
+				z = 1;
+			}
+		}
+	}
+	ret = 1;
+
+end:
+	return (ret);
+}
+#endif
+
+char *
+BN_options(void)
+{
+	static int init = 0;
+	static char data[16];
+
+	if (!init) {
+		init++;
+#ifdef BN_LLONG
+		snprintf(data,sizeof data, "bn(%d,%d)",
+		    (int)sizeof(BN_ULLONG) * 8, (int)sizeof(BN_ULONG) * 8);
+#else
+		snprintf(data,sizeof data, "bn(%d,%d)",
+		    (int)sizeof(BN_ULONG) * 8, (int)sizeof(BN_ULONG) * 8);
+#endif
+	}
+	return (data);
+}
diff --git a/crypto/libressl/crypto/bn/bn_rand.c b/crypto/libressl/crypto/bn/bn_rand.c
new file mode 100644
index 0000000000..336e280a7e
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_rand.c
@@ -0,0 +1,291 @@
+/* $OpenBSD: bn_rand.c,v 1.17 2015/02/19 06:10:29 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "bn_lcl.h"
+
+static int
+bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
+{
+	unsigned char *buf = NULL;
+	int ret = 0, bit, bytes, mask;
+
+	if (rnd == NULL) {
+		BNerr(BN_F_BNRAND, ERR_R_PASSED_NULL_PARAMETER);
+		return (0);
+	}
+
+	if (bits == 0) {
+		BN_zero(rnd);
+		return (1);
+	}
+
+	bytes = (bits + 7) / 8;
+	bit = (bits - 1) % 8;
+	mask = 0xff << (bit + 1);
+
+	buf = malloc(bytes);
+	if (buf == NULL) {
+		BNerr(BN_F_BNRAND, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	/* make a random number and set the top and bottom bits */
+	arc4random_buf(buf, bytes);
+
+#if 1
+	if (pseudorand == 2) {
+		/* generate patterns that are more likely to trigger BN
+		   library bugs */
+		int i;
+		unsigned char c;
+
+		for (i = 0; i < bytes; i++) {
+			arc4random_buf(&c, 1);
+			if (c >= 128 && i > 0)
+				buf[i] = buf[i - 1];
+			else if (c < 42)
+				buf[i] = 0;
+			else if (c < 84)
+				buf[i] = 255;
+		}
+	}
+#endif
+
+	if (top != -1) {
+		if (top) {
+			if (bit == 0) {
+				buf[0] = 1;
+				buf[1] |= 0x80;
+			} else {
+				buf[0] |= (3 << (bit - 1));
+			}
+		} else {
+			buf[0] |= (1 << bit);
+		}
+	}
+	buf[0] &= ~mask;
+	if (bottom) /* set bottom bit if requested */
+		buf[bytes - 1] |= 1;
+	if (BN_bin2bn(buf, bytes, rnd) == NULL)
+		goto err;
+	ret = 1;
+
+err:
+	if (buf != NULL) {
+		explicit_bzero(buf, bytes);
+		free(buf);
+	}
+	bn_check_top(rnd);
+	return (ret);
+}
+
+int    
+BN_rand(BIGNUM *rnd, int bits, int top, int bottom)
+{
+	return bnrand(0, rnd, bits, top, bottom);
+}
+
+int    
+BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom)
+{
+	return bnrand(1, rnd, bits, top, bottom);
+}
+
+#if 1
+int    
+BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom)
+{
+	return bnrand(2, rnd, bits, top, bottom);
+}
+#endif
+
+
+/* random number r:  0 <= r < range */
+static int
+bn_rand_range(int pseudo, BIGNUM *r, const BIGNUM *range)
+{
+	int (*bn_rand)(BIGNUM *, int, int, int) = pseudo ? BN_pseudo_rand : BN_rand;
+	int n;
+	int count = 100;
+
+	if (range->neg || BN_is_zero(range)) {
+		BNerr(BN_F_BN_RAND_RANGE, BN_R_INVALID_RANGE);
+		return 0;
+	}
+
+	n = BN_num_bits(range); /* n > 0 */
+
+	/* BN_is_bit_set(range, n - 1) always holds */
+
+	if (n == 1)
+		BN_zero(r);
+	else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3)) {
+		/* range = 100..._2,
+		 * so  3*range (= 11..._2)  is exactly one bit longer than  range */
+		do {
+			if (!bn_rand(r, n + 1, -1, 0))
+				return 0;
+			/* If  r < 3*range,  use  r := r MOD range
+			 * (which is either  r, r - range,  or  r - 2*range).
+			 * Otherwise, iterate once more.
+			 * Since  3*range = 11..._2, each iteration succeeds with
+			 * probability >= .75. */
+			if (BN_cmp(r, range) >= 0) {
+				if (!BN_sub(r, r, range))
+					return 0;
+				if (BN_cmp(r, range) >= 0)
+					if (!BN_sub(r, r, range))
+						return 0;
+			}
+
+			if (!--count) {
+				BNerr(BN_F_BN_RAND_RANGE,
+				    BN_R_TOO_MANY_ITERATIONS);
+				return 0;
+			}
+
+		} while (BN_cmp(r, range) >= 0);
+	} else {
+		do {
+			/* range = 11..._2  or  range = 101..._2 */
+			if (!bn_rand(r, n, -1, 0))
+				return 0;
+
+			if (!--count) {
+				BNerr(BN_F_BN_RAND_RANGE,
+				    BN_R_TOO_MANY_ITERATIONS);
+				return 0;
+			}
+		} while (BN_cmp(r, range) >= 0);
+	}
+
+	bn_check_top(r);
+	return 1;
+}
+
+int
+BN_rand_range(BIGNUM *r, const BIGNUM *range)
+{
+	return bn_rand_range(0, r, range);
+}
+
+int
+BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range)
+{
+	return bn_rand_range(1, r, range);
+}
diff --git a/crypto/libressl/crypto/bn/bn_recp.c b/crypto/libressl/crypto/bn/bn_recp.c
new file mode 100644
index 0000000000..412474dea9
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_recp.c
@@ -0,0 +1,263 @@
+/* $OpenBSD: bn_recp.c,v 1.12 2015/03/21 08:05:20 doug Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include "bn_lcl.h"
+
+void
+BN_RECP_CTX_init(BN_RECP_CTX *recp)
+{
+	BN_init(&(recp->N));
+	BN_init(&(recp->Nr));
+	recp->num_bits = 0;
+	recp->flags = 0;
+}
+
+BN_RECP_CTX *
+BN_RECP_CTX_new(void)
+{
+	BN_RECP_CTX *ret;
+
+	if ((ret = malloc(sizeof(BN_RECP_CTX))) == NULL)
+		return (NULL);
+
+	BN_RECP_CTX_init(ret);
+	ret->flags = BN_FLG_MALLOCED;
+	return (ret);
+}
+
+void
+BN_RECP_CTX_free(BN_RECP_CTX *recp)
+{
+	if (recp == NULL)
+		return;
+
+	BN_free(&(recp->N));
+	BN_free(&(recp->Nr));
+	if (recp->flags & BN_FLG_MALLOCED)
+		free(recp);
+}
+
+int
+BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx)
+{
+	if (!BN_copy(&(recp->N), d))
+		return 0;
+	BN_zero(&(recp->Nr));
+	recp->num_bits = BN_num_bits(d);
+	recp->shift = 0;
+	return (1);
+}
+
+int
+BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
+    BN_RECP_CTX *recp, BN_CTX *ctx)
+{
+	int ret = 0;
+	BIGNUM *a;
+	const BIGNUM *ca;
+
+	BN_CTX_start(ctx);
+	if ((a = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if (y != NULL) {
+		if (x == y) {
+			if (!BN_sqr(a, x, ctx))
+				goto err;
+		} else {
+			if (!BN_mul(a, x, y, ctx))
+				goto err;
+		}
+		ca = a;
+	} else
+		ca = x; /* Just do the mod */
+
+	ret = BN_div_recp(NULL, r, ca, recp, ctx);
+
+err:
+	BN_CTX_end(ctx);
+	bn_check_top(r);
+	return (ret);
+}
+
+int
+BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, BN_RECP_CTX *recp,
+    BN_CTX *ctx)
+{
+	int i, j, ret = 0;
+	BIGNUM *a, *b, *d, *r;
+
+	BN_CTX_start(ctx);
+	a = BN_CTX_get(ctx);
+	b = BN_CTX_get(ctx);
+	if (dv != NULL)
+		d = dv;
+	else
+		d = BN_CTX_get(ctx);
+	if (rem != NULL)
+		r = rem;
+	else
+		r = BN_CTX_get(ctx);
+	if (a == NULL || b == NULL || d == NULL || r == NULL)
+		goto err;
+
+	if (BN_ucmp(m, &(recp->N)) < 0) {
+		BN_zero(d);
+		if (!BN_copy(r, m)) {
+			BN_CTX_end(ctx);
+			return 0;
+		}
+		BN_CTX_end(ctx);
+		return (1);
+	}
+
+	/* We want the remainder
+	 * Given input of ABCDEF / ab
+	 * we need multiply ABCDEF by 3 digests of the reciprocal of ab
+	 *
+	 */
+
+	/* i := max(BN_num_bits(m), 2*BN_num_bits(N)) */
+	i = BN_num_bits(m);
+	j = recp->num_bits << 1;
+	if (j > i)
+		i = j;
+
+	/* Nr := round(2^i / N) */
+	if (i != recp->shift)
+		recp->shift = BN_reciprocal(&(recp->Nr), &(recp->N), i, ctx);
+
+	/* BN_reciprocal returns i, or -1 for an error */
+	if (recp->shift == -1)
+		goto err;
+
+	/* d := |round(round(m / 2^BN_num_bits(N)) * recp->Nr / 2^(i - BN_num_bits(N)))|
+	 *    = |round(round(m / 2^BN_num_bits(N)) * round(2^i / N) / 2^(i - BN_num_bits(N)))|
+	 *   <= |(m / 2^BN_num_bits(N)) * (2^i / N) * (2^BN_num_bits(N) / 2^i)|
+	 *    = |m/N|
+	 */
+	if (!BN_rshift(a, m, recp->num_bits))
+		goto err;
+	if (!BN_mul(b, a,&(recp->Nr), ctx))
+		goto err;
+	if (!BN_rshift(d, b, i - recp->num_bits))
+		goto err;
+	d->neg = 0;
+
+	if (!BN_mul(b, &(recp->N), d, ctx))
+		goto err;
+	if (!BN_usub(r, m, b))
+		goto err;
+	r->neg = 0;
+
+#if 1
+	j = 0;
+	while (BN_ucmp(r, &(recp->N)) >= 0) {
+		if (j++ > 2) {
+			BNerr(BN_F_BN_DIV_RECP, BN_R_BAD_RECIPROCAL);
+			goto err;
+		}
+		if (!BN_usub(r, r, &(recp->N)))
+			goto err;
+		if (!BN_add_word(d, 1))
+			goto err;
+	}
+#endif
+
+	r->neg = BN_is_zero(r) ? 0 : m->neg;
+	d->neg = m->neg^recp->N.neg;
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	bn_check_top(dv);
+	bn_check_top(rem);
+	return (ret);
+}
+
+/* len is the expected size of the result
+ * We actually calculate with an extra word of precision, so
+ * we can do faster division if the remainder is not required.
+ */
+/* r := 2^len / m */
+int
+BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx)
+{
+	int ret = -1;
+	BIGNUM *t;
+
+	BN_CTX_start(ctx);
+	if ((t = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!BN_set_bit(t, len))
+		goto err;
+
+	if (!BN_div(r, NULL, t,m, ctx))
+		goto err;
+
+	ret = len;
+
+err:
+	bn_check_top(r);
+	BN_CTX_end(ctx);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/bn/bn_shift.c b/crypto/libressl/crypto/bn/bn_shift.c
new file mode 100644
index 0000000000..4ece0367fe
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_shift.c
@@ -0,0 +1,218 @@
+/* $OpenBSD: bn_shift.c,v 1.12 2014/07/11 08:44:48 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include "bn_lcl.h"
+
+int
+BN_lshift1(BIGNUM *r, const BIGNUM *a)
+{
+	BN_ULONG *ap, *rp, t, c;
+	int i;
+
+	bn_check_top(r);
+	bn_check_top(a);
+
+	if (r != a) {
+		r->neg = a->neg;
+		if (bn_wexpand(r, a->top + 1) == NULL)
+			return (0);
+		r->top = a->top;
+	} else {
+		if (bn_wexpand(r, a->top + 1) == NULL)
+			return (0);
+	}
+	ap = a->d;
+	rp = r->d;
+	c = 0;
+	for (i = 0; i < a->top; i++) {
+		t= *(ap++);
+		*(rp++) = ((t << 1) | c) & BN_MASK2;
+		c = (t & BN_TBIT) ? 1 : 0;
+	}
+	if (c) {
+		*rp = 1;
+		r->top++;
+	}
+	bn_check_top(r);
+	return (1);
+}
+
+int
+BN_rshift1(BIGNUM *r, const BIGNUM *a)
+{
+	BN_ULONG *ap, *rp, t, c;
+	int i, j;
+
+	bn_check_top(r);
+	bn_check_top(a);
+
+	if (BN_is_zero(a)) {
+		BN_zero(r);
+		return (1);
+	}
+	i = a->top;
+	ap = a->d;
+	j = i - (ap[i - 1]==1);
+	if (a != r) {
+		if (bn_wexpand(r, j) == NULL)
+			return (0);
+		r->neg = a->neg;
+	}
+	rp = r->d;
+	t = ap[--i];
+	c = (t & 1) ? BN_TBIT : 0;
+	if (t >>= 1)
+		rp[i] = t;
+	while (i > 0) {
+		t = ap[--i];
+		rp[i] = ((t >> 1) & BN_MASK2) | c;
+		c = (t & 1) ? BN_TBIT : 0;
+	}
+	r->top = j;
+	bn_check_top(r);
+	return (1);
+}
+
+int
+BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
+{
+	int i, nw, lb, rb;
+	BN_ULONG *t, *f;
+	BN_ULONG l;
+
+	bn_check_top(r);
+	bn_check_top(a);
+
+	r->neg = a->neg;
+	nw = n / BN_BITS2;
+	if (bn_wexpand(r, a->top + nw + 1) == NULL)
+		return (0);
+	lb = n % BN_BITS2;
+	rb = BN_BITS2 - lb;
+	f = a->d;
+	t = r->d;
+	t[a->top + nw] = 0;
+	if (lb == 0)
+		for (i = a->top - 1; i >= 0; i--)
+			t[nw + i] = f[i];
+	else
+		for (i = a->top - 1; i >= 0; i--) {
+			l = f[i];
+			t[nw + i + 1] |= (l >> rb) & BN_MASK2;
+			t[nw + i] = (l << lb) & BN_MASK2;
+		}
+	memset(t, 0, nw * sizeof(t[0]));
+/*	for (i=0; itop = a->top + nw + 1;
+	bn_correct_top(r);
+	bn_check_top(r);
+	return (1);
+}
+
+int
+BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
+{
+	int i, j, nw, lb, rb;
+	BN_ULONG *t, *f;
+	BN_ULONG l, tmp;
+
+	bn_check_top(r);
+	bn_check_top(a);
+
+	nw = n / BN_BITS2;
+	rb = n % BN_BITS2;
+	lb = BN_BITS2 - rb;
+	if (nw >= a->top || a->top == 0) {
+		BN_zero(r);
+		return (1);
+	}
+	i = (BN_num_bits(a) - n + (BN_BITS2 - 1)) / BN_BITS2;
+	if (r != a) {
+		r->neg = a->neg;
+		if (bn_wexpand(r, i) == NULL)
+			return (0);
+	} else {
+		if (n == 0)
+			return 1; /* or the copying loop will go berserk */
+	}
+
+	f = &(a->d[nw]);
+	t = r->d;
+	j = a->top - nw;
+	r->top = i;
+
+	if (rb == 0) {
+		for (i = j; i != 0; i--)
+			*(t++) = *(f++);
+	} else {
+		l = *(f++);
+		for (i = j - 1; i != 0; i--) {
+			tmp = (l >> rb) & BN_MASK2;
+			l = *(f++);
+			*(t++) = (tmp|(l << lb)) & BN_MASK2;
+		}
+		if ((l = (l >> rb) & BN_MASK2))
+			*(t) = l;
+	}
+	bn_check_top(r);
+	return (1);
+}
diff --git a/crypto/libressl/crypto/bn/bn_sqr.c b/crypto/libressl/crypto/bn/bn_sqr.c
new file mode 100644
index 0000000000..16cc745d7b
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_sqr.c
@@ -0,0 +1,286 @@
+/* $OpenBSD: bn_sqr.c,v 1.11 2014/07/11 13:26:31 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include "bn_lcl.h"
+
+/* r must not be a */
+/* I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96 */
+int
+BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
+{
+	int max, al;
+	int ret = 0;
+	BIGNUM *tmp, *rr;
+
+#ifdef BN_COUNT
+	fprintf(stderr, "BN_sqr %d * %d\n", a->top, a->top);
+#endif
+	bn_check_top(a);
+
+	al = a->top;
+	if (al <= 0) {
+		r->top = 0;
+		r->neg = 0;
+		return 1;
+	}
+
+	BN_CTX_start(ctx);
+	rr = (a != r) ? r : BN_CTX_get(ctx);
+	tmp = BN_CTX_get(ctx);
+	if (rr == NULL || tmp == NULL)
+		goto err;
+
+	max = 2 * al; /* Non-zero (from above) */
+	if (bn_wexpand(rr, max) == NULL)
+		goto err;
+
+	if (al == 4) {
+#ifndef BN_SQR_COMBA
+		BN_ULONG t[8];
+		bn_sqr_normal(rr->d, a->d, 4, t);
+#else
+		bn_sqr_comba4(rr->d, a->d);
+#endif
+	} else if (al == 8) {
+#ifndef BN_SQR_COMBA
+		BN_ULONG t[16];
+		bn_sqr_normal(rr->d, a->d, 8, t);
+#else
+		bn_sqr_comba8(rr->d, a->d);
+#endif
+	} else {
+#if defined(BN_RECURSION)
+		if (al < BN_SQR_RECURSIVE_SIZE_NORMAL) {
+			BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL*2];
+			bn_sqr_normal(rr->d, a->d, al, t);
+		} else {
+			int j, k;
+
+			j = BN_num_bits_word((BN_ULONG)al);
+			j = 1 << (j - 1);
+			k = j + j;
+			if (al == j) {
+				if (bn_wexpand(tmp, k * 2) == NULL)
+					goto err;
+				bn_sqr_recursive(rr->d, a->d, al, tmp->d);
+			} else {
+				if (bn_wexpand(tmp, max) == NULL)
+					goto err;
+				bn_sqr_normal(rr->d, a->d, al, tmp->d);
+			}
+		}
+#else
+		if (bn_wexpand(tmp, max) == NULL)
+			goto err;
+		bn_sqr_normal(rr->d, a->d, al, tmp->d);
+#endif
+	}
+
+	rr->neg = 0;
+	/* If the most-significant half of the top word of 'a' is zero, then
+	 * the square of 'a' will max-1 words. */
+	if (a->d[al - 1] == (a->d[al - 1] & BN_MASK2l))
+		rr->top = max - 1;
+	else
+		rr->top = max;
+	if (rr != r)
+		BN_copy(r, rr);
+	ret = 1;
+
+err:
+	bn_check_top(rr);
+	bn_check_top(tmp);
+	BN_CTX_end(ctx);
+	return (ret);
+}
+
+/* tmp must have 2*n words */
+void
+bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
+{
+	int i, j, max;
+	const BN_ULONG *ap;
+	BN_ULONG *rp;
+
+	max = n * 2;
+	ap = a;
+	rp = r;
+	rp[0] = rp[max - 1] = 0;
+	rp++;
+	j = n;
+
+	if (--j > 0) {
+		ap++;
+		rp[j] = bn_mul_words(rp, ap, j, ap[-1]);
+		rp += 2;
+	}
+
+	for (i = n - 2; i > 0; i--) {
+		j--;
+		ap++;
+		rp[j] = bn_mul_add_words(rp, ap, j, ap[-1]);
+		rp += 2;
+	}
+
+	bn_add_words(r, r, r, max);
+
+	/* There will not be a carry */
+
+	bn_sqr_words(tmp, a, n);
+
+	bn_add_words(r, r, tmp, max);
+}
+
+#ifdef BN_RECURSION
+/* r is 2*n words in size,
+ * a and b are both n words in size.    (There's not actually a 'b' here ...)
+ * n must be a power of 2.
+ * We multiply and return the result.
+ * t must be 2*n words in size
+ * We calculate
+ * a[0]*b[0]
+ * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
+ * a[1]*b[1]
+ */
+void
+bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t)
+{
+	int n = n2 / 2;
+	int zero, c1;
+	BN_ULONG ln, lo, *p;
+
+#ifdef BN_COUNT
+	fprintf(stderr, " bn_sqr_recursive %d * %d\n", n2, n2);
+#endif
+	if (n2 == 4) {
+#ifndef BN_SQR_COMBA
+		bn_sqr_normal(r, a, 4, t);
+#else
+		bn_sqr_comba4(r, a);
+#endif
+		return;
+	} else if (n2 == 8) {
+#ifndef BN_SQR_COMBA
+		bn_sqr_normal(r, a, 8, t);
+#else
+		bn_sqr_comba8(r, a);
+#endif
+		return;
+	}
+	if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL) {
+		bn_sqr_normal(r, a, n2, t);
+		return;
+	}
+	/* r=(a[0]-a[1])*(a[1]-a[0]) */
+	c1 = bn_cmp_words(a, &(a[n]), n);
+	zero = 0;
+	if (c1 > 0)
+		bn_sub_words(t, a, &(a[n]), n);
+	else if (c1 < 0)
+		bn_sub_words(t, &(a[n]), a, n);
+	else
+		zero = 1;
+
+	/* The result will always be negative unless it is zero */
+	p = &(t[n2*2]);
+
+	if (!zero)
+		bn_sqr_recursive(&(t[n2]), t, n, p);
+	else
+		memset(&(t[n2]), 0, n2 * sizeof(BN_ULONG));
+	bn_sqr_recursive(r, a, n, p);
+	bn_sqr_recursive(&(r[n2]), &(a[n]), n, p);
+
+	/* t[32] holds (a[0]-a[1])*(a[1]-a[0]), it is negative or zero
+	 * r[10] holds (a[0]*b[0])
+	 * r[32] holds (b[1]*b[1])
+	 */
+
+	c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
+
+	/* t[32] is negative */
+	c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
+
+	/* t[32] holds (a[0]-a[1])*(a[1]-a[0])+(a[0]*a[0])+(a[1]*a[1])
+	 * r[10] holds (a[0]*a[0])
+	 * r[32] holds (a[1]*a[1])
+	 * c1 holds the carry bits
+	 */
+	c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
+	if (c1) {
+		p = &(r[n + n2]);
+		lo= *p;
+		ln = (lo + c1) & BN_MASK2;
+		*p = ln;
+
+		/* The overflow will stop before we over write
+		 * words we should not overwrite */
+		if (ln < (BN_ULONG)c1) {
+			do {
+				p++;
+				lo= *p;
+				ln = (lo + 1) & BN_MASK2;
+				*p = ln;
+			} while (ln == 0);
+		}
+	}
+}
+#endif
diff --git a/crypto/libressl/crypto/bn/bn_sqrt.c b/crypto/libressl/crypto/bn/bn_sqrt.c
new file mode 100644
index 0000000000..07e897a210
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_sqrt.c
@@ -0,0 +1,405 @@
+/* $OpenBSD: bn_sqrt.c,v 1.5 2014/07/11 08:44:48 jsing Exp $ */
+/* Written by Lenka Fibikova 
+ * and Bodo Moeller for the OpenSSL project. */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include "bn_lcl.h"
+
+BIGNUM *
+BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+/* Returns 'ret' such that
+ *      ret^2 == a (mod p),
+ * using the Tonelli/Shanks algorithm (cf. Henri Cohen, "A Course
+ * in Algebraic Computational Number Theory", algorithm 1.5.1).
+ * 'p' must be prime!
+ */
+{
+	BIGNUM *ret = in;
+	int err = 1;
+	int r;
+	BIGNUM *A, *b, *q, *t, *x, *y;
+	int e, i, j;
+
+	if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) {
+		if (BN_abs_is_word(p, 2)) {
+			if (ret == NULL)
+				ret = BN_new();
+			if (ret == NULL)
+				goto end;
+			if (!BN_set_word(ret, BN_is_bit_set(a, 0))) {
+				if (ret != in)
+					BN_free(ret);
+				return NULL;
+			}
+			bn_check_top(ret);
+			return ret;
+		}
+
+		BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
+		return (NULL);
+	}
+
+	if (BN_is_zero(a) || BN_is_one(a)) {
+		if (ret == NULL)
+			ret = BN_new();
+		if (ret == NULL)
+			goto end;
+		if (!BN_set_word(ret, BN_is_one(a))) {
+			if (ret != in)
+				BN_free(ret);
+			return NULL;
+		}
+		bn_check_top(ret);
+		return ret;
+	}
+
+	BN_CTX_start(ctx);
+	if ((A = BN_CTX_get(ctx)) == NULL)
+		goto end;
+	if ((b = BN_CTX_get(ctx)) == NULL)
+		goto end;
+	if ((q = BN_CTX_get(ctx)) == NULL)
+		goto end;
+	if ((t = BN_CTX_get(ctx)) == NULL)
+		goto end;
+	if ((x = BN_CTX_get(ctx)) == NULL)
+		goto end;
+	if ((y = BN_CTX_get(ctx)) == NULL)
+		goto end;
+
+	if (ret == NULL)
+		ret = BN_new();
+	if (ret == NULL)
+		goto end;
+
+	/* A = a mod p */
+	if (!BN_nnmod(A, a, p, ctx))
+		goto end;
+
+	/* now write  |p| - 1  as  2^e*q  where  q  is odd */
+	e = 1;
+	while (!BN_is_bit_set(p, e))
+		e++;
+	/* we'll set  q  later (if needed) */
+
+	if (e == 1) {
+		/* The easy case:  (|p|-1)/2  is odd, so 2 has an inverse
+		 * modulo  (|p|-1)/2,  and square roots can be computed
+		 * directly by modular exponentiation.
+		 * We have
+		 *     2 * (|p|+1)/4 == 1   (mod (|p|-1)/2),
+		 * so we can use exponent  (|p|+1)/4,  i.e.  (|p|-3)/4 + 1.
+		 */
+		if (!BN_rshift(q, p, 2))
+			goto end;
+		q->neg = 0;
+		if (!BN_add_word(q, 1))
+			goto end;
+		if (!BN_mod_exp(ret, A, q, p, ctx))
+			goto end;
+		err = 0;
+		goto vrfy;
+	}
+
+	if (e == 2) {
+		/* |p| == 5  (mod 8)
+		 *
+		 * In this case  2  is always a non-square since
+		 * Legendre(2,p) = (-1)^((p^2-1)/8)  for any odd prime.
+		 * So if  a  really is a square, then  2*a  is a non-square.
+		 * Thus for
+		 *      b := (2*a)^((|p|-5)/8),
+		 *      i := (2*a)*b^2
+		 * we have
+		 *     i^2 = (2*a)^((1 + (|p|-5)/4)*2)
+		 *         = (2*a)^((p-1)/2)
+		 *         = -1;
+		 * so if we set
+		 *      x := a*b*(i-1),
+		 * then
+		 *     x^2 = a^2 * b^2 * (i^2 - 2*i + 1)
+		 *         = a^2 * b^2 * (-2*i)
+		 *         = a*(-i)*(2*a*b^2)
+		 *         = a*(-i)*i
+		 *         = a.
+		 *
+		 * (This is due to A.O.L. Atkin,
+		 * ,
+		 * November 1992.)
+		 */
+
+		/* t := 2*a */
+		if (!BN_mod_lshift1_quick(t, A, p))
+			goto end;
+
+		/* b := (2*a)^((|p|-5)/8) */
+		if (!BN_rshift(q, p, 3))
+			goto end;
+		q->neg = 0;
+		if (!BN_mod_exp(b, t, q, p, ctx))
+			goto end;
+
+		/* y := b^2 */
+		if (!BN_mod_sqr(y, b, p, ctx))
+			goto end;
+
+		/* t := (2*a)*b^2 - 1*/
+		if (!BN_mod_mul(t, t, y, p, ctx))
+			goto end;
+		if (!BN_sub_word(t, 1))
+			goto end;
+
+		/* x = a*b*t */
+		if (!BN_mod_mul(x, A, b, p, ctx))
+			goto end;
+		if (!BN_mod_mul(x, x, t, p, ctx))
+			goto end;
+
+		if (!BN_copy(ret, x))
+			goto end;
+		err = 0;
+		goto vrfy;
+	}
+
+	/* e > 2, so we really have to use the Tonelli/Shanks algorithm.
+	 * First, find some  y  that is not a square. */
+	if (!BN_copy(q, p)) goto end; /* use 'q' as temp */
+		q->neg = 0;
+	i = 2;
+	do {
+		/* For efficiency, try small numbers first;
+		 * if this fails, try random numbers.
+		 */
+		if (i < 22) {
+			if (!BN_set_word(y, i))
+				goto end;
+		} else {
+			if (!BN_pseudo_rand(y, BN_num_bits(p), 0, 0))
+				goto end;
+			if (BN_ucmp(y, p) >= 0) {
+				if (!(p->neg ? BN_add : BN_sub)(y, y, p))
+					goto end;
+			}
+			/* now 0 <= y < |p| */
+			if (BN_is_zero(y))
+				if (!BN_set_word(y, i))
+					goto end;
+		}
+
+		r = BN_kronecker(y, q, ctx); /* here 'q' is |p| */
+		if (r < -1)
+			goto end;
+		if (r == 0) {
+			/* m divides p */
+			BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
+			goto end;
+		}
+	}
+	while (r == 1 && ++i < 82);
+
+		if (r != -1) {
+		/* Many rounds and still no non-square -- this is more likely
+		 * a bug than just bad luck.
+		 * Even if  p  is not prime, we should have found some  y
+		 * such that r == -1.
+		 */
+		BNerr(BN_F_BN_MOD_SQRT, BN_R_TOO_MANY_ITERATIONS);
+		goto end;
+	}
+
+	/* Here's our actual 'q': */
+	if (!BN_rshift(q, q, e))
+		goto end;
+
+	/* Now that we have some non-square, we can find an element
+	 * of order  2^e  by computing its q'th power. */
+	if (!BN_mod_exp(y, y, q, p, ctx))
+		goto end;
+	if (BN_is_one(y)) {
+		BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
+		goto end;
+	}
+
+	/* Now we know that (if  p  is indeed prime) there is an integer
+	 * k,  0 <= k < 2^e,  such that
+	 *
+	 *      a^q * y^k == 1   (mod p).
+	 *
+	 * As  a^q  is a square and  y  is not,  k  must be even.
+	 * q+1  is even, too, so there is an element
+	 *
+	 *     X := a^((q+1)/2) * y^(k/2),
+	 *
+	 * and it satisfies
+	 *
+	 *     X^2 = a^q * a     * y^k
+	 *         = a,
+	 *
+	 * so it is the square root that we are looking for.
+	 */
+
+	/* t := (q-1)/2  (note that  q  is odd) */
+	if (!BN_rshift1(t, q))
+		goto end;
+
+	/* x := a^((q-1)/2) */
+	if (BN_is_zero(t)) /* special case: p = 2^e + 1 */
+	{
+		if (!BN_nnmod(t, A, p, ctx))
+			goto end;
+		if (BN_is_zero(t)) {
+			/* special case: a == 0  (mod p) */
+			BN_zero(ret);
+			err = 0;
+			goto end;
+		} else if (!BN_one(x))
+			goto end;
+	} else {
+		if (!BN_mod_exp(x, A, t, p, ctx))
+			goto end;
+		if (BN_is_zero(x)) {
+			/* special case: a == 0  (mod p) */
+			BN_zero(ret);
+			err = 0;
+			goto end;
+		}
+	}
+
+	/* b := a*x^2  (= a^q) */
+	if (!BN_mod_sqr(b, x, p, ctx))
+		goto end;
+	if (!BN_mod_mul(b, b, A, p, ctx))
+		goto end;
+
+	/* x := a*x    (= a^((q+1)/2)) */
+	if (!BN_mod_mul(x, x, A, p, ctx))
+		goto end;
+
+	while (1) {
+		/* Now  b  is  a^q * y^k  for some even  k  (0 <= k < 2^E
+		 * where  E  refers to the original value of  e,  which we
+		 * don't keep in a variable),  and  x  is  a^((q+1)/2) * y^(k/2).
+		 *
+		 * We have  a*b = x^2,
+		 *    y^2^(e-1) = -1,
+		 *    b^2^(e-1) = 1.
+		 */
+
+		if (BN_is_one(b)) {
+			if (!BN_copy(ret, x))
+				goto end;
+			err = 0;
+			goto vrfy;
+		}
+
+
+		/* find smallest  i  such that  b^(2^i) = 1 */
+		i = 1;
+		if (!BN_mod_sqr(t, b, p, ctx))
+			goto end;
+		while (!BN_is_one(t)) {
+			i++;
+			if (i == e) {
+				BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
+				goto end;
+			}
+			if (!BN_mod_mul(t, t, t, p, ctx))
+				goto end;
+		}
+
+
+		/* t := y^2^(e - i - 1) */
+		if (!BN_copy(t, y))
+			goto end;
+		for (j = e - i - 1; j > 0; j--) {
+			if (!BN_mod_sqr(t, t, p, ctx))
+				goto end;
+		}
+		if (!BN_mod_mul(y, t, t, p, ctx))
+			goto end;
+		if (!BN_mod_mul(x, x, t, p, ctx))
+			goto end;
+		if (!BN_mod_mul(b, b, y, p, ctx))
+			goto end;
+		e = i;
+	}
+
+vrfy:
+	if (!err) {
+		/* verify the result -- the input might have been not a square
+		 * (test added in 0.9.8) */
+
+		if (!BN_mod_sqr(x, ret, p, ctx))
+			err = 1;
+
+		if (!err && 0 != BN_cmp(x, A)) {
+			BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
+			err = 1;
+		}
+	}
+
+end:
+	if (err) {
+		if (ret != NULL && ret != in) {
+			BN_clear_free(ret);
+		}
+		ret = NULL;
+	}
+	BN_CTX_end(ctx);
+	bn_check_top(ret);
+	return ret;
+}
diff --git a/crypto/libressl/crypto/bn/bn_word.c b/crypto/libressl/crypto/bn/bn_word.c
new file mode 100644
index 0000000000..ef781541e3
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_word.c
@@ -0,0 +1,247 @@
+/* $OpenBSD: bn_word.c,v 1.12 2014/07/11 08:44:48 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include "bn_lcl.h"
+
+BN_ULONG
+BN_mod_word(const BIGNUM *a, BN_ULONG w)
+{
+#ifndef BN_LLONG
+	BN_ULONG ret = 0;
+#else
+	BN_ULLONG ret = 0;
+#endif
+	int i;
+
+	if (w == 0)
+		return (BN_ULONG) - 1;
+
+#ifndef BN_ULLONG
+	/* If |w| is too long and we don't have |BN_ULLONG| then we need to fall back
+	* to using |BN_div_word|. */
+	if (w > ((BN_ULONG)1 << BN_BITS4)) {
+		BIGNUM *tmp = BN_dup(a);
+		if (tmp == NULL) {
+			return (BN_ULONG)-1;
+		}
+		ret = BN_div_word(tmp, w);
+		BN_free(tmp);
+		return ret;
+	}
+#endif
+
+	bn_check_top(a);
+	w &= BN_MASK2;
+	for (i = a->top - 1; i >= 0; i--) {
+#ifndef BN_LLONG
+		ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) &
+		    BN_MASK2l)) % w;
+		ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w;
+#else
+		ret = (BN_ULLONG)(((ret << (BN_ULLONG)BN_BITS2) |
+		    a->d[i]) % (BN_ULLONG)w);
+#endif
+	}
+	return ((BN_ULONG)ret);
+}
+
+BN_ULONG
+BN_div_word(BIGNUM *a, BN_ULONG w)
+{
+	BN_ULONG ret = 0;
+	int i, j;
+
+	bn_check_top(a);
+	w &= BN_MASK2;
+
+	if (!w)
+		/* actually this an error (division by zero) */
+		return (BN_ULONG) - 1;
+	if (a->top == 0)
+		return 0;
+
+	/* normalize input (so bn_div_words doesn't complain) */
+	j = BN_BITS2 - BN_num_bits_word(w);
+	w <<= j;
+	if (!BN_lshift(a, a, j))
+		return (BN_ULONG) - 1;
+
+	for (i = a->top - 1; i >= 0; i--) {
+		BN_ULONG l, d;
+
+		l = a->d[i];
+		d = bn_div_words(ret, l, w);
+		ret = (l - ((d*w)&BN_MASK2))&BN_MASK2;
+		a->d[i] = d;
+	}
+	if ((a->top > 0) && (a->d[a->top - 1] == 0))
+		a->top--;
+	ret >>= j;
+	bn_check_top(a);
+	return (ret);
+}
+
+int
+BN_add_word(BIGNUM *a, BN_ULONG w)
+{
+	BN_ULONG l;
+	int i;
+
+	bn_check_top(a);
+	w &= BN_MASK2;
+
+	/* degenerate case: w is zero */
+	if (!w)
+		return 1;
+	/* degenerate case: a is zero */
+	if (BN_is_zero(a))
+		return BN_set_word(a, w);
+	/* handle 'a' when negative */
+	if (a->neg) {
+		a->neg = 0;
+		i = BN_sub_word(a, w);
+		if (!BN_is_zero(a))
+			a->neg=!(a->neg);
+		return (i);
+	}
+	for (i = 0; w != 0 && i < a->top; i++) {
+		a->d[i] = l = (a->d[i] + w) & BN_MASK2;
+		w = (w > l) ? 1 : 0;
+	}
+	if (w && i == a->top) {
+		if (bn_wexpand(a, a->top + 1) == NULL)
+			return 0;
+		a->top++;
+		a->d[i] = w;
+	}
+	bn_check_top(a);
+	return (1);
+}
+
+int
+BN_sub_word(BIGNUM *a, BN_ULONG w)
+{
+	int i;
+
+	bn_check_top(a);
+	w &= BN_MASK2;
+
+	/* degenerate case: w is zero */
+	if (!w)
+		return 1;
+	/* degenerate case: a is zero */
+	if (BN_is_zero(a)) {
+		i = BN_set_word(a, w);
+		if (i != 0)
+			BN_set_negative(a, 1);
+		return i;
+	}
+	/* handle 'a' when negative */
+	if (a->neg) {
+		a->neg = 0;
+		i = BN_add_word(a, w);
+		a->neg = 1;
+		return (i);
+	}
+
+	if ((a->top == 1) && (a->d[0] < w)) {
+		a->d[0] = w - a->d[0];
+		a->neg = 1;
+		return (1);
+	}
+	i = 0;
+	for (;;) {
+		if (a->d[i] >= w) {
+			a->d[i] -= w;
+			break;
+		} else {
+			a->d[i] = (a->d[i] - w) & BN_MASK2;
+			i++;
+			w = 1;
+		}
+	}
+	if ((a->d[i] == 0) && (i == (a->top - 1)))
+		a->top--;
+	bn_check_top(a);
+	return (1);
+}
+
+int
+BN_mul_word(BIGNUM *a, BN_ULONG w)
+{
+	BN_ULONG ll;
+
+	bn_check_top(a);
+	w &= BN_MASK2;
+	if (a->top) {
+		if (w == 0)
+			BN_zero(a);
+		else {
+			ll = bn_mul_words(a->d, a->d, a->top, w);
+			if (ll) {
+				if (bn_wexpand(a, a->top + 1) == NULL)
+					return (0);
+				a->d[a->top++] = ll;
+			}
+		}
+	}
+	bn_check_top(a);
+	return (1);
+}
diff --git a/crypto/libressl/crypto/bn/bn_x931p.c b/crypto/libressl/crypto/bn/bn_x931p.c
new file mode 100644
index 0000000000..854f3054e3
--- /dev/null
+++ b/crypto/libressl/crypto/bn/bn_x931p.c
@@ -0,0 +1,279 @@
+/* $OpenBSD: bn_x931p.c,v 1.7 2015/02/14 15:07:54 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+/* X9.31 routines for prime derivation */
+
+/* X9.31 prime derivation. This is used to generate the primes pi
+ * (p1, p2, q1, q2) from a parameter Xpi by checking successive odd
+ * integers.
+ */
+
+static int
+bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx, BN_GENCB *cb)
+{
+	int i = 0;
+
+	if (!BN_copy(pi, Xpi))
+		return 0;
+	if (!BN_is_odd(pi) && !BN_add_word(pi, 1))
+		return 0;
+	for (;;) {
+		i++;
+		BN_GENCB_call(cb, 0, i);
+		/* NB 27 MR is specificed in X9.31 */
+		if (BN_is_prime_fasttest_ex(pi, 27, ctx, 1, cb))
+			break;
+		if (!BN_add_word(pi, 2))
+			return 0;
+	}
+	BN_GENCB_call(cb, 2, i);
+	return 1;
+}
+
+/* This is the main X9.31 prime derivation function. From parameters
+ * Xp1, Xp2 and Xp derive the prime p. If the parameters p1 or p2 are
+ * not NULL they will be returned too: this is needed for testing.
+ */
+
+int
+BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, const BIGNUM *Xp,
+    const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx,
+    BN_GENCB *cb)
+{
+	int ret = 0;
+
+	BIGNUM *t, *p1p2, *pm1;
+
+	/* Only even e supported */
+	if (!BN_is_odd(e))
+		return 0;
+
+	BN_CTX_start(ctx);
+	if (p1 == NULL) {
+		if ((p1 = BN_CTX_get(ctx)) == NULL)
+			goto err;
+	}
+	if (p2 == NULL) {
+		if ((p2 = BN_CTX_get(ctx)) == NULL)
+			goto err;
+	}
+
+	if ((t = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((p1p2 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((pm1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!bn_x931_derive_pi(p1, Xp1, ctx, cb))
+		goto err;
+
+	if (!bn_x931_derive_pi(p2, Xp2, ctx, cb))
+		goto err;
+
+	if (!BN_mul(p1p2, p1, p2, ctx))
+		goto err;
+
+	/* First set p to value of Rp */
+
+	if (!BN_mod_inverse(p, p2, p1, ctx))
+		goto err;
+
+	if (!BN_mul(p, p, p2, ctx))
+		goto err;
+
+	if (!BN_mod_inverse(t, p1, p2, ctx))
+		goto err;
+
+	if (!BN_mul(t, t, p1, ctx))
+		goto err;
+
+	if (!BN_sub(p, p, t))
+		goto err;
+
+	if (p->neg && !BN_add(p, p, p1p2))
+		goto err;
+
+	/* p now equals Rp */
+
+	if (!BN_mod_sub(p, p, Xp, p1p2, ctx))
+		goto err;
+
+	if (!BN_add(p, p, Xp))
+		goto err;
+
+	/* p now equals Yp0 */
+
+	for (;;) {
+		int i = 1;
+		BN_GENCB_call(cb, 0, i++);
+		if (!BN_copy(pm1, p))
+			goto err;
+		if (!BN_sub_word(pm1, 1))
+			goto err;
+		if (!BN_gcd(t, pm1, e, ctx))
+			goto err;
+		if (BN_is_one(t)
+		/* X9.31 specifies 8 MR and 1 Lucas test or any prime test
+		 * offering similar or better guarantees 50 MR is considerably
+		 * better.
+		 */
+		    && BN_is_prime_fasttest_ex(p, 50, ctx, 1, cb))
+			break;
+		if (!BN_add(p, p, p1p2))
+			goto err;
+	}
+
+	BN_GENCB_call(cb, 3, 0);
+
+	ret = 1;
+
+err:
+
+	BN_CTX_end(ctx);
+
+	return ret;
+}
+
+/* Generate pair of paramters Xp, Xq for X9.31 prime generation.
+ * Note: nbits paramter is sum of number of bits in both.
+ */
+
+int
+BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx)
+{
+	BIGNUM *t;
+	int i;
+	int ret = 0;
+
+	/* Number of bits for each prime is of the form
+	 * 512+128s for s = 0, 1, ...
+	 */
+	if ((nbits < 1024) || (nbits & 0xff))
+		return 0;
+	nbits >>= 1;
+	/* The random value Xp must be between sqrt(2) * 2^(nbits-1) and
+	 * 2^nbits - 1. By setting the top two bits we ensure that the lower
+	 * bound is exceeded.
+	 */
+	if (!BN_rand(Xp, nbits, 1, 0))
+		return 0;
+
+	BN_CTX_start(ctx);
+	if ((t = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	for (i = 0; i < 1000; i++) {
+		if (!BN_rand(Xq, nbits, 1, 0))
+			goto err;
+		/* Check that |Xp - Xq| > 2^(nbits - 100) */
+		BN_sub(t, Xp, Xq);
+		if (BN_num_bits(t) > (nbits - 100))
+			break;
+	}
+
+	if (i < 1000)
+		ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+
+	return ret;
+}
+
+/* Generate primes using X9.31 algorithm. Of the values p, p1, p2, Xp1
+ * and Xp2 only 'p' needs to be non-NULL. If any of the others are not NULL
+ * the relevant parameter will be stored in it.
+ *
+ * Due to the fact that |Xp - Xq| > 2^(nbits - 100) must be satisfied Xp and Xq
+ * are generated using the previous function and supplied as input.
+ */
+
+int
+BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, BIGNUM *Xp1,
+    BIGNUM *Xp2, const BIGNUM *Xp, const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb)
+{
+	int ret = 0;
+
+	BN_CTX_start(ctx);
+	if (Xp1 == NULL) {
+		if ((Xp1 = BN_CTX_get(ctx)) == NULL)
+			goto error;
+	}
+	if (Xp2 == NULL) {
+		if ((Xp2 = BN_CTX_get(ctx)) == NULL)
+			goto error;
+	}
+
+	if (!BN_rand(Xp1, 101, 0, 0))
+		goto error;
+	if (!BN_rand(Xp2, 101, 0, 0))
+		goto error;
+	if (!BN_X931_derive_prime_ex(p, p1, p2, Xp, Xp1, Xp2, e, ctx, cb))
+		goto error;
+
+	ret = 1;
+
+error:
+	BN_CTX_end(ctx);
+
+	return ret;
+}
diff --git a/crypto/libressl/crypto/bn/gf2m-elf-x86_64.s b/crypto/libressl/crypto/bn/gf2m-elf-x86_64.s
new file mode 100644
index 0000000000..268986fe9e
--- /dev/null
+++ b/crypto/libressl/crypto/bn/gf2m-elf-x86_64.s
@@ -0,0 +1,294 @@
+.text	
+
+.type	_mul_1x1,@function
+.align	16
+_mul_1x1:
+	subq	$128+8,%rsp
+	movq	$-1,%r9
+	leaq	(%rax,%rax,1),%rsi
+	shrq	$3,%r9
+	leaq	(,%rax,4),%rdi
+	andq	%rax,%r9
+	leaq	(,%rax,8),%r12
+	sarq	$63,%rax
+	leaq	(%r9,%r9,1),%r10
+	sarq	$63,%rsi
+	leaq	(,%r9,4),%r11
+	andq	%rbp,%rax
+	sarq	$63,%rdi
+	movq	%rax,%rdx
+	shlq	$63,%rax
+	andq	%rbp,%rsi
+	shrq	$1,%rdx
+	movq	%rsi,%rcx
+	shlq	$62,%rsi
+	andq	%rbp,%rdi
+	shrq	$2,%rcx
+	xorq	%rsi,%rax
+	movq	%rdi,%rbx
+	shlq	$61,%rdi
+	xorq	%rcx,%rdx
+	shrq	$3,%rbx
+	xorq	%rdi,%rax
+	xorq	%rbx,%rdx
+
+	movq	%r9,%r13
+	movq	$0,0(%rsp)
+	xorq	%r10,%r13
+	movq	%r9,8(%rsp)
+	movq	%r11,%r14
+	movq	%r10,16(%rsp)
+	xorq	%r12,%r14
+	movq	%r13,24(%rsp)
+
+	xorq	%r11,%r9
+	movq	%r11,32(%rsp)
+	xorq	%r11,%r10
+	movq	%r9,40(%rsp)
+	xorq	%r11,%r13
+	movq	%r10,48(%rsp)
+	xorq	%r14,%r9
+	movq	%r13,56(%rsp)
+	xorq	%r14,%r10
+
+	movq	%r12,64(%rsp)
+	xorq	%r14,%r13
+	movq	%r9,72(%rsp)
+	xorq	%r11,%r9
+	movq	%r10,80(%rsp)
+	xorq	%r11,%r10
+	movq	%r13,88(%rsp)
+
+	xorq	%r11,%r13
+	movq	%r14,96(%rsp)
+	movq	%r8,%rsi
+	movq	%r9,104(%rsp)
+	andq	%rbp,%rsi
+	movq	%r10,112(%rsp)
+	shrq	$4,%rbp
+	movq	%r13,120(%rsp)
+	movq	%r8,%rdi
+	andq	%rbp,%rdi
+	shrq	$4,%rbp
+
+	movq	(%rsp,%rsi,8),%xmm0
+	movq	%r8,%rsi
+	andq	%rbp,%rsi
+	shrq	$4,%rbp
+	movq	(%rsp,%rdi,8),%rcx
+	movq	%r8,%rdi
+	movq	%rcx,%rbx
+	shlq	$4,%rcx
+	andq	%rbp,%rdi
+	movq	(%rsp,%rsi,8),%xmm1
+	shrq	$60,%rbx
+	xorq	%rcx,%rax
+	pslldq	$1,%xmm1
+	movq	%r8,%rsi
+	shrq	$4,%rbp
+	xorq	%rbx,%rdx
+	andq	%rbp,%rsi
+	shrq	$4,%rbp
+	pxor	%xmm1,%xmm0
+	movq	(%rsp,%rdi,8),%rcx
+	movq	%r8,%rdi
+	movq	%rcx,%rbx
+	shlq	$12,%rcx
+	andq	%rbp,%rdi
+	movq	(%rsp,%rsi,8),%xmm1
+	shrq	$52,%rbx
+	xorq	%rcx,%rax
+	pslldq	$2,%xmm1
+	movq	%r8,%rsi
+	shrq	$4,%rbp
+	xorq	%rbx,%rdx
+	andq	%rbp,%rsi
+	shrq	$4,%rbp
+	pxor	%xmm1,%xmm0
+	movq	(%rsp,%rdi,8),%rcx
+	movq	%r8,%rdi
+	movq	%rcx,%rbx
+	shlq	$20,%rcx
+	andq	%rbp,%rdi
+	movq	(%rsp,%rsi,8),%xmm1
+	shrq	$44,%rbx
+	xorq	%rcx,%rax
+	pslldq	$3,%xmm1
+	movq	%r8,%rsi
+	shrq	$4,%rbp
+	xorq	%rbx,%rdx
+	andq	%rbp,%rsi
+	shrq	$4,%rbp
+	pxor	%xmm1,%xmm0
+	movq	(%rsp,%rdi,8),%rcx
+	movq	%r8,%rdi
+	movq	%rcx,%rbx
+	shlq	$28,%rcx
+	andq	%rbp,%rdi
+	movq	(%rsp,%rsi,8),%xmm1
+	shrq	$36,%rbx
+	xorq	%rcx,%rax
+	pslldq	$4,%xmm1
+	movq	%r8,%rsi
+	shrq	$4,%rbp
+	xorq	%rbx,%rdx
+	andq	%rbp,%rsi
+	shrq	$4,%rbp
+	pxor	%xmm1,%xmm0
+	movq	(%rsp,%rdi,8),%rcx
+	movq	%r8,%rdi
+	movq	%rcx,%rbx
+	shlq	$36,%rcx
+	andq	%rbp,%rdi
+	movq	(%rsp,%rsi,8),%xmm1
+	shrq	$28,%rbx
+	xorq	%rcx,%rax
+	pslldq	$5,%xmm1
+	movq	%r8,%rsi
+	shrq	$4,%rbp
+	xorq	%rbx,%rdx
+	andq	%rbp,%rsi
+	shrq	$4,%rbp
+	pxor	%xmm1,%xmm0
+	movq	(%rsp,%rdi,8),%rcx
+	movq	%r8,%rdi
+	movq	%rcx,%rbx
+	shlq	$44,%rcx
+	andq	%rbp,%rdi
+	movq	(%rsp,%rsi,8),%xmm1
+	shrq	$20,%rbx
+	xorq	%rcx,%rax
+	pslldq	$6,%xmm1
+	movq	%r8,%rsi
+	shrq	$4,%rbp
+	xorq	%rbx,%rdx
+	andq	%rbp,%rsi
+	shrq	$4,%rbp
+	pxor	%xmm1,%xmm0
+	movq	(%rsp,%rdi,8),%rcx
+	movq	%r8,%rdi
+	movq	%rcx,%rbx
+	shlq	$52,%rcx
+	andq	%rbp,%rdi
+	movq	(%rsp,%rsi,8),%xmm1
+	shrq	$12,%rbx
+	xorq	%rcx,%rax
+	pslldq	$7,%xmm1
+	movq	%r8,%rsi
+	shrq	$4,%rbp
+	xorq	%rbx,%rdx
+	andq	%rbp,%rsi
+	shrq	$4,%rbp
+	pxor	%xmm1,%xmm0
+	movq	(%rsp,%rdi,8),%rcx
+	movq	%rcx,%rbx
+	shlq	$60,%rcx
+	movd	%xmm0,%rsi
+	shrq	$4,%rbx
+	xorq	%rcx,%rax
+	psrldq	$8,%xmm0
+	xorq	%rbx,%rdx
+	movd	%xmm0,%rdi
+	xorq	%rsi,%rax
+	xorq	%rdi,%rdx
+
+	addq	$128+8,%rsp
+	.byte	0xf3,0xc3
+.Lend_mul_1x1:
+.size	_mul_1x1,.-_mul_1x1
+
+.globl	bn_GF2m_mul_2x2
+.type	bn_GF2m_mul_2x2,@function
+.align	16
+bn_GF2m_mul_2x2:
+	movq	OPENSSL_ia32cap_P(%rip),%rax
+	btq	$33,%rax
+	jnc	.Lvanilla_mul_2x2
+
+	movd	%rsi,%xmm0
+	movd	%rcx,%xmm1
+	movd	%rdx,%xmm2
+	movd	%r8,%xmm3
+	movdqa	%xmm0,%xmm4
+	movdqa	%xmm1,%xmm5
+.byte	102,15,58,68,193,0
+	pxor	%xmm2,%xmm4
+	pxor	%xmm3,%xmm5
+.byte	102,15,58,68,211,0
+.byte	102,15,58,68,229,0
+	xorps	%xmm0,%xmm4
+	xorps	%xmm2,%xmm4
+	movdqa	%xmm4,%xmm5
+	pslldq	$8,%xmm4
+	psrldq	$8,%xmm5
+	pxor	%xmm4,%xmm2
+	pxor	%xmm5,%xmm0
+	movdqu	%xmm2,0(%rdi)
+	movdqu	%xmm0,16(%rdi)
+	.byte	0xf3,0xc3
+
+.align	16
+.Lvanilla_mul_2x2:
+	leaq	-136(%rsp),%rsp
+	movq	%r14,80(%rsp)
+	movq	%r13,88(%rsp)
+	movq	%r12,96(%rsp)
+	movq	%rbp,104(%rsp)
+	movq	%rbx,112(%rsp)
+.Lbody_mul_2x2:
+	movq	%rdi,32(%rsp)
+	movq	%rsi,40(%rsp)
+	movq	%rdx,48(%rsp)
+	movq	%rcx,56(%rsp)
+	movq	%r8,64(%rsp)
+
+	movq	$15,%r8
+	movq	%rsi,%rax
+	movq	%rcx,%rbp
+	call	_mul_1x1		
+	movq	%rax,16(%rsp)
+	movq	%rdx,24(%rsp)
+
+	movq	48(%rsp),%rax
+	movq	64(%rsp),%rbp
+	call	_mul_1x1		
+	movq	%rax,0(%rsp)
+	movq	%rdx,8(%rsp)
+
+	movq	40(%rsp),%rax
+	movq	56(%rsp),%rbp
+	xorq	48(%rsp),%rax
+	xorq	64(%rsp),%rbp
+	call	_mul_1x1		
+	movq	0(%rsp),%rbx
+	movq	8(%rsp),%rcx
+	movq	16(%rsp),%rdi
+	movq	24(%rsp),%rsi
+	movq	32(%rsp),%rbp
+
+	xorq	%rdx,%rax
+	xorq	%rcx,%rdx
+	xorq	%rbx,%rax
+	movq	%rbx,0(%rbp)
+	xorq	%rdi,%rdx
+	movq	%rsi,24(%rbp)
+	xorq	%rsi,%rax
+	xorq	%rsi,%rdx
+	xorq	%rdx,%rax
+	movq	%rdx,16(%rbp)
+	movq	%rax,8(%rbp)
+
+	movq	80(%rsp),%r14
+	movq	88(%rsp),%r13
+	movq	96(%rsp),%r12
+	movq	104(%rsp),%rbp
+	movq	112(%rsp),%rbx
+	leaq	136(%rsp),%rsp
+	.byte	0xf3,0xc3
+.Lend_mul_2x2:
+.size	bn_GF2m_mul_2x2,.-bn_GF2m_mul_2x2
+.byte	71,70,40,50,94,109,41,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align	16
+#if defined(HAVE_GNU_STACK)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/crypto/libressl/crypto/bn/gf2m-macosx-x86_64.s b/crypto/libressl/crypto/bn/gf2m-macosx-x86_64.s
new file mode 100644
index 0000000000..e7d0ec9fe2
--- /dev/null
+++ b/crypto/libressl/crypto/bn/gf2m-macosx-x86_64.s
@@ -0,0 +1,291 @@
+.text	
+
+
+.p2align	4
+_mul_1x1:
+	subq	$128+8,%rsp
+	movq	$-1,%r9
+	leaq	(%rax,%rax,1),%rsi
+	shrq	$3,%r9
+	leaq	(,%rax,4),%rdi
+	andq	%rax,%r9
+	leaq	(,%rax,8),%r12
+	sarq	$63,%rax
+	leaq	(%r9,%r9,1),%r10
+	sarq	$63,%rsi
+	leaq	(,%r9,4),%r11
+	andq	%rbp,%rax
+	sarq	$63,%rdi
+	movq	%rax,%rdx
+	shlq	$63,%rax
+	andq	%rbp,%rsi
+	shrq	$1,%rdx
+	movq	%rsi,%rcx
+	shlq	$62,%rsi
+	andq	%rbp,%rdi
+	shrq	$2,%rcx
+	xorq	%rsi,%rax
+	movq	%rdi,%rbx
+	shlq	$61,%rdi
+	xorq	%rcx,%rdx
+	shrq	$3,%rbx
+	xorq	%rdi,%rax
+	xorq	%rbx,%rdx
+
+	movq	%r9,%r13
+	movq	$0,0(%rsp)
+	xorq	%r10,%r13
+	movq	%r9,8(%rsp)
+	movq	%r11,%r14
+	movq	%r10,16(%rsp)
+	xorq	%r12,%r14
+	movq	%r13,24(%rsp)
+
+	xorq	%r11,%r9
+	movq	%r11,32(%rsp)
+	xorq	%r11,%r10
+	movq	%r9,40(%rsp)
+	xorq	%r11,%r13
+	movq	%r10,48(%rsp)
+	xorq	%r14,%r9
+	movq	%r13,56(%rsp)
+	xorq	%r14,%r10
+
+	movq	%r12,64(%rsp)
+	xorq	%r14,%r13
+	movq	%r9,72(%rsp)
+	xorq	%r11,%r9
+	movq	%r10,80(%rsp)
+	xorq	%r11,%r10
+	movq	%r13,88(%rsp)
+
+	xorq	%r11,%r13
+	movq	%r14,96(%rsp)
+	movq	%r8,%rsi
+	movq	%r9,104(%rsp)
+	andq	%rbp,%rsi
+	movq	%r10,112(%rsp)
+	shrq	$4,%rbp
+	movq	%r13,120(%rsp)
+	movq	%r8,%rdi
+	andq	%rbp,%rdi
+	shrq	$4,%rbp
+
+	movq	(%rsp,%rsi,8),%xmm0
+	movq	%r8,%rsi
+	andq	%rbp,%rsi
+	shrq	$4,%rbp
+	movq	(%rsp,%rdi,8),%rcx
+	movq	%r8,%rdi
+	movq	%rcx,%rbx
+	shlq	$4,%rcx
+	andq	%rbp,%rdi
+	movq	(%rsp,%rsi,8),%xmm1
+	shrq	$60,%rbx
+	xorq	%rcx,%rax
+	pslldq	$1,%xmm1
+	movq	%r8,%rsi
+	shrq	$4,%rbp
+	xorq	%rbx,%rdx
+	andq	%rbp,%rsi
+	shrq	$4,%rbp
+	pxor	%xmm1,%xmm0
+	movq	(%rsp,%rdi,8),%rcx
+	movq	%r8,%rdi
+	movq	%rcx,%rbx
+	shlq	$12,%rcx
+	andq	%rbp,%rdi
+	movq	(%rsp,%rsi,8),%xmm1
+	shrq	$52,%rbx
+	xorq	%rcx,%rax
+	pslldq	$2,%xmm1
+	movq	%r8,%rsi
+	shrq	$4,%rbp
+	xorq	%rbx,%rdx
+	andq	%rbp,%rsi
+	shrq	$4,%rbp
+	pxor	%xmm1,%xmm0
+	movq	(%rsp,%rdi,8),%rcx
+	movq	%r8,%rdi
+	movq	%rcx,%rbx
+	shlq	$20,%rcx
+	andq	%rbp,%rdi
+	movq	(%rsp,%rsi,8),%xmm1
+	shrq	$44,%rbx
+	xorq	%rcx,%rax
+	pslldq	$3,%xmm1
+	movq	%r8,%rsi
+	shrq	$4,%rbp
+	xorq	%rbx,%rdx
+	andq	%rbp,%rsi
+	shrq	$4,%rbp
+	pxor	%xmm1,%xmm0
+	movq	(%rsp,%rdi,8),%rcx
+	movq	%r8,%rdi
+	movq	%rcx,%rbx
+	shlq	$28,%rcx
+	andq	%rbp,%rdi
+	movq	(%rsp,%rsi,8),%xmm1
+	shrq	$36,%rbx
+	xorq	%rcx,%rax
+	pslldq	$4,%xmm1
+	movq	%r8,%rsi
+	shrq	$4,%rbp
+	xorq	%rbx,%rdx
+	andq	%rbp,%rsi
+	shrq	$4,%rbp
+	pxor	%xmm1,%xmm0
+	movq	(%rsp,%rdi,8),%rcx
+	movq	%r8,%rdi
+	movq	%rcx,%rbx
+	shlq	$36,%rcx
+	andq	%rbp,%rdi
+	movq	(%rsp,%rsi,8),%xmm1
+	shrq	$28,%rbx
+	xorq	%rcx,%rax
+	pslldq	$5,%xmm1
+	movq	%r8,%rsi
+	shrq	$4,%rbp
+	xorq	%rbx,%rdx
+	andq	%rbp,%rsi
+	shrq	$4,%rbp
+	pxor	%xmm1,%xmm0
+	movq	(%rsp,%rdi,8),%rcx
+	movq	%r8,%rdi
+	movq	%rcx,%rbx
+	shlq	$44,%rcx
+	andq	%rbp,%rdi
+	movq	(%rsp,%rsi,8),%xmm1
+	shrq	$20,%rbx
+	xorq	%rcx,%rax
+	pslldq	$6,%xmm1
+	movq	%r8,%rsi
+	shrq	$4,%rbp
+	xorq	%rbx,%rdx
+	andq	%rbp,%rsi
+	shrq	$4,%rbp
+	pxor	%xmm1,%xmm0
+	movq	(%rsp,%rdi,8),%rcx
+	movq	%r8,%rdi
+	movq	%rcx,%rbx
+	shlq	$52,%rcx
+	andq	%rbp,%rdi
+	movq	(%rsp,%rsi,8),%xmm1
+	shrq	$12,%rbx
+	xorq	%rcx,%rax
+	pslldq	$7,%xmm1
+	movq	%r8,%rsi
+	shrq	$4,%rbp
+	xorq	%rbx,%rdx
+	andq	%rbp,%rsi
+	shrq	$4,%rbp
+	pxor	%xmm1,%xmm0
+	movq	(%rsp,%rdi,8),%rcx
+	movq	%rcx,%rbx
+	shlq	$60,%rcx
+	movd	%xmm0,%rsi
+	shrq	$4,%rbx
+	xorq	%rcx,%rax
+	psrldq	$8,%xmm0
+	xorq	%rbx,%rdx
+	movd	%xmm0,%rdi
+	xorq	%rsi,%rax
+	xorq	%rdi,%rdx
+
+	addq	$128+8,%rsp
+	.byte	0xf3,0xc3
+L$end_mul_1x1:
+
+
+.globl	_bn_GF2m_mul_2x2
+
+.p2align	4
+_bn_GF2m_mul_2x2:
+	movq	_OPENSSL_ia32cap_P(%rip),%rax
+	btq	$33,%rax
+	jnc	L$vanilla_mul_2x2
+
+	movd	%rsi,%xmm0
+	movd	%rcx,%xmm1
+	movd	%rdx,%xmm2
+	movd	%r8,%xmm3
+	movdqa	%xmm0,%xmm4
+	movdqa	%xmm1,%xmm5
+.byte	102,15,58,68,193,0
+	pxor	%xmm2,%xmm4
+	pxor	%xmm3,%xmm5
+.byte	102,15,58,68,211,0
+.byte	102,15,58,68,229,0
+	xorps	%xmm0,%xmm4
+	xorps	%xmm2,%xmm4
+	movdqa	%xmm4,%xmm5
+	pslldq	$8,%xmm4
+	psrldq	$8,%xmm5
+	pxor	%xmm4,%xmm2
+	pxor	%xmm5,%xmm0
+	movdqu	%xmm2,0(%rdi)
+	movdqu	%xmm0,16(%rdi)
+	.byte	0xf3,0xc3
+
+.p2align	4
+L$vanilla_mul_2x2:
+	leaq	-136(%rsp),%rsp
+	movq	%r14,80(%rsp)
+	movq	%r13,88(%rsp)
+	movq	%r12,96(%rsp)
+	movq	%rbp,104(%rsp)
+	movq	%rbx,112(%rsp)
+L$body_mul_2x2:
+	movq	%rdi,32(%rsp)
+	movq	%rsi,40(%rsp)
+	movq	%rdx,48(%rsp)
+	movq	%rcx,56(%rsp)
+	movq	%r8,64(%rsp)
+
+	movq	$15,%r8
+	movq	%rsi,%rax
+	movq	%rcx,%rbp
+	call	_mul_1x1		
+	movq	%rax,16(%rsp)
+	movq	%rdx,24(%rsp)
+
+	movq	48(%rsp),%rax
+	movq	64(%rsp),%rbp
+	call	_mul_1x1		
+	movq	%rax,0(%rsp)
+	movq	%rdx,8(%rsp)
+
+	movq	40(%rsp),%rax
+	movq	56(%rsp),%rbp
+	xorq	48(%rsp),%rax
+	xorq	64(%rsp),%rbp
+	call	_mul_1x1		
+	movq	0(%rsp),%rbx
+	movq	8(%rsp),%rcx
+	movq	16(%rsp),%rdi
+	movq	24(%rsp),%rsi
+	movq	32(%rsp),%rbp
+
+	xorq	%rdx,%rax
+	xorq	%rcx,%rdx
+	xorq	%rbx,%rax
+	movq	%rbx,0(%rbp)
+	xorq	%rdi,%rdx
+	movq	%rsi,24(%rbp)
+	xorq	%rsi,%rax
+	xorq	%rsi,%rdx
+	xorq	%rdx,%rax
+	movq	%rdx,16(%rbp)
+	movq	%rax,8(%rbp)
+
+	movq	80(%rsp),%r14
+	movq	88(%rsp),%r13
+	movq	96(%rsp),%r12
+	movq	104(%rsp),%rbp
+	movq	112(%rsp),%rbx
+	leaq	136(%rsp),%rsp
+	.byte	0xf3,0xc3
+L$end_mul_2x2:
+
+.byte	71,70,40,50,94,109,41,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.p2align	4
diff --git a/crypto/libressl/crypto/bn/modexp512-elf-x86_64.s b/crypto/libressl/crypto/bn/modexp512-elf-x86_64.s
new file mode 100644
index 0000000000..2bd11f6cfe
--- /dev/null
+++ b/crypto/libressl/crypto/bn/modexp512-elf-x86_64.s
@@ -0,0 +1,1776 @@
+.text	
+
+.type	MULADD_128x512,@function
+.align	16
+MULADD_128x512:
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	movq	%r8,0(%rcx)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%r8
+	movq	8(%rdi),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	movq	%r9,8(%rcx)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	addq	%rbx,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%r9
+	.byte	0xf3,0xc3
+.size	MULADD_128x512,.-MULADD_128x512
+.type	mont_reduce,@function
+.align	16
+mont_reduce:
+	leaq	192(%rsp),%rdi
+	movq	32(%rsp),%rsi
+	addq	$576,%rsi
+	leaq	520(%rsp),%rcx
+
+	movq	96(%rcx),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	movq	(%rcx),%r8
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	movq	%r8,0(%rdi)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	movq	8(%rcx),%r9
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	movq	16(%rcx),%r10
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	movq	24(%rcx),%r11
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	movq	32(%rcx),%r12
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	movq	40(%rcx),%r13
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	movq	48(%rcx),%r14
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	movq	56(%rcx),%r15
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%r8
+	movq	104(%rcx),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	movq	%r9,8(%rdi)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	addq	%rbx,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%r9
+	movq	112(%rcx),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	movq	%r10,16(%rdi)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	addq	%rbx,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+	movq	120(%rcx),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	movq	%r11,24(%rdi)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	addq	%rbx,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+	xorq	%rax,%rax
+
+	addq	64(%rcx),%r8
+	adcq	72(%rcx),%r9
+	adcq	80(%rcx),%r10
+	adcq	88(%rcx),%r11
+	adcq	$0,%rax
+
+
+
+
+	movq	%r8,64(%rdi)
+	movq	%r9,72(%rdi)
+	movq	%r10,%rbp
+	movq	%r11,88(%rdi)
+
+	movq	%rax,384(%rsp)
+
+	movq	0(%rdi),%r8
+	movq	8(%rdi),%r9
+	movq	16(%rdi),%r10
+	movq	24(%rdi),%r11
+
+
+
+
+
+
+
+
+	addq	$80,%rdi
+
+	addq	$64,%rsi
+	leaq	296(%rsp),%rcx
+
+	call	MULADD_128x512			
+
+	movq	384(%rsp),%rax
+
+
+	addq	-16(%rdi),%r8
+	adcq	-8(%rdi),%r9
+	movq	%r8,64(%rcx)
+	movq	%r9,72(%rcx)
+
+	adcq	%rax,%rax
+	movq	%rax,384(%rsp)
+
+	leaq	192(%rsp),%rdi
+	addq	$64,%rsi
+
+
+
+
+
+	movq	(%rsi),%r8
+	movq	8(%rsi),%rbx
+
+	movq	(%rcx),%rax
+	mulq	%r8
+	movq	%rax,%rbp
+	movq	%rdx,%r9
+
+	movq	8(%rcx),%rax
+	mulq	%r8
+	addq	%rax,%r9
+
+	movq	(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%r9
+
+	movq	%r9,8(%rdi)
+
+
+	subq	$192,%rsi
+
+	movq	(%rcx),%r8
+	movq	8(%rcx),%r9
+
+	call	MULADD_128x512			
+
+
+
+
+	movq	0(%rsi),%rax
+	movq	8(%rsi),%rbx
+	movq	16(%rsi),%rdi
+	movq	24(%rsi),%rdx
+
+
+	movq	384(%rsp),%rbp
+
+	addq	64(%rcx),%r8
+	adcq	72(%rcx),%r9
+
+
+	adcq	%rbp,%rbp
+
+
+
+	shlq	$3,%rbp
+	movq	32(%rsp),%rcx
+	addq	%rcx,%rbp
+
+
+	xorq	%rsi,%rsi
+
+	addq	0(%rbp),%r10
+	adcq	64(%rbp),%r11
+	adcq	128(%rbp),%r12
+	adcq	192(%rbp),%r13
+	adcq	256(%rbp),%r14
+	adcq	320(%rbp),%r15
+	adcq	384(%rbp),%r8
+	adcq	448(%rbp),%r9
+
+
+
+	sbbq	$0,%rsi
+
+
+	andq	%rsi,%rax
+	andq	%rsi,%rbx
+	andq	%rsi,%rdi
+	andq	%rsi,%rdx
+
+	movq	$1,%rbp
+	subq	%rax,%r10
+	sbbq	%rbx,%r11
+	sbbq	%rdi,%r12
+	sbbq	%rdx,%r13
+
+
+
+
+	sbbq	$0,%rbp
+
+
+
+	addq	$512,%rcx
+	movq	32(%rcx),%rax
+	movq	40(%rcx),%rbx
+	movq	48(%rcx),%rdi
+	movq	56(%rcx),%rdx
+
+
+
+	andq	%rsi,%rax
+	andq	%rsi,%rbx
+	andq	%rsi,%rdi
+	andq	%rsi,%rdx
+
+
+
+	subq	$1,%rbp
+
+	sbbq	%rax,%r14
+	sbbq	%rbx,%r15
+	sbbq	%rdi,%r8
+	sbbq	%rdx,%r9
+
+
+
+	movq	144(%rsp),%rsi
+	movq	%r10,0(%rsi)
+	movq	%r11,8(%rsi)
+	movq	%r12,16(%rsi)
+	movq	%r13,24(%rsi)
+	movq	%r14,32(%rsi)
+	movq	%r15,40(%rsi)
+	movq	%r8,48(%rsi)
+	movq	%r9,56(%rsi)
+
+	.byte	0xf3,0xc3
+.size	mont_reduce,.-mont_reduce
+.type	mont_mul_a3b,@function
+.align	16
+mont_mul_a3b:
+
+
+
+
+	movq	0(%rdi),%rbp
+
+	movq	%r10,%rax
+	mulq	%rbp
+	movq	%rax,520(%rsp)
+	movq	%rdx,%r10
+	movq	%r11,%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+	movq	%r12,%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%r12
+	movq	%r13,%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%r13
+	movq	%r14,%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%r14
+	movq	%r15,%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%r15
+	movq	%r8,%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%r8
+	movq	%r9,%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%r9
+	movq	8(%rdi),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	movq	%r10,528(%rsp)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	addq	%rbx,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+	movq	16(%rdi),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	movq	%r11,536(%rsp)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	addq	%rbx,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+	movq	24(%rdi),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	movq	%r12,544(%rsp)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	addq	%rbx,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%r12
+	movq	32(%rdi),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	movq	%r13,552(%rsp)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	addq	%rbx,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%r13
+	movq	40(%rdi),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	movq	%r14,560(%rsp)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	addq	%rbx,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%r14
+	movq	48(%rdi),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	movq	%r15,568(%rsp)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	addq	%rbx,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%r15
+	movq	56(%rdi),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	movq	%r8,576(%rsp)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%r8
+	movq	%r9,584(%rsp)
+	movq	%r10,592(%rsp)
+	movq	%r11,600(%rsp)
+	movq	%r12,608(%rsp)
+	movq	%r13,616(%rsp)
+	movq	%r14,624(%rsp)
+	movq	%r15,632(%rsp)
+	movq	%r8,640(%rsp)
+
+
+
+
+
+	jmp	mont_reduce
+
+
+.size	mont_mul_a3b,.-mont_mul_a3b
+.type	sqr_reduce,@function
+.align	16
+sqr_reduce:
+	movq	16(%rsp),%rcx
+
+
+
+	movq	%r10,%rbx
+
+	movq	%r11,%rax
+	mulq	%rbx
+	movq	%rax,528(%rsp)
+	movq	%rdx,%r10
+	movq	%r12,%rax
+	mulq	%rbx
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+	movq	%r13,%rax
+	mulq	%rbx
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%r12
+	movq	%r14,%rax
+	mulq	%rbx
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%r13
+	movq	%r15,%rax
+	mulq	%rbx
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%r14
+	movq	%r8,%rax
+	mulq	%rbx
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%r15
+	movq	%r9,%rax
+	mulq	%rbx
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%rsi
+
+	movq	%r10,536(%rsp)
+
+
+
+
+
+	movq	8(%rcx),%rbx
+
+	movq	16(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	movq	%r11,544(%rsp)
+
+	movq	%rdx,%r10
+	movq	24(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%r10,%r12
+	adcq	$0,%rdx
+	movq	%r12,552(%rsp)
+
+	movq	%rdx,%r10
+	movq	32(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+
+	movq	%rdx,%r10
+	movq	40(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%r10,%r14
+	adcq	$0,%rdx
+
+	movq	%rdx,%r10
+	movq	%r8,%rax
+	mulq	%rbx
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%r10,%r15
+	adcq	$0,%rdx
+
+	movq	%rdx,%r10
+	movq	%r9,%rax
+	mulq	%rbx
+	addq	%rax,%rsi
+	adcq	$0,%rdx
+	addq	%r10,%rsi
+	adcq	$0,%rdx
+
+	movq	%rdx,%r11
+
+
+
+
+	movq	16(%rcx),%rbx
+
+	movq	24(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	movq	%r13,560(%rsp)
+
+	movq	%rdx,%r10
+	movq	32(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%r10,%r14
+	adcq	$0,%rdx
+	movq	%r14,568(%rsp)
+
+	movq	%rdx,%r10
+	movq	40(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%r10,%r15
+	adcq	$0,%rdx
+
+	movq	%rdx,%r10
+	movq	%r8,%rax
+	mulq	%rbx
+	addq	%rax,%rsi
+	adcq	$0,%rdx
+	addq	%r10,%rsi
+	adcq	$0,%rdx
+
+	movq	%rdx,%r10
+	movq	%r9,%rax
+	mulq	%rbx
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%r10,%r11
+	adcq	$0,%rdx
+
+	movq	%rdx,%r12
+
+
+
+
+
+	movq	24(%rcx),%rbx
+
+	movq	32(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	movq	%r15,576(%rsp)
+
+	movq	%rdx,%r10
+	movq	40(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%rsi
+	adcq	$0,%rdx
+	addq	%r10,%rsi
+	adcq	$0,%rdx
+	movq	%rsi,584(%rsp)
+
+	movq	%rdx,%r10
+	movq	%r8,%rax
+	mulq	%rbx
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%r10,%r11
+	adcq	$0,%rdx
+
+	movq	%rdx,%r10
+	movq	%r9,%rax
+	mulq	%rbx
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%r10,%r12
+	adcq	$0,%rdx
+
+	movq	%rdx,%r15
+
+
+
+
+	movq	32(%rcx),%rbx
+
+	movq	40(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	movq	%r11,592(%rsp)
+
+	movq	%rdx,%r10
+	movq	%r8,%rax
+	mulq	%rbx
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%r10,%r12
+	adcq	$0,%rdx
+	movq	%r12,600(%rsp)
+
+	movq	%rdx,%r10
+	movq	%r9,%rax
+	mulq	%rbx
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%r10,%r15
+	adcq	$0,%rdx
+
+	movq	%rdx,%r11
+
+
+
+
+	movq	40(%rcx),%rbx
+
+	movq	%r8,%rax
+	mulq	%rbx
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	movq	%r15,608(%rsp)
+
+	movq	%rdx,%r10
+	movq	%r9,%rax
+	mulq	%rbx
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%r10,%r11
+	adcq	$0,%rdx
+	movq	%r11,616(%rsp)
+
+	movq	%rdx,%r12
+
+
+
+
+	movq	%r8,%rbx
+
+	movq	%r9,%rax
+	mulq	%rbx
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	movq	%r12,624(%rsp)
+
+	movq	%rdx,632(%rsp)
+
+
+	movq	528(%rsp),%r10
+	movq	536(%rsp),%r11
+	movq	544(%rsp),%r12
+	movq	552(%rsp),%r13
+	movq	560(%rsp),%r14
+	movq	568(%rsp),%r15
+
+	movq	24(%rcx),%rax
+	mulq	%rax
+	movq	%rax,%rdi
+	movq	%rdx,%r8
+
+	addq	%r10,%r10
+	adcq	%r11,%r11
+	adcq	%r12,%r12
+	adcq	%r13,%r13
+	adcq	%r14,%r14
+	adcq	%r15,%r15
+	adcq	$0,%r8
+
+	movq	0(%rcx),%rax
+	mulq	%rax
+	movq	%rax,520(%rsp)
+	movq	%rdx,%rbx
+
+	movq	8(%rcx),%rax
+	mulq	%rax
+
+	addq	%rbx,%r10
+	adcq	%rax,%r11
+	adcq	$0,%rdx
+
+	movq	%rdx,%rbx
+	movq	%r10,528(%rsp)
+	movq	%r11,536(%rsp)
+
+	movq	16(%rcx),%rax
+	mulq	%rax
+
+	addq	%rbx,%r12
+	adcq	%rax,%r13
+	adcq	$0,%rdx
+
+	movq	%rdx,%rbx
+
+	movq	%r12,544(%rsp)
+	movq	%r13,552(%rsp)
+
+	xorq	%rbp,%rbp
+	addq	%rbx,%r14
+	adcq	%rdi,%r15
+	adcq	$0,%rbp
+
+	movq	%r14,560(%rsp)
+	movq	%r15,568(%rsp)
+
+
+
+
+	movq	576(%rsp),%r10
+	movq	584(%rsp),%r11
+	movq	592(%rsp),%r12
+	movq	600(%rsp),%r13
+	movq	608(%rsp),%r14
+	movq	616(%rsp),%r15
+	movq	624(%rsp),%rdi
+	movq	632(%rsp),%rsi
+
+	movq	%r9,%rax
+	mulq	%rax
+	movq	%rax,%r9
+	movq	%rdx,%rbx
+
+	addq	%r10,%r10
+	adcq	%r11,%r11
+	adcq	%r12,%r12
+	adcq	%r13,%r13
+	adcq	%r14,%r14
+	adcq	%r15,%r15
+	adcq	%rdi,%rdi
+	adcq	%rsi,%rsi
+	adcq	$0,%rbx
+
+	addq	%rbp,%r10
+
+	movq	32(%rcx),%rax
+	mulq	%rax
+
+	addq	%r8,%r10
+	adcq	%rax,%r11
+	adcq	$0,%rdx
+
+	movq	%rdx,%rbp
+
+	movq	%r10,576(%rsp)
+	movq	%r11,584(%rsp)
+
+	movq	40(%rcx),%rax
+	mulq	%rax
+
+	addq	%rbp,%r12
+	adcq	%rax,%r13
+	adcq	$0,%rdx
+
+	movq	%rdx,%rbp
+
+	movq	%r12,592(%rsp)
+	movq	%r13,600(%rsp)
+
+	movq	48(%rcx),%rax
+	mulq	%rax
+
+	addq	%rbp,%r14
+	adcq	%rax,%r15
+	adcq	$0,%rdx
+
+	movq	%r14,608(%rsp)
+	movq	%r15,616(%rsp)
+
+	addq	%rdx,%rdi
+	adcq	%r9,%rsi
+	adcq	$0,%rbx
+
+	movq	%rdi,624(%rsp)
+	movq	%rsi,632(%rsp)
+	movq	%rbx,640(%rsp)
+
+	jmp	mont_reduce
+
+
+.size	sqr_reduce,.-sqr_reduce
+.globl	mod_exp_512
+.type	mod_exp_512,@function
+mod_exp_512:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+
+
+	movq	%rsp,%r8
+	subq	$2688,%rsp
+	andq	$-64,%rsp
+
+
+	movq	%r8,0(%rsp)
+	movq	%rdi,8(%rsp)
+	movq	%rsi,16(%rsp)
+	movq	%rcx,24(%rsp)
+.Lbody:
+
+
+
+	pxor	%xmm4,%xmm4
+	movdqu	0(%rsi),%xmm0
+	movdqu	16(%rsi),%xmm1
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm3
+	movdqa	%xmm4,512(%rsp)
+	movdqa	%xmm4,528(%rsp)
+	movdqa	%xmm4,608(%rsp)
+	movdqa	%xmm4,624(%rsp)
+	movdqa	%xmm0,544(%rsp)
+	movdqa	%xmm1,560(%rsp)
+	movdqa	%xmm2,576(%rsp)
+	movdqa	%xmm3,592(%rsp)
+
+
+	movdqu	0(%rdx),%xmm0
+	movdqu	16(%rdx),%xmm1
+	movdqu	32(%rdx),%xmm2
+	movdqu	48(%rdx),%xmm3
+
+	leaq	384(%rsp),%rbx
+	movq	%rbx,136(%rsp)
+	call	mont_reduce
+
+
+	leaq	448(%rsp),%rcx
+	xorq	%rax,%rax
+	movq	%rax,0(%rcx)
+	movq	%rax,8(%rcx)
+	movq	%rax,24(%rcx)
+	movq	%rax,32(%rcx)
+	movq	%rax,40(%rcx)
+	movq	%rax,48(%rcx)
+	movq	%rax,56(%rcx)
+	movq	%rax,128(%rsp)
+	movq	$1,16(%rcx)
+
+	leaq	640(%rsp),%rbp
+	movq	%rcx,%rsi
+	movq	%rbp,%rdi
+	movq	$8,%rax
+loop_0:
+	movq	(%rcx),%rbx
+	movw	%bx,(%rdi)
+	shrq	$16,%rbx
+	movw	%bx,64(%rdi)
+	shrq	$16,%rbx
+	movw	%bx,128(%rdi)
+	shrq	$16,%rbx
+	movw	%bx,192(%rdi)
+	leaq	8(%rcx),%rcx
+	leaq	256(%rdi),%rdi
+	decq	%rax
+	jnz	loop_0
+	movq	$31,%rax
+	movq	%rax,32(%rsp)
+	movq	%rbp,40(%rsp)
+
+	movq	%rsi,136(%rsp)
+	movq	0(%rsi),%r10
+	movq	8(%rsi),%r11
+	movq	16(%rsi),%r12
+	movq	24(%rsi),%r13
+	movq	32(%rsi),%r14
+	movq	40(%rsi),%r15
+	movq	48(%rsi),%r8
+	movq	56(%rsi),%r9
+init_loop:
+	leaq	384(%rsp),%rdi
+	call	mont_mul_a3b
+	leaq	448(%rsp),%rsi
+	movq	40(%rsp),%rbp
+	addq	$2,%rbp
+	movq	%rbp,40(%rsp)
+	movq	%rsi,%rcx
+	movq	$8,%rax
+loop_1:
+	movq	(%rcx),%rbx
+	movw	%bx,(%rbp)
+	shrq	$16,%rbx
+	movw	%bx,64(%rbp)
+	shrq	$16,%rbx
+	movw	%bx,128(%rbp)
+	shrq	$16,%rbx
+	movw	%bx,192(%rbp)
+	leaq	8(%rcx),%rcx
+	leaq	256(%rbp),%rbp
+	decq	%rax
+	jnz	loop_1
+	movq	32(%rsp),%rax
+	subq	$1,%rax
+	movq	%rax,32(%rsp)
+	jne	init_loop
+
+
+
+	movdqa	%xmm0,64(%rsp)
+	movdqa	%xmm1,80(%rsp)
+	movdqa	%xmm2,96(%rsp)
+	movdqa	%xmm3,112(%rsp)
+
+
+
+
+
+	movl	126(%rsp),%eax
+	movq	%rax,%rdx
+	shrq	$11,%rax
+	andl	$2047,%edx
+	movl	%edx,126(%rsp)
+	leaq	640(%rsp,%rax,2),%rsi
+	movq	8(%rsp),%rdx
+	movq	$4,%rbp
+loop_2:
+	movzwq	192(%rsi),%rbx
+	movzwq	448(%rsi),%rax
+	shlq	$16,%rbx
+	shlq	$16,%rax
+	movw	128(%rsi),%bx
+	movw	384(%rsi),%ax
+	shlq	$16,%rbx
+	shlq	$16,%rax
+	movw	64(%rsi),%bx
+	movw	320(%rsi),%ax
+	shlq	$16,%rbx
+	shlq	$16,%rax
+	movw	0(%rsi),%bx
+	movw	256(%rsi),%ax
+	movq	%rbx,0(%rdx)
+	movq	%rax,8(%rdx)
+	leaq	512(%rsi),%rsi
+	leaq	16(%rdx),%rdx
+	subq	$1,%rbp
+	jnz	loop_2
+	movq	$505,48(%rsp)
+
+	movq	8(%rsp),%rcx
+	movq	%rcx,136(%rsp)
+	movq	0(%rcx),%r10
+	movq	8(%rcx),%r11
+	movq	16(%rcx),%r12
+	movq	24(%rcx),%r13
+	movq	32(%rcx),%r14
+	movq	40(%rcx),%r15
+	movq	48(%rcx),%r8
+	movq	56(%rcx),%r9
+	jmp	sqr_2
+
+main_loop_a3b:
+	call	sqr_reduce
+	call	sqr_reduce
+	call	sqr_reduce
+sqr_2:
+	call	sqr_reduce
+	call	sqr_reduce
+
+
+
+	movq	48(%rsp),%rcx
+	movq	%rcx,%rax
+	shrq	$4,%rax
+	movl	64(%rsp,%rax,2),%edx
+	andq	$15,%rcx
+	shrq	%cl,%rdx
+	andq	$31,%rdx
+
+	leaq	640(%rsp,%rdx,2),%rsi
+	leaq	448(%rsp),%rdx
+	movq	%rdx,%rdi
+	movq	$4,%rbp
+loop_3:
+	movzwq	192(%rsi),%rbx
+	movzwq	448(%rsi),%rax
+	shlq	$16,%rbx
+	shlq	$16,%rax
+	movw	128(%rsi),%bx
+	movw	384(%rsi),%ax
+	shlq	$16,%rbx
+	shlq	$16,%rax
+	movw	64(%rsi),%bx
+	movw	320(%rsi),%ax
+	shlq	$16,%rbx
+	shlq	$16,%rax
+	movw	0(%rsi),%bx
+	movw	256(%rsi),%ax
+	movq	%rbx,0(%rdx)
+	movq	%rax,8(%rdx)
+	leaq	512(%rsi),%rsi
+	leaq	16(%rdx),%rdx
+	subq	$1,%rbp
+	jnz	loop_3
+	movq	8(%rsp),%rsi
+	call	mont_mul_a3b
+
+
+
+	movq	48(%rsp),%rcx
+	subq	$5,%rcx
+	movq	%rcx,48(%rsp)
+	jge	main_loop_a3b
+
+
+
+end_main_loop_a3b:
+
+
+	movq	8(%rsp),%rdx
+	pxor	%xmm4,%xmm4
+	movdqu	0(%rdx),%xmm0
+	movdqu	16(%rdx),%xmm1
+	movdqu	32(%rdx),%xmm2
+	movdqu	48(%rdx),%xmm3
+	movdqa	%xmm4,576(%rsp)
+	movdqa	%xmm4,592(%rsp)
+	movdqa	%xmm4,608(%rsp)
+	movdqa	%xmm4,624(%rsp)
+	movdqa	%xmm0,512(%rsp)
+	movdqa	%xmm1,528(%rsp)
+	movdqa	%xmm2,544(%rsp)
+	movdqa	%xmm3,560(%rsp)
+	call	mont_reduce
+
+
+
+	movq	8(%rsp),%rax
+	movq	0(%rax),%r8
+	movq	8(%rax),%r9
+	movq	16(%rax),%r10
+	movq	24(%rax),%r11
+	movq	32(%rax),%r12
+	movq	40(%rax),%r13
+	movq	48(%rax),%r14
+	movq	56(%rax),%r15
+
+
+	movq	24(%rsp),%rbx
+	addq	$512,%rbx
+
+	subq	0(%rbx),%r8
+	sbbq	8(%rbx),%r9
+	sbbq	16(%rbx),%r10
+	sbbq	24(%rbx),%r11
+	sbbq	32(%rbx),%r12
+	sbbq	40(%rbx),%r13
+	sbbq	48(%rbx),%r14
+	sbbq	56(%rbx),%r15
+
+
+	movq	0(%rax),%rsi
+	movq	8(%rax),%rdi
+	movq	16(%rax),%rcx
+	movq	24(%rax),%rdx
+	cmovncq	%r8,%rsi
+	cmovncq	%r9,%rdi
+	cmovncq	%r10,%rcx
+	cmovncq	%r11,%rdx
+	movq	%rsi,0(%rax)
+	movq	%rdi,8(%rax)
+	movq	%rcx,16(%rax)
+	movq	%rdx,24(%rax)
+
+	movq	32(%rax),%rsi
+	movq	40(%rax),%rdi
+	movq	48(%rax),%rcx
+	movq	56(%rax),%rdx
+	cmovncq	%r12,%rsi
+	cmovncq	%r13,%rdi
+	cmovncq	%r14,%rcx
+	cmovncq	%r15,%rdx
+	movq	%rsi,32(%rax)
+	movq	%rdi,40(%rax)
+	movq	%rcx,48(%rax)
+	movq	%rdx,56(%rax)
+
+	movq	0(%rsp),%rsi
+	movq	0(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbx
+	movq	40(%rsi),%rbp
+	leaq	48(%rsi),%rsp
+.Lepilogue:
+	.byte	0xf3,0xc3
+.size	mod_exp_512, . - mod_exp_512
+#if defined(HAVE_GNU_STACK)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/crypto/libressl/crypto/bn/modexp512-macosx-x86_64.s b/crypto/libressl/crypto/bn/modexp512-macosx-x86_64.s
new file mode 100644
index 0000000000..c8cb7fb8ef
--- /dev/null
+++ b/crypto/libressl/crypto/bn/modexp512-macosx-x86_64.s
@@ -0,0 +1,1773 @@
+.text	
+
+
+.p2align	4
+MULADD_128x512:
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	movq	%r8,0(%rcx)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%r8
+	movq	8(%rdi),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	movq	%r9,8(%rcx)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	addq	%rbx,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%r9
+	.byte	0xf3,0xc3
+
+
+.p2align	4
+mont_reduce:
+	leaq	192(%rsp),%rdi
+	movq	32(%rsp),%rsi
+	addq	$576,%rsi
+	leaq	520(%rsp),%rcx
+
+	movq	96(%rcx),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	movq	(%rcx),%r8
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	movq	%r8,0(%rdi)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	movq	8(%rcx),%r9
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	movq	16(%rcx),%r10
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	movq	24(%rcx),%r11
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	movq	32(%rcx),%r12
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	movq	40(%rcx),%r13
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	movq	48(%rcx),%r14
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	movq	56(%rcx),%r15
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%r8
+	movq	104(%rcx),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	movq	%r9,8(%rdi)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	addq	%rbx,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%r9
+	movq	112(%rcx),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	movq	%r10,16(%rdi)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	addq	%rbx,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+	movq	120(%rcx),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	movq	%r11,24(%rdi)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	addq	%rbx,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+	xorq	%rax,%rax
+
+	addq	64(%rcx),%r8
+	adcq	72(%rcx),%r9
+	adcq	80(%rcx),%r10
+	adcq	88(%rcx),%r11
+	adcq	$0,%rax
+
+
+
+
+	movq	%r8,64(%rdi)
+	movq	%r9,72(%rdi)
+	movq	%r10,%rbp
+	movq	%r11,88(%rdi)
+
+	movq	%rax,384(%rsp)
+
+	movq	0(%rdi),%r8
+	movq	8(%rdi),%r9
+	movq	16(%rdi),%r10
+	movq	24(%rdi),%r11
+
+
+
+
+
+
+
+
+	addq	$80,%rdi
+
+	addq	$64,%rsi
+	leaq	296(%rsp),%rcx
+
+	call	MULADD_128x512			
+
+	movq	384(%rsp),%rax
+
+
+	addq	-16(%rdi),%r8
+	adcq	-8(%rdi),%r9
+	movq	%r8,64(%rcx)
+	movq	%r9,72(%rcx)
+
+	adcq	%rax,%rax
+	movq	%rax,384(%rsp)
+
+	leaq	192(%rsp),%rdi
+	addq	$64,%rsi
+
+
+
+
+
+	movq	(%rsi),%r8
+	movq	8(%rsi),%rbx
+
+	movq	(%rcx),%rax
+	mulq	%r8
+	movq	%rax,%rbp
+	movq	%rdx,%r9
+
+	movq	8(%rcx),%rax
+	mulq	%r8
+	addq	%rax,%r9
+
+	movq	(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%r9
+
+	movq	%r9,8(%rdi)
+
+
+	subq	$192,%rsi
+
+	movq	(%rcx),%r8
+	movq	8(%rcx),%r9
+
+	call	MULADD_128x512			
+
+
+
+
+	movq	0(%rsi),%rax
+	movq	8(%rsi),%rbx
+	movq	16(%rsi),%rdi
+	movq	24(%rsi),%rdx
+
+
+	movq	384(%rsp),%rbp
+
+	addq	64(%rcx),%r8
+	adcq	72(%rcx),%r9
+
+
+	adcq	%rbp,%rbp
+
+
+
+	shlq	$3,%rbp
+	movq	32(%rsp),%rcx
+	addq	%rcx,%rbp
+
+
+	xorq	%rsi,%rsi
+
+	addq	0(%rbp),%r10
+	adcq	64(%rbp),%r11
+	adcq	128(%rbp),%r12
+	adcq	192(%rbp),%r13
+	adcq	256(%rbp),%r14
+	adcq	320(%rbp),%r15
+	adcq	384(%rbp),%r8
+	adcq	448(%rbp),%r9
+
+
+
+	sbbq	$0,%rsi
+
+
+	andq	%rsi,%rax
+	andq	%rsi,%rbx
+	andq	%rsi,%rdi
+	andq	%rsi,%rdx
+
+	movq	$1,%rbp
+	subq	%rax,%r10
+	sbbq	%rbx,%r11
+	sbbq	%rdi,%r12
+	sbbq	%rdx,%r13
+
+
+
+
+	sbbq	$0,%rbp
+
+
+
+	addq	$512,%rcx
+	movq	32(%rcx),%rax
+	movq	40(%rcx),%rbx
+	movq	48(%rcx),%rdi
+	movq	56(%rcx),%rdx
+
+
+
+	andq	%rsi,%rax
+	andq	%rsi,%rbx
+	andq	%rsi,%rdi
+	andq	%rsi,%rdx
+
+
+
+	subq	$1,%rbp
+
+	sbbq	%rax,%r14
+	sbbq	%rbx,%r15
+	sbbq	%rdi,%r8
+	sbbq	%rdx,%r9
+
+
+
+	movq	144(%rsp),%rsi
+	movq	%r10,0(%rsi)
+	movq	%r11,8(%rsi)
+	movq	%r12,16(%rsi)
+	movq	%r13,24(%rsi)
+	movq	%r14,32(%rsi)
+	movq	%r15,40(%rsi)
+	movq	%r8,48(%rsi)
+	movq	%r9,56(%rsi)
+
+	.byte	0xf3,0xc3
+
+
+.p2align	4
+mont_mul_a3b:
+
+
+
+
+	movq	0(%rdi),%rbp
+
+	movq	%r10,%rax
+	mulq	%rbp
+	movq	%rax,520(%rsp)
+	movq	%rdx,%r10
+	movq	%r11,%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+	movq	%r12,%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%r12
+	movq	%r13,%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%r13
+	movq	%r14,%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%r14
+	movq	%r15,%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%r15
+	movq	%r8,%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%r8
+	movq	%r9,%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%r9
+	movq	8(%rdi),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	movq	%r10,528(%rsp)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	addq	%rbx,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+	movq	16(%rdi),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	movq	%r11,536(%rsp)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	addq	%rbx,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+	movq	24(%rdi),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	movq	%r12,544(%rsp)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	addq	%rbx,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%r12
+	movq	32(%rdi),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	movq	%r13,552(%rsp)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	addq	%rbx,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%r13
+	movq	40(%rdi),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	movq	%r14,560(%rsp)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	addq	%rbx,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%r14
+	movq	48(%rdi),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	movq	%r15,568(%rsp)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	addq	%rbx,%r8
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%r15
+	movq	56(%rdi),%rbp
+	movq	0(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r8
+	adcq	$0,%rdx
+	movq	%r8,576(%rsp)
+	movq	%rdx,%rbx
+
+	movq	8(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r9
+	adcq	$0,%rdx
+	addq	%rbx,%r9
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	16(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	addq	%rbx,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	24(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%rbx,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	32(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%rbx,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	40(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%rbx,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	48(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%rbx,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%rbx
+
+	movq	56(%rsi),%rax
+	mulq	%rbp
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%rbx,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%r8
+	movq	%r9,584(%rsp)
+	movq	%r10,592(%rsp)
+	movq	%r11,600(%rsp)
+	movq	%r12,608(%rsp)
+	movq	%r13,616(%rsp)
+	movq	%r14,624(%rsp)
+	movq	%r15,632(%rsp)
+	movq	%r8,640(%rsp)
+
+
+
+
+
+	jmp	mont_reduce
+
+
+
+
+.p2align	4
+sqr_reduce:
+	movq	16(%rsp),%rcx
+
+
+
+	movq	%r10,%rbx
+
+	movq	%r11,%rax
+	mulq	%rbx
+	movq	%rax,528(%rsp)
+	movq	%rdx,%r10
+	movq	%r12,%rax
+	mulq	%rbx
+	addq	%rax,%r10
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+	movq	%r13,%rax
+	mulq	%rbx
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	movq	%rdx,%r12
+	movq	%r14,%rax
+	mulq	%rbx
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	movq	%rdx,%r13
+	movq	%r15,%rax
+	mulq	%rbx
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	movq	%rdx,%r14
+	movq	%r8,%rax
+	mulq	%rbx
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	movq	%rdx,%r15
+	movq	%r9,%rax
+	mulq	%rbx
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	movq	%rdx,%rsi
+
+	movq	%r10,536(%rsp)
+
+
+
+
+
+	movq	8(%rcx),%rbx
+
+	movq	16(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	movq	%r11,544(%rsp)
+
+	movq	%rdx,%r10
+	movq	24(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%r10,%r12
+	adcq	$0,%rdx
+	movq	%r12,552(%rsp)
+
+	movq	%rdx,%r10
+	movq	32(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+
+	movq	%rdx,%r10
+	movq	40(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%r10,%r14
+	adcq	$0,%rdx
+
+	movq	%rdx,%r10
+	movq	%r8,%rax
+	mulq	%rbx
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%r10,%r15
+	adcq	$0,%rdx
+
+	movq	%rdx,%r10
+	movq	%r9,%rax
+	mulq	%rbx
+	addq	%rax,%rsi
+	adcq	$0,%rdx
+	addq	%r10,%rsi
+	adcq	$0,%rdx
+
+	movq	%rdx,%r11
+
+
+
+
+	movq	16(%rcx),%rbx
+
+	movq	24(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%r13
+	adcq	$0,%rdx
+	movq	%r13,560(%rsp)
+
+	movq	%rdx,%r10
+	movq	32(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%r14
+	adcq	$0,%rdx
+	addq	%r10,%r14
+	adcq	$0,%rdx
+	movq	%r14,568(%rsp)
+
+	movq	%rdx,%r10
+	movq	40(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%r10,%r15
+	adcq	$0,%rdx
+
+	movq	%rdx,%r10
+	movq	%r8,%rax
+	mulq	%rbx
+	addq	%rax,%rsi
+	adcq	$0,%rdx
+	addq	%r10,%rsi
+	adcq	$0,%rdx
+
+	movq	%rdx,%r10
+	movq	%r9,%rax
+	mulq	%rbx
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%r10,%r11
+	adcq	$0,%rdx
+
+	movq	%rdx,%r12
+
+
+
+
+
+	movq	24(%rcx),%rbx
+
+	movq	32(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	movq	%r15,576(%rsp)
+
+	movq	%rdx,%r10
+	movq	40(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%rsi
+	adcq	$0,%rdx
+	addq	%r10,%rsi
+	adcq	$0,%rdx
+	movq	%rsi,584(%rsp)
+
+	movq	%rdx,%r10
+	movq	%r8,%rax
+	mulq	%rbx
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%r10,%r11
+	adcq	$0,%rdx
+
+	movq	%rdx,%r10
+	movq	%r9,%rax
+	mulq	%rbx
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%r10,%r12
+	adcq	$0,%rdx
+
+	movq	%rdx,%r15
+
+
+
+
+	movq	32(%rcx),%rbx
+
+	movq	40(%rcx),%rax
+	mulq	%rbx
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	movq	%r11,592(%rsp)
+
+	movq	%rdx,%r10
+	movq	%r8,%rax
+	mulq	%rbx
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	addq	%r10,%r12
+	adcq	$0,%rdx
+	movq	%r12,600(%rsp)
+
+	movq	%rdx,%r10
+	movq	%r9,%rax
+	mulq	%rbx
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	addq	%r10,%r15
+	adcq	$0,%rdx
+
+	movq	%rdx,%r11
+
+
+
+
+	movq	40(%rcx),%rbx
+
+	movq	%r8,%rax
+	mulq	%rbx
+	addq	%rax,%r15
+	adcq	$0,%rdx
+	movq	%r15,608(%rsp)
+
+	movq	%rdx,%r10
+	movq	%r9,%rax
+	mulq	%rbx
+	addq	%rax,%r11
+	adcq	$0,%rdx
+	addq	%r10,%r11
+	adcq	$0,%rdx
+	movq	%r11,616(%rsp)
+
+	movq	%rdx,%r12
+
+
+
+
+	movq	%r8,%rbx
+
+	movq	%r9,%rax
+	mulq	%rbx
+	addq	%rax,%r12
+	adcq	$0,%rdx
+	movq	%r12,624(%rsp)
+
+	movq	%rdx,632(%rsp)
+
+
+	movq	528(%rsp),%r10
+	movq	536(%rsp),%r11
+	movq	544(%rsp),%r12
+	movq	552(%rsp),%r13
+	movq	560(%rsp),%r14
+	movq	568(%rsp),%r15
+
+	movq	24(%rcx),%rax
+	mulq	%rax
+	movq	%rax,%rdi
+	movq	%rdx,%r8
+
+	addq	%r10,%r10
+	adcq	%r11,%r11
+	adcq	%r12,%r12
+	adcq	%r13,%r13
+	adcq	%r14,%r14
+	adcq	%r15,%r15
+	adcq	$0,%r8
+
+	movq	0(%rcx),%rax
+	mulq	%rax
+	movq	%rax,520(%rsp)
+	movq	%rdx,%rbx
+
+	movq	8(%rcx),%rax
+	mulq	%rax
+
+	addq	%rbx,%r10
+	adcq	%rax,%r11
+	adcq	$0,%rdx
+
+	movq	%rdx,%rbx
+	movq	%r10,528(%rsp)
+	movq	%r11,536(%rsp)
+
+	movq	16(%rcx),%rax
+	mulq	%rax
+
+	addq	%rbx,%r12
+	adcq	%rax,%r13
+	adcq	$0,%rdx
+
+	movq	%rdx,%rbx
+
+	movq	%r12,544(%rsp)
+	movq	%r13,552(%rsp)
+
+	xorq	%rbp,%rbp
+	addq	%rbx,%r14
+	adcq	%rdi,%r15
+	adcq	$0,%rbp
+
+	movq	%r14,560(%rsp)
+	movq	%r15,568(%rsp)
+
+
+
+
+	movq	576(%rsp),%r10
+	movq	584(%rsp),%r11
+	movq	592(%rsp),%r12
+	movq	600(%rsp),%r13
+	movq	608(%rsp),%r14
+	movq	616(%rsp),%r15
+	movq	624(%rsp),%rdi
+	movq	632(%rsp),%rsi
+
+	movq	%r9,%rax
+	mulq	%rax
+	movq	%rax,%r9
+	movq	%rdx,%rbx
+
+	addq	%r10,%r10
+	adcq	%r11,%r11
+	adcq	%r12,%r12
+	adcq	%r13,%r13
+	adcq	%r14,%r14
+	adcq	%r15,%r15
+	adcq	%rdi,%rdi
+	adcq	%rsi,%rsi
+	adcq	$0,%rbx
+
+	addq	%rbp,%r10
+
+	movq	32(%rcx),%rax
+	mulq	%rax
+
+	addq	%r8,%r10
+	adcq	%rax,%r11
+	adcq	$0,%rdx
+
+	movq	%rdx,%rbp
+
+	movq	%r10,576(%rsp)
+	movq	%r11,584(%rsp)
+
+	movq	40(%rcx),%rax
+	mulq	%rax
+
+	addq	%rbp,%r12
+	adcq	%rax,%r13
+	adcq	$0,%rdx
+
+	movq	%rdx,%rbp
+
+	movq	%r12,592(%rsp)
+	movq	%r13,600(%rsp)
+
+	movq	48(%rcx),%rax
+	mulq	%rax
+
+	addq	%rbp,%r14
+	adcq	%rax,%r15
+	adcq	$0,%rdx
+
+	movq	%r14,608(%rsp)
+	movq	%r15,616(%rsp)
+
+	addq	%rdx,%rdi
+	adcq	%r9,%rsi
+	adcq	$0,%rbx
+
+	movq	%rdi,624(%rsp)
+	movq	%rsi,632(%rsp)
+	movq	%rbx,640(%rsp)
+
+	jmp	mont_reduce
+
+
+
+.globl	_mod_exp_512
+
+_mod_exp_512:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+
+
+	movq	%rsp,%r8
+	subq	$2688,%rsp
+	andq	$-64,%rsp
+
+
+	movq	%r8,0(%rsp)
+	movq	%rdi,8(%rsp)
+	movq	%rsi,16(%rsp)
+	movq	%rcx,24(%rsp)
+L$body:
+
+
+
+	pxor	%xmm4,%xmm4
+	movdqu	0(%rsi),%xmm0
+	movdqu	16(%rsi),%xmm1
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm3
+	movdqa	%xmm4,512(%rsp)
+	movdqa	%xmm4,528(%rsp)
+	movdqa	%xmm4,608(%rsp)
+	movdqa	%xmm4,624(%rsp)
+	movdqa	%xmm0,544(%rsp)
+	movdqa	%xmm1,560(%rsp)
+	movdqa	%xmm2,576(%rsp)
+	movdqa	%xmm3,592(%rsp)
+
+
+	movdqu	0(%rdx),%xmm0
+	movdqu	16(%rdx),%xmm1
+	movdqu	32(%rdx),%xmm2
+	movdqu	48(%rdx),%xmm3
+
+	leaq	384(%rsp),%rbx
+	movq	%rbx,136(%rsp)
+	call	mont_reduce
+
+
+	leaq	448(%rsp),%rcx
+	xorq	%rax,%rax
+	movq	%rax,0(%rcx)
+	movq	%rax,8(%rcx)
+	movq	%rax,24(%rcx)
+	movq	%rax,32(%rcx)
+	movq	%rax,40(%rcx)
+	movq	%rax,48(%rcx)
+	movq	%rax,56(%rcx)
+	movq	%rax,128(%rsp)
+	movq	$1,16(%rcx)
+
+	leaq	640(%rsp),%rbp
+	movq	%rcx,%rsi
+	movq	%rbp,%rdi
+	movq	$8,%rax
+loop_0:
+	movq	(%rcx),%rbx
+	movw	%bx,(%rdi)
+	shrq	$16,%rbx
+	movw	%bx,64(%rdi)
+	shrq	$16,%rbx
+	movw	%bx,128(%rdi)
+	shrq	$16,%rbx
+	movw	%bx,192(%rdi)
+	leaq	8(%rcx),%rcx
+	leaq	256(%rdi),%rdi
+	decq	%rax
+	jnz	loop_0
+	movq	$31,%rax
+	movq	%rax,32(%rsp)
+	movq	%rbp,40(%rsp)
+
+	movq	%rsi,136(%rsp)
+	movq	0(%rsi),%r10
+	movq	8(%rsi),%r11
+	movq	16(%rsi),%r12
+	movq	24(%rsi),%r13
+	movq	32(%rsi),%r14
+	movq	40(%rsi),%r15
+	movq	48(%rsi),%r8
+	movq	56(%rsi),%r9
+init_loop:
+	leaq	384(%rsp),%rdi
+	call	mont_mul_a3b
+	leaq	448(%rsp),%rsi
+	movq	40(%rsp),%rbp
+	addq	$2,%rbp
+	movq	%rbp,40(%rsp)
+	movq	%rsi,%rcx
+	movq	$8,%rax
+loop_1:
+	movq	(%rcx),%rbx
+	movw	%bx,(%rbp)
+	shrq	$16,%rbx
+	movw	%bx,64(%rbp)
+	shrq	$16,%rbx
+	movw	%bx,128(%rbp)
+	shrq	$16,%rbx
+	movw	%bx,192(%rbp)
+	leaq	8(%rcx),%rcx
+	leaq	256(%rbp),%rbp
+	decq	%rax
+	jnz	loop_1
+	movq	32(%rsp),%rax
+	subq	$1,%rax
+	movq	%rax,32(%rsp)
+	jne	init_loop
+
+
+
+	movdqa	%xmm0,64(%rsp)
+	movdqa	%xmm1,80(%rsp)
+	movdqa	%xmm2,96(%rsp)
+	movdqa	%xmm3,112(%rsp)
+
+
+
+
+
+	movl	126(%rsp),%eax
+	movq	%rax,%rdx
+	shrq	$11,%rax
+	andl	$2047,%edx
+	movl	%edx,126(%rsp)
+	leaq	640(%rsp,%rax,2),%rsi
+	movq	8(%rsp),%rdx
+	movq	$4,%rbp
+loop_2:
+	movzwq	192(%rsi),%rbx
+	movzwq	448(%rsi),%rax
+	shlq	$16,%rbx
+	shlq	$16,%rax
+	movw	128(%rsi),%bx
+	movw	384(%rsi),%ax
+	shlq	$16,%rbx
+	shlq	$16,%rax
+	movw	64(%rsi),%bx
+	movw	320(%rsi),%ax
+	shlq	$16,%rbx
+	shlq	$16,%rax
+	movw	0(%rsi),%bx
+	movw	256(%rsi),%ax
+	movq	%rbx,0(%rdx)
+	movq	%rax,8(%rdx)
+	leaq	512(%rsi),%rsi
+	leaq	16(%rdx),%rdx
+	subq	$1,%rbp
+	jnz	loop_2
+	movq	$505,48(%rsp)
+
+	movq	8(%rsp),%rcx
+	movq	%rcx,136(%rsp)
+	movq	0(%rcx),%r10
+	movq	8(%rcx),%r11
+	movq	16(%rcx),%r12
+	movq	24(%rcx),%r13
+	movq	32(%rcx),%r14
+	movq	40(%rcx),%r15
+	movq	48(%rcx),%r8
+	movq	56(%rcx),%r9
+	jmp	sqr_2
+
+main_loop_a3b:
+	call	sqr_reduce
+	call	sqr_reduce
+	call	sqr_reduce
+sqr_2:
+	call	sqr_reduce
+	call	sqr_reduce
+
+
+
+	movq	48(%rsp),%rcx
+	movq	%rcx,%rax
+	shrq	$4,%rax
+	movl	64(%rsp,%rax,2),%edx
+	andq	$15,%rcx
+	shrq	%cl,%rdx
+	andq	$31,%rdx
+
+	leaq	640(%rsp,%rdx,2),%rsi
+	leaq	448(%rsp),%rdx
+	movq	%rdx,%rdi
+	movq	$4,%rbp
+loop_3:
+	movzwq	192(%rsi),%rbx
+	movzwq	448(%rsi),%rax
+	shlq	$16,%rbx
+	shlq	$16,%rax
+	movw	128(%rsi),%bx
+	movw	384(%rsi),%ax
+	shlq	$16,%rbx
+	shlq	$16,%rax
+	movw	64(%rsi),%bx
+	movw	320(%rsi),%ax
+	shlq	$16,%rbx
+	shlq	$16,%rax
+	movw	0(%rsi),%bx
+	movw	256(%rsi),%ax
+	movq	%rbx,0(%rdx)
+	movq	%rax,8(%rdx)
+	leaq	512(%rsi),%rsi
+	leaq	16(%rdx),%rdx
+	subq	$1,%rbp
+	jnz	loop_3
+	movq	8(%rsp),%rsi
+	call	mont_mul_a3b
+
+
+
+	movq	48(%rsp),%rcx
+	subq	$5,%rcx
+	movq	%rcx,48(%rsp)
+	jge	main_loop_a3b
+
+
+
+end_main_loop_a3b:
+
+
+	movq	8(%rsp),%rdx
+	pxor	%xmm4,%xmm4
+	movdqu	0(%rdx),%xmm0
+	movdqu	16(%rdx),%xmm1
+	movdqu	32(%rdx),%xmm2
+	movdqu	48(%rdx),%xmm3
+	movdqa	%xmm4,576(%rsp)
+	movdqa	%xmm4,592(%rsp)
+	movdqa	%xmm4,608(%rsp)
+	movdqa	%xmm4,624(%rsp)
+	movdqa	%xmm0,512(%rsp)
+	movdqa	%xmm1,528(%rsp)
+	movdqa	%xmm2,544(%rsp)
+	movdqa	%xmm3,560(%rsp)
+	call	mont_reduce
+
+
+
+	movq	8(%rsp),%rax
+	movq	0(%rax),%r8
+	movq	8(%rax),%r9
+	movq	16(%rax),%r10
+	movq	24(%rax),%r11
+	movq	32(%rax),%r12
+	movq	40(%rax),%r13
+	movq	48(%rax),%r14
+	movq	56(%rax),%r15
+
+
+	movq	24(%rsp),%rbx
+	addq	$512,%rbx
+
+	subq	0(%rbx),%r8
+	sbbq	8(%rbx),%r9
+	sbbq	16(%rbx),%r10
+	sbbq	24(%rbx),%r11
+	sbbq	32(%rbx),%r12
+	sbbq	40(%rbx),%r13
+	sbbq	48(%rbx),%r14
+	sbbq	56(%rbx),%r15
+
+
+	movq	0(%rax),%rsi
+	movq	8(%rax),%rdi
+	movq	16(%rax),%rcx
+	movq	24(%rax),%rdx
+	cmovncq	%r8,%rsi
+	cmovncq	%r9,%rdi
+	cmovncq	%r10,%rcx
+	cmovncq	%r11,%rdx
+	movq	%rsi,0(%rax)
+	movq	%rdi,8(%rax)
+	movq	%rcx,16(%rax)
+	movq	%rdx,24(%rax)
+
+	movq	32(%rax),%rsi
+	movq	40(%rax),%rdi
+	movq	48(%rax),%rcx
+	movq	56(%rax),%rdx
+	cmovncq	%r12,%rsi
+	cmovncq	%r13,%rdi
+	cmovncq	%r14,%rcx
+	cmovncq	%r15,%rdx
+	movq	%rsi,32(%rax)
+	movq	%rdi,40(%rax)
+	movq	%rcx,48(%rax)
+	movq	%rdx,56(%rax)
+
+	movq	0(%rsp),%rsi
+	movq	0(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbx
+	movq	40(%rsi),%rbp
+	leaq	48(%rsi),%rsp
+L$epilogue:
+	.byte	0xf3,0xc3
+
diff --git a/crypto/libressl/crypto/bn/mont-elf-x86_64.s b/crypto/libressl/crypto/bn/mont-elf-x86_64.s
new file mode 100644
index 0000000000..a48a778f0c
--- /dev/null
+++ b/crypto/libressl/crypto/bn/mont-elf-x86_64.s
@@ -0,0 +1,1377 @@
+.text	
+
+.globl	bn_mul_mont
+.type	bn_mul_mont,@function
+.align	16
+bn_mul_mont:
+	testl	$3,%r9d
+	jnz	.Lmul_enter
+	cmpl	$8,%r9d
+	jb	.Lmul_enter
+	cmpq	%rsi,%rdx
+	jne	.Lmul4x_enter
+	jmp	.Lsqr4x_enter
+
+.align	16
+.Lmul_enter:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+
+	movl	%r9d,%r9d
+	leaq	2(%r9),%r10
+	movq	%rsp,%r11
+	negq	%r10
+	leaq	(%rsp,%r10,8),%rsp
+	andq	$-1024,%rsp
+
+	movq	%r11,8(%rsp,%r9,8)
+.Lmul_body:
+	movq	%rdx,%r12
+	movq	(%r8),%r8
+	movq	(%r12),%rbx
+	movq	(%rsi),%rax
+
+	xorq	%r14,%r14
+	xorq	%r15,%r15
+
+	movq	%r8,%rbp
+	mulq	%rbx
+	movq	%rax,%r10
+	movq	(%rcx),%rax
+
+	imulq	%r10,%rbp
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r10
+	movq	8(%rsi),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r13
+
+	leaq	1(%r15),%r15
+	jmp	.L1st_enter
+
+.align	16
+.L1st:
+	addq	%rax,%r13
+	movq	(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%r13
+	movq	%r10,%r11
+	adcq	$0,%rdx
+	movq	%r13,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+.L1st_enter:
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	leaq	1(%r15),%r15
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	cmpq	%r9,%r15
+	jl	.L1st
+
+	addq	%rax,%r13
+	movq	(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r11,%r13
+	adcq	$0,%rdx
+	movq	%r13,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+	movq	%r10,%r11
+
+	xorq	%rdx,%rdx
+	addq	%r11,%r13
+	adcq	$0,%rdx
+	movq	%r13,-8(%rsp,%r9,8)
+	movq	%rdx,(%rsp,%r9,8)
+
+	leaq	1(%r14),%r14
+	jmp	.Louter
+.align	16
+.Louter:
+	movq	(%r12,%r14,8),%rbx
+	xorq	%r15,%r15
+	movq	%r8,%rbp
+	movq	(%rsp),%r10
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	(%rcx),%rax
+	adcq	$0,%rdx
+
+	imulq	%r10,%rbp
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r10
+	movq	8(%rsi),%rax
+	adcq	$0,%rdx
+	movq	8(%rsp),%r10
+	movq	%rdx,%r13
+
+	leaq	1(%r15),%r15
+	jmp	.Linner_enter
+
+.align	16
+.Linner:
+	addq	%rax,%r13
+	movq	(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	movq	(%rsp,%r15,8),%r10
+	adcq	$0,%rdx
+	movq	%r13,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+.Linner_enter:
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%r10
+	movq	%rdx,%r11
+	adcq	$0,%r11
+	leaq	1(%r15),%r15
+
+	mulq	%rbp
+	cmpq	%r9,%r15
+	jl	.Linner
+
+	addq	%rax,%r13
+	movq	(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	movq	(%rsp,%r15,8),%r10
+	adcq	$0,%rdx
+	movq	%r13,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+	xorq	%rdx,%rdx
+	addq	%r11,%r13
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-8(%rsp,%r9,8)
+	movq	%rdx,(%rsp,%r9,8)
+
+	leaq	1(%r14),%r14
+	cmpq	%r9,%r14
+	jl	.Louter
+
+	xorq	%r14,%r14
+	movq	(%rsp),%rax
+	leaq	(%rsp),%rsi
+	movq	%r9,%r15
+	jmp	.Lsub
+.align	16
+.Lsub:	sbbq	(%rcx,%r14,8),%rax
+	movq	%rax,(%rdi,%r14,8)
+	movq	8(%rsi,%r14,8),%rax
+	leaq	1(%r14),%r14
+	decq	%r15
+	jnz	.Lsub
+
+	sbbq	$0,%rax
+	xorq	%r14,%r14
+	andq	%rax,%rsi
+	notq	%rax
+	movq	%rdi,%rcx
+	andq	%rax,%rcx
+	movq	%r9,%r15
+	orq	%rcx,%rsi
+.align	16
+.Lcopy:
+	movq	(%rsi,%r14,8),%rax
+	movq	%r14,(%rsp,%r14,8)
+	movq	%rax,(%rdi,%r14,8)
+	leaq	1(%r14),%r14
+	subq	$1,%r15
+	jnz	.Lcopy
+
+	movq	8(%rsp,%r9,8),%rsi
+	movq	$1,%rax
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+.Lmul_epilogue:
+	.byte	0xf3,0xc3
+.size	bn_mul_mont,.-bn_mul_mont
+.type	bn_mul4x_mont,@function
+.align	16
+bn_mul4x_mont:
+.Lmul4x_enter:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+
+	movl	%r9d,%r9d
+	leaq	4(%r9),%r10
+	movq	%rsp,%r11
+	negq	%r10
+	leaq	(%rsp,%r10,8),%rsp
+	andq	$-1024,%rsp
+
+	movq	%r11,8(%rsp,%r9,8)
+.Lmul4x_body:
+	movq	%rdi,16(%rsp,%r9,8)
+	movq	%rdx,%r12
+	movq	(%r8),%r8
+	movq	(%r12),%rbx
+	movq	(%rsi),%rax
+
+	xorq	%r14,%r14
+	xorq	%r15,%r15
+
+	movq	%r8,%rbp
+	mulq	%rbx
+	movq	%rax,%r10
+	movq	(%rcx),%rax
+
+	imulq	%r10,%rbp
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r10
+	movq	8(%rsi),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	8(%rcx),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	16(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	leaq	4(%r15),%r15
+	adcq	$0,%rdx
+	movq	%rdi,(%rsp)
+	movq	%rdx,%r13
+	jmp	.L1st4x
+.align	16
+.L1st4x:
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	-16(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	-8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-24(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	-8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%rdi,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-8(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	leaq	4(%r15),%r15
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	-16(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%rdi,-32(%rsp,%r15,8)
+	movq	%rdx,%r13
+	cmpq	%r9,%r15
+	jl	.L1st4x
+
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	-16(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	-8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-24(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	-8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%rdi,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+	xorq	%rdi,%rdi
+	addq	%r10,%r13
+	adcq	$0,%rdi
+	movq	%r13,-8(%rsp,%r15,8)
+	movq	%rdi,(%rsp,%r15,8)
+
+	leaq	1(%r14),%r14
+.align	4
+.Louter4x:
+	movq	(%r12,%r14,8),%rbx
+	xorq	%r15,%r15
+	movq	(%rsp),%r10
+	movq	%r8,%rbp
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	(%rcx),%rax
+	adcq	$0,%rdx
+
+	imulq	%r10,%rbp
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r10
+	movq	8(%rsi),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	8(%rcx),%rax
+	adcq	$0,%rdx
+	addq	8(%rsp),%r11
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	16(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	leaq	4(%r15),%r15
+	adcq	$0,%rdx
+	movq	%rdi,(%rsp)
+	movq	%rdx,%r13
+	jmp	.Linner4x
+.align	16
+.Linner4x:
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	-16(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	-16(%rsp,%r15,8),%r10
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	-8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-24(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	-8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	-8(%rsp,%r15,8),%r11
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%rdi,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	(%rsp,%r15,8),%r10
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-8(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	8(%rsp,%r15,8),%r11
+	adcq	$0,%rdx
+	leaq	4(%r15),%r15
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	-16(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%rdi,-32(%rsp,%r15,8)
+	movq	%rdx,%r13
+	cmpq	%r9,%r15
+	jl	.Linner4x
+
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	-16(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	-16(%rsp,%r15,8),%r10
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	-8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-24(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	-8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	-8(%rsp,%r15,8),%r11
+	adcq	$0,%rdx
+	leaq	1(%r14),%r14
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%rdi,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+	xorq	%rdi,%rdi
+	addq	%r10,%r13
+	adcq	$0,%rdi
+	addq	(%rsp,%r9,8),%r13
+	adcq	$0,%rdi
+	movq	%r13,-8(%rsp,%r15,8)
+	movq	%rdi,(%rsp,%r15,8)
+
+	cmpq	%r9,%r14
+	jl	.Louter4x
+	movq	16(%rsp,%r9,8),%rdi
+	movq	0(%rsp),%rax
+	pxor	%xmm0,%xmm0
+	movq	8(%rsp),%rdx
+	shrq	$2,%r9
+	leaq	(%rsp),%rsi
+	xorq	%r14,%r14
+
+	subq	0(%rcx),%rax
+	movq	16(%rsi),%rbx
+	movq	24(%rsi),%rbp
+	sbbq	8(%rcx),%rdx
+	leaq	-1(%r9),%r15
+	jmp	.Lsub4x
+.align	16
+.Lsub4x:
+	movq	%rax,0(%rdi,%r14,8)
+	movq	%rdx,8(%rdi,%r14,8)
+	sbbq	16(%rcx,%r14,8),%rbx
+	movq	32(%rsi,%r14,8),%rax
+	movq	40(%rsi,%r14,8),%rdx
+	sbbq	24(%rcx,%r14,8),%rbp
+	movq	%rbx,16(%rdi,%r14,8)
+	movq	%rbp,24(%rdi,%r14,8)
+	sbbq	32(%rcx,%r14,8),%rax
+	movq	48(%rsi,%r14,8),%rbx
+	movq	56(%rsi,%r14,8),%rbp
+	sbbq	40(%rcx,%r14,8),%rdx
+	leaq	4(%r14),%r14
+	decq	%r15
+	jnz	.Lsub4x
+
+	movq	%rax,0(%rdi,%r14,8)
+	movq	32(%rsi,%r14,8),%rax
+	sbbq	16(%rcx,%r14,8),%rbx
+	movq	%rdx,8(%rdi,%r14,8)
+	sbbq	24(%rcx,%r14,8),%rbp
+	movq	%rbx,16(%rdi,%r14,8)
+
+	sbbq	$0,%rax
+	movq	%rbp,24(%rdi,%r14,8)
+	xorq	%r14,%r14
+	andq	%rax,%rsi
+	notq	%rax
+	movq	%rdi,%rcx
+	andq	%rax,%rcx
+	leaq	-1(%r9),%r15
+	orq	%rcx,%rsi
+
+	movdqu	(%rsi),%xmm1
+	movdqa	%xmm0,(%rsp)
+	movdqu	%xmm1,(%rdi)
+	jmp	.Lcopy4x
+.align	16
+.Lcopy4x:
+	movdqu	16(%rsi,%r14,1),%xmm2
+	movdqu	32(%rsi,%r14,1),%xmm1
+	movdqa	%xmm0,16(%rsp,%r14,1)
+	movdqu	%xmm2,16(%rdi,%r14,1)
+	movdqa	%xmm0,32(%rsp,%r14,1)
+	movdqu	%xmm1,32(%rdi,%r14,1)
+	leaq	32(%r14),%r14
+	decq	%r15
+	jnz	.Lcopy4x
+
+	shlq	$2,%r9
+	movdqu	16(%rsi,%r14,1),%xmm2
+	movdqa	%xmm0,16(%rsp,%r14,1)
+	movdqu	%xmm2,16(%rdi,%r14,1)
+	movq	8(%rsp,%r9,8),%rsi
+	movq	$1,%rax
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+.Lmul4x_epilogue:
+	.byte	0xf3,0xc3
+.size	bn_mul4x_mont,.-bn_mul4x_mont
+.type	bn_sqr4x_mont,@function
+.align	16
+bn_sqr4x_mont:
+.Lsqr4x_enter:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+
+	shll	$3,%r9d
+	xorq	%r10,%r10
+	movq	%rsp,%r11
+	subq	%r9,%r10
+	movq	(%r8),%r8
+	leaq	-72(%rsp,%r10,2),%rsp
+	andq	$-1024,%rsp
+
+
+
+
+
+
+
+
+
+
+
+	movq	%rdi,32(%rsp)
+	movq	%rcx,40(%rsp)
+	movq	%r8,48(%rsp)
+	movq	%r11,56(%rsp)
+.Lsqr4x_body:
+
+
+
+
+
+
+
+	leaq	32(%r10),%rbp
+	leaq	(%rsi,%r9,1),%rsi
+
+	movq	%r9,%rcx
+
+
+	movq	-32(%rsi,%rbp,1),%r14
+	leaq	64(%rsp,%r9,2),%rdi
+	movq	-24(%rsi,%rbp,1),%rax
+	leaq	-32(%rdi,%rbp,1),%rdi
+	movq	-16(%rsi,%rbp,1),%rbx
+	movq	%rax,%r15
+
+	mulq	%r14
+	movq	%rax,%r10
+	movq	%rbx,%rax
+	movq	%rdx,%r11
+	movq	%r10,-24(%rdi,%rbp,1)
+
+	xorq	%r10,%r10
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%rbx,%rax
+	adcq	%rdx,%r10
+	movq	%r11,-16(%rdi,%rbp,1)
+
+	leaq	-16(%rbp),%rcx
+
+
+	movq	8(%rsi,%rcx,1),%rbx
+	mulq	%r15
+	movq	%rax,%r12
+	movq	%rbx,%rax
+	movq	%rdx,%r13
+
+	xorq	%r11,%r11
+	addq	%r12,%r10
+	leaq	16(%rcx),%rcx
+	adcq	$0,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%rbx,%rax
+	adcq	%rdx,%r11
+	movq	%r10,-8(%rdi,%rcx,1)
+	jmp	.Lsqr4x_1st
+
+.align	16
+.Lsqr4x_1st:
+	movq	(%rsi,%rcx,1),%rbx
+	xorq	%r12,%r12
+	mulq	%r15
+	addq	%rax,%r13
+	movq	%rbx,%rax
+	adcq	%rdx,%r12
+
+	xorq	%r10,%r10
+	addq	%r13,%r11
+	adcq	$0,%r10
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%rbx,%rax
+	adcq	%rdx,%r10
+	movq	%r11,(%rdi,%rcx,1)
+
+
+	movq	8(%rsi,%rcx,1),%rbx
+	xorq	%r13,%r13
+	mulq	%r15
+	addq	%rax,%r12
+	movq	%rbx,%rax
+	adcq	%rdx,%r13
+
+	xorq	%r11,%r11
+	addq	%r12,%r10
+	adcq	$0,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%rbx,%rax
+	adcq	%rdx,%r11
+	movq	%r10,8(%rdi,%rcx,1)
+
+	movq	16(%rsi,%rcx,1),%rbx
+	xorq	%r12,%r12
+	mulq	%r15
+	addq	%rax,%r13
+	movq	%rbx,%rax
+	adcq	%rdx,%r12
+
+	xorq	%r10,%r10
+	addq	%r13,%r11
+	adcq	$0,%r10
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%rbx,%rax
+	adcq	%rdx,%r10
+	movq	%r11,16(%rdi,%rcx,1)
+
+
+	movq	24(%rsi,%rcx,1),%rbx
+	xorq	%r13,%r13
+	mulq	%r15
+	addq	%rax,%r12
+	movq	%rbx,%rax
+	adcq	%rdx,%r13
+
+	xorq	%r11,%r11
+	addq	%r12,%r10
+	leaq	32(%rcx),%rcx
+	adcq	$0,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%rbx,%rax
+	adcq	%rdx,%r11
+	movq	%r10,-8(%rdi,%rcx,1)
+
+	cmpq	$0,%rcx
+	jne	.Lsqr4x_1st
+
+	xorq	%r12,%r12
+	addq	%r11,%r13
+	adcq	$0,%r12
+	mulq	%r15
+	addq	%rax,%r13
+	adcq	%rdx,%r12
+
+	movq	%r13,(%rdi)
+	leaq	16(%rbp),%rbp
+	movq	%r12,8(%rdi)
+	jmp	.Lsqr4x_outer
+
+.align	16
+.Lsqr4x_outer:
+	movq	-32(%rsi,%rbp,1),%r14
+	leaq	64(%rsp,%r9,2),%rdi
+	movq	-24(%rsi,%rbp,1),%rax
+	leaq	-32(%rdi,%rbp,1),%rdi
+	movq	-16(%rsi,%rbp,1),%rbx
+	movq	%rax,%r15
+
+	movq	-24(%rdi,%rbp,1),%r10
+	xorq	%r11,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%rbx,%rax
+	adcq	%rdx,%r11
+	movq	%r10,-24(%rdi,%rbp,1)
+
+	xorq	%r10,%r10
+	addq	-16(%rdi,%rbp,1),%r11
+	adcq	$0,%r10
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%rbx,%rax
+	adcq	%rdx,%r10
+	movq	%r11,-16(%rdi,%rbp,1)
+
+	leaq	-16(%rbp),%rcx
+	xorq	%r12,%r12
+
+
+	movq	8(%rsi,%rcx,1),%rbx
+	xorq	%r13,%r13
+	addq	8(%rdi,%rcx,1),%r12
+	adcq	$0,%r13
+	mulq	%r15
+	addq	%rax,%r12
+	movq	%rbx,%rax
+	adcq	%rdx,%r13
+
+	xorq	%r11,%r11
+	addq	%r12,%r10
+	adcq	$0,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%rbx,%rax
+	adcq	%rdx,%r11
+	movq	%r10,8(%rdi,%rcx,1)
+
+	leaq	16(%rcx),%rcx
+	jmp	.Lsqr4x_inner
+
+.align	16
+.Lsqr4x_inner:
+	movq	(%rsi,%rcx,1),%rbx
+	xorq	%r12,%r12
+	addq	(%rdi,%rcx,1),%r13
+	adcq	$0,%r12
+	mulq	%r15
+	addq	%rax,%r13
+	movq	%rbx,%rax
+	adcq	%rdx,%r12
+
+	xorq	%r10,%r10
+	addq	%r13,%r11
+	adcq	$0,%r10
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%rbx,%rax
+	adcq	%rdx,%r10
+	movq	%r11,(%rdi,%rcx,1)
+
+	movq	8(%rsi,%rcx,1),%rbx
+	xorq	%r13,%r13
+	addq	8(%rdi,%rcx,1),%r12
+	adcq	$0,%r13
+	mulq	%r15
+	addq	%rax,%r12
+	movq	%rbx,%rax
+	adcq	%rdx,%r13
+
+	xorq	%r11,%r11
+	addq	%r12,%r10
+	leaq	16(%rcx),%rcx
+	adcq	$0,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%rbx,%rax
+	adcq	%rdx,%r11
+	movq	%r10,-8(%rdi,%rcx,1)
+
+	cmpq	$0,%rcx
+	jne	.Lsqr4x_inner
+
+	xorq	%r12,%r12
+	addq	%r11,%r13
+	adcq	$0,%r12
+	mulq	%r15
+	addq	%rax,%r13
+	adcq	%rdx,%r12
+
+	movq	%r13,(%rdi)
+	movq	%r12,8(%rdi)
+
+	addq	$16,%rbp
+	jnz	.Lsqr4x_outer
+
+
+	movq	-32(%rsi),%r14
+	leaq	64(%rsp,%r9,2),%rdi
+	movq	-24(%rsi),%rax
+	leaq	-32(%rdi,%rbp,1),%rdi
+	movq	-16(%rsi),%rbx
+	movq	%rax,%r15
+
+	xorq	%r11,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%rbx,%rax
+	adcq	%rdx,%r11
+	movq	%r10,-24(%rdi)
+
+	xorq	%r10,%r10
+	addq	%r13,%r11
+	adcq	$0,%r10
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%rbx,%rax
+	adcq	%rdx,%r10
+	movq	%r11,-16(%rdi)
+
+	movq	-8(%rsi),%rbx
+	mulq	%r15
+	addq	%rax,%r12
+	movq	%rbx,%rax
+	adcq	$0,%rdx
+
+	xorq	%r11,%r11
+	addq	%r12,%r10
+	movq	%rdx,%r13
+	adcq	$0,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%rbx,%rax
+	adcq	%rdx,%r11
+	movq	%r10,-8(%rdi)
+
+	xorq	%r12,%r12
+	addq	%r11,%r13
+	adcq	$0,%r12
+	mulq	%r15
+	addq	%rax,%r13
+	movq	-16(%rsi),%rax
+	adcq	%rdx,%r12
+
+	movq	%r13,(%rdi)
+	movq	%r12,8(%rdi)
+
+	mulq	%rbx
+	addq	$16,%rbp
+	xorq	%r14,%r14
+	subq	%r9,%rbp
+	xorq	%r15,%r15
+
+	addq	%r12,%rax
+	adcq	$0,%rdx
+	movq	%rax,8(%rdi)
+	movq	%rdx,16(%rdi)
+	movq	%r15,24(%rdi)
+
+	movq	-16(%rsi,%rbp,1),%rax
+	leaq	64(%rsp,%r9,2),%rdi
+	xorq	%r10,%r10
+	movq	-24(%rdi,%rbp,2),%r11
+
+	leaq	(%r14,%r10,2),%r12
+	shrq	$63,%r10
+	leaq	(%rcx,%r11,2),%r13
+	shrq	$63,%r11
+	orq	%r10,%r13
+	movq	-16(%rdi,%rbp,2),%r10
+	movq	%r11,%r14
+	mulq	%rax
+	negq	%r15
+	movq	-8(%rdi,%rbp,2),%r11
+	adcq	%rax,%r12
+	movq	-8(%rsi,%rbp,1),%rax
+	movq	%r12,-32(%rdi,%rbp,2)
+	adcq	%rdx,%r13
+
+	leaq	(%r14,%r10,2),%rbx
+	movq	%r13,-24(%rdi,%rbp,2)
+	sbbq	%r15,%r15
+	shrq	$63,%r10
+	leaq	(%rcx,%r11,2),%r8
+	shrq	$63,%r11
+	orq	%r10,%r8
+	movq	0(%rdi,%rbp,2),%r10
+	movq	%r11,%r14
+	mulq	%rax
+	negq	%r15
+	movq	8(%rdi,%rbp,2),%r11
+	adcq	%rax,%rbx
+	movq	0(%rsi,%rbp,1),%rax
+	movq	%rbx,-16(%rdi,%rbp,2)
+	adcq	%rdx,%r8
+	leaq	16(%rbp),%rbp
+	movq	%r8,-40(%rdi,%rbp,2)
+	sbbq	%r15,%r15
+	jmp	.Lsqr4x_shift_n_add
+
+.align	16
+.Lsqr4x_shift_n_add:
+	leaq	(%r14,%r10,2),%r12
+	shrq	$63,%r10
+	leaq	(%rcx,%r11,2),%r13
+	shrq	$63,%r11
+	orq	%r10,%r13
+	movq	-16(%rdi,%rbp,2),%r10
+	movq	%r11,%r14
+	mulq	%rax
+	negq	%r15
+	movq	-8(%rdi,%rbp,2),%r11
+	adcq	%rax,%r12
+	movq	-8(%rsi,%rbp,1),%rax
+	movq	%r12,-32(%rdi,%rbp,2)
+	adcq	%rdx,%r13
+
+	leaq	(%r14,%r10,2),%rbx
+	movq	%r13,-24(%rdi,%rbp,2)
+	sbbq	%r15,%r15
+	shrq	$63,%r10
+	leaq	(%rcx,%r11,2),%r8
+	shrq	$63,%r11
+	orq	%r10,%r8
+	movq	0(%rdi,%rbp,2),%r10
+	movq	%r11,%r14
+	mulq	%rax
+	negq	%r15
+	movq	8(%rdi,%rbp,2),%r11
+	adcq	%rax,%rbx
+	movq	0(%rsi,%rbp,1),%rax
+	movq	%rbx,-16(%rdi,%rbp,2)
+	adcq	%rdx,%r8
+
+	leaq	(%r14,%r10,2),%r12
+	movq	%r8,-8(%rdi,%rbp,2)
+	sbbq	%r15,%r15
+	shrq	$63,%r10
+	leaq	(%rcx,%r11,2),%r13
+	shrq	$63,%r11
+	orq	%r10,%r13
+	movq	16(%rdi,%rbp,2),%r10
+	movq	%r11,%r14
+	mulq	%rax
+	negq	%r15
+	movq	24(%rdi,%rbp,2),%r11
+	adcq	%rax,%r12
+	movq	8(%rsi,%rbp,1),%rax
+	movq	%r12,0(%rdi,%rbp,2)
+	adcq	%rdx,%r13
+
+	leaq	(%r14,%r10,2),%rbx
+	movq	%r13,8(%rdi,%rbp,2)
+	sbbq	%r15,%r15
+	shrq	$63,%r10
+	leaq	(%rcx,%r11,2),%r8
+	shrq	$63,%r11
+	orq	%r10,%r8
+	movq	32(%rdi,%rbp,2),%r10
+	movq	%r11,%r14
+	mulq	%rax
+	negq	%r15
+	movq	40(%rdi,%rbp,2),%r11
+	adcq	%rax,%rbx
+	movq	16(%rsi,%rbp,1),%rax
+	movq	%rbx,16(%rdi,%rbp,2)
+	adcq	%rdx,%r8
+	movq	%r8,24(%rdi,%rbp,2)
+	sbbq	%r15,%r15
+	addq	$32,%rbp
+	jnz	.Lsqr4x_shift_n_add
+
+	leaq	(%r14,%r10,2),%r12
+	shrq	$63,%r10
+	leaq	(%rcx,%r11,2),%r13
+	shrq	$63,%r11
+	orq	%r10,%r13
+	movq	-16(%rdi),%r10
+	movq	%r11,%r14
+	mulq	%rax
+	negq	%r15
+	movq	-8(%rdi),%r11
+	adcq	%rax,%r12
+	movq	-8(%rsi),%rax
+	movq	%r12,-32(%rdi)
+	adcq	%rdx,%r13
+
+	leaq	(%r14,%r10,2),%rbx
+	movq	%r13,-24(%rdi)
+	sbbq	%r15,%r15
+	shrq	$63,%r10
+	leaq	(%rcx,%r11,2),%r8
+	shrq	$63,%r11
+	orq	%r10,%r8
+	mulq	%rax
+	negq	%r15
+	adcq	%rax,%rbx
+	adcq	%rdx,%r8
+	movq	%rbx,-16(%rdi)
+	movq	%r8,-8(%rdi)
+	movq	40(%rsp),%rsi
+	movq	48(%rsp),%r8
+	xorq	%rcx,%rcx
+	movq	%r9,0(%rsp)
+	subq	%r9,%rcx
+	movq	64(%rsp),%r10
+	movq	%r8,%r14
+	leaq	64(%rsp,%r9,2),%rax
+	leaq	64(%rsp,%r9,1),%rdi
+	movq	%rax,8(%rsp)
+	leaq	(%rsi,%r9,1),%rsi
+	xorq	%rbp,%rbp
+
+	movq	0(%rsi,%rcx,1),%rax
+	movq	8(%rsi,%rcx,1),%r9
+	imulq	%r10,%r14
+	movq	%rax,%rbx
+	jmp	.Lsqr4x_mont_outer
+
+.align	16
+.Lsqr4x_mont_outer:
+	xorq	%r11,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%r9,%rax
+	adcq	%rdx,%r11
+	movq	%r8,%r15
+
+	xorq	%r10,%r10
+	addq	8(%rdi,%rcx,1),%r11
+	adcq	$0,%r10
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%rbx,%rax
+	adcq	%rdx,%r10
+
+	imulq	%r11,%r15
+
+	movq	16(%rsi,%rcx,1),%rbx
+	xorq	%r13,%r13
+	addq	%r11,%r12
+	adcq	$0,%r13
+	mulq	%r15
+	addq	%rax,%r12
+	movq	%rbx,%rax
+	adcq	%rdx,%r13
+	movq	%r12,8(%rdi,%rcx,1)
+
+	xorq	%r11,%r11
+	addq	16(%rdi,%rcx,1),%r10
+	adcq	$0,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%r9,%rax
+	adcq	%rdx,%r11
+
+	movq	24(%rsi,%rcx,1),%r9
+	xorq	%r12,%r12
+	addq	%r10,%r13
+	adcq	$0,%r12
+	mulq	%r15
+	addq	%rax,%r13
+	movq	%r9,%rax
+	adcq	%rdx,%r12
+	movq	%r13,16(%rdi,%rcx,1)
+
+	xorq	%r10,%r10
+	addq	24(%rdi,%rcx,1),%r11
+	leaq	32(%rcx),%rcx
+	adcq	$0,%r10
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%rbx,%rax
+	adcq	%rdx,%r10
+	jmp	.Lsqr4x_mont_inner
+
+.align	16
+.Lsqr4x_mont_inner:
+	movq	(%rsi,%rcx,1),%rbx
+	xorq	%r13,%r13
+	addq	%r11,%r12
+	adcq	$0,%r13
+	mulq	%r15
+	addq	%rax,%r12
+	movq	%rbx,%rax
+	adcq	%rdx,%r13
+	movq	%r12,-8(%rdi,%rcx,1)
+
+	xorq	%r11,%r11
+	addq	(%rdi,%rcx,1),%r10
+	adcq	$0,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%r9,%rax
+	adcq	%rdx,%r11
+
+	movq	8(%rsi,%rcx,1),%r9
+	xorq	%r12,%r12
+	addq	%r10,%r13
+	adcq	$0,%r12
+	mulq	%r15
+	addq	%rax,%r13
+	movq	%r9,%rax
+	adcq	%rdx,%r12
+	movq	%r13,(%rdi,%rcx,1)
+
+	xorq	%r10,%r10
+	addq	8(%rdi,%rcx,1),%r11
+	adcq	$0,%r10
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%rbx,%rax
+	adcq	%rdx,%r10
+
+
+	movq	16(%rsi,%rcx,1),%rbx
+	xorq	%r13,%r13
+	addq	%r11,%r12
+	adcq	$0,%r13
+	mulq	%r15
+	addq	%rax,%r12
+	movq	%rbx,%rax
+	adcq	%rdx,%r13
+	movq	%r12,8(%rdi,%rcx,1)
+
+	xorq	%r11,%r11
+	addq	16(%rdi,%rcx,1),%r10
+	adcq	$0,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%r9,%rax
+	adcq	%rdx,%r11
+
+	movq	24(%rsi,%rcx,1),%r9
+	xorq	%r12,%r12
+	addq	%r10,%r13
+	adcq	$0,%r12
+	mulq	%r15
+	addq	%rax,%r13
+	movq	%r9,%rax
+	adcq	%rdx,%r12
+	movq	%r13,16(%rdi,%rcx,1)
+
+	xorq	%r10,%r10
+	addq	24(%rdi,%rcx,1),%r11
+	leaq	32(%rcx),%rcx
+	adcq	$0,%r10
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%rbx,%rax
+	adcq	%rdx,%r10
+	cmpq	$0,%rcx
+	jne	.Lsqr4x_mont_inner
+
+	subq	0(%rsp),%rcx
+	movq	%r8,%r14
+
+	xorq	%r13,%r13
+	addq	%r11,%r12
+	adcq	$0,%r13
+	mulq	%r15
+	addq	%rax,%r12
+	movq	%r9,%rax
+	adcq	%rdx,%r13
+	movq	%r12,-8(%rdi)
+
+	xorq	%r11,%r11
+	addq	(%rdi),%r10
+	adcq	$0,%r11
+	movq	0(%rsi,%rcx,1),%rbx
+	addq	%rbp,%r10
+	adcq	$0,%r11
+
+	imulq	16(%rdi,%rcx,1),%r14
+	xorq	%r12,%r12
+	movq	8(%rsi,%rcx,1),%r9
+	addq	%r10,%r13
+	movq	16(%rdi,%rcx,1),%r10
+	adcq	$0,%r12
+	mulq	%r15
+	addq	%rax,%r13
+	movq	%rbx,%rax
+	adcq	%rdx,%r12
+	movq	%r13,(%rdi)
+
+	xorq	%rbp,%rbp
+	addq	8(%rdi),%r12
+	adcq	%rbp,%rbp
+	addq	%r11,%r12
+	leaq	16(%rdi),%rdi
+	adcq	$0,%rbp
+	movq	%r12,-8(%rdi)
+	cmpq	8(%rsp),%rdi
+	jb	.Lsqr4x_mont_outer
+
+	movq	0(%rsp),%r9
+	movq	%rbp,(%rdi)
+	movq	64(%rsp,%r9,1),%rax
+	leaq	64(%rsp,%r9,1),%rbx
+	movq	40(%rsp),%rsi
+	shrq	$5,%r9
+	movq	8(%rbx),%rdx
+	xorq	%rbp,%rbp
+
+	movq	32(%rsp),%rdi
+	subq	0(%rsi),%rax
+	movq	16(%rbx),%r10
+	movq	24(%rbx),%r11
+	sbbq	8(%rsi),%rdx
+	leaq	-1(%r9),%rcx
+	jmp	.Lsqr4x_sub
+.align	16
+.Lsqr4x_sub:
+	movq	%rax,0(%rdi,%rbp,8)
+	movq	%rdx,8(%rdi,%rbp,8)
+	sbbq	16(%rsi,%rbp,8),%r10
+	movq	32(%rbx,%rbp,8),%rax
+	movq	40(%rbx,%rbp,8),%rdx
+	sbbq	24(%rsi,%rbp,8),%r11
+	movq	%r10,16(%rdi,%rbp,8)
+	movq	%r11,24(%rdi,%rbp,8)
+	sbbq	32(%rsi,%rbp,8),%rax
+	movq	48(%rbx,%rbp,8),%r10
+	movq	56(%rbx,%rbp,8),%r11
+	sbbq	40(%rsi,%rbp,8),%rdx
+	leaq	4(%rbp),%rbp
+	decq	%rcx
+	jnz	.Lsqr4x_sub
+
+	movq	%rax,0(%rdi,%rbp,8)
+	movq	32(%rbx,%rbp,8),%rax
+	sbbq	16(%rsi,%rbp,8),%r10
+	movq	%rdx,8(%rdi,%rbp,8)
+	sbbq	24(%rsi,%rbp,8),%r11
+	movq	%r10,16(%rdi,%rbp,8)
+
+	sbbq	$0,%rax
+	movq	%r11,24(%rdi,%rbp,8)
+	xorq	%rbp,%rbp
+	andq	%rax,%rbx
+	notq	%rax
+	movq	%rdi,%rsi
+	andq	%rax,%rsi
+	leaq	-1(%r9),%rcx
+	orq	%rsi,%rbx
+
+	pxor	%xmm0,%xmm0
+	leaq	64(%rsp,%r9,8),%rsi
+	movdqu	(%rbx),%xmm1
+	leaq	(%rsi,%r9,8),%rsi
+	movdqa	%xmm0,64(%rsp)
+	movdqa	%xmm0,(%rsi)
+	movdqu	%xmm1,(%rdi)
+	jmp	.Lsqr4x_copy
+.align	16
+.Lsqr4x_copy:
+	movdqu	16(%rbx,%rbp,1),%xmm2
+	movdqu	32(%rbx,%rbp,1),%xmm1
+	movdqa	%xmm0,80(%rsp,%rbp,1)
+	movdqa	%xmm0,96(%rsp,%rbp,1)
+	movdqa	%xmm0,16(%rsi,%rbp,1)
+	movdqa	%xmm0,32(%rsi,%rbp,1)
+	movdqu	%xmm2,16(%rdi,%rbp,1)
+	movdqu	%xmm1,32(%rdi,%rbp,1)
+	leaq	32(%rbp),%rbp
+	decq	%rcx
+	jnz	.Lsqr4x_copy
+
+	movdqu	16(%rbx,%rbp,1),%xmm2
+	movdqa	%xmm0,80(%rsp,%rbp,1)
+	movdqa	%xmm0,16(%rsi,%rbp,1)
+	movdqu	%xmm2,16(%rdi,%rbp,1)
+	movq	56(%rsp),%rsi
+	movq	$1,%rax
+	movq	0(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+.Lsqr4x_epilogue:
+	.byte	0xf3,0xc3
+.size	bn_sqr4x_mont,.-bn_sqr4x_mont
+.byte	77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align	16
+#if defined(HAVE_GNU_STACK)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/crypto/libressl/crypto/bn/mont-macosx-x86_64.s b/crypto/libressl/crypto/bn/mont-macosx-x86_64.s
new file mode 100644
index 0000000000..293d2b1766
--- /dev/null
+++ b/crypto/libressl/crypto/bn/mont-macosx-x86_64.s
@@ -0,0 +1,1374 @@
+.text	
+
+.globl	_bn_mul_mont
+
+.p2align	4
+_bn_mul_mont:
+	testl	$3,%r9d
+	jnz	L$mul_enter
+	cmpl	$8,%r9d
+	jb	L$mul_enter
+	cmpq	%rsi,%rdx
+	jne	L$mul4x_enter
+	jmp	L$sqr4x_enter
+
+.p2align	4
+L$mul_enter:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+
+	movl	%r9d,%r9d
+	leaq	2(%r9),%r10
+	movq	%rsp,%r11
+	negq	%r10
+	leaq	(%rsp,%r10,8),%rsp
+	andq	$-1024,%rsp
+
+	movq	%r11,8(%rsp,%r9,8)
+L$mul_body:
+	movq	%rdx,%r12
+	movq	(%r8),%r8
+	movq	(%r12),%rbx
+	movq	(%rsi),%rax
+
+	xorq	%r14,%r14
+	xorq	%r15,%r15
+
+	movq	%r8,%rbp
+	mulq	%rbx
+	movq	%rax,%r10
+	movq	(%rcx),%rax
+
+	imulq	%r10,%rbp
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r10
+	movq	8(%rsi),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r13
+
+	leaq	1(%r15),%r15
+	jmp	L$1st_enter
+
+.p2align	4
+L$1st:
+	addq	%rax,%r13
+	movq	(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%r13
+	movq	%r10,%r11
+	adcq	$0,%rdx
+	movq	%r13,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+L$1st_enter:
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	leaq	1(%r15),%r15
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	cmpq	%r9,%r15
+	jl	L$1st
+
+	addq	%rax,%r13
+	movq	(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r11,%r13
+	adcq	$0,%rdx
+	movq	%r13,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+	movq	%r10,%r11
+
+	xorq	%rdx,%rdx
+	addq	%r11,%r13
+	adcq	$0,%rdx
+	movq	%r13,-8(%rsp,%r9,8)
+	movq	%rdx,(%rsp,%r9,8)
+
+	leaq	1(%r14),%r14
+	jmp	L$outer
+.p2align	4
+L$outer:
+	movq	(%r12,%r14,8),%rbx
+	xorq	%r15,%r15
+	movq	%r8,%rbp
+	movq	(%rsp),%r10
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	(%rcx),%rax
+	adcq	$0,%rdx
+
+	imulq	%r10,%rbp
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r10
+	movq	8(%rsi),%rax
+	adcq	$0,%rdx
+	movq	8(%rsp),%r10
+	movq	%rdx,%r13
+
+	leaq	1(%r15),%r15
+	jmp	L$inner_enter
+
+.p2align	4
+L$inner:
+	addq	%rax,%r13
+	movq	(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	movq	(%rsp,%r15,8),%r10
+	adcq	$0,%rdx
+	movq	%r13,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+L$inner_enter:
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%r10
+	movq	%rdx,%r11
+	adcq	$0,%r11
+	leaq	1(%r15),%r15
+
+	mulq	%rbp
+	cmpq	%r9,%r15
+	jl	L$inner
+
+	addq	%rax,%r13
+	movq	(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	movq	(%rsp,%r15,8),%r10
+	adcq	$0,%rdx
+	movq	%r13,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+	xorq	%rdx,%rdx
+	addq	%r11,%r13
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-8(%rsp,%r9,8)
+	movq	%rdx,(%rsp,%r9,8)
+
+	leaq	1(%r14),%r14
+	cmpq	%r9,%r14
+	jl	L$outer
+
+	xorq	%r14,%r14
+	movq	(%rsp),%rax
+	leaq	(%rsp),%rsi
+	movq	%r9,%r15
+	jmp	L$sub
+.p2align	4
+L$sub:	sbbq	(%rcx,%r14,8),%rax
+	movq	%rax,(%rdi,%r14,8)
+	movq	8(%rsi,%r14,8),%rax
+	leaq	1(%r14),%r14
+	decq	%r15
+	jnz	L$sub
+
+	sbbq	$0,%rax
+	xorq	%r14,%r14
+	andq	%rax,%rsi
+	notq	%rax
+	movq	%rdi,%rcx
+	andq	%rax,%rcx
+	movq	%r9,%r15
+	orq	%rcx,%rsi
+.p2align	4
+L$copy:
+	movq	(%rsi,%r14,8),%rax
+	movq	%r14,(%rsp,%r14,8)
+	movq	%rax,(%rdi,%r14,8)
+	leaq	1(%r14),%r14
+	subq	$1,%r15
+	jnz	L$copy
+
+	movq	8(%rsp,%r9,8),%rsi
+	movq	$1,%rax
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+L$mul_epilogue:
+	.byte	0xf3,0xc3
+
+
+.p2align	4
+bn_mul4x_mont:
+L$mul4x_enter:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+
+	movl	%r9d,%r9d
+	leaq	4(%r9),%r10
+	movq	%rsp,%r11
+	negq	%r10
+	leaq	(%rsp,%r10,8),%rsp
+	andq	$-1024,%rsp
+
+	movq	%r11,8(%rsp,%r9,8)
+L$mul4x_body:
+	movq	%rdi,16(%rsp,%r9,8)
+	movq	%rdx,%r12
+	movq	(%r8),%r8
+	movq	(%r12),%rbx
+	movq	(%rsi),%rax
+
+	xorq	%r14,%r14
+	xorq	%r15,%r15
+
+	movq	%r8,%rbp
+	mulq	%rbx
+	movq	%rax,%r10
+	movq	(%rcx),%rax
+
+	imulq	%r10,%rbp
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r10
+	movq	8(%rsi),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	8(%rcx),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	16(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	leaq	4(%r15),%r15
+	adcq	$0,%rdx
+	movq	%rdi,(%rsp)
+	movq	%rdx,%r13
+	jmp	L$1st4x
+.p2align	4
+L$1st4x:
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	-16(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	-8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-24(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	-8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%rdi,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-8(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	leaq	4(%r15),%r15
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	-16(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%rdi,-32(%rsp,%r15,8)
+	movq	%rdx,%r13
+	cmpq	%r9,%r15
+	jl	L$1st4x
+
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	-16(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	-8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-24(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	-8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%rdi,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+	xorq	%rdi,%rdi
+	addq	%r10,%r13
+	adcq	$0,%rdi
+	movq	%r13,-8(%rsp,%r15,8)
+	movq	%rdi,(%rsp,%r15,8)
+
+	leaq	1(%r14),%r14
+.p2align	2
+L$outer4x:
+	movq	(%r12,%r14,8),%rbx
+	xorq	%r15,%r15
+	movq	(%rsp),%r10
+	movq	%r8,%rbp
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	(%rcx),%rax
+	adcq	$0,%rdx
+
+	imulq	%r10,%rbp
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r10
+	movq	8(%rsi),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	8(%rcx),%rax
+	adcq	$0,%rdx
+	addq	8(%rsp),%r11
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	16(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	leaq	4(%r15),%r15
+	adcq	$0,%rdx
+	movq	%rdi,(%rsp)
+	movq	%rdx,%r13
+	jmp	L$inner4x
+.p2align	4
+L$inner4x:
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	-16(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	-16(%rsp,%r15,8),%r10
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	-8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-24(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	-8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	-8(%rsp,%r15,8),%r11
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%rdi,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	(%rsp,%r15,8),%r10
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-8(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	8(%rsp,%r15,8),%r11
+	adcq	$0,%rdx
+	leaq	4(%r15),%r15
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	-16(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%rdi,-32(%rsp,%r15,8)
+	movq	%rdx,%r13
+	cmpq	%r9,%r15
+	jl	L$inner4x
+
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	-16(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	-16(%rsp,%r15,8),%r10
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	-8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-24(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	-8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	-8(%rsp,%r15,8),%r11
+	adcq	$0,%rdx
+	leaq	1(%r14),%r14
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%rdi,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+	xorq	%rdi,%rdi
+	addq	%r10,%r13
+	adcq	$0,%rdi
+	addq	(%rsp,%r9,8),%r13
+	adcq	$0,%rdi
+	movq	%r13,-8(%rsp,%r15,8)
+	movq	%rdi,(%rsp,%r15,8)
+
+	cmpq	%r9,%r14
+	jl	L$outer4x
+	movq	16(%rsp,%r9,8),%rdi
+	movq	0(%rsp),%rax
+	pxor	%xmm0,%xmm0
+	movq	8(%rsp),%rdx
+	shrq	$2,%r9
+	leaq	(%rsp),%rsi
+	xorq	%r14,%r14
+
+	subq	0(%rcx),%rax
+	movq	16(%rsi),%rbx
+	movq	24(%rsi),%rbp
+	sbbq	8(%rcx),%rdx
+	leaq	-1(%r9),%r15
+	jmp	L$sub4x
+.p2align	4
+L$sub4x:
+	movq	%rax,0(%rdi,%r14,8)
+	movq	%rdx,8(%rdi,%r14,8)
+	sbbq	16(%rcx,%r14,8),%rbx
+	movq	32(%rsi,%r14,8),%rax
+	movq	40(%rsi,%r14,8),%rdx
+	sbbq	24(%rcx,%r14,8),%rbp
+	movq	%rbx,16(%rdi,%r14,8)
+	movq	%rbp,24(%rdi,%r14,8)
+	sbbq	32(%rcx,%r14,8),%rax
+	movq	48(%rsi,%r14,8),%rbx
+	movq	56(%rsi,%r14,8),%rbp
+	sbbq	40(%rcx,%r14,8),%rdx
+	leaq	4(%r14),%r14
+	decq	%r15
+	jnz	L$sub4x
+
+	movq	%rax,0(%rdi,%r14,8)
+	movq	32(%rsi,%r14,8),%rax
+	sbbq	16(%rcx,%r14,8),%rbx
+	movq	%rdx,8(%rdi,%r14,8)
+	sbbq	24(%rcx,%r14,8),%rbp
+	movq	%rbx,16(%rdi,%r14,8)
+
+	sbbq	$0,%rax
+	movq	%rbp,24(%rdi,%r14,8)
+	xorq	%r14,%r14
+	andq	%rax,%rsi
+	notq	%rax
+	movq	%rdi,%rcx
+	andq	%rax,%rcx
+	leaq	-1(%r9),%r15
+	orq	%rcx,%rsi
+
+	movdqu	(%rsi),%xmm1
+	movdqa	%xmm0,(%rsp)
+	movdqu	%xmm1,(%rdi)
+	jmp	L$copy4x
+.p2align	4
+L$copy4x:
+	movdqu	16(%rsi,%r14,1),%xmm2
+	movdqu	32(%rsi,%r14,1),%xmm1
+	movdqa	%xmm0,16(%rsp,%r14,1)
+	movdqu	%xmm2,16(%rdi,%r14,1)
+	movdqa	%xmm0,32(%rsp,%r14,1)
+	movdqu	%xmm1,32(%rdi,%r14,1)
+	leaq	32(%r14),%r14
+	decq	%r15
+	jnz	L$copy4x
+
+	shlq	$2,%r9
+	movdqu	16(%rsi,%r14,1),%xmm2
+	movdqa	%xmm0,16(%rsp,%r14,1)
+	movdqu	%xmm2,16(%rdi,%r14,1)
+	movq	8(%rsp,%r9,8),%rsi
+	movq	$1,%rax
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+L$mul4x_epilogue:
+	.byte	0xf3,0xc3
+
+
+.p2align	4
+bn_sqr4x_mont:
+L$sqr4x_enter:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+
+	shll	$3,%r9d
+	xorq	%r10,%r10
+	movq	%rsp,%r11
+	subq	%r9,%r10
+	movq	(%r8),%r8
+	leaq	-72(%rsp,%r10,2),%rsp
+	andq	$-1024,%rsp
+
+
+
+
+
+
+
+
+
+
+
+	movq	%rdi,32(%rsp)
+	movq	%rcx,40(%rsp)
+	movq	%r8,48(%rsp)
+	movq	%r11,56(%rsp)
+L$sqr4x_body:
+
+
+
+
+
+
+
+	leaq	32(%r10),%rbp
+	leaq	(%rsi,%r9,1),%rsi
+
+	movq	%r9,%rcx
+
+
+	movq	-32(%rsi,%rbp,1),%r14
+	leaq	64(%rsp,%r9,2),%rdi
+	movq	-24(%rsi,%rbp,1),%rax
+	leaq	-32(%rdi,%rbp,1),%rdi
+	movq	-16(%rsi,%rbp,1),%rbx
+	movq	%rax,%r15
+
+	mulq	%r14
+	movq	%rax,%r10
+	movq	%rbx,%rax
+	movq	%rdx,%r11
+	movq	%r10,-24(%rdi,%rbp,1)
+
+	xorq	%r10,%r10
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%rbx,%rax
+	adcq	%rdx,%r10
+	movq	%r11,-16(%rdi,%rbp,1)
+
+	leaq	-16(%rbp),%rcx
+
+
+	movq	8(%rsi,%rcx,1),%rbx
+	mulq	%r15
+	movq	%rax,%r12
+	movq	%rbx,%rax
+	movq	%rdx,%r13
+
+	xorq	%r11,%r11
+	addq	%r12,%r10
+	leaq	16(%rcx),%rcx
+	adcq	$0,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%rbx,%rax
+	adcq	%rdx,%r11
+	movq	%r10,-8(%rdi,%rcx,1)
+	jmp	L$sqr4x_1st
+
+.p2align	4
+L$sqr4x_1st:
+	movq	(%rsi,%rcx,1),%rbx
+	xorq	%r12,%r12
+	mulq	%r15
+	addq	%rax,%r13
+	movq	%rbx,%rax
+	adcq	%rdx,%r12
+
+	xorq	%r10,%r10
+	addq	%r13,%r11
+	adcq	$0,%r10
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%rbx,%rax
+	adcq	%rdx,%r10
+	movq	%r11,(%rdi,%rcx,1)
+
+
+	movq	8(%rsi,%rcx,1),%rbx
+	xorq	%r13,%r13
+	mulq	%r15
+	addq	%rax,%r12
+	movq	%rbx,%rax
+	adcq	%rdx,%r13
+
+	xorq	%r11,%r11
+	addq	%r12,%r10
+	adcq	$0,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%rbx,%rax
+	adcq	%rdx,%r11
+	movq	%r10,8(%rdi,%rcx,1)
+
+	movq	16(%rsi,%rcx,1),%rbx
+	xorq	%r12,%r12
+	mulq	%r15
+	addq	%rax,%r13
+	movq	%rbx,%rax
+	adcq	%rdx,%r12
+
+	xorq	%r10,%r10
+	addq	%r13,%r11
+	adcq	$0,%r10
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%rbx,%rax
+	adcq	%rdx,%r10
+	movq	%r11,16(%rdi,%rcx,1)
+
+
+	movq	24(%rsi,%rcx,1),%rbx
+	xorq	%r13,%r13
+	mulq	%r15
+	addq	%rax,%r12
+	movq	%rbx,%rax
+	adcq	%rdx,%r13
+
+	xorq	%r11,%r11
+	addq	%r12,%r10
+	leaq	32(%rcx),%rcx
+	adcq	$0,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%rbx,%rax
+	adcq	%rdx,%r11
+	movq	%r10,-8(%rdi,%rcx,1)
+
+	cmpq	$0,%rcx
+	jne	L$sqr4x_1st
+
+	xorq	%r12,%r12
+	addq	%r11,%r13
+	adcq	$0,%r12
+	mulq	%r15
+	addq	%rax,%r13
+	adcq	%rdx,%r12
+
+	movq	%r13,(%rdi)
+	leaq	16(%rbp),%rbp
+	movq	%r12,8(%rdi)
+	jmp	L$sqr4x_outer
+
+.p2align	4
+L$sqr4x_outer:
+	movq	-32(%rsi,%rbp,1),%r14
+	leaq	64(%rsp,%r9,2),%rdi
+	movq	-24(%rsi,%rbp,1),%rax
+	leaq	-32(%rdi,%rbp,1),%rdi
+	movq	-16(%rsi,%rbp,1),%rbx
+	movq	%rax,%r15
+
+	movq	-24(%rdi,%rbp,1),%r10
+	xorq	%r11,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%rbx,%rax
+	adcq	%rdx,%r11
+	movq	%r10,-24(%rdi,%rbp,1)
+
+	xorq	%r10,%r10
+	addq	-16(%rdi,%rbp,1),%r11
+	adcq	$0,%r10
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%rbx,%rax
+	adcq	%rdx,%r10
+	movq	%r11,-16(%rdi,%rbp,1)
+
+	leaq	-16(%rbp),%rcx
+	xorq	%r12,%r12
+
+
+	movq	8(%rsi,%rcx,1),%rbx
+	xorq	%r13,%r13
+	addq	8(%rdi,%rcx,1),%r12
+	adcq	$0,%r13
+	mulq	%r15
+	addq	%rax,%r12
+	movq	%rbx,%rax
+	adcq	%rdx,%r13
+
+	xorq	%r11,%r11
+	addq	%r12,%r10
+	adcq	$0,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%rbx,%rax
+	adcq	%rdx,%r11
+	movq	%r10,8(%rdi,%rcx,1)
+
+	leaq	16(%rcx),%rcx
+	jmp	L$sqr4x_inner
+
+.p2align	4
+L$sqr4x_inner:
+	movq	(%rsi,%rcx,1),%rbx
+	xorq	%r12,%r12
+	addq	(%rdi,%rcx,1),%r13
+	adcq	$0,%r12
+	mulq	%r15
+	addq	%rax,%r13
+	movq	%rbx,%rax
+	adcq	%rdx,%r12
+
+	xorq	%r10,%r10
+	addq	%r13,%r11
+	adcq	$0,%r10
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%rbx,%rax
+	adcq	%rdx,%r10
+	movq	%r11,(%rdi,%rcx,1)
+
+	movq	8(%rsi,%rcx,1),%rbx
+	xorq	%r13,%r13
+	addq	8(%rdi,%rcx,1),%r12
+	adcq	$0,%r13
+	mulq	%r15
+	addq	%rax,%r12
+	movq	%rbx,%rax
+	adcq	%rdx,%r13
+
+	xorq	%r11,%r11
+	addq	%r12,%r10
+	leaq	16(%rcx),%rcx
+	adcq	$0,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%rbx,%rax
+	adcq	%rdx,%r11
+	movq	%r10,-8(%rdi,%rcx,1)
+
+	cmpq	$0,%rcx
+	jne	L$sqr4x_inner
+
+	xorq	%r12,%r12
+	addq	%r11,%r13
+	adcq	$0,%r12
+	mulq	%r15
+	addq	%rax,%r13
+	adcq	%rdx,%r12
+
+	movq	%r13,(%rdi)
+	movq	%r12,8(%rdi)
+
+	addq	$16,%rbp
+	jnz	L$sqr4x_outer
+
+
+	movq	-32(%rsi),%r14
+	leaq	64(%rsp,%r9,2),%rdi
+	movq	-24(%rsi),%rax
+	leaq	-32(%rdi,%rbp,1),%rdi
+	movq	-16(%rsi),%rbx
+	movq	%rax,%r15
+
+	xorq	%r11,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%rbx,%rax
+	adcq	%rdx,%r11
+	movq	%r10,-24(%rdi)
+
+	xorq	%r10,%r10
+	addq	%r13,%r11
+	adcq	$0,%r10
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%rbx,%rax
+	adcq	%rdx,%r10
+	movq	%r11,-16(%rdi)
+
+	movq	-8(%rsi),%rbx
+	mulq	%r15
+	addq	%rax,%r12
+	movq	%rbx,%rax
+	adcq	$0,%rdx
+
+	xorq	%r11,%r11
+	addq	%r12,%r10
+	movq	%rdx,%r13
+	adcq	$0,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%rbx,%rax
+	adcq	%rdx,%r11
+	movq	%r10,-8(%rdi)
+
+	xorq	%r12,%r12
+	addq	%r11,%r13
+	adcq	$0,%r12
+	mulq	%r15
+	addq	%rax,%r13
+	movq	-16(%rsi),%rax
+	adcq	%rdx,%r12
+
+	movq	%r13,(%rdi)
+	movq	%r12,8(%rdi)
+
+	mulq	%rbx
+	addq	$16,%rbp
+	xorq	%r14,%r14
+	subq	%r9,%rbp
+	xorq	%r15,%r15
+
+	addq	%r12,%rax
+	adcq	$0,%rdx
+	movq	%rax,8(%rdi)
+	movq	%rdx,16(%rdi)
+	movq	%r15,24(%rdi)
+
+	movq	-16(%rsi,%rbp,1),%rax
+	leaq	64(%rsp,%r9,2),%rdi
+	xorq	%r10,%r10
+	movq	-24(%rdi,%rbp,2),%r11
+
+	leaq	(%r14,%r10,2),%r12
+	shrq	$63,%r10
+	leaq	(%rcx,%r11,2),%r13
+	shrq	$63,%r11
+	orq	%r10,%r13
+	movq	-16(%rdi,%rbp,2),%r10
+	movq	%r11,%r14
+	mulq	%rax
+	negq	%r15
+	movq	-8(%rdi,%rbp,2),%r11
+	adcq	%rax,%r12
+	movq	-8(%rsi,%rbp,1),%rax
+	movq	%r12,-32(%rdi,%rbp,2)
+	adcq	%rdx,%r13
+
+	leaq	(%r14,%r10,2),%rbx
+	movq	%r13,-24(%rdi,%rbp,2)
+	sbbq	%r15,%r15
+	shrq	$63,%r10
+	leaq	(%rcx,%r11,2),%r8
+	shrq	$63,%r11
+	orq	%r10,%r8
+	movq	0(%rdi,%rbp,2),%r10
+	movq	%r11,%r14
+	mulq	%rax
+	negq	%r15
+	movq	8(%rdi,%rbp,2),%r11
+	adcq	%rax,%rbx
+	movq	0(%rsi,%rbp,1),%rax
+	movq	%rbx,-16(%rdi,%rbp,2)
+	adcq	%rdx,%r8
+	leaq	16(%rbp),%rbp
+	movq	%r8,-40(%rdi,%rbp,2)
+	sbbq	%r15,%r15
+	jmp	L$sqr4x_shift_n_add
+
+.p2align	4
+L$sqr4x_shift_n_add:
+	leaq	(%r14,%r10,2),%r12
+	shrq	$63,%r10
+	leaq	(%rcx,%r11,2),%r13
+	shrq	$63,%r11
+	orq	%r10,%r13
+	movq	-16(%rdi,%rbp,2),%r10
+	movq	%r11,%r14
+	mulq	%rax
+	negq	%r15
+	movq	-8(%rdi,%rbp,2),%r11
+	adcq	%rax,%r12
+	movq	-8(%rsi,%rbp,1),%rax
+	movq	%r12,-32(%rdi,%rbp,2)
+	adcq	%rdx,%r13
+
+	leaq	(%r14,%r10,2),%rbx
+	movq	%r13,-24(%rdi,%rbp,2)
+	sbbq	%r15,%r15
+	shrq	$63,%r10
+	leaq	(%rcx,%r11,2),%r8
+	shrq	$63,%r11
+	orq	%r10,%r8
+	movq	0(%rdi,%rbp,2),%r10
+	movq	%r11,%r14
+	mulq	%rax
+	negq	%r15
+	movq	8(%rdi,%rbp,2),%r11
+	adcq	%rax,%rbx
+	movq	0(%rsi,%rbp,1),%rax
+	movq	%rbx,-16(%rdi,%rbp,2)
+	adcq	%rdx,%r8
+
+	leaq	(%r14,%r10,2),%r12
+	movq	%r8,-8(%rdi,%rbp,2)
+	sbbq	%r15,%r15
+	shrq	$63,%r10
+	leaq	(%rcx,%r11,2),%r13
+	shrq	$63,%r11
+	orq	%r10,%r13
+	movq	16(%rdi,%rbp,2),%r10
+	movq	%r11,%r14
+	mulq	%rax
+	negq	%r15
+	movq	24(%rdi,%rbp,2),%r11
+	adcq	%rax,%r12
+	movq	8(%rsi,%rbp,1),%rax
+	movq	%r12,0(%rdi,%rbp,2)
+	adcq	%rdx,%r13
+
+	leaq	(%r14,%r10,2),%rbx
+	movq	%r13,8(%rdi,%rbp,2)
+	sbbq	%r15,%r15
+	shrq	$63,%r10
+	leaq	(%rcx,%r11,2),%r8
+	shrq	$63,%r11
+	orq	%r10,%r8
+	movq	32(%rdi,%rbp,2),%r10
+	movq	%r11,%r14
+	mulq	%rax
+	negq	%r15
+	movq	40(%rdi,%rbp,2),%r11
+	adcq	%rax,%rbx
+	movq	16(%rsi,%rbp,1),%rax
+	movq	%rbx,16(%rdi,%rbp,2)
+	adcq	%rdx,%r8
+	movq	%r8,24(%rdi,%rbp,2)
+	sbbq	%r15,%r15
+	addq	$32,%rbp
+	jnz	L$sqr4x_shift_n_add
+
+	leaq	(%r14,%r10,2),%r12
+	shrq	$63,%r10
+	leaq	(%rcx,%r11,2),%r13
+	shrq	$63,%r11
+	orq	%r10,%r13
+	movq	-16(%rdi),%r10
+	movq	%r11,%r14
+	mulq	%rax
+	negq	%r15
+	movq	-8(%rdi),%r11
+	adcq	%rax,%r12
+	movq	-8(%rsi),%rax
+	movq	%r12,-32(%rdi)
+	adcq	%rdx,%r13
+
+	leaq	(%r14,%r10,2),%rbx
+	movq	%r13,-24(%rdi)
+	sbbq	%r15,%r15
+	shrq	$63,%r10
+	leaq	(%rcx,%r11,2),%r8
+	shrq	$63,%r11
+	orq	%r10,%r8
+	mulq	%rax
+	negq	%r15
+	adcq	%rax,%rbx
+	adcq	%rdx,%r8
+	movq	%rbx,-16(%rdi)
+	movq	%r8,-8(%rdi)
+	movq	40(%rsp),%rsi
+	movq	48(%rsp),%r8
+	xorq	%rcx,%rcx
+	movq	%r9,0(%rsp)
+	subq	%r9,%rcx
+	movq	64(%rsp),%r10
+	movq	%r8,%r14
+	leaq	64(%rsp,%r9,2),%rax
+	leaq	64(%rsp,%r9,1),%rdi
+	movq	%rax,8(%rsp)
+	leaq	(%rsi,%r9,1),%rsi
+	xorq	%rbp,%rbp
+
+	movq	0(%rsi,%rcx,1),%rax
+	movq	8(%rsi,%rcx,1),%r9
+	imulq	%r10,%r14
+	movq	%rax,%rbx
+	jmp	L$sqr4x_mont_outer
+
+.p2align	4
+L$sqr4x_mont_outer:
+	xorq	%r11,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%r9,%rax
+	adcq	%rdx,%r11
+	movq	%r8,%r15
+
+	xorq	%r10,%r10
+	addq	8(%rdi,%rcx,1),%r11
+	adcq	$0,%r10
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%rbx,%rax
+	adcq	%rdx,%r10
+
+	imulq	%r11,%r15
+
+	movq	16(%rsi,%rcx,1),%rbx
+	xorq	%r13,%r13
+	addq	%r11,%r12
+	adcq	$0,%r13
+	mulq	%r15
+	addq	%rax,%r12
+	movq	%rbx,%rax
+	adcq	%rdx,%r13
+	movq	%r12,8(%rdi,%rcx,1)
+
+	xorq	%r11,%r11
+	addq	16(%rdi,%rcx,1),%r10
+	adcq	$0,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%r9,%rax
+	adcq	%rdx,%r11
+
+	movq	24(%rsi,%rcx,1),%r9
+	xorq	%r12,%r12
+	addq	%r10,%r13
+	adcq	$0,%r12
+	mulq	%r15
+	addq	%rax,%r13
+	movq	%r9,%rax
+	adcq	%rdx,%r12
+	movq	%r13,16(%rdi,%rcx,1)
+
+	xorq	%r10,%r10
+	addq	24(%rdi,%rcx,1),%r11
+	leaq	32(%rcx),%rcx
+	adcq	$0,%r10
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%rbx,%rax
+	adcq	%rdx,%r10
+	jmp	L$sqr4x_mont_inner
+
+.p2align	4
+L$sqr4x_mont_inner:
+	movq	(%rsi,%rcx,1),%rbx
+	xorq	%r13,%r13
+	addq	%r11,%r12
+	adcq	$0,%r13
+	mulq	%r15
+	addq	%rax,%r12
+	movq	%rbx,%rax
+	adcq	%rdx,%r13
+	movq	%r12,-8(%rdi,%rcx,1)
+
+	xorq	%r11,%r11
+	addq	(%rdi,%rcx,1),%r10
+	adcq	$0,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%r9,%rax
+	adcq	%rdx,%r11
+
+	movq	8(%rsi,%rcx,1),%r9
+	xorq	%r12,%r12
+	addq	%r10,%r13
+	adcq	$0,%r12
+	mulq	%r15
+	addq	%rax,%r13
+	movq	%r9,%rax
+	adcq	%rdx,%r12
+	movq	%r13,(%rdi,%rcx,1)
+
+	xorq	%r10,%r10
+	addq	8(%rdi,%rcx,1),%r11
+	adcq	$0,%r10
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%rbx,%rax
+	adcq	%rdx,%r10
+
+
+	movq	16(%rsi,%rcx,1),%rbx
+	xorq	%r13,%r13
+	addq	%r11,%r12
+	adcq	$0,%r13
+	mulq	%r15
+	addq	%rax,%r12
+	movq	%rbx,%rax
+	adcq	%rdx,%r13
+	movq	%r12,8(%rdi,%rcx,1)
+
+	xorq	%r11,%r11
+	addq	16(%rdi,%rcx,1),%r10
+	adcq	$0,%r11
+	mulq	%r14
+	addq	%rax,%r10
+	movq	%r9,%rax
+	adcq	%rdx,%r11
+
+	movq	24(%rsi,%rcx,1),%r9
+	xorq	%r12,%r12
+	addq	%r10,%r13
+	adcq	$0,%r12
+	mulq	%r15
+	addq	%rax,%r13
+	movq	%r9,%rax
+	adcq	%rdx,%r12
+	movq	%r13,16(%rdi,%rcx,1)
+
+	xorq	%r10,%r10
+	addq	24(%rdi,%rcx,1),%r11
+	leaq	32(%rcx),%rcx
+	adcq	$0,%r10
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%rbx,%rax
+	adcq	%rdx,%r10
+	cmpq	$0,%rcx
+	jne	L$sqr4x_mont_inner
+
+	subq	0(%rsp),%rcx
+	movq	%r8,%r14
+
+	xorq	%r13,%r13
+	addq	%r11,%r12
+	adcq	$0,%r13
+	mulq	%r15
+	addq	%rax,%r12
+	movq	%r9,%rax
+	adcq	%rdx,%r13
+	movq	%r12,-8(%rdi)
+
+	xorq	%r11,%r11
+	addq	(%rdi),%r10
+	adcq	$0,%r11
+	movq	0(%rsi,%rcx,1),%rbx
+	addq	%rbp,%r10
+	adcq	$0,%r11
+
+	imulq	16(%rdi,%rcx,1),%r14
+	xorq	%r12,%r12
+	movq	8(%rsi,%rcx,1),%r9
+	addq	%r10,%r13
+	movq	16(%rdi,%rcx,1),%r10
+	adcq	$0,%r12
+	mulq	%r15
+	addq	%rax,%r13
+	movq	%rbx,%rax
+	adcq	%rdx,%r12
+	movq	%r13,(%rdi)
+
+	xorq	%rbp,%rbp
+	addq	8(%rdi),%r12
+	adcq	%rbp,%rbp
+	addq	%r11,%r12
+	leaq	16(%rdi),%rdi
+	adcq	$0,%rbp
+	movq	%r12,-8(%rdi)
+	cmpq	8(%rsp),%rdi
+	jb	L$sqr4x_mont_outer
+
+	movq	0(%rsp),%r9
+	movq	%rbp,(%rdi)
+	movq	64(%rsp,%r9,1),%rax
+	leaq	64(%rsp,%r9,1),%rbx
+	movq	40(%rsp),%rsi
+	shrq	$5,%r9
+	movq	8(%rbx),%rdx
+	xorq	%rbp,%rbp
+
+	movq	32(%rsp),%rdi
+	subq	0(%rsi),%rax
+	movq	16(%rbx),%r10
+	movq	24(%rbx),%r11
+	sbbq	8(%rsi),%rdx
+	leaq	-1(%r9),%rcx
+	jmp	L$sqr4x_sub
+.p2align	4
+L$sqr4x_sub:
+	movq	%rax,0(%rdi,%rbp,8)
+	movq	%rdx,8(%rdi,%rbp,8)
+	sbbq	16(%rsi,%rbp,8),%r10
+	movq	32(%rbx,%rbp,8),%rax
+	movq	40(%rbx,%rbp,8),%rdx
+	sbbq	24(%rsi,%rbp,8),%r11
+	movq	%r10,16(%rdi,%rbp,8)
+	movq	%r11,24(%rdi,%rbp,8)
+	sbbq	32(%rsi,%rbp,8),%rax
+	movq	48(%rbx,%rbp,8),%r10
+	movq	56(%rbx,%rbp,8),%r11
+	sbbq	40(%rsi,%rbp,8),%rdx
+	leaq	4(%rbp),%rbp
+	decq	%rcx
+	jnz	L$sqr4x_sub
+
+	movq	%rax,0(%rdi,%rbp,8)
+	movq	32(%rbx,%rbp,8),%rax
+	sbbq	16(%rsi,%rbp,8),%r10
+	movq	%rdx,8(%rdi,%rbp,8)
+	sbbq	24(%rsi,%rbp,8),%r11
+	movq	%r10,16(%rdi,%rbp,8)
+
+	sbbq	$0,%rax
+	movq	%r11,24(%rdi,%rbp,8)
+	xorq	%rbp,%rbp
+	andq	%rax,%rbx
+	notq	%rax
+	movq	%rdi,%rsi
+	andq	%rax,%rsi
+	leaq	-1(%r9),%rcx
+	orq	%rsi,%rbx
+
+	pxor	%xmm0,%xmm0
+	leaq	64(%rsp,%r9,8),%rsi
+	movdqu	(%rbx),%xmm1
+	leaq	(%rsi,%r9,8),%rsi
+	movdqa	%xmm0,64(%rsp)
+	movdqa	%xmm0,(%rsi)
+	movdqu	%xmm1,(%rdi)
+	jmp	L$sqr4x_copy
+.p2align	4
+L$sqr4x_copy:
+	movdqu	16(%rbx,%rbp,1),%xmm2
+	movdqu	32(%rbx,%rbp,1),%xmm1
+	movdqa	%xmm0,80(%rsp,%rbp,1)
+	movdqa	%xmm0,96(%rsp,%rbp,1)
+	movdqa	%xmm0,16(%rsi,%rbp,1)
+	movdqa	%xmm0,32(%rsi,%rbp,1)
+	movdqu	%xmm2,16(%rdi,%rbp,1)
+	movdqu	%xmm1,32(%rdi,%rbp,1)
+	leaq	32(%rbp),%rbp
+	decq	%rcx
+	jnz	L$sqr4x_copy
+
+	movdqu	16(%rbx,%rbp,1),%xmm2
+	movdqa	%xmm0,80(%rsp,%rbp,1)
+	movdqa	%xmm0,16(%rsi,%rbp,1)
+	movdqu	%xmm2,16(%rdi,%rbp,1)
+	movq	56(%rsp),%rsi
+	movq	$1,%rax
+	movq	0(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+L$sqr4x_epilogue:
+	.byte	0xf3,0xc3
+
+.byte	77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.p2align	4
diff --git a/crypto/libressl/crypto/bn/mont5-elf-x86_64.s b/crypto/libressl/crypto/bn/mont5-elf-x86_64.s
new file mode 100644
index 0000000000..036a887a93
--- /dev/null
+++ b/crypto/libressl/crypto/bn/mont5-elf-x86_64.s
@@ -0,0 +1,787 @@
+.text	
+
+.globl	bn_mul_mont_gather5
+.type	bn_mul_mont_gather5,@function
+.align	64
+bn_mul_mont_gather5:
+	testl	$3,%r9d
+	jnz	.Lmul_enter
+	cmpl	$8,%r9d
+	jb	.Lmul_enter
+	jmp	.Lmul4x_enter
+
+.align	16
+.Lmul_enter:
+	movl	%r9d,%r9d
+	movl	8(%rsp),%r10d
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	movq	%rsp,%rax
+	leaq	2(%r9),%r11
+	negq	%r11
+	leaq	(%rsp,%r11,8),%rsp
+	andq	$-1024,%rsp
+
+	movq	%rax,8(%rsp,%r9,8)
+.Lmul_body:
+	movq	%rdx,%r12
+	movq	%r10,%r11
+	shrq	$3,%r10
+	andq	$7,%r11
+	notq	%r10
+	leaq	.Lmagic_masks(%rip),%rax
+	andq	$3,%r10
+	leaq	96(%r12,%r11,8),%r12
+	movq	0(%rax,%r10,8),%xmm4
+	movq	8(%rax,%r10,8),%xmm5
+	movq	16(%rax,%r10,8),%xmm6
+	movq	24(%rax,%r10,8),%xmm7
+
+	movq	-96(%r12),%xmm0
+	movq	-32(%r12),%xmm1
+	pand	%xmm4,%xmm0
+	movq	32(%r12),%xmm2
+	pand	%xmm5,%xmm1
+	movq	96(%r12),%xmm3
+	pand	%xmm6,%xmm2
+	por	%xmm1,%xmm0
+	pand	%xmm7,%xmm3
+	por	%xmm2,%xmm0
+	leaq	256(%r12),%r12
+	por	%xmm3,%xmm0
+
+	movd	%xmm0,%rbx
+
+	movq	(%r8),%r8
+	movq	(%rsi),%rax
+
+	xorq	%r14,%r14
+	xorq	%r15,%r15
+
+	movq	-96(%r12),%xmm0
+	movq	-32(%r12),%xmm1
+	pand	%xmm4,%xmm0
+	movq	32(%r12),%xmm2
+	pand	%xmm5,%xmm1
+
+	movq	%r8,%rbp
+	mulq	%rbx
+	movq	%rax,%r10
+	movq	(%rcx),%rax
+
+	movq	96(%r12),%xmm3
+	pand	%xmm6,%xmm2
+	por	%xmm1,%xmm0
+	pand	%xmm7,%xmm3
+
+	imulq	%r10,%rbp
+	movq	%rdx,%r11
+
+	por	%xmm2,%xmm0
+	leaq	256(%r12),%r12
+	por	%xmm3,%xmm0
+
+	mulq	%rbp
+	addq	%rax,%r10
+	movq	8(%rsi),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r13
+
+	leaq	1(%r15),%r15
+	jmp	.L1st_enter
+
+.align	16
+.L1st:
+	addq	%rax,%r13
+	movq	(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%r13
+	movq	%r10,%r11
+	adcq	$0,%rdx
+	movq	%r13,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+.L1st_enter:
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	leaq	1(%r15),%r15
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	cmpq	%r9,%r15
+	jl	.L1st
+
+	movd	%xmm0,%rbx
+
+	addq	%rax,%r13
+	movq	(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r11,%r13
+	adcq	$0,%rdx
+	movq	%r13,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+	movq	%r10,%r11
+
+	xorq	%rdx,%rdx
+	addq	%r11,%r13
+	adcq	$0,%rdx
+	movq	%r13,-8(%rsp,%r9,8)
+	movq	%rdx,(%rsp,%r9,8)
+
+	leaq	1(%r14),%r14
+	jmp	.Louter
+.align	16
+.Louter:
+	xorq	%r15,%r15
+	movq	%r8,%rbp
+	movq	(%rsp),%r10
+
+	movq	-96(%r12),%xmm0
+	movq	-32(%r12),%xmm1
+	pand	%xmm4,%xmm0
+	movq	32(%r12),%xmm2
+	pand	%xmm5,%xmm1
+
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	(%rcx),%rax
+	adcq	$0,%rdx
+
+	movq	96(%r12),%xmm3
+	pand	%xmm6,%xmm2
+	por	%xmm1,%xmm0
+	pand	%xmm7,%xmm3
+
+	imulq	%r10,%rbp
+	movq	%rdx,%r11
+
+	por	%xmm2,%xmm0
+	leaq	256(%r12),%r12
+	por	%xmm3,%xmm0
+
+	mulq	%rbp
+	addq	%rax,%r10
+	movq	8(%rsi),%rax
+	adcq	$0,%rdx
+	movq	8(%rsp),%r10
+	movq	%rdx,%r13
+
+	leaq	1(%r15),%r15
+	jmp	.Linner_enter
+
+.align	16
+.Linner:
+	addq	%rax,%r13
+	movq	(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	movq	(%rsp,%r15,8),%r10
+	adcq	$0,%rdx
+	movq	%r13,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+.Linner_enter:
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%r10
+	movq	%rdx,%r11
+	adcq	$0,%r11
+	leaq	1(%r15),%r15
+
+	mulq	%rbp
+	cmpq	%r9,%r15
+	jl	.Linner
+
+	movd	%xmm0,%rbx
+
+	addq	%rax,%r13
+	movq	(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	movq	(%rsp,%r15,8),%r10
+	adcq	$0,%rdx
+	movq	%r13,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+	xorq	%rdx,%rdx
+	addq	%r11,%r13
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-8(%rsp,%r9,8)
+	movq	%rdx,(%rsp,%r9,8)
+
+	leaq	1(%r14),%r14
+	cmpq	%r9,%r14
+	jl	.Louter
+
+	xorq	%r14,%r14
+	movq	(%rsp),%rax
+	leaq	(%rsp),%rsi
+	movq	%r9,%r15
+	jmp	.Lsub
+.align	16
+.Lsub:	sbbq	(%rcx,%r14,8),%rax
+	movq	%rax,(%rdi,%r14,8)
+	movq	8(%rsi,%r14,8),%rax
+	leaq	1(%r14),%r14
+	decq	%r15
+	jnz	.Lsub
+
+	sbbq	$0,%rax
+	xorq	%r14,%r14
+	andq	%rax,%rsi
+	notq	%rax
+	movq	%rdi,%rcx
+	andq	%rax,%rcx
+	movq	%r9,%r15
+	orq	%rcx,%rsi
+.align	16
+.Lcopy:
+	movq	(%rsi,%r14,8),%rax
+	movq	%r14,(%rsp,%r14,8)
+	movq	%rax,(%rdi,%r14,8)
+	leaq	1(%r14),%r14
+	subq	$1,%r15
+	jnz	.Lcopy
+
+	movq	8(%rsp,%r9,8),%rsi
+	movq	$1,%rax
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+.Lmul_epilogue:
+	.byte	0xf3,0xc3
+.size	bn_mul_mont_gather5,.-bn_mul_mont_gather5
+.type	bn_mul4x_mont_gather5,@function
+.align	16
+bn_mul4x_mont_gather5:
+.Lmul4x_enter:
+	movl	%r9d,%r9d
+	movl	8(%rsp),%r10d
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	movq	%rsp,%rax
+	leaq	4(%r9),%r11
+	negq	%r11
+	leaq	(%rsp,%r11,8),%rsp
+	andq	$-1024,%rsp
+
+	movq	%rax,8(%rsp,%r9,8)
+.Lmul4x_body:
+	movq	%rdi,16(%rsp,%r9,8)
+	movq	%rdx,%r12
+	movq	%r10,%r11
+	shrq	$3,%r10
+	andq	$7,%r11
+	notq	%r10
+	leaq	.Lmagic_masks(%rip),%rax
+	andq	$3,%r10
+	leaq	96(%r12,%r11,8),%r12
+	movq	0(%rax,%r10,8),%xmm4
+	movq	8(%rax,%r10,8),%xmm5
+	movq	16(%rax,%r10,8),%xmm6
+	movq	24(%rax,%r10,8),%xmm7
+
+	movq	-96(%r12),%xmm0
+	movq	-32(%r12),%xmm1
+	pand	%xmm4,%xmm0
+	movq	32(%r12),%xmm2
+	pand	%xmm5,%xmm1
+	movq	96(%r12),%xmm3
+	pand	%xmm6,%xmm2
+	por	%xmm1,%xmm0
+	pand	%xmm7,%xmm3
+	por	%xmm2,%xmm0
+	leaq	256(%r12),%r12
+	por	%xmm3,%xmm0
+
+	movd	%xmm0,%rbx
+	movq	(%r8),%r8
+	movq	(%rsi),%rax
+
+	xorq	%r14,%r14
+	xorq	%r15,%r15
+
+	movq	-96(%r12),%xmm0
+	movq	-32(%r12),%xmm1
+	pand	%xmm4,%xmm0
+	movq	32(%r12),%xmm2
+	pand	%xmm5,%xmm1
+
+	movq	%r8,%rbp
+	mulq	%rbx
+	movq	%rax,%r10
+	movq	(%rcx),%rax
+
+	movq	96(%r12),%xmm3
+	pand	%xmm6,%xmm2
+	por	%xmm1,%xmm0
+	pand	%xmm7,%xmm3
+
+	imulq	%r10,%rbp
+	movq	%rdx,%r11
+
+	por	%xmm2,%xmm0
+	leaq	256(%r12),%r12
+	por	%xmm3,%xmm0
+
+	mulq	%rbp
+	addq	%rax,%r10
+	movq	8(%rsi),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	8(%rcx),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	16(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	leaq	4(%r15),%r15
+	adcq	$0,%rdx
+	movq	%rdi,(%rsp)
+	movq	%rdx,%r13
+	jmp	.L1st4x
+.align	16
+.L1st4x:
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	-16(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	-8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-24(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	-8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%rdi,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-8(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	leaq	4(%r15),%r15
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	-16(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%rdi,-32(%rsp,%r15,8)
+	movq	%rdx,%r13
+	cmpq	%r9,%r15
+	jl	.L1st4x
+
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	-16(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	-8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-24(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	-8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%rdi,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+	movd	%xmm0,%rbx
+
+	xorq	%rdi,%rdi
+	addq	%r10,%r13
+	adcq	$0,%rdi
+	movq	%r13,-8(%rsp,%r15,8)
+	movq	%rdi,(%rsp,%r15,8)
+
+	leaq	1(%r14),%r14
+.align	4
+.Louter4x:
+	xorq	%r15,%r15
+	movq	-96(%r12),%xmm0
+	movq	-32(%r12),%xmm1
+	pand	%xmm4,%xmm0
+	movq	32(%r12),%xmm2
+	pand	%xmm5,%xmm1
+
+	movq	(%rsp),%r10
+	movq	%r8,%rbp
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	(%rcx),%rax
+	adcq	$0,%rdx
+
+	movq	96(%r12),%xmm3
+	pand	%xmm6,%xmm2
+	por	%xmm1,%xmm0
+	pand	%xmm7,%xmm3
+
+	imulq	%r10,%rbp
+	movq	%rdx,%r11
+
+	por	%xmm2,%xmm0
+	leaq	256(%r12),%r12
+	por	%xmm3,%xmm0
+
+	mulq	%rbp
+	addq	%rax,%r10
+	movq	8(%rsi),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	8(%rcx),%rax
+	adcq	$0,%rdx
+	addq	8(%rsp),%r11
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	16(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	leaq	4(%r15),%r15
+	adcq	$0,%rdx
+	movq	%rdx,%r13
+	jmp	.Linner4x
+.align	16
+.Linner4x:
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	-16(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	-16(%rsp,%r15,8),%r10
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	-8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%rdi,-32(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	-8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	-8(%rsp,%r15,8),%r11
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%r13,-24(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	(%rsp,%r15,8),%r10
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%rdi,-16(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	8(%rsp,%r15,8),%r11
+	adcq	$0,%rdx
+	leaq	4(%r15),%r15
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	-16(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%r13,-40(%rsp,%r15,8)
+	movq	%rdx,%r13
+	cmpq	%r9,%r15
+	jl	.Linner4x
+
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	-16(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	-16(%rsp,%r15,8),%r10
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	-8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%rdi,-32(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	-8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	-8(%rsp,%r15,8),%r11
+	adcq	$0,%rdx
+	leaq	1(%r14),%r14
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%r13,-24(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+	movd	%xmm0,%rbx
+	movq	%rdi,-16(%rsp,%r15,8)
+
+	xorq	%rdi,%rdi
+	addq	%r10,%r13
+	adcq	$0,%rdi
+	addq	(%rsp,%r9,8),%r13
+	adcq	$0,%rdi
+	movq	%r13,-8(%rsp,%r15,8)
+	movq	%rdi,(%rsp,%r15,8)
+
+	cmpq	%r9,%r14
+	jl	.Louter4x
+	movq	16(%rsp,%r9,8),%rdi
+	movq	0(%rsp),%rax
+	pxor	%xmm0,%xmm0
+	movq	8(%rsp),%rdx
+	shrq	$2,%r9
+	leaq	(%rsp),%rsi
+	xorq	%r14,%r14
+
+	subq	0(%rcx),%rax
+	movq	16(%rsi),%rbx
+	movq	24(%rsi),%rbp
+	sbbq	8(%rcx),%rdx
+	leaq	-1(%r9),%r15
+	jmp	.Lsub4x
+.align	16
+.Lsub4x:
+	movq	%rax,0(%rdi,%r14,8)
+	movq	%rdx,8(%rdi,%r14,8)
+	sbbq	16(%rcx,%r14,8),%rbx
+	movq	32(%rsi,%r14,8),%rax
+	movq	40(%rsi,%r14,8),%rdx
+	sbbq	24(%rcx,%r14,8),%rbp
+	movq	%rbx,16(%rdi,%r14,8)
+	movq	%rbp,24(%rdi,%r14,8)
+	sbbq	32(%rcx,%r14,8),%rax
+	movq	48(%rsi,%r14,8),%rbx
+	movq	56(%rsi,%r14,8),%rbp
+	sbbq	40(%rcx,%r14,8),%rdx
+	leaq	4(%r14),%r14
+	decq	%r15
+	jnz	.Lsub4x
+
+	movq	%rax,0(%rdi,%r14,8)
+	movq	32(%rsi,%r14,8),%rax
+	sbbq	16(%rcx,%r14,8),%rbx
+	movq	%rdx,8(%rdi,%r14,8)
+	sbbq	24(%rcx,%r14,8),%rbp
+	movq	%rbx,16(%rdi,%r14,8)
+
+	sbbq	$0,%rax
+	movq	%rbp,24(%rdi,%r14,8)
+	xorq	%r14,%r14
+	andq	%rax,%rsi
+	notq	%rax
+	movq	%rdi,%rcx
+	andq	%rax,%rcx
+	leaq	-1(%r9),%r15
+	orq	%rcx,%rsi
+
+	movdqu	(%rsi),%xmm1
+	movdqa	%xmm0,(%rsp)
+	movdqu	%xmm1,(%rdi)
+	jmp	.Lcopy4x
+.align	16
+.Lcopy4x:
+	movdqu	16(%rsi,%r14,1),%xmm2
+	movdqu	32(%rsi,%r14,1),%xmm1
+	movdqa	%xmm0,16(%rsp,%r14,1)
+	movdqu	%xmm2,16(%rdi,%r14,1)
+	movdqa	%xmm0,32(%rsp,%r14,1)
+	movdqu	%xmm1,32(%rdi,%r14,1)
+	leaq	32(%r14),%r14
+	decq	%r15
+	jnz	.Lcopy4x
+
+	shlq	$2,%r9
+	movdqu	16(%rsi,%r14,1),%xmm2
+	movdqa	%xmm0,16(%rsp,%r14,1)
+	movdqu	%xmm2,16(%rdi,%r14,1)
+	movq	8(%rsp,%r9,8),%rsi
+	movq	$1,%rax
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+.Lmul4x_epilogue:
+	.byte	0xf3,0xc3
+.size	bn_mul4x_mont_gather5,.-bn_mul4x_mont_gather5
+.globl	bn_scatter5
+.type	bn_scatter5,@function
+.align	16
+bn_scatter5:
+	cmpq	$0,%rsi
+	jz	.Lscatter_epilogue
+	leaq	(%rdx,%rcx,8),%rdx
+.Lscatter:
+	movq	(%rdi),%rax
+	leaq	8(%rdi),%rdi
+	movq	%rax,(%rdx)
+	leaq	256(%rdx),%rdx
+	subq	$1,%rsi
+	jnz	.Lscatter
+.Lscatter_epilogue:
+	.byte	0xf3,0xc3
+.size	bn_scatter5,.-bn_scatter5
+
+.globl	bn_gather5
+.type	bn_gather5,@function
+.align	16
+bn_gather5:
+	movq	%rcx,%r11
+	shrq	$3,%rcx
+	andq	$7,%r11
+	notq	%rcx
+	leaq	.Lmagic_masks(%rip),%rax
+	andq	$3,%rcx
+	leaq	96(%rdx,%r11,8),%rdx
+	movq	0(%rax,%rcx,8),%xmm4
+	movq	8(%rax,%rcx,8),%xmm5
+	movq	16(%rax,%rcx,8),%xmm6
+	movq	24(%rax,%rcx,8),%xmm7
+	jmp	.Lgather
+.align	16
+.Lgather:
+	movq	-96(%rdx),%xmm0
+	movq	-32(%rdx),%xmm1
+	pand	%xmm4,%xmm0
+	movq	32(%rdx),%xmm2
+	pand	%xmm5,%xmm1
+	movq	96(%rdx),%xmm3
+	pand	%xmm6,%xmm2
+	por	%xmm1,%xmm0
+	pand	%xmm7,%xmm3
+	por	%xmm2,%xmm0
+	leaq	256(%rdx),%rdx
+	por	%xmm3,%xmm0
+
+	movq	%xmm0,(%rdi)
+	leaq	8(%rdi),%rdi
+	subq	$1,%rsi
+	jnz	.Lgather
+	.byte	0xf3,0xc3
+.LSEH_end_bn_gather5:
+.size	bn_gather5,.-bn_gather5
+.align	64
+.Lmagic_masks:
+.long	0,0, 0,0, 0,0, -1,-1
+.long	0,0, 0,0, 0,0,  0,0
+.byte	77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115,99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+#if defined(HAVE_GNU_STACK)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/crypto/libressl/crypto/bn/mont5-macosx-x86_64.s b/crypto/libressl/crypto/bn/mont5-macosx-x86_64.s
new file mode 100644
index 0000000000..b62d43cf72
--- /dev/null
+++ b/crypto/libressl/crypto/bn/mont5-macosx-x86_64.s
@@ -0,0 +1,784 @@
+.text	
+
+.globl	_bn_mul_mont_gather5
+
+.p2align	6
+_bn_mul_mont_gather5:
+	testl	$3,%r9d
+	jnz	L$mul_enter
+	cmpl	$8,%r9d
+	jb	L$mul_enter
+	jmp	L$mul4x_enter
+
+.p2align	4
+L$mul_enter:
+	movl	%r9d,%r9d
+	movl	8(%rsp),%r10d
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	movq	%rsp,%rax
+	leaq	2(%r9),%r11
+	negq	%r11
+	leaq	(%rsp,%r11,8),%rsp
+	andq	$-1024,%rsp
+
+	movq	%rax,8(%rsp,%r9,8)
+L$mul_body:
+	movq	%rdx,%r12
+	movq	%r10,%r11
+	shrq	$3,%r10
+	andq	$7,%r11
+	notq	%r10
+	leaq	L$magic_masks(%rip),%rax
+	andq	$3,%r10
+	leaq	96(%r12,%r11,8),%r12
+	movq	0(%rax,%r10,8),%xmm4
+	movq	8(%rax,%r10,8),%xmm5
+	movq	16(%rax,%r10,8),%xmm6
+	movq	24(%rax,%r10,8),%xmm7
+
+	movq	-96(%r12),%xmm0
+	movq	-32(%r12),%xmm1
+	pand	%xmm4,%xmm0
+	movq	32(%r12),%xmm2
+	pand	%xmm5,%xmm1
+	movq	96(%r12),%xmm3
+	pand	%xmm6,%xmm2
+	por	%xmm1,%xmm0
+	pand	%xmm7,%xmm3
+	por	%xmm2,%xmm0
+	leaq	256(%r12),%r12
+	por	%xmm3,%xmm0
+
+	movd	%xmm0,%rbx
+
+	movq	(%r8),%r8
+	movq	(%rsi),%rax
+
+	xorq	%r14,%r14
+	xorq	%r15,%r15
+
+	movq	-96(%r12),%xmm0
+	movq	-32(%r12),%xmm1
+	pand	%xmm4,%xmm0
+	movq	32(%r12),%xmm2
+	pand	%xmm5,%xmm1
+
+	movq	%r8,%rbp
+	mulq	%rbx
+	movq	%rax,%r10
+	movq	(%rcx),%rax
+
+	movq	96(%r12),%xmm3
+	pand	%xmm6,%xmm2
+	por	%xmm1,%xmm0
+	pand	%xmm7,%xmm3
+
+	imulq	%r10,%rbp
+	movq	%rdx,%r11
+
+	por	%xmm2,%xmm0
+	leaq	256(%r12),%r12
+	por	%xmm3,%xmm0
+
+	mulq	%rbp
+	addq	%rax,%r10
+	movq	8(%rsi),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r13
+
+	leaq	1(%r15),%r15
+	jmp	L$1st_enter
+
+.p2align	4
+L$1st:
+	addq	%rax,%r13
+	movq	(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%r13
+	movq	%r10,%r11
+	adcq	$0,%rdx
+	movq	%r13,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+L$1st_enter:
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	leaq	1(%r15),%r15
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	cmpq	%r9,%r15
+	jl	L$1st
+
+	movd	%xmm0,%rbx
+
+	addq	%rax,%r13
+	movq	(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r11,%r13
+	adcq	$0,%rdx
+	movq	%r13,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+	movq	%r10,%r11
+
+	xorq	%rdx,%rdx
+	addq	%r11,%r13
+	adcq	$0,%rdx
+	movq	%r13,-8(%rsp,%r9,8)
+	movq	%rdx,(%rsp,%r9,8)
+
+	leaq	1(%r14),%r14
+	jmp	L$outer
+.p2align	4
+L$outer:
+	xorq	%r15,%r15
+	movq	%r8,%rbp
+	movq	(%rsp),%r10
+
+	movq	-96(%r12),%xmm0
+	movq	-32(%r12),%xmm1
+	pand	%xmm4,%xmm0
+	movq	32(%r12),%xmm2
+	pand	%xmm5,%xmm1
+
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	(%rcx),%rax
+	adcq	$0,%rdx
+
+	movq	96(%r12),%xmm3
+	pand	%xmm6,%xmm2
+	por	%xmm1,%xmm0
+	pand	%xmm7,%xmm3
+
+	imulq	%r10,%rbp
+	movq	%rdx,%r11
+
+	por	%xmm2,%xmm0
+	leaq	256(%r12),%r12
+	por	%xmm3,%xmm0
+
+	mulq	%rbp
+	addq	%rax,%r10
+	movq	8(%rsi),%rax
+	adcq	$0,%rdx
+	movq	8(%rsp),%r10
+	movq	%rdx,%r13
+
+	leaq	1(%r15),%r15
+	jmp	L$inner_enter
+
+.p2align	4
+L$inner:
+	addq	%rax,%r13
+	movq	(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	movq	(%rsp,%r15,8),%r10
+	adcq	$0,%rdx
+	movq	%r13,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+L$inner_enter:
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%r10
+	movq	%rdx,%r11
+	adcq	$0,%r11
+	leaq	1(%r15),%r15
+
+	mulq	%rbp
+	cmpq	%r9,%r15
+	jl	L$inner
+
+	movd	%xmm0,%rbx
+
+	addq	%rax,%r13
+	movq	(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	movq	(%rsp,%r15,8),%r10
+	adcq	$0,%rdx
+	movq	%r13,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+	xorq	%rdx,%rdx
+	addq	%r11,%r13
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-8(%rsp,%r9,8)
+	movq	%rdx,(%rsp,%r9,8)
+
+	leaq	1(%r14),%r14
+	cmpq	%r9,%r14
+	jl	L$outer
+
+	xorq	%r14,%r14
+	movq	(%rsp),%rax
+	leaq	(%rsp),%rsi
+	movq	%r9,%r15
+	jmp	L$sub
+.p2align	4
+L$sub:	sbbq	(%rcx,%r14,8),%rax
+	movq	%rax,(%rdi,%r14,8)
+	movq	8(%rsi,%r14,8),%rax
+	leaq	1(%r14),%r14
+	decq	%r15
+	jnz	L$sub
+
+	sbbq	$0,%rax
+	xorq	%r14,%r14
+	andq	%rax,%rsi
+	notq	%rax
+	movq	%rdi,%rcx
+	andq	%rax,%rcx
+	movq	%r9,%r15
+	orq	%rcx,%rsi
+.p2align	4
+L$copy:
+	movq	(%rsi,%r14,8),%rax
+	movq	%r14,(%rsp,%r14,8)
+	movq	%rax,(%rdi,%r14,8)
+	leaq	1(%r14),%r14
+	subq	$1,%r15
+	jnz	L$copy
+
+	movq	8(%rsp,%r9,8),%rsi
+	movq	$1,%rax
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+L$mul_epilogue:
+	.byte	0xf3,0xc3
+
+
+.p2align	4
+bn_mul4x_mont_gather5:
+L$mul4x_enter:
+	movl	%r9d,%r9d
+	movl	8(%rsp),%r10d
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	movq	%rsp,%rax
+	leaq	4(%r9),%r11
+	negq	%r11
+	leaq	(%rsp,%r11,8),%rsp
+	andq	$-1024,%rsp
+
+	movq	%rax,8(%rsp,%r9,8)
+L$mul4x_body:
+	movq	%rdi,16(%rsp,%r9,8)
+	movq	%rdx,%r12
+	movq	%r10,%r11
+	shrq	$3,%r10
+	andq	$7,%r11
+	notq	%r10
+	leaq	L$magic_masks(%rip),%rax
+	andq	$3,%r10
+	leaq	96(%r12,%r11,8),%r12
+	movq	0(%rax,%r10,8),%xmm4
+	movq	8(%rax,%r10,8),%xmm5
+	movq	16(%rax,%r10,8),%xmm6
+	movq	24(%rax,%r10,8),%xmm7
+
+	movq	-96(%r12),%xmm0
+	movq	-32(%r12),%xmm1
+	pand	%xmm4,%xmm0
+	movq	32(%r12),%xmm2
+	pand	%xmm5,%xmm1
+	movq	96(%r12),%xmm3
+	pand	%xmm6,%xmm2
+	por	%xmm1,%xmm0
+	pand	%xmm7,%xmm3
+	por	%xmm2,%xmm0
+	leaq	256(%r12),%r12
+	por	%xmm3,%xmm0
+
+	movd	%xmm0,%rbx
+	movq	(%r8),%r8
+	movq	(%rsi),%rax
+
+	xorq	%r14,%r14
+	xorq	%r15,%r15
+
+	movq	-96(%r12),%xmm0
+	movq	-32(%r12),%xmm1
+	pand	%xmm4,%xmm0
+	movq	32(%r12),%xmm2
+	pand	%xmm5,%xmm1
+
+	movq	%r8,%rbp
+	mulq	%rbx
+	movq	%rax,%r10
+	movq	(%rcx),%rax
+
+	movq	96(%r12),%xmm3
+	pand	%xmm6,%xmm2
+	por	%xmm1,%xmm0
+	pand	%xmm7,%xmm3
+
+	imulq	%r10,%rbp
+	movq	%rdx,%r11
+
+	por	%xmm2,%xmm0
+	leaq	256(%r12),%r12
+	por	%xmm3,%xmm0
+
+	mulq	%rbp
+	addq	%rax,%r10
+	movq	8(%rsi),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	8(%rcx),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	16(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	leaq	4(%r15),%r15
+	adcq	$0,%rdx
+	movq	%rdi,(%rsp)
+	movq	%rdx,%r13
+	jmp	L$1st4x
+.p2align	4
+L$1st4x:
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	-16(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	-8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-24(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	-8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%rdi,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-8(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	leaq	4(%r15),%r15
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	-16(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%rdi,-32(%rsp,%r15,8)
+	movq	%rdx,%r13
+	cmpq	%r9,%r15
+	jl	L$1st4x
+
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	-16(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	-8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%r13,-24(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	-8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%rdi,-16(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+	movd	%xmm0,%rbx
+
+	xorq	%rdi,%rdi
+	addq	%r10,%r13
+	adcq	$0,%rdi
+	movq	%r13,-8(%rsp,%r15,8)
+	movq	%rdi,(%rsp,%r15,8)
+
+	leaq	1(%r14),%r14
+.p2align	2
+L$outer4x:
+	xorq	%r15,%r15
+	movq	-96(%r12),%xmm0
+	movq	-32(%r12),%xmm1
+	pand	%xmm4,%xmm0
+	movq	32(%r12),%xmm2
+	pand	%xmm5,%xmm1
+
+	movq	(%rsp),%r10
+	movq	%r8,%rbp
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	(%rcx),%rax
+	adcq	$0,%rdx
+
+	movq	96(%r12),%xmm3
+	pand	%xmm6,%xmm2
+	por	%xmm1,%xmm0
+	pand	%xmm7,%xmm3
+
+	imulq	%r10,%rbp
+	movq	%rdx,%r11
+
+	por	%xmm2,%xmm0
+	leaq	256(%r12),%r12
+	por	%xmm3,%xmm0
+
+	mulq	%rbp
+	addq	%rax,%r10
+	movq	8(%rsi),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	8(%rcx),%rax
+	adcq	$0,%rdx
+	addq	8(%rsp),%r11
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	16(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	leaq	4(%r15),%r15
+	adcq	$0,%rdx
+	movq	%rdx,%r13
+	jmp	L$inner4x
+.p2align	4
+L$inner4x:
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	-16(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	-16(%rsp,%r15,8),%r10
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	-8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%rdi,-32(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	-8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	-8(%rsp,%r15,8),%r11
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%r13,-24(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	(%rsp,%r15,8),%r10
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%rdi,-16(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	8(%rsp,%r15,8),%r11
+	adcq	$0,%rdx
+	leaq	4(%r15),%r15
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	-16(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%r13,-40(%rsp,%r15,8)
+	movq	%rdx,%r13
+	cmpq	%r9,%r15
+	jl	L$inner4x
+
+	mulq	%rbx
+	addq	%rax,%r10
+	movq	-16(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	-16(%rsp,%r15,8),%r10
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%rbp
+	addq	%rax,%r13
+	movq	-8(%rsi,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	%r10,%r13
+	adcq	$0,%rdx
+	movq	%rdi,-32(%rsp,%r15,8)
+	movq	%rdx,%rdi
+
+	mulq	%rbx
+	addq	%rax,%r11
+	movq	-8(%rcx,%r15,8),%rax
+	adcq	$0,%rdx
+	addq	-8(%rsp,%r15,8),%r11
+	adcq	$0,%rdx
+	leaq	1(%r14),%r14
+	movq	%rdx,%r10
+
+	mulq	%rbp
+	addq	%rax,%rdi
+	movq	(%rsi),%rax
+	adcq	$0,%rdx
+	addq	%r11,%rdi
+	adcq	$0,%rdx
+	movq	%r13,-24(%rsp,%r15,8)
+	movq	%rdx,%r13
+
+	movd	%xmm0,%rbx
+	movq	%rdi,-16(%rsp,%r15,8)
+
+	xorq	%rdi,%rdi
+	addq	%r10,%r13
+	adcq	$0,%rdi
+	addq	(%rsp,%r9,8),%r13
+	adcq	$0,%rdi
+	movq	%r13,-8(%rsp,%r15,8)
+	movq	%rdi,(%rsp,%r15,8)
+
+	cmpq	%r9,%r14
+	jl	L$outer4x
+	movq	16(%rsp,%r9,8),%rdi
+	movq	0(%rsp),%rax
+	pxor	%xmm0,%xmm0
+	movq	8(%rsp),%rdx
+	shrq	$2,%r9
+	leaq	(%rsp),%rsi
+	xorq	%r14,%r14
+
+	subq	0(%rcx),%rax
+	movq	16(%rsi),%rbx
+	movq	24(%rsi),%rbp
+	sbbq	8(%rcx),%rdx
+	leaq	-1(%r9),%r15
+	jmp	L$sub4x
+.p2align	4
+L$sub4x:
+	movq	%rax,0(%rdi,%r14,8)
+	movq	%rdx,8(%rdi,%r14,8)
+	sbbq	16(%rcx,%r14,8),%rbx
+	movq	32(%rsi,%r14,8),%rax
+	movq	40(%rsi,%r14,8),%rdx
+	sbbq	24(%rcx,%r14,8),%rbp
+	movq	%rbx,16(%rdi,%r14,8)
+	movq	%rbp,24(%rdi,%r14,8)
+	sbbq	32(%rcx,%r14,8),%rax
+	movq	48(%rsi,%r14,8),%rbx
+	movq	56(%rsi,%r14,8),%rbp
+	sbbq	40(%rcx,%r14,8),%rdx
+	leaq	4(%r14),%r14
+	decq	%r15
+	jnz	L$sub4x
+
+	movq	%rax,0(%rdi,%r14,8)
+	movq	32(%rsi,%r14,8),%rax
+	sbbq	16(%rcx,%r14,8),%rbx
+	movq	%rdx,8(%rdi,%r14,8)
+	sbbq	24(%rcx,%r14,8),%rbp
+	movq	%rbx,16(%rdi,%r14,8)
+
+	sbbq	$0,%rax
+	movq	%rbp,24(%rdi,%r14,8)
+	xorq	%r14,%r14
+	andq	%rax,%rsi
+	notq	%rax
+	movq	%rdi,%rcx
+	andq	%rax,%rcx
+	leaq	-1(%r9),%r15
+	orq	%rcx,%rsi
+
+	movdqu	(%rsi),%xmm1
+	movdqa	%xmm0,(%rsp)
+	movdqu	%xmm1,(%rdi)
+	jmp	L$copy4x
+.p2align	4
+L$copy4x:
+	movdqu	16(%rsi,%r14,1),%xmm2
+	movdqu	32(%rsi,%r14,1),%xmm1
+	movdqa	%xmm0,16(%rsp,%r14,1)
+	movdqu	%xmm2,16(%rdi,%r14,1)
+	movdqa	%xmm0,32(%rsp,%r14,1)
+	movdqu	%xmm1,32(%rdi,%r14,1)
+	leaq	32(%r14),%r14
+	decq	%r15
+	jnz	L$copy4x
+
+	shlq	$2,%r9
+	movdqu	16(%rsi,%r14,1),%xmm2
+	movdqa	%xmm0,16(%rsp,%r14,1)
+	movdqu	%xmm2,16(%rdi,%r14,1)
+	movq	8(%rsp,%r9,8),%rsi
+	movq	$1,%rax
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+L$mul4x_epilogue:
+	.byte	0xf3,0xc3
+
+.globl	_bn_scatter5
+
+.p2align	4
+_bn_scatter5:
+	cmpq	$0,%rsi
+	jz	L$scatter_epilogue
+	leaq	(%rdx,%rcx,8),%rdx
+L$scatter:
+	movq	(%rdi),%rax
+	leaq	8(%rdi),%rdi
+	movq	%rax,(%rdx)
+	leaq	256(%rdx),%rdx
+	subq	$1,%rsi
+	jnz	L$scatter
+L$scatter_epilogue:
+	.byte	0xf3,0xc3
+
+
+.globl	_bn_gather5
+
+.p2align	4
+_bn_gather5:
+	movq	%rcx,%r11
+	shrq	$3,%rcx
+	andq	$7,%r11
+	notq	%rcx
+	leaq	L$magic_masks(%rip),%rax
+	andq	$3,%rcx
+	leaq	96(%rdx,%r11,8),%rdx
+	movq	0(%rax,%rcx,8),%xmm4
+	movq	8(%rax,%rcx,8),%xmm5
+	movq	16(%rax,%rcx,8),%xmm6
+	movq	24(%rax,%rcx,8),%xmm7
+	jmp	L$gather
+.p2align	4
+L$gather:
+	movq	-96(%rdx),%xmm0
+	movq	-32(%rdx),%xmm1
+	pand	%xmm4,%xmm0
+	movq	32(%rdx),%xmm2
+	pand	%xmm5,%xmm1
+	movq	96(%rdx),%xmm3
+	pand	%xmm6,%xmm2
+	por	%xmm1,%xmm0
+	pand	%xmm7,%xmm3
+	por	%xmm2,%xmm0
+	leaq	256(%rdx),%rdx
+	por	%xmm3,%xmm0
+
+	movq	%xmm0,(%rdi)
+	leaq	8(%rdi),%rdi
+	subq	$1,%rsi
+	jnz	L$gather
+	.byte	0xf3,0xc3
+L$SEH_end_bn_gather5:
+
+.p2align	6
+L$magic_masks:
+.long	0,0, 0,0, 0,0, -1,-1
+.long	0,0, 0,0, 0,0,  0,0
+.byte	77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115,99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
diff --git a/crypto/libressl/crypto/buffer/buf_err.c b/crypto/libressl/crypto/buffer/buf_err.c
new file mode 100644
index 0000000000..08b9999f10
--- /dev/null
+++ b/crypto/libressl/crypto/buffer/buf_err.c
@@ -0,0 +1,99 @@
+/* $OpenBSD: buf_err.c,v 1.9 2014/06/12 15:49:28 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_BUF,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_BUF,0,reason)
+
+static ERR_STRING_DATA BUF_str_functs[] = {
+	{ERR_FUNC(BUF_F_BUF_MEMDUP),	"BUF_memdup"},
+	{ERR_FUNC(BUF_F_BUF_MEM_GROW),	"BUF_MEM_grow"},
+	{ERR_FUNC(BUF_F_BUF_MEM_GROW_CLEAN),	"BUF_MEM_grow_clean"},
+	{ERR_FUNC(BUF_F_BUF_MEM_NEW),	"BUF_MEM_new"},
+	{ERR_FUNC(BUF_F_BUF_STRDUP),	"BUF_strdup"},
+	{ERR_FUNC(BUF_F_BUF_STRNDUP),	"BUF_strndup"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA BUF_str_reasons[] = {
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_BUF_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(BUF_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, BUF_str_functs);
+		ERR_load_strings(0, BUF_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/buffer/buf_str.c b/crypto/libressl/crypto/buffer/buf_str.c
new file mode 100644
index 0000000000..bb8a5075f1
--- /dev/null
+++ b/crypto/libressl/crypto/buffer/buf_str.c
@@ -0,0 +1,79 @@
+/* $OpenBSD: buf_str.c,v 1.8 2014/04/26 13:07:16 jsing Exp $ */
+/*
+ * Copyright (c) 2014 Bob Beck
+ *
+ * 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 
+#include 
+#include 
+
+#include 
+#include 
+
+/*
+ * XXX these functions accept a NULL arg and return NULL
+ * when the standard ones do not. we should at an appropriate
+ * time change these to find the bad callers
+ */
+
+char *
+BUF_strdup(const char *str)
+{
+	char *ret = NULL;
+
+	if (str != NULL) {
+		if (!(ret = strdup(str)))
+			BUFerr(BUF_F_BUF_STRDUP, ERR_R_MALLOC_FAILURE);
+	}
+	return ret;
+}
+
+char *
+BUF_strndup(const char *str, size_t siz)
+{
+	char *ret = NULL;
+
+	if (str != NULL) {
+		if (!(ret = strndup(str, siz)))
+			BUFerr(BUF_F_BUF_STRNDUP, ERR_R_MALLOC_FAILURE);
+	}
+	return ret;
+}
+
+void *
+BUF_memdup(const void *data, size_t siz)
+{
+	void *ret = NULL;
+
+	if (data != NULL) {
+		if (!(ret = malloc(siz)))
+			BUFerr(BUF_F_BUF_MEMDUP, ERR_R_MALLOC_FAILURE);
+		else
+			(void) memcpy(ret, data, siz);
+	}
+	return ret;
+}
+
+size_t
+BUF_strlcpy(char *dst, const char *src, size_t size)
+{
+	return strlcpy(dst, src, size);
+}
+
+size_t
+BUF_strlcat(char *dst, const char *src, size_t size)
+{
+	return strlcat(dst, src, size);
+}
diff --git a/crypto/libressl/crypto/buffer/buffer.c b/crypto/libressl/crypto/buffer/buffer.c
new file mode 100644
index 0000000000..f045777f09
--- /dev/null
+++ b/crypto/libressl/crypto/buffer/buffer.c
@@ -0,0 +1,194 @@
+/* $OpenBSD: buffer.c,v 1.20 2014/07/10 13:58:22 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+/* LIMIT_BEFORE_EXPANSION is the maximum n such that (n+3)/3*4 < 2**31. That
+ * function is applied in several functions in this file and this limit ensures
+ * that the result fits in an int. */
+#define LIMIT_BEFORE_EXPANSION 0x5ffffffc
+
+BUF_MEM *
+BUF_MEM_new(void)
+{
+	BUF_MEM *ret;
+
+	ret = malloc(sizeof(BUF_MEM));
+	if (ret == NULL) {
+		BUFerr(BUF_F_BUF_MEM_NEW, ERR_R_MALLOC_FAILURE);
+		return (NULL);
+	}
+	ret->length = 0;
+	ret->max = 0;
+	ret->data = NULL;
+	return (ret);
+}
+
+void
+BUF_MEM_free(BUF_MEM *a)
+{
+	if (a == NULL)
+		return;
+
+	if (a->data != NULL) {
+		explicit_bzero(a->data, a->max);
+		free(a->data);
+	}
+	free(a);
+}
+
+int
+BUF_MEM_grow(BUF_MEM *str, size_t len)
+{
+	char *ret;
+	size_t n;
+
+	if (str->length >= len) {
+		str->length = len;
+		return (len);
+	}
+	if (str->max >= len) {
+		memset(&str->data[str->length], 0, len - str->length);
+		str->length = len;
+		return (len);
+	}
+	/* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
+	if (len > LIMIT_BEFORE_EXPANSION) {
+		BUFerr(BUF_F_BUF_MEM_GROW, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	n = (len + 3) / 3 * 4;
+	ret = realloc(str->data, n);
+	if (ret == NULL) {
+		BUFerr(BUF_F_BUF_MEM_GROW, ERR_R_MALLOC_FAILURE);
+		len = 0;
+	} else {
+		str->data = ret;
+		str->max = n;
+		memset(&str->data[str->length], 0, len - str->length);
+		str->length = len;
+	}
+	return (len);
+}
+
+int
+BUF_MEM_grow_clean(BUF_MEM *str, size_t len)
+{
+	char *ret;
+	size_t n;
+
+	if (str->length >= len) {
+		memset(&str->data[len], 0, str->length - len);
+		str->length = len;
+		return (len);
+	}
+	if (str->max >= len) {
+		memset(&str->data[str->length], 0, len - str->length);
+		str->length = len;
+		return (len);
+	}
+	/* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
+	if (len > LIMIT_BEFORE_EXPANSION) {
+		BUFerr(BUF_F_BUF_MEM_GROW_CLEAN, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	n = (len + 3) / 3 * 4;
+	ret = malloc(n);
+	/* we're not shrinking - that case returns above */
+	if ((ret != NULL)  && (str->data != NULL)) {
+		memcpy(ret, str->data, str->max);
+		explicit_bzero(str->data, str->max);
+		free(str->data);
+	}
+	if (ret == NULL) {
+		BUFerr(BUF_F_BUF_MEM_GROW_CLEAN, ERR_R_MALLOC_FAILURE);
+		len = 0;
+	} else {
+		str->data = ret;
+		str->max = n;
+		memset(&str->data[str->length], 0, len - str->length);
+		str->length = len;
+	}
+	return (len);
+}
+
+void
+BUF_reverse(unsigned char *out, const unsigned char *in, size_t size)
+{
+	size_t i;
+
+	if (in) {
+		out += size - 1;
+		for (i = 0; i < size; i++)
+			*out-- = *in++;
+	} else {
+		unsigned char *q;
+		char c;
+		q = out + size - 1;
+		for (i = 0; i < size / 2; i++) {
+			c = *q;
+			*q-- = *out;
+			*out++ = c;
+		}
+	}
+}
diff --git a/crypto/libressl/crypto/camellia/camellia.c b/crypto/libressl/crypto/camellia/camellia.c
new file mode 100644
index 0000000000..f697c67435
--- /dev/null
+++ b/crypto/libressl/crypto/camellia/camellia.c
@@ -0,0 +1,571 @@
+/* $OpenBSD: camellia.c,v 1.9 2014/11/13 20:01:58 miod Exp $ */
+/* ====================================================================
+ * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) . 
+ * ALL RIGHTS RESERVED.
+ *
+ * Intellectual Property information for Camellia:
+ *     http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html
+ *
+ * News Release for Announcement of Camellia open source:
+ *     http://www.ntt.co.jp/news/news06e/0604/060413a.html
+ *
+ * The Camellia Code included herein is developed by
+ * NTT (Nippon Telegraph and Telephone Corporation), and is contributed
+ * to the OpenSSL project.
+ *
+ * The Camellia Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+/*
+ * Algorithm Specification
+ * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
+ */
+
+/*
+ * This release balances code size and performance. In particular key
+ * schedule setup is fully unrolled, because doing so *significantly*
+ * reduces amount of instructions per setup round and code increase is
+ * justifiable. In block functions on the other hand only inner loops
+ * are unrolled, as full unroll gives only nominal performance boost,
+ * while code size grows 4 or 7 times. Also, unlike previous versions
+ * this one "encourages" compiler to keep intermediate variables in
+ * registers, which should give better "all round" results, in other
+ * words reasonable performance even with not so modern compilers.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "cmll_locl.h"
+
+/* 32-bit rotations */
+#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+# if defined(__GNUC__) && __GNUC__>=2
+#  if defined(__i386) || defined(__x86_64)
+#   define RightRotate(x,s) ({u32 ret; asm ("rorl %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; })
+#   define LeftRotate(x,s)  ({u32 ret; asm ("roll %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; })
+#   define GETU32(p)   ({u32 r=*(const u32 *)(p); asm("bswapl %0":"=r"(r):"0"(r)); r; })
+#   define PUTU32(p,v) ({u32 r=(v); asm("bswapl %0":"=r"(r):"0"(r)); *(u32 *)(p)=r; })
+#  elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
+        defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__)
+#   define LeftRotate(x,s)  ({u32 ret; asm ("rlwinm %0,%1,%2,0,31":"=r"(ret):"r"(x),"I"(s)); ret; })
+#   define RightRotate(x,s) LeftRotate(x,(32-s))
+#  elif defined(__s390x__)
+#   define LeftRotate(x,s)  ({u32 ret; asm ("rll %0,%1,%2":"=r"(ret):"r"(x),"I"(s)); ret; })
+#   define RightRotate(x,s) LeftRotate(x,(32-s))
+#   define GETU32(p)   (*(u32 *)(p))
+#   define PUTU32(p,v) (*(u32 *)(p)=(v))
+#  endif
+# endif
+#endif
+
+#if !defined(RightRotate) && !defined(LeftRotate)
+# define RightRotate(x, s) ( ((x) >> (s)) + ((x) << (32 - s)) )
+# define LeftRotate(x, s)  ( ((x) << (s)) + ((x) >> (32 - s)) )
+#endif
+
+#if !defined(GETU32) && !defined(PUTU32)
+# define GETU32(p)   (((u32)(p)[0] << 24) ^ ((u32)(p)[1] << 16) ^ ((u32)(p)[2] <<  8) ^ ((u32)(p)[3]))
+# define PUTU32(p,v) ((p)[0] = (u8)((v) >> 24), (p)[1] = (u8)((v) >> 16), (p)[2] = (u8)((v) >>  8), (p)[3] = (u8)(v))
+#endif
+
+/* S-box data */
+#define SBOX1_1110 Camellia_SBOX[0]
+#define SBOX4_4404 Camellia_SBOX[1]
+#define SBOX2_0222 Camellia_SBOX[2]
+#define SBOX3_3033 Camellia_SBOX[3]
+static const u32 Camellia_SBOX[][256] = {
+{   0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700,
+    0xc0c0c000, 0xe5e5e500, 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500,
+    0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, 0x23232300, 0xefefef00,
+    0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100,
+    0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500,
+    0x92929200, 0xbdbdbd00, 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00,
+    0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, 0x3e3e3e00, 0x30303000,
+    0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00,
+    0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700,
+    0x5d5d5d00, 0x3d3d3d00, 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600,
+    0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, 0x8b8b8b00, 0x0d0d0d00,
+    0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00,
+    0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100,
+    0x84848400, 0x99999900, 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200,
+    0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, 0x6d6d6d00, 0xb7b7b700,
+    0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700,
+    0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00,
+    0x11111100, 0x1c1c1c00, 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600,
+    0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, 0xfefefe00, 0x44444400,
+    0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100,
+    0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00,
+    0x69696900, 0x50505000, 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00,
+    0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, 0x54545400, 0x5b5b5b00,
+    0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200,
+    0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700,
+    0x75757500, 0xdbdbdb00, 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00,
+    0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, 0x87878700, 0x5c5c5c00,
+    0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300,
+    0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00,
+    0xbfbfbf00, 0xe2e2e200, 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600,
+    0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, 0x81818100, 0x96969600,
+    0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00,
+    0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00,
+    0xbcbcbc00, 0x8e8e8e00, 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600,
+    0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, 0x78787800, 0x98989800,
+    0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00,
+    0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200,
+    0x8d8d8d00, 0xfafafa00, 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500,
+    0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, 0x36363600, 0x49494900,
+    0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400,
+    0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900,
+    0x43434300, 0xc1c1c100, 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400,
+    0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00 },
+{   0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057,
+    0xeaea00ea, 0xaeae00ae, 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5,
+    0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, 0x86860086, 0xafaf00af,
+    0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b,
+    0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a,
+    0x51510051, 0x6c6c006c, 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0,
+    0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, 0xdfdf00df, 0xcbcb00cb,
+    0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004,
+    0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c,
+    0x53530053, 0xf2f200f2, 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a,
+    0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, 0xaaaa00aa, 0xa0a000a0,
+    0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064,
+    0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6,
+    0x09090009, 0xdddd00dd, 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090,
+    0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, 0x52520052, 0xd8d800d8,
+    0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063,
+    0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9,
+    0x2f2f002f, 0xb4b400b4, 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071,
+    0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, 0x72720072, 0xb9b900b9,
+    0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1,
+    0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad,
+    0x77770077, 0x80800080, 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5,
+    0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, 0xefef00ef, 0x93930093,
+    0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd,
+    0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f,
+    0xc5c500c5, 0x1a1a001a, 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d,
+    0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, 0x0d0d000d, 0x66660066,
+    0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099,
+    0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031,
+    0x17170017, 0xd7d700d7, 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c,
+    0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, 0x44440044, 0xb2b200b2,
+    0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050,
+    0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095,
+    0xffff00ff, 0xd2d200d2, 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db,
+    0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, 0x5c5c005c, 0x02020002,
+    0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2,
+    0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b,
+    0xbebe00be, 0x2e2e002e, 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e,
+    0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, 0x98980098, 0x6a6a006a,
+    0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa,
+    0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068,
+    0x38380038, 0xa4a400a4, 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1,
+    0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e },
+{   0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e,
+    0x00818181, 0x00cbcbcb, 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a,
+    0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, 0x00464646, 0x00dfdfdf,
+    0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242,
+    0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca,
+    0x00252525, 0x007b7b7b, 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f,
+    0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, 0x007c7c7c, 0x00606060,
+    0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434,
+    0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e,
+    0x00bababa, 0x007a7a7a, 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad,
+    0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, 0x00171717, 0x001a1a1a,
+    0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a,
+    0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363,
+    0x00090909, 0x00333333, 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585,
+    0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, 0x00dadada, 0x006f6f6f,
+    0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf,
+    0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636,
+    0x00222222, 0x00383838, 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c,
+    0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, 0x00fdfdfd, 0x00888888,
+    0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323,
+    0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9,
+    0x00d2d2d2, 0x00a0a0a0, 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa,
+    0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, 0x00a8a8a8, 0x00b6b6b6,
+    0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5,
+    0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef,
+    0x00eaeaea, 0x00b7b7b7, 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5,
+    0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, 0x000f0f0f, 0x00b8b8b8,
+    0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666,
+    0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe,
+    0x007f7f7f, 0x00c5c5c5, 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c,
+    0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, 0x00030303, 0x002d2d2d,
+    0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c,
+    0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc,
+    0x00797979, 0x001d1d1d, 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d,
+    0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, 0x00f0f0f0, 0x00313131,
+    0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575,
+    0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545,
+    0x001b1b1b, 0x00f5f5f5, 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa,
+    0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, 0x006c6c6c, 0x00929292,
+    0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949,
+    0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393,
+    0x00868686, 0x00838383, 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9,
+    0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d },
+{   0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393,
+    0x60006060, 0xf200f2f2, 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a,
+    0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, 0x91009191, 0xf700f7f7,
+    0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090,
+    0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2,
+    0x49004949, 0xde00dede, 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7,
+    0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, 0x1f001f1f, 0x18001818,
+    0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d,
+    0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3,
+    0xae00aeae, 0x9e009e9e, 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b,
+    0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, 0xc500c5c5, 0x86008686,
+    0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696,
+    0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8,
+    0x42004242, 0xcc00cccc, 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161,
+    0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, 0xb600b6b6, 0xdb00dbdb,
+    0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb,
+    0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d,
+    0x88008888, 0x0e000e0e, 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b,
+    0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, 0x7f007f7f, 0x22002222,
+    0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8,
+    0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e,
+    0xb400b4b4, 0x28002828, 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe,
+    0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, 0x2a002a2a, 0xad00adad,
+    0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969,
+    0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb,
+    0xba00baba, 0xed00eded, 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d,
+    0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, 0xc300c3c3, 0x2e002e2e,
+    0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999,
+    0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf,
+    0xdf00dfdf, 0x71007171, 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313,
+    0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, 0xc000c0c0, 0x4b004b4b,
+    0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717,
+    0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737,
+    0x5e005e5e, 0x47004747, 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b,
+    0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, 0x3c003c3c, 0x4c004c4c,
+    0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d,
+    0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151,
+    0xc600c6c6, 0x7d007d7d, 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa,
+    0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, 0x1b001b1b, 0xa400a4a4,
+    0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252,
+    0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4,
+    0xa100a1a1, 0xe000e0e0, 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a,
+    0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f }
+};
+
+/* Key generation constants */
+static const u32 SIGMA[] = {
+    0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2, 0xc6ef372f, 0xe94f82be,
+    0x54ff53a5, 0xf1d36f1c, 0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd
+};
+
+/* The phi algorithm given in C.2.7 of the Camellia spec document. */
+/*
+ * This version does not attempt to minimize amount of temporary
+ * variables, but instead explicitly exposes algorithm's parallelism.
+ * It is therefore most appropriate for platforms with not less than
+ * ~16 registers. For platforms with fewer registers [well, x86 to be
+ * specific] assembler version should be/is provided anyway...
+ */
+#define Camellia_Feistel(_s0,_s1,_s2,_s3,_key) \
+do { \
+	u32 _t0, _t1, _t2, _t3; \
+	_t0 = _s0 ^ (_key)[0]; \
+	_t3 = SBOX4_4404[_t0 & 0xff]; \
+	_t1 = _s1 ^ (_key)[1]; \
+	_t3 ^= SBOX3_3033[(_t0 >> 8) & 0xff]; \
+	_t2 = SBOX1_1110[_t1 & 0xff]; \
+	_t3 ^= SBOX2_0222[(_t0 >> 16) & 0xff]; \
+	_t2 ^= SBOX4_4404[(_t1 >> 8) & 0xff]; \
+	_t3 ^= SBOX1_1110[(_t0 >> 24)]; \
+	_t2 ^= _t3; \
+	_t3 = RightRotate(_t3, 8); \
+	_t2 ^= SBOX3_3033[(_t1 >> 16) & 0xff]; \
+	_s3 ^= _t3; \
+	_t2 ^= SBOX2_0222[(_t1 >> 24)]; \
+	_s2 ^= _t2; \
+	_s3 ^= _t2; \
+} while(0)
+
+/*
+ * Note that n has to be less than 32. Rotations for larger amount
+ * of bits are achieved by "rotating" order of s-elements and
+ * adjusting n accordingly, e.g. RotLeft128(s1, s2, s3, s0, n - 32).
+ */
+#define RotLeft128(_s0, _s1, _s2, _s3, _n) \
+do { \
+	u32 _t0 = _s0 >> (32 - _n); \
+	_s0 = (_s0 << _n) | (_s1 >> (32 - _n)); \
+	_s1 = (_s1 << _n) | (_s2 >> (32 - _n)); \
+	_s2 = (_s2 << _n) | (_s3 >> (32 - _n)); \
+	_s3 = (_s3 << _n) | _t0; \
+} while (0)
+
+int
+Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, KEY_TABLE_TYPE k)
+{
+	u32 s0, s1, s2, s3;
+
+	k[0] = s0 = GETU32(rawKey);
+	k[1] = s1 = GETU32(rawKey + 4);
+	k[2] = s2 = GETU32(rawKey + 8);
+	k[3] = s3 = GETU32(rawKey + 12);
+
+	if (keyBitLength != 128) {
+		k[8] = s0 = GETU32(rawKey + 16);
+		k[9] = s1 = GETU32(rawKey + 20);
+		if (keyBitLength == 192) {
+			k[10] = s2 = ~s0;
+			k[11] = s3 = ~s1;
+		} else {
+			k[10] = s2 = GETU32(rawKey + 24);
+			k[11] = s3 = GETU32(rawKey + 28);
+		}
+		s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3];
+	}
+
+	/* Use the Feistel routine to scramble the key material */
+	Camellia_Feistel(s0, s1, s2, s3, SIGMA + 0);
+	Camellia_Feistel(s2, s3, s0, s1, SIGMA + 2);
+
+	s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3];
+	Camellia_Feistel(s0, s1, s2, s3, SIGMA + 4);
+	Camellia_Feistel(s2, s3, s0, s1, SIGMA + 6);
+
+	/* Fill the keyTable. Requires many block rotations. */
+	if (keyBitLength == 128) {
+		k[ 4] = s0, k[ 5] = s1, k[ 6] = s2, k[ 7] = s3;
+		RotLeft128(s0, s1, s2, s3, 15);	/* KA <<< 15 */
+		k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
+		RotLeft128(s0, s1, s2, s3, 15);	/* KA <<< 30 */
+		k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3;
+		RotLeft128(s0, s1, s2, s3, 15);	/* KA <<< 45 */
+		k[24] = s0, k[25] = s1;
+		RotLeft128(s0, s1, s2, s3, 15);	/* KA <<< 60 */
+		k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3;
+		RotLeft128(s1, s2, s3, s0, 2);	/* KA <<< 94 */
+		k[40] = s1, k[41] = s2, k[42] = s3, k[43] = s0;
+		RotLeft128(s1, s2, s3, s0, 17);	/* KA <<<111 */
+		k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0;
+
+		s0 = k[ 0], s1 = k[ 1], s2 = k[ 2], s3 = k[ 3];
+		RotLeft128(s0, s1, s2, s3, 15);	/* KL <<< 15 */
+		k[ 8] = s0, k[ 9] = s1, k[10] = s2, k[11] = s3;
+		RotLeft128(s0, s1, s2, s3, 30);	/* KL <<< 45 */
+		k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3;
+		RotLeft128(s0, s1, s2, s3, 15);	/* KL <<< 60 */
+		k[26] = s2, k[27] = s3;
+		RotLeft128(s0, s1, s2, s3, 17);	/* KL <<< 77 */
+		k[32] = s0, k[33] = s1, k[34] = s2, k[35] = s3;
+		RotLeft128(s0, s1, s2, s3, 17);	/* KL <<< 94 */
+		k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3;
+		RotLeft128(s0, s1, s2, s3, 17);	/* KL <<<111 */
+		k[44] = s0, k[45] = s1, k[46] = s2, k[47] = s3;
+
+		return 3;	/* grand rounds */
+	} else {
+		k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
+		s0 ^= k[8], s1 ^= k[9], s2 ^=k[10], s3 ^=k[11];
+		Camellia_Feistel(s0, s1, s2, s3, (SIGMA + 8));
+		Camellia_Feistel(s2, s3, s0, s1, (SIGMA + 10));
+
+		k[ 4] = s0, k[ 5] = s1, k[ 6] = s2, k[ 7] = s3;
+		RotLeft128(s0, s1, s2, s3, 30);	/* KB <<< 30 */
+		k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3;
+		RotLeft128(s0, s1, s2, s3, 30);	/* KB <<< 60 */
+		k[40] = s0, k[41] = s1, k[42] = s2, k[43] = s3;
+		RotLeft128(s1, s2, s3, s0, 19);	/* KB <<<111 */
+		k[64] = s1, k[65] = s2, k[66] = s3, k[67] = s0;
+
+		s0 = k[ 8], s1 = k[ 9], s2 = k[10], s3 = k[11];
+		RotLeft128(s0, s1, s2, s3, 15);	/* KR <<< 15 */
+		k[ 8] = s0, k[ 9] = s1, k[10] = s2, k[11] = s3;
+		RotLeft128(s0, s1, s2, s3, 15);	/* KR <<< 30 */
+		k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3;
+		RotLeft128(s0, s1, s2, s3, 30);	/* KR <<< 60 */
+		k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3;
+		RotLeft128(s1, s2, s3, s0, 2);	/* KR <<< 94 */
+		k[52] = s1, k[53] = s2, k[54] = s3, k[55] = s0;
+
+		s0 = k[12], s1 = k[13], s2 = k[14], s3 = k[15];
+		RotLeft128(s0, s1, s2, s3, 15);	/* KA <<< 15 */
+		k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
+		RotLeft128(s0, s1, s2, s3, 30);	/* KA <<< 45 */
+		k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3;
+						/* KA <<< 77 */
+		k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0;
+		RotLeft128(s1, s2, s3, s0, 17);	/* KA <<< 94 */
+		k[56] = s1, k[57] = s2, k[58] = s3, k[59] = s0;
+
+		s0 = k[ 0], s1 = k[ 1], s2 = k[ 2], s3 = k[ 3];
+		RotLeft128(s1, s2, s3, s0, 13);	/* KL <<< 45 */
+		k[24] = s1, k[25] = s2, k[26] = s3, k[27] = s0;
+		RotLeft128(s1, s2, s3, s0, 15);	/* KL <<< 60 */
+		k[32] = s1, k[33] = s2, k[34] = s3, k[35] = s0;
+		RotLeft128(s1, s2, s3, s0, 17);	/* KL <<< 77 */
+		k[44] = s1, k[45] = s2, k[46] = s3, k[47] = s0;
+		RotLeft128(s2, s3, s0, s1, 2);	/* KL <<<111 */
+		k[60] = s2, k[61] = s3, k[62] = s0, k[63] = s1;
+
+		return 4;	/* grand rounds */
+	}
+	/*
+	 * It is possible to perform certain precalculations, which
+	 * would spare few cycles in block procedure. It's not done,
+	 * because it upsets the performance balance between key
+	 * setup and block procedures, negatively affecting overall
+	 * throughput in applications operating on short messages
+	 * and volatile keys.
+	 */
+}
+
+void
+Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[],
+    const KEY_TABLE_TYPE keyTable, u8 ciphertext[])
+{
+	u32 s0, s1, s2, s3;
+	const u32 *k = keyTable, *kend = keyTable + grandRounds * 16;
+
+	s0 = GETU32(plaintext) ^ k[0];
+	s1 = GETU32(plaintext + 4) ^ k[1];
+	s2 = GETU32(plaintext + 8) ^ k[2];
+	s3 = GETU32(plaintext + 12) ^ k[3];
+	k += 4;
+
+	while (1) {
+		/* Camellia makes 6 Feistel rounds */
+		Camellia_Feistel(s0, s1, s2, s3, k + 0);
+		Camellia_Feistel(s2, s3, s0, s1, k + 2);
+		Camellia_Feistel(s0, s1, s2, s3, k + 4);
+		Camellia_Feistel(s2, s3, s0, s1, k + 6);
+		Camellia_Feistel(s0, s1, s2, s3, k + 8);
+		Camellia_Feistel(s2, s3, s0, s1, k + 10);
+		k += 12;
+
+		if (k == kend)
+			break;
+
+		/* This is the same function as the diffusion function D
+		 * of the accompanying documentation. See section 3.2
+		 * for properties of the FLlayer function. */
+		s1 ^= LeftRotate(s0 & k[0], 1);
+		s2 ^= s3 | k[3];
+		s0 ^= s1 | k[1];
+		s3 ^= LeftRotate(s2 & k[2], 1);
+		k += 4;
+	}
+
+	s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3];
+
+	PUTU32(ciphertext, s2);
+	PUTU32(ciphertext + 4, s3);
+	PUTU32(ciphertext + 8, s0);
+	PUTU32(ciphertext + 12, s1);
+}
+
+void
+Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[],
+    const KEY_TABLE_TYPE keyTable, u8 ciphertext[])
+{
+	Camellia_EncryptBlock_Rounds(keyBitLength == 128 ? 3 : 4,
+	    plaintext, keyTable, ciphertext);
+}
+
+void
+Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[],
+    const KEY_TABLE_TYPE keyTable, u8 plaintext[])
+{
+	u32 s0, s1, s2, s3;
+	const u32 *k = keyTable+grandRounds * 16, *kend = keyTable+4;
+
+	s0 = GETU32(ciphertext) ^ k[0];
+	s1 = GETU32(ciphertext+4) ^ k[1];
+	s2 = GETU32(ciphertext+8) ^ k[2];
+	s3 = GETU32(ciphertext+12) ^ k[3];
+
+	while (1) {
+		/* Camellia makes 6 Feistel rounds */
+		k -= 12;
+		Camellia_Feistel(s0, s1, s2, s3, k+10);
+		Camellia_Feistel(s2, s3, s0, s1, k+8);
+		Camellia_Feistel(s0, s1, s2, s3, k+6);
+		Camellia_Feistel(s2, s3, s0, s1, k+4);
+		Camellia_Feistel(s0, s1, s2, s3, k+2);
+		Camellia_Feistel(s2, s3, s0, s1, k+0);
+
+		if (k == kend)
+			break;
+
+		/* This is the same function as the diffusion function D
+		 * of the accompanying documentation. See section 3.2
+		 * for properties of the FLlayer function. */
+		k -= 4;
+		s1 ^= LeftRotate(s0 & k[2], 1);
+		s2 ^= s3 | k[1];
+		s0 ^= s1 | k[3];
+		s3 ^= LeftRotate(s2 & k[0], 1);
+	}
+
+	k -= 4;
+	s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3];
+
+	PUTU32(plaintext, s2);
+	PUTU32(plaintext+4, s3);
+	PUTU32(plaintext+8, s0);
+	PUTU32(plaintext+12, s1);
+}
+
+void
+Camellia_DecryptBlock(int keyBitLength, const u8 plaintext[],
+    const KEY_TABLE_TYPE keyTable, u8 ciphertext[])
+{
+	Camellia_DecryptBlock_Rounds(keyBitLength == 128 ? 3 : 4,
+	    plaintext, keyTable, ciphertext);
+}
diff --git a/crypto/libressl/crypto/camellia/camellia.h b/crypto/libressl/crypto/camellia/camellia.h
new file mode 100644
index 0000000000..ead271bc7f
--- /dev/null
+++ b/crypto/libressl/crypto/camellia/camellia.h
@@ -0,0 +1,125 @@
+/* $OpenBSD: camellia.h,v 1.4 2014/06/12 15:49:28 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#ifndef HEADER_CAMELLIA_H
+#define HEADER_CAMELLIA_H
+
+#include 
+
+#ifdef OPENSSL_NO_CAMELLIA
+#error CAMELLIA is disabled.
+#endif
+
+#include 
+
+#define CAMELLIA_ENCRYPT	1
+#define CAMELLIA_DECRYPT	0
+
+/* Because array size can't be a const in C, the following two are macros.
+   Both sizes are in bytes. */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* This should be a hidden type, but EVP requires that the size be known */
+
+#define CAMELLIA_BLOCK_SIZE 16
+#define CAMELLIA_TABLE_BYTE_LEN 272
+#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
+
+typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match with WORD */
+
+struct camellia_key_st {
+	union {
+		double d;	/* ensures 64-bit align */
+		KEY_TABLE_TYPE rd_key;
+	} u;
+	int grand_rounds;
+};
+typedef struct camellia_key_st CAMELLIA_KEY;
+
+int Camellia_set_key(const unsigned char *userKey, const int bits,
+	CAMELLIA_KEY *key);
+
+void Camellia_encrypt(const unsigned char *in, unsigned char *out,
+	const CAMELLIA_KEY *key);
+void Camellia_decrypt(const unsigned char *in, unsigned char *out,
+	const CAMELLIA_KEY *key);
+
+void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out,
+	const CAMELLIA_KEY *key, const int enc);
+void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const CAMELLIA_KEY *key,
+	unsigned char *ivec, const int enc);
+void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const CAMELLIA_KEY *key,
+	unsigned char *ivec, int *num, const int enc);
+void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const CAMELLIA_KEY *key,
+	unsigned char *ivec, int *num, const int enc);
+void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const CAMELLIA_KEY *key,
+	unsigned char *ivec, int *num, const int enc);
+void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const CAMELLIA_KEY *key,
+	unsigned char *ivec, int *num);
+void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, const CAMELLIA_KEY *key,
+	unsigned char ivec[CAMELLIA_BLOCK_SIZE],
+	unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE],
+	unsigned int *num);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* !HEADER_Camellia_H */
diff --git a/crypto/libressl/crypto/camellia/cmll-elf-x86_64.s b/crypto/libressl/crypto/camellia/cmll-elf-x86_64.s
new file mode 100644
index 0000000000..bb0b605eca
--- /dev/null
+++ b/crypto/libressl/crypto/camellia/cmll-elf-x86_64.s
@@ -0,0 +1,1841 @@
+.text	
+
+
+.globl	Camellia_EncryptBlock
+.type	Camellia_EncryptBlock,@function
+.align	16
+Camellia_EncryptBlock:
+	movl	$128,%eax
+	subl	%edi,%eax
+	movl	$3,%edi
+	adcl	$0,%edi
+	jmp	.Lenc_rounds
+.size	Camellia_EncryptBlock,.-Camellia_EncryptBlock
+
+.globl	Camellia_EncryptBlock_Rounds
+.type	Camellia_EncryptBlock_Rounds,@function
+.align	16
+.Lenc_rounds:
+Camellia_EncryptBlock_Rounds:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+.Lenc_prologue:
+
+
+	movq	%rcx,%r13
+	movq	%rdx,%r14
+
+	shll	$6,%edi
+	leaq	.LCamellia_SBOX(%rip),%rbp
+	leaq	(%r14,%rdi,1),%r15
+
+	movl	0(%rsi),%r8d
+	movl	4(%rsi),%r9d
+	movl	8(%rsi),%r10d
+	bswapl	%r8d
+	movl	12(%rsi),%r11d
+	bswapl	%r9d
+	bswapl	%r10d
+	bswapl	%r11d
+
+	call	_x86_64_Camellia_encrypt
+
+	bswapl	%r8d
+	bswapl	%r9d
+	bswapl	%r10d
+	movl	%r8d,0(%r13)
+	bswapl	%r11d
+	movl	%r9d,4(%r13)
+	movl	%r10d,8(%r13)
+	movl	%r11d,12(%r13)
+
+	movq	0(%rsp),%r15
+	movq	8(%rsp),%r14
+	movq	16(%rsp),%r13
+	movq	24(%rsp),%rbp
+	movq	32(%rsp),%rbx
+	leaq	40(%rsp),%rsp
+.Lenc_epilogue:
+	.byte	0xf3,0xc3
+.size	Camellia_EncryptBlock_Rounds,.-Camellia_EncryptBlock_Rounds
+
+.type	_x86_64_Camellia_encrypt,@function
+.align	16
+_x86_64_Camellia_encrypt:
+	xorl	0(%r14),%r9d
+	xorl	4(%r14),%r8d
+	xorl	8(%r14),%r11d
+	xorl	12(%r14),%r10d
+.align	16
+.Leloop:
+	movl	16(%r14),%ebx
+	movl	20(%r14),%eax
+
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	24(%r14),%ebx
+	movl	28(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r10d
+	xorl	%ecx,%r11d
+	xorl	%edx,%r11d
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	32(%r14),%ebx
+	movl	36(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r8d
+	xorl	%ecx,%r9d
+	xorl	%edx,%r9d
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	40(%r14),%ebx
+	movl	44(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r10d
+	xorl	%ecx,%r11d
+	xorl	%edx,%r11d
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	48(%r14),%ebx
+	movl	52(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r8d
+	xorl	%ecx,%r9d
+	xorl	%edx,%r9d
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	56(%r14),%ebx
+	movl	60(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r10d
+	xorl	%ecx,%r11d
+	xorl	%edx,%r11d
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	64(%r14),%ebx
+	movl	68(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r8d
+	xorl	%ecx,%r9d
+	xorl	%edx,%r9d
+	leaq	64(%r14),%r14
+	cmpq	%r15,%r14
+	movl	8(%r14),%edx
+	movl	12(%r14),%ecx
+	je	.Ledone
+
+	andl	%r8d,%eax
+	orl	%r11d,%edx
+	roll	$1,%eax
+	xorl	%edx,%r10d
+	xorl	%eax,%r9d
+	andl	%r10d,%ecx
+	orl	%r9d,%ebx
+	roll	$1,%ecx
+	xorl	%ebx,%r8d
+	xorl	%ecx,%r11d
+	jmp	.Leloop
+
+.align	16
+.Ledone:
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	xorl	%r8d,%ecx
+	xorl	%r9d,%edx
+
+	movl	%eax,%r8d
+	movl	%ebx,%r9d
+	movl	%ecx,%r10d
+	movl	%edx,%r11d
+
+.byte	0xf3,0xc3		
+.size	_x86_64_Camellia_encrypt,.-_x86_64_Camellia_encrypt
+
+
+.globl	Camellia_DecryptBlock
+.type	Camellia_DecryptBlock,@function
+.align	16
+Camellia_DecryptBlock:
+	movl	$128,%eax
+	subl	%edi,%eax
+	movl	$3,%edi
+	adcl	$0,%edi
+	jmp	.Ldec_rounds
+.size	Camellia_DecryptBlock,.-Camellia_DecryptBlock
+
+.globl	Camellia_DecryptBlock_Rounds
+.type	Camellia_DecryptBlock_Rounds,@function
+.align	16
+.Ldec_rounds:
+Camellia_DecryptBlock_Rounds:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+.Ldec_prologue:
+
+
+	movq	%rcx,%r13
+	movq	%rdx,%r15
+
+	shll	$6,%edi
+	leaq	.LCamellia_SBOX(%rip),%rbp
+	leaq	(%r15,%rdi,1),%r14
+
+	movl	0(%rsi),%r8d
+	movl	4(%rsi),%r9d
+	movl	8(%rsi),%r10d
+	bswapl	%r8d
+	movl	12(%rsi),%r11d
+	bswapl	%r9d
+	bswapl	%r10d
+	bswapl	%r11d
+
+	call	_x86_64_Camellia_decrypt
+
+	bswapl	%r8d
+	bswapl	%r9d
+	bswapl	%r10d
+	movl	%r8d,0(%r13)
+	bswapl	%r11d
+	movl	%r9d,4(%r13)
+	movl	%r10d,8(%r13)
+	movl	%r11d,12(%r13)
+
+	movq	0(%rsp),%r15
+	movq	8(%rsp),%r14
+	movq	16(%rsp),%r13
+	movq	24(%rsp),%rbp
+	movq	32(%rsp),%rbx
+	leaq	40(%rsp),%rsp
+.Ldec_epilogue:
+	.byte	0xf3,0xc3
+.size	Camellia_DecryptBlock_Rounds,.-Camellia_DecryptBlock_Rounds
+
+.type	_x86_64_Camellia_decrypt,@function
+.align	16
+_x86_64_Camellia_decrypt:
+	xorl	0(%r14),%r9d
+	xorl	4(%r14),%r8d
+	xorl	8(%r14),%r11d
+	xorl	12(%r14),%r10d
+.align	16
+.Ldloop:
+	movl	-8(%r14),%ebx
+	movl	-4(%r14),%eax
+
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	-16(%r14),%ebx
+	movl	-12(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r10d
+	xorl	%ecx,%r11d
+	xorl	%edx,%r11d
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	-24(%r14),%ebx
+	movl	-20(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r8d
+	xorl	%ecx,%r9d
+	xorl	%edx,%r9d
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	-32(%r14),%ebx
+	movl	-28(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r10d
+	xorl	%ecx,%r11d
+	xorl	%edx,%r11d
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	-40(%r14),%ebx
+	movl	-36(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r8d
+	xorl	%ecx,%r9d
+	xorl	%edx,%r9d
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	-48(%r14),%ebx
+	movl	-44(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r10d
+	xorl	%ecx,%r11d
+	xorl	%edx,%r11d
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	-56(%r14),%ebx
+	movl	-52(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r8d
+	xorl	%ecx,%r9d
+	xorl	%edx,%r9d
+	leaq	-64(%r14),%r14
+	cmpq	%r15,%r14
+	movl	0(%r14),%edx
+	movl	4(%r14),%ecx
+	je	.Lddone
+
+	andl	%r8d,%eax
+	orl	%r11d,%edx
+	roll	$1,%eax
+	xorl	%edx,%r10d
+	xorl	%eax,%r9d
+	andl	%r10d,%ecx
+	orl	%r9d,%ebx
+	roll	$1,%ecx
+	xorl	%ebx,%r8d
+	xorl	%ecx,%r11d
+
+	jmp	.Ldloop
+
+.align	16
+.Lddone:
+	xorl	%r10d,%ecx
+	xorl	%r11d,%edx
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+
+	movl	%ecx,%r8d
+	movl	%edx,%r9d
+	movl	%eax,%r10d
+	movl	%ebx,%r11d
+
+.byte	0xf3,0xc3		
+.size	_x86_64_Camellia_decrypt,.-_x86_64_Camellia_decrypt
+.globl	Camellia_Ekeygen
+.type	Camellia_Ekeygen,@function
+.align	16
+Camellia_Ekeygen:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+.Lkey_prologue:
+
+	movq	%rdi,%r15
+	movq	%rdx,%r13
+
+	movl	0(%rsi),%r8d
+	movl	4(%rsi),%r9d
+	movl	8(%rsi),%r10d
+	movl	12(%rsi),%r11d
+
+	bswapl	%r8d
+	bswapl	%r9d
+	bswapl	%r10d
+	bswapl	%r11d
+	movl	%r9d,0(%r13)
+	movl	%r8d,4(%r13)
+	movl	%r11d,8(%r13)
+	movl	%r10d,12(%r13)
+	cmpq	$128,%r15
+	je	.L1st128
+
+	movl	16(%rsi),%r8d
+	movl	20(%rsi),%r9d
+	cmpq	$192,%r15
+	je	.L1st192
+	movl	24(%rsi),%r10d
+	movl	28(%rsi),%r11d
+	jmp	.L1st256
+.L1st192:
+	movl	%r8d,%r10d
+	movl	%r9d,%r11d
+	notl	%r10d
+	notl	%r11d
+.L1st256:
+	bswapl	%r8d
+	bswapl	%r9d
+	bswapl	%r10d
+	bswapl	%r11d
+	movl	%r9d,32(%r13)
+	movl	%r8d,36(%r13)
+	movl	%r11d,40(%r13)
+	movl	%r10d,44(%r13)
+	xorl	0(%r13),%r9d
+	xorl	4(%r13),%r8d
+	xorl	8(%r13),%r11d
+	xorl	12(%r13),%r10d
+
+.L1st128:
+	leaq	.LCamellia_SIGMA(%rip),%r14
+	leaq	.LCamellia_SBOX(%rip),%rbp
+
+	movl	0(%r14),%ebx
+	movl	4(%r14),%eax
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	8(%r14),%ebx
+	movl	12(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r10d
+	xorl	%ecx,%r11d
+	xorl	%edx,%r11d
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	16(%r14),%ebx
+	movl	20(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r8d
+	xorl	%ecx,%r9d
+	xorl	%edx,%r9d
+	xorl	0(%r13),%r9d
+	xorl	4(%r13),%r8d
+	xorl	8(%r13),%r11d
+	xorl	12(%r13),%r10d
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	24(%r14),%ebx
+	movl	28(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r10d
+	xorl	%ecx,%r11d
+	xorl	%edx,%r11d
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	32(%r14),%ebx
+	movl	36(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r8d
+	xorl	%ecx,%r9d
+	xorl	%edx,%r9d
+	cmpq	$128,%r15
+	jne	.L2nd256
+
+	leaq	128(%r13),%r13
+	shlq	$32,%r8
+	shlq	$32,%r10
+	orq	%r9,%r8
+	orq	%r11,%r10
+	movq	-128(%r13),%rax
+	movq	-120(%r13),%rbx
+	movq	%r8,-112(%r13)
+	movq	%r10,-104(%r13)
+	movq	%rax,%r11
+	shlq	$15,%rax
+	movq	%rbx,%r9
+	shrq	$49,%r9
+	shrq	$49,%r11
+	orq	%r9,%rax
+	shlq	$15,%rbx
+	orq	%r11,%rbx
+	movq	%rax,-96(%r13)
+	movq	%rbx,-88(%r13)
+	movq	%r8,%r11
+	shlq	$15,%r8
+	movq	%r10,%r9
+	shrq	$49,%r9
+	shrq	$49,%r11
+	orq	%r9,%r8
+	shlq	$15,%r10
+	orq	%r11,%r10
+	movq	%r8,-80(%r13)
+	movq	%r10,-72(%r13)
+	movq	%r8,%r11
+	shlq	$15,%r8
+	movq	%r10,%r9
+	shrq	$49,%r9
+	shrq	$49,%r11
+	orq	%r9,%r8
+	shlq	$15,%r10
+	orq	%r11,%r10
+	movq	%r8,-64(%r13)
+	movq	%r10,-56(%r13)
+	movq	%rax,%r11
+	shlq	$30,%rax
+	movq	%rbx,%r9
+	shrq	$34,%r9
+	shrq	$34,%r11
+	orq	%r9,%rax
+	shlq	$30,%rbx
+	orq	%r11,%rbx
+	movq	%rax,-48(%r13)
+	movq	%rbx,-40(%r13)
+	movq	%r8,%r11
+	shlq	$15,%r8
+	movq	%r10,%r9
+	shrq	$49,%r9
+	shrq	$49,%r11
+	orq	%r9,%r8
+	shlq	$15,%r10
+	orq	%r11,%r10
+	movq	%r8,-32(%r13)
+	movq	%rax,%r11
+	shlq	$15,%rax
+	movq	%rbx,%r9
+	shrq	$49,%r9
+	shrq	$49,%r11
+	orq	%r9,%rax
+	shlq	$15,%rbx
+	orq	%r11,%rbx
+	movq	%rbx,-24(%r13)
+	movq	%r8,%r11
+	shlq	$15,%r8
+	movq	%r10,%r9
+	shrq	$49,%r9
+	shrq	$49,%r11
+	orq	%r9,%r8
+	shlq	$15,%r10
+	orq	%r11,%r10
+	movq	%r8,-16(%r13)
+	movq	%r10,-8(%r13)
+	movq	%rax,%r11
+	shlq	$17,%rax
+	movq	%rbx,%r9
+	shrq	$47,%r9
+	shrq	$47,%r11
+	orq	%r9,%rax
+	shlq	$17,%rbx
+	orq	%r11,%rbx
+	movq	%rax,0(%r13)
+	movq	%rbx,8(%r13)
+	movq	%rax,%r11
+	shlq	$17,%rax
+	movq	%rbx,%r9
+	shrq	$47,%r9
+	shrq	$47,%r11
+	orq	%r9,%rax
+	shlq	$17,%rbx
+	orq	%r11,%rbx
+	movq	%rax,16(%r13)
+	movq	%rbx,24(%r13)
+	movq	%r8,%r11
+	shlq	$34,%r8
+	movq	%r10,%r9
+	shrq	$30,%r9
+	shrq	$30,%r11
+	orq	%r9,%r8
+	shlq	$34,%r10
+	orq	%r11,%r10
+	movq	%r8,32(%r13)
+	movq	%r10,40(%r13)
+	movq	%rax,%r11
+	shlq	$17,%rax
+	movq	%rbx,%r9
+	shrq	$47,%r9
+	shrq	$47,%r11
+	orq	%r9,%rax
+	shlq	$17,%rbx
+	orq	%r11,%rbx
+	movq	%rax,48(%r13)
+	movq	%rbx,56(%r13)
+	movq	%r8,%r11
+	shlq	$17,%r8
+	movq	%r10,%r9
+	shrq	$47,%r9
+	shrq	$47,%r11
+	orq	%r9,%r8
+	shlq	$17,%r10
+	orq	%r11,%r10
+	movq	%r8,64(%r13)
+	movq	%r10,72(%r13)
+	movl	$3,%eax
+	jmp	.Ldone
+.align	16
+.L2nd256:
+	movl	%r9d,48(%r13)
+	movl	%r8d,52(%r13)
+	movl	%r11d,56(%r13)
+	movl	%r10d,60(%r13)
+	xorl	32(%r13),%r9d
+	xorl	36(%r13),%r8d
+	xorl	40(%r13),%r11d
+	xorl	44(%r13),%r10d
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	40(%r14),%ebx
+	movl	44(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r10d
+	xorl	%ecx,%r11d
+	xorl	%edx,%r11d
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	48(%r14),%ebx
+	movl	52(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r8d
+	xorl	%ecx,%r9d
+	xorl	%edx,%r9d
+	movq	0(%r13),%rax
+	movq	8(%r13),%rbx
+	movq	32(%r13),%rcx
+	movq	40(%r13),%rdx
+	movq	48(%r13),%r14
+	movq	56(%r13),%r15
+	leaq	128(%r13),%r13
+	shlq	$32,%r8
+	shlq	$32,%r10
+	orq	%r9,%r8
+	orq	%r11,%r10
+	movq	%r8,-112(%r13)
+	movq	%r10,-104(%r13)
+	movq	%rcx,%r11
+	shlq	$15,%rcx
+	movq	%rdx,%r9
+	shrq	$49,%r9
+	shrq	$49,%r11
+	orq	%r9,%rcx
+	shlq	$15,%rdx
+	orq	%r11,%rdx
+	movq	%rcx,-96(%r13)
+	movq	%rdx,-88(%r13)
+	movq	%r14,%r11
+	shlq	$15,%r14
+	movq	%r15,%r9
+	shrq	$49,%r9
+	shrq	$49,%r11
+	orq	%r9,%r14
+	shlq	$15,%r15
+	orq	%r11,%r15
+	movq	%r14,-80(%r13)
+	movq	%r15,-72(%r13)
+	movq	%rcx,%r11
+	shlq	$15,%rcx
+	movq	%rdx,%r9
+	shrq	$49,%r9
+	shrq	$49,%r11
+	orq	%r9,%rcx
+	shlq	$15,%rdx
+	orq	%r11,%rdx
+	movq	%rcx,-64(%r13)
+	movq	%rdx,-56(%r13)
+	movq	%r8,%r11
+	shlq	$30,%r8
+	movq	%r10,%r9
+	shrq	$34,%r9
+	shrq	$34,%r11
+	orq	%r9,%r8
+	shlq	$30,%r10
+	orq	%r11,%r10
+	movq	%r8,-48(%r13)
+	movq	%r10,-40(%r13)
+	movq	%rax,%r11
+	shlq	$45,%rax
+	movq	%rbx,%r9
+	shrq	$19,%r9
+	shrq	$19,%r11
+	orq	%r9,%rax
+	shlq	$45,%rbx
+	orq	%r11,%rbx
+	movq	%rax,-32(%r13)
+	movq	%rbx,-24(%r13)
+	movq	%r14,%r11
+	shlq	$30,%r14
+	movq	%r15,%r9
+	shrq	$34,%r9
+	shrq	$34,%r11
+	orq	%r9,%r14
+	shlq	$30,%r15
+	orq	%r11,%r15
+	movq	%r14,-16(%r13)
+	movq	%r15,-8(%r13)
+	movq	%rax,%r11
+	shlq	$15,%rax
+	movq	%rbx,%r9
+	shrq	$49,%r9
+	shrq	$49,%r11
+	orq	%r9,%rax
+	shlq	$15,%rbx
+	orq	%r11,%rbx
+	movq	%rax,0(%r13)
+	movq	%rbx,8(%r13)
+	movq	%rcx,%r11
+	shlq	$30,%rcx
+	movq	%rdx,%r9
+	shrq	$34,%r9
+	shrq	$34,%r11
+	orq	%r9,%rcx
+	shlq	$30,%rdx
+	orq	%r11,%rdx
+	movq	%rcx,16(%r13)
+	movq	%rdx,24(%r13)
+	movq	%r8,%r11
+	shlq	$30,%r8
+	movq	%r10,%r9
+	shrq	$34,%r9
+	shrq	$34,%r11
+	orq	%r9,%r8
+	shlq	$30,%r10
+	orq	%r11,%r10
+	movq	%r8,32(%r13)
+	movq	%r10,40(%r13)
+	movq	%rax,%r11
+	shlq	$17,%rax
+	movq	%rbx,%r9
+	shrq	$47,%r9
+	shrq	$47,%r11
+	orq	%r9,%rax
+	shlq	$17,%rbx
+	orq	%r11,%rbx
+	movq	%rax,48(%r13)
+	movq	%rbx,56(%r13)
+	movq	%r14,%r11
+	shlq	$32,%r14
+	movq	%r15,%r9
+	shrq	$32,%r9
+	shrq	$32,%r11
+	orq	%r9,%r14
+	shlq	$32,%r15
+	orq	%r11,%r15
+	movq	%r14,64(%r13)
+	movq	%r15,72(%r13)
+	movq	%rcx,%r11
+	shlq	$34,%rcx
+	movq	%rdx,%r9
+	shrq	$30,%r9
+	shrq	$30,%r11
+	orq	%r9,%rcx
+	shlq	$34,%rdx
+	orq	%r11,%rdx
+	movq	%rcx,80(%r13)
+	movq	%rdx,88(%r13)
+	movq	%r14,%r11
+	shlq	$17,%r14
+	movq	%r15,%r9
+	shrq	$47,%r9
+	shrq	$47,%r11
+	orq	%r9,%r14
+	shlq	$17,%r15
+	orq	%r11,%r15
+	movq	%r14,96(%r13)
+	movq	%r15,104(%r13)
+	movq	%rax,%r11
+	shlq	$34,%rax
+	movq	%rbx,%r9
+	shrq	$30,%r9
+	shrq	$30,%r11
+	orq	%r9,%rax
+	shlq	$34,%rbx
+	orq	%r11,%rbx
+	movq	%rax,112(%r13)
+	movq	%rbx,120(%r13)
+	movq	%r8,%r11
+	shlq	$51,%r8
+	movq	%r10,%r9
+	shrq	$13,%r9
+	shrq	$13,%r11
+	orq	%r9,%r8
+	shlq	$51,%r10
+	orq	%r11,%r10
+	movq	%r8,128(%r13)
+	movq	%r10,136(%r13)
+	movl	$4,%eax
+.Ldone:
+	movq	0(%rsp),%r15
+	movq	8(%rsp),%r14
+	movq	16(%rsp),%r13
+	movq	24(%rsp),%rbp
+	movq	32(%rsp),%rbx
+	leaq	40(%rsp),%rsp
+.Lkey_epilogue:
+	.byte	0xf3,0xc3
+.size	Camellia_Ekeygen,.-Camellia_Ekeygen
+.align	64
+.LCamellia_SIGMA:
+.long	0x3bcc908b, 0xa09e667f, 0x4caa73b2, 0xb67ae858
+.long	0xe94f82be, 0xc6ef372f, 0xf1d36f1c, 0x54ff53a5
+.long	0xde682d1d, 0x10e527fa, 0xb3e6c1fd, 0xb05688c2
+.long	0,          0,          0,          0
+.LCamellia_SBOX:
+.long	0x70707000,0x70700070
+.long	0x82828200,0x2c2c002c
+.long	0x2c2c2c00,0xb3b300b3
+.long	0xececec00,0xc0c000c0
+.long	0xb3b3b300,0xe4e400e4
+.long	0x27272700,0x57570057
+.long	0xc0c0c000,0xeaea00ea
+.long	0xe5e5e500,0xaeae00ae
+.long	0xe4e4e400,0x23230023
+.long	0x85858500,0x6b6b006b
+.long	0x57575700,0x45450045
+.long	0x35353500,0xa5a500a5
+.long	0xeaeaea00,0xeded00ed
+.long	0x0c0c0c00,0x4f4f004f
+.long	0xaeaeae00,0x1d1d001d
+.long	0x41414100,0x92920092
+.long	0x23232300,0x86860086
+.long	0xefefef00,0xafaf00af
+.long	0x6b6b6b00,0x7c7c007c
+.long	0x93939300,0x1f1f001f
+.long	0x45454500,0x3e3e003e
+.long	0x19191900,0xdcdc00dc
+.long	0xa5a5a500,0x5e5e005e
+.long	0x21212100,0x0b0b000b
+.long	0xededed00,0xa6a600a6
+.long	0x0e0e0e00,0x39390039
+.long	0x4f4f4f00,0xd5d500d5
+.long	0x4e4e4e00,0x5d5d005d
+.long	0x1d1d1d00,0xd9d900d9
+.long	0x65656500,0x5a5a005a
+.long	0x92929200,0x51510051
+.long	0xbdbdbd00,0x6c6c006c
+.long	0x86868600,0x8b8b008b
+.long	0xb8b8b800,0x9a9a009a
+.long	0xafafaf00,0xfbfb00fb
+.long	0x8f8f8f00,0xb0b000b0
+.long	0x7c7c7c00,0x74740074
+.long	0xebebeb00,0x2b2b002b
+.long	0x1f1f1f00,0xf0f000f0
+.long	0xcecece00,0x84840084
+.long	0x3e3e3e00,0xdfdf00df
+.long	0x30303000,0xcbcb00cb
+.long	0xdcdcdc00,0x34340034
+.long	0x5f5f5f00,0x76760076
+.long	0x5e5e5e00,0x6d6d006d
+.long	0xc5c5c500,0xa9a900a9
+.long	0x0b0b0b00,0xd1d100d1
+.long	0x1a1a1a00,0x04040004
+.long	0xa6a6a600,0x14140014
+.long	0xe1e1e100,0x3a3a003a
+.long	0x39393900,0xdede00de
+.long	0xcacaca00,0x11110011
+.long	0xd5d5d500,0x32320032
+.long	0x47474700,0x9c9c009c
+.long	0x5d5d5d00,0x53530053
+.long	0x3d3d3d00,0xf2f200f2
+.long	0xd9d9d900,0xfefe00fe
+.long	0x01010100,0xcfcf00cf
+.long	0x5a5a5a00,0xc3c300c3
+.long	0xd6d6d600,0x7a7a007a
+.long	0x51515100,0x24240024
+.long	0x56565600,0xe8e800e8
+.long	0x6c6c6c00,0x60600060
+.long	0x4d4d4d00,0x69690069
+.long	0x8b8b8b00,0xaaaa00aa
+.long	0x0d0d0d00,0xa0a000a0
+.long	0x9a9a9a00,0xa1a100a1
+.long	0x66666600,0x62620062
+.long	0xfbfbfb00,0x54540054
+.long	0xcccccc00,0x1e1e001e
+.long	0xb0b0b000,0xe0e000e0
+.long	0x2d2d2d00,0x64640064
+.long	0x74747400,0x10100010
+.long	0x12121200,0x00000000
+.long	0x2b2b2b00,0xa3a300a3
+.long	0x20202000,0x75750075
+.long	0xf0f0f000,0x8a8a008a
+.long	0xb1b1b100,0xe6e600e6
+.long	0x84848400,0x09090009
+.long	0x99999900,0xdddd00dd
+.long	0xdfdfdf00,0x87870087
+.long	0x4c4c4c00,0x83830083
+.long	0xcbcbcb00,0xcdcd00cd
+.long	0xc2c2c200,0x90900090
+.long	0x34343400,0x73730073
+.long	0x7e7e7e00,0xf6f600f6
+.long	0x76767600,0x9d9d009d
+.long	0x05050500,0xbfbf00bf
+.long	0x6d6d6d00,0x52520052
+.long	0xb7b7b700,0xd8d800d8
+.long	0xa9a9a900,0xc8c800c8
+.long	0x31313100,0xc6c600c6
+.long	0xd1d1d100,0x81810081
+.long	0x17171700,0x6f6f006f
+.long	0x04040400,0x13130013
+.long	0xd7d7d700,0x63630063
+.long	0x14141400,0xe9e900e9
+.long	0x58585800,0xa7a700a7
+.long	0x3a3a3a00,0x9f9f009f
+.long	0x61616100,0xbcbc00bc
+.long	0xdedede00,0x29290029
+.long	0x1b1b1b00,0xf9f900f9
+.long	0x11111100,0x2f2f002f
+.long	0x1c1c1c00,0xb4b400b4
+.long	0x32323200,0x78780078
+.long	0x0f0f0f00,0x06060006
+.long	0x9c9c9c00,0xe7e700e7
+.long	0x16161600,0x71710071
+.long	0x53535300,0xd4d400d4
+.long	0x18181800,0xabab00ab
+.long	0xf2f2f200,0x88880088
+.long	0x22222200,0x8d8d008d
+.long	0xfefefe00,0x72720072
+.long	0x44444400,0xb9b900b9
+.long	0xcfcfcf00,0xf8f800f8
+.long	0xb2b2b200,0xacac00ac
+.long	0xc3c3c300,0x36360036
+.long	0xb5b5b500,0x2a2a002a
+.long	0x7a7a7a00,0x3c3c003c
+.long	0x91919100,0xf1f100f1
+.long	0x24242400,0x40400040
+.long	0x08080800,0xd3d300d3
+.long	0xe8e8e800,0xbbbb00bb
+.long	0xa8a8a800,0x43430043
+.long	0x60606000,0x15150015
+.long	0xfcfcfc00,0xadad00ad
+.long	0x69696900,0x77770077
+.long	0x50505000,0x80800080
+.long	0xaaaaaa00,0x82820082
+.long	0xd0d0d000,0xecec00ec
+.long	0xa0a0a000,0x27270027
+.long	0x7d7d7d00,0xe5e500e5
+.long	0xa1a1a100,0x85850085
+.long	0x89898900,0x35350035
+.long	0x62626200,0x0c0c000c
+.long	0x97979700,0x41410041
+.long	0x54545400,0xefef00ef
+.long	0x5b5b5b00,0x93930093
+.long	0x1e1e1e00,0x19190019
+.long	0x95959500,0x21210021
+.long	0xe0e0e000,0x0e0e000e
+.long	0xffffff00,0x4e4e004e
+.long	0x64646400,0x65650065
+.long	0xd2d2d200,0xbdbd00bd
+.long	0x10101000,0xb8b800b8
+.long	0xc4c4c400,0x8f8f008f
+.long	0x00000000,0xebeb00eb
+.long	0x48484800,0xcece00ce
+.long	0xa3a3a300,0x30300030
+.long	0xf7f7f700,0x5f5f005f
+.long	0x75757500,0xc5c500c5
+.long	0xdbdbdb00,0x1a1a001a
+.long	0x8a8a8a00,0xe1e100e1
+.long	0x03030300,0xcaca00ca
+.long	0xe6e6e600,0x47470047
+.long	0xdadada00,0x3d3d003d
+.long	0x09090900,0x01010001
+.long	0x3f3f3f00,0xd6d600d6
+.long	0xdddddd00,0x56560056
+.long	0x94949400,0x4d4d004d
+.long	0x87878700,0x0d0d000d
+.long	0x5c5c5c00,0x66660066
+.long	0x83838300,0xcccc00cc
+.long	0x02020200,0x2d2d002d
+.long	0xcdcdcd00,0x12120012
+.long	0x4a4a4a00,0x20200020
+.long	0x90909000,0xb1b100b1
+.long	0x33333300,0x99990099
+.long	0x73737300,0x4c4c004c
+.long	0x67676700,0xc2c200c2
+.long	0xf6f6f600,0x7e7e007e
+.long	0xf3f3f300,0x05050005
+.long	0x9d9d9d00,0xb7b700b7
+.long	0x7f7f7f00,0x31310031
+.long	0xbfbfbf00,0x17170017
+.long	0xe2e2e200,0xd7d700d7
+.long	0x52525200,0x58580058
+.long	0x9b9b9b00,0x61610061
+.long	0xd8d8d800,0x1b1b001b
+.long	0x26262600,0x1c1c001c
+.long	0xc8c8c800,0x0f0f000f
+.long	0x37373700,0x16160016
+.long	0xc6c6c600,0x18180018
+.long	0x3b3b3b00,0x22220022
+.long	0x81818100,0x44440044
+.long	0x96969600,0xb2b200b2
+.long	0x6f6f6f00,0xb5b500b5
+.long	0x4b4b4b00,0x91910091
+.long	0x13131300,0x08080008
+.long	0xbebebe00,0xa8a800a8
+.long	0x63636300,0xfcfc00fc
+.long	0x2e2e2e00,0x50500050
+.long	0xe9e9e900,0xd0d000d0
+.long	0x79797900,0x7d7d007d
+.long	0xa7a7a700,0x89890089
+.long	0x8c8c8c00,0x97970097
+.long	0x9f9f9f00,0x5b5b005b
+.long	0x6e6e6e00,0x95950095
+.long	0xbcbcbc00,0xffff00ff
+.long	0x8e8e8e00,0xd2d200d2
+.long	0x29292900,0xc4c400c4
+.long	0xf5f5f500,0x48480048
+.long	0xf9f9f900,0xf7f700f7
+.long	0xb6b6b600,0xdbdb00db
+.long	0x2f2f2f00,0x03030003
+.long	0xfdfdfd00,0xdada00da
+.long	0xb4b4b400,0x3f3f003f
+.long	0x59595900,0x94940094
+.long	0x78787800,0x5c5c005c
+.long	0x98989800,0x02020002
+.long	0x06060600,0x4a4a004a
+.long	0x6a6a6a00,0x33330033
+.long	0xe7e7e700,0x67670067
+.long	0x46464600,0xf3f300f3
+.long	0x71717100,0x7f7f007f
+.long	0xbababa00,0xe2e200e2
+.long	0xd4d4d400,0x9b9b009b
+.long	0x25252500,0x26260026
+.long	0xababab00,0x37370037
+.long	0x42424200,0x3b3b003b
+.long	0x88888800,0x96960096
+.long	0xa2a2a200,0x4b4b004b
+.long	0x8d8d8d00,0xbebe00be
+.long	0xfafafa00,0x2e2e002e
+.long	0x72727200,0x79790079
+.long	0x07070700,0x8c8c008c
+.long	0xb9b9b900,0x6e6e006e
+.long	0x55555500,0x8e8e008e
+.long	0xf8f8f800,0xf5f500f5
+.long	0xeeeeee00,0xb6b600b6
+.long	0xacacac00,0xfdfd00fd
+.long	0x0a0a0a00,0x59590059
+.long	0x36363600,0x98980098
+.long	0x49494900,0x6a6a006a
+.long	0x2a2a2a00,0x46460046
+.long	0x68686800,0xbaba00ba
+.long	0x3c3c3c00,0x25250025
+.long	0x38383800,0x42420042
+.long	0xf1f1f100,0xa2a200a2
+.long	0xa4a4a400,0xfafa00fa
+.long	0x40404000,0x07070007
+.long	0x28282800,0x55550055
+.long	0xd3d3d300,0xeeee00ee
+.long	0x7b7b7b00,0x0a0a000a
+.long	0xbbbbbb00,0x49490049
+.long	0xc9c9c900,0x68680068
+.long	0x43434300,0x38380038
+.long	0xc1c1c100,0xa4a400a4
+.long	0x15151500,0x28280028
+.long	0xe3e3e300,0x7b7b007b
+.long	0xadadad00,0xc9c900c9
+.long	0xf4f4f400,0xc1c100c1
+.long	0x77777700,0xe3e300e3
+.long	0xc7c7c700,0xf4f400f4
+.long	0x80808000,0xc7c700c7
+.long	0x9e9e9e00,0x9e9e009e
+.long	0x00e0e0e0,0x38003838
+.long	0x00050505,0x41004141
+.long	0x00585858,0x16001616
+.long	0x00d9d9d9,0x76007676
+.long	0x00676767,0xd900d9d9
+.long	0x004e4e4e,0x93009393
+.long	0x00818181,0x60006060
+.long	0x00cbcbcb,0xf200f2f2
+.long	0x00c9c9c9,0x72007272
+.long	0x000b0b0b,0xc200c2c2
+.long	0x00aeaeae,0xab00abab
+.long	0x006a6a6a,0x9a009a9a
+.long	0x00d5d5d5,0x75007575
+.long	0x00181818,0x06000606
+.long	0x005d5d5d,0x57005757
+.long	0x00828282,0xa000a0a0
+.long	0x00464646,0x91009191
+.long	0x00dfdfdf,0xf700f7f7
+.long	0x00d6d6d6,0xb500b5b5
+.long	0x00272727,0xc900c9c9
+.long	0x008a8a8a,0xa200a2a2
+.long	0x00323232,0x8c008c8c
+.long	0x004b4b4b,0xd200d2d2
+.long	0x00424242,0x90009090
+.long	0x00dbdbdb,0xf600f6f6
+.long	0x001c1c1c,0x07000707
+.long	0x009e9e9e,0xa700a7a7
+.long	0x009c9c9c,0x27002727
+.long	0x003a3a3a,0x8e008e8e
+.long	0x00cacaca,0xb200b2b2
+.long	0x00252525,0x49004949
+.long	0x007b7b7b,0xde00dede
+.long	0x000d0d0d,0x43004343
+.long	0x00717171,0x5c005c5c
+.long	0x005f5f5f,0xd700d7d7
+.long	0x001f1f1f,0xc700c7c7
+.long	0x00f8f8f8,0x3e003e3e
+.long	0x00d7d7d7,0xf500f5f5
+.long	0x003e3e3e,0x8f008f8f
+.long	0x009d9d9d,0x67006767
+.long	0x007c7c7c,0x1f001f1f
+.long	0x00606060,0x18001818
+.long	0x00b9b9b9,0x6e006e6e
+.long	0x00bebebe,0xaf00afaf
+.long	0x00bcbcbc,0x2f002f2f
+.long	0x008b8b8b,0xe200e2e2
+.long	0x00161616,0x85008585
+.long	0x00343434,0x0d000d0d
+.long	0x004d4d4d,0x53005353
+.long	0x00c3c3c3,0xf000f0f0
+.long	0x00727272,0x9c009c9c
+.long	0x00959595,0x65006565
+.long	0x00ababab,0xea00eaea
+.long	0x008e8e8e,0xa300a3a3
+.long	0x00bababa,0xae00aeae
+.long	0x007a7a7a,0x9e009e9e
+.long	0x00b3b3b3,0xec00ecec
+.long	0x00020202,0x80008080
+.long	0x00b4b4b4,0x2d002d2d
+.long	0x00adadad,0x6b006b6b
+.long	0x00a2a2a2,0xa800a8a8
+.long	0x00acacac,0x2b002b2b
+.long	0x00d8d8d8,0x36003636
+.long	0x009a9a9a,0xa600a6a6
+.long	0x00171717,0xc500c5c5
+.long	0x001a1a1a,0x86008686
+.long	0x00353535,0x4d004d4d
+.long	0x00cccccc,0x33003333
+.long	0x00f7f7f7,0xfd00fdfd
+.long	0x00999999,0x66006666
+.long	0x00616161,0x58005858
+.long	0x005a5a5a,0x96009696
+.long	0x00e8e8e8,0x3a003a3a
+.long	0x00242424,0x09000909
+.long	0x00565656,0x95009595
+.long	0x00404040,0x10001010
+.long	0x00e1e1e1,0x78007878
+.long	0x00636363,0xd800d8d8
+.long	0x00090909,0x42004242
+.long	0x00333333,0xcc00cccc
+.long	0x00bfbfbf,0xef00efef
+.long	0x00989898,0x26002626
+.long	0x00979797,0xe500e5e5
+.long	0x00858585,0x61006161
+.long	0x00686868,0x1a001a1a
+.long	0x00fcfcfc,0x3f003f3f
+.long	0x00ececec,0x3b003b3b
+.long	0x000a0a0a,0x82008282
+.long	0x00dadada,0xb600b6b6
+.long	0x006f6f6f,0xdb00dbdb
+.long	0x00535353,0xd400d4d4
+.long	0x00626262,0x98009898
+.long	0x00a3a3a3,0xe800e8e8
+.long	0x002e2e2e,0x8b008b8b
+.long	0x00080808,0x02000202
+.long	0x00afafaf,0xeb00ebeb
+.long	0x00282828,0x0a000a0a
+.long	0x00b0b0b0,0x2c002c2c
+.long	0x00747474,0x1d001d1d
+.long	0x00c2c2c2,0xb000b0b0
+.long	0x00bdbdbd,0x6f006f6f
+.long	0x00363636,0x8d008d8d
+.long	0x00222222,0x88008888
+.long	0x00383838,0x0e000e0e
+.long	0x00646464,0x19001919
+.long	0x001e1e1e,0x87008787
+.long	0x00393939,0x4e004e4e
+.long	0x002c2c2c,0x0b000b0b
+.long	0x00a6a6a6,0xa900a9a9
+.long	0x00303030,0x0c000c0c
+.long	0x00e5e5e5,0x79007979
+.long	0x00444444,0x11001111
+.long	0x00fdfdfd,0x7f007f7f
+.long	0x00888888,0x22002222
+.long	0x009f9f9f,0xe700e7e7
+.long	0x00656565,0x59005959
+.long	0x00878787,0xe100e1e1
+.long	0x006b6b6b,0xda00dada
+.long	0x00f4f4f4,0x3d003d3d
+.long	0x00232323,0xc800c8c8
+.long	0x00484848,0x12001212
+.long	0x00101010,0x04000404
+.long	0x00d1d1d1,0x74007474
+.long	0x00515151,0x54005454
+.long	0x00c0c0c0,0x30003030
+.long	0x00f9f9f9,0x7e007e7e
+.long	0x00d2d2d2,0xb400b4b4
+.long	0x00a0a0a0,0x28002828
+.long	0x00555555,0x55005555
+.long	0x00a1a1a1,0x68006868
+.long	0x00414141,0x50005050
+.long	0x00fafafa,0xbe00bebe
+.long	0x00434343,0xd000d0d0
+.long	0x00131313,0xc400c4c4
+.long	0x00c4c4c4,0x31003131
+.long	0x002f2f2f,0xcb00cbcb
+.long	0x00a8a8a8,0x2a002a2a
+.long	0x00b6b6b6,0xad00adad
+.long	0x003c3c3c,0x0f000f0f
+.long	0x002b2b2b,0xca00caca
+.long	0x00c1c1c1,0x70007070
+.long	0x00ffffff,0xff00ffff
+.long	0x00c8c8c8,0x32003232
+.long	0x00a5a5a5,0x69006969
+.long	0x00202020,0x08000808
+.long	0x00898989,0x62006262
+.long	0x00000000,0x00000000
+.long	0x00909090,0x24002424
+.long	0x00474747,0xd100d1d1
+.long	0x00efefef,0xfb00fbfb
+.long	0x00eaeaea,0xba00baba
+.long	0x00b7b7b7,0xed00eded
+.long	0x00151515,0x45004545
+.long	0x00060606,0x81008181
+.long	0x00cdcdcd,0x73007373
+.long	0x00b5b5b5,0x6d006d6d
+.long	0x00121212,0x84008484
+.long	0x007e7e7e,0x9f009f9f
+.long	0x00bbbbbb,0xee00eeee
+.long	0x00292929,0x4a004a4a
+.long	0x000f0f0f,0xc300c3c3
+.long	0x00b8b8b8,0x2e002e2e
+.long	0x00070707,0xc100c1c1
+.long	0x00040404,0x01000101
+.long	0x009b9b9b,0xe600e6e6
+.long	0x00949494,0x25002525
+.long	0x00212121,0x48004848
+.long	0x00666666,0x99009999
+.long	0x00e6e6e6,0xb900b9b9
+.long	0x00cecece,0xb300b3b3
+.long	0x00ededed,0x7b007b7b
+.long	0x00e7e7e7,0xf900f9f9
+.long	0x003b3b3b,0xce00cece
+.long	0x00fefefe,0xbf00bfbf
+.long	0x007f7f7f,0xdf00dfdf
+.long	0x00c5c5c5,0x71007171
+.long	0x00a4a4a4,0x29002929
+.long	0x00373737,0xcd00cdcd
+.long	0x00b1b1b1,0x6c006c6c
+.long	0x004c4c4c,0x13001313
+.long	0x00919191,0x64006464
+.long	0x006e6e6e,0x9b009b9b
+.long	0x008d8d8d,0x63006363
+.long	0x00767676,0x9d009d9d
+.long	0x00030303,0xc000c0c0
+.long	0x002d2d2d,0x4b004b4b
+.long	0x00dedede,0xb700b7b7
+.long	0x00969696,0xa500a5a5
+.long	0x00262626,0x89008989
+.long	0x007d7d7d,0x5f005f5f
+.long	0x00c6c6c6,0xb100b1b1
+.long	0x005c5c5c,0x17001717
+.long	0x00d3d3d3,0xf400f4f4
+.long	0x00f2f2f2,0xbc00bcbc
+.long	0x004f4f4f,0xd300d3d3
+.long	0x00191919,0x46004646
+.long	0x003f3f3f,0xcf00cfcf
+.long	0x00dcdcdc,0x37003737
+.long	0x00797979,0x5e005e5e
+.long	0x001d1d1d,0x47004747
+.long	0x00525252,0x94009494
+.long	0x00ebebeb,0xfa00fafa
+.long	0x00f3f3f3,0xfc00fcfc
+.long	0x006d6d6d,0x5b005b5b
+.long	0x005e5e5e,0x97009797
+.long	0x00fbfbfb,0xfe00fefe
+.long	0x00696969,0x5a005a5a
+.long	0x00b2b2b2,0xac00acac
+.long	0x00f0f0f0,0x3c003c3c
+.long	0x00313131,0x4c004c4c
+.long	0x000c0c0c,0x03000303
+.long	0x00d4d4d4,0x35003535
+.long	0x00cfcfcf,0xf300f3f3
+.long	0x008c8c8c,0x23002323
+.long	0x00e2e2e2,0xb800b8b8
+.long	0x00757575,0x5d005d5d
+.long	0x00a9a9a9,0x6a006a6a
+.long	0x004a4a4a,0x92009292
+.long	0x00575757,0xd500d5d5
+.long	0x00848484,0x21002121
+.long	0x00111111,0x44004444
+.long	0x00454545,0x51005151
+.long	0x001b1b1b,0xc600c6c6
+.long	0x00f5f5f5,0x7d007d7d
+.long	0x00e4e4e4,0x39003939
+.long	0x000e0e0e,0x83008383
+.long	0x00737373,0xdc00dcdc
+.long	0x00aaaaaa,0xaa00aaaa
+.long	0x00f1f1f1,0x7c007c7c
+.long	0x00dddddd,0x77007777
+.long	0x00595959,0x56005656
+.long	0x00141414,0x05000505
+.long	0x006c6c6c,0x1b001b1b
+.long	0x00929292,0xa400a4a4
+.long	0x00545454,0x15001515
+.long	0x00d0d0d0,0x34003434
+.long	0x00787878,0x1e001e1e
+.long	0x00707070,0x1c001c1c
+.long	0x00e3e3e3,0xf800f8f8
+.long	0x00494949,0x52005252
+.long	0x00808080,0x20002020
+.long	0x00505050,0x14001414
+.long	0x00a7a7a7,0xe900e9e9
+.long	0x00f6f6f6,0xbd00bdbd
+.long	0x00777777,0xdd00dddd
+.long	0x00939393,0xe400e4e4
+.long	0x00868686,0xa100a1a1
+.long	0x00838383,0xe000e0e0
+.long	0x002a2a2a,0x8a008a8a
+.long	0x00c7c7c7,0xf100f1f1
+.long	0x005b5b5b,0xd600d6d6
+.long	0x00e9e9e9,0x7a007a7a
+.long	0x00eeeeee,0xbb00bbbb
+.long	0x008f8f8f,0xe300e3e3
+.long	0x00010101,0x40004040
+.long	0x003d3d3d,0x4f004f4f
+.globl	Camellia_cbc_encrypt
+.type	Camellia_cbc_encrypt,@function
+.align	16
+Camellia_cbc_encrypt:
+	cmpq	$0,%rdx
+	je	.Lcbc_abort
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+.Lcbc_prologue:
+
+	movq	%rsp,%rbp
+	subq	$64,%rsp
+	andq	$-64,%rsp
+
+
+
+	leaq	-64-63(%rcx),%r10
+	subq	%rsp,%r10
+	negq	%r10
+	andq	$960,%r10
+	subq	%r10,%rsp
+
+
+	movq	%rdi,%r12
+	movq	%rsi,%r13
+	movq	%r8,%rbx
+	movq	%rcx,%r14
+	movl	272(%rcx),%r15d
+
+	movq	%r8,40(%rsp)
+	movq	%rbp,48(%rsp)
+
+.Lcbc_body:
+	leaq	.LCamellia_SBOX(%rip),%rbp
+
+	movl	$32,%ecx
+.align	4
+.Lcbc_prefetch_sbox:
+	movq	0(%rbp),%rax
+	movq	32(%rbp),%rsi
+	movq	64(%rbp),%rdi
+	movq	96(%rbp),%r11
+	leaq	128(%rbp),%rbp
+	loop	.Lcbc_prefetch_sbox
+	subq	$4096,%rbp
+	shlq	$6,%r15
+	movq	%rdx,%rcx
+	leaq	(%r14,%r15,1),%r15
+
+	cmpl	$0,%r9d
+	je	.LCBC_DECRYPT
+
+	andq	$-16,%rdx
+	andq	$15,%rcx
+	leaq	(%r12,%rdx,1),%rdx
+	movq	%r14,0(%rsp)
+	movq	%rdx,8(%rsp)
+	movq	%rcx,16(%rsp)
+
+	cmpq	%r12,%rdx
+	movl	0(%rbx),%r8d
+	movl	4(%rbx),%r9d
+	movl	8(%rbx),%r10d
+	movl	12(%rbx),%r11d
+	je	.Lcbc_enc_tail
+	jmp	.Lcbc_eloop
+
+.align	16
+.Lcbc_eloop:
+	xorl	0(%r12),%r8d
+	xorl	4(%r12),%r9d
+	xorl	8(%r12),%r10d
+	bswapl	%r8d
+	xorl	12(%r12),%r11d
+	bswapl	%r9d
+	bswapl	%r10d
+	bswapl	%r11d
+
+	call	_x86_64_Camellia_encrypt
+
+	movq	0(%rsp),%r14
+	bswapl	%r8d
+	movq	8(%rsp),%rdx
+	bswapl	%r9d
+	movq	16(%rsp),%rcx
+	bswapl	%r10d
+	movl	%r8d,0(%r13)
+	bswapl	%r11d
+	movl	%r9d,4(%r13)
+	movl	%r10d,8(%r13)
+	leaq	16(%r12),%r12
+	movl	%r11d,12(%r13)
+	cmpq	%rdx,%r12
+	leaq	16(%r13),%r13
+	jne	.Lcbc_eloop
+
+	cmpq	$0,%rcx
+	jne	.Lcbc_enc_tail
+
+	movq	40(%rsp),%r13
+	movl	%r8d,0(%r13)
+	movl	%r9d,4(%r13)
+	movl	%r10d,8(%r13)
+	movl	%r11d,12(%r13)
+	jmp	.Lcbc_done
+
+.align	16
+.Lcbc_enc_tail:
+	xorq	%rax,%rax
+	movq	%rax,0+24(%rsp)
+	movq	%rax,8+24(%rsp)
+	movq	%rax,16(%rsp)
+
+.Lcbc_enc_pushf:
+	pushfq
+	cld
+	movq	%r12,%rsi
+	leaq	8+24(%rsp),%rdi
+.long	0x9066A4F3		
+	popfq
+.Lcbc_enc_popf:
+
+	leaq	24(%rsp),%r12
+	leaq	16+24(%rsp),%rax
+	movq	%rax,8(%rsp)
+	jmp	.Lcbc_eloop		
+
+.align	16
+.LCBC_DECRYPT:
+	xchgq	%r14,%r15
+	addq	$15,%rdx
+	andq	$15,%rcx
+	andq	$-16,%rdx
+	movq	%r14,0(%rsp)
+	leaq	(%r12,%rdx,1),%rdx
+	movq	%rdx,8(%rsp)
+	movq	%rcx,16(%rsp)
+
+	movq	(%rbx),%rax
+	movq	8(%rbx),%rbx
+	jmp	.Lcbc_dloop
+.align	16
+.Lcbc_dloop:
+	movl	0(%r12),%r8d
+	movl	4(%r12),%r9d
+	movl	8(%r12),%r10d
+	bswapl	%r8d
+	movl	12(%r12),%r11d
+	bswapl	%r9d
+	movq	%rax,0+24(%rsp)
+	bswapl	%r10d
+	movq	%rbx,8+24(%rsp)
+	bswapl	%r11d
+
+	call	_x86_64_Camellia_decrypt
+
+	movq	0(%rsp),%r14
+	movq	8(%rsp),%rdx
+	movq	16(%rsp),%rcx
+
+	bswapl	%r8d
+	movq	(%r12),%rax
+	bswapl	%r9d
+	movq	8(%r12),%rbx
+	bswapl	%r10d
+	xorl	0+24(%rsp),%r8d
+	bswapl	%r11d
+	xorl	4+24(%rsp),%r9d
+	xorl	8+24(%rsp),%r10d
+	leaq	16(%r12),%r12
+	xorl	12+24(%rsp),%r11d
+	cmpq	%rdx,%r12
+	je	.Lcbc_ddone
+
+	movl	%r8d,0(%r13)
+	movl	%r9d,4(%r13)
+	movl	%r10d,8(%r13)
+	movl	%r11d,12(%r13)
+
+	leaq	16(%r13),%r13
+	jmp	.Lcbc_dloop
+
+.align	16
+.Lcbc_ddone:
+	movq	40(%rsp),%rdx
+	cmpq	$0,%rcx
+	jne	.Lcbc_dec_tail
+
+	movl	%r8d,0(%r13)
+	movl	%r9d,4(%r13)
+	movl	%r10d,8(%r13)
+	movl	%r11d,12(%r13)
+
+	movq	%rax,(%rdx)
+	movq	%rbx,8(%rdx)
+	jmp	.Lcbc_done
+.align	16
+.Lcbc_dec_tail:
+	movl	%r8d,0+24(%rsp)
+	movl	%r9d,4+24(%rsp)
+	movl	%r10d,8+24(%rsp)
+	movl	%r11d,12+24(%rsp)
+
+.Lcbc_dec_pushf:
+	pushfq
+	cld
+	leaq	8+24(%rsp),%rsi
+	leaq	(%r13),%rdi
+.long	0x9066A4F3		
+	popfq
+.Lcbc_dec_popf:
+
+	movq	%rax,(%rdx)
+	movq	%rbx,8(%rdx)
+	jmp	.Lcbc_done
+
+.align	16
+.Lcbc_done:
+	movq	48(%rsp),%rcx
+	movq	0(%rcx),%r15
+	movq	8(%rcx),%r14
+	movq	16(%rcx),%r13
+	movq	24(%rcx),%r12
+	movq	32(%rcx),%rbp
+	movq	40(%rcx),%rbx
+	leaq	48(%rcx),%rsp
+.Lcbc_abort:
+	.byte	0xf3,0xc3
+.size	Camellia_cbc_encrypt,.-Camellia_cbc_encrypt
+
+.byte	67,97,109,101,108,108,105,97,32,102,111,114,32,120,56,54,95,54,52,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+#if defined(HAVE_GNU_STACK)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/crypto/libressl/crypto/camellia/cmll-macosx-x86_64.s b/crypto/libressl/crypto/camellia/cmll-macosx-x86_64.s
new file mode 100644
index 0000000000..a55a34c82b
--- /dev/null
+++ b/crypto/libressl/crypto/camellia/cmll-macosx-x86_64.s
@@ -0,0 +1,1838 @@
+.text	
+
+
+.globl	_Camellia_EncryptBlock
+
+.p2align	4
+_Camellia_EncryptBlock:
+	movl	$128,%eax
+	subl	%edi,%eax
+	movl	$3,%edi
+	adcl	$0,%edi
+	jmp	L$enc_rounds
+
+
+.globl	_Camellia_EncryptBlock_Rounds
+
+.p2align	4
+L$enc_rounds:
+_Camellia_EncryptBlock_Rounds:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+L$enc_prologue:
+
+
+	movq	%rcx,%r13
+	movq	%rdx,%r14
+
+	shll	$6,%edi
+	leaq	L$Camellia_SBOX(%rip),%rbp
+	leaq	(%r14,%rdi,1),%r15
+
+	movl	0(%rsi),%r8d
+	movl	4(%rsi),%r9d
+	movl	8(%rsi),%r10d
+	bswapl	%r8d
+	movl	12(%rsi),%r11d
+	bswapl	%r9d
+	bswapl	%r10d
+	bswapl	%r11d
+
+	call	_x86_64_Camellia_encrypt
+
+	bswapl	%r8d
+	bswapl	%r9d
+	bswapl	%r10d
+	movl	%r8d,0(%r13)
+	bswapl	%r11d
+	movl	%r9d,4(%r13)
+	movl	%r10d,8(%r13)
+	movl	%r11d,12(%r13)
+
+	movq	0(%rsp),%r15
+	movq	8(%rsp),%r14
+	movq	16(%rsp),%r13
+	movq	24(%rsp),%rbp
+	movq	32(%rsp),%rbx
+	leaq	40(%rsp),%rsp
+L$enc_epilogue:
+	.byte	0xf3,0xc3
+
+
+
+.p2align	4
+_x86_64_Camellia_encrypt:
+	xorl	0(%r14),%r9d
+	xorl	4(%r14),%r8d
+	xorl	8(%r14),%r11d
+	xorl	12(%r14),%r10d
+.p2align	4
+L$eloop:
+	movl	16(%r14),%ebx
+	movl	20(%r14),%eax
+
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	24(%r14),%ebx
+	movl	28(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r10d
+	xorl	%ecx,%r11d
+	xorl	%edx,%r11d
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	32(%r14),%ebx
+	movl	36(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r8d
+	xorl	%ecx,%r9d
+	xorl	%edx,%r9d
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	40(%r14),%ebx
+	movl	44(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r10d
+	xorl	%ecx,%r11d
+	xorl	%edx,%r11d
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	48(%r14),%ebx
+	movl	52(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r8d
+	xorl	%ecx,%r9d
+	xorl	%edx,%r9d
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	56(%r14),%ebx
+	movl	60(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r10d
+	xorl	%ecx,%r11d
+	xorl	%edx,%r11d
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	64(%r14),%ebx
+	movl	68(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r8d
+	xorl	%ecx,%r9d
+	xorl	%edx,%r9d
+	leaq	64(%r14),%r14
+	cmpq	%r15,%r14
+	movl	8(%r14),%edx
+	movl	12(%r14),%ecx
+	je	L$edone
+
+	andl	%r8d,%eax
+	orl	%r11d,%edx
+	roll	$1,%eax
+	xorl	%edx,%r10d
+	xorl	%eax,%r9d
+	andl	%r10d,%ecx
+	orl	%r9d,%ebx
+	roll	$1,%ecx
+	xorl	%ebx,%r8d
+	xorl	%ecx,%r11d
+	jmp	L$eloop
+
+.p2align	4
+L$edone:
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	xorl	%r8d,%ecx
+	xorl	%r9d,%edx
+
+	movl	%eax,%r8d
+	movl	%ebx,%r9d
+	movl	%ecx,%r10d
+	movl	%edx,%r11d
+
+.byte	0xf3,0xc3		
+
+
+
+.globl	_Camellia_DecryptBlock
+
+.p2align	4
+_Camellia_DecryptBlock:
+	movl	$128,%eax
+	subl	%edi,%eax
+	movl	$3,%edi
+	adcl	$0,%edi
+	jmp	L$dec_rounds
+
+
+.globl	_Camellia_DecryptBlock_Rounds
+
+.p2align	4
+L$dec_rounds:
+_Camellia_DecryptBlock_Rounds:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+L$dec_prologue:
+
+
+	movq	%rcx,%r13
+	movq	%rdx,%r15
+
+	shll	$6,%edi
+	leaq	L$Camellia_SBOX(%rip),%rbp
+	leaq	(%r15,%rdi,1),%r14
+
+	movl	0(%rsi),%r8d
+	movl	4(%rsi),%r9d
+	movl	8(%rsi),%r10d
+	bswapl	%r8d
+	movl	12(%rsi),%r11d
+	bswapl	%r9d
+	bswapl	%r10d
+	bswapl	%r11d
+
+	call	_x86_64_Camellia_decrypt
+
+	bswapl	%r8d
+	bswapl	%r9d
+	bswapl	%r10d
+	movl	%r8d,0(%r13)
+	bswapl	%r11d
+	movl	%r9d,4(%r13)
+	movl	%r10d,8(%r13)
+	movl	%r11d,12(%r13)
+
+	movq	0(%rsp),%r15
+	movq	8(%rsp),%r14
+	movq	16(%rsp),%r13
+	movq	24(%rsp),%rbp
+	movq	32(%rsp),%rbx
+	leaq	40(%rsp),%rsp
+L$dec_epilogue:
+	.byte	0xf3,0xc3
+
+
+
+.p2align	4
+_x86_64_Camellia_decrypt:
+	xorl	0(%r14),%r9d
+	xorl	4(%r14),%r8d
+	xorl	8(%r14),%r11d
+	xorl	12(%r14),%r10d
+.p2align	4
+L$dloop:
+	movl	-8(%r14),%ebx
+	movl	-4(%r14),%eax
+
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	-16(%r14),%ebx
+	movl	-12(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r10d
+	xorl	%ecx,%r11d
+	xorl	%edx,%r11d
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	-24(%r14),%ebx
+	movl	-20(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r8d
+	xorl	%ecx,%r9d
+	xorl	%edx,%r9d
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	-32(%r14),%ebx
+	movl	-28(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r10d
+	xorl	%ecx,%r11d
+	xorl	%edx,%r11d
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	-40(%r14),%ebx
+	movl	-36(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r8d
+	xorl	%ecx,%r9d
+	xorl	%edx,%r9d
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	-48(%r14),%ebx
+	movl	-44(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r10d
+	xorl	%ecx,%r11d
+	xorl	%edx,%r11d
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	-56(%r14),%ebx
+	movl	-52(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r8d
+	xorl	%ecx,%r9d
+	xorl	%edx,%r9d
+	leaq	-64(%r14),%r14
+	cmpq	%r15,%r14
+	movl	0(%r14),%edx
+	movl	4(%r14),%ecx
+	je	L$ddone
+
+	andl	%r8d,%eax
+	orl	%r11d,%edx
+	roll	$1,%eax
+	xorl	%edx,%r10d
+	xorl	%eax,%r9d
+	andl	%r10d,%ecx
+	orl	%r9d,%ebx
+	roll	$1,%ecx
+	xorl	%ebx,%r8d
+	xorl	%ecx,%r11d
+
+	jmp	L$dloop
+
+.p2align	4
+L$ddone:
+	xorl	%r10d,%ecx
+	xorl	%r11d,%edx
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+
+	movl	%ecx,%r8d
+	movl	%edx,%r9d
+	movl	%eax,%r10d
+	movl	%ebx,%r11d
+
+.byte	0xf3,0xc3		
+
+.globl	_Camellia_Ekeygen
+
+.p2align	4
+_Camellia_Ekeygen:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+L$key_prologue:
+
+	movq	%rdi,%r15
+	movq	%rdx,%r13
+
+	movl	0(%rsi),%r8d
+	movl	4(%rsi),%r9d
+	movl	8(%rsi),%r10d
+	movl	12(%rsi),%r11d
+
+	bswapl	%r8d
+	bswapl	%r9d
+	bswapl	%r10d
+	bswapl	%r11d
+	movl	%r9d,0(%r13)
+	movl	%r8d,4(%r13)
+	movl	%r11d,8(%r13)
+	movl	%r10d,12(%r13)
+	cmpq	$128,%r15
+	je	L$1st128
+
+	movl	16(%rsi),%r8d
+	movl	20(%rsi),%r9d
+	cmpq	$192,%r15
+	je	L$1st192
+	movl	24(%rsi),%r10d
+	movl	28(%rsi),%r11d
+	jmp	L$1st256
+L$1st192:
+	movl	%r8d,%r10d
+	movl	%r9d,%r11d
+	notl	%r10d
+	notl	%r11d
+L$1st256:
+	bswapl	%r8d
+	bswapl	%r9d
+	bswapl	%r10d
+	bswapl	%r11d
+	movl	%r9d,32(%r13)
+	movl	%r8d,36(%r13)
+	movl	%r11d,40(%r13)
+	movl	%r10d,44(%r13)
+	xorl	0(%r13),%r9d
+	xorl	4(%r13),%r8d
+	xorl	8(%r13),%r11d
+	xorl	12(%r13),%r10d
+
+L$1st128:
+	leaq	L$Camellia_SIGMA(%rip),%r14
+	leaq	L$Camellia_SBOX(%rip),%rbp
+
+	movl	0(%r14),%ebx
+	movl	4(%r14),%eax
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	8(%r14),%ebx
+	movl	12(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r10d
+	xorl	%ecx,%r11d
+	xorl	%edx,%r11d
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	16(%r14),%ebx
+	movl	20(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r8d
+	xorl	%ecx,%r9d
+	xorl	%edx,%r9d
+	xorl	0(%r13),%r9d
+	xorl	4(%r13),%r8d
+	xorl	8(%r13),%r11d
+	xorl	12(%r13),%r10d
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	24(%r14),%ebx
+	movl	28(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r10d
+	xorl	%ecx,%r11d
+	xorl	%edx,%r11d
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	32(%r14),%ebx
+	movl	36(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r8d
+	xorl	%ecx,%r9d
+	xorl	%edx,%r9d
+	cmpq	$128,%r15
+	jne	L$2nd256
+
+	leaq	128(%r13),%r13
+	shlq	$32,%r8
+	shlq	$32,%r10
+	orq	%r9,%r8
+	orq	%r11,%r10
+	movq	-128(%r13),%rax
+	movq	-120(%r13),%rbx
+	movq	%r8,-112(%r13)
+	movq	%r10,-104(%r13)
+	movq	%rax,%r11
+	shlq	$15,%rax
+	movq	%rbx,%r9
+	shrq	$49,%r9
+	shrq	$49,%r11
+	orq	%r9,%rax
+	shlq	$15,%rbx
+	orq	%r11,%rbx
+	movq	%rax,-96(%r13)
+	movq	%rbx,-88(%r13)
+	movq	%r8,%r11
+	shlq	$15,%r8
+	movq	%r10,%r9
+	shrq	$49,%r9
+	shrq	$49,%r11
+	orq	%r9,%r8
+	shlq	$15,%r10
+	orq	%r11,%r10
+	movq	%r8,-80(%r13)
+	movq	%r10,-72(%r13)
+	movq	%r8,%r11
+	shlq	$15,%r8
+	movq	%r10,%r9
+	shrq	$49,%r9
+	shrq	$49,%r11
+	orq	%r9,%r8
+	shlq	$15,%r10
+	orq	%r11,%r10
+	movq	%r8,-64(%r13)
+	movq	%r10,-56(%r13)
+	movq	%rax,%r11
+	shlq	$30,%rax
+	movq	%rbx,%r9
+	shrq	$34,%r9
+	shrq	$34,%r11
+	orq	%r9,%rax
+	shlq	$30,%rbx
+	orq	%r11,%rbx
+	movq	%rax,-48(%r13)
+	movq	%rbx,-40(%r13)
+	movq	%r8,%r11
+	shlq	$15,%r8
+	movq	%r10,%r9
+	shrq	$49,%r9
+	shrq	$49,%r11
+	orq	%r9,%r8
+	shlq	$15,%r10
+	orq	%r11,%r10
+	movq	%r8,-32(%r13)
+	movq	%rax,%r11
+	shlq	$15,%rax
+	movq	%rbx,%r9
+	shrq	$49,%r9
+	shrq	$49,%r11
+	orq	%r9,%rax
+	shlq	$15,%rbx
+	orq	%r11,%rbx
+	movq	%rbx,-24(%r13)
+	movq	%r8,%r11
+	shlq	$15,%r8
+	movq	%r10,%r9
+	shrq	$49,%r9
+	shrq	$49,%r11
+	orq	%r9,%r8
+	shlq	$15,%r10
+	orq	%r11,%r10
+	movq	%r8,-16(%r13)
+	movq	%r10,-8(%r13)
+	movq	%rax,%r11
+	shlq	$17,%rax
+	movq	%rbx,%r9
+	shrq	$47,%r9
+	shrq	$47,%r11
+	orq	%r9,%rax
+	shlq	$17,%rbx
+	orq	%r11,%rbx
+	movq	%rax,0(%r13)
+	movq	%rbx,8(%r13)
+	movq	%rax,%r11
+	shlq	$17,%rax
+	movq	%rbx,%r9
+	shrq	$47,%r9
+	shrq	$47,%r11
+	orq	%r9,%rax
+	shlq	$17,%rbx
+	orq	%r11,%rbx
+	movq	%rax,16(%r13)
+	movq	%rbx,24(%r13)
+	movq	%r8,%r11
+	shlq	$34,%r8
+	movq	%r10,%r9
+	shrq	$30,%r9
+	shrq	$30,%r11
+	orq	%r9,%r8
+	shlq	$34,%r10
+	orq	%r11,%r10
+	movq	%r8,32(%r13)
+	movq	%r10,40(%r13)
+	movq	%rax,%r11
+	shlq	$17,%rax
+	movq	%rbx,%r9
+	shrq	$47,%r9
+	shrq	$47,%r11
+	orq	%r9,%rax
+	shlq	$17,%rbx
+	orq	%r11,%rbx
+	movq	%rax,48(%r13)
+	movq	%rbx,56(%r13)
+	movq	%r8,%r11
+	shlq	$17,%r8
+	movq	%r10,%r9
+	shrq	$47,%r9
+	shrq	$47,%r11
+	orq	%r9,%r8
+	shlq	$17,%r10
+	orq	%r11,%r10
+	movq	%r8,64(%r13)
+	movq	%r10,72(%r13)
+	movl	$3,%eax
+	jmp	L$done
+.p2align	4
+L$2nd256:
+	movl	%r9d,48(%r13)
+	movl	%r8d,52(%r13)
+	movl	%r11d,56(%r13)
+	movl	%r10d,60(%r13)
+	xorl	32(%r13),%r9d
+	xorl	36(%r13),%r8d
+	xorl	40(%r13),%r11d
+	xorl	44(%r13),%r10d
+	xorl	%r8d,%eax
+	xorl	%r9d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	40(%r14),%ebx
+	movl	44(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r10d
+	xorl	%ecx,%r11d
+	xorl	%edx,%r11d
+	xorl	%r10d,%eax
+	xorl	%r11d,%ebx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	movl	2052(%rbp,%rsi,8),%edx
+	movl	0(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	shrl	$16,%eax
+	movzbl	%bh,%edi
+	xorl	4(%rbp,%rsi,8),%edx
+	shrl	$16,%ebx
+	xorl	4(%rbp,%rdi,8),%ecx
+	movzbl	%ah,%esi
+	movzbl	%bl,%edi
+	xorl	0(%rbp,%rsi,8),%edx
+	xorl	2052(%rbp,%rdi,8),%ecx
+	movzbl	%al,%esi
+	movzbl	%bh,%edi
+	xorl	2048(%rbp,%rsi,8),%edx
+	xorl	2048(%rbp,%rdi,8),%ecx
+	movl	48(%r14),%ebx
+	movl	52(%r14),%eax
+	xorl	%edx,%ecx
+	rorl	$8,%edx
+	xorl	%ecx,%r8d
+	xorl	%ecx,%r9d
+	xorl	%edx,%r9d
+	movq	0(%r13),%rax
+	movq	8(%r13),%rbx
+	movq	32(%r13),%rcx
+	movq	40(%r13),%rdx
+	movq	48(%r13),%r14
+	movq	56(%r13),%r15
+	leaq	128(%r13),%r13
+	shlq	$32,%r8
+	shlq	$32,%r10
+	orq	%r9,%r8
+	orq	%r11,%r10
+	movq	%r8,-112(%r13)
+	movq	%r10,-104(%r13)
+	movq	%rcx,%r11
+	shlq	$15,%rcx
+	movq	%rdx,%r9
+	shrq	$49,%r9
+	shrq	$49,%r11
+	orq	%r9,%rcx
+	shlq	$15,%rdx
+	orq	%r11,%rdx
+	movq	%rcx,-96(%r13)
+	movq	%rdx,-88(%r13)
+	movq	%r14,%r11
+	shlq	$15,%r14
+	movq	%r15,%r9
+	shrq	$49,%r9
+	shrq	$49,%r11
+	orq	%r9,%r14
+	shlq	$15,%r15
+	orq	%r11,%r15
+	movq	%r14,-80(%r13)
+	movq	%r15,-72(%r13)
+	movq	%rcx,%r11
+	shlq	$15,%rcx
+	movq	%rdx,%r9
+	shrq	$49,%r9
+	shrq	$49,%r11
+	orq	%r9,%rcx
+	shlq	$15,%rdx
+	orq	%r11,%rdx
+	movq	%rcx,-64(%r13)
+	movq	%rdx,-56(%r13)
+	movq	%r8,%r11
+	shlq	$30,%r8
+	movq	%r10,%r9
+	shrq	$34,%r9
+	shrq	$34,%r11
+	orq	%r9,%r8
+	shlq	$30,%r10
+	orq	%r11,%r10
+	movq	%r8,-48(%r13)
+	movq	%r10,-40(%r13)
+	movq	%rax,%r11
+	shlq	$45,%rax
+	movq	%rbx,%r9
+	shrq	$19,%r9
+	shrq	$19,%r11
+	orq	%r9,%rax
+	shlq	$45,%rbx
+	orq	%r11,%rbx
+	movq	%rax,-32(%r13)
+	movq	%rbx,-24(%r13)
+	movq	%r14,%r11
+	shlq	$30,%r14
+	movq	%r15,%r9
+	shrq	$34,%r9
+	shrq	$34,%r11
+	orq	%r9,%r14
+	shlq	$30,%r15
+	orq	%r11,%r15
+	movq	%r14,-16(%r13)
+	movq	%r15,-8(%r13)
+	movq	%rax,%r11
+	shlq	$15,%rax
+	movq	%rbx,%r9
+	shrq	$49,%r9
+	shrq	$49,%r11
+	orq	%r9,%rax
+	shlq	$15,%rbx
+	orq	%r11,%rbx
+	movq	%rax,0(%r13)
+	movq	%rbx,8(%r13)
+	movq	%rcx,%r11
+	shlq	$30,%rcx
+	movq	%rdx,%r9
+	shrq	$34,%r9
+	shrq	$34,%r11
+	orq	%r9,%rcx
+	shlq	$30,%rdx
+	orq	%r11,%rdx
+	movq	%rcx,16(%r13)
+	movq	%rdx,24(%r13)
+	movq	%r8,%r11
+	shlq	$30,%r8
+	movq	%r10,%r9
+	shrq	$34,%r9
+	shrq	$34,%r11
+	orq	%r9,%r8
+	shlq	$30,%r10
+	orq	%r11,%r10
+	movq	%r8,32(%r13)
+	movq	%r10,40(%r13)
+	movq	%rax,%r11
+	shlq	$17,%rax
+	movq	%rbx,%r9
+	shrq	$47,%r9
+	shrq	$47,%r11
+	orq	%r9,%rax
+	shlq	$17,%rbx
+	orq	%r11,%rbx
+	movq	%rax,48(%r13)
+	movq	%rbx,56(%r13)
+	movq	%r14,%r11
+	shlq	$32,%r14
+	movq	%r15,%r9
+	shrq	$32,%r9
+	shrq	$32,%r11
+	orq	%r9,%r14
+	shlq	$32,%r15
+	orq	%r11,%r15
+	movq	%r14,64(%r13)
+	movq	%r15,72(%r13)
+	movq	%rcx,%r11
+	shlq	$34,%rcx
+	movq	%rdx,%r9
+	shrq	$30,%r9
+	shrq	$30,%r11
+	orq	%r9,%rcx
+	shlq	$34,%rdx
+	orq	%r11,%rdx
+	movq	%rcx,80(%r13)
+	movq	%rdx,88(%r13)
+	movq	%r14,%r11
+	shlq	$17,%r14
+	movq	%r15,%r9
+	shrq	$47,%r9
+	shrq	$47,%r11
+	orq	%r9,%r14
+	shlq	$17,%r15
+	orq	%r11,%r15
+	movq	%r14,96(%r13)
+	movq	%r15,104(%r13)
+	movq	%rax,%r11
+	shlq	$34,%rax
+	movq	%rbx,%r9
+	shrq	$30,%r9
+	shrq	$30,%r11
+	orq	%r9,%rax
+	shlq	$34,%rbx
+	orq	%r11,%rbx
+	movq	%rax,112(%r13)
+	movq	%rbx,120(%r13)
+	movq	%r8,%r11
+	shlq	$51,%r8
+	movq	%r10,%r9
+	shrq	$13,%r9
+	shrq	$13,%r11
+	orq	%r9,%r8
+	shlq	$51,%r10
+	orq	%r11,%r10
+	movq	%r8,128(%r13)
+	movq	%r10,136(%r13)
+	movl	$4,%eax
+L$done:
+	movq	0(%rsp),%r15
+	movq	8(%rsp),%r14
+	movq	16(%rsp),%r13
+	movq	24(%rsp),%rbp
+	movq	32(%rsp),%rbx
+	leaq	40(%rsp),%rsp
+L$key_epilogue:
+	.byte	0xf3,0xc3
+
+.p2align	6
+L$Camellia_SIGMA:
+.long	0x3bcc908b, 0xa09e667f, 0x4caa73b2, 0xb67ae858
+.long	0xe94f82be, 0xc6ef372f, 0xf1d36f1c, 0x54ff53a5
+.long	0xde682d1d, 0x10e527fa, 0xb3e6c1fd, 0xb05688c2
+.long	0,          0,          0,          0
+L$Camellia_SBOX:
+.long	0x70707000,0x70700070
+.long	0x82828200,0x2c2c002c
+.long	0x2c2c2c00,0xb3b300b3
+.long	0xececec00,0xc0c000c0
+.long	0xb3b3b300,0xe4e400e4
+.long	0x27272700,0x57570057
+.long	0xc0c0c000,0xeaea00ea
+.long	0xe5e5e500,0xaeae00ae
+.long	0xe4e4e400,0x23230023
+.long	0x85858500,0x6b6b006b
+.long	0x57575700,0x45450045
+.long	0x35353500,0xa5a500a5
+.long	0xeaeaea00,0xeded00ed
+.long	0x0c0c0c00,0x4f4f004f
+.long	0xaeaeae00,0x1d1d001d
+.long	0x41414100,0x92920092
+.long	0x23232300,0x86860086
+.long	0xefefef00,0xafaf00af
+.long	0x6b6b6b00,0x7c7c007c
+.long	0x93939300,0x1f1f001f
+.long	0x45454500,0x3e3e003e
+.long	0x19191900,0xdcdc00dc
+.long	0xa5a5a500,0x5e5e005e
+.long	0x21212100,0x0b0b000b
+.long	0xededed00,0xa6a600a6
+.long	0x0e0e0e00,0x39390039
+.long	0x4f4f4f00,0xd5d500d5
+.long	0x4e4e4e00,0x5d5d005d
+.long	0x1d1d1d00,0xd9d900d9
+.long	0x65656500,0x5a5a005a
+.long	0x92929200,0x51510051
+.long	0xbdbdbd00,0x6c6c006c
+.long	0x86868600,0x8b8b008b
+.long	0xb8b8b800,0x9a9a009a
+.long	0xafafaf00,0xfbfb00fb
+.long	0x8f8f8f00,0xb0b000b0
+.long	0x7c7c7c00,0x74740074
+.long	0xebebeb00,0x2b2b002b
+.long	0x1f1f1f00,0xf0f000f0
+.long	0xcecece00,0x84840084
+.long	0x3e3e3e00,0xdfdf00df
+.long	0x30303000,0xcbcb00cb
+.long	0xdcdcdc00,0x34340034
+.long	0x5f5f5f00,0x76760076
+.long	0x5e5e5e00,0x6d6d006d
+.long	0xc5c5c500,0xa9a900a9
+.long	0x0b0b0b00,0xd1d100d1
+.long	0x1a1a1a00,0x04040004
+.long	0xa6a6a600,0x14140014
+.long	0xe1e1e100,0x3a3a003a
+.long	0x39393900,0xdede00de
+.long	0xcacaca00,0x11110011
+.long	0xd5d5d500,0x32320032
+.long	0x47474700,0x9c9c009c
+.long	0x5d5d5d00,0x53530053
+.long	0x3d3d3d00,0xf2f200f2
+.long	0xd9d9d900,0xfefe00fe
+.long	0x01010100,0xcfcf00cf
+.long	0x5a5a5a00,0xc3c300c3
+.long	0xd6d6d600,0x7a7a007a
+.long	0x51515100,0x24240024
+.long	0x56565600,0xe8e800e8
+.long	0x6c6c6c00,0x60600060
+.long	0x4d4d4d00,0x69690069
+.long	0x8b8b8b00,0xaaaa00aa
+.long	0x0d0d0d00,0xa0a000a0
+.long	0x9a9a9a00,0xa1a100a1
+.long	0x66666600,0x62620062
+.long	0xfbfbfb00,0x54540054
+.long	0xcccccc00,0x1e1e001e
+.long	0xb0b0b000,0xe0e000e0
+.long	0x2d2d2d00,0x64640064
+.long	0x74747400,0x10100010
+.long	0x12121200,0x00000000
+.long	0x2b2b2b00,0xa3a300a3
+.long	0x20202000,0x75750075
+.long	0xf0f0f000,0x8a8a008a
+.long	0xb1b1b100,0xe6e600e6
+.long	0x84848400,0x09090009
+.long	0x99999900,0xdddd00dd
+.long	0xdfdfdf00,0x87870087
+.long	0x4c4c4c00,0x83830083
+.long	0xcbcbcb00,0xcdcd00cd
+.long	0xc2c2c200,0x90900090
+.long	0x34343400,0x73730073
+.long	0x7e7e7e00,0xf6f600f6
+.long	0x76767600,0x9d9d009d
+.long	0x05050500,0xbfbf00bf
+.long	0x6d6d6d00,0x52520052
+.long	0xb7b7b700,0xd8d800d8
+.long	0xa9a9a900,0xc8c800c8
+.long	0x31313100,0xc6c600c6
+.long	0xd1d1d100,0x81810081
+.long	0x17171700,0x6f6f006f
+.long	0x04040400,0x13130013
+.long	0xd7d7d700,0x63630063
+.long	0x14141400,0xe9e900e9
+.long	0x58585800,0xa7a700a7
+.long	0x3a3a3a00,0x9f9f009f
+.long	0x61616100,0xbcbc00bc
+.long	0xdedede00,0x29290029
+.long	0x1b1b1b00,0xf9f900f9
+.long	0x11111100,0x2f2f002f
+.long	0x1c1c1c00,0xb4b400b4
+.long	0x32323200,0x78780078
+.long	0x0f0f0f00,0x06060006
+.long	0x9c9c9c00,0xe7e700e7
+.long	0x16161600,0x71710071
+.long	0x53535300,0xd4d400d4
+.long	0x18181800,0xabab00ab
+.long	0xf2f2f200,0x88880088
+.long	0x22222200,0x8d8d008d
+.long	0xfefefe00,0x72720072
+.long	0x44444400,0xb9b900b9
+.long	0xcfcfcf00,0xf8f800f8
+.long	0xb2b2b200,0xacac00ac
+.long	0xc3c3c300,0x36360036
+.long	0xb5b5b500,0x2a2a002a
+.long	0x7a7a7a00,0x3c3c003c
+.long	0x91919100,0xf1f100f1
+.long	0x24242400,0x40400040
+.long	0x08080800,0xd3d300d3
+.long	0xe8e8e800,0xbbbb00bb
+.long	0xa8a8a800,0x43430043
+.long	0x60606000,0x15150015
+.long	0xfcfcfc00,0xadad00ad
+.long	0x69696900,0x77770077
+.long	0x50505000,0x80800080
+.long	0xaaaaaa00,0x82820082
+.long	0xd0d0d000,0xecec00ec
+.long	0xa0a0a000,0x27270027
+.long	0x7d7d7d00,0xe5e500e5
+.long	0xa1a1a100,0x85850085
+.long	0x89898900,0x35350035
+.long	0x62626200,0x0c0c000c
+.long	0x97979700,0x41410041
+.long	0x54545400,0xefef00ef
+.long	0x5b5b5b00,0x93930093
+.long	0x1e1e1e00,0x19190019
+.long	0x95959500,0x21210021
+.long	0xe0e0e000,0x0e0e000e
+.long	0xffffff00,0x4e4e004e
+.long	0x64646400,0x65650065
+.long	0xd2d2d200,0xbdbd00bd
+.long	0x10101000,0xb8b800b8
+.long	0xc4c4c400,0x8f8f008f
+.long	0x00000000,0xebeb00eb
+.long	0x48484800,0xcece00ce
+.long	0xa3a3a300,0x30300030
+.long	0xf7f7f700,0x5f5f005f
+.long	0x75757500,0xc5c500c5
+.long	0xdbdbdb00,0x1a1a001a
+.long	0x8a8a8a00,0xe1e100e1
+.long	0x03030300,0xcaca00ca
+.long	0xe6e6e600,0x47470047
+.long	0xdadada00,0x3d3d003d
+.long	0x09090900,0x01010001
+.long	0x3f3f3f00,0xd6d600d6
+.long	0xdddddd00,0x56560056
+.long	0x94949400,0x4d4d004d
+.long	0x87878700,0x0d0d000d
+.long	0x5c5c5c00,0x66660066
+.long	0x83838300,0xcccc00cc
+.long	0x02020200,0x2d2d002d
+.long	0xcdcdcd00,0x12120012
+.long	0x4a4a4a00,0x20200020
+.long	0x90909000,0xb1b100b1
+.long	0x33333300,0x99990099
+.long	0x73737300,0x4c4c004c
+.long	0x67676700,0xc2c200c2
+.long	0xf6f6f600,0x7e7e007e
+.long	0xf3f3f300,0x05050005
+.long	0x9d9d9d00,0xb7b700b7
+.long	0x7f7f7f00,0x31310031
+.long	0xbfbfbf00,0x17170017
+.long	0xe2e2e200,0xd7d700d7
+.long	0x52525200,0x58580058
+.long	0x9b9b9b00,0x61610061
+.long	0xd8d8d800,0x1b1b001b
+.long	0x26262600,0x1c1c001c
+.long	0xc8c8c800,0x0f0f000f
+.long	0x37373700,0x16160016
+.long	0xc6c6c600,0x18180018
+.long	0x3b3b3b00,0x22220022
+.long	0x81818100,0x44440044
+.long	0x96969600,0xb2b200b2
+.long	0x6f6f6f00,0xb5b500b5
+.long	0x4b4b4b00,0x91910091
+.long	0x13131300,0x08080008
+.long	0xbebebe00,0xa8a800a8
+.long	0x63636300,0xfcfc00fc
+.long	0x2e2e2e00,0x50500050
+.long	0xe9e9e900,0xd0d000d0
+.long	0x79797900,0x7d7d007d
+.long	0xa7a7a700,0x89890089
+.long	0x8c8c8c00,0x97970097
+.long	0x9f9f9f00,0x5b5b005b
+.long	0x6e6e6e00,0x95950095
+.long	0xbcbcbc00,0xffff00ff
+.long	0x8e8e8e00,0xd2d200d2
+.long	0x29292900,0xc4c400c4
+.long	0xf5f5f500,0x48480048
+.long	0xf9f9f900,0xf7f700f7
+.long	0xb6b6b600,0xdbdb00db
+.long	0x2f2f2f00,0x03030003
+.long	0xfdfdfd00,0xdada00da
+.long	0xb4b4b400,0x3f3f003f
+.long	0x59595900,0x94940094
+.long	0x78787800,0x5c5c005c
+.long	0x98989800,0x02020002
+.long	0x06060600,0x4a4a004a
+.long	0x6a6a6a00,0x33330033
+.long	0xe7e7e700,0x67670067
+.long	0x46464600,0xf3f300f3
+.long	0x71717100,0x7f7f007f
+.long	0xbababa00,0xe2e200e2
+.long	0xd4d4d400,0x9b9b009b
+.long	0x25252500,0x26260026
+.long	0xababab00,0x37370037
+.long	0x42424200,0x3b3b003b
+.long	0x88888800,0x96960096
+.long	0xa2a2a200,0x4b4b004b
+.long	0x8d8d8d00,0xbebe00be
+.long	0xfafafa00,0x2e2e002e
+.long	0x72727200,0x79790079
+.long	0x07070700,0x8c8c008c
+.long	0xb9b9b900,0x6e6e006e
+.long	0x55555500,0x8e8e008e
+.long	0xf8f8f800,0xf5f500f5
+.long	0xeeeeee00,0xb6b600b6
+.long	0xacacac00,0xfdfd00fd
+.long	0x0a0a0a00,0x59590059
+.long	0x36363600,0x98980098
+.long	0x49494900,0x6a6a006a
+.long	0x2a2a2a00,0x46460046
+.long	0x68686800,0xbaba00ba
+.long	0x3c3c3c00,0x25250025
+.long	0x38383800,0x42420042
+.long	0xf1f1f100,0xa2a200a2
+.long	0xa4a4a400,0xfafa00fa
+.long	0x40404000,0x07070007
+.long	0x28282800,0x55550055
+.long	0xd3d3d300,0xeeee00ee
+.long	0x7b7b7b00,0x0a0a000a
+.long	0xbbbbbb00,0x49490049
+.long	0xc9c9c900,0x68680068
+.long	0x43434300,0x38380038
+.long	0xc1c1c100,0xa4a400a4
+.long	0x15151500,0x28280028
+.long	0xe3e3e300,0x7b7b007b
+.long	0xadadad00,0xc9c900c9
+.long	0xf4f4f400,0xc1c100c1
+.long	0x77777700,0xe3e300e3
+.long	0xc7c7c700,0xf4f400f4
+.long	0x80808000,0xc7c700c7
+.long	0x9e9e9e00,0x9e9e009e
+.long	0x00e0e0e0,0x38003838
+.long	0x00050505,0x41004141
+.long	0x00585858,0x16001616
+.long	0x00d9d9d9,0x76007676
+.long	0x00676767,0xd900d9d9
+.long	0x004e4e4e,0x93009393
+.long	0x00818181,0x60006060
+.long	0x00cbcbcb,0xf200f2f2
+.long	0x00c9c9c9,0x72007272
+.long	0x000b0b0b,0xc200c2c2
+.long	0x00aeaeae,0xab00abab
+.long	0x006a6a6a,0x9a009a9a
+.long	0x00d5d5d5,0x75007575
+.long	0x00181818,0x06000606
+.long	0x005d5d5d,0x57005757
+.long	0x00828282,0xa000a0a0
+.long	0x00464646,0x91009191
+.long	0x00dfdfdf,0xf700f7f7
+.long	0x00d6d6d6,0xb500b5b5
+.long	0x00272727,0xc900c9c9
+.long	0x008a8a8a,0xa200a2a2
+.long	0x00323232,0x8c008c8c
+.long	0x004b4b4b,0xd200d2d2
+.long	0x00424242,0x90009090
+.long	0x00dbdbdb,0xf600f6f6
+.long	0x001c1c1c,0x07000707
+.long	0x009e9e9e,0xa700a7a7
+.long	0x009c9c9c,0x27002727
+.long	0x003a3a3a,0x8e008e8e
+.long	0x00cacaca,0xb200b2b2
+.long	0x00252525,0x49004949
+.long	0x007b7b7b,0xde00dede
+.long	0x000d0d0d,0x43004343
+.long	0x00717171,0x5c005c5c
+.long	0x005f5f5f,0xd700d7d7
+.long	0x001f1f1f,0xc700c7c7
+.long	0x00f8f8f8,0x3e003e3e
+.long	0x00d7d7d7,0xf500f5f5
+.long	0x003e3e3e,0x8f008f8f
+.long	0x009d9d9d,0x67006767
+.long	0x007c7c7c,0x1f001f1f
+.long	0x00606060,0x18001818
+.long	0x00b9b9b9,0x6e006e6e
+.long	0x00bebebe,0xaf00afaf
+.long	0x00bcbcbc,0x2f002f2f
+.long	0x008b8b8b,0xe200e2e2
+.long	0x00161616,0x85008585
+.long	0x00343434,0x0d000d0d
+.long	0x004d4d4d,0x53005353
+.long	0x00c3c3c3,0xf000f0f0
+.long	0x00727272,0x9c009c9c
+.long	0x00959595,0x65006565
+.long	0x00ababab,0xea00eaea
+.long	0x008e8e8e,0xa300a3a3
+.long	0x00bababa,0xae00aeae
+.long	0x007a7a7a,0x9e009e9e
+.long	0x00b3b3b3,0xec00ecec
+.long	0x00020202,0x80008080
+.long	0x00b4b4b4,0x2d002d2d
+.long	0x00adadad,0x6b006b6b
+.long	0x00a2a2a2,0xa800a8a8
+.long	0x00acacac,0x2b002b2b
+.long	0x00d8d8d8,0x36003636
+.long	0x009a9a9a,0xa600a6a6
+.long	0x00171717,0xc500c5c5
+.long	0x001a1a1a,0x86008686
+.long	0x00353535,0x4d004d4d
+.long	0x00cccccc,0x33003333
+.long	0x00f7f7f7,0xfd00fdfd
+.long	0x00999999,0x66006666
+.long	0x00616161,0x58005858
+.long	0x005a5a5a,0x96009696
+.long	0x00e8e8e8,0x3a003a3a
+.long	0x00242424,0x09000909
+.long	0x00565656,0x95009595
+.long	0x00404040,0x10001010
+.long	0x00e1e1e1,0x78007878
+.long	0x00636363,0xd800d8d8
+.long	0x00090909,0x42004242
+.long	0x00333333,0xcc00cccc
+.long	0x00bfbfbf,0xef00efef
+.long	0x00989898,0x26002626
+.long	0x00979797,0xe500e5e5
+.long	0x00858585,0x61006161
+.long	0x00686868,0x1a001a1a
+.long	0x00fcfcfc,0x3f003f3f
+.long	0x00ececec,0x3b003b3b
+.long	0x000a0a0a,0x82008282
+.long	0x00dadada,0xb600b6b6
+.long	0x006f6f6f,0xdb00dbdb
+.long	0x00535353,0xd400d4d4
+.long	0x00626262,0x98009898
+.long	0x00a3a3a3,0xe800e8e8
+.long	0x002e2e2e,0x8b008b8b
+.long	0x00080808,0x02000202
+.long	0x00afafaf,0xeb00ebeb
+.long	0x00282828,0x0a000a0a
+.long	0x00b0b0b0,0x2c002c2c
+.long	0x00747474,0x1d001d1d
+.long	0x00c2c2c2,0xb000b0b0
+.long	0x00bdbdbd,0x6f006f6f
+.long	0x00363636,0x8d008d8d
+.long	0x00222222,0x88008888
+.long	0x00383838,0x0e000e0e
+.long	0x00646464,0x19001919
+.long	0x001e1e1e,0x87008787
+.long	0x00393939,0x4e004e4e
+.long	0x002c2c2c,0x0b000b0b
+.long	0x00a6a6a6,0xa900a9a9
+.long	0x00303030,0x0c000c0c
+.long	0x00e5e5e5,0x79007979
+.long	0x00444444,0x11001111
+.long	0x00fdfdfd,0x7f007f7f
+.long	0x00888888,0x22002222
+.long	0x009f9f9f,0xe700e7e7
+.long	0x00656565,0x59005959
+.long	0x00878787,0xe100e1e1
+.long	0x006b6b6b,0xda00dada
+.long	0x00f4f4f4,0x3d003d3d
+.long	0x00232323,0xc800c8c8
+.long	0x00484848,0x12001212
+.long	0x00101010,0x04000404
+.long	0x00d1d1d1,0x74007474
+.long	0x00515151,0x54005454
+.long	0x00c0c0c0,0x30003030
+.long	0x00f9f9f9,0x7e007e7e
+.long	0x00d2d2d2,0xb400b4b4
+.long	0x00a0a0a0,0x28002828
+.long	0x00555555,0x55005555
+.long	0x00a1a1a1,0x68006868
+.long	0x00414141,0x50005050
+.long	0x00fafafa,0xbe00bebe
+.long	0x00434343,0xd000d0d0
+.long	0x00131313,0xc400c4c4
+.long	0x00c4c4c4,0x31003131
+.long	0x002f2f2f,0xcb00cbcb
+.long	0x00a8a8a8,0x2a002a2a
+.long	0x00b6b6b6,0xad00adad
+.long	0x003c3c3c,0x0f000f0f
+.long	0x002b2b2b,0xca00caca
+.long	0x00c1c1c1,0x70007070
+.long	0x00ffffff,0xff00ffff
+.long	0x00c8c8c8,0x32003232
+.long	0x00a5a5a5,0x69006969
+.long	0x00202020,0x08000808
+.long	0x00898989,0x62006262
+.long	0x00000000,0x00000000
+.long	0x00909090,0x24002424
+.long	0x00474747,0xd100d1d1
+.long	0x00efefef,0xfb00fbfb
+.long	0x00eaeaea,0xba00baba
+.long	0x00b7b7b7,0xed00eded
+.long	0x00151515,0x45004545
+.long	0x00060606,0x81008181
+.long	0x00cdcdcd,0x73007373
+.long	0x00b5b5b5,0x6d006d6d
+.long	0x00121212,0x84008484
+.long	0x007e7e7e,0x9f009f9f
+.long	0x00bbbbbb,0xee00eeee
+.long	0x00292929,0x4a004a4a
+.long	0x000f0f0f,0xc300c3c3
+.long	0x00b8b8b8,0x2e002e2e
+.long	0x00070707,0xc100c1c1
+.long	0x00040404,0x01000101
+.long	0x009b9b9b,0xe600e6e6
+.long	0x00949494,0x25002525
+.long	0x00212121,0x48004848
+.long	0x00666666,0x99009999
+.long	0x00e6e6e6,0xb900b9b9
+.long	0x00cecece,0xb300b3b3
+.long	0x00ededed,0x7b007b7b
+.long	0x00e7e7e7,0xf900f9f9
+.long	0x003b3b3b,0xce00cece
+.long	0x00fefefe,0xbf00bfbf
+.long	0x007f7f7f,0xdf00dfdf
+.long	0x00c5c5c5,0x71007171
+.long	0x00a4a4a4,0x29002929
+.long	0x00373737,0xcd00cdcd
+.long	0x00b1b1b1,0x6c006c6c
+.long	0x004c4c4c,0x13001313
+.long	0x00919191,0x64006464
+.long	0x006e6e6e,0x9b009b9b
+.long	0x008d8d8d,0x63006363
+.long	0x00767676,0x9d009d9d
+.long	0x00030303,0xc000c0c0
+.long	0x002d2d2d,0x4b004b4b
+.long	0x00dedede,0xb700b7b7
+.long	0x00969696,0xa500a5a5
+.long	0x00262626,0x89008989
+.long	0x007d7d7d,0x5f005f5f
+.long	0x00c6c6c6,0xb100b1b1
+.long	0x005c5c5c,0x17001717
+.long	0x00d3d3d3,0xf400f4f4
+.long	0x00f2f2f2,0xbc00bcbc
+.long	0x004f4f4f,0xd300d3d3
+.long	0x00191919,0x46004646
+.long	0x003f3f3f,0xcf00cfcf
+.long	0x00dcdcdc,0x37003737
+.long	0x00797979,0x5e005e5e
+.long	0x001d1d1d,0x47004747
+.long	0x00525252,0x94009494
+.long	0x00ebebeb,0xfa00fafa
+.long	0x00f3f3f3,0xfc00fcfc
+.long	0x006d6d6d,0x5b005b5b
+.long	0x005e5e5e,0x97009797
+.long	0x00fbfbfb,0xfe00fefe
+.long	0x00696969,0x5a005a5a
+.long	0x00b2b2b2,0xac00acac
+.long	0x00f0f0f0,0x3c003c3c
+.long	0x00313131,0x4c004c4c
+.long	0x000c0c0c,0x03000303
+.long	0x00d4d4d4,0x35003535
+.long	0x00cfcfcf,0xf300f3f3
+.long	0x008c8c8c,0x23002323
+.long	0x00e2e2e2,0xb800b8b8
+.long	0x00757575,0x5d005d5d
+.long	0x00a9a9a9,0x6a006a6a
+.long	0x004a4a4a,0x92009292
+.long	0x00575757,0xd500d5d5
+.long	0x00848484,0x21002121
+.long	0x00111111,0x44004444
+.long	0x00454545,0x51005151
+.long	0x001b1b1b,0xc600c6c6
+.long	0x00f5f5f5,0x7d007d7d
+.long	0x00e4e4e4,0x39003939
+.long	0x000e0e0e,0x83008383
+.long	0x00737373,0xdc00dcdc
+.long	0x00aaaaaa,0xaa00aaaa
+.long	0x00f1f1f1,0x7c007c7c
+.long	0x00dddddd,0x77007777
+.long	0x00595959,0x56005656
+.long	0x00141414,0x05000505
+.long	0x006c6c6c,0x1b001b1b
+.long	0x00929292,0xa400a4a4
+.long	0x00545454,0x15001515
+.long	0x00d0d0d0,0x34003434
+.long	0x00787878,0x1e001e1e
+.long	0x00707070,0x1c001c1c
+.long	0x00e3e3e3,0xf800f8f8
+.long	0x00494949,0x52005252
+.long	0x00808080,0x20002020
+.long	0x00505050,0x14001414
+.long	0x00a7a7a7,0xe900e9e9
+.long	0x00f6f6f6,0xbd00bdbd
+.long	0x00777777,0xdd00dddd
+.long	0x00939393,0xe400e4e4
+.long	0x00868686,0xa100a1a1
+.long	0x00838383,0xe000e0e0
+.long	0x002a2a2a,0x8a008a8a
+.long	0x00c7c7c7,0xf100f1f1
+.long	0x005b5b5b,0xd600d6d6
+.long	0x00e9e9e9,0x7a007a7a
+.long	0x00eeeeee,0xbb00bbbb
+.long	0x008f8f8f,0xe300e3e3
+.long	0x00010101,0x40004040
+.long	0x003d3d3d,0x4f004f4f
+.globl	_Camellia_cbc_encrypt
+
+.p2align	4
+_Camellia_cbc_encrypt:
+	cmpq	$0,%rdx
+	je	L$cbc_abort
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+L$cbc_prologue:
+
+	movq	%rsp,%rbp
+	subq	$64,%rsp
+	andq	$-64,%rsp
+
+
+
+	leaq	-64-63(%rcx),%r10
+	subq	%rsp,%r10
+	negq	%r10
+	andq	$960,%r10
+	subq	%r10,%rsp
+
+
+	movq	%rdi,%r12
+	movq	%rsi,%r13
+	movq	%r8,%rbx
+	movq	%rcx,%r14
+	movl	272(%rcx),%r15d
+
+	movq	%r8,40(%rsp)
+	movq	%rbp,48(%rsp)
+
+L$cbc_body:
+	leaq	L$Camellia_SBOX(%rip),%rbp
+
+	movl	$32,%ecx
+.p2align	2
+L$cbc_prefetch_sbox:
+	movq	0(%rbp),%rax
+	movq	32(%rbp),%rsi
+	movq	64(%rbp),%rdi
+	movq	96(%rbp),%r11
+	leaq	128(%rbp),%rbp
+	loop	L$cbc_prefetch_sbox
+	subq	$4096,%rbp
+	shlq	$6,%r15
+	movq	%rdx,%rcx
+	leaq	(%r14,%r15,1),%r15
+
+	cmpl	$0,%r9d
+	je	L$CBC_DECRYPT
+
+	andq	$-16,%rdx
+	andq	$15,%rcx
+	leaq	(%r12,%rdx,1),%rdx
+	movq	%r14,0(%rsp)
+	movq	%rdx,8(%rsp)
+	movq	%rcx,16(%rsp)
+
+	cmpq	%r12,%rdx
+	movl	0(%rbx),%r8d
+	movl	4(%rbx),%r9d
+	movl	8(%rbx),%r10d
+	movl	12(%rbx),%r11d
+	je	L$cbc_enc_tail
+	jmp	L$cbc_eloop
+
+.p2align	4
+L$cbc_eloop:
+	xorl	0(%r12),%r8d
+	xorl	4(%r12),%r9d
+	xorl	8(%r12),%r10d
+	bswapl	%r8d
+	xorl	12(%r12),%r11d
+	bswapl	%r9d
+	bswapl	%r10d
+	bswapl	%r11d
+
+	call	_x86_64_Camellia_encrypt
+
+	movq	0(%rsp),%r14
+	bswapl	%r8d
+	movq	8(%rsp),%rdx
+	bswapl	%r9d
+	movq	16(%rsp),%rcx
+	bswapl	%r10d
+	movl	%r8d,0(%r13)
+	bswapl	%r11d
+	movl	%r9d,4(%r13)
+	movl	%r10d,8(%r13)
+	leaq	16(%r12),%r12
+	movl	%r11d,12(%r13)
+	cmpq	%rdx,%r12
+	leaq	16(%r13),%r13
+	jne	L$cbc_eloop
+
+	cmpq	$0,%rcx
+	jne	L$cbc_enc_tail
+
+	movq	40(%rsp),%r13
+	movl	%r8d,0(%r13)
+	movl	%r9d,4(%r13)
+	movl	%r10d,8(%r13)
+	movl	%r11d,12(%r13)
+	jmp	L$cbc_done
+
+.p2align	4
+L$cbc_enc_tail:
+	xorq	%rax,%rax
+	movq	%rax,0+24(%rsp)
+	movq	%rax,8+24(%rsp)
+	movq	%rax,16(%rsp)
+
+L$cbc_enc_pushf:
+	pushfq
+	cld
+	movq	%r12,%rsi
+	leaq	8+24(%rsp),%rdi
+.long	0x9066A4F3		
+	popfq
+L$cbc_enc_popf:
+
+	leaq	24(%rsp),%r12
+	leaq	16+24(%rsp),%rax
+	movq	%rax,8(%rsp)
+	jmp	L$cbc_eloop		
+
+.p2align	4
+L$CBC_DECRYPT:
+	xchgq	%r14,%r15
+	addq	$15,%rdx
+	andq	$15,%rcx
+	andq	$-16,%rdx
+	movq	%r14,0(%rsp)
+	leaq	(%r12,%rdx,1),%rdx
+	movq	%rdx,8(%rsp)
+	movq	%rcx,16(%rsp)
+
+	movq	(%rbx),%rax
+	movq	8(%rbx),%rbx
+	jmp	L$cbc_dloop
+.p2align	4
+L$cbc_dloop:
+	movl	0(%r12),%r8d
+	movl	4(%r12),%r9d
+	movl	8(%r12),%r10d
+	bswapl	%r8d
+	movl	12(%r12),%r11d
+	bswapl	%r9d
+	movq	%rax,0+24(%rsp)
+	bswapl	%r10d
+	movq	%rbx,8+24(%rsp)
+	bswapl	%r11d
+
+	call	_x86_64_Camellia_decrypt
+
+	movq	0(%rsp),%r14
+	movq	8(%rsp),%rdx
+	movq	16(%rsp),%rcx
+
+	bswapl	%r8d
+	movq	(%r12),%rax
+	bswapl	%r9d
+	movq	8(%r12),%rbx
+	bswapl	%r10d
+	xorl	0+24(%rsp),%r8d
+	bswapl	%r11d
+	xorl	4+24(%rsp),%r9d
+	xorl	8+24(%rsp),%r10d
+	leaq	16(%r12),%r12
+	xorl	12+24(%rsp),%r11d
+	cmpq	%rdx,%r12
+	je	L$cbc_ddone
+
+	movl	%r8d,0(%r13)
+	movl	%r9d,4(%r13)
+	movl	%r10d,8(%r13)
+	movl	%r11d,12(%r13)
+
+	leaq	16(%r13),%r13
+	jmp	L$cbc_dloop
+
+.p2align	4
+L$cbc_ddone:
+	movq	40(%rsp),%rdx
+	cmpq	$0,%rcx
+	jne	L$cbc_dec_tail
+
+	movl	%r8d,0(%r13)
+	movl	%r9d,4(%r13)
+	movl	%r10d,8(%r13)
+	movl	%r11d,12(%r13)
+
+	movq	%rax,(%rdx)
+	movq	%rbx,8(%rdx)
+	jmp	L$cbc_done
+.p2align	4
+L$cbc_dec_tail:
+	movl	%r8d,0+24(%rsp)
+	movl	%r9d,4+24(%rsp)
+	movl	%r10d,8+24(%rsp)
+	movl	%r11d,12+24(%rsp)
+
+L$cbc_dec_pushf:
+	pushfq
+	cld
+	leaq	8+24(%rsp),%rsi
+	leaq	(%r13),%rdi
+.long	0x9066A4F3		
+	popfq
+L$cbc_dec_popf:
+
+	movq	%rax,(%rdx)
+	movq	%rbx,8(%rdx)
+	jmp	L$cbc_done
+
+.p2align	4
+L$cbc_done:
+	movq	48(%rsp),%rcx
+	movq	0(%rcx),%r15
+	movq	8(%rcx),%r14
+	movq	16(%rcx),%r13
+	movq	24(%rcx),%r12
+	movq	32(%rcx),%rbp
+	movq	40(%rcx),%rbx
+	leaq	48(%rcx),%rsp
+L$cbc_abort:
+	.byte	0xf3,0xc3
+
+
+.byte	67,97,109,101,108,108,105,97,32,102,111,114,32,120,56,54,95,54,52,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
diff --git a/crypto/libressl/crypto/camellia/cmll_cbc.c b/crypto/libressl/crypto/camellia/cmll_cbc.c
new file mode 100644
index 0000000000..7fc531e7c7
--- /dev/null
+++ b/crypto/libressl/crypto/camellia/cmll_cbc.c
@@ -0,0 +1,65 @@
+/* $OpenBSD: cmll_cbc.c,v 1.3 2014/06/12 15:49:28 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include 
+#include 
+
+void
+Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len,
+    const CAMELLIA_KEY *key, unsigned char *ivec, const int enc)
+{
+	if (enc)
+		CRYPTO_cbc128_encrypt(in, out, len, key, ivec,
+		    (block128_f)Camellia_encrypt);
+	else
+		CRYPTO_cbc128_decrypt(in, out, len, key, ivec,
+		   (block128_f)Camellia_decrypt);
+}
diff --git a/crypto/libressl/crypto/camellia/cmll_cfb.c b/crypto/libressl/crypto/camellia/cmll_cfb.c
new file mode 100644
index 0000000000..fdb9c5a85c
--- /dev/null
+++ b/crypto/libressl/crypto/camellia/cmll_cfb.c
@@ -0,0 +1,144 @@
+/* $OpenBSD: cmll_cfb.c,v 1.3 2014/06/12 15:49:28 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+
+/*
+ * The input and output encrypted as though 128bit cfb mode is being
+ * used.  The extra state information to record how much of the
+ * 128bit block we have used is contained in *num;
+ */
+
+void
+Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+    size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num,
+    const int enc)
+{
+	CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc,
+	    (block128_f)Camellia_encrypt);
+}
+
+/* N.B. This expects the input to be packed, MS bit first */
+void
+Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out,
+    size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num,
+    const int enc)
+{
+	CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc,
+	    (block128_f)Camellia_encrypt);
+}
+
+void
+Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out,
+    size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num,
+    const int enc)
+{
+	CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc,
+	    (block128_f)Camellia_encrypt);
+}
diff --git a/crypto/libressl/crypto/camellia/cmll_ctr.c b/crypto/libressl/crypto/camellia/cmll_ctr.c
new file mode 100644
index 0000000000..0d43b5b323
--- /dev/null
+++ b/crypto/libressl/crypto/camellia/cmll_ctr.c
@@ -0,0 +1,63 @@
+/* $OpenBSD: cmll_ctr.c,v 1.3 2014/06/12 15:49:28 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include 
+#include 
+
+void
+Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+    size_t length, const CAMELLIA_KEY *key,
+    unsigned char ivec[CAMELLIA_BLOCK_SIZE],
+    unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], unsigned int *num)
+{
+	CRYPTO_ctr128_encrypt(in, out, length, key, ivec, ecount_buf, num,
+	    (block128_f)Camellia_encrypt);
+}
diff --git a/crypto/libressl/crypto/camellia/cmll_ecb.c b/crypto/libressl/crypto/camellia/cmll_ecb.c
new file mode 100644
index 0000000000..cdcdfa75de
--- /dev/null
+++ b/crypto/libressl/crypto/camellia/cmll_ecb.c
@@ -0,0 +1,63 @@
+/* $OpenBSD: cmll_ecb.c,v 1.3 2014/06/12 15:49:28 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include 
+#include "cmll_locl.h"
+
+void
+Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out,
+    const CAMELLIA_KEY *key, const int enc)
+{
+	if (CAMELLIA_ENCRYPT == enc)
+		Camellia_encrypt(in, out, key);
+	else
+		Camellia_decrypt(in, out, key);
+}
diff --git a/crypto/libressl/crypto/camellia/cmll_locl.h b/crypto/libressl/crypto/camellia/cmll_locl.h
new file mode 100644
index 0000000000..b460967c23
--- /dev/null
+++ b/crypto/libressl/crypto/camellia/cmll_locl.h
@@ -0,0 +1,85 @@
+/* $OpenBSD: cmll_locl.h,v 1.4 2014/07/12 20:11:45 miod Exp $ */
+/* ====================================================================
+ * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) . 
+ * ALL RIGHTS RESERVED.
+ *
+ * Intellectual Property information for Camellia:
+ *     http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html
+ *
+ * News Release for Announcement of Camellia open source:
+ *     http://www.ntt.co.jp/news/news06e/0604/060413a.html
+ *
+ * The Camellia Code included herein is developed by
+ * NTT (Nippon Telegraph and Telephone Corporation), and is contributed
+ * to the OpenSSL project.
+ *
+ * The Camellia Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#ifndef HEADER_CAMELLIA_LOCL_H
+#define HEADER_CAMELLIA_LOCL_H
+
+typedef unsigned int  u32;
+typedef unsigned char u8;
+
+int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey,
+	    KEY_TABLE_TYPE keyTable);
+void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[],
+	    const KEY_TABLE_TYPE keyTable, u8 ciphertext[]);
+void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[],
+	    const KEY_TABLE_TYPE keyTable, u8 plaintext[]);
+void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[],
+	    const KEY_TABLE_TYPE keyTable, u8 ciphertext[]);
+void Camellia_DecryptBlock(int keyBitLength, const u8 ciphertext[],
+	    const KEY_TABLE_TYPE keyTable, u8 plaintext[]);
+
+#endif /* #ifndef HEADER_CAMELLIA_LOCL_H */
diff --git a/crypto/libressl/crypto/camellia/cmll_misc.c b/crypto/libressl/crypto/camellia/cmll_misc.c
new file mode 100644
index 0000000000..62173e65c6
--- /dev/null
+++ b/crypto/libressl/crypto/camellia/cmll_misc.c
@@ -0,0 +1,81 @@
+/* $OpenBSD: cmll_misc.c,v 1.5 2014/07/12 20:11:45 miod Exp $ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include 
+#include 
+#include 
+#include "cmll_locl.h"
+
+int
+Camellia_set_key(const unsigned char *userKey, const int bits,
+    CAMELLIA_KEY *key)
+{
+	if (userKey == NULL || key == NULL)
+		return -1;
+	if (bits != 128 && bits != 192 && bits != 256)
+		return -2;
+	key->grand_rounds = Camellia_Ekeygen(bits, userKey, key->u.rd_key);
+	return 0;
+}
+
+void
+Camellia_encrypt(const unsigned char *in, unsigned char *out,
+    const CAMELLIA_KEY *key)
+{
+	Camellia_EncryptBlock_Rounds(key->grand_rounds, in, key->u.rd_key, out);
+}
+
+void
+Camellia_decrypt(const unsigned char *in, unsigned char *out,
+    const CAMELLIA_KEY *key)
+{
+	Camellia_DecryptBlock_Rounds(key->grand_rounds, in, key->u.rd_key, out);
+}
diff --git a/crypto/libressl/crypto/camellia/cmll_ofb.c b/crypto/libressl/crypto/camellia/cmll_ofb.c
new file mode 100644
index 0000000000..ded72a04ce
--- /dev/null
+++ b/crypto/libressl/crypto/camellia/cmll_ofb.c
@@ -0,0 +1,122 @@
+/* $OpenBSD: cmll_ofb.c,v 1.3 2014/06/12 15:49:28 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+/*
+ * The input and output encrypted as though 128bit ofb mode is being
+ * used.  The extra state information to record how much of the
+ * 128bit block we have used is contained in *num;
+ */
+void
+Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+    size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num)
+{
+	CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num,
+	    (block128_f)Camellia_encrypt);
+}
diff --git a/crypto/libressl/crypto/cast/c_cfb64.c b/crypto/libressl/crypto/cast/c_cfb64.c
new file mode 100644
index 0000000000..2571486309
--- /dev/null
+++ b/crypto/libressl/crypto/cast/c_cfb64.c
@@ -0,0 +1,121 @@
+/* $OpenBSD: c_cfb64.c,v 1.4 2014/06/12 15:49:28 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include "cast_lcl.h"
+
+/* The input and output encrypted as though 64bit cfb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+
+void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+			long length, const CAST_KEY *schedule, unsigned char *ivec,
+			int *num, int enc)
+	{
+	CAST_LONG v0,v1,t;
+	int n= *num;
+	long l=length;
+	CAST_LONG ti[2];
+	unsigned char *iv,c,cc;
+
+	iv=ivec;
+	if (enc)
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				n2l(iv,v0); ti[0]=v0;
+				n2l(iv,v1); ti[1]=v1;
+				CAST_encrypt((CAST_LONG *)ti,schedule);
+				iv=ivec;
+				t=ti[0]; l2n(t,iv);
+				t=ti[1]; l2n(t,iv);
+				iv=ivec;
+				}
+			c= *(in++)^iv[n];
+			*(out++)=c;
+			iv[n]=c;
+			n=(n+1)&0x07;
+			}
+		}
+	else
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				n2l(iv,v0); ti[0]=v0;
+				n2l(iv,v1); ti[1]=v1;
+				CAST_encrypt((CAST_LONG *)ti,schedule);
+				iv=ivec;
+				t=ti[0]; l2n(t,iv);
+				t=ti[1]; l2n(t,iv);
+				iv=ivec;
+				}
+			cc= *(in++);
+			c=iv[n];
+			iv[n]=cc;
+			*(out++)=c^cc;
+			n=(n+1)&0x07;
+			}
+		}
+	v0=v1=ti[0]=ti[1]=t=c=cc=0;
+	*num=n;
+	}
diff --git a/crypto/libressl/crypto/cast/c_ecb.c b/crypto/libressl/crypto/cast/c_ecb.c
new file mode 100644
index 0000000000..19cc100396
--- /dev/null
+++ b/crypto/libressl/crypto/cast/c_ecb.c
@@ -0,0 +1,77 @@
+/* $OpenBSD: c_ecb.c,v 1.6 2014/06/12 15:49:28 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include "cast_lcl.h"
+#include 
+
+void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out,
+		      const CAST_KEY *ks, int enc)
+	{
+	CAST_LONG l,d[2];
+
+	n2l(in,l); d[0]=l;
+	n2l(in,l); d[1]=l;
+	if (enc)
+		CAST_encrypt(d,ks);
+	else
+		CAST_decrypt(d,ks);
+	l=d[0]; l2n(l,out);
+	l=d[1]; l2n(l,out);
+	l=d[0]=d[1]=0;
+	}
diff --git a/crypto/libressl/crypto/cast/c_enc.c b/crypto/libressl/crypto/cast/c_enc.c
new file mode 100644
index 0000000000..6dca24f849
--- /dev/null
+++ b/crypto/libressl/crypto/cast/c_enc.c
@@ -0,0 +1,210 @@
+/* $OpenBSD: c_enc.c,v 1.6 2014/06/12 15:49:28 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include "cast_lcl.h"
+
+#ifndef OPENBSD_CAST_ASM
+void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key)
+	{
+	CAST_LONG l,r,t;
+	const CAST_LONG *k;
+
+	k= &(key->data[0]);
+	l=data[0];
+	r=data[1];
+
+	E_CAST( 0,k,l,r,+,^,-);
+	E_CAST( 1,k,r,l,^,-,+);
+	E_CAST( 2,k,l,r,-,+,^);
+	E_CAST( 3,k,r,l,+,^,-);
+	E_CAST( 4,k,l,r,^,-,+);
+	E_CAST( 5,k,r,l,-,+,^);
+	E_CAST( 6,k,l,r,+,^,-);
+	E_CAST( 7,k,r,l,^,-,+);
+	E_CAST( 8,k,l,r,-,+,^);
+	E_CAST( 9,k,r,l,+,^,-);
+	E_CAST(10,k,l,r,^,-,+);
+	E_CAST(11,k,r,l,-,+,^);
+	if(!key->short_key)
+	    {
+	    E_CAST(12,k,l,r,+,^,-);
+	    E_CAST(13,k,r,l,^,-,+);
+	    E_CAST(14,k,l,r,-,+,^);
+	    E_CAST(15,k,r,l,+,^,-);
+	    }
+
+	data[1]=l&0xffffffffL;
+	data[0]=r&0xffffffffL;
+	}
+
+void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key)
+	{
+	CAST_LONG l,r,t;
+	const CAST_LONG *k;
+
+	k= &(key->data[0]);
+	l=data[0];
+	r=data[1];
+
+	if(!key->short_key)
+	    {
+	    E_CAST(15,k,l,r,+,^,-);
+	    E_CAST(14,k,r,l,-,+,^);
+	    E_CAST(13,k,l,r,^,-,+);
+	    E_CAST(12,k,r,l,+,^,-);
+	    }
+	E_CAST(11,k,l,r,-,+,^);
+	E_CAST(10,k,r,l,^,-,+);
+	E_CAST( 9,k,l,r,+,^,-);
+	E_CAST( 8,k,r,l,-,+,^);
+	E_CAST( 7,k,l,r,^,-,+);
+	E_CAST( 6,k,r,l,+,^,-);
+	E_CAST( 5,k,l,r,-,+,^);
+	E_CAST( 4,k,r,l,^,-,+);
+	E_CAST( 3,k,l,r,+,^,-);
+	E_CAST( 2,k,r,l,-,+,^);
+	E_CAST( 1,k,l,r,^,-,+);
+	E_CAST( 0,k,r,l,+,^,-);
+
+	data[1]=l&0xffffffffL;
+	data[0]=r&0xffffffffL;
+	}
+#endif
+
+void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+	     const CAST_KEY *ks, unsigned char *iv, int enc)
+	{
+	CAST_LONG tin0,tin1;
+	CAST_LONG tout0,tout1,xor0,xor1;
+	long l=length;
+	CAST_LONG tin[2];
+
+	if (enc)
+		{
+		n2l(iv,tout0);
+		n2l(iv,tout1);
+		iv-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			n2l(in,tin0);
+			n2l(in,tin1);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			CAST_encrypt(tin,ks);
+			tout0=tin[0];
+			tout1=tin[1];
+			l2n(tout0,out);
+			l2n(tout1,out);
+			}
+		if (l != -8)
+			{
+			n2ln(in,tin0,tin1,l+8);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			CAST_encrypt(tin,ks);
+			tout0=tin[0];
+			tout1=tin[1];
+			l2n(tout0,out);
+			l2n(tout1,out);
+			}
+		l2n(tout0,iv);
+		l2n(tout1,iv);
+		}
+	else
+		{
+		n2l(iv,xor0);
+		n2l(iv,xor1);
+		iv-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			n2l(in,tin0);
+			n2l(in,tin1);
+			tin[0]=tin0;
+			tin[1]=tin1;
+			CAST_decrypt(tin,ks);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2n(tout0,out);
+			l2n(tout1,out);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		if (l != -8)
+			{
+			n2l(in,tin0);
+			n2l(in,tin1);
+			tin[0]=tin0;
+			tin[1]=tin1;
+			CAST_decrypt(tin,ks);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2nn(tout0,tout1,out,l+8);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		l2n(xor0,iv);
+		l2n(xor1,iv);
+		}
+	tin0=tin1=tout0=tout1=xor0=xor1=0;
+	tin[0]=tin[1]=0;
+	}
diff --git a/crypto/libressl/crypto/cast/c_ofb64.c b/crypto/libressl/crypto/cast/c_ofb64.c
new file mode 100644
index 0000000000..2dcc501f5d
--- /dev/null
+++ b/crypto/libressl/crypto/cast/c_ofb64.c
@@ -0,0 +1,110 @@
+/* $OpenBSD: c_ofb64.c,v 1.4 2014/06/12 15:49:28 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include "cast_lcl.h"
+
+/* The input and output encrypted as though 64bit ofb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+			long length, const CAST_KEY *schedule, unsigned char *ivec,
+			int *num)
+	{
+	CAST_LONG v0,v1,t;
+	int n= *num;
+	long l=length;
+	unsigned char d[8];
+	char *dp;
+	CAST_LONG ti[2];
+	unsigned char *iv;
+	int save=0;
+
+	iv=ivec;
+	n2l(iv,v0);
+	n2l(iv,v1);
+	ti[0]=v0;
+	ti[1]=v1;
+	dp=(char *)d;
+	l2n(v0,dp);
+	l2n(v1,dp);
+	while (l--)
+		{
+		if (n == 0)
+			{
+			CAST_encrypt((CAST_LONG *)ti,schedule);
+			dp=(char *)d;
+			t=ti[0]; l2n(t,dp);
+			t=ti[1]; l2n(t,dp);
+			save++;
+			}
+		*(out++)= *(in++)^d[n];
+		n=(n+1)&0x07;
+		}
+	if (save)
+		{
+		v0=ti[0];
+		v1=ti[1];
+		iv=ivec;
+		l2n(v0,iv);
+		l2n(v1,iv);
+		}
+	t=v0=v1=ti[0]=ti[1]=0;
+	*num=n;
+	}
diff --git a/crypto/libressl/crypto/cast/c_skey.c b/crypto/libressl/crypto/cast/c_skey.c
new file mode 100644
index 0000000000..8f6528d65e
--- /dev/null
+++ b/crypto/libressl/crypto/cast/c_skey.c
@@ -0,0 +1,166 @@
+/* $OpenBSD$ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include "cast_lcl.h"
+#include "cast_s.h"
+
+#define CAST_exp(l,A,a,n) \
+	A[n/4]=l; \
+	a[n+3]=(l    )&0xff; \
+	a[n+2]=(l>> 8)&0xff; \
+	a[n+1]=(l>>16)&0xff; \
+	a[n+0]=(l>>24)&0xff;
+
+#define S4 CAST_S_table4
+#define S5 CAST_S_table5
+#define S6 CAST_S_table6
+#define S7 CAST_S_table7
+void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data)
+	{
+	CAST_LONG x[16];
+	CAST_LONG z[16];
+	CAST_LONG k[32];
+	CAST_LONG X[4],Z[4];
+	CAST_LONG l,*K;
+	int i;
+
+	for (i=0; i<16; i++) x[i]=0;
+	if (len > 16) len=16;
+	for (i=0; ishort_key=1;
+	else
+	    key->short_key=0;
+
+	K= &k[0];
+	X[0]=((x[ 0]<<24)|(x[ 1]<<16)|(x[ 2]<<8)|x[ 3])&0xffffffffL;
+	X[1]=((x[ 4]<<24)|(x[ 5]<<16)|(x[ 6]<<8)|x[ 7])&0xffffffffL;
+	X[2]=((x[ 8]<<24)|(x[ 9]<<16)|(x[10]<<8)|x[11])&0xffffffffL;
+	X[3]=((x[12]<<24)|(x[13]<<16)|(x[14]<<8)|x[15])&0xffffffffL;
+
+	for (;;)
+		{
+	l=X[0]^S4[x[13]]^S5[x[15]]^S6[x[12]]^S7[x[14]]^S6[x[ 8]];
+	CAST_exp(l,Z,z, 0);
+	l=X[2]^S4[z[ 0]]^S5[z[ 2]]^S6[z[ 1]]^S7[z[ 3]]^S7[x[10]];
+	CAST_exp(l,Z,z, 4);
+	l=X[3]^S4[z[ 7]]^S5[z[ 6]]^S6[z[ 5]]^S7[z[ 4]]^S4[x[ 9]];
+	CAST_exp(l,Z,z, 8);
+	l=X[1]^S4[z[10]]^S5[z[ 9]]^S6[z[11]]^S7[z[ 8]]^S5[x[11]];
+	CAST_exp(l,Z,z,12);
+
+	K[ 0]= S4[z[ 8]]^S5[z[ 9]]^S6[z[ 7]]^S7[z[ 6]]^S4[z[ 2]];
+	K[ 1]= S4[z[10]]^S5[z[11]]^S6[z[ 5]]^S7[z[ 4]]^S5[z[ 6]];
+	K[ 2]= S4[z[12]]^S5[z[13]]^S6[z[ 3]]^S7[z[ 2]]^S6[z[ 9]];
+	K[ 3]= S4[z[14]]^S5[z[15]]^S6[z[ 1]]^S7[z[ 0]]^S7[z[12]];
+
+	l=Z[2]^S4[z[ 5]]^S5[z[ 7]]^S6[z[ 4]]^S7[z[ 6]]^S6[z[ 0]];
+	CAST_exp(l,X,x, 0);
+	l=Z[0]^S4[x[ 0]]^S5[x[ 2]]^S6[x[ 1]]^S7[x[ 3]]^S7[z[ 2]];
+	CAST_exp(l,X,x, 4);
+	l=Z[1]^S4[x[ 7]]^S5[x[ 6]]^S6[x[ 5]]^S7[x[ 4]]^S4[z[ 1]];
+	CAST_exp(l,X,x, 8);
+	l=Z[3]^S4[x[10]]^S5[x[ 9]]^S6[x[11]]^S7[x[ 8]]^S5[z[ 3]];
+	CAST_exp(l,X,x,12);
+
+	K[ 4]= S4[x[ 3]]^S5[x[ 2]]^S6[x[12]]^S7[x[13]]^S4[x[ 8]];
+	K[ 5]= S4[x[ 1]]^S5[x[ 0]]^S6[x[14]]^S7[x[15]]^S5[x[13]];
+	K[ 6]= S4[x[ 7]]^S5[x[ 6]]^S6[x[ 8]]^S7[x[ 9]]^S6[x[ 3]];
+	K[ 7]= S4[x[ 5]]^S5[x[ 4]]^S6[x[10]]^S7[x[11]]^S7[x[ 7]];
+
+	l=X[0]^S4[x[13]]^S5[x[15]]^S6[x[12]]^S7[x[14]]^S6[x[ 8]];
+	CAST_exp(l,Z,z, 0);
+	l=X[2]^S4[z[ 0]]^S5[z[ 2]]^S6[z[ 1]]^S7[z[ 3]]^S7[x[10]];
+	CAST_exp(l,Z,z, 4);
+	l=X[3]^S4[z[ 7]]^S5[z[ 6]]^S6[z[ 5]]^S7[z[ 4]]^S4[x[ 9]];
+	CAST_exp(l,Z,z, 8);
+	l=X[1]^S4[z[10]]^S5[z[ 9]]^S6[z[11]]^S7[z[ 8]]^S5[x[11]];
+	CAST_exp(l,Z,z,12);
+
+	K[ 8]= S4[z[ 3]]^S5[z[ 2]]^S6[z[12]]^S7[z[13]]^S4[z[ 9]];
+	K[ 9]= S4[z[ 1]]^S5[z[ 0]]^S6[z[14]]^S7[z[15]]^S5[z[12]];
+	K[10]= S4[z[ 7]]^S5[z[ 6]]^S6[z[ 8]]^S7[z[ 9]]^S6[z[ 2]];
+	K[11]= S4[z[ 5]]^S5[z[ 4]]^S6[z[10]]^S7[z[11]]^S7[z[ 6]];
+
+	l=Z[2]^S4[z[ 5]]^S5[z[ 7]]^S6[z[ 4]]^S7[z[ 6]]^S6[z[ 0]];
+	CAST_exp(l,X,x, 0);
+	l=Z[0]^S4[x[ 0]]^S5[x[ 2]]^S6[x[ 1]]^S7[x[ 3]]^S7[z[ 2]];
+	CAST_exp(l,X,x, 4);
+	l=Z[1]^S4[x[ 7]]^S5[x[ 6]]^S6[x[ 5]]^S7[x[ 4]]^S4[z[ 1]];
+	CAST_exp(l,X,x, 8);
+	l=Z[3]^S4[x[10]]^S5[x[ 9]]^S6[x[11]]^S7[x[ 8]]^S5[z[ 3]];
+	CAST_exp(l,X,x,12);
+
+	K[12]= S4[x[ 8]]^S5[x[ 9]]^S6[x[ 7]]^S7[x[ 6]]^S4[x[ 3]];
+	K[13]= S4[x[10]]^S5[x[11]]^S6[x[ 5]]^S7[x[ 4]]^S5[x[ 7]];
+	K[14]= S4[x[12]]^S5[x[13]]^S6[x[ 3]]^S7[x[ 2]]^S6[x[ 8]];
+	K[15]= S4[x[14]]^S5[x[15]]^S6[x[ 1]]^S7[x[ 0]]^S7[x[13]];
+	if (K != k)  break;
+	K+=16;
+		}
+
+	for (i=0; i<16; i++)
+		{
+		key->data[i*2]=k[i];
+		key->data[i*2+1]=((k[i+16])+16)&0x1f;
+		}
+	}
+
diff --git a/crypto/libressl/crypto/cast/cast_lcl.h b/crypto/libressl/crypto/cast/cast_lcl.h
new file mode 100644
index 0000000000..cb8d848b8b
--- /dev/null
+++ b/crypto/libressl/crypto/cast/cast_lcl.h
@@ -0,0 +1,216 @@
+/* $OpenBSD: cast_lcl.h,v 1.10 2014/06/12 15:49:28 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#undef c2l
+#define c2l(c,l)	(l =((unsigned long)(*((c)++)))    , \
+			 l|=((unsigned long)(*((c)++)))<< 8L, \
+			 l|=((unsigned long)(*((c)++)))<<16L, \
+			 l|=((unsigned long)(*((c)++)))<<24L)
+
+/* NOTE - c is not incremented as per c2l */
+#undef c2ln
+#define c2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
+			case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
+			case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
+			case 5: l2|=((unsigned long)(*(--(c))));     \
+			case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
+			case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
+			case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
+			case 1: l1|=((unsigned long)(*(--(c))));     \
+				} \
+			}
+
+#undef l2c
+#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+#undef l2cn
+#define l2cn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
+				} \
+			}
+
+/* NOTE - c is not incremented as per n2l */
+#define n2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))    ; \
+			case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
+			case 6: l2|=((unsigned long)(*(--(c))))<<16; \
+			case 5: l2|=((unsigned long)(*(--(c))))<<24; \
+			case 4: l1 =((unsigned long)(*(--(c))))    ; \
+			case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
+			case 2: l1|=((unsigned long)(*(--(c))))<<16; \
+			case 1: l1|=((unsigned long)(*(--(c))))<<24; \
+				} \
+			}
+
+/* NOTE - c is not incremented as per l2n */
+#define l2nn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+				} \
+			}
+
+#undef n2l
+#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
+                         l|=((unsigned long)(*((c)++)))<<16L, \
+                         l|=((unsigned long)(*((c)++)))<< 8L, \
+                         l|=((unsigned long)(*((c)++))))
+
+#undef l2n
+#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)     )&0xff))
+
+/* only invoked with 0 <= n <= 31 */
+#define ROTL(a,n)     ((((a)<<(n))&0xffffffffL)|((a)>>(32-(n))))
+
+#define C_M    0x3fc
+#define C_0    22L
+#define C_1    14L
+#define C_2     6L
+#define C_3     2L /* left shift */
+
+/* The rotate has an extra 16 added to it to help the x86 asm */
+#if defined(CAST_PTR)
+#define E_CAST(n,key,L,R,OP1,OP2,OP3) \
+	{ \
+	int i; \
+	t=(key[n*2] OP1 R)&0xffffffffL; \
+	i=key[n*2+1]; \
+	t=ROTL(t,i); \
+	L^= (((((*(CAST_LONG *)((unsigned char *) \
+			CAST_S_table0+((t>>C_2)&C_M)) OP2 \
+		*(CAST_LONG *)((unsigned char *) \
+			CAST_S_table1+((t<>C_0)&C_M)))&0xffffffffL) OP1 \
+		*(CAST_LONG *)((unsigned char *) \
+			CAST_S_table3+((t>>C_1)&C_M)))&0xffffffffL; \
+	}
+#elif defined(CAST_PTR2)
+#define E_CAST(n,key,L,R,OP1,OP2,OP3) \
+	{ \
+	int i; \
+	CAST_LONG u,v,w; \
+	w=(key[n*2] OP1 R)&0xffffffffL; \
+	i=key[n*2+1]; \
+	w=ROTL(w,i); \
+	u=w>>C_2; \
+	v=w<>C_0; \
+	t=(t OP2 *(CAST_LONG *)((unsigned char *)CAST_S_table1+v))&0xffffffffL;\
+	v=w>>C_1; \
+	u&=C_M; \
+	v&=C_M; \
+	t=(t OP3 *(CAST_LONG *)((unsigned char *)CAST_S_table2+u)&0xffffffffL);\
+	t=(t OP1 *(CAST_LONG *)((unsigned char *)CAST_S_table3+v)&0xffffffffL);\
+	L^=(t&0xffffffff); \
+	}
+#else
+#define E_CAST(n,key,L,R,OP1,OP2,OP3) \
+	{ \
+	CAST_LONG a,b,c,d; \
+	t=(key[n*2] OP1 R)&0xffffffff; \
+	t=ROTL(t,(key[n*2+1])); \
+	a=CAST_S_table0[(t>> 8)&0xff]; \
+	b=CAST_S_table1[(t    )&0xff]; \
+	c=CAST_S_table2[(t>>24)&0xff]; \
+	d=CAST_S_table3[(t>>16)&0xff]; \
+	L^=(((((a OP2 b)&0xffffffffL) OP3 c)&0xffffffffL) OP1 d)&0xffffffffL; \
+	}
+#endif
+
+extern const CAST_LONG CAST_S_table0[256];
+extern const CAST_LONG CAST_S_table1[256];
+extern const CAST_LONG CAST_S_table2[256];
+extern const CAST_LONG CAST_S_table3[256];
+extern const CAST_LONG CAST_S_table4[256];
+extern const CAST_LONG CAST_S_table5[256];
+extern const CAST_LONG CAST_S_table6[256];
+extern const CAST_LONG CAST_S_table7[256];
diff --git a/crypto/libressl/crypto/cast/cast_s.h b/crypto/libressl/crypto/cast/cast_s.h
new file mode 100644
index 0000000000..3f05cb9b4e
--- /dev/null
+++ b/crypto/libressl/crypto/cast/cast_s.h
@@ -0,0 +1,585 @@
+/* $OpenBSD$ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+const CAST_LONG CAST_S_table0[256]={
+	0x30fb40d4,0x9fa0ff0b,0x6beccd2f,0x3f258c7a,
+	0x1e213f2f,0x9c004dd3,0x6003e540,0xcf9fc949,
+	0xbfd4af27,0x88bbbdb5,0xe2034090,0x98d09675,
+	0x6e63a0e0,0x15c361d2,0xc2e7661d,0x22d4ff8e,
+	0x28683b6f,0xc07fd059,0xff2379c8,0x775f50e2,
+	0x43c340d3,0xdf2f8656,0x887ca41a,0xa2d2bd2d,
+	0xa1c9e0d6,0x346c4819,0x61b76d87,0x22540f2f,
+	0x2abe32e1,0xaa54166b,0x22568e3a,0xa2d341d0,
+	0x66db40c8,0xa784392f,0x004dff2f,0x2db9d2de,
+	0x97943fac,0x4a97c1d8,0x527644b7,0xb5f437a7,
+	0xb82cbaef,0xd751d159,0x6ff7f0ed,0x5a097a1f,
+	0x827b68d0,0x90ecf52e,0x22b0c054,0xbc8e5935,
+	0x4b6d2f7f,0x50bb64a2,0xd2664910,0xbee5812d,
+	0xb7332290,0xe93b159f,0xb48ee411,0x4bff345d,
+	0xfd45c240,0xad31973f,0xc4f6d02e,0x55fc8165,
+	0xd5b1caad,0xa1ac2dae,0xa2d4b76d,0xc19b0c50,
+	0x882240f2,0x0c6e4f38,0xa4e4bfd7,0x4f5ba272,
+	0x564c1d2f,0xc59c5319,0xb949e354,0xb04669fe,
+	0xb1b6ab8a,0xc71358dd,0x6385c545,0x110f935d,
+	0x57538ad5,0x6a390493,0xe63d37e0,0x2a54f6b3,
+	0x3a787d5f,0x6276a0b5,0x19a6fcdf,0x7a42206a,
+	0x29f9d4d5,0xf61b1891,0xbb72275e,0xaa508167,
+	0x38901091,0xc6b505eb,0x84c7cb8c,0x2ad75a0f,
+	0x874a1427,0xa2d1936b,0x2ad286af,0xaa56d291,
+	0xd7894360,0x425c750d,0x93b39e26,0x187184c9,
+	0x6c00b32d,0x73e2bb14,0xa0bebc3c,0x54623779,
+	0x64459eab,0x3f328b82,0x7718cf82,0x59a2cea6,
+	0x04ee002e,0x89fe78e6,0x3fab0950,0x325ff6c2,
+	0x81383f05,0x6963c5c8,0x76cb5ad6,0xd49974c9,
+	0xca180dcf,0x380782d5,0xc7fa5cf6,0x8ac31511,
+	0x35e79e13,0x47da91d0,0xf40f9086,0xa7e2419e,
+	0x31366241,0x051ef495,0xaa573b04,0x4a805d8d,
+	0x548300d0,0x00322a3c,0xbf64cddf,0xba57a68e,
+	0x75c6372b,0x50afd341,0xa7c13275,0x915a0bf5,
+	0x6b54bfab,0x2b0b1426,0xab4cc9d7,0x449ccd82,
+	0xf7fbf265,0xab85c5f3,0x1b55db94,0xaad4e324,
+	0xcfa4bd3f,0x2deaa3e2,0x9e204d02,0xc8bd25ac,
+	0xeadf55b3,0xd5bd9e98,0xe31231b2,0x2ad5ad6c,
+	0x954329de,0xadbe4528,0xd8710f69,0xaa51c90f,
+	0xaa786bf6,0x22513f1e,0xaa51a79b,0x2ad344cc,
+	0x7b5a41f0,0xd37cfbad,0x1b069505,0x41ece491,
+	0xb4c332e6,0x032268d4,0xc9600acc,0xce387e6d,
+	0xbf6bb16c,0x6a70fb78,0x0d03d9c9,0xd4df39de,
+	0xe01063da,0x4736f464,0x5ad328d8,0xb347cc96,
+	0x75bb0fc3,0x98511bfb,0x4ffbcc35,0xb58bcf6a,
+	0xe11f0abc,0xbfc5fe4a,0xa70aec10,0xac39570a,
+	0x3f04442f,0x6188b153,0xe0397a2e,0x5727cb79,
+	0x9ceb418f,0x1cacd68d,0x2ad37c96,0x0175cb9d,
+	0xc69dff09,0xc75b65f0,0xd9db40d8,0xec0e7779,
+	0x4744ead4,0xb11c3274,0xdd24cb9e,0x7e1c54bd,
+	0xf01144f9,0xd2240eb1,0x9675b3fd,0xa3ac3755,
+	0xd47c27af,0x51c85f4d,0x56907596,0xa5bb15e6,
+	0x580304f0,0xca042cf1,0x011a37ea,0x8dbfaadb,
+	0x35ba3e4a,0x3526ffa0,0xc37b4d09,0xbc306ed9,
+	0x98a52666,0x5648f725,0xff5e569d,0x0ced63d0,
+	0x7c63b2cf,0x700b45e1,0xd5ea50f1,0x85a92872,
+	0xaf1fbda7,0xd4234870,0xa7870bf3,0x2d3b4d79,
+	0x42e04198,0x0cd0ede7,0x26470db8,0xf881814c,
+	0x474d6ad7,0x7c0c5e5c,0xd1231959,0x381b7298,
+	0xf5d2f4db,0xab838653,0x6e2f1e23,0x83719c9e,
+	0xbd91e046,0x9a56456e,0xdc39200c,0x20c8c571,
+	0x962bda1c,0xe1e696ff,0xb141ab08,0x7cca89b9,
+	0x1a69e783,0x02cc4843,0xa2f7c579,0x429ef47d,
+	0x427b169c,0x5ac9f049,0xdd8f0f00,0x5c8165bf,
+	};
+const CAST_LONG CAST_S_table1[256]={
+	0x1f201094,0xef0ba75b,0x69e3cf7e,0x393f4380,
+	0xfe61cf7a,0xeec5207a,0x55889c94,0x72fc0651,
+	0xada7ef79,0x4e1d7235,0xd55a63ce,0xde0436ba,
+	0x99c430ef,0x5f0c0794,0x18dcdb7d,0xa1d6eff3,
+	0xa0b52f7b,0x59e83605,0xee15b094,0xe9ffd909,
+	0xdc440086,0xef944459,0xba83ccb3,0xe0c3cdfb,
+	0xd1da4181,0x3b092ab1,0xf997f1c1,0xa5e6cf7b,
+	0x01420ddb,0xe4e7ef5b,0x25a1ff41,0xe180f806,
+	0x1fc41080,0x179bee7a,0xd37ac6a9,0xfe5830a4,
+	0x98de8b7f,0x77e83f4e,0x79929269,0x24fa9f7b,
+	0xe113c85b,0xacc40083,0xd7503525,0xf7ea615f,
+	0x62143154,0x0d554b63,0x5d681121,0xc866c359,
+	0x3d63cf73,0xcee234c0,0xd4d87e87,0x5c672b21,
+	0x071f6181,0x39f7627f,0x361e3084,0xe4eb573b,
+	0x602f64a4,0xd63acd9c,0x1bbc4635,0x9e81032d,
+	0x2701f50c,0x99847ab4,0xa0e3df79,0xba6cf38c,
+	0x10843094,0x2537a95e,0xf46f6ffe,0xa1ff3b1f,
+	0x208cfb6a,0x8f458c74,0xd9e0a227,0x4ec73a34,
+	0xfc884f69,0x3e4de8df,0xef0e0088,0x3559648d,
+	0x8a45388c,0x1d804366,0x721d9bfd,0xa58684bb,
+	0xe8256333,0x844e8212,0x128d8098,0xfed33fb4,
+	0xce280ae1,0x27e19ba5,0xd5a6c252,0xe49754bd,
+	0xc5d655dd,0xeb667064,0x77840b4d,0xa1b6a801,
+	0x84db26a9,0xe0b56714,0x21f043b7,0xe5d05860,
+	0x54f03084,0x066ff472,0xa31aa153,0xdadc4755,
+	0xb5625dbf,0x68561be6,0x83ca6b94,0x2d6ed23b,
+	0xeccf01db,0xa6d3d0ba,0xb6803d5c,0xaf77a709,
+	0x33b4a34c,0x397bc8d6,0x5ee22b95,0x5f0e5304,
+	0x81ed6f61,0x20e74364,0xb45e1378,0xde18639b,
+	0x881ca122,0xb96726d1,0x8049a7e8,0x22b7da7b,
+	0x5e552d25,0x5272d237,0x79d2951c,0xc60d894c,
+	0x488cb402,0x1ba4fe5b,0xa4b09f6b,0x1ca815cf,
+	0xa20c3005,0x8871df63,0xb9de2fcb,0x0cc6c9e9,
+	0x0beeff53,0xe3214517,0xb4542835,0x9f63293c,
+	0xee41e729,0x6e1d2d7c,0x50045286,0x1e6685f3,
+	0xf33401c6,0x30a22c95,0x31a70850,0x60930f13,
+	0x73f98417,0xa1269859,0xec645c44,0x52c877a9,
+	0xcdff33a6,0xa02b1741,0x7cbad9a2,0x2180036f,
+	0x50d99c08,0xcb3f4861,0xc26bd765,0x64a3f6ab,
+	0x80342676,0x25a75e7b,0xe4e6d1fc,0x20c710e6,
+	0xcdf0b680,0x17844d3b,0x31eef84d,0x7e0824e4,
+	0x2ccb49eb,0x846a3bae,0x8ff77888,0xee5d60f6,
+	0x7af75673,0x2fdd5cdb,0xa11631c1,0x30f66f43,
+	0xb3faec54,0x157fd7fa,0xef8579cc,0xd152de58,
+	0xdb2ffd5e,0x8f32ce19,0x306af97a,0x02f03ef8,
+	0x99319ad5,0xc242fa0f,0xa7e3ebb0,0xc68e4906,
+	0xb8da230c,0x80823028,0xdcdef3c8,0xd35fb171,
+	0x088a1bc8,0xbec0c560,0x61a3c9e8,0xbca8f54d,
+	0xc72feffa,0x22822e99,0x82c570b4,0xd8d94e89,
+	0x8b1c34bc,0x301e16e6,0x273be979,0xb0ffeaa6,
+	0x61d9b8c6,0x00b24869,0xb7ffce3f,0x08dc283b,
+	0x43daf65a,0xf7e19798,0x7619b72f,0x8f1c9ba4,
+	0xdc8637a0,0x16a7d3b1,0x9fc393b7,0xa7136eeb,
+	0xc6bcc63e,0x1a513742,0xef6828bc,0x520365d6,
+	0x2d6a77ab,0x3527ed4b,0x821fd216,0x095c6e2e,
+	0xdb92f2fb,0x5eea29cb,0x145892f5,0x91584f7f,
+	0x5483697b,0x2667a8cc,0x85196048,0x8c4bacea,
+	0x833860d4,0x0d23e0f9,0x6c387e8a,0x0ae6d249,
+	0xb284600c,0xd835731d,0xdcb1c647,0xac4c56ea,
+	0x3ebd81b3,0x230eabb0,0x6438bc87,0xf0b5b1fa,
+	0x8f5ea2b3,0xfc184642,0x0a036b7a,0x4fb089bd,
+	0x649da589,0xa345415e,0x5c038323,0x3e5d3bb9,
+	0x43d79572,0x7e6dd07c,0x06dfdf1e,0x6c6cc4ef,
+	0x7160a539,0x73bfbe70,0x83877605,0x4523ecf1,
+	};
+const CAST_LONG CAST_S_table2[256]={
+	0x8defc240,0x25fa5d9f,0xeb903dbf,0xe810c907,
+	0x47607fff,0x369fe44b,0x8c1fc644,0xaececa90,
+	0xbeb1f9bf,0xeefbcaea,0xe8cf1950,0x51df07ae,
+	0x920e8806,0xf0ad0548,0xe13c8d83,0x927010d5,
+	0x11107d9f,0x07647db9,0xb2e3e4d4,0x3d4f285e,
+	0xb9afa820,0xfade82e0,0xa067268b,0x8272792e,
+	0x553fb2c0,0x489ae22b,0xd4ef9794,0x125e3fbc,
+	0x21fffcee,0x825b1bfd,0x9255c5ed,0x1257a240,
+	0x4e1a8302,0xbae07fff,0x528246e7,0x8e57140e,
+	0x3373f7bf,0x8c9f8188,0xa6fc4ee8,0xc982b5a5,
+	0xa8c01db7,0x579fc264,0x67094f31,0xf2bd3f5f,
+	0x40fff7c1,0x1fb78dfc,0x8e6bd2c1,0x437be59b,
+	0x99b03dbf,0xb5dbc64b,0x638dc0e6,0x55819d99,
+	0xa197c81c,0x4a012d6e,0xc5884a28,0xccc36f71,
+	0xb843c213,0x6c0743f1,0x8309893c,0x0feddd5f,
+	0x2f7fe850,0xd7c07f7e,0x02507fbf,0x5afb9a04,
+	0xa747d2d0,0x1651192e,0xaf70bf3e,0x58c31380,
+	0x5f98302e,0x727cc3c4,0x0a0fb402,0x0f7fef82,
+	0x8c96fdad,0x5d2c2aae,0x8ee99a49,0x50da88b8,
+	0x8427f4a0,0x1eac5790,0x796fb449,0x8252dc15,
+	0xefbd7d9b,0xa672597d,0xada840d8,0x45f54504,
+	0xfa5d7403,0xe83ec305,0x4f91751a,0x925669c2,
+	0x23efe941,0xa903f12e,0x60270df2,0x0276e4b6,
+	0x94fd6574,0x927985b2,0x8276dbcb,0x02778176,
+	0xf8af918d,0x4e48f79e,0x8f616ddf,0xe29d840e,
+	0x842f7d83,0x340ce5c8,0x96bbb682,0x93b4b148,
+	0xef303cab,0x984faf28,0x779faf9b,0x92dc560d,
+	0x224d1e20,0x8437aa88,0x7d29dc96,0x2756d3dc,
+	0x8b907cee,0xb51fd240,0xe7c07ce3,0xe566b4a1,
+	0xc3e9615e,0x3cf8209d,0x6094d1e3,0xcd9ca341,
+	0x5c76460e,0x00ea983b,0xd4d67881,0xfd47572c,
+	0xf76cedd9,0xbda8229c,0x127dadaa,0x438a074e,
+	0x1f97c090,0x081bdb8a,0x93a07ebe,0xb938ca15,
+	0x97b03cff,0x3dc2c0f8,0x8d1ab2ec,0x64380e51,
+	0x68cc7bfb,0xd90f2788,0x12490181,0x5de5ffd4,
+	0xdd7ef86a,0x76a2e214,0xb9a40368,0x925d958f,
+	0x4b39fffa,0xba39aee9,0xa4ffd30b,0xfaf7933b,
+	0x6d498623,0x193cbcfa,0x27627545,0x825cf47a,
+	0x61bd8ba0,0xd11e42d1,0xcead04f4,0x127ea392,
+	0x10428db7,0x8272a972,0x9270c4a8,0x127de50b,
+	0x285ba1c8,0x3c62f44f,0x35c0eaa5,0xe805d231,
+	0x428929fb,0xb4fcdf82,0x4fb66a53,0x0e7dc15b,
+	0x1f081fab,0x108618ae,0xfcfd086d,0xf9ff2889,
+	0x694bcc11,0x236a5cae,0x12deca4d,0x2c3f8cc5,
+	0xd2d02dfe,0xf8ef5896,0xe4cf52da,0x95155b67,
+	0x494a488c,0xb9b6a80c,0x5c8f82bc,0x89d36b45,
+	0x3a609437,0xec00c9a9,0x44715253,0x0a874b49,
+	0xd773bc40,0x7c34671c,0x02717ef6,0x4feb5536,
+	0xa2d02fff,0xd2bf60c4,0xd43f03c0,0x50b4ef6d,
+	0x07478cd1,0x006e1888,0xa2e53f55,0xb9e6d4bc,
+	0xa2048016,0x97573833,0xd7207d67,0xde0f8f3d,
+	0x72f87b33,0xabcc4f33,0x7688c55d,0x7b00a6b0,
+	0x947b0001,0x570075d2,0xf9bb88f8,0x8942019e,
+	0x4264a5ff,0x856302e0,0x72dbd92b,0xee971b69,
+	0x6ea22fde,0x5f08ae2b,0xaf7a616d,0xe5c98767,
+	0xcf1febd2,0x61efc8c2,0xf1ac2571,0xcc8239c2,
+	0x67214cb8,0xb1e583d1,0xb7dc3e62,0x7f10bdce,
+	0xf90a5c38,0x0ff0443d,0x606e6dc6,0x60543a49,
+	0x5727c148,0x2be98a1d,0x8ab41738,0x20e1be24,
+	0xaf96da0f,0x68458425,0x99833be5,0x600d457d,
+	0x282f9350,0x8334b362,0xd91d1120,0x2b6d8da0,
+	0x642b1e31,0x9c305a00,0x52bce688,0x1b03588a,
+	0xf7baefd5,0x4142ed9c,0xa4315c11,0x83323ec5,
+	0xdfef4636,0xa133c501,0xe9d3531c,0xee353783,
+	};
+const CAST_LONG CAST_S_table3[256]={
+	0x9db30420,0x1fb6e9de,0xa7be7bef,0xd273a298,
+	0x4a4f7bdb,0x64ad8c57,0x85510443,0xfa020ed1,
+	0x7e287aff,0xe60fb663,0x095f35a1,0x79ebf120,
+	0xfd059d43,0x6497b7b1,0xf3641f63,0x241e4adf,
+	0x28147f5f,0x4fa2b8cd,0xc9430040,0x0cc32220,
+	0xfdd30b30,0xc0a5374f,0x1d2d00d9,0x24147b15,
+	0xee4d111a,0x0fca5167,0x71ff904c,0x2d195ffe,
+	0x1a05645f,0x0c13fefe,0x081b08ca,0x05170121,
+	0x80530100,0xe83e5efe,0xac9af4f8,0x7fe72701,
+	0xd2b8ee5f,0x06df4261,0xbb9e9b8a,0x7293ea25,
+	0xce84ffdf,0xf5718801,0x3dd64b04,0xa26f263b,
+	0x7ed48400,0x547eebe6,0x446d4ca0,0x6cf3d6f5,
+	0x2649abdf,0xaea0c7f5,0x36338cc1,0x503f7e93,
+	0xd3772061,0x11b638e1,0x72500e03,0xf80eb2bb,
+	0xabe0502e,0xec8d77de,0x57971e81,0xe14f6746,
+	0xc9335400,0x6920318f,0x081dbb99,0xffc304a5,
+	0x4d351805,0x7f3d5ce3,0xa6c866c6,0x5d5bcca9,
+	0xdaec6fea,0x9f926f91,0x9f46222f,0x3991467d,
+	0xa5bf6d8e,0x1143c44f,0x43958302,0xd0214eeb,
+	0x022083b8,0x3fb6180c,0x18f8931e,0x281658e6,
+	0x26486e3e,0x8bd78a70,0x7477e4c1,0xb506e07c,
+	0xf32d0a25,0x79098b02,0xe4eabb81,0x28123b23,
+	0x69dead38,0x1574ca16,0xdf871b62,0x211c40b7,
+	0xa51a9ef9,0x0014377b,0x041e8ac8,0x09114003,
+	0xbd59e4d2,0xe3d156d5,0x4fe876d5,0x2f91a340,
+	0x557be8de,0x00eae4a7,0x0ce5c2ec,0x4db4bba6,
+	0xe756bdff,0xdd3369ac,0xec17b035,0x06572327,
+	0x99afc8b0,0x56c8c391,0x6b65811c,0x5e146119,
+	0x6e85cb75,0xbe07c002,0xc2325577,0x893ff4ec,
+	0x5bbfc92d,0xd0ec3b25,0xb7801ab7,0x8d6d3b24,
+	0x20c763ef,0xc366a5fc,0x9c382880,0x0ace3205,
+	0xaac9548a,0xeca1d7c7,0x041afa32,0x1d16625a,
+	0x6701902c,0x9b757a54,0x31d477f7,0x9126b031,
+	0x36cc6fdb,0xc70b8b46,0xd9e66a48,0x56e55a79,
+	0x026a4ceb,0x52437eff,0x2f8f76b4,0x0df980a5,
+	0x8674cde3,0xedda04eb,0x17a9be04,0x2c18f4df,
+	0xb7747f9d,0xab2af7b4,0xefc34d20,0x2e096b7c,
+	0x1741a254,0xe5b6a035,0x213d42f6,0x2c1c7c26,
+	0x61c2f50f,0x6552daf9,0xd2c231f8,0x25130f69,
+	0xd8167fa2,0x0418f2c8,0x001a96a6,0x0d1526ab,
+	0x63315c21,0x5e0a72ec,0x49bafefd,0x187908d9,
+	0x8d0dbd86,0x311170a7,0x3e9b640c,0xcc3e10d7,
+	0xd5cad3b6,0x0caec388,0xf73001e1,0x6c728aff,
+	0x71eae2a1,0x1f9af36e,0xcfcbd12f,0xc1de8417,
+	0xac07be6b,0xcb44a1d8,0x8b9b0f56,0x013988c3,
+	0xb1c52fca,0xb4be31cd,0xd8782806,0x12a3a4e2,
+	0x6f7de532,0x58fd7eb6,0xd01ee900,0x24adffc2,
+	0xf4990fc5,0x9711aac5,0x001d7b95,0x82e5e7d2,
+	0x109873f6,0x00613096,0xc32d9521,0xada121ff,
+	0x29908415,0x7fbb977f,0xaf9eb3db,0x29c9ed2a,
+	0x5ce2a465,0xa730f32c,0xd0aa3fe8,0x8a5cc091,
+	0xd49e2ce7,0x0ce454a9,0xd60acd86,0x015f1919,
+	0x77079103,0xdea03af6,0x78a8565e,0xdee356df,
+	0x21f05cbe,0x8b75e387,0xb3c50651,0xb8a5c3ef,
+	0xd8eeb6d2,0xe523be77,0xc2154529,0x2f69efdf,
+	0xafe67afb,0xf470c4b2,0xf3e0eb5b,0xd6cc9876,
+	0x39e4460c,0x1fda8538,0x1987832f,0xca007367,
+	0xa99144f8,0x296b299e,0x492fc295,0x9266beab,
+	0xb5676e69,0x9bd3ddda,0xdf7e052f,0xdb25701c,
+	0x1b5e51ee,0xf65324e6,0x6afce36c,0x0316cc04,
+	0x8644213e,0xb7dc59d0,0x7965291f,0xccd6fd43,
+	0x41823979,0x932bcdf6,0xb657c34d,0x4edfd282,
+	0x7ae5290c,0x3cb9536b,0x851e20fe,0x9833557e,
+	0x13ecf0b0,0xd3ffb372,0x3f85c5c1,0x0aef7ed2,
+	};
+const CAST_LONG CAST_S_table4[256]={
+	0x7ec90c04,0x2c6e74b9,0x9b0e66df,0xa6337911,
+	0xb86a7fff,0x1dd358f5,0x44dd9d44,0x1731167f,
+	0x08fbf1fa,0xe7f511cc,0xd2051b00,0x735aba00,
+	0x2ab722d8,0x386381cb,0xacf6243a,0x69befd7a,
+	0xe6a2e77f,0xf0c720cd,0xc4494816,0xccf5c180,
+	0x38851640,0x15b0a848,0xe68b18cb,0x4caadeff,
+	0x5f480a01,0x0412b2aa,0x259814fc,0x41d0efe2,
+	0x4e40b48d,0x248eb6fb,0x8dba1cfe,0x41a99b02,
+	0x1a550a04,0xba8f65cb,0x7251f4e7,0x95a51725,
+	0xc106ecd7,0x97a5980a,0xc539b9aa,0x4d79fe6a,
+	0xf2f3f763,0x68af8040,0xed0c9e56,0x11b4958b,
+	0xe1eb5a88,0x8709e6b0,0xd7e07156,0x4e29fea7,
+	0x6366e52d,0x02d1c000,0xc4ac8e05,0x9377f571,
+	0x0c05372a,0x578535f2,0x2261be02,0xd642a0c9,
+	0xdf13a280,0x74b55bd2,0x682199c0,0xd421e5ec,
+	0x53fb3ce8,0xc8adedb3,0x28a87fc9,0x3d959981,
+	0x5c1ff900,0xfe38d399,0x0c4eff0b,0x062407ea,
+	0xaa2f4fb1,0x4fb96976,0x90c79505,0xb0a8a774,
+	0xef55a1ff,0xe59ca2c2,0xa6b62d27,0xe66a4263,
+	0xdf65001f,0x0ec50966,0xdfdd55bc,0x29de0655,
+	0x911e739a,0x17af8975,0x32c7911c,0x89f89468,
+	0x0d01e980,0x524755f4,0x03b63cc9,0x0cc844b2,
+	0xbcf3f0aa,0x87ac36e9,0xe53a7426,0x01b3d82b,
+	0x1a9e7449,0x64ee2d7e,0xcddbb1da,0x01c94910,
+	0xb868bf80,0x0d26f3fd,0x9342ede7,0x04a5c284,
+	0x636737b6,0x50f5b616,0xf24766e3,0x8eca36c1,
+	0x136e05db,0xfef18391,0xfb887a37,0xd6e7f7d4,
+	0xc7fb7dc9,0x3063fcdf,0xb6f589de,0xec2941da,
+	0x26e46695,0xb7566419,0xf654efc5,0xd08d58b7,
+	0x48925401,0xc1bacb7f,0xe5ff550f,0xb6083049,
+	0x5bb5d0e8,0x87d72e5a,0xab6a6ee1,0x223a66ce,
+	0xc62bf3cd,0x9e0885f9,0x68cb3e47,0x086c010f,
+	0xa21de820,0xd18b69de,0xf3f65777,0xfa02c3f6,
+	0x407edac3,0xcbb3d550,0x1793084d,0xb0d70eba,
+	0x0ab378d5,0xd951fb0c,0xded7da56,0x4124bbe4,
+	0x94ca0b56,0x0f5755d1,0xe0e1e56e,0x6184b5be,
+	0x580a249f,0x94f74bc0,0xe327888e,0x9f7b5561,
+	0xc3dc0280,0x05687715,0x646c6bd7,0x44904db3,
+	0x66b4f0a3,0xc0f1648a,0x697ed5af,0x49e92ff6,
+	0x309e374f,0x2cb6356a,0x85808573,0x4991f840,
+	0x76f0ae02,0x083be84d,0x28421c9a,0x44489406,
+	0x736e4cb8,0xc1092910,0x8bc95fc6,0x7d869cf4,
+	0x134f616f,0x2e77118d,0xb31b2be1,0xaa90b472,
+	0x3ca5d717,0x7d161bba,0x9cad9010,0xaf462ba2,
+	0x9fe459d2,0x45d34559,0xd9f2da13,0xdbc65487,
+	0xf3e4f94e,0x176d486f,0x097c13ea,0x631da5c7,
+	0x445f7382,0x175683f4,0xcdc66a97,0x70be0288,
+	0xb3cdcf72,0x6e5dd2f3,0x20936079,0x459b80a5,
+	0xbe60e2db,0xa9c23101,0xeba5315c,0x224e42f2,
+	0x1c5c1572,0xf6721b2c,0x1ad2fff3,0x8c25404e,
+	0x324ed72f,0x4067b7fd,0x0523138e,0x5ca3bc78,
+	0xdc0fd66e,0x75922283,0x784d6b17,0x58ebb16e,
+	0x44094f85,0x3f481d87,0xfcfeae7b,0x77b5ff76,
+	0x8c2302bf,0xaaf47556,0x5f46b02a,0x2b092801,
+	0x3d38f5f7,0x0ca81f36,0x52af4a8a,0x66d5e7c0,
+	0xdf3b0874,0x95055110,0x1b5ad7a8,0xf61ed5ad,
+	0x6cf6e479,0x20758184,0xd0cefa65,0x88f7be58,
+	0x4a046826,0x0ff6f8f3,0xa09c7f70,0x5346aba0,
+	0x5ce96c28,0xe176eda3,0x6bac307f,0x376829d2,
+	0x85360fa9,0x17e3fe2a,0x24b79767,0xf5a96b20,
+	0xd6cd2595,0x68ff1ebf,0x7555442c,0xf19f06be,
+	0xf9e0659a,0xeeb9491d,0x34010718,0xbb30cab8,
+	0xe822fe15,0x88570983,0x750e6249,0xda627e55,
+	0x5e76ffa8,0xb1534546,0x6d47de08,0xefe9e7d4,
+	};
+const CAST_LONG CAST_S_table5[256]={
+	0xf6fa8f9d,0x2cac6ce1,0x4ca34867,0xe2337f7c,
+	0x95db08e7,0x016843b4,0xeced5cbc,0x325553ac,
+	0xbf9f0960,0xdfa1e2ed,0x83f0579d,0x63ed86b9,
+	0x1ab6a6b8,0xde5ebe39,0xf38ff732,0x8989b138,
+	0x33f14961,0xc01937bd,0xf506c6da,0xe4625e7e,
+	0xa308ea99,0x4e23e33c,0x79cbd7cc,0x48a14367,
+	0xa3149619,0xfec94bd5,0xa114174a,0xeaa01866,
+	0xa084db2d,0x09a8486f,0xa888614a,0x2900af98,
+	0x01665991,0xe1992863,0xc8f30c60,0x2e78ef3c,
+	0xd0d51932,0xcf0fec14,0xf7ca07d2,0xd0a82072,
+	0xfd41197e,0x9305a6b0,0xe86be3da,0x74bed3cd,
+	0x372da53c,0x4c7f4448,0xdab5d440,0x6dba0ec3,
+	0x083919a7,0x9fbaeed9,0x49dbcfb0,0x4e670c53,
+	0x5c3d9c01,0x64bdb941,0x2c0e636a,0xba7dd9cd,
+	0xea6f7388,0xe70bc762,0x35f29adb,0x5c4cdd8d,
+	0xf0d48d8c,0xb88153e2,0x08a19866,0x1ae2eac8,
+	0x284caf89,0xaa928223,0x9334be53,0x3b3a21bf,
+	0x16434be3,0x9aea3906,0xefe8c36e,0xf890cdd9,
+	0x80226dae,0xc340a4a3,0xdf7e9c09,0xa694a807,
+	0x5b7c5ecc,0x221db3a6,0x9a69a02f,0x68818a54,
+	0xceb2296f,0x53c0843a,0xfe893655,0x25bfe68a,
+	0xb4628abc,0xcf222ebf,0x25ac6f48,0xa9a99387,
+	0x53bddb65,0xe76ffbe7,0xe967fd78,0x0ba93563,
+	0x8e342bc1,0xe8a11be9,0x4980740d,0xc8087dfc,
+	0x8de4bf99,0xa11101a0,0x7fd37975,0xda5a26c0,
+	0xe81f994f,0x9528cd89,0xfd339fed,0xb87834bf,
+	0x5f04456d,0x22258698,0xc9c4c83b,0x2dc156be,
+	0x4f628daa,0x57f55ec5,0xe2220abe,0xd2916ebf,
+	0x4ec75b95,0x24f2c3c0,0x42d15d99,0xcd0d7fa0,
+	0x7b6e27ff,0xa8dc8af0,0x7345c106,0xf41e232f,
+	0x35162386,0xe6ea8926,0x3333b094,0x157ec6f2,
+	0x372b74af,0x692573e4,0xe9a9d848,0xf3160289,
+	0x3a62ef1d,0xa787e238,0xf3a5f676,0x74364853,
+	0x20951063,0x4576698d,0xb6fad407,0x592af950,
+	0x36f73523,0x4cfb6e87,0x7da4cec0,0x6c152daa,
+	0xcb0396a8,0xc50dfe5d,0xfcd707ab,0x0921c42f,
+	0x89dff0bb,0x5fe2be78,0x448f4f33,0x754613c9,
+	0x2b05d08d,0x48b9d585,0xdc049441,0xc8098f9b,
+	0x7dede786,0xc39a3373,0x42410005,0x6a091751,
+	0x0ef3c8a6,0x890072d6,0x28207682,0xa9a9f7be,
+	0xbf32679d,0xd45b5b75,0xb353fd00,0xcbb0e358,
+	0x830f220a,0x1f8fb214,0xd372cf08,0xcc3c4a13,
+	0x8cf63166,0x061c87be,0x88c98f88,0x6062e397,
+	0x47cf8e7a,0xb6c85283,0x3cc2acfb,0x3fc06976,
+	0x4e8f0252,0x64d8314d,0xda3870e3,0x1e665459,
+	0xc10908f0,0x513021a5,0x6c5b68b7,0x822f8aa0,
+	0x3007cd3e,0x74719eef,0xdc872681,0x073340d4,
+	0x7e432fd9,0x0c5ec241,0x8809286c,0xf592d891,
+	0x08a930f6,0x957ef305,0xb7fbffbd,0xc266e96f,
+	0x6fe4ac98,0xb173ecc0,0xbc60b42a,0x953498da,
+	0xfba1ae12,0x2d4bd736,0x0f25faab,0xa4f3fceb,
+	0xe2969123,0x257f0c3d,0x9348af49,0x361400bc,
+	0xe8816f4a,0x3814f200,0xa3f94043,0x9c7a54c2,
+	0xbc704f57,0xda41e7f9,0xc25ad33a,0x54f4a084,
+	0xb17f5505,0x59357cbe,0xedbd15c8,0x7f97c5ab,
+	0xba5ac7b5,0xb6f6deaf,0x3a479c3a,0x5302da25,
+	0x653d7e6a,0x54268d49,0x51a477ea,0x5017d55b,
+	0xd7d25d88,0x44136c76,0x0404a8c8,0xb8e5a121,
+	0xb81a928a,0x60ed5869,0x97c55b96,0xeaec991b,
+	0x29935913,0x01fdb7f1,0x088e8dfa,0x9ab6f6f5,
+	0x3b4cbf9f,0x4a5de3ab,0xe6051d35,0xa0e1d855,
+	0xd36b4cf1,0xf544edeb,0xb0e93524,0xbebb8fbd,
+	0xa2d762cf,0x49c92f54,0x38b5f331,0x7128a454,
+	0x48392905,0xa65b1db8,0x851c97bd,0xd675cf2f,
+	};
+const CAST_LONG CAST_S_table6[256]={
+	0x85e04019,0x332bf567,0x662dbfff,0xcfc65693,
+	0x2a8d7f6f,0xab9bc912,0xde6008a1,0x2028da1f,
+	0x0227bce7,0x4d642916,0x18fac300,0x50f18b82,
+	0x2cb2cb11,0xb232e75c,0x4b3695f2,0xb28707de,
+	0xa05fbcf6,0xcd4181e9,0xe150210c,0xe24ef1bd,
+	0xb168c381,0xfde4e789,0x5c79b0d8,0x1e8bfd43,
+	0x4d495001,0x38be4341,0x913cee1d,0x92a79c3f,
+	0x089766be,0xbaeeadf4,0x1286becf,0xb6eacb19,
+	0x2660c200,0x7565bde4,0x64241f7a,0x8248dca9,
+	0xc3b3ad66,0x28136086,0x0bd8dfa8,0x356d1cf2,
+	0x107789be,0xb3b2e9ce,0x0502aa8f,0x0bc0351e,
+	0x166bf52a,0xeb12ff82,0xe3486911,0xd34d7516,
+	0x4e7b3aff,0x5f43671b,0x9cf6e037,0x4981ac83,
+	0x334266ce,0x8c9341b7,0xd0d854c0,0xcb3a6c88,
+	0x47bc2829,0x4725ba37,0xa66ad22b,0x7ad61f1e,
+	0x0c5cbafa,0x4437f107,0xb6e79962,0x42d2d816,
+	0x0a961288,0xe1a5c06e,0x13749e67,0x72fc081a,
+	0xb1d139f7,0xf9583745,0xcf19df58,0xbec3f756,
+	0xc06eba30,0x07211b24,0x45c28829,0xc95e317f,
+	0xbc8ec511,0x38bc46e9,0xc6e6fa14,0xbae8584a,
+	0xad4ebc46,0x468f508b,0x7829435f,0xf124183b,
+	0x821dba9f,0xaff60ff4,0xea2c4e6d,0x16e39264,
+	0x92544a8b,0x009b4fc3,0xaba68ced,0x9ac96f78,
+	0x06a5b79a,0xb2856e6e,0x1aec3ca9,0xbe838688,
+	0x0e0804e9,0x55f1be56,0xe7e5363b,0xb3a1f25d,
+	0xf7debb85,0x61fe033c,0x16746233,0x3c034c28,
+	0xda6d0c74,0x79aac56c,0x3ce4e1ad,0x51f0c802,
+	0x98f8f35a,0x1626a49f,0xeed82b29,0x1d382fe3,
+	0x0c4fb99a,0xbb325778,0x3ec6d97b,0x6e77a6a9,
+	0xcb658b5c,0xd45230c7,0x2bd1408b,0x60c03eb7,
+	0xb9068d78,0xa33754f4,0xf430c87d,0xc8a71302,
+	0xb96d8c32,0xebd4e7be,0xbe8b9d2d,0x7979fb06,
+	0xe7225308,0x8b75cf77,0x11ef8da4,0xe083c858,
+	0x8d6b786f,0x5a6317a6,0xfa5cf7a0,0x5dda0033,
+	0xf28ebfb0,0xf5b9c310,0xa0eac280,0x08b9767a,
+	0xa3d9d2b0,0x79d34217,0x021a718d,0x9ac6336a,
+	0x2711fd60,0x438050e3,0x069908a8,0x3d7fedc4,
+	0x826d2bef,0x4eeb8476,0x488dcf25,0x36c9d566,
+	0x28e74e41,0xc2610aca,0x3d49a9cf,0xbae3b9df,
+	0xb65f8de6,0x92aeaf64,0x3ac7d5e6,0x9ea80509,
+	0xf22b017d,0xa4173f70,0xdd1e16c3,0x15e0d7f9,
+	0x50b1b887,0x2b9f4fd5,0x625aba82,0x6a017962,
+	0x2ec01b9c,0x15488aa9,0xd716e740,0x40055a2c,
+	0x93d29a22,0xe32dbf9a,0x058745b9,0x3453dc1e,
+	0xd699296e,0x496cff6f,0x1c9f4986,0xdfe2ed07,
+	0xb87242d1,0x19de7eae,0x053e561a,0x15ad6f8c,
+	0x66626c1c,0x7154c24c,0xea082b2a,0x93eb2939,
+	0x17dcb0f0,0x58d4f2ae,0x9ea294fb,0x52cf564c,
+	0x9883fe66,0x2ec40581,0x763953c3,0x01d6692e,
+	0xd3a0c108,0xa1e7160e,0xe4f2dfa6,0x693ed285,
+	0x74904698,0x4c2b0edd,0x4f757656,0x5d393378,
+	0xa132234f,0x3d321c5d,0xc3f5e194,0x4b269301,
+	0xc79f022f,0x3c997e7e,0x5e4f9504,0x3ffafbbd,
+	0x76f7ad0e,0x296693f4,0x3d1fce6f,0xc61e45be,
+	0xd3b5ab34,0xf72bf9b7,0x1b0434c0,0x4e72b567,
+	0x5592a33d,0xb5229301,0xcfd2a87f,0x60aeb767,
+	0x1814386b,0x30bcc33d,0x38a0c07d,0xfd1606f2,
+	0xc363519b,0x589dd390,0x5479f8e6,0x1cb8d647,
+	0x97fd61a9,0xea7759f4,0x2d57539d,0x569a58cf,
+	0xe84e63ad,0x462e1b78,0x6580f87e,0xf3817914,
+	0x91da55f4,0x40a230f3,0xd1988f35,0xb6e318d2,
+	0x3ffa50bc,0x3d40f021,0xc3c0bdae,0x4958c24c,
+	0x518f36b2,0x84b1d370,0x0fedce83,0x878ddada,
+	0xf2a279c7,0x94e01be8,0x90716f4b,0x954b8aa3,
+	};
+const CAST_LONG CAST_S_table7[256]={
+	0xe216300d,0xbbddfffc,0xa7ebdabd,0x35648095,
+	0x7789f8b7,0xe6c1121b,0x0e241600,0x052ce8b5,
+	0x11a9cfb0,0xe5952f11,0xece7990a,0x9386d174,
+	0x2a42931c,0x76e38111,0xb12def3a,0x37ddddfc,
+	0xde9adeb1,0x0a0cc32c,0xbe197029,0x84a00940,
+	0xbb243a0f,0xb4d137cf,0xb44e79f0,0x049eedfd,
+	0x0b15a15d,0x480d3168,0x8bbbde5a,0x669ded42,
+	0xc7ece831,0x3f8f95e7,0x72df191b,0x7580330d,
+	0x94074251,0x5c7dcdfa,0xabbe6d63,0xaa402164,
+	0xb301d40a,0x02e7d1ca,0x53571dae,0x7a3182a2,
+	0x12a8ddec,0xfdaa335d,0x176f43e8,0x71fb46d4,
+	0x38129022,0xce949ad4,0xb84769ad,0x965bd862,
+	0x82f3d055,0x66fb9767,0x15b80b4e,0x1d5b47a0,
+	0x4cfde06f,0xc28ec4b8,0x57e8726e,0x647a78fc,
+	0x99865d44,0x608bd593,0x6c200e03,0x39dc5ff6,
+	0x5d0b00a3,0xae63aff2,0x7e8bd632,0x70108c0c,
+	0xbbd35049,0x2998df04,0x980cf42a,0x9b6df491,
+	0x9e7edd53,0x06918548,0x58cb7e07,0x3b74ef2e,
+	0x522fffb1,0xd24708cc,0x1c7e27cd,0xa4eb215b,
+	0x3cf1d2e2,0x19b47a38,0x424f7618,0x35856039,
+	0x9d17dee7,0x27eb35e6,0xc9aff67b,0x36baf5b8,
+	0x09c467cd,0xc18910b1,0xe11dbf7b,0x06cd1af8,
+	0x7170c608,0x2d5e3354,0xd4de495a,0x64c6d006,
+	0xbcc0c62c,0x3dd00db3,0x708f8f34,0x77d51b42,
+	0x264f620f,0x24b8d2bf,0x15c1b79e,0x46a52564,
+	0xf8d7e54e,0x3e378160,0x7895cda5,0x859c15a5,
+	0xe6459788,0xc37bc75f,0xdb07ba0c,0x0676a3ab,
+	0x7f229b1e,0x31842e7b,0x24259fd7,0xf8bef472,
+	0x835ffcb8,0x6df4c1f2,0x96f5b195,0xfd0af0fc,
+	0xb0fe134c,0xe2506d3d,0x4f9b12ea,0xf215f225,
+	0xa223736f,0x9fb4c428,0x25d04979,0x34c713f8,
+	0xc4618187,0xea7a6e98,0x7cd16efc,0x1436876c,
+	0xf1544107,0xbedeee14,0x56e9af27,0xa04aa441,
+	0x3cf7c899,0x92ecbae6,0xdd67016d,0x151682eb,
+	0xa842eedf,0xfdba60b4,0xf1907b75,0x20e3030f,
+	0x24d8c29e,0xe139673b,0xefa63fb8,0x71873054,
+	0xb6f2cf3b,0x9f326442,0xcb15a4cc,0xb01a4504,
+	0xf1e47d8d,0x844a1be5,0xbae7dfdc,0x42cbda70,
+	0xcd7dae0a,0x57e85b7a,0xd53f5af6,0x20cf4d8c,
+	0xcea4d428,0x79d130a4,0x3486ebfb,0x33d3cddc,
+	0x77853b53,0x37effcb5,0xc5068778,0xe580b3e6,
+	0x4e68b8f4,0xc5c8b37e,0x0d809ea2,0x398feb7c,
+	0x132a4f94,0x43b7950e,0x2fee7d1c,0x223613bd,
+	0xdd06caa2,0x37df932b,0xc4248289,0xacf3ebc3,
+	0x5715f6b7,0xef3478dd,0xf267616f,0xc148cbe4,
+	0x9052815e,0x5e410fab,0xb48a2465,0x2eda7fa4,
+	0xe87b40e4,0xe98ea084,0x5889e9e1,0xefd390fc,
+	0xdd07d35b,0xdb485694,0x38d7e5b2,0x57720101,
+	0x730edebc,0x5b643113,0x94917e4f,0x503c2fba,
+	0x646f1282,0x7523d24a,0xe0779695,0xf9c17a8f,
+	0x7a5b2121,0xd187b896,0x29263a4d,0xba510cdf,
+	0x81f47c9f,0xad1163ed,0xea7b5965,0x1a00726e,
+	0x11403092,0x00da6d77,0x4a0cdd61,0xad1f4603,
+	0x605bdfb0,0x9eedc364,0x22ebe6a8,0xcee7d28a,
+	0xa0e736a0,0x5564a6b9,0x10853209,0xc7eb8f37,
+	0x2de705ca,0x8951570f,0xdf09822b,0xbd691a6c,
+	0xaa12e4f2,0x87451c0f,0xe0f6a27a,0x3ada4819,
+	0x4cf1764f,0x0d771c2b,0x67cdb156,0x350d8384,
+	0x5938fa0f,0x42399ef3,0x36997b07,0x0e84093d,
+	0x4aa93e61,0x8360d87b,0x1fa98b0c,0x1149382c,
+	0xe97625a5,0x0614d1b7,0x0e25244b,0x0c768347,
+	0x589e8d82,0x0d2059d1,0xa466bb1e,0xf8da0a82,
+	0x04f19130,0xba6e4ec0,0x99265164,0x1ee7230d,
+	0x50b2ad80,0xeaee6801,0x8db2a283,0xea8bf59e,
+	};
diff --git a/crypto/libressl/crypto/chacha/chacha-merged.c b/crypto/libressl/crypto/chacha/chacha-merged.c
new file mode 100644
index 0000000000..b6eaf854f1
--- /dev/null
+++ b/crypto/libressl/crypto/chacha/chacha-merged.c
@@ -0,0 +1,270 @@
+/* $OpenBSD: chacha-merged.c,v 1.6 2014/06/24 18:12:09 jsing Exp $ */
+/*
+chacha-merged.c version 20080118
+D. J. Bernstein
+Public domain.
+*/
+
+#include 
+
+#include 
+
+#define CHACHA_MINKEYLEN 	16
+#define CHACHA_NONCELEN		8
+#define CHACHA_CTRLEN		8
+#define CHACHA_STATELEN		(CHACHA_NONCELEN+CHACHA_CTRLEN)
+#define CHACHA_BLOCKLEN		64
+
+struct chacha_ctx {
+	u_int input[16];
+	uint8_t ks[CHACHA_BLOCKLEN];
+	uint8_t unused;
+};
+
+static inline void chacha_keysetup(struct chacha_ctx *x, const u_char *k,
+    u_int kbits)
+    __attribute__((__bounded__(__minbytes__, 2, CHACHA_MINKEYLEN)));
+static inline 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)));
+static inline 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)));
+
+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";
+
+static inline 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);
+}
+
+static inline 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);
+}
+
+static inline void
+chacha_encrypt_bytes(chacha_ctx *x, const u8 *m, u8 *c, u32 bytes)
+{
+	u32 x0, x1, x2, x3, x4, x5, x6, x7;
+	u32 x8, x9, x10, x11, x12, x13, x14, x15;
+	u32 j0, j1, j2, j3, j4, j5, j6, j7;
+	u32 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);
+
+		if (bytes < 64) {
+			U32TO8_LITTLE(x->ks + 0, x0);
+			U32TO8_LITTLE(x->ks + 4, x1);
+			U32TO8_LITTLE(x->ks + 8, x2);
+			U32TO8_LITTLE(x->ks + 12, x3);
+			U32TO8_LITTLE(x->ks + 16, x4);
+			U32TO8_LITTLE(x->ks + 20, x5);
+			U32TO8_LITTLE(x->ks + 24, x6);
+			U32TO8_LITTLE(x->ks + 28, x7);
+			U32TO8_LITTLE(x->ks + 32, x8);
+			U32TO8_LITTLE(x->ks + 36, x9);
+			U32TO8_LITTLE(x->ks + 40, x10);
+			U32TO8_LITTLE(x->ks + 44, x11);
+			U32TO8_LITTLE(x->ks + 48, x12);
+			U32TO8_LITTLE(x->ks + 52, x13);
+			U32TO8_LITTLE(x->ks + 56, x14);
+			U32TO8_LITTLE(x->ks + 60, x15);
+		}
+
+		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 the 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;
+			x->unused = 64 - bytes;
+			return;
+		}
+		bytes -= 64;
+		c += 64;
+		m += 64;
+	}
+}
diff --git a/crypto/libressl/crypto/chacha/chacha.c b/crypto/libressl/crypto/chacha/chacha.c
new file mode 100644
index 0000000000..00c5fbb837
--- /dev/null
+++ b/crypto/libressl/crypto/chacha/chacha.c
@@ -0,0 +1,77 @@
+/* $OpenBSD: chacha.c,v 1.6 2014/07/08 14:30:23 bcook Exp $ */
+/*
+ * Copyright (c) 2014 Joel Sing 
+ *
+ * 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 
+
+#include 
+
+#include "chacha-merged.c"
+
+void
+ChaCha_set_key(ChaCha_ctx *ctx, const unsigned char *key, uint32_t keybits)
+{
+	chacha_keysetup((chacha_ctx *)ctx, key, keybits);
+	ctx->unused = 0;
+}
+
+void
+ChaCha_set_iv(ChaCha_ctx *ctx, const unsigned char *iv,
+    const unsigned char *counter)
+{
+	chacha_ivsetup((chacha_ctx *)ctx, iv, counter);
+	ctx->unused = 0;
+}
+
+void
+ChaCha(ChaCha_ctx *ctx, unsigned char *out, const unsigned char *in, size_t len)
+{
+	unsigned char *k;
+	int i, l;
+
+	/* Consume remaining keystream, if any exists. */
+	if (ctx->unused > 0) {
+		k = ctx->ks + 64 - ctx->unused;
+		l = (len > ctx->unused) ? ctx->unused : len;
+		for (i = 0; i < l; i++)
+			*(out++) = *(in++) ^ *(k++);
+		ctx->unused -= l;
+		len -= l;
+	}
+
+	chacha_encrypt_bytes((chacha_ctx *)ctx, in, out, (uint32_t)len);
+}
+
+void
+CRYPTO_chacha_20(unsigned char *out, const unsigned char *in, size_t len,
+    const unsigned char key[32], const unsigned char iv[8], uint64_t counter)
+{
+	struct chacha_ctx ctx;
+
+	/*
+	 * chacha_ivsetup expects the counter to be in u8. Rather than
+	 * converting size_t to u8 and then back again, pass a counter of
+	 * NULL and manually assign it afterwards.
+	 */
+	chacha_keysetup(&ctx, key, 256);
+	chacha_ivsetup(&ctx, iv, NULL);
+	if (counter != 0) {
+		ctx.input[12] = (uint32_t)counter;
+		ctx.input[13] = (uint32_t)(counter >> 32);
+	}
+
+	chacha_encrypt_bytes(&ctx, in, out, (uint32_t)len);
+}
diff --git a/crypto/libressl/crypto/cmac/cm_ameth.c b/crypto/libressl/crypto/cmac/cm_ameth.c
new file mode 100644
index 0000000000..9e5938fb41
--- /dev/null
+++ b/crypto/libressl/crypto/cmac/cm_ameth.c
@@ -0,0 +1,89 @@
+/* $OpenBSD: cm_ameth.c,v 1.6 2014/07/11 08:44:48 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2010.
+ */
+/* ====================================================================
+ * Copyright (c) 2010 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include 
+
+#include 
+#include 
+
+#include "asn1_locl.h"
+
+/* CMAC "ASN1" method. This is just here to indicate the
+ * maximum CMAC output length and to free up a CMAC
+ * key.
+ */
+
+static int
+cmac_size(const EVP_PKEY *pkey)
+{
+	return EVP_MAX_BLOCK_LENGTH;
+}
+
+static void
+cmac_key_free(EVP_PKEY *pkey)
+{
+	CMAC_CTX *cmctx = (CMAC_CTX *)pkey->pkey.ptr;
+
+	CMAC_CTX_free(cmctx);
+}
+
+const EVP_PKEY_ASN1_METHOD cmac_asn1_meth = {
+	.pkey_id = EVP_PKEY_CMAC,
+	.pkey_base_id = EVP_PKEY_CMAC,
+
+	.pem_str = "CMAC",
+	.info = "OpenSSL CMAC method",
+
+	.pkey_size = cmac_size,
+	.pkey_free = cmac_key_free
+};
diff --git a/crypto/libressl/crypto/cmac/cm_pmeth.c b/crypto/libressl/crypto/cmac/cm_pmeth.c
new file mode 100644
index 0000000000..f95fe88d7c
--- /dev/null
+++ b/crypto/libressl/crypto/cmac/cm_pmeth.c
@@ -0,0 +1,213 @@
+/* $OpenBSD: cm_pmeth.c,v 1.7 2014/07/10 13:58:22 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2010.
+ */
+/* ====================================================================
+ * Copyright (c) 2010 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+
+/* The context structure and "key" is simply a CMAC_CTX */
+
+static int
+pkey_cmac_init(EVP_PKEY_CTX *ctx)
+{
+	ctx->data = CMAC_CTX_new();
+	if (!ctx->data)
+		return 0;
+	ctx->keygen_info_count = 0;
+	return 1;
+}
+
+static int
+pkey_cmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+{
+	if (!pkey_cmac_init(dst))
+		return 0;
+	if (!CMAC_CTX_copy(dst->data, src->data))
+		return 0;
+	return 1;
+}
+
+static void
+pkey_cmac_cleanup(EVP_PKEY_CTX *ctx)
+{
+	CMAC_CTX_free(ctx->data);
+}
+
+static int
+pkey_cmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+	CMAC_CTX *cmkey = CMAC_CTX_new();
+	CMAC_CTX *cmctx = ctx->data;
+
+	if (!cmkey)
+		return 0;
+	if (!CMAC_CTX_copy(cmkey, cmctx)) {
+		CMAC_CTX_free(cmkey);
+		return 0;
+	}
+	EVP_PKEY_assign(pkey, EVP_PKEY_CMAC, cmkey);
+
+	return 1;
+}
+
+static int
+int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+	if (!CMAC_Update(ctx->pctx->data, data, count))
+		return 0;
+	return 1;
+}
+
+static int
+cmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
+{
+	EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
+	mctx->update = int_update;
+	return 1;
+}
+
+static int
+cmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+    EVP_MD_CTX *mctx)
+{
+	return CMAC_Final(ctx->data, sig, siglen);
+}
+
+static int
+pkey_cmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+	CMAC_CTX *cmctx = ctx->data;
+
+	switch (type) {
+	case EVP_PKEY_CTRL_SET_MAC_KEY:
+		if (!p2 || p1 < 0)
+			return 0;
+		if (!CMAC_Init(cmctx, p2, p1, NULL, NULL))
+			return 0;
+		break;
+
+	case EVP_PKEY_CTRL_CIPHER:
+		if (!CMAC_Init(cmctx, NULL, 0, p2, ctx->engine))
+			return 0;
+		break;
+
+	case EVP_PKEY_CTRL_MD:
+		if (ctx->pkey && !CMAC_CTX_copy(ctx->data,
+		    (CMAC_CTX *)ctx->pkey->pkey.ptr))
+			return 0;
+		if (!CMAC_Init(cmctx, NULL, 0, NULL, NULL))
+			return 0;
+		break;
+
+	default:
+		return -2;
+	}
+	return 1;
+}
+
+static int
+pkey_cmac_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value)
+{
+	if (!value)
+		return 0;
+	if (!strcmp(type, "key")) {
+		void *p = (void *)value;
+		return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
+		    strlen(p), p);
+	}
+	if (!strcmp(type, "cipher")) {
+		const EVP_CIPHER *c;
+
+		c = EVP_get_cipherbyname(value);
+		if (!c)
+			return 0;
+		return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_CIPHER, -1, (void *)c);
+	}
+	if (!strcmp(type, "hexkey")) {
+		unsigned char *key;
+		int r;
+		long keylen;
+
+		key = string_to_hex(value, &keylen);
+		if (!key)
+			return 0;
+		r = pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key);
+		free(key);
+		return r;
+	}
+
+	return -2;
+}
+
+const EVP_PKEY_METHOD cmac_pkey_meth = {
+	.pkey_id = EVP_PKEY_CMAC,
+	.flags = EVP_PKEY_FLAG_SIGCTX_CUSTOM,
+
+	.init = pkey_cmac_init,
+	.copy = pkey_cmac_copy,
+	.cleanup = pkey_cmac_cleanup,
+
+	.keygen = pkey_cmac_keygen,
+
+	.signctx_init = cmac_signctx_init,
+	.signctx = cmac_signctx,
+
+	.ctrl = pkey_cmac_ctrl,
+	.ctrl_str = pkey_cmac_ctrl_str
+};
diff --git a/crypto/libressl/crypto/cmac/cmac.c b/crypto/libressl/crypto/cmac/cmac.c
new file mode 100644
index 0000000000..463f97d18f
--- /dev/null
+++ b/crypto/libressl/crypto/cmac/cmac.c
@@ -0,0 +1,281 @@
+/* $OpenBSD: cmac.c,v 1.9 2014/07/12 14:58:32 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2010 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+struct CMAC_CTX_st {
+	/* Cipher context to use */
+	EVP_CIPHER_CTX cctx;
+	/* Keys k1 and k2 */
+	unsigned char k1[EVP_MAX_BLOCK_LENGTH];
+	unsigned char k2[EVP_MAX_BLOCK_LENGTH];
+	/* Temporary block */
+	unsigned char tbl[EVP_MAX_BLOCK_LENGTH];
+	/* Last (possibly partial) block */
+	unsigned char last_block[EVP_MAX_BLOCK_LENGTH];
+	/* Number of bytes in last block: -1 means context not initialised */
+	int nlast_block;
+};
+
+
+/* Make temporary keys K1 and K2 */
+
+static void
+make_kn(unsigned char *k1, unsigned char *l, int bl)
+{
+	int i;
+
+	/* Shift block to left, including carry */
+	for (i = 0; i < bl; i++) {
+		k1[i] = l[i] << 1;
+		if (i < bl - 1 && l[i + 1] & 0x80)
+			k1[i] |= 1;
+	}
+	/* If MSB set fixup with R */
+	if (l[0] & 0x80)
+		k1[bl - 1] ^= bl == 16 ? 0x87 : 0x1b;
+}
+
+CMAC_CTX *
+CMAC_CTX_new(void)
+{
+	CMAC_CTX *ctx;
+
+	ctx = malloc(sizeof(CMAC_CTX));
+	if (!ctx)
+		return NULL;
+	EVP_CIPHER_CTX_init(&ctx->cctx);
+	ctx->nlast_block = -1;
+	return ctx;
+}
+
+void
+CMAC_CTX_cleanup(CMAC_CTX *ctx)
+{
+	EVP_CIPHER_CTX_cleanup(&ctx->cctx);
+	explicit_bzero(ctx->tbl, EVP_MAX_BLOCK_LENGTH);
+	explicit_bzero(ctx->k1, EVP_MAX_BLOCK_LENGTH);
+	explicit_bzero(ctx->k2, EVP_MAX_BLOCK_LENGTH);
+	explicit_bzero(ctx->last_block, EVP_MAX_BLOCK_LENGTH);
+	ctx->nlast_block = -1;
+}
+
+EVP_CIPHER_CTX *
+CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx)
+{
+	return &ctx->cctx;
+}
+
+void
+CMAC_CTX_free(CMAC_CTX *ctx)
+{
+	if (ctx == NULL)
+		return;
+
+	CMAC_CTX_cleanup(ctx);
+	free(ctx);
+}
+
+int
+CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in)
+{
+	int bl;
+
+	if (in->nlast_block == -1)
+		return 0;
+	if (!EVP_CIPHER_CTX_copy(&out->cctx, &in->cctx))
+		return 0;
+	bl = EVP_CIPHER_CTX_block_size(&in->cctx);
+	memcpy(out->k1, in->k1, bl);
+	memcpy(out->k2, in->k2, bl);
+	memcpy(out->tbl, in->tbl, bl);
+	memcpy(out->last_block, in->last_block, bl);
+	out->nlast_block = in->nlast_block;
+	return 1;
+}
+
+int
+CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
+    const EVP_CIPHER *cipher, ENGINE *impl)
+{
+	static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH];
+
+	/* All zeros means restart */
+	if (!key && !cipher && !impl && keylen == 0) {
+		/* Not initialised */
+		if (ctx->nlast_block == -1)
+			return 0;
+		if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv))
+			return 0;
+		memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(&ctx->cctx));
+		ctx->nlast_block = 0;
+		return 1;
+	}
+	/* Initialiase context */
+	if (cipher && !EVP_EncryptInit_ex(&ctx->cctx, cipher, impl, NULL, NULL))
+		return 0;
+	/* Non-NULL key means initialisation complete */
+	if (key) {
+		int bl;
+
+		if (!EVP_CIPHER_CTX_cipher(&ctx->cctx))
+			return 0;
+		if (!EVP_CIPHER_CTX_set_key_length(&ctx->cctx, keylen))
+			return 0;
+		if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, key, zero_iv))
+			return 0;
+		bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
+		if (!EVP_Cipher(&ctx->cctx, ctx->tbl, zero_iv, bl))
+			return 0;
+		make_kn(ctx->k1, ctx->tbl, bl);
+		make_kn(ctx->k2, ctx->k1, bl);
+		explicit_bzero(ctx->tbl, bl);
+		/* Reset context again ready for first data block */
+		if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv))
+			return 0;
+		/* Zero tbl so resume works */
+		memset(ctx->tbl, 0, bl);
+		ctx->nlast_block = 0;
+	}
+	return 1;
+}
+
+int
+CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
+{
+	const unsigned char *data = in;
+	size_t bl;
+
+	if (ctx->nlast_block == -1)
+		return 0;
+	if (dlen == 0)
+		return 1;
+	bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
+	/* Copy into partial block if we need to */
+	if (ctx->nlast_block > 0) {
+		size_t nleft;
+
+		nleft = bl - ctx->nlast_block;
+		if (dlen < nleft)
+			nleft = dlen;
+		memcpy(ctx->last_block + ctx->nlast_block, data, nleft);
+		dlen -= nleft;
+		ctx->nlast_block += nleft;
+		/* If no more to process return */
+		if (dlen == 0)
+			return 1;
+		data += nleft;
+		/* Else not final block so encrypt it */
+		if (!EVP_Cipher(&ctx->cctx, ctx->tbl, ctx->last_block, bl))
+			return 0;
+	}
+	/* Encrypt all but one of the complete blocks left */
+	while (dlen > bl) {
+		if (!EVP_Cipher(&ctx->cctx, ctx->tbl, data, bl))
+			return 0;
+		dlen -= bl;
+		data += bl;
+	}
+	/* Copy any data left to last block buffer */
+	memcpy(ctx->last_block, data, dlen);
+	ctx->nlast_block = dlen;
+	return 1;
+}
+
+int
+CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen)
+{
+	int i, bl, lb;
+
+	if (ctx->nlast_block == -1)
+		return 0;
+	bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
+	*poutlen = (size_t)bl;
+	if (!out)
+		return 1;
+	lb = ctx->nlast_block;
+	/* Is last block complete? */
+	if (lb == bl) {
+		for (i = 0; i < bl; i++)
+			out[i] = ctx->last_block[i] ^ ctx->k1[i];
+	} else {
+		ctx->last_block[lb] = 0x80;
+		if (bl - lb > 1)
+			memset(ctx->last_block + lb + 1, 0, bl - lb - 1);
+		for (i = 0; i < bl; i++)
+			out[i] = ctx->last_block[i] ^ ctx->k2[i];
+	}
+	if (!EVP_Cipher(&ctx->cctx, out, out, bl)) {
+		explicit_bzero(out, bl);
+		return 0;
+	}
+	return 1;
+}
+
+int
+CMAC_resume(CMAC_CTX *ctx)
+{
+	if (ctx->nlast_block == -1)
+		return 0;
+	/* The buffer "tbl" containes the last fully encrypted block
+	 * which is the last IV (or all zeroes if no last encrypted block).
+	 * The last block has not been modified since CMAC_final().
+	 * So reinitialising using the last decrypted block will allow
+	 * CMAC to continue after calling CMAC_Final().
+	 */
+	return EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, ctx->tbl);
+}
diff --git a/crypto/libressl/crypto/comp/c_rle.c b/crypto/libressl/crypto/comp/c_rle.c
new file mode 100644
index 0000000000..19b5ef6a4f
--- /dev/null
+++ b/crypto/libressl/crypto/comp/c_rle.c
@@ -0,0 +1,55 @@
+/* $OpenBSD: c_rle.c,v 1.7 2014/06/12 15:49:28 deraadt Exp $ */
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int rle_compress_block(COMP_CTX *ctx, unsigned char *out,
+    unsigned int olen, unsigned char *in, unsigned int ilen);
+static int rle_expand_block(COMP_CTX *ctx, unsigned char *out,
+    unsigned int olen, unsigned char *in, unsigned int ilen);
+
+static COMP_METHOD rle_method = {
+	.type = NID_rle_compression,
+	.name = LN_rle_compression,
+	.compress = rle_compress_block,
+	.expand = rle_expand_block
+};
+
+COMP_METHOD *
+COMP_rle(void)
+{
+	return (&rle_method);
+}
+
+static int
+rle_compress_block(COMP_CTX *ctx, unsigned char *out, unsigned int olen,
+    unsigned char *in, unsigned int ilen)
+{
+
+	if (ilen == 0 || olen < (ilen - 1)) {
+		return (-1);
+	}
+
+	*(out++) = 0;
+	memcpy(out, in, ilen);
+	return (ilen + 1);
+}
+
+static int
+rle_expand_block(COMP_CTX *ctx, unsigned char *out, unsigned int olen,
+    unsigned char *in, unsigned int ilen)
+{
+	int i;
+
+	if (olen < (ilen - 1)) {
+		return (-1);
+	}
+
+	i= *(in++);
+	if (i == 0) {
+		memcpy(out, in, ilen - 1);
+	}
+	return (ilen - 1);
+}
diff --git a/crypto/libressl/crypto/comp/c_zlib.c b/crypto/libressl/crypto/comp/c_zlib.c
new file mode 100644
index 0000000000..fc8a01a465
--- /dev/null
+++ b/crypto/libressl/crypto/comp/c_zlib.c
@@ -0,0 +1,564 @@
+/* $OpenBSD: c_zlib.c,v 1.17 2014/11/03 16:58:28 tedu Exp $ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+COMP_METHOD *COMP_zlib(void );
+
+static COMP_METHOD zlib_method_nozlib = {
+	.type = NID_undef,
+	.name = "(undef)"
+};
+
+#ifdef ZLIB
+
+#include 
+
+static int zlib_stateful_init(COMP_CTX *ctx);
+static void zlib_stateful_finish(COMP_CTX *ctx);
+static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
+    unsigned int olen, unsigned char *in, unsigned int ilen);
+static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
+    unsigned int olen, unsigned char *in, unsigned int ilen);
+
+
+/* memory allocations functions for zlib intialization */
+static void*
+zlib_zalloc(void* opaque, unsigned int no, unsigned int size)
+{
+	return calloc(no, size);
+}
+
+static void
+zlib_zfree(void* opaque, void* address)
+{
+	free(address);
+}
+
+static COMP_METHOD zlib_stateful_method = {
+	.type = NID_zlib_compression,
+	.name = LN_zlib_compression,
+	.init = zlib_stateful_init,
+	.finish = zlib_stateful_finish,
+	.compress = zlib_stateful_compress_block,
+	.expand = zlib_stateful_expand_block
+};
+
+struct zlib_state {
+	z_stream istream;
+	z_stream ostream;
+};
+
+static int zlib_stateful_ex_idx = -1;
+
+static int
+zlib_stateful_init(COMP_CTX *ctx)
+{
+	int err;
+	struct zlib_state *state = malloc(sizeof(struct zlib_state));
+
+	if (state == NULL)
+		goto err;
+
+	state->istream.zalloc = zlib_zalloc;
+	state->istream.zfree = zlib_zfree;
+	state->istream.opaque = Z_NULL;
+	state->istream.next_in = Z_NULL;
+	state->istream.next_out = Z_NULL;
+	state->istream.avail_in = 0;
+	state->istream.avail_out = 0;
+	err = inflateInit_(&state->istream, ZLIB_VERSION, sizeof(z_stream));
+	if (err != Z_OK)
+		goto err;
+
+	state->ostream.zalloc = zlib_zalloc;
+	state->ostream.zfree = zlib_zfree;
+	state->ostream.opaque = Z_NULL;
+	state->ostream.next_in = Z_NULL;
+	state->ostream.next_out = Z_NULL;
+	state->ostream.avail_in = 0;
+	state->ostream.avail_out = 0;
+	err = deflateInit_(&state->ostream, Z_DEFAULT_COMPRESSION,
+	    ZLIB_VERSION, sizeof(z_stream));
+	if (err != Z_OK)
+		goto err;
+
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_COMP, ctx, &ctx->ex_data);
+	CRYPTO_set_ex_data(&ctx->ex_data, zlib_stateful_ex_idx, state);
+	return 1;
+
+err:
+	free(state);
+	return 0;
+}
+
+static void
+zlib_stateful_finish(COMP_CTX *ctx)
+{
+	struct zlib_state *state =
+	    (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
+	    zlib_stateful_ex_idx);
+
+	inflateEnd(&state->istream);
+	deflateEnd(&state->ostream);
+	free(state);
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP, ctx, &ctx->ex_data);
+}
+
+static int
+zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
+    unsigned int olen, unsigned char *in, unsigned int ilen)
+{
+	int err = Z_OK;
+	struct zlib_state *state =
+	    (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
+	    zlib_stateful_ex_idx);
+
+	if (state == NULL)
+		return -1;
+
+	state->ostream.next_in = in;
+	state->ostream.avail_in = ilen;
+	state->ostream.next_out = out;
+	state->ostream.avail_out = olen;
+	if (ilen > 0)
+		err = deflate(&state->ostream, Z_SYNC_FLUSH);
+	if (err != Z_OK)
+		return -1;
+
+#ifdef DEBUG_ZLIB
+	fprintf(stderr, "compress(%4d)->%4d %s\n",
+	    ilen, olen - state->ostream.avail_out,
+	    (ilen != olen - state->ostream.avail_out)?"zlib":"clear");
+#endif
+
+	return olen - state->ostream.avail_out;
+}
+
+static int
+zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
+    unsigned int olen, unsigned char *in, unsigned int ilen)
+{
+	int err = Z_OK;
+
+	struct zlib_state *state =
+	    (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
+	    zlib_stateful_ex_idx);
+
+	if (state == NULL)
+		return 0;
+
+	state->istream.next_in = in;
+	state->istream.avail_in = ilen;
+	state->istream.next_out = out;
+	state->istream.avail_out = olen;
+	if (ilen > 0)
+		err = inflate(&state->istream, Z_SYNC_FLUSH);
+	if (err != Z_OK)
+		return -1;
+
+#ifdef DEBUG_ZLIB
+	fprintf(stderr, "expand(%4d)->%4d %s\n",
+	    ilen, olen - state->istream.avail_out,
+	    (ilen != olen - state->istream.avail_out)?"zlib":"clear");
+#endif
+
+	return olen - state->istream.avail_out;
+}
+
+#endif
+
+COMP_METHOD *
+COMP_zlib(void)
+{
+	COMP_METHOD *meth = &zlib_method_nozlib;
+
+#ifdef ZLIB
+	{
+		/* init zlib_stateful_ex_idx here so that in a multi-process
+		 * application it's enough to intialize openssl before forking
+		 * (idx will be inherited in all the children) */
+		if (zlib_stateful_ex_idx == -1) {
+			CRYPTO_w_lock(CRYPTO_LOCK_COMP);
+			if (zlib_stateful_ex_idx == -1)
+				zlib_stateful_ex_idx =
+			    CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP,
+			    0, NULL, NULL, NULL, NULL);
+			CRYPTO_w_unlock(CRYPTO_LOCK_COMP);
+			if (zlib_stateful_ex_idx == -1)
+				goto err;
+		}
+
+		meth = &zlib_stateful_method;
+	}
+
+err:
+#endif
+
+	return (meth);
+}
+
+void
+COMP_zlib_cleanup(void)
+{
+}
+
+#ifdef ZLIB
+
+/* Zlib based compression/decompression filter BIO */
+
+typedef struct {
+	unsigned char *ibuf;	/* Input buffer */
+	int ibufsize;		/* Buffer size */
+	z_stream zin;		/* Input decompress context */
+	unsigned char *obuf;	/* Output buffer */
+	int obufsize;		/* Output buffer size */
+	unsigned char *optr;	/* Position in output buffer */
+	int ocount;		/* Amount of data in output buffer */
+	int odone;		/* deflate EOF */
+	int comp_level;		/* Compression level to use */
+	z_stream zout;		/* Output compression context */
+} BIO_ZLIB_CTX;
+
+#define ZLIB_DEFAULT_BUFSIZE 1024
+
+static int bio_zlib_new(BIO *bi);
+static int bio_zlib_free(BIO *bi);
+static int bio_zlib_read(BIO *b, char *out, int outl);
+static int bio_zlib_write(BIO *b, const char *in, int inl);
+static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr);
+static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp);
+
+static BIO_METHOD bio_meth_zlib = {
+	.type = BIO_TYPE_COMP,
+	.name = "zlib",
+	.bwrite = bio_zlib_write,
+	.bread = bio_zlib_read,
+	.ctrl = bio_zlib_ctrl,
+	.create = bio_zlib_new,
+	.destroy = bio_zlib_free,
+	.callback_ctrl = bio_zlib_callback_ctrl
+};
+
+BIO_METHOD *
+BIO_f_zlib(void)
+{
+	return &bio_meth_zlib;
+}
+
+
+static int
+bio_zlib_new(BIO *bi)
+{
+	BIO_ZLIB_CTX *ctx;
+
+	ctx = malloc(sizeof(BIO_ZLIB_CTX));
+	if (!ctx) {
+		COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	ctx->ibuf = NULL;
+	ctx->obuf = NULL;
+	ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE;
+	ctx->obufsize = ZLIB_DEFAULT_BUFSIZE;
+	ctx->zin.zalloc = Z_NULL;
+	ctx->zin.zfree = Z_NULL;
+	ctx->zin.next_in = NULL;
+	ctx->zin.avail_in = 0;
+	ctx->zin.next_out = NULL;
+	ctx->zin.avail_out = 0;
+	ctx->zout.zalloc = Z_NULL;
+	ctx->zout.zfree = Z_NULL;
+	ctx->zout.next_in = NULL;
+	ctx->zout.avail_in = 0;
+	ctx->zout.next_out = NULL;
+	ctx->zout.avail_out = 0;
+	ctx->odone = 0;
+	ctx->comp_level = Z_DEFAULT_COMPRESSION;
+	bi->init = 1;
+	bi->ptr = (char *)ctx;
+	bi->flags = 0;
+	return 1;
+}
+
+static int
+bio_zlib_free(BIO *bi)
+{
+	BIO_ZLIB_CTX *ctx;
+
+	if (!bi)
+		return 0;
+	ctx = (BIO_ZLIB_CTX *)bi->ptr;
+	if (ctx->ibuf) {
+		/* Destroy decompress context */
+		inflateEnd(&ctx->zin);
+		free(ctx->ibuf);
+	}
+	if (ctx->obuf) {
+		/* Destroy compress context */
+		deflateEnd(&ctx->zout);
+		free(ctx->obuf);
+	}
+	free(ctx);
+	bi->ptr = NULL;
+	bi->init = 0;
+	bi->flags = 0;
+	return 1;
+}
+
+static int
+bio_zlib_read(BIO *b, char *out, int outl)
+{
+	BIO_ZLIB_CTX *ctx;
+	int ret;
+	z_stream *zin;
+
+	if (!out || !outl)
+		return 0;
+	ctx = (BIO_ZLIB_CTX *)b->ptr;
+	zin = &ctx->zin;
+	BIO_clear_retry_flags(b);
+	if (!ctx->ibuf) {
+		ctx->ibuf = malloc(ctx->ibufsize);
+		if (!ctx->ibuf) {
+			COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		inflateInit(zin);
+		zin->next_in = ctx->ibuf;
+		zin->avail_in = 0;
+	}
+
+	/* Copy output data directly to supplied buffer */
+	zin->next_out = (unsigned char *)out;
+	zin->avail_out = (unsigned int)outl;
+	for (;;) {
+		/* Decompress while data available */
+		while (zin->avail_in) {
+			ret = inflate(zin, 0);
+			if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
+				COMPerr(COMP_F_BIO_ZLIB_READ,
+				    COMP_R_ZLIB_INFLATE_ERROR);
+				ERR_asprintf_error_data("zlib error:%s",
+				    zError(ret));
+				return 0;
+			}
+			/* If EOF or we've read everything then return */
+			if ((ret == Z_STREAM_END) || !zin->avail_out)
+				return outl - zin->avail_out;
+		}
+
+		/* No data in input buffer try to read some in,
+		 * if an error then return the total data read.
+		 */
+		ret = BIO_read(b->next_bio, ctx->ibuf, ctx->ibufsize);
+		if (ret <= 0) {
+			/* Total data read */
+			int tot = outl - zin->avail_out;
+			BIO_copy_next_retry(b);
+			if (ret < 0)
+				return (tot > 0) ? tot : ret;
+			return tot;
+		}
+		zin->avail_in = ret;
+		zin->next_in = ctx->ibuf;
+	}
+}
+
+static int
+bio_zlib_write(BIO *b, const char *in, int inl)
+{
+	BIO_ZLIB_CTX *ctx;
+	int ret;
+	z_stream *zout;
+
+	if (!in || !inl)
+		return 0;
+	ctx = (BIO_ZLIB_CTX *)b->ptr;
+	if (ctx->odone)
+		return 0;
+	zout = &ctx->zout;
+	BIO_clear_retry_flags(b);
+	if (!ctx->obuf) {
+		ctx->obuf = malloc(ctx->obufsize);
+		/* Need error here */
+		if (!ctx->obuf) {
+			COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		ctx->optr = ctx->obuf;
+		ctx->ocount = 0;
+		deflateInit(zout, ctx->comp_level);
+		zout->next_out = ctx->obuf;
+		zout->avail_out = ctx->obufsize;
+	}
+	/* Obtain input data directly from supplied buffer */
+	zout->next_in = (void *)in;
+	zout->avail_in = inl;
+	for (;;) {
+		/* If data in output buffer write it first */
+		while (ctx->ocount) {
+			ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
+			if (ret <= 0) {
+				/* Total data written */
+				int tot = inl - zout->avail_in;
+				BIO_copy_next_retry(b);
+				if (ret < 0)
+					return (tot > 0) ? tot : ret;
+				return tot;
+			}
+			ctx->optr += ret;
+			ctx->ocount -= ret;
+		}
+
+		/* Have we consumed all supplied data? */
+		if (!zout->avail_in)
+			return inl;
+
+		/* Compress some more */
+
+		/* Reset buffer */
+		ctx->optr = ctx->obuf;
+		zout->next_out = ctx->obuf;
+		zout->avail_out = ctx->obufsize;
+		/* Compress some more */
+		ret = deflate(zout, 0);
+		if (ret != Z_OK) {
+			COMPerr(COMP_F_BIO_ZLIB_WRITE,
+			    COMP_R_ZLIB_DEFLATE_ERROR);
+			ERR_asprintf_error_data("zlib error:%s", zError(ret));
+			return 0;
+		}
+		ctx->ocount = ctx->obufsize - zout->avail_out;
+	}
+}
+
+static int
+bio_zlib_flush(BIO *b)
+{
+	BIO_ZLIB_CTX *ctx;
+	int ret;
+	z_stream *zout;
+
+	ctx = (BIO_ZLIB_CTX *)b->ptr;
+	/* If no data written or already flush show success */
+	if (!ctx->obuf || (ctx->odone && !ctx->ocount))
+		return 1;
+	zout = &ctx->zout;
+	BIO_clear_retry_flags(b);
+	/* No more input data */
+	zout->next_in = NULL;
+	zout->avail_in = 0;
+	for (;;) {
+		/* If data in output buffer write it first */
+		while (ctx->ocount) {
+			ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
+			if (ret <= 0) {
+				BIO_copy_next_retry(b);
+				return ret;
+			}
+			ctx->optr += ret;
+			ctx->ocount -= ret;
+		}
+		if (ctx->odone)
+			return 1;
+
+		/* Compress some more */
+
+		/* Reset buffer */
+		ctx->optr = ctx->obuf;
+		zout->next_out = ctx->obuf;
+		zout->avail_out = ctx->obufsize;
+		/* Compress some more */
+		ret = deflate(zout, Z_FINISH);
+		if (ret == Z_STREAM_END)
+			ctx->odone = 1;
+		else if (ret != Z_OK) {
+			COMPerr(COMP_F_BIO_ZLIB_FLUSH,
+			    COMP_R_ZLIB_DEFLATE_ERROR);
+			ERR_asprintf_error_data("zlib error:%s", zError(ret));
+			return 0;
+		}
+		ctx->ocount = ctx->obufsize - zout->avail_out;
+	}
+}
+
+static long
+bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+	BIO_ZLIB_CTX *ctx;
+	int ret, *ip;
+	int ibs, obs;
+	if (!b->next_bio)
+		return 0;
+	ctx = (BIO_ZLIB_CTX *)b->ptr;
+	switch (cmd) {
+
+	case BIO_CTRL_RESET:
+		ctx->ocount = 0;
+		ctx->odone = 0;
+		ret = 1;
+		break;
+
+	case BIO_CTRL_FLUSH:
+		ret = bio_zlib_flush(b);
+		if (ret > 0)
+			ret = BIO_flush(b->next_bio);
+		break;
+
+	case BIO_C_SET_BUFF_SIZE:
+		ibs = -1;
+		obs = -1;
+		if (ptr != NULL) {
+			ip = ptr;
+			if (*ip == 0)
+				ibs = (int) num;
+			else
+				obs = (int) num;
+		} else {
+			ibs = (int)num;
+			obs = ibs;
+		}
+
+		if (ibs != -1) {
+			free(ctx->ibuf);
+			ctx->ibuf = NULL;
+			ctx->ibufsize = ibs;
+		}
+
+		if (obs != -1) {
+			free(ctx->obuf);
+			ctx->obuf = NULL;
+			ctx->obufsize = obs;
+		}
+		ret = 1;
+		break;
+
+	case BIO_C_DO_STATE_MACHINE:
+		BIO_clear_retry_flags(b);
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		BIO_copy_next_retry(b);
+		break;
+
+	default:
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		break;
+
+	}
+
+	return ret;
+}
+
+
+static long
+bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+	if (!b->next_bio)
+		return 0;
+	return BIO_callback_ctrl(b->next_bio, cmd, fp);
+}
+
+#endif
diff --git a/crypto/libressl/crypto/comp/comp_err.c b/crypto/libressl/crypto/comp/comp_err.c
new file mode 100644
index 0000000000..804974c7a3
--- /dev/null
+++ b/crypto/libressl/crypto/comp/comp_err.c
@@ -0,0 +1,95 @@
+/* $OpenBSD: comp_err.c,v 1.8 2014/07/10 22:45:56 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_COMP,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_COMP,0,reason)
+
+static ERR_STRING_DATA COMP_str_functs[] = {
+	{ERR_FUNC(COMP_F_BIO_ZLIB_FLUSH),	"BIO_ZLIB_FLUSH"},
+	{ERR_FUNC(COMP_F_BIO_ZLIB_NEW),	"BIO_ZLIB_NEW"},
+	{ERR_FUNC(COMP_F_BIO_ZLIB_READ),	"BIO_ZLIB_READ"},
+	{ERR_FUNC(COMP_F_BIO_ZLIB_WRITE),	"BIO_ZLIB_WRITE"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA COMP_str_reasons[] = {
+	{ERR_REASON(COMP_R_ZLIB_DEFLATE_ERROR)   , "zlib deflate error"},
+	{ERR_REASON(COMP_R_ZLIB_INFLATE_ERROR)   , "zlib inflate error"},
+	{ERR_REASON(COMP_R_ZLIB_NOT_SUPPORTED)   , "zlib not supported"},
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_COMP_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(COMP_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, COMP_str_functs);
+		ERR_load_strings(0, COMP_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/comp/comp_lib.c b/crypto/libressl/crypto/comp/comp_lib.c
new file mode 100644
index 0000000000..3e0b567e4a
--- /dev/null
+++ b/crypto/libressl/crypto/comp/comp_lib.c
@@ -0,0 +1,68 @@
+/* $OpenBSD: comp_lib.c,v 1.7 2014/06/12 15:49:28 deraadt Exp $ */
+#include 
+#include 
+#include 
+#include 
+#include 
+
+COMP_CTX *
+COMP_CTX_new(COMP_METHOD *meth)
+{
+	COMP_CTX *ret;
+
+	if ((ret = calloc(1, sizeof(COMP_CTX))) == NULL) {
+		return (NULL);
+	}
+	ret->meth = meth;
+	if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
+		free(ret);
+		ret = NULL;
+	}
+	return (ret);
+}
+
+void
+COMP_CTX_free(COMP_CTX *ctx)
+{
+	if (ctx == NULL)
+		return;
+
+	if (ctx->meth->finish != NULL)
+		ctx->meth->finish(ctx);
+
+	free(ctx);
+}
+
+int
+COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen,
+    unsigned char *in, int ilen)
+{
+	int ret;
+
+	if (ctx->meth->compress == NULL) {
+		return (-1);
+	}
+	ret = ctx->meth->compress(ctx, out, olen, in, ilen);
+	if (ret > 0) {
+		ctx->compress_in += ilen;
+		ctx->compress_out += ret;
+	}
+	return (ret);
+}
+
+int
+COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen,
+    unsigned char *in, int ilen)
+{
+	int ret;
+
+	if (ctx->meth->expand == NULL) {
+		return (-1);
+	}
+	ret = ctx->meth->expand(ctx, out, olen, in, ilen);
+	if (ret > 0) {
+		ctx->expand_in += ilen;
+		ctx->expand_out += ret;
+	}
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/compat/arc4random.c b/crypto/libressl/crypto/compat/arc4random.c
new file mode 100644
index 0000000000..5afc6a15ab
--- /dev/null
+++ b/crypto/libressl/crypto/compat/arc4random.c
@@ -0,0 +1,196 @@
+/*	$OpenBSD: arc4random.c,v 1.53 2015/09/10 18:53:50 bcook Exp $	*/
+
+/*
+ * Copyright (c) 1996, David Mazieres 
+ * Copyright (c) 2008, Damien Miller 
+ * Copyright (c) 2013, Markus Friedl 
+ * Copyright (c) 2014, Theo de Raadt 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define KEYSTREAM_ONLY
+#include "chacha_private.h"
+
+#define minimum(a, b) ((a) < (b) ? (a) : (b))
+
+#if defined(__GNUC__) || defined(_MSC_VER)
+#define inline __inline
+#else				/* __GNUC__ || _MSC_VER */
+#define inline
+#endif				/* !__GNUC__ && !_MSC_VER */
+
+#define KEYSZ	32
+#define IVSZ	8
+#define BLOCKSZ	64
+#define RSBUFSZ	(16*BLOCKSZ)
+
+/* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */
+static struct _rs {
+	size_t		rs_have;	/* valid bytes at end of rs_buf */
+	size_t		rs_count;	/* bytes till reseed */
+} *rs;
+
+/* Maybe be preserved in fork children, if _rs_allocate() decides. */
+static struct _rsx {
+	chacha_ctx	rs_chacha;	/* chacha context for random keystream */
+	u_char		rs_buf[RSBUFSZ];	/* keystream blocks */
+} *rsx;
+
+static inline int _rs_allocate(struct _rs **, struct _rsx **);
+static inline void _rs_forkdetect(void);
+#include "arc4random.h"
+
+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;
+
+	if (rs == NULL) {
+		if (_rs_allocate(&rs, &rsx) == -1)
+			abort();
+	}
+
+	chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8, 0);
+	chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ);
+}
+
+static void
+_rs_stir(void)
+{
+	u_char rnd[KEYSZ + IVSZ];
+
+	if (getentropy(rnd, sizeof rnd) == -1)
+		_getentropy_fail();
+
+	if (!rs)
+		_rs_init(rnd, sizeof(rnd));
+	else
+		_rs_rekey(rnd, sizeof(rnd));
+	explicit_bzero(rnd, sizeof(rnd));	/* discard source seed */
+
+	/* invalidate rs_buf */
+	rs->rs_have = 0;
+	memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
+
+	rs->rs_count = 1600000;
+}
+
+static inline void
+_rs_stir_if_needed(size_t len)
+{
+	_rs_forkdetect();
+	if (!rs || rs->rs_count <= len)
+		_rs_stir();
+	if (rs->rs_count <= len)
+		rs->rs_count = 0;
+	else
+		rs->rs_count -= len;
+}
+
+static inline void
+_rs_rekey(u_char *dat, size_t datlen)
+{
+#ifndef KEYSTREAM_ONLY
+	memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
+#endif
+	/* fill rs_buf with the keystream */
+	chacha_encrypt_bytes(&rsx->rs_chacha, rsx->rs_buf,
+	    rsx->rs_buf, sizeof(rsx->rs_buf));
+	/* mix in optional user provided data */
+	if (dat) {
+		size_t i, m;
+
+		m = minimum(datlen, KEYSZ + IVSZ);
+		for (i = 0; i < m; i++)
+			rsx->rs_buf[i] ^= dat[i];
+	}
+	/* immediately reinit for backtracking resistance */
+	_rs_init(rsx->rs_buf, KEYSZ + IVSZ);
+	memset(rsx->rs_buf, 0, KEYSZ + IVSZ);
+	rs->rs_have = sizeof(rsx->rs_buf) - KEYSZ - IVSZ;
+}
+
+static inline void
+_rs_random_buf(void *_buf, size_t n)
+{
+	u_char *buf = (u_char *)_buf;
+	u_char *keystream;
+	size_t m;
+
+	_rs_stir_if_needed(n);
+	while (n > 0) {
+		if (rs->rs_have > 0) {
+			m = minimum(n, rs->rs_have);
+			keystream = rsx->rs_buf + sizeof(rsx->rs_buf)
+			    - rs->rs_have;
+			memcpy(buf, keystream, m);
+			memset(keystream, 0, m);
+			buf += m;
+			n -= m;
+			rs->rs_have -= m;
+		}
+		if (rs->rs_have == 0)
+			_rs_rekey(NULL, 0);
+	}
+}
+
+static inline void
+_rs_random_u32(uint32_t *val)
+{
+	u_char *keystream;
+
+	_rs_stir_if_needed(sizeof(*val));
+	if (rs->rs_have < sizeof(*val))
+		_rs_rekey(NULL, 0);
+	keystream = rsx->rs_buf + sizeof(rsx->rs_buf) - rs->rs_have;
+	memcpy(val, keystream, sizeof(*val));
+	memset(keystream, 0, sizeof(*val));
+	rs->rs_have -= sizeof(*val);
+}
+
+uint32_t
+arc4random(void)
+{
+	uint32_t val;
+
+	_ARC4_LOCK();
+	_rs_random_u32(&val);
+	_ARC4_UNLOCK();
+	return val;
+}
+
+void
+arc4random_buf(void *buf, size_t n)
+{
+	_ARC4_LOCK();
+	_rs_random_buf(buf, n);
+	_ARC4_UNLOCK();
+}
diff --git a/crypto/libressl/crypto/compat/arc4random.h b/crypto/libressl/crypto/compat/arc4random.h
new file mode 100644
index 0000000000..762aec23cf
--- /dev/null
+++ b/crypto/libressl/crypto/compat/arc4random.h
@@ -0,0 +1,35 @@
+#ifndef LIBCRYPTOCOMPAT_ARC4RANDOM_H
+#define LIBCRYPTOCOMPAT_ARC4RANDOM_H
+
+#include 
+
+#if defined(_AIX)
+#include "arc4random_aix.h"
+
+#elif defined(__FreeBSD__)
+#include "arc4random_freebsd.h"
+
+#elif defined(__hpux)
+#include "arc4random_hpux.h"
+
+#elif defined(__linux__)
+#include "arc4random_linux.h"
+
+#elif defined(__NetBSD__)
+#include "arc4random_netbsd.h"
+
+#elif defined(__APPLE__)
+#include "arc4random_osx.h"
+
+#elif defined(__sun)
+#include "arc4random_solaris.h"
+
+#elif defined(_WIN32)
+#include "arc4random_win.h"
+
+#else
+#error "No arc4random hooks defined for this platform."
+
+#endif
+
+#endif
diff --git a/crypto/libressl/crypto/compat/arc4random_aix.h b/crypto/libressl/crypto/compat/arc4random_aix.h
new file mode 100644
index 0000000000..b5419132a0
--- /dev/null
+++ b/crypto/libressl/crypto/compat/arc4random_aix.h
@@ -0,0 +1,81 @@
+/*	$OpenBSD: arc4random_aix.h,v 1.1 2015/03/30 11:29:48 bcook Exp $	*/
+
+/*
+ * Copyright (c) 1996, David Mazieres 
+ * Copyright (c) 2008, Damien Miller 
+ * Copyright (c) 2013, Markus Friedl 
+ * Copyright (c) 2014, Theo de Raadt 
+ *
+ * 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.
+ */
+
+/*
+ * Stub functions for portability.
+ */
+
+#include 
+
+#include 
+#include 
+
+static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
+#define _ARC4_LOCK()   pthread_mutex_lock(&arc4random_mtx)
+#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx)
+
+#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f))
+
+static inline void
+_getentropy_fail(void)
+{
+	raise(SIGKILL);
+}
+
+static volatile sig_atomic_t _rs_forked;
+
+static inline void
+_rs_forkhandler(void)
+{
+	_rs_forked = 1;
+}
+
+static inline void
+_rs_forkdetect(void)
+{
+	static pid_t _rs_pid = 0;
+	pid_t pid = getpid();
+
+	if (_rs_pid == 0 || _rs_pid != pid || _rs_forked) {
+		_rs_pid = pid;
+		_rs_forked = 0;
+		if (rs)
+			memset(rs, 0, sizeof(*rs));
+	}
+}
+
+static inline int
+_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
+{
+	if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE,
+	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+		return (-1);
+
+	if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE,
+	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
+		munmap(*rsp, sizeof(**rsp));
+		*rsp = NULL;
+		return (-1);
+	}
+
+	_ARC4_ATFORK(_rs_forkhandler);
+	return (0);
+}
diff --git a/crypto/libressl/crypto/compat/arc4random_freebsd.h b/crypto/libressl/crypto/compat/arc4random_freebsd.h
new file mode 100644
index 0000000000..d5bd347772
--- /dev/null
+++ b/crypto/libressl/crypto/compat/arc4random_freebsd.h
@@ -0,0 +1,87 @@
+/*	$OpenBSD: arc4random_freebsd.h,v 1.3 2015/09/11 11:52:55 deraadt Exp $	*/
+
+/*
+ * Copyright (c) 1996, David Mazieres 
+ * Copyright (c) 2008, Damien Miller 
+ * Copyright (c) 2013, Markus Friedl 
+ * Copyright (c) 2014, Theo de Raadt 
+ *
+ * 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.
+ */
+
+/*
+ * Stub functions for portability.
+ */
+
+#include 
+
+#include 
+#include 
+
+static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
+#define _ARC4_LOCK()   pthread_mutex_lock(&arc4random_mtx)
+#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx)
+
+/*
+ * Unfortunately, pthread_atfork() is broken on FreeBSD (at least 9 and 10) if
+ * a program does not link to -lthr. Callbacks registered with pthread_atfork()
+ * appear to fail silently. So, it is not always possible to detect a PID
+ * wraparound.
+ */
+#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f))
+
+static inline void
+_getentropy_fail(void)
+{
+	raise(SIGKILL);
+}
+
+static volatile sig_atomic_t _rs_forked;
+
+static inline void
+_rs_forkhandler(void)
+{
+	_rs_forked = 1;
+}
+
+static inline void
+_rs_forkdetect(void)
+{
+	static pid_t _rs_pid = 0;
+	pid_t pid = getpid();
+
+	if (_rs_pid == 0 || _rs_pid != pid || _rs_forked) {
+		_rs_pid = pid;
+		_rs_forked = 0;
+		if (rs)
+			memset(rs, 0, sizeof(*rs));
+	}
+}
+
+static inline int
+_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
+{
+	if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE,
+	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+		return (-1);
+
+	if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE,
+	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
+		munmap(*rsp, sizeof(**rsp));
+		*rsp = NULL;
+		return (-1);
+	}
+
+	_ARC4_ATFORK(_rs_forkhandler);
+	return (0);
+}
diff --git a/crypto/libressl/crypto/compat/arc4random_hpux.h b/crypto/libressl/crypto/compat/arc4random_hpux.h
new file mode 100644
index 0000000000..77945aa3c2
--- /dev/null
+++ b/crypto/libressl/crypto/compat/arc4random_hpux.h
@@ -0,0 +1,81 @@
+/*	$OpenBSD: arc4random_hpux.h,v 1.2 2015/01/15 06:57:18 deraadt Exp $	*/
+
+/*
+ * Copyright (c) 1996, David Mazieres 
+ * Copyright (c) 2008, Damien Miller 
+ * Copyright (c) 2013, Markus Friedl 
+ * Copyright (c) 2014, Theo de Raadt 
+ *
+ * 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.
+ */
+
+/*
+ * Stub functions for portability.
+ */
+
+#include 
+
+#include 
+#include 
+
+static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
+#define _ARC4_LOCK()   pthread_mutex_lock(&arc4random_mtx)
+#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx)
+
+#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f))
+
+static inline void
+_getentropy_fail(void)
+{
+	raise(SIGKILL);
+}
+
+static volatile sig_atomic_t _rs_forked;
+
+static inline void
+_rs_forkhandler(void)
+{
+	_rs_forked = 1;
+}
+
+static inline void
+_rs_forkdetect(void)
+{
+	static pid_t _rs_pid = 0;
+	pid_t pid = getpid();
+
+	if (_rs_pid == 0 || _rs_pid != pid || _rs_forked) {
+		_rs_pid = pid;
+		_rs_forked = 0;
+		if (rs)
+			memset(rs, 0, sizeof(*rs));
+	}
+}
+
+static inline int
+_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
+{
+	if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE,
+	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+		return (-1);
+
+	if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE,
+	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
+		munmap(*rsp, sizeof(**rsp));
+		*rsp = NULL;
+		return (-1);
+	}
+
+	_ARC4_ATFORK(_rs_forkhandler);
+	return (0);
+}
diff --git a/crypto/libressl/crypto/compat/arc4random_linux.h b/crypto/libressl/crypto/compat/arc4random_linux.h
new file mode 100644
index 0000000000..c542f41081
--- /dev/null
+++ b/crypto/libressl/crypto/compat/arc4random_linux.h
@@ -0,0 +1,88 @@
+/*	$OpenBSD: arc4random_linux.h,v 1.10 2016/01/04 02:04:56 bcook Exp $	*/
+
+/*
+ * Copyright (c) 1996, David Mazieres 
+ * Copyright (c) 2008, Damien Miller 
+ * Copyright (c) 2013, Markus Friedl 
+ * Copyright (c) 2014, Theo de Raadt 
+ *
+ * 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.
+ */
+
+/*
+ * Stub functions for portability.
+ */
+
+#include 
+
+#include 
+#include 
+
+static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
+#define _ARC4_LOCK()   pthread_mutex_lock(&arc4random_mtx)
+#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx)
+
+#ifdef __GLIBC__
+extern void *__dso_handle;
+extern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void *);
+#define _ARC4_ATFORK(f) __register_atfork(NULL, NULL, (f), __dso_handle)
+#else
+#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f))
+#endif
+
+static inline void
+_getentropy_fail(void)
+{
+	raise(SIGKILL);
+}
+
+static volatile sig_atomic_t _rs_forked;
+
+static inline void
+_rs_forkhandler(void)
+{
+	_rs_forked = 1;
+}
+
+static inline void
+_rs_forkdetect(void)
+{
+	static pid_t _rs_pid = 0;
+	pid_t pid = getpid();
+
+        /* XXX unusual calls to clone() can bypass checks */
+	if (_rs_pid == 0 || _rs_pid == 1 || _rs_pid != pid || _rs_forked) {
+		_rs_pid = pid;
+		_rs_forked = 0;
+		if (rs)
+			memset(rs, 0, sizeof(*rs));
+	}
+}
+
+static inline int
+_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
+{
+	if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE,
+	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+		return (-1);
+
+	if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE,
+	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
+		munmap(*rsp, sizeof(**rsp));
+		*rsp = NULL;
+		return (-1);
+	}
+
+	_ARC4_ATFORK(_rs_forkhandler);
+	return (0);
+}
diff --git a/crypto/libressl/crypto/compat/arc4random_netbsd.h b/crypto/libressl/crypto/compat/arc4random_netbsd.h
new file mode 100644
index 0000000000..4c7be2e85b
--- /dev/null
+++ b/crypto/libressl/crypto/compat/arc4random_netbsd.h
@@ -0,0 +1,87 @@
+/*	$OpenBSD: arc4random_netbsd.h,v 1.2 2015/09/11 11:52:55 deraadt Exp $	*/
+
+/*
+ * Copyright (c) 1996, David Mazieres 
+ * Copyright (c) 2008, Damien Miller 
+ * Copyright (c) 2013, Markus Friedl 
+ * Copyright (c) 2014, Theo de Raadt 
+ *
+ * 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.
+ */
+
+/*
+ * Stub functions for portability.
+ */
+
+#include 
+
+#include 
+#include 
+
+static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
+#define _ARC4_LOCK()   pthread_mutex_lock(&arc4random_mtx)
+#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx)
+
+/*
+ * Unfortunately, pthread_atfork() is broken on FreeBSD (at least 9 and 10) if
+ * a program does not link to -lthr. Callbacks registered with pthread_atfork()
+ * appear to fail silently. So, it is not always possible to detect a PID
+ * wraparound.
+ */
+#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f))
+
+static inline void
+_getentropy_fail(void)
+{
+	raise(SIGKILL);
+}
+
+static volatile sig_atomic_t _rs_forked;
+
+static inline void
+_rs_forkhandler(void)
+{
+	_rs_forked = 1;
+}
+
+static inline void
+_rs_forkdetect(void)
+{
+	static pid_t _rs_pid = 0;
+	pid_t pid = getpid();
+
+	if (_rs_pid == 0 || _rs_pid != pid || _rs_forked) {
+		_rs_pid = pid;
+		_rs_forked = 0;
+		if (rs)
+			memset(rs, 0, sizeof(*rs));
+	}
+}
+
+static inline int
+_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
+{
+	if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE,
+	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+		return (-1);
+
+	if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE,
+	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
+		munmap(*rsp, sizeof(**rsp));
+		*rsp = NULL;
+		return (-1);
+	}
+
+	_ARC4_ATFORK(_rs_forkhandler);
+	return (0);
+}
diff --git a/crypto/libressl/crypto/compat/arc4random_osx.h b/crypto/libressl/crypto/compat/arc4random_osx.h
new file mode 100644
index 0000000000..6dca188795
--- /dev/null
+++ b/crypto/libressl/crypto/compat/arc4random_osx.h
@@ -0,0 +1,81 @@
+/*	$OpenBSD: arc4random_osx.h,v 1.10 2015/09/11 11:52:55 deraadt Exp $	*/
+
+/*
+ * Copyright (c) 1996, David Mazieres 
+ * Copyright (c) 2008, Damien Miller 
+ * Copyright (c) 2013, Markus Friedl 
+ * Copyright (c) 2014, Theo de Raadt 
+ *
+ * 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.
+ */
+
+/*
+ * Stub functions for portability.
+ */
+
+#include 
+
+#include 
+#include 
+
+static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
+#define _ARC4_LOCK()   pthread_mutex_lock(&arc4random_mtx)
+#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx)
+
+#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f))
+
+static inline void
+_getentropy_fail(void)
+{
+	raise(SIGKILL);
+}
+
+static volatile sig_atomic_t _rs_forked;
+
+static inline void
+_rs_forkhandler(void)
+{
+	_rs_forked = 1;
+}
+
+static inline void
+_rs_forkdetect(void)
+{
+	static pid_t _rs_pid = 0;
+	pid_t pid = getpid();
+
+	if (_rs_pid == 0 || _rs_pid != pid || _rs_forked) {
+		_rs_pid = pid;
+		_rs_forked = 0;
+		if (rs)
+			memset(rs, 0, sizeof(*rs));
+	}
+}
+
+static inline int
+_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
+{
+	if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE,
+	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+		return (-1);
+
+	if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE,
+	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
+		munmap(*rsp, sizeof(**rsp));
+		*rsp = NULL;
+		return (-1);
+	}
+
+	_ARC4_ATFORK(_rs_forkhandler);
+	return (0);
+}
diff --git a/crypto/libressl/crypto/compat/arc4random_solaris.h b/crypto/libressl/crypto/compat/arc4random_solaris.h
new file mode 100644
index 0000000000..91f0fe1143
--- /dev/null
+++ b/crypto/libressl/crypto/compat/arc4random_solaris.h
@@ -0,0 +1,81 @@
+/*	$OpenBSD: arc4random_solaris.h,v 1.9 2015/01/15 06:57:18 deraadt Exp $	*/
+
+/*
+ * Copyright (c) 1996, David Mazieres 
+ * Copyright (c) 2008, Damien Miller 
+ * Copyright (c) 2013, Markus Friedl 
+ * Copyright (c) 2014, Theo de Raadt 
+ *
+ * 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.
+ */
+
+/*
+ * Stub functions for portability.
+ */
+
+#include 
+
+#include 
+#include 
+
+static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
+#define _ARC4_LOCK()   pthread_mutex_lock(&arc4random_mtx)
+#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx)
+
+#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f))
+
+static inline void
+_getentropy_fail(void)
+{
+	raise(SIGKILL);
+}
+
+static volatile sig_atomic_t _rs_forked;
+
+static inline void
+_rs_forkhandler(void)
+{
+	_rs_forked = 1;
+}
+
+static inline void
+_rs_forkdetect(void)
+{
+	static pid_t _rs_pid = 0;
+	pid_t pid = getpid();
+
+	if (_rs_pid == 0 || _rs_pid != pid || _rs_forked) {
+		_rs_pid = pid;
+		_rs_forked = 0;
+		if (rs)
+			memset(rs, 0, sizeof(*rs));
+	}
+}
+
+static inline int
+_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
+{
+	if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE,
+	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+		return (-1);
+
+	if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE,
+	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
+		munmap(*rsp, sizeof(**rsp));
+		*rsp = NULL;
+		return (-1);
+	}
+
+	_ARC4_ATFORK(_rs_forkhandler);
+	return (0);
+}
diff --git a/crypto/libressl/crypto/compat/arc4random_uniform.c b/crypto/libressl/crypto/compat/arc4random_uniform.c
new file mode 100644
index 0000000000..1aa9a622f1
--- /dev/null
+++ b/crypto/libressl/crypto/compat/arc4random_uniform.c
@@ -0,0 +1,56 @@
+/*	$OpenBSD: arc4random_uniform.c,v 1.1 2014/07/12 13:24:54 deraadt Exp $	*/
+
+/*
+ * Copyright (c) 2008, 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 
+#include 
+
+/*
+ * 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.
+ */
+uint32_t
+arc4random_uniform(uint32_t upper_bound)
+{
+	uint32_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;
+}
diff --git a/crypto/libressl/crypto/compat/arc4random_win.h b/crypto/libressl/crypto/compat/arc4random_win.h
new file mode 100644
index 0000000000..3e808003cb
--- /dev/null
+++ b/crypto/libressl/crypto/compat/arc4random_win.h
@@ -0,0 +1,78 @@
+/*	$OpenBSD: arc4random_win.h,v 1.4 2014/07/20 20:51:13 bcook Exp $	*/
+
+/*
+ * Copyright (c) 1996, David Mazieres 
+ * Copyright (c) 2008, Damien Miller 
+ * Copyright (c) 2013, Markus Friedl 
+ * Copyright (c) 2014, Theo de Raadt 
+ *
+ * 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.
+ */
+
+/*
+ * Stub functions for portability.
+ */
+
+#include 
+
+static volatile HANDLE arc4random_mtx = NULL;
+
+/*
+ * Initialize the mutex on the first lock attempt. On collision, each thread
+ * will attempt to allocate a mutex and compare-and-swap it into place as the
+ * global mutex. On failure to swap in the global mutex, the mutex is closed.
+ */
+#define _ARC4_LOCK() { \
+	if (!arc4random_mtx) { \
+		HANDLE p = CreateMutex(NULL, FALSE, NULL); \
+		if (InterlockedCompareExchangePointer((void **)&arc4random_mtx, (void *)p, NULL)) \
+			CloseHandle(p); \
+	} \
+	WaitForSingleObject(arc4random_mtx, INFINITE); \
+} \
+
+#define _ARC4_UNLOCK() ReleaseMutex(arc4random_mtx)
+
+static inline void
+_getentropy_fail(void)
+{
+	TerminateProcess(GetCurrentProcess(), 0);
+}
+
+static inline int
+_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
+{
+	*rsp = VirtualAlloc(NULL, sizeof(**rsp),
+	    MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
+	if (*rsp == NULL)
+		return (-1);
+
+	*rsxp = VirtualAlloc(NULL, sizeof(**rsxp),
+	    MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
+	if (*rsxp == NULL) {
+		VirtualFree(*rsp, 0, MEM_RELEASE);
+		*rsp = NULL;
+		return (-1);
+	}
+	return (0);
+}
+
+static inline void
+_rs_forkhandler(void)
+{
+}
+
+static inline void
+_rs_forkdetect(void)
+{
+}
diff --git a/crypto/libressl/crypto/compat/bsd-asprintf.c b/crypto/libressl/crypto/compat/bsd-asprintf.c
new file mode 100644
index 0000000000..3728bc53d6
--- /dev/null
+++ b/crypto/libressl/crypto/compat/bsd-asprintf.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2004 Darren Tucker.
+ *
+ * Based originally on asprintf.c from OpenBSD:
+ * Copyright (c) 1997 Todd C. 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 HAVE_ASPRINTF
+
+#include 
+#include  /* for INT_MAX */
+#include 
+#include  /* for vsnprintf */
+#include 
+
+#ifndef VA_COPY
+# ifdef HAVE_VA_COPY
+#  define VA_COPY(dest, src) va_copy(dest, src)
+# else
+#  ifdef HAVE___VA_COPY
+#   define VA_COPY(dest, src) __va_copy(dest, src)
+#  else
+#   define VA_COPY(dest, src) (dest) = (src)
+#  endif
+# endif
+#endif
+
+#define INIT_SZ	128
+
+int
+vasprintf(char **str, const char *fmt, va_list ap)
+{
+	int ret;
+	va_list ap2;
+	char *string, *newstr;
+	size_t len;
+
+	if ((string = malloc(INIT_SZ)) == NULL)
+		goto fail;
+
+	VA_COPY(ap2, ap);
+	ret = vsnprintf(string, INIT_SZ, fmt, ap2);
+	va_end(ap2);
+	if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */
+		*str = string;
+	} else if (ret == INT_MAX || ret < 0) { /* Bad length */
+		free(string);
+		goto fail;
+	} else {	/* bigger than initial, realloc allowing for nul */
+		len = (size_t)ret + 1;
+		if ((newstr = realloc(string, len)) == NULL) {
+			free(string);
+			goto fail;
+		}
+		VA_COPY(ap2, ap);
+		ret = vsnprintf(newstr, len, fmt, ap2);
+		va_end(ap2);
+		if (ret < 0 || (size_t)ret >= len) { /* failed with realloc'ed string */
+			free(newstr);
+			goto fail;
+		}
+		*str = newstr;
+	}
+	return (ret);
+
+fail:
+	*str = NULL;
+	errno = ENOMEM;
+	return (-1);
+}
+
+int asprintf(char **str, const char *fmt, ...)
+{
+	va_list ap;
+	int ret;
+	
+	*str = NULL;
+	va_start(ap, fmt);
+	ret = vasprintf(str, fmt, ap);
+	va_end(ap);
+
+	return ret;
+}
+#endif
diff --git a/crypto/libressl/crypto/compat/chacha_private.h b/crypto/libressl/crypto/compat/chacha_private.h
new file mode 100644
index 0000000000..b720d93f16
--- /dev/null
+++ b/crypto/libressl/crypto/compat/chacha_private.h
@@ -0,0 +1,222 @@
+/*
+chacha-merged.c version 20080118
+D. J. Bernstein
+Public domain.
+*/
+
+/* $OpenBSD$ */
+
+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/crypto/libressl/crypto/compat/explicit_bzero.c b/crypto/libressl/crypto/compat/explicit_bzero.c
new file mode 100644
index 0000000000..3e33ca85b8
--- /dev/null
+++ b/crypto/libressl/crypto/compat/explicit_bzero.c
@@ -0,0 +1,19 @@
+/*	$OpenBSD: explicit_bzero.c,v 1.3 2014/06/21 02:34:26 matthew Exp $ */
+/*
+ * Public domain.
+ * Written by Matthew Dempsky.
+ */
+
+#include 
+
+__attribute__((weak)) void
+__explicit_bzero_hook(void *buf, size_t len)
+{
+}
+
+void
+explicit_bzero(void *buf, size_t len)
+{
+	memset(buf, 0, len);
+	__explicit_bzero_hook(buf, len);
+}
diff --git a/crypto/libressl/crypto/compat/explicit_bzero_win.c b/crypto/libressl/crypto/compat/explicit_bzero_win.c
new file mode 100644
index 0000000000..0d09d906a2
--- /dev/null
+++ b/crypto/libressl/crypto/compat/explicit_bzero_win.c
@@ -0,0 +1,13 @@
+/*
+ * Public domain.
+ * Win32 explicit_bzero compatibility shim.
+ */
+
+#include 
+#include 
+
+void
+explicit_bzero(void *buf, size_t len)
+{
+	SecureZeroMemory(buf, len);
+}
diff --git a/crypto/libressl/crypto/compat/getentropy_aix.c b/crypto/libressl/crypto/compat/getentropy_aix.c
new file mode 100644
index 0000000000..cbd4037aed
--- /dev/null
+++ b/crypto/libressl/crypto/compat/getentropy_aix.c
@@ -0,0 +1,425 @@
+/*	$OpenBSD: getentropy_aix.c,v 1.3 2015/08/25 17:26:43 deraadt Exp $	*/
+
+/*
+ * Copyright (c) 2015 Michael Felt 
+ * Copyright (c) 2014 Theo de Raadt 
+ * Copyright (c) 2014 Bob Beck 
+ *
+ * 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.
+ *
+ * Emulation of getentropy(2) as documented at:
+ * http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
+ */
+/*
+ * -lperfstat is needed for the psuedo entropy data
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+
+#define REPEAT 5
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+
+#define HX(a, b) \
+	do { \
+		if ((a)) \
+			HD(errno); \
+		else \
+			HD(b); \
+	} while (0)
+
+#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
+#define HD(x)	 (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
+#define HF(x)    (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
+
+int	getentropy(void *buf, size_t len);
+
+static int gotdata(char *buf, size_t len);
+static int getentropy_urandom(void *buf, size_t len, const char *path,
+    int devfscheck);
+static int getentropy_fallback(void *buf, size_t len);
+
+int
+getentropy(void *buf, size_t len)
+{
+	int ret = -1;
+
+	if (len > 256) {
+		errno = EIO;
+		return (-1);
+	}
+
+	/*
+	 * Try to get entropy with /dev/urandom
+	 */
+	ret = getentropy_urandom(buf, len, "/dev/urandom", 0);
+	if (ret != -1)
+		return (ret);
+
+	/*
+	 * Entropy collection via /dev/urandom has failed.
+	 *
+	 * No other API exists for collecting entropy, and we have
+	 * no failsafe way to get it on AIX that is not sensitive
+	 * to resource exhaustion.
+	 *
+	 * We have very few options:
+	 *     - Even syslog_r is unsafe to call at this low level, so
+	 *	 there is no way to alert the user or program.
+	 *     - Cannot call abort() because some systems have unsafe
+	 *	 corefiles.
+	 *     - Could raise(SIGKILL) resulting in silent program termination.
+	 *     - Return EIO, to hint that arc4random's stir function
+	 *       should raise(SIGKILL)
+	 *     - Do the best under the circumstances....
+	 *
+	 * This code path exists to bring light to the issue that AIX
+	 * does not provide a failsafe API for entropy collection.
+	 *
+	 * We hope this demonstrates that AIX should consider
+	 * providing a new failsafe API which works in a chroot or
+	 * when file descriptors are exhausted.
+	 */
+#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
+#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
+	raise(SIGKILL);
+#endif
+	ret = getentropy_fallback(buf, len);
+	if (ret != -1)
+		return (ret);
+
+	errno = EIO;
+	return (ret);
+}
+
+/*
+ * Basic sanity checking; wish we could do better.
+ */
+static int
+gotdata(char *buf, size_t len)
+{
+	char	any_set = 0;
+	size_t	i;
+
+	for (i = 0; i < len; ++i)
+		any_set |= buf[i];
+	if (any_set == 0)
+		return (-1);
+	return (0);
+}
+
+static int
+getentropy_urandom(void *buf, size_t len, const char *path, int devfscheck)
+{
+	struct stat st;
+	size_t i;
+	int fd, flags;
+	int save_errno = errno;
+
+start:
+
+	flags = O_RDONLY;
+#ifdef O_NOFOLLOW
+	flags |= O_NOFOLLOW;
+#endif
+#ifdef O_CLOEXEC
+	flags |= O_CLOEXEC;
+#endif
+	fd = open(path, flags, 0);
+	if (fd == -1) {
+		if (errno == EINTR)
+			goto start;
+		goto nodevrandom;
+	}
+#ifndef O_CLOEXEC
+	fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+#endif
+
+	/* Lightly verify that the device node looks sane */
+	if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) {
+		close(fd);
+		goto nodevrandom;
+	}
+	for (i = 0; i < len; ) {
+		size_t wanted = len - i;
+		ssize_t ret = read(fd, (char *)buf + i, wanted);
+
+		if (ret == -1) {
+			if (errno == EAGAIN || errno == EINTR)
+				continue;
+			close(fd);
+			goto nodevrandom;
+		}
+		i += ret;
+	}
+	close(fd);
+	if (gotdata(buf, len) == 0) {
+		errno = save_errno;
+		return (0);		/* satisfied */
+	}
+nodevrandom:
+	errno = EIO;
+	return (-1);
+}
+
+static const int cl[] = {
+	CLOCK_REALTIME,
+#ifdef CLOCK_MONOTONIC
+	CLOCK_MONOTONIC,
+#endif
+#ifdef CLOCK_MONOTONIC_RAW
+	CLOCK_MONOTONIC_RAW,
+#endif
+#ifdef CLOCK_TAI
+	CLOCK_TAI,
+#endif
+#ifdef CLOCK_VIRTUAL
+	CLOCK_VIRTUAL,
+#endif
+#ifdef CLOCK_UPTIME
+	CLOCK_UPTIME,
+#endif
+#ifdef CLOCK_PROCESS_CPUTIME_ID
+	CLOCK_PROCESS_CPUTIME_ID,
+#endif
+#ifdef CLOCK_THREAD_CPUTIME_ID
+	CLOCK_THREAD_CPUTIME_ID,
+#endif
+};
+
+static int
+getentropy_fallback(void *buf, size_t len)
+{
+	uint8_t results[SHA512_DIGEST_LENGTH];
+	int save_errno = errno, e, pgs = sysconf(_SC_PAGESIZE), faster = 0, repeat;
+	static int cnt;
+	struct timespec ts;
+	struct timeval tv;
+	perfstat_cpu_total_t cpustats;
+#ifdef _AIX61
+	perfstat_cpu_total_wpar_t cpustats_wpar;
+#endif
+	perfstat_partition_total_t lparstats;
+	perfstat_disk_total_t diskinfo;
+	perfstat_netinterface_total_t netinfo;
+	struct rusage ru;
+	sigset_t sigset;
+	struct stat st;
+	SHA512_CTX ctx;
+	static pid_t lastpid;
+	pid_t pid;
+	size_t i, ii, m;
+	char *p;
+
+	pid = getpid();
+	if (lastpid == pid) {
+		faster = 1;
+		repeat = 2;
+	} else {
+		faster = 0;
+		lastpid = pid;
+		repeat = REPEAT;
+	}
+	for (i = 0; i < len; ) {
+		int j;
+		SHA512_Init(&ctx);
+		for (j = 0; j < repeat; j++) {
+			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
+			if (e != -1) {
+				cnt += (int)tv.tv_sec;
+				cnt += (int)tv.tv_usec;
+			}
+
+			HX(perfstat_cpu_total(NULL, &cpustats,
+			    sizeof(cpustats), 1) == -1, cpustats);
+
+#ifdef _AIX61
+			HX(perfstat_cpu_total_wpar(NULL, &cpustats_wpar,
+			    sizeof(cpustats_wpar), 1) == -1, cpustats_wpar);
+#endif
+
+			HX(perfstat_partition_total(NULL, &lparstats,
+			    sizeof(lparstats), 1) == -1, lparstats);
+
+			HX(perfstat_disk_total(NULL, &diskinfo,
+			    sizeof(diskinfo), 1) == -1, diskinfo);
+
+			HX(perfstat_netinterface_total(NULL, &netinfo,
+			    sizeof(netinfo), 1) == -1, netinfo);
+
+			for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
+				HX(clock_gettime(cl[ii], &ts) == -1, ts);
+
+			HX((pid = getpid()) == -1, pid);
+			HX((pid = getsid(pid)) == -1, pid);
+			HX((pid = getppid()) == -1, pid);
+			HX((pid = getpgid(0)) == -1, pid);
+			HX((e = getpriority(0, 0)) == -1, e);
+
+			if (!faster) {
+				ts.tv_sec = 0;
+				ts.tv_nsec = 1;
+				(void) nanosleep(&ts, NULL);
+			}
+
+			HX(sigpending(&sigset) == -1, sigset);
+			HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
+			    sigset);
+
+			HF(getentropy);	/* an addr in this library */
+			HF(printf);		/* an addr in libc */
+			p = (char *)&p;
+			HD(p);		/* an addr on stack */
+			p = (char *)&errno;
+			HD(p);		/* the addr of errno */
+
+			if (i == 0) {
+				struct sockaddr_storage ss;
+				struct statvfs stvfs;
+				struct termios tios;
+				socklen_t ssl;
+				off_t off;
+
+				/*
+				 * Prime-sized mappings encourage fragmentation;
+				 * thus exposing some address entropy.
+				 */
+				struct mm {
+					size_t	npg;
+					void	*p;
+				} mm[] =	 {
+					{ 17, MAP_FAILED }, { 3, MAP_FAILED },
+					{ 11, MAP_FAILED }, { 2, MAP_FAILED },
+					{ 5, MAP_FAILED }, { 3, MAP_FAILED },
+					{ 7, MAP_FAILED }, { 1, MAP_FAILED },
+					{ 57, MAP_FAILED }, { 3, MAP_FAILED },
+					{ 131, MAP_FAILED }, { 1, MAP_FAILED },
+				};
+
+				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
+					HX(mm[m].p = mmap(NULL,
+					    mm[m].npg * pgs,
+					    PROT_READ|PROT_WRITE,
+					    MAP_PRIVATE|MAP_ANON, -1,
+					    (off_t)0), mm[m].p);
+					if (mm[m].p != MAP_FAILED) {
+						size_t mo;
+
+						/* Touch some memory... */
+						p = mm[m].p;
+						mo = cnt %
+						    (mm[m].npg * pgs - 1);
+						p[mo] = 1;
+						cnt += (int)((long)(mm[m].p)
+						    / pgs);
+					}
+
+					/* Check cnts and times... */
+					for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]);
+					    ii++) {
+						HX((e = clock_gettime(cl[ii],
+						    &ts)) == -1, ts);
+						if (e != -1)
+							cnt += (int)ts.tv_nsec;
+					}
+
+					HX((e = getrusage(RUSAGE_SELF,
+					    &ru)) == -1, ru);
+					if (e != -1) {
+						cnt += (int)ru.ru_utime.tv_sec;
+						cnt += (int)ru.ru_utime.tv_usec;
+					}
+				}
+
+				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
+					if (mm[m].p != MAP_FAILED)
+						munmap(mm[m].p, mm[m].npg * pgs);
+					mm[m].p = MAP_FAILED;
+				}
+
+				HX(stat(".", &st) == -1, st);
+				HX(statvfs(".", &stvfs) == -1, stvfs);
+
+				HX(stat("/", &st) == -1, st);
+				HX(statvfs("/", &stvfs) == -1, stvfs);
+
+				HX((e = fstat(0, &st)) == -1, st);
+				if (e == -1) {
+					if (S_ISREG(st.st_mode) ||
+					    S_ISFIFO(st.st_mode) ||
+					    S_ISSOCK(st.st_mode)) {
+						HX(fstatvfs(0, &stvfs) == -1,
+						    stvfs);
+						HX((off = lseek(0, (off_t)0,
+						    SEEK_CUR)) < 0, off);
+					}
+					if (S_ISCHR(st.st_mode)) {
+						HX(tcgetattr(0, &tios) == -1,
+						    tios);
+					} else if (S_ISSOCK(st.st_mode)) {
+						memset(&ss, 0, sizeof ss);
+						ssl = sizeof(ss);
+						HX(getpeername(0,
+						    (void *)&ss, &ssl) == -1,
+						    ss);
+					}
+				}
+
+				HX((e = getrusage(RUSAGE_CHILDREN,
+				    &ru)) == -1, ru);
+				if (e != -1) {
+					cnt += (int)ru.ru_utime.tv_sec;
+					cnt += (int)ru.ru_utime.tv_usec;
+				}
+			} else {
+				/* Subsequent hashes absorb previous result */
+				HD(results);
+			}
+
+			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
+			if (e != -1) {
+				cnt += (int)tv.tv_sec;
+				cnt += (int)tv.tv_usec;
+			}
+
+			HD(cnt);
+		}
+		SHA512_Final(results, &ctx);
+		memcpy((char *)buf + i, results, min(sizeof(results), len - i));
+		i += min(sizeof(results), len - i);
+	}
+	explicit_bzero(&ctx, sizeof ctx);
+	explicit_bzero(results, sizeof results);
+	if (gotdata(buf, len) == 0) {
+		errno = save_errno;
+		return (0);		/* satisfied */
+	}
+	errno = EIO;
+	return (-1);
+}
diff --git a/crypto/libressl/crypto/compat/getentropy_freebsd.c b/crypto/libressl/crypto/compat/getentropy_freebsd.c
new file mode 100644
index 0000000000..19599842d6
--- /dev/null
+++ b/crypto/libressl/crypto/compat/getentropy_freebsd.c
@@ -0,0 +1,62 @@
+/*	$OpenBSD: getentropy_freebsd.c,v 1.1 2014/11/03 06:23:30 bcook Exp $	*/
+
+/*
+ * Copyright (c) 2014 Pawel Jakub Dawidek 
+ * Copyright (c) 2014 Brent Cook 
+ *
+ * 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.
+ *
+ * Emulation of getentropy(2) as documented at:
+ * http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+
+/*
+ * Derived from lib/libc/gen/arc4random.c from FreeBSD.
+ */
+static size_t
+getentropy_sysctl(u_char *buf, size_t size)
+{
+	int mib[2];
+	size_t len, done;
+
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_ARND;
+	done = 0;
+
+	do {
+		len = size;
+		if (sysctl(mib, 2, buf, &len, NULL, 0) == -1)
+			return (done);
+		done += len;
+		buf += len;
+		size -= len;
+	} while (size > 0);
+
+	return (done);
+}
+
+int
+getentropy(void *buf, size_t len)
+{
+	if (len <= 256 && getentropy_sysctl(buf, len) == len)
+		return (0);
+
+	errno = EIO;
+	return (-1);
+}
diff --git a/crypto/libressl/crypto/compat/getentropy_hpux.c b/crypto/libressl/crypto/compat/getentropy_hpux.c
new file mode 100644
index 0000000000..65336518b4
--- /dev/null
+++ b/crypto/libressl/crypto/compat/getentropy_hpux.c
@@ -0,0 +1,419 @@
+/*	$OpenBSD: getentropy_hpux.c,v 1.3 2015/08/25 17:26:43 deraadt Exp $	*/
+
+/*
+ * Copyright (c) 2014 Theo de Raadt 
+ * Copyright (c) 2014 Bob Beck 
+ *
+ * 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.
+ *
+ * Emulation of getentropy(2) as documented at:
+ * http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+
+#define REPEAT 5
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+
+#define HX(a, b) \
+	do { \
+		if ((a)) \
+			HD(errno); \
+		else \
+			HD(b); \
+	} while (0)
+
+#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
+#define HD(x)	 (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
+#define HF(x)    (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
+
+int	getentropy(void *buf, size_t len);
+
+static int gotdata(char *buf, size_t len);
+static int getentropy_urandom(void *buf, size_t len, const char *path,
+    int devfscheck);
+static int getentropy_fallback(void *buf, size_t len);
+
+int
+getentropy(void *buf, size_t len)
+{
+	int ret = -1;
+
+	if (len > 256) {
+		errno = EIO;
+		return (-1);
+	}
+
+	/*
+	 * Try to get entropy with /dev/urandom
+	 */
+	ret = getentropy_urandom(buf, len, "/dev/urandom", 0);
+	if (ret != -1)
+		return (ret);
+
+	/*
+	 * Entropy collection via /dev/urandom has failed.
+	 *
+	 * No other API exists for collecting entropy, and we have
+	 * no failsafe way to get it on hpux that is not sensitive
+	 * to resource exhaustion.
+	 *
+	 * We have very few options:
+	 *     - Even syslog_r is unsafe to call at this low level, so
+	 *	 there is no way to alert the user or program.
+	 *     - Cannot call abort() because some systems have unsafe
+	 *	 corefiles.
+	 *     - Could raise(SIGKILL) resulting in silent program termination.
+	 *     - Return EIO, to hint that arc4random's stir function
+	 *       should raise(SIGKILL)
+	 *     - Do the best under the circumstances....
+	 *
+	 * This code path exists to bring light to the issue that hpux 
+	 * does not provide a failsafe API for entropy collection.
+	 *
+	 * We hope this demonstrates that hpux should consider
+	 * providing a new failsafe API which works in a chroot or
+	 * when file descriptors are exhausted.
+	 */
+#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
+#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
+	raise(SIGKILL);
+#endif
+	ret = getentropy_fallback(buf, len);
+	if (ret != -1)
+		return (ret);
+
+	errno = EIO;
+	return (ret);
+}
+
+/*
+ * Basic sanity checking; wish we could do better.
+ */
+static int
+gotdata(char *buf, size_t len)
+{
+	char	any_set = 0;
+	size_t	i;
+
+	for (i = 0; i < len; ++i)
+		any_set |= buf[i];
+	if (any_set == 0)
+		return (-1);
+	return (0);
+}
+
+static int
+getentropy_urandom(void *buf, size_t len, const char *path, int devfscheck)
+{
+	struct stat st;
+	size_t i;
+	int fd, flags;
+	int save_errno = errno;
+
+start:
+
+	flags = O_RDONLY;
+#ifdef O_NOFOLLOW
+	flags |= O_NOFOLLOW;
+#endif
+#ifdef O_CLOEXEC
+	flags |= O_CLOEXEC;
+#endif
+	fd = open(path, flags, 0);
+	if (fd == -1) {
+		if (errno == EINTR)
+			goto start;
+		goto nodevrandom;
+	}
+#ifndef O_CLOEXEC
+	fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+#endif
+
+	/* Lightly verify that the device node looks sane */
+	if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) {
+		close(fd);
+		goto nodevrandom;
+	}
+	for (i = 0; i < len; ) {
+		size_t wanted = len - i;
+		ssize_t ret = read(fd, (char *)buf + i, wanted);
+
+		if (ret == -1) {
+			if (errno == EAGAIN || errno == EINTR)
+				continue;
+			close(fd);
+			goto nodevrandom;
+		}
+		i += ret;
+	}
+	close(fd);
+	if (gotdata(buf, len) == 0) {
+		errno = save_errno;
+		return (0);		/* satisfied */
+	}
+nodevrandom:
+	errno = EIO;
+	return (-1);
+}
+
+static const int cl[] = {
+	CLOCK_REALTIME,
+#ifdef CLOCK_MONOTONIC
+	CLOCK_MONOTONIC,
+#endif
+#ifdef CLOCK_MONOTONIC_RAW
+	CLOCK_MONOTONIC_RAW,
+#endif
+#ifdef CLOCK_TAI
+	CLOCK_TAI,
+#endif
+#ifdef CLOCK_VIRTUAL
+	CLOCK_VIRTUAL,
+#endif
+#ifdef CLOCK_UPTIME
+	CLOCK_UPTIME,
+#endif
+#ifdef CLOCK_PROCESS_CPUTIME_ID
+	CLOCK_PROCESS_CPUTIME_ID,
+#endif
+#ifdef CLOCK_THREAD_CPUTIME_ID
+	CLOCK_THREAD_CPUTIME_ID,
+#endif
+};
+
+static int
+getentropy_fallback(void *buf, size_t len)
+{
+	uint8_t results[SHA512_DIGEST_LENGTH];
+	int save_errno = errno, e, pgs = sysconf(_SC_PAGESIZE), faster = 0, repeat;
+	static int cnt;
+	struct timespec ts;
+	struct timeval tv;
+	struct pst_vminfo pvi;
+	struct pst_vm_status pvs;
+	struct pst_dynamic pdy;
+	struct rusage ru;
+	sigset_t sigset;
+	struct stat st;
+	SHA512_CTX ctx;
+	static pid_t lastpid;
+	pid_t pid;
+	size_t i, ii, m;
+	char *p;
+
+	pid = getpid();
+	if (lastpid == pid) {
+		faster = 1;
+		repeat = 2;
+	} else {
+		faster = 0;
+		lastpid = pid;
+		repeat = REPEAT;
+	}
+	for (i = 0; i < len; ) {
+		int j;
+		SHA512_Init(&ctx);
+		for (j = 0; j < repeat; j++) {
+			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
+			if (e != -1) {
+				cnt += (int)tv.tv_sec;
+				cnt += (int)tv.tv_usec;
+			}
+
+			HX(pstat_getvminfo(&pvi, sizeof(pvi), 1, 0) != 1, pvi);
+			HX(pstat_getprocvm(&pvs, sizeof(pvs), 0, 0) != 1, pvs);
+
+			for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
+				HX(clock_gettime(cl[ii], &ts) == -1, ts);
+
+			HX((pid = getpid()) == -1, pid);
+			HX((pid = getsid(pid)) == -1, pid);
+			HX((pid = getppid()) == -1, pid);
+			HX((pid = getpgid(0)) == -1, pid);
+			HX((e = getpriority(0, 0)) == -1, e);
+
+			if(pstat_getdynamic(&pdy, sizeof(pdy), 1, 0) != 1) {
+				HD(errno);
+			} else {
+				HD(pdy.psd_avg_1_min);
+				HD(pdy.psd_avg_5_min);
+				HD(pdy.psd_avg_15_min);
+			}
+
+			if (!faster) {
+				ts.tv_sec = 0;
+				ts.tv_nsec = 1;
+				(void) nanosleep(&ts, NULL);
+			}
+
+			HX(sigpending(&sigset) == -1, sigset);
+			HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
+			    sigset);
+
+			HF(getentropy);	/* an addr in this library */
+			HF(printf);		/* an addr in libc */
+			p = (char *)&p;
+			HD(p);		/* an addr on stack */
+			p = (char *)&errno;
+			HD(p);		/* the addr of errno */
+
+			if (i == 0) {
+				struct sockaddr_storage ss;
+				struct statvfs stvfs;
+				struct termios tios;
+				socklen_t ssl;
+				off_t off;
+
+				/*
+				 * Prime-sized mappings encourage fragmentation;
+				 * thus exposing some address entropy.
+				 */
+				struct mm {
+					size_t	npg;
+					void	*p;
+				} mm[] =	 {
+					{ 17, MAP_FAILED }, { 3, MAP_FAILED },
+					{ 11, MAP_FAILED }, { 2, MAP_FAILED },
+					{ 5, MAP_FAILED }, { 3, MAP_FAILED },
+					{ 7, MAP_FAILED }, { 1, MAP_FAILED },
+					{ 57, MAP_FAILED }, { 3, MAP_FAILED },
+					{ 131, MAP_FAILED }, { 1, MAP_FAILED },
+				};
+
+				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
+					HX(mm[m].p = mmap(NULL,
+					    mm[m].npg * pgs,
+					    PROT_READ|PROT_WRITE,
+					    MAP_PRIVATE|MAP_ANON, -1,
+					    (off_t)0), mm[m].p);
+					if (mm[m].p != MAP_FAILED) {
+						size_t mo;
+
+						/* Touch some memory... */
+						p = mm[m].p;
+						mo = cnt %
+						    (mm[m].npg * pgs - 1);
+						p[mo] = 1;
+						cnt += (int)((long)(mm[m].p)
+						    / pgs);
+					}
+
+					/* Check cnts and times... */
+					for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]);
+					    ii++) {
+						HX((e = clock_gettime(cl[ii],
+						    &ts)) == -1, ts);
+						if (e != -1)
+							cnt += (int)ts.tv_nsec;
+					}
+
+					HX((e = getrusage(RUSAGE_SELF,
+					    &ru)) == -1, ru);
+					if (e != -1) {
+						cnt += (int)ru.ru_utime.tv_sec;
+						cnt += (int)ru.ru_utime.tv_usec;
+					}
+				}
+
+				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
+					if (mm[m].p != MAP_FAILED)
+						munmap(mm[m].p, mm[m].npg * pgs);
+					mm[m].p = MAP_FAILED;
+				}
+
+				HX(stat(".", &st) == -1, st);
+				HX(statvfs(".", &stvfs) == -1, stvfs);
+
+				HX(stat("/", &st) == -1, st);
+				HX(statvfs("/", &stvfs) == -1, stvfs);
+
+				HX((e = fstat(0, &st)) == -1, st);
+				if (e == -1) {
+					if (S_ISREG(st.st_mode) ||
+					    S_ISFIFO(st.st_mode) ||
+					    S_ISSOCK(st.st_mode)) {
+						HX(fstatvfs(0, &stvfs) == -1,
+						    stvfs);
+						HX((off = lseek(0, (off_t)0,
+						    SEEK_CUR)) < 0, off);
+					}
+					if (S_ISCHR(st.st_mode)) {
+						HX(tcgetattr(0, &tios) == -1,
+						    tios);
+					} else if (S_ISSOCK(st.st_mode)) {
+						memset(&ss, 0, sizeof ss);
+						ssl = sizeof(ss);
+						HX(getpeername(0,
+						    (void *)&ss, &ssl) == -1,
+						    ss);
+					}
+				}
+
+				HX((e = getrusage(RUSAGE_CHILDREN,
+				    &ru)) == -1, ru);
+				if (e != -1) {
+					cnt += (int)ru.ru_utime.tv_sec;
+					cnt += (int)ru.ru_utime.tv_usec;
+				}
+			} else {
+				/* Subsequent hashes absorb previous result */
+				HD(results);
+			}
+
+			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
+			if (e != -1) {
+				cnt += (int)tv.tv_sec;
+				cnt += (int)tv.tv_usec;
+			}
+
+			HD(cnt);
+		}
+		SHA512_Final(results, &ctx);
+		memcpy((char *)buf + i, results, min(sizeof(results), len - i));
+		i += min(sizeof(results), len - i);
+	}
+	explicit_bzero(&ctx, sizeof ctx);
+	explicit_bzero(results, sizeof results);
+	if (gotdata(buf, len) == 0) {
+		errno = save_errno;
+		return (0);		/* satisfied */
+	}
+	errno = EIO;
+	return (-1);
+}
diff --git a/crypto/libressl/crypto/compat/getentropy_linux.c b/crypto/libressl/crypto/compat/getentropy_linux.c
new file mode 100644
index 0000000000..f0e3d40a60
--- /dev/null
+++ b/crypto/libressl/crypto/compat/getentropy_linux.c
@@ -0,0 +1,547 @@
+/*	$OpenBSD: getentropy_linux.c,v 1.41 2015/09/11 11:52:55 deraadt Exp $	*/
+
+/*
+ * Copyright (c) 2014 Theo de Raadt 
+ * Copyright (c) 2014 Bob Beck 
+ *
+ * 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.
+ *
+ * Emulation of getentropy(2) as documented at:
+ * http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
+ */
+
+#define	_POSIX_C_SOURCE	199309L
+#define	_GNU_SOURCE	1
+#include 
+#include 
+#include 
+#include 
+#include 
+#ifdef SYS__sysctl
+#include 
+#endif
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#ifdef HAVE_GETAUXVAL
+#include 
+#endif
+#include 
+
+#define REPEAT 5
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+
+#define HX(a, b) \
+	do { \
+		if ((a)) \
+			HD(errno); \
+		else \
+			HD(b); \
+	} while (0)
+
+#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
+#define HD(x)	 (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
+#define HF(x)    (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
+
+int	getentropy(void *buf, size_t len);
+
+static int gotdata(char *buf, size_t len);
+#ifdef SYS_getrandom
+static int getentropy_getrandom(void *buf, size_t len);
+#endif
+static int getentropy_urandom(void *buf, size_t len);
+#ifdef SYS__sysctl
+static int getentropy_sysctl(void *buf, size_t len);
+#endif
+static int getentropy_fallback(void *buf, size_t len);
+static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data);
+
+int
+getentropy(void *buf, size_t len)
+{
+	int ret = -1;
+
+	if (len > 256) {
+		errno = EIO;
+		return (-1);
+	}
+
+#ifdef SYS_getrandom
+	/*
+	 * Try descriptor-less getrandom()
+	 */
+	ret = getentropy_getrandom(buf, len);
+	if (ret != -1)
+		return (ret);
+	if (errno != ENOSYS)
+		return (-1);
+#endif
+
+	/*
+	 * Try to get entropy with /dev/urandom
+	 *
+	 * This can fail if the process is inside a chroot or if file
+	 * descriptors are exhausted.
+	 */
+	ret = getentropy_urandom(buf, len);
+	if (ret != -1)
+		return (ret);
+
+#ifdef SYS__sysctl
+	/*
+	 * Try to use sysctl CTL_KERN, KERN_RANDOM, RANDOM_UUID.
+	 * sysctl is a failsafe API, so it guarantees a result.  This
+	 * should work inside a chroot, or when file descriptors are
+	 * exhausted.
+	 *
+	 * However this can fail if the Linux kernel removes support
+	 * for sysctl.  Starting in 2007, there have been efforts to
+	 * deprecate the sysctl API/ABI, and push callers towards use
+	 * of the chroot-unavailable fd-using /proc mechanism --
+	 * essentially the same problems as /dev/urandom.
+	 *
+	 * Numerous setbacks have been encountered in their deprecation
+	 * schedule, so as of June 2014 the kernel ABI still exists on
+	 * most Linux architectures. The sysctl() stub in libc is missing
+	 * on some systems.  There are also reports that some kernels
+	 * spew messages to the console.
+	 */
+	ret = getentropy_sysctl(buf, len);
+	if (ret != -1)
+		return (ret);
+#endif /* SYS__sysctl */
+
+	/*
+	 * Entropy collection via /dev/urandom and sysctl have failed.
+	 *
+	 * No other API exists for collecting entropy.  See the large
+	 * comment block above.
+	 *
+	 * We have very few options:
+	 *     - Even syslog_r is unsafe to call at this low level, so
+	 *	 there is no way to alert the user or program.
+	 *     - Cannot call abort() because some systems have unsafe
+	 *	 corefiles.
+	 *     - Could raise(SIGKILL) resulting in silent program termination.
+	 *     - Return EIO, to hint that arc4random's stir function
+	 *       should raise(SIGKILL)
+	 *     - Do the best under the circumstances....
+	 *
+	 * This code path exists to bring light to the issue that Linux
+	 * does not provide a failsafe API for entropy collection.
+	 *
+	 * We hope this demonstrates that Linux should either retain their
+	 * sysctl ABI, or consider providing a new failsafe API which
+	 * works in a chroot or when file descriptors are exhausted.
+	 */
+#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
+#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
+	raise(SIGKILL);
+#endif
+	ret = getentropy_fallback(buf, len);
+	if (ret != -1)
+		return (ret);
+
+	errno = EIO;
+	return (ret);
+}
+
+/*
+ * Basic sanity checking; wish we could do better.
+ */
+static int
+gotdata(char *buf, size_t len)
+{
+	char	any_set = 0;
+	size_t	i;
+
+	for (i = 0; i < len; ++i)
+		any_set |= buf[i];
+	if (any_set == 0)
+		return (-1);
+	return (0);
+}
+
+#ifdef SYS_getrandom
+static int
+getentropy_getrandom(void *buf, size_t len)
+{
+	int pre_errno = errno;
+	int ret;
+	if (len > 256)
+		return (-1);
+	do {
+		ret = syscall(SYS_getrandom, buf, len, 0);
+	} while (ret == -1 && errno == EINTR);
+
+	if (ret != len)
+		return (-1);
+	errno = pre_errno;
+	return (0);
+}
+#endif
+
+static int
+getentropy_urandom(void *buf, size_t len)
+{
+	struct stat st;
+	size_t i;
+	int fd, cnt, flags;
+	int save_errno = errno;
+
+start:
+
+	flags = O_RDONLY;
+#ifdef O_NOFOLLOW
+	flags |= O_NOFOLLOW;
+#endif
+#ifdef O_CLOEXEC
+	flags |= O_CLOEXEC;
+#endif
+	fd = open("/dev/urandom", flags, 0);
+	if (fd == -1) {
+		if (errno == EINTR)
+			goto start;
+		goto nodevrandom;
+	}
+#ifndef O_CLOEXEC
+	fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+#endif
+
+	/* Lightly verify that the device node looks sane */
+	if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) {
+		close(fd);
+		goto nodevrandom;
+	}
+	if (ioctl(fd, RNDGETENTCNT, &cnt) == -1) {
+		close(fd);
+		goto nodevrandom;
+	}
+	for (i = 0; i < len; ) {
+		size_t wanted = len - i;
+		ssize_t ret = read(fd, (char *)buf + i, wanted);
+
+		if (ret == -1) {
+			if (errno == EAGAIN || errno == EINTR)
+				continue;
+			close(fd);
+			goto nodevrandom;
+		}
+		i += ret;
+	}
+	close(fd);
+	if (gotdata(buf, len) == 0) {
+		errno = save_errno;
+		return (0);		/* satisfied */
+	}
+nodevrandom:
+	errno = EIO;
+	return (-1);
+}
+
+#ifdef SYS__sysctl
+static int
+getentropy_sysctl(void *buf, size_t len)
+{
+	static int mib[] = { CTL_KERN, KERN_RANDOM, RANDOM_UUID };
+	size_t i;
+	int save_errno = errno;
+
+	for (i = 0; i < len; ) {
+		size_t chunk = min(len - i, 16);
+
+		/* SYS__sysctl because some systems already removed sysctl() */
+		struct __sysctl_args args = {
+			.name = mib,
+			.nlen = 3,
+			.oldval = (char *)buf + i,
+			.oldlenp = &chunk,
+		};
+		if (syscall(SYS__sysctl, &args) != 0)
+			goto sysctlfailed;
+		i += chunk;
+	}
+	if (gotdata(buf, len) == 0) {
+		errno = save_errno;
+		return (0);			/* satisfied */
+	}
+sysctlfailed:
+	errno = EIO;
+	return (-1);
+}
+#endif /* SYS__sysctl */
+
+static const int cl[] = {
+	CLOCK_REALTIME,
+#ifdef CLOCK_MONOTONIC
+	CLOCK_MONOTONIC,
+#endif
+#ifdef CLOCK_MONOTONIC_RAW
+	CLOCK_MONOTONIC_RAW,
+#endif
+#ifdef CLOCK_TAI
+	CLOCK_TAI,
+#endif
+#ifdef CLOCK_VIRTUAL
+	CLOCK_VIRTUAL,
+#endif
+#ifdef CLOCK_UPTIME
+	CLOCK_UPTIME,
+#endif
+#ifdef CLOCK_PROCESS_CPUTIME_ID
+	CLOCK_PROCESS_CPUTIME_ID,
+#endif
+#ifdef CLOCK_THREAD_CPUTIME_ID
+	CLOCK_THREAD_CPUTIME_ID,
+#endif
+};
+
+static int
+getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data)
+{
+	SHA512_CTX *ctx = data;
+
+	SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr));
+	return (0);
+}
+
+static int
+getentropy_fallback(void *buf, size_t len)
+{
+	uint8_t results[SHA512_DIGEST_LENGTH];
+	int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat;
+	static int cnt;
+	struct timespec ts;
+	struct timeval tv;
+	struct rusage ru;
+	sigset_t sigset;
+	struct stat st;
+	SHA512_CTX ctx;
+	static pid_t lastpid;
+	pid_t pid;
+	size_t i, ii, m;
+	char *p;
+
+	pid = getpid();
+	if (lastpid == pid) {
+		faster = 1;
+		repeat = 2;
+	} else {
+		faster = 0;
+		lastpid = pid;
+		repeat = REPEAT;
+	}
+	for (i = 0; i < len; ) {
+		int j;
+		SHA512_Init(&ctx);
+		for (j = 0; j < repeat; j++) {
+			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
+			if (e != -1) {
+				cnt += (int)tv.tv_sec;
+				cnt += (int)tv.tv_usec;
+			}
+
+			dl_iterate_phdr(getentropy_phdr, &ctx);
+
+			for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
+				HX(clock_gettime(cl[ii], &ts) == -1, ts);
+
+			HX((pid = getpid()) == -1, pid);
+			HX((pid = getsid(pid)) == -1, pid);
+			HX((pid = getppid()) == -1, pid);
+			HX((pid = getpgid(0)) == -1, pid);
+			HX((e = getpriority(0, 0)) == -1, e);
+
+			if (!faster) {
+				ts.tv_sec = 0;
+				ts.tv_nsec = 1;
+				(void) nanosleep(&ts, NULL);
+			}
+
+			HX(sigpending(&sigset) == -1, sigset);
+			HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
+			    sigset);
+
+			HF(getentropy);	/* an addr in this library */
+			HF(printf);		/* an addr in libc */
+			p = (char *)&p;
+			HD(p);		/* an addr on stack */
+			p = (char *)&errno;
+			HD(p);		/* the addr of errno */
+
+			if (i == 0) {
+				struct sockaddr_storage ss;
+				struct statvfs stvfs;
+				struct termios tios;
+				struct statfs stfs;
+				socklen_t ssl;
+				off_t off;
+
+				/*
+				 * Prime-sized mappings encourage fragmentation;
+				 * thus exposing some address entropy.
+				 */
+				struct mm {
+					size_t	npg;
+					void	*p;
+				} mm[] =	 {
+					{ 17, MAP_FAILED }, { 3, MAP_FAILED },
+					{ 11, MAP_FAILED }, { 2, MAP_FAILED },
+					{ 5, MAP_FAILED }, { 3, MAP_FAILED },
+					{ 7, MAP_FAILED }, { 1, MAP_FAILED },
+					{ 57, MAP_FAILED }, { 3, MAP_FAILED },
+					{ 131, MAP_FAILED }, { 1, MAP_FAILED },
+				};
+
+				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
+					HX(mm[m].p = mmap(NULL,
+					    mm[m].npg * pgs,
+					    PROT_READ|PROT_WRITE,
+					    MAP_PRIVATE|MAP_ANON, -1,
+					    (off_t)0), mm[m].p);
+					if (mm[m].p != MAP_FAILED) {
+						size_t mo;
+
+						/* Touch some memory... */
+						p = mm[m].p;
+						mo = cnt %
+						    (mm[m].npg * pgs - 1);
+						p[mo] = 1;
+						cnt += (int)((long)(mm[m].p)
+						    / pgs);
+					}
+
+					/* Check cnts and times... */
+					for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]);
+					    ii++) {
+						HX((e = clock_gettime(cl[ii],
+						    &ts)) == -1, ts);
+						if (e != -1)
+							cnt += (int)ts.tv_nsec;
+					}
+
+					HX((e = getrusage(RUSAGE_SELF,
+					    &ru)) == -1, ru);
+					if (e != -1) {
+						cnt += (int)ru.ru_utime.tv_sec;
+						cnt += (int)ru.ru_utime.tv_usec;
+					}
+				}
+
+				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
+					if (mm[m].p != MAP_FAILED)
+						munmap(mm[m].p, mm[m].npg * pgs);
+					mm[m].p = MAP_FAILED;
+				}
+
+				HX(stat(".", &st) == -1, st);
+				HX(statvfs(".", &stvfs) == -1, stvfs);
+				HX(statfs(".", &stfs) == -1, stfs);
+
+				HX(stat("/", &st) == -1, st);
+				HX(statvfs("/", &stvfs) == -1, stvfs);
+				HX(statfs("/", &stfs) == -1, stfs);
+
+				HX((e = fstat(0, &st)) == -1, st);
+				if (e == -1) {
+					if (S_ISREG(st.st_mode) ||
+					    S_ISFIFO(st.st_mode) ||
+					    S_ISSOCK(st.st_mode)) {
+						HX(fstatvfs(0, &stvfs) == -1,
+						    stvfs);
+						HX(fstatfs(0, &stfs) == -1,
+						    stfs);
+						HX((off = lseek(0, (off_t)0,
+						    SEEK_CUR)) < 0, off);
+					}
+					if (S_ISCHR(st.st_mode)) {
+						HX(tcgetattr(0, &tios) == -1,
+						    tios);
+					} else if (S_ISSOCK(st.st_mode)) {
+						memset(&ss, 0, sizeof ss);
+						ssl = sizeof(ss);
+						HX(getpeername(0,
+						    (void *)&ss, &ssl) == -1,
+						    ss);
+					}
+				}
+
+				HX((e = getrusage(RUSAGE_CHILDREN,
+				    &ru)) == -1, ru);
+				if (e != -1) {
+					cnt += (int)ru.ru_utime.tv_sec;
+					cnt += (int)ru.ru_utime.tv_usec;
+				}
+			} else {
+				/* Subsequent hashes absorb previous result */
+				HD(results);
+			}
+
+			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
+			if (e != -1) {
+				cnt += (int)tv.tv_sec;
+				cnt += (int)tv.tv_usec;
+			}
+
+			HD(cnt);
+		}
+#ifdef HAVE_GETAUXVAL
+#ifdef AT_RANDOM
+		/* Not as random as you think but we take what we are given */
+		p = (char *) getauxval(AT_RANDOM);
+		if (p)
+			HR(p, 16);
+#endif
+#ifdef AT_SYSINFO_EHDR
+		p = (char *) getauxval(AT_SYSINFO_EHDR);
+		if (p)
+			HR(p, pgs);
+#endif
+#ifdef AT_BASE
+		p = (char *) getauxval(AT_BASE);
+		if (p)
+			HD(p);
+#endif
+#endif
+
+		SHA512_Final(results, &ctx);
+		memcpy((char *)buf + i, results, min(sizeof(results), len - i));
+		i += min(sizeof(results), len - i);
+	}
+	explicit_bzero(&ctx, sizeof ctx);
+	explicit_bzero(results, sizeof results);
+	if (gotdata(buf, len) == 0) {
+		errno = save_errno;
+		return (0);		/* satisfied */
+	}
+	errno = EIO;
+	return (-1);
+}
diff --git a/crypto/libressl/crypto/compat/getentropy_netbsd.c b/crypto/libressl/crypto/compat/getentropy_netbsd.c
new file mode 100644
index 0000000000..c19759f668
--- /dev/null
+++ b/crypto/libressl/crypto/compat/getentropy_netbsd.c
@@ -0,0 +1,64 @@
+/*	$OpenBSD: getentropy_netbsd.c,v 1.1 2015/01/19 20:21:40 bcook Exp $	*/
+
+/*
+ * Copyright (c) 2014 Pawel Jakub Dawidek 
+ * Copyright (c) 2014 Brent Cook 
+ *
+ * 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.
+ *
+ * Emulation of getentropy(2) as documented at:
+ * http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+
+/*
+ * Derived from lib/libc/gen/arc4random.c from FreeBSD.
+ */
+static size_t
+getentropy_sysctl(u_char *buf, size_t size)
+{
+	int mib[2];
+	size_t len, done;
+
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_ARND;
+	done = 0;
+
+	do {
+		len = size;
+		if (sysctl(mib, 2, buf, &len, NULL, 0) == -1)
+			return (done);
+		done += len;
+		buf += len;
+		size -= len;
+	} while (size > 0);
+
+	return (done);
+}
+
+int
+getentropy(void *buf, size_t len)
+{
+	if (len <= 256 &&
+	    getentropy_sysctl(buf, len) == len) {
+		return (0);
+	}
+
+	errno = EIO;
+	return (-1);
+}
diff --git a/crypto/libressl/crypto/compat/getentropy_osx.c b/crypto/libressl/crypto/compat/getentropy_osx.c
new file mode 100644
index 0000000000..2bc811585a
--- /dev/null
+++ b/crypto/libressl/crypto/compat/getentropy_osx.c
@@ -0,0 +1,429 @@
+/*	$OpenBSD: getentropy_osx.c,v 1.8 2014/07/21 20:19:47 guenther Exp $	*/
+
+/*
+ * Copyright (c) 2014 Theo de Raadt 
+ * Copyright (c) 2014 Bob Beck 
+ *
+ * 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.
+ *
+ * Emulation of getentropy(2) as documented at:
+ * http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#define SHA512_Update(a, b, c)	(CC_SHA512_Update((a), (b), (c)))
+#define SHA512_Init(xxx) (CC_SHA512_Init((xxx)))
+#define SHA512_Final(xxx, yyy) (CC_SHA512_Final((xxx), (yyy)))
+#define SHA512_CTX CC_SHA512_CTX
+#define SHA512_DIGEST_LENGTH CC_SHA512_DIGEST_LENGTH
+
+#define REPEAT 5
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+
+#define HX(a, b) \
+	do { \
+		if ((a)) \
+			HD(errno); \
+		else \
+			HD(b); \
+	} while (0)
+
+#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
+#define HD(x)	 (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
+#define HF(x)    (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
+
+int	getentropy(void *buf, size_t len);
+
+static int gotdata(char *buf, size_t len);
+static int getentropy_urandom(void *buf, size_t len);
+static int getentropy_fallback(void *buf, size_t len);
+
+int
+getentropy(void *buf, size_t len)
+{
+	int ret = -1;
+
+	if (len > 256) {
+		errno = EIO;
+		return (-1);
+	}
+
+	/*
+	 * Try to get entropy with /dev/urandom
+	 *
+	 * This can fail if the process is inside a chroot or if file
+	 * descriptors are exhausted.
+	 */
+	ret = getentropy_urandom(buf, len);
+	if (ret != -1)
+		return (ret);
+
+	/*
+	 * Entropy collection via /dev/urandom and sysctl have failed.
+	 *
+	 * No other API exists for collecting entropy, and we have
+	 * no failsafe way to get it on OSX that is not sensitive
+	 * to resource exhaustion.
+	 *
+	 * We have very few options:
+	 *     - Even syslog_r is unsafe to call at this low level, so
+	 *	 there is no way to alert the user or program.
+	 *     - Cannot call abort() because some systems have unsafe
+	 *	 corefiles.
+	 *     - Could raise(SIGKILL) resulting in silent program termination.
+	 *     - Return EIO, to hint that arc4random's stir function
+	 *       should raise(SIGKILL)
+	 *     - Do the best under the circumstances....
+	 *
+	 * This code path exists to bring light to the issue that OSX
+	 * does not provide a failsafe API for entropy collection.
+	 *
+	 * We hope this demonstrates that OSX should consider
+	 * providing a new failsafe API which works in a chroot or
+	 * when file descriptors are exhausted.
+	 */
+#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
+#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
+	raise(SIGKILL);
+#endif
+	ret = getentropy_fallback(buf, len);
+	if (ret != -1)
+		return (ret);
+
+	errno = EIO;
+	return (ret);
+}
+
+/*
+ * Basic sanity checking; wish we could do better.
+ */
+static int
+gotdata(char *buf, size_t len)
+{
+	char	any_set = 0;
+	size_t	i;
+
+	for (i = 0; i < len; ++i)
+		any_set |= buf[i];
+	if (any_set == 0)
+		return (-1);
+	return (0);
+}
+
+static int
+getentropy_urandom(void *buf, size_t len)
+{
+	struct stat st;
+	size_t i;
+	int fd, flags;
+	int save_errno = errno;
+
+start:
+
+	flags = O_RDONLY;
+#ifdef O_NOFOLLOW
+	flags |= O_NOFOLLOW;
+#endif
+#ifdef O_CLOEXEC
+	flags |= O_CLOEXEC;
+#endif
+	fd = open("/dev/urandom", flags, 0);
+	if (fd == -1) {
+		if (errno == EINTR)
+			goto start;
+		goto nodevrandom;
+	}
+#ifndef O_CLOEXEC
+	fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+#endif
+
+	/* Lightly verify that the device node looks sane */
+	if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) {
+		close(fd);
+		goto nodevrandom;
+	}
+	for (i = 0; i < len; ) {
+		size_t wanted = len - i;
+		ssize_t ret = read(fd, (char *)buf + i, wanted);
+
+		if (ret == -1) {
+			if (errno == EAGAIN || errno == EINTR)
+				continue;
+			close(fd);
+			goto nodevrandom;
+		}
+		i += ret;
+	}
+	close(fd);
+	if (gotdata(buf, len) == 0) {
+		errno = save_errno;
+		return (0);		/* satisfied */
+	}
+nodevrandom:
+	errno = EIO;
+	return (-1);
+}
+
+static int tcpmib[] = { CTL_NET, AF_INET, IPPROTO_TCP, TCPCTL_STATS };
+static int udpmib[] = { CTL_NET, AF_INET, IPPROTO_UDP, UDPCTL_STATS };
+static int ipmib[] = { CTL_NET, AF_INET, IPPROTO_IP, IPCTL_STATS };
+static int kmib[] = { CTL_KERN, KERN_USRSTACK };
+static int hwmib[] = { CTL_HW, HW_USERMEM };
+
+static int
+getentropy_fallback(void *buf, size_t len)
+{
+	uint8_t results[SHA512_DIGEST_LENGTH];
+	int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat;
+	static int cnt;
+	struct timespec ts;
+	struct timeval tv;
+	struct rusage ru;
+	sigset_t sigset;
+	struct stat st;
+	SHA512_CTX ctx;
+	static pid_t lastpid;
+	pid_t pid;
+	size_t i, ii, m;
+	char *p;
+	struct tcpstat tcpstat;
+	struct udpstat udpstat;
+	struct ipstat ipstat;
+	u_int64_t mach_time;
+	unsigned int idata;
+	void *addr;
+
+	pid = getpid();
+	if (lastpid == pid) {
+		faster = 1;
+		repeat = 2;
+	} else {
+		faster = 0;
+		lastpid = pid;
+		repeat = REPEAT;
+	}
+	for (i = 0; i < len; ) {
+		int j;
+		SHA512_Init(&ctx);
+		for (j = 0; j < repeat; j++) {
+			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
+			if (e != -1) {
+				cnt += (int)tv.tv_sec;
+				cnt += (int)tv.tv_usec;
+			}
+
+			mach_time = mach_absolute_time();
+			HD(mach_time);
+
+			ii = sizeof(addr);
+			HX(sysctl(kmib, sizeof(kmib) / sizeof(kmib[0]),
+			    &addr, &ii, NULL, 0) == -1, addr);
+
+			ii = sizeof(idata);
+			HX(sysctl(hwmib, sizeof(hwmib) / sizeof(hwmib[0]),
+			    &idata, &ii, NULL, 0) == -1, idata);
+
+			ii = sizeof(tcpstat);
+			HX(sysctl(tcpmib, sizeof(tcpmib) / sizeof(tcpmib[0]),
+			    &tcpstat, &ii, NULL, 0) == -1, tcpstat);
+
+			ii = sizeof(udpstat);
+			HX(sysctl(udpmib, sizeof(udpmib) / sizeof(udpmib[0]),
+			    &udpstat, &ii, NULL, 0) == -1, udpstat);
+
+			ii = sizeof(ipstat);
+			HX(sysctl(ipmib, sizeof(ipmib) / sizeof(ipmib[0]),
+			    &ipstat, &ii, NULL, 0) == -1, ipstat);
+
+			HX((pid = getpid()) == -1, pid);
+			HX((pid = getsid(pid)) == -1, pid);
+			HX((pid = getppid()) == -1, pid);
+			HX((pid = getpgid(0)) == -1, pid);
+			HX((e = getpriority(0, 0)) == -1, e);
+
+			if (!faster) {
+				ts.tv_sec = 0;
+				ts.tv_nsec = 1;
+				(void) nanosleep(&ts, NULL);
+			}
+
+			HX(sigpending(&sigset) == -1, sigset);
+			HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
+			    sigset);
+
+			HF(getentropy);	/* an addr in this library */
+			HF(printf);		/* an addr in libc */
+			p = (char *)&p;
+			HD(p);		/* an addr on stack */
+			p = (char *)&errno;
+			HD(p);		/* the addr of errno */
+
+			if (i == 0) {
+				struct sockaddr_storage ss;
+				struct statvfs stvfs;
+				struct termios tios;
+				struct statfs stfs;
+				socklen_t ssl;
+				off_t off;
+
+				/*
+				 * Prime-sized mappings encourage fragmentation;
+				 * thus exposing some address entropy.
+				 */
+				struct mm {
+					size_t	npg;
+					void	*p;
+				} mm[] =	 {
+					{ 17, MAP_FAILED }, { 3, MAP_FAILED },
+					{ 11, MAP_FAILED }, { 2, MAP_FAILED },
+					{ 5, MAP_FAILED }, { 3, MAP_FAILED },
+					{ 7, MAP_FAILED }, { 1, MAP_FAILED },
+					{ 57, MAP_FAILED }, { 3, MAP_FAILED },
+					{ 131, MAP_FAILED }, { 1, MAP_FAILED },
+				};
+
+				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
+					HX(mm[m].p = mmap(NULL,
+					    mm[m].npg * pgs,
+					    PROT_READ|PROT_WRITE,
+					    MAP_PRIVATE|MAP_ANON, -1,
+					    (off_t)0), mm[m].p);
+					if (mm[m].p != MAP_FAILED) {
+						size_t mo;
+
+						/* Touch some memory... */
+						p = mm[m].p;
+						mo = cnt %
+						    (mm[m].npg * pgs - 1);
+						p[mo] = 1;
+						cnt += (int)((long)(mm[m].p)
+						    / pgs);
+					}
+
+					/* Check cnts and times... */
+					mach_time = mach_absolute_time();
+					HD(mach_time);
+					cnt += (int)mach_time;
+
+					HX((e = getrusage(RUSAGE_SELF,
+					    &ru)) == -1, ru);
+					if (e != -1) {
+						cnt += (int)ru.ru_utime.tv_sec;
+						cnt += (int)ru.ru_utime.tv_usec;
+					}
+				}
+
+				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
+					if (mm[m].p != MAP_FAILED)
+						munmap(mm[m].p, mm[m].npg * pgs);
+					mm[m].p = MAP_FAILED;
+				}
+
+				HX(stat(".", &st) == -1, st);
+				HX(statvfs(".", &stvfs) == -1, stvfs);
+				HX(statfs(".", &stfs) == -1, stfs);
+
+				HX(stat("/", &st) == -1, st);
+				HX(statvfs("/", &stvfs) == -1, stvfs);
+				HX(statfs("/", &stfs) == -1, stfs);
+
+				HX((e = fstat(0, &st)) == -1, st);
+				if (e == -1) {
+					if (S_ISREG(st.st_mode) ||
+					    S_ISFIFO(st.st_mode) ||
+					    S_ISSOCK(st.st_mode)) {
+						HX(fstatvfs(0, &stvfs) == -1,
+						    stvfs);
+						HX(fstatfs(0, &stfs) == -1,
+						    stfs);
+						HX((off = lseek(0, (off_t)0,
+						    SEEK_CUR)) < 0, off);
+					}
+					if (S_ISCHR(st.st_mode)) {
+						HX(tcgetattr(0, &tios) == -1,
+						    tios);
+					} else if (S_ISSOCK(st.st_mode)) {
+						memset(&ss, 0, sizeof ss);
+						ssl = sizeof(ss);
+						HX(getpeername(0,
+						    (void *)&ss, &ssl) == -1,
+						    ss);
+					}
+				}
+
+				HX((e = getrusage(RUSAGE_CHILDREN,
+				    &ru)) == -1, ru);
+				if (e != -1) {
+					cnt += (int)ru.ru_utime.tv_sec;
+					cnt += (int)ru.ru_utime.tv_usec;
+				}
+			} else {
+				/* Subsequent hashes absorb previous result */
+				HD(results);
+			}
+
+			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
+			if (e != -1) {
+				cnt += (int)tv.tv_sec;
+				cnt += (int)tv.tv_usec;
+			}
+
+			HD(cnt);
+		}
+
+		SHA512_Final(results, &ctx);
+		memcpy((char *)buf + i, results, min(sizeof(results), len - i));
+		i += min(sizeof(results), len - i);
+	}
+	explicit_bzero(&ctx, sizeof ctx);
+	explicit_bzero(results, sizeof results);
+	if (gotdata(buf, len) == 0) {
+		errno = save_errno;
+		return (0);		/* satisfied */
+	}
+	errno = EIO;
+	return (-1);
+}
diff --git a/crypto/libressl/crypto/compat/getentropy_solaris.c b/crypto/libressl/crypto/compat/getentropy_solaris.c
new file mode 100644
index 0000000000..ca787f89d3
--- /dev/null
+++ b/crypto/libressl/crypto/compat/getentropy_solaris.c
@@ -0,0 +1,445 @@
+/*	$OpenBSD: getentropy_solaris.c,v 1.10 2015/08/25 17:26:43 deraadt Exp $	*/
+
+/*
+ * Copyright (c) 2014 Theo de Raadt 
+ * Copyright (c) 2014 Bob Beck 
+ *
+ * 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.
+ *
+ * Emulation of getentropy(2) as documented at:
+ * http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#define SHA512_Init SHA512Init
+#define SHA512_Update SHA512Update
+#define SHA512_Final SHA512Final
+
+#include 
+#include 
+#include 
+
+#define REPEAT 5
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+
+#define HX(a, b) \
+	do { \
+		if ((a)) \
+			HD(errno); \
+		else \
+			HD(b); \
+	} while (0)
+
+#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
+#define HD(x)	 (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
+#define HF(x)    (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
+
+int	getentropy(void *buf, size_t len);
+
+static int gotdata(char *buf, size_t len);
+static int getentropy_urandom(void *buf, size_t len, const char *path,
+    int devfscheck);
+static int getentropy_fallback(void *buf, size_t len);
+static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data);
+
+int
+getentropy(void *buf, size_t len)
+{
+	int ret = -1;
+
+	if (len > 256) {
+		errno = EIO;
+		return (-1);
+	}
+
+	/*
+	 * Try to get entropy with /dev/urandom
+	 *
+	 * Solaris provides /dev/urandom as a symbolic link to
+	 * /devices/pseudo/random@0:urandom which is provided by
+	 * a devfs filesystem.  Best practice is to use O_NOFOLLOW,
+	 * so we must try the unpublished name directly.
+	 *
+	 * This can fail if the process is inside a chroot which lacks
+	 * the devfs mount, or if file descriptors are exhausted.
+	 */
+	ret = getentropy_urandom(buf, len,
+	    "/devices/pseudo/random@0:urandom", 1);
+	if (ret != -1)
+		return (ret);
+
+	/*
+	 * Unfortunately, chroot spaces on Solaris are sometimes setup
+	 * with direct device node of the well-known /dev/urandom name
+	 * (perhaps to avoid dragging all of devfs into the space).
+	 *
+	 * This can fail if the process is inside a chroot or if file
+	 * descriptors are exhausted.
+	 */
+	ret = getentropy_urandom(buf, len, "/dev/urandom", 0);
+	if (ret != -1)
+		return (ret);
+
+	/*
+	 * Entropy collection via /dev/urandom has failed.
+	 *
+	 * No other API exists for collecting entropy, and we have
+	 * no failsafe way to get it on Solaris that is not sensitive
+	 * to resource exhaustion.
+	 *
+	 * We have very few options:
+	 *     - Even syslog_r is unsafe to call at this low level, so
+	 *	 there is no way to alert the user or program.
+	 *     - Cannot call abort() because some systems have unsafe
+	 *	 corefiles.
+	 *     - Could raise(SIGKILL) resulting in silent program termination.
+	 *     - Return EIO, to hint that arc4random's stir function
+	 *       should raise(SIGKILL)
+	 *     - Do the best under the circumstances....
+	 *
+	 * This code path exists to bring light to the issue that Solaris
+	 * does not provide a failsafe API for entropy collection.
+	 *
+	 * We hope this demonstrates that Solaris should consider
+	 * providing a new failsafe API which works in a chroot or
+	 * when file descriptors are exhausted.
+	 */
+#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
+#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
+	raise(SIGKILL);
+#endif
+	ret = getentropy_fallback(buf, len);
+	if (ret != -1)
+		return (ret);
+
+	errno = EIO;
+	return (ret);
+}
+
+/*
+ * Basic sanity checking; wish we could do better.
+ */
+static int
+gotdata(char *buf, size_t len)
+{
+	char	any_set = 0;
+	size_t	i;
+
+	for (i = 0; i < len; ++i)
+		any_set |= buf[i];
+	if (any_set == 0)
+		return (-1);
+	return (0);
+}
+
+static int
+getentropy_urandom(void *buf, size_t len, const char *path, int devfscheck)
+{
+	struct stat st;
+	size_t i;
+	int fd, flags;
+	int save_errno = errno;
+
+start:
+
+	flags = O_RDONLY;
+#ifdef O_NOFOLLOW
+	flags |= O_NOFOLLOW;
+#endif
+#ifdef O_CLOEXEC
+	flags |= O_CLOEXEC;
+#endif
+	fd = open(path, flags, 0);
+	if (fd == -1) {
+		if (errno == EINTR)
+			goto start;
+		goto nodevrandom;
+	}
+#ifndef O_CLOEXEC
+	fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+#endif
+
+	/* Lightly verify that the device node looks sane */
+	if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode) ||
+	    (devfscheck && (strcmp(st.st_fstype, "devfs") != 0))) {
+		close(fd);
+		goto nodevrandom;
+	}
+	for (i = 0; i < len; ) {
+		size_t wanted = len - i;
+		ssize_t ret = read(fd, (char *)buf + i, wanted);
+
+		if (ret == -1) {
+			if (errno == EAGAIN || errno == EINTR)
+				continue;
+			close(fd);
+			goto nodevrandom;
+		}
+		i += ret;
+	}
+	close(fd);
+	if (gotdata(buf, len) == 0) {
+		errno = save_errno;
+		return (0);		/* satisfied */
+	}
+nodevrandom:
+	errno = EIO;
+	return (-1);
+}
+
+static const int cl[] = {
+	CLOCK_REALTIME,
+#ifdef CLOCK_MONOTONIC
+	CLOCK_MONOTONIC,
+#endif
+#ifdef CLOCK_MONOTONIC_RAW
+	CLOCK_MONOTONIC_RAW,
+#endif
+#ifdef CLOCK_TAI
+	CLOCK_TAI,
+#endif
+#ifdef CLOCK_VIRTUAL
+	CLOCK_VIRTUAL,
+#endif
+#ifdef CLOCK_UPTIME
+	CLOCK_UPTIME,
+#endif
+#ifdef CLOCK_PROCESS_CPUTIME_ID
+	CLOCK_PROCESS_CPUTIME_ID,
+#endif
+#ifdef CLOCK_THREAD_CPUTIME_ID
+	CLOCK_THREAD_CPUTIME_ID,
+#endif
+};
+
+static int
+getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data)
+{
+	SHA512_CTX *ctx = data;
+
+	SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr));
+	return (0);
+}
+
+static int
+getentropy_fallback(void *buf, size_t len)
+{
+	uint8_t results[SHA512_DIGEST_LENGTH];
+	int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat;
+	static int cnt;
+	struct timespec ts;
+	struct timeval tv;
+	double loadavg[3];
+	struct rusage ru;
+	sigset_t sigset;
+	struct stat st;
+	SHA512_CTX ctx;
+	static pid_t lastpid;
+	pid_t pid;
+	size_t i, ii, m;
+	char *p;
+
+	pid = getpid();
+	if (lastpid == pid) {
+		faster = 1;
+		repeat = 2;
+	} else {
+		faster = 0;
+		lastpid = pid;
+		repeat = REPEAT;
+	}
+	for (i = 0; i < len; ) {
+		int j;
+		SHA512_Init(&ctx);
+		for (j = 0; j < repeat; j++) {
+			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
+			if (e != -1) {
+				cnt += (int)tv.tv_sec;
+				cnt += (int)tv.tv_usec;
+			}
+
+			dl_iterate_phdr(getentropy_phdr, &ctx);
+
+			for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
+				HX(clock_gettime(cl[ii], &ts) == -1, ts);
+
+			HX((pid = getpid()) == -1, pid);
+			HX((pid = getsid(pid)) == -1, pid);
+			HX((pid = getppid()) == -1, pid);
+			HX((pid = getpgid(0)) == -1, pid);
+			HX((e = getpriority(0, 0)) == -1, e);
+			HX((getloadavg(loadavg, 3) == -1), loadavg);
+
+			if (!faster) {
+				ts.tv_sec = 0;
+				ts.tv_nsec = 1;
+				(void) nanosleep(&ts, NULL);
+			}
+
+			HX(sigpending(&sigset) == -1, sigset);
+			HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
+			    sigset);
+
+			HF(getentropy);	/* an addr in this library */
+			HF(printf);		/* an addr in libc */
+			p = (char *)&p;
+			HD(p);		/* an addr on stack */
+			p = (char *)&errno;
+			HD(p);		/* the addr of errno */
+
+			if (i == 0) {
+				struct sockaddr_storage ss;
+				struct statvfs stvfs;
+				struct termios tios;
+				socklen_t ssl;
+				off_t off;
+
+				/*
+				 * Prime-sized mappings encourage fragmentation;
+				 * thus exposing some address entropy.
+				 */
+				struct mm {
+					size_t	npg;
+					void	*p;
+				} mm[] =	 {
+					{ 17, MAP_FAILED }, { 3, MAP_FAILED },
+					{ 11, MAP_FAILED }, { 2, MAP_FAILED },
+					{ 5, MAP_FAILED }, { 3, MAP_FAILED },
+					{ 7, MAP_FAILED }, { 1, MAP_FAILED },
+					{ 57, MAP_FAILED }, { 3, MAP_FAILED },
+					{ 131, MAP_FAILED }, { 1, MAP_FAILED },
+				};
+
+				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
+					HX(mm[m].p = mmap(NULL,
+					    mm[m].npg * pgs,
+					    PROT_READ|PROT_WRITE,
+					    MAP_PRIVATE|MAP_ANON, -1,
+					    (off_t)0), mm[m].p);
+					if (mm[m].p != MAP_FAILED) {
+						size_t mo;
+
+						/* Touch some memory... */
+						p = mm[m].p;
+						mo = cnt %
+						    (mm[m].npg * pgs - 1);
+						p[mo] = 1;
+						cnt += (int)((long)(mm[m].p)
+						    / pgs);
+					}
+
+					/* Check cnts and times... */
+					for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]);
+					    ii++) {
+						HX((e = clock_gettime(cl[ii],
+						    &ts)) == -1, ts);
+						if (e != -1)
+							cnt += (int)ts.tv_nsec;
+					}
+
+					HX((e = getrusage(RUSAGE_SELF,
+					    &ru)) == -1, ru);
+					if (e != -1) {
+						cnt += (int)ru.ru_utime.tv_sec;
+						cnt += (int)ru.ru_utime.tv_usec;
+					}
+				}
+
+				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
+					if (mm[m].p != MAP_FAILED)
+						munmap(mm[m].p, mm[m].npg * pgs);
+					mm[m].p = MAP_FAILED;
+				}
+
+				HX(stat(".", &st) == -1, st);
+				HX(statvfs(".", &stvfs) == -1, stvfs);
+
+				HX(stat("/", &st) == -1, st);
+				HX(statvfs("/", &stvfs) == -1, stvfs);
+
+				HX((e = fstat(0, &st)) == -1, st);
+				if (e == -1) {
+					if (S_ISREG(st.st_mode) ||
+					    S_ISFIFO(st.st_mode) ||
+					    S_ISSOCK(st.st_mode)) {
+						HX(fstatvfs(0, &stvfs) == -1,
+						    stvfs);
+						HX((off = lseek(0, (off_t)0,
+						    SEEK_CUR)) < 0, off);
+					}
+					if (S_ISCHR(st.st_mode)) {
+						HX(tcgetattr(0, &tios) == -1,
+						    tios);
+					} else if (S_ISSOCK(st.st_mode)) {
+						memset(&ss, 0, sizeof ss);
+						ssl = sizeof(ss);
+						HX(getpeername(0,
+						    (void *)&ss, &ssl) == -1,
+						    ss);
+					}
+				}
+
+				HX((e = getrusage(RUSAGE_CHILDREN,
+				    &ru)) == -1, ru);
+				if (e != -1) {
+					cnt += (int)ru.ru_utime.tv_sec;
+					cnt += (int)ru.ru_utime.tv_usec;
+				}
+			} else {
+				/* Subsequent hashes absorb previous result */
+				HD(results);
+			}
+
+			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
+			if (e != -1) {
+				cnt += (int)tv.tv_sec;
+				cnt += (int)tv.tv_usec;
+			}
+
+			HD(cnt);
+		}
+		SHA512_Final(results, &ctx);
+		memcpy((char *)buf + i, results, min(sizeof(results), len - i));
+		i += min(sizeof(results), len - i);
+	}
+	explicit_bzero(&ctx, sizeof ctx);
+	explicit_bzero(results, sizeof results);
+	if (gotdata(buf, len) == 0) {
+		errno = save_errno;
+		return (0);		/* satisfied */
+	}
+	errno = EIO;
+	return (-1);
+}
diff --git a/crypto/libressl/crypto/compat/getentropy_win.c b/crypto/libressl/crypto/compat/getentropy_win.c
new file mode 100644
index 0000000000..1a8d0eb791
--- /dev/null
+++ b/crypto/libressl/crypto/compat/getentropy_win.c
@@ -0,0 +1,59 @@
+/*	$OpenBSD: getentropy_win.c,v 1.3 2014/11/11 13:54:33 bcook Exp $	*/
+
+/*
+ * Copyright (c) 2014, Theo de Raadt  
+ * Copyright (c) 2014, Bob Beck 
+ *
+ * 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.
+ *
+ * Emulation of getentropy(2) as documented at:
+ * http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+int	getentropy(void *buf, size_t len);
+
+/*
+ * On Windows, CryptGenRandom is supposed to be a well-seeded
+ * cryptographically strong random number generator.
+ */
+int
+getentropy(void *buf, size_t len)
+{
+	HCRYPTPROV provider;
+
+	if (len > 256) {
+		errno = EIO;
+		return (-1);
+	}
+
+	if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
+	    CRYPT_VERIFYCONTEXT) == 0)
+		goto fail;
+	if (CryptGenRandom(provider, len, buf) == 0) {
+		CryptReleaseContext(provider, 0);
+		goto fail;
+	}
+	CryptReleaseContext(provider, 0);
+	return (0);
+
+fail:
+	errno = EIO;
+	return (-1);
+}
diff --git a/crypto/libressl/crypto/compat/inet_pton.c b/crypto/libressl/crypto/compat/inet_pton.c
new file mode 100644
index 0000000000..f8e299b7b8
--- /dev/null
+++ b/crypto/libressl/crypto/compat/inet_pton.c
@@ -0,0 +1,212 @@
+/*	$OpenBSD: inet_pton.c,v 1.9 2015/01/16 16:48:51 deraadt Exp $	*/
+
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int	inet_pton4(const char *src, u_char *dst);
+static int	inet_pton6(const char *src, u_char *dst);
+
+/* int
+ * inet_pton(af, src, dst)
+ *	convert from presentation format (which usually means ASCII printable)
+ *	to network format (which is usually some kind of binary format).
+ * return:
+ *	1 if the address was valid for the specified address family
+ *	0 if the address wasn't valid (`dst' is untouched in this case)
+ *	-1 if some other error occurred (`dst' is untouched in this case, too)
+ * author:
+ *	Paul Vixie, 1996.
+ */
+int
+inet_pton(int af, const char *src, void *dst)
+{
+	switch (af) {
+	case AF_INET:
+		return (inet_pton4(src, dst));
+	case AF_INET6:
+		return (inet_pton6(src, dst));
+	default:
+		errno = EAFNOSUPPORT;
+		return (-1);
+	}
+	/* NOTREACHED */
+}
+
+/* int
+ * inet_pton4(src, dst)
+ *	like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ *	1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ *	does not touch `dst' unless it's returning 1.
+ * author:
+ *	Paul Vixie, 1996.
+ */
+static int
+inet_pton4(const char *src, u_char *dst)
+{
+	static const char digits[] = "0123456789";
+	int saw_digit, octets, ch;
+	u_char tmp[INADDRSZ], *tp;
+
+	saw_digit = 0;
+	octets = 0;
+	*(tp = tmp) = 0;
+	while ((ch = *src++) != '\0') {
+		const char *pch;
+
+		if ((pch = strchr(digits, ch)) != NULL) {
+			u_int new = *tp * 10 + (pch - digits);
+
+			if (new > 255)
+				return (0);
+			if (! saw_digit) {
+				if (++octets > 4)
+					return (0);
+				saw_digit = 1;
+			}
+			*tp = new;
+		} else if (ch == '.' && saw_digit) {
+			if (octets == 4)
+				return (0);
+			*++tp = 0;
+			saw_digit = 0;
+		} else
+			return (0);
+	}
+	if (octets < 4)
+		return (0);
+
+	memcpy(dst, tmp, INADDRSZ);
+	return (1);
+}
+
+/* int
+ * inet_pton6(src, dst)
+ *	convert presentation level address to network order binary form.
+ * return:
+ *	1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ *	does not touch `dst' unless it's returning 1.
+ * credit:
+ *	inspired by Mark Andrews.
+ * author:
+ *	Paul Vixie, 1996.
+ */
+static int
+inet_pton6(const char *src, u_char *dst)
+{
+	static const char xdigits_l[] = "0123456789abcdef",
+			  xdigits_u[] = "0123456789ABCDEF";
+	u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
+	const char *xdigits, *curtok;
+	int ch, saw_xdigit, count_xdigit;
+	u_int val;
+
+	memset((tp = tmp), '\0', IN6ADDRSZ);
+	endp = tp + IN6ADDRSZ;
+	colonp = NULL;
+	/* Leading :: requires some special handling. */
+	if (*src == ':')
+		if (*++src != ':')
+			return (0);
+	curtok = src;
+	saw_xdigit = count_xdigit = 0;
+	val = 0;
+	while ((ch = *src++) != '\0') {
+		const char *pch;
+
+		if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+			pch = strchr((xdigits = xdigits_u), ch);
+		if (pch != NULL) {
+			if (count_xdigit >= 4)
+				return (0);
+			val <<= 4;
+			val |= (pch - xdigits);
+			if (val > 0xffff)
+				return (0);
+			saw_xdigit = 1;
+			count_xdigit++;
+			continue;
+		}
+		if (ch == ':') {
+			curtok = src;
+			if (!saw_xdigit) {
+				if (colonp)
+					return (0);
+				colonp = tp;
+				continue;
+			} else if (*src == '\0') {
+				return (0);
+			}
+			if (tp + INT16SZ > endp)
+				return (0);
+			*tp++ = (u_char) (val >> 8) & 0xff;
+			*tp++ = (u_char) val & 0xff;
+			saw_xdigit = 0;
+			count_xdigit = 0;
+			val = 0;
+			continue;
+		}
+		if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
+		    inet_pton4(curtok, tp) > 0) {
+			tp += INADDRSZ;
+			saw_xdigit = 0;
+			count_xdigit = 0;
+			break;	/* '\0' was seen by inet_pton4(). */
+		}
+		return (0);
+	}
+	if (saw_xdigit) {
+		if (tp + INT16SZ > endp)
+			return (0);
+		*tp++ = (u_char) (val >> 8) & 0xff;
+		*tp++ = (u_char) val & 0xff;
+	}
+	if (colonp != NULL) {
+		/*
+		 * Since some memmove()'s erroneously fail to handle
+		 * overlapping regions, we'll do the shift by hand.
+		 */
+		const int n = tp - colonp;
+		int i;
+
+		if (tp == endp)
+			return (0);
+		for (i = 1; i <= n; i++) {
+			endp[- i] = colonp[n - i];
+			colonp[n - i] = 0;
+		}
+		tp = endp;
+	}
+	if (tp != endp)
+		return (0);
+	memcpy(dst, tmp, IN6ADDRSZ);
+	return (1);
+}
diff --git a/crypto/libressl/crypto/compat/posix_win.c b/crypto/libressl/crypto/compat/posix_win.c
new file mode 100644
index 0000000000..110323a3df
--- /dev/null
+++ b/crypto/libressl/crypto/compat/posix_win.c
@@ -0,0 +1,214 @@
+/*
+ * Public domain
+ *
+ * BSD socket emulation code for Winsock2
+ * File IO compatibility shims
+ * Brent Cook 
+ */
+
+#define NO_REDEF_POSIX_FUNCTIONS
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+void
+posix_perror(const char *s)
+{
+	fprintf(stderr, "%s: %s\n", s, strerror(errno));
+}
+
+FILE *
+posix_fopen(const char *path, const char *mode)
+{
+	if (strchr(mode, 'b') == NULL) {
+		char *bin_mode = NULL;
+		if (asprintf(&bin_mode, "%sb", mode) == -1)
+			return NULL;
+		FILE *f = fopen(path, bin_mode);
+		free(bin_mode);
+		return f;
+	}
+
+	return fopen(path, mode);
+}
+
+char *
+posix_fgets(char *s, int size, FILE *stream)
+{
+	char *ret = fgets(s, size, stream);
+	if (ret != NULL) {
+		size_t end = strlen(ret);
+		if (end >= 2 && ret[end - 2] == '\r' && ret[end - 1] == '\n') {
+			ret[end - 2] = '\n';
+			ret[end - 1] = '\0';
+		}
+	}
+	return ret;
+}
+
+int
+posix_rename(const char *oldpath, const char *newpath)
+{
+	return MoveFileEx(oldpath, newpath, MOVEFILE_REPLACE_EXISTING) ? 0 : -1;
+}
+
+static int
+wsa_errno(int err)
+{
+	switch (err) {
+	case WSAENOBUFS:
+		errno = ENOMEM;
+		break;
+	case WSAEACCES:
+		errno = EACCES;
+		break;
+	case WSANOTINITIALISED:
+		errno = EPERM;
+		break;
+	case WSAEHOSTUNREACH:
+	case WSAENETDOWN:
+		errno = EIO;
+		break;
+	case WSAEFAULT:
+		errno = EFAULT;
+		break;
+	case WSAEINTR:
+		errno = EINTR;
+		break;
+	case WSAEINVAL:
+		errno = EINVAL;
+		break;
+	case WSAEINPROGRESS:
+		errno = EINPROGRESS;
+		break;
+	case WSAEWOULDBLOCK:
+		errno = EAGAIN;
+		break;
+	case WSAEOPNOTSUPP:
+		errno = ENOTSUP;
+		break;
+	case WSAEMSGSIZE:
+		errno = EFBIG;
+		break;
+	case WSAENOTSOCK:
+		errno = ENOTSOCK;
+		break;
+	case WSAENOPROTOOPT:
+		errno = ENOPROTOOPT;
+		break;
+	case WSAECONNREFUSED:
+		errno = ECONNREFUSED;
+		break;
+	case WSAEAFNOSUPPORT:
+		errno = EAFNOSUPPORT;
+		break;
+	case WSAENETRESET:
+	case WSAENOTCONN:
+	case WSAECONNABORTED:
+	case WSAECONNRESET:
+	case WSAESHUTDOWN:
+	case WSAETIMEDOUT:
+		errno = EPIPE;
+		break;
+	}
+	return -1;
+}
+
+int
+posix_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
+{
+	int rc = connect(sockfd, addr, addrlen);
+	if (rc == SOCKET_ERROR)
+		return wsa_errno(WSAGetLastError());
+	return rc;
+}
+
+int
+posix_close(int fd)
+{
+	if (closesocket(fd) == SOCKET_ERROR) {
+		int err = WSAGetLastError();
+		return err == WSAENOTSOCK ?
+			close(fd) : wsa_errno(err);
+	}
+	return 0;
+}
+
+ssize_t
+posix_read(int fd, void *buf, size_t count)
+{
+	ssize_t rc = recv(fd, buf, count, 0);
+	if (rc == SOCKET_ERROR) {
+		int err = WSAGetLastError();
+		return err == WSAENOTSOCK ?
+			read(fd, buf, count) : wsa_errno(err);
+	}
+	return rc;
+}
+
+ssize_t
+posix_write(int fd, const void *buf, size_t count)
+{
+	ssize_t rc = send(fd, buf, count, 0);
+	if (rc == SOCKET_ERROR) {
+		int err = WSAGetLastError();
+		return err == WSAENOTSOCK ?
+			write(fd, buf, count) : wsa_errno(err);
+	}
+	return rc;
+}
+
+int
+posix_getsockopt(int sockfd, int level, int optname,
+	void *optval, socklen_t *optlen)
+{
+	int rc = getsockopt(sockfd, level, optname, (char *)optval, optlen);
+	return rc == 0 ? 0 : wsa_errno(WSAGetLastError());
+
+}
+
+int
+posix_setsockopt(int sockfd, int level, int optname,
+	const void *optval, socklen_t optlen)
+{
+	int rc = setsockopt(sockfd, level, optname, (char *)optval, optlen);
+	return rc == 0 ? 0 : wsa_errno(WSAGetLastError());
+}
+
+#ifdef _MSC_VER
+int gettimeofday(struct timeval * tp, struct timezone * tzp)
+{
+	/*
+	 * Note: some broken versions only have 8 trailing zero's, the correct
+	 * epoch has 9 trailing zero's
+	 */
+	static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);
+
+	SYSTEMTIME  system_time;
+	FILETIME    file_time;
+	uint64_t    time;
+
+	GetSystemTime(&system_time);
+	SystemTimeToFileTime(&system_time, &file_time);
+	time = ((uint64_t)file_time.dwLowDateTime);
+	time += ((uint64_t)file_time.dwHighDateTime) << 32;
+
+	tp->tv_sec = (long)((time - EPOCH) / 10000000L);
+	tp->tv_usec = (long)(system_time.wMilliseconds * 1000);
+	return 0;
+}
+
+unsigned int sleep(unsigned int seconds)
+{
+	Sleep(seconds * 1000);
+	return seconds;
+}
+
+#endif
diff --git a/crypto/libressl/crypto/compat/reallocarray.c b/crypto/libressl/crypto/compat/reallocarray.c
new file mode 100644
index 0000000000..ed3244e22f
--- /dev/null
+++ b/crypto/libressl/crypto/compat/reallocarray.c
@@ -0,0 +1,38 @@
+/*	$OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $	*/
+/*
+ * Copyright (c) 2008 Otto Moerbeek 
+ *
+ * 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 
+#include 
+#include 
+#include 
+
+/*
+ * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
+ * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
+ */
+#define MUL_NO_OVERFLOW	((size_t)1 << (sizeof(size_t) * 4))
+
+void *
+reallocarray(void *optr, size_t nmemb, size_t size)
+{
+	if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+	    nmemb > 0 && SIZE_MAX / nmemb < size) {
+		errno = ENOMEM;
+		return NULL;
+	}
+	return realloc(optr, size * nmemb);
+}
diff --git a/crypto/libressl/crypto/compat/strcasecmp.c b/crypto/libressl/crypto/compat/strcasecmp.c
new file mode 100644
index 0000000000..2be09136c0
--- /dev/null
+++ b/crypto/libressl/crypto/compat/strcasecmp.c
@@ -0,0 +1,105 @@
+/*	$OpenBSD: strcasecmp.c,v 1.6 2005/08/08 08:05:37 espie Exp $	*/
+
+/*
+ * Copyright (c) 1987, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include 
+
+typedef unsigned char u_char;
+
+/*
+ * This array is designed for mapping upper and lower case letter
+ * together for a case independent comparison.  The mappings are
+ * based upon ascii character sequences.
+ */
+static const u_char charmap[] = {
+	'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+	'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+	'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+	'\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+	'\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
+	'\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
+	'\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
+	'\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
+	'\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+	'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+	'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+	'\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
+	'\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+	'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+	'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+	'\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
+	'\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
+	'\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
+	'\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
+	'\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
+	'\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
+	'\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
+	'\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
+	'\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
+	'\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
+	'\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
+	'\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
+	'\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
+	'\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+	'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+	'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+	'\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
+};
+
+int
+strcasecmp(const char *s1, const char *s2)
+{
+	const u_char *cm = charmap;
+	const u_char *us1 = (const u_char *)s1;
+	const u_char *us2 = (const u_char *)s2;
+
+	while (cm[*us1] == cm[*us2++])
+		if (*us1++ == '\0')
+			return (0);
+	return (cm[*us1] - cm[*--us2]);
+}
+
+int
+strncasecmp(const char *s1, const char *s2, size_t n)
+{
+	if (n != 0) {
+		const u_char *cm = charmap;
+		const u_char *us1 = (const u_char *)s1;
+		const u_char *us2 = (const u_char *)s2;
+
+		do {
+			if (cm[*us1] != cm[*us2++])
+				return (cm[*us1] - cm[*--us2]);
+			if (*us1++ == '\0')
+				break;
+		} while (--n != 0);
+	}
+	return (0);
+}
diff --git a/crypto/libressl/crypto/compat/strlcat.c b/crypto/libressl/crypto/compat/strlcat.c
new file mode 100644
index 0000000000..14c53a1f69
--- /dev/null
+++ b/crypto/libressl/crypto/compat/strlcat.c
@@ -0,0 +1,55 @@
+/*	$OpenBSD: strlcat.c,v 1.15 2015/03/02 21:41:08 millert Exp $	*/
+
+/*
+ * Copyright (c) 1998, 2015 Todd C. 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 
+#include 
+
+/*
+ * Appends src to string dst of size dsize (unlike strncat, dsize is the
+ * full size of dst, not space left).  At most dsize-1 characters
+ * will be copied.  Always NUL terminates (unless dsize <= strlen(dst)).
+ * Returns strlen(src) + MIN(dsize, strlen(initial dst)).
+ * If retval >= dsize, truncation occurred.
+ */
+size_t
+strlcat(char *dst, const char *src, size_t dsize)
+{
+	const char *odst = dst;
+	const char *osrc = src;
+	size_t n = dsize;
+	size_t dlen;
+
+	/* Find the end of dst and adjust bytes left but don't go past end. */
+	while (n-- != 0 && *dst != '\0')
+		dst++;
+	dlen = dst - odst;
+	n = dsize - dlen;
+
+	if (n-- == 0)
+		return(dlen + strlen(src));
+	while (*src != '\0') {
+		if (n != 0) {
+			*dst++ = *src;
+			n--;
+		}
+		src++;
+	}
+	*dst = '\0';
+
+	return(dlen + (src - osrc));	/* count does not include NUL */
+}
diff --git a/crypto/libressl/crypto/compat/strlcpy.c b/crypto/libressl/crypto/compat/strlcpy.c
new file mode 100644
index 0000000000..e9a7fe4be7
--- /dev/null
+++ b/crypto/libressl/crypto/compat/strlcpy.c
@@ -0,0 +1,50 @@
+/*	$OpenBSD: strlcpy.c,v 1.12 2015/01/15 03:54:12 millert Exp $	*/
+
+/*
+ * Copyright (c) 1998, 2015 Todd C. 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 
+#include 
+
+/*
+ * Copy string src to buffer dst of size dsize.  At most dsize-1
+ * chars will be copied.  Always NUL terminates (unless dsize == 0).
+ * Returns strlen(src); if retval >= dsize, truncation occurred.
+ */
+size_t
+strlcpy(char *dst, const char *src, size_t dsize)
+{
+	const char *osrc = src;
+	size_t nleft = dsize;
+
+	/* Copy as many bytes as will fit. */
+	if (nleft != 0) {
+		while (--nleft != 0) {
+			if ((*dst++ = *src++) == '\0')
+				break;
+		}
+	}
+
+	/* Not enough room in dst, add NUL and traverse rest of src. */
+	if (nleft == 0) {
+		if (dsize != 0)
+			*dst = '\0';		/* NUL-terminate dst */
+		while (*src++)
+			;
+	}
+
+	return(src - osrc - 1);	/* count does not include NUL */
+}
diff --git a/crypto/libressl/crypto/compat/strndup.c b/crypto/libressl/crypto/compat/strndup.c
new file mode 100644
index 0000000000..27701ac555
--- /dev/null
+++ b/crypto/libressl/crypto/compat/strndup.c
@@ -0,0 +1,39 @@
+/*	$OpenBSD: strndup.c,v 1.1 2010/05/18 22:24:55 tedu Exp $	*/
+
+/*
+ * Copyright (c) 2010 Todd C. 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 
+
+#include 
+#include 
+#include 
+
+char *
+strndup(const char *str, size_t maxlen)
+{
+	char *copy;
+	size_t len;
+
+	len = strnlen(str, maxlen);
+	copy = malloc(len + 1);
+	if (copy != NULL) {
+		(void)memcpy(copy, str, len);
+		copy[len] = '\0';
+	}
+
+	return copy;
+}
diff --git a/crypto/libressl/crypto/compat/strnlen.c b/crypto/libressl/crypto/compat/strnlen.c
new file mode 100644
index 0000000000..872cfa6cce
--- /dev/null
+++ b/crypto/libressl/crypto/compat/strnlen.c
@@ -0,0 +1,32 @@
+/*	$OpenBSD: strnlen.c,v 1.5 2014/06/10 04:17:37 deraadt Exp $	*/
+
+/*
+ * Copyright (c) 2010 Todd C. 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 
+
+#include 
+
+size_t
+strnlen(const char *str, size_t maxlen)
+{
+	const char *cp;
+
+	for (cp = str; maxlen != 0 && *cp != '\0'; cp++, maxlen--)
+		;
+
+	return (size_t)(cp - str);
+}
diff --git a/crypto/libressl/crypto/compat/timegm.c b/crypto/libressl/crypto/compat/timegm.c
new file mode 100644
index 0000000000..2658445fce
--- /dev/null
+++ b/crypto/libressl/crypto/compat/timegm.c
@@ -0,0 +1,220 @@
+/*
+ * ----------------------------------------------------------------------
+ * Copyright © 2005-2014 Rich Felker, et al.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * ----------------------------------------------------------------------
+ */
+
+#include 
+#include 
+#include 
+
+/* 2000-03-01 (mod 400 year, immediately after feb29 */
+#define LEAPOCH (946684800LL + 86400*(31+29))
+
+#define DAYS_PER_400Y (365*400 + 97)
+#define DAYS_PER_100Y (365*100 + 24)
+#define DAYS_PER_4Y   (365*4   + 1)
+
+static int __month_to_secs(int month, int is_leap)
+{
+	static const int secs_through_month[] = {
+		0, 31*86400, 59*86400, 90*86400,
+		120*86400, 151*86400, 181*86400, 212*86400,
+		243*86400, 273*86400, 304*86400, 334*86400 };
+	int t = secs_through_month[month];
+	if (is_leap && month >= 2) t+=86400;
+	return t;
+}
+
+static long long __year_to_secs(long long year, int *is_leap)
+{
+	if (year-2ULL <= 136) {
+		int y = year;
+		int leaps = (y-68)>>2;
+		if (!((y-68)&3)) {
+			leaps--;
+			if (is_leap) *is_leap = 1;
+		} else if (is_leap) *is_leap = 0;
+		return 31536000*(y-70) + 86400*leaps;
+	}
+
+	int cycles, centuries, leaps, rem;
+
+	if (!is_leap) is_leap = &(int){0};
+	cycles = (year-100) / 400;
+	rem = (year-100) % 400;
+	if (rem < 0) {
+		cycles--;
+		rem += 400;
+	}
+	if (!rem) {
+		*is_leap = 1;
+		centuries = 0;
+		leaps = 0;
+	} else {
+		if (rem >= 200) {
+			if (rem >= 300) centuries = 3, rem -= 300;
+			else centuries = 2, rem -= 200;
+		} else {
+			if (rem >= 100) centuries = 1, rem -= 100;
+			else centuries = 0;
+		}
+		if (!rem) {
+			*is_leap = 0;
+			leaps = 0;
+		} else {
+			leaps = rem / 4U;
+			rem %= 4U;
+			*is_leap = !rem;
+		}
+	}
+
+	leaps += 97*cycles + 24*centuries - *is_leap;
+
+	return (year-100) * 31536000LL + leaps * 86400LL + 946684800 + 86400;
+}
+
+static long long __tm_to_secs(const struct tm *tm)
+{
+	int is_leap;
+	long long year = tm->tm_year;
+	int month = tm->tm_mon;
+	if (month >= 12 || month < 0) {
+		int adj = month / 12;
+		month %= 12;
+		if (month < 0) {
+			adj--;
+			month += 12;
+		}
+		year += adj;
+	}
+	long long t = __year_to_secs(year, &is_leap);
+	t += __month_to_secs(month, is_leap);
+	t += 86400LL * (tm->tm_mday-1);
+	t += 3600LL * tm->tm_hour;
+	t += 60LL * tm->tm_min;
+	t += tm->tm_sec;
+	return t;
+}
+
+static int __secs_to_tm(long long t, struct tm *tm)
+{
+	long long days, secs;
+	int remdays, remsecs, remyears;
+	int qc_cycles, c_cycles, q_cycles;
+	int years, months;
+	int wday, yday, leap;
+	static const char days_in_month[] = {31,30,31,30,31,31,30,31,30,31,31,29};
+
+	/* Reject time_t values whose year would overflow int */
+	if (t < INT_MIN * 31622400LL || t > INT_MAX * 31622400LL)
+		return -1;
+
+	secs = t - LEAPOCH;
+	days = secs / 86400;
+	remsecs = secs % 86400;
+	if (remsecs < 0) {
+		remsecs += 86400;
+		days--;
+	}
+
+	wday = (3+days)%7;
+	if (wday < 0) wday += 7;
+
+	qc_cycles = days / DAYS_PER_400Y;
+	remdays = days % DAYS_PER_400Y;
+	if (remdays < 0) {
+		remdays += DAYS_PER_400Y;
+		qc_cycles--;
+	}
+
+	c_cycles = remdays / DAYS_PER_100Y;
+	if (c_cycles == 4) c_cycles--;
+	remdays -= c_cycles * DAYS_PER_100Y;
+
+	q_cycles = remdays / DAYS_PER_4Y;
+	if (q_cycles == 25) q_cycles--;
+	remdays -= q_cycles * DAYS_PER_4Y;
+
+	remyears = remdays / 365;
+	if (remyears == 4) remyears--;
+	remdays -= remyears * 365;
+
+	leap = !remyears && (q_cycles || !c_cycles);
+	yday = remdays + 31 + 28 + leap;
+	if (yday >= 365+leap) yday -= 365+leap;
+
+	years = remyears + 4*q_cycles + 100*c_cycles + 400*qc_cycles;
+
+	for (months=0; days_in_month[months] <= remdays; months++)
+		remdays -= days_in_month[months];
+
+	if (years+100 > INT_MAX || years+100 < INT_MIN)
+		return -1;
+
+	tm->tm_year = years + 100;
+	tm->tm_mon = months + 2;
+	if (tm->tm_mon >= 12) {
+		tm->tm_mon -=12;
+		tm->tm_year++;
+	}
+	tm->tm_mday = remdays + 1;
+	tm->tm_wday = wday;
+	tm->tm_yday = yday;
+
+	tm->tm_hour = remsecs / 3600;
+	tm->tm_min = remsecs / 60 % 60;
+	tm->tm_sec = remsecs % 60;
+
+	return 0;
+}
+
+#ifdef _WIN32
+struct tm *__gmtime_r(const time_t *t, struct tm *tm)
+{
+	if (__secs_to_tm(*t, tm) < 0) {
+		errno = EOVERFLOW;
+		return 0;
+	}
+	tm->tm_isdst = 0;
+	return tm;
+}
+#endif
+
+time_t timegm(struct tm *tm)
+{
+	struct tm new;
+	long long t = __tm_to_secs(tm);
+	if (__secs_to_tm(t, &new) < 0) {
+		errno = EOVERFLOW;
+		return -1;
+	}
+#if SIZEOF_TIME_T != 8
+	if (t > (long long)INT_MAX || t < (long long)INT_MIN) {
+		errno = EOVERFLOW;
+		return -1;
+	}
+#endif
+	*tm = new;
+	tm->tm_isdst = 0;
+	return t;
+}
diff --git a/crypto/libressl/crypto/compat/timingsafe_bcmp.c b/crypto/libressl/crypto/compat/timingsafe_bcmp.c
new file mode 100644
index 0000000000..0b736154ca
--- /dev/null
+++ b/crypto/libressl/crypto/compat/timingsafe_bcmp.c
@@ -0,0 +1,29 @@
+/*	$OpenBSD: timingsafe_bcmp.c,v 1.2 2014/06/10 04:17:37 deraadt Exp $	*/
+/*
+ * Copyright (c) 2010 Damien Miller.  All rights reserved.
+ *
+ * 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 
+
+int
+timingsafe_bcmp(const void *b1, const void *b2, size_t n)
+{
+	const unsigned char *p1 = b1, *p2 = b2;
+	int ret = 0;
+
+	for (; n > 0; n--)
+		ret |= *p1++ ^ *p2++;
+	return (ret != 0);
+}
diff --git a/crypto/libressl/crypto/compat/timingsafe_memcmp.c b/crypto/libressl/crypto/compat/timingsafe_memcmp.c
new file mode 100644
index 0000000000..04e2ac5e20
--- /dev/null
+++ b/crypto/libressl/crypto/compat/timingsafe_memcmp.c
@@ -0,0 +1,46 @@
+/*	$OpenBSD: timingsafe_memcmp.c,v 1.1 2014/06/13 02:12:17 matthew Exp $	*/
+/*
+ * Copyright (c) 2014 Google Inc.
+ *
+ * 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 
+#include 
+
+int
+timingsafe_memcmp(const void *b1, const void *b2, size_t len)
+{
+        const unsigned char *p1 = b1, *p2 = b2;
+        size_t i;
+        int res = 0, done = 0;
+
+        for (i = 0; i < len; i++) {
+                /* lt is -1 if p1[i] < p2[i]; else 0. */
+                int lt = (p1[i] - p2[i]) >> CHAR_BIT;
+
+                /* gt is -1 if p1[i] > p2[i]; else 0. */
+                int gt = (p2[i] - p1[i]) >> CHAR_BIT;
+
+                /* cmp is 1 if p1[i] > p2[i]; -1 if p1[i] < p2[i]; else 0. */
+                int cmp = lt - gt;
+
+                /* set res = cmp if !done. */
+                res |= cmp & ~done;
+
+                /* set done if p1[i] != p2[i]. */
+                done |= lt | gt;
+        }
+
+        return (res);
+}
diff --git a/crypto/libressl/crypto/conf/conf_api.c b/crypto/libressl/crypto/conf/conf_api.c
new file mode 100644
index 0000000000..a1f5698d59
--- /dev/null
+++ b/crypto/libressl/crypto/conf/conf_api.c
@@ -0,0 +1,279 @@
+/* $OpenBSD: conf_api.c,v 1.14 2015/02/10 11:22:21 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Part of the code in here was originally in conf.c, which is now removed */
+
+#ifndef CONF_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static void value_free_hash_doall_arg(CONF_VALUE *a,
+    LHASH_OF(CONF_VALUE) *conf);
+static void value_free_stack_doall(CONF_VALUE *a);
+static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE,
+    LHASH_OF(CONF_VALUE))
+static IMPLEMENT_LHASH_DOALL_FN(value_free_stack, CONF_VALUE)
+
+/* Up until OpenSSL 0.9.5a, this was get_section */
+CONF_VALUE *
+_CONF_get_section(const CONF *conf, const char *section)
+{
+	CONF_VALUE *v, vv;
+
+	if ((conf == NULL) || (section == NULL))
+		return (NULL);
+	vv.name = NULL;
+	vv.section = (char *)section;
+	v = lh_CONF_VALUE_retrieve(conf->data, &vv);
+	return (v);
+}
+
+/* Up until OpenSSL 0.9.5a, this was CONF_get_section */
+STACK_OF(CONF_VALUE) *
+_CONF_get_section_values(const CONF *conf, const char *section)
+{
+	CONF_VALUE *v;
+
+	v = _CONF_get_section(conf, section);
+	if (v != NULL)
+		return ((STACK_OF(CONF_VALUE) *)v->value);
+	else
+		return (NULL);
+}
+
+int
+_CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value)
+{
+	CONF_VALUE *v = NULL;
+	STACK_OF(CONF_VALUE) *ts;
+
+	ts = (STACK_OF(CONF_VALUE) *)section->value;
+
+	value->section = section->section;
+	if (!sk_CONF_VALUE_push(ts, value)) {
+		return 0;
+	}
+
+	v = lh_CONF_VALUE_insert(conf->data, value);
+	if (v != NULL) {
+		(void)sk_CONF_VALUE_delete_ptr(ts, v);
+		free(v->name);
+		free(v->value);
+		free(v);
+	}
+	return 1;
+}
+
+char *
+_CONF_get_string(const CONF *conf, const char *section, const char *name)
+{
+	CONF_VALUE *v, vv;
+
+	if (name == NULL)
+		return (NULL);
+	if (conf != NULL) {
+		if (section != NULL) {
+			vv.name = (char *)name;
+			vv.section = (char *)section;
+			v = lh_CONF_VALUE_retrieve(conf->data, &vv);
+			if (v != NULL)
+				return (v->value);
+		}
+		vv.section = "default";
+		vv.name = (char *)name;
+		v = lh_CONF_VALUE_retrieve(conf->data, &vv);
+		if (v != NULL)
+			return (v->value);
+		else
+			return (NULL);
+	} else
+		return (NULL);
+}
+
+static unsigned long
+conf_value_hash(const CONF_VALUE *v)
+{
+	return (lh_strhash(v->section) << 2) ^ lh_strhash(v->name);
+}
+
+static IMPLEMENT_LHASH_HASH_FN(conf_value, CONF_VALUE)
+
+static int
+conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b)
+{
+	int i;
+
+	if (a->section != b->section) {
+		i = strcmp(a->section, b->section);
+		if (i)
+			return (i);
+	}
+	if ((a->name != NULL) && (b->name != NULL)) {
+		i = strcmp(a->name, b->name);
+		return (i);
+	} else if (a->name == b->name)
+		return (0);
+	else
+		return ((a->name == NULL)?-1 : 1);
+}
+
+static IMPLEMENT_LHASH_COMP_FN(conf_value, CONF_VALUE)
+
+int
+_CONF_new_data(CONF *conf)
+{
+	if (conf == NULL) {
+		return 0;
+	}
+	if (conf->data == NULL)
+		if ((conf->data = lh_CONF_VALUE_new()) == NULL) {
+			return 0;
+		}
+	return 1;
+}
+
+void
+_CONF_free_data(CONF *conf)
+{
+	if (conf == NULL || conf->data == NULL)
+		return;
+
+	lh_CONF_VALUE_down_load(conf->data) = 0; /* evil thing to make
+						  * sure the 'free()' works as
+						  * expected */
+	lh_CONF_VALUE_doall_arg(conf->data,
+	    LHASH_DOALL_ARG_FN(value_free_hash),
+	    LHASH_OF(CONF_VALUE), conf->data);
+
+	/* We now have only 'section' entries in the hash table.
+	 * Due to problems with */
+
+	lh_CONF_VALUE_doall(conf->data, LHASH_DOALL_FN(value_free_stack));
+	lh_CONF_VALUE_free(conf->data);
+}
+
+static void
+value_free_hash_doall_arg(CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf)
+{
+	if (a->name != NULL)
+		(void)lh_CONF_VALUE_delete(conf, a);
+}
+
+static void
+value_free_stack_doall(CONF_VALUE *a)
+{
+	CONF_VALUE *vv;
+	STACK_OF(CONF_VALUE) *sk;
+	int i;
+
+	if (a->name != NULL)
+		return;
+
+	sk = (STACK_OF(CONF_VALUE) *)a->value;
+	for (i = sk_CONF_VALUE_num(sk) - 1; i >= 0; i--) {
+		vv = sk_CONF_VALUE_value(sk, i);
+		free(vv->value);
+		free(vv->name);
+		free(vv);
+	}
+	if (sk != NULL)
+		sk_CONF_VALUE_free(sk);
+	free(a->section);
+	free(a);
+}
+
+/* Up until OpenSSL 0.9.5a, this was new_section */
+CONF_VALUE *
+_CONF_new_section(CONF *conf, const char *section)
+{
+	STACK_OF(CONF_VALUE) *sk = NULL;
+	int ok = 0, i;
+	CONF_VALUE *v = NULL, *vv;
+
+	if ((sk = sk_CONF_VALUE_new_null()) == NULL)
+		goto err;
+	if ((v = malloc(sizeof(CONF_VALUE))) == NULL)
+		goto err;
+	i = strlen(section) + 1;
+	if ((v->section = malloc(i)) == NULL)
+		goto err;
+
+	memcpy(v->section, section, i);
+	v->name = NULL;
+	v->value = (char *)sk;
+
+	vv = lh_CONF_VALUE_insert(conf->data, v);
+	OPENSSL_assert(vv == NULL);
+	ok = 1;
+
+err:
+	if (!ok) {
+		if (sk != NULL)
+			sk_CONF_VALUE_free(sk);
+		free(v);
+		v = NULL;
+	}
+	return (v);
+}
diff --git a/crypto/libressl/crypto/conf/conf_def.c b/crypto/libressl/crypto/conf/conf_def.c
new file mode 100644
index 0000000000..56d5bafe5a
--- /dev/null
+++ b/crypto/libressl/crypto/conf/conf_def.c
@@ -0,0 +1,702 @@
+/* $OpenBSD: conf_def.c,v 1.30 2015/04/30 15:28:03 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Part of the code in here was originally in conf.c, which is now removed */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "conf_def.h"
+
+static char *eat_ws(CONF *conf, char *p);
+static char *eat_alpha_numeric(CONF *conf, char *p);
+static void clear_comments(CONF *conf, char *p);
+static int str_copy(CONF *conf, char *section, char **to, char *from);
+static char *scan_quote(CONF *conf, char *p);
+static char *scan_dquote(CONF *conf, char *p);
+#define scan_esc(conf,p)	(((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2)))
+
+static CONF *def_create(CONF_METHOD *meth);
+static int def_init_default(CONF *conf);
+static int def_init_WIN32(CONF *conf);
+static int def_destroy(CONF *conf);
+static int def_destroy_data(CONF *conf);
+static int def_load(CONF *conf, const char *name, long *eline);
+static int def_load_bio(CONF *conf, BIO *bp, long *eline);
+static int def_dump(const CONF *conf, BIO *bp);
+static int def_is_number(const CONF *conf, char c);
+static int def_to_int(const CONF *conf, char c);
+
+static CONF_METHOD default_method = {
+	.name = "OpenSSL default",
+	.create = def_create,
+	.init = def_init_default,
+	.destroy = def_destroy,
+	.destroy_data = def_destroy_data,
+	.load_bio = def_load_bio,
+	.dump = def_dump,
+	.is_number = def_is_number,
+	.to_int = def_to_int,
+	.load = def_load
+};
+
+static CONF_METHOD WIN32_method = {
+	"WIN32",
+	def_create,
+	def_init_WIN32,
+	def_destroy,
+	def_destroy_data,
+	def_load_bio,
+	def_dump,
+	def_is_number,
+	def_to_int,
+	def_load
+};
+
+CONF_METHOD *
+NCONF_default(void)
+{
+	return &default_method;
+}
+
+CONF_METHOD *
+NCONF_WIN32(void)
+{
+	return &WIN32_method;
+}
+
+static CONF *
+def_create(CONF_METHOD *meth)
+{
+	CONF *ret;
+
+	ret = malloc(sizeof(CONF) + sizeof(unsigned short *));
+	if (ret)
+		if (meth->init(ret) == 0) {
+			free(ret);
+			ret = NULL;
+		}
+	return ret;
+}
+
+static int
+def_init_default(CONF *conf)
+{
+	if (conf == NULL)
+		return 0;
+
+	conf->meth = &default_method;
+	conf->meth_data = CONF_type_default;
+	conf->data = NULL;
+
+	return 1;
+}
+
+static int
+def_init_WIN32(CONF *conf)
+{
+	if (conf == NULL)
+		return 0;
+
+	conf->meth = &WIN32_method;
+	conf->meth_data = (void *)CONF_type_win32;
+	conf->data = NULL;
+
+	return 1;
+}
+
+static int
+def_destroy(CONF *conf)
+{
+	if (def_destroy_data(conf)) {
+		free(conf);
+		return 1;
+	}
+	return 0;
+}
+
+static int
+def_destroy_data(CONF *conf)
+{
+	if (conf == NULL)
+		return 0;
+	_CONF_free_data(conf);
+	return 1;
+}
+
+static int
+def_load(CONF *conf, const char *name, long *line)
+{
+	int ret;
+	BIO *in = NULL;
+
+	in = BIO_new_file(name, "rb");
+	if (in == NULL) {
+		if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE)
+			CONFerr(CONF_F_DEF_LOAD, CONF_R_NO_SUCH_FILE);
+		else
+			CONFerr(CONF_F_DEF_LOAD, ERR_R_SYS_LIB);
+		return 0;
+	}
+
+	ret = def_load_bio(conf, in, line);
+	BIO_free(in);
+
+	return ret;
+}
+
+static int
+def_load_bio(CONF *conf, BIO *in, long *line)
+{
+/* The macro BUFSIZE conflicts with a system macro in VxWorks */
+#define CONFBUFSIZE	512
+	int bufnum = 0, i, ii;
+	BUF_MEM *buff = NULL;
+	char *s, *p, *end;
+	int again;
+	long eline = 0;
+	CONF_VALUE *v = NULL, *tv;
+	CONF_VALUE *sv = NULL;
+	char *section = NULL, *buf;
+	char *start, *psection, *pname;
+	void *h = (void *)(conf->data);
+
+	if ((buff = BUF_MEM_new()) == NULL) {
+		CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB);
+		goto err;
+	}
+
+	section = strdup("default");
+	if (section == NULL) {
+		CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	if (_CONF_new_data(conf) == 0) {
+		CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	sv = _CONF_new_section(conf, section);
+	if (sv == NULL) {
+		CONFerr(CONF_F_DEF_LOAD_BIO,
+		    CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+		goto err;
+	}
+
+	bufnum = 0;
+	again = 0;
+	for (;;) {
+		if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) {
+			CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB);
+			goto err;
+		}
+		p = &(buff->data[bufnum]);
+		*p = '\0';
+		BIO_gets(in, p, CONFBUFSIZE - 1);
+		p[CONFBUFSIZE - 1] = '\0';
+		ii = i = strlen(p);
+		if (i == 0 && !again)
+			break;
+		again = 0;
+		while (i > 0) {
+			if ((p[i - 1] != '\r') && (p[i - 1] != '\n'))
+				break;
+			else
+				i--;
+		}
+		/* we removed some trailing stuff so there is a new
+		 * line on the end. */
+		if (ii && i == ii)
+			again = 1; /* long line */
+		else {
+			p[i] = '\0';
+			eline++; /* another input line */
+		}
+
+		/* we now have a line with trailing \r\n removed */
+
+		/* i is the number of bytes */
+		bufnum += i;
+
+		v = NULL;
+		/* check for line continuation */
+		if (bufnum >= 1) {
+			/* If we have bytes and the last char '\\' and
+			 * second last char is not '\\' */
+			p = &(buff->data[bufnum - 1]);
+			if (IS_ESC(conf, p[0]) &&
+			    ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) {
+				bufnum--;
+				again = 1;
+			}
+		}
+		if (again)
+			continue;
+		bufnum = 0;
+		buf = buff->data;
+
+		clear_comments(conf, buf);
+		s = eat_ws(conf, buf);
+		if (IS_EOF(conf, *s))
+			continue; /* blank line */
+		if (*s == '[') {
+			char *ss;
+
+			s++;
+			start = eat_ws(conf, s);
+			ss = start;
+again:
+			end = eat_alpha_numeric(conf, ss);
+			p = eat_ws(conf, end);
+			if (*p != ']') {
+				if (*p != '\0' && ss != p) {
+					ss = p;
+					goto again;
+				}
+				CONFerr(CONF_F_DEF_LOAD_BIO,
+				    CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
+				goto err;
+			}
+			*end = '\0';
+			if (!str_copy(conf, NULL, §ion, start))
+				goto err;
+			if ((sv = _CONF_get_section(conf, section)) == NULL)
+				sv = _CONF_new_section(conf, section);
+			if (sv == NULL) {
+				CONFerr(CONF_F_DEF_LOAD_BIO,
+				    CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+				goto err;
+			}
+			continue;
+		} else {
+			pname = s;
+			psection = NULL;
+			end = eat_alpha_numeric(conf, s);
+			if ((end[0] == ':') && (end[1] == ':')) {
+				*end = '\0';
+				end += 2;
+				psection = pname;
+				pname = end;
+				end = eat_alpha_numeric(conf, end);
+			}
+			p = eat_ws(conf, end);
+			if (*p != '=') {
+				CONFerr(CONF_F_DEF_LOAD_BIO,
+				    CONF_R_MISSING_EQUAL_SIGN);
+				goto err;
+			}
+			*end = '\0';
+			p++;
+			start = eat_ws(conf, p);
+			while (!IS_EOF(conf, *p))
+				p++;
+			p--;
+			while ((p != start) && (IS_WS(conf, *p)))
+				p--;
+			p++;
+			*p = '\0';
+
+			if (!(v = malloc(sizeof(CONF_VALUE)))) {
+				CONFerr(CONF_F_DEF_LOAD_BIO,
+				    ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+			if (psection == NULL)
+				psection = section;
+			v->name = strdup(pname);
+			v->value = NULL;
+			if (v->name == NULL) {
+				CONFerr(CONF_F_DEF_LOAD_BIO,
+				    ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+			if (!str_copy(conf, psection, &(v->value), start))
+				goto err;
+
+			if (strcmp(psection, section) != 0) {
+				if ((tv = _CONF_get_section(conf, psection))
+					== NULL)
+					tv = _CONF_new_section(conf, psection);
+				if (tv == NULL) {
+					CONFerr(CONF_F_DEF_LOAD_BIO,
+					    CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+					goto err;
+				}
+			} else
+				tv = sv;
+
+			if (_CONF_add_string(conf, tv, v) == 0) {
+				CONFerr(CONF_F_DEF_LOAD_BIO,
+				    ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+			v = NULL;
+		}
+	}
+	if (buff != NULL)
+		BUF_MEM_free(buff);
+	free(section);
+	return (1);
+
+err:
+	if (buff != NULL)
+		BUF_MEM_free(buff);
+	free(section);
+	if (line != NULL)
+		*line = eline;
+	ERR_asprintf_error_data("line %ld", eline);
+	if ((h != conf->data) && (conf->data != NULL)) {
+		CONF_free(conf->data);
+		conf->data = NULL;
+	}
+	if (v != NULL) {
+		free(v->name);
+		free(v->value);
+		free(v);
+	}
+	return (0);
+}
+
+static void
+clear_comments(CONF *conf, char *p)
+{
+	for (;;) {
+		if (IS_FCOMMENT(conf, *p)) {
+			*p = '\0';
+			return;
+		}
+		if (!IS_WS(conf, *p)) {
+			break;
+		}
+		p++;
+	}
+
+	for (;;) {
+		if (IS_COMMENT(conf, *p)) {
+			*p = '\0';
+			return;
+		}
+		if (IS_DQUOTE(conf, *p)) {
+			p = scan_dquote(conf, p);
+			continue;
+		}
+		if (IS_QUOTE(conf, *p)) {
+			p = scan_quote(conf, p);
+			continue;
+		}
+		if (IS_ESC(conf, *p)) {
+			p = scan_esc(conf, p);
+			continue;
+		}
+		if (IS_EOF(conf, *p))
+			return;
+		else
+			p++;
+	}
+}
+
+static int
+str_copy(CONF *conf, char *section, char **pto, char *from)
+{
+	int q, r,rr = 0, to = 0, len = 0;
+	char *s, *e, *rp, *p, *rrp, *np, *cp, v;
+	BUF_MEM *buf;
+
+	if ((buf = BUF_MEM_new()) == NULL)
+		return (0);
+
+	len = strlen(from) + 1;
+	if (!BUF_MEM_grow(buf, len))
+		goto err;
+
+	for (;;) {
+		if (IS_QUOTE(conf, *from)) {
+			q = *from;
+			from++;
+			while (!IS_EOF(conf, *from) && (*from != q)) {
+				if (IS_ESC(conf, *from)) {
+					from++;
+					if (IS_EOF(conf, *from))
+						break;
+				}
+				buf->data[to++] = *(from++);
+			}
+			if (*from == q)
+				from++;
+		} else if (IS_DQUOTE(conf, *from)) {
+			q = *from;
+			from++;
+			while (!IS_EOF(conf, *from)) {
+				if (*from == q) {
+					if (*(from + 1) == q) {
+						from++;
+					} else {
+						break;
+					}
+				}
+				buf->data[to++] = *(from++);
+			}
+			if (*from == q)
+				from++;
+		} else if (IS_ESC(conf, *from)) {
+			from++;
+			v = *(from++);
+			if (IS_EOF(conf, v))
+				break;
+			else if (v == 'r')
+				v = '\r';
+			else if (v == 'n')
+				v = '\n';
+			else if (v == 'b')
+				v = '\b';
+			else if (v == 't')
+				v = '\t';
+			buf->data[to++] = v;
+		} else if (IS_EOF(conf, *from))
+			break;
+		else if (*from == '$') {
+			/* try to expand it */
+			rrp = NULL;
+			s = &(from[1]);
+			if (*s == '{')
+				q = '}';
+			else if (*s == '(')
+				q = ')';
+			else
+				q = 0;
+
+			if (q)
+				s++;
+			cp = section;
+			e = np = s;
+			while (IS_ALPHA_NUMERIC(conf, *e))
+				e++;
+			if ((e[0] == ':') && (e[1] == ':')) {
+				cp = np;
+				rrp = e;
+				rr = *e;
+				*rrp = '\0';
+				e += 2;
+				np = e;
+				while (IS_ALPHA_NUMERIC(conf, *e))
+					e++;
+			}
+			r = *e;
+			*e = '\0';
+			rp = e;
+			if (q) {
+				if (r != q) {
+					CONFerr(CONF_F_STR_COPY,
+					    CONF_R_NO_CLOSE_BRACE);
+					goto err;
+				}
+				e++;
+			}
+			/* So at this point we have
+			 * np which is the start of the name string which is
+			 *   '\0' terminated.
+			 * cp which is the start of the section string which is
+			 *   '\0' terminated.
+			 * e is the 'next point after'.
+			 * r and rr are the chars replaced by the '\0'
+			 * rp and rrp is where 'r' and 'rr' came from.
+			 */
+			p = _CONF_get_string(conf, cp, np);
+			if (rrp != NULL)
+				*rrp = rr;
+			*rp = r;
+			if (p == NULL) {
+				CONFerr(CONF_F_STR_COPY,
+				    CONF_R_VARIABLE_HAS_NO_VALUE);
+				goto err;
+			}
+			if (!BUF_MEM_grow_clean(buf,
+				(strlen(p) + buf->length - (e - from)))) {
+				CONFerr(CONF_F_STR_COPY,
+				    CONF_R_MODULE_INITIALIZATION_ERROR);
+				goto err;
+			}
+			while (*p)
+				buf->data[to++] = *(p++);
+
+			/* Since we change the pointer 'from', we also have
+			   to change the perceived length of the string it
+			   points at.  /RL */
+			len -= e - from;
+			from = e;
+
+			/* In case there were no braces or parenthesis around
+			   the variable reference, we have to put back the
+			   character that was replaced with a '\0'.  /RL */
+			*rp = r;
+		} else
+			buf->data[to++] = *(from++);
+	}
+	buf->data[to]='\0';
+	free(*pto);
+	*pto = buf->data;
+	free(buf);
+	return (1);
+
+err:
+	if (buf != NULL)
+		BUF_MEM_free(buf);
+	return (0);
+}
+
+static char *
+eat_ws(CONF *conf, char *p)
+{
+	while (IS_WS(conf, *p) && (!IS_EOF(conf, *p)))
+		p++;
+	return (p);
+}
+
+static char *
+eat_alpha_numeric(CONF *conf, char *p)
+{
+	for (;;) {
+		if (IS_ESC(conf, *p)) {
+			p = scan_esc(conf, p);
+			continue;
+		}
+		if (!IS_ALPHA_NUMERIC_PUNCT(conf, *p))
+			return (p);
+		p++;
+	}
+}
+
+static char *
+scan_quote(CONF *conf, char *p)
+{
+	int q = *p;
+
+	p++;
+	while (!(IS_EOF(conf, *p)) && (*p != q)) {
+		if (IS_ESC(conf, *p)) {
+			p++;
+			if (IS_EOF(conf, *p))
+				return (p);
+		}
+		p++;
+	}
+	if (*p == q)
+		p++;
+	return (p);
+}
+
+
+static char *
+scan_dquote(CONF *conf, char *p)
+{
+	int q = *p;
+
+	p++;
+	while (!(IS_EOF(conf, *p))) {
+		if (*p == q) {
+			if (*(p + 1) == q) {
+				p++;
+			} else {
+				break;
+			}
+		}
+		p++;
+	}
+	if (*p == q)
+		p++;
+	return (p);
+}
+
+static void
+dump_value_doall_arg(CONF_VALUE *a, BIO *out)
+{
+	if (a->name)
+		BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value);
+	else
+		BIO_printf(out, "[[%s]]\n", a->section);
+}
+
+static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE, BIO)
+
+static int
+def_dump(const CONF *conf, BIO *out)
+{
+	lh_CONF_VALUE_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value),
+	    BIO, out);
+	return 1;
+}
+
+static int
+def_is_number(const CONF *conf, char c)
+{
+	return IS_NUMBER(conf, c);
+}
+
+static int
+def_to_int(const CONF *conf, char c)
+{
+	return c - '0';
+}
diff --git a/crypto/libressl/crypto/conf/conf_def.h b/crypto/libressl/crypto/conf/conf_def.h
new file mode 100644
index 0000000000..fc74068c63
--- /dev/null
+++ b/crypto/libressl/crypto/conf/conf_def.h
@@ -0,0 +1,162 @@
+/* $OpenBSD$ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* THIS FILE WAS AUTOMAGICALLY GENERATED!
+   Please modify and use keysets.pl to regenerate it. */
+
+#define CONF_NUMBER		1
+#define CONF_UPPER		2
+#define CONF_LOWER		4
+#define CONF_UNDER		256
+#define CONF_PUNCTUATION	512
+#define CONF_WS			16
+#define CONF_ESC		32
+#define CONF_QUOTE		64
+#define CONF_DQUOTE		1024
+#define CONF_COMMENT		128
+#define CONF_FCOMMENT		2048
+#define CONF_EOF		8
+#define CONF_HIGHBIT		4096
+#define CONF_ALPHA		(CONF_UPPER|CONF_LOWER)
+#define CONF_ALPHA_NUMERIC	(CONF_ALPHA|CONF_NUMBER|CONF_UNDER)
+#define CONF_ALPHA_NUMERIC_PUNCT (CONF_ALPHA|CONF_NUMBER|CONF_UNDER| \
+					CONF_PUNCTUATION)
+
+#define KEYTYPES(c)		((unsigned short *)((c)->meth_data))
+#define IS_COMMENT(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_COMMENT)
+#define IS_FCOMMENT(c,a)	(KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT)
+#define IS_EOF(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_EOF)
+#define IS_ESC(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_ESC)
+#define IS_NUMBER(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_NUMBER)
+#define IS_WS(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_WS)
+#define IS_ALPHA_NUMERIC(c,a)	(KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC)
+#define IS_ALPHA_NUMERIC_PUNCT(c,a) \
+				(KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC_PUNCT)
+#define IS_QUOTE(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_QUOTE)
+#define IS_DQUOTE(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE)
+#define IS_HIGHBIT(c,a)		(KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT)
+
+static unsigned short CONF_type_default[256] = {
+	0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0010, 0x0200, 0x0040, 0x0080, 0x0000, 0x0200, 0x0200, 0x0040,
+	0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200,
+	0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
+	0x0001, 0x0001, 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200,
+	0x0200, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
+	0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
+	0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
+	0x0002, 0x0002, 0x0002, 0x0000, 0x0020, 0x0000, 0x0200, 0x0100,
+	0x0040, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
+	0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
+	0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
+	0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+};
+
+static unsigned short CONF_type_win32[256] = {
+	0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0010, 0x0200, 0x0400, 0x0000, 0x0000, 0x0200, 0x0200, 0x0000,
+	0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200,
+	0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
+	0x0001, 0x0001, 0x0000, 0x0A00, 0x0000, 0x0000, 0x0000, 0x0200,
+	0x0200, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
+	0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
+	0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
+	0x0002, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0200, 0x0100,
+	0x0000, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
+	0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
+	0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
+	0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+	0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+};
diff --git a/crypto/libressl/crypto/conf/conf_err.c b/crypto/libressl/crypto/conf/conf_err.c
new file mode 100644
index 0000000000..56d4e18163
--- /dev/null
+++ b/crypto/libressl/crypto/conf/conf_err.c
@@ -0,0 +1,131 @@
+/* $OpenBSD: conf_err.c,v 1.11 2014/06/12 15:49:28 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_CONF,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_CONF,0,reason)
+
+static ERR_STRING_DATA CONF_str_functs[]= {
+	{ERR_FUNC(CONF_F_CONF_DUMP_FP),	"CONF_dump_fp"},
+	{ERR_FUNC(CONF_F_CONF_LOAD),	"CONF_load"},
+	{ERR_FUNC(CONF_F_CONF_LOAD_BIO),	"CONF_load_bio"},
+	{ERR_FUNC(CONF_F_CONF_LOAD_FP),	"CONF_load_fp"},
+	{ERR_FUNC(CONF_F_CONF_MODULES_LOAD),	"CONF_modules_load"},
+	{ERR_FUNC(CONF_F_CONF_PARSE_LIST),	"CONF_parse_list"},
+	{ERR_FUNC(CONF_F_DEF_LOAD),	"DEF_LOAD"},
+	{ERR_FUNC(CONF_F_DEF_LOAD_BIO),	"DEF_LOAD_BIO"},
+	{ERR_FUNC(CONF_F_MODULE_INIT),	"MODULE_INIT"},
+	{ERR_FUNC(CONF_F_MODULE_LOAD_DSO),	"MODULE_LOAD_DSO"},
+	{ERR_FUNC(CONF_F_MODULE_RUN),	"MODULE_RUN"},
+	{ERR_FUNC(CONF_F_NCONF_DUMP_BIO),	"NCONF_dump_bio"},
+	{ERR_FUNC(CONF_F_NCONF_DUMP_FP),	"NCONF_dump_fp"},
+	{ERR_FUNC(CONF_F_NCONF_GET_NUMBER),	"NCONF_get_number"},
+	{ERR_FUNC(CONF_F_NCONF_GET_NUMBER_E),	"NCONF_get_number_e"},
+	{ERR_FUNC(CONF_F_NCONF_GET_SECTION),	"NCONF_get_section"},
+	{ERR_FUNC(CONF_F_NCONF_GET_STRING),	"NCONF_get_string"},
+	{ERR_FUNC(CONF_F_NCONF_LOAD),	"NCONF_load"},
+	{ERR_FUNC(CONF_F_NCONF_LOAD_BIO),	"NCONF_load_bio"},
+	{ERR_FUNC(CONF_F_NCONF_LOAD_FP),	"NCONF_load_fp"},
+	{ERR_FUNC(CONF_F_NCONF_NEW),	"NCONF_new"},
+	{ERR_FUNC(CONF_F_STR_COPY),	"STR_COPY"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA CONF_str_reasons[]= {
+	{ERR_REASON(CONF_R_ERROR_LOADING_DSO)    , "error loading dso"},
+	{ERR_REASON(CONF_R_LIST_CANNOT_BE_NULL)  , "list cannot be null"},
+	{ERR_REASON(CONF_R_MISSING_CLOSE_SQUARE_BRACKET), "missing close square bracket"},
+	{ERR_REASON(CONF_R_MISSING_EQUAL_SIGN)   , "missing equal sign"},
+	{ERR_REASON(CONF_R_MISSING_FINISH_FUNCTION), "missing finish function"},
+	{ERR_REASON(CONF_R_MISSING_INIT_FUNCTION), "missing init function"},
+	{ERR_REASON(CONF_R_MODULE_INITIALIZATION_ERROR), "module initialization error"},
+	{ERR_REASON(CONF_R_NO_CLOSE_BRACE)       , "no close brace"},
+	{ERR_REASON(CONF_R_NO_CONF)              , "no conf"},
+	{ERR_REASON(CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE), "no conf or environment variable"},
+	{ERR_REASON(CONF_R_NO_SECTION)           , "no section"},
+	{ERR_REASON(CONF_R_NO_SUCH_FILE)         , "no such file"},
+	{ERR_REASON(CONF_R_NO_VALUE)             , "no value"},
+	{ERR_REASON(CONF_R_UNABLE_TO_CREATE_NEW_SECTION), "unable to create new section"},
+	{ERR_REASON(CONF_R_UNKNOWN_MODULE_NAME)  , "unknown module name"},
+	{ERR_REASON(CONF_R_VARIABLE_HAS_NO_VALUE), "variable has no value"},
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_CONF_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(CONF_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, CONF_str_functs);
+		ERR_load_strings(0, CONF_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/conf/conf_lib.c b/crypto/libressl/crypto/conf/conf_lib.c
new file mode 100644
index 0000000000..b9ea0d0b24
--- /dev/null
+++ b/crypto/libressl/crypto/conf/conf_lib.c
@@ -0,0 +1,375 @@
+/* $OpenBSD: conf_lib.c,v 1.12 2014/07/09 11:10:50 bcook Exp $ */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static CONF_METHOD *default_CONF_method = NULL;
+
+/* Init a 'CONF' structure from an old LHASH */
+
+void
+CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash)
+{
+	if (default_CONF_method == NULL)
+		default_CONF_method = NCONF_default();
+	default_CONF_method->init(conf);
+	conf->data = hash;
+}
+
+/* The following section contains the "CONF classic" functions,
+   rewritten in terms of the new CONF interface. */
+
+int
+CONF_set_default_method(CONF_METHOD *meth)
+{
+	default_CONF_method = meth;
+	return 1;
+}
+
+LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file,
+    long *eline)
+{
+	LHASH_OF(CONF_VALUE) *ltmp;
+	BIO *in = NULL;
+
+	in = BIO_new_file(file, "rb");
+	if (in == NULL) {
+		CONFerr(CONF_F_CONF_LOAD, ERR_R_SYS_LIB);
+		return NULL;
+	}
+
+	ltmp = CONF_load_bio(conf, in, eline);
+	BIO_free(in);
+
+	return ltmp;
+}
+
+LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp,
+    long *eline)
+{
+	BIO *btmp;
+	LHASH_OF(CONF_VALUE) *ltmp;
+
+	if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) {
+		CONFerr(CONF_F_CONF_LOAD_FP, ERR_R_BUF_LIB);
+		return NULL;
+	}
+	ltmp = CONF_load_bio(conf, btmp, eline);
+	BIO_free(btmp);
+	return ltmp;
+}
+
+LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,
+    long *eline)
+{
+	CONF ctmp;
+	int ret;
+
+	CONF_set_nconf(&ctmp, conf);
+
+	ret = NCONF_load_bio(&ctmp, bp, eline);
+	if (ret)
+		return ctmp.data;
+	return NULL;
+}
+
+STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf,
+    const char *section)
+{
+	if (conf == NULL) {
+		return NULL;
+	} else {
+		CONF ctmp;
+		CONF_set_nconf(&ctmp, conf);
+		return NCONF_get_section(&ctmp, section);
+	}
+}
+
+char *
+CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group,
+    const char *name)
+{
+	if (conf == NULL) {
+		return NCONF_get_string(NULL, group, name);
+	} else {
+		CONF ctmp;
+		CONF_set_nconf(&ctmp, conf);
+		return NCONF_get_string(&ctmp, group, name);
+	}
+}
+
+long
+CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group,
+    const char *name)
+{
+	int status;
+	long result = 0;
+
+	if (conf == NULL) {
+		status = NCONF_get_number_e(NULL, group, name, &result);
+	} else {
+		CONF ctmp;
+		CONF_set_nconf(&ctmp, conf);
+		status = NCONF_get_number_e(&ctmp, group, name, &result);
+	}
+
+	if (status == 0) {
+		/* This function does not believe in errors... */
+		ERR_clear_error();
+	}
+	return result;
+}
+
+void
+CONF_free(LHASH_OF(CONF_VALUE) *conf)
+{
+	CONF ctmp;
+
+	CONF_set_nconf(&ctmp, conf);
+	NCONF_free_data(&ctmp);
+}
+
+int
+CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out)
+{
+	BIO *btmp;
+	int ret;
+
+	if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) {
+		CONFerr(CONF_F_CONF_DUMP_FP, ERR_R_BUF_LIB);
+		return 0;
+	}
+	ret = CONF_dump_bio(conf, btmp);
+	BIO_free(btmp);
+	return ret;
+}
+
+int
+CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out)
+{
+	CONF ctmp;
+
+	CONF_set_nconf(&ctmp, conf);
+	return NCONF_dump_bio(&ctmp, out);
+}
+
+/* The following section contains the "New CONF" functions.  They are
+   completely centralised around a new CONF structure that may contain
+   basically anything, but at least a method pointer and a table of data.
+   These functions are also written in terms of the bridge functions used
+   by the "CONF classic" functions, for consistency.  */
+
+CONF *
+NCONF_new(CONF_METHOD *meth)
+{
+	CONF *ret;
+
+	if (meth == NULL)
+		meth = NCONF_default();
+
+	ret = meth->create(meth);
+	if (ret == NULL) {
+		CONFerr(CONF_F_NCONF_NEW, ERR_R_MALLOC_FAILURE);
+		return (NULL);
+	}
+
+	return ret;
+}
+
+void
+NCONF_free(CONF *conf)
+{
+	if (conf == NULL)
+		return;
+	conf->meth->destroy(conf);
+}
+
+void
+NCONF_free_data(CONF *conf)
+{
+	if (conf == NULL)
+		return;
+	conf->meth->destroy_data(conf);
+}
+
+int
+NCONF_load(CONF *conf, const char *file, long *eline)
+{
+	if (conf == NULL) {
+		CONFerr(CONF_F_NCONF_LOAD, CONF_R_NO_CONF);
+		return 0;
+	}
+
+	return conf->meth->load(conf, file, eline);
+}
+
+int
+NCONF_load_fp(CONF *conf, FILE *fp, long *eline)
+{
+	BIO *btmp;
+	int ret;
+
+	if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) {
+		CONFerr(CONF_F_NCONF_LOAD_FP, ERR_R_BUF_LIB);
+		return 0;
+	}
+	ret = NCONF_load_bio(conf, btmp, eline);
+	BIO_free(btmp);
+	return ret;
+}
+
+int
+NCONF_load_bio(CONF *conf, BIO *bp, long *eline)
+{
+	if (conf == NULL) {
+		CONFerr(CONF_F_NCONF_LOAD_BIO, CONF_R_NO_CONF);
+		return 0;
+	}
+
+	return conf->meth->load_bio(conf, bp, eline);
+}
+
+STACK_OF(CONF_VALUE) *
+NCONF_get_section(const CONF *conf, const char *section)
+{
+	if (conf == NULL) {
+		CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_CONF);
+		return NULL;
+	}
+
+	if (section == NULL) {
+		CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_SECTION);
+		return NULL;
+	}
+
+	return _CONF_get_section_values(conf, section);
+}
+
+char *
+NCONF_get_string(const CONF *conf, const char *group, const char *name)
+{
+	char *s = _CONF_get_string(conf, group, name);
+
+        /* Since we may get a value from an environment variable even
+           if conf is NULL, let's check the value first */
+	if (s)
+		return s;
+
+	if (conf == NULL) {
+		CONFerr(CONF_F_NCONF_GET_STRING,
+		    CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE);
+		return NULL;
+	}
+	CONFerr(CONF_F_NCONF_GET_STRING, CONF_R_NO_VALUE);
+	ERR_asprintf_error_data("group=%s name=%s", group, name);
+	return NULL;
+}
+
+int
+NCONF_get_number_e(const CONF *conf, const char *group, const char *name,
+    long *result)
+{
+	char *str;
+
+	if (result == NULL) {
+		CONFerr(CONF_F_NCONF_GET_NUMBER_E, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+
+	str = NCONF_get_string(conf, group, name);
+
+	if (str == NULL)
+		return 0;
+
+	for (*result = 0; conf->meth->is_number(conf, *str); ) {
+		*result = (*result) * 10 + conf->meth->to_int(conf, *str);
+		str++;
+	}
+
+	return 1;
+}
+
+int
+NCONF_dump_fp(const CONF *conf, FILE *out)
+{
+	BIO *btmp;
+	int ret;
+	if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) {
+		CONFerr(CONF_F_NCONF_DUMP_FP, ERR_R_BUF_LIB);
+		return 0;
+	}
+	ret = NCONF_dump_bio(conf, btmp);
+	BIO_free(btmp);
+	return ret;
+}
+
+int
+NCONF_dump_bio(const CONF *conf, BIO *out)
+{
+	if (conf == NULL) {
+		CONFerr(CONF_F_NCONF_DUMP_BIO, CONF_R_NO_CONF);
+		return 0;
+	}
+
+	return conf->meth->dump(conf, out);
+}
diff --git a/crypto/libressl/crypto/conf/conf_mall.c b/crypto/libressl/crypto/conf/conf_mall.c
new file mode 100644
index 0000000000..5e6a780891
--- /dev/null
+++ b/crypto/libressl/crypto/conf/conf_mall.c
@@ -0,0 +1,82 @@
+/* $OpenBSD: conf_mall.c,v 1.8 2014/07/10 22:45:56 jsing Exp $ */
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+
+/* Load all OpenSSL builtin modules */
+
+void
+OPENSSL_load_builtin_modules(void)
+{
+	/* Add builtin modules here */
+	ASN1_add_oid_module();
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE_add_conf_module();
+#endif
+}
diff --git a/crypto/libressl/crypto/conf/conf_mod.c b/crypto/libressl/crypto/conf/conf_mod.c
new file mode 100644
index 0000000000..9070103873
--- /dev/null
+++ b/crypto/libressl/crypto/conf/conf_mod.c
@@ -0,0 +1,599 @@
+/* $OpenBSD: conf_mod.c,v 1.25 2014/07/22 02:21:20 beck Exp $ */
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DSO_mod_init_name "OPENSSL_init"
+#define DSO_mod_finish_name "OPENSSL_finish"
+
+/* This structure contains a data about supported modules.
+ * entries in this table correspond to either dynamic or
+ * static modules.
+ */
+
+struct conf_module_st {
+	/* DSO of this module or NULL if static */
+	DSO *dso;
+	/* Name of the module */
+	char *name;
+	/* Init function */
+	conf_init_func *init;
+	/* Finish function */
+	conf_finish_func *finish;
+	/* Number of successfully initialized modules */
+	int links;
+	void *usr_data;
+};
+
+
+/* This structure contains information about modules that have been
+ * successfully initialized. There may be more than one entry for a
+ * given module.
+ */
+
+struct conf_imodule_st {
+	CONF_MODULE *pmod;
+	char *name;
+	char *value;
+	unsigned long flags;
+	void *usr_data;
+};
+
+static STACK_OF(CONF_MODULE) *supported_modules = NULL;
+static STACK_OF(CONF_IMODULE) *initialized_modules = NULL;
+
+static void module_free(CONF_MODULE *md);
+static void module_finish(CONF_IMODULE *imod);
+static int module_run(const CONF *cnf, char *name, char *value,
+    unsigned long flags);
+static CONF_MODULE *module_add(DSO *dso, const char *name,
+    conf_init_func *ifunc, conf_finish_func *ffunc);
+static CONF_MODULE *module_find(char *name);
+static int module_init(CONF_MODULE *pmod, char *name, char *value,
+    const CONF *cnf);
+static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value,
+    unsigned long flags);
+
+/* Main function: load modules from a CONF structure */
+
+int
+CONF_modules_load(const CONF *cnf, const char *appname, unsigned long flags)
+{
+	STACK_OF(CONF_VALUE) *values;
+	CONF_VALUE *vl;
+	char *vsection = NULL;
+
+	int ret, i;
+
+	if (!cnf)
+		return 1;
+
+	if (appname)
+		vsection = NCONF_get_string(cnf, NULL, appname);
+
+	if (!appname || (!vsection && (flags & CONF_MFLAGS_DEFAULT_SECTION)))
+		vsection = NCONF_get_string(cnf, NULL, "openssl_conf");
+
+	if (!vsection) {
+		ERR_clear_error();
+		return 1;
+	}
+
+	values = NCONF_get_section(cnf, vsection);
+
+	if (!values)
+		return 0;
+
+	for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+		vl = sk_CONF_VALUE_value(values, i);
+		ret = module_run(cnf, vl->name, vl->value, flags);
+		if (ret <= 0)
+			if (!(flags & CONF_MFLAGS_IGNORE_ERRORS))
+				return ret;
+	}
+
+	return 1;
+}
+
+int
+CONF_modules_load_file(const char *filename, const char *appname,
+    unsigned long flags)
+{
+	char *file = NULL;
+	CONF *conf = NULL;
+	int ret = 0;
+	conf = NCONF_new(NULL);
+	if (!conf)
+		goto err;
+
+	if (filename == NULL) {
+		file = CONF_get1_default_config_file();
+		if (!file)
+			goto err;
+	} else
+		file = (char *)filename;
+
+	if (NCONF_load(conf, file, NULL) <= 0) {
+		if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) &&
+		    (ERR_GET_REASON(ERR_peek_last_error()) ==
+		    CONF_R_NO_SUCH_FILE)) {
+			ERR_clear_error();
+			ret = 1;
+		}
+		goto err;
+	}
+
+	ret = CONF_modules_load(conf, appname, flags);
+
+err:
+	if (filename == NULL)
+		free(file);
+	NCONF_free(conf);
+
+	return ret;
+}
+
+static int
+module_run(const CONF *cnf, char *name, char *value, unsigned long flags)
+{
+	CONF_MODULE *md;
+	int ret;
+
+	md = module_find(name);
+
+	/* Module not found: try to load DSO */
+	if (!md && !(flags & CONF_MFLAGS_NO_DSO))
+		md = module_load_dso(cnf, name, value, flags);
+
+	if (!md) {
+		if (!(flags & CONF_MFLAGS_SILENT)) {
+			CONFerr(CONF_F_MODULE_RUN, CONF_R_UNKNOWN_MODULE_NAME);
+			ERR_asprintf_error_data("module=%s", name);
+		}
+		return -1;
+	}
+
+	ret = module_init(md, name, value, cnf);
+
+	if (ret <= 0) {
+		if (!(flags & CONF_MFLAGS_SILENT)) {
+			CONFerr(CONF_F_MODULE_RUN,
+			    CONF_R_MODULE_INITIALIZATION_ERROR);
+			ERR_asprintf_error_data
+			    ("module=%s, value=%s, retcode=%-8d",
+			    name, value, ret);
+		}
+	}
+
+	return ret;
+}
+
+/* Load a module from a DSO */
+static CONF_MODULE *
+module_load_dso(const CONF *cnf, char *name, char *value, unsigned long flags)
+{
+	DSO *dso = NULL;
+	conf_init_func *ifunc;
+	conf_finish_func *ffunc;
+	char *path = NULL;
+	int errcode = 0;
+	CONF_MODULE *md;
+
+	/* Look for alternative path in module section */
+	path = NCONF_get_string(cnf, value, "path");
+	if (!path) {
+		ERR_clear_error();
+		path = name;
+	}
+	dso = DSO_load(NULL, path, NULL, 0);
+	if (!dso) {
+		errcode = CONF_R_ERROR_LOADING_DSO;
+		goto err;
+	}
+	ifunc = (conf_init_func *)DSO_bind_func(dso, DSO_mod_init_name);
+	if (!ifunc) {
+		errcode = CONF_R_MISSING_INIT_FUNCTION;
+		goto err;
+	}
+	ffunc = (conf_finish_func *)DSO_bind_func(dso, DSO_mod_finish_name);
+	/* All OK, add module */
+	md = module_add(dso, name, ifunc, ffunc);
+
+	if (!md)
+		goto err;
+
+	return md;
+
+err:
+	if (dso)
+		DSO_free(dso);
+	CONFerr(CONF_F_MODULE_LOAD_DSO, errcode);
+	ERR_asprintf_error_data("module=%s, path=%s", name, path);
+	return NULL;
+}
+
+/* add module to list */
+static CONF_MODULE *
+module_add(DSO *dso, const char *name, conf_init_func *ifunc,
+    conf_finish_func *ffunc)
+{
+	CONF_MODULE *tmod = NULL;
+
+	if (name == NULL)
+		return NULL;
+	if (supported_modules == NULL)
+		supported_modules = sk_CONF_MODULE_new_null();
+	if (supported_modules == NULL)
+		return NULL;
+	tmod = malloc(sizeof(CONF_MODULE));
+	if (tmod == NULL)
+		return NULL;
+
+	tmod->dso = dso;
+	tmod->name = strdup(name);
+	tmod->init = ifunc;
+	tmod->finish = ffunc;
+	tmod->links = 0;
+
+	if (!sk_CONF_MODULE_push(supported_modules, tmod)) {
+		free(tmod);
+		return NULL;
+	}
+
+	return tmod;
+}
+
+/* Find a module from the list. We allow module names of the
+ * form modname.XXXX to just search for modname to allow the
+ * same module to be initialized more than once.
+ */
+
+static CONF_MODULE *
+module_find(char *name)
+{
+	CONF_MODULE *tmod;
+	int i, nchar;
+	char *p;
+
+	p = strrchr(name, '.');
+
+	if (p)
+		nchar = p - name;
+	else
+		nchar = strlen(name);
+
+	for (i = 0; i < sk_CONF_MODULE_num(supported_modules); i++) {
+		tmod = sk_CONF_MODULE_value(supported_modules, i);
+		if (!strncmp(tmod->name, name, nchar))
+			return tmod;
+	}
+
+	return NULL;
+}
+
+/* initialize a module */
+static int
+module_init(CONF_MODULE *pmod, char *name, char *value, const CONF *cnf)
+{
+	int ret = 1;
+	int init_called = 0;
+	CONF_IMODULE *imod = NULL;
+
+	/* Otherwise add initialized module to list */
+	imod = malloc(sizeof(CONF_IMODULE));
+	if (!imod)
+		goto err;
+
+	imod->pmod = pmod;
+	imod->name = name ? strdup(name) : NULL;
+	imod->value = value ? strdup(value) : NULL;
+	imod->usr_data = NULL;
+
+	if (!imod->name || !imod->value)
+		goto memerr;
+
+	/* Try to initialize module */
+	if (pmod->init) {
+		ret = pmod->init(imod, cnf);
+		init_called = 1;
+		/* Error occurred, exit */
+		if (ret <= 0)
+			goto err;
+	}
+
+	if (initialized_modules == NULL) {
+		initialized_modules = sk_CONF_IMODULE_new_null();
+		if (!initialized_modules) {
+			CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+	}
+
+	if (!sk_CONF_IMODULE_push(initialized_modules, imod)) {
+		CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	pmod->links++;
+
+	return ret;
+
+err:
+	/* We've started the module so we'd better finish it */
+	if (pmod->finish && init_called)
+		pmod->finish(imod);
+
+memerr:
+	if (imod) {
+		free(imod->name);
+		free(imod->value);
+		free(imod);
+	}
+
+	return -1;
+}
+
+/* Unload any dynamic modules that have a link count of zero:
+ * i.e. have no active initialized modules. If 'all' is set
+ * then all modules are unloaded including static ones.
+ */
+
+void
+CONF_modules_unload(int all)
+{
+	int i;
+	CONF_MODULE *md;
+
+	CONF_modules_finish();
+
+	/* unload modules in reverse order */
+	for (i = sk_CONF_MODULE_num(supported_modules) - 1; i >= 0; i--) {
+		md = sk_CONF_MODULE_value(supported_modules, i);
+		/* If static or in use and 'all' not set ignore it */
+		if (((md->links > 0) || !md->dso) && !all)
+			continue;
+		/* Since we're working in reverse this is OK */
+		(void)sk_CONF_MODULE_delete(supported_modules, i);
+		module_free(md);
+	}
+	if (sk_CONF_MODULE_num(supported_modules) == 0) {
+		sk_CONF_MODULE_free(supported_modules);
+		supported_modules = NULL;
+	}
+}
+
+/* unload a single module */
+static void
+module_free(CONF_MODULE *md)
+{
+	if (md->dso)
+		DSO_free(md->dso);
+	free(md->name);
+	free(md);
+}
+
+/* finish and free up all modules instances */
+
+void
+CONF_modules_finish(void)
+{
+	CONF_IMODULE *imod;
+
+	while (sk_CONF_IMODULE_num(initialized_modules) > 0) {
+		imod = sk_CONF_IMODULE_pop(initialized_modules);
+		module_finish(imod);
+	}
+	sk_CONF_IMODULE_free(initialized_modules);
+	initialized_modules = NULL;
+}
+
+/* finish a module instance */
+
+static void
+module_finish(CONF_IMODULE *imod)
+{
+	if (imod->pmod->finish)
+		imod->pmod->finish(imod);
+	imod->pmod->links--;
+	free(imod->name);
+	free(imod->value);
+	free(imod);
+}
+
+/* Add a static module to OpenSSL */
+
+int
+CONF_module_add(const char *name, conf_init_func *ifunc,
+    conf_finish_func *ffunc)
+{
+	if (module_add(NULL, name, ifunc, ffunc))
+		return 1;
+	else
+		return 0;
+}
+
+void
+CONF_modules_free(void)
+{
+	CONF_modules_finish();
+	CONF_modules_unload(1);
+}
+
+/* Utility functions */
+
+const char *
+CONF_imodule_get_name(const CONF_IMODULE *md)
+{
+	return md->name;
+}
+
+const char *
+CONF_imodule_get_value(const CONF_IMODULE *md)
+{
+	return md->value;
+}
+
+void *
+CONF_imodule_get_usr_data(const CONF_IMODULE *md)
+{
+	return md->usr_data;
+}
+
+void
+CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data)
+{
+	md->usr_data = usr_data;
+}
+
+CONF_MODULE *
+CONF_imodule_get_module(const CONF_IMODULE *md)
+{
+	return md->pmod;
+}
+
+unsigned long
+CONF_imodule_get_flags(const CONF_IMODULE *md)
+{
+	return md->flags;
+}
+
+void
+CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags)
+{
+	md->flags = flags;
+}
+
+void *
+CONF_module_get_usr_data(CONF_MODULE *pmod)
+{
+	return pmod->usr_data;
+}
+
+void
+CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data)
+{
+	pmod->usr_data = usr_data;
+}
+
+/* Return default config file name */
+
+char *
+CONF_get1_default_config_file(void)
+{
+	char *file = NULL;
+
+	if (asprintf(&file, "%s/openssl.cnf",
+	    X509_get_default_cert_area()) == -1)
+		return (NULL);
+	return file;
+}
+
+/* This function takes a list separated by 'sep' and calls the
+ * callback function giving the start and length of each member
+ * optionally stripping leading and trailing whitespace. This can
+ * be used to parse comma separated lists for example.
+ */
+
+int
+CONF_parse_list(const char *list_, int sep, int nospc,
+    int (*list_cb)(const char *elem, int len, void *usr), void *arg)
+{
+	int ret;
+	const char *lstart, *tmpend, *p;
+
+	if (list_ == NULL) {
+		CONFerr(CONF_F_CONF_PARSE_LIST, CONF_R_LIST_CANNOT_BE_NULL);
+		return 0;
+	}
+
+	lstart = list_;
+	for (;;) {
+		if (nospc) {
+			while (*lstart && isspace((unsigned char)*lstart))
+				lstart++;
+		}
+		p = strchr(lstart, sep);
+		if (p == lstart || !*lstart)
+			ret = list_cb(NULL, 0, arg);
+		else {
+			if (p)
+				tmpend = p - 1;
+			else
+				tmpend = lstart + strlen(lstart) - 1;
+			if (nospc) {
+				while (isspace((unsigned char)*tmpend))
+					tmpend--;
+			}
+			ret = list_cb(lstart, tmpend - lstart + 1, arg);
+		}
+		if (ret <= 0)
+			return ret;
+		if (p == NULL)
+			return 1;
+		lstart = p + 1;
+	}
+}
diff --git a/crypto/libressl/crypto/conf/conf_sap.c b/crypto/libressl/crypto/conf/conf_sap.c
new file mode 100644
index 0000000000..35eb0cc721
--- /dev/null
+++ b/crypto/libressl/crypto/conf/conf_sap.c
@@ -0,0 +1,113 @@
+/* $OpenBSD: conf_sap.c,v 1.10 2014/07/11 08:44:48 jsing Exp $ */
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+
+/* This is the automatic configuration loader: it is called automatically by
+ * OpenSSL when any of a number of standard initialisation functions are called,
+ * unless this is overridden by calling OPENSSL_no_config()
+ */
+
+static int openssl_configured = 0;
+
+void
+OPENSSL_config(const char *config_name)
+{
+	if (openssl_configured)
+		return;
+
+	OPENSSL_load_builtin_modules();
+#ifndef OPENSSL_NO_ENGINE
+	/* Need to load ENGINEs */
+	ENGINE_load_builtin_engines();
+#endif
+	/* Add others here? */
+
+	ERR_clear_error();
+	if (CONF_modules_load_file(NULL, config_name,
+	    CONF_MFLAGS_DEFAULT_SECTION|CONF_MFLAGS_IGNORE_MISSING_FILE) <= 0) {
+		BIO *bio_err;
+		ERR_load_crypto_strings();
+		if ((bio_err = BIO_new_fp(stderr, BIO_NOCLOSE)) != NULL) {
+			BIO_printf(bio_err, "Auto configuration failed\n");
+			ERR_print_errors(bio_err);
+			BIO_free(bio_err);
+		}
+		exit(1);
+	}
+
+	return;
+}
+
+void
+OPENSSL_no_config(void)
+{
+	openssl_configured = 1;
+}
diff --git a/crypto/libressl/crypto/constant_time_locl.h b/crypto/libressl/crypto/constant_time_locl.h
new file mode 100644
index 0000000000..f8f0eae7ea
--- /dev/null
+++ b/crypto/libressl/crypto/constant_time_locl.h
@@ -0,0 +1,209 @@
+/* crypto/constant_time_locl.h */
+/*-
+ * Utilities for constant-time cryptography.
+ *
+ * Author: Emilia Kasper (emilia@openssl.org)
+ * Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley
+ * (Google).
+ * ====================================================================
+ * Copyright (c) 2014 The OpenSSL Project.  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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_CONSTANT_TIME_LOCL_H
+# define HEADER_CONSTANT_TIME_LOCL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-
+ * The boolean methods return a bitmask of all ones (0xff...f) for true
+ * and 0 for false. This is useful for choosing a value based on the result
+ * of a conditional in constant time. For example,
+ *
+ * if (a < b) {
+ *   c = a;
+ * } else {
+ *   c = b;
+ * }
+ *
+ * can be written as
+ *
+ * unsigned int lt = constant_time_lt(a, b);
+ * c = constant_time_select(lt, a, b);
+ */
+
+/*
+ * Returns the given value with the MSB copied to all the other
+ * bits. Uses the fact that arithmetic shift shifts-in the sign bit.
+ * However, this is not ensured by the C standard so you may need to
+ * replace this with something else on odd CPUs.
+ */
+static inline unsigned int constant_time_msb(unsigned int a);
+
+/*
+ * Returns 0xff..f if a < b and 0 otherwise.
+ */
+static inline unsigned int constant_time_lt(unsigned int a, unsigned int b);
+/* Convenience method for getting an 8-bit mask. */
+static inline unsigned char constant_time_lt_8(unsigned int a,
+                                               unsigned int b);
+
+/*
+ * Returns 0xff..f if a >= b and 0 otherwise.
+ */
+static inline unsigned int constant_time_ge(unsigned int a, unsigned int b);
+/* Convenience method for getting an 8-bit mask. */
+static inline unsigned char constant_time_ge_8(unsigned int a,
+                                               unsigned int b);
+
+/*
+ * Returns 0xff..f if a == 0 and 0 otherwise.
+ */
+static inline unsigned int constant_time_is_zero(unsigned int a);
+/* Convenience method for getting an 8-bit mask. */
+static inline unsigned char constant_time_is_zero_8(unsigned int a);
+
+/*
+ * Returns 0xff..f if a == b and 0 otherwise.
+ */
+static inline unsigned int constant_time_eq(unsigned int a, unsigned int b);
+/* Convenience method for getting an 8-bit mask. */
+static inline unsigned char constant_time_eq_8(unsigned int a,
+                                               unsigned int b);
+/* Signed integers. */
+static inline unsigned int constant_time_eq_int(int a, int b);
+/* Convenience method for getting an 8-bit mask. */
+static inline unsigned char constant_time_eq_int_8(int a, int b);
+
+/*-
+ * Returns (mask & a) | (~mask & b).
+ *
+ * When |mask| is all 1s or all 0s (as returned by the methods above),
+ * the select methods return either |a| (if |mask| is nonzero) or |b|
+ * (if |mask| is zero).
+ */
+static inline unsigned int constant_time_select(unsigned int mask,
+                                                unsigned int a,
+                                                unsigned int b);
+/* Convenience method for unsigned chars. */
+static inline unsigned char constant_time_select_8(unsigned char mask,
+                                                   unsigned char a,
+                                                   unsigned char b);
+/* Convenience method for signed integers. */
+static inline int constant_time_select_int(unsigned int mask, int a, int b);
+
+static inline unsigned int constant_time_msb(unsigned int a)
+{
+    return 0 - (a >> (sizeof(a) * 8 - 1));
+}
+
+static inline unsigned int constant_time_lt(unsigned int a, unsigned int b)
+{
+    return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b)));
+}
+
+static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b)
+{
+    return (unsigned char)(constant_time_lt(a, b));
+}
+
+static inline unsigned int constant_time_ge(unsigned int a, unsigned int b)
+{
+    return ~constant_time_lt(a, b);
+}
+
+static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b)
+{
+    return (unsigned char)(constant_time_ge(a, b));
+}
+
+static inline unsigned int constant_time_is_zero(unsigned int a)
+{
+    return constant_time_msb(~a & (a - 1));
+}
+
+static inline unsigned char constant_time_is_zero_8(unsigned int a)
+{
+    return (unsigned char)(constant_time_is_zero(a));
+}
+
+static inline unsigned int constant_time_eq(unsigned int a, unsigned int b)
+{
+    return constant_time_is_zero(a ^ b);
+}
+
+static inline unsigned char constant_time_eq_8(unsigned int a, unsigned int b)
+{
+    return (unsigned char)(constant_time_eq(a, b));
+}
+
+static inline unsigned int constant_time_eq_int(int a, int b)
+{
+    return constant_time_eq((unsigned)(a), (unsigned)(b));
+}
+
+static inline unsigned char constant_time_eq_int_8(int a, int b)
+{
+    return constant_time_eq_8((unsigned)(a), (unsigned)(b));
+}
+
+static inline unsigned int constant_time_select(unsigned int mask,
+                                                unsigned int a,
+                                                unsigned int b)
+{
+    return (mask & a) | (~mask & b);
+}
+
+static inline unsigned char constant_time_select_8(unsigned char mask,
+                                                   unsigned char a,
+                                                   unsigned char b)
+{
+    return (unsigned char)(constant_time_select(mask, a, b));
+}
+
+static inline int constant_time_select_int(unsigned int mask, int a, int b)
+{
+    return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b)));
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif                          /* HEADER_CONSTANT_TIME_LOCL_H */
diff --git a/crypto/libressl/crypto/cpt_err.c b/crypto/libressl/crypto/cpt_err.c
new file mode 100644
index 0000000000..92f5724572
--- /dev/null
+++ b/crypto/libressl/crypto/cpt_err.c
@@ -0,0 +1,105 @@
+/* $OpenBSD: cpt_err.c,v 1.12 2014/06/12 15:49:27 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2011 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_CRYPTO,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_CRYPTO,0,reason)
+
+static ERR_STRING_DATA CRYPTO_str_functs[] = {
+	{ERR_FUNC(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX),	"CRYPTO_get_ex_new_index"},
+	{ERR_FUNC(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID),	"CRYPTO_get_new_dynlockid"},
+	{ERR_FUNC(CRYPTO_F_CRYPTO_GET_NEW_LOCKID),	"CRYPTO_get_new_lockid"},
+	{ERR_FUNC(CRYPTO_F_CRYPTO_SET_EX_DATA),	"CRYPTO_set_ex_data"},
+	{ERR_FUNC(CRYPTO_F_DEF_ADD_INDEX),	"DEF_ADD_INDEX"},
+	{ERR_FUNC(CRYPTO_F_DEF_GET_CLASS),	"DEF_GET_CLASS"},
+	{ERR_FUNC(CRYPTO_F_FIPS_MODE_SET),	"FIPS_mode_set"},
+	{ERR_FUNC(CRYPTO_F_INT_DUP_EX_DATA),	"INT_DUP_EX_DATA"},
+	{ERR_FUNC(CRYPTO_F_INT_FREE_EX_DATA),	"INT_FREE_EX_DATA"},
+	{ERR_FUNC(CRYPTO_F_INT_NEW_EX_DATA),	"INT_NEW_EX_DATA"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA CRYPTO_str_reasons[] = {
+	{ERR_REASON(CRYPTO_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"},
+	{ERR_REASON(CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK), "no dynlock create callback"},
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_CRYPTO_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(CRYPTO_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, CRYPTO_str_functs);
+		ERR_load_strings(0, CRYPTO_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/cpuid-elf-x86_64.S b/crypto/libressl/crypto/cpuid-elf-x86_64.S
new file mode 100644
index 0000000000..a2528d9838
--- /dev/null
+++ b/crypto/libressl/crypto/cpuid-elf-x86_64.S
@@ -0,0 +1,178 @@
+
+.hidden	OPENSSL_cpuid_setup
+.section	.init
+	call	OPENSSL_cpuid_setup
+
+.hidden	OPENSSL_ia32cap_P
+.comm	OPENSSL_ia32cap_P,8,4
+
+.text	
+
+.globl	OPENSSL_atomic_add
+.type	OPENSSL_atomic_add,@function
+.align	16
+OPENSSL_atomic_add:
+	movl	(%rdi),%eax
+.Lspin:	leaq	(%rsi,%rax,1),%r8
+.byte	0xf0		
+	cmpxchgl	%r8d,(%rdi)
+	jne	.Lspin
+	movl	%r8d,%eax
+.byte	0x48,0x98	
+	.byte	0xf3,0xc3
+.size	OPENSSL_atomic_add,.-OPENSSL_atomic_add
+
+.globl	OPENSSL_ia32_cpuid
+.type	OPENSSL_ia32_cpuid,@function
+.align	16
+OPENSSL_ia32_cpuid:
+	movq	%rbx,%r8
+
+	xorl	%eax,%eax
+	cpuid
+	movl	%eax,%r11d
+
+	xorl	%eax,%eax
+	cmpl	$1970169159,%ebx
+	setne	%al
+	movl	%eax,%r9d
+	cmpl	$1231384169,%edx
+	setne	%al
+	orl	%eax,%r9d
+	cmpl	$1818588270,%ecx
+	setne	%al
+	orl	%eax,%r9d
+	jz	.Lintel
+
+	cmpl	$1752462657,%ebx
+	setne	%al
+	movl	%eax,%r10d
+	cmpl	$1769238117,%edx
+	setne	%al
+	orl	%eax,%r10d
+	cmpl	$1145913699,%ecx
+	setne	%al
+	orl	%eax,%r10d
+	jnz	.Lintel
+
+
+	movl	$2147483648,%eax
+	cpuid
+	cmpl	$2147483649,%eax
+	jb	.Lintel
+	movl	%eax,%r10d
+	movl	$2147483649,%eax
+	cpuid
+	orl	%ecx,%r9d
+	andl	$2049,%r9d
+
+	cmpl	$2147483656,%r10d
+	jb	.Lintel
+
+	movl	$2147483656,%eax
+	cpuid
+	movzbq	%cl,%r10
+	incq	%r10
+
+	movl	$1,%eax
+	cpuid
+	btl	$28,%edx
+	jnc	.Lgeneric
+	shrl	$16,%ebx
+	cmpb	%r10b,%bl
+	ja	.Lgeneric
+	andl	$4026531839,%edx
+	jmp	.Lgeneric
+
+.Lintel:
+	cmpl	$4,%r11d
+	movl	$-1,%r10d
+	jb	.Lnocacheinfo
+
+	movl	$4,%eax
+	movl	$0,%ecx
+	cpuid
+	movl	%eax,%r10d
+	shrl	$14,%r10d
+	andl	$4095,%r10d
+
+.Lnocacheinfo:
+	movl	$1,%eax
+	cpuid
+	andl	$3220176895,%edx
+	cmpl	$0,%r9d
+	jne	.Lnotintel
+	orl	$1073741824,%edx
+	andb	$15,%ah
+	cmpb	$15,%ah
+	jne	.Lnotintel
+	orl	$1048576,%edx
+.Lnotintel:
+	btl	$28,%edx
+	jnc	.Lgeneric
+	andl	$4026531839,%edx
+	cmpl	$0,%r10d
+	je	.Lgeneric
+
+	orl	$268435456,%edx
+	shrl	$16,%ebx
+	cmpb	$1,%bl
+	ja	.Lgeneric
+	andl	$4026531839,%edx
+.Lgeneric:
+	andl	$2048,%r9d
+	andl	$4294965247,%ecx
+	orl	%ecx,%r9d
+
+	movl	%edx,%r10d
+	btl	$27,%r9d
+	jnc	.Lclear_avx
+	xorl	%ecx,%ecx
+.byte	0x0f,0x01,0xd0		
+	andl	$6,%eax
+	cmpl	$6,%eax
+	je	.Ldone
+.Lclear_avx:
+	movl	$4026525695,%eax
+	andl	%eax,%r9d
+.Ldone:
+	shlq	$32,%r9
+	movl	%r10d,%eax
+	movq	%r8,%rbx
+	orq	%r9,%rax
+	.byte	0xf3,0xc3
+.size	OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid
+.globl	OPENSSL_wipe_cpu
+.type	OPENSSL_wipe_cpu,@function
+.align	16
+OPENSSL_wipe_cpu:
+	pxor	%xmm0,%xmm0
+	pxor	%xmm1,%xmm1
+	pxor	%xmm2,%xmm2
+	pxor	%xmm3,%xmm3
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	pxor	%xmm6,%xmm6
+	pxor	%xmm7,%xmm7
+	pxor	%xmm8,%xmm8
+	pxor	%xmm9,%xmm9
+	pxor	%xmm10,%xmm10
+	pxor	%xmm11,%xmm11
+	pxor	%xmm12,%xmm12
+	pxor	%xmm13,%xmm13
+	pxor	%xmm14,%xmm14
+	pxor	%xmm15,%xmm15
+	xorq	%rcx,%rcx
+	xorq	%rdx,%rdx
+	xorq	%rsi,%rsi
+	xorq	%rdi,%rdi
+	xorq	%r8,%r8
+	xorq	%r9,%r9
+	xorq	%r10,%r10
+	xorq	%r11,%r11
+	leaq	8(%rsp),%rax
+	.byte	0xf3,0xc3
+.size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
+#if defined(HAVE_GNU_STACK)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/crypto/libressl/crypto/cpuid-macosx-x86_64.S b/crypto/libressl/crypto/cpuid-macosx-x86_64.S
new file mode 100644
index 0000000000..d0e5c07157
--- /dev/null
+++ b/crypto/libressl/crypto/cpuid-macosx-x86_64.S
@@ -0,0 +1,176 @@
+
+.private_extern	_OPENSSL_cpuid_setup
+.mod_init_func
+	.p2align	3
+	.quad	_OPENSSL_cpuid_setup
+
+.private_extern	_OPENSSL_ia32cap_P
+.comm	_OPENSSL_ia32cap_P,8,2
+
+.text	
+
+.globl	_OPENSSL_atomic_add
+
+.p2align	4
+_OPENSSL_atomic_add:
+	movl	(%rdi),%eax
+L$spin:	leaq	(%rsi,%rax,1),%r8
+.byte	0xf0		
+	cmpxchgl	%r8d,(%rdi)
+	jne	L$spin
+	movl	%r8d,%eax
+.byte	0x48,0x98	
+	.byte	0xf3,0xc3
+
+
+.globl	_OPENSSL_ia32_cpuid
+
+.p2align	4
+_OPENSSL_ia32_cpuid:
+	movq	%rbx,%r8
+
+	xorl	%eax,%eax
+	cpuid
+	movl	%eax,%r11d
+
+	xorl	%eax,%eax
+	cmpl	$1970169159,%ebx
+	setne	%al
+	movl	%eax,%r9d
+	cmpl	$1231384169,%edx
+	setne	%al
+	orl	%eax,%r9d
+	cmpl	$1818588270,%ecx
+	setne	%al
+	orl	%eax,%r9d
+	jz	L$intel
+
+	cmpl	$1752462657,%ebx
+	setne	%al
+	movl	%eax,%r10d
+	cmpl	$1769238117,%edx
+	setne	%al
+	orl	%eax,%r10d
+	cmpl	$1145913699,%ecx
+	setne	%al
+	orl	%eax,%r10d
+	jnz	L$intel
+
+
+	movl	$2147483648,%eax
+	cpuid
+	cmpl	$2147483649,%eax
+	jb	L$intel
+	movl	%eax,%r10d
+	movl	$2147483649,%eax
+	cpuid
+	orl	%ecx,%r9d
+	andl	$2049,%r9d
+
+	cmpl	$2147483656,%r10d
+	jb	L$intel
+
+	movl	$2147483656,%eax
+	cpuid
+	movzbq	%cl,%r10
+	incq	%r10
+
+	movl	$1,%eax
+	cpuid
+	btl	$28,%edx
+	jnc	L$generic
+	shrl	$16,%ebx
+	cmpb	%r10b,%bl
+	ja	L$generic
+	andl	$4026531839,%edx
+	jmp	L$generic
+
+L$intel:
+	cmpl	$4,%r11d
+	movl	$-1,%r10d
+	jb	L$nocacheinfo
+
+	movl	$4,%eax
+	movl	$0,%ecx
+	cpuid
+	movl	%eax,%r10d
+	shrl	$14,%r10d
+	andl	$4095,%r10d
+
+L$nocacheinfo:
+	movl	$1,%eax
+	cpuid
+	andl	$3220176895,%edx
+	cmpl	$0,%r9d
+	jne	L$notintel
+	orl	$1073741824,%edx
+	andb	$15,%ah
+	cmpb	$15,%ah
+	jne	L$notintel
+	orl	$1048576,%edx
+L$notintel:
+	btl	$28,%edx
+	jnc	L$generic
+	andl	$4026531839,%edx
+	cmpl	$0,%r10d
+	je	L$generic
+
+	orl	$268435456,%edx
+	shrl	$16,%ebx
+	cmpb	$1,%bl
+	ja	L$generic
+	andl	$4026531839,%edx
+L$generic:
+	andl	$2048,%r9d
+	andl	$4294965247,%ecx
+	orl	%ecx,%r9d
+
+	movl	%edx,%r10d
+	btl	$27,%r9d
+	jnc	L$clear_avx
+	xorl	%ecx,%ecx
+.byte	0x0f,0x01,0xd0		
+	andl	$6,%eax
+	cmpl	$6,%eax
+	je	L$done
+L$clear_avx:
+	movl	$4026525695,%eax
+	andl	%eax,%r9d
+L$done:
+	shlq	$32,%r9
+	movl	%r10d,%eax
+	movq	%r8,%rbx
+	orq	%r9,%rax
+	.byte	0xf3,0xc3
+
+.globl	_OPENSSL_wipe_cpu
+
+.p2align	4
+_OPENSSL_wipe_cpu:
+	pxor	%xmm0,%xmm0
+	pxor	%xmm1,%xmm1
+	pxor	%xmm2,%xmm2
+	pxor	%xmm3,%xmm3
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	pxor	%xmm6,%xmm6
+	pxor	%xmm7,%xmm7
+	pxor	%xmm8,%xmm8
+	pxor	%xmm9,%xmm9
+	pxor	%xmm10,%xmm10
+	pxor	%xmm11,%xmm11
+	pxor	%xmm12,%xmm12
+	pxor	%xmm13,%xmm13
+	pxor	%xmm14,%xmm14
+	pxor	%xmm15,%xmm15
+	xorq	%rcx,%rcx
+	xorq	%rdx,%rdx
+	xorq	%rsi,%rsi
+	xorq	%rdi,%rdi
+	xorq	%r8,%r8
+	xorq	%r9,%r9
+	xorq	%r10,%r10
+	xorq	%r11,%r11
+	leaq	8(%rsp),%rax
+	.byte	0xf3,0xc3
+
diff --git a/crypto/libressl/crypto/cryptlib.c b/crypto/libressl/crypto/cryptlib.c
new file mode 100644
index 0000000000..695f3549b2
--- /dev/null
+++ b/crypto/libressl/crypto/cryptlib.c
@@ -0,0 +1,716 @@
+/* $OpenBSD: cryptlib.c,v 1.36 2015/09/13 10:02:49 miod Exp $ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+DECLARE_STACK_OF(CRYPTO_dynlock)
+
+/* real #defines in crypto.h, keep these upto date */
+static const char* const lock_names[CRYPTO_NUM_LOCKS] = {
+	"<>",
+	"err",
+	"ex_data",
+	"x509",
+	"x509_info",
+	"x509_pkey",
+	"x509_crl",
+	"x509_req",
+	"dsa",
+	"rsa",
+	"evp_pkey",
+	"x509_store",
+	"ssl_ctx",
+	"ssl_cert",
+	"ssl_session",
+	"ssl_sess_cert",
+	"ssl",
+	"ssl_method",
+	"rand",
+	"rand2",
+	"debug_malloc",
+	"BIO",
+	"gethostbyname",
+	"getservbyname",
+	"readdir",
+	"RSA_blinding",
+	"dh",
+	"debug_malloc2",
+	"dso",
+	"dynlock",
+	"engine",
+	"ui",
+	"ecdsa",
+	"ec",
+	"ecdh",
+	"bn",
+	"ec_pre_comp",
+	"store",
+	"comp",
+	"fips",
+	"fips2",
+#if CRYPTO_NUM_LOCKS != 41
+# error "Inconsistency between crypto.h and cryptlib.c"
+#endif
+};
+
+/* This is for applications to allocate new type names in the non-dynamic
+   array of lock names.  These are numbered with positive numbers.  */
+static STACK_OF(OPENSSL_STRING) *app_locks = NULL;
+
+/* For applications that want a more dynamic way of handling threads, the
+   following stack is used.  These are externally numbered with negative
+   numbers.  */
+static STACK_OF(CRYPTO_dynlock) *dyn_locks = NULL;
+
+static void (*locking_callback)(int mode, int type,
+    const char *file, int line) = 0;
+static int (*add_lock_callback)(int *pointer, int amount,
+    int type, const char *file, int line) = 0;
+#ifndef OPENSSL_NO_DEPRECATED
+static unsigned long (*id_callback)(void) = 0;
+#endif
+static void (*threadid_callback)(CRYPTO_THREADID *) = 0;
+static struct CRYPTO_dynlock_value *(*dynlock_create_callback)(
+    const char *file, int line) = 0;
+static void (*dynlock_lock_callback)(int mode,
+    struct CRYPTO_dynlock_value *l, const char *file, int line) = 0;
+static void (*dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l,
+    const char *file, int line) = 0;
+
+int
+CRYPTO_get_new_lockid(char *name)
+{
+	char *str;
+	int i;
+
+	if ((app_locks == NULL) &&
+	    ((app_locks = sk_OPENSSL_STRING_new_null()) == NULL)) {
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID, ERR_R_MALLOC_FAILURE);
+		return (0);
+	}
+	if (name == NULL || (str = strdup(name)) == NULL) {
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID, ERR_R_MALLOC_FAILURE);
+		return (0);
+	}
+	i = sk_OPENSSL_STRING_push(app_locks, str);
+	if (!i)
+		free(str);
+	else
+		i += CRYPTO_NUM_LOCKS; /* gap of one :-) */
+	return (i);
+}
+
+int
+CRYPTO_num_locks(void)
+{
+	return CRYPTO_NUM_LOCKS;
+}
+
+int
+CRYPTO_get_new_dynlockid(void)
+{
+	int i = 0;
+	CRYPTO_dynlock *pointer = NULL;
+
+	if (dynlock_create_callback == NULL) {
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,
+		    CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK);
+		return (0);
+	}
+	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
+	if ((dyn_locks == NULL) &&
+	    ((dyn_locks = sk_CRYPTO_dynlock_new_null()) == NULL)) {
+		CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,
+		    ERR_R_MALLOC_FAILURE);
+		return (0);
+	}
+	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+
+	pointer = malloc(sizeof(CRYPTO_dynlock));
+	if (pointer == NULL) {
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,
+		    ERR_R_MALLOC_FAILURE);
+		return (0);
+	}
+	pointer->references = 1;
+	pointer->data = dynlock_create_callback(__FILE__, __LINE__);
+	if (pointer->data == NULL) {
+		free(pointer);
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,
+		    ERR_R_MALLOC_FAILURE);
+		return (0);
+	}
+
+	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
+	/* First, try to find an existing empty slot */
+	i = sk_CRYPTO_dynlock_find(dyn_locks, NULL);
+	/* If there was none, push, thereby creating a new one */
+	if (i == -1)
+		/* Since sk_push() returns the number of items on the
+		   stack, not the location of the pushed item, we need
+		   to transform the returned number into a position,
+		   by decreasing it.  */
+		i = sk_CRYPTO_dynlock_push(dyn_locks, pointer) - 1;
+	else
+		/* If we found a place with a NULL pointer, put our pointer
+		   in it.  */
+		(void)sk_CRYPTO_dynlock_set(dyn_locks, i, pointer);
+	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+
+	if (i == -1) {
+		dynlock_destroy_callback(pointer->data, __FILE__, __LINE__);
+		free(pointer);
+	} else
+		i += 1; /* to avoid 0 */
+	return -i;
+}
+
+void
+CRYPTO_destroy_dynlockid(int i)
+{
+	CRYPTO_dynlock *pointer = NULL;
+
+	if (i)
+		i = -i - 1;
+	if (dynlock_destroy_callback == NULL)
+		return;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
+
+	if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks)) {
+		CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+		return;
+	}
+	pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
+	if (pointer != NULL) {
+		--pointer->references;
+		if (pointer->references <= 0) {
+			(void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
+		} else
+			pointer = NULL;
+	}
+	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+
+	if (pointer) {
+		dynlock_destroy_callback(pointer->data, __FILE__, __LINE__);
+		free(pointer);
+	}
+}
+
+struct CRYPTO_dynlock_value *
+CRYPTO_get_dynlock_value(int i)
+{
+	CRYPTO_dynlock *pointer = NULL;
+
+	if (i)
+		i = -i - 1;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
+
+	if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
+		pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
+	if (pointer)
+		pointer->references++;
+
+	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+
+	if (pointer)
+		return pointer->data;
+	return NULL;
+}
+
+struct CRYPTO_dynlock_value *
+(*CRYPTO_get_dynlock_create_callback(void))(const char *file, int line)
+{
+	return (dynlock_create_callback);
+}
+
+void
+(*CRYPTO_get_dynlock_lock_callback(void))(int mode,
+    struct CRYPTO_dynlock_value *l, const char *file, int line)
+{
+	return (dynlock_lock_callback);
+}
+
+void
+(*CRYPTO_get_dynlock_destroy_callback(void))(struct CRYPTO_dynlock_value *l,
+    const char *file, int line)
+{
+	return (dynlock_destroy_callback);
+}
+
+void
+CRYPTO_set_dynlock_create_callback(
+    struct CRYPTO_dynlock_value *(*func)(const char *file, int line))
+{
+	dynlock_create_callback = func;
+}
+
+void
+CRYPTO_set_dynlock_lock_callback(void (*func)(int mode,
+    struct CRYPTO_dynlock_value *l, const char *file, int line))
+{
+	dynlock_lock_callback = func;
+}
+
+void
+CRYPTO_set_dynlock_destroy_callback(
+    void (*func)(struct CRYPTO_dynlock_value *l, const char *file, int line))
+{
+	dynlock_destroy_callback = func;
+}
+
+void
+(*CRYPTO_get_locking_callback(void))(int mode, int type, const char *file,
+    int line)
+{
+	return (locking_callback);
+}
+
+int
+(*CRYPTO_get_add_lock_callback(void))(int *num, int mount, int type,
+    const char *file, int line)
+{
+	return (add_lock_callback);
+}
+
+void
+CRYPTO_set_locking_callback(void (*func)(int mode, int type,
+    const char *file, int line))
+{
+	/* Calling this here ensures initialisation before any threads
+	 * are started.
+	 */
+	OPENSSL_init();
+	locking_callback = func;
+}
+
+void
+CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int type,
+    const char *file, int line))
+{
+	add_lock_callback = func;
+}
+
+/* the memset() here and in set_pointer() seem overkill, but for the sake of
+ * CRYPTO_THREADID_cmp() this avoids any platform silliness that might cause two
+ * "equal" THREADID structs to not be memcmp()-identical. */
+void
+CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val)
+{
+	memset(id, 0, sizeof(*id));
+	id->val = val;
+}
+
+void
+CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr)
+{
+	memset(id, 0, sizeof(*id));
+	id->ptr = ptr;
+#if ULONG_MAX >= UINTPTR_MAX
+	/*s u 'ptr' can be embedded in 'val' without loss of uniqueness */
+	id->val = (uintptr_t)id->ptr;
+#else
+	{
+		SHA256_CTX ctx;
+		uint8_t results[SHA256_DIGEST_LENGTH];
+
+		SHA256_Init(&ctx);
+		SHA256_Update(&ctx, (char *)(&id->ptr), sizeof(id->ptr));
+		SHA256_Final(results, &ctx);
+		memcpy(&id->val, results, sizeof(id->val));
+	}
+#endif
+}
+
+int
+CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *))
+{
+	if (threadid_callback)
+		return 0;
+	threadid_callback = func;
+	return 1;
+}
+
+void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *)
+{
+	return threadid_callback;
+}
+
+void
+CRYPTO_THREADID_current(CRYPTO_THREADID *id)
+{
+	if (threadid_callback) {
+		threadid_callback(id);
+		return;
+	}
+#ifndef OPENSSL_NO_DEPRECATED
+	/* If the deprecated callback was set, fall back to that */
+	if (id_callback) {
+		CRYPTO_THREADID_set_numeric(id, id_callback());
+		return;
+	}
+#endif
+	/* Else pick a backup */
+	/* For everything else, default to using the address of 'errno' */
+	CRYPTO_THREADID_set_pointer(id, (void*)&errno);
+}
+
+int
+CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b)
+{
+	return memcmp(a, b, sizeof(*a));
+}
+
+void
+CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src)
+{
+	memcpy(dest, src, sizeof(*src));
+}
+
+unsigned long
+CRYPTO_THREADID_hash(const CRYPTO_THREADID *id)
+{
+	return id->val;
+}
+
+#ifndef OPENSSL_NO_DEPRECATED
+unsigned long (*CRYPTO_get_id_callback(void))(void)
+{
+	return (id_callback);
+}
+
+void
+CRYPTO_set_id_callback(unsigned long (*func)(void))
+{
+	id_callback = func;
+}
+
+unsigned long
+CRYPTO_thread_id(void)
+{
+	unsigned long ret = 0;
+
+	if (id_callback == NULL) {
+		ret = (unsigned long)getpid();
+	} else
+		ret = id_callback();
+	return (ret);
+}
+#endif
+
+void
+CRYPTO_lock(int mode, int type, const char *file, int line)
+{
+#ifdef LOCK_DEBUG
+	{
+		CRYPTO_THREADID id;
+		char *rw_text, *operation_text;
+
+		if (mode & CRYPTO_LOCK)
+			operation_text = "lock  ";
+		else if (mode & CRYPTO_UNLOCK)
+			operation_text = "unlock";
+		else
+			operation_text = "ERROR ";
+
+		if (mode & CRYPTO_READ)
+			rw_text = "r";
+		else if (mode & CRYPTO_WRITE)
+			rw_text = "w";
+		else
+			rw_text = "ERROR";
+
+		CRYPTO_THREADID_current(&id);
+		fprintf(stderr, "lock:%08lx:(%s)%s %-18s %s:%d\n",
+		    CRYPTO_THREADID_hash(&id), rw_text, operation_text,
+		    CRYPTO_get_lock_name(type), file, line);
+	}
+#endif
+	if (type < 0) {
+		if (dynlock_lock_callback != NULL) {
+			struct CRYPTO_dynlock_value *pointer =
+			    CRYPTO_get_dynlock_value(type);
+
+			OPENSSL_assert(pointer != NULL);
+
+			dynlock_lock_callback(mode, pointer, file, line);
+
+			CRYPTO_destroy_dynlockid(type);
+		}
+	} else if (locking_callback != NULL)
+		locking_callback(mode, type, file, line);
+}
+
+int
+CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
+    int line)
+{
+	int ret = 0;
+
+	if (add_lock_callback != NULL) {
+#ifdef LOCK_DEBUG
+		int before= *pointer;
+#endif
+
+		ret = add_lock_callback(pointer, amount, type, file, line);
+#ifdef LOCK_DEBUG
+		{
+			CRYPTO_THREADID id;
+			CRYPTO_THREADID_current(&id);
+			fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
+			    CRYPTO_THREADID_hash(&id), before, amount, ret,
+			    CRYPTO_get_lock_name(type),
+			    file, line);
+		}
+#endif
+	} else {
+		CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE, type, file, line);
+
+		ret= *pointer + amount;
+#ifdef LOCK_DEBUG
+		{
+			CRYPTO_THREADID id;
+			CRYPTO_THREADID_current(&id);
+			fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
+			    CRYPTO_THREADID_hash(&id), *pointer, amount, ret,
+			    CRYPTO_get_lock_name(type), file, line);
+		}
+#endif
+		*pointer = ret;
+		CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE, type, file, line);
+	}
+	return (ret);
+}
+
+const char *
+CRYPTO_get_lock_name(int type)
+{
+	if (type < 0)
+		return("dynamic");
+	else if (type < CRYPTO_NUM_LOCKS)
+		return (lock_names[type]);
+	else if (type - CRYPTO_NUM_LOCKS > sk_OPENSSL_STRING_num(app_locks))
+		return("ERROR");
+	else
+		return (sk_OPENSSL_STRING_value(app_locks,
+		    type - CRYPTO_NUM_LOCKS));
+}
+
+#if	defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
+	defined(__INTEL__) || \
+	defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
+
+unsigned int  OPENSSL_ia32cap_P[2];
+
+uint64_t
+OPENSSL_cpu_caps(void)
+{
+	return *(uint64_t *)OPENSSL_ia32cap_P;
+}
+
+#if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
+#define OPENSSL_CPUID_SETUP
+typedef unsigned long long IA32CAP;
+void
+OPENSSL_cpuid_setup(void)
+{
+	static int trigger = 0;
+	IA32CAP OPENSSL_ia32_cpuid(void);
+	IA32CAP vec;
+
+	if (trigger)
+		return;
+	trigger = 1;
+
+	vec = OPENSSL_ia32_cpuid();
+
+	/*
+	 * |(1<<10) sets a reserved bit to signal that variable
+	 * was initialized already... This is to avoid interference
+	 * with cpuid snippets in ELF .init segment.
+	 */
+	OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10);
+	OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32);
+}
+#endif
+
+#else
+unsigned long *
+OPENSSL_ia32cap_loc(void)
+{
+	return NULL;
+}
+
+uint64_t
+OPENSSL_cpu_caps(void)
+{
+	return 0;
+}
+#endif
+
+#if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)
+void
+OPENSSL_cpuid_setup(void)
+{
+}
+#endif
+
+static void
+OPENSSL_showfatal(const char *fmta, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmta);
+	vfprintf(stderr, fmta, ap);
+	va_end(ap);
+}
+
+void
+OpenSSLDie(const char *file, int line, const char *assertion)
+{
+	OPENSSL_showfatal(
+	    "%s(%d): OpenSSL internal error, assertion failed: %s\n",
+	    file, line, assertion);
+	abort();
+}
+
+int
+CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len)
+{
+	size_t i;
+	const unsigned char *a = in_a;
+	const unsigned char *b = in_b;
+	unsigned char x = 0;
+
+	for (i = 0; i < len; i++)
+		x |= a[i] ^ b[i];
+
+	return x;
+}
diff --git a/crypto/libressl/crypto/cryptlib.h b/crypto/libressl/crypto/cryptlib.h
new file mode 100644
index 0000000000..2b89109b3b
--- /dev/null
+++ b/crypto/libressl/crypto/cryptlib.h
@@ -0,0 +1,82 @@
+/* $OpenBSD: cryptlib.h,v 1.23 2014/07/10 22:13:39 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_CRYPTLIB_H
+#define HEADER_CRYPTLIB_H
+
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define X509_CERT_AREA		OPENSSLDIR
+#define X509_CERT_DIR		OPENSSLDIR "/certs"
+#define X509_CERT_FILE		OPENSSLDIR "/cert.pem"
+#define X509_PRIVATE_DIR	OPENSSLDIR "/private"
+#define X509_CERT_DIR_EVP        "SSL_CERT_DIR"
+#define X509_CERT_FILE_EVP       "SSL_CERT_FILE"
+
+void OPENSSL_cpuid_setup(void);
+extern unsigned int OPENSSL_ia32cap_P[];
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/crypto/libressl/crypto/cversion.c b/crypto/libressl/crypto/cversion.c
new file mode 100644
index 0000000000..580176df65
--- /dev/null
+++ b/crypto/libressl/crypto/cversion.c
@@ -0,0 +1,86 @@
+/* $OpenBSD: cversion.c,v 1.14 2014/07/11 08:44:47 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include "cryptlib.h"
+
+const char *
+SSLeay_version(int t)
+{
+	switch (t) {
+	case SSLEAY_VERSION:
+		return OPENSSL_VERSION_TEXT;
+	case SSLEAY_BUILT_ON:
+		return("built on: date not available");
+	case SSLEAY_CFLAGS:
+		return("compiler: information not available");
+	case SSLEAY_PLATFORM:
+		return("platform: information not available");
+	case SSLEAY_DIR:
+		return "OPENSSLDIR: \"" OPENSSLDIR "\"";
+	}
+	return("not available");
+}
+
+unsigned long
+SSLeay(void)
+{
+	return (SSLEAY_VERSION_NUMBER);
+}
diff --git a/crypto/libressl/crypto/des/cbc_cksm.c b/crypto/libressl/crypto/des/cbc_cksm.c
new file mode 100644
index 0000000000..d1a3fc3580
--- /dev/null
+++ b/crypto/libressl/crypto/des/cbc_cksm.c
@@ -0,0 +1,106 @@
+/* $OpenBSD: cbc_cksm.c,v 1.6 2014/06/12 15:49:28 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+DES_LONG DES_cbc_cksum(const unsigned char *in, DES_cblock *output,
+		       long length, DES_key_schedule *schedule,
+		       const_DES_cblock *ivec)
+	{
+	DES_LONG tout0,tout1,tin0,tin1;
+	long l=length;
+	DES_LONG tin[2];
+	unsigned char *out = &(*output)[0];
+	const unsigned char *iv = &(*ivec)[0];
+
+	c2l(iv,tout0);
+	c2l(iv,tout1);
+	for (; l>0; l-=8)
+		{
+		if (l >= 8)
+			{
+			c2l(in,tin0);
+			c2l(in,tin1);
+			}
+		else
+			c2ln(in,tin0,tin1,l);
+			
+		tin0^=tout0; tin[0]=tin0;
+		tin1^=tout1; tin[1]=tin1;
+		DES_encrypt1((DES_LONG *)tin,schedule,DES_ENCRYPT);
+		/* fix 15/10/91 eay - thanks to keithr@sco.COM */
+		tout0=tin[0];
+		tout1=tin[1];
+		}
+	if (out != NULL)
+		{
+		l2c(tout0,out);
+		l2c(tout1,out);
+		}
+	tout0=tin0=tin1=tin[0]=tin[1]=0;
+	/*
+	  Transform the data in tout1 so that it will
+	  match the return value that the MIT Kerberos
+	  mit_des_cbc_cksum API returns.
+	*/
+	tout1 = ((tout1 >> 24L) & 0x000000FF)
+	      | ((tout1 >> 8L)  & 0x0000FF00)
+	      | ((tout1 << 8L)  & 0x00FF0000)
+	      | ((tout1 << 24L) & 0xFF000000);
+	return(tout1);
+	}
diff --git a/crypto/libressl/crypto/des/cbc_enc.c b/crypto/libressl/crypto/des/cbc_enc.c
new file mode 100644
index 0000000000..83e8af3a32
--- /dev/null
+++ b/crypto/libressl/crypto/des/cbc_enc.c
@@ -0,0 +1,61 @@
+/* $OpenBSD$ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#define CBC_ENC_C__DONT_UPDATE_IV
+
+#include "ncbc_enc.c" /* des_cbc_encrypt */
diff --git a/crypto/libressl/crypto/des/cfb64ede.c b/crypto/libressl/crypto/des/cfb64ede.c
new file mode 100644
index 0000000000..09a096ce5d
--- /dev/null
+++ b/crypto/libressl/crypto/des/cfb64ede.c
@@ -0,0 +1,244 @@
+/* $OpenBSD: cfb64ede.c,v 1.8 2014/10/28 07:35:58 jsg Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+/* The input and output encrypted as though 64bit cfb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+
+void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+			    long length, DES_key_schedule *ks1,
+			    DES_key_schedule *ks2, DES_key_schedule *ks3,
+			    DES_cblock *ivec, int *num, int enc)
+	{
+	DES_LONG v0,v1;
+	long l=length;
+	int n= *num;
+	DES_LONG ti[2];
+	unsigned char *iv,c,cc;
+
+	iv=&(*ivec)[0];
+	if (enc)
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				c2l(iv,v0);
+				c2l(iv,v1);
+
+				ti[0]=v0;
+				ti[1]=v1;
+				DES_encrypt3(ti,ks1,ks2,ks3);
+				v0=ti[0];
+				v1=ti[1];
+
+				iv = &(*ivec)[0];
+				l2c(v0,iv);
+				l2c(v1,iv);
+				iv = &(*ivec)[0];
+				}
+			c= *(in++)^iv[n];
+			*(out++)=c;
+			iv[n]=c;
+			n=(n+1)&0x07;
+			}
+		}
+	else
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				c2l(iv,v0);
+				c2l(iv,v1);
+
+				ti[0]=v0;
+				ti[1]=v1;
+				DES_encrypt3(ti,ks1,ks2,ks3);
+				v0=ti[0];
+				v1=ti[1];
+
+				iv = &(*ivec)[0];
+				l2c(v0,iv);
+				l2c(v1,iv);
+				iv = &(*ivec)[0];
+				}
+			cc= *(in++);
+			c=iv[n];
+			iv[n]=cc;
+			*(out++)=c^cc;
+			n=(n+1)&0x07;
+			}
+		}
+	v0=v1=ti[0]=ti[1]=c=cc=0;
+	*num=n;
+	}
+
+/* This is compatible with the single key CFB-r for DES, even thought that's
+ * not what EVP needs.
+ */
+
+void DES_ede3_cfb_encrypt(const unsigned char *in,unsigned char *out,
+			  int numbits,long length,DES_key_schedule *ks1,
+			  DES_key_schedule *ks2,DES_key_schedule *ks3,
+			  DES_cblock *ivec,int enc)
+	{
+	DES_LONG d0,d1,v0,v1;
+	unsigned long l=length,n=((unsigned int)numbits+7)/8;
+	int num=numbits,i;
+	DES_LONG ti[2];
+	unsigned char *iv;
+	unsigned char ovec[16];
+
+	if (num > 64) return;
+	iv = &(*ivec)[0];
+	c2l(iv,v0);
+	c2l(iv,v1);
+	if (enc)
+		{
+		while (l >= n)
+			{
+			l-=n;
+			ti[0]=v0;
+			ti[1]=v1;
+			DES_encrypt3(ti,ks1,ks2,ks3);
+			c2ln(in,d0,d1,n);
+			in+=n;
+			d0^=ti[0];
+			d1^=ti[1];
+			l2cn(d0,d1,out,n);
+			out+=n;
+			/* 30-08-94 - eay - changed because l>>32 and
+			 * l<<32 are bad under gcc :-( */
+			if (num == 32)
+				{ v0=v1; v1=d0; }
+			else if (num == 64)
+				{ v0=d0; v1=d1; }
+			else
+				{
+				iv=&ovec[0];
+				l2c(v0,iv);
+				l2c(v1,iv);
+				l2c(d0,iv);
+				l2c(d1,iv);
+				/* shift ovec left most of the bits... */
+				memmove(ovec,ovec+num/8,8+(num%8 ? 1 : 0));
+				/* now the remaining bits */
+				if(num%8 != 0)
+					for(i=0 ; i < 8 ; ++i)
+						{
+						ovec[i]<<=num%8;
+						ovec[i]|=ovec[i+1]>>(8-num%8);
+						}
+				iv=&ovec[0];
+				c2l(iv,v0);
+				c2l(iv,v1);
+				}
+			}
+		}
+	else
+		{
+		while (l >= n)
+			{
+			l-=n;
+			ti[0]=v0;
+			ti[1]=v1;
+			DES_encrypt3(ti,ks1,ks2,ks3);
+			c2ln(in,d0,d1,n);
+			in+=n;
+			/* 30-08-94 - eay - changed because l>>32 and
+			 * l<<32 are bad under gcc :-( */
+			if (num == 32)
+				{ v0=v1; v1=d0; }
+			else if (num == 64)
+				{ v0=d0; v1=d1; }
+			else
+				{
+				iv=&ovec[0];
+				l2c(v0,iv);
+				l2c(v1,iv);
+				l2c(d0,iv);
+				l2c(d1,iv);
+				/* shift ovec left most of the bits... */
+				memmove(ovec,ovec+num/8,8+(num%8 ? 1 : 0));
+				/* now the remaining bits */
+				if(num%8 != 0)
+					for(i=0 ; i < 8 ; ++i)
+						{
+						ovec[i]<<=num%8;
+						ovec[i]|=ovec[i+1]>>(8-num%8);
+						}
+				iv=&ovec[0];
+				c2l(iv,v0);
+				c2l(iv,v1);
+				}
+			d0^=ti[0];
+			d1^=ti[1];
+			l2cn(d0,d1,out,n);
+			out+=n;
+			}
+		}
+	iv = &(*ivec)[0];
+	l2c(v0,iv);
+	l2c(v1,iv);
+	v0=v1=d0=d1=ti[0]=ti[1]=0;
+	}
+
diff --git a/crypto/libressl/crypto/des/cfb64enc.c b/crypto/libressl/crypto/des/cfb64enc.c
new file mode 100644
index 0000000000..c6c3b39212
--- /dev/null
+++ b/crypto/libressl/crypto/des/cfb64enc.c
@@ -0,0 +1,121 @@
+/* $OpenBSD: cfb64enc.c,v 1.5 2014/06/12 15:49:28 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+/* The input and output encrypted as though 64bit cfb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+
+void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+		       long length, DES_key_schedule *schedule,
+		       DES_cblock *ivec, int *num, int enc)
+	{
+	DES_LONG v0,v1;
+	long l=length;
+	int n= *num;
+	DES_LONG ti[2];
+	unsigned char *iv,c,cc;
+
+	iv = &(*ivec)[0];
+	if (enc)
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				c2l(iv,v0); ti[0]=v0;
+				c2l(iv,v1); ti[1]=v1;
+				DES_encrypt1(ti,schedule,DES_ENCRYPT);
+				iv = &(*ivec)[0];
+				v0=ti[0]; l2c(v0,iv);
+				v0=ti[1]; l2c(v0,iv);
+				iv = &(*ivec)[0];
+				}
+			c= *(in++)^iv[n];
+			*(out++)=c;
+			iv[n]=c;
+			n=(n+1)&0x07;
+			}
+		}
+	else
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				c2l(iv,v0); ti[0]=v0;
+				c2l(iv,v1); ti[1]=v1;
+				DES_encrypt1(ti,schedule,DES_ENCRYPT);
+				iv = &(*ivec)[0];
+				v0=ti[0]; l2c(v0,iv);
+				v0=ti[1]; l2c(v0,iv);
+				iv = &(*ivec)[0];
+				}
+			cc= *(in++);
+			c=iv[n];
+			iv[n]=cc;
+			*(out++)=c^cc;
+			n=(n+1)&0x07;
+			}
+		}
+	v0=v1=ti[0]=ti[1]=c=cc=0;
+	*num=n;
+	}
+
diff --git a/crypto/libressl/crypto/des/cfb_enc.c b/crypto/libressl/crypto/des/cfb_enc.c
new file mode 100644
index 0000000000..f2cc45f601
--- /dev/null
+++ b/crypto/libressl/crypto/des/cfb_enc.c
@@ -0,0 +1,189 @@
+/* $OpenBSD: cfb_enc.c,v 1.12 2014/10/28 07:35:58 jsg Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+#include 
+
+/* The input and output are loaded in multiples of 8 bits.
+ * What this means is that if you hame numbits=12 and length=2
+ * the first 12 bits will be retrieved from the first byte and half
+ * the second.  The second 12 bits will come from the 3rd and half the 4th
+ * byte.
+ */
+/* Until Aug 1 2003 this function did not correctly implement CFB-r, so it
+ * will not be compatible with any encryption prior to that date. Ben. */
+void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
+		     long length, DES_key_schedule *schedule, DES_cblock *ivec,
+		     int enc)
+	{
+	DES_LONG d0,d1,v0,v1;
+	unsigned long l=length;
+	int num=numbits/8,n=(numbits+7)/8,i,rem=numbits%8;
+	DES_LONG ti[2];
+	unsigned char *iv;
+#if BYTE_ORDER != LITTLE_ENDIAN
+	unsigned char ovec[16];
+#else
+	unsigned int  sh[4];
+	unsigned char *ovec=(unsigned char *)sh;
+#endif
+
+	if (numbits<=0 || numbits > 64) return;
+	iv = &(*ivec)[0];
+	c2l(iv,v0);
+	c2l(iv,v1);
+	if (enc)
+		{
+		while (l >= (unsigned long)n)
+			{
+			l-=n;
+			ti[0]=v0;
+			ti[1]=v1;
+			DES_encrypt1((DES_LONG *)ti,schedule,DES_ENCRYPT);
+			c2ln(in,d0,d1,n);
+			in+=n;
+			d0^=ti[0];
+			d1^=ti[1];
+			l2cn(d0,d1,out,n);
+			out+=n;
+			/* 30-08-94 - eay - changed because l>>32 and
+			 * l<<32 are bad under gcc :-( */
+			if (numbits == 32)
+				{ v0=v1; v1=d0; }
+			else if (numbits == 64)
+				{ v0=d0; v1=d1; }
+			else
+				{
+#if BYTE_ORDER != LITTLE_ENDIAN
+				iv=&ovec[0];
+				l2c(v0,iv);
+				l2c(v1,iv);
+				l2c(d0,iv);
+				l2c(d1,iv);
+#else
+				sh[0]=v0, sh[1]=v1, sh[2]=d0, sh[3]=d1;
+#endif
+				if (rem==0)
+					memmove(ovec,ovec+num,8);
+				else
+					for(i=0 ; i < 8 ; ++i)
+						ovec[i]=ovec[i+num]<>(8-rem);
+#if BYTE_ORDER == LITTLE_ENDIAN
+				v0=sh[0], v1=sh[1];
+#else
+				iv=&ovec[0];
+				c2l(iv,v0);
+				c2l(iv,v1);
+#endif
+				}
+			}
+		}
+	else
+		{
+		while (l >= (unsigned long)n)
+			{
+			l-=n;
+			ti[0]=v0;
+			ti[1]=v1;
+			DES_encrypt1((DES_LONG *)ti,schedule,DES_ENCRYPT);
+			c2ln(in,d0,d1,n);
+			in+=n;
+			/* 30-08-94 - eay - changed because l>>32 and
+			 * l<<32 are bad under gcc :-( */
+			if (numbits == 32)
+				{ v0=v1; v1=d0; }
+			else if (numbits == 64)
+				{ v0=d0; v1=d1; }
+			else
+				{
+#if BYTE_ORDER != LITTLE_ENDIAN
+				iv=&ovec[0];
+				l2c(v0,iv);
+				l2c(v1,iv);
+				l2c(d0,iv);
+				l2c(d1,iv);
+#else
+				sh[0]=v0, sh[1]=v1, sh[2]=d0, sh[3]=d1;
+#endif
+				if (rem==0)
+					memmove(ovec,ovec+num,8);
+				else
+					for(i=0 ; i < 8 ; ++i)
+						ovec[i]=ovec[i+num]<>(8-rem);
+#if BYTE_ORDER == LITTLE_ENDIAN
+				v0=sh[0], v1=sh[1];
+#else
+				iv=&ovec[0];
+				c2l(iv,v0);
+				c2l(iv,v1);
+#endif
+				}
+			d0^=ti[0];
+			d1^=ti[1];
+			l2cn(d0,d1,out,n);
+			out+=n;
+			}
+		}
+	iv = &(*ivec)[0];
+	l2c(v0,iv);
+	l2c(v1,iv);
+	v0=v1=d0=d1=ti[0]=ti[1]=0;
+	}
+
diff --git a/crypto/libressl/crypto/des/des_enc.c b/crypto/libressl/crypto/des/des_enc.c
new file mode 100644
index 0000000000..f218296efe
--- /dev/null
+++ b/crypto/libressl/crypto/des/des_enc.c
@@ -0,0 +1,404 @@
+/* $OpenBSD: des_enc.c,v 1.11 2014/06/12 15:49:28 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+#include "spr.h"
+
+#ifndef OPENBSD_DES_ASM
+
+void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc)
+	{
+	DES_LONG l,r,t,u;
+#ifdef DES_PTR
+	const unsigned char *des_SP=(const unsigned char *)DES_SPtrans;
+#endif
+#ifndef DES_UNROLL
+	int i;
+#endif
+	DES_LONG *s;
+
+	r=data[0];
+	l=data[1];
+
+	IP(r,l);
+	/* Things have been modified so that the initial rotate is
+	 * done outside the loop.  This required the
+	 * DES_SPtrans values in sp.h to be rotated 1 bit to the right.
+	 * One perl script later and things have a 5% speed up on a sparc2.
+	 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
+	 * for pointing this out. */
+	/* clear the top bits on machines with 8byte longs */
+	/* shift left by 2 */
+	r=ROTATE(r,29)&0xffffffffL;
+	l=ROTATE(l,29)&0xffffffffL;
+
+	s=ks->ks->deslong;
+	/* I don't know if it is worth the effort of loop unrolling the
+	 * inner loop */
+	if (enc)
+		{
+#ifdef DES_UNROLL
+		D_ENCRYPT(l,r, 0); /*  1 */
+		D_ENCRYPT(r,l, 2); /*  2 */
+		D_ENCRYPT(l,r, 4); /*  3 */
+		D_ENCRYPT(r,l, 6); /*  4 */
+		D_ENCRYPT(l,r, 8); /*  5 */
+		D_ENCRYPT(r,l,10); /*  6 */
+		D_ENCRYPT(l,r,12); /*  7 */
+		D_ENCRYPT(r,l,14); /*  8 */
+		D_ENCRYPT(l,r,16); /*  9 */
+		D_ENCRYPT(r,l,18); /*  10 */
+		D_ENCRYPT(l,r,20); /*  11 */
+		D_ENCRYPT(r,l,22); /*  12 */
+		D_ENCRYPT(l,r,24); /*  13 */
+		D_ENCRYPT(r,l,26); /*  14 */
+		D_ENCRYPT(l,r,28); /*  15 */
+		D_ENCRYPT(r,l,30); /*  16 */
+#else
+		for (i=0; i<32; i+=4)
+			{
+			D_ENCRYPT(l,r,i+0); /*  1 */
+			D_ENCRYPT(r,l,i+2); /*  2 */
+			}
+#endif
+		}
+	else
+		{
+#ifdef DES_UNROLL
+		D_ENCRYPT(l,r,30); /* 16 */
+		D_ENCRYPT(r,l,28); /* 15 */
+		D_ENCRYPT(l,r,26); /* 14 */
+		D_ENCRYPT(r,l,24); /* 13 */
+		D_ENCRYPT(l,r,22); /* 12 */
+		D_ENCRYPT(r,l,20); /* 11 */
+		D_ENCRYPT(l,r,18); /* 10 */
+		D_ENCRYPT(r,l,16); /*  9 */
+		D_ENCRYPT(l,r,14); /*  8 */
+		D_ENCRYPT(r,l,12); /*  7 */
+		D_ENCRYPT(l,r,10); /*  6 */
+		D_ENCRYPT(r,l, 8); /*  5 */
+		D_ENCRYPT(l,r, 6); /*  4 */
+		D_ENCRYPT(r,l, 4); /*  3 */
+		D_ENCRYPT(l,r, 2); /*  2 */
+		D_ENCRYPT(r,l, 0); /*  1 */
+#else
+		for (i=30; i>0; i-=4)
+			{
+			D_ENCRYPT(l,r,i-0); /* 16 */
+			D_ENCRYPT(r,l,i-2); /* 15 */
+			}
+#endif
+		}
+
+	/* rotate and clear the top bits on machines with 8byte longs */
+	l=ROTATE(l,3)&0xffffffffL;
+	r=ROTATE(r,3)&0xffffffffL;
+
+	FP(r,l);
+	data[0]=l;
+	data[1]=r;
+	l=r=t=u=0;
+	}
+
+void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc)
+	{
+	DES_LONG l,r,t,u;
+#ifdef DES_PTR
+	const unsigned char *des_SP=(const unsigned char *)DES_SPtrans;
+#endif
+#ifndef DES_UNROLL
+	int i;
+#endif
+	DES_LONG *s;
+
+	r=data[0];
+	l=data[1];
+
+	/* Things have been modified so that the initial rotate is
+	 * done outside the loop.  This required the
+	 * DES_SPtrans values in sp.h to be rotated 1 bit to the right.
+	 * One perl script later and things have a 5% speed up on a sparc2.
+	 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
+	 * for pointing this out. */
+	/* clear the top bits on machines with 8byte longs */
+	r=ROTATE(r,29)&0xffffffffL;
+	l=ROTATE(l,29)&0xffffffffL;
+
+	s=ks->ks->deslong;
+	/* I don't know if it is worth the effort of loop unrolling the
+	 * inner loop */
+	if (enc)
+		{
+#ifdef DES_UNROLL
+		D_ENCRYPT(l,r, 0); /*  1 */
+		D_ENCRYPT(r,l, 2); /*  2 */
+		D_ENCRYPT(l,r, 4); /*  3 */
+		D_ENCRYPT(r,l, 6); /*  4 */
+		D_ENCRYPT(l,r, 8); /*  5 */
+		D_ENCRYPT(r,l,10); /*  6 */
+		D_ENCRYPT(l,r,12); /*  7 */
+		D_ENCRYPT(r,l,14); /*  8 */
+		D_ENCRYPT(l,r,16); /*  9 */
+		D_ENCRYPT(r,l,18); /*  10 */
+		D_ENCRYPT(l,r,20); /*  11 */
+		D_ENCRYPT(r,l,22); /*  12 */
+		D_ENCRYPT(l,r,24); /*  13 */
+		D_ENCRYPT(r,l,26); /*  14 */
+		D_ENCRYPT(l,r,28); /*  15 */
+		D_ENCRYPT(r,l,30); /*  16 */
+#else
+		for (i=0; i<32; i+=4)
+			{
+			D_ENCRYPT(l,r,i+0); /*  1 */
+			D_ENCRYPT(r,l,i+2); /*  2 */
+			}
+#endif
+		}
+	else
+		{
+#ifdef DES_UNROLL
+		D_ENCRYPT(l,r,30); /* 16 */
+		D_ENCRYPT(r,l,28); /* 15 */
+		D_ENCRYPT(l,r,26); /* 14 */
+		D_ENCRYPT(r,l,24); /* 13 */
+		D_ENCRYPT(l,r,22); /* 12 */
+		D_ENCRYPT(r,l,20); /* 11 */
+		D_ENCRYPT(l,r,18); /* 10 */
+		D_ENCRYPT(r,l,16); /*  9 */
+		D_ENCRYPT(l,r,14); /*  8 */
+		D_ENCRYPT(r,l,12); /*  7 */
+		D_ENCRYPT(l,r,10); /*  6 */
+		D_ENCRYPT(r,l, 8); /*  5 */
+		D_ENCRYPT(l,r, 6); /*  4 */
+		D_ENCRYPT(r,l, 4); /*  3 */
+		D_ENCRYPT(l,r, 2); /*  2 */
+		D_ENCRYPT(r,l, 0); /*  1 */
+#else
+		for (i=30; i>0; i-=4)
+			{
+			D_ENCRYPT(l,r,i-0); /* 16 */
+			D_ENCRYPT(r,l,i-2); /* 15 */
+			}
+#endif
+		}
+	/* rotate and clear the top bits on machines with 8byte longs */
+	data[0]=ROTATE(l,3)&0xffffffffL;
+	data[1]=ROTATE(r,3)&0xffffffffL;
+	l=r=t=u=0;
+	}
+
+#endif /* OPENBSD_DES_ASM */
+
+void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
+		  DES_key_schedule *ks2, DES_key_schedule *ks3)
+	{
+	DES_LONG l,r;
+
+	l=data[0];
+	r=data[1];
+	IP(l,r);
+	data[0]=l;
+	data[1]=r;
+	DES_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
+	DES_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
+	DES_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
+	l=data[0];
+	r=data[1];
+	FP(r,l);
+	data[0]=l;
+	data[1]=r;
+	}
+
+void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
+		  DES_key_schedule *ks2, DES_key_schedule *ks3)
+	{
+	DES_LONG l,r;
+
+	l=data[0];
+	r=data[1];
+	IP(l,r);
+	data[0]=l;
+	data[1]=r;
+	DES_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
+	DES_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
+	DES_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
+	l=data[0];
+	r=data[1];
+	FP(r,l);
+	data[0]=l;
+	data[1]=r;
+	}
+
+#ifndef DES_DEFAULT_OPTIONS
+
+#undef CBC_ENC_C__DONT_UPDATE_IV
+#include "ncbc_enc.c" /* DES_ncbc_encrypt */
+
+void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
+			  long length, DES_key_schedule *ks1,
+			  DES_key_schedule *ks2, DES_key_schedule *ks3,
+			  DES_cblock *ivec, int enc)
+	{
+	DES_LONG tin0,tin1;
+	DES_LONG tout0,tout1,xor0,xor1;
+	const unsigned char *in;
+	unsigned char *out;
+	long l=length;
+	DES_LONG tin[2];
+	unsigned char *iv;
+
+	in=input;
+	out=output;
+	iv = &(*ivec)[0];
+
+	if (enc)
+		{
+		c2l(iv,tout0);
+		c2l(iv,tout1);
+		for (l-=8; l>=0; l-=8)
+			{
+			c2l(in,tin0);
+			c2l(in,tin1);
+			tin0^=tout0;
+			tin1^=tout1;
+
+			tin[0]=tin0;
+			tin[1]=tin1;
+			DES_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
+			tout0=tin[0];
+			tout1=tin[1];
+
+			l2c(tout0,out);
+			l2c(tout1,out);
+			}
+		if (l != -8)
+			{
+			c2ln(in,tin0,tin1,l+8);
+			tin0^=tout0;
+			tin1^=tout1;
+
+			tin[0]=tin0;
+			tin[1]=tin1;
+			DES_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
+			tout0=tin[0];
+			tout1=tin[1];
+
+			l2c(tout0,out);
+			l2c(tout1,out);
+			}
+		iv = &(*ivec)[0];
+		l2c(tout0,iv);
+		l2c(tout1,iv);
+		}
+	else
+		{
+		DES_LONG t0,t1;
+
+		c2l(iv,xor0);
+		c2l(iv,xor1);
+		for (l-=8; l>=0; l-=8)
+			{
+			c2l(in,tin0);
+			c2l(in,tin1);
+
+			t0=tin0;
+			t1=tin1;
+
+			tin[0]=tin0;
+			tin[1]=tin1;
+			DES_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
+			tout0=tin[0];
+			tout1=tin[1];
+
+			tout0^=xor0;
+			tout1^=xor1;
+			l2c(tout0,out);
+			l2c(tout1,out);
+			xor0=t0;
+			xor1=t1;
+			}
+		if (l != -8)
+			{
+			c2l(in,tin0);
+			c2l(in,tin1);
+			
+			t0=tin0;
+			t1=tin1;
+
+			tin[0]=tin0;
+			tin[1]=tin1;
+			DES_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
+			tout0=tin[0];
+			tout1=tin[1];
+		
+			tout0^=xor0;
+			tout1^=xor1;
+			l2cn(tout0,tout1,out,l+8);
+			xor0=t0;
+			xor1=t1;
+			}
+
+		iv = &(*ivec)[0];
+		l2c(xor0,iv);
+		l2c(xor1,iv);
+		}
+	tin0=tin1=tout0=tout1=xor0=xor1=0;
+	tin[0]=tin[1]=0;
+	}
+
+#endif /* DES_DEFAULT_OPTIONS */
diff --git a/crypto/libressl/crypto/des/des_locl.h b/crypto/libressl/crypto/des/des_locl.h
new file mode 100644
index 0000000000..a5e3439ab7
--- /dev/null
+++ b/crypto/libressl/crypto/des/des_locl.h
@@ -0,0 +1,392 @@
+/* $OpenBSD: des_locl.h,v 1.17 2014/08/18 19:15:34 bcook Exp $ */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_DES_LOCL_H
+#define HEADER_DES_LOCL_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+
+#define ITERATIONS 16
+#define HALF_ITERATIONS 8
+
+/* used in des_read and des_write */
+#define MAXWRITE	(1024*16)
+#define BSIZE		(MAXWRITE+4)
+
+#define c2l(c,l)	(l =((DES_LONG)(*((c)++)))    , \
+			 l|=((DES_LONG)(*((c)++)))<< 8L, \
+			 l|=((DES_LONG)(*((c)++)))<<16L, \
+			 l|=((DES_LONG)(*((c)++)))<<24L)
+
+/* NOTE - c is not incremented as per c2l */
+#define c2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
+			case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
+			case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
+			case 5: l2|=((DES_LONG)(*(--(c))));     \
+			case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
+			case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
+			case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
+			case 1: l1|=((DES_LONG)(*(--(c))));     \
+				} \
+			}
+
+#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+/* replacements for htonl and ntohl since I have no idea what to do
+ * when faced with machines with 8 byte longs. */
+#define HDRSIZE 4
+
+#define n2l(c,l)	(l =((DES_LONG)(*((c)++)))<<24L, \
+			 l|=((DES_LONG)(*((c)++)))<<16L, \
+			 l|=((DES_LONG)(*((c)++)))<< 8L, \
+			 l|=((DES_LONG)(*((c)++))))
+
+#define l2n(l,c)	(*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)     )&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+#define l2cn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
+				} \
+			}
+
+static inline uint32_t ROTATE(uint32_t a, uint32_t n)
+{
+	return (a>>n)+(a<<(32-n));
+}
+
+/* Don't worry about the LOAD_DATA() stuff, that is used by
+ * fcrypt() to add it's little bit to the front */
+
+#ifdef DES_FCRYPT
+
+#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
+	{ DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
+
+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
+	t=R^(R>>16L); \
+	u=t&E0; t&=E1; \
+	tmp=(u<<16); u^=R^s[S  ]; u^=tmp; \
+	tmp=(t<<16); t^=R^s[S+1]; t^=tmp
+#else
+#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
+	u=R^s[S  ]; \
+	t=R^s[S+1]
+#endif
+
+/* The changes to this macro may help or hinder, depending on the
+ * compiler and the architecture.  gcc2 always seems to do well :-).
+ * Inspired by Dana How 
+ * DO NOT use the alternative version on machines with 8 byte longs.
+ * It does not seem to work on the Alpha, even when DES_LONG is 4
+ * bytes, probably an issue of accessing non-word aligned objects :-( */
+#ifdef DES_PTR
+
+/* It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there
+ * is no reason to not xor all the sub items together.  This potentially
+ * saves a register since things can be xored directly into L */
+
+#if defined(DES_RISC1) || defined(DES_RISC2)
+#ifdef DES_RISC1
+#define D_ENCRYPT(LL,R,S) { \
+	unsigned int u1,u2,u3; \
+	LOAD_DATA(R,S,u,t,E0,E1,u1); \
+	u2=(int)u>>8L; \
+	u1=(int)u&0xfc; \
+	u2&=0xfc; \
+	t=ROTATE(t,4); \
+	u>>=16L; \
+	LL^= *(const DES_LONG *)(des_SP      +u1); \
+	LL^= *(const DES_LONG *)(des_SP+0x200+u2); \
+	u3=(int)(u>>8L); \
+	u1=(int)u&0xfc; \
+	u3&=0xfc; \
+	LL^= *(const DES_LONG *)(des_SP+0x400+u1); \
+	LL^= *(const DES_LONG *)(des_SP+0x600+u3); \
+	u2=(int)t>>8L; \
+	u1=(int)t&0xfc; \
+	u2&=0xfc; \
+	t>>=16L; \
+	LL^= *(const DES_LONG *)(des_SP+0x100+u1); \
+	LL^= *(const DES_LONG *)(des_SP+0x300+u2); \
+	u3=(int)t>>8L; \
+	u1=(int)t&0xfc; \
+	u3&=0xfc; \
+	LL^= *(const DES_LONG *)(des_SP+0x500+u1); \
+	LL^= *(const DES_LONG *)(des_SP+0x700+u3); }
+#endif
+#ifdef DES_RISC2
+#define D_ENCRYPT(LL,R,S) { \
+	unsigned int u1,u2,s1,s2; \
+	LOAD_DATA(R,S,u,t,E0,E1,u1); \
+	u2=(int)u>>8L; \
+	u1=(int)u&0xfc; \
+	u2&=0xfc; \
+	t=ROTATE(t,4); \
+	LL^= *(const DES_LONG *)(des_SP      +u1); \
+	LL^= *(const DES_LONG *)(des_SP+0x200+u2); \
+	s1=(int)(u>>16L); \
+	s2=(int)(u>>24L); \
+	s1&=0xfc; \
+	s2&=0xfc; \
+	LL^= *(const DES_LONG *)(des_SP+0x400+s1); \
+	LL^= *(const DES_LONG *)(des_SP+0x600+s2); \
+	u2=(int)t>>8L; \
+	u1=(int)t&0xfc; \
+	u2&=0xfc; \
+	LL^= *(const DES_LONG *)(des_SP+0x100+u1); \
+	LL^= *(const DES_LONG *)(des_SP+0x300+u2); \
+	s1=(int)(t>>16L); \
+	s2=(int)(t>>24L); \
+	s1&=0xfc; \
+	s2&=0xfc; \
+	LL^= *(const DES_LONG *)(des_SP+0x500+s1); \
+	LL^= *(const DES_LONG *)(des_SP+0x700+s2); }
+#endif
+#else
+#define D_ENCRYPT(LL,R,S) { \
+	LOAD_DATA_tmp(R,S,u,t,E0,E1); \
+	t=ROTATE(t,4); \
+	LL^= \
+	*(const DES_LONG *)(des_SP      +((u     )&0xfc))^ \
+	*(const DES_LONG *)(des_SP+0x200+((u>> 8L)&0xfc))^ \
+	*(const DES_LONG *)(des_SP+0x400+((u>>16L)&0xfc))^ \
+	*(const DES_LONG *)(des_SP+0x600+((u>>24L)&0xfc))^ \
+	*(const DES_LONG *)(des_SP+0x100+((t     )&0xfc))^ \
+	*(const DES_LONG *)(des_SP+0x300+((t>> 8L)&0xfc))^ \
+	*(const DES_LONG *)(des_SP+0x500+((t>>16L)&0xfc))^ \
+	*(const DES_LONG *)(des_SP+0x700+((t>>24L)&0xfc)); }
+#endif
+
+#else /* original version */
+
+#if defined(DES_RISC1) || defined(DES_RISC2)
+#ifdef DES_RISC1
+#define D_ENCRYPT(LL,R,S) {\
+	unsigned int u1,u2,u3; \
+	LOAD_DATA(R,S,u,t,E0,E1,u1); \
+	u>>=2L; \
+	t=ROTATE(t,6); \
+	u2=(int)u>>8L; \
+	u1=(int)u&0x3f; \
+	u2&=0x3f; \
+	u>>=16L; \
+	LL^=DES_SPtrans[0][u1]; \
+	LL^=DES_SPtrans[2][u2]; \
+	u3=(int)u>>8L; \
+	u1=(int)u&0x3f; \
+	u3&=0x3f; \
+	LL^=DES_SPtrans[4][u1]; \
+	LL^=DES_SPtrans[6][u3]; \
+	u2=(int)t>>8L; \
+	u1=(int)t&0x3f; \
+	u2&=0x3f; \
+	t>>=16L; \
+	LL^=DES_SPtrans[1][u1]; \
+	LL^=DES_SPtrans[3][u2]; \
+	u3=(int)t>>8L; \
+	u1=(int)t&0x3f; \
+	u3&=0x3f; \
+	LL^=DES_SPtrans[5][u1]; \
+	LL^=DES_SPtrans[7][u3]; }
+#endif
+#ifdef DES_RISC2
+#define D_ENCRYPT(LL,R,S) {\
+	unsigned int u1,u2,s1,s2; \
+	LOAD_DATA(R,S,u,t,E0,E1,u1); \
+	u>>=2L; \
+	t=ROTATE(t,6); \
+	u2=(int)u>>8L; \
+	u1=(int)u&0x3f; \
+	u2&=0x3f; \
+	LL^=DES_SPtrans[0][u1]; \
+	LL^=DES_SPtrans[2][u2]; \
+	s1=(int)u>>16L; \
+	s2=(int)u>>24L; \
+	s1&=0x3f; \
+	s2&=0x3f; \
+	LL^=DES_SPtrans[4][s1]; \
+	LL^=DES_SPtrans[6][s2]; \
+	u2=(int)t>>8L; \
+	u1=(int)t&0x3f; \
+	u2&=0x3f; \
+	LL^=DES_SPtrans[1][u1]; \
+	LL^=DES_SPtrans[3][u2]; \
+	s1=(int)t>>16; \
+	s2=(int)t>>24L; \
+	s1&=0x3f; \
+	s2&=0x3f; \
+	LL^=DES_SPtrans[5][s1]; \
+	LL^=DES_SPtrans[7][s2]; }
+#endif
+
+#else
+
+#define D_ENCRYPT(LL,R,S) {\
+	LOAD_DATA_tmp(R,S,u,t,E0,E1); \
+	t=ROTATE(t,4); \
+	LL^=\
+		DES_SPtrans[0][(u>> 2L)&0x3f]^ \
+		DES_SPtrans[2][(u>>10L)&0x3f]^ \
+		DES_SPtrans[4][(u>>18L)&0x3f]^ \
+		DES_SPtrans[6][(u>>26L)&0x3f]^ \
+		DES_SPtrans[1][(t>> 2L)&0x3f]^ \
+		DES_SPtrans[3][(t>>10L)&0x3f]^ \
+		DES_SPtrans[5][(t>>18L)&0x3f]^ \
+		DES_SPtrans[7][(t>>26L)&0x3f]; }
+#endif
+#endif
+
+	/* IP and FP
+	 * The problem is more of a geometric problem that random bit fiddling.
+	 0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6
+	 8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4
+	16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2
+	24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0
+
+	32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7
+	40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5
+	48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3
+	56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1
+
+	The output has been subject to swaps of the form
+	0 1 -> 3 1 but the odd and even bits have been put into
+	2 3    2 0
+	different words.  The main trick is to remember that
+	t=((l>>size)^r)&(mask);
+	r^=t;
+	l^=(t<>(n))^(b))&(m)),\
+	(b)^=(t),\
+	(a)^=((t)<<(n)))
+
+#define IP(l,r) \
+	{ \
+	DES_LONG tt; \
+	PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
+	PERM_OP(l,r,tt,16,0x0000ffffL); \
+	PERM_OP(r,l,tt, 2,0x33333333L); \
+	PERM_OP(l,r,tt, 8,0x00ff00ffL); \
+	PERM_OP(r,l,tt, 1,0x55555555L); \
+	}
+
+#define FP(l,r) \
+	{ \
+	DES_LONG tt; \
+	PERM_OP(l,r,tt, 1,0x55555555L); \
+	PERM_OP(r,l,tt, 8,0x00ff00ffL); \
+	PERM_OP(l,r,tt, 2,0x33333333L); \
+	PERM_OP(r,l,tt,16,0x0000ffffL); \
+	PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
+	}
+
+extern const DES_LONG DES_SPtrans[8][64];
+
+void fcrypt_body(DES_LONG *out,DES_key_schedule *ks,
+		 DES_LONG Eswap0, DES_LONG Eswap1);
+
+#ifdef OPENSSL_SMALL_FOOTPRINT
+#undef DES_UNROLL
+#endif
+#endif
diff --git a/crypto/libressl/crypto/des/ecb3_enc.c b/crypto/libressl/crypto/des/ecb3_enc.c
new file mode 100644
index 0000000000..dde41106a6
--- /dev/null
+++ b/crypto/libressl/crypto/des/ecb3_enc.c
@@ -0,0 +1,83 @@
+/* $OpenBSD: ecb3_enc.c,v 1.6 2014/06/12 15:49:28 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
+		      DES_key_schedule *ks1, DES_key_schedule *ks2,
+		      DES_key_schedule *ks3,
+	     int enc)
+	{
+	DES_LONG l0,l1;
+	DES_LONG ll[2];
+	const unsigned char *in = &(*input)[0];
+	unsigned char *out = &(*output)[0];
+
+	c2l(in,l0);
+	c2l(in,l1);
+	ll[0]=l0;
+	ll[1]=l1;
+	if (enc)
+		DES_encrypt3(ll,ks1,ks2,ks3);
+	else
+		DES_decrypt3(ll,ks1,ks2,ks3);
+	l0=ll[0];
+	l1=ll[1];
+	l2c(l0,out);
+	l2c(l1,out);
+	}
diff --git a/crypto/libressl/crypto/des/ecb_enc.c b/crypto/libressl/crypto/des/ecb_enc.c
new file mode 100644
index 0000000000..14238c2ebd
--- /dev/null
+++ b/crypto/libressl/crypto/des/ecb_enc.c
@@ -0,0 +1,118 @@
+/* $OpenBSD: ecb_enc.c,v 1.15 2014/07/09 11:10:50 bcook Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+#include 
+#include 
+
+const char *DES_options(void)
+	{
+	static int init=1;
+	static char buf[32];
+
+	if (init)
+		{
+		const char *ptr,*unroll,*risc,*size;
+
+#ifdef DES_PTR
+		ptr="ptr";
+#else
+		ptr="idx";
+#endif
+#if defined(DES_RISC1) || defined(DES_RISC2)
+#ifdef DES_RISC1
+		risc="risc1";
+#endif
+#ifdef DES_RISC2
+		risc="risc2";
+#endif
+#else
+		risc="cisc";
+#endif
+#ifdef DES_UNROLL
+		unroll="16";
+#else
+		unroll="2";
+#endif
+		if (sizeof(DES_LONG) != sizeof(long))
+			size="int";
+		else
+			size="long";
+		snprintf(buf,sizeof buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,
+			     size);
+		init=0;
+		}
+	return(buf);
+	}
+		
+
+void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output,
+		     DES_key_schedule *ks, int enc)
+	{
+	DES_LONG l;
+	DES_LONG ll[2];
+	const unsigned char *in = &(*input)[0];
+	unsigned char *out = &(*output)[0];
+
+	c2l(in,l); ll[0]=l;
+	c2l(in,l); ll[1]=l;
+	DES_encrypt1(ll,ks,enc);
+	l=ll[0]; l2c(l,out);
+	l=ll[1]; l2c(l,out);
+	l=ll[0]=ll[1]=0;
+	}
diff --git a/crypto/libressl/crypto/des/ede_cbcm_enc.c b/crypto/libressl/crypto/des/ede_cbcm_enc.c
new file mode 100644
index 0000000000..e242363a95
--- /dev/null
+++ b/crypto/libressl/crypto/des/ede_cbcm_enc.c
@@ -0,0 +1,199 @@
+/* $OpenBSD: ede_cbcm_enc.c,v 1.5 2014/06/12 15:49:28 deraadt Exp $ */
+/* Written by Ben Laurie  for the OpenSSL
+ * project 13 Feb 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/*
+
+This is an implementation of Triple DES Cipher Block Chaining with Output
+Feedback Masking, by Coppersmith, Johnson and Matyas, (IBM and Certicom).
+
+Note that there is a known attack on this by Biham and Knudsen but it takes
+a lot of work:
+
+http://www.cs.technion.ac.il/users/wwwb/cgi-bin/tr-get.cgi/1998/CS/CS0928.ps.gz
+
+*/
+
+#include  /* To see if OPENSSL_NO_DESCBCM is defined */
+
+#ifndef OPENSSL_NO_DESCBCM
+#include "des_locl.h"
+
+void DES_ede3_cbcm_encrypt(const unsigned char *in, unsigned char *out,
+	     long length, DES_key_schedule *ks1, DES_key_schedule *ks2,
+	     DES_key_schedule *ks3, DES_cblock *ivec1, DES_cblock *ivec2,
+	     int enc)
+    {
+    DES_LONG tin0,tin1;
+    DES_LONG tout0,tout1,xor0,xor1,m0,m1;
+    long l=length;
+    DES_LONG tin[2];
+    unsigned char *iv1,*iv2;
+
+    iv1 = &(*ivec1)[0];
+    iv2 = &(*ivec2)[0];
+
+    if (enc)
+	{
+	c2l(iv1,m0);
+	c2l(iv1,m1);
+	c2l(iv2,tout0);
+	c2l(iv2,tout1);
+	for (l-=8; l>=-7; l-=8)
+	    {
+	    tin[0]=m0;
+	    tin[1]=m1;
+	    DES_encrypt1(tin,ks3,1);
+	    m0=tin[0];
+	    m1=tin[1];
+
+	    if(l < 0)
+		{
+		c2ln(in,tin0,tin1,l+8);
+		}
+	    else
+		{
+		c2l(in,tin0);
+		c2l(in,tin1);
+		}
+	    tin0^=tout0;
+	    tin1^=tout1;
+
+	    tin[0]=tin0;
+	    tin[1]=tin1;
+	    DES_encrypt1(tin,ks1,1);
+	    tin[0]^=m0;
+	    tin[1]^=m1;
+	    DES_encrypt1(tin,ks2,0);
+	    tin[0]^=m0;
+	    tin[1]^=m1;
+	    DES_encrypt1(tin,ks1,1);
+	    tout0=tin[0];
+	    tout1=tin[1];
+
+	    l2c(tout0,out);
+	    l2c(tout1,out);
+	    }
+	iv1=&(*ivec1)[0];
+	l2c(m0,iv1);
+	l2c(m1,iv1);
+
+	iv2=&(*ivec2)[0];
+	l2c(tout0,iv2);
+	l2c(tout1,iv2);
+	}
+    else
+	{
+	DES_LONG t0,t1;
+
+	c2l(iv1,m0);
+	c2l(iv1,m1);
+	c2l(iv2,xor0);
+	c2l(iv2,xor1);
+	for (l-=8; l>=-7; l-=8)
+	    {
+	    tin[0]=m0;
+	    tin[1]=m1;
+	    DES_encrypt1(tin,ks3,1);
+	    m0=tin[0];
+	    m1=tin[1];
+
+	    c2l(in,tin0);
+	    c2l(in,tin1);
+
+	    t0=tin0;
+	    t1=tin1;
+
+	    tin[0]=tin0;
+	    tin[1]=tin1;
+	    DES_encrypt1(tin,ks1,0);
+	    tin[0]^=m0;
+	    tin[1]^=m1;
+	    DES_encrypt1(tin,ks2,1);
+	    tin[0]^=m0;
+	    tin[1]^=m1;
+	    DES_encrypt1(tin,ks1,0);
+	    tout0=tin[0];
+	    tout1=tin[1];
+
+	    tout0^=xor0;
+	    tout1^=xor1;
+	    if(l < 0)
+		{
+		l2cn(tout0,tout1,out,l+8);
+		}
+	    else
+		{
+		l2c(tout0,out);
+		l2c(tout1,out);
+		}
+	    xor0=t0;
+	    xor1=t1;
+	    }
+
+	iv1=&(*ivec1)[0];
+	l2c(m0,iv1);
+	l2c(m1,iv1);
+
+	iv2=&(*ivec2)[0];
+	l2c(xor0,iv2);
+	l2c(xor1,iv2);
+	}
+    tin0=tin1=tout0=tout1=xor0=xor1=0;
+    tin[0]=tin[1]=0;
+    }
+#endif
diff --git a/crypto/libressl/crypto/des/enc_read.c b/crypto/libressl/crypto/des/enc_read.c
new file mode 100644
index 0000000000..fad2152fe2
--- /dev/null
+++ b/crypto/libressl/crypto/des/enc_read.c
@@ -0,0 +1,229 @@
+/* $OpenBSD: enc_read.c,v 1.14 2014/07/11 08:44:48 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+
+#include "des_locl.h"
+
+/* This has some uglies in it but it works - even over sockets. */
+/*extern int errno;*/
+int DES_rw_mode = DES_PCBC_MODE;
+
+/*
+ * WARNINGS:
+ *
+ *  -  The data format used by DES_enc_write() and DES_enc_read()
+ *     has a cryptographic weakness: When asked to write more
+ *     than MAXWRITE bytes, DES_enc_write will split the data
+ *     into several chunks that are all encrypted
+ *     using the same IV.  So don't use these functions unless you
+ *     are sure you know what you do (in which case you might
+ *     not want to use them anyway).
+ *
+ *  -  This code cannot handle non-blocking sockets.
+ *
+ *  -  This function uses an internal state and thus cannot be
+ *     used on multiple files.
+ */
+
+
+int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched,
+		 DES_cblock *iv)
+	{
+	/* data to be unencrypted */
+	int net_num=0;
+	static unsigned char *net=NULL;
+	/* extra unencrypted data 
+	 * for when a block of 100 comes in but is des_read one byte at
+	 * a time. */
+	static unsigned char *unnet=NULL;
+	static int unnet_start=0;
+	static int unnet_left=0;
+	static unsigned char *tmpbuf=NULL;
+	int i;
+	long num=0,rnum;
+	unsigned char *p;
+
+	if (tmpbuf == NULL)
+		{
+		tmpbuf=malloc(BSIZE);
+		if (tmpbuf == NULL) return(-1);
+		}
+	if (net == NULL)
+		{
+		net=malloc(BSIZE);
+		if (net == NULL) return(-1);
+		}
+	if (unnet == NULL)
+		{
+		unnet=malloc(BSIZE);
+		if (unnet == NULL) return(-1);
+		}
+	/* left over data from last decrypt */
+	if (unnet_left != 0)
+		{
+		if (unnet_left < len)
+			{
+			/* we still still need more data but will return
+			 * with the number of bytes we have - should always
+			 * check the return value */
+			memcpy(buf,&(unnet[unnet_start]),
+			       unnet_left);
+			/* eay 26/08/92 I had the next 2 lines
+			 * reversed :-( */
+			i=unnet_left;
+			unnet_start=unnet_left=0;
+			}
+		else
+			{
+			memcpy(buf,&(unnet[unnet_start]),len);
+			unnet_start+=len;
+			unnet_left-=len;
+			i=len;
+			}
+		return(i);
+		}
+
+	/* We need to get more data. */
+	if (len > MAXWRITE) len=MAXWRITE;
+
+	/* first - get the length */
+	while (net_num < HDRSIZE) 
+		{
+		i=read(fd,(void *)&(net[net_num]),HDRSIZE-net_num);
+#ifdef EINTR
+		if ((i == -1) && (errno == EINTR)) continue;
+#endif
+		if (i <= 0) return(0);
+		net_num+=i;
+		}
+
+	/* we now have at net_num bytes in net */
+	p=net;
+	/* num=0;  */
+	n2l(p,num);
+	/* num should be rounded up to the next group of eight
+	 * we make sure that we have read a multiple of 8 bytes from the net.
+	 */
+	if ((num > MAXWRITE) || (num < 0)) /* error */
+		return(-1);
+	rnum=(num < 8)?8:((num+7)/8*8);
+
+	net_num=0;
+	while (net_num < rnum)
+		{
+		i=read(fd,(void *)&(net[net_num]),rnum-net_num);
+#ifdef EINTR
+		if ((i == -1) && (errno == EINTR)) continue;
+#endif
+		if (i <= 0) return(0);
+		net_num+=i;
+		}
+
+	/* Check if there will be data left over. */
+	if (len < num)
+		{
+		if (DES_rw_mode & DES_PCBC_MODE)
+			DES_pcbc_encrypt(net,unnet,num,sched,iv,DES_DECRYPT);
+		else
+			DES_cbc_encrypt(net,unnet,num,sched,iv,DES_DECRYPT);
+		memcpy(buf,unnet,len);
+		unnet_start=len;
+		unnet_left=num-len;
+
+		/* The following line is done because we return num
+		 * as the number of bytes read. */
+		num=len;
+		}
+	else
+		{
+		/* >output is a multiple of 8 byes, if len < rnum
+		 * >we must be careful.  The user must be aware that this
+		 * >routine will write more bytes than he asked for.
+		 * >The length of the buffer must be correct.
+		 * FIXED - Should be ok now 18-9-90 - eay */
+		if (len < rnum)
+			{
+
+			if (DES_rw_mode & DES_PCBC_MODE)
+				DES_pcbc_encrypt(net,tmpbuf,num,sched,iv,
+						 DES_DECRYPT);
+			else
+				DES_cbc_encrypt(net,tmpbuf,num,sched,iv,
+						DES_DECRYPT);
+
+			/* eay 26/08/92 fix a bug that returned more
+			 * bytes than you asked for (returned len bytes :-( */
+			memcpy(buf,tmpbuf,num);
+			}
+		else
+			{
+			if (DES_rw_mode & DES_PCBC_MODE)
+				DES_pcbc_encrypt(net,buf,num,sched,iv,
+						 DES_DECRYPT);
+			else
+				DES_cbc_encrypt(net,buf,num,sched,iv,
+						DES_DECRYPT);
+			}
+		}
+	return num;
+	}
+
diff --git a/crypto/libressl/crypto/des/enc_writ.c b/crypto/libressl/crypto/des/enc_writ.c
new file mode 100644
index 0000000000..0b69d4c5bf
--- /dev/null
+++ b/crypto/libressl/crypto/des/enc_writ.c
@@ -0,0 +1,173 @@
+/* $OpenBSD: enc_writ.c,v 1.13 2014/10/22 13:02:04 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "des_locl.h"
+
+/*
+ * WARNINGS:
+ *
+ *  -  The data format used by DES_enc_write() and DES_enc_read()
+ *     has a cryptographic weakness: When asked to write more
+ *     than MAXWRITE bytes, DES_enc_write will split the data
+ *     into several chunks that are all encrypted
+ *     using the same IV.  So don't use these functions unless you
+ *     are sure you know what you do (in which case you might
+ *     not want to use them anyway).
+ *
+ *  -  This code cannot handle non-blocking sockets.
+ */
+
+int DES_enc_write(int fd, const void *_buf, int len,
+		  DES_key_schedule *sched, DES_cblock *iv)
+	{
+#ifdef _LIBC
+	extern unsigned long time();
+	extern int write();
+#endif
+	const unsigned char *buf=_buf;
+	long rnum;
+	int i,j,k,outnum;
+	static unsigned char *outbuf=NULL;
+	unsigned char shortbuf[8];
+	unsigned char *p;
+	const unsigned char *cp;
+	static int start=1;
+
+	if (outbuf == NULL)
+		{
+		outbuf=malloc(BSIZE+HDRSIZE);
+		if (outbuf == NULL) return(-1);
+		}
+	/* If we are sending less than 8 bytes, the same char will look
+	 * the same if we don't pad it out with random bytes */
+	if (start)
+		{
+		start=0;
+		}
+
+	/* lets recurse if we want to send the data in small chunks */
+	if (len > MAXWRITE)
+		{
+		j=0;
+		for (i=0; i MAXWRITE)?MAXWRITE:(len-i),sched,iv);
+			if (k < 0)
+				return(k);
+			else
+				j+=k;
+			}
+		return(j);
+		}
+
+	/* write length first */
+	p=outbuf;
+	l2n(len,p);
+
+	/* pad short strings */
+	if (len < 8)
+		{
+		cp=shortbuf;
+		memcpy(shortbuf,buf,len);
+		arc4random_buf(shortbuf+len, 8-len);
+		rnum=8;
+		}
+	else
+		{
+		cp=buf;
+		rnum=((len+7)/8*8); /* round up to nearest eight */
+		}
+
+	if (DES_rw_mode & DES_PCBC_MODE)
+		DES_pcbc_encrypt(cp,&(outbuf[HDRSIZE]),(len<8)?8:len,sched,iv,
+				 DES_ENCRYPT); 
+	else
+		DES_cbc_encrypt(cp,&(outbuf[HDRSIZE]),(len<8)?8:len,sched,iv,
+				DES_ENCRYPT); 
+
+	/* output */
+	outnum=rnum+HDRSIZE;
+
+	for (j=0; j
+
+/* This version of crypt has been developed from my MIT compatible
+ * DES library.
+ * Eric Young (eay@cryptsoft.com)
+ */
+
+/* Modification by Jens Kupferschmidt (Cu)
+ * I have included directive PARA for shared memory computers.
+ * I have included a directive LONGCRYPT to using this routine to cipher
+ * passwords with more then 8 bytes like HP-UX 10.x it used. The MAXPLEN
+ * definition is the maximum of length of password and can changed. I have
+ * defined 24.
+ */
+
+#include "des_locl.h"
+
+/* Added more values to handle illegal salt values the way normal
+ * crypt() implementations do.  The patch was sent by 
+ * Bjorn Gronvall 
+ */
+static unsigned const char con_salt[128]={
+0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,
+0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1,
+0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
+0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,
+0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,
+0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x00,0x01,
+0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
+0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A,
+0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,
+0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,
+0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,
+0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24,
+0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,
+0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,
+0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,
+0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,
+};
+
+static unsigned const char cov_2char[64]={
+0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
+0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,
+0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,
+0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,
+0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,
+0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
+0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,
+0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
+};
+
+char *DES_crypt(const char *buf, const char *salt)
+	{
+	static char buff[14];
+
+	return(DES_fcrypt(buf,salt,buff));
+	}
+
+
+char *DES_fcrypt(const char *buf, const char *salt, char *ret)
+	{
+	unsigned int i,j,x,y;
+	DES_LONG Eswap0,Eswap1;
+	DES_LONG out[2],ll;
+	DES_cblock key;
+	DES_key_schedule ks;
+	unsigned char bb[9];
+	unsigned char *b=bb;
+	unsigned char c,u;
+
+	/* eay 25/08/92
+	 * If you call crypt("pwd","*") as often happens when you
+	 * have * as the pwd field in /etc/passwd, the function
+	 * returns *\0xxxxxxxxx
+	 * The \0 makes the string look like * so the pwd "*" would
+	 * crypt to "*".  This was found when replacing the crypt in
+	 * our shared libraries.  People found that the disabled
+	 * accounts effectively had no passwd :-(. */
+	x=ret[0]=((salt[0] == '\0')?'A':salt[0]);
+	Eswap0=con_salt[x]<<2;
+	x=ret[1]=((salt[1] == '\0')?'A':salt[1]);
+	Eswap1=con_salt[x]<<6;
+/* EAY
+r=strlen(buf);
+r=(r+7)/8;
+*/
+	for (i=0; i<8; i++)
+		{
+		c= *(buf++);
+		if (!c) break;
+		key[i]=(c<<1);
+		}
+	for (; i<8; i++)
+		key[i]=0;
+
+	DES_set_key_unchecked(&key,&ks);
+	fcrypt_body(&(out[0]),&ks,Eswap0,Eswap1);
+
+	ll=out[0]; l2c(ll,b);
+	ll=out[1]; l2c(ll,b);
+	y=0;
+	u=0x80;
+	bb[8]=0;
+	for (i=2; i<13; i++)
+		{
+		c=0;
+		for (j=0; j<6; j++)
+			{
+			c<<=1;
+			if (bb[y] & u) c|=1;
+			u>>=1;
+			if (!u)
+				{
+				y++;
+				u=0x80;
+				}
+			}
+		ret[i]=cov_2char[c];
+		}
+	ret[13]='\0';
+	return(ret);
+	}
+
diff --git a/crypto/libressl/crypto/des/fcrypt_b.c b/crypto/libressl/crypto/des/fcrypt_b.c
new file mode 100644
index 0000000000..fc8bc0bc61
--- /dev/null
+++ b/crypto/libressl/crypto/des/fcrypt_b.c
@@ -0,0 +1,146 @@
+/* $OpenBSD: fcrypt_b.c,v 1.8 2014/06/12 15:49:28 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+/* This version of crypt has been developed from my MIT compatible
+ * DES library.
+ * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au
+ * Eric Young (eay@cryptsoft.com)
+ */
+
+#define DES_FCRYPT
+#include "des_locl.h"
+#undef DES_FCRYPT
+
+#ifndef OPENBSD_DES_ASM
+
+#undef PERM_OP
+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+	(b)^=(t),\
+	(a)^=((t)<<(n)))
+
+#undef HPERM_OP
+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
+	(a)=(a)^(t)^(t>>(16-(n))))\
+
+void fcrypt_body(DES_LONG *out, DES_key_schedule *ks, DES_LONG Eswap0,
+		 DES_LONG Eswap1)
+	{
+	DES_LONG l,r,t,u;
+#ifdef DES_PTR
+	const unsigned char *des_SP=(const unsigned char *)DES_SPtrans;
+#endif
+	DES_LONG *s;
+	int j;
+	DES_LONG E0,E1;
+
+	l=0;
+	r=0;
+
+	s=(DES_LONG *)ks;
+	E0=Eswap0;
+	E1=Eswap1;
+
+	for (j=0; j<25; j++)
+		{
+#ifndef DES_UNROLL
+		int i;
+
+		for (i=0; i<32; i+=4)
+			{
+			D_ENCRYPT(l,r,i+0); /*  1 */
+			D_ENCRYPT(r,l,i+2); /*  2 */
+			}
+#else
+		D_ENCRYPT(l,r, 0); /*  1 */
+		D_ENCRYPT(r,l, 2); /*  2 */
+		D_ENCRYPT(l,r, 4); /*  3 */
+		D_ENCRYPT(r,l, 6); /*  4 */
+		D_ENCRYPT(l,r, 8); /*  5 */
+		D_ENCRYPT(r,l,10); /*  6 */
+		D_ENCRYPT(l,r,12); /*  7 */
+		D_ENCRYPT(r,l,14); /*  8 */
+		D_ENCRYPT(l,r,16); /*  9 */
+		D_ENCRYPT(r,l,18); /*  10 */
+		D_ENCRYPT(l,r,20); /*  11 */
+		D_ENCRYPT(r,l,22); /*  12 */
+		D_ENCRYPT(l,r,24); /*  13 */
+		D_ENCRYPT(r,l,26); /*  14 */
+		D_ENCRYPT(l,r,28); /*  15 */
+		D_ENCRYPT(r,l,30); /*  16 */
+#endif
+
+		t=l;
+		l=r;
+		r=t;
+		}
+	l=ROTATE(l,3)&0xffffffffL;
+	r=ROTATE(r,3)&0xffffffffL;
+
+	PERM_OP(l,r,t, 1,0x55555555L);
+	PERM_OP(r,l,t, 8,0x00ff00ffL);
+	PERM_OP(l,r,t, 2,0x33333333L);
+	PERM_OP(r,l,t,16,0x0000ffffL);
+	PERM_OP(l,r,t, 4,0x0f0f0f0fL);
+
+	out[0]=r;
+	out[1]=l;
+	}
+
+#endif /* OPENBSD_DES_ASM */
diff --git a/crypto/libressl/crypto/des/ncbc_enc.c b/crypto/libressl/crypto/des/ncbc_enc.c
new file mode 100644
index 0000000000..518470d57a
--- /dev/null
+++ b/crypto/libressl/crypto/des/ncbc_enc.c
@@ -0,0 +1,148 @@
+/* $OpenBSD: ncbc_enc.c,v 1.6 2014/06/12 15:49:28 deraadt Exp $ */
+/*
+ * #included by:
+ *    cbc_enc.c  (DES_cbc_encrypt)
+ *    des_enc.c  (DES_ncbc_encrypt)
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+#ifdef CBC_ENC_C__DONT_UPDATE_IV
+void DES_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+		     DES_key_schedule *_schedule, DES_cblock *ivec, int enc)
+#else
+void DES_ncbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+		     DES_key_schedule *_schedule, DES_cblock *ivec, int enc)
+#endif
+	{
+	DES_LONG tin0,tin1;
+	DES_LONG tout0,tout1,xor0,xor1;
+	long l=length;
+	DES_LONG tin[2];
+	unsigned char *iv;
+
+	iv = &(*ivec)[0];
+
+	if (enc)
+		{
+		c2l(iv,tout0);
+		c2l(iv,tout1);
+		for (l-=8; l>=0; l-=8)
+			{
+			c2l(in,tin0);
+			c2l(in,tin1);
+			tin0^=tout0; tin[0]=tin0;
+			tin1^=tout1; tin[1]=tin1;
+			DES_encrypt1((DES_LONG *)tin,_schedule,DES_ENCRYPT);
+			tout0=tin[0]; l2c(tout0,out);
+			tout1=tin[1]; l2c(tout1,out);
+			}
+		if (l != -8)
+			{
+			c2ln(in,tin0,tin1,l+8);
+			tin0^=tout0; tin[0]=tin0;
+			tin1^=tout1; tin[1]=tin1;
+			DES_encrypt1((DES_LONG *)tin,_schedule,DES_ENCRYPT);
+			tout0=tin[0]; l2c(tout0,out);
+			tout1=tin[1]; l2c(tout1,out);
+			}
+#ifndef CBC_ENC_C__DONT_UPDATE_IV
+		iv = &(*ivec)[0];
+		l2c(tout0,iv);
+		l2c(tout1,iv);
+#endif
+		}
+	else
+		{
+		c2l(iv,xor0);
+		c2l(iv,xor1);
+		for (l-=8; l>=0; l-=8)
+			{
+			c2l(in,tin0); tin[0]=tin0;
+			c2l(in,tin1); tin[1]=tin1;
+			DES_encrypt1((DES_LONG *)tin,_schedule,DES_DECRYPT);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2c(tout0,out);
+			l2c(tout1,out);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		if (l != -8)
+			{
+			c2l(in,tin0); tin[0]=tin0;
+			c2l(in,tin1); tin[1]=tin1;
+			DES_encrypt1((DES_LONG *)tin,_schedule,DES_DECRYPT);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2cn(tout0,tout1,out,l+8);
+#ifndef CBC_ENC_C__DONT_UPDATE_IV
+			xor0=tin0;
+			xor1=tin1;
+#endif
+			}
+#ifndef CBC_ENC_C__DONT_UPDATE_IV 
+		iv = &(*ivec)[0];
+		l2c(xor0,iv);
+		l2c(xor1,iv);
+#endif
+		}
+	tin0=tin1=tout0=tout1=xor0=xor1=0;
+	tin[0]=tin[1]=0;
+	}
diff --git a/crypto/libressl/crypto/des/ofb64ede.c b/crypto/libressl/crypto/des/ofb64ede.c
new file mode 100644
index 0000000000..c6ed389319
--- /dev/null
+++ b/crypto/libressl/crypto/des/ofb64ede.c
@@ -0,0 +1,114 @@
+/* $OpenBSD: ofb64ede.c,v 1.5 2014/10/28 07:35:58 jsg Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+/* The input and output encrypted as though 64bit ofb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+void DES_ede3_ofb64_encrypt(const unsigned char *in,
+			    unsigned char *out, long length,
+			    DES_key_schedule *k1, DES_key_schedule *k2,
+			    DES_key_schedule *k3, DES_cblock *ivec,
+			    int *num)
+	{
+	DES_LONG v0,v1;
+	int n= *num;
+	long l=length;
+	DES_cblock d;
+	char *dp;
+	DES_LONG ti[2];
+	unsigned char *iv;
+	int save=0;
+
+	iv = &(*ivec)[0];
+	c2l(iv,v0);
+	c2l(iv,v1);
+	ti[0]=v0;
+	ti[1]=v1;
+	dp=(char *)d;
+	l2c(v0,dp);
+	l2c(v1,dp);
+	while (l--)
+		{
+		if (n == 0)
+			{
+			/* ti[0]=v0; */
+			/* ti[1]=v1; */
+			DES_encrypt3(ti,k1,k2,k3);
+			v0=ti[0];
+			v1=ti[1];
+
+			dp=(char *)d;
+			l2c(v0,dp);
+			l2c(v1,dp);
+			save++;
+			}
+		*(out++)= *(in++)^d[n];
+		n=(n+1)&0x07;
+		}
+	if (save)
+		{
+		iv = &(*ivec)[0];
+		l2c(v0,iv);
+		l2c(v1,iv);
+		}
+	v0=v1=ti[0]=ti[1]=0;
+	*num=n;
+	}
diff --git a/crypto/libressl/crypto/des/ofb64enc.c b/crypto/libressl/crypto/des/ofb64enc.c
new file mode 100644
index 0000000000..1e55ae5fcd
--- /dev/null
+++ b/crypto/libressl/crypto/des/ofb64enc.c
@@ -0,0 +1,110 @@
+/* $OpenBSD: ofb64enc.c,v 1.5 2014/06/12 15:49:28 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+/* The input and output encrypted as though 64bit ofb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+void DES_ofb64_encrypt(const unsigned char *in,
+		       unsigned char *out, long length,
+		       DES_key_schedule *schedule, DES_cblock *ivec, int *num)
+	{
+	DES_LONG v0,v1,t;
+	int n= *num;
+	long l=length;
+	DES_cblock d;
+	unsigned char *dp;
+	DES_LONG ti[2];
+	unsigned char *iv;
+	int save=0;
+
+	iv = &(*ivec)[0];
+	c2l(iv,v0);
+	c2l(iv,v1);
+	ti[0]=v0;
+	ti[1]=v1;
+	dp=d;
+	l2c(v0,dp);
+	l2c(v1,dp);
+	while (l--)
+		{
+		if (n == 0)
+			{
+			DES_encrypt1(ti,schedule,DES_ENCRYPT);
+			dp=d;
+			t=ti[0]; l2c(t,dp);
+			t=ti[1]; l2c(t,dp);
+			save++;
+			}
+		*(out++)= *(in++)^d[n];
+		n=(n+1)&0x07;
+		}
+	if (save)
+		{
+		v0=ti[0];
+		v1=ti[1];
+		iv = &(*ivec)[0];
+		l2c(v0,iv);
+		l2c(v1,iv);
+		}
+	t=v0=v1=ti[0]=ti[1]=0;
+	*num=n;
+	}
+
diff --git a/crypto/libressl/crypto/des/ofb_enc.c b/crypto/libressl/crypto/des/ofb_enc.c
new file mode 100644
index 0000000000..7ed7e38d80
--- /dev/null
+++ b/crypto/libressl/crypto/des/ofb_enc.c
@@ -0,0 +1,135 @@
+/* $OpenBSD: ofb_enc.c,v 1.5 2014/06/12 15:49:28 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+/* The input and output are loaded in multiples of 8 bits.
+ * What this means is that if you hame numbits=12 and length=2
+ * the first 12 bits will be retrieved from the first byte and half
+ * the second.  The second 12 bits will come from the 3rd and half the 4th
+ * byte.
+ */
+void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
+		     long length, DES_key_schedule *schedule,
+		     DES_cblock *ivec)
+	{
+	DES_LONG d0,d1,vv0,vv1,v0,v1,n=(numbits+7)/8;
+	DES_LONG mask0,mask1;
+	long l=length;
+	int num=numbits;
+	DES_LONG ti[2];
+	unsigned char *iv;
+
+	if (num > 64) return;
+	if (num > 32)
+		{
+		mask0=0xffffffffL;
+		if (num >= 64)
+			mask1=mask0;
+		else
+			mask1=(1L<<(num-32))-1;
+		}
+	else
+		{
+		if (num == 32)
+			mask0=0xffffffffL;
+		else
+			mask0=(1L< 0)
+		{
+		ti[0]=v0;
+		ti[1]=v1;
+		DES_encrypt1((DES_LONG *)ti,schedule,DES_ENCRYPT);
+		vv0=ti[0];
+		vv1=ti[1];
+		c2ln(in,d0,d1,n);
+		in+=n;
+		d0=(d0^vv0)&mask0;
+		d1=(d1^vv1)&mask1;
+		l2cn(d0,d1,out,n);
+		out+=n;
+
+		if (num == 32)
+			{ v0=v1; v1=vv0; }
+		else if (num == 64)
+				{ v0=vv0; v1=vv1; }
+		else if (num > 32) /* && num != 64 */
+			{
+			v0=((v1>>(num-32))|(vv0<<(64-num)))&0xffffffffL;
+			v1=((vv0>>(num-32))|(vv1<<(64-num)))&0xffffffffL;
+			}
+		else /* num < 32 */
+			{
+			v0=((v0>>num)|(v1<<(32-num)))&0xffffffffL;
+			v1=((v1>>num)|(vv0<<(32-num)))&0xffffffffL;
+			}
+		}
+	iv = &(*ivec)[0];
+	l2c(v0,iv);
+	l2c(v1,iv);
+	v0=v1=d0=d1=ti[0]=ti[1]=vv0=vv1=0;
+	}
+
diff --git a/crypto/libressl/crypto/des/pcbc_enc.c b/crypto/libressl/crypto/des/pcbc_enc.c
new file mode 100644
index 0000000000..c5fb3112cb
--- /dev/null
+++ b/crypto/libressl/crypto/des/pcbc_enc.c
@@ -0,0 +1,123 @@
+/* $OpenBSD: pcbc_enc.c,v 1.5 2014/06/12 15:49:28 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output,
+		      long length, DES_key_schedule *schedule,
+		      DES_cblock *ivec, int enc)
+	{
+	DES_LONG sin0,sin1,xor0,xor1,tout0,tout1;
+	DES_LONG tin[2];
+	const unsigned char *in;
+	unsigned char *out,*iv;
+
+	in=input;
+	out=output;
+	iv = &(*ivec)[0];
+
+	if (enc)
+		{
+		c2l(iv,xor0);
+		c2l(iv,xor1);
+		for (; length>0; length-=8)
+			{
+			if (length >= 8)
+				{
+				c2l(in,sin0);
+				c2l(in,sin1);
+				}
+			else
+				c2ln(in,sin0,sin1,length);
+			tin[0]=sin0^xor0;
+			tin[1]=sin1^xor1;
+			DES_encrypt1((DES_LONG *)tin,schedule,DES_ENCRYPT);
+			tout0=tin[0];
+			tout1=tin[1];
+			xor0=sin0^tout0;
+			xor1=sin1^tout1;
+			l2c(tout0,out);
+			l2c(tout1,out);
+			}
+		}
+	else
+		{
+		c2l(iv,xor0); c2l(iv,xor1);
+		for (; length>0; length-=8)
+			{
+			c2l(in,sin0);
+			c2l(in,sin1);
+			tin[0]=sin0;
+			tin[1]=sin1;
+			DES_encrypt1((DES_LONG *)tin,schedule,DES_DECRYPT);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			if (length >= 8)
+				{
+				l2c(tout0,out);
+				l2c(tout1,out);
+				}
+			else
+				l2cn(tout0,tout1,out,length);
+			xor0=tout0^sin0;
+			xor1=tout1^sin1;
+			}
+		}
+	tin[0]=tin[1]=0;
+	sin0=sin1=xor0=xor1=tout0=tout1=0;
+	}
diff --git a/crypto/libressl/crypto/des/qud_cksm.c b/crypto/libressl/crypto/des/qud_cksm.c
new file mode 100644
index 0000000000..8fd37a8d16
--- /dev/null
+++ b/crypto/libressl/crypto/des/qud_cksm.c
@@ -0,0 +1,125 @@
+/* $OpenBSD$ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* From "Message Authentication"  R.R. Jueneman, S.M. Matyas, C.H. Meyer
+ * IEEE Communications Magazine Sept 1985 Vol. 23 No. 9 p 29-40
+ * This module in only based on the code in this paper and is
+ * almost definitely not the same as the MIT implementation.
+ */
+#include "des_locl.h"
+
+/* bug fix for dos - 7/6/91 - Larry hughes@logos.ucs.indiana.edu */
+#define Q_B0(a)	(((DES_LONG)(a)))
+#define Q_B1(a)	(((DES_LONG)(a))<<8)
+#define Q_B2(a)	(((DES_LONG)(a))<<16)
+#define Q_B3(a)	(((DES_LONG)(a))<<24)
+
+/* used to scramble things a bit */
+/* Got the value MIT uses via brute force :-) 2/10/90 eay */
+#define NOISE	((DES_LONG)83653421L)
+
+DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[],
+	     long length, int out_count, DES_cblock *seed)
+	{
+	DES_LONG z0,z1,t0,t1;
+	int i;
+	long l;
+	const unsigned char *cp;
+	DES_LONG *lp;
+
+	if (out_count < 1) out_count=1;
+	lp = (DES_LONG *) &(output[0])[0];
+
+	z0=Q_B0((*seed)[0])|Q_B1((*seed)[1])|Q_B2((*seed)[2])|Q_B3((*seed)[3]);
+	z1=Q_B0((*seed)[4])|Q_B1((*seed)[5])|Q_B2((*seed)[6])|Q_B3((*seed)[7]);
+
+	for (i=0; ((i<4)&&(i 0)
+			{
+			if (l > 1)
+				{
+				t0= (DES_LONG)(*(cp++));
+				t0|=(DES_LONG)Q_B1(*(cp++));
+				l--;
+				}
+			else
+				t0= (DES_LONG)(*(cp++));
+			l--;
+			/* add */
+			t0+=z0;
+			t0&=0xffffffffL;
+			t1=z1;
+			/* square, well sort of square */
+			z0=((((t0*t0)&0xffffffffL)+((t1*t1)&0xffffffffL))
+				&0xffffffffL)%0x7fffffffL; 
+			z1=((t0*((t1+NOISE)&0xffffffffL))&0xffffffffL)%0x7fffffffL;
+			}
+		if (lp != NULL)
+			{
+			/* The MIT library assumes that the checksum is
+			 * composed of 2*out_count 32 bit ints */
+			*lp++ = z0;
+			*lp++ = z1;
+			}
+		}
+	return(z0);
+	}
+
diff --git a/crypto/libressl/crypto/des/rand_key.c b/crypto/libressl/crypto/des/rand_key.c
new file mode 100644
index 0000000000..1d7130fcc7
--- /dev/null
+++ b/crypto/libressl/crypto/des/rand_key.c
@@ -0,0 +1,68 @@
+/* $OpenBSD: rand_key.c,v 1.7 2014/07/22 18:09:20 miod Exp $ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+int
+DES_random_key(DES_cblock *ret)
+{
+	do {
+		arc4random_buf(ret, sizeof(DES_cblock));
+		DES_set_odd_parity(ret);
+	} while (DES_is_weak_key(ret));
+	return (1);
+}
diff --git a/crypto/libressl/crypto/des/set_key.c b/crypto/libressl/crypto/des/set_key.c
new file mode 100644
index 0000000000..65a3198855
--- /dev/null
+++ b/crypto/libressl/crypto/des/set_key.c
@@ -0,0 +1,400 @@
+/* $OpenBSD: set_key.c,v 1.18 2014/10/12 20:48:58 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* set_key.c v 1.4 eay 24/9/91
+ * 1.4 Speed up by 400% :-)
+ * 1.3 added register declarations.
+ * 1.2 unrolled make_key_sched a bit more
+ * 1.1 added norm_expand_bits
+ * 1.0 First working version
+ */
+#include 
+#include "des_locl.h"
+
+int DES_check_key = 0;	/* defaults to false */
+
+static const unsigned char odd_parity[256]={
+  1,  1,  2,  2,  4,  4,  7,  7,  8,  8, 11, 11, 13, 13, 14, 14,
+ 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
+ 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
+ 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
+ 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
+ 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
+ 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
+112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
+128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
+145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
+161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
+176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
+193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
+208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
+224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
+241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
+
+void DES_set_odd_parity(DES_cblock *key)
+	{
+	unsigned int i;
+
+	for (i=0; i>(n))^(b))&(m)),\
+ * 	(b)^=(t),\
+ * 	(a)=((a)^((t)<<(n))))
+ */
+
+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
+	(a)=(a)^(t)^(t>>(16-(n))))
+
+static const DES_LONG des_skb[8][64]={
+	{
+	/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+	0x00000000L,0x00000010L,0x20000000L,0x20000010L,
+	0x00010000L,0x00010010L,0x20010000L,0x20010010L,
+	0x00000800L,0x00000810L,0x20000800L,0x20000810L,
+	0x00010800L,0x00010810L,0x20010800L,0x20010810L,
+	0x00000020L,0x00000030L,0x20000020L,0x20000030L,
+	0x00010020L,0x00010030L,0x20010020L,0x20010030L,
+	0x00000820L,0x00000830L,0x20000820L,0x20000830L,
+	0x00010820L,0x00010830L,0x20010820L,0x20010830L,
+	0x00080000L,0x00080010L,0x20080000L,0x20080010L,
+	0x00090000L,0x00090010L,0x20090000L,0x20090010L,
+	0x00080800L,0x00080810L,0x20080800L,0x20080810L,
+	0x00090800L,0x00090810L,0x20090800L,0x20090810L,
+	0x00080020L,0x00080030L,0x20080020L,0x20080030L,
+	0x00090020L,0x00090030L,0x20090020L,0x20090030L,
+	0x00080820L,0x00080830L,0x20080820L,0x20080830L,
+	0x00090820L,0x00090830L,0x20090820L,0x20090830L,
+	},{
+	/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
+	0x00000000L,0x02000000L,0x00002000L,0x02002000L,
+	0x00200000L,0x02200000L,0x00202000L,0x02202000L,
+	0x00000004L,0x02000004L,0x00002004L,0x02002004L,
+	0x00200004L,0x02200004L,0x00202004L,0x02202004L,
+	0x00000400L,0x02000400L,0x00002400L,0x02002400L,
+	0x00200400L,0x02200400L,0x00202400L,0x02202400L,
+	0x00000404L,0x02000404L,0x00002404L,0x02002404L,
+	0x00200404L,0x02200404L,0x00202404L,0x02202404L,
+	0x10000000L,0x12000000L,0x10002000L,0x12002000L,
+	0x10200000L,0x12200000L,0x10202000L,0x12202000L,
+	0x10000004L,0x12000004L,0x10002004L,0x12002004L,
+	0x10200004L,0x12200004L,0x10202004L,0x12202004L,
+	0x10000400L,0x12000400L,0x10002400L,0x12002400L,
+	0x10200400L,0x12200400L,0x10202400L,0x12202400L,
+	0x10000404L,0x12000404L,0x10002404L,0x12002404L,
+	0x10200404L,0x12200404L,0x10202404L,0x12202404L,
+	},{
+	/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
+	0x00000000L,0x00000001L,0x00040000L,0x00040001L,
+	0x01000000L,0x01000001L,0x01040000L,0x01040001L,
+	0x00000002L,0x00000003L,0x00040002L,0x00040003L,
+	0x01000002L,0x01000003L,0x01040002L,0x01040003L,
+	0x00000200L,0x00000201L,0x00040200L,0x00040201L,
+	0x01000200L,0x01000201L,0x01040200L,0x01040201L,
+	0x00000202L,0x00000203L,0x00040202L,0x00040203L,
+	0x01000202L,0x01000203L,0x01040202L,0x01040203L,
+	0x08000000L,0x08000001L,0x08040000L,0x08040001L,
+	0x09000000L,0x09000001L,0x09040000L,0x09040001L,
+	0x08000002L,0x08000003L,0x08040002L,0x08040003L,
+	0x09000002L,0x09000003L,0x09040002L,0x09040003L,
+	0x08000200L,0x08000201L,0x08040200L,0x08040201L,
+	0x09000200L,0x09000201L,0x09040200L,0x09040201L,
+	0x08000202L,0x08000203L,0x08040202L,0x08040203L,
+	0x09000202L,0x09000203L,0x09040202L,0x09040203L,
+	},{
+	/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
+	0x00000000L,0x00100000L,0x00000100L,0x00100100L,
+	0x00000008L,0x00100008L,0x00000108L,0x00100108L,
+	0x00001000L,0x00101000L,0x00001100L,0x00101100L,
+	0x00001008L,0x00101008L,0x00001108L,0x00101108L,
+	0x04000000L,0x04100000L,0x04000100L,0x04100100L,
+	0x04000008L,0x04100008L,0x04000108L,0x04100108L,
+	0x04001000L,0x04101000L,0x04001100L,0x04101100L,
+	0x04001008L,0x04101008L,0x04001108L,0x04101108L,
+	0x00020000L,0x00120000L,0x00020100L,0x00120100L,
+	0x00020008L,0x00120008L,0x00020108L,0x00120108L,
+	0x00021000L,0x00121000L,0x00021100L,0x00121100L,
+	0x00021008L,0x00121008L,0x00021108L,0x00121108L,
+	0x04020000L,0x04120000L,0x04020100L,0x04120100L,
+	0x04020008L,0x04120008L,0x04020108L,0x04120108L,
+	0x04021000L,0x04121000L,0x04021100L,0x04121100L,
+	0x04021008L,0x04121008L,0x04021108L,0x04121108L,
+	},{
+	/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+	0x00000000L,0x10000000L,0x00010000L,0x10010000L,
+	0x00000004L,0x10000004L,0x00010004L,0x10010004L,
+	0x20000000L,0x30000000L,0x20010000L,0x30010000L,
+	0x20000004L,0x30000004L,0x20010004L,0x30010004L,
+	0x00100000L,0x10100000L,0x00110000L,0x10110000L,
+	0x00100004L,0x10100004L,0x00110004L,0x10110004L,
+	0x20100000L,0x30100000L,0x20110000L,0x30110000L,
+	0x20100004L,0x30100004L,0x20110004L,0x30110004L,
+	0x00001000L,0x10001000L,0x00011000L,0x10011000L,
+	0x00001004L,0x10001004L,0x00011004L,0x10011004L,
+	0x20001000L,0x30001000L,0x20011000L,0x30011000L,
+	0x20001004L,0x30001004L,0x20011004L,0x30011004L,
+	0x00101000L,0x10101000L,0x00111000L,0x10111000L,
+	0x00101004L,0x10101004L,0x00111004L,0x10111004L,
+	0x20101000L,0x30101000L,0x20111000L,0x30111000L,
+	0x20101004L,0x30101004L,0x20111004L,0x30111004L,
+	},{
+	/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
+	0x00000000L,0x08000000L,0x00000008L,0x08000008L,
+	0x00000400L,0x08000400L,0x00000408L,0x08000408L,
+	0x00020000L,0x08020000L,0x00020008L,0x08020008L,
+	0x00020400L,0x08020400L,0x00020408L,0x08020408L,
+	0x00000001L,0x08000001L,0x00000009L,0x08000009L,
+	0x00000401L,0x08000401L,0x00000409L,0x08000409L,
+	0x00020001L,0x08020001L,0x00020009L,0x08020009L,
+	0x00020401L,0x08020401L,0x00020409L,0x08020409L,
+	0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
+	0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
+	0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
+	0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
+	0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
+	0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
+	0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
+	0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
+	},{
+	/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
+	0x00000000L,0x00000100L,0x00080000L,0x00080100L,
+	0x01000000L,0x01000100L,0x01080000L,0x01080100L,
+	0x00000010L,0x00000110L,0x00080010L,0x00080110L,
+	0x01000010L,0x01000110L,0x01080010L,0x01080110L,
+	0x00200000L,0x00200100L,0x00280000L,0x00280100L,
+	0x01200000L,0x01200100L,0x01280000L,0x01280100L,
+	0x00200010L,0x00200110L,0x00280010L,0x00280110L,
+	0x01200010L,0x01200110L,0x01280010L,0x01280110L,
+	0x00000200L,0x00000300L,0x00080200L,0x00080300L,
+	0x01000200L,0x01000300L,0x01080200L,0x01080300L,
+	0x00000210L,0x00000310L,0x00080210L,0x00080310L,
+	0x01000210L,0x01000310L,0x01080210L,0x01080310L,
+	0x00200200L,0x00200300L,0x00280200L,0x00280300L,
+	0x01200200L,0x01200300L,0x01280200L,0x01280300L,
+	0x00200210L,0x00200310L,0x00280210L,0x00280310L,
+	0x01200210L,0x01200310L,0x01280210L,0x01280310L,
+	},{
+	/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
+	0x00000000L,0x04000000L,0x00040000L,0x04040000L,
+	0x00000002L,0x04000002L,0x00040002L,0x04040002L,
+	0x00002000L,0x04002000L,0x00042000L,0x04042000L,
+	0x00002002L,0x04002002L,0x00042002L,0x04042002L,
+	0x00000020L,0x04000020L,0x00040020L,0x04040020L,
+	0x00000022L,0x04000022L,0x00040022L,0x04040022L,
+	0x00002020L,0x04002020L,0x00042020L,0x04042020L,
+	0x00002022L,0x04002022L,0x00042022L,0x04042022L,
+	0x00000800L,0x04000800L,0x00040800L,0x04040800L,
+	0x00000802L,0x04000802L,0x00040802L,0x04040802L,
+	0x00002800L,0x04002800L,0x00042800L,0x04042800L,
+	0x00002802L,0x04002802L,0x00042802L,0x04042802L,
+	0x00000820L,0x04000820L,0x00040820L,0x04040820L,
+	0x00000822L,0x04000822L,0x00040822L,0x04040822L,
+	0x00002820L,0x04002820L,0x00042820L,0x04042820L,
+	0x00002822L,0x04002822L,0x00042822L,0x04042822L,
+	}};
+
+int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule)
+	{
+	if (DES_check_key)
+		{
+		return DES_set_key_checked(key, schedule);
+		}
+	else
+		{
+		DES_set_key_unchecked(key, schedule);
+		return 0;
+		}
+	}
+
+/* return 0 if key parity is odd (correct),
+ * return -1 if key parity error,
+ * return -2 if illegal weak key.
+ */
+int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule)
+	{
+	if (!DES_check_key_parity(key))
+		return(-1);
+	if (DES_is_weak_key(key))
+		return(-2);
+	DES_set_key_unchecked(key, schedule);
+	return 0;
+	}
+
+void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule)
+	{
+	static const int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
+	DES_LONG c,d,t,s,t2;
+	const unsigned char *in;
+	DES_LONG *k;
+	int i;
+
+	k = &schedule->ks->deslong[0];
+	in = &(*key)[0];
+
+	c2l(in,c);
+	c2l(in,d);
+
+	/* do PC1 in 47 simple operations :-)
+	 * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
+	 * for the inspiration. :-) */
+	PERM_OP (d,c,t,4,0x0f0f0f0fL);
+	HPERM_OP(c,t,-2,0xcccc0000L);
+	HPERM_OP(d,t,-2,0xcccc0000L);
+	PERM_OP (d,c,t,1,0x55555555L);
+	PERM_OP (c,d,t,8,0x00ff00ffL);
+	PERM_OP (d,c,t,1,0x55555555L);
+	d=	(((d&0x000000ffL)<<16L)| (d&0x0000ff00L)     |
+		 ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
+	c&=0x0fffffffL;
+
+	for (i=0; i>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
+		else
+			{ c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
+		c&=0x0fffffffL;
+		d&=0x0fffffffL;
+		/* could be a few less shifts but I am to lazy at this
+		 * point in time to investigate */
+		s=	des_skb[0][ (c    )&0x3f                ]|
+			des_skb[1][((c>> 6L)&0x03)|((c>> 7L)&0x3c)]|
+			des_skb[2][((c>>13L)&0x0f)|((c>>14L)&0x30)]|
+			des_skb[3][((c>>20L)&0x01)|((c>>21L)&0x06) |
+						  ((c>>22L)&0x38)];
+		t=	des_skb[4][ (d    )&0x3f                ]|
+			des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
+			des_skb[6][ (d>>15L)&0x3f                ]|
+			des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
+
+		/* table contained 0213 4657 */
+		t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
+		*(k++)=ROTATE(t2,30)&0xffffffffL;
+
+		t2=((s>>16L)|(t&0xffff0000L));
+		*(k++)=ROTATE(t2,26)&0xffffffffL;
+		}
+	}
+
+int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule)
+	{
+	return(DES_set_key(key,schedule));
+	}
+/*
+#undef des_fixup_key_parity
+void des_fixup_key_parity(des_cblock *key)
+	{
+	des_set_odd_parity(key);
+	}
+*/
diff --git a/crypto/libressl/crypto/des/spr.h b/crypto/libressl/crypto/des/spr.h
new file mode 100644
index 0000000000..9465bcd86a
--- /dev/null
+++ b/crypto/libressl/crypto/des/spr.h
@@ -0,0 +1,204 @@
+/* $OpenBSD$ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+const DES_LONG DES_SPtrans[8][64]={
+{
+/* nibble 0 */
+0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
+0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
+0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
+0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
+0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
+0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
+0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
+0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
+0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
+0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
+0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
+0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
+0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
+0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
+0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
+0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
+},{
+/* nibble 1 */
+0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
+0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
+0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
+0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
+0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
+0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
+0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
+0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
+0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
+0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
+0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
+0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
+0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
+0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
+0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
+0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
+},{
+/* nibble 2 */
+0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
+0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
+0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
+0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
+0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
+0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
+0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
+0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
+0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
+0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
+0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
+0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
+0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
+0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
+0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
+0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
+},{
+/* nibble 3 */
+0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
+0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
+0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
+0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
+0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
+0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
+0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
+0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
+0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
+0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
+0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
+0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
+0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
+0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
+0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
+0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
+},{
+/* nibble 4 */
+0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
+0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
+0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
+0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
+0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
+0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
+0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
+0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
+0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
+0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
+0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
+0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
+0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
+0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
+0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
+0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
+},{
+/* nibble 5 */
+0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
+0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
+0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
+0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
+0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
+0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
+0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
+0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
+0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
+0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
+0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
+0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
+0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
+0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
+0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
+0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
+},{
+/* nibble 6 */
+0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
+0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
+0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
+0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
+0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
+0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
+0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
+0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
+0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
+0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
+0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
+0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
+0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
+0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
+0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
+0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
+},{
+/* nibble 7 */
+0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
+0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
+0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
+0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
+0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
+0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
+0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
+0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
+0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
+0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
+0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
+0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
+0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
+0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
+0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
+0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
+}};
diff --git a/crypto/libressl/crypto/des/str2key.c b/crypto/libressl/crypto/des/str2key.c
new file mode 100644
index 0000000000..94a2127173
--- /dev/null
+++ b/crypto/libressl/crypto/des/str2key.c
@@ -0,0 +1,174 @@
+/* $OpenBSD: str2key.c,v 1.9 2014/10/28 07:35:58 jsg Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include "des_locl.h"
+
+void DES_string_to_key(const char *str, DES_cblock *key)
+	{
+	DES_key_schedule ks;
+	int i,length;
+	unsigned char j;
+
+	memset(key,0,8);
+	length=strlen(str);
+#ifdef OLD_STR_TO_KEY
+	for (i=0; i>4)&0x0f);
+			j=((j<<2)&0xcc)|((j>>2)&0x33);
+			j=((j<<1)&0xaa)|((j>>1)&0x55);
+			(*key)[7-(i%8)]^=j;
+			}
+		}
+#endif
+	DES_set_odd_parity(key);
+#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY
+	if(DES_is_weak_key(key))
+	    (*key)[7] ^= 0xF0;
+	DES_set_key(key,&ks);
+#else
+	DES_set_key_unchecked(key,&ks);
+#endif
+	DES_cbc_cksum((const unsigned char*)str,key,length,&ks,key);
+	explicit_bzero(&ks,sizeof(ks));
+	DES_set_odd_parity(key);
+	}
+
+void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2)
+	{
+	DES_key_schedule ks;
+	int i,length;
+	unsigned char j;
+
+	memset(key1,0,8);
+	memset(key2,0,8);
+	length=strlen(str);
+#ifdef OLD_STR_TO_KEY
+	if (length <= 8)
+		{
+		for (i=0; i>4)&0x0f);
+			j=((j<<2)&0xcc)|((j>>2)&0x33);
+			j=((j<<1)&0xaa)|((j>>1)&0x55);
+			if ((i%16) < 8)
+				(*key1)[7-(i%8)]^=j;
+			else
+				(*key2)[7-(i%8)]^=j;
+			}
+		}
+	if (length <= 8) memcpy(key2,key1,8);
+#endif
+	DES_set_odd_parity(key1);
+	DES_set_odd_parity(key2);
+#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY
+	if(DES_is_weak_key(key1))
+	    (*key1)[7] ^= 0xF0;
+	DES_set_key(key1,&ks);
+#else
+	DES_set_key_unchecked(key1,&ks);
+#endif
+	DES_cbc_cksum((const unsigned char*)str,key1,length,&ks,key1);
+#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY
+	if(DES_is_weak_key(key2))
+	    (*key2)[7] ^= 0xF0;
+	DES_set_key(key2,&ks);
+#else
+	DES_set_key_unchecked(key2,&ks);
+#endif
+	DES_cbc_cksum((const unsigned char*)str,key2,length,&ks,key2);
+	explicit_bzero(&ks,sizeof(ks));
+	DES_set_odd_parity(key1);
+	DES_set_odd_parity(key2);
+	}
diff --git a/crypto/libressl/crypto/des/xcbc_enc.c b/crypto/libressl/crypto/des/xcbc_enc.c
new file mode 100644
index 0000000000..1304050cd1
--- /dev/null
+++ b/crypto/libressl/crypto/des/xcbc_enc.c
@@ -0,0 +1,148 @@
+/* $OpenBSD: xcbc_enc.c,v 1.8 2014/10/28 07:35:58 jsg Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+/* RSA's DESX */
+
+void DES_xcbc_encrypt(const unsigned char *in, unsigned char *out,
+		      long length, DES_key_schedule *schedule,
+		      DES_cblock *ivec, const_DES_cblock *inw,
+		      const_DES_cblock *outw, int enc)
+	{
+	DES_LONG tin0,tin1;
+	DES_LONG tout0,tout1,xor0,xor1;
+	DES_LONG inW0,inW1,outW0,outW1;
+	const unsigned char *in2;
+	long l=length;
+	DES_LONG tin[2];
+	unsigned char *iv;
+
+	in2 = &(*inw)[0];
+	c2l(in2,inW0);
+	c2l(in2,inW1);
+	in2 = &(*outw)[0];
+	c2l(in2,outW0);
+	c2l(in2,outW1);
+
+	iv = &(*ivec)[0];
+
+	if (enc)
+		{
+		c2l(iv,tout0);
+		c2l(iv,tout1);
+		for (l-=8; l>=0; l-=8)
+			{
+			c2l(in,tin0);
+			c2l(in,tin1);
+			tin0^=tout0^inW0; tin[0]=tin0;
+			tin1^=tout1^inW1; tin[1]=tin1;
+			DES_encrypt1(tin,schedule,DES_ENCRYPT);
+			tout0=tin[0]^outW0; l2c(tout0,out);
+			tout1=tin[1]^outW1; l2c(tout1,out);
+			}
+		if (l != -8)
+			{
+			c2ln(in,tin0,tin1,l+8);
+			tin0^=tout0^inW0; tin[0]=tin0;
+			tin1^=tout1^inW1; tin[1]=tin1;
+			DES_encrypt1(tin,schedule,DES_ENCRYPT);
+			tout0=tin[0]^outW0; l2c(tout0,out);
+			tout1=tin[1]^outW1; l2c(tout1,out);
+			}
+		iv = &(*ivec)[0];
+		l2c(tout0,iv);
+		l2c(tout1,iv);
+		}
+	else
+		{
+		c2l(iv,xor0);
+		c2l(iv,xor1);
+		for (l-=8; l>0; l-=8)
+			{
+			c2l(in,tin0); tin[0]=tin0^outW0;
+			c2l(in,tin1); tin[1]=tin1^outW1;
+			DES_encrypt1(tin,schedule,DES_DECRYPT);
+			tout0=tin[0]^xor0^inW0;
+			tout1=tin[1]^xor1^inW1;
+			l2c(tout0,out);
+			l2c(tout1,out);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		if (l != -8)
+			{
+			c2l(in,tin0); tin[0]=tin0^outW0;
+			c2l(in,tin1); tin[1]=tin1^outW1;
+			DES_encrypt1(tin,schedule,DES_DECRYPT);
+			tout0=tin[0]^xor0^inW0;
+			tout1=tin[1]^xor1^inW1;
+			l2cn(tout0,tout1,out,l+8);
+			xor0=tin0;
+			xor1=tin1;
+			}
+
+		iv = &(*ivec)[0];
+		l2c(xor0,iv);
+		l2c(xor1,iv);
+		}
+	tin0=tin1=tout0=tout1=xor0=xor1=0;
+	inW0=inW1=outW0=outW1=0;
+	tin[0]=tin[1]=0;
+	}
+
diff --git a/crypto/libressl/crypto/dh/dh_ameth.c b/crypto/libressl/crypto/dh/dh_ameth.c
new file mode 100644
index 0000000000..0a9df20446
--- /dev/null
+++ b/crypto/libressl/crypto/dh/dh_ameth.c
@@ -0,0 +1,493 @@
+/* $OpenBSD: dh_ameth.c,v 1.12 2014/07/12 16:03:37 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "asn1_locl.h"
+
+static void
+int_dh_free(EVP_PKEY *pkey)
+{
+	DH_free(pkey->pkey.dh);
+}
+
+static int
+dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+{
+	const unsigned char *p, *pm;
+	int pklen, pmlen;
+	int ptype;
+	void *pval;
+	ASN1_STRING *pstr;
+	X509_ALGOR *palg;
+	ASN1_INTEGER *public_key = NULL;
+	DH *dh = NULL;
+
+	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
+		return 0;
+	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+	if (ptype != V_ASN1_SEQUENCE) {
+		DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR);
+		goto err;
+	}
+
+	pstr = pval;	
+	pm = pstr->data;
+	pmlen = pstr->length;
+
+	if (!(dh = d2i_DHparams(NULL, &pm, pmlen))) {
+		DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
+		goto err;
+	}
+
+	if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen))) {
+		DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
+		goto err;
+	}
+
+	/* We have parameters now set public key */
+	if (!(dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) {
+		DHerr(DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR);
+		goto err;
+	}
+
+	ASN1_INTEGER_free(public_key);
+	EVP_PKEY_assign_DH(pkey, dh);
+	return 1;
+
+err:
+	if (public_key)
+		ASN1_INTEGER_free(public_key);
+	DH_free(dh);
+	return 0;
+}
+
+static int
+dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
+{
+	DH *dh;
+	int ptype;
+	unsigned char *penc = NULL;
+	int penclen;
+	ASN1_STRING *str;
+	ASN1_INTEGER *pub_key = NULL;
+
+	dh=pkey->pkey.dh;
+
+	str = ASN1_STRING_new();
+	if (str == NULL) {
+		DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	str->length = i2d_DHparams(dh, &str->data);
+	if (str->length <= 0) {
+		DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	ptype = V_ASN1_SEQUENCE;
+
+	pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL);
+	if (!pub_key)
+		goto err;
+
+	penclen = i2d_ASN1_INTEGER(pub_key, &penc);
+
+	ASN1_INTEGER_free(pub_key);
+
+	if (penclen <= 0) {
+		DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DH), ptype,
+	    (void *)str, penc, penclen))
+		return 1;
+
+err:
+	free(penc);
+	ASN1_STRING_free(str);
+
+	return 0;
+}
+
+/*
+ * PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in
+ * that the AlgorithmIdentifier contains the paramaters, the private key
+ * is explcitly included and the pubkey must be recalculated.
+ */
+	
+static int
+dh_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
+{
+	const unsigned char *p, *pm;
+	int pklen, pmlen;
+	int ptype;
+	void *pval;
+	ASN1_STRING *pstr;
+	X509_ALGOR *palg;
+	ASN1_INTEGER *privkey = NULL;
+	DH *dh = NULL;
+
+	if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
+		return 0;
+
+	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+	if (ptype != V_ASN1_SEQUENCE)
+		goto decerr;
+
+	if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen)))
+		goto decerr;
+
+	pstr = pval;	
+	pm = pstr->data;
+	pmlen = pstr->length;
+	if (!(dh = d2i_DHparams(NULL, &pm, pmlen)))
+		goto decerr;
+	/* We have parameters now set private key */
+	if (!(dh->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) {
+		DHerr(DH_F_DH_PRIV_DECODE, DH_R_BN_ERROR);
+		goto dherr;
+	}
+	/* Calculate public key */
+	if (!DH_generate_key(dh))
+		goto dherr;
+
+	EVP_PKEY_assign_DH(pkey, dh);
+
+	ASN1_INTEGER_free(privkey);
+
+	return 1;
+
+decerr:
+	DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR);
+dherr:
+	DH_free(dh);
+	return 0;
+}
+
+static int
+dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
+{
+	ASN1_STRING *params = NULL;
+	ASN1_INTEGER *prkey = NULL;
+	unsigned char *dp = NULL;
+	int dplen;
+
+	params = ASN1_STRING_new();
+
+	if (!params) {
+		DHerr(DH_F_DH_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	params->length = i2d_DHparams(pkey->pkey.dh, ¶ms->data);
+	if (params->length <= 0) {
+		DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	params->type = V_ASN1_SEQUENCE;
+
+	/* Get private key into integer */
+	prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL);
+
+	if (!prkey) {
+		DHerr(DH_F_DH_PRIV_ENCODE, DH_R_BN_ERROR);
+		goto err;
+	}
+
+	dplen = i2d_ASN1_INTEGER(prkey, &dp);
+
+	ASN1_INTEGER_free(prkey);
+	prkey = NULL;
+
+	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dhKeyAgreement), 0,
+	    V_ASN1_SEQUENCE, params, dp, dplen))
+		goto err;
+
+	return 1;
+
+err:
+	free(dp);
+	ASN1_STRING_free(params);
+	ASN1_INTEGER_free(prkey);
+	return 0;
+}
+
+static void
+update_buflen(const BIGNUM *b, size_t *pbuflen)
+{
+	size_t i;
+
+	if (!b)
+		return;
+	if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
+		*pbuflen = i;
+}
+
+static int
+dh_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
+{
+	DH *dh;
+
+	if (!(dh = d2i_DHparams(NULL, pder, derlen))) {
+		DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB);
+		return 0;
+	}
+	EVP_PKEY_assign_DH(pkey, dh);
+	return 1;
+}
+
+static int
+dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
+{
+	return i2d_DHparams(pkey->pkey.dh, pder);
+}
+
+static int
+do_dh_print(BIO *bp, const DH *x, int indent, ASN1_PCTX *ctx, int ptype)
+{
+	unsigned char *m = NULL;
+	int reason = ERR_R_BUF_LIB, ret = 0;
+	size_t buf_len = 0;
+	const char *ktype = NULL;
+	BIGNUM *priv_key, *pub_key;
+
+	if (ptype == 2)
+		priv_key = x->priv_key;
+	else
+		priv_key = NULL;
+
+	if (ptype > 0)
+		pub_key = x->pub_key;
+	else
+		pub_key = NULL;
+
+	update_buflen(x->p, &buf_len);
+
+	if (buf_len == 0) {
+		reason = ERR_R_PASSED_NULL_PARAMETER;
+		goto err;
+	}
+
+	update_buflen(x->g, &buf_len);
+	update_buflen(pub_key, &buf_len);
+	update_buflen(priv_key, &buf_len);
+
+	if (ptype == 2)
+		ktype = "PKCS#3 DH Private-Key";
+	else if (ptype == 1)
+		ktype = "PKCS#3 DH Public-Key";
+	else
+		ktype = "PKCS#3 DH Parameters";
+
+	m= malloc(buf_len + 10);
+	if (m == NULL) {
+		reason = ERR_R_MALLOC_FAILURE;
+		goto err;
+	}
+
+	BIO_indent(bp, indent, 128);
+	if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0)
+		goto err;
+	indent += 4;
+
+	if (!ASN1_bn_print(bp, "private-key:", priv_key, m, indent))
+		goto err;
+	if (!ASN1_bn_print(bp, "public-key:", pub_key, m, indent))
+		goto err;
+
+	if (!ASN1_bn_print(bp, "prime:", x->p, m, indent))
+		goto err;
+	if (!ASN1_bn_print(bp, "generator:", x->g, m, indent))
+		goto err;
+	if (x->length != 0) {
+		BIO_indent(bp, indent, 128);
+		if (BIO_printf(bp, "recommended-private-length: %d bits\n",
+		    (int)x->length) <= 0)
+			goto err;
+	}
+
+	ret = 1;
+	if (0) {
+err:
+		DHerr(DH_F_DO_DH_PRINT,reason);
+	}
+	free(m);
+	return(ret);
+}
+
+static int
+int_dh_size(const EVP_PKEY *pkey)
+{
+	return DH_size(pkey->pkey.dh);
+}
+
+static int
+dh_bits(const EVP_PKEY *pkey)
+{
+	return BN_num_bits(pkey->pkey.dh->p);
+}
+
+static int
+dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+	if (BN_cmp(a->pkey.dh->p, b->pkey.dh->p) ||
+	    BN_cmp(a->pkey.dh->g, b->pkey.dh->g))
+		return 0;
+	else
+		return 1;
+}
+
+static int
+dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+{
+	BIGNUM *a;
+
+	if ((a = BN_dup(from->pkey.dh->p)) == NULL)
+		return 0;
+	BN_free(to->pkey.dh->p);
+	to->pkey.dh->p = a;
+
+	if ((a = BN_dup(from->pkey.dh->g)) == NULL)
+		return 0;
+	BN_free(to->pkey.dh->g);
+	to->pkey.dh->g = a;
+
+	return 1;
+}
+
+static int
+dh_missing_parameters(const EVP_PKEY *a)
+{
+	if (!a->pkey.dh->p || !a->pkey.dh->g)
+		return 1;
+	return 0;
+}
+
+static int
+dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+	if (dh_cmp_parameters(a, b) == 0)
+		return 0;
+	if (BN_cmp(b->pkey.dh->pub_key, a->pkey.dh->pub_key) != 0)
+		return 0;
+	else
+		return 1;
+}
+
+static int
+dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
+{
+	return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 0);
+}
+
+static int
+dh_public_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
+{
+	return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 1);
+}
+
+static int
+dh_private_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
+{
+	return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 2);
+}
+
+int
+DHparams_print(BIO *bp, const DH *x)
+{
+	return do_dh_print(bp, x, 4, NULL, 0);
+}
+
+const EVP_PKEY_ASN1_METHOD dh_asn1_meth = {
+	.pkey_id = EVP_PKEY_DH,
+	.pkey_base_id = EVP_PKEY_DH,
+
+	.pem_str = "DH",
+	.info = "OpenSSL PKCS#3 DH method",
+
+	.pub_decode = dh_pub_decode,
+	.pub_encode = dh_pub_encode,
+	.pub_cmp = dh_pub_cmp,
+	.pub_print = dh_public_print,
+
+	.priv_decode = dh_priv_decode,
+	.priv_encode = dh_priv_encode,
+	.priv_print = dh_private_print,
+
+	.pkey_size = int_dh_size,
+	.pkey_bits = dh_bits,
+
+	.param_decode = dh_param_decode,
+	.param_encode = dh_param_encode,
+	.param_missing = dh_missing_parameters,
+	.param_copy = dh_copy_parameters,
+	.param_cmp = dh_cmp_parameters,
+	.param_print = dh_param_print,
+
+	.pkey_free = int_dh_free,
+};
diff --git a/crypto/libressl/crypto/dh/dh_asn1.c b/crypto/libressl/crypto/dh/dh_asn1.c
new file mode 100644
index 0000000000..22b43892b4
--- /dev/null
+++ b/crypto/libressl/crypto/dh/dh_asn1.c
@@ -0,0 +1,143 @@
+/* $OpenBSD: dh_asn1.c,v 1.7 2015/02/10 05:12:23 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+/* Override the default free and new methods */
+static int
+dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
+{
+	if (operation == ASN1_OP_NEW_PRE) {
+		*pval = (ASN1_VALUE *)DH_new();
+		if (*pval)
+			return 2;
+		return 0;
+	} else if (operation == ASN1_OP_FREE_PRE) {
+		DH_free((DH *)*pval);
+		*pval = NULL;
+		return 2;
+	}
+	return 1;
+}
+
+static const ASN1_AUX DHparams_aux = {
+	.app_data = NULL,
+	.flags = 0,
+	.ref_offset = 0,
+	.ref_lock = 0,
+	.asn1_cb = dh_cb,
+	.enc_offset = 0,
+};
+static const ASN1_TEMPLATE DHparams_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(DH, p),
+		.field_name = "p",
+		.item = &BIGNUM_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(DH, g),
+		.field_name = "g",
+		.item = &BIGNUM_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(DH, length),
+		.field_name = "length",
+		.item = &ZLONG_it,
+	},
+};
+
+const ASN1_ITEM DHparams_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = DHparams_seq_tt,
+	.tcount = sizeof(DHparams_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &DHparams_aux,
+	.size = sizeof(DH),
+	.sname = "DH",
+};
+
+
+DH *
+d2i_DHparams(DH **a, const unsigned char **in, long len)
+{
+	return (DH *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &DHparams_it);
+}
+
+int
+i2d_DHparams(const DH *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &DHparams_it);
+}
+
+DH *
+DHparams_dup(DH *dh)
+{
+	return ASN1_item_dup(ASN1_ITEM_rptr(DHparams), dh);
+}
diff --git a/crypto/libressl/crypto/dh/dh_check.c b/crypto/libressl/crypto/dh/dh_check.c
new file mode 100644
index 0000000000..3d700d7419
--- /dev/null
+++ b/crypto/libressl/crypto/dh/dh_check.c
@@ -0,0 +1,139 @@
+/* $OpenBSD: dh_check.c,v 1.15 2015/02/07 13:19:15 doug Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+
+/*
+ * Check that p is a safe prime and
+ * if g is 2, 3 or 5, check that it is a suitable generator
+ * where
+ * for 2, p mod 24 == 11
+ * for 3, p mod 12 == 5
+ * for 5, p mod 10 == 3 or 7
+ * should hold.
+ */
+
+int
+DH_check(const DH *dh, int *ret)
+{
+	int ok = 0;
+	BN_CTX *ctx = NULL;
+	BN_ULONG l;
+	BIGNUM *q = NULL;
+
+	*ret = 0;
+	ctx = BN_CTX_new();
+	if (ctx == NULL)
+		goto err;
+	q = BN_new();
+	if (q == NULL)
+		goto err;
+
+	if (BN_is_word(dh->g, DH_GENERATOR_2)) {
+		l = BN_mod_word(dh->p, 24);
+		if (l == (BN_ULONG)-1)
+			goto err;
+		if (l != 11)
+			*ret |= DH_NOT_SUITABLE_GENERATOR;
+	} else if (BN_is_word(dh->g, DH_GENERATOR_5)) {
+		l = BN_mod_word(dh->p, 10);
+		if (l == (BN_ULONG)-1)
+			goto err;
+		if (l != 3 && l != 7)
+			*ret |= DH_NOT_SUITABLE_GENERATOR;
+	} else
+		*ret |= DH_UNABLE_TO_CHECK_GENERATOR;
+
+	if (!BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL))
+		*ret |= DH_CHECK_P_NOT_PRIME;
+	else {
+		if (!BN_rshift1(q, dh->p))
+			goto err;
+		if (!BN_is_prime_ex(q, BN_prime_checks, ctx, NULL))
+			*ret |= DH_CHECK_P_NOT_SAFE_PRIME;
+	}
+	ok = 1;
+err:
+	BN_CTX_free(ctx);
+	BN_free(q);
+	return ok;
+}
+
+int
+DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
+{
+	BIGNUM *q = NULL;
+
+	*ret = 0;
+	q = BN_new();
+	if (q == NULL)
+		return 0;
+	BN_set_word(q, 1);
+	if (BN_cmp(pub_key, q) <= 0)
+		*ret |= DH_CHECK_PUBKEY_TOO_SMALL;
+	BN_copy(q, dh->p);
+	BN_sub_word(q, 1);
+	if (BN_cmp(pub_key, q) >= 0)
+		*ret |= DH_CHECK_PUBKEY_TOO_LARGE;
+
+	BN_free(q);
+	return 1;
+}
diff --git a/crypto/libressl/crypto/dh/dh_depr.c b/crypto/libressl/crypto/dh/dh_depr.c
new file mode 100644
index 0000000000..2f66bdc515
--- /dev/null
+++ b/crypto/libressl/crypto/dh/dh_depr.c
@@ -0,0 +1,83 @@
+/* $OpenBSD: dh_depr.c,v 1.5 2014/07/10 22:45:56 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* This file contains deprecated functions as wrappers to the new ones */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+#ifndef OPENSSL_NO_DEPRECATED
+DH *
+DH_generate_parameters(int prime_len, int generator,
+    void (*callback)(int, int, void *), void *cb_arg)
+{
+	BN_GENCB cb;
+	DH *ret = NULL;
+
+	if ((ret = DH_new()) == NULL)
+		return NULL;
+
+	BN_GENCB_set_old(&cb, callback, cb_arg);
+
+	if (DH_generate_parameters_ex(ret, prime_len, generator, &cb))
+		return ret;
+	DH_free(ret);
+	return NULL;
+}
+#endif
diff --git a/crypto/libressl/crypto/dh/dh_err.c b/crypto/libressl/crypto/dh/dh_err.c
new file mode 100644
index 0000000000..631330564f
--- /dev/null
+++ b/crypto/libressl/crypto/dh/dh_err.c
@@ -0,0 +1,125 @@
+/* $OpenBSD: dh_err.c,v 1.14 2014/06/12 15:49:28 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2011 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_DH,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_DH,0,reason)
+
+static ERR_STRING_DATA DH_str_functs[]=
+	{
+{ERR_FUNC(DH_F_COMPUTE_KEY),	"COMPUTE_KEY"},
+{ERR_FUNC(DH_F_DHPARAMS_PRINT_FP),	"DHparams_print_fp"},
+{ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS),	"DH_BUILTIN_GENPARAMS"},
+{ERR_FUNC(DH_F_DH_COMPUTE_KEY),	"DH_compute_key"},
+{ERR_FUNC(DH_F_DH_GENERATE_KEY),	"DH_generate_key"},
+{ERR_FUNC(DH_F_DH_GENERATE_PARAMETERS_EX),	"DH_generate_parameters_ex"},
+{ERR_FUNC(DH_F_DH_NEW_METHOD),	"DH_new_method"},
+{ERR_FUNC(DH_F_DH_PARAM_DECODE),	"DH_PARAM_DECODE"},
+{ERR_FUNC(DH_F_DH_PRIV_DECODE),	"DH_PRIV_DECODE"},
+{ERR_FUNC(DH_F_DH_PRIV_ENCODE),	"DH_PRIV_ENCODE"},
+{ERR_FUNC(DH_F_DH_PUB_DECODE),	"DH_PUB_DECODE"},
+{ERR_FUNC(DH_F_DH_PUB_ENCODE),	"DH_PUB_ENCODE"},
+{ERR_FUNC(DH_F_DO_DH_PRINT),	"DO_DH_PRINT"},
+{ERR_FUNC(DH_F_GENERATE_KEY),	"GENERATE_KEY"},
+{ERR_FUNC(DH_F_GENERATE_PARAMETERS),	"GENERATE_PARAMETERS"},
+{ERR_FUNC(DH_F_PKEY_DH_DERIVE),	"PKEY_DH_DERIVE"},
+{ERR_FUNC(DH_F_PKEY_DH_KEYGEN),	"PKEY_DH_KEYGEN"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA DH_str_reasons[]=
+	{
+{ERR_REASON(DH_R_BAD_GENERATOR)          ,"bad generator"},
+{ERR_REASON(DH_R_BN_DECODE_ERROR)        ,"bn decode error"},
+{ERR_REASON(DH_R_BN_ERROR)               ,"bn error"},
+{ERR_REASON(DH_R_DECODE_ERROR)           ,"decode error"},
+{ERR_REASON(DH_R_INVALID_PUBKEY)         ,"invalid public key"},
+{ERR_REASON(DH_R_KEYS_NOT_SET)           ,"keys not set"},
+{ERR_REASON(DH_R_KEY_SIZE_TOO_SMALL)     ,"key size too small"},
+{ERR_REASON(DH_R_MODULUS_TOO_LARGE)      ,"modulus too large"},
+{ERR_REASON(DH_R_NON_FIPS_METHOD)        ,"non fips method"},
+{ERR_REASON(DH_R_NO_PARAMETERS_SET)      ,"no parameters set"},
+{ERR_REASON(DH_R_NO_PRIVATE_VALUE)       ,"no private value"},
+{ERR_REASON(DH_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_DH_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(DH_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,DH_str_functs);
+		ERR_load_strings(0,DH_str_reasons);
+		}
+#endif
+	}
diff --git a/crypto/libressl/crypto/dh/dh_gen.c b/crypto/libressl/crypto/dh/dh_gen.c
new file mode 100644
index 0000000000..53940d848e
--- /dev/null
+++ b/crypto/libressl/crypto/dh/dh_gen.c
@@ -0,0 +1,179 @@
+/* $OpenBSD: dh_gen.c,v 1.14 2015/02/07 13:19:15 doug Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* NB: These functions have been upgraded - the previous prototypes are in
+ * dh_depr.c as wrappers to these ones.
+ *  - Geoff
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
+	    BN_GENCB *cb);
+
+int
+DH_generate_parameters_ex(DH *ret, int prime_len, int generator, BN_GENCB *cb)
+{
+	if (ret->meth->generate_params)
+		return ret->meth->generate_params(ret, prime_len, generator, cb);
+	return dh_builtin_genparams(ret, prime_len, generator, cb);
+}
+
+/*
+ * We generate DH parameters as follows:
+ * find a prime q which is prime_len/2 bits long.
+ * p=(2*q)+1 or (p-1)/2 = q
+ * For this case, g is a generator if
+ * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1.
+ * Since the factors of p-1 are q and 2, we just need to check
+ * g^2 mod p != 1 and g^q mod p != 1.
+ *
+ * Having said all that,
+ * there is another special case method for the generators 2, 3 and 5.
+ * for 2, p mod 24 == 11
+ * for 3, p mod 12 == 5  <<<<< does not work for safe primes.
+ * for 5, p mod 10 == 3 or 7
+ *
+ * Thanks to Phil Karn  for the pointers about the
+ * special generators and for answering some of my questions.
+ *
+ * I've implemented the second simple method :-).
+ * Since DH should be using a safe prime (both p and q are prime),
+ * this generator function can take a very very long time to run.
+ */
+/* Actually there is no reason to insist that 'generator' be a generator.
+ * It's just as OK (and in some sense better) to use a generator of the
+ * order-q subgroup.
+ */
+static int
+dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb)
+{
+	BIGNUM *t1, *t2;
+	int g, ok = -1;
+	BN_CTX *ctx = NULL;
+
+	ctx = BN_CTX_new();
+	if (ctx == NULL)
+		goto err;
+	BN_CTX_start(ctx);
+	if ((t1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((t2 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	/* Make sure 'ret' has the necessary elements */
+	if (!ret->p && ((ret->p = BN_new()) == NULL))
+		goto err;
+	if (!ret->g && ((ret->g = BN_new()) == NULL))
+		goto err;
+	
+	if (generator <= 1) {
+		DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
+		goto err;
+	}
+	if (generator == DH_GENERATOR_2) {
+		if (!BN_set_word(t1, 24))
+			goto err;
+		if (!BN_set_word(t2, 11))
+			goto err;
+		g = 2;
+	} else if (generator == DH_GENERATOR_5) {
+		if (!BN_set_word(t1, 10))
+			goto err;
+		if (!BN_set_word(t2, 3))
+			goto err;
+		/* BN_set_word(t3,7); just have to miss
+		 * out on these ones :-( */
+		g = 5;
+	} else {
+		/*
+		 * in the general case, don't worry if 'generator' is a
+		 * generator or not: since we are using safe primes,
+		 * it will generate either an order-q or an order-2q group,
+		 * which both is OK
+		 */
+		if (!BN_set_word(t1, 2))
+			goto err;
+		if (!BN_set_word(t2, 1))
+			goto err;
+		g = generator;
+	}
+	
+	if (!BN_generate_prime_ex(ret->p, prime_len, 1, t1, t2, cb))
+		goto err;
+	if (!BN_GENCB_call(cb, 3, 0))
+		goto err;
+	if (!BN_set_word(ret->g, g))
+		goto err;
+	ok = 1;
+err:
+	if (ok == -1) {
+		DHerr(DH_F_DH_BUILTIN_GENPARAMS, ERR_R_BN_LIB);
+		ok = 0;
+	}
+
+	if (ctx != NULL) {
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+	}
+	return ok;
+}
diff --git a/crypto/libressl/crypto/dh/dh_key.c b/crypto/libressl/crypto/dh/dh_key.c
new file mode 100644
index 0000000000..7f6b538f29
--- /dev/null
+++ b/crypto/libressl/crypto/dh/dh_key.c
@@ -0,0 +1,251 @@
+/* $OpenBSD: dh_key.c,v 1.24 2016/06/30 02:02:06 bcook Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+static int generate_key(DH *dh);
+static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
+static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, const BIGNUM *a,
+	    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+static int dh_init(DH *dh);
+static int dh_finish(DH *dh);
+
+int
+DH_generate_key(DH *dh)
+{
+	return dh->meth->generate_key(dh);
+}
+
+int
+DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+{
+	return dh->meth->compute_key(key, pub_key, dh);
+}
+
+static DH_METHOD dh_ossl = {
+	.name = "OpenSSL DH Method",
+	.generate_key = generate_key,
+	.compute_key = compute_key,
+	.bn_mod_exp = dh_bn_mod_exp,
+	.init = dh_init,
+	.finish = dh_finish,
+};
+
+const DH_METHOD *
+DH_OpenSSL(void)
+{
+	return &dh_ossl;
+}
+
+static int
+generate_key(DH *dh)
+{
+	int ok = 0;
+	int generate_new_key = 0;
+	unsigned l;
+	BN_CTX *ctx;
+	BN_MONT_CTX *mont = NULL;
+	BIGNUM *pub_key = NULL, *priv_key = NULL;
+
+	ctx = BN_CTX_new();
+	if (ctx == NULL)
+		goto err;
+
+	if (dh->priv_key == NULL) {
+		priv_key = BN_new();
+		if (priv_key == NULL)
+			goto err;
+		generate_new_key = 1;
+	} else
+		priv_key = dh->priv_key;
+
+	if (dh->pub_key == NULL) {
+		pub_key = BN_new();
+		if (pub_key == NULL)
+			goto err;
+	} else
+		pub_key = dh->pub_key;
+
+	if (dh->flags & DH_FLAG_CACHE_MONT_P) {
+		mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
+		    CRYPTO_LOCK_DH, dh->p, ctx);
+		if (!mont)
+			goto err;
+	}
+
+	if (generate_new_key) {
+		if (dh->q) {
+			do {
+				if (!BN_rand_range(priv_key, dh->q))
+					goto err;
+			} while (BN_is_zero(priv_key) || BN_is_one(priv_key));
+		} else {
+			/* secret exponent length */
+			l = dh->length ? dh->length : BN_num_bits(dh->p) - 1;
+			if (!BN_rand(priv_key, l, 0, 0))
+				goto err;
+		}
+	}
+
+	{
+		BIGNUM prk;
+
+		BN_init(&prk);
+		BN_with_flags(&prk, priv_key, BN_FLG_CONSTTIME);
+
+		if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, &prk, dh->p, ctx,
+		    mont)) {
+			goto err;
+		}
+	}
+
+	dh->pub_key = pub_key;
+	dh->priv_key = priv_key;
+	ok = 1;
+err:
+	if (ok != 1)
+		DHerr(DH_F_GENERATE_KEY, ERR_R_BN_LIB);
+
+	if (pub_key != NULL && dh->pub_key == NULL)
+		BN_free(pub_key);
+	if (priv_key != NULL && dh->priv_key == NULL)
+		BN_free(priv_key);
+	BN_CTX_free(ctx);
+	return ok;
+}
+
+static int
+compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+{
+	BN_CTX *ctx = NULL;
+	BN_MONT_CTX *mont = NULL;
+	BIGNUM *tmp;
+	int ret = -1;
+        int check_result;
+
+	if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) {
+		DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_LARGE);
+		goto err;
+	}
+
+	ctx = BN_CTX_new();
+	if (ctx == NULL)
+		goto err;
+	BN_CTX_start(ctx);
+	if ((tmp = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	
+	if (dh->priv_key == NULL) {
+		DHerr(DH_F_COMPUTE_KEY, DH_R_NO_PRIVATE_VALUE);
+		goto err;
+	}
+
+	if (dh->flags & DH_FLAG_CACHE_MONT_P) {
+		mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
+		    CRYPTO_LOCK_DH, dh->p, ctx);
+
+		BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME);
+
+		if (!mont)
+			goto err;
+	}
+
+        if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) {
+		DHerr(DH_F_COMPUTE_KEY, DH_R_INVALID_PUBKEY);
+		goto err;
+	}
+
+	if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key, dh->p, ctx,
+	    mont)) {
+		DHerr(DH_F_COMPUTE_KEY, ERR_R_BN_LIB);
+		goto err;
+	}
+
+	ret = BN_bn2bin(tmp, key);
+err:
+	if (ctx != NULL) {
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+	}
+	return ret;
+}
+
+static int
+dh_bn_mod_exp(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+{
+	return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
+}
+
+static int
+dh_init(DH *dh)
+{
+	dh->flags |= DH_FLAG_CACHE_MONT_P;
+	return 1;
+}
+
+static int
+dh_finish(DH *dh)
+{
+	BN_MONT_CTX_free(dh->method_mont_p);
+	return 1;
+}
diff --git a/crypto/libressl/crypto/dh/dh_lib.c b/crypto/libressl/crypto/dh/dh_lib.c
new file mode 100644
index 0000000000..7db4547e55
--- /dev/null
+++ b/crypto/libressl/crypto/dh/dh_lib.c
@@ -0,0 +1,241 @@
+/* $OpenBSD: dh_lib.c,v 1.20 2014/07/12 16:03:37 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+
+static const DH_METHOD *default_DH_method = NULL;
+
+void
+DH_set_default_method(const DH_METHOD *meth)
+{
+	default_DH_method = meth;
+}
+
+const DH_METHOD *
+DH_get_default_method(void)
+{
+	if (!default_DH_method)
+		default_DH_method = DH_OpenSSL();
+	return default_DH_method;
+}
+
+int
+DH_set_method(DH *dh, const DH_METHOD *meth)
+{
+	/*
+	 * NB: The caller is specifically setting a method, so it's not up to us
+	 * to deal with which ENGINE it comes from.
+	 */
+        const DH_METHOD *mtmp;
+
+        mtmp = dh->meth;
+        if (mtmp->finish)
+		mtmp->finish(dh);
+#ifndef OPENSSL_NO_ENGINE
+	if (dh->engine) {
+		ENGINE_finish(dh->engine);
+		dh->engine = NULL;
+	}
+#endif
+        dh->meth = meth;
+        if (meth->init)
+		meth->init(dh);
+        return 1;
+}
+
+DH *
+DH_new(void)
+{
+	return DH_new_method(NULL);
+}
+
+DH *
+DH_new_method(ENGINE *engine)
+{
+	DH *ret;
+
+	ret = malloc(sizeof(DH));
+	if (ret == NULL) {
+		DHerr(DH_F_DH_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+
+	ret->meth = DH_get_default_method();
+#ifndef OPENSSL_NO_ENGINE
+	if (engine) {
+		if (!ENGINE_init(engine)) {
+			DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB);
+			free(ret);
+			return NULL;
+		}
+		ret->engine = engine;
+	} else
+		ret->engine = ENGINE_get_default_DH();
+	if(ret->engine) {
+		ret->meth = ENGINE_get_DH(ret->engine);
+		if (!ret->meth) {
+			DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB);
+			ENGINE_finish(ret->engine);
+			free(ret);
+			return NULL;
+		}
+	}
+#endif
+
+	ret->pad = 0;
+	ret->version = 0;
+	ret->p = NULL;
+	ret->g = NULL;
+	ret->length = 0;
+	ret->pub_key = NULL;
+	ret->priv_key = NULL;
+	ret->q = NULL;
+	ret->j = NULL;
+	ret->seed = NULL;
+	ret->seedlen = 0;
+	ret->counter = NULL;
+	ret->method_mont_p=NULL;
+	ret->references = 1;
+	ret->flags = ret->meth->flags & ~DH_FLAG_NON_FIPS_ALLOW;
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data);
+	if (ret->meth->init != NULL && !ret->meth->init(ret)) {
+#ifndef OPENSSL_NO_ENGINE
+		if (ret->engine)
+			ENGINE_finish(ret->engine);
+#endif
+		CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data);
+		free(ret);
+		ret = NULL;
+	}
+	return ret;
+}
+
+void
+DH_free(DH *r)
+{
+	int i;
+
+	if (r == NULL)
+		return;
+	i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_DH);
+	if (i > 0)
+		return;
+
+	if (r->meth->finish)
+		r->meth->finish(r);
+#ifndef OPENSSL_NO_ENGINE
+	if (r->engine)
+		ENGINE_finish(r->engine);
+#endif
+
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, r, &r->ex_data);
+
+	BN_clear_free(r->p);
+	BN_clear_free(r->g);
+	BN_clear_free(r->q);
+	BN_clear_free(r->j);
+	free(r->seed);
+	BN_clear_free(r->counter);
+	BN_clear_free(r->pub_key);
+	BN_clear_free(r->priv_key);
+	free(r);
+}
+
+int
+DH_up_ref(DH *r)
+{
+	int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DH);
+
+	return i > 1 ? 1 : 0;
+}
+
+int
+DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+    CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+{
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DH, argl, argp, new_func,
+	    dup_func, free_func);
+}
+
+int
+DH_set_ex_data(DH *d, int idx, void *arg)
+{
+	return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
+}
+
+void *
+DH_get_ex_data(DH *d, int idx)
+{
+	return CRYPTO_get_ex_data(&d->ex_data, idx);
+}
+
+int
+DH_size(const DH *dh)
+{
+	return BN_num_bytes(dh->p);
+}
diff --git a/crypto/libressl/crypto/dh/dh_pmeth.c b/crypto/libressl/crypto/dh/dh_pmeth.c
new file mode 100644
index 0000000000..7c5e983447
--- /dev/null
+++ b/crypto/libressl/crypto/dh/dh_pmeth.c
@@ -0,0 +1,264 @@
+/* $OpenBSD: dh_pmeth.c,v 1.8 2014/07/10 13:58:22 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+
+/* DH pkey context structure */
+
+typedef struct {
+	/* Parameter gen parameters */
+	int prime_len;
+	int generator;
+	int use_dsa;
+	/* Keygen callback info */
+	int gentmp[2];
+	/* message digest */
+} DH_PKEY_CTX;
+
+static int
+pkey_dh_init(EVP_PKEY_CTX *ctx)
+{
+	DH_PKEY_CTX *dctx;
+
+	dctx = malloc(sizeof(DH_PKEY_CTX));
+	if (!dctx)
+		return 0;
+	dctx->prime_len = 1024;
+	dctx->generator = 2;
+	dctx->use_dsa = 0;
+
+	ctx->data = dctx;
+	ctx->keygen_info = dctx->gentmp;
+	ctx->keygen_info_count = 2;
+	
+	return 1;
+}
+
+static int
+pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+{
+	DH_PKEY_CTX *dctx, *sctx;
+
+	if (!pkey_dh_init(dst))
+		return 0;
+       	sctx = src->data;
+	dctx = dst->data;
+	dctx->prime_len = sctx->prime_len;
+	dctx->generator = sctx->generator;
+	dctx->use_dsa = sctx->use_dsa;
+	return 1;
+}
+
+static void
+pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
+{
+	DH_PKEY_CTX *dctx = ctx->data;
+
+	free(dctx);
+}
+
+static int
+pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+	DH_PKEY_CTX *dctx = ctx->data;
+
+	switch (type) {
+	case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
+		if (p1 < 256)
+			return -2;
+		dctx->prime_len = p1;
+		return 1;
+
+	case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
+		dctx->generator = p1;
+		return 1;
+
+	case EVP_PKEY_CTRL_PEER_KEY:
+		/* Default behaviour is OK */
+		return 1;
+
+	default:
+		return -2;
+	}
+}
+			
+static int
+pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value)
+{
+ 	long lval;
+	char *ep;
+	int len;
+
+	if (!strcmp(type, "dh_paramgen_prime_len")) {
+		errno = 0;
+		lval = strtol(value, &ep, 10);
+		if (value[0] == '\0' || *ep != '\0')
+			goto not_a_number;
+		if ((errno == ERANGE &&
+		    (lval == LONG_MAX || lval == LONG_MIN)) ||
+		    (lval > INT_MAX || lval < INT_MIN))
+			goto out_of_range;
+		len = lval;
+		return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
+	} else if (!strcmp(type, "dh_paramgen_generator")) {
+		errno = 0;
+		lval = strtol(value, &ep, 10);
+		if (value[0] == '\0' || *ep != '\0')
+			goto not_a_number;
+		if ((errno == ERANGE &&
+		    (lval == LONG_MAX || lval == LONG_MIN)) ||
+		    (lval > INT_MAX || lval < INT_MIN))
+			goto out_of_range;
+		len = lval;
+		return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
+	}
+
+not_a_number:
+out_of_range:
+	return -2;
+}
+
+static int
+pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+	DH *dh = NULL;
+	DH_PKEY_CTX *dctx = ctx->data;
+	BN_GENCB *pcb, cb;
+	int ret;
+
+	if (ctx->pkey_gencb) {
+		pcb = &cb;
+		evp_pkey_set_cb_translate(pcb, ctx);
+	} else
+		pcb = NULL;
+	dh = DH_new();
+	if (!dh)
+		return 0;
+	ret = DH_generate_parameters_ex(dh, dctx->prime_len, dctx->generator,
+	    pcb);
+	if (ret)
+		EVP_PKEY_assign_DH(pkey, dh);
+	else
+		DH_free(dh);
+	return ret;
+}
+
+static int
+pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+	DH *dh = NULL;
+
+	if (ctx->pkey == NULL) {
+		DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
+		return 0;
+	}
+	dh = DH_new();
+	if (!dh)
+		return 0;
+	EVP_PKEY_assign_DH(pkey, dh);
+	/* Note: if error return, pkey is freed by parent routine */
+	if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
+		return 0;
+	return DH_generate_key(pkey->pkey.dh);
+}
+
+static int
+pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
+{
+	int ret;
+
+	if (!ctx->pkey || !ctx->peerkey) {
+		DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
+		return 0;
+	}
+	ret = DH_compute_key(key, ctx->peerkey->pkey.dh->pub_key,
+	    ctx->pkey->pkey.dh);
+	if (ret < 0)
+		return ret;
+	*keylen = ret;
+	return 1;
+}
+
+const EVP_PKEY_METHOD dh_pkey_meth = {
+	.pkey_id = EVP_PKEY_DH,
+	.flags = EVP_PKEY_FLAG_AUTOARGLEN,
+
+	.init = pkey_dh_init,
+	.copy = pkey_dh_copy,
+	.cleanup = pkey_dh_cleanup,
+
+	.paramgen = pkey_dh_paramgen,
+
+	.keygen = pkey_dh_keygen,
+
+	.derive = pkey_dh_derive,
+
+	.ctrl = pkey_dh_ctrl,
+	.ctrl_str = pkey_dh_ctrl_str
+};
diff --git a/crypto/libressl/crypto/dh/dh_prn.c b/crypto/libressl/crypto/dh/dh_prn.c
new file mode 100644
index 0000000000..aec7c680d8
--- /dev/null
+++ b/crypto/libressl/crypto/dh/dh_prn.c
@@ -0,0 +1,79 @@
+/* $OpenBSD: dh_prn.c,v 1.4 2014/07/09 13:26:47 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+int
+DHparams_print_fp(FILE *fp, const DH *x)
+{
+	BIO *b;
+	int ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL) {
+		DHerr(DH_F_DHPARAMS_PRINT_FP, ERR_R_BUF_LIB);
+		return 0;
+	}
+	BIO_set_fp(b,fp,BIO_NOCLOSE);
+	ret = DHparams_print(b, x);
+	BIO_free(b);
+	return ret;
+}
diff --git a/crypto/libressl/crypto/dsa/dsa_ameth.c b/crypto/libressl/crypto/dsa/dsa_ameth.c
new file mode 100644
index 0000000000..43dbe48359
--- /dev/null
+++ b/crypto/libressl/crypto/dsa/dsa_ameth.c
@@ -0,0 +1,698 @@
+/* $OpenBSD: dsa_ameth.c,v 1.18 2015/09/10 18:12:55 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_CMS
+#include 
+#endif
+
+#include "asn1_locl.h"
+
+static int
+dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+{
+	const unsigned char *p, *pm;
+	int pklen, pmlen;
+	int ptype;
+	void *pval;
+	ASN1_STRING *pstr;
+	X509_ALGOR *palg;
+	ASN1_INTEGER *public_key = NULL;
+
+	DSA *dsa = NULL;
+
+	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
+		return 0;
+	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+	if (ptype == V_ASN1_SEQUENCE) {
+		pstr = pval;	
+		pm = pstr->data;
+		pmlen = pstr->length;
+
+		if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) {
+			DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
+			goto err;
+		}
+	} else if (ptype == V_ASN1_NULL || ptype == V_ASN1_UNDEF) {
+		if (!(dsa = DSA_new())) {
+			DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+	} else {
+		DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR);
+		goto err;
+	}
+
+	if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen))) {
+		DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
+		goto err;
+	}
+
+	if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) {
+		DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR);
+		goto err;
+	}
+
+	ASN1_INTEGER_free(public_key);
+	EVP_PKEY_assign_DSA(pkey, dsa);
+	return 1;
+
+err:
+	if (public_key)
+		ASN1_INTEGER_free(public_key);
+	DSA_free(dsa);
+	return 0;
+}
+
+static int
+dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
+{
+	DSA *dsa;
+	void *pval = NULL;
+	int ptype;
+	unsigned char *penc = NULL;
+	int penclen;
+
+	dsa = pkey->pkey.dsa;
+	if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) {
+		ASN1_STRING *str;
+
+		str = ASN1_STRING_new();
+		if (str == NULL) {
+			DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		str->length = i2d_DSAparams(dsa, &str->data);
+		if (str->length <= 0) {
+			DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+			ASN1_STRING_free(str);
+			goto err;
+		}
+		pval = str;
+		ptype = V_ASN1_SEQUENCE;
+	} else
+		ptype = V_ASN1_UNDEF;
+
+	dsa->write_params = 0;
+
+	penclen = i2d_DSAPublicKey(dsa, &penc);
+
+	if (penclen <= 0) {
+		DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), ptype, pval,
+	    penc, penclen))
+		return 1;
+
+err:
+	free(penc);
+	ASN1_STRING_free(pval);
+
+	return 0;
+}
+
+/* In PKCS#8 DSA: you just get a private key integer and parameters in the
+ * AlgorithmIdentifier the pubkey must be recalculated.
+ */
+static int
+dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
+{
+	const unsigned char *p, *pm;
+	int pklen, pmlen;
+	int ptype;
+	void *pval;
+	ASN1_STRING *pstr;
+	X509_ALGOR *palg;
+	ASN1_INTEGER *privkey = NULL;
+	BN_CTX *ctx = NULL;
+	DSA *dsa = NULL;
+
+	int ret = 0;
+
+	if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
+		return 0;
+	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+	if (ptype != V_ASN1_SEQUENCE)
+		goto decerr;
+
+	if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL)
+		goto decerr;
+	if (privkey->type == V_ASN1_NEG_INTEGER)
+		goto decerr;
+
+	pstr = pval;
+	pm = pstr->data;
+	pmlen = pstr->length;
+	if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen)))
+		goto decerr;
+	/* We have parameters now set private key */
+	if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) {
+		DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR);
+		goto dsaerr;
+	}
+	/* Calculate public key */
+	if (!(dsa->pub_key = BN_new())) {
+		DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
+		goto dsaerr;
+	}
+	if (!(ctx = BN_CTX_new())) {
+		DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
+		goto dsaerr;
+	}
+
+	if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) {
+		DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR);
+		goto dsaerr;
+	}
+
+	if (!EVP_PKEY_assign_DSA(pkey, dsa))
+		goto decerr;
+
+	ret = 1;
+	goto done;
+
+decerr:
+	DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_DECODE_ERROR);
+dsaerr:
+	DSA_free(dsa);
+done:
+	BN_CTX_free(ctx);
+	ASN1_INTEGER_free(privkey);
+	return ret;
+}
+
+static int
+dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
+{
+	ASN1_STRING *params = NULL;
+	ASN1_INTEGER *prkey = NULL;
+	unsigned char *dp = NULL;
+	int dplen;
+
+	params = ASN1_STRING_new();
+	if (!params) {
+		DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	params->length = i2d_DSAparams(pkey->pkey.dsa, ¶ms->data);
+	if (params->length <= 0) {
+		DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	params->type = V_ASN1_SEQUENCE;
+
+	/* Get private key into integer */
+	prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);
+	if (!prkey) {
+		DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_BN_ERROR);
+		goto err;
+	}
+
+	dplen = i2d_ASN1_INTEGER(prkey, &dp);
+
+	ASN1_INTEGER_free(prkey);
+	prkey = NULL;
+
+	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0, V_ASN1_SEQUENCE,
+	    params, dp, dplen))
+		goto err;
+
+	return 1;
+
+err:
+	free(dp);
+	ASN1_STRING_free(params);
+	ASN1_INTEGER_free(prkey);
+	return 0;
+}
+
+static int
+int_dsa_size(const EVP_PKEY *pkey)
+{
+	return DSA_size(pkey->pkey.dsa);
+}
+
+static int
+dsa_bits(const EVP_PKEY *pkey)
+{
+	return BN_num_bits(pkey->pkey.dsa->p);
+}
+
+static int
+dsa_missing_parameters(const EVP_PKEY *pkey)
+{
+	DSA *dsa;
+
+	dsa = pkey->pkey.dsa;
+	if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL)
+		return 1;
+	return 0;
+}
+
+static int
+dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+{
+	BIGNUM *a;
+
+	if ((a = BN_dup(from->pkey.dsa->p)) == NULL)
+		return 0;
+	BN_free(to->pkey.dsa->p);
+	to->pkey.dsa->p = a;
+
+	if ((a = BN_dup(from->pkey.dsa->q)) == NULL)
+		return 0;
+	BN_free(to->pkey.dsa->q);
+	to->pkey.dsa->q = a;
+
+	if ((a = BN_dup(from->pkey.dsa->g)) == NULL)
+		return 0;
+	BN_free(to->pkey.dsa->g);
+	to->pkey.dsa->g = a;
+	return 1;
+}
+
+static int
+dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+	if (BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) ||
+	    BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) ||
+	    BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g))
+		return 0;
+	else
+		return 1;
+}
+
+static int
+dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+	if (BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) != 0)
+		return 0;
+	else
+		return 1;
+}
+
+static void
+int_dsa_free(EVP_PKEY *pkey)
+{
+	DSA_free(pkey->pkey.dsa);
+}
+
+static void
+update_buflen(const BIGNUM *b, size_t *pbuflen)
+{
+	size_t i;
+
+	if (!b)
+		return;
+	if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
+		*pbuflen = i;
+}
+
+static int
+do_dsa_print(BIO *bp, const DSA *x, int off, int ptype)
+{
+	unsigned char *m = NULL;
+	int ret = 0;
+	size_t buf_len = 0;
+	const char *ktype = NULL;
+	const BIGNUM *priv_key, *pub_key;
+
+	if (ptype == 2)
+		priv_key = x->priv_key;
+	else
+		priv_key = NULL;
+
+	if (ptype > 0)
+		pub_key = x->pub_key;
+	else
+		pub_key = NULL;
+
+	if (ptype == 2)
+		ktype = "Private-Key";
+	else if (ptype == 1)
+		ktype = "Public-Key";
+	else
+		ktype = "DSA-Parameters";
+
+	update_buflen(x->p, &buf_len);
+	update_buflen(x->q, &buf_len);
+	update_buflen(x->g, &buf_len);
+	update_buflen(priv_key, &buf_len);
+	update_buflen(pub_key, &buf_len);
+
+	m = malloc(buf_len + 10);
+	if (m == NULL) {
+		DSAerr(DSA_F_DO_DSA_PRINT, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	if (priv_key) {
+		if (!BIO_indent(bp, off, 128))
+			goto err;
+		if (BIO_printf(bp, "%s: (%d bit)\n", ktype,
+		    BN_num_bits(x->p)) <= 0)
+			goto err;
+	}
+
+	if (!ASN1_bn_print(bp, "priv:", priv_key, m, off))
+		goto err;
+	if (!ASN1_bn_print(bp, "pub: ", pub_key, m, off))
+		goto err;
+	if (!ASN1_bn_print(bp, "P:   ", x->p, m, off))
+		goto err;
+	if (!ASN1_bn_print(bp, "Q:   ", x->q, m, off))
+		goto err;
+	if (!ASN1_bn_print(bp, "G:   ", x->g, m, off))
+		goto err;
+	ret = 1;
+err:
+	free(m);
+	return(ret);
+}
+
+static int
+dsa_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
+{
+	DSA *dsa;
+
+	if (!(dsa = d2i_DSAparams(NULL, pder, derlen))) {
+		DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB);
+		return 0;
+	}
+	EVP_PKEY_assign_DSA(pkey, dsa);
+	return 1;
+}
+
+static int
+dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
+{
+	return i2d_DSAparams(pkey->pkey.dsa, pder);
+}
+
+static int
+dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
+{
+	return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
+}
+
+static int
+dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
+{
+	return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
+}
+
+static int
+dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
+{
+	return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
+}
+
+static int
+old_dsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
+{
+	DSA *dsa;
+	BN_CTX *ctx = NULL;
+	BIGNUM *j, *p1, *newp1;
+
+	if (!(dsa = d2i_DSAPrivateKey(NULL, pder, derlen))) {
+		DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB);
+		return 0;
+	}
+
+	ctx = BN_CTX_new();
+	if (ctx == NULL)
+		goto err;
+
+	/*
+	 * Check that p and q are consistent with each other.
+	 */
+
+	j = BN_CTX_get(ctx);
+	p1 = BN_CTX_get(ctx);
+	newp1 = BN_CTX_get(ctx);
+	if (j == NULL || p1 == NULL || newp1 == NULL)
+		goto err;
+	/* p1 = p - 1 */
+	if (BN_sub(p1, dsa->p, BN_value_one()) == 0)
+		goto err;
+	/* j = (p - 1) / q */
+	if (BN_div(j, NULL, p1, dsa->q, ctx) == 0)
+		goto err;
+	/* q * j should == p - 1 */
+	if (BN_mul(newp1, dsa->q, j, ctx) == 0)
+		goto err;
+	if (BN_cmp(newp1, p1) != 0) {
+		DSAerr(DSA_F_DSA_PARAM_DECODE, DSA_R_BAD_Q_VALUE);
+		goto err;
+	}
+
+	/*
+	 * Check that q is not a composite number.
+	 */
+
+	if (BN_is_prime_ex(dsa->q, BN_prime_checks, ctx, NULL) == 0) {
+		DSAerr(DSA_F_DSA_PARAM_DECODE, DSA_R_BAD_Q_VALUE);
+		goto err;
+	}
+
+	BN_CTX_free(ctx);
+
+	EVP_PKEY_assign_DSA(pkey, dsa);
+	return 1;
+
+err:
+	BN_CTX_free(ctx);
+	DSA_free(dsa);
+	return 0;
+}
+
+static int
+old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
+{
+	return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
+}
+
+static int
+dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig,
+    int indent, ASN1_PCTX *pctx)
+{
+	DSA_SIG *dsa_sig;
+	const unsigned char *p;
+
+	if (!sig) {
+		if (BIO_puts(bp, "\n") <= 0)
+			return 0;
+		else
+			return 1;
+	}
+	p = sig->data;
+	dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length);
+	if (dsa_sig) {
+		int rv = 0;
+		size_t buf_len = 0;
+		unsigned char *m = NULL;
+
+		update_buflen(dsa_sig->r, &buf_len);
+		update_buflen(dsa_sig->s, &buf_len);
+		m = malloc(buf_len + 10);
+		if (m == NULL) {
+			DSAerr(DSA_F_DSA_SIG_PRINT, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+
+		if (BIO_write(bp, "\n", 1) != 1)
+			goto err;
+
+		if (!ASN1_bn_print(bp, "r:   ", dsa_sig->r, m, indent))
+			goto err;
+		if (!ASN1_bn_print(bp, "s:   ", dsa_sig->s, m, indent))
+			goto err;
+		rv = 1;
+err:
+		free(m);
+		DSA_SIG_free(dsa_sig);
+		return rv;
+	}
+	return X509_signature_dump(bp, sig, indent);
+}
+
+static int
+dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+{
+	switch (op) {
+	case ASN1_PKEY_CTRL_PKCS7_SIGN:
+		if (arg1 == 0) {
+			int snid, hnid;
+			X509_ALGOR *alg1, *alg2;
+
+			PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
+			if (alg1 == NULL || alg1->algorithm == NULL)
+				return -1;
+			hnid = OBJ_obj2nid(alg1->algorithm);
+			if (hnid == NID_undef)
+				return -1;
+			if (!OBJ_find_sigid_by_algs(&snid, hnid,
+			    EVP_PKEY_id(pkey)))
+				return -1; 
+			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF,
+			    0);
+		}
+		return 1;
+#ifndef OPENSSL_NO_CMS
+	case ASN1_PKEY_CTRL_CMS_SIGN:
+		if (arg1 == 0) {
+			int snid, hnid;
+			X509_ALGOR *alg1, *alg2;
+
+			CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
+			if (alg1 == NULL || alg1->algorithm == NULL)
+				return -1;
+			hnid = OBJ_obj2nid(alg1->algorithm);
+			if (hnid == NID_undef)
+				return -1;
+			if (!OBJ_find_sigid_by_algs(&snid, hnid,
+			    EVP_PKEY_id(pkey)))
+				return -1; 
+			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF,
+			    0);
+		}
+		return 1;
+#endif
+
+	case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+		*(int *)arg2 = NID_sha1;
+		return 2;
+
+	default:
+		return -2;
+	}
+}
+
+/* NB these are sorted in pkey_id order, lowest first */
+
+const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = {
+	{
+		.pkey_id = EVP_PKEY_DSA2,
+		.pkey_base_id = EVP_PKEY_DSA,
+		.pkey_flags = ASN1_PKEY_ALIAS
+	},
+
+	{
+		.pkey_id = EVP_PKEY_DSA1,
+		.pkey_base_id = EVP_PKEY_DSA,
+		.pkey_flags = ASN1_PKEY_ALIAS
+	},
+
+	{
+		.pkey_id = EVP_PKEY_DSA4,
+		.pkey_base_id = EVP_PKEY_DSA,
+		.pkey_flags = ASN1_PKEY_ALIAS
+	},
+
+	{
+		.pkey_id = EVP_PKEY_DSA3,
+		.pkey_base_id = EVP_PKEY_DSA,
+		.pkey_flags = ASN1_PKEY_ALIAS
+	},
+
+	{
+		.pkey_id = EVP_PKEY_DSA,
+		.pkey_base_id = EVP_PKEY_DSA,
+
+		.pem_str = "DSA",
+		.info = "OpenSSL DSA method",
+
+		.pub_decode = dsa_pub_decode,
+		.pub_encode = dsa_pub_encode,
+		.pub_cmp = dsa_pub_cmp,
+		.pub_print = dsa_pub_print,
+
+		.priv_decode = dsa_priv_decode,
+		.priv_encode = dsa_priv_encode,
+		.priv_print = dsa_priv_print,
+
+		.pkey_size = int_dsa_size,
+		.pkey_bits = dsa_bits,
+
+		.param_decode = dsa_param_decode,
+		.param_encode = dsa_param_encode,
+		.param_missing = dsa_missing_parameters,
+		.param_copy = dsa_copy_parameters,
+		.param_cmp = dsa_cmp_parameters,
+		.param_print = dsa_param_print,
+		.sig_print = dsa_sig_print,
+
+		.pkey_free = int_dsa_free,
+		.pkey_ctrl = dsa_pkey_ctrl,
+		.old_priv_decode = old_dsa_priv_decode,
+		.old_priv_encode = old_dsa_priv_encode
+	}
+};
diff --git a/crypto/libressl/crypto/dsa/dsa_asn1.c b/crypto/libressl/crypto/dsa/dsa_asn1.c
new file mode 100644
index 0000000000..e2035164fc
--- /dev/null
+++ b/crypto/libressl/crypto/dsa/dsa_asn1.c
@@ -0,0 +1,439 @@
+/* $OpenBSD: dsa_asn1.c,v 1.15 2015/02/10 05:12:23 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+/* Override the default new methods */
+static int
+sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
+{
+	if (operation == ASN1_OP_NEW_PRE) {
+		DSA_SIG *sig;
+
+		sig = malloc(sizeof(DSA_SIG));
+		if (!sig) {
+			DSAerr(DSA_F_SIG_CB, ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		sig->r = NULL;
+		sig->s = NULL;
+		*pval = (ASN1_VALUE *)sig;
+		return 2;
+	}
+	return 1;
+}
+
+static const ASN1_AUX DSA_SIG_aux = {
+	.app_data = NULL,
+	.flags = 0,
+	.ref_offset = 0,
+	.ref_lock = 0,
+	.asn1_cb = sig_cb,
+	.enc_offset = 0,
+};
+static const ASN1_TEMPLATE DSA_SIG_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(DSA_SIG, r),
+		.field_name = "r",
+		.item = &CBIGNUM_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(DSA_SIG, s),
+		.field_name = "s",
+		.item = &CBIGNUM_it,
+	},
+};
+
+const ASN1_ITEM DSA_SIG_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = DSA_SIG_seq_tt,
+	.tcount = sizeof(DSA_SIG_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &DSA_SIG_aux,
+	.size = sizeof(DSA_SIG),
+	.sname = "DSA_SIG",
+};
+
+
+DSA_SIG *
+d2i_DSA_SIG(DSA_SIG **a, const unsigned char **in, long len)
+{
+	return (DSA_SIG *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &DSA_SIG_it);
+}
+
+int
+i2d_DSA_SIG(const DSA_SIG *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &DSA_SIG_it);
+}
+
+/* Override the default free and new methods */
+static int
+dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
+{
+	if (operation == ASN1_OP_NEW_PRE) {
+		*pval = (ASN1_VALUE *)DSA_new();
+		if (*pval)
+			return 2;
+		return 0;
+	} else if (operation == ASN1_OP_FREE_PRE) {
+		DSA_free((DSA *)*pval);
+		*pval = NULL;
+		return 2;
+	}
+	return 1;
+}
+
+static const ASN1_AUX DSAPrivateKey_aux = {
+	.app_data = NULL,
+	.flags = 0,
+	.ref_offset = 0,
+	.ref_lock = 0,
+	.asn1_cb = dsa_cb,
+	.enc_offset = 0,
+};
+static const ASN1_TEMPLATE DSAPrivateKey_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(DSA, version),
+		.field_name = "version",
+		.item = &LONG_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(DSA, p),
+		.field_name = "p",
+		.item = &BIGNUM_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(DSA, q),
+		.field_name = "q",
+		.item = &BIGNUM_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(DSA, g),
+		.field_name = "g",
+		.item = &BIGNUM_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(DSA, pub_key),
+		.field_name = "pub_key",
+		.item = &BIGNUM_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(DSA, priv_key),
+		.field_name = "priv_key",
+		.item = &BIGNUM_it,
+	},
+};
+
+const ASN1_ITEM DSAPrivateKey_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = DSAPrivateKey_seq_tt,
+	.tcount = sizeof(DSAPrivateKey_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &DSAPrivateKey_aux,
+	.size = sizeof(DSA),
+	.sname = "DSA",
+};
+
+
+DSA *
+d2i_DSAPrivateKey(DSA **a, const unsigned char **in, long len)
+{
+	return (DSA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &DSAPrivateKey_it);
+}
+
+int
+i2d_DSAPrivateKey(const DSA *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &DSAPrivateKey_it);
+}
+
+static const ASN1_AUX DSAparams_aux = {
+	.app_data = NULL,
+	.flags = 0,
+	.ref_offset = 0,
+	.ref_lock = 0,
+	.asn1_cb = dsa_cb,
+	.enc_offset = 0,
+};
+static const ASN1_TEMPLATE DSAparams_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(DSA, p),
+		.field_name = "p",
+		.item = &BIGNUM_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(DSA, q),
+		.field_name = "q",
+		.item = &BIGNUM_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(DSA, g),
+		.field_name = "g",
+		.item = &BIGNUM_it,
+	},
+};
+
+const ASN1_ITEM DSAparams_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = DSAparams_seq_tt,
+	.tcount = sizeof(DSAparams_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &DSAparams_aux,
+	.size = sizeof(DSA),
+	.sname = "DSA",
+};
+
+
+DSA *
+d2i_DSAparams(DSA **a, const unsigned char **in, long len)
+{
+	return (DSA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &DSAparams_it);
+}
+
+int
+i2d_DSAparams(const DSA *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &DSAparams_it);
+}
+
+/*
+ * DSA public key is a bit trickier... its effectively a CHOICE type
+ * decided by a field called write_params which can either write out
+ * just the public key as an INTEGER or the parameters and public key
+ * in a SEQUENCE
+ */
+
+static const ASN1_TEMPLATE dsa_pub_internal_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(DSA, pub_key),
+		.field_name = "pub_key",
+		.item = &BIGNUM_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(DSA, p),
+		.field_name = "p",
+		.item = &BIGNUM_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(DSA, q),
+		.field_name = "q",
+		.item = &BIGNUM_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(DSA, g),
+		.field_name = "g",
+		.item = &BIGNUM_it,
+	},
+};
+
+const ASN1_ITEM dsa_pub_internal_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = dsa_pub_internal_seq_tt,
+	.tcount = sizeof(dsa_pub_internal_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(DSA),
+	.sname = "DSA",
+};
+
+static const ASN1_AUX DSAPublicKey_aux = {
+	.app_data = NULL,
+	.flags = 0,
+	.ref_offset = 0,
+	.ref_lock = 0,
+	.asn1_cb = dsa_cb,
+	.enc_offset = 0,
+};
+static const ASN1_TEMPLATE DSAPublicKey_ch_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(DSA, pub_key),
+		.field_name = "pub_key",
+		.item = &BIGNUM_it,
+	},
+	{
+		.flags = 0 | ASN1_TFLG_COMBINE,
+		.tag = 0,
+		.offset = 0,
+		.field_name = NULL,
+		.item = &dsa_pub_internal_it,
+	},
+};
+
+const ASN1_ITEM DSAPublicKey_it = {
+	.itype = ASN1_ITYPE_CHOICE,
+	.utype = offsetof(DSA, write_params),
+	.templates = DSAPublicKey_ch_tt,
+	.tcount = sizeof(DSAPublicKey_ch_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &DSAPublicKey_aux,
+	.size = sizeof(DSA),
+	.sname = "DSA",
+};
+
+
+DSA *
+d2i_DSAPublicKey(DSA **a, const unsigned char **in, long len)
+{
+	return (DSA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &DSAPublicKey_it);
+}
+
+int
+i2d_DSAPublicKey(const DSA *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &DSAPublicKey_it);
+}
+
+DSA *
+DSAparams_dup(DSA *dsa)
+{
+	return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa);
+}
+
+int
+DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
+    unsigned int *siglen, DSA *dsa)
+{
+	DSA_SIG *s;
+
+	s = DSA_do_sign(dgst, dlen, dsa);
+	if (s == NULL) {
+		*siglen = 0;
+		return 0;
+	}
+	*siglen = i2d_DSA_SIG(s,&sig);
+	DSA_SIG_free(s);
+	return 1;
+}
+
+/*
+ * data has already been hashed (probably with SHA or SHA-1).
+ * returns
+ *      1: correct signature
+ *      0: incorrect signature
+ *     -1: error
+ */
+int
+DSA_verify(int type, const unsigned char *dgst, int dgst_len,
+    const unsigned char *sigbuf, int siglen, DSA *dsa)
+{
+	DSA_SIG *s;
+	unsigned char *der = NULL;
+	const unsigned char *p = sigbuf;
+	int derlen = -1;
+	int ret = -1;
+
+	s = DSA_SIG_new();
+	if (s == NULL)
+		return ret;
+	if (d2i_DSA_SIG(&s, &p, siglen) == NULL)
+		goto err;
+	/* Ensure signature uses DER and doesn't have trailing garbage */
+	derlen = i2d_DSA_SIG(s, &der);
+	if (derlen != siglen || memcmp(sigbuf, der, derlen))
+		goto err;
+	ret = DSA_do_verify(dgst, dgst_len, s, dsa);
+err:
+	if (derlen > 0) {
+		explicit_bzero(der, derlen);
+		free(der);
+	}
+	DSA_SIG_free(s);
+	return ret;
+}
diff --git a/crypto/libressl/crypto/dsa/dsa_depr.c b/crypto/libressl/crypto/dsa/dsa_depr.c
new file mode 100644
index 0000000000..ee9318b2f1
--- /dev/null
+++ b/crypto/libressl/crypto/dsa/dsa_depr.c
@@ -0,0 +1,92 @@
+/* $OpenBSD: dsa_depr.c,v 1.6 2014/07/11 08:44:48 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* This file contains deprecated function(s) that are now wrappers to the new
+ * version(s). */
+
+#include 
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_SHA
+
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_DEPRECATED
+DSA *
+DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len,
+    int *counter_ret, unsigned long *h_ret, void (*callback)(int, int, void *),
+    void *cb_arg)
+{
+	BN_GENCB cb;
+	DSA *ret;
+
+	if ((ret = DSA_new()) == NULL)
+		return NULL;
+
+	BN_GENCB_set_old(&cb, callback, cb_arg);
+
+	if (DSA_generate_parameters_ex(ret, bits, seed_in, seed_len,
+	    counter_ret, h_ret, &cb))
+		return ret;
+	DSA_free(ret);
+	return NULL;
+}
+#endif
+#endif
diff --git a/crypto/libressl/crypto/dsa/dsa_err.c b/crypto/libressl/crypto/dsa/dsa_err.c
new file mode 100644
index 0000000000..c199d1fedb
--- /dev/null
+++ b/crypto/libressl/crypto/dsa/dsa_err.c
@@ -0,0 +1,133 @@
+/* $OpenBSD: dsa_err.c,v 1.13 2014/06/12 15:49:28 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2011 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_DSA,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_DSA,0,reason)
+
+static ERR_STRING_DATA DSA_str_functs[]=
+	{
+{ERR_FUNC(DSA_F_D2I_DSA_SIG),	"d2i_DSA_SIG"},
+{ERR_FUNC(DSA_F_DO_DSA_PRINT),	"DO_DSA_PRINT"},
+{ERR_FUNC(DSA_F_DSAPARAMS_PRINT),	"DSAparams_print"},
+{ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP),	"DSAparams_print_fp"},
+{ERR_FUNC(DSA_F_DSA_DO_SIGN),	"DSA_do_sign"},
+{ERR_FUNC(DSA_F_DSA_DO_VERIFY),	"DSA_do_verify"},
+{ERR_FUNC(DSA_F_DSA_GENERATE_KEY),	"DSA_generate_key"},
+{ERR_FUNC(DSA_F_DSA_GENERATE_PARAMETERS_EX),	"DSA_generate_parameters_ex"},
+{ERR_FUNC(DSA_F_DSA_NEW_METHOD),	"DSA_new_method"},
+{ERR_FUNC(DSA_F_DSA_PARAM_DECODE),	"DSA_PARAM_DECODE"},
+{ERR_FUNC(DSA_F_DSA_PRINT_FP),	"DSA_print_fp"},
+{ERR_FUNC(DSA_F_DSA_PRIV_DECODE),	"DSA_PRIV_DECODE"},
+{ERR_FUNC(DSA_F_DSA_PRIV_ENCODE),	"DSA_PRIV_ENCODE"},
+{ERR_FUNC(DSA_F_DSA_PUB_DECODE),	"DSA_PUB_DECODE"},
+{ERR_FUNC(DSA_F_DSA_PUB_ENCODE),	"DSA_PUB_ENCODE"},
+{ERR_FUNC(DSA_F_DSA_SIGN),	"DSA_sign"},
+{ERR_FUNC(DSA_F_DSA_SIGN_SETUP),	"DSA_sign_setup"},
+{ERR_FUNC(DSA_F_DSA_SIG_NEW),	"DSA_SIG_new"},
+{ERR_FUNC(DSA_F_DSA_SIG_PRINT),	"DSA_SIG_PRINT"},
+{ERR_FUNC(DSA_F_DSA_VERIFY),	"DSA_verify"},
+{ERR_FUNC(DSA_F_I2D_DSA_SIG),	"i2d_DSA_SIG"},
+{ERR_FUNC(DSA_F_OLD_DSA_PRIV_DECODE),	"OLD_DSA_PRIV_DECODE"},
+{ERR_FUNC(DSA_F_PKEY_DSA_CTRL),	"PKEY_DSA_CTRL"},
+{ERR_FUNC(DSA_F_PKEY_DSA_KEYGEN),	"PKEY_DSA_KEYGEN"},
+{ERR_FUNC(DSA_F_SIG_CB),	"SIG_CB"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA DSA_str_reasons[]=
+	{
+{ERR_REASON(DSA_R_BAD_Q_VALUE)           ,"bad q value"},
+{ERR_REASON(DSA_R_BN_DECODE_ERROR)       ,"bn decode error"},
+{ERR_REASON(DSA_R_BN_ERROR)              ,"bn error"},
+{ERR_REASON(DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"},
+{ERR_REASON(DSA_R_DECODE_ERROR)          ,"decode error"},
+{ERR_REASON(DSA_R_INVALID_DIGEST_TYPE)   ,"invalid digest type"},
+{ERR_REASON(DSA_R_MISSING_PARAMETERS)    ,"missing parameters"},
+{ERR_REASON(DSA_R_MODULUS_TOO_LARGE)     ,"modulus too large"},
+{ERR_REASON(DSA_R_NEED_NEW_SETUP_VALUES) ,"need new setup values"},
+{ERR_REASON(DSA_R_NON_FIPS_DSA_METHOD)   ,"non fips dsa method"},
+{ERR_REASON(DSA_R_NO_PARAMETERS_SET)     ,"no parameters set"},
+{ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_DSA_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(DSA_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,DSA_str_functs);
+		ERR_load_strings(0,DSA_str_reasons);
+		}
+#endif
+	}
diff --git a/crypto/libressl/crypto/dsa/dsa_gen.c b/crypto/libressl/crypto/dsa/dsa_gen.c
new file mode 100644
index 0000000000..e69e6bd28d
--- /dev/null
+++ b/crypto/libressl/crypto/dsa/dsa_gen.c
@@ -0,0 +1,357 @@
+/* $OpenBSD: dsa_gen.c,v 1.21 2015/07/15 16:32:29 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include  /* To see if OPENSSL_NO_SHA is defined */
+
+#ifndef OPENSSL_NO_SHA
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include "dsa_locl.h"
+
+int
+DSA_generate_parameters_ex(DSA *ret, int bits, const unsigned char *seed_in,
+    int seed_len, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
+{
+	if (ret->meth->dsa_paramgen)
+		return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
+		    counter_ret, h_ret, cb);
+	else {
+		const EVP_MD *evpmd;
+		size_t qbits;
+
+		if (bits >= 2048) {
+			qbits = 256;
+			evpmd = EVP_sha256();
+		} else {
+			qbits = 160;
+			evpmd = EVP_sha1();
+		}
+
+		return dsa_builtin_paramgen(ret, bits, qbits, evpmd, seed_in,
+		    seed_len, NULL, counter_ret, h_ret, cb);
+	}
+}
+
+int
+dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, const EVP_MD *evpmd,
+    const unsigned char *seed_in, size_t seed_len, unsigned char *seed_out,
+    int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
+{
+	int ok = 0;
+	unsigned char seed[SHA256_DIGEST_LENGTH];
+	unsigned char md[SHA256_DIGEST_LENGTH];
+	unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH];
+	BIGNUM *r0, *W, *X, *c, *test;
+	BIGNUM *g = NULL, *q = NULL, *p = NULL;
+	BN_MONT_CTX *mont = NULL;
+	int i, k, n = 0, m = 0, qsize = qbits >> 3;
+	int counter = 0;
+	int r = 0;
+	BN_CTX *ctx = NULL;
+	unsigned int h = 2;
+
+	if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
+	    qsize != SHA256_DIGEST_LENGTH)
+		/* invalid q size */
+		return 0;
+
+	if (evpmd == NULL)
+		/* use SHA1 as default */
+		evpmd = EVP_sha1();
+
+	if (bits < 512)
+		bits = 512;
+
+	bits = (bits + 63) / 64 * 64;
+
+	if (seed_len < (size_t)qsize) {
+		seed_in = NULL;		/* seed buffer too small -- ignore */
+		seed_len = 0;
+	}
+	/*
+	 * App. 2.2 of FIPS PUB 186 allows larger SEED,
+	 * but our internal buffers are restricted to 160 bits
+	 */
+	if (seed_len > (size_t)qsize) 
+		seed_len = qsize;
+	if (seed_in != NULL)
+		memcpy(seed, seed_in, seed_len);
+	else if (seed_len != 0)
+		goto err;
+
+	if ((mont=BN_MONT_CTX_new()) == NULL)
+		goto err;
+
+	if ((ctx=BN_CTX_new()) == NULL)
+		goto err;
+	BN_CTX_start(ctx);
+
+	if ((r0 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((g = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((W = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((q = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((X = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((c = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((p = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((test = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!BN_lshift(test, BN_value_one(), bits - 1))
+		goto err;
+
+	for (;;) {
+		for (;;) { /* find q */
+			int seed_is_random;
+
+			/* step 1 */
+			if (!BN_GENCB_call(cb, 0, m++))
+				goto err;
+
+			if (seed_len == 0) {
+				arc4random_buf(seed, qsize);
+				seed_is_random = 1;
+			} else {
+				seed_is_random = 0;
+				/* use random seed if 'seed_in' turns out
+				   to be bad */
+				seed_len = 0;
+			}
+			memcpy(buf, seed, qsize);
+			memcpy(buf2, seed, qsize);
+			/* precompute "SEED + 1" for step 7: */
+			for (i = qsize - 1; i >= 0; i--) {
+				buf[i]++;
+				if (buf[i] != 0)
+					break;
+			}
+
+			/* step 2 */
+			if (!EVP_Digest(seed, qsize, md,   NULL, evpmd, NULL))
+				goto err;
+			if (!EVP_Digest(buf,  qsize, buf2, NULL, evpmd, NULL))
+				goto err;
+			for (i = 0; i < qsize; i++)
+				md[i] ^= buf2[i];
+
+			/* step 3 */
+			md[0] |= 0x80;
+			md[qsize - 1] |= 0x01;
+			if (!BN_bin2bn(md, qsize, q))
+				goto err;
+
+			/* step 4 */
+			r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
+			    seed_is_random, cb);
+			if (r > 0)
+				break;
+			if (r != 0)
+				goto err;
+
+			/* do a callback call */
+			/* step 5 */
+		}
+
+		if (!BN_GENCB_call(cb, 2, 0))
+			goto err;
+		if (!BN_GENCB_call(cb, 3, 0))
+			goto err;
+
+		/* step 6 */
+		counter = 0;
+		/* "offset = 2" */
+
+		n = (bits - 1) / 160;
+
+		for (;;) {
+			if (counter != 0 && !BN_GENCB_call(cb, 0, counter))
+				goto err;
+
+			/* step 7 */
+			BN_zero(W);
+			/* now 'buf' contains "SEED + offset - 1" */
+			for (k = 0; k <= n; k++) {
+				/* obtain "SEED + offset + k" by incrementing: */
+				for (i = qsize - 1; i >= 0; i--) {
+					buf[i]++;
+					if (buf[i] != 0)
+						break;
+				}
+
+				if (!EVP_Digest(buf, qsize, md ,NULL, evpmd,
+				    NULL))
+					goto err;
+
+				/* step 8 */
+				if (!BN_bin2bn(md, qsize, r0))
+					goto err;
+				if (!BN_lshift(r0, r0, (qsize << 3) * k))
+					goto err;
+				if (!BN_add(W, W, r0))
+					goto err;
+			}
+
+			/* more of step 8 */
+			if (!BN_mask_bits(W, bits - 1))
+				goto err;
+			if (!BN_copy(X, W))
+				goto err;
+			if (!BN_add(X, X, test))
+				goto err;
+
+			/* step 9 */
+			if (!BN_lshift1(r0, q))
+				goto err;
+			if (!BN_mod(c, X, r0, ctx))
+				goto err;
+			if (!BN_sub(r0, c, BN_value_one()))
+				goto err;
+			if (!BN_sub(p, X, r0))
+				goto err;
+
+			/* step 10 */
+			if (BN_cmp(p, test) >= 0) {
+				/* step 11 */
+				r = BN_is_prime_fasttest_ex(p, DSS_prime_checks,
+				    ctx, 1, cb);
+				if (r > 0)
+					goto end; /* found it */
+				if (r != 0)
+					goto err;
+			}
+
+			/* step 13 */
+			counter++;
+			/* "offset = offset + n + 1" */
+
+			/* step 14 */
+			if (counter >= 4096)
+				break;
+		}
+	}
+end:
+	if (!BN_GENCB_call(cb, 2, 1))
+		goto err;
+
+	/* We now need to generate g */
+	/* Set r0=(p-1)/q */
+	if (!BN_sub(test, p, BN_value_one()))
+		goto err;
+	if (!BN_div(r0, NULL, test, q, ctx))
+		goto err;
+
+	if (!BN_set_word(test, h))
+		goto err;
+	if (!BN_MONT_CTX_set(mont, p, ctx))
+		goto err;
+
+	for (;;) {
+		/* g=test^r0%p */
+		if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont))
+			goto err;
+		if (!BN_is_one(g))
+			break;
+		if (!BN_add(test, test, BN_value_one()))
+			goto err;
+		h++;
+	}
+
+	if (!BN_GENCB_call(cb, 3, 1))
+		goto err;
+
+	ok = 1;
+err:
+	if (ok) {
+		BN_free(ret->p);
+		BN_free(ret->q);
+		BN_free(ret->g);
+		ret->p = BN_dup(p);
+		ret->q = BN_dup(q);
+		ret->g = BN_dup(g);
+		if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
+			ok = 0;
+			goto err;
+		}
+		if (counter_ret != NULL)
+			*counter_ret = counter;
+		if (h_ret != NULL)
+			*h_ret = h;
+		if (seed_out != NULL)
+			memcpy(seed_out, seed, qsize);
+	}
+	if (ctx) {
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+	}
+	BN_MONT_CTX_free(mont);
+	return ok;
+}
+#endif
diff --git a/crypto/libressl/crypto/dsa/dsa_key.c b/crypto/libressl/crypto/dsa/dsa_key.c
new file mode 100644
index 0000000000..a7e1721a9f
--- /dev/null
+++ b/crypto/libressl/crypto/dsa/dsa_key.c
@@ -0,0 +1,127 @@
+/* $OpenBSD: dsa_key.c,v 1.21 2016/06/21 04:16:53 bcook Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_SHA
+
+#include 
+#include 
+
+static int dsa_builtin_keygen(DSA *dsa);
+
+int
+DSA_generate_key(DSA *dsa)
+{
+	if (dsa->meth->dsa_keygen)
+		return dsa->meth->dsa_keygen(dsa);
+	return dsa_builtin_keygen(dsa);
+}
+
+static int
+dsa_builtin_keygen(DSA *dsa)
+{
+	int ok = 0;
+	BN_CTX *ctx = NULL;
+	BIGNUM *pub_key = NULL, *priv_key = NULL;
+
+	if ((ctx = BN_CTX_new()) == NULL)
+		goto err;
+
+	if (dsa->priv_key == NULL) {
+		if ((priv_key = BN_new()) == NULL)
+			goto err;
+	} else
+		priv_key=dsa->priv_key;
+
+	do {
+		if (!BN_rand_range(priv_key, dsa->q))
+			goto err;
+	} while (BN_is_zero(priv_key));
+
+	if (dsa->pub_key == NULL) {
+		if ((pub_key = BN_new()) == NULL)
+			goto err;
+	} else
+		pub_key=dsa->pub_key;
+	
+	{
+		BIGNUM prk;
+
+		BN_with_flags(&prk, priv_key, BN_FLG_CONSTTIME);
+
+		if (!BN_mod_exp(pub_key, dsa->g, &prk, dsa->p, ctx))
+			goto err;
+	}
+
+	dsa->priv_key = priv_key;
+	dsa->pub_key = pub_key;
+	ok = 1;
+
+err:
+	if (pub_key != NULL && dsa->pub_key == NULL)
+		BN_free(pub_key);
+	if (priv_key != NULL && dsa->priv_key == NULL)
+		BN_free(priv_key);
+	BN_CTX_free(ctx);
+	return ok;
+}
+#endif
diff --git a/crypto/libressl/crypto/dsa/dsa_lib.c b/crypto/libressl/crypto/dsa/dsa_lib.c
new file mode 100644
index 0000000000..b8c26427f9
--- /dev/null
+++ b/crypto/libressl/crypto/dsa/dsa_lib.c
@@ -0,0 +1,305 @@
+/* $OpenBSD: dsa_lib.c,v 1.21 2014/07/12 16:03:37 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Original version from Steven Schoch  */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_DH
+#include 
+#endif
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+
+static const DSA_METHOD *default_DSA_method = NULL;
+
+void
+DSA_set_default_method(const DSA_METHOD *meth)
+{
+	default_DSA_method = meth;
+}
+
+const DSA_METHOD *
+DSA_get_default_method(void)
+{
+	if (!default_DSA_method)
+		default_DSA_method = DSA_OpenSSL();
+	return default_DSA_method;
+}
+
+DSA *
+DSA_new(void)
+{
+	return DSA_new_method(NULL);
+}
+
+int
+DSA_set_method(DSA *dsa, const DSA_METHOD *meth)
+{
+	/*
+	 * NB: The caller is specifically setting a method, so it's not up to us
+	 * to deal with which ENGINE it comes from.
+	 */
+        const DSA_METHOD *mtmp;
+        mtmp = dsa->meth;
+        if (mtmp->finish)
+		mtmp->finish(dsa);
+#ifndef OPENSSL_NO_ENGINE
+	if (dsa->engine) {
+		ENGINE_finish(dsa->engine);
+		dsa->engine = NULL;
+	}
+#endif
+        dsa->meth = meth;
+        if (meth->init)
+		meth->init(dsa);
+        return 1;
+}
+
+DSA *
+DSA_new_method(ENGINE *engine)
+{
+	DSA *ret;
+
+	ret = malloc(sizeof(DSA));
+	if (ret == NULL) {
+		DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	ret->meth = DSA_get_default_method();
+#ifndef OPENSSL_NO_ENGINE
+	if (engine) {
+		if (!ENGINE_init(engine)) {
+			DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
+			free(ret);
+			return NULL;
+		}
+		ret->engine = engine;
+	} else
+		ret->engine = ENGINE_get_default_DSA();
+	if (ret->engine) {
+		ret->meth = ENGINE_get_DSA(ret->engine);
+		if (!ret->meth) {
+			DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
+			ENGINE_finish(ret->engine);
+			free(ret);
+			return NULL;
+		}
+	}
+#endif
+
+	ret->pad = 0;
+	ret->version = 0;
+	ret->write_params = 1;
+	ret->p = NULL;
+	ret->q = NULL;
+	ret->g = NULL;
+
+	ret->pub_key = NULL;
+	ret->priv_key = NULL;
+
+	ret->kinv = NULL;
+	ret->r = NULL;
+	ret->method_mont_p = NULL;
+
+	ret->references = 1;
+	ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data);
+	if (ret->meth->init != NULL && !ret->meth->init(ret)) {
+#ifndef OPENSSL_NO_ENGINE
+		if (ret->engine)
+			ENGINE_finish(ret->engine);
+#endif
+		CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data);
+		free(ret);
+		ret = NULL;
+	}
+	
+	return ret;
+}
+
+void
+DSA_free(DSA *r)
+{
+	int i;
+
+	if (r == NULL)
+		return;
+
+	i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_DSA);
+	if (i > 0)
+		return;
+
+	if (r->meth->finish)
+		r->meth->finish(r);
+#ifndef OPENSSL_NO_ENGINE
+	if (r->engine)
+		ENGINE_finish(r->engine);
+#endif
+
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data);
+
+	BN_clear_free(r->p);
+	BN_clear_free(r->q);
+	BN_clear_free(r->g);
+	BN_clear_free(r->pub_key);
+	BN_clear_free(r->priv_key);
+	BN_clear_free(r->kinv);
+	BN_clear_free(r->r);
+	free(r);
+}
+
+int
+DSA_up_ref(DSA *r)
+{
+	int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DSA);
+	return i > 1 ? 1 : 0;
+}
+
+int
+DSA_size(const DSA *r)
+{
+	int ret, i;
+	ASN1_INTEGER bs;
+	unsigned char buf[4];	/* 4 bytes looks really small.
+				   However, i2d_ASN1_INTEGER() will not look
+				   beyond the first byte, as long as the second
+				   parameter is NULL. */
+
+	i = BN_num_bits(r->q);
+	bs.length = (i + 7) / 8;
+	bs.data = buf;
+	bs.type = V_ASN1_INTEGER;
+	/* If the top bit is set the asn1 encoding is 1 larger. */
+	buf[0] = 0xff;
+
+	i = i2d_ASN1_INTEGER(&bs, NULL);
+	i += i; /* r and s */
+	ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
+	return ret;
+}
+
+int
+DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+    CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+{
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DSA, argl, argp,
+	    new_func, dup_func, free_func);
+}
+
+int
+DSA_set_ex_data(DSA *d, int idx, void *arg)
+{
+	return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
+}
+
+void *
+DSA_get_ex_data(DSA *d, int idx)
+{
+	return CRYPTO_get_ex_data(&d->ex_data, idx);
+}
+
+#ifndef OPENSSL_NO_DH
+DH *
+DSA_dup_DH(const DSA *r)
+{
+	/*
+	 * DSA has p, q, g, optional pub_key, optional priv_key.
+	 * DH has p, optional length, g, optional pub_key, optional priv_key,
+	 * optional q.
+	 */ 
+	DH *ret = NULL;
+
+	if (r == NULL)
+		goto err;
+	ret = DH_new();
+	if (ret == NULL)
+		goto err;
+	if (r->p != NULL) 
+		if ((ret->p = BN_dup(r->p)) == NULL)
+			goto err;
+	if (r->q != NULL) {
+		ret->length = BN_num_bits(r->q);
+		if ((ret->q = BN_dup(r->q)) == NULL)
+			goto err;
+	}
+	if (r->g != NULL)
+		if ((ret->g = BN_dup(r->g)) == NULL)
+			goto err;
+	if (r->pub_key != NULL)
+		if ((ret->pub_key = BN_dup(r->pub_key)) == NULL)
+			goto err;
+	if (r->priv_key != NULL)
+		if ((ret->priv_key = BN_dup(r->priv_key)) == NULL)
+			goto err;
+
+	return ret;
+
+err:
+	DH_free(ret);
+	return NULL;
+}
+#endif
diff --git a/crypto/libressl/crypto/dsa/dsa_locl.h b/crypto/libressl/crypto/dsa/dsa_locl.h
new file mode 100644
index 0000000000..9eb45e430d
--- /dev/null
+++ b/crypto/libressl/crypto/dsa/dsa_locl.h
@@ -0,0 +1,61 @@
+/* $OpenBSD$ */
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
+	const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
+	unsigned char *seed_out,
+	int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
diff --git a/crypto/libressl/crypto/dsa/dsa_ossl.c b/crypto/libressl/crypto/dsa/dsa_ossl.c
new file mode 100644
index 0000000000..62c0e904ab
--- /dev/null
+++ b/crypto/libressl/crypto/dsa/dsa_ossl.c
@@ -0,0 +1,385 @@
+/* $OpenBSD: dsa_ossl.c,v 1.25 2016/06/06 23:37:37 tedu Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Original version from Steven Schoch  */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
+static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
+	    BIGNUM **rp);
+static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
+	    DSA *dsa);
+static int dsa_init(DSA *dsa);
+static int dsa_finish(DSA *dsa);
+
+static DSA_METHOD openssl_dsa_meth = {
+	.name = "OpenSSL DSA method",
+	.dsa_do_sign = dsa_do_sign,
+	.dsa_sign_setup = dsa_sign_setup,
+	.dsa_do_verify = dsa_do_verify,
+	.init = dsa_init,
+	.finish = dsa_finish
+};
+
+const DSA_METHOD *
+DSA_OpenSSL(void)
+{
+	return &openssl_dsa_meth;
+}
+
+static DSA_SIG *
+dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+{
+	BIGNUM *kinv = NULL, *r = NULL, *s = NULL;
+	BIGNUM m;
+	BIGNUM xr;
+	BN_CTX *ctx = NULL;
+	int reason = ERR_R_BN_LIB;
+	DSA_SIG *ret = NULL;
+	int noredo = 0;
+
+	BN_init(&m);
+	BN_init(&xr);
+
+	if (!dsa->p || !dsa->q || !dsa->g) {
+		reason = DSA_R_MISSING_PARAMETERS;
+		goto err;
+	}
+
+	s = BN_new();
+	if (s == NULL)
+		goto err;
+	ctx = BN_CTX_new();
+	if (ctx == NULL)
+		goto err;
+redo:
+	if (dsa->kinv == NULL || dsa->r == NULL) {
+		if (!DSA_sign_setup(dsa, ctx, &kinv, &r))
+			goto err;
+	} else {
+		kinv = dsa->kinv;
+		dsa->kinv = NULL;
+		r = dsa->r;
+		dsa->r = NULL;
+		noredo = 1;
+	}
+
+	
+	/*
+	 * If the digest length is greater than the size of q use the
+	 * BN_num_bits(dsa->q) leftmost bits of the digest, see
+	 * fips 186-3, 4.2
+	 */
+	if (dlen > BN_num_bytes(dsa->q))
+		dlen = BN_num_bytes(dsa->q);
+	if (BN_bin2bn(dgst,dlen,&m) == NULL)
+		goto err;
+
+	/* Compute  s = inv(k) (m + xr) mod q */
+	if (!BN_mod_mul(&xr, dsa->priv_key, r, dsa->q, ctx))	/* s = xr */
+		goto err;
+	if (!BN_add(s, &xr, &m))				/* s = m + xr */
+		goto err;
+	if (BN_cmp(s, dsa->q) > 0)
+		if (!BN_sub(s, s, dsa->q))
+			goto err;
+	if (!BN_mod_mul(s, s, kinv, dsa->q, ctx))
+		goto err;
+
+	ret = DSA_SIG_new();
+	if (ret == NULL)
+		goto err;
+	/*
+	 * Redo if r or s is zero as required by FIPS 186-3: this is
+	 * very unlikely.
+	 */
+	if (BN_is_zero(r) || BN_is_zero(s)) {
+		if (noredo) {
+			reason = DSA_R_NEED_NEW_SETUP_VALUES;
+			goto err;
+		}
+		goto redo;
+	}
+	ret->r = r;
+	ret->s = s;
+	
+err:
+	if (!ret) {
+		DSAerr(DSA_F_DSA_DO_SIGN, reason);
+		BN_free(r);
+		BN_free(s);
+	}
+	BN_CTX_free(ctx);
+	BN_clear_free(&m);
+	BN_clear_free(&xr);
+	BN_clear_free(kinv);
+	return ret;
+}
+
+static int
+dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+{
+	BN_CTX *ctx;
+	BIGNUM k, *kinv = NULL, *r = NULL;
+	int ret = 0;
+
+	if (!dsa->p || !dsa->q || !dsa->g) {
+		DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS);
+		return 0;
+	}
+
+	BN_init(&k);
+
+	if (ctx_in == NULL) {
+		if ((ctx = BN_CTX_new()) == NULL)
+			goto err;
+	} else
+		ctx = ctx_in;
+
+	if ((r = BN_new()) == NULL)
+		goto err;
+
+	/* Get random k */
+	do {
+		if (!BN_rand_range(&k, dsa->q))
+			goto err;
+	} while (BN_is_zero(&k));
+
+	BN_set_flags(&k, BN_FLG_CONSTTIME);
+
+	if (dsa->flags & DSA_FLAG_CACHE_MONT_P) {
+		if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p,
+		    CRYPTO_LOCK_DSA, dsa->p, ctx))
+			goto err;
+	}
+
+	/* Compute r = (g^k mod p) mod q */
+
+	/*
+	 * We do not want timing information to leak the length of k,
+	 * so we compute g^k using an equivalent exponent of fixed
+	 * length.
+	 *
+	 * (This is a kludge that we need because the BN_mod_exp_mont()
+	 * does not let us specify the desired timing behaviour.)
+	 */
+
+	if (!BN_add(&k, &k, dsa->q))
+		goto err;
+	if (BN_num_bits(&k) <= BN_num_bits(dsa->q)) {
+		if (!BN_add(&k, &k, dsa->q))
+			goto err;
+	}
+
+	if (dsa->meth->bn_mod_exp != NULL) {
+		if (!dsa->meth->bn_mod_exp(dsa, r, dsa->g, &k, dsa->p, ctx,
+					dsa->method_mont_p))
+			goto err;
+	} else {
+		if (!BN_mod_exp_mont(r, dsa->g, &k, dsa->p, ctx, dsa->method_mont_p))
+			goto err;
+	}
+
+	if (!BN_mod(r,r,dsa->q,ctx))
+		goto err;
+
+	/* Compute  part of 's = inv(k) (m + xr) mod q' */
+	if ((kinv = BN_mod_inverse(NULL, &k, dsa->q, ctx)) == NULL)
+		goto err;
+
+	BN_clear_free(*kinvp);
+	*kinvp = kinv;
+	kinv = NULL;
+	BN_clear_free(*rp);
+	*rp = r;
+	ret = 1;
+err:
+	if (!ret) {
+		DSAerr(DSA_F_DSA_SIGN_SETUP, ERR_R_BN_LIB);
+		BN_clear_free(r);
+	}
+	if (ctx_in == NULL)
+		BN_CTX_free(ctx);
+	BN_clear_free(&k);
+	return ret;
+}
+
+static int
+dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa)
+{
+	BN_CTX *ctx;
+	BIGNUM u1, u2, t1;
+	BN_MONT_CTX *mont = NULL;
+	int ret = -1, i;
+
+	if (!dsa->p || !dsa->q || !dsa->g) {
+		DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MISSING_PARAMETERS);
+		return -1;
+	}
+
+	i = BN_num_bits(dsa->q);
+	/* fips 186-3 allows only different sizes for q */
+	if (i != 160 && i != 224 && i != 256) {
+		DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_BAD_Q_VALUE);
+		return -1;
+	}
+
+	if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) {
+		DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MODULUS_TOO_LARGE);
+		return -1;
+	}
+	BN_init(&u1);
+	BN_init(&u2);
+	BN_init(&t1);
+
+	if ((ctx = BN_CTX_new()) == NULL)
+		goto err;
+
+	if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
+	    BN_ucmp(sig->r, dsa->q) >= 0) {
+		ret = 0;
+		goto err;
+	}
+	if (BN_is_zero(sig->s) || BN_is_negative(sig->s) ||
+	    BN_ucmp(sig->s, dsa->q) >= 0) {
+		ret = 0;
+		goto err;
+	}
+
+	/* Calculate W = inv(S) mod Q
+	 * save W in u2 */
+	if ((BN_mod_inverse(&u2, sig->s, dsa->q, ctx)) == NULL)
+		goto err;
+
+	/* save M in u1 */
+	/*
+	 * If the digest length is greater than the size of q use the
+	 * BN_num_bits(dsa->q) leftmost bits of the digest, see
+	 * fips 186-3, 4.2
+	 */
+	if (dgst_len > (i >> 3))
+		dgst_len = (i >> 3);
+	if (BN_bin2bn(dgst, dgst_len, &u1) == NULL)
+		goto err;
+
+	/* u1 = M * w mod q */
+	if (!BN_mod_mul(&u1, &u1, &u2, dsa->q, ctx))
+		goto err;
+
+	/* u2 = r * w mod q */
+	if (!BN_mod_mul(&u2, sig->r, &u2, dsa->q, ctx))
+		goto err;
+
+
+	if (dsa->flags & DSA_FLAG_CACHE_MONT_P) {
+		mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p,
+		    CRYPTO_LOCK_DSA, dsa->p, ctx);
+		if (!mont)
+			goto err;
+	}
+
+	if (dsa->meth->dsa_mod_exp != NULL) {
+		if (!dsa->meth->dsa_mod_exp(dsa, &t1, dsa->g, &u1, dsa->pub_key, &u2,
+						dsa->p, ctx, mont))
+			goto err;
+	} else {
+		if (!BN_mod_exp2_mont(&t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx,
+						mont))
+			goto err;
+	}
+		
+	/* BN_copy(&u1,&t1); */
+	/* let u1 = u1 mod q */
+	if (!BN_mod(&u1, &t1, dsa->q, ctx))
+		goto err;
+
+	/* V is now in u1.  If the signature is correct, it will be
+	 * equal to R. */
+	ret = BN_ucmp(&u1, sig->r) == 0;
+
+err:
+	if (ret < 0)
+		DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_BN_LIB);
+	BN_CTX_free(ctx);
+	BN_free(&u1);
+	BN_free(&u2);
+	BN_free(&t1);
+	return ret;
+}
+
+static int
+dsa_init(DSA *dsa)
+{
+	dsa->flags |= DSA_FLAG_CACHE_MONT_P;
+	return 1;
+}
+
+static int
+dsa_finish(DSA *dsa)
+{
+	BN_MONT_CTX_free(dsa->method_mont_p);
+	return 1;
+}
+
diff --git a/crypto/libressl/crypto/dsa/dsa_pmeth.c b/crypto/libressl/crypto/dsa/dsa_pmeth.c
new file mode 100644
index 0000000000..a331d9a6c2
--- /dev/null
+++ b/crypto/libressl/crypto/dsa/dsa_pmeth.c
@@ -0,0 +1,337 @@
+/* $OpenBSD: dsa_pmeth.c,v 1.9 2014/07/10 13:58:22 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "dsa_locl.h"
+#include "evp_locl.h"
+
+/* DSA pkey context structure */
+
+typedef struct {
+	/* Parameter gen parameters */
+	int nbits;		/* size of p in bits (default: 1024) */
+	int qbits;		/* size of q in bits (default: 160)  */
+	const EVP_MD *pmd;	/* MD for parameter generation */
+	/* Keygen callback info */
+	int gentmp[2];
+	/* message digest */
+	const EVP_MD *md;	/* MD for the signature */
+} DSA_PKEY_CTX;
+
+static int
+pkey_dsa_init(EVP_PKEY_CTX *ctx)
+{
+	DSA_PKEY_CTX *dctx;
+
+	dctx = malloc(sizeof(DSA_PKEY_CTX));
+	if (!dctx)
+		return 0;
+	dctx->nbits = 1024;
+	dctx->qbits = 160;
+	dctx->pmd = NULL;
+	dctx->md = NULL;
+
+	ctx->data = dctx;
+	ctx->keygen_info = dctx->gentmp;
+	ctx->keygen_info_count = 2;
+	
+	return 1;
+}
+
+static int
+pkey_dsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+{
+	DSA_PKEY_CTX *dctx, *sctx;
+
+	if (!pkey_dsa_init(dst))
+		return 0;
+       	sctx = src->data;
+	dctx = dst->data;
+	dctx->nbits = sctx->nbits;
+	dctx->qbits = sctx->qbits;
+	dctx->pmd = sctx->pmd;
+	dctx->md  = sctx->md;
+	return 1;
+}
+
+static void
+pkey_dsa_cleanup(EVP_PKEY_CTX *ctx)
+{
+	DSA_PKEY_CTX *dctx = ctx->data;
+
+	free(dctx);
+}
+
+static int
+pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+    const unsigned char *tbs, size_t tbslen)
+{
+	int ret, type;
+	unsigned int sltmp;
+	DSA_PKEY_CTX *dctx = ctx->data;
+	DSA *dsa = ctx->pkey->pkey.dsa;
+
+	if (dctx->md)
+		type = EVP_MD_type(dctx->md);
+	else
+		type = NID_sha1;
+
+	ret = DSA_sign(type, tbs, tbslen, sig, &sltmp, dsa);
+
+	if (ret <= 0)
+		return ret;
+	*siglen = sltmp;
+	return 1;
+}
+
+static int
+pkey_dsa_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
+    const unsigned char *tbs, size_t tbslen)
+{
+	int ret, type;
+	DSA_PKEY_CTX *dctx = ctx->data;
+	DSA *dsa = ctx->pkey->pkey.dsa;
+
+	if (dctx->md)
+		type = EVP_MD_type(dctx->md);
+	else
+		type = NID_sha1;
+
+	ret = DSA_verify(type, tbs, tbslen, sig, siglen, dsa);
+
+	return ret;
+}
+
+static int
+pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+	DSA_PKEY_CTX *dctx = ctx->data;
+
+	switch (type) {
+	case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS:
+		if (p1 < 256)
+			return -2;
+		dctx->nbits = p1;
+		return 1;
+
+	case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS:
+		if (p1 != 160 && p1 != 224 && p1 && p1 != 256)
+			return -2;
+		dctx->qbits = p1;
+		return 1;
+
+	case EVP_PKEY_CTRL_DSA_PARAMGEN_MD:
+		switch (EVP_MD_type((const EVP_MD *)p2)) {
+		case NID_sha1:
+		case NID_sha224:
+		case NID_sha256:
+			break;
+		default:
+			DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
+			return 0;
+		}
+		dctx->md = p2;
+		return 1;
+
+	case EVP_PKEY_CTRL_MD:
+		switch (EVP_MD_type((const EVP_MD *)p2)) {
+		case NID_sha1:
+		case NID_dsa:
+		case NID_dsaWithSHA:
+		case NID_sha224:
+		case NID_sha256:
+		case NID_sha384:
+		case NID_sha512:
+			break;
+		default:
+			DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
+			return 0;
+		}
+		dctx->md = p2;
+		return 1;
+
+	case EVP_PKEY_CTRL_DIGESTINIT:
+	case EVP_PKEY_CTRL_PKCS7_SIGN:
+	case EVP_PKEY_CTRL_CMS_SIGN:
+		return 1;
+		
+	case EVP_PKEY_CTRL_PEER_KEY:
+		DSAerr(DSA_F_PKEY_DSA_CTRL,
+		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;	
+	default:
+		return -2;
+	}
+}
+			
+static int
+pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value)
+{
+ 	long lval;
+	char *ep;
+
+	if (!strcmp(type, "dsa_paramgen_bits")) {
+		int nbits;
+
+		errno = 0;
+		lval = strtol(value, &ep, 10);
+		if (value[0] == '\0' || *ep != '\0')
+			goto not_a_number;
+		if ((errno == ERANGE &&
+		    (lval == LONG_MAX || lval == LONG_MIN)) ||
+		    (lval > INT_MAX || lval < INT_MIN))
+			goto out_of_range;
+		nbits = lval;
+		return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits);
+	} else if (!strcmp(type, "dsa_paramgen_q_bits")) {
+		int qbits;
+
+		errno = 0;
+		lval = strtol(value, &ep, 10);
+		if (value[0] == '\0' || *ep != '\0')
+			goto not_a_number;
+		if ((errno == ERANGE &&
+		    (lval == LONG_MAX || lval == LONG_MIN)) ||
+		    (lval > INT_MAX || lval < INT_MIN))
+			goto out_of_range;
+		qbits = lval;
+		return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA,
+		    EVP_PKEY_OP_PARAMGEN, EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS,
+		    qbits, NULL);
+	} else if (!strcmp(type, "dsa_paramgen_md")) {
+		return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA,
+		    EVP_PKEY_OP_PARAMGEN, EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, 
+		    (void *)EVP_get_digestbyname(value));
+	}
+not_a_number:
+out_of_range:
+	return -2;
+}
+
+static int
+pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+	DSA *dsa = NULL;
+	DSA_PKEY_CTX *dctx = ctx->data;
+	BN_GENCB *pcb, cb;
+	int ret;
+
+	if (ctx->pkey_gencb) {
+		pcb = &cb;
+		evp_pkey_set_cb_translate(pcb, ctx);
+	} else
+		pcb = NULL;
+	dsa = DSA_new();
+	if (!dsa)
+		return 0;
+	ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd,
+	    NULL, 0, NULL, NULL, NULL, pcb);
+	if (ret)
+		EVP_PKEY_assign_DSA(pkey, dsa);
+	else
+		DSA_free(dsa);
+	return ret;
+}
+
+static int
+pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+	DSA *dsa = NULL;
+
+	if (ctx->pkey == NULL) {
+		DSAerr(DSA_F_PKEY_DSA_KEYGEN, DSA_R_NO_PARAMETERS_SET);
+		return 0;
+	}
+	dsa = DSA_new();
+	if (!dsa)
+		return 0;
+	EVP_PKEY_assign_DSA(pkey, dsa);
+	/* Note: if error return, pkey is freed by parent routine */
+	if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
+		return 0;
+	return DSA_generate_key(pkey->pkey.dsa);
+}
+
+const EVP_PKEY_METHOD dsa_pkey_meth = {
+	.pkey_id = EVP_PKEY_DSA,
+	.flags = EVP_PKEY_FLAG_AUTOARGLEN,
+
+	.init = pkey_dsa_init,
+	.copy = pkey_dsa_copy,
+	.cleanup = pkey_dsa_cleanup,
+
+	.paramgen = pkey_dsa_paramgen,
+
+	.keygen = pkey_dsa_keygen,
+
+	.sign = pkey_dsa_sign,
+
+	.verify = pkey_dsa_verify,
+
+	.ctrl = pkey_dsa_ctrl,
+	.ctrl_str = pkey_dsa_ctrl_str
+};
diff --git a/crypto/libressl/crypto/dsa/dsa_prn.c b/crypto/libressl/crypto/dsa/dsa_prn.c
new file mode 100644
index 0000000000..03a266e3f8
--- /dev/null
+++ b/crypto/libressl/crypto/dsa/dsa_prn.c
@@ -0,0 +1,123 @@
+/* $OpenBSD: dsa_prn.c,v 1.4 2014/07/09 10:16:24 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+int
+DSA_print_fp(FILE *fp, const DSA *x, int off)
+{
+	BIO *b;
+	int ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL) {
+		DSAerr(DSA_F_DSA_PRINT_FP, ERR_R_BUF_LIB);
+		return 0;
+	}
+	BIO_set_fp(b, fp, BIO_NOCLOSE);
+	ret = DSA_print(b, x, off);
+	BIO_free(b);
+	return ret;
+}
+
+int
+DSAparams_print_fp(FILE *fp, const DSA *x)
+{
+	BIO *b;
+	int ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL) {
+		DSAerr(DSA_F_DSAPARAMS_PRINT_FP, ERR_R_BUF_LIB);
+		return 0;
+	}
+	BIO_set_fp(b, fp, BIO_NOCLOSE);
+	ret = DSAparams_print(b, x);
+	BIO_free(b);
+	return ret;
+}
+
+int
+DSA_print(BIO *bp, const DSA *x, int off)
+{
+	EVP_PKEY *pk;
+	int ret;
+
+	pk = EVP_PKEY_new();
+	if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x))
+		return 0;
+	ret = EVP_PKEY_print_private(bp, pk, off, NULL);
+	EVP_PKEY_free(pk);
+	return ret;
+}
+
+int
+DSAparams_print(BIO *bp, const DSA *x)
+{
+	EVP_PKEY *pk;
+	int ret;
+
+	pk = EVP_PKEY_new();
+	if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x))
+		return 0;
+	ret = EVP_PKEY_print_params(bp, pk, 4, NULL);
+	EVP_PKEY_free(pk);
+	return ret;
+}
diff --git a/crypto/libressl/crypto/dsa/dsa_sign.c b/crypto/libressl/crypto/dsa/dsa_sign.c
new file mode 100644
index 0000000000..a563b6c924
--- /dev/null
+++ b/crypto/libressl/crypto/dsa/dsa_sign.c
@@ -0,0 +1,97 @@
+/* $OpenBSD: dsa_sign.c,v 1.18 2014/07/12 16:03:37 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Original version from Steven Schoch  */
+
+#include 
+#include 
+
+DSA_SIG *
+DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+{
+	return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
+}
+
+int
+DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+{
+	return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
+}
+
+DSA_SIG *
+DSA_SIG_new(void)
+{
+	DSA_SIG *sig;
+
+	sig = malloc(sizeof(DSA_SIG));
+	if (!sig)
+		return NULL;
+	sig->r = NULL;
+	sig->s = NULL;
+	return sig;
+}
+
+void
+DSA_SIG_free(DSA_SIG *sig)
+{
+	if (sig) {
+		BN_free(sig->r);
+		BN_free(sig->s);
+		free(sig);
+	}
+}
diff --git a/crypto/libressl/crypto/dsa/dsa_vrf.c b/crypto/libressl/crypto/dsa/dsa_vrf.c
new file mode 100644
index 0000000000..70c4523dbe
--- /dev/null
+++ b/crypto/libressl/crypto/dsa/dsa_vrf.c
@@ -0,0 +1,67 @@
+/* $OpenBSD: dsa_vrf.c,v 1.15 2014/07/09 10:16:24 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Original version from Steven Schoch  */
+
+#include 
+
+int
+DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa)
+{
+	return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
+}
diff --git a/crypto/libressl/crypto/dso/dso_dlfcn.c b/crypto/libressl/crypto/dso/dso_dlfcn.c
new file mode 100644
index 0000000000..63a515804c
--- /dev/null
+++ b/crypto/libressl/crypto/dso/dso_dlfcn.c
@@ -0,0 +1,355 @@
+/* $OpenBSD: dso_dlfcn.c,v 1.27 2014/07/11 08:44:48 jsing Exp $ */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+
+#ifndef DSO_DLFCN
+DSO_METHOD *
+DSO_METHOD_dlfcn(void)
+{
+	return NULL;
+}
+#else
+
+#ifdef HAVE_DLFCN_H
+# include 
+# define HAVE_DLINFO 1
+#endif
+
+/* Part of the hack in "dlfcn_load" ... */
+#define DSO_MAX_TRANSLATED_SIZE 256
+
+static int dlfcn_load(DSO *dso);
+static int dlfcn_unload(DSO *dso);
+static void *dlfcn_bind_var(DSO *dso, const char *symname);
+static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname);
+static char *dlfcn_name_converter(DSO *dso, const char *filename);
+static char *dlfcn_merger(DSO *dso, const char *filespec1,
+    const char *filespec2);
+static int dlfcn_pathbyaddr(void *addr, char *path, int sz);
+static void *dlfcn_globallookup(const char *name);
+
+static DSO_METHOD dso_meth_dlfcn = {
+	.name = "OpenSSL 'dlfcn' shared library method",
+	.dso_load = dlfcn_load,
+	.dso_unload = dlfcn_unload,
+	.dso_bind_var = dlfcn_bind_var,
+	.dso_bind_func = dlfcn_bind_func,
+	.dso_name_converter = dlfcn_name_converter,
+	.dso_merger = dlfcn_merger,
+	.pathbyaddr = dlfcn_pathbyaddr,
+	.globallookup = dlfcn_globallookup
+};
+
+DSO_METHOD *
+DSO_METHOD_dlfcn(void)
+{
+	return (&dso_meth_dlfcn);
+}
+
+/* For this DSO_METHOD, our meth_data STACK will contain;
+ * (i) the handle (void*) returned from dlopen().
+ */
+
+static int
+dlfcn_load(DSO *dso)
+{
+	void *ptr = NULL;
+	/* See applicable comments in dso_dl.c */
+	char *filename = DSO_convert_filename(dso, NULL);
+	int flags = RTLD_LAZY;
+
+	if (filename == NULL) {
+		DSOerr(DSO_F_DLFCN_LOAD, DSO_R_NO_FILENAME);
+		goto err;
+	}
+
+	if (dso->flags & DSO_FLAG_GLOBAL_SYMBOLS)
+		flags |= RTLD_GLOBAL;
+	ptr = dlopen(filename, flags);
+	if (ptr == NULL) {
+		DSOerr(DSO_F_DLFCN_LOAD, DSO_R_LOAD_FAILED);
+		ERR_asprintf_error_data("filename(%s): %s", filename,
+		    dlerror());
+		goto err;
+	}
+	if (!sk_void_push(dso->meth_data, (char *)ptr)) {
+		DSOerr(DSO_F_DLFCN_LOAD, DSO_R_STACK_ERROR);
+		goto err;
+	}
+	/* Success */
+	dso->loaded_filename = filename;
+	return (1);
+
+err:
+	/* Cleanup! */
+	free(filename);
+	if (ptr != NULL)
+		dlclose(ptr);
+	return (0);
+}
+
+static int
+dlfcn_unload(DSO *dso)
+{
+	void *ptr;
+	if (dso == NULL) {
+		DSOerr(DSO_F_DLFCN_UNLOAD, ERR_R_PASSED_NULL_PARAMETER);
+		return (0);
+	}
+	if (sk_void_num(dso->meth_data) < 1)
+		return (1);
+	ptr = sk_void_pop(dso->meth_data);
+	if (ptr == NULL) {
+		DSOerr(DSO_F_DLFCN_UNLOAD, DSO_R_NULL_HANDLE);
+		/* Should push the value back onto the stack in
+		 * case of a retry. */
+		sk_void_push(dso->meth_data, ptr);
+		return (0);
+	}
+	/* For now I'm not aware of any errors associated with dlclose() */
+	dlclose(ptr);
+	return (1);
+}
+
+static void *
+dlfcn_bind_var(DSO *dso, const char *symname)
+{
+	void *ptr, *sym;
+
+	if ((dso == NULL) || (symname == NULL)) {
+		DSOerr(DSO_F_DLFCN_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER);
+		return (NULL);
+	}
+	if (sk_void_num(dso->meth_data) < 1) {
+		DSOerr(DSO_F_DLFCN_BIND_VAR, DSO_R_STACK_ERROR);
+		return (NULL);
+	}
+	ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
+	if (ptr == NULL) {
+		DSOerr(DSO_F_DLFCN_BIND_VAR, DSO_R_NULL_HANDLE);
+		return (NULL);
+	}
+	sym = dlsym(ptr, symname);
+	if (sym == NULL) {
+		DSOerr(DSO_F_DLFCN_BIND_VAR, DSO_R_SYM_FAILURE);
+		ERR_asprintf_error_data("symname(%s): %s", symname, dlerror());
+		return (NULL);
+	}
+	return (sym);
+}
+
+static DSO_FUNC_TYPE
+dlfcn_bind_func(DSO *dso, const char *symname)
+{
+	void *ptr;
+	union {
+		DSO_FUNC_TYPE sym;
+		void *dlret;
+	} u;
+
+	if ((dso == NULL) || (symname == NULL)) {
+		DSOerr(DSO_F_DLFCN_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER);
+		return (NULL);
+	}
+	if (sk_void_num(dso->meth_data) < 1) {
+		DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_STACK_ERROR);
+		return (NULL);
+	}
+	ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
+	if (ptr == NULL) {
+		DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_NULL_HANDLE);
+		return (NULL);
+	}
+	u.dlret = dlsym(ptr, symname);
+	if (u.dlret == NULL) {
+		DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_SYM_FAILURE);
+		ERR_asprintf_error_data("symname(%s): %s", symname, dlerror());
+		return (NULL);
+	}
+	return u.sym;
+}
+
+static char *
+dlfcn_merger(DSO *dso, const char *filespec1, const char *filespec2)
+{
+	char *merged;
+
+	if (!filespec1 && !filespec2) {
+		DSOerr(DSO_F_DLFCN_MERGER,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		return (NULL);
+	}
+	/* If the first file specification is a rooted path, it rules.
+	   same goes if the second file specification is missing. */
+	if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/')) {
+		merged = strdup(filespec1);
+		if (!merged) {
+			DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE);
+			return (NULL);
+		}
+	}
+	/* If the first file specification is missing, the second one rules. */
+	else if (!filespec1) {
+		merged = strdup(filespec2);
+		if (!merged) {
+			DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE);
+			return (NULL);
+		}
+	} else
+		/* This part isn't as trivial as it looks.  It assumes that
+		   the second file specification really is a directory, and
+		   makes no checks whatsoever.  Therefore, the result becomes
+		   the concatenation of filespec2 followed by a slash followed
+		   by filespec1. */
+	{
+		size_t spec2len, len;
+
+		spec2len = strlen(filespec2);
+		len = spec2len + (filespec1 ? strlen(filespec1) : 0);
+
+		if (filespec2 && filespec2[spec2len - 1] == '/') {
+			spec2len--;
+			len--;
+		}
+		merged = malloc(len + 2);
+		if (!merged) {
+			DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE);
+			return (NULL);
+		}
+		strlcpy(merged, filespec2, len + 2);
+		merged[spec2len] = '/';
+		strlcpy(&merged[spec2len + 1], filespec1, len + 1 - spec2len);
+	}
+	return (merged);
+}
+
+#define DSO_ext	".so"
+#define DSO_extlen 3
+
+static char *
+dlfcn_name_converter(DSO *dso, const char *filename)
+{
+	char *translated;
+	int ret;
+
+	if (strchr(filename, '/') == NULL) {
+		/* Bare name, so convert to "%s.so" or "lib%s.so" */
+		if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
+			ret = asprintf(&translated, "lib%s" DSO_ext, filename);
+		else
+			ret = asprintf(&translated, "%s" DSO_ext, filename);
+		if (ret == -1)
+			translated = NULL;
+	} else {
+		/* Full path, so just duplicate it */
+		translated = strdup(filename);
+	}
+
+	if (translated == NULL)
+		DSOerr(DSO_F_DLFCN_NAME_CONVERTER,
+		    DSO_R_NAME_TRANSLATION_FAILED);
+	return (translated);
+}
+
+static int
+dlfcn_pathbyaddr(void *addr, char *path, int sz)
+{
+	Dl_info dli;
+	int len;
+
+	if (addr == NULL) {
+		union{
+			int(*f)(void*, char*, int);
+			void *p;
+		} t = { dlfcn_pathbyaddr };
+		addr = t.p;
+	}
+
+	if (dladdr(addr, &dli)) {
+		len = (int)strlen(dli.dli_fname);
+		if (sz <= 0)
+			return len + 1;
+		if (len >= sz)
+			len = sz - 1;
+		memcpy(path, dli.dli_fname, len);
+		path[len++] = 0;
+		return len;
+	}
+
+	ERR_asprintf_error_data("dlfcn_pathbyaddr(): %s", dlerror());
+	return -1;
+}
+
+static void *
+dlfcn_globallookup(const char *name)
+{
+	void *ret = NULL, *handle = dlopen(NULL, RTLD_LAZY);
+
+	if (handle) {
+		ret = dlsym(handle, name);
+		dlclose(handle);
+	}
+
+	return ret;
+}
+#endif /* DSO_DLFCN */
diff --git a/crypto/libressl/crypto/dso/dso_err.c b/crypto/libressl/crypto/dso/dso_err.c
new file mode 100644
index 0000000000..a3773a2624
--- /dev/null
+++ b/crypto/libressl/crypto/dso/dso_err.c
@@ -0,0 +1,159 @@
+/* $OpenBSD: dso_err.c,v 1.7 2014/06/12 15:49:29 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_DSO,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_DSO,0,reason)
+
+static ERR_STRING_DATA DSO_str_functs[]= {
+	{ERR_FUNC(DSO_F_BEOS_BIND_FUNC),	"BEOS_BIND_FUNC"},
+	{ERR_FUNC(DSO_F_BEOS_BIND_VAR),	"BEOS_BIND_VAR"},
+	{ERR_FUNC(DSO_F_BEOS_LOAD),	"BEOS_LOAD"},
+	{ERR_FUNC(DSO_F_BEOS_NAME_CONVERTER),	"BEOS_NAME_CONVERTER"},
+	{ERR_FUNC(DSO_F_BEOS_UNLOAD),	"BEOS_UNLOAD"},
+	{ERR_FUNC(DSO_F_DLFCN_BIND_FUNC),	"DLFCN_BIND_FUNC"},
+	{ERR_FUNC(DSO_F_DLFCN_BIND_VAR),	"DLFCN_BIND_VAR"},
+	{ERR_FUNC(DSO_F_DLFCN_LOAD),	"DLFCN_LOAD"},
+	{ERR_FUNC(DSO_F_DLFCN_MERGER),	"DLFCN_MERGER"},
+	{ERR_FUNC(DSO_F_DLFCN_NAME_CONVERTER),	"DLFCN_NAME_CONVERTER"},
+	{ERR_FUNC(DSO_F_DLFCN_UNLOAD),	"DLFCN_UNLOAD"},
+	{ERR_FUNC(DSO_F_DL_BIND_FUNC),	"DL_BIND_FUNC"},
+	{ERR_FUNC(DSO_F_DL_BIND_VAR),	"DL_BIND_VAR"},
+	{ERR_FUNC(DSO_F_DL_LOAD),	"DL_LOAD"},
+	{ERR_FUNC(DSO_F_DL_MERGER),	"DL_MERGER"},
+	{ERR_FUNC(DSO_F_DL_NAME_CONVERTER),	"DL_NAME_CONVERTER"},
+	{ERR_FUNC(DSO_F_DL_UNLOAD),	"DL_UNLOAD"},
+	{ERR_FUNC(DSO_F_DSO_BIND_FUNC),	"DSO_bind_func"},
+	{ERR_FUNC(DSO_F_DSO_BIND_VAR),	"DSO_bind_var"},
+	{ERR_FUNC(DSO_F_DSO_CONVERT_FILENAME),	"DSO_convert_filename"},
+	{ERR_FUNC(DSO_F_DSO_CTRL),	"DSO_ctrl"},
+	{ERR_FUNC(DSO_F_DSO_FREE),	"DSO_free"},
+	{ERR_FUNC(DSO_F_DSO_GET_FILENAME),	"DSO_get_filename"},
+	{ERR_FUNC(DSO_F_DSO_GET_LOADED_FILENAME),	"DSO_get_loaded_filename"},
+	{ERR_FUNC(DSO_F_DSO_GLOBAL_LOOKUP),	"DSO_global_lookup"},
+	{ERR_FUNC(DSO_F_DSO_LOAD),	"DSO_load"},
+	{ERR_FUNC(DSO_F_DSO_MERGE),	"DSO_merge"},
+	{ERR_FUNC(DSO_F_DSO_NEW_METHOD),	"DSO_new_method"},
+	{ERR_FUNC(DSO_F_DSO_PATHBYADDR),	"DSO_pathbyaddr"},
+	{ERR_FUNC(DSO_F_DSO_SET_FILENAME),	"DSO_set_filename"},
+	{ERR_FUNC(DSO_F_DSO_SET_NAME_CONVERTER),	"DSO_set_name_converter"},
+	{ERR_FUNC(DSO_F_DSO_UP_REF),	"DSO_up_ref"},
+	{ERR_FUNC(DSO_F_GLOBAL_LOOKUP_FUNC),	"GLOBAL_LOOKUP_FUNC"},
+	{ERR_FUNC(DSO_F_PATHBYADDR),	"PATHBYADDR"},
+	{ERR_FUNC(DSO_F_VMS_BIND_SYM),	"VMS_BIND_SYM"},
+	{ERR_FUNC(DSO_F_VMS_LOAD),	"VMS_LOAD"},
+	{ERR_FUNC(DSO_F_VMS_MERGER),	"VMS_MERGER"},
+	{ERR_FUNC(DSO_F_VMS_UNLOAD),	"VMS_UNLOAD"},
+	{ERR_FUNC(DSO_F_WIN32_BIND_FUNC),	"WIN32_BIND_FUNC"},
+	{ERR_FUNC(DSO_F_WIN32_BIND_VAR),	"WIN32_BIND_VAR"},
+	{ERR_FUNC(DSO_F_WIN32_GLOBALLOOKUP),	"WIN32_GLOBALLOOKUP"},
+	{ERR_FUNC(DSO_F_WIN32_GLOBALLOOKUP_FUNC),	"WIN32_GLOBALLOOKUP_FUNC"},
+	{ERR_FUNC(DSO_F_WIN32_JOINER),	"WIN32_JOINER"},
+	{ERR_FUNC(DSO_F_WIN32_LOAD),	"WIN32_LOAD"},
+	{ERR_FUNC(DSO_F_WIN32_MERGER),	"WIN32_MERGER"},
+	{ERR_FUNC(DSO_F_WIN32_NAME_CONVERTER),	"WIN32_NAME_CONVERTER"},
+	{ERR_FUNC(DSO_F_WIN32_PATHBYADDR),	"WIN32_PATHBYADDR"},
+	{ERR_FUNC(DSO_F_WIN32_SPLITTER),	"WIN32_SPLITTER"},
+	{ERR_FUNC(DSO_F_WIN32_UNLOAD),	"WIN32_UNLOAD"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA DSO_str_reasons[]= {
+	{ERR_REASON(DSO_R_CTRL_FAILED)           , "control command failed"},
+	{ERR_REASON(DSO_R_DSO_ALREADY_LOADED)    , "dso already loaded"},
+	{ERR_REASON(DSO_R_EMPTY_FILE_STRUCTURE)  , "empty file structure"},
+	{ERR_REASON(DSO_R_FAILURE)               , "failure"},
+	{ERR_REASON(DSO_R_FILENAME_TOO_BIG)      , "filename too big"},
+	{ERR_REASON(DSO_R_FINISH_FAILED)         , "cleanup method function failed"},
+	{ERR_REASON(DSO_R_INCORRECT_FILE_SYNTAX) , "incorrect file syntax"},
+	{ERR_REASON(DSO_R_LOAD_FAILED)           , "could not load the shared library"},
+	{ERR_REASON(DSO_R_NAME_TRANSLATION_FAILED), "name translation failed"},
+	{ERR_REASON(DSO_R_NO_FILENAME)           , "no filename"},
+	{ERR_REASON(DSO_R_NO_FILE_SPECIFICATION) , "no file specification"},
+	{ERR_REASON(DSO_R_NULL_HANDLE)           , "a null shared library handle was used"},
+	{ERR_REASON(DSO_R_SET_FILENAME_FAILED)   , "set filename failed"},
+	{ERR_REASON(DSO_R_STACK_ERROR)           , "the meth_data stack is corrupt"},
+	{ERR_REASON(DSO_R_SYM_FAILURE)           , "could not bind to the requested symbol name"},
+	{ERR_REASON(DSO_R_UNLOAD_FAILED)         , "could not unload the shared library"},
+	{ERR_REASON(DSO_R_UNSUPPORTED)           , "functionality not supported"},
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_DSO_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(DSO_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, DSO_str_functs);
+		ERR_load_strings(0, DSO_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/dso/dso_lib.c b/crypto/libressl/crypto/dso/dso_lib.c
new file mode 100644
index 0000000000..a55754b0db
--- /dev/null
+++ b/crypto/libressl/crypto/dso/dso_lib.c
@@ -0,0 +1,454 @@
+/* $OpenBSD: dso_lib.c,v 1.17 2014/07/10 13:58:22 jsing Exp $ */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+static DSO_METHOD *default_DSO_meth = NULL;
+
+DSO *
+DSO_new(void)
+{
+	return (DSO_new_method(NULL));
+}
+
+void
+DSO_set_default_method(DSO_METHOD *meth)
+{
+	default_DSO_meth = meth;
+}
+
+DSO_METHOD *
+DSO_get_default_method(void)
+{
+	return (default_DSO_meth);
+}
+
+DSO_METHOD *
+DSO_get_method(DSO *dso)
+{
+	return (dso->meth);
+}
+
+DSO_METHOD *
+DSO_set_method(DSO *dso, DSO_METHOD *meth)
+{
+	DSO_METHOD *mtmp;
+
+	mtmp = dso->meth;
+	dso->meth = meth;
+	return (mtmp);
+}
+
+DSO *
+DSO_new_method(DSO_METHOD *meth)
+{
+	DSO *ret;
+
+	if (default_DSO_meth == NULL)
+		/* We default to DSO_METH_openssl() which in turn defaults
+		 * to stealing the "best available" method. Will fallback
+		 * to DSO_METH_null() in the worst case. */
+		default_DSO_meth = DSO_METHOD_openssl();
+	ret = calloc(1, sizeof(DSO));
+	if (ret == NULL) {
+		DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+		return (NULL);
+	}
+	ret->meth_data = sk_void_new_null();
+	if (ret->meth_data == NULL) {
+		/* sk_new doesn't generate any errors so we do */
+		DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+		free(ret);
+		return (NULL);
+	}
+	if (meth == NULL)
+		ret->meth = default_DSO_meth;
+	else
+		ret->meth = meth;
+	ret->references = 1;
+	if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
+		free(ret);
+		ret = NULL;
+	}
+	return (ret);
+}
+
+int
+DSO_free(DSO *dso)
+{
+	int i;
+
+	if (dso == NULL) {
+		DSOerr(DSO_F_DSO_FREE, ERR_R_PASSED_NULL_PARAMETER);
+		return (0);
+	}
+
+	i = CRYPTO_add(&dso->references, -1, CRYPTO_LOCK_DSO);
+	if (i > 0)
+		return (1);
+
+	if ((dso->meth->dso_unload != NULL) && !dso->meth->dso_unload(dso)) {
+		DSOerr(DSO_F_DSO_FREE, DSO_R_UNLOAD_FAILED);
+		return (0);
+	}
+
+	if ((dso->meth->finish != NULL) && !dso->meth->finish(dso)) {
+		DSOerr(DSO_F_DSO_FREE, DSO_R_FINISH_FAILED);
+		return (0);
+	}
+
+	sk_void_free(dso->meth_data);
+	free(dso->filename);
+	free(dso->loaded_filename);
+	free(dso);
+	return (1);
+}
+
+int
+DSO_flags(DSO *dso)
+{
+	return ((dso == NULL) ? 0 : dso->flags);
+}
+
+
+int
+DSO_up_ref(DSO *dso)
+{
+	if (dso == NULL) {
+		DSOerr(DSO_F_DSO_UP_REF, ERR_R_PASSED_NULL_PARAMETER);
+		return (0);
+	}
+
+	CRYPTO_add(&dso->references, 1, CRYPTO_LOCK_DSO);
+	return (1);
+}
+
+DSO *
+DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags)
+{
+	DSO *ret;
+	int allocated = 0;
+
+	if (dso == NULL) {
+		ret = DSO_new_method(meth);
+		if (ret == NULL) {
+			DSOerr(DSO_F_DSO_LOAD, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		allocated = 1;
+		/* Pass the provided flags to the new DSO object */
+		if (DSO_ctrl(ret, DSO_CTRL_SET_FLAGS, flags, NULL) < 0) {
+			DSOerr(DSO_F_DSO_LOAD, DSO_R_CTRL_FAILED);
+			goto err;
+		}
+	} else
+		ret = dso;
+	/* Don't load if we're currently already loaded */
+	if (ret->filename != NULL) {
+		DSOerr(DSO_F_DSO_LOAD, DSO_R_DSO_ALREADY_LOADED);
+		goto err;
+	}
+	/* filename can only be NULL if we were passed a dso that already has
+	 * one set. */
+	if (filename != NULL)
+		if (!DSO_set_filename(ret, filename)) {
+		DSOerr(DSO_F_DSO_LOAD, DSO_R_SET_FILENAME_FAILED);
+		goto err;
+	}
+	filename = ret->filename;
+	if (filename == NULL) {
+		DSOerr(DSO_F_DSO_LOAD, DSO_R_NO_FILENAME);
+		goto err;
+	}
+	if (ret->meth->dso_load == NULL) {
+		DSOerr(DSO_F_DSO_LOAD, DSO_R_UNSUPPORTED);
+		goto err;
+	}
+	if (!ret->meth->dso_load(ret)) {
+		DSOerr(DSO_F_DSO_LOAD, DSO_R_LOAD_FAILED);
+		goto err;
+	}
+	/* Load succeeded */
+	return (ret);
+
+err:
+	if (allocated)
+		DSO_free(ret);
+	return (NULL);
+}
+
+void *
+DSO_bind_var(DSO *dso, const char *symname)
+{
+	void *ret = NULL;
+
+	if ((dso == NULL) || (symname == NULL)) {
+		DSOerr(DSO_F_DSO_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER);
+		return (NULL);
+	}
+	if (dso->meth->dso_bind_var == NULL) {
+		DSOerr(DSO_F_DSO_BIND_VAR, DSO_R_UNSUPPORTED);
+		return (NULL);
+	}
+	if ((ret = dso->meth->dso_bind_var(dso, symname)) == NULL) {
+		DSOerr(DSO_F_DSO_BIND_VAR, DSO_R_SYM_FAILURE);
+		return (NULL);
+	}
+	/* Success */
+	return (ret);
+}
+
+DSO_FUNC_TYPE
+DSO_bind_func(DSO *dso, const char *symname)
+{
+	DSO_FUNC_TYPE ret = NULL;
+
+	if ((dso == NULL) || (symname == NULL)) {
+		DSOerr(DSO_F_DSO_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER);
+		return (NULL);
+	}
+	if (dso->meth->dso_bind_func == NULL) {
+		DSOerr(DSO_F_DSO_BIND_FUNC, DSO_R_UNSUPPORTED);
+		return (NULL);
+	}
+	if ((ret = dso->meth->dso_bind_func(dso, symname)) == NULL) {
+		DSOerr(DSO_F_DSO_BIND_FUNC, DSO_R_SYM_FAILURE);
+		return (NULL);
+	}
+	/* Success */
+	return (ret);
+}
+
+/* I don't really like these *_ctrl functions very much to be perfectly
+ * honest. For one thing, I think I have to return a negative value for
+ * any error because possible DSO_ctrl() commands may return values
+ * such as "size"s that can legitimately be zero (making the standard
+ * "if(DSO_cmd(...))" form that works almost everywhere else fail at
+ * odd times. I'd prefer "output" values to be passed by reference and
+ * the return value as success/failure like usual ... but we conform
+ * when we must... :-) */
+long
+DSO_ctrl(DSO *dso, int cmd, long larg, void *parg)
+{
+	if (dso == NULL) {
+		DSOerr(DSO_F_DSO_CTRL, ERR_R_PASSED_NULL_PARAMETER);
+		return (-1);
+	}
+	/* We should intercept certain generic commands and only pass control
+	 * to the method-specific ctrl() function if it's something we don't
+	 * handle. */
+	switch (cmd) {
+	case DSO_CTRL_GET_FLAGS:
+		return dso->flags;
+	case DSO_CTRL_SET_FLAGS:
+		dso->flags = (int)larg;
+		return (0);
+	case DSO_CTRL_OR_FLAGS:
+		dso->flags |= (int)larg;
+		return (0);
+	default:
+		break;
+	}
+	if ((dso->meth == NULL) || (dso->meth->dso_ctrl == NULL)) {
+		DSOerr(DSO_F_DSO_CTRL, DSO_R_UNSUPPORTED);
+		return (-1);
+	}
+	return (dso->meth->dso_ctrl(dso, cmd, larg, parg));
+}
+
+int
+DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb,
+    DSO_NAME_CONVERTER_FUNC *oldcb)
+{
+	if (dso == NULL) {
+		DSOerr(DSO_F_DSO_SET_NAME_CONVERTER,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		return (0);
+	}
+	if (oldcb)
+		*oldcb = dso->name_converter;
+	dso->name_converter = cb;
+	return (1);
+}
+
+const char *
+DSO_get_filename(DSO *dso)
+{
+	if (dso == NULL) {
+		DSOerr(DSO_F_DSO_GET_FILENAME, ERR_R_PASSED_NULL_PARAMETER);
+		return (NULL);
+	}
+	return (dso->filename);
+}
+
+int
+DSO_set_filename(DSO *dso, const char *filename)
+{
+	char *copied;
+
+	if ((dso == NULL) || (filename == NULL)) {
+		DSOerr(DSO_F_DSO_SET_FILENAME, ERR_R_PASSED_NULL_PARAMETER);
+		return (0);
+	}
+	if (dso->loaded_filename) {
+		DSOerr(DSO_F_DSO_SET_FILENAME, DSO_R_DSO_ALREADY_LOADED);
+		return (0);
+	}
+	/* We'll duplicate filename */
+	copied = strdup(filename);
+	if (copied == NULL) {
+		DSOerr(DSO_F_DSO_SET_FILENAME, ERR_R_MALLOC_FAILURE);
+		return (0);
+	}
+	free(dso->filename);
+	dso->filename = copied;
+	return (1);
+}
+
+char *
+DSO_merge(DSO *dso, const char *filespec1, const char *filespec2)
+{
+	char *result = NULL;
+
+	if (dso == NULL || filespec1 == NULL) {
+		DSOerr(DSO_F_DSO_MERGE, ERR_R_PASSED_NULL_PARAMETER);
+		return (NULL);
+	}
+	if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) {
+		if (dso->merger != NULL)
+			result = dso->merger(dso, filespec1, filespec2);
+		else if (dso->meth->dso_merger != NULL)
+			result = dso->meth->dso_merger(dso,
+			    filespec1, filespec2);
+	}
+	return (result);
+}
+
+char *
+DSO_convert_filename(DSO *dso, const char *filename)
+{
+	char *result = NULL;
+
+	if (dso == NULL) {
+		DSOerr(DSO_F_DSO_CONVERT_FILENAME, ERR_R_PASSED_NULL_PARAMETER);
+		return (NULL);
+	}
+	if (filename == NULL)
+		filename = dso->filename;
+	if (filename == NULL) {
+		DSOerr(DSO_F_DSO_CONVERT_FILENAME, DSO_R_NO_FILENAME);
+		return (NULL);
+	}
+	if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) {
+		if (dso->name_converter != NULL)
+			result = dso->name_converter(dso, filename);
+		else if (dso->meth->dso_name_converter != NULL)
+			result = dso->meth->dso_name_converter(dso, filename);
+	}
+	if (result == NULL) {
+		result = strdup(filename);
+		if (result == NULL) {
+			DSOerr(DSO_F_DSO_CONVERT_FILENAME,
+			    ERR_R_MALLOC_FAILURE);
+			return (NULL);
+		}
+	}
+	return (result);
+}
+
+const char *
+DSO_get_loaded_filename(DSO *dso)
+{
+	if (dso == NULL) {
+		DSOerr(DSO_F_DSO_GET_LOADED_FILENAME,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		return (NULL);
+	}
+	return (dso->loaded_filename);
+}
+
+int
+DSO_pathbyaddr(void *addr, char *path, int sz)
+{
+	DSO_METHOD *meth = default_DSO_meth;
+	if (meth == NULL)
+		meth = DSO_METHOD_openssl();
+	if (meth->pathbyaddr == NULL) {
+		DSOerr(DSO_F_DSO_PATHBYADDR, DSO_R_UNSUPPORTED);
+		return -1;
+	}
+	return (*meth->pathbyaddr)(addr, path, sz);
+}
+
+void *
+DSO_global_lookup(const char *name)
+{
+	DSO_METHOD *meth = default_DSO_meth;
+	if (meth == NULL)
+		meth = DSO_METHOD_openssl();
+	if (meth->globallookup == NULL) {
+		DSOerr(DSO_F_DSO_GLOBAL_LOOKUP, DSO_R_UNSUPPORTED);
+		return NULL;
+	}
+	return (*meth->globallookup)(name);
+}
diff --git a/crypto/libressl/crypto/dso/dso_null.c b/crypto/libressl/crypto/dso/dso_null.c
new file mode 100644
index 0000000000..703311c855
--- /dev/null
+++ b/crypto/libressl/crypto/dso/dso_null.c
@@ -0,0 +1,74 @@
+/* $OpenBSD: dso_null.c,v 1.6 2014/06/12 15:49:29 deraadt Exp $ */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* This "NULL" method is provided as the fallback for systems that have
+ * no appropriate support for "shared-libraries". */
+
+#include 
+
+#include 
+
+static DSO_METHOD dso_meth_null = {
+	.name = "NULL shared library method"
+};
+
+DSO_METHOD *
+DSO_METHOD_null(void)
+{
+	return (&dso_meth_null);
+}
diff --git a/crypto/libressl/crypto/dso/dso_openssl.c b/crypto/libressl/crypto/dso/dso_openssl.c
new file mode 100644
index 0000000000..0f2cf59303
--- /dev/null
+++ b/crypto/libressl/crypto/dso/dso_openssl.c
@@ -0,0 +1,75 @@
+/* $OpenBSD: dso_openssl.c,v 1.5 2014/06/12 15:49:29 deraadt Exp $ */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+/* We just pinch the method from an appropriate "default" method. */
+
+DSO_METHOD *
+DSO_METHOD_openssl(void)
+{
+#ifdef DEF_DSO_METHOD
+	return (DEF_DSO_METHOD());
+#elif defined(DSO_DLFCN)
+	return (DSO_METHOD_dlfcn());
+#else
+	return (DSO_METHOD_null());
+#endif
+}
diff --git a/crypto/libressl/crypto/ec/ec2_mult.c b/crypto/libressl/crypto/ec/ec2_mult.c
new file mode 100644
index 0000000000..b8adfb8c6c
--- /dev/null
+++ b/crypto/libressl/crypto/ec/ec2_mult.c
@@ -0,0 +1,450 @@
+/* $OpenBSD: ec2_mult.c,v 1.7 2015/02/09 15:49:22 jsing Exp $ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The software is originally written by Sheueling Chang Shantz and
+ * Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include "ec_lcl.h"
+
+#ifndef OPENSSL_NO_EC2M
+
+
+/* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective
+ * coordinates.
+ * Uses algorithm Mdouble in appendix of
+ *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over
+ *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
+ * modified to not require precomputation of c=b^{2^{m-1}}.
+ */
+static int
+gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, BN_CTX *ctx)
+{
+	BIGNUM *t1;
+	int ret = 0;
+
+	/* Since Mdouble is static we can guarantee that ctx != NULL. */
+	BN_CTX_start(ctx);
+	if ((t1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!group->meth->field_sqr(group, x, x, ctx))
+		goto err;
+	if (!group->meth->field_sqr(group, t1, z, ctx))
+		goto err;
+	if (!group->meth->field_mul(group, z, x, t1, ctx))
+		goto err;
+	if (!group->meth->field_sqr(group, x, x, ctx))
+		goto err;
+	if (!group->meth->field_sqr(group, t1, t1, ctx))
+		goto err;
+	if (!group->meth->field_mul(group, t1, &group->b, t1, ctx))
+		goto err;
+	if (!BN_GF2m_add(x, x, t1))
+		goto err;
+
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	return ret;
+}
+
+/* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery
+ * projective coordinates.
+ * Uses algorithm Madd in appendix of
+ *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over
+ *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
+ */
+static int
+gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, BIGNUM *z1,
+    const BIGNUM *x2, const BIGNUM *z2, BN_CTX *ctx)
+{
+	BIGNUM *t1, *t2;
+	int ret = 0;
+
+	/* Since Madd is static we can guarantee that ctx != NULL. */
+	BN_CTX_start(ctx);
+	if ((t1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((t2 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!BN_copy(t1, x))
+		goto err;
+	if (!group->meth->field_mul(group, x1, x1, z2, ctx))
+		goto err;
+	if (!group->meth->field_mul(group, z1, z1, x2, ctx))
+		goto err;
+	if (!group->meth->field_mul(group, t2, x1, z1, ctx))
+		goto err;
+	if (!BN_GF2m_add(z1, z1, x1))
+		goto err;
+	if (!group->meth->field_sqr(group, z1, z1, ctx))
+		goto err;
+	if (!group->meth->field_mul(group, x1, z1, t1, ctx))
+		goto err;
+	if (!BN_GF2m_add(x1, x1, t2))
+		goto err;
+
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	return ret;
+}
+
+/* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2)
+ * using Montgomery point multiplication algorithm Mxy() in appendix of
+ *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over
+ *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
+ * Returns:
+ *     0 on error
+ *     1 if return value should be the point at infinity
+ *     2 otherwise
+ */
+static int
+gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y, BIGNUM *x1,
+    BIGNUM *z1, BIGNUM *x2, BIGNUM *z2, BN_CTX *ctx)
+{
+	BIGNUM *t3, *t4, *t5;
+	int ret = 0;
+
+	if (BN_is_zero(z1)) {
+		BN_zero(x2);
+		BN_zero(z2);
+		return 1;
+	}
+	if (BN_is_zero(z2)) {
+		if (!BN_copy(x2, x))
+			return 0;
+		if (!BN_GF2m_add(z2, x, y))
+			return 0;
+		return 2;
+	}
+	/* Since Mxy is static we can guarantee that ctx != NULL. */
+	BN_CTX_start(ctx);
+	if ((t3 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((t4 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((t5 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!BN_one(t5))
+		goto err;
+
+	if (!group->meth->field_mul(group, t3, z1, z2, ctx))
+		goto err;
+
+	if (!group->meth->field_mul(group, z1, z1, x, ctx))
+		goto err;
+	if (!BN_GF2m_add(z1, z1, x1))
+		goto err;
+	if (!group->meth->field_mul(group, z2, z2, x, ctx))
+		goto err;
+	if (!group->meth->field_mul(group, x1, z2, x1, ctx))
+		goto err;
+	if (!BN_GF2m_add(z2, z2, x2))
+		goto err;
+
+	if (!group->meth->field_mul(group, z2, z2, z1, ctx))
+		goto err;
+	if (!group->meth->field_sqr(group, t4, x, ctx))
+		goto err;
+	if (!BN_GF2m_add(t4, t4, y))
+		goto err;
+	if (!group->meth->field_mul(group, t4, t4, t3, ctx))
+		goto err;
+	if (!BN_GF2m_add(t4, t4, z2))
+		goto err;
+
+	if (!group->meth->field_mul(group, t3, t3, x, ctx))
+		goto err;
+	if (!group->meth->field_div(group, t3, t5, t3, ctx))
+		goto err;
+	if (!group->meth->field_mul(group, t4, t3, t4, ctx))
+		goto err;
+	if (!group->meth->field_mul(group, x2, x1, t3, ctx))
+		goto err;
+	if (!BN_GF2m_add(z2, x2, x))
+		goto err;
+
+	if (!group->meth->field_mul(group, z2, z2, t4, ctx))
+		goto err;
+	if (!BN_GF2m_add(z2, z2, y))
+		goto err;
+
+	ret = 2;
+
+err:
+	BN_CTX_end(ctx);
+	return ret;
+}
+
+
+/* Computes scalar*point and stores the result in r.
+ * point can not equal r.
+ * Uses a modified algorithm 2P of
+ *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over
+ *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
+ *
+ * To protect against side-channel attack the function uses constant time swap,
+ * avoiding conditional branches.
+ */
+static int
+ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r,
+    const BIGNUM *scalar, const EC_POINT *point, BN_CTX *ctx)
+{
+	BIGNUM *x1, *x2, *z1, *z2;
+	int ret = 0, i;
+	BN_ULONG mask, word;
+
+	if (r == point) {
+		ECerr(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, EC_R_INVALID_ARGUMENT);
+		return 0;
+	}
+	/* if result should be point at infinity */
+	if ((scalar == NULL) || BN_is_zero(scalar) || (point == NULL) ||
+	    EC_POINT_is_at_infinity(group, point) > 0) {
+		return EC_POINT_set_to_infinity(group, r);
+	}
+	/* only support affine coordinates */
+	if (!point->Z_is_one)
+		return 0;
+
+	/* Since point_multiply is static we can guarantee that ctx != NULL. */
+	BN_CTX_start(ctx);
+	if ((x1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((z1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	x2 = &r->X;
+	z2 = &r->Y;
+
+	if (!bn_wexpand(x1, group->field.top))
+                goto err;
+	if (!bn_wexpand(z1, group->field.top))
+                goto err;
+	if (!bn_wexpand(x2, group->field.top))
+                goto err;
+	if (!bn_wexpand(z2, group->field.top))
+                goto err;
+
+	if (!BN_GF2m_mod_arr(x1, &point->X, group->poly))
+		goto err;	/* x1 = x */
+	if (!BN_one(z1))
+		goto err;	/* z1 = 1 */
+	if (!group->meth->field_sqr(group, z2, x1, ctx))
+		goto err;	/* z2 = x1^2 = x^2 */
+	if (!group->meth->field_sqr(group, x2, z2, ctx))
+		goto err;
+	if (!BN_GF2m_add(x2, x2, &group->b))
+		goto err;	/* x2 = x^4 + b */
+
+	/* find top most bit and go one past it */
+	i = scalar->top - 1;
+	mask = BN_TBIT;
+	word = scalar->d[i];
+	while (!(word & mask))
+		mask >>= 1;
+	mask >>= 1;
+	/* if top most bit was at word break, go to next word */
+	if (!mask) {
+		i--;
+		mask = BN_TBIT;
+	}
+	for (; i >= 0; i--) {
+		word = scalar->d[i];
+		while (mask) {
+			BN_consttime_swap(word & mask, x1, x2, group->field.top);
+			BN_consttime_swap(word & mask, z1, z2, group->field.top);
+			if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx))
+				goto err;
+			if (!gf2m_Mdouble(group, x1, z1, ctx))
+				goto err;
+			BN_consttime_swap(word & mask, x1, x2, group->field.top);
+			BN_consttime_swap(word & mask, z1, z2, group->field.top);
+			mask >>= 1;
+		}
+		mask = BN_TBIT;
+	}
+
+	/* convert out of "projective" coordinates */
+	i = gf2m_Mxy(group, &point->X, &point->Y, x1, z1, x2, z2, ctx);
+	if (i == 0)
+		goto err;
+	else if (i == 1) {
+		if (!EC_POINT_set_to_infinity(group, r))
+			goto err;
+	} else {
+		if (!BN_one(&r->Z))
+			goto err;
+		r->Z_is_one = 1;
+	}
+
+	/* GF(2^m) field elements should always have BIGNUM::neg = 0 */
+	BN_set_negative(&r->X, 0);
+	BN_set_negative(&r->Y, 0);
+
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	return ret;
+}
+
+
+/* Computes the sum
+ *     scalar*group->generator + scalars[0]*points[0] + ... + scalars[num-1]*points[num-1]
+ * gracefully ignoring NULL scalar values.
+ */
+int
+ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+    size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
+{
+	BN_CTX *new_ctx = NULL;
+	int ret = 0;
+	size_t i;
+	EC_POINT *p = NULL;
+	EC_POINT *acc = NULL;
+
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+	}
+	/*
+	 * This implementation is more efficient than the wNAF implementation
+	 * for 2 or fewer points.  Use the ec_wNAF_mul implementation for 3
+	 * or more points, or if we can perform a fast multiplication based
+	 * on precomputation.
+	 */
+	if ((scalar && (num > 1)) || (num > 2) ||
+	    (num == 0 && EC_GROUP_have_precompute_mult(group))) {
+		ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
+		goto err;
+	}
+	if ((p = EC_POINT_new(group)) == NULL)
+		goto err;
+	if ((acc = EC_POINT_new(group)) == NULL)
+		goto err;
+
+	if (!EC_POINT_set_to_infinity(group, acc))
+		goto err;
+
+	if (scalar) {
+		if (!ec_GF2m_montgomery_point_multiply(group, p, scalar, group->generator, ctx))
+			goto err;
+		if (BN_is_negative(scalar))
+			if (!group->meth->invert(group, p, ctx))
+				goto err;
+		if (!group->meth->add(group, acc, acc, p, ctx))
+			goto err;
+	}
+	for (i = 0; i < num; i++) {
+		if (!ec_GF2m_montgomery_point_multiply(group, p, scalars[i], points[i], ctx))
+			goto err;
+		if (BN_is_negative(scalars[i]))
+			if (!group->meth->invert(group, p, ctx))
+				goto err;
+		if (!group->meth->add(group, acc, acc, p, ctx))
+			goto err;
+	}
+
+	if (!EC_POINT_copy(r, acc))
+		goto err;
+
+	ret = 1;
+
+err:
+	EC_POINT_free(p);
+	EC_POINT_free(acc);
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+
+
+/* Precomputation for point multiplication: fall back to wNAF methods
+ * because ec_GF2m_simple_mul() uses ec_wNAF_mul() if appropriate */
+
+int
+ec_GF2m_precompute_mult(EC_GROUP * group, BN_CTX * ctx)
+{
+	return ec_wNAF_precompute_mult(group, ctx);
+}
+
+int
+ec_GF2m_have_precompute_mult(const EC_GROUP * group)
+{
+	return ec_wNAF_have_precompute_mult(group);
+}
+
+#endif
diff --git a/crypto/libressl/crypto/ec/ec2_oct.c b/crypto/libressl/crypto/ec/ec2_oct.c
new file mode 100644
index 0000000000..e94a28e0de
--- /dev/null
+++ b/crypto/libressl/crypto/ec/ec2_oct.c
@@ -0,0 +1,382 @@
+/* $OpenBSD: ec2_oct.c,v 1.6 2015/02/08 22:25:03 miod Exp $ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The software is originally written by Sheueling Chang Shantz and
+ * Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include "ec_lcl.h"
+
+#ifndef OPENSSL_NO_EC2M
+
+/* Calculates and sets the affine coordinates of an EC_POINT from the given
+ * compressed coordinates.  Uses algorithm 2.3.4 of SEC 1.
+ * Note that the simple implementation only uses affine coordinates.
+ *
+ * The method is from the following publication:
+ *
+ *     Harper, Menezes, Vanstone:
+ *     "Public-Key Cryptosystems with Very Small Key Lengths",
+ *     EUROCRYPT '92, Springer-Verlag LNCS 658,
+ *     published February 1993
+ *
+ * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe
+ * the same method, but claim no priority date earlier than July 29, 1994
+ * (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
+ */
+int 
+ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
+    const BIGNUM *x_, int y_bit, BN_CTX *ctx)
+{
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *tmp, *x, *y, *z;
+	int ret = 0, z0;
+
+	/* clear error queue */
+	ERR_clear_error();
+
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+	}
+	y_bit = (y_bit != 0) ? 1 : 0;
+
+	BN_CTX_start(ctx);
+	if ((tmp = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((x = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((y = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((z = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!BN_GF2m_mod_arr(x, x_, group->poly))
+		goto err;
+	if (BN_is_zero(x)) {
+		if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx))
+			goto err;
+	} else {
+		if (!group->meth->field_sqr(group, tmp, x, ctx))
+			goto err;
+		if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx))
+			goto err;
+		if (!BN_GF2m_add(tmp, &group->a, tmp))
+			goto err;
+		if (!BN_GF2m_add(tmp, x, tmp))
+			goto err;
+		if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx)) {
+			unsigned long err = ERR_peek_last_error();
+
+			if (ERR_GET_LIB(err) == ERR_LIB_BN &&
+			    ERR_GET_REASON(err) == BN_R_NO_SOLUTION) {
+				ERR_clear_error();
+				ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
+			} else
+				ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
+			goto err;
+		}
+		z0 = (BN_is_odd(z)) ? 1 : 0;
+		if (!group->meth->field_mul(group, y, x, z, ctx))
+			goto err;
+		if (z0 != y_bit) {
+			if (!BN_GF2m_add(y, y, x))
+				goto err;
+		}
+	}
+
+	if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx))
+		goto err;
+
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+
+
+/* Converts an EC_POINT to an octet string.
+ * If buf is NULL, the encoded length will be returned.
+ * If the length len of buf is smaller than required an error will be returned.
+ */
+size_t 
+ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
+    point_conversion_form_t form,
+    unsigned char *buf, size_t len, BN_CTX * ctx)
+{
+	size_t ret;
+	BN_CTX *new_ctx = NULL;
+	int used_ctx = 0;
+	BIGNUM *x, *y, *yxi;
+	size_t field_len, i, skip;
+
+	if ((form != POINT_CONVERSION_COMPRESSED)
+	    && (form != POINT_CONVERSION_UNCOMPRESSED)
+	    && (form != POINT_CONVERSION_HYBRID)) {
+		ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
+		goto err;
+	}
+	if (EC_POINT_is_at_infinity(group, point) > 0) {
+		/* encodes to a single 0 octet */
+		if (buf != NULL) {
+			if (len < 1) {
+				ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+				return 0;
+			}
+			buf[0] = 0;
+		}
+		return 1;
+	}
+	/* ret := required output buffer length */
+	field_len = (EC_GROUP_get_degree(group) + 7) / 8;
+	ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len :
+	    1 + 2 * field_len;
+
+	/* if 'buf' is NULL, just return required length */
+	if (buf != NULL) {
+		if (len < ret) {
+			ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+			goto err;
+		}
+		if (ctx == NULL) {
+			ctx = new_ctx = BN_CTX_new();
+			if (ctx == NULL)
+				return 0;
+		}
+		BN_CTX_start(ctx);
+		used_ctx = 1;
+		if ((x = BN_CTX_get(ctx)) == NULL)
+			goto err;
+		if ((y = BN_CTX_get(ctx)) == NULL)
+			goto err;
+		if ((yxi = BN_CTX_get(ctx)) == NULL)
+			goto err;
+
+		if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx))
+			goto err;
+
+		buf[0] = form;
+		if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x)) {
+			if (!group->meth->field_div(group, yxi, y, x, ctx))
+				goto err;
+			if (BN_is_odd(yxi))
+				buf[0]++;
+		}
+		i = 1;
+
+		skip = field_len - BN_num_bytes(x);
+		if (skip > field_len) {
+			ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+			goto err;
+		}
+		while (skip > 0) {
+			buf[i++] = 0;
+			skip--;
+		}
+		skip = BN_bn2bin(x, buf + i);
+		i += skip;
+		if (i != 1 + field_len) {
+			ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+			goto err;
+		}
+		if (form == POINT_CONVERSION_UNCOMPRESSED ||
+		    form == POINT_CONVERSION_HYBRID) {
+			skip = field_len - BN_num_bytes(y);
+			if (skip > field_len) {
+				ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+				goto err;
+			}
+			while (skip > 0) {
+				buf[i++] = 0;
+				skip--;
+			}
+			skip = BN_bn2bin(y, buf + i);
+			i += skip;
+		}
+		if (i != ret) {
+			ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+			goto err;
+		}
+	}
+	if (used_ctx)
+		BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return ret;
+
+err:
+	if (used_ctx)
+		BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return 0;
+}
+
+
+/* Converts an octet string representation to an EC_POINT.
+ * Note that the simple implementation only uses affine coordinates.
+ */
+int 
+ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
+    const unsigned char *buf, size_t len, BN_CTX *ctx)
+{
+	point_conversion_form_t form;
+	int y_bit;
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *x, *y, *yxi;
+	size_t field_len, enc_len;
+	int ret = 0;
+
+	if (len == 0) {
+		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
+		return 0;
+	}
+	form = buf[0];
+	y_bit = form & 1;
+	form = form & ~1U;
+	if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) &&
+	    (form != POINT_CONVERSION_UNCOMPRESSED) &&
+	    (form != POINT_CONVERSION_HYBRID)) {
+		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+		return 0;
+	}
+	if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
+		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+		return 0;
+	}
+	if (form == 0) {
+		if (len != 1) {
+			ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+			return 0;
+		}
+		return EC_POINT_set_to_infinity(group, point);
+	}
+	field_len = (EC_GROUP_get_degree(group) + 7) / 8;
+	enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len :
+	    1 + 2 * field_len;
+
+	if (len != enc_len) {
+		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+		return 0;
+	}
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+	}
+	BN_CTX_start(ctx);
+	if ((x = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((y = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((yxi = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!BN_bin2bn(buf + 1, field_len, x))
+		goto err;
+	if (BN_ucmp(x, &group->field) >= 0) {
+		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+		goto err;
+	}
+	if (form == POINT_CONVERSION_COMPRESSED) {
+		if (!EC_POINT_set_compressed_coordinates_GF2m(group, point, x, y_bit, ctx))
+			goto err;
+	} else {
+		if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
+			goto err;
+		if (BN_ucmp(y, &group->field) >= 0) {
+			ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+			goto err;
+		}
+		if (form == POINT_CONVERSION_HYBRID) {
+			if (!group->meth->field_div(group, yxi, y, x, ctx))
+				goto err;
+			if (y_bit != BN_is_odd(yxi)) {
+				ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+				goto err;
+			}
+		}
+		if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx))
+			goto err;
+	}
+
+	/* test required by X9.62 */
+	if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
+		ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
+		goto err;
+	}
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+#endif
diff --git a/crypto/libressl/crypto/ec/ec2_smpl.c b/crypto/libressl/crypto/ec/ec2_smpl.c
new file mode 100644
index 0000000000..638b69635c
--- /dev/null
+++ b/crypto/libressl/crypto/ec/ec2_smpl.c
@@ -0,0 +1,787 @@
+/* $OpenBSD: ec2_smpl.c,v 1.13 2015/02/08 22:25:03 miod Exp $ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The software is originally written by Sheueling Chang Shantz and
+ * Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include "ec_lcl.h"
+
+#ifndef OPENSSL_NO_EC2M
+
+const EC_METHOD *
+EC_GF2m_simple_method(void)
+{
+	static const EC_METHOD ret = {
+		.flags = EC_FLAGS_DEFAULT_OCT,
+		.field_type = NID_X9_62_characteristic_two_field,
+		.group_init = ec_GF2m_simple_group_init,
+		.group_finish = ec_GF2m_simple_group_finish,
+		.group_clear_finish = ec_GF2m_simple_group_clear_finish,
+		.group_copy = ec_GF2m_simple_group_copy,
+		.group_set_curve = ec_GF2m_simple_group_set_curve,
+		.group_get_curve = ec_GF2m_simple_group_get_curve,
+		.group_get_degree = ec_GF2m_simple_group_get_degree,
+		.group_check_discriminant =
+		ec_GF2m_simple_group_check_discriminant,
+		.point_init = ec_GF2m_simple_point_init,
+		.point_finish = ec_GF2m_simple_point_finish,
+		.point_clear_finish = ec_GF2m_simple_point_clear_finish,
+		.point_copy = ec_GF2m_simple_point_copy,
+		.point_set_to_infinity = ec_GF2m_simple_point_set_to_infinity,
+		.point_set_affine_coordinates =
+		ec_GF2m_simple_point_set_affine_coordinates,
+		.point_get_affine_coordinates =
+		ec_GF2m_simple_point_get_affine_coordinates,
+		.add = ec_GF2m_simple_add,
+		.dbl = ec_GF2m_simple_dbl,
+		.invert = ec_GF2m_simple_invert,
+		.is_at_infinity = ec_GF2m_simple_is_at_infinity,
+		.is_on_curve = ec_GF2m_simple_is_on_curve,
+		.point_cmp = ec_GF2m_simple_cmp,
+		.make_affine = ec_GF2m_simple_make_affine,
+		.points_make_affine = ec_GF2m_simple_points_make_affine,
+
+		/*
+		 * the following three method functions are defined in
+		 * ec2_mult.c
+		 */
+		.mul = ec_GF2m_simple_mul,
+		.precompute_mult = ec_GF2m_precompute_mult,
+		.have_precompute_mult = ec_GF2m_have_precompute_mult,
+
+		.field_mul = ec_GF2m_simple_field_mul,
+		.field_sqr = ec_GF2m_simple_field_sqr,
+		.field_div = ec_GF2m_simple_field_div,
+	};
+
+	return &ret;
+}
+
+
+/* Initialize a GF(2^m)-based EC_GROUP structure.
+ * Note that all other members are handled by EC_GROUP_new.
+ */
+int 
+ec_GF2m_simple_group_init(EC_GROUP * group)
+{
+	BN_init(&group->field);
+	BN_init(&group->a);
+	BN_init(&group->b);
+	return 1;
+}
+
+
+/* Free a GF(2^m)-based EC_GROUP structure.
+ * Note that all other members are handled by EC_GROUP_free.
+ */
+void 
+ec_GF2m_simple_group_finish(EC_GROUP * group)
+{
+	BN_free(&group->field);
+	BN_free(&group->a);
+	BN_free(&group->b);
+}
+
+
+/* Clear and free a GF(2^m)-based EC_GROUP structure.
+ * Note that all other members are handled by EC_GROUP_clear_free.
+ */
+void 
+ec_GF2m_simple_group_clear_finish(EC_GROUP * group)
+{
+	BN_clear_free(&group->field);
+	BN_clear_free(&group->a);
+	BN_clear_free(&group->b);
+	group->poly[0] = 0;
+	group->poly[1] = 0;
+	group->poly[2] = 0;
+	group->poly[3] = 0;
+	group->poly[4] = 0;
+	group->poly[5] = -1;
+}
+
+
+/* Copy a GF(2^m)-based EC_GROUP structure.
+ * Note that all other members are handled by EC_GROUP_copy.
+ */
+int 
+ec_GF2m_simple_group_copy(EC_GROUP * dest, const EC_GROUP * src)
+{
+	int i;
+
+	if (!BN_copy(&dest->field, &src->field))
+		return 0;
+	if (!BN_copy(&dest->a, &src->a))
+		return 0;
+	if (!BN_copy(&dest->b, &src->b))
+		return 0;
+	dest->poly[0] = src->poly[0];
+	dest->poly[1] = src->poly[1];
+	dest->poly[2] = src->poly[2];
+	dest->poly[3] = src->poly[3];
+	dest->poly[4] = src->poly[4];
+	dest->poly[5] = src->poly[5];
+	if (bn_wexpand(&dest->a, (int) (dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL)
+		return 0;
+	if (bn_wexpand(&dest->b, (int) (dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL)
+		return 0;
+	for (i = dest->a.top; i < dest->a.dmax; i++)
+		dest->a.d[i] = 0;
+	for (i = dest->b.top; i < dest->b.dmax; i++)
+		dest->b.d[i] = 0;
+	return 1;
+}
+
+
+/* Set the curve parameters of an EC_GROUP structure. */
+int 
+ec_GF2m_simple_group_set_curve(EC_GROUP * group,
+    const BIGNUM * p, const BIGNUM * a, const BIGNUM * b, BN_CTX * ctx)
+{
+	int ret = 0, i;
+
+	/* group->field */
+	if (!BN_copy(&group->field, p))
+		goto err;
+	i = BN_GF2m_poly2arr(&group->field, group->poly, 6) - 1;
+	if ((i != 5) && (i != 3)) {
+		ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD);
+		goto err;
+	}
+	/* group->a */
+	if (!BN_GF2m_mod_arr(&group->a, a, group->poly))
+		goto err;
+	if (bn_wexpand(&group->a, (int) (group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL)
+		goto err;
+	for (i = group->a.top; i < group->a.dmax; i++)
+		group->a.d[i] = 0;
+
+	/* group->b */
+	if (!BN_GF2m_mod_arr(&group->b, b, group->poly))
+		goto err;
+	if (bn_wexpand(&group->b, (int) (group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL)
+		goto err;
+	for (i = group->b.top; i < group->b.dmax; i++)
+		group->b.d[i] = 0;
+
+	ret = 1;
+err:
+	return ret;
+}
+
+
+/* Get the curve parameters of an EC_GROUP structure.
+ * If p, a, or b are NULL then there values will not be set but the method will return with success.
+ */
+int 
+ec_GF2m_simple_group_get_curve(const EC_GROUP *group,
+    BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
+{
+	int ret = 0;
+
+	if (p != NULL) {
+		if (!BN_copy(p, &group->field))
+			return 0;
+	}
+	if (a != NULL) {
+		if (!BN_copy(a, &group->a))
+			goto err;
+	}
+	if (b != NULL) {
+		if (!BN_copy(b, &group->b))
+			goto err;
+	}
+	ret = 1;
+
+err:
+	return ret;
+}
+
+
+/* Gets the degree of the field.  For a curve over GF(2^m) this is the value m. */
+int 
+ec_GF2m_simple_group_get_degree(const EC_GROUP * group)
+{
+	return BN_num_bits(&group->field) - 1;
+}
+
+
+/* Checks the discriminant of the curve.
+ * y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p)
+ */
+int 
+ec_GF2m_simple_group_check_discriminant(const EC_GROUP * group, BN_CTX * ctx)
+{
+	int ret = 0;
+	BIGNUM *b;
+	BN_CTX *new_ctx = NULL;
+
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL) {
+			ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+	}
+	BN_CTX_start(ctx);
+	if ((b = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!BN_GF2m_mod_arr(b, &group->b, group->poly))
+		goto err;
+
+	/*
+	 * check the discriminant: y^2 + x*y = x^3 + a*x^2 + b is an elliptic
+	 * curve <=> b != 0 (mod p)
+	 */
+	if (BN_is_zero(b))
+		goto err;
+
+	ret = 1;
+
+err:
+	if (ctx != NULL)
+		BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+
+
+/* Initializes an EC_POINT. */
+int 
+ec_GF2m_simple_point_init(EC_POINT * point)
+{
+	BN_init(&point->X);
+	BN_init(&point->Y);
+	BN_init(&point->Z);
+	return 1;
+}
+
+
+/* Frees an EC_POINT. */
+void 
+ec_GF2m_simple_point_finish(EC_POINT * point)
+{
+	BN_free(&point->X);
+	BN_free(&point->Y);
+	BN_free(&point->Z);
+}
+
+
+/* Clears and frees an EC_POINT. */
+void 
+ec_GF2m_simple_point_clear_finish(EC_POINT * point)
+{
+	BN_clear_free(&point->X);
+	BN_clear_free(&point->Y);
+	BN_clear_free(&point->Z);
+	point->Z_is_one = 0;
+}
+
+
+/* Copy the contents of one EC_POINT into another.  Assumes dest is initialized. */
+int 
+ec_GF2m_simple_point_copy(EC_POINT * dest, const EC_POINT * src)
+{
+	if (!BN_copy(&dest->X, &src->X))
+		return 0;
+	if (!BN_copy(&dest->Y, &src->Y))
+		return 0;
+	if (!BN_copy(&dest->Z, &src->Z))
+		return 0;
+	dest->Z_is_one = src->Z_is_one;
+
+	return 1;
+}
+
+
+/* Set an EC_POINT to the point at infinity.
+ * A point at infinity is represented by having Z=0.
+ */
+int 
+ec_GF2m_simple_point_set_to_infinity(const EC_GROUP * group, EC_POINT * point)
+{
+	point->Z_is_one = 0;
+	BN_zero(&point->Z);
+	return 1;
+}
+
+
+/* Set the coordinates of an EC_POINT using affine coordinates.
+ * Note that the simple implementation only uses affine coordinates.
+ */
+int 
+ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP * group, EC_POINT * point,
+    const BIGNUM * x, const BIGNUM * y, BN_CTX * ctx)
+{
+	int ret = 0;
+	if (x == NULL || y == NULL) {
+		ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	if (!BN_copy(&point->X, x))
+		goto err;
+	BN_set_negative(&point->X, 0);
+	if (!BN_copy(&point->Y, y))
+		goto err;
+	BN_set_negative(&point->Y, 0);
+	if (!BN_copy(&point->Z, BN_value_one()))
+		goto err;
+	BN_set_negative(&point->Z, 0);
+	point->Z_is_one = 1;
+	ret = 1;
+
+err:
+	return ret;
+}
+
+
+/* Gets the affine coordinates of an EC_POINT.
+ * Note that the simple implementation only uses affine coordinates.
+ */
+int 
+ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group,
+    const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
+{
+	int ret = 0;
+
+	if (EC_POINT_is_at_infinity(group, point) > 0) {
+		ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY);
+		return 0;
+	}
+	if (BN_cmp(&point->Z, BN_value_one())) {
+		ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if (x != NULL) {
+		if (!BN_copy(x, &point->X))
+			goto err;
+		BN_set_negative(x, 0);
+	}
+	if (y != NULL) {
+		if (!BN_copy(y, &point->Y))
+			goto err;
+		BN_set_negative(y, 0);
+	}
+	ret = 1;
+
+err:
+	return ret;
+}
+
+/* Computes a + b and stores the result in r.  r could be a or b, a could be b.
+ * Uses algorithm A.10.2 of IEEE P1363.
+ */
+int 
+ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+    const EC_POINT *b, BN_CTX *ctx)
+{
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t;
+	int ret = 0;
+
+	if (EC_POINT_is_at_infinity(group, a) > 0) {
+		if (!EC_POINT_copy(r, b))
+			return 0;
+		return 1;
+	}
+	if (EC_POINT_is_at_infinity(group, b) > 0) {
+		if (!EC_POINT_copy(r, a))
+			return 0;
+		return 1;
+	}
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+	}
+	BN_CTX_start(ctx);
+	if ((x0 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((y0 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((x1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((y1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((x2 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((y2 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((s = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((t = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (a->Z_is_one) {
+		if (!BN_copy(x0, &a->X))
+			goto err;
+		if (!BN_copy(y0, &a->Y))
+			goto err;
+	} else {
+		if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x0, y0, ctx))
+			goto err;
+	}
+	if (b->Z_is_one) {
+		if (!BN_copy(x1, &b->X))
+			goto err;
+		if (!BN_copy(y1, &b->Y))
+			goto err;
+	} else {
+		if (!EC_POINT_get_affine_coordinates_GF2m(group, b, x1, y1, ctx))
+			goto err;
+	}
+
+
+	if (BN_GF2m_cmp(x0, x1)) {
+		if (!BN_GF2m_add(t, x0, x1))
+			goto err;
+		if (!BN_GF2m_add(s, y0, y1))
+			goto err;
+		if (!group->meth->field_div(group, s, s, t, ctx))
+			goto err;
+		if (!group->meth->field_sqr(group, x2, s, ctx))
+			goto err;
+		if (!BN_GF2m_add(x2, x2, &group->a))
+			goto err;
+		if (!BN_GF2m_add(x2, x2, s))
+			goto err;
+		if (!BN_GF2m_add(x2, x2, t))
+			goto err;
+	} else {
+		if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1)) {
+			if (!EC_POINT_set_to_infinity(group, r))
+				goto err;
+			ret = 1;
+			goto err;
+		}
+		if (!group->meth->field_div(group, s, y1, x1, ctx))
+			goto err;
+		if (!BN_GF2m_add(s, s, x1))
+			goto err;
+
+		if (!group->meth->field_sqr(group, x2, s, ctx))
+			goto err;
+		if (!BN_GF2m_add(x2, x2, s))
+			goto err;
+		if (!BN_GF2m_add(x2, x2, &group->a))
+			goto err;
+	}
+
+	if (!BN_GF2m_add(y2, x1, x2))
+		goto err;
+	if (!group->meth->field_mul(group, y2, y2, s, ctx))
+		goto err;
+	if (!BN_GF2m_add(y2, y2, x2))
+		goto err;
+	if (!BN_GF2m_add(y2, y2, y1))
+		goto err;
+
+	if (!EC_POINT_set_affine_coordinates_GF2m(group, r, x2, y2, ctx))
+		goto err;
+
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+
+
+/* Computes 2 * a and stores the result in r.  r could be a.
+ * Uses algorithm A.10.2 of IEEE P1363.
+ */
+int 
+ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+    BN_CTX *ctx)
+{
+	return ec_GF2m_simple_add(group, r, a, a, ctx);
+}
+
+int 
+ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
+{
+	if (EC_POINT_is_at_infinity(group, point) > 0 || BN_is_zero(&point->Y))
+		/* point is its own inverse */
+		return 1;
+
+	if (!EC_POINT_make_affine(group, point, ctx))
+		return 0;
+	return BN_GF2m_add(&point->Y, &point->X, &point->Y);
+}
+
+
+/* Indicates whether the given point is the point at infinity. */
+int 
+ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
+{
+	return BN_is_zero(&point->Z);
+}
+
+
+/* Determines whether the given EC_POINT is an actual point on the curve defined
+ * in the EC_GROUP.  A point is valid if it satisfies the Weierstrass equation:
+ *      y^2 + x*y = x^3 + a*x^2 + b.
+ */
+int 
+ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
+{
+	int ret = -1;
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *lh, *y2;
+	int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
+	int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+
+	if (EC_POINT_is_at_infinity(group, point) > 0)
+		return 1;
+
+	field_mul = group->meth->field_mul;
+	field_sqr = group->meth->field_sqr;
+
+	/* only support affine coordinates */
+	if (!point->Z_is_one)
+		return -1;
+
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return -1;
+	}
+	BN_CTX_start(ctx);
+	if ((y2 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((lh = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	/*
+	 * We have a curve defined by a Weierstrass equation y^2 + x*y = x^3
+	 * + a*x^2 + b. <=> x^3 + a*x^2 + x*y + b + y^2 = 0 <=> ((x + a) * x
+	 * + y ) * x + b + y^2 = 0
+	 */
+	if (!BN_GF2m_add(lh, &point->X, &group->a))
+		goto err;
+	if (!field_mul(group, lh, lh, &point->X, ctx))
+		goto err;
+	if (!BN_GF2m_add(lh, lh, &point->Y))
+		goto err;
+	if (!field_mul(group, lh, lh, &point->X, ctx))
+		goto err;
+	if (!BN_GF2m_add(lh, lh, &group->b))
+		goto err;
+	if (!field_sqr(group, y2, &point->Y, ctx))
+		goto err;
+	if (!BN_GF2m_add(lh, lh, y2))
+		goto err;
+	ret = BN_is_zero(lh);
+err:
+	if (ctx)
+		BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+
+
+/* Indicates whether two points are equal.
+ * Return values:
+ *  -1   error
+ *   0   equal (in affine coordinates)
+ *   1   not equal
+ */
+int 
+ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
+    const EC_POINT *b, BN_CTX *ctx)
+{
+	BIGNUM *aX, *aY, *bX, *bY;
+	BN_CTX *new_ctx = NULL;
+	int ret = -1;
+
+	if (EC_POINT_is_at_infinity(group, a) > 0) {
+		return EC_POINT_is_at_infinity(group, b) > 0 ? 0 : 1;
+	}
+	if (EC_POINT_is_at_infinity(group, b) > 0)
+		return 1;
+
+	if (a->Z_is_one && b->Z_is_one) {
+		return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
+	}
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return -1;
+	}
+	BN_CTX_start(ctx);
+	if ((aX = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((aY = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((bX = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((bY = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!EC_POINT_get_affine_coordinates_GF2m(group, a, aX, aY, ctx))
+		goto err;
+	if (!EC_POINT_get_affine_coordinates_GF2m(group, b, bX, bY, ctx))
+		goto err;
+	ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1;
+
+err:
+	if (ctx)
+		BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+
+
+/* Forces the given EC_POINT to internally use affine coordinates. */
+int 
+ec_GF2m_simple_make_affine(const EC_GROUP * group, EC_POINT * point, BN_CTX * ctx)
+{
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *x, *y;
+	int ret = 0;
+
+	if (point->Z_is_one || EC_POINT_is_at_infinity(group, point) > 0)
+		return 1;
+
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+	}
+	BN_CTX_start(ctx);
+	if ((x = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((y = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx))
+		goto err;
+	if (!BN_copy(&point->X, x))
+		goto err;
+	if (!BN_copy(&point->Y, y))
+		goto err;
+	if (!BN_one(&point->Z))
+		goto err;
+
+	ret = 1;
+
+err:
+	if (ctx)
+		BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+
+
+/* Forces each of the EC_POINTs in the given array to use affine coordinates. */
+int 
+ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num,
+    EC_POINT *points[], BN_CTX *ctx)
+{
+	size_t i;
+
+	for (i = 0; i < num; i++) {
+		if (!group->meth->make_affine(group, points[i], ctx))
+			return 0;
+	}
+
+	return 1;
+}
+
+
+/* Wrapper to simple binary polynomial field multiplication implementation. */
+int 
+ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+    const BIGNUM *b, BN_CTX *ctx)
+{
+	return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx);
+}
+
+
+/* Wrapper to simple binary polynomial field squaring implementation. */
+int 
+ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+    BN_CTX *ctx)
+{
+	return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx);
+}
+
+
+/* Wrapper to simple binary polynomial field division implementation. */
+int 
+ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+    const BIGNUM *b, BN_CTX *ctx)
+{
+	return BN_GF2m_mod_div(r, a, b, &group->field, ctx);
+}
+
+#endif
diff --git a/crypto/libressl/crypto/ec/ec_ameth.c b/crypto/libressl/crypto/ec/ec_ameth.c
new file mode 100644
index 0000000000..cfe7be1d2e
--- /dev/null
+++ b/crypto/libressl/crypto/ec/ec_ameth.c
@@ -0,0 +1,636 @@
+/* $OpenBSD: ec_ameth.c,v 1.15 2015/02/11 03:55:42 beck Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_CMS
+#include 
+#endif
+
+#include "asn1_locl.h"
+
+static int 
+eckey_param2type(int *pptype, void **ppval, EC_KEY * ec_key)
+{
+	const EC_GROUP *group;
+	int nid;
+	if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
+		ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS);
+		return 0;
+	}
+	if (EC_GROUP_get_asn1_flag(group) &&
+	    (nid = EC_GROUP_get_curve_name(group))) {
+		/* we have a 'named curve' => just set the OID */
+		*ppval = OBJ_nid2obj(nid);
+		*pptype = V_ASN1_OBJECT;
+	} else {
+		/* explicit parameters */
+		ASN1_STRING *pstr = NULL;
+		pstr = ASN1_STRING_new();
+		if (!pstr)
+			return 0;
+		pstr->length = i2d_ECParameters(ec_key, &pstr->data);
+		if (pstr->length <= 0) {
+			ASN1_STRING_free(pstr);
+			ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
+			return 0;
+		}
+		*ppval = pstr;
+		*pptype = V_ASN1_SEQUENCE;
+	}
+	return 1;
+}
+
+static int 
+eckey_pub_encode(X509_PUBKEY * pk, const EVP_PKEY * pkey)
+{
+	EC_KEY *ec_key = pkey->pkey.ec;
+	void *pval = NULL;
+	int ptype;
+	unsigned char *penc = NULL, *p;
+	int penclen;
+
+	if (!eckey_param2type(&ptype, &pval, ec_key)) {
+		ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB);
+		return 0;
+	}
+	penclen = i2o_ECPublicKey(ec_key, NULL);
+	if (penclen <= 0)
+		goto err;
+	penc = malloc(penclen);
+	if (!penc)
+		goto err;
+	p = penc;
+	penclen = i2o_ECPublicKey(ec_key, &p);
+	if (penclen <= 0)
+		goto err;
+	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
+		ptype, pval, penc, penclen))
+		return 1;
+err:
+	if (ptype == V_ASN1_OBJECT)
+		ASN1_OBJECT_free(pval);
+	else
+		ASN1_STRING_free(pval);
+	free(penc);
+	return 0;
+}
+
+static EC_KEY *
+eckey_type2param(int ptype, void *pval)
+{
+	EC_KEY *eckey = NULL;
+
+	if (ptype == V_ASN1_SEQUENCE) {
+		ASN1_STRING *pstr = pval;
+		const unsigned char *pm = NULL;
+		int pmlen;
+
+		pm = pstr->data;
+		pmlen = pstr->length;
+		if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen))) {
+			ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
+			goto ecerr;
+		}
+	} else if (ptype == V_ASN1_OBJECT) {
+		ASN1_OBJECT *poid = pval;
+		EC_GROUP *group;
+
+		/*
+		 * type == V_ASN1_OBJECT => the parameters are given by an
+		 * asn1 OID
+		 */
+		if ((eckey = EC_KEY_new()) == NULL) {
+			ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE);
+			goto ecerr;
+		}
+		group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
+		if (group == NULL)
+			goto ecerr;
+		EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
+		if (EC_KEY_set_group(eckey, group) == 0)
+			goto ecerr;
+		EC_GROUP_free(group);
+	} else {
+		ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
+		goto ecerr;
+	}
+
+	return eckey;
+
+ecerr:
+	if (eckey)
+		EC_KEY_free(eckey);
+	return NULL;
+}
+
+static int 
+eckey_pub_decode(EVP_PKEY * pkey, X509_PUBKEY * pubkey)
+{
+	const unsigned char *p = NULL;
+	void *pval;
+	int ptype, pklen;
+	EC_KEY *eckey = NULL;
+	X509_ALGOR *palg;
+
+	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
+		return 0;
+	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+	eckey = eckey_type2param(ptype, pval);
+
+	if (!eckey) {
+		ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB);
+		return 0;
+	}
+	/* We have parameters now set public key */
+	if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
+		ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
+		goto ecerr;
+	}
+	EVP_PKEY_assign_EC_KEY(pkey, eckey);
+	return 1;
+
+ecerr:
+	if (eckey)
+		EC_KEY_free(eckey);
+	return 0;
+}
+
+static int 
+eckey_pub_cmp(const EVP_PKEY * a, const EVP_PKEY * b)
+{
+	int r;
+	const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
+	const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), *pb = EC_KEY_get0_public_key(b->pkey.ec);
+
+	r = EC_POINT_cmp(group, pa, pb, NULL);
+	if (r == 0)
+		return 1;
+	if (r == 1)
+		return 0;
+	return -2;
+}
+
+static int 
+eckey_priv_decode(EVP_PKEY * pkey, PKCS8_PRIV_KEY_INFO * p8)
+{
+	const unsigned char *p = NULL;
+	void *pval;
+	int ptype, pklen;
+	EC_KEY *eckey = NULL;
+	X509_ALGOR *palg;
+
+	if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
+		return 0;
+	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+	eckey = eckey_type2param(ptype, pval);
+
+	if (!eckey)
+		goto ecliberr;
+
+	/* We have parameters now set private key */
+	if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
+		ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
+		goto ecerr;
+	}
+	/* calculate public key (if necessary) */
+	if (EC_KEY_get0_public_key(eckey) == NULL) {
+		const BIGNUM *priv_key;
+		const EC_GROUP *group;
+		EC_POINT *pub_key;
+		/*
+		 * the public key was not included in the SEC1 private key =>
+		 * calculate the public key
+		 */
+		group = EC_KEY_get0_group(eckey);
+		pub_key = EC_POINT_new(group);
+		if (pub_key == NULL) {
+			ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
+			goto ecliberr;
+		}
+		if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
+			EC_POINT_free(pub_key);
+			ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
+			goto ecliberr;
+		}
+		priv_key = EC_KEY_get0_private_key(eckey);
+		if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) {
+			EC_POINT_free(pub_key);
+			ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
+			goto ecliberr;
+		}
+		if (EC_KEY_set_public_key(eckey, pub_key) == 0) {
+			EC_POINT_free(pub_key);
+			ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
+			goto ecliberr;
+		}
+		EC_POINT_free(pub_key);
+	}
+	EVP_PKEY_assign_EC_KEY(pkey, eckey);
+	return 1;
+
+ecliberr:
+	ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
+ecerr:
+	if (eckey)
+		EC_KEY_free(eckey);
+	return 0;
+}
+
+static int 
+eckey_priv_encode(PKCS8_PRIV_KEY_INFO * p8, const EVP_PKEY * pkey)
+{
+	EC_KEY *ec_key;
+	unsigned char *ep, *p;
+	int eplen, ptype;
+	void *pval;
+	unsigned int tmp_flags, old_flags;
+
+	ec_key = pkey->pkey.ec;
+
+	if (!eckey_param2type(&ptype, &pval, ec_key)) {
+		ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR);
+		return 0;
+	}
+	/* set the private key */
+
+	/*
+	 * do not include the parameters in the SEC1 private key see PKCS#11
+	 * 12.11
+	 */
+	old_flags = EC_KEY_get_enc_flags(ec_key);
+	tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
+	EC_KEY_set_enc_flags(ec_key, tmp_flags);
+	eplen = i2d_ECPrivateKey(ec_key, NULL);
+	if (!eplen) {
+		EC_KEY_set_enc_flags(ec_key, old_flags);
+		ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
+		return 0;
+	}
+	ep = malloc(eplen);
+	if (!ep) {
+		EC_KEY_set_enc_flags(ec_key, old_flags);
+		ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	p = ep;
+	if (!i2d_ECPrivateKey(ec_key, &p)) {
+		EC_KEY_set_enc_flags(ec_key, old_flags);
+		free(ep);
+		ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
+		return 0;
+	}
+	/* restore old encoding flags */
+	EC_KEY_set_enc_flags(ec_key, old_flags);
+
+	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
+		ptype, pval, ep, eplen))
+		return 0;
+
+	return 1;
+}
+
+static int 
+int_ec_size(const EVP_PKEY * pkey)
+{
+	return ECDSA_size(pkey->pkey.ec);
+}
+
+static int 
+ec_bits(const EVP_PKEY * pkey)
+{
+	BIGNUM *order = BN_new();
+	const EC_GROUP *group;
+	int ret;
+
+	if (!order) {
+		ERR_clear_error();
+		return 0;
+	}
+	group = EC_KEY_get0_group(pkey->pkey.ec);
+	if (!EC_GROUP_get_order(group, order, NULL)) {
+		BN_free(order);
+		ERR_clear_error();
+		return 0;
+	}
+	ret = BN_num_bits(order);
+	BN_free(order);
+	return ret;
+}
+
+static int 
+ec_missing_parameters(const EVP_PKEY * pkey)
+{
+	if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
+		return 1;
+	return 0;
+}
+
+static int 
+ec_copy_parameters(EVP_PKEY * to, const EVP_PKEY * from)
+{
+	return EC_KEY_set_group(to->pkey.ec, EC_KEY_get0_group(from->pkey.ec));
+}
+
+static int 
+ec_cmp_parameters(const EVP_PKEY * a, const EVP_PKEY * b)
+{
+	const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), *group_b = EC_KEY_get0_group(b->pkey.ec);
+	if (EC_GROUP_cmp(group_a, group_b, NULL))
+		return 0;
+	else
+		return 1;
+}
+
+static void 
+int_ec_free(EVP_PKEY * pkey)
+{
+	EC_KEY_free(pkey->pkey.ec);
+}
+
+static int 
+do_EC_KEY_print(BIO * bp, const EC_KEY * x, int off, int ktype)
+{
+	unsigned char *buffer = NULL;
+	const char *ecstr;
+	size_t buf_len = 0, i;
+	int ret = 0, reason = ERR_R_BIO_LIB;
+	BIGNUM *pub_key = NULL, *order = NULL;
+	BN_CTX *ctx = NULL;
+	const EC_GROUP *group;
+	const EC_POINT *public_key;
+	const BIGNUM *priv_key;
+
+	if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
+		reason = ERR_R_PASSED_NULL_PARAMETER;
+		goto err;
+	}
+	ctx = BN_CTX_new();
+	if (ctx == NULL) {
+		reason = ERR_R_MALLOC_FAILURE;
+		goto err;
+	}
+	if (ktype > 0) {
+		public_key = EC_KEY_get0_public_key(x);
+		if ((pub_key = EC_POINT_point2bn(group, public_key,
+			    EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) {
+			reason = ERR_R_EC_LIB;
+			goto err;
+		}
+		if (pub_key)
+			buf_len = (size_t) BN_num_bytes(pub_key);
+	}
+	if (ktype == 2) {
+		priv_key = EC_KEY_get0_private_key(x);
+		if (priv_key && (i = (size_t) BN_num_bytes(priv_key)) > buf_len)
+			buf_len = i;
+	} else
+		priv_key = NULL;
+
+	if (ktype > 0) {
+		buf_len += 10;
+		if ((buffer = malloc(buf_len)) == NULL) {
+			reason = ERR_R_MALLOC_FAILURE;
+			goto err;
+		}
+	}
+	if (ktype == 2)
+		ecstr = "Private-Key";
+	else if (ktype == 1)
+		ecstr = "Public-Key";
+	else
+		ecstr = "ECDSA-Parameters";
+
+	if (!BIO_indent(bp, off, 128))
+		goto err;
+	if ((order = BN_new()) == NULL)
+		goto err;
+	if (!EC_GROUP_get_order(group, order, NULL))
+		goto err;
+	if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
+		BN_num_bits(order)) <= 0)
+		goto err;
+
+	if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key,
+		buffer, off))
+		goto err;
+	if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key,
+		buffer, off))
+		goto err;
+	if (!ECPKParameters_print(bp, group, off))
+		goto err;
+	ret = 1;
+err:
+	if (!ret)
+		ECerr(EC_F_DO_EC_KEY_PRINT, reason);
+	BN_free(pub_key);
+	BN_free(order);
+	BN_CTX_free(ctx);
+	free(buffer);
+	return (ret);
+}
+
+static int 
+eckey_param_decode(EVP_PKEY * pkey,
+    const unsigned char **pder, int derlen)
+{
+	EC_KEY *eckey;
+	if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) {
+		ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
+		return 0;
+	}
+	EVP_PKEY_assign_EC_KEY(pkey, eckey);
+	return 1;
+}
+
+static int 
+eckey_param_encode(const EVP_PKEY * pkey, unsigned char **pder)
+{
+	return i2d_ECParameters(pkey->pkey.ec, pder);
+}
+
+static int 
+eckey_param_print(BIO * bp, const EVP_PKEY * pkey, int indent,
+    ASN1_PCTX * ctx)
+{
+	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
+}
+
+static int 
+eckey_pub_print(BIO * bp, const EVP_PKEY * pkey, int indent,
+    ASN1_PCTX * ctx)
+{
+	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
+}
+
+
+static int 
+eckey_priv_print(BIO * bp, const EVP_PKEY * pkey, int indent,
+    ASN1_PCTX * ctx)
+{
+	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
+}
+
+static int 
+old_ec_priv_decode(EVP_PKEY * pkey,
+    const unsigned char **pder, int derlen)
+{
+	EC_KEY *ec;
+	if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) {
+		ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR);
+		return 0;
+	}
+	EVP_PKEY_assign_EC_KEY(pkey, ec);
+	return 1;
+}
+
+static int 
+old_ec_priv_encode(const EVP_PKEY * pkey, unsigned char **pder)
+{
+	return i2d_ECPrivateKey(pkey->pkey.ec, pder);
+}
+
+static int 
+ec_pkey_ctrl(EVP_PKEY * pkey, int op, long arg1, void *arg2)
+{
+	switch (op) {
+	case ASN1_PKEY_CTRL_PKCS7_SIGN:
+		if (arg1 == 0) {
+			int snid, hnid;
+			X509_ALGOR *alg1, *alg2;
+			PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
+			if (alg1 == NULL || alg1->algorithm == NULL)
+				return -1;
+			hnid = OBJ_obj2nid(alg1->algorithm);
+			if (hnid == NID_undef)
+				return -1;
+			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
+				return -1;
+			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
+		}
+		return 1;
+#ifndef OPENSSL_NO_CMS
+	case ASN1_PKEY_CTRL_CMS_SIGN:
+		if (arg1 == 0) {
+			int snid, hnid;
+			X509_ALGOR *alg1, *alg2;
+			CMS_SignerInfo_get0_algs(arg2, NULL, NULL,
+			    &alg1, &alg2);
+			if (alg1 == NULL || alg1->algorithm == NULL)
+				return -1;
+			hnid = OBJ_obj2nid(alg1->algorithm);
+			if (hnid == NID_undef)
+				return -1;
+			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
+				return -1;
+			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
+		}
+		return 1;
+#endif
+
+	case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+		*(int *) arg2 = NID_sha1;
+		return 2;
+
+	default:
+		return -2;
+
+	}
+
+}
+
+const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
+	.pkey_id = EVP_PKEY_EC,
+	.pkey_base_id = EVP_PKEY_EC,
+
+	.pem_str = "EC",
+	.info = "OpenSSL EC algorithm",
+
+	.pub_decode = eckey_pub_decode,
+	.pub_encode = eckey_pub_encode,
+	.pub_cmp = eckey_pub_cmp,
+	.pub_print = eckey_pub_print,
+
+	.priv_decode = eckey_priv_decode,
+	.priv_encode = eckey_priv_encode,
+	.priv_print = eckey_priv_print,
+
+	.pkey_size = int_ec_size,
+	.pkey_bits = ec_bits,
+
+	.param_decode = eckey_param_decode,
+	.param_encode = eckey_param_encode,
+	.param_missing = ec_missing_parameters,
+	.param_copy = ec_copy_parameters,
+	.param_cmp = ec_cmp_parameters,
+	.param_print = eckey_param_print,
+
+	.pkey_free = int_ec_free,
+	.pkey_ctrl = ec_pkey_ctrl,
+	.old_priv_decode = old_ec_priv_decode,
+	.old_priv_encode = old_ec_priv_encode
+};
diff --git a/crypto/libressl/crypto/ec/ec_asn1.c b/crypto/libressl/crypto/ec/ec_asn1.c
new file mode 100644
index 0000000000..43cb3e9a32
--- /dev/null
+++ b/crypto/libressl/crypto/ec/ec_asn1.c
@@ -0,0 +1,1618 @@
+/* $OpenBSD: ec_asn1.c,v 1.21 2015/10/16 15:15:39 jsing Exp $ */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2003 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include "ec_lcl.h"
+#include 
+#include 
+#include 
+
+int 
+EC_GROUP_get_basis_type(const EC_GROUP * group)
+{
+	int i = 0;
+
+	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
+	    NID_X9_62_characteristic_two_field)
+		/* everything else is currently not supported */
+		return 0;
+
+	while (group->poly[i] != 0)
+		i++;
+
+	if (i == 4)
+		return NID_X9_62_ppBasis;
+	else if (i == 2)
+		return NID_X9_62_tpBasis;
+	else
+		/* everything else is currently not supported */
+		return 0;
+}
+#ifndef OPENSSL_NO_EC2M
+int 
+EC_GROUP_get_trinomial_basis(const EC_GROUP * group, unsigned int *k)
+{
+	if (group == NULL)
+		return 0;
+
+	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
+	    NID_X9_62_characteristic_two_field
+	    || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] == 0))) {
+		ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if (k)
+		*k = group->poly[1];
+
+	return 1;
+}
+int 
+EC_GROUP_get_pentanomial_basis(const EC_GROUP * group, unsigned int *k1,
+    unsigned int *k2, unsigned int *k3)
+{
+	if (group == NULL)
+		return 0;
+
+	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
+	    NID_X9_62_characteristic_two_field
+	    || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] != 0) && (group->poly[3] != 0) && (group->poly[4] == 0))) {
+		ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if (k1)
+		*k1 = group->poly[3];
+	if (k2)
+		*k2 = group->poly[2];
+	if (k3)
+		*k3 = group->poly[1];
+
+	return 1;
+}
+#endif
+
+
+/* some structures needed for the asn1 encoding */
+typedef struct x9_62_pentanomial_st {
+	long k1;
+	long k2;
+	long k3;
+} X9_62_PENTANOMIAL;
+
+typedef struct x9_62_characteristic_two_st {
+	long m;
+	ASN1_OBJECT *type;
+	union {
+		char *ptr;
+		/* NID_X9_62_onBasis */
+		ASN1_NULL *onBasis;
+		/* NID_X9_62_tpBasis */
+		ASN1_INTEGER *tpBasis;
+		/* NID_X9_62_ppBasis */
+		X9_62_PENTANOMIAL *ppBasis;
+		/* anything else */
+		ASN1_TYPE *other;
+	} p;
+} X9_62_CHARACTERISTIC_TWO;
+
+typedef struct x9_62_fieldid_st {
+	ASN1_OBJECT *fieldType;
+	union {
+		char *ptr;
+		/* NID_X9_62_prime_field */
+		ASN1_INTEGER *prime;
+		/* NID_X9_62_characteristic_two_field */
+		X9_62_CHARACTERISTIC_TWO *char_two;
+		/* anything else */
+		ASN1_TYPE *other;
+	} p;
+} X9_62_FIELDID;
+
+typedef struct x9_62_curve_st {
+	ASN1_OCTET_STRING *a;
+	ASN1_OCTET_STRING *b;
+	ASN1_BIT_STRING *seed;
+} X9_62_CURVE;
+
+typedef struct ec_parameters_st {
+	long version;
+	X9_62_FIELDID *fieldID;
+	X9_62_CURVE *curve;
+	ASN1_OCTET_STRING *base;
+	ASN1_INTEGER *order;
+	ASN1_INTEGER *cofactor;
+} ECPARAMETERS;
+
+struct ecpk_parameters_st {
+	int type;
+	union {
+		ASN1_OBJECT *named_curve;
+		ECPARAMETERS *parameters;
+		ASN1_NULL *implicitlyCA;
+	} value;
+} /* ECPKPARAMETERS */ ;
+
+/* SEC1 ECPrivateKey */
+typedef struct ec_privatekey_st {
+	long version;
+	ASN1_OCTET_STRING *privateKey;
+	ECPKPARAMETERS *parameters;
+	ASN1_BIT_STRING *publicKey;
+} EC_PRIVATEKEY;
+
+/* the OpenSSL ASN.1 definitions */
+static const ASN1_TEMPLATE X9_62_PENTANOMIAL_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(X9_62_PENTANOMIAL, k1),
+		.field_name = "k1",
+		.item = &LONG_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(X9_62_PENTANOMIAL, k2),
+		.field_name = "k2",
+		.item = &LONG_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(X9_62_PENTANOMIAL, k3),
+		.field_name = "k3",
+		.item = &LONG_it,
+	},
+};
+
+const ASN1_ITEM X9_62_PENTANOMIAL_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = X9_62_PENTANOMIAL_seq_tt,
+	.tcount = sizeof(X9_62_PENTANOMIAL_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(X9_62_PENTANOMIAL),
+	.sname = "X9_62_PENTANOMIAL",
+};
+
+X9_62_PENTANOMIAL *X9_62_PENTANOMIAL_new(void);
+void X9_62_PENTANOMIAL_free(X9_62_PENTANOMIAL *a);
+
+X9_62_PENTANOMIAL *
+X9_62_PENTANOMIAL_new(void)
+{
+	return (X9_62_PENTANOMIAL*)ASN1_item_new(&X9_62_PENTANOMIAL_it);
+}
+
+void
+X9_62_PENTANOMIAL_free(X9_62_PENTANOMIAL *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &X9_62_PENTANOMIAL_it);
+}
+
+static const ASN1_TEMPLATE char_two_def_tt = {
+	.flags = 0,
+	.tag = 0,
+	.offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.other),
+	.field_name = "p.other",
+	.item = &ASN1_ANY_it,
+};
+
+static const ASN1_ADB_TABLE X9_62_CHARACTERISTIC_TWO_adbtbl[] = {
+	{
+		.value = NID_X9_62_onBasis,
+		.tt = {
+			.flags = 0,
+			.tag = 0,
+			.offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.onBasis),
+			.field_name = "p.onBasis",
+			.item = &ASN1_NULL_it,
+		},
+	
+	},
+	{
+		.value = NID_X9_62_tpBasis,
+		.tt = {
+			.flags = 0,
+			.tag = 0,
+			.offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.tpBasis),
+			.field_name = "p.tpBasis",
+			.item = &ASN1_INTEGER_it,
+		},
+	
+	},
+	{
+		.value = NID_X9_62_ppBasis,
+		.tt = {
+			.flags = 0,
+			.tag = 0,
+			.offset = offsetof(X9_62_CHARACTERISTIC_TWO, p.ppBasis),
+			.field_name = "p.ppBasis",
+			.item = &X9_62_PENTANOMIAL_it,
+		},
+	
+	},
+};
+
+static const ASN1_ADB X9_62_CHARACTERISTIC_TWO_adb = {
+	.flags = 0,
+	.offset = offsetof(X9_62_CHARACTERISTIC_TWO, type),
+	.app_items = 0,
+	.tbl = X9_62_CHARACTERISTIC_TWO_adbtbl,
+	.tblcount = sizeof(X9_62_CHARACTERISTIC_TWO_adbtbl) / sizeof(ASN1_ADB_TABLE),
+	.default_tt = &char_two_def_tt,
+	.null_tt = NULL,
+};
+
+static const ASN1_TEMPLATE X9_62_CHARACTERISTIC_TWO_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(X9_62_CHARACTERISTIC_TWO, m),
+		.field_name = "m",
+		.item = &LONG_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(X9_62_CHARACTERISTIC_TWO, type),
+		.field_name = "type",
+		.item = &ASN1_OBJECT_it,
+	},
+	{
+		.flags = ASN1_TFLG_ADB_OID,
+		.tag = -1,
+		.offset = 0,
+		.field_name = "X9_62_CHARACTERISTIC_TWO",
+		.item = (const ASN1_ITEM *)&X9_62_CHARACTERISTIC_TWO_adb,
+	},
+};
+
+const ASN1_ITEM X9_62_CHARACTERISTIC_TWO_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = X9_62_CHARACTERISTIC_TWO_seq_tt,
+	.tcount = sizeof(X9_62_CHARACTERISTIC_TWO_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(X9_62_CHARACTERISTIC_TWO),
+	.sname = "X9_62_CHARACTERISTIC_TWO",
+};
+X9_62_CHARACTERISTIC_TWO *X9_62_CHARACTERISTIC_TWO_new(void);
+void X9_62_CHARACTERISTIC_TWO_free(X9_62_CHARACTERISTIC_TWO *a);
+
+X9_62_CHARACTERISTIC_TWO *
+X9_62_CHARACTERISTIC_TWO_new(void)
+{
+	return (X9_62_CHARACTERISTIC_TWO*)ASN1_item_new(&X9_62_CHARACTERISTIC_TWO_it);
+}
+
+void
+X9_62_CHARACTERISTIC_TWO_free(X9_62_CHARACTERISTIC_TWO *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &X9_62_CHARACTERISTIC_TWO_it);
+}
+static const ASN1_TEMPLATE fieldID_def_tt = {
+	.flags = 0,
+	.tag = 0,
+	.offset = offsetof(X9_62_FIELDID, p.other),
+	.field_name = "p.other",
+	.item = &ASN1_ANY_it,
+};
+
+static const ASN1_ADB_TABLE X9_62_FIELDID_adbtbl[] = {
+	{
+		.value = NID_X9_62_prime_field,
+		.tt = {
+			.flags = 0,
+			.tag = 0,
+			.offset = offsetof(X9_62_FIELDID, p.prime),
+			.field_name = "p.prime",
+			.item = &ASN1_INTEGER_it,
+		},
+	
+	},
+	{
+		.value = NID_X9_62_characteristic_two_field,
+		.tt = {
+			.flags = 0,
+			.tag = 0,
+			.offset = offsetof(X9_62_FIELDID, p.char_two),
+			.field_name = "p.char_two",
+			.item = &X9_62_CHARACTERISTIC_TWO_it,
+		},
+	
+	},
+};
+
+static const ASN1_ADB X9_62_FIELDID_adb = {
+	.flags = 0,
+	.offset = offsetof(X9_62_FIELDID, fieldType),
+	.app_items = 0,
+	.tbl = X9_62_FIELDID_adbtbl,
+	.tblcount = sizeof(X9_62_FIELDID_adbtbl) / sizeof(ASN1_ADB_TABLE),
+	.default_tt = &fieldID_def_tt,
+	.null_tt = NULL,
+};
+
+static const ASN1_TEMPLATE X9_62_FIELDID_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(X9_62_FIELDID, fieldType),
+		.field_name = "fieldType",
+		.item = &ASN1_OBJECT_it,
+	},
+	{
+		.flags = ASN1_TFLG_ADB_OID,
+		.tag = -1,
+		.offset = 0,
+		.field_name = "X9_62_FIELDID",
+		.item = (const ASN1_ITEM *)&X9_62_FIELDID_adb,
+	},
+};
+
+const ASN1_ITEM X9_62_FIELDID_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = X9_62_FIELDID_seq_tt,
+	.tcount = sizeof(X9_62_FIELDID_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(X9_62_FIELDID),
+	.sname = "X9_62_FIELDID",
+};
+
+static const ASN1_TEMPLATE X9_62_CURVE_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(X9_62_CURVE, a),
+		.field_name = "a",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(X9_62_CURVE, b),
+		.field_name = "b",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(X9_62_CURVE, seed),
+		.field_name = "seed",
+		.item = &ASN1_BIT_STRING_it,
+	},
+};
+
+const ASN1_ITEM X9_62_CURVE_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = X9_62_CURVE_seq_tt,
+	.tcount = sizeof(X9_62_CURVE_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(X9_62_CURVE),
+	.sname = "X9_62_CURVE",
+};
+
+static const ASN1_TEMPLATE ECPARAMETERS_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(ECPARAMETERS, version),
+		.field_name = "version",
+		.item = &LONG_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(ECPARAMETERS, fieldID),
+		.field_name = "fieldID",
+		.item = &X9_62_FIELDID_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(ECPARAMETERS, curve),
+		.field_name = "curve",
+		.item = &X9_62_CURVE_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(ECPARAMETERS, base),
+		.field_name = "base",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(ECPARAMETERS, order),
+		.field_name = "order",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(ECPARAMETERS, cofactor),
+		.field_name = "cofactor",
+		.item = &ASN1_INTEGER_it,
+	},
+};
+
+const ASN1_ITEM ECPARAMETERS_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = ECPARAMETERS_seq_tt,
+	.tcount = sizeof(ECPARAMETERS_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(ECPARAMETERS),
+	.sname = "ECPARAMETERS",
+};
+ECPARAMETERS *ECPARAMETERS_new(void);
+void ECPARAMETERS_free(ECPARAMETERS *a);
+
+ECPARAMETERS *
+ECPARAMETERS_new(void)
+{
+	return (ECPARAMETERS*)ASN1_item_new(&ECPARAMETERS_it);
+}
+
+void
+ECPARAMETERS_free(ECPARAMETERS *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ECPARAMETERS_it);
+}
+
+static const ASN1_TEMPLATE ECPKPARAMETERS_ch_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(ECPKPARAMETERS, value.named_curve),
+		.field_name = "value.named_curve",
+		.item = &ASN1_OBJECT_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(ECPKPARAMETERS, value.parameters),
+		.field_name = "value.parameters",
+		.item = &ECPARAMETERS_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(ECPKPARAMETERS, value.implicitlyCA),
+		.field_name = "value.implicitlyCA",
+		.item = &ASN1_NULL_it,
+	},
+};
+
+const ASN1_ITEM ECPKPARAMETERS_it = {
+	.itype = ASN1_ITYPE_CHOICE,
+	.utype = offsetof(ECPKPARAMETERS, type),
+	.templates = ECPKPARAMETERS_ch_tt,
+	.tcount = sizeof(ECPKPARAMETERS_ch_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(ECPKPARAMETERS),
+	.sname = "ECPKPARAMETERS",
+};
+
+ECPKPARAMETERS *ECPKPARAMETERS_new(void);
+void ECPKPARAMETERS_free(ECPKPARAMETERS *a);
+ECPKPARAMETERS *d2i_ECPKPARAMETERS(ECPKPARAMETERS **a, const unsigned char **in, long len);
+int i2d_ECPKPARAMETERS(const ECPKPARAMETERS *a, unsigned char **out);
+
+ECPKPARAMETERS *
+d2i_ECPKPARAMETERS(ECPKPARAMETERS **a, const unsigned char **in, long len)
+{
+	return (ECPKPARAMETERS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ECPKPARAMETERS_it);
+}
+
+int
+i2d_ECPKPARAMETERS(const ECPKPARAMETERS *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ECPKPARAMETERS_it);
+}
+
+ECPKPARAMETERS *
+ECPKPARAMETERS_new(void)
+{
+	return (ECPKPARAMETERS *)ASN1_item_new(&ECPKPARAMETERS_it);
+}
+
+void
+ECPKPARAMETERS_free(ECPKPARAMETERS *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ECPKPARAMETERS_it);
+}
+
+static const ASN1_TEMPLATE EC_PRIVATEKEY_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(EC_PRIVATEKEY, version),
+		.field_name = "version",
+		.item = &LONG_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(EC_PRIVATEKEY, privateKey),
+		.field_name = "privateKey",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(EC_PRIVATEKEY, parameters),
+		.field_name = "parameters",
+		.item = &ECPKPARAMETERS_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 1,
+		.offset = offsetof(EC_PRIVATEKEY, publicKey),
+		.field_name = "publicKey",
+		.item = &ASN1_BIT_STRING_it,
+	},
+};
+
+const ASN1_ITEM EC_PRIVATEKEY_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = EC_PRIVATEKEY_seq_tt,
+	.tcount = sizeof(EC_PRIVATEKEY_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(EC_PRIVATEKEY),
+	.sname = "EC_PRIVATEKEY",
+};
+
+EC_PRIVATEKEY *EC_PRIVATEKEY_new(void);
+void EC_PRIVATEKEY_free(EC_PRIVATEKEY *a);
+EC_PRIVATEKEY *d2i_EC_PRIVATEKEY(EC_PRIVATEKEY **a, const unsigned char **in, long len);
+int i2d_EC_PRIVATEKEY(const EC_PRIVATEKEY *a, unsigned char **out);
+
+EC_PRIVATEKEY *
+d2i_EC_PRIVATEKEY(EC_PRIVATEKEY **a, const unsigned char **in, long len)
+{
+	return (EC_PRIVATEKEY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &EC_PRIVATEKEY_it);
+}
+
+int
+i2d_EC_PRIVATEKEY(const EC_PRIVATEKEY *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &EC_PRIVATEKEY_it);
+}
+
+EC_PRIVATEKEY *
+EC_PRIVATEKEY_new(void)
+{
+	return (EC_PRIVATEKEY *)ASN1_item_new(&EC_PRIVATEKEY_it);
+}
+
+void
+EC_PRIVATEKEY_free(EC_PRIVATEKEY *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &EC_PRIVATEKEY_it);
+}
+/* some declarations of internal function */
+
+/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */
+static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *);
+/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */
+static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *);
+/* ec_asn1_parameters2group() creates a EC_GROUP object from a
+ * ECPARAMETERS object */
+static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *);
+/* ec_asn1_group2parameters() creates a ECPARAMETERS object from a
+ * EC_GROUP object */
+static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *, ECPARAMETERS *);
+/* ec_asn1_pkparameters2group() creates a EC_GROUP object from a
+ * ECPKPARAMETERS object */
+static EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *);
+/* ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a
+ * EC_GROUP object */
+static ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *,
+    ECPKPARAMETERS *);
+
+
+/* the function definitions */
+
+static int
+ec_asn1_group2fieldid(const EC_GROUP * group, X9_62_FIELDID * field)
+{
+	int ok = 0, nid;
+	BIGNUM *tmp = NULL;
+
+	if (group == NULL || field == NULL)
+		return 0;
+
+	/* clear the old values (if necessary) */
+	if (field->fieldType != NULL)
+		ASN1_OBJECT_free(field->fieldType);
+	if (field->p.other != NULL)
+		ASN1_TYPE_free(field->p.other);
+
+	nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
+	/* set OID for the field */
+	if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) {
+		ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
+		goto err;
+	}
+	if (nid == NID_X9_62_prime_field) {
+		if ((tmp = BN_new()) == NULL) {
+			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		/* the parameters are specified by the prime number p */
+		if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL)) {
+			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
+			goto err;
+		}
+		/* set the prime number */
+		field->p.prime = BN_to_ASN1_INTEGER(tmp, NULL);
+		if (field->p.prime == NULL) {
+			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
+			goto err;
+		}
+	} else			/* nid == NID_X9_62_characteristic_two_field */
+#ifdef OPENSSL_NO_EC2M
+	{
+		ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED);
+		goto err;
+	}
+#else
+	{
+		int field_type;
+		X9_62_CHARACTERISTIC_TWO *char_two;
+
+		field->p.char_two = X9_62_CHARACTERISTIC_TWO_new();
+		char_two = field->p.char_two;
+
+		if (char_two == NULL) {
+			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		char_two->m = (long) EC_GROUP_get_degree(group);
+
+		field_type = EC_GROUP_get_basis_type(group);
+
+		if (field_type == 0) {
+			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
+			goto err;
+		}
+		/* set base type OID */
+		if ((char_two->type = OBJ_nid2obj(field_type)) == NULL) {
+			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
+			goto err;
+		}
+		if (field_type == NID_X9_62_tpBasis) {
+			unsigned int k;
+
+			if (!EC_GROUP_get_trinomial_basis(group, &k))
+				goto err;
+
+			char_two->p.tpBasis = ASN1_INTEGER_new();
+			if (!char_two->p.tpBasis) {
+				ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+			if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long) k)) {
+				ECerr(EC_F_EC_ASN1_GROUP2FIELDID,
+				    ERR_R_ASN1_LIB);
+				goto err;
+			}
+		} else if (field_type == NID_X9_62_ppBasis) {
+			unsigned int k1, k2, k3;
+
+			if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3))
+				goto err;
+
+			char_two->p.ppBasis = X9_62_PENTANOMIAL_new();
+			if (!char_two->p.ppBasis) {
+				ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+			/* set k? values */
+			char_two->p.ppBasis->k1 = (long) k1;
+			char_two->p.ppBasis->k2 = (long) k2;
+			char_two->p.ppBasis->k3 = (long) k3;
+		} else {	/* field_type == NID_X9_62_onBasis */
+			/* for ONB the parameters are (asn1) NULL */
+			char_two->p.onBasis = ASN1_NULL_new();
+			if (!char_two->p.onBasis) {
+				ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+		}
+	}
+#endif
+
+	ok = 1;
+
+err:
+	BN_free(tmp);
+	return (ok);
+}
+
+static int 
+ec_asn1_group2curve(const EC_GROUP * group, X9_62_CURVE * curve)
+{
+	int ok = 0, nid;
+	BIGNUM *tmp_1 = NULL, *tmp_2 = NULL;
+	unsigned char *buffer_1 = NULL, *buffer_2 = NULL, *a_buf = NULL,
+	*b_buf = NULL;
+	size_t len_1, len_2;
+	unsigned char char_zero = 0;
+
+	if (!group || !curve || !curve->a || !curve->b)
+		return 0;
+
+	if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) {
+		ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
+
+	/* get a and b */
+	if (nid == NID_X9_62_prime_field) {
+		if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL)) {
+			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
+			goto err;
+		}
+	}
+#ifndef OPENSSL_NO_EC2M
+	else {			/* nid == NID_X9_62_characteristic_two_field */
+		if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL)) {
+			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
+			goto err;
+		}
+	}
+#endif
+	len_1 = (size_t) BN_num_bytes(tmp_1);
+	len_2 = (size_t) BN_num_bytes(tmp_2);
+
+	if (len_1 == 0) {
+		/* len_1 == 0 => a == 0 */
+		a_buf = &char_zero;
+		len_1 = 1;
+	} else {
+		if ((buffer_1 = malloc(len_1)) == NULL) {
+			ECerr(EC_F_EC_ASN1_GROUP2CURVE,
+			    ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		if ((len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0) {
+			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
+			goto err;
+		}
+		a_buf = buffer_1;
+	}
+
+	if (len_2 == 0) {
+		/* len_2 == 0 => b == 0 */
+		b_buf = &char_zero;
+		len_2 = 1;
+	} else {
+		if ((buffer_2 = malloc(len_2)) == NULL) {
+			ECerr(EC_F_EC_ASN1_GROUP2CURVE,
+			    ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		if ((len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0) {
+			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
+			goto err;
+		}
+		b_buf = buffer_2;
+	}
+
+	/* set a and b */
+	if (!ASN1_STRING_set(curve->a, a_buf, len_1) ||
+	    !ASN1_STRING_set(curve->b, b_buf, len_2)) {
+		ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
+		goto err;
+	}
+	/* set the seed (optional) */
+	if (group->seed) {
+		if (!curve->seed)
+			if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) {
+				ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+		curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+		curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+		if (!ASN1_BIT_STRING_set(curve->seed, group->seed,
+			(int) group->seed_len)) {
+			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
+			goto err;
+		}
+	} else {
+		if (curve->seed) {
+			ASN1_BIT_STRING_free(curve->seed);
+			curve->seed = NULL;
+		}
+	}
+
+	ok = 1;
+
+err:
+	free(buffer_1);
+	free(buffer_2);
+	BN_free(tmp_1);
+	BN_free(tmp_2);
+	return (ok);
+}
+
+static ECPARAMETERS *
+ec_asn1_group2parameters(const EC_GROUP * group, ECPARAMETERS * param)
+{
+	int ok = 0;
+	size_t len = 0;
+	ECPARAMETERS *ret = NULL;
+	BIGNUM *tmp = NULL;
+	unsigned char *buffer = NULL;
+	const EC_POINT *point = NULL;
+	point_conversion_form_t form;
+
+	if ((tmp = BN_new()) == NULL) {
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	if (param == NULL) {
+		if ((ret = ECPARAMETERS_new()) == NULL) {
+			ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS,
+			    ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+	} else
+		ret = param;
+
+	/* set the version (always one) */
+	ret->version = (long) 0x1;
+
+	/* set the fieldID */
+	if (!ec_asn1_group2fieldid(group, ret->fieldID)) {
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
+		goto err;
+	}
+	/* set the curve */
+	if (!ec_asn1_group2curve(group, ret->curve)) {
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
+		goto err;
+	}
+	/* set the base point */
+	if ((point = EC_GROUP_get0_generator(group)) == NULL) {
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR);
+		goto err;
+	}
+	form = EC_GROUP_get_point_conversion_form(group);
+
+	len = EC_POINT_point2oct(group, point, form, NULL, len, NULL);
+	if (len == 0) {
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
+		goto err;
+	}
+	if ((buffer = malloc(len)) == NULL) {
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL)) {
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
+		goto err;
+	}
+	if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) {
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	if (!ASN1_OCTET_STRING_set(ret->base, buffer, len)) {
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
+		goto err;
+	}
+	/* set the order */
+	if (!EC_GROUP_get_order(group, tmp, NULL)) {
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
+		goto err;
+	}
+	ret->order = BN_to_ASN1_INTEGER(tmp, ret->order);
+	if (ret->order == NULL) {
+		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
+		goto err;
+	}
+	/* set the cofactor (optional) */
+	if (EC_GROUP_get_cofactor(group, tmp, NULL)) {
+		ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor);
+		if (ret->cofactor == NULL) {
+			ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
+			goto err;
+		}
+	}
+	ok = 1;
+
+err:	if (!ok) {
+		if (ret && !param)
+			ECPARAMETERS_free(ret);
+		ret = NULL;
+	}
+	BN_free(tmp);
+	free(buffer);
+	return (ret);
+}
+
+ECPKPARAMETERS *
+ec_asn1_group2pkparameters(const EC_GROUP * group, ECPKPARAMETERS * params)
+{
+	int ok = 1, tmp;
+	ECPKPARAMETERS *ret = params;
+
+	if (ret == NULL) {
+		if ((ret = ECPKPARAMETERS_new()) == NULL) {
+			ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS,
+			    ERR_R_MALLOC_FAILURE);
+			return NULL;
+		}
+	} else {
+		if (ret->type == 0 && ret->value.named_curve)
+			ASN1_OBJECT_free(ret->value.named_curve);
+		else if (ret->type == 1 && ret->value.parameters)
+			ECPARAMETERS_free(ret->value.parameters);
+	}
+
+	if (EC_GROUP_get_asn1_flag(group)) {
+		/*
+		 * use the asn1 OID to describe the elliptic curve
+		 * parameters
+		 */
+		tmp = EC_GROUP_get_curve_name(group);
+		if (tmp) {
+			ret->type = 0;
+			if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
+				ok = 0;
+		} else
+			/* we don't kmow the nid => ERROR */
+			ok = 0;
+	} else {
+		/* use the ECPARAMETERS structure */
+		ret->type = 1;
+		if ((ret->value.parameters = ec_asn1_group2parameters(
+			    group, NULL)) == NULL)
+			ok = 0;
+	}
+
+	if (!ok) {
+		ECPKPARAMETERS_free(ret);
+		return NULL;
+	}
+	return ret;
+}
+
+static EC_GROUP *
+ec_asn1_parameters2group(const ECPARAMETERS * params)
+{
+	int ok = 0, tmp;
+	EC_GROUP *ret = NULL;
+	BIGNUM *p = NULL, *a = NULL, *b = NULL;
+	EC_POINT *point = NULL;
+	long field_bits;
+
+	if (!params->fieldID || !params->fieldID->fieldType ||
+	    !params->fieldID->p.ptr) {
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+		goto err;
+	}
+	/* now extract the curve parameters a and b */
+	if (!params->curve || !params->curve->a ||
+	    !params->curve->a->data || !params->curve->b ||
+	    !params->curve->b->data) {
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+		goto err;
+	}
+	a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL);
+	if (a == NULL) {
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
+		goto err;
+	}
+	b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL);
+	if (b == NULL) {
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
+		goto err;
+	}
+	/* get the field parameters */
+	tmp = OBJ_obj2nid(params->fieldID->fieldType);
+	if (tmp == NID_X9_62_characteristic_two_field)
+#ifdef OPENSSL_NO_EC2M
+	{
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_GF2M_NOT_SUPPORTED);
+		goto err;
+	}
+#else
+	{
+		X9_62_CHARACTERISTIC_TWO *char_two;
+
+		char_two = params->fieldID->p.char_two;
+
+		field_bits = char_two->m;
+		if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
+			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
+			goto err;
+		}
+		if ((p = BN_new()) == NULL) {
+			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		/* get the base type */
+		tmp = OBJ_obj2nid(char_two->type);
+
+		if (tmp == NID_X9_62_tpBasis) {
+			long tmp_long;
+
+			if (!char_two->p.tpBasis) {
+				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+				goto err;
+			}
+			tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis);
+
+			if (!(char_two->m > tmp_long && tmp_long > 0)) {
+				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_TRINOMIAL_BASIS);
+				goto err;
+			}
+			/* create the polynomial */
+			if (!BN_set_bit(p, (int) char_two->m))
+				goto err;
+			if (!BN_set_bit(p, (int) tmp_long))
+				goto err;
+			if (!BN_set_bit(p, 0))
+				goto err;
+		} else if (tmp == NID_X9_62_ppBasis) {
+			X9_62_PENTANOMIAL *penta;
+
+			penta = char_two->p.ppBasis;
+			if (!penta) {
+				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+				goto err;
+			}
+			if (!(char_two->m > penta->k3 && penta->k3 > penta->k2 && penta->k2 > penta->k1 && penta->k1 > 0)) {
+				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_PENTANOMIAL_BASIS);
+				goto err;
+			}
+			/* create the polynomial */
+			if (!BN_set_bit(p, (int) char_two->m))
+				goto err;
+			if (!BN_set_bit(p, (int) penta->k1))
+				goto err;
+			if (!BN_set_bit(p, (int) penta->k2))
+				goto err;
+			if (!BN_set_bit(p, (int) penta->k3))
+				goto err;
+			if (!BN_set_bit(p, 0))
+				goto err;
+		} else if (tmp == NID_X9_62_onBasis) {
+			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED);
+			goto err;
+		} else {	/* error */
+			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+			goto err;
+		}
+
+		/* create the EC_GROUP structure */
+		ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
+	}
+#endif
+	else if (tmp == NID_X9_62_prime_field) {
+		/* we have a curve over a prime field */
+		/* extract the prime number */
+		if (!params->fieldID->p.prime) {
+			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+			goto err;
+		}
+		p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
+		if (p == NULL) {
+			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
+			goto err;
+		}
+		if (BN_is_negative(p) || BN_is_zero(p)) {
+			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
+			goto err;
+		}
+		field_bits = BN_num_bits(p);
+		if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
+			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
+			goto err;
+		}
+		/* create the EC_GROUP structure */
+		ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
+	} else {
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
+		goto err;
+	}
+
+	if (ret == NULL) {
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
+		goto err;
+	}
+	/* extract seed (optional) */
+	if (params->curve->seed != NULL) {
+		free(ret->seed);
+		if (!(ret->seed = malloc(params->curve->seed->length))) {
+			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP,
+			    ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		memcpy(ret->seed, params->curve->seed->data,
+		    params->curve->seed->length);
+		ret->seed_len = params->curve->seed->length;
+	}
+	if (!params->order || !params->base || !params->base->data) {
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+		goto err;
+	}
+	if ((point = EC_POINT_new(ret)) == NULL)
+		goto err;
+
+	/* set the point conversion form */
+	EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t)
+	    (params->base->data[0] & ~0x01));
+
+	/* extract the ec point */
+	if (!EC_POINT_oct2point(ret, point, params->base->data,
+		params->base->length, NULL)) {
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
+		goto err;
+	}
+	/* extract the order */
+	if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) {
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
+		goto err;
+	}
+	if (BN_is_negative(a) || BN_is_zero(a)) {
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
+		goto err;
+	}
+	if (BN_num_bits(a) > (int) field_bits + 1) {	/* Hasse bound */
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
+		goto err;
+	}
+	/* extract the cofactor (optional) */
+	if (params->cofactor == NULL) {
+		BN_free(b);
+		b = NULL;
+	} else if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) {
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
+		goto err;
+	}
+	/* set the generator, order and cofactor (if present) */
+	if (!EC_GROUP_set_generator(ret, point, a, b)) {
+		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
+		goto err;
+	}
+	ok = 1;
+
+err:	if (!ok) {
+		EC_GROUP_clear_free(ret);
+		ret = NULL;
+	}
+	BN_free(p);
+	BN_free(a);
+	BN_free(b);
+	EC_POINT_free(point);
+	return (ret);
+}
+
+EC_GROUP *
+ec_asn1_pkparameters2group(const ECPKPARAMETERS * params)
+{
+	EC_GROUP *ret = NULL;
+	int tmp = 0;
+
+	if (params == NULL) {
+		ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP,
+		    EC_R_MISSING_PARAMETERS);
+		return NULL;
+	}
+	if (params->type == 0) {/* the curve is given by an OID */
+		tmp = OBJ_obj2nid(params->value.named_curve);
+		if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) {
+			ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP,
+			    EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
+			return NULL;
+		}
+		EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
+	} else if (params->type == 1) {	/* the parameters are given by a
+					 * ECPARAMETERS structure */
+		ret = ec_asn1_parameters2group(params->value.parameters);
+		if (!ret) {
+			ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB);
+			return NULL;
+		}
+		EC_GROUP_set_asn1_flag(ret, 0x0);
+	} else if (params->type == 2) {	/* implicitlyCA */
+		return NULL;
+	} else {
+		ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR);
+		return NULL;
+	}
+
+	return ret;
+}
+
+/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */
+
+EC_GROUP *
+d2i_ECPKParameters(EC_GROUP ** a, const unsigned char **in, long len)
+{
+	EC_GROUP *group = NULL;
+	ECPKPARAMETERS *params = NULL;
+
+	if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL) {
+		ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
+		goto err;
+	}
+	if ((group = ec_asn1_pkparameters2group(params)) == NULL) {
+		ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
+		goto err;
+	}
+
+	if (a != NULL) {
+		EC_GROUP_clear_free(*a);
+		*a = group;
+	}
+
+err:
+	ECPKPARAMETERS_free(params);
+	return (group);
+}
+
+int 
+i2d_ECPKParameters(const EC_GROUP * a, unsigned char **out)
+{
+	int ret = 0;
+	ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(a, NULL);
+	if (tmp == NULL) {
+		ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
+		return 0;
+	}
+	if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) {
+		ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
+		ECPKPARAMETERS_free(tmp);
+		return 0;
+	}
+	ECPKPARAMETERS_free(tmp);
+	return (ret);
+}
+
+/* some EC_KEY functions */
+
+EC_KEY *
+d2i_ECPrivateKey(EC_KEY ** a, const unsigned char **in, long len)
+{
+	EC_KEY *ret = NULL;
+	EC_PRIVATEKEY *priv_key = NULL;
+
+	if ((priv_key = EC_PRIVATEKEY_new()) == NULL) {
+		ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	if ((priv_key = d2i_EC_PRIVATEKEY(&priv_key, in, len)) == NULL) {
+		ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+		EC_PRIVATEKEY_free(priv_key);
+		return NULL;
+	}
+	if (a == NULL || *a == NULL) {
+		if ((ret = EC_KEY_new()) == NULL) {
+			ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+	} else
+		ret = *a;
+
+	if (priv_key->parameters) {
+		EC_GROUP_clear_free(ret->group);
+		ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
+	}
+	if (ret->group == NULL) {
+		ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+		goto err;
+	}
+	ret->version = priv_key->version;
+
+	if (priv_key->privateKey) {
+		ret->priv_key = BN_bin2bn(
+		    ASN1_STRING_data(priv_key->privateKey),
+		    ASN1_STRING_length(priv_key->privateKey),
+		    ret->priv_key);
+		if (ret->priv_key == NULL) {
+			ECerr(EC_F_D2I_ECPRIVATEKEY,
+			    ERR_R_BN_LIB);
+			goto err;
+		}
+	} else {
+		ECerr(EC_F_D2I_ECPRIVATEKEY,
+		    EC_R_MISSING_PRIVATE_KEY);
+		goto err;
+	}
+
+	if (priv_key->publicKey) {
+		const unsigned char *pub_oct;
+		size_t pub_oct_len;
+
+		EC_POINT_clear_free(ret->pub_key);
+		ret->pub_key = EC_POINT_new(ret->group);
+		if (ret->pub_key == NULL) {
+			ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+			goto err;
+		}
+		pub_oct = ASN1_STRING_data(priv_key->publicKey);
+		pub_oct_len = ASN1_STRING_length(priv_key->publicKey);
+		/* save the point conversion form */
+		ret->conv_form = (point_conversion_form_t) (pub_oct[0] & ~0x01);
+		if (!EC_POINT_oct2point(ret->group, ret->pub_key,
+			pub_oct, pub_oct_len, NULL)) {
+			ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+			goto err;
+		}
+	}
+
+	EC_PRIVATEKEY_free(priv_key);
+	if (a != NULL)
+		*a = ret;
+	return (ret);
+
+err:
+	if (a == NULL || *a != ret)
+		EC_KEY_free(ret);
+	if (priv_key)
+		EC_PRIVATEKEY_free(priv_key);
+
+	return (NULL);
+}
+
+int 
+i2d_ECPrivateKey(EC_KEY * a, unsigned char **out)
+{
+	int ret = 0, ok = 0;
+	unsigned char *buffer = NULL;
+	size_t buf_len = 0, tmp_len;
+	EC_PRIVATEKEY *priv_key = NULL;
+
+	if (a == NULL || a->group == NULL || a->priv_key == NULL) {
+		ECerr(EC_F_I2D_ECPRIVATEKEY,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		goto err;
+	}
+	if ((priv_key = EC_PRIVATEKEY_new()) == NULL) {
+		ECerr(EC_F_I2D_ECPRIVATEKEY,
+		    ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	priv_key->version = a->version;
+
+	buf_len = (size_t) BN_num_bytes(a->priv_key);
+	buffer = malloc(buf_len);
+	if (buffer == NULL) {
+		ECerr(EC_F_I2D_ECPRIVATEKEY,
+		    ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	if (!BN_bn2bin(a->priv_key, buffer)) {
+		ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
+		goto err;
+	}
+	if (!ASN1_STRING_set(priv_key->privateKey, buffer, buf_len)) {
+		ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
+		goto err;
+	}
+	if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) {
+		if ((priv_key->parameters = ec_asn1_group2pkparameters(
+			    a->group, priv_key->parameters)) == NULL) {
+			ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
+			goto err;
+		}
+	}
+	if (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key != NULL) {
+		priv_key->publicKey = ASN1_BIT_STRING_new();
+		if (priv_key->publicKey == NULL) {
+			ECerr(EC_F_I2D_ECPRIVATEKEY,
+			    ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		tmp_len = EC_POINT_point2oct(a->group, a->pub_key,
+		    a->conv_form, NULL, 0, NULL);
+
+		if (tmp_len > buf_len) {
+			unsigned char *tmp_buffer = realloc(buffer, tmp_len);
+			if (!tmp_buffer) {
+				ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+			buffer = tmp_buffer;
+			buf_len = tmp_len;
+		}
+		if (!EC_POINT_point2oct(a->group, a->pub_key,
+			a->conv_form, buffer, buf_len, NULL)) {
+			ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
+			goto err;
+		}
+		priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+		priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+		if (!ASN1_STRING_set(priv_key->publicKey, buffer,
+			buf_len)) {
+			ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
+			goto err;
+		}
+	}
+	if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) {
+		ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
+		goto err;
+	}
+	ok = 1;
+err:
+	free(buffer);
+	if (priv_key)
+		EC_PRIVATEKEY_free(priv_key);
+	return (ok ? ret : 0);
+}
+
+int 
+i2d_ECParameters(EC_KEY * a, unsigned char **out)
+{
+	if (a == NULL) {
+		ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	return i2d_ECPKParameters(a->group, out);
+}
+
+EC_KEY *
+d2i_ECParameters(EC_KEY ** a, const unsigned char **in, long len)
+{
+	EC_KEY *ret;
+
+	if (in == NULL || *in == NULL) {
+		ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
+		return NULL;
+	}
+	if (a == NULL || *a == NULL) {
+		if ((ret = EC_KEY_new()) == NULL) {
+			ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
+			return NULL;
+		}
+	} else
+		ret = *a;
+
+	if (!d2i_ECPKParameters(&ret->group, in, len)) {
+		ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
+		if (a == NULL || *a != ret)
+			EC_KEY_free(ret);
+		return NULL;
+	}
+
+	if (a != NULL)
+		*a = ret;
+	return ret;
+}
+
+EC_KEY *
+o2i_ECPublicKey(EC_KEY ** a, const unsigned char **in, long len)
+{
+	EC_KEY *ret = NULL;
+
+	if (a == NULL || (*a) == NULL || (*a)->group == NULL) {
+		/*
+		 * sorry, but a EC_GROUP-structur is necessary to set the
+		 * public key
+		 */
+		ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	ret = *a;
+	if (ret->pub_key == NULL &&
+	    (ret->pub_key = EC_POINT_new(ret->group)) == NULL) {
+		ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL)) {
+		ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB);
+		return 0;
+	}
+	/* save the point conversion form */
+	ret->conv_form = (point_conversion_form_t) (*in[0] & ~0x01);
+	*in += len;
+	return ret;
+}
+
+int 
+i2o_ECPublicKey(EC_KEY * a, unsigned char **out)
+{
+	size_t buf_len = 0;
+	int new_buffer = 0;
+
+	if (a == NULL) {
+		ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	buf_len = EC_POINT_point2oct(a->group, a->pub_key,
+	    a->conv_form, NULL, 0, NULL);
+
+	if (out == NULL || buf_len == 0)
+		/* out == NULL => just return the length of the octet string */
+		return buf_len;
+
+	if (*out == NULL) {
+		if ((*out = malloc(buf_len)) == NULL) {
+			ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		new_buffer = 1;
+	}
+	if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
+		*out, buf_len, NULL)) {
+		ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
+		if (new_buffer) {
+			free(*out);
+			*out = NULL;
+		}
+		return 0;
+	}
+	if (!new_buffer)
+		*out += buf_len;
+	return buf_len;
+}
diff --git a/crypto/libressl/crypto/ec/ec_check.c b/crypto/libressl/crypto/ec/ec_check.c
new file mode 100644
index 0000000000..233d28916c
--- /dev/null
+++ b/crypto/libressl/crypto/ec/ec_check.c
@@ -0,0 +1,115 @@
+/* $OpenBSD: ec_check.c,v 1.4 2014/07/12 16:03:37 miod Exp $ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "ec_lcl.h"
+#include 
+
+int 
+EC_GROUP_check(const EC_GROUP * group, BN_CTX * ctx)
+{
+	int ret = 0;
+	BIGNUM *order;
+	BN_CTX *new_ctx = NULL;
+	EC_POINT *point = NULL;
+
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL) {
+			ECerr(EC_F_EC_GROUP_CHECK, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+	}
+	BN_CTX_start(ctx);
+	if ((order = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	/* check the discriminant */
+	if (!EC_GROUP_check_discriminant(group, ctx)) {
+		ECerr(EC_F_EC_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO);
+		goto err;
+	}
+	/* check the generator */
+	if (group->generator == NULL) {
+		ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);
+		goto err;
+	}
+	if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) {
+		ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);
+		goto err;
+	}
+	/* check the order of the generator */
+	if ((point = EC_POINT_new(group)) == NULL)
+		goto err;
+	if (!EC_GROUP_get_order(group, order, ctx))
+		goto err;
+	if (BN_is_zero(order)) {
+		ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER);
+		goto err;
+	}
+	if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx))
+		goto err;
+	if (EC_POINT_is_at_infinity(group, point) <= 0) {
+		ECerr(EC_F_EC_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER);
+		goto err;
+	}
+	ret = 1;
+
+err:
+	if (ctx != NULL)
+		BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	EC_POINT_free(point);
+	return ret;
+}
diff --git a/crypto/libressl/crypto/ec/ec_curve.c b/crypto/libressl/crypto/ec/ec_curve.c
new file mode 100644
index 0000000000..4eaaa4f9c3
--- /dev/null
+++ b/crypto/libressl/crypto/ec/ec_curve.c
@@ -0,0 +1,3340 @@
+/* $OpenBSD: ec_curve.c,v 1.12 2015/06/20 13:26:08 jsing Exp $ */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2010 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#include 
+
+#include 
+
+#include "ec_lcl.h"
+#include 
+#include 
+
+typedef struct {
+	int field_type,		/* either NID_X9_62_prime_field or
+				 * NID_X9_62_characteristic_two_field */
+	 seed_len, param_len;
+	unsigned int cofactor;	/* promoted to BN_ULONG */
+} EC_CURVE_DATA;
+
+/* the nist prime curves */
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 24 * 6];
+}
+ _EC_NIST_PRIME_192 = {
+	{
+		NID_X9_62_prime_field, 20, 24, 1
+	},
+	{
+		0x30, 0x45, 0xAE, 0x6F, 0xC8, 0x42, 0x2F, 0x64, 0xED, 0x57,	/* seed */
+		0x95, 0x28, 0xD3, 0x81, 0x20, 0xEA, 0xE1, 0x21, 0x96, 0xD5,
+
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* a */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFC,
+		0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7, 0x0F, 0xA7,	/* b */
+		0xE9, 0xAB, 0x72, 0x24, 0x30, 0x49, 0xFE, 0xB8, 0xDE, 0xEC,
+		0xC1, 0x46, 0xB9, 0xB1,
+		0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6, 0x7C, 0xBF,	/* x */
+		0x20, 0xEB, 0x43, 0xA1, 0x88, 0x00, 0xF4, 0xFF, 0x0A, 0xFD,
+		0x82, 0xFF, 0x10, 0x12,
+		0x07, 0x19, 0x2b, 0x95, 0xff, 0xc8, 0xda, 0x78, 0x63, 0x10,	/* y */
+		0x11, 0xed, 0x6b, 0x24, 0xcd, 0xd5, 0x73, 0xf9, 0x77, 0xa1,
+		0x1e, 0x79, 0x48, 0x11,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFF, 0xFF, 0x99, 0xDE, 0xF8, 0x36, 0x14, 0x6B, 0xC9, 0xB1,
+		0xB4, 0xD2, 0x28, 0x31
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 28 * 6];
+}
+ _EC_NIST_PRIME_224 = {
+	{
+		NID_X9_62_prime_field, 20, 28, 1
+	},
+	{
+		0xBD, 0x71, 0x34, 0x47, 0x99, 0xD5, 0xC7, 0xFC, 0xDC, 0x45,	/* seed */
+		0xB5, 0x9F, 0xA3, 0xB9, 0xAB, 0x8F, 0x6A, 0x94, 0x8B, 0xC5,
+
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* a */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
+		0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41,	/* b */
+		0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA,
+		0x27, 0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4,
+		0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13,	/* x */
+		0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22,
+		0x34, 0x32, 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21,
+		0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22,	/* y */
+		0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64,
+		0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFF, 0xFF, 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E,
+		0x13, 0xDD, 0x29, 0x45, 0x5C, 0x5C, 0x2A, 0x3D
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 48 * 6];
+}
+ _EC_NIST_PRIME_384 = {
+	{
+		NID_X9_62_prime_field, 20, 48, 1
+	},
+	{
+		0xA3, 0x35, 0x92, 0x6A, 0xA3, 0x19, 0xA2, 0x7A, 0x1D, 0x00,	/* seed */
+		0x89, 0x6A, 0x67, 0x73, 0xA4, 0x82, 0x7A, 0xCD, 0xAC, 0x73,
+
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* a */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC,
+		0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E,	/* b */
+		0x05, 0x6B, 0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E,
+		0xFE, 0x81, 0x41, 0x12, 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13,
+		0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D, 0x8A, 0x2E, 0xD1, 0x9D,
+		0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF,
+		0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1,	/* x */
+		0xC7, 0x1E, 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62,
+		0x8B, 0xA7, 0x9B, 0x98, 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54,
+		0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D, 0xBF, 0x55, 0x29, 0x6C,
+		0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
+		0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e,	/* y */
+		0x98, 0xbf, 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd,
+		0x28, 0x9a, 0x14, 0x7c, 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0,
+		0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce, 0x1d, 0x7e, 0x81, 0x9d,
+		0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37,
+		0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A,
+		0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 66 * 6];
+}
+ _EC_NIST_PRIME_521 = {
+	{
+		NID_X9_62_prime_field, 20, 66, 1
+	},
+	{
+		0xD0, 0x9E, 0x88, 0x00, 0x29, 0x1C, 0xB8, 0x53, 0x96, 0xCC,	/* seed */
+		0x67, 0x17, 0x39, 0x32, 0x84, 0xAA, 0xA0, 0xDA, 0x64, 0xBA,
+
+		0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* a */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+		0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F,	/* b */
+		0x92, 0x9A, 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA,
+		0x72, 0x5B, 0x99, 0xB3, 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91,
+		0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19, 0x39, 0x51, 0xEC, 0x7E,
+		0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, 0xBF, 0x07,
+		0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
+		0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00,
+		0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD,	/* x */
+		0x9E, 0x3E, 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64,
+		0x81, 0x39, 0x05, 0x3F, 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60,
+		0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B, 0x5E, 0x77, 0xEF, 0xE7,
+		0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, 0xA8, 0xDE,
+		0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
+		0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
+		0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04,	/* y */
+		0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5,
+		0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
+		0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4,
+		0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61,
+		0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
+		0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
+		0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F,
+		0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, 0xA5, 0xD0,
+		0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
+		0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09
+	}
+};
+
+/* the x9.62 prime curves (minus the nist prime curves) */
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 24 * 6];
+}
+ _EC_X9_62_PRIME_192V2 = {
+	{
+		NID_X9_62_prime_field, 20, 24, 1
+	},
+	{
+		0x31, 0xA9, 0x2E, 0xE2, 0x02, 0x9F, 0xD1, 0x0D, 0x90, 0x1B,	/* seed */
+		0x11, 0x3E, 0x99, 0x07, 0x10, 0xF0, 0xD2, 0x1A, 0xC6, 0xB6,
+
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* a */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFC,
+		0xCC, 0x22, 0xD6, 0xDF, 0xB9, 0x5C, 0x6B, 0x25, 0xE4, 0x9C,	/* b */
+		0x0D, 0x63, 0x64, 0xA4, 0xE5, 0x98, 0x0C, 0x39, 0x3A, 0xA2,
+		0x16, 0x68, 0xD9, 0x53,
+		0xEE, 0xA2, 0xBA, 0xE7, 0xE1, 0x49, 0x78, 0x42, 0xF2, 0xDE,	/* x */
+		0x77, 0x69, 0xCF, 0xE9, 0xC9, 0x89, 0xC0, 0x72, 0xAD, 0x69,
+		0x6F, 0x48, 0x03, 0x4A,
+		0x65, 0x74, 0xd1, 0x1d, 0x69, 0xb6, 0xec, 0x7a, 0x67, 0x2b,	/* y */
+		0xb8, 0x2a, 0x08, 0x3d, 0xf2, 0xf2, 0xb0, 0x84, 0x7d, 0xe9,
+		0x70, 0xb2, 0xde, 0x15,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFF, 0xFE, 0x5F, 0xB1, 0xA7, 0x24, 0xDC, 0x80, 0x41, 0x86,
+		0x48, 0xD8, 0xDD, 0x31
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 24 * 6];
+}
+ _EC_X9_62_PRIME_192V3 = {
+	{
+		NID_X9_62_prime_field, 20, 24, 1
+	},
+	{
+		0xC4, 0x69, 0x68, 0x44, 0x35, 0xDE, 0xB3, 0x78, 0xC4, 0xB6,	/* seed */
+		0x5C, 0xA9, 0x59, 0x1E, 0x2A, 0x57, 0x63, 0x05, 0x9A, 0x2E,
+
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* a */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFC,
+		0x22, 0x12, 0x3D, 0xC2, 0x39, 0x5A, 0x05, 0xCA, 0xA7, 0x42,	/* b */
+		0x3D, 0xAE, 0xCC, 0xC9, 0x47, 0x60, 0xA7, 0xD4, 0x62, 0x25,
+		0x6B, 0xD5, 0x69, 0x16,
+		0x7D, 0x29, 0x77, 0x81, 0x00, 0xC6, 0x5A, 0x1D, 0xA1, 0x78,	/* x */
+		0x37, 0x16, 0x58, 0x8D, 0xCE, 0x2B, 0x8B, 0x4A, 0xEE, 0x8E,
+		0x22, 0x8F, 0x18, 0x96,
+		0x38, 0xa9, 0x0f, 0x22, 0x63, 0x73, 0x37, 0x33, 0x4b, 0x49,	/* y */
+		0xdc, 0xb6, 0x6a, 0x6d, 0xc8, 0xf9, 0x97, 0x8a, 0xca, 0x76,
+		0x48, 0xa9, 0x43, 0xb0,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFF, 0xFF, 0x7A, 0x62, 0xD0, 0x31, 0xC8, 0x3F, 0x42, 0x94,
+		0xF6, 0x40, 0xEC, 0x13
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 30 * 6];
+}
+ _EC_X9_62_PRIME_239V1 = {
+	{
+		NID_X9_62_prime_field, 20, 30, 1
+	},
+	{
+		0xE4, 0x3B, 0xB4, 0x60, 0xF0, 0xB8, 0x0C, 0xC0, 0xC0, 0xB0,	/* seed */
+		0x75, 0x79, 0x8E, 0x94, 0x80, 0x60, 0xF8, 0x32, 0x1B, 0x7D,
+
+		0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
+		0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* a */
+		0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+
+		0x6B, 0x01, 0x6C, 0x3B, 0xDC, 0xF1, 0x89, 0x41, 0xD0, 0xD6,	/* b */
+		0x54, 0x92, 0x14, 0x75, 0xCA, 0x71, 0xA9, 0xDB, 0x2F, 0xB2,
+		0x7D, 0x1D, 0x37, 0x79, 0x61, 0x85, 0xC2, 0x94, 0x2C, 0x0A,
+
+		0x0F, 0xFA, 0x96, 0x3C, 0xDC, 0xA8, 0x81, 0x6C, 0xCC, 0x33,	/* x */
+		0xB8, 0x64, 0x2B, 0xED, 0xF9, 0x05, 0xC3, 0xD3, 0x58, 0x57,
+		0x3D, 0x3F, 0x27, 0xFB, 0xBD, 0x3B, 0x3C, 0xB9, 0xAA, 0xAF,
+
+		0x7d, 0xeb, 0xe8, 0xe4, 0xe9, 0x0a, 0x5d, 0xae, 0x6e, 0x40,	/* y */
+		0x54, 0xca, 0x53, 0x0b, 0xa0, 0x46, 0x54, 0xb3, 0x68, 0x18,
+		0xce, 0x22, 0x6b, 0x39, 0xfc, 0xcb, 0x7b, 0x02, 0xf1, 0xae,
+
+		0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x9E, 0x5E, 0x9A, 0x9F, 0x5D,
+		0x90, 0x71, 0xFB, 0xD1, 0x52, 0x26, 0x88, 0x90, 0x9D, 0x0B
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 30 * 6];
+}
+ _EC_X9_62_PRIME_239V2 = {
+	{
+		NID_X9_62_prime_field, 20, 30, 1
+	},
+	{
+		0xE8, 0xB4, 0x01, 0x16, 0x04, 0x09, 0x53, 0x03, 0xCA, 0x3B,	/* seed */
+		0x80, 0x99, 0x98, 0x2B, 0xE0, 0x9F, 0xCB, 0x9A, 0xE6, 0x16,
+
+		0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
+		0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* a */
+		0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+
+		0x61, 0x7F, 0xAB, 0x68, 0x32, 0x57, 0x6C, 0xBB, 0xFE, 0xD5,	/* b */
+		0x0D, 0x99, 0xF0, 0x24, 0x9C, 0x3F, 0xEE, 0x58, 0xB9, 0x4B,
+		0xA0, 0x03, 0x8C, 0x7A, 0xE8, 0x4C, 0x8C, 0x83, 0x2F, 0x2C,
+
+		0x38, 0xAF, 0x09, 0xD9, 0x87, 0x27, 0x70, 0x51, 0x20, 0xC9,	/* x */
+		0x21, 0xBB, 0x5E, 0x9E, 0x26, 0x29, 0x6A, 0x3C, 0xDC, 0xF2,
+		0xF3, 0x57, 0x57, 0xA0, 0xEA, 0xFD, 0x87, 0xB8, 0x30, 0xE7,
+
+		0x5b, 0x01, 0x25, 0xe4, 0xdb, 0xea, 0x0e, 0xc7, 0x20, 0x6d,	/* y */
+		0xa0, 0xfc, 0x01, 0xd9, 0xb0, 0x81, 0x32, 0x9f, 0xb5, 0x55,
+		0xde, 0x6e, 0xf4, 0x60, 0x23, 0x7d, 0xff, 0x8b, 0xe4, 0xba,
+
+		0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFF, 0xFF, 0x80, 0x00, 0x00, 0xCF, 0xA7, 0xE8, 0x59, 0x43,
+		0x77, 0xD4, 0x14, 0xC0, 0x38, 0x21, 0xBC, 0x58, 0x20, 0x63
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 30 * 6];
+}
+ _EC_X9_62_PRIME_239V3 = {
+	{
+		NID_X9_62_prime_field, 20, 30, 1
+	},
+	{
+		0x7D, 0x73, 0x74, 0x16, 0x8F, 0xFE, 0x34, 0x71, 0xB6, 0x0A,	/* seed */
+		0x85, 0x76, 0x86, 0xA1, 0x94, 0x75, 0xD3, 0xBF, 0xA2, 0xFF,
+
+		0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
+		0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* a */
+		0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+
+		0x25, 0x57, 0x05, 0xFA, 0x2A, 0x30, 0x66, 0x54, 0xB1, 0xF4,	/* b */
+		0xCB, 0x03, 0xD6, 0xA7, 0x50, 0xA3, 0x0C, 0x25, 0x01, 0x02,
+		0xD4, 0x98, 0x87, 0x17, 0xD9, 0xBA, 0x15, 0xAB, 0x6D, 0x3E,
+
+		0x67, 0x68, 0xAE, 0x8E, 0x18, 0xBB, 0x92, 0xCF, 0xCF, 0x00,	/* x */
+		0x5C, 0x94, 0x9A, 0xA2, 0xC6, 0xD9, 0x48, 0x53, 0xD0, 0xE6,
+		0x60, 0xBB, 0xF8, 0x54, 0xB1, 0xC9, 0x50, 0x5F, 0xE9, 0x5A,
+
+		0x16, 0x07, 0xe6, 0x89, 0x8f, 0x39, 0x0c, 0x06, 0xbc, 0x1d,	/* y */
+		0x55, 0x2b, 0xad, 0x22, 0x6f, 0x3b, 0x6f, 0xcf, 0xe4, 0x8b,
+		0x6e, 0x81, 0x84, 0x99, 0xaf, 0x18, 0xe3, 0xed, 0x6c, 0xf3,
+
+		0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x97, 0x5D, 0xEB, 0x41, 0xB3,
+		0xA6, 0x05, 0x7C, 0x3C, 0x43, 0x21, 0x46, 0x52, 0x65, 0x51
+	}
+};
+
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 32 * 6];
+}
+ _EC_X9_62_PRIME_256V1 = {
+	{
+		NID_X9_62_prime_field, 20, 32, 1
+	},
+	{
+		0xC4, 0x9D, 0x36, 0x08, 0x86, 0xE7, 0x04, 0x93, 0x6A, 0x66,	/* seed */
+		0x78, 0xE1, 0x13, 0x9D, 0x26, 0xB7, 0x81, 0x9F, 0x7E, 0x90,
+
+		0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFC,
+		0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB,	/* b */
+		0xBD, 0x55, 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0,
+		0xCC, 0x53, 0xB0, 0xF6, 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2,
+		0x60, 0x4B,
+		0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC,	/* x */
+		0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81,
+		0x2D, 0xEB, 0x33, 0xA0, 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98,
+		0xC2, 0x96,
+		0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7,	/* y */
+		0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57,
+		0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf,
+		0x51, 0xf5,
+		0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,	/* order */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD,
+		0xA7, 0x17, 0x9E, 0x84, 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63,
+		0x25, 0x51
+	}
+};
+
+/* the secg prime curves (minus the nist and x9.62 prime curves) */
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 14 * 6];
+}
+ _EC_SECG_PRIME_112R1 = {
+	{
+		NID_X9_62_prime_field, 20, 14, 1
+	},
+	{
+		0x00, 0xF5, 0x0B, 0x02, 0x8E, 0x4D, 0x69, 0x6E, 0x67, 0x68,	/* seed */
+		0x75, 0x61, 0x51, 0x75, 0x29, 0x04, 0x72, 0x78, 0x3F, 0xB1,
+
+		0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76,	/* p */
+		0xBE, 0xAD, 0x20, 0x8B,
+		0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76,	/* a */
+		0xBE, 0xAD, 0x20, 0x88,
+		0x65, 0x9E, 0xF8, 0xBA, 0x04, 0x39, 0x16, 0xEE, 0xDE, 0x89,	/* b */
+		0x11, 0x70, 0x2B, 0x22,
+		0x09, 0x48, 0x72, 0x39, 0x99, 0x5A, 0x5E, 0xE7, 0x6B, 0x55,	/* x */
+		0xF9, 0xC2, 0xF0, 0x98,
+		0xa8, 0x9c, 0xe5, 0xaf, 0x87, 0x24, 0xc0, 0xa2, 0x3e, 0x0e,	/* y */
+		0x0f, 0xf7, 0x75, 0x00,
+		0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x76, 0x28, 0xDF,	/* order */
+		0xAC, 0x65, 0x61, 0xC5
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 14 * 6];
+}
+ _EC_SECG_PRIME_112R2 = {
+	{
+		NID_X9_62_prime_field, 20, 14, 4
+	},
+	{
+		0x00, 0x27, 0x57, 0xA1, 0x11, 0x4D, 0x69, 0x6E, 0x67, 0x68,	/* seed */
+		0x75, 0x61, 0x51, 0x75, 0x53, 0x16, 0xC0, 0x5E, 0x0B, 0xD4,
+
+		0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76,	/* p */
+		0xBE, 0xAD, 0x20, 0x8B,
+		0x61, 0x27, 0xC2, 0x4C, 0x05, 0xF3, 0x8A, 0x0A, 0xAA, 0xF6,	/* a */
+		0x5C, 0x0E, 0xF0, 0x2C,
+		0x51, 0xDE, 0xF1, 0x81, 0x5D, 0xB5, 0xED, 0x74, 0xFC, 0xC3,	/* b */
+		0x4C, 0x85, 0xD7, 0x09,
+		0x4B, 0xA3, 0x0A, 0xB5, 0xE8, 0x92, 0xB4, 0xE1, 0x64, 0x9D,	/* x */
+		0xD0, 0x92, 0x86, 0x43,
+		0xad, 0xcd, 0x46, 0xf5, 0x88, 0x2e, 0x37, 0x47, 0xde, 0xf3,	/* y */
+		0x6e, 0x95, 0x6e, 0x97,
+		0x36, 0xDF, 0x0A, 0xAF, 0xD8, 0xB8, 0xD7, 0x59, 0x7C, 0xA1,	/* order */
+		0x05, 0x20, 0xD0, 0x4B
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 16 * 6];
+}
+ _EC_SECG_PRIME_128R1 = {
+	{
+		NID_X9_62_prime_field, 20, 16, 1
+	},
+	{
+		0x00, 0x0E, 0x0D, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61,	/* seed */
+		0x51, 0x75, 0x0C, 0xC0, 0x3A, 0x44, 0x73, 0xD0, 0x36, 0x79,
+
+		0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* a */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+		0xE8, 0x75, 0x79, 0xC1, 0x10, 0x79, 0xF4, 0x3D, 0xD8, 0x24,	/* b */
+		0x99, 0x3C, 0x2C, 0xEE, 0x5E, 0xD3,
+		0x16, 0x1F, 0xF7, 0x52, 0x8B, 0x89, 0x9B, 0x2D, 0x0C, 0x28,	/* x */
+		0x60, 0x7C, 0xA5, 0x2C, 0x5B, 0x86,
+		0xcf, 0x5a, 0xc8, 0x39, 0x5b, 0xaf, 0xeb, 0x13, 0xc0, 0x2d,	/* y */
+		0xa2, 0x92, 0xdd, 0xed, 0x7a, 0x83,
+		0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x75, 0xA3,	/* order */
+		0x0D, 0x1B, 0x90, 0x38, 0xA1, 0x15
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 16 * 6];
+}
+ _EC_SECG_PRIME_128R2 = {
+	{
+		NID_X9_62_prime_field, 20, 16, 4
+	},
+	{
+		0x00, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75,	/* seed */
+		0x12, 0xD8, 0xF0, 0x34, 0x31, 0xFC, 0xE6, 0x3B, 0x88, 0xF4,
+
+		0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xD6, 0x03, 0x19, 0x98, 0xD1, 0xB3, 0xBB, 0xFE, 0xBF, 0x59,	/* a */
+		0xCC, 0x9B, 0xBF, 0xF9, 0xAE, 0xE1,
+		0x5E, 0xEE, 0xFC, 0xA3, 0x80, 0xD0, 0x29, 0x19, 0xDC, 0x2C,	/* b */
+		0x65, 0x58, 0xBB, 0x6D, 0x8A, 0x5D,
+		0x7B, 0x6A, 0xA5, 0xD8, 0x5E, 0x57, 0x29, 0x83, 0xE6, 0xFB,	/* x */
+		0x32, 0xA7, 0xCD, 0xEB, 0xC1, 0x40,
+		0x27, 0xb6, 0x91, 0x6a, 0x89, 0x4d, 0x3a, 0xee, 0x71, 0x06,	/* y */
+		0xfe, 0x80, 0x5f, 0xc3, 0x4b, 0x44,
+		0x3F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xBE, 0x00,	/* order */
+		0x24, 0x72, 0x06, 0x13, 0xB5, 0xA3
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 21 * 6];
+}
+ _EC_SECG_PRIME_160K1 = {
+	{
+		NID_X9_62_prime_field, 0, 21, 1
+	},
+	{			/* no seed */
+		0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC,
+		0x73,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* b */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x07,
+		0x00, 0x3B, 0x4C, 0x38, 0x2C, 0xE3, 0x7A, 0xA1, 0x92, 0xA4,	/* x */
+		0x01, 0x9E, 0x76, 0x30, 0x36, 0xF4, 0xF5, 0xDD, 0x4D, 0x7E,
+		0xBB,
+		0x00, 0x93, 0x8c, 0xf9, 0x35, 0x31, 0x8f, 0xdc, 0xed, 0x6b,	/* y */
+		0xc2, 0x82, 0x86, 0x53, 0x17, 0x33, 0xc3, 0xf0, 0x3c, 0x4f,
+		0xee,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x01, 0xB8, 0xFA, 0x16, 0xDF, 0xAB, 0x9A, 0xCA, 0x16, 0xB6,
+		0xB3
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 21 * 6];
+}
+ _EC_SECG_PRIME_160R1 = {
+	{
+		NID_X9_62_prime_field, 20, 21, 1
+	},
+	{
+		0x10, 0x53, 0xCD, 0xE4, 0x2C, 0x14, 0xD6, 0x96, 0xE6, 0x76,	/* seed */
+		0x87, 0x56, 0x15, 0x17, 0x53, 0x3B, 0xF3, 0xF8, 0x33, 0x45,
+
+		0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF,
+		0xFF,
+		0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* a */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF,
+		0xFC,
+		0x00, 0x1C, 0x97, 0xBE, 0xFC, 0x54, 0xBD, 0x7A, 0x8B, 0x65,	/* b */
+		0xAC, 0xF8, 0x9F, 0x81, 0xD4, 0xD4, 0xAD, 0xC5, 0x65, 0xFA,
+		0x45,
+		0x00, 0x4A, 0x96, 0xB5, 0x68, 0x8E, 0xF5, 0x73, 0x28, 0x46,	/* x */
+		0x64, 0x69, 0x89, 0x68, 0xC3, 0x8B, 0xB9, 0x13, 0xCB, 0xFC,
+		0x82,
+		0x00, 0x23, 0xa6, 0x28, 0x55, 0x31, 0x68, 0x94, 0x7d, 0x59,	/* y */
+		0xdc, 0xc9, 0x12, 0x04, 0x23, 0x51, 0x37, 0x7a, 0xc5, 0xfb,
+		0x32,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x01, 0xF4, 0xC8, 0xF9, 0x27, 0xAE, 0xD3, 0xCA, 0x75, 0x22,
+		0x57
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 21 * 6];
+}
+ _EC_SECG_PRIME_160R2 = {
+	{
+		NID_X9_62_prime_field, 20, 21, 1
+	},
+	{
+		0xB9, 0x9B, 0x99, 0xB0, 0x99, 0xB3, 0x23, 0xE0, 0x27, 0x09,	/* seed */
+		0xA4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x51,
+
+		0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC,
+		0x73,
+		0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* a */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC,
+		0x70,
+		0x00, 0xB4, 0xE1, 0x34, 0xD3, 0xFB, 0x59, 0xEB, 0x8B, 0xAB,	/* b */
+		0x57, 0x27, 0x49, 0x04, 0x66, 0x4D, 0x5A, 0xF5, 0x03, 0x88,
+		0xBA,
+		0x00, 0x52, 0xDC, 0xB0, 0x34, 0x29, 0x3A, 0x11, 0x7E, 0x1F,	/* x */
+		0x4F, 0xF1, 0x1B, 0x30, 0xF7, 0x19, 0x9D, 0x31, 0x44, 0xCE,
+		0x6D,
+		0x00, 0xfe, 0xaf, 0xfe, 0xf2, 0xe3, 0x31, 0xf2, 0x96, 0xe0,	/* y */
+		0x71, 0xfa, 0x0d, 0xf9, 0x98, 0x2c, 0xfe, 0xa7, 0xd4, 0x3f,
+		0x2e,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x00, 0x35, 0x1E, 0xE7, 0x86, 0xA8, 0x18, 0xF3, 0xA1, 0xA1,
+		0x6B
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 24 * 6];
+}
+ _EC_SECG_PRIME_192K1 = {
+	{
+		NID_X9_62_prime_field, 0, 24, 1
+	},
+	{			/* no seed */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
+		0xFF, 0xFF, 0xEE, 0x37,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* b */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x03,
+		0xDB, 0x4F, 0xF1, 0x0E, 0xC0, 0x57, 0xE9, 0xAE, 0x26, 0xB0,	/* x */
+		0x7D, 0x02, 0x80, 0xB7, 0xF4, 0x34, 0x1D, 0xA5, 0xD1, 0xB1,
+		0xEA, 0xE0, 0x6C, 0x7D,
+		0x9b, 0x2f, 0x2f, 0x6d, 0x9c, 0x56, 0x28, 0xa7, 0x84, 0x41,	/* y */
+		0x63, 0xd0, 0x15, 0xbe, 0x86, 0x34, 0x40, 0x82, 0xaa, 0x88,
+		0xd9, 0x5e, 0x2f, 0x9d,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFF, 0xFE, 0x26, 0xF2, 0xFC, 0x17, 0x0F, 0x69, 0x46, 0x6A,
+		0x74, 0xDE, 0xFD, 0x8D
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 29 * 6];
+}
+ _EC_SECG_PRIME_224K1 = {
+	{
+		NID_X9_62_prime_field, 0, 29, 1
+	},
+	{			/* no seed */
+		0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xE5, 0x6D,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* b */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+		0x00, 0xA1, 0x45, 0x5B, 0x33, 0x4D, 0xF0, 0x99, 0xDF, 0x30,	/* x */
+		0xFC, 0x28, 0xA1, 0x69, 0xA4, 0x67, 0xE9, 0xE4, 0x70, 0x75,
+		0xA9, 0x0F, 0x7E, 0x65, 0x0E, 0xB6, 0xB7, 0xA4, 0x5C,
+		0x00, 0x7e, 0x08, 0x9f, 0xed, 0x7f, 0xba, 0x34, 0x42, 0x82,	/* y */
+		0xca, 0xfb, 0xd6, 0xf7, 0xe3, 0x19, 0xf7, 0xc0, 0xb0, 0xbd,
+		0x59, 0xe2, 0xca, 0x4b, 0xdb, 0x55, 0x6d, 0x61, 0xa5,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x00, 0x00, 0x00, 0x00, 0x01, 0xDC, 0xE8, 0xD2, 0xEC, 0x61,
+		0x84, 0xCA, 0xF0, 0xA9, 0x71, 0x76, 0x9F, 0xB1, 0xF7
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 32 * 6];
+}
+ _EC_SECG_PRIME_256K1 = {
+	{
+		NID_X9_62_prime_field, 0, 32, 1
+	},
+	{			/* no seed */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF,
+		0xFC, 0x2F,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* b */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x07,
+		0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0,	/* x */
+		0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB,
+		0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8,
+		0x17, 0x98,
+		0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4,	/* y */
+		0xfb, 0xfc, 0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48,
+		0xa6, 0x85, 0x54, 0x19, 0x9c, 0x47, 0xd0, 0x8f, 0xfb, 0x10,
+		0xd4, 0xb8,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6,
+		0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36,
+		0x41, 0x41
+	}
+};
+
+/* some wap/wtls curves */
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 15 * 6];
+}
+ _EC_WTLS_8 = {
+	{
+		NID_X9_62_prime_field, 0, 15, 1
+	},
+	{			/* no seed */
+		0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0xFF, 0xFD, 0xE7,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* b */
+		0x00, 0x00, 0x00, 0x00, 0x03,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* x */
+		0x00, 0x00, 0x00, 0x00, 0x01,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* y */
+		0x00, 0x00, 0x00, 0x00, 0x02,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xEC, 0xEA,	/* order */
+		0x55, 0x1A, 0xD8, 0x37, 0xE9
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 21 * 6];
+}
+ _EC_WTLS_9 = {
+	{
+		NID_X9_62_prime_field, 0, 21, 1
+	},
+	{			/* no seed */
+		0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x80,
+		0x8F,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* b */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x03,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* x */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x01,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* y */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x02,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x01, 0xCD, 0xC9, 0x8A, 0xE0, 0xE2, 0xDE, 0x57, 0x4A, 0xBF,
+		0x33
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 28 * 6];
+}
+ _EC_WTLS_12 = {
+	{
+		NID_X9_62_prime_field, 0, 28, 1
+	},
+	{			/* no seed */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* a */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
+		0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41,	/* b */
+		0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA,
+		0x27, 0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4,
+		0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13,	/* x */
+		0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22,
+		0x34, 0x32, 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21,
+		0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22,	/* y */
+		0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64,
+		0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFF, 0xFF, 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E,
+		0x13, 0xDD, 0x29, 0x45, 0x5C, 0x5C, 0x2A, 0x3D
+	}
+};
+
+#ifndef OPENSSL_NO_EC2M
+
+/* characteristic two curves */
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 15 * 6];
+}
+ _EC_SECG_CHAR2_113R1 = {
+	{
+		NID_X9_62_characteristic_two_field, 20, 15, 2
+	},
+	{
+		0x10, 0xE7, 0x23, 0xAB, 0x14, 0xD6, 0x96, 0xE6, 0x76, 0x87,	/* seed */
+		0x56, 0x15, 0x17, 0x56, 0xFE, 0xBF, 0x8F, 0xCB, 0x49, 0xA9,
+
+		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x02, 0x01,
+		0x00, 0x30, 0x88, 0x25, 0x0C, 0xA6, 0xE7, 0xC7, 0xFE, 0x64,	/* a */
+		0x9C, 0xE8, 0x58, 0x20, 0xF7,
+		0x00, 0xE8, 0xBE, 0xE4, 0xD3, 0xE2, 0x26, 0x07, 0x44, 0x18,	/* b */
+		0x8B, 0xE0, 0xE9, 0xC7, 0x23,
+		0x00, 0x9D, 0x73, 0x61, 0x6F, 0x35, 0xF4, 0xAB, 0x14, 0x07,	/* x */
+		0xD7, 0x35, 0x62, 0xC1, 0x0F,
+		0x00, 0xA5, 0x28, 0x30, 0x27, 0x79, 0x58, 0xEE, 0x84, 0xD1,	/* y */
+		0x31, 0x5E, 0xD3, 0x18, 0x86,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0xCC,	/* order */
+		0xEC, 0x8A, 0x39, 0xE5, 0x6F
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 15 * 6];
+}
+ _EC_SECG_CHAR2_113R2 = {
+	{
+		NID_X9_62_characteristic_two_field, 20, 15, 2
+	},
+	{
+		0x10, 0xC0, 0xFB, 0x15, 0x76, 0x08, 0x60, 0xDE, 0xF1, 0xEE,	/* seed */
+		0xF4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x5D,
+
+		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x02, 0x01,
+		0x00, 0x68, 0x99, 0x18, 0xDB, 0xEC, 0x7E, 0x5A, 0x0D, 0xD6,	/* a */
+		0xDF, 0xC0, 0xAA, 0x55, 0xC7,
+		0x00, 0x95, 0xE9, 0xA9, 0xEC, 0x9B, 0x29, 0x7B, 0xD4, 0xBF,	/* b */
+		0x36, 0xE0, 0x59, 0x18, 0x4F,
+		0x01, 0xA5, 0x7A, 0x6A, 0x7B, 0x26, 0xCA, 0x5E, 0xF5, 0x2F,	/* x */
+		0xCD, 0xB8, 0x16, 0x47, 0x97,
+		0x00, 0xB3, 0xAD, 0xC9, 0x4E, 0xD1, 0xFE, 0x67, 0x4C, 0x06,	/* y */
+		0xE6, 0x95, 0xBA, 0xBA, 0x1D,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x78,	/* order */
+		0x9B, 0x24, 0x96, 0xAF, 0x93
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 17 * 6];
+}
+ _EC_SECG_CHAR2_131R1 = {
+	{
+		NID_X9_62_characteristic_two_field, 20, 17, 2
+	},
+	{
+		0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, 0x98,	/* seed */
+		0x5B, 0xD3, 0xAD, 0xBA, 0xDA, 0x21, 0xB4, 0x3A, 0x97, 0xE2,
+
+		0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0D,
+		0x07, 0xA1, 0x1B, 0x09, 0xA7, 0x6B, 0x56, 0x21, 0x44, 0x41,	/* a */
+		0x8F, 0xF3, 0xFF, 0x8C, 0x25, 0x70, 0xB8,
+		0x02, 0x17, 0xC0, 0x56, 0x10, 0x88, 0x4B, 0x63, 0xB9, 0xC6,	/* b */
+		0xC7, 0x29, 0x16, 0x78, 0xF9, 0xD3, 0x41,
+		0x00, 0x81, 0xBA, 0xF9, 0x1F, 0xDF, 0x98, 0x33, 0xC4, 0x0F,	/* x */
+		0x9C, 0x18, 0x13, 0x43, 0x63, 0x83, 0x99,
+		0x07, 0x8C, 0x6E, 0x7E, 0xA3, 0x8C, 0x00, 0x1F, 0x73, 0xC8,	/* y */
+		0x13, 0x4B, 0x1B, 0x4E, 0xF9, 0xE1, 0x50,
+		0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31,	/* order */
+		0x23, 0x95, 0x3A, 0x94, 0x64, 0xB5, 0x4D
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 17 * 6];
+}
+ _EC_SECG_CHAR2_131R2 = {
+	{
+		NID_X9_62_characteristic_two_field, 20, 17, 2
+	},
+	{
+		0x98, 0x5B, 0xD3, 0xAD, 0xBA, 0xD4, 0xD6, 0x96, 0xE6, 0x76,	/* seed */
+		0x87, 0x56, 0x15, 0x17, 0x5A, 0x21, 0xB4, 0x3A, 0x97, 0xE3,
+
+		0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0D,
+		0x03, 0xE5, 0xA8, 0x89, 0x19, 0xD7, 0xCA, 0xFC, 0xBF, 0x41,	/* a */
+		0x5F, 0x07, 0xC2, 0x17, 0x65, 0x73, 0xB2,
+		0x04, 0xB8, 0x26, 0x6A, 0x46, 0xC5, 0x56, 0x57, 0xAC, 0x73,	/* b */
+		0x4C, 0xE3, 0x8F, 0x01, 0x8F, 0x21, 0x92,
+		0x03, 0x56, 0xDC, 0xD8, 0xF2, 0xF9, 0x50, 0x31, 0xAD, 0x65,	/* x */
+		0x2D, 0x23, 0x95, 0x1B, 0xB3, 0x66, 0xA8,
+		0x06, 0x48, 0xF0, 0x6D, 0x86, 0x79, 0x40, 0xA5, 0x36, 0x6D,	/* y */
+		0x9E, 0x26, 0x5D, 0xE9, 0xEB, 0x24, 0x0F,
+		0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x69,	/* order */
+		0x54, 0xA2, 0x33, 0x04, 0x9B, 0xA9, 0x8F
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 21 * 6];
+}
+ _EC_NIST_CHAR2_163K = {
+	{
+		NID_X9_62_characteristic_two_field, 0, 21, 2
+	},
+	{			/* no seed */
+		0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0xC9,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x01,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* b */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x01,
+		0x02, 0xFE, 0x13, 0xC0, 0x53, 0x7B, 0xBC, 0x11, 0xAC, 0xAA,	/* x */
+		0x07, 0xD7, 0x93, 0xDE, 0x4E, 0x6D, 0x5E, 0x5C, 0x94, 0xEE,
+		0xE8,
+		0x02, 0x89, 0x07, 0x0F, 0xB0, 0x5D, 0x38, 0xFF, 0x58, 0x32,	/* y */
+		0x1F, 0x2E, 0x80, 0x05, 0x36, 0xD5, 0x38, 0xCC, 0xDA, 0xA3,
+		0xD9,
+		0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x02, 0x01, 0x08, 0xA2, 0xE0, 0xCC, 0x0D, 0x99, 0xF8, 0xA5,
+		0xEF
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 21 * 6];
+}
+ _EC_SECG_CHAR2_163R1 = {
+	{
+		NID_X9_62_characteristic_two_field, 0, 21, 2
+	},
+	{			/* no seed */
+		0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0xC9,
+		0x07, 0xB6, 0x88, 0x2C, 0xAA, 0xEF, 0xA8, 0x4F, 0x95, 0x54,	/* a */
+		0xFF, 0x84, 0x28, 0xBD, 0x88, 0xE2, 0x46, 0xD2, 0x78, 0x2A,
+		0xE2,
+		0x07, 0x13, 0x61, 0x2D, 0xCD, 0xDC, 0xB4, 0x0A, 0xAB, 0x94,	/* b */
+		0x6B, 0xDA, 0x29, 0xCA, 0x91, 0xF7, 0x3A, 0xF9, 0x58, 0xAF,
+		0xD9,
+		0x03, 0x69, 0x97, 0x96, 0x97, 0xAB, 0x43, 0x89, 0x77, 0x89,	/* x */
+		0x56, 0x67, 0x89, 0x56, 0x7F, 0x78, 0x7A, 0x78, 0x76, 0xA6,
+		0x54,
+		0x00, 0x43, 0x5E, 0xDB, 0x42, 0xEF, 0xAF, 0xB2, 0x98, 0x9D,	/* y */
+		0x51, 0xFE, 0xFC, 0xE3, 0xC8, 0x09, 0x88, 0xF4, 0x1F, 0xF8,
+		0x83,
+		0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFF, 0x48, 0xAA, 0xB6, 0x89, 0xC2, 0x9C, 0xA7, 0x10, 0x27,
+		0x9B
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 21 * 6];
+}
+ _EC_NIST_CHAR2_163B = {
+	{
+		NID_X9_62_characteristic_two_field, 0, 21, 2
+	},
+	{			/* no seed */
+		0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0xC9,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x01,
+		0x02, 0x0A, 0x60, 0x19, 0x07, 0xB8, 0xC9, 0x53, 0xCA, 0x14,	/* b */
+		0x81, 0xEB, 0x10, 0x51, 0x2F, 0x78, 0x74, 0x4A, 0x32, 0x05,
+		0xFD,
+		0x03, 0xF0, 0xEB, 0xA1, 0x62, 0x86, 0xA2, 0xD5, 0x7E, 0xA0,	/* x */
+		0x99, 0x11, 0x68, 0xD4, 0x99, 0x46, 0x37, 0xE8, 0x34, 0x3E,
+		0x36,
+		0x00, 0xD5, 0x1F, 0xBC, 0x6C, 0x71, 0xA0, 0x09, 0x4F, 0xA2,	/* y */
+		0xCD, 0xD5, 0x45, 0xB1, 0x1C, 0x5C, 0x0C, 0x79, 0x73, 0x24,
+		0xF1,
+		0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x02, 0x92, 0xFE, 0x77, 0xE7, 0x0C, 0x12, 0xA4, 0x23, 0x4C,
+		0x33
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 25 * 6];
+}
+ _EC_SECG_CHAR2_193R1 = {
+	{
+		NID_X9_62_characteristic_two_field, 20, 25, 2
+	},
+	{
+		0x10, 0x3F, 0xAE, 0xC7, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75,	/* seed */
+		0x61, 0x51, 0x75, 0x77, 0x7F, 0xC5, 0xB1, 0x91, 0xEF, 0x30,
+
+		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x80, 0x01,
+		0x00, 0x17, 0x85, 0x8F, 0xEB, 0x7A, 0x98, 0x97, 0x51, 0x69,	/* a */
+		0xE1, 0x71, 0xF7, 0x7B, 0x40, 0x87, 0xDE, 0x09, 0x8A, 0xC8,
+		0xA9, 0x11, 0xDF, 0x7B, 0x01,
+		0x00, 0xFD, 0xFB, 0x49, 0xBF, 0xE6, 0xC3, 0xA8, 0x9F, 0xAC,	/* b */
+		0xAD, 0xAA, 0x7A, 0x1E, 0x5B, 0xBC, 0x7C, 0xC1, 0xC2, 0xE5,
+		0xD8, 0x31, 0x47, 0x88, 0x14,
+		0x01, 0xF4, 0x81, 0xBC, 0x5F, 0x0F, 0xF8, 0x4A, 0x74, 0xAD,	/* x */
+		0x6C, 0xDF, 0x6F, 0xDE, 0xF4, 0xBF, 0x61, 0x79, 0x62, 0x53,
+		0x72, 0xD8, 0xC0, 0xC5, 0xE1,
+		0x00, 0x25, 0xE3, 0x99, 0xF2, 0x90, 0x37, 0x12, 0xCC, 0xF3,	/* y */
+		0xEA, 0x9E, 0x3A, 0x1A, 0xD1, 0x7F, 0xB0, 0xB3, 0x20, 0x1B,
+		0x6A, 0xF7, 0xCE, 0x1B, 0x05,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x00, 0x00, 0x00, 0xC7, 0xF3, 0x4A, 0x77, 0x8F, 0x44, 0x3A,
+		0xCC, 0x92, 0x0E, 0xBA, 0x49
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 25 * 6];
+}
+ _EC_SECG_CHAR2_193R2 = {
+	{
+		NID_X9_62_characteristic_two_field, 20, 25, 2
+	},
+	{
+		0x10, 0xB7, 0xB4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15,	/* seed */
+		0x17, 0x51, 0x37, 0xC8, 0xA1, 0x6F, 0xD0, 0xDA, 0x22, 0x11,
+
+		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x80, 0x01,
+		0x01, 0x63, 0xF3, 0x5A, 0x51, 0x37, 0xC2, 0xCE, 0x3E, 0xA6,	/* a */
+		0xED, 0x86, 0x67, 0x19, 0x0B, 0x0B, 0xC4, 0x3E, 0xCD, 0x69,
+		0x97, 0x77, 0x02, 0x70, 0x9B,
+		0x00, 0xC9, 0xBB, 0x9E, 0x89, 0x27, 0xD4, 0xD6, 0x4C, 0x37,	/* b */
+		0x7E, 0x2A, 0xB2, 0x85, 0x6A, 0x5B, 0x16, 0xE3, 0xEF, 0xB7,
+		0xF6, 0x1D, 0x43, 0x16, 0xAE,
+		0x00, 0xD9, 0xB6, 0x7D, 0x19, 0x2E, 0x03, 0x67, 0xC8, 0x03,	/* x */
+		0xF3, 0x9E, 0x1A, 0x7E, 0x82, 0xCA, 0x14, 0xA6, 0x51, 0x35,
+		0x0A, 0xAE, 0x61, 0x7E, 0x8F,
+		0x01, 0xCE, 0x94, 0x33, 0x56, 0x07, 0xC3, 0x04, 0xAC, 0x29,	/* y */
+		0xE7, 0xDE, 0xFB, 0xD9, 0xCA, 0x01, 0xF5, 0x96, 0xF9, 0x27,
+		0x22, 0x4C, 0xDE, 0xCF, 0x6C,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x00, 0x00, 0x01, 0x5A, 0xAB, 0x56, 0x1B, 0x00, 0x54, 0x13,
+		0xCC, 0xD4, 0xEE, 0x99, 0xD5
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 30 * 6];
+}
+ _EC_NIST_CHAR2_233K = {
+	{
+		NID_X9_62_characteristic_two_field, 0, 30, 4
+	},
+	{			/* no seed */
+		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* b */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+
+		0x01, 0x72, 0x32, 0xBA, 0x85, 0x3A, 0x7E, 0x73, 0x1A, 0xF1,	/* x */
+		0x29, 0xF2, 0x2F, 0xF4, 0x14, 0x95, 0x63, 0xA4, 0x19, 0xC2,
+		0x6B, 0xF5, 0x0A, 0x4C, 0x9D, 0x6E, 0xEF, 0xAD, 0x61, 0x26,
+
+		0x01, 0xDB, 0x53, 0x7D, 0xEC, 0xE8, 0x19, 0xB7, 0xF7, 0x0F,	/* y */
+		0x55, 0x5A, 0x67, 0xC4, 0x27, 0xA8, 0xCD, 0x9B, 0xF1, 0x8A,
+		0xEB, 0x9B, 0x56, 0xE0, 0xC1, 0x10, 0x56, 0xFA, 0xE6, 0xA3,
+
+		0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x9D, 0x5B, 0xB9, 0x15,
+		0xBC, 0xD4, 0x6E, 0xFB, 0x1A, 0xD5, 0xF1, 0x73, 0xAB, 0xDF
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 30 * 6];
+}
+ _EC_NIST_CHAR2_233B = {
+	{
+		NID_X9_62_characteristic_two_field, 20, 30, 2
+	},
+	{
+		0x74, 0xD5, 0x9F, 0xF0, 0x7F, 0x6B, 0x41, 0x3D, 0x0E, 0xA1,	/* seed */
+		0x4B, 0x34, 0x4B, 0x20, 0xA2, 0xDB, 0x04, 0x9B, 0x50, 0xC3,
+
+		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+
+		0x00, 0x66, 0x64, 0x7E, 0xDE, 0x6C, 0x33, 0x2C, 0x7F, 0x8C,	/* b */
+		0x09, 0x23, 0xBB, 0x58, 0x21, 0x3B, 0x33, 0x3B, 0x20, 0xE9,
+		0xCE, 0x42, 0x81, 0xFE, 0x11, 0x5F, 0x7D, 0x8F, 0x90, 0xAD,
+
+		0x00, 0xFA, 0xC9, 0xDF, 0xCB, 0xAC, 0x83, 0x13, 0xBB, 0x21,	/* x */
+		0x39, 0xF1, 0xBB, 0x75, 0x5F, 0xEF, 0x65, 0xBC, 0x39, 0x1F,
+		0x8B, 0x36, 0xF8, 0xF8, 0xEB, 0x73, 0x71, 0xFD, 0x55, 0x8B,
+
+		0x01, 0x00, 0x6A, 0x08, 0xA4, 0x19, 0x03, 0x35, 0x06, 0x78,	/* y */
+		0xE5, 0x85, 0x28, 0xBE, 0xBF, 0x8A, 0x0B, 0xEF, 0xF8, 0x67,
+		0xA7, 0xCA, 0x36, 0x71, 0x6F, 0x7E, 0x01, 0xF8, 0x10, 0x52,
+
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xE9, 0x74, 0xE7, 0x2F,
+		0x8A, 0x69, 0x22, 0x03, 0x1D, 0x26, 0x03, 0xCF, 0xE0, 0xD7
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 30 * 6];
+}
+ _EC_SECG_CHAR2_239K1 = {
+	{
+		NID_X9_62_characteristic_two_field, 0, 30, 4
+	},
+	{			/* no seed */
+		0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x40, 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,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* b */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+
+		0x29, 0xA0, 0xB6, 0xA8, 0x87, 0xA9, 0x83, 0xE9, 0x73, 0x09,	/* x */
+		0x88, 0xA6, 0x87, 0x27, 0xA8, 0xB2, 0xD1, 0x26, 0xC4, 0x4C,
+		0xC2, 0xCC, 0x7B, 0x2A, 0x65, 0x55, 0x19, 0x30, 0x35, 0xDC,
+
+		0x76, 0x31, 0x08, 0x04, 0xF1, 0x2E, 0x54, 0x9B, 0xDB, 0x01,	/* y */
+		0x1C, 0x10, 0x30, 0x89, 0xE7, 0x35, 0x10, 0xAC, 0xB2, 0x75,
+		0xFC, 0x31, 0x2A, 0x5D, 0xC6, 0xB7, 0x65, 0x53, 0xF0, 0xCA,
+
+		0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x5A, 0x79, 0xFE, 0xC6, 0x7C,
+		0xB6, 0xE9, 0x1F, 0x1C, 0x1D, 0xA8, 0x00, 0xE4, 0x78, 0xA5
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 36 * 6];
+}
+ _EC_NIST_CHAR2_283K = {
+	{
+		NID_X9_62_characteristic_two_field, 0, 36, 4
+	},
+	{			/* no seed */
+		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, 0x00, 0x10, 0xA1,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* b */
+		0x00, 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,
+		0x05, 0x03, 0x21, 0x3F, 0x78, 0xCA, 0x44, 0x88, 0x3F, 0x1A,	/* x */
+		0x3B, 0x81, 0x62, 0xF1, 0x88, 0xE5, 0x53, 0xCD, 0x26, 0x5F,
+		0x23, 0xC1, 0x56, 0x7A, 0x16, 0x87, 0x69, 0x13, 0xB0, 0xC2,
+		0xAC, 0x24, 0x58, 0x49, 0x28, 0x36,
+		0x01, 0xCC, 0xDA, 0x38, 0x0F, 0x1C, 0x9E, 0x31, 0x8D, 0x90,	/* y */
+		0xF9, 0x5D, 0x07, 0xE5, 0x42, 0x6F, 0xE8, 0x7E, 0x45, 0xC0,
+		0xE8, 0x18, 0x46, 0x98, 0xE4, 0x59, 0x62, 0x36, 0x4E, 0x34,
+		0x11, 0x61, 0x77, 0xDD, 0x22, 0x59,
+		0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0xAE,
+		0x2E, 0xD0, 0x75, 0x77, 0x26, 0x5D, 0xFF, 0x7F, 0x94, 0x45,
+		0x1E, 0x06, 0x1E, 0x16, 0x3C, 0x61
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 36 * 6];
+}
+ _EC_NIST_CHAR2_283B = {
+	{
+		NID_X9_62_characteristic_two_field, 20, 36, 2
+	},
+	{
+		0x77, 0xE2, 0xB0, 0x73, 0x70, 0xEB, 0x0F, 0x83, 0x2A, 0x6D,	/* no seed */
+		0xD5, 0xB6, 0x2D, 0xFC, 0x88, 0xCD, 0x06, 0xBB, 0x84, 0xBE,
+
+		0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x10, 0xA1,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 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,
+		0x02, 0x7B, 0x68, 0x0A, 0xC8, 0xB8, 0x59, 0x6D, 0xA5, 0xA4,	/* b */
+		0xAF, 0x8A, 0x19, 0xA0, 0x30, 0x3F, 0xCA, 0x97, 0xFD, 0x76,
+		0x45, 0x30, 0x9F, 0xA2, 0xA5, 0x81, 0x48, 0x5A, 0xF6, 0x26,
+		0x3E, 0x31, 0x3B, 0x79, 0xA2, 0xF5,
+		0x05, 0xF9, 0x39, 0x25, 0x8D, 0xB7, 0xDD, 0x90, 0xE1, 0x93,	/* x */
+		0x4F, 0x8C, 0x70, 0xB0, 0xDF, 0xEC, 0x2E, 0xED, 0x25, 0xB8,
+		0x55, 0x7E, 0xAC, 0x9C, 0x80, 0xE2, 0xE1, 0x98, 0xF8, 0xCD,
+		0xBE, 0xCD, 0x86, 0xB1, 0x20, 0x53,
+		0x03, 0x67, 0x68, 0x54, 0xFE, 0x24, 0x14, 0x1C, 0xB9, 0x8F,	/* y */
+		0xE6, 0xD4, 0xB2, 0x0D, 0x02, 0xB4, 0x51, 0x6F, 0xF7, 0x02,
+		0x35, 0x0E, 0xDD, 0xB0, 0x82, 0x67, 0x79, 0xC8, 0x13, 0xF0,
+		0xDF, 0x45, 0xBE, 0x81, 0x12, 0xF4,
+		0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x90,
+		0x39, 0x96, 0x60, 0xFC, 0x93, 0x8A, 0x90, 0x16, 0x5B, 0x04,
+		0x2A, 0x7C, 0xEF, 0xAD, 0xB3, 0x07
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 52 * 6];
+}
+ _EC_NIST_CHAR2_409K = {
+	{
+		NID_X9_62_characteristic_two_field, 0, 52, 4
+	},
+	{			/* no seed */
+		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x01,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* b */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x60, 0xF0, 0x5F, 0x65, 0x8F, 0x49, 0xC1, 0xAD, 0x3A,	/* x */
+		0xB1, 0x89, 0x0F, 0x71, 0x84, 0x21, 0x0E, 0xFD, 0x09, 0x87,
+		0xE3, 0x07, 0xC8, 0x4C, 0x27, 0xAC, 0xCF, 0xB8, 0xF9, 0xF6,
+		0x7C, 0xC2, 0xC4, 0x60, 0x18, 0x9E, 0xB5, 0xAA, 0xAA, 0x62,
+		0xEE, 0x22, 0x2E, 0xB1, 0xB3, 0x55, 0x40, 0xCF, 0xE9, 0x02,
+		0x37, 0x46,
+		0x01, 0xE3, 0x69, 0x05, 0x0B, 0x7C, 0x4E, 0x42, 0xAC, 0xBA,	/* y */
+		0x1D, 0xAC, 0xBF, 0x04, 0x29, 0x9C, 0x34, 0x60, 0x78, 0x2F,
+		0x91, 0x8E, 0xA4, 0x27, 0xE6, 0x32, 0x51, 0x65, 0xE9, 0xEA,
+		0x10, 0xE3, 0xDA, 0x5F, 0x6C, 0x42, 0xE9, 0xC5, 0x52, 0x15,
+		0xAA, 0x9C, 0xA2, 0x7A, 0x58, 0x63, 0xEC, 0x48, 0xD8, 0xE0,
+		0x28, 0x6B,
+		0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x5F, 0x83, 0xB2,
+		0xD4, 0xEA, 0x20, 0x40, 0x0E, 0xC4, 0x55, 0x7D, 0x5E, 0xD3,
+		0xE3, 0xE7, 0xCA, 0x5B, 0x4B, 0x5C, 0x83, 0xB8, 0xE0, 0x1E,
+		0x5F, 0xCF
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 52 * 6];
+}
+ _EC_NIST_CHAR2_409B = {
+	{
+		NID_X9_62_characteristic_two_field, 20, 52, 2
+	},
+	{
+		0x40, 0x99, 0xB5, 0xA4, 0x57, 0xF9, 0xD6, 0x9F, 0x79, 0x21,	/* seed */
+		0x3D, 0x09, 0x4C, 0x4B, 0xCD, 0x4D, 0x42, 0x62, 0x21, 0x0B,
+
+		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x01,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x21, 0xA5, 0xC2, 0xC8, 0xEE, 0x9F, 0xEB, 0x5C, 0x4B,	/* b */
+		0x9A, 0x75, 0x3B, 0x7B, 0x47, 0x6B, 0x7F, 0xD6, 0x42, 0x2E,
+		0xF1, 0xF3, 0xDD, 0x67, 0x47, 0x61, 0xFA, 0x99, 0xD6, 0xAC,
+		0x27, 0xC8, 0xA9, 0xA1, 0x97, 0xB2, 0x72, 0x82, 0x2F, 0x6C,
+		0xD5, 0x7A, 0x55, 0xAA, 0x4F, 0x50, 0xAE, 0x31, 0x7B, 0x13,
+		0x54, 0x5F,
+		0x01, 0x5D, 0x48, 0x60, 0xD0, 0x88, 0xDD, 0xB3, 0x49, 0x6B,	/* x */
+		0x0C, 0x60, 0x64, 0x75, 0x62, 0x60, 0x44, 0x1C, 0xDE, 0x4A,
+		0xF1, 0x77, 0x1D, 0x4D, 0xB0, 0x1F, 0xFE, 0x5B, 0x34, 0xE5,
+		0x97, 0x03, 0xDC, 0x25, 0x5A, 0x86, 0x8A, 0x11, 0x80, 0x51,
+		0x56, 0x03, 0xAE, 0xAB, 0x60, 0x79, 0x4E, 0x54, 0xBB, 0x79,
+		0x96, 0xA7,
+		0x00, 0x61, 0xB1, 0xCF, 0xAB, 0x6B, 0xE5, 0xF3, 0x2B, 0xBF,	/* y */
+		0xA7, 0x83, 0x24, 0xED, 0x10, 0x6A, 0x76, 0x36, 0xB9, 0xC5,
+		0xA7, 0xBD, 0x19, 0x8D, 0x01, 0x58, 0xAA, 0x4F, 0x54, 0x88,
+		0xD0, 0x8F, 0x38, 0x51, 0x4F, 0x1F, 0xDF, 0x4B, 0x4F, 0x40,
+		0xD2, 0x18, 0x1B, 0x36, 0x81, 0xC3, 0x64, 0xBA, 0x02, 0x73,
+		0xC7, 0x06,
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE2, 0xAA, 0xD6,
+		0xA6, 0x12, 0xF3, 0x33, 0x07, 0xBE, 0x5F, 0xA4, 0x7C, 0x3C,
+		0x9E, 0x05, 0x2F, 0x83, 0x81, 0x64, 0xCD, 0x37, 0xD9, 0xA2,
+		0x11, 0x73
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 72 * 6];
+}
+ _EC_NIST_CHAR2_571K = {
+	{
+		NID_X9_62_characteristic_two_field, 0, 72, 4
+	},
+	{			/* no seed */
+		0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x04, 0x25,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* b */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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,
+		0x02, 0x6E, 0xB7, 0xA8, 0x59, 0x92, 0x3F, 0xBC, 0x82, 0x18,	/* x */
+		0x96, 0x31, 0xF8, 0x10, 0x3F, 0xE4, 0xAC, 0x9C, 0xA2, 0x97,
+		0x00, 0x12, 0xD5, 0xD4, 0x60, 0x24, 0x80, 0x48, 0x01, 0x84,
+		0x1C, 0xA4, 0x43, 0x70, 0x95, 0x84, 0x93, 0xB2, 0x05, 0xE6,
+		0x47, 0xDA, 0x30, 0x4D, 0xB4, 0xCE, 0xB0, 0x8C, 0xBB, 0xD1,
+		0xBA, 0x39, 0x49, 0x47, 0x76, 0xFB, 0x98, 0x8B, 0x47, 0x17,
+		0x4D, 0xCA, 0x88, 0xC7, 0xE2, 0x94, 0x52, 0x83, 0xA0, 0x1C,
+		0x89, 0x72,
+		0x03, 0x49, 0xDC, 0x80, 0x7F, 0x4F, 0xBF, 0x37, 0x4F, 0x4A,	/* y */
+		0xEA, 0xDE, 0x3B, 0xCA, 0x95, 0x31, 0x4D, 0xD5, 0x8C, 0xEC,
+		0x9F, 0x30, 0x7A, 0x54, 0xFF, 0xC6, 0x1E, 0xFC, 0x00, 0x6D,
+		0x8A, 0x2C, 0x9D, 0x49, 0x79, 0xC0, 0xAC, 0x44, 0xAE, 0xA7,
+		0x4F, 0xBE, 0xBB, 0xB9, 0xF7, 0x72, 0xAE, 0xDC, 0xB6, 0x20,
+		0xB0, 0x1A, 0x7B, 0xA7, 0xAF, 0x1B, 0x32, 0x04, 0x30, 0xC8,
+		0x59, 0x19, 0x84, 0xF6, 0x01, 0xCD, 0x4C, 0x14, 0x3E, 0xF1,
+		0xC7, 0xA3,
+		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x00, 0x00, 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, 0x18, 0x50, 0xE1,
+		0xF1, 0x9A, 0x63, 0xE4, 0xB3, 0x91, 0xA8, 0xDB, 0x91, 0x7F,
+		0x41, 0x38, 0xB6, 0x30, 0xD8, 0x4B, 0xE5, 0xD6, 0x39, 0x38,
+		0x1E, 0x91, 0xDE, 0xB4, 0x5C, 0xFE, 0x77, 0x8F, 0x63, 0x7C,
+		0x10, 0x01
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 72 * 6];
+}
+ _EC_NIST_CHAR2_571B = {
+	{
+		NID_X9_62_characteristic_two_field, 20, 72, 2
+	},
+	{
+		0x2A, 0xA0, 0x58, 0xF7, 0x3A, 0x0E, 0x33, 0xAB, 0x48, 0x6B,	/* seed */
+		0x0F, 0x61, 0x04, 0x10, 0xC5, 0x3A, 0x7F, 0x13, 0x23, 0x10,
+
+		0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x04, 0x25,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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,
+		0x02, 0xF4, 0x0E, 0x7E, 0x22, 0x21, 0xF2, 0x95, 0xDE, 0x29,	/* b */
+		0x71, 0x17, 0xB7, 0xF3, 0xD6, 0x2F, 0x5C, 0x6A, 0x97, 0xFF,
+		0xCB, 0x8C, 0xEF, 0xF1, 0xCD, 0x6B, 0xA8, 0xCE, 0x4A, 0x9A,
+		0x18, 0xAD, 0x84, 0xFF, 0xAB, 0xBD, 0x8E, 0xFA, 0x59, 0x33,
+		0x2B, 0xE7, 0xAD, 0x67, 0x56, 0xA6, 0x6E, 0x29, 0x4A, 0xFD,
+		0x18, 0x5A, 0x78, 0xFF, 0x12, 0xAA, 0x52, 0x0E, 0x4D, 0xE7,
+		0x39, 0xBA, 0xCA, 0x0C, 0x7F, 0xFE, 0xFF, 0x7F, 0x29, 0x55,
+		0x72, 0x7A,
+		0x03, 0x03, 0x00, 0x1D, 0x34, 0xB8, 0x56, 0x29, 0x6C, 0x16,	/* x */
+		0xC0, 0xD4, 0x0D, 0x3C, 0xD7, 0x75, 0x0A, 0x93, 0xD1, 0xD2,
+		0x95, 0x5F, 0xA8, 0x0A, 0xA5, 0xF4, 0x0F, 0xC8, 0xDB, 0x7B,
+		0x2A, 0xBD, 0xBD, 0xE5, 0x39, 0x50, 0xF4, 0xC0, 0xD2, 0x93,
+		0xCD, 0xD7, 0x11, 0xA3, 0x5B, 0x67, 0xFB, 0x14, 0x99, 0xAE,
+		0x60, 0x03, 0x86, 0x14, 0xF1, 0x39, 0x4A, 0xBF, 0xA3, 0xB4,
+		0xC8, 0x50, 0xD9, 0x27, 0xE1, 0xE7, 0x76, 0x9C, 0x8E, 0xEC,
+		0x2D, 0x19,
+		0x03, 0x7B, 0xF2, 0x73, 0x42, 0xDA, 0x63, 0x9B, 0x6D, 0xCC,	/* y */
+		0xFF, 0xFE, 0xB7, 0x3D, 0x69, 0xD7, 0x8C, 0x6C, 0x27, 0xA6,
+		0x00, 0x9C, 0xBB, 0xCA, 0x19, 0x80, 0xF8, 0x53, 0x39, 0x21,
+		0xE8, 0xA6, 0x84, 0x42, 0x3E, 0x43, 0xBA, 0xB0, 0x8A, 0x57,
+		0x62, 0x91, 0xAF, 0x8F, 0x46, 0x1B, 0xB2, 0xA8, 0xB3, 0x53,
+		0x1D, 0x2F, 0x04, 0x85, 0xC1, 0x9B, 0x16, 0xE2, 0xF1, 0x51,
+		0x6E, 0x23, 0xDD, 0x3C, 0x1A, 0x48, 0x27, 0xAF, 0x1B, 0x8A,
+		0xC1, 0x5B,
+		0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0x61, 0xCE, 0x18,
+		0xFF, 0x55, 0x98, 0x73, 0x08, 0x05, 0x9B, 0x18, 0x68, 0x23,
+		0x85, 0x1E, 0xC7, 0xDD, 0x9C, 0xA1, 0x16, 0x1D, 0xE9, 0x3D,
+		0x51, 0x74, 0xD6, 0x6E, 0x83, 0x82, 0xE9, 0xBB, 0x2F, 0xE8,
+		0x4E, 0x47
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 21 * 6];
+}
+ _EC_X9_62_CHAR2_163V1 = {
+	{
+		NID_X9_62_characteristic_two_field, 20, 21, 2
+	},
+	{
+		0xD2, 0xC0, 0xFB, 0x15, 0x76, 0x08, 0x60, 0xDE, 0xF1, 0xEE,
+		0xF4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x54,	/* seed */
+
+		0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+		0x07,
+		0x07, 0x25, 0x46, 0xB5, 0x43, 0x52, 0x34, 0xA4, 0x22, 0xE0,	/* a */
+		0x78, 0x96, 0x75, 0xF4, 0x32, 0xC8, 0x94, 0x35, 0xDE, 0x52,
+		0x42,
+		0x00, 0xC9, 0x51, 0x7D, 0x06, 0xD5, 0x24, 0x0D, 0x3C, 0xFF,	/* b */
+		0x38, 0xC7, 0x4B, 0x20, 0xB6, 0xCD, 0x4D, 0x6F, 0x9D, 0xD4,
+		0xD9,
+		0x07, 0xAF, 0x69, 0x98, 0x95, 0x46, 0x10, 0x3D, 0x79, 0x32,	/* x */
+		0x9F, 0xCC, 0x3D, 0x74, 0x88, 0x0F, 0x33, 0xBB, 0xE8, 0x03,
+		0xCB,
+		0x01, 0xEC, 0x23, 0x21, 0x1B, 0x59, 0x66, 0xAD, 0xEA, 0x1D,	/* y */
+		0x3F, 0x87, 0xF7, 0xEA, 0x58, 0x48, 0xAE, 0xF0, 0xB7, 0xCA,
+		0x9F,
+		0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x01, 0xE6, 0x0F, 0xC8, 0x82, 0x1C, 0xC7, 0x4D, 0xAE, 0xAF,
+		0xC1
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 21 * 6];
+}
+ _EC_X9_62_CHAR2_163V2 = {
+	{
+		NID_X9_62_characteristic_two_field, 20, 21, 2
+	},
+	{
+		0x53, 0x81, 0x4C, 0x05, 0x0D, 0x44, 0xD6, 0x96, 0xE6, 0x76,	/* seed */
+		0x87, 0x56, 0x15, 0x17, 0x58, 0x0C, 0xA4, 0xE2, 0x9F, 0xFD,
+
+		0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+		0x07,
+		0x01, 0x08, 0xB3, 0x9E, 0x77, 0xC4, 0xB1, 0x08, 0xBE, 0xD9,	/* a */
+		0x81, 0xED, 0x0E, 0x89, 0x0E, 0x11, 0x7C, 0x51, 0x1C, 0xF0,
+		0x72,
+		0x06, 0x67, 0xAC, 0xEB, 0x38, 0xAF, 0x4E, 0x48, 0x8C, 0x40,	/* b */
+		0x74, 0x33, 0xFF, 0xAE, 0x4F, 0x1C, 0x81, 0x16, 0x38, 0xDF,
+		0x20,
+		0x00, 0x24, 0x26, 0x6E, 0x4E, 0xB5, 0x10, 0x6D, 0x0A, 0x96,	/* x */
+		0x4D, 0x92, 0xC4, 0x86, 0x0E, 0x26, 0x71, 0xDB, 0x9B, 0x6C,
+		0xC5,
+		0x07, 0x9F, 0x68, 0x4D, 0xDF, 0x66, 0x84, 0xC5, 0xCD, 0x25,	/* y */
+		0x8B, 0x38, 0x90, 0x02, 0x1B, 0x23, 0x86, 0xDF, 0xD1, 0x9F,
+		0xC5,
+		0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFD, 0xF6, 0x4D, 0xE1, 0x15, 0x1A, 0xDB, 0xB7, 0x8F, 0x10,
+		0xA7
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 21 * 6];
+}
+ _EC_X9_62_CHAR2_163V3 = {
+	{
+		NID_X9_62_characteristic_two_field, 20, 21, 2
+	},
+	{
+		0x50, 0xCB, 0xF1, 0xD9, 0x5C, 0xA9, 0x4D, 0x69, 0x6E, 0x67,	/* seed */
+		0x68, 0x75, 0x61, 0x51, 0x75, 0xF1, 0x6A, 0x36, 0xA3, 0xB8,
+
+		0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+		0x07,
+		0x07, 0xA5, 0x26, 0xC6, 0x3D, 0x3E, 0x25, 0xA2, 0x56, 0xA0,	/* a */
+		0x07, 0x69, 0x9F, 0x54, 0x47, 0xE3, 0x2A, 0xE4, 0x56, 0xB5,
+		0x0E,
+		0x03, 0xF7, 0x06, 0x17, 0x98, 0xEB, 0x99, 0xE2, 0x38, 0xFD,	/* b */
+		0x6F, 0x1B, 0xF9, 0x5B, 0x48, 0xFE, 0xEB, 0x48, 0x54, 0x25,
+		0x2B,
+		0x02, 0xF9, 0xF8, 0x7B, 0x7C, 0x57, 0x4D, 0x0B, 0xDE, 0xCF,	/* x */
+		0x8A, 0x22, 0xE6, 0x52, 0x47, 0x75, 0xF9, 0x8C, 0xDE, 0xBD,
+		0xCB,
+		0x05, 0xB9, 0x35, 0x59, 0x0C, 0x15, 0x5E, 0x17, 0xEA, 0x48,	/* y */
+		0xEB, 0x3F, 0xF3, 0x71, 0x8B, 0x89, 0x3D, 0xF5, 0x9A, 0x05,
+		0xD0,
+		0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFE, 0x1A, 0xEE, 0x14, 0x0F, 0x11, 0x0A, 0xFF, 0x96, 0x13,
+		0x09
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 23 * 6];
+}
+ _EC_X9_62_CHAR2_176V1 = {
+	{
+		NID_X9_62_characteristic_two_field, 0, 23, 0xFF6E
+	},
+	{			/* no seed */
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+		0x00, 0x00, 0x07,
+		0x00, 0xE4, 0xE6, 0xDB, 0x29, 0x95, 0x06, 0x5C, 0x40, 0x7D,	/* a */
+		0x9D, 0x39, 0xB8, 0xD0, 0x96, 0x7B, 0x96, 0x70, 0x4B, 0xA8,
+		0xE9, 0xC9, 0x0B,
+		0x00, 0x5D, 0xDA, 0x47, 0x0A, 0xBE, 0x64, 0x14, 0xDE, 0x8E,	/* b */
+		0xC1, 0x33, 0xAE, 0x28, 0xE9, 0xBB, 0xD7, 0xFC, 0xEC, 0x0A,
+		0xE0, 0xFF, 0xF2,
+		0x00, 0x8D, 0x16, 0xC2, 0x86, 0x67, 0x98, 0xB6, 0x00, 0xF9,	/* x */
+		0xF0, 0x8B, 0xB4, 0xA8, 0xE8, 0x60, 0xF3, 0x29, 0x8C, 0xE0,
+		0x4A, 0x57, 0x98,
+		0x00, 0x6F, 0xA4, 0x53, 0x9C, 0x2D, 0xAD, 0xDD, 0xD6, 0xBA,	/* y */
+		0xB5, 0x16, 0x7D, 0x61, 0xB4, 0x36, 0xE1, 0xD9, 0x2B, 0xB1,
+		0x6A, 0x56, 0x2C,
+		0x00, 0x00, 0x01, 0x00, 0x92, 0x53, 0x73, 0x97, 0xEC, 0xA4,	/* order */
+		0xF6, 0x14, 0x57, 0x99, 0xD6, 0x2B, 0x0A, 0x19, 0xCE, 0x06,
+		0xFE, 0x26, 0xAD
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 24 * 6];
+}
+ _EC_X9_62_CHAR2_191V1 = {
+	{
+		NID_X9_62_characteristic_two_field, 20, 24, 2
+	},
+	{
+		0x4E, 0x13, 0xCA, 0x54, 0x27, 0x44, 0xD6, 0x96, 0xE6, 0x76,	/* seed */
+		0x87, 0x56, 0x15, 0x17, 0x55, 0x2F, 0x27, 0x9A, 0x8C, 0x84,
+
+		0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x02, 0x01,
+		0x28, 0x66, 0x53, 0x7B, 0x67, 0x67, 0x52, 0x63, 0x6A, 0x68,	/* a */
+		0xF5, 0x65, 0x54, 0xE1, 0x26, 0x40, 0x27, 0x6B, 0x64, 0x9E,
+		0xF7, 0x52, 0x62, 0x67,
+		0x2E, 0x45, 0xEF, 0x57, 0x1F, 0x00, 0x78, 0x6F, 0x67, 0xB0,	/* b */
+		0x08, 0x1B, 0x94, 0x95, 0xA3, 0xD9, 0x54, 0x62, 0xF5, 0xDE,
+		0x0A, 0xA1, 0x85, 0xEC,
+		0x36, 0xB3, 0xDA, 0xF8, 0xA2, 0x32, 0x06, 0xF9, 0xC4, 0xF2,	/* x */
+		0x99, 0xD7, 0xB2, 0x1A, 0x9C, 0x36, 0x91, 0x37, 0xF2, 0xC8,
+		0x4A, 0xE1, 0xAA, 0x0D,
+		0x76, 0x5B, 0xE7, 0x34, 0x33, 0xB3, 0xF9, 0x5E, 0x33, 0x29,	/* y */
+		0x32, 0xE7, 0x0E, 0xA2, 0x45, 0xCA, 0x24, 0x18, 0xEA, 0x0E,
+		0xF9, 0x80, 0x18, 0xFB,
+		0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x00, 0x00, 0x04, 0xA2, 0x0E, 0x90, 0xC3, 0x90, 0x67, 0xC8,
+		0x93, 0xBB, 0xB9, 0xA5
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 24 * 6];
+}
+ _EC_X9_62_CHAR2_191V2 = {
+	{
+		NID_X9_62_characteristic_two_field, 20, 24, 4
+	},
+	{
+		0x08, 0x71, 0xEF, 0x2F, 0xEF, 0x24, 0xD6, 0x96, 0xE6, 0x76,	/* seed */
+		0x87, 0x56, 0x15, 0x17, 0x58, 0xBE, 0xE0, 0xD9, 0x5C, 0x15,
+
+		0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x02, 0x01,
+		0x40, 0x10, 0x28, 0x77, 0x4D, 0x77, 0x77, 0xC7, 0xB7, 0x66,	/* a */
+		0x6D, 0x13, 0x66, 0xEA, 0x43, 0x20, 0x71, 0x27, 0x4F, 0x89,
+		0xFF, 0x01, 0xE7, 0x18,
+		0x06, 0x20, 0x04, 0x8D, 0x28, 0xBC, 0xBD, 0x03, 0xB6, 0x24,	/* b */
+		0x9C, 0x99, 0x18, 0x2B, 0x7C, 0x8C, 0xD1, 0x97, 0x00, 0xC3,
+		0x62, 0xC4, 0x6A, 0x01,
+		0x38, 0x09, 0xB2, 0xB7, 0xCC, 0x1B, 0x28, 0xCC, 0x5A, 0x87,	/* x */
+		0x92, 0x6A, 0xAD, 0x83, 0xFD, 0x28, 0x78, 0x9E, 0x81, 0xE2,
+		0xC9, 0xE3, 0xBF, 0x10,
+		0x17, 0x43, 0x43, 0x86, 0x62, 0x6D, 0x14, 0xF3, 0xDB, 0xF0,	/* y */
+		0x17, 0x60, 0xD9, 0x21, 0x3A, 0x3E, 0x1C, 0xF3, 0x7A, 0xEC,
+		0x43, 0x7D, 0x66, 0x8A,
+		0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x00, 0x00, 0x50, 0x50, 0x8C, 0xB8, 0x9F, 0x65, 0x28, 0x24,
+		0xE0, 0x6B, 0x81, 0x73
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 24 * 6];
+}
+ _EC_X9_62_CHAR2_191V3 = {
+	{
+		NID_X9_62_characteristic_two_field, 20, 24, 6
+	},
+	{
+		0xE0, 0x53, 0x51, 0x2D, 0xC6, 0x84, 0xD6, 0x96, 0xE6, 0x76,	/* seed */
+		0x87, 0x56, 0x15, 0x17, 0x50, 0x67, 0xAE, 0x78, 0x6D, 0x1F,
+
+		0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x02, 0x01,
+		0x6C, 0x01, 0x07, 0x47, 0x56, 0x09, 0x91, 0x22, 0x22, 0x10,	/* a */
+		0x56, 0x91, 0x1C, 0x77, 0xD7, 0x7E, 0x77, 0xA7, 0x77, 0xE7,
+		0xE7, 0xE7, 0x7F, 0xCB,
+		0x71, 0xFE, 0x1A, 0xF9, 0x26, 0xCF, 0x84, 0x79, 0x89, 0xEF,	/* b */
+		0xEF, 0x8D, 0xB4, 0x59, 0xF6, 0x63, 0x94, 0xD9, 0x0F, 0x32,
+		0xAD, 0x3F, 0x15, 0xE8,
+		0x37, 0x5D, 0x4C, 0xE2, 0x4F, 0xDE, 0x43, 0x44, 0x89, 0xDE,	/* x */
+		0x87, 0x46, 0xE7, 0x17, 0x86, 0x01, 0x50, 0x09, 0xE6, 0x6E,
+		0x38, 0xA9, 0x26, 0xDD,
+		0x54, 0x5A, 0x39, 0x17, 0x61, 0x96, 0x57, 0x5D, 0x98, 0x59,	/* y */
+		0x99, 0x36, 0x6E, 0x6A, 0xD3, 0x4C, 0xE0, 0xA7, 0x7C, 0xD7,
+		0x12, 0x7B, 0x06, 0xBE,
+		0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,	/* order */
+		0x55, 0x55, 0x61, 0x0C, 0x0B, 0x19, 0x68, 0x12, 0xBF, 0xB6,
+		0x28, 0x8A, 0x3E, 0xA3
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 27 * 6];
+}
+ _EC_X9_62_CHAR2_208W1 = {
+	{
+		NID_X9_62_characteristic_two_field, 0, 27, 0xFE48
+	},
+	{			/* no seed */
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0xC8, 0x61, 0x9E, 0xD4, 0x5A, 0x62, 0xE6, 0x21, 0x2E,	/* b */
+		0x11, 0x60, 0x34, 0x9E, 0x2B, 0xFA, 0x84, 0x44, 0x39, 0xFA,
+		0xFC, 0x2A, 0x3F, 0xD1, 0x63, 0x8F, 0x9E,
+		0x00, 0x89, 0xFD, 0xFB, 0xE4, 0xAB, 0xE1, 0x93, 0xDF, 0x95,	/* x */
+		0x59, 0xEC, 0xF0, 0x7A, 0xC0, 0xCE, 0x78, 0x55, 0x4E, 0x27,
+		0x84, 0xEB, 0x8C, 0x1E, 0xD1, 0xA5, 0x7A,
+		0x00, 0x0F, 0x55, 0xB5, 0x1A, 0x06, 0xE7, 0x8E, 0x9A, 0xC3,	/* y */
+		0x8A, 0x03, 0x5F, 0xF5, 0x20, 0xD8, 0xB0, 0x17, 0x81, 0xBE,
+		0xB1, 0xA6, 0xBB, 0x08, 0x61, 0x7D, 0xE3,
+		0x00, 0x00, 0x01, 0x01, 0xBA, 0xF9, 0x5C, 0x97, 0x23, 0xC5,	/* order */
+		0x7B, 0x6C, 0x21, 0xDA, 0x2E, 0xFF, 0x2D, 0x5E, 0xD5, 0x88,
+		0xBD, 0xD5, 0x71, 0x7E, 0x21, 0x2F, 0x9D
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 30 * 6];
+}
+ _EC_X9_62_CHAR2_239V1 = {
+	{
+		NID_X9_62_characteristic_two_field, 20, 30, 4
+	},
+	{
+		0xD3, 0x4B, 0x9A, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61,	/* seed */
+		0x51, 0x75, 0xCA, 0x71, 0xB9, 0x20, 0xBF, 0xEF, 0xB0, 0x5D,
+
+		0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
+
+		0x32, 0x01, 0x08, 0x57, 0x07, 0x7C, 0x54, 0x31, 0x12, 0x3A,	/* a */
+		0x46, 0xB8, 0x08, 0x90, 0x67, 0x56, 0xF5, 0x43, 0x42, 0x3E,
+		0x8D, 0x27, 0x87, 0x75, 0x78, 0x12, 0x57, 0x78, 0xAC, 0x76,
+
+		0x79, 0x04, 0x08, 0xF2, 0xEE, 0xDA, 0xF3, 0x92, 0xB0, 0x12,	/* b */
+		0xED, 0xEF, 0xB3, 0x39, 0x2F, 0x30, 0xF4, 0x32, 0x7C, 0x0C,
+		0xA3, 0xF3, 0x1F, 0xC3, 0x83, 0xC4, 0x22, 0xAA, 0x8C, 0x16,
+
+		0x57, 0x92, 0x70, 0x98, 0xFA, 0x93, 0x2E, 0x7C, 0x0A, 0x96,	/* x */
+		0xD3, 0xFD, 0x5B, 0x70, 0x6E, 0xF7, 0xE5, 0xF5, 0xC1, 0x56,
+		0xE1, 0x6B, 0x7E, 0x7C, 0x86, 0x03, 0x85, 0x52, 0xE9, 0x1D,
+
+		0x61, 0xD8, 0xEE, 0x50, 0x77, 0xC3, 0x3F, 0xEC, 0xF6, 0xF1,	/* y */
+		0xA1, 0x6B, 0x26, 0x8D, 0xE4, 0x69, 0xC3, 0xC7, 0x74, 0x4E,
+		0xA9, 0xA9, 0x71, 0x64, 0x9F, 0xC7, 0xA9, 0x61, 0x63, 0x05,
+
+		0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x4D, 0x42, 0xFF, 0xE1,
+		0x49, 0x2A, 0x49, 0x93, 0xF1, 0xCA, 0xD6, 0x66, 0xE4, 0x47
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 30 * 6];
+}
+ _EC_X9_62_CHAR2_239V2 = {
+	{
+		NID_X9_62_characteristic_two_field, 20, 30, 6
+	},
+	{
+		0x2A, 0xA6, 0x98, 0x2F, 0xDF, 0xA4, 0xD6, 0x96, 0xE6, 0x76,	/* seed */
+		0x87, 0x56, 0x15, 0x17, 0x5D, 0x26, 0x67, 0x27, 0x27, 0x7D,
+
+		0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
+
+		0x42, 0x30, 0x01, 0x77, 0x57, 0xA7, 0x67, 0xFA, 0xE4, 0x23,	/* a */
+		0x98, 0x56, 0x9B, 0x74, 0x63, 0x25, 0xD4, 0x53, 0x13, 0xAF,
+		0x07, 0x66, 0x26, 0x64, 0x79, 0xB7, 0x56, 0x54, 0xE6, 0x5F,
+
+		0x50, 0x37, 0xEA, 0x65, 0x41, 0x96, 0xCF, 0xF0, 0xCD, 0x82,	/* b */
+		0xB2, 0xC1, 0x4A, 0x2F, 0xCF, 0x2E, 0x3F, 0xF8, 0x77, 0x52,
+		0x85, 0xB5, 0x45, 0x72, 0x2F, 0x03, 0xEA, 0xCD, 0xB7, 0x4B,
+
+		0x28, 0xF9, 0xD0, 0x4E, 0x90, 0x00, 0x69, 0xC8, 0xDC, 0x47,	/* x */
+		0xA0, 0x85, 0x34, 0xFE, 0x76, 0xD2, 0xB9, 0x00, 0xB7, 0xD7,
+		0xEF, 0x31, 0xF5, 0x70, 0x9F, 0x20, 0x0C, 0x4C, 0xA2, 0x05,
+
+		0x56, 0x67, 0x33, 0x4C, 0x45, 0xAF, 0xF3, 0xB5, 0xA0, 0x3B,	/* y */
+		0xAD, 0x9D, 0xD7, 0x5E, 0x2C, 0x71, 0xA9, 0x93, 0x62, 0x56,
+		0x7D, 0x54, 0x53, 0xF7, 0xFA, 0x6E, 0x22, 0x7E, 0xC8, 0x33,
+
+		0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,	/* order */
+		0x55, 0x55, 0x55, 0x55, 0x55, 0x3C, 0x6F, 0x28, 0x85, 0x25,
+		0x9C, 0x31, 0xE3, 0xFC, 0xDF, 0x15, 0x46, 0x24, 0x52, 0x2D
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 30 * 6];
+}
+ _EC_X9_62_CHAR2_239V3 = {
+	{
+		NID_X9_62_characteristic_two_field, 20, 30, 0xA
+	},
+	{
+		0x9E, 0x07, 0x6F, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61,	/* seed */
+		0x51, 0x75, 0xE1, 0x1E, 0x9F, 0xDD, 0x77, 0xF9, 0x20, 0x41,
+
+		0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
+
+		0x01, 0x23, 0x87, 0x74, 0x66, 0x6A, 0x67, 0x76, 0x6D, 0x66,	/* a */
+		0x76, 0xF7, 0x78, 0xE6, 0x76, 0xB6, 0x69, 0x99, 0x17, 0x66,
+		0x66, 0xE6, 0x87, 0x66, 0x6D, 0x87, 0x66, 0xC6, 0x6A, 0x9F,
+
+		0x6A, 0x94, 0x19, 0x77, 0xBA, 0x9F, 0x6A, 0x43, 0x51, 0x99,	/* b */
+		0xAC, 0xFC, 0x51, 0x06, 0x7E, 0xD5, 0x87, 0xF5, 0x19, 0xC5,
+		0xEC, 0xB5, 0x41, 0xB8, 0xE4, 0x41, 0x11, 0xDE, 0x1D, 0x40,
+
+		0x70, 0xF6, 0xE9, 0xD0, 0x4D, 0x28, 0x9C, 0x4E, 0x89, 0x91,	/* x */
+		0x3C, 0xE3, 0x53, 0x0B, 0xFD, 0xE9, 0x03, 0x97, 0x7D, 0x42,
+		0xB1, 0x46, 0xD5, 0x39, 0xBF, 0x1B, 0xDE, 0x4E, 0x9C, 0x92,
+
+		0x2E, 0x5A, 0x0E, 0xAF, 0x6E, 0x5E, 0x13, 0x05, 0xB9, 0x00,	/* y */
+		0x4D, 0xCE, 0x5C, 0x0E, 0xD7, 0xFE, 0x59, 0xA3, 0x56, 0x08,
+		0xF3, 0x38, 0x37, 0xC8, 0x16, 0xD8, 0x0B, 0x79, 0xF4, 0x61,
+
+		0x0C, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,	/* order */
+		0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xAC, 0x49, 0x12, 0xD2, 0xD9,
+		0xDF, 0x90, 0x3E, 0xF9, 0x88, 0x8B, 0x8A, 0x0E, 0x4C, 0xFF
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 35 * 6];
+}
+ _EC_X9_62_CHAR2_272W1 = {
+	{
+		NID_X9_62_characteristic_two_field, 0, 35, 0xFF06
+	},
+	{			/* no seed */
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x0B,
+		0x00, 0x91, 0xA0, 0x91, 0xF0, 0x3B, 0x5F, 0xBA, 0x4A, 0xB2,	/* a */
+		0xCC, 0xF4, 0x9C, 0x4E, 0xDD, 0x22, 0x0F, 0xB0, 0x28, 0x71,
+		0x2D, 0x42, 0xBE, 0x75, 0x2B, 0x2C, 0x40, 0x09, 0x4D, 0xBA,
+		0xCD, 0xB5, 0x86, 0xFB, 0x20,
+		0x00, 0x71, 0x67, 0xEF, 0xC9, 0x2B, 0xB2, 0xE3, 0xCE, 0x7C,	/* b */
+		0x8A, 0xAA, 0xFF, 0x34, 0xE1, 0x2A, 0x9C, 0x55, 0x70, 0x03,
+		0xD7, 0xC7, 0x3A, 0x6F, 0xAF, 0x00, 0x3F, 0x99, 0xF6, 0xCC,
+		0x84, 0x82, 0xE5, 0x40, 0xF7,
+		0x00, 0x61, 0x08, 0xBA, 0xBB, 0x2C, 0xEE, 0xBC, 0xF7, 0x87,	/* x */
+		0x05, 0x8A, 0x05, 0x6C, 0xBE, 0x0C, 0xFE, 0x62, 0x2D, 0x77,
+		0x23, 0xA2, 0x89, 0xE0, 0x8A, 0x07, 0xAE, 0x13, 0xEF, 0x0D,
+		0x10, 0xD1, 0x71, 0xDD, 0x8D,
+		0x00, 0x10, 0xC7, 0x69, 0x57, 0x16, 0x85, 0x1E, 0xEF, 0x6B,	/* y */
+		0xA7, 0xF6, 0x87, 0x2E, 0x61, 0x42, 0xFB, 0xD2, 0x41, 0xB8,
+		0x30, 0xFF, 0x5E, 0xFC, 0xAC, 0xEC, 0xCA, 0xB0, 0x5E, 0x02,
+		0x00, 0x5D, 0xDE, 0x9D, 0x23,
+		0x00, 0x00, 0x01, 0x00, 0xFA, 0xF5, 0x13, 0x54, 0xE0, 0xE3,	/* order */
+		0x9E, 0x48, 0x92, 0xDF, 0x6E, 0x31, 0x9C, 0x72, 0xC8, 0x16,
+		0x16, 0x03, 0xFA, 0x45, 0xAA, 0x7B, 0x99, 0x8A, 0x16, 0x7B,
+		0x8F, 0x1E, 0x62, 0x95, 0x21
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 39 * 6];
+}
+ _EC_X9_62_CHAR2_304W1 = {
+	{
+		NID_X9_62_characteristic_two_field, 0, 39, 0xFE2E
+	},
+	{			/* no seed */
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07,
+		0x00, 0xFD, 0x0D, 0x69, 0x31, 0x49, 0xA1, 0x18, 0xF6, 0x51,	/* a */
+		0xE6, 0xDC, 0xE6, 0x80, 0x20, 0x85, 0x37, 0x7E, 0x5F, 0x88,
+		0x2D, 0x1B, 0x51, 0x0B, 0x44, 0x16, 0x00, 0x74, 0xC1, 0x28,
+		0x80, 0x78, 0x36, 0x5A, 0x03, 0x96, 0xC8, 0xE6, 0x81,
+		0x00, 0xBD, 0xDB, 0x97, 0xE5, 0x55, 0xA5, 0x0A, 0x90, 0x8E,	/* b */
+		0x43, 0xB0, 0x1C, 0x79, 0x8E, 0xA5, 0xDA, 0xA6, 0x78, 0x8F,
+		0x1E, 0xA2, 0x79, 0x4E, 0xFC, 0xF5, 0x71, 0x66, 0xB8, 0xC1,
+		0x40, 0x39, 0x60, 0x1E, 0x55, 0x82, 0x73, 0x40, 0xBE,
+		0x00, 0x19, 0x7B, 0x07, 0x84, 0x5E, 0x9B, 0xE2, 0xD9, 0x6A,	/* x */
+		0xDB, 0x0F, 0x5F, 0x3C, 0x7F, 0x2C, 0xFF, 0xBD, 0x7A, 0x3E,
+		0xB8, 0xB6, 0xFE, 0xC3, 0x5C, 0x7F, 0xD6, 0x7F, 0x26, 0xDD,
+		0xF6, 0x28, 0x5A, 0x64, 0x4F, 0x74, 0x0A, 0x26, 0x14,
+		0x00, 0xE1, 0x9F, 0xBE, 0xB7, 0x6E, 0x0D, 0xA1, 0x71, 0x51,	/* y */
+		0x7E, 0xCF, 0x40, 0x1B, 0x50, 0x28, 0x9B, 0xF0, 0x14, 0x10,
+		0x32, 0x88, 0x52, 0x7A, 0x9B, 0x41, 0x6A, 0x10, 0x5E, 0x80,
+		0x26, 0x0B, 0x54, 0x9F, 0xDC, 0x1B, 0x92, 0xC0, 0x3B,
+		0x00, 0x00, 0x01, 0x01, 0xD5, 0x56, 0x57, 0x2A, 0xAB, 0xAC,	/* order */
+		0x80, 0x01, 0x01, 0xD5, 0x56, 0x57, 0x2A, 0xAB, 0xAC, 0x80,
+		0x01, 0x02, 0x2D, 0x5C, 0x91, 0xDD, 0x17, 0x3F, 0x8F, 0xB5,
+		0x61, 0xDA, 0x68, 0x99, 0x16, 0x44, 0x43, 0x05, 0x1D
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[20 + 45 * 6];
+}
+ _EC_X9_62_CHAR2_359V1 = {
+	{
+		NID_X9_62_characteristic_two_field, 20, 45, 0x4C
+	},
+	{
+		0x2B, 0x35, 0x49, 0x20, 0xB7, 0x24, 0xD6, 0x96, 0xE6, 0x76,	/* seed */
+		0x87, 0x56, 0x15, 0x17, 0x58, 0x5B, 0xA1, 0x33, 0x2D, 0xC6,
+
+		0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x01,
+		0x56, 0x67, 0x67, 0x6A, 0x65, 0x4B, 0x20, 0x75, 0x4F, 0x35,	/* a */
+		0x6E, 0xA9, 0x20, 0x17, 0xD9, 0x46, 0x56, 0x7C, 0x46, 0x67,
+		0x55, 0x56, 0xF1, 0x95, 0x56, 0xA0, 0x46, 0x16, 0xB5, 0x67,
+		0xD2, 0x23, 0xA5, 0xE0, 0x56, 0x56, 0xFB, 0x54, 0x90, 0x16,
+		0xA9, 0x66, 0x56, 0xA5, 0x57,
+		0x24, 0x72, 0xE2, 0xD0, 0x19, 0x7C, 0x49, 0x36, 0x3F, 0x1F,	/* b */
+		0xE7, 0xF5, 0xB6, 0xDB, 0x07, 0x5D, 0x52, 0xB6, 0x94, 0x7D,
+		0x13, 0x5D, 0x8C, 0xA4, 0x45, 0x80, 0x5D, 0x39, 0xBC, 0x34,
+		0x56, 0x26, 0x08, 0x96, 0x87, 0x74, 0x2B, 0x63, 0x29, 0xE7,
+		0x06, 0x80, 0x23, 0x19, 0x88,
+		0x3C, 0x25, 0x8E, 0xF3, 0x04, 0x77, 0x67, 0xE7, 0xED, 0xE0,	/* x */
+		0xF1, 0xFD, 0xAA, 0x79, 0xDA, 0xEE, 0x38, 0x41, 0x36, 0x6A,
+		0x13, 0x2E, 0x16, 0x3A, 0xCE, 0xD4, 0xED, 0x24, 0x01, 0xDF,
+		0x9C, 0x6B, 0xDC, 0xDE, 0x98, 0xE8, 0xE7, 0x07, 0xC0, 0x7A,
+		0x22, 0x39, 0xB1, 0xB0, 0x97,
+		0x53, 0xD7, 0xE0, 0x85, 0x29, 0x54, 0x70, 0x48, 0x12, 0x1E,	/* y */
+		0x9C, 0x95, 0xF3, 0x79, 0x1D, 0xD8, 0x04, 0x96, 0x39, 0x48,
+		0xF3, 0x4F, 0xAE, 0x7B, 0xF4, 0x4E, 0xA8, 0x23, 0x65, 0xDC,
+		0x78, 0x68, 0xFE, 0x57, 0xE4, 0xAE, 0x2D, 0xE2, 0x11, 0x30,
+		0x5A, 0x40, 0x71, 0x04, 0xBD,
+		0x01, 0xAF, 0x28, 0x6B, 0xCA, 0x1A, 0xF2, 0x86, 0xBC, 0xA1,	/* order */
+		0xAF, 0x28, 0x6B, 0xCA, 0x1A, 0xF2, 0x86, 0xBC, 0xA1, 0xAF,
+		0x28, 0x6B, 0xC9, 0xFB, 0x8F, 0x6B, 0x85, 0xC5, 0x56, 0x89,
+		0x2C, 0x20, 0xA7, 0xEB, 0x96, 0x4F, 0xE7, 0x71, 0x9E, 0x74,
+		0xF4, 0x90, 0x75, 0x8D, 0x3B
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 47 * 6];
+}
+ _EC_X9_62_CHAR2_368W1 = {
+	{
+		NID_X9_62_characteristic_two_field, 0, 47, 0xFF70
+	},
+	{			/* no seed */
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 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, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+		0x00, 0xE0, 0xD2, 0xEE, 0x25, 0x09, 0x52, 0x06, 0xF5, 0xE2,	/* a */
+		0xA4, 0xF9, 0xED, 0x22, 0x9F, 0x1F, 0x25, 0x6E, 0x79, 0xA0,
+		0xE2, 0xB4, 0x55, 0x97, 0x0D, 0x8D, 0x0D, 0x86, 0x5B, 0xD9,
+		0x47, 0x78, 0xC5, 0x76, 0xD6, 0x2F, 0x0A, 0xB7, 0x51, 0x9C,
+		0xCD, 0x2A, 0x1A, 0x90, 0x6A, 0xE3, 0x0D,
+		0x00, 0xFC, 0x12, 0x17, 0xD4, 0x32, 0x0A, 0x90, 0x45, 0x2C,	/* b */
+		0x76, 0x0A, 0x58, 0xED, 0xCD, 0x30, 0xC8, 0xDD, 0x06, 0x9B,
+		0x3C, 0x34, 0x45, 0x38, 0x37, 0xA3, 0x4E, 0xD5, 0x0C, 0xB5,
+		0x49, 0x17, 0xE1, 0xC2, 0x11, 0x2D, 0x84, 0xD1, 0x64, 0xF4,
+		0x44, 0xF8, 0xF7, 0x47, 0x86, 0x04, 0x6A,
+		0x00, 0x10, 0x85, 0xE2, 0x75, 0x53, 0x81, 0xDC, 0xCC, 0xE3,	/* x */
+		0xC1, 0x55, 0x7A, 0xFA, 0x10, 0xC2, 0xF0, 0xC0, 0xC2, 0x82,
+		0x56, 0x46, 0xC5, 0xB3, 0x4A, 0x39, 0x4C, 0xBC, 0xFA, 0x8B,
+		0xC1, 0x6B, 0x22, 0xE7, 0xE7, 0x89, 0xE9, 0x27, 0xBE, 0x21,
+		0x6F, 0x02, 0xE1, 0xFB, 0x13, 0x6A, 0x5F,
+		0x00, 0x7B, 0x3E, 0xB1, 0xBD, 0xDC, 0xBA, 0x62, 0xD5, 0xD8,	/* y */
+		0xB2, 0x05, 0x9B, 0x52, 0x57, 0x97, 0xFC, 0x73, 0x82, 0x2C,
+		0x59, 0x05, 0x9C, 0x62, 0x3A, 0x45, 0xFF, 0x38, 0x43, 0xCE,
+		0xE8, 0xF8, 0x7C, 0xD1, 0x85, 0x5A, 0xDA, 0xA8, 0x1E, 0x2A,
+		0x07, 0x50, 0xB8, 0x0F, 0xDA, 0x23, 0x10,
+		0x00, 0x00, 0x01, 0x00, 0x90, 0x51, 0x2D, 0xA9, 0xAF, 0x72,	/* order */
+		0xB0, 0x83, 0x49, 0xD9, 0x8A, 0x5D, 0xD4, 0xC7, 0xB0, 0x53,
+		0x2E, 0xCA, 0x51, 0xCE, 0x03, 0xE2, 0xD1, 0x0F, 0x3B, 0x7A,
+		0xC5, 0x79, 0xBD, 0x87, 0xE9, 0x09, 0xAE, 0x40, 0xA6, 0xF1,
+		0x31, 0xE9, 0xCF, 0xCE, 0x5B, 0xD9, 0x67
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 54 * 6];
+}
+ _EC_X9_62_CHAR2_431R1 = {
+	{
+		NID_X9_62_characteristic_two_field, 0, 54, 0x2760
+	},
+	{			/* no seed */
+		0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 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, 0x01,
+		0x1A, 0x82, 0x7E, 0xF0, 0x0D, 0xD6, 0xFC, 0x0E, 0x23, 0x4C,	/* a */
+		0xAF, 0x04, 0x6C, 0x6A, 0x5D, 0x8A, 0x85, 0x39, 0x5B, 0x23,
+		0x6C, 0xC4, 0xAD, 0x2C, 0xF3, 0x2A, 0x0C, 0xAD, 0xBD, 0xC9,
+		0xDD, 0xF6, 0x20, 0xB0, 0xEB, 0x99, 0x06, 0xD0, 0x95, 0x7F,
+		0x6C, 0x6F, 0xEA, 0xCD, 0x61, 0x54, 0x68, 0xDF, 0x10, 0x4D,
+		0xE2, 0x96, 0xCD, 0x8F,
+		0x10, 0xD9, 0xB4, 0xA3, 0xD9, 0x04, 0x7D, 0x8B, 0x15, 0x43,	/* b */
+		0x59, 0xAB, 0xFB, 0x1B, 0x7F, 0x54, 0x85, 0xB0, 0x4C, 0xEB,
+		0x86, 0x82, 0x37, 0xDD, 0xC9, 0xDE, 0xDA, 0x98, 0x2A, 0x67,
+		0x9A, 0x5A, 0x91, 0x9B, 0x62, 0x6D, 0x4E, 0x50, 0xA8, 0xDD,
+		0x73, 0x1B, 0x10, 0x7A, 0x99, 0x62, 0x38, 0x1F, 0xB5, 0xD8,
+		0x07, 0xBF, 0x26, 0x18,
+		0x12, 0x0F, 0xC0, 0x5D, 0x3C, 0x67, 0xA9, 0x9D, 0xE1, 0x61,	/* x */
+		0xD2, 0xF4, 0x09, 0x26, 0x22, 0xFE, 0xCA, 0x70, 0x1B, 0xE4,
+		0xF5, 0x0F, 0x47, 0x58, 0x71, 0x4E, 0x8A, 0x87, 0xBB, 0xF2,
+		0xA6, 0x58, 0xEF, 0x8C, 0x21, 0xE7, 0xC5, 0xEF, 0xE9, 0x65,
+		0x36, 0x1F, 0x6C, 0x29, 0x99, 0xC0, 0xC2, 0x47, 0xB0, 0xDB,
+		0xD7, 0x0C, 0xE6, 0xB7,
+		0x20, 0xD0, 0xAF, 0x89, 0x03, 0xA9, 0x6F, 0x8D, 0x5F, 0xA2,	/* y */
+		0xC2, 0x55, 0x74, 0x5D, 0x3C, 0x45, 0x1B, 0x30, 0x2C, 0x93,
+		0x46, 0xD9, 0xB7, 0xE4, 0x85, 0xE7, 0xBC, 0xE4, 0x1F, 0x6B,
+		0x59, 0x1F, 0x3E, 0x8F, 0x6A, 0xDD, 0xCB, 0xB0, 0xBC, 0x4C,
+		0x2F, 0x94, 0x7A, 0x7D, 0xE1, 0xA8, 0x9B, 0x62, 0x5D, 0x6A,
+		0x59, 0x8B, 0x37, 0x60,
+		0x00, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34,	/* order */
+		0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03,
+		0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x23,
+		0xC3, 0x13, 0xFA, 0xB5, 0x05, 0x89, 0x70, 0x3B, 0x5E, 0xC6,
+		0x8D, 0x35, 0x87, 0xFE, 0xC6, 0x0D, 0x16, 0x1C, 0xC1, 0x49,
+		0xC1, 0xAD, 0x4A, 0x91
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 15 * 6];
+}
+ _EC_WTLS_1 = {
+	{
+		NID_X9_62_characteristic_two_field, 0, 15, 2
+	},
+	{			/* no seed */
+		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x02, 0x01,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x01,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* b */
+		0x00, 0x00, 0x00, 0x00, 0x01,
+		0x01, 0x66, 0x79, 0x79, 0xA4, 0x0B, 0xA4, 0x97, 0xE5, 0xD5,	/* x */
+		0xC2, 0x70, 0x78, 0x06, 0x17,
+		0x00, 0xF4, 0x4B, 0x4A, 0xF1, 0xEC, 0xC2, 0x63, 0x0E, 0x08,	/* y */
+		0x78, 0x5C, 0xEB, 0xCC, 0x15,
+		0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xBF,	/* order */
+		0x91, 0xAF, 0x6D, 0xEA, 0x73
+	}
+};
+
+/* IPSec curves */
+/* NOTE: The of curves over a extension field of non prime degree
+ * is not recommended (Weil-descent).
+ * As the group order is not a prime this curve is not suitable
+ * for ECDSA.
+ */
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 20 * 6];
+}
+ _EC_IPSEC_155_ID3 = {
+	{
+		NID_X9_62_characteristic_two_field, 0, 20, 3
+	},
+	{			/* no seed */
+		0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* b */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x33, 0x8f,
+
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* x */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
+
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* y */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc8,
+
+		0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,	/* order */
+		0xC7, 0xF3, 0xC7, 0x88, 0x1B, 0xD0, 0x86, 0x8F, 0xA8, 0x6C
+	}
+};
+
+/* NOTE: The of curves over a extension field of non prime degree
+ * is not recommended (Weil-descent).
+ * As the group order is not a prime this curve is not suitable
+ * for ECDSA.
+ */
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 24 * 6];
+}
+ _EC_IPSEC_185_ID4 = {
+	{
+		NID_X9_62_characteristic_two_field, 0, 24, 2
+	},
+	{			/* no seed */
+		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x01,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* b */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x1e, 0xe9,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* x */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x18,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* y */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x0d,
+		0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFF, 0xFF, 0xED, 0xF9, 0x7C, 0x44, 0xDB, 0x9F, 0x24, 0x20,
+		0xBA, 0xFC, 0xA7, 0x5E
+	}
+};
+
+#endif
+
+/* These curves were added by Annie Yousar 
+ * For the definition of RFC 5639 curves see
+ * https://www.ietf.org/rfc/rfc5639.txt
+ * These curves are generated verifiable at random, nevertheless the seed is
+ * omitted as parameter because the generation mechanism is different from
+ * those defined in ANSI X9.62.
+ */
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 20 * 6];
+}
+ _EC_brainpoolP160r1 = {
+	{
+		NID_X9_62_prime_field, 0, 20, 1
+	},
+	{			/* no seed */
+		0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF,	/* p */
+		0xC7, 0xAD, 0x95, 0xB3, 0xD8, 0x13, 0x95, 0x15, 0x62, 0x0F,
+		0x34, 0x0E, 0x7B, 0xE2, 0xA2, 0x80, 0xEB, 0x74, 0xE2, 0xBE,	/* a */
+		0x61, 0xBA, 0xDA, 0x74, 0x5D, 0x97, 0xE8, 0xF7, 0xC3, 0x00,
+		0x1E, 0x58, 0x9A, 0x85, 0x95, 0x42, 0x34, 0x12, 0x13, 0x4F,	/* b */
+		0xAA, 0x2D, 0xBD, 0xEC, 0x95, 0xC8, 0xD8, 0x67, 0x5E, 0x58,
+		0xBE, 0xD5, 0xAF, 0x16, 0xEA, 0x3F, 0x6A, 0x4F, 0x62, 0x93,	/* x */
+		0x8C, 0x46, 0x31, 0xEB, 0x5A, 0xF7, 0xBD, 0xBC, 0xDB, 0xC3,
+		0x16, 0x67, 0xCB, 0x47, 0x7A, 0x1A, 0x8E, 0xC3, 0x38, 0xF9,	/* y */
+		0x47, 0x41, 0x66, 0x9C, 0x97, 0x63, 0x16, 0xDA, 0x63, 0x21,
+		0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF,	/* order */
+		0x59, 0x91, 0xD4, 0x50, 0x29, 0x40, 0x9E, 0x60, 0xFC, 0x09
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 20 * 6];
+}
+ _EC_brainpoolP160t1 = {
+	{
+		NID_X9_62_prime_field, 0, 20, 1
+	},
+	{			/* no seed */
+		0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF,	/* p */
+		0xC7, 0xAD, 0x95, 0xB3, 0xD8, 0x13, 0x95, 0x15, 0x62, 0x0F,
+		0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF,	/* a */
+		0xC7, 0xAD, 0x95, 0xB3, 0xD8, 0x13, 0x95, 0x15, 0x62, 0x0C,
+		0x7A, 0x55, 0x6B, 0x6D, 0xAE, 0x53, 0x5B, 0x7B, 0x51, 0xED,	/* b */
+		0x2C, 0x4D, 0x7D, 0xAA, 0x7A, 0x0B, 0x5C, 0x55, 0xF3, 0x80,
+		0xB1, 0x99, 0xB1, 0x3B, 0x9B, 0x34, 0xEF, 0xC1, 0x39, 0x7E,	/* x */
+		0x64, 0xBA, 0xEB, 0x05, 0xAC, 0xC2, 0x65, 0xFF, 0x23, 0x78,
+		0xAD, 0xD6, 0x71, 0x8B, 0x7C, 0x7C, 0x19, 0x61, 0xF0, 0x99,	/* y */
+		0x1B, 0x84, 0x24, 0x43, 0x77, 0x21, 0x52, 0xC9, 0xE0, 0xAD,
+		0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF,	/* order */
+		0x59, 0x91, 0xD4, 0x50, 0x29, 0x40, 0x9E, 0x60, 0xFC, 0x09
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 24 * 6];
+}
+ _EC_brainpoolP192r1 = {
+	{
+		NID_X9_62_prime_field, 0, 24, 1
+	},
+	{			/* no seed */
+		0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3,	/* p */
+		0x46, 0x30, 0x93, 0xD1, 0x8D, 0xB7, 0x8F, 0xCE, 0x47, 0x6D,
+		0xE1, 0xA8, 0x62, 0x97,
+		0x6A, 0x91, 0x17, 0x40, 0x76, 0xB1, 0xE0, 0xE1, 0x9C, 0x39,	/* a */
+		0xC0, 0x31, 0xFE, 0x86, 0x85, 0xC1, 0xCA, 0xE0, 0x40, 0xE5,
+		0xC6, 0x9A, 0x28, 0xEF,
+		0x46, 0x9A, 0x28, 0xEF, 0x7C, 0x28, 0xCC, 0xA3, 0xDC, 0x72,	/* b */
+		0x1D, 0x04, 0x4F, 0x44, 0x96, 0xBC, 0xCA, 0x7E, 0xF4, 0x14,
+		0x6F, 0xBF, 0x25, 0xC9,
+		0xC0, 0xA0, 0x64, 0x7E, 0xAA, 0xB6, 0xA4, 0x87, 0x53, 0xB0,	/* x */
+		0x33, 0xC5, 0x6C, 0xB0, 0xF0, 0x90, 0x0A, 0x2F, 0x5C, 0x48,
+		0x53, 0x37, 0x5F, 0xD6,
+		0x14, 0xB6, 0x90, 0x86, 0x6A, 0xBD, 0x5B, 0xB8, 0x8B, 0x5F,	/* y */
+		0x48, 0x28, 0xC1, 0x49, 0x00, 0x02, 0xE6, 0x77, 0x3F, 0xA2,
+		0xFA, 0x29, 0x9B, 0x8F,
+		0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3,	/* order */
+		0x46, 0x2F, 0x9E, 0x9E, 0x91, 0x6B, 0x5B, 0xE8, 0xF1, 0x02,
+		0x9A, 0xC4, 0xAC, 0xC1
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 24 * 6];
+}
+ _EC_brainpoolP192t1 = {
+	{
+		NID_X9_62_prime_field, 0, 24, 1
+	},
+	{			/* no seed */
+		0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3,	/* p */
+		0x46, 0x30, 0x93, 0xD1, 0x8D, 0xB7, 0x8F, 0xCE, 0x47, 0x6D,
+		0xE1, 0xA8, 0x62, 0x97,
+		0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3,	/* a */
+		0x46, 0x30, 0x93, 0xD1, 0x8D, 0xB7, 0x8F, 0xCE, 0x47, 0x6D,
+		0xE1, 0xA8, 0x62, 0x94,
+		0x13, 0xD5, 0x6F, 0xFA, 0xEC, 0x78, 0x68, 0x1E, 0x68, 0xF9,	/* b */
+		0xDE, 0xB4, 0x3B, 0x35, 0xBE, 0xC2, 0xFB, 0x68, 0x54, 0x2E,
+		0x27, 0x89, 0x7B, 0x79,
+		0x3A, 0xE9, 0xE5, 0x8C, 0x82, 0xF6, 0x3C, 0x30, 0x28, 0x2E,	/* x */
+		0x1F, 0xE7, 0xBB, 0xF4, 0x3F, 0xA7, 0x2C, 0x44, 0x6A, 0xF6,
+		0xF4, 0x61, 0x81, 0x29,
+		0x09, 0x7E, 0x2C, 0x56, 0x67, 0xC2, 0x22, 0x3A, 0x90, 0x2A,	/* y */
+		0xB5, 0xCA, 0x44, 0x9D, 0x00, 0x84, 0xB7, 0xE5, 0xB3, 0xDE,
+		0x7C, 0xCC, 0x01, 0xC9,
+		0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3,	/* order */
+		0x46, 0x2F, 0x9E, 0x9E, 0x91, 0x6B, 0x5B, 0xE8, 0xF1, 0x02,
+		0x9A, 0xC4, 0xAC, 0xC1
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 28 * 6];
+}
+ _EC_brainpoolP224r1 = {
+	{
+		NID_X9_62_prime_field, 0, 28, 1
+	},
+	{			/* no seed */
+		0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18,	/* p */
+		0x30, 0x25, 0x75, 0xD1, 0xD7, 0x87, 0xB0, 0x9F, 0x07, 0x57,
+		0x97, 0xDA, 0x89, 0xF5, 0x7E, 0xC8, 0xC0, 0xFF,
+		0x68, 0xA5, 0xE6, 0x2C, 0xA9, 0xCE, 0x6C, 0x1C, 0x29, 0x98,	/* a */
+		0x03, 0xA6, 0xC1, 0x53, 0x0B, 0x51, 0x4E, 0x18, 0x2A, 0xD8,
+		0xB0, 0x04, 0x2A, 0x59, 0xCA, 0xD2, 0x9F, 0x43,
+		0x25, 0x80, 0xF6, 0x3C, 0xCF, 0xE4, 0x41, 0x38, 0x87, 0x07,	/* b */
+		0x13, 0xB1, 0xA9, 0x23, 0x69, 0xE3, 0x3E, 0x21, 0x35, 0xD2,
+		0x66, 0xDB, 0xB3, 0x72, 0x38, 0x6C, 0x40, 0x0B,
+		0x0D, 0x90, 0x29, 0xAD, 0x2C, 0x7E, 0x5C, 0xF4, 0x34, 0x08,	/* x */
+		0x23, 0xB2, 0xA8, 0x7D, 0xC6, 0x8C, 0x9E, 0x4C, 0xE3, 0x17,
+		0x4C, 0x1E, 0x6E, 0xFD, 0xEE, 0x12, 0xC0, 0x7D,
+		0x58, 0xAA, 0x56, 0xF7, 0x72, 0xC0, 0x72, 0x6F, 0x24, 0xC6,	/* y */
+		0xB8, 0x9E, 0x4E, 0xCD, 0xAC, 0x24, 0x35, 0x4B, 0x9E, 0x99,
+		0xCA, 0xA3, 0xF6, 0xD3, 0x76, 0x14, 0x02, 0xCD,
+		0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18,	/* order */
+		0x30, 0x25, 0x75, 0xD0, 0xFB, 0x98, 0xD1, 0x16, 0xBC, 0x4B,
+		0x6D, 0xDE, 0xBC, 0xA3, 0xA5, 0xA7, 0x93, 0x9F
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 28 * 6];
+}
+ _EC_brainpoolP224t1 = {
+	{
+		NID_X9_62_prime_field, 0, 28, 1
+	},
+	{			/* no seed */
+		0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18,	/* p */
+		0x30, 0x25, 0x75, 0xD1, 0xD7, 0x87, 0xB0, 0x9F, 0x07, 0x57,
+		0x97, 0xDA, 0x89, 0xF5, 0x7E, 0xC8, 0xC0, 0xFF,
+		0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18,	/* a */
+		0x30, 0x25, 0x75, 0xD1, 0xD7, 0x87, 0xB0, 0x9F, 0x07, 0x57,
+		0x97, 0xDA, 0x89, 0xF5, 0x7E, 0xC8, 0xC0, 0xFC,
+		0x4B, 0x33, 0x7D, 0x93, 0x41, 0x04, 0xCD, 0x7B, 0xEF, 0x27,	/* b */
+		0x1B, 0xF6, 0x0C, 0xED, 0x1E, 0xD2, 0x0D, 0xA1, 0x4C, 0x08,
+		0xB3, 0xBB, 0x64, 0xF1, 0x8A, 0x60, 0x88, 0x8D,
+		0x6A, 0xB1, 0xE3, 0x44, 0xCE, 0x25, 0xFF, 0x38, 0x96, 0x42,	/* x */
+		0x4E, 0x7F, 0xFE, 0x14, 0x76, 0x2E, 0xCB, 0x49, 0xF8, 0x92,
+		0x8A, 0xC0, 0xC7, 0x60, 0x29, 0xB4, 0xD5, 0x80,
+		0x03, 0x74, 0xE9, 0xF5, 0x14, 0x3E, 0x56, 0x8C, 0xD2, 0x3F,	/* y */
+		0x3F, 0x4D, 0x7C, 0x0D, 0x4B, 0x1E, 0x41, 0xC8, 0xCC, 0x0D,
+		0x1C, 0x6A, 0xBD, 0x5F, 0x1A, 0x46, 0xDB, 0x4C,
+		0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18,	/* order */
+		0x30, 0x25, 0x75, 0xD0, 0xFB, 0x98, 0xD1, 0x16, 0xBC, 0x4B,
+		0x6D, 0xDE, 0xBC, 0xA3, 0xA5, 0xA7, 0x93, 0x9F
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 32 * 6];
+}
+ _EC_brainpoolP256r1 = {
+	{
+		NID_X9_62_prime_field, 0, 32, 1
+	},
+	{			/* no seed */
+		0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66,	/* p */
+		0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72, 0x6E, 0x3B, 0xF6, 0x23,
+		0xD5, 0x26, 0x20, 0x28, 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E,
+		0x53, 0x77,
+		0x7D, 0x5A, 0x09, 0x75, 0xFC, 0x2C, 0x30, 0x57, 0xEE, 0xF6,	/* a */
+		0x75, 0x30, 0x41, 0x7A, 0xFF, 0xE7, 0xFB, 0x80, 0x55, 0xC1,
+		0x26, 0xDC, 0x5C, 0x6C, 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30,
+		0xB5, 0xD9,
+		0x26, 0xDC, 0x5C, 0x6C, 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30,	/* b */
+		0xB5, 0xD9, 0xBB, 0xD7, 0x7C, 0xBF, 0x95, 0x84, 0x16, 0x29,
+		0x5C, 0xF7, 0xE1, 0xCE, 0x6B, 0xCC, 0xDC, 0x18, 0xFF, 0x8C,
+		0x07, 0xB6,
+		0x8B, 0xD2, 0xAE, 0xB9, 0xCB, 0x7E, 0x57, 0xCB, 0x2C, 0x4B,	/* x */
+		0x48, 0x2F, 0xFC, 0x81, 0xB7, 0xAF, 0xB9, 0xDE, 0x27, 0xE1,
+		0xE3, 0xBD, 0x23, 0xC2, 0x3A, 0x44, 0x53, 0xBD, 0x9A, 0xCE,
+		0x32, 0x62,
+		0x54, 0x7E, 0xF8, 0x35, 0xC3, 0xDA, 0xC4, 0xFD, 0x97, 0xF8,	/* y */
+		0x46, 0x1A, 0x14, 0x61, 0x1D, 0xC9, 0xC2, 0x77, 0x45, 0x13,
+		0x2D, 0xED, 0x8E, 0x54, 0x5C, 0x1D, 0x54, 0xC7, 0x2F, 0x04,
+		0x69, 0x97,
+		0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66,	/* order */
+		0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x71, 0x8C, 0x39, 0x7A, 0xA3,
+		0xB5, 0x61, 0xA6, 0xF7, 0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48,
+		0x56, 0xA7
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 32 * 6];
+}
+ _EC_brainpoolP256t1 = {
+	{
+		NID_X9_62_prime_field, 0, 32, 1
+	},
+	{			/* no seed */
+		0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66,	/* p */
+		0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72, 0x6E, 0x3B, 0xF6, 0x23,
+		0xD5, 0x26, 0x20, 0x28, 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E,
+		0x53, 0x77,
+		0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66,	/* a */
+		0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72, 0x6E, 0x3B, 0xF6, 0x23,
+		0xD5, 0x26, 0x20, 0x28, 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E,
+		0x53, 0x74,
+		0x66, 0x2C, 0x61, 0xC4, 0x30, 0xD8, 0x4E, 0xA4, 0xFE, 0x66,	/* b */
+		0xA7, 0x73, 0x3D, 0x0B, 0x76, 0xB7, 0xBF, 0x93, 0xEB, 0xC4,
+		0xAF, 0x2F, 0x49, 0x25, 0x6A, 0xE5, 0x81, 0x01, 0xFE, 0xE9,
+		0x2B, 0x04,
+		0xA3, 0xE8, 0xEB, 0x3C, 0xC1, 0xCF, 0xE7, 0xB7, 0x73, 0x22,	/* x */
+		0x13, 0xB2, 0x3A, 0x65, 0x61, 0x49, 0xAF, 0xA1, 0x42, 0xC4,
+		0x7A, 0xAF, 0xBC, 0x2B, 0x79, 0xA1, 0x91, 0x56, 0x2E, 0x13,
+		0x05, 0xF4,
+		0x2D, 0x99, 0x6C, 0x82, 0x34, 0x39, 0xC5, 0x6D, 0x7F, 0x7B,	/* y */
+		0x22, 0xE1, 0x46, 0x44, 0x41, 0x7E, 0x69, 0xBC, 0xB6, 0xDE,
+		0x39, 0xD0, 0x27, 0x00, 0x1D, 0xAB, 0xE8, 0xF3, 0x5B, 0x25,
+		0xC9, 0xBE,
+		0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66,	/* order */
+		0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x71, 0x8C, 0x39, 0x7A, 0xA3,
+		0xB5, 0x61, 0xA6, 0xF7, 0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48,
+		0x56, 0xA7
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 40 * 6];
+}
+ _EC_brainpoolP320r1 = {
+	{
+		NID_X9_62_prime_field, 0, 40, 1
+	},
+	{			/* no seed */
+		0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C,	/* p */
+		0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA6,
+		0xF6, 0xF4, 0x0D, 0xEF, 0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93,
+		0xEC, 0x28, 0xFC, 0xD4, 0x12, 0xB1, 0xF1, 0xB3, 0x2E, 0x27,
+		0x3E, 0xE3, 0x0B, 0x56, 0x8F, 0xBA, 0xB0, 0xF8, 0x83, 0xCC,	/* a */
+		0xEB, 0xD4, 0x6D, 0x3F, 0x3B, 0xB8, 0xA2, 0xA7, 0x35, 0x13,
+		0xF5, 0xEB, 0x79, 0xDA, 0x66, 0x19, 0x0E, 0xB0, 0x85, 0xFF,
+		0xA9, 0xF4, 0x92, 0xF3, 0x75, 0xA9, 0x7D, 0x86, 0x0E, 0xB4,
+		0x52, 0x08, 0x83, 0x94, 0x9D, 0xFD, 0xBC, 0x42, 0xD3, 0xAD,	/* b */
+		0x19, 0x86, 0x40, 0x68, 0x8A, 0x6F, 0xE1, 0x3F, 0x41, 0x34,
+		0x95, 0x54, 0xB4, 0x9A, 0xCC, 0x31, 0xDC, 0xCD, 0x88, 0x45,
+		0x39, 0x81, 0x6F, 0x5E, 0xB4, 0xAC, 0x8F, 0xB1, 0xF1, 0xA6,
+		0x43, 0xBD, 0x7E, 0x9A, 0xFB, 0x53, 0xD8, 0xB8, 0x52, 0x89,	/* x */
+		0xBC, 0xC4, 0x8E, 0xE5, 0xBF, 0xE6, 0xF2, 0x01, 0x37, 0xD1,
+		0x0A, 0x08, 0x7E, 0xB6, 0xE7, 0x87, 0x1E, 0x2A, 0x10, 0xA5,
+		0x99, 0xC7, 0x10, 0xAF, 0x8D, 0x0D, 0x39, 0xE2, 0x06, 0x11,
+		0x14, 0xFD, 0xD0, 0x55, 0x45, 0xEC, 0x1C, 0xC8, 0xAB, 0x40,	/* y */
+		0x93, 0x24, 0x7F, 0x77, 0x27, 0x5E, 0x07, 0x43, 0xFF, 0xED,
+		0x11, 0x71, 0x82, 0xEA, 0xA9, 0xC7, 0x78, 0x77, 0xAA, 0xAC,
+		0x6A, 0xC7, 0xD3, 0x52, 0x45, 0xD1, 0x69, 0x2E, 0x8E, 0xE1,
+		0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C,	/* order */
+		0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA5,
+		0xB6, 0x8F, 0x12, 0xA3, 0x2D, 0x48, 0x2E, 0xC7, 0xEE, 0x86,
+		0x58, 0xE9, 0x86, 0x91, 0x55, 0x5B, 0x44, 0xC5, 0x93, 0x11
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 40 * 6];
+}
+ _EC_brainpoolP320t1 = {
+	{
+		NID_X9_62_prime_field, 0, 40, 1
+	},
+	{			/* no seed */
+		0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C,	/* p */
+		0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA6,
+		0xF6, 0xF4, 0x0D, 0xEF, 0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93,
+		0xEC, 0x28, 0xFC, 0xD4, 0x12, 0xB1, 0xF1, 0xB3, 0x2E, 0x27,
+		0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C,	/* a */
+		0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA6,
+		0xF6, 0xF4, 0x0D, 0xEF, 0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93,
+		0xEC, 0x28, 0xFC, 0xD4, 0x12, 0xB1, 0xF1, 0xB3, 0x2E, 0x24,
+		0xA7, 0xF5, 0x61, 0xE0, 0x38, 0xEB, 0x1E, 0xD5, 0x60, 0xB3,	/* b */
+		0xD1, 0x47, 0xDB, 0x78, 0x20, 0x13, 0x06, 0x4C, 0x19, 0xF2,
+		0x7E, 0xD2, 0x7C, 0x67, 0x80, 0xAA, 0xF7, 0x7F, 0xB8, 0xA5,
+		0x47, 0xCE, 0xB5, 0xB4, 0xFE, 0xF4, 0x22, 0x34, 0x03, 0x53,
+		0x92, 0x5B, 0xE9, 0xFB, 0x01, 0xAF, 0xC6, 0xFB, 0x4D, 0x3E,	/* x */
+		0x7D, 0x49, 0x90, 0x01, 0x0F, 0x81, 0x34, 0x08, 0xAB, 0x10,
+		0x6C, 0x4F, 0x09, 0xCB, 0x7E, 0xE0, 0x78, 0x68, 0xCC, 0x13,
+		0x6F, 0xFF, 0x33, 0x57, 0xF6, 0x24, 0xA2, 0x1B, 0xED, 0x52,
+		0x63, 0xBA, 0x3A, 0x7A, 0x27, 0x48, 0x3E, 0xBF, 0x66, 0x71,	/* y */
+		0xDB, 0xEF, 0x7A, 0xBB, 0x30, 0xEB, 0xEE, 0x08, 0x4E, 0x58,
+		0xA0, 0xB0, 0x77, 0xAD, 0x42, 0xA5, 0xA0, 0x98, 0x9D, 0x1E,
+		0xE7, 0x1B, 0x1B, 0x9B, 0xC0, 0x45, 0x5F, 0xB0, 0xD2, 0xC3,
+		0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C,	/* order */
+		0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA5,
+		0xB6, 0x8F, 0x12, 0xA3, 0x2D, 0x48, 0x2E, 0xC7, 0xEE, 0x86,
+		0x58, 0xE9, 0x86, 0x91, 0x55, 0x5B, 0x44, 0xC5, 0x93, 0x11
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 48 * 6];
+}
+ _EC_brainpoolP384r1 = {
+	{
+		NID_X9_62_prime_field, 0, 48, 1
+	},
+	{			/* no seed */
+		0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D,	/* p */
+		0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09,
+		0xED, 0x54, 0x56, 0xB4, 0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7,
+		0x11, 0x23, 0xAC, 0xD3, 0xA7, 0x29, 0x90, 0x1D, 0x1A, 0x71,
+		0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x53,
+		0x7B, 0xC3, 0x82, 0xC6, 0x3D, 0x8C, 0x15, 0x0C, 0x3C, 0x72,	/* a */
+		0x08, 0x0A, 0xCE, 0x05, 0xAF, 0xA0, 0xC2, 0xBE, 0xA2, 0x8E,
+		0x4F, 0xB2, 0x27, 0x87, 0x13, 0x91, 0x65, 0xEF, 0xBA, 0x91,
+		0xF9, 0x0F, 0x8A, 0xA5, 0x81, 0x4A, 0x50, 0x3A, 0xD4, 0xEB,
+		0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26,
+		0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26, 0x8B, 0x39,	/* b */
+		0xB5, 0x54, 0x16, 0xF0, 0x44, 0x7C, 0x2F, 0xB7, 0x7D, 0xE1,
+		0x07, 0xDC, 0xD2, 0xA6, 0x2E, 0x88, 0x0E, 0xA5, 0x3E, 0xEB,
+		0x62, 0xD5, 0x7C, 0xB4, 0x39, 0x02, 0x95, 0xDB, 0xC9, 0x94,
+		0x3A, 0xB7, 0x86, 0x96, 0xFA, 0x50, 0x4C, 0x11,
+		0x1D, 0x1C, 0x64, 0xF0, 0x68, 0xCF, 0x45, 0xFF, 0xA2, 0xA6,	/* x */
+		0x3A, 0x81, 0xB7, 0xC1, 0x3F, 0x6B, 0x88, 0x47, 0xA3, 0xE7,
+		0x7E, 0xF1, 0x4F, 0xE3, 0xDB, 0x7F, 0xCA, 0xFE, 0x0C, 0xBD,
+		0x10, 0xE8, 0xE8, 0x26, 0xE0, 0x34, 0x36, 0xD6, 0x46, 0xAA,
+		0xEF, 0x87, 0xB2, 0xE2, 0x47, 0xD4, 0xAF, 0x1E,
+		0x8A, 0xBE, 0x1D, 0x75, 0x20, 0xF9, 0xC2, 0xA4, 0x5C, 0xB1,	/* y */
+		0xEB, 0x8E, 0x95, 0xCF, 0xD5, 0x52, 0x62, 0xB7, 0x0B, 0x29,
+		0xFE, 0xEC, 0x58, 0x64, 0xE1, 0x9C, 0x05, 0x4F, 0xF9, 0x91,
+		0x29, 0x28, 0x0E, 0x46, 0x46, 0x21, 0x77, 0x91, 0x81, 0x11,
+		0x42, 0x82, 0x03, 0x41, 0x26, 0x3C, 0x53, 0x15,
+		0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D,	/* order */
+		0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09,
+		0xED, 0x54, 0x56, 0xB3, 0x1F, 0x16, 0x6E, 0x6C, 0xAC, 0x04,
+		0x25, 0xA7, 0xCF, 0x3A, 0xB6, 0xAF, 0x6B, 0x7F, 0xC3, 0x10,
+		0x3B, 0x88, 0x32, 0x02, 0xE9, 0x04, 0x65, 0x65
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 48 * 6];
+}
+ _EC_brainpoolP384t1 = {
+	{
+		NID_X9_62_prime_field, 0, 48, 1
+	},
+	{			/* no seed */
+		0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D,	/* p */
+		0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09,
+		0xED, 0x54, 0x56, 0xB4, 0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7,
+		0x11, 0x23, 0xAC, 0xD3, 0xA7, 0x29, 0x90, 0x1D, 0x1A, 0x71,
+		0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x53,
+		0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D,	/* a */
+		0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09,
+		0xED, 0x54, 0x56, 0xB4, 0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7,
+		0x11, 0x23, 0xAC, 0xD3, 0xA7, 0x29, 0x90, 0x1D, 0x1A, 0x71,
+		0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x50,
+		0x7F, 0x51, 0x9E, 0xAD, 0xA7, 0xBD, 0xA8, 0x1B, 0xD8, 0x26,	/* b */
+		0xDB, 0xA6, 0x47, 0x91, 0x0F, 0x8C, 0x4B, 0x93, 0x46, 0xED,
+		0x8C, 0xCD, 0xC6, 0x4E, 0x4B, 0x1A, 0xBD, 0x11, 0x75, 0x6D,
+		0xCE, 0x1D, 0x20, 0x74, 0xAA, 0x26, 0x3B, 0x88, 0x80, 0x5C,
+		0xED, 0x70, 0x35, 0x5A, 0x33, 0xB4, 0x71, 0xEE,
+		0x18, 0xDE, 0x98, 0xB0, 0x2D, 0xB9, 0xA3, 0x06, 0xF2, 0xAF,	/* x */
+		0xCD, 0x72, 0x35, 0xF7, 0x2A, 0x81, 0x9B, 0x80, 0xAB, 0x12,
+		0xEB, 0xD6, 0x53, 0x17, 0x24, 0x76, 0xFE, 0xCD, 0x46, 0x2A,
+		0xAB, 0xFF, 0xC4, 0xFF, 0x19, 0x1B, 0x94, 0x6A, 0x5F, 0x54,
+		0xD8, 0xD0, 0xAA, 0x2F, 0x41, 0x88, 0x08, 0xCC,
+		0x25, 0xAB, 0x05, 0x69, 0x62, 0xD3, 0x06, 0x51, 0xA1, 0x14,	/* y */
+		0xAF, 0xD2, 0x75, 0x5A, 0xD3, 0x36, 0x74, 0x7F, 0x93, 0x47,
+		0x5B, 0x7A, 0x1F, 0xCA, 0x3B, 0x88, 0xF2, 0xB6, 0xA2, 0x08,
+		0xCC, 0xFE, 0x46, 0x94, 0x08, 0x58, 0x4D, 0xC2, 0xB2, 0x91,
+		0x26, 0x75, 0xBF, 0x5B, 0x9E, 0x58, 0x29, 0x28,
+		0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D,	/* order */
+		0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09,
+		0xED, 0x54, 0x56, 0xB3, 0x1F, 0x16, 0x6E, 0x6C, 0xAC, 0x04,
+		0x25, 0xA7, 0xCF, 0x3A, 0xB6, 0xAF, 0x6B, 0x7F, 0xC3, 0x10,
+		0x3B, 0x88, 0x32, 0x02, 0xE9, 0x04, 0x65, 0x65
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 64 * 6];
+}
+ _EC_brainpoolP512r1 = {
+	{
+		NID_X9_62_prime_field, 0, 64, 1
+	},
+	{			/* no seed */
+		0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4,	/* p */
+		0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3,
+		0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33,
+		0x08, 0x71, 0x7D, 0x4D, 0x9B, 0x00, 0x9B, 0xC6, 0x68, 0x42,
+		0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6, 0x28, 0x81,
+		0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56,
+		0x58, 0x3A, 0x48, 0xF3,
+		0x78, 0x30, 0xA3, 0x31, 0x8B, 0x60, 0x3B, 0x89, 0xE2, 0x32,	/* a */
+		0x71, 0x45, 0xAC, 0x23, 0x4C, 0xC5, 0x94, 0xCB, 0xDD, 0x8D,
+		0x3D, 0xF9, 0x16, 0x10, 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98,
+		0x63, 0xBC, 0x2D, 0xED, 0x5D, 0x5A, 0xA8, 0x25, 0x3A, 0xA1,
+		0x0A, 0x2E, 0xF1, 0xC9, 0x8B, 0x9A, 0xC8, 0xB5, 0x7F, 0x11,
+		0x17, 0xA7, 0x2B, 0xF2, 0xC7, 0xB9, 0xE7, 0xC1, 0xAC, 0x4D,
+		0x77, 0xFC, 0x94, 0xCA,
+		0x3D, 0xF9, 0x16, 0x10, 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98,	/* b */
+		0x63, 0xBC, 0x2D, 0xED, 0x5D, 0x5A, 0xA8, 0x25, 0x3A, 0xA1,
+		0x0A, 0x2E, 0xF1, 0xC9, 0x8B, 0x9A, 0xC8, 0xB5, 0x7F, 0x11,
+		0x17, 0xA7, 0x2B, 0xF2, 0xC7, 0xB9, 0xE7, 0xC1, 0xAC, 0x4D,
+		0x77, 0xFC, 0x94, 0xCA, 0xDC, 0x08, 0x3E, 0x67, 0x98, 0x40,
+		0x50, 0xB7, 0x5E, 0xBA, 0xE5, 0xDD, 0x28, 0x09, 0xBD, 0x63,
+		0x80, 0x16, 0xF7, 0x23,
+		0x81, 0xAE, 0xE4, 0xBD, 0xD8, 0x2E, 0xD9, 0x64, 0x5A, 0x21,	/* x */
+		0x32, 0x2E, 0x9C, 0x4C, 0x6A, 0x93, 0x85, 0xED, 0x9F, 0x70,
+		0xB5, 0xD9, 0x16, 0xC1, 0xB4, 0x3B, 0x62, 0xEE, 0xF4, 0xD0,
+		0x09, 0x8E, 0xFF, 0x3B, 0x1F, 0x78, 0xE2, 0xD0, 0xD4, 0x8D,
+		0x50, 0xD1, 0x68, 0x7B, 0x93, 0xB9, 0x7D, 0x5F, 0x7C, 0x6D,
+		0x50, 0x47, 0x40, 0x6A, 0x5E, 0x68, 0x8B, 0x35, 0x22, 0x09,
+		0xBC, 0xB9, 0xF8, 0x22,
+		0x7D, 0xDE, 0x38, 0x5D, 0x56, 0x63, 0x32, 0xEC, 0xC0, 0xEA,	/* y */
+		0xBF, 0xA9, 0xCF, 0x78, 0x22, 0xFD, 0xF2, 0x09, 0xF7, 0x00,
+		0x24, 0xA5, 0x7B, 0x1A, 0xA0, 0x00, 0xC5, 0x5B, 0x88, 0x1F,
+		0x81, 0x11, 0xB2, 0xDC, 0xDE, 0x49, 0x4A, 0x5F, 0x48, 0x5E,
+		0x5B, 0xCA, 0x4B, 0xD8, 0x8A, 0x27, 0x63, 0xAE, 0xD1, 0xCA,
+		0x2B, 0x2F, 0xA8, 0xF0, 0x54, 0x06, 0x78, 0xCD, 0x1E, 0x0F,
+		0x3A, 0xD8, 0x08, 0x92,
+		0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4,	/* order */
+		0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3,
+		0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33,
+		0x08, 0x70, 0x55, 0x3E, 0x5C, 0x41, 0x4C, 0xA9, 0x26, 0x19,
+		0x41, 0x86, 0x61, 0x19, 0x7F, 0xAC, 0x10, 0x47, 0x1D, 0xB1,
+		0xD3, 0x81, 0x08, 0x5D, 0xDA, 0xDD, 0xB5, 0x87, 0x96, 0x82,
+		0x9C, 0xA9, 0x00, 0x69
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 64 * 6];
+}
+ _EC_brainpoolP512t1 = {
+	{
+		NID_X9_62_prime_field, 0, 64, 1
+	},
+	{			/* no seed */
+		0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4,	/* p */
+		0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3,
+		0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33,
+		0x08, 0x71, 0x7D, 0x4D, 0x9B, 0x00, 0x9B, 0xC6, 0x68, 0x42,
+		0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6, 0x28, 0x81,
+		0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56,
+		0x58, 0x3A, 0x48, 0xF3,
+		0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4,	/* a */
+		0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3,
+		0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33,
+		0x08, 0x71, 0x7D, 0x4D, 0x9B, 0x00, 0x9B, 0xC6, 0x68, 0x42,
+		0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6, 0x28, 0x81,
+		0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56,
+		0x58, 0x3A, 0x48, 0xF0,
+		0x7C, 0xBB, 0xBC, 0xF9, 0x44, 0x1C, 0xFA, 0xB7, 0x6E, 0x18,	/* b */
+		0x90, 0xE4, 0x68, 0x84, 0xEA, 0xE3, 0x21, 0xF7, 0x0C, 0x0B,
+		0xCB, 0x49, 0x81, 0x52, 0x78, 0x97, 0x50, 0x4B, 0xEC, 0x3E,
+		0x36, 0xA6, 0x2B, 0xCD, 0xFA, 0x23, 0x04, 0x97, 0x65, 0x40,
+		0xF6, 0x45, 0x00, 0x85, 0xF2, 0xDA, 0xE1, 0x45, 0xC2, 0x25,
+		0x53, 0xB4, 0x65, 0x76, 0x36, 0x89, 0x18, 0x0E, 0xA2, 0x57,
+		0x18, 0x67, 0x42, 0x3E,
+		0x64, 0x0E, 0xCE, 0x5C, 0x12, 0x78, 0x87, 0x17, 0xB9, 0xC1,	/* x */
+		0xBA, 0x06, 0xCB, 0xC2, 0xA6, 0xFE, 0xBA, 0x85, 0x84, 0x24,
+		0x58, 0xC5, 0x6D, 0xDE, 0x9D, 0xB1, 0x75, 0x8D, 0x39, 0xC0,
+		0x31, 0x3D, 0x82, 0xBA, 0x51, 0x73, 0x5C, 0xDB, 0x3E, 0xA4,
+		0x99, 0xAA, 0x77, 0xA7, 0xD6, 0x94, 0x3A, 0x64, 0xF7, 0xA3,
+		0xF2, 0x5F, 0xE2, 0x6F, 0x06, 0xB5, 0x1B, 0xAA, 0x26, 0x96,
+		0xFA, 0x90, 0x35, 0xDA,
+		0x5B, 0x53, 0x4B, 0xD5, 0x95, 0xF5, 0xAF, 0x0F, 0xA2, 0xC8,	/* y */
+		0x92, 0x37, 0x6C, 0x84, 0xAC, 0xE1, 0xBB, 0x4E, 0x30, 0x19,
+		0xB7, 0x16, 0x34, 0xC0, 0x11, 0x31, 0x15, 0x9C, 0xAE, 0x03,
+		0xCE, 0xE9, 0xD9, 0x93, 0x21, 0x84, 0xBE, 0xEF, 0x21, 0x6B,
+		0xD7, 0x1D, 0xF2, 0xDA, 0xDF, 0x86, 0xA6, 0x27, 0x30, 0x6E,
+		0xCF, 0xF9, 0x6D, 0xBB, 0x8B, 0xAC, 0xE1, 0x98, 0xB6, 0x1E,
+		0x00, 0xF8, 0xB3, 0x32,
+		0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4,	/* order */
+		0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3,
+		0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33,
+		0x08, 0x70, 0x55, 0x3E, 0x5C, 0x41, 0x4C, 0xA9, 0x26, 0x19,
+		0x41, 0x86, 0x61, 0x19, 0x7F, 0xAC, 0x10, 0x47, 0x1D, 0xB1,
+		0xD3, 0x81, 0x08, 0x5D, 0xDA, 0xDD, 0xB5, 0x87, 0x96, 0x82,
+		0x9C, 0xA9, 0x00, 0x69
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 32 * 6];
+}
+ _EC_FRP256v1 = {
+	{
+		NID_X9_62_prime_field, 0, 32, 1
+	},
+	{			/* no seed */
+		0xF1, 0xFD, 0x17, 0x8C, 0x0B, 0x3A, 0xD5, 0x8F, 0x10, 0x12,	/* p */
+		0x6D, 0xE8, 0xCE, 0x42, 0x43, 0x5B, 0x39, 0x61, 0xAD, 0xBC,
+		0xAB, 0xC8, 0xCA, 0x6D, 0xE8, 0xFC, 0xF3, 0x53, 0xD8, 0x6E,
+		0x9C, 0x03,
+		0xF1, 0xFD, 0x17, 0x8C, 0x0B, 0x3A, 0xD5, 0x8F, 0x10, 0x12,	/* a */
+		0x6D, 0xE8, 0xCE, 0x42, 0x43, 0x5B, 0x39, 0x61, 0xAD, 0xBC,
+		0xAB, 0xC8, 0xCA, 0x6D, 0xE8, 0xFC, 0xF3, 0x53, 0xD8, 0x6E,
+		0x9C, 0x00,
+		0xEE, 0x35, 0x3F, 0xCA, 0x54, 0x28, 0xA9, 0x30, 0x0D, 0x4A,	/* b */
+		0xBA, 0x75, 0x4A, 0x44, 0xC0, 0x0F, 0xDF, 0xEC, 0x0C, 0x9A,
+		0xE4, 0xB1, 0xA1, 0x80, 0x30, 0x75, 0xED, 0x96, 0x7B, 0x7B,
+		0xB7, 0x3F,
+		0xB6, 0xB3, 0xD4, 0xC3, 0x56, 0xC1, 0x39, 0xEB, 0x31, 0x18,	/* x */
+		0x3D, 0x47, 0x49, 0xD4, 0x23, 0x95, 0x8C, 0x27, 0xD2, 0xDC,
+		0xAF, 0x98, 0xB7, 0x01, 0x64, 0xC9, 0x7A, 0x2D, 0xD9, 0x8F,
+		0x5C, 0xFF,
+		0x61, 0x42, 0xE0, 0xF7, 0xC8, 0xB2, 0x04, 0x91, 0x1F, 0x92,	/* y */
+		0x71, 0xF0, 0xF3, 0xEC, 0xEF, 0x8C, 0x27, 0x01, 0xC3, 0x07,
+		0xE8, 0xE4, 0xC9, 0xE1, 0x83, 0x11, 0x5A, 0x15, 0x54, 0x06,
+		0x2C, 0xFB,
+		0xF1, 0xFD, 0x17, 0x8C, 0x0B, 0x3A, 0xD5, 0x8F, 0x10, 0x12,	/* order */
+		0x6D, 0xE8, 0xCE, 0x42, 0x43, 0x5B, 0x53, 0xDC, 0x67, 0xE1,
+		0x40, 0xD2, 0xBF, 0x94, 0x1F, 0xFD, 0xD4, 0x59, 0xC6, 0xD6,
+		0x55, 0xE1
+	}
+};
+
+#ifndef OPENSSL_NO_GOST
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 32 * 6];
+}
+ _EC_GOST_2001_Test = {
+	{
+		NID_X9_62_prime_field, 0, 32, 1
+	},
+	{			/* no seed */
+		0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x04, 0x31,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x07,
+		0x5F, 0xBF, 0xF4, 0x98, 0xAA, 0x93, 0x8C, 0xE7, 0x39, 0xB8,	/* b */
+		0xE0, 0x22, 0xFB, 0xAF, 0xEF, 0x40, 0x56, 0x3F, 0x6E, 0x6A,
+		0x34, 0x72, 0xFC, 0x2A, 0x51, 0x4C, 0x0C, 0xE9, 0xDA, 0xE2,
+		0x3B, 0x7E,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* x */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x02,
+		0x08, 0xE2, 0xA8, 0xA0, 0xE6, 0x51, 0x47, 0xD4, 0xBD, 0x63,	/* y */
+		0x16, 0x03, 0x0E, 0x16, 0xD1, 0x9C, 0x85, 0xC9, 0x7F, 0x0A,
+		0x9C, 0xA2, 0x67, 0x12, 0x2B, 0x96, 0xAB, 0xBC, 0xEA, 0x7E,
+		0x8F, 0xC8,
+		0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x50, 0xFE, 0x8A, 0x18,
+		0x92, 0x97, 0x61, 0x54, 0xC5, 0x9C, 0xFC, 0x19, 0x3A, 0xCC,
+		0xF5, 0xB3,
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 32 * 6];
+}
+ _EC_GOST_2001_CryptoPro_A = {
+	{
+		NID_X9_62_prime_field, 0, 32, 1
+	},
+	{			/* no seed */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* p */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFD, 0x97,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* a */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFD, 0x94,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* b */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0xA6,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* x */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x01,
+		0x8D, 0x91, 0xE4, 0x71, 0xE0, 0x98, 0x9C, 0xDA, 0x27, 0xDF,	/* y */
+		0x50, 0x5A, 0x45, 0x3F, 0x2B, 0x76, 0x35, 0x29, 0x4F, 0x2D,
+		0xDF, 0x23, 0xE3, 0xB1, 0x22, 0xAC, 0xC9, 0x9C, 0x9E, 0x9F,
+		0x1E, 0x14,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,	/* order */
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x6C, 0x61, 0x10, 0x70,
+		0x99, 0x5A, 0xD1, 0x00, 0x45, 0x84, 0x1B, 0x09, 0xB7, 0x61,
+		0xB8, 0x93,
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 32 * 6];
+}
+ _EC_GOST_2001_CryptoPro_B = {
+	{
+		NID_X9_62_prime_field, 0, 32, 1
+	},
+	{			/* no seed */
+		0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x0C, 0x99,
+		0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x0C, 0x96,
+		0x3E, 0x1A, 0xF4, 0x19, 0xA2, 0x69, 0xA5, 0xF8, 0x66, 0xA7,	/* b */
+		0xD3, 0xC2, 0x5C, 0x3D, 0xF8, 0x0A, 0xE9, 0x79, 0x25, 0x93,
+		0x73, 0xFF, 0x2B, 0x18, 0x2F, 0x49, 0xD4, 0xCE, 0x7E, 0x1B,
+		0xBC, 0x8B,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* x */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x01,
+		0x3F, 0xA8, 0x12, 0x43, 0x59, 0xF9, 0x66, 0x80, 0xB8, 0x3D,	/* y */
+		0x1C, 0x3E, 0xB2, 0xC0, 0x70, 0xE5, 0xC5, 0x45, 0xC9, 0x85,
+		0x8D, 0x03, 0xEC, 0xFB, 0x74, 0x4B, 0xF8, 0xD7, 0x17, 0x71,
+		0x7E, 0xFC,
+		0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x5F, 0x70, 0x0C, 0xFF,
+		0xF1, 0xA6, 0x24, 0xE5, 0xE4, 0x97, 0x16, 0x1B, 0xCC, 0x8A,
+		0x19, 0x8F,
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 32 * 6];
+}
+ _EC_GOST_2001_CryptoPro_C = {
+	{
+		NID_X9_62_prime_field, 0, 32, 1
+	},
+	{			/* no seed */
+		0x9B, 0x9F, 0x60, 0x5F, 0x5A, 0x85, 0x81, 0x07, 0xAB, 0x1E,	/* p */
+		0xC8, 0x5E, 0x6B, 0x41, 0xC8, 0xAA, 0xCF, 0x84, 0x6E, 0x86,
+		0x78, 0x90, 0x51, 0xD3, 0x79, 0x98, 0xF7, 0xB9, 0x02, 0x2D,
+		0x75, 0x9B,
+		0x9B, 0x9F, 0x60, 0x5F, 0x5A, 0x85, 0x81, 0x07, 0xAB, 0x1E,	/* a */
+		0xC8, 0x5E, 0x6B, 0x41, 0xC8, 0xAA, 0xCF, 0x84, 0x6E, 0x86,
+		0x78, 0x90, 0x51, 0xD3, 0x79, 0x98, 0xF7, 0xB9, 0x02, 0x2D,
+		0x75, 0x98,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* b */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x80, 0x5A,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* x */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00,
+		0x41, 0xEC, 0xE5, 0x57, 0x43, 0x71, 0x1A, 0x8C, 0x3C, 0xBF,	/* y */
+		0x37, 0x83, 0xCD, 0x08, 0xC0, 0xEE, 0x4D, 0x4D, 0xC4, 0x40,
+		0xD4, 0x64, 0x1A, 0x8F, 0x36, 0x6E, 0x55, 0x0D, 0xFD, 0xB3,
+		0xBB, 0x67,
+		0x9B, 0x9F, 0x60, 0x5F, 0x5A, 0x85, 0x81, 0x07, 0xAB, 0x1E,	/* order */
+		0xC8, 0x5E, 0x6B, 0x41, 0xC8, 0xAA, 0x58, 0x2C, 0xA3, 0x51,
+		0x1E, 0xDD, 0xFB, 0x74, 0xF0, 0x2F, 0x3A, 0x65, 0x98, 0x98,
+		0x0B, 0xB9,
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 64 * 6];
+}
+ _EC_GOST_2012_TC26_A = {
+	{
+		NID_X9_62_prime_field, 0, 64, 1
+	},
+	{			/* no seed */
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,	/* p */
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xfd, 0xc7,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,	/* a */
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xfd, 0xc4,
+		0xe8, 0xc2, 0x50, 0x5d, 0xed, 0xfc, 0x86, 0xdd, 0xc1, 0xbd,	/* b */
+		0x0b, 0x2b, 0x66, 0x67, 0xf1, 0xda, 0x34, 0xb8, 0x25, 0x74,
+		0x76, 0x1c, 0xb0, 0xe8, 0x79, 0xbd, 0x08, 0x1c, 0xfd, 0x0b,
+		0x62, 0x65, 0xee, 0x3c, 0xb0, 0x90, 0xf3, 0x0d, 0x27, 0x61,
+		0x4c, 0xb4, 0x57, 0x40, 0x10, 0xda, 0x90, 0xdd, 0x86, 0x2e,
+		0xf9, 0xd4, 0xeb, 0xee, 0x47, 0x61, 0x50, 0x31, 0x90, 0x78,
+		0x5a, 0x71, 0xc7, 0x60,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* x */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x03,
+		0x75, 0x03, 0xcf, 0xe8, 0x7a, 0x83, 0x6a, 0xe3, 0xa6, 0x1b,	/* y */
+		0x88, 0x16, 0xe2, 0x54, 0x50, 0xe6, 0xce, 0x5e, 0x1c, 0x93,
+		0xac, 0xf1, 0xab, 0xc1, 0x77, 0x80, 0x64, 0xfd, 0xcb, 0xef,
+		0xa9, 0x21, 0xdf, 0x16, 0x26, 0xbe, 0x4f, 0xd0, 0x36, 0xe9,
+		0x3d, 0x75, 0xe6, 0xa5, 0x0e, 0x3a, 0x41, 0xe9, 0x80, 0x28,
+		0xfe, 0x5f, 0xc2, 0x35, 0xf5, 0xb8, 0x89, 0xa5, 0x89, 0xcb,
+		0x52, 0x15, 0xf2, 0xa4,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,	/* order */
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0x27, 0xe6, 0x95, 0x32, 0xf4, 0x8d, 0x89, 0x11,
+		0x6f, 0xf2, 0x2b, 0x8d, 0x4e, 0x05, 0x60, 0x60, 0x9b, 0x4b,
+		0x38, 0xab, 0xfa, 0xd2, 0xb8, 0x5d, 0xca, 0xcd, 0xb1, 0x41,
+		0x1f, 0x10, 0xb2, 0x75
+	}
+};
+
+static const struct {
+	EC_CURVE_DATA h;
+	unsigned char data[0 + 64 * 6];
+}
+ _EC_GOST_2012_TC26_B = {
+	{
+		NID_X9_62_prime_field, 0, 64, 1
+	},
+	{			/* no seed */
+		0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* p */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x6f,
+		0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* a */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x6c,
+		0x68, 0x7d, 0x1b, 0x45, 0x9d, 0xc8, 0x41, 0x45, 0x7e, 0x3e,	/* b */
+		0x06, 0xcf, 0x6f, 0x5e, 0x25, 0x17, 0xb9, 0x7c, 0x7d, 0x61,
+		0x4a, 0xf1, 0x38, 0xbc, 0xbf, 0x85, 0xdc, 0x80, 0x6c, 0x4b,
+		0x28, 0x9f, 0x3e, 0x96, 0x5d, 0x2d, 0xb1, 0x41, 0x6d, 0x21,
+		0x7f, 0x8b, 0x27, 0x6f, 0xad, 0x1a, 0xb6, 0x9c, 0x50, 0xf7,
+		0x8b, 0xee, 0x1f, 0xa3, 0x10, 0x6e, 0xfb, 0x8c, 0xcb, 0xc7,
+		0xc5, 0x14, 0x01, 0x16,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* x */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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,
+		0x1a, 0x8f, 0x7e, 0xda, 0x38, 0x9b, 0x09, 0x4c, 0x2c, 0x07,	/* y */
+		0x1e, 0x36, 0x47, 0xa8, 0x94, 0x0f, 0x3c, 0x12, 0x3b, 0x69,
+		0x75, 0x78, 0xc2, 0x13, 0xbe, 0x6d, 0xd9, 0xe6, 0xc8, 0xec,
+		0x73, 0x35, 0xdc, 0xb2, 0x28, 0xfd, 0x1e, 0xdf, 0x4a, 0x39,
+		0x15, 0x2c, 0xbc, 0xaa, 0xf8, 0xc0, 0x39, 0x88, 0x28, 0x04,
+		0x10, 0x55, 0xf9, 0x4c, 0xee, 0xec, 0x7e, 0x21, 0x34, 0x07,
+		0x80, 0xfe, 0x41, 0xbd,
+		0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* order */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x01, 0x49, 0xa1, 0xec, 0x14, 0x25, 0x65, 0xa5, 0x45,
+		0xac, 0xfd, 0xb7, 0x7b, 0xd9, 0xd4, 0x0c, 0xfa, 0x8b, 0x99,
+		0x67, 0x12, 0x10, 0x1b, 0xea, 0x0e, 0xc6, 0x34, 0x6c, 0x54,
+		0x37, 0x4f, 0x25, 0xbd
+	}
+};
+
+#endif
+
+typedef struct _ec_list_element_st {
+	int nid;
+	const EC_CURVE_DATA *data;
+	const EC_METHOD *(*meth) (void);
+	const char *comment;
+} ec_list_element;
+
+static const ec_list_element curve_list[] = {
+	/* prime field curves */
+	/* secg curves */
+	{NID_secp112r1, &_EC_SECG_PRIME_112R1.h, 0, "SECG/WTLS curve over a 112 bit prime field"},
+	{NID_secp112r2, &_EC_SECG_PRIME_112R2.h, 0, "SECG curve over a 112 bit prime field"},
+	{NID_secp128r1, &_EC_SECG_PRIME_128R1.h, 0, "SECG curve over a 128 bit prime field"},
+	{NID_secp128r2, &_EC_SECG_PRIME_128R2.h, 0, "SECG curve over a 128 bit prime field"},
+	{NID_secp160k1, &_EC_SECG_PRIME_160K1.h, 0, "SECG curve over a 160 bit prime field"},
+	{NID_secp160r1, &_EC_SECG_PRIME_160R1.h, 0, "SECG curve over a 160 bit prime field"},
+	{NID_secp160r2, &_EC_SECG_PRIME_160R2.h, 0, "SECG/WTLS curve over a 160 bit prime field"},
+	/* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */
+	{NID_secp192k1, &_EC_SECG_PRIME_192K1.h, 0, "SECG curve over a 192 bit prime field"},
+	{NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0, "SECG curve over a 224 bit prime field"},
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+	{NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method, "NIST/SECG curve over a 224 bit prime field"},
+#else
+	{NID_secp224r1, &_EC_NIST_PRIME_224.h, 0, "NIST/SECG curve over a 224 bit prime field"},
+#endif
+	{NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0, "SECG curve over a 256 bit prime field"},
+	/* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
+	{NID_secp384r1, &_EC_NIST_PRIME_384.h, 0, "NIST/SECG curve over a 384 bit prime field"},
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+	{NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method, "NIST/SECG curve over a 521 bit prime field"},
+#else
+	{NID_secp521r1, &_EC_NIST_PRIME_521.h, 0, "NIST/SECG curve over a 521 bit prime field"},
+#endif
+	/* X9.62 curves */
+	{NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0, "NIST/X9.62/SECG curve over a 192 bit prime field"},
+	{NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, 0, "X9.62 curve over a 192 bit prime field"},
+	{NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, 0, "X9.62 curve over a 192 bit prime field"},
+	{NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, 0, "X9.62 curve over a 239 bit prime field"},
+	{NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, 0, "X9.62 curve over a 239 bit prime field"},
+	{NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0, "X9.62 curve over a 239 bit prime field"},
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+	{NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, EC_GFp_nistp256_method, "X9.62/SECG curve over a 256 bit prime field"},
+#else
+	{NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, 0, "X9.62/SECG curve over a 256 bit prime field"},
+#endif
+#ifndef OPENSSL_NO_EC2M
+	/* characteristic two field curves */
+	/* NIST/SECG curves */
+	{NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, 0, "SECG curve over a 113 bit binary field"},
+	{NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, 0, "SECG curve over a 113 bit binary field"},
+	{NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, 0, "SECG/WTLS curve over a 131 bit binary field"},
+	{NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, 0, "SECG curve over a 131 bit binary field"},
+	{NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0, "NIST/SECG/WTLS curve over a 163 bit binary field"},
+	{NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, 0, "SECG curve over a 163 bit binary field"},
+	{NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0, "NIST/SECG curve over a 163 bit binary field"},
+	{NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, 0, "SECG curve over a 193 bit binary field"},
+	{NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, 0, "SECG curve over a 193 bit binary field"},
+	{NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field"},
+	{NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field"},
+	{NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, 0, "SECG curve over a 239 bit binary field"},
+	{NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0, "NIST/SECG curve over a 283 bit binary field"},
+	{NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0, "NIST/SECG curve over a 283 bit binary field"},
+	{NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0, "NIST/SECG curve over a 409 bit binary field"},
+	{NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0, "NIST/SECG curve over a 409 bit binary field"},
+	{NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0, "NIST/SECG curve over a 571 bit binary field"},
+	{NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0, "NIST/SECG curve over a 571 bit binary field"},
+	/* X9.62 curves */
+	{NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, 0, "X9.62 curve over a 163 bit binary field"},
+	{NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, 0, "X9.62 curve over a 163 bit binary field"},
+	{NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, 0, "X9.62 curve over a 163 bit binary field"},
+	{NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, 0, "X9.62 curve over a 176 bit binary field"},
+	{NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, 0, "X9.62 curve over a 191 bit binary field"},
+	{NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, 0, "X9.62 curve over a 191 bit binary field"},
+	{NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, 0, "X9.62 curve over a 191 bit binary field"},
+	{NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, 0, "X9.62 curve over a 208 bit binary field"},
+	{NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, 0, "X9.62 curve over a 239 bit binary field"},
+	{NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, 0, "X9.62 curve over a 239 bit binary field"},
+	{NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, 0, "X9.62 curve over a 239 bit binary field"},
+	{NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, 0, "X9.62 curve over a 272 bit binary field"},
+	{NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, 0, "X9.62 curve over a 304 bit binary field"},
+	{NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, 0, "X9.62 curve over a 359 bit binary field"},
+	{NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, 0, "X9.62 curve over a 368 bit binary field"},
+	{NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, 0, "X9.62 curve over a 431 bit binary field"},
+	/*
+	 * the WAP/WTLS curves [unlike SECG, spec has its own OIDs for curves
+	 * from X9.62]
+	 */
+	{NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, 0, "WTLS curve over a 113 bit binary field"},
+	{NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, 0, "NIST/SECG/WTLS curve over a 163 bit binary field"},
+	{NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, 0, "SECG curve over a 113 bit binary field"},
+	{NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, 0, "X9.62 curve over a 163 bit binary field"},
+#endif
+	{NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, 0, "SECG/WTLS curve over a 112 bit prime field"},
+	{NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, 0, "SECG/WTLS curve over a 160 bit prime field"},
+	{NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, 0, "WTLS curve over a 112 bit prime field"},
+	{NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, 0, "WTLS curve over a 160 bit prime field"},
+#ifndef OPENSSL_NO_EC2M
+	{NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field"},
+	{NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, 0, "NIST/SECG/WTLS curve over a 233 bit binary field"},
+#endif
+	{NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0, "WTLS curve over a 224 bit prime field"},
+#ifndef OPENSSL_NO_EC2M
+	/* IPSec curves */
+	{NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0, "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n"
+	"\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
+	{NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0, "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n"
+	"\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
+#endif
+	/* RFC 5639 curves */
+	{NID_brainpoolP160r1, &_EC_brainpoolP160r1.h, 0, "RFC 5639 curve over a 160 bit prime field"},
+	{NID_brainpoolP160t1, &_EC_brainpoolP160t1.h, 0, "RFC 5639 curve over a 160 bit prime field"},
+	{NID_brainpoolP192r1, &_EC_brainpoolP192r1.h, 0, "RFC 5639 curve over a 192 bit prime field"},
+	{NID_brainpoolP192t1, &_EC_brainpoolP192t1.h, 0, "RFC 5639 curve over a 192 bit prime field"},
+	{NID_brainpoolP224r1, &_EC_brainpoolP224r1.h, 0, "RFC 5639 curve over a 224 bit prime field"},
+	{NID_brainpoolP224t1, &_EC_brainpoolP224t1.h, 0, "RFC 5639 curve over a 224 bit prime field"},
+	{NID_brainpoolP256r1, &_EC_brainpoolP256r1.h, 0, "RFC 5639 curve over a 256 bit prime field"},
+	{NID_brainpoolP256t1, &_EC_brainpoolP256t1.h, 0, "RFC 5639 curve over a 256 bit prime field"},
+	{NID_brainpoolP320r1, &_EC_brainpoolP320r1.h, 0, "RFC 5639 curve over a 320 bit prime field"},
+	{NID_brainpoolP320t1, &_EC_brainpoolP320t1.h, 0, "RFC 5639 curve over a 320 bit prime field"},
+	{NID_brainpoolP384r1, &_EC_brainpoolP384r1.h, 0, "RFC 5639 curve over a 384 bit prime field"},
+	{NID_brainpoolP384t1, &_EC_brainpoolP384t1.h, 0, "RFC 5639 curve over a 384 bit prime field"},
+	{NID_brainpoolP512r1, &_EC_brainpoolP512r1.h, 0, "RFC 5639 curve over a 512 bit prime field"},
+	{NID_brainpoolP512t1, &_EC_brainpoolP512t1.h, 0, "RFC 5639 curve over a 512 bit prime field"},
+	/* ANSSI */
+	{NID_FRP256v1, &_EC_FRP256v1.h, 0, "FRP256v1"},
+#ifndef OPENSSL_NO_GOST
+	/* GOST R 34.10-2001 */
+	{NID_id_GostR3410_2001_TestParamSet, &_EC_GOST_2001_Test.h, 0, "GOST R 34.10-2001 Test Curve"},
+	{NID_id_GostR3410_2001_CryptoPro_A_ParamSet, &_EC_GOST_2001_CryptoPro_A.h, 0, "GOST R 34.10-2001 CryptoPro-A"},
+	{NID_id_GostR3410_2001_CryptoPro_B_ParamSet, &_EC_GOST_2001_CryptoPro_B.h, 0, "GOST R 34.10-2001 CryptoPro-B"},
+	{NID_id_GostR3410_2001_CryptoPro_C_ParamSet, &_EC_GOST_2001_CryptoPro_C.h, 0, "GOST R 34.10-2001 CryptoPro-C"},
+	{NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet, &_EC_GOST_2001_CryptoPro_A.h, 0, "GOST R 34.10-2001 CryptoPro-XchA"},
+	{NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet, &_EC_GOST_2001_CryptoPro_C.h, 0, "GOST R 34.10-2001 CryptoPro-XchB"},
+	{NID_id_tc26_gost_3410_2012_512_paramSetA, &_EC_GOST_2012_TC26_A.h, 0, "GOST R 34.10-2012 TC26-A"},
+	{NID_id_tc26_gost_3410_2012_512_paramSetB, &_EC_GOST_2012_TC26_B.h, 0, "GOST R 34.10-2012 TC26-B"},
+#endif
+};
+
+#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element))
+
+static EC_GROUP *
+ec_group_new_from_data(const ec_list_element curve)
+{
+	EC_GROUP *group = NULL;
+	EC_POINT *P = NULL;
+	BN_CTX *ctx = NULL;
+	BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = NULL;
+	int ok = 0;
+	int seed_len, param_len;
+	const EC_METHOD *meth;
+	const EC_CURVE_DATA *data;
+	const unsigned char *params;
+
+	if ((ctx = BN_CTX_new()) == NULL) {
+		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	data = curve.data;
+	seed_len = data->seed_len;
+	param_len = data->param_len;
+	params = (const unsigned char *) (data + 1);	/* skip header */
+	params += seed_len;	/* skip seed   */
+
+	if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
+	    !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
+	    !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
+		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
+		goto err;
+	}
+	if (curve.meth != 0) {
+		meth = curve.meth();
+		if (((group = EC_GROUP_new(meth)) == NULL) ||
+		    (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
+			ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+			goto err;
+		}
+	} else if (data->field_type == NID_X9_62_prime_field) {
+		if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
+			ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+			goto err;
+		}
+	}
+#ifndef OPENSSL_NO_EC2M
+	else {			/* field_type ==
+				 * NID_X9_62_characteristic_two_field */
+		if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) {
+			ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+			goto err;
+		}
+	}
+#endif
+
+	if ((P = EC_POINT_new(group)) == NULL) {
+		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+		goto err;
+	}
+	if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL))
+	    || !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
+		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
+		goto err;
+	}
+	if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
+		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+		goto err;
+	}
+	if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL))
+	    || !BN_set_word(x, (BN_ULONG) data->cofactor)) {
+		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
+		goto err;
+	}
+	if (!EC_GROUP_set_generator(group, P, order, x)) {
+		ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+		goto err;
+	}
+	if (seed_len) {
+		if (!EC_GROUP_set_seed(group, params - seed_len, seed_len)) {
+			ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+			goto err;
+		}
+	}
+	ok = 1;
+err:
+	if (!ok) {
+		EC_GROUP_free(group);
+		group = NULL;
+	}
+	EC_POINT_free(P);
+	BN_CTX_free(ctx);
+	BN_free(p);
+	BN_free(a);
+	BN_free(b);
+	BN_free(order);
+	BN_free(x);
+	BN_free(y);
+	return group;
+}
+
+EC_GROUP *
+EC_GROUP_new_by_curve_name(int nid)
+{
+	size_t i;
+	EC_GROUP *ret = NULL;
+
+	if (nid <= 0)
+		return NULL;
+
+	for (i = 0; i < curve_list_length; i++)
+		if (curve_list[i].nid == nid) {
+			ret = ec_group_new_from_data(curve_list[i]);
+			break;
+		}
+	if (ret == NULL) {
+		ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP);
+		return NULL;
+	}
+	EC_GROUP_set_curve_name(ret, nid);
+
+	return ret;
+}
+
+size_t 
+EC_get_builtin_curves(EC_builtin_curve * r, size_t nitems)
+{
+	size_t i, min;
+
+	if (r == NULL || nitems == 0)
+		return curve_list_length;
+
+	min = nitems < curve_list_length ? nitems : curve_list_length;
+
+	for (i = 0; i < min; i++) {
+		r[i].nid = curve_list[i].nid;
+		r[i].comment = curve_list[i].comment;
+	}
+
+	return curve_list_length;
+}
+
+/*
+ * Functions to translate between common NIST curve names and NIDs.
+ */
+
+typedef struct {
+	const char *name;	/* NIST Name of curve */
+	int nid;		/* Curve NID */
+} EC_NIST_NAME;
+
+static EC_NIST_NAME nist_curves[] = {
+	{ "B-163", NID_sect163r2 },
+	{ "B-233", NID_sect233r1 },
+	{ "B-283", NID_sect283r1 },
+	{ "B-409", NID_sect409r1 },
+	{ "B-571", NID_sect571r1 },
+	{ "K-163", NID_sect163k1 },
+	{ "K-233", NID_sect233k1 },
+	{ "K-283", NID_sect283k1 },
+	{ "K-409", NID_sect409k1 },
+	{ "K-571", NID_sect571k1 },
+	{ "P-192", NID_X9_62_prime192v1 },
+	{ "P-224", NID_secp224r1 },
+	{ "P-256", NID_X9_62_prime256v1 },
+	{ "P-384", NID_secp384r1 },
+	{ "P-521", NID_secp521r1 }
+};
+
+const char *
+EC_curve_nid2nist(int nid)
+{
+	size_t i;
+
+	for (i = 0; i < sizeof(nist_curves) / sizeof(EC_NIST_NAME); i++) {
+		if (nist_curves[i].nid == nid)
+			return (nist_curves[i].name);
+	}
+	return (NULL);
+}
+
+int
+EC_curve_nist2nid(const char *name)
+{
+	size_t i;
+
+	for (i = 0; i < sizeof(nist_curves) / sizeof(EC_NIST_NAME); i++) {
+		if (!strcmp(nist_curves[i].name, name))
+			return (nist_curves[i].nid);
+	}
+	return (NID_undef);
+}
diff --git a/crypto/libressl/crypto/ec/ec_cvt.c b/crypto/libressl/crypto/ec/ec_cvt.c
new file mode 100644
index 0000000000..52f52c5cf2
--- /dev/null
+++ b/crypto/libressl/crypto/ec/ec_cvt.c
@@ -0,0 +1,167 @@
+/* $OpenBSD: ec_cvt.c,v 1.5 2014/06/12 15:49:29 deraadt Exp $ */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#include 
+
+#include 
+#include "ec_lcl.h"
+
+EC_GROUP *
+EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b,
+    BN_CTX *ctx)
+{
+	const EC_METHOD *meth;
+	EC_GROUP *ret;
+
+#if defined(OPENSSL_BN_ASM_MONT)
+	/*
+	 * This might appear controversial, but the fact is that generic
+	 * prime method was observed to deliver better performance even
+	 * for NIST primes on a range of platforms, e.g.: 60%-15%
+	 * improvement on IA-64, ~25% on ARM, 30%-90% on P4, 20%-25%
+	 * in 32-bit build and 35%--12% in 64-bit build on Core2...
+	 * Coefficients are relative to optimized bn_nist.c for most
+	 * intensive ECDSA verify and ECDH operations for 192- and 521-
+	 * bit keys respectively. Choice of these boundary values is
+	 * arguable, because the dependency of improvement coefficient
+	 * from key length is not a "monotone" curve. For example while
+	 * 571-bit result is 23% on ARM, 384-bit one is -1%. But it's
+	 * generally faster, sometimes "respectfully" faster, sometimes
+	 * "tolerably" slower... What effectively happens is that loop
+	 * with bn_mul_add_words is put against bn_mul_mont, and the
+	 * latter "wins" on short vectors. Correct solution should be
+	 * implementing dedicated NxN multiplication subroutines for
+	 * small N. But till it materializes, let's stick to generic
+	 * prime method...
+	 *						
+	 */
+	meth = EC_GFp_mont_method();
+#else
+	meth = EC_GFp_nist_method();
+#endif
+
+	ret = EC_GROUP_new(meth);
+	if (ret == NULL)
+		return NULL;
+
+	if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) {
+		unsigned long err;
+
+		err = ERR_peek_last_error();
+
+		if (!(ERR_GET_LIB(err) == ERR_LIB_EC &&
+		    ((ERR_GET_REASON(err) == EC_R_NOT_A_NIST_PRIME) ||
+		    (ERR_GET_REASON(err) == EC_R_NOT_A_SUPPORTED_NIST_PRIME)))) {
+			/* real error */
+
+			EC_GROUP_clear_free(ret);
+			return NULL;
+		}
+		/* not an actual error, we just cannot use EC_GFp_nist_method */
+
+		ERR_clear_error();
+
+		EC_GROUP_clear_free(ret);
+		meth = EC_GFp_mont_method();
+
+		ret = EC_GROUP_new(meth);
+		if (ret == NULL)
+			return NULL;
+
+		if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) {
+			EC_GROUP_clear_free(ret);
+			return NULL;
+		}
+	}
+	return ret;
+}
+
+#ifndef OPENSSL_NO_EC2M
+EC_GROUP *
+EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b,
+    BN_CTX *ctx)
+{
+	const EC_METHOD *meth;
+	EC_GROUP *ret;
+
+	meth = EC_GF2m_simple_method();
+
+	ret = EC_GROUP_new(meth);
+	if (ret == NULL)
+		return NULL;
+
+	if (!EC_GROUP_set_curve_GF2m(ret, p, a, b, ctx)) {
+		EC_GROUP_clear_free(ret);
+		return NULL;
+	}
+	return ret;
+}
+#endif
diff --git a/crypto/libressl/crypto/ec/ec_err.c b/crypto/libressl/crypto/ec/ec_err.c
new file mode 100644
index 0000000000..e4c2c46e60
--- /dev/null
+++ b/crypto/libressl/crypto/ec/ec_err.c
@@ -0,0 +1,279 @@
+/* $OpenBSD: ec_err.c,v 1.8 2014/06/12 15:49:29 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2011 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_EC,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_EC,0,reason)
+
+static ERR_STRING_DATA EC_str_functs[] =
+{
+	{ERR_FUNC(EC_F_BN_TO_FELEM), "BN_TO_FELEM"},
+	{ERR_FUNC(EC_F_COMPUTE_WNAF), "COMPUTE_WNAF"},
+	{ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"},
+	{ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"},
+	{ERR_FUNC(EC_F_D2I_ECPRIVATEKEY), "d2i_ECPrivateKey"},
+	{ERR_FUNC(EC_F_DO_EC_KEY_PRINT), "DO_EC_KEY_PRINT"},
+	{ERR_FUNC(EC_F_ECKEY_PARAM2TYPE), "ECKEY_PARAM2TYPE"},
+	{ERR_FUNC(EC_F_ECKEY_PARAM_DECODE), "ECKEY_PARAM_DECODE"},
+	{ERR_FUNC(EC_F_ECKEY_PRIV_DECODE), "ECKEY_PRIV_DECODE"},
+	{ERR_FUNC(EC_F_ECKEY_PRIV_ENCODE), "ECKEY_PRIV_ENCODE"},
+	{ERR_FUNC(EC_F_ECKEY_PUB_DECODE), "ECKEY_PUB_DECODE"},
+	{ERR_FUNC(EC_F_ECKEY_PUB_ENCODE), "ECKEY_PUB_ENCODE"},
+	{ERR_FUNC(EC_F_ECKEY_TYPE2PARAM), "ECKEY_TYPE2PARAM"},
+	{ERR_FUNC(EC_F_ECPARAMETERS_PRINT), "ECParameters_print"},
+	{ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP), "ECParameters_print_fp"},
+	{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT), "ECPKParameters_print"},
+	{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT_FP), "ECPKParameters_print_fp"},
+	{ERR_FUNC(EC_F_ECP_NIST_MOD_192), "ECP_NIST_MOD_192"},
+	{ERR_FUNC(EC_F_ECP_NIST_MOD_224), "ECP_NIST_MOD_224"},
+	{ERR_FUNC(EC_F_ECP_NIST_MOD_256), "ECP_NIST_MOD_256"},
+	{ERR_FUNC(EC_F_ECP_NIST_MOD_521), "ECP_NIST_MOD_521"},
+	{ERR_FUNC(EC_F_EC_ASN1_GROUP2CURVE), "EC_ASN1_GROUP2CURVE"},
+	{ERR_FUNC(EC_F_EC_ASN1_GROUP2FIELDID), "EC_ASN1_GROUP2FIELDID"},
+	{ERR_FUNC(EC_F_EC_ASN1_GROUP2PARAMETERS), "EC_ASN1_GROUP2PARAMETERS"},
+	{ERR_FUNC(EC_F_EC_ASN1_GROUP2PKPARAMETERS), "EC_ASN1_GROUP2PKPARAMETERS"},
+	{ERR_FUNC(EC_F_EC_ASN1_PARAMETERS2GROUP), "EC_ASN1_PARAMETERS2GROUP"},
+	{ERR_FUNC(EC_F_EC_ASN1_PKPARAMETERS2GROUP), "EC_ASN1_PKPARAMETERS2GROUP"},
+	{ERR_FUNC(EC_F_EC_EX_DATA_SET_DATA), "EC_EX_DATA_set_data"},
+	{ERR_FUNC(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY), "EC_GF2M_MONTGOMERY_POINT_MULTIPLY"},
+	{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT), "ec_GF2m_simple_group_check_discriminant"},
+	{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE), "ec_GF2m_simple_group_set_curve"},
+	{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_OCT2POINT), "ec_GF2m_simple_oct2point"},
+	{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT2OCT), "ec_GF2m_simple_point2oct"},
+	{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES), "ec_GF2m_simple_point_get_affine_coordinates"},
+	{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES), "ec_GF2m_simple_point_set_affine_coordinates"},
+	{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES), "ec_GF2m_simple_set_compressed_coordinates"},
+	{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_DECODE), "ec_GFp_mont_field_decode"},
+	{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_ENCODE), "ec_GFp_mont_field_encode"},
+	{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_MUL), "ec_GFp_mont_field_mul"},
+	{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE), "ec_GFp_mont_field_set_to_one"},
+	{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SQR), "ec_GFp_mont_field_sqr"},
+	{ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE), "ec_GFp_mont_group_set_curve"},
+	{ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP), "EC_GFP_MONT_GROUP_SET_CURVE_GFP"},
+	{ERR_FUNC(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE), "ec_GFp_nistp224_group_set_curve"},
+	{ERR_FUNC(EC_F_EC_GFP_NISTP224_POINTS_MUL), "ec_GFp_nistp224_points_mul"},
+	{ERR_FUNC(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES), "ec_GFp_nistp224_point_get_affine_coordinates"},
+	{ERR_FUNC(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE), "ec_GFp_nistp256_group_set_curve"},
+	{ERR_FUNC(EC_F_EC_GFP_NISTP256_POINTS_MUL), "ec_GFp_nistp256_points_mul"},
+	{ERR_FUNC(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES), "ec_GFp_nistp256_point_get_affine_coordinates"},
+	{ERR_FUNC(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE), "ec_GFp_nistp521_group_set_curve"},
+	{ERR_FUNC(EC_F_EC_GFP_NISTP521_POINTS_MUL), "ec_GFp_nistp521_points_mul"},
+	{ERR_FUNC(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES), "ec_GFp_nistp521_point_get_affine_coordinates"},
+	{ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_MUL), "ec_GFp_nist_field_mul"},
+	{ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_SQR), "ec_GFp_nist_field_sqr"},
+	{ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE), "ec_GFp_nist_group_set_curve"},
+	{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT), "ec_GFp_simple_group_check_discriminant"},
+	{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE), "ec_GFp_simple_group_set_curve"},
+	{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP), "EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP"},
+	{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR), "EC_GFP_SIMPLE_GROUP_SET_GENERATOR"},
+	{ERR_FUNC(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE), "ec_GFp_simple_make_affine"},
+	{ERR_FUNC(EC_F_EC_GFP_SIMPLE_OCT2POINT), "ec_GFp_simple_oct2point"},
+	{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT2OCT), "ec_GFp_simple_point2oct"},
+	{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE), "ec_GFp_simple_points_make_affine"},
+	{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES), "ec_GFp_simple_point_get_affine_coordinates"},
+	{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP), "EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP"},
+	{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES), "ec_GFp_simple_point_set_affine_coordinates"},
+	{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP), "EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP"},
+	{ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES), "ec_GFp_simple_set_compressed_coordinates"},
+	{ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP), "EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP"},
+	{ERR_FUNC(EC_F_EC_GROUP_CHECK), "EC_GROUP_check"},
+	{ERR_FUNC(EC_F_EC_GROUP_CHECK_DISCRIMINANT), "EC_GROUP_check_discriminant"},
+	{ERR_FUNC(EC_F_EC_GROUP_COPY), "EC_GROUP_copy"},
+	{ERR_FUNC(EC_F_EC_GROUP_GET0_GENERATOR), "EC_GROUP_get0_generator"},
+	{ERR_FUNC(EC_F_EC_GROUP_GET_COFACTOR), "EC_GROUP_get_cofactor"},
+	{ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GF2M), "EC_GROUP_get_curve_GF2m"},
+	{ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GFP), "EC_GROUP_get_curve_GFp"},
+	{ERR_FUNC(EC_F_EC_GROUP_GET_DEGREE), "EC_GROUP_get_degree"},
+	{ERR_FUNC(EC_F_EC_GROUP_GET_ORDER), "EC_GROUP_get_order"},
+	{ERR_FUNC(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS), "EC_GROUP_get_pentanomial_basis"},
+	{ERR_FUNC(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS), "EC_GROUP_get_trinomial_basis"},
+	{ERR_FUNC(EC_F_EC_GROUP_NEW), "EC_GROUP_new"},
+	{ERR_FUNC(EC_F_EC_GROUP_NEW_BY_CURVE_NAME), "EC_GROUP_new_by_curve_name"},
+	{ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_DATA), "EC_GROUP_NEW_FROM_DATA"},
+	{ERR_FUNC(EC_F_EC_GROUP_PRECOMPUTE_MULT), "EC_GROUP_precompute_mult"},
+	{ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GF2M), "EC_GROUP_set_curve_GF2m"},
+	{ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GFP), "EC_GROUP_set_curve_GFp"},
+	{ERR_FUNC(EC_F_EC_GROUP_SET_EXTRA_DATA), "EC_GROUP_SET_EXTRA_DATA"},
+	{ERR_FUNC(EC_F_EC_GROUP_SET_GENERATOR), "EC_GROUP_set_generator"},
+	{ERR_FUNC(EC_F_EC_KEY_CHECK_KEY), "EC_KEY_check_key"},
+	{ERR_FUNC(EC_F_EC_KEY_COPY), "EC_KEY_copy"},
+	{ERR_FUNC(EC_F_EC_KEY_GENERATE_KEY), "EC_KEY_generate_key"},
+	{ERR_FUNC(EC_F_EC_KEY_NEW), "EC_KEY_new"},
+	{ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"},
+	{ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"},
+	{ERR_FUNC(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES), "EC_KEY_set_public_key_affine_coordinates"},
+	{ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"},
+	{ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"},
+	{ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"},
+	{ERR_FUNC(EC_F_EC_POINT_COPY), "EC_POINT_copy"},
+	{ERR_FUNC(EC_F_EC_POINT_DBL), "EC_POINT_dbl"},
+	{ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M), "EC_POINT_get_affine_coordinates_GF2m"},
+	{ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP), "EC_POINT_get_affine_coordinates_GFp"},
+	{ERR_FUNC(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP), "EC_POINT_get_Jprojective_coordinates_GFp"},
+	{ERR_FUNC(EC_F_EC_POINT_INVERT), "EC_POINT_invert"},
+	{ERR_FUNC(EC_F_EC_POINT_IS_AT_INFINITY), "EC_POINT_is_at_infinity"},
+	{ERR_FUNC(EC_F_EC_POINT_IS_ON_CURVE), "EC_POINT_is_on_curve"},
+	{ERR_FUNC(EC_F_EC_POINT_MAKE_AFFINE), "EC_POINT_make_affine"},
+	{ERR_FUNC(EC_F_EC_POINT_MUL), "EC_POINT_mul"},
+	{ERR_FUNC(EC_F_EC_POINT_NEW), "EC_POINT_new"},
+	{ERR_FUNC(EC_F_EC_POINT_OCT2POINT), "EC_POINT_oct2point"},
+	{ERR_FUNC(EC_F_EC_POINT_POINT2OCT), "EC_POINT_point2oct"},
+	{ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M), "EC_POINT_set_affine_coordinates_GF2m"},
+	{ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP), "EC_POINT_set_affine_coordinates_GFp"},
+	{ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M), "EC_POINT_set_compressed_coordinates_GF2m"},
+	{ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP), "EC_POINT_set_compressed_coordinates_GFp"},
+	{ERR_FUNC(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP), "EC_POINT_set_Jprojective_coordinates_GFp"},
+	{ERR_FUNC(EC_F_EC_POINT_SET_TO_INFINITY), "EC_POINT_set_to_infinity"},
+	{ERR_FUNC(EC_F_EC_PRE_COMP_DUP), "EC_PRE_COMP_DUP"},
+	{ERR_FUNC(EC_F_EC_PRE_COMP_NEW), "EC_PRE_COMP_NEW"},
+	{ERR_FUNC(EC_F_EC_WNAF_MUL), "ec_wNAF_mul"},
+	{ERR_FUNC(EC_F_EC_WNAF_PRECOMPUTE_MULT), "ec_wNAF_precompute_mult"},
+	{ERR_FUNC(EC_F_I2D_ECPARAMETERS), "i2d_ECParameters"},
+	{ERR_FUNC(EC_F_I2D_ECPKPARAMETERS), "i2d_ECPKParameters"},
+	{ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"},
+	{ERR_FUNC(EC_F_I2O_ECPUBLICKEY), "i2o_ECPublicKey"},
+	{ERR_FUNC(EC_F_NISTP224_PRE_COMP_NEW), "NISTP224_PRE_COMP_NEW"},
+	{ERR_FUNC(EC_F_NISTP256_PRE_COMP_NEW), "NISTP256_PRE_COMP_NEW"},
+	{ERR_FUNC(EC_F_NISTP521_PRE_COMP_NEW), "NISTP521_PRE_COMP_NEW"},
+	{ERR_FUNC(EC_F_O2I_ECPUBLICKEY), "o2i_ECPublicKey"},
+	{ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE), "OLD_EC_PRIV_DECODE"},
+	{ERR_FUNC(EC_F_PKEY_EC_CTRL), "PKEY_EC_CTRL"},
+	{ERR_FUNC(EC_F_PKEY_EC_CTRL_STR), "PKEY_EC_CTRL_STR"},
+	{ERR_FUNC(EC_F_PKEY_EC_DERIVE), "PKEY_EC_DERIVE"},
+	{ERR_FUNC(EC_F_PKEY_EC_KEYGEN), "PKEY_EC_KEYGEN"},
+	{ERR_FUNC(EC_F_PKEY_EC_PARAMGEN), "PKEY_EC_PARAMGEN"},
+	{ERR_FUNC(EC_F_PKEY_EC_SIGN), "PKEY_EC_SIGN"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA EC_str_reasons[] =
+{
+	{ERR_REASON(EC_R_ASN1_ERROR), "asn1 error"},
+	{ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD), "asn1 unknown field"},
+	{ERR_REASON(EC_R_BIGNUM_OUT_OF_RANGE), "bignum out of range"},
+	{ERR_REASON(EC_R_BUFFER_TOO_SMALL), "buffer too small"},
+	{ERR_REASON(EC_R_COORDINATES_OUT_OF_RANGE), "coordinates out of range"},
+	{ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE), "d2i ecpkparameters failure"},
+	{ERR_REASON(EC_R_DECODE_ERROR), "decode error"},
+	{ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO), "discriminant is zero"},
+	{ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE), "ec group new by name failure"},
+	{ERR_REASON(EC_R_FIELD_TOO_LARGE), "field too large"},
+	{ERR_REASON(EC_R_GF2M_NOT_SUPPORTED), "gf2m not supported"},
+	{ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE), "group2pkparameters failure"},
+	{ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE), "i2d ecpkparameters failure"},
+	{ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS), "incompatible objects"},
+	{ERR_REASON(EC_R_INVALID_ARGUMENT), "invalid argument"},
+	{ERR_REASON(EC_R_INVALID_COMPRESSED_POINT), "invalid compressed point"},
+	{ERR_REASON(EC_R_INVALID_COMPRESSION_BIT), "invalid compression bit"},
+	{ERR_REASON(EC_R_INVALID_CURVE), "invalid curve"},
+	{ERR_REASON(EC_R_INVALID_DIGEST_TYPE), "invalid digest type"},
+	{ERR_REASON(EC_R_INVALID_ENCODING), "invalid encoding"},
+	{ERR_REASON(EC_R_INVALID_FIELD), "invalid field"},
+	{ERR_REASON(EC_R_INVALID_FORM), "invalid form"},
+	{ERR_REASON(EC_R_INVALID_GROUP_ORDER), "invalid group order"},
+	{ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"},
+	{ERR_REASON(EC_R_INVALID_PRIVATE_KEY), "invalid private key"},
+	{ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS), "invalid trinomial basis"},
+	{ERR_REASON(EC_R_KEYS_NOT_SET), "keys not set"},
+	{ERR_REASON(EC_R_MISSING_PARAMETERS), "missing parameters"},
+	{ERR_REASON(EC_R_MISSING_PRIVATE_KEY), "missing private key"},
+	{ERR_REASON(EC_R_NOT_A_NIST_PRIME), "not a NIST prime"},
+	{ERR_REASON(EC_R_NOT_A_SUPPORTED_NIST_PRIME), "not a supported NIST prime"},
+	{ERR_REASON(EC_R_NOT_IMPLEMENTED), "not implemented"},
+	{ERR_REASON(EC_R_NOT_INITIALIZED), "not initialized"},
+	{ERR_REASON(EC_R_NO_FIELD_MOD), "no field mod"},
+	{ERR_REASON(EC_R_NO_PARAMETERS_SET), "no parameters set"},
+	{ERR_REASON(EC_R_PASSED_NULL_PARAMETER), "passed null parameter"},
+	{ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE), "pkparameters2group failure"},
+	{ERR_REASON(EC_R_POINT_AT_INFINITY), "point at infinity"},
+	{ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE), "point is not on curve"},
+	{ERR_REASON(EC_R_SLOT_FULL), "slot full"},
+	{ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"},
+	{ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"},
+	{ERR_REASON(EC_R_UNKNOWN_GROUP), "unknown group"},
+	{ERR_REASON(EC_R_UNKNOWN_ORDER), "unknown order"},
+	{ERR_REASON(EC_R_UNSUPPORTED_FIELD), "unsupported field"},
+	{ERR_REASON(EC_R_WRONG_CURVE_PARAMETERS), "wrong curve parameters"},
+	{ERR_REASON(EC_R_WRONG_ORDER), "wrong order"},
+	{0, NULL}
+};
+
+#endif
+
+void 
+ERR_load_EC_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(EC_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, EC_str_functs);
+		ERR_load_strings(0, EC_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/ec/ec_key.c b/crypto/libressl/crypto/ec/ec_key.c
new file mode 100644
index 0000000000..2aabea3f00
--- /dev/null
+++ b/crypto/libressl/crypto/ec/ec_key.c
@@ -0,0 +1,540 @@
+/* $OpenBSD: ec_key.c,v 1.11 2015/02/09 15:49:22 jsing Exp $ */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions originally developed by SUN MICROSYSTEMS, INC., and
+ * contributed to the OpenSSL project.
+ */
+
+#include 
+
+#include 
+
+#include "ec_lcl.h"
+#include 
+
+EC_KEY *
+EC_KEY_new(void)
+{
+	EC_KEY *ret;
+
+	ret = malloc(sizeof(EC_KEY));
+	if (ret == NULL) {
+		ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE);
+		return (NULL);
+	}
+	ret->version = 1;
+	ret->flags = 0;
+	ret->group = NULL;
+	ret->pub_key = NULL;
+	ret->priv_key = NULL;
+	ret->enc_flag = 0;
+	ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
+	ret->references = 1;
+	ret->method_data = NULL;
+	return (ret);
+}
+
+EC_KEY *
+EC_KEY_new_by_curve_name(int nid)
+{
+	EC_KEY *ret = EC_KEY_new();
+	if (ret == NULL)
+		return NULL;
+	ret->group = EC_GROUP_new_by_curve_name(nid);
+	if (ret->group == NULL) {
+		EC_KEY_free(ret);
+		return NULL;
+	}
+	return ret;
+}
+
+void 
+EC_KEY_free(EC_KEY * r)
+{
+	int i;
+
+	if (r == NULL)
+		return;
+
+	i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_EC);
+	if (i > 0)
+		return;
+
+	EC_GROUP_free(r->group);
+	EC_POINT_free(r->pub_key);
+	BN_clear_free(r->priv_key);
+
+	EC_EX_DATA_free_all_data(&r->method_data);
+
+	explicit_bzero((void *) r, sizeof(EC_KEY));
+
+	free(r);
+}
+
+EC_KEY *
+EC_KEY_copy(EC_KEY * dest, const EC_KEY * src)
+{
+	EC_EXTRA_DATA *d;
+
+	if (dest == NULL || src == NULL) {
+		ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
+		return NULL;
+	}
+	/* copy the parameters */
+	if (src->group) {
+		const EC_METHOD *meth = EC_GROUP_method_of(src->group);
+		/* clear the old group */
+		EC_GROUP_free(dest->group);
+		dest->group = EC_GROUP_new(meth);
+		if (dest->group == NULL)
+			return NULL;
+		if (!EC_GROUP_copy(dest->group, src->group))
+			return NULL;
+	}
+	/* copy the public key */
+	if (src->pub_key && src->group) {
+		EC_POINT_free(dest->pub_key);
+		dest->pub_key = EC_POINT_new(src->group);
+		if (dest->pub_key == NULL)
+			return NULL;
+		if (!EC_POINT_copy(dest->pub_key, src->pub_key))
+			return NULL;
+	}
+	/* copy the private key */
+	if (src->priv_key) {
+		if (dest->priv_key == NULL) {
+			dest->priv_key = BN_new();
+			if (dest->priv_key == NULL)
+				return NULL;
+		}
+		if (!BN_copy(dest->priv_key, src->priv_key))
+			return NULL;
+	}
+	/* copy method/extra data */
+	EC_EX_DATA_free_all_data(&dest->method_data);
+
+	for (d = src->method_data; d != NULL; d = d->next) {
+		void *t = d->dup_func(d->data);
+
+		if (t == NULL)
+			return 0;
+		if (!EC_EX_DATA_set_data(&dest->method_data, t, d->dup_func,
+		    d->free_func, d->clear_free_func))
+			return 0;
+	}
+
+	/* copy the rest */
+	dest->enc_flag = src->enc_flag;
+	dest->conv_form = src->conv_form;
+	dest->version = src->version;
+	dest->flags = src->flags;
+
+	return dest;
+}
+
+EC_KEY *
+EC_KEY_dup(const EC_KEY * ec_key)
+{
+	EC_KEY *ret = EC_KEY_new();
+	if (ret == NULL)
+		return NULL;
+	if (EC_KEY_copy(ret, ec_key) == NULL) {
+		EC_KEY_free(ret);
+		return NULL;
+	}
+	return ret;
+}
+
+int 
+EC_KEY_up_ref(EC_KEY * r)
+{
+	int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC);
+	return ((i > 1) ? 1 : 0);
+}
+
+int 
+EC_KEY_generate_key(EC_KEY * eckey)
+{
+	int ok = 0;
+	BN_CTX *ctx = NULL;
+	BIGNUM *priv_key = NULL, *order = NULL;
+	EC_POINT *pub_key = NULL;
+
+	if (!eckey || !eckey->group) {
+		ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	if ((order = BN_new()) == NULL)
+		goto err;
+	if ((ctx = BN_CTX_new()) == NULL)
+		goto err;
+
+	if (eckey->priv_key == NULL) {
+		priv_key = BN_new();
+		if (priv_key == NULL)
+			goto err;
+	} else
+		priv_key = eckey->priv_key;
+
+	if (!EC_GROUP_get_order(eckey->group, order, ctx))
+		goto err;
+
+	do
+		if (!BN_rand_range(priv_key, order))
+			goto err;
+	while (BN_is_zero(priv_key));
+
+	if (eckey->pub_key == NULL) {
+		pub_key = EC_POINT_new(eckey->group);
+		if (pub_key == NULL)
+			goto err;
+	} else
+		pub_key = eckey->pub_key;
+
+	if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx))
+		goto err;
+
+	eckey->priv_key = priv_key;
+	eckey->pub_key = pub_key;
+
+	ok = 1;
+
+err:
+	BN_free(order);
+	if (pub_key != NULL && eckey->pub_key == NULL)
+		EC_POINT_free(pub_key);
+	if (priv_key != NULL && eckey->priv_key == NULL)
+		BN_free(priv_key);
+	BN_CTX_free(ctx);
+	return (ok);
+}
+
+int 
+EC_KEY_check_key(const EC_KEY * eckey)
+{
+	int ok = 0;
+	BN_CTX *ctx = NULL;
+	const BIGNUM *order = NULL;
+	EC_POINT *point = NULL;
+
+	if (!eckey || !eckey->group || !eckey->pub_key) {
+		ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key) > 0) {
+		ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY);
+		goto err;
+	}
+	if ((ctx = BN_CTX_new()) == NULL)
+		goto err;
+	if ((point = EC_POINT_new(eckey->group)) == NULL)
+		goto err;
+
+	/* testing whether the pub_key is on the elliptic curve */
+	if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) {
+		ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
+		goto err;
+	}
+	/* testing whether pub_key * order is the point at infinity */
+	order = &eckey->group->order;
+	if (BN_is_zero(order)) {
+		ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
+		goto err;
+	}
+	if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
+		ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
+		goto err;
+	}
+	if (EC_POINT_is_at_infinity(eckey->group, point) <= 0) {
+		ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
+		goto err;
+	}
+	/*
+	 * in case the priv_key is present : check if generator * priv_key ==
+	 * pub_key
+	 */
+	if (eckey->priv_key) {
+		if (BN_cmp(eckey->priv_key, order) >= 0) {
+			ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
+			goto err;
+		}
+		if (!EC_POINT_mul(eckey->group, point, eckey->priv_key,
+			NULL, NULL, ctx)) {
+			ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
+			goto err;
+		}
+		if (EC_POINT_cmp(eckey->group, point, eckey->pub_key,
+			ctx) != 0) {
+			ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY);
+			goto err;
+		}
+	}
+	ok = 1;
+err:
+	BN_CTX_free(ctx);
+	EC_POINT_free(point);
+	return (ok);
+}
+
+int 
+EC_KEY_set_public_key_affine_coordinates(EC_KEY * key, BIGNUM * x, BIGNUM * y)
+{
+	BN_CTX *ctx = NULL;
+	BIGNUM *tx, *ty;
+	EC_POINT *point = NULL;
+	int ok = 0, tmp_nid, is_char_two = 0;
+
+	if (!key || !key->group || !x || !y) {
+		ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	ctx = BN_CTX_new();
+	if (!ctx)
+		goto err;
+
+	point = EC_POINT_new(key->group);
+
+	if (!point)
+		goto err;
+
+	tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group));
+
+	if (tmp_nid == NID_X9_62_characteristic_two_field)
+		is_char_two = 1;
+
+	if ((tx = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((ty = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+#ifndef OPENSSL_NO_EC2M
+	if (is_char_two) {
+		if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point,
+			x, y, ctx))
+			goto err;
+		if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point,
+			tx, ty, ctx))
+			goto err;
+	} else
+#endif
+	{
+		if (!EC_POINT_set_affine_coordinates_GFp(key->group, point,
+			x, y, ctx))
+			goto err;
+		if (!EC_POINT_get_affine_coordinates_GFp(key->group, point,
+			tx, ty, ctx))
+			goto err;
+	}
+	/*
+	 * Check if retrieved coordinates match originals: if not values are
+	 * out of range.
+	 */
+	if (BN_cmp(x, tx) || BN_cmp(y, ty)) {
+		ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
+		    EC_R_COORDINATES_OUT_OF_RANGE);
+		goto err;
+	}
+	if (!EC_KEY_set_public_key(key, point))
+		goto err;
+
+	if (EC_KEY_check_key(key) == 0)
+		goto err;
+
+	ok = 1;
+
+err:
+	BN_CTX_free(ctx);
+	EC_POINT_free(point);
+	return ok;
+
+}
+
+const EC_GROUP *
+EC_KEY_get0_group(const EC_KEY * key)
+{
+	return key->group;
+}
+
+int 
+EC_KEY_set_group(EC_KEY * key, const EC_GROUP * group)
+{
+	EC_GROUP_free(key->group);
+	key->group = EC_GROUP_dup(group);
+	return (key->group == NULL) ? 0 : 1;
+}
+
+const BIGNUM *
+EC_KEY_get0_private_key(const EC_KEY * key)
+{
+	return key->priv_key;
+}
+
+int 
+EC_KEY_set_private_key(EC_KEY * key, const BIGNUM * priv_key)
+{
+	BN_clear_free(key->priv_key);
+	key->priv_key = BN_dup(priv_key);
+	return (key->priv_key == NULL) ? 0 : 1;
+}
+
+const EC_POINT *
+EC_KEY_get0_public_key(const EC_KEY * key)
+{
+	return key->pub_key;
+}
+
+int 
+EC_KEY_set_public_key(EC_KEY * key, const EC_POINT * pub_key)
+{
+	EC_POINT_free(key->pub_key);
+	key->pub_key = EC_POINT_dup(pub_key, key->group);
+	return (key->pub_key == NULL) ? 0 : 1;
+}
+
+unsigned int 
+EC_KEY_get_enc_flags(const EC_KEY * key)
+{
+	return key->enc_flag;
+}
+
+void 
+EC_KEY_set_enc_flags(EC_KEY * key, unsigned int flags)
+{
+	key->enc_flag = flags;
+}
+
+point_conversion_form_t 
+EC_KEY_get_conv_form(const EC_KEY * key)
+{
+	return key->conv_form;
+}
+
+void 
+EC_KEY_set_conv_form(EC_KEY * key, point_conversion_form_t cform)
+{
+	key->conv_form = cform;
+	if (key->group != NULL)
+		EC_GROUP_set_point_conversion_form(key->group, cform);
+}
+
+void *
+EC_KEY_get_key_method_data(EC_KEY *key,
+    void *(*dup_func) (void *),
+    void (*free_func) (void *),
+    void (*clear_free_func) (void *))
+{
+	void *ret;
+
+	CRYPTO_r_lock(CRYPTO_LOCK_EC);
+	ret = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
+	CRYPTO_r_unlock(CRYPTO_LOCK_EC);
+
+	return ret;
+}
+
+void *
+EC_KEY_insert_key_method_data(EC_KEY * key, void *data,
+    void *(*dup_func) (void *),
+    void (*free_func) (void *),
+    void (*clear_free_func) (void *))
+{
+	EC_EXTRA_DATA *ex_data;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_EC);
+	ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
+	if (ex_data == NULL)
+		EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func);
+	CRYPTO_w_unlock(CRYPTO_LOCK_EC);
+
+	return ex_data;
+}
+
+void 
+EC_KEY_set_asn1_flag(EC_KEY * key, int flag)
+{
+	if (key->group != NULL)
+		EC_GROUP_set_asn1_flag(key->group, flag);
+}
+
+int 
+EC_KEY_precompute_mult(EC_KEY * key, BN_CTX * ctx)
+{
+	if (key->group == NULL)
+		return 0;
+	return EC_GROUP_precompute_mult(key->group, ctx);
+}
+
+int 
+EC_KEY_get_flags(const EC_KEY * key)
+{
+	return key->flags;
+}
+
+void 
+EC_KEY_set_flags(EC_KEY * key, int flags)
+{
+	key->flags |= flags;
+}
+
+void 
+EC_KEY_clear_flags(EC_KEY * key, int flags)
+{
+	key->flags &= ~flags;
+}
diff --git a/crypto/libressl/crypto/ec/ec_lcl.h b/crypto/libressl/crypto/ec/ec_lcl.h
new file mode 100644
index 0000000000..ce762403e5
--- /dev/null
+++ b/crypto/libressl/crypto/ec/ec_lcl.h
@@ -0,0 +1,446 @@
+/* $OpenBSD$ */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2010 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by 
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+
+#include 
+
+#include 
+#include 
+#include 
+
+#if defined(__SUNPRO_C)
+# if __SUNPRO_C >= 0x520
+# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
+# endif
+#endif
+
+/* Use default functions for poin2oct, oct2point and compressed coordinates */
+#define EC_FLAGS_DEFAULT_OCT	0x1
+
+/* Structure details are not part of the exported interface,
+ * so all this may change in future versions. */
+
+struct ec_method_st {
+	/* Various method flags */
+	int flags;
+	/* used by EC_METHOD_get_field_type: */
+	int field_type; /* a NID */
+
+	/* used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free, EC_GROUP_copy: */
+	int (*group_init)(EC_GROUP *);
+	void (*group_finish)(EC_GROUP *);
+	void (*group_clear_finish)(EC_GROUP *);
+	int (*group_copy)(EC_GROUP *, const EC_GROUP *);
+
+	/* used by EC_GROUP_set_curve_GFp, EC_GROUP_get_curve_GFp, */
+	/* EC_GROUP_set_curve_GF2m, and EC_GROUP_get_curve_GF2m: */
+	int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+	int (*group_get_curve)(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
+
+	/* used by EC_GROUP_get_degree: */
+	int (*group_get_degree)(const EC_GROUP *);
+
+	/* used by EC_GROUP_check: */
+	int (*group_check_discriminant)(const EC_GROUP *, BN_CTX *);
+
+	/* used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, EC_POINT_copy: */
+	int (*point_init)(EC_POINT *);
+	void (*point_finish)(EC_POINT *);
+	void (*point_clear_finish)(EC_POINT *);
+	int (*point_copy)(EC_POINT *, const EC_POINT *);
+
+	/* used by EC_POINT_set_to_infinity,
+	 * EC_POINT_set_Jprojective_coordinates_GFp,
+	 * EC_POINT_get_Jprojective_coordinates_GFp,
+	 * EC_POINT_set_affine_coordinates_GFp,     ..._GF2m,
+	 * EC_POINT_get_affine_coordinates_GFp,     ..._GF2m,
+	 * EC_POINT_set_compressed_coordinates_GFp, ..._GF2m:
+	 */
+	int (*point_set_to_infinity)(const EC_GROUP *, EC_POINT *);
+	int (*point_set_Jprojective_coordinates_GFp)(const EC_GROUP *, EC_POINT *,
+		const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
+	int (*point_get_Jprojective_coordinates_GFp)(const EC_GROUP *, const EC_POINT *,
+		BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
+	int (*point_set_affine_coordinates)(const EC_GROUP *, EC_POINT *,
+		const BIGNUM *x, const BIGNUM *y, BN_CTX *);
+	int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *,
+		BIGNUM *x, BIGNUM *y, BN_CTX *);
+	int (*point_set_compressed_coordinates)(const EC_GROUP *, EC_POINT *,
+		const BIGNUM *x, int y_bit, BN_CTX *);
+
+	/* used by EC_POINT_point2oct, EC_POINT_oct2point: */
+	size_t (*point2oct)(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
+	        unsigned char *buf, size_t len, BN_CTX *);
+	int (*oct2point)(const EC_GROUP *, EC_POINT *,
+	        const unsigned char *buf, size_t len, BN_CTX *);
+
+	/* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */
+	int (*add)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
+	int (*dbl)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
+	int (*invert)(const EC_GROUP *, EC_POINT *, BN_CTX *);
+
+	/* used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp: */
+	int (*is_at_infinity)(const EC_GROUP *, const EC_POINT *);
+	int (*is_on_curve)(const EC_GROUP *, const EC_POINT *, BN_CTX *);
+	int (*point_cmp)(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
+
+	/* used by EC_POINT_make_affine, EC_POINTs_make_affine: */
+	int (*make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *);
+	int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
+
+	/* used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult, EC_POINT_have_precompute_mult
+	 * (default implementations are used if the 'mul' pointer is 0): */
+	int (*mul)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+		size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
+	int (*precompute_mult)(EC_GROUP *group, BN_CTX *);
+	int (*have_precompute_mult)(const EC_GROUP *group);
+
+
+	/* internal functions */
+
+	/* 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and 'dbl' so that
+	 * the same implementations of point operations can be used with different
+	 * optimized implementations of expensive field operations: */
+	int (*field_mul)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+	int (*field_sqr)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
+	int (*field_div)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+
+	int (*field_encode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. to Montgomery */
+	int (*field_decode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. from Montgomery */
+	int (*field_set_to_one)(const EC_GROUP *, BIGNUM *r, BN_CTX *);
+} /* EC_METHOD */;
+
+typedef struct ec_extra_data_st {
+	struct ec_extra_data_st *next;
+	void *data;
+	void *(*dup_func)(void *);
+	void (*free_func)(void *);
+	void (*clear_free_func)(void *);
+} EC_EXTRA_DATA; /* used in EC_GROUP */
+
+struct ec_group_st {
+	const EC_METHOD *meth;
+
+	EC_POINT *generator; /* optional */
+	BIGNUM order, cofactor;
+
+	int curve_name;/* optional NID for named curve */
+	int asn1_flag; /* flag to control the asn1 encoding */
+	point_conversion_form_t asn1_form;
+
+	unsigned char *seed; /* optional seed for parameters (appears in ASN1) */
+	size_t seed_len;
+
+	EC_EXTRA_DATA *extra_data; /* linked list */
+
+	/* The following members are handled by the method functions,
+	 * even if they appear generic */
+	
+	BIGNUM field; /* Field specification.
+	               * For curves over GF(p), this is the modulus;
+	               * for curves over GF(2^m), this is the 
+	               * irreducible polynomial defining the field.
+	               */
+
+	int poly[6]; /* Field specification for curves over GF(2^m).
+	              * The irreducible f(t) is then of the form:
+	              *     t^poly[0] + t^poly[1] + ... + t^poly[k]
+	              * where m = poly[0] > poly[1] > ... > poly[k] = 0.
+	              * The array is terminated with poly[k+1]=-1.
+	              * All elliptic curve irreducibles have at most 5
+	              * non-zero terms.
+	              */
+
+	BIGNUM a, b; /* Curve coefficients.
+	              * (Here the assumption is that BIGNUMs can be used
+	              * or abused for all kinds of fields, not just GF(p).)
+	              * For characteristic  > 3,  the curve is defined
+	              * by a Weierstrass equation of the form
+	              *     y^2 = x^3 + a*x + b.
+	              * For characteristic  2,  the curve is defined by
+	              * an equation of the form
+	              *     y^2 + x*y = x^3 + a*x^2 + b.
+	              */
+
+	int a_is_minus3; /* enable optimized point arithmetics for special case */
+
+	void *field_data1; /* method-specific (e.g., Montgomery structure) */
+	void *field_data2; /* method-specific */
+	int (*field_mod_func)(BIGNUM *, const BIGNUM *, const BIGNUM *,	BN_CTX *); /* method-specific */
+} /* EC_GROUP */;
+
+struct ec_key_st {
+	int version;
+
+	EC_GROUP *group;
+
+	EC_POINT *pub_key;
+	BIGNUM	 *priv_key;
+
+	unsigned int enc_flag;
+	point_conversion_form_t conv_form;
+
+	int 	references;
+	int	flags;
+
+	EC_EXTRA_DATA *method_data;
+} /* EC_KEY */;
+
+/* Basically a 'mixin' for extra data, but available for EC_GROUPs/EC_KEYs only
+ * (with visibility limited to 'package' level for now).
+ * We use the function pointers as index for retrieval; this obviates
+ * global ex_data-style index tables.
+ */
+int EC_EX_DATA_set_data(EC_EXTRA_DATA **, void *data,
+	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
+void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *,
+	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
+void EC_EX_DATA_free_data(EC_EXTRA_DATA **,
+	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
+void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **,
+	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
+void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **);
+void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **);
+
+
+
+struct ec_point_st {
+	const EC_METHOD *meth;
+
+	/* All members except 'meth' are handled by the method functions,
+	 * even if they appear generic */
+
+	BIGNUM X;
+	BIGNUM Y;
+	BIGNUM Z; /* Jacobian projective coordinates:
+	           * (X, Y, Z)  represents  (X/Z^2, Y/Z^3)  if  Z != 0 */
+	int Z_is_one; /* enable optimized point arithmetics for special case */
+} /* EC_POINT */;
+
+
+
+/* method functions in ec_mult.c
+ * (ec_lib.c uses these as defaults if group->method->mul is 0) */
+int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+	size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
+int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *);
+int ec_wNAF_have_precompute_mult(const EC_GROUP *group);
+
+
+/* method functions in ecp_smpl.c */
+int ec_GFp_simple_group_init(EC_GROUP *);
+void ec_GFp_simple_group_finish(EC_GROUP *);
+void ec_GFp_simple_group_clear_finish(EC_GROUP *);
+int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *);
+int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
+int ec_GFp_simple_group_get_degree(const EC_GROUP *);
+int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
+int ec_GFp_simple_point_init(EC_POINT *);
+void ec_GFp_simple_point_finish(EC_POINT *);
+void ec_GFp_simple_point_clear_finish(EC_POINT *);
+int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *);
+int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
+int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *,
+	const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
+int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
+	BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
+int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
+	const BIGNUM *x, const BIGNUM *y, BN_CTX *);
+int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *, const EC_POINT *,
+	BIGNUM *x, BIGNUM *y, BN_CTX *);
+int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
+	const BIGNUM *x, int y_bit, BN_CTX *);
+size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
+	unsigned char *buf, size_t len, BN_CTX *);
+int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *,
+	const unsigned char *buf, size_t len, BN_CTX *);
+int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
+int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
+int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
+int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
+int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
+int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
+int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
+
+
+/* method functions in ecp_mont.c */
+int ec_GFp_mont_group_init(EC_GROUP *);
+int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+void ec_GFp_mont_group_finish(EC_GROUP *);
+void ec_GFp_mont_group_clear_finish(EC_GROUP *);
+int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *);
+int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
+int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
+int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
+int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *);
+
+
+/* method functions in ecp_nist.c */
+int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src);
+int ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
+
+
+/* method functions in ec2_smpl.c */
+int ec_GF2m_simple_group_init(EC_GROUP *);
+void ec_GF2m_simple_group_finish(EC_GROUP *);
+void ec_GF2m_simple_group_clear_finish(EC_GROUP *);
+int ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *);
+int ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
+int ec_GF2m_simple_group_get_degree(const EC_GROUP *);
+int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
+int ec_GF2m_simple_point_init(EC_POINT *);
+void ec_GF2m_simple_point_finish(EC_POINT *);
+void ec_GF2m_simple_point_clear_finish(EC_POINT *);
+int ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *);
+int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
+int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
+	const BIGNUM *x, const BIGNUM *y, BN_CTX *);
+int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *, const EC_POINT *,
+	BIGNUM *x, BIGNUM *y, BN_CTX *);
+int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
+	const BIGNUM *x, int y_bit, BN_CTX *);
+size_t ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
+	unsigned char *buf, size_t len, BN_CTX *);
+int ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *,
+	const unsigned char *buf, size_t len, BN_CTX *);
+int ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
+int ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
+int ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
+int ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
+int ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
+int ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
+int ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
+int ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+
+
+/* method functions in ec2_mult.c */
+int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+	size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
+int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
+
+/* method functions in ec2_mult.c */
+int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+	size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
+int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
+
+#ifndef OPENSSL_EC_NISTP_64_GCC_128
+/* method functions in ecp_nistp224.c */
+int ec_GFp_nistp224_group_init(EC_GROUP *group);
+int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *);
+int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
+int ec_GFp_nistp224_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
+int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx);
+int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group);
+
+/* method functions in ecp_nistp256.c */
+int ec_GFp_nistp256_group_init(EC_GROUP *group);
+int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *);
+int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
+int ec_GFp_nistp256_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
+int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx);
+int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group);
+
+/* method functions in ecp_nistp521.c */
+int ec_GFp_nistp521_group_init(EC_GROUP *group);
+int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *);
+int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
+int ec_GFp_nistp521_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
+int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx);
+int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group);
+
+/* utility functions in ecp_nistputil.c */
+void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
+	size_t felem_size, void *tmp_felems,
+	void (*felem_one)(void *out),
+	int (*felem_is_zero)(const void *in),
+	void (*felem_assign)(void *out, const void *in),
+	void (*felem_square)(void *out, const void *in),
+	void (*felem_mul)(void *out, const void *in1, const void *in2),
+	void (*felem_inv)(void *out, const void *in),
+	void (*felem_contract)(void *out, const void *in));
+void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, unsigned char *digit, unsigned char in);
+#endif
diff --git a/crypto/libressl/crypto/ec/ec_lib.c b/crypto/libressl/crypto/ec/ec_lib.c
new file mode 100644
index 0000000000..bc06587d0e
--- /dev/null
+++ b/crypto/libressl/crypto/ec/ec_lib.c
@@ -0,0 +1,1120 @@
+/* $OpenBSD: ec_lib.c,v 1.19 2015/09/10 15:56:25 jsing Exp $ */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Binary polynomial ECC support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+#include "ec_lcl.h"
+
+/* functions for EC_GROUP objects */
+
+EC_GROUP *
+EC_GROUP_new(const EC_METHOD * meth)
+{
+	EC_GROUP *ret;
+
+	if (meth == NULL) {
+		ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL);
+		return NULL;
+	}
+	if (meth->group_init == 0) {
+		ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return NULL;
+	}
+	ret = malloc(sizeof *ret);
+	if (ret == NULL) {
+		ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	ret->meth = meth;
+
+	ret->extra_data = NULL;
+
+	ret->generator = NULL;
+	BN_init(&ret->order);
+	BN_init(&ret->cofactor);
+
+	ret->curve_name = 0;
+	ret->asn1_flag = 0;
+	ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
+
+	ret->seed = NULL;
+	ret->seed_len = 0;
+
+	if (!meth->group_init(ret)) {
+		free(ret);
+		return NULL;
+	}
+	return ret;
+}
+
+
+void 
+EC_GROUP_free(EC_GROUP * group)
+{
+	if (!group)
+		return;
+
+	if (group->meth->group_finish != 0)
+		group->meth->group_finish(group);
+
+	EC_EX_DATA_free_all_data(&group->extra_data);
+
+	EC_POINT_free(group->generator);
+	BN_free(&group->order);
+	BN_free(&group->cofactor);
+
+	free(group->seed);
+
+	free(group);
+}
+
+
+void 
+EC_GROUP_clear_free(EC_GROUP * group)
+{
+	if (!group)
+		return;
+
+	if (group->meth->group_clear_finish != 0)
+		group->meth->group_clear_finish(group);
+	else if (group->meth->group_finish != 0)
+		group->meth->group_finish(group);
+
+	EC_EX_DATA_clear_free_all_data(&group->extra_data);
+
+	EC_POINT_clear_free(group->generator);
+	BN_clear_free(&group->order);
+	BN_clear_free(&group->cofactor);
+
+	if (group->seed) {
+		explicit_bzero(group->seed, group->seed_len);
+		free(group->seed);
+	}
+	explicit_bzero(group, sizeof *group);
+	free(group);
+}
+
+
+int 
+EC_GROUP_copy(EC_GROUP * dest, const EC_GROUP * src)
+{
+	EC_EXTRA_DATA *d;
+
+	if (dest->meth->group_copy == 0) {
+		ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if (dest->meth != src->meth) {
+		ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+	}
+	if (dest == src)
+		return 1;
+
+	EC_EX_DATA_free_all_data(&dest->extra_data);
+
+	for (d = src->extra_data; d != NULL; d = d->next) {
+		void *t = d->dup_func(d->data);
+
+		if (t == NULL)
+			return 0;
+		if (!EC_EX_DATA_set_data(&dest->extra_data, t, d->dup_func,
+		    d->free_func, d->clear_free_func))
+			return 0;
+	}
+
+	if (src->generator != NULL) {
+		if (dest->generator == NULL) {
+			dest->generator = EC_POINT_new(dest);
+			if (dest->generator == NULL)
+				return 0;
+		}
+		if (!EC_POINT_copy(dest->generator, src->generator))
+			return 0;
+	} else {
+		/* src->generator == NULL */
+		EC_POINT_clear_free(dest->generator);
+		dest->generator = NULL;
+	}
+
+	if (!BN_copy(&dest->order, &src->order))
+		return 0;
+	if (!BN_copy(&dest->cofactor, &src->cofactor))
+		return 0;
+
+	dest->curve_name = src->curve_name;
+	dest->asn1_flag = src->asn1_flag;
+	dest->asn1_form = src->asn1_form;
+
+	if (src->seed) {
+		free(dest->seed);
+		dest->seed = malloc(src->seed_len);
+		if (dest->seed == NULL)
+			return 0;
+		memcpy(dest->seed, src->seed, src->seed_len);
+		dest->seed_len = src->seed_len;
+	} else {
+		free(dest->seed);
+		dest->seed = NULL;
+		dest->seed_len = 0;
+	}
+
+
+	return dest->meth->group_copy(dest, src);
+}
+
+
+EC_GROUP *
+EC_GROUP_dup(const EC_GROUP * a)
+{
+	EC_GROUP *t = NULL;
+	int ok = 0;
+
+	if (a == NULL)
+		return NULL;
+
+	if ((t = EC_GROUP_new(a->meth)) == NULL)
+		return (NULL);
+	if (!EC_GROUP_copy(t, a))
+		goto err;
+
+	ok = 1;
+
+err:
+	if (!ok) {
+		EC_GROUP_free(t);
+		return NULL;
+	} else
+		return t;
+}
+
+
+const EC_METHOD *
+EC_GROUP_method_of(const EC_GROUP *group)
+{
+	return group->meth;
+}
+
+
+int 
+EC_METHOD_get_field_type(const EC_METHOD *meth)
+{
+	return meth->field_type;
+}
+
+
+int 
+EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
+    const BIGNUM *order, const BIGNUM *cofactor)
+{
+	if (generator == NULL) {
+		ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	if (group->generator == NULL) {
+		group->generator = EC_POINT_new(group);
+		if (group->generator == NULL)
+			return 0;
+	}
+	if (!EC_POINT_copy(group->generator, generator))
+		return 0;
+
+	if (order != NULL) {
+		if (!BN_copy(&group->order, order))
+			return 0;
+	} else
+		BN_zero(&group->order);
+
+	if (cofactor != NULL) {
+		if (!BN_copy(&group->cofactor, cofactor))
+			return 0;
+	} else
+		BN_zero(&group->cofactor);
+
+	return 1;
+}
+
+
+const EC_POINT *
+EC_GROUP_get0_generator(const EC_GROUP *group)
+{
+	return group->generator;
+}
+
+
+int 
+EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
+{
+	if (!BN_copy(order, &group->order))
+		return 0;
+
+	return !BN_is_zero(order);
+}
+
+
+int 
+EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
+{
+	if (!BN_copy(cofactor, &group->cofactor))
+		return 0;
+
+	return !BN_is_zero(&group->cofactor);
+}
+
+
+void 
+EC_GROUP_set_curve_name(EC_GROUP * group, int nid)
+{
+	group->curve_name = nid;
+}
+
+
+int 
+EC_GROUP_get_curve_name(const EC_GROUP * group)
+{
+	return group->curve_name;
+}
+
+
+void 
+EC_GROUP_set_asn1_flag(EC_GROUP * group, int flag)
+{
+	group->asn1_flag = flag;
+}
+
+
+int 
+EC_GROUP_get_asn1_flag(const EC_GROUP * group)
+{
+	return group->asn1_flag;
+}
+
+
+void 
+EC_GROUP_set_point_conversion_form(EC_GROUP * group,
+    point_conversion_form_t form)
+{
+	group->asn1_form = form;
+}
+
+
+point_conversion_form_t 
+EC_GROUP_get_point_conversion_form(const EC_GROUP * group)
+{
+	return group->asn1_form;
+}
+
+
+size_t 
+EC_GROUP_set_seed(EC_GROUP * group, const unsigned char *p, size_t len)
+{
+	if (group->seed) {
+		free(group->seed);
+		group->seed = NULL;
+		group->seed_len = 0;
+	}
+	if (!len || !p)
+		return 1;
+
+	if ((group->seed = malloc(len)) == NULL)
+		return 0;
+	memcpy(group->seed, p, len);
+	group->seed_len = len;
+
+	return len;
+}
+
+
+unsigned char *
+EC_GROUP_get0_seed(const EC_GROUP * group)
+{
+	return group->seed;
+}
+
+
+size_t 
+EC_GROUP_get_seed_len(const EC_GROUP * group)
+{
+	return group->seed_len;
+}
+
+
+int 
+EC_GROUP_set_curve_GFp(EC_GROUP * group, const BIGNUM * p, const BIGNUM * a,
+    const BIGNUM * b, BN_CTX * ctx)
+{
+	if (group->meth->group_set_curve == 0) {
+		ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	return group->meth->group_set_curve(group, p, a, b, ctx);
+}
+
+
+int 
+EC_GROUP_get_curve_GFp(const EC_GROUP * group, BIGNUM * p, BIGNUM * a,
+    BIGNUM * b, BN_CTX * ctx)
+{
+	if (group->meth->group_get_curve == 0) {
+		ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	return group->meth->group_get_curve(group, p, a, b, ctx);
+}
+
+#ifndef OPENSSL_NO_EC2M
+int 
+EC_GROUP_set_curve_GF2m(EC_GROUP * group, const BIGNUM * p, const BIGNUM * a,
+    const BIGNUM * b, BN_CTX * ctx)
+{
+	if (group->meth->group_set_curve == 0) {
+		ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	return group->meth->group_set_curve(group, p, a, b, ctx);
+}
+
+
+int 
+EC_GROUP_get_curve_GF2m(const EC_GROUP * group, BIGNUM * p, BIGNUM * a,
+    BIGNUM * b, BN_CTX * ctx)
+{
+	if (group->meth->group_get_curve == 0) {
+		ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	return group->meth->group_get_curve(group, p, a, b, ctx);
+}
+#endif
+
+int 
+EC_GROUP_get_degree(const EC_GROUP * group)
+{
+	if (group->meth->group_get_degree == 0) {
+		ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	return group->meth->group_get_degree(group);
+}
+
+
+int 
+EC_GROUP_check_discriminant(const EC_GROUP * group, BN_CTX * ctx)
+{
+	if (group->meth->group_check_discriminant == 0) {
+		ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	return group->meth->group_check_discriminant(group, ctx);
+}
+
+
+int 
+EC_GROUP_cmp(const EC_GROUP * a, const EC_GROUP * b, BN_CTX * ctx)
+{
+	int r = 0;
+	BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
+	BN_CTX *ctx_new = NULL;
+
+	/* compare the field types */
+	if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
+	    EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
+		return 1;
+	/* compare the curve name (if present in both) */
+	if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
+	    EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
+		return 1;
+
+	if (!ctx)
+		ctx_new = ctx = BN_CTX_new();
+	if (!ctx)
+		return -1;
+
+	BN_CTX_start(ctx);
+	if ((a1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((a2 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((a3 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((b1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((b2 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((b3 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	/*
+	 * XXX This approach assumes that the external representation of
+	 * curves over the same field type is the same.
+	 */
+	if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
+	    !b->meth->group_get_curve(b, b1, b2, b3, ctx))
+		r = 1;
+
+	if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
+		r = 1;
+
+	/* XXX EC_POINT_cmp() assumes that the methods are equal */
+	if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
+		EC_GROUP_get0_generator(b), ctx))
+		r = 1;
+
+	if (!r) {
+		/* compare the order and cofactor */
+		if (!EC_GROUP_get_order(a, a1, ctx) ||
+		    !EC_GROUP_get_order(b, b1, ctx) ||
+		    !EC_GROUP_get_cofactor(a, a2, ctx) ||
+		    !EC_GROUP_get_cofactor(b, b2, ctx))
+			goto err;
+		if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
+			r = 1;
+	}
+	BN_CTX_end(ctx);
+	if (ctx_new)
+		BN_CTX_free(ctx);
+
+	return r;
+
+err:
+	BN_CTX_end(ctx);
+	if (ctx_new)
+		BN_CTX_free(ctx);
+	return -1;
+}
+
+
+/* this has 'package' visibility */
+int 
+EC_EX_DATA_set_data(EC_EXTRA_DATA ** ex_data, void *data,
+    void *(*dup_func) (void *),
+    void (*free_func) (void *),
+    void (*clear_free_func) (void *))
+{
+	EC_EXTRA_DATA *d;
+
+	if (ex_data == NULL)
+		return 0;
+
+	for (d = *ex_data; d != NULL; d = d->next) {
+		if (d->dup_func == dup_func && d->free_func == free_func &&
+		    d->clear_free_func == clear_free_func) {
+			ECerr(EC_F_EC_EX_DATA_SET_DATA, EC_R_SLOT_FULL);
+			return 0;
+		}
+	}
+
+	if (data == NULL)
+		/* no explicit entry needed */
+		return 1;
+
+	d = malloc(sizeof *d);
+	if (d == NULL)
+		return 0;
+
+	d->data = data;
+	d->dup_func = dup_func;
+	d->free_func = free_func;
+	d->clear_free_func = clear_free_func;
+
+	d->next = *ex_data;
+	*ex_data = d;
+
+	return 1;
+}
+
+/* this has 'package' visibility */
+void *
+EC_EX_DATA_get_data(const EC_EXTRA_DATA * ex_data,
+    void *(*dup_func) (void *),
+    void (*free_func) (void *),
+    void (*clear_free_func) (void *))
+{
+	const EC_EXTRA_DATA *d;
+
+	for (d = ex_data; d != NULL; d = d->next) {
+		if (d->dup_func == dup_func && d->free_func == free_func && d->clear_free_func == clear_free_func)
+			return d->data;
+	}
+
+	return NULL;
+}
+
+/* this has 'package' visibility */
+void 
+EC_EX_DATA_free_data(EC_EXTRA_DATA ** ex_data,
+    void *(*dup_func) (void *),
+    void (*free_func) (void *),
+    void (*clear_free_func) (void *))
+{
+	EC_EXTRA_DATA **p;
+
+	if (ex_data == NULL)
+		return;
+
+	for (p = ex_data; *p != NULL; p = &((*p)->next)) {
+		if ((*p)->dup_func == dup_func &&
+		    (*p)->free_func == free_func &&
+		    (*p)->clear_free_func == clear_free_func) {
+			EC_EXTRA_DATA *next = (*p)->next;
+
+			(*p)->free_func((*p)->data);
+			free(*p);
+
+			*p = next;
+			return;
+		}
+	}
+}
+
+/* this has 'package' visibility */
+void 
+EC_EX_DATA_clear_free_data(EC_EXTRA_DATA ** ex_data,
+    void *(*dup_func) (void *),
+    void (*free_func) (void *),
+    void (*clear_free_func) (void *))
+{
+	EC_EXTRA_DATA **p;
+
+	if (ex_data == NULL)
+		return;
+
+	for (p = ex_data; *p != NULL; p = &((*p)->next)) {
+		if ((*p)->dup_func == dup_func &&
+		    (*p)->free_func == free_func &&
+		    (*p)->clear_free_func == clear_free_func) {
+			EC_EXTRA_DATA *next = (*p)->next;
+
+			(*p)->clear_free_func((*p)->data);
+			free(*p);
+
+			*p = next;
+			return;
+		}
+	}
+}
+
+/* this has 'package' visibility */
+void 
+EC_EX_DATA_free_all_data(EC_EXTRA_DATA ** ex_data)
+{
+	EC_EXTRA_DATA *d;
+
+	if (ex_data == NULL)
+		return;
+
+	d = *ex_data;
+	while (d) {
+		EC_EXTRA_DATA *next = d->next;
+
+		d->free_func(d->data);
+		free(d);
+
+		d = next;
+	}
+	*ex_data = NULL;
+}
+
+/* this has 'package' visibility */
+void 
+EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA ** ex_data)
+{
+	EC_EXTRA_DATA *d;
+
+	if (ex_data == NULL)
+		return;
+
+	d = *ex_data;
+	while (d) {
+		EC_EXTRA_DATA *next = d->next;
+
+		d->clear_free_func(d->data);
+		free(d);
+
+		d = next;
+	}
+	*ex_data = NULL;
+}
+
+
+/* functions for EC_POINT objects */
+
+EC_POINT *
+EC_POINT_new(const EC_GROUP * group)
+{
+	EC_POINT *ret;
+
+	if (group == NULL) {
+		ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER);
+		return NULL;
+	}
+	if (group->meth->point_init == 0) {
+		ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return NULL;
+	}
+	ret = malloc(sizeof *ret);
+	if (ret == NULL) {
+		ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	ret->meth = group->meth;
+
+	if (!ret->meth->point_init(ret)) {
+		free(ret);
+		return NULL;
+	}
+	return ret;
+}
+
+
+void 
+EC_POINT_free(EC_POINT * point)
+{
+	if (!point)
+		return;
+
+	if (point->meth->point_finish != 0)
+		point->meth->point_finish(point);
+	free(point);
+}
+
+
+void 
+EC_POINT_clear_free(EC_POINT * point)
+{
+	if (!point)
+		return;
+
+	if (point->meth->point_clear_finish != 0)
+		point->meth->point_clear_finish(point);
+	else if (point->meth->point_finish != 0)
+		point->meth->point_finish(point);
+	explicit_bzero(point, sizeof *point);
+	free(point);
+}
+
+
+int 
+EC_POINT_copy(EC_POINT * dest, const EC_POINT * src)
+{
+	if (dest->meth->point_copy == 0) {
+		ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if (dest->meth != src->meth) {
+		ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+	}
+	if (dest == src)
+		return 1;
+	return dest->meth->point_copy(dest, src);
+}
+
+
+EC_POINT *
+EC_POINT_dup(const EC_POINT * a, const EC_GROUP * group)
+{
+	EC_POINT *t;
+	int r;
+
+	if (a == NULL)
+		return NULL;
+
+	t = EC_POINT_new(group);
+	if (t == NULL)
+		return (NULL);
+	r = EC_POINT_copy(t, a);
+	if (!r) {
+		EC_POINT_free(t);
+		return NULL;
+	} else
+		return t;
+}
+
+
+const EC_METHOD *
+EC_POINT_method_of(const EC_POINT * point)
+{
+	return point->meth;
+}
+
+
+int 
+EC_POINT_set_to_infinity(const EC_GROUP * group, EC_POINT * point)
+{
+	if (group->meth->point_set_to_infinity == 0) {
+		ECerr(EC_F_EC_POINT_SET_TO_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if (group->meth != point->meth) {
+		ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+	}
+	return group->meth->point_set_to_infinity(group, point);
+}
+
+
+int 
+EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
+    const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx)
+{
+	if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
+		ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if (group->meth != point->meth) {
+		ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+	}
+	return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y, z, ctx);
+}
+
+
+int 
+EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
+    const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
+{
+	if (group->meth->point_get_Jprojective_coordinates_GFp == 0) {
+		ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if (group->meth != point->meth) {
+		ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+	}
+	return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x, y, z, ctx);
+}
+
+
+int 
+EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
+    const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
+{
+	if (group->meth->point_set_affine_coordinates == 0) {
+		ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if (group->meth != point->meth) {
+		ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+	}
+	return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
+}
+
+#ifndef OPENSSL_NO_EC2M
+int 
+EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
+    const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
+{
+	if (group->meth->point_set_affine_coordinates == 0) {
+		ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if (group->meth != point->meth) {
+		ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+	}
+	return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
+}
+#endif
+
+int 
+EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
+    BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
+{
+	if (group->meth->point_get_affine_coordinates == 0) {
+		ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if (group->meth != point->meth) {
+		ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+	}
+	return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
+}
+
+#ifndef OPENSSL_NO_EC2M
+int 
+EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *point,
+    BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
+{
+	if (group->meth->point_get_affine_coordinates == 0) {
+		ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if (group->meth != point->meth) {
+		ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+	}
+	return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
+}
+#endif
+
+int 
+EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+    const EC_POINT *b, BN_CTX *ctx)
+{
+	if (group->meth->add == 0) {
+		ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if ((group->meth != r->meth) || (r->meth != a->meth) || (a->meth != b->meth)) {
+		ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+	}
+	return group->meth->add(group, r, a, b, ctx);
+}
+
+
+int 
+EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
+{
+	if (group->meth->dbl == 0) {
+		ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if ((group->meth != r->meth) || (r->meth != a->meth)) {
+		ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+	}
+	return group->meth->dbl(group, r, a, ctx);
+}
+
+
+int 
+EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
+{
+	if (group->meth->invert == 0) {
+		ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if (group->meth != a->meth) {
+		ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+	}
+	return group->meth->invert(group, a, ctx);
+}
+
+
+int 
+EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
+{
+	if (group->meth->is_at_infinity == 0) {
+		ECerr(EC_F_EC_POINT_IS_AT_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if (group->meth != point->meth) {
+		ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+	}
+	return group->meth->is_at_infinity(group, point);
+}
+
+
+int 
+EC_POINT_is_on_curve(const EC_GROUP * group, const EC_POINT * point, BN_CTX * ctx)
+{
+	if (group->meth->is_on_curve == 0) {
+		ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if (group->meth != point->meth) {
+		ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+	}
+	return group->meth->is_on_curve(group, point, ctx);
+}
+
+
+int 
+EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
+    BN_CTX * ctx)
+{
+	if (group->meth->point_cmp == 0) {
+		ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return -1;
+	}
+	if ((group->meth != a->meth) || (a->meth != b->meth)) {
+		ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
+		return -1;
+	}
+	return group->meth->point_cmp(group, a, b, ctx);
+}
+
+
+int 
+EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
+{
+	if (group->meth->make_affine == 0) {
+		ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if (group->meth != point->meth) {
+		ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+	}
+	return group->meth->make_affine(group, point, ctx);
+}
+
+
+int 
+EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
+    BN_CTX *ctx)
+{
+	size_t i;
+
+	if (group->meth->points_make_affine == 0) {
+		ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	for (i = 0; i < num; i++) {
+		if (group->meth != points[i]->meth) {
+			ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
+			return 0;
+		}
+	}
+	return group->meth->points_make_affine(group, num, points, ctx);
+}
+
+
+/* Functions for point multiplication.
+ *
+ * If group->meth->mul is 0, we use the wNAF-based implementations in ec_mult.c;
+ * otherwise we dispatch through methods.
+ */
+
+int 
+EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+    size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
+{
+	if (group->meth->mul == 0)
+		/* use default */
+		return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
+
+	return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
+}
+
+int 
+EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
+    const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
+{
+	/* just a convenient interface to EC_POINTs_mul() */
+
+	const EC_POINT *points[1];
+	const BIGNUM *scalars[1];
+
+	points[0] = point;
+	scalars[0] = p_scalar;
+
+	return EC_POINTs_mul(group, r, g_scalar,
+	    (point != NULL && p_scalar != NULL),
+	    points, scalars, ctx);
+}
+
+int 
+EC_GROUP_precompute_mult(EC_GROUP * group, BN_CTX * ctx)
+{
+	if (group->meth->mul == 0)
+		/* use default */
+		return ec_wNAF_precompute_mult(group, ctx);
+
+	if (group->meth->precompute_mult != 0)
+		return group->meth->precompute_mult(group, ctx);
+	else
+		return 1;	/* nothing to do, so report success */
+}
+
+int 
+EC_GROUP_have_precompute_mult(const EC_GROUP * group)
+{
+	if (group->meth->mul == 0)
+		/* use default */
+		return ec_wNAF_have_precompute_mult(group);
+
+	if (group->meth->have_precompute_mult != 0)
+		return group->meth->have_precompute_mult(group);
+	else
+		return 0;	/* cannot tell whether precomputation has
+				 * been performed */
+}
+
+EC_KEY *
+ECParameters_dup(EC_KEY *key)
+{
+	unsigned char *p = NULL;
+	EC_KEY *k = NULL;
+	int len;
+
+	if (key == NULL)
+		return (NULL);
+
+	if ((len = i2d_ECParameters(key, &p)) > 0)
+		k = d2i_ECParameters(NULL, (const unsigned char **)&p, len);
+
+	return (k);	
+}
diff --git a/crypto/libressl/crypto/ec/ec_mult.c b/crypto/libressl/crypto/ec/ec_mult.c
new file mode 100644
index 0000000000..5eecd0ce8f
--- /dev/null
+++ b/crypto/libressl/crypto/ec/ec_mult.c
@@ -0,0 +1,886 @@
+/* $OpenBSD: ec_mult.c,v 1.18 2015/02/15 08:44:35 miod Exp $ */
+/*
+ * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include 
+
+#include 
+
+#include "ec_lcl.h"
+
+
+/*
+ * This file implements the wNAF-based interleaving multi-exponentation method
+ * ();
+ * for multiplication with precomputation, we use wNAF splitting
+ * ().
+ */
+
+
+
+
+/* structure for precomputed multiples of the generator */
+typedef struct ec_pre_comp_st {
+	const EC_GROUP *group;	/* parent EC_GROUP object */
+	size_t blocksize;	/* block size for wNAF splitting */
+	size_t numblocks;	/* max. number of blocks for which we have
+				 * precomputation */
+	size_t w;		/* window size */
+	EC_POINT **points;	/* array with pre-calculated multiples of
+				 * generator: 'num' pointers to EC_POINT
+				 * objects followed by a NULL */
+	size_t num;		/* numblocks * 2^(w-1) */
+	int references;
+} EC_PRE_COMP;
+
+/* functions to manage EC_PRE_COMP within the EC_GROUP extra_data framework */
+static void *ec_pre_comp_dup(void *);
+static void ec_pre_comp_free(void *);
+static void ec_pre_comp_clear_free(void *);
+
+static EC_PRE_COMP *
+ec_pre_comp_new(const EC_GROUP * group)
+{
+	EC_PRE_COMP *ret = NULL;
+
+	if (!group)
+		return NULL;
+
+	ret = malloc(sizeof(EC_PRE_COMP));
+	if (!ret) {
+		ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+		return ret;
+	}
+	ret->group = group;
+	ret->blocksize = 8;	/* default */
+	ret->numblocks = 0;
+	ret->w = 4;		/* default */
+	ret->points = NULL;
+	ret->num = 0;
+	ret->references = 1;
+	return ret;
+}
+
+static void *
+ec_pre_comp_dup(void *src_)
+{
+	EC_PRE_COMP *src = src_;
+
+	/* no need to actually copy, these objects never change! */
+
+	CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
+
+	return src_;
+}
+
+static void 
+ec_pre_comp_free(void *pre_)
+{
+	int i;
+	EC_PRE_COMP *pre = pre_;
+
+	if (!pre)
+		return;
+
+	i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
+	if (i > 0)
+		return;
+
+	if (pre->points) {
+		EC_POINT **p;
+
+		for (p = pre->points; *p != NULL; p++)
+			EC_POINT_free(*p);
+		free(pre->points);
+	}
+	free(pre);
+}
+
+static void 
+ec_pre_comp_clear_free(void *pre_)
+{
+	int i;
+	EC_PRE_COMP *pre = pre_;
+
+	if (!pre)
+		return;
+
+	i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
+	if (i > 0)
+		return;
+
+	if (pre->points) {
+		EC_POINT **p;
+
+		for (p = pre->points; *p != NULL; p++) {
+			EC_POINT_clear_free(*p);
+			explicit_bzero(p, sizeof *p);
+		}
+		free(pre->points);
+	}
+	explicit_bzero(pre, sizeof *pre);
+	free(pre);
+}
+
+
+
+
+/* Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
+ * This is an array  r[]  of values that are either zero or odd with an
+ * absolute value less than  2^w  satisfying
+ *     scalar = \sum_j r[j]*2^j
+ * where at most one of any  w+1  consecutive digits is non-zero
+ * with the exception that the most significant digit may be only
+ * w-1 zeros away from that next non-zero digit.
+ */
+static signed char *
+compute_wNAF(const BIGNUM * scalar, int w, size_t * ret_len)
+{
+	int window_val;
+	int ok = 0;
+	signed char *r = NULL;
+	int sign = 1;
+	int bit, next_bit, mask;
+	size_t len = 0, j;
+
+	if (BN_is_zero(scalar)) {
+		r = malloc(1);
+		if (!r) {
+			ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		r[0] = 0;
+		*ret_len = 1;
+		return r;
+	}
+	if (w <= 0 || w > 7) {
+		/* 'signed char' can represent integers with
+		 * absolute values less than 2^7 */
+		ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+		goto err;
+	}
+	bit = 1 << w;		/* at most 128 */
+	next_bit = bit << 1;	/* at most 256 */
+	mask = next_bit - 1;	/* at most 255 */
+
+	if (BN_is_negative(scalar)) {
+		sign = -1;
+	}
+	if (scalar->d == NULL || scalar->top == 0) {
+		ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+		goto err;
+	}
+	len = BN_num_bits(scalar);
+	r = malloc(len + 1);	/* modified wNAF may be one digit longer than
+				 * binary representation (*ret_len will be
+				 * set to the actual length, i.e. at most
+				 * BN_num_bits(scalar) + 1) */
+	if (r == NULL) {
+		ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	window_val = scalar->d[0] & mask;
+	j = 0;
+	while ((window_val != 0) || (j + w + 1 < len)) {
+		/* if j+w+1 >= len, window_val will not increase */
+		int digit = 0;
+
+		/* 0 <= window_val <= 2^(w+1) */
+		if (window_val & 1) {
+			/* 0 < window_val < 2^(w+1) */
+			if (window_val & bit) {
+				digit = window_val - next_bit;	/* -2^w < digit < 0 */
+
+#if 1				/* modified wNAF */
+				if (j + w + 1 >= len) {
+					/*
+					 * special case for generating
+					 * modified wNAFs: no new bits will
+					 * be added into window_val, so using
+					 * a positive digit here will
+					 * decrease the total length of the
+					 * representation
+					 */
+
+					digit = window_val & (mask >> 1);	/* 0 < digit < 2^w */
+				}
+#endif
+			} else {
+				digit = window_val;	/* 0 < digit < 2^w */
+			}
+
+			if (digit <= -bit || digit >= bit || !(digit & 1)) {
+				ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+				goto err;
+			}
+			window_val -= digit;
+
+			/*
+			 * now window_val is 0 or 2^(w+1) in standard wNAF
+			 * generation; for modified window NAFs, it may also
+			 * be 2^w
+			 */
+			if (window_val != 0 && window_val != next_bit && window_val != bit) {
+				ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+				goto err;
+			}
+		}
+		r[j++] = sign * digit;
+
+		window_val >>= 1;
+		window_val += bit * BN_is_bit_set(scalar, j + w);
+
+		if (window_val > next_bit) {
+			ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+			goto err;
+		}
+	}
+
+	if (j > len + 1) {
+		ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+		goto err;
+	}
+	len = j;
+	ok = 1;
+
+err:
+	if (!ok) {
+		free(r);
+		r = NULL;
+	}
+	if (ok)
+		*ret_len = len;
+	return r;
+}
+
+
+/* TODO: table should be optimised for the wNAF-based implementation,
+ *       sometimes smaller windows will give better performance
+ *       (thus the boundaries should be increased)
+ */
+#define EC_window_bits_for_scalar_size(b) \
+		((size_t) \
+		 ((b) >= 2000 ? 6 : \
+		  (b) >=  800 ? 5 : \
+		  (b) >=  300 ? 4 : \
+		  (b) >=   70 ? 3 : \
+		  (b) >=   20 ? 2 : \
+		  1))
+
+/* Compute
+ *      \sum scalars[i]*points[i],
+ * also including
+ *      scalar*generator
+ * in the addition if scalar != NULL
+ */
+int 
+ec_wNAF_mul(const EC_GROUP * group, EC_POINT * r, const BIGNUM * scalar,
+    size_t num, const EC_POINT * points[], const BIGNUM * scalars[], BN_CTX * ctx)
+{
+	BN_CTX *new_ctx = NULL;
+	const EC_POINT *generator = NULL;
+	EC_POINT *tmp = NULL;
+	size_t totalnum;
+	size_t blocksize = 0, numblocks = 0;	/* for wNAF splitting */
+	size_t pre_points_per_block = 0;
+	size_t i, j;
+	int k;
+	int r_is_inverted = 0;
+	int r_is_at_infinity = 1;
+	size_t *wsize = NULL;	/* individual window sizes */
+	signed char **wNAF = NULL;	/* individual wNAFs */
+	signed char *tmp_wNAF = NULL;
+	size_t *wNAF_len = NULL;
+	size_t max_len = 0;
+	size_t num_val;
+	EC_POINT **val = NULL;	/* precomputation */
+	EC_POINT **v;
+	EC_POINT ***val_sub = NULL;	/* pointers to sub-arrays of 'val' or
+					 * 'pre_comp->points' */
+	const EC_PRE_COMP *pre_comp = NULL;
+	int num_scalar = 0;	/* flag: will be set to 1 if 'scalar' must be
+				 * treated like other scalars, i.e.
+				 * precomputation is not available */
+	int ret = 0;
+
+	if (group->meth != r->meth) {
+		ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+	}
+	if ((scalar == NULL) && (num == 0)) {
+		return EC_POINT_set_to_infinity(group, r);
+	}
+	for (i = 0; i < num; i++) {
+		if (group->meth != points[i]->meth) {
+			ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
+			return 0;
+		}
+	}
+
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			goto err;
+	}
+	if (scalar != NULL) {
+		generator = EC_GROUP_get0_generator(group);
+		if (generator == NULL) {
+			ECerr(EC_F_EC_WNAF_MUL, EC_R_UNDEFINED_GENERATOR);
+			goto err;
+		}
+		/* look if we can use precomputed multiples of generator */
+
+		pre_comp = EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free);
+
+		if (pre_comp && pre_comp->numblocks &&
+		    (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == 0)) {
+			blocksize = pre_comp->blocksize;
+
+			/*
+			 * determine maximum number of blocks that wNAF
+			 * splitting may yield (NB: maximum wNAF length is
+			 * bit length plus one)
+			 */
+			numblocks = (BN_num_bits(scalar) / blocksize) + 1;
+
+			/*
+			 * we cannot use more blocks than we have
+			 * precomputation for
+			 */
+			if (numblocks > pre_comp->numblocks)
+				numblocks = pre_comp->numblocks;
+
+			pre_points_per_block = (size_t) 1 << (pre_comp->w - 1);
+
+			/* check that pre_comp looks sane */
+			if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) {
+				ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+				goto err;
+			}
+		} else {
+			/* can't use precomputation */
+			pre_comp = NULL;
+			numblocks = 1;
+			num_scalar = 1;	/* treat 'scalar' like 'num'-th
+					 * element of 'scalars' */
+		}
+	}
+	totalnum = num + numblocks;
+
+	/* includes space for pivot */
+	wNAF = reallocarray(NULL, (totalnum + 1), sizeof wNAF[0]);
+	if (wNAF == NULL) {
+		ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	wNAF[0] = NULL;		/* preliminary pivot */
+
+	wsize = reallocarray(NULL, totalnum, sizeof wsize[0]);
+	wNAF_len = reallocarray(NULL, totalnum, sizeof wNAF_len[0]);
+	val_sub = reallocarray(NULL, totalnum, sizeof val_sub[0]);
+
+	if (wsize == NULL || wNAF_len == NULL || val_sub == NULL) {
+		ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	/* num_val will be the total number of temporarily precomputed points */
+	num_val = 0;
+
+	for (i = 0; i < num + num_scalar; i++) {
+		size_t bits;
+
+		bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar);
+		wsize[i] = EC_window_bits_for_scalar_size(bits);
+		num_val += (size_t) 1 << (wsize[i] - 1);
+		wNAF[i + 1] = NULL;	/* make sure we always have a pivot */
+		wNAF[i] = compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], &wNAF_len[i]);
+		if (wNAF[i] == NULL)
+			goto err;
+		if (wNAF_len[i] > max_len)
+			max_len = wNAF_len[i];
+	}
+
+	if (numblocks) {
+		/* we go here iff scalar != NULL */
+
+		if (pre_comp == NULL) {
+			if (num_scalar != 1) {
+				ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+				goto err;
+			}
+			/* we have already generated a wNAF for 'scalar' */
+		} else {
+			size_t tmp_len = 0;
+
+			if (num_scalar != 0) {
+				ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+				goto err;
+			}
+			/*
+			 * use the window size for which we have
+			 * precomputation
+			 */
+			wsize[num] = pre_comp->w;
+			tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len);
+			if (tmp_wNAF == NULL)
+				goto err;
+
+			if (tmp_len <= max_len) {
+				/*
+				 * One of the other wNAFs is at least as long
+				 * as the wNAF belonging to the generator, so
+				 * wNAF splitting will not buy us anything.
+				 */
+
+				numblocks = 1;
+				totalnum = num + 1;	/* don't use wNAF
+							 * splitting */
+				wNAF[num] = tmp_wNAF;
+				tmp_wNAF = NULL;
+				wNAF[num + 1] = NULL;
+				wNAF_len[num] = tmp_len;
+				if (tmp_len > max_len)
+					max_len = tmp_len;
+				/*
+				 * pre_comp->points starts with the points
+				 * that we need here:
+				 */
+				val_sub[num] = pre_comp->points;
+			} else {
+				/*
+				 * don't include tmp_wNAF directly into wNAF
+				 * array - use wNAF splitting and include the
+				 * blocks
+				 */
+
+				signed char *pp;
+				EC_POINT **tmp_points;
+
+				if (tmp_len < numblocks * blocksize) {
+					/*
+					 * possibly we can do with fewer
+					 * blocks than estimated
+					 */
+					numblocks = (tmp_len + blocksize - 1) / blocksize;
+					if (numblocks > pre_comp->numblocks) {
+						ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+						goto err;
+					}
+					totalnum = num + numblocks;
+				}
+				/* split wNAF in 'numblocks' parts */
+				pp = tmp_wNAF;
+				tmp_points = pre_comp->points;
+
+				for (i = num; i < totalnum; i++) {
+					if (i < totalnum - 1) {
+						wNAF_len[i] = blocksize;
+						if (tmp_len < blocksize) {
+							ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+							goto err;
+						}
+						tmp_len -= blocksize;
+					} else
+						/*
+						 * last block gets whatever
+						 * is left (this could be
+						 * more or less than
+						 * 'blocksize'!)
+						 */
+						wNAF_len[i] = tmp_len;
+
+					wNAF[i + 1] = NULL;
+					wNAF[i] = malloc(wNAF_len[i]);
+					if (wNAF[i] == NULL) {
+						ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
+						goto err;
+					}
+					memcpy(wNAF[i], pp, wNAF_len[i]);
+					if (wNAF_len[i] > max_len)
+						max_len = wNAF_len[i];
+
+					if (*tmp_points == NULL) {
+						ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+						goto err;
+					}
+					val_sub[i] = tmp_points;
+					tmp_points += pre_points_per_block;
+					pp += blocksize;
+				}
+			}
+		}
+	}
+	/*
+	 * All points we precompute now go into a single array 'val'.
+	 * 'val_sub[i]' is a pointer to the subarray for the i-th point, or
+	 * to a subarray of 'pre_comp->points' if we already have
+	 * precomputation.
+	 */
+	val = reallocarray(NULL, (num_val + 1), sizeof val[0]);
+	if (val == NULL) {
+		ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	val[num_val] = NULL;	/* pivot element */
+
+	/* allocate points for precomputation */
+	v = val;
+	for (i = 0; i < num + num_scalar; i++) {
+		val_sub[i] = v;
+		for (j = 0; j < ((size_t) 1 << (wsize[i] - 1)); j++) {
+			*v = EC_POINT_new(group);
+			if (*v == NULL)
+				goto err;
+			v++;
+		}
+	}
+	if (!(v == val + num_val)) {
+		ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+		goto err;
+	}
+	if (!(tmp = EC_POINT_new(group)))
+		goto err;
+
+	/*
+	 * prepare precomputed values: val_sub[i][0] :=     points[i]
+	 * val_sub[i][1] := 3 * points[i] val_sub[i][2] := 5 * points[i] ...
+	 */
+	for (i = 0; i < num + num_scalar; i++) {
+		if (i < num) {
+			if (!EC_POINT_copy(val_sub[i][0], points[i]))
+				goto err;
+		} else {
+			if (!EC_POINT_copy(val_sub[i][0], generator))
+				goto err;
+		}
+
+		if (wsize[i] > 1) {
+			if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx))
+				goto err;
+			for (j = 1; j < ((size_t) 1 << (wsize[i] - 1)); j++) {
+				if (!EC_POINT_add(group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx))
+					goto err;
+			}
+		}
+	}
+
+	if (!EC_POINTs_make_affine(group, num_val, val, ctx))
+		goto err;
+
+	r_is_at_infinity = 1;
+
+	for (k = max_len - 1; k >= 0; k--) {
+		if (!r_is_at_infinity) {
+			if (!EC_POINT_dbl(group, r, r, ctx))
+				goto err;
+		}
+		for (i = 0; i < totalnum; i++) {
+			if (wNAF_len[i] > (size_t) k) {
+				int digit = wNAF[i][k];
+				int is_neg;
+
+				if (digit) {
+					is_neg = digit < 0;
+
+					if (is_neg)
+						digit = -digit;
+
+					if (is_neg != r_is_inverted) {
+						if (!r_is_at_infinity) {
+							if (!EC_POINT_invert(group, r, ctx))
+								goto err;
+						}
+						r_is_inverted = !r_is_inverted;
+					}
+					/* digit > 0 */
+
+					if (r_is_at_infinity) {
+						if (!EC_POINT_copy(r, val_sub[i][digit >> 1]))
+							goto err;
+						r_is_at_infinity = 0;
+					} else {
+						if (!EC_POINT_add(group, r, r, val_sub[i][digit >> 1], ctx))
+							goto err;
+					}
+				}
+			}
+		}
+	}
+
+	if (r_is_at_infinity) {
+		if (!EC_POINT_set_to_infinity(group, r))
+			goto err;
+	} else {
+		if (r_is_inverted)
+			if (!EC_POINT_invert(group, r, ctx))
+				goto err;
+	}
+
+	ret = 1;
+
+err:
+	BN_CTX_free(new_ctx);
+	EC_POINT_free(tmp);
+	free(wsize);
+	free(wNAF_len);
+	free(tmp_wNAF);
+	if (wNAF != NULL) {
+		signed char **w;
+
+		for (w = wNAF; *w != NULL; w++)
+			free(*w);
+
+		free(wNAF);
+	}
+	if (val != NULL) {
+		for (v = val; *v != NULL; v++)
+			EC_POINT_clear_free(*v);
+		free(val);
+	}
+	free(val_sub);
+	return ret;
+}
+
+
+/* ec_wNAF_precompute_mult()
+ * creates an EC_PRE_COMP object with preprecomputed multiples of the generator
+ * for use with wNAF splitting as implemented in ec_wNAF_mul().
+ *
+ * 'pre_comp->points' is an array of multiples of the generator
+ * of the following form:
+ * points[0] =     generator;
+ * points[1] = 3 * generator;
+ * ...
+ * points[2^(w-1)-1] =     (2^(w-1)-1) * generator;
+ * points[2^(w-1)]   =     2^blocksize * generator;
+ * points[2^(w-1)+1] = 3 * 2^blocksize * generator;
+ * ...
+ * points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) *  2^(blocksize*(numblocks-2)) * generator
+ * points[2^(w-1)*(numblocks-1)]   =              2^(blocksize*(numblocks-1)) * generator
+ * ...
+ * points[2^(w-1)*numblocks-1]     = (2^(w-1)) *  2^(blocksize*(numblocks-1)) * generator
+ * points[2^(w-1)*numblocks]       = NULL
+ */
+int 
+ec_wNAF_precompute_mult(EC_GROUP * group, BN_CTX * ctx)
+{
+	const EC_POINT *generator;
+	EC_POINT *tmp_point = NULL, *base = NULL, **var;
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *order;
+	size_t i, bits, w, pre_points_per_block, blocksize, numblocks,
+	 num;
+	EC_POINT **points = NULL;
+	EC_PRE_COMP *pre_comp;
+	int ret = 0;
+
+	/* if there is an old EC_PRE_COMP object, throw it away */
+	EC_EX_DATA_free_data(&group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free);
+
+	if ((pre_comp = ec_pre_comp_new(group)) == NULL)
+		return 0;
+
+	generator = EC_GROUP_get0_generator(group);
+	if (generator == NULL) {
+		ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR);
+		goto err;
+	}
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			goto err;
+	}
+	BN_CTX_start(ctx);
+	if ((order = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!EC_GROUP_get_order(group, order, ctx))
+		goto err;
+	if (BN_is_zero(order)) {
+		ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER);
+		goto err;
+	}
+	bits = BN_num_bits(order);
+	/*
+	 * The following parameters mean we precompute (approximately) one
+	 * point per bit.
+	 * 
+	 * TBD: The combination  8, 4  is perfect for 160 bits; for other bit
+	 * lengths, other parameter combinations might provide better
+	 * efficiency.
+	 */
+	blocksize = 8;
+	w = 4;
+	if (EC_window_bits_for_scalar_size(bits) > w) {
+		/* let's not make the window too small ... */
+		w = EC_window_bits_for_scalar_size(bits);
+	}
+	numblocks = (bits + blocksize - 1) / blocksize;	/* max. number of blocks
+							 * to use for wNAF
+							 * splitting */
+
+	pre_points_per_block = (size_t) 1 << (w - 1);
+	num = pre_points_per_block * numblocks;	/* number of points to
+						 * compute and store */
+
+	points = reallocarray(NULL, (num + 1), sizeof(EC_POINT *));
+	if (!points) {
+		ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	var = points;
+	var[num] = NULL;	/* pivot */
+	for (i = 0; i < num; i++) {
+		if ((var[i] = EC_POINT_new(group)) == NULL) {
+			ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+	}
+
+	if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group))) {
+		ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	if (!EC_POINT_copy(base, generator))
+		goto err;
+
+	/* do the precomputation */
+	for (i = 0; i < numblocks; i++) {
+		size_t j;
+
+		if (!EC_POINT_dbl(group, tmp_point, base, ctx))
+			goto err;
+
+		if (!EC_POINT_copy(*var++, base))
+			goto err;
+
+		for (j = 1; j < pre_points_per_block; j++, var++) {
+			/* calculate odd multiples of the current base point */
+			if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx))
+				goto err;
+		}
+
+		if (i < numblocks - 1) {
+			/*
+			 * get the next base (multiply current one by
+			 * 2^blocksize)
+			 */
+			size_t k;
+
+			if (blocksize <= 2) {
+				ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_INTERNAL_ERROR);
+				goto err;
+			}
+			if (!EC_POINT_dbl(group, base, tmp_point, ctx))
+				goto err;
+			for (k = 2; k < blocksize; k++) {
+				if (!EC_POINT_dbl(group, base, base, ctx))
+					goto err;
+			}
+		}
+	}
+
+	if (!EC_POINTs_make_affine(group, num, points, ctx))
+		goto err;
+
+	pre_comp->group = group;
+	pre_comp->blocksize = blocksize;
+	pre_comp->numblocks = numblocks;
+	pre_comp->w = w;
+	pre_comp->points = points;
+	points = NULL;
+	pre_comp->num = num;
+
+	if (!EC_EX_DATA_set_data(&group->extra_data, pre_comp,
+		ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free))
+		goto err;
+	pre_comp = NULL;
+
+	ret = 1;
+err:
+	if (ctx != NULL)
+		BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	ec_pre_comp_free(pre_comp);
+	if (points) {
+		EC_POINT **p;
+
+		for (p = points; *p != NULL; p++)
+			EC_POINT_free(*p);
+		free(points);
+	}
+	EC_POINT_free(tmp_point);
+	EC_POINT_free(base);
+	return ret;
+}
+
+
+int 
+ec_wNAF_have_precompute_mult(const EC_GROUP * group)
+{
+	if (EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free) != NULL)
+		return 1;
+	else
+		return 0;
+}
diff --git a/crypto/libressl/crypto/ec/ec_oct.c b/crypto/libressl/crypto/ec/ec_oct.c
new file mode 100644
index 0000000000..d44fac0280
--- /dev/null
+++ b/crypto/libressl/crypto/ec/ec_oct.c
@@ -0,0 +1,192 @@
+/* $OpenBSD: ec_oct.c,v 1.3 2014/06/12 15:49:29 deraadt Exp $ */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Binary polynomial ECC support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+#include "ec_lcl.h"
+
+int 
+EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP * group, EC_POINT * point,
+    const BIGNUM * x, int y_bit, BN_CTX * ctx)
+{
+	if (group->meth->point_set_compressed_coordinates == 0
+	    && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
+		ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if (group->meth != point->meth) {
+		ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+	}
+	if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
+		if (group->meth->field_type == NID_X9_62_prime_field)
+			return ec_GFp_simple_set_compressed_coordinates(
+			    group, point, x, y_bit, ctx);
+		else
+#ifdef OPENSSL_NO_EC2M
+		{
+			ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_GF2M_NOT_SUPPORTED);
+			return 0;
+		}
+#else
+			return ec_GF2m_simple_set_compressed_coordinates(
+			    group, point, x, y_bit, ctx);
+#endif
+	}
+	return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
+}
+
+#ifndef OPENSSL_NO_EC2M
+int 
+EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP * group, EC_POINT * point,
+    const BIGNUM * x, int y_bit, BN_CTX * ctx)
+{
+	if (group->meth->point_set_compressed_coordinates == 0
+	    && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
+		ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if (group->meth != point->meth) {
+		ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+	}
+	if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
+		if (group->meth->field_type == NID_X9_62_prime_field)
+			return ec_GFp_simple_set_compressed_coordinates(
+			    group, point, x, y_bit, ctx);
+		else
+			return ec_GF2m_simple_set_compressed_coordinates(
+			    group, point, x, y_bit, ctx);
+	}
+	return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
+}
+#endif
+
+size_t 
+EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point,
+    point_conversion_form_t form,
+    unsigned char *buf, size_t len, BN_CTX *ctx)
+{
+	if (group->meth->point2oct == 0
+	    && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
+		ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if (group->meth != point->meth) {
+		ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+	}
+	if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
+		if (group->meth->field_type == NID_X9_62_prime_field)
+			return ec_GFp_simple_point2oct(group, point,
+			    form, buf, len, ctx);
+		else
+#ifdef OPENSSL_NO_EC2M
+		{
+			ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_GF2M_NOT_SUPPORTED);
+			return 0;
+		}
+#else
+			return ec_GF2m_simple_point2oct(group, point,
+			    form, buf, len, ctx);
+#endif
+	}
+	return group->meth->point2oct(group, point, form, buf, len, ctx);
+}
+
+
+int 
+EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
+    const unsigned char *buf, size_t len, BN_CTX *ctx)
+{
+	if (group->meth->oct2point == 0 &&
+	    !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
+		ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+		return 0;
+	}
+	if (group->meth != point->meth) {
+		ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS);
+		return 0;
+	}
+	if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
+		if (group->meth->field_type == NID_X9_62_prime_field)
+			return ec_GFp_simple_oct2point(group, point,
+			    buf, len, ctx);
+		else
+#ifdef OPENSSL_NO_EC2M
+		{
+			ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_GF2M_NOT_SUPPORTED);
+			return 0;
+		}
+#else
+			return ec_GF2m_simple_oct2point(group, point,
+			    buf, len, ctx);
+#endif
+	}
+	return group->meth->oct2point(group, point, buf, len, ctx);
+}
diff --git a/crypto/libressl/crypto/ec/ec_pmeth.c b/crypto/libressl/crypto/ec/ec_pmeth.c
new file mode 100644
index 0000000000..309a6c9757
--- /dev/null
+++ b/crypto/libressl/crypto/ec/ec_pmeth.c
@@ -0,0 +1,323 @@
+/* $OpenBSD: ec_pmeth.c,v 1.8 2014/07/12 16:03:37 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+
+/* EC pkey context structure */
+
+typedef struct {
+	/* Key and paramgen group */
+	EC_GROUP *gen_group;
+	/* message digest */
+	const EVP_MD *md;
+} EC_PKEY_CTX;
+
+static int 
+pkey_ec_init(EVP_PKEY_CTX * ctx)
+{
+	EC_PKEY_CTX *dctx;
+	dctx = malloc(sizeof(EC_PKEY_CTX));
+	if (!dctx)
+		return 0;
+	dctx->gen_group = NULL;
+	dctx->md = NULL;
+
+	ctx->data = dctx;
+
+	return 1;
+}
+
+static int 
+pkey_ec_copy(EVP_PKEY_CTX * dst, EVP_PKEY_CTX * src)
+{
+	EC_PKEY_CTX *dctx, *sctx;
+	if (!pkey_ec_init(dst))
+		return 0;
+	sctx = src->data;
+	dctx = dst->data;
+	if (sctx->gen_group) {
+		dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
+		if (!dctx->gen_group)
+			return 0;
+	}
+	dctx->md = sctx->md;
+	return 1;
+}
+
+static void 
+pkey_ec_cleanup(EVP_PKEY_CTX * ctx)
+{
+	EC_PKEY_CTX *dctx = ctx->data;
+	if (dctx) {
+		EC_GROUP_free(dctx->gen_group);
+		free(dctx);
+	}
+}
+
+static int 
+pkey_ec_sign(EVP_PKEY_CTX * ctx, unsigned char *sig, size_t * siglen,
+    const unsigned char *tbs, size_t tbslen)
+{
+	int ret, type;
+	unsigned int sltmp;
+	EC_PKEY_CTX *dctx = ctx->data;
+	EC_KEY *ec = ctx->pkey->pkey.ec;
+
+	if (!sig) {
+		*siglen = ECDSA_size(ec);
+		return 1;
+	} else if (*siglen < (size_t) ECDSA_size(ec)) {
+		ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL);
+		return 0;
+	}
+	if (dctx->md)
+		type = EVP_MD_type(dctx->md);
+	else
+		type = NID_sha1;
+
+
+	ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
+
+	if (ret <= 0)
+		return ret;
+	*siglen = (size_t) sltmp;
+	return 1;
+}
+
+static int 
+pkey_ec_verify(EVP_PKEY_CTX * ctx,
+    const unsigned char *sig, size_t siglen,
+    const unsigned char *tbs, size_t tbslen)
+{
+	int ret, type;
+	EC_PKEY_CTX *dctx = ctx->data;
+	EC_KEY *ec = ctx->pkey->pkey.ec;
+
+	if (dctx->md)
+		type = EVP_MD_type(dctx->md);
+	else
+		type = NID_sha1;
+
+	ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
+
+	return ret;
+}
+
+static int 
+pkey_ec_derive(EVP_PKEY_CTX * ctx, unsigned char *key, size_t * keylen)
+{
+	int ret;
+	size_t outlen;
+	const EC_POINT *pubkey = NULL;
+	if (!ctx->pkey || !ctx->peerkey) {
+		ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET);
+		return 0;
+	}
+	if (!key) {
+		const EC_GROUP *group;
+		group = EC_KEY_get0_group(ctx->pkey->pkey.ec);
+		*keylen = (EC_GROUP_get_degree(group) + 7) / 8;
+		return 1;
+	}
+	pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
+
+	/*
+	 * NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is
+	 * not an error, the result is truncated.
+	 */
+
+	outlen = *keylen;
+
+	ret = ECDH_compute_key(key, outlen, pubkey, ctx->pkey->pkey.ec, 0);
+	if (ret < 0)
+		return ret;
+	*keylen = ret;
+	return 1;
+}
+
+static int 
+pkey_ec_ctrl(EVP_PKEY_CTX * ctx, int type, int p1, void *p2)
+{
+	EC_PKEY_CTX *dctx = ctx->data;
+	EC_GROUP *group;
+	switch (type) {
+	case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
+		group = EC_GROUP_new_by_curve_name(p1);
+		if (group == NULL) {
+			ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE);
+			return 0;
+		}
+		EC_GROUP_free(dctx->gen_group);
+		dctx->gen_group = group;
+		return 1;
+
+	case EVP_PKEY_CTRL_MD:
+		if (EVP_MD_type((const EVP_MD *) p2) != NID_sha1 &&
+		    EVP_MD_type((const EVP_MD *) p2) != NID_ecdsa_with_SHA1 &&
+		    EVP_MD_type((const EVP_MD *) p2) != NID_sha224 &&
+		    EVP_MD_type((const EVP_MD *) p2) != NID_sha256 &&
+		    EVP_MD_type((const EVP_MD *) p2) != NID_sha384 &&
+		    EVP_MD_type((const EVP_MD *) p2) != NID_sha512) {
+			ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
+			return 0;
+		}
+		dctx->md = p2;
+		return 1;
+
+	case EVP_PKEY_CTRL_PEER_KEY:
+		/* Default behaviour is OK */
+	case EVP_PKEY_CTRL_DIGESTINIT:
+	case EVP_PKEY_CTRL_PKCS7_SIGN:
+	case EVP_PKEY_CTRL_CMS_SIGN:
+		return 1;
+
+	default:
+		return -2;
+
+	}
+}
+
+static int 
+pkey_ec_ctrl_str(EVP_PKEY_CTX * ctx,
+    const char *type, const char *value)
+{
+	if (!strcmp(type, "ec_paramgen_curve")) {
+		int nid;
+		nid = EC_curve_nist2nid(value);
+		if (nid == NID_undef)
+			nid = OBJ_sn2nid(value);
+		if (nid == NID_undef)
+			nid = OBJ_ln2nid(value);
+		if (nid == NID_undef) {
+			ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE);
+			return 0;
+		}
+		return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
+	}
+	return -2;
+}
+
+static int 
+pkey_ec_paramgen(EVP_PKEY_CTX * ctx, EVP_PKEY * pkey)
+{
+	EC_KEY *ec = NULL;
+	EC_PKEY_CTX *dctx = ctx->data;
+	int ret = 0;
+	if (dctx->gen_group == NULL) {
+		ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET);
+		return 0;
+	}
+	ec = EC_KEY_new();
+	if (!ec)
+		return 0;
+	ret = EC_KEY_set_group(ec, dctx->gen_group);
+	if (ret)
+		EVP_PKEY_assign_EC_KEY(pkey, ec);
+	else
+		EC_KEY_free(ec);
+	return ret;
+}
+
+static int 
+pkey_ec_keygen(EVP_PKEY_CTX * ctx, EVP_PKEY * pkey)
+{
+	EC_KEY *ec = NULL;
+	if (ctx->pkey == NULL) {
+		ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
+		return 0;
+	}
+	ec = EC_KEY_new();
+	if (!ec)
+		return 0;
+	EVP_PKEY_assign_EC_KEY(pkey, ec);
+	/* Note: if error return, pkey is freed by parent routine */
+	if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
+		return 0;
+	return EC_KEY_generate_key(pkey->pkey.ec);
+}
+
+const EVP_PKEY_METHOD ec_pkey_meth = {
+	.pkey_id = EVP_PKEY_EC,
+
+	.init = pkey_ec_init,
+	.copy = pkey_ec_copy,
+	.cleanup = pkey_ec_cleanup,
+
+	.paramgen = pkey_ec_paramgen,
+
+	.keygen = pkey_ec_keygen,
+
+	.sign = pkey_ec_sign,
+
+	.verify = pkey_ec_verify,
+
+	.derive = pkey_ec_derive,
+
+	.ctrl = pkey_ec_ctrl,
+	.ctrl_str = pkey_ec_ctrl_str
+};
diff --git a/crypto/libressl/crypto/ec/ec_print.c b/crypto/libressl/crypto/ec/ec_print.c
new file mode 100644
index 0000000000..911e03e993
--- /dev/null
+++ b/crypto/libressl/crypto/ec/ec_print.c
@@ -0,0 +1,178 @@
+/* $OpenBSD: ec_print.c,v 1.6 2014/12/03 19:45:16 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include "ec_lcl.h"
+
+BIGNUM *
+EC_POINT_point2bn(const EC_GROUP * group, const EC_POINT * point,
+    point_conversion_form_t form, BIGNUM * ret, BN_CTX * ctx)
+{
+	size_t buf_len = 0;
+	unsigned char *buf;
+
+	buf_len = EC_POINT_point2oct(group, point, form,
+	    NULL, 0, ctx);
+	if (buf_len == 0)
+		return NULL;
+
+	if ((buf = malloc(buf_len)) == NULL)
+		return NULL;
+
+	if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) {
+		free(buf);
+		return NULL;
+	}
+	ret = BN_bin2bn(buf, buf_len, ret);
+
+	free(buf);
+
+	return ret;
+}
+
+EC_POINT *
+EC_POINT_bn2point(const EC_GROUP * group,
+    const BIGNUM * bn, EC_POINT * point, BN_CTX * ctx)
+{
+	size_t buf_len = 0;
+	unsigned char *buf;
+	EC_POINT *ret;
+
+	if ((buf_len = BN_num_bytes(bn)) == 0)
+		return NULL;
+	buf = malloc(buf_len);
+	if (buf == NULL)
+		return NULL;
+
+	if (!BN_bn2bin(bn, buf)) {
+		free(buf);
+		return NULL;
+	}
+	if (point == NULL) {
+		if ((ret = EC_POINT_new(group)) == NULL) {
+			free(buf);
+			return NULL;
+		}
+	} else
+		ret = point;
+
+	if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx)) {
+		if (point == NULL)
+			EC_POINT_clear_free(ret);
+		free(buf);
+		return NULL;
+	}
+	free(buf);
+	return ret;
+}
+
+static const char *HEX_DIGITS = "0123456789ABCDEF";
+
+/* the return value must be freed (using free()) */
+char *
+EC_POINT_point2hex(const EC_GROUP * group, const EC_POINT * point,
+    point_conversion_form_t form, BN_CTX * ctx)
+{
+	char *ret, *p;
+	size_t buf_len = 0, i;
+	unsigned char *buf, *pbuf;
+
+	buf_len = EC_POINT_point2oct(group, point, form,
+	    NULL, 0, ctx);
+	if (buf_len == 0 || buf_len + 1 == 0)
+		return NULL;
+
+	if ((buf = malloc(buf_len)) == NULL)
+		return NULL;
+
+	if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) {
+		free(buf);
+		return NULL;
+	}
+	ret = reallocarray(NULL, buf_len + 1, 2);
+	if (ret == NULL) {
+		free(buf);
+		return NULL;
+	}
+	p = ret;
+	pbuf = buf;
+	for (i = buf_len; i > 0; i--) {
+		int v = (int) *(pbuf++);
+		*(p++) = HEX_DIGITS[v >> 4];
+		*(p++) = HEX_DIGITS[v & 0x0F];
+	}
+	*p = '\0';
+
+	free(buf);
+
+	return ret;
+}
+
+EC_POINT *
+EC_POINT_hex2point(const EC_GROUP * group, const char *buf,
+    EC_POINT * point, BN_CTX * ctx)
+{
+	EC_POINT *ret = NULL;
+	BIGNUM *tmp_bn = NULL;
+
+	if (!BN_hex2bn(&tmp_bn, buf))
+		return NULL;
+
+	ret = EC_POINT_bn2point(group, tmp_bn, point, ctx);
+
+	BN_clear_free(tmp_bn);
+
+	return ret;
+}
diff --git a/crypto/libressl/crypto/ec/eck_prn.c b/crypto/libressl/crypto/ec/eck_prn.c
new file mode 100644
index 0000000000..d361a0dd12
--- /dev/null
+++ b/crypto/libressl/crypto/ec/eck_prn.c
@@ -0,0 +1,371 @@
+/* $OpenBSD: eck_prn.c,v 1.10 2014/07/12 16:03:37 miod Exp $ */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions originally developed by SUN MICROSYSTEMS, INC., and
+ * contributed to the OpenSSL project.
+ */
+
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+int 
+ECPKParameters_print_fp(FILE * fp, const EC_GROUP * x, int off)
+{
+	BIO *b;
+	int ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL) {
+		ECerr(EC_F_ECPKPARAMETERS_PRINT_FP, ERR_R_BUF_LIB);
+		return (0);
+	}
+	BIO_set_fp(b, fp, BIO_NOCLOSE);
+	ret = ECPKParameters_print(b, x, off);
+	BIO_free(b);
+	return (ret);
+}
+
+int 
+EC_KEY_print_fp(FILE * fp, const EC_KEY * x, int off)
+{
+	BIO *b;
+	int ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL) {
+		ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
+		return (0);
+	}
+	BIO_set_fp(b, fp, BIO_NOCLOSE);
+	ret = EC_KEY_print(b, x, off);
+	BIO_free(b);
+	return (ret);
+}
+
+int 
+ECParameters_print_fp(FILE * fp, const EC_KEY * x)
+{
+	BIO *b;
+	int ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL) {
+		ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
+		return (0);
+	}
+	BIO_set_fp(b, fp, BIO_NOCLOSE);
+	ret = ECParameters_print(b, x);
+	BIO_free(b);
+	return (ret);
+}
+
+int 
+EC_KEY_print(BIO * bp, const EC_KEY * x, int off)
+{
+	EVP_PKEY *pk;
+	int ret;
+	pk = EVP_PKEY_new();
+	if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *) x))
+		return 0;
+	ret = EVP_PKEY_print_private(bp, pk, off, NULL);
+	EVP_PKEY_free(pk);
+	return ret;
+}
+
+int 
+ECParameters_print(BIO * bp, const EC_KEY * x)
+{
+	EVP_PKEY *pk;
+	int ret;
+	pk = EVP_PKEY_new();
+	if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *) x))
+		return 0;
+	ret = EVP_PKEY_print_params(bp, pk, 4, NULL);
+	EVP_PKEY_free(pk);
+	return ret;
+}
+
+static int 
+print_bin(BIO * fp, const char *str, const unsigned char *num,
+    size_t len, int off);
+
+int 
+ECPKParameters_print(BIO * bp, const EC_GROUP * x, int off)
+{
+	unsigned char *buffer = NULL;
+	size_t buf_len = 0, i;
+	int ret = 0, reason = ERR_R_BIO_LIB;
+	BN_CTX *ctx = NULL;
+	const EC_POINT *point = NULL;
+	BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL, *order = NULL,
+	*cofactor = NULL;
+	const unsigned char *seed;
+	size_t seed_len = 0;
+	const char *nname;
+
+	static const char *gen_compressed = "Generator (compressed):";
+	static const char *gen_uncompressed = "Generator (uncompressed):";
+	static const char *gen_hybrid = "Generator (hybrid):";
+
+	if (!x) {
+		reason = ERR_R_PASSED_NULL_PARAMETER;
+		goto err;
+	}
+	ctx = BN_CTX_new();
+	if (ctx == NULL) {
+		reason = ERR_R_MALLOC_FAILURE;
+		goto err;
+	}
+	if (EC_GROUP_get_asn1_flag(x)) {
+		/* the curve parameter are given by an asn1 OID */
+		int nid;
+
+		if (!BIO_indent(bp, off, 128))
+			goto err;
+
+		nid = EC_GROUP_get_curve_name(x);
+		if (nid == 0)
+			goto err;
+
+		if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
+			goto err;
+		if (BIO_printf(bp, "\n") <= 0)
+			goto err;
+
+		nname = EC_curve_nid2nist(nid);
+		if (nname) {
+			if (!BIO_indent(bp, off, 128))
+				goto err;
+			if (BIO_printf(bp, "NIST CURVE: %s\n", nname) <= 0)
+				goto err;
+		}
+	} else {
+		/* explicit parameters */
+		int is_char_two = 0;
+		point_conversion_form_t form;
+		int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
+
+		if (tmp_nid == NID_X9_62_characteristic_two_field)
+			is_char_two = 1;
+
+		if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
+		    (b = BN_new()) == NULL || (order = BN_new()) == NULL ||
+		    (cofactor = BN_new()) == NULL) {
+			reason = ERR_R_MALLOC_FAILURE;
+			goto err;
+		}
+#ifndef OPENSSL_NO_EC2M
+		if (is_char_two) {
+			if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) {
+				reason = ERR_R_EC_LIB;
+				goto err;
+			}
+		} else		/* prime field */
+#endif
+		{
+			if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) {
+				reason = ERR_R_EC_LIB;
+				goto err;
+			}
+		}
+
+		if ((point = EC_GROUP_get0_generator(x)) == NULL) {
+			reason = ERR_R_EC_LIB;
+			goto err;
+		}
+		if (!EC_GROUP_get_order(x, order, NULL) ||
+		    !EC_GROUP_get_cofactor(x, cofactor, NULL)) {
+			reason = ERR_R_EC_LIB;
+			goto err;
+		}
+		form = EC_GROUP_get_point_conversion_form(x);
+
+		if ((gen = EC_POINT_point2bn(x, point,
+			    form, NULL, ctx)) == NULL) {
+			reason = ERR_R_EC_LIB;
+			goto err;
+		}
+		buf_len = (size_t) BN_num_bytes(p);
+		if (buf_len < (i = (size_t) BN_num_bytes(a)))
+			buf_len = i;
+		if (buf_len < (i = (size_t) BN_num_bytes(b)))
+			buf_len = i;
+		if (buf_len < (i = (size_t) BN_num_bytes(gen)))
+			buf_len = i;
+		if (buf_len < (i = (size_t) BN_num_bytes(order)))
+			buf_len = i;
+		if (buf_len < (i = (size_t) BN_num_bytes(cofactor)))
+			buf_len = i;
+
+		if ((seed = EC_GROUP_get0_seed(x)) != NULL)
+			seed_len = EC_GROUP_get_seed_len(x);
+
+		buf_len += 10;
+		if ((buffer = malloc(buf_len)) == NULL) {
+			reason = ERR_R_MALLOC_FAILURE;
+			goto err;
+		}
+		if (!BIO_indent(bp, off, 128))
+			goto err;
+
+		/* print the 'short name' of the field type */
+		if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
+		    <= 0)
+			goto err;
+
+		if (is_char_two) {
+			/* print the 'short name' of the base type OID */
+			int basis_type = EC_GROUP_get_basis_type(x);
+			if (basis_type == 0)
+				goto err;
+
+			if (!BIO_indent(bp, off, 128))
+				goto err;
+
+			if (BIO_printf(bp, "Basis Type: %s\n",
+				OBJ_nid2sn(basis_type)) <= 0)
+				goto err;
+
+			/* print the polynomial */
+			if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer,
+				off))
+				goto err;
+		} else {
+			if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer, off))
+				goto err;
+		}
+		if ((a != NULL) && !ASN1_bn_print(bp, "A:   ", a, buffer, off))
+			goto err;
+		if ((b != NULL) && !ASN1_bn_print(bp, "B:   ", b, buffer, off))
+			goto err;
+		if (form == POINT_CONVERSION_COMPRESSED) {
+			if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen,
+				buffer, off))
+				goto err;
+		} else if (form == POINT_CONVERSION_UNCOMPRESSED) {
+			if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen,
+				buffer, off))
+				goto err;
+		} else {	/* form == POINT_CONVERSION_HYBRID */
+			if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen,
+				buffer, off))
+				goto err;
+		}
+		if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order,
+			buffer, off))
+			goto err;
+		if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor,
+			buffer, off))
+			goto err;
+		if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
+			goto err;
+	}
+	ret = 1;
+err:
+	if (!ret)
+		ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
+	BN_free(p);
+	BN_free(a);
+	BN_free(b);
+	BN_free(gen);
+	BN_free(order);
+	BN_free(cofactor);
+	BN_CTX_free(ctx);
+	free(buffer);
+	return (ret);
+}
+
+static int 
+print_bin(BIO * fp, const char *name, const unsigned char *buf,
+    size_t len, int off)
+{
+	size_t i;
+	char str[128];
+
+	if (buf == NULL)
+		return 1;
+	if (off) {
+		if (off > 128)
+			off = 128;
+		memset(str, ' ', off);
+		if (BIO_write(fp, str, off) <= 0)
+			return 0;
+	}
+	if (BIO_printf(fp, "%s", name) <= 0)
+		return 0;
+
+	for (i = 0; i < len; i++) {
+		if ((i % 15) == 0) {
+			str[0] = '\n';
+			memset(&(str[1]), ' ', off + 4);
+			if (BIO_write(fp, str, off + 1 + 4) <= 0)
+				return 0;
+		}
+		if (BIO_printf(fp, "%02x%s", buf[i], ((i + 1) == len) ? "" : ":") <= 0)
+			return 0;
+	}
+	if (BIO_write(fp, "\n", 1) <= 0)
+		return 0;
+
+	return 1;
+}
diff --git a/crypto/libressl/crypto/ec/ecp_mont.c b/crypto/libressl/crypto/ec/ecp_mont.c
new file mode 100644
index 0000000000..2e10952a82
--- /dev/null
+++ b/crypto/libressl/crypto/ec/ecp_mont.c
@@ -0,0 +1,294 @@
+/* $OpenBSD: ecp_mont.c,v 1.9 2014/07/12 16:03:37 miod Exp $ */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include 
+
+#include "ec_lcl.h"
+
+
+const EC_METHOD *
+EC_GFp_mont_method(void)
+{
+	static const EC_METHOD ret = {
+		.flags = EC_FLAGS_DEFAULT_OCT,
+		.field_type = NID_X9_62_prime_field,
+		.group_init = ec_GFp_mont_group_init,
+		.group_finish = ec_GFp_mont_group_finish,
+		.group_clear_finish = ec_GFp_mont_group_clear_finish,
+		.group_copy = ec_GFp_mont_group_copy,
+		.group_set_curve = ec_GFp_mont_group_set_curve,
+		.group_get_curve = ec_GFp_simple_group_get_curve,
+		.group_get_degree = ec_GFp_simple_group_get_degree,
+		.group_check_discriminant =
+		ec_GFp_simple_group_check_discriminant,
+		.point_init = ec_GFp_simple_point_init,
+		.point_finish = ec_GFp_simple_point_finish,
+		.point_clear_finish = ec_GFp_simple_point_clear_finish,
+		.point_copy = ec_GFp_simple_point_copy,
+		.point_set_to_infinity = ec_GFp_simple_point_set_to_infinity,
+		.point_set_Jprojective_coordinates_GFp =
+		ec_GFp_simple_set_Jprojective_coordinates_GFp,
+		.point_get_Jprojective_coordinates_GFp =
+		ec_GFp_simple_get_Jprojective_coordinates_GFp,
+		.point_set_affine_coordinates =
+		ec_GFp_simple_point_set_affine_coordinates,
+		.point_get_affine_coordinates =
+		ec_GFp_simple_point_get_affine_coordinates,
+		.add = ec_GFp_simple_add,
+		.dbl = ec_GFp_simple_dbl,
+		.invert = ec_GFp_simple_invert,
+		.is_at_infinity = ec_GFp_simple_is_at_infinity,
+		.is_on_curve = ec_GFp_simple_is_on_curve,
+		.point_cmp = ec_GFp_simple_cmp,
+		.make_affine = ec_GFp_simple_make_affine,
+		.points_make_affine = ec_GFp_simple_points_make_affine,
+		.field_mul = ec_GFp_mont_field_mul,
+		.field_sqr = ec_GFp_mont_field_sqr,
+		.field_encode = ec_GFp_mont_field_encode,
+		.field_decode = ec_GFp_mont_field_decode,
+		.field_set_to_one = ec_GFp_mont_field_set_to_one
+	};
+
+	return &ret;
+}
+
+
+int 
+ec_GFp_mont_group_init(EC_GROUP * group)
+{
+	int ok;
+
+	ok = ec_GFp_simple_group_init(group);
+	group->field_data1 = NULL;
+	group->field_data2 = NULL;
+	return ok;
+}
+
+
+void 
+ec_GFp_mont_group_finish(EC_GROUP * group)
+{
+	BN_MONT_CTX_free(group->field_data1);
+	group->field_data1 = NULL;
+	BN_free(group->field_data2);
+	group->field_data2 = NULL;
+	ec_GFp_simple_group_finish(group);
+}
+
+
+void 
+ec_GFp_mont_group_clear_finish(EC_GROUP * group)
+{
+	BN_MONT_CTX_free(group->field_data1);
+	group->field_data1 = NULL;
+	BN_clear_free(group->field_data2);
+	group->field_data2 = NULL;
+	ec_GFp_simple_group_clear_finish(group);
+}
+
+
+int 
+ec_GFp_mont_group_copy(EC_GROUP * dest, const EC_GROUP * src)
+{
+	BN_MONT_CTX_free(dest->field_data1);
+	dest->field_data1 = NULL;
+	BN_clear_free(dest->field_data2);
+	dest->field_data2 = NULL;
+
+	if (!ec_GFp_simple_group_copy(dest, src))
+		return 0;
+
+	if (src->field_data1 != NULL) {
+		dest->field_data1 = BN_MONT_CTX_new();
+		if (dest->field_data1 == NULL)
+			return 0;
+		if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1))
+			goto err;
+	}
+	if (src->field_data2 != NULL) {
+		dest->field_data2 = BN_dup(src->field_data2);
+		if (dest->field_data2 == NULL)
+			goto err;
+	}
+	return 1;
+
+err:
+	if (dest->field_data1 != NULL) {
+		BN_MONT_CTX_free(dest->field_data1);
+		dest->field_data1 = NULL;
+	}
+	return 0;
+}
+
+
+int 
+ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
+    const BIGNUM *b, BN_CTX *ctx)
+{
+	BN_CTX *new_ctx = NULL;
+	BN_MONT_CTX *mont = NULL;
+	BIGNUM *one = NULL;
+	int ret = 0;
+
+	BN_MONT_CTX_free(group->field_data1);
+	group->field_data1 = NULL;
+	BN_free(group->field_data2);
+	group->field_data2 = NULL;
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+	}
+	mont = BN_MONT_CTX_new();
+	if (mont == NULL)
+		goto err;
+	if (!BN_MONT_CTX_set(mont, p, ctx)) {
+		ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB);
+		goto err;
+	}
+	one = BN_new();
+	if (one == NULL)
+		goto err;
+	if (!BN_to_montgomery(one, BN_value_one(), mont, ctx))
+		goto err;
+
+	group->field_data1 = mont;
+	mont = NULL;
+	group->field_data2 = one;
+	one = NULL;
+
+	ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+
+	if (!ret) {
+		BN_MONT_CTX_free(group->field_data1);
+		group->field_data1 = NULL;
+		BN_free(group->field_data2);
+		group->field_data2 = NULL;
+	}
+err:
+	BN_CTX_free(new_ctx);
+	BN_MONT_CTX_free(mont);
+	BN_free(one);
+	return ret;
+}
+
+
+int 
+ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+    const BIGNUM *b, BN_CTX *ctx)
+{
+	if (group->field_data1 == NULL) {
+		ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED);
+		return 0;
+	}
+	return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx);
+}
+
+
+int 
+ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+    BN_CTX *ctx)
+{
+	if (group->field_data1 == NULL) {
+		ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED);
+		return 0;
+	}
+	return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx);
+}
+
+
+int 
+ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+    BN_CTX *ctx)
+{
+	if (group->field_data1 == NULL) {
+		ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED);
+		return 0;
+	}
+	return BN_to_montgomery(r, a, (BN_MONT_CTX *) group->field_data1, ctx);
+}
+
+
+int 
+ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+    BN_CTX *ctx)
+{
+	if (group->field_data1 == NULL) {
+		ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED);
+		return 0;
+	}
+	return BN_from_montgomery(r, a, group->field_data1, ctx);
+}
+
+
+int 
+ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, BN_CTX *ctx)
+{
+	if (group->field_data2 == NULL) {
+		ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED);
+		return 0;
+	}
+	if (!BN_copy(r, group->field_data2))
+		return 0;
+	return 1;
+}
diff --git a/crypto/libressl/crypto/ec/ecp_nist.c b/crypto/libressl/crypto/ec/ecp_nist.c
new file mode 100644
index 0000000000..dee94b62bb
--- /dev/null
+++ b/crypto/libressl/crypto/ec/ecp_nist.c
@@ -0,0 +1,212 @@
+/* $OpenBSD: ecp_nist.c,v 1.8 2014/06/12 15:49:29 deraadt Exp $ */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include 
+
+#include 
+#include 
+#include "ec_lcl.h"
+
+const EC_METHOD *
+EC_GFp_nist_method(void)
+{
+	static const EC_METHOD ret = {
+		.flags = EC_FLAGS_DEFAULT_OCT,
+		.field_type = NID_X9_62_prime_field,
+		.group_init = ec_GFp_simple_group_init,
+		.group_finish = ec_GFp_simple_group_finish,
+		.group_clear_finish = ec_GFp_simple_group_clear_finish,
+		.group_copy = ec_GFp_nist_group_copy,
+		.group_set_curve = ec_GFp_nist_group_set_curve,
+		.group_get_curve = ec_GFp_simple_group_get_curve,
+		.group_get_degree = ec_GFp_simple_group_get_degree,
+		.group_check_discriminant =
+		ec_GFp_simple_group_check_discriminant,
+		.point_init = ec_GFp_simple_point_init,
+		.point_finish = ec_GFp_simple_point_finish,
+		.point_clear_finish = ec_GFp_simple_point_clear_finish,
+		.point_copy = ec_GFp_simple_point_copy,
+		.point_set_to_infinity = ec_GFp_simple_point_set_to_infinity,
+		.point_set_Jprojective_coordinates_GFp =
+		ec_GFp_simple_set_Jprojective_coordinates_GFp,
+		.point_get_Jprojective_coordinates_GFp =
+		ec_GFp_simple_get_Jprojective_coordinates_GFp,
+		.point_set_affine_coordinates =
+		ec_GFp_simple_point_set_affine_coordinates,
+		.point_get_affine_coordinates =
+		ec_GFp_simple_point_get_affine_coordinates,
+		.add = ec_GFp_simple_add,
+		.dbl = ec_GFp_simple_dbl,
+		.invert = ec_GFp_simple_invert,
+		.is_at_infinity = ec_GFp_simple_is_at_infinity,
+		.is_on_curve = ec_GFp_simple_is_on_curve,
+		.point_cmp = ec_GFp_simple_cmp,
+		.make_affine = ec_GFp_simple_make_affine,
+		.points_make_affine = ec_GFp_simple_points_make_affine,
+		.field_mul = ec_GFp_nist_field_mul,
+		.field_sqr = ec_GFp_nist_field_sqr
+	};
+
+	return &ret;
+}
+
+int 
+ec_GFp_nist_group_copy(EC_GROUP * dest, const EC_GROUP * src)
+{
+	dest->field_mod_func = src->field_mod_func;
+
+	return ec_GFp_simple_group_copy(dest, src);
+}
+
+int 
+ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+    const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+{
+	int ret = 0;
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *tmp_bn;
+
+	if (ctx == NULL)
+		if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+			return 0;
+
+	BN_CTX_start(ctx);
+	if ((tmp_bn = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
+		group->field_mod_func = BN_nist_mod_192;
+	else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0)
+		group->field_mod_func = BN_nist_mod_224;
+	else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0)
+		group->field_mod_func = BN_nist_mod_256;
+	else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0)
+		group->field_mod_func = BN_nist_mod_384;
+	else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0)
+		group->field_mod_func = BN_nist_mod_521;
+	else {
+		ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME);
+		goto err;
+	}
+
+	ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+
+err:
+	BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+
+
+int 
+ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+    const BIGNUM *b, BN_CTX *ctx)
+{
+	int ret = 0;
+	BN_CTX *ctx_new = NULL;
+
+	if (!group || !r || !a || !b) {
+		ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER);
+		goto err;
+	}
+	if (!ctx)
+		if ((ctx_new = ctx = BN_CTX_new()) == NULL)
+			goto err;
+
+	if (!BN_mul(r, a, b, ctx))
+		goto err;
+	if (!group->field_mod_func(r, r, &group->field, ctx))
+		goto err;
+
+	ret = 1;
+err:
+	BN_CTX_free(ctx_new);
+	return ret;
+}
+
+
+int 
+ec_GFp_nist_field_sqr(const EC_GROUP * group, BIGNUM * r, const BIGNUM * a,
+    BN_CTX * ctx)
+{
+	int ret = 0;
+	BN_CTX *ctx_new = NULL;
+
+	if (!group || !r || !a) {
+		ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER);
+		goto err;
+	}
+	if (!ctx)
+		if ((ctx_new = ctx = BN_CTX_new()) == NULL)
+			goto err;
+
+	if (!BN_sqr(r, a, ctx))
+		goto err;
+	if (!group->field_mod_func(r, r, &group->field, ctx))
+		goto err;
+
+	ret = 1;
+err:
+	BN_CTX_free(ctx_new);
+	return ret;
+}
diff --git a/crypto/libressl/crypto/ec/ecp_oct.c b/crypto/libressl/crypto/ec/ecp_oct.c
new file mode 100644
index 0000000000..56da527ded
--- /dev/null
+++ b/crypto/libressl/crypto/ec/ecp_oct.c
@@ -0,0 +1,395 @@
+/* $OpenBSD: ecp_oct.c,v 1.6 2015/02/08 22:25:03 miod Exp $ */
+/* Includes code written by Lenka Fibikova 
+ * for the OpenSSL project.
+ * Includes code written by Bodo Moeller for the OpenSSL project.
+*/
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include 
+
+#include "ec_lcl.h"
+
+int 
+ec_GFp_simple_set_compressed_coordinates(const EC_GROUP * group,
+    EC_POINT * point, const BIGNUM * x_, int y_bit, BN_CTX * ctx)
+{
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *tmp1, *tmp2, *x, *y;
+	int ret = 0;
+
+	/* clear error queue */
+	ERR_clear_error();
+
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+	}
+	y_bit = (y_bit != 0);
+
+	BN_CTX_start(ctx);
+	if ((tmp1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((tmp2 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((x = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((y = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	/*
+	 * Recover y.  We have a Weierstrass equation y^2 = x^3 + a*x + b, so
+	 * y  is one of the square roots of  x^3 + a*x + b.
+	 */
+
+	/* tmp1 := x^3 */
+	if (!BN_nnmod(x, x_, &group->field, ctx))
+		goto err;
+	if (group->meth->field_decode == 0) {
+		/* field_{sqr,mul} work on standard representation */
+		if (!group->meth->field_sqr(group, tmp2, x_, ctx))
+			goto err;
+		if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx))
+			goto err;
+	} else {
+		if (!BN_mod_sqr(tmp2, x_, &group->field, ctx))
+			goto err;
+		if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx))
+			goto err;
+	}
+
+	/* tmp1 := tmp1 + a*x */
+	if (group->a_is_minus3) {
+		if (!BN_mod_lshift1_quick(tmp2, x, &group->field))
+			goto err;
+		if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field))
+			goto err;
+		if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field))
+			goto err;
+	} else {
+		if (group->meth->field_decode) {
+			if (!group->meth->field_decode(group, tmp2, &group->a, ctx))
+				goto err;
+			if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx))
+				goto err;
+		} else {
+			/* field_mul works on standard representation */
+			if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx))
+				goto err;
+		}
+
+		if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field))
+			goto err;
+	}
+
+	/* tmp1 := tmp1 + b */
+	if (group->meth->field_decode) {
+		if (!group->meth->field_decode(group, tmp2, &group->b, ctx))
+			goto err;
+		if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field))
+			goto err;
+	} else {
+		if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field))
+			goto err;
+	}
+
+	if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) {
+		unsigned long err = ERR_peek_last_error();
+
+		if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) {
+			ERR_clear_error();
+			ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
+		} else
+			ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
+		goto err;
+	}
+	if (y_bit != BN_is_odd(y)) {
+		if (BN_is_zero(y)) {
+			int kron;
+
+			kron = BN_kronecker(x, &group->field, ctx);
+			if (kron == -2)
+				goto err;
+
+			if (kron == 1)
+				ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSION_BIT);
+			else
+				/*
+				 * BN_mod_sqrt() should have cought this
+				 * error (not a square)
+				 */
+				ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
+			goto err;
+		}
+		if (!BN_usub(y, &group->field, y))
+			goto err;
+	}
+	if (y_bit != BN_is_odd(y)) {
+		ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_INTERNAL_ERROR);
+		goto err;
+	}
+	if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
+		goto err;
+
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+
+
+size_t 
+ec_GFp_simple_point2oct(const EC_GROUP * group, const EC_POINT * point, point_conversion_form_t form,
+    unsigned char *buf, size_t len, BN_CTX * ctx)
+{
+	size_t ret;
+	BN_CTX *new_ctx = NULL;
+	int used_ctx = 0;
+	BIGNUM *x, *y;
+	size_t field_len, i, skip;
+
+	if ((form != POINT_CONVERSION_COMPRESSED)
+	    && (form != POINT_CONVERSION_UNCOMPRESSED)
+	    && (form != POINT_CONVERSION_HYBRID)) {
+		ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
+		goto err;
+	}
+	if (EC_POINT_is_at_infinity(group, point) > 0) {
+		/* encodes to a single 0 octet */
+		if (buf != NULL) {
+			if (len < 1) {
+				ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+				return 0;
+			}
+			buf[0] = 0;
+		}
+		return 1;
+	}
+	/* ret := required output buffer length */
+	field_len = BN_num_bytes(&group->field);
+	ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
+
+	/* if 'buf' is NULL, just return required length */
+	if (buf != NULL) {
+		if (len < ret) {
+			ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+			goto err;
+		}
+		if (ctx == NULL) {
+			ctx = new_ctx = BN_CTX_new();
+			if (ctx == NULL)
+				return 0;
+		}
+		BN_CTX_start(ctx);
+		used_ctx = 1;
+		if ((x = BN_CTX_get(ctx)) == NULL)
+			goto err;
+		if ((y = BN_CTX_get(ctx)) == NULL)
+			goto err;
+
+		if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx))
+			goto err;
+
+		if ((form == POINT_CONVERSION_COMPRESSED || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
+			buf[0] = form + 1;
+		else
+			buf[0] = form;
+
+		i = 1;
+
+		skip = field_len - BN_num_bytes(x);
+		if (skip > field_len) {
+			ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+			goto err;
+		}
+		while (skip > 0) {
+			buf[i++] = 0;
+			skip--;
+		}
+		skip = BN_bn2bin(x, buf + i);
+		i += skip;
+		if (i != 1 + field_len) {
+			ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+			goto err;
+		}
+		if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID) {
+			skip = field_len - BN_num_bytes(y);
+			if (skip > field_len) {
+				ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+				goto err;
+			}
+			while (skip > 0) {
+				buf[i++] = 0;
+				skip--;
+			}
+			skip = BN_bn2bin(y, buf + i);
+			i += skip;
+		}
+		if (i != ret) {
+			ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+			goto err;
+		}
+	}
+	if (used_ctx)
+		BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return ret;
+
+err:
+	if (used_ctx)
+		BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return 0;
+}
+
+
+int 
+ec_GFp_simple_oct2point(const EC_GROUP * group, EC_POINT * point,
+    const unsigned char *buf, size_t len, BN_CTX * ctx)
+{
+	point_conversion_form_t form;
+	int y_bit;
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *x, *y;
+	size_t field_len, enc_len;
+	int ret = 0;
+
+	if (len == 0) {
+		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
+		return 0;
+	}
+	form = buf[0];
+	y_bit = form & 1;
+	form = form & ~1U;
+	if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
+	    && (form != POINT_CONVERSION_UNCOMPRESSED)
+	    && (form != POINT_CONVERSION_HYBRID)) {
+		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+		return 0;
+	}
+	if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
+		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+		return 0;
+	}
+	if (form == 0) {
+		if (len != 1) {
+			ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+			return 0;
+		}
+		return EC_POINT_set_to_infinity(group, point);
+	}
+	field_len = BN_num_bytes(&group->field);
+	enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
+
+	if (len != enc_len) {
+		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+		return 0;
+	}
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+	}
+	BN_CTX_start(ctx);
+	if ((x = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((y = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!BN_bin2bn(buf + 1, field_len, x))
+		goto err;
+	if (BN_ucmp(x, &group->field) >= 0) {
+		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+		goto err;
+	}
+	if (form == POINT_CONVERSION_COMPRESSED) {
+		if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx))
+			goto err;
+	} else {
+		if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
+			goto err;
+		if (BN_ucmp(y, &group->field) >= 0) {
+			ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+			goto err;
+		}
+		if (form == POINT_CONVERSION_HYBRID) {
+			if (y_bit != BN_is_odd(y)) {
+				ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+				goto err;
+			}
+		}
+		if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
+			goto err;
+	}
+
+	/* test required by X9.62 */
+	if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
+		ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
+		goto err;
+	}
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return ret;
+}
diff --git a/crypto/libressl/crypto/ec/ecp_smpl.c b/crypto/libressl/crypto/ec/ecp_smpl.c
new file mode 100644
index 0000000000..a6192ac7e9
--- /dev/null
+++ b/crypto/libressl/crypto/ec/ecp_smpl.c
@@ -0,0 +1,1410 @@
+/* $OpenBSD: ecp_smpl.c,v 1.14 2015/02/08 22:25:03 miod Exp $ */
+/* Includes code written by Lenka Fibikova 
+ * for the OpenSSL project.
+ * Includes code written by Bodo Moeller for the OpenSSL project.
+*/
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include 
+
+#include "ec_lcl.h"
+
+const EC_METHOD *
+EC_GFp_simple_method(void)
+{
+	static const EC_METHOD ret = {
+		.flags = EC_FLAGS_DEFAULT_OCT,
+		.field_type = NID_X9_62_prime_field,
+		.group_init = ec_GFp_simple_group_init,
+		.group_finish = ec_GFp_simple_group_finish,
+		.group_clear_finish = ec_GFp_simple_group_clear_finish,
+		.group_copy = ec_GFp_simple_group_copy,
+		.group_set_curve = ec_GFp_simple_group_set_curve,
+		.group_get_curve = ec_GFp_simple_group_get_curve,
+		.group_get_degree = ec_GFp_simple_group_get_degree,
+		.group_check_discriminant =
+		ec_GFp_simple_group_check_discriminant,
+		.point_init = ec_GFp_simple_point_init,
+		.point_finish = ec_GFp_simple_point_finish,
+		.point_clear_finish = ec_GFp_simple_point_clear_finish,
+		.point_copy = ec_GFp_simple_point_copy,
+		.point_set_to_infinity = ec_GFp_simple_point_set_to_infinity,
+		.point_set_Jprojective_coordinates_GFp =
+		ec_GFp_simple_set_Jprojective_coordinates_GFp,
+		.point_get_Jprojective_coordinates_GFp =
+		ec_GFp_simple_get_Jprojective_coordinates_GFp,
+		.point_set_affine_coordinates =
+		ec_GFp_simple_point_set_affine_coordinates,
+		.point_get_affine_coordinates =
+		ec_GFp_simple_point_get_affine_coordinates,
+		.add = ec_GFp_simple_add,
+		.dbl = ec_GFp_simple_dbl,
+		.invert = ec_GFp_simple_invert,
+		.is_at_infinity = ec_GFp_simple_is_at_infinity,
+		.is_on_curve = ec_GFp_simple_is_on_curve,
+		.point_cmp = ec_GFp_simple_cmp,
+		.make_affine = ec_GFp_simple_make_affine,
+		.points_make_affine = ec_GFp_simple_points_make_affine,
+		.field_mul = ec_GFp_simple_field_mul,
+		.field_sqr = ec_GFp_simple_field_sqr
+	};
+
+	return &ret;
+}
+
+
+/* Most method functions in this file are designed to work with
+ * non-trivial representations of field elements if necessary
+ * (see ecp_mont.c): while standard modular addition and subtraction
+ * are used, the field_mul and field_sqr methods will be used for
+ * multiplication, and field_encode and field_decode (if defined)
+ * will be used for converting between representations.
+
+ * Functions ec_GFp_simple_points_make_affine() and
+ * ec_GFp_simple_point_get_affine_coordinates() specifically assume
+ * that if a non-trivial representation is used, it is a Montgomery
+ * representation (i.e. 'encoding' means multiplying by some factor R).
+ */
+
+
+int 
+ec_GFp_simple_group_init(EC_GROUP * group)
+{
+	BN_init(&group->field);
+	BN_init(&group->a);
+	BN_init(&group->b);
+	group->a_is_minus3 = 0;
+	return 1;
+}
+
+
+void 
+ec_GFp_simple_group_finish(EC_GROUP * group)
+{
+	BN_free(&group->field);
+	BN_free(&group->a);
+	BN_free(&group->b);
+}
+
+
+void 
+ec_GFp_simple_group_clear_finish(EC_GROUP * group)
+{
+	BN_clear_free(&group->field);
+	BN_clear_free(&group->a);
+	BN_clear_free(&group->b);
+}
+
+
+int 
+ec_GFp_simple_group_copy(EC_GROUP * dest, const EC_GROUP * src)
+{
+	if (!BN_copy(&dest->field, &src->field))
+		return 0;
+	if (!BN_copy(&dest->a, &src->a))
+		return 0;
+	if (!BN_copy(&dest->b, &src->b))
+		return 0;
+
+	dest->a_is_minus3 = src->a_is_minus3;
+
+	return 1;
+}
+
+
+int 
+ec_GFp_simple_group_set_curve(EC_GROUP * group,
+    const BIGNUM * p, const BIGNUM * a, const BIGNUM * b, BN_CTX * ctx)
+{
+	int ret = 0;
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *tmp_a;
+
+	/* p must be a prime > 3 */
+	if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) {
+		ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD);
+		return 0;
+	}
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+	}
+	BN_CTX_start(ctx);
+	if ((tmp_a = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	/* group->field */
+	if (!BN_copy(&group->field, p))
+		goto err;
+	BN_set_negative(&group->field, 0);
+
+	/* group->a */
+	if (!BN_nnmod(tmp_a, a, p, ctx))
+		goto err;
+	if (group->meth->field_encode) {
+		if (!group->meth->field_encode(group, &group->a, tmp_a, ctx))
+			goto err;
+	} else if (!BN_copy(&group->a, tmp_a))
+		goto err;
+
+	/* group->b */
+	if (!BN_nnmod(&group->b, b, p, ctx))
+		goto err;
+	if (group->meth->field_encode)
+		if (!group->meth->field_encode(group, &group->b, &group->b, ctx))
+			goto err;
+
+	/* group->a_is_minus3 */
+	if (!BN_add_word(tmp_a, 3))
+		goto err;
+	group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field));
+
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+
+
+int 
+ec_GFp_simple_group_get_curve(const EC_GROUP * group, BIGNUM * p, BIGNUM * a, BIGNUM * b, BN_CTX * ctx)
+{
+	int ret = 0;
+	BN_CTX *new_ctx = NULL;
+
+	if (p != NULL) {
+		if (!BN_copy(p, &group->field))
+			return 0;
+	}
+	if (a != NULL || b != NULL) {
+		if (group->meth->field_decode) {
+			if (ctx == NULL) {
+				ctx = new_ctx = BN_CTX_new();
+				if (ctx == NULL)
+					return 0;
+			}
+			if (a != NULL) {
+				if (!group->meth->field_decode(group, a, &group->a, ctx))
+					goto err;
+			}
+			if (b != NULL) {
+				if (!group->meth->field_decode(group, b, &group->b, ctx))
+					goto err;
+			}
+		} else {
+			if (a != NULL) {
+				if (!BN_copy(a, &group->a))
+					goto err;
+			}
+			if (b != NULL) {
+				if (!BN_copy(b, &group->b))
+					goto err;
+			}
+		}
+	}
+	ret = 1;
+
+err:
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+
+
+int 
+ec_GFp_simple_group_get_degree(const EC_GROUP * group)
+{
+	return BN_num_bits(&group->field);
+}
+
+
+int 
+ec_GFp_simple_group_check_discriminant(const EC_GROUP * group, BN_CTX * ctx)
+{
+	int ret = 0;
+	BIGNUM *a, *b, *order, *tmp_1, *tmp_2;
+	const BIGNUM *p = &group->field;
+	BN_CTX *new_ctx = NULL;
+
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL) {
+			ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+	}
+	BN_CTX_start(ctx);
+	if ((a = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((b = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((tmp_1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((tmp_2 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((order = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (group->meth->field_decode) {
+		if (!group->meth->field_decode(group, a, &group->a, ctx))
+			goto err;
+		if (!group->meth->field_decode(group, b, &group->b, ctx))
+			goto err;
+	} else {
+		if (!BN_copy(a, &group->a))
+			goto err;
+		if (!BN_copy(b, &group->b))
+			goto err;
+	}
+
+	/*
+	 * check the discriminant: y^2 = x^3 + a*x + b is an elliptic curve
+	 * <=> 4*a^3 + 27*b^2 != 0 (mod p) 0 =< a, b < p
+	 */
+	if (BN_is_zero(a)) {
+		if (BN_is_zero(b))
+			goto err;
+	} else if (!BN_is_zero(b)) {
+		if (!BN_mod_sqr(tmp_1, a, p, ctx))
+			goto err;
+		if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx))
+			goto err;
+		if (!BN_lshift(tmp_1, tmp_2, 2))
+			goto err;
+		/* tmp_1 = 4*a^3 */
+
+		if (!BN_mod_sqr(tmp_2, b, p, ctx))
+			goto err;
+		if (!BN_mul_word(tmp_2, 27))
+			goto err;
+		/* tmp_2 = 27*b^2 */
+
+		if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx))
+			goto err;
+		if (BN_is_zero(a))
+			goto err;
+	}
+	ret = 1;
+
+err:
+	if (ctx != NULL)
+		BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+
+
+int 
+ec_GFp_simple_point_init(EC_POINT * point)
+{
+	BN_init(&point->X);
+	BN_init(&point->Y);
+	BN_init(&point->Z);
+	point->Z_is_one = 0;
+
+	return 1;
+}
+
+
+void 
+ec_GFp_simple_point_finish(EC_POINT * point)
+{
+	BN_free(&point->X);
+	BN_free(&point->Y);
+	BN_free(&point->Z);
+}
+
+
+void 
+ec_GFp_simple_point_clear_finish(EC_POINT * point)
+{
+	BN_clear_free(&point->X);
+	BN_clear_free(&point->Y);
+	BN_clear_free(&point->Z);
+	point->Z_is_one = 0;
+}
+
+
+int 
+ec_GFp_simple_point_copy(EC_POINT * dest, const EC_POINT * src)
+{
+	if (!BN_copy(&dest->X, &src->X))
+		return 0;
+	if (!BN_copy(&dest->Y, &src->Y))
+		return 0;
+	if (!BN_copy(&dest->Z, &src->Z))
+		return 0;
+	dest->Z_is_one = src->Z_is_one;
+
+	return 1;
+}
+
+
+int 
+ec_GFp_simple_point_set_to_infinity(const EC_GROUP * group, EC_POINT * point)
+{
+	point->Z_is_one = 0;
+	BN_zero(&point->Z);
+	return 1;
+}
+
+
+int 
+ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP * group, EC_POINT * point,
+    const BIGNUM * x, const BIGNUM * y, const BIGNUM * z, BN_CTX * ctx)
+{
+	BN_CTX *new_ctx = NULL;
+	int ret = 0;
+
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+	}
+	if (x != NULL) {
+		if (!BN_nnmod(&point->X, x, &group->field, ctx))
+			goto err;
+		if (group->meth->field_encode) {
+			if (!group->meth->field_encode(group, &point->X, &point->X, ctx))
+				goto err;
+		}
+	}
+	if (y != NULL) {
+		if (!BN_nnmod(&point->Y, y, &group->field, ctx))
+			goto err;
+		if (group->meth->field_encode) {
+			if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx))
+				goto err;
+		}
+	}
+	if (z != NULL) {
+		int Z_is_one;
+
+		if (!BN_nnmod(&point->Z, z, &group->field, ctx))
+			goto err;
+		Z_is_one = BN_is_one(&point->Z);
+		if (group->meth->field_encode) {
+			if (Z_is_one && (group->meth->field_set_to_one != 0)) {
+				if (!group->meth->field_set_to_one(group, &point->Z, ctx))
+					goto err;
+			} else {
+				if (!group->meth->field_encode(group, &point->Z, &point->Z, ctx))
+					goto err;
+			}
+		}
+		point->Z_is_one = Z_is_one;
+	}
+	ret = 1;
+
+err:
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+
+
+int 
+ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP * group, const EC_POINT * point,
+    BIGNUM * x, BIGNUM * y, BIGNUM * z, BN_CTX * ctx)
+{
+	BN_CTX *new_ctx = NULL;
+	int ret = 0;
+
+	if (group->meth->field_decode != 0) {
+		if (ctx == NULL) {
+			ctx = new_ctx = BN_CTX_new();
+			if (ctx == NULL)
+				return 0;
+		}
+		if (x != NULL) {
+			if (!group->meth->field_decode(group, x, &point->X, ctx))
+				goto err;
+		}
+		if (y != NULL) {
+			if (!group->meth->field_decode(group, y, &point->Y, ctx))
+				goto err;
+		}
+		if (z != NULL) {
+			if (!group->meth->field_decode(group, z, &point->Z, ctx))
+				goto err;
+		}
+	} else {
+		if (x != NULL) {
+			if (!BN_copy(x, &point->X))
+				goto err;
+		}
+		if (y != NULL) {
+			if (!BN_copy(y, &point->Y))
+				goto err;
+		}
+		if (z != NULL) {
+			if (!BN_copy(z, &point->Z))
+				goto err;
+		}
+	}
+
+	ret = 1;
+
+err:
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+
+
+int 
+ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP * group, EC_POINT * point,
+    const BIGNUM * x, const BIGNUM * y, BN_CTX * ctx)
+{
+	if (x == NULL || y == NULL) {
+		/* unlike for projective coordinates, we do not tolerate this */
+		ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y, BN_value_one(), ctx);
+}
+
+
+int 
+ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP * group, const EC_POINT * point,
+    BIGNUM * x, BIGNUM * y, BN_CTX * ctx)
+{
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *Z, *Z_1, *Z_2, *Z_3;
+	const BIGNUM *Z_;
+	int ret = 0;
+
+	if (EC_POINT_is_at_infinity(group, point) > 0) {
+		ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY);
+		return 0;
+	}
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+	}
+	BN_CTX_start(ctx);
+	if ((Z = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((Z_1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((Z_2 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((Z_3 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	/* transform  (X, Y, Z)  into  (x, y) := (X/Z^2, Y/Z^3) */
+
+	if (group->meth->field_decode) {
+		if (!group->meth->field_decode(group, Z, &point->Z, ctx))
+			goto err;
+		Z_ = Z;
+	} else {
+		Z_ = &point->Z;
+	}
+
+	if (BN_is_one(Z_)) {
+		if (group->meth->field_decode) {
+			if (x != NULL) {
+				if (!group->meth->field_decode(group, x, &point->X, ctx))
+					goto err;
+			}
+			if (y != NULL) {
+				if (!group->meth->field_decode(group, y, &point->Y, ctx))
+					goto err;
+			}
+		} else {
+			if (x != NULL) {
+				if (!BN_copy(x, &point->X))
+					goto err;
+			}
+			if (y != NULL) {
+				if (!BN_copy(y, &point->Y))
+					goto err;
+			}
+		}
+	} else {
+		if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx)) {
+			ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_BN_LIB);
+			goto err;
+		}
+		if (group->meth->field_encode == 0) {
+			/* field_sqr works on standard representation */
+			if (!group->meth->field_sqr(group, Z_2, Z_1, ctx))
+				goto err;
+		} else {
+			if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx))
+				goto err;
+		}
+
+		if (x != NULL) {
+			/*
+			 * in the Montgomery case, field_mul will cancel out
+			 * Montgomery factor in X:
+			 */
+			if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx))
+				goto err;
+		}
+		if (y != NULL) {
+			if (group->meth->field_encode == 0) {
+				/* field_mul works on standard representation */
+				if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx))
+					goto err;
+			} else {
+				if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx))
+					goto err;
+			}
+
+			/*
+			 * in the Montgomery case, field_mul will cancel out
+			 * Montgomery factor in Y:
+			 */
+			if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx))
+				goto err;
+		}
+	}
+
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+
+int 
+ec_GFp_simple_add(const EC_GROUP * group, EC_POINT * r, const EC_POINT * a, const EC_POINT * b, BN_CTX * ctx)
+{
+	int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
+	int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+	const BIGNUM *p;
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
+	int ret = 0;
+
+	if (a == b)
+		return EC_POINT_dbl(group, r, a, ctx);
+	if (EC_POINT_is_at_infinity(group, a) > 0)
+		return EC_POINT_copy(r, b);
+	if (EC_POINT_is_at_infinity(group, b) > 0)
+		return EC_POINT_copy(r, a);
+
+	field_mul = group->meth->field_mul;
+	field_sqr = group->meth->field_sqr;
+	p = &group->field;
+
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+	}
+	BN_CTX_start(ctx);
+	if ((n0 = BN_CTX_get(ctx)) == NULL)
+		goto end;
+	if ((n1 = BN_CTX_get(ctx)) == NULL)
+		goto end;
+	if ((n2 = BN_CTX_get(ctx)) == NULL)
+		goto end;
+	if ((n3 = BN_CTX_get(ctx)) == NULL)
+		goto end;
+	if ((n4 = BN_CTX_get(ctx)) == NULL)
+		goto end;
+	if ((n5 = BN_CTX_get(ctx)) == NULL)
+		goto end;
+	if ((n6 = BN_CTX_get(ctx)) == NULL)
+		goto end;
+
+	/*
+	 * Note that in this function we must not read components of 'a' or
+	 * 'b' once we have written the corresponding components of 'r'. ('r'
+	 * might be one of 'a' or 'b'.)
+	 */
+
+	/* n1, n2 */
+	if (b->Z_is_one) {
+		if (!BN_copy(n1, &a->X))
+			goto end;
+		if (!BN_copy(n2, &a->Y))
+			goto end;
+		/* n1 = X_a */
+		/* n2 = Y_a */
+	} else {
+		if (!field_sqr(group, n0, &b->Z, ctx))
+			goto end;
+		if (!field_mul(group, n1, &a->X, n0, ctx))
+			goto end;
+		/* n1 = X_a * Z_b^2 */
+
+		if (!field_mul(group, n0, n0, &b->Z, ctx))
+			goto end;
+		if (!field_mul(group, n2, &a->Y, n0, ctx))
+			goto end;
+		/* n2 = Y_a * Z_b^3 */
+	}
+
+	/* n3, n4 */
+	if (a->Z_is_one) {
+		if (!BN_copy(n3, &b->X))
+			goto end;
+		if (!BN_copy(n4, &b->Y))
+			goto end;
+		/* n3 = X_b */
+		/* n4 = Y_b */
+	} else {
+		if (!field_sqr(group, n0, &a->Z, ctx))
+			goto end;
+		if (!field_mul(group, n3, &b->X, n0, ctx))
+			goto end;
+		/* n3 = X_b * Z_a^2 */
+
+		if (!field_mul(group, n0, n0, &a->Z, ctx))
+			goto end;
+		if (!field_mul(group, n4, &b->Y, n0, ctx))
+			goto end;
+		/* n4 = Y_b * Z_a^3 */
+	}
+
+	/* n5, n6 */
+	if (!BN_mod_sub_quick(n5, n1, n3, p))
+		goto end;
+	if (!BN_mod_sub_quick(n6, n2, n4, p))
+		goto end;
+	/* n5 = n1 - n3 */
+	/* n6 = n2 - n4 */
+
+	if (BN_is_zero(n5)) {
+		if (BN_is_zero(n6)) {
+			/* a is the same point as b */
+			BN_CTX_end(ctx);
+			ret = EC_POINT_dbl(group, r, a, ctx);
+			ctx = NULL;
+			goto end;
+		} else {
+			/* a is the inverse of b */
+			BN_zero(&r->Z);
+			r->Z_is_one = 0;
+			ret = 1;
+			goto end;
+		}
+	}
+	/* 'n7', 'n8' */
+	if (!BN_mod_add_quick(n1, n1, n3, p))
+		goto end;
+	if (!BN_mod_add_quick(n2, n2, n4, p))
+		goto end;
+	/* 'n7' = n1 + n3 */
+	/* 'n8' = n2 + n4 */
+
+	/* Z_r */
+	if (a->Z_is_one && b->Z_is_one) {
+		if (!BN_copy(&r->Z, n5))
+			goto end;
+	} else {
+		if (a->Z_is_one) {
+			if (!BN_copy(n0, &b->Z))
+				goto end;
+		} else if (b->Z_is_one) {
+			if (!BN_copy(n0, &a->Z))
+				goto end;
+		} else {
+			if (!field_mul(group, n0, &a->Z, &b->Z, ctx))
+				goto end;
+		}
+		if (!field_mul(group, &r->Z, n0, n5, ctx))
+			goto end;
+	}
+	r->Z_is_one = 0;
+	/* Z_r = Z_a * Z_b * n5 */
+
+	/* X_r */
+	if (!field_sqr(group, n0, n6, ctx))
+		goto end;
+	if (!field_sqr(group, n4, n5, ctx))
+		goto end;
+	if (!field_mul(group, n3, n1, n4, ctx))
+		goto end;
+	if (!BN_mod_sub_quick(&r->X, n0, n3, p))
+		goto end;
+	/* X_r = n6^2 - n5^2 * 'n7' */
+
+	/* 'n9' */
+	if (!BN_mod_lshift1_quick(n0, &r->X, p))
+		goto end;
+	if (!BN_mod_sub_quick(n0, n3, n0, p))
+		goto end;
+	/* n9 = n5^2 * 'n7' - 2 * X_r */
+
+	/* Y_r */
+	if (!field_mul(group, n0, n0, n6, ctx))
+		goto end;
+	if (!field_mul(group, n5, n4, n5, ctx))
+		goto end;	/* now n5 is n5^3 */
+	if (!field_mul(group, n1, n2, n5, ctx))
+		goto end;
+	if (!BN_mod_sub_quick(n0, n0, n1, p))
+		goto end;
+	if (BN_is_odd(n0))
+		if (!BN_add(n0, n0, p))
+			goto end;
+	/* now  0 <= n0 < 2*p,  and n0 is even */
+	if (!BN_rshift1(&r->Y, n0))
+		goto end;
+	/* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
+
+	ret = 1;
+
+end:
+	if (ctx)		/* otherwise we already called BN_CTX_end */
+		BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+
+
+int 
+ec_GFp_simple_dbl(const EC_GROUP * group, EC_POINT * r, const EC_POINT * a, BN_CTX * ctx)
+{
+	int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
+	int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+	const BIGNUM *p;
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *n0, *n1, *n2, *n3;
+	int ret = 0;
+
+	if (EC_POINT_is_at_infinity(group, a) > 0) {
+		BN_zero(&r->Z);
+		r->Z_is_one = 0;
+		return 1;
+	}
+	field_mul = group->meth->field_mul;
+	field_sqr = group->meth->field_sqr;
+	p = &group->field;
+
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+	}
+	BN_CTX_start(ctx);
+	if ((n0 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((n1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((n2 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((n3 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	/*
+	 * Note that in this function we must not read components of 'a' once
+	 * we have written the corresponding components of 'r'. ('r' might
+	 * the same as 'a'.)
+	 */
+
+	/* n1 */
+	if (a->Z_is_one) {
+		if (!field_sqr(group, n0, &a->X, ctx))
+			goto err;
+		if (!BN_mod_lshift1_quick(n1, n0, p))
+			goto err;
+		if (!BN_mod_add_quick(n0, n0, n1, p))
+			goto err;
+		if (!BN_mod_add_quick(n1, n0, &group->a, p))
+			goto err;
+		/* n1 = 3 * X_a^2 + a_curve */
+	} else if (group->a_is_minus3) {
+		if (!field_sqr(group, n1, &a->Z, ctx))
+			goto err;
+		if (!BN_mod_add_quick(n0, &a->X, n1, p))
+			goto err;
+		if (!BN_mod_sub_quick(n2, &a->X, n1, p))
+			goto err;
+		if (!field_mul(group, n1, n0, n2, ctx))
+			goto err;
+		if (!BN_mod_lshift1_quick(n0, n1, p))
+			goto err;
+		if (!BN_mod_add_quick(n1, n0, n1, p))
+			goto err;
+		/*
+		 * n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2) = 3 * X_a^2 - 3 *
+		 * Z_a^4
+		 */
+	} else {
+		if (!field_sqr(group, n0, &a->X, ctx))
+			goto err;
+		if (!BN_mod_lshift1_quick(n1, n0, p))
+			goto err;
+		if (!BN_mod_add_quick(n0, n0, n1, p))
+			goto err;
+		if (!field_sqr(group, n1, &a->Z, ctx))
+			goto err;
+		if (!field_sqr(group, n1, n1, ctx))
+			goto err;
+		if (!field_mul(group, n1, n1, &group->a, ctx))
+			goto err;
+		if (!BN_mod_add_quick(n1, n1, n0, p))
+			goto err;
+		/* n1 = 3 * X_a^2 + a_curve * Z_a^4 */
+	}
+
+	/* Z_r */
+	if (a->Z_is_one) {
+		if (!BN_copy(n0, &a->Y))
+			goto err;
+	} else {
+		if (!field_mul(group, n0, &a->Y, &a->Z, ctx))
+			goto err;
+	}
+	if (!BN_mod_lshift1_quick(&r->Z, n0, p))
+		goto err;
+	r->Z_is_one = 0;
+	/* Z_r = 2 * Y_a * Z_a */
+
+	/* n2 */
+	if (!field_sqr(group, n3, &a->Y, ctx))
+		goto err;
+	if (!field_mul(group, n2, &a->X, n3, ctx))
+		goto err;
+	if (!BN_mod_lshift_quick(n2, n2, 2, p))
+		goto err;
+	/* n2 = 4 * X_a * Y_a^2 */
+
+	/* X_r */
+	if (!BN_mod_lshift1_quick(n0, n2, p))
+		goto err;
+	if (!field_sqr(group, &r->X, n1, ctx))
+		goto err;
+	if (!BN_mod_sub_quick(&r->X, &r->X, n0, p))
+		goto err;
+	/* X_r = n1^2 - 2 * n2 */
+
+	/* n3 */
+	if (!field_sqr(group, n0, n3, ctx))
+		goto err;
+	if (!BN_mod_lshift_quick(n3, n0, 3, p))
+		goto err;
+	/* n3 = 8 * Y_a^4 */
+
+	/* Y_r */
+	if (!BN_mod_sub_quick(n0, n2, &r->X, p))
+		goto err;
+	if (!field_mul(group, n0, n1, n0, ctx))
+		goto err;
+	if (!BN_mod_sub_quick(&r->Y, n0, n3, p))
+		goto err;
+	/* Y_r = n1 * (n2 - X_r) - n3 */
+
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+
+
+int 
+ec_GFp_simple_invert(const EC_GROUP * group, EC_POINT * point, BN_CTX * ctx)
+{
+	if (EC_POINT_is_at_infinity(group, point) > 0 || BN_is_zero(&point->Y))
+		/* point is its own inverse */
+		return 1;
+
+	return BN_usub(&point->Y, &group->field, &point->Y);
+}
+
+
+int 
+ec_GFp_simple_is_at_infinity(const EC_GROUP * group, const EC_POINT * point)
+{
+	return BN_is_zero(&point->Z);
+}
+
+
+int 
+ec_GFp_simple_is_on_curve(const EC_GROUP * group, const EC_POINT * point, BN_CTX * ctx)
+{
+	int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
+	int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+	const BIGNUM *p;
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *rh, *tmp, *Z4, *Z6;
+	int ret = -1;
+
+	if (EC_POINT_is_at_infinity(group, point) > 0)
+		return 1;
+
+	field_mul = group->meth->field_mul;
+	field_sqr = group->meth->field_sqr;
+	p = &group->field;
+
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return -1;
+	}
+	BN_CTX_start(ctx);
+	if ((rh = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((tmp = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((Z4 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((Z6 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	/*
+	 * We have a curve defined by a Weierstrass equation y^2 = x^3 + a*x
+	 * + b. The point to consider is given in Jacobian projective
+	 * coordinates where  (X, Y, Z)  represents  (x, y) = (X/Z^2, Y/Z^3).
+	 * Substituting this and multiplying by  Z^6  transforms the above
+	 * equation into Y^2 = X^3 + a*X*Z^4 + b*Z^6. To test this, we add up
+	 * the right-hand side in 'rh'.
+	 */
+
+	/* rh := X^2 */
+	if (!field_sqr(group, rh, &point->X, ctx))
+		goto err;
+
+	if (!point->Z_is_one) {
+		if (!field_sqr(group, tmp, &point->Z, ctx))
+			goto err;
+		if (!field_sqr(group, Z4, tmp, ctx))
+			goto err;
+		if (!field_mul(group, Z6, Z4, tmp, ctx))
+			goto err;
+
+		/* rh := (rh + a*Z^4)*X */
+		if (group->a_is_minus3) {
+			if (!BN_mod_lshift1_quick(tmp, Z4, p))
+				goto err;
+			if (!BN_mod_add_quick(tmp, tmp, Z4, p))
+				goto err;
+			if (!BN_mod_sub_quick(rh, rh, tmp, p))
+				goto err;
+			if (!field_mul(group, rh, rh, &point->X, ctx))
+				goto err;
+		} else {
+			if (!field_mul(group, tmp, Z4, &group->a, ctx))
+				goto err;
+			if (!BN_mod_add_quick(rh, rh, tmp, p))
+				goto err;
+			if (!field_mul(group, rh, rh, &point->X, ctx))
+				goto err;
+		}
+
+		/* rh := rh + b*Z^6 */
+		if (!field_mul(group, tmp, &group->b, Z6, ctx))
+			goto err;
+		if (!BN_mod_add_quick(rh, rh, tmp, p))
+			goto err;
+	} else {
+		/* point->Z_is_one */
+
+		/* rh := (rh + a)*X */
+		if (!BN_mod_add_quick(rh, rh, &group->a, p))
+			goto err;
+		if (!field_mul(group, rh, rh, &point->X, ctx))
+			goto err;
+		/* rh := rh + b */
+		if (!BN_mod_add_quick(rh, rh, &group->b, p))
+			goto err;
+	}
+
+	/* 'lh' := Y^2 */
+	if (!field_sqr(group, tmp, &point->Y, ctx))
+		goto err;
+
+	ret = (0 == BN_ucmp(tmp, rh));
+
+err:
+	BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+
+
+int 
+ec_GFp_simple_cmp(const EC_GROUP * group, const EC_POINT * a, const EC_POINT * b, BN_CTX * ctx)
+{
+	/*
+	 * return values: -1   error 0   equal (in affine coordinates) 1
+	 * not equal
+	 */
+
+	int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
+	int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
+	const BIGNUM *tmp1_, *tmp2_;
+	int ret = -1;
+
+	if (EC_POINT_is_at_infinity(group, a) > 0) {
+		return EC_POINT_is_at_infinity(group, b) > 0 ? 0 : 1;
+	}
+	if (EC_POINT_is_at_infinity(group, b) > 0)
+		return 1;
+
+	if (a->Z_is_one && b->Z_is_one) {
+		return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
+	}
+	field_mul = group->meth->field_mul;
+	field_sqr = group->meth->field_sqr;
+
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return -1;
+	}
+	BN_CTX_start(ctx);
+	if ((tmp1 = BN_CTX_get(ctx)) == NULL)
+		goto end;
+	if ((tmp2 = BN_CTX_get(ctx)) == NULL)
+		goto end;
+	if ((Za23 = BN_CTX_get(ctx)) == NULL)
+		goto end;
+	if ((Zb23 = BN_CTX_get(ctx)) == NULL)
+		goto end;
+
+	/*
+	 * We have to decide whether (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2,
+	 * Y_b/Z_b^3), or equivalently, whether (X_a*Z_b^2, Y_a*Z_b^3) =
+	 * (X_b*Z_a^2, Y_b*Z_a^3).
+	 */
+
+	if (!b->Z_is_one) {
+		if (!field_sqr(group, Zb23, &b->Z, ctx))
+			goto end;
+		if (!field_mul(group, tmp1, &a->X, Zb23, ctx))
+			goto end;
+		tmp1_ = tmp1;
+	} else
+		tmp1_ = &a->X;
+	if (!a->Z_is_one) {
+		if (!field_sqr(group, Za23, &a->Z, ctx))
+			goto end;
+		if (!field_mul(group, tmp2, &b->X, Za23, ctx))
+			goto end;
+		tmp2_ = tmp2;
+	} else
+		tmp2_ = &b->X;
+
+	/* compare  X_a*Z_b^2  with  X_b*Z_a^2 */
+	if (BN_cmp(tmp1_, tmp2_) != 0) {
+		ret = 1;	/* points differ */
+		goto end;
+	}
+	if (!b->Z_is_one) {
+		if (!field_mul(group, Zb23, Zb23, &b->Z, ctx))
+			goto end;
+		if (!field_mul(group, tmp1, &a->Y, Zb23, ctx))
+			goto end;
+		/* tmp1_ = tmp1 */
+	} else
+		tmp1_ = &a->Y;
+	if (!a->Z_is_one) {
+		if (!field_mul(group, Za23, Za23, &a->Z, ctx))
+			goto end;
+		if (!field_mul(group, tmp2, &b->Y, Za23, ctx))
+			goto end;
+		/* tmp2_ = tmp2 */
+	} else
+		tmp2_ = &b->Y;
+
+	/* compare  Y_a*Z_b^3  with  Y_b*Z_a^3 */
+	if (BN_cmp(tmp1_, tmp2_) != 0) {
+		ret = 1;	/* points differ */
+		goto end;
+	}
+	/* points are equal */
+	ret = 0;
+
+end:
+	BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+
+
+int 
+ec_GFp_simple_make_affine(const EC_GROUP * group, EC_POINT * point, BN_CTX * ctx)
+{
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *x, *y;
+	int ret = 0;
+
+	if (point->Z_is_one || EC_POINT_is_at_infinity(group, point) > 0)
+		return 1;
+
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+	}
+	BN_CTX_start(ctx);
+	if ((x = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((y = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx))
+		goto err;
+	if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
+		goto err;
+	if (!point->Z_is_one) {
+		ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR);
+		goto err;
+	}
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	return ret;
+}
+
+
+int 
+ec_GFp_simple_points_make_affine(const EC_GROUP * group, size_t num, EC_POINT * points[], BN_CTX * ctx)
+{
+	BN_CTX *new_ctx = NULL;
+	BIGNUM *tmp0, *tmp1;
+	size_t pow2 = 0;
+	BIGNUM **heap = NULL;
+	size_t i;
+	int ret = 0;
+
+	if (num == 0)
+		return 1;
+
+	if (ctx == NULL) {
+		ctx = new_ctx = BN_CTX_new();
+		if (ctx == NULL)
+			return 0;
+	}
+	BN_CTX_start(ctx);
+	if ((tmp0 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((tmp1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	/*
+	 * Before converting the individual points, compute inverses of all Z
+	 * values. Modular inversion is rather slow, but luckily we can do
+	 * with a single explicit inversion, plus about 3 multiplications per
+	 * input value.
+	 */
+
+	pow2 = 1;
+	while (num > pow2)
+		pow2 <<= 1;
+	/*
+	 * Now pow2 is the smallest power of 2 satifsying pow2 >= num. We
+	 * need twice that.
+	 */
+	pow2 <<= 1;
+
+	heap = reallocarray(NULL, pow2, sizeof heap[0]);
+	if (heap == NULL)
+		goto err;
+
+	/*
+	 * The array is used as a binary tree, exactly as in heapsort:
+	 * 
+	 * heap[1] heap[2]                     heap[3] heap[4]       heap[5]
+	 * heap[6]       heap[7] heap[8]heap[9] heap[10]heap[11]
+	 * heap[12]heap[13] heap[14] heap[15]
+	 * 
+	 * We put the Z's in the last line; then we set each other node to the
+	 * product of its two child-nodes (where empty or 0 entries are
+	 * treated as ones); then we invert heap[1]; then we invert each
+	 * other node by replacing it by the product of its parent (after
+	 * inversion) and its sibling (before inversion).
+	 */
+	heap[0] = NULL;
+	for (i = pow2 / 2 - 1; i > 0; i--)
+		heap[i] = NULL;
+	for (i = 0; i < num; i++)
+		heap[pow2 / 2 + i] = &points[i]->Z;
+	for (i = pow2 / 2 + num; i < pow2; i++)
+		heap[i] = NULL;
+
+	/* set each node to the product of its children */
+	for (i = pow2 / 2 - 1; i > 0; i--) {
+		heap[i] = BN_new();
+		if (heap[i] == NULL)
+			goto err;
+
+		if (heap[2 * i] != NULL) {
+			if ((heap[2 * i + 1] == NULL) || BN_is_zero(heap[2 * i + 1])) {
+				if (!BN_copy(heap[i], heap[2 * i]))
+					goto err;
+			} else {
+				if (BN_is_zero(heap[2 * i])) {
+					if (!BN_copy(heap[i], heap[2 * i + 1]))
+						goto err;
+				} else {
+					if (!group->meth->field_mul(group, heap[i],
+						heap[2 * i], heap[2 * i + 1], ctx))
+						goto err;
+				}
+			}
+		}
+	}
+
+	/* invert heap[1] */
+	if (!BN_is_zero(heap[1])) {
+		if (!BN_mod_inverse(heap[1], heap[1], &group->field, ctx)) {
+			ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB);
+			goto err;
+		}
+	}
+	if (group->meth->field_encode != 0) {
+		/*
+		 * in the Montgomery case, we just turned  R*H  (representing
+		 * H) into  1/(R*H),  but we need  R*(1/H)  (representing
+		 * 1/H); i.e. we have need to multiply by the Montgomery
+		 * factor twice
+		 */
+		if (!group->meth->field_encode(group, heap[1], heap[1], ctx))
+			goto err;
+		if (!group->meth->field_encode(group, heap[1], heap[1], ctx))
+			goto err;
+	}
+	/* set other heap[i]'s to their inverses */
+	for (i = 2; i < pow2 / 2 + num; i += 2) {
+		/* i is even */
+		if ((heap[i + 1] != NULL) && !BN_is_zero(heap[i + 1])) {
+			if (!group->meth->field_mul(group, tmp0, heap[i / 2], heap[i + 1], ctx))
+				goto err;
+			if (!group->meth->field_mul(group, tmp1, heap[i / 2], heap[i], ctx))
+				goto err;
+			if (!BN_copy(heap[i], tmp0))
+				goto err;
+			if (!BN_copy(heap[i + 1], tmp1))
+				goto err;
+		} else {
+			if (!BN_copy(heap[i], heap[i / 2]))
+				goto err;
+		}
+	}
+
+	/*
+	 * we have replaced all non-zero Z's by their inverses, now fix up
+	 * all the points
+	 */
+	for (i = 0; i < num; i++) {
+		EC_POINT *p = points[i];
+
+		if (!BN_is_zero(&p->Z)) {
+			/* turn  (X, Y, 1/Z)  into  (X/Z^2, Y/Z^3, 1) */
+
+			if (!group->meth->field_sqr(group, tmp1, &p->Z, ctx))
+				goto err;
+			if (!group->meth->field_mul(group, &p->X, &p->X, tmp1, ctx))
+				goto err;
+
+			if (!group->meth->field_mul(group, tmp1, tmp1, &p->Z, ctx))
+				goto err;
+			if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp1, ctx))
+				goto err;
+
+			if (group->meth->field_set_to_one != 0) {
+				if (!group->meth->field_set_to_one(group, &p->Z, ctx))
+					goto err;
+			} else {
+				if (!BN_one(&p->Z))
+					goto err;
+			}
+			p->Z_is_one = 1;
+		}
+	}
+
+	ret = 1;
+
+err:
+	BN_CTX_end(ctx);
+	BN_CTX_free(new_ctx);
+	if (heap != NULL) {
+		/*
+		 * heap[pow2/2] .. heap[pow2-1] have not been allocated
+		 * locally!
+		 */
+		for (i = pow2 / 2 - 1; i > 0; i--) {
+			BN_clear_free(heap[i]);
+		}
+		free(heap);
+	}
+	return ret;
+}
+
+
+int 
+ec_GFp_simple_field_mul(const EC_GROUP * group, BIGNUM * r, const BIGNUM * a, const BIGNUM * b, BN_CTX * ctx)
+{
+	return BN_mod_mul(r, a, b, &group->field, ctx);
+}
+
+
+int 
+ec_GFp_simple_field_sqr(const EC_GROUP * group, BIGNUM * r, const BIGNUM * a, BN_CTX * ctx)
+{
+	return BN_mod_sqr(r, a, &group->field, ctx);
+}
diff --git a/crypto/libressl/crypto/ecdh/ech_err.c b/crypto/libressl/crypto/ecdh/ech_err.c
new file mode 100644
index 0000000000..41475f1b1b
--- /dev/null
+++ b/crypto/libressl/crypto/ecdh/ech_err.c
@@ -0,0 +1,101 @@
+/* $OpenBSD: ech_err.c,v 1.4 2015/09/13 10:46:20 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2011 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECDH,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECDH,0,reason)
+
+static ERR_STRING_DATA ECDH_str_functs[]= {
+	{ERR_FUNC(ECDH_F_ECDH_CHECK),	"ECDH_CHECK"},
+	{ERR_FUNC(ECDH_F_ECDH_COMPUTE_KEY),	"ECDH_compute_key"},
+	{ERR_FUNC(ECDH_F_ECDH_DATA_NEW_METHOD),	"ECDH_DATA_new_method"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA ECDH_str_reasons[]= {
+	{ERR_REASON(ECDH_R_KDF_FAILED)           , "KDF failed"},
+	{ERR_REASON(ECDH_R_KEY_TRUNCATION), "key would be truncated"},
+	{ERR_REASON(ECDH_R_NON_FIPS_METHOD)      , "non fips method"},
+	{ERR_REASON(ECDH_R_NO_PRIVATE_VALUE)     , "no private value"},
+	{ERR_REASON(ECDH_R_POINT_ARITHMETIC_FAILURE), "point arithmetic failure"},
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_ECDH_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(ECDH_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, ECDH_str_functs);
+		ERR_load_strings(0, ECDH_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/ecdh/ech_key.c b/crypto/libressl/crypto/ecdh/ech_key.c
new file mode 100644
index 0000000000..74a063ee11
--- /dev/null
+++ b/crypto/libressl/crypto/ecdh/ech_key.c
@@ -0,0 +1,226 @@
+/* $OpenBSD: ech_key.c,v 1.5 2015/09/13 14:11:57 jsing Exp $ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The ECDH software is originally written by Douglas Stebila of
+ * Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include "ech_locl.h"
+
+static int ecdh_compute_key(void *out, size_t len, const EC_POINT *pub_key,
+    EC_KEY *ecdh,
+    void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen));
+
+/*
+ * This implementation is based on the following primitives in the IEEE 1363
+ * standard:
+ *  - ECKAS-DH1
+ *  - ECSVDP-DH
+ * Finally an optional KDF is applied.
+ */
+static int
+ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
+    EC_KEY *ecdh,
+    void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen))
+{
+	BN_CTX *ctx;
+	EC_POINT *tmp = NULL;
+	BIGNUM *x = NULL, *y = NULL;
+	const BIGNUM *priv_key;
+	const EC_GROUP* group;
+	int ret = -1;
+	size_t buflen, len;
+	unsigned char *buf = NULL;
+
+	if (outlen > INT_MAX) {
+		/* Sort of, anyway. */
+		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
+		return -1;
+	}
+
+	if ((ctx = BN_CTX_new()) == NULL)
+		goto err;
+	BN_CTX_start(ctx);
+	if ((x = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((y = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	priv_key = EC_KEY_get0_private_key(ecdh);
+	if (priv_key == NULL) {
+		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_NO_PRIVATE_VALUE);
+		goto err;
+	}
+
+	group = EC_KEY_get0_group(ecdh);
+	if ((tmp = EC_POINT_new(group)) == NULL) {
+		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)) {
+		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,
+		    ECDH_R_POINT_ARITHMETIC_FAILURE);
+		goto err;
+	}
+
+	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
+	    NID_X9_62_prime_field) {
+		if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y,
+		    ctx)) {
+			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,
+			    ECDH_R_POINT_ARITHMETIC_FAILURE);
+			goto err;
+		}
+	}
+#ifndef OPENSSL_NO_EC2M
+	else {
+		if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y,
+		    ctx)) {
+			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,
+			    ECDH_R_POINT_ARITHMETIC_FAILURE);
+			goto err;
+		}
+	}
+#endif
+
+	buflen = ECDH_size(ecdh);
+	len = BN_num_bytes(x);
+	if (len > buflen) {
+		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR);
+		goto err;
+	}
+	if (KDF == NULL && outlen < buflen) {
+		/* The resulting key would be truncated. */
+		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_KEY_TRUNCATION);
+		goto err;
+	}
+	if ((buf = malloc(buflen)) == NULL) {
+		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	memset(buf, 0, buflen - len);
+	if (len != (size_t)BN_bn2bin(x, buf + buflen - len)) {
+		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_BN_LIB);
+		goto err;
+	}
+
+	if (KDF != NULL) {
+		if (KDF(buf, buflen, out, &outlen) == NULL) {
+			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_KDF_FAILED);
+			goto err;
+		}
+		ret = outlen;
+	} else {
+		/* No KDF, just copy out the key and zero the rest. */
+		if (outlen > buflen) {
+			memset((void *)((uintptr_t)out + buflen), 0, outlen - buflen);
+			outlen = buflen;
+		}
+		memcpy(out, buf, outlen);
+		ret = outlen;
+	}
+
+err:
+	EC_POINT_free(tmp);
+	if (ctx)
+		BN_CTX_end(ctx);
+	BN_CTX_free(ctx);
+	free(buf);
+	return (ret);
+}
+
+static ECDH_METHOD openssl_ecdh_meth = {
+	.name = "OpenSSL ECDH method",
+	.compute_key = ecdh_compute_key
+};
+
+const ECDH_METHOD *
+ECDH_OpenSSL(void)
+{
+	return &openssl_ecdh_meth;
+}
+
+int
+ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
+    EC_KEY *eckey,
+    void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen))
+{
+	ECDH_DATA *ecdh = ecdh_check(eckey);
+	if (ecdh == NULL)
+		return 0;
+	return ecdh->meth->compute_key(out, outlen, pub_key, eckey, KDF);
+}
diff --git a/crypto/libressl/crypto/ecdh/ech_lib.c b/crypto/libressl/crypto/ecdh/ech_lib.c
new file mode 100644
index 0000000000..7042bcbf1b
--- /dev/null
+++ b/crypto/libressl/crypto/ecdh/ech_lib.c
@@ -0,0 +1,247 @@
+/* $OpenBSD: ech_lib.c,v 1.10 2015/09/13 10:46:20 jsing Exp $ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The ECDH software is originally written by Douglas Stebila of
+ * Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include "ech_locl.h"
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+#include 
+
+static const ECDH_METHOD *default_ECDH_method = NULL;
+
+static void *ecdh_data_new(void);
+static void *ecdh_data_dup(void *);
+static void  ecdh_data_free(void *);
+
+void
+ECDH_set_default_method(const ECDH_METHOD *meth)
+{
+	default_ECDH_method = meth;
+}
+
+const ECDH_METHOD *
+ECDH_get_default_method(void)
+{
+	if (!default_ECDH_method) {
+		default_ECDH_method = ECDH_OpenSSL();
+	}
+	return default_ECDH_method;
+}
+
+int
+ECDH_set_method(EC_KEY *eckey, const ECDH_METHOD *meth)
+{
+	ECDH_DATA *ecdh;
+
+	ecdh = ecdh_check(eckey);
+
+	if (ecdh == NULL)
+		return 0;
+
+#ifndef OPENSSL_NO_ENGINE
+	if (ecdh->engine) {
+		ENGINE_finish(ecdh->engine);
+		ecdh->engine = NULL;
+	}
+#endif
+	ecdh->meth = meth;
+	return 1;
+}
+
+static ECDH_DATA *
+ECDH_DATA_new_method(ENGINE *engine)
+{
+	ECDH_DATA *ret;
+
+	ret = malloc(sizeof(ECDH_DATA));
+	if (ret == NULL) {
+		ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+		return (NULL);
+	}
+
+	ret->init = NULL;
+
+	ret->meth = ECDH_get_default_method();
+	ret->engine = engine;
+#ifndef OPENSSL_NO_ENGINE
+	if (!ret->engine)
+		ret->engine = ENGINE_get_default_ECDH();
+	if (ret->engine) {
+		ret->meth = ENGINE_get_ECDH(ret->engine);
+		if (!ret->meth) {
+			ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_ENGINE_LIB);
+			ENGINE_finish(ret->engine);
+			free(ret);
+			return NULL;
+		}
+	}
+#endif
+
+	ret->flags = ret->meth->flags;
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data);
+	return (ret);
+}
+
+static void *
+ecdh_data_new(void)
+{
+	return (void *)ECDH_DATA_new_method(NULL);
+}
+
+static void *
+ecdh_data_dup(void *data)
+{
+	ECDH_DATA *r = (ECDH_DATA *)data;
+
+	/* XXX: dummy operation */
+	if (r == NULL)
+		return NULL;
+
+	return (void *)ecdh_data_new();
+}
+
+void
+ecdh_data_free(void *data)
+{
+	ECDH_DATA *r = (ECDH_DATA *)data;
+
+#ifndef OPENSSL_NO_ENGINE
+	if (r->engine)
+		ENGINE_finish(r->engine);
+#endif
+
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, r, &r->ex_data);
+
+	explicit_bzero((void *)r, sizeof(ECDH_DATA));
+
+	free(r);
+}
+
+ECDH_DATA *
+ecdh_check(EC_KEY *key)
+{
+	ECDH_DATA *ecdh_data;
+
+	void *data = EC_KEY_get_key_method_data(key, ecdh_data_dup,
+	    ecdh_data_free, ecdh_data_free);
+	if (data == NULL) {
+		ecdh_data = (ECDH_DATA *)ecdh_data_new();
+		if (ecdh_data == NULL)
+			return NULL;
+		data = EC_KEY_insert_key_method_data(key, (void *)ecdh_data,
+		    ecdh_data_dup, ecdh_data_free, ecdh_data_free);
+		if (data != NULL) {
+			/* Another thread raced us to install the key_method
+			 * data and won. */
+			ecdh_data_free(ecdh_data);
+			ecdh_data = (ECDH_DATA *)data;
+		}
+	} else
+		ecdh_data = (ECDH_DATA *)data;
+
+	return ecdh_data;
+}
+
+int
+ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+    CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+{
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDH, argl, argp,
+	    new_func, dup_func, free_func);
+}
+
+int
+ECDH_set_ex_data(EC_KEY *d, int idx, void *arg)
+{
+	ECDH_DATA *ecdh;
+	ecdh = ecdh_check(d);
+	if (ecdh == NULL)
+		return 0;
+	return (CRYPTO_set_ex_data(&ecdh->ex_data, idx, arg));
+}
+
+void *
+ECDH_get_ex_data(EC_KEY *d, int idx)
+{
+	ECDH_DATA *ecdh;
+	ecdh = ecdh_check(d);
+	if (ecdh == NULL)
+		return NULL;
+	return (CRYPTO_get_ex_data(&ecdh->ex_data, idx));
+}
+
+int
+ECDH_size(const EC_KEY *d)
+{
+	return ((EC_GROUP_get_degree(EC_KEY_get0_group(d)) + 7) / 8);
+}
diff --git a/crypto/libressl/crypto/ecdh/ech_locl.h b/crypto/libressl/crypto/ecdh/ech_locl.h
new file mode 100644
index 0000000000..5181efb5f5
--- /dev/null
+++ b/crypto/libressl/crypto/ecdh/ech_locl.h
@@ -0,0 +1,97 @@
+/* $OpenBSD: ech_locl.h,v 1.3 2015/02/07 13:19:15 doug Exp $ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_ECH_LOCL_H
+#define HEADER_ECH_LOCL_H
+
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+struct ecdh_method {
+	const char *name;
+	int (*compute_key)(void *key, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh,
+	    void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen));
+	int flags;
+	char *app_data;
+};
+
+/* If this flag is set the ECDH method is FIPS compliant and can be used
+ * in FIPS mode. This is set in the validated module method. If an
+ * application sets this flag in its own methods it is its responsibility
+ * to ensure the result is compliant.
+ */
+
+#define ECDH_FLAG_FIPS_METHOD	0x1
+
+typedef struct ecdh_data_st {
+	/* EC_KEY_METH_DATA part */
+	int (*init)(EC_KEY *);
+	/* method specific part */
+	ENGINE	*engine;
+	int	flags;
+	const ECDH_METHOD *meth;
+	CRYPTO_EX_DATA ex_data;
+} ECDH_DATA;
+
+ECDH_DATA *ecdh_check(EC_KEY *);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* HEADER_ECH_LOCL_H */
diff --git a/crypto/libressl/crypto/ecdsa/ecs_asn1.c b/crypto/libressl/crypto/ecdsa/ecs_asn1.c
new file mode 100644
index 0000000000..c6d198cb70
--- /dev/null
+++ b/crypto/libressl/crypto/ecdsa/ecs_asn1.c
@@ -0,0 +1,115 @@
+/* $OpenBSD: ecs_asn1.c,v 1.7 2015/10/16 15:12:30 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 2000-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "ecs_locl.h"
+#include 
+#include 
+
+static const ASN1_TEMPLATE ECDSA_SIG_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(ECDSA_SIG, r),
+		.field_name = "r",
+		.item = &CBIGNUM_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(ECDSA_SIG, s),
+		.field_name = "s",
+		.item = &CBIGNUM_it,
+	},
+};
+
+const ASN1_ITEM ECDSA_SIG_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = ECDSA_SIG_seq_tt,
+	.tcount = sizeof(ECDSA_SIG_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(ECDSA_SIG),
+	.sname = "ECDSA_SIG",
+};
+
+ECDSA_SIG *ECDSA_SIG_new(void);
+void ECDSA_SIG_free(ECDSA_SIG *a);
+ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **a, const unsigned char **in, long len);
+int i2d_ECDSA_SIG(const ECDSA_SIG *a, unsigned char **out);
+
+ECDSA_SIG *
+d2i_ECDSA_SIG(ECDSA_SIG **a, const unsigned char **in, long len)
+{
+	return (ECDSA_SIG *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ECDSA_SIG_it);
+}
+
+int
+i2d_ECDSA_SIG(const ECDSA_SIG *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ECDSA_SIG_it);
+}
+
+ECDSA_SIG *
+ECDSA_SIG_new(void)
+{
+	return (ECDSA_SIG *)ASN1_item_new(&ECDSA_SIG_it);
+}
+
+void
+ECDSA_SIG_free(ECDSA_SIG *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ECDSA_SIG_it);
+}
diff --git a/crypto/libressl/crypto/ecdsa/ecs_err.c b/crypto/libressl/crypto/ecdsa/ecs_err.c
new file mode 100644
index 0000000000..625cea30cd
--- /dev/null
+++ b/crypto/libressl/crypto/ecdsa/ecs_err.c
@@ -0,0 +1,106 @@
+/* $OpenBSD: ecs_err.c,v 1.3 2014/07/10 22:45:57 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2011 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECDSA,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECDSA,0,reason)
+
+static ERR_STRING_DATA ECDSA_str_functs[]= {
+	{ERR_FUNC(ECDSA_F_ECDSA_CHECK),	"ECDSA_CHECK"},
+	{ERR_FUNC(ECDSA_F_ECDSA_DATA_NEW_METHOD),	"ECDSA_DATA_NEW_METHOD"},
+	{ERR_FUNC(ECDSA_F_ECDSA_DO_SIGN),	"ECDSA_do_sign"},
+	{ERR_FUNC(ECDSA_F_ECDSA_DO_VERIFY),	"ECDSA_do_verify"},
+	{ERR_FUNC(ECDSA_F_ECDSA_SIGN_SETUP),	"ECDSA_sign_setup"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA ECDSA_str_reasons[]= {
+	{ERR_REASON(ECDSA_R_BAD_SIGNATURE)       , "bad signature"},
+	{ERR_REASON(ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE), "data too large for key size"},
+	{ERR_REASON(ECDSA_R_ERR_EC_LIB)          , "err ec lib"},
+	{ERR_REASON(ECDSA_R_MISSING_PARAMETERS)  , "missing parameters"},
+	{ERR_REASON(ECDSA_R_NEED_NEW_SETUP_VALUES), "need new setup values"},
+	{ERR_REASON(ECDSA_R_NON_FIPS_METHOD)     , "non fips method"},
+	{ERR_REASON(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED), "random number generation failed"},
+	{ERR_REASON(ECDSA_R_SIGNATURE_MALLOC_FAILED), "signature malloc failed"},
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_ECDSA_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(ECDSA_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, ECDSA_str_functs);
+		ERR_load_strings(0, ECDSA_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/ecdsa/ecs_lib.c b/crypto/libressl/crypto/ecdsa/ecs_lib.c
new file mode 100644
index 0000000000..5cc2605e6b
--- /dev/null
+++ b/crypto/libressl/crypto/ecdsa/ecs_lib.c
@@ -0,0 +1,264 @@
+/* $OpenBSD: ecs_lib.c,v 1.9 2015/02/08 13:35:07 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include "ecs_locl.h"
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+#include 
+#include 
+
+static const ECDSA_METHOD *default_ECDSA_method = NULL;
+
+static void *ecdsa_data_new(void);
+static void *ecdsa_data_dup(void *);
+static void  ecdsa_data_free(void *);
+
+void
+ECDSA_set_default_method(const ECDSA_METHOD *meth)
+{
+	default_ECDSA_method = meth;
+}
+
+const ECDSA_METHOD *
+ECDSA_get_default_method(void)
+{
+	if (!default_ECDSA_method) {
+		default_ECDSA_method = ECDSA_OpenSSL();
+	}
+	return default_ECDSA_method;
+}
+
+int
+ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth)
+{
+	ECDSA_DATA *ecdsa;
+
+	ecdsa = ecdsa_check(eckey);
+
+	if (ecdsa == NULL)
+		return 0;
+
+#ifndef OPENSSL_NO_ENGINE
+	if (ecdsa->engine) {
+		ENGINE_finish(ecdsa->engine);
+		ecdsa->engine = NULL;
+	}
+#endif
+	ecdsa->meth = meth;
+
+	return 1;
+}
+
+static ECDSA_DATA *
+ECDSA_DATA_new_method(ENGINE *engine)
+{
+	ECDSA_DATA *ret;
+
+	ret = malloc(sizeof(ECDSA_DATA));
+	if (ret == NULL) {
+		ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+		return (NULL);
+	}
+
+	ret->init = NULL;
+
+	ret->meth = ECDSA_get_default_method();
+	ret->engine = engine;
+#ifndef OPENSSL_NO_ENGINE
+	if (!ret->engine)
+		ret->engine = ENGINE_get_default_ECDSA();
+	if (ret->engine) {
+		ret->meth = ENGINE_get_ECDSA(ret->engine);
+		if (!ret->meth) {
+			ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD,
+			    ERR_R_ENGINE_LIB);
+			ENGINE_finish(ret->engine);
+			free(ret);
+			return NULL;
+		}
+	}
+#endif
+
+	ret->flags = ret->meth->flags;
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data);
+	return (ret);
+}
+
+static void *
+ecdsa_data_new(void)
+{
+	return (void *)ECDSA_DATA_new_method(NULL);
+}
+
+static void *
+ecdsa_data_dup(void *data)
+{
+	ECDSA_DATA *r = (ECDSA_DATA *)data;
+
+	/* XXX: dummy operation */
+	if (r == NULL)
+		return NULL;
+
+	return ecdsa_data_new();
+}
+
+static void
+ecdsa_data_free(void *data)
+{
+	ECDSA_DATA *r = (ECDSA_DATA *)data;
+
+#ifndef OPENSSL_NO_ENGINE
+	if (r->engine)
+		ENGINE_finish(r->engine);
+#endif
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, r, &r->ex_data);
+
+	explicit_bzero((void *)r, sizeof(ECDSA_DATA));
+
+	free(r);
+}
+
+ECDSA_DATA *
+ecdsa_check(EC_KEY *key)
+{
+	ECDSA_DATA *ecdsa_data;
+
+	void *data = EC_KEY_get_key_method_data(key, ecdsa_data_dup,
+	    ecdsa_data_free, ecdsa_data_free);
+	if (data == NULL) {
+		ecdsa_data = (ECDSA_DATA *)ecdsa_data_new();
+		if (ecdsa_data == NULL)
+			return NULL;
+		data = EC_KEY_insert_key_method_data(key, (void *)ecdsa_data,
+		    ecdsa_data_dup, ecdsa_data_free, ecdsa_data_free);
+		if (data != NULL) {
+			/* Another thread raced us to install the key_method
+			 * data and won. */
+			ecdsa_data_free(ecdsa_data);
+			ecdsa_data = (ECDSA_DATA *)data;
+		}
+	} else
+		ecdsa_data = (ECDSA_DATA *)data;
+
+	return ecdsa_data;
+}
+
+int
+ECDSA_size(const EC_KEY *r)
+{
+	int ret, i;
+	ASN1_INTEGER bs;
+	BIGNUM	*order = NULL;
+	unsigned char buf[4];
+	const EC_GROUP *group;
+
+	if (r == NULL)
+		return 0;
+	group = EC_KEY_get0_group(r);
+	if (group == NULL)
+		return 0;
+
+	if ((order = BN_new()) == NULL)
+		return 0;
+	if (!EC_GROUP_get_order(group, order, NULL)) {
+		BN_clear_free(order);
+		return 0;
+	}
+	i = BN_num_bits(order);
+	bs.length = (i + 7) / 8;
+	bs.data = buf;
+	bs.type = V_ASN1_INTEGER;
+	/* If the top bit is set the asn1 encoding is 1 larger. */
+	buf[0] = 0xff;
+
+	i = i2d_ASN1_INTEGER(&bs, NULL);
+	i += i; /* r and s */
+	ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
+	BN_clear_free(order);
+	return (ret);
+}
+
+int
+ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+    CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+{
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDSA, argl, argp,
+	    new_func, dup_func, free_func);
+}
+
+int
+ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg)
+{
+	ECDSA_DATA *ecdsa;
+	ecdsa = ecdsa_check(d);
+	if (ecdsa == NULL)
+		return 0;
+	return (CRYPTO_set_ex_data(&ecdsa->ex_data, idx, arg));
+}
+
+void *
+ECDSA_get_ex_data(EC_KEY *d, int idx)
+{
+	ECDSA_DATA *ecdsa;
+	ecdsa = ecdsa_check(d);
+	if (ecdsa == NULL)
+		return NULL;
+	return (CRYPTO_get_ex_data(&ecdsa->ex_data, idx));
+}
diff --git a/crypto/libressl/crypto/ecdsa/ecs_locl.h b/crypto/libressl/crypto/ecdsa/ecs_locl.h
new file mode 100644
index 0000000000..47795b44e6
--- /dev/null
+++ b/crypto/libressl/crypto/ecdsa/ecs_locl.h
@@ -0,0 +1,90 @@
+/* $OpenBSD: ecs_locl.h,v 1.3 2014/11/17 20:25:50 miod Exp $ */
+/*
+ * Written by Nils Larsch for the OpenSSL project
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_ECS_LOCL_H
+#define HEADER_ECS_LOCL_H
+
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct ecdsa_data_st {
+	/* EC_KEY_METH_DATA part */
+	int (*init)(EC_KEY *);
+	/* method (ECDSA) specific part */
+	ENGINE	*engine;
+	int	flags;
+	const ECDSA_METHOD *meth;
+	CRYPTO_EX_DATA ex_data;
+} ECDSA_DATA;
+
+/** ecdsa_check
+ * checks whether ECKEY->meth_data is a pointer to a ECDSA_DATA structure
+ * and if not it removes the old meth_data and creates a ECDSA_DATA structure.
+ * \param  eckey pointer to a EC_KEY object
+ * \return pointer to a ECDSA_DATA structure
+ */
+ECDSA_DATA *ecdsa_check(EC_KEY *eckey);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* HEADER_ECS_LOCL_H */
diff --git a/crypto/libressl/crypto/ecdsa/ecs_ossl.c b/crypto/libressl/crypto/ecdsa/ecs_ossl.c
new file mode 100644
index 0000000000..b03b1fb0bd
--- /dev/null
+++ b/crypto/libressl/crypto/ecdsa/ecs_ossl.c
@@ -0,0 +1,430 @@
+/* $OpenBSD: ecs_ossl.c,v 1.5 2014/07/12 16:03:37 miod Exp $ */
+/*
+ * Written by Nils Larsch for the OpenSSL project
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2004 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include "ecs_locl.h"
+#include 
+#include 
+#include 
+
+static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen,
+    const BIGNUM *, const BIGNUM *, EC_KEY *eckey);
+static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
+    BIGNUM **rp);
+static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
+    const ECDSA_SIG *sig, EC_KEY *eckey);
+
+static ECDSA_METHOD openssl_ecdsa_meth = {
+	.name = "OpenSSL ECDSA method",
+	.ecdsa_do_sign = ecdsa_do_sign,
+	.ecdsa_sign_setup = ecdsa_sign_setup,
+	.ecdsa_do_verify = ecdsa_do_verify
+};
+
+const ECDSA_METHOD *
+ECDSA_OpenSSL(void)
+{
+	return &openssl_ecdsa_meth;
+}
+
+static int
+ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+{
+	BN_CTX   *ctx = NULL;
+	BIGNUM	 *k = NULL, *r = NULL, *order = NULL, *X = NULL;
+	EC_POINT *tmp_point = NULL;
+	const EC_GROUP *group;
+	int 	 ret = 0;
+
+	if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
+		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+
+	if (ctx_in == NULL) {
+		if ((ctx = BN_CTX_new()) == NULL) {
+			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
+			    ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+	} else
+		ctx = ctx_in;
+
+	k = BN_new();	/* this value is later returned in *kinvp */
+	r = BN_new();	/* this value is later returned in *rp    */
+	order = BN_new();
+	X = BN_new();
+	if (!k || !r || !order || !X) {
+		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	if ((tmp_point = EC_POINT_new(group)) == NULL) {
+		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
+		goto err;
+	}
+	if (!EC_GROUP_get_order(group, order, ctx)) {
+		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
+		goto err;
+	}
+
+	do {
+		/* get random k */
+		do
+			if (!BN_rand_range(k, order)) {
+				ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
+				    ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
+				goto err;
+			}
+		while (BN_is_zero(k));
+
+		/* We do not want timing information to leak the length of k,
+		 * so we compute G*k using an equivalent scalar of fixed
+		 * bit-length. */
+		if (!BN_add(k, k, order))
+			goto err;
+		if (BN_num_bits(k) <= BN_num_bits(order))
+			if (!BN_add(k, k, order))
+				goto err;
+
+		/* compute r the x-coordinate of generator * k */
+		if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
+			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
+			goto err;
+		}
+		if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
+		    NID_X9_62_prime_field) {
+			if (!EC_POINT_get_affine_coordinates_GFp(group,
+			    tmp_point, X, NULL, ctx)) {
+				ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
+				    ERR_R_EC_LIB);
+				goto err;
+			}
+		}
+#ifndef OPENSSL_NO_EC2M
+		else /* NID_X9_62_characteristic_two_field */
+		{
+			if (!EC_POINT_get_affine_coordinates_GF2m(group,
+			    tmp_point, X, NULL, ctx)) {
+				ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
+				    ERR_R_EC_LIB);
+				goto err;
+			}
+		}
+#endif
+		if (!BN_nnmod(r, X, order, ctx)) {
+			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
+			goto err;
+		}
+	} while (BN_is_zero(r));
+
+	/* compute the inverse of k */
+	if (!BN_mod_inverse(k, k, order, ctx)) {
+		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
+		goto err;
+	}
+	/* clear old values if necessary */
+	BN_clear_free(*rp);
+	BN_clear_free(*kinvp);
+	/* save the pre-computed values  */
+	*rp = r;
+	*kinvp = k;
+	ret = 1;
+
+err:
+	if (!ret) {
+		BN_clear_free(k);
+		BN_clear_free(r);
+	}
+	if (ctx_in == NULL)
+		BN_CTX_free(ctx);
+	BN_free(order);
+	EC_POINT_free(tmp_point);
+	BN_clear_free(X);
+	return (ret);
+}
+
+
+static ECDSA_SIG *
+ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
+    const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
+{
+	int     ok = 0, i;
+	BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL;
+	const BIGNUM *ckinv;
+	BN_CTX     *ctx = NULL;
+	const EC_GROUP   *group;
+	ECDSA_SIG  *ret;
+	ECDSA_DATA *ecdsa;
+	const BIGNUM *priv_key;
+
+	ecdsa = ecdsa_check(eckey);
+	group = EC_KEY_get0_group(eckey);
+	priv_key = EC_KEY_get0_private_key(eckey);
+
+	if (group == NULL || priv_key == NULL || ecdsa == NULL) {
+		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
+		return NULL;
+	}
+
+	ret = ECDSA_SIG_new();
+	if (!ret) {
+		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	s = ret->s;
+
+	if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
+	    (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) {
+		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	if (!EC_GROUP_get_order(group, order, ctx)) {
+		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
+		goto err;
+	}
+	i = BN_num_bits(order);
+	/* Need to truncate digest if it is too long: first truncate whole
+	 * bytes.
+	 */
+	if (8 * dgst_len > i)
+		dgst_len = (i + 7)/8;
+	if (!BN_bin2bn(dgst, dgst_len, m)) {
+		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
+		goto err;
+	}
+	/* If still too long truncate remaining bits with a shift */
+	if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
+		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
+		goto err;
+	}
+	do {
+		if (in_kinv == NULL || in_r == NULL) {
+			if (!ECDSA_sign_setup(eckey, ctx, &kinv, &ret->r)) {
+				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,
+				    ERR_R_ECDSA_LIB);
+				goto err;
+			}
+			ckinv = kinv;
+		} else {
+			ckinv = in_kinv;
+			if (BN_copy(ret->r, in_r) == NULL) {
+				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,
+				    ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+		}
+
+		if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) {
+			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
+			goto err;
+		}
+		if (!BN_mod_add_quick(s, tmp, m, order)) {
+			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
+			goto err;
+		}
+		if (!BN_mod_mul(s, s, ckinv, order, ctx)) {
+			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
+			goto err;
+		}
+		if (BN_is_zero(s)) {
+			/* if kinv and r have been supplied by the caller
+			 * don't to generate new kinv and r values */
+			if (in_kinv != NULL && in_r != NULL) {
+				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,
+				    ECDSA_R_NEED_NEW_SETUP_VALUES);
+				goto err;
+			}
+		} else
+			/* s != 0 => we have a valid signature */
+			break;
+	} while (1);
+
+	ok = 1;
+
+err:
+	if (!ok) {
+		ECDSA_SIG_free(ret);
+		ret = NULL;
+	}
+	BN_CTX_free(ctx);
+	BN_clear_free(m);
+	BN_clear_free(tmp);
+	BN_free(order);
+	BN_clear_free(kinv);
+	return ret;
+}
+
+static int
+ecdsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig,
+    EC_KEY *eckey)
+{
+	int ret = -1, i;
+	BN_CTX   *ctx;
+	BIGNUM   *order, *u1, *u2, *m, *X;
+	EC_POINT *point = NULL;
+	const EC_GROUP *group;
+	const EC_POINT *pub_key;
+
+	/* check input values */
+	if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
+	    (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) {
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
+		return -1;
+	}
+
+	ctx = BN_CTX_new();
+	if (!ctx) {
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
+		return -1;
+	}
+	BN_CTX_start(ctx);
+	order = BN_CTX_get(ctx);
+	u1 = BN_CTX_get(ctx);
+	u2 = BN_CTX_get(ctx);
+	m = BN_CTX_get(ctx);
+	X = BN_CTX_get(ctx);
+	if (!X) {
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+		goto err;
+	}
+
+	if (!EC_GROUP_get_order(group, order, ctx)) {
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
+		goto err;
+	}
+
+	if (BN_is_zero(sig->r)          || BN_is_negative(sig->r) ||
+	    BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s)  ||
+	    BN_is_negative(sig->s)      || BN_ucmp(sig->s, order) >= 0) {
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
+		ret = 0;	/* signature is invalid */
+		goto err;
+	}
+	/* calculate tmp1 = inv(S) mod order */
+	if (!BN_mod_inverse(u2, sig->s, order, ctx)) {
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+		goto err;
+	}
+	/* digest -> m */
+	i = BN_num_bits(order);
+	/* Need to truncate digest if it is too long: first truncate whole
+	 * bytes.
+	 */
+	if (8 * dgst_len > i)
+		dgst_len = (i + 7)/8;
+	if (!BN_bin2bn(dgst, dgst_len, m)) {
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+		goto err;
+	}
+	/* If still too long truncate remaining bits with a shift */
+	if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+		goto err;
+	}
+	/* u1 = m * tmp mod order */
+	if (!BN_mod_mul(u1, m, u2, order, ctx)) {
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+		goto err;
+	}
+	/* u2 = r * w mod q */
+	if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) {
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+		goto err;
+	}
+
+	if ((point = EC_POINT_new(group)) == NULL) {
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) {
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
+		goto err;
+	}
+	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
+	    NID_X9_62_prime_field) {
+		if (!EC_POINT_get_affine_coordinates_GFp(group,
+		    point, X, NULL, ctx)) {
+			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
+			goto err;
+		}
+	}
+#ifndef OPENSSL_NO_EC2M
+	else /* NID_X9_62_characteristic_two_field */
+	{
+		if (!EC_POINT_get_affine_coordinates_GF2m(group,
+		    point, X, NULL, ctx)) {
+			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
+			goto err;
+		}
+	}
+#endif
+	if (!BN_nnmod(u1, X, order, ctx)) {
+		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+		goto err;
+	}
+	/*  if the signature is correct u1 is equal to sig->r */
+	ret = (BN_ucmp(u1, sig->r) == 0);
+
+err:
+	BN_CTX_end(ctx);
+	BN_CTX_free(ctx);
+	EC_POINT_free(point);
+	return ret;
+}
diff --git a/crypto/libressl/crypto/ecdsa/ecs_sign.c b/crypto/libressl/crypto/ecdsa/ecs_sign.c
new file mode 100644
index 0000000000..2001513c8f
--- /dev/null
+++ b/crypto/libressl/crypto/ecdsa/ecs_sign.c
@@ -0,0 +1,111 @@
+/* $OpenBSD: ecs_sign.c,v 1.5 2014/10/18 17:20:40 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include "ecs_locl.h"
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+
+ECDSA_SIG *
+ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
+{
+	return ECDSA_do_sign_ex(dgst, dlen, NULL, NULL, eckey);
+}
+
+ECDSA_SIG *
+ECDSA_do_sign_ex(const unsigned char *dgst, int dlen, const BIGNUM *kinv,
+    const BIGNUM *rp, EC_KEY *eckey)
+{
+	ECDSA_DATA *ecdsa = ecdsa_check(eckey);
+
+	if (ecdsa == NULL)
+		return NULL;
+	return ecdsa->meth->ecdsa_do_sign(dgst, dlen, kinv, rp, eckey);
+}
+
+int
+ECDSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
+    unsigned int *siglen, EC_KEY *eckey)
+{
+	return ECDSA_sign_ex(type, dgst, dlen, sig, siglen, NULL, NULL, eckey);
+}
+
+int
+ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
+    unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey)
+{
+	ECDSA_SIG *s;
+
+	s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey);
+	if (s == NULL) {
+		*siglen = 0;
+		return 0;
+	}
+	*siglen = i2d_ECDSA_SIG(s, &sig);
+	ECDSA_SIG_free(s);
+	return 1;
+}
+
+int
+ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+{
+	ECDSA_DATA *ecdsa = ecdsa_check(eckey);
+
+	if (ecdsa == NULL)
+		return 0;
+	return ecdsa->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp);
+}
diff --git a/crypto/libressl/crypto/ecdsa/ecs_vrf.c b/crypto/libressl/crypto/ecdsa/ecs_vrf.c
new file mode 100644
index 0000000000..c9a6edafee
--- /dev/null
+++ b/crypto/libressl/crypto/ecdsa/ecs_vrf.c
@@ -0,0 +1,116 @@
+/* $OpenBSD: ecs_vrf.c,v 1.4 2015/01/28 04:14:31 beck Exp $ */
+/*
+ * Written by Nils Larsch for the OpenSSL project
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include "ecs_locl.h"
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+
+/* returns
+ *      1: correct signature
+ *      0: incorrect signature
+ *     -1: error
+ */
+int
+ECDSA_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig,
+    EC_KEY *eckey)
+{
+	ECDSA_DATA *ecdsa = ecdsa_check(eckey);
+
+	if (ecdsa == NULL)
+		return 0;
+	return ecdsa->meth->ecdsa_do_verify(dgst, dgst_len, sig, eckey);
+}
+
+/* returns
+ *      1: correct signature
+ *      0: incorrect signature
+ *     -1: error
+ */
+int
+ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
+    const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
+{
+	ECDSA_SIG *s;
+	unsigned char *der = NULL;
+	const unsigned char *p = sigbuf;
+	int derlen = -1;
+	int ret = -1;
+
+	s = ECDSA_SIG_new();
+	if (s == NULL)
+		return (ret);
+	if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL)
+		goto err;
+	/* Ensure signature uses DER and doesn't have trailing garbage */
+	derlen = i2d_ECDSA_SIG(s, &der);
+	if (derlen != sig_len || memcmp(sigbuf, der, derlen))
+		goto err;
+	ret = ECDSA_do_verify(dgst, dgst_len, s, eckey);
+
+err:
+	if (derlen > 0) {
+		explicit_bzero(der, derlen);
+		free(der);
+	}
+	ECDSA_SIG_free(s);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/engine/eng_all.c b/crypto/libressl/crypto/engine/eng_all.c
new file mode 100644
index 0000000000..852ea943b9
--- /dev/null
+++ b/crypto/libressl/crypto/engine/eng_all.c
@@ -0,0 +1,78 @@
+/* $OpenBSD: eng_all.c,v 1.28 2015/06/19 06:05:11 bcook Exp $ */
+/* Written by Richard Levitte  for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include "cryptlib.h"
+#include "eng_int.h"
+
+void
+ENGINE_load_builtin_engines(void)
+{
+	/* Some ENGINEs need this */
+	OPENSSL_cpuid_setup();
+
+#ifndef OPENSSL_NO_STATIC_ENGINE
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_PADLOCK
+	ENGINE_load_padlock();
+#endif
+#endif
+#endif
+	ENGINE_register_all_complete();
+}
diff --git a/crypto/libressl/crypto/engine/eng_cnf.c b/crypto/libressl/crypto/engine/eng_cnf.c
new file mode 100644
index 0000000000..1143153450
--- /dev/null
+++ b/crypto/libressl/crypto/engine/eng_cnf.c
@@ -0,0 +1,257 @@
+/* $OpenBSD: eng_cnf.c,v 1.12 2014/07/10 13:58:22 jsing Exp $ */
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include "eng_int.h"
+#include 
+
+/* #define ENGINE_CONF_DEBUG */
+
+/* ENGINE config module */
+
+static char *
+skip_dot(char *name)
+{
+	char *p;
+
+	p = strchr(name, '.');
+	if (p)
+		return p + 1;
+	return name;
+}
+
+static STACK_OF(ENGINE) *initialized_engines = NULL;
+
+static int
+int_engine_init(ENGINE *e)
+{
+	if (!ENGINE_init(e))
+		return 0;
+	if (!initialized_engines)
+		initialized_engines = sk_ENGINE_new_null();
+	if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e)) {
+		ENGINE_finish(e);
+		return 0;
+	}
+	return 1;
+}
+
+
+static int
+int_engine_configure(char *name, char *value, const CONF *cnf)
+{
+	int i;
+	int ret = 0;
+	long do_init = -1;
+	STACK_OF(CONF_VALUE) *ecmds;
+	CONF_VALUE *ecmd = NULL;
+	char *ctrlname, *ctrlvalue;
+	ENGINE *e = NULL;
+	int soft = 0;
+
+	name = skip_dot(name);
+#ifdef ENGINE_CONF_DEBUG
+	fprintf(stderr, "Configuring engine %s\n", name);
+#endif
+	/* Value is a section containing ENGINE commands */
+	ecmds = NCONF_get_section(cnf, value);
+
+	if (!ecmds) {
+		ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE,
+		    ENGINE_R_ENGINE_SECTION_ERROR);
+		return 0;
+	}
+
+	for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++) {
+		ecmd = sk_CONF_VALUE_value(ecmds, i);
+		ctrlname = skip_dot(ecmd->name);
+		ctrlvalue = ecmd->value;
+#ifdef ENGINE_CONF_DEBUG
+		fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n",
+		    ctrlname, ctrlvalue);
+#endif
+
+		/* First handle some special pseudo ctrls */
+
+		/* Override engine name to use */
+		if (!strcmp(ctrlname, "engine_id"))
+			name = ctrlvalue;
+		else if (!strcmp(ctrlname, "soft_load"))
+			soft = 1;
+		/* Load a dynamic ENGINE */
+		else if (!strcmp(ctrlname, "dynamic_path")) {
+			e = ENGINE_by_id("dynamic");
+			if (!e)
+				goto err;
+			if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0))
+				goto err;
+			if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0))
+				goto err;
+			if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
+				goto err;
+		}
+		/* ... add other pseudos here ... */
+		else {
+			/* At this point we need an ENGINE structural reference
+			 * if we don't already have one.
+			 */
+			if (!e) {
+				e = ENGINE_by_id(name);
+				if (!e && soft) {
+					ERR_clear_error();
+					return 1;
+				}
+				if (!e)
+					goto err;
+			}
+			/* Allow "EMPTY" to mean no value: this allows a valid
+			 * "value" to be passed to ctrls of type NO_INPUT
+		 	 */
+			if (!strcmp(ctrlvalue, "EMPTY"))
+				ctrlvalue = NULL;
+			if (!strcmp(ctrlname, "init")) {
+				if (!NCONF_get_number_e(cnf, value, "init",
+				    &do_init))
+					goto err;
+				if (do_init == 1) {
+					if (!int_engine_init(e))
+						goto err;
+				} else if (do_init != 0) {
+					ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE,
+					    ENGINE_R_INVALID_INIT_VALUE);
+					goto err;
+				}
+			}
+			else if (!strcmp(ctrlname, "default_algorithms")) {
+				if (!ENGINE_set_default_string(e, ctrlvalue))
+					goto err;
+			} else if (!ENGINE_ctrl_cmd_string(e,
+				ctrlname, ctrlvalue, 0))
+				goto err;
+		}
+	}
+	if (e && (do_init == -1) && !int_engine_init(e)) {
+		ecmd = NULL;
+		goto err;
+	}
+	ret = 1;
+
+err:
+	if (ret != 1) {
+		ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE,
+		    ENGINE_R_ENGINE_CONFIGURATION_ERROR);
+		if (ecmd)
+			ERR_asprintf_error_data(
+			    "section=%s, name=%s, value=%s",
+			    ecmd->section, ecmd->name, ecmd->value);
+	}
+	if (e)
+		ENGINE_free(e);
+	return ret;
+}
+
+
+static int
+int_engine_module_init(CONF_IMODULE *md, const CONF *cnf)
+{
+	STACK_OF(CONF_VALUE) *elist;
+	CONF_VALUE *cval;
+	int i;
+
+#ifdef ENGINE_CONF_DEBUG
+	fprintf(stderr, "Called engine module: name %s, value %s\n",
+	    CONF_imodule_get_name(md), CONF_imodule_get_value(md));
+#endif
+	/* Value is a section containing ENGINEs to configure */
+	elist = NCONF_get_section(cnf, CONF_imodule_get_value(md));
+
+	if (!elist) {
+		ENGINEerr(ENGINE_F_INT_ENGINE_MODULE_INIT,
+		    ENGINE_R_ENGINES_SECTION_ERROR);
+		return 0;
+	}
+
+	for (i = 0; i < sk_CONF_VALUE_num(elist); i++) {
+		cval = sk_CONF_VALUE_value(elist, i);
+		if (!int_engine_configure(cval->name, cval->value, cnf))
+			return 0;
+	}
+
+	return 1;
+}
+
+static void
+int_engine_module_finish(CONF_IMODULE *md)
+{
+	ENGINE *e;
+
+	while ((e = sk_ENGINE_pop(initialized_engines)))
+		ENGINE_finish(e);
+	sk_ENGINE_free(initialized_engines);
+	initialized_engines = NULL;
+}
+
+void
+ENGINE_add_conf_module(void)
+{
+	CONF_module_add("engines", int_engine_module_init,
+	    int_engine_module_finish);
+}
diff --git a/crypto/libressl/crypto/engine/eng_ctrl.c b/crypto/libressl/crypto/engine/eng_ctrl.c
new file mode 100644
index 0000000000..47a9455544
--- /dev/null
+++ b/crypto/libressl/crypto/engine/eng_ctrl.c
@@ -0,0 +1,393 @@
+/* $OpenBSD: eng_ctrl.c,v 1.9 2014/07/10 13:58:22 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include "eng_int.h"
+
+/* When querying a ENGINE-specific control command's 'description', this string
+ * is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL. */
+static const char *int_no_description = "";
+
+/* These internal functions handle 'CMD'-related control commands when the
+ * ENGINE in question has asked us to take care of it (ie. the ENGINE did not
+ * set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag. */
+
+static int
+int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn)
+{
+	if ((defn->cmd_num == 0) || (defn->cmd_name == NULL))
+		return 1;
+	return 0;
+}
+
+static int
+int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s)
+{
+	int idx = 0;
+	while (!int_ctrl_cmd_is_null(defn) &&
+	    (strcmp(defn->cmd_name, s) != 0)) {
+		idx++;
+		defn++;
+	}
+	if (int_ctrl_cmd_is_null(defn))
+		/* The given name wasn't found */
+		return -1;
+	return idx;
+}
+
+static int
+int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num)
+{
+	int idx = 0;
+	/* NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So
+	 * our searches don't need to take any longer than necessary. */
+	while (!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num)) {
+		idx++;
+		defn++;
+	}
+	if (defn->cmd_num == num)
+		return idx;
+	/* The given cmd_num wasn't found */
+	return -1;
+}
+
+static int
+int_ctrl_helper(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+{
+	int idx;
+	int ret;
+	char *s = (char *)p;
+
+	/* Take care of the easy one first (eg. it requires no searches) */
+	if (cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE) {
+		if ((e->cmd_defns == NULL) ||
+		    int_ctrl_cmd_is_null(e->cmd_defns))
+			return 0;
+		return e->cmd_defns->cmd_num;
+	}
+	/* One or two commands require that "p" be a valid string buffer */
+	if ((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) ||
+	    (cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) ||
+	    (cmd == ENGINE_CTRL_GET_DESC_FROM_CMD)) {
+		if (s == NULL) {
+			ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
+			    ERR_R_PASSED_NULL_PARAMETER);
+			return -1;
+		}
+	}
+	/* Now handle cmd_name -> cmd_num conversion */
+	if (cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) {
+		if ((e->cmd_defns == NULL) ||
+		    ((idx = int_ctrl_cmd_by_name(e->cmd_defns, s)) < 0)) {
+			ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
+			    ENGINE_R_INVALID_CMD_NAME);
+			return -1;
+		}
+		return e->cmd_defns[idx].cmd_num;
+	}
+	/* For the rest of the commands, the 'long' argument must specify a
+	 * valie command number - so we need to conduct a search. */
+	if ((e->cmd_defns == NULL) ||
+	    ((idx = int_ctrl_cmd_by_num(e->cmd_defns, (unsigned int)i)) < 0)) {
+		ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
+		    ENGINE_R_INVALID_CMD_NUMBER);
+		return -1;
+	}
+	/* Now the logic splits depending on command type */
+	switch (cmd) {
+	case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
+		idx++;
+		if (int_ctrl_cmd_is_null(e->cmd_defns + idx))
+			/* end-of-list */
+			return 0;
+		else
+			return e->cmd_defns[idx].cmd_num;
+	case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
+		return strlen(e->cmd_defns[idx].cmd_name);
+	case ENGINE_CTRL_GET_NAME_FROM_CMD:
+		ret = snprintf(s, strlen(e->cmd_defns[idx].cmd_name) + 1,
+		    "%s", e->cmd_defns[idx].cmd_name);
+		if (ret >= (strlen(e->cmd_defns[idx].cmd_name) + 1))
+			ret = -1;
+		return ret;
+	case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
+		if (e->cmd_defns[idx].cmd_desc)
+			return strlen(e->cmd_defns[idx].cmd_desc);
+		return strlen(int_no_description);
+	case ENGINE_CTRL_GET_DESC_FROM_CMD:
+		if (e->cmd_defns[idx].cmd_desc) {
+			ret = snprintf(s,
+			    strlen(e->cmd_defns[idx].cmd_desc) + 1,
+			    "%s", e->cmd_defns[idx].cmd_desc);
+			if (ret >= strlen(e->cmd_defns[idx].cmd_desc) + 1)
+				ret = -1;
+			return ret;
+		}
+		ret = snprintf(s, strlen(int_no_description) + 1, "%s",
+		    int_no_description);
+		if (ret >= strlen(int_no_description) + 1)
+			ret = -1;
+		return ret;
+	case ENGINE_CTRL_GET_CMD_FLAGS:
+		return e->cmd_defns[idx].cmd_flags;
+	}
+
+	/* Shouldn't really be here ... */
+	ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INTERNAL_LIST_ERROR);
+	return -1;
+}
+
+int
+ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
+{
+	int ctrl_exists, ref_exists;
+
+	if (e == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_CTRL, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	ref_exists = ((e->struct_ref > 0) ? 1 : 0);
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	ctrl_exists = ((e->ctrl == NULL) ? 0 : 1);
+	if (!ref_exists) {
+		ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_NO_REFERENCE);
+		return 0;
+	}
+	/* Intercept any "root-level" commands before trying to hand them on to
+	 * ctrl() handlers. */
+	switch (cmd) {
+	case ENGINE_CTRL_HAS_CTRL_FUNCTION:
+		return ctrl_exists;
+	case ENGINE_CTRL_GET_FIRST_CMD_TYPE:
+	case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
+	case ENGINE_CTRL_GET_CMD_FROM_NAME:
+	case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
+	case ENGINE_CTRL_GET_NAME_FROM_CMD:
+	case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
+	case ENGINE_CTRL_GET_DESC_FROM_CMD:
+	case ENGINE_CTRL_GET_CMD_FLAGS:
+		if (ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL))
+			return int_ctrl_helper(e, cmd, i, p, f);
+		if (!ctrl_exists) {
+			ENGINEerr(ENGINE_F_ENGINE_CTRL,
+			    ENGINE_R_NO_CONTROL_FUNCTION);
+			/* For these cmd-related functions, failure is indicated
+			 * by a -1 return value (because 0 is used as a valid
+			 * return in some places). */
+			return -1;
+		}
+	default:
+		break;
+	}
+	/* Anything else requires a ctrl() handler to exist. */
+	if (!ctrl_exists) {
+		ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_NO_CONTROL_FUNCTION);
+		return 0;
+	}
+	return e->ctrl(e, cmd, i, p, f);
+}
+
+int
+ENGINE_cmd_is_executable(ENGINE *e, int cmd)
+{
+	int flags;
+
+	if ((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd,
+	    NULL, NULL)) < 0) {
+		ENGINEerr(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE,
+		    ENGINE_R_INVALID_CMD_NUMBER);
+		return 0;
+	}
+	if (!(flags & ENGINE_CMD_FLAG_NO_INPUT) &&
+	    !(flags & ENGINE_CMD_FLAG_NUMERIC) &&
+	    !(flags & ENGINE_CMD_FLAG_STRING))
+		return 0;
+	return 1;
+}
+
+int
+ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, long i, void *p,
+    void (*f)(void), int cmd_optional)
+{
+	int num;
+
+	if ((e == NULL) || (cmd_name == NULL)) {
+		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	if ((e->ctrl == NULL) ||
+	    ((num = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FROM_NAME,
+	    0, (void *)cmd_name, NULL)) <= 0)) {
+		/* If the command didn't *have* to be supported, we fake
+		 * success. This allows certain settings to be specified for
+		 * multiple ENGINEs and only require a change of ENGINE id
+		 * (without having to selectively apply settings). Eg. changing
+		 * from a hardware device back to the regular software ENGINE
+		 * without editing the config file, etc. */
+		if (cmd_optional) {
+			ERR_clear_error();
+			return 1;
+		}
+		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD, ENGINE_R_INVALID_CMD_NAME);
+		return 0;
+	}
+
+	/* Force the result of the control command to 0 or 1, for the reasons
+	 * mentioned before. */
+	if (ENGINE_ctrl(e, num, i, p, f) > 0)
+		return 1;
+
+	return 0;
+}
+
+int
+ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
+    int cmd_optional)
+{
+	int num, flags;
+	long l;
+	char *ptr;
+
+	if ((e == NULL) || (cmd_name == NULL)) {
+		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	if ((e->ctrl == NULL) ||
+	    ((num = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FROM_NAME, 0,
+	    (void *)cmd_name, NULL)) <= 0)) {
+		/* If the command didn't *have* to be supported, we fake
+		 * success. This allows certain settings to be specified for
+		 * multiple ENGINEs and only require a change of ENGINE id
+		 * (without having to selectively apply settings). Eg. changing
+		 * from a hardware device back to the regular software ENGINE
+		 * without editing the config file, etc. */
+		if (cmd_optional) {
+			ERR_clear_error();
+			return 1;
+		}
+		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+		    ENGINE_R_INVALID_CMD_NAME);
+		return 0;
+	}
+	if (!ENGINE_cmd_is_executable(e, num)) {
+		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+		    ENGINE_R_CMD_NOT_EXECUTABLE);
+		return 0;
+	}
+	if ((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num,
+	    NULL, NULL)) < 0) {
+		/* Shouldn't happen, given that ENGINE_cmd_is_executable()
+		 * returned success. */
+		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+		    ENGINE_R_INTERNAL_LIST_ERROR);
+		return 0;
+	}
+	/* If the command takes no input, there must be no input. And vice
+	 * versa. */
+	if (flags & ENGINE_CMD_FLAG_NO_INPUT) {
+		if (arg != NULL) {
+			ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+			    ENGINE_R_COMMAND_TAKES_NO_INPUT);
+			return 0;
+		}
+		/* We deliberately force the result of ENGINE_ctrl() to 0 or 1
+		 * rather than returning it as "return data". This is to ensure
+		 * usage of these commands is consistent across applications and
+		 * that certain applications don't understand it one way, and
+		 * others another. */
+		if (ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
+			return 1;
+		return 0;
+	}
+	/* So, we require input */
+	if (arg == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+		    ENGINE_R_COMMAND_TAKES_INPUT);
+		return 0;
+	}
+	/* If it takes string input, that's easy */
+	if (flags & ENGINE_CMD_FLAG_STRING) {
+		/* Same explanation as above */
+		if (ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
+			return 1;
+		return 0;
+	}
+	/* If it doesn't take numeric either, then it is unsupported for use in
+	 * a config-setting situation, which is what this function is for. This
+	 * should never happen though, because ENGINE_cmd_is_executable() was
+	 * used. */
+	if (!(flags & ENGINE_CMD_FLAG_NUMERIC)) {
+		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+		    ENGINE_R_INTERNAL_LIST_ERROR);
+		return 0;
+	}
+	l = strtol(arg, &ptr, 10);
+	if ((arg == ptr) || (*ptr != '\0')) {
+		ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+		    ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER);
+		return 0;
+	}
+	/* Force the result of the control command to 0 or 1, for the reasons
+	 * mentioned before. */
+	if (ENGINE_ctrl(e, num, l, NULL, NULL) > 0)
+		return 1;
+	return 0;
+}
diff --git a/crypto/libressl/crypto/engine/eng_dyn.c b/crypto/libressl/crypto/engine/eng_dyn.c
new file mode 100644
index 0000000000..2c5792ac3c
--- /dev/null
+++ b/crypto/libressl/crypto/engine/eng_dyn.c
@@ -0,0 +1,64 @@
+/* $OpenBSD: eng_dyn.c,v 1.13 2015/02/11 03:19:37 doug Exp $ */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+void
+ENGINE_load_dynamic(void)
+{
+}
diff --git a/crypto/libressl/crypto/engine/eng_err.c b/crypto/libressl/crypto/engine/eng_err.c
new file mode 100644
index 0000000000..85eeb5a046
--- /dev/null
+++ b/crypto/libressl/crypto/engine/eng_err.c
@@ -0,0 +1,173 @@
+/* $OpenBSD: eng_err.c,v 1.9 2014/06/22 11:33:47 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2010 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ENGINE,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ENGINE,0,reason)
+
+static ERR_STRING_DATA ENGINE_str_functs[] = {
+	{ERR_FUNC(ENGINE_F_DYNAMIC_CTRL),	"DYNAMIC_CTRL"},
+	{ERR_FUNC(ENGINE_F_DYNAMIC_GET_DATA_CTX),	"DYNAMIC_GET_DATA_CTX"},
+	{ERR_FUNC(ENGINE_F_DYNAMIC_LOAD),	"DYNAMIC_LOAD"},
+	{ERR_FUNC(ENGINE_F_DYNAMIC_SET_DATA_CTX),	"DYNAMIC_SET_DATA_CTX"},
+	{ERR_FUNC(ENGINE_F_ENGINE_ADD),	"ENGINE_add"},
+	{ERR_FUNC(ENGINE_F_ENGINE_BY_ID),	"ENGINE_by_id"},
+	{ERR_FUNC(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE),	"ENGINE_cmd_is_executable"},
+	{ERR_FUNC(ENGINE_F_ENGINE_CTRL),	"ENGINE_ctrl"},
+	{ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD),	"ENGINE_ctrl_cmd"},
+	{ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD_STRING),	"ENGINE_ctrl_cmd_string"},
+	{ERR_FUNC(ENGINE_F_ENGINE_FINISH),	"ENGINE_finish"},
+	{ERR_FUNC(ENGINE_F_ENGINE_FREE_UTIL),	"ENGINE_FREE_UTIL"},
+	{ERR_FUNC(ENGINE_F_ENGINE_GET_CIPHER),	"ENGINE_get_cipher"},
+	{ERR_FUNC(ENGINE_F_ENGINE_GET_DEFAULT_TYPE),	"ENGINE_GET_DEFAULT_TYPE"},
+	{ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST),	"ENGINE_get_digest"},
+	{ERR_FUNC(ENGINE_F_ENGINE_GET_NEXT),	"ENGINE_get_next"},
+	{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH),	"ENGINE_get_pkey_asn1_meth"},
+	{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_METH),	"ENGINE_get_pkey_meth"},
+	{ERR_FUNC(ENGINE_F_ENGINE_GET_PREV),	"ENGINE_get_prev"},
+	{ERR_FUNC(ENGINE_F_ENGINE_INIT),	"ENGINE_init"},
+	{ERR_FUNC(ENGINE_F_ENGINE_LIST_ADD),	"ENGINE_LIST_ADD"},
+	{ERR_FUNC(ENGINE_F_ENGINE_LIST_REMOVE),	"ENGINE_LIST_REMOVE"},
+	{ERR_FUNC(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY),	"ENGINE_load_private_key"},
+	{ERR_FUNC(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY),	"ENGINE_load_public_key"},
+	{ERR_FUNC(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT),	"ENGINE_load_ssl_client_cert"},
+	{ERR_FUNC(ENGINE_F_ENGINE_NEW),	"ENGINE_new"},
+	{ERR_FUNC(ENGINE_F_ENGINE_REMOVE),	"ENGINE_remove"},
+	{ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_STRING),	"ENGINE_set_default_string"},
+	{ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_TYPE),	"ENGINE_SET_DEFAULT_TYPE"},
+	{ERR_FUNC(ENGINE_F_ENGINE_SET_ID),	"ENGINE_set_id"},
+	{ERR_FUNC(ENGINE_F_ENGINE_SET_NAME),	"ENGINE_set_name"},
+	{ERR_FUNC(ENGINE_F_ENGINE_TABLE_REGISTER),	"ENGINE_TABLE_REGISTER"},
+	{ERR_FUNC(ENGINE_F_ENGINE_UNLOAD_KEY),	"ENGINE_UNLOAD_KEY"},
+	{ERR_FUNC(ENGINE_F_ENGINE_UNLOCKED_FINISH),	"ENGINE_UNLOCKED_FINISH"},
+	{ERR_FUNC(ENGINE_F_ENGINE_UP_REF),	"ENGINE_up_ref"},
+	{ERR_FUNC(ENGINE_F_INT_CTRL_HELPER),	"INT_CTRL_HELPER"},
+	{ERR_FUNC(ENGINE_F_INT_ENGINE_CONFIGURE),	"INT_ENGINE_CONFIGURE"},
+	{ERR_FUNC(ENGINE_F_INT_ENGINE_MODULE_INIT),	"INT_ENGINE_MODULE_INIT"},
+	{ERR_FUNC(ENGINE_F_LOG_MESSAGE),	"LOG_MESSAGE"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA ENGINE_str_reasons[] = {
+	{ERR_REASON(ENGINE_R_ALREADY_LOADED)     , "already loaded"},
+	{ERR_REASON(ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER), "argument is not a number"},
+	{ERR_REASON(ENGINE_R_CMD_NOT_EXECUTABLE) , "cmd not executable"},
+	{ERR_REASON(ENGINE_R_COMMAND_TAKES_INPUT), "command takes input"},
+	{ERR_REASON(ENGINE_R_COMMAND_TAKES_NO_INPUT), "command takes no input"},
+	{ERR_REASON(ENGINE_R_CONFLICTING_ENGINE_ID), "conflicting engine id"},
+	{ERR_REASON(ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED), "ctrl command not implemented"},
+	{ERR_REASON(ENGINE_R_DH_NOT_IMPLEMENTED) , "dh not implemented"},
+	{ERR_REASON(ENGINE_R_DSA_NOT_IMPLEMENTED), "dsa not implemented"},
+	{ERR_REASON(ENGINE_R_DSO_FAILURE)        , "DSO failure"},
+	{ERR_REASON(ENGINE_R_DSO_NOT_FOUND)      , "dso not found"},
+	{ERR_REASON(ENGINE_R_ENGINES_SECTION_ERROR), "engines section error"},
+	{ERR_REASON(ENGINE_R_ENGINE_CONFIGURATION_ERROR), "engine configuration error"},
+	{ERR_REASON(ENGINE_R_ENGINE_IS_NOT_IN_LIST), "engine is not in the list"},
+	{ERR_REASON(ENGINE_R_ENGINE_SECTION_ERROR), "engine section error"},
+	{ERR_REASON(ENGINE_R_FAILED_LOADING_PRIVATE_KEY), "failed loading private key"},
+	{ERR_REASON(ENGINE_R_FAILED_LOADING_PUBLIC_KEY), "failed loading public key"},
+	{ERR_REASON(ENGINE_R_FINISH_FAILED)      , "finish failed"},
+	{ERR_REASON(ENGINE_R_GET_HANDLE_FAILED)  , "could not obtain hardware handle"},
+	{ERR_REASON(ENGINE_R_ID_OR_NAME_MISSING) , "'id' or 'name' missing"},
+	{ERR_REASON(ENGINE_R_INIT_FAILED)        , "init failed"},
+	{ERR_REASON(ENGINE_R_INTERNAL_LIST_ERROR), "internal list error"},
+	{ERR_REASON(ENGINE_R_INVALID_ARGUMENT)   , "invalid argument"},
+	{ERR_REASON(ENGINE_R_INVALID_CMD_NAME)   , "invalid cmd name"},
+	{ERR_REASON(ENGINE_R_INVALID_CMD_NUMBER) , "invalid cmd number"},
+	{ERR_REASON(ENGINE_R_INVALID_INIT_VALUE) , "invalid init value"},
+	{ERR_REASON(ENGINE_R_INVALID_STRING)     , "invalid string"},
+	{ERR_REASON(ENGINE_R_NOT_INITIALISED)    , "not initialised"},
+	{ERR_REASON(ENGINE_R_NOT_LOADED)         , "not loaded"},
+	{ERR_REASON(ENGINE_R_NO_CONTROL_FUNCTION), "no control function"},
+	{ERR_REASON(ENGINE_R_NO_INDEX)           , "no index"},
+	{ERR_REASON(ENGINE_R_NO_LOAD_FUNCTION)   , "no load function"},
+	{ERR_REASON(ENGINE_R_NO_REFERENCE)       , "no reference"},
+	{ERR_REASON(ENGINE_R_NO_SUCH_ENGINE)     , "no such engine"},
+	{ERR_REASON(ENGINE_R_NO_UNLOAD_FUNCTION) , "no unload function"},
+	{ERR_REASON(ENGINE_R_PROVIDE_PARAMETERS) , "provide parameters"},
+	{ERR_REASON(ENGINE_R_RSA_NOT_IMPLEMENTED), "rsa not implemented"},
+	{ERR_REASON(ENGINE_R_UNIMPLEMENTED_CIPHER), "unimplemented cipher"},
+	{ERR_REASON(ENGINE_R_UNIMPLEMENTED_DIGEST), "unimplemented digest"},
+	{ERR_REASON(ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD), "unimplemented public key method"},
+	{ERR_REASON(ENGINE_R_VERSION_INCOMPATIBILITY), "version incompatibility"},
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_ENGINE_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(ENGINE_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, ENGINE_str_functs);
+		ERR_load_strings(0, ENGINE_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/engine/eng_fat.c b/crypto/libressl/crypto/engine/eng_fat.c
new file mode 100644
index 0000000000..aef9908354
--- /dev/null
+++ b/crypto/libressl/crypto/engine/eng_fat.c
@@ -0,0 +1,192 @@
+/* $OpenBSD: eng_fat.c,v 1.14 2014/07/10 22:45:57 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include "eng_int.h"
+#include 
+
+int
+ENGINE_set_default(ENGINE *e, unsigned int flags)
+{
+	if ((flags & ENGINE_METHOD_CIPHERS) && !ENGINE_set_default_ciphers(e))
+		return 0;
+	if ((flags & ENGINE_METHOD_DIGESTS) && !ENGINE_set_default_digests(e))
+		return 0;
+#ifndef OPENSSL_NO_RSA
+	if ((flags & ENGINE_METHOD_RSA) && !ENGINE_set_default_RSA(e))
+		return 0;
+#endif
+#ifndef OPENSSL_NO_DSA
+	if ((flags & ENGINE_METHOD_DSA) && !ENGINE_set_default_DSA(e))
+		return 0;
+#endif
+#ifndef OPENSSL_NO_DH
+	if ((flags & ENGINE_METHOD_DH) && !ENGINE_set_default_DH(e))
+		return 0;
+#endif
+#ifndef OPENSSL_NO_ECDH
+	if ((flags & ENGINE_METHOD_ECDH) && !ENGINE_set_default_ECDH(e))
+		return 0;
+#endif
+#ifndef OPENSSL_NO_ECDSA
+	if ((flags & ENGINE_METHOD_ECDSA) && !ENGINE_set_default_ECDSA(e))
+		return 0;
+#endif
+	if ((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e))
+		return 0;
+	if ((flags & ENGINE_METHOD_PKEY_METHS) &&
+	    !ENGINE_set_default_pkey_meths(e))
+		return 0;
+	if ((flags & ENGINE_METHOD_PKEY_ASN1_METHS) &&
+	    !ENGINE_set_default_pkey_asn1_meths(e))
+		return 0;
+	return 1;
+}
+
+/* Set default algorithms using a string */
+
+static int
+int_def_cb(const char *alg, int len, void *arg)
+{
+	unsigned int *pflags = arg;
+
+	if (!strncmp(alg, "ALL", len))
+		*pflags |= ENGINE_METHOD_ALL;
+	else if (!strncmp(alg, "RSA", len))
+		*pflags |= ENGINE_METHOD_RSA;
+	else if (!strncmp(alg, "DSA", len))
+		*pflags |= ENGINE_METHOD_DSA;
+	else if (!strncmp(alg, "ECDH", len))
+		*pflags |= ENGINE_METHOD_ECDH;
+	else if (!strncmp(alg, "ECDSA", len))
+		*pflags |= ENGINE_METHOD_ECDSA;
+	else if (!strncmp(alg, "DH", len))
+		*pflags |= ENGINE_METHOD_DH;
+	else if (!strncmp(alg, "RAND", len))
+		*pflags |= ENGINE_METHOD_RAND;
+	else if (!strncmp(alg, "CIPHERS", len))
+		*pflags |= ENGINE_METHOD_CIPHERS;
+	else if (!strncmp(alg, "DIGESTS", len))
+		*pflags |= ENGINE_METHOD_DIGESTS;
+	else if (!strncmp(alg, "PKEY", len))
+		*pflags |= ENGINE_METHOD_PKEY_METHS |
+		    ENGINE_METHOD_PKEY_ASN1_METHS;
+	else if (!strncmp(alg, "PKEY_CRYPTO", len))
+		*pflags |= ENGINE_METHOD_PKEY_METHS;
+	else if (!strncmp(alg, "PKEY_ASN1", len))
+		*pflags |= ENGINE_METHOD_PKEY_ASN1_METHS;
+	else
+		return 0;
+	return 1;
+}
+
+int
+ENGINE_set_default_string(ENGINE *e, const char *def_list)
+{
+	unsigned int flags = 0;
+
+	if (!CONF_parse_list(def_list, ',', 1, int_def_cb, &flags)) {
+		ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_STRING,
+		    ENGINE_R_INVALID_STRING);
+		ERR_asprintf_error_data("str=%s",def_list);
+		return 0;
+	}
+	return ENGINE_set_default(e, flags);
+}
+
+int
+ENGINE_register_complete(ENGINE *e)
+{
+	ENGINE_register_ciphers(e);
+	ENGINE_register_digests(e);
+#ifndef OPENSSL_NO_RSA
+	ENGINE_register_RSA(e);
+#endif
+#ifndef OPENSSL_NO_DSA
+	ENGINE_register_DSA(e);
+#endif
+#ifndef OPENSSL_NO_DH
+	ENGINE_register_DH(e);
+#endif
+#ifndef OPENSSL_NO_ECDH
+	ENGINE_register_ECDH(e);
+#endif
+#ifndef OPENSSL_NO_ECDSA
+	ENGINE_register_ECDSA(e);
+#endif
+	ENGINE_register_RAND(e);
+	ENGINE_register_pkey_meths(e);
+	return 1;
+}
+
+int
+ENGINE_register_all_complete(void)
+{
+	ENGINE *e;
+
+	for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+		if (!(e->flags & ENGINE_FLAGS_NO_REGISTER_ALL))
+			ENGINE_register_complete(e);
+	return 1;
+}
diff --git a/crypto/libressl/crypto/engine/eng_init.c b/crypto/libressl/crypto/engine/eng_init.c
new file mode 100644
index 0000000000..f1edf80a4c
--- /dev/null
+++ b/crypto/libressl/crypto/engine/eng_init.c
@@ -0,0 +1,150 @@
+/* $OpenBSD: eng_init.c,v 1.6 2014/06/12 15:49:29 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include "eng_int.h"
+
+/* Initialise a engine type for use (or up its functional reference count
+ * if it's already in use). This version is only used internally. */
+int
+engine_unlocked_init(ENGINE *e)
+{
+	int to_return = 1;
+
+	if ((e->funct_ref == 0) && e->init)
+		/* This is the first functional reference and the engine
+		 * requires initialisation so we do it now. */
+		to_return = e->init(e);
+	if (to_return) {
+		/* OK, we return a functional reference which is also a
+		 * structural reference. */
+		e->struct_ref++;
+		e->funct_ref++;
+		engine_ref_debug(e, 0, 1)
+		engine_ref_debug(e, 1, 1)
+	}
+	return to_return;
+}
+
+/* Free a functional reference to a engine type. This version is only used
+ * internally. */
+int
+engine_unlocked_finish(ENGINE *e, int unlock_for_handlers)
+{
+	int to_return = 1;
+
+	/* Reduce the functional reference count here so if it's the terminating
+	 * case, we can release the lock safely and call the finish() handler
+	 * without risk of a race. We get a race if we leave the count until
+	 * after and something else is calling "finish" at the same time -
+	 * there's a chance that both threads will together take the count from
+	 * 2 to 0 without either calling finish(). */
+	e->funct_ref--;
+	engine_ref_debug(e, 1, -1);
+	if ((e->funct_ref == 0) && e->finish) {
+		if (unlock_for_handlers)
+			CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+		to_return = e->finish(e);
+		if (unlock_for_handlers)
+			CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+		if (!to_return)
+			return 0;
+	}
+
+	/* Release the structural reference too */
+	if (!engine_free_util(e, 0)) {
+		ENGINEerr(ENGINE_F_ENGINE_UNLOCKED_FINISH,
+		    ENGINE_R_FINISH_FAILED);
+		return 0;
+	}
+	return to_return;
+}
+
+/* The API (locked) version of "init" */
+int
+ENGINE_init(ENGINE *e)
+{
+	int ret;
+
+	if (e == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_INIT, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	ret = engine_unlocked_init(e);
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	return ret;
+}
+
+/* The API (locked) version of "finish" */
+int
+ENGINE_finish(ENGINE *e)
+{
+	int to_return = 1;
+
+	if (e == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_FINISH, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	to_return = engine_unlocked_finish(e, 1);
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	if (!to_return) {
+		ENGINEerr(ENGINE_F_ENGINE_FINISH, ENGINE_R_FINISH_FAILED);
+		return 0;
+	}
+	return to_return;
+}
diff --git a/crypto/libressl/crypto/engine/eng_int.h b/crypto/libressl/crypto/engine/eng_int.h
new file mode 100644
index 0000000000..d0b868138b
--- /dev/null
+++ b/crypto/libressl/crypto/engine/eng_int.h
@@ -0,0 +1,206 @@
+/* $OpenBSD: eng_int.h,v 1.7 2014/07/10 22:45:57 jsing Exp $ */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_ENGINE_INT_H
+#define HEADER_ENGINE_INT_H
+
+/* Take public definitions from engine.h */
+#include 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* If we compile with this symbol defined, then both reference counts in the
+ * ENGINE structure will be monitored with a line of output on stderr for each
+ * change. This prints the engine's pointer address (truncated to unsigned int),
+ * "struct" or "funct" to indicate the reference type, the before and after
+ * reference count, and the file:line-number pair. The "engine_ref_debug"
+ * statements must come *after* the change. */
+#ifdef ENGINE_REF_COUNT_DEBUG
+
+#define engine_ref_debug(e, isfunct, diff) \
+	fprintf(stderr, "engine: %08x %s from %d to %d (%s:%d)\n", \
+		(unsigned int)(e), (isfunct ? "funct" : "struct"), \
+		((isfunct) ? ((e)->funct_ref - (diff)) : ((e)->struct_ref - (diff))), \
+		((isfunct) ? (e)->funct_ref : (e)->struct_ref), \
+		(__FILE__), (__LINE__));
+
+#else
+
+#define engine_ref_debug(e, isfunct, diff)
+
+#endif
+
+/* Any code that will need cleanup operations should use these functions to
+ * register callbacks. ENGINE_cleanup() will call all registered callbacks in
+ * order. NB: both the "add" functions assume CRYPTO_LOCK_ENGINE to already be
+ * held (in "write" mode). */
+typedef void (ENGINE_CLEANUP_CB)(void);
+typedef struct st_engine_cleanup_item {
+	ENGINE_CLEANUP_CB *cb;
+} ENGINE_CLEANUP_ITEM;
+DECLARE_STACK_OF(ENGINE_CLEANUP_ITEM)
+void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb);
+void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb);
+
+/* We need stacks of ENGINEs for use in eng_table.c */
+DECLARE_STACK_OF(ENGINE)
+
+/* If this symbol is defined then engine_table_select(), the function that is
+ * used by RSA, DSA (etc) code to select registered ENGINEs, cache defaults and
+ * functional references (etc), will display debugging summaries to stderr. */
+/* #define ENGINE_TABLE_DEBUG */
+
+/* This represents an implementation table. Dependent code should instantiate it
+ * as a (ENGINE_TABLE *) pointer value set initially to NULL. */
+typedef struct st_engine_table ENGINE_TABLE;
+int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
+    ENGINE *e, const int *nids, int num_nids, int setdefault);
+void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e);
+void engine_table_cleanup(ENGINE_TABLE **table);
+#ifndef ENGINE_TABLE_DEBUG
+ENGINE *engine_table_select(ENGINE_TABLE **table, int nid);
+#else
+ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f,
+    int l);
+#define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__)
+#endif
+typedef void (engine_table_doall_cb)(int nid, STACK_OF(ENGINE) *sk,
+    ENGINE *def, void *arg);
+void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb,
+    void *arg);
+
+/* Internal versions of API functions that have control over locking. These are
+ * used between C files when functionality needs to be shared but the caller may
+ * already be controlling of the CRYPTO_LOCK_ENGINE lock. */
+int engine_unlocked_init(ENGINE *e);
+int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers);
+int engine_free_util(ENGINE *e, int locked);
+
+/* This function will reset all "set"able values in an ENGINE to NULL. This
+ * won't touch reference counts or ex_data, but is equivalent to calling all the
+ * ENGINE_set_***() functions with a NULL value. */
+void engine_set_all_null(ENGINE *e);
+
+/* NB: Bitwise OR-able values for the "flags" variable in ENGINE are now exposed
+ * in engine.h. */
+
+/* Free up dynamically allocated public key methods associated with ENGINE */
+
+void engine_pkey_meths_free(ENGINE *e);
+void engine_pkey_asn1_meths_free(ENGINE *e);
+
+/* This is a structure for storing implementations of various crypto
+ * algorithms and functions. */
+struct engine_st {
+	const char *id;
+	const char *name;
+	const RSA_METHOD *rsa_meth;
+	const DSA_METHOD *dsa_meth;
+	const DH_METHOD *dh_meth;
+	const ECDH_METHOD *ecdh_meth;
+	const ECDSA_METHOD *ecdsa_meth;
+	const RAND_METHOD *rand_meth;
+	const STORE_METHOD *store_meth;
+	/* Cipher handling is via this callback */
+	ENGINE_CIPHERS_PTR ciphers;
+	/* Digest handling is via this callback */
+	ENGINE_DIGESTS_PTR digests;
+	/* Public key handling via this callback */
+	ENGINE_PKEY_METHS_PTR pkey_meths;
+	/* ASN1 public key handling via this callback */
+	ENGINE_PKEY_ASN1_METHS_PTR pkey_asn1_meths;
+
+	ENGINE_GEN_INT_FUNC_PTR	destroy;
+
+	ENGINE_GEN_INT_FUNC_PTR init;
+	ENGINE_GEN_INT_FUNC_PTR finish;
+	ENGINE_CTRL_FUNC_PTR ctrl;
+	ENGINE_LOAD_KEY_PTR load_privkey;
+	ENGINE_LOAD_KEY_PTR load_pubkey;
+
+	ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert;
+
+	const ENGINE_CMD_DEFN *cmd_defns;
+	int flags;
+	/* reference count on the structure itself */
+	int struct_ref;
+	/* reference count on usability of the engine type. NB: This
+	 * controls the loading and initialisation of any functionlity
+	 * required by this engine, whereas the previous count is
+	 * simply to cope with (de)allocation of this structure. Hence,
+	 * running_ref <= struct_ref at all times. */
+	int funct_ref;
+	/* A place to store per-ENGINE data */
+	CRYPTO_EX_DATA ex_data;
+	/* Used to maintain the linked-list of engines. */
+	struct engine_st *prev;
+	struct engine_st *next;
+};
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* HEADER_ENGINE_INT_H */
diff --git a/crypto/libressl/crypto/engine/eng_lib.c b/crypto/libressl/crypto/engine/eng_lib.c
new file mode 100644
index 0000000000..517072e305
--- /dev/null
+++ b/crypto/libressl/crypto/engine/eng_lib.c
@@ -0,0 +1,367 @@
+/* $OpenBSD: eng_lib.c,v 1.10 2014/10/22 13:02:04 jsing Exp $ */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+
+#include "eng_int.h"
+
+/* The "new"/"free" stuff first */
+
+ENGINE *
+ENGINE_new(void)
+{
+	ENGINE *ret;
+
+	ret = malloc(sizeof(ENGINE));
+	if (ret == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	memset(ret, 0, sizeof(ENGINE));
+	ret->struct_ref = 1;
+	engine_ref_debug(ret, 0, 1)
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data);
+	return ret;
+}
+
+/* Placed here (close proximity to ENGINE_new) so that modifications to the
+ * elements of the ENGINE structure are more likely to be caught and changed
+ * here. */
+void
+engine_set_all_null(ENGINE *e)
+{
+	e->id = NULL;
+	e->name = NULL;
+	e->rsa_meth = NULL;
+	e->dsa_meth = NULL;
+	e->dh_meth = NULL;
+	e->rand_meth = NULL;
+	e->store_meth = NULL;
+	e->ciphers = NULL;
+	e->digests = NULL;
+	e->destroy = NULL;
+	e->init = NULL;
+	e->finish = NULL;
+	e->ctrl = NULL;
+	e->load_privkey = NULL;
+	e->load_pubkey = NULL;
+	e->cmd_defns = NULL;
+	e->flags = 0;
+}
+
+int
+engine_free_util(ENGINE *e, int locked)
+{
+	int i;
+
+	if (e == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_FREE_UTIL,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	if (locked)
+		i = CRYPTO_add(&e->struct_ref, -1, CRYPTO_LOCK_ENGINE);
+	else
+		i = --e->struct_ref;
+	engine_ref_debug(e, 0, -1)
+	if (i > 0)
+		return 1;
+
+	/* Free up any dynamically allocated public key methods */
+	engine_pkey_meths_free(e);
+	engine_pkey_asn1_meths_free(e);
+	/* Give the ENGINE a chance to do any structural cleanup corresponding
+	 * to allocation it did in its constructor (eg. unload error strings) */
+	if (e->destroy)
+		e->destroy(e);
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ENGINE, e, &e->ex_data);
+	free(e);
+	return 1;
+}
+
+int
+ENGINE_free(ENGINE *e)
+{
+	return engine_free_util(e, 1);
+}
+
+/* Cleanup stuff */
+
+/* ENGINE_cleanup() is coded such that anything that does work that will need
+ * cleanup can register a "cleanup" callback here. That way we don't get linker
+ * bloat by referring to all *possible* cleanups, but any linker bloat into code
+ * "X" will cause X's cleanup function to end up here. */
+static STACK_OF(ENGINE_CLEANUP_ITEM) *cleanup_stack = NULL;
+static int
+int_cleanup_check(int create)
+{
+	if (cleanup_stack)
+		return 1;
+	if (!create)
+		return 0;
+	cleanup_stack = sk_ENGINE_CLEANUP_ITEM_new_null();
+	return (cleanup_stack ? 1 : 0);
+}
+
+static ENGINE_CLEANUP_ITEM *
+int_cleanup_item(ENGINE_CLEANUP_CB *cb)
+{
+	ENGINE_CLEANUP_ITEM *item = malloc(sizeof(ENGINE_CLEANUP_ITEM));
+
+	if (!item)
+		return NULL;
+	item->cb = cb;
+	return item;
+}
+
+void
+engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb)
+{
+	ENGINE_CLEANUP_ITEM *item;
+
+	if (!int_cleanup_check(1))
+		return;
+	item = int_cleanup_item(cb);
+	if (item)
+		sk_ENGINE_CLEANUP_ITEM_insert(cleanup_stack, item, 0);
+}
+
+void
+engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb)
+{
+	ENGINE_CLEANUP_ITEM *item;
+
+	if (!int_cleanup_check(1))
+		return;
+	item = int_cleanup_item(cb);
+	if (item)
+		sk_ENGINE_CLEANUP_ITEM_push(cleanup_stack, item);
+}
+/* The API function that performs all cleanup */
+static void
+engine_cleanup_cb_free(ENGINE_CLEANUP_ITEM *item)
+{
+	(*(item->cb))();
+	free(item);
+}
+
+void
+ENGINE_cleanup(void)
+{
+	if (int_cleanup_check(0)) {
+		sk_ENGINE_CLEANUP_ITEM_pop_free(cleanup_stack,
+		    engine_cleanup_cb_free);
+		cleanup_stack = NULL;
+	}
+	/* FIXME: This should be handled (somehow) through RAND, eg. by it
+	 * registering a cleanup callback. */
+	RAND_set_rand_method(NULL);
+}
+
+/* Now the "ex_data" support */
+
+int
+ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+    CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+{
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ENGINE, argl, argp,
+	    new_func, dup_func, free_func);
+}
+
+int
+ENGINE_set_ex_data(ENGINE *e, int idx, void *arg)
+{
+	return (CRYPTO_set_ex_data(&e->ex_data, idx, arg));
+}
+
+void *
+ENGINE_get_ex_data(const ENGINE *e, int idx)
+{
+	return (CRYPTO_get_ex_data(&e->ex_data, idx));
+}
+
+/* Functions to get/set an ENGINE's elements - mainly to avoid exposing the
+ * ENGINE structure itself. */
+
+int
+ENGINE_set_id(ENGINE *e, const char *id)
+{
+	if (id == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_SET_ID,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	e->id = id;
+	return 1;
+}
+
+int
+ENGINE_set_name(ENGINE *e, const char *name)
+{
+	if (name == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_SET_NAME,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	e->name = name;
+	return 1;
+}
+
+int
+ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f)
+{
+	e->destroy = destroy_f;
+	return 1;
+}
+
+int
+ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f)
+{
+	e->init = init_f;
+	return 1;
+}
+
+int
+ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f)
+{
+	e->finish = finish_f;
+	return 1;
+}
+
+int
+ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f)
+{
+	e->ctrl = ctrl_f;
+	return 1;
+}
+
+int
+ENGINE_set_flags(ENGINE *e, int flags)
+{
+	e->flags = flags;
+	return 1;
+}
+
+int
+ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns)
+{
+	e->cmd_defns = defns;
+	return 1;
+}
+
+const char *
+ENGINE_get_id(const ENGINE *e)
+{
+	return e->id;
+}
+
+const char *
+ENGINE_get_name(const ENGINE *e)
+{
+	return e->name;
+}
+
+ENGINE_GEN_INT_FUNC_PTR
+ENGINE_get_destroy_function(const ENGINE *e)
+{
+	return e->destroy;
+}
+
+ENGINE_GEN_INT_FUNC_PTR
+ENGINE_get_init_function(const ENGINE *e)
+{
+	return e->init;
+}
+
+ENGINE_GEN_INT_FUNC_PTR
+ENGINE_get_finish_function(const ENGINE *e)
+{
+	return e->finish;
+}
+
+ENGINE_CTRL_FUNC_PTR
+ENGINE_get_ctrl_function(const ENGINE *e)
+{
+	return e->ctrl;
+}
+
+int
+ENGINE_get_flags(const ENGINE *e)
+{
+	return e->flags;
+}
+
+const ENGINE_CMD_DEFN *
+ENGINE_get_cmd_defns(const ENGINE *e)
+{
+	return e->cmd_defns;
+}
+
+/* eng_lib.o is pretty much linked into anything that touches ENGINE already, so
+ * put the "static_state" hack here. */
+
+static int internal_static_hack = 0;
+
+void *
+ENGINE_get_static_state(void)
+{
+	return &internal_static_hack;
+}
diff --git a/crypto/libressl/crypto/engine/eng_list.c b/crypto/libressl/crypto/engine/eng_list.c
new file mode 100644
index 0000000000..fc98714466
--- /dev/null
+++ b/crypto/libressl/crypto/engine/eng_list.c
@@ -0,0 +1,396 @@
+/* $OpenBSD: eng_list.c,v 1.20 2015/06/19 06:32:43 bcook Exp $ */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include 
+#include 
+
+#include 
+
+#include 
+
+#include "cryptlib.h"
+#include "eng_int.h"
+
+/* The linked-list of pointers to engine types. engine_list_head
+ * incorporates an implicit structural reference but engine_list_tail
+ * does not - the latter is a computational niceity and only points
+ * to something that is already pointed to by its predecessor in the
+ * list (or engine_list_head itself). In the same way, the use of the
+ * "prev" pointer in each ENGINE is to save excessive list iteration,
+ * it doesn't correspond to an extra structural reference. Hence,
+ * engine_list_head, and each non-null "next" pointer account for
+ * the list itself assuming exactly 1 structural reference on each
+ * list member. */
+static ENGINE *engine_list_head = NULL;
+static ENGINE *engine_list_tail = NULL;
+
+/* This cleanup function is only needed internally. If it should be called, we
+ * register it with the "ENGINE_cleanup()" stack to be called during cleanup. */
+
+static void
+engine_list_cleanup(void)
+{
+	ENGINE *iterator = engine_list_head;
+
+	while (iterator != NULL && ENGINE_remove(iterator))
+		iterator = engine_list_head;
+}
+
+/* These static functions starting with a lower case "engine_" always
+ * take place when CRYPTO_LOCK_ENGINE has been locked up. */
+static int
+engine_list_add(ENGINE *e)
+{
+	int conflict = 0;
+	ENGINE *iterator = NULL;
+
+	if (e == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	iterator = engine_list_head;
+	while (iterator && !conflict) {
+		conflict = (strcmp(iterator->id, e->id) == 0);
+		iterator = iterator->next;
+	}
+	if (conflict) {
+		ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
+		    ENGINE_R_CONFLICTING_ENGINE_ID);
+		return 0;
+	}
+	if (engine_list_head == NULL) {
+		/* We are adding to an empty list. */
+		if (engine_list_tail) {
+			ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
+			    ENGINE_R_INTERNAL_LIST_ERROR);
+			return 0;
+		}
+		engine_list_head = e;
+		e->prev = NULL;
+		/* The first time the list allocates, we should register the
+		 * cleanup. */
+		engine_cleanup_add_last(engine_list_cleanup);
+	} else {
+		/* We are adding to the tail of an existing list. */
+		if ((engine_list_tail == NULL) ||
+		    (engine_list_tail->next != NULL)) {
+			ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
+			    ENGINE_R_INTERNAL_LIST_ERROR);
+			return 0;
+		}
+		engine_list_tail->next = e;
+		e->prev = engine_list_tail;
+	}
+	/* Having the engine in the list assumes a structural
+	 * reference. */
+	e->struct_ref++;
+	engine_ref_debug(e, 0, 1)
+	/* However it came to be, e is the last item in the list. */
+	engine_list_tail = e;
+	e->next = NULL;
+	return 1;
+}
+
+static int
+engine_list_remove(ENGINE *e)
+{
+	ENGINE *iterator;
+
+	if (e == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	/* We need to check that e is in our linked list! */
+	iterator = engine_list_head;
+	while (iterator && (iterator != e))
+		iterator = iterator->next;
+	if (iterator == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
+		    ENGINE_R_ENGINE_IS_NOT_IN_LIST);
+		return 0;
+	}
+	/* un-link e from the chain. */
+	if (e->next)
+		e->next->prev = e->prev;
+	if (e->prev)
+		e->prev->next = e->next;
+	/* Correct our head/tail if necessary. */
+	if (engine_list_head == e)
+		engine_list_head = e->next;
+	if (engine_list_tail == e)
+		engine_list_tail = e->prev;
+	engine_free_util(e, 0);
+	return 1;
+}
+
+/* Get the first/last "ENGINE" type available. */
+ENGINE *
+ENGINE_get_first(void)
+{
+	ENGINE *ret;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	ret = engine_list_head;
+	if (ret) {
+		ret->struct_ref++;
+		engine_ref_debug(ret, 0, 1)
+	}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	return ret;
+}
+
+ENGINE *
+ENGINE_get_last(void)
+{
+	ENGINE *ret;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	ret = engine_list_tail;
+	if (ret) {
+		ret->struct_ref++;
+		engine_ref_debug(ret, 0, 1)
+	}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	return ret;
+}
+
+/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
+ENGINE *
+ENGINE_get_next(ENGINE *e)
+{
+	ENGINE *ret = NULL;
+
+	if (e == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_GET_NEXT,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	ret = e->next;
+	if (ret) {
+		/* Return a valid structural refernce to the next ENGINE */
+		ret->struct_ref++;
+		engine_ref_debug(ret, 0, 1)
+	}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	/* Release the structural reference to the previous ENGINE */
+	ENGINE_free(e);
+	return ret;
+}
+
+ENGINE *
+ENGINE_get_prev(ENGINE *e)
+{
+	ENGINE *ret = NULL;
+
+	if (e == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_GET_PREV,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	ret = e->prev;
+	if (ret) {
+		/* Return a valid structural reference to the next ENGINE */
+		ret->struct_ref++;
+		engine_ref_debug(ret, 0, 1)
+	}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	/* Release the structural reference to the previous ENGINE */
+	ENGINE_free(e);
+	return ret;
+}
+
+/* Add another "ENGINE" type into the list. */
+int
+ENGINE_add(ENGINE *e)
+{
+	int to_return = 1;
+
+	if (e == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_ADD,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	if ((e->id == NULL) || (e->name == NULL)) {
+		ENGINEerr(ENGINE_F_ENGINE_ADD,
+		    ENGINE_R_ID_OR_NAME_MISSING);
+	}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	if (!engine_list_add(e)) {
+		ENGINEerr(ENGINE_F_ENGINE_ADD,
+		    ENGINE_R_INTERNAL_LIST_ERROR);
+		to_return = 0;
+	}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	return to_return;
+}
+
+/* Remove an existing "ENGINE" type from the array. */
+int
+ENGINE_remove(ENGINE *e)
+{
+	int to_return = 1;
+
+	if (e == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_REMOVE,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	if (!engine_list_remove(e)) {
+		ENGINEerr(ENGINE_F_ENGINE_REMOVE,
+		    ENGINE_R_INTERNAL_LIST_ERROR);
+		to_return = 0;
+	}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	return to_return;
+}
+
+static void
+engine_cpy(ENGINE *dest, const ENGINE *src)
+{
+	dest->id = src->id;
+	dest->name = src->name;
+#ifndef OPENSSL_NO_RSA
+	dest->rsa_meth = src->rsa_meth;
+#endif
+#ifndef OPENSSL_NO_DSA
+	dest->dsa_meth = src->dsa_meth;
+#endif
+#ifndef OPENSSL_NO_DH
+	dest->dh_meth = src->dh_meth;
+#endif
+#ifndef OPENSSL_NO_ECDH
+	dest->ecdh_meth = src->ecdh_meth;
+#endif
+#ifndef OPENSSL_NO_ECDSA
+	dest->ecdsa_meth = src->ecdsa_meth;
+#endif
+	dest->rand_meth = src->rand_meth;
+	dest->store_meth = src->store_meth;
+	dest->ciphers = src->ciphers;
+	dest->digests = src->digests;
+	dest->pkey_meths = src->pkey_meths;
+	dest->destroy = src->destroy;
+	dest->init = src->init;
+	dest->finish = src->finish;
+	dest->ctrl = src->ctrl;
+	dest->load_privkey = src->load_privkey;
+	dest->load_pubkey = src->load_pubkey;
+	dest->cmd_defns = src->cmd_defns;
+	dest->flags = src->flags;
+}
+
+ENGINE *
+ENGINE_by_id(const char *id)
+{
+	ENGINE *iterator;
+
+	if (id == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_BY_ID,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		return NULL;
+	}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	iterator = engine_list_head;
+	while (iterator && (strcmp(id, iterator->id) != 0))
+		iterator = iterator->next;
+	if (iterator) {
+		/* We need to return a structural reference. If this is an
+		 * ENGINE type that returns copies, make a duplicate - otherwise
+		 * increment the existing ENGINE's reference count. */
+		if (iterator->flags & ENGINE_FLAGS_BY_ID_COPY) {
+			ENGINE *cp = ENGINE_new();
+			if (!cp)
+				iterator = NULL;
+			else {
+				engine_cpy(cp, iterator);
+				iterator = cp;
+			}
+		} else {
+			iterator->struct_ref++;
+			engine_ref_debug(iterator, 0, 1)
+		}
+	}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+
+	if (iterator == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_BY_ID, ENGINE_R_NO_SUCH_ENGINE);
+		ERR_asprintf_error_data("id=%s", id);
+	}
+	return iterator;
+}
+
+int
+ENGINE_up_ref(ENGINE *e)
+{
+	if (e == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_UP_REF, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	CRYPTO_add(&e->struct_ref, 1, CRYPTO_LOCK_ENGINE);
+	return 1;
+}
diff --git a/crypto/libressl/crypto/engine/eng_openssl.c b/crypto/libressl/crypto/engine/eng_openssl.c
new file mode 100644
index 0000000000..d6ebdfa2be
--- /dev/null
+++ b/crypto/libressl/crypto/engine/eng_openssl.c
@@ -0,0 +1,406 @@
+/* $OpenBSD: eng_openssl.c,v 1.11 2015/08/28 01:06:09 beck Exp $ */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_DH
+#include 
+#endif
+#ifndef OPENSSL_NO_DSA
+#include 
+#endif
+#ifndef OPENSSL_NO_RSA
+#include 
+#endif
+
+/* This testing gunk is implemented (and explained) lower down. It also assumes
+ * the application explicitly calls "ENGINE_load_openssl()" because this is no
+ * longer automatic in ENGINE_load_builtin_engines(). */
+#define TEST_ENG_OPENSSL_RC4
+#define TEST_ENG_OPENSSL_PKEY
+/* #define TEST_ENG_OPENSSL_RC4_OTHERS */
+#define TEST_ENG_OPENSSL_RC4_P_INIT
+/* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */
+#define TEST_ENG_OPENSSL_SHA
+/* #define TEST_ENG_OPENSSL_SHA_OTHERS */
+/* #define TEST_ENG_OPENSSL_SHA_P_INIT */
+/* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */
+/* #define TEST_ENG_OPENSSL_SHA_P_FINAL */
+
+/* Now check what of those algorithms are actually enabled */
+#ifdef OPENSSL_NO_RC4
+#undef TEST_ENG_OPENSSL_RC4
+#undef TEST_ENG_OPENSSL_RC4_OTHERS
+#undef TEST_ENG_OPENSSL_RC4_P_INIT
+#undef TEST_ENG_OPENSSL_RC4_P_CIPHER
+#endif
+#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA1)
+#undef TEST_ENG_OPENSSL_SHA
+#undef TEST_ENG_OPENSSL_SHA_OTHERS
+#undef TEST_ENG_OPENSSL_SHA_P_INIT
+#undef TEST_ENG_OPENSSL_SHA_P_UPDATE
+#undef TEST_ENG_OPENSSL_SHA_P_FINAL
+#endif
+
+#ifdef TEST_ENG_OPENSSL_RC4
+static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
+    const int **nids, int nid);
+#endif
+#ifdef TEST_ENG_OPENSSL_SHA
+static int openssl_digests(ENGINE *e, const EVP_MD **digest,
+    const int **nids, int nid);
+#endif
+
+#ifdef TEST_ENG_OPENSSL_PKEY
+static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
+    UI_METHOD *ui_method, void *callback_data);
+#endif
+
+/* The constants used when creating the ENGINE */
+static const char *engine_openssl_id = "openssl";
+static const char *engine_openssl_name = "Software engine support";
+
+/* This internal function is used by ENGINE_openssl() and possibly by the
+ * "dynamic" ENGINE support too */
+static int
+bind_helper(ENGINE *e)
+{
+	if (!ENGINE_set_id(e, engine_openssl_id) ||
+	    !ENGINE_set_name(e, engine_openssl_name)
+#ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS
+#ifndef OPENSSL_NO_RSA
+	    || !ENGINE_set_RSA(e, RSA_get_default_method())
+#endif
+#ifndef OPENSSL_NO_DSA
+	    || !ENGINE_set_DSA(e, DSA_get_default_method())
+#endif
+#ifndef OPENSSL_NO_ECDH
+	    || !ENGINE_set_ECDH(e, ECDH_OpenSSL())
+#endif
+#ifndef OPENSSL_NO_ECDSA
+	    || !ENGINE_set_ECDSA(e, ECDSA_OpenSSL())
+#endif
+#ifndef OPENSSL_NO_DH
+	    || !ENGINE_set_DH(e, DH_get_default_method())
+#endif
+	    || !ENGINE_set_RAND(e, RAND_SSLeay())
+#ifdef TEST_ENG_OPENSSL_RC4
+	    || !ENGINE_set_ciphers(e, openssl_ciphers)
+#endif
+#ifdef TEST_ENG_OPENSSL_SHA
+	    || !ENGINE_set_digests(e, openssl_digests)
+#endif
+#endif
+#ifdef TEST_ENG_OPENSSL_PKEY
+	    || !ENGINE_set_load_privkey_function(e, openssl_load_privkey)
+#endif
+		)
+		return 0;
+	/* If we add errors to this ENGINE, ensure the error handling is setup here */
+	/* openssl_load_error_strings(); */
+	return 1;
+}
+
+static ENGINE *
+engine_openssl(void)
+{
+	ENGINE *ret = ENGINE_new();
+
+	if (!ret)
+		return NULL;
+	if (!bind_helper(ret)) {
+		ENGINE_free(ret);
+		return NULL;
+	}
+	return ret;
+}
+
+void
+ENGINE_load_openssl(void)
+{
+	ENGINE *toadd = engine_openssl();
+
+	if (!toadd)
+		return;
+	(void) ENGINE_add(toadd);
+	/* If the "add" worked, it gets a structural reference. So either way,
+	 * we release our just-created reference. */
+	ENGINE_free(toadd);
+	ERR_clear_error();
+}
+
+/* This stuff is needed if this ENGINE is being compiled into a self-contained
+ * shared-library. */
+#ifdef ENGINE_DYNAMIC_SUPPORT
+static int
+bind_fn(ENGINE *e, const char *id)
+{
+	if (id && (strcmp(id, engine_openssl_id) != 0))
+		return 0;
+	if (!bind_helper(e))
+		return 0;
+	return 1;
+}
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
+#endif /* ENGINE_DYNAMIC_SUPPORT */
+
+#ifdef TEST_ENG_OPENSSL_RC4
+/* This section of code compiles an "alternative implementation" of two modes of
+ * RC4 into this ENGINE. The result is that EVP_CIPHER operation for "rc4"
+ * should under normal circumstances go via this support rather than the default
+ * EVP support. There are other symbols to tweak the testing;
+ *    TEST_ENC_OPENSSL_RC4_OTHERS - print a one line message to stderr each time
+ *        we're asked for a cipher we don't support (should not happen).
+ *    TEST_ENG_OPENSSL_RC4_P_INIT - print a one line message to stderr each time
+ *        the "init_key" handler is called.
+ *    TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler.
+ */
+#include 
+#define TEST_RC4_KEY_SIZE		16
+static int test_cipher_nids[] = {NID_rc4, NID_rc4_40};
+static int test_cipher_nids_number = 2;
+
+typedef struct {
+	unsigned char key[TEST_RC4_KEY_SIZE];
+	RC4_KEY ks;
+} TEST_RC4_KEY;
+
+#define test(ctx) ((TEST_RC4_KEY *)(ctx)->cipher_data)
+static int
+test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+#ifdef TEST_ENG_OPENSSL_RC4_P_INIT
+	fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n");
+#endif
+	memcpy(&test(ctx)->key[0], key, EVP_CIPHER_CTX_key_length(ctx));
+	RC4_set_key(&test(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
+	    test(ctx)->key);
+	return 1;
+}
+
+static int
+test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl)
+{
+#ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER
+	fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n");
+#endif
+	RC4(&test(ctx)->ks, inl, in, out);
+	return 1;
+}
+
+static const EVP_CIPHER test_r4_cipher = {
+	NID_rc4,
+	1, TEST_RC4_KEY_SIZE, 0,
+	EVP_CIPH_VARIABLE_LENGTH,
+	test_rc4_init_key,
+	test_rc4_cipher,
+	NULL,
+	sizeof(TEST_RC4_KEY),
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+static const EVP_CIPHER test_r4_40_cipher = {
+	NID_rc4_40,
+	1,5 /* 40 bit */,0,
+	EVP_CIPH_VARIABLE_LENGTH,
+	test_rc4_init_key,
+	test_rc4_cipher,
+	NULL,
+	sizeof(TEST_RC4_KEY),
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+static int
+openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid)
+{
+	if (!cipher) {
+		/* We are returning a list of supported nids */
+		*nids = test_cipher_nids;
+		return test_cipher_nids_number;
+	}
+	/* We are being asked for a specific cipher */
+	if (nid == NID_rc4)
+		*cipher = &test_r4_cipher;
+	else if (nid == NID_rc4_40)
+		*cipher = &test_r4_40_cipher;
+	else {
+#ifdef TEST_ENG_OPENSSL_RC4_OTHERS
+		fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) returning NULL for "
+		    "nid %d\n", nid);
+#endif
+		*cipher = NULL;
+		return 0;
+	}
+	return 1;
+}
+#endif
+
+#ifdef TEST_ENG_OPENSSL_SHA
+/* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */
+#include 
+static int test_digest_nids[] = {NID_sha1};
+static int test_digest_nids_number = 1;
+
+static int
+test_sha1_init(EVP_MD_CTX *ctx)
+{
+#ifdef TEST_ENG_OPENSSL_SHA_P_INIT
+	fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n");
+#endif
+	return SHA1_Init(ctx->md_data);
+}
+
+static int
+test_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+#ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE
+	fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n");
+#endif
+	return SHA1_Update(ctx->md_data, data, count);
+}
+
+static int
+test_sha1_final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+#ifdef TEST_ENG_OPENSSL_SHA_P_FINAL
+	fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n");
+#endif
+	return SHA1_Final(md, ctx->md_data);
+}
+
+static const EVP_MD test_sha_md = {
+	NID_sha1,
+	NID_sha1WithRSAEncryption,
+	SHA_DIGEST_LENGTH,
+	0,
+	test_sha1_init,
+	test_sha1_update,
+	test_sha1_final,
+	NULL,
+	NULL,
+	EVP_PKEY_RSA_method,
+	SHA_CBLOCK,
+	sizeof(EVP_MD *) + sizeof(SHA_CTX),
+};
+
+static int
+openssl_digests(ENGINE *e, const EVP_MD **digest, const int **nids, int nid)
+{
+	if (!digest) {
+		/* We are returning a list of supported nids */
+		*nids = test_digest_nids;
+		return test_digest_nids_number;
+	}
+	/* We are being asked for a specific digest */
+	if (nid == NID_sha1)
+		*digest = &test_sha_md;
+	else {
+#ifdef TEST_ENG_OPENSSL_SHA_OTHERS
+		fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) returning NULL for "
+		    "nid %d\n", nid);
+#endif
+		*digest = NULL;
+		return 0;
+	}
+	return 1;
+}
+#endif
+
+#ifdef TEST_ENG_OPENSSL_PKEY
+static EVP_PKEY *
+openssl_load_privkey(ENGINE *eng, const char *key_id, UI_METHOD *ui_method,
+    void *callback_data)
+{
+	BIO *in;
+	EVP_PKEY *key;
+
+	fprintf(stderr, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n",
+	    key_id);
+	in = BIO_new_file(key_id, "r");
+	if (!in)
+		return NULL;
+	key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL);
+	BIO_free(in);
+	return key;
+}
+#endif
diff --git a/crypto/libressl/crypto/engine/eng_pkey.c b/crypto/libressl/crypto/engine/eng_pkey.c
new file mode 100644
index 0000000000..b7c8888c86
--- /dev/null
+++ b/crypto/libressl/crypto/engine/eng_pkey.c
@@ -0,0 +1,195 @@
+/* $OpenBSD: eng_pkey.c,v 1.5 2014/06/22 12:05:09 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include "eng_int.h"
+
+/* Basic get/set stuff */
+
+int
+ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f)
+{
+	e->load_privkey = loadpriv_f;
+	return 1;
+}
+
+int
+ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f)
+{
+	e->load_pubkey = loadpub_f;
+	return 1;
+}
+
+int
+ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
+    ENGINE_SSL_CLIENT_CERT_PTR loadssl_f)
+{
+	e->load_ssl_client_cert = loadssl_f;
+	return 1;
+}
+
+ENGINE_LOAD_KEY_PTR
+ENGINE_get_load_privkey_function(const ENGINE *e)
+{
+	return e->load_privkey;
+}
+
+ENGINE_LOAD_KEY_PTR
+ENGINE_get_load_pubkey_function(const ENGINE *e)
+{
+	return e->load_pubkey;
+}
+
+ENGINE_SSL_CLIENT_CERT_PTR
+ENGINE_get_ssl_client_cert_function(const ENGINE *e)
+{
+	return e->load_ssl_client_cert;
+}
+
+/* API functions to load public/private keys */
+
+EVP_PKEY *
+ENGINE_load_private_key(ENGINE *e, const char *key_id, UI_METHOD *ui_method,
+    void *callback_data)
+{
+	EVP_PKEY *pkey;
+
+	if (e == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	if (e->funct_ref == 0) {
+		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
+		    ENGINE_R_NOT_INITIALISED);
+		return 0;
+	}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	if (!e->load_privkey) {
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
+		    ENGINE_R_NO_LOAD_FUNCTION);
+		return 0;
+	}
+	pkey = e->load_privkey(e, key_id, ui_method, callback_data);
+	if (!pkey) {
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
+		    ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
+		return 0;
+	}
+	return pkey;
+}
+
+EVP_PKEY *
+ENGINE_load_public_key(ENGINE *e, const char *key_id, UI_METHOD *ui_method,
+    void *callback_data)
+{
+	EVP_PKEY *pkey;
+
+	if (e == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	if (e->funct_ref == 0) {
+		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
+		    ENGINE_R_NOT_INITIALISED);
+		return 0;
+	}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	if (!e->load_pubkey) {
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
+		    ENGINE_R_NO_LOAD_FUNCTION);
+		return 0;
+	}
+	pkey = e->load_pubkey(e, key_id, ui_method, callback_data);
+	if (!pkey) {
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
+		    ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
+		return 0;
+	}
+	return pkey;
+}
+
+int
+ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s, STACK_OF(X509_NAME) *ca_dn,
+    X509 **pcert, EVP_PKEY **ppkey, STACK_OF(X509) **pother,
+    UI_METHOD *ui_method, void *callback_data)
+{
+	if (e == NULL) {
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	if (e->funct_ref == 0) {
+		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
+		    ENGINE_R_NOT_INITIALISED);
+		return 0;
+	}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	if (!e->load_ssl_client_cert) {
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
+		    ENGINE_R_NO_LOAD_FUNCTION);
+		return 0;
+	}
+	return e->load_ssl_client_cert(e, s, ca_dn, pcert, ppkey, pother,
+	    ui_method, callback_data);
+}
diff --git a/crypto/libressl/crypto/engine/eng_table.c b/crypto/libressl/crypto/engine/eng_table.c
new file mode 100644
index 0000000000..4fd83a00d8
--- /dev/null
+++ b/crypto/libressl/crypto/engine/eng_table.c
@@ -0,0 +1,355 @@
+/* $OpenBSD: eng_table.c,v 1.7 2014/07/11 08:44:48 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include "eng_int.h"
+
+/* The type of the items in the table */
+typedef struct st_engine_pile {
+	/* The 'nid' of this algorithm/mode */
+	int nid;
+	/* ENGINEs that implement this algorithm/mode. */
+	STACK_OF(ENGINE) *sk;
+	/* The default ENGINE to perform this algorithm/mode. */
+	ENGINE *funct;
+	/* Zero if 'sk' is newer than the cached 'funct', non-zero otherwise */
+	int uptodate;
+} ENGINE_PILE;
+
+DECLARE_LHASH_OF(ENGINE_PILE);
+
+/* The type exposed in eng_int.h */
+struct st_engine_table {
+	LHASH_OF(ENGINE_PILE) piles;
+}; /* ENGINE_TABLE */
+
+typedef struct st_engine_pile_doall {
+	engine_table_doall_cb *cb;
+	void *arg;
+} ENGINE_PILE_DOALL;
+
+/* Global flags (ENGINE_TABLE_FLAG_***). */
+static unsigned int table_flags = 0;
+
+/* API function manipulating 'table_flags' */
+unsigned int
+ENGINE_get_table_flags(void)
+{
+	return table_flags;
+}
+
+void
+ENGINE_set_table_flags(unsigned int flags)
+{
+	table_flags = flags;
+}
+
+/* Internal functions for the "piles" hash table */
+static unsigned long
+engine_pile_hash(const ENGINE_PILE *c)
+{
+	return c->nid;
+}
+
+static int
+engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b)
+{
+	return a->nid - b->nid;
+}
+static IMPLEMENT_LHASH_HASH_FN(engine_pile, ENGINE_PILE)
+static IMPLEMENT_LHASH_COMP_FN(engine_pile, ENGINE_PILE)
+
+static int
+int_table_check(ENGINE_TABLE **t, int create)
+{
+	LHASH_OF(ENGINE_PILE) *lh;
+
+	if (*t)
+		return 1;
+	if (!create)
+		return 0;
+	if ((lh = lh_ENGINE_PILE_new()) == NULL)
+		return 0;
+	*t = (ENGINE_TABLE *)lh;
+	return 1;
+}
+
+/* Privately exposed (via eng_int.h) functions for adding and/or removing
+ * ENGINEs from the implementation table */
+int
+engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
+    ENGINE *e, const int *nids, int num_nids, int setdefault)
+{
+	int ret = 0, added = 0;
+	ENGINE_PILE tmplate, *fnd;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	if (!(*table))
+		added = 1;
+	if (!int_table_check(table, 1))
+		goto end;
+	if (added)
+		/* The cleanup callback needs to be added */
+		engine_cleanup_add_first(cleanup);
+	while (num_nids--) {
+		tmplate.nid = *nids;
+		fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
+		if (!fnd) {
+			fnd = malloc(sizeof(ENGINE_PILE));
+			if (!fnd)
+				goto end;
+			fnd->uptodate = 1;
+			fnd->nid = *nids;
+			fnd->sk = sk_ENGINE_new_null();
+			if (!fnd->sk) {
+				free(fnd);
+				goto end;
+			}
+			fnd->funct = NULL;
+			(void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd);
+		}
+		/* A registration shouldn't add duplciate entries */
+		(void)sk_ENGINE_delete_ptr(fnd->sk, e);
+		/* if 'setdefault', this ENGINE goes to the head of the list */
+		if (!sk_ENGINE_push(fnd->sk, e))
+			goto end;
+		/* "touch" this ENGINE_PILE */
+		fnd->uptodate = 0;
+		if (setdefault) {
+			if (!engine_unlocked_init(e)) {
+				ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER,
+				    ENGINE_R_INIT_FAILED);
+				goto end;
+			}
+			if (fnd->funct)
+				engine_unlocked_finish(fnd->funct, 0);
+			fnd->funct = e;
+			fnd->uptodate = 1;
+		}
+		nids++;
+	}
+	ret = 1;
+end:
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	return ret;
+}
+
+static void
+int_unregister_cb_doall_arg(ENGINE_PILE *pile, ENGINE *e)
+{
+	int n;
+
+	/* Iterate the 'c->sk' stack removing any occurance of 'e' */
+	while ((n = sk_ENGINE_find(pile->sk, e)) >= 0) {
+		(void)sk_ENGINE_delete(pile->sk, n);
+		pile->uptodate = 0;
+	}
+	if (pile->funct == e) {
+		engine_unlocked_finish(e, 0);
+		pile->funct = NULL;
+	}
+}
+static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb, ENGINE_PILE, ENGINE)
+
+void
+engine_table_unregister(ENGINE_TABLE **table, ENGINE *e)
+{
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	if (int_table_check(table, 0))
+		lh_ENGINE_PILE_doall_arg(&(*table)->piles,
+		    LHASH_DOALL_ARG_FN(int_unregister_cb), ENGINE, e);
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+}
+
+static void
+int_cleanup_cb_doall(ENGINE_PILE *p)
+{
+	sk_ENGINE_free(p->sk);
+	if (p->funct)
+		engine_unlocked_finish(p->funct, 0);
+	free(p);
+}
+static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb, ENGINE_PILE)
+
+void
+engine_table_cleanup(ENGINE_TABLE **table)
+{
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	if (*table) {
+		lh_ENGINE_PILE_doall(&(*table)->piles,
+		    LHASH_DOALL_FN(int_cleanup_cb));
+		lh_ENGINE_PILE_free(&(*table)->piles);
+		*table = NULL;
+	}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+}
+
+/* return a functional reference for a given 'nid' */
+#ifndef ENGINE_TABLE_DEBUG
+ENGINE *
+engine_table_select(ENGINE_TABLE **table, int nid)
+#else
+ENGINE *
+engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l)
+#endif
+{
+	ENGINE *ret = NULL;
+	ENGINE_PILE tmplate, *fnd = NULL;
+	int initres, loop = 0;
+
+	if (!(*table)) {
+#ifdef ENGINE_TABLE_DEBUG
+		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing "
+		    "registered!\n", f, l, nid);
+#endif
+		return NULL;
+	}
+	ERR_set_mark();
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	/* Check again inside the lock otherwise we could race against cleanup
+	 * operations. But don't worry about a fprintf(stderr). */
+	if (!int_table_check(table, 0))
+		goto end;
+	tmplate.nid = nid;
+	fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
+	if (!fnd)
+		goto end;
+	if (fnd->funct && engine_unlocked_init(fnd->funct)) {
+#ifdef ENGINE_TABLE_DEBUG
+		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
+		    "ENGINE '%s' cached\n", f, l, nid, fnd->funct->id);
+#endif
+		ret = fnd->funct;
+		goto end;
+	}
+	if (fnd->uptodate) {
+		ret = fnd->funct;
+		goto end;
+	}
+trynext:
+	ret = sk_ENGINE_value(fnd->sk, loop++);
+	if (!ret) {
+#ifdef ENGINE_TABLE_DEBUG
+		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no "
+		    "registered implementations would initialise\n", f, l, nid);
+#endif
+		goto end;
+	}
+	/* Try to initialise the ENGINE? */
+	if ((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT))
+		initres = engine_unlocked_init(ret);
+	else
+		initres = 0;
+	if (initres) {
+		/* Update 'funct' */
+		if ((fnd->funct != ret) && engine_unlocked_init(ret)) {
+			/* If there was a previous default we release it. */
+			if (fnd->funct)
+				engine_unlocked_finish(fnd->funct, 0);
+			fnd->funct = ret;
+#ifdef ENGINE_TABLE_DEBUG
+			fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, "
+			    "setting default to '%s'\n", f, l, nid, ret->id);
+#endif
+		}
+#ifdef ENGINE_TABLE_DEBUG
+		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
+		    "newly initialised '%s'\n", f, l, nid, ret->id);
+#endif
+		goto end;
+	}
+	goto trynext;
+end:
+	/* If it failed, it is unlikely to succeed again until some future
+	 * registrations have taken place. In all cases, we cache. */
+	if (fnd)
+		fnd->uptodate = 1;
+#ifdef ENGINE_TABLE_DEBUG
+	if (ret)
+		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
+		    "ENGINE '%s'\n", f, l, nid, ret->id);
+	else
+		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
+		    "'no matching ENGINE'\n", f, l, nid);
+#endif
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	/* Whatever happened, any failed init()s are not failures in this
+	 * context, so clear our error state. */
+	ERR_pop_to_mark();
+	return ret;
+}
+
+/* Table enumeration */
+
+static void
+int_cb_doall_arg(ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall)
+{
+	dall->cb(pile->nid, pile->sk, pile->funct, dall->arg);
+}
+static IMPLEMENT_LHASH_DOALL_ARG_FN(int_cb, ENGINE_PILE, ENGINE_PILE_DOALL)
+
+void
+engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, void *arg)
+{
+	ENGINE_PILE_DOALL dall;
+
+	dall.cb = cb;
+	dall.arg = arg;
+	lh_ENGINE_PILE_doall_arg(&table->piles, LHASH_DOALL_ARG_FN(int_cb),
+	    ENGINE_PILE_DOALL, &dall);
+}
diff --git a/crypto/libressl/crypto/engine/tb_asnmth.c b/crypto/libressl/crypto/engine/tb_asnmth.c
new file mode 100644
index 0000000000..373201429e
--- /dev/null
+++ b/crypto/libressl/crypto/engine/tb_asnmth.c
@@ -0,0 +1,256 @@
+/* $OpenBSD: tb_asnmth.c,v 1.4 2014/07/10 13:58:22 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include "eng_int.h"
+#include "asn1_locl.h"
+#include 
+
+/* If this symbol is defined then ENGINE_get_pkey_asn1_meth_engine(), the
+ * function that is used by EVP to hook in pkey_asn1_meth code and cache
+ * defaults (etc), will display brief debugging summaries to stderr with the
+ * 'nid'. */
+/* #define ENGINE_PKEY_ASN1_METH_DEBUG */
+
+static ENGINE_TABLE *pkey_asn1_meth_table = NULL;
+
+void
+ENGINE_unregister_pkey_asn1_meths(ENGINE *e)
+{
+	engine_table_unregister(&pkey_asn1_meth_table, e);
+}
+
+static void
+engine_unregister_all_pkey_asn1_meths(void)
+{
+	engine_table_cleanup(&pkey_asn1_meth_table);
+}
+
+int
+ENGINE_register_pkey_asn1_meths(ENGINE *e)
+{
+	if (e->pkey_asn1_meths) {
+		const int *nids;
+		int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
+		if (num_nids > 0)
+			return engine_table_register(&pkey_asn1_meth_table,
+			    engine_unregister_all_pkey_asn1_meths, e, nids,
+			    num_nids, 0);
+	}
+	return 1;
+}
+
+void
+ENGINE_register_all_pkey_asn1_meths(void)
+{
+	ENGINE *e;
+
+	for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+		ENGINE_register_pkey_asn1_meths(e);
+}
+
+int
+ENGINE_set_default_pkey_asn1_meths(ENGINE *e)
+{
+	if (e->pkey_asn1_meths) {
+		const int *nids;
+		int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
+		if (num_nids > 0)
+			return engine_table_register(&pkey_asn1_meth_table,
+			    engine_unregister_all_pkey_asn1_meths, e, nids,
+			    num_nids, 1);
+	}
+	return 1;
+}
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references) for a given pkey_asn1_meth 'nid' */
+ENGINE *
+ENGINE_get_pkey_asn1_meth_engine(int nid)
+{
+	return engine_table_select(&pkey_asn1_meth_table, nid);
+}
+
+/* Obtains a pkey_asn1_meth implementation from an ENGINE functional reference */
+const EVP_PKEY_ASN1_METHOD *
+ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid)
+{
+	EVP_PKEY_ASN1_METHOD *ret;
+	ENGINE_PKEY_ASN1_METHS_PTR fn = ENGINE_get_pkey_asn1_meths(e);
+
+	if (!fn || !fn(e, &ret, NULL, nid)) {
+		ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH,
+		    ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
+		return NULL;
+	}
+	return ret;
+}
+
+/* Gets the pkey_asn1_meth callback from an ENGINE structure */
+ENGINE_PKEY_ASN1_METHS_PTR
+ENGINE_get_pkey_asn1_meths(const ENGINE *e)
+{
+	return e->pkey_asn1_meths;
+}
+
+/* Sets the pkey_asn1_meth callback in an ENGINE structure */
+int
+ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f)
+{
+	e->pkey_asn1_meths = f;
+	return 1;
+}
+
+/* Internal function to free up EVP_PKEY_ASN1_METHOD structures before an
+ * ENGINE is destroyed
+ */
+
+void
+engine_pkey_asn1_meths_free(ENGINE *e)
+{
+	int i;
+	EVP_PKEY_ASN1_METHOD *pkm;
+
+	if (e->pkey_asn1_meths) {
+		const int *pknids;
+		int npknids;
+		npknids = e->pkey_asn1_meths(e, NULL, &pknids, 0);
+		for (i = 0; i < npknids; i++) {
+			if (e->pkey_asn1_meths(e, &pkm, NULL, pknids[i])) {
+				EVP_PKEY_asn1_free(pkm);
+			}
+		}
+	}
+}
+
+/* Find a method based on a string. This does a linear search through
+ * all implemented algorithms. This is OK in practice because only
+ * a small number of algorithms are likely to be implemented in an engine
+ * and it is not used for speed critical operations.
+ */
+
+const EVP_PKEY_ASN1_METHOD *
+ENGINE_get_pkey_asn1_meth_str(ENGINE *e, const char *str, int len)
+{
+	int i, nidcount;
+	const int *nids;
+	EVP_PKEY_ASN1_METHOD *ameth;
+
+	if (!e->pkey_asn1_meths)
+		return NULL;
+	if (len == -1)
+		len = strlen(str);
+	nidcount = e->pkey_asn1_meths(e, NULL, &nids, 0);
+	for (i = 0; i < nidcount; i++) {
+		e->pkey_asn1_meths(e, &ameth, NULL, nids[i]);
+		if (((int)strlen(ameth->pem_str) == len) &&
+		    !strncasecmp(ameth->pem_str, str, len))
+			return ameth;
+	}
+	return NULL;
+}
+
+typedef struct {
+	ENGINE *e;
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	const char *str;
+	int len;
+} ENGINE_FIND_STR;
+
+static void
+look_str_cb(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg)
+{
+	ENGINE_FIND_STR *lk = arg;
+	int i;
+
+	if (lk->ameth)
+		return;
+	for (i = 0; i < sk_ENGINE_num(sk); i++) {
+		ENGINE *e = sk_ENGINE_value(sk, i);
+		EVP_PKEY_ASN1_METHOD *ameth;
+		e->pkey_asn1_meths(e, &ameth, NULL, nid);
+		if (((int)strlen(ameth->pem_str) == lk->len) &&
+		    !strncasecmp(ameth->pem_str, lk->str, lk->len)) {
+			lk->e = e;
+			lk->ameth = ameth;
+			return;
+		}
+	}
+}
+
+const EVP_PKEY_ASN1_METHOD *
+ENGINE_pkey_asn1_find_str(ENGINE **pe, const char *str, int len)
+{
+	ENGINE_FIND_STR fstr;
+
+	fstr.e = NULL;
+	fstr.ameth = NULL;
+	fstr.str = str;
+	fstr.len = len;
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr);
+	/* If found obtain a structural reference to engine */
+	if (fstr.e) {
+		fstr.e->struct_ref++;
+		engine_ref_debug(fstr.e, 0, 1)
+	}
+	*pe = fstr.e;
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	return fstr.ameth;
+}
diff --git a/crypto/libressl/crypto/engine/tb_cipher.c b/crypto/libressl/crypto/engine/tb_cipher.c
new file mode 100644
index 0000000000..d446850921
--- /dev/null
+++ b/crypto/libressl/crypto/engine/tb_cipher.c
@@ -0,0 +1,153 @@
+/* $OpenBSD: tb_cipher.c,v 1.6 2014/06/12 15:49:29 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include "eng_int.h"
+
+/* If this symbol is defined then ENGINE_get_cipher_engine(), the function that
+ * is used by EVP to hook in cipher code and cache defaults (etc), will display
+ * brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_CIPHER_DEBUG */
+
+static ENGINE_TABLE *cipher_table = NULL;
+
+void
+ENGINE_unregister_ciphers(ENGINE *e)
+{
+	engine_table_unregister(&cipher_table, e);
+}
+
+static void
+engine_unregister_all_ciphers(void)
+{
+	engine_table_cleanup(&cipher_table);
+}
+
+int
+ENGINE_register_ciphers(ENGINE *e)
+{
+	if (e->ciphers) {
+		const int *nids;
+		int num_nids = e->ciphers(e, NULL, &nids, 0);
+		if (num_nids > 0)
+			return engine_table_register(&cipher_table,
+			    engine_unregister_all_ciphers, e, nids,
+			    num_nids, 0);
+	}
+	return 1;
+}
+
+void
+ENGINE_register_all_ciphers(void)
+{
+	ENGINE *e;
+
+	for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+		ENGINE_register_ciphers(e);
+}
+
+int
+ENGINE_set_default_ciphers(ENGINE *e)
+{
+	if (e->ciphers) {
+		const int *nids;
+		int num_nids = e->ciphers(e, NULL, &nids, 0);
+		if (num_nids > 0)
+			return engine_table_register(&cipher_table,
+			    engine_unregister_all_ciphers, e, nids,
+			    num_nids, 1);
+	}
+	return 1;
+}
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references) for a given cipher 'nid' */
+ENGINE *
+ENGINE_get_cipher_engine(int nid)
+{
+	return engine_table_select(&cipher_table, nid);
+}
+
+/* Obtains a cipher implementation from an ENGINE functional reference */
+const EVP_CIPHER *
+ENGINE_get_cipher(ENGINE *e, int nid)
+{
+	const EVP_CIPHER *ret;
+	ENGINE_CIPHERS_PTR fn = ENGINE_get_ciphers(e);
+
+	if (!fn || !fn(e, &ret, NULL, nid)) {
+		ENGINEerr(ENGINE_F_ENGINE_GET_CIPHER,
+		    ENGINE_R_UNIMPLEMENTED_CIPHER);
+		return NULL;
+	}
+	return ret;
+}
+
+/* Gets the cipher callback from an ENGINE structure */
+ENGINE_CIPHERS_PTR
+ENGINE_get_ciphers(const ENGINE *e)
+{
+	return e->ciphers;
+}
+
+/* Sets the cipher callback in an ENGINE structure */
+int
+ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f)
+{
+	e->ciphers = f;
+	return 1;
+}
diff --git a/crypto/libressl/crypto/engine/tb_dh.c b/crypto/libressl/crypto/engine/tb_dh.c
new file mode 100644
index 0000000000..e0866e5f6a
--- /dev/null
+++ b/crypto/libressl/crypto/engine/tb_dh.c
@@ -0,0 +1,127 @@
+/* $OpenBSD$ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+/* If this symbol is defined then ENGINE_get_default_DH(), the function that is
+ * used by DH to hook in implementation code and cache defaults (etc), will
+ * display brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_DH_DEBUG */
+
+static ENGINE_TABLE *dh_table = NULL;
+static const int dummy_nid = 1;
+
+void
+ENGINE_unregister_DH(ENGINE *e)
+{
+	engine_table_unregister(&dh_table, e);
+}
+
+static void
+engine_unregister_all_DH(void)
+{
+	engine_table_cleanup(&dh_table);
+}
+
+int
+ENGINE_register_DH(ENGINE *e)
+{
+	if (e->dh_meth)
+		return engine_table_register(&dh_table,
+		    engine_unregister_all_DH, e, &dummy_nid, 1, 0);
+	return 1;
+}
+
+void
+ENGINE_register_all_DH(void)
+{
+	ENGINE *e;
+
+	for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+		ENGINE_register_DH(e);
+}
+
+int
+ENGINE_set_default_DH(ENGINE *e)
+{
+	if (e->dh_meth)
+		return engine_table_register(&dh_table,
+		    engine_unregister_all_DH, e, &dummy_nid, 1, 1);
+	return 1;
+}
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references). */
+ENGINE *
+ENGINE_get_default_DH(void)
+{
+	return engine_table_select(&dh_table, dummy_nid);
+}
+
+/* Obtains an DH implementation from an ENGINE functional reference */
+const DH_METHOD *
+ENGINE_get_DH(const ENGINE *e)
+{
+	return e->dh_meth;
+}
+
+/* Sets an DH implementation in an ENGINE structure */
+int
+ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth)
+{
+	e->dh_meth = dh_meth;
+	return 1;
+}
diff --git a/crypto/libressl/crypto/engine/tb_digest.c b/crypto/libressl/crypto/engine/tb_digest.c
new file mode 100644
index 0000000000..67f8b28ca9
--- /dev/null
+++ b/crypto/libressl/crypto/engine/tb_digest.c
@@ -0,0 +1,153 @@
+/* $OpenBSD: tb_digest.c,v 1.6 2014/06/12 15:49:29 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include "eng_int.h"
+
+/* If this symbol is defined then ENGINE_get_digest_engine(), the function that
+ * is used by EVP to hook in digest code and cache defaults (etc), will display
+ * brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_DIGEST_DEBUG */
+
+static ENGINE_TABLE *digest_table = NULL;
+
+void
+ENGINE_unregister_digests(ENGINE *e)
+{
+	engine_table_unregister(&digest_table, e);
+}
+
+static void
+engine_unregister_all_digests(void)
+{
+	engine_table_cleanup(&digest_table);
+}
+
+int
+ENGINE_register_digests(ENGINE *e)
+{
+	if (e->digests) {
+		const int *nids;
+		int num_nids = e->digests(e, NULL, &nids, 0);
+		if (num_nids > 0)
+			return engine_table_register(&digest_table,
+			    engine_unregister_all_digests, e, nids,
+			    num_nids, 0);
+	}
+	return 1;
+}
+
+void
+ENGINE_register_all_digests(void)
+{
+	ENGINE *e;
+
+	for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+		ENGINE_register_digests(e);
+}
+
+int
+ENGINE_set_default_digests(ENGINE *e)
+{
+	if (e->digests) {
+		const int *nids;
+		int num_nids = e->digests(e, NULL, &nids, 0);
+		if (num_nids > 0)
+			return engine_table_register(&digest_table,
+			    engine_unregister_all_digests, e, nids,
+			    num_nids, 1);
+	}
+	return 1;
+}
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references) for a given digest 'nid' */
+ENGINE *
+ENGINE_get_digest_engine(int nid)
+{
+	return engine_table_select(&digest_table, nid);
+}
+
+/* Obtains a digest implementation from an ENGINE functional reference */
+const EVP_MD *
+ENGINE_get_digest(ENGINE *e, int nid)
+{
+	const EVP_MD *ret;
+	ENGINE_DIGESTS_PTR fn = ENGINE_get_digests(e);
+
+	if (!fn || !fn(e, &ret, NULL, nid)) {
+		ENGINEerr(ENGINE_F_ENGINE_GET_DIGEST,
+		    ENGINE_R_UNIMPLEMENTED_DIGEST);
+		return NULL;
+	}
+	return ret;
+}
+
+/* Gets the digest callback from an ENGINE structure */
+ENGINE_DIGESTS_PTR
+ENGINE_get_digests(const ENGINE *e)
+{
+	return e->digests;
+}
+
+/* Sets the digest callback in an ENGINE structure */
+int
+ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f)
+{
+	e->digests = f;
+	return 1;
+}
diff --git a/crypto/libressl/crypto/engine/tb_dsa.c b/crypto/libressl/crypto/engine/tb_dsa.c
new file mode 100644
index 0000000000..e5afcd6d33
--- /dev/null
+++ b/crypto/libressl/crypto/engine/tb_dsa.c
@@ -0,0 +1,127 @@
+/* $OpenBSD$ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+/* If this symbol is defined then ENGINE_get_default_DSA(), the function that is
+ * used by DSA to hook in implementation code and cache defaults (etc), will
+ * display brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_DSA_DEBUG */
+
+static ENGINE_TABLE *dsa_table = NULL;
+static const int dummy_nid = 1;
+
+void
+ENGINE_unregister_DSA(ENGINE *e)
+{
+	engine_table_unregister(&dsa_table, e);
+}
+
+static void
+engine_unregister_all_DSA(void)
+{
+	engine_table_cleanup(&dsa_table);
+}
+
+int
+ENGINE_register_DSA(ENGINE *e)
+{
+	if (e->dsa_meth)
+		return engine_table_register(&dsa_table,
+		    engine_unregister_all_DSA, e, &dummy_nid, 1, 0);
+	return 1;
+}
+
+void
+ENGINE_register_all_DSA(void)
+{
+	ENGINE *e;
+
+	for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+		ENGINE_register_DSA(e);
+}
+
+int
+ENGINE_set_default_DSA(ENGINE *e)
+{
+	if (e->dsa_meth)
+		return engine_table_register(&dsa_table,
+		    engine_unregister_all_DSA, e, &dummy_nid, 1, 1);
+	return 1;
+}
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references). */
+ENGINE *
+ENGINE_get_default_DSA(void)
+{
+	return engine_table_select(&dsa_table, dummy_nid);
+}
+
+/* Obtains an DSA implementation from an ENGINE functional reference */
+const DSA_METHOD *
+ENGINE_get_DSA(const ENGINE *e)
+{
+	return e->dsa_meth;
+}
+
+/* Sets an DSA implementation in an ENGINE structure */
+int
+ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth)
+{
+	e->dsa_meth = dsa_meth;
+	return 1;
+}
diff --git a/crypto/libressl/crypto/engine/tb_ecdh.c b/crypto/libressl/crypto/engine/tb_ecdh.c
new file mode 100644
index 0000000000..acd9c295f9
--- /dev/null
+++ b/crypto/libressl/crypto/engine/tb_ecdh.c
@@ -0,0 +1,141 @@
+/* $OpenBSD$ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The ECDH engine software is originally written by Nils Gura and
+ * Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+/* If this symbol is defined then ENGINE_get_default_ECDH(), the function that is
+ * used by ECDH to hook in implementation code and cache defaults (etc), will
+ * display brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_ECDH_DEBUG */
+
+static ENGINE_TABLE *ecdh_table = NULL;
+static const int dummy_nid = 1;
+
+void
+ENGINE_unregister_ECDH(ENGINE *e)
+{
+	engine_table_unregister(&ecdh_table, e);
+}
+
+static void
+engine_unregister_all_ECDH(void)
+{
+	engine_table_cleanup(&ecdh_table);
+}
+
+int
+ENGINE_register_ECDH(ENGINE *e)
+{
+	if (e->ecdh_meth)
+		return engine_table_register(&ecdh_table,
+		    engine_unregister_all_ECDH, e, &dummy_nid, 1, 0);
+	return 1;
+}
+
+void
+ENGINE_register_all_ECDH(void)
+{
+	ENGINE *e;
+
+	for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+		ENGINE_register_ECDH(e);
+}
+
+int
+ENGINE_set_default_ECDH(ENGINE *e)
+{
+	if (e->ecdh_meth)
+		return engine_table_register(&ecdh_table,
+		    engine_unregister_all_ECDH, e, &dummy_nid, 1, 1);
+	return 1;
+}
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references). */
+ENGINE *
+ENGINE_get_default_ECDH(void)
+{
+	return engine_table_select(&ecdh_table, dummy_nid);
+}
+
+/* Obtains an ECDH implementation from an ENGINE functional reference */
+const ECDH_METHOD *
+ENGINE_get_ECDH(const ENGINE *e)
+{
+	return e->ecdh_meth;
+}
+
+/* Sets an ECDH implementation in an ENGINE structure */
+int
+ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth)
+{
+	e->ecdh_meth = ecdh_meth;
+	return 1;
+}
diff --git a/crypto/libressl/crypto/engine/tb_ecdsa.c b/crypto/libressl/crypto/engine/tb_ecdsa.c
new file mode 100644
index 0000000000..260eaa0841
--- /dev/null
+++ b/crypto/libressl/crypto/engine/tb_ecdsa.c
@@ -0,0 +1,127 @@
+/* $OpenBSD$ */
+/* ====================================================================
+ * Copyright (c) 2000-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+/* If this symbol is defined then ENGINE_get_default_ECDSA(), the function that is
+ * used by ECDSA to hook in implementation code and cache defaults (etc), will
+ * display brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_ECDSA_DEBUG */
+
+static ENGINE_TABLE *ecdsa_table = NULL;
+static const int dummy_nid = 1;
+
+void
+ENGINE_unregister_ECDSA(ENGINE *e)
+{
+	engine_table_unregister(&ecdsa_table, e);
+}
+
+static void
+engine_unregister_all_ECDSA(void)
+{
+	engine_table_cleanup(&ecdsa_table);
+}
+
+int
+ENGINE_register_ECDSA(ENGINE *e)
+{
+	if (e->ecdsa_meth)
+		return engine_table_register(&ecdsa_table,
+		    engine_unregister_all_ECDSA, e, &dummy_nid, 1, 0);
+	return 1;
+}
+
+void
+ENGINE_register_all_ECDSA(void)
+{
+	ENGINE *e;
+
+	for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+		ENGINE_register_ECDSA(e);
+}
+
+int
+ENGINE_set_default_ECDSA(ENGINE *e)
+{
+	if (e->ecdsa_meth)
+		return engine_table_register(&ecdsa_table,
+		    engine_unregister_all_ECDSA, e, &dummy_nid, 1, 1);
+	return 1;
+}
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references). */
+ENGINE *
+ENGINE_get_default_ECDSA(void)
+{
+	return engine_table_select(&ecdsa_table, dummy_nid);
+}
+
+/* Obtains an ECDSA implementation from an ENGINE functional reference */
+const ECDSA_METHOD *
+ENGINE_get_ECDSA(const ENGINE *e)
+{
+	return e->ecdsa_meth;
+}
+
+/* Sets an ECDSA implementation in an ENGINE structure */
+int
+ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth)
+{
+	e->ecdsa_meth = ecdsa_meth;
+	return 1;
+}
diff --git a/crypto/libressl/crypto/engine/tb_pkmeth.c b/crypto/libressl/crypto/engine/tb_pkmeth.c
new file mode 100644
index 0000000000..3722e3101d
--- /dev/null
+++ b/crypto/libressl/crypto/engine/tb_pkmeth.c
@@ -0,0 +1,176 @@
+/* $OpenBSD: tb_pkmeth.c,v 1.4 2014/06/12 15:49:29 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include "eng_int.h"
+#include 
+
+/* If this symbol is defined then ENGINE_get_pkey_meth_engine(), the function
+ * that is used by EVP to hook in pkey_meth code and cache defaults (etc), will
+ * display brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_PKEY_METH_DEBUG */
+
+static ENGINE_TABLE *pkey_meth_table = NULL;
+
+void
+ENGINE_unregister_pkey_meths(ENGINE *e)
+{
+	engine_table_unregister(&pkey_meth_table, e);
+}
+
+static void
+engine_unregister_all_pkey_meths(void)
+{
+	engine_table_cleanup(&pkey_meth_table);
+}
+
+int
+ENGINE_register_pkey_meths(ENGINE *e)
+{
+	if (e->pkey_meths) {
+		const int *nids;
+		int num_nids = e->pkey_meths(e, NULL, &nids, 0);
+		if (num_nids > 0)
+			return engine_table_register(&pkey_meth_table,
+			    engine_unregister_all_pkey_meths, e, nids,
+			    num_nids, 0);
+	}
+	return 1;
+}
+
+void
+ENGINE_register_all_pkey_meths(void)
+{
+	ENGINE *e;
+
+	for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+		ENGINE_register_pkey_meths(e);
+}
+
+int
+ENGINE_set_default_pkey_meths(ENGINE *e)
+{
+	if (e->pkey_meths) {
+		const int *nids;
+		int num_nids = e->pkey_meths(e, NULL, &nids, 0);
+		if (num_nids > 0)
+			return engine_table_register(&pkey_meth_table,
+			    engine_unregister_all_pkey_meths, e, nids,
+			    num_nids, 1);
+	}
+	return 1;
+}
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references) for a given pkey_meth 'nid' */
+ENGINE *
+ENGINE_get_pkey_meth_engine(int nid)
+{
+	return engine_table_select(&pkey_meth_table, nid);
+}
+
+/* Obtains a pkey_meth implementation from an ENGINE functional reference */
+const EVP_PKEY_METHOD *
+ENGINE_get_pkey_meth(ENGINE *e, int nid)
+{
+	EVP_PKEY_METHOD *ret;
+	ENGINE_PKEY_METHS_PTR fn = ENGINE_get_pkey_meths(e);
+
+	if (!fn || !fn(e, &ret, NULL, nid)) {
+		ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_METH,
+		    ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
+		return NULL;
+	}
+	return ret;
+}
+
+/* Gets the pkey_meth callback from an ENGINE structure */
+ENGINE_PKEY_METHS_PTR
+ENGINE_get_pkey_meths(const ENGINE *e)
+{
+	return e->pkey_meths;
+}
+
+/* Sets the pkey_meth callback in an ENGINE structure */
+int
+ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f)
+{
+	e->pkey_meths = f;
+	return 1;
+}
+
+/* Internal function to free up EVP_PKEY_METHOD structures before an
+ * ENGINE is destroyed
+ */
+
+void
+engine_pkey_meths_free(ENGINE *e)
+{
+	int i;
+	EVP_PKEY_METHOD *pkm;
+
+	if (e->pkey_meths) {
+		const int *pknids;
+		int npknids;
+		npknids = e->pkey_meths(e, NULL, &pknids, 0);
+		for (i = 0; i < npknids; i++) {
+			if (e->pkey_meths(e, &pkm, NULL, pknids[i])) {
+				EVP_PKEY_meth_free(pkm);
+			}
+		}
+	}
+}
diff --git a/crypto/libressl/crypto/engine/tb_rand.c b/crypto/libressl/crypto/engine/tb_rand.c
new file mode 100644
index 0000000000..cbd201596a
--- /dev/null
+++ b/crypto/libressl/crypto/engine/tb_rand.c
@@ -0,0 +1,127 @@
+/* $OpenBSD$ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+/* If this symbol is defined then ENGINE_get_default_RAND(), the function that is
+ * used by RAND to hook in implementation code and cache defaults (etc), will
+ * display brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_RAND_DEBUG */
+
+static ENGINE_TABLE *rand_table = NULL;
+static const int dummy_nid = 1;
+
+void
+ENGINE_unregister_RAND(ENGINE *e)
+{
+	engine_table_unregister(&rand_table, e);
+}
+
+static void
+engine_unregister_all_RAND(void)
+{
+	engine_table_cleanup(&rand_table);
+}
+
+int
+ENGINE_register_RAND(ENGINE *e)
+{
+	if (e->rand_meth)
+		return engine_table_register(&rand_table,
+		    engine_unregister_all_RAND, e, &dummy_nid, 1, 0);
+	return 1;
+}
+
+void
+ENGINE_register_all_RAND(void)
+{
+	ENGINE *e;
+
+	for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+		ENGINE_register_RAND(e);
+}
+
+int
+ENGINE_set_default_RAND(ENGINE *e)
+{
+	if (e->rand_meth)
+		return engine_table_register(&rand_table,
+		    engine_unregister_all_RAND, e, &dummy_nid, 1, 1);
+	return 1;
+}
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references). */
+ENGINE *
+ENGINE_get_default_RAND(void)
+{
+	return engine_table_select(&rand_table, dummy_nid);
+}
+
+/* Obtains an RAND implementation from an ENGINE functional reference */
+const RAND_METHOD *
+ENGINE_get_RAND(const ENGINE *e)
+{
+	return e->rand_meth;
+}
+
+/* Sets an RAND implementation in an ENGINE structure */
+int
+ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth)
+{
+	e->rand_meth = rand_meth;
+	return 1;
+}
diff --git a/crypto/libressl/crypto/engine/tb_rsa.c b/crypto/libressl/crypto/engine/tb_rsa.c
new file mode 100644
index 0000000000..390d7e9b58
--- /dev/null
+++ b/crypto/libressl/crypto/engine/tb_rsa.c
@@ -0,0 +1,127 @@
+/* $OpenBSD$ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+/* If this symbol is defined then ENGINE_get_default_RSA(), the function that is
+ * used by RSA to hook in implementation code and cache defaults (etc), will
+ * display brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_RSA_DEBUG */
+
+static ENGINE_TABLE *rsa_table = NULL;
+static const int dummy_nid = 1;
+
+void
+ENGINE_unregister_RSA(ENGINE *e)
+{
+	engine_table_unregister(&rsa_table, e);
+}
+
+static void
+engine_unregister_all_RSA(void)
+{
+	engine_table_cleanup(&rsa_table);
+}
+
+int
+ENGINE_register_RSA(ENGINE *e)
+{
+	if (e->rsa_meth)
+		return engine_table_register(&rsa_table,
+		    engine_unregister_all_RSA, e, &dummy_nid, 1, 0);
+	return 1;
+}
+
+void
+ENGINE_register_all_RSA(void)
+{
+	ENGINE *e;
+
+	for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+		ENGINE_register_RSA(e);
+}
+
+int
+ENGINE_set_default_RSA(ENGINE *e)
+{
+	if (e->rsa_meth)
+		return engine_table_register(&rsa_table,
+		    engine_unregister_all_RSA, e, &dummy_nid, 1, 1);
+	return 1;
+}
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references). */
+ENGINE *
+ENGINE_get_default_RSA(void)
+{
+	return engine_table_select(&rsa_table, dummy_nid);
+}
+
+/* Obtains an RSA implementation from an ENGINE functional reference */
+const RSA_METHOD *
+ENGINE_get_RSA(const ENGINE *e)
+{
+	return e->rsa_meth;
+}
+
+/* Sets an RSA implementation in an ENGINE structure */
+int
+ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth)
+{
+	e->rsa_meth = rsa_meth;
+	return 1;
+}
diff --git a/crypto/libressl/crypto/engine/tb_store.c b/crypto/libressl/crypto/engine/tb_store.c
new file mode 100644
index 0000000000..c49e243f0f
--- /dev/null
+++ b/crypto/libressl/crypto/engine/tb_store.c
@@ -0,0 +1,109 @@
+/* $OpenBSD: tb_store.c,v 1.4 2014/06/12 15:49:29 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+/* If this symbol is defined then ENGINE_get_default_STORE(), the function that is
+ * used by STORE to hook in implementation code and cache defaults (etc), will
+ * display brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_STORE_DEBUG */
+
+static ENGINE_TABLE *store_table = NULL;
+static const int dummy_nid = 1;
+
+void
+ENGINE_unregister_STORE(ENGINE *e)
+{
+	engine_table_unregister(&store_table, e);
+}
+
+static void
+engine_unregister_all_STORE(void)
+{
+	engine_table_cleanup(&store_table);
+}
+
+int
+ENGINE_register_STORE(ENGINE *e)
+{
+	if (e->store_meth)
+		return engine_table_register(&store_table,
+		    engine_unregister_all_STORE, e, &dummy_nid, 1, 0);
+	return 1;
+}
+
+void
+ENGINE_register_all_STORE(void)
+{
+	ENGINE *e;
+
+	for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+		ENGINE_register_STORE(e);
+}
+
+/* Obtains an STORE implementation from an ENGINE functional reference */
+const STORE_METHOD *
+ENGINE_get_STORE(const ENGINE *e)
+{
+	return e->store_meth;
+}
+
+/* Sets an STORE implementation in an ENGINE structure */
+int
+ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth)
+{
+	e->store_meth = store_meth;
+	return 1;
+}
diff --git a/crypto/libressl/crypto/err/err.c b/crypto/libressl/crypto/err/err.c
new file mode 100644
index 0000000000..387c974a66
--- /dev/null
+++ b/crypto/libressl/crypto/err/err.c
@@ -0,0 +1,1156 @@
+/* $OpenBSD: err.c,v 1.40 2014/10/05 15:21:48 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+DECLARE_LHASH_OF(ERR_STRING_DATA);
+DECLARE_LHASH_OF(ERR_STATE);
+
+static void err_load_strings(int lib, ERR_STRING_DATA *str);
+
+static void ERR_STATE_free(ERR_STATE *s);
+#ifndef OPENSSL_NO_ERR
+static ERR_STRING_DATA ERR_str_libraries[] = {
+	{ERR_PACK(ERR_LIB_NONE,0,0),		"unknown library"},
+	{ERR_PACK(ERR_LIB_SYS,0,0),		"system library"},
+	{ERR_PACK(ERR_LIB_BN,0,0),		"bignum routines"},
+	{ERR_PACK(ERR_LIB_RSA,0,0),		"rsa routines"},
+	{ERR_PACK(ERR_LIB_DH,0,0),		"Diffie-Hellman routines"},
+	{ERR_PACK(ERR_LIB_EVP,0,0),		"digital envelope routines"},
+	{ERR_PACK(ERR_LIB_BUF,0,0),		"memory buffer routines"},
+	{ERR_PACK(ERR_LIB_OBJ,0,0),		"object identifier routines"},
+	{ERR_PACK(ERR_LIB_PEM,0,0),		"PEM routines"},
+	{ERR_PACK(ERR_LIB_DSA,0,0),		"dsa routines"},
+	{ERR_PACK(ERR_LIB_X509,0,0),		"x509 certificate routines"},
+	{ERR_PACK(ERR_LIB_ASN1,0,0),		"asn1 encoding routines"},
+	{ERR_PACK(ERR_LIB_CONF,0,0),		"configuration file routines"},
+	{ERR_PACK(ERR_LIB_CRYPTO,0,0),		"common libcrypto routines"},
+	{ERR_PACK(ERR_LIB_EC,0,0),		"elliptic curve routines"},
+	{ERR_PACK(ERR_LIB_SSL,0,0),		"SSL routines"},
+	{ERR_PACK(ERR_LIB_BIO,0,0),		"BIO routines"},
+	{ERR_PACK(ERR_LIB_PKCS7,0,0),		"PKCS7 routines"},
+	{ERR_PACK(ERR_LIB_X509V3,0,0),		"X509 V3 routines"},
+	{ERR_PACK(ERR_LIB_PKCS12,0,0),		"PKCS12 routines"},
+	{ERR_PACK(ERR_LIB_RAND,0,0),		"random number generator"},
+	{ERR_PACK(ERR_LIB_DSO,0,0),		"DSO support routines"},
+	{ERR_PACK(ERR_LIB_TS,0,0),		"time stamp routines"},
+	{ERR_PACK(ERR_LIB_ENGINE,0,0),		"engine routines"},
+	{ERR_PACK(ERR_LIB_OCSP,0,0),		"OCSP routines"},
+	{ERR_PACK(ERR_LIB_FIPS,0,0),		"FIPS routines"},
+	{ERR_PACK(ERR_LIB_CMS,0,0),		"CMS routines"},
+	{ERR_PACK(ERR_LIB_HMAC,0,0),		"HMAC routines"},
+	{ERR_PACK(ERR_LIB_GOST,0,0),		"GOST routines"},
+	{0, NULL},
+};
+
+static ERR_STRING_DATA ERR_str_functs[] = {
+	{ERR_PACK(0,SYS_F_FOPEN, 0),     	"fopen"},
+	{ERR_PACK(0,SYS_F_CONNECT, 0),		"connect"},
+	{ERR_PACK(0,SYS_F_GETSERVBYNAME, 0),	"getservbyname"},
+	{ERR_PACK(0,SYS_F_SOCKET, 0),		"socket"},
+	{ERR_PACK(0,SYS_F_IOCTLSOCKET, 0),	"ioctl"},
+	{ERR_PACK(0,SYS_F_BIND, 0),		"bind"},
+	{ERR_PACK(0,SYS_F_LISTEN, 0),		"listen"},
+	{ERR_PACK(0,SYS_F_ACCEPT, 0),		"accept"},
+	{ERR_PACK(0,SYS_F_OPENDIR, 0),		"opendir"},
+	{ERR_PACK(0,SYS_F_FREAD, 0),		"fread"},
+	{0, NULL},
+};
+
+static ERR_STRING_DATA ERR_str_reasons[] = {
+	{ERR_R_SYS_LIB,				"system lib"},
+	{ERR_R_BN_LIB,				"BN lib"},
+	{ERR_R_RSA_LIB,				"RSA lib"},
+	{ERR_R_DH_LIB,				"DH lib"},
+	{ERR_R_EVP_LIB,				"EVP lib"},
+	{ERR_R_BUF_LIB,				"BUF lib"},
+	{ERR_R_OBJ_LIB,				"OBJ lib"},
+	{ERR_R_PEM_LIB,				"PEM lib"},
+	{ERR_R_DSA_LIB,				"DSA lib"},
+	{ERR_R_X509_LIB,			"X509 lib"},
+	{ERR_R_ASN1_LIB,			"ASN1 lib"},
+	{ERR_R_CONF_LIB,			"CONF lib"},
+	{ERR_R_CRYPTO_LIB,			"CRYPTO lib"},
+	{ERR_R_EC_LIB,				"EC lib"},
+	{ERR_R_SSL_LIB,				"SSL lib"},
+	{ERR_R_BIO_LIB,				"BIO lib"},
+	{ERR_R_PKCS7_LIB,			"PKCS7 lib"},
+	{ERR_R_X509V3_LIB,			"X509V3 lib"},
+	{ERR_R_PKCS12_LIB,			"PKCS12 lib"},
+	{ERR_R_RAND_LIB,			"RAND lib"},
+	{ERR_R_DSO_LIB,				"DSO lib"},
+	{ERR_R_ENGINE_LIB,			"ENGINE lib"},
+	{ERR_R_OCSP_LIB,			"OCSP lib"},
+	{ERR_R_TS_LIB,				"TS lib"},
+
+	{ERR_R_NESTED_ASN1_ERROR,		"nested asn1 error"},
+	{ERR_R_BAD_ASN1_OBJECT_HEADER,		"bad asn1 object header"},
+	{ERR_R_BAD_GET_ASN1_OBJECT_CALL,	"bad get asn1 object call"},
+	{ERR_R_EXPECTING_AN_ASN1_SEQUENCE,	"expecting an asn1 sequence"},
+	{ERR_R_ASN1_LENGTH_MISMATCH,		"asn1 length mismatch"},
+	{ERR_R_MISSING_ASN1_EOS,		"missing asn1 eos"},
+
+	{ERR_R_FATAL,				"fatal"},
+	{ERR_R_MALLOC_FAILURE,			"malloc failure"},
+	{ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED,	"called a function you should not call"},
+	{ERR_R_PASSED_NULL_PARAMETER,		"passed a null parameter"},
+	{ERR_R_INTERNAL_ERROR,			"internal error"},
+	{ERR_R_DISABLED	,			"called a function that was disabled at compile-time"},
+
+	{0, NULL},
+};
+#endif
+
+
+/* Define the predeclared (but externally opaque) "ERR_FNS" type */
+struct st_ERR_FNS {
+	/* Works on the "error_hash" string table */
+	LHASH_OF(ERR_STRING_DATA) *(*cb_err_get)(int create);
+	void (*cb_err_del)(void);
+	ERR_STRING_DATA *(*cb_err_get_item)(const ERR_STRING_DATA *);
+	ERR_STRING_DATA *(*cb_err_set_item)(ERR_STRING_DATA *);
+	ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *);
+	/* Works on the "thread_hash" error-state table */
+	LHASH_OF(ERR_STATE) *(*cb_thread_get)(int create);
+	void (*cb_thread_release)(LHASH_OF(ERR_STATE) **hash);
+	ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *);
+	ERR_STATE *(*cb_thread_set_item)(ERR_STATE *);
+	void (*cb_thread_del_item)(const ERR_STATE *);
+	/* Returns the next available error "library" numbers */
+	int (*cb_get_next_lib)(void);
+};
+
+/* Predeclarations of the "err_defaults" functions */
+static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create);
+static void int_err_del(void);
+static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);
+static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *);
+static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *);
+static LHASH_OF(ERR_STATE) *int_thread_get(int create);
+static void int_thread_release(LHASH_OF(ERR_STATE) **hash);
+static ERR_STATE *int_thread_get_item(const ERR_STATE *);
+static ERR_STATE *int_thread_set_item(ERR_STATE *);
+static void int_thread_del_item(const ERR_STATE *);
+static int int_err_get_next_lib(void);
+
+/* The static ERR_FNS table using these defaults functions */
+static const ERR_FNS err_defaults = {
+	int_err_get,
+	int_err_del,
+	int_err_get_item,
+	int_err_set_item,
+	int_err_del_item,
+	int_thread_get,
+	int_thread_release,
+	int_thread_get_item,
+	int_thread_set_item,
+	int_thread_del_item,
+	int_err_get_next_lib
+};
+
+/* The replacable table of ERR_FNS functions we use at run-time */
+static const ERR_FNS *err_fns = NULL;
+
+/* Eg. rather than using "err_get()", use "ERRFN(err_get)()". */
+#define ERRFN(a) err_fns->cb_##a
+
+/* The internal state used by "err_defaults" - as such, the setting, reading,
+ * creating, and deleting of this data should only be permitted via the
+ * "err_defaults" functions. This way, a linked module can completely defer all
+ * ERR state operation (together with requisite locking) to the implementations
+ * and state in the loading application. */
+static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL;
+static LHASH_OF(ERR_STATE) *int_thread_hash = NULL;
+static int int_thread_hash_references = 0;
+static int int_err_library_number = ERR_LIB_USER;
+
+/* Internal function that checks whether "err_fns" is set and if not, sets it to
+ * the defaults. */
+static void
+err_fns_check(void)
+{
+	if (err_fns)
+		return;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	if (!err_fns)
+		err_fns = &err_defaults;
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+}
+
+/* API functions to get or set the underlying ERR functions. */
+
+const ERR_FNS *
+ERR_get_implementation(void)
+{
+	err_fns_check();
+	return err_fns;
+}
+
+int
+ERR_set_implementation(const ERR_FNS *fns)
+{
+	int ret = 0;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	/* It's too late if 'err_fns' is non-NULL. BTW: not much point setting
+	 * an error is there?! */
+	if (!err_fns) {
+		err_fns = fns;
+		ret = 1;
+	}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+	return ret;
+}
+
+/* These are the callbacks provided to "lh_new()" when creating the LHASH tables
+ * internal to the "err_defaults" implementation. */
+
+static unsigned long get_error_values(int inc, int top, const char **file,
+    int *line, const char **data, int *flags);
+
+/* The internal functions used in the "err_defaults" implementation */
+
+static unsigned long
+err_string_data_hash(const ERR_STRING_DATA *a)
+{
+	unsigned long ret, l;
+
+	l = a->error;
+	ret = l^ERR_GET_LIB(l)^ERR_GET_FUNC(l);
+	return (ret^ret % 19*13);
+}
+static IMPLEMENT_LHASH_HASH_FN(err_string_data, ERR_STRING_DATA)
+
+static int
+err_string_data_cmp(const ERR_STRING_DATA *a, const ERR_STRING_DATA *b)
+{
+	return (int)(a->error - b->error);
+}
+static IMPLEMENT_LHASH_COMP_FN(err_string_data, ERR_STRING_DATA)
+
+static
+LHASH_OF(ERR_STRING_DATA) *int_err_get(int create)
+{
+	LHASH_OF(ERR_STRING_DATA) *ret = NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	if (!int_error_hash && create) {
+		CRYPTO_push_info("int_err_get (err.c)");
+		int_error_hash = lh_ERR_STRING_DATA_new();
+		CRYPTO_pop_info();
+	}
+	if (int_error_hash)
+		ret = int_error_hash;
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+	return ret;
+}
+
+static void
+int_err_del(void)
+{
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	if (int_error_hash) {
+		lh_ERR_STRING_DATA_free(int_error_hash);
+		int_error_hash = NULL;
+	}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+}
+
+static ERR_STRING_DATA *
+int_err_get_item(const ERR_STRING_DATA *d)
+{
+	ERR_STRING_DATA *p;
+	LHASH_OF(ERR_STRING_DATA) *hash;
+
+	err_fns_check();
+	hash = ERRFN(err_get)(0);
+	if (!hash)
+		return NULL;
+
+	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
+	p = lh_ERR_STRING_DATA_retrieve(hash, d);
+	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
+
+	return p;
+}
+
+static ERR_STRING_DATA *
+int_err_set_item(ERR_STRING_DATA *d)
+{
+	ERR_STRING_DATA *p;
+	LHASH_OF(ERR_STRING_DATA) *hash;
+
+	err_fns_check();
+	hash = ERRFN(err_get)(1);
+	if (!hash)
+		return NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	p = lh_ERR_STRING_DATA_insert(hash, d);
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+	return p;
+}
+
+static ERR_STRING_DATA *
+int_err_del_item(ERR_STRING_DATA *d)
+{
+	ERR_STRING_DATA *p;
+	LHASH_OF(ERR_STRING_DATA) *hash;
+
+	err_fns_check();
+	hash = ERRFN(err_get)(0);
+	if (!hash)
+		return NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	p = lh_ERR_STRING_DATA_delete(hash, d);
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+	return p;
+}
+
+static unsigned long
+err_state_hash(const ERR_STATE *a)
+{
+	return CRYPTO_THREADID_hash(&a->tid) * 13;
+}
+static IMPLEMENT_LHASH_HASH_FN(err_state, ERR_STATE)
+
+static int
+err_state_cmp(const ERR_STATE *a, const ERR_STATE *b)
+{
+	return CRYPTO_THREADID_cmp(&a->tid, &b->tid);
+}
+static IMPLEMENT_LHASH_COMP_FN(err_state, ERR_STATE)
+
+static
+LHASH_OF(ERR_STATE) *int_thread_get(int create)
+{
+	LHASH_OF(ERR_STATE) *ret = NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	if (!int_thread_hash && create) {
+		CRYPTO_push_info("int_thread_get (err.c)");
+		int_thread_hash = lh_ERR_STATE_new();
+		CRYPTO_pop_info();
+	}
+	if (int_thread_hash) {
+		int_thread_hash_references++;
+		ret = int_thread_hash;
+	}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+	return ret;
+}
+
+static void
+int_thread_release(LHASH_OF(ERR_STATE) **hash)
+{
+	int i;
+
+	if (hash == NULL || *hash == NULL)
+		return;
+
+	i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR);
+	if (i > 0)
+		return;
+
+	*hash = NULL;
+}
+
+static ERR_STATE *
+int_thread_get_item(const ERR_STATE *d)
+{
+	ERR_STATE *p;
+	LHASH_OF(ERR_STATE) *hash;
+
+	err_fns_check();
+	hash = ERRFN(thread_get)(0);
+	if (!hash)
+		return NULL;
+
+	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
+	p = lh_ERR_STATE_retrieve(hash, d);
+	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
+
+	ERRFN(thread_release)(&hash);
+	return p;
+}
+
+static ERR_STATE *
+int_thread_set_item(ERR_STATE *d)
+{
+	ERR_STATE *p;
+	LHASH_OF(ERR_STATE) *hash;
+
+	err_fns_check();
+	hash = ERRFN(thread_get)(1);
+	if (!hash)
+		return NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	p = lh_ERR_STATE_insert(hash, d);
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+	ERRFN(thread_release)(&hash);
+	return p;
+}
+
+static void
+int_thread_del_item(const ERR_STATE *d)
+{
+	ERR_STATE *p;
+	LHASH_OF(ERR_STATE) *hash;
+
+	err_fns_check();
+	hash = ERRFN(thread_get)(0);
+	if (!hash)
+		return;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	p = lh_ERR_STATE_delete(hash, d);
+	/* make sure we don't leak memory */
+	if (int_thread_hash_references == 1 &&
+	    int_thread_hash && lh_ERR_STATE_num_items(int_thread_hash) == 0) {
+		lh_ERR_STATE_free(int_thread_hash);
+		int_thread_hash = NULL;
+	}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+	ERRFN(thread_release)(&hash);
+	if (p)
+		ERR_STATE_free(p);
+}
+
+static int
+int_err_get_next_lib(void)
+{
+	int ret;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	ret = int_err_library_number++;
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+	return ret;
+}
+
+
+#ifndef OPENSSL_NO_ERR
+#define NUM_SYS_STR_REASONS 127
+#define LEN_SYS_STR_REASON 32
+
+static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
+/* SYS_str_reasons is filled with copies of strerror() results at
+ * initialization.
+ * 'errno' values up to 127 should cover all usual errors,
+ * others will be displayed numerically by ERR_error_string.
+ * It is crucial that we have something for each reason code
+ * that occurs in ERR_str_reasons, or bogus reason strings
+ * will be returned for SYSerr(), which always gets an errno
+ * value and never one of those 'standard' reason codes. */
+
+static void
+build_SYS_str_reasons(void)
+{
+	/* malloc cannot be used here, use static storage instead */
+	static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON];
+	int i;
+	static int init = 1;
+
+	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
+	if (!init) {
+		CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
+		return;
+	}
+
+	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	if (!init) {
+		CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+		return;
+	}
+
+	for (i = 1; i <= NUM_SYS_STR_REASONS; i++) {
+		ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];
+
+		str->error = (unsigned long)i;
+		if (str->string == NULL) {
+			char (*dest)[LEN_SYS_STR_REASON] =
+			    &(strerror_tab[i - 1]);
+			const char *src = strerror(i);
+			if (src != NULL) {
+				strlcpy(*dest, src, sizeof *dest);
+				str->string = *dest;
+			}
+		}
+		if (str->string == NULL)
+			str->string = "unknown";
+	}
+
+	/* Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL},
+	 * as required by ERR_load_strings. */
+
+	init = 0;
+
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+}
+#endif
+
+#define err_clear_data(p,i) \
+	do { \
+		if (((p)->err_data[i] != NULL) && \
+		    (p)->err_data_flags[i] & ERR_TXT_MALLOCED) { \
+			free((p)->err_data[i]); \
+			(p)->err_data[i] = NULL; \
+		} \
+		(p)->err_data_flags[i] = 0; \
+	} while(0)
+
+#define err_clear(p,i) \
+	do { \
+		(p)->err_flags[i] = 0; \
+		(p)->err_buffer[i] = 0; \
+		err_clear_data(p, i); \
+		(p)->err_file[i] = NULL; \
+		(p)->err_line[i] = -1; \
+	} while(0)
+
+static void
+ERR_STATE_free(ERR_STATE *s)
+{
+	int i;
+
+	if (s == NULL)
+		return;
+
+	for (i = 0; i < ERR_NUM_ERRORS; i++) {
+		err_clear_data(s, i);
+	}
+	free(s);
+}
+
+void
+ERR_load_ERR_strings(void)
+{
+	err_fns_check();
+#ifndef OPENSSL_NO_ERR
+	err_load_strings(0, ERR_str_libraries);
+	err_load_strings(0, ERR_str_reasons);
+	err_load_strings(ERR_LIB_SYS, ERR_str_functs);
+	build_SYS_str_reasons();
+	err_load_strings(ERR_LIB_SYS, SYS_str_reasons);
+#endif
+}
+
+static void
+err_load_strings(int lib, ERR_STRING_DATA *str)
+{
+	while (str->error) {
+		if (lib)
+			str->error |= ERR_PACK(lib, 0, 0);
+		ERRFN(err_set_item)(str);
+		str++;
+	}
+}
+
+void
+ERR_load_strings(int lib, ERR_STRING_DATA *str)
+{
+	ERR_load_ERR_strings();
+	err_load_strings(lib, str);
+}
+
+void
+ERR_unload_strings(int lib, ERR_STRING_DATA *str)
+{
+	while (str->error) {
+		if (lib)
+			str->error |= ERR_PACK(lib, 0, 0);
+		ERRFN(err_del_item)(str);
+		str++;
+	}
+}
+
+void
+ERR_free_strings(void)
+{
+	err_fns_check();
+	ERRFN(err_del)();
+}
+
+/********************************************************/
+
+void
+ERR_put_error(int lib, int func, int reason, const char *file, int line)
+{
+	ERR_STATE *es;
+	int save_errno = errno;
+
+	es = ERR_get_state();
+
+	es->top = (es->top + 1) % ERR_NUM_ERRORS;
+	if (es->top == es->bottom)
+		es->bottom = (es->bottom + 1) % ERR_NUM_ERRORS;
+	es->err_flags[es->top] = 0;
+	es->err_buffer[es->top] = ERR_PACK(lib, func, reason);
+	es->err_file[es->top] = file;
+	es->err_line[es->top] = line;
+	err_clear_data(es, es->top);
+	errno = save_errno;
+}
+
+void
+ERR_clear_error(void)
+{
+	int i;
+	ERR_STATE *es;
+
+	es = ERR_get_state();
+
+	for (i = 0; i < ERR_NUM_ERRORS; i++) {
+		err_clear(es, i);
+	}
+	es->top = es->bottom = 0;
+}
+
+
+unsigned long
+ERR_get_error(void)
+{
+	return (get_error_values(1, 0, NULL, NULL, NULL, NULL));
+}
+
+unsigned long
+ERR_get_error_line(const char **file, int *line)
+{
+	return (get_error_values(1, 0, file, line, NULL, NULL));
+}
+
+unsigned long
+ERR_get_error_line_data(const char **file, int *line,
+    const char **data, int *flags)
+{
+	return (get_error_values(1, 0, file, line, data, flags));
+}
+
+
+unsigned long
+ERR_peek_error(void)
+{
+	return (get_error_values(0, 0, NULL, NULL, NULL, NULL));
+}
+
+unsigned long
+ERR_peek_error_line(const char **file, int *line)
+{
+	return (get_error_values(0, 0, file, line, NULL, NULL));
+}
+
+unsigned long
+ERR_peek_error_line_data(const char **file, int *line,
+    const char **data, int *flags)
+{
+	return (get_error_values(0, 0, file, line, data, flags));
+}
+
+unsigned long
+ERR_peek_last_error(void)
+{
+	return (get_error_values(0, 1, NULL, NULL, NULL, NULL));
+}
+
+unsigned long
+ERR_peek_last_error_line(const char **file, int *line)
+{
+	return (get_error_values(0, 1, file, line, NULL, NULL));
+}
+
+unsigned long
+ERR_peek_last_error_line_data(const char **file, int *line,
+    const char **data, int *flags)
+{
+	return (get_error_values(0, 1, file, line, data, flags));
+}
+
+static unsigned long
+get_error_values(int inc, int top, const char **file, int *line,
+    const char **data, int *flags)
+{
+	int i = 0;
+	ERR_STATE *es;
+	unsigned long ret;
+
+	es = ERR_get_state();
+
+	if (inc && top) {
+		if (file)
+			*file = "";
+		if (line)
+			*line = 0;
+		if (data)
+			*data = "";
+		if (flags)
+			*flags = 0;
+
+		return ERR_R_INTERNAL_ERROR;
+	}
+
+	if (es->bottom == es->top)
+		return 0;
+	if (top)
+		i = es->top;			 /* last error */
+	else
+		i = (es->bottom + 1) % ERR_NUM_ERRORS; /* first error */
+
+	ret = es->err_buffer[i];
+	if (inc) {
+		es->bottom = i;
+		es->err_buffer[i] = 0;
+	}
+
+	if ((file != NULL) && (line != NULL)) {
+		if (es->err_file[i] == NULL) {
+			*file = "NA";
+			if (line != NULL)
+				*line = 0;
+		} else {
+			*file = es->err_file[i];
+			if (line != NULL)
+				*line = es->err_line[i];
+		}
+	}
+
+	if (data == NULL) {
+		if (inc) {
+			err_clear_data(es, i);
+		}
+	} else {
+		if (es->err_data[i] == NULL) {
+			*data = "";
+			if (flags != NULL)
+				*flags = 0;
+		} else {
+			*data = es->err_data[i];
+			if (flags != NULL)
+				*flags = es->err_data_flags[i];
+		}
+	}
+	return ret;
+}
+
+void
+ERR_error_string_n(unsigned long e, char *buf, size_t len)
+{
+	char lsbuf[30], fsbuf[30], rsbuf[30];
+	const char *ls, *fs, *rs;
+	int l, f, r, ret;
+
+	l = ERR_GET_LIB(e);
+	f = ERR_GET_FUNC(e);
+	r = ERR_GET_REASON(e);
+
+	ls = ERR_lib_error_string(e);
+	fs = ERR_func_error_string(e);
+	rs = ERR_reason_error_string(e);
+
+	if (ls == NULL) {
+		(void) snprintf(lsbuf, sizeof(lsbuf), "lib(%d)", l);
+		ls = lsbuf;
+	}
+	if (fs == NULL) {
+		(void) snprintf(fsbuf, sizeof(fsbuf), "func(%d)", f);
+		fs = fsbuf;
+	}
+	if (rs == NULL) {
+		(void) snprintf(rsbuf, sizeof(rsbuf), "reason(%d)", r);
+		rs = rsbuf;
+	}
+
+	ret = snprintf(buf, len, "error:%08lX:%s:%s:%s", e, ls, fs, rs);
+	if (ret == -1)
+		return;	/* can't happen, and can't do better if it does */
+	if (ret >= len) {
+		/* output may be truncated; make sure we always have 5
+		 * colon-separated fields, i.e. 4 colons ... */
+#define NUM_COLONS 4
+		if (len > NUM_COLONS) /* ... if possible */
+		{
+			int i;
+			char *s = buf;
+
+			for (i = 0; i < NUM_COLONS; i++) {
+				char *colon = strchr(s, ':');
+				if (colon == NULL ||
+				    colon > &buf[len - 1] - NUM_COLONS + i) {
+					/* set colon no. i at last possible position
+					 * (buf[len-1] is the terminating 0)*/
+					colon = &buf[len - 1] - NUM_COLONS + i;
+					*colon = ':';
+				}
+				s = colon + 1;
+			}
+		}
+	}
+}
+
+/* BAD for multi-threading: uses a local buffer if ret == NULL */
+/* ERR_error_string_n should be used instead for ret != NULL
+ * as ERR_error_string cannot know how large the buffer is */
+char *
+ERR_error_string(unsigned long e, char *ret)
+{
+	static char buf[256];
+
+	if (ret == NULL)
+		ret = buf;
+	ERR_error_string_n(e, ret, 256);
+
+	return ret;
+}
+
+LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void)
+{
+	err_fns_check();
+	return ERRFN(err_get)(0);
+}
+
+LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void)
+{
+	err_fns_check();
+	return ERRFN(thread_get)(0);
+}
+
+void
+ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash)
+{
+	err_fns_check();
+	ERRFN(thread_release)(hash);
+}
+
+const char *
+ERR_lib_error_string(unsigned long e)
+{
+	ERR_STRING_DATA d, *p;
+	unsigned long l;
+
+	err_fns_check();
+	l = ERR_GET_LIB(e);
+	d.error = ERR_PACK(l, 0, 0);
+	p = ERRFN(err_get_item)(&d);
+	return ((p == NULL) ? NULL : p->string);
+}
+
+const char *
+ERR_func_error_string(unsigned long e)
+{
+	ERR_STRING_DATA d, *p;
+	unsigned long l, f;
+
+	err_fns_check();
+	l = ERR_GET_LIB(e);
+	f = ERR_GET_FUNC(e);
+	d.error = ERR_PACK(l, f, 0);
+	p = ERRFN(err_get_item)(&d);
+	return ((p == NULL) ? NULL : p->string);
+}
+
+const char *
+ERR_reason_error_string(unsigned long e)
+{
+	ERR_STRING_DATA d, *p = NULL;
+	unsigned long l, r;
+
+	err_fns_check();
+	l = ERR_GET_LIB(e);
+	r = ERR_GET_REASON(e);
+	d.error = ERR_PACK(l, 0, r);
+	p = ERRFN(err_get_item)(&d);
+	if (!p) {
+		d.error = ERR_PACK(0, 0, r);
+		p = ERRFN(err_get_item)(&d);
+	}
+	return ((p == NULL) ? NULL : p->string);
+}
+
+void
+ERR_remove_thread_state(const CRYPTO_THREADID *id)
+{
+	ERR_STATE tmp;
+
+	if (id)
+		CRYPTO_THREADID_cpy(&tmp.tid, id);
+	else
+		CRYPTO_THREADID_current(&tmp.tid);
+	err_fns_check();
+	/* thread_del_item automatically destroys the LHASH if the number of
+	 * items reaches zero. */
+	ERRFN(thread_del_item)(&tmp);
+}
+
+#ifndef OPENSSL_NO_DEPRECATED
+void
+ERR_remove_state(unsigned long pid)
+{
+	ERR_remove_thread_state(NULL);
+}
+#endif
+
+ERR_STATE *
+ERR_get_state(void)
+{
+	static ERR_STATE fallback;
+	ERR_STATE *ret, tmp, *tmpp = NULL;
+	int i;
+	CRYPTO_THREADID tid;
+
+	err_fns_check();
+	CRYPTO_THREADID_current(&tid);
+	CRYPTO_THREADID_cpy(&tmp.tid, &tid);
+	ret = ERRFN(thread_get_item)(&tmp);
+
+	/* ret == the error state, if NULL, make a new one */
+	if (ret == NULL) {
+		ret = malloc(sizeof(ERR_STATE));
+		if (ret == NULL)
+			return (&fallback);
+		CRYPTO_THREADID_cpy(&ret->tid, &tid);
+		ret->top = 0;
+		ret->bottom = 0;
+		for (i = 0; i < ERR_NUM_ERRORS; i++) {
+			ret->err_data[i] = NULL;
+			ret->err_data_flags[i] = 0;
+		}
+		tmpp = ERRFN(thread_set_item)(ret);
+		/* To check if insertion failed, do a get. */
+		if (ERRFN(thread_get_item)(ret) != ret) {
+			ERR_STATE_free(ret); /* could not insert it */
+			return (&fallback);
+		}
+		/* If a race occured in this function and we came second, tmpp
+		 * is the first one that we just replaced. */
+		if (tmpp)
+			ERR_STATE_free(tmpp);
+	}
+	return ret;
+}
+
+int
+ERR_get_next_error_library(void)
+{
+	err_fns_check();
+	return ERRFN(get_next_lib)();
+}
+
+void
+ERR_set_error_data(char *data, int flags)
+{
+	ERR_STATE *es;
+	int i;
+
+	es = ERR_get_state();
+
+	i = es->top;
+	if (i == 0)
+		i = ERR_NUM_ERRORS - 1;
+
+	err_clear_data(es, i);
+	es->err_data[i] = data;
+	es->err_data_flags[i] = flags;
+}
+
+void
+ERR_asprintf_error_data(char * format, ...) {
+	char *errbuf = NULL;
+	va_list ap;
+	int r;
+
+	va_start(ap, format);
+	r = vasprintf(&errbuf, format, ap);
+	va_end(ap);
+	if (r == -1)
+		ERR_set_error_data("malloc failed", ERR_TXT_STRING);
+	else
+		ERR_set_error_data(errbuf, ERR_TXT_MALLOCED|ERR_TXT_STRING);
+}
+void
+ERR_add_error_data(int num, ...)
+{
+	va_list args;
+	va_start(args, num);
+	ERR_add_error_vdata(num, args);
+	va_end(args);
+}
+
+void
+ERR_add_error_vdata(int num, va_list args)
+{
+	char format[129];
+	char *errbuf;
+	int i;
+
+	format[0] = '\0';
+	for (i = 0; i < num; i++) {
+		if (strlcat(format, "%s", sizeof(format)) >= sizeof(format)) {
+			ERR_set_error_data("too many errors", ERR_TXT_STRING);
+			return;
+		}
+	}
+	if (vasprintf(&errbuf, format, args) == -1)
+		ERR_set_error_data("malloc failed", ERR_TXT_STRING);
+	else
+		ERR_set_error_data(errbuf, ERR_TXT_MALLOCED|ERR_TXT_STRING);
+}
+
+int
+ERR_set_mark(void)
+{
+	ERR_STATE *es;
+
+	es = ERR_get_state();
+
+	if (es->bottom == es->top)
+		return 0;
+	es->err_flags[es->top] |= ERR_FLAG_MARK;
+	return 1;
+}
+
+int
+ERR_pop_to_mark(void)
+{
+	ERR_STATE *es;
+
+	es = ERR_get_state();
+
+	while (es->bottom != es->top &&
+	    (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) {
+		err_clear(es, es->top);
+		es->top -= 1;
+		if (es->top == -1)
+			es->top = ERR_NUM_ERRORS - 1;
+	}
+
+	if (es->bottom == es->top)
+		return 0;
+	es->err_flags[es->top]&=~ERR_FLAG_MARK;
+	return 1;
+}
diff --git a/crypto/libressl/crypto/err/err_all.c b/crypto/libressl/crypto/err/err_all.c
new file mode 100644
index 0000000000..3de5e0223d
--- /dev/null
+++ b/crypto/libressl/crypto/err/err_all.c
@@ -0,0 +1,161 @@
+/* $OpenBSD: err_all.c,v 1.21 2015/02/11 03:55:42 beck Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_CMS
+#include 
+#endif
+#ifndef OPENSSL_NO_DH
+#include 
+#endif
+#ifndef OPENSSL_NO_DSA
+#include 
+#endif
+#ifndef OPENSSL_NO_EC
+#include 
+#endif
+#ifndef OPENSSL_NO_ECDH
+#include 
+#endif
+#ifndef OPENSSL_NO_ECDSA
+#include 
+#endif
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+#ifndef OPENSSL_NO_RSA
+#include 
+#endif
+#ifndef OPENSSL_NO_GOST
+#include 
+#endif
+
+void
+ERR_load_crypto_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	ERR_load_ERR_strings(); /* include error strings for SYSerr */
+	ERR_load_BN_strings();
+#ifndef OPENSSL_NO_RSA
+	ERR_load_RSA_strings();
+#endif
+#ifndef OPENSSL_NO_DH
+	ERR_load_DH_strings();
+#endif
+	ERR_load_EVP_strings();
+	ERR_load_BUF_strings();
+	ERR_load_OBJ_strings();
+	ERR_load_PEM_strings();
+#ifndef OPENSSL_NO_DSA
+	ERR_load_DSA_strings();
+#endif
+	ERR_load_X509_strings();
+	ERR_load_ASN1_strings();
+	ERR_load_CONF_strings();
+	ERR_load_CRYPTO_strings();
+#ifndef OPENSSL_NO_EC
+	ERR_load_EC_strings();
+#endif
+#ifndef OPENSSL_NO_ECDSA
+	ERR_load_ECDSA_strings();
+#endif
+#ifndef OPENSSL_NO_ECDH
+	ERR_load_ECDH_strings();
+#endif
+	/* skip ERR_load_SSL_strings() because it is not in this library */
+	ERR_load_BIO_strings();
+	ERR_load_PKCS7_strings();
+	ERR_load_X509V3_strings();
+	ERR_load_PKCS12_strings();
+	ERR_load_RAND_strings();
+	ERR_load_DSO_strings();
+	ERR_load_TS_strings();
+#ifndef OPENSSL_NO_ENGINE
+	ERR_load_ENGINE_strings();
+#endif
+	ERR_load_OCSP_strings();
+	ERR_load_UI_strings();
+#ifndef OPENSSL_NO_CMS
+	ERR_load_CMS_strings();
+#endif
+#ifndef OPENSSL_NO_GOST
+	ERR_load_GOST_strings();
+#endif
+#endif
+}
diff --git a/crypto/libressl/crypto/err/err_prn.c b/crypto/libressl/crypto/err/err_prn.c
new file mode 100644
index 0000000000..cd2ace53c3
--- /dev/null
+++ b/crypto/libressl/crypto/err/err_prn.c
@@ -0,0 +1,117 @@
+/* $OpenBSD: err_prn.c,v 1.15 2014/07/10 13:58:22 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+void
+ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u), void *u)
+{
+	unsigned long l;
+	char buf[256];
+	char buf2[4096];
+	const char *file, *data;
+	int line, flags;
+	unsigned long es;
+	CRYPTO_THREADID cur;
+
+	CRYPTO_THREADID_current(&cur);
+	es = CRYPTO_THREADID_hash(&cur);
+	while ((l = ERR_get_error_line_data(&file, &line, &data,
+	    &flags)) != 0) {
+		ERR_error_string_n(l, buf, sizeof buf);
+		(void) snprintf(buf2, sizeof(buf2), "%lu:%s:%s:%d:%s\n", es,
+		    buf, file, line, (flags & ERR_TXT_STRING) ? data : "");
+		if (cb(buf2, strlen(buf2), u) <= 0)
+			break; /* abort outputting the error report */
+	}
+}
+
+static int
+print_fp(const char *str, size_t len, void *fp)
+{
+	BIO bio;
+
+	BIO_set(&bio, BIO_s_file());
+	BIO_set_fp(&bio, fp, BIO_NOCLOSE);
+
+	return BIO_printf(&bio, "%s", str);
+}
+
+void
+ERR_print_errors_fp(FILE *fp)
+{
+	ERR_print_errors_cb(print_fp, fp);
+}
+
+static int
+print_bio(const char *str, size_t len, void *bp)
+{
+	return BIO_write((BIO *)bp, str, len);
+}
+
+void
+ERR_print_errors(BIO *bp)
+{
+	ERR_print_errors_cb(print_bio, bp);
+}
diff --git a/crypto/libressl/crypto/evp/bio_b64.c b/crypto/libressl/crypto/evp/bio_b64.c
new file mode 100644
index 0000000000..3503a16e24
--- /dev/null
+++ b/crypto/libressl/crypto/evp/bio_b64.c
@@ -0,0 +1,567 @@
+/* $OpenBSD: bio_b64.c,v 1.19 2014/07/11 12:04:46 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+static int b64_write(BIO *h, const char *buf, int num);
+static int b64_read(BIO *h, char *buf, int size);
+static int b64_puts(BIO *h, const char *str);
+/*static int b64_gets(BIO *h, char *str, int size); */
+static long b64_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int b64_new(BIO *h);
+static int b64_free(BIO *data);
+static long b64_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+#define B64_BLOCK_SIZE	1024
+#define B64_BLOCK_SIZE2	768
+#define B64_NONE	0
+#define B64_ENCODE	1
+#define B64_DECODE	2
+
+typedef struct b64_struct {
+	/*BIO *bio; moved to the BIO structure */
+	int buf_len;
+	int buf_off;
+	int tmp_len;		/* used to find the start when decoding */
+	int tmp_nl;		/* If true, scan until '\n' */
+	int encode;
+	int start;		/* have we started decoding yet? */
+	int cont;		/* <= 0 when finished */
+	EVP_ENCODE_CTX base64;
+	char buf[EVP_ENCODE_LENGTH(B64_BLOCK_SIZE) + 10];
+	char tmp[B64_BLOCK_SIZE];
+} BIO_B64_CTX;
+
+static BIO_METHOD methods_b64 = {
+	.type = BIO_TYPE_BASE64,
+	.name = "base64 encoding",
+	.bwrite = b64_write,
+	.bread = b64_read,
+	.bputs = b64_puts,
+	.ctrl = b64_ctrl,
+	.create = b64_new,
+	.destroy = b64_free,
+	.callback_ctrl = b64_callback_ctrl
+};
+
+BIO_METHOD *
+BIO_f_base64(void)
+{
+	return (&methods_b64);
+}
+
+static int
+b64_new(BIO *bi)
+{
+	BIO_B64_CTX *ctx;
+
+	ctx = malloc(sizeof(BIO_B64_CTX));
+	if (ctx == NULL)
+		return (0);
+
+	ctx->buf_len = 0;
+	ctx->tmp_len = 0;
+	ctx->tmp_nl = 0;
+	ctx->buf_off = 0;
+	ctx->cont = 1;
+	ctx->start = 1;
+	ctx->encode = 0;
+
+	bi->init = 1;
+	bi->ptr = (char *)ctx;
+	bi->flags = 0;
+	bi->num = 0;
+	return (1);
+}
+
+static int
+b64_free(BIO *a)
+{
+	if (a == NULL)
+		return (0);
+	free(a->ptr);
+	a->ptr = NULL;
+	a->init = 0;
+	a->flags = 0;
+	return (1);
+}
+
+static int
+b64_read(BIO *b, char *out, int outl)
+{
+	int ret = 0, i, ii, j, k, x, n, num, ret_code = 0;
+	BIO_B64_CTX *ctx;
+	unsigned char *p, *q;
+
+	if (out == NULL)
+		return (0);
+	ctx = (BIO_B64_CTX *)b->ptr;
+
+	if ((ctx == NULL) || (b->next_bio == NULL))
+		return (0);
+
+	BIO_clear_retry_flags(b);
+
+	if (ctx->encode != B64_DECODE) {
+		ctx->encode = B64_DECODE;
+		ctx->buf_len = 0;
+		ctx->buf_off = 0;
+		ctx->tmp_len = 0;
+		EVP_DecodeInit(&(ctx->base64));
+	}
+
+	/* First check if there are bytes decoded/encoded */
+	if (ctx->buf_len > 0) {
+		OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+		i = ctx->buf_len - ctx->buf_off;
+		if (i > outl)
+			i = outl;
+		OPENSSL_assert(ctx->buf_off + i < (int)sizeof(ctx->buf));
+		memcpy(out, &(ctx->buf[ctx->buf_off]), i);
+		ret = i;
+		out += i;
+		outl -= i;
+		ctx->buf_off += i;
+		if (ctx->buf_len == ctx->buf_off) {
+			ctx->buf_len = 0;
+			ctx->buf_off = 0;
+		}
+	}
+
+	/* At this point, we have room of outl bytes and an empty
+	 * buffer, so we should read in some more. */
+
+	ret_code = 0;
+	while (outl > 0) {
+		if (ctx->cont <= 0)
+			break;
+
+		i = BIO_read(b->next_bio, &(ctx->tmp[ctx->tmp_len]),
+		    B64_BLOCK_SIZE - ctx->tmp_len);
+
+		if (i <= 0) {
+			ret_code = i;
+
+			/* Should we continue next time we are called? */
+			if (!BIO_should_retry(b->next_bio)) {
+				ctx->cont = i;
+				/* If buffer empty break */
+				if (ctx->tmp_len == 0)
+					break;
+				/* Fall through and process what we have */
+				else
+					i = 0;
+			}
+			/* else we retry and add more data to buffer */
+			else
+				break;
+		}
+		i += ctx->tmp_len;
+		ctx->tmp_len = i;
+
+		/* We need to scan, a line at a time until we
+		 * have a valid line if we are starting. */
+		if (ctx->start && (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)) {
+			/* ctx->start=1; */
+			ctx->tmp_len = 0;
+		} else if (ctx->start) {
+			q = p =(unsigned char *)ctx->tmp;
+			num = 0;
+			for (j = 0; j < i; j++) {
+				if (*(q++) != '\n')
+					continue;
+
+				/* due to a previous very long line,
+				 * we need to keep on scanning for a '\n'
+				 * before we even start looking for
+				 * base64 encoded stuff. */
+				if (ctx->tmp_nl) {
+					p = q;
+					ctx->tmp_nl = 0;
+					continue;
+				}
+
+				k = EVP_DecodeUpdate(&(ctx->base64),
+				    (unsigned char *)ctx->buf,
+				    &num, p, q - p);
+				if ((k <= 0) && (num == 0) && (ctx->start))
+					EVP_DecodeInit(&ctx->base64);
+				else {
+					if (p != (unsigned char *)
+						&(ctx->tmp[0])) {
+						i -= (p - (unsigned char *)
+						&(ctx->tmp[0]));
+						for (x = 0; x < i; x++)
+							ctx->tmp[x] = p[x];
+					}
+					EVP_DecodeInit(&ctx->base64);
+					ctx->start = 0;
+					break;
+				}
+				p = q;
+			}
+
+			/* we fell off the end without starting */
+			if ((j == i) && (num == 0)) {
+				/* Is this is one long chunk?, if so, keep on
+				 * reading until a new line. */
+				if (p == (unsigned char *)&(ctx->tmp[0])) {
+					/* Check buffer full */
+					if (i == B64_BLOCK_SIZE) {
+						ctx->tmp_nl = 1;
+						ctx->tmp_len = 0;
+					}
+				}
+				else if (p != q) /* finished on a '\n' */
+				{
+					n = q - p;
+					for (ii = 0; ii < n; ii++)
+						ctx->tmp[ii] = p[ii];
+					ctx->tmp_len = n;
+				}
+				/* else finished on a '\n' */
+				continue;
+			} else {
+				ctx->tmp_len = 0;
+			}
+		} else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0)) {
+			/* If buffer isn't full and we can retry then
+			 * restart to read in more data.
+			 */
+			continue;
+		}
+
+		if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
+			int z, jj;
+
+			jj = i & ~3; /* process per 4 */
+			z = EVP_DecodeBlock((unsigned char *)ctx->buf,
+			    (unsigned char *)ctx->tmp, jj);
+			if (jj > 2) {
+				if (ctx->tmp[jj-1] == '=') {
+					z--;
+					if (ctx->tmp[jj-2] == '=')
+						z--;
+				}
+			}
+			/* z is now number of output bytes and jj is the
+			 * number consumed */
+			if (jj != i) {
+				memmove(ctx->tmp, &ctx->tmp[jj], i - jj);
+				ctx->tmp_len = i - jj;
+			}
+			ctx->buf_len = 0;
+			if (z > 0) {
+				ctx->buf_len = z;
+			}
+			i = z;
+		} else {
+			i = EVP_DecodeUpdate(&(ctx->base64),
+			    (unsigned char *)ctx->buf, &ctx->buf_len,
+			    (unsigned char *)ctx->tmp, i);
+			ctx->tmp_len = 0;
+		}
+		ctx->buf_off = 0;
+		if (i < 0) {
+			ret_code = 0;
+			ctx->buf_len = 0;
+			break;
+		}
+
+		if (ctx->buf_len <= outl)
+			i = ctx->buf_len;
+		else
+			i = outl;
+
+		memcpy(out, ctx->buf, i);
+		ret += i;
+		ctx->buf_off = i;
+		if (ctx->buf_off == ctx->buf_len) {
+			ctx->buf_len = 0;
+			ctx->buf_off = 0;
+		}
+		outl -= i;
+		out += i;
+	}
+	/* BIO_clear_retry_flags(b); */
+	BIO_copy_next_retry(b);
+	return ((ret == 0) ? ret_code : ret);
+}
+
+static int
+b64_write(BIO *b, const char *in, int inl)
+{
+	int ret = 0;
+	int n;
+	int i;
+	BIO_B64_CTX *ctx;
+
+	ctx = (BIO_B64_CTX *)b->ptr;
+	BIO_clear_retry_flags(b);
+
+	if (ctx->encode != B64_ENCODE) {
+		ctx->encode = B64_ENCODE;
+		ctx->buf_len = 0;
+		ctx->buf_off = 0;
+		ctx->tmp_len = 0;
+		EVP_EncodeInit(&(ctx->base64));
+	}
+
+	OPENSSL_assert(ctx->buf_off < (int)sizeof(ctx->buf));
+	OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+	OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+	n = ctx->buf_len - ctx->buf_off;
+	while (n > 0) {
+		i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
+		if (i <= 0) {
+			BIO_copy_next_retry(b);
+			return (i);
+		}
+		OPENSSL_assert(i <= n);
+		ctx->buf_off += i;
+		OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
+		OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+		n -= i;
+	}
+	/* at this point all pending data has been written */
+	ctx->buf_off = 0;
+	ctx->buf_len = 0;
+
+	if ((in == NULL) || (inl <= 0))
+		return (0);
+
+	while (inl > 0) {
+		n = (inl > B64_BLOCK_SIZE) ? B64_BLOCK_SIZE : inl;
+
+		if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
+			if (ctx->tmp_len > 0) {
+				OPENSSL_assert(ctx->tmp_len <= 3);
+				n = 3 - ctx->tmp_len;
+				/* There's a theoretical possibility for this */
+				if (n > inl)
+					n = inl;
+				memcpy(&(ctx->tmp[ctx->tmp_len]), in, n);
+				ctx->tmp_len += n;
+				ret += n;
+				if (ctx->tmp_len < 3)
+					break;
+				ctx->buf_len = EVP_EncodeBlock(
+				    (unsigned char *)ctx->buf,
+				    (unsigned char *)ctx->tmp, ctx->tmp_len);
+				OPENSSL_assert(ctx->buf_len <=
+				    (int)sizeof(ctx->buf));
+				OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+				/* Since we're now done using the temporary
+				   buffer, the length should be 0'd */
+				ctx->tmp_len = 0;
+			} else {
+				if (n < 3) {
+					memcpy(ctx->tmp, in, n);
+					ctx->tmp_len = n;
+					ret += n;
+					break;
+				}
+				n -= n % 3;
+				ctx->buf_len = EVP_EncodeBlock(
+				    (unsigned char *)ctx->buf,
+				    (const unsigned char *)in, n);
+				OPENSSL_assert(ctx->buf_len <=
+				    (int)sizeof(ctx->buf));
+				OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+				ret += n;
+			}
+		} else {
+			EVP_EncodeUpdate(&(ctx->base64),
+			    (unsigned char *)ctx->buf, &ctx->buf_len,
+			    (unsigned char *)in, n);
+			OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+			OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+			ret += n;
+		}
+		inl -= n;
+		in += n;
+
+		ctx->buf_off = 0;
+		n = ctx->buf_len;
+		while (n > 0) {
+			i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
+			if (i <= 0) {
+				BIO_copy_next_retry(b);
+				return ((ret == 0) ? i : ret);
+			}
+			OPENSSL_assert(i <= n);
+			n -= i;
+			ctx->buf_off += i;
+			OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
+			OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+		}
+		ctx->buf_len = 0;
+		ctx->buf_off = 0;
+	}
+	return (ret);
+}
+
+static long
+b64_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+	BIO_B64_CTX *ctx;
+	long ret = 1;
+	int i;
+
+	ctx = (BIO_B64_CTX *)b->ptr;
+
+	switch (cmd) {
+	case BIO_CTRL_RESET:
+		ctx->cont = 1;
+		ctx->start = 1;
+		ctx->encode = B64_NONE;
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		break;
+	case BIO_CTRL_EOF:	/* More to read */
+		if (ctx->cont <= 0)
+			ret = 1;
+		else
+			ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		break;
+	case BIO_CTRL_WPENDING: /* More to write in buffer */
+		OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+		ret = ctx->buf_len - ctx->buf_off;
+		if ((ret == 0) && (ctx->encode != B64_NONE) &&
+		    (ctx->base64.num != 0))
+			ret = 1;
+		else if (ret <= 0)
+			ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		break;
+	case BIO_CTRL_PENDING: /* More to read in buffer */
+		OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+		ret = ctx->buf_len - ctx->buf_off;
+		if (ret <= 0)
+			ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		break;
+	case BIO_CTRL_FLUSH:
+		/* do a final write */
+again:
+		while (ctx->buf_len != ctx->buf_off) {
+			i = b64_write(b, NULL, 0);
+			if (i < 0)
+				return i;
+		}
+		if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
+			if (ctx->tmp_len != 0) {
+				ctx->buf_len = EVP_EncodeBlock(
+				    (unsigned char *)ctx->buf,
+				    (unsigned char *)ctx->tmp,
+				    ctx->tmp_len);
+				ctx->buf_off = 0;
+				ctx->tmp_len = 0;
+				goto again;
+			}
+		} else if (ctx->encode != B64_NONE && ctx->base64.num != 0) {
+			ctx->buf_off = 0;
+			EVP_EncodeFinal(&(ctx->base64),
+			    (unsigned char *)ctx->buf,
+			    &(ctx->buf_len));
+			/* push out the bytes */
+			goto again;
+		}
+		/* Finally flush the underlying BIO */
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		break;
+
+	case BIO_C_DO_STATE_MACHINE:
+		BIO_clear_retry_flags(b);
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		BIO_copy_next_retry(b);
+		break;
+
+	case BIO_CTRL_DUP:
+		break;
+	case BIO_CTRL_INFO:
+	case BIO_CTRL_GET:
+	case BIO_CTRL_SET:
+	default:
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		break;
+	}
+	return (ret);
+}
+
+static long
+b64_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+	long ret = 1;
+
+	if (b->next_bio == NULL)
+		return (0);
+	switch (cmd) {
+	default:
+		ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+		break;
+	}
+	return (ret);
+}
+
+static int
+b64_puts(BIO *b, const char *str)
+{
+	return b64_write(b, str, strlen(str));
+}
diff --git a/crypto/libressl/crypto/evp/bio_enc.c b/crypto/libressl/crypto/evp/bio_enc.c
new file mode 100644
index 0000000000..ec9625555a
--- /dev/null
+++ b/crypto/libressl/crypto/evp/bio_enc.c
@@ -0,0 +1,427 @@
+/* $OpenBSD: bio_enc.c,v 1.18 2014/07/11 08:44:48 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+static int enc_write(BIO *h, const char *buf, int num);
+static int enc_read(BIO *h, char *buf, int size);
+/*static int enc_puts(BIO *h, const char *str); */
+/*static int enc_gets(BIO *h, char *str, int size); */
+static long enc_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int enc_new(BIO *h);
+static int enc_free(BIO *data);
+static long enc_callback_ctrl(BIO *h, int cmd, bio_info_cb *fps);
+#define ENC_BLOCK_SIZE	(1024*4)
+#define BUF_OFFSET	(EVP_MAX_BLOCK_LENGTH*2)
+
+typedef struct enc_struct {
+	int buf_len;
+	int buf_off;
+	int cont;		/* <= 0 when finished */
+	int finished;
+	int ok;			/* bad decrypt */
+	EVP_CIPHER_CTX cipher;
+	/* buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate
+	 * can return up to a block more data than is presented to it
+	 */
+	char buf[ENC_BLOCK_SIZE + BUF_OFFSET + 2];
+} BIO_ENC_CTX;
+
+static BIO_METHOD methods_enc = {
+	.type = BIO_TYPE_CIPHER,
+	.name = "cipher",
+	.bwrite = enc_write,
+	.bread = enc_read,
+	.ctrl = enc_ctrl,
+	.create = enc_new,
+	.destroy = enc_free,
+	.callback_ctrl = enc_callback_ctrl
+};
+
+BIO_METHOD *
+BIO_f_cipher(void)
+{
+	return (&methods_enc);
+}
+
+static int
+enc_new(BIO *bi)
+{
+	BIO_ENC_CTX *ctx;
+
+	ctx = malloc(sizeof(BIO_ENC_CTX));
+	if (ctx == NULL)
+		return (0);
+	EVP_CIPHER_CTX_init(&ctx->cipher);
+
+	ctx->buf_len = 0;
+	ctx->buf_off = 0;
+	ctx->cont = 1;
+	ctx->finished = 0;
+	ctx->ok = 1;
+
+	bi->init = 0;
+	bi->ptr = (char *)ctx;
+	bi->flags = 0;
+	return (1);
+}
+
+static int
+enc_free(BIO *a)
+{
+	BIO_ENC_CTX *b;
+
+	if (a == NULL)
+		return (0);
+	b = (BIO_ENC_CTX *)a->ptr;
+	EVP_CIPHER_CTX_cleanup(&(b->cipher));
+	explicit_bzero(a->ptr, sizeof(BIO_ENC_CTX));
+	free(a->ptr);
+	a->ptr = NULL;
+	a->init = 0;
+	a->flags = 0;
+	return (1);
+}
+
+static int
+enc_read(BIO *b, char *out, int outl)
+{
+	int ret = 0, i;
+	BIO_ENC_CTX *ctx;
+
+	if (out == NULL)
+		return (0);
+	ctx = (BIO_ENC_CTX *)b->ptr;
+
+	if ((ctx == NULL) || (b->next_bio == NULL))
+		return (0);
+
+	/* First check if there are bytes decoded/encoded */
+	if (ctx->buf_len > 0) {
+		i = ctx->buf_len - ctx->buf_off;
+		if (i > outl)
+			i = outl;
+		memcpy(out, &(ctx->buf[ctx->buf_off]), i);
+		ret = i;
+		out += i;
+		outl -= i;
+		ctx->buf_off += i;
+		if (ctx->buf_len == ctx->buf_off) {
+			ctx->buf_len = 0;
+			ctx->buf_off = 0;
+		}
+	}
+
+	/* At this point, we have room of outl bytes and an empty
+	 * buffer, so we should read in some more. */
+
+	while (outl > 0) {
+		if (ctx->cont <= 0)
+			break;
+
+		/* read in at IV offset, read the EVP_Cipher
+		 * documentation about why */
+		i = BIO_read(b->next_bio, &(ctx->buf[BUF_OFFSET]), ENC_BLOCK_SIZE);
+
+		if (i <= 0) {
+			/* Should be continue next time we are called? */
+			if (!BIO_should_retry(b->next_bio)) {
+				ctx->cont = i;
+				i = EVP_CipherFinal_ex(&(ctx->cipher),
+				    (unsigned char *)ctx->buf,
+				    &(ctx->buf_len));
+				ctx->ok = i;
+				ctx->buf_off = 0;
+			} else {
+				ret = (ret == 0) ? i : ret;
+				break;
+			}
+		} else {
+			EVP_CipherUpdate(&(ctx->cipher),
+			    (unsigned char *)ctx->buf, &ctx->buf_len,
+			    (unsigned char *)&(ctx->buf[BUF_OFFSET]), i);
+			ctx->cont = 1;
+			/* Note: it is possible for EVP_CipherUpdate to
+			 * decrypt zero bytes because this is or looks like
+			 * the final block: if this happens we should retry
+			 * and either read more data or decrypt the final
+			 * block
+			 */
+			if (ctx->buf_len == 0)
+				continue;
+		}
+
+		if (ctx->buf_len <= outl)
+			i = ctx->buf_len;
+		else
+			i = outl;
+		if (i <= 0)
+			break;
+		memcpy(out, ctx->buf, i);
+		ret += i;
+		ctx->buf_off = i;
+		outl -= i;
+		out += i;
+	}
+
+	BIO_clear_retry_flags(b);
+	BIO_copy_next_retry(b);
+	return ((ret == 0) ? ctx->cont : ret);
+}
+
+static int
+enc_write(BIO *b, const char *in, int inl)
+{
+	int ret = 0, n, i;
+	BIO_ENC_CTX *ctx;
+
+	ctx = (BIO_ENC_CTX *)b->ptr;
+	ret = inl;
+
+	BIO_clear_retry_flags(b);
+	n = ctx->buf_len - ctx->buf_off;
+	while (n > 0) {
+		i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
+		if (i <= 0) {
+			BIO_copy_next_retry(b);
+			return (i);
+		}
+		ctx->buf_off += i;
+		n -= i;
+	}
+	/* at this point all pending data has been written */
+
+	if ((in == NULL) || (inl <= 0))
+		return (0);
+
+	ctx->buf_off = 0;
+	while (inl > 0) {
+		n = (inl > ENC_BLOCK_SIZE) ? ENC_BLOCK_SIZE : inl;
+		EVP_CipherUpdate(&(ctx->cipher),
+		    (unsigned char *)ctx->buf, &ctx->buf_len,
+		    (unsigned char *)in, n);
+		inl -= n;
+		in += n;
+
+		ctx->buf_off = 0;
+		n = ctx->buf_len;
+		while (n > 0) {
+			i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
+			if (i <= 0) {
+				BIO_copy_next_retry(b);
+				return (ret == inl) ? i : ret - inl;
+			}
+			n -= i;
+			ctx->buf_off += i;
+		}
+		ctx->buf_len = 0;
+		ctx->buf_off = 0;
+	}
+	BIO_copy_next_retry(b);
+	return (ret);
+}
+
+static long
+enc_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+	BIO *dbio;
+	BIO_ENC_CTX *ctx, *dctx;
+	long ret = 1;
+	int i;
+	EVP_CIPHER_CTX **c_ctx;
+
+	ctx = (BIO_ENC_CTX *)b->ptr;
+
+	switch (cmd) {
+	case BIO_CTRL_RESET:
+		ctx->ok = 1;
+		ctx->finished = 0;
+		EVP_CipherInit_ex(&(ctx->cipher), NULL, NULL, NULL, NULL,
+		    ctx->cipher.encrypt);
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		break;
+	case BIO_CTRL_EOF:	/* More to read */
+		if (ctx->cont <= 0)
+			ret = 1;
+		else
+			ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		break;
+	case BIO_CTRL_WPENDING:
+		ret = ctx->buf_len - ctx->buf_off;
+		if (ret <= 0)
+			ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		break;
+	case BIO_CTRL_PENDING: /* More to read in buffer */
+		ret = ctx->buf_len - ctx->buf_off;
+		if (ret <= 0)
+			ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		break;
+	case BIO_CTRL_FLUSH:
+		/* do a final write */
+again:
+		while (ctx->buf_len != ctx->buf_off) {
+			i = enc_write(b, NULL, 0);
+			if (i < 0)
+				return i;
+		}
+
+		if (!ctx->finished) {
+			ctx->finished = 1;
+			ctx->buf_off = 0;
+			ret = EVP_CipherFinal_ex(&(ctx->cipher),
+			    (unsigned char *)ctx->buf,
+			    &(ctx->buf_len));
+			ctx->ok = (int)ret;
+			if (ret <= 0)
+				break;
+
+			/* push out the bytes */
+			goto again;
+		}
+
+		/* Finally flush the underlying BIO */
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		break;
+	case BIO_C_GET_CIPHER_STATUS:
+		ret = (long)ctx->ok;
+		break;
+	case BIO_C_DO_STATE_MACHINE:
+		BIO_clear_retry_flags(b);
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		BIO_copy_next_retry(b);
+		break;
+	case BIO_C_GET_CIPHER_CTX:
+		c_ctx = (EVP_CIPHER_CTX **)ptr;
+		(*c_ctx) = &(ctx->cipher);
+		b->init = 1;
+		break;
+	case BIO_CTRL_DUP:
+		dbio = (BIO *)ptr;
+		dctx = (BIO_ENC_CTX *)dbio->ptr;
+		EVP_CIPHER_CTX_init(&dctx->cipher);
+		ret = EVP_CIPHER_CTX_copy(&dctx->cipher, &ctx->cipher);
+		if (ret)
+			dbio->init = 1;
+		break;
+	default:
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		break;
+	}
+	return (ret);
+}
+
+static long
+enc_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+	long ret = 1;
+
+	if (b->next_bio == NULL)
+		return (0);
+	switch (cmd) {
+	default:
+		ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+		break;
+	}
+	return (ret);
+}
+
+/*
+void BIO_set_cipher_ctx(b,c)
+BIO *b;
+EVP_CIPHER_ctx *c;
+	{
+	if (b == NULL) return;
+
+	if ((b->callback != NULL) &&
+		(b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0))
+		return;
+
+	b->init=1;
+	ctx=(BIO_ENC_CTX *)b->ptr;
+	memcpy(ctx->cipher,c,sizeof(EVP_CIPHER_CTX));
+
+	if (b->callback != NULL)
+		b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L);
+	}
+*/
+
+void
+BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
+    const unsigned char *i, int e)
+{
+	BIO_ENC_CTX *ctx;
+
+	if (b == NULL)
+		return;
+
+	if ((b->callback != NULL) &&
+	    (b->callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 0L) <= 0))
+		return;
+
+	b->init = 1;
+	ctx = (BIO_ENC_CTX *)b->ptr;
+	EVP_CipherInit_ex(&(ctx->cipher), c, NULL, k, i, e);
+
+	if (b->callback != NULL)
+		b->callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 1L);
+}
diff --git a/crypto/libressl/crypto/evp/bio_md.c b/crypto/libressl/crypto/evp/bio_md.c
new file mode 100644
index 0000000000..528c7cbea7
--- /dev/null
+++ b/crypto/libressl/crypto/evp/bio_md.c
@@ -0,0 +1,277 @@
+/* $OpenBSD: bio_md.c,v 1.13 2014/06/12 15:49:29 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+
+/* BIO_put and BIO_get both add to the digest,
+ * BIO_gets returns the digest */
+
+static int md_write(BIO *h, char const *buf, int num);
+static int md_read(BIO *h, char *buf, int size);
+/*static int md_puts(BIO *h, const char *str); */
+static int md_gets(BIO *h, char *str, int size);
+static long md_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int md_new(BIO *h);
+static int md_free(BIO *data);
+static long md_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+
+static BIO_METHOD methods_md = {
+	.type = BIO_TYPE_MD,
+	.name = "message digest",
+	.bwrite = md_write,
+	.bread = md_read,
+	.bgets = md_gets,
+	.ctrl = md_ctrl,
+	.create = md_new,
+	.destroy = md_free,
+	.callback_ctrl = md_callback_ctrl
+};
+
+BIO_METHOD *
+BIO_f_md(void)
+{
+	return (&methods_md);
+}
+
+static int
+md_new(BIO *bi)
+{
+	EVP_MD_CTX *ctx;
+
+	ctx = EVP_MD_CTX_create();
+	if (ctx == NULL)
+		return (0);
+
+	bi->init = 0;
+	bi->ptr = (char *)ctx;
+	bi->flags = 0;
+	return (1);
+}
+
+static int
+md_free(BIO *a)
+{
+	if (a == NULL)
+		return (0);
+	EVP_MD_CTX_destroy(a->ptr);
+	a->ptr = NULL;
+	a->init = 0;
+	a->flags = 0;
+	return (1);
+}
+
+static int
+md_read(BIO *b, char *out, int outl)
+{
+	int ret = 0;
+	EVP_MD_CTX *ctx;
+
+	if (out == NULL)
+		return (0);
+	ctx = b->ptr;
+
+	if ((ctx == NULL) || (b->next_bio == NULL))
+		return (0);
+
+	ret = BIO_read(b->next_bio, out, outl);
+	if (b->init) {
+		if (ret > 0) {
+			if (EVP_DigestUpdate(ctx, (unsigned char *)out,
+			    (unsigned int)ret) <= 0)
+				return (-1);
+		}
+	}
+	BIO_clear_retry_flags(b);
+	BIO_copy_next_retry(b);
+	return (ret);
+}
+
+static int
+md_write(BIO *b, const char *in, int inl)
+{
+	int ret = 0;
+	EVP_MD_CTX *ctx;
+
+	if ((in == NULL) || (inl <= 0))
+		return (0);
+	ctx = b->ptr;
+
+	if ((ctx != NULL) && (b->next_bio != NULL))
+		ret = BIO_write(b->next_bio, in, inl);
+	if (b->init) {
+		if (ret > 0) {
+			if (!EVP_DigestUpdate(ctx, (const unsigned char *)in,
+			    (unsigned int)ret)) {
+				BIO_clear_retry_flags(b);
+				return 0;
+			}
+		}
+	}
+	if (b->next_bio != NULL) {
+		BIO_clear_retry_flags(b);
+		BIO_copy_next_retry(b);
+	}
+	return (ret);
+}
+
+static long
+md_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+	EVP_MD_CTX *ctx, *dctx, **pctx;
+	const EVP_MD **ppmd;
+	EVP_MD *md;
+	long ret = 1;
+	BIO *dbio;
+
+	ctx = b->ptr;
+
+	switch (cmd) {
+	case BIO_CTRL_RESET:
+		if (b->init)
+			ret = EVP_DigestInit_ex(ctx, ctx->digest, NULL);
+		else
+			ret = 0;
+		if (ret > 0)
+			ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		break;
+	case BIO_C_GET_MD:
+		if (b->init) {
+			ppmd = ptr;
+			*ppmd = ctx->digest;
+		} else
+			ret = 0;
+		break;
+	case BIO_C_GET_MD_CTX:
+		pctx = ptr;
+		*pctx = ctx;
+		b->init = 1;
+		break;
+	case BIO_C_SET_MD_CTX:
+		if (b->init)
+			b->ptr = ptr;
+		else
+			ret = 0;
+		break;
+	case BIO_C_DO_STATE_MACHINE:
+		BIO_clear_retry_flags(b);
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		BIO_copy_next_retry(b);
+		break;
+
+	case BIO_C_SET_MD:
+		md = ptr;
+		ret = EVP_DigestInit_ex(ctx, md, NULL);
+		if (ret > 0)
+			b->init = 1;
+		break;
+	case BIO_CTRL_DUP:
+		dbio = ptr;
+		dctx = dbio->ptr;
+		if (!EVP_MD_CTX_copy_ex(dctx, ctx))
+			return 0;
+		b->init = 1;
+		break;
+	default:
+		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+		break;
+	}
+	return (ret);
+}
+
+static long
+md_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+	long ret = 1;
+
+	if (b->next_bio == NULL)
+		return (0);
+	switch (cmd) {
+	default:
+		ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+		break;
+	}
+	return (ret);
+}
+
+static int
+md_gets(BIO *bp, char *buf, int size)
+{
+	EVP_MD_CTX *ctx;
+	unsigned int ret;
+
+	ctx = bp->ptr;
+	if (size < ctx->digest->md_size)
+		return (0);
+	if (EVP_DigestFinal_ex(ctx, (unsigned char *)buf, &ret) <= 0)
+		return -1;
+
+	return ((int)ret);
+}
+
+/*
+static int md_puts(bp,str)
+BIO *bp;
+char *str;
+	{
+	return(-1);
+	}
+*/
diff --git a/crypto/libressl/crypto/evp/c_all.c b/crypto/libressl/crypto/evp/c_all.c
new file mode 100644
index 0000000000..a98c661617
--- /dev/null
+++ b/crypto/libressl/crypto/evp/c_all.c
@@ -0,0 +1,298 @@
+/* $OpenBSD: c_all.c,v 1.19 2015/09/13 23:36:21 doug Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include "cryptlib.h"
+
+void
+OpenSSL_add_all_ciphers(void)
+{
+#ifndef OPENSSL_NO_DES
+	EVP_add_cipher(EVP_des_cfb());
+	EVP_add_cipher(EVP_des_cfb1());
+	EVP_add_cipher(EVP_des_cfb8());
+	EVP_add_cipher(EVP_des_ede_cfb());
+	EVP_add_cipher(EVP_des_ede3_cfb());
+	EVP_add_cipher(EVP_des_ede3_cfb1());
+	EVP_add_cipher(EVP_des_ede3_cfb8());
+
+	EVP_add_cipher(EVP_des_ofb());
+	EVP_add_cipher(EVP_des_ede_ofb());
+	EVP_add_cipher(EVP_des_ede3_ofb());
+
+	EVP_add_cipher(EVP_desx_cbc());
+	EVP_add_cipher_alias(SN_desx_cbc, "DESX");
+	EVP_add_cipher_alias(SN_desx_cbc, "desx");
+
+	EVP_add_cipher(EVP_des_cbc());
+	EVP_add_cipher_alias(SN_des_cbc, "DES");
+	EVP_add_cipher_alias(SN_des_cbc, "des");
+	EVP_add_cipher(EVP_des_ede_cbc());
+	EVP_add_cipher(EVP_des_ede3_cbc());
+	EVP_add_cipher_alias(SN_des_ede3_cbc, "DES3");
+	EVP_add_cipher_alias(SN_des_ede3_cbc, "des3");
+
+	EVP_add_cipher(EVP_des_ecb());
+	EVP_add_cipher(EVP_des_ede());
+	EVP_add_cipher(EVP_des_ede3());
+#endif
+
+#ifndef OPENSSL_NO_RC4
+	EVP_add_cipher(EVP_rc4());
+	EVP_add_cipher(EVP_rc4_40());
+#ifndef OPENSSL_NO_MD5
+	EVP_add_cipher(EVP_rc4_hmac_md5());
+#endif
+#endif
+
+#ifndef OPENSSL_NO_IDEA
+	EVP_add_cipher(EVP_idea_ecb());
+	EVP_add_cipher(EVP_idea_cfb());
+	EVP_add_cipher(EVP_idea_ofb());
+	EVP_add_cipher(EVP_idea_cbc());
+	EVP_add_cipher_alias(SN_idea_cbc, "IDEA");
+	EVP_add_cipher_alias(SN_idea_cbc, "idea");
+#endif
+
+#ifndef OPENSSL_NO_RC2
+	EVP_add_cipher(EVP_rc2_ecb());
+	EVP_add_cipher(EVP_rc2_cfb());
+	EVP_add_cipher(EVP_rc2_ofb());
+	EVP_add_cipher(EVP_rc2_cbc());
+	EVP_add_cipher(EVP_rc2_40_cbc());
+	EVP_add_cipher(EVP_rc2_64_cbc());
+	EVP_add_cipher_alias(SN_rc2_cbc, "RC2");
+	EVP_add_cipher_alias(SN_rc2_cbc, "rc2");
+#endif
+
+#ifndef OPENSSL_NO_BF
+	EVP_add_cipher(EVP_bf_ecb());
+	EVP_add_cipher(EVP_bf_cfb());
+	EVP_add_cipher(EVP_bf_ofb());
+	EVP_add_cipher(EVP_bf_cbc());
+	EVP_add_cipher_alias(SN_bf_cbc, "BF");
+	EVP_add_cipher_alias(SN_bf_cbc, "bf");
+	EVP_add_cipher_alias(SN_bf_cbc, "blowfish");
+#endif
+
+#ifndef OPENSSL_NO_CAST
+	EVP_add_cipher(EVP_cast5_ecb());
+	EVP_add_cipher(EVP_cast5_cfb());
+	EVP_add_cipher(EVP_cast5_ofb());
+	EVP_add_cipher(EVP_cast5_cbc());
+	EVP_add_cipher_alias(SN_cast5_cbc, "CAST");
+	EVP_add_cipher_alias(SN_cast5_cbc, "cast");
+	EVP_add_cipher_alias(SN_cast5_cbc, "CAST-cbc");
+	EVP_add_cipher_alias(SN_cast5_cbc, "cast-cbc");
+#endif
+
+#ifndef OPENSSL_NO_AES
+	EVP_add_cipher(EVP_aes_128_ecb());
+	EVP_add_cipher(EVP_aes_128_cbc());
+	EVP_add_cipher(EVP_aes_128_cfb());
+	EVP_add_cipher(EVP_aes_128_cfb1());
+	EVP_add_cipher(EVP_aes_128_cfb8());
+	EVP_add_cipher(EVP_aes_128_ofb());
+	EVP_add_cipher(EVP_aes_128_ctr());
+	EVP_add_cipher(EVP_aes_128_gcm());
+	EVP_add_cipher(EVP_aes_128_xts());
+	EVP_add_cipher_alias(SN_aes_128_cbc, "AES128");
+	EVP_add_cipher_alias(SN_aes_128_cbc, "aes128");
+	EVP_add_cipher(EVP_aes_192_ecb());
+	EVP_add_cipher(EVP_aes_192_cbc());
+	EVP_add_cipher(EVP_aes_192_cfb());
+	EVP_add_cipher(EVP_aes_192_cfb1());
+	EVP_add_cipher(EVP_aes_192_cfb8());
+	EVP_add_cipher(EVP_aes_192_ofb());
+	EVP_add_cipher(EVP_aes_192_ctr());
+	EVP_add_cipher(EVP_aes_192_gcm());
+	EVP_add_cipher_alias(SN_aes_192_cbc, "AES192");
+	EVP_add_cipher_alias(SN_aes_192_cbc, "aes192");
+	EVP_add_cipher(EVP_aes_256_ecb());
+	EVP_add_cipher(EVP_aes_256_cbc());
+	EVP_add_cipher(EVP_aes_256_cfb());
+	EVP_add_cipher(EVP_aes_256_cfb1());
+	EVP_add_cipher(EVP_aes_256_cfb8());
+	EVP_add_cipher(EVP_aes_256_ofb());
+	EVP_add_cipher(EVP_aes_256_ctr());
+	EVP_add_cipher(EVP_aes_256_gcm());
+	EVP_add_cipher(EVP_aes_256_xts());
+	EVP_add_cipher_alias(SN_aes_256_cbc, "AES256");
+	EVP_add_cipher_alias(SN_aes_256_cbc, "aes256");
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
+	EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1());
+	EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
+#endif
+#endif
+
+#ifndef OPENSSL_NO_CAMELLIA
+	EVP_add_cipher(EVP_camellia_128_ecb());
+	EVP_add_cipher(EVP_camellia_128_cbc());
+	EVP_add_cipher(EVP_camellia_128_cfb());
+	EVP_add_cipher(EVP_camellia_128_cfb1());
+	EVP_add_cipher(EVP_camellia_128_cfb8());
+	EVP_add_cipher(EVP_camellia_128_ofb());
+	EVP_add_cipher_alias(SN_camellia_128_cbc, "CAMELLIA128");
+	EVP_add_cipher_alias(SN_camellia_128_cbc, "camellia128");
+	EVP_add_cipher(EVP_camellia_192_ecb());
+	EVP_add_cipher(EVP_camellia_192_cbc());
+	EVP_add_cipher(EVP_camellia_192_cfb());
+	EVP_add_cipher(EVP_camellia_192_cfb1());
+	EVP_add_cipher(EVP_camellia_192_cfb8());
+	EVP_add_cipher(EVP_camellia_192_ofb());
+	EVP_add_cipher_alias(SN_camellia_192_cbc, "CAMELLIA192");
+	EVP_add_cipher_alias(SN_camellia_192_cbc, "camellia192");
+	EVP_add_cipher(EVP_camellia_256_ecb());
+	EVP_add_cipher(EVP_camellia_256_cbc());
+	EVP_add_cipher(EVP_camellia_256_cfb());
+	EVP_add_cipher(EVP_camellia_256_cfb1());
+	EVP_add_cipher(EVP_camellia_256_cfb8());
+	EVP_add_cipher(EVP_camellia_256_ofb());
+	EVP_add_cipher_alias(SN_camellia_256_cbc, "CAMELLIA256");
+	EVP_add_cipher_alias(SN_camellia_256_cbc, "camellia256");
+#endif
+
+#ifndef OPENSSL_NO_CHACHA
+	EVP_add_cipher(EVP_chacha20());
+#endif
+
+#ifndef OPENSSL_NO_GOST
+	EVP_add_cipher(EVP_gost2814789_ecb());
+	EVP_add_cipher(EVP_gost2814789_cfb64());
+	EVP_add_cipher(EVP_gost2814789_cnt());
+#endif
+}
+
+void
+OpenSSL_add_all_digests(void)
+{
+#ifndef OPENSSL_NO_MD4
+	EVP_add_digest(EVP_md4());
+#endif
+
+#ifndef OPENSSL_NO_MD5
+	EVP_add_digest(EVP_md5());
+	EVP_add_digest_alias(SN_md5, "ssl2-md5");
+	EVP_add_digest_alias(SN_md5, "ssl3-md5");
+#endif
+
+#if !defined(OPENSSL_NO_SHA)
+#ifndef OPENSSL_NO_DSA
+	EVP_add_digest(EVP_dss());
+#endif
+#endif
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
+	EVP_add_digest(EVP_sha1());
+	EVP_add_digest_alias(SN_sha1, "ssl3-sha1");
+	EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA);
+#ifndef OPENSSL_NO_DSA
+	EVP_add_digest(EVP_dss1());
+	EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2);
+	EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1");
+	EVP_add_digest_alias(SN_dsaWithSHA1, "dss1");
+#endif
+#ifndef OPENSSL_NO_ECDSA
+	EVP_add_digest(EVP_ecdsa());
+#endif
+#endif
+
+#ifndef OPENSSL_NO_GOST
+	EVP_add_digest(EVP_gostr341194());
+	EVP_add_digest(EVP_gost2814789imit());
+	EVP_add_digest(EVP_streebog256());
+	EVP_add_digest(EVP_streebog512());
+#endif
+#ifndef OPENSSL_NO_RIPEMD
+	EVP_add_digest(EVP_ripemd160());
+	EVP_add_digest_alias(SN_ripemd160, "ripemd");
+	EVP_add_digest_alias(SN_ripemd160, "rmd160");
+#endif
+#ifndef OPENSSL_NO_SHA256
+	EVP_add_digest(EVP_sha224());
+	EVP_add_digest(EVP_sha256());
+#endif
+#ifndef OPENSSL_NO_SHA512
+	EVP_add_digest(EVP_sha384());
+	EVP_add_digest(EVP_sha512());
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+	EVP_add_digest(EVP_whirlpool());
+#endif
+}
+
+void
+OPENSSL_add_all_algorithms_noconf(void)
+{
+	OPENSSL_cpuid_setup();
+	OpenSSL_add_all_ciphers();
+	OpenSSL_add_all_digests();
+}
+
+void
+OPENSSL_add_all_algorithms_conf(void)
+{
+	OPENSSL_add_all_algorithms_noconf();
+	OPENSSL_config(NULL);
+}
diff --git a/crypto/libressl/crypto/evp/digest.c b/crypto/libressl/crypto/evp/digest.c
new file mode 100644
index 0000000000..ea0b168907
--- /dev/null
+++ b/crypto/libressl/crypto/evp/digest.c
@@ -0,0 +1,405 @@
+/* $OpenBSD: digest.c,v 1.25 2015/02/10 09:52:35 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+
+void
+EVP_MD_CTX_init(EVP_MD_CTX *ctx)
+{
+	memset(ctx, 0, sizeof *ctx);
+}
+
+EVP_MD_CTX *
+EVP_MD_CTX_create(void)
+{
+	return calloc(1, sizeof(EVP_MD_CTX));
+}
+
+int
+EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
+{
+	EVP_MD_CTX_init(ctx);
+	return EVP_DigestInit_ex(ctx, type, NULL);
+}
+
+int
+EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
+{
+	EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
+
+#ifndef OPENSSL_NO_ENGINE
+	/* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
+	 * so this context may already have an ENGINE! Try to avoid releasing
+	 * the previous handle, re-querying for an ENGINE, and having a
+	 * reinitialisation, when it may all be unecessary. */
+	if (ctx->engine && ctx->digest && (!type ||
+	    (type && (type->type == ctx->digest->type))))
+		goto skip_to_init;
+	if (type) {
+		/* Ensure an ENGINE left lying around from last time is cleared
+		 * (the previous check attempted to avoid this if the same
+		 * ENGINE and EVP_MD could be used). */
+		if (ctx->engine)
+			ENGINE_finish(ctx->engine);
+		if (impl) {
+			if (!ENGINE_init(impl)) {
+				EVPerr(EVP_F_EVP_DIGESTINIT_EX,
+				    EVP_R_INITIALIZATION_ERROR);
+				return 0;
+			}
+		} else
+			/* Ask if an ENGINE is reserved for this job */
+			impl = ENGINE_get_digest_engine(type->type);
+		if (impl) {
+			/* There's an ENGINE for this job ... (apparently) */
+			const EVP_MD *d = ENGINE_get_digest(impl, type->type);
+			if (!d) {
+				/* Same comment from evp_enc.c */
+				EVPerr(EVP_F_EVP_DIGESTINIT_EX,
+				    EVP_R_INITIALIZATION_ERROR);
+				ENGINE_finish(impl);
+				return 0;
+			}
+			/* We'll use the ENGINE's private digest definition */
+			type = d;
+			/* Store the ENGINE functional reference so we know
+			 * 'type' came from an ENGINE and we need to release
+			 * it when done. */
+			ctx->engine = impl;
+		} else
+			ctx->engine = NULL;
+	} else if (!ctx->digest) {
+		EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_NO_DIGEST_SET);
+		return 0;
+	}
+#endif
+	if (ctx->digest != type) {
+		if (ctx->digest && ctx->digest->ctx_size && ctx->md_data &&
+		    !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) {
+			explicit_bzero(ctx->md_data, ctx->digest->ctx_size);
+			free(ctx->md_data);
+			ctx->md_data = NULL;
+		}
+		ctx->digest = type;
+		if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) {
+			ctx->update = type->update;
+			ctx->md_data = malloc(type->ctx_size);
+			if (ctx->md_data == NULL) {
+				EVP_PKEY_CTX_free(ctx->pctx);
+				ctx->pctx = NULL;
+				EVPerr(EVP_F_EVP_DIGESTINIT_EX,
+				    ERR_R_MALLOC_FAILURE);
+				return 0;
+			}
+		}
+	}
+#ifndef OPENSSL_NO_ENGINE
+skip_to_init:
+#endif
+	if (ctx->pctx) {
+		int r;
+		r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
+		    EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
+		if (r <= 0 && (r != -2))
+			return 0;
+	}
+	if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
+		return 1;
+	return ctx->digest->init(ctx);
+}
+
+int
+EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+	return ctx->update(ctx, data, count);
+}
+
+/* The caller can assume that this removes any secret data from the context */
+int
+EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
+{
+	int ret;
+
+	ret = EVP_DigestFinal_ex(ctx, md, size);
+	EVP_MD_CTX_cleanup(ctx);
+	return ret;
+}
+
+/* The caller can assume that this removes any secret data from the context */
+int
+EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
+{
+	int ret;
+
+	if ((size_t)ctx->digest->md_size > EVP_MAX_MD_SIZE) {
+		EVPerr(EVP_F_EVP_DIGESTFINAL_EX, EVP_R_TOO_LARGE);
+		return 0;
+	}
+	ret = ctx->digest->final(ctx, md);
+	if (size != NULL)
+		*size = ctx->digest->md_size;
+	if (ctx->digest->cleanup) {
+		ctx->digest->cleanup(ctx);
+		EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
+	}
+	memset(ctx->md_data, 0, ctx->digest->ctx_size);
+	return ret;
+}
+
+int
+EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
+{
+	EVP_MD_CTX_init(out);
+	return EVP_MD_CTX_copy_ex(out, in);
+}
+
+int
+EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
+{
+	unsigned char *tmp_buf;
+
+	if ((in == NULL) || (in->digest == NULL)) {
+		EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_INPUT_NOT_INITIALIZED);
+		return 0;
+	}
+#ifndef OPENSSL_NO_ENGINE
+	/* Make sure it's safe to copy a digest context using an ENGINE */
+	if (in->engine && !ENGINE_init(in->engine)) {
+		EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_ENGINE_LIB);
+		return 0;
+	}
+#endif
+
+	if (out->digest == in->digest) {
+		tmp_buf = out->md_data;
+		EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE);
+	} else
+		tmp_buf = NULL;
+	EVP_MD_CTX_cleanup(out);
+	memcpy(out, in, sizeof *out);
+
+	if (in->md_data && out->digest->ctx_size) {
+		if (tmp_buf)
+			out->md_data = tmp_buf;
+		else {
+			out->md_data = malloc(out->digest->ctx_size);
+			if (!out->md_data) {
+				EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,
+				    ERR_R_MALLOC_FAILURE);
+				return 0;
+			}
+		}
+		memcpy(out->md_data, in->md_data, out->digest->ctx_size);
+	}
+
+	out->update = in->update;
+
+	if (in->pctx) {
+		out->pctx = EVP_PKEY_CTX_dup(in->pctx);
+		if (!out->pctx) {
+			EVP_MD_CTX_cleanup(out);
+			return 0;
+		}
+	}
+
+	if (out->digest->copy)
+		return out->digest->copy(out, in);
+
+	return 1;
+}
+
+int
+EVP_Digest(const void *data, size_t count,
+    unsigned char *md, unsigned int *size, const EVP_MD *type, ENGINE *impl)
+{
+	EVP_MD_CTX ctx;
+	int ret;
+
+	EVP_MD_CTX_init(&ctx);
+	EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_ONESHOT);
+	ret = EVP_DigestInit_ex(&ctx, type, impl) &&
+	    EVP_DigestUpdate(&ctx, data, count) &&
+	    EVP_DigestFinal_ex(&ctx, md, size);
+	EVP_MD_CTX_cleanup(&ctx);
+
+	return ret;
+}
+
+void
+EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
+{
+	if (ctx) {
+		EVP_MD_CTX_cleanup(ctx);
+		free(ctx);
+	}
+}
+
+/* This call frees resources associated with the context */
+int
+EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
+{
+	/* Don't assume ctx->md_data was cleaned in EVP_Digest_Final,
+	 * because sometimes only copies of the context are ever finalised.
+	 */
+	if (ctx->digest && ctx->digest->cleanup &&
+	    !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
+		ctx->digest->cleanup(ctx);
+	if (ctx->digest && ctx->digest->ctx_size && ctx->md_data &&
+	    !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) {
+		explicit_bzero(ctx->md_data, ctx->digest->ctx_size);
+		free(ctx->md_data);
+	}
+	EVP_PKEY_CTX_free(ctx->pctx);
+#ifndef OPENSSL_NO_ENGINE
+	if (ctx->engine)
+		/* The EVP_MD we used belongs to an ENGINE, release the
+		 * functional reference we held for this reason. */
+		ENGINE_finish(ctx->engine);
+#endif
+	memset(ctx, 0, sizeof *ctx);
+
+	return 1;
+}
+
+int
+EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr)
+{
+	int ret;
+
+	if (!ctx->digest) {
+		EVPerr(EVP_F_EVP_MD_CTX_CTRL, EVP_R_NO_CIPHER_SET);
+		return 0;
+	}
+
+	if (!ctx->digest->md_ctrl) {
+		EVPerr(EVP_F_EVP_MD_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
+		return 0;
+	}
+
+	ret = ctx->digest->md_ctrl(ctx, type, arg, ptr);
+	if (ret == -1) {
+		EVPerr(EVP_F_EVP_MD_CTX_CTRL,
+		    EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
+		return 0;
+	}
+	return ret;
+}
diff --git a/crypto/libressl/crypto/evp/e_aes.c b/crypto/libressl/crypto/evp/e_aes.c
new file mode 100644
index 0000000000..ba8681a115
--- /dev/null
+++ b/crypto/libressl/crypto/evp/e_aes.c
@@ -0,0 +1,1548 @@
+/* $OpenBSD: e_aes.c,v 1.28 2015/06/20 12:01:14 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 2001-2011 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include 
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_AES
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+#include "modes_lcl.h"
+
+typedef struct {
+	AES_KEY ks;
+	block128_f block;
+	union {
+		cbc128_f cbc;
+		ctr128_f ctr;
+	} stream;
+} EVP_AES_KEY;
+
+typedef struct {
+	AES_KEY ks;		/* AES key schedule to use */
+	int key_set;		/* Set if key initialised */
+	int iv_set;		/* Set if an iv is set */
+	GCM128_CONTEXT gcm;
+	unsigned char *iv;	/* Temporary IV store */
+	int ivlen;		/* IV length */
+	int taglen;
+	int iv_gen;		/* It is OK to generate IVs */
+	int tls_aad_len;	/* TLS AAD length */
+	ctr128_f ctr;
+} EVP_AES_GCM_CTX;
+
+typedef struct {
+	AES_KEY ks1, ks2;	/* AES key schedules to use */
+	XTS128_CONTEXT xts;
+	void (*stream)(const unsigned char *in, unsigned char *out,
+	    size_t length, const AES_KEY *key1, const AES_KEY *key2,
+	    const unsigned char iv[16]);
+} EVP_AES_XTS_CTX;
+
+typedef struct {
+	AES_KEY ks;		/* AES key schedule to use */
+	int key_set;		/* Set if key initialised */
+	int iv_set;		/* Set if an iv is set */
+	int tag_set;		/* Set if tag is valid */
+	int len_set;		/* Set if message length set */
+	int L, M;		/* L and M parameters from RFC3610 */
+	CCM128_CONTEXT ccm;
+	ccm128_f str;
+} EVP_AES_CCM_CTX;
+
+#define MAXBITCHUNK	((size_t)1<<(sizeof(size_t)*8-4))
+
+#ifdef VPAES_ASM
+int vpaes_set_encrypt_key(const unsigned char *userKey, int bits,
+    AES_KEY *key);
+int vpaes_set_decrypt_key(const unsigned char *userKey, int bits,
+    AES_KEY *key);
+
+void vpaes_encrypt(const unsigned char *in, unsigned char *out,
+    const AES_KEY *key);
+void vpaes_decrypt(const unsigned char *in, unsigned char *out,
+    const AES_KEY *key);
+
+void vpaes_cbc_encrypt(const unsigned char *in, unsigned char *out,
+    size_t length, const AES_KEY *key, unsigned char *ivec, int enc);
+#endif
+#ifdef BSAES_ASM
+void bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out,
+    size_t length, const AES_KEY *key, unsigned char ivec[16], int enc);
+void bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
+    size_t len, const AES_KEY *key, const unsigned char ivec[16]);
+void bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out,
+    size_t len, const AES_KEY *key1, const AES_KEY *key2,
+    const unsigned char iv[16]);
+void bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out,
+    size_t len, const AES_KEY *key1, const AES_KEY *key2,
+    const unsigned char iv[16]);
+#endif
+#ifdef AES_CTR_ASM
+void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+    size_t blocks, const AES_KEY *key,
+    const unsigned char ivec[AES_BLOCK_SIZE]);
+#endif
+#ifdef AES_XTS_ASM
+void AES_xts_encrypt(const char *inp, char *out, size_t len,
+    const AES_KEY *key1, const AES_KEY *key2, const unsigned char iv[16]);
+void AES_xts_decrypt(const char *inp, char *out, size_t len,
+    const AES_KEY *key1, const AES_KEY *key2, const unsigned char iv[16]);
+#endif
+
+#if	defined(AES_ASM) && !defined(I386_ONLY) &&	(  \
+	((defined(__i386)	|| defined(__i386__)	|| \
+	  defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \
+	defined(__x86_64)	|| defined(__x86_64__)	|| \
+	defined(_M_AMD64)	|| defined(_M_X64)	|| \
+	defined(__INTEL__)				)
+
+extern unsigned int OPENSSL_ia32cap_P[2];
+
+#ifdef VPAES_ASM
+#define VPAES_CAPABLE	(OPENSSL_ia32cap_P[1]&(1<<(41-32)))
+#endif
+#ifdef BSAES_ASM
+#define BSAES_CAPABLE	VPAES_CAPABLE
+#endif
+/*
+ * AES-NI section
+ */
+#define	AESNI_CAPABLE	(OPENSSL_ia32cap_P[1]&(1<<(57-32)))
+
+int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
+    AES_KEY *key);
+int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
+    AES_KEY *key);
+
+void aesni_encrypt(const unsigned char *in, unsigned char *out,
+    const AES_KEY *key);
+void aesni_decrypt(const unsigned char *in, unsigned char *out,
+    const AES_KEY *key);
+
+void aesni_ecb_encrypt(const unsigned char *in, unsigned char *out,
+    size_t length, const AES_KEY *key, int enc);
+void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out,
+    size_t length, const AES_KEY *key, unsigned char *ivec, int enc);
+
+void aesni_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
+    size_t blocks, const void *key, const unsigned char *ivec);
+
+void aesni_xts_encrypt(const unsigned char *in, unsigned char *out,
+    size_t length, const AES_KEY *key1, const AES_KEY *key2,
+    const unsigned char iv[16]);
+
+void aesni_xts_decrypt(const unsigned char *in, unsigned char *out,
+    size_t length, const AES_KEY *key1, const AES_KEY *key2,
+    const unsigned char iv[16]);
+
+void aesni_ccm64_encrypt_blocks (const unsigned char *in, unsigned char *out,
+    size_t blocks, const void *key, const unsigned char ivec[16],
+    unsigned char cmac[16]);
+
+void aesni_ccm64_decrypt_blocks (const unsigned char *in, unsigned char *out,
+    size_t blocks, const void *key, const unsigned char ivec[16],
+    unsigned char cmac[16]);
+
+static int
+aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	int ret, mode;
+	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+	mode = ctx->cipher->flags & EVP_CIPH_MODE;
+	if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) &&
+	    !enc) {
+		ret = aesni_set_decrypt_key(key, ctx->key_len * 8,
+		    ctx->cipher_data);
+		dat->block = (block128_f)aesni_decrypt;
+		dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+		    (cbc128_f)aesni_cbc_encrypt : NULL;
+	} else {
+		ret = aesni_set_encrypt_key(key, ctx->key_len * 8,
+		    ctx->cipher_data);
+		dat->block = (block128_f)aesni_encrypt;
+		if (mode == EVP_CIPH_CBC_MODE)
+			dat->stream.cbc = (cbc128_f)aesni_cbc_encrypt;
+		else if (mode == EVP_CIPH_CTR_MODE)
+			dat->stream.ctr = (ctr128_f)aesni_ctr32_encrypt_blocks;
+		else
+			dat->stream.cbc = NULL;
+	}
+
+	if (ret < 0) {
+		EVPerr(EVP_F_AESNI_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED);
+		return 0;
+	}
+
+	return 1;
+}
+
+static int
+aesni_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len)
+{
+	aesni_cbc_encrypt(in, out, len, ctx->cipher_data, ctx->iv,
+	    ctx->encrypt);
+
+	return 1;
+}
+
+static int
+aesni_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len)
+{
+	size_t	bl = ctx->cipher->block_size;
+
+	if (len < bl)
+		return 1;
+
+	aesni_ecb_encrypt(in, out, len, ctx->cipher_data, ctx->encrypt);
+
+	return 1;
+}
+
+#define aesni_ofb_cipher aes_ofb_cipher
+static int aesni_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len);
+
+#define aesni_cfb_cipher aes_cfb_cipher
+static int aesni_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len);
+
+#define aesni_cfb8_cipher aes_cfb8_cipher
+static int aesni_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len);
+
+#define aesni_cfb1_cipher aes_cfb1_cipher
+static int aesni_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len);
+
+#define aesni_ctr_cipher aes_ctr_cipher
+static int aesni_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len);
+
+static int
+aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+
+	if (!iv && !key)
+		return 1;
+	if (key) {
+		aesni_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks);
+		CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
+		    (block128_f)aesni_encrypt);
+		gctx->ctr = (ctr128_f)aesni_ctr32_encrypt_blocks;
+		/* If we have an iv can set it directly, otherwise use
+		 * saved IV.
+		 */
+		if (iv == NULL && gctx->iv_set)
+			iv = gctx->iv;
+		if (iv) {
+			CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+			gctx->iv_set = 1;
+		}
+		gctx->key_set = 1;
+	} else {
+		/* If key set use IV, otherwise copy */
+		if (gctx->key_set)
+			CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+		else
+			memcpy(gctx->iv, iv, gctx->ivlen);
+		gctx->iv_set = 1;
+		gctx->iv_gen = 0;
+	}
+	return 1;
+}
+
+#define aesni_gcm_cipher aes_gcm_cipher
+static int aesni_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len);
+
+static int
+aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+
+	if (!iv && !key)
+		return 1;
+
+	if (key) {
+		/* key_len is two AES keys */
+		if (enc) {
+			aesni_set_encrypt_key(key, ctx->key_len * 4,
+			    &xctx->ks1);
+			xctx->xts.block1 = (block128_f)aesni_encrypt;
+			xctx->stream = aesni_xts_encrypt;
+		} else {
+			aesni_set_decrypt_key(key, ctx->key_len * 4,
+			    &xctx->ks1);
+			xctx->xts.block1 = (block128_f)aesni_decrypt;
+			xctx->stream = aesni_xts_decrypt;
+		}
+
+		aesni_set_encrypt_key(key + ctx->key_len / 2,
+		    ctx->key_len * 4, &xctx->ks2);
+		xctx->xts.block2 = (block128_f)aesni_encrypt;
+
+		xctx->xts.key1 = &xctx->ks1;
+	}
+
+	if (iv) {
+		xctx->xts.key2 = &xctx->ks2;
+		memcpy(ctx->iv, iv, 16);
+	}
+
+	return 1;
+}
+
+#define aesni_xts_cipher aes_xts_cipher
+static int aesni_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len);
+
+static int
+aesni_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
+
+	if (!iv && !key)
+		return 1;
+	if (key) {
+		aesni_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks);
+		CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+		    &cctx->ks, (block128_f)aesni_encrypt);
+		cctx->str = enc ? (ccm128_f)aesni_ccm64_encrypt_blocks :
+		    (ccm128_f)aesni_ccm64_decrypt_blocks;
+		cctx->key_set = 1;
+	}
+	if (iv) {
+		memcpy(ctx->iv, iv, 15 - cctx->L);
+		cctx->iv_set = 1;
+	}
+	return 1;
+}
+
+#define aesni_ccm_cipher aes_ccm_cipher
+static int aesni_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len);
+
+#define BLOCK_CIPHER_generic(n,keylen,blocksize,ivlen,nmode,mode,MODE,fl) \
+static const EVP_CIPHER aesni_##keylen##_##mode = {			\
+	.nid = n##_##keylen##_##nmode,					\
+	.block_size = blocksize,					\
+	.key_len = keylen / 8,						\
+	.iv_len = ivlen, 						\
+	.flags = fl | EVP_CIPH_##MODE##_MODE,				\
+	.init = aesni_init_key,						\
+	.do_cipher = aesni_##mode##_cipher,				\
+	.ctx_size = sizeof(EVP_AES_KEY)					\
+};									\
+static const EVP_CIPHER aes_##keylen##_##mode = {			\
+	.nid = n##_##keylen##_##nmode,					\
+	.block_size = blocksize,					\
+	.key_len = keylen / 8,						\
+	.iv_len = ivlen, 						\
+	.flags = fl | EVP_CIPH_##MODE##_MODE,				\
+	.init = aes_init_key,						\
+	.do_cipher = aes_##mode##_cipher,				\
+	.ctx_size = sizeof(EVP_AES_KEY)					\
+};									\
+const EVP_CIPHER *							\
+EVP_aes_##keylen##_##mode(void)						\
+{									\
+	return AESNI_CAPABLE ?						\
+	    &aesni_##keylen##_##mode : &aes_##keylen##_##mode;		\
+}
+
+#define BLOCK_CIPHER_custom(n,keylen,blocksize,ivlen,mode,MODE,fl)	\
+static const EVP_CIPHER aesni_##keylen##_##mode = {			\
+	.nid = n##_##keylen##_##mode,					\
+	.block_size = blocksize,					\
+	.key_len =							\
+	    (EVP_CIPH_##MODE##_MODE == EVP_CIPH_XTS_MODE ? 2 : 1) *	\
+	    keylen / 8,							\
+	.iv_len = ivlen,						\
+	.flags = fl | EVP_CIPH_##MODE##_MODE,				\
+	.init = aesni_##mode##_init_key,				\
+	.do_cipher = aesni_##mode##_cipher,				\
+	.cleanup = aes_##mode##_cleanup,				\
+	.ctx_size = sizeof(EVP_AES_##MODE##_CTX),			\
+	.ctrl = aes_##mode##_ctrl					\
+};									\
+static const EVP_CIPHER aes_##keylen##_##mode = {			\
+	.nid = n##_##keylen##_##mode,					\
+	.block_size = blocksize,					\
+	.key_len =							\
+	    (EVP_CIPH_##MODE##_MODE == EVP_CIPH_XTS_MODE ? 2 : 1) *	\
+	    keylen / 8,							\
+	.iv_len = ivlen,						\
+	.flags = fl | EVP_CIPH_##MODE##_MODE,				\
+	.init = aes_##mode##_init_key,					\
+	.do_cipher = aes_##mode##_cipher,				\
+	.cleanup = aes_##mode##_cleanup,				\
+	.ctx_size = sizeof(EVP_AES_##MODE##_CTX),			\
+	.ctrl = aes_##mode##_ctrl					\
+};									\
+const EVP_CIPHER *							\
+EVP_aes_##keylen##_##mode(void)						\
+{									\
+	return AESNI_CAPABLE ?						\
+	    &aesni_##keylen##_##mode : &aes_##keylen##_##mode;		\
+}
+
+#else
+
+#define BLOCK_CIPHER_generic(n,keylen,blocksize,ivlen,nmode,mode,MODE,fl) \
+static const EVP_CIPHER aes_##keylen##_##mode = {			\
+	.nid = n##_##keylen##_##nmode,					\
+	.block_size = blocksize,					\
+	.key_len = keylen / 8,						\
+	.iv_len = ivlen,						\
+	.flags = fl | EVP_CIPH_##MODE##_MODE,				\
+	.init = aes_init_key,						\
+	.do_cipher = aes_##mode##_cipher,				\
+	.ctx_size = sizeof(EVP_AES_KEY)					\
+};									\
+const EVP_CIPHER *							\
+EVP_aes_##keylen##_##mode(void)						\
+{									\
+	return &aes_##keylen##_##mode;					\
+}
+
+#define BLOCK_CIPHER_custom(n,keylen,blocksize,ivlen,mode,MODE,fl)	\
+static const EVP_CIPHER aes_##keylen##_##mode = {			\
+	.nid = n##_##keylen##_##mode,					\
+	.block_size = blocksize,					\
+	.key_len =							\
+	    (EVP_CIPH_##MODE##_MODE == EVP_CIPH_XTS_MODE ? 2 : 1) *	\
+	    keylen / 8,							\
+	.iv_len = ivlen,						\
+	.flags = fl | EVP_CIPH_##MODE##_MODE,				\
+	.init = aes_##mode##_init_key,					\
+	.do_cipher = aes_##mode##_cipher,				\
+	.cleanup = aes_##mode##_cleanup,				\
+	.ctx_size = sizeof(EVP_AES_##MODE##_CTX),			\
+	.ctrl = aes_##mode##_ctrl					\
+};									\
+const EVP_CIPHER *							\
+EVP_aes_##keylen##_##mode(void)						\
+{									\
+	return &aes_##keylen##_##mode;					\
+}
+
+#endif
+
+#define BLOCK_CIPHER_generic_pack(nid,keylen,flags)		\
+	BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)	\
+	BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)	\
+	BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)	\
+	BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)	\
+	BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags)	\
+	BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags)	\
+	BLOCK_CIPHER_generic(nid,keylen,1,16,ctr,ctr,CTR,flags)
+
+static int
+aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	int ret, mode;
+	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+	mode = ctx->cipher->flags & EVP_CIPH_MODE;
+	if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) &&
+	    !enc)
+#ifdef BSAES_CAPABLE
+		if (BSAES_CAPABLE && mode == EVP_CIPH_CBC_MODE) {
+			ret = AES_set_decrypt_key(key, ctx->key_len * 8,
+			    &dat->ks);
+			dat->block = (block128_f)AES_decrypt;
+			dat->stream.cbc = (cbc128_f)bsaes_cbc_encrypt;
+		} else
+#endif
+#ifdef VPAES_CAPABLE
+		if (VPAES_CAPABLE) {
+			ret = vpaes_set_decrypt_key(key, ctx->key_len * 8,
+			    &dat->ks);
+			dat->block = (block128_f)vpaes_decrypt;
+			dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+			    (cbc128_f)vpaes_cbc_encrypt : NULL;
+		} else
+#endif
+		{
+			ret = AES_set_decrypt_key(key, ctx->key_len * 8,
+			    &dat->ks);
+			dat->block = (block128_f)AES_decrypt;
+			dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+			    (cbc128_f)AES_cbc_encrypt : NULL;
+		} else
+#ifdef BSAES_CAPABLE
+		if (BSAES_CAPABLE && mode == EVP_CIPH_CTR_MODE) {
+			ret = AES_set_encrypt_key(key, ctx->key_len * 8,
+			    &dat->ks);
+			dat->block = (block128_f)AES_encrypt;
+			dat->stream.ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks;
+		} else
+#endif
+#ifdef VPAES_CAPABLE
+		if (VPAES_CAPABLE) {
+			ret = vpaes_set_encrypt_key(key, ctx->key_len * 8,
+			    &dat->ks);
+			dat->block = (block128_f)vpaes_encrypt;
+			dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+			    (cbc128_f)vpaes_cbc_encrypt : NULL;
+		} else
+#endif
+		{
+			ret = AES_set_encrypt_key(key, ctx->key_len * 8,
+			    &dat->ks);
+			dat->block = (block128_f)AES_encrypt;
+			dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+			    (cbc128_f)AES_cbc_encrypt : NULL;
+#ifdef AES_CTR_ASM
+			if (mode == EVP_CIPH_CTR_MODE)
+				dat->stream.ctr = (ctr128_f)AES_ctr32_encrypt;
+#endif
+		}
+
+	if (ret < 0) {
+		EVPerr(EVP_F_AES_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED);
+		return 0;
+	}
+
+	return 1;
+}
+
+static int
+aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len)
+{
+	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+	if (dat->stream.cbc)
+		(*dat->stream.cbc)(in, out, len, &dat->ks, ctx->iv,
+		    ctx->encrypt);
+	else if (ctx->encrypt)
+		CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv,
+		    dat->block);
+	else
+		CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, ctx->iv,
+		    dat->block);
+
+	return 1;
+}
+
+static int
+aes_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len)
+{
+	size_t	bl = ctx->cipher->block_size;
+	size_t	i;
+	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+	if (len < bl)
+		return 1;
+
+	for (i = 0, len -= bl; i <= len; i += bl)
+		(*dat->block)(in + i, out + i, &dat->ks);
+
+	return 1;
+}
+
+static int
+aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len)
+{
+	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+	CRYPTO_ofb128_encrypt(in, out, len, &dat->ks, ctx->iv, &ctx->num,
+	    dat->block);
+	return 1;
+}
+
+static int
+aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len)
+{
+	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+	CRYPTO_cfb128_encrypt(in, out, len, &dat->ks, ctx->iv, &ctx->num,
+	    ctx->encrypt, dat->block);
+	return 1;
+}
+
+static int
+aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len)
+{
+	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+	CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks, ctx->iv, &ctx->num,
+	    ctx->encrypt, dat->block);
+	return 1;
+}
+
+static int
+aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len)
+{
+	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+	if (ctx->flags&EVP_CIPH_FLAG_LENGTH_BITS) {
+		CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks, ctx->iv,
+		    &ctx->num, ctx->encrypt, dat->block);
+		return 1;
+	}
+
+	while (len >= MAXBITCHUNK) {
+		CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK*8, &dat->ks,
+		    ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+		len -= MAXBITCHUNK;
+	}
+	if (len)
+		CRYPTO_cfb128_1_encrypt(in, out, len*8, &dat->ks,
+		    ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+
+	return 1;
+}
+
+static int aes_ctr_cipher (EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len)
+{
+	unsigned int num = ctx->num;
+	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+	if (dat->stream.ctr)
+		CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks,
+		    ctx->iv, ctx->buf, &num, dat->stream.ctr);
+	else
+		CRYPTO_ctr128_encrypt(in, out, len, &dat->ks,
+		    ctx->iv, ctx->buf, &num, dat->block);
+	ctx->num = (size_t)num;
+	return 1;
+}
+
+BLOCK_CIPHER_generic_pack(NID_aes, 128, EVP_CIPH_FLAG_FIPS)
+BLOCK_CIPHER_generic_pack(NID_aes, 192, EVP_CIPH_FLAG_FIPS)
+BLOCK_CIPHER_generic_pack(NID_aes, 256, EVP_CIPH_FLAG_FIPS)
+
+static int
+aes_gcm_cleanup(EVP_CIPHER_CTX *c)
+{
+	EVP_AES_GCM_CTX *gctx = c->cipher_data;
+
+	if (gctx->iv != c->iv)
+		free(gctx->iv);
+	explicit_bzero(gctx, sizeof(*gctx));
+	return 1;
+}
+
+/* increment counter (64-bit int) by 1 */
+static void
+ctr64_inc(unsigned char *counter)
+{
+	int n = 8;
+	unsigned char  c;
+
+	do {
+		--n;
+		c = counter[n];
+		++c;
+		counter[n] = c;
+		if (c)
+			return;
+	} while (n);
+}
+
+static int
+aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+	EVP_AES_GCM_CTX *gctx = c->cipher_data;
+
+	switch (type) {
+	case EVP_CTRL_INIT:
+		gctx->key_set = 0;
+		gctx->iv_set = 0;
+		gctx->ivlen = c->cipher->iv_len;
+		gctx->iv = c->iv;
+		gctx->taglen = -1;
+		gctx->iv_gen = 0;
+		gctx->tls_aad_len = -1;
+		return 1;
+
+	case EVP_CTRL_GCM_SET_IVLEN:
+		if (arg <= 0)
+			return 0;
+		/* Allocate memory for IV if needed */
+		if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) {
+			if (gctx->iv != c->iv)
+				free(gctx->iv);
+			gctx->iv = malloc(arg);
+			if (!gctx->iv)
+				return 0;
+		}
+		gctx->ivlen = arg;
+		return 1;
+
+	case EVP_CTRL_GCM_SET_TAG:
+		if (arg <= 0 || arg > 16 || c->encrypt)
+			return 0;
+		memcpy(c->buf, ptr, arg);
+		gctx->taglen = arg;
+		return 1;
+
+	case EVP_CTRL_GCM_GET_TAG:
+		if (arg <= 0 || arg > 16 || !c->encrypt || gctx->taglen < 0)
+			return 0;
+		memcpy(ptr, c->buf, arg);
+		return 1;
+
+	case EVP_CTRL_GCM_SET_IV_FIXED:
+		/* Special case: -1 length restores whole IV */
+		if (arg == -1) {
+			memcpy(gctx->iv, ptr, gctx->ivlen);
+			gctx->iv_gen = 1;
+			return 1;
+		}
+		/* Fixed field must be at least 4 bytes and invocation field
+		 * at least 8.
+		 */
+		if ((arg < 4) || (gctx->ivlen - arg) < 8)
+			return 0;
+		if (arg)
+			memcpy(gctx->iv, ptr, arg);
+		if (c->encrypt)
+			arc4random_buf(gctx->iv + arg, gctx->ivlen - arg);
+		gctx->iv_gen = 1;
+		return 1;
+
+	case EVP_CTRL_GCM_IV_GEN:
+		if (gctx->iv_gen == 0 || gctx->key_set == 0)
+			return 0;
+		CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
+		if (arg <= 0 || arg > gctx->ivlen)
+			arg = gctx->ivlen;
+		memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg);
+		/* Invocation field will be at least 8 bytes in size and
+		 * so no need to check wrap around or increment more than
+		 * last 8 bytes.
+		 */
+		ctr64_inc(gctx->iv + gctx->ivlen - 8);
+		gctx->iv_set = 1;
+		return 1;
+
+	case EVP_CTRL_GCM_SET_IV_INV:
+		if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt)
+			return 0;
+		memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg);
+		CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
+		gctx->iv_set = 1;
+		return 1;
+
+	case EVP_CTRL_AEAD_TLS1_AAD:
+		/* Save the AAD for later use */
+		if (arg != 13)
+			return 0;
+		memcpy(c->buf, ptr, arg);
+		gctx->tls_aad_len = arg;
+		{
+			unsigned int len = c->buf[arg - 2] << 8 |
+			    c->buf[arg - 1];
+
+			/* Correct length for explicit IV */
+			len -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
+
+			/* If decrypting correct for tag too */
+			if (!c->encrypt)
+				len -= EVP_GCM_TLS_TAG_LEN;
+			c->buf[arg - 2] = len >> 8;
+			c->buf[arg - 1] = len & 0xff;
+		}
+		/* Extra padding: tag appended to record */
+		return EVP_GCM_TLS_TAG_LEN;
+
+	case EVP_CTRL_COPY:
+	    {
+		EVP_CIPHER_CTX *out = ptr;
+		EVP_AES_GCM_CTX *gctx_out = out->cipher_data;
+
+		if (gctx->gcm.key) {
+			if (gctx->gcm.key != &gctx->ks)
+				return 0;
+			gctx_out->gcm.key = &gctx_out->ks;
+		}
+		if (gctx->iv == c->iv)
+			gctx_out->iv = out->iv;
+		else {
+			gctx_out->iv = malloc(gctx->ivlen);
+			if (!gctx_out->iv)
+				return 0;
+			memcpy(gctx_out->iv, gctx->iv, gctx->ivlen);
+		}
+		return 1;
+	    }
+
+	default:
+		return -1;
+
+	}
+}
+
+static ctr128_f
+aes_gcm_set_key(AES_KEY *aes_key, GCM128_CONTEXT *gcm_ctx,
+    const unsigned char *key, size_t key_len)
+{
+#ifdef BSAES_CAPABLE
+	if (BSAES_CAPABLE) {
+		AES_set_encrypt_key(key, key_len * 8, aes_key);
+		CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)AES_encrypt);
+		return (ctr128_f)bsaes_ctr32_encrypt_blocks;
+	} else
+#endif
+#ifdef VPAES_CAPABLE
+	if (VPAES_CAPABLE) {
+		vpaes_set_encrypt_key(key, key_len * 8, aes_key);
+		CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)vpaes_encrypt);
+		return NULL;
+	} else
+#endif
+		(void)0; /* terminate potentially open 'else' */
+
+	AES_set_encrypt_key(key, key_len * 8, aes_key);
+	CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)AES_encrypt);
+#ifdef AES_CTR_ASM
+	return (ctr128_f)AES_ctr32_encrypt;
+#else
+	return NULL;
+#endif
+}
+
+static int
+aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+
+	if (!iv && !key)
+		return 1;
+	if (key) {
+		gctx->ctr = aes_gcm_set_key(&gctx->ks, &gctx->gcm,
+		    key, ctx->key_len);
+
+		/* If we have an iv can set it directly, otherwise use
+		 * saved IV.
+		 */
+		if (iv == NULL && gctx->iv_set)
+			iv = gctx->iv;
+		if (iv) {
+			CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+			gctx->iv_set = 1;
+		}
+		gctx->key_set = 1;
+	} else {
+		/* If key set use IV, otherwise copy */
+		if (gctx->key_set)
+			CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+		else
+			memcpy(gctx->iv, iv, gctx->ivlen);
+		gctx->iv_set = 1;
+		gctx->iv_gen = 0;
+	}
+	return 1;
+}
+
+/* Handle TLS GCM packet format. This consists of the last portion of the IV
+ * followed by the payload and finally the tag. On encrypt generate IV,
+ * encrypt payload and write the tag. On verify retrieve IV, decrypt payload
+ * and verify tag.
+ */
+
+static int
+aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len)
+{
+	EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+	int rv = -1;
+
+	/* Encrypt/decrypt must be performed in place */
+	if (out != in ||
+	    len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN))
+		return -1;
+
+	/* Set IV from start of buffer or generate IV and write to start
+	 * of buffer.
+	 */
+	if (EVP_CIPHER_CTX_ctrl(ctx, ctx->encrypt ?
+	    EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV,
+	    EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0)
+		goto err;
+
+	/* Use saved AAD */
+	if (CRYPTO_gcm128_aad(&gctx->gcm, ctx->buf, gctx->tls_aad_len))
+		goto err;
+
+	/* Fix buffer and length to point to payload */
+	in += EVP_GCM_TLS_EXPLICIT_IV_LEN;
+	out += EVP_GCM_TLS_EXPLICIT_IV_LEN;
+	len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
+	if (ctx->encrypt) {
+		/* Encrypt payload */
+		if (gctx->ctr) {
+			if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, in, out,
+			    len, gctx->ctr))
+				goto err;
+		} else {
+			if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len))
+				goto err;
+		}
+		out += len;
+
+		/* Finally write tag */
+		CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN);
+		rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
+	} else {
+		/* Decrypt */
+		if (gctx->ctr) {
+			if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, in, out,
+			    len, gctx->ctr))
+				goto err;
+		} else {
+			if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len))
+				goto err;
+		}
+		/* Retrieve tag */
+		CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, EVP_GCM_TLS_TAG_LEN);
+
+		/* If tag mismatch wipe buffer */
+		if (memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN)) {
+			explicit_bzero(out, len);
+			goto err;
+		}
+		rv = len;
+	}
+
+err:
+	gctx->iv_set = 0;
+	gctx->tls_aad_len = -1;
+	return rv;
+}
+
+static int
+aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len)
+{
+	EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+
+	/* If not set up, return error */
+	if (!gctx->key_set)
+		return -1;
+
+	if (gctx->tls_aad_len >= 0)
+		return aes_gcm_tls_cipher(ctx, out, in, len);
+
+	if (!gctx->iv_set)
+		return -1;
+
+	if (in) {
+		if (out == NULL) {
+			if (CRYPTO_gcm128_aad(&gctx->gcm, in, len))
+				return -1;
+		} else if (ctx->encrypt) {
+			if (gctx->ctr) {
+				if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
+				    in, out, len, gctx->ctr))
+					return -1;
+			} else {
+				if (CRYPTO_gcm128_encrypt(&gctx->gcm,
+				    in, out, len))
+					return -1;
+			}
+		} else {
+			if (gctx->ctr) {
+				if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
+				    in, out, len, gctx->ctr))
+					return -1;
+			} else {
+				if (CRYPTO_gcm128_decrypt(&gctx->gcm,
+				    in, out, len))
+					return -1;
+			}
+		}
+		return len;
+	} else {
+		if (!ctx->encrypt) {
+			if (gctx->taglen < 0)
+				return -1;
+			if (CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf,
+			    gctx->taglen) != 0)
+				return -1;
+			gctx->iv_set = 0;
+			return 0;
+		}
+		CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16);
+		gctx->taglen = 16;
+
+		/* Don't reuse the IV */
+		gctx->iv_set = 0;
+		return 0;
+	}
+
+}
+
+#define CUSTOM_FLAGS \
+    ( EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV | \
+      EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | \
+      EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY )
+
+BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, gcm, GCM,
+    EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS)
+BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, gcm, GCM,
+    EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS)
+BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, gcm, GCM,
+    EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS)
+
+static int
+aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+	EVP_AES_XTS_CTX *xctx = c->cipher_data;
+
+	switch (type) {
+	case EVP_CTRL_INIT:
+		/*
+		 * key1 and key2 are used as an indicator both key and IV
+		 * are set
+		 */
+		xctx->xts.key1 = NULL;
+		xctx->xts.key2 = NULL;
+		return 1;
+
+	case EVP_CTRL_COPY:
+	    {
+		EVP_CIPHER_CTX *out = ptr;
+		EVP_AES_XTS_CTX *xctx_out = out->cipher_data;
+
+		if (xctx->xts.key1) {
+			if (xctx->xts.key1 != &xctx->ks1)
+				return 0;
+			xctx_out->xts.key1 = &xctx_out->ks1;
+		}
+		if (xctx->xts.key2) {
+			if (xctx->xts.key2 != &xctx->ks2)
+				return 0;
+			xctx_out->xts.key2 = &xctx_out->ks2;
+		}
+		return 1;
+	    }
+	}
+	return -1;
+}
+
+static int
+aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+
+	if (!iv && !key)
+		return 1;
+
+	if (key) do {
+#ifdef AES_XTS_ASM
+		xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt;
+#else
+		xctx->stream = NULL;
+#endif
+		/* key_len is two AES keys */
+#ifdef BSAES_CAPABLE
+		if (BSAES_CAPABLE)
+			xctx->stream = enc ? bsaes_xts_encrypt :
+			    bsaes_xts_decrypt;
+		else
+#endif
+#ifdef VPAES_CAPABLE
+		if (VPAES_CAPABLE) {
+			if (enc) {
+				vpaes_set_encrypt_key(key, ctx->key_len * 4,
+				    &xctx->ks1);
+				xctx->xts.block1 = (block128_f)vpaes_encrypt;
+			} else {
+				vpaes_set_decrypt_key(key, ctx->key_len * 4,
+				    &xctx->ks1);
+				xctx->xts.block1 = (block128_f)vpaes_decrypt;
+			}
+
+			vpaes_set_encrypt_key(key + ctx->key_len / 2,
+			    ctx->key_len * 4, &xctx->ks2);
+			xctx->xts.block2 = (block128_f)vpaes_encrypt;
+
+			xctx->xts.key1 = &xctx->ks1;
+			break;
+		} else
+#endif
+			(void)0;	/* terminate potentially open 'else' */
+
+		if (enc) {
+			AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1);
+			xctx->xts.block1 = (block128_f)AES_encrypt;
+		} else {
+			AES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1);
+			xctx->xts.block1 = (block128_f)AES_decrypt;
+		}
+
+		AES_set_encrypt_key(key + ctx->key_len / 2,
+		    ctx->key_len * 4, &xctx->ks2);
+		xctx->xts.block2 = (block128_f)AES_encrypt;
+
+		xctx->xts.key1 = &xctx->ks1;
+	} while (0);
+
+	if (iv) {
+		xctx->xts.key2 = &xctx->ks2;
+		memcpy(ctx->iv, iv, 16);
+	}
+
+	return 1;
+}
+
+static int
+aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len)
+{
+	EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+
+	if (!xctx->xts.key1 || !xctx->xts.key2)
+		return 0;
+	if (!out || !in || len < AES_BLOCK_SIZE)
+		return 0;
+
+	if (xctx->stream)
+		(*xctx->stream)(in, out, len, xctx->xts.key1, xctx->xts.key2,
+		    ctx->iv);
+	else if (CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len,
+	    ctx->encrypt))
+		return 0;
+	return 1;
+}
+
+#define aes_xts_cleanup NULL
+
+#define XTS_FLAGS \
+    ( EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV | \
+      EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY )
+
+BLOCK_CIPHER_custom(NID_aes, 128, 1, 16, xts, XTS, EVP_CIPH_FLAG_FIPS|XTS_FLAGS)
+BLOCK_CIPHER_custom(NID_aes, 256, 1, 16, xts, XTS, EVP_CIPH_FLAG_FIPS|XTS_FLAGS)
+
+static int
+aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+	EVP_AES_CCM_CTX *cctx = c->cipher_data;
+
+	switch (type) {
+	case EVP_CTRL_INIT:
+		cctx->key_set = 0;
+		cctx->iv_set = 0;
+		cctx->L = 8;
+		cctx->M = 12;
+		cctx->tag_set = 0;
+		cctx->len_set = 0;
+		return 1;
+
+	case EVP_CTRL_CCM_SET_IVLEN:
+		arg = 15 - arg;
+
+	case EVP_CTRL_CCM_SET_L:
+		if (arg < 2 || arg > 8)
+			return 0;
+		cctx->L = arg;
+		return 1;
+
+	case EVP_CTRL_CCM_SET_TAG:
+		if ((arg & 1) || arg < 4 || arg > 16)
+			return 0;
+		if ((c->encrypt && ptr) || (!c->encrypt && !ptr))
+			return 0;
+		if (ptr) {
+			cctx->tag_set = 1;
+			memcpy(c->buf, ptr, arg);
+		}
+		cctx->M = arg;
+		return 1;
+
+	case EVP_CTRL_CCM_GET_TAG:
+		if (!c->encrypt || !cctx->tag_set)
+			return 0;
+		if (!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg))
+			return 0;
+		cctx->tag_set = 0;
+		cctx->iv_set = 0;
+		cctx->len_set = 0;
+		return 1;
+
+	case EVP_CTRL_COPY:
+	    {
+		EVP_CIPHER_CTX *out = ptr;
+		EVP_AES_CCM_CTX *cctx_out = out->cipher_data;
+
+		if (cctx->ccm.key) {
+			if (cctx->ccm.key != &cctx->ks)
+				return 0;
+			cctx_out->ccm.key = &cctx_out->ks;
+		}
+		return 1;
+	    }
+
+	default:
+		return -1;
+	}
+}
+
+static int
+aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
+
+	if (!iv && !key)
+		return 1;
+	if (key) do {
+#ifdef VPAES_CAPABLE
+		if (VPAES_CAPABLE) {
+			vpaes_set_encrypt_key(key, ctx->key_len*8, &cctx->ks);
+			CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+			    &cctx->ks, (block128_f)vpaes_encrypt);
+			cctx->str = NULL;
+			cctx->key_set = 1;
+			break;
+		}
+#endif
+		AES_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks);
+		CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+		    &cctx->ks, (block128_f)AES_encrypt);
+		cctx->str = NULL;
+		cctx->key_set = 1;
+	} while (0);
+	if (iv) {
+		memcpy(ctx->iv, iv, 15 - cctx->L);
+		cctx->iv_set = 1;
+	}
+	return 1;
+}
+
+static int
+aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len)
+{
+	EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
+	CCM128_CONTEXT *ccm = &cctx->ccm;
+
+	/* If not set up, return error */
+	if (!cctx->iv_set && !cctx->key_set)
+		return -1;
+	if (!ctx->encrypt && !cctx->tag_set)
+		return -1;
+
+	if (!out) {
+		if (!in) {
+			if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L,
+			    len))
+				return -1;
+			cctx->len_set = 1;
+			return len;
+		}
+		/* If have AAD need message length */
+		if (!cctx->len_set && len)
+			return -1;
+		CRYPTO_ccm128_aad(ccm, in, len);
+		return len;
+	}
+	/* EVP_*Final() doesn't return any data */
+	if (!in)
+		return 0;
+	/* If not set length yet do it */
+	if (!cctx->len_set) {
+		if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len))
+			return -1;
+		cctx->len_set = 1;
+	}
+	if (ctx->encrypt) {
+		if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len,
+		    cctx->str) : CRYPTO_ccm128_encrypt(ccm, in, out, len))
+			return -1;
+		cctx->tag_set = 1;
+		return len;
+	} else {
+		int rv = -1;
+		if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len,
+		    cctx->str) : !CRYPTO_ccm128_decrypt(ccm, in, out, len)) {
+			unsigned char tag[16];
+			if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) {
+				if (!memcmp(tag, ctx->buf, cctx->M))
+					rv = len;
+			}
+		}
+		if (rv == -1)
+			explicit_bzero(out, len);
+		cctx->iv_set = 0;
+		cctx->tag_set = 0;
+		cctx->len_set = 0;
+		return rv;
+	}
+
+}
+
+#define aes_ccm_cleanup NULL
+
+BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, ccm, CCM,
+    EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
+BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, ccm, CCM,
+    EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
+BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, ccm, CCM,
+    EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
+
+#define EVP_AEAD_AES_GCM_TAG_LEN 16
+
+struct aead_aes_gcm_ctx {
+	union {
+		double align;
+		AES_KEY ks;
+	} ks;
+	GCM128_CONTEXT gcm;
+	ctr128_f ctr;
+	unsigned char tag_len;
+};
+
+static int
+aead_aes_gcm_init(EVP_AEAD_CTX *ctx, const unsigned char *key, size_t key_len,
+    size_t tag_len)
+{
+	struct aead_aes_gcm_ctx *gcm_ctx;
+	const size_t key_bits = key_len * 8;
+
+	/* EVP_AEAD_CTX_init should catch this. */
+	if (key_bits != 128 && key_bits != 256) {
+		EVPerr(EVP_F_AEAD_AES_GCM_INIT, EVP_R_BAD_KEY_LENGTH);
+		return 0;
+	}
+
+	if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH)
+		tag_len = EVP_AEAD_AES_GCM_TAG_LEN;
+
+	if (tag_len > EVP_AEAD_AES_GCM_TAG_LEN) {
+		EVPerr(EVP_F_AEAD_AES_GCM_INIT, EVP_R_TAG_TOO_LARGE);
+		return 0;
+	}
+
+	gcm_ctx = malloc(sizeof(struct aead_aes_gcm_ctx));
+	if (gcm_ctx == NULL)
+		return 0;
+
+#ifdef AESNI_CAPABLE
+	if (AESNI_CAPABLE) {
+		aesni_set_encrypt_key(key, key_bits, &gcm_ctx->ks.ks);
+		CRYPTO_gcm128_init(&gcm_ctx->gcm, &gcm_ctx->ks.ks,
+		    (block128_f)aesni_encrypt);
+		gcm_ctx->ctr = (ctr128_f) aesni_ctr32_encrypt_blocks;
+	} else
+#endif
+	{
+		gcm_ctx->ctr = aes_gcm_set_key(&gcm_ctx->ks.ks, &gcm_ctx->gcm,
+		    key, key_len);
+	}
+	gcm_ctx->tag_len = tag_len;
+	ctx->aead_state = gcm_ctx;
+
+	return 1;
+}
+
+static void
+aead_aes_gcm_cleanup(EVP_AEAD_CTX *ctx)
+{
+	struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
+
+	explicit_bzero(gcm_ctx, sizeof(*gcm_ctx));
+	free(gcm_ctx);
+}
+
+static int
+aead_aes_gcm_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
+    size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
+    const unsigned char *in, size_t in_len, const unsigned char *ad,
+    size_t ad_len)
+{
+	const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
+	GCM128_CONTEXT gcm;
+	size_t bulk = 0;
+
+	if (max_out_len < in_len + gcm_ctx->tag_len) {
+		EVPerr(EVP_F_AEAD_AES_GCM_SEAL, EVP_R_BUFFER_TOO_SMALL);
+		return 0;
+	}
+
+	memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
+	CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len);
+
+	if (ad_len > 0 && CRYPTO_gcm128_aad(&gcm, ad, ad_len))
+		return 0;
+
+	if (gcm_ctx->ctr) {
+		if (CRYPTO_gcm128_encrypt_ctr32(&gcm, in + bulk, out + bulk,
+		    in_len - bulk, gcm_ctx->ctr))
+			return 0;
+	} else {
+		if (CRYPTO_gcm128_encrypt(&gcm, in + bulk, out + bulk,
+		    in_len - bulk))
+			return 0;
+	}
+
+	CRYPTO_gcm128_tag(&gcm, out + in_len, gcm_ctx->tag_len);
+	*out_len = in_len + gcm_ctx->tag_len;
+
+	return 1;
+}
+
+static int
+aead_aes_gcm_open(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
+    size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
+    const unsigned char *in, size_t in_len, const unsigned char *ad,
+    size_t ad_len)
+{
+	const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
+	unsigned char tag[EVP_AEAD_AES_GCM_TAG_LEN];
+	GCM128_CONTEXT gcm;
+	size_t plaintext_len;
+	size_t bulk = 0;
+
+	if (in_len < gcm_ctx->tag_len) {
+		EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BAD_DECRYPT);
+		return 0;
+	}
+
+	plaintext_len = in_len - gcm_ctx->tag_len;
+
+	if (max_out_len < plaintext_len) {
+		EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BUFFER_TOO_SMALL);
+		return 0;
+	}
+
+	memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
+	CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len);
+
+	if (CRYPTO_gcm128_aad(&gcm, ad, ad_len))
+		return 0;
+
+	if (gcm_ctx->ctr) {
+		if (CRYPTO_gcm128_decrypt_ctr32(&gcm, in + bulk, out + bulk,
+		    in_len - bulk - gcm_ctx->tag_len, gcm_ctx->ctr))
+			return 0;
+	} else {
+		if (CRYPTO_gcm128_decrypt(&gcm, in + bulk, out + bulk,
+		    in_len - bulk - gcm_ctx->tag_len))
+			return 0;
+	}
+
+	CRYPTO_gcm128_tag(&gcm, tag, gcm_ctx->tag_len);
+	if (timingsafe_memcmp(tag, in + plaintext_len, gcm_ctx->tag_len) != 0) {
+		EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BAD_DECRYPT);
+		return 0;
+	}
+
+	*out_len = plaintext_len;
+
+	return 1;
+}
+
+static const EVP_AEAD aead_aes_128_gcm = {
+	.key_len = 16,
+	.nonce_len = 12,
+	.overhead = EVP_AEAD_AES_GCM_TAG_LEN,
+	.max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN,
+
+	.init = aead_aes_gcm_init,
+	.cleanup = aead_aes_gcm_cleanup,
+	.seal = aead_aes_gcm_seal,
+	.open = aead_aes_gcm_open,
+};
+
+static const EVP_AEAD aead_aes_256_gcm = {
+	.key_len = 32,
+	.nonce_len = 12,
+	.overhead = EVP_AEAD_AES_GCM_TAG_LEN,
+	.max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN,
+
+	.init = aead_aes_gcm_init,
+	.cleanup = aead_aes_gcm_cleanup,
+	.seal = aead_aes_gcm_seal,
+	.open = aead_aes_gcm_open,
+};
+
+const EVP_AEAD *
+EVP_aead_aes_128_gcm(void)
+{
+	return &aead_aes_128_gcm;
+}
+
+const EVP_AEAD *
+EVP_aead_aes_256_gcm(void)
+{
+	return &aead_aes_256_gcm;
+}
+
+#endif
diff --git a/crypto/libressl/crypto/evp/e_aes_cbc_hmac_sha1.c b/crypto/libressl/crypto/evp/e_aes_cbc_hmac_sha1.c
new file mode 100644
index 0000000000..01ca68d40b
--- /dev/null
+++ b/crypto/libressl/crypto/evp/e_aes_cbc_hmac_sha1.c
@@ -0,0 +1,604 @@
+/* $OpenBSD: e_aes_cbc_hmac_sha1.c,v 1.11 2016/05/04 14:53:29 tedu Exp $ */
+/* ====================================================================
+ * Copyright (c) 2011-2013 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include 
+#include 
+
+#include 
+
+#if !defined(OPENSSL_NO_AES) && !defined(OPENSSL_NO_SHA1)
+
+#include 
+#include 
+#include 
+#include 
+#include "evp_locl.h"
+#include "constant_time_locl.h"
+
+#ifndef EVP_CIPH_FLAG_AEAD_CIPHER
+#define EVP_CIPH_FLAG_AEAD_CIPHER	0x200000
+#define EVP_CTRL_AEAD_TLS1_AAD		0x16
+#define EVP_CTRL_AEAD_SET_MAC_KEY	0x17
+#endif
+
+#define TLS1_1_VERSION 0x0302
+
+typedef struct {
+	AES_KEY		ks;
+	SHA_CTX		head, tail, md;
+	size_t		payload_length;	/* AAD length in decrypt case */
+	union {
+		unsigned int	tls_ver;
+		unsigned char	tls_aad[16];	/* 13 used */
+	} aux;
+} EVP_AES_HMAC_SHA1;
+
+#define NO_PAYLOAD_LENGTH	((size_t)-1)
+
+#if	defined(AES_ASM) &&	( \
+	defined(__x86_64)	|| defined(__x86_64__)	|| \
+	defined(_M_AMD64)	|| defined(_M_X64)	|| \
+	defined(__INTEL__)	)
+
+#if defined(__GNUC__) && __GNUC__>=2
+# define BSWAP(x) ({ unsigned int r=(x); asm ("bswapl %0":"=r"(r):"0"(r)); r; })
+#endif
+
+extern unsigned int OPENSSL_ia32cap_P[2];
+#define AESNI_CAPABLE   (1<<(57-32))
+
+int aesni_set_encrypt_key(const unsigned char *userKey, int bits, AES_KEY *key);
+int aesni_set_decrypt_key(const unsigned char *userKey, int bits, AES_KEY *key);
+
+void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out,
+    size_t length, const AES_KEY *key, unsigned char *ivec, int enc);
+
+void aesni_cbc_sha1_enc (const void *inp, void *out, size_t blocks,
+    const AES_KEY *key, unsigned char iv[16], SHA_CTX *ctx, const void *in0);
+
+#define data(ctx) ((EVP_AES_HMAC_SHA1 *)(ctx)->cipher_data)
+
+static int
+aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *inkey,
+    const unsigned char *iv, int enc)
+{
+	EVP_AES_HMAC_SHA1 *key = data(ctx);
+	int ret;
+
+	if (enc)
+		ret = aesni_set_encrypt_key(inkey, ctx->key_len * 8, &key->ks);
+	else
+		ret = aesni_set_decrypt_key(inkey, ctx->key_len * 8, &key->ks);
+
+	SHA1_Init(&key->head);	/* handy when benchmarking */
+	key->tail = key->head;
+	key->md = key->head;
+
+	key->payload_length = NO_PAYLOAD_LENGTH;
+
+	return ret < 0 ? 0 : 1;
+}
+
+#define	STITCHED_CALL
+
+#if !defined(STITCHED_CALL)
+#define	aes_off 0
+#endif
+
+void sha1_block_data_order (void *c, const void *p, size_t len);
+
+static void
+sha1_update(SHA_CTX *c, const void *data, size_t len)
+{
+	const unsigned char *ptr = data;
+	size_t res;
+
+	if ((res = c->num)) {
+		res = SHA_CBLOCK - res;
+		if (len < res)
+			res = len;
+		SHA1_Update(c, ptr, res);
+		ptr += res;
+		len -= res;
+	}
+
+	res = len % SHA_CBLOCK;
+	len -= res;
+
+	if (len) {
+		sha1_block_data_order(c, ptr, len / SHA_CBLOCK);
+
+		ptr += len;
+		c->Nh += len >> 29;
+		c->Nl += len <<= 3;
+		if (c->Nl < (unsigned int)len)
+			c->Nh++;
+	}
+
+	if (res)
+		SHA1_Update(c, ptr, res);
+}
+
+#ifdef SHA1_Update
+#undef SHA1_Update
+#endif
+#define SHA1_Update sha1_update
+
+static int
+aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len)
+{
+	EVP_AES_HMAC_SHA1 *key = data(ctx);
+	unsigned int l;
+	size_t plen = key->payload_length,
+	    iv = 0,		/* explicit IV in TLS 1.1 and later */
+	    sha_off = 0;
+#if defined(STITCHED_CALL)
+	size_t aes_off = 0, blocks;
+
+	sha_off = SHA_CBLOCK - key->md.num;
+#endif
+
+	key->payload_length = NO_PAYLOAD_LENGTH;
+
+	if (len % AES_BLOCK_SIZE)
+		return 0;
+
+	if (ctx->encrypt) {
+		if (plen == NO_PAYLOAD_LENGTH)
+			plen = len;
+		else if (len != ((plen + SHA_DIGEST_LENGTH + AES_BLOCK_SIZE) &
+		    -AES_BLOCK_SIZE))
+			return 0;
+		else if (key->aux.tls_ver >= TLS1_1_VERSION)
+			iv = AES_BLOCK_SIZE;
+
+#if defined(STITCHED_CALL)
+		if (plen > (sha_off + iv) &&
+		    (blocks = (plen - (sha_off + iv)) / SHA_CBLOCK)) {
+			SHA1_Update(&key->md, in + iv, sha_off);
+
+			aesni_cbc_sha1_enc(in, out, blocks, &key->ks,
+			    ctx->iv, &key->md, in + iv + sha_off);
+			blocks *= SHA_CBLOCK;
+			aes_off += blocks;
+			sha_off += blocks;
+			key->md.Nh += blocks >> 29;
+			key->md.Nl += blocks <<= 3;
+			if (key->md.Nl < (unsigned int)blocks)
+				key->md.Nh++;
+		} else {
+			sha_off = 0;
+		}
+#endif
+		sha_off += iv;
+		SHA1_Update(&key->md, in + sha_off, plen - sha_off);
+
+		if (plen != len) {	/* "TLS" mode of operation */
+			if (in != out)
+				memcpy(out + aes_off, in + aes_off,
+				    plen - aes_off);
+
+			/* calculate HMAC and append it to payload */
+			SHA1_Final(out + plen, &key->md);
+			key->md = key->tail;
+			SHA1_Update(&key->md, out + plen, SHA_DIGEST_LENGTH);
+			SHA1_Final(out + plen, &key->md);
+
+			/* pad the payload|hmac */
+			plen += SHA_DIGEST_LENGTH;
+			for (l = len - plen - 1; plen < len; plen++)
+				out[plen] = l;
+
+			/* encrypt HMAC|padding at once */
+			aesni_cbc_encrypt(out + aes_off, out + aes_off,
+			    len - aes_off, &key->ks, ctx->iv, 1);
+		} else {
+			aesni_cbc_encrypt(in + aes_off, out + aes_off,
+			    len - aes_off, &key->ks, ctx->iv, 1);
+		}
+	} else {
+		union {
+			unsigned int u[SHA_DIGEST_LENGTH/sizeof(unsigned int)];
+			unsigned char c[32 + SHA_DIGEST_LENGTH];
+		} mac, *pmac;
+
+		/* arrange cache line alignment */
+		pmac = (void *)(((size_t)mac.c + 31) & ((size_t)0 - 32));
+
+		/* decrypt HMAC|padding at once */
+		aesni_cbc_encrypt(in, out, len, &key->ks, ctx->iv, 0);
+
+		if (plen) {	/* "TLS" mode of operation */
+			size_t inp_len, mask, j, i;
+			unsigned int res, maxpad, pad, bitlen;
+			int ret = 1;
+			union {
+				unsigned int u[SHA_LBLOCK];
+				unsigned char c[SHA_CBLOCK];
+			}
+			*data = (void *)key->md.data;
+
+			if ((key->aux.tls_aad[plen - 4] << 8 |
+			    key->aux.tls_aad[plen - 3]) >= TLS1_1_VERSION)
+				iv = AES_BLOCK_SIZE;
+
+			if (len < (iv + SHA_DIGEST_LENGTH + 1))
+				return 0;
+
+			/* omit explicit iv */
+			out += iv;
+			len -= iv;
+
+			/* figure out payload length */
+			pad = out[len - 1];
+			maxpad = len - (SHA_DIGEST_LENGTH + 1);
+			maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8);
+			maxpad &= 255;
+
+			ret &= constant_time_ge(maxpad, pad);
+
+			inp_len = len - (SHA_DIGEST_LENGTH + pad + 1);
+			mask = (0 - ((inp_len - len) >>
+			    (sizeof(inp_len) * 8 - 1)));
+			inp_len &= mask;
+			ret &= (int)mask;
+
+			key->aux.tls_aad[plen - 2] = inp_len >> 8;
+			key->aux.tls_aad[plen - 1] = inp_len;
+
+			/* calculate HMAC */
+			key->md = key->head;
+			SHA1_Update(&key->md, key->aux.tls_aad, plen);
+
+#if 1
+			len -= SHA_DIGEST_LENGTH;		/* amend mac */
+			if (len >= (256 + SHA_CBLOCK)) {
+				j = (len - (256 + SHA_CBLOCK)) &
+				    (0 - SHA_CBLOCK);
+				j += SHA_CBLOCK - key->md.num;
+				SHA1_Update(&key->md, out, j);
+				out += j;
+				len -= j;
+				inp_len -= j;
+			}
+
+			/* but pretend as if we hashed padded payload */
+			bitlen = key->md.Nl + (inp_len << 3);	/* at most 18 bits */
+#ifdef BSWAP
+			bitlen = BSWAP(bitlen);
+#else
+			mac.c[0] = 0;
+			mac.c[1] = (unsigned char)(bitlen >> 16);
+			mac.c[2] = (unsigned char)(bitlen >> 8);
+			mac.c[3] = (unsigned char)bitlen;
+			bitlen = mac.u[0];
+#endif
+
+			pmac->u[0] = 0;
+			pmac->u[1] = 0;
+			pmac->u[2] = 0;
+			pmac->u[3] = 0;
+			pmac->u[4] = 0;
+
+			for (res = key->md.num, j = 0; j < len; j++) {
+				size_t c = out[j];
+				mask = (j - inp_len) >> (sizeof(j) * 8 - 8);
+				c &= mask;
+				c |= 0x80 & ~mask &
+				    ~((inp_len - j) >> (sizeof(j) * 8 - 8));
+				data->c[res++] = (unsigned char)c;
+
+				if (res != SHA_CBLOCK)
+					continue;
+
+				/* j is not incremented yet */
+				mask = 0 - ((inp_len + 7 - j) >>
+				    (sizeof(j) * 8 - 1));
+				data->u[SHA_LBLOCK - 1] |= bitlen&mask;
+				sha1_block_data_order(&key->md, data, 1);
+				mask &= 0 - ((j - inp_len - 72) >>
+				    (sizeof(j) * 8 - 1));
+				pmac->u[0] |= key->md.h0 & mask;
+				pmac->u[1] |= key->md.h1 & mask;
+				pmac->u[2] |= key->md.h2 & mask;
+				pmac->u[3] |= key->md.h3 & mask;
+				pmac->u[4] |= key->md.h4 & mask;
+				res = 0;
+			}
+
+			for (i = res; i < SHA_CBLOCK; i++, j++)
+				data->c[i] = 0;
+
+			if (res > SHA_CBLOCK - 8) {
+				mask = 0 - ((inp_len + 8 - j) >>
+				    (sizeof(j) * 8 - 1));
+				data->u[SHA_LBLOCK - 1] |= bitlen & mask;
+				sha1_block_data_order(&key->md, data, 1);
+				mask &= 0 - ((j - inp_len - 73) >>
+				    (sizeof(j) * 8 - 1));
+				pmac->u[0] |= key->md.h0 & mask;
+				pmac->u[1] |= key->md.h1 & mask;
+				pmac->u[2] |= key->md.h2 & mask;
+				pmac->u[3] |= key->md.h3 & mask;
+				pmac->u[4] |= key->md.h4 & mask;
+
+				memset(data, 0, SHA_CBLOCK);
+				j += 64;
+			}
+			data->u[SHA_LBLOCK - 1] = bitlen;
+			sha1_block_data_order(&key->md, data, 1);
+			mask = 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1));
+			pmac->u[0] |= key->md.h0 & mask;
+			pmac->u[1] |= key->md.h1 & mask;
+			pmac->u[2] |= key->md.h2 & mask;
+			pmac->u[3] |= key->md.h3 & mask;
+			pmac->u[4] |= key->md.h4 & mask;
+
+#ifdef BSWAP
+			pmac->u[0] = BSWAP(pmac->u[0]);
+			pmac->u[1] = BSWAP(pmac->u[1]);
+			pmac->u[2] = BSWAP(pmac->u[2]);
+			pmac->u[3] = BSWAP(pmac->u[3]);
+			pmac->u[4] = BSWAP(pmac->u[4]);
+#else
+			for (i = 0; i < 5; i++) {
+				res = pmac->u[i];
+				pmac->c[4 * i + 0] = (unsigned char)(res >> 24);
+				pmac->c[4 * i + 1] = (unsigned char)(res >> 16);
+				pmac->c[4 * i + 2] = (unsigned char)(res >> 8);
+				pmac->c[4 * i + 3] = (unsigned char)res;
+			}
+#endif
+			len += SHA_DIGEST_LENGTH;
+#else
+			SHA1_Update(&key->md, out, inp_len);
+			res = key->md.num;
+			SHA1_Final(pmac->c, &key->md);
+
+			{
+				unsigned int inp_blocks, pad_blocks;
+
+				/* but pretend as if we hashed padded payload */
+				inp_blocks = 1 + ((SHA_CBLOCK - 9 - res) >>
+				    (sizeof(res) * 8 - 1));
+				res += (unsigned int)(len - inp_len);
+				pad_blocks = res / SHA_CBLOCK;
+				res %= SHA_CBLOCK;
+				pad_blocks += 1 + ((SHA_CBLOCK - 9 - res) >>
+				    (sizeof(res) * 8 - 1));
+				for (; inp_blocks < pad_blocks; inp_blocks++)
+					sha1_block_data_order(&key->md,
+					    data, 1);
+			}
+#endif
+			key->md = key->tail;
+			SHA1_Update(&key->md, pmac->c, SHA_DIGEST_LENGTH);
+			SHA1_Final(pmac->c, &key->md);
+
+			/* verify HMAC */
+			out += inp_len;
+			len -= inp_len;
+#if 1
+			{
+				unsigned char *p =
+				    out + len - 1 - maxpad - SHA_DIGEST_LENGTH;
+				size_t off = out - p;
+				unsigned int c, cmask;
+
+				maxpad += SHA_DIGEST_LENGTH;
+				for (res = 0, i = 0, j = 0; j < maxpad; j++) {
+					c = p[j];
+					cmask = ((int)(j - off -
+					    SHA_DIGEST_LENGTH)) >>
+					    (sizeof(int) * 8 - 1);
+					res |= (c ^ pad) & ~cmask;	/* ... and padding */
+					cmask &= ((int)(off - 1 - j)) >>
+					    (sizeof(int) * 8 - 1);
+					res |= (c ^ pmac->c[i]) & cmask;
+					i += 1 & cmask;
+				}
+				maxpad -= SHA_DIGEST_LENGTH;
+
+				res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
+				ret &= (int)~res;
+			}
+#else
+			for (res = 0, i = 0; i < SHA_DIGEST_LENGTH; i++)
+				res |= out[i] ^ pmac->c[i];
+			res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
+			ret &= (int)~res;
+
+			/* verify padding */
+			pad = (pad & ~res) | (maxpad & res);
+			out = out + len - 1 - pad;
+			for (res = 0, i = 0; i < pad; i++)
+				res |= out[i] ^ pad;
+
+			res = (0 - res) >> (sizeof(res) * 8 - 1);
+			ret &= (int)~res;
+#endif
+			return ret;
+		} else {
+			SHA1_Update(&key->md, out, len);
+		}
+	}
+
+	return 1;
+}
+
+static int
+aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+	EVP_AES_HMAC_SHA1 *key = data(ctx);
+
+	switch (type) {
+	case EVP_CTRL_AEAD_SET_MAC_KEY:
+		{
+			unsigned int  i;
+			unsigned char hmac_key[64];
+
+			memset(hmac_key, 0, sizeof(hmac_key));
+
+			if (arg > (int)sizeof(hmac_key)) {
+				SHA1_Init(&key->head);
+				SHA1_Update(&key->head, ptr, arg);
+				SHA1_Final(hmac_key, &key->head);
+			} else {
+				memcpy(hmac_key, ptr, arg);
+			}
+
+			for (i = 0; i < sizeof(hmac_key); i++)
+				hmac_key[i] ^= 0x36;		/* ipad */
+			SHA1_Init(&key->head);
+			SHA1_Update(&key->head, hmac_key, sizeof(hmac_key));
+
+			for (i = 0; i < sizeof(hmac_key); i++)
+				hmac_key[i] ^= 0x36 ^ 0x5c;	/* opad */
+			SHA1_Init(&key->tail);
+			SHA1_Update(&key->tail, hmac_key, sizeof(hmac_key));
+
+			explicit_bzero(hmac_key, sizeof(hmac_key));
+
+			return 1;
+		}
+	case EVP_CTRL_AEAD_TLS1_AAD:
+		{
+			unsigned char *p = ptr;
+			unsigned int len = p[arg - 2] << 8 | p[arg - 1];
+
+			if (ctx->encrypt) {
+				key->payload_length = len;
+				if ((key->aux.tls_ver = p[arg - 4] << 8 |
+				    p[arg - 3]) >= TLS1_1_VERSION) {
+					len -= AES_BLOCK_SIZE;
+					p[arg - 2] = len >> 8;
+					p[arg - 1] = len;
+				}
+				key->md = key->head;
+				SHA1_Update(&key->md, p, arg);
+
+				return (int)(((len + SHA_DIGEST_LENGTH +
+				    AES_BLOCK_SIZE) & -AES_BLOCK_SIZE) - len);
+			} else {
+				if (arg > 13)
+					arg = 13;
+				memcpy(key->aux.tls_aad, ptr, arg);
+				key->payload_length = arg;
+
+				return SHA_DIGEST_LENGTH;
+			}
+		}
+	default:
+		return -1;
+	}
+}
+
+static EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher = {
+#ifdef NID_aes_128_cbc_hmac_sha1
+	.nid = NID_aes_128_cbc_hmac_sha1,
+#else
+	.nid = NID_undef,
+#endif
+	.block_size = 16,
+	.key_len = 16,
+	.iv_len = 16,
+	.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
+	    EVP_CIPH_FLAG_AEAD_CIPHER,
+	.init = aesni_cbc_hmac_sha1_init_key,
+	.do_cipher = aesni_cbc_hmac_sha1_cipher,
+	.ctx_size = sizeof(EVP_AES_HMAC_SHA1),
+	.ctrl = aesni_cbc_hmac_sha1_ctrl
+};
+
+static EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher = {
+#ifdef NID_aes_256_cbc_hmac_sha1
+	.nid = NID_aes_256_cbc_hmac_sha1,
+#else
+	.nid = NID_undef,
+#endif
+	.block_size = 16,
+	.key_len = 32,
+	.iv_len = 16,
+	.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
+	    EVP_CIPH_FLAG_AEAD_CIPHER,
+	.init = aesni_cbc_hmac_sha1_init_key,
+	.do_cipher = aesni_cbc_hmac_sha1_cipher,
+	.ctx_size = sizeof(EVP_AES_HMAC_SHA1),
+	.ctrl = aesni_cbc_hmac_sha1_ctrl
+};
+
+const EVP_CIPHER *
+EVP_aes_128_cbc_hmac_sha1(void)
+{
+	return OPENSSL_ia32cap_P[1] & AESNI_CAPABLE ?
+	    &aesni_128_cbc_hmac_sha1_cipher : NULL;
+}
+
+const EVP_CIPHER *
+EVP_aes_256_cbc_hmac_sha1(void)
+{
+	return OPENSSL_ia32cap_P[1] & AESNI_CAPABLE ?
+	    &aesni_256_cbc_hmac_sha1_cipher : NULL;
+}
+#else
+const EVP_CIPHER *
+EVP_aes_128_cbc_hmac_sha1(void)
+{
+	return NULL;
+}
+
+const EVP_CIPHER *
+EVP_aes_256_cbc_hmac_sha1(void)
+{
+	    return NULL;
+}
+#endif
+#endif
diff --git a/crypto/libressl/crypto/evp/e_bf.c b/crypto/libressl/crypto/evp/e_bf.c
new file mode 100644
index 0000000000..5806f9c8b9
--- /dev/null
+++ b/crypto/libressl/crypto/evp/e_bf.c
@@ -0,0 +1,91 @@
+/* $OpenBSD: e_bf.c,v 1.7 2014/07/10 22:45:57 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_BF
+
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+
+static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc);
+
+typedef struct {
+	BF_KEY ks;
+} EVP_BF_KEY;
+
+#define data(ctx)	EVP_C_DATA(EVP_BF_KEY,ctx)
+
+IMPLEMENT_BLOCK_CIPHER(bf, ks, BF, EVP_BF_KEY, NID_bf, 8, 16, 8, 64,
+    EVP_CIPH_VARIABLE_LENGTH, bf_init_key, NULL,
+    EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL)
+
+static int
+bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	BF_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key);
+	return 1;
+}
+#endif
diff --git a/crypto/libressl/crypto/evp/e_camellia.c b/crypto/libressl/crypto/evp/e_camellia.c
new file mode 100644
index 0000000000..b3512049b7
--- /dev/null
+++ b/crypto/libressl/crypto/evp/e_camellia.c
@@ -0,0 +1,124 @@
+/* $OpenBSD: e_camellia.c,v 1.6 2014/07/10 22:45:57 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_CAMELLIA
+#include 
+#include 
+#include 
+#include "evp_locl.h"
+
+static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc);
+
+/* Camellia subkey Structure */
+typedef struct {
+	CAMELLIA_KEY ks;
+} EVP_CAMELLIA_KEY;
+
+/* Attribute operation for Camellia */
+#define data(ctx)	EVP_C_DATA(EVP_CAMELLIA_KEY,ctx)
+
+IMPLEMENT_BLOCK_CIPHER(camellia_128, ks, Camellia, EVP_CAMELLIA_KEY,
+    NID_camellia_128, 16, 16, 16, 128,
+    0, camellia_init_key, NULL,
+    EVP_CIPHER_set_asn1_iv,
+    EVP_CIPHER_get_asn1_iv,
+    NULL)
+IMPLEMENT_BLOCK_CIPHER(camellia_192, ks, Camellia, EVP_CAMELLIA_KEY,
+    NID_camellia_192, 16, 24, 16, 128,
+    0, camellia_init_key, NULL,
+    EVP_CIPHER_set_asn1_iv,
+    EVP_CIPHER_get_asn1_iv,
+    NULL)
+IMPLEMENT_BLOCK_CIPHER(camellia_256, ks, Camellia, EVP_CAMELLIA_KEY,
+    NID_camellia_256, 16, 32, 16, 128,
+    0, camellia_init_key, NULL,
+    EVP_CIPHER_set_asn1_iv,
+    EVP_CIPHER_get_asn1_iv,
+    NULL)
+
+#define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits)	IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16)
+
+IMPLEMENT_CAMELLIA_CFBR(128, 1)
+IMPLEMENT_CAMELLIA_CFBR(192, 1)
+IMPLEMENT_CAMELLIA_CFBR(256, 1)
+
+IMPLEMENT_CAMELLIA_CFBR(128, 8)
+IMPLEMENT_CAMELLIA_CFBR(192, 8)
+IMPLEMENT_CAMELLIA_CFBR(256, 8)
+
+
+/* The subkey for Camellia is generated. */
+static int
+camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	int ret;
+
+	ret = Camellia_set_key(key, ctx->key_len * 8, ctx->cipher_data);
+
+	if (ret < 0) {
+		EVPerr(EVP_F_CAMELLIA_INIT_KEY,
+		    EVP_R_CAMELLIA_KEY_SETUP_FAILED);
+		return 0;
+	}
+
+	return 1;
+}
+#endif
diff --git a/crypto/libressl/crypto/evp/e_cast.c b/crypto/libressl/crypto/evp/e_cast.c
new file mode 100644
index 0000000000..2b43d34f5f
--- /dev/null
+++ b/crypto/libressl/crypto/evp/e_cast.c
@@ -0,0 +1,92 @@
+/* $OpenBSD: e_cast.c,v 1.6 2014/07/10 22:45:57 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_CAST
+
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+
+static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc);
+
+typedef struct {
+	CAST_KEY ks;
+} EVP_CAST_KEY;
+
+#define data(ctx)	EVP_C_DATA(EVP_CAST_KEY,ctx)
+
+IMPLEMENT_BLOCK_CIPHER(cast5, ks, CAST, EVP_CAST_KEY,
+    NID_cast5, 8, CAST_KEY_LENGTH, 8, 64,
+    EVP_CIPH_VARIABLE_LENGTH, cast_init_key, NULL,
+    EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL)
+
+static int
+cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	CAST_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key);
+	return 1;
+}
+#endif
diff --git a/crypto/libressl/crypto/evp/e_chacha.c b/crypto/libressl/crypto/evp/e_chacha.c
new file mode 100644
index 0000000000..ad2425533b
--- /dev/null
+++ b/crypto/libressl/crypto/evp/e_chacha.c
@@ -0,0 +1,69 @@
+/* $OpenBSD: e_chacha.c,v 1.4 2014/07/10 22:45:57 jsing Exp $ */
+/*
+ * Copyright (c) 2014 Joel Sing 
+ *
+ * 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 
+
+#ifndef OPENSSL_NO_CHACHA
+
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+
+static int chacha_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len);
+static int chacha_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc);
+
+static const EVP_CIPHER chacha20_cipher = {
+	.nid = NID_chacha20,
+	.block_size = 1,
+	.key_len = 32,
+	.iv_len = 8,
+	.flags = EVP_CIPH_STREAM_CIPHER,
+	.init = chacha_init,
+	.do_cipher = chacha_cipher,
+	.ctx_size = sizeof(ChaCha_ctx)
+};
+
+const EVP_CIPHER *
+EVP_chacha20(void)
+{
+	return (&chacha20_cipher);
+}
+
+static int
+chacha_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	ChaCha_set_key((ChaCha_ctx *)ctx->cipher_data, key,
+	    EVP_CIPHER_CTX_key_length(ctx) * 8);
+	if (iv != NULL)
+		ChaCha_set_iv((ChaCha_ctx *)ctx->cipher_data, iv, NULL);
+	return 1;
+}
+
+static int
+chacha_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
+    size_t len)
+{
+	ChaCha((ChaCha_ctx *)ctx->cipher_data, out, in, len);
+	return 1;
+}
+
+#endif
diff --git a/crypto/libressl/crypto/evp/e_chacha20poly1305.c b/crypto/libressl/crypto/evp/e_chacha20poly1305.c
new file mode 100644
index 0000000000..3678f3e4ed
--- /dev/null
+++ b/crypto/libressl/crypto/evp/e_chacha20poly1305.c
@@ -0,0 +1,324 @@
+/* $OpenBSD: e_chacha20poly1305.c,v 1.13 2016/04/13 13:25:05 jsing Exp $ */
+
+/*
+ * Copyright (c) 2015 Reyk Floter 
+ * Copyright (c) 2014, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or 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 
+#include 
+
+#include 
+
+#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
+
+#include 
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+
+#define POLY1305_TAG_LEN 16
+#define CHACHA20_NONCE_LEN_OLD 8
+
+/*
+ * The informational RFC 7539, "ChaCha20 and Poly1305 for IETF Protocols",
+ * introduced a modified AEAD construction that is incompatible with the
+ * common style that has been already used in TLS.  The IETF version also
+ * adds a constant (salt) that is prepended to the nonce.
+ */
+#define CHACHA20_CONSTANT_LEN 4
+#define CHACHA20_IV_LEN 8
+#define CHACHA20_NONCE_LEN (CHACHA20_CONSTANT_LEN + CHACHA20_IV_LEN)
+
+struct aead_chacha20_poly1305_ctx {
+	unsigned char key[32];
+	unsigned char tag_len;
+};
+
+static int
+aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const unsigned char *key,
+    size_t key_len, size_t tag_len)
+{
+	struct aead_chacha20_poly1305_ctx *c20_ctx;
+
+	if (tag_len == 0)
+		tag_len = POLY1305_TAG_LEN;
+
+	if (tag_len > POLY1305_TAG_LEN) {
+		EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_INIT, EVP_R_TOO_LARGE);
+		return 0;
+	}
+
+	/* Internal error - EVP_AEAD_CTX_init should catch this. */
+	if (key_len != sizeof(c20_ctx->key))
+		return 0;
+
+	c20_ctx = malloc(sizeof(struct aead_chacha20_poly1305_ctx));
+	if (c20_ctx == NULL)
+		return 0;
+
+	memcpy(&c20_ctx->key[0], key, key_len);
+	c20_ctx->tag_len = tag_len;
+	ctx->aead_state = c20_ctx;
+
+	return 1;
+}
+
+static void
+aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx)
+{
+	struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
+
+	explicit_bzero(c20_ctx->key, sizeof(c20_ctx->key));
+	free(c20_ctx);
+}
+
+static void
+poly1305_update_with_length(poly1305_state *poly1305,
+    const unsigned char *data, size_t data_len)
+{
+	size_t j = data_len;
+	unsigned char length_bytes[8];
+	unsigned i;
+
+	for (i = 0; i < sizeof(length_bytes); i++) {
+		length_bytes[i] = j;
+		j >>= 8;
+	}
+
+	if (data != NULL)
+		CRYPTO_poly1305_update(poly1305, data, data_len);
+	CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes));
+}
+
+static void
+poly1305_update_with_pad16(poly1305_state *poly1305,
+    const unsigned char *data, size_t data_len)
+{
+	static const unsigned char zero_pad16[16];
+	size_t pad_len;
+
+	CRYPTO_poly1305_update(poly1305, data, data_len);
+
+	/* pad16() is defined in RFC 7539 2.8.1. */
+	if ((pad_len = data_len % 16) == 0)
+		return;
+
+	CRYPTO_poly1305_update(poly1305, zero_pad16, 16 - pad_len);
+}
+
+static int
+aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out,
+    size_t *out_len, size_t max_out_len, const unsigned char *nonce,
+    size_t nonce_len, const unsigned char *in, size_t in_len,
+    const unsigned char *ad, size_t ad_len)
+{
+	const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
+	unsigned char poly1305_key[32];
+	poly1305_state poly1305;
+	const unsigned char *iv;
+	const uint64_t in_len_64 = in_len;
+	uint64_t ctr;
+
+	/* The underlying ChaCha implementation may not overflow the block
+	 * counter into the second counter word. Therefore we disallow
+	 * individual operations that work on more than 2TB at a time.
+	 * in_len_64 is needed because, on 32-bit platforms, size_t is only
+	 * 32-bits and this produces a warning because it's always false.
+	 * Casting to uint64_t inside the conditional is not sufficient to stop
+	 * the warning. */
+	if (in_len_64 >= (1ULL << 32) * 64 - 64) {
+		EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_TOO_LARGE);
+		return 0;
+	}
+
+	if (max_out_len < in_len + c20_ctx->tag_len) {
+		EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL,
+		    EVP_R_BUFFER_TOO_SMALL);
+		return 0;
+	}
+
+	if (nonce_len != ctx->aead->nonce_len) {
+		EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_IV_TOO_LARGE);
+		return 0;
+	}
+
+	if (nonce_len == CHACHA20_NONCE_LEN_OLD) {
+		/* Google's draft-agl-tls-chacha20poly1305-04, Nov 2013 */
+
+		memset(poly1305_key, 0, sizeof(poly1305_key));
+		CRYPTO_chacha_20(poly1305_key, poly1305_key,
+		    sizeof(poly1305_key), c20_ctx->key, nonce, 0);
+
+		CRYPTO_poly1305_init(&poly1305, poly1305_key);
+		poly1305_update_with_length(&poly1305, ad, ad_len);
+		CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1);
+		poly1305_update_with_length(&poly1305, out, in_len);
+	} else if (nonce_len == CHACHA20_NONCE_LEN) {
+		/* RFC 7539, May 2015 */
+
+		ctr = (uint64_t)(nonce[0] | nonce[1] << 8 |
+		    nonce[2] << 16 | nonce[3] << 24) << 32;
+		iv = nonce + CHACHA20_CONSTANT_LEN;
+
+		memset(poly1305_key, 0, sizeof(poly1305_key));
+		CRYPTO_chacha_20(poly1305_key, poly1305_key,
+		    sizeof(poly1305_key), c20_ctx->key, iv, ctr);
+
+		CRYPTO_poly1305_init(&poly1305, poly1305_key);
+		poly1305_update_with_pad16(&poly1305, ad, ad_len);
+		CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, iv, ctr + 1);
+		poly1305_update_with_pad16(&poly1305, out, in_len);
+		poly1305_update_with_length(&poly1305, NULL, ad_len);
+		poly1305_update_with_length(&poly1305, NULL, in_len);
+	}
+
+	if (c20_ctx->tag_len != POLY1305_TAG_LEN) {
+		unsigned char tag[POLY1305_TAG_LEN];
+		CRYPTO_poly1305_finish(&poly1305, tag);
+		memcpy(out + in_len, tag, c20_ctx->tag_len);
+		*out_len = in_len + c20_ctx->tag_len;
+		return 1;
+	}
+
+	CRYPTO_poly1305_finish(&poly1305, out + in_len);
+	*out_len = in_len + POLY1305_TAG_LEN;
+	return 1;
+}
+
+static int
+aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
+    size_t *out_len, size_t max_out_len, const unsigned char *nonce,
+    size_t nonce_len, const unsigned char *in, size_t in_len,
+    const unsigned char *ad, size_t ad_len)
+{
+	const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
+	unsigned char mac[POLY1305_TAG_LEN];
+	unsigned char poly1305_key[32];
+	const unsigned char *iv = nonce;
+	poly1305_state poly1305;
+	const uint64_t in_len_64 = in_len;
+	size_t plaintext_len;
+	uint64_t ctr = 0;
+
+	if (in_len < c20_ctx->tag_len) {
+		EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT);
+		return 0;
+	}
+
+	/* The underlying ChaCha implementation may not overflow the block
+	 * counter into the second counter word. Therefore we disallow
+	 * individual operations that work on more than 2TB at a time.
+	 * in_len_64 is needed because, on 32-bit platforms, size_t is only
+	 * 32-bits and this produces a warning because it's always false.
+	 * Casting to uint64_t inside the conditional is not sufficient to stop
+	 * the warning. */
+	if (in_len_64 >= (1ULL << 32) * 64 - 64) {
+		EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_TOO_LARGE);
+		return 0;
+	}
+
+	if (nonce_len != ctx->aead->nonce_len) {
+		EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_IV_TOO_LARGE);
+		return 0;
+	}
+
+	plaintext_len = in_len - c20_ctx->tag_len;
+
+	if (max_out_len < plaintext_len) {
+		EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN,
+		    EVP_R_BUFFER_TOO_SMALL);
+		return 0;
+	}
+
+	if (nonce_len == CHACHA20_NONCE_LEN_OLD) {
+		/* Google's draft-agl-tls-chacha20poly1305-04, Nov 2013 */
+
+		memset(poly1305_key, 0, sizeof(poly1305_key));
+		CRYPTO_chacha_20(poly1305_key, poly1305_key,
+		    sizeof(poly1305_key), c20_ctx->key, nonce, 0);
+
+		CRYPTO_poly1305_init(&poly1305, poly1305_key);
+		poly1305_update_with_length(&poly1305, ad, ad_len);
+		poly1305_update_with_length(&poly1305, in, plaintext_len);
+	} else if (nonce_len == CHACHA20_NONCE_LEN) {
+		/* RFC 7539, May 2015 */
+
+		ctr = (uint64_t)(nonce[0] | nonce[1] << 8 |
+		    nonce[2] << 16 | nonce[3] << 24) << 32;
+		iv = nonce + CHACHA20_CONSTANT_LEN;
+
+		memset(poly1305_key, 0, sizeof(poly1305_key));
+		CRYPTO_chacha_20(poly1305_key, poly1305_key,
+		    sizeof(poly1305_key), c20_ctx->key, iv, ctr);
+
+		CRYPTO_poly1305_init(&poly1305, poly1305_key);
+		poly1305_update_with_pad16(&poly1305, ad, ad_len);
+		poly1305_update_with_pad16(&poly1305, in, plaintext_len);
+		poly1305_update_with_length(&poly1305, NULL, ad_len);
+		poly1305_update_with_length(&poly1305, NULL, plaintext_len);
+	}
+
+	CRYPTO_poly1305_finish(&poly1305, mac);
+
+	if (timingsafe_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) {
+		EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT);
+		return 0;
+	}
+
+	CRYPTO_chacha_20(out, in, plaintext_len, c20_ctx->key, iv, ctr + 1);
+	*out_len = plaintext_len;
+	return 1;
+}
+
+static const EVP_AEAD aead_chacha20_poly1305 = {
+	.key_len = 32,
+	.nonce_len = CHACHA20_NONCE_LEN,
+	.overhead = POLY1305_TAG_LEN,
+	.max_tag_len = POLY1305_TAG_LEN,
+
+	.init = aead_chacha20_poly1305_init,
+	.cleanup = aead_chacha20_poly1305_cleanup,
+	.seal = aead_chacha20_poly1305_seal,
+	.open = aead_chacha20_poly1305_open,
+};
+
+static const EVP_AEAD aead_chacha20_poly1305_old = {
+	.key_len = 32,
+	.nonce_len = CHACHA20_NONCE_LEN_OLD,
+	.overhead = POLY1305_TAG_LEN,
+	.max_tag_len = POLY1305_TAG_LEN,
+
+	.init = aead_chacha20_poly1305_init,
+	.cleanup = aead_chacha20_poly1305_cleanup,
+	.seal = aead_chacha20_poly1305_seal,
+	.open = aead_chacha20_poly1305_open,
+};
+
+const EVP_AEAD *
+EVP_aead_chacha20_poly1305()
+{
+	return &aead_chacha20_poly1305;
+}
+
+const EVP_AEAD *
+EVP_aead_chacha20_poly1305_old()
+{
+	return &aead_chacha20_poly1305_old;
+}
+
+#endif  /* !OPENSSL_NO_CHACHA && !OPENSSL_NO_POLY1305 */
diff --git a/crypto/libressl/crypto/evp/e_des.c b/crypto/libressl/crypto/evp/e_des.c
new file mode 100644
index 0000000000..db700ec134
--- /dev/null
+++ b/crypto/libressl/crypto/evp/e_des.c
@@ -0,0 +1,226 @@
+/* $OpenBSD: e_des.c,v 1.13 2014/10/18 17:20:40 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_DES
+
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+
+static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc);
+static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
+
+/* Because of various casts and different names can't use IMPLEMENT_BLOCK_CIPHER */
+
+static int
+des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl)
+{
+	BLOCK_CIPHER_ecb_loop()
+		DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i),
+		    ctx->cipher_data, ctx->encrypt);
+	return 1;
+}
+
+static int
+des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl)
+{
+	while (inl >= EVP_MAXCHUNK) {
+		DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data,
+		    (DES_cblock *)ctx->iv, &ctx->num);
+		inl -= EVP_MAXCHUNK;
+		in += EVP_MAXCHUNK;
+		out += EVP_MAXCHUNK;
+	}
+	if (inl)
+		DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data,
+		    (DES_cblock *)ctx->iv, &ctx->num);
+	return 1;
+}
+
+static int
+des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl)
+{
+	while (inl >= EVP_MAXCHUNK) {
+		DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data,
+		    (DES_cblock *)ctx->iv, ctx->encrypt);
+		inl -= EVP_MAXCHUNK;
+		in += EVP_MAXCHUNK;
+		out += EVP_MAXCHUNK;
+	}
+	if (inl)
+		DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data,
+		    (DES_cblock *)ctx->iv, ctx->encrypt);
+	return 1;
+}
+
+static int
+des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl)
+{
+	while (inl >= EVP_MAXCHUNK) {
+		DES_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data,
+		    (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
+		inl -= EVP_MAXCHUNK;
+		in += EVP_MAXCHUNK;
+		out += EVP_MAXCHUNK;
+	}
+	if (inl)
+		DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data,
+		    (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
+	return 1;
+}
+
+/* Although we have a CFB-r implementation for DES, it doesn't pack the right
+   way, so wrap it here */
+static int
+des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl)
+{
+	size_t n, chunk = EVP_MAXCHUNK/8;
+	unsigned char c[1], d[1];
+
+	if (inl < chunk)
+		chunk = inl;
+
+	while (inl && inl >= chunk) {
+		for (n = 0; n < chunk*8; ++n) {
+			c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
+			DES_cfb_encrypt(c, d, 1, 1, ctx->cipher_data,
+			    (DES_cblock *)ctx->iv, ctx->encrypt);
+			out[n / 8] = (out[n / 8] &
+			    ~(0x80 >> (unsigned int)(n % 8))) |
+			    ((d[0] & 0x80) >> (unsigned int)(n % 8));
+		}
+		inl -= chunk;
+		in += chunk;
+		out += chunk;
+		if (inl < chunk)
+			chunk = inl;
+	}
+
+	return 1;
+}
+
+static int
+des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl)
+{
+	while (inl >= EVP_MAXCHUNK) {
+		DES_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK,
+		    ctx->cipher_data, (DES_cblock *)ctx->iv, ctx->encrypt);
+		inl -= EVP_MAXCHUNK;
+		in += EVP_MAXCHUNK;
+		out += EVP_MAXCHUNK;
+	}
+	if (inl)
+		DES_cfb_encrypt(in, out, 8, (long)inl, ctx->cipher_data,
+		    (DES_cblock *)ctx->iv, ctx->encrypt);
+	return 1;
+}
+
+BLOCK_CIPHER_defs(des, DES_key_schedule, NID_des, 8, 8, 8, 64,
+    EVP_CIPH_RAND_KEY, des_init_key, NULL,
+    EVP_CIPHER_set_asn1_iv,
+    EVP_CIPHER_get_asn1_iv,
+    des_ctrl)
+
+BLOCK_CIPHER_def_cfb(des, DES_key_schedule, NID_des, 8, 8, 1,
+    EVP_CIPH_RAND_KEY, des_init_key, NULL,
+    EVP_CIPHER_set_asn1_iv,
+    EVP_CIPHER_get_asn1_iv, des_ctrl)
+
+BLOCK_CIPHER_def_cfb(des, DES_key_schedule, NID_des, 8, 8, 8,
+    EVP_CIPH_RAND_KEY, des_init_key, NULL,
+    EVP_CIPHER_set_asn1_iv,
+    EVP_CIPHER_get_asn1_iv, des_ctrl)
+
+static int
+des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	DES_cblock *deskey = (DES_cblock *)key;
+
+	DES_set_key_unchecked(deskey, ctx->cipher_data);
+	return 1;
+}
+
+static int
+des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+	switch (type) {
+	case EVP_CTRL_RAND_KEY:
+		if (DES_random_key((DES_cblock *)ptr) == 0)
+			return 0;
+		return 1;
+
+	default:
+		return -1;
+	}
+}
+
+#endif
diff --git a/crypto/libressl/crypto/evp/e_des3.c b/crypto/libressl/crypto/evp/e_des3.c
new file mode 100644
index 0000000000..0b08a5269c
--- /dev/null
+++ b/crypto/libressl/crypto/evp/e_des3.c
@@ -0,0 +1,284 @@
+/* $OpenBSD: e_des3.c,v 1.18 2014/10/18 17:20:40 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_DES
+
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+
+static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc);
+
+static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc);
+
+static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
+
+typedef struct {
+    DES_key_schedule ks1;/* key schedule */
+    DES_key_schedule ks2;/* key schedule (for ede) */
+    DES_key_schedule ks3;/* key schedule (for ede3) */
+} DES_EDE_KEY;
+
+#define data(ctx) ((DES_EDE_KEY *)(ctx)->cipher_data)
+
+/* Because of various casts and different args can't use IMPLEMENT_BLOCK_CIPHER */
+
+static int
+des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl)
+{
+	BLOCK_CIPHER_ecb_loop()
+	DES_ecb3_encrypt((const_DES_cblock *)(in + i), (DES_cblock *)(out + i),
+	    &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, ctx->encrypt);
+	return 1;
+}
+
+static int
+des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl)
+{
+	while (inl >= EVP_MAXCHUNK) {
+		DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK,
+		    &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+		    (DES_cblock *)ctx->iv, &ctx->num);
+		inl -= EVP_MAXCHUNK;
+		in += EVP_MAXCHUNK;
+		out += EVP_MAXCHUNK;
+	}
+	if (inl)
+		DES_ede3_ofb64_encrypt(in, out, (long)inl,
+		    &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+		    (DES_cblock *)ctx->iv, &ctx->num);
+
+	return 1;
+}
+
+static int
+des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl)
+{
+	while (inl >= EVP_MAXCHUNK) {
+		DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK,
+		    &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+		    (DES_cblock *)ctx->iv, ctx->encrypt);
+		inl -= EVP_MAXCHUNK;
+		in += EVP_MAXCHUNK;
+		out += EVP_MAXCHUNK;
+	}
+	if (inl)
+		DES_ede3_cbc_encrypt(in, out, (long)inl,
+		    &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+		    (DES_cblock *)ctx->iv, ctx->encrypt);
+	return 1;
+}
+
+static int
+des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl)
+{
+	while (inl >= EVP_MAXCHUNK) {
+		DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK,
+		    &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+		    (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
+		inl -= EVP_MAXCHUNK;
+		in += EVP_MAXCHUNK;
+		out += EVP_MAXCHUNK;
+	}
+	if (inl)
+		DES_ede3_cfb64_encrypt(in, out, (long)inl,
+		    &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+		    (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
+	return 1;
+}
+
+/* Although we have a CFB-r implementation for 3-DES, it doesn't pack the right
+   way, so wrap it here */
+static int
+des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl)
+{
+	size_t n;
+	unsigned char c[1], d[1];
+
+	for (n = 0; n < inl; ++n) {
+		c[0] = (in[n/8]&(1 << (7 - n % 8))) ? 0x80 : 0;
+		DES_ede3_cfb_encrypt(c, d, 1, 1,
+		    &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+		    (DES_cblock *)ctx->iv, ctx->encrypt);
+		out[n / 8] = (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) |
+		    ((d[0] & 0x80) >> (unsigned int)(n % 8));
+	}
+
+	return 1;
+}
+
+static int
+des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl)
+{
+	while (inl >= EVP_MAXCHUNK) {
+		DES_ede3_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK,
+		    &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+		    (DES_cblock *)ctx->iv, ctx->encrypt);
+		inl -= EVP_MAXCHUNK;
+		in += EVP_MAXCHUNK;
+		out += EVP_MAXCHUNK;
+	}
+	if (inl)
+		DES_ede3_cfb_encrypt(in, out, 8, (long)inl,
+		    &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+		    (DES_cblock *)ctx->iv, ctx->encrypt);
+	return 1;
+}
+
+BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64,
+    EVP_CIPH_RAND_KEY, des_ede_init_key, NULL,
+    EVP_CIPHER_set_asn1_iv,
+    EVP_CIPHER_get_asn1_iv,
+    des3_ctrl)
+
+#define des_ede3_cfb64_cipher des_ede_cfb64_cipher
+#define des_ede3_ofb_cipher des_ede_ofb_cipher
+#define des_ede3_cbc_cipher des_ede_cbc_cipher
+#define des_ede3_ecb_cipher des_ede_ecb_cipher
+
+BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64,
+    EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL,
+    EVP_CIPHER_set_asn1_iv,
+    EVP_CIPHER_get_asn1_iv,
+    des3_ctrl)
+
+BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 1,
+    EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL,
+    EVP_CIPHER_set_asn1_iv,
+    EVP_CIPHER_get_asn1_iv,
+    des3_ctrl)
+
+BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 8,
+    EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL,
+    EVP_CIPHER_set_asn1_iv,
+    EVP_CIPHER_get_asn1_iv,
+    des3_ctrl)
+
+static int
+des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	DES_cblock *deskey = (DES_cblock *)key;
+
+	DES_set_key_unchecked(&deskey[0], &data(ctx)->ks1);
+	DES_set_key_unchecked(&deskey[1], &data(ctx)->ks2);
+	memcpy(&data(ctx)->ks3, &data(ctx)->ks1,
+	    sizeof(data(ctx)->ks1));
+	return 1;
+}
+
+static int
+des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	DES_cblock *deskey = (DES_cblock *)key;
+
+
+	DES_set_key_unchecked(&deskey[0], &data(ctx)->ks1);
+	DES_set_key_unchecked(&deskey[1], &data(ctx)->ks2);
+	DES_set_key_unchecked(&deskey[2], &data(ctx)->ks3);
+	return 1;
+}
+
+static int
+des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+	DES_cblock *deskey = ptr;
+
+	switch (type) {
+	case EVP_CTRL_RAND_KEY:
+		if (DES_random_key(deskey) == 0)
+			return 0;
+		if (c->key_len >= 16 && DES_random_key(deskey + 1) == 0)
+			return 0;
+		if (c->key_len >= 24 && DES_random_key(deskey + 2) == 0)
+			return 0;
+		return 1;
+
+	default:
+		return -1;
+	}
+}
+
+const EVP_CIPHER *
+EVP_des_ede(void)
+{
+	return &des_ede_ecb;
+}
+
+const EVP_CIPHER *
+EVP_des_ede3(void)
+{
+	return &des_ede3_ecb;
+}
+#endif
diff --git a/crypto/libressl/crypto/evp/e_gost2814789.c b/crypto/libressl/crypto/evp/e_gost2814789.c
new file mode 100644
index 0000000000..cbb6b22e33
--- /dev/null
+++ b/crypto/libressl/crypto/evp/e_gost2814789.c
@@ -0,0 +1,229 @@
+/* $OpenBSD: e_gost2814789.c,v 1.2 2014/11/09 23:06:50 miod Exp $ */
+/*
+ * Copyright (c) 2014 Dmitry Eremin-Solenikov 
+ * Copyright (c) 2005-2006 Cryptocom LTD
+ *
+ * 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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_GOST
+#include 
+#include 
+#include 
+#include "evp_locl.h"
+
+typedef struct {
+	GOST2814789_KEY ks;
+	int param_nid;
+} EVP_GOST2814789_CTX;
+
+static int
+gost2814789_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+	EVP_GOST2814789_CTX *c = ctx->cipher_data;
+
+	switch (type) {
+	case EVP_CTRL_PBE_PRF_NID:
+		if (ptr != NULL) {
+			*((int *)ptr) = NID_id_HMACGostR3411_94;
+			return 1;
+		} else {
+			return 0;
+		}
+	case EVP_CTRL_INIT:
+		/* Default value to have any s-box set at all */
+		c->param_nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet;
+		return Gost2814789_set_sbox(&c->ks, c->param_nid);
+	case EVP_CTRL_GOST_SET_SBOX:
+		return Gost2814789_set_sbox(&c->ks, arg);
+	default:
+		return -1;
+	}
+}
+
+static int
+gost2814789_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	EVP_GOST2814789_CTX *c = ctx->cipher_data;
+
+	return Gost2814789_set_key(&c->ks, key, ctx->key_len * 8);
+}
+
+int
+gost2814789_set_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
+{
+	int len = 0;
+	unsigned char *buf = NULL;
+	unsigned char *p = NULL;
+	EVP_GOST2814789_CTX *c = ctx->cipher_data;
+	ASN1_OCTET_STRING *os = NULL;
+	GOST_CIPHER_PARAMS *gcp = GOST_CIPHER_PARAMS_new();
+
+	if (gcp == NULL) {
+		GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS,
+		    ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	if (ASN1_OCTET_STRING_set(gcp->iv, ctx->iv, ctx->cipher->iv_len) == 0) {
+		GOST_CIPHER_PARAMS_free(gcp);
+		GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, ERR_R_ASN1_LIB);
+		return 0;
+	}
+	ASN1_OBJECT_free(gcp->enc_param_set);
+	gcp->enc_param_set = OBJ_nid2obj(c->param_nid);
+
+	len = i2d_GOST_CIPHER_PARAMS(gcp, NULL);
+	p = buf = malloc(len);
+	if (buf == NULL) {
+		GOST_CIPHER_PARAMS_free(gcp);
+		GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS,
+		    ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	i2d_GOST_CIPHER_PARAMS(gcp, &p);
+	GOST_CIPHER_PARAMS_free(gcp);
+
+	os = ASN1_OCTET_STRING_new();
+	if (os == NULL) {
+		free(buf);
+		GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS,
+		    ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	if (ASN1_OCTET_STRING_set(os, buf, len) == 0) {
+		ASN1_OCTET_STRING_free(os);
+		free(buf);
+		GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, ERR_R_ASN1_LIB);
+		return 0;
+	}
+	free(buf);
+
+	ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
+	return 1;
+}
+
+int
+gost2814789_get_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
+{
+	int ret = -1;
+	int len;
+	GOST_CIPHER_PARAMS *gcp = NULL;
+	EVP_GOST2814789_CTX *c = ctx->cipher_data;
+	unsigned char *p;
+
+	if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE)
+		return ret;
+
+	p = params->value.sequence->data;
+
+	gcp = d2i_GOST_CIPHER_PARAMS(NULL, (const unsigned char **)&p,
+	    params->value.sequence->length);
+
+	len = gcp->iv->length;
+	if (len != ctx->cipher->iv_len) {
+		GOST_CIPHER_PARAMS_free(gcp);
+		GOSTerr(GOST_F_GOST89_GET_ASN1_PARAMETERS,
+		    GOST_R_INVALID_IV_LENGTH);
+		return -1;
+	}
+
+	if (!Gost2814789_set_sbox(&c->ks, OBJ_obj2nid(gcp->enc_param_set))) {
+		GOST_CIPHER_PARAMS_free(gcp);
+		return -1;
+	}
+	c->param_nid = OBJ_obj2nid(gcp->enc_param_set);
+
+	memcpy(ctx->oiv, gcp->iv->data, len);
+	memcpy(ctx->iv, gcp->iv->data, len);
+
+	GOST_CIPHER_PARAMS_free(gcp);
+
+	return 1;
+}
+
+BLOCK_CIPHER_func_ecb(gost2814789, Gost2814789, EVP_GOST2814789_CTX, ks)
+BLOCK_CIPHER_func_cfb(gost2814789, Gost2814789, 64, EVP_GOST2814789_CTX, ks)
+
+static int
+gost2814789_cnt_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl)
+{
+	EVP_GOST2814789_CTX *c = ctx->cipher_data;
+
+	while (inl >= EVP_MAXCHUNK) {
+		Gost2814789_cnt_encrypt(in, out, (long)EVP_MAXCHUNK, &c->ks,
+		    ctx->iv, ctx->buf, &ctx->num);
+		inl -= EVP_MAXCHUNK;
+		in += EVP_MAXCHUNK;
+		out += EVP_MAXCHUNK;
+	}
+
+	if (inl)
+		Gost2814789_cnt_encrypt(in, out, inl, &c->ks, ctx->iv, ctx->buf,
+		    &ctx->num);
+	return 1;
+}
+
+/* gost89 is CFB-64 */
+#define NID_gost89_cfb64 NID_id_Gost28147_89
+
+BLOCK_CIPHER_def_ecb(gost2814789, EVP_GOST2814789_CTX, NID_gost89, 8, 32,
+		     EVP_CIPH_NO_PADDING | EVP_CIPH_CTRL_INIT,
+		     gost2814789_init_key, NULL, gost2814789_set_asn1_params,
+		     gost2814789_get_asn1_params, gost2814789_ctl)
+BLOCK_CIPHER_def_cfb(gost2814789, EVP_GOST2814789_CTX, NID_gost89, 32, 8, 64,
+		     EVP_CIPH_NO_PADDING | EVP_CIPH_CTRL_INIT,
+		     gost2814789_init_key, NULL, gost2814789_set_asn1_params,
+		     gost2814789_get_asn1_params, gost2814789_ctl)
+BLOCK_CIPHER_def1(gost2814789, cnt, cnt, OFB, EVP_GOST2814789_CTX, NID_gost89,
+		  1, 32, 8, EVP_CIPH_NO_PADDING | EVP_CIPH_CTRL_INIT,
+		  gost2814789_init_key, NULL, gost2814789_set_asn1_params,
+		  gost2814789_get_asn1_params, gost2814789_ctl)
+#endif
diff --git a/crypto/libressl/crypto/evp/e_idea.c b/crypto/libressl/crypto/evp/e_idea.c
new file mode 100644
index 0000000000..49ad399ae4
--- /dev/null
+++ b/crypto/libressl/crypto/evp/e_idea.c
@@ -0,0 +1,125 @@
+/* $OpenBSD: e_idea.c,v 1.9 2014/07/11 08:44:48 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_IDEA
+
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+
+static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc);
+
+/* NB idea_ecb_encrypt doesn't take an 'encrypt' argument so we treat it as a special
+ * case
+ */
+
+static int
+idea_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl)
+{
+	BLOCK_CIPHER_ecb_loop()
+	idea_ecb_encrypt(in + i, out + i, ctx->cipher_data);
+	return 1;
+}
+
+/* Can't use IMPLEMENT_BLOCK_CIPHER because idea_ecb_encrypt is different */
+
+typedef struct {
+	IDEA_KEY_SCHEDULE ks;
+} EVP_IDEA_KEY;
+
+BLOCK_CIPHER_func_cbc(idea, idea, EVP_IDEA_KEY, ks)
+BLOCK_CIPHER_func_ofb(idea, idea, 64, EVP_IDEA_KEY, ks)
+BLOCK_CIPHER_func_cfb(idea, idea, 64, EVP_IDEA_KEY, ks)
+
+BLOCK_CIPHER_defs(idea, IDEA_KEY_SCHEDULE, NID_idea, 8, 16, 8, 64,
+    0, idea_init_key, NULL,
+    EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL)
+
+static int
+idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	if (!enc) {
+		if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE)
+			enc = 1;
+		else if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE)
+			enc = 1;
+	}
+	if (enc)
+		idea_set_encrypt_key(key, ctx->cipher_data);
+	else {
+		IDEA_KEY_SCHEDULE tmp;
+
+		idea_set_encrypt_key(key, &tmp);
+		idea_set_decrypt_key(&tmp, ctx->cipher_data);
+		explicit_bzero((unsigned char *)&tmp,
+		    sizeof(IDEA_KEY_SCHEDULE));
+	}
+	return 1;
+}
+
+#endif
diff --git a/crypto/libressl/crypto/evp/e_null.c b/crypto/libressl/crypto/evp/e_null.c
new file mode 100644
index 0000000000..81adf75479
--- /dev/null
+++ b/crypto/libressl/crypto/evp/e_null.c
@@ -0,0 +1,105 @@
+/* $OpenBSD: e_null.c,v 1.13 2014/07/10 13:58:22 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+
+static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc);
+static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl);
+
+static const EVP_CIPHER n_cipher = {
+	NID_undef,
+	1, 0, 0,
+	0,
+	null_init_key,
+	null_cipher,
+	NULL,
+	0,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+const EVP_CIPHER *
+EVP_enc_null(void)
+{
+	return (&n_cipher);
+}
+
+static int
+null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	/*	memset(&(ctx->c),0,sizeof(ctx->c));*/
+	return 1;
+}
+
+static int
+null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl)
+{
+	if (in != out)
+		memcpy((char *)out, (const char *)in, inl);
+	return 1;
+}
diff --git a/crypto/libressl/crypto/evp/e_old.c b/crypto/libressl/crypto/evp/e_old.c
new file mode 100644
index 0000000000..28e328c631
--- /dev/null
+++ b/crypto/libressl/crypto/evp/e_old.c
@@ -0,0 +1,159 @@
+/* $OpenBSD: e_old.c,v 1.7 2014/07/10 22:45:57 jsing Exp $ */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#ifndef OPENSSL_NO_DEPRECATED
+
+#include 
+
+/* Define some deprecated functions, so older programs
+   don't crash and burn too quickly.  On Windows and VMS,
+   these will never be used, since functions and variables
+   in shared libraries are selected by entry point location,
+   not by name.  */
+
+#ifndef OPENSSL_NO_BF
+#undef EVP_bf_cfb
+const EVP_CIPHER *EVP_bf_cfb(void);
+const EVP_CIPHER *
+EVP_bf_cfb(void)
+{
+	return EVP_bf_cfb64();
+}
+#endif
+
+#ifndef OPENSSL_NO_DES
+#undef EVP_des_cfb
+const EVP_CIPHER *EVP_des_cfb(void);
+const EVP_CIPHER *
+EVP_des_cfb(void)
+{
+	return EVP_des_cfb64();
+}
+#undef EVP_des_ede3_cfb
+const EVP_CIPHER *EVP_des_ede3_cfb(void);
+const EVP_CIPHER *
+EVP_des_ede3_cfb(void)
+{
+	return EVP_des_ede3_cfb64();
+}
+#undef EVP_des_ede_cfb
+const EVP_CIPHER *EVP_des_ede_cfb(void);
+const EVP_CIPHER *
+EVP_des_ede_cfb(void)
+{
+	return EVP_des_ede_cfb64();
+}
+#endif
+
+#ifndef OPENSSL_NO_IDEA
+#undef EVP_idea_cfb
+const EVP_CIPHER *EVP_idea_cfb(void);
+const EVP_CIPHER *
+EVP_idea_cfb(void)
+{
+	return EVP_idea_cfb64();
+}
+#endif
+
+#ifndef OPENSSL_NO_RC2
+#undef EVP_rc2_cfb
+const EVP_CIPHER *EVP_rc2_cfb(void);
+const EVP_CIPHER *
+EVP_rc2_cfb(void)
+{
+	return EVP_rc2_cfb64();
+}
+#endif
+
+#ifndef OPENSSL_NO_CAST
+#undef EVP_cast5_cfb
+const EVP_CIPHER *EVP_cast5_cfb(void);
+const EVP_CIPHER *
+EVP_cast5_cfb(void)
+{
+	return EVP_cast5_cfb64();
+}
+#endif
+
+#ifndef OPENSSL_NO_AES
+#undef EVP_aes_128_cfb
+const EVP_CIPHER *EVP_aes_128_cfb(void);
+const EVP_CIPHER *
+EVP_aes_128_cfb(void)
+{
+	return EVP_aes_128_cfb128();
+}
+#undef EVP_aes_192_cfb
+const EVP_CIPHER *EVP_aes_192_cfb(void);
+const EVP_CIPHER *
+EVP_aes_192_cfb(void)
+{
+	return EVP_aes_192_cfb128();
+}
+#undef EVP_aes_256_cfb
+const EVP_CIPHER *EVP_aes_256_cfb(void);
+const EVP_CIPHER *
+EVP_aes_256_cfb(void)
+{
+	return EVP_aes_256_cfb128();
+}
+#endif
+
+#endif
diff --git a/crypto/libressl/crypto/evp/e_rc2.c b/crypto/libressl/crypto/evp/e_rc2.c
new file mode 100644
index 0000000000..0b3b94bdfa
--- /dev/null
+++ b/crypto/libressl/crypto/evp/e_rc2.c
@@ -0,0 +1,254 @@
+/* $OpenBSD: e_rc2.c,v 1.10 2014/07/11 08:44:48 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_RC2
+
+#include 
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+
+static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc);
+static int rc2_meth_to_magic(EVP_CIPHER_CTX *ctx);
+static int rc2_magic_to_meth(int i);
+static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
+
+typedef struct {
+	int key_bits;	/* effective key bits */
+	RC2_KEY ks;	/* key schedule */
+} EVP_RC2_KEY;
+
+#define data(ctx)	((EVP_RC2_KEY *)(ctx)->cipher_data)
+
+IMPLEMENT_BLOCK_CIPHER(rc2, ks, RC2, EVP_RC2_KEY, NID_rc2,
+    8,
+    RC2_KEY_LENGTH, 8, 64,
+    EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+    rc2_init_key, NULL,
+    rc2_set_asn1_type_and_iv, rc2_get_asn1_type_and_iv,
+    rc2_ctrl)
+
+#define RC2_40_MAGIC	0xa0
+#define RC2_64_MAGIC	0x78
+#define RC2_128_MAGIC	0x3a
+
+static const EVP_CIPHER r2_64_cbc_cipher = {
+	NID_rc2_64_cbc,
+	8, 8 /* 64 bit */, 8,
+	EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+	rc2_init_key,
+	rc2_cbc_cipher,
+	NULL,
+	sizeof(EVP_RC2_KEY),
+	rc2_set_asn1_type_and_iv,
+	rc2_get_asn1_type_and_iv,
+	rc2_ctrl,
+	NULL
+};
+
+static const EVP_CIPHER r2_40_cbc_cipher = {
+	NID_rc2_40_cbc,
+	8, 5 /* 40 bit */, 8,
+	EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+	rc2_init_key,
+	rc2_cbc_cipher,
+	NULL,
+	sizeof(EVP_RC2_KEY),
+	rc2_set_asn1_type_and_iv,
+	rc2_get_asn1_type_and_iv,
+	rc2_ctrl,
+	NULL
+};
+
+const EVP_CIPHER *
+EVP_rc2_64_cbc(void)
+{
+	return (&r2_64_cbc_cipher);
+}
+
+const EVP_CIPHER *
+EVP_rc2_40_cbc(void)
+{
+	return (&r2_40_cbc_cipher);
+}
+
+static int
+rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	RC2_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
+	    key, data(ctx)->key_bits);
+	return 1;
+}
+
+static int
+rc2_meth_to_magic(EVP_CIPHER_CTX *e)
+{
+	int i;
+
+	EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i);
+	if (i == 128)
+		return (RC2_128_MAGIC);
+	else if (i == 64)
+		return (RC2_64_MAGIC);
+	else if (i == 40)
+		return (RC2_40_MAGIC);
+	else
+		return (0);
+}
+
+static int
+rc2_magic_to_meth(int i)
+{
+	if (i == RC2_128_MAGIC)
+		return 128;
+	else if (i == RC2_64_MAGIC)
+		return 64;
+	else if (i == RC2_40_MAGIC)
+		return 40;
+	else {
+		EVPerr(EVP_F_RC2_MAGIC_TO_METH, EVP_R_UNSUPPORTED_KEY_SIZE);
+		return (0);
+	}
+}
+
+static int
+rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+	long num = 0;
+	int i = 0;
+	int key_bits;
+	unsigned int l;
+	unsigned char iv[EVP_MAX_IV_LENGTH];
+
+	if (type != NULL) {
+		l = EVP_CIPHER_CTX_iv_length(c);
+		if (l > sizeof(iv)) {
+			EVPerr(EVP_F_RC2_GET_ASN1_TYPE_AND_IV,
+			    EVP_R_IV_TOO_LARGE);
+			return -1;
+		}
+		i = ASN1_TYPE_get_int_octetstring(type, &num, iv, l);
+		if (i != (int)l)
+			return (-1);
+		key_bits = rc2_magic_to_meth((int)num);
+		if (!key_bits)
+			return (-1);
+		if (i > 0 && !EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1))
+			return -1;
+		EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS,
+		    key_bits, NULL);
+		EVP_CIPHER_CTX_set_key_length(c, key_bits / 8);
+	}
+	return (i);
+}
+
+static int
+rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+	long num;
+	int i = 0, j;
+
+	if (type != NULL) {
+		num = rc2_meth_to_magic(c);
+		j = EVP_CIPHER_CTX_iv_length(c);
+		i = ASN1_TYPE_set_int_octetstring(type, num, c->oiv, j);
+	}
+	return (i);
+}
+
+static int
+rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+	switch (type) {
+	case EVP_CTRL_INIT:
+		data(c)->key_bits = EVP_CIPHER_CTX_key_length(c) * 8;
+		return 1;
+
+	case EVP_CTRL_GET_RC2_KEY_BITS:
+		*(int *)ptr = data(c)->key_bits;
+		return 1;
+
+	case EVP_CTRL_SET_RC2_KEY_BITS:
+		if (arg > 0) {
+			data(c)->key_bits = arg;
+			return 1;
+		}
+		return 0;
+
+#ifdef PBE_PRF_TEST
+	case EVP_CTRL_PBE_PRF_NID:
+		*(int *)ptr = NID_hmacWithMD5;
+		return 1;
+#endif
+
+	default:
+		return -1;
+	}
+}
+
+#endif
diff --git a/crypto/libressl/crypto/evp/e_rc4.c b/crypto/libressl/crypto/evp/e_rc4.c
new file mode 100644
index 0000000000..93e1c869e5
--- /dev/null
+++ b/crypto/libressl/crypto/evp/e_rc4.c
@@ -0,0 +1,140 @@
+/* $OpenBSD: e_rc4.c,v 1.13 2014/07/10 22:45:57 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_RC4
+
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+
+/* FIXME: surely this is available elsewhere? */
+#define EVP_RC4_KEY_SIZE		16
+
+typedef struct {
+    RC4_KEY ks;	/* working key */
+} EVP_RC4_KEY;
+
+#define data(ctx) ((EVP_RC4_KEY *)(ctx)->cipher_data)
+
+static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc);
+static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl);
+
+static const EVP_CIPHER r4_cipher = {
+	NID_rc4,
+	1, EVP_RC4_KEY_SIZE, 0,
+	EVP_CIPH_VARIABLE_LENGTH,
+	rc4_init_key,
+	rc4_cipher,
+	NULL,
+	sizeof(EVP_RC4_KEY),
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+static const EVP_CIPHER r4_40_cipher = {
+	NID_rc4_40,
+	1, 5 /* 40 bit */, 0,
+	EVP_CIPH_VARIABLE_LENGTH,
+	rc4_init_key,
+	rc4_cipher,
+	NULL,
+	sizeof(EVP_RC4_KEY),
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+const EVP_CIPHER *
+EVP_rc4(void)
+{
+	return (&r4_cipher);
+}
+
+const EVP_CIPHER *
+EVP_rc4_40(void)
+{
+	return (&r4_40_cipher);
+}
+
+static int
+rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	RC4_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key);
+	return 1;
+}
+
+static int
+rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl)
+{
+	RC4(&data(ctx)->ks, inl, in, out);
+	return 1;
+}
+#endif
diff --git a/crypto/libressl/crypto/evp/e_rc4_hmac_md5.c b/crypto/libressl/crypto/evp/e_rc4_hmac_md5.c
new file mode 100644
index 0000000000..2747dcb2a6
--- /dev/null
+++ b/crypto/libressl/crypto/evp/e_rc4_hmac_md5.c
@@ -0,0 +1,309 @@
+/* $OpenBSD: e_rc4_hmac_md5.c,v 1.4 2014/07/10 22:45:57 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include 
+#include 
+
+#include 
+
+#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_MD5)
+
+#include 
+#include 
+#include 
+#include 
+
+#ifndef EVP_CIPH_FLAG_AEAD_CIPHER
+#define EVP_CIPH_FLAG_AEAD_CIPHER	0x200000
+#define EVP_CTRL_AEAD_TLS1_AAD		0x16
+#define EVP_CTRL_AEAD_SET_MAC_KEY	0x17
+#endif
+
+/* FIXME: surely this is available elsewhere? */
+#define EVP_RC4_KEY_SIZE		16
+
+typedef struct {
+	RC4_KEY		ks;
+	MD5_CTX		head, tail, md;
+	size_t		payload_length;
+} EVP_RC4_HMAC_MD5;
+
+#define NO_PAYLOAD_LENGTH	((size_t)-1)
+
+void rc4_md5_enc (RC4_KEY *key, const void *in0, void *out,
+    MD5_CTX *ctx, const void *inp, size_t blocks);
+
+#define data(ctx) ((EVP_RC4_HMAC_MD5 *)(ctx)->cipher_data)
+
+static int
+rc4_hmac_md5_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *inkey,
+    const unsigned char *iv, int enc)
+{
+	EVP_RC4_HMAC_MD5 *key = data(ctx);
+
+	RC4_set_key(&key->ks, EVP_CIPHER_CTX_key_length(ctx), inkey);
+
+	MD5_Init(&key->head);	/* handy when benchmarking */
+	key->tail = key->head;
+	key->md = key->head;
+
+	key->payload_length = NO_PAYLOAD_LENGTH;
+
+	return 1;
+}
+
+#if	!defined(OPENSSL_NO_ASM) && defined(RC4_MD5_ASM) &&	( \
+	defined(__x86_64)	|| defined(__x86_64__)	|| \
+	defined(_M_AMD64)	|| defined(_M_X64)	|| \
+	defined(__INTEL__)		) && \
+	!(defined(__APPLE__) && defined(__MACH__))
+#define	STITCHED_CALL
+#endif
+
+#if !defined(STITCHED_CALL)
+#define	rc4_off 0
+#define	md5_off 0
+#endif
+
+static int
+rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t len)
+{
+	EVP_RC4_HMAC_MD5 *key = data(ctx);
+#if defined(STITCHED_CALL)
+	size_t	rc4_off = 32-1-(key->ks.x&(32-1)),	/* 32 is $MOD from rc4_md5-x86_64.pl */
+	md5_off = MD5_CBLOCK - key->md.num,
+	    blocks;
+	unsigned int l;
+	extern unsigned int OPENSSL_ia32cap_P[];
+#endif
+	size_t	plen = key->payload_length;
+
+	if (plen != NO_PAYLOAD_LENGTH && len != (plen + MD5_DIGEST_LENGTH))
+		return 0;
+
+	if (ctx->encrypt) {
+		if (plen == NO_PAYLOAD_LENGTH)
+			plen = len;
+#if defined(STITCHED_CALL)
+		/* cipher has to "fall behind" */
+		if (rc4_off > md5_off)
+			md5_off += MD5_CBLOCK;
+
+		if (plen > md5_off &&
+		    (blocks = (plen - md5_off) / MD5_CBLOCK) &&
+		    (OPENSSL_ia32cap_P[0]&(1 << 20)) == 0) {
+			MD5_Update(&key->md, in, md5_off);
+			RC4(&key->ks, rc4_off, in, out);
+
+			rc4_md5_enc(&key->ks, in + rc4_off, out + rc4_off,
+			    &key->md, in + md5_off, blocks);
+			blocks *= MD5_CBLOCK;
+			rc4_off += blocks;
+			md5_off += blocks;
+			key->md.Nh += blocks >> 29;
+			key->md.Nl += blocks <<= 3;
+			if (key->md.Nl < (unsigned int)blocks)
+				key->md.Nh++;
+		} else {
+			rc4_off = 0;
+			md5_off = 0;
+		}
+#endif
+		MD5_Update(&key->md, in + md5_off, plen - md5_off);
+
+		if (plen!=len) {	/* "TLS" mode of operation */
+			if (in != out)
+				memcpy(out + rc4_off, in + rc4_off,
+				    plen - rc4_off);
+
+			/* calculate HMAC and append it to payload */
+			MD5_Final(out + plen, &key->md);
+			key->md = key->tail;
+			MD5_Update(&key->md, out + plen, MD5_DIGEST_LENGTH);
+			MD5_Final(out + plen, &key->md);
+
+			/* encrypt HMAC at once */
+			RC4(&key->ks, len - rc4_off, out + rc4_off,
+			    out + rc4_off);
+		} else {
+			RC4(&key->ks, len - rc4_off, in + rc4_off,
+			    out + rc4_off);
+		}
+	} else {
+		unsigned char mac[MD5_DIGEST_LENGTH];
+#if defined(STITCHED_CALL)
+		/* digest has to "fall behind" */
+		if (md5_off > rc4_off)
+			rc4_off += 2*MD5_CBLOCK;
+		else
+			rc4_off += MD5_CBLOCK;
+
+		if (len > rc4_off && (blocks = (len - rc4_off) / MD5_CBLOCK) &&
+		    (OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) {
+			RC4(&key->ks, rc4_off, in, out);
+			MD5_Update(&key->md, out, md5_off);
+
+			rc4_md5_enc(&key->ks, in + rc4_off, out + rc4_off,
+			    &key->md, out + md5_off, blocks);
+			blocks *= MD5_CBLOCK;
+			rc4_off += blocks;
+			md5_off += blocks;
+			l = (key->md.Nl + (blocks << 3)) & 0xffffffffU;
+			if (l < key->md.Nl)
+				key->md.Nh++;
+			key->md.Nl = l;
+			key->md.Nh += blocks >> 29;
+		} else {
+			md5_off = 0;
+			rc4_off = 0;
+		}
+#endif
+		/* decrypt HMAC at once */
+		RC4(&key->ks, len - rc4_off, in + rc4_off, out + rc4_off);
+		if (plen!=NO_PAYLOAD_LENGTH) {	/* "TLS" mode of operation */
+			MD5_Update(&key->md, out + md5_off, plen - md5_off);
+
+			/* calculate HMAC and verify it */
+			MD5_Final(mac, &key->md);
+			key->md = key->tail;
+			MD5_Update(&key->md, mac, MD5_DIGEST_LENGTH);
+			MD5_Final(mac, &key->md);
+
+			if (memcmp(out + plen, mac, MD5_DIGEST_LENGTH))
+				return 0;
+		} else {
+			MD5_Update(&key->md, out + md5_off, len - md5_off);
+		}
+	}
+
+	key->payload_length = NO_PAYLOAD_LENGTH;
+
+	return 1;
+}
+
+static int
+rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+	EVP_RC4_HMAC_MD5 *key = data(ctx);
+
+	switch (type) {
+	case EVP_CTRL_AEAD_SET_MAC_KEY:
+		{
+			unsigned int  i;
+			unsigned char hmac_key[64];
+
+			memset (hmac_key, 0, sizeof(hmac_key));
+
+			if (arg > (int)sizeof(hmac_key)) {
+				MD5_Init(&key->head);
+				MD5_Update(&key->head, ptr, arg);
+				MD5_Final(hmac_key, &key->head);
+			} else {
+				memcpy(hmac_key, ptr, arg);
+			}
+
+			for (i = 0; i < sizeof(hmac_key); i++)
+				hmac_key[i] ^= 0x36;		/* ipad */
+			MD5_Init(&key->head);
+			MD5_Update(&key->head, hmac_key, sizeof(hmac_key));
+
+			for (i = 0; i < sizeof(hmac_key); i++)
+				hmac_key[i] ^= 0x36 ^ 0x5c;	/* opad */
+			MD5_Init(&key->tail);
+			MD5_Update(&key->tail, hmac_key, sizeof(hmac_key));
+
+			return 1;
+		}
+	case EVP_CTRL_AEAD_TLS1_AAD:
+		{
+			unsigned char *p = ptr;
+			unsigned int len = p[arg - 2] << 8 | p[arg - 1];
+
+			if (!ctx->encrypt) {
+				len -= MD5_DIGEST_LENGTH;
+				p[arg - 2] = len >> 8;
+				p[arg - 1] = len;
+			}
+			key->payload_length = len;
+			key->md = key->head;
+			MD5_Update(&key->md, p, arg);
+
+			return MD5_DIGEST_LENGTH;
+		}
+	default:
+		return -1;
+	}
+}
+
+static EVP_CIPHER r4_hmac_md5_cipher = {
+#ifdef NID_rc4_hmac_md5
+	NID_rc4_hmac_md5,
+#else
+	NID_undef,
+#endif
+	1, EVP_RC4_KEY_SIZE, 0,
+	EVP_CIPH_STREAM_CIPHER|EVP_CIPH_VARIABLE_LENGTH|EVP_CIPH_FLAG_AEAD_CIPHER,
+	rc4_hmac_md5_init_key,
+	rc4_hmac_md5_cipher,
+	NULL,
+	sizeof(EVP_RC4_HMAC_MD5),
+	NULL,
+	NULL,
+	rc4_hmac_md5_ctrl,
+	NULL
+};
+
+const EVP_CIPHER *
+EVP_rc4_hmac_md5(void)
+{
+	return (&r4_hmac_md5_cipher);
+}
+#endif
diff --git a/crypto/libressl/crypto/evp/e_xcbc_d.c b/crypto/libressl/crypto/evp/e_xcbc_d.c
new file mode 100644
index 0000000000..aac732f644
--- /dev/null
+++ b/crypto/libressl/crypto/evp/e_xcbc_d.c
@@ -0,0 +1,137 @@
+/* $OpenBSD: e_xcbc_d.c,v 1.11 2014/07/10 22:45:57 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_DES
+
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+
+static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc);
+static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl);
+
+
+typedef struct {
+	DES_key_schedule ks;/* key schedule */
+	DES_cblock inw;
+	DES_cblock outw;
+} DESX_CBC_KEY;
+
+#define data(ctx) ((DESX_CBC_KEY *)(ctx)->cipher_data)
+
+static const EVP_CIPHER d_xcbc_cipher = {
+	NID_desx_cbc,
+	8, 24, 8,
+	EVP_CIPH_CBC_MODE,
+	desx_cbc_init_key,
+	desx_cbc_cipher,
+	NULL,
+	sizeof(DESX_CBC_KEY),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL,
+	NULL
+};
+
+const EVP_CIPHER *
+EVP_desx_cbc(void)
+{
+	return (&d_xcbc_cipher);
+}
+
+static int
+desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+{
+	DES_cblock *deskey = (DES_cblock *)key;
+
+	DES_set_key_unchecked(deskey, &data(ctx)->ks);
+	memcpy(&data(ctx)->inw[0], &key[8], 8);
+	memcpy(&data(ctx)->outw[0], &key[16], 8);
+
+	return 1;
+}
+
+static int
+desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+    const unsigned char *in, size_t inl)
+{
+	while (inl >= EVP_MAXCHUNK) {
+		DES_xcbc_encrypt(in, out, (long)EVP_MAXCHUNK, &data(ctx)->ks,
+		    (DES_cblock *)&(ctx->iv[0]), &data(ctx)->inw,
+		    &data(ctx)->outw, ctx->encrypt);
+		inl -= EVP_MAXCHUNK;
+		in += EVP_MAXCHUNK;
+		out += EVP_MAXCHUNK;
+	}
+	if (inl)
+		DES_xcbc_encrypt(in, out, (long)inl, &data(ctx)->ks,
+		    (DES_cblock *)&(ctx->iv[0]), &data(ctx)->inw,
+		    &data(ctx)->outw, ctx->encrypt);
+	return 1;
+}
+#endif
diff --git a/crypto/libressl/crypto/evp/encode.c b/crypto/libressl/crypto/evp/encode.c
new file mode 100644
index 0000000000..bbc94bafe3
--- /dev/null
+++ b/crypto/libressl/crypto/evp/encode.c
@@ -0,0 +1,423 @@
+/* $OpenBSD: encode.c,v 1.23 2016/05/04 14:53:29 tedu Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#define conv_bin2ascii(a)	(data_bin2ascii[(a)&0x3f])
+#define conv_ascii2bin(a)	(data_ascii2bin[(a)&0x7f])
+
+/* 64 char lines
+ * pad input with 0
+ * left over chars are set to =
+ * 1 byte  => xx==
+ * 2 bytes => xxx=
+ * 3 bytes => xxxx
+ */
+#define BIN_PER_LINE    (64/4*3)
+#define CHUNKS_PER_LINE (64/4)
+#define CHAR_PER_LINE   (64+1)
+
+static const unsigned char data_bin2ascii[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\
+abcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/* 0xF0 is a EOLN
+ * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing).
+ * 0xF2 is EOF
+ * 0xE0 is ignore at start of line.
+ * 0xFF is error
+ */
+
+#define B64_EOLN		0xF0
+#define B64_CR			0xF1
+#define B64_EOF			0xF2
+#define B64_WS			0xE0
+#define B64_ERROR       	0xFF
+#define B64_NOT_BASE64(a)	(((a)|0x13) == 0xF3)
+
+static const unsigned char data_ascii2bin[128] = {
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xE0, 0xF0, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F,
+	0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
+	0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
+	0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+	0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
+	0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
+	0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
+	0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+	0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
+	0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+void
+EVP_EncodeInit(EVP_ENCODE_CTX *ctx)
+{
+	ctx->length = 48;
+	ctx->num = 0;
+	ctx->line_num = 0;
+}
+
+void
+EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
+    const unsigned char *in, int inl)
+{
+	int i, j;
+	size_t total = 0;
+
+	*outl = 0;
+	if (inl == 0)
+		return;
+	OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data));
+	if (ctx->length - ctx->num > inl) {
+		memcpy(&(ctx->enc_data[ctx->num]), in, inl);
+		ctx->num += inl;
+		return;
+	}
+	if (ctx->num != 0) {
+		i = ctx->length - ctx->num;
+		memcpy(&(ctx->enc_data[ctx->num]), in, i);
+		in += i;
+		inl -= i;
+		j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length);
+		ctx->num = 0;
+		out += j;
+		*(out++) = '\n';
+		*out = '\0';
+		total = j + 1;
+	}
+	while (inl >= ctx->length && total <= INT_MAX) {
+		j = EVP_EncodeBlock(out, in, ctx->length);
+		in += ctx->length;
+		inl -= ctx->length;
+		out += j;
+		*(out++) = '\n';
+		*out = '\0';
+		total += j + 1;
+	}
+	if (total > INT_MAX) {
+		/* Too much output data! */
+		*outl = 0;
+		return;
+	}
+	if (inl != 0)
+		memcpy(&(ctx->enc_data[0]), in, inl);
+	ctx->num = inl;
+	*outl = total;
+}
+
+void
+EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
+{
+	unsigned int ret = 0;
+
+	if (ctx->num != 0) {
+		ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num);
+		out[ret++] = '\n';
+		out[ret] = '\0';
+		ctx->num = 0;
+	}
+	*outl = ret;
+}
+
+int
+EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen)
+{
+	int i, ret = 0;
+	unsigned long l;
+
+	for (i = dlen; i > 0; i -= 3) {
+		if (i >= 3) {
+			l = (((unsigned long)f[0]) << 16L) |
+			    (((unsigned long)f[1]) << 8L) | f[2];
+			*(t++) = conv_bin2ascii(l >> 18L);
+			*(t++) = conv_bin2ascii(l >> 12L);
+			*(t++) = conv_bin2ascii(l >> 6L);
+			*(t++) = conv_bin2ascii(l     );
+		} else {
+			l = ((unsigned long)f[0]) << 16L;
+			if (i == 2)
+				l |= ((unsigned long)f[1] << 8L);
+
+			*(t++) = conv_bin2ascii(l >> 18L);
+			*(t++) = conv_bin2ascii(l >> 12L);
+			*(t++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L);
+			*(t++) = '=';
+		}
+		ret += 4;
+		f += 3;
+	}
+
+	*t = '\0';
+	return (ret);
+}
+
+void
+EVP_DecodeInit(EVP_ENCODE_CTX *ctx)
+{
+	ctx->length = 30;
+	ctx->num = 0;
+	ctx->line_num = 0;
+	ctx->expect_nl = 0;
+}
+
+/* -1 for error
+ *  0 for last line
+ *  1 for full line
+ */
+int
+EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
+    const unsigned char *in, int inl)
+{
+	int seof = -1, eof = 0, rv = -1, ret = 0, i, v, tmp, n, ln, exp_nl;
+	unsigned char *d;
+
+	n = ctx->num;
+	d = ctx->enc_data;
+	ln = ctx->line_num;
+	exp_nl = ctx->expect_nl;
+
+	/* last line of input. */
+	if ((inl == 0) || ((n == 0) && (conv_ascii2bin(in[0]) == B64_EOF))) {
+		rv = 0;
+		goto end;
+	}
+
+	/* We parse the input data */
+	for (i = 0; i < inl; i++) {
+		/* If the current line is > 80 characters, scream alot */
+		if (ln >= 80) {
+			rv = -1;
+			goto end;
+		}
+
+		/* Get char and put it into the buffer */
+		tmp= *(in++);
+		v = conv_ascii2bin(tmp);
+		/* only save the good data :-) */
+		if (!B64_NOT_BASE64(v)) {
+			OPENSSL_assert(n < (int)sizeof(ctx->enc_data));
+			d[n++] = tmp;
+			ln++;
+		} else if (v == B64_ERROR) {
+			rv = -1;
+			goto end;
+		}
+
+		/* There should not be base64 data after padding. */
+		if (eof && tmp != '=' && tmp != '\r' && tmp != '\n' &&
+		    v != B64_EOF) {
+			rv = -1;
+			goto end;
+		}
+
+		/* have we seen a '=' which is 'definitely' the last
+		 * input line.  seof will point to the character that
+		 * holds it. and eof will hold how many characters to
+		 * chop off. */
+		if (tmp == '=') {
+			if (seof == -1)
+				seof = n;
+			eof++;
+		}
+
+		/* There should be no more than two padding markers. */
+		if (eof > 2) {
+			rv = -1;
+			goto end;
+		}
+
+		if (v == B64_CR) {
+			ln = 0;
+			if (exp_nl)
+				continue;
+		}
+
+		/* eoln */
+		if (v == B64_EOLN) {
+			ln = 0;
+			if (exp_nl) {
+				exp_nl = 0;
+				continue;
+			}
+		}
+		exp_nl = 0;
+
+		/* If we are at the end of input and it looks like a
+		 * line, process it. */
+		if (((i + 1) == inl) && (((n&3) == 0) || eof)) {
+			v = B64_EOF;
+			/* In case things were given us in really small
+			   records (so two '=' were given in separate
+			   updates), eof may contain the incorrect number
+			   of ending bytes to skip, so let's redo the count */
+			eof = 0;
+			if (d[n-1] == '=')
+				eof++;
+			if (d[n-2] == '=')
+				eof++;
+			/* There will never be more than two '=' */
+		}
+
+		if ((v == B64_EOF && (n&3) == 0) || (n >= 64)) {
+			/* This is needed to work correctly on 64 byte input
+			 * lines.  We process the line and then need to
+			 * accept the '\n' */
+			if ((v != B64_EOF) && (n >= 64))
+				exp_nl = 1;
+			if (n > 0) {
+				v = EVP_DecodeBlock(out, d, n);
+				n = 0;
+				if (v < 0) {
+					rv = 0;
+					goto end;
+				}
+				ret += (v - eof);
+			} else {
+				eof = 1;
+				v = 0;
+			}
+
+			/* This is the case where we have had a short
+			 * but valid input line */
+			if ((v < ctx->length) && eof) {
+				rv = 0;
+				goto end;
+			} else
+				ctx->length = v;
+
+			if (seof >= 0) {
+				rv = 0;
+				goto end;
+			}
+			out += v;
+		}
+	}
+	rv = 1;
+
+end:
+	*outl = ret;
+	ctx->num = n;
+	ctx->line_num = ln;
+	ctx->expect_nl = exp_nl;
+	return (rv);
+}
+
+int
+EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n)
+{
+	int i, ret = 0, a, b, c, d;
+	unsigned long l;
+
+	/* trim white space from the start of the line. */
+	while ((conv_ascii2bin(*f) == B64_WS) && (n > 0)) {
+		f++;
+		n--;
+	}
+
+	/* strip off stuff at the end of the line
+	 * ascii2bin values B64_WS, B64_EOLN, B64_EOLN and B64_EOF */
+	while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n - 1]))))
+		n--;
+
+	if (n % 4 != 0)
+		return (-1);
+
+	for (i = 0; i < n; i += 4) {
+		a = conv_ascii2bin(*(f++));
+		b = conv_ascii2bin(*(f++));
+		c = conv_ascii2bin(*(f++));
+		d = conv_ascii2bin(*(f++));
+		if ((a & 0x80) || (b & 0x80) ||
+		    (c & 0x80) || (d & 0x80))
+			return (-1);
+		l = ((((unsigned long)a) << 18L) |
+		    (((unsigned long)b) << 12L) |
+		    (((unsigned long)c) << 6L) |
+		    (((unsigned long)d)));
+		*(t++) = (unsigned char)(l >> 16L) & 0xff;
+		*(t++) = (unsigned char)(l >> 8L) & 0xff;
+		*(t++) = (unsigned char)(l) & 0xff;
+		ret += 3;
+	}
+	return (ret);
+}
+
+int
+EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
+{
+	int i;
+
+	*outl = 0;
+	if (ctx->num != 0) {
+		i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num);
+		if (i < 0)
+			return (-1);
+		ctx->num = 0;
+		*outl = i;
+		return (1);
+	} else
+		return (1);
+}
diff --git a/crypto/libressl/crypto/evp/evp_aead.c b/crypto/libressl/crypto/evp/evp_aead.c
new file mode 100644
index 0000000000..53c711b257
--- /dev/null
+++ b/crypto/libressl/crypto/evp/evp_aead.c
@@ -0,0 +1,144 @@
+/* $OpenBSD: evp_aead.c,v 1.4 2014/06/12 15:49:29 deraadt Exp $ */
+/*
+ * Copyright (c) 2014, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or 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 
+#include 
+
+#include 
+#include 
+
+#include "evp_locl.h"
+
+size_t
+EVP_AEAD_key_length(const EVP_AEAD *aead)
+{
+	return aead->key_len;
+}
+
+size_t
+EVP_AEAD_nonce_length(const EVP_AEAD *aead)
+{
+	return aead->nonce_len;
+}
+
+size_t
+EVP_AEAD_max_overhead(const EVP_AEAD *aead)
+{
+	return aead->overhead;
+}
+
+size_t
+EVP_AEAD_max_tag_len(const EVP_AEAD *aead)
+{
+	return aead->max_tag_len;
+}
+
+int
+EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
+    const unsigned char *key, size_t key_len, size_t tag_len, ENGINE *impl)
+{
+	ctx->aead = aead;
+	if (key_len != aead->key_len) {
+		EVPerr(EVP_F_EVP_AEAD_CTX_INIT, EVP_R_UNSUPPORTED_KEY_SIZE);
+		return 0;
+	}
+	return aead->init(ctx, key, key_len, tag_len);
+}
+
+void
+EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx)
+{
+	if (ctx->aead == NULL)
+		return;
+	ctx->aead->cleanup(ctx);
+	ctx->aead = NULL;
+}
+
+/* check_alias returns 0 if out points within the buffer determined by in
+ * and in_len and 1 otherwise.
+ *
+ * When processing, there's only an issue if out points within in[:in_len]
+ * and isn't equal to in. If that's the case then writing the output will
+ * stomp input that hasn't been read yet.
+ *
+ * This function checks for that case. */
+static int
+check_alias(const unsigned char *in, size_t in_len, const unsigned char *out)
+{
+	if (out <= in)
+		return 1;
+	if (in + in_len <= out)
+		return 1;
+	return 0;
+}
+
+int
+EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
+    size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
+    const unsigned char *in, size_t in_len, const unsigned char *ad,
+    size_t ad_len)
+{
+	size_t possible_out_len = in_len + ctx->aead->overhead;
+
+	/* Overflow. */
+	if (possible_out_len < in_len) {
+		EVPerr(EVP_F_AEAD_CTX_SEAL, EVP_R_TOO_LARGE);
+		goto error;
+	}
+
+	if (!check_alias(in, in_len, out)) {
+		EVPerr(EVP_F_AEAD_CTX_SEAL, EVP_R_OUTPUT_ALIASES_INPUT);
+		goto error;
+	}
+
+	if (ctx->aead->seal(ctx, out, out_len, max_out_len, nonce, nonce_len,
+	    in, in_len, ad, ad_len)) {
+		return 1;
+	}
+
+error:
+	/* In the event of an error, clear the output buffer so that a caller
+	 * that doesn't check the return value doesn't send raw data. */
+	memset(out, 0, max_out_len);
+	*out_len = 0;
+	return 0;
+}
+
+int
+EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
+    size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
+    const unsigned char *in, size_t in_len, const unsigned char *ad,
+    size_t ad_len)
+{
+	if (!check_alias(in, in_len, out)) {
+		EVPerr(EVP_F_AEAD_CTX_OPEN, EVP_R_OUTPUT_ALIASES_INPUT);
+		goto error;
+	}
+
+	if (ctx->aead->open(ctx, out, out_len, max_out_len, nonce, nonce_len,
+	    in, in_len, ad, ad_len)) {
+		return 1;
+	}
+
+error:
+	/* In the event of an error, clear the output buffer so that a caller
+	 * that doesn't check the return value doesn't try and process bad
+	 * data. */
+	memset(out, 0, max_out_len);
+	*out_len = 0;
+	return 0;
+}
diff --git a/crypto/libressl/crypto/evp/evp_enc.c b/crypto/libressl/crypto/evp/evp_enc.c
new file mode 100644
index 0000000000..222d476dbb
--- /dev/null
+++ b/crypto/libressl/crypto/evp/evp_enc.c
@@ -0,0 +1,670 @@
+/* $OpenBSD: evp_enc.c,v 1.30 2016/05/04 15:05:13 tedu Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+
+#include "evp_locl.h"
+
+#define M_do_cipher(ctx, out, in, inl) ctx->cipher->do_cipher(ctx, out, in, inl)
+
+void
+EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
+{
+	memset(ctx, 0, sizeof(EVP_CIPHER_CTX));
+}
+
+EVP_CIPHER_CTX *
+EVP_CIPHER_CTX_new(void)
+{
+	return calloc(1, sizeof(EVP_CIPHER_CTX));
+}
+
+int
+EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+    const unsigned char *key, const unsigned char *iv, int enc)
+{
+	if (cipher)
+		EVP_CIPHER_CTX_init(ctx);
+	return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc);
+}
+
+int
+EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
+    const unsigned char *key, const unsigned char *iv, int enc)
+{
+	if (enc == -1)
+		enc = ctx->encrypt;
+	else {
+		if (enc)
+			enc = 1;
+		ctx->encrypt = enc;
+	}
+#ifndef OPENSSL_NO_ENGINE
+	/* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
+	 * so this context may already have an ENGINE! Try to avoid releasing
+	 * the previous handle, re-querying for an ENGINE, and having a
+	 * reinitialisation, when it may all be unecessary. */
+	if (ctx->engine && ctx->cipher &&
+	    (!cipher || (cipher && (cipher->nid == ctx->cipher->nid))))
+		goto skip_to_init;
+#endif
+	if (cipher) {
+		/* Ensure a context left lying around from last time is cleared
+		 * (the previous check attempted to avoid this if the same
+		 * ENGINE and EVP_CIPHER could be used). */
+		if (ctx->cipher) {
+			unsigned long flags = ctx->flags;
+			EVP_CIPHER_CTX_cleanup(ctx);
+			/* Restore encrypt and flags */
+			ctx->encrypt = enc;
+			ctx->flags = flags;
+		}
+#ifndef OPENSSL_NO_ENGINE
+		if (impl) {
+			if (!ENGINE_init(impl)) {
+				EVPerr(EVP_F_EVP_CIPHERINIT_EX,
+				    EVP_R_INITIALIZATION_ERROR);
+				return 0;
+			}
+		} else
+			/* Ask if an ENGINE is reserved for this job */
+			impl = ENGINE_get_cipher_engine(cipher->nid);
+		if (impl) {
+			/* There's an ENGINE for this job ... (apparently) */
+			const EVP_CIPHER *c =
+			    ENGINE_get_cipher(impl, cipher->nid);
+			if (!c) {
+				EVPerr(EVP_F_EVP_CIPHERINIT_EX,
+				    EVP_R_INITIALIZATION_ERROR);
+				return 0;
+			}
+			/* We'll use the ENGINE's private cipher definition */
+			cipher = c;
+			/* Store the ENGINE functional reference so we know
+			 * 'cipher' came from an ENGINE and we need to release
+			 * it when done. */
+			ctx->engine = impl;
+		} else
+			ctx->engine = NULL;
+#endif
+
+		ctx->cipher = cipher;
+		if (ctx->cipher->ctx_size) {
+			ctx->cipher_data = malloc(ctx->cipher->ctx_size);
+			if (!ctx->cipher_data) {
+				EVPerr(EVP_F_EVP_CIPHERINIT_EX,
+				    ERR_R_MALLOC_FAILURE);
+				return 0;
+			}
+		} else {
+			ctx->cipher_data = NULL;
+		}
+		ctx->key_len = cipher->key_len;
+		ctx->flags = 0;
+		if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) {
+			if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) {
+				EVPerr(EVP_F_EVP_CIPHERINIT_EX,
+				    EVP_R_INITIALIZATION_ERROR);
+				return 0;
+			}
+		}
+	} else if (!ctx->cipher) {
+		EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET);
+		return 0;
+	}
+#ifndef OPENSSL_NO_ENGINE
+skip_to_init:
+#endif
+	/* we assume block size is a power of 2 in *cryptUpdate */
+	if (ctx->cipher->block_size != 1 &&
+	    ctx->cipher->block_size != 8 &&
+	    ctx->cipher->block_size != 16) {
+		EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_BAD_BLOCK_LENGTH);
+		return 0;
+	}
+
+	if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
+		switch (EVP_CIPHER_CTX_mode(ctx)) {
+
+		case EVP_CIPH_STREAM_CIPHER:
+		case EVP_CIPH_ECB_MODE:
+			break;
+
+		case EVP_CIPH_CFB_MODE:
+		case EVP_CIPH_OFB_MODE:
+
+			ctx->num = 0;
+			/* fall-through */
+
+		case EVP_CIPH_CBC_MODE:
+
+			if ((size_t)EVP_CIPHER_CTX_iv_length(ctx) >
+			    sizeof(ctx->iv)) {
+				EVPerr(EVP_F_EVP_CIPHERINIT_EX,
+				    EVP_R_IV_TOO_LARGE);
+				return 0;
+			}
+			if (iv)
+				memcpy(ctx->oiv, iv,
+				    EVP_CIPHER_CTX_iv_length(ctx));
+			memcpy(ctx->iv, ctx->oiv,
+			    EVP_CIPHER_CTX_iv_length(ctx));
+			break;
+
+		case EVP_CIPH_CTR_MODE:
+			ctx->num = 0;
+			/* Don't reuse IV for CTR mode */
+			if (iv)
+				memcpy(ctx->iv, iv,
+				    EVP_CIPHER_CTX_iv_length(ctx));
+			break;
+
+		default:
+			return 0;
+			break;
+		}
+	}
+
+	if (key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
+		if (!ctx->cipher->init(ctx, key, iv, enc))
+			return 0;
+	}
+	ctx->buf_len = 0;
+	ctx->final_used = 0;
+	ctx->block_mask = ctx->cipher->block_size - 1;
+	return 1;
+}
+
+int
+EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+    const unsigned char *in, int inl)
+{
+	if (ctx->encrypt)
+		return EVP_EncryptUpdate(ctx, out, outl, in, inl);
+	else
+		return EVP_DecryptUpdate(ctx, out, outl, in, inl);
+}
+
+int
+EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+	if (ctx->encrypt)
+		return EVP_EncryptFinal_ex(ctx, out, outl);
+	else
+		return EVP_DecryptFinal_ex(ctx, out, outl);
+}
+
+int
+EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+	if (ctx->encrypt)
+		return EVP_EncryptFinal_ex(ctx, out, outl);
+	else
+		return EVP_DecryptFinal_ex(ctx, out, outl);
+}
+
+int
+EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+    const unsigned char *key, const unsigned char *iv)
+{
+	return EVP_CipherInit(ctx, cipher, key, iv, 1);
+}
+
+int
+EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
+    const unsigned char *key, const unsigned char *iv)
+{
+	return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1);
+}
+
+int
+EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+    const unsigned char *key, const unsigned char *iv)
+{
+	return EVP_CipherInit(ctx, cipher, key, iv, 0);
+}
+
+int
+EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
+    const unsigned char *key, const unsigned char *iv)
+{
+	return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0);
+}
+
+int
+EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+    const unsigned char *in, int inl)
+{
+	int i, j, bl;
+
+	if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
+		i = M_do_cipher(ctx, out, in, inl);
+		if (i < 0)
+			return 0;
+		else
+			*outl = i;
+		return 1;
+	}
+
+	if (inl <= 0) {
+		*outl = 0;
+		return inl == 0;
+	}
+
+	if (ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0) {
+		if (M_do_cipher(ctx, out, in, inl)) {
+			*outl = inl;
+			return 1;
+		} else {
+			*outl = 0;
+			return 0;
+		}
+	}
+	i = ctx->buf_len;
+	bl = ctx->cipher->block_size;
+	if ((size_t)bl > sizeof(ctx->buf)) {
+		EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_BAD_BLOCK_LENGTH);
+		*outl = 0;
+		return 0;
+	}
+	if (i != 0) {
+		if (bl - i > inl) {
+			memcpy(&(ctx->buf[i]), in, inl);
+			ctx->buf_len += inl;
+			*outl = 0;
+			return 1;
+		} else {
+			j = bl - i;
+			memcpy(&(ctx->buf[i]), in, j);
+			if (!M_do_cipher(ctx, out, ctx->buf, bl))
+				return 0;
+			inl -= j;
+			in += j;
+			out += bl;
+			*outl = bl;
+		}
+	} else
+		*outl = 0;
+	i = inl&(bl - 1);
+	inl -= i;
+	if (inl > 0) {
+		if (!M_do_cipher(ctx, out, in, inl))
+			return 0;
+		*outl += inl;
+	}
+
+	if (i != 0)
+		memcpy(ctx->buf, &(in[inl]), i);
+	ctx->buf_len = i;
+	return 1;
+}
+
+int
+EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+	int ret;
+
+	ret = EVP_EncryptFinal_ex(ctx, out, outl);
+	(void) EVP_CIPHER_CTX_cleanup(ctx);
+	return ret;
+}
+
+int
+EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+	int n, ret;
+	unsigned int i, b, bl;
+
+	if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
+		ret = M_do_cipher(ctx, out, NULL, 0);
+		if (ret < 0)
+			return 0;
+		else
+			*outl = ret;
+		return 1;
+	}
+
+	b = ctx->cipher->block_size;
+	if (b > sizeof ctx->buf) {
+		EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_BAD_BLOCK_LENGTH);
+		return 0;
+	}
+	if (b == 1) {
+		*outl = 0;
+		return 1;
+	}
+	bl = ctx->buf_len;
+	if (ctx->flags & EVP_CIPH_NO_PADDING) {
+		if (bl) {
+			EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX,
+			    EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
+			return 0;
+		}
+		*outl = 0;
+		return 1;
+	}
+
+	n = b - bl;
+	for (i = bl; i < b; i++)
+		ctx->buf[i] = n;
+	ret = M_do_cipher(ctx, out, ctx->buf, b);
+
+
+	if (ret)
+		*outl = b;
+
+	return ret;
+}
+
+int
+EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+    const unsigned char *in, int inl)
+{
+	int fix_len;
+	unsigned int b;
+
+	if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
+		fix_len = M_do_cipher(ctx, out, in, inl);
+		if (fix_len < 0) {
+			*outl = 0;
+			return 0;
+		} else
+			*outl = fix_len;
+		return 1;
+	}
+
+	if (inl <= 0) {
+		*outl = 0;
+		return inl == 0;
+	}
+
+	if (ctx->flags & EVP_CIPH_NO_PADDING)
+		return EVP_EncryptUpdate(ctx, out, outl, in, inl);
+
+	b = ctx->cipher->block_size;
+	if (b > sizeof ctx->final) {
+		EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_BAD_BLOCK_LENGTH);
+		return 0;
+	}
+
+	if (ctx->final_used) {
+		memcpy(out, ctx->final, b);
+		out += b;
+		fix_len = 1;
+	} else
+		fix_len = 0;
+
+
+	if (!EVP_EncryptUpdate(ctx, out, outl, in, inl))
+		return 0;
+
+	/* if we have 'decrypted' a multiple of block size, make sure
+	 * we have a copy of this last block */
+	if (b > 1 && !ctx->buf_len) {
+		*outl -= b;
+		ctx->final_used = 1;
+		memcpy(ctx->final, &out[*outl], b);
+	} else
+		ctx->final_used = 0;
+
+	if (fix_len)
+		*outl += b;
+
+	return 1;
+}
+
+int
+EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+	int ret;
+
+	ret = EVP_DecryptFinal_ex(ctx, out, outl);
+	(void) EVP_CIPHER_CTX_cleanup(ctx);
+	return ret;
+}
+
+int
+EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+	int i, n;
+	unsigned int b;
+	*outl = 0;
+
+	if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
+		i = M_do_cipher(ctx, out, NULL, 0);
+		if (i < 0)
+			return 0;
+		else
+			*outl = i;
+		return 1;
+	}
+
+	b = ctx->cipher->block_size;
+	if (ctx->flags & EVP_CIPH_NO_PADDING) {
+		if (ctx->buf_len) {
+			EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,
+			    EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
+			return 0;
+		}
+		*outl = 0;
+		return 1;
+	}
+	if (b > 1) {
+		if (ctx->buf_len || !ctx->final_used) {
+			EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,
+			    EVP_R_WRONG_FINAL_BLOCK_LENGTH);
+			return (0);
+		}
+		if (b > sizeof ctx->final) {
+			EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,
+			    EVP_R_BAD_BLOCK_LENGTH);
+			return 0;
+		}
+		n = ctx->final[b - 1];
+		if (n == 0 || n > (int)b) {
+			EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT);
+			return (0);
+		}
+		for (i = 0; i < n; i++) {
+			if (ctx->final[--b] != n) {
+				EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,
+				    EVP_R_BAD_DECRYPT);
+				return (0);
+			}
+		}
+		n = ctx->cipher->block_size - n;
+		for (i = 0; i < n; i++)
+			out[i] = ctx->final[i];
+		*outl = n;
+	} else
+		*outl = 0;
+	return (1);
+}
+
+void
+EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
+{
+	if (ctx) {
+		EVP_CIPHER_CTX_cleanup(ctx);
+		free(ctx);
+	}
+}
+
+int
+EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
+{
+	if (c->cipher != NULL) {
+		if (c->cipher->cleanup && !c->cipher->cleanup(c))
+			return 0;
+		/* Cleanse cipher context data */
+		if (c->cipher_data)
+			explicit_bzero(c->cipher_data, c->cipher->ctx_size);
+	}
+	free(c->cipher_data);
+#ifndef OPENSSL_NO_ENGINE
+	if (c->engine)
+		/* The EVP_CIPHER we used belongs to an ENGINE, release the
+		 * functional reference we held for this reason. */
+		ENGINE_finish(c->engine);
+#endif
+	explicit_bzero(c, sizeof(EVP_CIPHER_CTX));
+	return 1;
+}
+
+int
+EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
+{
+	if (c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH)
+		return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH,
+		    keylen, NULL);
+	if (c->key_len == keylen)
+		return 1;
+	if ((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) {
+		c->key_len = keylen;
+		return 1;
+	}
+	EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH, EVP_R_INVALID_KEY_LENGTH);
+	return 0;
+}
+
+int
+EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
+{
+	if (pad)
+		ctx->flags &= ~EVP_CIPH_NO_PADDING;
+	else
+		ctx->flags |= EVP_CIPH_NO_PADDING;
+	return 1;
+}
+
+int
+EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+	int ret;
+
+	if (!ctx->cipher) {
+		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
+		return 0;
+	}
+
+	if (!ctx->cipher->ctrl) {
+		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
+		return 0;
+	}
+
+	ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
+	if (ret == -1) {
+		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL,
+		    EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
+		return 0;
+	}
+	return ret;
+}
+
+int
+EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
+{
+	if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
+		return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key);
+	arc4random_buf(key, ctx->key_len);
+	return 1;
+}
+
+int
+EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
+{
+	if ((in == NULL) || (in->cipher == NULL)) {
+		EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, EVP_R_INPUT_NOT_INITIALIZED);
+		return 0;
+	}
+#ifndef OPENSSL_NO_ENGINE
+	/* Make sure it's safe to copy a cipher context using an ENGINE */
+	if (in->engine && !ENGINE_init(in->engine)) {
+		EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, ERR_R_ENGINE_LIB);
+		return 0;
+	}
+#endif
+
+	EVP_CIPHER_CTX_cleanup(out);
+	memcpy(out, in, sizeof *out);
+
+	if (in->cipher_data && in->cipher->ctx_size) {
+		out->cipher_data = malloc(in->cipher->ctx_size);
+		if (!out->cipher_data) {
+			EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size);
+	}
+
+	if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY)
+		return in->cipher->ctrl((EVP_CIPHER_CTX *)in,
+		    EVP_CTRL_COPY, 0, out);
+	return 1;
+}
diff --git a/crypto/libressl/crypto/evp/evp_err.c b/crypto/libressl/crypto/evp/evp_err.c
new file mode 100644
index 0000000000..2a77d351ee
--- /dev/null
+++ b/crypto/libressl/crypto/evp/evp_err.c
@@ -0,0 +1,261 @@
+/* $OpenBSD$ */
+/* ====================================================================
+ * Copyright (c) 1999-2011 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_EVP,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_EVP,0,reason)
+
+static ERR_STRING_DATA EVP_str_functs[] = {
+	{ERR_FUNC(EVP_F_AEAD_AES_GCM_INIT), "AEAD_AES_GCM_INIT"},
+	{ERR_FUNC(EVP_F_AEAD_AES_GCM_OPEN), "AEAD_AES_GCM_OPEN"},
+	{ERR_FUNC(EVP_F_AEAD_AES_GCM_SEAL), "AEAD_AES_GCM_SEAL"},
+	{ERR_FUNC(EVP_F_AEAD_CHACHA20_POLY1305_INIT), "AEAD_CHACHA20_POLY1305_INIT"},
+	{ERR_FUNC(EVP_F_AEAD_CHACHA20_POLY1305_OPEN), "AEAD_CHACHA20_POLY1305_OPEN"},
+	{ERR_FUNC(EVP_F_AEAD_CHACHA20_POLY1305_SEAL), "AEAD_CHACHA20_POLY1305_SEAL"},
+	{ERR_FUNC(EVP_F_AEAD_CTX_OPEN), "AEAD_CTX_OPEN"},
+	{ERR_FUNC(EVP_F_AEAD_CTX_SEAL), "AEAD_CTX_SEAL"},
+	{ERR_FUNC(EVP_F_AESNI_INIT_KEY), "AESNI_INIT_KEY"},
+	{ERR_FUNC(EVP_F_AESNI_XTS_CIPHER), "AESNI_XTS_CIPHER"},
+	{ERR_FUNC(EVP_F_AES_INIT_KEY), "AES_INIT_KEY"},
+	{ERR_FUNC(EVP_F_AES_XTS), "AES_XTS"},
+	{ERR_FUNC(EVP_F_AES_XTS_CIPHER), "AES_XTS_CIPHER"},
+	{ERR_FUNC(EVP_F_ALG_MODULE_INIT), "ALG_MODULE_INIT"},
+	{ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY), "CAMELLIA_INIT_KEY"},
+	{ERR_FUNC(EVP_F_CMAC_INIT), "CMAC_INIT"},
+	{ERR_FUNC(EVP_F_D2I_PKEY), "D2I_PKEY"},
+	{ERR_FUNC(EVP_F_DO_SIGVER_INIT), "DO_SIGVER_INIT"},
+	{ERR_FUNC(EVP_F_DSAPKEY2PKCS8), "DSAPKEY2PKCS8"},
+	{ERR_FUNC(EVP_F_DSA_PKEY2PKCS8), "DSA_PKEY2PKCS8"},
+	{ERR_FUNC(EVP_F_ECDSA_PKEY2PKCS8), "ECDSA_PKEY2PKCS8"},
+	{ERR_FUNC(EVP_F_ECKEY_PKEY2PKCS8), "ECKEY_PKEY2PKCS8"},
+	{ERR_FUNC(EVP_F_EVP_AEAD_CTX_INIT), "EVP_AEAD_CTX_init"},
+	{ERR_FUNC(EVP_F_EVP_AEAD_CTX_OPEN), "EVP_AEAD_CTX_open"},
+	{ERR_FUNC(EVP_F_EVP_AEAD_CTX_SEAL), "EVP_AEAD_CTX_seal"},
+	{ERR_FUNC(EVP_F_EVP_BYTESTOKEY), "EVP_BytesToKey"},
+	{ERR_FUNC(EVP_F_EVP_CIPHERINIT_EX), "EVP_CipherInit_ex"},
+	{ERR_FUNC(EVP_F_EVP_CIPHER_CTX_COPY), "EVP_CIPHER_CTX_copy"},
+	{ERR_FUNC(EVP_F_EVP_CIPHER_CTX_CTRL), "EVP_CIPHER_CTX_ctrl"},
+	{ERR_FUNC(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH), "EVP_CIPHER_CTX_set_key_length"},
+	{ERR_FUNC(EVP_F_EVP_CIPHER_GET_ASN1_IV), "EVP_CIPHER_get_asn1_iv"},
+	{ERR_FUNC(EVP_F_EVP_CIPHER_SET_ASN1_IV), "EVP_CIPHER_set_asn1_iv"},
+	{ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX), "EVP_DecryptFinal_ex"},
+	{ERR_FUNC(EVP_F_EVP_DECRYPTUPDATE), "EVP_DecryptUpdate"},
+	{ERR_FUNC(EVP_F_EVP_DIGESTFINAL_EX), "EVP_DigestFinal_ex"},
+	{ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"},
+	{ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"},
+	{ERR_FUNC(EVP_F_EVP_ENCRYPTUPDATE), "EVP_EncryptUpdate"},
+	{ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX), "EVP_MD_CTX_copy_ex"},
+	{ERR_FUNC(EVP_F_EVP_MD_CTX_CTRL), "EVP_MD_CTX_ctrl"},
+	{ERR_FUNC(EVP_F_EVP_MD_SIZE), "EVP_MD_size"},
+	{ERR_FUNC(EVP_F_EVP_OPENINIT), "EVP_OpenInit"},
+	{ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD), "EVP_PBE_alg_add"},
+	{ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD_TYPE), "EVP_PBE_alg_add_type"},
+	{ERR_FUNC(EVP_F_EVP_PBE_CIPHERINIT), "EVP_PBE_CipherInit"},
+	{ERR_FUNC(EVP_F_EVP_PKCS82PKEY), "EVP_PKCS82PKEY"},
+	{ERR_FUNC(EVP_F_EVP_PKCS82PKEY_BROKEN), "EVP_PKCS82PKEY_BROKEN"},
+	{ERR_FUNC(EVP_F_EVP_PKEY2PKCS8_BROKEN), "EVP_PKEY2PKCS8_broken"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_COPY_PARAMETERS), "EVP_PKEY_copy_parameters"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL), "EVP_PKEY_CTX_ctrl"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL_STR), "EVP_PKEY_CTX_ctrl_str"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_CTX_DUP), "EVP_PKEY_CTX_dup"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT), "EVP_PKEY_decrypt"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_INIT), "EVP_PKEY_decrypt_init"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_OLD), "EVP_PKEY_decrypt_old"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE), "EVP_PKEY_derive"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_INIT), "EVP_PKEY_derive_init"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_SET_PEER), "EVP_PKEY_derive_set_peer"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT), "EVP_PKEY_encrypt"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_INIT), "EVP_PKEY_encrypt_init"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_OLD), "EVP_PKEY_encrypt_old"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_GET1_DH), "EVP_PKEY_get1_DH"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_GET1_DSA), "EVP_PKEY_get1_DSA"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_GET1_ECDSA), "EVP_PKEY_GET1_ECDSA"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_GET1_EC_KEY), "EVP_PKEY_get1_EC_KEY"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_GET1_RSA), "EVP_PKEY_get1_RSA"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN), "EVP_PKEY_keygen"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN_INIT), "EVP_PKEY_keygen_init"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_NEW), "EVP_PKEY_new"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN), "EVP_PKEY_paramgen"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN_INIT), "EVP_PKEY_paramgen_init"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_SIGN), "EVP_PKEY_sign"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_SIGN_INIT), "EVP_PKEY_sign_init"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY), "EVP_PKEY_verify"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_INIT), "EVP_PKEY_verify_init"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER), "EVP_PKEY_verify_recover"},
+	{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT), "EVP_PKEY_verify_recover_init"},
+	{ERR_FUNC(EVP_F_EVP_RIJNDAEL), "EVP_RIJNDAEL"},
+	{ERR_FUNC(EVP_F_EVP_SIGNFINAL), "EVP_SignFinal"},
+	{ERR_FUNC(EVP_F_EVP_VERIFYFINAL), "EVP_VerifyFinal"},
+	{ERR_FUNC(EVP_F_FIPS_CIPHERINIT), "FIPS_CIPHERINIT"},
+	{ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_COPY), "FIPS_CIPHER_CTX_COPY"},
+	{ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_CTRL), "FIPS_CIPHER_CTX_CTRL"},
+	{ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH), "FIPS_CIPHER_CTX_SET_KEY_LENGTH"},
+	{ERR_FUNC(EVP_F_FIPS_DIGESTINIT), "FIPS_DIGESTINIT"},
+	{ERR_FUNC(EVP_F_FIPS_MD_CTX_COPY), "FIPS_MD_CTX_COPY"},
+	{ERR_FUNC(EVP_F_HMAC_INIT_EX), "HMAC_Init_ex"},
+	{ERR_FUNC(EVP_F_INT_CTX_NEW), "INT_CTX_NEW"},
+	{ERR_FUNC(EVP_F_PKCS5_PBE_KEYIVGEN), "PKCS5_PBE_keyivgen"},
+	{ERR_FUNC(EVP_F_PKCS5_V2_PBE_KEYIVGEN), "PKCS5_v2_PBE_keyivgen"},
+	{ERR_FUNC(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN), "PKCS5_V2_PBKDF2_KEYIVGEN"},
+	{ERR_FUNC(EVP_F_PKCS8_SET_BROKEN), "PKCS8_set_broken"},
+	{ERR_FUNC(EVP_F_PKEY_SET_TYPE), "PKEY_SET_TYPE"},
+	{ERR_FUNC(EVP_F_RC2_GET_ASN1_TYPE_AND_IV), "RC2_GET_ASN1_TYPE_AND_IV"},
+	{ERR_FUNC(EVP_F_RC2_MAGIC_TO_METH), "RC2_MAGIC_TO_METH"},
+	{ERR_FUNC(EVP_F_RC5_CTRL), "RC5_CTRL"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA EVP_str_reasons[] = {
+	{ERR_REASON(EVP_R_AES_IV_SETUP_FAILED)   , "aes iv setup failed"},
+	{ERR_REASON(EVP_R_AES_KEY_SETUP_FAILED)  , "aes key setup failed"},
+	{ERR_REASON(EVP_R_ASN1_LIB)              , "asn1 lib"},
+	{ERR_REASON(EVP_R_BAD_BLOCK_LENGTH)      , "bad block length"},
+	{ERR_REASON(EVP_R_BAD_DECRYPT)           , "bad decrypt"},
+	{ERR_REASON(EVP_R_BAD_KEY_LENGTH)        , "bad key length"},
+	{ERR_REASON(EVP_R_BN_DECODE_ERROR)       , "bn decode error"},
+	{ERR_REASON(EVP_R_BN_PUBKEY_ERROR)       , "bn pubkey error"},
+	{ERR_REASON(EVP_R_BUFFER_TOO_SMALL)      , "buffer too small"},
+	{ERR_REASON(EVP_R_CAMELLIA_KEY_SETUP_FAILED), "camellia key setup failed"},
+	{ERR_REASON(EVP_R_CIPHER_PARAMETER_ERROR), "cipher parameter error"},
+	{ERR_REASON(EVP_R_COMMAND_NOT_SUPPORTED) , "command not supported"},
+	{ERR_REASON(EVP_R_CTRL_NOT_IMPLEMENTED)  , "ctrl not implemented"},
+	{ERR_REASON(EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED), "ctrl operation not implemented"},
+	{ERR_REASON(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH), "data not multiple of block length"},
+	{ERR_REASON(EVP_R_DECODE_ERROR)          , "decode error"},
+	{ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES)   , "different key types"},
+	{ERR_REASON(EVP_R_DIFFERENT_PARAMETERS)  , "different parameters"},
+	{ERR_REASON(EVP_R_DISABLED_FOR_FIPS)     , "disabled for fips"},
+	{ERR_REASON(EVP_R_ENCODE_ERROR)          , "encode error"},
+	{ERR_REASON(EVP_R_ERROR_LOADING_SECTION) , "error loading section"},
+	{ERR_REASON(EVP_R_ERROR_SETTING_FIPS_MODE), "error setting fips mode"},
+	{ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR), "evp pbe cipherinit error"},
+	{ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY)  , "expecting an rsa key"},
+	{ERR_REASON(EVP_R_EXPECTING_A_DH_KEY)    , "expecting a dh key"},
+	{ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY)   , "expecting a dsa key"},
+	{ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY) , "expecting a ecdsa key"},
+	{ERR_REASON(EVP_R_EXPECTING_A_EC_KEY)    , "expecting a ec key"},
+	{ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"},
+	{ERR_REASON(EVP_R_INITIALIZATION_ERROR)  , "initialization error"},
+	{ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED) , "input not initialized"},
+	{ERR_REASON(EVP_R_INVALID_DIGEST)        , "invalid digest"},
+	{ERR_REASON(EVP_R_INVALID_FIPS_MODE)     , "invalid fips mode"},
+	{ERR_REASON(EVP_R_INVALID_KEY_LENGTH)    , "invalid key length"},
+	{ERR_REASON(EVP_R_INVALID_OPERATION)     , "invalid operation"},
+	{ERR_REASON(EVP_R_IV_TOO_LARGE)          , "iv too large"},
+	{ERR_REASON(EVP_R_KEYGEN_FAILURE)        , "keygen failure"},
+	{ERR_REASON(EVP_R_MESSAGE_DIGEST_IS_NULL), "message digest is null"},
+	{ERR_REASON(EVP_R_METHOD_NOT_SUPPORTED)  , "method not supported"},
+	{ERR_REASON(EVP_R_MISSING_PARAMETERS)    , "missing parameters"},
+	{ERR_REASON(EVP_R_NO_CIPHER_SET)         , "no cipher set"},
+	{ERR_REASON(EVP_R_NO_DEFAULT_DIGEST)     , "no default digest"},
+	{ERR_REASON(EVP_R_NO_DIGEST_SET)         , "no digest set"},
+	{ERR_REASON(EVP_R_NO_DSA_PARAMETERS)     , "no dsa parameters"},
+	{ERR_REASON(EVP_R_NO_KEY_SET)            , "no key set"},
+	{ERR_REASON(EVP_R_NO_OPERATION_SET)      , "no operation set"},
+	{ERR_REASON(EVP_R_NO_SIGN_FUNCTION_CONFIGURED), "no sign function configured"},
+	{ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED), "no verify function configured"},
+	{ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), "operation not supported for this keytype"},
+	{ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED), "operaton not initialized"},
+	{ERR_REASON(EVP_R_OUTPUT_ALIASES_INPUT)  , "output aliases input"},
+	{ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE), "pkcs8 unknown broken type"},
+	{ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR), "private key decode error"},
+	{ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR), "private key encode error"},
+	{ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA)    , "public key not rsa"},
+	{ERR_REASON(EVP_R_TAG_TOO_LARGE)         , "tag too large"},
+	{ERR_REASON(EVP_R_TOO_LARGE)             , "too large"},
+	{ERR_REASON(EVP_R_UNKNOWN_CIPHER)        , "unknown cipher"},
+	{ERR_REASON(EVP_R_UNKNOWN_DIGEST)        , "unknown digest"},
+	{ERR_REASON(EVP_R_UNKNOWN_OPTION)        , "unknown option"},
+	{ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) , "unknown pbe algorithm"},
+	{ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS), "unsuported number of rounds"},
+	{ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM) , "unsupported algorithm"},
+	{ERR_REASON(EVP_R_UNSUPPORTED_CIPHER)    , "unsupported cipher"},
+	{ERR_REASON(EVP_R_UNSUPPORTED_KEYLENGTH) , "unsupported keylength"},
+	{ERR_REASON(EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION), "unsupported key derivation function"},
+	{ERR_REASON(EVP_R_UNSUPPORTED_KEY_SIZE)  , "unsupported key size"},
+	{ERR_REASON(EVP_R_UNSUPPORTED_PRF)       , "unsupported prf"},
+	{ERR_REASON(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM), "unsupported private key algorithm"},
+	{ERR_REASON(EVP_R_UNSUPPORTED_SALT_TYPE) , "unsupported salt type"},
+	{ERR_REASON(EVP_R_WRONG_FINAL_BLOCK_LENGTH), "wrong final block length"},
+	{ERR_REASON(EVP_R_WRONG_PUBLIC_KEY_TYPE) , "wrong public key type"},
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_EVP_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(EVP_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, EVP_str_functs);
+		ERR_load_strings(0, EVP_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/evp/evp_key.c b/crypto/libressl/crypto/evp/evp_key.c
new file mode 100644
index 0000000000..04d94c9651
--- /dev/null
+++ b/crypto/libressl/crypto/evp/evp_key.c
@@ -0,0 +1,206 @@
+/* $OpenBSD: evp_key.c,v 1.22 2015/02/10 09:55:39 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* should be init to zeros. */
+static char prompt_string[80];
+
+void
+EVP_set_pw_prompt(const char *prompt)
+{
+	if (prompt == NULL)
+		prompt_string[0] = '\0';
+	else {
+		strlcpy(prompt_string, prompt, sizeof(prompt_string));
+	}
+}
+
+char *
+EVP_get_pw_prompt(void)
+{
+	if (prompt_string[0] == '\0')
+		return (NULL);
+	else
+		return (prompt_string);
+}
+
+int
+EVP_read_pw_string(char *buf, int len, const char *prompt, int verify)
+{
+	return EVP_read_pw_string_min(buf, 0, len, prompt, verify);
+}
+
+int
+EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt,
+    int verify)
+{
+	int ret;
+	char buff[BUFSIZ];
+	UI *ui;
+
+	if ((prompt == NULL) && (prompt_string[0] != '\0'))
+		prompt = prompt_string;
+	ui = UI_new();
+	if (ui == NULL)
+		return -1;
+	if (UI_add_input_string(ui, prompt, 0, buf, min,
+	    (len >= BUFSIZ) ? BUFSIZ - 1 : len) < 0)
+		return -1;
+	if (verify) {
+		if (UI_add_verify_string(ui, prompt, 0, buff, min,
+		    (len >= BUFSIZ) ? BUFSIZ - 1 : len, buf) < 0)
+			return -1;
+	}
+	ret = UI_process(ui);
+	UI_free(ui);
+	explicit_bzero(buff, BUFSIZ);
+	return ret;
+}
+
+int
+EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
+    const unsigned char *salt, const unsigned char *data, int datal,
+    int count, unsigned char *key, unsigned char *iv)
+{
+	EVP_MD_CTX c;
+	unsigned char md_buf[EVP_MAX_MD_SIZE];
+	int niv, nkey, addmd = 0;
+	unsigned int mds = 0, i;
+	int rv = 0;
+
+	nkey = type->key_len;
+	niv = type->iv_len;
+
+	if ((size_t)nkey > EVP_MAX_KEY_LENGTH) {
+		EVPerr(EVP_F_EVP_BYTESTOKEY, EVP_R_BAD_KEY_LENGTH);
+		return 0;
+	}
+	if ((size_t)niv > EVP_MAX_IV_LENGTH) {
+		EVPerr(EVP_F_EVP_BYTESTOKEY, EVP_R_IV_TOO_LARGE);
+		return 0;
+	}
+
+	if (data == NULL)
+		return (nkey);
+
+	EVP_MD_CTX_init(&c);
+	for (;;) {
+		if (!EVP_DigestInit_ex(&c, md, NULL))
+			goto err;
+		if (addmd++)
+			if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds))
+				goto err;
+		if (!EVP_DigestUpdate(&c, data, datal))
+			goto err;
+		if (salt != NULL)
+			if (!EVP_DigestUpdate(&c, salt, PKCS5_SALT_LEN))
+				goto err;
+		if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds))
+			goto err;
+
+		for (i = 1; i < (unsigned int)count; i++) {
+			if (!EVP_DigestInit_ex(&c, md, NULL))
+				goto err;
+			if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds))
+				goto err;
+			if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds))
+				goto err;
+		}
+		i = 0;
+		if (nkey) {
+			for (;;) {
+				if (nkey == 0)
+					break;
+				if (i == mds)
+					break;
+				if (key != NULL)
+					*(key++) = md_buf[i];
+				nkey--;
+				i++;
+			}
+		}
+		if (niv && (i != mds)) {
+			for (;;) {
+				if (niv == 0)
+					break;
+				if (i == mds)
+					break;
+				if (iv != NULL)
+					*(iv++) = md_buf[i];
+				niv--;
+				i++;
+			}
+		}
+		if ((nkey == 0) && (niv == 0))
+			break;
+	}
+	rv = type->key_len;
+
+err:
+	EVP_MD_CTX_cleanup(&c);
+	explicit_bzero(md_buf, sizeof md_buf);
+	return rv;
+}
diff --git a/crypto/libressl/crypto/evp/evp_lib.c b/crypto/libressl/crypto/evp/evp_lib.c
new file mode 100644
index 0000000000..92bc3c217e
--- /dev/null
+++ b/crypto/libressl/crypto/evp/evp_lib.c
@@ -0,0 +1,348 @@
+/* $OpenBSD: evp_lib.c,v 1.13 2014/07/11 08:44:48 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+int
+EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+	int ret;
+
+	if (c->cipher->set_asn1_parameters != NULL)
+		ret = c->cipher->set_asn1_parameters(c, type);
+	else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1)
+		ret = EVP_CIPHER_set_asn1_iv(c, type);
+	else
+		ret = -1;
+	return (ret);
+}
+
+int
+EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+	int ret;
+
+	if (c->cipher->get_asn1_parameters != NULL)
+		ret = c->cipher->get_asn1_parameters(c, type);
+	else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1)
+		ret = EVP_CIPHER_get_asn1_iv(c, type);
+	else
+		ret = -1;
+	return (ret);
+}
+
+int
+EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+	int i = 0;
+	unsigned int l;
+
+	if (type != NULL) {
+		l = EVP_CIPHER_CTX_iv_length(c);
+		if (l > sizeof(c->iv)) {
+			EVPerr(EVP_F_EVP_CIPHER_GET_ASN1_IV,
+			     EVP_R_IV_TOO_LARGE);
+			return 0;
+		}
+		i = ASN1_TYPE_get_octetstring(type, c->oiv, l);
+		if (i != (int)l)
+			return (-1);
+		else if (i > 0)
+			memcpy(c->iv, c->oiv, l);
+	}
+	return (i);
+}
+
+int
+EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+	int i = 0;
+	unsigned int j;
+
+	if (type != NULL) {
+		j = EVP_CIPHER_CTX_iv_length(c);
+		if (j > sizeof(c->iv)) {
+			EVPerr(EVP_F_EVP_CIPHER_SET_ASN1_IV,
+			     EVP_R_IV_TOO_LARGE);
+			return 0;
+		}
+		i = ASN1_TYPE_set_octetstring(type, c->oiv, j);
+	}
+	return (i);
+}
+
+/* Convert the various cipher NIDs and dummies to a proper OID NID */
+int
+EVP_CIPHER_type(const EVP_CIPHER *ctx)
+{
+	int nid;
+	ASN1_OBJECT *otmp;
+	nid = EVP_CIPHER_nid(ctx);
+
+	switch (nid) {
+	case NID_rc2_cbc:
+	case NID_rc2_64_cbc:
+	case NID_rc2_40_cbc:
+		return NID_rc2_cbc;
+
+	case NID_rc4:
+	case NID_rc4_40:
+		return NID_rc4;
+
+	case NID_aes_128_cfb128:
+	case NID_aes_128_cfb8:
+	case NID_aes_128_cfb1:
+		return NID_aes_128_cfb128;
+
+	case NID_aes_192_cfb128:
+	case NID_aes_192_cfb8:
+	case NID_aes_192_cfb1:
+		return NID_aes_192_cfb128;
+
+	case NID_aes_256_cfb128:
+	case NID_aes_256_cfb8:
+	case NID_aes_256_cfb1:
+		return NID_aes_256_cfb128;
+
+	case NID_des_cfb64:
+	case NID_des_cfb8:
+	case NID_des_cfb1:
+		return NID_des_cfb64;
+
+	case NID_des_ede3_cfb64:
+	case NID_des_ede3_cfb8:
+	case NID_des_ede3_cfb1:
+		return NID_des_cfb64;
+
+	default:
+		/* Check it has an OID and it is valid */
+		otmp = OBJ_nid2obj(nid);
+		if (!otmp || !otmp->data)
+			nid = NID_undef;
+		ASN1_OBJECT_free(otmp);
+		return nid;
+	}
+}
+
+int
+EVP_CIPHER_block_size(const EVP_CIPHER *e)
+{
+	return e->block_size;
+}
+
+int
+EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
+{
+	return ctx->cipher->block_size;
+}
+
+int
+EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
+    unsigned int inl)
+{
+	return ctx->cipher->do_cipher(ctx, out, in, inl);
+}
+
+const EVP_CIPHER *
+EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx)
+{
+	return ctx->cipher;
+}
+
+unsigned long
+EVP_CIPHER_flags(const EVP_CIPHER *cipher)
+{
+	return cipher->flags;
+}
+
+unsigned long
+EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
+{
+	return ctx->cipher->flags;
+}
+
+void *
+EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
+{
+	return ctx->app_data;
+}
+
+void
+EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data)
+{
+	ctx->app_data = data;
+}
+
+int
+EVP_CIPHER_iv_length(const EVP_CIPHER *cipher)
+{
+	return cipher->iv_len;
+}
+
+int
+EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
+{
+	return ctx->cipher->iv_len;
+}
+
+int
+EVP_CIPHER_key_length(const EVP_CIPHER *cipher)
+{
+	return cipher->key_len;
+}
+
+int
+EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
+{
+	return ctx->key_len;
+}
+
+int
+EVP_CIPHER_nid(const EVP_CIPHER *cipher)
+{
+	return cipher->nid;
+}
+
+int
+EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
+{
+	return ctx->cipher->nid;
+}
+
+int
+EVP_MD_block_size(const EVP_MD *md)
+{
+	return md->block_size;
+}
+
+int
+EVP_MD_type(const EVP_MD *md)
+{
+	return md->type;
+}
+
+int
+EVP_MD_pkey_type(const EVP_MD *md)
+{
+	return md->pkey_type;
+}
+
+int
+EVP_MD_size(const EVP_MD *md)
+{
+	if (!md) {
+		EVPerr(EVP_F_EVP_MD_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL);
+		return -1;
+	}
+	return md->md_size;
+}
+
+unsigned long
+EVP_MD_flags(const EVP_MD *md)
+{
+	return md->flags;
+}
+
+const EVP_MD *
+EVP_MD_CTX_md(const EVP_MD_CTX *ctx)
+{
+	if (!ctx)
+		return NULL;
+	return ctx->digest;
+}
+
+void
+EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags)
+{
+	ctx->flags |= flags;
+}
+
+void
+EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags)
+{
+	ctx->flags &= ~flags;
+}
+
+int
+EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags)
+{
+	return (ctx->flags & flags);
+}
+
+void
+EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags)
+{
+	ctx->flags |= flags;
+}
+
+void
+EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags)
+{
+	ctx->flags &= ~flags;
+}
+
+int
+EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags)
+{
+	return (ctx->flags & flags);
+}
diff --git a/crypto/libressl/crypto/evp/evp_locl.h b/crypto/libressl/crypto/evp/evp_locl.h
new file mode 100644
index 0000000000..4e7dcd2da7
--- /dev/null
+++ b/crypto/libressl/crypto/evp/evp_locl.h
@@ -0,0 +1,366 @@
+/* $OpenBSD$ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Macros to code block cipher wrappers */
+
+/* Wrapper functions for each cipher mode */
+
+#define BLOCK_CIPHER_ecb_loop() \
+	size_t i, bl; \
+	bl = ctx->cipher->block_size;\
+	if(inl < bl) return 1;\
+	inl -= bl; \
+	for(i=0; i <= inl; i+=bl)
+
+#define BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
+static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
+{\
+	BLOCK_CIPHER_ecb_loop() \
+		cprefix##_ecb_encrypt(in + i, out + i, &((kstruct *)ctx->cipher_data)->ksched, ctx->encrypt);\
+	return 1;\
+}
+
+#define EVP_MAXCHUNK ((size_t)1<<(sizeof(long)*8-2))
+
+#define BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched) \
+static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
+{\
+	while(inl>=EVP_MAXCHUNK)\
+	    {\
+	    cprefix##_ofb##cbits##_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\
+	    inl-=EVP_MAXCHUNK;\
+	    in +=EVP_MAXCHUNK;\
+	    out+=EVP_MAXCHUNK;\
+	    }\
+	if (inl)\
+	    cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\
+	return 1;\
+}
+
+#define BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
+static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
+{\
+	while(inl>=EVP_MAXCHUNK) \
+	    {\
+	    cprefix##_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\
+	    inl-=EVP_MAXCHUNK;\
+	    in +=EVP_MAXCHUNK;\
+	    out+=EVP_MAXCHUNK;\
+	    }\
+	if (inl)\
+	    cprefix##_cbc_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\
+	return 1;\
+}
+
+#define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
+static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
+{\
+	size_t chunk=EVP_MAXCHUNK;\
+	if (cbits==1)  chunk>>=3;\
+	if (inl=chunk)\
+	    {\
+            cprefix##_cfb##cbits##_encrypt(in, out, (long)((cbits==1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\
+	    inl-=chunk;\
+	    in +=chunk;\
+	    out+=chunk;\
+	    if(inlc))+\
+		sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+	set_asn1, get_asn1,\
+	ctrl, \
+	NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_cbc(void) { return &cname##_cbc; }\
+static const EVP_CIPHER cname##_cfb = {\
+	nid##_cfb64, 1, key_len, iv_len, \
+	flags | EVP_CIPH_CFB_MODE,\
+	init_key,\
+	cname##_cfb_cipher,\
+	cleanup,\
+	sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+		sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+	set_asn1, get_asn1,\
+	ctrl,\
+	NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_cfb(void) { return &cname##_cfb; }\
+static const EVP_CIPHER cname##_ofb = {\
+	nid##_ofb64, 1, key_len, iv_len, \
+	flags | EVP_CIPH_OFB_MODE,\
+	init_key,\
+	cname##_ofb_cipher,\
+	cleanup,\
+	sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+		sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+	set_asn1, get_asn1,\
+	ctrl,\
+	NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_ofb(void) { return &cname##_ofb; }\
+static const EVP_CIPHER cname##_ecb = {\
+	nid##_ecb, block_size, key_len, iv_len, \
+	flags | EVP_CIPH_ECB_MODE,\
+	init_key,\
+	cname##_ecb_cipher,\
+	cleanup,\
+	sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+		sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+	set_asn1, get_asn1,\
+	ctrl,\
+	NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; }
+*/
+
+#define IMPLEMENT_BLOCK_CIPHER(cname, ksched, cprefix, kstruct, nid, \
+			       block_size, key_len, iv_len, cbits, \
+			       flags, init_key, \
+			       cleanup, set_asn1, get_asn1, ctrl) \
+	BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \
+	BLOCK_CIPHER_defs(cname, kstruct, nid, block_size, key_len, iv_len, \
+			  cbits, flags, init_key, cleanup, set_asn1, \
+			  get_asn1, ctrl)
+
+#define EVP_C_DATA(kstruct, ctx)	((kstruct *)(ctx)->cipher_data)
+
+#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len) \
+	BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \
+	BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \
+			     NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \
+			     0, cipher##_init_key, NULL, \
+			     EVP_CIPHER_set_asn1_iv, \
+			     EVP_CIPHER_get_asn1_iv, \
+			     NULL)
+
+										struct evp_pkey_ctx_st {
+	/* Method associated with this operation */
+	const EVP_PKEY_METHOD *pmeth;
+	/* Engine that implements this method or NULL if builtin */
+	ENGINE *engine;
+	/* Key: may be NULL */
+	EVP_PKEY *pkey;
+	/* Peer key for key agreement, may be NULL */
+	EVP_PKEY *peerkey;
+	/* Actual operation */
+	int operation;
+	/* Algorithm specific data */
+	void *data;
+	/* Application specific data */
+	void *app_data;
+	/* Keygen callback */
+	EVP_PKEY_gen_cb *pkey_gencb;
+	/* implementation specific keygen data */
+	int *keygen_info;
+	int keygen_info_count;
+} /* EVP_PKEY_CTX */;
+
+#define EVP_PKEY_FLAG_DYNAMIC	1
+
+struct evp_pkey_method_st {
+	int pkey_id;
+	int flags;
+
+	int (*init)(EVP_PKEY_CTX *ctx);
+	int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src);
+	void (*cleanup)(EVP_PKEY_CTX *ctx);
+
+	int (*paramgen_init)(EVP_PKEY_CTX *ctx);
+	int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
+
+	int (*keygen_init)(EVP_PKEY_CTX *ctx);
+	int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
+
+	int (*sign_init)(EVP_PKEY_CTX *ctx);
+	int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+	    const unsigned char *tbs, size_t tbslen);
+
+	int (*verify_init)(EVP_PKEY_CTX *ctx);
+	int (*verify)(EVP_PKEY_CTX *ctx,
+	    const unsigned char *sig, size_t siglen,
+	    const unsigned char *tbs, size_t tbslen);
+
+	int (*verify_recover_init)(EVP_PKEY_CTX *ctx);
+	int (*verify_recover)(EVP_PKEY_CTX *ctx,
+	    unsigned char *rout, size_t *routlen,
+	    const unsigned char *sig, size_t siglen);
+
+	int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
+	int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+	    EVP_MD_CTX *mctx);
+
+	int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
+	int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig,
+	    int siglen, EVP_MD_CTX *mctx);
+
+	int (*encrypt_init)(EVP_PKEY_CTX *ctx);
+	int (*encrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+	    const unsigned char *in, size_t inlen);
+
+	int (*decrypt_init)(EVP_PKEY_CTX *ctx);
+	int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+	    const unsigned char *in, size_t inlen);
+
+	int (*derive_init)(EVP_PKEY_CTX *ctx);
+	int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
+
+	int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
+	int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value);
+} /* EVP_PKEY_METHOD */;
+
+void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx);
+
+int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+    ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md, int en_de);
+
+/* EVP_AEAD represents a specific AEAD algorithm. */
+struct evp_aead_st {
+	unsigned char key_len;
+	unsigned char nonce_len;
+	unsigned char overhead;
+	unsigned char max_tag_len;
+
+	int (*init)(struct evp_aead_ctx_st*, const unsigned char *key,
+	    size_t key_len, size_t tag_len);
+	void (*cleanup)(struct evp_aead_ctx_st*);
+
+	int (*seal)(const struct evp_aead_ctx_st *ctx, unsigned char *out,
+	    size_t *out_len, size_t max_out_len, const unsigned char *nonce,
+	    size_t nonce_len, const unsigned char *in, size_t in_len,
+	    const unsigned char *ad, size_t ad_len);
+
+	int (*open)(const struct evp_aead_ctx_st *ctx, unsigned char *out,
+	    size_t *out_len, size_t max_out_len, const unsigned char *nonce,
+	    size_t nonce_len, const unsigned char *in, size_t in_len,
+	    const unsigned char *ad, size_t ad_len);
+};
diff --git a/crypto/libressl/crypto/evp/evp_pbe.c b/crypto/libressl/crypto/evp/evp_pbe.c
new file mode 100644
index 0000000000..7c73073314
--- /dev/null
+++ b/crypto/libressl/crypto/evp/evp_pbe.c
@@ -0,0 +1,295 @@
+/* $OpenBSD: evp_pbe.c,v 1.22 2014/10/28 05:46:56 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+
+/* Password based encryption (PBE) functions */
+
+DECLARE_STACK_OF(EVP_PBE_CTL)
+static STACK_OF(EVP_PBE_CTL) *pbe_algs;
+
+/* Setup a cipher context from a PBE algorithm */
+
+typedef struct {
+	int pbe_type;
+	int pbe_nid;
+	int cipher_nid;
+	int md_nid;
+	EVP_PBE_KEYGEN *keygen;
+} EVP_PBE_CTL;
+
+static const EVP_PBE_CTL builtin_pbe[] = {
+	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC, NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC, NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC, NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen},
+
+#ifndef OPENSSL_NO_HMAC
+	{EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen},
+#endif
+
+	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4, NID_rc4, NID_sha1, PKCS12_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4, NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC, NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC, NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC, NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC, NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen},
+
+#ifndef OPENSSL_NO_HMAC
+	{EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen},
+#endif
+	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC, NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC, NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen},
+	{EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC, NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen},
+
+
+	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0},
+	{EVP_PBE_TYPE_PRF, NID_hmacWithMD5, -1, NID_md5, 0},
+	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA224, -1, NID_sha224, 0},
+	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA256, -1, NID_sha256, 0},
+	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0},
+	{EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0},
+	{EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0},
+};
+
+int
+EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
+    ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de)
+{
+	const EVP_CIPHER *cipher;
+	const EVP_MD *md;
+	int cipher_nid, md_nid;
+	EVP_PBE_KEYGEN *keygen;
+
+	if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj),
+	    &cipher_nid, &md_nid, &keygen)) {
+		char obj_tmp[80];
+		EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_PBE_ALGORITHM);
+		if (!pbe_obj)
+			strlcpy(obj_tmp, "NULL", sizeof obj_tmp);
+		else
+			i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj);
+		ERR_asprintf_error_data("TYPE=%s", obj_tmp);
+		return 0;
+	}
+
+	if (!pass)
+		passlen = 0;
+	else if (passlen == -1)
+		passlen = strlen(pass);
+
+	if (cipher_nid == -1)
+		cipher = NULL;
+	else {
+		cipher = EVP_get_cipherbynid(cipher_nid);
+		if (!cipher) {
+			EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_CIPHER);
+			return 0;
+		}
+	}
+
+	if (md_nid == -1)
+		md = NULL;
+	else {
+		md = EVP_get_digestbynid(md_nid);
+		if (!md) {
+			EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_DIGEST);
+			return 0;
+		}
+	}
+
+	if (!keygen(ctx, pass, passlen, param, cipher, md, en_de)) {
+		EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_KEYGEN_FAILURE);
+		return 0;
+	}
+	return 1;
+}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
+
+static int
+pbe2_cmp(const EVP_PBE_CTL *pbe1, const EVP_PBE_CTL *pbe2)
+{
+	int ret = pbe1->pbe_type - pbe2->pbe_type;
+
+	if (ret)
+		return ret;
+	else
+		return pbe1->pbe_nid - pbe2->pbe_nid;
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
+
+static int
+pbe_cmp(const EVP_PBE_CTL * const *a, const EVP_PBE_CTL * const *b)
+{
+	int ret = (*a)->pbe_type - (*b)->pbe_type;
+
+	if (ret)
+		return ret;
+	else
+		return (*a)->pbe_nid - (*b)->pbe_nid;
+}
+
+/* Add a PBE algorithm */
+
+int
+EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid,
+    EVP_PBE_KEYGEN *keygen)
+{
+	EVP_PBE_CTL *pbe_tmp;
+
+	if (pbe_algs == NULL) {
+		pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp);
+		if (pbe_algs == NULL) {
+			EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE,
+			    ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+	}
+	pbe_tmp = malloc(sizeof(EVP_PBE_CTL));
+	if (pbe_tmp == NULL) {
+		EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	pbe_tmp->pbe_type = pbe_type;
+	pbe_tmp->pbe_nid = pbe_nid;
+	pbe_tmp->cipher_nid = cipher_nid;
+	pbe_tmp->md_nid = md_nid;
+	pbe_tmp->keygen = keygen;
+
+	if (sk_EVP_PBE_CTL_push(pbe_algs, pbe_tmp) == 0) {
+		free(pbe_tmp);
+		EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	return 1;
+}
+
+int
+EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
+    EVP_PBE_KEYGEN *keygen)
+{
+	int cipher_nid, md_nid;
+
+	if (cipher)
+		cipher_nid = EVP_CIPHER_nid(cipher);
+	else
+		cipher_nid = -1;
+	if (md)
+		md_nid = EVP_MD_type(md);
+	else
+		md_nid = -1;
+
+	return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid,
+	    cipher_nid, md_nid, keygen);
+}
+
+int
+EVP_PBE_find(int type, int pbe_nid,
+    int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen)
+{
+	EVP_PBE_CTL *pbetmp = NULL, pbelu;
+	int i;
+	if (pbe_nid == NID_undef)
+		return 0;
+
+	pbelu.pbe_type = type;
+	pbelu.pbe_nid = pbe_nid;
+
+	if (pbe_algs) {
+		i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu);
+		if (i != -1)
+			pbetmp = sk_EVP_PBE_CTL_value (pbe_algs, i);
+	}
+	if (pbetmp == NULL) {
+		pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe,
+		    sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL));
+	}
+	if (pbetmp == NULL)
+		return 0;
+	if (pcnid)
+		*pcnid = pbetmp->cipher_nid;
+	if (pmnid)
+		*pmnid = pbetmp->md_nid;
+	if (pkeygen)
+		*pkeygen = pbetmp->keygen;
+	return 1;
+}
+
+static void
+free_evp_pbe_ctl(EVP_PBE_CTL *pbe)
+{
+	free(pbe);
+}
+
+void
+EVP_PBE_cleanup(void)
+{
+	sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl);
+	pbe_algs = NULL;
+}
diff --git a/crypto/libressl/crypto/evp/evp_pkey.c b/crypto/libressl/crypto/evp/evp_pkey.c
new file mode 100644
index 0000000000..42c6788db8
--- /dev/null
+++ b/crypto/libressl/crypto/evp/evp_pkey.c
@@ -0,0 +1,240 @@
+/* $OpenBSD: evp_pkey.c,v 1.17 2014/07/12 16:03:37 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+
+#include "asn1_locl.h"
+
+/* Extract a private key from a PKCS8 structure */
+
+EVP_PKEY *
+EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
+{
+	EVP_PKEY *pkey = NULL;
+	ASN1_OBJECT *algoid;
+	char obj_tmp[80];
+
+	if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8))
+		return NULL;
+
+	if (!(pkey = EVP_PKEY_new())) {
+		EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+
+	if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) {
+		EVPerr(EVP_F_EVP_PKCS82PKEY,
+		    EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
+		i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
+		ERR_asprintf_error_data("TYPE=%s", obj_tmp);
+		goto error;
+	}
+
+	if (pkey->ameth->priv_decode) {
+		if (!pkey->ameth->priv_decode(pkey, p8)) {
+			EVPerr(EVP_F_EVP_PKCS82PKEY,
+			    EVP_R_PRIVATE_KEY_DECODE_ERROR);
+			goto error;
+		}
+	} else {
+		EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED);
+		goto error;
+	}
+
+	return pkey;
+
+error:
+	EVP_PKEY_free(pkey);
+	return NULL;
+}
+
+PKCS8_PRIV_KEY_INFO *
+EVP_PKEY2PKCS8(EVP_PKEY *pkey)
+{
+	return EVP_PKEY2PKCS8_broken(pkey, PKCS8_OK);
+}
+
+/* Turn a private key into a PKCS8 structure */
+
+PKCS8_PRIV_KEY_INFO *
+EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
+{
+	PKCS8_PRIV_KEY_INFO *p8;
+
+	if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) {
+		EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	p8->broken = broken;
+
+	if (pkey->ameth) {
+		if (pkey->ameth->priv_encode) {
+			if (!pkey->ameth->priv_encode(p8, pkey)) {
+				EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
+				    EVP_R_PRIVATE_KEY_ENCODE_ERROR);
+				goto error;
+			}
+		} else {
+			EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
+			    EVP_R_METHOD_NOT_SUPPORTED);
+			goto error;
+		}
+	} else {
+		EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
+		    EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
+		goto error;
+	}
+	return p8;
+
+error:
+	PKCS8_PRIV_KEY_INFO_free(p8);
+	return NULL;
+}
+
+PKCS8_PRIV_KEY_INFO *
+PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken)
+{
+	switch (broken) {
+	case PKCS8_OK:
+		p8->broken = PKCS8_OK;
+		return p8;
+		break;
+
+	case PKCS8_NO_OCTET:
+		p8->broken = PKCS8_NO_OCTET;
+		p8->pkey->type = V_ASN1_SEQUENCE;
+		return p8;
+		break;
+
+	default:
+		EVPerr(EVP_F_PKCS8_SET_BROKEN, EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE);
+		return NULL;
+	}
+}
+
+/* EVP_PKEY attribute functions */
+
+int
+EVP_PKEY_get_attr_count(const EVP_PKEY *key)
+{
+	return X509at_get_attr_count(key->attributes);
+}
+
+int
+EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos)
+{
+	return X509at_get_attr_by_NID(key->attributes, nid, lastpos);
+}
+
+int
+EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj, int lastpos)
+{
+	return X509at_get_attr_by_OBJ(key->attributes, obj, lastpos);
+}
+
+X509_ATTRIBUTE *
+EVP_PKEY_get_attr(const EVP_PKEY *key, int loc)
+{
+	return X509at_get_attr(key->attributes, loc);
+}
+
+X509_ATTRIBUTE *
+EVP_PKEY_delete_attr(EVP_PKEY *key, int loc)
+{
+	return X509at_delete_attr(key->attributes, loc);
+}
+
+int
+EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr)
+{
+	if (X509at_add1_attr(&key->attributes, attr))
+		return 1;
+	return 0;
+}
+
+int
+EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key, const ASN1_OBJECT *obj, int type,
+    const unsigned char *bytes, int len)
+{
+	if (X509at_add1_attr_by_OBJ(&key->attributes, obj, type, bytes, len))
+		return 1;
+	return 0;
+}
+
+int
+EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key, int nid, int type,
+    const unsigned char *bytes, int len)
+{
+	if (X509at_add1_attr_by_NID(&key->attributes, nid, type, bytes, len))
+		return 1;
+	return 0;
+}
+
+int
+EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, const char *attrname, int type,
+    const unsigned char *bytes, int len)
+{
+	if (X509at_add1_attr_by_txt(&key->attributes, attrname, type,
+	    bytes, len))
+		return 1;
+	return 0;
+}
diff --git a/crypto/libressl/crypto/evp/m_dss.c b/crypto/libressl/crypto/evp/m_dss.c
new file mode 100644
index 0000000000..938d347975
--- /dev/null
+++ b/crypto/libressl/crypto/evp/m_dss.c
@@ -0,0 +1,117 @@
+/* $OpenBSD: m_dss.c,v 1.15 2014/07/10 22:45:57 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_DSA
+#include 
+#endif
+
+#ifndef OPENSSL_NO_SHA
+
+static int
+init(EVP_MD_CTX *ctx)
+{
+	return SHA1_Init(ctx->md_data);
+}
+
+static int
+update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+	return SHA1_Update(ctx->md_data, data, count);
+}
+
+static int
+final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+	return SHA1_Final(md, ctx->md_data);
+}
+
+static const EVP_MD dsa_md = {
+	.type = NID_dsaWithSHA,
+	.pkey_type = NID_dsaWithSHA,
+	.md_size = SHA_DIGEST_LENGTH,
+	.flags = EVP_MD_FLAG_PKEY_DIGEST,
+	.init = init,
+	.update = update,
+	.final = final,
+	.copy = NULL,
+	.cleanup = NULL,
+#ifndef OPENSSL_NO_DSA
+	.sign = (evp_sign_method *)DSA_sign,
+	.verify = (evp_verify_method *)DSA_verify,
+	.required_pkey_type = {
+		EVP_PKEY_DSA, EVP_PKEY_DSA2, EVP_PKEY_DSA3, EVP_PKEY_DSA4, 0,
+	},
+#endif
+	.block_size = SHA_CBLOCK,
+	.ctx_size = sizeof(EVP_MD *) + sizeof(SHA_CTX),
+};
+
+const EVP_MD *
+EVP_dss(void)
+{
+	return (&dsa_md);
+}
+#endif
diff --git a/crypto/libressl/crypto/evp/m_dss1.c b/crypto/libressl/crypto/evp/m_dss1.c
new file mode 100644
index 0000000000..c13bbdecd6
--- /dev/null
+++ b/crypto/libressl/crypto/evp/m_dss1.c
@@ -0,0 +1,117 @@
+/* $OpenBSD: m_dss1.c,v 1.15 2014/07/10 22:45:57 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_SHA
+
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_DSA
+#include 
+#endif
+
+static int
+init(EVP_MD_CTX *ctx)
+{
+	return SHA1_Init(ctx->md_data);
+}
+
+static int
+update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+	return SHA1_Update(ctx->md_data, data, count);
+}
+
+static int
+final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+	return SHA1_Final(md, ctx->md_data);
+}
+
+static const EVP_MD dss1_md = {
+	.type = NID_dsa,
+	.pkey_type = NID_dsaWithSHA1,
+	.md_size = SHA_DIGEST_LENGTH,
+	.flags = EVP_MD_FLAG_PKEY_DIGEST,
+	.init = init,
+	.update = update,
+	.final = final,
+	.copy = NULL,
+	.cleanup = NULL,
+#ifndef OPENSSL_NO_DSA
+	.sign = (evp_sign_method *)DSA_sign,
+	.verify = (evp_verify_method *)DSA_verify,
+	.required_pkey_type = {
+	        EVP_PKEY_DSA, EVP_PKEY_DSA2, EVP_PKEY_DSA3, EVP_PKEY_DSA4, 0,
+	},
+#endif
+	.block_size = SHA_CBLOCK,
+	.ctx_size = sizeof(EVP_MD *) + sizeof(SHA_CTX),
+};
+
+const EVP_MD *
+EVP_dss1(void)
+{
+	return (&dss1_md);
+}
+#endif
diff --git a/crypto/libressl/crypto/evp/m_ecdsa.c b/crypto/libressl/crypto/evp/m_ecdsa.c
new file mode 100644
index 0000000000..75ff20067d
--- /dev/null
+++ b/crypto/libressl/crypto/evp/m_ecdsa.c
@@ -0,0 +1,166 @@
+/* $OpenBSD: m_ecdsa.c,v 1.7 2014/07/10 22:45:57 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_SHA
+
+static int
+init(EVP_MD_CTX *ctx)
+{
+	return SHA1_Init(ctx->md_data);
+}
+
+static int
+update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+	return SHA1_Update(ctx->md_data, data, count);
+}
+
+static int
+final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+	return SHA1_Final(md, ctx->md_data);
+}
+
+static const EVP_MD ecdsa_md = {
+	.type = NID_ecdsa_with_SHA1,
+	.pkey_type = NID_ecdsa_with_SHA1,
+	.md_size = SHA_DIGEST_LENGTH,
+	.flags = EVP_MD_FLAG_PKEY_DIGEST,
+	.init = init,
+	.update = update,
+	.final = final,
+	.copy = NULL,
+	.cleanup = NULL,
+#ifndef OPENSSL_NO_ECDSA
+	.sign = (evp_sign_method *)ECDSA_sign,
+	.verify = (evp_verify_method *)ECDSA_verify,
+	.required_pkey_type = {
+		EVP_PKEY_EC, 0, 0, 0,
+	},
+#endif
+	.block_size = SHA_CBLOCK,
+	.ctx_size = sizeof(EVP_MD *) + sizeof(SHA_CTX),
+};
+
+const EVP_MD *
+EVP_ecdsa(void)
+{
+	return (&ecdsa_md);
+}
+#endif
diff --git a/crypto/libressl/crypto/evp/m_gost2814789.c b/crypto/libressl/crypto/evp/m_gost2814789.c
new file mode 100644
index 0000000000..fcfdb4bb64
--- /dev/null
+++ b/crypto/libressl/crypto/evp/m_gost2814789.c
@@ -0,0 +1,110 @@
+/* $OpenBSD: m_gost2814789.c,v 1.1 2014/11/09 19:17:13 miod Exp $ */
+/*
+ * Copyright (c) 2014 Dmitry Eremin-Solenikov 
+ * Copyright (c) 2005-2006 Cryptocom LTD
+ *
+ * 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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+#include 
+
+#ifndef OPENSSL_NO_GOST
+
+#include 
+#include 
+#include 
+
+static int
+gost2814789_init(EVP_MD_CTX *ctx)
+{
+	return GOST2814789IMIT_Init(ctx->md_data,
+	    NID_id_Gost28147_89_CryptoPro_A_ParamSet);
+}
+
+static int
+gost2814789_update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+	return GOST2814789IMIT_Update(ctx->md_data, data, count);
+}
+
+static int
+gost2814789_final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+	return GOST2814789IMIT_Final(md, ctx->md_data);
+}
+
+static int
+gost2814789_md_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
+{
+	GOST2814789IMIT_CTX *gctx = ctx->md_data;
+
+	switch (cmd) {
+	case EVP_MD_CTRL_SET_KEY:
+		return Gost2814789_set_key(&gctx->cipher, p2, p1);
+	case EVP_MD_CTRL_GOST_SET_SBOX:
+		return Gost2814789_set_sbox(&gctx->cipher, p1);
+	}
+	return -2;
+}
+
+static const EVP_MD gost2814789imit_md = {
+	.type = NID_id_Gost28147_89_MAC,
+	.pkey_type = NID_undef,
+	.md_size = GOST2814789IMIT_LENGTH,
+	.flags = 0,
+	.init = gost2814789_init,
+	.update = gost2814789_update,
+	.final = gost2814789_final,
+	.block_size = GOST2814789IMIT_CBLOCK,
+	.ctx_size = sizeof(EVP_MD *) + sizeof(GOST2814789IMIT_CTX),
+	.md_ctrl = gost2814789_md_ctrl,
+};
+
+const EVP_MD *
+EVP_gost2814789imit(void)
+{
+	return (&gost2814789imit_md);
+}
+#endif
diff --git a/crypto/libressl/crypto/evp/m_gostr341194.c b/crypto/libressl/crypto/evp/m_gostr341194.c
new file mode 100644
index 0000000000..3e1b586fdc
--- /dev/null
+++ b/crypto/libressl/crypto/evp/m_gostr341194.c
@@ -0,0 +1,97 @@
+/* $OpenBSD: m_gostr341194.c,v 1.1 2014/11/09 19:17:13 miod Exp $ */
+/*
+ * Copyright (c) 2014 Dmitry Eremin-Solenikov 
+ * Copyright (c) 2005-2006 Cryptocom LTD
+ *
+ * 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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_GOST
+
+#include 
+#include 
+#include 
+
+static int
+gostr341194_init(EVP_MD_CTX *ctx)
+{
+	return GOSTR341194_Init(ctx->md_data,
+	    NID_id_GostR3411_94_CryptoProParamSet);
+}
+
+static int
+gostr341194_update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+	return GOSTR341194_Update(ctx->md_data, data, count);
+}
+
+static int
+gostr341194_final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+	return GOSTR341194_Final(md, ctx->md_data);
+}
+
+static const EVP_MD gostr341194_md = {
+	.type = NID_id_GostR3411_94,
+	.pkey_type = NID_undef,
+	.md_size = GOSTR341194_LENGTH,
+	.flags = EVP_MD_FLAG_PKEY_METHOD_SIGNATURE,
+	.init = gostr341194_init,
+	.update = gostr341194_update,
+	.final = gostr341194_final,
+	.block_size = GOSTR341194_CBLOCK,
+	.ctx_size = sizeof(EVP_MD *) + sizeof(GOSTR341194_CTX),
+};
+
+const EVP_MD *
+EVP_gostr341194(void)
+{
+	return (&gostr341194_md);
+}
+#endif
diff --git a/crypto/libressl/crypto/evp/m_md4.c b/crypto/libressl/crypto/evp/m_md4.c
new file mode 100644
index 0000000000..65cdd7bfba
--- /dev/null
+++ b/crypto/libressl/crypto/evp/m_md4.c
@@ -0,0 +1,118 @@
+/* $OpenBSD$ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_MD4
+
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_RSA
+#include 
+#endif
+
+static int
+init(EVP_MD_CTX *ctx)
+{
+	return MD4_Init(ctx->md_data);
+}
+
+static int
+update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+	return MD4_Update(ctx->md_data, data, count);
+}
+
+static int
+final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+	return MD4_Final(md, ctx->md_data);
+}
+
+static const EVP_MD md4_md = {
+	.type = NID_md4,
+	.pkey_type = NID_md4WithRSAEncryption,
+	.md_size = MD4_DIGEST_LENGTH,
+	.flags = 0,
+	.init = init,
+	.update = update,
+	.final = final,
+	.copy = NULL,
+	.cleanup = NULL,
+#ifndef OPENSSL_NO_RSA
+	.sign = (evp_sign_method *)RSA_sign,
+	.verify = (evp_verify_method *)RSA_verify,
+	.required_pkey_type = {
+		EVP_PKEY_RSA, EVP_PKEY_RSA2, 0, 0,
+	},
+#endif
+	.block_size = MD4_CBLOCK,
+	.ctx_size = sizeof(EVP_MD *) + sizeof(MD4_CTX),
+};
+
+const EVP_MD *
+EVP_md4(void)
+{
+	return (&md4_md);
+}
+#endif
diff --git a/crypto/libressl/crypto/evp/m_md5.c b/crypto/libressl/crypto/evp/m_md5.c
new file mode 100644
index 0000000000..d9ab24904a
--- /dev/null
+++ b/crypto/libressl/crypto/evp/m_md5.c
@@ -0,0 +1,118 @@
+/* $OpenBSD: m_md5.c,v 1.14 2014/07/11 08:44:48 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_MD5
+
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_RSA
+#include 
+#endif
+
+static int
+init(EVP_MD_CTX *ctx)
+{
+	return MD5_Init(ctx->md_data);
+}
+
+static int
+update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+	return MD5_Update(ctx->md_data, data, count);
+}
+
+static int
+final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+	return MD5_Final(md, ctx->md_data);
+}
+
+static const EVP_MD md5_md = {
+	.type = NID_md5,
+	.pkey_type = NID_md5WithRSAEncryption,
+	.md_size = MD5_DIGEST_LENGTH,
+	.flags = 0,
+	.init = init,
+	.update = update,
+	.final = final,
+	.copy = NULL,
+	.cleanup = NULL,
+#ifndef OPENSSL_NO_RSA
+	.sign = (evp_sign_method *)RSA_sign,
+	.verify = (evp_verify_method *)RSA_verify,
+	.required_pkey_type = {
+		EVP_PKEY_RSA, EVP_PKEY_RSA2, 0, 0,
+	},
+#endif
+	.block_size = MD5_CBLOCK,
+	.ctx_size = sizeof(EVP_MD *) + sizeof(MD5_CTX),
+};
+
+const EVP_MD *
+EVP_md5(void)
+{
+	return (&md5_md);
+}
+#endif
diff --git a/crypto/libressl/crypto/evp/m_null.c b/crypto/libressl/crypto/evp/m_null.c
new file mode 100644
index 0000000000..b562cc6ad1
--- /dev/null
+++ b/crypto/libressl/crypto/evp/m_null.c
@@ -0,0 +1,106 @@
+/* $OpenBSD: m_null.c,v 1.8 2014/06/12 15:49:29 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+static int
+init(EVP_MD_CTX *ctx)
+{
+	return 1;
+}
+
+static int
+update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+	return 1;
+}
+
+static int
+final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+	return 1;
+}
+
+static const EVP_MD null_md = {
+	.type = NID_undef,
+	.pkey_type = NID_undef,
+	.md_size = 0,
+	.flags = 0,
+	.init = init,
+	.update = update,
+	.final = final,
+	.copy = NULL,
+	.cleanup = NULL,
+	.sign = NULL,
+	.verify = NULL,
+	.required_pkey_type = {
+		0, 0, 0, 0,
+	},
+	.block_size = 0,
+	.ctx_size = sizeof(EVP_MD *),
+};
+
+const EVP_MD *
+EVP_md_null(void)
+{
+	return (&null_md);
+}
diff --git a/crypto/libressl/crypto/evp/m_ripemd.c b/crypto/libressl/crypto/evp/m_ripemd.c
new file mode 100644
index 0000000000..09c8fec439
--- /dev/null
+++ b/crypto/libressl/crypto/evp/m_ripemd.c
@@ -0,0 +1,118 @@
+/* $OpenBSD: m_ripemd.c,v 1.11 2014/07/11 08:44:48 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_RIPEMD
+
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_RSA
+#include 
+#endif
+
+static int
+init(EVP_MD_CTX *ctx)
+{
+	return RIPEMD160_Init(ctx->md_data);
+}
+
+static int
+update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+	return RIPEMD160_Update(ctx->md_data, data, count);
+}
+
+static int
+final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+	return RIPEMD160_Final(md, ctx->md_data);
+}
+
+static const EVP_MD ripemd160_md = {
+	.type = NID_ripemd160,
+	.pkey_type = NID_ripemd160WithRSA,
+	.md_size = RIPEMD160_DIGEST_LENGTH,
+	.flags = 0,
+	.init = init,
+	.update = update,
+	.final = final,
+	.copy = NULL,
+	.cleanup = NULL,
+#ifndef OPENSSL_NO_RSA
+	.sign = (evp_sign_method *)RSA_sign,
+	.verify = (evp_verify_method *)RSA_verify,
+	.required_pkey_type = {
+		EVP_PKEY_RSA, EVP_PKEY_RSA2, 0, 0,
+	},
+#endif
+	.block_size = RIPEMD160_CBLOCK,
+	.ctx_size = sizeof(EVP_MD *) + sizeof(RIPEMD160_CTX),
+};
+
+const EVP_MD *
+EVP_ripemd160(void)
+{
+	return (&ripemd160_md);
+}
+#endif
diff --git a/crypto/libressl/crypto/evp/m_sha1.c b/crypto/libressl/crypto/evp/m_sha1.c
new file mode 100644
index 0000000000..4f32f88f82
--- /dev/null
+++ b/crypto/libressl/crypto/evp/m_sha1.c
@@ -0,0 +1,281 @@
+/* $OpenBSD: m_sha1.c,v 1.16 2014/07/10 22:45:57 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_SHA
+
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_RSA
+#include 
+#endif
+
+static int
+init(EVP_MD_CTX *ctx)
+{
+	return SHA1_Init(ctx->md_data);
+}
+
+static int
+update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+	return SHA1_Update(ctx->md_data, data, count);
+}
+
+static int
+final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+	return SHA1_Final(md, ctx->md_data);
+}
+
+static const EVP_MD sha1_md = {
+	.type = NID_sha1,
+	.pkey_type = NID_sha1WithRSAEncryption,
+	.md_size = SHA_DIGEST_LENGTH,
+	.flags = EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
+	.init = init,
+	.update = update,
+	.final = final,
+	.copy = NULL,
+	.cleanup = NULL,
+#ifndef OPENSSL_NO_RSA
+	.sign = (evp_sign_method *)RSA_sign,
+	.verify = (evp_verify_method *)RSA_verify,
+	.required_pkey_type = {
+		EVP_PKEY_RSA, EVP_PKEY_RSA2, 0, 0,
+	},
+#endif
+	.block_size = SHA_CBLOCK,
+	.ctx_size = sizeof(EVP_MD *) + sizeof(SHA_CTX),
+};
+
+const EVP_MD *
+EVP_sha1(void)
+{
+	return (&sha1_md);
+}
+#endif
+
+#ifndef OPENSSL_NO_SHA256
+static int
+init224(EVP_MD_CTX *ctx)
+{
+	return SHA224_Init(ctx->md_data);
+}
+
+static int
+init256(EVP_MD_CTX *ctx)
+{
+	return SHA256_Init(ctx->md_data);
+}
+/*
+ * Even though there're separate SHA224_[Update|Final], we call
+ * SHA256 functions even in SHA224 context. This is what happens
+ * there anyway, so we can spare few CPU cycles:-)
+ */
+static int
+update256(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+	return SHA256_Update(ctx->md_data, data, count);
+}
+
+static int
+final256(EVP_MD_CTX *ctx, unsigned char *md)
+{
+	return SHA256_Final(md, ctx->md_data);
+}
+
+static const EVP_MD sha224_md = {
+	.type = NID_sha224,
+	.pkey_type = NID_sha224WithRSAEncryption,
+	.md_size = SHA224_DIGEST_LENGTH,
+	.flags = EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
+	.init = init224,
+	.update = update256,
+	.final = final256,
+	.copy = NULL,
+	.cleanup = NULL,
+#ifndef OPENSSL_NO_RSA
+	.sign = (evp_sign_method *)RSA_sign,
+	.verify = (evp_verify_method *)RSA_verify,
+	.required_pkey_type = {
+		EVP_PKEY_RSA, EVP_PKEY_RSA2, 0, 0,
+	},
+#endif
+	.block_size = SHA256_CBLOCK,
+	.ctx_size = sizeof(EVP_MD *) + sizeof(SHA256_CTX),
+};
+
+const EVP_MD *
+EVP_sha224(void)
+{
+	return (&sha224_md);
+}
+
+static const EVP_MD sha256_md = {
+	.type = NID_sha256,
+	.pkey_type = NID_sha256WithRSAEncryption,
+	.md_size = SHA256_DIGEST_LENGTH,
+	.flags = EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
+	.init = init256,
+	.update = update256,
+	.final = final256,
+	.copy = NULL,
+	.cleanup = NULL,
+#ifndef OPENSSL_NO_RSA
+	.sign = (evp_sign_method *)RSA_sign,
+	.verify = (evp_verify_method *)RSA_verify,
+	.required_pkey_type = {
+		EVP_PKEY_RSA, EVP_PKEY_RSA2, 0, 0,
+	},
+#endif
+	.block_size = SHA256_CBLOCK,
+	.ctx_size = sizeof(EVP_MD *) + sizeof(SHA256_CTX),
+};
+
+const EVP_MD *
+EVP_sha256(void)
+{
+	return (&sha256_md);
+}
+#endif	/* ifndef OPENSSL_NO_SHA256 */
+
+#ifndef OPENSSL_NO_SHA512
+static int
+init384(EVP_MD_CTX *ctx)
+{
+	return SHA384_Init(ctx->md_data);
+}
+
+static int
+init512(EVP_MD_CTX *ctx)
+{
+	return SHA512_Init(ctx->md_data);
+}
+/* See comment in SHA224/256 section */
+static int
+update512(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+	return SHA512_Update(ctx->md_data, data, count);
+}
+
+static int
+final512(EVP_MD_CTX *ctx, unsigned char *md)
+{
+	return SHA512_Final(md, ctx->md_data);
+}
+
+static const EVP_MD sha384_md = {
+	.type = NID_sha384,
+	.pkey_type = NID_sha384WithRSAEncryption,
+	.md_size = SHA384_DIGEST_LENGTH,
+	.flags = EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
+	.init = init384,
+	.update = update512,
+	.final = final512,
+	.copy = NULL,
+	.cleanup = NULL,
+#ifndef OPENSSL_NO_RSA
+	.sign = (evp_sign_method *)RSA_sign,
+	.verify = (evp_verify_method *)RSA_verify,
+	.required_pkey_type = {
+		EVP_PKEY_RSA, EVP_PKEY_RSA2, 0, 0,
+	},
+#endif
+	.block_size = SHA512_CBLOCK,
+	.ctx_size = sizeof(EVP_MD *) + sizeof(SHA512_CTX),
+};
+
+const EVP_MD *
+EVP_sha384(void)
+{
+	return (&sha384_md);
+}
+
+static const EVP_MD sha512_md = {
+	.type = NID_sha512,
+	.pkey_type = NID_sha512WithRSAEncryption,
+	.md_size = SHA512_DIGEST_LENGTH,
+	.flags = EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
+	.init = init512,
+	.update = update512,
+	.final = final512,
+	.copy = NULL,
+	.cleanup = NULL,
+#ifndef OPENSSL_NO_RSA
+	.sign = (evp_sign_method *)RSA_sign,
+	.verify = (evp_verify_method *)RSA_verify,
+	.required_pkey_type = {
+		EVP_PKEY_RSA, EVP_PKEY_RSA2, 0, 0,
+	},
+#endif
+	.block_size = SHA512_CBLOCK,
+	.ctx_size = sizeof(EVP_MD *) + sizeof(SHA512_CTX),
+};
+
+const EVP_MD *
+EVP_sha512(void)
+{
+	return (&sha512_md);
+}
+#endif	/* ifndef OPENSSL_NO_SHA512 */
diff --git a/crypto/libressl/crypto/evp/m_sigver.c b/crypto/libressl/crypto/evp/m_sigver.c
new file mode 100644
index 0000000000..b5770340a8
--- /dev/null
+++ b/crypto/libressl/crypto/evp/m_sigver.c
@@ -0,0 +1,193 @@
+/* $OpenBSD: m_sigver.c,v 1.4 2014/07/11 08:44:48 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006,2007 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+
+static int
+do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type,
+    ENGINE *e, EVP_PKEY *pkey, int ver)
+{
+	if (ctx->pctx == NULL)
+		ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
+	if (ctx->pctx == NULL)
+		return 0;
+
+	if (type == NULL) {
+		int def_nid;
+		if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
+			type = EVP_get_digestbynid(def_nid);
+	}
+
+	if (type == NULL) {
+		EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST);
+		return 0;
+	}
+
+	if (ver) {
+		if (ctx->pctx->pmeth->verifyctx_init) {
+			if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx,
+			    ctx) <=0)
+				return 0;
+			ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX;
+		} else if (EVP_PKEY_verify_init(ctx->pctx) <= 0)
+			return 0;
+	} else {
+		if (ctx->pctx->pmeth->signctx_init) {
+			if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0)
+				return 0;
+			ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
+		} else if (EVP_PKEY_sign_init(ctx->pctx) <= 0)
+			return 0;
+	}
+	if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0)
+		return 0;
+	if (pctx)
+		*pctx = ctx->pctx;
+	if (!EVP_DigestInit_ex(ctx, type, e))
+		return 0;
+	return 1;
+}
+
+int
+EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type,
+    ENGINE *e, EVP_PKEY *pkey)
+{
+	return do_sigver_init(ctx, pctx, type, e, pkey, 0);
+}
+
+int
+EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type,
+    ENGINE *e, EVP_PKEY *pkey)
+{
+	return do_sigver_init(ctx, pctx, type, e, pkey, 1);
+}
+
+int
+EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen)
+{
+	int sctx, r = 0;
+
+	if (ctx->pctx->pmeth->signctx)
+		sctx = 1;
+	else
+		sctx = 0;
+	if (sigret) {
+		EVP_MD_CTX tmp_ctx;
+		unsigned char md[EVP_MAX_MD_SIZE];
+		unsigned int mdlen = 0;
+		EVP_MD_CTX_init(&tmp_ctx);
+		if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx))
+			return 0;
+		if (sctx)
+			r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx,
+			    sigret, siglen, &tmp_ctx);
+		else
+			r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen);
+		EVP_MD_CTX_cleanup(&tmp_ctx);
+		if (sctx || !r)
+			return r;
+		if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0)
+			return 0;
+	} else {
+		if (sctx) {
+			if (ctx->pctx->pmeth->signctx(ctx->pctx, sigret,
+			    siglen, ctx) <= 0)
+				return 0;
+		} else {
+			int s = EVP_MD_size(ctx->digest);
+			if (s < 0 || EVP_PKEY_sign(ctx->pctx, sigret, siglen,
+			    NULL, s) <= 0)
+				return 0;
+		}
+	}
+	return 1;
+}
+
+int
+EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen)
+{
+	EVP_MD_CTX tmp_ctx;
+	unsigned char md[EVP_MAX_MD_SIZE];
+	int r;
+	unsigned int mdlen = 0;
+	int vctx;
+
+	if (ctx->pctx->pmeth->verifyctx)
+		vctx = 1;
+	else
+		vctx = 0;
+	EVP_MD_CTX_init(&tmp_ctx);
+	if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx))
+		return -1;
+	if (vctx) {
+		r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx, sig,
+		    siglen, &tmp_ctx);
+	} else
+		r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen);
+	EVP_MD_CTX_cleanup(&tmp_ctx);
+	if (vctx || !r)
+		return r;
+	return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen);
+}
diff --git a/crypto/libressl/crypto/evp/m_streebog.c b/crypto/libressl/crypto/evp/m_streebog.c
new file mode 100644
index 0000000000..da9065a1fb
--- /dev/null
+++ b/crypto/libressl/crypto/evp/m_streebog.c
@@ -0,0 +1,131 @@
+/* $OpenBSD: m_streebog.c,v 1.1 2014/11/09 19:17:13 miod Exp $ */
+/*
+ * Copyright (c) 2014 Dmitry Eremin-Solenikov 
+ * Copyright (c) 2005-2006 Cryptocom LTD
+ *
+ * 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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include 
+
+#ifndef OPENSSL_NO_GOST
+
+#include 
+#include 
+#include 
+
+static int
+streebog_init256(EVP_MD_CTX *ctx)
+{
+	return STREEBOG256_Init(ctx->md_data);
+}
+
+static int
+streebog_update256(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+	return STREEBOG256_Update(ctx->md_data, data, count);
+}
+
+static int
+streebog_final256(EVP_MD_CTX *ctx, unsigned char *md)
+{
+	return STREEBOG256_Final(md, ctx->md_data);
+}
+
+static int
+streebog_init512(EVP_MD_CTX *ctx)
+{
+	return STREEBOG512_Init(ctx->md_data);
+}
+
+static int
+streebog_update512(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+	return STREEBOG512_Update(ctx->md_data, data, count);
+}
+
+static int
+streebog_final512(EVP_MD_CTX *ctx, unsigned char *md)
+{
+	return STREEBOG512_Final(md, ctx->md_data);
+}
+
+static const EVP_MD streebog256_md = {
+	.type = NID_id_tc26_gost3411_2012_256,
+	.pkey_type = NID_undef,
+	.md_size = STREEBOG256_LENGTH,
+	.flags = EVP_MD_FLAG_PKEY_METHOD_SIGNATURE,
+	.init = streebog_init256,
+	.update = streebog_update256,
+	.final = streebog_final256,
+	.block_size = STREEBOG_CBLOCK,
+	.ctx_size = sizeof(EVP_MD *) + sizeof(STREEBOG_CTX),
+};
+
+static const EVP_MD streebog512_md = {
+	.type = NID_id_tc26_gost3411_2012_512,
+	.pkey_type = NID_undef,
+	.md_size = STREEBOG512_LENGTH,
+	.flags = EVP_MD_FLAG_PKEY_METHOD_SIGNATURE,
+	.init = streebog_init512,
+	.update = streebog_update512,
+	.final = streebog_final512,
+	.block_size = STREEBOG_CBLOCK,
+	.ctx_size = sizeof(EVP_MD *) + sizeof(STREEBOG_CTX),
+};
+
+const EVP_MD *
+EVP_streebog256(void)
+{
+	return (&streebog256_md);
+}
+
+const EVP_MD *
+EVP_streebog512(void)
+{
+	return (&streebog512_md);
+}
+#endif
diff --git a/crypto/libressl/crypto/evp/m_wp.c b/crypto/libressl/crypto/evp/m_wp.c
new file mode 100644
index 0000000000..d083218a91
--- /dev/null
+++ b/crypto/libressl/crypto/evp/m_wp.c
@@ -0,0 +1,56 @@
+/* $OpenBSD: m_wp.c,v 1.7 2014/07/11 08:44:48 jsing Exp $ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_WHIRLPOOL
+
+#include 
+#include 
+#include 
+#include 
+
+static int
+init(EVP_MD_CTX *ctx)
+{
+	return WHIRLPOOL_Init(ctx->md_data);
+}
+
+static int
+update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+	return WHIRLPOOL_Update(ctx->md_data, data, count);
+}
+
+static int
+final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+	return WHIRLPOOL_Final(md, ctx->md_data);
+}
+
+static const EVP_MD whirlpool_md = {
+	.type = NID_whirlpool,
+	.pkey_type = 0,
+	.md_size = WHIRLPOOL_DIGEST_LENGTH,
+	.flags = 0,
+	.init = init,
+	.update = update,
+	.final = final,
+	.copy = NULL,
+	.cleanup = NULL,
+	.sign = NULL,
+	.verify = NULL,
+	.required_pkey_type = {
+		0, 0, 0, 0,
+	},
+	.block_size = WHIRLPOOL_BBLOCK / 8,
+	.ctx_size = sizeof(EVP_MD *) + sizeof(WHIRLPOOL_CTX),
+};
+
+const EVP_MD *
+EVP_whirlpool(void)
+{
+	return (&whirlpool_md);
+}
+#endif
diff --git a/crypto/libressl/crypto/evp/names.c b/crypto/libressl/crypto/evp/names.c
new file mode 100644
index 0000000000..b541600b48
--- /dev/null
+++ b/crypto/libressl/crypto/evp/names.c
@@ -0,0 +1,228 @@
+/* $OpenBSD: names.c,v 1.11 2014/06/12 15:49:29 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+int
+EVP_add_cipher(const EVP_CIPHER *c)
+{
+	int r;
+
+	if (c == NULL)
+		return 0;
+
+	OPENSSL_init();
+
+	r = OBJ_NAME_add(OBJ_nid2sn(c->nid), OBJ_NAME_TYPE_CIPHER_METH,
+	    (const char *)c);
+	if (r == 0)
+		return (0);
+	check_defer(c->nid);
+	r = OBJ_NAME_add(OBJ_nid2ln(c->nid), OBJ_NAME_TYPE_CIPHER_METH,
+	    (const char *)c);
+	return (r);
+}
+
+int
+EVP_add_digest(const EVP_MD *md)
+{
+	int r;
+	const char *name;
+
+	OPENSSL_init();
+
+	name = OBJ_nid2sn(md->type);
+	r = OBJ_NAME_add(name, OBJ_NAME_TYPE_MD_METH, (const char *)md);
+	if (r == 0)
+		return (0);
+	check_defer(md->type);
+	r = OBJ_NAME_add(OBJ_nid2ln(md->type), OBJ_NAME_TYPE_MD_METH,
+	    (const char *)md);
+	if (r == 0)
+		return (0);
+
+	if (md->pkey_type && md->type != md->pkey_type) {
+		r = OBJ_NAME_add(OBJ_nid2sn(md->pkey_type),
+		    OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS, name);
+		if (r == 0)
+			return (0);
+		check_defer(md->pkey_type);
+		r = OBJ_NAME_add(OBJ_nid2ln(md->pkey_type),
+		    OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS, name);
+	}
+	return (r);
+}
+
+const EVP_CIPHER *
+EVP_get_cipherbyname(const char *name)
+{
+	const EVP_CIPHER *cp;
+
+	cp = (const EVP_CIPHER *)OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH);
+	return (cp);
+}
+
+const EVP_MD *
+EVP_get_digestbyname(const char *name)
+{
+	const EVP_MD *cp;
+
+	cp = (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH);
+	return (cp);
+}
+
+void
+EVP_cleanup(void)
+{
+	OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH);
+	OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH);
+	/* The above calls will only clean out the contents of the name
+	   hash table, but not the hash table itself.  The following line
+	   does that part.  -- Richard Levitte */
+	OBJ_NAME_cleanup(-1);
+
+	EVP_PBE_cleanup();
+	if (obj_cleanup_defer == 2) {
+		obj_cleanup_defer = 0;
+		OBJ_cleanup();
+	}
+	OBJ_sigid_free();
+}
+
+struct doall_cipher {
+	void *arg;
+	void (*fn)(const EVP_CIPHER *ciph, const char *from, const char *to,
+	    void *arg);
+};
+
+static void
+do_all_cipher_fn(const OBJ_NAME *nm, void *arg)
+{
+	struct doall_cipher *dc = arg;
+
+	if (nm->alias)
+		dc->fn(NULL, nm->name, nm->data, dc->arg);
+	else
+		dc->fn((const EVP_CIPHER *)nm->data, nm->name, NULL, dc->arg);
+}
+
+void
+EVP_CIPHER_do_all(void (*fn)(const EVP_CIPHER *ciph, const char *from,
+    const char *to, void *x), void *arg)
+{
+	struct doall_cipher dc;
+
+	dc.fn = fn;
+	dc.arg = arg;
+	OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc);
+}
+
+void
+EVP_CIPHER_do_all_sorted(void (*fn)(const EVP_CIPHER *ciph, const char *from,
+    const char *to, void *x), void *arg)
+{
+	struct doall_cipher dc;
+
+	dc.fn = fn;
+	dc.arg = arg;
+	OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
+	    do_all_cipher_fn, &dc);
+}
+
+struct doall_md {
+	void *arg;
+	void (*fn)(const EVP_MD *ciph, const char *from, const char *to,
+	    void *arg);
+};
+
+static void
+do_all_md_fn(const OBJ_NAME *nm, void *arg)
+{
+	struct doall_md *dc = arg;
+
+	if (nm->alias)
+		dc->fn(NULL, nm->name, nm->data, dc->arg);
+	else
+		dc->fn((const EVP_MD *)nm->data, nm->name, NULL, dc->arg);
+}
+
+void
+EVP_MD_do_all(void (*fn)(const EVP_MD *md, const char *from, const char *to,
+    void *x), void *arg)
+{
+	struct doall_md dc;
+
+	dc.fn = fn;
+	dc.arg = arg;
+	OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
+}
+
+void
+EVP_MD_do_all_sorted(void (*fn)(const EVP_MD *md,
+    const char *from, const char *to, void *x), void *arg)
+{
+	struct doall_md dc;
+
+	dc.fn = fn;
+	dc.arg = arg;
+	OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
+}
diff --git a/crypto/libressl/crypto/evp/p5_crpt.c b/crypto/libressl/crypto/evp/p5_crpt.c
new file mode 100644
index 0000000000..22ffb550a8
--- /dev/null
+++ b/crypto/libressl/crypto/evp/p5_crpt.c
@@ -0,0 +1,158 @@
+/* $OpenBSD: p5_crpt.c,v 1.15 2015/02/10 09:52:35 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+/* Doesn't do anything now: Builtin PBE algorithms in static table.
+ */
+
+void
+PKCS5_PBE_add(void)
+{
+}
+
+int
+PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
+    ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, int en_de)
+{
+	EVP_MD_CTX ctx;
+	unsigned char md_tmp[EVP_MAX_MD_SIZE];
+	unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
+	int i;
+	PBEPARAM *pbe;
+	int saltlen, iter;
+	unsigned char *salt;
+	const unsigned char *pbuf;
+	int mdsize;
+	int rv = 0;
+
+	/* Extract useful info from parameter */
+	if (param == NULL || param->type != V_ASN1_SEQUENCE ||
+	    param->value.sequence == NULL) {
+		EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
+		return 0;
+	}
+
+	mdsize = EVP_MD_size(md);
+	if (mdsize < 0)
+		return 0;
+
+	pbuf = param->value.sequence->data;
+	if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) {
+		EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
+		return 0;
+	}
+
+	if (!pbe->iter)
+		iter = 1;
+	else
+		iter = ASN1_INTEGER_get (pbe->iter);
+	salt = pbe->salt->data;
+	saltlen = pbe->salt->length;
+
+	if (!pass)
+		passlen = 0;
+	else if (passlen == -1)
+		passlen = strlen(pass);
+
+	EVP_MD_CTX_init(&ctx);
+
+	if (!EVP_DigestInit_ex(&ctx, md, NULL))
+		goto err;
+	if (!EVP_DigestUpdate(&ctx, pass, passlen))
+		goto err;
+	if (!EVP_DigestUpdate(&ctx, salt, saltlen))
+		goto err;
+	if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL))
+		goto err;
+	for (i = 1; i < iter; i++) {
+		if (!EVP_DigestInit_ex(&ctx, md, NULL))
+			goto err;
+		if (!EVP_DigestUpdate(&ctx, md_tmp, mdsize))
+			goto err;
+		if (!EVP_DigestFinal_ex (&ctx, md_tmp, NULL))
+			goto err;
+	}
+	if ((size_t)EVP_CIPHER_key_length(cipher) > sizeof(md_tmp)) {
+		EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_BAD_KEY_LENGTH);
+		goto err;
+	}
+	memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher));
+	if ((size_t)EVP_CIPHER_iv_length(cipher) > 16) {
+		EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_IV_TOO_LARGE);
+		goto err;
+	}
+	memcpy(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)),
+	    EVP_CIPHER_iv_length(cipher));
+	if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de))
+		goto err;
+	explicit_bzero(md_tmp, EVP_MAX_MD_SIZE);
+	explicit_bzero(key, EVP_MAX_KEY_LENGTH);
+	explicit_bzero(iv, EVP_MAX_IV_LENGTH);
+	rv = 1;
+err:
+	EVP_MD_CTX_cleanup(&ctx);
+	PBEPARAM_free(pbe);
+	return rv;
+}
diff --git a/crypto/libressl/crypto/evp/p5_crpt2.c b/crypto/libressl/crypto/evp/p5_crpt2.c
new file mode 100644
index 0000000000..e17563d101
--- /dev/null
+++ b/crypto/libressl/crypto/evp/p5_crpt2.c
@@ -0,0 +1,308 @@
+/* $OpenBSD: p5_crpt2.c,v 1.20 2015/02/14 15:49:51 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#if !defined(OPENSSL_NO_HMAC) && !defined(OPENSSL_NO_SHA)
+
+#include 
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+
+/* This is an implementation of PKCS#5 v2.0 password based encryption key
+ * derivation function PBKDF2.
+ * SHA1 version verified against test vectors posted by Peter Gutmann
+ *  to the PKCS-TNG  mailing list.
+ */
+
+int
+PKCS5_PBKDF2_HMAC(const char *pass, int passlen, const unsigned char *salt,
+    int saltlen, int iter, const EVP_MD *digest, int keylen, unsigned char *out)
+{
+	unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
+	int cplen, j, k, tkeylen, mdlen;
+	unsigned long i = 1;
+	HMAC_CTX hctx_tpl, hctx;
+
+	mdlen = EVP_MD_size(digest);
+	if (mdlen < 0)
+		return 0;
+
+	HMAC_CTX_init(&hctx_tpl);
+	p = out;
+	tkeylen = keylen;
+	if (!pass)
+		passlen = 0;
+	else if (passlen == -1)
+		passlen = strlen(pass);
+	if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL)) {
+		HMAC_CTX_cleanup(&hctx_tpl);
+		return 0;
+	}
+	while (tkeylen) {
+		if (tkeylen > mdlen)
+			cplen = mdlen;
+		else
+			cplen = tkeylen;
+		/* We are unlikely to ever use more than 256 blocks (5120 bits!)
+		 * but just in case...
+		 */
+		itmp[0] = (unsigned char)((i >> 24) & 0xff);
+		itmp[1] = (unsigned char)((i >> 16) & 0xff);
+		itmp[2] = (unsigned char)((i >> 8) & 0xff);
+		itmp[3] = (unsigned char)(i & 0xff);
+		if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) {
+			HMAC_CTX_cleanup(&hctx_tpl);
+			return 0;
+		}
+		if (!HMAC_Update(&hctx, salt, saltlen) ||
+		    !HMAC_Update(&hctx, itmp, 4) ||
+		    !HMAC_Final(&hctx, digtmp, NULL)) {
+			HMAC_CTX_cleanup(&hctx_tpl);
+			HMAC_CTX_cleanup(&hctx);
+			return 0;
+		}
+		HMAC_CTX_cleanup(&hctx);
+		memcpy(p, digtmp, cplen);
+		for (j = 1; j < iter; j++) {
+			if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) {
+				HMAC_CTX_cleanup(&hctx_tpl);
+				return 0;
+			}
+			if (!HMAC_Update(&hctx, digtmp, mdlen) ||
+			    !HMAC_Final(&hctx, digtmp, NULL)) {
+				HMAC_CTX_cleanup(&hctx_tpl);
+				HMAC_CTX_cleanup(&hctx);
+				return 0;
+			}
+			HMAC_CTX_cleanup(&hctx);
+			for (k = 0; k < cplen; k++)
+				p[k] ^= digtmp[k];
+		}
+		tkeylen -= cplen;
+		i++;
+		p += cplen;
+	}
+	HMAC_CTX_cleanup(&hctx_tpl);
+	return 1;
+}
+
+int
+PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, const unsigned char *salt,
+    int saltlen, int iter, int keylen, unsigned char *out)
+{
+	return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter,
+	    EVP_sha1(), keylen, out);
+}
+
+/* Now the key derivation function itself. This is a bit evil because
+ * it has to check the ASN1 parameters are valid: and there are quite a
+ * few of them...
+ */
+
+int
+PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+    ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md, int en_de)
+{
+	const unsigned char *pbuf;
+	int plen;
+	PBE2PARAM *pbe2 = NULL;
+	const EVP_CIPHER *cipher;
+
+	int rv = 0;
+
+	if (param == NULL || param->type != V_ASN1_SEQUENCE ||
+	    param->value.sequence == NULL) {
+		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
+		goto err;
+	}
+
+	pbuf = param->value.sequence->data;
+	plen = param->value.sequence->length;
+	if (!(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) {
+		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
+		goto err;
+	}
+
+	/* See if we recognise the key derivation function */
+
+	if (OBJ_obj2nid(pbe2->keyfunc->algorithm) != NID_id_pbkdf2) {
+		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
+		    EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION);
+		goto err;
+	}
+
+	/* lets see if we recognise the encryption algorithm.
+	 */
+
+	cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm);
+
+	if (!cipher) {
+		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
+		    EVP_R_UNSUPPORTED_CIPHER);
+		goto err;
+	}
+
+	/* Fixup cipher based on AlgorithmIdentifier */
+	if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de))
+		goto err;
+	if (EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) {
+		EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
+		    EVP_R_CIPHER_PARAMETER_ERROR);
+		goto err;
+	}
+	rv = PKCS5_v2_PBKDF2_keyivgen(ctx, pass, passlen,
+	    pbe2->keyfunc->parameter, c, md, en_de);
+
+err:
+	PBE2PARAM_free(pbe2);
+	return rv;
+}
+
+int
+PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+    ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md, int en_de)
+{
+	unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
+	const unsigned char *pbuf;
+	int saltlen, iter, plen;
+	int rv = 0;
+	unsigned int keylen = 0;
+	int prf_nid, hmac_md_nid;
+	PBKDF2PARAM *kdf = NULL;
+	const EVP_MD *prfmd;
+
+	if (EVP_CIPHER_CTX_cipher(ctx) == NULL) {
+		EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_NO_CIPHER_SET);
+		return 0;
+	}
+	keylen = EVP_CIPHER_CTX_key_length(ctx);
+	if (keylen > sizeof key) {
+		EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_BAD_KEY_LENGTH);
+		return 0;
+	}
+
+	/* Decode parameter */
+
+	if (!param || (param->type != V_ASN1_SEQUENCE)) {
+		EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR);
+		return 0;
+	}
+
+	pbuf = param->value.sequence->data;
+	plen = param->value.sequence->length;
+
+	if (!(kdf = d2i_PBKDF2PARAM(NULL, &pbuf, plen)) ) {
+		EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR);
+		return 0;
+	}
+
+	/* Now check the parameters of the kdf */
+
+	if (kdf->keylength &&
+	    (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)){
+		EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,
+		    EVP_R_UNSUPPORTED_KEYLENGTH);
+		goto err;
+	}
+
+	if (kdf->prf)
+		prf_nid = OBJ_obj2nid(kdf->prf->algorithm);
+	else
+		prf_nid = NID_hmacWithSHA1;
+
+	if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0)) {
+		EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
+		goto err;
+	}
+
+	prfmd = EVP_get_digestbynid(hmac_md_nid);
+	if (prfmd == NULL) {
+		EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
+		goto err;
+	}
+
+	if (kdf->salt->type != V_ASN1_OCTET_STRING) {
+		EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,
+		    EVP_R_UNSUPPORTED_SALT_TYPE);
+		goto err;
+	}
+
+	/* it seems that its all OK */
+	salt = kdf->salt->value.octet_string->data;
+	saltlen = kdf->salt->value.octet_string->length;
+	iter = ASN1_INTEGER_get(kdf->iter);
+	if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd,
+	    keylen, key))
+		goto err;
+	rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
+
+err:
+	explicit_bzero(key, keylen);
+	PBKDF2PARAM_free(kdf);
+	return rv;
+}
+
+#endif
diff --git a/crypto/libressl/crypto/evp/p_dec.c b/crypto/libressl/crypto/evp/p_dec.c
new file mode 100644
index 0000000000..834c90fd47
--- /dev/null
+++ b/crypto/libressl/crypto/evp/p_dec.c
@@ -0,0 +1,92 @@
+/* $OpenBSD: p_dec.c,v 1.9 2014/07/11 08:44:48 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_RSA
+#include 
+#endif
+
+int
+EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl,
+    EVP_PKEY *priv)
+{
+	int ret = -1;
+
+#ifndef OPENSSL_NO_RSA
+	if (priv->type != EVP_PKEY_RSA) {
+#endif
+		EVPerr(EVP_F_EVP_PKEY_DECRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA);
+#ifndef OPENSSL_NO_RSA
+		goto err;
+	}
+
+	ret = RSA_private_decrypt(ekl, ek, key, priv->pkey.rsa,
+	    RSA_PKCS1_PADDING);
+
+err:
+#endif
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/evp/p_enc.c b/crypto/libressl/crypto/evp/p_enc.c
new file mode 100644
index 0000000000..30ee70571c
--- /dev/null
+++ b/crypto/libressl/crypto/evp/p_enc.c
@@ -0,0 +1,89 @@
+/* $OpenBSD: p_enc.c,v 1.9 2014/07/11 08:44:48 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_RSA
+#include 
+#endif
+
+int
+EVP_PKEY_encrypt_old(unsigned char *ek, const unsigned char *key, int key_len,
+    EVP_PKEY *pubk)
+{
+	int ret = 0;
+
+#ifndef OPENSSL_NO_RSA
+	if (pubk->type != EVP_PKEY_RSA) {
+#endif
+		EVPerr(EVP_F_EVP_PKEY_ENCRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA);
+#ifndef OPENSSL_NO_RSA
+		goto err;
+	}
+	ret = RSA_public_encrypt(key_len, key, ek, pubk->pkey.rsa, RSA_PKCS1_PADDING);
+err:
+#endif
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/evp/p_lib.c b/crypto/libressl/crypto/evp/p_lib.c
new file mode 100644
index 0000000000..87642fdd19
--- /dev/null
+++ b/crypto/libressl/crypto/evp/p_lib.c
@@ -0,0 +1,483 @@
+/* $OpenBSD: p_lib.c,v 1.15 2014/07/11 08:44:48 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_DH
+#include 
+#endif
+#ifndef OPENSSL_NO_DSA
+#include 
+#endif
+#ifndef OPENSSL_NO_RSA
+#include 
+#endif
+
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+
+#include "asn1_locl.h"
+
+static void EVP_PKEY_free_it(EVP_PKEY *x);
+
+int
+EVP_PKEY_bits(EVP_PKEY *pkey)
+{
+	if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
+		return pkey->ameth->pkey_bits(pkey);
+	return 0;
+}
+
+int
+EVP_PKEY_size(EVP_PKEY *pkey)
+{
+	if (pkey && pkey->ameth && pkey->ameth->pkey_size)
+		return pkey->ameth->pkey_size(pkey);
+	return 0;
+}
+
+int
+EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
+{
+#ifndef OPENSSL_NO_DSA
+	if (pkey->type == EVP_PKEY_DSA) {
+		int ret = pkey->save_parameters;
+
+		if (mode >= 0)
+			pkey->save_parameters = mode;
+		return (ret);
+	}
+#endif
+#ifndef OPENSSL_NO_EC
+	if (pkey->type == EVP_PKEY_EC) {
+		int ret = pkey->save_parameters;
+
+		if (mode >= 0)
+			pkey->save_parameters = mode;
+		return (ret);
+	}
+#endif
+	return (0);
+}
+
+int
+EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+{
+	if (to->type != from->type) {
+		EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,
+		    EVP_R_DIFFERENT_KEY_TYPES);
+		goto err;
+	}
+
+	if (EVP_PKEY_missing_parameters(from)) {
+		EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,
+		    EVP_R_MISSING_PARAMETERS);
+		goto err;
+	}
+	if (from->ameth && from->ameth->param_copy)
+		return from->ameth->param_copy(to, from);
+
+err:
+	return 0;
+}
+
+int
+EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
+{
+	if (pkey->ameth && pkey->ameth->param_missing)
+		return pkey->ameth->param_missing(pkey);
+	return 0;
+}
+
+int
+EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+	if (a->type != b->type)
+		return -1;
+	if (a->ameth && a->ameth->param_cmp)
+		return a->ameth->param_cmp(a, b);
+	return -2;
+}
+
+int
+EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+	if (a->type != b->type)
+		return -1;
+
+	if (a->ameth) {
+		int ret;
+		/* Compare parameters if the algorithm has them */
+		if (a->ameth->param_cmp) {
+			ret = a->ameth->param_cmp(a, b);
+			if (ret <= 0)
+				return ret;
+		}
+
+		if (a->ameth->pub_cmp)
+			return a->ameth->pub_cmp(a, b);
+	}
+
+	return -2;
+}
+
+EVP_PKEY *
+EVP_PKEY_new(void)
+{
+	EVP_PKEY *ret;
+
+	ret = malloc(sizeof(EVP_PKEY));
+	if (ret == NULL) {
+		EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
+		return (NULL);
+	}
+	ret->type = EVP_PKEY_NONE;
+	ret->save_type = EVP_PKEY_NONE;
+	ret->references = 1;
+	ret->ameth = NULL;
+	ret->engine = NULL;
+	ret->pkey.ptr = NULL;
+	ret->attributes = NULL;
+	ret->save_parameters = 1;
+	return (ret);
+}
+
+/* Setup a public key ASN1 method and ENGINE from a NID or a string.
+ * If pkey is NULL just return 1 or 0 if the algorithm exists.
+ */
+
+static int
+pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
+{
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	ENGINE *e = NULL;
+	if (pkey) {
+		if (pkey->pkey.ptr)
+			EVP_PKEY_free_it(pkey);
+		/* If key type matches and a method exists then this
+		 * lookup has succeeded once so just indicate success.
+		 */
+		if ((type == pkey->save_type) && pkey->ameth)
+			return 1;
+#ifndef OPENSSL_NO_ENGINE
+		/* If we have an ENGINE release it */
+		if (pkey->engine) {
+			ENGINE_finish(pkey->engine);
+			pkey->engine = NULL;
+		}
+#endif
+	}
+	if (str)
+		ameth = EVP_PKEY_asn1_find_str(&e, str, len);
+	else
+		ameth = EVP_PKEY_asn1_find(&e, type);
+#ifndef OPENSSL_NO_ENGINE
+	if (!pkey && e)
+		ENGINE_finish(e);
+#endif
+	if (!ameth) {
+		EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
+		return 0;
+	}
+	if (pkey) {
+		pkey->ameth = ameth;
+		pkey->engine = e;
+
+		pkey->type = pkey->ameth->pkey_id;
+		pkey->save_type = type;
+	}
+	return 1;
+}
+
+int
+EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
+{
+	return pkey_set_type(pkey, type, NULL, -1);
+}
+
+int
+EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
+{
+	return pkey_set_type(pkey, EVP_PKEY_NONE, str, len);
+}
+
+int
+EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
+{
+	if (!EVP_PKEY_set_type(pkey, type))
+		return 0;
+	pkey->pkey.ptr = key;
+	return (key != NULL);
+}
+
+void *
+EVP_PKEY_get0(EVP_PKEY *pkey)
+{
+	return pkey->pkey.ptr;
+}
+
+#ifndef OPENSSL_NO_RSA
+int
+EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
+{
+	int ret = EVP_PKEY_assign_RSA(pkey, key);
+	if (ret)
+		RSA_up_ref(key);
+	return ret;
+}
+
+RSA *
+EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
+{
+	if (pkey->type != EVP_PKEY_RSA) {
+		EVPerr(EVP_F_EVP_PKEY_GET1_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
+		return NULL;
+	}
+	RSA_up_ref(pkey->pkey.rsa);
+	return pkey->pkey.rsa;
+}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+int
+EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
+{
+	int ret = EVP_PKEY_assign_DSA(pkey, key);
+	if (ret)
+		DSA_up_ref(key);
+	return ret;
+}
+
+DSA *
+EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
+{
+	if (pkey->type != EVP_PKEY_DSA) {
+		EVPerr(EVP_F_EVP_PKEY_GET1_DSA, EVP_R_EXPECTING_A_DSA_KEY);
+		return NULL;
+	}
+	DSA_up_ref(pkey->pkey.dsa);
+	return pkey->pkey.dsa;
+}
+#endif
+
+#ifndef OPENSSL_NO_EC
+
+int
+EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
+{
+	int ret = EVP_PKEY_assign_EC_KEY(pkey, key);
+	if (ret)
+		EC_KEY_up_ref(key);
+	return ret;
+}
+
+EC_KEY *
+EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
+{
+	if (pkey->type != EVP_PKEY_EC) {
+		EVPerr(EVP_F_EVP_PKEY_GET1_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
+		return NULL;
+	}
+	EC_KEY_up_ref(pkey->pkey.ec);
+	return pkey->pkey.ec;
+}
+#endif
+
+
+#ifndef OPENSSL_NO_DH
+
+int
+EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
+{
+	int ret = EVP_PKEY_assign_DH(pkey, key);
+	if (ret)
+		DH_up_ref(key);
+	return ret;
+}
+
+DH *
+EVP_PKEY_get1_DH(EVP_PKEY *pkey)
+{
+	if (pkey->type != EVP_PKEY_DH) {
+		EVPerr(EVP_F_EVP_PKEY_GET1_DH, EVP_R_EXPECTING_A_DH_KEY);
+		return NULL;
+	}
+	DH_up_ref(pkey->pkey.dh);
+	return pkey->pkey.dh;
+}
+#endif
+
+int
+EVP_PKEY_type(int type)
+{
+	int ret;
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	ENGINE *e;
+	ameth = EVP_PKEY_asn1_find(&e, type);
+	if (ameth)
+		ret = ameth->pkey_id;
+	else
+		ret = NID_undef;
+#ifndef OPENSSL_NO_ENGINE
+	if (e)
+		ENGINE_finish(e);
+#endif
+	return ret;
+}
+
+int
+EVP_PKEY_id(const EVP_PKEY *pkey)
+{
+	return pkey->type;
+}
+
+int
+EVP_PKEY_base_id(const EVP_PKEY *pkey)
+{
+	return EVP_PKEY_type(pkey->type);
+}
+
+void
+EVP_PKEY_free(EVP_PKEY *x)
+{
+	int i;
+
+	if (x == NULL)
+		return;
+
+	i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_EVP_PKEY);
+	if (i > 0)
+		return;
+
+	EVP_PKEY_free_it(x);
+	if (x->attributes)
+		sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
+	free(x);
+}
+
+static void
+EVP_PKEY_free_it(EVP_PKEY *x)
+{
+	if (x->ameth && x->ameth->pkey_free) {
+		x->ameth->pkey_free(x);
+		x->pkey.ptr = NULL;
+	}
+#ifndef OPENSSL_NO_ENGINE
+	if (x->engine) {
+		ENGINE_finish(x->engine);
+		x->engine = NULL;
+	}
+#endif
+}
+
+static int
+unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent, const char *kstr)
+{
+	BIO_indent(out, indent, 128);
+	BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
+	    kstr, OBJ_nid2ln(pkey->type));
+	return 1;
+}
+
+int
+EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
+    ASN1_PCTX *pctx)
+{
+	if (pkey->ameth && pkey->ameth->pub_print)
+		return pkey->ameth->pub_print(out, pkey, indent, pctx);
+
+	return unsup_alg(out, pkey, indent, "Public Key");
+}
+
+int
+EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
+    ASN1_PCTX *pctx)
+{
+	if (pkey->ameth && pkey->ameth->priv_print)
+		return pkey->ameth->priv_print(out, pkey, indent, pctx);
+
+	return unsup_alg(out, pkey, indent, "Private Key");
+}
+
+int
+EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
+    ASN1_PCTX *pctx)
+{
+	if (pkey->ameth && pkey->ameth->param_print)
+		return pkey->ameth->param_print(out, pkey, indent, pctx);
+	return unsup_alg(out, pkey, indent, "Parameters");
+}
+
+int
+EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
+{
+	if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
+		return -2;
+	return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID,
+	    0, pnid);
+}
+
diff --git a/crypto/libressl/crypto/evp/p_open.c b/crypto/libressl/crypto/evp/p_open.c
new file mode 100644
index 0000000000..8ac49ea3c9
--- /dev/null
+++ b/crypto/libressl/crypto/evp/p_open.c
@@ -0,0 +1,128 @@
+/* $OpenBSD: p_open.c,v 1.16 2014/07/11 08:44:48 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_RSA
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+int
+EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+    const unsigned char *ek, int ekl, const unsigned char *iv, EVP_PKEY *priv)
+{
+	unsigned char *key = NULL;
+	int i, size = 0, ret = 0;
+
+	if (type) {
+		EVP_CIPHER_CTX_init(ctx);
+		if (!EVP_DecryptInit_ex(ctx, type, NULL, NULL, NULL))
+			return 0;
+	}
+
+	if (!priv)
+		return 1;
+
+	if (priv->type != EVP_PKEY_RSA) {
+		EVPerr(EVP_F_EVP_OPENINIT, EVP_R_PUBLIC_KEY_NOT_RSA);
+		goto err;
+	}
+
+	size = RSA_size(priv->pkey.rsa);
+	key = malloc(size + 2);
+	if (key == NULL) {
+		/* ERROR */
+		EVPerr(EVP_F_EVP_OPENINIT, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	i = EVP_PKEY_decrypt_old(key, ek, ekl, priv);
+	if ((i <= 0) || !EVP_CIPHER_CTX_set_key_length(ctx, i)) {
+		/* ERROR */
+		goto err;
+	}
+	if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv))
+		goto err;
+
+	ret = 1;
+
+err:
+	if (key != NULL)
+		explicit_bzero(key, size);
+	free(key);
+	return (ret);
+}
+
+int
+EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+	int i;
+
+	i = EVP_DecryptFinal_ex(ctx, out, outl);
+	if (i)
+		i = EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL);
+	return (i);
+}
+#endif
diff --git a/crypto/libressl/crypto/evp/p_seal.c b/crypto/libressl/crypto/evp/p_seal.c
new file mode 100644
index 0000000000..d1f52459ea
--- /dev/null
+++ b/crypto/libressl/crypto/evp/p_seal.c
@@ -0,0 +1,124 @@
+/* $OpenBSD: p_seal.c,v 1.13 2014/07/11 08:44:48 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_RSA
+#include 
+#endif
+
+int
+EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char **ek,
+    int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk)
+{
+	unsigned char key[EVP_MAX_KEY_LENGTH];
+	int i;
+
+	if (type) {
+		EVP_CIPHER_CTX_init(ctx);
+		if (!EVP_EncryptInit_ex(ctx, type, NULL, NULL, NULL))
+			return 0;
+	}
+	if ((npubk <= 0) || !pubk)
+		return 1;
+	if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
+		return 0;
+	if (EVP_CIPHER_CTX_iv_length(ctx))
+		arc4random_buf(iv, EVP_CIPHER_CTX_iv_length(ctx));
+
+	if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
+		return 0;
+
+	for (i = 0; i < npubk; i++) {
+		ekl[i] = EVP_PKEY_encrypt_old(ek[i], key,
+		    EVP_CIPHER_CTX_key_length(ctx), pubk[i]);
+		if (ekl[i] <= 0)
+			return (-1);
+	}
+	return (npubk);
+}
+
+/* MACRO
+void EVP_SealUpdate(ctx,out,outl,in,inl)
+EVP_CIPHER_CTX *ctx;
+unsigned char *out;
+int *outl;
+unsigned char *in;
+int inl;
+	{
+	EVP_EncryptUpdate(ctx,out,outl,in,inl);
+	}
+*/
+
+int
+EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+	int i;
+
+	i = EVP_EncryptFinal_ex(ctx, out, outl);
+	if (i)
+		i = EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, NULL);
+	return i;
+}
diff --git a/crypto/libressl/crypto/evp/p_sign.c b/crypto/libressl/crypto/evp/p_sign.c
new file mode 100644
index 0000000000..5857fe21de
--- /dev/null
+++ b/crypto/libressl/crypto/evp/p_sign.c
@@ -0,0 +1,123 @@
+/* $OpenBSD: p_sign.c,v 1.12 2014/07/11 08:44:48 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+int
+EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
+    EVP_PKEY *pkey)
+{
+	unsigned char m[EVP_MAX_MD_SIZE];
+	unsigned int m_len;
+	int i = 0, ok = 0, v;
+	EVP_MD_CTX tmp_ctx;
+	EVP_PKEY_CTX *pkctx = NULL;
+
+	*siglen = 0;
+	EVP_MD_CTX_init(&tmp_ctx);
+	if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx))
+		goto err;
+	if (!EVP_DigestFinal_ex(&tmp_ctx, &(m[0]), &m_len))
+		goto err;
+	EVP_MD_CTX_cleanup(&tmp_ctx);
+
+	if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) {
+		size_t sltmp = (size_t)EVP_PKEY_size(pkey);
+		i = 0;
+		pkctx = EVP_PKEY_CTX_new(pkey, NULL);
+		if (!pkctx)
+			goto err;
+		if (EVP_PKEY_sign_init(pkctx) <= 0)
+			goto err;
+		if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
+			goto err;
+		if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0)
+			goto err;
+		*siglen = sltmp;
+		i = 1;
+err:
+		EVP_PKEY_CTX_free(pkctx);
+		return i;
+	}
+
+	for (i = 0; i < 4; i++) {
+		v = ctx->digest->required_pkey_type[i];
+		if (v == 0)
+			break;
+		if (pkey->type == v) {
+			ok = 1;
+			break;
+		}
+	}
+	if (!ok) {
+		EVPerr(EVP_F_EVP_SIGNFINAL, EVP_R_WRONG_PUBLIC_KEY_TYPE);
+		return (0);
+	}
+
+	if (ctx->digest->sign == NULL) {
+		EVPerr(EVP_F_EVP_SIGNFINAL, EVP_R_NO_SIGN_FUNCTION_CONFIGURED);
+		return (0);
+	}
+	return(ctx->digest->sign(ctx->digest->type, m, m_len, sigret, siglen,
+	    pkey->pkey.ptr));
+}
diff --git a/crypto/libressl/crypto/evp/p_verify.c b/crypto/libressl/crypto/evp/p_verify.c
new file mode 100644
index 0000000000..06192b28c2
--- /dev/null
+++ b/crypto/libressl/crypto/evp/p_verify.c
@@ -0,0 +1,119 @@
+/* $OpenBSD: p_verify.c,v 1.11 2014/06/12 15:49:29 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+int
+EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
+    unsigned int siglen, EVP_PKEY *pkey)
+{
+	unsigned char m[EVP_MAX_MD_SIZE];
+	unsigned int m_len;
+	int i = 0, ok = 0, v;
+	EVP_MD_CTX tmp_ctx;
+	EVP_PKEY_CTX *pkctx = NULL;
+
+	EVP_MD_CTX_init(&tmp_ctx);
+	if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx))
+		goto err;
+	if (!EVP_DigestFinal_ex(&tmp_ctx, &(m[0]), &m_len))
+		goto err;
+	EVP_MD_CTX_cleanup(&tmp_ctx);
+
+	if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) {
+		i = -1;
+		pkctx = EVP_PKEY_CTX_new(pkey, NULL);
+		if (!pkctx)
+			goto err;
+		if (EVP_PKEY_verify_init(pkctx) <= 0)
+			goto err;
+		if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
+			goto err;
+		i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len);
+err:
+		EVP_PKEY_CTX_free(pkctx);
+		return i;
+	}
+
+	for (i = 0; i < 4; i++) {
+		v = ctx->digest->required_pkey_type[i];
+		if (v == 0)
+			break;
+		if (pkey->type == v) {
+			ok = 1;
+			break;
+		}
+	}
+	if (!ok) {
+		EVPerr(EVP_F_EVP_VERIFYFINAL, EVP_R_WRONG_PUBLIC_KEY_TYPE);
+		return (-1);
+	}
+	if (ctx->digest->verify == NULL) {
+		EVPerr(EVP_F_EVP_VERIFYFINAL,
+		    EVP_R_NO_VERIFY_FUNCTION_CONFIGURED);
+		return (0);
+	}
+
+	return(ctx->digest->verify(ctx->digest->type, m, m_len,
+	    sigbuf, siglen, pkey->pkey.ptr));
+}
diff --git a/crypto/libressl/crypto/evp/pmeth_fn.c b/crypto/libressl/crypto/evp/pmeth_fn.c
new file mode 100644
index 0000000000..061a352404
--- /dev/null
+++ b/crypto/libressl/crypto/evp/pmeth_fn.c
@@ -0,0 +1,362 @@
+/* $OpenBSD: pmeth_fn.c,v 1.4 2014/07/11 08:44:48 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+
+#define M_check_autoarg(ctx, arg, arglen, err) \
+	if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \
+		{ \
+		size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
+		if (!arg) \
+			{ \
+			*arglen = pksize; \
+			return 1; \
+			} \
+		else if (*arglen < pksize) \
+			{ \
+			EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\
+			return 0; \
+			} \
+		}
+
+int
+EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
+{
+	int ret;
+
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
+		EVPerr(EVP_F_EVP_PKEY_SIGN_INIT,
+		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+	}
+	ctx->operation = EVP_PKEY_OP_SIGN;
+	if (!ctx->pmeth->sign_init)
+		return 1;
+	ret = ctx->pmeth->sign_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+}
+
+int
+EVP_PKEY_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+    const unsigned char *tbs, size_t tbslen)
+{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
+		EVPerr(EVP_F_EVP_PKEY_SIGN,
+		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+	}
+	if (ctx->operation != EVP_PKEY_OP_SIGN) {
+		EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+	}
+	M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
+	return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
+}
+
+int
+EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx)
+{
+	int ret;
+
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
+		EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT,
+		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+	}
+	ctx->operation = EVP_PKEY_OP_VERIFY;
+	if (!ctx->pmeth->verify_init)
+		return 1;
+	ret = ctx->pmeth->verify_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+}
+
+int
+EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
+    const unsigned char *tbs, size_t tbslen)
+{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
+		EVPerr(EVP_F_EVP_PKEY_VERIFY,
+		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+	}
+	if (ctx->operation != EVP_PKEY_OP_VERIFY) {
+		EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+	}
+	return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
+}
+
+int
+EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx)
+{
+	int ret;
+
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
+		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT,
+		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+	}
+	ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
+	if (!ctx->pmeth->verify_recover_init)
+		return 1;
+	ret = ctx->pmeth->verify_recover_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+}
+
+int
+EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, unsigned char *rout, size_t *routlen,
+    const unsigned char *sig, size_t siglen)
+{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
+		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER,
+		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+	}
+	if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) {
+		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER,
+		    EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+	}
+	M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER)
+	return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen);
+}
+
+int
+EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx)
+{
+	int ret;
+
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
+		EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT,
+		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+	}
+	ctx->operation = EVP_PKEY_OP_ENCRYPT;
+	if (!ctx->pmeth->encrypt_init)
+		return 1;
+	ret = ctx->pmeth->encrypt_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+}
+
+int
+EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+    const unsigned char *in, size_t inlen)
+{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
+		EVPerr(EVP_F_EVP_PKEY_ENCRYPT,
+		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+	}
+	if (ctx->operation != EVP_PKEY_OP_ENCRYPT) {
+		EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+	}
+	M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
+	return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
+}
+
+int
+EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx)
+{
+	int ret;
+
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
+		EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT,
+		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+	}
+	ctx->operation = EVP_PKEY_OP_DECRYPT;
+	if (!ctx->pmeth->decrypt_init)
+		return 1;
+	ret = ctx->pmeth->decrypt_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+}
+
+int
+EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+    const unsigned char *in, size_t inlen)
+{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
+		EVPerr(EVP_F_EVP_PKEY_DECRYPT,
+		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+	}
+	if (ctx->operation != EVP_PKEY_OP_DECRYPT) {
+		EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+	}
+	M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
+	return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
+}
+
+int
+EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
+{
+	int ret;
+
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
+		EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT,
+		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+	}
+	ctx->operation = EVP_PKEY_OP_DERIVE;
+	if (!ctx->pmeth->derive_init)
+		return 1;
+	ret = ctx->pmeth->derive_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+}
+
+int
+EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
+{
+	int ret;
+
+	if (!ctx || !ctx->pmeth || !(ctx->pmeth->derive ||
+	    ctx->pmeth->encrypt || ctx->pmeth->decrypt) ||
+	    !ctx->pmeth->ctrl) {
+		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
+		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+	}
+	if (ctx->operation != EVP_PKEY_OP_DERIVE &&
+	    ctx->operation != EVP_PKEY_OP_ENCRYPT &&
+	    ctx->operation != EVP_PKEY_OP_DECRYPT) {
+		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
+		    EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+	}
+
+	ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
+
+	if (ret <= 0)
+		return ret;
+
+	if (ret == 2)
+		return 1;
+
+	if (!ctx->pkey) {
+		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET);
+		return -1;
+	}
+
+	if (ctx->pkey->type != peer->type) {
+		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
+		    EVP_R_DIFFERENT_KEY_TYPES);
+		return -1;
+	}
+
+	/* ran@cryptocom.ru: For clarity.  The error is if parameters in peer are
+	 * present (!missing) but don't match.  EVP_PKEY_cmp_parameters may return
+	 * 1 (match), 0 (don't match) and -2 (comparison is not defined).  -1
+	 * (different key types) is impossible here because it is checked earlier.
+	 * -2 is OK for us here, as well as 1, so we can check for 0 only. */
+	if (!EVP_PKEY_missing_parameters(peer) &&
+	    !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) {
+		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
+		    EVP_R_DIFFERENT_PARAMETERS);
+		return -1;
+	}
+
+	EVP_PKEY_free(ctx->peerkey);
+	ctx->peerkey = peer;
+
+	ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
+
+	if (ret <= 0) {
+		ctx->peerkey = NULL;
+		return ret;
+	}
+
+	CRYPTO_add(&peer->references, 1, CRYPTO_LOCK_EVP_PKEY);
+	return 1;
+}
+
+int
+EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
+{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
+		EVPerr(EVP_F_EVP_PKEY_DERIVE,
+		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+	}
+	if (ctx->operation != EVP_PKEY_OP_DERIVE) {
+		EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+	}
+	M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
+	return ctx->pmeth->derive(ctx, key, pkeylen);
+}
diff --git a/crypto/libressl/crypto/evp/pmeth_gn.c b/crypto/libressl/crypto/evp/pmeth_gn.c
new file mode 100644
index 0000000000..cf3cf50f7e
--- /dev/null
+++ b/crypto/libressl/crypto/evp/pmeth_gn.c
@@ -0,0 +1,227 @@
+/* $OpenBSD: pmeth_gn.c,v 1.4 2014/07/11 08:44:48 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+
+int
+EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx)
+{
+	int ret;
+
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) {
+		EVPerr(EVP_F_EVP_PKEY_PARAMGEN_INIT,
+		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+	}
+	ctx->operation = EVP_PKEY_OP_PARAMGEN;
+	if (!ctx->pmeth->paramgen_init)
+		return 1;
+	ret = ctx->pmeth->paramgen_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+}
+
+int
+EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
+{
+	int ret;
+
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) {
+		EVPerr(EVP_F_EVP_PKEY_PARAMGEN,
+		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+	}
+
+	if (ctx->operation != EVP_PKEY_OP_PARAMGEN) {
+		EVPerr(EVP_F_EVP_PKEY_PARAMGEN, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+	}
+
+	if (!ppkey)
+		return -1;
+
+	if (!*ppkey)
+		*ppkey = EVP_PKEY_new();
+
+	ret = ctx->pmeth->paramgen(ctx, *ppkey);
+	if (ret <= 0) {
+		EVP_PKEY_free(*ppkey);
+		*ppkey = NULL;
+	}
+	return ret;
+}
+
+int
+EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx)
+{
+	int ret;
+
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) {
+		EVPerr(EVP_F_EVP_PKEY_KEYGEN_INIT,
+		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+	}
+	ctx->operation = EVP_PKEY_OP_KEYGEN;
+	if (!ctx->pmeth->keygen_init)
+		return 1;
+	ret = ctx->pmeth->keygen_init(ctx);
+	if (ret <= 0)
+		ctx->operation = EVP_PKEY_OP_UNDEFINED;
+	return ret;
+}
+
+int
+EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
+{
+	int ret;
+
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) {
+		EVPerr(EVP_F_EVP_PKEY_KEYGEN,
+		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+	}
+	if (ctx->operation != EVP_PKEY_OP_KEYGEN) {
+		EVPerr(EVP_F_EVP_PKEY_KEYGEN, EVP_R_OPERATON_NOT_INITIALIZED);
+		return -1;
+	}
+
+	if (!ppkey)
+		return -1;
+
+	if (!*ppkey)
+		*ppkey = EVP_PKEY_new();
+
+	ret = ctx->pmeth->keygen(ctx, *ppkey);
+	if (ret <= 0) {
+		EVP_PKEY_free(*ppkey);
+		*ppkey = NULL;
+	}
+	return ret;
+}
+
+void
+EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb)
+{
+	ctx->pkey_gencb = cb;
+}
+
+EVP_PKEY_gen_cb *
+EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx)
+{
+	return ctx->pkey_gencb;
+}
+
+/* "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB
+ * style callbacks.
+ */
+
+static int
+trans_cb(int a, int b, BN_GENCB *gcb)
+{
+	EVP_PKEY_CTX *ctx = gcb->arg;
+	ctx->keygen_info[0] = a;
+	ctx->keygen_info[1] = b;
+	return ctx->pkey_gencb(ctx);
+}
+
+void
+evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx)
+{
+	BN_GENCB_set(cb, trans_cb, ctx)
+}
+
+int
+EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx)
+{
+	if (idx == -1)
+		return ctx->keygen_info_count;
+	if (idx < 0 || idx > ctx->keygen_info_count)
+		return 0;
+	return ctx->keygen_info[idx];
+}
+
+EVP_PKEY *
+EVP_PKEY_new_mac_key(int type, ENGINE *e, const unsigned char *key, int keylen)
+{
+	EVP_PKEY_CTX *mac_ctx = NULL;
+	EVP_PKEY *mac_key = NULL;
+
+	mac_ctx = EVP_PKEY_CTX_new_id(type, e);
+	if (!mac_ctx)
+		return NULL;
+	if (EVP_PKEY_keygen_init(mac_ctx) <= 0)
+		goto merr;
+	if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN,
+	    EVP_PKEY_CTRL_SET_MAC_KEY, keylen, (void *)key) <= 0)
+		goto merr;
+	if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0)
+		goto merr;
+
+merr:
+	EVP_PKEY_CTX_free(mac_ctx);
+	return mac_key;
+}
diff --git a/crypto/libressl/crypto/evp/pmeth_lib.c b/crypto/libressl/crypto/evp/pmeth_lib.c
new file mode 100644
index 0000000000..b2b95dddc7
--- /dev/null
+++ b/crypto/libressl/crypto/evp/pmeth_lib.c
@@ -0,0 +1,618 @@
+/* $OpenBSD: pmeth_lib.c,v 1.10 2014/11/09 19:17:13 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+
+#include "asn1_locl.h"
+#include "evp_locl.h"
+
+typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
+
+DECLARE_STACK_OF(EVP_PKEY_METHOD)
+STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL;
+
+extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth;
+extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth, cmac_pkey_meth;
+extern const EVP_PKEY_METHOD gostimit_pkey_meth, gostr01_pkey_meth;
+
+static const EVP_PKEY_METHOD *standard_methods[] = {
+#ifndef OPENSSL_NO_RSA
+	&rsa_pkey_meth,
+#endif
+#ifndef OPENSSL_NO_DH
+	&dh_pkey_meth,
+#endif
+#ifndef OPENSSL_NO_DSA
+	&dsa_pkey_meth,
+#endif
+#ifndef OPENSSL_NO_EC
+	&ec_pkey_meth,
+#endif
+#ifndef OPENSSL_NO_GOST
+	&gostr01_pkey_meth,
+	&gostimit_pkey_meth,
+#endif
+	&hmac_pkey_meth,
+	&cmac_pkey_meth,
+};
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
+    pmeth);
+
+static int
+pmeth_cmp(const EVP_PKEY_METHOD * const *a, const EVP_PKEY_METHOD * const *b)
+{
+	return ((*a)->pkey_id - (*b)->pkey_id);
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
+    pmeth);
+
+const EVP_PKEY_METHOD *
+EVP_PKEY_meth_find(int type)
+{
+	EVP_PKEY_METHOD tmp;
+	const EVP_PKEY_METHOD *t = &tmp, **ret;
+
+	tmp.pkey_id = type;
+	if (app_pkey_methods) {
+		int idx;
+		idx = sk_EVP_PKEY_METHOD_find(app_pkey_methods, &tmp);
+		if (idx >= 0)
+			return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx);
+	}
+	ret = OBJ_bsearch_pmeth(&t, standard_methods,
+	    sizeof(standard_methods)/sizeof(EVP_PKEY_METHOD *));
+	if (!ret || !*ret)
+		return NULL;
+	return *ret;
+}
+
+static EVP_PKEY_CTX *
+int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
+{
+	EVP_PKEY_CTX *ret;
+	const EVP_PKEY_METHOD *pmeth;
+
+	if (id == -1) {
+		if (!pkey || !pkey->ameth)
+			return NULL;
+		id = pkey->ameth->pkey_id;
+	}
+#ifndef OPENSSL_NO_ENGINE
+	if (pkey && pkey->engine)
+		e = pkey->engine;
+	/* Try to find an ENGINE which implements this method */
+	if (e) {
+		if (!ENGINE_init(e)) {
+			EVPerr(EVP_F_INT_CTX_NEW, ERR_R_ENGINE_LIB);
+			return NULL;
+		}
+	} else
+		e = ENGINE_get_pkey_meth_engine(id);
+
+	/* If an ENGINE handled this method look it up. Othewise
+	 * use internal tables.
+	 */
+
+	if (e)
+		pmeth = ENGINE_get_pkey_meth(e, id);
+	else
+#endif
+		pmeth = EVP_PKEY_meth_find(id);
+
+	if (pmeth == NULL) {
+		EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM);
+		return NULL;
+	}
+
+	ret = malloc(sizeof(EVP_PKEY_CTX));
+	if (!ret) {
+#ifndef OPENSSL_NO_ENGINE
+		if (e)
+			ENGINE_finish(e);
+#endif
+		EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	ret->engine = e;
+	ret->pmeth = pmeth;
+	ret->operation = EVP_PKEY_OP_UNDEFINED;
+	ret->pkey = pkey;
+	ret->peerkey = NULL;
+	ret->pkey_gencb = 0;
+	if (pkey)
+		CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+	ret->data = NULL;
+
+	if (pmeth->init) {
+		if (pmeth->init(ret) <= 0) {
+			EVP_PKEY_CTX_free(ret);
+			return NULL;
+		}
+	}
+
+	return ret;
+}
+
+EVP_PKEY_METHOD*
+EVP_PKEY_meth_new(int id, int flags)
+{
+	EVP_PKEY_METHOD *pmeth;
+
+	pmeth = calloc(1, sizeof(EVP_PKEY_METHOD));
+	if (!pmeth)
+		return NULL;
+
+	pmeth->pkey_id = id;
+	pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
+
+	pmeth->init = 0;
+	pmeth->copy = 0;
+	pmeth->cleanup = 0;
+	pmeth->paramgen_init = 0;
+	pmeth->paramgen = 0;
+	pmeth->keygen_init = 0;
+	pmeth->keygen = 0;
+	pmeth->sign_init = 0;
+	pmeth->sign = 0;
+	pmeth->verify_init = 0;
+	pmeth->verify = 0;
+	pmeth->verify_recover_init = 0;
+	pmeth->verify_recover = 0;
+	pmeth->signctx_init = 0;
+	pmeth->signctx = 0;
+	pmeth->verifyctx_init = 0;
+	pmeth->verifyctx = 0;
+	pmeth->encrypt_init = 0;
+	pmeth->encrypt = 0;
+	pmeth->decrypt_init = 0;
+	pmeth->decrypt = 0;
+	pmeth->derive_init = 0;
+	pmeth->derive = 0;
+	pmeth->ctrl = 0;
+	pmeth->ctrl_str = 0;
+
+	return pmeth;
+}
+
+void
+EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, const EVP_PKEY_METHOD *meth)
+{
+	if (ppkey_id)
+		*ppkey_id = meth->pkey_id;
+	if (pflags)
+		*pflags = meth->flags;
+}
+
+void
+EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src)
+{
+	dst->init = src->init;
+	dst->copy = src->copy;
+	dst->cleanup = src->cleanup;
+
+	dst->paramgen_init = src->paramgen_init;
+	dst->paramgen = src->paramgen;
+
+	dst->keygen_init = src->keygen_init;
+	dst->keygen = src->keygen;
+
+	dst->sign_init = src->sign_init;
+	dst->sign = src->sign;
+
+	dst->verify_init = src->verify_init;
+	dst->verify = src->verify;
+
+	dst->verify_recover_init = src->verify_recover_init;
+	dst->verify_recover = src->verify_recover;
+
+	dst->signctx_init = src->signctx_init;
+	dst->signctx = src->signctx;
+
+	dst->verifyctx_init = src->verifyctx_init;
+	dst->verifyctx = src->verifyctx;
+
+	dst->encrypt_init = src->encrypt_init;
+	dst->encrypt = src->encrypt;
+
+	dst->decrypt_init = src->decrypt_init;
+	dst->decrypt = src->decrypt;
+
+	dst->derive_init = src->derive_init;
+	dst->derive = src->derive;
+
+	dst->ctrl = src->ctrl;
+	dst->ctrl_str = src->ctrl_str;
+}
+
+void
+EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
+{
+	if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC))
+		free(pmeth);
+}
+
+EVP_PKEY_CTX *
+EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e)
+{
+	return int_ctx_new(pkey, e, -1);
+}
+
+EVP_PKEY_CTX *
+EVP_PKEY_CTX_new_id(int id, ENGINE *e)
+{
+	return int_ctx_new(NULL, e, id);
+}
+
+EVP_PKEY_CTX *
+EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
+{
+	EVP_PKEY_CTX *rctx;
+
+	if (!pctx->pmeth || !pctx->pmeth->copy)
+		return NULL;
+#ifndef OPENSSL_NO_ENGINE
+	/* Make sure it's safe to copy a pkey context using an ENGINE */
+	if (pctx->engine && !ENGINE_init(pctx->engine)) {
+		EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_ENGINE_LIB);
+		return 0;
+	}
+#endif
+	rctx = malloc(sizeof(EVP_PKEY_CTX));
+	if (!rctx)
+		return NULL;
+
+	rctx->pmeth = pctx->pmeth;
+#ifndef OPENSSL_NO_ENGINE
+	rctx->engine = pctx->engine;
+#endif
+
+	if (pctx->pkey)
+		CRYPTO_add(&pctx->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+
+	rctx->pkey = pctx->pkey;
+
+	if (pctx->peerkey)
+		CRYPTO_add(&pctx->peerkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+
+	rctx->peerkey = pctx->peerkey;
+
+	rctx->data = NULL;
+	rctx->app_data = NULL;
+	rctx->operation = pctx->operation;
+
+	if (pctx->pmeth->copy(rctx, pctx) > 0)
+		return rctx;
+
+	EVP_PKEY_CTX_free(rctx);
+	return NULL;
+}
+
+int
+EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth)
+{
+	if (app_pkey_methods == NULL) {
+		app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp);
+		if (!app_pkey_methods)
+			return 0;
+	}
+	if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth))
+		return 0;
+	sk_EVP_PKEY_METHOD_sort(app_pkey_methods);
+	return 1;
+}
+
+void
+EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
+{
+	if (ctx == NULL)
+		return;
+	if (ctx->pmeth && ctx->pmeth->cleanup)
+		ctx->pmeth->cleanup(ctx);
+	EVP_PKEY_free(ctx->pkey);
+	EVP_PKEY_free(ctx->peerkey);
+#ifndef OPENSSL_NO_ENGINE
+	if (ctx->engine)
+		/* The EVP_PKEY_CTX we used belongs to an ENGINE, release the
+		 * functional reference we held for this reason. */
+		ENGINE_finish(ctx->engine);
+#endif
+	free(ctx);
+}
+
+int
+EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd,
+    int p1, void *p2)
+{
+	int ret;
+
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) {
+		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
+		return -2;
+	}
+	if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype))
+		return -1;
+
+	if (ctx->operation == EVP_PKEY_OP_UNDEFINED) {
+		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET);
+		return -1;
+	}
+
+	if ((optype != -1) && !(ctx->operation & optype)) {
+		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION);
+		return -1;
+	}
+
+	ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2);
+
+	if (ret == -2)
+		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
+
+	return ret;
+
+}
+
+int
+EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *name, const char *value)
+{
+	if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) {
+		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR,
+		    EVP_R_COMMAND_NOT_SUPPORTED);
+		return -2;
+	}
+	if (!strcmp(name, "digest")) {
+		const EVP_MD *md;
+		if (!value || !(md = EVP_get_digestbyname(value))) {
+			EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR,
+			    EVP_R_INVALID_DIGEST);
+			return 0;
+		}
+		return EVP_PKEY_CTX_set_signature_md(ctx, md);
+	}
+	return ctx->pmeth->ctrl_str(ctx, name, value);
+}
+
+int
+EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx)
+{
+	return ctx->operation;
+}
+
+void
+EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen)
+{
+	ctx->keygen_info = dat;
+	ctx->keygen_info_count = datlen;
+}
+
+void
+EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data)
+{
+	ctx->data = data;
+}
+
+void *
+EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx)
+{
+	return ctx->data;
+}
+
+EVP_PKEY *
+EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx)
+{
+	return ctx->pkey;
+}
+
+EVP_PKEY *
+EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx)
+{
+	return ctx->peerkey;
+}
+
+void
+EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data)
+{
+	ctx->app_data = data;
+}
+
+void *
+EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx)
+{
+	return ctx->app_data;
+}
+
+void
+EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
+    int (*init)(EVP_PKEY_CTX *ctx))
+{
+	pmeth->init = init;
+}
+
+void
+EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
+    int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src))
+{
+	pmeth->copy = copy;
+}
+
+void
+EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
+    void (*cleanup)(EVP_PKEY_CTX *ctx))
+{
+	pmeth->cleanup = cleanup;
+}
+
+void
+EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
+    int (*paramgen_init)(EVP_PKEY_CTX *ctx),
+    int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey))
+{
+	pmeth->paramgen_init = paramgen_init;
+	pmeth->paramgen = paramgen;
+}
+
+void
+EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
+    int (*keygen_init)(EVP_PKEY_CTX *ctx),
+    int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey))
+{
+	pmeth->keygen_init = keygen_init;
+	pmeth->keygen = keygen;
+}
+
+void
+EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
+    int (*sign_init)(EVP_PKEY_CTX *ctx),
+    int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+    const unsigned char *tbs, size_t tbslen))
+{
+	pmeth->sign_init = sign_init;
+	pmeth->sign = sign;
+}
+
+void
+EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
+    int (*verify_init)(EVP_PKEY_CTX *ctx),
+    int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
+    const unsigned char *tbs, size_t tbslen))
+{
+	pmeth->verify_init = verify_init;
+	pmeth->verify = verify;
+}
+
+void
+EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
+    int (*verify_recover_init)(EVP_PKEY_CTX *ctx),
+    int (*verify_recover)(EVP_PKEY_CTX *ctx,
+    unsigned char *sig, size_t *siglen,
+    const unsigned char *tbs, size_t tbslen))
+{
+	pmeth->verify_recover_init = verify_recover_init;
+	pmeth->verify_recover = verify_recover;
+}
+
+void
+EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
+    int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
+    int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+    EVP_MD_CTX *mctx))
+{
+	pmeth->signctx_init = signctx_init;
+	pmeth->signctx = signctx;
+}
+
+void
+EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
+    int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
+    int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen,
+    EVP_MD_CTX *mctx))
+{
+	pmeth->verifyctx_init = verifyctx_init;
+	pmeth->verifyctx = verifyctx;
+}
+
+void
+EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
+    int (*encrypt_init)(EVP_PKEY_CTX *ctx),
+    int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+    const unsigned char *in, size_t inlen))
+{
+	pmeth->encrypt_init = encrypt_init;
+	pmeth->encrypt = encryptfn;
+}
+
+void
+EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
+    int (*decrypt_init)(EVP_PKEY_CTX *ctx),
+    int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+    const unsigned char *in, size_t inlen))
+{
+	pmeth->decrypt_init = decrypt_init;
+	pmeth->decrypt = decrypt;
+}
+
+void
+EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
+    int (*derive_init)(EVP_PKEY_CTX *ctx),
+    int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen))
+{
+	pmeth->derive_init = derive_init;
+	pmeth->derive = derive;
+}
+
+void
+EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
+    int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2),
+    int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value))
+{
+	pmeth->ctrl = ctrl;
+	pmeth->ctrl_str = ctrl_str;
+}
diff --git a/crypto/libressl/crypto/ex_data.c b/crypto/libressl/crypto/ex_data.c
new file mode 100644
index 0000000000..bc86a5bd2d
--- /dev/null
+++ b/crypto/libressl/crypto/ex_data.c
@@ -0,0 +1,638 @@
+/* $OpenBSD: ex_data.c,v 1.17 2014/07/11 08:44:47 jsing Exp $ */
+
+/*
+ * Overhaul notes;
+ *
+ * This code is now *mostly* thread-safe. It is now easier to understand in what
+ * ways it is safe and in what ways it is not, which is an improvement. Firstly,
+ * all per-class stacks and index-counters for ex_data are stored in the same
+ * global LHASH table (keyed by class). This hash table uses locking for all
+ * access with the exception of CRYPTO_cleanup_all_ex_data(), which must only be
+ * called when no other threads can possibly race against it (even if it was
+ * locked, the race would mean it's possible the hash table might have been
+ * recreated after the cleanup). As classes can only be added to the hash table,
+ * and within each class, the stack of methods can only be incremented, the
+ * locking mechanics are simpler than they would otherwise be. For example, the
+ * new/dup/free ex_data functions will lock the hash table, copy the method
+ * pointers it needs from the relevant class, then unlock the hash table before
+ * actually applying those method pointers to the task of the new/dup/free
+ * operations. As they can't be removed from the method-stack, only
+ * supplemented, there's no race conditions associated with using them outside
+ * the lock. The get/set_ex_data functions are not locked because they do not
+ * involve this global state at all - they operate directly with a previously
+ * obtained per-class method index and a particular "ex_data" variable. These
+ * variables are usually instantiated per-context (eg. each RSA structure has
+ * one) so locking on read/write access to that variable can be locked locally
+ * if required (eg. using the "RSA" lock to synchronise access to a
+ * per-RSA-structure ex_data variable if required).
+ * [Geoff]
+ */
+
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+/* What an "implementation of ex_data functionality" looks like */
+struct st_CRYPTO_EX_DATA_IMPL {
+	/*********************/
+	/* GLOBAL OPERATIONS */
+	/* Return a new class index */
+	int (*cb_new_class)(void);
+	/* Cleanup all state used by the implementation */
+	void (*cb_cleanup)(void);
+	/************************/
+	/* PER-CLASS OPERATIONS */
+	/* Get a new method index within a class */
+	int (*cb_get_new_index)(int class_index, long argl, void *argp,
+	    CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+	    CRYPTO_EX_free *free_func);
+	/* Initialise a new CRYPTO_EX_DATA of a given class */
+	int (*cb_new_ex_data)(int class_index, void *obj,
+	    CRYPTO_EX_DATA *ad);
+	/* Duplicate a CRYPTO_EX_DATA of a given class onto a copy */
+	int (*cb_dup_ex_data)(int class_index, CRYPTO_EX_DATA *to,
+	    CRYPTO_EX_DATA *from);
+	/* Cleanup a CRYPTO_EX_DATA of a given class */
+	void (*cb_free_ex_data)(int class_index, void *obj,
+	    CRYPTO_EX_DATA *ad);
+};
+
+/* The implementation we use at run-time */
+static const CRYPTO_EX_DATA_IMPL *impl = NULL;
+
+/* To call "impl" functions, use this macro rather than referring to 'impl' directly, eg.
+ * EX_IMPL(get_new_index)(...);
+*/
+#define EX_IMPL(a) impl->cb_##a
+
+/* Predeclare the "default" ex_data implementation */
+static int int_new_class(void);
+static void int_cleanup(void);
+static int int_get_new_index(int class_index, long argl, void *argp,
+    CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+    CRYPTO_EX_free *free_func);
+static int int_new_ex_data(int class_index, void *obj,
+    CRYPTO_EX_DATA *ad);
+static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
+    CRYPTO_EX_DATA *from);
+static void int_free_ex_data(int class_index, void *obj,
+    CRYPTO_EX_DATA *ad);
+
+static CRYPTO_EX_DATA_IMPL impl_default = {
+	int_new_class,
+	int_cleanup,
+	int_get_new_index,
+	int_new_ex_data,
+	int_dup_ex_data,
+	int_free_ex_data
+};
+
+/* Internal function that checks whether "impl" is set and if not, sets it to
+ * the default. */
+static void
+impl_check(void)
+{
+	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+	if (!impl)
+		impl = &impl_default;
+	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+}
+/* A macro wrapper for impl_check that first uses a non-locked test before
+ * invoking the function (which checks again inside a lock). */
+#define IMPL_CHECK if(!impl) impl_check();
+
+/* API functions to get/set the "ex_data" implementation */
+const CRYPTO_EX_DATA_IMPL *
+CRYPTO_get_ex_data_implementation(void)
+{
+	IMPL_CHECK
+	return impl;
+}
+
+int
+CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i)
+{
+	int toret = 0;
+	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+	if (!impl) {
+		impl = i;
+		toret = 1;
+	}
+	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+	return toret;
+}
+
+/****************************************************************************/
+/* Interal (default) implementation of "ex_data" support. API functions are
+ * further down. */
+
+/* The type that represents what each "class" used to implement locally. A STACK
+ * of CRYPTO_EX_DATA_FUNCS plus a index-counter. The 'class_index' is the global
+ * value representing the class that is used to distinguish these items. */
+typedef struct st_ex_class_item {
+	int class_index;
+	STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth;
+	int meth_num;
+} EX_CLASS_ITEM;
+
+/* When assigning new class indexes, this is our counter */
+static int ex_class = CRYPTO_EX_INDEX_USER;
+
+/* The global hash table of EX_CLASS_ITEM items */
+DECLARE_LHASH_OF(EX_CLASS_ITEM);
+static LHASH_OF(EX_CLASS_ITEM) *ex_data = NULL;
+
+/* The callbacks required in the "ex_data" hash table */
+static unsigned long
+ex_class_item_hash(const EX_CLASS_ITEM *a)
+{
+	return a->class_index;
+}
+
+static IMPLEMENT_LHASH_HASH_FN(ex_class_item, EX_CLASS_ITEM)
+
+static int
+ex_class_item_cmp(const EX_CLASS_ITEM *a, const EX_CLASS_ITEM *b)
+{
+	return a->class_index - b->class_index;
+}
+
+static IMPLEMENT_LHASH_COMP_FN(ex_class_item, EX_CLASS_ITEM)
+
+/* Internal functions used by the "impl_default" implementation to access the
+ * state */
+
+static int
+ex_data_check(void)
+{
+	int toret = 1;
+	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+	if (!ex_data &&
+	    (ex_data = lh_EX_CLASS_ITEM_new()) == NULL)
+		toret = 0;
+	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+	return toret;
+}
+/* This macros helps reduce the locking from repeated checks because the
+ * ex_data_check() function checks ex_data again inside a lock. */
+#define EX_DATA_CHECK(iffail) if(!ex_data && !ex_data_check()) {iffail}
+
+/* This "inner" callback is used by the callback function that follows it */
+static void
+def_cleanup_util_cb(CRYPTO_EX_DATA_FUNCS *funcs)
+{
+	free(funcs);
+}
+
+/* This callback is used in lh_doall to destroy all EX_CLASS_ITEM values from
+ * "ex_data" prior to the ex_data hash table being itself destroyed. Doesn't do
+ * any locking. */
+static void
+def_cleanup_cb(void *a_void)
+{
+	EX_CLASS_ITEM *item = (EX_CLASS_ITEM *)a_void;
+	sk_CRYPTO_EX_DATA_FUNCS_pop_free(item->meth, def_cleanup_util_cb);
+	free(item);
+}
+
+/* Return the EX_CLASS_ITEM from the "ex_data" hash table that corresponds to a
+ * given class. Handles locking. */
+static EX_CLASS_ITEM *
+def_get_class(int class_index)
+{
+	EX_CLASS_ITEM d, *p, *gen;
+	EX_DATA_CHECK(return NULL;)
+	d.class_index = class_index;
+	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+	p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d);
+	if (!p) {
+		gen = malloc(sizeof(EX_CLASS_ITEM));
+		if (gen) {
+			gen->class_index = class_index;
+			gen->meth_num = 0;
+			gen->meth = sk_CRYPTO_EX_DATA_FUNCS_new_null();
+			if (!gen->meth)
+				free(gen);
+			else {
+				/* Because we're inside the ex_data lock, the
+				 * return value from the insert will be NULL */
+				(void)lh_EX_CLASS_ITEM_insert(ex_data, gen);
+				p = gen;
+			}
+		}
+	}
+	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+	if (!p)
+		CRYPTOerr(CRYPTO_F_DEF_GET_CLASS, ERR_R_MALLOC_FAILURE);
+	return p;
+}
+
+/* Add a new method to the given EX_CLASS_ITEM and return the corresponding
+ * index (or -1 for error). Handles locking. */
+static int
+def_add_index(EX_CLASS_ITEM *item, long argl, void *argp,
+    CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+{
+	int toret = -1;
+	CRYPTO_EX_DATA_FUNCS *a = malloc(sizeof(CRYPTO_EX_DATA_FUNCS));
+
+	if (!a) {
+		CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX, ERR_R_MALLOC_FAILURE);
+		return -1;
+	}
+	a->argl = argl;
+	a->argp = argp;
+	a->new_func = new_func;
+	a->dup_func = dup_func;
+	a->free_func = free_func;
+	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+	while (sk_CRYPTO_EX_DATA_FUNCS_num(item->meth) <= item->meth_num) {
+		if (!sk_CRYPTO_EX_DATA_FUNCS_push(item->meth, NULL)) {
+			CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX, ERR_R_MALLOC_FAILURE);
+			free(a);
+			goto err;
+		}
+	}
+	toret = item->meth_num++;
+	(void)sk_CRYPTO_EX_DATA_FUNCS_set(item->meth, toret, a);
+err:
+	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+	return toret;
+}
+
+/**************************************************************/
+/* The functions in the default CRYPTO_EX_DATA_IMPL structure */
+
+static int
+int_new_class(void)
+{
+	int toret;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+	toret = ex_class++;
+	CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+	return toret;
+}
+
+static void
+int_cleanup(void)
+{
+	EX_DATA_CHECK(return;)
+	lh_EX_CLASS_ITEM_doall(ex_data, def_cleanup_cb);
+	lh_EX_CLASS_ITEM_free(ex_data);
+	ex_data = NULL;
+	impl = NULL;
+}
+
+static int
+int_get_new_index(int class_index, long argl, void *argp,
+    CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+    CRYPTO_EX_free *free_func)
+{
+	EX_CLASS_ITEM *item = def_get_class(class_index);
+
+	if (!item)
+		return -1;
+	return def_add_index(item, argl, argp, new_func, dup_func, free_func);
+}
+
+/* Thread-safe by copying a class's array of "CRYPTO_EX_DATA_FUNCS" entries in
+ * the lock, then using them outside the lock. NB: Thread-safety only applies to
+ * the global "ex_data" state (ie. class definitions), not thread-safe on 'ad'
+ * itself. */
+static int
+int_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
+{
+	int mx, i;
+	void *ptr;
+	CRYPTO_EX_DATA_FUNCS **storage = NULL;
+	EX_CLASS_ITEM *item = def_get_class(class_index);
+
+	if (!item)
+		/* error is already set */
+		return 0;
+	ad->sk = NULL;
+	CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
+	mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
+	if (mx > 0) {
+		storage = reallocarray(NULL, mx, sizeof(CRYPTO_EX_DATA_FUNCS*));
+		if (!storage)
+			goto skip;
+		for (i = 0; i < mx; i++)
+			storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(
+			    item->meth, i);
+	}
+skip:
+	CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
+	if ((mx > 0) && !storage) {
+		CRYPTOerr(CRYPTO_F_INT_NEW_EX_DATA, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	for (i = 0; i < mx; i++) {
+		if (storage[i] && storage[i]->new_func) {
+			ptr = CRYPTO_get_ex_data(ad, i);
+			storage[i]->new_func(obj, ptr, ad, i,
+			    storage[i]->argl, storage[i]->argp);
+		}
+	}
+	free(storage);
+	return 1;
+}
+
+/* Same thread-safety notes as for "int_new_ex_data" */
+static int
+int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from)
+{
+	int mx, j, i;
+	char *ptr;
+	CRYPTO_EX_DATA_FUNCS **storage = NULL;
+	EX_CLASS_ITEM *item;
+
+	if (!from->sk)
+		/* 'to' should be "blank" which *is* just like 'from' */
+		return 1;
+	if ((item = def_get_class(class_index)) == NULL)
+		return 0;
+	CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
+	mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
+	j = sk_void_num(from->sk);
+	if (j < mx)
+		mx = j;
+	if (mx > 0) {
+		storage = reallocarray(NULL, mx, sizeof(CRYPTO_EX_DATA_FUNCS*));
+		if (!storage)
+			goto skip;
+		for (i = 0; i < mx; i++)
+			storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(
+			    item->meth, i);
+	}
+skip:
+	CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
+	if ((mx > 0) && !storage) {
+		CRYPTOerr(CRYPTO_F_INT_DUP_EX_DATA, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	for (i = 0; i < mx; i++) {
+		ptr = CRYPTO_get_ex_data(from, i);
+		if (storage[i] && storage[i]->dup_func)
+			storage[i]->dup_func(to, from, &ptr, i,
+			    storage[i]->argl, storage[i]->argp);
+		CRYPTO_set_ex_data(to, i, ptr);
+	}
+	free(storage);
+	return 1;
+}
+
+/* Same thread-safety notes as for "int_new_ex_data" */
+static void
+int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
+{
+	int mx, i;
+	EX_CLASS_ITEM *item;
+	void *ptr;
+	CRYPTO_EX_DATA_FUNCS **storage = NULL;
+	if ((item = def_get_class(class_index)) == NULL)
+		return;
+	CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
+	mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
+	if (mx > 0) {
+		storage = reallocarray(NULL, mx, sizeof(CRYPTO_EX_DATA_FUNCS*));
+		if (!storage)
+			goto skip;
+		for (i = 0; i < mx; i++)
+			storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(
+			    item->meth, i);
+	}
+skip:
+	CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
+	if ((mx > 0) && !storage) {
+		CRYPTOerr(CRYPTO_F_INT_FREE_EX_DATA, ERR_R_MALLOC_FAILURE);
+		return;
+	}
+	for (i = 0; i < mx; i++) {
+		if (storage[i] && storage[i]->free_func) {
+			ptr = CRYPTO_get_ex_data(ad, i);
+			storage[i]->free_func(obj, ptr, ad, i,
+			    storage[i]->argl, storage[i]->argp);
+		}
+	}
+	free(storage);
+	if (ad->sk) {
+		sk_void_free(ad->sk);
+		ad->sk = NULL;
+	}
+}
+
+/********************************************************************/
+/* API functions that defer all "state" operations to the "ex_data"
+ * implementation we have set. */
+
+/* Obtain an index for a new class (not the same as getting a new index within
+ * an existing class - this is actually getting a new *class*) */
+int
+CRYPTO_ex_data_new_class(void)
+{
+	IMPL_CHECK
+	return EX_IMPL(new_class)();
+}
+
+/* Release all "ex_data" state to prevent memory leaks. This can't be made
+ * thread-safe without overhauling a lot of stuff, and shouldn't really be
+ * called under potential race-conditions anyway (it's for program shutdown
+ * after all). */
+void
+CRYPTO_cleanup_all_ex_data(void)
+{
+	IMPL_CHECK
+	EX_IMPL(cleanup)();
+}
+
+/* Inside an existing class, get/register a new index. */
+int
+CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
+    CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+{
+	int ret = -1;
+
+	IMPL_CHECK
+	ret = EX_IMPL(get_new_index)(class_index,
+	    argl, argp, new_func, dup_func, free_func);
+	return ret;
+}
+
+/* Initialise a new CRYPTO_EX_DATA for use in a particular class - including
+ * calling new() callbacks for each index in the class used by this variable */
+int
+CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
+{
+	IMPL_CHECK
+	return EX_IMPL(new_ex_data)(class_index, obj, ad);
+}
+
+/* Duplicate a CRYPTO_EX_DATA variable - including calling dup() callbacks for
+ * each index in the class used by this variable */
+int
+CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from)
+{
+	IMPL_CHECK
+	return EX_IMPL(dup_ex_data)(class_index, to, from);
+}
+
+/* Cleanup a CRYPTO_EX_DATA variable - including calling free() callbacks for
+ * each index in the class used by this variable */
+void
+CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
+{
+	IMPL_CHECK
+	EX_IMPL(free_ex_data)(class_index, obj, ad);
+}
+
+/* For a given CRYPTO_EX_DATA variable, set the value corresponding to a
+ * particular index in the class used by this variable */
+int
+CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val)
+{
+	int i;
+
+	if (ad->sk == NULL) {
+		if ((ad->sk = sk_void_new_null()) == NULL) {
+			CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,
+			    ERR_R_MALLOC_FAILURE);
+			return (0);
+		}
+	}
+	i = sk_void_num(ad->sk);
+
+	while (i <= idx) {
+		if (!sk_void_push(ad->sk, NULL)) {
+			CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,
+			    ERR_R_MALLOC_FAILURE);
+			return (0);
+		}
+		i++;
+	}
+	sk_void_set(ad->sk, idx, val);
+	return (1);
+}
+
+/* For a given CRYPTO_EX_DATA_ variable, get the value corresponding to a
+ * particular index in the class used by this variable */
+void *
+CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx)
+{
+	if (ad->sk == NULL)
+		return (0);
+	else if (idx >= sk_void_num(ad->sk))
+		return (0);
+	else
+		return (sk_void_value(ad->sk, idx));
+}
diff --git a/crypto/libressl/crypto/gost/gost.h b/crypto/libressl/crypto/gost/gost.h
new file mode 100644
index 0000000000..f6f1007763
--- /dev/null
+++ b/crypto/libressl/crypto/gost/gost.h
@@ -0,0 +1,262 @@
+/* $OpenBSD: gost.h,v 1.1 2014/11/09 19:17:13 miod Exp $ */
+/*
+ * Copyright (c) 2014 Dmitry Eremin-Solenikov 
+ * Copyright (c) 2005-2006 Cryptocom LTD
+ *
+ * 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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#ifndef HEADER_GOST_H
+#define HEADER_GOST_H
+
+#include 
+
+#ifdef OPENSSL_NO_GOST
+#error GOST is disabled.
+#endif
+
+#include 
+#include 
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct gost2814789_key_st {
+	unsigned int key[8];
+	unsigned int k87[256],k65[256],k43[256],k21[256];
+	unsigned int count;
+	unsigned key_meshing : 1;
+} GOST2814789_KEY;
+
+int Gost2814789_set_sbox(GOST2814789_KEY *key, int nid);
+int Gost2814789_set_key(GOST2814789_KEY *key,
+		const unsigned char *userKey, const int bits);
+void Gost2814789_ecb_encrypt(const unsigned char *in, unsigned char *out,
+	GOST2814789_KEY *key, const int enc);
+void Gost2814789_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, GOST2814789_KEY *key,
+	unsigned char *ivec, int *num, const int enc);
+void Gost2814789_cnt_encrypt(const unsigned char *in, unsigned char *out,
+	size_t length, GOST2814789_KEY *key,
+	unsigned char *ivec, unsigned char *cnt_buf, int *num);
+
+typedef struct {
+	ASN1_OCTET_STRING *iv;
+	ASN1_OBJECT *enc_param_set;
+} GOST_CIPHER_PARAMS;
+
+DECLARE_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS)
+
+#define GOST2814789IMIT_LENGTH 4
+#define GOST2814789IMIT_CBLOCK 8
+#define GOST2814789IMIT_LONG unsigned int
+
+typedef struct GOST2814789IMITstate_st {
+	GOST2814789IMIT_LONG	Nl, Nh;
+	unsigned char		data[GOST2814789IMIT_CBLOCK];
+	unsigned int		num;
+
+	GOST2814789_KEY		cipher;
+	unsigned char		mac[GOST2814789IMIT_CBLOCK];
+} GOST2814789IMIT_CTX;
+
+/* Note, also removed second parameter and removed dctx->cipher setting */
+int GOST2814789IMIT_Init(GOST2814789IMIT_CTX *c, int nid);
+int GOST2814789IMIT_Update(GOST2814789IMIT_CTX *c, const void *data, size_t len);
+int GOST2814789IMIT_Final(unsigned char *md, GOST2814789IMIT_CTX *c);
+void GOST2814789IMIT_Transform(GOST2814789IMIT_CTX *c, const unsigned char *data);
+unsigned char *GOST2814789IMIT(const unsigned char *d, size_t n,
+		unsigned char *md, int nid,
+		const unsigned char *key, const unsigned char *iv);
+
+#define GOSTR341194_LONG unsigned int
+
+#define GOSTR341194_LENGTH	32
+#define GOSTR341194_CBLOCK	32
+#define GOSTR341194_LBLOCK	(GOSTR341194_CBLOCK/4)
+
+typedef struct GOSTR341194state_st {
+	GOSTR341194_LONG	Nl, Nh;
+	GOSTR341194_LONG	data[GOSTR341194_LBLOCK];
+	unsigned int		num;
+
+	GOST2814789_KEY		cipher;
+	unsigned char		H[GOSTR341194_CBLOCK];
+	unsigned char		S[GOSTR341194_CBLOCK];
+} GOSTR341194_CTX;
+
+/* Note, also removed second parameter and removed dctx->cipher setting */
+int GOSTR341194_Init(GOSTR341194_CTX *c, int nid);
+int GOSTR341194_Update(GOSTR341194_CTX *c, const void *data, size_t len);
+int GOSTR341194_Final(unsigned char *md, GOSTR341194_CTX *c);
+void GOSTR341194_Transform(GOSTR341194_CTX *c, const unsigned char *data);
+unsigned char *GOSTR341194(const unsigned char *d, size_t n,unsigned char *md, int nid);
+
+#if defined(_LP64)
+#define STREEBOG_LONG64 unsigned long
+#define U64(C)     C##UL
+#else
+#define STREEBOG_LONG64 unsigned long long
+#define U64(C)     C##ULL
+#endif
+
+#define STREEBOG_LBLOCK 8
+#define STREEBOG_CBLOCK 64
+#define STREEBOG256_LENGTH 32
+#define STREEBOG512_LENGTH 64
+
+typedef struct STREEBOGstate_st {
+	STREEBOG_LONG64	data[STREEBOG_LBLOCK];
+	unsigned int	num;
+	unsigned int	md_len;
+	STREEBOG_LONG64	h[STREEBOG_LBLOCK];
+	STREEBOG_LONG64 N[STREEBOG_LBLOCK];
+	STREEBOG_LONG64 Sigma[STREEBOG_LBLOCK];
+} STREEBOG_CTX;
+
+int STREEBOG256_Init(STREEBOG_CTX *c);
+int STREEBOG256_Update(STREEBOG_CTX *c, const void *data, size_t len);
+int STREEBOG256_Final(unsigned char *md, STREEBOG_CTX *c);
+void STREEBOG256_Transform(STREEBOG_CTX *c, const unsigned char *data);
+unsigned char *STREEBOG256(const unsigned char *d, size_t n,unsigned char *md);
+
+int STREEBOG512_Init(STREEBOG_CTX *c);
+int STREEBOG512_Update(STREEBOG_CTX *c, const void *data, size_t len);
+int STREEBOG512_Final(unsigned char *md, STREEBOG_CTX *c);
+void STREEBOG512_Transform(STREEBOG_CTX *c, const unsigned char *data);
+unsigned char *STREEBOG512(const unsigned char *d, size_t n,unsigned char *md);
+
+typedef struct gost_key_st GOST_KEY;
+GOST_KEY *GOST_KEY_new(void);
+void GOST_KEY_free(GOST_KEY * r);
+int GOST_KEY_check_key(const GOST_KEY * eckey);
+int GOST_KEY_set_public_key_affine_coordinates(GOST_KEY * key, BIGNUM * x, BIGNUM * y);
+const EC_GROUP * GOST_KEY_get0_group(const GOST_KEY * key);
+int GOST_KEY_set_group(GOST_KEY * key, const EC_GROUP * group);
+int GOST_KEY_get_digest(const GOST_KEY * key);
+int GOST_KEY_set_digest(GOST_KEY * key, int digest_nid);
+const BIGNUM * GOST_KEY_get0_private_key(const GOST_KEY * key);
+int GOST_KEY_set_private_key(GOST_KEY * key, const BIGNUM * priv_key);
+const EC_POINT * GOST_KEY_get0_public_key(const GOST_KEY * key);
+int GOST_KEY_set_public_key(GOST_KEY * key, const EC_POINT * pub_key);
+size_t GOST_KEY_get_size(const GOST_KEY * r);
+
+/* Gost-specific pmeth control-function parameters */
+/* For GOST R34.10 parameters */
+#define EVP_PKEY_CTRL_GOST_PARAMSET	(EVP_PKEY_ALG_CTRL+1)
+#define EVP_PKEY_CTRL_GOST_SIG_FORMAT	(EVP_PKEY_ALG_CTRL+2)
+#define EVP_PKEY_CTRL_GOST_SET_DIGEST	(EVP_PKEY_ALG_CTRL+3)
+#define EVP_PKEY_CTRL_GOST_GET_DIGEST	(EVP_PKEY_ALG_CTRL+4)
+
+#define GOST_SIG_FORMAT_SR_BE	0
+#define GOST_SIG_FORMAT_RS_LE	1
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_GOST_strings(void);
+
+/* Error codes for the GOST functions. */
+
+/* Function codes. */
+#define GOST_F_DECODE_GOST01_ALGOR_PARAMS		 104
+#define GOST_F_ENCODE_GOST01_ALGOR_PARAMS		 105
+#define GOST_F_GOST2001_COMPUTE_PUBLIC			 106
+#define GOST_F_GOST2001_DO_SIGN				 107
+#define GOST_F_GOST2001_DO_VERIFY			 108
+#define GOST_F_GOST2001_KEYGEN				 109
+#define GOST_F_GOST89_GET_ASN1_PARAMETERS		 102
+#define GOST_F_GOST89_SET_ASN1_PARAMETERS		 103
+#define GOST_F_GOST_KEY_CHECK_KEY			 124
+#define GOST_F_GOST_KEY_NEW				 125
+#define GOST_F_GOST_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES 126
+#define GOST_F_PARAM_COPY_GOST01			 110
+#define GOST_F_PARAM_DECODE_GOST01			 111
+#define GOST_F_PKEY_GOST01_CTRL				 116
+#define GOST_F_PKEY_GOST01_DECRYPT			 112
+#define GOST_F_PKEY_GOST01_DERIVE			 113
+#define GOST_F_PKEY_GOST01_ENCRYPT			 114
+#define GOST_F_PKEY_GOST01_PARAMGEN			 115
+#define GOST_F_PKEY_GOST01_SIGN				 123
+#define GOST_F_PKEY_GOST_MAC_CTRL			 100
+#define GOST_F_PKEY_GOST_MAC_KEYGEN			 101
+#define GOST_F_PRIV_DECODE_GOST01			 117
+#define GOST_F_PUB_DECODE_GOST01			 118
+#define GOST_F_PUB_ENCODE_GOST01			 119
+#define GOST_F_PUB_PRINT_GOST01				 120
+#define GOST_F_UNPACK_SIGNATURE_CP			 121
+#define GOST_F_UNPACK_SIGNATURE_LE			 122
+
+/* Reason codes. */
+#define GOST_R_BAD_KEY_PARAMETERS_FORMAT		 104
+#define GOST_R_BAD_PKEY_PARAMETERS_FORMAT		 105
+#define GOST_R_CANNOT_PACK_EPHEMERAL_KEY		 106
+#define GOST_R_CTRL_CALL_FAILED				 107
+#define GOST_R_ERROR_COMPUTING_SHARED_KEY		 108
+#define GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO		 109
+#define GOST_R_INCOMPATIBLE_ALGORITHMS			 110
+#define GOST_R_INCOMPATIBLE_PEER_KEY			 111
+#define GOST_R_INVALID_DIGEST_TYPE			 100
+#define GOST_R_INVALID_IV_LENGTH			 103
+#define GOST_R_INVALID_MAC_KEY_LENGTH			 101
+#define GOST_R_KEY_IS_NOT_INITIALIZED			 112
+#define GOST_R_KEY_PARAMETERS_MISSING			 113
+#define GOST_R_MAC_KEY_NOT_SET				 102
+#define GOST_R_NO_PARAMETERS_SET			 115
+#define GOST_R_NO_PEER_KEY				 116
+#define GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR	 117
+#define GOST_R_PUBLIC_KEY_UNDEFINED			 118
+#define GOST_R_RANDOM_NUMBER_GENERATOR_FAILED		 120
+#define GOST_R_SIGNATURE_MISMATCH			 121
+#define GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q		 122
+#define GOST_R_UKM_NOT_SET				 123
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/crypto/libressl/crypto/gost/gost2814789.c b/crypto/libressl/crypto/gost/gost2814789.c
new file mode 100644
index 0000000000..259478e9f8
--- /dev/null
+++ b/crypto/libressl/crypto/gost/gost2814789.c
@@ -0,0 +1,471 @@
+/* $OpenBSD: gost2814789.c,v 1.4 2015/02/10 09:46:30 miod Exp $ */
+/*
+ * Copyright (c) 2014 Dmitry Eremin-Solenikov 
+ * Copyright (c) 2005-2006 Cryptocom LTD
+ *
+ * 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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_GOST
+#include 
+#include 
+
+#include "gost_locl.h"
+
+static inline unsigned int
+f(const GOST2814789_KEY *c, unsigned int x)
+{
+	return  c->k87[(x>>24) & 255] | c->k65[(x>>16) & 255]|
+		c->k43[(x>> 8) & 255] | c->k21[(x    ) & 255];
+}
+
+void
+Gost2814789_encrypt(const unsigned char *in, unsigned char *out,
+    const GOST2814789_KEY *key)
+{
+	unsigned int n1, n2; /* As named in the GOST */
+
+	c2l(in, n1);
+	c2l(in, n2);
+
+	/* Instead of swapping halves, swap names each round */
+	n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]);
+	n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]);
+	n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]);
+	n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]);
+
+	n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]);
+	n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]);
+	n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]);
+	n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]);
+
+	n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]);
+	n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]);
+	n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]);
+	n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]);
+
+	n2 ^= f(key, n1 + key->key[7]); n1 ^= f(key, n2 + key->key[6]);
+	n2 ^= f(key, n1 + key->key[5]); n1 ^= f(key, n2 + key->key[4]);
+	n2 ^= f(key, n1 + key->key[3]); n1 ^= f(key, n2 + key->key[2]);
+	n2 ^= f(key, n1 + key->key[1]); n1 ^= f(key, n2 + key->key[0]);
+
+	l2c(n2, out);
+	l2c(n1, out);
+}
+
+void
+Gost2814789_decrypt(const unsigned char *in, unsigned char *out,
+    const GOST2814789_KEY *key)
+{
+	unsigned int n1, n2; /* As named in the GOST */
+
+	c2l(in, n1);
+	c2l(in, n2);
+
+	/* Instead of swapping halves, swap names each round */
+	n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]);
+	n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]);
+	n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]);
+	n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]);
+
+	n2 ^= f(key, n1 + key->key[7]); n1 ^= f(key, n2 + key->key[6]);
+	n2 ^= f(key, n1 + key->key[5]); n1 ^= f(key, n2 + key->key[4]);
+	n2 ^= f(key, n1 + key->key[3]); n1 ^= f(key, n2 + key->key[2]);
+	n2 ^= f(key, n1 + key->key[1]); n1 ^= f(key, n2 + key->key[0]);
+
+	n2 ^= f(key, n1 + key->key[7]); n1 ^= f(key, n2 + key->key[6]);
+	n2 ^= f(key, n1 + key->key[5]); n1 ^= f(key, n2 + key->key[4]);
+	n2 ^= f(key, n1 + key->key[3]); n1 ^= f(key, n2 + key->key[2]);
+	n2 ^= f(key, n1 + key->key[1]); n1 ^= f(key, n2 + key->key[0]);
+
+	n2 ^= f(key, n1 + key->key[7]); n1 ^= f(key, n2 + key->key[6]);
+	n2 ^= f(key, n1 + key->key[5]); n1 ^= f(key, n2 + key->key[4]);
+	n2 ^= f(key, n1 + key->key[3]); n1 ^= f(key, n2 + key->key[2]);
+	n2 ^= f(key, n1 + key->key[1]); n1 ^= f(key, n2 + key->key[0]);
+
+	l2c(n2, out);
+	l2c(n1, out);
+}
+
+static void
+Gost2814789_mac(const unsigned char *in, unsigned char *mac,
+    GOST2814789_KEY *key)
+{
+	unsigned int n1, n2; /* As named in the GOST */
+	unsigned char *p;
+	int i;
+
+	for (i = 0; i < 8; i++)
+		mac[i] ^= in[i];
+
+	p = mac;
+	c2l(p, n1);
+	c2l(p, n2);
+
+	/* Instead of swapping halves, swap names each round */
+	n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]);
+	n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]);
+	n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]);
+	n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]);
+
+	n2 ^= f(key, n1 + key->key[0]); n1 ^= f(key, n2 + key->key[1]);
+	n2 ^= f(key, n1 + key->key[2]); n1 ^= f(key, n2 + key->key[3]);
+	n2 ^= f(key, n1 + key->key[4]); n1 ^= f(key, n2 + key->key[5]);
+	n2 ^= f(key, n1 + key->key[6]); n1 ^= f(key, n2 + key->key[7]);
+
+	p = mac;
+	l2c(n1, p);
+	l2c(n2, p);
+}
+
+void
+Gost2814789_ecb_encrypt(const unsigned char *in, unsigned char *out,
+    GOST2814789_KEY *key, const int enc)
+{
+	if (key->key_meshing && key->count == 1024) {
+		Gost2814789_cryptopro_key_mesh(key);
+		key->count = 0;
+	}
+
+	if (enc)
+		Gost2814789_encrypt(in, out, key);
+	else
+		Gost2814789_decrypt(in, out, key);
+}
+
+static inline void
+Gost2814789_encrypt_mesh(unsigned char *iv, GOST2814789_KEY *key)
+{
+	if (key->key_meshing && key->count == 1024) {
+		Gost2814789_cryptopro_key_mesh(key);
+		Gost2814789_encrypt(iv, iv, key);
+		key->count = 0;
+	}
+	Gost2814789_encrypt(iv, iv, key);
+	key->count += 8;
+}
+
+static inline void
+Gost2814789_mac_mesh(const unsigned char *data, unsigned char *mac,
+    GOST2814789_KEY *key)
+{
+	if (key->key_meshing && key->count == 1024) {
+		Gost2814789_cryptopro_key_mesh(key);
+		key->count = 0;
+	}
+	Gost2814789_mac(data, mac, key);
+	key->count += 8;
+}
+
+void
+Gost2814789_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+    size_t len, GOST2814789_KEY *key, unsigned char *ivec, int *num,
+    const int enc)
+{
+	unsigned int n;
+	size_t l = 0;
+
+	n = *num;
+
+	if (enc) {
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+		if (8 % sizeof(size_t) == 0) do { /* always true actually */
+			while (n && len) {
+				*(out++) = ivec[n] ^= *(in++);
+				--len;
+				n = (n + 1) % 8;
+			}
+#ifdef __STRICT_ALIGNMENT
+			if (((size_t)in | (size_t)out | (size_t)ivec) %
+			    sizeof(size_t) != 0)
+				break;
+#endif
+			while (len >= 8) {
+				Gost2814789_encrypt_mesh(ivec, key);
+				for (; n < 8; n += sizeof(size_t)) {
+					*(size_t*)(out + n) =
+					*(size_t*)(ivec + n) ^=
+					    *(size_t*)(in + n);
+				}
+				len -= 8;
+				out += 8;
+				in  += 8;
+				n = 0;
+			}
+			if (len) {
+				Gost2814789_encrypt_mesh(ivec, key);
+				while (len--) {
+					out[n] = ivec[n] ^= in[n];
+					++n;
+				}
+			}
+			*num = n;
+			return;
+		} while (0);
+		/* the rest would be commonly eliminated by x86* compiler */
+#endif
+		while (l= 8) {
+				Gost2814789_encrypt_mesh(ivec, key);
+				for (; n < 8; n += sizeof(size_t)) {
+					size_t t = *(size_t*)(in + n);
+					*(size_t*)(out + n) =
+					    *(size_t*)(ivec + n) ^ t;
+					*(size_t*)(ivec + n) = t;
+				}
+				len -= 8;
+				out += 8;
+				in  += 8;
+				n = 0;
+			}
+			if (len) {
+				Gost2814789_encrypt_mesh(ivec, key);
+				while (len--) {
+					unsigned char c;
+
+					out[n] = ivec[n] ^ (c = in[n]);
+					ivec[n] = c;
+					++n;
+				}
+ 			}
+			*num = n;
+			return;
+		} while (0);
+		/* the rest would be commonly eliminated by x86* compiler */
+#endif
+		while (l < len) {
+			unsigned char c;
+
+			if (n == 0) {
+				Gost2814789_encrypt_mesh(ivec, key);
+			}
+			out[l] = ivec[n] ^ (c = in[l]); ivec[n] = c;
+			++l;
+			n = (n + 1) % 8;
+		}
+		*num = n;
+	}
+}
+
+static inline void
+Gost2814789_cnt_next(unsigned char *ivec, unsigned char *out,
+    GOST2814789_KEY *key)
+{
+	unsigned char *p = ivec, *p2 = ivec;
+	unsigned int val, val2;
+
+	if (key->count == 0)
+		Gost2814789_encrypt(ivec, ivec, key);
+
+	if (key->key_meshing && key->count == 1024) {
+		Gost2814789_cryptopro_key_mesh(key);
+		Gost2814789_encrypt(ivec, ivec, key);
+		key->count = 0;
+	}
+
+	c2l(p, val);
+	val2 = val + 0x01010101;
+	l2c(val2, p2);
+
+	c2l(p, val);
+	val2 = val + 0x01010104;
+	if (val > val2) /* overflow */
+		val2++;
+	l2c(val2, p2);
+
+	Gost2814789_encrypt(ivec, out, key);
+	key->count += 8;
+}
+
+void
+Gost2814789_cnt_encrypt(const unsigned char *in, unsigned char *out, size_t len,
+    GOST2814789_KEY *key, unsigned char *ivec, unsigned char *cnt_buf, int *num)
+{
+	unsigned int n;
+	size_t l = 0;
+
+	n = *num;
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	if (8 % sizeof(size_t) == 0) do { /* always true actually */
+		while (n && len) {
+			*(out++) = *(in++) ^ cnt_buf[n];
+			--len;
+			n = (n + 1) % 8;
+		}
+
+#ifdef __STRICT_ALIGNMENT
+		if (((size_t)in | (size_t)out | (size_t)ivec) %
+		    sizeof(size_t) != 0)
+			break;
+#endif
+		while (len >= 8) {
+			Gost2814789_cnt_next(ivec, cnt_buf, key);
+			for (; n < 8; n += sizeof(size_t))
+				*(size_t *)(out + n) = *(size_t *)(in + n) ^
+				    *(size_t *)(cnt_buf + n);
+			len -= 8;
+			out += 8;
+			in  += 8;
+			n = 0;
+		}
+		if (len) {
+			Gost2814789_cnt_next(ivec, cnt_buf, key);
+			while (len--) {
+				out[n] = in[n] ^ cnt_buf[n];
+				++n;
+			}
+		}
+		*num = n;
+		return;
+	} while(0);
+	/* the rest would be commonly eliminated by x86* compiler */
+#endif
+	while (l < len) {
+		if (n==0)
+			Gost2814789_cnt_next(ivec, cnt_buf, key);
+		out[l] = in[l] ^ cnt_buf[n];
+		++l;
+		n = (n + 1) % 8;
+	}
+
+	*num=n;
+}
+
+int
+GOST2814789IMIT_Init(GOST2814789IMIT_CTX *c, int nid)
+{
+	c->Nl = c->Nh = c->num = 0;
+	memset(c->mac, 0, 8);
+	return Gost2814789_set_sbox(&c->cipher, nid);
+}
+
+static void
+GOST2814789IMIT_block_data_order(GOST2814789IMIT_CTX *ctx,
+    const unsigned char *p, size_t num)
+{
+	int i;
+
+	for (i = 0; i < num; i++) {
+		Gost2814789_mac_mesh(p, ctx->mac, &ctx->cipher);
+		p += 8;
+	}
+}
+
+#define DATA_ORDER_IS_LITTLE_ENDIAN
+
+#define HASH_CBLOCK	GOST2814789IMIT_CBLOCK
+#define HASH_LONG	GOST2814789IMIT_LONG
+#define HASH_CTX	GOST2814789IMIT_CTX
+#define HASH_UPDATE	GOST2814789IMIT_Update
+#define HASH_TRANSFORM	GOST2814789IMIT_Transform
+#define HASH_NO_FINAL	1
+#define HASH_BLOCK_DATA_ORDER	GOST2814789IMIT_block_data_order
+
+#include "md32_common.h"
+
+int
+GOST2814789IMIT_Final(unsigned char *md, GOST2814789IMIT_CTX *c)
+{
+	if (c->num) {
+		memset(c->data + c->num, 0, 8 - c->num);
+		Gost2814789_mac_mesh(c->data, c->mac, &c->cipher);
+	}
+	if (c->Nl <= 8 * 8 && c->Nl > 0 && c->Nh == 0) {
+		memset(c->data, 0, 8);
+		Gost2814789_mac_mesh(c->data, c->mac, &c->cipher);
+	}
+	memcpy(md, c->mac, 4);
+	return 1;
+}
+
+unsigned char *
+GOST2814789IMIT(const unsigned char *d, size_t n, unsigned char *md, int nid,
+    const unsigned char *key, const unsigned char *iv)
+{
+	GOST2814789IMIT_CTX c;
+	static unsigned char m[GOST2814789IMIT_LENGTH];
+
+	if (md == NULL)
+		md = m;
+	GOST2814789IMIT_Init(&c, nid);
+	memcpy(c.mac, iv, 8);
+	Gost2814789_set_key(&c.cipher, key, 256);
+	GOST2814789IMIT_Update(&c, d, n);
+	GOST2814789IMIT_Final(md, &c);
+	explicit_bzero(&c, sizeof(c));
+	return (md);
+}
+
+#endif
diff --git a/crypto/libressl/crypto/gost/gost89_keywrap.c b/crypto/libressl/crypto/gost/gost89_keywrap.c
new file mode 100644
index 0000000000..043807e832
--- /dev/null
+++ b/crypto/libressl/crypto/gost/gost89_keywrap.c
@@ -0,0 +1,138 @@
+/* $OpenBSD: gost89_keywrap.c,v 1.2 2014/11/09 19:27:29 miod Exp $ */
+/*
+ * Copyright (c) 2014 Dmitry Eremin-Solenikov 
+ * Copyright (c) 2005-2006 Cryptocom LTD
+ *
+ * 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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_GOST
+
+#include 
+
+#include "gost_locl.h"
+
+static void
+key_diversify_crypto_pro(GOST2814789_KEY *ctx, const unsigned char *inputKey,
+    const unsigned char *ukm, unsigned char *outputKey)
+{
+	unsigned long k, s1, s2;
+	int i, mask;
+	unsigned char S[8];
+	unsigned char *p;
+
+	memcpy(outputKey, inputKey, 32);
+	for (i = 0; i < 8; i++) {
+		/* Make array of integers from key */
+		/* Compute IV S */
+		s1 = 0, s2 = 0;
+		p = outputKey;
+		for (mask = 1; mask < 256; mask <<= 1) {
+			c2l(p, k);
+			if (mask & ukm[i]) {
+				s1 += k;
+			} else {
+				s2 += k;
+			}
+		}
+		p = S;
+		l2c (s1, p);
+		l2c (s2, p);
+		Gost2814789_set_key(ctx, outputKey, 256);
+		mask = 0;
+		Gost2814789_cfb64_encrypt(outputKey, outputKey, 32, ctx, S,
+		    &mask, 1);
+	}
+}
+
+int
+gost_key_wrap_crypto_pro(int nid, const unsigned char *keyExchangeKey,
+    const unsigned char *ukm, const unsigned char *sessionKey,
+    unsigned char *wrappedKey)
+{
+	GOST2814789_KEY ctx;
+	unsigned char kek_ukm[32];
+
+	Gost2814789_set_sbox(&ctx, nid);
+	key_diversify_crypto_pro(&ctx, keyExchangeKey, ukm, kek_ukm);
+	Gost2814789_set_key(&ctx, kek_ukm, 256);
+	memcpy(wrappedKey, ukm, 8);
+	Gost2814789_encrypt(sessionKey +  0, wrappedKey + 8 +  0, &ctx);
+	Gost2814789_encrypt(sessionKey +  8, wrappedKey + 8 +  8, &ctx);
+	Gost2814789_encrypt(sessionKey + 16, wrappedKey + 8 + 16, &ctx);
+	Gost2814789_encrypt(sessionKey + 24, wrappedKey + 8 + 24, &ctx);
+	GOST2814789IMIT(sessionKey, 32, wrappedKey + 40, nid, kek_ukm, ukm);
+	return 1;
+}
+
+int
+gost_key_unwrap_crypto_pro(int nid, const unsigned char *keyExchangeKey,
+    const unsigned char *wrappedKey, unsigned char *sessionKey)
+{
+	unsigned char kek_ukm[32], cek_mac[4];
+	GOST2814789_KEY ctx;
+
+	Gost2814789_set_sbox(&ctx, nid);
+	/* First 8 bytes of wrapped Key is ukm */
+	key_diversify_crypto_pro(&ctx, keyExchangeKey, wrappedKey, kek_ukm);
+	Gost2814789_set_key(&ctx, kek_ukm, 256);
+	Gost2814789_decrypt(wrappedKey + 8 +  0, sessionKey +  0, &ctx);
+	Gost2814789_decrypt(wrappedKey + 8 +  8, sessionKey +  8, &ctx);
+	Gost2814789_decrypt(wrappedKey + 8 + 16, sessionKey + 16, &ctx);
+	Gost2814789_decrypt(wrappedKey + 8 + 24, sessionKey + 24, &ctx);
+
+	GOST2814789IMIT(sessionKey, 32, cek_mac, nid, kek_ukm, wrappedKey);
+	if (memcmp(cek_mac, wrappedKey + 40, 4))
+		return 0;
+
+	return 1;
+}
+
+#endif
diff --git a/crypto/libressl/crypto/gost/gost89_params.c b/crypto/libressl/crypto/gost/gost89_params.c
new file mode 100644
index 0000000000..1bd70f7891
--- /dev/null
+++ b/crypto/libressl/crypto/gost/gost89_params.c
@@ -0,0 +1,244 @@
+/* $OpenBSD: gost89_params.c,v 1.1 2014/11/09 19:17:13 miod Exp $ */
+/*
+ * Copyright (c) 2014 Dmitry Eremin-Solenikov 
+ * Copyright (c) 2005-2006 Cryptocom LTD
+ *
+ * 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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_GOST
+#include 
+#include 
+
+#include "gost_locl.h"
+
+/* Substitution blocks from test examples for GOST R 34.11-94*/
+static const gost_subst_block GostR3411_94_TestParamSet = {
+	{0x1,0xF,0xD,0x0,0x5,0x7,0xA,0x4,0x9,0x2,0x3,0xE,0x6,0xB,0x8,0xC},
+	{0xD,0xB,0x4,0x1,0x3,0xF,0x5,0x9,0x0,0xA,0xE,0x7,0x6,0x8,0x2,0xC},
+	{0x4,0xB,0xA,0x0,0x7,0x2,0x1,0xD,0x3,0x6,0x8,0x5,0x9,0xC,0xF,0xE},
+	{0x6,0xC,0x7,0x1,0x5,0xF,0xD,0x8,0x4,0xA,0x9,0xE,0x0,0x3,0xB,0x2},
+	{0x7,0xD,0xA,0x1,0x0,0x8,0x9,0xF,0xE,0x4,0x6,0xC,0xB,0x2,0x5,0x3},
+	{0x5,0x8,0x1,0xD,0xA,0x3,0x4,0x2,0xE,0xF,0xC,0x7,0x6,0x0,0x9,0xB},
+	{0xE,0xB,0x4,0xC,0x6,0xD,0xF,0xA,0x2,0x3,0x8,0x1,0x0,0x7,0x5,0x9},
+	{0x4,0xA,0x9,0x2,0xD,0x8,0x0,0xE,0x6,0xB,0x1,0xC,0x7,0xF,0x5,0x3}
+};
+
+/* Substitution blocks for hash function 1.2.643.2.9.1.6.1  */
+static const gost_subst_block GostR3411_94_CryptoProParamSet = {
+	{0x1,0x3,0xA,0x9,0x5,0xB,0x4,0xF,0x8,0x6,0x7,0xE,0xD,0x0,0x2,0xC},
+	{0xD,0xE,0x4,0x1,0x7,0x0,0x5,0xA,0x3,0xC,0x8,0xF,0x6,0x2,0x9,0xB},
+	{0x7,0x6,0x2,0x4,0xD,0x9,0xF,0x0,0xA,0x1,0x5,0xB,0x8,0xE,0xC,0x3},
+	{0x7,0x6,0x4,0xB,0x9,0xC,0x2,0xA,0x1,0x8,0x0,0xE,0xF,0xD,0x3,0x5},
+	{0x4,0xA,0x7,0xC,0x0,0xF,0x2,0x8,0xE,0x1,0x6,0x5,0xD,0xB,0x9,0x3},
+	{0x7,0xF,0xC,0xE,0x9,0x4,0x1,0x0,0x3,0xB,0x5,0x2,0x6,0xA,0x8,0xD},
+	{0x5,0xF,0x4,0x0,0x2,0xD,0xB,0x9,0x1,0x7,0x6,0x3,0xC,0xE,0xA,0x8},
+	{0xA,0x4,0x5,0x6,0x8,0x1,0x3,0x7,0xD,0xC,0xE,0x0,0x9,0x2,0xB,0xF}
+};
+
+/* Test paramset from GOST 28147 */
+gost_subst_block Gost28147_TestParamSet = {
+	{0xC,0x6,0x5,0x2,0xB,0x0,0x9,0xD,0x3,0xE,0x7,0xA,0xF,0x4,0x1,0x8},
+	{0x9,0xB,0xC,0x0,0x3,0x6,0x7,0x5,0x4,0x8,0xE,0xF,0x1,0xA,0x2,0xD},
+	{0x8,0xF,0x6,0xB,0x1,0x9,0xC,0x5,0xD,0x3,0x7,0xA,0x0,0xE,0x2,0x4},
+	{0x3,0xE,0x5,0x9,0x6,0x8,0x0,0xD,0xA,0xB,0x7,0xC,0x2,0x1,0xF,0x4},
+	{0xE,0x9,0xB,0x2,0x5,0xF,0x7,0x1,0x0,0xD,0xC,0x6,0xA,0x4,0x3,0x8},
+	{0xD,0x8,0xE,0xC,0x7,0x3,0x9,0xA,0x1,0x5,0x2,0x4,0x6,0xF,0x0,0xB},
+	{0xC,0x9,0xF,0xE,0x8,0x1,0x3,0xA,0x2,0x7,0x4,0xD,0x6,0x0,0xB,0x5},
+	{0x4,0x2,0xF,0x5,0x9,0x1,0x0,0x8,0xE,0x3,0xB,0xC,0xD,0x7,0xA,0x6}
+};
+
+
+/* 1.2.643.2.2.31.1 */
+static const gost_subst_block Gost28147_CryptoProParamSetA = {
+	{0xB,0xA,0xF,0x5,0x0,0xC,0xE,0x8,0x6,0x2,0x3,0x9,0x1,0x7,0xD,0x4},
+	{0x1,0xD,0x2,0x9,0x7,0xA,0x6,0x0,0x8,0xC,0x4,0x5,0xF,0x3,0xB,0xE},
+	{0x3,0xA,0xD,0xC,0x1,0x2,0x0,0xB,0x7,0x5,0x9,0x4,0x8,0xF,0xE,0x6},
+	{0xB,0x5,0x1,0x9,0x8,0xD,0xF,0x0,0xE,0x4,0x2,0x3,0xC,0x7,0xA,0x6},
+	{0xE,0x7,0xA,0xC,0xD,0x1,0x3,0x9,0x0,0x2,0xB,0x4,0xF,0x8,0x5,0x6},
+	{0xE,0x4,0x6,0x2,0xB,0x3,0xD,0x8,0xC,0xF,0x5,0xA,0x0,0x7,0x1,0x9},
+	{0x3,0x7,0xE,0x9,0x8,0xA,0xF,0x0,0x5,0x2,0x6,0xC,0xB,0x4,0xD,0x1},
+	{0x9,0x6,0x3,0x2,0x8,0xB,0x1,0x7,0xA,0x4,0xE,0xF,0xC,0x0,0xD,0x5}
+};
+
+/* 1.2.643.2.2.31.2 */
+static const gost_subst_block Gost28147_CryptoProParamSetB = {
+	{0x0,0x4,0xB,0xE,0x8,0x3,0x7,0x1,0xA,0x2,0x9,0x6,0xF,0xD,0x5,0xC},
+	{0x5,0x2,0xA,0xB,0x9,0x1,0xC,0x3,0x7,0x4,0xD,0x0,0x6,0xF,0x8,0xE},
+	{0x8,0x3,0x2,0x6,0x4,0xD,0xE,0xB,0xC,0x1,0x7,0xF,0xA,0x0,0x9,0x5},
+	{0x2,0x7,0xC,0xF,0x9,0x5,0xA,0xB,0x1,0x4,0x0,0xD,0x6,0x8,0xE,0x3},
+	{0x7,0x5,0x0,0xD,0xB,0x6,0x1,0x2,0x3,0xA,0xC,0xF,0x4,0xE,0x9,0x8},
+	{0xE,0xC,0x0,0xA,0x9,0x2,0xD,0xB,0x7,0x5,0x8,0xF,0x3,0x6,0x1,0x4},
+	{0x0,0x1,0x2,0xA,0x4,0xD,0x5,0xC,0x9,0x7,0x3,0xF,0xB,0x8,0x6,0xE},
+	{0x8,0x4,0xB,0x1,0x3,0x5,0x0,0x9,0x2,0xE,0xA,0xC,0xD,0x6,0x7,0xF}
+};
+
+/* 1.2.643.2.2.31.3 */
+static const gost_subst_block Gost28147_CryptoProParamSetC = {
+	{0x7,0x4,0x0,0x5,0xA,0x2,0xF,0xE,0xC,0x6,0x1,0xB,0xD,0x9,0x3,0x8},
+	{0xA,0x9,0x6,0x8,0xD,0xE,0x2,0x0,0xF,0x3,0x5,0xB,0x4,0x1,0xC,0x7},
+	{0xC,0x9,0xB,0x1,0x8,0xE,0x2,0x4,0x7,0x3,0x6,0x5,0xA,0x0,0xF,0xD},
+	{0x8,0xD,0xB,0x0,0x4,0x5,0x1,0x2,0x9,0x3,0xC,0xE,0x6,0xF,0xA,0x7},
+	{0x3,0x6,0x0,0x1,0x5,0xD,0xA,0x8,0xB,0x2,0x9,0x7,0xE,0xF,0xC,0x4},
+	{0x8,0x2,0x5,0x0,0x4,0x9,0xF,0xA,0x3,0x7,0xC,0xD,0x6,0xE,0x1,0xB},
+	{0x0,0x1,0x7,0xD,0xB,0x4,0x5,0x2,0x8,0xE,0xF,0xC,0x9,0xA,0x6,0x3},
+	{0x1,0xB,0xC,0x2,0x9,0xD,0x0,0xF,0x4,0x5,0x8,0xE,0xA,0x7,0x6,0x3}
+};
+
+/* 1.2.643.2.2.31.4 */
+static const gost_subst_block Gost28147_CryptoProParamSetD = {
+	{0x1,0xA,0x6,0x8,0xF,0xB,0x0,0x4,0xC,0x3,0x5,0x9,0x7,0xD,0x2,0xE},
+	{0x3,0x0,0x6,0xF,0x1,0xE,0x9,0x2,0xD,0x8,0xC,0x4,0xB,0xA,0x5,0x7},
+	{0x8,0x0,0xF,0x3,0x2,0x5,0xE,0xB,0x1,0xA,0x4,0x7,0xC,0x9,0xD,0x6},
+	{0x0,0xC,0x8,0x9,0xD,0x2,0xA,0xB,0x7,0x3,0x6,0x5,0x4,0xE,0xF,0x1},
+	{0x1,0x5,0xE,0xC,0xA,0x7,0x0,0xD,0x6,0x2,0xB,0x4,0x9,0x3,0xF,0x8},
+	{0x1,0xC,0xB,0x0,0xF,0xE,0x6,0x5,0xA,0xD,0x4,0x8,0x9,0x3,0x7,0x2},
+	{0xB,0x6,0x3,0x4,0xC,0xF,0xE,0x2,0x7,0xD,0x8,0x0,0x5,0xA,0x9,0x1},
+	{0xF,0xC,0x2,0xA,0x6,0x4,0x5,0x0,0x7,0x9,0xE,0xD,0x1,0xB,0x8,0x3}
+};
+
+static const gost_subst_block Gost28147_TC26ParamSetZ = {
+	{0x1,0x7,0xe,0xd,0x0,0x5,0x8,0x3,0x4,0xf,0xa,0x6,0x9,0xc,0xb,0x2},
+	{0x8,0xe,0x2,0x5,0x6,0x9,0x1,0xc,0xf,0x4,0xb,0x0,0xd,0xa,0x3,0x7},
+	{0x5,0xd,0xf,0x6,0x9,0x2,0xc,0xa,0xb,0x7,0x8,0x1,0x4,0x3,0xe,0x0},
+	{0x7,0xf,0x5,0xa,0x8,0x1,0x6,0xd,0x0,0x9,0x3,0xe,0xb,0x4,0x2,0xc},
+	{0xc,0x8,0x2,0x1,0xd,0x4,0xf,0x6,0x7,0x0,0xa,0x5,0x3,0xe,0x9,0xb},
+	{0xb,0x3,0x5,0x8,0x2,0xf,0xa,0xd,0xe,0x1,0x7,0x4,0xc,0x9,0x6,0x0},
+	{0x6,0x8,0x2,0x3,0x9,0xa,0x5,0xc,0x1,0xe,0x4,0x7,0xb,0xd,0x0,0xf},
+	{0xc,0x4,0x6,0x2,0xa,0x5,0xb,0x9,0xe,0x8,0xd,0x7,0x0,0x3,0xf,0x1}
+};
+
+static const unsigned char CryptoProKeyMeshingKey[] = {
+	0x69, 0x00, 0x72, 0x22,   0x64, 0xC9, 0x04, 0x23,
+	0x8D, 0x3A, 0xDB, 0x96,   0x46, 0xE9, 0x2A, 0xC4,
+	0x18, 0xFE, 0xAC, 0x94,   0x00, 0xED, 0x07, 0x12,
+	0xC0, 0x86, 0xDC, 0xC2,   0xEF, 0x4C, 0xA9, 0x2B
+};
+
+static const struct gost89_parameters_info {
+	int nid;
+	const gost_subst_block *sblock;
+	int key_meshing;
+} gost_cipher_list[] =
+{
+	{NID_id_Gost28147_89_CryptoPro_A_ParamSet,&Gost28147_CryptoProParamSetA,1},
+	{NID_id_Gost28147_89_CryptoPro_B_ParamSet,&Gost28147_CryptoProParamSetB,1},
+	{NID_id_Gost28147_89_CryptoPro_C_ParamSet,&Gost28147_CryptoProParamSetC,1},
+	{NID_id_Gost28147_89_CryptoPro_D_ParamSet,&Gost28147_CryptoProParamSetD,1},
+	{NID_id_tc26_gost_28147_param_Z,&Gost28147_TC26ParamSetZ,1},
+	{NID_id_Gost28147_89_TestParamSet,&Gost28147_TestParamSet,0},
+	{NID_id_GostR3411_94_TestParamSet,&GostR3411_94_TestParamSet,0},
+	{NID_id_GostR3411_94_CryptoProParamSet,&GostR3411_94_CryptoProParamSet,0},
+	{NID_undef,NULL,0}
+};
+
+int
+Gost2814789_set_sbox(GOST2814789_KEY *key, int nid)
+{
+	int i;
+	const gost_subst_block *b = NULL;
+	unsigned int t;
+
+	for (i = 0; gost_cipher_list[i].nid != NID_undef; i++) {
+		if (gost_cipher_list[i].nid != nid)
+			continue;
+
+		b = gost_cipher_list[i].sblock;
+		key->key_meshing = gost_cipher_list[i].key_meshing;
+		break;
+	}
+
+	if (b == NULL)
+		return 0;
+
+	for (i = 0; i < 256; i++) {
+		t = (unsigned int)(b->k8[i >> 4] <<4 | b->k7 [i & 15]) << 24;
+		key->k87[i] = (t << 11) | (t >> 21);
+		t = (unsigned int)(b->k6[i >> 4] <<4 | b->k5 [i & 15]) << 16;
+		key->k65[i] = (t << 11) | (t >> 21);
+		t = (unsigned int)(b->k4[i >> 4] <<4 | b->k3 [i & 15]) << 8;
+		key->k43[i] = (t << 11) | (t >> 21);
+		t = (unsigned int)(b->k2[i >> 4] <<4 | b->k1 [i & 15]) << 0;
+		key->k21[i] = (t << 11) | (t >> 21);
+	}
+
+	return 1;
+}
+
+int
+Gost2814789_set_key(GOST2814789_KEY *key, const unsigned char *userKey,
+    const int bits)
+{
+	int i;
+
+	if (bits != 256)
+		return 0;
+
+	for (i = 0; i < 8; i++)
+		c2l(userKey, key->key[i]);
+
+	key->count = 0;
+
+	return 1;
+}
+
+void
+Gost2814789_cryptopro_key_mesh(GOST2814789_KEY *key)
+{
+	unsigned char newkey[32];
+
+	Gost2814789_decrypt(CryptoProKeyMeshingKey +  0, newkey +  0, key);
+	Gost2814789_decrypt(CryptoProKeyMeshingKey +  8, newkey +  8, key);
+	Gost2814789_decrypt(CryptoProKeyMeshingKey + 16, newkey + 16, key);
+	Gost2814789_decrypt(CryptoProKeyMeshingKey + 24, newkey + 24, key);
+
+	Gost2814789_set_key(key, newkey, 256);
+}
+#endif
diff --git a/crypto/libressl/crypto/gost/gost89imit_ameth.c b/crypto/libressl/crypto/gost/gost89imit_ameth.c
new file mode 100644
index 0000000000..1d2aa19c36
--- /dev/null
+++ b/crypto/libressl/crypto/gost/gost89imit_ameth.c
@@ -0,0 +1,88 @@
+/* $OpenBSD: gost89imit_ameth.c,v 1.1 2014/11/09 19:17:13 miod Exp $ */
+/*
+ * Copyright (c) 2014 Dmitry Eremin-Solenikov 
+ * Copyright (c) 2005-2006 Cryptocom LTD
+ *
+ * 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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include 
+
+#ifndef OPENSSL_NO_GOST
+#include 
+
+#include "asn1_locl.h"
+
+static void
+mackey_free_gost(EVP_PKEY *pk)
+{
+	free(pk->pkey.ptr);
+}
+
+static int
+mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+{
+	switch (op) {
+	case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+		*(int *)arg2 = NID_id_Gost28147_89_MAC;
+		return 2;
+	}
+	return -2;
+}
+
+const EVP_PKEY_ASN1_METHOD gostimit_asn1_meth = {
+	.pkey_id = EVP_PKEY_GOSTIMIT,
+	.pkey_base_id = EVP_PKEY_GOSTIMIT,
+	.pkey_flags = ASN1_PKEY_SIGPARAM_NULL,
+
+	.pem_str = "GOST-MAC",
+	.info = "GOST 28147-89 MAC",
+
+	.pkey_free = mackey_free_gost,
+	.pkey_ctrl = mac_ctrl_gost,
+};
+
+#endif
diff --git a/crypto/libressl/crypto/gost/gost89imit_pmeth.c b/crypto/libressl/crypto/gost/gost89imit_pmeth.c
new file mode 100644
index 0000000000..0486d96c9a
--- /dev/null
+++ b/crypto/libressl/crypto/gost/gost89imit_pmeth.c
@@ -0,0 +1,252 @@
+/* $OpenBSD: gost89imit_pmeth.c,v 1.2 2014/11/09 23:06:52 miod Exp $ */
+/*
+ * Copyright (c) 2014 Dmitry Eremin-Solenikov 
+ * Copyright (c) 2005-2006 Cryptocom LTD
+ *
+ * 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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_GOST
+#include 
+#include 
+#include 
+#include  /* For string_to_hex */
+
+#include "evp_locl.h"
+#include "gost_locl.h"
+
+struct gost_mac_pmeth_data {
+	EVP_MD *md;
+	unsigned char key[32];
+	unsigned key_set :1;
+};
+
+static int
+pkey_gost_mac_init(EVP_PKEY_CTX *ctx)
+{
+	struct gost_mac_pmeth_data *data;
+
+	data = calloc(1, sizeof(struct gost_mac_pmeth_data));
+	if (data == NULL)
+		return 0;
+	EVP_PKEY_CTX_set_data(ctx, data);
+	return 1;
+}
+
+static void
+pkey_gost_mac_cleanup(EVP_PKEY_CTX *ctx)
+{
+	struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
+	free(data);
+}
+
+static int
+pkey_gost_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+{
+	struct gost_mac_pmeth_data *dst_data, *src_data;
+
+	if (pkey_gost_mac_init(dst) == 0)
+		return 0;
+
+	src_data = EVP_PKEY_CTX_get_data(src);
+	dst_data = EVP_PKEY_CTX_get_data(dst);
+
+	*dst_data = *src_data;
+
+	return 1;
+}
+
+static int
+pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+	struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
+	unsigned char *keydata;
+
+	if (!data->key_set) {
+		GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN, GOST_R_MAC_KEY_NOT_SET);
+		return 0;
+	}
+
+	keydata = malloc(32);
+	if (keydata == NULL) {
+		GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	memcpy(keydata, data->key, 32);
+	EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata);
+
+	return 1;
+}
+
+static int
+pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+	struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
+
+	switch (type) {
+	case EVP_PKEY_CTRL_MD:
+		if (EVP_MD_type(p2) != NID_id_Gost28147_89_MAC) {
+			GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
+			    GOST_R_INVALID_DIGEST_TYPE);
+			return 0;
+		}
+		data->md = p2;
+		return 1;
+
+	case EVP_PKEY_CTRL_SET_MAC_KEY:
+		if (p1 != 32) {
+			GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
+			    GOST_R_INVALID_MAC_KEY_LENGTH);
+			return 0;
+		}
+
+		memcpy(data->key, p2, 32);
+		data->key_set = 1;
+		return 1;
+
+	case EVP_PKEY_CTRL_DIGESTINIT:
+	    {
+		EVP_MD_CTX *mctx = p2;
+		void *key;
+
+		if (!data->key_set) {
+			EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
+			if (pkey == NULL) {
+				GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
+				    GOST_R_MAC_KEY_NOT_SET);
+				return 0;
+			}
+			key = EVP_PKEY_get0(pkey);
+			if (key == NULL) {
+				GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
+				    GOST_R_MAC_KEY_NOT_SET);
+				return 0;
+			}
+		} else {
+			key = &(data->key);
+		}
+		if (mctx->digest->md_ctrl == NULL)
+			return 0;
+		return mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_SET_KEY, 32 * 8,
+		    key);
+	    }
+
+	}
+
+	return -2;
+}
+
+static int
+pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value)
+{
+	if (value == NULL)
+		return 0;
+	if (strcmp(type, "key") == 0) {
+		void *p = (void *)value;
+		return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
+		    strlen(value), p);
+	}
+	if (strcmp(type, "hexkey") == 0) {
+		unsigned char *key;
+		int r;
+		long keylen;
+
+		key = string_to_hex(value, &keylen);
+		if (key == NULL)
+			return 0;
+		r = pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen,
+		    key);
+		free(key);
+		return r;
+	}
+	return -2;
+}
+
+static int
+pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
+{
+	return 1;
+}
+
+static int
+pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+    EVP_MD_CTX *mctx)
+{
+	/* for platforms where sizeof(int) != sizeof(size_t)*/
+	unsigned int tmpsiglen = *siglen;
+	int ret;
+
+	if (sig == NULL) {
+		*siglen = 4;
+		return 1;
+	}
+
+	ret = EVP_DigestFinal_ex(mctx, sig, &tmpsiglen);
+	*siglen = tmpsiglen;
+	return ret;
+}
+
+const EVP_PKEY_METHOD gostimit_pkey_meth = {
+	.pkey_id = EVP_PKEY_GOSTIMIT,
+
+	.init = pkey_gost_mac_init,
+	.cleanup = pkey_gost_mac_cleanup,
+	.copy = pkey_gost_mac_copy,
+
+	.keygen = pkey_gost_mac_keygen,
+
+	.signctx_init = pkey_gost_mac_signctx_init,
+	.signctx = pkey_gost_mac_signctx,
+
+	.ctrl = pkey_gost_mac_ctrl,
+	.ctrl_str = pkey_gost_mac_ctrl_str,
+};
+
+#endif
diff --git a/crypto/libressl/crypto/gost/gost_asn1.c b/crypto/libressl/crypto/gost/gost_asn1.c
new file mode 100644
index 0000000000..2652162777
--- /dev/null
+++ b/crypto/libressl/crypto/gost/gost_asn1.c
@@ -0,0 +1,295 @@
+/**********************************************************************
+ *                          gost_keytrans.c                           *
+ *             Copyright (c) 2005-2006 Cryptocom LTD                  *
+ *         This file is distributed under the same license as OpenSSL *
+ *                                                                    *
+ *   ASN1 structure definition for GOST key transport                 *
+ *          Requires OpenSSL 0.9.9 for compilation                    *
+ **********************************************************************/
+
+#include 
+
+#ifndef OPENSSL_NO_GOST
+#include 
+#include 
+#include 
+
+#include "gost_locl.h"
+#include "gost_asn1.h"
+
+static const ASN1_TEMPLATE GOST_KEY_TRANSPORT_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(GOST_KEY_TRANSPORT, key_info),
+		.field_name = "key_info",
+		.item = &GOST_KEY_INFO_it,
+	},
+	{
+		.flags = ASN1_TFLG_IMPLICIT,
+		.tag = 0,
+		.offset = offsetof(GOST_KEY_TRANSPORT, key_agreement_info),
+		.field_name = "key_agreement_info",
+		.item = &GOST_KEY_AGREEMENT_INFO_it,
+	},
+};
+
+const ASN1_ITEM GOST_KEY_TRANSPORT_it = {
+	.itype = ASN1_ITYPE_NDEF_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = GOST_KEY_TRANSPORT_seq_tt,
+	.tcount = sizeof(GOST_KEY_TRANSPORT_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(GOST_KEY_TRANSPORT),
+	.sname = "GOST_KEY_TRANSPORT",
+};
+
+GOST_KEY_TRANSPORT *
+d2i_GOST_KEY_TRANSPORT(GOST_KEY_TRANSPORT **a, const unsigned char **in, long len)
+{
+	return (GOST_KEY_TRANSPORT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &GOST_KEY_TRANSPORT_it);
+}
+
+int
+i2d_GOST_KEY_TRANSPORT(GOST_KEY_TRANSPORT *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &GOST_KEY_TRANSPORT_it);
+}
+
+GOST_KEY_TRANSPORT *
+GOST_KEY_TRANSPORT_new(void)
+{
+	return (GOST_KEY_TRANSPORT *)ASN1_item_new(&GOST_KEY_TRANSPORT_it);
+}
+
+void
+GOST_KEY_TRANSPORT_free(GOST_KEY_TRANSPORT *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &GOST_KEY_TRANSPORT_it);
+}
+
+static const ASN1_TEMPLATE GOST_KEY_INFO_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(GOST_KEY_INFO, encrypted_key),
+		.field_name = "encrypted_key",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(GOST_KEY_INFO, imit),
+		.field_name = "imit",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+};
+
+const ASN1_ITEM GOST_KEY_INFO_it = {
+	.itype = ASN1_ITYPE_NDEF_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = GOST_KEY_INFO_seq_tt,
+	.tcount = sizeof(GOST_KEY_INFO_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(GOST_KEY_INFO),
+	.sname = "GOST_KEY_INFO",
+};
+
+GOST_KEY_INFO *
+d2i_GOST_KEY_INFO(GOST_KEY_INFO **a, const unsigned char **in, long len)
+{
+	return (GOST_KEY_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &GOST_KEY_INFO_it);
+}
+
+int
+i2d_GOST_KEY_INFO(GOST_KEY_INFO *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &GOST_KEY_INFO_it);
+}
+
+GOST_KEY_INFO *
+GOST_KEY_INFO_new(void)
+{
+	return (GOST_KEY_INFO *)ASN1_item_new(&GOST_KEY_INFO_it);
+}
+
+void
+GOST_KEY_INFO_free(GOST_KEY_INFO *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &GOST_KEY_INFO_it);
+}
+
+static const ASN1_TEMPLATE GOST_KEY_AGREEMENT_INFO_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(GOST_KEY_AGREEMENT_INFO, cipher),
+		.field_name = "cipher",
+		.item = &ASN1_OBJECT_it,
+	},
+	{
+		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(GOST_KEY_AGREEMENT_INFO, ephem_key),
+		.field_name = "ephem_key",
+		.item = &X509_PUBKEY_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(GOST_KEY_AGREEMENT_INFO, eph_iv),
+		.field_name = "eph_iv",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+};
+
+const ASN1_ITEM GOST_KEY_AGREEMENT_INFO_it = {
+	.itype = ASN1_ITYPE_NDEF_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = GOST_KEY_AGREEMENT_INFO_seq_tt,
+	.tcount = sizeof(GOST_KEY_AGREEMENT_INFO_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(GOST_KEY_AGREEMENT_INFO),
+	.sname = "GOST_KEY_AGREEMENT_INFO",
+};
+
+GOST_KEY_AGREEMENT_INFO *
+d2i_GOST_KEY_AGREEMENT_INFO(GOST_KEY_AGREEMENT_INFO **a, const unsigned char **in, long len)
+{
+	return (GOST_KEY_AGREEMENT_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &GOST_KEY_AGREEMENT_INFO_it);
+}
+
+int
+i2d_GOST_KEY_AGREEMENT_INFO(GOST_KEY_AGREEMENT_INFO *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &GOST_KEY_AGREEMENT_INFO_it);
+}
+
+GOST_KEY_AGREEMENT_INFO *
+GOST_KEY_AGREEMENT_INFO_new(void)
+{
+	return (GOST_KEY_AGREEMENT_INFO *)ASN1_item_new(&GOST_KEY_AGREEMENT_INFO_it);
+}
+
+void
+GOST_KEY_AGREEMENT_INFO_free(GOST_KEY_AGREEMENT_INFO *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &GOST_KEY_AGREEMENT_INFO_it);
+}
+
+
+static const ASN1_TEMPLATE GOST_KEY_PARAMS_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(GOST_KEY_PARAMS, key_params),
+		.field_name = "key_params",
+		.item = &ASN1_OBJECT_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(GOST_KEY_PARAMS, hash_params),
+		.field_name = "hash_params",
+		.item = &ASN1_OBJECT_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(GOST_KEY_PARAMS, cipher_params),
+		.field_name = "cipher_params",
+		.item = &ASN1_OBJECT_it,
+	},
+};
+
+const ASN1_ITEM GOST_KEY_PARAMS_it = {
+	.itype = ASN1_ITYPE_NDEF_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = GOST_KEY_PARAMS_seq_tt,
+	.tcount = sizeof(GOST_KEY_PARAMS_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(GOST_KEY_PARAMS),
+	.sname = "GOST_KEY_PARAMS",
+};
+
+GOST_KEY_PARAMS *
+d2i_GOST_KEY_PARAMS(GOST_KEY_PARAMS **a, const unsigned char **in, long len)
+{
+	return (GOST_KEY_PARAMS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &GOST_KEY_PARAMS_it);
+}
+
+int
+i2d_GOST_KEY_PARAMS(GOST_KEY_PARAMS *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &GOST_KEY_PARAMS_it);
+}
+
+GOST_KEY_PARAMS *
+GOST_KEY_PARAMS_new(void)
+{
+	return (GOST_KEY_PARAMS *)ASN1_item_new(&GOST_KEY_PARAMS_it);
+}
+
+void
+GOST_KEY_PARAMS_free(GOST_KEY_PARAMS *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &GOST_KEY_PARAMS_it);
+}
+
+static const ASN1_TEMPLATE GOST_CIPHER_PARAMS_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(GOST_CIPHER_PARAMS, iv),
+		.field_name = "iv",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(GOST_CIPHER_PARAMS, enc_param_set),
+		.field_name = "enc_param_set",
+		.item = &ASN1_OBJECT_it,
+	},
+};
+
+const ASN1_ITEM GOST_CIPHER_PARAMS_it = {
+	.itype = ASN1_ITYPE_NDEF_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = GOST_CIPHER_PARAMS_seq_tt,
+	.tcount = sizeof(GOST_CIPHER_PARAMS_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(GOST_CIPHER_PARAMS),
+	.sname = "GOST_CIPHER_PARAMS",
+};
+
+GOST_CIPHER_PARAMS *
+d2i_GOST_CIPHER_PARAMS(GOST_CIPHER_PARAMS **a, const unsigned char **in, long len)
+{
+	return (GOST_CIPHER_PARAMS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &GOST_CIPHER_PARAMS_it);
+}
+
+int
+i2d_GOST_CIPHER_PARAMS(GOST_CIPHER_PARAMS *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &GOST_CIPHER_PARAMS_it);
+}
+
+GOST_CIPHER_PARAMS *
+GOST_CIPHER_PARAMS_new(void)
+{
+	return (GOST_CIPHER_PARAMS *)ASN1_item_new(&GOST_CIPHER_PARAMS_it);
+}
+
+void
+GOST_CIPHER_PARAMS_free(GOST_CIPHER_PARAMS *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &GOST_CIPHER_PARAMS_it);
+}
+
+#endif
diff --git a/crypto/libressl/crypto/gost/gost_asn1.h b/crypto/libressl/crypto/gost/gost_asn1.h
new file mode 100644
index 0000000000..320cc4b7d9
--- /dev/null
+++ b/crypto/libressl/crypto/gost/gost_asn1.h
@@ -0,0 +1,87 @@
+/* $OpenBSD$ */
+/*
+ * Copyright (c) 2014 Dmitry Eremin-Solenikov 
+ * Copyright (c) 2005-2006 Cryptocom LTD
+ *
+ * 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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#ifndef HEADER_GOST_ASN1_H
+#define HEADER_GOST_ASN1_H
+
+#include 
+
+typedef struct {
+	ASN1_OCTET_STRING *encrypted_key;
+	ASN1_OCTET_STRING *imit;
+} GOST_KEY_INFO;
+
+DECLARE_ASN1_FUNCTIONS(GOST_KEY_INFO)
+
+typedef struct {
+	ASN1_OBJECT *cipher;
+	X509_PUBKEY *ephem_key;
+	ASN1_OCTET_STRING *eph_iv;
+} GOST_KEY_AGREEMENT_INFO;
+
+DECLARE_ASN1_FUNCTIONS(GOST_KEY_AGREEMENT_INFO)
+
+typedef struct {
+	GOST_KEY_INFO *key_info;
+	GOST_KEY_AGREEMENT_INFO *key_agreement_info;
+} GOST_KEY_TRANSPORT;
+
+DECLARE_ASN1_FUNCTIONS(GOST_KEY_TRANSPORT)
+
+typedef struct {
+	ASN1_OBJECT *key_params;
+	ASN1_OBJECT *hash_params;
+	ASN1_OBJECT *cipher_params;
+} GOST_KEY_PARAMS;
+
+DECLARE_ASN1_FUNCTIONS(GOST_KEY_PARAMS)
+
+#endif
diff --git a/crypto/libressl/crypto/gost/gost_err.c b/crypto/libressl/crypto/gost/gost_err.c
new file mode 100644
index 0000000000..b4e061f985
--- /dev/null
+++ b/crypto/libressl/crypto/gost/gost_err.c
@@ -0,0 +1,142 @@
+/* crypto/gost/gost_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2014 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_GOST,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_GOST,0,reason)
+
+static ERR_STRING_DATA GOST_str_functs[]=
+	{
+{ERR_FUNC(GOST_F_DECODE_GOST01_ALGOR_PARAMS),	"DECODE_GOST01_ALGOR_PARAMS"},
+{ERR_FUNC(GOST_F_ENCODE_GOST01_ALGOR_PARAMS),	"ENCODE_GOST01_ALGOR_PARAMS"},
+{ERR_FUNC(GOST_F_GOST2001_COMPUTE_PUBLIC),	"GOST2001_COMPUTE_PUBLIC"},
+{ERR_FUNC(GOST_F_GOST2001_DO_SIGN),	"GOST2001_DO_SIGN"},
+{ERR_FUNC(GOST_F_GOST2001_DO_VERIFY),	"GOST2001_DO_VERIFY"},
+{ERR_FUNC(GOST_F_GOST2001_KEYGEN),	"GOST2001_KEYGEN"},
+{ERR_FUNC(GOST_F_GOST89_GET_ASN1_PARAMETERS),	"GOST89_GET_ASN1_PARAMETERS"},
+{ERR_FUNC(GOST_F_GOST89_SET_ASN1_PARAMETERS),	"GOST89_SET_ASN1_PARAMETERS"},
+{ERR_FUNC(GOST_F_GOST_KEY_CHECK_KEY),	"GOST_KEY_check_key"},
+{ERR_FUNC(GOST_F_GOST_KEY_NEW),	"GOST_KEY_new"},
+{ERR_FUNC(GOST_F_GOST_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES),	"GOST_KEY_set_public_key_affine_coordinates"},
+{ERR_FUNC(GOST_F_PARAM_COPY_GOST01),	"PARAM_COPY_GOST01"},
+{ERR_FUNC(GOST_F_PARAM_DECODE_GOST01),	"PARAM_DECODE_GOST01"},
+{ERR_FUNC(GOST_F_PKEY_GOST01_CTRL),	"PKEY_GOST01_CTRL"},
+{ERR_FUNC(GOST_F_PKEY_GOST01_DECRYPT),	"PKEY_GOST01_DECRYPT"},
+{ERR_FUNC(GOST_F_PKEY_GOST01_DERIVE),	"PKEY_GOST01_DERIVE"},
+{ERR_FUNC(GOST_F_PKEY_GOST01_ENCRYPT),	"PKEY_GOST01_ENCRYPT"},
+{ERR_FUNC(GOST_F_PKEY_GOST01_PARAMGEN),	"PKEY_GOST01_PARAMGEN"},
+{ERR_FUNC(GOST_F_PKEY_GOST01_SIGN),	"PKEY_GOST01_SIGN"},
+{ERR_FUNC(GOST_F_PKEY_GOST_MAC_CTRL),	"PKEY_GOST_MAC_CTRL"},
+{ERR_FUNC(GOST_F_PKEY_GOST_MAC_KEYGEN),	"PKEY_GOST_MAC_KEYGEN"},
+{ERR_FUNC(GOST_F_PRIV_DECODE_GOST01),	"PRIV_DECODE_GOST01"},
+{ERR_FUNC(GOST_F_PUB_DECODE_GOST01),	"PUB_DECODE_GOST01"},
+{ERR_FUNC(GOST_F_PUB_ENCODE_GOST01),	"PUB_ENCODE_GOST01"},
+{ERR_FUNC(GOST_F_PUB_PRINT_GOST01),	"PUB_PRINT_GOST01"},
+{ERR_FUNC(GOST_F_UNPACK_SIGNATURE_CP),	"UNPACK_SIGNATURE_CP"},
+{ERR_FUNC(GOST_F_UNPACK_SIGNATURE_LE),	"UNPACK_SIGNATURE_LE"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA GOST_str_reasons[]=
+	{
+{ERR_REASON(GOST_R_BAD_KEY_PARAMETERS_FORMAT),"bad key parameters format"},
+{ERR_REASON(GOST_R_BAD_PKEY_PARAMETERS_FORMAT),"bad pkey parameters format"},
+{ERR_REASON(GOST_R_CANNOT_PACK_EPHEMERAL_KEY),"cannot pack ephemeral key"},
+{ERR_REASON(GOST_R_CTRL_CALL_FAILED)     ,"ctrl call failed"},
+{ERR_REASON(GOST_R_ERROR_COMPUTING_SHARED_KEY),"error computing shared key"},
+{ERR_REASON(GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO),"error parsing key transport info"},
+{ERR_REASON(GOST_R_INCOMPATIBLE_ALGORITHMS),"incompatible algorithms"},
+{ERR_REASON(GOST_R_INCOMPATIBLE_PEER_KEY),"incompatible peer key"},
+{ERR_REASON(GOST_R_INVALID_DIGEST_TYPE)  ,"invalid digest type"},
+{ERR_REASON(GOST_R_INVALID_IV_LENGTH)    ,"invalid iv length"},
+{ERR_REASON(GOST_R_INVALID_MAC_KEY_LENGTH),"invalid mac key length"},
+{ERR_REASON(GOST_R_KEY_IS_NOT_INITIALIZED),"key is not initialized"},
+{ERR_REASON(GOST_R_KEY_PARAMETERS_MISSING),"key parameters missing"},
+{ERR_REASON(GOST_R_MAC_KEY_NOT_SET)      ,"mac key not set"},
+{ERR_REASON(GOST_R_NO_PARAMETERS_SET)    ,"no parameters set"},
+{ERR_REASON(GOST_R_NO_PEER_KEY)          ,"no peer key"},
+{ERR_REASON(GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR),"no private part of non ephemeral keypair"},
+{ERR_REASON(GOST_R_PUBLIC_KEY_UNDEFINED) ,"public key undefined"},
+{ERR_REASON(GOST_R_RANDOM_NUMBER_GENERATOR_FAILED),"random number generator failed"},
+{ERR_REASON(GOST_R_SIGNATURE_MISMATCH)   ,"signature mismatch"},
+{ERR_REASON(GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q),"signature parts greater than q"},
+{ERR_REASON(GOST_R_UKM_NOT_SET)          ,"ukm not set"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_GOST_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(GOST_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,GOST_str_functs);
+		ERR_load_strings(0,GOST_str_reasons);
+		}
+#endif
+	}
diff --git a/crypto/libressl/crypto/gost/gost_locl.h b/crypto/libressl/crypto/gost/gost_locl.h
new file mode 100644
index 0000000000..238936824b
--- /dev/null
+++ b/crypto/libressl/crypto/gost/gost_locl.h
@@ -0,0 +1,113 @@
+/* $OpenBSD: gost_locl.h,v 1.2 2014/11/09 19:27:29 miod Exp $ */
+/*
+ * Copyright (c) 2014 Dmitry Eremin-Solenikov 
+ * Copyright (c) 2005-2006 Cryptocom LTD
+ *
+ * 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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#ifndef HEADER_GOST_LOCL_H
+#define HEADER_GOST_LOCL_H
+
+#include 
+#include 
+
+/* Internal representation of GOST substitution blocks */
+typedef struct {
+	unsigned char k8[16];
+	unsigned char k7[16];
+	unsigned char k6[16];
+	unsigned char k5[16];
+	unsigned char k4[16];
+	unsigned char k3[16];
+	unsigned char k2[16];
+	unsigned char k1[16];
+} gost_subst_block;		
+
+#if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
+#  define c2l(c,l)	((l)=*((const unsigned int *)(c)), (c)+=4)
+#  define l2c(l,c)	(*((unsigned int *)(c))=(l), (c)+=4)
+#else
+#define c2l(c,l)	(l =(((unsigned long)(*((c)++)))    ),		\
+			 l|=(((unsigned long)(*((c)++)))<< 8),		\
+			 l|=(((unsigned long)(*((c)++)))<<16),		\
+			 l|=(((unsigned long)(*((c)++)))<<24))
+#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)    )&0xff),	\
+			 *((c)++)=(unsigned char)(((l)>> 8)&0xff),	\
+			 *((c)++)=(unsigned char)(((l)>>16)&0xff),	\
+			 *((c)++)=(unsigned char)(((l)>>24)&0xff))
+#endif
+
+extern void Gost2814789_encrypt(const unsigned char *in, unsigned char *out,
+	const GOST2814789_KEY *key);
+extern void Gost2814789_decrypt(const unsigned char *in, unsigned char *out,
+	const GOST2814789_KEY *key);
+extern void Gost2814789_cryptopro_key_mesh(GOST2814789_KEY *key);
+
+/* GOST 28147-89 key wrapping */
+extern int gost_key_unwrap_crypto_pro(int nid,
+    const unsigned char *keyExchangeKey, const unsigned char *wrappedKey,
+    unsigned char *sessionKey);
+extern int gost_key_wrap_crypto_pro(int nid,
+    const unsigned char *keyExchangeKey, const unsigned char *ukm,
+    const unsigned char *sessionKey, unsigned char *wrappedKey);
+/* Pkey part */
+extern int gost2001_compute_public(GOST_KEY *ec);
+extern ECDSA_SIG *gost2001_do_sign(BIGNUM *md, GOST_KEY *eckey);
+extern int gost2001_do_verify(BIGNUM *md, ECDSA_SIG *sig, GOST_KEY *ec);
+extern int gost2001_keygen(GOST_KEY *ec);
+extern int VKO_compute_key(BIGNUM *X, BIGNUM *Y, const GOST_KEY *pkey,
+    GOST_KEY *priv_key, const BIGNUM *ukm);
+extern BIGNUM *GOST_le2bn(const unsigned char *buf, size_t len, BIGNUM *bn);
+extern int GOST_bn2le(BIGNUM *bn, unsigned char *buf, int len);
+
+/* GOST R 34.10 parameters */
+extern int GostR3410_get_md_digest(int nid);
+extern int GostR3410_get_pk_digest(int nid);
+extern int GostR3410_256_param_id(const char *value);
+extern int GostR3410_512_param_id(const char *value);
+
+#endif
diff --git a/crypto/libressl/crypto/gost/gostr341001.c b/crypto/libressl/crypto/gost/gostr341001.c
new file mode 100644
index 0000000000..5d3df9cd75
--- /dev/null
+++ b/crypto/libressl/crypto/gost/gostr341001.c
@@ -0,0 +1,401 @@
+/* $OpenBSD: gostr341001.c,v 1.3 2015/02/11 03:19:37 doug Exp $ */
+/*
+ * Copyright (c) 2014 Dmitry Eremin-Solenikov 
+ * Copyright (c) 2005-2006 Cryptocom LTD
+ *
+ * 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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_GOST
+#include 
+#include 
+#include 
+#include "gost_locl.h"
+
+/* Convert little-endian byte array into bignum */
+BIGNUM *
+GOST_le2bn(const unsigned char *buf, size_t len, BIGNUM *bn)
+{
+	unsigned char temp[64];
+	int i;
+
+	if (len > 64)
+		return NULL;
+
+	for (i = 0; i < len; i++) {
+		temp[len - 1 - i] = buf[i];
+	}
+
+	return BN_bin2bn(temp, len, bn);
+}
+
+int
+GOST_bn2le(BIGNUM *bn, unsigned char *buf, int len)
+{
+	unsigned char temp[64];
+	int i, bytes;
+
+	bytes = BN_num_bytes(bn);
+	if (len > 64 || bytes > len)
+		return 0;
+
+	BN_bn2bin(bn, temp);
+
+	for (i = 0; i < bytes; i++) {
+		buf[bytes - 1 - i] = temp[i];
+	}
+
+	memset(buf + bytes, 0, len - bytes);
+
+	return 1;
+}
+
+int
+gost2001_compute_public(GOST_KEY *ec)
+{
+	const EC_GROUP *group = GOST_KEY_get0_group(ec);
+	EC_POINT *pub_key = NULL;
+	const BIGNUM *priv_key = NULL;
+	BN_CTX *ctx = NULL;
+	int ok = 0;
+
+	if (group == NULL) {
+		GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,
+		    GOST_R_KEY_IS_NOT_INITIALIZED);
+		return 0;
+	}
+	ctx = BN_CTX_new();
+	if (ctx == NULL) {
+		GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,
+		    ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	BN_CTX_start(ctx);
+	if ((priv_key = GOST_KEY_get0_private_key(ec)) == NULL)
+		goto err;
+
+	pub_key = EC_POINT_new(group);
+	if (pub_key == NULL)
+		goto err;
+	if (EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx) == 0)
+		goto err;
+	if (GOST_KEY_set_public_key(ec, pub_key) == 0)
+		goto err;
+	ok = 1;
+
+	if (ok == 0) {
+err:
+		GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB);
+	}
+	EC_POINT_free(pub_key);
+	if (ctx != NULL) {
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+	}
+	return ok;
+}
+
+ECDSA_SIG *
+gost2001_do_sign(BIGNUM *md, GOST_KEY *eckey)
+{
+	ECDSA_SIG *newsig = NULL;
+	BIGNUM *order = NULL;
+	const EC_GROUP *group;
+	const BIGNUM *priv_key;
+	BIGNUM *r = NULL, *s = NULL, *X = NULL, *tmp = NULL, *tmp2 = NULL, *k =
+	    NULL, *e = NULL;
+	EC_POINT *C = NULL;
+	BN_CTX *ctx = BN_CTX_new();
+	int ok = 0;
+
+	if (ctx == NULL) {
+		GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	BN_CTX_start(ctx);
+	newsig = ECDSA_SIG_new();
+	if (newsig == NULL) {
+		GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	s = newsig->s;
+	r = newsig->r;
+	group = GOST_KEY_get0_group(eckey);
+	if ((order = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if (EC_GROUP_get_order(group, order, ctx) == 0)
+		goto err;
+	priv_key = GOST_KEY_get0_private_key(eckey);
+	if ((e = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if (BN_mod(e, md, order, ctx) == 0)
+		goto err;
+	if (BN_is_zero(e))
+		BN_one(e);
+	if ((k = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((X = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((C = EC_POINT_new(group)) == NULL)
+		goto err;
+	do {
+		do {
+			if (!BN_rand_range(k, order)) {
+				GOSTerr(GOST_F_GOST2001_DO_SIGN,
+					GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
+				goto err;
+			}
+			/*
+			 * We do not want timing information to leak the length
+			 * of k, so we compute G*k using an equivalent scalar
+			 * of fixed bit-length.
+			 */
+			if (BN_add(k, k, order) == 0)
+				goto err;
+			if (BN_num_bits(k) <= BN_num_bits(order))
+				if (BN_add(k, k, order) == 0)
+					goto err;
+
+			if (EC_POINT_mul(group, C, k, NULL, NULL, ctx) == 0) {
+				GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB);
+				goto err;
+			}
+			if (EC_POINT_get_affine_coordinates_GFp(group, C, X,
+			    NULL, ctx) == 0) {
+				GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB);
+				goto err;
+			}
+			if (BN_nnmod(r, X, order, ctx) == 0)
+				goto err;
+		} while (BN_is_zero(r));
+		/* s = (r*priv_key+k*e) mod order */
+		if (tmp == NULL) {
+			if ((tmp = BN_CTX_get(ctx)) == NULL)
+				goto err;
+		}
+		if (BN_mod_mul(tmp, priv_key, r, order, ctx) == 0)
+			goto err;
+		if (tmp2 == NULL) {
+			if ((tmp2 = BN_CTX_get(ctx)) == NULL)
+				goto err;
+		}
+		if (BN_mod_mul(tmp2, k, e, order, ctx) == 0)
+			goto err;
+		if (BN_mod_add(s, tmp, tmp2, order, ctx) == 0)
+			goto err;
+	} while (BN_is_zero(s));
+	ok = 1;
+
+err:
+	EC_POINT_free(C);
+	if (ctx != NULL) {
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+	}
+	if (ok == 0) {
+		ECDSA_SIG_free(newsig);
+		newsig = NULL;
+	}
+	return newsig;
+}
+
+int
+gost2001_do_verify(BIGNUM *md, ECDSA_SIG *sig, GOST_KEY *ec)
+{
+	BN_CTX *ctx = BN_CTX_new();
+	const EC_GROUP *group = GOST_KEY_get0_group(ec);
+	BIGNUM *order;
+	BIGNUM *e = NULL, *R = NULL, *v = NULL, *z1 = NULL, *z2 = NULL;
+	BIGNUM *X = NULL, *tmp = NULL;
+	EC_POINT *C = NULL;
+	const EC_POINT *pub_key = NULL;
+	int ok = 0;
+
+	if (ctx == NULL)
+		goto err;
+	BN_CTX_start(ctx);
+	if ((order = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((e = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((z1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((z2 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((tmp = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((X = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((R = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((v = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (EC_GROUP_get_order(group, order, ctx) == 0)
+		goto err;
+	pub_key = GOST_KEY_get0_public_key(ec);
+	if (BN_is_zero(sig->s) || BN_is_zero(sig->r) ||
+	    BN_cmp(sig->s, order) >= 1 || BN_cmp(sig->r, order) >= 1) {
+		GOSTerr(GOST_F_GOST2001_DO_VERIFY,
+		    GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
+		goto err;
+	}
+
+	if (BN_mod(e, md, order, ctx) == 0)
+		goto err;
+	if (BN_is_zero(e))
+		BN_one(e);
+	if ((v = BN_mod_inverse(v, e, order, ctx)) == NULL)
+		goto err;
+	if (BN_mod_mul(z1, sig->s, v, order, ctx) == 0)
+		goto err;
+	if (BN_sub(tmp, order, sig->r) == 0)
+		goto err;
+	if (BN_mod_mul(z2, tmp, v, order, ctx) == 0)
+		goto err;
+	if ((C = EC_POINT_new(group)) == NULL)
+		goto err;
+	if (EC_POINT_mul(group, C, z1, pub_key, z2, ctx) == 0) {
+		GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB);
+		goto err;
+	}
+	if (EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx) == 0) {
+		GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB);
+		goto err;
+	}
+	if (BN_mod(R, X, order, ctx) == 0)
+		goto err;
+	if (BN_cmp(R, sig->r) != 0) {
+		GOSTerr(GOST_F_GOST2001_DO_VERIFY, GOST_R_SIGNATURE_MISMATCH);
+	} else {
+		ok = 1;
+	}
+err:
+	EC_POINT_free(C);
+	if (ctx != NULL) {
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+	}
+	return ok;
+}
+
+/* Implementation of CryptoPro VKO 34.10-2001 algorithm */
+int
+VKO_compute_key(BIGNUM *X, BIGNUM *Y, const GOST_KEY *pkey, GOST_KEY *priv_key,
+    const BIGNUM *ukm)
+{
+	BIGNUM *p = NULL, *order = NULL;
+	const BIGNUM *key = GOST_KEY_get0_private_key(priv_key);
+	const EC_GROUP *group = GOST_KEY_get0_group(priv_key);
+	const EC_POINT *pub_key = GOST_KEY_get0_public_key(pkey);
+	EC_POINT *pnt;
+	BN_CTX *ctx = NULL;
+	int ok = 0;
+
+	pnt = EC_POINT_new(group);
+	if (pnt == NULL)
+		goto err;
+	ctx = BN_CTX_new();
+	if (ctx == NULL)
+		goto err;
+	BN_CTX_start(ctx);
+	if ((p = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((order = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if (EC_GROUP_get_order(group, order, ctx) == 0)
+		goto err;
+	if (BN_mod_mul(p, key, ukm, order, ctx) == 0)
+		goto err;
+	if (EC_POINT_mul(group, pnt, NULL, pub_key, p, ctx) == 0)
+		goto err;
+	if (EC_POINT_get_affine_coordinates_GFp(group, pnt, X, Y, ctx) == 0)
+		goto err;
+	ok = 1;
+
+err:
+	if (ctx != NULL) {
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+	}
+	EC_POINT_free(pnt);
+	return ok;
+}
+
+int
+gost2001_keygen(GOST_KEY *ec)
+{
+	BIGNUM *order = BN_new(), *d = BN_new();
+	const EC_GROUP *group = GOST_KEY_get0_group(ec);
+	int rc = 0;
+
+	if (order == NULL || d == NULL)
+		goto err;
+	if (EC_GROUP_get_order(group, order, NULL) == 0)
+		goto err;
+
+	do {
+		if (BN_rand_range(d, order) == 0) {
+			GOSTerr(GOST_F_GOST2001_KEYGEN,
+				GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
+			goto err;
+		}
+	} while (BN_is_zero(d));
+
+	if (GOST_KEY_set_private_key(ec, d) == 0)
+		goto err;
+	rc = gost2001_compute_public(ec);
+
+err:
+	BN_free(d);
+	BN_free(order);
+	return rc;
+}
+#endif
diff --git a/crypto/libressl/crypto/gost/gostr341001_ameth.c b/crypto/libressl/crypto/gost/gostr341001_ameth.c
new file mode 100644
index 0000000000..28c4cb08ed
--- /dev/null
+++ b/crypto/libressl/crypto/gost/gostr341001_ameth.c
@@ -0,0 +1,737 @@
+/* $OpenBSD: gostr341001_ameth.c,v 1.8 2015/02/11 04:05:14 beck Exp $ */
+/*
+ * Copyright (c) 2014 Dmitry Eremin-Solenikov 
+ * Copyright (c) 2005-2006 Cryptocom LTD
+ *
+ * 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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_GOST
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_CMS
+#include 
+#endif
+
+#include "asn1_locl.h"
+#include "gost_locl.h"
+#include "gost_asn1.h"
+
+static void
+pkey_free_gost01(EVP_PKEY *key)
+{
+	GOST_KEY_free(key->pkey.gost);
+}
+
+/*
+ * Parses GOST algorithm parameters from X509_ALGOR and
+ * modifies pkey setting NID and parameters
+ */
+static int
+decode_gost01_algor_params(EVP_PKEY *pkey, const unsigned char **p, int len)
+{
+	int param_nid = NID_undef, digest_nid = NID_undef;
+	GOST_KEY_PARAMS *gkp = NULL;
+	EC_GROUP *group;
+	GOST_KEY *ec;
+
+	gkp = d2i_GOST_KEY_PARAMS(NULL, p, len);
+	if (gkp == NULL) {
+		GOSTerr(GOST_F_DECODE_GOST01_ALGOR_PARAMS,
+			GOST_R_BAD_PKEY_PARAMETERS_FORMAT);
+		return 0;
+	}
+	param_nid = OBJ_obj2nid(gkp->key_params);
+	digest_nid = OBJ_obj2nid(gkp->hash_params);
+	GOST_KEY_PARAMS_free(gkp);
+
+	ec = pkey->pkey.gost;
+	if (ec == NULL) {
+		ec = GOST_KEY_new();
+		if (ec == NULL)
+			return 0;
+		if (EVP_PKEY_assign_GOST(pkey, ec) == 0)
+			return 0;
+	}
+
+	group = EC_GROUP_new_by_curve_name(param_nid);
+	if (group == NULL)
+		return 0;
+	EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
+	if (GOST_KEY_set_group(ec, group) == 0) {
+		EC_GROUP_free(group);
+		return 0;
+	}
+	EC_GROUP_free(group);
+	if (GOST_KEY_set_digest(ec, digest_nid) == 0)
+		return 0;
+	return 1;
+}
+
+static ASN1_STRING *
+encode_gost01_algor_params(const EVP_PKEY *key)
+{
+	ASN1_STRING *params = ASN1_STRING_new();
+	GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new();
+	int pkey_param_nid = NID_undef;
+
+	if (params == NULL || gkp == NULL) {
+		GOSTerr(GOST_F_ENCODE_GOST01_ALGOR_PARAMS,
+		    ERR_R_MALLOC_FAILURE);
+		ASN1_STRING_free(params);
+		params = NULL;
+		goto err;
+	}
+
+	pkey_param_nid =
+	    EC_GROUP_get_curve_name(GOST_KEY_get0_group(key->pkey.gost));
+	gkp->key_params = OBJ_nid2obj(pkey_param_nid);
+	gkp->hash_params = OBJ_nid2obj(GOST_KEY_get_digest(key->pkey.gost));
+	/*gkp->cipher_params = OBJ_nid2obj(cipher_param_nid); */
+	params->length = i2d_GOST_KEY_PARAMS(gkp, ¶ms->data);
+	if (params->length <= 0) {
+		GOSTerr(GOST_F_ENCODE_GOST01_ALGOR_PARAMS,
+		    ERR_R_MALLOC_FAILURE);
+		ASN1_STRING_free(params);
+		params = NULL;
+		goto err;
+	}
+	params->type = V_ASN1_SEQUENCE;
+err:
+	GOST_KEY_PARAMS_free(gkp);
+	return params;
+}
+
+static int
+pub_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+	const GOST_KEY *ea = a->pkey.gost;
+	const GOST_KEY *eb = b->pkey.gost;
+	const EC_POINT *ka, *kb;
+	int ret = 0;
+
+	if (ea == NULL || eb == NULL)
+		return 0;
+	ka = GOST_KEY_get0_public_key(ea);
+	kb = GOST_KEY_get0_public_key(eb);
+	if (ka == NULL || kb == NULL)
+		return 0;
+	ret = (0 == EC_POINT_cmp(GOST_KEY_get0_group(ea), ka, kb, NULL));
+	return ret;
+}
+
+static int
+pkey_size_gost01(const EVP_PKEY *pk)
+{
+	if (GOST_KEY_get_digest(pk->pkey.gost) == NID_id_tc26_gost3411_2012_512)
+		return 128;
+	return 64;
+}
+
+static int
+pkey_bits_gost01(const EVP_PKEY *pk)
+{
+	if (GOST_KEY_get_digest(pk->pkey.gost) == NID_id_tc26_gost3411_2012_512)
+		return 512;
+	return 256;
+}
+
+static int
+pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub)
+{
+	X509_ALGOR *palg = NULL;
+	const unsigned char *pubkey_buf = NULL;
+	const unsigned char *p;
+	ASN1_OBJECT *palgobj = NULL;
+	int pub_len;
+	BIGNUM *X, *Y;
+	ASN1_OCTET_STRING *octet = NULL;
+	int len;
+	int ret;
+	int ptype = V_ASN1_UNDEF;
+	ASN1_STRING *pval = NULL;
+
+	if (X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub)
+	    == 0)
+		return 0;
+	(void)EVP_PKEY_assign_GOST(pk, NULL);
+	X509_ALGOR_get0(NULL, &ptype, (void **)&pval, palg);
+	if (ptype != V_ASN1_SEQUENCE) {
+		GOSTerr(GOST_F_PUB_DECODE_GOST01,
+		    GOST_R_BAD_KEY_PARAMETERS_FORMAT);
+		return 0;
+	}
+	p = pval->data;
+	if (decode_gost01_algor_params(pk, &p, pval->length) == 0)
+		return 0;
+
+	octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len);
+	if (octet == NULL) {
+		GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	len = octet->length / 2;
+
+	X = GOST_le2bn(octet->data, len, NULL);
+	Y = GOST_le2bn(octet->data + len, len, NULL);
+
+	ASN1_OCTET_STRING_free(octet);
+
+	ret = GOST_KEY_set_public_key_affine_coordinates(pk->pkey.gost, X, Y);
+	if (ret == 0)
+		GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB);
+
+	BN_free(X);
+	BN_free(Y);
+
+	return ret;
+}
+
+static int
+pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk)
+{
+	ASN1_OBJECT *algobj = NULL;
+	ASN1_OCTET_STRING *octet = NULL;
+	ASN1_STRING *params = NULL;
+	void *pval = NULL;
+	unsigned char *buf = NULL, *sptr;
+	int key_size, ret = 0;
+	const EC_POINT *pub_key;
+	BIGNUM *X = NULL, *Y = NULL;
+	const GOST_KEY *ec = pk->pkey.gost;
+	int ptype = V_ASN1_UNDEF;
+
+	algobj = OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(ec)));
+	if (pk->save_parameters) {
+		params = encode_gost01_algor_params(pk);
+		if (params == NULL)
+			return 0;
+		pval = params;
+		ptype = V_ASN1_SEQUENCE;
+	}
+
+	key_size = GOST_KEY_get_size(ec);
+
+	pub_key = GOST_KEY_get0_public_key(ec);
+	if (pub_key == NULL) {
+		GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED);
+		goto err;
+	}
+
+	octet = ASN1_OCTET_STRING_new();
+	if (octet == NULL) {
+		GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	ret = ASN1_STRING_set(octet, NULL, 2 * key_size);
+	if (ret == 0) {
+		GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR);
+		goto err;
+	}
+
+	sptr = ASN1_STRING_data(octet);
+
+	X = BN_new();
+	Y = BN_new();
+	if (X == NULL || Y == NULL) {
+		GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	if (EC_POINT_get_affine_coordinates_GFp(GOST_KEY_get0_group(ec),
+	    pub_key, X, Y, NULL) == 0) {
+		GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_EC_LIB);
+		goto err;
+	}
+
+	GOST_bn2le(X, sptr, key_size);
+	GOST_bn2le(Y, sptr + key_size, key_size);
+
+	BN_free(Y);
+	BN_free(X);
+
+	ret = i2d_ASN1_OCTET_STRING(octet, &buf);
+	ASN1_BIT_STRING_free(octet);
+	if (ret < 0)
+		return 0;
+
+	return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret);
+
+err:
+	BN_free(Y);
+	BN_free(X);
+	ASN1_BIT_STRING_free(octet);
+	ASN1_STRING_free(params);
+	return 0;
+}
+
+static int
+param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx)
+{
+	int param_nid =
+	    EC_GROUP_get_curve_name(GOST_KEY_get0_group(pkey->pkey.gost));
+
+	if (BIO_indent(out, indent, 128) == 0)
+		return 0;
+	BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid));
+	if (BIO_indent(out, indent, 128) == 0)
+		return 0;
+	BIO_printf(out, "Digest Algorithm: %s\n",
+	    OBJ_nid2ln(GOST_KEY_get_digest(pkey->pkey.gost)));
+	return 1;
+}
+
+static int
+pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx)
+{
+	BN_CTX *ctx = BN_CTX_new();
+	BIGNUM *X, *Y;
+	const EC_POINT *pubkey;
+	const EC_GROUP *group;
+
+	if (ctx == NULL) {
+		GOSTerr(GOST_F_PUB_PRINT_GOST01, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	BN_CTX_start(ctx);
+	if ((X = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((Y = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	pubkey = GOST_KEY_get0_public_key(pkey->pkey.gost);
+	group = GOST_KEY_get0_group(pkey->pkey.gost);
+	if (EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y,
+	    ctx) == 0) {
+		GOSTerr(GOST_F_PUB_PRINT_GOST01, ERR_R_EC_LIB);
+		goto err;
+	}
+	if (BIO_indent(out, indent, 128) == 0)
+		goto err;
+	BIO_printf(out, "Public key:\n");
+	if (BIO_indent(out, indent + 3, 128) == 0)
+		goto err;
+	BIO_printf(out, "X:");
+	BN_print(out, X);
+	BIO_printf(out, "\n");
+	BIO_indent(out, indent + 3, 128);
+	BIO_printf(out, "Y:");
+	BN_print(out, Y);
+	BIO_printf(out, "\n");
+
+	BN_CTX_end(ctx);
+	BN_CTX_free(ctx);
+
+	return param_print_gost01(out, pkey, indent, pctx);
+
+err:
+	BN_CTX_end(ctx);
+	BN_CTX_free(ctx);
+	return 0;
+}
+
+static int
+priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx)
+{
+	const BIGNUM *key;
+
+	if (BIO_indent(out, indent, 128) == 0)
+		return 0;
+	BIO_printf(out, "Private key: ");
+	key = GOST_KEY_get0_private_key(pkey->pkey.gost);
+	if (key == NULL)
+		BIO_printf(out, "data;
+	if (decode_gost01_algor_params(pk, &p, pval->length) == 0)
+		return 0;
+	p = pkey_buf;
+	if (V_ASN1_OCTET_STRING == *p) {
+		/* New format - Little endian octet string */
+		unsigned char rev_buf[32];
+		int i;
+		ASN1_OCTET_STRING *s =
+		    d2i_ASN1_OCTET_STRING(NULL, &p, priv_len);
+
+		if (s == NULL || s->length != 32) {
+			GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR);
+			ASN1_STRING_free(s);
+			return 0;
+		}
+		for (i = 0; i < 32; i++) {
+			rev_buf[31 - i] = s->data[i];
+		}
+		ASN1_STRING_free(s);
+		pk_num = BN_bin2bn(rev_buf, 32, NULL);
+	} else {
+		priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len);
+		if (priv_key == NULL)
+			return 0;
+		ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL);
+		ASN1_INTEGER_free(priv_key);
+		if (ret == 0) {
+			GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR);
+			return 0;
+		}
+	}
+
+	ec = pk->pkey.gost;
+	if (ec == NULL) {
+		ec = GOST_KEY_new();
+		if (ec == NULL) {
+			BN_free(pk_num);
+			return 0;
+		}
+		if (EVP_PKEY_assign_GOST(pk, ec) == 0) {
+			BN_free(pk_num);
+			GOST_KEY_free(ec);
+			return 0;
+		}
+	}
+	if (GOST_KEY_set_private_key(ec, pk_num) == 0) {
+		BN_free(pk_num);
+		return 0;
+	}
+	ret = 0;
+	if (EVP_PKEY_missing_parameters(pk) == 0)
+		ret = gost2001_compute_public(ec) != 0;
+	BN_free(pk_num);
+
+	return ret;
+}
+
+static int
+priv_encode_gost01(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk)
+{
+	ASN1_OBJECT *algobj =
+	    OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(pk->pkey.gost)));
+	ASN1_STRING *params = encode_gost01_algor_params(pk);
+	unsigned char *priv_buf = NULL;
+	int priv_len;
+	ASN1_INTEGER *asn1key = NULL;
+
+	if (params == NULL)
+		return 0;
+
+	asn1key = BN_to_ASN1_INTEGER(GOST_KEY_get0_private_key(pk->pkey.gost),
+	    NULL);
+	if (asn1key == NULL) {
+		ASN1_STRING_free(params);
+		return 0;
+	}
+	priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf);
+	ASN1_INTEGER_free(asn1key);
+	return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, priv_buf,
+	    priv_len);
+}
+
+static int
+param_encode_gost01(const EVP_PKEY *pkey, unsigned char **pder)
+{
+	ASN1_STRING *params = encode_gost01_algor_params(pkey);
+	int len;
+
+	if (params == NULL)
+		return 0;
+	len = params->length;
+	if (pder != NULL)
+		memcpy(*pder, params->data, params->length);
+	ASN1_STRING_free(params);
+	return len;
+}
+
+static int
+param_decode_gost01(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
+{
+	ASN1_OBJECT *obj = NULL;
+	int nid;
+	GOST_KEY *ec;
+	EC_GROUP *group;
+	int ret;
+
+	/* New format */
+	if ((V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED) == **pder)
+		return decode_gost01_algor_params(pkey, pder, derlen);
+
+	/* Compatibility */
+	if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) {
+		GOSTerr(GOST_F_PARAM_DECODE_GOST01, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	nid = OBJ_obj2nid(obj);
+	ASN1_OBJECT_free(obj);
+
+	ec = GOST_KEY_new();
+	if (ec == NULL) {
+		GOSTerr(GOST_F_PARAM_DECODE_GOST01, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	group = EC_GROUP_new_by_curve_name(nid);
+	if (group == NULL) {
+		GOSTerr(GOST_F_PARAM_DECODE_GOST01,
+		    EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
+		GOST_KEY_free(ec);
+		return 0;
+	}
+
+	EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
+	if (GOST_KEY_set_group(ec, group) == 0) {
+		GOSTerr(GOST_F_PARAM_DECODE_GOST01, ERR_R_EC_LIB);
+		EC_GROUP_free(group);
+		GOST_KEY_free(ec);
+		return 0;
+	}
+	EC_GROUP_free(group);
+	if (GOST_KEY_set_digest(ec,
+	    NID_id_GostR3411_94_CryptoProParamSet) == 0) {
+		GOSTerr(GOST_F_PARAM_DECODE_GOST01, GOST_R_INVALID_DIGEST_TYPE);
+		GOST_KEY_free(ec);
+		return 0;
+	}
+	ret = EVP_PKEY_assign_GOST(pkey, ec);
+	if (ret == 0)
+		GOST_KEY_free(ec);
+	return ret;
+}
+
+static int
+param_missing_gost01(const EVP_PKEY *pk)
+{
+	const GOST_KEY *ec = pk->pkey.gost;
+
+	if (ec == NULL)
+		return 1;
+	if (GOST_KEY_get0_group(ec) == NULL)
+		return 1;
+	if (GOST_KEY_get_digest(ec) == NID_undef)
+		return 1;
+	return 0;
+}
+
+static int
+param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from)
+{
+	GOST_KEY *eto = to->pkey.gost;
+	const GOST_KEY *efrom = from->pkey.gost;
+	int ret = 1;
+
+	if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) {
+		GOSTerr(GOST_F_PARAM_COPY_GOST01,
+		    GOST_R_INCOMPATIBLE_ALGORITHMS);
+		return 0;
+	}
+	if (efrom == NULL) {
+		GOSTerr(GOST_F_PARAM_COPY_GOST01,
+		    GOST_R_KEY_PARAMETERS_MISSING);
+		return 0;
+	}
+	if (eto == NULL) {
+		eto = GOST_KEY_new();
+		if (eto == NULL) {
+			GOSTerr(GOST_F_PARAM_COPY_GOST01,
+			    ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		if (EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto) == 0) {
+			GOST_KEY_free(eto);
+			return 0;
+		}
+	}
+	GOST_KEY_set_group(eto, GOST_KEY_get0_group(efrom));
+	GOST_KEY_set_digest(eto, GOST_KEY_get_digest(efrom));
+	if (GOST_KEY_get0_private_key(eto) != NULL)
+		ret = gost2001_compute_public(eto);
+
+	return ret;
+}
+
+static int
+param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+	if (EC_GROUP_get_curve_name(GOST_KEY_get0_group(a->pkey.gost)) !=
+	    EC_GROUP_get_curve_name(GOST_KEY_get0_group(b->pkey.gost)))
+		return 0;
+
+	if (GOST_KEY_get_digest(a->pkey.gost) !=
+	    GOST_KEY_get_digest(b->pkey.gost))
+		return 0;
+
+	return 1;
+}
+
+static int
+pkey_ctrl_gost01(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+{
+	X509_ALGOR *alg1 = NULL, *alg2 = NULL, *alg3 = NULL;
+	int digest = GOST_KEY_get_digest(pkey->pkey.gost);
+
+	switch (op) {
+	case ASN1_PKEY_CTRL_PKCS7_SIGN:
+		if (arg1 == 0)
+			PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
+		break;
+
+	case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
+		if (arg1 == 0)
+			PKCS7_RECIP_INFO_get0_alg(arg2, &alg3);
+		break;
+#ifndef OPENSSL_NO_CMS
+	case ASN1_PKEY_CTRL_CMS_SIGN:
+		if (arg1 == 0)
+			CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
+		break;
+
+	case ASN1_PKEY_CTRL_CMS_ENVELOPE:
+		if (arg1 == 0)
+			CMS_RecipientInfo_ktri_get0_algs(arg2, NULL, NULL, &alg3);
+		break;
+#endif
+	case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+		*(int *)arg2 = GostR3410_get_md_digest(digest);
+		return 2;
+
+	default:
+		return -2;
+	}
+
+	if (alg1)
+		X509_ALGOR_set0(alg1, OBJ_nid2obj(GostR3410_get_md_digest(digest)), V_ASN1_NULL, 0);
+	if (alg2)
+		X509_ALGOR_set0(alg2, OBJ_nid2obj(GostR3410_get_pk_digest(digest)), V_ASN1_NULL, 0);
+	if (alg3) {
+		ASN1_STRING *params = encode_gost01_algor_params(pkey);
+		if (params == NULL) {
+			return -1;
+		}
+		X509_ALGOR_set0(alg3,
+		    OBJ_nid2obj(GostR3410_get_pk_digest(digest)),
+		    V_ASN1_SEQUENCE, params);
+	}
+
+	return 1;
+}
+
+const EVP_PKEY_ASN1_METHOD gostr01_asn1_meths[] = {
+	{
+		.pkey_id = EVP_PKEY_GOSTR01,
+		.pkey_base_id = EVP_PKEY_GOSTR01,
+		.pkey_flags = ASN1_PKEY_SIGPARAM_NULL,
+
+		.pem_str = "GOST2001",
+		.info = "GOST R 34.10-2001",
+
+		.pkey_free = pkey_free_gost01,
+		.pkey_ctrl = pkey_ctrl_gost01,
+
+		.priv_decode = priv_decode_gost01,
+		.priv_encode = priv_encode_gost01,
+		.priv_print = priv_print_gost01,
+
+		.param_decode = param_decode_gost01,
+		.param_encode = param_encode_gost01,
+		.param_missing = param_missing_gost01,
+		.param_copy = param_copy_gost01,
+		.param_cmp = param_cmp_gost01,
+		.param_print = param_print_gost01,
+
+		.pub_decode = pub_decode_gost01,
+		.pub_encode = pub_encode_gost01,
+		.pub_cmp = pub_cmp_gost01,
+		.pub_print = pub_print_gost01,
+		.pkey_size = pkey_size_gost01,
+		.pkey_bits = pkey_bits_gost01,
+	},
+	{
+		.pkey_id = EVP_PKEY_GOSTR12_256,
+		.pkey_base_id = EVP_PKEY_GOSTR01,
+		.pkey_flags = ASN1_PKEY_ALIAS
+	},
+	{
+		.pkey_id = EVP_PKEY_GOSTR12_512,
+		.pkey_base_id = EVP_PKEY_GOSTR01,
+		.pkey_flags = ASN1_PKEY_ALIAS
+	},
+};
+
+#endif
diff --git a/crypto/libressl/crypto/gost/gostr341001_key.c b/crypto/libressl/crypto/gost/gostr341001_key.c
new file mode 100644
index 0000000000..c0e3d4145e
--- /dev/null
+++ b/crypto/libressl/crypto/gost/gostr341001_key.c
@@ -0,0 +1,322 @@
+/* $OpenBSD: gostr341001_key.c,v 1.5 2015/02/14 06:40:04 jsing Exp $ */
+/*
+ * Copyright (c) 2014 Dmitry Eremin-Solenikov 
+ * Copyright (c) 2005-2006 Cryptocom LTD
+ *
+ * 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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_GOST
+#include 
+#include 
+#include 
+#include 
+#include "gost_locl.h"
+
+struct gost_key_st {
+	EC_GROUP *group;
+
+	EC_POINT *pub_key;
+	BIGNUM	 *priv_key;
+
+	int	references;
+
+	int digest_nid;
+};
+
+GOST_KEY *
+GOST_KEY_new(void)
+{
+	GOST_KEY *ret;
+
+	ret = malloc(sizeof(GOST_KEY));
+	if (ret == NULL) {
+		GOSTerr(GOST_F_GOST_KEY_NEW, ERR_R_MALLOC_FAILURE);
+		return (NULL);
+	}
+	ret->group = NULL;
+	ret->pub_key = NULL;
+	ret->priv_key = NULL;
+	ret->references = 1;
+	ret->digest_nid = NID_undef;
+	return (ret);
+}
+
+void
+GOST_KEY_free(GOST_KEY *r)
+{
+	int i;
+
+	if (r == NULL)
+		return;
+
+	i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_EC);
+	if (i > 0)
+		return;
+
+	EC_GROUP_free(r->group);
+	EC_POINT_free(r->pub_key);
+	BN_clear_free(r->priv_key);
+
+	explicit_bzero((void *)r, sizeof(GOST_KEY));
+	free(r);
+}
+
+int
+GOST_KEY_check_key(const GOST_KEY *key)
+{
+	int ok = 0;
+	BN_CTX *ctx = NULL;
+	BIGNUM *order = NULL;
+	EC_POINT *point = NULL;
+
+	if (key == NULL || key->group == NULL || key->pub_key == NULL) {
+		GOSTerr(GOST_F_GOST_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	if (EC_POINT_is_at_infinity(key->group, key->pub_key) != 0) {
+		GOSTerr(GOST_F_GOST_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY);
+		goto err;
+	}
+	if ((ctx = BN_CTX_new()) == NULL)
+		goto err;
+	if ((point = EC_POINT_new(key->group)) == NULL)
+		goto err;
+
+	/* testing whether the pub_key is on the elliptic curve */
+	if (EC_POINT_is_on_curve(key->group, key->pub_key, ctx) == 0) {
+		GOSTerr(GOST_F_GOST_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
+		goto err;
+	}
+	/* testing whether pub_key * order is the point at infinity */
+	if ((order = BN_new()) == NULL)
+		goto err;
+	if (EC_GROUP_get_order(key->group, order, ctx) == 0) {
+		GOSTerr(GOST_F_GOST_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
+		goto err;
+	}
+	if (EC_POINT_mul(key->group, point, NULL, key->pub_key, order,
+	    ctx) == 0) {
+		GOSTerr(GOST_F_GOST_KEY_CHECK_KEY, ERR_R_EC_LIB);
+		goto err;
+	}
+	if (EC_POINT_is_at_infinity(key->group, point) == 0) {
+		GOSTerr(GOST_F_GOST_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
+		goto err;
+	}
+	/*
+	 * in case the priv_key is present : check if generator * priv_key ==
+	 * pub_key
+	 */
+	if (key->priv_key != NULL) {
+		if (BN_cmp(key->priv_key, order) >= 0) {
+			GOSTerr(GOST_F_GOST_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
+			goto err;
+		}
+		if (EC_POINT_mul(key->group, point, key->priv_key, NULL, NULL,
+		    ctx) == 0) {
+			GOSTerr(GOST_F_GOST_KEY_CHECK_KEY, ERR_R_EC_LIB);
+			goto err;
+		}
+		if (EC_POINT_cmp(key->group, point, key->pub_key, ctx) != 0) {
+			GOSTerr(GOST_F_GOST_KEY_CHECK_KEY,
+			    EC_R_INVALID_PRIVATE_KEY);
+			goto err;
+		}
+	}
+	ok = 1;
+err:
+	BN_free(order);
+	BN_CTX_free(ctx);
+	EC_POINT_free(point);
+	return (ok);
+}
+
+int
+GOST_KEY_set_public_key_affine_coordinates(GOST_KEY *key, BIGNUM *x, BIGNUM *y)
+{
+	BN_CTX *ctx = NULL;
+	BIGNUM *tx, *ty;
+	EC_POINT *point = NULL;
+	int ok = 0;
+
+	if (key == NULL || key->group == NULL || x == NULL || y == NULL) {
+		GOSTerr(GOST_F_GOST_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
+		    ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+	}
+	ctx = BN_CTX_new();
+	if (ctx == NULL)
+		goto err;
+
+	point = EC_POINT_new(key->group);
+	if (point == NULL)
+		goto err;
+
+	if ((tx = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((ty = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if (EC_POINT_set_affine_coordinates_GFp(key->group, point, x, y,
+	    ctx) == 0)
+		goto err;
+	if (EC_POINT_get_affine_coordinates_GFp(key->group, point, tx, ty,
+	    ctx) == 0)
+		goto err;
+	/*
+	 * Check if retrieved coordinates match originals: if not, values are
+	 * out of range.
+	 */
+	if (BN_cmp(x, tx) != 0 || BN_cmp(y, ty) != 0) {
+		GOSTerr(GOST_F_GOST_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
+		    EC_R_COORDINATES_OUT_OF_RANGE);
+		goto err;
+	}
+	if (GOST_KEY_set_public_key(key, point) == 0)
+		goto err;
+
+	if (GOST_KEY_check_key(key) == 0)
+		goto err;
+
+	ok = 1;
+
+err:
+	EC_POINT_free(point);
+	BN_CTX_free(ctx);
+	return ok;
+
+}
+
+const EC_GROUP *
+GOST_KEY_get0_group(const GOST_KEY *key)
+{
+	return key->group;
+}
+
+int
+GOST_KEY_set_group(GOST_KEY *key, const EC_GROUP *group)
+{
+	EC_GROUP_free(key->group);
+	key->group = EC_GROUP_dup(group);
+	return (key->group == NULL) ? 0 : 1;
+}
+
+const BIGNUM *
+GOST_KEY_get0_private_key(const GOST_KEY *key)
+{
+	return key->priv_key;
+}
+
+int
+GOST_KEY_set_private_key(GOST_KEY *key, const BIGNUM *priv_key)
+{
+	BN_clear_free(key->priv_key);
+	key->priv_key = BN_dup(priv_key);
+	return (key->priv_key == NULL) ? 0 : 1;
+}
+
+const EC_POINT *
+GOST_KEY_get0_public_key(const GOST_KEY *key)
+{
+	return key->pub_key;
+}
+
+int
+GOST_KEY_set_public_key(GOST_KEY *key, const EC_POINT *pub_key)
+{
+	EC_POINT_free(key->pub_key);
+	key->pub_key = EC_POINT_dup(pub_key, key->group);
+	return (key->pub_key == NULL) ? 0 : 1;
+}
+
+int
+GOST_KEY_get_digest(const GOST_KEY *key)
+{
+	return key->digest_nid;
+}
+int
+GOST_KEY_set_digest(GOST_KEY *key, int digest_nid)
+{
+	if (digest_nid == NID_id_GostR3411_94_CryptoProParamSet ||
+	    digest_nid == NID_id_tc26_gost3411_2012_256 ||
+	    digest_nid == NID_id_tc26_gost3411_2012_512) {
+		key->digest_nid = digest_nid;
+		return 1;
+	}
+
+	return 0;
+}
+
+size_t
+GOST_KEY_get_size(const GOST_KEY *r)
+{
+	int i;
+	BIGNUM *order = NULL;
+	const EC_GROUP *group;
+
+	if (r == NULL)
+		return 0;
+	group = GOST_KEY_get0_group(r);
+	if (group == NULL)
+		return 0;
+
+	if ((order = BN_new()) == NULL)
+		return 0;
+
+	if (EC_GROUP_get_order(group, order, NULL) == 0) {
+		BN_clear_free(order);
+		return 0;
+	}
+
+	i = BN_num_bytes(order);
+	BN_clear_free(order);
+	return (i);
+}
+#endif
diff --git a/crypto/libressl/crypto/gost/gostr341001_params.c b/crypto/libressl/crypto/gost/gostr341001_params.c
new file mode 100644
index 0000000000..5c891c27ee
--- /dev/null
+++ b/crypto/libressl/crypto/gost/gostr341001_params.c
@@ -0,0 +1,132 @@
+/* $OpenBSD: gostr341001_params.c,v 1.2 2014/11/09 23:06:52 miod Exp $ */
+/*
+ * Copyright (c) 2014 Dmitry Eremin-Solenikov 
+ * Copyright (c) 2005-2006 Cryptocom LTD
+ *
+ * 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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_GOST
+#include 
+#include 
+
+#include "gost_locl.h"
+
+int
+GostR3410_get_md_digest(int nid)
+{
+	if (nid == NID_id_GostR3411_94_CryptoProParamSet)
+		return NID_id_GostR3411_94;
+	return nid;
+}
+
+int
+GostR3410_get_pk_digest(int nid)
+{
+	switch (nid) {
+	case NID_id_GostR3411_94_CryptoProParamSet:
+		return NID_id_GostR3410_2001;
+	case NID_id_tc26_gost3411_2012_256:
+		return NID_id_tc26_gost3410_2012_256;
+	case NID_id_tc26_gost3411_2012_512:
+		return NID_id_tc26_gost3410_2012_512;
+	default:
+		return NID_undef;
+	}
+}
+
+typedef struct GostR3410_params {
+	const char *name;
+	int nid;
+} GostR3410_params;
+
+static const GostR3410_params GostR3410_256_params[] = {
+	{ "A",  NID_id_GostR3410_2001_CryptoPro_A_ParamSet },
+	{ "B",  NID_id_GostR3410_2001_CryptoPro_B_ParamSet },
+	{ "C",  NID_id_GostR3410_2001_CryptoPro_C_ParamSet },
+	{ "0",  NID_id_GostR3410_2001_TestParamSet },
+	{ "XA", NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet },
+	{ "XB", NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet },
+	{ NULL, NID_undef },
+};
+
+static const GostR3410_params GostR3410_512_params[] = {
+	{ "A",  NID_id_tc26_gost_3410_2012_512_paramSetA },
+	{ "B",  NID_id_tc26_gost_3410_2012_512_paramSetB },
+	{ NULL, NID_undef },
+};
+
+int
+GostR3410_256_param_id(const char *value)
+{
+	int i;
+
+	for (i = 0; GostR3410_256_params[i].nid != NID_undef; i++) {
+		if (strcasecmp(GostR3410_256_params[i].name, value) == 0)
+			return GostR3410_256_params[i].nid;
+	}
+
+	return NID_undef;
+}
+
+int
+GostR3410_512_param_id(const char *value)
+{
+	int i;
+
+	for (i = 0; GostR3410_512_params[i].nid != NID_undef; i++) {
+		if (strcasecmp(GostR3410_512_params[i].name, value) == 0)
+			return GostR3410_512_params[i].nid;
+	}
+
+	return NID_undef;
+}
+
+#endif
diff --git a/crypto/libressl/crypto/gost/gostr341001_pmeth.c b/crypto/libressl/crypto/gost/gostr341001_pmeth.c
new file mode 100644
index 0000000000..67901d6753
--- /dev/null
+++ b/crypto/libressl/crypto/gost/gostr341001_pmeth.c
@@ -0,0 +1,719 @@
+/* $OpenBSD: gostr341001_pmeth.c,v 1.11 2015/02/14 06:40:04 jsing Exp $ */
+/*
+ * Copyright (c) 2014 Dmitry Eremin-Solenikov 
+ * Copyright (c) 2005-2006 Cryptocom LTD
+ *
+ * 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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_GOST
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+#include "gost_locl.h"
+#include "gost_asn1.h"
+
+static ECDSA_SIG *
+unpack_signature_cp(const unsigned char *sig, size_t siglen)
+{
+	ECDSA_SIG *s;
+
+	s = ECDSA_SIG_new();
+	if (s == NULL) {
+		GOSTerr(GOST_F_UNPACK_SIGNATURE_CP, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	BN_bin2bn(sig, siglen / 2, s->s);
+	BN_bin2bn(sig + siglen / 2, siglen / 2, s->r);
+	return s;
+}
+
+static int
+pack_signature_cp(ECDSA_SIG *s, int order, unsigned char *sig, size_t *siglen)
+{
+	int r_len = BN_num_bytes(s->r);
+	int s_len = BN_num_bytes(s->s);
+
+	if (r_len > order || s_len > order)
+		return 0;
+
+	*siglen = 2 * order;
+
+	memset(sig, 0, *siglen);
+	BN_bn2bin(s->s, sig + order - s_len);
+	BN_bn2bin(s->r, sig + 2 * order - r_len);
+	ECDSA_SIG_free(s);
+	return 1;
+}
+
+static ECDSA_SIG *
+unpack_signature_le(const unsigned char *sig, size_t siglen)
+{
+	ECDSA_SIG *s;
+
+	s = ECDSA_SIG_new();
+	if (s == NULL) {
+		GOSTerr(GOST_F_UNPACK_SIGNATURE_LE, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	GOST_le2bn(sig, siglen / 2, s->r);
+	GOST_le2bn(sig + siglen / 2, siglen / 2, s->s);
+	return s;
+}
+
+static int
+pack_signature_le(ECDSA_SIG *s, int order, unsigned char *sig, size_t *siglen)
+{
+	*siglen = 2 * order;
+	memset(sig, 0, *siglen);
+	GOST_bn2le(s->r, sig, order);
+	GOST_bn2le(s->s, sig + order, order);
+	ECDSA_SIG_free(s);
+	return 1;
+}
+
+struct gost_pmeth_data {
+	int sign_param_nid; /* Should be set whenever parameters are filled */
+	int digest_nid;
+	EVP_MD *md;
+	unsigned char *shared_ukm;
+	int peer_key_used;
+	int sig_format;
+};
+
+static int
+pkey_gost01_init(EVP_PKEY_CTX *ctx)
+{
+	struct gost_pmeth_data *data;
+	EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
+
+	data = calloc(1, sizeof(struct gost_pmeth_data));
+	if (data == NULL)
+		return 0;
+
+	if (pkey != NULL && pkey->pkey.gost != NULL) {
+		data->sign_param_nid =
+		    EC_GROUP_get_curve_name(GOST_KEY_get0_group(pkey->pkey.gost));
+		data->digest_nid = GOST_KEY_get_digest(pkey->pkey.gost);
+	}
+	EVP_PKEY_CTX_set_data(ctx, data);
+	return 1;
+}
+
+/* Copies contents of gost_pmeth_data structure */
+static int
+pkey_gost01_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+{
+	struct gost_pmeth_data *dst_data, *src_data;
+
+	if (pkey_gost01_init(dst) == 0)
+		return 0;
+
+	src_data = EVP_PKEY_CTX_get_data(src);
+	dst_data = EVP_PKEY_CTX_get_data(dst);
+	*dst_data = *src_data;
+	if (src_data->shared_ukm != NULL)
+		dst_data->shared_ukm = NULL;
+	return 1;
+}
+
+/* Frees up gost_pmeth_data structure */
+static void
+pkey_gost01_cleanup(EVP_PKEY_CTX *ctx)
+{
+	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
+
+	free(data->shared_ukm);
+	free(data);
+}
+
+static int
+pkey_gost01_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
+	EC_GROUP *group = NULL;
+	GOST_KEY *gost = NULL;
+	int ret = 0;
+
+	if (data->sign_param_nid == NID_undef ||
+	    data->digest_nid == NID_undef) {
+		GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN, GOST_R_NO_PARAMETERS_SET);
+		return 0;
+	}
+
+	group = EC_GROUP_new_by_curve_name(data->sign_param_nid);
+	if (group == NULL)
+		goto done;
+
+	EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
+
+	gost = GOST_KEY_new();
+	if (gost == NULL)
+		goto done;
+
+	if (GOST_KEY_set_digest(gost, data->digest_nid) == 0)
+		goto done;
+
+	if (GOST_KEY_set_group(gost, group) != 0)
+		ret = EVP_PKEY_assign_GOST(pkey, gost);
+
+done:
+	if (ret == 0)
+		GOST_KEY_free(gost);
+	EC_GROUP_free(group);
+	return ret;
+}
+
+static int
+pkey_gost01_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+	if (pkey_gost01_paramgen(ctx, pkey) == 0)
+		return 0;
+	return gost2001_keygen(pkey->pkey.gost) != 0;
+}
+
+static int
+pkey_gost01_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+    const unsigned char *tbs, size_t tbs_len)
+{
+	ECDSA_SIG *unpacked_sig = NULL;
+	EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
+	struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx);
+	BIGNUM *md;
+	size_t size;
+	int ret;
+
+	if (pkey == NULL || pkey->pkey.gost == NULL)
+		return 0;
+	size = GOST_KEY_get_size(pkey->pkey.gost);
+
+	if (siglen == NULL)
+		return 0;
+	if (sig == NULL) {
+		*siglen = 2 * size;
+		return 1;
+	} else if (*siglen < 2 * size) {
+		GOSTerr(GOST_F_PKEY_GOST01_SIGN, EC_R_BUFFER_TOO_SMALL);
+		return 0;
+	}
+	if (tbs_len != 32 && tbs_len != 64) {
+		GOSTerr(GOST_F_PKEY_GOST01_SIGN, EVP_R_BAD_BLOCK_LENGTH);
+		return 0;
+	}
+	md = GOST_le2bn(tbs, tbs_len, NULL);
+	if (md == NULL)
+		return 0;
+	unpacked_sig = gost2001_do_sign(md, pkey->pkey.gost);
+	BN_free(md);
+	if (unpacked_sig == NULL) {
+		return 0;
+	}
+	switch (pctx->sig_format) {
+	case GOST_SIG_FORMAT_SR_BE:
+		ret = pack_signature_cp(unpacked_sig, size, sig, siglen);
+		break;
+	case GOST_SIG_FORMAT_RS_LE:
+		ret = pack_signature_le(unpacked_sig, size, sig, siglen);
+		break;
+	default:
+		ret = -1;
+		break;
+	}
+	if (ret <= 0)
+		ECDSA_SIG_free(unpacked_sig);
+	return ret;
+}
+
+static int
+pkey_gost01_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
+    const unsigned char *tbs, size_t tbs_len)
+{
+	int ok = 0;
+	EVP_PKEY *pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
+	struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx);
+	ECDSA_SIG *s = NULL;
+	BIGNUM *md;
+
+	if (pub_key == NULL)
+		return 0;
+	switch (pctx->sig_format) {
+	case GOST_SIG_FORMAT_SR_BE:
+		s = unpack_signature_cp(sig, siglen);
+		break;
+	case GOST_SIG_FORMAT_RS_LE:
+		s = unpack_signature_le(sig, siglen);
+		break;
+	}
+	if (s == NULL)
+		return 0;
+	md = GOST_le2bn(tbs, tbs_len, NULL);
+	if (md == NULL)
+		goto err;
+	ok = gost2001_do_verify(md, s, pub_key->pkey.gost);
+
+err:
+	BN_free(md);
+	ECDSA_SIG_free(s);
+	return ok;
+}
+
+static int
+gost01_VKO_key(EVP_PKEY *pub_key, EVP_PKEY *priv_key, const unsigned char *ukm,
+    unsigned char *key)
+{
+	unsigned char hashbuf[128];
+	int digest_nid;
+	int ret = 0;
+	BN_CTX *ctx = BN_CTX_new();
+	BIGNUM *UKM, *X, *Y;
+
+	if (ctx == NULL)
+		return 0;
+
+	BN_CTX_start(ctx);
+	if ((UKM = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((X = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((Y = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	GOST_le2bn(ukm, 8, UKM);
+
+	digest_nid = GOST_KEY_get_digest(priv_key->pkey.gost);
+	if (VKO_compute_key(X, Y, pub_key->pkey.gost, priv_key->pkey.gost,
+	    UKM) == 0)
+		goto err;
+
+	switch (digest_nid) {
+	case NID_id_GostR3411_94_CryptoProParamSet:
+		GOST_bn2le(X, hashbuf, 32);
+		GOST_bn2le(Y, hashbuf + 32, 32);
+		GOSTR341194(hashbuf, 64, key, digest_nid);
+		ret = 1;
+		break;
+	case NID_id_tc26_gost3411_2012_256:
+		GOST_bn2le(X, hashbuf, 32);
+		GOST_bn2le(Y, hashbuf + 32, 32);
+		STREEBOG256(hashbuf, 64, key);
+		ret = 1;
+		break;
+	case NID_id_tc26_gost3411_2012_512:
+		GOST_bn2le(X, hashbuf, 64);
+		GOST_bn2le(Y, hashbuf + 64, 64);
+		STREEBOG256(hashbuf, 128, key);
+		ret = 1;
+		break;
+	default:
+		ret = -2;
+		break;
+	}
+err:
+	BN_CTX_end(ctx);
+	BN_CTX_free(ctx);
+	return ret;
+}
+
+int
+pkey_gost01_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_len,
+    const unsigned char *in, size_t in_len)
+{
+	const unsigned char *p = in;
+	EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx);
+	GOST_KEY_TRANSPORT *gkt = NULL;
+	int ret = 0;
+	unsigned char wrappedKey[44];
+	unsigned char sharedKey[32];
+	EVP_PKEY *eph_key = NULL, *peerkey = NULL;
+	int nid;
+
+	if (key == NULL) {
+		*key_len = 32;
+		return 1;
+	}
+	gkt = d2i_GOST_KEY_TRANSPORT(NULL, (const unsigned char **)&p, in_len);
+	if (gkt == NULL) {
+		GOSTerr(GOST_F_PKEY_GOST01_DECRYPT,
+		    GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
+		return -1;
+	}
+
+	/* If key transport structure contains public key, use it */
+	eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key);
+	if (eph_key != NULL) {
+		if (EVP_PKEY_derive_set_peer(pctx, eph_key) <= 0) {
+			GOSTerr(GOST_F_PKEY_GOST01_DECRYPT,
+			    GOST_R_INCOMPATIBLE_PEER_KEY);
+			goto err;
+		}
+	} else {
+		/* Set control "public key from client certificate used" */
+		if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3,
+		    NULL) <= 0) {
+			GOSTerr(GOST_F_PKEY_GOST01_DECRYPT,
+			    GOST_R_CTRL_CALL_FAILED);
+			goto err;
+		}
+	}
+	peerkey = EVP_PKEY_CTX_get0_peerkey(pctx);
+	if (peerkey == NULL) {
+		GOSTerr(GOST_F_PKEY_GOST01_DECRYPT, GOST_R_NO_PEER_KEY);
+		goto err;
+	}
+
+	nid = OBJ_obj2nid(gkt->key_agreement_info->cipher);
+
+	if (gkt->key_agreement_info->eph_iv->length != 8) {
+		GOSTerr(GOST_F_PKEY_GOST01_DECRYPT,
+		    GOST_R_INVALID_IV_LENGTH);
+		goto err;
+	}
+	memcpy(wrappedKey, gkt->key_agreement_info->eph_iv->data, 8);
+	if (gkt->key_info->encrypted_key->length != 32) {
+		GOSTerr(GOST_F_PKEY_GOST01_DECRYPT,
+		    EVP_R_BAD_KEY_LENGTH);
+		goto err;
+	}
+	memcpy(wrappedKey + 8, gkt->key_info->encrypted_key->data, 32);
+	if (gkt->key_info->imit->length != 4) {
+		GOSTerr(GOST_F_PKEY_GOST01_DECRYPT,
+		    ERR_R_INTERNAL_ERROR);
+		goto err;
+	}
+	memcpy(wrappedKey + 40, gkt->key_info->imit->data, 4);
+	if (gost01_VKO_key(peerkey, priv, wrappedKey, sharedKey) <= 0)
+		goto err;
+	if (gost_key_unwrap_crypto_pro(nid, sharedKey, wrappedKey, key) == 0) {
+		GOSTerr(GOST_F_PKEY_GOST01_DECRYPT,
+		    GOST_R_ERROR_COMPUTING_SHARED_KEY);
+		goto err;
+	}
+
+	ret = 1;
+err:
+	EVP_PKEY_free(eph_key);
+	GOST_KEY_TRANSPORT_free(gkt);
+	return ret;
+}
+
+int
+pkey_gost01_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
+{
+	/*
+	 * Public key of peer in the ctx field peerkey
+	 * Our private key in the ctx pkey
+	 * ukm is in the algorithm specific context data
+	 */
+	EVP_PKEY *my_key = EVP_PKEY_CTX_get0_pkey(ctx);
+	EVP_PKEY *peer_key = EVP_PKEY_CTX_get0_peerkey(ctx);
+	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
+
+	if (data->shared_ukm == NULL) {
+		GOSTerr(GOST_F_PKEY_GOST01_DERIVE, GOST_R_UKM_NOT_SET);
+		return 0;
+	}
+
+	if (key == NULL) {
+		*keylen = 32;
+		return 32;
+	}
+
+	if (gost01_VKO_key(peer_key, my_key, data->shared_ukm, key) <= 0)
+		return 0;
+
+	*keylen = 32;
+	return 1;
+}
+
+int
+pkey_gost01_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len,
+    const unsigned char *key, size_t key_len)
+{
+	GOST_KEY_TRANSPORT *gkt = NULL;
+	EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx);
+	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx);
+	unsigned char ukm[8], shared_key[32], crypted_key[44];
+	int ret = 0;
+	int key_is_ephemeral;
+	EVP_PKEY *sec_key = EVP_PKEY_CTX_get0_peerkey(pctx);
+	int nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet;
+
+	if (data->shared_ukm != NULL) {
+		memcpy(ukm, data->shared_ukm, 8);
+	} else /* if (out != NULL) */ {
+		arc4random_buf(ukm, 8);
+	}
+	/* Check for private key in the peer_key of context */
+	if (sec_key) {
+		key_is_ephemeral = 0;
+		if (GOST_KEY_get0_private_key(sec_key->pkey.gost) == 0) {
+			GOSTerr(GOST_F_PKEY_GOST01_ENCRYPT,
+			    GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR);
+			goto err;
+		}
+	} else {
+		key_is_ephemeral = 1;
+		if (out != NULL) {
+			GOST_KEY *tmp_key;
+
+			sec_key = EVP_PKEY_new();
+			if (sec_key == NULL)
+				goto err;
+			tmp_key = GOST_KEY_new();
+			if (tmp_key == NULL)
+				goto err;
+			if (EVP_PKEY_assign(sec_key, EVP_PKEY_base_id(pubk),
+			    tmp_key) == 0) {
+				GOST_KEY_free(tmp_key);
+				goto err;
+			}
+			if (EVP_PKEY_copy_parameters(sec_key, pubk) == 0)
+				goto err;
+			if (gost2001_keygen(sec_key->pkey.gost) == 0) {
+				goto err;
+			}
+		}
+	}
+
+	if (out != NULL) {
+		if (gost01_VKO_key(pubk, sec_key, ukm, shared_key) <= 0)
+			goto err;
+		gost_key_wrap_crypto_pro(nid, shared_key, ukm, key,
+		    crypted_key);
+	}
+	gkt = GOST_KEY_TRANSPORT_new();
+	if (gkt == NULL)
+		goto err;
+	if (ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm, 8) == 0)
+		goto err;
+	if (ASN1_OCTET_STRING_set(gkt->key_info->imit, crypted_key + 40,
+	    4) == 0)
+		goto err;
+	if (ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key, crypted_key + 8,
+	    32) == 0)
+		goto err;
+	if (key_is_ephemeral) {
+		if (X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,
+		    out != NULL ? sec_key : pubk) == 0) {
+			GOSTerr(GOST_F_PKEY_GOST01_ENCRYPT,
+			    GOST_R_CANNOT_PACK_EPHEMERAL_KEY);
+			goto err;
+		}
+	}
+	ASN1_OBJECT_free(gkt->key_agreement_info->cipher);
+	gkt->key_agreement_info->cipher = OBJ_nid2obj(nid);
+	if (key_is_ephemeral)
+		EVP_PKEY_free(sec_key);
+	else {
+		/* Set control "public key from client certificate used" */
+		if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3,
+		    NULL) <= 0) {
+			GOSTerr(GOST_F_PKEY_GOST01_ENCRYPT,
+			    GOST_R_CTRL_CALL_FAILED);
+			goto err;
+		}
+	}
+	if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt, out ? &out : NULL)) > 0)
+		ret = 1;
+	GOST_KEY_TRANSPORT_free(gkt);
+	return ret;
+
+err:
+	if (key_is_ephemeral)
+		EVP_PKEY_free(sec_key);
+	GOST_KEY_TRANSPORT_free(gkt);
+	return -1;
+}
+
+
+static int
+pkey_gost01_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+	struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx);
+
+	switch (type) {
+	case EVP_PKEY_CTRL_MD:
+		if (EVP_MD_type(p2) !=
+		    GostR3410_get_md_digest(pctx->digest_nid)) {
+			GOSTerr(GOST_F_PKEY_GOST01_CTRL,
+			    GOST_R_INVALID_DIGEST_TYPE);
+			return 0;
+		}
+		pctx->md = p2;
+		return 1;
+	case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
+	case EVP_PKEY_CTRL_PKCS7_DECRYPT:
+	case EVP_PKEY_CTRL_PKCS7_SIGN:
+	case EVP_PKEY_CTRL_DIGESTINIT:
+#ifndef OPENSSL_NO_CMS
+	case EVP_PKEY_CTRL_CMS_ENCRYPT:
+	case EVP_PKEY_CTRL_CMS_DECRYPT:
+	case EVP_PKEY_CTRL_CMS_SIGN:
+#endif
+		return 1;
+
+	case EVP_PKEY_CTRL_GOST_PARAMSET:
+		pctx->sign_param_nid = (int)p1;
+		return 1;
+
+	case EVP_PKEY_CTRL_SET_IV:
+	    {
+		char *ukm = malloc(p1);
+
+		if (ukm == NULL) {
+			GOSTerr(GOST_F_PKEY_GOST01_CTRL,
+			    ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		memcpy(ukm, p2, p1);
+		free(pctx->shared_ukm);
+		pctx->shared_ukm = ukm;
+		return 1;
+	    }
+
+	case EVP_PKEY_CTRL_PEER_KEY:
+		if (p1 == 0 || p1 == 1)	/* call from EVP_PKEY_derive_set_peer */
+			return 1;
+		if (p1 == 2)	/* TLS: peer key used? */
+			return pctx->peer_key_used;
+		if (p1 == 3)	/* TLS: peer key used! */
+			return (pctx->peer_key_used = 1);
+		return -2;
+	case EVP_PKEY_CTRL_GOST_SIG_FORMAT:
+		switch (p1) {
+		case GOST_SIG_FORMAT_SR_BE:
+		case GOST_SIG_FORMAT_RS_LE:
+			pctx->sig_format = p1;
+			return 1;
+		default:
+			return 0;
+		}
+		break;
+	case EVP_PKEY_CTRL_GOST_SET_DIGEST:
+		pctx->digest_nid = (int)p1;
+		return 1;
+	case EVP_PKEY_CTRL_GOST_GET_DIGEST:
+		*(int *)p2 = pctx->digest_nid;
+		return 1;
+	default:
+		return -2;
+	}
+}
+
+static int
+pkey_gost01_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value)
+{
+	int param_nid = NID_undef;
+	int digest_nid = NID_undef;
+
+	if (strcmp(type, "paramset") == 0) {
+		if (value == NULL)
+			return 0;
+		if (pkey_gost01_ctrl(ctx, EVP_PKEY_CTRL_GOST_GET_DIGEST, 0,
+		    &digest_nid) == 0)
+			return 0;
+		if (digest_nid == NID_id_tc26_gost3411_2012_512)
+			param_nid = GostR3410_512_param_id(value);
+		else
+			param_nid = GostR3410_256_param_id(value);
+		if (param_nid == NID_undef)
+			param_nid = OBJ_txt2nid(value);
+		if (param_nid == NID_undef)
+			return 0;
+
+		return pkey_gost01_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
+		    param_nid, NULL);
+	}
+	if (strcmp(type, "dgst") == 0) {
+		if (value == NULL)
+			return 0;
+		else if (strcmp(value, "gost94") == 0 ||
+		    strcmp(value, "md_gost94") == 0)
+			digest_nid = NID_id_GostR3411_94_CryptoProParamSet;
+		else if (strcmp(value, "streebog256") == 0)
+			digest_nid = NID_id_tc26_gost3411_2012_256;
+		else if (strcmp(value, "streebog512") == 0)
+			digest_nid = NID_id_tc26_gost3411_2012_512;
+
+		if (digest_nid == NID_undef)
+			return 0;
+
+		return pkey_gost01_ctrl(ctx, EVP_PKEY_CTRL_GOST_SET_DIGEST,
+		    digest_nid, NULL);
+	}
+	return -2;
+}
+
+const EVP_PKEY_METHOD gostr01_pkey_meth = {
+	.pkey_id = EVP_PKEY_GOSTR01,
+
+	.init = pkey_gost01_init,
+	.copy = pkey_gost01_copy,
+	.cleanup = pkey_gost01_cleanup,
+
+	.paramgen = pkey_gost01_paramgen,
+	.keygen = pkey_gost01_keygen,
+	.sign = pkey_gost01_sign,
+	.verify = pkey_gost01_verify,
+
+	.encrypt = pkey_gost01_encrypt,
+	.decrypt = pkey_gost01_decrypt,
+	.derive = pkey_gost01_derive,
+
+	.ctrl = pkey_gost01_ctrl,
+	.ctrl_str = pkey_gost01_ctrl_str,
+};
+#endif
diff --git a/crypto/libressl/crypto/gost/gostr341194.c b/crypto/libressl/crypto/gost/gostr341194.c
new file mode 100644
index 0000000000..c5ebd6cfaf
--- /dev/null
+++ b/crypto/libressl/crypto/gost/gostr341194.c
@@ -0,0 +1,273 @@
+/* $OpenBSD: gostr341194.c,v 1.4 2015/07/15 17:13:17 beck Exp $ */
+/*
+ * Copyright (c) 2014 Dmitry Eremin-Solenikov 
+ * Copyright (c) 2005-2006 Cryptocom LTD
+ *
+ * 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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_GOST
+#include 
+#include 
+#include 
+
+#include "gost_locl.h"
+
+/* Following functions are various bit meshing routines used in
+ * GOST R 34.11-94 algorithms */
+static void
+swap_bytes(unsigned char *w, unsigned char *k)
+{
+	int i, j;
+
+	for (i = 0; i < 4; i++)
+		for (j = 0; j < 8; j++)
+			k[i + 4 * j] = w[8 * i + j];
+}
+
+/* was A_A */
+static void
+circle_xor8(const unsigned char *w, unsigned char *k)
+{
+	unsigned char buf[8];
+	int i;
+
+	memcpy(buf, w, 8);
+	memmove(k, w + 8, 24);
+	for (i = 0; i < 8; i++)
+		k[i + 24] = buf[i] ^ k[i];
+}
+
+/* was R_R */
+static void
+transform_3(unsigned char *data)
+{
+	unsigned short int acc;
+
+	acc = (data[0] ^ data[2] ^ data[4] ^ data[6] ^ data[24] ^ data[30]) |
+	     ((data[1] ^ data[3] ^ data[5] ^ data[7] ^ data[25] ^ data[31]) << 8);
+	memmove(data, data + 2, 30);
+	data[30] = acc & 0xff;
+	data[31] = acc >> 8;
+}
+
+/* Adds blocks of N bytes modulo 2**(8*n). Returns carry*/
+static int
+add_blocks(int n, unsigned char *left, const unsigned char *right)
+{
+	int i;
+	int carry = 0;
+	int sum;
+
+	for (i = 0; i < n; i++) {
+		sum = (int)left[i] + (int)right[i] + carry;
+		left[i] = sum & 0xff;
+		carry = sum >> 8;
+	}
+	return carry;
+}
+
+/* Xor two sequences of bytes */
+static void
+xor_blocks(unsigned char *result, const unsigned char *a,
+    const unsigned char *b, size_t len)
+{
+	size_t i;
+
+	for (i = 0; i < len; i++)
+		result[i] = a[i] ^ b[i];
+}
+
+/* 
+ * 	Calculate H(i+1) = Hash(Hi,Mi) 
+ * 	Where H and M are 32 bytes long
+ */
+static int
+hash_step(GOSTR341194_CTX *c, unsigned char *H, const unsigned char *M)
+{
+	unsigned char U[32], W[32], V[32], S[32], Key[32];
+	int i;
+
+	/* Compute first key */
+	xor_blocks(W, H, M, 32);
+	swap_bytes(W, Key);
+	/* Encrypt first 8 bytes of H with first key */
+	Gost2814789_set_key(&c->cipher, Key, 256);
+	Gost2814789_encrypt(H, S, &c->cipher);
+
+	/* Compute second key */
+	circle_xor8(H, U);
+	circle_xor8(M, V);
+	circle_xor8(V, V);
+	xor_blocks(W, U, V, 32);
+	swap_bytes(W, Key);
+	/* encrypt second 8 bytes of H with second key */
+	Gost2814789_set_key(&c->cipher, Key, 256);
+	Gost2814789_encrypt(H+8, S+8, &c->cipher);
+
+	/* compute third key */
+	circle_xor8(U, U);
+	U[31] = ~U[31];
+	U[29] = ~U[29];
+	U[28] = ~U[28];
+	U[24] = ~U[24];
+	U[23] = ~U[23];
+	U[20] = ~U[20];
+	U[18] = ~U[18];
+	U[17] = ~U[17];
+	U[14] = ~U[14];
+	U[12] = ~U[12];
+	U[10] = ~U[10];
+	U[8] = ~U[8];
+	U[7] = ~U[7];
+	U[5] = ~U[5];
+	U[3] = ~U[3];
+	U[1] = ~U[1];
+	circle_xor8(V, V);
+	circle_xor8(V, V);
+	xor_blocks(W, U, V, 32);
+	swap_bytes(W, Key);
+	/* encrypt third 8 bytes of H with third key */
+	Gost2814789_set_key(&c->cipher, Key, 256);
+	Gost2814789_encrypt(H+16, S+16, &c->cipher);
+
+	/* Compute fourth key */
+	circle_xor8(U, U);
+	circle_xor8(V, V);
+	circle_xor8(V, V);
+	xor_blocks(W, U, V, 32);
+	swap_bytes(W, Key);
+	/* Encrypt last 8 bytes with fourth key */
+	Gost2814789_set_key(&c->cipher, Key, 256);
+	Gost2814789_encrypt(H+24, S+24, &c->cipher);
+
+	for (i = 0; i < 12; i++)
+		transform_3(S);
+	xor_blocks(S, S, M, 32);
+	transform_3(S);
+	xor_blocks(S, S, H, 32);
+	for (i = 0; i < 61; i++)
+		transform_3(S);
+	memcpy(H, S, 32);
+	return 1;
+}
+
+int
+GOSTR341194_Init(GOSTR341194_CTX *c, int nid)
+{
+	memset(c, 0, sizeof(*c));
+	return Gost2814789_set_sbox(&c->cipher, nid);
+}
+
+static void
+GOSTR341194_block_data_order(GOSTR341194_CTX *ctx, const unsigned char *p,
+    size_t num)
+{
+	int i;
+
+	for (i = 0; i < num; i++) {
+		hash_step(ctx, ctx->H, p);
+		add_blocks(32, ctx->S, p);
+		p += 32;
+	}
+}
+
+#define DATA_ORDER_IS_LITTLE_ENDIAN
+
+#define HASH_CBLOCK	GOSTR341194_CBLOCK
+#define HASH_LONG	GOSTR341194_LONG
+#define HASH_CTX	GOSTR341194_CTX
+#define HASH_UPDATE	GOSTR341194_Update
+#define HASH_TRANSFORM	GOSTR341194_Transform
+#define HASH_NO_FINAL	1
+#define HASH_BLOCK_DATA_ORDER	GOSTR341194_block_data_order
+
+#include "md32_common.h"
+
+int
+GOSTR341194_Final(unsigned char *md, GOSTR341194_CTX * c)
+{
+	unsigned char *p = (unsigned char *)c->data;
+	unsigned char T[32];
+
+	if (c->num > 0) {
+		memset(p + c->num, 0, 32 - c->num);
+		hash_step(c, c->H, p);
+		add_blocks(32, c->S, p);
+	}
+
+	p = T;
+	HOST_l2c(c->Nl, p);
+	HOST_l2c(c->Nh, p);
+	memset(p, 0, 32 - 8);
+	hash_step(c, c->H, T);
+	hash_step(c, c->H, c->S);
+
+	memcpy(md, c->H, 32);
+
+	return 1;
+}
+
+unsigned char *
+GOSTR341194(const unsigned char *d, size_t n, unsigned char *md, int nid)
+{
+	GOSTR341194_CTX c;
+	static unsigned char m[GOSTR341194_LENGTH];
+
+	if (md == NULL)
+		md = m;
+	if (!GOSTR341194_Init(&c, nid))
+		return 0;
+	GOSTR341194_Update(&c, d, n);
+	GOSTR341194_Final(md, &c);
+	explicit_bzero(&c, sizeof(c));
+	return (md);
+}
+#endif
diff --git a/crypto/libressl/crypto/gost/streebog.c b/crypto/libressl/crypto/gost/streebog.c
new file mode 100644
index 0000000000..aada82f541
--- /dev/null
+++ b/crypto/libressl/crypto/gost/streebog.c
@@ -0,0 +1,1477 @@
+/* $OpenBSD: streebog.c,v 1.4 2014/12/07 16:33:51 jsing Exp $ */
+/*
+ * Copyright (c) 2014 Dmitry Eremin-Solenikov 
+ * Copyright (c) 2005-2006 Cryptocom LTD
+ *
+ * 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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include 
+
+#include 
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_GOST
+#include 
+#include 
+#include 
+
+#include "gost_locl.h"
+
+static const STREEBOG_LONG64 A_PI_table[8][256] = {
+	{ /* 0 */
+		U64(0xd01f715b5c7ef8e6), U64(0x16fa240980778325),
+		U64(0xa8a42e857ee049c8), U64(0x6ac1068fa186465b),
+		U64(0x6e417bd7a2e9320b), U64(0x665c8167a437daab),
+		U64(0x7666681aa89617f6), U64(0x4b959163700bdcf5),
+		U64(0xf14be6b78df36248), U64(0xc585bd689a625cff),
+		U64(0x9557d7fca67d82cb), U64(0x89f0b969af6dd366),
+		U64(0xb0833d48749f6c35), U64(0xa1998c23b1ecbc7c),
+		U64(0x8d70c431ac02a736), U64(0xd6dfbc2fd0a8b69e),
+		U64(0x37aeb3e551fa198b), U64(0x0b7d128a40b5cf9c),
+		U64(0x5a8f2008b5780cbc), U64(0xedec882284e333e5),
+		U64(0xd25fc177d3c7c2ce), U64(0x5e0f5d50b61778ec),
+		U64(0x1d873683c0c24cb9), U64(0xad040bcbb45d208c),
+		U64(0x2f89a0285b853c76), U64(0x5732fff6791b8d58),
+		U64(0x3e9311439ef6ec3f), U64(0xc9183a809fd3c00f),
+		U64(0x83adf3f5260a01ee), U64(0xa6791941f4e8ef10),
+		U64(0x103ae97d0ca1cd5d), U64(0x2ce948121dee1b4a),
+		U64(0x39738421dbf2bf53), U64(0x093da2a6cf0cf5b4),
+		U64(0xcd9847d89cbcb45f), U64(0xf9561c078b2d8ae8),
+		U64(0x9c6a755a6971777f), U64(0xbc1ebaa0712ef0c5),
+		U64(0x72e61542abf963a6), U64(0x78bb5fde229eb12e),
+		U64(0x14ba94250fceb90d), U64(0x844d6697630e5282),
+		U64(0x98ea08026a1e032f), U64(0xf06bbea144217f5c),
+		U64(0xdb6263d11ccb377a), U64(0x641c314b2b8ee083),
+		U64(0x320e96ab9b4770cf), U64(0x1ee7deb986a96b85),
+		U64(0xe96cf57a878c47b5), U64(0xfdd6615f8842feb8),
+		U64(0xc83862965601dd1b), U64(0x2ea9f83e92572162),
+		U64(0xf876441142ff97fc), U64(0xeb2c455608357d9d),
+		U64(0x5612a7e0b0c9904c), U64(0x6c01cbfb2d500823),
+		U64(0x4548a6a7fa037a2d), U64(0xabc4c6bf388b6ef4),
+		U64(0xbade77d4fdf8bebd), U64(0x799b07c8eb4cac3a),
+		U64(0x0c9d87e805b19cf0), U64(0xcb588aac106afa27),
+		U64(0xea0c1d40c1e76089), U64(0x2869354a1e816f1a),
+		U64(0xff96d17307fbc490), U64(0x9f0a9d602f1a5043),
+		U64(0x96373fc6e016a5f7), U64(0x5292dab8b3a6e41c),
+		U64(0x9b8ae0382c752413), U64(0x4f15ec3b7364a8a5),
+		U64(0x3fb349555724f12b), U64(0xc7c50d4415db66d7),
+		U64(0x92b7429ee379d1a7), U64(0xd37f99611a15dfda),
+		U64(0x231427c05e34a086), U64(0xa439a96d7b51d538),
+		U64(0xb403401077f01865), U64(0xdda2aea5901d7902),
+		U64(0x0a5d4a9c8967d288), U64(0xc265280adf660f93),
+		U64(0x8bb0094520d4e94e), U64(0x2a29856691385532),
+		U64(0x42a833c5bf072941), U64(0x73c64d54622b7eb2),
+		U64(0x07e095624504536c), U64(0x8a905153e906f45a),
+		U64(0x6f6123c16b3b2f1f), U64(0xc6e55552dc097bc3),
+		U64(0x4468feb133d16739), U64(0xe211e7f0c7398829),
+		U64(0xa2f96419f7879b40), U64(0x19074bdbc3ad38e9),
+		U64(0xf4ebc3f9474e0b0c), U64(0x43886bd376d53455),
+		U64(0xd8028beb5aa01046), U64(0x51f23282f5cdc320),
+		U64(0xe7b1c2be0d84e16d), U64(0x081dfab006dee8a0),
+		U64(0x3b33340d544b857b), U64(0x7f5bcabc679ae242),
+		U64(0x0edd37c48a08a6d8), U64(0x81ed43d9a9b33bc6),
+		U64(0xb1a3655ebd4d7121), U64(0x69a1eeb5e7ed6167),
+		U64(0xf6ab73d5c8f73124), U64(0x1a67a3e185c61fd5),
+		U64(0x2dc91004d43c065e), U64(0x0240b02c8fb93a28),
+		U64(0x90f7f2b26cc0eb8f), U64(0x3cd3a16f114fd617),
+		U64(0xaae49ea9f15973e0), U64(0x06c0cd748cd64e78),
+		U64(0xda423bc7d5192a6e), U64(0xc345701c16b41287),
+		U64(0x6d2193ede4821537), U64(0xfcf639494190e3ac),
+		U64(0x7c3b228621f1c57e), U64(0xfb16ac2b0494b0c0),
+		U64(0xbf7e529a3745d7f9), U64(0x6881b6a32e3f7c73),
+		U64(0xca78d2bad9b8e733), U64(0xbbfe2fc2342aa3a9),
+		U64(0x0dbddffecc6381e4), U64(0x70a6a56e2440598e),
+		U64(0xe4d12a844befc651), U64(0x8c509c2765d0ba22),
+		U64(0xee8c6018c28814d9), U64(0x17da7c1f49a59e31),
+		U64(0x609c4c1328e194d3), U64(0xb3e3d57232f44b09),
+		U64(0x91d7aaa4a512f69b), U64(0x0ffd6fd243dabbcc),
+		U64(0x50d26a943c1fde34), U64(0x6be15e9968545b4f),
+		U64(0x94778fea6faf9fdf), U64(0x2b09dd7058ea4826),
+		U64(0x677cd9716de5c7bf), U64(0x49d5214fffb2e6dd),
+		U64(0x0360e83a466b273c), U64(0x1fc786af4f7b7691),
+		U64(0xa0b9d435783ea168), U64(0xd49f0c035f118cb6),
+		U64(0x01205816c9d21d14), U64(0xac2453dd7d8f3d98),
+		U64(0x545217cc3f70aa64), U64(0x26b4028e9489c9c2),
+		U64(0xdec2469fd6765e3e), U64(0x04807d58036f7450),
+		U64(0xe5f17292823ddb45), U64(0xf30b569b024a5860),
+		U64(0x62dcfc3fa758aefb), U64(0xe84cad6c4e5e5aa1),
+		U64(0xccb81fce556ea94b), U64(0x53b282ae7a74f908),
+		U64(0x1b47fbf74c1402c1), U64(0x368eebf39828049f),
+		U64(0x7afbeff2ad278b06), U64(0xbe5e0a8cfe97caed),
+		U64(0xcfd8f7f413058e77), U64(0xf78b2bc301252c30),
+		U64(0x4d555c17fcdd928d), U64(0x5f2f05467fc565f8),
+		U64(0x24f4b2a21b30f3ea), U64(0x860dd6bbecb768aa),
+		U64(0x4c750401350f8f99), U64(0x0000000000000000),
+		U64(0xecccd0344d312ef1), U64(0xb5231806be220571),
+		U64(0xc105c030990d28af), U64(0x653c695de25cfd97),
+		U64(0x159acc33c61ca419), U64(0xb89ec7f872418495),
+		U64(0xa9847693b73254dc), U64(0x58cf90243ac13694),
+		U64(0x59efc832f3132b80), U64(0x5c4fed7c39ae42c4),
+		U64(0x828dabe3efd81cfa), U64(0xd13f294d95ace5f2),
+		U64(0x7d1b7a90e823d86a), U64(0xb643f03cf849224d),
+		U64(0x3df3f979d89dcb03), U64(0x7426d836272f2dde),
+		U64(0xdfe21e891fa4432a), U64(0x3a136c1b9d99986f),
+		U64(0xfa36f43dcd46add4), U64(0xc025982650df35bb),
+		U64(0x856d3e81aadc4f96), U64(0xc4a5e57e53b041eb),
+		U64(0x4708168b75ba4005), U64(0xaf44bbe73be41aa4),
+		U64(0x971767d029c4b8e3), U64(0xb9be9feebb939981),
+		U64(0x215497ecd18d9aae), U64(0x316e7e91dd2c57f3),
+		U64(0xcef8afe2dad79363), U64(0x3853dc371220a247),
+		U64(0x35ee03c9de4323a3), U64(0xe6919aa8c456fc79),
+		U64(0xe05157dc4880b201), U64(0x7bdbb7e464f59612),
+		U64(0x127a59518318f775), U64(0x332ecebd52956ddb),
+		U64(0x8f30741d23bb9d1e), U64(0xd922d3fd93720d52),
+		U64(0x7746300c61440ae2), U64(0x25d4eab4d2e2eefe),
+		U64(0x75068020eefd30ca), U64(0x135a01474acaea61),
+		U64(0x304e268714fe4ae7), U64(0xa519f17bb283c82c),
+		U64(0xdc82f6b359cf6416), U64(0x5baf781e7caa11a8),
+		U64(0xb2c38d64fb26561d), U64(0x34ce5bdf17913eb7),
+		U64(0x5d6fb56af07c5fd0), U64(0x182713cd0a7f25fd),
+		U64(0x9e2ac576e6c84d57), U64(0x9aaab82ee5a73907),
+		U64(0xa3d93c0f3e558654), U64(0x7e7b92aaae48ff56),
+		U64(0x872d8ead256575be), U64(0x41c8dbfff96c0e7d),
+		U64(0x99ca5014a3cc1e3b), U64(0x40e883e930be1369),
+		U64(0x1ca76e95091051ad), U64(0x4e35b42dbab6b5b1),
+		U64(0x05a0254ecabd6944), U64(0xe1710fca8152af15),
+		U64(0xf22b0e8dcb984574), U64(0xb763a82a319b3f59),
+		U64(0x63fca4296e8ab3ef), U64(0x9d4a2d4ca0a36a6b),
+		U64(0xe331bfe60eeb953d), U64(0xd5bf541596c391a2),
+		U64(0xf5cb9bef8e9c1618), U64(0x46284e9dbc685d11),
+		U64(0x2074cffa185f87ba), U64(0xbd3ee2b6b8fcedd1),
+		U64(0xae64e3f1f23607b0), U64(0xfeb68965ce29d984),
+		U64(0x55724fdaf6a2b770), U64(0x29496d5cd753720e),
+		U64(0xa75941573d3af204), U64(0x8e102c0bea69800a),
+		U64(0x111ab16bc573d049), U64(0xd7ffe439197aab8a),
+		U64(0xefac380e0b5a09cd), U64(0x48f579593660fbc9),
+		U64(0x22347fd697e6bd92), U64(0x61bc1405e13389c7),
+		U64(0x4ab5c975b9d9c1e1), U64(0x80cd1bcf606126d2),
+		U64(0x7186fd78ed92449a), U64(0x93971a882aabccb3),
+		U64(0x88d0e17f66bfce72), U64(0x27945a985d5bd4d6)
+	}, { /* 1 */
+		U64(0xde553f8c05a811c8), U64(0x1906b59631b4f565),
+		U64(0x436e70d6b1964ff7), U64(0x36d343cb8b1e9d85),
+		U64(0x843dfacc858aab5a), U64(0xfdfc95c299bfc7f9),
+		U64(0x0f634bdea1d51fa2), U64(0x6d458b3b76efb3cd),
+		U64(0x85c3f77cf8593f80), U64(0x3c91315fbe737cb2),
+		U64(0x2148b03366ace398), U64(0x18f8b8264c6761bf),
+		U64(0xc830c1c495c9fb0f), U64(0x981a76102086a0aa),
+		U64(0xaa16012142f35760), U64(0x35cc54060c763cf6),
+		U64(0x42907d66cc45db2d), U64(0x8203d44b965af4bc),
+		U64(0x3d6f3cefc3a0e868), U64(0xbc73ff69d292bda7),
+		U64(0x8722ed0102e20a29), U64(0x8f8185e8cd34deb7),
+		U64(0x9b0561dda7ee01d9), U64(0x5335a0193227fad6),
+		U64(0xc9cecc74e81a6fd5), U64(0x54f5832e5c2431ea),
+		U64(0x99e47ba05d553470), U64(0xf7bee756acd226ce),
+		U64(0x384e05a5571816fd), U64(0xd1367452a47d0e6a),
+		U64(0xf29fde1c386ad85b), U64(0x320c77316275f7ca),
+		U64(0xd0c879e2d9ae9ab0), U64(0xdb7406c69110ef5d),
+		U64(0x45505e51a2461011), U64(0xfc029872e46c5323),
+		U64(0xfa3cb6f5f7bc0cc5), U64(0x031f17cd8768a173),
+		U64(0xbd8df2d9af41297d), U64(0x9d3b4f5ab43e5e3f),
+		U64(0x4071671b36feee84), U64(0x716207e7d3e3b83d),
+		U64(0x48d20ff2f9283a1a), U64(0x27769eb4757cbc7e),
+		U64(0x5c56ebc793f2e574), U64(0xa48b474f9ef5dc18),
+		U64(0x52cbada94ff46e0c), U64(0x60c7da982d8199c6),
+		U64(0x0e9d466edc068b78), U64(0x4eec2175eaf865fc),
+		U64(0x550b8e9e21f7a530), U64(0x6b7ba5bc653fec2b),
+		U64(0x5eb7f1ba6949d0dd), U64(0x57ea94e3db4c9099),
+		U64(0xf640eae6d101b214), U64(0xdd4a284182c0b0bb),
+		U64(0xff1d8fbf6304f250), U64(0xb8accb933bf9d7e8),
+		U64(0xe8867c478eb68c4d), U64(0x3f8e2692391bddc1),
+		U64(0xcb2fd60912a15a7c), U64(0xaec935dbab983d2f),
+		U64(0xf55ffd2b56691367), U64(0x80e2ce366ce1c115),
+		U64(0x179bf3f8edb27e1d), U64(0x01fe0db07dd394da),
+		U64(0xda8a0b76ecc37b87), U64(0x44ae53e1df9584cb),
+		U64(0xb310b4b77347a205), U64(0xdfab323c787b8512),
+		U64(0x3b511268d070b78e), U64(0x65e6e3d2b9396753),
+		U64(0x6864b271e2574d58), U64(0x259784c98fc789d7),
+		U64(0x02e11a7dfabb35a9), U64(0x8841a6dfa337158b),
+		U64(0x7ade78c39b5dcdd0), U64(0xb7cf804d9a2cc84a),
+		U64(0x20b6bd831b7f7742), U64(0x75bd331d3a88d272),
+		U64(0x418f6aab4b2d7a5e), U64(0xd9951cbb6babdaf4),
+		U64(0xb6318dfde7ff5c90), U64(0x1f389b112264aa83),
+		U64(0x492c024284fbaec0), U64(0xe33a0363c608f9a0),
+		U64(0x2688930408af28a4), U64(0xc7538a1a341ce4ad),
+		U64(0x5da8e677ee2171ae), U64(0x8c9e92254a5c7fc4),
+		U64(0x63d8cd55aae938b5), U64(0x29ebd8daa97a3706),
+		U64(0x959827b37be88aa1), U64(0x1484e4356adadf6e),
+		U64(0xa7945082199d7d6b), U64(0xbf6ce8a455fa1cd4),
+		U64(0x9cc542eac9edcae5), U64(0x79c16f0e1c356ca3),
+		U64(0x89bfab6fdee48151), U64(0xd4174d1830c5f0ff),
+		U64(0x9258048415eb419d), U64(0x6139d72850520d1c),
+		U64(0x6a85a80c18ec78f1), U64(0xcd11f88e0171059a),
+		U64(0xcceff53e7ca29140), U64(0xd229639f2315af19),
+		U64(0x90b91ef9ef507434), U64(0x5977d28d074a1be1),
+		U64(0x311360fce51d56b9), U64(0xc093a92d5a1f2f91),
+		U64(0x1a19a25bb6dc5416), U64(0xeb996b8a09de2d3e),
+		U64(0xfee3820f1ed7668a), U64(0xd7085ad5b7ad518c),
+		U64(0x7fff41890fe53345), U64(0xec5948bd67dde602),
+		U64(0x2fd5f65dbaaa68e0), U64(0xa5754affe32648c2),
+		U64(0xf8ddac880d07396c), U64(0x6fa491468c548664),
+		U64(0x0c7c5c1326bdbed1), U64(0x4a33158f03930fb3),
+		U64(0x699abfc19f84d982), U64(0xe4fa2054a80b329c),
+		U64(0x6707f9af438252fa), U64(0x08a368e9cfd6d49e),
+		U64(0x47b1442c58fd25b8), U64(0xbbb3dc5ebc91769b),
+		U64(0x1665fe489061eac7), U64(0x33f27a811fa66310),
+		U64(0x93a609346838d547), U64(0x30ed6d4c98cec263),
+		U64(0x1dd9816cd8df9f2a), U64(0x94662a03063b1e7b),
+		U64(0x83fdd9fbeb896066), U64(0x7b207573e68e590a),
+		U64(0x5f49fc0a149a4407), U64(0x343259b671a5a82c),
+		U64(0xfbc2bb458a6f981f), U64(0xc272b350a0a41a38),
+		U64(0x3aaf1fd8ada32354), U64(0x6cbb868b0b3c2717),
+		U64(0xa2b569c88d2583fe), U64(0xf180c9d1bf027928),
+		U64(0xaf37386bd64ba9f5), U64(0x12bacab2790a8088),
+		U64(0x4c0d3b0810435055), U64(0xb2eeb9070e9436df),
+		U64(0xc5b29067cea7d104), U64(0xdcb425f1ff132461),
+		U64(0x4f122cc5972bf126), U64(0xac282fa651230886),
+		U64(0xe7e537992f6393ef), U64(0xe61b3a2952b00735),
+		U64(0x709c0a57ae302ce7), U64(0xe02514ae416058d3),
+		U64(0xc44c9dd7b37445de), U64(0x5a68c5408022ba92),
+		U64(0x1c278cdca50c0bf0), U64(0x6e5a9cf6f18712be),
+		U64(0x86dce0b17f319ef3), U64(0x2d34ec2040115d49),
+		U64(0x4bcd183f7e409b69), U64(0x2815d56ad4a9a3dc),
+		U64(0x24698979f2141d0d), U64(0x0000000000000000),
+		U64(0x1ec696a15fb73e59), U64(0xd86b110b16784e2e),
+		U64(0x8e7f8858b0e74a6d), U64(0x063e2e8713d05fe6),
+		U64(0xe2c40ed3bbdb6d7a), U64(0xb1f1aeca89fc97ac),
+		U64(0xe1db191e3cb3cc09), U64(0x6418ee62c4eaf389),
+		U64(0xc6ad87aa49cf7077), U64(0xd6f65765ca7ec556),
+		U64(0x9afb6c6dda3d9503), U64(0x7ce05644888d9236),
+		U64(0x8d609f95378feb1e), U64(0x23a9aa4e9c17d631),
+		U64(0x6226c0e5d73aac6f), U64(0x56149953a69f0443),
+		U64(0xeeb852c09d66d3ab), U64(0x2b0ac2a753c102af),
+		U64(0x07c023376e03cb3c), U64(0x2ccae1903dc2c993),
+		U64(0xd3d76e2f5ec63bc3), U64(0x9e2458973356ff4c),
+		U64(0xa66a5d32644ee9b1), U64(0x0a427294356de137),
+		U64(0x783f62be61e6f879), U64(0x1344c70204d91452),
+		U64(0x5b96c8f0fdf12e48), U64(0xa90916ecc59bf613),
+		U64(0xbe92e5142829880e), U64(0x727d102a548b194e),
+		U64(0x1be7afebcb0fc0cc), U64(0x3e702b2244c8491b),
+		U64(0xd5e940a84d166425), U64(0x66f9f41f3e51c620),
+		U64(0xabe80c913f20c3ba), U64(0xf07ec461c2d1edf2),
+		U64(0xf361d3ac45b94c81), U64(0x0521394a94b8fe95),
+		U64(0xadd622162cf09c5c), U64(0xe97871f7f3651897),
+		U64(0xf4a1f09b2bba87bd), U64(0x095d6559b2054044),
+		U64(0x0bbc7f2448be75ed), U64(0x2af4cf172e129675),
+		U64(0x157ae98517094bb4), U64(0x9fda55274e856b96),
+		U64(0x914713499283e0ee), U64(0xb952c623462a4332),
+		U64(0x74433ead475b46a8), U64(0x8b5eb112245fb4f8),
+		U64(0xa34b6478f0f61724), U64(0x11a5dd7ffe6221fb),
+		U64(0xc16da49d27ccbb4b), U64(0x76a224d0bde07301),
+		U64(0x8aa0bca2598c2022), U64(0x4df336b86d90c48f),
+		U64(0xea67663a740db9e4), U64(0xef465f70e0b54771),
+		U64(0x39b008152acb8227), U64(0x7d1e5bf4f55e06ec),
+		U64(0x105bd0cf83b1b521), U64(0x775c2960c033e7db),
+		U64(0x7e014c397236a79f), U64(0x811cc386113255cf),
+		U64(0xeda7450d1a0e72d8), U64(0x5889df3d7a998f3b),
+		U64(0x2e2bfbedc779fc3a), U64(0xce0eef438619a4e9),
+		U64(0x372d4e7bf6cd095f), U64(0x04df34fae96b6a4f),
+		U64(0xf923a13870d4adb6), U64(0xa1aa7e050a4d228d),
+		U64(0xa8f71b5cb84862c9), U64(0xb52e9a306097fde3),
+		U64(0x0d8251a35b6e2a0b), U64(0x2257a7fee1c442eb),
+		U64(0x73831d9a29588d94), U64(0x51d4ba64c89ccf7f),
+		U64(0x502ab7d4b54f5ba5), U64(0x97793dce8153bf08),
+		U64(0xe5042de4d5d8a646), U64(0x9687307efc802bd2),
+		U64(0xa05473b5779eb657), U64(0xb4d097801d446939),
+		U64(0xcff0e2f3fbca3033), U64(0xc38cbee0dd778ee2),
+		U64(0x464f499c252eb162), U64(0xcad1dbb96f72cea6),
+		U64(0xba4dd1eec142e241), U64(0xb00fa37af42f0376)
+	}, { /* 2 */
+		U64(0xcce4cd3aa968b245), U64(0x089d5484e80b7faf),
+		U64(0x638246c1b3548304), U64(0xd2fe0ec8c2355492),
+		U64(0xa7fbdf7ff2374eee), U64(0x4df1600c92337a16),
+		U64(0x84e503ea523b12fb), U64(0x0790bbfd53ab0c4a),
+		U64(0x198a780f38f6ea9d), U64(0x2ab30c8f55ec48cb),
+		U64(0xe0f7fed6b2c49db5), U64(0xb6ecf3f422cadbdc),
+		U64(0x409c9a541358df11), U64(0xd3ce8a56dfde3fe3),
+		U64(0xc3e9224312c8c1a0), U64(0x0d6dfa58816ba507),
+		U64(0xddf3e1b179952777), U64(0x04c02a42748bb1d9),
+		U64(0x94c2abff9f2decb8), U64(0x4f91752da8f8acf4),
+		U64(0x78682befb169bf7b), U64(0xe1c77a48af2ff6c4),
+		U64(0x0c5d7ec69c80ce76), U64(0x4cc1e4928fd81167),
+		U64(0xfeed3d24d9997b62), U64(0x518bb6dfc3a54a23),
+		U64(0x6dbf2d26151f9b90), U64(0xb5bc624b05ea664f),
+		U64(0xe86aaa525acfe21a), U64(0x4801ced0fb53a0be),
+		U64(0xc91463e6c00868ed), U64(0x1027a815cd16fe43),
+		U64(0xf67069a0319204cd), U64(0xb04ccc976c8abce7),
+		U64(0xc0b9b3fc35e87c33), U64(0xf380c77c58f2de65),
+		U64(0x50bb3241de4e2152), U64(0xdf93f490435ef195),
+		U64(0xf1e0d25d62390887), U64(0xaf668bfb1a3c3141),
+		U64(0xbc11b251f00a7291), U64(0x73a5eed47e427d47),
+		U64(0x25bee3f6ee4c3b2e), U64(0x43cc0beb34786282),
+		U64(0xc824e778dde3039c), U64(0xf97d86d98a327728),
+		U64(0xf2b043e24519b514), U64(0xe297ebf7880f4b57),
+		U64(0x3a94a49a98fab688), U64(0x868516cb68f0c419),
+		U64(0xeffa11af0964ee50), U64(0xa4ab4ec0d517f37d),
+		U64(0xa9c6b498547c567a), U64(0x8e18424f80fbbbb6),
+		U64(0x0bcdc53bcf2bc23c), U64(0x137739aaea3643d0),
+		U64(0x2c1333ec1bac2ff0), U64(0x8d48d3f0a7db0625),
+		U64(0x1e1ac3f26b5de6d7), U64(0xf520f81f16b2b95e),
+		U64(0x9f0f6ec450062e84), U64(0x0130849e1deb6b71),
+		U64(0xd45e31ab8c7533a9), U64(0x652279a2fd14e43f),
+		U64(0x3209f01e70f1c927), U64(0xbe71a770cac1a473),
+		U64(0x0e3d6be7a64b1894), U64(0x7ec8148cff29d840),
+		U64(0xcb7476c7fac3be0f), U64(0x72956a4a63a91636),
+		U64(0x37f95ec21991138f), U64(0x9e3fea5a4ded45f5),
+		U64(0x7b38ba50964902e8), U64(0x222e580bbde73764),
+		U64(0x61e253e0899f55e6), U64(0xfc8d2805e352ad80),
+		U64(0x35994be3235ac56d), U64(0x09add01af5e014de),
+		U64(0x5e8659a6780539c6), U64(0xb17c48097161d796),
+		U64(0x026015213acbd6e2), U64(0xd1ae9f77e515e901),
+		U64(0xb7dc776a3f21b0ad), U64(0xaba6a1b96eb78098),
+		U64(0x9bcf4486248d9f5d), U64(0x582666c536455efd),
+		U64(0xfdbdac9bfeb9c6f1), U64(0xc47999be4163cdea),
+		U64(0x765540081722a7ef), U64(0x3e548ed8ec710751),
+		U64(0x3d041f67cb51bac2), U64(0x7958af71ac82d40a),
+		U64(0x36c9da5c047a78fe), U64(0xed9a048e33af38b2),
+		U64(0x26ee7249c96c86bd), U64(0x900281bdeba65d61),
+		U64(0x11172c8bd0fd9532), U64(0xea0abf73600434f8),
+		U64(0x42fc8f75299309f3), U64(0x34a9cf7d3eb1ae1c),
+		U64(0x2b838811480723ba), U64(0x5ce64c8742ceef24),
+		U64(0x1adae9b01fd6570e), U64(0x3c349bf9d6bad1b3),
+		U64(0x82453c891c7b75c0), U64(0x97923a40b80d512b),
+		U64(0x4a61dbf1c198765c), U64(0xb48ce6d518010d3e),
+		U64(0xcfb45c858e480fd6), U64(0xd933cbf30d1e96ae),
+		U64(0xd70ea014ab558e3a), U64(0xc189376228031742),
+		U64(0x9262949cd16d8b83), U64(0xeb3a3bed7def5f89),
+		U64(0x49314a4ee6b8cbcf), U64(0xdcc3652f647e4c06),
+		U64(0xda635a4c2a3e2b3d), U64(0x470c21a940f3d35b),
+		U64(0x315961a157d174b4), U64(0x6672e81dda3459ac),
+		U64(0x5b76f77a1165e36e), U64(0x445cb01667d36ec8),
+		U64(0xc5491d205c88a69b), U64(0x456c34887a3805b9),
+		U64(0xffddb9bac4721013), U64(0x99af51a71e4649bf),
+		U64(0xa15be01cbc7729d5), U64(0x52db2760e485f7b0),
+		U64(0x8c78576eba306d54), U64(0xae560f6507d75a30),
+		U64(0x95f22f6182c687c9), U64(0x71c5fbf54489aba5),
+		U64(0xca44f259e728d57e), U64(0x88b87d2ccebbdc8d),
+		U64(0xbab18d32be4a15aa), U64(0x8be8ec93e99b611e),
+		U64(0x17b713e89ebdf209), U64(0xb31c5d284baa0174),
+		U64(0xeeca9531148f8521), U64(0xb8d198138481c348),
+		U64(0x8988f9b2d350b7fc), U64(0xb9e11c8d996aa839),
+		U64(0x5a4673e40c8e881f), U64(0x1687977683569978),
+		U64(0xbf4123eed72acf02), U64(0x4ea1f1b3b513c785),
+		U64(0xe767452be16f91ff), U64(0x7505d1b730021a7c),
+		U64(0xa59bca5ec8fc980c), U64(0xad069eda20f7e7a3),
+		U64(0x38f4b1bba231606a), U64(0x60d2d77e94743e97),
+		U64(0x9affc0183966f42c), U64(0x248e6768f3a7505f),
+		U64(0xcdd449a4b483d934), U64(0x87b59255751baf68),
+		U64(0x1bea6d2e023d3c7f), U64(0x6b1f12455b5ffcab),
+		U64(0x743555292de9710d), U64(0xd8034f6d10f5fddf),
+		U64(0xc6198c9f7ba81b08), U64(0xbb8109aca3a17edb),
+		U64(0xfa2d1766ad12cabb), U64(0xc729080166437079),
+		U64(0x9c5fff7b77269317), U64(0x0000000000000000),
+		U64(0x15d706c9a47624eb), U64(0x6fdf38072fd44d72),
+		U64(0x5fb6dd3865ee52b7), U64(0xa33bf53d86bcff37),
+		U64(0xe657c1b5fc84fa8e), U64(0xaa962527735cebe9),
+		U64(0x39c43525bfda0b1b), U64(0x204e4d2a872ce186),
+		U64(0x7a083ece8ba26999), U64(0x554b9c9db72efbfa),
+		U64(0xb22cd9b656416a05), U64(0x96a2bedea5e63a5a),
+		U64(0x802529a826b0a322), U64(0x8115ad363b5bc853),
+		U64(0x8375b81701901eb1), U64(0x3069e53f4a3a1fc5),
+		U64(0xbd2136cfede119e0), U64(0x18bafc91251d81ec),
+		U64(0x1d4a524d4c7d5b44), U64(0x05f0aedc6960daa8),
+		U64(0x29e39d3072ccf558), U64(0x70f57f6b5962c0d4),
+		U64(0x989fd53903ad22ce), U64(0xf84d024797d91c59),
+		U64(0x547b1803aac5908b), U64(0xf0d056c37fd263f6),
+		U64(0xd56eb535919e58d8), U64(0x1c7ad6d351963035),
+		U64(0x2e7326cd2167f912), U64(0xac361a443d1c8cd2),
+		U64(0x697f076461942a49), U64(0x4b515f6fdc731d2d),
+		U64(0x8ad8680df4700a6f), U64(0x41ac1eca0eb3b460),
+		U64(0x7d988533d80965d3), U64(0xa8f6300649973d0b),
+		U64(0x7765c4960ac9cc9e), U64(0x7ca801adc5e20ea2),
+		U64(0xdea3700e5eb59ae4), U64(0xa06b6482a19c42a4),
+		U64(0x6a2f96db46b497da), U64(0x27def6d7d487edcc),
+		U64(0x463ca5375d18b82a), U64(0xa6cb5be1efdc259f),
+		U64(0x53eba3fef96e9cc1), U64(0xce84d81b93a364a7),
+		U64(0xf4107c810b59d22f), U64(0x333974806d1aa256),
+		U64(0x0f0def79bba073e5), U64(0x231edc95a00c5c15),
+		U64(0xe437d494c64f2c6c), U64(0x91320523f64d3610),
+		U64(0x67426c83c7df32dd), U64(0x6eefbc99323f2603),
+		U64(0x9d6f7be56acdf866), U64(0x5916e25b2bae358c),
+		U64(0x7ff89012e2c2b331), U64(0x035091bf2720bd93),
+		U64(0x561b0d22900e4669), U64(0x28d319ae6f279e29),
+		U64(0x2f43a2533c8c9263), U64(0xd09e1be9f8fe8270),
+		U64(0xf740ed3e2c796fbc), U64(0xdb53ded237d5404c),
+		U64(0x62b2c25faebfe875), U64(0x0afd41a5d2c0a94d),
+		U64(0x6412fd3ce0ff8f4e), U64(0xe3a76f6995e42026),
+		U64(0x6c8fa9b808f4f0e1), U64(0xc2d9a6dd0f23aad1),
+		U64(0x8f28c6d19d10d0c7), U64(0x85d587744fd0798a),
+		U64(0xa20b71a39b579446), U64(0x684f83fa7c7f4138),
+		U64(0xe507500adba4471d), U64(0x3f640a46f19a6c20),
+		U64(0x1247bd34f7dd28a1), U64(0x2d23b77206474481),
+		U64(0x93521002cc86e0f2), U64(0x572b89bc8de52d18),
+		U64(0xfb1d93f8b0f9a1ca), U64(0xe95a2ecc4724896b),
+		U64(0x3ba420048511ddf9), U64(0xd63e248ab6bee54b),
+		U64(0x5dd6c8195f258455), U64(0x06a03f634e40673b),
+		U64(0x1f2a476c76b68da6), U64(0x217ec9b49ac78af7),
+		U64(0xecaa80102e4453c3), U64(0x14e78257b99d4f9a)
+	}, { /* 3 */
+		U64(0x20329b2cc87bba05), U64(0x4f5eb6f86546a531),
+		U64(0xd4f44775f751b6b1), U64(0x8266a47b850dfa8b),
+		U64(0xbb986aa15a6ca985), U64(0xc979eb08f9ae0f99),
+		U64(0x2da6f447a2375ea1), U64(0x1e74275dcd7d8576),
+		U64(0xbc20180a800bc5f8), U64(0xb4a2f701b2dc65be),
+		U64(0xe726946f981b6d66), U64(0x48e6c453bf21c94c),
+		U64(0x42cad9930f0a4195), U64(0xefa47b64aacccd20),
+		U64(0x71180a8960409a42), U64(0x8bb3329bf6a44e0c),
+		U64(0xd34c35de2d36dacc), U64(0xa92f5b7cbc23dc96),
+		U64(0xb31a85aa68bb09c3), U64(0x13e04836a73161d2),
+		U64(0xb24dfc4129c51d02), U64(0x8ae44b70b7da5acd),
+		U64(0xe671ed84d96579a7), U64(0xa4bb3417d66f3832),
+		U64(0x4572ab38d56d2de8), U64(0xb1b47761ea47215c),
+		U64(0xe81c09cf70aba15d), U64(0xffbdb872ce7f90ac),
+		U64(0xa8782297fd5dc857), U64(0x0d946f6b6a4ce4a4),
+		U64(0xe4df1f4f5b995138), U64(0x9ebc71edca8c5762),
+		U64(0x0a2c1dc0b02b88d9), U64(0x3b503c115d9d7b91),
+		U64(0xc64376a8111ec3a2), U64(0xcec199a323c963e4),
+		U64(0xdc76a87ec58616f7), U64(0x09d596e073a9b487),
+		U64(0x14583a9d7d560daf), U64(0xf4c6dc593f2a0cb4),
+		U64(0xdd21d19584f80236), U64(0x4a4836983ddde1d3),
+		U64(0xe58866a41ae745f9), U64(0xf591a5b27e541875),
+		U64(0x891dc05074586693), U64(0x5b068c651810a89e),
+		U64(0xa30346bc0c08544f), U64(0x3dbf3751c684032d),
+		U64(0x2a1e86ec785032dc), U64(0xf73f5779fca830ea),
+		U64(0xb60c05ca30204d21), U64(0x0cc316802b32f065),
+		U64(0x8770241bdd96be69), U64(0xb861e18199ee95db),
+		U64(0xf805cad91418fcd1), U64(0x29e70dccbbd20e82),
+		U64(0xc7140f435060d763), U64(0x0f3a9da0e8b0cc3b),
+		U64(0xa2543f574d76408e), U64(0xbd7761e1c175d139),
+		U64(0x4b1f4f737ca3f512), U64(0x6dc2df1f2fc137ab),
+		U64(0xf1d05c3967b14856), U64(0xa742bf3715ed046c),
+		U64(0x654030141d1697ed), U64(0x07b872abda676c7d),
+		U64(0x3ce84eba87fa17ec), U64(0xc1fb0403cb79afdf),
+		U64(0x3e46bc7105063f73), U64(0x278ae987121cd678),
+		U64(0xa1adb4778ef47cd0), U64(0x26dd906c5362c2b9),
+		U64(0x05168060589b44e2), U64(0xfbfc41f9d79ac08f),
+		U64(0x0e6de44ba9ced8fa), U64(0x9feb08068bf243a3),
+		U64(0x7b341749d06b129b), U64(0x229c69e74a87929a),
+		U64(0xe09ee6c4427c011b), U64(0x5692e30e725c4c3a),
+		U64(0xda99a33e5e9f6e4b), U64(0x353dd85af453a36b),
+		U64(0x25241b4c90e0fee7), U64(0x5de987258309d022),
+		U64(0xe230140fc0802984), U64(0x93281e86a0c0b3c6),
+		U64(0xf229d719a4337408), U64(0x6f6c2dd4ad3d1f34),
+		U64(0x8ea5b2fbae3f0aee), U64(0x8331dd90c473ee4a),
+		U64(0x346aa1b1b52db7aa), U64(0xdf8f235e06042aa9),
+		U64(0xcc6f6b68a1354b7b), U64(0x6c95a6f46ebf236a),
+		U64(0x52d31a856bb91c19), U64(0x1a35ded6d498d555),
+		U64(0xf37eaef2e54d60c9), U64(0x72e181a9a3c2a61c),
+		U64(0x98537aad51952fde), U64(0x16f6c856ffaa2530),
+		U64(0xd960281e9d1d5215), U64(0x3a0745fa1ce36f50),
+		U64(0x0b7b642bf1559c18), U64(0x59a87eae9aec8001),
+		U64(0x5e100c05408bec7c), U64(0x0441f98b19e55023),
+		U64(0xd70dcc5534d38aef), U64(0x927f676de1bea707),
+		U64(0x9769e70db925e3e5), U64(0x7a636ea29115065a),
+		U64(0x468b201816ef11b6), U64(0xab81a9b73edff409),
+		U64(0xc0ac7de88a07bb1e), U64(0x1f235eb68c0391b7),
+		U64(0x6056b074458dd30f), U64(0xbe8eeac102f7ed67),
+		U64(0xcd381283e04b5fba), U64(0x5cbefecec277c4e3),
+		U64(0xd21b4c356c48ce0d), U64(0x1019c31664b35d8c),
+		U64(0x247362a7d19eea26), U64(0xebe582efb3299d03),
+		U64(0x02aef2cb82fc289f), U64(0x86275df09ce8aaa8),
+		U64(0x28b07427faac1a43), U64(0x38a9b7319e1f47cf),
+		U64(0xc82e92e3b8d01b58), U64(0x06ef0b409b1978bc),
+		U64(0x62f842bfc771fb90), U64(0x9904034610eb3b1f),
+		U64(0xded85ab5477a3e68), U64(0x90d195a663428f98),
+		U64(0x5384636e2ac708d8), U64(0xcbd719c37b522706),
+		U64(0xae9729d76644b0eb), U64(0x7c8c65e20a0c7ee6),
+		U64(0x80c856b007f1d214), U64(0x8c0b40302cc32271),
+		U64(0xdbcedad51fe17a8a), U64(0x740e8ae938dbdea0),
+		U64(0xa615c6dc549310ad), U64(0x19cc55f6171ae90b),
+		U64(0x49b1bdb8fe5fdd8d), U64(0xed0a89af2830e5bf),
+		U64(0x6a7aadb4f5a65bd6), U64(0x7e22972988f05679),
+		U64(0xf952b3325566e810), U64(0x39fecedadf61530e),
+		U64(0x6101c99f04f3c7ce), U64(0x2e5f7f6761b562ff),
+		U64(0xf08725d226cf5c97), U64(0x63af3b54860fef51),
+		U64(0x8ff2cb10ef411e2f), U64(0x884ab9bb35267252),
+		U64(0x4df04433e7ba8dae), U64(0x9afd8866d3690741),
+		U64(0x66b9bb34de94abb3), U64(0x9baaf18d92171380),
+		U64(0x543c11c5f0a064a5), U64(0x17a1b1bdbed431f1),
+		U64(0xb5f58eeaf3a2717f), U64(0xc355f6c849858740),
+		U64(0xec5df044694ef17e), U64(0xd83751f5dc6346d4),
+		U64(0xfc4433520dfdacf2), U64(0x0000000000000000),
+		U64(0x5a51f58e596ebc5f), U64(0x3285aaf12e34cf16),
+		U64(0x8d5c39db6dbd36b0), U64(0x12b731dde64f7513),
+		U64(0x94906c2d7aa7dfbb), U64(0x302b583aacc8e789),
+		U64(0x9d45facd090e6b3c), U64(0x2165e2c78905aec4),
+		U64(0x68d45f7f775a7349), U64(0x189b2c1d5664fdca),
+		U64(0xe1c99f2f030215da), U64(0x6983269436246788),
+		U64(0x8489af3b1e148237), U64(0xe94b702431d5b59c),
+		U64(0x33d2d31a6f4adbd7), U64(0xbfd9932a4389f9a6),
+		U64(0xb0e30e8aab39359d), U64(0xd1e2c715afcaf253),
+		U64(0x150f43763c28196e), U64(0xc4ed846393e2eb3d),
+		U64(0x03f98b20c3823c5e), U64(0xfd134ab94c83b833),
+		U64(0x556b682eb1de7064), U64(0x36c4537a37d19f35),
+		U64(0x7559f30279a5ca61), U64(0x799ae58252973a04),
+		U64(0x9c12832648707ffd), U64(0x78cd9c6913e92ec5),
+		U64(0x1d8dac7d0effb928), U64(0x439da0784e745554),
+		U64(0x413352b3cc887dcb), U64(0xbacf134a1b12bd44),
+		U64(0x114ebafd25cd494d), U64(0x2f08068c20cb763e),
+		U64(0x76a07822ba27f63f), U64(0xeab2fb04f25789c2),
+		U64(0xe3676de481fe3d45), U64(0x1b62a73d95e6c194),
+		U64(0x641749ff5c68832c), U64(0xa5ec4dfc97112cf3),
+		U64(0xf6682e92bdd6242b), U64(0x3f11c59a44782bb2),
+		U64(0x317c21d1edb6f348), U64(0xd65ab5be75ad9e2e),
+		U64(0x6b2dd45fb4d84f17), U64(0xfaab381296e4d44e),
+		U64(0xd0b5befeeeb4e692), U64(0x0882ef0b32d7a046),
+		U64(0x512a91a5a83b2047), U64(0x963e9ee6f85bf724),
+		U64(0x4e09cf132438b1f0), U64(0x77f701c9fb59e2fe),
+		U64(0x7ddb1c094b726a27), U64(0x5f4775ee01f5f8bd),
+		U64(0x9186ec4d223c9b59), U64(0xfeeac1998f01846d),
+		U64(0xac39db1ce4b89874), U64(0xb75b7c21715e59e0),
+		U64(0xafc0503c273aa42a), U64(0x6e3b543fec430bf5),
+		U64(0x704f7362213e8e83), U64(0x58ff0745db9294c0),
+		U64(0x67eec2df9feabf72), U64(0xa0facd9ccf8a6811),
+		U64(0xb936986ad890811a), U64(0x95c715c63bd9cb7a),
+		U64(0xca8060283a2c33c7), U64(0x507de84ee9453486),
+		U64(0x85ded6d05f6a96f6), U64(0x1cdad5964f81ade9),
+		U64(0xd5a33e9eb62fa270), U64(0x40642b588df6690a),
+		U64(0x7f75eec2c98e42b8), U64(0x2cf18dace3494a60),
+		U64(0x23cb100c0bf9865b), U64(0xeef3028febb2d9e1),
+		U64(0x4425d2d394133929), U64(0xaad6d05c7fa1e0c8),
+		U64(0xad6ea2f7a5c68cb5), U64(0xc2028f2308fb9381),
+		U64(0x819f2f5b468fc6d5), U64(0xc5bafd88d29cfffc),
+		U64(0x47dc59f357910577), U64(0x2b49ff07392e261d),
+		U64(0x57c59ae5332258fb), U64(0x73b6f842e2bcb2dd),
+		U64(0xcf96e04862b77725), U64(0x4ca73dd8a6c4996f),
+		U64(0x015779eb417e14c1), U64(0x37932a9176af8bf4)
+	}, { /* 4 */
+		U64(0x190a2c9b249df23e), U64(0x2f62f8b62263e1e9),
+		U64(0x7a7f754740993655), U64(0x330b7ba4d5564d9f),
+		U64(0x4c17a16a46672582), U64(0xb22f08eb7d05f5b8),
+		U64(0x535f47f40bc148cc), U64(0x3aec5d27d4883037),
+		U64(0x10ed0a1825438f96), U64(0x516101f72c233d17),
+		U64(0x13cc6f949fd04eae), U64(0x739853c441474bfd),
+		U64(0x653793d90d3f5b1b), U64(0x5240647b96b0fc2f),
+		U64(0x0c84890ad27623e0), U64(0xd7189b32703aaea3),
+		U64(0x2685de3523bd9c41), U64(0x99317c5b11bffefa),
+		U64(0x0d9baa854f079703), U64(0x70b93648fbd48ac5),
+		U64(0xa80441fce30bc6be), U64(0x7287704bdc36ff1e),
+		U64(0xb65384ed33dc1f13), U64(0xd36417343ee34408),
+		U64(0x39cd38ab6e1bf10f), U64(0x5ab861770a1f3564),
+		U64(0x0ebacf09f594563b), U64(0xd04572b884708530),
+		U64(0x3cae9722bdb3af47), U64(0x4a556b6f2f5cbaf2),
+		U64(0xe1704f1f76c4bd74), U64(0x5ec4ed7144c6dfcf),
+		U64(0x16afc01d4c7810e6), U64(0x283f113cd629ca7a),
+		U64(0xaf59a8761741ed2d), U64(0xeed5a3991e215fac),
+		U64(0x3bf37ea849f984d4), U64(0xe413e096a56ce33c),
+		U64(0x2c439d3a98f020d1), U64(0x637559dc6404c46b),
+		U64(0x9e6c95d1e5f5d569), U64(0x24bb9836045fe99a),
+		U64(0x44efa466dac8ecc9), U64(0xc6eab2a5c80895d6),
+		U64(0x803b50c035220cc4), U64(0x0321658cba93c138),
+		U64(0x8f9ebc465dc7ee1c), U64(0xd15a5137190131d3),
+		U64(0x0fa5ec8668e5e2d8), U64(0x91c979578d1037b1),
+		U64(0x0642ca05693b9f70), U64(0xefca80168350eb4f),
+		U64(0x38d21b24f36a45ec), U64(0xbeab81e1af73d658),
+		U64(0x8cbfd9cae7542f24), U64(0xfd19cc0d81f11102),
+		U64(0x0ac6430fbb4dbc90), U64(0x1d76a09d6a441895),
+		U64(0x2a01573ff1cbbfa1), U64(0xb572e161894fde2b),
+		U64(0x8124734fa853b827), U64(0x614b1fdf43e6b1b0),
+		U64(0x68ac395c4238cc18), U64(0x21d837bfd7f7b7d2),
+		U64(0x20c714304a860331), U64(0x5cfaab726324aa14),
+		U64(0x74c5ba4eb50d606e), U64(0xf3a3030474654739),
+		U64(0x23e671bcf015c209), U64(0x45f087e947b9582a),
+		U64(0xd8bd77b418df4c7b), U64(0xe06f6c90ebb50997),
+		U64(0x0bd96080263c0873), U64(0x7e03f9410e40dcfe),
+		U64(0xb8e94be4c6484928), U64(0xfb5b0608e8ca8e72),
+		U64(0x1a2b49179e0e3306), U64(0x4e29e76961855059),
+		U64(0x4f36c4e6fcf4e4ba), U64(0x49740ee395cf7bca),
+		U64(0xc2963ea386d17f7d), U64(0x90d65ad810618352),
+		U64(0x12d34c1b02a1fa4d), U64(0xfa44258775bb3a91),
+		U64(0x18150f14b9ec46dd), U64(0x1491861e6b9a653d),
+		U64(0x9a1019d7ab2c3fc2), U64(0x3668d42d06fe13d7),
+		U64(0xdcc1fbb25606a6d0), U64(0x969490dd795a1c22),
+		U64(0x3549b1a1bc6dd2ef), U64(0xc94f5e23a0ed770e),
+		U64(0xb9f6686b5b39fdcb), U64(0xc4d4f4a6efeae00d),
+		U64(0xe732851a1fff2204), U64(0x94aad6de5eb869f9),
+		U64(0x3f8ff2ae07206e7f), U64(0xfe38a9813b62d03a),
+		U64(0xa7a1ad7a8bee2466), U64(0x7b6056c8dde882b6),
+		U64(0x302a1e286fc58ca7), U64(0x8da0fa457a259bc7),
+		U64(0xb3302b64e074415b), U64(0x5402ae7eff8b635f),
+		U64(0x08f8050c9cafc94b), U64(0xae468bf98a3059ce),
+		U64(0x88c355cca98dc58f), U64(0xb10e6d67c7963480),
+		U64(0xbad70de7e1aa3cf3), U64(0xbfb4a26e320262bb),
+		U64(0xcb711820870f02d5), U64(0xce12b7a954a75c9d),
+		U64(0x563ce87dd8691684), U64(0x9f73b65e7884618a),
+		U64(0x2b1e74b06cba0b42), U64(0x47cec1ea605b2df1),
+		U64(0x1c698312f735ac76), U64(0x5fdbcefed9b76b2c),
+		U64(0x831a354c8fb1cdfc), U64(0x820516c312c0791f),
+		U64(0xb74ca762aeadabf0), U64(0xfc06ef821c80a5e1),
+		U64(0x5723cbf24518a267), U64(0x9d4df05d5f661451),
+		U64(0x588627742dfd40bf), U64(0xda8331b73f3d39a0),
+		U64(0x17b0e392d109a405), U64(0xf965400bcf28fba9),
+		U64(0x7c3dbf4229a2a925), U64(0x023e460327e275db),
+		U64(0x6cd0b55a0ce126b3), U64(0xe62da695828e96e7),
+		U64(0x42ad6e63b3f373b9), U64(0xe50cc319381d57df),
+		U64(0xc5cbd729729b54ee), U64(0x46d1e265fd2a9912),
+		U64(0x6428b056904eeff8), U64(0x8be23040131e04b7),
+		U64(0x6709d5da2add2ec0), U64(0x075de98af44a2b93),
+		U64(0x8447dcc67bfbe66f), U64(0x6616f655b7ac9a23),
+		U64(0xd607b8bded4b1a40), U64(0x0563af89d3a85e48),
+		U64(0x3db1b4ad20c21ba4), U64(0x11f22997b8323b75),
+		U64(0x292032b34b587e99), U64(0x7f1cdace9331681d),
+		U64(0x8e819fc9c0b65aff), U64(0xa1e3677fe2d5bb16),
+		U64(0xcd33d225ee349da5), U64(0xd9a2543b85aef898),
+		U64(0x795e10cbfa0af76d), U64(0x25a4bbb9992e5d79),
+		U64(0x78413344677b438e), U64(0xf0826688cef68601),
+		U64(0xd27b34bba392f0eb), U64(0x551d8df162fad7bc),
+		U64(0x1e57c511d0d7d9ad), U64(0xdeffbdb171e4d30b),
+		U64(0xf4feea8e802f6caa), U64(0xa480c8f6317de55e),
+		U64(0xa0fc44f07fa40ff5), U64(0x95b5f551c3c9dd1a),
+		U64(0x22f952336d6476ea), U64(0x0000000000000000),
+		U64(0xa6be8ef5169f9085), U64(0xcc2cf1aa73452946),
+		U64(0x2e7ddb39bf12550a), U64(0xd526dd3157d8db78),
+		U64(0x486b2d6c08becf29), U64(0x9b0f3a58365d8b21),
+		U64(0xac78cdfaadd22c15), U64(0xbc95c7e28891a383),
+		U64(0x6a927f5f65dab9c3), U64(0xc3891d2c1ba0cb9e),
+		U64(0xeaa92f9f50f8b507), U64(0xcf0d9426c9d6e87e),
+		U64(0xca6e3baf1a7eb636), U64(0xab25247059980786),
+		U64(0x69b31ad3df4978fb), U64(0xe2512a93cc577c4c),
+		U64(0xff278a0ea61364d9), U64(0x71a615c766a53e26),
+		U64(0x89dc764334fc716c), U64(0xf87a638452594f4a),
+		U64(0xf2bc208be914f3da), U64(0x8766b94ac1682757),
+		U64(0xbbc82e687cdb8810), U64(0x626a7a53f9757088),
+		U64(0xa2c202f358467a2e), U64(0x4d0882e5db169161),
+		U64(0x09e7268301de7da8), U64(0xe897699c771ac0dc),
+		U64(0xc8507dac3d9cc3ed), U64(0xc0a878a0a1330aa6),
+		U64(0x978bb352e42ba8c1), U64(0xe9884a13ea6b743f),
+		U64(0x279afdbabecc28a2), U64(0x047c8c064ed9eaab),
+		U64(0x507e2278b15289f4), U64(0x599904fbb08cf45c),
+		U64(0xbd8ae46d15e01760), U64(0x31353da7f2b43844),
+		U64(0x8558ff49e68a528c), U64(0x76fbfc4d92ef15b5),
+		U64(0x3456922e211c660c), U64(0x86799ac55c1993b4),
+		U64(0x3e90d1219a51da9c), U64(0x2d5cbeb505819432),
+		U64(0x982e5fd48cce4a19), U64(0xdb9c1238a24c8d43),
+		U64(0xd439febecaa96f9b), U64(0x418c0bef0960b281),
+		U64(0x158ea591f6ebd1de), U64(0x1f48e69e4da66d4e),
+		U64(0x8afd13cf8e6fb054), U64(0xf5e1c9011d5ed849),
+		U64(0xe34e091c5126c8af), U64(0xad67ee7530a398f6),
+		U64(0x43b24dec2e82c75a), U64(0x75da99c1287cd48d),
+		U64(0x92e81cdb3783f689), U64(0xa3dd217cc537cecd),
+		U64(0x60543c50de970553), U64(0x93f73f54aaf2426a),
+		U64(0xa91b62737e7a725d), U64(0xf19d4507538732e2),
+		U64(0x77e4dfc20f9ea156), U64(0x7d229ccdb4d31dc6),
+		U64(0x1b346a98037f87e5), U64(0xedf4c615a4b29e94),
+		U64(0x4093286094110662), U64(0xb0114ee85ae78063),
+		U64(0x6ff1d0d6b672e78b), U64(0x6dcf96d591909250),
+		U64(0xdfe09e3eec9567e8), U64(0x3214582b4827f97c),
+		U64(0xb46dc2ee143e6ac8), U64(0xf6c0ac8da7cd1971),
+		U64(0xebb60c10cd8901e4), U64(0xf7df8f023abcad92),
+		U64(0x9c52d3d2c217a0b2), U64(0x6b8d5cd0f8ab0d20),
+		U64(0x3777f7a29b8fa734), U64(0x011f238f9d71b4e3),
+		U64(0xc1b75b2f3c42be45), U64(0x5de588fdfe551ef7),
+		U64(0x6eeef3592b035368), U64(0xaa3a07ffc4e9b365),
+		U64(0xecebe59a39c32a77), U64(0x5ba742f8976e8187),
+		U64(0x4b4a48e0b22d0e11), U64(0xddded83dcb771233),
+		U64(0xa59feb79ac0c51bd), U64(0xc7f5912a55792135)
+	}, { /* 5 */
+		U64(0x6d6ae04668a9b08a), U64(0x3ab3f04b0be8c743),
+		U64(0xe51e166b54b3c908), U64(0xbe90a9eb35c2f139),
+		U64(0xb2c7066637f2bec1), U64(0xaa6945613392202c),
+		U64(0x9a28c36f3b5201eb), U64(0xddce5a93ab536994),
+		U64(0x0e34133ef6382827), U64(0x52a02ba1ec55048b),
+		U64(0xa2f88f97c4b2a177), U64(0x8640e513ca2251a5),
+		U64(0xcdf1d36258137622), U64(0xfe6cb708dedf8ddb),
+		U64(0x8a174a9ec8121e5d), U64(0x679896036b81560e),
+		U64(0x59ed033395795fee), U64(0x1dd778ab8b74edaf),
+		U64(0xee533ef92d9f926d), U64(0x2a8c79baf8a8d8f5),
+		U64(0x6bcf398e69b119f6), U64(0xe20491742fafdd95),
+		U64(0x276488e0809c2aec), U64(0xea955b82d88f5cce),
+		U64(0x7102c63a99d9e0c4), U64(0xf9763017a5c39946),
+		U64(0x429fa2501f151b3d), U64(0x4659c72bea05d59e),
+		U64(0x984b7fdccf5a6634), U64(0xf742232953fbb161),
+		U64(0x3041860e08c021c7), U64(0x747bfd9616cd9386),
+		U64(0x4bb1367192312787), U64(0x1b72a1638a6c44d3),
+		U64(0x4a0e68a6e8359a66), U64(0x169a5039f258b6ca),
+		U64(0xb98a2ef44edee5a4), U64(0xd9083fe85e43a737),
+		U64(0x967f6ce239624e13), U64(0x8874f62d3c1a7982),
+		U64(0x3c1629830af06e3f), U64(0x9165ebfd427e5a8e),
+		U64(0xb5dd81794ceeaa5c), U64(0x0de8f15a7834f219),
+		U64(0x70bd98ede3dd5d25), U64(0xaccc9ca9328a8950),
+		U64(0x56664eda1945ca28), U64(0x221db34c0f8859ae),
+		U64(0x26dbd637fa98970d), U64(0x1acdffb4f068f932),
+		U64(0x4585254f64090fa0), U64(0x72de245e17d53afa),
+		U64(0x1546b25d7c546cf4), U64(0x207e0ffffb803e71),
+		U64(0xfaaad2732bcf4378), U64(0xb462dfae36ea17bd),
+		U64(0xcf926fd1ac1b11fd), U64(0xe0672dc7dba7ba4a),
+		U64(0xd3fa49ad5d6b41b3), U64(0x8ba81449b216a3bc),
+		U64(0x14f9ec8a0650d115), U64(0x40fc1ee3eb1d7ce2),
+		U64(0x23a2ed9b758ce44f), U64(0x782c521b14fddc7e),
+		U64(0x1c68267cf170504e), U64(0xbcf31558c1ca96e6),
+		U64(0xa781b43b4ba6d235), U64(0xf6fd7dfe29ff0c80),
+		U64(0xb0a4bad5c3fad91e), U64(0xd199f51ea963266c),
+		U64(0x414340349119c103), U64(0x5405f269ed4dadf7),
+		U64(0xabd61bb649969dcd), U64(0x6813dbeae7bdc3c8),
+		U64(0x65fb2ab09f8931d1), U64(0xf1e7fae152e3181d),
+		U64(0xc1a67cef5a2339da), U64(0x7a4feea8e0f5bba1),
+		U64(0x1e0b9acf05783791), U64(0x5b8ebf8061713831),
+		U64(0x80e53cdbcb3af8d9), U64(0x7e898bd315e57502),
+		U64(0xc6bcfbf0213f2d47), U64(0x95a38e86b76e942d),
+		U64(0x092e94218d243cba), U64(0x8339debf453622e7),
+		U64(0xb11be402b9fe64ff), U64(0x57d9100d634177c9),
+		U64(0xcc4e8db52217cbc3), U64(0x3b0cae9c71ec7aa2),
+		U64(0xfb158ca451cbfe99), U64(0x2b33276d82ac6514),
+		U64(0x01bf5ed77a04bde1), U64(0xc5601994af33f779),
+		U64(0x75c4a3416cc92e67), U64(0xf3844652a6eb7fc2),
+		U64(0x3487e375fdd0ef64), U64(0x18ae430704609eed),
+		U64(0x4d14efb993298efb), U64(0x815a620cb13e4538),
+		U64(0x125c354207487869), U64(0x9eeea614ce42cf48),
+		U64(0xce2d3106d61fac1c), U64(0xbbe99247bad6827b),
+		U64(0x071a871f7b1c149d), U64(0x2e4a1cc10db81656),
+		U64(0x77a71ff298c149b8), U64(0x06a5d9c80118a97c),
+		U64(0xad73c27e488e34b1), U64(0x443a7b981e0db241),
+		U64(0xe3bbcfa355ab6074), U64(0x0af276450328e684),
+		U64(0x73617a896dd1871b), U64(0x58525de4ef7de20f),
+		U64(0xb7be3dcab8e6cd83), U64(0x19111dd07e64230c),
+		U64(0x842359a03e2a367a), U64(0x103f89f1f3401fb6),
+		U64(0xdc710444d157d475), U64(0xb835702334da5845),
+		U64(0x4320fc876511a6dc), U64(0xd026abc9d3679b8d),
+		U64(0x17250eee885c0b2b), U64(0x90dab52a387ae76f),
+		U64(0x31fed8d972c49c26), U64(0x89cba8fa461ec463),
+		U64(0x2ff5421677bcabb7), U64(0x396f122f85e41d7d),
+		U64(0xa09b332430bac6a8), U64(0xc888e8ced7070560),
+		U64(0xaeaf201ac682ee8f), U64(0x1180d7268944a257),
+		U64(0xf058a43628e7a5fc), U64(0xbd4c4b8fbbce2b07),
+		U64(0xa1246df34abe7b49), U64(0x7d5569b79be9af3c),
+		U64(0xa9b5a705bd9efa12), U64(0xdb6b835baa4bc0e8),
+		U64(0x05793bac8f147342), U64(0x21c1512881848390),
+		U64(0xfdb0556c50d357e5), U64(0x613d4fcb6a99ff72),
+		U64(0x03dce2648e0cda3e), U64(0xe949b9e6568386f0),
+		U64(0xfc0f0bbb2ad7ea04), U64(0x6a70675913b5a417),
+		U64(0x7f36d5046fe1c8e3), U64(0x0c57af8d02304ff8),
+		U64(0x32223abdfcc84618), U64(0x0891caf6f720815b),
+		U64(0xa63eeaec31a26fd4), U64(0x2507345374944d33),
+		U64(0x49d28ac266394058), U64(0xf5219f9aa7f3d6be),
+		U64(0x2d96fea583b4cc68), U64(0x5a31e1571b7585d0),
+		U64(0x8ed12fe53d02d0fe), U64(0xdfade6205f5b0e4b),
+		U64(0x4cabb16ee92d331a), U64(0x04c6657bf510cea3),
+		U64(0xd73c2cd6a87b8f10), U64(0xe1d87310a1a307ab),
+		U64(0x6cd5be9112ad0d6b), U64(0x97c032354366f3f2),
+		U64(0xd4e0ceb22677552e), U64(0x0000000000000000),
+		U64(0x29509bde76a402cb), U64(0xc27a9e8bd42fe3e4),
+		U64(0x5ef7842cee654b73), U64(0xaf107ecdbc86536e),
+		U64(0x3fcacbe784fcb401), U64(0xd55f90655c73e8cf),
+		U64(0xe6c2f40fdabf1336), U64(0xe8f6e7312c873b11),
+		U64(0xeb2a0555a28be12f), U64(0xe4a148bc2eb774e9),
+		U64(0x9b979db84156bc0a), U64(0x6eb60222e6a56ab4),
+		U64(0x87ffbbc4b026ec44), U64(0xc703a5275b3b90a6),
+		U64(0x47e699fc9001687f), U64(0x9c8d1aa73a4aa897),
+		U64(0x7cea3760e1ed12dd), U64(0x4ec80ddd1d2554c5),
+		U64(0x13e36b957d4cc588), U64(0x5d2b66486069914d),
+		U64(0x92b90999cc7280b0), U64(0x517cc9c56259deb5),
+		U64(0xc937b619ad03b881), U64(0xec30824ad997f5b2),
+		U64(0xa45d565fc5aa080b), U64(0xd6837201d27f32f1),
+		U64(0x635ef3789e9198ad), U64(0x531f75769651b96a),
+		U64(0x4f77530a6721e924), U64(0x486dd4151c3dfdb9),
+		U64(0x5f48dafb9461f692), U64(0x375b011173dc355a),
+		U64(0x3da9775470f4d3de), U64(0x8d0dcd81b30e0ac0),
+		U64(0x36e45fc609d888bb), U64(0x55baacbe97491016),
+		U64(0x8cb29356c90ab721), U64(0x76184125e2c5f459),
+		U64(0x99f4210bb55edbd5), U64(0x6f095cf59ca1d755),
+		U64(0x9f51f8c3b44672a9), U64(0x3538bda287d45285),
+		U64(0x50c39712185d6354), U64(0xf23b1885dcefc223),
+		U64(0x79930ccc6ef9619f), U64(0xed8fdc9da3934853),
+		U64(0xcb540aaa590bdf5e), U64(0x5c94389f1a6d2cac),
+		U64(0xe77daad8a0bbaed7), U64(0x28efc5090ca0bf2a),
+		U64(0xbf2ff73c4fc64cd8), U64(0xb37858b14df60320),
+		U64(0xf8c96ec0dfc724a7), U64(0x828680683f329f06),
+		U64(0x941cd051cd6a29cc), U64(0xc3c5c05cae2b5e05),
+		U64(0xb601631dc2e27062), U64(0xc01922382027843b),
+		U64(0x24b86a840e90f0d2), U64(0xd245177a276ffc52),
+		U64(0x0f8b4de98c3c95c6), U64(0x3e759530fef809e0),
+		U64(0x0b4d2892792c5b65), U64(0xc4df4743d5374a98),
+		U64(0xa5e20888bfaeb5ea), U64(0xba56cc90c0d23f9a),
+		U64(0x38d04cf8ffe0a09c), U64(0x62e1adafe495254c),
+		U64(0x0263bcb3f40867df), U64(0xcaeb547d230f62bf),
+		U64(0x6082111c109d4293), U64(0xdad4dd8cd04f7d09),
+		U64(0xefec602e579b2f8c), U64(0x1fb4c4187f7c8a70),
+		U64(0xffd3e9dfa4db303a), U64(0x7bf0b07f9af10640),
+		U64(0xf49ec14dddf76b5f), U64(0x8f6e713247066d1f),
+		U64(0x339d646a86ccfbf9), U64(0x64447467e58d8c30),
+		U64(0x2c29a072f9b07189), U64(0xd8b7613f24471ad6),
+		U64(0x6627c8d41185ebef), U64(0xa347d140beb61c96),
+		U64(0xde12b8f7255fb3aa), U64(0x9d324470404e1576),
+		U64(0x9306574eb6763d51), U64(0xa80af9d2c79a47f3),
+		U64(0x859c0777442e8b9b), U64(0x69ac853d9db97e29)
+	}, { /* 6 */
+		U64(0xc3407dfc2de6377e), U64(0x5b9e93eea4256f77),
+		U64(0xadb58fdd50c845e0), U64(0x5219ff11a75bed86),
+		U64(0x356b61cfd90b1de9), U64(0xfb8f406e25abe037),
+		U64(0x7a5a0231c0f60796), U64(0x9d3cd216e1f5020b),
+		U64(0x0c6550fb6b48d8f3), U64(0xf57508c427ff1c62),
+		U64(0x4ad35ffa71cb407d), U64(0x6290a2da1666aa6d),
+		U64(0xe284ec2349355f9f), U64(0xb3c307c53d7c84ec),
+		U64(0x05e23c0468365a02), U64(0x190bac4d6c9ebfa8),
+		U64(0x94bbbee9e28b80fa), U64(0xa34fc777529cb9b5),
+		U64(0xcc7b39f095bcd978), U64(0x2426addb0ce532e3),
+		U64(0x7e79329312ce4fc7), U64(0xab09a72eebec2917),
+		U64(0xf8d15499f6b9d6c2), U64(0x1a55b8babf8c895d),
+		U64(0xdb8add17fb769a85), U64(0xb57f2f368658e81b),
+		U64(0x8acd36f18f3f41f6), U64(0x5ce3b7bba50f11d3),
+		U64(0x114dcc14d5ee2f0a), U64(0xb91a7fcded1030e8),
+		U64(0x81d5425fe55de7a1), U64(0xb6213bc1554adeee),
+		U64(0x80144ef95f53f5f2), U64(0x1e7688186db4c10c),
+		U64(0x3b912965db5fe1bc), U64(0xc281715a97e8252d),
+		U64(0x54a5d7e21c7f8171), U64(0x4b12535ccbc5522e),
+		U64(0x1d289cefbea6f7f9), U64(0x6ef5f2217d2e729e),
+		U64(0xe6a7dc819b0d17ce), U64(0x1b94b41c05829b0e),
+		U64(0x33d7493c622f711e), U64(0xdcf7f942fa5ce421),
+		U64(0x600fba8b7f7a8ecb), U64(0x46b60f011a83988e),
+		U64(0x235b898e0dcf4c47), U64(0x957ab24f588592a9),
+		U64(0x4354330572b5c28c), U64(0xa5f3ef84e9b8d542),
+		U64(0x8c711e02341b2d01), U64(0x0b1874ae6a62a657),
+		U64(0x1213d8e306fc19ff), U64(0xfe6d7c6a4d9dba35),
+		U64(0x65ed868f174cd4c9), U64(0x88522ea0e6236550),
+		U64(0x899322065c2d7703), U64(0xc01e690bfef4018b),
+		U64(0x915982ed8abddaf8), U64(0xbe675b98ec3a4e4c),
+		U64(0xa996bf7f82f00db1), U64(0xe1daf8d49a27696a),
+		U64(0x2effd5d3dc8986e7), U64(0xd153a51f2b1a2e81),
+		U64(0x18caa0ebd690adfb), U64(0x390e3134b243c51a),
+		U64(0x2778b92cdff70416), U64(0x029f1851691c24a6),
+		U64(0x5e7cafeacc133575), U64(0xfa4e4cc89fa5f264),
+		U64(0x5a5f9f481e2b7d24), U64(0x484c47ab18d764db),
+		U64(0x400a27f2a1a7f479), U64(0xaeeb9b2a83da7315),
+		U64(0x721c626879869734), U64(0x042330a2d2384851),
+		U64(0x85f672fd3765aff0), U64(0xba446b3a3e02061d),
+		U64(0x73dd6ecec3888567), U64(0xffac70ccf793a866),
+		U64(0xdfa9edb5294ed2d4), U64(0x6c6aea7014325638),
+		U64(0x834a5a0e8c41c307), U64(0xcdba35562fb2cb2b),
+		U64(0x0ad97808d06cb404), U64(0x0f3b440cb85aee06),
+		U64(0xe5f9c876481f213b), U64(0x98deee1289c35809),
+		U64(0x59018bbfcd394bd1), U64(0xe01bf47220297b39),
+		U64(0xde68e1139340c087), U64(0x9fa3ca4788e926ad),
+		U64(0xbb85679c840c144e), U64(0x53d8f3b71d55ffd5),
+		U64(0x0da45c5dd146caa0), U64(0x6f34fe87c72060cd),
+		U64(0x57fbc315cf6db784), U64(0xcee421a1fca0fdde),
+		U64(0x3d2d0196607b8d4b), U64(0x642c8a29ad42c69a),
+		U64(0x14aff010bdd87508), U64(0xac74837beac657b3),
+		U64(0x3216459ad821634d), U64(0x3fb219c70967a9ed),
+		U64(0x06bc28f3bb246cf7), U64(0xf2082c9126d562c6),
+		U64(0x66b39278c45ee23c), U64(0xbd394f6f3f2878b9),
+		U64(0xfd33689d9e8f8cc0), U64(0x37f4799eb017394f),
+		U64(0x108cc0b26fe03d59), U64(0xda4bd1b1417888d6),
+		U64(0xb09d1332ee6eb219), U64(0x2f3ed975668794b4),
+		U64(0x58c0871977375982), U64(0x7561463d78ace990),
+		U64(0x09876cff037e82f1), U64(0x7fb83e35a8c05d94),
+		U64(0x26b9b58a65f91645), U64(0xef20b07e9873953f),
+		U64(0x3148516d0b3355b8), U64(0x41cb2b541ba9e62a),
+		U64(0x790416c613e43163), U64(0xa011d380818e8f40),
+		U64(0x3a5025c36151f3ef), U64(0xd57095bdf92266d0),
+		U64(0x498d4b0da2d97688), U64(0x8b0c3a57353153a5),
+		U64(0x21c491df64d368e1), U64(0x8f2f0af5e7091bf4),
+		U64(0x2da1c1240f9bb012), U64(0xc43d59a92ccc49da),
+		U64(0xbfa6573e56345c1f), U64(0x828b56a8364fd154),
+		U64(0x9a41f643e0df7caf), U64(0xbcf843c985266aea),
+		U64(0x2b1de9d7b4bfdce5), U64(0x20059d79dedd7ab2),
+		U64(0x6dabe6d6ae3c446b), U64(0x45e81bf6c991ae7b),
+		U64(0x6351ae7cac68b83e), U64(0xa432e32253b6c711),
+		U64(0xd092a9b991143cd2), U64(0xcac711032e98b58f),
+		U64(0xd8d4c9e02864ac70), U64(0xc5fc550f96c25b89),
+		U64(0xd7ef8dec903e4276), U64(0x67729ede7e50f06f),
+		U64(0xeac28c7af045cf3d), U64(0xb15c1f945460a04a),
+		U64(0x9cfddeb05bfb1058), U64(0x93c69abce3a1fe5e),
+		U64(0xeb0380dc4a4bdd6e), U64(0xd20db1e8f8081874),
+		U64(0x229a8528b7c15e14), U64(0x44291750739fbc28),
+		U64(0xd3ccbd4e42060a27), U64(0xf62b1c33f4ed2a97),
+		U64(0x86a8660ae4779905), U64(0xd62e814a2a305025),
+		U64(0x477703a7a08d8add), U64(0x7b9b0e977af815c5),
+		U64(0x78c51a60a9ea2330), U64(0xa6adfb733aaae3b7),
+		U64(0x97e5aa1e3199b60f), U64(0x0000000000000000),
+		U64(0xf4b404629df10e31), U64(0x5564db44a6719322),
+		U64(0x9207961a59afec0d), U64(0x9624a6b88b97a45c),
+		U64(0x363575380a192b1c), U64(0x2c60cd82b595a241),
+		U64(0x7d272664c1dc7932), U64(0x7142769faa94a1c1),
+		U64(0xa1d0df263b809d13), U64(0x1630e841d4c451ae),
+		U64(0xc1df65ad44fa13d8), U64(0x13d2d445bcf20bac),
+		U64(0xd915c546926abe23), U64(0x38cf3d92084dd749),
+		U64(0xe766d0272103059d), U64(0xc7634d5effde7f2f),
+		U64(0x077d2455012a7ea4), U64(0xedbfa82ff16fb199),
+		U64(0xaf2a978c39d46146), U64(0x42953fa3c8bbd0df),
+		U64(0xcb061da59496a7dc), U64(0x25e7a17db6eb20b0),
+		U64(0x34aa6d6963050fba), U64(0xa76cf7d580a4f1e4),
+		U64(0xf7ea10954ee338c4), U64(0xfcf2643b24819e93),
+		U64(0xcf252d0746aeef8d), U64(0x4ef06f58a3f3082c),
+		U64(0x563acfb37563a5d7), U64(0x5086e740ce47c920),
+		U64(0x2982f186dda3f843), U64(0x87696aac5e798b56),
+		U64(0x5d22bb1d1f010380), U64(0x035e14f7d31236f5),
+		U64(0x3cec0d30da759f18), U64(0xf3c920379cdb7095),
+		U64(0xb8db736b571e22bb), U64(0xdd36f5e44052f672),
+		U64(0xaac8ab8851e23b44), U64(0xa857b3d938fe1fe2),
+		U64(0x17f1e4e76eca43fd), U64(0xec7ea4894b61a3ca),
+		U64(0x9e62c6e132e734fe), U64(0xd4b1991b432c7483),
+		U64(0x6ad6c283af163acf), U64(0x1ce9904904a8e5aa),
+		U64(0x5fbda34c761d2726), U64(0xf910583f4cb7c491),
+		U64(0xc6a241f845d06d7c), U64(0x4f3163fe19fd1a7f),
+		U64(0xe99c988d2357f9c8), U64(0x8eee06535d0709a7),
+		U64(0x0efa48aa0254fc55), U64(0xb4be23903c56fa48),
+		U64(0x763f52caabbedf65), U64(0xeee1bcd8227d876c),
+		U64(0xe345e085f33b4dcc), U64(0x3e731561b369bbbe),
+		U64(0x2843fd2067adea10), U64(0x2adce5710eb1ceb6),
+		U64(0xb7e03767ef44ccbd), U64(0x8db012a48e153f52),
+		U64(0x61ceb62dc5749c98), U64(0xe85d942b9959eb9b),
+		U64(0x4c6f7709caef2c8a), U64(0x84377e5b8d6bbda3),
+		U64(0x30895dcbb13d47eb), U64(0x74a04a9bc2a2fbc3),
+		U64(0x6b17ce251518289c), U64(0xe438c4d0f2113368),
+		U64(0x1fb784bed7bad35f), U64(0x9b80fae55ad16efc),
+		U64(0x77fe5e6c11b0cd36), U64(0xc858095247849129),
+		U64(0x08466059b97090a2), U64(0x01c10ca6ba0e1253),
+		U64(0x6988d6747c040c3a), U64(0x6849dad2c60a1e69),
+		U64(0x5147ebe67449db73), U64(0xc99905f4fd8a837a),
+		U64(0x991fe2b433cd4a5a), U64(0xf09734c04fc94660),
+		U64(0xa28ecbd1e892abe6), U64(0xf1563866f5c75433),
+		U64(0x4dae7baf70e13ed9), U64(0x7ce62ac27bd26b61),
+		U64(0x70837a39109ab392), U64(0x90988e4b30b3c8ab),
+		U64(0xb2020b63877296bf), U64(0x156efcb607d6675b)
+	}, { /* 7 */
+		U64(0xe63f55ce97c331d0), U64(0x25b506b0015bba16),
+		U64(0xc8706e29e6ad9ba8), U64(0x5b43d3775d521f6a),
+		U64(0x0bfa3d577035106e), U64(0xab95fc172afb0e66),
+		U64(0xf64b63979e7a3276), U64(0xf58b4562649dad4b),
+		U64(0x48f7c3dbae0c83f1), U64(0xff31916642f5c8c5),
+		U64(0xcbb048dc1c4a0495), U64(0x66b8f83cdf622989),
+		U64(0x35c130e908e2b9b0), U64(0x7c761a61f0b34fa1),
+		U64(0x3601161cf205268d), U64(0x9e54ccfe2219b7d6),
+		U64(0x8b7d90a538940837), U64(0x9cd403588ea35d0b),
+		U64(0xbc3c6fea9ccc5b5a), U64(0xe5ff733b6d24aeed),
+		U64(0xceed22de0f7eb8d2), U64(0xec8581cab1ab545e),
+		U64(0xb96105e88ff8e71d), U64(0x8ca03501871a5ead),
+		U64(0x76ccce65d6db2a2f), U64(0x5883f582a7b58057),
+		U64(0x3f7be4ed2e8adc3e), U64(0x0fe7be06355cd9c9),
+		U64(0xee054e6c1d11be83), U64(0x1074365909b903a6),
+		U64(0x5dde9f80b4813c10), U64(0x4a770c7d02b6692c),
+		U64(0x5379c8d5d7809039), U64(0xb4067448161ed409),
+		U64(0x5f5e5026183bd6cd), U64(0xe898029bf4c29df9),
+		U64(0x7fb63c940a54d09c), U64(0xc5171f897f4ba8bc),
+		U64(0xa6f28db7b31d3d72), U64(0x2e4f3be7716eaa78),
+		U64(0x0d6771a099e63314), U64(0x82076254e41bf284),
+		U64(0x2f0fd2b42733df98), U64(0x5c9e76d3e2dc49f0),
+		U64(0x7aeb569619606cdb), U64(0x83478b07b2468764),
+		U64(0xcfadcb8d5923cd32), U64(0x85dac7f05b95a41e),
+		U64(0xb5469d1b4043a1e9), U64(0xb821ecbbd9a592fd),
+		U64(0x1b8e0b0e798c13c8), U64(0x62a57b6d9a0be02e),
+		U64(0xfcf1b793b81257f8), U64(0x9d94ea0bd8fe28eb),
+		U64(0x4cea408aeb654a56), U64(0x23284a47e888996c),
+		U64(0x2d8f1d128b893545), U64(0xf4cbac3132c0d8ab),
+		U64(0xbd7c86b9ca912eba), U64(0x3a268eef3dbe6079),
+		U64(0xf0d62f6077a9110c), U64(0x2735c916ade150cb),
+		U64(0x89fd5f03942ee2ea), U64(0x1acee25d2fd16628),
+		U64(0x90f39bab41181bff), U64(0x430dfe8cde39939f),
+		U64(0xf70b8ac4c8274796), U64(0x1c53aeaac6024552),
+		U64(0x13b410acf35e9c9b), U64(0xa532ab4249faa24f),
+		U64(0x2b1251e5625a163f), U64(0xd7e3e676da4841c7),
+		U64(0xa7b264e4e5404892), U64(0xda8497d643ae72d3),
+		U64(0x861ae105a1723b23), U64(0x38a6414991048aa4),
+		U64(0x6578dec92585b6b4), U64(0x0280cfa6acbaeadd),
+		U64(0x88bdb650c273970a), U64(0x9333bd5ebbff84c2),
+		U64(0x4e6a8f2c47dfa08b), U64(0x321c954db76cef2a),
+		U64(0x418d312a72837942), U64(0xb29b38bfffcdf773),
+		U64(0x6c022c38f90a4c07), U64(0x5a033a240b0f6a8a),
+		U64(0x1f93885f3ce5da6f), U64(0xc38a537e96988bc6),
+		U64(0x39e6a81ac759ff44), U64(0x29929e43cee0fce2),
+		U64(0x40cdd87924de0ca2), U64(0xe9d8ebc8a29fe819),
+		U64(0x0c2798f3cfbb46f4), U64(0x55e484223e53b343),
+		U64(0x4650948ecd0d2fd8), U64(0x20e86cb2126f0651),
+		U64(0x6d42c56baf5739e7), U64(0xa06fc1405ace1e08),
+		U64(0x7babbfc54f3d193b), U64(0x424d17df8864e67f),
+		U64(0xd8045870ef14980e), U64(0xc6d7397c85ac3781),
+		U64(0x21a885e1443273b1), U64(0x67f8116f893f5c69),
+		U64(0x24f5efe35706cff6), U64(0xd56329d076f2ab1a),
+		U64(0x5e1eb9754e66a32d), U64(0x28d2771098bd8902),
+		U64(0x8f6013f47dfdc190), U64(0x17a993fdb637553c),
+		U64(0xe0a219397e1012aa), U64(0x786b9930b5da8606),
+		U64(0x6e82e39e55b0a6da), U64(0x875a0856f72f4ec3),
+		U64(0x3741ff4fa458536d), U64(0xac4859b3957558fc),
+		U64(0x7ef6d5c75c09a57c), U64(0xc04a758b6c7f14fb),
+		U64(0xf9acdd91ab26ebbf), U64(0x7391a467c5ef9668),
+		U64(0x335c7c1ee1319aca), U64(0xa91533b18641e4bb),
+		U64(0xe4bf9a683b79db0d), U64(0x8e20faa72ba0b470),
+		U64(0x51f907737b3a7ae4), U64(0x2268a314bed5ec8c),
+		U64(0xd944b123b949edee), U64(0x31dcb3b84d8b7017),
+		U64(0xd3fe65279f218860), U64(0x097af2f1dc8ffab3),
+		U64(0x9b09a6fc312d0b91), U64(0xcc6ded78a3c4520f),
+		U64(0x3481d9ba5ebfcc50), U64(0x4f2a667f1182d56b),
+		U64(0xdfd9fdd4509ace94), U64(0x26752045fbbc252b),
+		U64(0xbffc491f662bc467), U64(0xdd593272fc202449),
+		U64(0x3cbbc218d46d4303), U64(0x91b372f817456e1f),
+		U64(0x681faf69bc6385a0), U64(0xb686bbeebaa43ed4),
+		U64(0x1469b5084cd0ca01), U64(0x98c98009cbca94ac),
+		U64(0x6438379a73d8c354), U64(0xc2caba2dc0c5fe26),
+		U64(0x3e3b0dbe78d7a9de), U64(0x50b9ee202d670f04),
+		U64(0x4590b27b37eab0e5), U64(0x6025b4cb36b10af3),
+		U64(0xfb2c1237079c0162), U64(0xa12f28130c936be8),
+		U64(0x4b37e52e54eb1ccc), U64(0x083a1ba28ad28f53),
+		U64(0xc10a9cd83a22611b), U64(0x9f1425ad7444c236),
+		U64(0x069d4cf7e9d3237a), U64(0xedc56899e7f621be),
+		U64(0x778c273680865fcf), U64(0x309c5aeb1bd605f7),
+		U64(0x8de0dc52d1472b4d), U64(0xf8ec34c2fd7b9e5f),
+		U64(0xea18cd3d58787724), U64(0xaad515447ca67b86),
+		U64(0x9989695a9d97e14c), U64(0x0000000000000000),
+		U64(0xf196c63321f464ec), U64(0x71116bc169557cb5),
+		U64(0xaf887f466f92c7c1), U64(0x972e3e0ffe964d65),
+		U64(0x190ec4a8d536f915), U64(0x95aef1a9522ca7b8),
+		U64(0xdc19db21aa7d51a9), U64(0x94ee18fa0471d258),
+		U64(0x8087adf248a11859), U64(0xc457f6da2916dd5c),
+		U64(0xfa6cfb6451c17482), U64(0xf256e0c6db13fbd1),
+		U64(0x6a9f60cf10d96f7d), U64(0x4daaa9d9bd383fb6),
+		U64(0x03c026f5fae79f3d), U64(0xde99148706c7bb74),
+		U64(0x2a52b8b6340763df), U64(0x6fc20acd03edd33a),
+		U64(0xd423c08320afdefa), U64(0xbbe1ca4e23420dc0),
+		U64(0x966ed75ca8cb3885), U64(0xeb58246e0e2502c4),
+		U64(0x055d6a021334bc47), U64(0xa47242111fa7d7af),
+		U64(0xe3623fcc84f78d97), U64(0x81c744a11efc6db9),
+		U64(0xaec8961539cfb221), U64(0xf31609958d4e8e31),
+		U64(0x63e5923ecc5695ce), U64(0x47107ddd9b505a38),
+		U64(0xa3afe7b5a0298135), U64(0x792b7063e387f3e6),
+		U64(0x0140e953565d75e0), U64(0x12f4f9ffa503e97b),
+		U64(0x750ce8902c3cb512), U64(0xdbc47e8515f30733),
+		U64(0x1ed3610c6ab8af8f), U64(0x5239218681dde5d9),
+		U64(0xe222d69fd2aaf877), U64(0xfe71783514a8bd25),
+		U64(0xcaf0a18f4a177175), U64(0x61655d9860ec7f13),
+		U64(0xe77fbc9dc19e4430), U64(0x2ccff441ddd440a5),
+		U64(0x16e97aaee06a20dc), U64(0xa855dae2d01c915b),
+		U64(0x1d1347f9905f30b2), U64(0xb7c652bdecf94b34),
+		U64(0xd03e43d265c6175d), U64(0xfdb15ec0ee4f2218),
+		U64(0x57644b8492e9599e), U64(0x07dda5a4bf8e569a),
+		U64(0x54a46d71680ec6a3), U64(0x5624a2d7c4b42c7e),
+		U64(0xbebca04c3076b187), U64(0x7d36f332a6ee3a41),
+		U64(0x3b6667bc6be31599), U64(0x695f463aea3ef040),
+		U64(0xad08b0e0c3282d1c), U64(0xb15b1e4a052a684e),
+		U64(0x44d05b2861b7c505), U64(0x15295c5b1a8dbfe1),
+		U64(0x744c01c37a61c0f2), U64(0x59c31cd1f1e8f5b7),
+		U64(0xef45a73f4b4ccb63), U64(0x6bdf899c46841a9d),
+		U64(0x3dfb2b4b823036e3), U64(0xa2ef0ee6f674f4d5),
+		U64(0x184e2dfb836b8cf5), U64(0x1134df0a5fe47646),
+		U64(0xbaa1231d751f7820), U64(0xd17eaa81339b62bd),
+		U64(0xb01bf71953771dae), U64(0x849a2ea30dc8d1fe),
+		U64(0x705182923f080955), U64(0x0ea757556301ac29),
+		U64(0x041d83514569c9a7), U64(0x0abad4042668658e),
+		U64(0x49b72a88f851f611), U64(0x8a3d79f66ec97dd7),
+		U64(0xcd2d042bf59927ef), U64(0xc930877ab0f0ee48),
+		U64(0x9273540deda2f122), U64(0xc797d02fd3f14261),
+		U64(0xe1e2f06a284d674a), U64(0xd2be8c74c97cfd80),
+		U64(0x9a494faf67707e71), U64(0xb3dbd1eca9908293),
+		U64(0x72d14d3493b2e388), U64(0xd6a30f258c153427)
+	},
+};
+
+static const STREEBOG_LONG64 C16[12][8] = {
+	{
+		U64(0xdd806559f2a64507), U64(0x05767436cc744d23),
+		U64(0xa2422a08a460d315), U64(0x4b7ce09192676901),
+		U64(0x714eb88d7585c4fc), U64(0x2f6a76432e45d016),
+		U64(0xebcb2f81c0657c1f), U64(0xb1085bda1ecadae9)
+	}, {
+		U64(0xe679047021b19bb7), U64(0x55dda21bd7cbcd56),
+		U64(0x5cb561c2db0aa7ca), U64(0x9ab5176b12d69958),
+		U64(0x61d55e0f16b50131), U64(0xf3feea720a232b98),
+		U64(0x4fe39d460f70b5d7), U64(0x6fa3b58aa99d2f1a)
+	}, {
+		U64(0x991e96f50aba0ab2), U64(0xc2b6f443867adb31),
+		U64(0xc1c93a376062db09), U64(0xd3e20fe490359eb1),
+		U64(0xf2ea7514b1297b7b), U64(0x06f15e5f529c1f8b),
+		U64(0x0a39fc286a3d8435), U64(0xf574dcac2bce2fc7)
+	}, {
+		U64(0x220cbebc84e3d12e), U64(0x3453eaa193e837f1),
+		U64(0xd8b71333935203be), U64(0xa9d72c82ed03d675),
+		U64(0x9d721cad685e353f), U64(0x488e857e335c3c7d),
+		U64(0xf948e1a05d71e4dd), U64(0xef1fdfb3e81566d2)
+	}, {
+		U64(0x601758fd7c6cfe57), U64(0x7a56a27ea9ea63f5),
+		U64(0xdfff00b723271a16), U64(0xbfcd1747253af5a3),
+		U64(0x359e35d7800fffbd), U64(0x7f151c1f1686104a),
+		U64(0x9a3f410c6ca92363), U64(0x4bea6bacad474799)
+	}, {
+		U64(0xfa68407a46647d6e), U64(0xbf71c57236904f35),
+		U64(0x0af21f66c2bec6b6), U64(0xcffaa6b71c9ab7b4),
+		U64(0x187f9ab49af08ec6), U64(0x2d66c4f95142a46c),
+		U64(0x6fa4c33b7a3039c0), U64(0xae4faeae1d3ad3d9)
+	}, {
+		U64(0x8886564d3a14d493), U64(0x3517454ca23c4af3),
+		U64(0x06476983284a0504), U64(0x0992abc52d822c37),
+		U64(0xd3473e33197a93c9), U64(0x399ec6c7e6bf87c9),
+		U64(0x51ac86febf240954), U64(0xf4c70e16eeaac5ec)
+	}, {
+		U64(0xa47f0dd4bf02e71e), U64(0x36acc2355951a8d9),
+		U64(0x69d18d2bd1a5c42f), U64(0xf4892bcb929b0690),
+		U64(0x89b4443b4ddbc49a), U64(0x4eb7f8719c36de1e),
+		U64(0x03e7aa020c6e4141), U64(0x9b1f5b424d93c9a7)
+	}, {
+		U64(0x7261445183235adb), U64(0x0e38dc92cb1f2a60),
+		U64(0x7b2b8a9aa6079c54), U64(0x800a440bdbb2ceb1),
+		U64(0x3cd955b7e00d0984), U64(0x3a7d3a1b25894224),
+		U64(0x944c9ad8ec165fde), U64(0x378f5a541631229b)
+	}, {
+		U64(0x74b4c7fb98459ced), U64(0x3698fad1153bb6c3),
+		U64(0x7a1e6c303b7652f4), U64(0x9fe76702af69334b),
+		U64(0x1fffe18a1b336103), U64(0x8941e71cff8a78db),
+		U64(0x382ae548b2e4f3f3), U64(0xabbedea680056f52)
+	}, {
+		U64(0x6bcaa4cd81f32d1b), U64(0xdea2594ac06fd85d),
+		U64(0xefbacd1d7d476e98), U64(0x8a1d71efea48b9ca),
+		U64(0x2001802114846679), U64(0xd8fa6bbbebab0761),
+		U64(0x3002c6cd635afe94), U64(0x7bcd9ed0efc889fb)
+	}, {
+		U64(0x48bc924af11bd720), U64(0xfaf417d5d9b21b99),
+		U64(0xe71da4aa88e12852), U64(0x5d80ef9d1891cc86),
+		U64(0xf82012d430219f9b), U64(0xcda43c32bcdf1d77),
+		U64(0xd21380b00449b17a), U64(0x378ee767f11631ba)
+	},
+};
+
+#define B(x,i,j)	(((STREEBOG_LONG64)(*(((const unsigned char *)(&x))+i)))<<(j*8))
+#define PULL64(x) (B(x,0,0)|B(x,1,1)|B(x,2,2)|B(x,3,3)|B(x,4,4)|B(x,5,5)|B(x,6,6)|B(x,7,7))
+#define SWAB64(x) (B(x,0,7)|B(x,1,6)|B(x,2,5)|B(x,3,4)|B(x,4,3)|B(x,5,2)|B(x,6,1)|B(x,7,0))
+
+static inline STREEBOG_LONG64
+multipermute(const STREEBOG_LONG64 *in, int i)
+{
+	STREEBOG_LONG64 t = 0;
+
+	t ^= A_PI_table[0][(in[0] >> (i * 8)) & 0xff];
+	t ^= A_PI_table[1][(in[1] >> (i * 8)) & 0xff];
+	t ^= A_PI_table[2][(in[2] >> (i * 8)) & 0xff];
+	t ^= A_PI_table[3][(in[3] >> (i * 8)) & 0xff];
+	t ^= A_PI_table[4][(in[4] >> (i * 8)) & 0xff];
+	t ^= A_PI_table[5][(in[5] >> (i * 8)) & 0xff];
+	t ^= A_PI_table[6][(in[6] >> (i * 8)) & 0xff];
+	t ^= A_PI_table[7][(in[7] >> (i * 8)) & 0xff];
+
+	return t;
+}
+
+static void
+transform(STREEBOG_LONG64 *out, const STREEBOG_LONG64 *a,
+    const STREEBOG_LONG64 *b)
+{
+	STREEBOG_LONG64 tmp[8];
+
+	tmp[0] = a[0] ^ b[0];
+	tmp[1] = a[1] ^ b[1];
+	tmp[2] = a[2] ^ b[2];
+	tmp[3] = a[3] ^ b[3];
+	tmp[4] = a[4] ^ b[4];
+	tmp[5] = a[5] ^ b[5];
+	tmp[6] = a[6] ^ b[6];
+	tmp[7] = a[7] ^ b[7];
+
+	out[0] = multipermute(tmp, 0);
+	out[1] = multipermute(tmp, 1);
+	out[2] = multipermute(tmp, 2);
+	out[3] = multipermute(tmp, 3);
+	out[4] = multipermute(tmp, 4);
+	out[5] = multipermute(tmp, 5);
+	out[6] = multipermute(tmp, 6);
+	out[7] = multipermute(tmp, 7);
+}
+
+static inline void
+gN(STREEBOG_LONG64 *h, STREEBOG_LONG64 *m, STREEBOG_LONG64 *N)
+{
+	STREEBOG_LONG64 K[8];
+	STREEBOG_LONG64 T[8];
+	int i;
+
+	transform(K, h, N);
+
+	transform(T, K, m);
+	transform(K, K, C16[0]);
+	for (i = 1; i < 12; i++) {
+		transform(T, K, T);
+		transform(K, K, C16[i]);
+	}
+
+	h[0] ^= T[0] ^ K[0] ^ m[0];
+	h[1] ^= T[1] ^ K[1] ^ m[1];
+	h[2] ^= T[2] ^ K[2] ^ m[2];
+	h[3] ^= T[3] ^ K[3] ^ m[3];
+	h[4] ^= T[4] ^ K[4] ^ m[4];
+	h[5] ^= T[5] ^ K[5] ^ m[5];
+	h[6] ^= T[6] ^ K[6] ^ m[6];
+	h[7] ^= T[7] ^ K[7] ^ m[7];
+}
+
+
+static void
+streebog_single_block(STREEBOG_CTX *ctx, const unsigned char *in, size_t num)
+{
+	STREEBOG_LONG64 M[8], l;
+	int i;
+
+	for (i = 0; i < 8; i++)
+		M[i] = PULL64(in[i*8]);
+
+	gN(ctx->h, M, ctx->N);
+
+	l = ctx->N[0];
+	ctx->N[0] += num;
+
+	if (ctx->N[0] < l || ctx->N[0] < num) {
+		for (i = 1; i < 8; i++) {
+			ctx->N[i]++;
+			if (ctx->N[i] != 0)
+				break;
+		}
+	}
+
+	ctx->Sigma[0] += M[0];
+	for (i = 1; i < 8; i++)
+		if (ctx->Sigma[i-1] < M[i-1])
+			ctx->Sigma[i] += M[i] + 1;
+		else
+			ctx->Sigma[i] += M[i];
+}
+
+
+
+static void
+streebog_block_data_order(STREEBOG_CTX *ctx, const unsigned char *in,
+    size_t num)
+{
+	int i;
+
+	for (i = 0; i < num; i++)
+		streebog_single_block(ctx, in + i * STREEBOG_CBLOCK, 64 * 8);
+}
+
+int
+STREEBOG512_Final(unsigned char *md, STREEBOG_CTX *c)
+{
+	unsigned char *p = (unsigned char *)c->data;
+	STREEBOG_LONG64 Z[STREEBOG_LBLOCK] = {0};
+	int n;
+
+	if (c->num == STREEBOG_CBLOCK) {
+		streebog_block_data_order(c, p, 1);
+		c->num -= STREEBOG_CBLOCK;
+	}
+
+	n = c->num;
+	p[n++] = 1;
+	memset(p + n, 0, STREEBOG_CBLOCK - n);
+
+	streebog_single_block(c, p, c->num * 8);
+
+	gN(c->h, c->N, Z);
+	gN(c->h, c->Sigma, Z);
+
+	for (n = 0; n < STREEBOG_LBLOCK; n++)
+		c->h[n] = SWAB64(c->h[n]);
+
+	if (md == NULL)
+		return 0;
+
+	switch (c->md_len) {
+		/* Let compiler decide if it's appropriate to unroll... */
+	case STREEBOG256_LENGTH:
+		for (n = 0; n < STREEBOG256_LENGTH / 8; n++) {
+			STREEBOG_LONG64 t = c->h[4+n];
+
+#if BYTE_ORDER == BIG_ENDIAN
+			*(md++) = (unsigned char)(t);
+			*(md++) = (unsigned char)(t >> 8);
+			*(md++) = (unsigned char)(t >> 16);
+			*(md++) = (unsigned char)(t >> 24);
+			*(md++) = (unsigned char)(t >> 32);
+			*(md++) = (unsigned char)(t >> 40);
+			*(md++) = (unsigned char)(t >> 48);
+			*(md++) = (unsigned char)(t >> 56);
+#else
+			*(md++) = (unsigned char)(t >> 56);
+			*(md++) = (unsigned char)(t >> 48);
+			*(md++) = (unsigned char)(t >> 40);
+			*(md++) = (unsigned char)(t >> 32);
+			*(md++) = (unsigned char)(t >> 24);
+			*(md++) = (unsigned char)(t >> 16);
+			*(md++) = (unsigned char)(t >> 8);
+			*(md++) = (unsigned char)(t);
+#endif
+		}
+		break;
+	case STREEBOG512_LENGTH:
+		for (n = 0; n < STREEBOG512_LENGTH / 8; n++) {
+			STREEBOG_LONG64 t = c->h[n];
+
+#if BYTE_ORDER == BIG_ENDIAN
+			*(md++) = (unsigned char)(t);
+			*(md++) = (unsigned char)(t >> 8);
+			*(md++) = (unsigned char)(t >> 16);
+			*(md++) = (unsigned char)(t >> 24);
+			*(md++) = (unsigned char)(t >> 32);
+			*(md++) = (unsigned char)(t >> 40);
+			*(md++) = (unsigned char)(t >> 48);
+			*(md++) = (unsigned char)(t >> 56);
+#else
+			*(md++) = (unsigned char)(t >> 56);
+			*(md++) = (unsigned char)(t >> 48);
+			*(md++) = (unsigned char)(t >> 40);
+			*(md++) = (unsigned char)(t >> 32);
+			*(md++) = (unsigned char)(t >> 24);
+			*(md++) = (unsigned char)(t >> 16);
+			*(md++) = (unsigned char)(t >> 8);
+			*(md++) = (unsigned char)(t);
+#endif
+		}
+		break;
+		/* ... as well as make sure md_len is not abused. */
+	default:
+		return 0;
+	}
+
+	return 1;
+}
+
+int
+STREEBOG256_Final(unsigned char *md, STREEBOG_CTX * c)
+{
+	return STREEBOG512_Final(md, c);
+}
+
+int
+STREEBOG512_Update(STREEBOG_CTX *c, const void *_data, size_t len)
+{
+	unsigned char *p = (unsigned char *)c->data;
+	const unsigned char *data = (const unsigned char *)_data;
+
+	if (len == 0)
+		return 1;
+
+	if (c->num != 0) {
+		size_t n = STREEBOG_CBLOCK - c->num;
+
+		if (len < n) {
+			memcpy(p + c->num, data, len);
+			c->num += (unsigned int)len;
+			return 1;
+		} else {
+			memcpy(p + c->num, data, n);
+			c->num = 0;
+			len -= n;
+			data += n;
+			streebog_block_data_order(c, p, 1);
+		}
+	}
+
+	if (len >= STREEBOG_CBLOCK) {
+		streebog_block_data_order(c, data, len / STREEBOG_CBLOCK);
+		data += len;
+		len %= STREEBOG_CBLOCK;
+		data -= len;
+	}
+
+	if (len != 0) {
+		memcpy(p, data, len);
+		c->num = (int)len;
+	}
+
+	return 1;
+}
+
+int
+STREEBOG256_Update(STREEBOG_CTX *c, const void *data, size_t len)
+{
+	return STREEBOG512_Update(c, data, len);
+}
+
+void
+STREEBOG512_Transform(STREEBOG_CTX *c, const unsigned char *data)
+{
+	streebog_block_data_order(c, data, 1);
+}
+
+int
+STREEBOG256_Init(STREEBOG_CTX *c)
+{
+	memset(c, 0, sizeof(*c));
+	memset(c->h, 1, sizeof(c->h));
+
+	c->md_len = STREEBOG256_LENGTH;
+	return 1;
+}
+
+int
+STREEBOG512_Init(STREEBOG_CTX *c)
+{
+	memset(c, 0, sizeof(*c));
+	memset(c->h, 0, sizeof(c->h));
+
+	c->num = 0;
+	c->md_len = STREEBOG512_LENGTH;
+	return 1;
+}
+
+unsigned char *
+STREEBOG256(const unsigned char *d, size_t n, unsigned char *md)
+{
+	STREEBOG_CTX c;
+	static unsigned char m[STREEBOG256_LENGTH];
+
+	if (md == NULL)
+		md = m;
+	STREEBOG256_Init(&c);
+	STREEBOG256_Update(&c, d, n);
+	STREEBOG256_Final(md, &c);
+	explicit_bzero(&c, sizeof(c));
+	return (md);
+}
+
+unsigned char *
+STREEBOG512(const unsigned char *d, size_t n, unsigned char *md)
+{
+	STREEBOG_CTX c;
+	static unsigned char m[STREEBOG512_LENGTH];
+
+	if (md == NULL)
+		md = m;
+	STREEBOG512_Init(&c);
+	STREEBOG512_Update(&c, d, n);
+	STREEBOG512_Final(md, &c);
+	explicit_bzero(&c, sizeof(c));
+	return (md);
+}
+
+#endif
diff --git a/crypto/libressl/crypto/hmac/hm_ameth.c b/crypto/libressl/crypto/hmac/hm_ameth.c
new file mode 100644
index 0000000000..96f707d2fd
--- /dev/null
+++ b/crypto/libressl/crypto/hmac/hm_ameth.c
@@ -0,0 +1,169 @@
+/* $OpenBSD: hm_ameth.c,v 1.9 2015/07/20 15:45:29 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2007.
+ */
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+
+#include "asn1_locl.h"
+
+#define HMAC_TEST_PRIVATE_KEY_FORMAT
+
+/* HMAC "ASN1" method. This is just here to indicate the
+ * maximum HMAC output length and to free up an HMAC
+ * key.
+ */
+
+static int
+hmac_size(const EVP_PKEY *pkey)
+{
+	return EVP_MAX_MD_SIZE;
+}
+
+static void
+hmac_key_free(EVP_PKEY *pkey)
+{
+	ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
+
+	if (os) {
+		if (os->data)
+			explicit_bzero(os->data, os->length);
+		ASN1_OCTET_STRING_free(os);
+	}
+}
+
+static int
+hmac_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+{
+	switch (op) {
+	case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+		*(int *)arg2 = NID_sha1;
+		return 1;
+	default:
+		return -2;
+	}
+}
+
+#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT
+/* A bogus private key format for test purposes. This is simply the
+ * HMAC key with "HMAC PRIVATE KEY" in the headers. When enabled the
+ * genpkey utility can be used to "generate" HMAC keys.
+ */
+
+static int
+old_hmac_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
+{
+	ASN1_OCTET_STRING *os;
+
+	os = ASN1_OCTET_STRING_new();
+	if (os == NULL)
+		goto err;
+	if (ASN1_OCTET_STRING_set(os, *pder, derlen) == 0)
+		goto err;
+	if (EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, os) == 0)
+		goto err;
+	return 1;
+
+err:
+	ASN1_OCTET_STRING_free(os);
+	return 0;
+}
+
+static int
+old_hmac_encode(const EVP_PKEY *pkey, unsigned char **pder)
+{
+	int inc;
+	ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
+
+	if (pder) {
+		if (!*pder) {
+			*pder = malloc(os->length);
+			if (*pder == NULL)
+				return -1;
+			inc = 0;
+		} else
+			inc = 1;
+
+		memcpy(*pder, os->data, os->length);
+
+		if (inc)
+			*pder += os->length;
+	}
+
+	return os->length;
+}
+
+#endif
+
+const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = {
+	.pkey_id = EVP_PKEY_HMAC,
+	.pkey_base_id = EVP_PKEY_HMAC,
+
+	.pem_str = "HMAC",
+	.info = "OpenSSL HMAC method",
+
+	.pkey_size = hmac_size,
+
+	.pkey_free = hmac_key_free,
+	.pkey_ctrl = hmac_pkey_ctrl,
+#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT
+	.old_priv_decode = old_hmac_decode,
+	.old_priv_encode = old_hmac_encode
+#endif
+};
diff --git a/crypto/libressl/crypto/hmac/hm_pmeth.c b/crypto/libressl/crypto/hmac/hm_pmeth.c
new file mode 100644
index 0000000000..50c4d0cc8a
--- /dev/null
+++ b/crypto/libressl/crypto/hmac/hm_pmeth.c
@@ -0,0 +1,259 @@
+/* $OpenBSD: hm_pmeth.c,v 1.8 2014/07/11 08:44:48 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2007.
+ */
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include "evp_locl.h"
+
+/* HMAC pkey context structure */
+
+typedef struct {
+	const EVP_MD *md;	/* MD for HMAC use */
+	ASN1_OCTET_STRING ktmp; /* Temp storage for key */
+	HMAC_CTX ctx;
+} HMAC_PKEY_CTX;
+
+static int
+pkey_hmac_init(EVP_PKEY_CTX *ctx)
+{
+	HMAC_PKEY_CTX *hctx;
+
+	hctx = malloc(sizeof(HMAC_PKEY_CTX));
+	if (!hctx)
+		return 0;
+	hctx->md = NULL;
+	hctx->ktmp.data = NULL;
+	hctx->ktmp.length = 0;
+	hctx->ktmp.flags = 0;
+	hctx->ktmp.type = V_ASN1_OCTET_STRING;
+	HMAC_CTX_init(&hctx->ctx);
+
+	ctx->data = hctx;
+	ctx->keygen_info_count = 0;
+
+	return 1;
+}
+
+static int
+pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+{
+	HMAC_PKEY_CTX *sctx, *dctx;
+
+	if (!pkey_hmac_init(dst))
+		return 0;
+	sctx = src->data;
+	dctx = dst->data;
+	dctx->md = sctx->md;
+	HMAC_CTX_init(&dctx->ctx);
+	if (!HMAC_CTX_copy(&dctx->ctx, &sctx->ctx))
+		return 0;
+	if (sctx->ktmp.data) {
+		if (!ASN1_OCTET_STRING_set(&dctx->ktmp, sctx->ktmp.data,
+		    sctx->ktmp.length))
+			return 0;
+	}
+	return 1;
+}
+
+static void
+pkey_hmac_cleanup(EVP_PKEY_CTX *ctx)
+{
+	HMAC_PKEY_CTX *hctx = ctx->data;
+
+	HMAC_CTX_cleanup(&hctx->ctx);
+	if (hctx->ktmp.data) {
+		if (hctx->ktmp.length)
+			explicit_bzero(hctx->ktmp.data, hctx->ktmp.length);
+		free(hctx->ktmp.data);
+		hctx->ktmp.data = NULL;
+	}
+	free(hctx);
+}
+
+static int
+pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+	ASN1_OCTET_STRING *hkey = NULL;
+	HMAC_PKEY_CTX *hctx = ctx->data;
+
+	if (!hctx->ktmp.data)
+		return 0;
+	hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp);
+	if (!hkey)
+		return 0;
+	EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey);
+
+	return 1;
+}
+
+static int
+int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+	HMAC_PKEY_CTX *hctx = ctx->pctx->data;
+
+	if (!HMAC_Update(&hctx->ctx, data, count))
+		return 0;
+	return 1;
+}
+
+static int
+hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
+{
+	HMAC_PKEY_CTX *hctx = ctx->data;
+
+	HMAC_CTX_set_flags(&hctx->ctx, mctx->flags & ~EVP_MD_CTX_FLAG_NO_INIT);
+	EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
+	mctx->update = int_update;
+	return 1;
+}
+
+static int
+hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+    EVP_MD_CTX *mctx)
+{
+	unsigned int hlen;
+	HMAC_PKEY_CTX *hctx = ctx->data;
+	int l = EVP_MD_CTX_size(mctx);
+
+	if (l < 0)
+		return 0;
+	*siglen = l;
+	if (!sig)
+		return 1;
+
+	if (!HMAC_Final(&hctx->ctx, sig, &hlen))
+		return 0;
+	*siglen = (size_t)hlen;
+	return 1;
+}
+
+static int
+pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+	HMAC_PKEY_CTX *hctx = ctx->data;
+	ASN1_OCTET_STRING *key;
+
+	switch (type) {
+	case EVP_PKEY_CTRL_SET_MAC_KEY:
+		if ((!p2 && p1 > 0) || (p1 < -1))
+			return 0;
+		if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1))
+			return 0;
+		break;
+
+	case EVP_PKEY_CTRL_MD:
+		hctx->md = p2;
+		break;
+
+	case EVP_PKEY_CTRL_DIGESTINIT:
+		key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
+		if (!HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md,
+		    ctx->engine))
+			return 0;
+		break;
+
+	default:
+		return -2;
+	}
+	return 1;
+}
+
+static int
+pkey_hmac_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value)
+{
+	if (!value)
+		return 0;
+	if (!strcmp(type, "key")) {
+		void *p = (void *)value;
+		return pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, -1, p);
+	}
+	if (!strcmp(type, "hexkey")) {
+		unsigned char *key;
+		int r;
+		long keylen;
+		key = string_to_hex(value, &keylen);
+		if (!key)
+			return 0;
+		r = pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key);
+		free(key);
+		return r;
+	}
+	return -2;
+}
+
+const EVP_PKEY_METHOD hmac_pkey_meth = {
+	.pkey_id = EVP_PKEY_HMAC,
+
+	.init = pkey_hmac_init,
+	.copy = pkey_hmac_copy,
+	.cleanup = pkey_hmac_cleanup,
+
+	.keygen = pkey_hmac_keygen,
+
+	.signctx_init = hmac_signctx_init,
+	.signctx = hmac_signctx,
+
+	.ctrl = pkey_hmac_ctrl,
+	.ctrl_str = pkey_hmac_ctrl_str
+};
diff --git a/crypto/libressl/crypto/hmac/hmac.c b/crypto/libressl/crypto/hmac/hmac.c
new file mode 100644
index 0000000000..0de0aeccfc
--- /dev/null
+++ b/crypto/libressl/crypto/hmac/hmac.c
@@ -0,0 +1,225 @@
+/* $OpenBSD: hmac.c,v 1.21 2014/07/11 08:44:48 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+int
+HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md,
+    ENGINE *impl)
+{
+	int i, j, reset = 0;
+	unsigned char pad[HMAC_MAX_MD_CBLOCK];
+
+	if (md != NULL) {
+		reset = 1;
+		ctx->md = md;
+	} else
+		md = ctx->md;
+
+	if (key != NULL) {
+		reset = 1;
+		j = EVP_MD_block_size(md);
+		if ((size_t)j > sizeof(ctx->key)) {
+			EVPerr(EVP_F_HMAC_INIT_EX, EVP_R_BAD_BLOCK_LENGTH);
+			goto err;
+		}
+		if (j < len) {
+			if (!EVP_DigestInit_ex(&ctx->md_ctx, md, impl))
+				goto err;
+			if (!EVP_DigestUpdate(&ctx->md_ctx, key, len))
+				goto err;
+			if (!EVP_DigestFinal_ex(&(ctx->md_ctx), ctx->key,
+			    &ctx->key_length))
+				goto err;
+		} else {
+			if ((size_t)len > sizeof(ctx->key)) {
+				EVPerr(EVP_F_HMAC_INIT_EX,
+				    EVP_R_BAD_KEY_LENGTH);
+				goto err;
+			}
+			memcpy(ctx->key, key, len);
+			ctx->key_length = len;
+		}
+		if (ctx->key_length != HMAC_MAX_MD_CBLOCK)
+			memset(&ctx->key[ctx->key_length], 0,
+			    HMAC_MAX_MD_CBLOCK - ctx->key_length);
+	}
+
+	if (reset) {
+		for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++)
+			pad[i] = 0x36 ^ ctx->key[i];
+		if (!EVP_DigestInit_ex(&ctx->i_ctx, md, impl))
+			goto err;
+		if (!EVP_DigestUpdate(&ctx->i_ctx, pad, EVP_MD_block_size(md)))
+			goto err;
+
+		for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++)
+			pad[i] = 0x5c ^ ctx->key[i];
+		if (!EVP_DigestInit_ex(&ctx->o_ctx, md, impl))
+			goto err;
+		if (!EVP_DigestUpdate(&ctx->o_ctx, pad, EVP_MD_block_size(md)))
+			goto err;
+	}
+	if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->i_ctx))
+		goto err;
+	return 1;
+err:
+	return 0;
+}
+
+int
+HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md)
+{
+	if (key && md)
+		HMAC_CTX_init(ctx);
+	return HMAC_Init_ex(ctx, key, len, md, NULL);
+}
+
+int
+HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
+{
+	return EVP_DigestUpdate(&ctx->md_ctx, data, len);
+}
+
+int
+HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
+{
+	unsigned int i;
+	unsigned char buf[EVP_MAX_MD_SIZE];
+
+	if (!EVP_DigestFinal_ex(&ctx->md_ctx, buf, &i))
+		goto err;
+	if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->o_ctx))
+		goto err;
+	if (!EVP_DigestUpdate(&ctx->md_ctx, buf, i))
+		goto err;
+	if (!EVP_DigestFinal_ex(&ctx->md_ctx, md, len))
+		goto err;
+	return 1;
+err:
+	return 0;
+}
+
+void
+HMAC_CTX_init(HMAC_CTX *ctx)
+{
+	EVP_MD_CTX_init(&ctx->i_ctx);
+	EVP_MD_CTX_init(&ctx->o_ctx);
+	EVP_MD_CTX_init(&ctx->md_ctx);
+}
+
+int
+HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx)
+{
+	if (!EVP_MD_CTX_copy(&dctx->i_ctx, &sctx->i_ctx))
+		goto err;
+	if (!EVP_MD_CTX_copy(&dctx->o_ctx, &sctx->o_ctx))
+		goto err;
+	if (!EVP_MD_CTX_copy(&dctx->md_ctx, &sctx->md_ctx))
+		goto err;
+	memcpy(dctx->key, sctx->key, HMAC_MAX_MD_CBLOCK);
+	dctx->key_length = sctx->key_length;
+	dctx->md = sctx->md;
+	return 1;
+err:
+	return 0;
+}
+
+void
+HMAC_CTX_cleanup(HMAC_CTX *ctx)
+{
+	EVP_MD_CTX_cleanup(&ctx->i_ctx);
+	EVP_MD_CTX_cleanup(&ctx->o_ctx);
+	EVP_MD_CTX_cleanup(&ctx->md_ctx);
+	memset(ctx, 0, sizeof *ctx);
+}
+
+unsigned char *
+HMAC(const EVP_MD *evp_md, const void *key, int key_len, const unsigned char *d,
+    size_t n, unsigned char *md, unsigned int *md_len)
+{
+	HMAC_CTX c;
+	static unsigned char m[EVP_MAX_MD_SIZE];
+
+	if (md == NULL)
+		md = m;
+	HMAC_CTX_init(&c);
+	if (!HMAC_Init(&c, key, key_len, evp_md))
+		goto err;
+	if (!HMAC_Update(&c, d, n))
+		goto err;
+	if (!HMAC_Final(&c, md, md_len))
+		goto err;
+	HMAC_CTX_cleanup(&c);
+	return md;
+err:
+	return NULL;
+}
+
+void
+HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags)
+{
+	EVP_MD_CTX_set_flags(&ctx->i_ctx, flags);
+	EVP_MD_CTX_set_flags(&ctx->o_ctx, flags);
+	EVP_MD_CTX_set_flags(&ctx->md_ctx, flags);
+}
diff --git a/crypto/libressl/crypto/idea/i_cbc.c b/crypto/libressl/crypto/idea/i_cbc.c
new file mode 100644
index 0000000000..2078af8d9e
--- /dev/null
+++ b/crypto/libressl/crypto/idea/i_cbc.c
@@ -0,0 +1,168 @@
+/* $OpenBSD: i_cbc.c,v 1.2 2014/06/12 15:49:29 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include "idea_lcl.h"
+
+void idea_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+	     IDEA_KEY_SCHEDULE *ks, unsigned char *iv, int encrypt)
+	{
+	unsigned long tin0,tin1;
+	unsigned long tout0,tout1,xor0,xor1;
+	long l=length;
+	unsigned long tin[2];
+
+	if (encrypt)
+		{
+		n2l(iv,tout0);
+		n2l(iv,tout1);
+		iv-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			n2l(in,tin0);
+			n2l(in,tin1);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			idea_encrypt(tin,ks);
+			tout0=tin[0]; l2n(tout0,out);
+			tout1=tin[1]; l2n(tout1,out);
+			}
+		if (l != -8)
+			{
+			n2ln(in,tin0,tin1,l+8);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			idea_encrypt(tin,ks);
+			tout0=tin[0]; l2n(tout0,out);
+			tout1=tin[1]; l2n(tout1,out);
+			}
+		l2n(tout0,iv);
+		l2n(tout1,iv);
+		}
+	else
+		{
+		n2l(iv,xor0);
+		n2l(iv,xor1);
+		iv-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			n2l(in,tin0); tin[0]=tin0;
+			n2l(in,tin1); tin[1]=tin1;
+			idea_encrypt(tin,ks);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2n(tout0,out);
+			l2n(tout1,out);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		if (l != -8)
+			{
+			n2l(in,tin0); tin[0]=tin0;
+			n2l(in,tin1); tin[1]=tin1;
+			idea_encrypt(tin,ks);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2nn(tout0,tout1,out,l+8);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		l2n(xor0,iv);
+		l2n(xor1,iv);
+		}
+	tin0=tin1=tout0=tout1=xor0=xor1=0;
+	tin[0]=tin[1]=0;
+	}
+
+void idea_encrypt(unsigned long *d, IDEA_KEY_SCHEDULE *key)
+	{
+	IDEA_INT *p;
+	unsigned long x1,x2,x3,x4,t0,t1,ul;
+
+	x2=d[0];
+	x1=(x2>>16);
+	x4=d[1];
+	x3=(x4>>16);
+
+	p= &(key->data[0][0]);
+
+	E_IDEA(0);
+	E_IDEA(1);
+	E_IDEA(2);
+	E_IDEA(3);
+	E_IDEA(4);
+	E_IDEA(5);
+	E_IDEA(6);
+	E_IDEA(7);
+
+	x1&=0xffff;
+	idea_mul(x1,x1,*p,ul); p++;
+
+	t0= x3+ *(p++);
+	t1= x2+ *(p++);
+
+	x4&=0xffff;
+	idea_mul(x4,x4,*p,ul);
+
+	d[0]=(t0&0xffff)|((x1&0xffff)<<16);
+	d[1]=(x4&0xffff)|((t1&0xffff)<<16);
+	}
diff --git a/crypto/libressl/crypto/idea/i_cfb64.c b/crypto/libressl/crypto/idea/i_cfb64.c
new file mode 100644
index 0000000000..04f36c9349
--- /dev/null
+++ b/crypto/libressl/crypto/idea/i_cfb64.c
@@ -0,0 +1,122 @@
+/* $OpenBSD: i_cfb64.c,v 1.2 2014/06/12 15:49:29 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include "idea_lcl.h"
+
+/* The input and output encrypted as though 64bit cfb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+
+void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+			long length, IDEA_KEY_SCHEDULE *schedule,
+			unsigned char *ivec, int *num, int encrypt)
+	{
+	unsigned long v0,v1,t;
+	int n= *num;
+	long l=length;
+	unsigned long ti[2];
+	unsigned char *iv,c,cc;
+
+	iv=(unsigned char *)ivec;
+	if (encrypt)
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				n2l(iv,v0); ti[0]=v0;
+				n2l(iv,v1); ti[1]=v1;
+				idea_encrypt((unsigned long *)ti,schedule);
+				iv=(unsigned char *)ivec;
+				t=ti[0]; l2n(t,iv);
+				t=ti[1]; l2n(t,iv);
+				iv=(unsigned char *)ivec;
+				}
+			c= *(in++)^iv[n];
+			*(out++)=c;
+			iv[n]=c;
+			n=(n+1)&0x07;
+			}
+		}
+	else
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				n2l(iv,v0); ti[0]=v0;
+				n2l(iv,v1); ti[1]=v1;
+				idea_encrypt((unsigned long *)ti,schedule);
+				iv=(unsigned char *)ivec;
+				t=ti[0]; l2n(t,iv);
+				t=ti[1]; l2n(t,iv);
+				iv=(unsigned char *)ivec;
+				}
+			cc= *(in++);
+			c=iv[n];
+			iv[n]=cc;
+			*(out++)=c^cc;
+			n=(n+1)&0x07;
+			}
+		}
+	v0=v1=ti[0]=ti[1]=t=c=cc=0;
+	*num=n;
+	}
+
diff --git a/crypto/libressl/crypto/idea/i_ecb.c b/crypto/libressl/crypto/idea/i_ecb.c
new file mode 100644
index 0000000000..602a3a9354
--- /dev/null
+++ b/crypto/libressl/crypto/idea/i_ecb.c
@@ -0,0 +1,83 @@
+/* $OpenBSD: i_ecb.c,v 1.2 2014/06/12 15:49:29 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include "idea_lcl.h"
+#include 
+
+const char *idea_options(void)
+	{
+	if (sizeof(short) != sizeof(IDEA_INT))
+		return("idea(int)");
+	else
+		return("idea(short)");
+	}
+
+void idea_ecb_encrypt(const unsigned char *in, unsigned char *out,
+	     IDEA_KEY_SCHEDULE *ks)
+	{
+	unsigned long l0,l1,d[2];
+
+	n2l(in,l0); d[0]=l0;
+	n2l(in,l1); d[1]=l1;
+	idea_encrypt(d,ks);
+	l0=d[0]; l2n(l0,out);
+	l1=d[1]; l2n(l1,out);
+	l0=l1=d[0]=d[1]=0;
+	}
+
diff --git a/crypto/libressl/crypto/idea/i_ofb64.c b/crypto/libressl/crypto/idea/i_ofb64.c
new file mode 100644
index 0000000000..5814831639
--- /dev/null
+++ b/crypto/libressl/crypto/idea/i_ofb64.c
@@ -0,0 +1,111 @@
+/* $OpenBSD: i_ofb64.c,v 1.2 2014/06/12 15:49:29 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include "idea_lcl.h"
+
+/* The input and output encrypted as though 64bit ofb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+void idea_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+			long length, IDEA_KEY_SCHEDULE *schedule,
+			unsigned char *ivec, int *num)
+	{
+	unsigned long v0,v1,t;
+	int n= *num;
+	long l=length;
+	unsigned char d[8];
+	char *dp;
+	unsigned long ti[2];
+	unsigned char *iv;
+	int save=0;
+
+	iv=(unsigned char *)ivec;
+	n2l(iv,v0);
+	n2l(iv,v1);
+	ti[0]=v0;
+	ti[1]=v1;
+	dp=(char *)d;
+	l2n(v0,dp);
+	l2n(v1,dp);
+	while (l--)
+		{
+		if (n == 0)
+			{
+			idea_encrypt((unsigned long *)ti,schedule);
+			dp=(char *)d;
+			t=ti[0]; l2n(t,dp);
+			t=ti[1]; l2n(t,dp);
+			save++;
+			}
+		*(out++)= *(in++)^d[n];
+		n=(n+1)&0x07;
+		}
+	if (save)
+		{
+		v0=ti[0];
+		v1=ti[1];
+		iv=(unsigned char *)ivec;
+		l2n(v0,iv);
+		l2n(v1,iv);
+		}
+	t=v0=v1=ti[0]=ti[1]=0;
+	*num=n;
+	}
+
diff --git a/crypto/libressl/crypto/idea/i_skey.c b/crypto/libressl/crypto/idea/i_skey.c
new file mode 100644
index 0000000000..5a6fed17e2
--- /dev/null
+++ b/crypto/libressl/crypto/idea/i_skey.c
@@ -0,0 +1,157 @@
+/* $OpenBSD: i_skey.c,v 1.3 2014/06/12 15:49:29 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include "idea_lcl.h"
+
+static IDEA_INT inverse(unsigned int xin);
+void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks)
+	{
+	int i;
+	IDEA_INT *kt,*kf,r0,r1,r2;
+
+	kt= &(ks->data[0][0]);
+	n2s(key,kt[0]); n2s(key,kt[1]); n2s(key,kt[2]); n2s(key,kt[3]);
+	n2s(key,kt[4]); n2s(key,kt[5]); n2s(key,kt[6]); n2s(key,kt[7]);
+
+	kf=kt;
+	kt+=8;
+	for (i=0; i<6; i++)
+		{
+		r2= kf[1];
+		r1= kf[2];
+		*(kt++)= ((r2<<9) | (r1>>7))&0xffff;
+		r0= kf[3];
+		*(kt++)= ((r1<<9) | (r0>>7))&0xffff;
+		r1= kf[4];
+		*(kt++)= ((r0<<9) | (r1>>7))&0xffff;
+		r0= kf[5];
+		*(kt++)= ((r1<<9) | (r0>>7))&0xffff;
+		r1= kf[6];
+		*(kt++)= ((r0<<9) | (r1>>7))&0xffff;
+		r0= kf[7];
+		*(kt++)= ((r1<<9) | (r0>>7))&0xffff;
+		r1= kf[0];
+		if (i >= 5) break;
+		*(kt++)= ((r0<<9) | (r1>>7))&0xffff;
+		*(kt++)= ((r1<<9) | (r2>>7))&0xffff;
+		kf+=8;
+		}
+	}
+
+void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk)
+	{
+	int r;
+	IDEA_INT *fp,*tp,t;
+
+	tp= &(dk->data[0][0]);
+	fp= &(ek->data[8][0]);
+	for (r=0; r<9; r++)
+		{
+		*(tp++)=inverse(fp[0]);
+		*(tp++)=((int)(0x10000L-fp[2])&0xffff);
+		*(tp++)=((int)(0x10000L-fp[1])&0xffff);
+		*(tp++)=inverse(fp[3]);
+		if (r == 8) break;
+		fp-=6;
+		*(tp++)=fp[4];
+		*(tp++)=fp[5];
+		}
+
+	tp= &(dk->data[0][0]);
+	t=tp[1];
+	tp[1]=tp[2];
+	tp[2]=t;
+
+	t=tp[49];
+	tp[49]=tp[50];
+	tp[50]=t;
+	}
+
+/* taken directly from the 'paper' I'll have a look at it later */
+static IDEA_INT inverse(unsigned int xin)
+	{
+	long n1,n2,q,r,b1,b2,t;
+
+	if (xin == 0)
+		b2=0;
+	else
+		{
+		n1=0x10001;
+		n2=xin;
+		b2=1;
+		b1=0;
+
+		do	{
+			r=(n1%n2);
+			q=(n1-r)/n2;
+			if (r == 0)
+				{ if (b2 < 0) b2=0x10001+b2; }
+			else
+				{
+				n1=n2;
+				n2=r;
+				t=b2;
+				b2=b1-q*b2;
+				b1=t;
+				}
+			} while (r != 0);
+		}
+	return((IDEA_INT)b2);
+	}
diff --git a/crypto/libressl/crypto/idea/idea_lcl.h b/crypto/libressl/crypto/idea/idea_lcl.h
new file mode 100644
index 0000000000..17400c17db
--- /dev/null
+++ b/crypto/libressl/crypto/idea/idea_lcl.h
@@ -0,0 +1,150 @@
+/* $OpenBSD: idea_lcl.h,v 1.2 2014/06/12 15:49:29 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* The new form of this macro (check if the a*b == 0) was suggested by 
+ * Colin Plumb  */
+/* Removal of the inner if from from Wei Dai 24/4/96 */
+#define idea_mul(r,a,b,ul) \
+ul=(unsigned long)a*b; \
+if (ul != 0) \
+	{ \
+	r=(ul&0xffff)-(ul>>16); \
+	r-=((r)>>16); \
+	} \
+else \
+	r=(-(int)a-b+1); /* assuming a or b is 0 and in range */ 
+
+/*  7/12/95 - Many thanks to Rhys Weatherley 
+ * for pointing out that I was assuming little endian
+ * byte order for all quantities what idea
+ * actually used bigendian.  No where in the spec does it mention
+ * this, it is all in terms of 16 bit numbers and even the example
+ * does not use byte streams for the input example :-(.
+ * If you byte swap each pair of input, keys and iv, the functions
+ * would produce the output as the old version :-(.
+ */
+
+/* NOTE - c is not incremented as per n2l */
+#define n2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))    ; \
+			case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
+			case 6: l2|=((unsigned long)(*(--(c))))<<16; \
+			case 5: l2|=((unsigned long)(*(--(c))))<<24; \
+			case 4: l1 =((unsigned long)(*(--(c))))    ; \
+			case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
+			case 2: l1|=((unsigned long)(*(--(c))))<<16; \
+			case 1: l1|=((unsigned long)(*(--(c))))<<24; \
+				} \
+			}
+
+/* NOTE - c is not incremented as per l2n */
+#define l2nn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+				} \
+			}
+
+#undef n2l
+#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
+                         l|=((unsigned long)(*((c)++)))<<16L, \
+                         l|=((unsigned long)(*((c)++)))<< 8L, \
+                         l|=((unsigned long)(*((c)++))))
+
+#undef l2n
+#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)     )&0xff))
+
+#undef s2n
+#define s2n(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff))
+
+#undef n2s
+#define n2s(c,l)	(l =((IDEA_INT)(*((c)++)))<< 8L, \
+			 l|=((IDEA_INT)(*((c)++)))      )
+
+#define E_IDEA(num) \
+	x1&=0xffff; \
+	idea_mul(x1,x1,*p,ul); p++; \
+	x2+= *(p++); \
+	x3+= *(p++); \
+	x4&=0xffff; \
+	idea_mul(x4,x4,*p,ul); p++; \
+	t0=(x1^x3)&0xffff; \
+	idea_mul(t0,t0,*p,ul); p++; \
+	t1=(t0+(x2^x4))&0xffff; \
+	idea_mul(t1,t1,*p,ul); p++; \
+	t0+=t1; \
+	x1^=t1; \
+	x4^=t0; \
+	ul=x2^t0; /* do the swap to x3 */ \
+	x2=x3^t1; \
+	x3=ul;
+
diff --git a/crypto/libressl/crypto/krb5/krb5_asn.c b/crypto/libressl/crypto/krb5/krb5_asn.c
new file mode 100644
index 0000000000..158d2d0f8d
--- /dev/null
+++ b/crypto/libressl/crypto/krb5/krb5_asn.c
@@ -0,0 +1,722 @@
+/* $OpenBSD: krb5_asn.c,v 1.3 2015/02/09 16:04:46 jsing Exp $ */
+/* Written by Vern Staats  for the OpenSSL project,
+** using ocsp/{*.h,*asn*.c} as a starting point
+*/
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include 
+#include 
+#include 
+
+
+static const ASN1_TEMPLATE KRB5_ENCDATA_seq_tt[] = {
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 0,
+		.offset = offsetof(KRB5_ENCDATA, etype),
+		.field_name = "etype",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 1,
+		.offset = offsetof(KRB5_ENCDATA, kvno),
+		.field_name = "kvno",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 2,
+		.offset = offsetof(KRB5_ENCDATA, cipher),
+		.field_name = "cipher",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+};
+
+const ASN1_ITEM KRB5_ENCDATA_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = KRB5_ENCDATA_seq_tt,
+	.tcount = sizeof(KRB5_ENCDATA_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(KRB5_ENCDATA),
+	.sname = "KRB5_ENCDATA",
+};
+
+
+KRB5_ENCDATA *
+d2i_KRB5_ENCDATA(KRB5_ENCDATA **a, const unsigned char **in, long len)
+{
+	return (KRB5_ENCDATA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &KRB5_ENCDATA_it);
+}
+
+int
+i2d_KRB5_ENCDATA(KRB5_ENCDATA *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &KRB5_ENCDATA_it);
+}
+
+KRB5_ENCDATA *
+KRB5_ENCDATA_new(void)
+{
+	return (KRB5_ENCDATA *)ASN1_item_new(&KRB5_ENCDATA_it);
+}
+
+void
+KRB5_ENCDATA_free(KRB5_ENCDATA *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &KRB5_ENCDATA_it);
+}
+
+
+static const ASN1_TEMPLATE KRB5_PRINCNAME_seq_tt[] = {
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 0,
+		.offset = offsetof(KRB5_PRINCNAME, nametype),
+		.field_name = "nametype",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF,
+		.tag = 1,
+		.offset = offsetof(KRB5_PRINCNAME, namestring),
+		.field_name = "namestring",
+		.item = &ASN1_GENERALSTRING_it,
+	},
+};
+
+const ASN1_ITEM KRB5_PRINCNAME_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = KRB5_PRINCNAME_seq_tt,
+	.tcount = sizeof(KRB5_PRINCNAME_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(KRB5_PRINCNAME),
+	.sname = "KRB5_PRINCNAME",
+};
+
+
+KRB5_PRINCNAME *
+d2i_KRB5_PRINCNAME(KRB5_PRINCNAME **a, const unsigned char **in, long len)
+{
+	return (KRB5_PRINCNAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &KRB5_PRINCNAME_it);
+}
+
+int
+i2d_KRB5_PRINCNAME(KRB5_PRINCNAME *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &KRB5_PRINCNAME_it);
+}
+
+KRB5_PRINCNAME *
+KRB5_PRINCNAME_new(void)
+{
+	return (KRB5_PRINCNAME *)ASN1_item_new(&KRB5_PRINCNAME_it);
+}
+
+void
+KRB5_PRINCNAME_free(KRB5_PRINCNAME *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &KRB5_PRINCNAME_it);
+}
+
+
+/* [APPLICATION 1] = 0x61 */
+static const ASN1_TEMPLATE KRB5_TKTBODY_seq_tt[] = {
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 0,
+		.offset = offsetof(KRB5_TKTBODY, tktvno),
+		.field_name = "tktvno",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 1,
+		.offset = offsetof(KRB5_TKTBODY, realm),
+		.field_name = "realm",
+		.item = &ASN1_GENERALSTRING_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 2,
+		.offset = offsetof(KRB5_TKTBODY, sname),
+		.field_name = "sname",
+		.item = &KRB5_PRINCNAME_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 3,
+		.offset = offsetof(KRB5_TKTBODY, encdata),
+		.field_name = "encdata",
+		.item = &KRB5_ENCDATA_it,
+	},
+};
+
+const ASN1_ITEM KRB5_TKTBODY_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = KRB5_TKTBODY_seq_tt,
+	.tcount = sizeof(KRB5_TKTBODY_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(KRB5_TKTBODY),
+	.sname = "KRB5_TKTBODY",
+};
+
+
+KRB5_TKTBODY *
+d2i_KRB5_TKTBODY(KRB5_TKTBODY **a, const unsigned char **in, long len)
+{
+	return (KRB5_TKTBODY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &KRB5_TKTBODY_it);
+}
+
+int
+i2d_KRB5_TKTBODY(KRB5_TKTBODY *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &KRB5_TKTBODY_it);
+}
+
+KRB5_TKTBODY *
+KRB5_TKTBODY_new(void)
+{
+	return (KRB5_TKTBODY *)ASN1_item_new(&KRB5_TKTBODY_it);
+}
+
+void
+KRB5_TKTBODY_free(KRB5_TKTBODY *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &KRB5_TKTBODY_it);
+}
+
+
+static const ASN1_TEMPLATE KRB5_TICKET_item_tt =  {
+	.flags = ASN1_TFLG_EXPTAG | ASN1_TFLG_APPLICATION,
+	.tag = 1,
+	.offset = 0,
+	.field_name = "KRB5_TICKET",
+	.item = &KRB5_TKTBODY_it,
+};
+
+const ASN1_ITEM KRB5_TICKET_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = -1,
+	.templates = &KRB5_TICKET_item_tt,
+	.tcount = 0,
+	.funcs = NULL,
+	.size = 0,
+	.sname = "KRB5_TICKET",
+};
+
+
+KRB5_TICKET *
+d2i_KRB5_TICKET(KRB5_TICKET **a, const unsigned char **in, long len)
+{
+	return (KRB5_TICKET *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &KRB5_TICKET_it);
+}
+
+int
+i2d_KRB5_TICKET(KRB5_TICKET *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &KRB5_TICKET_it);
+}
+
+KRB5_TICKET *
+KRB5_TICKET_new(void)
+{
+	return (KRB5_TICKET *)ASN1_item_new(&KRB5_TICKET_it);
+}
+
+void
+KRB5_TICKET_free(KRB5_TICKET *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &KRB5_TICKET_it);
+}
+
+
+/* [APPLICATION 14] = 0x6e */
+static const ASN1_TEMPLATE KRB5_APREQBODY_seq_tt[] = {
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 0,
+		.offset = offsetof(KRB5_APREQBODY, pvno),
+		.field_name = "pvno",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 1,
+		.offset = offsetof(KRB5_APREQBODY, msgtype),
+		.field_name = "msgtype",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 2,
+		.offset = offsetof(KRB5_APREQBODY, apoptions),
+		.field_name = "apoptions",
+		.item = &ASN1_BIT_STRING_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 3,
+		.offset = offsetof(KRB5_APREQBODY, ticket),
+		.field_name = "ticket",
+		.item = &KRB5_TICKET_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 4,
+		.offset = offsetof(KRB5_APREQBODY, authenticator),
+		.field_name = "authenticator",
+		.item = &KRB5_ENCDATA_it,
+	},
+};
+
+const ASN1_ITEM KRB5_APREQBODY_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = KRB5_APREQBODY_seq_tt,
+	.tcount = sizeof(KRB5_APREQBODY_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(KRB5_APREQBODY),
+	.sname = "KRB5_APREQBODY",
+};
+
+
+KRB5_APREQBODY *
+d2i_KRB5_APREQBODY(KRB5_APREQBODY **a, const unsigned char **in, long len)
+{
+	return (KRB5_APREQBODY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &KRB5_APREQBODY_it);
+}
+
+int
+i2d_KRB5_APREQBODY(KRB5_APREQBODY *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &KRB5_APREQBODY_it);
+}
+
+KRB5_APREQBODY *
+KRB5_APREQBODY_new(void)
+{
+	return (KRB5_APREQBODY *)ASN1_item_new(&KRB5_APREQBODY_it);
+}
+
+void
+KRB5_APREQBODY_free(KRB5_APREQBODY *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &KRB5_APREQBODY_it);
+}
+
+static const ASN1_TEMPLATE KRB5_APREQ_item_tt =  {
+	.flags = ASN1_TFLG_EXPTAG | ASN1_TFLG_APPLICATION,
+	.tag = 14,
+	.offset = 0,
+	.field_name = "KRB5_APREQ",
+	.item = &KRB5_APREQBODY_it,
+};
+
+const ASN1_ITEM KRB5_APREQ_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = -1,
+	.templates = &KRB5_APREQ_item_tt,
+	.tcount = 0,
+	.funcs = NULL,
+	.size = 0,
+	.sname = "KRB5_APREQ",
+};
+
+
+KRB5_APREQ *
+d2i_KRB5_APREQ(KRB5_APREQ **a, const unsigned char **in, long len)
+{
+	return (KRB5_APREQ *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &KRB5_APREQ_it);
+}
+
+int
+i2d_KRB5_APREQ(KRB5_APREQ *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &KRB5_APREQ_it);
+}
+
+KRB5_APREQ *
+KRB5_APREQ_new(void)
+{
+	return (KRB5_APREQ *)ASN1_item_new(&KRB5_APREQ_it);
+}
+
+void
+KRB5_APREQ_free(KRB5_APREQ *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &KRB5_APREQ_it);
+}
+
+
+/*  Authenticator stuff 	*/
+
+static const ASN1_TEMPLATE KRB5_CHECKSUM_seq_tt[] = {
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 0,
+		.offset = offsetof(KRB5_CHECKSUM, ctype),
+		.field_name = "ctype",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 1,
+		.offset = offsetof(KRB5_CHECKSUM, checksum),
+		.field_name = "checksum",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+};
+
+const ASN1_ITEM KRB5_CHECKSUM_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = KRB5_CHECKSUM_seq_tt,
+	.tcount = sizeof(KRB5_CHECKSUM_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(KRB5_CHECKSUM),
+	.sname = "KRB5_CHECKSUM",
+};
+
+
+KRB5_CHECKSUM *
+d2i_KRB5_CHECKSUM(KRB5_CHECKSUM **a, const unsigned char **in, long len)
+{
+	return (KRB5_CHECKSUM *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &KRB5_CHECKSUM_it);
+}
+
+int
+i2d_KRB5_CHECKSUM(KRB5_CHECKSUM *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &KRB5_CHECKSUM_it);
+}
+
+KRB5_CHECKSUM *
+KRB5_CHECKSUM_new(void)
+{
+	return (KRB5_CHECKSUM *)ASN1_item_new(&KRB5_CHECKSUM_it);
+}
+
+void
+KRB5_CHECKSUM_free(KRB5_CHECKSUM *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &KRB5_CHECKSUM_it);
+}
+
+
+static const ASN1_TEMPLATE KRB5_ENCKEY_seq_tt[] = {
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 0,
+		.offset = offsetof(KRB5_ENCKEY, ktype),
+		.field_name = "ktype",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 1,
+		.offset = offsetof(KRB5_ENCKEY, keyvalue),
+		.field_name = "keyvalue",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+};
+
+const ASN1_ITEM KRB5_ENCKEY_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = KRB5_ENCKEY_seq_tt,
+	.tcount = sizeof(KRB5_ENCKEY_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(KRB5_ENCKEY),
+	.sname = "KRB5_ENCKEY",
+};
+
+
+KRB5_ENCKEY *
+d2i_KRB5_ENCKEY(KRB5_ENCKEY **a, const unsigned char **in, long len)
+{
+	return (KRB5_ENCKEY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &KRB5_ENCKEY_it);
+}
+
+int
+i2d_KRB5_ENCKEY(KRB5_ENCKEY *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &KRB5_ENCKEY_it);
+}
+
+KRB5_ENCKEY *
+KRB5_ENCKEY_new(void)
+{
+	return (KRB5_ENCKEY *)ASN1_item_new(&KRB5_ENCKEY_it);
+}
+
+void
+KRB5_ENCKEY_free(KRB5_ENCKEY *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &KRB5_ENCKEY_it);
+}
+
+
+/* SEQ OF SEQ; see ASN1_EXP_SEQUENCE_OF_OPT() below */
+static const ASN1_TEMPLATE KRB5_AUTHDATA_seq_tt[] = {
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 0,
+		.offset = offsetof(KRB5_AUTHDATA, adtype),
+		.field_name = "adtype",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 1,
+		.offset = offsetof(KRB5_AUTHDATA, addata),
+		.field_name = "addata",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+};
+
+const ASN1_ITEM KRB5_AUTHDATA_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = KRB5_AUTHDATA_seq_tt,
+	.tcount = sizeof(KRB5_AUTHDATA_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(KRB5_AUTHDATA),
+	.sname = "KRB5_AUTHDATA",
+};
+
+
+KRB5_AUTHDATA *
+d2i_KRB5_AUTHDATA(KRB5_AUTHDATA **a, const unsigned char **in, long len)
+{
+	return (KRB5_AUTHDATA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &KRB5_AUTHDATA_it);
+}
+
+int
+i2d_KRB5_AUTHDATA(KRB5_AUTHDATA *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &KRB5_AUTHDATA_it);
+}
+
+KRB5_AUTHDATA *
+KRB5_AUTHDATA_new(void)
+{
+	return (KRB5_AUTHDATA *)ASN1_item_new(&KRB5_AUTHDATA_it);
+}
+
+void
+KRB5_AUTHDATA_free(KRB5_AUTHDATA *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &KRB5_AUTHDATA_it);
+}
+
+
+/* [APPLICATION 2] = 0x62 */
+static const ASN1_TEMPLATE KRB5_AUTHENTBODY_seq_tt[] = {
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 0,
+		.offset = offsetof(KRB5_AUTHENTBODY, avno),
+		.field_name = "avno",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 1,
+		.offset = offsetof(KRB5_AUTHENTBODY, crealm),
+		.field_name = "crealm",
+		.item = &ASN1_GENERALSTRING_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 2,
+		.offset = offsetof(KRB5_AUTHENTBODY, cname),
+		.field_name = "cname",
+		.item = &KRB5_PRINCNAME_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 3,
+		.offset = offsetof(KRB5_AUTHENTBODY, cksum),
+		.field_name = "cksum",
+		.item = &KRB5_CHECKSUM_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 4,
+		.offset = offsetof(KRB5_AUTHENTBODY, cusec),
+		.field_name = "cusec",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 5,
+		.offset = offsetof(KRB5_AUTHENTBODY, ctime),
+		.field_name = "ctime",
+		.item = &ASN1_GENERALIZEDTIME_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 6,
+		.offset = offsetof(KRB5_AUTHENTBODY, subkey),
+		.field_name = "subkey",
+		.item = &KRB5_ENCKEY_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 7,
+		.offset = offsetof(KRB5_AUTHENTBODY, seqnum),
+		.field_name = "seqnum",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
+		.tag = 8,
+		.offset = offsetof(KRB5_AUTHENTBODY, authorization),
+		.field_name = "authorization",
+		.item = &KRB5_AUTHDATA_it,
+	},
+};
+
+const ASN1_ITEM KRB5_AUTHENTBODY_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = KRB5_AUTHENTBODY_seq_tt,
+	.tcount = sizeof(KRB5_AUTHENTBODY_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(KRB5_AUTHENTBODY),
+	.sname = "KRB5_AUTHENTBODY",
+};
+
+
+KRB5_AUTHENTBODY *
+d2i_KRB5_AUTHENTBODY(KRB5_AUTHENTBODY **a, const unsigned char **in, long len)
+{
+	return (KRB5_AUTHENTBODY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &KRB5_AUTHENTBODY_it);
+}
+
+int
+i2d_KRB5_AUTHENTBODY(KRB5_AUTHENTBODY *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &KRB5_AUTHENTBODY_it);
+}
+
+KRB5_AUTHENTBODY *
+KRB5_AUTHENTBODY_new(void)
+{
+	return (KRB5_AUTHENTBODY *)ASN1_item_new(&KRB5_AUTHENTBODY_it);
+}
+
+void
+KRB5_AUTHENTBODY_free(KRB5_AUTHENTBODY *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &KRB5_AUTHENTBODY_it);
+}
+
+static const ASN1_TEMPLATE KRB5_AUTHENT_item_tt =  {
+	.flags = ASN1_TFLG_EXPTAG | ASN1_TFLG_APPLICATION,
+	.tag = 2,
+	.offset = 0,
+	.field_name = "KRB5_AUTHENT",
+	.item = &KRB5_AUTHENTBODY_it,
+};
+
+const ASN1_ITEM KRB5_AUTHENT_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = -1,
+	.templates = &KRB5_AUTHENT_item_tt,
+	.tcount = 0,
+	.funcs = NULL,
+	.size = 0,
+	.sname = "KRB5_AUTHENT",
+};
+
+
+KRB5_AUTHENT *
+d2i_KRB5_AUTHENT(KRB5_AUTHENT **a, const unsigned char **in, long len)
+{
+	return (KRB5_AUTHENT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &KRB5_AUTHENT_it);
+}
+
+int
+i2d_KRB5_AUTHENT(KRB5_AUTHENT *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &KRB5_AUTHENT_it);
+}
+
+KRB5_AUTHENT *
+KRB5_AUTHENT_new(void)
+{
+	return (KRB5_AUTHENT *)ASN1_item_new(&KRB5_AUTHENT_it);
+}
+
+void
+KRB5_AUTHENT_free(KRB5_AUTHENT *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &KRB5_AUTHENT_it);
+}
diff --git a/crypto/libressl/crypto/lhash/lh_stats.c b/crypto/libressl/crypto/lhash/lh_stats.c
new file mode 100644
index 0000000000..dbadf260ba
--- /dev/null
+++ b/crypto/libressl/crypto/lhash/lh_stats.c
@@ -0,0 +1,254 @@
+/* $OpenBSD: lh_stats.c,v 1.11 2014/07/10 22:45:57 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_BIO
+#include 
+#endif
+#include 
+
+#ifdef OPENSSL_NO_BIO
+
+void
+lh_stats(LHASH *lh, FILE *out)
+{
+	fprintf(out, "num_items             = %lu\n", lh->num_items);
+	fprintf(out, "num_nodes             = %u\n", lh->num_nodes);
+	fprintf(out, "num_alloc_nodes       = %u\n", lh->num_alloc_nodes);
+	fprintf(out, "num_expands           = %lu\n", lh->num_expands);
+	fprintf(out, "num_expand_reallocs   = %lu\n", lh->num_expand_reallocs);
+	fprintf(out, "num_contracts         = %lu\n", lh->num_contracts);
+	fprintf(out, "num_contract_reallocs = %lu\n",
+	    lh->num_contract_reallocs);
+	fprintf(out, "num_hash_calls        = %lu\n", lh->num_hash_calls);
+	fprintf(out, "num_comp_calls        = %lu\n", lh->num_comp_calls);
+	fprintf(out, "num_insert            = %lu\n", lh->num_insert);
+	fprintf(out, "num_replace           = %lu\n", lh->num_replace);
+	fprintf(out, "num_delete            = %lu\n", lh->num_delete);
+	fprintf(out, "num_no_delete         = %lu\n", lh->num_no_delete);
+	fprintf(out, "num_retrieve          = %lu\n", lh->num_retrieve);
+	fprintf(out, "num_retrieve_miss     = %lu\n", lh->num_retrieve_miss);
+	fprintf(out, "num_hash_comps        = %lu\n", lh->num_hash_comps);
+#if 0
+	fprintf(out, "p                     = %u\n", lh->p);
+	fprintf(out, "pmax                  = %u\n", lh->pmax);
+	fprintf(out, "up_load               = %lu\n", lh->up_load);
+	fprintf(out, "down_load             = %lu\n", lh->down_load);
+#endif
+}
+
+void
+lh_node_stats(LHASH *lh, FILE *out)
+{
+	LHASH_NODE *n;
+	unsigned int i, num;
+
+	for (i = 0; i < lh->num_nodes; i++) {
+		for (n = lh->b[i], num = 0; n != NULL; n = n->next)
+			num++;
+		fprintf(out, "node %6u -> %3u\n", i, num);
+	}
+}
+
+void
+lh_node_usage_stats(LHASH *lh, FILE *out)
+{
+	LHASH_NODE *n;
+	unsigned long num;
+	unsigned int i;
+	unsigned long total = 0, n_used = 0;
+
+	for (i = 0; i < lh->num_nodes; i++) {
+		for (n = lh->b[i], num = 0; n != NULL; n = n->next)
+			num++;
+		if (num != 0) {
+			n_used++;
+			total += num;
+		}
+	}
+	fprintf(out, "%lu nodes used out of %u\n", n_used, lh->num_nodes);
+	fprintf(out, "%lu items\n", total);
+	if (n_used == 0)
+		return;
+	fprintf(out, "load %d.%02d  actual load %d.%02d\n",
+	    (int)(total / lh->num_nodes),
+	    (int)((total % lh->num_nodes) * 100 / lh->num_nodes),
+	    (int)(total / n_used),
+	    (int)((total % n_used) * 100 / n_used));
+}
+
+#else
+
+void
+lh_stats(const _LHASH *lh, FILE *fp)
+{
+	BIO *bp;
+
+	bp = BIO_new(BIO_s_file());
+	if (bp == NULL)
+		goto end;
+	BIO_set_fp(bp, fp, BIO_NOCLOSE);
+	lh_stats_bio(lh, bp);
+	BIO_free(bp);
+end:;
+}
+
+void
+lh_node_stats(const _LHASH *lh, FILE *fp)
+{
+	BIO *bp;
+
+	bp = BIO_new(BIO_s_file());
+	if (bp == NULL)
+		goto end;
+	BIO_set_fp(bp, fp, BIO_NOCLOSE);
+	lh_node_stats_bio(lh, bp);
+	BIO_free(bp);
+end:;
+}
+
+void
+lh_node_usage_stats(const _LHASH *lh, FILE *fp)
+{
+	BIO *bp;
+
+	bp = BIO_new(BIO_s_file());
+	if (bp == NULL)
+		goto end;
+	BIO_set_fp(bp, fp, BIO_NOCLOSE);
+	lh_node_usage_stats_bio(lh, bp);
+	BIO_free(bp);
+end:;
+}
+
+
+void
+lh_stats_bio(const _LHASH *lh, BIO *out)
+{
+	BIO_printf(out, "num_items             = %lu\n", lh->num_items);
+	BIO_printf(out, "num_nodes             = %u\n", lh->num_nodes);
+	BIO_printf(out, "num_alloc_nodes       = %u\n", lh->num_alloc_nodes);
+	BIO_printf(out, "num_expands           = %lu\n", lh->num_expands);
+	BIO_printf(out, "num_expand_reallocs   = %lu\n",
+	    lh->num_expand_reallocs);
+	BIO_printf(out, "num_contracts         = %lu\n", lh->num_contracts);
+	BIO_printf(out, "num_contract_reallocs = %lu\n",
+	    lh->num_contract_reallocs);
+	BIO_printf(out, "num_hash_calls        = %lu\n", lh->num_hash_calls);
+	BIO_printf(out, "num_comp_calls        = %lu\n", lh->num_comp_calls);
+	BIO_printf(out, "num_insert            = %lu\n", lh->num_insert);
+	BIO_printf(out, "num_replace           = %lu\n", lh->num_replace);
+	BIO_printf(out, "num_delete            = %lu\n", lh->num_delete);
+	BIO_printf(out, "num_no_delete         = %lu\n", lh->num_no_delete);
+	BIO_printf(out, "num_retrieve          = %lu\n", lh->num_retrieve);
+	BIO_printf(out, "num_retrieve_miss     = %lu\n", lh->num_retrieve_miss);
+	BIO_printf(out, "num_hash_comps        = %lu\n", lh->num_hash_comps);
+#if 0
+	BIO_printf(out, "p                     = %u\n", lh->p);
+	BIO_printf(out, "pmax                  = %u\n", lh->pmax);
+	BIO_printf(out, "up_load               = %lu\n", lh->up_load);
+	BIO_printf(out, "down_load             = %lu\n", lh->down_load);
+#endif
+}
+
+void
+lh_node_stats_bio(const _LHASH *lh, BIO *out)
+{
+	LHASH_NODE *n;
+	unsigned int i, num;
+
+	for (i = 0; i < lh->num_nodes; i++) {
+		for (n = lh->b[i], num = 0; n != NULL; n = n->next)
+			num++;
+		BIO_printf(out, "node %6u -> %3u\n", i, num);
+	}
+}
+
+void
+lh_node_usage_stats_bio(const _LHASH *lh, BIO *out)
+{
+	LHASH_NODE *n;
+	unsigned long num;
+	unsigned int i;
+	unsigned long total = 0, n_used = 0;
+
+	for (i = 0; i < lh->num_nodes; i++) {
+		for (n = lh->b[i], num = 0; n != NULL; n = n->next)
+			num++;
+		if (num != 0) {
+			n_used++;
+			total += num;
+		}
+	}
+	BIO_printf(out, "%lu nodes used out of %u\n", n_used, lh->num_nodes);
+	BIO_printf(out, "%lu items\n", total);
+	if (n_used == 0)
+		return;
+	BIO_printf(out, "load %d.%02d  actual load %d.%02d\n",
+	    (int)(total / lh->num_nodes),
+	    (int)((total % lh->num_nodes) * 100 / lh->num_nodes),
+	    (int)(total / n_used),
+	    (int)((total % n_used) * 100 / n_used));
+}
+
+#endif
diff --git a/crypto/libressl/crypto/lhash/lhash.c b/crypto/libressl/crypto/lhash/lhash.c
new file mode 100644
index 0000000000..84ff6da154
--- /dev/null
+++ b/crypto/libressl/crypto/lhash/lhash.c
@@ -0,0 +1,463 @@
+/* $OpenBSD: lhash.c,v 1.16 2014/07/09 11:10:51 bcook Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Code for dynamic hash table routines
+ * Author - Eric Young v 2.0
+ *
+ * 2.2 eay - added #include "crypto.h" so the memory leak checking code is
+ *	     present. eay 18-Jun-98
+ *
+ * 2.1 eay - Added an 'error in last operation' flag. eay 6-May-98
+ *
+ * 2.0 eay - Fixed a bug that occurred when using lh_delete
+ *	     from inside lh_doall().  As entries were deleted,
+ *	     the 'table' was 'contract()ed', making some entries
+ *	     jump from the end of the table to the start, there by
+ *	     skipping the lh_doall() processing. eay - 4/12/95
+ *
+ * 1.9 eay - Fixed a memory leak in lh_free, the LHASH_NODEs
+ *	     were not being free()ed. 21/11/95
+ *
+ * 1.8 eay - Put the stats routines into a separate file, lh_stats.c
+ *	     19/09/95
+ *
+ * 1.7 eay - Removed the fputs() for realloc failures - the code
+ *           should silently tolerate them.  I have also fixed things
+ *           lint complained about 04/05/95
+ *
+ * 1.6 eay - Fixed an invalid pointers in contract/expand 27/07/92
+ *
+ * 1.5 eay - Fixed a misuse of realloc in expand 02/03/1992
+ *
+ * 1.4 eay - Fixed lh_doall so the function can call lh_delete 28/05/91
+ *
+ * 1.3 eay - Fixed a few lint problems 19/3/1991
+ *
+ * 1.2 eay - Fixed lh_doall problem 13/3/1991
+ *
+ * 1.1 eay - Added lh_doall
+ *
+ * 1.0 eay - First version
+ */
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+
+#undef MIN_NODES
+#define MIN_NODES	16
+#define UP_LOAD		(2*LH_LOAD_MULT) /* load times 256  (default 2) */
+#define DOWN_LOAD	(LH_LOAD_MULT)   /* load times 256  (default 1) */
+
+static void expand(_LHASH *lh);
+static void contract(_LHASH *lh);
+static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash);
+
+_LHASH *
+lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c)
+{
+	_LHASH *ret;
+	int i;
+
+	if ((ret = malloc(sizeof(_LHASH))) == NULL)
+		goto err0;
+	if ((ret->b = reallocarray(NULL, MIN_NODES, sizeof(LHASH_NODE *))) == NULL)
+		goto err1;
+	for (i = 0; i < MIN_NODES; i++)
+		ret->b[i] = NULL;
+	ret->comp = ((c == NULL) ? (LHASH_COMP_FN_TYPE)strcmp : c);
+	ret->hash = ((h == NULL) ? (LHASH_HASH_FN_TYPE)lh_strhash : h);
+	ret->num_nodes = MIN_NODES / 2;
+	ret->num_alloc_nodes = MIN_NODES;
+	ret->p = 0;
+	ret->pmax = MIN_NODES / 2;
+	ret->up_load = UP_LOAD;
+	ret->down_load = DOWN_LOAD;
+	ret->num_items = 0;
+
+	ret->num_expands = 0;
+	ret->num_expand_reallocs = 0;
+	ret->num_contracts = 0;
+	ret->num_contract_reallocs = 0;
+	ret->num_hash_calls = 0;
+	ret->num_comp_calls = 0;
+	ret->num_insert = 0;
+	ret->num_replace = 0;
+	ret->num_delete = 0;
+	ret->num_no_delete = 0;
+	ret->num_retrieve = 0;
+	ret->num_retrieve_miss = 0;
+	ret->num_hash_comps = 0;
+
+	ret->error = 0;
+	return (ret);
+
+err1:
+	free(ret);
+err0:
+	return (NULL);
+}
+
+void
+lh_free(_LHASH *lh)
+{
+	unsigned int i;
+	LHASH_NODE *n, *nn;
+
+	if (lh == NULL)
+		return;
+
+	for (i = 0; i < lh->num_nodes; i++) {
+		n = lh->b[i];
+		while (n != NULL) {
+			nn = n->next;
+			free(n);
+			n = nn;
+		}
+	}
+	free(lh->b);
+	free(lh);
+}
+
+void *
+lh_insert(_LHASH *lh, void *data)
+{
+	unsigned long hash;
+	LHASH_NODE *nn, **rn;
+	void *ret;
+
+	lh->error = 0;
+	if (lh->up_load <= (lh->num_items * LH_LOAD_MULT / lh->num_nodes))
+		expand(lh);
+
+	rn = getrn(lh, data, &hash);
+
+	if (*rn == NULL) {
+		if ((nn = malloc(sizeof(LHASH_NODE))) == NULL) {
+			lh->error++;
+			return (NULL);
+		}
+		nn->data = data;
+		nn->next = NULL;
+#ifndef OPENSSL_NO_HASH_COMP
+		nn->hash = hash;
+#endif
+		*rn = nn;
+		ret = NULL;
+		lh->num_insert++;
+		lh->num_items++;
+	}
+	else /* replace same key */
+	{
+		ret = (*rn)->data;
+		(*rn)->data = data;
+		lh->num_replace++;
+	}
+	return (ret);
+}
+
+void *
+lh_delete(_LHASH *lh, const void *data)
+{
+	unsigned long hash;
+	LHASH_NODE *nn, **rn;
+	void *ret;
+
+	lh->error = 0;
+	rn = getrn(lh, data, &hash);
+
+	if (*rn == NULL) {
+		lh->num_no_delete++;
+		return (NULL);
+	} else {
+		nn= *rn;
+		*rn = nn->next;
+		ret = nn->data;
+		free(nn);
+		lh->num_delete++;
+	}
+
+	lh->num_items--;
+	if ((lh->num_nodes > MIN_NODES) &&
+	    (lh->down_load >= (lh->num_items * LH_LOAD_MULT / lh->num_nodes)))
+		contract(lh);
+
+	return (ret);
+}
+
+void *
+lh_retrieve(_LHASH *lh, const void *data)
+{
+	unsigned long hash;
+	LHASH_NODE **rn;
+	void *ret;
+
+	lh->error = 0;
+	rn = getrn(lh, data, &hash);
+
+	if (*rn == NULL) {
+		lh->num_retrieve_miss++;
+		return (NULL);
+	} else {
+		ret = (*rn)->data;
+		lh->num_retrieve++;
+	}
+	return (ret);
+}
+
+static void
+doall_util_fn(_LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func,
+    LHASH_DOALL_ARG_FN_TYPE func_arg, void *arg)
+{
+	int i;
+	LHASH_NODE *a, *n;
+
+	if (lh == NULL)
+		return;
+
+	/* reverse the order so we search from 'top to bottom'
+	 * We were having memory leaks otherwise */
+	for (i = lh->num_nodes - 1; i >= 0; i--) {
+		a = lh->b[i];
+		while (a != NULL) {
+			/* 28/05/91 - eay - n added so items can be deleted
+			 * via lh_doall */
+			/* 22/05/08 - ben - eh? since a is not passed,
+			 * this should not be needed */
+			n = a->next;
+			if (use_arg)
+				func_arg(a->data, arg);
+			else
+				func(a->data);
+			a = n;
+		}
+	}
+}
+
+void
+lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func)
+{
+	doall_util_fn(lh, 0, func, (LHASH_DOALL_ARG_FN_TYPE)0, NULL);
+}
+
+void
+lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg)
+{
+	doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg);
+}
+
+static void
+expand(_LHASH *lh)
+{
+	LHASH_NODE **n, **n1, **n2, *np;
+	unsigned int p, i, j;
+	unsigned long hash, nni;
+
+	lh->num_nodes++;
+	lh->num_expands++;
+	p = (int)lh->p++;
+	n1 = &(lh->b[p]);
+	n2 = &(lh->b[p + (int)lh->pmax]);
+	*n2 = NULL;        /* 27/07/92 - eay - undefined pointer bug */
+	nni = lh->num_alloc_nodes;
+
+	for (np = *n1; np != NULL; ) {
+#ifndef OPENSSL_NO_HASH_COMP
+		hash = np->hash;
+#else
+		hash = lh->hash(np->data);
+		lh->num_hash_calls++;
+#endif
+		if ((hash % nni) != p) { /* move it */
+			*n1 = (*n1)->next;
+			np->next= *n2;
+			*n2 = np;
+		} else
+			n1 = &((*n1)->next);
+		np= *n1;
+	}
+
+	if ((lh->p) >= lh->pmax) {
+		j = (int)lh->num_alloc_nodes * 2;
+		n = reallocarray(lh->b, j, sizeof(LHASH_NODE *));
+		if (n == NULL) {
+/*			fputs("realloc error in lhash", stderr); */
+			lh->error++;
+			lh->p = 0;
+			return;
+		}
+		/* else */
+		for (i = (int)lh->num_alloc_nodes; i < j; i++)/* 26/02/92 eay */
+			n[i] = NULL;			  /* 02/03/92 eay */
+		lh->pmax = lh->num_alloc_nodes;
+		lh->num_alloc_nodes = j;
+		lh->num_expand_reallocs++;
+		lh->p = 0;
+		lh->b = n;
+	}
+}
+
+static void
+contract(_LHASH *lh)
+{
+	LHASH_NODE **n, *n1, *np;
+
+	np = lh->b[lh->p + lh->pmax - 1];
+	lh->b[lh->p+lh->pmax - 1] = NULL; /* 24/07-92 - eay - weird but :-( */
+	if (lh->p == 0) {
+		n = reallocarray(lh->b, lh->pmax, sizeof(LHASH_NODE *));
+		if (n == NULL) {
+/*			fputs("realloc error in lhash", stderr); */
+			lh->error++;
+			return;
+		}
+		lh->num_contract_reallocs++;
+		lh->num_alloc_nodes /= 2;
+		lh->pmax /= 2;
+		lh->p = lh->pmax - 1;
+		lh->b = n;
+	} else
+		lh->p--;
+
+	lh->num_nodes--;
+	lh->num_contracts++;
+
+	n1 = lh->b[(int)lh->p];
+	if (n1 == NULL)
+		lh->b[(int)lh->p] = np;
+	else {
+		while (n1->next != NULL)
+			n1 = n1->next;
+		n1->next = np;
+	}
+}
+
+static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash)
+{
+	LHASH_NODE **ret, *n1;
+	unsigned long hash, nn;
+	LHASH_COMP_FN_TYPE cf;
+
+	hash = (*(lh->hash))(data);
+	lh->num_hash_calls++;
+	*rhash = hash;
+
+	nn = hash % lh->pmax;
+	if (nn < lh->p)
+		nn = hash % lh->num_alloc_nodes;
+
+	cf = lh->comp;
+	ret = &(lh->b[(int)nn]);
+	for (n1 = *ret; n1 != NULL; n1 = n1->next) {
+#ifndef OPENSSL_NO_HASH_COMP
+		lh->num_hash_comps++;
+		if (n1->hash != hash) {
+			ret = &(n1->next);
+			continue;
+		}
+#endif
+		lh->num_comp_calls++;
+		if (cf(n1->data, data) == 0)
+			break;
+		ret = &(n1->next);
+	}
+	return (ret);
+}
+
+/* The following hash seems to work very well on normal text strings
+ * no collisions on /usr/dict/words and it distributes on %2^n quite
+ * well, not as good as MD5, but still good.
+ */
+unsigned long
+lh_strhash(const char *c)
+{
+	unsigned long ret = 0;
+	long n;
+	unsigned long v;
+	int r;
+
+	if ((c == NULL) || (*c == '\0'))
+		return (ret);
+/*
+	unsigned char b[16];
+	MD5(c,strlen(c),b);
+	return(b[0]|(b[1]<<8)|(b[2]<<16)|(b[3]<<24));
+*/
+
+	n = 0x100;
+	while (*c) {
+		v = n | (*c);
+		n += 0x100;
+		r = (int)((v >> 2) ^ v) & 0x0f;
+		ret = (ret << r)|(ret >> (32 - r));
+		ret &= 0xFFFFFFFFL;
+		ret ^= v * v;
+		c++;
+	}
+	return ((ret >> 16) ^ ret);
+}
+
+unsigned long
+lh_num_items(const _LHASH *lh)
+{
+	return lh ? lh->num_items : 0;
+}
diff --git a/crypto/libressl/crypto/malloc-wrapper.c b/crypto/libressl/crypto/malloc-wrapper.c
new file mode 100644
index 0000000000..9e27ec9a24
--- /dev/null
+++ b/crypto/libressl/crypto/malloc-wrapper.c
@@ -0,0 +1,197 @@
+/* $OpenBSD: malloc-wrapper.c,v 1.2 2014/04/17 20:44:45 tedu Exp $ */
+/*
+ * Copyright (c) 2014 Bob Beck
+ *
+ * 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 
+#include 
+#include 
+
+int
+CRYPTO_set_mem_functions(void *(*m)(size_t), void *(*r)(void *, size_t),
+    void (*f)(void *))
+{
+	return 0;
+}
+
+int
+CRYPTO_set_mem_ex_functions(void *(*m)(size_t, const char *, int),
+    void *(*r)(void *, size_t, const char *, int), void (*f)(void *))
+{
+	return 0;
+}
+
+int
+CRYPTO_set_locked_mem_functions(void *(*m)(size_t), void (*f)(void *))
+{
+	return 0;
+}
+
+int
+CRYPTO_set_locked_mem_ex_functions(void *(*m)(size_t, const char *, int),
+    void (*f)(void *))
+{
+	return 0;
+}
+
+int
+CRYPTO_set_mem_debug_functions(void (*m)(void *, int, const char *, int, int),
+    void (*r)(void *, void *, int, const char *, int, int),
+    void (*f)(void *, int), void (*so)(long), long (*go)(void))
+{
+	return 0;
+}
+
+
+void
+CRYPTO_get_mem_functions(void *(**m)(size_t), void *(**r)(void *, size_t),
+    void (**f)(void *))
+{
+	if (m != NULL)
+		*m = malloc;
+	if (r != NULL)
+		*r = realloc;
+	if (f != NULL)
+		*f = free;
+}
+
+void
+CRYPTO_get_mem_ex_functions(void *(**m)(size_t, const char *, int),
+    void *(**r)(void *, size_t, const char *, int), void (**f)(void *))
+{
+	if (m != NULL)
+		*m = NULL;
+	if (r != NULL)
+		*r = NULL;
+	if (f != NULL)
+		*f = free;
+}
+
+void
+CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *))
+{
+	if (m != NULL)
+		*m = malloc;
+	if (f != NULL)
+		*f = free;
+}
+
+void
+CRYPTO_get_locked_mem_ex_functions(void *(**m)(size_t, const char *, int),
+    void (**f)(void *))
+{
+	if (m != NULL)
+		*m = NULL;
+	if (f != NULL)
+		*f = free;
+}
+
+void
+CRYPTO_get_mem_debug_functions(void (**m)(void *, int, const char *, int, int),
+    void (**r)(void *, void *, int, const char *, int, int),
+    void (**f)(void *, int), void (**so)(long), long (**go)(void))
+{
+	if (m != NULL)
+		*m = NULL;
+	if (r != NULL)
+		*r = NULL;
+	if (f != NULL)
+		*f = NULL;
+	if (so != NULL)
+		*so = NULL;
+	if (go != NULL)
+		*go = NULL;
+}
+
+
+void *
+CRYPTO_malloc_locked(int num, const char *file, int line)
+{
+	if (num <= 0)
+		return NULL;
+	return malloc(num);
+}
+
+void
+CRYPTO_free_locked(void *ptr)
+{
+	free(ptr);
+}
+
+void *
+CRYPTO_malloc(int num, const char *file, int line)
+{
+	if (num <= 0)
+		return NULL;
+	return malloc(num);
+}
+
+char *
+CRYPTO_strdup(const char *str, const char *file, int line)
+{
+	return strdup(str);
+}
+
+void *
+CRYPTO_realloc(void *ptr, int num, const char *file, int line)
+{
+	if (num <= 0)
+		return NULL;
+
+	return realloc(ptr, num);
+}
+
+void *
+CRYPTO_realloc_clean(void *ptr, int old_len, int num, const char *file,
+    int line)
+{
+	void *ret = NULL;
+
+	if (num <= 0)
+		return NULL;
+	if (num < old_len)
+		return NULL; /* original does not support shrinking */
+	ret = malloc(num);
+	if (ret && ptr && old_len > 0) {
+		memcpy(ret, ptr, old_len);
+		explicit_bzero(ptr, old_len);
+		free(ptr);
+	}
+	return ret;
+}
+
+void
+CRYPTO_free(void *ptr)
+{
+	free(ptr);
+}
+
+void *
+CRYPTO_remalloc(void *a, int num, const char *file, int line)
+{
+	free(a);
+	return malloc(num);
+}
+
+void
+CRYPTO_set_mem_debug_options(long bits)
+{
+	return;
+}
+
+long
+CRYPTO_get_mem_debug_options(void)
+{
+	return 0;
+}
diff --git a/crypto/libressl/crypto/md32_common.h b/crypto/libressl/crypto/md32_common.h
new file mode 100644
index 0000000000..05b950015c
--- /dev/null
+++ b/crypto/libressl/crypto/md32_common.h
@@ -0,0 +1,359 @@
+/* $OpenBSD: md32_common.h,v 1.19 2014/10/20 13:06:54 bcook Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+/*
+ * This is a generic 32 bit "collector" for message digest algorithms.
+ * Whenever needed it collects input character stream into chunks of
+ * 32 bit values and invokes a block function that performs actual hash
+ * calculations.
+ *
+ * Porting guide.
+ *
+ * Obligatory macros:
+ *
+ * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
+ *	this macro defines byte order of input stream.
+ * HASH_CBLOCK
+ *	size of a unit chunk HASH_BLOCK operates on.
+ * HASH_LONG
+ *	has to be at least 32 bit wide.
+ * HASH_CTX
+ *	context structure that at least contains following
+ *	members:
+ *		typedef struct {
+ *			...
+ *			HASH_LONG	Nl,Nh;
+ *			either {
+ *			HASH_LONG	data[HASH_LBLOCK];
+ *			unsigned char	data[HASH_CBLOCK];
+ *			};
+ *			unsigned int	num;
+ *			...
+ *			} HASH_CTX;
+ *	data[] vector is expected to be zeroed upon first call to
+ *	HASH_UPDATE.
+ * HASH_UPDATE
+ *	name of "Update" function, implemented here.
+ * HASH_TRANSFORM
+ *	name of "Transform" function, implemented here.
+ * HASH_FINAL
+ *	name of "Final" function, implemented here.
+ * HASH_BLOCK_DATA_ORDER
+ *	name of "block" function capable of treating *unaligned* input
+ *	message in original (data) byte order, implemented externally.
+ * HASH_MAKE_STRING
+ *	macro convering context variables to an ASCII hash string.
+ *
+ * MD5 example:
+ *
+ *	#define DATA_ORDER_IS_LITTLE_ENDIAN
+ *
+ *	#define HASH_LONG		MD5_LONG
+ *	#define HASH_CTX		MD5_CTX
+ *	#define HASH_CBLOCK		MD5_CBLOCK
+ *	#define HASH_UPDATE		MD5_Update
+ *	#define HASH_TRANSFORM		MD5_Transform
+ *	#define HASH_FINAL		MD5_Final
+ *	#define HASH_BLOCK_DATA_ORDER	md5_block_data_order
+ *
+ *					
+ */
+
+#include 
+
+#include 
+
+#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+#error "DATA_ORDER must be defined!"
+#endif
+
+#ifndef HASH_CBLOCK
+#error "HASH_CBLOCK must be defined!"
+#endif
+#ifndef HASH_LONG
+#error "HASH_LONG must be defined!"
+#endif
+#ifndef HASH_CTX
+#error "HASH_CTX must be defined!"
+#endif
+
+#ifndef HASH_UPDATE
+#error "HASH_UPDATE must be defined!"
+#endif
+#ifndef HASH_TRANSFORM
+#error "HASH_TRANSFORM must be defined!"
+#endif
+#if !defined(HASH_FINAL) && !defined(HASH_NO_FINAL)
+#error "HASH_FINAL or HASH_NO_FINAL must be defined!"
+#endif
+
+#ifndef HASH_BLOCK_DATA_ORDER
+#error "HASH_BLOCK_DATA_ORDER must be defined!"
+#endif
+
+/*
+ * This common idiom is recognized by the compiler and turned into a
+ * CPU-specific intrinsic as appropriate. 
+ * e.g. GCC optimizes to roll on amd64 at -O0
+ */
+static inline uint32_t ROTATE(uint32_t a, uint32_t n)
+{
+	return (a<>(32-n));
+}
+
+#if defined(DATA_ORDER_IS_BIG_ENDIAN)
+
+#if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+# if ((defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)) || \
+      (defined(__x86_64) || defined(__x86_64__))
+    /*
+     * This gives ~30-40% performance improvement in SHA-256 compiled
+     * with gcc [on P4]. Well, first macro to be frank. We can pull
+     * this trick on x86* platforms only, because these CPUs can fetch
+     * unaligned data without raising an exception.
+     */
+#  define HOST_c2l(c,l)	({ unsigned int r=*((const unsigned int *)(c));	\
+				   asm ("bswapl %0":"=r"(r):"0"(r));	\
+				   (c)+=4; (l)=r;			})
+#  define HOST_l2c(l,c)	({ unsigned int r=(l);			\
+				   asm ("bswapl %0":"=r"(r):"0"(r));	\
+				   *((unsigned int *)(c))=r; (c)+=4;	})
+# endif
+#endif
+#if defined(__s390__) || defined(__s390x__)
+# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4)
+# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4)
+#endif
+
+#ifndef HOST_c2l
+#define HOST_c2l(c,l) do {l =(((unsigned long)(*((c)++)))<<24);	\
+			  l|=(((unsigned long)(*((c)++)))<<16);	\
+			  l|=(((unsigned long)(*((c)++)))<< 8);	\
+			  l|=(((unsigned long)(*((c)++)))    );	\
+		      } while (0)
+#endif
+#ifndef HOST_l2c
+#define HOST_l2c(l,c) do {*((c)++)=(unsigned char)(((l)>>24)&0xff);	\
+			  *((c)++)=(unsigned char)(((l)>>16)&0xff);	\
+			  *((c)++)=(unsigned char)(((l)>> 8)&0xff);	\
+			  *((c)++)=(unsigned char)(((l)    )&0xff);	\
+		      } while (0)
+#endif
+
+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+
+#if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+# if defined(__s390x__)
+#  define HOST_c2l(c,l)	({ asm ("lrv	%0,%1"			\
+				   :"=d"(l) :"m"(*(const unsigned int *)(c)));\
+				   (c)+=4; 				})
+#  define HOST_l2c(l,c)	({ asm ("strv	%1,%0"			\
+				   :"=m"(*(unsigned int *)(c)) :"d"(l));\
+				   (c)+=4; 				})
+# endif
+#endif
+#if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
+#  define HOST_c2l(c,l)	((l)=*((const unsigned int *)(c)), (c)+=4)
+#  define HOST_l2c(l,c)	(*((unsigned int *)(c))=(l), (c)+=4)
+#endif
+
+#ifndef HOST_c2l
+#define HOST_c2l(c,l) do {l =(((unsigned long)(*((c)++)))    );	\
+			  l|=(((unsigned long)(*((c)++)))<< 8);	\
+			  l|=(((unsigned long)(*((c)++)))<<16);	\
+			  l|=(((unsigned long)(*((c)++)))<<24);	\
+		      } while (0)
+#endif
+#ifndef HOST_l2c
+#define HOST_l2c(l,c) do {*((c)++)=(unsigned char)(((l)    )&0xff);	\
+			  *((c)++)=(unsigned char)(((l)>> 8)&0xff);	\
+			  *((c)++)=(unsigned char)(((l)>>16)&0xff);	\
+			  *((c)++)=(unsigned char)(((l)>>24)&0xff);	\
+		      } while (0)
+#endif
+
+#endif
+
+/*
+ * Time for some action:-)
+ */
+
+int
+HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len)
+{
+	const unsigned char *data = data_;
+	unsigned char *p;
+	HASH_LONG l;
+	size_t n;
+
+	if (len == 0)
+		return 1;
+
+	l = (c->Nl + (((HASH_LONG)len) << 3))&0xffffffffUL;
+	/* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
+	 * Wei Dai  for pointing it out. */
+	if (l < c->Nl) /* overflow */
+		c->Nh++;
+	c->Nh+=(HASH_LONG)(len>>29);	/* might cause compiler warning on 16-bit */
+	c->Nl = l;
+
+	n = c->num;
+	if (n != 0) {
+		p = (unsigned char *)c->data;
+
+		if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) {
+			memcpy (p + n, data, HASH_CBLOCK - n);
+			HASH_BLOCK_DATA_ORDER (c, p, 1);
+			n = HASH_CBLOCK - n;
+			data += n;
+			len -= n;
+			c->num = 0;
+			memset (p,0,HASH_CBLOCK);	/* keep it zeroed */
+		} else {
+			memcpy (p + n, data, len);
+			c->num += (unsigned int)len;
+			return 1;
+		}
+	}
+
+	n = len/HASH_CBLOCK;
+	if (n > 0) {
+		HASH_BLOCK_DATA_ORDER (c, data, n);
+		n    *= HASH_CBLOCK;
+		data += n;
+		len -= n;
+	}
+
+	if (len != 0) {
+		p = (unsigned char *)c->data;
+		c->num = (unsigned int)len;
+		memcpy (p, data, len);
+	}
+	return 1;
+}
+
+
+void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data)
+{
+	HASH_BLOCK_DATA_ORDER (c, data, 1);
+}
+
+
+#ifndef HASH_NO_FINAL
+int HASH_FINAL (unsigned char *md, HASH_CTX *c)
+{
+	unsigned char *p = (unsigned char *)c->data;
+	size_t n = c->num;
+
+	p[n] = 0x80; /* there is always room for one */
+	n++;
+
+	if (n > (HASH_CBLOCK - 8)) {
+		memset (p + n, 0, HASH_CBLOCK - n);
+		n = 0;
+		HASH_BLOCK_DATA_ORDER (c, p, 1);
+	}
+	memset (p + n, 0, HASH_CBLOCK - 8 - n);
+
+	p += HASH_CBLOCK - 8;
+#if   defined(DATA_ORDER_IS_BIG_ENDIAN)
+	HOST_l2c(c->Nh, p);
+	HOST_l2c(c->Nl, p);
+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+	HOST_l2c(c->Nl, p);
+	HOST_l2c(c->Nh, p);
+#endif
+	p -= HASH_CBLOCK;
+	HASH_BLOCK_DATA_ORDER (c, p, 1);
+	c->num = 0;
+	memset (p, 0, HASH_CBLOCK);
+
+#ifndef HASH_MAKE_STRING
+#error "HASH_MAKE_STRING must be defined!"
+#else
+	HASH_MAKE_STRING(c, md);
+#endif
+
+	return 1;
+}
+#endif
+
+#ifndef MD32_REG_T
+#if defined(__alpha) || defined(__sparcv9) || defined(__mips)
+#define MD32_REG_T long
+/*
+ * This comment was originaly written for MD5, which is why it
+ * discusses A-D. But it basically applies to all 32-bit digests,
+ * which is why it was moved to common header file.
+ *
+ * In case you wonder why A-D are declared as long and not
+ * as MD5_LONG. Doing so results in slight performance
+ * boost on LP64 architectures. The catch is we don't
+ * really care if 32 MSBs of a 64-bit register get polluted
+ * with eventual overflows as we *save* only 32 LSBs in
+ * *either* case. Now declaring 'em long excuses the compiler
+ * from keeping 32 MSBs zeroed resulting in 13% performance
+ * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
+ * Well, to be honest it should say that this *prevents*
+ * performance degradation.
+ *				
+ */
+#else
+/*
+ * Above is not absolute and there are LP64 compilers that
+ * generate better code if MD32_REG_T is defined int. The above
+ * pre-processor condition reflects the circumstances under which
+ * the conclusion was made and is subject to further extension.
+ *				
+ */
+#define MD32_REG_T int
+#endif
+#endif
diff --git a/crypto/libressl/crypto/md4/md4_dgst.c b/crypto/libressl/crypto/md4/md4_dgst.c
new file mode 100644
index 0000000000..b9b42c9ea9
--- /dev/null
+++ b/crypto/libressl/crypto/md4/md4_dgst.c
@@ -0,0 +1,167 @@
+/* $OpenBSD$ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+#include "md4_locl.h"
+
+/* Implemented from RFC1186 The MD4 Message-Digest Algorithm
+ */
+
+#define INIT_DATA_A (unsigned long)0x67452301L
+#define INIT_DATA_B (unsigned long)0xefcdab89L
+#define INIT_DATA_C (unsigned long)0x98badcfeL
+#define INIT_DATA_D (unsigned long)0x10325476L
+
+int MD4_Init(MD4_CTX *c)
+	{
+	memset (c,0,sizeof(*c));
+	c->A=INIT_DATA_A;
+	c->B=INIT_DATA_B;
+	c->C=INIT_DATA_C;
+	c->D=INIT_DATA_D;
+	return 1;
+	}
+
+#ifndef md4_block_data_order
+#ifdef X
+#undef X
+#endif
+void md4_block_data_order (MD4_CTX *c, const void *data_, size_t num)
+	{
+	const unsigned char *data=data_;
+	unsigned MD32_REG_T A,B,C,D,l;
+#ifndef MD32_XARRAY
+	/* See comment in crypto/sha/sha_locl.h for details. */
+	unsigned MD32_REG_T	XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+				XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
+# define X(i)	XX##i
+#else
+	MD4_LONG XX[MD4_LBLOCK];
+# define X(i)	XX[i]
+#endif
+
+	A=c->A;
+	B=c->B;
+	C=c->C;
+	D=c->D;
+
+	for (;num--;)
+		{
+	HOST_c2l(data,l); X( 0)=l;
+	HOST_c2l(data,l); X( 1)=l;
+	/* Round 0 */
+	R0(A,B,C,D,X( 0), 3,0);	HOST_c2l(data,l); X( 2)=l;
+	R0(D,A,B,C,X( 1), 7,0);	HOST_c2l(data,l); X( 3)=l;
+	R0(C,D,A,B,X( 2),11,0);	HOST_c2l(data,l); X( 4)=l;
+	R0(B,C,D,A,X( 3),19,0);	HOST_c2l(data,l); X( 5)=l;
+	R0(A,B,C,D,X( 4), 3,0);	HOST_c2l(data,l); X( 6)=l;
+	R0(D,A,B,C,X( 5), 7,0);	HOST_c2l(data,l); X( 7)=l;
+	R0(C,D,A,B,X( 6),11,0);	HOST_c2l(data,l); X( 8)=l;
+	R0(B,C,D,A,X( 7),19,0);	HOST_c2l(data,l); X( 9)=l;
+	R0(A,B,C,D,X( 8), 3,0);	HOST_c2l(data,l); X(10)=l;
+	R0(D,A,B,C,X( 9), 7,0);	HOST_c2l(data,l); X(11)=l;
+	R0(C,D,A,B,X(10),11,0);	HOST_c2l(data,l); X(12)=l;
+	R0(B,C,D,A,X(11),19,0);	HOST_c2l(data,l); X(13)=l;
+	R0(A,B,C,D,X(12), 3,0);	HOST_c2l(data,l); X(14)=l;
+	R0(D,A,B,C,X(13), 7,0);	HOST_c2l(data,l); X(15)=l;
+	R0(C,D,A,B,X(14),11,0);
+	R0(B,C,D,A,X(15),19,0);
+	/* Round 1 */
+	R1(A,B,C,D,X( 0), 3,0x5A827999L);
+	R1(D,A,B,C,X( 4), 5,0x5A827999L);
+	R1(C,D,A,B,X( 8), 9,0x5A827999L);
+	R1(B,C,D,A,X(12),13,0x5A827999L);
+	R1(A,B,C,D,X( 1), 3,0x5A827999L);
+	R1(D,A,B,C,X( 5), 5,0x5A827999L);
+	R1(C,D,A,B,X( 9), 9,0x5A827999L);
+	R1(B,C,D,A,X(13),13,0x5A827999L);
+	R1(A,B,C,D,X( 2), 3,0x5A827999L);
+	R1(D,A,B,C,X( 6), 5,0x5A827999L);
+	R1(C,D,A,B,X(10), 9,0x5A827999L);
+	R1(B,C,D,A,X(14),13,0x5A827999L);
+	R1(A,B,C,D,X( 3), 3,0x5A827999L);
+	R1(D,A,B,C,X( 7), 5,0x5A827999L);
+	R1(C,D,A,B,X(11), 9,0x5A827999L);
+	R1(B,C,D,A,X(15),13,0x5A827999L);
+	/* Round 2 */
+	R2(A,B,C,D,X( 0), 3,0x6ED9EBA1L);
+	R2(D,A,B,C,X( 8), 9,0x6ED9EBA1L);
+	R2(C,D,A,B,X( 4),11,0x6ED9EBA1L);
+	R2(B,C,D,A,X(12),15,0x6ED9EBA1L);
+	R2(A,B,C,D,X( 2), 3,0x6ED9EBA1L);
+	R2(D,A,B,C,X(10), 9,0x6ED9EBA1L);
+	R2(C,D,A,B,X( 6),11,0x6ED9EBA1L);
+	R2(B,C,D,A,X(14),15,0x6ED9EBA1L);
+	R2(A,B,C,D,X( 1), 3,0x6ED9EBA1L);
+	R2(D,A,B,C,X( 9), 9,0x6ED9EBA1L);
+	R2(C,D,A,B,X( 5),11,0x6ED9EBA1L);
+	R2(B,C,D,A,X(13),15,0x6ED9EBA1L);
+	R2(A,B,C,D,X( 3), 3,0x6ED9EBA1L);
+	R2(D,A,B,C,X(11), 9,0x6ED9EBA1L);
+	R2(C,D,A,B,X( 7),11,0x6ED9EBA1L);
+	R2(B,C,D,A,X(15),15,0x6ED9EBA1L);
+
+	A = c->A += A;
+	B = c->B += B;
+	C = c->C += C;
+	D = c->D += D;
+		}
+	}
+#endif
diff --git a/crypto/libressl/crypto/md4/md4_locl.h b/crypto/libressl/crypto/md4/md4_locl.h
new file mode 100644
index 0000000000..194f8059e9
--- /dev/null
+++ b/crypto/libressl/crypto/md4/md4_locl.h
@@ -0,0 +1,108 @@
+/* $OpenBSD$ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+void md4_block_data_order (MD4_CTX *c, const void *p,size_t num);
+
+#define DATA_ORDER_IS_LITTLE_ENDIAN
+
+#define HASH_LONG		MD4_LONG
+#define HASH_CTX		MD4_CTX
+#define HASH_CBLOCK		MD4_CBLOCK
+#define HASH_UPDATE		MD4_Update
+#define HASH_TRANSFORM		MD4_Transform
+#define HASH_FINAL		MD4_Final
+#define	HASH_MAKE_STRING(c,s)	do {	\
+	unsigned long ll;		\
+	ll=(c)->A; HOST_l2c(ll,(s));	\
+	ll=(c)->B; HOST_l2c(ll,(s));	\
+	ll=(c)->C; HOST_l2c(ll,(s));	\
+	ll=(c)->D; HOST_l2c(ll,(s));	\
+	} while (0)
+#define	HASH_BLOCK_DATA_ORDER	md4_block_data_order
+
+#include "md32_common.h"
+
+/*
+#define	F(x,y,z)	(((x) & (y))  |  ((~(x)) & (z)))
+#define	G(x,y,z)	(((x) & (y))  |  ((x) & ((z))) | ((y) & ((z))))
+*/
+
+/* As pointed out by Wei Dai , the above can be
+ * simplified to the code below.  Wei attributes these optimizations
+ * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
+ */
+#define	F(b,c,d)	((((c) ^ (d)) & (b)) ^ (d))
+#define G(b,c,d)	(((b) & (c)) | ((b) & (d)) | ((c) & (d)))
+#define	H(b,c,d)	((b) ^ (c) ^ (d))
+
+#define R0(a,b,c,d,k,s,t) { \
+	a+=((k)+(t)+F((b),(c),(d))); \
+	a=ROTATE(a,s); };
+
+#define R1(a,b,c,d,k,s,t) { \
+	a+=((k)+(t)+G((b),(c),(d))); \
+	a=ROTATE(a,s); };\
+
+#define R2(a,b,c,d,k,s,t) { \
+	a+=((k)+(t)+H((b),(c),(d))); \
+	a=ROTATE(a,s); };
diff --git a/crypto/libressl/crypto/md4/md4_one.c b/crypto/libressl/crypto/md4/md4_one.c
new file mode 100644
index 0000000000..0a98c0d467
--- /dev/null
+++ b/crypto/libressl/crypto/md4/md4_one.c
@@ -0,0 +1,77 @@
+/* $OpenBSD$ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md)
+	{
+	MD4_CTX c;
+	static unsigned char m[MD4_DIGEST_LENGTH];
+
+	if (md == NULL) md=m;
+	if (!MD4_Init(&c))
+		return NULL;
+	MD4_Update(&c,d,n);
+	MD4_Final(md,&c);
+	explicit_bzero(&c,sizeof(c));
+	return(md);
+	}
+
diff --git a/crypto/libressl/crypto/md5/md5-elf-x86_64.s b/crypto/libressl/crypto/md5/md5-elf-x86_64.s
new file mode 100644
index 0000000000..8a8107170f
--- /dev/null
+++ b/crypto/libressl/crypto/md5/md5-elf-x86_64.s
@@ -0,0 +1,671 @@
+.text	
+.align	16
+
+.globl	md5_block_asm_data_order
+.type	md5_block_asm_data_order,@function
+md5_block_asm_data_order:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r14
+	pushq	%r15
+.Lprologue:
+
+
+
+
+	movq	%rdi,%rbp
+	shlq	$6,%rdx
+	leaq	(%rsi,%rdx,1),%rdi
+	movl	0(%rbp),%eax
+	movl	4(%rbp),%ebx
+	movl	8(%rbp),%ecx
+	movl	12(%rbp),%edx
+
+
+
+
+
+
+
+	cmpq	%rdi,%rsi
+	je	.Lend				
+
+
+.Lloop:
+	movl	%eax,%r8d
+	movl	%ebx,%r9d
+	movl	%ecx,%r14d
+	movl	%edx,%r15d
+	movl	0(%rsi),%r10d
+	movl	%edx,%r11d
+	xorl	%ecx,%r11d
+	leal	-680876936(%rax,%r10,1),%eax
+	andl	%ebx,%r11d
+	xorl	%edx,%r11d
+	movl	4(%rsi),%r10d
+	addl	%r11d,%eax
+	roll	$7,%eax
+	movl	%ecx,%r11d
+	addl	%ebx,%eax
+	xorl	%ebx,%r11d
+	leal	-389564586(%rdx,%r10,1),%edx
+	andl	%eax,%r11d
+	xorl	%ecx,%r11d
+	movl	8(%rsi),%r10d
+	addl	%r11d,%edx
+	roll	$12,%edx
+	movl	%ebx,%r11d
+	addl	%eax,%edx
+	xorl	%eax,%r11d
+	leal	606105819(%rcx,%r10,1),%ecx
+	andl	%edx,%r11d
+	xorl	%ebx,%r11d
+	movl	12(%rsi),%r10d
+	addl	%r11d,%ecx
+	roll	$17,%ecx
+	movl	%eax,%r11d
+	addl	%edx,%ecx
+	xorl	%edx,%r11d
+	leal	-1044525330(%rbx,%r10,1),%ebx
+	andl	%ecx,%r11d
+	xorl	%eax,%r11d
+	movl	16(%rsi),%r10d
+	addl	%r11d,%ebx
+	roll	$22,%ebx
+	movl	%edx,%r11d
+	addl	%ecx,%ebx
+	xorl	%ecx,%r11d
+	leal	-176418897(%rax,%r10,1),%eax
+	andl	%ebx,%r11d
+	xorl	%edx,%r11d
+	movl	20(%rsi),%r10d
+	addl	%r11d,%eax
+	roll	$7,%eax
+	movl	%ecx,%r11d
+	addl	%ebx,%eax
+	xorl	%ebx,%r11d
+	leal	1200080426(%rdx,%r10,1),%edx
+	andl	%eax,%r11d
+	xorl	%ecx,%r11d
+	movl	24(%rsi),%r10d
+	addl	%r11d,%edx
+	roll	$12,%edx
+	movl	%ebx,%r11d
+	addl	%eax,%edx
+	xorl	%eax,%r11d
+	leal	-1473231341(%rcx,%r10,1),%ecx
+	andl	%edx,%r11d
+	xorl	%ebx,%r11d
+	movl	28(%rsi),%r10d
+	addl	%r11d,%ecx
+	roll	$17,%ecx
+	movl	%eax,%r11d
+	addl	%edx,%ecx
+	xorl	%edx,%r11d
+	leal	-45705983(%rbx,%r10,1),%ebx
+	andl	%ecx,%r11d
+	xorl	%eax,%r11d
+	movl	32(%rsi),%r10d
+	addl	%r11d,%ebx
+	roll	$22,%ebx
+	movl	%edx,%r11d
+	addl	%ecx,%ebx
+	xorl	%ecx,%r11d
+	leal	1770035416(%rax,%r10,1),%eax
+	andl	%ebx,%r11d
+	xorl	%edx,%r11d
+	movl	36(%rsi),%r10d
+	addl	%r11d,%eax
+	roll	$7,%eax
+	movl	%ecx,%r11d
+	addl	%ebx,%eax
+	xorl	%ebx,%r11d
+	leal	-1958414417(%rdx,%r10,1),%edx
+	andl	%eax,%r11d
+	xorl	%ecx,%r11d
+	movl	40(%rsi),%r10d
+	addl	%r11d,%edx
+	roll	$12,%edx
+	movl	%ebx,%r11d
+	addl	%eax,%edx
+	xorl	%eax,%r11d
+	leal	-42063(%rcx,%r10,1),%ecx
+	andl	%edx,%r11d
+	xorl	%ebx,%r11d
+	movl	44(%rsi),%r10d
+	addl	%r11d,%ecx
+	roll	$17,%ecx
+	movl	%eax,%r11d
+	addl	%edx,%ecx
+	xorl	%edx,%r11d
+	leal	-1990404162(%rbx,%r10,1),%ebx
+	andl	%ecx,%r11d
+	xorl	%eax,%r11d
+	movl	48(%rsi),%r10d
+	addl	%r11d,%ebx
+	roll	$22,%ebx
+	movl	%edx,%r11d
+	addl	%ecx,%ebx
+	xorl	%ecx,%r11d
+	leal	1804603682(%rax,%r10,1),%eax
+	andl	%ebx,%r11d
+	xorl	%edx,%r11d
+	movl	52(%rsi),%r10d
+	addl	%r11d,%eax
+	roll	$7,%eax
+	movl	%ecx,%r11d
+	addl	%ebx,%eax
+	xorl	%ebx,%r11d
+	leal	-40341101(%rdx,%r10,1),%edx
+	andl	%eax,%r11d
+	xorl	%ecx,%r11d
+	movl	56(%rsi),%r10d
+	addl	%r11d,%edx
+	roll	$12,%edx
+	movl	%ebx,%r11d
+	addl	%eax,%edx
+	xorl	%eax,%r11d
+	leal	-1502002290(%rcx,%r10,1),%ecx
+	andl	%edx,%r11d
+	xorl	%ebx,%r11d
+	movl	60(%rsi),%r10d
+	addl	%r11d,%ecx
+	roll	$17,%ecx
+	movl	%eax,%r11d
+	addl	%edx,%ecx
+	xorl	%edx,%r11d
+	leal	1236535329(%rbx,%r10,1),%ebx
+	andl	%ecx,%r11d
+	xorl	%eax,%r11d
+	movl	0(%rsi),%r10d
+	addl	%r11d,%ebx
+	roll	$22,%ebx
+	movl	%edx,%r11d
+	addl	%ecx,%ebx
+	movl	4(%rsi),%r10d
+	movl	%edx,%r11d
+	movl	%edx,%r12d
+	notl	%r11d
+	leal	-165796510(%rax,%r10,1),%eax
+	andl	%ebx,%r12d
+	andl	%ecx,%r11d
+	movl	24(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%ecx,%r11d
+	addl	%r12d,%eax
+	movl	%ecx,%r12d
+	roll	$5,%eax
+	addl	%ebx,%eax
+	notl	%r11d
+	leal	-1069501632(%rdx,%r10,1),%edx
+	andl	%eax,%r12d
+	andl	%ebx,%r11d
+	movl	44(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%ebx,%r11d
+	addl	%r12d,%edx
+	movl	%ebx,%r12d
+	roll	$9,%edx
+	addl	%eax,%edx
+	notl	%r11d
+	leal	643717713(%rcx,%r10,1),%ecx
+	andl	%edx,%r12d
+	andl	%eax,%r11d
+	movl	0(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%eax,%r11d
+	addl	%r12d,%ecx
+	movl	%eax,%r12d
+	roll	$14,%ecx
+	addl	%edx,%ecx
+	notl	%r11d
+	leal	-373897302(%rbx,%r10,1),%ebx
+	andl	%ecx,%r12d
+	andl	%edx,%r11d
+	movl	20(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%edx,%r11d
+	addl	%r12d,%ebx
+	movl	%edx,%r12d
+	roll	$20,%ebx
+	addl	%ecx,%ebx
+	notl	%r11d
+	leal	-701558691(%rax,%r10,1),%eax
+	andl	%ebx,%r12d
+	andl	%ecx,%r11d
+	movl	40(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%ecx,%r11d
+	addl	%r12d,%eax
+	movl	%ecx,%r12d
+	roll	$5,%eax
+	addl	%ebx,%eax
+	notl	%r11d
+	leal	38016083(%rdx,%r10,1),%edx
+	andl	%eax,%r12d
+	andl	%ebx,%r11d
+	movl	60(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%ebx,%r11d
+	addl	%r12d,%edx
+	movl	%ebx,%r12d
+	roll	$9,%edx
+	addl	%eax,%edx
+	notl	%r11d
+	leal	-660478335(%rcx,%r10,1),%ecx
+	andl	%edx,%r12d
+	andl	%eax,%r11d
+	movl	16(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%eax,%r11d
+	addl	%r12d,%ecx
+	movl	%eax,%r12d
+	roll	$14,%ecx
+	addl	%edx,%ecx
+	notl	%r11d
+	leal	-405537848(%rbx,%r10,1),%ebx
+	andl	%ecx,%r12d
+	andl	%edx,%r11d
+	movl	36(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%edx,%r11d
+	addl	%r12d,%ebx
+	movl	%edx,%r12d
+	roll	$20,%ebx
+	addl	%ecx,%ebx
+	notl	%r11d
+	leal	568446438(%rax,%r10,1),%eax
+	andl	%ebx,%r12d
+	andl	%ecx,%r11d
+	movl	56(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%ecx,%r11d
+	addl	%r12d,%eax
+	movl	%ecx,%r12d
+	roll	$5,%eax
+	addl	%ebx,%eax
+	notl	%r11d
+	leal	-1019803690(%rdx,%r10,1),%edx
+	andl	%eax,%r12d
+	andl	%ebx,%r11d
+	movl	12(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%ebx,%r11d
+	addl	%r12d,%edx
+	movl	%ebx,%r12d
+	roll	$9,%edx
+	addl	%eax,%edx
+	notl	%r11d
+	leal	-187363961(%rcx,%r10,1),%ecx
+	andl	%edx,%r12d
+	andl	%eax,%r11d
+	movl	32(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%eax,%r11d
+	addl	%r12d,%ecx
+	movl	%eax,%r12d
+	roll	$14,%ecx
+	addl	%edx,%ecx
+	notl	%r11d
+	leal	1163531501(%rbx,%r10,1),%ebx
+	andl	%ecx,%r12d
+	andl	%edx,%r11d
+	movl	52(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%edx,%r11d
+	addl	%r12d,%ebx
+	movl	%edx,%r12d
+	roll	$20,%ebx
+	addl	%ecx,%ebx
+	notl	%r11d
+	leal	-1444681467(%rax,%r10,1),%eax
+	andl	%ebx,%r12d
+	andl	%ecx,%r11d
+	movl	8(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%ecx,%r11d
+	addl	%r12d,%eax
+	movl	%ecx,%r12d
+	roll	$5,%eax
+	addl	%ebx,%eax
+	notl	%r11d
+	leal	-51403784(%rdx,%r10,1),%edx
+	andl	%eax,%r12d
+	andl	%ebx,%r11d
+	movl	28(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%ebx,%r11d
+	addl	%r12d,%edx
+	movl	%ebx,%r12d
+	roll	$9,%edx
+	addl	%eax,%edx
+	notl	%r11d
+	leal	1735328473(%rcx,%r10,1),%ecx
+	andl	%edx,%r12d
+	andl	%eax,%r11d
+	movl	48(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%eax,%r11d
+	addl	%r12d,%ecx
+	movl	%eax,%r12d
+	roll	$14,%ecx
+	addl	%edx,%ecx
+	notl	%r11d
+	leal	-1926607734(%rbx,%r10,1),%ebx
+	andl	%ecx,%r12d
+	andl	%edx,%r11d
+	movl	0(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%edx,%r11d
+	addl	%r12d,%ebx
+	movl	%edx,%r12d
+	roll	$20,%ebx
+	addl	%ecx,%ebx
+	movl	20(%rsi),%r10d
+	movl	%ecx,%r11d
+	leal	-378558(%rax,%r10,1),%eax
+	movl	32(%rsi),%r10d
+	xorl	%edx,%r11d
+	xorl	%ebx,%r11d
+	addl	%r11d,%eax
+	roll	$4,%eax
+	movl	%ebx,%r11d
+	addl	%ebx,%eax
+	leal	-2022574463(%rdx,%r10,1),%edx
+	movl	44(%rsi),%r10d
+	xorl	%ecx,%r11d
+	xorl	%eax,%r11d
+	addl	%r11d,%edx
+	roll	$11,%edx
+	movl	%eax,%r11d
+	addl	%eax,%edx
+	leal	1839030562(%rcx,%r10,1),%ecx
+	movl	56(%rsi),%r10d
+	xorl	%ebx,%r11d
+	xorl	%edx,%r11d
+	addl	%r11d,%ecx
+	roll	$16,%ecx
+	movl	%edx,%r11d
+	addl	%edx,%ecx
+	leal	-35309556(%rbx,%r10,1),%ebx
+	movl	4(%rsi),%r10d
+	xorl	%eax,%r11d
+	xorl	%ecx,%r11d
+	addl	%r11d,%ebx
+	roll	$23,%ebx
+	movl	%ecx,%r11d
+	addl	%ecx,%ebx
+	leal	-1530992060(%rax,%r10,1),%eax
+	movl	16(%rsi),%r10d
+	xorl	%edx,%r11d
+	xorl	%ebx,%r11d
+	addl	%r11d,%eax
+	roll	$4,%eax
+	movl	%ebx,%r11d
+	addl	%ebx,%eax
+	leal	1272893353(%rdx,%r10,1),%edx
+	movl	28(%rsi),%r10d
+	xorl	%ecx,%r11d
+	xorl	%eax,%r11d
+	addl	%r11d,%edx
+	roll	$11,%edx
+	movl	%eax,%r11d
+	addl	%eax,%edx
+	leal	-155497632(%rcx,%r10,1),%ecx
+	movl	40(%rsi),%r10d
+	xorl	%ebx,%r11d
+	xorl	%edx,%r11d
+	addl	%r11d,%ecx
+	roll	$16,%ecx
+	movl	%edx,%r11d
+	addl	%edx,%ecx
+	leal	-1094730640(%rbx,%r10,1),%ebx
+	movl	52(%rsi),%r10d
+	xorl	%eax,%r11d
+	xorl	%ecx,%r11d
+	addl	%r11d,%ebx
+	roll	$23,%ebx
+	movl	%ecx,%r11d
+	addl	%ecx,%ebx
+	leal	681279174(%rax,%r10,1),%eax
+	movl	0(%rsi),%r10d
+	xorl	%edx,%r11d
+	xorl	%ebx,%r11d
+	addl	%r11d,%eax
+	roll	$4,%eax
+	movl	%ebx,%r11d
+	addl	%ebx,%eax
+	leal	-358537222(%rdx,%r10,1),%edx
+	movl	12(%rsi),%r10d
+	xorl	%ecx,%r11d
+	xorl	%eax,%r11d
+	addl	%r11d,%edx
+	roll	$11,%edx
+	movl	%eax,%r11d
+	addl	%eax,%edx
+	leal	-722521979(%rcx,%r10,1),%ecx
+	movl	24(%rsi),%r10d
+	xorl	%ebx,%r11d
+	xorl	%edx,%r11d
+	addl	%r11d,%ecx
+	roll	$16,%ecx
+	movl	%edx,%r11d
+	addl	%edx,%ecx
+	leal	76029189(%rbx,%r10,1),%ebx
+	movl	36(%rsi),%r10d
+	xorl	%eax,%r11d
+	xorl	%ecx,%r11d
+	addl	%r11d,%ebx
+	roll	$23,%ebx
+	movl	%ecx,%r11d
+	addl	%ecx,%ebx
+	leal	-640364487(%rax,%r10,1),%eax
+	movl	48(%rsi),%r10d
+	xorl	%edx,%r11d
+	xorl	%ebx,%r11d
+	addl	%r11d,%eax
+	roll	$4,%eax
+	movl	%ebx,%r11d
+	addl	%ebx,%eax
+	leal	-421815835(%rdx,%r10,1),%edx
+	movl	60(%rsi),%r10d
+	xorl	%ecx,%r11d
+	xorl	%eax,%r11d
+	addl	%r11d,%edx
+	roll	$11,%edx
+	movl	%eax,%r11d
+	addl	%eax,%edx
+	leal	530742520(%rcx,%r10,1),%ecx
+	movl	8(%rsi),%r10d
+	xorl	%ebx,%r11d
+	xorl	%edx,%r11d
+	addl	%r11d,%ecx
+	roll	$16,%ecx
+	movl	%edx,%r11d
+	addl	%edx,%ecx
+	leal	-995338651(%rbx,%r10,1),%ebx
+	movl	0(%rsi),%r10d
+	xorl	%eax,%r11d
+	xorl	%ecx,%r11d
+	addl	%r11d,%ebx
+	roll	$23,%ebx
+	movl	%ecx,%r11d
+	addl	%ecx,%ebx
+	movl	0(%rsi),%r10d
+	movl	$4294967295,%r11d
+	xorl	%edx,%r11d
+	leal	-198630844(%rax,%r10,1),%eax
+	orl	%ebx,%r11d
+	xorl	%ecx,%r11d
+	addl	%r11d,%eax
+	movl	28(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$6,%eax
+	xorl	%ecx,%r11d
+	addl	%ebx,%eax
+	leal	1126891415(%rdx,%r10,1),%edx
+	orl	%eax,%r11d
+	xorl	%ebx,%r11d
+	addl	%r11d,%edx
+	movl	56(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$10,%edx
+	xorl	%ebx,%r11d
+	addl	%eax,%edx
+	leal	-1416354905(%rcx,%r10,1),%ecx
+	orl	%edx,%r11d
+	xorl	%eax,%r11d
+	addl	%r11d,%ecx
+	movl	20(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$15,%ecx
+	xorl	%eax,%r11d
+	addl	%edx,%ecx
+	leal	-57434055(%rbx,%r10,1),%ebx
+	orl	%ecx,%r11d
+	xorl	%edx,%r11d
+	addl	%r11d,%ebx
+	movl	48(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$21,%ebx
+	xorl	%edx,%r11d
+	addl	%ecx,%ebx
+	leal	1700485571(%rax,%r10,1),%eax
+	orl	%ebx,%r11d
+	xorl	%ecx,%r11d
+	addl	%r11d,%eax
+	movl	12(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$6,%eax
+	xorl	%ecx,%r11d
+	addl	%ebx,%eax
+	leal	-1894986606(%rdx,%r10,1),%edx
+	orl	%eax,%r11d
+	xorl	%ebx,%r11d
+	addl	%r11d,%edx
+	movl	40(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$10,%edx
+	xorl	%ebx,%r11d
+	addl	%eax,%edx
+	leal	-1051523(%rcx,%r10,1),%ecx
+	orl	%edx,%r11d
+	xorl	%eax,%r11d
+	addl	%r11d,%ecx
+	movl	4(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$15,%ecx
+	xorl	%eax,%r11d
+	addl	%edx,%ecx
+	leal	-2054922799(%rbx,%r10,1),%ebx
+	orl	%ecx,%r11d
+	xorl	%edx,%r11d
+	addl	%r11d,%ebx
+	movl	32(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$21,%ebx
+	xorl	%edx,%r11d
+	addl	%ecx,%ebx
+	leal	1873313359(%rax,%r10,1),%eax
+	orl	%ebx,%r11d
+	xorl	%ecx,%r11d
+	addl	%r11d,%eax
+	movl	60(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$6,%eax
+	xorl	%ecx,%r11d
+	addl	%ebx,%eax
+	leal	-30611744(%rdx,%r10,1),%edx
+	orl	%eax,%r11d
+	xorl	%ebx,%r11d
+	addl	%r11d,%edx
+	movl	24(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$10,%edx
+	xorl	%ebx,%r11d
+	addl	%eax,%edx
+	leal	-1560198380(%rcx,%r10,1),%ecx
+	orl	%edx,%r11d
+	xorl	%eax,%r11d
+	addl	%r11d,%ecx
+	movl	52(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$15,%ecx
+	xorl	%eax,%r11d
+	addl	%edx,%ecx
+	leal	1309151649(%rbx,%r10,1),%ebx
+	orl	%ecx,%r11d
+	xorl	%edx,%r11d
+	addl	%r11d,%ebx
+	movl	16(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$21,%ebx
+	xorl	%edx,%r11d
+	addl	%ecx,%ebx
+	leal	-145523070(%rax,%r10,1),%eax
+	orl	%ebx,%r11d
+	xorl	%ecx,%r11d
+	addl	%r11d,%eax
+	movl	44(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$6,%eax
+	xorl	%ecx,%r11d
+	addl	%ebx,%eax
+	leal	-1120210379(%rdx,%r10,1),%edx
+	orl	%eax,%r11d
+	xorl	%ebx,%r11d
+	addl	%r11d,%edx
+	movl	8(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$10,%edx
+	xorl	%ebx,%r11d
+	addl	%eax,%edx
+	leal	718787259(%rcx,%r10,1),%ecx
+	orl	%edx,%r11d
+	xorl	%eax,%r11d
+	addl	%r11d,%ecx
+	movl	36(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$15,%ecx
+	xorl	%eax,%r11d
+	addl	%edx,%ecx
+	leal	-343485551(%rbx,%r10,1),%ebx
+	orl	%ecx,%r11d
+	xorl	%edx,%r11d
+	addl	%r11d,%ebx
+	movl	0(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$21,%ebx
+	xorl	%edx,%r11d
+	addl	%ecx,%ebx
+
+	addl	%r8d,%eax
+	addl	%r9d,%ebx
+	addl	%r14d,%ecx
+	addl	%r15d,%edx
+
+
+	addq	$64,%rsi
+	cmpq	%rdi,%rsi
+	jb	.Lloop				
+
+
+.Lend:
+	movl	%eax,0(%rbp)
+	movl	%ebx,4(%rbp)
+	movl	%ecx,8(%rbp)
+	movl	%edx,12(%rbp)
+
+	movq	(%rsp),%r15
+	movq	8(%rsp),%r14
+	movq	16(%rsp),%r12
+	movq	24(%rsp),%rbx
+	movq	32(%rsp),%rbp
+	addq	$40,%rsp
+.Lepilogue:
+	.byte	0xf3,0xc3
+.size	md5_block_asm_data_order,.-md5_block_asm_data_order
+#if defined(HAVE_GNU_STACK)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/crypto/libressl/crypto/md5/md5-macosx-x86_64.s b/crypto/libressl/crypto/md5/md5-macosx-x86_64.s
new file mode 100644
index 0000000000..63da5c0f9a
--- /dev/null
+++ b/crypto/libressl/crypto/md5/md5-macosx-x86_64.s
@@ -0,0 +1,668 @@
+.text	
+.p2align	4
+
+.globl	_md5_block_asm_data_order
+
+_md5_block_asm_data_order:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r14
+	pushq	%r15
+L$prologue:
+
+
+
+
+	movq	%rdi,%rbp
+	shlq	$6,%rdx
+	leaq	(%rsi,%rdx,1),%rdi
+	movl	0(%rbp),%eax
+	movl	4(%rbp),%ebx
+	movl	8(%rbp),%ecx
+	movl	12(%rbp),%edx
+
+
+
+
+
+
+
+	cmpq	%rdi,%rsi
+	je	L$end				
+
+
+L$loop:
+	movl	%eax,%r8d
+	movl	%ebx,%r9d
+	movl	%ecx,%r14d
+	movl	%edx,%r15d
+	movl	0(%rsi),%r10d
+	movl	%edx,%r11d
+	xorl	%ecx,%r11d
+	leal	-680876936(%rax,%r10,1),%eax
+	andl	%ebx,%r11d
+	xorl	%edx,%r11d
+	movl	4(%rsi),%r10d
+	addl	%r11d,%eax
+	roll	$7,%eax
+	movl	%ecx,%r11d
+	addl	%ebx,%eax
+	xorl	%ebx,%r11d
+	leal	-389564586(%rdx,%r10,1),%edx
+	andl	%eax,%r11d
+	xorl	%ecx,%r11d
+	movl	8(%rsi),%r10d
+	addl	%r11d,%edx
+	roll	$12,%edx
+	movl	%ebx,%r11d
+	addl	%eax,%edx
+	xorl	%eax,%r11d
+	leal	606105819(%rcx,%r10,1),%ecx
+	andl	%edx,%r11d
+	xorl	%ebx,%r11d
+	movl	12(%rsi),%r10d
+	addl	%r11d,%ecx
+	roll	$17,%ecx
+	movl	%eax,%r11d
+	addl	%edx,%ecx
+	xorl	%edx,%r11d
+	leal	-1044525330(%rbx,%r10,1),%ebx
+	andl	%ecx,%r11d
+	xorl	%eax,%r11d
+	movl	16(%rsi),%r10d
+	addl	%r11d,%ebx
+	roll	$22,%ebx
+	movl	%edx,%r11d
+	addl	%ecx,%ebx
+	xorl	%ecx,%r11d
+	leal	-176418897(%rax,%r10,1),%eax
+	andl	%ebx,%r11d
+	xorl	%edx,%r11d
+	movl	20(%rsi),%r10d
+	addl	%r11d,%eax
+	roll	$7,%eax
+	movl	%ecx,%r11d
+	addl	%ebx,%eax
+	xorl	%ebx,%r11d
+	leal	1200080426(%rdx,%r10,1),%edx
+	andl	%eax,%r11d
+	xorl	%ecx,%r11d
+	movl	24(%rsi),%r10d
+	addl	%r11d,%edx
+	roll	$12,%edx
+	movl	%ebx,%r11d
+	addl	%eax,%edx
+	xorl	%eax,%r11d
+	leal	-1473231341(%rcx,%r10,1),%ecx
+	andl	%edx,%r11d
+	xorl	%ebx,%r11d
+	movl	28(%rsi),%r10d
+	addl	%r11d,%ecx
+	roll	$17,%ecx
+	movl	%eax,%r11d
+	addl	%edx,%ecx
+	xorl	%edx,%r11d
+	leal	-45705983(%rbx,%r10,1),%ebx
+	andl	%ecx,%r11d
+	xorl	%eax,%r11d
+	movl	32(%rsi),%r10d
+	addl	%r11d,%ebx
+	roll	$22,%ebx
+	movl	%edx,%r11d
+	addl	%ecx,%ebx
+	xorl	%ecx,%r11d
+	leal	1770035416(%rax,%r10,1),%eax
+	andl	%ebx,%r11d
+	xorl	%edx,%r11d
+	movl	36(%rsi),%r10d
+	addl	%r11d,%eax
+	roll	$7,%eax
+	movl	%ecx,%r11d
+	addl	%ebx,%eax
+	xorl	%ebx,%r11d
+	leal	-1958414417(%rdx,%r10,1),%edx
+	andl	%eax,%r11d
+	xorl	%ecx,%r11d
+	movl	40(%rsi),%r10d
+	addl	%r11d,%edx
+	roll	$12,%edx
+	movl	%ebx,%r11d
+	addl	%eax,%edx
+	xorl	%eax,%r11d
+	leal	-42063(%rcx,%r10,1),%ecx
+	andl	%edx,%r11d
+	xorl	%ebx,%r11d
+	movl	44(%rsi),%r10d
+	addl	%r11d,%ecx
+	roll	$17,%ecx
+	movl	%eax,%r11d
+	addl	%edx,%ecx
+	xorl	%edx,%r11d
+	leal	-1990404162(%rbx,%r10,1),%ebx
+	andl	%ecx,%r11d
+	xorl	%eax,%r11d
+	movl	48(%rsi),%r10d
+	addl	%r11d,%ebx
+	roll	$22,%ebx
+	movl	%edx,%r11d
+	addl	%ecx,%ebx
+	xorl	%ecx,%r11d
+	leal	1804603682(%rax,%r10,1),%eax
+	andl	%ebx,%r11d
+	xorl	%edx,%r11d
+	movl	52(%rsi),%r10d
+	addl	%r11d,%eax
+	roll	$7,%eax
+	movl	%ecx,%r11d
+	addl	%ebx,%eax
+	xorl	%ebx,%r11d
+	leal	-40341101(%rdx,%r10,1),%edx
+	andl	%eax,%r11d
+	xorl	%ecx,%r11d
+	movl	56(%rsi),%r10d
+	addl	%r11d,%edx
+	roll	$12,%edx
+	movl	%ebx,%r11d
+	addl	%eax,%edx
+	xorl	%eax,%r11d
+	leal	-1502002290(%rcx,%r10,1),%ecx
+	andl	%edx,%r11d
+	xorl	%ebx,%r11d
+	movl	60(%rsi),%r10d
+	addl	%r11d,%ecx
+	roll	$17,%ecx
+	movl	%eax,%r11d
+	addl	%edx,%ecx
+	xorl	%edx,%r11d
+	leal	1236535329(%rbx,%r10,1),%ebx
+	andl	%ecx,%r11d
+	xorl	%eax,%r11d
+	movl	0(%rsi),%r10d
+	addl	%r11d,%ebx
+	roll	$22,%ebx
+	movl	%edx,%r11d
+	addl	%ecx,%ebx
+	movl	4(%rsi),%r10d
+	movl	%edx,%r11d
+	movl	%edx,%r12d
+	notl	%r11d
+	leal	-165796510(%rax,%r10,1),%eax
+	andl	%ebx,%r12d
+	andl	%ecx,%r11d
+	movl	24(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%ecx,%r11d
+	addl	%r12d,%eax
+	movl	%ecx,%r12d
+	roll	$5,%eax
+	addl	%ebx,%eax
+	notl	%r11d
+	leal	-1069501632(%rdx,%r10,1),%edx
+	andl	%eax,%r12d
+	andl	%ebx,%r11d
+	movl	44(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%ebx,%r11d
+	addl	%r12d,%edx
+	movl	%ebx,%r12d
+	roll	$9,%edx
+	addl	%eax,%edx
+	notl	%r11d
+	leal	643717713(%rcx,%r10,1),%ecx
+	andl	%edx,%r12d
+	andl	%eax,%r11d
+	movl	0(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%eax,%r11d
+	addl	%r12d,%ecx
+	movl	%eax,%r12d
+	roll	$14,%ecx
+	addl	%edx,%ecx
+	notl	%r11d
+	leal	-373897302(%rbx,%r10,1),%ebx
+	andl	%ecx,%r12d
+	andl	%edx,%r11d
+	movl	20(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%edx,%r11d
+	addl	%r12d,%ebx
+	movl	%edx,%r12d
+	roll	$20,%ebx
+	addl	%ecx,%ebx
+	notl	%r11d
+	leal	-701558691(%rax,%r10,1),%eax
+	andl	%ebx,%r12d
+	andl	%ecx,%r11d
+	movl	40(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%ecx,%r11d
+	addl	%r12d,%eax
+	movl	%ecx,%r12d
+	roll	$5,%eax
+	addl	%ebx,%eax
+	notl	%r11d
+	leal	38016083(%rdx,%r10,1),%edx
+	andl	%eax,%r12d
+	andl	%ebx,%r11d
+	movl	60(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%ebx,%r11d
+	addl	%r12d,%edx
+	movl	%ebx,%r12d
+	roll	$9,%edx
+	addl	%eax,%edx
+	notl	%r11d
+	leal	-660478335(%rcx,%r10,1),%ecx
+	andl	%edx,%r12d
+	andl	%eax,%r11d
+	movl	16(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%eax,%r11d
+	addl	%r12d,%ecx
+	movl	%eax,%r12d
+	roll	$14,%ecx
+	addl	%edx,%ecx
+	notl	%r11d
+	leal	-405537848(%rbx,%r10,1),%ebx
+	andl	%ecx,%r12d
+	andl	%edx,%r11d
+	movl	36(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%edx,%r11d
+	addl	%r12d,%ebx
+	movl	%edx,%r12d
+	roll	$20,%ebx
+	addl	%ecx,%ebx
+	notl	%r11d
+	leal	568446438(%rax,%r10,1),%eax
+	andl	%ebx,%r12d
+	andl	%ecx,%r11d
+	movl	56(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%ecx,%r11d
+	addl	%r12d,%eax
+	movl	%ecx,%r12d
+	roll	$5,%eax
+	addl	%ebx,%eax
+	notl	%r11d
+	leal	-1019803690(%rdx,%r10,1),%edx
+	andl	%eax,%r12d
+	andl	%ebx,%r11d
+	movl	12(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%ebx,%r11d
+	addl	%r12d,%edx
+	movl	%ebx,%r12d
+	roll	$9,%edx
+	addl	%eax,%edx
+	notl	%r11d
+	leal	-187363961(%rcx,%r10,1),%ecx
+	andl	%edx,%r12d
+	andl	%eax,%r11d
+	movl	32(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%eax,%r11d
+	addl	%r12d,%ecx
+	movl	%eax,%r12d
+	roll	$14,%ecx
+	addl	%edx,%ecx
+	notl	%r11d
+	leal	1163531501(%rbx,%r10,1),%ebx
+	andl	%ecx,%r12d
+	andl	%edx,%r11d
+	movl	52(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%edx,%r11d
+	addl	%r12d,%ebx
+	movl	%edx,%r12d
+	roll	$20,%ebx
+	addl	%ecx,%ebx
+	notl	%r11d
+	leal	-1444681467(%rax,%r10,1),%eax
+	andl	%ebx,%r12d
+	andl	%ecx,%r11d
+	movl	8(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%ecx,%r11d
+	addl	%r12d,%eax
+	movl	%ecx,%r12d
+	roll	$5,%eax
+	addl	%ebx,%eax
+	notl	%r11d
+	leal	-51403784(%rdx,%r10,1),%edx
+	andl	%eax,%r12d
+	andl	%ebx,%r11d
+	movl	28(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%ebx,%r11d
+	addl	%r12d,%edx
+	movl	%ebx,%r12d
+	roll	$9,%edx
+	addl	%eax,%edx
+	notl	%r11d
+	leal	1735328473(%rcx,%r10,1),%ecx
+	andl	%edx,%r12d
+	andl	%eax,%r11d
+	movl	48(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%eax,%r11d
+	addl	%r12d,%ecx
+	movl	%eax,%r12d
+	roll	$14,%ecx
+	addl	%edx,%ecx
+	notl	%r11d
+	leal	-1926607734(%rbx,%r10,1),%ebx
+	andl	%ecx,%r12d
+	andl	%edx,%r11d
+	movl	0(%rsi),%r10d
+	orl	%r11d,%r12d
+	movl	%edx,%r11d
+	addl	%r12d,%ebx
+	movl	%edx,%r12d
+	roll	$20,%ebx
+	addl	%ecx,%ebx
+	movl	20(%rsi),%r10d
+	movl	%ecx,%r11d
+	leal	-378558(%rax,%r10,1),%eax
+	movl	32(%rsi),%r10d
+	xorl	%edx,%r11d
+	xorl	%ebx,%r11d
+	addl	%r11d,%eax
+	roll	$4,%eax
+	movl	%ebx,%r11d
+	addl	%ebx,%eax
+	leal	-2022574463(%rdx,%r10,1),%edx
+	movl	44(%rsi),%r10d
+	xorl	%ecx,%r11d
+	xorl	%eax,%r11d
+	addl	%r11d,%edx
+	roll	$11,%edx
+	movl	%eax,%r11d
+	addl	%eax,%edx
+	leal	1839030562(%rcx,%r10,1),%ecx
+	movl	56(%rsi),%r10d
+	xorl	%ebx,%r11d
+	xorl	%edx,%r11d
+	addl	%r11d,%ecx
+	roll	$16,%ecx
+	movl	%edx,%r11d
+	addl	%edx,%ecx
+	leal	-35309556(%rbx,%r10,1),%ebx
+	movl	4(%rsi),%r10d
+	xorl	%eax,%r11d
+	xorl	%ecx,%r11d
+	addl	%r11d,%ebx
+	roll	$23,%ebx
+	movl	%ecx,%r11d
+	addl	%ecx,%ebx
+	leal	-1530992060(%rax,%r10,1),%eax
+	movl	16(%rsi),%r10d
+	xorl	%edx,%r11d
+	xorl	%ebx,%r11d
+	addl	%r11d,%eax
+	roll	$4,%eax
+	movl	%ebx,%r11d
+	addl	%ebx,%eax
+	leal	1272893353(%rdx,%r10,1),%edx
+	movl	28(%rsi),%r10d
+	xorl	%ecx,%r11d
+	xorl	%eax,%r11d
+	addl	%r11d,%edx
+	roll	$11,%edx
+	movl	%eax,%r11d
+	addl	%eax,%edx
+	leal	-155497632(%rcx,%r10,1),%ecx
+	movl	40(%rsi),%r10d
+	xorl	%ebx,%r11d
+	xorl	%edx,%r11d
+	addl	%r11d,%ecx
+	roll	$16,%ecx
+	movl	%edx,%r11d
+	addl	%edx,%ecx
+	leal	-1094730640(%rbx,%r10,1),%ebx
+	movl	52(%rsi),%r10d
+	xorl	%eax,%r11d
+	xorl	%ecx,%r11d
+	addl	%r11d,%ebx
+	roll	$23,%ebx
+	movl	%ecx,%r11d
+	addl	%ecx,%ebx
+	leal	681279174(%rax,%r10,1),%eax
+	movl	0(%rsi),%r10d
+	xorl	%edx,%r11d
+	xorl	%ebx,%r11d
+	addl	%r11d,%eax
+	roll	$4,%eax
+	movl	%ebx,%r11d
+	addl	%ebx,%eax
+	leal	-358537222(%rdx,%r10,1),%edx
+	movl	12(%rsi),%r10d
+	xorl	%ecx,%r11d
+	xorl	%eax,%r11d
+	addl	%r11d,%edx
+	roll	$11,%edx
+	movl	%eax,%r11d
+	addl	%eax,%edx
+	leal	-722521979(%rcx,%r10,1),%ecx
+	movl	24(%rsi),%r10d
+	xorl	%ebx,%r11d
+	xorl	%edx,%r11d
+	addl	%r11d,%ecx
+	roll	$16,%ecx
+	movl	%edx,%r11d
+	addl	%edx,%ecx
+	leal	76029189(%rbx,%r10,1),%ebx
+	movl	36(%rsi),%r10d
+	xorl	%eax,%r11d
+	xorl	%ecx,%r11d
+	addl	%r11d,%ebx
+	roll	$23,%ebx
+	movl	%ecx,%r11d
+	addl	%ecx,%ebx
+	leal	-640364487(%rax,%r10,1),%eax
+	movl	48(%rsi),%r10d
+	xorl	%edx,%r11d
+	xorl	%ebx,%r11d
+	addl	%r11d,%eax
+	roll	$4,%eax
+	movl	%ebx,%r11d
+	addl	%ebx,%eax
+	leal	-421815835(%rdx,%r10,1),%edx
+	movl	60(%rsi),%r10d
+	xorl	%ecx,%r11d
+	xorl	%eax,%r11d
+	addl	%r11d,%edx
+	roll	$11,%edx
+	movl	%eax,%r11d
+	addl	%eax,%edx
+	leal	530742520(%rcx,%r10,1),%ecx
+	movl	8(%rsi),%r10d
+	xorl	%ebx,%r11d
+	xorl	%edx,%r11d
+	addl	%r11d,%ecx
+	roll	$16,%ecx
+	movl	%edx,%r11d
+	addl	%edx,%ecx
+	leal	-995338651(%rbx,%r10,1),%ebx
+	movl	0(%rsi),%r10d
+	xorl	%eax,%r11d
+	xorl	%ecx,%r11d
+	addl	%r11d,%ebx
+	roll	$23,%ebx
+	movl	%ecx,%r11d
+	addl	%ecx,%ebx
+	movl	0(%rsi),%r10d
+	movl	$4294967295,%r11d
+	xorl	%edx,%r11d
+	leal	-198630844(%rax,%r10,1),%eax
+	orl	%ebx,%r11d
+	xorl	%ecx,%r11d
+	addl	%r11d,%eax
+	movl	28(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$6,%eax
+	xorl	%ecx,%r11d
+	addl	%ebx,%eax
+	leal	1126891415(%rdx,%r10,1),%edx
+	orl	%eax,%r11d
+	xorl	%ebx,%r11d
+	addl	%r11d,%edx
+	movl	56(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$10,%edx
+	xorl	%ebx,%r11d
+	addl	%eax,%edx
+	leal	-1416354905(%rcx,%r10,1),%ecx
+	orl	%edx,%r11d
+	xorl	%eax,%r11d
+	addl	%r11d,%ecx
+	movl	20(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$15,%ecx
+	xorl	%eax,%r11d
+	addl	%edx,%ecx
+	leal	-57434055(%rbx,%r10,1),%ebx
+	orl	%ecx,%r11d
+	xorl	%edx,%r11d
+	addl	%r11d,%ebx
+	movl	48(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$21,%ebx
+	xorl	%edx,%r11d
+	addl	%ecx,%ebx
+	leal	1700485571(%rax,%r10,1),%eax
+	orl	%ebx,%r11d
+	xorl	%ecx,%r11d
+	addl	%r11d,%eax
+	movl	12(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$6,%eax
+	xorl	%ecx,%r11d
+	addl	%ebx,%eax
+	leal	-1894986606(%rdx,%r10,1),%edx
+	orl	%eax,%r11d
+	xorl	%ebx,%r11d
+	addl	%r11d,%edx
+	movl	40(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$10,%edx
+	xorl	%ebx,%r11d
+	addl	%eax,%edx
+	leal	-1051523(%rcx,%r10,1),%ecx
+	orl	%edx,%r11d
+	xorl	%eax,%r11d
+	addl	%r11d,%ecx
+	movl	4(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$15,%ecx
+	xorl	%eax,%r11d
+	addl	%edx,%ecx
+	leal	-2054922799(%rbx,%r10,1),%ebx
+	orl	%ecx,%r11d
+	xorl	%edx,%r11d
+	addl	%r11d,%ebx
+	movl	32(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$21,%ebx
+	xorl	%edx,%r11d
+	addl	%ecx,%ebx
+	leal	1873313359(%rax,%r10,1),%eax
+	orl	%ebx,%r11d
+	xorl	%ecx,%r11d
+	addl	%r11d,%eax
+	movl	60(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$6,%eax
+	xorl	%ecx,%r11d
+	addl	%ebx,%eax
+	leal	-30611744(%rdx,%r10,1),%edx
+	orl	%eax,%r11d
+	xorl	%ebx,%r11d
+	addl	%r11d,%edx
+	movl	24(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$10,%edx
+	xorl	%ebx,%r11d
+	addl	%eax,%edx
+	leal	-1560198380(%rcx,%r10,1),%ecx
+	orl	%edx,%r11d
+	xorl	%eax,%r11d
+	addl	%r11d,%ecx
+	movl	52(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$15,%ecx
+	xorl	%eax,%r11d
+	addl	%edx,%ecx
+	leal	1309151649(%rbx,%r10,1),%ebx
+	orl	%ecx,%r11d
+	xorl	%edx,%r11d
+	addl	%r11d,%ebx
+	movl	16(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$21,%ebx
+	xorl	%edx,%r11d
+	addl	%ecx,%ebx
+	leal	-145523070(%rax,%r10,1),%eax
+	orl	%ebx,%r11d
+	xorl	%ecx,%r11d
+	addl	%r11d,%eax
+	movl	44(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$6,%eax
+	xorl	%ecx,%r11d
+	addl	%ebx,%eax
+	leal	-1120210379(%rdx,%r10,1),%edx
+	orl	%eax,%r11d
+	xorl	%ebx,%r11d
+	addl	%r11d,%edx
+	movl	8(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$10,%edx
+	xorl	%ebx,%r11d
+	addl	%eax,%edx
+	leal	718787259(%rcx,%r10,1),%ecx
+	orl	%edx,%r11d
+	xorl	%eax,%r11d
+	addl	%r11d,%ecx
+	movl	36(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$15,%ecx
+	xorl	%eax,%r11d
+	addl	%edx,%ecx
+	leal	-343485551(%rbx,%r10,1),%ebx
+	orl	%ecx,%r11d
+	xorl	%edx,%r11d
+	addl	%r11d,%ebx
+	movl	0(%rsi),%r10d
+	movl	$4294967295,%r11d
+	roll	$21,%ebx
+	xorl	%edx,%r11d
+	addl	%ecx,%ebx
+
+	addl	%r8d,%eax
+	addl	%r9d,%ebx
+	addl	%r14d,%ecx
+	addl	%r15d,%edx
+
+
+	addq	$64,%rsi
+	cmpq	%rdi,%rsi
+	jb	L$loop				
+
+
+L$end:
+	movl	%eax,0(%rbp)
+	movl	%ebx,4(%rbp)
+	movl	%ecx,8(%rbp)
+	movl	%edx,12(%rbp)
+
+	movq	(%rsp),%r15
+	movq	8(%rsp),%r14
+	movq	16(%rsp),%r12
+	movq	24(%rsp),%rbx
+	movq	32(%rsp),%rbp
+	addq	$40,%rsp
+L$epilogue:
+	.byte	0xf3,0xc3
+
diff --git a/crypto/libressl/crypto/md5/md5_dgst.c b/crypto/libressl/crypto/md5/md5_dgst.c
new file mode 100644
index 0000000000..32e9883c67
--- /dev/null
+++ b/crypto/libressl/crypto/md5/md5_dgst.c
@@ -0,0 +1,183 @@
+/* $OpenBSD: md5_dgst.c,v 1.13 2014/07/09 11:10:51 bcook Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include "md5_locl.h"
+#include 
+#include 
+
+/* Implemented from RFC1321 The MD5 Message-Digest Algorithm
+ */
+
+#define INIT_DATA_A (unsigned long)0x67452301L
+#define INIT_DATA_B (unsigned long)0xefcdab89L
+#define INIT_DATA_C (unsigned long)0x98badcfeL
+#define INIT_DATA_D (unsigned long)0x10325476L
+
+int MD5_Init(MD5_CTX *c)
+	{
+	memset (c,0,sizeof(*c));
+	c->A=INIT_DATA_A;
+	c->B=INIT_DATA_B;
+	c->C=INIT_DATA_C;
+	c->D=INIT_DATA_D;
+	return 1;
+	}
+
+#ifndef md5_block_data_order
+#ifdef X
+#undef X
+#endif
+void md5_block_data_order (MD5_CTX *c, const void *data_, size_t num)
+	{
+	const unsigned char *data=data_;
+	unsigned MD32_REG_T A,B,C,D,l;
+#ifndef MD32_XARRAY
+	/* See comment in crypto/sha/sha_locl.h for details. */
+	unsigned MD32_REG_T	XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+				XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
+# define X(i)	XX##i
+#else
+	MD5_LONG XX[MD5_LBLOCK];
+# define X(i)	XX[i]
+#endif
+
+	A=c->A;
+	B=c->B;
+	C=c->C;
+	D=c->D;
+
+	for (;num--;)
+		{
+	HOST_c2l(data,l); X( 0)=l;		HOST_c2l(data,l); X( 1)=l;
+	/* Round 0 */
+	R0(A,B,C,D,X( 0), 7,0xd76aa478L);	HOST_c2l(data,l); X( 2)=l;
+	R0(D,A,B,C,X( 1),12,0xe8c7b756L);	HOST_c2l(data,l); X( 3)=l;
+	R0(C,D,A,B,X( 2),17,0x242070dbL);	HOST_c2l(data,l); X( 4)=l;
+	R0(B,C,D,A,X( 3),22,0xc1bdceeeL);	HOST_c2l(data,l); X( 5)=l;
+	R0(A,B,C,D,X( 4), 7,0xf57c0fafL);	HOST_c2l(data,l); X( 6)=l;
+	R0(D,A,B,C,X( 5),12,0x4787c62aL);	HOST_c2l(data,l); X( 7)=l;
+	R0(C,D,A,B,X( 6),17,0xa8304613L);	HOST_c2l(data,l); X( 8)=l;
+	R0(B,C,D,A,X( 7),22,0xfd469501L);	HOST_c2l(data,l); X( 9)=l;
+	R0(A,B,C,D,X( 8), 7,0x698098d8L);	HOST_c2l(data,l); X(10)=l;
+	R0(D,A,B,C,X( 9),12,0x8b44f7afL);	HOST_c2l(data,l); X(11)=l;
+	R0(C,D,A,B,X(10),17,0xffff5bb1L);	HOST_c2l(data,l); X(12)=l;
+	R0(B,C,D,A,X(11),22,0x895cd7beL);	HOST_c2l(data,l); X(13)=l;
+	R0(A,B,C,D,X(12), 7,0x6b901122L);	HOST_c2l(data,l); X(14)=l;
+	R0(D,A,B,C,X(13),12,0xfd987193L);	HOST_c2l(data,l); X(15)=l;
+	R0(C,D,A,B,X(14),17,0xa679438eL);
+	R0(B,C,D,A,X(15),22,0x49b40821L);
+	/* Round 1 */
+	R1(A,B,C,D,X( 1), 5,0xf61e2562L);
+	R1(D,A,B,C,X( 6), 9,0xc040b340L);
+	R1(C,D,A,B,X(11),14,0x265e5a51L);
+	R1(B,C,D,A,X( 0),20,0xe9b6c7aaL);
+	R1(A,B,C,D,X( 5), 5,0xd62f105dL);
+	R1(D,A,B,C,X(10), 9,0x02441453L);
+	R1(C,D,A,B,X(15),14,0xd8a1e681L);
+	R1(B,C,D,A,X( 4),20,0xe7d3fbc8L);
+	R1(A,B,C,D,X( 9), 5,0x21e1cde6L);
+	R1(D,A,B,C,X(14), 9,0xc33707d6L);
+	R1(C,D,A,B,X( 3),14,0xf4d50d87L);
+	R1(B,C,D,A,X( 8),20,0x455a14edL);
+	R1(A,B,C,D,X(13), 5,0xa9e3e905L);
+	R1(D,A,B,C,X( 2), 9,0xfcefa3f8L);
+	R1(C,D,A,B,X( 7),14,0x676f02d9L);
+	R1(B,C,D,A,X(12),20,0x8d2a4c8aL);
+	/* Round 2 */
+	R2(A,B,C,D,X( 5), 4,0xfffa3942L);
+	R2(D,A,B,C,X( 8),11,0x8771f681L);
+	R2(C,D,A,B,X(11),16,0x6d9d6122L);
+	R2(B,C,D,A,X(14),23,0xfde5380cL);
+	R2(A,B,C,D,X( 1), 4,0xa4beea44L);
+	R2(D,A,B,C,X( 4),11,0x4bdecfa9L);
+	R2(C,D,A,B,X( 7),16,0xf6bb4b60L);
+	R2(B,C,D,A,X(10),23,0xbebfbc70L);
+	R2(A,B,C,D,X(13), 4,0x289b7ec6L);
+	R2(D,A,B,C,X( 0),11,0xeaa127faL);
+	R2(C,D,A,B,X( 3),16,0xd4ef3085L);
+	R2(B,C,D,A,X( 6),23,0x04881d05L);
+	R2(A,B,C,D,X( 9), 4,0xd9d4d039L);
+	R2(D,A,B,C,X(12),11,0xe6db99e5L);
+	R2(C,D,A,B,X(15),16,0x1fa27cf8L);
+	R2(B,C,D,A,X( 2),23,0xc4ac5665L);
+	/* Round 3 */
+	R3(A,B,C,D,X( 0), 6,0xf4292244L);
+	R3(D,A,B,C,X( 7),10,0x432aff97L);
+	R3(C,D,A,B,X(14),15,0xab9423a7L);
+	R3(B,C,D,A,X( 5),21,0xfc93a039L);
+	R3(A,B,C,D,X(12), 6,0x655b59c3L);
+	R3(D,A,B,C,X( 3),10,0x8f0ccc92L);
+	R3(C,D,A,B,X(10),15,0xffeff47dL);
+	R3(B,C,D,A,X( 1),21,0x85845dd1L);
+	R3(A,B,C,D,X( 8), 6,0x6fa87e4fL);
+	R3(D,A,B,C,X(15),10,0xfe2ce6e0L);
+	R3(C,D,A,B,X( 6),15,0xa3014314L);
+	R3(B,C,D,A,X(13),21,0x4e0811a1L);
+	R3(A,B,C,D,X( 4), 6,0xf7537e82L);
+	R3(D,A,B,C,X(11),10,0xbd3af235L);
+	R3(C,D,A,B,X( 2),15,0x2ad7d2bbL);
+	R3(B,C,D,A,X( 9),21,0xeb86d391L);
+
+	A = c->A += A;
+	B = c->B += B;
+	C = c->C += C;
+	D = c->D += D;
+		}
+	}
+#endif
diff --git a/crypto/libressl/crypto/md5/md5_locl.h b/crypto/libressl/crypto/md5/md5_locl.h
new file mode 100644
index 0000000000..e34e25aea1
--- /dev/null
+++ b/crypto/libressl/crypto/md5/md5_locl.h
@@ -0,0 +1,128 @@
+/* $OpenBSD: md5_locl.h,v 1.12 2014/08/18 19:11:48 bcook Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+
+#include 
+
+#ifdef MD5_ASM
+# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) || \
+     defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
+#  define md5_block_data_order md5_block_asm_data_order
+# elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
+#  define md5_block_data_order md5_block_asm_data_order
+# endif
+#endif
+
+void md5_block_data_order (MD5_CTX *c, const void *p,size_t num);
+
+#define DATA_ORDER_IS_LITTLE_ENDIAN
+
+#define HASH_LONG		MD5_LONG
+#define HASH_CTX		MD5_CTX
+#define HASH_CBLOCK		MD5_CBLOCK
+#define HASH_UPDATE		MD5_Update
+#define HASH_TRANSFORM		MD5_Transform
+#define HASH_FINAL		MD5_Final
+#define	HASH_MAKE_STRING(c,s)	do {	\
+	unsigned long ll;		\
+	ll=(c)->A; HOST_l2c(ll,(s));	\
+	ll=(c)->B; HOST_l2c(ll,(s));	\
+	ll=(c)->C; HOST_l2c(ll,(s));	\
+	ll=(c)->D; HOST_l2c(ll,(s));	\
+	} while (0)
+#define	HASH_BLOCK_DATA_ORDER	md5_block_data_order
+
+#include "md32_common.h"
+
+/*
+#define	F(x,y,z)	(((x) & (y))  |  ((~(x)) & (z)))
+#define	G(x,y,z)	(((x) & (z))  |  ((y) & (~(z))))
+*/
+
+/* As pointed out by Wei Dai , the above can be
+ * simplified to the code below.  Wei attributes these optimizations
+ * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
+ */
+#define	F(b,c,d)	((((c) ^ (d)) & (b)) ^ (d))
+#define	G(b,c,d)	((((b) ^ (c)) & (d)) ^ (c))
+#define	H(b,c,d)	((b) ^ (c) ^ (d))
+#define	I(b,c,d)	(((~(d)) | (b)) ^ (c))
+
+#define R0(a,b,c,d,k,s,t) { \
+	a+=((k)+(t)+F((b),(c),(d))); \
+	a=ROTATE(a,s); \
+	a+=b; };\
+
+#define R1(a,b,c,d,k,s,t) { \
+	a+=((k)+(t)+G((b),(c),(d))); \
+	a=ROTATE(a,s); \
+	a+=b; };
+
+#define R2(a,b,c,d,k,s,t) { \
+	a+=((k)+(t)+H((b),(c),(d))); \
+	a=ROTATE(a,s); \
+	a+=b; };
+
+#define R3(a,b,c,d,k,s,t) { \
+	a+=((k)+(t)+I((b),(c),(d))); \
+	a=ROTATE(a,s); \
+	a+=b; };
diff --git a/crypto/libressl/crypto/md5/md5_one.c b/crypto/libressl/crypto/md5/md5_one.c
new file mode 100644
index 0000000000..f93fb0e844
--- /dev/null
+++ b/crypto/libressl/crypto/md5/md5_one.c
@@ -0,0 +1,77 @@
+/* $OpenBSD: md5_one.c,v 1.9 2015/09/10 15:03:59 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md)
+	{
+	MD5_CTX c;
+	static unsigned char m[MD5_DIGEST_LENGTH];
+
+	if (md == NULL) md=m;
+	if (!MD5_Init(&c))
+		return NULL;
+	MD5_Update(&c,d,n);
+	MD5_Final(md,&c);
+	explicit_bzero(&c,sizeof(c));
+	return(md);
+	}
+
diff --git a/crypto/libressl/crypto/mem_clr.c b/crypto/libressl/crypto/mem_clr.c
new file mode 100644
index 0000000000..d8ce0c286a
--- /dev/null
+++ b/crypto/libressl/crypto/mem_clr.c
@@ -0,0 +1,11 @@
+/* $OpenBSD: mem_clr.c,v 1.3 2014/04/15 23:04:49 tedu Exp $ */
+
+/* Ted Unangst places this file in the public domain. */
+#include 
+#include 
+
+void
+OPENSSL_cleanse(void *ptr, size_t len)
+{
+	explicit_bzero(ptr, len);
+}
diff --git a/crypto/libressl/crypto/mem_dbg.c b/crypto/libressl/crypto/mem_dbg.c
new file mode 100644
index 0000000000..b0b5e78af7
--- /dev/null
+++ b/crypto/libressl/crypto/mem_dbg.c
@@ -0,0 +1,201 @@
+/* $OpenBSD$ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+int
+CRYPTO_mem_ctrl(int mode)
+{
+	return (CRYPTO_MEM_CHECK_OFF);
+}
+
+int
+CRYPTO_is_mem_check_on(void)
+{
+	return (0);
+}
+
+
+void
+CRYPTO_dbg_set_options(long bits)
+{
+	return;
+}
+
+long
+CRYPTO_dbg_get_options(void)
+{
+	return (0);
+}
+
+int
+CRYPTO_push_info_(const char *info, const char *file, int line)
+{
+	return (0);
+}
+
+int
+CRYPTO_pop_info(void)
+{
+	return (0);
+}
+
+int
+CRYPTO_remove_all_info(void)
+{
+	return (0);
+}
+
+void
+CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
+    int before_p)
+{
+	/* CRYPTO_dbg_malloc is no longer permitted */
+	abort();
+}
+
+void
+CRYPTO_dbg_free(void *addr, int before_p)
+{
+	/* CRYPTO_dbg_free is no longer permitted */
+	abort();
+}
+
+void
+CRYPTO_dbg_realloc(void *addr1, void *addr2, int num,
+    const char *file, int line, int before_p)
+{
+	/* CRYPTO_dbg_realloc is no longer permitted */
+	abort();
+}
+
+void
+CRYPTO_mem_leaks(BIO *b)
+{
+	return;
+}
+
+void
+CRYPTO_mem_leaks_fp(FILE *fp)
+{
+	return;
+}
+
+
+void
+CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb)
+{
+	return;
+}
diff --git a/crypto/libressl/crypto/modes/cbc128.c b/crypto/libressl/crypto/modes/cbc128.c
new file mode 100644
index 0000000000..e9a4f06316
--- /dev/null
+++ b/crypto/libressl/crypto/modes/cbc128.c
@@ -0,0 +1,202 @@
+/* $OpenBSD: cbc128.c,v 1.3 2014/06/12 15:49:30 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include 
+#include "modes_lcl.h"
+#include 
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+
+#undef STRICT_ALIGNMENT
+#ifdef __STRICT_ALIGNMENT
+#define STRICT_ALIGNMENT 1
+#else
+#define STRICT_ALIGNMENT 0
+#endif
+
+void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], block128_f block)
+{
+	size_t n;
+	const unsigned char *iv = ivec;
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	if (STRICT_ALIGNMENT &&
+	    ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
+		while (len>=16) {
+			for(n=0; n<16; ++n)
+				out[n] = in[n] ^ iv[n];
+			(*block)(out, out, key);
+			iv = out;
+			len -= 16;
+			in  += 16;
+			out += 16;
+		}
+	} else {
+		while (len>=16) {
+			for(n=0; n<16; n+=sizeof(size_t))
+				*(size_t*)(out+n) =
+				*(size_t*)(in+n) ^ *(size_t*)(iv+n);
+			(*block)(out, out, key);
+			iv = out;
+			len -= 16;
+			in  += 16;
+			out += 16;
+		}
+	}
+#endif
+	while (len) {
+		for(n=0; n<16 && n=16) {
+				(*block)(in, out, key);
+				for(n=0; n<16; ++n)
+					out[n] ^= iv[n];
+				iv = in;
+				len -= 16;
+				in  += 16;
+				out += 16;
+			}
+		} else if (16%sizeof(size_t) == 0) { /* always true */
+			while (len>=16) {
+				size_t *out_t=(size_t *)out, *iv_t=(size_t *)iv;
+
+				(*block)(in, out, key);
+				for(n=0; n<16/sizeof(size_t); n++)
+					out_t[n] ^= iv_t[n];
+				iv = in;
+				len -= 16;
+				in  += 16;
+				out += 16;
+			}
+		}
+		memcpy(ivec,iv,16);
+	} else {
+		if (STRICT_ALIGNMENT &&
+		    ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0) {
+			unsigned char c;
+			while (len>=16) {
+				(*block)(in, tmp.c, key);
+				for(n=0; n<16; ++n) {
+					c = in[n];
+					out[n] = tmp.c[n] ^ ivec[n];
+					ivec[n] = c;
+				}
+				len -= 16;
+				in  += 16;
+				out += 16;
+			}
+		} else if (16%sizeof(size_t) == 0) { /* always true */
+			while (len>=16) {
+				size_t c, *out_t=(size_t *)out, *ivec_t=(size_t *)ivec;
+				const size_t *in_t=(const size_t *)in;
+
+				(*block)(in, tmp.c, key);
+				for(n=0; n<16/sizeof(size_t); n++) {
+					c = in_t[n];
+					out_t[n] = tmp.t[n] ^ ivec_t[n];
+					ivec_t[n] = c;
+				}
+				len -= 16;
+				in  += 16;
+				out += 16;
+			}
+		}
+	}
+#endif
+	while (len) {
+		unsigned char c;
+		(*block)(in, tmp.c, key);
+		for(n=0; n<16 && n
+#include "modes_lcl.h"
+#include 
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+
+/* First you setup M and L parameters and pass the key schedule.
+ * This is called once per session setup... */
+void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx,
+	unsigned int M,unsigned int L,void *key,block128_f block)
+{
+	memset(ctx->nonce.c,0,sizeof(ctx->nonce.c));
+	ctx->nonce.c[0] = ((u8)(L-1)&7) | (u8)(((M-2)/2)&7)<<3;
+	ctx->blocks = 0;
+	ctx->block = block;
+	ctx->key = key;
+}
+
+/* !!! Following interfaces are to be called *once* per packet !!! */
+
+/* Then you setup per-message nonce and pass the length of the message */
+int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx,
+	const unsigned char *nonce,size_t nlen,size_t mlen)
+{
+	unsigned int L = ctx->nonce.c[0]&7;	/* the L parameter */
+
+	if (nlen<(14-L)) return -1;		/* nonce is too short */
+
+	if (sizeof(mlen)==8 && L>=3) {
+		ctx->nonce.c[8]  = (u8)(mlen>>(56%(sizeof(mlen)*8)));
+		ctx->nonce.c[9]  = (u8)(mlen>>(48%(sizeof(mlen)*8)));
+		ctx->nonce.c[10] = (u8)(mlen>>(40%(sizeof(mlen)*8)));
+		ctx->nonce.c[11] = (u8)(mlen>>(32%(sizeof(mlen)*8)));
+	}
+	else
+		ctx->nonce.u[1] = 0;
+
+	ctx->nonce.c[12] = (u8)(mlen>>24);
+	ctx->nonce.c[13] = (u8)(mlen>>16);
+	ctx->nonce.c[14] = (u8)(mlen>>8);
+	ctx->nonce.c[15] = (u8)mlen;
+
+	ctx->nonce.c[0] &= ~0x40;	/* clear Adata flag */
+	memcpy(&ctx->nonce.c[1],nonce,14-L);
+
+	return 0;
+}
+
+/* Then you pass additional authentication data, this is optional */
+void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx,
+	const unsigned char *aad,size_t alen)
+{	unsigned int i;
+	block128_f block = ctx->block;
+
+	if (alen==0) return;
+
+	ctx->nonce.c[0] |= 0x40;	/* set Adata flag */
+	(*block)(ctx->nonce.c,ctx->cmac.c,ctx->key),
+	ctx->blocks++;
+
+	if (alen<(0x10000-0x100)) {
+		ctx->cmac.c[0] ^= (u8)(alen>>8);
+		ctx->cmac.c[1] ^= (u8)alen;
+		i=2;
+	}
+	else if (sizeof(alen)==8 && alen>=(size_t)1<<(32%(sizeof(alen)*8))) {
+		ctx->cmac.c[0] ^= 0xFF;
+		ctx->cmac.c[1] ^= 0xFF;
+		ctx->cmac.c[2] ^= (u8)(alen>>(56%(sizeof(alen)*8)));
+		ctx->cmac.c[3] ^= (u8)(alen>>(48%(sizeof(alen)*8)));
+		ctx->cmac.c[4] ^= (u8)(alen>>(40%(sizeof(alen)*8)));
+		ctx->cmac.c[5] ^= (u8)(alen>>(32%(sizeof(alen)*8)));
+		ctx->cmac.c[6] ^= (u8)(alen>>24);
+		ctx->cmac.c[7] ^= (u8)(alen>>16);
+		ctx->cmac.c[8] ^= (u8)(alen>>8);
+		ctx->cmac.c[9] ^= (u8)alen;
+		i=10;
+	}
+	else {
+		ctx->cmac.c[0] ^= 0xFF;
+		ctx->cmac.c[1] ^= 0xFE;
+		ctx->cmac.c[2] ^= (u8)(alen>>24);
+		ctx->cmac.c[3] ^= (u8)(alen>>16);
+		ctx->cmac.c[4] ^= (u8)(alen>>8);
+		ctx->cmac.c[5] ^= (u8)alen;
+		i=6;
+	}
+
+	do {
+		for(;i<16 && alen;++i,++aad,--alen)
+			ctx->cmac.c[i] ^= *aad;
+		(*block)(ctx->cmac.c,ctx->cmac.c,ctx->key),
+		ctx->blocks++;
+		i=0;
+	} while (alen);
+}
+
+/* Finally you encrypt or decrypt the message */
+
+/* counter part of nonce may not be larger than L*8 bits,
+ * L is not larger than 8, therefore 64-bit counter... */
+static void ctr64_inc(unsigned char *counter) {
+	unsigned int n=8;
+	u8  c;
+
+	counter += 8;
+	do {
+		--n;
+		c = counter[n];
+		++c;
+		counter[n] = c;
+		if (c) return;
+	} while (n);
+}
+
+int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx,
+	const unsigned char *inp, unsigned char *out,
+	size_t len)
+{
+	size_t		n;
+	unsigned int	i,L;
+	unsigned char	flags0	= ctx->nonce.c[0];
+	block128_f	block	= ctx->block;
+	void *		key	= ctx->key;
+	union { u64 u[2]; u8 c[16]; } scratch;
+
+	if (!(flags0&0x40))
+		(*block)(ctx->nonce.c,ctx->cmac.c,key),
+		ctx->blocks++;
+
+	ctx->nonce.c[0] = L = flags0&7;
+	for (n=0,i=15-L;i<15;++i) {
+		n |= ctx->nonce.c[i];
+		ctx->nonce.c[i]=0;
+		n <<= 8;
+	}
+	n |= ctx->nonce.c[15];	/* reconstructed length */
+	ctx->nonce.c[15]=1;
+
+	if (n!=len) return -1;	/* length mismatch */
+
+	ctx->blocks += ((len+15)>>3)|1;
+	if (ctx->blocks > (U64(1)<<61))	return -2; /* too much data */
+
+	while (len>=16) {
+#ifdef __STRICT_ALIGNMENT
+		union { u64 u[2]; u8 c[16]; } temp;
+
+		memcpy (temp.c,inp,16);
+		ctx->cmac.u[0] ^= temp.u[0];
+		ctx->cmac.u[1] ^= temp.u[1];
+#else
+		ctx->cmac.u[0] ^= ((u64*)inp)[0];
+		ctx->cmac.u[1] ^= ((u64*)inp)[1];
+#endif
+		(*block)(ctx->cmac.c,ctx->cmac.c,key);
+		(*block)(ctx->nonce.c,scratch.c,key);
+		ctr64_inc(ctx->nonce.c);
+#ifdef __STRICT_ALIGNMENT
+		temp.u[0] ^= scratch.u[0];
+		temp.u[1] ^= scratch.u[1];
+		memcpy(out,temp.c,16);
+#else
+		((u64*)out)[0] = scratch.u[0]^((u64*)inp)[0];
+		((u64*)out)[1] = scratch.u[1]^((u64*)inp)[1];
+#endif
+		inp += 16;
+		out += 16;
+		len -= 16;
+	}
+
+	if (len) {
+		for (i=0; icmac.c[i] ^= inp[i];
+		(*block)(ctx->cmac.c,ctx->cmac.c,key);
+		(*block)(ctx->nonce.c,scratch.c,key);
+		for (i=0; inonce.c[i]=0;
+
+	(*block)(ctx->nonce.c,scratch.c,key);
+	ctx->cmac.u[0] ^= scratch.u[0];
+	ctx->cmac.u[1] ^= scratch.u[1];
+
+	ctx->nonce.c[0] = flags0;
+
+	return 0;
+}
+
+int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx,
+	const unsigned char *inp, unsigned char *out,
+	size_t len)
+{
+	size_t		n;
+	unsigned int	i,L;
+	unsigned char	flags0	= ctx->nonce.c[0];
+	block128_f	block	= ctx->block;
+	void *		key	= ctx->key;
+	union { u64 u[2]; u8 c[16]; } scratch;
+
+	if (!(flags0&0x40))
+		(*block)(ctx->nonce.c,ctx->cmac.c,key);
+
+	ctx->nonce.c[0] = L = flags0&7;
+	for (n=0,i=15-L;i<15;++i) {
+		n |= ctx->nonce.c[i];
+		ctx->nonce.c[i]=0;
+		n <<= 8;
+	}
+	n |= ctx->nonce.c[15];	/* reconstructed length */
+	ctx->nonce.c[15]=1;
+
+	if (n!=len) return -1;
+
+	while (len>=16) {
+#ifdef __STRICT_ALIGNMENT
+		union { u64 u[2]; u8 c[16]; } temp;
+#endif
+		(*block)(ctx->nonce.c,scratch.c,key);
+		ctr64_inc(ctx->nonce.c);
+#ifdef __STRICT_ALIGNMENT
+		memcpy (temp.c,inp,16);
+		ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]);
+		ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]);
+		memcpy (out,scratch.c,16);
+#else
+		ctx->cmac.u[0] ^= (((u64*)out)[0] = scratch.u[0]^((u64*)inp)[0]);
+		ctx->cmac.u[1] ^= (((u64*)out)[1] = scratch.u[1]^((u64*)inp)[1]);
+#endif
+		(*block)(ctx->cmac.c,ctx->cmac.c,key);
+
+		inp += 16;
+		out += 16;
+		len -= 16;
+	}
+
+	if (len) {
+		(*block)(ctx->nonce.c,scratch.c,key);
+		for (i=0; icmac.c[i] ^= (out[i] = scratch.c[i]^inp[i]);
+		(*block)(ctx->cmac.c,ctx->cmac.c,key);
+	}
+
+	for (i=15-L;i<16;++i)
+		ctx->nonce.c[i]=0;
+
+	(*block)(ctx->nonce.c,scratch.c,key);
+	ctx->cmac.u[0] ^= scratch.u[0];
+	ctx->cmac.u[1] ^= scratch.u[1];
+
+	ctx->nonce.c[0] = flags0;
+
+	return 0;
+}
+
+static void ctr64_add (unsigned char *counter,size_t inc)
+{	size_t n=8, val=0;
+
+	counter += 8;
+	do {
+		--n;
+		val += counter[n] + (inc&0xff);
+		counter[n] = (unsigned char)val;
+		val >>= 8;	/* carry bit */
+		inc >>= 8;
+	} while(n && (inc || val));
+}
+
+int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx,
+	const unsigned char *inp, unsigned char *out,
+	size_t len,ccm128_f stream)
+{
+	size_t		n;
+	unsigned int	i,L;
+	unsigned char	flags0	= ctx->nonce.c[0];
+	block128_f	block	= ctx->block;
+	void *		key	= ctx->key;
+	union { u64 u[2]; u8 c[16]; } scratch;
+
+	if (!(flags0&0x40))
+		(*block)(ctx->nonce.c,ctx->cmac.c,key),
+		ctx->blocks++;
+
+	ctx->nonce.c[0] = L = flags0&7;
+	for (n=0,i=15-L;i<15;++i) {
+		n |= ctx->nonce.c[i];
+		ctx->nonce.c[i]=0;
+		n <<= 8;
+	}
+	n |= ctx->nonce.c[15];	/* reconstructed length */
+	ctx->nonce.c[15]=1;
+
+	if (n!=len) return -1;	/* length mismatch */
+
+	ctx->blocks += ((len+15)>>3)|1;
+	if (ctx->blocks > (U64(1)<<61))	return -2; /* too much data */
+
+	if ((n=len/16)) {
+		(*stream)(inp,out,n,key,ctx->nonce.c,ctx->cmac.c);
+		n   *= 16;
+		inp += n;
+		out += n;
+		len -= n;
+		if (len) ctr64_add(ctx->nonce.c,n/16);
+	}
+
+	if (len) {
+		for (i=0; icmac.c[i] ^= inp[i];
+		(*block)(ctx->cmac.c,ctx->cmac.c,key);
+		(*block)(ctx->nonce.c,scratch.c,key);
+		for (i=0; inonce.c[i]=0;
+
+	(*block)(ctx->nonce.c,scratch.c,key);
+	ctx->cmac.u[0] ^= scratch.u[0];
+	ctx->cmac.u[1] ^= scratch.u[1];
+
+	ctx->nonce.c[0] = flags0;
+
+	return 0;
+}
+
+int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx,
+	const unsigned char *inp, unsigned char *out,
+	size_t len,ccm128_f stream)
+{
+	size_t		n;
+	unsigned int	i,L;
+	unsigned char	flags0	= ctx->nonce.c[0];
+	block128_f	block	= ctx->block;
+	void *		key	= ctx->key;
+	union { u64 u[2]; u8 c[16]; } scratch;
+
+	if (!(flags0&0x40))
+		(*block)(ctx->nonce.c,ctx->cmac.c,key);
+
+	ctx->nonce.c[0] = L = flags0&7;
+	for (n=0,i=15-L;i<15;++i) {
+		n |= ctx->nonce.c[i];
+		ctx->nonce.c[i]=0;
+		n <<= 8;
+	}
+	n |= ctx->nonce.c[15];	/* reconstructed length */
+	ctx->nonce.c[15]=1;
+
+	if (n!=len) return -1;
+
+	if ((n=len/16)) {
+		(*stream)(inp,out,n,key,ctx->nonce.c,ctx->cmac.c);
+		n   *= 16;
+		inp += n;
+		out += n;
+		len -= n;
+		if (len) ctr64_add(ctx->nonce.c,n/16);
+	}
+
+	if (len) {
+		(*block)(ctx->nonce.c,scratch.c,key);
+		for (i=0; icmac.c[i] ^= (out[i] = scratch.c[i]^inp[i]);
+		(*block)(ctx->cmac.c,ctx->cmac.c,key);
+	}
+
+	for (i=15-L;i<16;++i)
+		ctx->nonce.c[i]=0;
+
+	(*block)(ctx->nonce.c,scratch.c,key);
+	ctx->cmac.u[0] ^= scratch.u[0];
+	ctx->cmac.u[1] ^= scratch.u[1];
+
+	ctx->nonce.c[0] = flags0;
+
+	return 0;
+}
+
+size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx,unsigned char *tag,size_t len)
+{	unsigned int M = (ctx->nonce.c[0]>>3)&7;	/* the M parameter */
+
+	M *= 2; M += 2;
+	if (lencmac.c,M);
+	return M;
+}
diff --git a/crypto/libressl/crypto/modes/cfb128.c b/crypto/libressl/crypto/modes/cfb128.c
new file mode 100644
index 0000000000..f1e7bfa12b
--- /dev/null
+++ b/crypto/libressl/crypto/modes/cfb128.c
@@ -0,0 +1,234 @@
+/* $OpenBSD: cfb128.c,v 1.3 2014/06/12 15:49:30 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include 
+#include "modes_lcl.h"
+#include 
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+
+/* The input and output encrypted as though 128bit cfb mode is being
+ * used.  The extra state information to record how much of the
+ * 128bit block we have used is contained in *num;
+ */
+void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], int *num,
+			int enc, block128_f block)
+{
+    unsigned int n;
+    size_t l = 0;
+
+    n = *num;
+
+    if (enc) {
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	if (16%sizeof(size_t) == 0) do {	/* always true actually */
+		while (n && len) {
+			*(out++) = ivec[n] ^= *(in++);
+			--len;
+			n = (n+1) % 16;
+		}
+#ifdef __STRICT_ALIGNMENT
+		if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
+			break;
+#endif
+		while (len>=16) {
+			(*block)(ivec, ivec, key);
+			for (; n<16; n+=sizeof(size_t)) {
+				*(size_t*)(out+n) =
+				*(size_t*)(ivec+n) ^= *(size_t*)(in+n);
+			}
+			len -= 16;
+			out += 16;
+			in  += 16;
+			n = 0;
+		}
+		if (len) {
+			(*block)(ivec, ivec, key);
+			while (len--) {
+				out[n] = ivec[n] ^= in[n];
+				++n;
+			}
+		}
+		*num = n;
+		return;
+	} while (0);
+	/* the rest would be commonly eliminated by x86* compiler */
+#endif
+	while (l=16) {
+			(*block)(ivec, ivec, key);
+			for (; n<16; n+=sizeof(size_t)) {
+				size_t t = *(size_t*)(in+n);
+				*(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t;
+				*(size_t*)(ivec+n) = t;
+			}
+			len -= 16;
+			out += 16;
+			in  += 16;
+			n = 0;
+		}
+		if (len) {
+			(*block)(ivec, ivec, key);
+			while (len--) {
+				unsigned char c;
+				out[n] = ivec[n] ^ (c = in[n]); ivec[n] = c;
+				++n;
+			}
+ 		}
+		*num = n;
+		return;
+	} while (0);
+	/* the rest would be commonly eliminated by x86* compiler */
+#endif
+	while (l128) return;
+
+	/* fill in the first half of the new IV with the current IV */
+	memcpy(ovec,ivec,16);
+	/* construct the new IV */
+	(*block)(ivec,ivec,key);
+	num = (nbits+7)/8;
+	if (enc)	/* encrypt the input */
+	    for(n=0 ; n < num ; ++n)
+		out[n] = (ovec[16+n] = in[n] ^ ivec[n]);
+	else		/* decrypt the input */
+	    for(n=0 ; n < num ; ++n)
+		out[n] = (ovec[16+n] = in[n]) ^ ivec[n];
+	/* shift ovec left... */
+	rem = nbits%8;
+	num = nbits/8;
+	if(rem==0)
+	    memcpy(ivec,ovec+num,16);
+	else
+	    for(n=0 ; n < 16 ; ++n)
+		ivec[n] = ovec[n+num]<>(8-rem);
+
+    /* it is not necessary to cleanse ovec, since the IV is not secret */
+}
+
+/* N.B. This expects the input to be packed, MS bit first */
+void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out,
+		 	size_t bits, const void *key,
+			unsigned char ivec[16], int *num,
+			int enc, block128_f block)
+{
+    size_t n;
+    unsigned char c[1],d[1];
+
+    for(n=0 ; n> (unsigned int)(n%8));
+	}
+}
+
+void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
+			size_t length, const void *key,
+			unsigned char ivec[16], int *num,
+			int enc, block128_f block)
+{
+    size_t n;
+
+    for(n=0 ; n
+#include "modes_lcl.h"
+#include 
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+#include 
+
+/* NOTE: the IV/counter CTR mode is big-endian.  The code itself
+ * is endian-neutral. */
+
+/* increment counter (128-bit int) by 1 */
+static void ctr128_inc(unsigned char *counter) {
+	u32 n=16;
+	u8  c;
+
+	do {
+		--n;
+		c = counter[n];
+		++c;
+		counter[n] = c;
+		if (c) return;
+	} while (n);
+}
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+static void
+ctr128_inc_aligned(unsigned char *counter)
+{
+	size_t *data,c,n;
+
+	if (BYTE_ORDER == LITTLE_ENDIAN) {
+		ctr128_inc(counter);
+		return;
+	}
+
+	data = (size_t *)counter;
+	n = 16/sizeof(size_t);
+	do {
+		--n;
+		c = data[n];
+		++c;
+		data[n] = c;
+		if (c) return;
+	} while (n);
+}
+#endif
+
+/* The input encrypted as though 128bit counter mode is being
+ * used.  The extra state information to record how much of the
+ * 128bit block we have used is contained in *num, and the
+ * encrypted counter is kept in ecount_buf.  Both *num and
+ * ecount_buf must be initialised with zeros before the first
+ * call to CRYPTO_ctr128_encrypt().
+ *
+ * This algorithm assumes that the counter is in the x lower bits
+ * of the IV (ivec), and that the application has full control over
+ * overflow and the rest of the IV.  This implementation takes NO
+ * responsability for checking that the counter doesn't overflow
+ * into the rest of the IV when incremented.
+ */
+void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], unsigned char ecount_buf[16],
+			unsigned int *num, block128_f block)
+{
+	unsigned int n;
+	size_t l=0;
+
+	assert(*num < 16);
+
+	n = *num;
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	if (16%sizeof(size_t) == 0) do { /* always true actually */
+		while (n && len) {
+			*(out++) = *(in++) ^ ecount_buf[n];
+			--len;
+			n = (n+1) % 16;
+		}
+
+#ifdef __STRICT_ALIGNMENT
+		if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
+			break;
+#endif
+		while (len>=16) {
+			(*block)(ivec, ecount_buf, key);
+			ctr128_inc_aligned(ivec);
+			for (; n<16; n+=sizeof(size_t))
+				*(size_t *)(out+n) =
+				*(size_t *)(in+n) ^ *(size_t *)(ecount_buf+n);
+			len -= 16;
+			out += 16;
+			in  += 16;
+			n = 0;
+		}
+		if (len) {
+			(*block)(ivec, ecount_buf, key);
+ 			ctr128_inc_aligned(ivec);
+			while (len--) {
+				out[n] = in[n] ^ ecount_buf[n];
+				++n;
+			}
+		}
+		*num = n;
+		return;
+	} while(0);
+	/* the rest would be commonly eliminated by x86* compiler */
+#endif
+	while (l=16) {
+		size_t blocks = len/16;
+		/*
+		 * 1<<28 is just a not-so-small yet not-so-large number...
+		 * Below condition is practically never met, but it has to
+		 * be checked for code correctness.
+		 */
+		if (sizeof(size_t)>sizeof(unsigned int) && blocks>(1U<<28))
+			blocks = (1U<<28);
+		/*
+		 * As (*func) operates on 32-bit counter, caller
+		 * has to handle overflow. 'if' below detects the
+		 * overflow, which is then handled by limiting the
+		 * amount of blocks to the exact overflow point...
+		 */
+		ctr32 += (u32)blocks;
+		if (ctr32 < blocks) {
+			blocks -= ctr32;
+			ctr32   = 0;
+		}
+		(*func)(in,out,blocks,key,ivec);
+		/* (*ctr) does not update ivec, caller does: */
+		PUTU32(ivec+12,ctr32);
+		/* ... overflow was detected, propogate carry. */
+		if (ctr32 == 0)	ctr96_inc(ivec);
+		blocks *= 16;
+		len -= blocks;
+		out += blocks;
+		in  += blocks;
+	}
+	if (len) {
+		memset(ecount_buf,0,16);
+		(*func)(ecount_buf,ecount_buf,1,key,ivec);
+		++ctr32;
+		PUTU32(ivec+12,ctr32);
+		if (ctr32 == 0)	ctr96_inc(ivec);
+		while (len--) {
+			out[n] = in[n] ^ ecount_buf[n];
+			++n;
+		}
+	}
+
+	*num=n;
+}
diff --git a/crypto/libressl/crypto/modes/cts128.c b/crypto/libressl/crypto/modes/cts128.c
new file mode 100644
index 0000000000..faada177e7
--- /dev/null
+++ b/crypto/libressl/crypto/modes/cts128.c
@@ -0,0 +1,267 @@
+/* $OpenBSD: cts128.c,v 1.4 2015/02/10 09:46:30 miod Exp $ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
+ *
+ * Rights for redistribution and usage in source and binary
+ * forms are granted according to the OpenSSL license.
+ */
+
+#include 
+#include "modes_lcl.h"
+#include 
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+
+/*
+ * Trouble with Ciphertext Stealing, CTS, mode is that there is no
+ * common official specification, but couple of cipher/application
+ * specific ones: RFC2040 and RFC3962. Then there is 'Proposal to
+ * Extend CBC Mode By "Ciphertext Stealing"' at NIST site, which
+ * deviates from mentioned RFCs. Most notably it allows input to be
+ * of block length and it doesn't flip the order of the last two
+ * blocks. CTS is being discussed even in ECB context, but it's not
+ * adopted for any known application. This implementation provides
+ * two interfaces: one compliant with above mentioned RFCs and one
+ * compliant with the NIST proposal, both extending CBC mode.
+ */
+
+size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], block128_f block)
+{	size_t residue, n;
+
+	if (len <= 16) return 0;
+
+	if ((residue=len%16) == 0) residue = 16;
+
+	len -= residue;
+
+	CRYPTO_cbc128_encrypt(in,out,len,key,ivec,block);
+
+	in  += len;
+	out += len;
+
+	for (n=0; n
+#include "modes_lcl.h"
+#include 
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+
+#if defined(BSWAP4) && defined(__STRICT_ALIGNMENT)
+/* redefine, because alignment is ensured */
+#undef	GETU32
+#define	GETU32(p)	BSWAP4(*(const u32 *)(p))
+#undef	PUTU32
+#define	PUTU32(p,v)	*(u32 *)(p) = BSWAP4(v)
+#endif
+
+#define	PACK(s)		((size_t)(s)<<(sizeof(size_t)*8-16))
+#define REDUCE1BIT(V)	\
+	do { \
+		if (sizeof(size_t)==8) { \
+			u64 T = U64(0xe100000000000000) & (0-(V.lo&1)); \
+			V.lo  = (V.hi<<63)|(V.lo>>1); \
+			V.hi  = (V.hi>>1 )^T; \
+		} else { \
+			u32 T = 0xe1000000U & (0-(u32)(V.lo&1)); \
+			V.lo  = (V.hi<<63)|(V.lo>>1); \
+			V.hi  = (V.hi>>1 )^((u64)T<<32); \
+		} \
+	} while(0)
+
+/*
+ * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should
+ * never be set to 8. 8 is effectively reserved for testing purposes.
+ * TABLE_BITS>1 are lookup-table-driven implementations referred to as
+ * "Shoup's" in GCM specification. In other words OpenSSL does not cover
+ * whole spectrum of possible table driven implementations. Why? In
+ * non-"Shoup's" case memory access pattern is segmented in such manner,
+ * that it's trivial to see that cache timing information can reveal
+ * fair portion of intermediate hash value. Given that ciphertext is
+ * always available to attacker, it's possible for him to attempt to
+ * deduce secret parameter H and if successful, tamper with messages
+ * [which is nothing but trivial in CTR mode]. In "Shoup's" case it's
+ * not as trivial, but there is no reason to believe that it's resistant
+ * to cache-timing attack. And the thing about "8-bit" implementation is
+ * that it consumes 16 (sixteen) times more memory, 4KB per individual
+ * key + 1KB shared. Well, on pros side it should be twice as fast as
+ * "4-bit" version. And for gcc-generated x86[_64] code, "8-bit" version
+ * was observed to run ~75% faster, closer to 100% for commercial
+ * compilers... Yet "4-bit" procedure is preferred, because it's
+ * believed to provide better security-performance balance and adequate
+ * all-round performance. "All-round" refers to things like:
+ *
+ * - shorter setup time effectively improves overall timing for
+ *   handling short messages;
+ * - larger table allocation can become unbearable because of VM
+ *   subsystem penalties (for example on Windows large enough free
+ *   results in VM working set trimming, meaning that consequent
+ *   malloc would immediately incur working set expansion);
+ * - larger table has larger cache footprint, which can affect
+ *   performance of other code paths (not necessarily even from same
+ *   thread in Hyper-Threading world);
+ *
+ * Value of 1 is not appropriate for performance reasons.
+ */
+#if	TABLE_BITS==8
+
+static void gcm_init_8bit(u128 Htable[256], u64 H[2])
+{
+	int  i, j;
+	u128 V;
+
+	Htable[0].hi = 0;
+	Htable[0].lo = 0;
+	V.hi = H[0];
+	V.lo = H[1];
+
+	for (Htable[128]=V, i=64; i>0; i>>=1) {
+		REDUCE1BIT(V);
+		Htable[i] = V;
+	}
+
+	for (i=2; i<256; i<<=1) {
+		u128 *Hi = Htable+i, H0 = *Hi;
+		for (j=1; j>8);
+		Z.hi = (Z.hi>>8);
+		if (sizeof(size_t)==8)
+			Z.hi ^= rem_8bit[rem];
+		else
+			Z.hi ^= (u64)rem_8bit[rem]<<32;
+	}
+
+	if (BYTE_ORDER == LITTLE_ENDIAN) {
+#ifdef BSWAP8
+		Xi[0] = BSWAP8(Z.hi);
+		Xi[1] = BSWAP8(Z.lo);
+#else
+		u8 *p = (u8 *)Xi;
+		u32 v;
+		v = (u32)(Z.hi>>32);	PUTU32(p,v);
+		v = (u32)(Z.hi);	PUTU32(p+4,v);
+		v = (u32)(Z.lo>>32);	PUTU32(p+8,v);
+		v = (u32)(Z.lo);	PUTU32(p+12,v);
+#endif
+	}
+	else {
+		Xi[0] = Z.hi;
+		Xi[1] = Z.lo;
+	}
+}
+#define GCM_MUL(ctx,Xi)   gcm_gmult_8bit(ctx->Xi.u,ctx->Htable)
+
+#elif	TABLE_BITS==4
+
+static void gcm_init_4bit(u128 Htable[16], u64 H[2])
+{
+	u128 V;
+#if defined(OPENSSL_SMALL_FOOTPRINT)
+	int  i;
+#endif
+
+	Htable[0].hi = 0;
+	Htable[0].lo = 0;
+	V.hi = H[0];
+	V.lo = H[1];
+
+#if defined(OPENSSL_SMALL_FOOTPRINT)
+	for (Htable[8]=V, i=4; i>0; i>>=1) {
+		REDUCE1BIT(V);
+		Htable[i] = V;
+	}
+
+	for (i=2; i<16; i<<=1) {
+		u128 *Hi = Htable+i;
+		int   j;
+		for (V=*Hi, j=1; j>32;
+			Htable[j].lo = V.hi<<32|V.hi>>32;
+		}
+	}
+#endif
+}
+
+#ifndef GHASH_ASM
+static const size_t rem_4bit[16] = {
+	PACK(0x0000), PACK(0x1C20), PACK(0x3840), PACK(0x2460),
+	PACK(0x7080), PACK(0x6CA0), PACK(0x48C0), PACK(0x54E0),
+	PACK(0xE100), PACK(0xFD20), PACK(0xD940), PACK(0xC560),
+	PACK(0x9180), PACK(0x8DA0), PACK(0xA9C0), PACK(0xB5E0) };
+
+static void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16])
+{
+	u128 Z;
+	int cnt = 15;
+	size_t rem, nlo, nhi;
+
+	nlo  = ((const u8 *)Xi)[15];
+	nhi  = nlo>>4;
+	nlo &= 0xf;
+
+	Z.hi = Htable[nlo].hi;
+	Z.lo = Htable[nlo].lo;
+
+	while (1) {
+		rem  = (size_t)Z.lo&0xf;
+		Z.lo = (Z.hi<<60)|(Z.lo>>4);
+		Z.hi = (Z.hi>>4);
+		if (sizeof(size_t)==8)
+			Z.hi ^= rem_4bit[rem];
+		else
+			Z.hi ^= (u64)rem_4bit[rem]<<32;
+
+		Z.hi ^= Htable[nhi].hi;
+		Z.lo ^= Htable[nhi].lo;
+
+		if (--cnt<0)		break;
+
+		nlo  = ((const u8 *)Xi)[cnt];
+		nhi  = nlo>>4;
+		nlo &= 0xf;
+
+		rem  = (size_t)Z.lo&0xf;
+		Z.lo = (Z.hi<<60)|(Z.lo>>4);
+		Z.hi = (Z.hi>>4);
+		if (sizeof(size_t)==8)
+			Z.hi ^= rem_4bit[rem];
+		else
+			Z.hi ^= (u64)rem_4bit[rem]<<32;
+
+		Z.hi ^= Htable[nlo].hi;
+		Z.lo ^= Htable[nlo].lo;
+	}
+
+	if (BYTE_ORDER == LITTLE_ENDIAN) {
+#ifdef BSWAP8
+		Xi[0] = BSWAP8(Z.hi);
+		Xi[1] = BSWAP8(Z.lo);
+#else
+		u8 *p = (u8 *)Xi;
+		u32 v;
+		v = (u32)(Z.hi>>32);	PUTU32(p,v);
+		v = (u32)(Z.hi);	PUTU32(p+4,v);
+		v = (u32)(Z.lo>>32);	PUTU32(p+8,v);
+		v = (u32)(Z.lo);	PUTU32(p+12,v);
+#endif
+	}
+	else {
+		Xi[0] = Z.hi;
+		Xi[1] = Z.lo;
+	}
+}
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+/*
+ * Streamed gcm_mult_4bit, see CRYPTO_gcm128_[en|de]crypt for
+ * details... Compiler-generated code doesn't seem to give any
+ * performance improvement, at least not on x86[_64]. It's here
+ * mostly as reference and a placeholder for possible future
+ * non-trivial optimization[s]...
+ */
+static void gcm_ghash_4bit(u64 Xi[2],const u128 Htable[16],
+				const u8 *inp,size_t len)
+{
+    u128 Z;
+    int cnt;
+    size_t rem, nlo, nhi;
+
+#if 1
+    do {
+	cnt  = 15;
+	nlo  = ((const u8 *)Xi)[15];
+	nlo ^= inp[15];
+	nhi  = nlo>>4;
+	nlo &= 0xf;
+
+	Z.hi = Htable[nlo].hi;
+	Z.lo = Htable[nlo].lo;
+
+	while (1) {
+		rem  = (size_t)Z.lo&0xf;
+		Z.lo = (Z.hi<<60)|(Z.lo>>4);
+		Z.hi = (Z.hi>>4);
+		if (sizeof(size_t)==8)
+			Z.hi ^= rem_4bit[rem];
+		else
+			Z.hi ^= (u64)rem_4bit[rem]<<32;
+
+		Z.hi ^= Htable[nhi].hi;
+		Z.lo ^= Htable[nhi].lo;
+
+		if (--cnt<0)		break;
+
+		nlo  = ((const u8 *)Xi)[cnt];
+		nlo ^= inp[cnt];
+		nhi  = nlo>>4;
+		nlo &= 0xf;
+
+		rem  = (size_t)Z.lo&0xf;
+		Z.lo = (Z.hi<<60)|(Z.lo>>4);
+		Z.hi = (Z.hi>>4);
+		if (sizeof(size_t)==8)
+			Z.hi ^= rem_4bit[rem];
+		else
+			Z.hi ^= (u64)rem_4bit[rem]<<32;
+
+		Z.hi ^= Htable[nlo].hi;
+		Z.lo ^= Htable[nlo].lo;
+	}
+#else
+    /*
+     * Extra 256+16 bytes per-key plus 512 bytes shared tables
+     * [should] give ~50% improvement... One could have PACK()-ed
+     * the rem_8bit even here, but the priority is to minimize
+     * cache footprint...
+     */ 
+    u128 Hshr4[16];	/* Htable shifted right by 4 bits */
+    u8   Hshl4[16];	/* Htable shifted left  by 4 bits */
+    static const unsigned short rem_8bit[256] = {
+	0x0000, 0x01C2, 0x0384, 0x0246, 0x0708, 0x06CA, 0x048C, 0x054E,
+	0x0E10, 0x0FD2, 0x0D94, 0x0C56, 0x0918, 0x08DA, 0x0A9C, 0x0B5E,
+	0x1C20, 0x1DE2, 0x1FA4, 0x1E66, 0x1B28, 0x1AEA, 0x18AC, 0x196E,
+	0x1230, 0x13F2, 0x11B4, 0x1076, 0x1538, 0x14FA, 0x16BC, 0x177E,
+	0x3840, 0x3982, 0x3BC4, 0x3A06, 0x3F48, 0x3E8A, 0x3CCC, 0x3D0E,
+	0x3650, 0x3792, 0x35D4, 0x3416, 0x3158, 0x309A, 0x32DC, 0x331E,
+	0x2460, 0x25A2, 0x27E4, 0x2626, 0x2368, 0x22AA, 0x20EC, 0x212E,
+	0x2A70, 0x2BB2, 0x29F4, 0x2836, 0x2D78, 0x2CBA, 0x2EFC, 0x2F3E,
+	0x7080, 0x7142, 0x7304, 0x72C6, 0x7788, 0x764A, 0x740C, 0x75CE,
+	0x7E90, 0x7F52, 0x7D14, 0x7CD6, 0x7998, 0x785A, 0x7A1C, 0x7BDE,
+	0x6CA0, 0x6D62, 0x6F24, 0x6EE6, 0x6BA8, 0x6A6A, 0x682C, 0x69EE,
+	0x62B0, 0x6372, 0x6134, 0x60F6, 0x65B8, 0x647A, 0x663C, 0x67FE,
+	0x48C0, 0x4902, 0x4B44, 0x4A86, 0x4FC8, 0x4E0A, 0x4C4C, 0x4D8E,
+	0x46D0, 0x4712, 0x4554, 0x4496, 0x41D8, 0x401A, 0x425C, 0x439E,
+	0x54E0, 0x5522, 0x5764, 0x56A6, 0x53E8, 0x522A, 0x506C, 0x51AE,
+	0x5AF0, 0x5B32, 0x5974, 0x58B6, 0x5DF8, 0x5C3A, 0x5E7C, 0x5FBE,
+	0xE100, 0xE0C2, 0xE284, 0xE346, 0xE608, 0xE7CA, 0xE58C, 0xE44E,
+	0xEF10, 0xEED2, 0xEC94, 0xED56, 0xE818, 0xE9DA, 0xEB9C, 0xEA5E,
+	0xFD20, 0xFCE2, 0xFEA4, 0xFF66, 0xFA28, 0xFBEA, 0xF9AC, 0xF86E,
+	0xF330, 0xF2F2, 0xF0B4, 0xF176, 0xF438, 0xF5FA, 0xF7BC, 0xF67E,
+	0xD940, 0xD882, 0xDAC4, 0xDB06, 0xDE48, 0xDF8A, 0xDDCC, 0xDC0E,
+	0xD750, 0xD692, 0xD4D4, 0xD516, 0xD058, 0xD19A, 0xD3DC, 0xD21E,
+	0xC560, 0xC4A2, 0xC6E4, 0xC726, 0xC268, 0xC3AA, 0xC1EC, 0xC02E,
+	0xCB70, 0xCAB2, 0xC8F4, 0xC936, 0xCC78, 0xCDBA, 0xCFFC, 0xCE3E,
+	0x9180, 0x9042, 0x9204, 0x93C6, 0x9688, 0x974A, 0x950C, 0x94CE,
+	0x9F90, 0x9E52, 0x9C14, 0x9DD6, 0x9898, 0x995A, 0x9B1C, 0x9ADE,
+	0x8DA0, 0x8C62, 0x8E24, 0x8FE6, 0x8AA8, 0x8B6A, 0x892C, 0x88EE,
+	0x83B0, 0x8272, 0x8034, 0x81F6, 0x84B8, 0x857A, 0x873C, 0x86FE,
+	0xA9C0, 0xA802, 0xAA44, 0xAB86, 0xAEC8, 0xAF0A, 0xAD4C, 0xAC8E,
+	0xA7D0, 0xA612, 0xA454, 0xA596, 0xA0D8, 0xA11A, 0xA35C, 0xA29E,
+	0xB5E0, 0xB422, 0xB664, 0xB7A6, 0xB2E8, 0xB32A, 0xB16C, 0xB0AE,
+	0xBBF0, 0xBA32, 0xB874, 0xB9B6, 0xBCF8, 0xBD3A, 0xBF7C, 0xBEBE };
+    /*
+     * This pre-processing phase slows down procedure by approximately
+     * same time as it makes each loop spin faster. In other words
+     * single block performance is approximately same as straightforward
+     * "4-bit" implementation, and then it goes only faster...
+     */
+    for (cnt=0; cnt<16; ++cnt) {
+	Z.hi = Htable[cnt].hi;
+	Z.lo = Htable[cnt].lo;
+	Hshr4[cnt].lo = (Z.hi<<60)|(Z.lo>>4);
+	Hshr4[cnt].hi = (Z.hi>>4);
+	Hshl4[cnt]    = (u8)(Z.lo<<4);
+    }
+
+    do {
+	for (Z.lo=0, Z.hi=0, cnt=15; cnt; --cnt) {
+		nlo  = ((const u8 *)Xi)[cnt];
+		nlo ^= inp[cnt];
+		nhi  = nlo>>4;
+		nlo &= 0xf;
+
+		Z.hi ^= Htable[nlo].hi;
+		Z.lo ^= Htable[nlo].lo;
+
+		rem = (size_t)Z.lo&0xff;
+
+		Z.lo = (Z.hi<<56)|(Z.lo>>8);
+		Z.hi = (Z.hi>>8);
+
+		Z.hi ^= Hshr4[nhi].hi;
+		Z.lo ^= Hshr4[nhi].lo;
+		Z.hi ^= (u64)rem_8bit[rem^Hshl4[nhi]]<<48;
+	}
+
+	nlo  = ((const u8 *)Xi)[0];
+	nlo ^= inp[0];
+	nhi  = nlo>>4;
+	nlo &= 0xf;
+
+	Z.hi ^= Htable[nlo].hi;
+	Z.lo ^= Htable[nlo].lo;
+
+	rem = (size_t)Z.lo&0xf;
+
+	Z.lo = (Z.hi<<60)|(Z.lo>>4);
+	Z.hi = (Z.hi>>4);
+
+	Z.hi ^= Htable[nhi].hi;
+	Z.lo ^= Htable[nhi].lo;
+	Z.hi ^= ((u64)rem_8bit[rem<<4])<<48;
+#endif
+
+	if (BYTE_ORDER == LITTLE_ENDIAN) {
+#ifdef BSWAP8
+		Xi[0] = BSWAP8(Z.hi);
+		Xi[1] = BSWAP8(Z.lo);
+#else
+		u8 *p = (u8 *)Xi;
+		u32 v;
+		v = (u32)(Z.hi>>32);	PUTU32(p,v);
+		v = (u32)(Z.hi);	PUTU32(p+4,v);
+		v = (u32)(Z.lo>>32);	PUTU32(p+8,v);
+		v = (u32)(Z.lo);	PUTU32(p+12,v);
+#endif
+	}
+	else {
+		Xi[0] = Z.hi;
+		Xi[1] = Z.lo;
+	}
+    } while (inp+=16, len-=16);
+}
+#endif
+#else
+void gcm_gmult_4bit(u64 Xi[2],const u128 Htable[16]);
+void gcm_ghash_4bit(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
+#endif
+
+#define GCM_MUL(ctx,Xi)   gcm_gmult_4bit(ctx->Xi.u,ctx->Htable)
+#if defined(GHASH_ASM) || !defined(OPENSSL_SMALL_FOOTPRINT)
+#define GHASH(ctx,in,len) gcm_ghash_4bit((ctx)->Xi.u,(ctx)->Htable,in,len)
+/* GHASH_CHUNK is "stride parameter" missioned to mitigate cache
+ * trashing effect. In other words idea is to hash data while it's
+ * still in L1 cache after encryption pass... */
+#define GHASH_CHUNK       (3*1024)
+#endif
+
+#else	/* TABLE_BITS */
+
+static void gcm_gmult_1bit(u64 Xi[2],const u64 H[2])
+{
+	u128 V,Z = { 0,0 };
+	long X;
+	int  i,j;
+	const long *xi = (const long *)Xi;
+
+	V.hi = H[0];	/* H is in host byte order, no byte swapping */
+	V.lo = H[1];
+
+	for (j=0; j<16/sizeof(long); ++j) {
+		if (BYTE_ORDER == LITTLE_ENDIAN) {
+			if (sizeof(long)==8) {
+#ifdef BSWAP8
+				X = (long)(BSWAP8(xi[j]));
+#else
+				const u8 *p = (const u8 *)(xi+j);
+				X = (long)((u64)GETU32(p)<<32|GETU32(p+4));
+#endif
+			}
+			else {
+				const u8 *p = (const u8 *)(xi+j);
+				X = (long)GETU32(p);
+			}
+		}
+		else
+			X = xi[j];
+
+		for (i=0; i<8*sizeof(long); ++i, X<<=1) {
+			u64 M = (u64)(X>>(8*sizeof(long)-1));
+			Z.hi ^= V.hi&M;
+			Z.lo ^= V.lo&M;
+
+			REDUCE1BIT(V);
+		}
+	}
+
+	if (BYTE_ORDER == LITTLE_ENDIAN) {
+#ifdef BSWAP8
+		Xi[0] = BSWAP8(Z.hi);
+		Xi[1] = BSWAP8(Z.lo);
+#else
+		u8 *p = (u8 *)Xi;
+		u32 v;
+		v = (u32)(Z.hi>>32);	PUTU32(p,v);
+		v = (u32)(Z.hi);	PUTU32(p+4,v);
+		v = (u32)(Z.lo>>32);	PUTU32(p+8,v);
+		v = (u32)(Z.lo);	PUTU32(p+12,v);
+#endif
+	}
+	else {
+		Xi[0] = Z.hi;
+		Xi[1] = Z.lo;
+	}
+}
+#define GCM_MUL(ctx,Xi)	  gcm_gmult_1bit(ctx->Xi.u,ctx->H.u)
+
+#endif
+
+#if	TABLE_BITS==4 && defined(GHASH_ASM)
+# if	!defined(I386_ONLY) && \
+	(defined(__i386)	|| defined(__i386__)	|| \
+	 defined(__x86_64)	|| defined(__x86_64__)	|| \
+	 defined(_M_IX86)	|| defined(_M_AMD64)	|| defined(_M_X64))
+#  define GHASH_ASM_X86_OR_64
+#  define GCM_FUNCREF_4BIT
+extern unsigned int OPENSSL_ia32cap_P[2];
+
+void gcm_init_clmul(u128 Htable[16],const u64 Xi[2]);
+void gcm_gmult_clmul(u64 Xi[2],const u128 Htable[16]);
+void gcm_ghash_clmul(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
+
+#  if	defined(__i386) || defined(__i386__) || defined(_M_IX86)
+#   define GHASH_ASM_X86
+void gcm_gmult_4bit_mmx(u64 Xi[2],const u128 Htable[16]);
+void gcm_ghash_4bit_mmx(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
+
+void gcm_gmult_4bit_x86(u64 Xi[2],const u128 Htable[16]);
+void gcm_ghash_4bit_x86(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
+#  endif
+# elif defined(__arm__) || defined(__arm)
+#  include "arm_arch.h"
+#  if __ARM_ARCH__>=7
+#   define GHASH_ASM_ARM
+#   define GCM_FUNCREF_4BIT
+void gcm_gmult_neon(u64 Xi[2],const u128 Htable[16]);
+void gcm_ghash_neon(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
+#  endif
+# endif
+#endif
+
+#ifdef GCM_FUNCREF_4BIT
+# undef  GCM_MUL
+# define GCM_MUL(ctx,Xi)	(*gcm_gmult_p)(ctx->Xi.u,ctx->Htable)
+# ifdef GHASH
+#  undef  GHASH
+#  define GHASH(ctx,in,len)	(*gcm_ghash_p)(ctx->Xi.u,ctx->Htable,in,len)
+# endif
+#endif
+
+void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx,void *key,block128_f block)
+{
+	memset(ctx,0,sizeof(*ctx));
+	ctx->block = block;
+	ctx->key   = key;
+
+	(*block)(ctx->H.c,ctx->H.c,key);
+
+	if (BYTE_ORDER == LITTLE_ENDIAN) {
+		/* H is stored in host byte order */
+#ifdef BSWAP8
+		ctx->H.u[0] = BSWAP8(ctx->H.u[0]);
+		ctx->H.u[1] = BSWAP8(ctx->H.u[1]);
+#else
+		u8 *p = ctx->H.c;
+		u64 hi,lo;
+		hi = (u64)GETU32(p)  <<32|GETU32(p+4);
+		lo = (u64)GETU32(p+8)<<32|GETU32(p+12);
+		ctx->H.u[0] = hi;
+		ctx->H.u[1] = lo;
+#endif
+	}
+
+#if	TABLE_BITS==8
+	gcm_init_8bit(ctx->Htable,ctx->H.u);
+#elif	TABLE_BITS==4
+# if	defined(GHASH_ASM_X86_OR_64)
+#  if	!defined(GHASH_ASM_X86) || defined(OPENSSL_IA32_SSE2)
+	if (OPENSSL_ia32cap_P[0]&(1<<24) &&	/* check FXSR bit */
+	    OPENSSL_ia32cap_P[1]&(1<<1) ) {	/* check PCLMULQDQ bit */
+		gcm_init_clmul(ctx->Htable,ctx->H.u);
+		ctx->gmult = gcm_gmult_clmul;
+		ctx->ghash = gcm_ghash_clmul;
+		return;
+	}
+#  endif
+	gcm_init_4bit(ctx->Htable,ctx->H.u);
+#  if	defined(GHASH_ASM_X86)			/* x86 only */
+#   if	defined(OPENSSL_IA32_SSE2)
+	if (OPENSSL_ia32cap_P[0]&(1<<25)) {	/* check SSE bit */
+#   else
+	if (OPENSSL_ia32cap_P[0]&(1<<23)) {	/* check MMX bit */
+#   endif
+		ctx->gmult = gcm_gmult_4bit_mmx;
+		ctx->ghash = gcm_ghash_4bit_mmx;
+	} else {
+		ctx->gmult = gcm_gmult_4bit_x86;
+		ctx->ghash = gcm_ghash_4bit_x86;
+	}
+#  else
+	ctx->gmult = gcm_gmult_4bit;
+	ctx->ghash = gcm_ghash_4bit;
+#  endif
+# elif	defined(GHASH_ASM_ARM)
+	if (OPENSSL_armcap_P & ARMV7_NEON) {
+		ctx->gmult = gcm_gmult_neon;
+		ctx->ghash = gcm_ghash_neon;
+	} else {
+		gcm_init_4bit(ctx->Htable,ctx->H.u);
+		ctx->gmult = gcm_gmult_4bit;
+		ctx->ghash = gcm_ghash_4bit;
+	}
+# else
+	gcm_init_4bit(ctx->Htable,ctx->H.u);
+# endif
+#endif
+}
+
+void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx,const unsigned char *iv,size_t len)
+{
+	unsigned int ctr;
+#ifdef GCM_FUNCREF_4BIT
+	void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16])	= ctx->gmult;
+#endif
+
+	ctx->Yi.u[0]  = 0;
+	ctx->Yi.u[1]  = 0;
+	ctx->Xi.u[0]  = 0;
+	ctx->Xi.u[1]  = 0;
+	ctx->len.u[0] = 0;	/* AAD length */
+	ctx->len.u[1] = 0;	/* message length */
+	ctx->ares = 0;
+	ctx->mres = 0;
+
+	if (len==12) {
+		memcpy(ctx->Yi.c,iv,12);
+		ctx->Yi.c[15]=1;
+		ctr=1;
+	}
+	else {
+		size_t i;
+		u64 len0 = len;
+
+		while (len>=16) {
+			for (i=0; i<16; ++i) ctx->Yi.c[i] ^= iv[i];
+			GCM_MUL(ctx,Yi);
+			iv += 16;
+			len -= 16;
+		}
+		if (len) {
+			for (i=0; iYi.c[i] ^= iv[i];
+			GCM_MUL(ctx,Yi);
+		}
+		len0 <<= 3;
+		if (BYTE_ORDER == LITTLE_ENDIAN) {
+#ifdef BSWAP8
+			ctx->Yi.u[1]  ^= BSWAP8(len0);
+#else
+			ctx->Yi.c[8]  ^= (u8)(len0>>56);
+			ctx->Yi.c[9]  ^= (u8)(len0>>48);
+			ctx->Yi.c[10] ^= (u8)(len0>>40);
+			ctx->Yi.c[11] ^= (u8)(len0>>32);
+			ctx->Yi.c[12] ^= (u8)(len0>>24);
+			ctx->Yi.c[13] ^= (u8)(len0>>16);
+			ctx->Yi.c[14] ^= (u8)(len0>>8);
+			ctx->Yi.c[15] ^= (u8)(len0);
+#endif
+		}
+		else
+			ctx->Yi.u[1]  ^= len0;
+
+		GCM_MUL(ctx,Yi);
+
+		if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+			ctr = BSWAP4(ctx->Yi.d[3]);
+#else
+			ctr = GETU32(ctx->Yi.c+12);
+#endif
+		else
+			ctr = ctx->Yi.d[3];
+	}
+
+	(*ctx->block)(ctx->Yi.c,ctx->EK0.c,ctx->key);
+	++ctr;
+	if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+		ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+		PUTU32(ctx->Yi.c+12,ctr);
+#endif
+	else
+		ctx->Yi.d[3] = ctr;
+}
+
+int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx,const unsigned char *aad,size_t len)
+{
+	size_t i;
+	unsigned int n;
+	u64 alen = ctx->len.u[0];
+#ifdef GCM_FUNCREF_4BIT
+	void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16])	= ctx->gmult;
+# ifdef GHASH
+	void (*gcm_ghash_p)(u64 Xi[2],const u128 Htable[16],
+				const u8 *inp,size_t len)	= ctx->ghash;
+# endif
+#endif
+
+	if (ctx->len.u[1]) return -2;
+
+	alen += len;
+	if (alen>(U64(1)<<61) || (sizeof(len)==8 && alenlen.u[0] = alen;
+
+	n = ctx->ares;
+	if (n) {
+		while (n && len) {
+			ctx->Xi.c[n] ^= *(aad++);
+			--len;
+			n = (n+1)%16;
+		}
+		if (n==0) GCM_MUL(ctx,Xi);
+		else {
+			ctx->ares = n;
+			return 0;
+		}
+	}
+
+#ifdef GHASH
+	if ((i = (len&(size_t)-16))) {
+		GHASH(ctx,aad,i);
+		aad += i;
+		len -= i;
+	}
+#else
+	while (len>=16) {
+		for (i=0; i<16; ++i) ctx->Xi.c[i] ^= aad[i];
+		GCM_MUL(ctx,Xi);
+		aad += 16;
+		len -= 16;
+	}
+#endif
+	if (len) {
+		n = (unsigned int)len;
+		for (i=0; iXi.c[i] ^= aad[i];
+	}
+
+	ctx->ares = n;
+	return 0;
+}
+
+int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
+		const unsigned char *in, unsigned char *out,
+		size_t len)
+{
+	unsigned int n, ctr;
+	size_t i;
+	u64        mlen  = ctx->len.u[1];
+	block128_f block = ctx->block;
+	void      *key   = ctx->key;
+#ifdef GCM_FUNCREF_4BIT
+	void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16])	= ctx->gmult;
+# ifdef GHASH
+	void (*gcm_ghash_p)(u64 Xi[2],const u128 Htable[16],
+				const u8 *inp,size_t len)	= ctx->ghash;
+# endif
+#endif
+
+	mlen += len;
+	if (mlen>((U64(1)<<36)-32) || (sizeof(len)==8 && mlenlen.u[1] = mlen;
+
+	if (ctx->ares) {
+		/* First call to encrypt finalizes GHASH(AAD) */
+		GCM_MUL(ctx,Xi);
+		ctx->ares = 0;
+	}
+
+	if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+		ctr = BSWAP4(ctx->Yi.d[3]);
+#else
+		ctr = GETU32(ctx->Yi.c+12);
+#endif
+	else
+		ctr = ctx->Yi.d[3];
+
+	n = ctx->mres;
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	if (16%sizeof(size_t) == 0) do {	/* always true actually */
+		if (n) {
+			while (n && len) {
+				ctx->Xi.c[n] ^= *(out++) = *(in++)^ctx->EKi.c[n];
+				--len;
+				n = (n+1)%16;
+			}
+			if (n==0) GCM_MUL(ctx,Xi);
+			else {
+				ctx->mres = n;
+				return 0;
+			}
+		}
+#ifdef __STRICT_ALIGNMENT
+		if (((size_t)in|(size_t)out)%sizeof(size_t) != 0)
+			break;
+#endif
+#if defined(GHASH) && defined(GHASH_CHUNK)
+		while (len>=GHASH_CHUNK) {
+		    size_t j=GHASH_CHUNK;
+
+		    while (j) {
+		    	size_t *out_t=(size_t *)out;
+		    	const size_t *in_t=(const size_t *)in;
+
+			(*block)(ctx->Yi.c,ctx->EKi.c,key);
+			++ctr;
+			if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+				ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+				PUTU32(ctx->Yi.c+12,ctr);
+#endif
+			else
+				ctx->Yi.d[3] = ctr;
+			for (i=0; i<16/sizeof(size_t); ++i)
+				out_t[i] = in_t[i] ^ ctx->EKi.t[i];
+			out += 16;
+			in  += 16;
+			j   -= 16;
+		    }
+		    GHASH(ctx,out-GHASH_CHUNK,GHASH_CHUNK);
+		    len -= GHASH_CHUNK;
+		}
+		if ((i = (len&(size_t)-16))) {
+		    size_t j=i;
+
+		    while (len>=16) {
+		    	size_t *out_t=(size_t *)out;
+		    	const size_t *in_t=(const size_t *)in;
+
+			(*block)(ctx->Yi.c,ctx->EKi.c,key);
+			++ctr;
+			if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+				ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+				PUTU32(ctx->Yi.c+12,ctr);
+#endif
+			else
+				ctx->Yi.d[3] = ctr;
+			for (i=0; i<16/sizeof(size_t); ++i)
+				out_t[i] = in_t[i] ^ ctx->EKi.t[i];
+			out += 16;
+			in  += 16;
+			len -= 16;
+		    }
+		    GHASH(ctx,out-j,j);
+		}
+#else
+		while (len>=16) {
+		    	size_t *out_t=(size_t *)out;
+		    	const size_t *in_t=(const size_t *)in;
+
+			(*block)(ctx->Yi.c,ctx->EKi.c,key);
+			++ctr;
+			if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+				ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+				PUTU32(ctx->Yi.c+12,ctr);
+#endif
+			else
+				ctx->Yi.d[3] = ctr;
+			for (i=0; i<16/sizeof(size_t); ++i)
+				ctx->Xi.t[i] ^=
+				out_t[i] = in_t[i]^ctx->EKi.t[i];
+			GCM_MUL(ctx,Xi);
+			out += 16;
+			in  += 16;
+			len -= 16;
+		}
+#endif
+		if (len) {
+			(*block)(ctx->Yi.c,ctx->EKi.c,key);
+			++ctr;
+			if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+				ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+				PUTU32(ctx->Yi.c+12,ctr);
+#endif
+			else
+				ctx->Yi.d[3] = ctr;
+			while (len--) {
+				ctx->Xi.c[n] ^= out[n] = in[n]^ctx->EKi.c[n];
+				++n;
+			}
+		}
+
+		ctx->mres = n;
+		return 0;
+	} while(0);
+#endif
+	for (i=0;iYi.c,ctx->EKi.c,key);
+			++ctr;
+			if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+				ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+				PUTU32(ctx->Yi.c+12,ctr);
+#endif
+			else
+				ctx->Yi.d[3] = ctr;
+		}
+		ctx->Xi.c[n] ^= out[i] = in[i]^ctx->EKi.c[n];
+		n = (n+1)%16;
+		if (n==0)
+			GCM_MUL(ctx,Xi);
+	}
+
+	ctx->mres = n;
+	return 0;
+}
+
+int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
+		const unsigned char *in, unsigned char *out,
+		size_t len)
+{
+	unsigned int n, ctr;
+	size_t i;
+	u64        mlen  = ctx->len.u[1];
+	block128_f block = ctx->block;
+	void      *key   = ctx->key;
+#ifdef GCM_FUNCREF_4BIT
+	void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16])	= ctx->gmult;
+# ifdef GHASH
+	void (*gcm_ghash_p)(u64 Xi[2],const u128 Htable[16],
+				const u8 *inp,size_t len)	= ctx->ghash;
+# endif
+#endif
+
+	mlen += len;
+	if (mlen>((U64(1)<<36)-32) || (sizeof(len)==8 && mlenlen.u[1] = mlen;
+
+	if (ctx->ares) {
+		/* First call to decrypt finalizes GHASH(AAD) */
+		GCM_MUL(ctx,Xi);
+		ctx->ares = 0;
+	}
+
+	if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+		ctr = BSWAP4(ctx->Yi.d[3]);
+#else
+		ctr = GETU32(ctx->Yi.c+12);
+#endif
+	else
+		ctr = ctx->Yi.d[3];
+
+	n = ctx->mres;
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	if (16%sizeof(size_t) == 0) do {	/* always true actually */
+		if (n) {
+			while (n && len) {
+				u8 c = *(in++);
+				*(out++) = c^ctx->EKi.c[n];
+				ctx->Xi.c[n] ^= c;
+				--len;
+				n = (n+1)%16;
+			}
+			if (n==0) GCM_MUL (ctx,Xi);
+			else {
+				ctx->mres = n;
+				return 0;
+			}
+		}
+#ifdef __STRICT_ALIGNMENT
+		if (((size_t)in|(size_t)out)%sizeof(size_t) != 0)
+			break;
+#endif
+#if defined(GHASH) && defined(GHASH_CHUNK)
+		while (len>=GHASH_CHUNK) {
+		    size_t j=GHASH_CHUNK;
+
+		    GHASH(ctx,in,GHASH_CHUNK);
+		    while (j) {
+		    	size_t *out_t=(size_t *)out;
+		    	const size_t *in_t=(const size_t *)in;
+
+			(*block)(ctx->Yi.c,ctx->EKi.c,key);
+			++ctr;
+			if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+				ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+				PUTU32(ctx->Yi.c+12,ctr);
+#endif
+			else
+				ctx->Yi.d[3] = ctr;
+			for (i=0; i<16/sizeof(size_t); ++i)
+				out_t[i] = in_t[i]^ctx->EKi.t[i];
+			out += 16;
+			in  += 16;
+			j   -= 16;
+		    }
+		    len -= GHASH_CHUNK;
+		}
+		if ((i = (len&(size_t)-16))) {
+		    GHASH(ctx,in,i);
+		    while (len>=16) {
+		    	size_t *out_t=(size_t *)out;
+		    	const size_t *in_t=(const size_t *)in;
+
+			(*block)(ctx->Yi.c,ctx->EKi.c,key);
+			++ctr;
+			if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+				ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+				PUTU32(ctx->Yi.c+12,ctr);
+#endif
+			else
+				ctx->Yi.d[3] = ctr;
+			for (i=0; i<16/sizeof(size_t); ++i)
+				out_t[i] = in_t[i]^ctx->EKi.t[i];
+			out += 16;
+			in  += 16;
+			len -= 16;
+		    }
+		}
+#else
+		while (len>=16) {
+		    	size_t *out_t=(size_t *)out;
+		    	const size_t *in_t=(const size_t *)in;
+
+			(*block)(ctx->Yi.c,ctx->EKi.c,key);
+			++ctr;
+			if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+				ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+				PUTU32(ctx->Yi.c+12,ctr);
+#endif
+			else
+				ctx->Yi.d[3] = ctr;
+			for (i=0; i<16/sizeof(size_t); ++i) {
+				size_t c = in[i];
+				out[i] = c^ctx->EKi.t[i];
+				ctx->Xi.t[i] ^= c;
+			}
+			GCM_MUL(ctx,Xi);
+			out += 16;
+			in  += 16;
+			len -= 16;
+		}
+#endif
+		if (len) {
+			(*block)(ctx->Yi.c,ctx->EKi.c,key);
+			++ctr;
+			if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+				ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+				PUTU32(ctx->Yi.c+12,ctr);
+#endif
+			else
+				ctx->Yi.d[3] = ctr;
+			while (len--) {
+				u8 c = in[n];
+				ctx->Xi.c[n] ^= c;
+				out[n] = c^ctx->EKi.c[n];
+				++n;
+			}
+		}
+
+		ctx->mres = n;
+		return 0;
+	} while(0);
+#endif
+	for (i=0;iYi.c,ctx->EKi.c,key);
+			++ctr;
+			if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+				ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+				PUTU32(ctx->Yi.c+12,ctr);
+#endif
+			else
+				ctx->Yi.d[3] = ctr;
+		}
+		c = in[i];
+		out[i] = c^ctx->EKi.c[n];
+		ctx->Xi.c[n] ^= c;
+		n = (n+1)%16;
+		if (n==0)
+			GCM_MUL(ctx,Xi);
+	}
+
+	ctx->mres = n;
+	return 0;
+}
+
+int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
+		const unsigned char *in, unsigned char *out,
+		size_t len, ctr128_f stream)
+{
+	unsigned int n, ctr;
+	size_t i;
+	u64   mlen = ctx->len.u[1];
+	void *key  = ctx->key;
+#ifdef GCM_FUNCREF_4BIT
+	void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16])	= ctx->gmult;
+# ifdef GHASH
+	void (*gcm_ghash_p)(u64 Xi[2],const u128 Htable[16],
+				const u8 *inp,size_t len)	= ctx->ghash;
+# endif
+#endif
+
+	mlen += len;
+	if (mlen>((U64(1)<<36)-32) || (sizeof(len)==8 && mlenlen.u[1] = mlen;
+
+	if (ctx->ares) {
+		/* First call to encrypt finalizes GHASH(AAD) */
+		GCM_MUL(ctx,Xi);
+		ctx->ares = 0;
+	}
+
+	if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+		ctr = BSWAP4(ctx->Yi.d[3]);
+#else
+		ctr = GETU32(ctx->Yi.c+12);
+#endif
+	else
+		ctr = ctx->Yi.d[3];
+
+	n = ctx->mres;
+	if (n) {
+		while (n && len) {
+			ctx->Xi.c[n] ^= *(out++) = *(in++)^ctx->EKi.c[n];
+			--len;
+			n = (n+1)%16;
+		}
+		if (n==0) GCM_MUL(ctx,Xi);
+		else {
+			ctx->mres = n;
+			return 0;
+		}
+	}
+#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)
+	while (len>=GHASH_CHUNK) {
+		(*stream)(in,out,GHASH_CHUNK/16,key,ctx->Yi.c);
+		ctr += GHASH_CHUNK/16;
+		if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+			ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+			PUTU32(ctx->Yi.c+12,ctr);
+#endif
+		else
+			ctx->Yi.d[3] = ctr;
+		GHASH(ctx,out,GHASH_CHUNK);
+		out += GHASH_CHUNK;
+		in  += GHASH_CHUNK;
+		len -= GHASH_CHUNK;
+	}
+#endif
+	if ((i = (len&(size_t)-16))) {
+		size_t j=i/16;
+
+		(*stream)(in,out,j,key,ctx->Yi.c);
+		ctr += (unsigned int)j;
+		if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+			ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+			PUTU32(ctx->Yi.c+12,ctr);
+#endif
+		else
+			ctx->Yi.d[3] = ctr;
+		in  += i;
+		len -= i;
+#if defined(GHASH)
+		GHASH(ctx,out,i);
+		out += i;
+#else
+		while (j--) {
+			for (i=0;i<16;++i) ctx->Xi.c[i] ^= out[i];
+			GCM_MUL(ctx,Xi);
+			out += 16;
+		}
+#endif
+	}
+	if (len) {
+		(*ctx->block)(ctx->Yi.c,ctx->EKi.c,key);
+		++ctr;
+		if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+			ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+			PUTU32(ctx->Yi.c+12,ctr);
+#endif
+		else
+			ctx->Yi.d[3] = ctr;
+		while (len--) {
+			ctx->Xi.c[n] ^= out[n] = in[n]^ctx->EKi.c[n];
+			++n;
+		}
+	}
+
+	ctx->mres = n;
+	return 0;
+}
+
+int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
+		const unsigned char *in, unsigned char *out,
+		size_t len,ctr128_f stream)
+{
+	unsigned int n, ctr;
+	size_t i;
+	u64   mlen = ctx->len.u[1];
+	void *key  = ctx->key;
+#ifdef GCM_FUNCREF_4BIT
+	void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16])	= ctx->gmult;
+# ifdef GHASH
+	void (*gcm_ghash_p)(u64 Xi[2],const u128 Htable[16],
+				const u8 *inp,size_t len)	= ctx->ghash;
+# endif
+#endif
+
+	mlen += len;
+	if (mlen>((U64(1)<<36)-32) || (sizeof(len)==8 && mlenlen.u[1] = mlen;
+
+	if (ctx->ares) {
+		/* First call to decrypt finalizes GHASH(AAD) */
+		GCM_MUL(ctx,Xi);
+		ctx->ares = 0;
+	}
+
+	if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+		ctr = BSWAP4(ctx->Yi.d[3]);
+#else
+		ctr = GETU32(ctx->Yi.c+12);
+#endif
+	else
+		ctr = ctx->Yi.d[3];
+
+	n = ctx->mres;
+	if (n) {
+		while (n && len) {
+			u8 c = *(in++);
+			*(out++) = c^ctx->EKi.c[n];
+			ctx->Xi.c[n] ^= c;
+			--len;
+			n = (n+1)%16;
+		}
+		if (n==0) GCM_MUL (ctx,Xi);
+		else {
+			ctx->mres = n;
+			return 0;
+		}
+	}
+#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)
+	while (len>=GHASH_CHUNK) {
+		GHASH(ctx,in,GHASH_CHUNK);
+		(*stream)(in,out,GHASH_CHUNK/16,key,ctx->Yi.c);
+		ctr += GHASH_CHUNK/16;
+		if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+			ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+			PUTU32(ctx->Yi.c+12,ctr);
+#endif
+		else
+			ctx->Yi.d[3] = ctr;
+		out += GHASH_CHUNK;
+		in  += GHASH_CHUNK;
+		len -= GHASH_CHUNK;
+	}
+#endif
+	if ((i = (len&(size_t)-16))) {
+		size_t j=i/16;
+
+#if defined(GHASH)
+		GHASH(ctx,in,i);
+#else
+		while (j--) {
+			size_t k;
+			for (k=0;k<16;++k) ctx->Xi.c[k] ^= in[k];
+			GCM_MUL(ctx,Xi);
+			in += 16;
+		}
+		j   = i/16;
+		in -= i;
+#endif
+		(*stream)(in,out,j,key,ctx->Yi.c);
+		ctr += (unsigned int)j;
+		if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+			ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+			PUTU32(ctx->Yi.c+12,ctr);
+#endif
+		else
+			ctx->Yi.d[3] = ctr;
+		out += i;
+		in  += i;
+		len -= i;
+	}
+	if (len) {
+		(*ctx->block)(ctx->Yi.c,ctx->EKi.c,key);
+		++ctr;
+		if (BYTE_ORDER == LITTLE_ENDIAN)
+#ifdef BSWAP4
+			ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+			PUTU32(ctx->Yi.c+12,ctr);
+#endif
+		else
+			ctx->Yi.d[3] = ctr;
+		while (len--) {
+			u8 c = in[n];
+			ctx->Xi.c[n] ^= c;
+			out[n] = c^ctx->EKi.c[n];
+			++n;
+		}
+	}
+
+	ctx->mres = n;
+	return 0;
+}
+
+int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx,const unsigned char *tag,
+			size_t len)
+{
+	u64 alen = ctx->len.u[0]<<3;
+	u64 clen = ctx->len.u[1]<<3;
+#ifdef GCM_FUNCREF_4BIT
+	void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16])	= ctx->gmult;
+#endif
+
+	if (ctx->mres || ctx->ares)
+		GCM_MUL(ctx,Xi);
+
+	if (BYTE_ORDER == LITTLE_ENDIAN) {
+#ifdef BSWAP8
+		alen = BSWAP8(alen);
+		clen = BSWAP8(clen);
+#else
+		u8 *p = ctx->len.c;
+
+		ctx->len.u[0] = alen;
+		ctx->len.u[1] = clen;
+
+		alen = (u64)GETU32(p)  <<32|GETU32(p+4);
+		clen = (u64)GETU32(p+8)<<32|GETU32(p+12);
+#endif
+	}
+
+	ctx->Xi.u[0] ^= alen;
+	ctx->Xi.u[1] ^= clen;
+	GCM_MUL(ctx,Xi);
+
+	ctx->Xi.u[0] ^= ctx->EK0.u[0];
+	ctx->Xi.u[1] ^= ctx->EK0.u[1];
+
+	if (tag && len<=sizeof(ctx->Xi))
+		return memcmp(ctx->Xi.c,tag,len);
+	else
+		return -1;
+}
+
+void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len)
+{
+	CRYPTO_gcm128_finish(ctx, NULL, 0);
+	memcpy(tag, ctx->Xi.c, len<=sizeof(ctx->Xi.c)?len:sizeof(ctx->Xi.c));
+}
+
+GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block)
+{
+	GCM128_CONTEXT *ret;
+
+	if ((ret = malloc(sizeof(GCM128_CONTEXT))))
+		CRYPTO_gcm128_init(ret,key,block);
+
+	return ret;
+}
+
+void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx)
+{
+	if (ctx) {
+		explicit_bzero(ctx,sizeof(*ctx));
+		free(ctx);
+	}
+}
diff --git a/crypto/libressl/crypto/modes/ghash-elf-x86_64.s b/crypto/libressl/crypto/modes/ghash-elf-x86_64.s
new file mode 100644
index 0000000000..1a97cae26f
--- /dev/null
+++ b/crypto/libressl/crypto/modes/ghash-elf-x86_64.s
@@ -0,0 +1,1029 @@
+.text	
+
+.globl	gcm_gmult_4bit
+.type	gcm_gmult_4bit,@function
+.align	16
+gcm_gmult_4bit:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+.Lgmult_prologue:
+
+	movzbq	15(%rdi),%r8
+	leaq	.Lrem_4bit(%rip),%r11
+	xorq	%rax,%rax
+	xorq	%rbx,%rbx
+	movb	%r8b,%al
+	movb	%r8b,%bl
+	shlb	$4,%al
+	movq	$14,%rcx
+	movq	8(%rsi,%rax,1),%r8
+	movq	(%rsi,%rax,1),%r9
+	andb	$240,%bl
+	movq	%r8,%rdx
+	jmp	.Loop1
+
+.align	16
+.Loop1:
+	shrq	$4,%r8
+	andq	$15,%rdx
+	movq	%r9,%r10
+	movb	(%rdi,%rcx,1),%al
+	shrq	$4,%r9
+	xorq	8(%rsi,%rbx,1),%r8
+	shlq	$60,%r10
+	xorq	(%rsi,%rbx,1),%r9
+	movb	%al,%bl
+	xorq	(%r11,%rdx,8),%r9
+	movq	%r8,%rdx
+	shlb	$4,%al
+	xorq	%r10,%r8
+	decq	%rcx
+	js	.Lbreak1
+
+	shrq	$4,%r8
+	andq	$15,%rdx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	xorq	8(%rsi,%rax,1),%r8
+	shlq	$60,%r10
+	xorq	(%rsi,%rax,1),%r9
+	andb	$240,%bl
+	xorq	(%r11,%rdx,8),%r9
+	movq	%r8,%rdx
+	xorq	%r10,%r8
+	jmp	.Loop1
+
+.align	16
+.Lbreak1:
+	shrq	$4,%r8
+	andq	$15,%rdx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	xorq	8(%rsi,%rax,1),%r8
+	shlq	$60,%r10
+	xorq	(%rsi,%rax,1),%r9
+	andb	$240,%bl
+	xorq	(%r11,%rdx,8),%r9
+	movq	%r8,%rdx
+	xorq	%r10,%r8
+
+	shrq	$4,%r8
+	andq	$15,%rdx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	xorq	8(%rsi,%rbx,1),%r8
+	shlq	$60,%r10
+	xorq	(%rsi,%rbx,1),%r9
+	xorq	%r10,%r8
+	xorq	(%r11,%rdx,8),%r9
+
+	bswapq	%r8
+	bswapq	%r9
+	movq	%r8,8(%rdi)
+	movq	%r9,(%rdi)
+
+	movq	16(%rsp),%rbx
+	leaq	24(%rsp),%rsp
+.Lgmult_epilogue:
+	.byte	0xf3,0xc3
+.size	gcm_gmult_4bit,.-gcm_gmult_4bit
+.globl	gcm_ghash_4bit
+.type	gcm_ghash_4bit,@function
+.align	16
+gcm_ghash_4bit:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	subq	$280,%rsp
+.Lghash_prologue:
+	movq	%rdx,%r14
+	movq	%rcx,%r15
+	subq	$-128,%rsi
+	leaq	16+128(%rsp),%rbp
+	xorl	%edx,%edx
+	movq	0+0-128(%rsi),%r8
+	movq	0+8-128(%rsi),%rax
+	movb	%al,%dl
+	shrq	$4,%rax
+	movq	%r8,%r10
+	shrq	$4,%r8
+	movq	16+0-128(%rsi),%r9
+	shlb	$4,%dl
+	movq	16+8-128(%rsi),%rbx
+	shlq	$60,%r10
+	movb	%dl,0(%rsp)
+	orq	%r10,%rax
+	movb	%bl,%dl
+	shrq	$4,%rbx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	movq	%r8,0(%rbp)
+	movq	32+0-128(%rsi),%r8
+	shlb	$4,%dl
+	movq	%rax,0-128(%rbp)
+	movq	32+8-128(%rsi),%rax
+	shlq	$60,%r10
+	movb	%dl,1(%rsp)
+	orq	%r10,%rbx
+	movb	%al,%dl
+	shrq	$4,%rax
+	movq	%r8,%r10
+	shrq	$4,%r8
+	movq	%r9,8(%rbp)
+	movq	48+0-128(%rsi),%r9
+	shlb	$4,%dl
+	movq	%rbx,8-128(%rbp)
+	movq	48+8-128(%rsi),%rbx
+	shlq	$60,%r10
+	movb	%dl,2(%rsp)
+	orq	%r10,%rax
+	movb	%bl,%dl
+	shrq	$4,%rbx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	movq	%r8,16(%rbp)
+	movq	64+0-128(%rsi),%r8
+	shlb	$4,%dl
+	movq	%rax,16-128(%rbp)
+	movq	64+8-128(%rsi),%rax
+	shlq	$60,%r10
+	movb	%dl,3(%rsp)
+	orq	%r10,%rbx
+	movb	%al,%dl
+	shrq	$4,%rax
+	movq	%r8,%r10
+	shrq	$4,%r8
+	movq	%r9,24(%rbp)
+	movq	80+0-128(%rsi),%r9
+	shlb	$4,%dl
+	movq	%rbx,24-128(%rbp)
+	movq	80+8-128(%rsi),%rbx
+	shlq	$60,%r10
+	movb	%dl,4(%rsp)
+	orq	%r10,%rax
+	movb	%bl,%dl
+	shrq	$4,%rbx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	movq	%r8,32(%rbp)
+	movq	96+0-128(%rsi),%r8
+	shlb	$4,%dl
+	movq	%rax,32-128(%rbp)
+	movq	96+8-128(%rsi),%rax
+	shlq	$60,%r10
+	movb	%dl,5(%rsp)
+	orq	%r10,%rbx
+	movb	%al,%dl
+	shrq	$4,%rax
+	movq	%r8,%r10
+	shrq	$4,%r8
+	movq	%r9,40(%rbp)
+	movq	112+0-128(%rsi),%r9
+	shlb	$4,%dl
+	movq	%rbx,40-128(%rbp)
+	movq	112+8-128(%rsi),%rbx
+	shlq	$60,%r10
+	movb	%dl,6(%rsp)
+	orq	%r10,%rax
+	movb	%bl,%dl
+	shrq	$4,%rbx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	movq	%r8,48(%rbp)
+	movq	128+0-128(%rsi),%r8
+	shlb	$4,%dl
+	movq	%rax,48-128(%rbp)
+	movq	128+8-128(%rsi),%rax
+	shlq	$60,%r10
+	movb	%dl,7(%rsp)
+	orq	%r10,%rbx
+	movb	%al,%dl
+	shrq	$4,%rax
+	movq	%r8,%r10
+	shrq	$4,%r8
+	movq	%r9,56(%rbp)
+	movq	144+0-128(%rsi),%r9
+	shlb	$4,%dl
+	movq	%rbx,56-128(%rbp)
+	movq	144+8-128(%rsi),%rbx
+	shlq	$60,%r10
+	movb	%dl,8(%rsp)
+	orq	%r10,%rax
+	movb	%bl,%dl
+	shrq	$4,%rbx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	movq	%r8,64(%rbp)
+	movq	160+0-128(%rsi),%r8
+	shlb	$4,%dl
+	movq	%rax,64-128(%rbp)
+	movq	160+8-128(%rsi),%rax
+	shlq	$60,%r10
+	movb	%dl,9(%rsp)
+	orq	%r10,%rbx
+	movb	%al,%dl
+	shrq	$4,%rax
+	movq	%r8,%r10
+	shrq	$4,%r8
+	movq	%r9,72(%rbp)
+	movq	176+0-128(%rsi),%r9
+	shlb	$4,%dl
+	movq	%rbx,72-128(%rbp)
+	movq	176+8-128(%rsi),%rbx
+	shlq	$60,%r10
+	movb	%dl,10(%rsp)
+	orq	%r10,%rax
+	movb	%bl,%dl
+	shrq	$4,%rbx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	movq	%r8,80(%rbp)
+	movq	192+0-128(%rsi),%r8
+	shlb	$4,%dl
+	movq	%rax,80-128(%rbp)
+	movq	192+8-128(%rsi),%rax
+	shlq	$60,%r10
+	movb	%dl,11(%rsp)
+	orq	%r10,%rbx
+	movb	%al,%dl
+	shrq	$4,%rax
+	movq	%r8,%r10
+	shrq	$4,%r8
+	movq	%r9,88(%rbp)
+	movq	208+0-128(%rsi),%r9
+	shlb	$4,%dl
+	movq	%rbx,88-128(%rbp)
+	movq	208+8-128(%rsi),%rbx
+	shlq	$60,%r10
+	movb	%dl,12(%rsp)
+	orq	%r10,%rax
+	movb	%bl,%dl
+	shrq	$4,%rbx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	movq	%r8,96(%rbp)
+	movq	224+0-128(%rsi),%r8
+	shlb	$4,%dl
+	movq	%rax,96-128(%rbp)
+	movq	224+8-128(%rsi),%rax
+	shlq	$60,%r10
+	movb	%dl,13(%rsp)
+	orq	%r10,%rbx
+	movb	%al,%dl
+	shrq	$4,%rax
+	movq	%r8,%r10
+	shrq	$4,%r8
+	movq	%r9,104(%rbp)
+	movq	240+0-128(%rsi),%r9
+	shlb	$4,%dl
+	movq	%rbx,104-128(%rbp)
+	movq	240+8-128(%rsi),%rbx
+	shlq	$60,%r10
+	movb	%dl,14(%rsp)
+	orq	%r10,%rax
+	movb	%bl,%dl
+	shrq	$4,%rbx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	movq	%r8,112(%rbp)
+	shlb	$4,%dl
+	movq	%rax,112-128(%rbp)
+	shlq	$60,%r10
+	movb	%dl,15(%rsp)
+	orq	%r10,%rbx
+	movq	%r9,120(%rbp)
+	movq	%rbx,120-128(%rbp)
+	addq	$-128,%rsi
+	movq	8(%rdi),%r8
+	movq	0(%rdi),%r9
+	addq	%r14,%r15
+	leaq	.Lrem_8bit(%rip),%r11
+	jmp	.Louter_loop
+.align	16
+.Louter_loop:
+	xorq	(%r14),%r9
+	movq	8(%r14),%rdx
+	leaq	16(%r14),%r14
+	xorq	%r8,%rdx
+	movq	%r9,(%rdi)
+	movq	%rdx,8(%rdi)
+	shrq	$32,%rdx
+	xorq	%rax,%rax
+	roll	$8,%edx
+	movb	%dl,%al
+	movzbl	%dl,%ebx
+	shlb	$4,%al
+	shrl	$4,%ebx
+	roll	$8,%edx
+	movq	8(%rsi,%rax,1),%r8
+	movq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	movzbl	%dl,%ecx
+	shlb	$4,%al
+	movzbq	(%rsp,%rbx,1),%r12
+	shrl	$4,%ecx
+	xorq	%r8,%r12
+	movq	%r9,%r10
+	shrq	$8,%r8
+	movzbq	%r12b,%r12
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rbx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rbx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r12,2),%r12
+	movzbl	%dl,%ebx
+	shlb	$4,%al
+	movzbq	(%rsp,%rcx,1),%r13
+	shrl	$4,%ebx
+	shlq	$48,%r12
+	xorq	%r8,%r13
+	movq	%r9,%r10
+	xorq	%r12,%r9
+	shrq	$8,%r8
+	movzbq	%r13b,%r13
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rcx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rcx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r13,2),%r13
+	movzbl	%dl,%ecx
+	shlb	$4,%al
+	movzbq	(%rsp,%rbx,1),%r12
+	shrl	$4,%ecx
+	shlq	$48,%r13
+	xorq	%r8,%r12
+	movq	%r9,%r10
+	xorq	%r13,%r9
+	shrq	$8,%r8
+	movzbq	%r12b,%r12
+	movl	8(%rdi),%edx
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rbx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rbx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r12,2),%r12
+	movzbl	%dl,%ebx
+	shlb	$4,%al
+	movzbq	(%rsp,%rcx,1),%r13
+	shrl	$4,%ebx
+	shlq	$48,%r12
+	xorq	%r8,%r13
+	movq	%r9,%r10
+	xorq	%r12,%r9
+	shrq	$8,%r8
+	movzbq	%r13b,%r13
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rcx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rcx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r13,2),%r13
+	movzbl	%dl,%ecx
+	shlb	$4,%al
+	movzbq	(%rsp,%rbx,1),%r12
+	shrl	$4,%ecx
+	shlq	$48,%r13
+	xorq	%r8,%r12
+	movq	%r9,%r10
+	xorq	%r13,%r9
+	shrq	$8,%r8
+	movzbq	%r12b,%r12
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rbx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rbx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r12,2),%r12
+	movzbl	%dl,%ebx
+	shlb	$4,%al
+	movzbq	(%rsp,%rcx,1),%r13
+	shrl	$4,%ebx
+	shlq	$48,%r12
+	xorq	%r8,%r13
+	movq	%r9,%r10
+	xorq	%r12,%r9
+	shrq	$8,%r8
+	movzbq	%r13b,%r13
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rcx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rcx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r13,2),%r13
+	movzbl	%dl,%ecx
+	shlb	$4,%al
+	movzbq	(%rsp,%rbx,1),%r12
+	shrl	$4,%ecx
+	shlq	$48,%r13
+	xorq	%r8,%r12
+	movq	%r9,%r10
+	xorq	%r13,%r9
+	shrq	$8,%r8
+	movzbq	%r12b,%r12
+	movl	4(%rdi),%edx
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rbx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rbx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r12,2),%r12
+	movzbl	%dl,%ebx
+	shlb	$4,%al
+	movzbq	(%rsp,%rcx,1),%r13
+	shrl	$4,%ebx
+	shlq	$48,%r12
+	xorq	%r8,%r13
+	movq	%r9,%r10
+	xorq	%r12,%r9
+	shrq	$8,%r8
+	movzbq	%r13b,%r13
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rcx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rcx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r13,2),%r13
+	movzbl	%dl,%ecx
+	shlb	$4,%al
+	movzbq	(%rsp,%rbx,1),%r12
+	shrl	$4,%ecx
+	shlq	$48,%r13
+	xorq	%r8,%r12
+	movq	%r9,%r10
+	xorq	%r13,%r9
+	shrq	$8,%r8
+	movzbq	%r12b,%r12
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rbx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rbx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r12,2),%r12
+	movzbl	%dl,%ebx
+	shlb	$4,%al
+	movzbq	(%rsp,%rcx,1),%r13
+	shrl	$4,%ebx
+	shlq	$48,%r12
+	xorq	%r8,%r13
+	movq	%r9,%r10
+	xorq	%r12,%r9
+	shrq	$8,%r8
+	movzbq	%r13b,%r13
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rcx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rcx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r13,2),%r13
+	movzbl	%dl,%ecx
+	shlb	$4,%al
+	movzbq	(%rsp,%rbx,1),%r12
+	shrl	$4,%ecx
+	shlq	$48,%r13
+	xorq	%r8,%r12
+	movq	%r9,%r10
+	xorq	%r13,%r9
+	shrq	$8,%r8
+	movzbq	%r12b,%r12
+	movl	0(%rdi),%edx
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rbx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rbx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r12,2),%r12
+	movzbl	%dl,%ebx
+	shlb	$4,%al
+	movzbq	(%rsp,%rcx,1),%r13
+	shrl	$4,%ebx
+	shlq	$48,%r12
+	xorq	%r8,%r13
+	movq	%r9,%r10
+	xorq	%r12,%r9
+	shrq	$8,%r8
+	movzbq	%r13b,%r13
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rcx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rcx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r13,2),%r13
+	movzbl	%dl,%ecx
+	shlb	$4,%al
+	movzbq	(%rsp,%rbx,1),%r12
+	shrl	$4,%ecx
+	shlq	$48,%r13
+	xorq	%r8,%r12
+	movq	%r9,%r10
+	xorq	%r13,%r9
+	shrq	$8,%r8
+	movzbq	%r12b,%r12
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rbx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rbx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r12,2),%r12
+	movzbl	%dl,%ebx
+	shlb	$4,%al
+	movzbq	(%rsp,%rcx,1),%r13
+	shrl	$4,%ebx
+	shlq	$48,%r12
+	xorq	%r8,%r13
+	movq	%r9,%r10
+	xorq	%r12,%r9
+	shrq	$8,%r8
+	movzbq	%r13b,%r13
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rcx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rcx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r13,2),%r13
+	movzbl	%dl,%ecx
+	shlb	$4,%al
+	movzbq	(%rsp,%rbx,1),%r12
+	andl	$240,%ecx
+	shlq	$48,%r13
+	xorq	%r8,%r12
+	movq	%r9,%r10
+	xorq	%r13,%r9
+	shrq	$8,%r8
+	movzbq	%r12b,%r12
+	movl	-4(%rdi),%edx
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rbx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rbx,8),%r9
+	movzwq	(%r11,%r12,2),%r12
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	shlq	$48,%r12
+	xorq	%r10,%r8
+	xorq	%r12,%r9
+	movzbq	%r8b,%r13
+	shrq	$4,%r8
+	movq	%r9,%r10
+	shlb	$4,%r13b
+	shrq	$4,%r9
+	xorq	8(%rsi,%rcx,1),%r8
+	movzwq	(%r11,%r13,2),%r13
+	shlq	$60,%r10
+	xorq	(%rsi,%rcx,1),%r9
+	xorq	%r10,%r8
+	shlq	$48,%r13
+	bswapq	%r8
+	xorq	%r13,%r9
+	bswapq	%r9
+	cmpq	%r15,%r14
+	jb	.Louter_loop
+	movq	%r8,8(%rdi)
+	movq	%r9,(%rdi)
+
+	leaq	280(%rsp),%rsi
+	movq	0(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+.Lghash_epilogue:
+	.byte	0xf3,0xc3
+.size	gcm_ghash_4bit,.-gcm_ghash_4bit
+.globl	gcm_init_clmul
+.type	gcm_init_clmul,@function
+.align	16
+gcm_init_clmul:
+	movdqu	(%rsi),%xmm2
+	pshufd	$78,%xmm2,%xmm2
+
+
+	pshufd	$255,%xmm2,%xmm4
+	movdqa	%xmm2,%xmm3
+	psllq	$1,%xmm2
+	pxor	%xmm5,%xmm5
+	psrlq	$63,%xmm3
+	pcmpgtd	%xmm4,%xmm5
+	pslldq	$8,%xmm3
+	por	%xmm3,%xmm2
+
+
+	pand	.L0x1c2_polynomial(%rip),%xmm5
+	pxor	%xmm5,%xmm2
+
+
+	movdqa	%xmm2,%xmm0
+	movdqa	%xmm0,%xmm1
+	pshufd	$78,%xmm0,%xmm3
+	pshufd	$78,%xmm2,%xmm4
+	pxor	%xmm0,%xmm3
+	pxor	%xmm2,%xmm4
+.byte	102,15,58,68,194,0
+.byte	102,15,58,68,202,17
+.byte	102,15,58,68,220,0
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
+
+	movdqa	%xmm3,%xmm4
+	psrldq	$8,%xmm3
+	pslldq	$8,%xmm4
+	pxor	%xmm3,%xmm1
+	pxor	%xmm4,%xmm0
+
+	movdqa	%xmm0,%xmm3
+	psllq	$1,%xmm0
+	pxor	%xmm3,%xmm0
+	psllq	$5,%xmm0
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm4
+	pslldq	$8,%xmm0
+	psrldq	$8,%xmm4
+	pxor	%xmm3,%xmm0
+	pxor	%xmm4,%xmm1
+
+
+	movdqa	%xmm0,%xmm4
+	psrlq	$5,%xmm0
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm4,%xmm0
+	pxor	%xmm1,%xmm4
+	psrlq	$1,%xmm0
+	pxor	%xmm4,%xmm0
+	movdqu	%xmm2,(%rdi)
+	movdqu	%xmm0,16(%rdi)
+	.byte	0xf3,0xc3
+.size	gcm_init_clmul,.-gcm_init_clmul
+.globl	gcm_gmult_clmul
+.type	gcm_gmult_clmul,@function
+.align	16
+gcm_gmult_clmul:
+	movdqu	(%rdi),%xmm0
+	movdqa	.Lbswap_mask(%rip),%xmm5
+	movdqu	(%rsi),%xmm2
+.byte	102,15,56,0,197
+	movdqa	%xmm0,%xmm1
+	pshufd	$78,%xmm0,%xmm3
+	pshufd	$78,%xmm2,%xmm4
+	pxor	%xmm0,%xmm3
+	pxor	%xmm2,%xmm4
+.byte	102,15,58,68,194,0
+.byte	102,15,58,68,202,17
+.byte	102,15,58,68,220,0
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
+
+	movdqa	%xmm3,%xmm4
+	psrldq	$8,%xmm3
+	pslldq	$8,%xmm4
+	pxor	%xmm3,%xmm1
+	pxor	%xmm4,%xmm0
+
+	movdqa	%xmm0,%xmm3
+	psllq	$1,%xmm0
+	pxor	%xmm3,%xmm0
+	psllq	$5,%xmm0
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm4
+	pslldq	$8,%xmm0
+	psrldq	$8,%xmm4
+	pxor	%xmm3,%xmm0
+	pxor	%xmm4,%xmm1
+
+
+	movdqa	%xmm0,%xmm4
+	psrlq	$5,%xmm0
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm4,%xmm0
+	pxor	%xmm1,%xmm4
+	psrlq	$1,%xmm0
+	pxor	%xmm4,%xmm0
+.byte	102,15,56,0,197
+	movdqu	%xmm0,(%rdi)
+	.byte	0xf3,0xc3
+.size	gcm_gmult_clmul,.-gcm_gmult_clmul
+.globl	gcm_ghash_clmul
+.type	gcm_ghash_clmul,@function
+.align	16
+gcm_ghash_clmul:
+	movdqa	.Lbswap_mask(%rip),%xmm5
+
+	movdqu	(%rdi),%xmm0
+	movdqu	(%rsi),%xmm2
+.byte	102,15,56,0,197
+
+	subq	$16,%rcx
+	jz	.Lodd_tail
+
+	movdqu	16(%rsi),%xmm8
+
+
+
+
+
+	movdqu	(%rdx),%xmm3
+	movdqu	16(%rdx),%xmm6
+.byte	102,15,56,0,221
+.byte	102,15,56,0,245
+	pxor	%xmm3,%xmm0
+	movdqa	%xmm6,%xmm7
+	pshufd	$78,%xmm6,%xmm3
+	pshufd	$78,%xmm2,%xmm4
+	pxor	%xmm6,%xmm3
+	pxor	%xmm2,%xmm4
+.byte	102,15,58,68,242,0
+.byte	102,15,58,68,250,17
+.byte	102,15,58,68,220,0
+	pxor	%xmm6,%xmm3
+	pxor	%xmm7,%xmm3
+
+	movdqa	%xmm3,%xmm4
+	psrldq	$8,%xmm3
+	pslldq	$8,%xmm4
+	pxor	%xmm3,%xmm7
+	pxor	%xmm4,%xmm6
+	movdqa	%xmm0,%xmm1
+	pshufd	$78,%xmm0,%xmm3
+	pshufd	$78,%xmm8,%xmm4
+	pxor	%xmm0,%xmm3
+	pxor	%xmm8,%xmm4
+
+	leaq	32(%rdx),%rdx
+	subq	$32,%rcx
+	jbe	.Leven_tail
+
+.Lmod_loop:
+.byte	102,65,15,58,68,192,0
+.byte	102,65,15,58,68,200,17
+.byte	102,15,58,68,220,0
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
+
+	movdqa	%xmm3,%xmm4
+	psrldq	$8,%xmm3
+	pslldq	$8,%xmm4
+	pxor	%xmm3,%xmm1
+	pxor	%xmm4,%xmm0
+	movdqu	(%rdx),%xmm3
+	pxor	%xmm6,%xmm0
+	pxor	%xmm7,%xmm1
+
+	movdqu	16(%rdx),%xmm6
+.byte	102,15,56,0,221
+.byte	102,15,56,0,245
+
+	movdqa	%xmm6,%xmm7
+	pshufd	$78,%xmm6,%xmm9
+	pshufd	$78,%xmm2,%xmm10
+	pxor	%xmm6,%xmm9
+	pxor	%xmm2,%xmm10
+	pxor	%xmm3,%xmm1
+
+	movdqa	%xmm0,%xmm3
+	psllq	$1,%xmm0
+	pxor	%xmm3,%xmm0
+	psllq	$5,%xmm0
+	pxor	%xmm3,%xmm0
+.byte	102,15,58,68,242,0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm4
+	pslldq	$8,%xmm0
+	psrldq	$8,%xmm4
+	pxor	%xmm3,%xmm0
+	pxor	%xmm4,%xmm1
+
+.byte	102,15,58,68,250,17
+	movdqa	%xmm0,%xmm4
+	psrlq	$5,%xmm0
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm4,%xmm0
+	pxor	%xmm1,%xmm4
+	psrlq	$1,%xmm0
+	pxor	%xmm4,%xmm0
+
+.byte	102,69,15,58,68,202,0
+	movdqa	%xmm0,%xmm1
+	pshufd	$78,%xmm0,%xmm3
+	pshufd	$78,%xmm8,%xmm4
+	pxor	%xmm0,%xmm3
+	pxor	%xmm8,%xmm4
+
+	pxor	%xmm6,%xmm9
+	pxor	%xmm7,%xmm9
+	movdqa	%xmm9,%xmm10
+	psrldq	$8,%xmm9
+	pslldq	$8,%xmm10
+	pxor	%xmm9,%xmm7
+	pxor	%xmm10,%xmm6
+
+	leaq	32(%rdx),%rdx
+	subq	$32,%rcx
+	ja	.Lmod_loop
+
+.Leven_tail:
+.byte	102,65,15,58,68,192,0
+.byte	102,65,15,58,68,200,17
+.byte	102,15,58,68,220,0
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
+
+	movdqa	%xmm3,%xmm4
+	psrldq	$8,%xmm3
+	pslldq	$8,%xmm4
+	pxor	%xmm3,%xmm1
+	pxor	%xmm4,%xmm0
+	pxor	%xmm6,%xmm0
+	pxor	%xmm7,%xmm1
+
+	movdqa	%xmm0,%xmm3
+	psllq	$1,%xmm0
+	pxor	%xmm3,%xmm0
+	psllq	$5,%xmm0
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm4
+	pslldq	$8,%xmm0
+	psrldq	$8,%xmm4
+	pxor	%xmm3,%xmm0
+	pxor	%xmm4,%xmm1
+
+
+	movdqa	%xmm0,%xmm4
+	psrlq	$5,%xmm0
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm4,%xmm0
+	pxor	%xmm1,%xmm4
+	psrlq	$1,%xmm0
+	pxor	%xmm4,%xmm0
+	testq	%rcx,%rcx
+	jnz	.Ldone
+
+.Lodd_tail:
+	movdqu	(%rdx),%xmm3
+.byte	102,15,56,0,221
+	pxor	%xmm3,%xmm0
+	movdqa	%xmm0,%xmm1
+	pshufd	$78,%xmm0,%xmm3
+	pshufd	$78,%xmm2,%xmm4
+	pxor	%xmm0,%xmm3
+	pxor	%xmm2,%xmm4
+.byte	102,15,58,68,194,0
+.byte	102,15,58,68,202,17
+.byte	102,15,58,68,220,0
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
+
+	movdqa	%xmm3,%xmm4
+	psrldq	$8,%xmm3
+	pslldq	$8,%xmm4
+	pxor	%xmm3,%xmm1
+	pxor	%xmm4,%xmm0
+
+	movdqa	%xmm0,%xmm3
+	psllq	$1,%xmm0
+	pxor	%xmm3,%xmm0
+	psllq	$5,%xmm0
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm4
+	pslldq	$8,%xmm0
+	psrldq	$8,%xmm4
+	pxor	%xmm3,%xmm0
+	pxor	%xmm4,%xmm1
+
+
+	movdqa	%xmm0,%xmm4
+	psrlq	$5,%xmm0
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm4,%xmm0
+	pxor	%xmm1,%xmm4
+	psrlq	$1,%xmm0
+	pxor	%xmm4,%xmm0
+.Ldone:
+.byte	102,15,56,0,197
+	movdqu	%xmm0,(%rdi)
+	.byte	0xf3,0xc3
+.LSEH_end_gcm_ghash_clmul:
+.size	gcm_ghash_clmul,.-gcm_ghash_clmul
+.align	64
+.Lbswap_mask:
+.byte	15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
+.L0x1c2_polynomial:
+.byte	1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2
+.align	64
+.type	.Lrem_4bit,@object
+.Lrem_4bit:
+.long	0,0,0,471859200,0,943718400,0,610271232
+.long	0,1887436800,0,1822425088,0,1220542464,0,1423966208
+.long	0,3774873600,0,4246732800,0,3644850176,0,3311403008
+.long	0,2441084928,0,2376073216,0,2847932416,0,3051356160
+.type	.Lrem_8bit,@object
+.Lrem_8bit:
+.value	0x0000,0x01C2,0x0384,0x0246,0x0708,0x06CA,0x048C,0x054E
+.value	0x0E10,0x0FD2,0x0D94,0x0C56,0x0918,0x08DA,0x0A9C,0x0B5E
+.value	0x1C20,0x1DE2,0x1FA4,0x1E66,0x1B28,0x1AEA,0x18AC,0x196E
+.value	0x1230,0x13F2,0x11B4,0x1076,0x1538,0x14FA,0x16BC,0x177E
+.value	0x3840,0x3982,0x3BC4,0x3A06,0x3F48,0x3E8A,0x3CCC,0x3D0E
+.value	0x3650,0x3792,0x35D4,0x3416,0x3158,0x309A,0x32DC,0x331E
+.value	0x2460,0x25A2,0x27E4,0x2626,0x2368,0x22AA,0x20EC,0x212E
+.value	0x2A70,0x2BB2,0x29F4,0x2836,0x2D78,0x2CBA,0x2EFC,0x2F3E
+.value	0x7080,0x7142,0x7304,0x72C6,0x7788,0x764A,0x740C,0x75CE
+.value	0x7E90,0x7F52,0x7D14,0x7CD6,0x7998,0x785A,0x7A1C,0x7BDE
+.value	0x6CA0,0x6D62,0x6F24,0x6EE6,0x6BA8,0x6A6A,0x682C,0x69EE
+.value	0x62B0,0x6372,0x6134,0x60F6,0x65B8,0x647A,0x663C,0x67FE
+.value	0x48C0,0x4902,0x4B44,0x4A86,0x4FC8,0x4E0A,0x4C4C,0x4D8E
+.value	0x46D0,0x4712,0x4554,0x4496,0x41D8,0x401A,0x425C,0x439E
+.value	0x54E0,0x5522,0x5764,0x56A6,0x53E8,0x522A,0x506C,0x51AE
+.value	0x5AF0,0x5B32,0x5974,0x58B6,0x5DF8,0x5C3A,0x5E7C,0x5FBE
+.value	0xE100,0xE0C2,0xE284,0xE346,0xE608,0xE7CA,0xE58C,0xE44E
+.value	0xEF10,0xEED2,0xEC94,0xED56,0xE818,0xE9DA,0xEB9C,0xEA5E
+.value	0xFD20,0xFCE2,0xFEA4,0xFF66,0xFA28,0xFBEA,0xF9AC,0xF86E
+.value	0xF330,0xF2F2,0xF0B4,0xF176,0xF438,0xF5FA,0xF7BC,0xF67E
+.value	0xD940,0xD882,0xDAC4,0xDB06,0xDE48,0xDF8A,0xDDCC,0xDC0E
+.value	0xD750,0xD692,0xD4D4,0xD516,0xD058,0xD19A,0xD3DC,0xD21E
+.value	0xC560,0xC4A2,0xC6E4,0xC726,0xC268,0xC3AA,0xC1EC,0xC02E
+.value	0xCB70,0xCAB2,0xC8F4,0xC936,0xCC78,0xCDBA,0xCFFC,0xCE3E
+.value	0x9180,0x9042,0x9204,0x93C6,0x9688,0x974A,0x950C,0x94CE
+.value	0x9F90,0x9E52,0x9C14,0x9DD6,0x9898,0x995A,0x9B1C,0x9ADE
+.value	0x8DA0,0x8C62,0x8E24,0x8FE6,0x8AA8,0x8B6A,0x892C,0x88EE
+.value	0x83B0,0x8272,0x8034,0x81F6,0x84B8,0x857A,0x873C,0x86FE
+.value	0xA9C0,0xA802,0xAA44,0xAB86,0xAEC8,0xAF0A,0xAD4C,0xAC8E
+.value	0xA7D0,0xA612,0xA454,0xA596,0xA0D8,0xA11A,0xA35C,0xA29E
+.value	0xB5E0,0xB422,0xB664,0xB7A6,0xB2E8,0xB32A,0xB16C,0xB0AE
+.value	0xBBF0,0xBA32,0xB874,0xB9B6,0xBCF8,0xBD3A,0xBF7C,0xBEBE
+
+.byte	71,72,65,83,72,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align	64
+#if defined(HAVE_GNU_STACK)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/crypto/libressl/crypto/modes/ghash-macosx-x86_64.s b/crypto/libressl/crypto/modes/ghash-macosx-x86_64.s
new file mode 100644
index 0000000000..1b49e328cd
--- /dev/null
+++ b/crypto/libressl/crypto/modes/ghash-macosx-x86_64.s
@@ -0,0 +1,1026 @@
+.text	
+
+.globl	_gcm_gmult_4bit
+
+.p2align	4
+_gcm_gmult_4bit:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+L$gmult_prologue:
+
+	movzbq	15(%rdi),%r8
+	leaq	L$rem_4bit(%rip),%r11
+	xorq	%rax,%rax
+	xorq	%rbx,%rbx
+	movb	%r8b,%al
+	movb	%r8b,%bl
+	shlb	$4,%al
+	movq	$14,%rcx
+	movq	8(%rsi,%rax,1),%r8
+	movq	(%rsi,%rax,1),%r9
+	andb	$240,%bl
+	movq	%r8,%rdx
+	jmp	L$oop1
+
+.p2align	4
+L$oop1:
+	shrq	$4,%r8
+	andq	$15,%rdx
+	movq	%r9,%r10
+	movb	(%rdi,%rcx,1),%al
+	shrq	$4,%r9
+	xorq	8(%rsi,%rbx,1),%r8
+	shlq	$60,%r10
+	xorq	(%rsi,%rbx,1),%r9
+	movb	%al,%bl
+	xorq	(%r11,%rdx,8),%r9
+	movq	%r8,%rdx
+	shlb	$4,%al
+	xorq	%r10,%r8
+	decq	%rcx
+	js	L$break1
+
+	shrq	$4,%r8
+	andq	$15,%rdx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	xorq	8(%rsi,%rax,1),%r8
+	shlq	$60,%r10
+	xorq	(%rsi,%rax,1),%r9
+	andb	$240,%bl
+	xorq	(%r11,%rdx,8),%r9
+	movq	%r8,%rdx
+	xorq	%r10,%r8
+	jmp	L$oop1
+
+.p2align	4
+L$break1:
+	shrq	$4,%r8
+	andq	$15,%rdx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	xorq	8(%rsi,%rax,1),%r8
+	shlq	$60,%r10
+	xorq	(%rsi,%rax,1),%r9
+	andb	$240,%bl
+	xorq	(%r11,%rdx,8),%r9
+	movq	%r8,%rdx
+	xorq	%r10,%r8
+
+	shrq	$4,%r8
+	andq	$15,%rdx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	xorq	8(%rsi,%rbx,1),%r8
+	shlq	$60,%r10
+	xorq	(%rsi,%rbx,1),%r9
+	xorq	%r10,%r8
+	xorq	(%r11,%rdx,8),%r9
+
+	bswapq	%r8
+	bswapq	%r9
+	movq	%r8,8(%rdi)
+	movq	%r9,(%rdi)
+
+	movq	16(%rsp),%rbx
+	leaq	24(%rsp),%rsp
+L$gmult_epilogue:
+	.byte	0xf3,0xc3
+
+.globl	_gcm_ghash_4bit
+
+.p2align	4
+_gcm_ghash_4bit:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	subq	$280,%rsp
+L$ghash_prologue:
+	movq	%rdx,%r14
+	movq	%rcx,%r15
+	subq	$-128,%rsi
+	leaq	16+128(%rsp),%rbp
+	xorl	%edx,%edx
+	movq	0+0-128(%rsi),%r8
+	movq	0+8-128(%rsi),%rax
+	movb	%al,%dl
+	shrq	$4,%rax
+	movq	%r8,%r10
+	shrq	$4,%r8
+	movq	16+0-128(%rsi),%r9
+	shlb	$4,%dl
+	movq	16+8-128(%rsi),%rbx
+	shlq	$60,%r10
+	movb	%dl,0(%rsp)
+	orq	%r10,%rax
+	movb	%bl,%dl
+	shrq	$4,%rbx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	movq	%r8,0(%rbp)
+	movq	32+0-128(%rsi),%r8
+	shlb	$4,%dl
+	movq	%rax,0-128(%rbp)
+	movq	32+8-128(%rsi),%rax
+	shlq	$60,%r10
+	movb	%dl,1(%rsp)
+	orq	%r10,%rbx
+	movb	%al,%dl
+	shrq	$4,%rax
+	movq	%r8,%r10
+	shrq	$4,%r8
+	movq	%r9,8(%rbp)
+	movq	48+0-128(%rsi),%r9
+	shlb	$4,%dl
+	movq	%rbx,8-128(%rbp)
+	movq	48+8-128(%rsi),%rbx
+	shlq	$60,%r10
+	movb	%dl,2(%rsp)
+	orq	%r10,%rax
+	movb	%bl,%dl
+	shrq	$4,%rbx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	movq	%r8,16(%rbp)
+	movq	64+0-128(%rsi),%r8
+	shlb	$4,%dl
+	movq	%rax,16-128(%rbp)
+	movq	64+8-128(%rsi),%rax
+	shlq	$60,%r10
+	movb	%dl,3(%rsp)
+	orq	%r10,%rbx
+	movb	%al,%dl
+	shrq	$4,%rax
+	movq	%r8,%r10
+	shrq	$4,%r8
+	movq	%r9,24(%rbp)
+	movq	80+0-128(%rsi),%r9
+	shlb	$4,%dl
+	movq	%rbx,24-128(%rbp)
+	movq	80+8-128(%rsi),%rbx
+	shlq	$60,%r10
+	movb	%dl,4(%rsp)
+	orq	%r10,%rax
+	movb	%bl,%dl
+	shrq	$4,%rbx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	movq	%r8,32(%rbp)
+	movq	96+0-128(%rsi),%r8
+	shlb	$4,%dl
+	movq	%rax,32-128(%rbp)
+	movq	96+8-128(%rsi),%rax
+	shlq	$60,%r10
+	movb	%dl,5(%rsp)
+	orq	%r10,%rbx
+	movb	%al,%dl
+	shrq	$4,%rax
+	movq	%r8,%r10
+	shrq	$4,%r8
+	movq	%r9,40(%rbp)
+	movq	112+0-128(%rsi),%r9
+	shlb	$4,%dl
+	movq	%rbx,40-128(%rbp)
+	movq	112+8-128(%rsi),%rbx
+	shlq	$60,%r10
+	movb	%dl,6(%rsp)
+	orq	%r10,%rax
+	movb	%bl,%dl
+	shrq	$4,%rbx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	movq	%r8,48(%rbp)
+	movq	128+0-128(%rsi),%r8
+	shlb	$4,%dl
+	movq	%rax,48-128(%rbp)
+	movq	128+8-128(%rsi),%rax
+	shlq	$60,%r10
+	movb	%dl,7(%rsp)
+	orq	%r10,%rbx
+	movb	%al,%dl
+	shrq	$4,%rax
+	movq	%r8,%r10
+	shrq	$4,%r8
+	movq	%r9,56(%rbp)
+	movq	144+0-128(%rsi),%r9
+	shlb	$4,%dl
+	movq	%rbx,56-128(%rbp)
+	movq	144+8-128(%rsi),%rbx
+	shlq	$60,%r10
+	movb	%dl,8(%rsp)
+	orq	%r10,%rax
+	movb	%bl,%dl
+	shrq	$4,%rbx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	movq	%r8,64(%rbp)
+	movq	160+0-128(%rsi),%r8
+	shlb	$4,%dl
+	movq	%rax,64-128(%rbp)
+	movq	160+8-128(%rsi),%rax
+	shlq	$60,%r10
+	movb	%dl,9(%rsp)
+	orq	%r10,%rbx
+	movb	%al,%dl
+	shrq	$4,%rax
+	movq	%r8,%r10
+	shrq	$4,%r8
+	movq	%r9,72(%rbp)
+	movq	176+0-128(%rsi),%r9
+	shlb	$4,%dl
+	movq	%rbx,72-128(%rbp)
+	movq	176+8-128(%rsi),%rbx
+	shlq	$60,%r10
+	movb	%dl,10(%rsp)
+	orq	%r10,%rax
+	movb	%bl,%dl
+	shrq	$4,%rbx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	movq	%r8,80(%rbp)
+	movq	192+0-128(%rsi),%r8
+	shlb	$4,%dl
+	movq	%rax,80-128(%rbp)
+	movq	192+8-128(%rsi),%rax
+	shlq	$60,%r10
+	movb	%dl,11(%rsp)
+	orq	%r10,%rbx
+	movb	%al,%dl
+	shrq	$4,%rax
+	movq	%r8,%r10
+	shrq	$4,%r8
+	movq	%r9,88(%rbp)
+	movq	208+0-128(%rsi),%r9
+	shlb	$4,%dl
+	movq	%rbx,88-128(%rbp)
+	movq	208+8-128(%rsi),%rbx
+	shlq	$60,%r10
+	movb	%dl,12(%rsp)
+	orq	%r10,%rax
+	movb	%bl,%dl
+	shrq	$4,%rbx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	movq	%r8,96(%rbp)
+	movq	224+0-128(%rsi),%r8
+	shlb	$4,%dl
+	movq	%rax,96-128(%rbp)
+	movq	224+8-128(%rsi),%rax
+	shlq	$60,%r10
+	movb	%dl,13(%rsp)
+	orq	%r10,%rbx
+	movb	%al,%dl
+	shrq	$4,%rax
+	movq	%r8,%r10
+	shrq	$4,%r8
+	movq	%r9,104(%rbp)
+	movq	240+0-128(%rsi),%r9
+	shlb	$4,%dl
+	movq	%rbx,104-128(%rbp)
+	movq	240+8-128(%rsi),%rbx
+	shlq	$60,%r10
+	movb	%dl,14(%rsp)
+	orq	%r10,%rax
+	movb	%bl,%dl
+	shrq	$4,%rbx
+	movq	%r9,%r10
+	shrq	$4,%r9
+	movq	%r8,112(%rbp)
+	shlb	$4,%dl
+	movq	%rax,112-128(%rbp)
+	shlq	$60,%r10
+	movb	%dl,15(%rsp)
+	orq	%r10,%rbx
+	movq	%r9,120(%rbp)
+	movq	%rbx,120-128(%rbp)
+	addq	$-128,%rsi
+	movq	8(%rdi),%r8
+	movq	0(%rdi),%r9
+	addq	%r14,%r15
+	leaq	L$rem_8bit(%rip),%r11
+	jmp	L$outer_loop
+.p2align	4
+L$outer_loop:
+	xorq	(%r14),%r9
+	movq	8(%r14),%rdx
+	leaq	16(%r14),%r14
+	xorq	%r8,%rdx
+	movq	%r9,(%rdi)
+	movq	%rdx,8(%rdi)
+	shrq	$32,%rdx
+	xorq	%rax,%rax
+	roll	$8,%edx
+	movb	%dl,%al
+	movzbl	%dl,%ebx
+	shlb	$4,%al
+	shrl	$4,%ebx
+	roll	$8,%edx
+	movq	8(%rsi,%rax,1),%r8
+	movq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	movzbl	%dl,%ecx
+	shlb	$4,%al
+	movzbq	(%rsp,%rbx,1),%r12
+	shrl	$4,%ecx
+	xorq	%r8,%r12
+	movq	%r9,%r10
+	shrq	$8,%r8
+	movzbq	%r12b,%r12
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rbx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rbx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r12,2),%r12
+	movzbl	%dl,%ebx
+	shlb	$4,%al
+	movzbq	(%rsp,%rcx,1),%r13
+	shrl	$4,%ebx
+	shlq	$48,%r12
+	xorq	%r8,%r13
+	movq	%r9,%r10
+	xorq	%r12,%r9
+	shrq	$8,%r8
+	movzbq	%r13b,%r13
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rcx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rcx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r13,2),%r13
+	movzbl	%dl,%ecx
+	shlb	$4,%al
+	movzbq	(%rsp,%rbx,1),%r12
+	shrl	$4,%ecx
+	shlq	$48,%r13
+	xorq	%r8,%r12
+	movq	%r9,%r10
+	xorq	%r13,%r9
+	shrq	$8,%r8
+	movzbq	%r12b,%r12
+	movl	8(%rdi),%edx
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rbx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rbx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r12,2),%r12
+	movzbl	%dl,%ebx
+	shlb	$4,%al
+	movzbq	(%rsp,%rcx,1),%r13
+	shrl	$4,%ebx
+	shlq	$48,%r12
+	xorq	%r8,%r13
+	movq	%r9,%r10
+	xorq	%r12,%r9
+	shrq	$8,%r8
+	movzbq	%r13b,%r13
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rcx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rcx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r13,2),%r13
+	movzbl	%dl,%ecx
+	shlb	$4,%al
+	movzbq	(%rsp,%rbx,1),%r12
+	shrl	$4,%ecx
+	shlq	$48,%r13
+	xorq	%r8,%r12
+	movq	%r9,%r10
+	xorq	%r13,%r9
+	shrq	$8,%r8
+	movzbq	%r12b,%r12
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rbx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rbx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r12,2),%r12
+	movzbl	%dl,%ebx
+	shlb	$4,%al
+	movzbq	(%rsp,%rcx,1),%r13
+	shrl	$4,%ebx
+	shlq	$48,%r12
+	xorq	%r8,%r13
+	movq	%r9,%r10
+	xorq	%r12,%r9
+	shrq	$8,%r8
+	movzbq	%r13b,%r13
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rcx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rcx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r13,2),%r13
+	movzbl	%dl,%ecx
+	shlb	$4,%al
+	movzbq	(%rsp,%rbx,1),%r12
+	shrl	$4,%ecx
+	shlq	$48,%r13
+	xorq	%r8,%r12
+	movq	%r9,%r10
+	xorq	%r13,%r9
+	shrq	$8,%r8
+	movzbq	%r12b,%r12
+	movl	4(%rdi),%edx
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rbx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rbx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r12,2),%r12
+	movzbl	%dl,%ebx
+	shlb	$4,%al
+	movzbq	(%rsp,%rcx,1),%r13
+	shrl	$4,%ebx
+	shlq	$48,%r12
+	xorq	%r8,%r13
+	movq	%r9,%r10
+	xorq	%r12,%r9
+	shrq	$8,%r8
+	movzbq	%r13b,%r13
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rcx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rcx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r13,2),%r13
+	movzbl	%dl,%ecx
+	shlb	$4,%al
+	movzbq	(%rsp,%rbx,1),%r12
+	shrl	$4,%ecx
+	shlq	$48,%r13
+	xorq	%r8,%r12
+	movq	%r9,%r10
+	xorq	%r13,%r9
+	shrq	$8,%r8
+	movzbq	%r12b,%r12
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rbx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rbx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r12,2),%r12
+	movzbl	%dl,%ebx
+	shlb	$4,%al
+	movzbq	(%rsp,%rcx,1),%r13
+	shrl	$4,%ebx
+	shlq	$48,%r12
+	xorq	%r8,%r13
+	movq	%r9,%r10
+	xorq	%r12,%r9
+	shrq	$8,%r8
+	movzbq	%r13b,%r13
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rcx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rcx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r13,2),%r13
+	movzbl	%dl,%ecx
+	shlb	$4,%al
+	movzbq	(%rsp,%rbx,1),%r12
+	shrl	$4,%ecx
+	shlq	$48,%r13
+	xorq	%r8,%r12
+	movq	%r9,%r10
+	xorq	%r13,%r9
+	shrq	$8,%r8
+	movzbq	%r12b,%r12
+	movl	0(%rdi),%edx
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rbx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rbx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r12,2),%r12
+	movzbl	%dl,%ebx
+	shlb	$4,%al
+	movzbq	(%rsp,%rcx,1),%r13
+	shrl	$4,%ebx
+	shlq	$48,%r12
+	xorq	%r8,%r13
+	movq	%r9,%r10
+	xorq	%r12,%r9
+	shrq	$8,%r8
+	movzbq	%r13b,%r13
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rcx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rcx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r13,2),%r13
+	movzbl	%dl,%ecx
+	shlb	$4,%al
+	movzbq	(%rsp,%rbx,1),%r12
+	shrl	$4,%ecx
+	shlq	$48,%r13
+	xorq	%r8,%r12
+	movq	%r9,%r10
+	xorq	%r13,%r9
+	shrq	$8,%r8
+	movzbq	%r12b,%r12
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rbx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rbx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r12,2),%r12
+	movzbl	%dl,%ebx
+	shlb	$4,%al
+	movzbq	(%rsp,%rcx,1),%r13
+	shrl	$4,%ebx
+	shlq	$48,%r12
+	xorq	%r8,%r13
+	movq	%r9,%r10
+	xorq	%r12,%r9
+	shrq	$8,%r8
+	movzbq	%r13b,%r13
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rcx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rcx,8),%r9
+	roll	$8,%edx
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	movb	%dl,%al
+	xorq	%r10,%r8
+	movzwq	(%r11,%r13,2),%r13
+	movzbl	%dl,%ecx
+	shlb	$4,%al
+	movzbq	(%rsp,%rbx,1),%r12
+	andl	$240,%ecx
+	shlq	$48,%r13
+	xorq	%r8,%r12
+	movq	%r9,%r10
+	xorq	%r13,%r9
+	shrq	$8,%r8
+	movzbq	%r12b,%r12
+	movl	-4(%rdi),%edx
+	shrq	$8,%r9
+	xorq	-128(%rbp,%rbx,8),%r8
+	shlq	$56,%r10
+	xorq	(%rbp,%rbx,8),%r9
+	movzwq	(%r11,%r12,2),%r12
+	xorq	8(%rsi,%rax,1),%r8
+	xorq	(%rsi,%rax,1),%r9
+	shlq	$48,%r12
+	xorq	%r10,%r8
+	xorq	%r12,%r9
+	movzbq	%r8b,%r13
+	shrq	$4,%r8
+	movq	%r9,%r10
+	shlb	$4,%r13b
+	shrq	$4,%r9
+	xorq	8(%rsi,%rcx,1),%r8
+	movzwq	(%r11,%r13,2),%r13
+	shlq	$60,%r10
+	xorq	(%rsi,%rcx,1),%r9
+	xorq	%r10,%r8
+	shlq	$48,%r13
+	bswapq	%r8
+	xorq	%r13,%r9
+	bswapq	%r9
+	cmpq	%r15,%r14
+	jb	L$outer_loop
+	movq	%r8,8(%rdi)
+	movq	%r9,(%rdi)
+
+	leaq	280(%rsp),%rsi
+	movq	0(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+L$ghash_epilogue:
+	.byte	0xf3,0xc3
+
+.globl	_gcm_init_clmul
+
+.p2align	4
+_gcm_init_clmul:
+	movdqu	(%rsi),%xmm2
+	pshufd	$78,%xmm2,%xmm2
+
+
+	pshufd	$255,%xmm2,%xmm4
+	movdqa	%xmm2,%xmm3
+	psllq	$1,%xmm2
+	pxor	%xmm5,%xmm5
+	psrlq	$63,%xmm3
+	pcmpgtd	%xmm4,%xmm5
+	pslldq	$8,%xmm3
+	por	%xmm3,%xmm2
+
+
+	pand	L$0x1c2_polynomial(%rip),%xmm5
+	pxor	%xmm5,%xmm2
+
+
+	movdqa	%xmm2,%xmm0
+	movdqa	%xmm0,%xmm1
+	pshufd	$78,%xmm0,%xmm3
+	pshufd	$78,%xmm2,%xmm4
+	pxor	%xmm0,%xmm3
+	pxor	%xmm2,%xmm4
+.byte	102,15,58,68,194,0
+.byte	102,15,58,68,202,17
+.byte	102,15,58,68,220,0
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
+
+	movdqa	%xmm3,%xmm4
+	psrldq	$8,%xmm3
+	pslldq	$8,%xmm4
+	pxor	%xmm3,%xmm1
+	pxor	%xmm4,%xmm0
+
+	movdqa	%xmm0,%xmm3
+	psllq	$1,%xmm0
+	pxor	%xmm3,%xmm0
+	psllq	$5,%xmm0
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm4
+	pslldq	$8,%xmm0
+	psrldq	$8,%xmm4
+	pxor	%xmm3,%xmm0
+	pxor	%xmm4,%xmm1
+
+
+	movdqa	%xmm0,%xmm4
+	psrlq	$5,%xmm0
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm4,%xmm0
+	pxor	%xmm1,%xmm4
+	psrlq	$1,%xmm0
+	pxor	%xmm4,%xmm0
+	movdqu	%xmm2,(%rdi)
+	movdqu	%xmm0,16(%rdi)
+	.byte	0xf3,0xc3
+
+.globl	_gcm_gmult_clmul
+
+.p2align	4
+_gcm_gmult_clmul:
+	movdqu	(%rdi),%xmm0
+	movdqa	L$bswap_mask(%rip),%xmm5
+	movdqu	(%rsi),%xmm2
+.byte	102,15,56,0,197
+	movdqa	%xmm0,%xmm1
+	pshufd	$78,%xmm0,%xmm3
+	pshufd	$78,%xmm2,%xmm4
+	pxor	%xmm0,%xmm3
+	pxor	%xmm2,%xmm4
+.byte	102,15,58,68,194,0
+.byte	102,15,58,68,202,17
+.byte	102,15,58,68,220,0
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
+
+	movdqa	%xmm3,%xmm4
+	psrldq	$8,%xmm3
+	pslldq	$8,%xmm4
+	pxor	%xmm3,%xmm1
+	pxor	%xmm4,%xmm0
+
+	movdqa	%xmm0,%xmm3
+	psllq	$1,%xmm0
+	pxor	%xmm3,%xmm0
+	psllq	$5,%xmm0
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm4
+	pslldq	$8,%xmm0
+	psrldq	$8,%xmm4
+	pxor	%xmm3,%xmm0
+	pxor	%xmm4,%xmm1
+
+
+	movdqa	%xmm0,%xmm4
+	psrlq	$5,%xmm0
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm4,%xmm0
+	pxor	%xmm1,%xmm4
+	psrlq	$1,%xmm0
+	pxor	%xmm4,%xmm0
+.byte	102,15,56,0,197
+	movdqu	%xmm0,(%rdi)
+	.byte	0xf3,0xc3
+
+.globl	_gcm_ghash_clmul
+
+.p2align	4
+_gcm_ghash_clmul:
+	movdqa	L$bswap_mask(%rip),%xmm5
+
+	movdqu	(%rdi),%xmm0
+	movdqu	(%rsi),%xmm2
+.byte	102,15,56,0,197
+
+	subq	$16,%rcx
+	jz	L$odd_tail
+
+	movdqu	16(%rsi),%xmm8
+
+
+
+
+
+	movdqu	(%rdx),%xmm3
+	movdqu	16(%rdx),%xmm6
+.byte	102,15,56,0,221
+.byte	102,15,56,0,245
+	pxor	%xmm3,%xmm0
+	movdqa	%xmm6,%xmm7
+	pshufd	$78,%xmm6,%xmm3
+	pshufd	$78,%xmm2,%xmm4
+	pxor	%xmm6,%xmm3
+	pxor	%xmm2,%xmm4
+.byte	102,15,58,68,242,0
+.byte	102,15,58,68,250,17
+.byte	102,15,58,68,220,0
+	pxor	%xmm6,%xmm3
+	pxor	%xmm7,%xmm3
+
+	movdqa	%xmm3,%xmm4
+	psrldq	$8,%xmm3
+	pslldq	$8,%xmm4
+	pxor	%xmm3,%xmm7
+	pxor	%xmm4,%xmm6
+	movdqa	%xmm0,%xmm1
+	pshufd	$78,%xmm0,%xmm3
+	pshufd	$78,%xmm8,%xmm4
+	pxor	%xmm0,%xmm3
+	pxor	%xmm8,%xmm4
+
+	leaq	32(%rdx),%rdx
+	subq	$32,%rcx
+	jbe	L$even_tail
+
+L$mod_loop:
+.byte	102,65,15,58,68,192,0
+.byte	102,65,15,58,68,200,17
+.byte	102,15,58,68,220,0
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
+
+	movdqa	%xmm3,%xmm4
+	psrldq	$8,%xmm3
+	pslldq	$8,%xmm4
+	pxor	%xmm3,%xmm1
+	pxor	%xmm4,%xmm0
+	movdqu	(%rdx),%xmm3
+	pxor	%xmm6,%xmm0
+	pxor	%xmm7,%xmm1
+
+	movdqu	16(%rdx),%xmm6
+.byte	102,15,56,0,221
+.byte	102,15,56,0,245
+
+	movdqa	%xmm6,%xmm7
+	pshufd	$78,%xmm6,%xmm9
+	pshufd	$78,%xmm2,%xmm10
+	pxor	%xmm6,%xmm9
+	pxor	%xmm2,%xmm10
+	pxor	%xmm3,%xmm1
+
+	movdqa	%xmm0,%xmm3
+	psllq	$1,%xmm0
+	pxor	%xmm3,%xmm0
+	psllq	$5,%xmm0
+	pxor	%xmm3,%xmm0
+.byte	102,15,58,68,242,0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm4
+	pslldq	$8,%xmm0
+	psrldq	$8,%xmm4
+	pxor	%xmm3,%xmm0
+	pxor	%xmm4,%xmm1
+
+.byte	102,15,58,68,250,17
+	movdqa	%xmm0,%xmm4
+	psrlq	$5,%xmm0
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm4,%xmm0
+	pxor	%xmm1,%xmm4
+	psrlq	$1,%xmm0
+	pxor	%xmm4,%xmm0
+
+.byte	102,69,15,58,68,202,0
+	movdqa	%xmm0,%xmm1
+	pshufd	$78,%xmm0,%xmm3
+	pshufd	$78,%xmm8,%xmm4
+	pxor	%xmm0,%xmm3
+	pxor	%xmm8,%xmm4
+
+	pxor	%xmm6,%xmm9
+	pxor	%xmm7,%xmm9
+	movdqa	%xmm9,%xmm10
+	psrldq	$8,%xmm9
+	pslldq	$8,%xmm10
+	pxor	%xmm9,%xmm7
+	pxor	%xmm10,%xmm6
+
+	leaq	32(%rdx),%rdx
+	subq	$32,%rcx
+	ja	L$mod_loop
+
+L$even_tail:
+.byte	102,65,15,58,68,192,0
+.byte	102,65,15,58,68,200,17
+.byte	102,15,58,68,220,0
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
+
+	movdqa	%xmm3,%xmm4
+	psrldq	$8,%xmm3
+	pslldq	$8,%xmm4
+	pxor	%xmm3,%xmm1
+	pxor	%xmm4,%xmm0
+	pxor	%xmm6,%xmm0
+	pxor	%xmm7,%xmm1
+
+	movdqa	%xmm0,%xmm3
+	psllq	$1,%xmm0
+	pxor	%xmm3,%xmm0
+	psllq	$5,%xmm0
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm4
+	pslldq	$8,%xmm0
+	psrldq	$8,%xmm4
+	pxor	%xmm3,%xmm0
+	pxor	%xmm4,%xmm1
+
+
+	movdqa	%xmm0,%xmm4
+	psrlq	$5,%xmm0
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm4,%xmm0
+	pxor	%xmm1,%xmm4
+	psrlq	$1,%xmm0
+	pxor	%xmm4,%xmm0
+	testq	%rcx,%rcx
+	jnz	L$done
+
+L$odd_tail:
+	movdqu	(%rdx),%xmm3
+.byte	102,15,56,0,221
+	pxor	%xmm3,%xmm0
+	movdqa	%xmm0,%xmm1
+	pshufd	$78,%xmm0,%xmm3
+	pshufd	$78,%xmm2,%xmm4
+	pxor	%xmm0,%xmm3
+	pxor	%xmm2,%xmm4
+.byte	102,15,58,68,194,0
+.byte	102,15,58,68,202,17
+.byte	102,15,58,68,220,0
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
+
+	movdqa	%xmm3,%xmm4
+	psrldq	$8,%xmm3
+	pslldq	$8,%xmm4
+	pxor	%xmm3,%xmm1
+	pxor	%xmm4,%xmm0
+
+	movdqa	%xmm0,%xmm3
+	psllq	$1,%xmm0
+	pxor	%xmm3,%xmm0
+	psllq	$5,%xmm0
+	pxor	%xmm3,%xmm0
+	psllq	$57,%xmm0
+	movdqa	%xmm0,%xmm4
+	pslldq	$8,%xmm0
+	psrldq	$8,%xmm4
+	pxor	%xmm3,%xmm0
+	pxor	%xmm4,%xmm1
+
+
+	movdqa	%xmm0,%xmm4
+	psrlq	$5,%xmm0
+	pxor	%xmm4,%xmm0
+	psrlq	$1,%xmm0
+	pxor	%xmm4,%xmm0
+	pxor	%xmm1,%xmm4
+	psrlq	$1,%xmm0
+	pxor	%xmm4,%xmm0
+L$done:
+.byte	102,15,56,0,197
+	movdqu	%xmm0,(%rdi)
+	.byte	0xf3,0xc3
+L$SEH_end_gcm_ghash_clmul:
+
+.p2align	6
+L$bswap_mask:
+.byte	15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
+L$0x1c2_polynomial:
+.byte	1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2
+.p2align	6
+
+L$rem_4bit:
+.long	0,0,0,471859200,0,943718400,0,610271232
+.long	0,1887436800,0,1822425088,0,1220542464,0,1423966208
+.long	0,3774873600,0,4246732800,0,3644850176,0,3311403008
+.long	0,2441084928,0,2376073216,0,2847932416,0,3051356160
+
+L$rem_8bit:
+.value	0x0000,0x01C2,0x0384,0x0246,0x0708,0x06CA,0x048C,0x054E
+.value	0x0E10,0x0FD2,0x0D94,0x0C56,0x0918,0x08DA,0x0A9C,0x0B5E
+.value	0x1C20,0x1DE2,0x1FA4,0x1E66,0x1B28,0x1AEA,0x18AC,0x196E
+.value	0x1230,0x13F2,0x11B4,0x1076,0x1538,0x14FA,0x16BC,0x177E
+.value	0x3840,0x3982,0x3BC4,0x3A06,0x3F48,0x3E8A,0x3CCC,0x3D0E
+.value	0x3650,0x3792,0x35D4,0x3416,0x3158,0x309A,0x32DC,0x331E
+.value	0x2460,0x25A2,0x27E4,0x2626,0x2368,0x22AA,0x20EC,0x212E
+.value	0x2A70,0x2BB2,0x29F4,0x2836,0x2D78,0x2CBA,0x2EFC,0x2F3E
+.value	0x7080,0x7142,0x7304,0x72C6,0x7788,0x764A,0x740C,0x75CE
+.value	0x7E90,0x7F52,0x7D14,0x7CD6,0x7998,0x785A,0x7A1C,0x7BDE
+.value	0x6CA0,0x6D62,0x6F24,0x6EE6,0x6BA8,0x6A6A,0x682C,0x69EE
+.value	0x62B0,0x6372,0x6134,0x60F6,0x65B8,0x647A,0x663C,0x67FE
+.value	0x48C0,0x4902,0x4B44,0x4A86,0x4FC8,0x4E0A,0x4C4C,0x4D8E
+.value	0x46D0,0x4712,0x4554,0x4496,0x41D8,0x401A,0x425C,0x439E
+.value	0x54E0,0x5522,0x5764,0x56A6,0x53E8,0x522A,0x506C,0x51AE
+.value	0x5AF0,0x5B32,0x5974,0x58B6,0x5DF8,0x5C3A,0x5E7C,0x5FBE
+.value	0xE100,0xE0C2,0xE284,0xE346,0xE608,0xE7CA,0xE58C,0xE44E
+.value	0xEF10,0xEED2,0xEC94,0xED56,0xE818,0xE9DA,0xEB9C,0xEA5E
+.value	0xFD20,0xFCE2,0xFEA4,0xFF66,0xFA28,0xFBEA,0xF9AC,0xF86E
+.value	0xF330,0xF2F2,0xF0B4,0xF176,0xF438,0xF5FA,0xF7BC,0xF67E
+.value	0xD940,0xD882,0xDAC4,0xDB06,0xDE48,0xDF8A,0xDDCC,0xDC0E
+.value	0xD750,0xD692,0xD4D4,0xD516,0xD058,0xD19A,0xD3DC,0xD21E
+.value	0xC560,0xC4A2,0xC6E4,0xC726,0xC268,0xC3AA,0xC1EC,0xC02E
+.value	0xCB70,0xCAB2,0xC8F4,0xC936,0xCC78,0xCDBA,0xCFFC,0xCE3E
+.value	0x9180,0x9042,0x9204,0x93C6,0x9688,0x974A,0x950C,0x94CE
+.value	0x9F90,0x9E52,0x9C14,0x9DD6,0x9898,0x995A,0x9B1C,0x9ADE
+.value	0x8DA0,0x8C62,0x8E24,0x8FE6,0x8AA8,0x8B6A,0x892C,0x88EE
+.value	0x83B0,0x8272,0x8034,0x81F6,0x84B8,0x857A,0x873C,0x86FE
+.value	0xA9C0,0xA802,0xAA44,0xAB86,0xAEC8,0xAF0A,0xAD4C,0xAC8E
+.value	0xA7D0,0xA612,0xA454,0xA596,0xA0D8,0xA11A,0xA35C,0xA29E
+.value	0xB5E0,0xB422,0xB664,0xB7A6,0xB2E8,0xB32A,0xB16C,0xB0AE
+.value	0xBBF0,0xBA32,0xB874,0xB9B6,0xBCF8,0xBD3A,0xBF7C,0xBEBE
+
+.byte	71,72,65,83,72,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.p2align	6
diff --git a/crypto/libressl/crypto/modes/modes_lcl.h b/crypto/libressl/crypto/modes/modes_lcl.h
new file mode 100644
index 0000000000..0d9b6dcd6a
--- /dev/null
+++ b/crypto/libressl/crypto/modes/modes_lcl.h
@@ -0,0 +1,108 @@
+/* $OpenBSD: modes_lcl.h,v 1.7 2014/06/12 15:49:30 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 2010 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use is governed by OpenSSL license.
+ * ====================================================================
+ */
+
+#include 
+
+#include 
+
+#include 
+
+#if defined(_LP64)
+typedef long i64;
+typedef unsigned long u64;
+#define U64(C) C##UL
+#else
+typedef long long i64;
+typedef unsigned long long u64;
+#define U64(C) C##ULL
+#endif
+
+typedef unsigned int u32;
+typedef unsigned char u8;
+
+#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+#if defined(__GNUC__) && __GNUC__>=2
+# if defined(__x86_64) || defined(__x86_64__)
+#  define BSWAP8(x) ({	u64 ret=(x);			\
+			asm ("bswapq %0"		\
+			: "+r"(ret));	ret;		})
+#  define BSWAP4(x) ({	u32 ret=(x);			\
+			asm ("bswapl %0"		\
+			: "+r"(ret));	ret;		})
+# elif (defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)
+#  define BSWAP8(x) ({	u32 lo=(u64)(x)>>32,hi=(x);	\
+			asm ("bswapl %0; bswapl %1"	\
+			: "+r"(hi),"+r"(lo));		\
+			(u64)hi<<32|lo;			})
+#  define BSWAP4(x) ({	u32 ret=(x);			\
+			asm ("bswapl %0"		\
+			: "+r"(ret));	ret;		})
+# elif (defined(__arm__) || defined(__arm)) && !defined(__STRICT_ALIGNMENT)
+#  define BSWAP8(x) ({	u32 lo=(u64)(x)>>32,hi=(x);	\
+			asm ("rev %0,%0; rev %1,%1"	\
+			: "+r"(hi),"+r"(lo));		\
+			(u64)hi<<32|lo;			})
+#  define BSWAP4(x) ({	u32 ret;			\
+			asm ("rev %0,%1"		\
+			: "=r"(ret) : "r"((u32)(x)));	\
+			ret;				})
+# endif
+#endif
+#endif
+
+#if defined(BSWAP4) && !defined(__STRICT_ALIGNMENT)
+#define GETU32(p)	BSWAP4(*(const u32 *)(p))
+#define PUTU32(p,v)	*(u32 *)(p) = BSWAP4(v)
+#else
+#define GETU32(p)	((u32)(p)[0]<<24|(u32)(p)[1]<<16|(u32)(p)[2]<<8|(u32)(p)[3])
+#define PUTU32(p,v)	((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v))
+#endif
+
+/* GCM definitions */
+
+typedef struct { u64 hi,lo; } u128;
+
+#ifdef	TABLE_BITS
+#undef	TABLE_BITS
+#endif
+/*
+ * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should
+ * never be set to 8 [or 1]. For further information see gcm128.c.
+ */
+#define	TABLE_BITS 4
+
+struct gcm128_context {
+	/* Following 6 names follow names in GCM specification */
+	union { u64 u[2]; u32 d[4]; u8 c[16]; size_t t[16/sizeof(size_t)]; }
+	  Yi,EKi,EK0,len,Xi,H;
+	/* Relative position of Xi, H and pre-computed Htable is used
+	 * in some assembler modules, i.e. don't change the order! */
+#if TABLE_BITS==8
+	u128 Htable[256];
+#else
+	u128 Htable[16];
+	void (*gmult)(u64 Xi[2],const u128 Htable[16]);
+	void (*ghash)(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
+#endif
+	unsigned int mres, ares;
+	block128_f block;
+	void *key;
+};
+
+struct xts128_context {
+	void      *key1, *key2;
+	block128_f block1,block2;
+};
+
+struct ccm128_context {
+	union { u64 u[2]; u8 c[16]; } nonce, cmac;
+	u64 blocks;
+	block128_f block;
+	void *key;
+};
+
diff --git a/crypto/libressl/crypto/modes/ofb128.c b/crypto/libressl/crypto/modes/ofb128.c
new file mode 100644
index 0000000000..ce2a0270fc
--- /dev/null
+++ b/crypto/libressl/crypto/modes/ofb128.c
@@ -0,0 +1,119 @@
+/* $OpenBSD: ofb128.c,v 1.3 2014/06/12 15:49:30 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include 
+#include "modes_lcl.h"
+#include 
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+
+/* The input and output encrypted as though 128bit ofb mode is being
+ * used.  The extra state information to record how much of the
+ * 128bit block we have used is contained in *num;
+ */
+void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+			size_t len, const void *key,
+			unsigned char ivec[16], int *num,
+			block128_f block)
+{
+	unsigned int n;
+	size_t l=0;
+
+	n = *num;
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+	if (16%sizeof(size_t) == 0) do { /* always true actually */
+		while (n && len) {
+			*(out++) = *(in++) ^ ivec[n];
+			--len;
+			n = (n+1) % 16;
+		}
+#ifdef __STRICT_ALIGNMENT
+		if (((size_t)in|(size_t)out|(size_t)ivec)%sizeof(size_t) != 0)
+			break;
+#endif
+		while (len>=16) {
+			(*block)(ivec, ivec, key);
+			for (; n<16; n+=sizeof(size_t))
+				*(size_t*)(out+n) =
+				*(size_t*)(in+n) ^ *(size_t*)(ivec+n);
+			len -= 16;
+			out += 16;
+			in  += 16;
+			n = 0;
+		}
+		if (len) {
+			(*block)(ivec, ivec, key);
+			while (len--) {
+				out[n] = in[n] ^ ivec[n];
+				++n;
+			}
+		}
+		*num = n;
+		return;
+	} while(0);
+	/* the rest would be commonly eliminated by x86* compiler */
+#endif
+	while (l
+#include 
+#include "modes_lcl.h"
+#include 
+
+#ifndef MODES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+
+int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char iv[16],
+	const unsigned char *inp, unsigned char *out,
+	size_t len, int enc)
+{
+	union { u64 u[2]; u32 d[4]; u8 c[16]; } tweak, scratch;
+	unsigned int i;
+
+	if (len<16) return -1;
+
+	memcpy(tweak.c, iv, 16);
+
+	(*ctx->block2)(tweak.c,tweak.c,ctx->key2);
+
+	if (!enc && (len%16)) len-=16;
+
+	while (len>=16) {
+#ifdef __STRICT_ALIGNMENT
+		memcpy(scratch.c,inp,16);
+		scratch.u[0] ^= tweak.u[0];
+		scratch.u[1] ^= tweak.u[1];
+#else
+		scratch.u[0] = ((u64*)inp)[0]^tweak.u[0];
+		scratch.u[1] = ((u64*)inp)[1]^tweak.u[1];
+#endif
+		(*ctx->block1)(scratch.c,scratch.c,ctx->key1);
+#ifdef __STRICT_ALIGNMENT
+		scratch.u[0] ^= tweak.u[0];
+		scratch.u[1] ^= tweak.u[1];
+		memcpy(out,scratch.c,16);
+#else
+		((u64*)out)[0] = scratch.u[0]^=tweak.u[0];
+		((u64*)out)[1] = scratch.u[1]^=tweak.u[1];
+#endif
+		inp += 16;
+		out += 16;
+		len -= 16;
+
+		if (len==0)	return 0;
+
+		if (BYTE_ORDER == LITTLE_ENDIAN) {
+			unsigned int carry,res;
+			
+			res = 0x87&(((int)tweak.d[3])>>31);
+			carry = (unsigned int)(tweak.u[0]>>63);
+			tweak.u[0] = (tweak.u[0]<<1)^res;
+			tweak.u[1] = (tweak.u[1]<<1)|carry;
+		}
+		else {
+			size_t c;
+
+			for (c=0,i=0;i<16;++i) {
+				/*+ substitutes for |, because c is 1 bit */ 
+				c += ((size_t)tweak.c[i])<<1;
+				tweak.c[i] = (u8)c;
+				c = c>>8;
+			}
+			tweak.c[0] ^= (u8)(0x87&(0-c));
+		}
+	}
+	if (enc) {
+		for (i=0;iblock1)(scratch.c,scratch.c,ctx->key1);
+		scratch.u[0] ^= tweak.u[0];
+		scratch.u[1] ^= tweak.u[1];
+		memcpy(out-16,scratch.c,16);
+	}
+	else {
+		union { u64 u[2]; u8 c[16]; } tweak1;
+
+		if (BYTE_ORDER == LITTLE_ENDIAN) {
+			unsigned int carry,res;
+
+			res = 0x87&(((int)tweak.d[3])>>31);
+			carry = (unsigned int)(tweak.u[0]>>63);
+			tweak1.u[0] = (tweak.u[0]<<1)^res;
+			tweak1.u[1] = (tweak.u[1]<<1)|carry;
+		}
+		else {
+			size_t c;
+
+			for (c=0,i=0;i<16;++i) {
+				/*+ substitutes for |, because c is 1 bit */ 
+				c += ((size_t)tweak.c[i])<<1;
+				tweak1.c[i] = (u8)c;
+				c = c>>8;
+			}
+			tweak1.c[0] ^= (u8)(0x87&(0-c));
+		}
+#ifdef __STRICT_ALIGNMENT
+		memcpy(scratch.c,inp,16);
+		scratch.u[0] ^= tweak1.u[0];
+		scratch.u[1] ^= tweak1.u[1];
+#else
+		scratch.u[0] = ((u64*)inp)[0]^tweak1.u[0];
+		scratch.u[1] = ((u64*)inp)[1]^tweak1.u[1];
+#endif
+		(*ctx->block1)(scratch.c,scratch.c,ctx->key1);
+		scratch.u[0] ^= tweak1.u[0];
+		scratch.u[1] ^= tweak1.u[1];
+
+		for (i=0;iblock1)(scratch.c,scratch.c,ctx->key1);
+#ifdef __STRICT_ALIGNMENT
+		scratch.u[0] ^= tweak.u[0];
+		scratch.u[1] ^= tweak.u[1];
+		memcpy (out,scratch.c,16);
+#else
+		((u64*)out)[0] = scratch.u[0]^tweak.u[0];
+		((u64*)out)[1] = scratch.u[1]^tweak.u[1];
+#endif
+	}
+
+	return 0;
+}
diff --git a/crypto/libressl/crypto/o_init.c b/crypto/libressl/crypto/o_init.c
new file mode 100644
index 0000000000..0471c4daba
--- /dev/null
+++ b/crypto/libressl/crypto/o_init.c
@@ -0,0 +1,10 @@
+/* $OpenBSD$ */
+/* Ted Unangst places this file in the public domain. */
+
+#include 
+
+void
+OPENSSL_init(void)
+{
+
+}
diff --git a/crypto/libressl/crypto/o_str.c b/crypto/libressl/crypto/o_str.c
new file mode 100644
index 0000000000..c35fcf3bdf
--- /dev/null
+++ b/crypto/libressl/crypto/o_str.c
@@ -0,0 +1,21 @@
+/* $OpenBSD: o_str.c,v 1.8 2014/06/12 15:49:27 deraadt Exp $ */
+/*
+ * Written by Theo de Raadt.  Public domain.
+ */
+
+#include 
+
+int OPENSSL_strcasecmp(const char *str1, const char *str2);
+int OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n);
+
+int
+OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n)
+{
+	return strncasecmp(str1, str2, n);
+}
+
+int
+OPENSSL_strcasecmp(const char *str1, const char *str2)
+{
+	return strcasecmp(str1, str2);
+}
diff --git a/crypto/libressl/crypto/o_time.c b/crypto/libressl/crypto/o_time.c
new file mode 100644
index 0000000000..a8f26d0b7c
--- /dev/null
+++ b/crypto/libressl/crypto/o_time.c
@@ -0,0 +1,161 @@
+/* $OpenBSD$ */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2001.
+ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2008.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include "o_time.h"
+
+/* Take a tm structure and add an offset to it. This avoids any OS issues
+ * with restricted date types and overflows which cause the year 2038
+ * problem.
+ */
+
+#define SECS_PER_DAY (24 * 60 * 60)
+
+static long date_to_julian(int y, int m, int d);
+static void julian_to_date(long jd, int *y, int *m, int *d);
+
+int
+OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec)
+{
+	int offset_hms, offset_day;
+	long time_jd;
+	int time_year, time_month, time_day;
+	/* split offset into days and day seconds */
+	offset_day = offset_sec / SECS_PER_DAY;
+	/* Avoid sign issues with % operator */
+	offset_hms = offset_sec - (offset_day * SECS_PER_DAY);
+	offset_day += off_day;
+	/* Add current time seconds to offset */
+	offset_hms += tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec;
+	/* Adjust day seconds if overflow */
+	if (offset_hms >= SECS_PER_DAY) {
+		offset_day++;
+		offset_hms -= SECS_PER_DAY;
+	} else if (offset_hms < 0) {
+		offset_day--;
+		offset_hms += SECS_PER_DAY;
+	}
+
+	/* Convert date of time structure into a Julian day number.
+	 */
+
+	time_year = tm->tm_year + 1900;
+	time_month = tm->tm_mon + 1;
+	time_day = tm->tm_mday;
+
+	time_jd = date_to_julian(time_year, time_month, time_day);
+
+	/* Work out Julian day of new date */
+	time_jd += offset_day;
+
+	if (time_jd < 0)
+		return 0;
+
+	/* Convert Julian day back to date */
+
+	julian_to_date(time_jd, &time_year, &time_month, &time_day);
+
+	if (time_year < 1900 || time_year > 9999)
+		return 0;
+
+	/* Update tm structure */
+
+	tm->tm_year = time_year - 1900;
+	tm->tm_mon = time_month - 1;
+	tm->tm_mday = time_day;
+
+	tm->tm_hour = offset_hms / 3600;
+	tm->tm_min = (offset_hms / 60) % 60;
+	tm->tm_sec = offset_hms % 60;
+
+	return 1;
+
+}
+
+/* Convert date to and from julian day
+ * Uses Fliegel & Van Flandern algorithm
+ */
+static long
+date_to_julian(int y, int m, int d)
+{
+	return (1461 * (y + 4800 + (m - 14) / 12)) / 4 +
+	    (367 * (m - 2 - 12 * ((m - 14) / 12))) / 12 -
+	    (3 * ((y + 4900 + (m - 14) / 12) / 100)) / 4 +
+	    d - 32075;
+}
+
+static void
+julian_to_date(long jd, int *y, int *m, int *d)
+{
+	long  L = jd + 68569;
+	long  n = (4 * L) / 146097;
+	long  i, j;
+
+	L = L - (146097 * n + 3) / 4;
+	i = (4000 * (L + 1)) / 1461001;
+	L = L - (1461 * i) / 4 + 31;
+	j = (80 * L) / 2447;
+	*d = L - (2447 * j) / 80;
+	L = j / 11;
+	*m = j + 2 - (12 * L);
+	*y = 100 * (n - 49) + i + L;
+}
diff --git a/crypto/libressl/crypto/o_time.h b/crypto/libressl/crypto/o_time.h
new file mode 100644
index 0000000000..ea3f5d0cc8
--- /dev/null
+++ b/crypto/libressl/crypto/o_time.h
@@ -0,0 +1,66 @@
+/* $OpenBSD$ */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_O_TIME_H
+#define HEADER_O_TIME_H
+
+#include 
+
+int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec);
+
+#endif
diff --git a/crypto/libressl/crypto/objects/o_names.c b/crypto/libressl/crypto/objects/o_names.c
new file mode 100644
index 0000000000..924fa4a505
--- /dev/null
+++ b/crypto/libressl/crypto/objects/o_names.c
@@ -0,0 +1,354 @@
+/* $OpenBSD: o_names.c,v 1.20 2015/02/10 11:22:21 jsing Exp $ */
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+/* I use the ex_data stuff to manage the identifiers for the obj_name_types
+ * that applications may define.  I only really use the free function field.
+ */
+DECLARE_LHASH_OF(OBJ_NAME);
+static LHASH_OF(OBJ_NAME) *names_lh = NULL;
+static int names_type_num = OBJ_NAME_TYPE_NUM;
+
+typedef struct name_funcs_st {
+	unsigned long (*hash_func)(const char *name);
+	int (*cmp_func)(const char *a, const char *b);
+	void (*free_func)(const char *, int, const char *);
+} NAME_FUNCS;
+
+DECLARE_STACK_OF(NAME_FUNCS)
+
+static STACK_OF(NAME_FUNCS) *name_funcs_stack;
+
+/* The LHASH callbacks now use the raw "void *" prototypes and do per-variable
+ * casting in the functions. This prevents function pointer casting without the
+ * need for macro-generated wrapper functions. */
+
+/* static unsigned long obj_name_hash(OBJ_NAME *a); */
+static unsigned long obj_name_hash(const void *a_void);
+/* static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); */
+static int obj_name_cmp(const void *a_void, const void *b_void);
+
+static IMPLEMENT_LHASH_HASH_FN(obj_name, OBJ_NAME)
+static IMPLEMENT_LHASH_COMP_FN(obj_name, OBJ_NAME)
+
+int
+OBJ_NAME_init(void)
+{
+	if (names_lh != NULL)
+		return (1);
+	names_lh = lh_OBJ_NAME_new();
+	return (names_lh != NULL);
+}
+
+int
+OBJ_NAME_new_index(unsigned long (*hash_func)(const char *),
+    int (*cmp_func)(const char *, const char *),
+    void (*free_func)(const char *, int, const char *))
+{
+	int ret;
+	int i;
+	NAME_FUNCS *name_funcs;
+
+	if (name_funcs_stack == NULL)
+		name_funcs_stack = sk_NAME_FUNCS_new_null();
+	if (name_funcs_stack == NULL)
+		return (0);
+
+	ret = names_type_num;
+	names_type_num++;
+	for (i = sk_NAME_FUNCS_num(name_funcs_stack); i < names_type_num; i++) {
+		name_funcs = malloc(sizeof(NAME_FUNCS));
+		if (!name_funcs) {
+			OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX, ERR_R_MALLOC_FAILURE);
+			return (0);
+		}
+		name_funcs->hash_func = lh_strhash;
+		name_funcs->cmp_func = strcmp;
+		name_funcs->free_func = NULL;
+		if (sk_NAME_FUNCS_push(name_funcs_stack, name_funcs) == 0) {
+			free(name_funcs);
+			OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX, ERR_R_MALLOC_FAILURE);
+			return (0);
+		}
+	}
+	name_funcs = sk_NAME_FUNCS_value(name_funcs_stack, ret);
+	if (hash_func != NULL)
+		name_funcs->hash_func = hash_func;
+	if (cmp_func != NULL)
+		name_funcs->cmp_func = cmp_func;
+	if (free_func != NULL)
+		name_funcs->free_func = free_func;
+	return (ret);
+}
+
+/* static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) */
+static int
+obj_name_cmp(const void *a_void, const void *b_void)
+{
+	int ret;
+	const OBJ_NAME *a = (const OBJ_NAME *)a_void;
+	const OBJ_NAME *b = (const OBJ_NAME *)b_void;
+
+	ret = a->type - b->type;
+	if (ret == 0) {
+		if ((name_funcs_stack != NULL) &&
+		    (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) {
+			ret = sk_NAME_FUNCS_value(name_funcs_stack,
+			    a->type)->cmp_func(a->name, b->name);
+		} else
+			ret = strcmp(a->name, b->name);
+	}
+	return (ret);
+}
+
+/* static unsigned long obj_name_hash(OBJ_NAME *a) */
+static unsigned long
+obj_name_hash(const void *a_void)
+{
+	unsigned long ret;
+	const OBJ_NAME *a = (const OBJ_NAME *)a_void;
+
+	if ((name_funcs_stack != NULL) &&
+	    (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) {
+		ret = sk_NAME_FUNCS_value(name_funcs_stack,
+		    a->type)->hash_func(a->name);
+	} else {
+		ret = lh_strhash(a->name);
+	}
+	ret ^= a->type;
+	return (ret);
+}
+
+const char *
+OBJ_NAME_get(const char *name, int type)
+{
+	OBJ_NAME on, *ret;
+	int num = 0, alias;
+
+	if (name == NULL)
+		return (NULL);
+	if ((names_lh == NULL) && !OBJ_NAME_init())
+		return (NULL);
+
+	alias = type&OBJ_NAME_ALIAS;
+	type&= ~OBJ_NAME_ALIAS;
+
+	on.name = name;
+	on.type = type;
+
+	for (;;) {
+		ret = lh_OBJ_NAME_retrieve(names_lh, &on);
+		if (ret == NULL)
+			return (NULL);
+		if ((ret->alias) && !alias) {
+			if (++num > 10)
+				return (NULL);
+			on.name = ret->data;
+		} else {
+			return (ret->data);
+		}
+	}
+}
+
+int
+OBJ_NAME_add(const char *name, int type, const char *data)
+{
+	OBJ_NAME *onp, *ret;
+	int alias;
+
+	if ((names_lh == NULL) && !OBJ_NAME_init())
+		return (0);
+
+	alias = type & OBJ_NAME_ALIAS;
+	type &= ~OBJ_NAME_ALIAS;
+
+	onp = malloc(sizeof(OBJ_NAME));
+	if (onp == NULL) {
+		/* ERROR */
+		return (0);
+	}
+
+	onp->name = name;
+	onp->alias = alias;
+	onp->type = type;
+	onp->data = data;
+
+	ret = lh_OBJ_NAME_insert(names_lh, onp);
+	if (ret != NULL) {
+		/* free things */
+		if ((name_funcs_stack != NULL) &&
+		    (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) {
+			/* XXX: I'm not sure I understand why the free
+			 * function should get three arguments...
+			 * -- Richard Levitte
+			 */
+			sk_NAME_FUNCS_value(
+			    name_funcs_stack, ret->type)->free_func(
+			    ret->name, ret->type, ret->data);
+		}
+		free(ret);
+	} else {
+		if (lh_OBJ_NAME_error(names_lh)) {
+			/* ERROR */
+			return (0);
+		}
+	}
+	return (1);
+}
+
+int
+OBJ_NAME_remove(const char *name, int type)
+{
+	OBJ_NAME on, *ret;
+
+	if (names_lh == NULL)
+		return (0);
+
+	type &= ~OBJ_NAME_ALIAS;
+	on.name = name;
+	on.type = type;
+	ret = lh_OBJ_NAME_delete(names_lh, &on);
+	if (ret != NULL) {
+		/* free things */
+		if ((name_funcs_stack != NULL) &&
+		    (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) {
+			/* XXX: I'm not sure I understand why the free
+			 * function should get three arguments...
+			 * -- Richard Levitte
+			 */
+			sk_NAME_FUNCS_value(
+			    name_funcs_stack, ret->type)->free_func(
+			    ret->name, ret->type, ret->data);
+		}
+		free(ret);
+		return (1);
+	} else
+		return (0);
+}
+
+struct doall {
+	int type;
+	void (*fn)(const OBJ_NAME *, void *arg);
+	void *arg;
+};
+
+static void
+do_all_fn_doall_arg(const OBJ_NAME *name, struct doall *d)
+{
+	if (name->type == d->type)
+		d->fn(name, d->arg);
+}
+
+static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME, struct doall)
+
+void
+OBJ_NAME_do_all(int type, void (*fn)(const OBJ_NAME *, void *arg), void *arg)
+{
+	struct doall d;
+
+	d.type = type;
+	d.fn = fn;
+	d.arg = arg;
+
+	lh_OBJ_NAME_doall_arg(names_lh, LHASH_DOALL_ARG_FN(do_all_fn),
+	    struct doall, &d);
+}
+
+struct doall_sorted {
+	int type;
+	int n;
+	const OBJ_NAME **names;
+};
+
+static void
+do_all_sorted_fn(const OBJ_NAME *name, void *d_)
+{
+	struct doall_sorted *d = d_;
+
+	if (name->type != d->type)
+		return;
+
+	d->names[d->n++] = name;
+}
+
+static int
+do_all_sorted_cmp(const void *n1_, const void *n2_)
+{
+	const OBJ_NAME * const *n1 = n1_;
+	const OBJ_NAME * const *n2 = n2_;
+
+	return strcmp((*n1)->name, (*n2)->name);
+}
+
+void
+OBJ_NAME_do_all_sorted(int type, void (*fn)(const OBJ_NAME *, void *arg),
+    void *arg)
+{
+	struct doall_sorted d;
+	int n;
+
+	d.type = type;
+	d.names = reallocarray(NULL, lh_OBJ_NAME_num_items(names_lh),
+	    sizeof *d.names);
+	d.n = 0;
+	if (d.names != NULL) {
+		OBJ_NAME_do_all(type, do_all_sorted_fn, &d);
+
+		qsort((void *)d.names, d.n, sizeof *d.names, do_all_sorted_cmp);
+
+		for (n = 0; n < d.n; ++n)
+			fn(d.names[n], arg);
+
+		free(d.names);
+	}
+}
+
+static int free_type;
+
+static void
+names_lh_free_doall(OBJ_NAME *onp)
+{
+	if (onp == NULL)
+		return;
+
+	if (free_type < 0 || free_type == onp->type)
+		OBJ_NAME_remove(onp->name, onp->type);
+}
+
+static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME)
+
+static void
+name_funcs_free(NAME_FUNCS *ptr)
+{
+	free(ptr);
+}
+
+void
+OBJ_NAME_cleanup(int type)
+{
+	unsigned long down_load;
+
+	if (names_lh == NULL)
+		return;
+
+	free_type = type;
+	down_load = lh_OBJ_NAME_down_load(names_lh);
+	lh_OBJ_NAME_down_load(names_lh) = 0;
+
+	lh_OBJ_NAME_doall(names_lh, LHASH_DOALL_FN(names_lh_free));
+	if (type < 0) {
+		lh_OBJ_NAME_free(names_lh);
+		sk_NAME_FUNCS_pop_free(name_funcs_stack, name_funcs_free);
+		names_lh = NULL;
+		name_funcs_stack = NULL;
+	} else
+		lh_OBJ_NAME_down_load(names_lh) = down_load;
+}
diff --git a/crypto/libressl/crypto/objects/obj_dat.c b/crypto/libressl/crypto/objects/obj_dat.c
new file mode 100644
index 0000000000..e755d0b2e0
--- /dev/null
+++ b/crypto/libressl/crypto/objects/obj_dat.c
@@ -0,0 +1,773 @@
+/* $OpenBSD: obj_dat.c,v 1.35 2015/10/14 21:54:10 tedu Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* obj_dat.h is generated from objects.h by obj_dat.pl */
+#include "obj_dat.h"
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
+DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
+DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
+
+#define ADDED_DATA	0
+#define ADDED_SNAME	1
+#define ADDED_LNAME	2
+#define ADDED_NID	3
+
+typedef struct added_obj_st {
+	int type;
+	ASN1_OBJECT *obj;
+} ADDED_OBJ;
+DECLARE_LHASH_OF(ADDED_OBJ);
+
+static int new_nid = NUM_NID;
+static LHASH_OF(ADDED_OBJ) *added = NULL;
+
+static int sn_cmp(const ASN1_OBJECT * const *a, const unsigned int *b)
+{
+	return (strcmp((*a)->sn, nid_objs[*b].sn));
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
+
+static int ln_cmp(const ASN1_OBJECT * const *a, const unsigned int *b)
+{
+	return (strcmp((*a)->ln, nid_objs[*b].ln));
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
+
+static unsigned long
+added_obj_hash(const ADDED_OBJ *ca)
+{
+	const ASN1_OBJECT *a;
+	int i;
+	unsigned long ret = 0;
+	unsigned char *p;
+
+	a = ca->obj;
+	switch (ca->type) {
+	case ADDED_DATA:
+		ret = a->length << 20L;
+		p = (unsigned char *)a->data;
+		for (i = 0; i < a->length; i++)
+			ret ^= p[i] << ((i * 3) % 24);
+		break;
+	case ADDED_SNAME:
+		ret = lh_strhash(a->sn);
+		break;
+	case ADDED_LNAME:
+		ret = lh_strhash(a->ln);
+		break;
+	case ADDED_NID:
+		ret = a->nid;
+		break;
+	default:
+		/* abort(); */
+		return 0;
+	}
+	ret &= 0x3fffffffL;
+	ret |= ca->type << 30L;
+	return (ret);
+}
+static IMPLEMENT_LHASH_HASH_FN(added_obj, ADDED_OBJ)
+
+static int
+added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb)
+{
+	ASN1_OBJECT *a, *b;
+	int i;
+
+	i = ca->type - cb->type;
+	if (i)
+		return (i);
+	a = ca->obj;
+	b = cb->obj;
+	switch (ca->type) {
+	case ADDED_DATA:
+		i = (a->length - b->length);
+		if (i)
+			return (i);
+		return (memcmp(a->data, b->data, (size_t)a->length));
+	case ADDED_SNAME:
+		if (a->sn == NULL)
+			return (-1);
+		else if (b->sn == NULL)
+			return (1);
+		else
+			return (strcmp(a->sn, b->sn));
+	case ADDED_LNAME:
+		if (a->ln == NULL)
+			return (-1);
+		else if (b->ln == NULL)
+			return (1);
+		else
+			return (strcmp(a->ln, b->ln));
+	case ADDED_NID:
+		return (a->nid - b->nid);
+	default:
+		/* abort(); */
+		return 0;
+	}
+}
+static IMPLEMENT_LHASH_COMP_FN(added_obj, ADDED_OBJ)
+
+static int
+init_added(void)
+{
+	if (added != NULL)
+		return (1);
+	added = lh_ADDED_OBJ_new();
+	return (added != NULL);
+}
+
+static void
+cleanup1_doall(ADDED_OBJ *a)
+{
+	a->obj->nid = 0;
+	a->obj->flags |= ASN1_OBJECT_FLAG_DYNAMIC |
+	    ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
+	    ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+}
+
+static void cleanup2_doall(ADDED_OBJ *a)
+{
+	a->obj->nid++;
+}
+
+static void
+cleanup3_doall(ADDED_OBJ *a)
+{
+	if (--a->obj->nid == 0)
+		ASN1_OBJECT_free(a->obj);
+	free(a);
+}
+
+static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ)
+static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ)
+static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ)
+
+/* The purpose of obj_cleanup_defer is to avoid EVP_cleanup() attempting
+ * to use freed up OIDs. If neccessary the actual freeing up of OIDs is
+ * delayed.
+ */
+
+int obj_cleanup_defer = 0;
+
+void
+check_defer(int nid)
+{
+	if (!obj_cleanup_defer && nid >= NUM_NID)
+		obj_cleanup_defer = 1;
+}
+
+void
+OBJ_cleanup(void)
+{
+	if (obj_cleanup_defer) {
+		obj_cleanup_defer = 2;
+		return;
+	}
+	if (added == NULL)
+		return;
+	lh_ADDED_OBJ_down_load(added) = 0;
+	lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup1)); /* zero counters */
+	lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup2)); /* set counters */
+	lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup3)); /* free objects */
+	lh_ADDED_OBJ_free(added);
+	added = NULL;
+}
+
+int
+OBJ_new_nid(int num)
+{
+	int i;
+
+	i = new_nid;
+	new_nid += num;
+	return (i);
+}
+
+int
+OBJ_add_object(const ASN1_OBJECT *obj)
+{
+	ASN1_OBJECT *o;
+	ADDED_OBJ *ao[4] = {NULL, NULL, NULL, NULL}, *aop;
+	int i;
+
+	if (added == NULL)
+		if (!init_added())
+			return (0);
+	if ((o = OBJ_dup(obj)) == NULL)
+		goto err;
+	if (!(ao[ADDED_NID] = malloc(sizeof(ADDED_OBJ))))
+		goto err2;
+	if ((o->length != 0) && (obj->data != NULL))
+		if (!(ao[ADDED_DATA] = malloc(sizeof(ADDED_OBJ))))
+			goto err2;
+	if (o->sn != NULL)
+		if (!(ao[ADDED_SNAME] = malloc(sizeof(ADDED_OBJ))))
+			goto err2;
+	if (o->ln != NULL)
+		if (!(ao[ADDED_LNAME] = malloc(sizeof(ADDED_OBJ))))
+			goto err2;
+
+	for (i = ADDED_DATA; i <= ADDED_NID; i++) {
+		if (ao[i] != NULL) {
+			ao[i]->type = i;
+			ao[i]->obj = o;
+			aop = lh_ADDED_OBJ_insert(added, ao[i]);
+			/* memory leak, buit should not normally matter */
+			free(aop);
+		}
+	}
+	o->flags &= ~(ASN1_OBJECT_FLAG_DYNAMIC |
+	    ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
+	    ASN1_OBJECT_FLAG_DYNAMIC_DATA);
+
+	return (o->nid);
+
+err2:
+	OBJerr(OBJ_F_OBJ_ADD_OBJECT, ERR_R_MALLOC_FAILURE);
+err:
+	for (i = ADDED_DATA; i <= ADDED_NID; i++)
+		free(ao[i]);
+	free(o);
+	return (NID_undef);
+}
+
+ASN1_OBJECT *
+OBJ_nid2obj(int n)
+{
+	ADDED_OBJ ad, *adp;
+	ASN1_OBJECT ob;
+
+	if ((n >= 0) && (n < NUM_NID)) {
+		if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
+			OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID);
+			return (NULL);
+		}
+		return ((ASN1_OBJECT *)&(nid_objs[n]));
+	} else if (added == NULL)
+		return (NULL);
+	else {
+		ad.type = ADDED_NID;
+		ad.obj = &ob;
+		ob.nid = n;
+		adp = lh_ADDED_OBJ_retrieve(added, &ad);
+		if (adp != NULL)
+			return (adp->obj);
+		else {
+			OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID);
+			return (NULL);
+		}
+	}
+}
+
+const char *
+OBJ_nid2sn(int n)
+{
+	ADDED_OBJ ad, *adp;
+	ASN1_OBJECT ob;
+
+	if ((n >= 0) && (n < NUM_NID)) {
+		if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
+			OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID);
+			return (NULL);
+		}
+		return (nid_objs[n].sn);
+	} else if (added == NULL)
+		return (NULL);
+	else {
+		ad.type = ADDED_NID;
+		ad.obj = &ob;
+		ob.nid = n;
+		adp = lh_ADDED_OBJ_retrieve(added, &ad);
+		if (adp != NULL)
+			return (adp->obj->sn);
+		else {
+			OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID);
+			return (NULL);
+		}
+	}
+}
+
+const char *
+OBJ_nid2ln(int n)
+{
+	ADDED_OBJ ad, *adp;
+	ASN1_OBJECT ob;
+
+	if ((n >= 0) && (n < NUM_NID)) {
+		if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
+			OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID);
+			return (NULL);
+		}
+		return (nid_objs[n].ln);
+	} else if (added == NULL)
+		return (NULL);
+	else {
+		ad.type = ADDED_NID;
+		ad.obj = &ob;
+		ob.nid = n;
+		adp = lh_ADDED_OBJ_retrieve(added, &ad);
+		if (adp != NULL)
+			return (adp->obj->ln);
+		else {
+			OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID);
+			return (NULL);
+		}
+	}
+}
+
+static int
+obj_cmp(const ASN1_OBJECT * const *ap, const unsigned int *bp)
+{
+	int j;
+	const ASN1_OBJECT *a= *ap;
+	const ASN1_OBJECT *b = &nid_objs[*bp];
+
+	j = (a->length - b->length);
+	if (j)
+		return (j);
+	return (memcmp(a->data, b->data, a->length));
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
+
+int
+OBJ_obj2nid(const ASN1_OBJECT *a)
+{
+	const unsigned int *op;
+	ADDED_OBJ ad, *adp;
+
+	if (a == NULL)
+		return (NID_undef);
+	if (a->nid != 0)
+		return (a->nid);
+
+	if (added != NULL) {
+		ad.type = ADDED_DATA;
+		ad.obj=(ASN1_OBJECT *)a; /* XXX: ugly but harmless */
+		adp = lh_ADDED_OBJ_retrieve(added, &ad);
+		if (adp != NULL)
+			return (adp->obj->nid);
+	}
+	op = OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ);
+	if (op == NULL)
+		return (NID_undef);
+	return (nid_objs[*op].nid);
+}
+
+/* Convert an object name into an ASN1_OBJECT
+ * if "noname" is not set then search for short and long names first.
+ * This will convert the "dotted" form into an object: unlike OBJ_txt2nid
+ * it can be used with any objects, not just registered ones.
+ */
+
+ASN1_OBJECT *
+OBJ_txt2obj(const char *s, int no_name)
+{
+	int nid = NID_undef;
+	ASN1_OBJECT *op = NULL;
+	unsigned char *buf;
+	unsigned char *p;
+	const unsigned char *cp;
+	int i, j;
+
+	if (!no_name) {
+		if (((nid = OBJ_sn2nid(s)) != NID_undef) ||
+		    ((nid = OBJ_ln2nid(s)) != NID_undef) )
+			return OBJ_nid2obj(nid);
+	}
+
+	/* Work out size of content octets */
+	i = a2d_ASN1_OBJECT(NULL, 0, s, -1);
+	if (i <= 0) {
+		/* Don't clear the error */
+		/*ERR_clear_error();*/
+		return NULL;
+	}
+	/* Work out total size */
+	j = ASN1_object_size(0, i, V_ASN1_OBJECT);
+
+	if ((buf = malloc(j)) == NULL)
+		return NULL;
+
+	p = buf;
+	/* Write out tag+length */
+	ASN1_put_object(&p, 0, i, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
+	/* Write out contents */
+	a2d_ASN1_OBJECT(p, i, s, -1);
+
+	cp = buf;
+	op = d2i_ASN1_OBJECT(NULL, &cp, j);
+	free(buf);
+	return op;
+}
+
+int
+OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
+{
+	int i, ret = 0, len, nid, first = 1, use_bn;
+	BIGNUM *bl = NULL;
+	unsigned long l;
+	const unsigned char *p;
+
+	/* Ensure that, at every state, |buf| is NUL-terminated. */
+	if (buf_len > 0)
+		buf[0] = '\0';
+
+	if ((a == NULL) || (a->data == NULL))
+		goto err;
+
+	if (!no_name && (nid = OBJ_obj2nid(a)) != NID_undef) {
+		const char *s;
+		s = OBJ_nid2ln(nid);
+		if (s == NULL)
+			s = OBJ_nid2sn(nid);
+		if (s) {
+			ret = strlcpy(buf, s, buf_len);
+			goto out;
+		}
+	}
+
+	len = a->length;
+	p = a->data;
+
+	while (len > 0) {
+		l = 0;
+		use_bn = 0;
+		for (;;) {
+			unsigned char c = *p++;
+			len--;
+			if ((len == 0) && (c & 0x80))
+				goto err;
+			if (use_bn) {
+				if (!BN_add_word(bl, c & 0x7f))
+					goto err;
+			} else
+				l |= c & 0x7f;
+			if (!(c & 0x80))
+				break;
+			if (!use_bn && (l > (ULONG_MAX >> 7L))) {
+				if (!bl && !(bl = BN_new()))
+					goto err;
+				if (!BN_set_word(bl, l))
+					goto err;
+				use_bn = 1;
+			}
+			if (use_bn) {
+				if (!BN_lshift(bl, bl, 7))
+					goto err;
+			} else
+				l <<= 7L;
+		}
+
+		if (first) {
+			first = 0;
+			if (l >= 80) {
+				i = 2;
+				if (use_bn) {
+					if (!BN_sub_word(bl, 80))
+						goto err;
+				} else
+					l -= 80;
+			} else {
+				i = (int)(l / 40);
+				l -= (long)(i * 40);
+			}
+			if (buf_len > 1) {
+				*buf++ = i + '0';
+				*buf = '\0';
+				buf_len--;
+			}
+			ret++;
+		}
+
+		if (buf_len <= 0) {
+			ret = 0;
+			goto out;
+		}
+		if (use_bn) {
+			char *bndec;
+
+			bndec = BN_bn2dec(bl);
+			if (!bndec)
+				goto err;
+			i = snprintf(buf, buf_len, ".%s", bndec);
+			free(bndec);
+			if (i == -1)
+				goto err;
+			if (i >= buf_len) {
+				buf_len = 0;
+			} else {
+				buf += i;
+				buf_len -= i;
+			}
+			ret += i;
+		} else {
+			i = snprintf(buf, buf_len, ".%lu", l);
+			if (i == -1)
+				goto err;
+			if (i >= buf_len) {
+				buf_len = 0;
+			} else {
+				buf += i;
+				buf_len -= i;
+			}
+			ret += i;
+			l = 0;
+		}
+	}
+
+out:
+	BN_free(bl);
+	return ret;
+
+err:
+	ret = 0;
+	goto out;
+}
+
+int
+OBJ_txt2nid(const char *s)
+{
+	ASN1_OBJECT *obj;
+	int nid;
+
+	obj = OBJ_txt2obj(s, 0);
+	nid = OBJ_obj2nid(obj);
+	ASN1_OBJECT_free(obj);
+	return nid;
+}
+
+int
+OBJ_ln2nid(const char *s)
+{
+	ASN1_OBJECT o;
+	const ASN1_OBJECT *oo = &o;
+	ADDED_OBJ ad, *adp;
+	const unsigned int *op;
+
+	o.ln = s;
+	if (added != NULL) {
+		ad.type = ADDED_LNAME;
+		ad.obj = &o;
+		adp = lh_ADDED_OBJ_retrieve(added, &ad);
+		if (adp != NULL)
+			return (adp->obj->nid);
+	}
+	op = OBJ_bsearch_ln(&oo, ln_objs, NUM_LN);
+	if (op == NULL)
+		return (NID_undef);
+	return (nid_objs[*op].nid);
+}
+
+int
+OBJ_sn2nid(const char *s)
+{
+	ASN1_OBJECT o;
+	const ASN1_OBJECT *oo = &o;
+	ADDED_OBJ ad, *adp;
+	const unsigned int *op;
+
+	o.sn = s;
+	if (added != NULL) {
+		ad.type = ADDED_SNAME;
+		ad.obj = &o;
+		adp = lh_ADDED_OBJ_retrieve(added, &ad);
+		if (adp != NULL)
+			return (adp->obj->nid);
+	}
+	op = OBJ_bsearch_sn(&oo, sn_objs, NUM_SN);
+	if (op == NULL)
+		return (NID_undef);
+	return (nid_objs[*op].nid);
+}
+
+const void *
+OBJ_bsearch_(const void *key, const void *base, int num, int size,
+    int (*cmp)(const void *, const void *))
+{
+	return OBJ_bsearch_ex_(key, base, num, size, cmp, 0);
+}
+
+const void *
+OBJ_bsearch_ex_(const void *key, const void *base_, int num, int size,
+    int (*cmp)(const void *, const void *), int flags)
+{
+	const char *base = base_;
+	int l, h, i = 0, c = 0;
+	const char *p = NULL;
+
+	if (num == 0)
+		return (NULL);
+	l = 0;
+	h = num;
+	while (l < h) {
+		i = (l + h) / 2;
+		p = &(base[i * size]);
+		c = (*cmp)(key, p);
+		if (c < 0)
+			h = i;
+		else if (c > 0)
+			l = i + 1;
+		else
+			break;
+	}
+	if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))
+		p = NULL;
+	else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH)) {
+		while (i > 0 && (*cmp)(key, &(base[(i - 1) * size])) == 0)
+			i--;
+		p = &(base[i * size]);
+	}
+	return (p);
+}
+
+int
+OBJ_create_objects(BIO *in)
+{
+	char buf[512];
+	int i, num = 0;
+	char *o, *s, *l = NULL;
+
+	for (;;) {
+		s = o = NULL;
+		i = BIO_gets(in, buf, 512);
+		if (i <= 0)
+			return (num);
+		buf[i - 1] = '\0';
+		if (!isalnum((unsigned char)buf[0]))
+			return (num);
+		o = s=buf;
+		while (isdigit((unsigned char)*s) || (*s == '.'))
+			s++;
+		if (*s != '\0') {
+			*(s++) = '\0';
+			while (isspace((unsigned char)*s))
+				s++;
+			if (*s == '\0')
+				s = NULL;
+			else {
+				l = s;
+				while ((*l != '\0') &&
+				    !isspace((unsigned char)*l))
+					l++;
+				if (*l != '\0') {
+					*(l++) = '\0';
+					while (isspace((unsigned char)*l))
+						l++;
+					if (*l == '\0')
+						l = NULL;
+				} else
+					l = NULL;
+			}
+		} else
+			s = NULL;
+		if ((o == NULL) || (*o == '\0'))
+			return (num);
+		if (!OBJ_create(o, s, l))
+			return (num);
+		num++;
+	}
+	/* return(num); */
+}
+
+int
+OBJ_create(const char *oid, const char *sn, const char *ln)
+{
+	int ok = 0;
+	ASN1_OBJECT *op = NULL;
+	unsigned char *buf;
+	int i;
+
+	i = a2d_ASN1_OBJECT(NULL, 0, oid, -1);
+	if (i <= 0)
+		return (0);
+
+	if ((buf = malloc(i)) == NULL) {
+		OBJerr(OBJ_F_OBJ_CREATE, ERR_R_MALLOC_FAILURE);
+		return (0);
+	}
+	i = a2d_ASN1_OBJECT(buf, i, oid, -1);
+	if (i == 0)
+		goto err;
+	op = (ASN1_OBJECT *)ASN1_OBJECT_create(OBJ_new_nid(1), buf, i, sn, ln);
+	if (op == NULL)
+		goto err;
+	ok = OBJ_add_object(op);
+
+err:
+	ASN1_OBJECT_free(op);
+	free(buf);
+	return (ok);
+}
diff --git a/crypto/libressl/crypto/objects/obj_dat.h b/crypto/libressl/crypto/objects/obj_dat.h
new file mode 100644
index 0000000000..fdb826ab30
--- /dev/null
+++ b/crypto/libressl/crypto/objects/obj_dat.h
@@ -0,0 +1,5266 @@
+/* crypto/objects/obj_dat.h */
+
+/* THIS FILE IS GENERATED FROM objects.h by obj_dat.pl via the
+ * following command:
+ * perl obj_dat.pl obj_mac.h obj_dat.h
+ */
+
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#define NUM_NID 950
+#define NUM_SN 943
+#define NUM_LN 943
+#define NUM_OBJ 884
+
+static const unsigned char lvalues[6199]={
+0x2A,0x86,0x48,0x86,0xF7,0x0D,               /* [  0] OBJ_rsadsi */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,          /* [  6] OBJ_pkcs */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02,     /* [ 13] OBJ_md2 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x05,     /* [ 21] OBJ_md5 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x04,     /* [ 29] OBJ_rc4 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,/* [ 37] OBJ_rsaEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x02,/* [ 46] OBJ_md2WithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,/* [ 55] OBJ_md5WithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x01,/* [ 64] OBJ_pbeWithMD2AndDES_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x03,/* [ 73] OBJ_pbeWithMD5AndDES_CBC */
+0x55,                                        /* [ 82] OBJ_X500 */
+0x55,0x04,                                   /* [ 83] OBJ_X509 */
+0x55,0x04,0x03,                              /* [ 85] OBJ_commonName */
+0x55,0x04,0x06,                              /* [ 88] OBJ_countryName */
+0x55,0x04,0x07,                              /* [ 91] OBJ_localityName */
+0x55,0x04,0x08,                              /* [ 94] OBJ_stateOrProvinceName */
+0x55,0x04,0x0A,                              /* [ 97] OBJ_organizationName */
+0x55,0x04,0x0B,                              /* [100] OBJ_organizationalUnitName */
+0x55,0x08,0x01,0x01,                         /* [103] OBJ_rsa */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,     /* [107] OBJ_pkcs7 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x01,/* [115] OBJ_pkcs7_data */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x02,/* [124] OBJ_pkcs7_signed */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x03,/* [133] OBJ_pkcs7_enveloped */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x04,/* [142] OBJ_pkcs7_signedAndEnveloped */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x05,/* [151] OBJ_pkcs7_digest */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x06,/* [160] OBJ_pkcs7_encrypted */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03,     /* [169] OBJ_pkcs3 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03,0x01,/* [177] OBJ_dhKeyAgreement */
+0x2B,0x0E,0x03,0x02,0x06,                    /* [186] OBJ_des_ecb */
+0x2B,0x0E,0x03,0x02,0x09,                    /* [191] OBJ_des_cfb64 */
+0x2B,0x0E,0x03,0x02,0x07,                    /* [196] OBJ_des_cbc */
+0x2B,0x0E,0x03,0x02,0x11,                    /* [201] OBJ_des_ede_ecb */
+0x2B,0x06,0x01,0x04,0x01,0x81,0x3C,0x07,0x01,0x01,0x02,/* [206] OBJ_idea_cbc */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x02,     /* [217] OBJ_rc2_cbc */
+0x2B,0x0E,0x03,0x02,0x12,                    /* [225] OBJ_sha */
+0x2B,0x0E,0x03,0x02,0x0F,                    /* [230] OBJ_shaWithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x07,     /* [235] OBJ_des_ede3_cbc */
+0x2B,0x0E,0x03,0x02,0x08,                    /* [243] OBJ_des_ofb64 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,     /* [248] OBJ_pkcs9 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,/* [256] OBJ_pkcs9_emailAddress */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x02,/* [265] OBJ_pkcs9_unstructuredName */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x03,/* [274] OBJ_pkcs9_contentType */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x04,/* [283] OBJ_pkcs9_messageDigest */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x05,/* [292] OBJ_pkcs9_signingTime */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x06,/* [301] OBJ_pkcs9_countersignature */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x07,/* [310] OBJ_pkcs9_challengePassword */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x08,/* [319] OBJ_pkcs9_unstructuredAddress */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x09,/* [328] OBJ_pkcs9_extCertAttributes */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,          /* [337] OBJ_netscape */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,     /* [344] OBJ_netscape_cert_extension */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02,     /* [352] OBJ_netscape_data_type */
+0x2B,0x0E,0x03,0x02,0x1A,                    /* [360] OBJ_sha1 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,/* [365] OBJ_sha1WithRSAEncryption */
+0x2B,0x0E,0x03,0x02,0x0D,                    /* [374] OBJ_dsaWithSHA */
+0x2B,0x0E,0x03,0x02,0x0C,                    /* [379] OBJ_dsa_2 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0B,/* [384] OBJ_pbeWithSHA1AndRC2_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0C,/* [393] OBJ_id_pbkdf2 */
+0x2B,0x0E,0x03,0x02,0x1B,                    /* [402] OBJ_dsaWithSHA1_2 */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,/* [407] OBJ_netscape_cert_type */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x02,/* [416] OBJ_netscape_base_url */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x03,/* [425] OBJ_netscape_revocation_url */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x04,/* [434] OBJ_netscape_ca_revocation_url */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x07,/* [443] OBJ_netscape_renewal_url */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x08,/* [452] OBJ_netscape_ca_policy_url */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0C,/* [461] OBJ_netscape_ssl_server_name */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0D,/* [470] OBJ_netscape_comment */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02,0x05,/* [479] OBJ_netscape_cert_sequence */
+0x55,0x1D,                                   /* [488] OBJ_id_ce */
+0x55,0x1D,0x0E,                              /* [490] OBJ_subject_key_identifier */
+0x55,0x1D,0x0F,                              /* [493] OBJ_key_usage */
+0x55,0x1D,0x10,                              /* [496] OBJ_private_key_usage_period */
+0x55,0x1D,0x11,                              /* [499] OBJ_subject_alt_name */
+0x55,0x1D,0x12,                              /* [502] OBJ_issuer_alt_name */
+0x55,0x1D,0x13,                              /* [505] OBJ_basic_constraints */
+0x55,0x1D,0x14,                              /* [508] OBJ_crl_number */
+0x55,0x1D,0x20,                              /* [511] OBJ_certificate_policies */
+0x55,0x1D,0x23,                              /* [514] OBJ_authority_key_identifier */
+0x2B,0x06,0x01,0x04,0x01,0x97,0x55,0x01,0x02,/* [517] OBJ_bf_cbc */
+0x55,0x08,0x03,0x65,                         /* [526] OBJ_mdc2 */
+0x55,0x08,0x03,0x64,                         /* [530] OBJ_mdc2WithRSA */
+0x55,0x04,0x2A,                              /* [534] OBJ_givenName */
+0x55,0x04,0x04,                              /* [537] OBJ_surname */
+0x55,0x04,0x2B,                              /* [540] OBJ_initials */
+0x55,0x1D,0x1F,                              /* [543] OBJ_crl_distribution_points */
+0x2B,0x0E,0x03,0x02,0x03,                    /* [546] OBJ_md5WithRSA */
+0x55,0x04,0x05,                              /* [551] OBJ_serialNumber */
+0x55,0x04,0x0C,                              /* [554] OBJ_title */
+0x55,0x04,0x0D,                              /* [557] OBJ_description */
+0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0A,/* [560] OBJ_cast5_cbc */
+0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0C,/* [569] OBJ_pbeWithMD5AndCast5_CBC */
+0x2A,0x86,0x48,0xCE,0x38,0x04,0x03,          /* [578] OBJ_dsaWithSHA1 */
+0x2B,0x0E,0x03,0x02,0x1D,                    /* [585] OBJ_sha1WithRSA */
+0x2A,0x86,0x48,0xCE,0x38,0x04,0x01,          /* [590] OBJ_dsa */
+0x2B,0x24,0x03,0x02,0x01,                    /* [597] OBJ_ripemd160 */
+0x2B,0x24,0x03,0x03,0x01,0x02,               /* [602] OBJ_ripemd160WithRSA */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x08,     /* [608] OBJ_rc5_cbc */
+0x29,0x01,0x01,0x85,0x1A,0x01,               /* [616] OBJ_rle_compression */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x08,/* [622] OBJ_zlib_compression */
+0x55,0x1D,0x25,                              /* [633] OBJ_ext_key_usage */
+0x2B,0x06,0x01,0x05,0x05,0x07,               /* [636] OBJ_id_pkix */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,          /* [642] OBJ_id_kp */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,     /* [649] OBJ_server_auth */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,     /* [657] OBJ_client_auth */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x03,     /* [665] OBJ_code_sign */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x04,     /* [673] OBJ_email_protect */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x08,     /* [681] OBJ_time_stamp */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x15,/* [689] OBJ_ms_code_ind */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x16,/* [699] OBJ_ms_code_com */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x01,/* [709] OBJ_ms_ctl_sign */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x03,/* [719] OBJ_ms_sgc */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x04,/* [729] OBJ_ms_efs */
+0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,/* [739] OBJ_ns_sgc */
+0x55,0x1D,0x1B,                              /* [748] OBJ_delta_crl */
+0x55,0x1D,0x15,                              /* [751] OBJ_crl_reason */
+0x55,0x1D,0x18,                              /* [754] OBJ_invalidity_date */
+0x2B,0x65,0x01,0x04,0x01,                    /* [757] OBJ_sxnet */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x01,/* [762] OBJ_pbe_WithSHA1And128BitRC4 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x02,/* [772] OBJ_pbe_WithSHA1And40BitRC4 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x03,/* [782] OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x04,/* [792] OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x05,/* [802] OBJ_pbe_WithSHA1And128BitRC2_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x06,/* [812] OBJ_pbe_WithSHA1And40BitRC2_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x01,/* [822] OBJ_keyBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x02,/* [833] OBJ_pkcs8ShroudedKeyBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x03,/* [844] OBJ_certBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x04,/* [855] OBJ_crlBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x05,/* [866] OBJ_secretBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x06,/* [877] OBJ_safeContentsBag */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x14,/* [888] OBJ_friendlyName */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x15,/* [897] OBJ_localKeyID */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x01,/* [906] OBJ_x509Certificate */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x02,/* [916] OBJ_sdsiCertificate */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x17,0x01,/* [926] OBJ_x509Crl */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0D,/* [936] OBJ_pbes2 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0E,/* [945] OBJ_pbmac1 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x07,     /* [954] OBJ_hmacWithSHA1 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,     /* [962] OBJ_id_qt_cps */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02,     /* [970] OBJ_id_qt_unotice */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0F,/* [978] OBJ_SMIMECapabilities */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x04,/* [987] OBJ_pbeWithMD2AndRC2_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x06,/* [996] OBJ_pbeWithMD5AndRC2_CBC */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0A,/* [1005] OBJ_pbeWithSHA1AndDES_CBC */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x0E,/* [1014] OBJ_ms_ext_req */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0E,/* [1024] OBJ_ext_req */
+0x55,0x04,0x29,                              /* [1033] OBJ_name */
+0x55,0x04,0x2E,                              /* [1036] OBJ_dnQualifier */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,          /* [1039] OBJ_id_pe */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,          /* [1046] OBJ_id_ad */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,     /* [1053] OBJ_info_access */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,     /* [1061] OBJ_ad_OCSP */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,     /* [1069] OBJ_ad_ca_issuers */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x09,     /* [1077] OBJ_OCSP_sign */
+0x2A,                                        /* [1085] OBJ_member_body */
+0x2A,0x86,0x48,                              /* [1086] OBJ_ISO_US */
+0x2A,0x86,0x48,0xCE,0x38,                    /* [1089] OBJ_X9_57 */
+0x2A,0x86,0x48,0xCE,0x38,0x04,               /* [1094] OBJ_X9cm */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,     /* [1100] OBJ_pkcs1 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,     /* [1108] OBJ_pkcs5 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,/* [1116] OBJ_SMIME */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,/* [1125] OBJ_id_smime_mod */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,/* [1135] OBJ_id_smime_ct */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,/* [1145] OBJ_id_smime_aa */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,/* [1155] OBJ_id_smime_alg */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,/* [1165] OBJ_id_smime_cd */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,/* [1175] OBJ_id_smime_spq */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,/* [1185] OBJ_id_smime_cti */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x01,/* [1195] OBJ_id_smime_mod_cms */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x02,/* [1206] OBJ_id_smime_mod_ess */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x03,/* [1217] OBJ_id_smime_mod_oid */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x04,/* [1228] OBJ_id_smime_mod_msg_v3 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x05,/* [1239] OBJ_id_smime_mod_ets_eSignature_88 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x06,/* [1250] OBJ_id_smime_mod_ets_eSignature_97 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x07,/* [1261] OBJ_id_smime_mod_ets_eSigPolicy_88 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x08,/* [1272] OBJ_id_smime_mod_ets_eSigPolicy_97 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x01,/* [1283] OBJ_id_smime_ct_receipt */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x02,/* [1294] OBJ_id_smime_ct_authData */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x03,/* [1305] OBJ_id_smime_ct_publishCert */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x04,/* [1316] OBJ_id_smime_ct_TSTInfo */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x05,/* [1327] OBJ_id_smime_ct_TDTInfo */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x06,/* [1338] OBJ_id_smime_ct_contentInfo */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x07,/* [1349] OBJ_id_smime_ct_DVCSRequestData */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x08,/* [1360] OBJ_id_smime_ct_DVCSResponseData */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x01,/* [1371] OBJ_id_smime_aa_receiptRequest */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x02,/* [1382] OBJ_id_smime_aa_securityLabel */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x03,/* [1393] OBJ_id_smime_aa_mlExpandHistory */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x04,/* [1404] OBJ_id_smime_aa_contentHint */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x05,/* [1415] OBJ_id_smime_aa_msgSigDigest */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x06,/* [1426] OBJ_id_smime_aa_encapContentType */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x07,/* [1437] OBJ_id_smime_aa_contentIdentifier */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x08,/* [1448] OBJ_id_smime_aa_macValue */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x09,/* [1459] OBJ_id_smime_aa_equivalentLabels */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0A,/* [1470] OBJ_id_smime_aa_contentReference */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0B,/* [1481] OBJ_id_smime_aa_encrypKeyPref */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0C,/* [1492] OBJ_id_smime_aa_signingCertificate */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0D,/* [1503] OBJ_id_smime_aa_smimeEncryptCerts */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0E,/* [1514] OBJ_id_smime_aa_timeStampToken */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0F,/* [1525] OBJ_id_smime_aa_ets_sigPolicyId */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x10,/* [1536] OBJ_id_smime_aa_ets_commitmentType */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x11,/* [1547] OBJ_id_smime_aa_ets_signerLocation */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x12,/* [1558] OBJ_id_smime_aa_ets_signerAttr */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x13,/* [1569] OBJ_id_smime_aa_ets_otherSigCert */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x14,/* [1580] OBJ_id_smime_aa_ets_contentTimestamp */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x15,/* [1591] OBJ_id_smime_aa_ets_CertificateRefs */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x16,/* [1602] OBJ_id_smime_aa_ets_RevocationRefs */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x17,/* [1613] OBJ_id_smime_aa_ets_certValues */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x18,/* [1624] OBJ_id_smime_aa_ets_revocationValues */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x19,/* [1635] OBJ_id_smime_aa_ets_escTimeStamp */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1A,/* [1646] OBJ_id_smime_aa_ets_certCRLTimestamp */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1B,/* [1657] OBJ_id_smime_aa_ets_archiveTimeStamp */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1C,/* [1668] OBJ_id_smime_aa_signatureType */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1D,/* [1679] OBJ_id_smime_aa_dvcs_dvc */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x01,/* [1690] OBJ_id_smime_alg_ESDHwith3DES */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x02,/* [1701] OBJ_id_smime_alg_ESDHwithRC2 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x03,/* [1712] OBJ_id_smime_alg_3DESwrap */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x04,/* [1723] OBJ_id_smime_alg_RC2wrap */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x05,/* [1734] OBJ_id_smime_alg_ESDH */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x06,/* [1745] OBJ_id_smime_alg_CMS3DESwrap */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x07,/* [1756] OBJ_id_smime_alg_CMSRC2wrap */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,0x01,/* [1767] OBJ_id_smime_cd_ldap */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x01,/* [1778] OBJ_id_smime_spq_ets_sqt_uri */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x02,/* [1789] OBJ_id_smime_spq_ets_sqt_unotice */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x01,/* [1800] OBJ_id_smime_cti_ets_proofOfOrigin */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x02,/* [1811] OBJ_id_smime_cti_ets_proofOfReceipt */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x03,/* [1822] OBJ_id_smime_cti_ets_proofOfDelivery */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x04,/* [1833] OBJ_id_smime_cti_ets_proofOfSender */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x05,/* [1844] OBJ_id_smime_cti_ets_proofOfApproval */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x06,/* [1855] OBJ_id_smime_cti_ets_proofOfCreation */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x04,     /* [1866] OBJ_md4 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,          /* [1874] OBJ_id_pkix_mod */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x02,          /* [1881] OBJ_id_qt */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,          /* [1888] OBJ_id_it */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,          /* [1895] OBJ_id_pkip */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x06,          /* [1902] OBJ_id_alg */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,          /* [1909] OBJ_id_cmc */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x08,          /* [1916] OBJ_id_on */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,          /* [1923] OBJ_id_pda */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,          /* [1930] OBJ_id_aca */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0B,          /* [1937] OBJ_id_qcs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,          /* [1944] OBJ_id_cct */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x01,     /* [1951] OBJ_id_pkix1_explicit_88 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x02,     /* [1959] OBJ_id_pkix1_implicit_88 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x03,     /* [1967] OBJ_id_pkix1_explicit_93 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x04,     /* [1975] OBJ_id_pkix1_implicit_93 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x05,     /* [1983] OBJ_id_mod_crmf */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x06,     /* [1991] OBJ_id_mod_cmc */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x07,     /* [1999] OBJ_id_mod_kea_profile_88 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x08,     /* [2007] OBJ_id_mod_kea_profile_93 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x09,     /* [2015] OBJ_id_mod_cmp */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0A,     /* [2023] OBJ_id_mod_qualified_cert_88 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0B,     /* [2031] OBJ_id_mod_qualified_cert_93 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0C,     /* [2039] OBJ_id_mod_attribute_cert */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0D,     /* [2047] OBJ_id_mod_timestamp_protocol */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0E,     /* [2055] OBJ_id_mod_ocsp */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0F,     /* [2063] OBJ_id_mod_dvcs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x10,     /* [2071] OBJ_id_mod_cmp2000 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x02,     /* [2079] OBJ_biometricInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x03,     /* [2087] OBJ_qcStatements */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x04,     /* [2095] OBJ_ac_auditEntity */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x05,     /* [2103] OBJ_ac_targeting */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x06,     /* [2111] OBJ_aaControls */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x07,     /* [2119] OBJ_sbgp_ipAddrBlock */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x08,     /* [2127] OBJ_sbgp_autonomousSysNum */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x09,     /* [2135] OBJ_sbgp_routerIdentifier */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x03,     /* [2143] OBJ_textNotice */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x05,     /* [2151] OBJ_ipsecEndSystem */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x06,     /* [2159] OBJ_ipsecTunnel */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x07,     /* [2167] OBJ_ipsecUser */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x0A,     /* [2175] OBJ_dvcs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x01,     /* [2183] OBJ_id_it_caProtEncCert */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x02,     /* [2191] OBJ_id_it_signKeyPairTypes */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x03,     /* [2199] OBJ_id_it_encKeyPairTypes */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x04,     /* [2207] OBJ_id_it_preferredSymmAlg */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x05,     /* [2215] OBJ_id_it_caKeyUpdateInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x06,     /* [2223] OBJ_id_it_currentCRL */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x07,     /* [2231] OBJ_id_it_unsupportedOIDs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x08,     /* [2239] OBJ_id_it_subscriptionRequest */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x09,     /* [2247] OBJ_id_it_subscriptionResponse */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0A,     /* [2255] OBJ_id_it_keyPairParamReq */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0B,     /* [2263] OBJ_id_it_keyPairParamRep */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0C,     /* [2271] OBJ_id_it_revPassphrase */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0D,     /* [2279] OBJ_id_it_implicitConfirm */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0E,     /* [2287] OBJ_id_it_confirmWaitTime */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0F,     /* [2295] OBJ_id_it_origPKIMessage */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,     /* [2303] OBJ_id_regCtrl */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,     /* [2311] OBJ_id_regInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x01,/* [2319] OBJ_id_regCtrl_regToken */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x02,/* [2328] OBJ_id_regCtrl_authenticator */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x03,/* [2337] OBJ_id_regCtrl_pkiPublicationInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x04,/* [2346] OBJ_id_regCtrl_pkiArchiveOptions */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x05,/* [2355] OBJ_id_regCtrl_oldCertID */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x06,/* [2364] OBJ_id_regCtrl_protocolEncrKey */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x01,/* [2373] OBJ_id_regInfo_utf8Pairs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x02,/* [2382] OBJ_id_regInfo_certReq */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x01,     /* [2391] OBJ_id_alg_des40 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x02,     /* [2399] OBJ_id_alg_noSignature */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x03,     /* [2407] OBJ_id_alg_dh_sig_hmac_sha1 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x04,     /* [2415] OBJ_id_alg_dh_pop */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x01,     /* [2423] OBJ_id_cmc_statusInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x02,     /* [2431] OBJ_id_cmc_identification */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x03,     /* [2439] OBJ_id_cmc_identityProof */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x04,     /* [2447] OBJ_id_cmc_dataReturn */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x05,     /* [2455] OBJ_id_cmc_transactionId */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x06,     /* [2463] OBJ_id_cmc_senderNonce */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x07,     /* [2471] OBJ_id_cmc_recipientNonce */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x08,     /* [2479] OBJ_id_cmc_addExtensions */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x09,     /* [2487] OBJ_id_cmc_encryptedPOP */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0A,     /* [2495] OBJ_id_cmc_decryptedPOP */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0B,     /* [2503] OBJ_id_cmc_lraPOPWitness */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0F,     /* [2511] OBJ_id_cmc_getCert */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x10,     /* [2519] OBJ_id_cmc_getCRL */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x11,     /* [2527] OBJ_id_cmc_revokeRequest */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x12,     /* [2535] OBJ_id_cmc_regInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x13,     /* [2543] OBJ_id_cmc_responseInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x15,     /* [2551] OBJ_id_cmc_queryPending */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x16,     /* [2559] OBJ_id_cmc_popLinkRandom */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x17,     /* [2567] OBJ_id_cmc_popLinkWitness */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x18,     /* [2575] OBJ_id_cmc_confirmCertAcceptance */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x01,     /* [2583] OBJ_id_on_personalData */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x01,     /* [2591] OBJ_id_pda_dateOfBirth */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x02,     /* [2599] OBJ_id_pda_placeOfBirth */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x03,     /* [2607] OBJ_id_pda_gender */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x04,     /* [2615] OBJ_id_pda_countryOfCitizenship */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x05,     /* [2623] OBJ_id_pda_countryOfResidence */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x01,     /* [2631] OBJ_id_aca_authenticationInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x02,     /* [2639] OBJ_id_aca_accessIdentity */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x03,     /* [2647] OBJ_id_aca_chargingIdentity */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x04,     /* [2655] OBJ_id_aca_group */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x05,     /* [2663] OBJ_id_aca_role */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0B,0x01,     /* [2671] OBJ_id_qcs_pkixQCSyntax_v1 */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x01,     /* [2679] OBJ_id_cct_crs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x02,     /* [2687] OBJ_id_cct_PKIData */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x03,     /* [2695] OBJ_id_cct_PKIResponse */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x03,     /* [2703] OBJ_ad_timeStamping */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x04,     /* [2711] OBJ_ad_dvcs */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x01,/* [2719] OBJ_id_pkix_OCSP_basic */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x02,/* [2728] OBJ_id_pkix_OCSP_Nonce */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x03,/* [2737] OBJ_id_pkix_OCSP_CrlID */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x04,/* [2746] OBJ_id_pkix_OCSP_acceptableResponses */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x05,/* [2755] OBJ_id_pkix_OCSP_noCheck */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x06,/* [2764] OBJ_id_pkix_OCSP_archiveCutoff */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x07,/* [2773] OBJ_id_pkix_OCSP_serviceLocator */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x08,/* [2782] OBJ_id_pkix_OCSP_extendedStatus */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x09,/* [2791] OBJ_id_pkix_OCSP_valid */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0A,/* [2800] OBJ_id_pkix_OCSP_path */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0B,/* [2809] OBJ_id_pkix_OCSP_trustRoot */
+0x2B,0x0E,0x03,0x02,                         /* [2818] OBJ_algorithm */
+0x2B,0x0E,0x03,0x02,0x0B,                    /* [2822] OBJ_rsaSignature */
+0x55,0x08,                                   /* [2827] OBJ_X500algorithms */
+0x2B,                                        /* [2829] OBJ_org */
+0x2B,0x06,                                   /* [2830] OBJ_dod */
+0x2B,0x06,0x01,                              /* [2832] OBJ_iana */
+0x2B,0x06,0x01,0x01,                         /* [2835] OBJ_Directory */
+0x2B,0x06,0x01,0x02,                         /* [2839] OBJ_Management */
+0x2B,0x06,0x01,0x03,                         /* [2843] OBJ_Experimental */
+0x2B,0x06,0x01,0x04,                         /* [2847] OBJ_Private */
+0x2B,0x06,0x01,0x05,                         /* [2851] OBJ_Security */
+0x2B,0x06,0x01,0x06,                         /* [2855] OBJ_SNMPv2 */
+0x2B,0x06,0x01,0x07,                         /* [2859] OBJ_Mail */
+0x2B,0x06,0x01,0x04,0x01,                    /* [2863] OBJ_Enterprises */
+0x2B,0x06,0x01,0x04,0x01,0x8B,0x3A,0x82,0x58,/* [2868] OBJ_dcObject */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x19,/* [2877] OBJ_domainComponent */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0D,/* [2887] OBJ_Domain */
+0x55,0x01,0x05,                              /* [2897] OBJ_selected_attribute_types */
+0x55,0x01,0x05,0x37,                         /* [2900] OBJ_clearance */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x03,/* [2904] OBJ_md4WithRSAEncryption */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0A,     /* [2913] OBJ_ac_proxying */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0B,     /* [2921] OBJ_sinfo_access */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x06,     /* [2929] OBJ_id_aca_encAttrs */
+0x55,0x04,0x48,                              /* [2937] OBJ_role */
+0x55,0x1D,0x24,                              /* [2940] OBJ_policy_constraints */
+0x55,0x1D,0x37,                              /* [2943] OBJ_target_information */
+0x55,0x1D,0x38,                              /* [2946] OBJ_no_rev_avail */
+0x2A,0x86,0x48,0xCE,0x3D,                    /* [2949] OBJ_ansi_X9_62 */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x01,          /* [2954] OBJ_X9_62_prime_field */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,          /* [2961] OBJ_X9_62_characteristic_two_field */
+0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,          /* [2968] OBJ_X9_62_id_ecPublicKey */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01,     /* [2975] OBJ_X9_62_prime192v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02,     /* [2983] OBJ_X9_62_prime192v2 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03,     /* [2991] OBJ_X9_62_prime192v3 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04,     /* [2999] OBJ_X9_62_prime239v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05,     /* [3007] OBJ_X9_62_prime239v2 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06,     /* [3015] OBJ_X9_62_prime239v3 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07,     /* [3023] OBJ_X9_62_prime256v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,          /* [3031] OBJ_ecdsa_with_SHA1 */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x01,/* [3038] OBJ_ms_csp_name */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x01,/* [3047] OBJ_aes_128_ecb */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x02,/* [3056] OBJ_aes_128_cbc */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x03,/* [3065] OBJ_aes_128_ofb128 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x04,/* [3074] OBJ_aes_128_cfb128 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x15,/* [3083] OBJ_aes_192_ecb */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x16,/* [3092] OBJ_aes_192_cbc */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x17,/* [3101] OBJ_aes_192_ofb128 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x18,/* [3110] OBJ_aes_192_cfb128 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x29,/* [3119] OBJ_aes_256_ecb */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2A,/* [3128] OBJ_aes_256_cbc */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2B,/* [3137] OBJ_aes_256_ofb128 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2C,/* [3146] OBJ_aes_256_cfb128 */
+0x55,0x1D,0x17,                              /* [3155] OBJ_hold_instruction_code */
+0x2A,0x86,0x48,0xCE,0x38,0x02,0x01,          /* [3158] OBJ_hold_instruction_none */
+0x2A,0x86,0x48,0xCE,0x38,0x02,0x02,          /* [3165] OBJ_hold_instruction_call_issuer */
+0x2A,0x86,0x48,0xCE,0x38,0x02,0x03,          /* [3172] OBJ_hold_instruction_reject */
+0x09,                                        /* [3179] OBJ_data */
+0x09,0x92,0x26,                              /* [3180] OBJ_pss */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,          /* [3183] OBJ_ucl */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,     /* [3190] OBJ_pilot */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,/* [3198] OBJ_pilotAttributeType */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,/* [3207] OBJ_pilotAttributeSyntax */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,/* [3216] OBJ_pilotObjectClass */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x0A,/* [3225] OBJ_pilotGroups */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x04,/* [3234] OBJ_iA5StringSyntax */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x05,/* [3244] OBJ_caseIgnoreIA5StringSyntax */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x03,/* [3254] OBJ_pilotObject */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x04,/* [3264] OBJ_pilotPerson */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x05,/* [3274] OBJ_account */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x06,/* [3284] OBJ_document */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x07,/* [3294] OBJ_room */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x09,/* [3304] OBJ_documentSeries */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0E,/* [3314] OBJ_rFC822localPart */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0F,/* [3324] OBJ_dNSDomain */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x11,/* [3334] OBJ_domainRelatedObject */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x12,/* [3344] OBJ_friendlyCountry */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x13,/* [3354] OBJ_simpleSecurityObject */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x14,/* [3364] OBJ_pilotOrganization */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x15,/* [3374] OBJ_pilotDSA */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x16,/* [3384] OBJ_qualityLabelledData */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x01,/* [3394] OBJ_userId */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x02,/* [3404] OBJ_textEncodedORAddress */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x03,/* [3414] OBJ_rfc822Mailbox */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x04,/* [3424] OBJ_info */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x05,/* [3434] OBJ_favouriteDrink */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x06,/* [3444] OBJ_roomNumber */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x07,/* [3454] OBJ_photo */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x08,/* [3464] OBJ_userClass */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x09,/* [3474] OBJ_host */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0A,/* [3484] OBJ_manager */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0B,/* [3494] OBJ_documentIdentifier */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0C,/* [3504] OBJ_documentTitle */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0D,/* [3514] OBJ_documentVersion */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0E,/* [3524] OBJ_documentAuthor */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0F,/* [3534] OBJ_documentLocation */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x14,/* [3544] OBJ_homeTelephoneNumber */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x15,/* [3554] OBJ_secretary */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x16,/* [3564] OBJ_otherMailbox */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x17,/* [3574] OBJ_lastModifiedTime */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x18,/* [3584] OBJ_lastModifiedBy */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1A,/* [3594] OBJ_aRecord */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1B,/* [3604] OBJ_pilotAttributeType27 */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1C,/* [3614] OBJ_mXRecord */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1D,/* [3624] OBJ_nSRecord */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1E,/* [3634] OBJ_sOARecord */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1F,/* [3644] OBJ_cNAMERecord */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x25,/* [3654] OBJ_associatedDomain */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x26,/* [3664] OBJ_associatedName */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x27,/* [3674] OBJ_homePostalAddress */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x28,/* [3684] OBJ_personalTitle */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x29,/* [3694] OBJ_mobileTelephoneNumber */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2A,/* [3704] OBJ_pagerTelephoneNumber */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2B,/* [3714] OBJ_friendlyCountryName */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2D,/* [3724] OBJ_organizationalStatus */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2E,/* [3734] OBJ_janetMailbox */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2F,/* [3744] OBJ_mailPreferenceOption */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x30,/* [3754] OBJ_buildingName */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x31,/* [3764] OBJ_dSAQuality */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x32,/* [3774] OBJ_singleLevelQuality */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x33,/* [3784] OBJ_subtreeMinimumQuality */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x34,/* [3794] OBJ_subtreeMaximumQuality */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x35,/* [3804] OBJ_personalSignature */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x36,/* [3814] OBJ_dITRedirect */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x37,/* [3824] OBJ_audio */
+0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x38,/* [3834] OBJ_documentPublisher */
+0x55,0x04,0x2D,                              /* [3844] OBJ_x500UniqueIdentifier */
+0x2B,0x06,0x01,0x07,0x01,                    /* [3847] OBJ_mime_mhs */
+0x2B,0x06,0x01,0x07,0x01,0x01,               /* [3852] OBJ_mime_mhs_headings */
+0x2B,0x06,0x01,0x07,0x01,0x02,               /* [3858] OBJ_mime_mhs_bodies */
+0x2B,0x06,0x01,0x07,0x01,0x01,0x01,          /* [3864] OBJ_id_hex_partial_message */
+0x2B,0x06,0x01,0x07,0x01,0x01,0x02,          /* [3871] OBJ_id_hex_multipart_message */
+0x55,0x04,0x2C,                              /* [3878] OBJ_generationQualifier */
+0x55,0x04,0x41,                              /* [3881] OBJ_pseudonym */
+0x67,0x2A,                                   /* [3884] OBJ_id_set */
+0x67,0x2A,0x00,                              /* [3886] OBJ_set_ctype */
+0x67,0x2A,0x01,                              /* [3889] OBJ_set_msgExt */
+0x67,0x2A,0x03,                              /* [3892] OBJ_set_attr */
+0x67,0x2A,0x05,                              /* [3895] OBJ_set_policy */
+0x67,0x2A,0x07,                              /* [3898] OBJ_set_certExt */
+0x67,0x2A,0x08,                              /* [3901] OBJ_set_brand */
+0x67,0x2A,0x00,0x00,                         /* [3904] OBJ_setct_PANData */
+0x67,0x2A,0x00,0x01,                         /* [3908] OBJ_setct_PANToken */
+0x67,0x2A,0x00,0x02,                         /* [3912] OBJ_setct_PANOnly */
+0x67,0x2A,0x00,0x03,                         /* [3916] OBJ_setct_OIData */
+0x67,0x2A,0x00,0x04,                         /* [3920] OBJ_setct_PI */
+0x67,0x2A,0x00,0x05,                         /* [3924] OBJ_setct_PIData */
+0x67,0x2A,0x00,0x06,                         /* [3928] OBJ_setct_PIDataUnsigned */
+0x67,0x2A,0x00,0x07,                         /* [3932] OBJ_setct_HODInput */
+0x67,0x2A,0x00,0x08,                         /* [3936] OBJ_setct_AuthResBaggage */
+0x67,0x2A,0x00,0x09,                         /* [3940] OBJ_setct_AuthRevReqBaggage */
+0x67,0x2A,0x00,0x0A,                         /* [3944] OBJ_setct_AuthRevResBaggage */
+0x67,0x2A,0x00,0x0B,                         /* [3948] OBJ_setct_CapTokenSeq */
+0x67,0x2A,0x00,0x0C,                         /* [3952] OBJ_setct_PInitResData */
+0x67,0x2A,0x00,0x0D,                         /* [3956] OBJ_setct_PI_TBS */
+0x67,0x2A,0x00,0x0E,                         /* [3960] OBJ_setct_PResData */
+0x67,0x2A,0x00,0x10,                         /* [3964] OBJ_setct_AuthReqTBS */
+0x67,0x2A,0x00,0x11,                         /* [3968] OBJ_setct_AuthResTBS */
+0x67,0x2A,0x00,0x12,                         /* [3972] OBJ_setct_AuthResTBSX */
+0x67,0x2A,0x00,0x13,                         /* [3976] OBJ_setct_AuthTokenTBS */
+0x67,0x2A,0x00,0x14,                         /* [3980] OBJ_setct_CapTokenData */
+0x67,0x2A,0x00,0x15,                         /* [3984] OBJ_setct_CapTokenTBS */
+0x67,0x2A,0x00,0x16,                         /* [3988] OBJ_setct_AcqCardCodeMsg */
+0x67,0x2A,0x00,0x17,                         /* [3992] OBJ_setct_AuthRevReqTBS */
+0x67,0x2A,0x00,0x18,                         /* [3996] OBJ_setct_AuthRevResData */
+0x67,0x2A,0x00,0x19,                         /* [4000] OBJ_setct_AuthRevResTBS */
+0x67,0x2A,0x00,0x1A,                         /* [4004] OBJ_setct_CapReqTBS */
+0x67,0x2A,0x00,0x1B,                         /* [4008] OBJ_setct_CapReqTBSX */
+0x67,0x2A,0x00,0x1C,                         /* [4012] OBJ_setct_CapResData */
+0x67,0x2A,0x00,0x1D,                         /* [4016] OBJ_setct_CapRevReqTBS */
+0x67,0x2A,0x00,0x1E,                         /* [4020] OBJ_setct_CapRevReqTBSX */
+0x67,0x2A,0x00,0x1F,                         /* [4024] OBJ_setct_CapRevResData */
+0x67,0x2A,0x00,0x20,                         /* [4028] OBJ_setct_CredReqTBS */
+0x67,0x2A,0x00,0x21,                         /* [4032] OBJ_setct_CredReqTBSX */
+0x67,0x2A,0x00,0x22,                         /* [4036] OBJ_setct_CredResData */
+0x67,0x2A,0x00,0x23,                         /* [4040] OBJ_setct_CredRevReqTBS */
+0x67,0x2A,0x00,0x24,                         /* [4044] OBJ_setct_CredRevReqTBSX */
+0x67,0x2A,0x00,0x25,                         /* [4048] OBJ_setct_CredRevResData */
+0x67,0x2A,0x00,0x26,                         /* [4052] OBJ_setct_PCertReqData */
+0x67,0x2A,0x00,0x27,                         /* [4056] OBJ_setct_PCertResTBS */
+0x67,0x2A,0x00,0x28,                         /* [4060] OBJ_setct_BatchAdminReqData */
+0x67,0x2A,0x00,0x29,                         /* [4064] OBJ_setct_BatchAdminResData */
+0x67,0x2A,0x00,0x2A,                         /* [4068] OBJ_setct_CardCInitResTBS */
+0x67,0x2A,0x00,0x2B,                         /* [4072] OBJ_setct_MeAqCInitResTBS */
+0x67,0x2A,0x00,0x2C,                         /* [4076] OBJ_setct_RegFormResTBS */
+0x67,0x2A,0x00,0x2D,                         /* [4080] OBJ_setct_CertReqData */
+0x67,0x2A,0x00,0x2E,                         /* [4084] OBJ_setct_CertReqTBS */
+0x67,0x2A,0x00,0x2F,                         /* [4088] OBJ_setct_CertResData */
+0x67,0x2A,0x00,0x30,                         /* [4092] OBJ_setct_CertInqReqTBS */
+0x67,0x2A,0x00,0x31,                         /* [4096] OBJ_setct_ErrorTBS */
+0x67,0x2A,0x00,0x32,                         /* [4100] OBJ_setct_PIDualSignedTBE */
+0x67,0x2A,0x00,0x33,                         /* [4104] OBJ_setct_PIUnsignedTBE */
+0x67,0x2A,0x00,0x34,                         /* [4108] OBJ_setct_AuthReqTBE */
+0x67,0x2A,0x00,0x35,                         /* [4112] OBJ_setct_AuthResTBE */
+0x67,0x2A,0x00,0x36,                         /* [4116] OBJ_setct_AuthResTBEX */
+0x67,0x2A,0x00,0x37,                         /* [4120] OBJ_setct_AuthTokenTBE */
+0x67,0x2A,0x00,0x38,                         /* [4124] OBJ_setct_CapTokenTBE */
+0x67,0x2A,0x00,0x39,                         /* [4128] OBJ_setct_CapTokenTBEX */
+0x67,0x2A,0x00,0x3A,                         /* [4132] OBJ_setct_AcqCardCodeMsgTBE */
+0x67,0x2A,0x00,0x3B,                         /* [4136] OBJ_setct_AuthRevReqTBE */
+0x67,0x2A,0x00,0x3C,                         /* [4140] OBJ_setct_AuthRevResTBE */
+0x67,0x2A,0x00,0x3D,                         /* [4144] OBJ_setct_AuthRevResTBEB */
+0x67,0x2A,0x00,0x3E,                         /* [4148] OBJ_setct_CapReqTBE */
+0x67,0x2A,0x00,0x3F,                         /* [4152] OBJ_setct_CapReqTBEX */
+0x67,0x2A,0x00,0x40,                         /* [4156] OBJ_setct_CapResTBE */
+0x67,0x2A,0x00,0x41,                         /* [4160] OBJ_setct_CapRevReqTBE */
+0x67,0x2A,0x00,0x42,                         /* [4164] OBJ_setct_CapRevReqTBEX */
+0x67,0x2A,0x00,0x43,                         /* [4168] OBJ_setct_CapRevResTBE */
+0x67,0x2A,0x00,0x44,                         /* [4172] OBJ_setct_CredReqTBE */
+0x67,0x2A,0x00,0x45,                         /* [4176] OBJ_setct_CredReqTBEX */
+0x67,0x2A,0x00,0x46,                         /* [4180] OBJ_setct_CredResTBE */
+0x67,0x2A,0x00,0x47,                         /* [4184] OBJ_setct_CredRevReqTBE */
+0x67,0x2A,0x00,0x48,                         /* [4188] OBJ_setct_CredRevReqTBEX */
+0x67,0x2A,0x00,0x49,                         /* [4192] OBJ_setct_CredRevResTBE */
+0x67,0x2A,0x00,0x4A,                         /* [4196] OBJ_setct_BatchAdminReqTBE */
+0x67,0x2A,0x00,0x4B,                         /* [4200] OBJ_setct_BatchAdminResTBE */
+0x67,0x2A,0x00,0x4C,                         /* [4204] OBJ_setct_RegFormReqTBE */
+0x67,0x2A,0x00,0x4D,                         /* [4208] OBJ_setct_CertReqTBE */
+0x67,0x2A,0x00,0x4E,                         /* [4212] OBJ_setct_CertReqTBEX */
+0x67,0x2A,0x00,0x4F,                         /* [4216] OBJ_setct_CertResTBE */
+0x67,0x2A,0x00,0x50,                         /* [4220] OBJ_setct_CRLNotificationTBS */
+0x67,0x2A,0x00,0x51,                         /* [4224] OBJ_setct_CRLNotificationResTBS */
+0x67,0x2A,0x00,0x52,                         /* [4228] OBJ_setct_BCIDistributionTBS */
+0x67,0x2A,0x01,0x01,                         /* [4232] OBJ_setext_genCrypt */
+0x67,0x2A,0x01,0x03,                         /* [4236] OBJ_setext_miAuth */
+0x67,0x2A,0x01,0x04,                         /* [4240] OBJ_setext_pinSecure */
+0x67,0x2A,0x01,0x05,                         /* [4244] OBJ_setext_pinAny */
+0x67,0x2A,0x01,0x07,                         /* [4248] OBJ_setext_track2 */
+0x67,0x2A,0x01,0x08,                         /* [4252] OBJ_setext_cv */
+0x67,0x2A,0x05,0x00,                         /* [4256] OBJ_set_policy_root */
+0x67,0x2A,0x07,0x00,                         /* [4260] OBJ_setCext_hashedRoot */
+0x67,0x2A,0x07,0x01,                         /* [4264] OBJ_setCext_certType */
+0x67,0x2A,0x07,0x02,                         /* [4268] OBJ_setCext_merchData */
+0x67,0x2A,0x07,0x03,                         /* [4272] OBJ_setCext_cCertRequired */
+0x67,0x2A,0x07,0x04,                         /* [4276] OBJ_setCext_tunneling */
+0x67,0x2A,0x07,0x05,                         /* [4280] OBJ_setCext_setExt */
+0x67,0x2A,0x07,0x06,                         /* [4284] OBJ_setCext_setQualf */
+0x67,0x2A,0x07,0x07,                         /* [4288] OBJ_setCext_PGWYcapabilities */
+0x67,0x2A,0x07,0x08,                         /* [4292] OBJ_setCext_TokenIdentifier */
+0x67,0x2A,0x07,0x09,                         /* [4296] OBJ_setCext_Track2Data */
+0x67,0x2A,0x07,0x0A,                         /* [4300] OBJ_setCext_TokenType */
+0x67,0x2A,0x07,0x0B,                         /* [4304] OBJ_setCext_IssuerCapabilities */
+0x67,0x2A,0x03,0x00,                         /* [4308] OBJ_setAttr_Cert */
+0x67,0x2A,0x03,0x01,                         /* [4312] OBJ_setAttr_PGWYcap */
+0x67,0x2A,0x03,0x02,                         /* [4316] OBJ_setAttr_TokenType */
+0x67,0x2A,0x03,0x03,                         /* [4320] OBJ_setAttr_IssCap */
+0x67,0x2A,0x03,0x00,0x00,                    /* [4324] OBJ_set_rootKeyThumb */
+0x67,0x2A,0x03,0x00,0x01,                    /* [4329] OBJ_set_addPolicy */
+0x67,0x2A,0x03,0x02,0x01,                    /* [4334] OBJ_setAttr_Token_EMV */
+0x67,0x2A,0x03,0x02,0x02,                    /* [4339] OBJ_setAttr_Token_B0Prime */
+0x67,0x2A,0x03,0x03,0x03,                    /* [4344] OBJ_setAttr_IssCap_CVM */
+0x67,0x2A,0x03,0x03,0x04,                    /* [4349] OBJ_setAttr_IssCap_T2 */
+0x67,0x2A,0x03,0x03,0x05,                    /* [4354] OBJ_setAttr_IssCap_Sig */
+0x67,0x2A,0x03,0x03,0x03,0x01,               /* [4359] OBJ_setAttr_GenCryptgrm */
+0x67,0x2A,0x03,0x03,0x04,0x01,               /* [4365] OBJ_setAttr_T2Enc */
+0x67,0x2A,0x03,0x03,0x04,0x02,               /* [4371] OBJ_setAttr_T2cleartxt */
+0x67,0x2A,0x03,0x03,0x05,0x01,               /* [4377] OBJ_setAttr_TokICCsig */
+0x67,0x2A,0x03,0x03,0x05,0x02,               /* [4383] OBJ_setAttr_SecDevSig */
+0x67,0x2A,0x08,0x01,                         /* [4389] OBJ_set_brand_IATA_ATA */
+0x67,0x2A,0x08,0x1E,                         /* [4393] OBJ_set_brand_Diners */
+0x67,0x2A,0x08,0x22,                         /* [4397] OBJ_set_brand_AmericanExpress */
+0x67,0x2A,0x08,0x23,                         /* [4401] OBJ_set_brand_JCB */
+0x67,0x2A,0x08,0x04,                         /* [4405] OBJ_set_brand_Visa */
+0x67,0x2A,0x08,0x05,                         /* [4409] OBJ_set_brand_MasterCard */
+0x67,0x2A,0x08,0xAE,0x7B,                    /* [4413] OBJ_set_brand_Novus */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x0A,     /* [4418] OBJ_des_cdmf */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x06,/* [4426] OBJ_rsaOAEPEncryptionSET */
+0x67,                                        /* [4435] OBJ_international_organizations */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x02,/* [4436] OBJ_ms_smartcard_login */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x03,/* [4446] OBJ_ms_upn */
+0x55,0x04,0x09,                              /* [4456] OBJ_streetAddress */
+0x55,0x04,0x11,                              /* [4459] OBJ_postalCode */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x15,          /* [4462] OBJ_id_ppl */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0E,     /* [4469] OBJ_proxyCertInfo */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x00,     /* [4477] OBJ_id_ppl_anyLanguage */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x01,     /* [4485] OBJ_id_ppl_inheritAll */
+0x55,0x1D,0x1E,                              /* [4493] OBJ_name_constraints */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x02,     /* [4496] OBJ_Independent */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,/* [4504] OBJ_sha256WithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C,/* [4513] OBJ_sha384WithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0D,/* [4522] OBJ_sha512WithRSAEncryption */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0E,/* [4531] OBJ_sha224WithRSAEncryption */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,/* [4540] OBJ_sha256 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,/* [4549] OBJ_sha384 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,/* [4558] OBJ_sha512 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,/* [4567] OBJ_sha224 */
+0x2B,                                        /* [4576] OBJ_identified_organization */
+0x2B,0x81,0x04,                              /* [4577] OBJ_certicom_arc */
+0x67,0x2B,                                   /* [4580] OBJ_wap */
+0x67,0x2B,0x01,                              /* [4582] OBJ_wap_wsg */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,     /* [4585] OBJ_X9_62_id_characteristic_two_basis */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x01,/* [4593] OBJ_X9_62_onBasis */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x02,/* [4602] OBJ_X9_62_tpBasis */
+0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x03,/* [4611] OBJ_X9_62_ppBasis */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x01,     /* [4620] OBJ_X9_62_c2pnb163v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x02,     /* [4628] OBJ_X9_62_c2pnb163v2 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x03,     /* [4636] OBJ_X9_62_c2pnb163v3 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x04,     /* [4644] OBJ_X9_62_c2pnb176v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x05,     /* [4652] OBJ_X9_62_c2tnb191v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x06,     /* [4660] OBJ_X9_62_c2tnb191v2 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x07,     /* [4668] OBJ_X9_62_c2tnb191v3 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x08,     /* [4676] OBJ_X9_62_c2onb191v4 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x09,     /* [4684] OBJ_X9_62_c2onb191v5 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0A,     /* [4692] OBJ_X9_62_c2pnb208w1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0B,     /* [4700] OBJ_X9_62_c2tnb239v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0C,     /* [4708] OBJ_X9_62_c2tnb239v2 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0D,     /* [4716] OBJ_X9_62_c2tnb239v3 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0E,     /* [4724] OBJ_X9_62_c2onb239v4 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0F,     /* [4732] OBJ_X9_62_c2onb239v5 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x10,     /* [4740] OBJ_X9_62_c2pnb272w1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x11,     /* [4748] OBJ_X9_62_c2pnb304w1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x12,     /* [4756] OBJ_X9_62_c2tnb359v1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x13,     /* [4764] OBJ_X9_62_c2pnb368w1 */
+0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x14,     /* [4772] OBJ_X9_62_c2tnb431r1 */
+0x2B,0x81,0x04,0x00,0x06,                    /* [4780] OBJ_secp112r1 */
+0x2B,0x81,0x04,0x00,0x07,                    /* [4785] OBJ_secp112r2 */
+0x2B,0x81,0x04,0x00,0x1C,                    /* [4790] OBJ_secp128r1 */
+0x2B,0x81,0x04,0x00,0x1D,                    /* [4795] OBJ_secp128r2 */
+0x2B,0x81,0x04,0x00,0x09,                    /* [4800] OBJ_secp160k1 */
+0x2B,0x81,0x04,0x00,0x08,                    /* [4805] OBJ_secp160r1 */
+0x2B,0x81,0x04,0x00,0x1E,                    /* [4810] OBJ_secp160r2 */
+0x2B,0x81,0x04,0x00,0x1F,                    /* [4815] OBJ_secp192k1 */
+0x2B,0x81,0x04,0x00,0x20,                    /* [4820] OBJ_secp224k1 */
+0x2B,0x81,0x04,0x00,0x21,                    /* [4825] OBJ_secp224r1 */
+0x2B,0x81,0x04,0x00,0x0A,                    /* [4830] OBJ_secp256k1 */
+0x2B,0x81,0x04,0x00,0x22,                    /* [4835] OBJ_secp384r1 */
+0x2B,0x81,0x04,0x00,0x23,                    /* [4840] OBJ_secp521r1 */
+0x2B,0x81,0x04,0x00,0x04,                    /* [4845] OBJ_sect113r1 */
+0x2B,0x81,0x04,0x00,0x05,                    /* [4850] OBJ_sect113r2 */
+0x2B,0x81,0x04,0x00,0x16,                    /* [4855] OBJ_sect131r1 */
+0x2B,0x81,0x04,0x00,0x17,                    /* [4860] OBJ_sect131r2 */
+0x2B,0x81,0x04,0x00,0x01,                    /* [4865] OBJ_sect163k1 */
+0x2B,0x81,0x04,0x00,0x02,                    /* [4870] OBJ_sect163r1 */
+0x2B,0x81,0x04,0x00,0x0F,                    /* [4875] OBJ_sect163r2 */
+0x2B,0x81,0x04,0x00,0x18,                    /* [4880] OBJ_sect193r1 */
+0x2B,0x81,0x04,0x00,0x19,                    /* [4885] OBJ_sect193r2 */
+0x2B,0x81,0x04,0x00,0x1A,                    /* [4890] OBJ_sect233k1 */
+0x2B,0x81,0x04,0x00,0x1B,                    /* [4895] OBJ_sect233r1 */
+0x2B,0x81,0x04,0x00,0x03,                    /* [4900] OBJ_sect239k1 */
+0x2B,0x81,0x04,0x00,0x10,                    /* [4905] OBJ_sect283k1 */
+0x2B,0x81,0x04,0x00,0x11,                    /* [4910] OBJ_sect283r1 */
+0x2B,0x81,0x04,0x00,0x24,                    /* [4915] OBJ_sect409k1 */
+0x2B,0x81,0x04,0x00,0x25,                    /* [4920] OBJ_sect409r1 */
+0x2B,0x81,0x04,0x00,0x26,                    /* [4925] OBJ_sect571k1 */
+0x2B,0x81,0x04,0x00,0x27,                    /* [4930] OBJ_sect571r1 */
+0x67,0x2B,0x01,0x04,0x01,                    /* [4935] OBJ_wap_wsg_idm_ecid_wtls1 */
+0x67,0x2B,0x01,0x04,0x03,                    /* [4940] OBJ_wap_wsg_idm_ecid_wtls3 */
+0x67,0x2B,0x01,0x04,0x04,                    /* [4945] OBJ_wap_wsg_idm_ecid_wtls4 */
+0x67,0x2B,0x01,0x04,0x05,                    /* [4950] OBJ_wap_wsg_idm_ecid_wtls5 */
+0x67,0x2B,0x01,0x04,0x06,                    /* [4955] OBJ_wap_wsg_idm_ecid_wtls6 */
+0x67,0x2B,0x01,0x04,0x07,                    /* [4960] OBJ_wap_wsg_idm_ecid_wtls7 */
+0x67,0x2B,0x01,0x04,0x08,                    /* [4965] OBJ_wap_wsg_idm_ecid_wtls8 */
+0x67,0x2B,0x01,0x04,0x09,                    /* [4970] OBJ_wap_wsg_idm_ecid_wtls9 */
+0x67,0x2B,0x01,0x04,0x0A,                    /* [4975] OBJ_wap_wsg_idm_ecid_wtls10 */
+0x67,0x2B,0x01,0x04,0x0B,                    /* [4980] OBJ_wap_wsg_idm_ecid_wtls11 */
+0x67,0x2B,0x01,0x04,0x0C,                    /* [4985] OBJ_wap_wsg_idm_ecid_wtls12 */
+0x55,0x1D,0x20,0x00,                         /* [4990] OBJ_any_policy */
+0x55,0x1D,0x21,                              /* [4994] OBJ_policy_mappings */
+0x55,0x1D,0x36,                              /* [4997] OBJ_inhibit_any_policy */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x02,/* [5000] OBJ_camellia_128_cbc */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x03,/* [5011] OBJ_camellia_192_cbc */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x04,/* [5022] OBJ_camellia_256_cbc */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x01,     /* [5033] OBJ_camellia_128_ecb */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x15,     /* [5041] OBJ_camellia_192_ecb */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x29,     /* [5049] OBJ_camellia_256_ecb */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x04,     /* [5057] OBJ_camellia_128_cfb128 */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x18,     /* [5065] OBJ_camellia_192_cfb128 */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2C,     /* [5073] OBJ_camellia_256_cfb128 */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x03,     /* [5081] OBJ_camellia_128_ofb128 */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x17,     /* [5089] OBJ_camellia_192_ofb128 */
+0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2B,     /* [5097] OBJ_camellia_256_ofb128 */
+0x55,0x1D,0x09,                              /* [5105] OBJ_subject_directory_attributes */
+0x55,0x1D,0x1C,                              /* [5108] OBJ_issuing_distribution_point */
+0x55,0x1D,0x1D,                              /* [5111] OBJ_certificate_issuer */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,               /* [5114] OBJ_kisa */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x03,     /* [5120] OBJ_seed_ecb */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x04,     /* [5128] OBJ_seed_cbc */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x06,     /* [5136] OBJ_seed_ofb128 */
+0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x05,     /* [5144] OBJ_seed_cfb128 */
+0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x01,     /* [5152] OBJ_hmac_md5 */
+0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x02,     /* [5160] OBJ_hmac_sha1 */
+0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0D,/* [5168] OBJ_id_PasswordBasedMAC */
+0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x1E,/* [5177] OBJ_id_DHBasedMac */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x10,     /* [5186] OBJ_id_it_suppLangTags */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x05,     /* [5194] OBJ_caRepository */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x09,/* [5202] OBJ_id_smime_ct_compressedData */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x1B,/* [5213] OBJ_id_ct_asciiTextWithCRLF */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x05,/* [5224] OBJ_id_aes128_wrap */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x19,/* [5233] OBJ_id_aes192_wrap */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2D,/* [5242] OBJ_id_aes256_wrap */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x02,          /* [5251] OBJ_ecdsa_with_Recommended */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,          /* [5258] OBJ_ecdsa_with_Specified */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x01,     /* [5265] OBJ_ecdsa_with_SHA224 */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,     /* [5273] OBJ_ecdsa_with_SHA256 */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,     /* [5281] OBJ_ecdsa_with_SHA384 */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x04,     /* [5289] OBJ_ecdsa_with_SHA512 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x06,     /* [5297] OBJ_hmacWithMD5 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x08,     /* [5305] OBJ_hmacWithSHA224 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x09,     /* [5313] OBJ_hmacWithSHA256 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0A,     /* [5321] OBJ_hmacWithSHA384 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0B,     /* [5329] OBJ_hmacWithSHA512 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x01,/* [5337] OBJ_dsa_with_SHA224 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x02,/* [5346] OBJ_dsa_with_SHA256 */
+0x28,0xCF,0x06,0x03,0x00,0x37,               /* [5355] OBJ_whirlpool */
+0x2A,0x85,0x03,0x02,0x02,                    /* [5361] OBJ_cryptopro */
+0x2A,0x85,0x03,0x02,0x09,                    /* [5366] OBJ_cryptocom */
+0x2A,0x85,0x03,0x02,0x02,0x03,               /* [5371] OBJ_id_GostR3411_94_with_GostR3410_2001 */
+0x2A,0x85,0x03,0x02,0x02,0x04,               /* [5377] OBJ_id_GostR3411_94_with_GostR3410_94 */
+0x2A,0x85,0x03,0x02,0x02,0x09,               /* [5383] OBJ_id_GostR3411_94 */
+0x2A,0x85,0x03,0x02,0x02,0x0A,               /* [5389] OBJ_id_HMACGostR3411_94 */
+0x2A,0x85,0x03,0x02,0x02,0x13,               /* [5395] OBJ_id_GostR3410_2001 */
+0x2A,0x85,0x03,0x02,0x02,0x14,               /* [5401] OBJ_id_GostR3410_94 */
+0x2A,0x85,0x03,0x02,0x02,0x15,               /* [5407] OBJ_id_Gost28147_89 */
+0x2A,0x85,0x03,0x02,0x02,0x16,               /* [5413] OBJ_id_Gost28147_89_MAC */
+0x2A,0x85,0x03,0x02,0x02,0x17,               /* [5419] OBJ_id_GostR3411_94_prf */
+0x2A,0x85,0x03,0x02,0x02,0x62,               /* [5425] OBJ_id_GostR3410_2001DH */
+0x2A,0x85,0x03,0x02,0x02,0x63,               /* [5431] OBJ_id_GostR3410_94DH */
+0x2A,0x85,0x03,0x02,0x02,0x0E,0x01,          /* [5437] OBJ_id_Gost28147_89_CryptoPro_KeyMeshing */
+0x2A,0x85,0x03,0x02,0x02,0x0E,0x00,          /* [5444] OBJ_id_Gost28147_89_None_KeyMeshing */
+0x2A,0x85,0x03,0x02,0x02,0x1E,0x00,          /* [5451] OBJ_id_GostR3411_94_TestParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1E,0x01,          /* [5458] OBJ_id_GostR3411_94_CryptoProParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x00,          /* [5465] OBJ_id_Gost28147_89_TestParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x01,          /* [5472] OBJ_id_Gost28147_89_CryptoPro_A_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x02,          /* [5479] OBJ_id_Gost28147_89_CryptoPro_B_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x03,          /* [5486] OBJ_id_Gost28147_89_CryptoPro_C_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x04,          /* [5493] OBJ_id_Gost28147_89_CryptoPro_D_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x05,          /* [5500] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x06,          /* [5507] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x07,          /* [5514] OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x00,          /* [5521] OBJ_id_GostR3410_94_TestParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x02,          /* [5528] OBJ_id_GostR3410_94_CryptoPro_A_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x03,          /* [5535] OBJ_id_GostR3410_94_CryptoPro_B_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x04,          /* [5542] OBJ_id_GostR3410_94_CryptoPro_C_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x05,          /* [5549] OBJ_id_GostR3410_94_CryptoPro_D_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x21,0x01,          /* [5556] OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x21,0x02,          /* [5563] OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x21,0x03,          /* [5570] OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x23,0x00,          /* [5577] OBJ_id_GostR3410_2001_TestParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x23,0x01,          /* [5584] OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x23,0x02,          /* [5591] OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x23,0x03,          /* [5598] OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x24,0x00,          /* [5605] OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x24,0x01,          /* [5612] OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x14,0x01,          /* [5619] OBJ_id_GostR3410_94_a */
+0x2A,0x85,0x03,0x02,0x02,0x14,0x02,          /* [5626] OBJ_id_GostR3410_94_aBis */
+0x2A,0x85,0x03,0x02,0x02,0x14,0x03,          /* [5633] OBJ_id_GostR3410_94_b */
+0x2A,0x85,0x03,0x02,0x02,0x14,0x04,          /* [5640] OBJ_id_GostR3410_94_bBis */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x06,0x01,     /* [5647] OBJ_id_Gost28147_89_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x03,     /* [5655] OBJ_id_GostR3410_94_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x04,     /* [5663] OBJ_id_GostR3410_2001_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x03,     /* [5671] OBJ_id_GostR3411_94_with_GostR3410_94_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x04,     /* [5679] OBJ_id_GostR3411_94_with_GostR3410_2001_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x08,0x01,     /* [5687] OBJ_id_GostR3410_2001_ParamSet_cc */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x02,/* [5695] OBJ_LocalKeySet */
+0x55,0x1D,0x2E,                              /* [5704] OBJ_freshest_crl */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x03,     /* [5707] OBJ_id_on_permanentIdentifier */
+0x55,0x04,0x0E,                              /* [5715] OBJ_searchGuide */
+0x55,0x04,0x0F,                              /* [5718] OBJ_businessCategory */
+0x55,0x04,0x10,                              /* [5721] OBJ_postalAddress */
+0x55,0x04,0x12,                              /* [5724] OBJ_postOfficeBox */
+0x55,0x04,0x13,                              /* [5727] OBJ_physicalDeliveryOfficeName */
+0x55,0x04,0x14,                              /* [5730] OBJ_telephoneNumber */
+0x55,0x04,0x15,                              /* [5733] OBJ_telexNumber */
+0x55,0x04,0x16,                              /* [5736] OBJ_teletexTerminalIdentifier */
+0x55,0x04,0x17,                              /* [5739] OBJ_facsimileTelephoneNumber */
+0x55,0x04,0x18,                              /* [5742] OBJ_x121Address */
+0x55,0x04,0x19,                              /* [5745] OBJ_internationaliSDNNumber */
+0x55,0x04,0x1A,                              /* [5748] OBJ_registeredAddress */
+0x55,0x04,0x1B,                              /* [5751] OBJ_destinationIndicator */
+0x55,0x04,0x1C,                              /* [5754] OBJ_preferredDeliveryMethod */
+0x55,0x04,0x1D,                              /* [5757] OBJ_presentationAddress */
+0x55,0x04,0x1E,                              /* [5760] OBJ_supportedApplicationContext */
+0x55,0x04,0x1F,                              /* [5763] OBJ_member */
+0x55,0x04,0x20,                              /* [5766] OBJ_owner */
+0x55,0x04,0x21,                              /* [5769] OBJ_roleOccupant */
+0x55,0x04,0x22,                              /* [5772] OBJ_seeAlso */
+0x55,0x04,0x23,                              /* [5775] OBJ_userPassword */
+0x55,0x04,0x24,                              /* [5778] OBJ_userCertificate */
+0x55,0x04,0x25,                              /* [5781] OBJ_cACertificate */
+0x55,0x04,0x26,                              /* [5784] OBJ_authorityRevocationList */
+0x55,0x04,0x27,                              /* [5787] OBJ_certificateRevocationList */
+0x55,0x04,0x28,                              /* [5790] OBJ_crossCertificatePair */
+0x55,0x04,0x2F,                              /* [5793] OBJ_enhancedSearchGuide */
+0x55,0x04,0x30,                              /* [5796] OBJ_protocolInformation */
+0x55,0x04,0x31,                              /* [5799] OBJ_distinguishedName */
+0x55,0x04,0x32,                              /* [5802] OBJ_uniqueMember */
+0x55,0x04,0x33,                              /* [5805] OBJ_houseIdentifier */
+0x55,0x04,0x34,                              /* [5808] OBJ_supportedAlgorithms */
+0x55,0x04,0x35,                              /* [5811] OBJ_deltaRevocationList */
+0x55,0x04,0x36,                              /* [5814] OBJ_dmdName */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x09,/* [5817] OBJ_id_alg_PWRI_KEK */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x06,/* [5828] OBJ_aes_128_gcm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x07,/* [5837] OBJ_aes_128_ccm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x08,/* [5846] OBJ_id_aes128_wrap_pad */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1A,/* [5855] OBJ_aes_192_gcm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1B,/* [5864] OBJ_aes_192_ccm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1C,/* [5873] OBJ_id_aes192_wrap_pad */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2E,/* [5882] OBJ_aes_256_gcm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2F,/* [5891] OBJ_aes_256_ccm */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x30,/* [5900] OBJ_id_aes256_wrap_pad */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x02,/* [5909] OBJ_id_camellia128_wrap */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x03,/* [5920] OBJ_id_camellia192_wrap */
+0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x04,/* [5931] OBJ_id_camellia256_wrap */
+0x55,0x1D,0x25,0x00,                         /* [5942] OBJ_anyExtendedKeyUsage */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x08,/* [5946] OBJ_mgf1 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0A,/* [5955] OBJ_rsassaPss */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x07,/* [5964] OBJ_rsaesOaep */
+0x2B,0x24,                                   /* [5973] OBJ_teletrust */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,          /* [5975] OBJ_brainpool */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01,/* [5982] OBJ_brainpoolP160r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x02,/* [5991] OBJ_brainpoolP160t1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03,/* [6000] OBJ_brainpoolP192r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x04,/* [6009] OBJ_brainpoolP192t1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05,/* [6018] OBJ_brainpoolP224r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x06,/* [6027] OBJ_brainpoolP224t1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07,/* [6036] OBJ_brainpoolP256r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x08,/* [6045] OBJ_brainpoolP256t1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09,/* [6054] OBJ_brainpoolP320r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0A,/* [6063] OBJ_brainpoolP320t1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B,/* [6072] OBJ_brainpoolP384r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0C,/* [6081] OBJ_brainpoolP384t1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D,/* [6090] OBJ_brainpoolP512r1 */
+0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0E,/* [6099] OBJ_brainpoolP512t1 */
+0x2A,0x81,0x7A,0x01,0x81,0x5F,0x65,0x82,0x00,0x01,/* [6108] OBJ_FRP256v1 */
+0x2A,0x85,0x03,0x07,0x01,                    /* [6118] OBJ_tc26 */
+0x2A,0x85,0x03,0x07,0x01,0x01,0x02,0x02,     /* [6123] OBJ_id_tc26_gost3411_2012_256 */
+0x2A,0x85,0x03,0x07,0x01,0x01,0x02,0x03,     /* [6131] OBJ_id_tc26_gost3411_2012_512 */
+0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x02,0x01,/* [6139] OBJ_id_tc26_gost_3410_2012_512_paramSetA */
+0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x02,0x02,/* [6148] OBJ_id_tc26_gost_3410_2012_512_paramSetB */
+0x2A,0x85,0x03,0x07,0x01,0x02,0x05,0x01,0x01,/* [6157] OBJ_id_tc26_gost_28147_param_Z */
+0x2A,0x85,0x03,0x07,0x01,0x01,0x01,0x01,     /* [6166] OBJ_id_tc26_gost3410_2012_256 */
+0x2A,0x85,0x03,0x07,0x01,0x01,0x01,0x02,     /* [6174] OBJ_id_tc26_gost3410_2012_512 */
+0x2A,0x85,0x03,0x07,0x01,0x01,0x03,0x02,     /* [6182] OBJ_id_tc26_signwithdigest_gost3410_2012_256 */
+0x2A,0x85,0x03,0x07,0x01,0x01,0x03,0x03,     /* [6190] OBJ_id_tc26_signwithdigest_gost3410_2012_512 */
+};
+
+static const ASN1_OBJECT nid_objs[NUM_NID]={
+{"UNDEF","undefined",NID_undef,0,NULL,0},
+{"rsadsi","RSA Data Security, Inc.",NID_rsadsi,6,&(lvalues[0]),0},
+{"pkcs","RSA Data Security, Inc. PKCS",NID_pkcs,7,&(lvalues[6]),0},
+{"MD2","md2",NID_md2,8,&(lvalues[13]),0},
+{"MD5","md5",NID_md5,8,&(lvalues[21]),0},
+{"RC4","rc4",NID_rc4,8,&(lvalues[29]),0},
+{"rsaEncryption","rsaEncryption",NID_rsaEncryption,9,&(lvalues[37]),0},
+{"RSA-MD2","md2WithRSAEncryption",NID_md2WithRSAEncryption,9,
+	&(lvalues[46]),0},
+{"RSA-MD5","md5WithRSAEncryption",NID_md5WithRSAEncryption,9,
+	&(lvalues[55]),0},
+{"PBE-MD2-DES","pbeWithMD2AndDES-CBC",NID_pbeWithMD2AndDES_CBC,9,
+	&(lvalues[64]),0},
+{"PBE-MD5-DES","pbeWithMD5AndDES-CBC",NID_pbeWithMD5AndDES_CBC,9,
+	&(lvalues[73]),0},
+{"X500","directory services (X.500)",NID_X500,1,&(lvalues[82]),0},
+{"X509","X509",NID_X509,2,&(lvalues[83]),0},
+{"CN","commonName",NID_commonName,3,&(lvalues[85]),0},
+{"C","countryName",NID_countryName,3,&(lvalues[88]),0},
+{"L","localityName",NID_localityName,3,&(lvalues[91]),0},
+{"ST","stateOrProvinceName",NID_stateOrProvinceName,3,&(lvalues[94]),0},
+{"O","organizationName",NID_organizationName,3,&(lvalues[97]),0},
+{"OU","organizationalUnitName",NID_organizationalUnitName,3,
+	&(lvalues[100]),0},
+{"RSA","rsa",NID_rsa,4,&(lvalues[103]),0},
+{"pkcs7","pkcs7",NID_pkcs7,8,&(lvalues[107]),0},
+{"pkcs7-data","pkcs7-data",NID_pkcs7_data,9,&(lvalues[115]),0},
+{"pkcs7-signedData","pkcs7-signedData",NID_pkcs7_signed,9,
+	&(lvalues[124]),0},
+{"pkcs7-envelopedData","pkcs7-envelopedData",NID_pkcs7_enveloped,9,
+	&(lvalues[133]),0},
+{"pkcs7-signedAndEnvelopedData","pkcs7-signedAndEnvelopedData",
+	NID_pkcs7_signedAndEnveloped,9,&(lvalues[142]),0},
+{"pkcs7-digestData","pkcs7-digestData",NID_pkcs7_digest,9,
+	&(lvalues[151]),0},
+{"pkcs7-encryptedData","pkcs7-encryptedData",NID_pkcs7_encrypted,9,
+	&(lvalues[160]),0},
+{"pkcs3","pkcs3",NID_pkcs3,8,&(lvalues[169]),0},
+{"dhKeyAgreement","dhKeyAgreement",NID_dhKeyAgreement,9,
+	&(lvalues[177]),0},
+{"DES-ECB","des-ecb",NID_des_ecb,5,&(lvalues[186]),0},
+{"DES-CFB","des-cfb",NID_des_cfb64,5,&(lvalues[191]),0},
+{"DES-CBC","des-cbc",NID_des_cbc,5,&(lvalues[196]),0},
+{"DES-EDE","des-ede",NID_des_ede_ecb,5,&(lvalues[201]),0},
+{"DES-EDE3","des-ede3",NID_des_ede3_ecb,0,NULL,0},
+{"IDEA-CBC","idea-cbc",NID_idea_cbc,11,&(lvalues[206]),0},
+{"IDEA-CFB","idea-cfb",NID_idea_cfb64,0,NULL,0},
+{"IDEA-ECB","idea-ecb",NID_idea_ecb,0,NULL,0},
+{"RC2-CBC","rc2-cbc",NID_rc2_cbc,8,&(lvalues[217]),0},
+{"RC2-ECB","rc2-ecb",NID_rc2_ecb,0,NULL,0},
+{"RC2-CFB","rc2-cfb",NID_rc2_cfb64,0,NULL,0},
+{"RC2-OFB","rc2-ofb",NID_rc2_ofb64,0,NULL,0},
+{"SHA","sha",NID_sha,5,&(lvalues[225]),0},
+{"RSA-SHA","shaWithRSAEncryption",NID_shaWithRSAEncryption,5,
+	&(lvalues[230]),0},
+{"DES-EDE-CBC","des-ede-cbc",NID_des_ede_cbc,0,NULL,0},
+{"DES-EDE3-CBC","des-ede3-cbc",NID_des_ede3_cbc,8,&(lvalues[235]),0},
+{"DES-OFB","des-ofb",NID_des_ofb64,5,&(lvalues[243]),0},
+{"IDEA-OFB","idea-ofb",NID_idea_ofb64,0,NULL,0},
+{"pkcs9","pkcs9",NID_pkcs9,8,&(lvalues[248]),0},
+{"emailAddress","emailAddress",NID_pkcs9_emailAddress,9,
+	&(lvalues[256]),0},
+{"unstructuredName","unstructuredName",NID_pkcs9_unstructuredName,9,
+	&(lvalues[265]),0},
+{"contentType","contentType",NID_pkcs9_contentType,9,&(lvalues[274]),0},
+{"messageDigest","messageDigest",NID_pkcs9_messageDigest,9,
+	&(lvalues[283]),0},
+{"signingTime","signingTime",NID_pkcs9_signingTime,9,&(lvalues[292]),0},
+{"countersignature","countersignature",NID_pkcs9_countersignature,9,
+	&(lvalues[301]),0},
+{"challengePassword","challengePassword",NID_pkcs9_challengePassword,
+	9,&(lvalues[310]),0},
+{"unstructuredAddress","unstructuredAddress",
+	NID_pkcs9_unstructuredAddress,9,&(lvalues[319]),0},
+{"extendedCertificateAttributes","extendedCertificateAttributes",
+	NID_pkcs9_extCertAttributes,9,&(lvalues[328]),0},
+{"Netscape","Netscape Communications Corp.",NID_netscape,7,
+	&(lvalues[337]),0},
+{"nsCertExt","Netscape Certificate Extension",
+	NID_netscape_cert_extension,8,&(lvalues[344]),0},
+{"nsDataType","Netscape Data Type",NID_netscape_data_type,8,
+	&(lvalues[352]),0},
+{"DES-EDE-CFB","des-ede-cfb",NID_des_ede_cfb64,0,NULL,0},
+{"DES-EDE3-CFB","des-ede3-cfb",NID_des_ede3_cfb64,0,NULL,0},
+{"DES-EDE-OFB","des-ede-ofb",NID_des_ede_ofb64,0,NULL,0},
+{"DES-EDE3-OFB","des-ede3-ofb",NID_des_ede3_ofb64,0,NULL,0},
+{"SHA1","sha1",NID_sha1,5,&(lvalues[360]),0},
+{"RSA-SHA1","sha1WithRSAEncryption",NID_sha1WithRSAEncryption,9,
+	&(lvalues[365]),0},
+{"DSA-SHA","dsaWithSHA",NID_dsaWithSHA,5,&(lvalues[374]),0},
+{"DSA-old","dsaEncryption-old",NID_dsa_2,5,&(lvalues[379]),0},
+{"PBE-SHA1-RC2-64","pbeWithSHA1AndRC2-CBC",NID_pbeWithSHA1AndRC2_CBC,
+	9,&(lvalues[384]),0},
+{"PBKDF2","PBKDF2",NID_id_pbkdf2,9,&(lvalues[393]),0},
+{"DSA-SHA1-old","dsaWithSHA1-old",NID_dsaWithSHA1_2,5,&(lvalues[402]),0},
+{"nsCertType","Netscape Cert Type",NID_netscape_cert_type,9,
+	&(lvalues[407]),0},
+{"nsBaseUrl","Netscape Base Url",NID_netscape_base_url,9,
+	&(lvalues[416]),0},
+{"nsRevocationUrl","Netscape Revocation Url",
+	NID_netscape_revocation_url,9,&(lvalues[425]),0},
+{"nsCaRevocationUrl","Netscape CA Revocation Url",
+	NID_netscape_ca_revocation_url,9,&(lvalues[434]),0},
+{"nsRenewalUrl","Netscape Renewal Url",NID_netscape_renewal_url,9,
+	&(lvalues[443]),0},
+{"nsCaPolicyUrl","Netscape CA Policy Url",NID_netscape_ca_policy_url,
+	9,&(lvalues[452]),0},
+{"nsSslServerName","Netscape SSL Server Name",
+	NID_netscape_ssl_server_name,9,&(lvalues[461]),0},
+{"nsComment","Netscape Comment",NID_netscape_comment,9,&(lvalues[470]),0},
+{"nsCertSequence","Netscape Certificate Sequence",
+	NID_netscape_cert_sequence,9,&(lvalues[479]),0},
+{"DESX-CBC","desx-cbc",NID_desx_cbc,0,NULL,0},
+{"id-ce","id-ce",NID_id_ce,2,&(lvalues[488]),0},
+{"subjectKeyIdentifier","X509v3 Subject Key Identifier",
+	NID_subject_key_identifier,3,&(lvalues[490]),0},
+{"keyUsage","X509v3 Key Usage",NID_key_usage,3,&(lvalues[493]),0},
+{"privateKeyUsagePeriod","X509v3 Private Key Usage Period",
+	NID_private_key_usage_period,3,&(lvalues[496]),0},
+{"subjectAltName","X509v3 Subject Alternative Name",
+	NID_subject_alt_name,3,&(lvalues[499]),0},
+{"issuerAltName","X509v3 Issuer Alternative Name",NID_issuer_alt_name,
+	3,&(lvalues[502]),0},
+{"basicConstraints","X509v3 Basic Constraints",NID_basic_constraints,
+	3,&(lvalues[505]),0},
+{"crlNumber","X509v3 CRL Number",NID_crl_number,3,&(lvalues[508]),0},
+{"certificatePolicies","X509v3 Certificate Policies",
+	NID_certificate_policies,3,&(lvalues[511]),0},
+{"authorityKeyIdentifier","X509v3 Authority Key Identifier",
+	NID_authority_key_identifier,3,&(lvalues[514]),0},
+{"BF-CBC","bf-cbc",NID_bf_cbc,9,&(lvalues[517]),0},
+{"BF-ECB","bf-ecb",NID_bf_ecb,0,NULL,0},
+{"BF-CFB","bf-cfb",NID_bf_cfb64,0,NULL,0},
+{"BF-OFB","bf-ofb",NID_bf_ofb64,0,NULL,0},
+{"MDC2","mdc2",NID_mdc2,4,&(lvalues[526]),0},
+{"RSA-MDC2","mdc2WithRSA",NID_mdc2WithRSA,4,&(lvalues[530]),0},
+{"RC4-40","rc4-40",NID_rc4_40,0,NULL,0},
+{"RC2-40-CBC","rc2-40-cbc",NID_rc2_40_cbc,0,NULL,0},
+{"GN","givenName",NID_givenName,3,&(lvalues[534]),0},
+{"SN","surname",NID_surname,3,&(lvalues[537]),0},
+{"initials","initials",NID_initials,3,&(lvalues[540]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"crlDistributionPoints","X509v3 CRL Distribution Points",
+	NID_crl_distribution_points,3,&(lvalues[543]),0},
+{"RSA-NP-MD5","md5WithRSA",NID_md5WithRSA,5,&(lvalues[546]),0},
+{"serialNumber","serialNumber",NID_serialNumber,3,&(lvalues[551]),0},
+{"title","title",NID_title,3,&(lvalues[554]),0},
+{"description","description",NID_description,3,&(lvalues[557]),0},
+{"CAST5-CBC","cast5-cbc",NID_cast5_cbc,9,&(lvalues[560]),0},
+{"CAST5-ECB","cast5-ecb",NID_cast5_ecb,0,NULL,0},
+{"CAST5-CFB","cast5-cfb",NID_cast5_cfb64,0,NULL,0},
+{"CAST5-OFB","cast5-ofb",NID_cast5_ofb64,0,NULL,0},
+{"pbeWithMD5AndCast5CBC","pbeWithMD5AndCast5CBC",
+	NID_pbeWithMD5AndCast5_CBC,9,&(lvalues[569]),0},
+{"DSA-SHA1","dsaWithSHA1",NID_dsaWithSHA1,7,&(lvalues[578]),0},
+{"MD5-SHA1","md5-sha1",NID_md5_sha1,0,NULL,0},
+{"RSA-SHA1-2","sha1WithRSA",NID_sha1WithRSA,5,&(lvalues[585]),0},
+{"DSA","dsaEncryption",NID_dsa,7,&(lvalues[590]),0},
+{"RIPEMD160","ripemd160",NID_ripemd160,5,&(lvalues[597]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"RSA-RIPEMD160","ripemd160WithRSA",NID_ripemd160WithRSA,6,
+	&(lvalues[602]),0},
+{"RC5-CBC","rc5-cbc",NID_rc5_cbc,8,&(lvalues[608]),0},
+{"RC5-ECB","rc5-ecb",NID_rc5_ecb,0,NULL,0},
+{"RC5-CFB","rc5-cfb",NID_rc5_cfb64,0,NULL,0},
+{"RC5-OFB","rc5-ofb",NID_rc5_ofb64,0,NULL,0},
+{"RLE","run length compression",NID_rle_compression,6,&(lvalues[616]),0},
+{"ZLIB","zlib compression",NID_zlib_compression,11,&(lvalues[622]),0},
+{"extendedKeyUsage","X509v3 Extended Key Usage",NID_ext_key_usage,3,
+	&(lvalues[633]),0},
+{"PKIX","PKIX",NID_id_pkix,6,&(lvalues[636]),0},
+{"id-kp","id-kp",NID_id_kp,7,&(lvalues[642]),0},
+{"serverAuth","TLS Web Server Authentication",NID_server_auth,8,
+	&(lvalues[649]),0},
+{"clientAuth","TLS Web Client Authentication",NID_client_auth,8,
+	&(lvalues[657]),0},
+{"codeSigning","Code Signing",NID_code_sign,8,&(lvalues[665]),0},
+{"emailProtection","E-mail Protection",NID_email_protect,8,
+	&(lvalues[673]),0},
+{"timeStamping","Time Stamping",NID_time_stamp,8,&(lvalues[681]),0},
+{"msCodeInd","Microsoft Individual Code Signing",NID_ms_code_ind,10,
+	&(lvalues[689]),0},
+{"msCodeCom","Microsoft Commercial Code Signing",NID_ms_code_com,10,
+	&(lvalues[699]),0},
+{"msCTLSign","Microsoft Trust List Signing",NID_ms_ctl_sign,10,
+	&(lvalues[709]),0},
+{"msSGC","Microsoft Server Gated Crypto",NID_ms_sgc,10,&(lvalues[719]),0},
+{"msEFS","Microsoft Encrypted File System",NID_ms_efs,10,
+	&(lvalues[729]),0},
+{"nsSGC","Netscape Server Gated Crypto",NID_ns_sgc,9,&(lvalues[739]),0},
+{"deltaCRL","X509v3 Delta CRL Indicator",NID_delta_crl,3,
+	&(lvalues[748]),0},
+{"CRLReason","X509v3 CRL Reason Code",NID_crl_reason,3,&(lvalues[751]),0},
+{"invalidityDate","Invalidity Date",NID_invalidity_date,3,
+	&(lvalues[754]),0},
+{"SXNetID","Strong Extranet ID",NID_sxnet,5,&(lvalues[757]),0},
+{"PBE-SHA1-RC4-128","pbeWithSHA1And128BitRC4",
+	NID_pbe_WithSHA1And128BitRC4,10,&(lvalues[762]),0},
+{"PBE-SHA1-RC4-40","pbeWithSHA1And40BitRC4",
+	NID_pbe_WithSHA1And40BitRC4,10,&(lvalues[772]),0},
+{"PBE-SHA1-3DES","pbeWithSHA1And3-KeyTripleDES-CBC",
+	NID_pbe_WithSHA1And3_Key_TripleDES_CBC,10,&(lvalues[782]),0},
+{"PBE-SHA1-2DES","pbeWithSHA1And2-KeyTripleDES-CBC",
+	NID_pbe_WithSHA1And2_Key_TripleDES_CBC,10,&(lvalues[792]),0},
+{"PBE-SHA1-RC2-128","pbeWithSHA1And128BitRC2-CBC",
+	NID_pbe_WithSHA1And128BitRC2_CBC,10,&(lvalues[802]),0},
+{"PBE-SHA1-RC2-40","pbeWithSHA1And40BitRC2-CBC",
+	NID_pbe_WithSHA1And40BitRC2_CBC,10,&(lvalues[812]),0},
+{"keyBag","keyBag",NID_keyBag,11,&(lvalues[822]),0},
+{"pkcs8ShroudedKeyBag","pkcs8ShroudedKeyBag",NID_pkcs8ShroudedKeyBag,
+	11,&(lvalues[833]),0},
+{"certBag","certBag",NID_certBag,11,&(lvalues[844]),0},
+{"crlBag","crlBag",NID_crlBag,11,&(lvalues[855]),0},
+{"secretBag","secretBag",NID_secretBag,11,&(lvalues[866]),0},
+{"safeContentsBag","safeContentsBag",NID_safeContentsBag,11,
+	&(lvalues[877]),0},
+{"friendlyName","friendlyName",NID_friendlyName,9,&(lvalues[888]),0},
+{"localKeyID","localKeyID",NID_localKeyID,9,&(lvalues[897]),0},
+{"x509Certificate","x509Certificate",NID_x509Certificate,10,
+	&(lvalues[906]),0},
+{"sdsiCertificate","sdsiCertificate",NID_sdsiCertificate,10,
+	&(lvalues[916]),0},
+{"x509Crl","x509Crl",NID_x509Crl,10,&(lvalues[926]),0},
+{"PBES2","PBES2",NID_pbes2,9,&(lvalues[936]),0},
+{"PBMAC1","PBMAC1",NID_pbmac1,9,&(lvalues[945]),0},
+{"hmacWithSHA1","hmacWithSHA1",NID_hmacWithSHA1,8,&(lvalues[954]),0},
+{"id-qt-cps","Policy Qualifier CPS",NID_id_qt_cps,8,&(lvalues[962]),0},
+{"id-qt-unotice","Policy Qualifier User Notice",NID_id_qt_unotice,8,
+	&(lvalues[970]),0},
+{"RC2-64-CBC","rc2-64-cbc",NID_rc2_64_cbc,0,NULL,0},
+{"SMIME-CAPS","S/MIME Capabilities",NID_SMIMECapabilities,9,
+	&(lvalues[978]),0},
+{"PBE-MD2-RC2-64","pbeWithMD2AndRC2-CBC",NID_pbeWithMD2AndRC2_CBC,9,
+	&(lvalues[987]),0},
+{"PBE-MD5-RC2-64","pbeWithMD5AndRC2-CBC",NID_pbeWithMD5AndRC2_CBC,9,
+	&(lvalues[996]),0},
+{"PBE-SHA1-DES","pbeWithSHA1AndDES-CBC",NID_pbeWithSHA1AndDES_CBC,9,
+	&(lvalues[1005]),0},
+{"msExtReq","Microsoft Extension Request",NID_ms_ext_req,10,
+	&(lvalues[1014]),0},
+{"extReq","Extension Request",NID_ext_req,9,&(lvalues[1024]),0},
+{"name","name",NID_name,3,&(lvalues[1033]),0},
+{"dnQualifier","dnQualifier",NID_dnQualifier,3,&(lvalues[1036]),0},
+{"id-pe","id-pe",NID_id_pe,7,&(lvalues[1039]),0},
+{"id-ad","id-ad",NID_id_ad,7,&(lvalues[1046]),0},
+{"authorityInfoAccess","Authority Information Access",NID_info_access,
+	8,&(lvalues[1053]),0},
+{"OCSP","OCSP",NID_ad_OCSP,8,&(lvalues[1061]),0},
+{"caIssuers","CA Issuers",NID_ad_ca_issuers,8,&(lvalues[1069]),0},
+{"OCSPSigning","OCSP Signing",NID_OCSP_sign,8,&(lvalues[1077]),0},
+{"ISO","iso",NID_iso,0,NULL,0},
+{"member-body","ISO Member Body",NID_member_body,1,&(lvalues[1085]),0},
+{"ISO-US","ISO US Member Body",NID_ISO_US,3,&(lvalues[1086]),0},
+{"X9-57","X9.57",NID_X9_57,5,&(lvalues[1089]),0},
+{"X9cm","X9.57 CM ?",NID_X9cm,6,&(lvalues[1094]),0},
+{"pkcs1","pkcs1",NID_pkcs1,8,&(lvalues[1100]),0},
+{"pkcs5","pkcs5",NID_pkcs5,8,&(lvalues[1108]),0},
+{"SMIME","S/MIME",NID_SMIME,9,&(lvalues[1116]),0},
+{"id-smime-mod","id-smime-mod",NID_id_smime_mod,10,&(lvalues[1125]),0},
+{"id-smime-ct","id-smime-ct",NID_id_smime_ct,10,&(lvalues[1135]),0},
+{"id-smime-aa","id-smime-aa",NID_id_smime_aa,10,&(lvalues[1145]),0},
+{"id-smime-alg","id-smime-alg",NID_id_smime_alg,10,&(lvalues[1155]),0},
+{"id-smime-cd","id-smime-cd",NID_id_smime_cd,10,&(lvalues[1165]),0},
+{"id-smime-spq","id-smime-spq",NID_id_smime_spq,10,&(lvalues[1175]),0},
+{"id-smime-cti","id-smime-cti",NID_id_smime_cti,10,&(lvalues[1185]),0},
+{"id-smime-mod-cms","id-smime-mod-cms",NID_id_smime_mod_cms,11,
+	&(lvalues[1195]),0},
+{"id-smime-mod-ess","id-smime-mod-ess",NID_id_smime_mod_ess,11,
+	&(lvalues[1206]),0},
+{"id-smime-mod-oid","id-smime-mod-oid",NID_id_smime_mod_oid,11,
+	&(lvalues[1217]),0},
+{"id-smime-mod-msg-v3","id-smime-mod-msg-v3",NID_id_smime_mod_msg_v3,
+	11,&(lvalues[1228]),0},
+{"id-smime-mod-ets-eSignature-88","id-smime-mod-ets-eSignature-88",
+	NID_id_smime_mod_ets_eSignature_88,11,&(lvalues[1239]),0},
+{"id-smime-mod-ets-eSignature-97","id-smime-mod-ets-eSignature-97",
+	NID_id_smime_mod_ets_eSignature_97,11,&(lvalues[1250]),0},
+{"id-smime-mod-ets-eSigPolicy-88","id-smime-mod-ets-eSigPolicy-88",
+	NID_id_smime_mod_ets_eSigPolicy_88,11,&(lvalues[1261]),0},
+{"id-smime-mod-ets-eSigPolicy-97","id-smime-mod-ets-eSigPolicy-97",
+	NID_id_smime_mod_ets_eSigPolicy_97,11,&(lvalues[1272]),0},
+{"id-smime-ct-receipt","id-smime-ct-receipt",NID_id_smime_ct_receipt,
+	11,&(lvalues[1283]),0},
+{"id-smime-ct-authData","id-smime-ct-authData",
+	NID_id_smime_ct_authData,11,&(lvalues[1294]),0},
+{"id-smime-ct-publishCert","id-smime-ct-publishCert",
+	NID_id_smime_ct_publishCert,11,&(lvalues[1305]),0},
+{"id-smime-ct-TSTInfo","id-smime-ct-TSTInfo",NID_id_smime_ct_TSTInfo,
+	11,&(lvalues[1316]),0},
+{"id-smime-ct-TDTInfo","id-smime-ct-TDTInfo",NID_id_smime_ct_TDTInfo,
+	11,&(lvalues[1327]),0},
+{"id-smime-ct-contentInfo","id-smime-ct-contentInfo",
+	NID_id_smime_ct_contentInfo,11,&(lvalues[1338]),0},
+{"id-smime-ct-DVCSRequestData","id-smime-ct-DVCSRequestData",
+	NID_id_smime_ct_DVCSRequestData,11,&(lvalues[1349]),0},
+{"id-smime-ct-DVCSResponseData","id-smime-ct-DVCSResponseData",
+	NID_id_smime_ct_DVCSResponseData,11,&(lvalues[1360]),0},
+{"id-smime-aa-receiptRequest","id-smime-aa-receiptRequest",
+	NID_id_smime_aa_receiptRequest,11,&(lvalues[1371]),0},
+{"id-smime-aa-securityLabel","id-smime-aa-securityLabel",
+	NID_id_smime_aa_securityLabel,11,&(lvalues[1382]),0},
+{"id-smime-aa-mlExpandHistory","id-smime-aa-mlExpandHistory",
+	NID_id_smime_aa_mlExpandHistory,11,&(lvalues[1393]),0},
+{"id-smime-aa-contentHint","id-smime-aa-contentHint",
+	NID_id_smime_aa_contentHint,11,&(lvalues[1404]),0},
+{"id-smime-aa-msgSigDigest","id-smime-aa-msgSigDigest",
+	NID_id_smime_aa_msgSigDigest,11,&(lvalues[1415]),0},
+{"id-smime-aa-encapContentType","id-smime-aa-encapContentType",
+	NID_id_smime_aa_encapContentType,11,&(lvalues[1426]),0},
+{"id-smime-aa-contentIdentifier","id-smime-aa-contentIdentifier",
+	NID_id_smime_aa_contentIdentifier,11,&(lvalues[1437]),0},
+{"id-smime-aa-macValue","id-smime-aa-macValue",
+	NID_id_smime_aa_macValue,11,&(lvalues[1448]),0},
+{"id-smime-aa-equivalentLabels","id-smime-aa-equivalentLabels",
+	NID_id_smime_aa_equivalentLabels,11,&(lvalues[1459]),0},
+{"id-smime-aa-contentReference","id-smime-aa-contentReference",
+	NID_id_smime_aa_contentReference,11,&(lvalues[1470]),0},
+{"id-smime-aa-encrypKeyPref","id-smime-aa-encrypKeyPref",
+	NID_id_smime_aa_encrypKeyPref,11,&(lvalues[1481]),0},
+{"id-smime-aa-signingCertificate","id-smime-aa-signingCertificate",
+	NID_id_smime_aa_signingCertificate,11,&(lvalues[1492]),0},
+{"id-smime-aa-smimeEncryptCerts","id-smime-aa-smimeEncryptCerts",
+	NID_id_smime_aa_smimeEncryptCerts,11,&(lvalues[1503]),0},
+{"id-smime-aa-timeStampToken","id-smime-aa-timeStampToken",
+	NID_id_smime_aa_timeStampToken,11,&(lvalues[1514]),0},
+{"id-smime-aa-ets-sigPolicyId","id-smime-aa-ets-sigPolicyId",
+	NID_id_smime_aa_ets_sigPolicyId,11,&(lvalues[1525]),0},
+{"id-smime-aa-ets-commitmentType","id-smime-aa-ets-commitmentType",
+	NID_id_smime_aa_ets_commitmentType,11,&(lvalues[1536]),0},
+{"id-smime-aa-ets-signerLocation","id-smime-aa-ets-signerLocation",
+	NID_id_smime_aa_ets_signerLocation,11,&(lvalues[1547]),0},
+{"id-smime-aa-ets-signerAttr","id-smime-aa-ets-signerAttr",
+	NID_id_smime_aa_ets_signerAttr,11,&(lvalues[1558]),0},
+{"id-smime-aa-ets-otherSigCert","id-smime-aa-ets-otherSigCert",
+	NID_id_smime_aa_ets_otherSigCert,11,&(lvalues[1569]),0},
+{"id-smime-aa-ets-contentTimestamp",
+	"id-smime-aa-ets-contentTimestamp",
+	NID_id_smime_aa_ets_contentTimestamp,11,&(lvalues[1580]),0},
+{"id-smime-aa-ets-CertificateRefs","id-smime-aa-ets-CertificateRefs",
+	NID_id_smime_aa_ets_CertificateRefs,11,&(lvalues[1591]),0},
+{"id-smime-aa-ets-RevocationRefs","id-smime-aa-ets-RevocationRefs",
+	NID_id_smime_aa_ets_RevocationRefs,11,&(lvalues[1602]),0},
+{"id-smime-aa-ets-certValues","id-smime-aa-ets-certValues",
+	NID_id_smime_aa_ets_certValues,11,&(lvalues[1613]),0},
+{"id-smime-aa-ets-revocationValues",
+	"id-smime-aa-ets-revocationValues",
+	NID_id_smime_aa_ets_revocationValues,11,&(lvalues[1624]),0},
+{"id-smime-aa-ets-escTimeStamp","id-smime-aa-ets-escTimeStamp",
+	NID_id_smime_aa_ets_escTimeStamp,11,&(lvalues[1635]),0},
+{"id-smime-aa-ets-certCRLTimestamp",
+	"id-smime-aa-ets-certCRLTimestamp",
+	NID_id_smime_aa_ets_certCRLTimestamp,11,&(lvalues[1646]),0},
+{"id-smime-aa-ets-archiveTimeStamp",
+	"id-smime-aa-ets-archiveTimeStamp",
+	NID_id_smime_aa_ets_archiveTimeStamp,11,&(lvalues[1657]),0},
+{"id-smime-aa-signatureType","id-smime-aa-signatureType",
+	NID_id_smime_aa_signatureType,11,&(lvalues[1668]),0},
+{"id-smime-aa-dvcs-dvc","id-smime-aa-dvcs-dvc",
+	NID_id_smime_aa_dvcs_dvc,11,&(lvalues[1679]),0},
+{"id-smime-alg-ESDHwith3DES","id-smime-alg-ESDHwith3DES",
+	NID_id_smime_alg_ESDHwith3DES,11,&(lvalues[1690]),0},
+{"id-smime-alg-ESDHwithRC2","id-smime-alg-ESDHwithRC2",
+	NID_id_smime_alg_ESDHwithRC2,11,&(lvalues[1701]),0},
+{"id-smime-alg-3DESwrap","id-smime-alg-3DESwrap",
+	NID_id_smime_alg_3DESwrap,11,&(lvalues[1712]),0},
+{"id-smime-alg-RC2wrap","id-smime-alg-RC2wrap",
+	NID_id_smime_alg_RC2wrap,11,&(lvalues[1723]),0},
+{"id-smime-alg-ESDH","id-smime-alg-ESDH",NID_id_smime_alg_ESDH,11,
+	&(lvalues[1734]),0},
+{"id-smime-alg-CMS3DESwrap","id-smime-alg-CMS3DESwrap",
+	NID_id_smime_alg_CMS3DESwrap,11,&(lvalues[1745]),0},
+{"id-smime-alg-CMSRC2wrap","id-smime-alg-CMSRC2wrap",
+	NID_id_smime_alg_CMSRC2wrap,11,&(lvalues[1756]),0},
+{"id-smime-cd-ldap","id-smime-cd-ldap",NID_id_smime_cd_ldap,11,
+	&(lvalues[1767]),0},
+{"id-smime-spq-ets-sqt-uri","id-smime-spq-ets-sqt-uri",
+	NID_id_smime_spq_ets_sqt_uri,11,&(lvalues[1778]),0},
+{"id-smime-spq-ets-sqt-unotice","id-smime-spq-ets-sqt-unotice",
+	NID_id_smime_spq_ets_sqt_unotice,11,&(lvalues[1789]),0},
+{"id-smime-cti-ets-proofOfOrigin","id-smime-cti-ets-proofOfOrigin",
+	NID_id_smime_cti_ets_proofOfOrigin,11,&(lvalues[1800]),0},
+{"id-smime-cti-ets-proofOfReceipt","id-smime-cti-ets-proofOfReceipt",
+	NID_id_smime_cti_ets_proofOfReceipt,11,&(lvalues[1811]),0},
+{"id-smime-cti-ets-proofOfDelivery",
+	"id-smime-cti-ets-proofOfDelivery",
+	NID_id_smime_cti_ets_proofOfDelivery,11,&(lvalues[1822]),0},
+{"id-smime-cti-ets-proofOfSender","id-smime-cti-ets-proofOfSender",
+	NID_id_smime_cti_ets_proofOfSender,11,&(lvalues[1833]),0},
+{"id-smime-cti-ets-proofOfApproval",
+	"id-smime-cti-ets-proofOfApproval",
+	NID_id_smime_cti_ets_proofOfApproval,11,&(lvalues[1844]),0},
+{"id-smime-cti-ets-proofOfCreation",
+	"id-smime-cti-ets-proofOfCreation",
+	NID_id_smime_cti_ets_proofOfCreation,11,&(lvalues[1855]),0},
+{"MD4","md4",NID_md4,8,&(lvalues[1866]),0},
+{"id-pkix-mod","id-pkix-mod",NID_id_pkix_mod,7,&(lvalues[1874]),0},
+{"id-qt","id-qt",NID_id_qt,7,&(lvalues[1881]),0},
+{"id-it","id-it",NID_id_it,7,&(lvalues[1888]),0},
+{"id-pkip","id-pkip",NID_id_pkip,7,&(lvalues[1895]),0},
+{"id-alg","id-alg",NID_id_alg,7,&(lvalues[1902]),0},
+{"id-cmc","id-cmc",NID_id_cmc,7,&(lvalues[1909]),0},
+{"id-on","id-on",NID_id_on,7,&(lvalues[1916]),0},
+{"id-pda","id-pda",NID_id_pda,7,&(lvalues[1923]),0},
+{"id-aca","id-aca",NID_id_aca,7,&(lvalues[1930]),0},
+{"id-qcs","id-qcs",NID_id_qcs,7,&(lvalues[1937]),0},
+{"id-cct","id-cct",NID_id_cct,7,&(lvalues[1944]),0},
+{"id-pkix1-explicit-88","id-pkix1-explicit-88",
+	NID_id_pkix1_explicit_88,8,&(lvalues[1951]),0},
+{"id-pkix1-implicit-88","id-pkix1-implicit-88",
+	NID_id_pkix1_implicit_88,8,&(lvalues[1959]),0},
+{"id-pkix1-explicit-93","id-pkix1-explicit-93",
+	NID_id_pkix1_explicit_93,8,&(lvalues[1967]),0},
+{"id-pkix1-implicit-93","id-pkix1-implicit-93",
+	NID_id_pkix1_implicit_93,8,&(lvalues[1975]),0},
+{"id-mod-crmf","id-mod-crmf",NID_id_mod_crmf,8,&(lvalues[1983]),0},
+{"id-mod-cmc","id-mod-cmc",NID_id_mod_cmc,8,&(lvalues[1991]),0},
+{"id-mod-kea-profile-88","id-mod-kea-profile-88",
+	NID_id_mod_kea_profile_88,8,&(lvalues[1999]),0},
+{"id-mod-kea-profile-93","id-mod-kea-profile-93",
+	NID_id_mod_kea_profile_93,8,&(lvalues[2007]),0},
+{"id-mod-cmp","id-mod-cmp",NID_id_mod_cmp,8,&(lvalues[2015]),0},
+{"id-mod-qualified-cert-88","id-mod-qualified-cert-88",
+	NID_id_mod_qualified_cert_88,8,&(lvalues[2023]),0},
+{"id-mod-qualified-cert-93","id-mod-qualified-cert-93",
+	NID_id_mod_qualified_cert_93,8,&(lvalues[2031]),0},
+{"id-mod-attribute-cert","id-mod-attribute-cert",
+	NID_id_mod_attribute_cert,8,&(lvalues[2039]),0},
+{"id-mod-timestamp-protocol","id-mod-timestamp-protocol",
+	NID_id_mod_timestamp_protocol,8,&(lvalues[2047]),0},
+{"id-mod-ocsp","id-mod-ocsp",NID_id_mod_ocsp,8,&(lvalues[2055]),0},
+{"id-mod-dvcs","id-mod-dvcs",NID_id_mod_dvcs,8,&(lvalues[2063]),0},
+{"id-mod-cmp2000","id-mod-cmp2000",NID_id_mod_cmp2000,8,
+	&(lvalues[2071]),0},
+{"biometricInfo","Biometric Info",NID_biometricInfo,8,&(lvalues[2079]),0},
+{"qcStatements","qcStatements",NID_qcStatements,8,&(lvalues[2087]),0},
+{"ac-auditEntity","ac-auditEntity",NID_ac_auditEntity,8,
+	&(lvalues[2095]),0},
+{"ac-targeting","ac-targeting",NID_ac_targeting,8,&(lvalues[2103]),0},
+{"aaControls","aaControls",NID_aaControls,8,&(lvalues[2111]),0},
+{"sbgp-ipAddrBlock","sbgp-ipAddrBlock",NID_sbgp_ipAddrBlock,8,
+	&(lvalues[2119]),0},
+{"sbgp-autonomousSysNum","sbgp-autonomousSysNum",
+	NID_sbgp_autonomousSysNum,8,&(lvalues[2127]),0},
+{"sbgp-routerIdentifier","sbgp-routerIdentifier",
+	NID_sbgp_routerIdentifier,8,&(lvalues[2135]),0},
+{"textNotice","textNotice",NID_textNotice,8,&(lvalues[2143]),0},
+{"ipsecEndSystem","IPSec End System",NID_ipsecEndSystem,8,
+	&(lvalues[2151]),0},
+{"ipsecTunnel","IPSec Tunnel",NID_ipsecTunnel,8,&(lvalues[2159]),0},
+{"ipsecUser","IPSec User",NID_ipsecUser,8,&(lvalues[2167]),0},
+{"DVCS","dvcs",NID_dvcs,8,&(lvalues[2175]),0},
+{"id-it-caProtEncCert","id-it-caProtEncCert",NID_id_it_caProtEncCert,
+	8,&(lvalues[2183]),0},
+{"id-it-signKeyPairTypes","id-it-signKeyPairTypes",
+	NID_id_it_signKeyPairTypes,8,&(lvalues[2191]),0},
+{"id-it-encKeyPairTypes","id-it-encKeyPairTypes",
+	NID_id_it_encKeyPairTypes,8,&(lvalues[2199]),0},
+{"id-it-preferredSymmAlg","id-it-preferredSymmAlg",
+	NID_id_it_preferredSymmAlg,8,&(lvalues[2207]),0},
+{"id-it-caKeyUpdateInfo","id-it-caKeyUpdateInfo",
+	NID_id_it_caKeyUpdateInfo,8,&(lvalues[2215]),0},
+{"id-it-currentCRL","id-it-currentCRL",NID_id_it_currentCRL,8,
+	&(lvalues[2223]),0},
+{"id-it-unsupportedOIDs","id-it-unsupportedOIDs",
+	NID_id_it_unsupportedOIDs,8,&(lvalues[2231]),0},
+{"id-it-subscriptionRequest","id-it-subscriptionRequest",
+	NID_id_it_subscriptionRequest,8,&(lvalues[2239]),0},
+{"id-it-subscriptionResponse","id-it-subscriptionResponse",
+	NID_id_it_subscriptionResponse,8,&(lvalues[2247]),0},
+{"id-it-keyPairParamReq","id-it-keyPairParamReq",
+	NID_id_it_keyPairParamReq,8,&(lvalues[2255]),0},
+{"id-it-keyPairParamRep","id-it-keyPairParamRep",
+	NID_id_it_keyPairParamRep,8,&(lvalues[2263]),0},
+{"id-it-revPassphrase","id-it-revPassphrase",NID_id_it_revPassphrase,
+	8,&(lvalues[2271]),0},
+{"id-it-implicitConfirm","id-it-implicitConfirm",
+	NID_id_it_implicitConfirm,8,&(lvalues[2279]),0},
+{"id-it-confirmWaitTime","id-it-confirmWaitTime",
+	NID_id_it_confirmWaitTime,8,&(lvalues[2287]),0},
+{"id-it-origPKIMessage","id-it-origPKIMessage",
+	NID_id_it_origPKIMessage,8,&(lvalues[2295]),0},
+{"id-regCtrl","id-regCtrl",NID_id_regCtrl,8,&(lvalues[2303]),0},
+{"id-regInfo","id-regInfo",NID_id_regInfo,8,&(lvalues[2311]),0},
+{"id-regCtrl-regToken","id-regCtrl-regToken",NID_id_regCtrl_regToken,
+	9,&(lvalues[2319]),0},
+{"id-regCtrl-authenticator","id-regCtrl-authenticator",
+	NID_id_regCtrl_authenticator,9,&(lvalues[2328]),0},
+{"id-regCtrl-pkiPublicationInfo","id-regCtrl-pkiPublicationInfo",
+	NID_id_regCtrl_pkiPublicationInfo,9,&(lvalues[2337]),0},
+{"id-regCtrl-pkiArchiveOptions","id-regCtrl-pkiArchiveOptions",
+	NID_id_regCtrl_pkiArchiveOptions,9,&(lvalues[2346]),0},
+{"id-regCtrl-oldCertID","id-regCtrl-oldCertID",
+	NID_id_regCtrl_oldCertID,9,&(lvalues[2355]),0},
+{"id-regCtrl-protocolEncrKey","id-regCtrl-protocolEncrKey",
+	NID_id_regCtrl_protocolEncrKey,9,&(lvalues[2364]),0},
+{"id-regInfo-utf8Pairs","id-regInfo-utf8Pairs",
+	NID_id_regInfo_utf8Pairs,9,&(lvalues[2373]),0},
+{"id-regInfo-certReq","id-regInfo-certReq",NID_id_regInfo_certReq,9,
+	&(lvalues[2382]),0},
+{"id-alg-des40","id-alg-des40",NID_id_alg_des40,8,&(lvalues[2391]),0},
+{"id-alg-noSignature","id-alg-noSignature",NID_id_alg_noSignature,8,
+	&(lvalues[2399]),0},
+{"id-alg-dh-sig-hmac-sha1","id-alg-dh-sig-hmac-sha1",
+	NID_id_alg_dh_sig_hmac_sha1,8,&(lvalues[2407]),0},
+{"id-alg-dh-pop","id-alg-dh-pop",NID_id_alg_dh_pop,8,&(lvalues[2415]),0},
+{"id-cmc-statusInfo","id-cmc-statusInfo",NID_id_cmc_statusInfo,8,
+	&(lvalues[2423]),0},
+{"id-cmc-identification","id-cmc-identification",
+	NID_id_cmc_identification,8,&(lvalues[2431]),0},
+{"id-cmc-identityProof","id-cmc-identityProof",
+	NID_id_cmc_identityProof,8,&(lvalues[2439]),0},
+{"id-cmc-dataReturn","id-cmc-dataReturn",NID_id_cmc_dataReturn,8,
+	&(lvalues[2447]),0},
+{"id-cmc-transactionId","id-cmc-transactionId",
+	NID_id_cmc_transactionId,8,&(lvalues[2455]),0},
+{"id-cmc-senderNonce","id-cmc-senderNonce",NID_id_cmc_senderNonce,8,
+	&(lvalues[2463]),0},
+{"id-cmc-recipientNonce","id-cmc-recipientNonce",
+	NID_id_cmc_recipientNonce,8,&(lvalues[2471]),0},
+{"id-cmc-addExtensions","id-cmc-addExtensions",
+	NID_id_cmc_addExtensions,8,&(lvalues[2479]),0},
+{"id-cmc-encryptedPOP","id-cmc-encryptedPOP",NID_id_cmc_encryptedPOP,
+	8,&(lvalues[2487]),0},
+{"id-cmc-decryptedPOP","id-cmc-decryptedPOP",NID_id_cmc_decryptedPOP,
+	8,&(lvalues[2495]),0},
+{"id-cmc-lraPOPWitness","id-cmc-lraPOPWitness",
+	NID_id_cmc_lraPOPWitness,8,&(lvalues[2503]),0},
+{"id-cmc-getCert","id-cmc-getCert",NID_id_cmc_getCert,8,
+	&(lvalues[2511]),0},
+{"id-cmc-getCRL","id-cmc-getCRL",NID_id_cmc_getCRL,8,&(lvalues[2519]),0},
+{"id-cmc-revokeRequest","id-cmc-revokeRequest",
+	NID_id_cmc_revokeRequest,8,&(lvalues[2527]),0},
+{"id-cmc-regInfo","id-cmc-regInfo",NID_id_cmc_regInfo,8,
+	&(lvalues[2535]),0},
+{"id-cmc-responseInfo","id-cmc-responseInfo",NID_id_cmc_responseInfo,
+	8,&(lvalues[2543]),0},
+{"id-cmc-queryPending","id-cmc-queryPending",NID_id_cmc_queryPending,
+	8,&(lvalues[2551]),0},
+{"id-cmc-popLinkRandom","id-cmc-popLinkRandom",
+	NID_id_cmc_popLinkRandom,8,&(lvalues[2559]),0},
+{"id-cmc-popLinkWitness","id-cmc-popLinkWitness",
+	NID_id_cmc_popLinkWitness,8,&(lvalues[2567]),0},
+{"id-cmc-confirmCertAcceptance","id-cmc-confirmCertAcceptance",
+	NID_id_cmc_confirmCertAcceptance,8,&(lvalues[2575]),0},
+{"id-on-personalData","id-on-personalData",NID_id_on_personalData,8,
+	&(lvalues[2583]),0},
+{"id-pda-dateOfBirth","id-pda-dateOfBirth",NID_id_pda_dateOfBirth,8,
+	&(lvalues[2591]),0},
+{"id-pda-placeOfBirth","id-pda-placeOfBirth",NID_id_pda_placeOfBirth,
+	8,&(lvalues[2599]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"id-pda-gender","id-pda-gender",NID_id_pda_gender,8,&(lvalues[2607]),0},
+{"id-pda-countryOfCitizenship","id-pda-countryOfCitizenship",
+	NID_id_pda_countryOfCitizenship,8,&(lvalues[2615]),0},
+{"id-pda-countryOfResidence","id-pda-countryOfResidence",
+	NID_id_pda_countryOfResidence,8,&(lvalues[2623]),0},
+{"id-aca-authenticationInfo","id-aca-authenticationInfo",
+	NID_id_aca_authenticationInfo,8,&(lvalues[2631]),0},
+{"id-aca-accessIdentity","id-aca-accessIdentity",
+	NID_id_aca_accessIdentity,8,&(lvalues[2639]),0},
+{"id-aca-chargingIdentity","id-aca-chargingIdentity",
+	NID_id_aca_chargingIdentity,8,&(lvalues[2647]),0},
+{"id-aca-group","id-aca-group",NID_id_aca_group,8,&(lvalues[2655]),0},
+{"id-aca-role","id-aca-role",NID_id_aca_role,8,&(lvalues[2663]),0},
+{"id-qcs-pkixQCSyntax-v1","id-qcs-pkixQCSyntax-v1",
+	NID_id_qcs_pkixQCSyntax_v1,8,&(lvalues[2671]),0},
+{"id-cct-crs","id-cct-crs",NID_id_cct_crs,8,&(lvalues[2679]),0},
+{"id-cct-PKIData","id-cct-PKIData",NID_id_cct_PKIData,8,
+	&(lvalues[2687]),0},
+{"id-cct-PKIResponse","id-cct-PKIResponse",NID_id_cct_PKIResponse,8,
+	&(lvalues[2695]),0},
+{"ad_timestamping","AD Time Stamping",NID_ad_timeStamping,8,
+	&(lvalues[2703]),0},
+{"AD_DVCS","ad dvcs",NID_ad_dvcs,8,&(lvalues[2711]),0},
+{"basicOCSPResponse","Basic OCSP Response",NID_id_pkix_OCSP_basic,9,
+	&(lvalues[2719]),0},
+{"Nonce","OCSP Nonce",NID_id_pkix_OCSP_Nonce,9,&(lvalues[2728]),0},
+{"CrlID","OCSP CRL ID",NID_id_pkix_OCSP_CrlID,9,&(lvalues[2737]),0},
+{"acceptableResponses","Acceptable OCSP Responses",
+	NID_id_pkix_OCSP_acceptableResponses,9,&(lvalues[2746]),0},
+{"noCheck","OCSP No Check",NID_id_pkix_OCSP_noCheck,9,&(lvalues[2755]),0},
+{"archiveCutoff","OCSP Archive Cutoff",NID_id_pkix_OCSP_archiveCutoff,
+	9,&(lvalues[2764]),0},
+{"serviceLocator","OCSP Service Locator",
+	NID_id_pkix_OCSP_serviceLocator,9,&(lvalues[2773]),0},
+{"extendedStatus","Extended OCSP Status",
+	NID_id_pkix_OCSP_extendedStatus,9,&(lvalues[2782]),0},
+{"valid","valid",NID_id_pkix_OCSP_valid,9,&(lvalues[2791]),0},
+{"path","path",NID_id_pkix_OCSP_path,9,&(lvalues[2800]),0},
+{"trustRoot","Trust Root",NID_id_pkix_OCSP_trustRoot,9,
+	&(lvalues[2809]),0},
+{"algorithm","algorithm",NID_algorithm,4,&(lvalues[2818]),0},
+{"rsaSignature","rsaSignature",NID_rsaSignature,5,&(lvalues[2822]),0},
+{"X500algorithms","directory services - algorithms",
+	NID_X500algorithms,2,&(lvalues[2827]),0},
+{"ORG","org",NID_org,1,&(lvalues[2829]),0},
+{"DOD","dod",NID_dod,2,&(lvalues[2830]),0},
+{"IANA","iana",NID_iana,3,&(lvalues[2832]),0},
+{"directory","Directory",NID_Directory,4,&(lvalues[2835]),0},
+{"mgmt","Management",NID_Management,4,&(lvalues[2839]),0},
+{"experimental","Experimental",NID_Experimental,4,&(lvalues[2843]),0},
+{"private","Private",NID_Private,4,&(lvalues[2847]),0},
+{"security","Security",NID_Security,4,&(lvalues[2851]),0},
+{"snmpv2","SNMPv2",NID_SNMPv2,4,&(lvalues[2855]),0},
+{"Mail","Mail",NID_Mail,4,&(lvalues[2859]),0},
+{"enterprises","Enterprises",NID_Enterprises,5,&(lvalues[2863]),0},
+{"dcobject","dcObject",NID_dcObject,9,&(lvalues[2868]),0},
+{"DC","domainComponent",NID_domainComponent,10,&(lvalues[2877]),0},
+{"domain","Domain",NID_Domain,10,&(lvalues[2887]),0},
+{"NULL","NULL",NID_joint_iso_ccitt,0,NULL,0},
+{"selected-attribute-types","Selected Attribute Types",
+	NID_selected_attribute_types,3,&(lvalues[2897]),0},
+{"clearance","clearance",NID_clearance,4,&(lvalues[2900]),0},
+{"RSA-MD4","md4WithRSAEncryption",NID_md4WithRSAEncryption,9,
+	&(lvalues[2904]),0},
+{"ac-proxying","ac-proxying",NID_ac_proxying,8,&(lvalues[2913]),0},
+{"subjectInfoAccess","Subject Information Access",NID_sinfo_access,8,
+	&(lvalues[2921]),0},
+{"id-aca-encAttrs","id-aca-encAttrs",NID_id_aca_encAttrs,8,
+	&(lvalues[2929]),0},
+{"role","role",NID_role,3,&(lvalues[2937]),0},
+{"policyConstraints","X509v3 Policy Constraints",
+	NID_policy_constraints,3,&(lvalues[2940]),0},
+{"targetInformation","X509v3 AC Targeting",NID_target_information,3,
+	&(lvalues[2943]),0},
+{"noRevAvail","X509v3 No Revocation Available",NID_no_rev_avail,3,
+	&(lvalues[2946]),0},
+{"NULL","NULL",NID_ccitt,0,NULL,0},
+{"ansi-X9-62","ANSI X9.62",NID_ansi_X9_62,5,&(lvalues[2949]),0},
+{"prime-field","prime-field",NID_X9_62_prime_field,7,&(lvalues[2954]),0},
+{"characteristic-two-field","characteristic-two-field",
+	NID_X9_62_characteristic_two_field,7,&(lvalues[2961]),0},
+{"id-ecPublicKey","id-ecPublicKey",NID_X9_62_id_ecPublicKey,7,
+	&(lvalues[2968]),0},
+{"prime192v1","prime192v1",NID_X9_62_prime192v1,8,&(lvalues[2975]),0},
+{"prime192v2","prime192v2",NID_X9_62_prime192v2,8,&(lvalues[2983]),0},
+{"prime192v3","prime192v3",NID_X9_62_prime192v3,8,&(lvalues[2991]),0},
+{"prime239v1","prime239v1",NID_X9_62_prime239v1,8,&(lvalues[2999]),0},
+{"prime239v2","prime239v2",NID_X9_62_prime239v2,8,&(lvalues[3007]),0},
+{"prime239v3","prime239v3",NID_X9_62_prime239v3,8,&(lvalues[3015]),0},
+{"prime256v1","prime256v1",NID_X9_62_prime256v1,8,&(lvalues[3023]),0},
+{"ecdsa-with-SHA1","ecdsa-with-SHA1",NID_ecdsa_with_SHA1,7,
+	&(lvalues[3031]),0},
+{"CSPName","Microsoft CSP Name",NID_ms_csp_name,9,&(lvalues[3038]),0},
+{"AES-128-ECB","aes-128-ecb",NID_aes_128_ecb,9,&(lvalues[3047]),0},
+{"AES-128-CBC","aes-128-cbc",NID_aes_128_cbc,9,&(lvalues[3056]),0},
+{"AES-128-OFB","aes-128-ofb",NID_aes_128_ofb128,9,&(lvalues[3065]),0},
+{"AES-128-CFB","aes-128-cfb",NID_aes_128_cfb128,9,&(lvalues[3074]),0},
+{"AES-192-ECB","aes-192-ecb",NID_aes_192_ecb,9,&(lvalues[3083]),0},
+{"AES-192-CBC","aes-192-cbc",NID_aes_192_cbc,9,&(lvalues[3092]),0},
+{"AES-192-OFB","aes-192-ofb",NID_aes_192_ofb128,9,&(lvalues[3101]),0},
+{"AES-192-CFB","aes-192-cfb",NID_aes_192_cfb128,9,&(lvalues[3110]),0},
+{"AES-256-ECB","aes-256-ecb",NID_aes_256_ecb,9,&(lvalues[3119]),0},
+{"AES-256-CBC","aes-256-cbc",NID_aes_256_cbc,9,&(lvalues[3128]),0},
+{"AES-256-OFB","aes-256-ofb",NID_aes_256_ofb128,9,&(lvalues[3137]),0},
+{"AES-256-CFB","aes-256-cfb",NID_aes_256_cfb128,9,&(lvalues[3146]),0},
+{"holdInstructionCode","Hold Instruction Code",
+	NID_hold_instruction_code,3,&(lvalues[3155]),0},
+{"holdInstructionNone","Hold Instruction None",
+	NID_hold_instruction_none,7,&(lvalues[3158]),0},
+{"holdInstructionCallIssuer","Hold Instruction Call Issuer",
+	NID_hold_instruction_call_issuer,7,&(lvalues[3165]),0},
+{"holdInstructionReject","Hold Instruction Reject",
+	NID_hold_instruction_reject,7,&(lvalues[3172]),0},
+{"data","data",NID_data,1,&(lvalues[3179]),0},
+{"pss","pss",NID_pss,3,&(lvalues[3180]),0},
+{"ucl","ucl",NID_ucl,7,&(lvalues[3183]),0},
+{"pilot","pilot",NID_pilot,8,&(lvalues[3190]),0},
+{"pilotAttributeType","pilotAttributeType",NID_pilotAttributeType,9,
+	&(lvalues[3198]),0},
+{"pilotAttributeSyntax","pilotAttributeSyntax",
+	NID_pilotAttributeSyntax,9,&(lvalues[3207]),0},
+{"pilotObjectClass","pilotObjectClass",NID_pilotObjectClass,9,
+	&(lvalues[3216]),0},
+{"pilotGroups","pilotGroups",NID_pilotGroups,9,&(lvalues[3225]),0},
+{"iA5StringSyntax","iA5StringSyntax",NID_iA5StringSyntax,10,
+	&(lvalues[3234]),0},
+{"caseIgnoreIA5StringSyntax","caseIgnoreIA5StringSyntax",
+	NID_caseIgnoreIA5StringSyntax,10,&(lvalues[3244]),0},
+{"pilotObject","pilotObject",NID_pilotObject,10,&(lvalues[3254]),0},
+{"pilotPerson","pilotPerson",NID_pilotPerson,10,&(lvalues[3264]),0},
+{"account","account",NID_account,10,&(lvalues[3274]),0},
+{"document","document",NID_document,10,&(lvalues[3284]),0},
+{"room","room",NID_room,10,&(lvalues[3294]),0},
+{"documentSeries","documentSeries",NID_documentSeries,10,
+	&(lvalues[3304]),0},
+{"rFC822localPart","rFC822localPart",NID_rFC822localPart,10,
+	&(lvalues[3314]),0},
+{"dNSDomain","dNSDomain",NID_dNSDomain,10,&(lvalues[3324]),0},
+{"domainRelatedObject","domainRelatedObject",NID_domainRelatedObject,
+	10,&(lvalues[3334]),0},
+{"friendlyCountry","friendlyCountry",NID_friendlyCountry,10,
+	&(lvalues[3344]),0},
+{"simpleSecurityObject","simpleSecurityObject",
+	NID_simpleSecurityObject,10,&(lvalues[3354]),0},
+{"pilotOrganization","pilotOrganization",NID_pilotOrganization,10,
+	&(lvalues[3364]),0},
+{"pilotDSA","pilotDSA",NID_pilotDSA,10,&(lvalues[3374]),0},
+{"qualityLabelledData","qualityLabelledData",NID_qualityLabelledData,
+	10,&(lvalues[3384]),0},
+{"UID","userId",NID_userId,10,&(lvalues[3394]),0},
+{"textEncodedORAddress","textEncodedORAddress",
+	NID_textEncodedORAddress,10,&(lvalues[3404]),0},
+{"mail","rfc822Mailbox",NID_rfc822Mailbox,10,&(lvalues[3414]),0},
+{"info","info",NID_info,10,&(lvalues[3424]),0},
+{"favouriteDrink","favouriteDrink",NID_favouriteDrink,10,
+	&(lvalues[3434]),0},
+{"roomNumber","roomNumber",NID_roomNumber,10,&(lvalues[3444]),0},
+{"photo","photo",NID_photo,10,&(lvalues[3454]),0},
+{"userClass","userClass",NID_userClass,10,&(lvalues[3464]),0},
+{"host","host",NID_host,10,&(lvalues[3474]),0},
+{"manager","manager",NID_manager,10,&(lvalues[3484]),0},
+{"documentIdentifier","documentIdentifier",NID_documentIdentifier,10,
+	&(lvalues[3494]),0},
+{"documentTitle","documentTitle",NID_documentTitle,10,&(lvalues[3504]),0},
+{"documentVersion","documentVersion",NID_documentVersion,10,
+	&(lvalues[3514]),0},
+{"documentAuthor","documentAuthor",NID_documentAuthor,10,
+	&(lvalues[3524]),0},
+{"documentLocation","documentLocation",NID_documentLocation,10,
+	&(lvalues[3534]),0},
+{"homeTelephoneNumber","homeTelephoneNumber",NID_homeTelephoneNumber,
+	10,&(lvalues[3544]),0},
+{"secretary","secretary",NID_secretary,10,&(lvalues[3554]),0},
+{"otherMailbox","otherMailbox",NID_otherMailbox,10,&(lvalues[3564]),0},
+{"lastModifiedTime","lastModifiedTime",NID_lastModifiedTime,10,
+	&(lvalues[3574]),0},
+{"lastModifiedBy","lastModifiedBy",NID_lastModifiedBy,10,
+	&(lvalues[3584]),0},
+{"aRecord","aRecord",NID_aRecord,10,&(lvalues[3594]),0},
+{"pilotAttributeType27","pilotAttributeType27",
+	NID_pilotAttributeType27,10,&(lvalues[3604]),0},
+{"mXRecord","mXRecord",NID_mXRecord,10,&(lvalues[3614]),0},
+{"nSRecord","nSRecord",NID_nSRecord,10,&(lvalues[3624]),0},
+{"sOARecord","sOARecord",NID_sOARecord,10,&(lvalues[3634]),0},
+{"cNAMERecord","cNAMERecord",NID_cNAMERecord,10,&(lvalues[3644]),0},
+{"associatedDomain","associatedDomain",NID_associatedDomain,10,
+	&(lvalues[3654]),0},
+{"associatedName","associatedName",NID_associatedName,10,
+	&(lvalues[3664]),0},
+{"homePostalAddress","homePostalAddress",NID_homePostalAddress,10,
+	&(lvalues[3674]),0},
+{"personalTitle","personalTitle",NID_personalTitle,10,&(lvalues[3684]),0},
+{"mobileTelephoneNumber","mobileTelephoneNumber",
+	NID_mobileTelephoneNumber,10,&(lvalues[3694]),0},
+{"pagerTelephoneNumber","pagerTelephoneNumber",
+	NID_pagerTelephoneNumber,10,&(lvalues[3704]),0},
+{"friendlyCountryName","friendlyCountryName",NID_friendlyCountryName,
+	10,&(lvalues[3714]),0},
+{"organizationalStatus","organizationalStatus",
+	NID_organizationalStatus,10,&(lvalues[3724]),0},
+{"janetMailbox","janetMailbox",NID_janetMailbox,10,&(lvalues[3734]),0},
+{"mailPreferenceOption","mailPreferenceOption",
+	NID_mailPreferenceOption,10,&(lvalues[3744]),0},
+{"buildingName","buildingName",NID_buildingName,10,&(lvalues[3754]),0},
+{"dSAQuality","dSAQuality",NID_dSAQuality,10,&(lvalues[3764]),0},
+{"singleLevelQuality","singleLevelQuality",NID_singleLevelQuality,10,
+	&(lvalues[3774]),0},
+{"subtreeMinimumQuality","subtreeMinimumQuality",
+	NID_subtreeMinimumQuality,10,&(lvalues[3784]),0},
+{"subtreeMaximumQuality","subtreeMaximumQuality",
+	NID_subtreeMaximumQuality,10,&(lvalues[3794]),0},
+{"personalSignature","personalSignature",NID_personalSignature,10,
+	&(lvalues[3804]),0},
+{"dITRedirect","dITRedirect",NID_dITRedirect,10,&(lvalues[3814]),0},
+{"audio","audio",NID_audio,10,&(lvalues[3824]),0},
+{"documentPublisher","documentPublisher",NID_documentPublisher,10,
+	&(lvalues[3834]),0},
+{"x500UniqueIdentifier","x500UniqueIdentifier",
+	NID_x500UniqueIdentifier,3,&(lvalues[3844]),0},
+{"mime-mhs","MIME MHS",NID_mime_mhs,5,&(lvalues[3847]),0},
+{"mime-mhs-headings","mime-mhs-headings",NID_mime_mhs_headings,6,
+	&(lvalues[3852]),0},
+{"mime-mhs-bodies","mime-mhs-bodies",NID_mime_mhs_bodies,6,
+	&(lvalues[3858]),0},
+{"id-hex-partial-message","id-hex-partial-message",
+	NID_id_hex_partial_message,7,&(lvalues[3864]),0},
+{"id-hex-multipart-message","id-hex-multipart-message",
+	NID_id_hex_multipart_message,7,&(lvalues[3871]),0},
+{"generationQualifier","generationQualifier",NID_generationQualifier,
+	3,&(lvalues[3878]),0},
+{"pseudonym","pseudonym",NID_pseudonym,3,&(lvalues[3881]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"id-set","Secure Electronic Transactions",NID_id_set,2,
+	&(lvalues[3884]),0},
+{"set-ctype","content types",NID_set_ctype,3,&(lvalues[3886]),0},
+{"set-msgExt","message extensions",NID_set_msgExt,3,&(lvalues[3889]),0},
+{"set-attr","set-attr",NID_set_attr,3,&(lvalues[3892]),0},
+{"set-policy","set-policy",NID_set_policy,3,&(lvalues[3895]),0},
+{"set-certExt","certificate extensions",NID_set_certExt,3,
+	&(lvalues[3898]),0},
+{"set-brand","set-brand",NID_set_brand,3,&(lvalues[3901]),0},
+{"setct-PANData","setct-PANData",NID_setct_PANData,4,&(lvalues[3904]),0},
+{"setct-PANToken","setct-PANToken",NID_setct_PANToken,4,
+	&(lvalues[3908]),0},
+{"setct-PANOnly","setct-PANOnly",NID_setct_PANOnly,4,&(lvalues[3912]),0},
+{"setct-OIData","setct-OIData",NID_setct_OIData,4,&(lvalues[3916]),0},
+{"setct-PI","setct-PI",NID_setct_PI,4,&(lvalues[3920]),0},
+{"setct-PIData","setct-PIData",NID_setct_PIData,4,&(lvalues[3924]),0},
+{"setct-PIDataUnsigned","setct-PIDataUnsigned",
+	NID_setct_PIDataUnsigned,4,&(lvalues[3928]),0},
+{"setct-HODInput","setct-HODInput",NID_setct_HODInput,4,
+	&(lvalues[3932]),0},
+{"setct-AuthResBaggage","setct-AuthResBaggage",
+	NID_setct_AuthResBaggage,4,&(lvalues[3936]),0},
+{"setct-AuthRevReqBaggage","setct-AuthRevReqBaggage",
+	NID_setct_AuthRevReqBaggage,4,&(lvalues[3940]),0},
+{"setct-AuthRevResBaggage","setct-AuthRevResBaggage",
+	NID_setct_AuthRevResBaggage,4,&(lvalues[3944]),0},
+{"setct-CapTokenSeq","setct-CapTokenSeq",NID_setct_CapTokenSeq,4,
+	&(lvalues[3948]),0},
+{"setct-PInitResData","setct-PInitResData",NID_setct_PInitResData,4,
+	&(lvalues[3952]),0},
+{"setct-PI-TBS","setct-PI-TBS",NID_setct_PI_TBS,4,&(lvalues[3956]),0},
+{"setct-PResData","setct-PResData",NID_setct_PResData,4,
+	&(lvalues[3960]),0},
+{"setct-AuthReqTBS","setct-AuthReqTBS",NID_setct_AuthReqTBS,4,
+	&(lvalues[3964]),0},
+{"setct-AuthResTBS","setct-AuthResTBS",NID_setct_AuthResTBS,4,
+	&(lvalues[3968]),0},
+{"setct-AuthResTBSX","setct-AuthResTBSX",NID_setct_AuthResTBSX,4,
+	&(lvalues[3972]),0},
+{"setct-AuthTokenTBS","setct-AuthTokenTBS",NID_setct_AuthTokenTBS,4,
+	&(lvalues[3976]),0},
+{"setct-CapTokenData","setct-CapTokenData",NID_setct_CapTokenData,4,
+	&(lvalues[3980]),0},
+{"setct-CapTokenTBS","setct-CapTokenTBS",NID_setct_CapTokenTBS,4,
+	&(lvalues[3984]),0},
+{"setct-AcqCardCodeMsg","setct-AcqCardCodeMsg",
+	NID_setct_AcqCardCodeMsg,4,&(lvalues[3988]),0},
+{"setct-AuthRevReqTBS","setct-AuthRevReqTBS",NID_setct_AuthRevReqTBS,
+	4,&(lvalues[3992]),0},
+{"setct-AuthRevResData","setct-AuthRevResData",
+	NID_setct_AuthRevResData,4,&(lvalues[3996]),0},
+{"setct-AuthRevResTBS","setct-AuthRevResTBS",NID_setct_AuthRevResTBS,
+	4,&(lvalues[4000]),0},
+{"setct-CapReqTBS","setct-CapReqTBS",NID_setct_CapReqTBS,4,
+	&(lvalues[4004]),0},
+{"setct-CapReqTBSX","setct-CapReqTBSX",NID_setct_CapReqTBSX,4,
+	&(lvalues[4008]),0},
+{"setct-CapResData","setct-CapResData",NID_setct_CapResData,4,
+	&(lvalues[4012]),0},
+{"setct-CapRevReqTBS","setct-CapRevReqTBS",NID_setct_CapRevReqTBS,4,
+	&(lvalues[4016]),0},
+{"setct-CapRevReqTBSX","setct-CapRevReqTBSX",NID_setct_CapRevReqTBSX,
+	4,&(lvalues[4020]),0},
+{"setct-CapRevResData","setct-CapRevResData",NID_setct_CapRevResData,
+	4,&(lvalues[4024]),0},
+{"setct-CredReqTBS","setct-CredReqTBS",NID_setct_CredReqTBS,4,
+	&(lvalues[4028]),0},
+{"setct-CredReqTBSX","setct-CredReqTBSX",NID_setct_CredReqTBSX,4,
+	&(lvalues[4032]),0},
+{"setct-CredResData","setct-CredResData",NID_setct_CredResData,4,
+	&(lvalues[4036]),0},
+{"setct-CredRevReqTBS","setct-CredRevReqTBS",NID_setct_CredRevReqTBS,
+	4,&(lvalues[4040]),0},
+{"setct-CredRevReqTBSX","setct-CredRevReqTBSX",
+	NID_setct_CredRevReqTBSX,4,&(lvalues[4044]),0},
+{"setct-CredRevResData","setct-CredRevResData",
+	NID_setct_CredRevResData,4,&(lvalues[4048]),0},
+{"setct-PCertReqData","setct-PCertReqData",NID_setct_PCertReqData,4,
+	&(lvalues[4052]),0},
+{"setct-PCertResTBS","setct-PCertResTBS",NID_setct_PCertResTBS,4,
+	&(lvalues[4056]),0},
+{"setct-BatchAdminReqData","setct-BatchAdminReqData",
+	NID_setct_BatchAdminReqData,4,&(lvalues[4060]),0},
+{"setct-BatchAdminResData","setct-BatchAdminResData",
+	NID_setct_BatchAdminResData,4,&(lvalues[4064]),0},
+{"setct-CardCInitResTBS","setct-CardCInitResTBS",
+	NID_setct_CardCInitResTBS,4,&(lvalues[4068]),0},
+{"setct-MeAqCInitResTBS","setct-MeAqCInitResTBS",
+	NID_setct_MeAqCInitResTBS,4,&(lvalues[4072]),0},
+{"setct-RegFormResTBS","setct-RegFormResTBS",NID_setct_RegFormResTBS,
+	4,&(lvalues[4076]),0},
+{"setct-CertReqData","setct-CertReqData",NID_setct_CertReqData,4,
+	&(lvalues[4080]),0},
+{"setct-CertReqTBS","setct-CertReqTBS",NID_setct_CertReqTBS,4,
+	&(lvalues[4084]),0},
+{"setct-CertResData","setct-CertResData",NID_setct_CertResData,4,
+	&(lvalues[4088]),0},
+{"setct-CertInqReqTBS","setct-CertInqReqTBS",NID_setct_CertInqReqTBS,
+	4,&(lvalues[4092]),0},
+{"setct-ErrorTBS","setct-ErrorTBS",NID_setct_ErrorTBS,4,
+	&(lvalues[4096]),0},
+{"setct-PIDualSignedTBE","setct-PIDualSignedTBE",
+	NID_setct_PIDualSignedTBE,4,&(lvalues[4100]),0},
+{"setct-PIUnsignedTBE","setct-PIUnsignedTBE",NID_setct_PIUnsignedTBE,
+	4,&(lvalues[4104]),0},
+{"setct-AuthReqTBE","setct-AuthReqTBE",NID_setct_AuthReqTBE,4,
+	&(lvalues[4108]),0},
+{"setct-AuthResTBE","setct-AuthResTBE",NID_setct_AuthResTBE,4,
+	&(lvalues[4112]),0},
+{"setct-AuthResTBEX","setct-AuthResTBEX",NID_setct_AuthResTBEX,4,
+	&(lvalues[4116]),0},
+{"setct-AuthTokenTBE","setct-AuthTokenTBE",NID_setct_AuthTokenTBE,4,
+	&(lvalues[4120]),0},
+{"setct-CapTokenTBE","setct-CapTokenTBE",NID_setct_CapTokenTBE,4,
+	&(lvalues[4124]),0},
+{"setct-CapTokenTBEX","setct-CapTokenTBEX",NID_setct_CapTokenTBEX,4,
+	&(lvalues[4128]),0},
+{"setct-AcqCardCodeMsgTBE","setct-AcqCardCodeMsgTBE",
+	NID_setct_AcqCardCodeMsgTBE,4,&(lvalues[4132]),0},
+{"setct-AuthRevReqTBE","setct-AuthRevReqTBE",NID_setct_AuthRevReqTBE,
+	4,&(lvalues[4136]),0},
+{"setct-AuthRevResTBE","setct-AuthRevResTBE",NID_setct_AuthRevResTBE,
+	4,&(lvalues[4140]),0},
+{"setct-AuthRevResTBEB","setct-AuthRevResTBEB",
+	NID_setct_AuthRevResTBEB,4,&(lvalues[4144]),0},
+{"setct-CapReqTBE","setct-CapReqTBE",NID_setct_CapReqTBE,4,
+	&(lvalues[4148]),0},
+{"setct-CapReqTBEX","setct-CapReqTBEX",NID_setct_CapReqTBEX,4,
+	&(lvalues[4152]),0},
+{"setct-CapResTBE","setct-CapResTBE",NID_setct_CapResTBE,4,
+	&(lvalues[4156]),0},
+{"setct-CapRevReqTBE","setct-CapRevReqTBE",NID_setct_CapRevReqTBE,4,
+	&(lvalues[4160]),0},
+{"setct-CapRevReqTBEX","setct-CapRevReqTBEX",NID_setct_CapRevReqTBEX,
+	4,&(lvalues[4164]),0},
+{"setct-CapRevResTBE","setct-CapRevResTBE",NID_setct_CapRevResTBE,4,
+	&(lvalues[4168]),0},
+{"setct-CredReqTBE","setct-CredReqTBE",NID_setct_CredReqTBE,4,
+	&(lvalues[4172]),0},
+{"setct-CredReqTBEX","setct-CredReqTBEX",NID_setct_CredReqTBEX,4,
+	&(lvalues[4176]),0},
+{"setct-CredResTBE","setct-CredResTBE",NID_setct_CredResTBE,4,
+	&(lvalues[4180]),0},
+{"setct-CredRevReqTBE","setct-CredRevReqTBE",NID_setct_CredRevReqTBE,
+	4,&(lvalues[4184]),0},
+{"setct-CredRevReqTBEX","setct-CredRevReqTBEX",
+	NID_setct_CredRevReqTBEX,4,&(lvalues[4188]),0},
+{"setct-CredRevResTBE","setct-CredRevResTBE",NID_setct_CredRevResTBE,
+	4,&(lvalues[4192]),0},
+{"setct-BatchAdminReqTBE","setct-BatchAdminReqTBE",
+	NID_setct_BatchAdminReqTBE,4,&(lvalues[4196]),0},
+{"setct-BatchAdminResTBE","setct-BatchAdminResTBE",
+	NID_setct_BatchAdminResTBE,4,&(lvalues[4200]),0},
+{"setct-RegFormReqTBE","setct-RegFormReqTBE",NID_setct_RegFormReqTBE,
+	4,&(lvalues[4204]),0},
+{"setct-CertReqTBE","setct-CertReqTBE",NID_setct_CertReqTBE,4,
+	&(lvalues[4208]),0},
+{"setct-CertReqTBEX","setct-CertReqTBEX",NID_setct_CertReqTBEX,4,
+	&(lvalues[4212]),0},
+{"setct-CertResTBE","setct-CertResTBE",NID_setct_CertResTBE,4,
+	&(lvalues[4216]),0},
+{"setct-CRLNotificationTBS","setct-CRLNotificationTBS",
+	NID_setct_CRLNotificationTBS,4,&(lvalues[4220]),0},
+{"setct-CRLNotificationResTBS","setct-CRLNotificationResTBS",
+	NID_setct_CRLNotificationResTBS,4,&(lvalues[4224]),0},
+{"setct-BCIDistributionTBS","setct-BCIDistributionTBS",
+	NID_setct_BCIDistributionTBS,4,&(lvalues[4228]),0},
+{"setext-genCrypt","generic cryptogram",NID_setext_genCrypt,4,
+	&(lvalues[4232]),0},
+{"setext-miAuth","merchant initiated auth",NID_setext_miAuth,4,
+	&(lvalues[4236]),0},
+{"setext-pinSecure","setext-pinSecure",NID_setext_pinSecure,4,
+	&(lvalues[4240]),0},
+{"setext-pinAny","setext-pinAny",NID_setext_pinAny,4,&(lvalues[4244]),0},
+{"setext-track2","setext-track2",NID_setext_track2,4,&(lvalues[4248]),0},
+{"setext-cv","additional verification",NID_setext_cv,4,
+	&(lvalues[4252]),0},
+{"set-policy-root","set-policy-root",NID_set_policy_root,4,
+	&(lvalues[4256]),0},
+{"setCext-hashedRoot","setCext-hashedRoot",NID_setCext_hashedRoot,4,
+	&(lvalues[4260]),0},
+{"setCext-certType","setCext-certType",NID_setCext_certType,4,
+	&(lvalues[4264]),0},
+{"setCext-merchData","setCext-merchData",NID_setCext_merchData,4,
+	&(lvalues[4268]),0},
+{"setCext-cCertRequired","setCext-cCertRequired",
+	NID_setCext_cCertRequired,4,&(lvalues[4272]),0},
+{"setCext-tunneling","setCext-tunneling",NID_setCext_tunneling,4,
+	&(lvalues[4276]),0},
+{"setCext-setExt","setCext-setExt",NID_setCext_setExt,4,
+	&(lvalues[4280]),0},
+{"setCext-setQualf","setCext-setQualf",NID_setCext_setQualf,4,
+	&(lvalues[4284]),0},
+{"setCext-PGWYcapabilities","setCext-PGWYcapabilities",
+	NID_setCext_PGWYcapabilities,4,&(lvalues[4288]),0},
+{"setCext-TokenIdentifier","setCext-TokenIdentifier",
+	NID_setCext_TokenIdentifier,4,&(lvalues[4292]),0},
+{"setCext-Track2Data","setCext-Track2Data",NID_setCext_Track2Data,4,
+	&(lvalues[4296]),0},
+{"setCext-TokenType","setCext-TokenType",NID_setCext_TokenType,4,
+	&(lvalues[4300]),0},
+{"setCext-IssuerCapabilities","setCext-IssuerCapabilities",
+	NID_setCext_IssuerCapabilities,4,&(lvalues[4304]),0},
+{"setAttr-Cert","setAttr-Cert",NID_setAttr_Cert,4,&(lvalues[4308]),0},
+{"setAttr-PGWYcap","payment gateway capabilities",NID_setAttr_PGWYcap,
+	4,&(lvalues[4312]),0},
+{"setAttr-TokenType","setAttr-TokenType",NID_setAttr_TokenType,4,
+	&(lvalues[4316]),0},
+{"setAttr-IssCap","issuer capabilities",NID_setAttr_IssCap,4,
+	&(lvalues[4320]),0},
+{"set-rootKeyThumb","set-rootKeyThumb",NID_set_rootKeyThumb,5,
+	&(lvalues[4324]),0},
+{"set-addPolicy","set-addPolicy",NID_set_addPolicy,5,&(lvalues[4329]),0},
+{"setAttr-Token-EMV","setAttr-Token-EMV",NID_setAttr_Token_EMV,5,
+	&(lvalues[4334]),0},
+{"setAttr-Token-B0Prime","setAttr-Token-B0Prime",
+	NID_setAttr_Token_B0Prime,5,&(lvalues[4339]),0},
+{"setAttr-IssCap-CVM","setAttr-IssCap-CVM",NID_setAttr_IssCap_CVM,5,
+	&(lvalues[4344]),0},
+{"setAttr-IssCap-T2","setAttr-IssCap-T2",NID_setAttr_IssCap_T2,5,
+	&(lvalues[4349]),0},
+{"setAttr-IssCap-Sig","setAttr-IssCap-Sig",NID_setAttr_IssCap_Sig,5,
+	&(lvalues[4354]),0},
+{"setAttr-GenCryptgrm","generate cryptogram",NID_setAttr_GenCryptgrm,
+	6,&(lvalues[4359]),0},
+{"setAttr-T2Enc","encrypted track 2",NID_setAttr_T2Enc,6,
+	&(lvalues[4365]),0},
+{"setAttr-T2cleartxt","cleartext track 2",NID_setAttr_T2cleartxt,6,
+	&(lvalues[4371]),0},
+{"setAttr-TokICCsig","ICC or token signature",NID_setAttr_TokICCsig,6,
+	&(lvalues[4377]),0},
+{"setAttr-SecDevSig","secure device signature",NID_setAttr_SecDevSig,
+	6,&(lvalues[4383]),0},
+{"set-brand-IATA-ATA","set-brand-IATA-ATA",NID_set_brand_IATA_ATA,4,
+	&(lvalues[4389]),0},
+{"set-brand-Diners","set-brand-Diners",NID_set_brand_Diners,4,
+	&(lvalues[4393]),0},
+{"set-brand-AmericanExpress","set-brand-AmericanExpress",
+	NID_set_brand_AmericanExpress,4,&(lvalues[4397]),0},
+{"set-brand-JCB","set-brand-JCB",NID_set_brand_JCB,4,&(lvalues[4401]),0},
+{"set-brand-Visa","set-brand-Visa",NID_set_brand_Visa,4,
+	&(lvalues[4405]),0},
+{"set-brand-MasterCard","set-brand-MasterCard",
+	NID_set_brand_MasterCard,4,&(lvalues[4409]),0},
+{"set-brand-Novus","set-brand-Novus",NID_set_brand_Novus,5,
+	&(lvalues[4413]),0},
+{"DES-CDMF","des-cdmf",NID_des_cdmf,8,&(lvalues[4418]),0},
+{"rsaOAEPEncryptionSET","rsaOAEPEncryptionSET",
+	NID_rsaOAEPEncryptionSET,9,&(lvalues[4426]),0},
+{"ITU-T","itu-t",NID_itu_t,0,NULL,0},
+{"JOINT-ISO-ITU-T","joint-iso-itu-t",NID_joint_iso_itu_t,0,NULL,0},
+{"international-organizations","International Organizations",
+	NID_international_organizations,1,&(lvalues[4435]),0},
+{"msSmartcardLogin","Microsoft Smartcardlogin",NID_ms_smartcard_login,
+	10,&(lvalues[4436]),0},
+{"msUPN","Microsoft Universal Principal Name",NID_ms_upn,10,
+	&(lvalues[4446]),0},
+{"AES-128-CFB1","aes-128-cfb1",NID_aes_128_cfb1,0,NULL,0},
+{"AES-192-CFB1","aes-192-cfb1",NID_aes_192_cfb1,0,NULL,0},
+{"AES-256-CFB1","aes-256-cfb1",NID_aes_256_cfb1,0,NULL,0},
+{"AES-128-CFB8","aes-128-cfb8",NID_aes_128_cfb8,0,NULL,0},
+{"AES-192-CFB8","aes-192-cfb8",NID_aes_192_cfb8,0,NULL,0},
+{"AES-256-CFB8","aes-256-cfb8",NID_aes_256_cfb8,0,NULL,0},
+{"DES-CFB1","des-cfb1",NID_des_cfb1,0,NULL,0},
+{"DES-CFB8","des-cfb8",NID_des_cfb8,0,NULL,0},
+{"DES-EDE3-CFB1","des-ede3-cfb1",NID_des_ede3_cfb1,0,NULL,0},
+{"DES-EDE3-CFB8","des-ede3-cfb8",NID_des_ede3_cfb8,0,NULL,0},
+{"street","streetAddress",NID_streetAddress,3,&(lvalues[4456]),0},
+{"postalCode","postalCode",NID_postalCode,3,&(lvalues[4459]),0},
+{"id-ppl","id-ppl",NID_id_ppl,7,&(lvalues[4462]),0},
+{"proxyCertInfo","Proxy Certificate Information",NID_proxyCertInfo,8,
+	&(lvalues[4469]),0},
+{"id-ppl-anyLanguage","Any language",NID_id_ppl_anyLanguage,8,
+	&(lvalues[4477]),0},
+{"id-ppl-inheritAll","Inherit all",NID_id_ppl_inheritAll,8,
+	&(lvalues[4485]),0},
+{"nameConstraints","X509v3 Name Constraints",NID_name_constraints,3,
+	&(lvalues[4493]),0},
+{"id-ppl-independent","Independent",NID_Independent,8,&(lvalues[4496]),0},
+{"RSA-SHA256","sha256WithRSAEncryption",NID_sha256WithRSAEncryption,9,
+	&(lvalues[4504]),0},
+{"RSA-SHA384","sha384WithRSAEncryption",NID_sha384WithRSAEncryption,9,
+	&(lvalues[4513]),0},
+{"RSA-SHA512","sha512WithRSAEncryption",NID_sha512WithRSAEncryption,9,
+	&(lvalues[4522]),0},
+{"RSA-SHA224","sha224WithRSAEncryption",NID_sha224WithRSAEncryption,9,
+	&(lvalues[4531]),0},
+{"SHA256","sha256",NID_sha256,9,&(lvalues[4540]),0},
+{"SHA384","sha384",NID_sha384,9,&(lvalues[4549]),0},
+{"SHA512","sha512",NID_sha512,9,&(lvalues[4558]),0},
+{"SHA224","sha224",NID_sha224,9,&(lvalues[4567]),0},
+{"identified-organization","identified-organization",
+	NID_identified_organization,1,&(lvalues[4576]),0},
+{"certicom-arc","certicom-arc",NID_certicom_arc,3,&(lvalues[4577]),0},
+{"wap","wap",NID_wap,2,&(lvalues[4580]),0},
+{"wap-wsg","wap-wsg",NID_wap_wsg,3,&(lvalues[4582]),0},
+{"id-characteristic-two-basis","id-characteristic-two-basis",
+	NID_X9_62_id_characteristic_two_basis,8,&(lvalues[4585]),0},
+{"onBasis","onBasis",NID_X9_62_onBasis,9,&(lvalues[4593]),0},
+{"tpBasis","tpBasis",NID_X9_62_tpBasis,9,&(lvalues[4602]),0},
+{"ppBasis","ppBasis",NID_X9_62_ppBasis,9,&(lvalues[4611]),0},
+{"c2pnb163v1","c2pnb163v1",NID_X9_62_c2pnb163v1,8,&(lvalues[4620]),0},
+{"c2pnb163v2","c2pnb163v2",NID_X9_62_c2pnb163v2,8,&(lvalues[4628]),0},
+{"c2pnb163v3","c2pnb163v3",NID_X9_62_c2pnb163v3,8,&(lvalues[4636]),0},
+{"c2pnb176v1","c2pnb176v1",NID_X9_62_c2pnb176v1,8,&(lvalues[4644]),0},
+{"c2tnb191v1","c2tnb191v1",NID_X9_62_c2tnb191v1,8,&(lvalues[4652]),0},
+{"c2tnb191v2","c2tnb191v2",NID_X9_62_c2tnb191v2,8,&(lvalues[4660]),0},
+{"c2tnb191v3","c2tnb191v3",NID_X9_62_c2tnb191v3,8,&(lvalues[4668]),0},
+{"c2onb191v4","c2onb191v4",NID_X9_62_c2onb191v4,8,&(lvalues[4676]),0},
+{"c2onb191v5","c2onb191v5",NID_X9_62_c2onb191v5,8,&(lvalues[4684]),0},
+{"c2pnb208w1","c2pnb208w1",NID_X9_62_c2pnb208w1,8,&(lvalues[4692]),0},
+{"c2tnb239v1","c2tnb239v1",NID_X9_62_c2tnb239v1,8,&(lvalues[4700]),0},
+{"c2tnb239v2","c2tnb239v2",NID_X9_62_c2tnb239v2,8,&(lvalues[4708]),0},
+{"c2tnb239v3","c2tnb239v3",NID_X9_62_c2tnb239v3,8,&(lvalues[4716]),0},
+{"c2onb239v4","c2onb239v4",NID_X9_62_c2onb239v4,8,&(lvalues[4724]),0},
+{"c2onb239v5","c2onb239v5",NID_X9_62_c2onb239v5,8,&(lvalues[4732]),0},
+{"c2pnb272w1","c2pnb272w1",NID_X9_62_c2pnb272w1,8,&(lvalues[4740]),0},
+{"c2pnb304w1","c2pnb304w1",NID_X9_62_c2pnb304w1,8,&(lvalues[4748]),0},
+{"c2tnb359v1","c2tnb359v1",NID_X9_62_c2tnb359v1,8,&(lvalues[4756]),0},
+{"c2pnb368w1","c2pnb368w1",NID_X9_62_c2pnb368w1,8,&(lvalues[4764]),0},
+{"c2tnb431r1","c2tnb431r1",NID_X9_62_c2tnb431r1,8,&(lvalues[4772]),0},
+{"secp112r1","secp112r1",NID_secp112r1,5,&(lvalues[4780]),0},
+{"secp112r2","secp112r2",NID_secp112r2,5,&(lvalues[4785]),0},
+{"secp128r1","secp128r1",NID_secp128r1,5,&(lvalues[4790]),0},
+{"secp128r2","secp128r2",NID_secp128r2,5,&(lvalues[4795]),0},
+{"secp160k1","secp160k1",NID_secp160k1,5,&(lvalues[4800]),0},
+{"secp160r1","secp160r1",NID_secp160r1,5,&(lvalues[4805]),0},
+{"secp160r2","secp160r2",NID_secp160r2,5,&(lvalues[4810]),0},
+{"secp192k1","secp192k1",NID_secp192k1,5,&(lvalues[4815]),0},
+{"secp224k1","secp224k1",NID_secp224k1,5,&(lvalues[4820]),0},
+{"secp224r1","secp224r1",NID_secp224r1,5,&(lvalues[4825]),0},
+{"secp256k1","secp256k1",NID_secp256k1,5,&(lvalues[4830]),0},
+{"secp384r1","secp384r1",NID_secp384r1,5,&(lvalues[4835]),0},
+{"secp521r1","secp521r1",NID_secp521r1,5,&(lvalues[4840]),0},
+{"sect113r1","sect113r1",NID_sect113r1,5,&(lvalues[4845]),0},
+{"sect113r2","sect113r2",NID_sect113r2,5,&(lvalues[4850]),0},
+{"sect131r1","sect131r1",NID_sect131r1,5,&(lvalues[4855]),0},
+{"sect131r2","sect131r2",NID_sect131r2,5,&(lvalues[4860]),0},
+{"sect163k1","sect163k1",NID_sect163k1,5,&(lvalues[4865]),0},
+{"sect163r1","sect163r1",NID_sect163r1,5,&(lvalues[4870]),0},
+{"sect163r2","sect163r2",NID_sect163r2,5,&(lvalues[4875]),0},
+{"sect193r1","sect193r1",NID_sect193r1,5,&(lvalues[4880]),0},
+{"sect193r2","sect193r2",NID_sect193r2,5,&(lvalues[4885]),0},
+{"sect233k1","sect233k1",NID_sect233k1,5,&(lvalues[4890]),0},
+{"sect233r1","sect233r1",NID_sect233r1,5,&(lvalues[4895]),0},
+{"sect239k1","sect239k1",NID_sect239k1,5,&(lvalues[4900]),0},
+{"sect283k1","sect283k1",NID_sect283k1,5,&(lvalues[4905]),0},
+{"sect283r1","sect283r1",NID_sect283r1,5,&(lvalues[4910]),0},
+{"sect409k1","sect409k1",NID_sect409k1,5,&(lvalues[4915]),0},
+{"sect409r1","sect409r1",NID_sect409r1,5,&(lvalues[4920]),0},
+{"sect571k1","sect571k1",NID_sect571k1,5,&(lvalues[4925]),0},
+{"sect571r1","sect571r1",NID_sect571r1,5,&(lvalues[4930]),0},
+{"wap-wsg-idm-ecid-wtls1","wap-wsg-idm-ecid-wtls1",
+	NID_wap_wsg_idm_ecid_wtls1,5,&(lvalues[4935]),0},
+{"wap-wsg-idm-ecid-wtls3","wap-wsg-idm-ecid-wtls3",
+	NID_wap_wsg_idm_ecid_wtls3,5,&(lvalues[4940]),0},
+{"wap-wsg-idm-ecid-wtls4","wap-wsg-idm-ecid-wtls4",
+	NID_wap_wsg_idm_ecid_wtls4,5,&(lvalues[4945]),0},
+{"wap-wsg-idm-ecid-wtls5","wap-wsg-idm-ecid-wtls5",
+	NID_wap_wsg_idm_ecid_wtls5,5,&(lvalues[4950]),0},
+{"wap-wsg-idm-ecid-wtls6","wap-wsg-idm-ecid-wtls6",
+	NID_wap_wsg_idm_ecid_wtls6,5,&(lvalues[4955]),0},
+{"wap-wsg-idm-ecid-wtls7","wap-wsg-idm-ecid-wtls7",
+	NID_wap_wsg_idm_ecid_wtls7,5,&(lvalues[4960]),0},
+{"wap-wsg-idm-ecid-wtls8","wap-wsg-idm-ecid-wtls8",
+	NID_wap_wsg_idm_ecid_wtls8,5,&(lvalues[4965]),0},
+{"wap-wsg-idm-ecid-wtls9","wap-wsg-idm-ecid-wtls9",
+	NID_wap_wsg_idm_ecid_wtls9,5,&(lvalues[4970]),0},
+{"wap-wsg-idm-ecid-wtls10","wap-wsg-idm-ecid-wtls10",
+	NID_wap_wsg_idm_ecid_wtls10,5,&(lvalues[4975]),0},
+{"wap-wsg-idm-ecid-wtls11","wap-wsg-idm-ecid-wtls11",
+	NID_wap_wsg_idm_ecid_wtls11,5,&(lvalues[4980]),0},
+{"wap-wsg-idm-ecid-wtls12","wap-wsg-idm-ecid-wtls12",
+	NID_wap_wsg_idm_ecid_wtls12,5,&(lvalues[4985]),0},
+{"anyPolicy","X509v3 Any Policy",NID_any_policy,4,&(lvalues[4990]),0},
+{"policyMappings","X509v3 Policy Mappings",NID_policy_mappings,3,
+	&(lvalues[4994]),0},
+{"inhibitAnyPolicy","X509v3 Inhibit Any Policy",
+	NID_inhibit_any_policy,3,&(lvalues[4997]),0},
+{"Oakley-EC2N-3","ipsec3",NID_ipsec3,0,NULL,0},
+{"Oakley-EC2N-4","ipsec4",NID_ipsec4,0,NULL,0},
+{"CAMELLIA-128-CBC","camellia-128-cbc",NID_camellia_128_cbc,11,
+	&(lvalues[5000]),0},
+{"CAMELLIA-192-CBC","camellia-192-cbc",NID_camellia_192_cbc,11,
+	&(lvalues[5011]),0},
+{"CAMELLIA-256-CBC","camellia-256-cbc",NID_camellia_256_cbc,11,
+	&(lvalues[5022]),0},
+{"CAMELLIA-128-ECB","camellia-128-ecb",NID_camellia_128_ecb,8,
+	&(lvalues[5033]),0},
+{"CAMELLIA-192-ECB","camellia-192-ecb",NID_camellia_192_ecb,8,
+	&(lvalues[5041]),0},
+{"CAMELLIA-256-ECB","camellia-256-ecb",NID_camellia_256_ecb,8,
+	&(lvalues[5049]),0},
+{"CAMELLIA-128-CFB","camellia-128-cfb",NID_camellia_128_cfb128,8,
+	&(lvalues[5057]),0},
+{"CAMELLIA-192-CFB","camellia-192-cfb",NID_camellia_192_cfb128,8,
+	&(lvalues[5065]),0},
+{"CAMELLIA-256-CFB","camellia-256-cfb",NID_camellia_256_cfb128,8,
+	&(lvalues[5073]),0},
+{"CAMELLIA-128-CFB1","camellia-128-cfb1",NID_camellia_128_cfb1,0,NULL,0},
+{"CAMELLIA-192-CFB1","camellia-192-cfb1",NID_camellia_192_cfb1,0,NULL,0},
+{"CAMELLIA-256-CFB1","camellia-256-cfb1",NID_camellia_256_cfb1,0,NULL,0},
+{"CAMELLIA-128-CFB8","camellia-128-cfb8",NID_camellia_128_cfb8,0,NULL,0},
+{"CAMELLIA-192-CFB8","camellia-192-cfb8",NID_camellia_192_cfb8,0,NULL,0},
+{"CAMELLIA-256-CFB8","camellia-256-cfb8",NID_camellia_256_cfb8,0,NULL,0},
+{"CAMELLIA-128-OFB","camellia-128-ofb",NID_camellia_128_ofb128,8,
+	&(lvalues[5081]),0},
+{"CAMELLIA-192-OFB","camellia-192-ofb",NID_camellia_192_ofb128,8,
+	&(lvalues[5089]),0},
+{"CAMELLIA-256-OFB","camellia-256-ofb",NID_camellia_256_ofb128,8,
+	&(lvalues[5097]),0},
+{"subjectDirectoryAttributes","X509v3 Subject Directory Attributes",
+	NID_subject_directory_attributes,3,&(lvalues[5105]),0},
+{"issuingDistributionPoint","X509v3 Issuing Distrubution Point",
+	NID_issuing_distribution_point,3,&(lvalues[5108]),0},
+{"certificateIssuer","X509v3 Certificate Issuer",
+	NID_certificate_issuer,3,&(lvalues[5111]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"KISA","kisa",NID_kisa,6,&(lvalues[5114]),0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{NULL,NULL,NID_undef,0,NULL,0},
+{"SEED-ECB","seed-ecb",NID_seed_ecb,8,&(lvalues[5120]),0},
+{"SEED-CBC","seed-cbc",NID_seed_cbc,8,&(lvalues[5128]),0},
+{"SEED-OFB","seed-ofb",NID_seed_ofb128,8,&(lvalues[5136]),0},
+{"SEED-CFB","seed-cfb",NID_seed_cfb128,8,&(lvalues[5144]),0},
+{"HMAC-MD5","hmac-md5",NID_hmac_md5,8,&(lvalues[5152]),0},
+{"HMAC-SHA1","hmac-sha1",NID_hmac_sha1,8,&(lvalues[5160]),0},
+{"id-PasswordBasedMAC","password based MAC",NID_id_PasswordBasedMAC,9,
+	&(lvalues[5168]),0},
+{"id-DHBasedMac","Diffie-Hellman based MAC",NID_id_DHBasedMac,9,
+	&(lvalues[5177]),0},
+{"id-it-suppLangTags","id-it-suppLangTags",NID_id_it_suppLangTags,8,
+	&(lvalues[5186]),0},
+{"caRepository","CA Repository",NID_caRepository,8,&(lvalues[5194]),0},
+{"id-smime-ct-compressedData","id-smime-ct-compressedData",
+	NID_id_smime_ct_compressedData,11,&(lvalues[5202]),0},
+{"id-ct-asciiTextWithCRLF","id-ct-asciiTextWithCRLF",
+	NID_id_ct_asciiTextWithCRLF,11,&(lvalues[5213]),0},
+{"id-aes128-wrap","id-aes128-wrap",NID_id_aes128_wrap,9,
+	&(lvalues[5224]),0},
+{"id-aes192-wrap","id-aes192-wrap",NID_id_aes192_wrap,9,
+	&(lvalues[5233]),0},
+{"id-aes256-wrap","id-aes256-wrap",NID_id_aes256_wrap,9,
+	&(lvalues[5242]),0},
+{"ecdsa-with-Recommended","ecdsa-with-Recommended",
+	NID_ecdsa_with_Recommended,7,&(lvalues[5251]),0},
+{"ecdsa-with-Specified","ecdsa-with-Specified",
+	NID_ecdsa_with_Specified,7,&(lvalues[5258]),0},
+{"ecdsa-with-SHA224","ecdsa-with-SHA224",NID_ecdsa_with_SHA224,8,
+	&(lvalues[5265]),0},
+{"ecdsa-with-SHA256","ecdsa-with-SHA256",NID_ecdsa_with_SHA256,8,
+	&(lvalues[5273]),0},
+{"ecdsa-with-SHA384","ecdsa-with-SHA384",NID_ecdsa_with_SHA384,8,
+	&(lvalues[5281]),0},
+{"ecdsa-with-SHA512","ecdsa-with-SHA512",NID_ecdsa_with_SHA512,8,
+	&(lvalues[5289]),0},
+{"hmacWithMD5","hmacWithMD5",NID_hmacWithMD5,8,&(lvalues[5297]),0},
+{"hmacWithSHA224","hmacWithSHA224",NID_hmacWithSHA224,8,
+	&(lvalues[5305]),0},
+{"hmacWithSHA256","hmacWithSHA256",NID_hmacWithSHA256,8,
+	&(lvalues[5313]),0},
+{"hmacWithSHA384","hmacWithSHA384",NID_hmacWithSHA384,8,
+	&(lvalues[5321]),0},
+{"hmacWithSHA512","hmacWithSHA512",NID_hmacWithSHA512,8,
+	&(lvalues[5329]),0},
+{"dsa_with_SHA224","dsa_with_SHA224",NID_dsa_with_SHA224,9,
+	&(lvalues[5337]),0},
+{"dsa_with_SHA256","dsa_with_SHA256",NID_dsa_with_SHA256,9,
+	&(lvalues[5346]),0},
+{"whirlpool","whirlpool",NID_whirlpool,6,&(lvalues[5355]),0},
+{"cryptopro","cryptopro",NID_cryptopro,5,&(lvalues[5361]),0},
+{"cryptocom","cryptocom",NID_cryptocom,5,&(lvalues[5366]),0},
+{"id-GostR3411-94-with-GostR3410-2001",
+	"GOST R 34.11-94 with GOST R 34.10-2001",
+	NID_id_GostR3411_94_with_GostR3410_2001,6,&(lvalues[5371]),0},
+{"id-GostR3411-94-with-GostR3410-94",
+	"GOST R 34.11-94 with GOST R 34.10-94",
+	NID_id_GostR3411_94_with_GostR3410_94,6,&(lvalues[5377]),0},
+{"md_gost94","GOST R 34.11-94",NID_id_GostR3411_94,6,&(lvalues[5383]),0},
+{"id-HMACGostR3411-94","HMAC GOST 34.11-94",NID_id_HMACGostR3411_94,6,
+	&(lvalues[5389]),0},
+{"gost2001","GOST R 34.10-2001",NID_id_GostR3410_2001,6,
+	&(lvalues[5395]),0},
+{"gost94","GOST R 34.10-94",NID_id_GostR3410_94,6,&(lvalues[5401]),0},
+{"gost89","GOST 28147-89",NID_id_Gost28147_89,6,&(lvalues[5407]),0},
+{"gost89-cnt","gost89-cnt",NID_gost89_cnt,0,NULL,0},
+{"gost-mac","GOST 28147-89 MAC",NID_id_Gost28147_89_MAC,6,
+	&(lvalues[5413]),0},
+{"prf-gostr3411-94","GOST R 34.11-94 PRF",NID_id_GostR3411_94_prf,6,
+	&(lvalues[5419]),0},
+{"id-GostR3410-2001DH","GOST R 34.10-2001 DH",NID_id_GostR3410_2001DH,
+	6,&(lvalues[5425]),0},
+{"id-GostR3410-94DH","GOST R 34.10-94 DH",NID_id_GostR3410_94DH,6,
+	&(lvalues[5431]),0},
+{"id-Gost28147-89-CryptoPro-KeyMeshing",
+	"id-Gost28147-89-CryptoPro-KeyMeshing",
+	NID_id_Gost28147_89_CryptoPro_KeyMeshing,7,&(lvalues[5437]),0},
+{"id-Gost28147-89-None-KeyMeshing","id-Gost28147-89-None-KeyMeshing",
+	NID_id_Gost28147_89_None_KeyMeshing,7,&(lvalues[5444]),0},
+{"id-GostR3411-94-TestParamSet","id-GostR3411-94-TestParamSet",
+	NID_id_GostR3411_94_TestParamSet,7,&(lvalues[5451]),0},
+{"id-GostR3411-94-CryptoProParamSet",
+	"id-GostR3411-94-CryptoProParamSet",
+	NID_id_GostR3411_94_CryptoProParamSet,7,&(lvalues[5458]),0},
+{"id-Gost28147-89-TestParamSet","id-Gost28147-89-TestParamSet",
+	NID_id_Gost28147_89_TestParamSet,7,&(lvalues[5465]),0},
+{"id-Gost28147-89-CryptoPro-A-ParamSet",
+	"id-Gost28147-89-CryptoPro-A-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_A_ParamSet,7,&(lvalues[5472]),0},
+{"id-Gost28147-89-CryptoPro-B-ParamSet",
+	"id-Gost28147-89-CryptoPro-B-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_B_ParamSet,7,&(lvalues[5479]),0},
+{"id-Gost28147-89-CryptoPro-C-ParamSet",
+	"id-Gost28147-89-CryptoPro-C-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_C_ParamSet,7,&(lvalues[5486]),0},
+{"id-Gost28147-89-CryptoPro-D-ParamSet",
+	"id-Gost28147-89-CryptoPro-D-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_D_ParamSet,7,&(lvalues[5493]),0},
+{"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet",
+	"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet,7,&(lvalues[5500]),
+	0},
+{"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet",
+	"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet,7,&(lvalues[5507]),
+	0},
+{"id-Gost28147-89-CryptoPro-RIC-1-ParamSet",
+	"id-Gost28147-89-CryptoPro-RIC-1-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet,7,&(lvalues[5514]),0},
+{"id-GostR3410-94-TestParamSet","id-GostR3410-94-TestParamSet",
+	NID_id_GostR3410_94_TestParamSet,7,&(lvalues[5521]),0},
+{"id-GostR3410-94-CryptoPro-A-ParamSet",
+	"id-GostR3410-94-CryptoPro-A-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_A_ParamSet,7,&(lvalues[5528]),0},
+{"id-GostR3410-94-CryptoPro-B-ParamSet",
+	"id-GostR3410-94-CryptoPro-B-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_B_ParamSet,7,&(lvalues[5535]),0},
+{"id-GostR3410-94-CryptoPro-C-ParamSet",
+	"id-GostR3410-94-CryptoPro-C-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_C_ParamSet,7,&(lvalues[5542]),0},
+{"id-GostR3410-94-CryptoPro-D-ParamSet",
+	"id-GostR3410-94-CryptoPro-D-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_D_ParamSet,7,&(lvalues[5549]),0},
+{"id-GostR3410-94-CryptoPro-XchA-ParamSet",
+	"id-GostR3410-94-CryptoPro-XchA-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_XchA_ParamSet,7,&(lvalues[5556]),0},
+{"id-GostR3410-94-CryptoPro-XchB-ParamSet",
+	"id-GostR3410-94-CryptoPro-XchB-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_XchB_ParamSet,7,&(lvalues[5563]),0},
+{"id-GostR3410-94-CryptoPro-XchC-ParamSet",
+	"id-GostR3410-94-CryptoPro-XchC-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_XchC_ParamSet,7,&(lvalues[5570]),0},
+{"id-GostR3410-2001-TestParamSet","id-GostR3410-2001-TestParamSet",
+	NID_id_GostR3410_2001_TestParamSet,7,&(lvalues[5577]),0},
+{"id-GostR3410-2001-CryptoPro-A-ParamSet",
+	"id-GostR3410-2001-CryptoPro-A-ParamSet",
+	NID_id_GostR3410_2001_CryptoPro_A_ParamSet,7,&(lvalues[5584]),0},
+{"id-GostR3410-2001-CryptoPro-B-ParamSet",
+	"id-GostR3410-2001-CryptoPro-B-ParamSet",
+	NID_id_GostR3410_2001_CryptoPro_B_ParamSet,7,&(lvalues[5591]),0},
+{"id-GostR3410-2001-CryptoPro-C-ParamSet",
+	"id-GostR3410-2001-CryptoPro-C-ParamSet",
+	NID_id_GostR3410_2001_CryptoPro_C_ParamSet,7,&(lvalues[5598]),0},
+{"id-GostR3410-2001-CryptoPro-XchA-ParamSet",
+	"id-GostR3410-2001-CryptoPro-XchA-ParamSet",
+	NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet,7,&(lvalues[5605]),0},
+	
+{"id-GostR3410-2001-CryptoPro-XchB-ParamSet",
+	"id-GostR3410-2001-CryptoPro-XchB-ParamSet",
+	NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet,7,&(lvalues[5612]),0},
+	
+{"id-GostR3410-94-a","id-GostR3410-94-a",NID_id_GostR3410_94_a,7,
+	&(lvalues[5619]),0},
+{"id-GostR3410-94-aBis","id-GostR3410-94-aBis",
+	NID_id_GostR3410_94_aBis,7,&(lvalues[5626]),0},
+{"id-GostR3410-94-b","id-GostR3410-94-b",NID_id_GostR3410_94_b,7,
+	&(lvalues[5633]),0},
+{"id-GostR3410-94-bBis","id-GostR3410-94-bBis",
+	NID_id_GostR3410_94_bBis,7,&(lvalues[5640]),0},
+{"id-Gost28147-89-cc","GOST 28147-89 Cryptocom ParamSet",
+	NID_id_Gost28147_89_cc,8,&(lvalues[5647]),0},
+{"gost94cc","GOST 34.10-94 Cryptocom",NID_id_GostR3410_94_cc,8,
+	&(lvalues[5655]),0},
+{"gost2001cc","GOST 34.10-2001 Cryptocom",NID_id_GostR3410_2001_cc,8,
+	&(lvalues[5663]),0},
+{"id-GostR3411-94-with-GostR3410-94-cc",
+	"GOST R 34.11-94 with GOST R 34.10-94 Cryptocom",
+	NID_id_GostR3411_94_with_GostR3410_94_cc,8,&(lvalues[5671]),0},
+{"id-GostR3411-94-with-GostR3410-2001-cc",
+	"GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom",
+	NID_id_GostR3411_94_with_GostR3410_2001_cc,8,&(lvalues[5679]),0},
+{"id-GostR3410-2001-ParamSet-cc",
+	"GOST R 3410-2001 Parameter Set Cryptocom",
+	NID_id_GostR3410_2001_ParamSet_cc,8,&(lvalues[5687]),0},
+{"HMAC","hmac",NID_hmac,0,NULL,0},
+{"LocalKeySet","Microsoft Local Key set",NID_LocalKeySet,9,
+	&(lvalues[5695]),0},
+{"freshestCRL","X509v3 Freshest CRL",NID_freshest_crl,3,
+	&(lvalues[5704]),0},
+{"id-on-permanentIdentifier","Permanent Identifier",
+	NID_id_on_permanentIdentifier,8,&(lvalues[5707]),0},
+{"searchGuide","searchGuide",NID_searchGuide,3,&(lvalues[5715]),0},
+{"businessCategory","businessCategory",NID_businessCategory,3,
+	&(lvalues[5718]),0},
+{"postalAddress","postalAddress",NID_postalAddress,3,&(lvalues[5721]),0},
+{"postOfficeBox","postOfficeBox",NID_postOfficeBox,3,&(lvalues[5724]),0},
+{"physicalDeliveryOfficeName","physicalDeliveryOfficeName",
+	NID_physicalDeliveryOfficeName,3,&(lvalues[5727]),0},
+{"telephoneNumber","telephoneNumber",NID_telephoneNumber,3,
+	&(lvalues[5730]),0},
+{"telexNumber","telexNumber",NID_telexNumber,3,&(lvalues[5733]),0},
+{"teletexTerminalIdentifier","teletexTerminalIdentifier",
+	NID_teletexTerminalIdentifier,3,&(lvalues[5736]),0},
+{"facsimileTelephoneNumber","facsimileTelephoneNumber",
+	NID_facsimileTelephoneNumber,3,&(lvalues[5739]),0},
+{"x121Address","x121Address",NID_x121Address,3,&(lvalues[5742]),0},
+{"internationaliSDNNumber","internationaliSDNNumber",
+	NID_internationaliSDNNumber,3,&(lvalues[5745]),0},
+{"registeredAddress","registeredAddress",NID_registeredAddress,3,
+	&(lvalues[5748]),0},
+{"destinationIndicator","destinationIndicator",
+	NID_destinationIndicator,3,&(lvalues[5751]),0},
+{"preferredDeliveryMethod","preferredDeliveryMethod",
+	NID_preferredDeliveryMethod,3,&(lvalues[5754]),0},
+{"presentationAddress","presentationAddress",NID_presentationAddress,
+	3,&(lvalues[5757]),0},
+{"supportedApplicationContext","supportedApplicationContext",
+	NID_supportedApplicationContext,3,&(lvalues[5760]),0},
+{"member","member",NID_member,3,&(lvalues[5763]),0},
+{"owner","owner",NID_owner,3,&(lvalues[5766]),0},
+{"roleOccupant","roleOccupant",NID_roleOccupant,3,&(lvalues[5769]),0},
+{"seeAlso","seeAlso",NID_seeAlso,3,&(lvalues[5772]),0},
+{"userPassword","userPassword",NID_userPassword,3,&(lvalues[5775]),0},
+{"userCertificate","userCertificate",NID_userCertificate,3,
+	&(lvalues[5778]),0},
+{"cACertificate","cACertificate",NID_cACertificate,3,&(lvalues[5781]),0},
+{"authorityRevocationList","authorityRevocationList",
+	NID_authorityRevocationList,3,&(lvalues[5784]),0},
+{"certificateRevocationList","certificateRevocationList",
+	NID_certificateRevocationList,3,&(lvalues[5787]),0},
+{"crossCertificatePair","crossCertificatePair",
+	NID_crossCertificatePair,3,&(lvalues[5790]),0},
+{"enhancedSearchGuide","enhancedSearchGuide",NID_enhancedSearchGuide,
+	3,&(lvalues[5793]),0},
+{"protocolInformation","protocolInformation",NID_protocolInformation,
+	3,&(lvalues[5796]),0},
+{"distinguishedName","distinguishedName",NID_distinguishedName,3,
+	&(lvalues[5799]),0},
+{"uniqueMember","uniqueMember",NID_uniqueMember,3,&(lvalues[5802]),0},
+{"houseIdentifier","houseIdentifier",NID_houseIdentifier,3,
+	&(lvalues[5805]),0},
+{"supportedAlgorithms","supportedAlgorithms",NID_supportedAlgorithms,
+	3,&(lvalues[5808]),0},
+{"deltaRevocationList","deltaRevocationList",NID_deltaRevocationList,
+	3,&(lvalues[5811]),0},
+{"dmdName","dmdName",NID_dmdName,3,&(lvalues[5814]),0},
+{"id-alg-PWRI-KEK","id-alg-PWRI-KEK",NID_id_alg_PWRI_KEK,11,
+	&(lvalues[5817]),0},
+{"CMAC","cmac",NID_cmac,0,NULL,0},
+{"id-aes128-GCM","aes-128-gcm",NID_aes_128_gcm,9,&(lvalues[5828]),0},
+{"id-aes128-CCM","aes-128-ccm",NID_aes_128_ccm,9,&(lvalues[5837]),0},
+{"id-aes128-wrap-pad","id-aes128-wrap-pad",NID_id_aes128_wrap_pad,9,
+	&(lvalues[5846]),0},
+{"id-aes192-GCM","aes-192-gcm",NID_aes_192_gcm,9,&(lvalues[5855]),0},
+{"id-aes192-CCM","aes-192-ccm",NID_aes_192_ccm,9,&(lvalues[5864]),0},
+{"id-aes192-wrap-pad","id-aes192-wrap-pad",NID_id_aes192_wrap_pad,9,
+	&(lvalues[5873]),0},
+{"id-aes256-GCM","aes-256-gcm",NID_aes_256_gcm,9,&(lvalues[5882]),0},
+{"id-aes256-CCM","aes-256-ccm",NID_aes_256_ccm,9,&(lvalues[5891]),0},
+{"id-aes256-wrap-pad","id-aes256-wrap-pad",NID_id_aes256_wrap_pad,9,
+	&(lvalues[5900]),0},
+{"AES-128-CTR","aes-128-ctr",NID_aes_128_ctr,0,NULL,0},
+{"AES-192-CTR","aes-192-ctr",NID_aes_192_ctr,0,NULL,0},
+{"AES-256-CTR","aes-256-ctr",NID_aes_256_ctr,0,NULL,0},
+{"id-camellia128-wrap","id-camellia128-wrap",NID_id_camellia128_wrap,
+	11,&(lvalues[5909]),0},
+{"id-camellia192-wrap","id-camellia192-wrap",NID_id_camellia192_wrap,
+	11,&(lvalues[5920]),0},
+{"id-camellia256-wrap","id-camellia256-wrap",NID_id_camellia256_wrap,
+	11,&(lvalues[5931]),0},
+{"anyExtendedKeyUsage","Any Extended Key Usage",
+	NID_anyExtendedKeyUsage,4,&(lvalues[5942]),0},
+{"MGF1","mgf1",NID_mgf1,9,&(lvalues[5946]),0},
+{"RSASSA-PSS","rsassaPss",NID_rsassaPss,9,&(lvalues[5955]),0},
+{"AES-128-XTS","aes-128-xts",NID_aes_128_xts,0,NULL,0},
+{"AES-256-XTS","aes-256-xts",NID_aes_256_xts,0,NULL,0},
+{"RC4-HMAC-MD5","rc4-hmac-md5",NID_rc4_hmac_md5,0,NULL,0},
+{"AES-128-CBC-HMAC-SHA1","aes-128-cbc-hmac-sha1",
+	NID_aes_128_cbc_hmac_sha1,0,NULL,0},
+{"AES-192-CBC-HMAC-SHA1","aes-192-cbc-hmac-sha1",
+	NID_aes_192_cbc_hmac_sha1,0,NULL,0},
+{"AES-256-CBC-HMAC-SHA1","aes-256-cbc-hmac-sha1",
+	NID_aes_256_cbc_hmac_sha1,0,NULL,0},
+{"RSAES-OAEP","rsaesOaep",NID_rsaesOaep,9,&(lvalues[5964]),0},
+{"teletrust","teletrust",NID_teletrust,2,&(lvalues[5973]),0},
+{"brainpool","brainpool",NID_brainpool,7,&(lvalues[5975]),0},
+{"brainpoolP160r1","brainpoolP160r1",NID_brainpoolP160r1,9,
+	&(lvalues[5982]),0},
+{"brainpoolP160t1","brainpoolP160t1",NID_brainpoolP160t1,9,
+	&(lvalues[5991]),0},
+{"brainpoolP192r1","brainpoolP192r1",NID_brainpoolP192r1,9,
+	&(lvalues[6000]),0},
+{"brainpoolP192t1","brainpoolP192t1",NID_brainpoolP192t1,9,
+	&(lvalues[6009]),0},
+{"brainpoolP224r1","brainpoolP224r1",NID_brainpoolP224r1,9,
+	&(lvalues[6018]),0},
+{"brainpoolP224t1","brainpoolP224t1",NID_brainpoolP224t1,9,
+	&(lvalues[6027]),0},
+{"brainpoolP256r1","brainpoolP256r1",NID_brainpoolP256r1,9,
+	&(lvalues[6036]),0},
+{"brainpoolP256t1","brainpoolP256t1",NID_brainpoolP256t1,9,
+	&(lvalues[6045]),0},
+{"brainpoolP320r1","brainpoolP320r1",NID_brainpoolP320r1,9,
+	&(lvalues[6054]),0},
+{"brainpoolP320t1","brainpoolP320t1",NID_brainpoolP320t1,9,
+	&(lvalues[6063]),0},
+{"brainpoolP384r1","brainpoolP384r1",NID_brainpoolP384r1,9,
+	&(lvalues[6072]),0},
+{"brainpoolP384t1","brainpoolP384t1",NID_brainpoolP384t1,9,
+	&(lvalues[6081]),0},
+{"brainpoolP512r1","brainpoolP512r1",NID_brainpoolP512r1,9,
+	&(lvalues[6090]),0},
+{"brainpoolP512t1","brainpoolP512t1",NID_brainpoolP512t1,9,
+	&(lvalues[6099]),0},
+{"FRP256v1","FRP256v1",NID_FRP256v1,10,&(lvalues[6108]),0},
+{"ChaCha","chacha",NID_chacha20,0,NULL,0},
+{"gost89-ecb","gost89-ecb",NID_gost89_ecb,0,NULL,0},
+{"gost89-cbc","gost89-cbc",NID_gost89_cbc,0,NULL,0},
+{"tc26","tc26",NID_tc26,5,&(lvalues[6118]),0},
+{"streebog256","GOST R 34.11-2012 (256 bit)",
+	NID_id_tc26_gost3411_2012_256,8,&(lvalues[6123]),0},
+{"streebog512","GOST R 34-11-2012 (512 bit)",
+	NID_id_tc26_gost3411_2012_512,8,&(lvalues[6131]),0},
+{"id-tc26-gost-3410-2012-512-paramSetA",
+	"id-tc26-gost-3410-2012-512-paramSetA",
+	NID_id_tc26_gost_3410_2012_512_paramSetA,9,&(lvalues[6139]),0},
+{"id-tc26-gost-3410-2012-512-paramSetB",
+	"id-tc26-gost-3410-2012-512-paramSetB",
+	NID_id_tc26_gost_3410_2012_512_paramSetB,9,&(lvalues[6148]),0},
+{"id-tc26-gost-28147-param-Z","id-tc26-gost-28147-param-Z",
+	NID_id_tc26_gost_28147_param_Z,9,&(lvalues[6157]),0},
+{"id-tc26-gost3410-2012-256","GOST R 34.10-2012 (256 bit)",
+	NID_id_tc26_gost3410_2012_256,8,&(lvalues[6166]),0},
+{"id-tc26-gost3410-2012-512","GOST R 34.10-2012 (512 bit)",
+	NID_id_tc26_gost3410_2012_512,8,&(lvalues[6174]),0},
+{"id-tc26-signwithdigest-gost3410-2012-256",
+	"GOST R 34.11-2012 with GOST R 34.10-2012 (256 bit)",
+	NID_id_tc26_signwithdigest_gost3410_2012_256,8,&(lvalues[6182]),0},
+{"id-tc26-signwithdigest-gost3410-2012-512",
+	"GOST R 34.11-2012 with GOST R 34.10-2012 (512 bit)",
+	NID_id_tc26_signwithdigest_gost3410_2012_512,8,&(lvalues[6190]),0},
+};
+
+static const unsigned int sn_objs[NUM_SN]={
+364,	/* "AD_DVCS" */
+419,	/* "AES-128-CBC" */
+916,	/* "AES-128-CBC-HMAC-SHA1" */
+421,	/* "AES-128-CFB" */
+650,	/* "AES-128-CFB1" */
+653,	/* "AES-128-CFB8" */
+904,	/* "AES-128-CTR" */
+418,	/* "AES-128-ECB" */
+420,	/* "AES-128-OFB" */
+913,	/* "AES-128-XTS" */
+423,	/* "AES-192-CBC" */
+917,	/* "AES-192-CBC-HMAC-SHA1" */
+425,	/* "AES-192-CFB" */
+651,	/* "AES-192-CFB1" */
+654,	/* "AES-192-CFB8" */
+905,	/* "AES-192-CTR" */
+422,	/* "AES-192-ECB" */
+424,	/* "AES-192-OFB" */
+427,	/* "AES-256-CBC" */
+918,	/* "AES-256-CBC-HMAC-SHA1" */
+429,	/* "AES-256-CFB" */
+652,	/* "AES-256-CFB1" */
+655,	/* "AES-256-CFB8" */
+906,	/* "AES-256-CTR" */
+426,	/* "AES-256-ECB" */
+428,	/* "AES-256-OFB" */
+914,	/* "AES-256-XTS" */
+91,	/* "BF-CBC" */
+93,	/* "BF-CFB" */
+92,	/* "BF-ECB" */
+94,	/* "BF-OFB" */
+14,	/* "C" */
+751,	/* "CAMELLIA-128-CBC" */
+757,	/* "CAMELLIA-128-CFB" */
+760,	/* "CAMELLIA-128-CFB1" */
+763,	/* "CAMELLIA-128-CFB8" */
+754,	/* "CAMELLIA-128-ECB" */
+766,	/* "CAMELLIA-128-OFB" */
+752,	/* "CAMELLIA-192-CBC" */
+758,	/* "CAMELLIA-192-CFB" */
+761,	/* "CAMELLIA-192-CFB1" */
+764,	/* "CAMELLIA-192-CFB8" */
+755,	/* "CAMELLIA-192-ECB" */
+767,	/* "CAMELLIA-192-OFB" */
+753,	/* "CAMELLIA-256-CBC" */
+759,	/* "CAMELLIA-256-CFB" */
+762,	/* "CAMELLIA-256-CFB1" */
+765,	/* "CAMELLIA-256-CFB8" */
+756,	/* "CAMELLIA-256-ECB" */
+768,	/* "CAMELLIA-256-OFB" */
+108,	/* "CAST5-CBC" */
+110,	/* "CAST5-CFB" */
+109,	/* "CAST5-ECB" */
+111,	/* "CAST5-OFB" */
+894,	/* "CMAC" */
+13,	/* "CN" */
+141,	/* "CRLReason" */
+417,	/* "CSPName" */
+937,	/* "ChaCha" */
+367,	/* "CrlID" */
+391,	/* "DC" */
+31,	/* "DES-CBC" */
+643,	/* "DES-CDMF" */
+30,	/* "DES-CFB" */
+656,	/* "DES-CFB1" */
+657,	/* "DES-CFB8" */
+29,	/* "DES-ECB" */
+32,	/* "DES-EDE" */
+43,	/* "DES-EDE-CBC" */
+60,	/* "DES-EDE-CFB" */
+62,	/* "DES-EDE-OFB" */
+33,	/* "DES-EDE3" */
+44,	/* "DES-EDE3-CBC" */
+61,	/* "DES-EDE3-CFB" */
+658,	/* "DES-EDE3-CFB1" */
+659,	/* "DES-EDE3-CFB8" */
+63,	/* "DES-EDE3-OFB" */
+45,	/* "DES-OFB" */
+80,	/* "DESX-CBC" */
+380,	/* "DOD" */
+116,	/* "DSA" */
+66,	/* "DSA-SHA" */
+113,	/* "DSA-SHA1" */
+70,	/* "DSA-SHA1-old" */
+67,	/* "DSA-old" */
+297,	/* "DVCS" */
+936,	/* "FRP256v1" */
+99,	/* "GN" */
+855,	/* "HMAC" */
+780,	/* "HMAC-MD5" */
+781,	/* "HMAC-SHA1" */
+381,	/* "IANA" */
+34,	/* "IDEA-CBC" */
+35,	/* "IDEA-CFB" */
+36,	/* "IDEA-ECB" */
+46,	/* "IDEA-OFB" */
+181,	/* "ISO" */
+183,	/* "ISO-US" */
+645,	/* "ITU-T" */
+646,	/* "JOINT-ISO-ITU-T" */
+773,	/* "KISA" */
+15,	/* "L" */
+856,	/* "LocalKeySet" */
+ 3,	/* "MD2" */
+257,	/* "MD4" */
+ 4,	/* "MD5" */
+114,	/* "MD5-SHA1" */
+95,	/* "MDC2" */
+911,	/* "MGF1" */
+388,	/* "Mail" */
+393,	/* "NULL" */
+404,	/* "NULL" */
+57,	/* "Netscape" */
+366,	/* "Nonce" */
+17,	/* "O" */
+178,	/* "OCSP" */
+180,	/* "OCSPSigning" */
+379,	/* "ORG" */
+18,	/* "OU" */
+749,	/* "Oakley-EC2N-3" */
+750,	/* "Oakley-EC2N-4" */
+ 9,	/* "PBE-MD2-DES" */
+168,	/* "PBE-MD2-RC2-64" */
+10,	/* "PBE-MD5-DES" */
+169,	/* "PBE-MD5-RC2-64" */
+147,	/* "PBE-SHA1-2DES" */
+146,	/* "PBE-SHA1-3DES" */
+170,	/* "PBE-SHA1-DES" */
+148,	/* "PBE-SHA1-RC2-128" */
+149,	/* "PBE-SHA1-RC2-40" */
+68,	/* "PBE-SHA1-RC2-64" */
+144,	/* "PBE-SHA1-RC4-128" */
+145,	/* "PBE-SHA1-RC4-40" */
+161,	/* "PBES2" */
+69,	/* "PBKDF2" */
+162,	/* "PBMAC1" */
+127,	/* "PKIX" */
+98,	/* "RC2-40-CBC" */
+166,	/* "RC2-64-CBC" */
+37,	/* "RC2-CBC" */
+39,	/* "RC2-CFB" */
+38,	/* "RC2-ECB" */
+40,	/* "RC2-OFB" */
+ 5,	/* "RC4" */
+97,	/* "RC4-40" */
+915,	/* "RC4-HMAC-MD5" */
+120,	/* "RC5-CBC" */
+122,	/* "RC5-CFB" */
+121,	/* "RC5-ECB" */
+123,	/* "RC5-OFB" */
+117,	/* "RIPEMD160" */
+124,	/* "RLE" */
+19,	/* "RSA" */
+ 7,	/* "RSA-MD2" */
+396,	/* "RSA-MD4" */
+ 8,	/* "RSA-MD5" */
+96,	/* "RSA-MDC2" */
+104,	/* "RSA-NP-MD5" */
+119,	/* "RSA-RIPEMD160" */
+42,	/* "RSA-SHA" */
+65,	/* "RSA-SHA1" */
+115,	/* "RSA-SHA1-2" */
+671,	/* "RSA-SHA224" */
+668,	/* "RSA-SHA256" */
+669,	/* "RSA-SHA384" */
+670,	/* "RSA-SHA512" */
+919,	/* "RSAES-OAEP" */
+912,	/* "RSASSA-PSS" */
+777,	/* "SEED-CBC" */
+779,	/* "SEED-CFB" */
+776,	/* "SEED-ECB" */
+778,	/* "SEED-OFB" */
+41,	/* "SHA" */
+64,	/* "SHA1" */
+675,	/* "SHA224" */
+672,	/* "SHA256" */
+673,	/* "SHA384" */
+674,	/* "SHA512" */
+188,	/* "SMIME" */
+167,	/* "SMIME-CAPS" */
+100,	/* "SN" */
+16,	/* "ST" */
+143,	/* "SXNetID" */
+458,	/* "UID" */
+ 0,	/* "UNDEF" */
+11,	/* "X500" */
+378,	/* "X500algorithms" */
+12,	/* "X509" */
+184,	/* "X9-57" */
+185,	/* "X9cm" */
+125,	/* "ZLIB" */
+478,	/* "aRecord" */
+289,	/* "aaControls" */
+287,	/* "ac-auditEntity" */
+397,	/* "ac-proxying" */
+288,	/* "ac-targeting" */
+368,	/* "acceptableResponses" */
+446,	/* "account" */
+363,	/* "ad_timestamping" */
+376,	/* "algorithm" */
+405,	/* "ansi-X9-62" */
+910,	/* "anyExtendedKeyUsage" */
+746,	/* "anyPolicy" */
+370,	/* "archiveCutoff" */
+484,	/* "associatedDomain" */
+485,	/* "associatedName" */
+501,	/* "audio" */
+177,	/* "authorityInfoAccess" */
+90,	/* "authorityKeyIdentifier" */
+882,	/* "authorityRevocationList" */
+87,	/* "basicConstraints" */
+365,	/* "basicOCSPResponse" */
+285,	/* "biometricInfo" */
+921,	/* "brainpool" */
+922,	/* "brainpoolP160r1" */
+923,	/* "brainpoolP160t1" */
+924,	/* "brainpoolP192r1" */
+925,	/* "brainpoolP192t1" */
+926,	/* "brainpoolP224r1" */
+927,	/* "brainpoolP224t1" */
+928,	/* "brainpoolP256r1" */
+929,	/* "brainpoolP256t1" */
+930,	/* "brainpoolP320r1" */
+931,	/* "brainpoolP320t1" */
+932,	/* "brainpoolP384r1" */
+933,	/* "brainpoolP384t1" */
+934,	/* "brainpoolP512r1" */
+935,	/* "brainpoolP512t1" */
+494,	/* "buildingName" */
+860,	/* "businessCategory" */
+691,	/* "c2onb191v4" */
+692,	/* "c2onb191v5" */
+697,	/* "c2onb239v4" */
+698,	/* "c2onb239v5" */
+684,	/* "c2pnb163v1" */
+685,	/* "c2pnb163v2" */
+686,	/* "c2pnb163v3" */
+687,	/* "c2pnb176v1" */
+693,	/* "c2pnb208w1" */
+699,	/* "c2pnb272w1" */
+700,	/* "c2pnb304w1" */
+702,	/* "c2pnb368w1" */
+688,	/* "c2tnb191v1" */
+689,	/* "c2tnb191v2" */
+690,	/* "c2tnb191v3" */
+694,	/* "c2tnb239v1" */
+695,	/* "c2tnb239v2" */
+696,	/* "c2tnb239v3" */
+701,	/* "c2tnb359v1" */
+703,	/* "c2tnb431r1" */
+881,	/* "cACertificate" */
+483,	/* "cNAMERecord" */
+179,	/* "caIssuers" */
+785,	/* "caRepository" */
+443,	/* "caseIgnoreIA5StringSyntax" */
+152,	/* "certBag" */
+677,	/* "certicom-arc" */
+771,	/* "certificateIssuer" */
+89,	/* "certificatePolicies" */
+883,	/* "certificateRevocationList" */
+54,	/* "challengePassword" */
+407,	/* "characteristic-two-field" */
+395,	/* "clearance" */
+130,	/* "clientAuth" */
+131,	/* "codeSigning" */
+50,	/* "contentType" */
+53,	/* "countersignature" */
+153,	/* "crlBag" */
+103,	/* "crlDistributionPoints" */
+88,	/* "crlNumber" */
+884,	/* "crossCertificatePair" */
+806,	/* "cryptocom" */
+805,	/* "cryptopro" */
+500,	/* "dITRedirect" */
+451,	/* "dNSDomain" */
+495,	/* "dSAQuality" */
+434,	/* "data" */
+390,	/* "dcobject" */
+140,	/* "deltaCRL" */
+891,	/* "deltaRevocationList" */
+107,	/* "description" */
+871,	/* "destinationIndicator" */
+28,	/* "dhKeyAgreement" */
+382,	/* "directory" */
+887,	/* "distinguishedName" */
+892,	/* "dmdName" */
+174,	/* "dnQualifier" */
+447,	/* "document" */
+471,	/* "documentAuthor" */
+468,	/* "documentIdentifier" */
+472,	/* "documentLocation" */
+502,	/* "documentPublisher" */
+449,	/* "documentSeries" */
+469,	/* "documentTitle" */
+470,	/* "documentVersion" */
+392,	/* "domain" */
+452,	/* "domainRelatedObject" */
+802,	/* "dsa_with_SHA224" */
+803,	/* "dsa_with_SHA256" */
+791,	/* "ecdsa-with-Recommended" */
+416,	/* "ecdsa-with-SHA1" */
+793,	/* "ecdsa-with-SHA224" */
+794,	/* "ecdsa-with-SHA256" */
+795,	/* "ecdsa-with-SHA384" */
+796,	/* "ecdsa-with-SHA512" */
+792,	/* "ecdsa-with-Specified" */
+48,	/* "emailAddress" */
+132,	/* "emailProtection" */
+885,	/* "enhancedSearchGuide" */
+389,	/* "enterprises" */
+384,	/* "experimental" */
+172,	/* "extReq" */
+56,	/* "extendedCertificateAttributes" */
+126,	/* "extendedKeyUsage" */
+372,	/* "extendedStatus" */
+867,	/* "facsimileTelephoneNumber" */
+462,	/* "favouriteDrink" */
+857,	/* "freshestCRL" */
+453,	/* "friendlyCountry" */
+490,	/* "friendlyCountryName" */
+156,	/* "friendlyName" */
+509,	/* "generationQualifier" */
+815,	/* "gost-mac" */
+811,	/* "gost2001" */
+851,	/* "gost2001cc" */
+813,	/* "gost89" */
+939,	/* "gost89-cbc" */
+814,	/* "gost89-cnt" */
+938,	/* "gost89-ecb" */
+812,	/* "gost94" */
+850,	/* "gost94cc" */
+797,	/* "hmacWithMD5" */
+163,	/* "hmacWithSHA1" */
+798,	/* "hmacWithSHA224" */
+799,	/* "hmacWithSHA256" */
+800,	/* "hmacWithSHA384" */
+801,	/* "hmacWithSHA512" */
+432,	/* "holdInstructionCallIssuer" */
+430,	/* "holdInstructionCode" */
+431,	/* "holdInstructionNone" */
+433,	/* "holdInstructionReject" */
+486,	/* "homePostalAddress" */
+473,	/* "homeTelephoneNumber" */
+466,	/* "host" */
+889,	/* "houseIdentifier" */
+442,	/* "iA5StringSyntax" */
+783,	/* "id-DHBasedMac" */
+824,	/* "id-Gost28147-89-CryptoPro-A-ParamSet" */
+825,	/* "id-Gost28147-89-CryptoPro-B-ParamSet" */
+826,	/* "id-Gost28147-89-CryptoPro-C-ParamSet" */
+827,	/* "id-Gost28147-89-CryptoPro-D-ParamSet" */
+819,	/* "id-Gost28147-89-CryptoPro-KeyMeshing" */
+829,	/* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */
+828,	/* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */
+830,	/* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */
+820,	/* "id-Gost28147-89-None-KeyMeshing" */
+823,	/* "id-Gost28147-89-TestParamSet" */
+849,	/* "id-Gost28147-89-cc" */
+840,	/* "id-GostR3410-2001-CryptoPro-A-ParamSet" */
+841,	/* "id-GostR3410-2001-CryptoPro-B-ParamSet" */
+842,	/* "id-GostR3410-2001-CryptoPro-C-ParamSet" */
+843,	/* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */
+844,	/* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */
+854,	/* "id-GostR3410-2001-ParamSet-cc" */
+839,	/* "id-GostR3410-2001-TestParamSet" */
+817,	/* "id-GostR3410-2001DH" */
+832,	/* "id-GostR3410-94-CryptoPro-A-ParamSet" */
+833,	/* "id-GostR3410-94-CryptoPro-B-ParamSet" */
+834,	/* "id-GostR3410-94-CryptoPro-C-ParamSet" */
+835,	/* "id-GostR3410-94-CryptoPro-D-ParamSet" */
+836,	/* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */
+837,	/* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */
+838,	/* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */
+831,	/* "id-GostR3410-94-TestParamSet" */
+845,	/* "id-GostR3410-94-a" */
+846,	/* "id-GostR3410-94-aBis" */
+847,	/* "id-GostR3410-94-b" */
+848,	/* "id-GostR3410-94-bBis" */
+818,	/* "id-GostR3410-94DH" */
+822,	/* "id-GostR3411-94-CryptoProParamSet" */
+821,	/* "id-GostR3411-94-TestParamSet" */
+807,	/* "id-GostR3411-94-with-GostR3410-2001" */
+853,	/* "id-GostR3411-94-with-GostR3410-2001-cc" */
+808,	/* "id-GostR3411-94-with-GostR3410-94" */
+852,	/* "id-GostR3411-94-with-GostR3410-94-cc" */
+810,	/* "id-HMACGostR3411-94" */
+782,	/* "id-PasswordBasedMAC" */
+266,	/* "id-aca" */
+355,	/* "id-aca-accessIdentity" */
+354,	/* "id-aca-authenticationInfo" */
+356,	/* "id-aca-chargingIdentity" */
+399,	/* "id-aca-encAttrs" */
+357,	/* "id-aca-group" */
+358,	/* "id-aca-role" */
+176,	/* "id-ad" */
+896,	/* "id-aes128-CCM" */
+895,	/* "id-aes128-GCM" */
+788,	/* "id-aes128-wrap" */
+897,	/* "id-aes128-wrap-pad" */
+899,	/* "id-aes192-CCM" */
+898,	/* "id-aes192-GCM" */
+789,	/* "id-aes192-wrap" */
+900,	/* "id-aes192-wrap-pad" */
+902,	/* "id-aes256-CCM" */
+901,	/* "id-aes256-GCM" */
+790,	/* "id-aes256-wrap" */
+903,	/* "id-aes256-wrap-pad" */
+262,	/* "id-alg" */
+893,	/* "id-alg-PWRI-KEK" */
+323,	/* "id-alg-des40" */
+326,	/* "id-alg-dh-pop" */
+325,	/* "id-alg-dh-sig-hmac-sha1" */
+324,	/* "id-alg-noSignature" */
+907,	/* "id-camellia128-wrap" */
+908,	/* "id-camellia192-wrap" */
+909,	/* "id-camellia256-wrap" */
+268,	/* "id-cct" */
+361,	/* "id-cct-PKIData" */
+362,	/* "id-cct-PKIResponse" */
+360,	/* "id-cct-crs" */
+81,	/* "id-ce" */
+680,	/* "id-characteristic-two-basis" */
+263,	/* "id-cmc" */
+334,	/* "id-cmc-addExtensions" */
+346,	/* "id-cmc-confirmCertAcceptance" */
+330,	/* "id-cmc-dataReturn" */
+336,	/* "id-cmc-decryptedPOP" */
+335,	/* "id-cmc-encryptedPOP" */
+339,	/* "id-cmc-getCRL" */
+338,	/* "id-cmc-getCert" */
+328,	/* "id-cmc-identification" */
+329,	/* "id-cmc-identityProof" */
+337,	/* "id-cmc-lraPOPWitness" */
+344,	/* "id-cmc-popLinkRandom" */
+345,	/* "id-cmc-popLinkWitness" */
+343,	/* "id-cmc-queryPending" */
+333,	/* "id-cmc-recipientNonce" */
+341,	/* "id-cmc-regInfo" */
+342,	/* "id-cmc-responseInfo" */
+340,	/* "id-cmc-revokeRequest" */
+332,	/* "id-cmc-senderNonce" */
+327,	/* "id-cmc-statusInfo" */
+331,	/* "id-cmc-transactionId" */
+787,	/* "id-ct-asciiTextWithCRLF" */
+408,	/* "id-ecPublicKey" */
+508,	/* "id-hex-multipart-message" */
+507,	/* "id-hex-partial-message" */
+260,	/* "id-it" */
+302,	/* "id-it-caKeyUpdateInfo" */
+298,	/* "id-it-caProtEncCert" */
+311,	/* "id-it-confirmWaitTime" */
+303,	/* "id-it-currentCRL" */
+300,	/* "id-it-encKeyPairTypes" */
+310,	/* "id-it-implicitConfirm" */
+308,	/* "id-it-keyPairParamRep" */
+307,	/* "id-it-keyPairParamReq" */
+312,	/* "id-it-origPKIMessage" */
+301,	/* "id-it-preferredSymmAlg" */
+309,	/* "id-it-revPassphrase" */
+299,	/* "id-it-signKeyPairTypes" */
+305,	/* "id-it-subscriptionRequest" */
+306,	/* "id-it-subscriptionResponse" */
+784,	/* "id-it-suppLangTags" */
+304,	/* "id-it-unsupportedOIDs" */
+128,	/* "id-kp" */
+280,	/* "id-mod-attribute-cert" */
+274,	/* "id-mod-cmc" */
+277,	/* "id-mod-cmp" */
+284,	/* "id-mod-cmp2000" */
+273,	/* "id-mod-crmf" */
+283,	/* "id-mod-dvcs" */
+275,	/* "id-mod-kea-profile-88" */
+276,	/* "id-mod-kea-profile-93" */
+282,	/* "id-mod-ocsp" */
+278,	/* "id-mod-qualified-cert-88" */
+279,	/* "id-mod-qualified-cert-93" */
+281,	/* "id-mod-timestamp-protocol" */
+264,	/* "id-on" */
+858,	/* "id-on-permanentIdentifier" */
+347,	/* "id-on-personalData" */
+265,	/* "id-pda" */
+352,	/* "id-pda-countryOfCitizenship" */
+353,	/* "id-pda-countryOfResidence" */
+348,	/* "id-pda-dateOfBirth" */
+351,	/* "id-pda-gender" */
+349,	/* "id-pda-placeOfBirth" */
+175,	/* "id-pe" */
+261,	/* "id-pkip" */
+258,	/* "id-pkix-mod" */
+269,	/* "id-pkix1-explicit-88" */
+271,	/* "id-pkix1-explicit-93" */
+270,	/* "id-pkix1-implicit-88" */
+272,	/* "id-pkix1-implicit-93" */
+662,	/* "id-ppl" */
+664,	/* "id-ppl-anyLanguage" */
+667,	/* "id-ppl-independent" */
+665,	/* "id-ppl-inheritAll" */
+267,	/* "id-qcs" */
+359,	/* "id-qcs-pkixQCSyntax-v1" */
+259,	/* "id-qt" */
+164,	/* "id-qt-cps" */
+165,	/* "id-qt-unotice" */
+313,	/* "id-regCtrl" */
+316,	/* "id-regCtrl-authenticator" */
+319,	/* "id-regCtrl-oldCertID" */
+318,	/* "id-regCtrl-pkiArchiveOptions" */
+317,	/* "id-regCtrl-pkiPublicationInfo" */
+320,	/* "id-regCtrl-protocolEncrKey" */
+315,	/* "id-regCtrl-regToken" */
+314,	/* "id-regInfo" */
+322,	/* "id-regInfo-certReq" */
+321,	/* "id-regInfo-utf8Pairs" */
+512,	/* "id-set" */
+191,	/* "id-smime-aa" */
+215,	/* "id-smime-aa-contentHint" */
+218,	/* "id-smime-aa-contentIdentifier" */
+221,	/* "id-smime-aa-contentReference" */
+240,	/* "id-smime-aa-dvcs-dvc" */
+217,	/* "id-smime-aa-encapContentType" */
+222,	/* "id-smime-aa-encrypKeyPref" */
+220,	/* "id-smime-aa-equivalentLabels" */
+232,	/* "id-smime-aa-ets-CertificateRefs" */
+233,	/* "id-smime-aa-ets-RevocationRefs" */
+238,	/* "id-smime-aa-ets-archiveTimeStamp" */
+237,	/* "id-smime-aa-ets-certCRLTimestamp" */
+234,	/* "id-smime-aa-ets-certValues" */
+227,	/* "id-smime-aa-ets-commitmentType" */
+231,	/* "id-smime-aa-ets-contentTimestamp" */
+236,	/* "id-smime-aa-ets-escTimeStamp" */
+230,	/* "id-smime-aa-ets-otherSigCert" */
+235,	/* "id-smime-aa-ets-revocationValues" */
+226,	/* "id-smime-aa-ets-sigPolicyId" */
+229,	/* "id-smime-aa-ets-signerAttr" */
+228,	/* "id-smime-aa-ets-signerLocation" */
+219,	/* "id-smime-aa-macValue" */
+214,	/* "id-smime-aa-mlExpandHistory" */
+216,	/* "id-smime-aa-msgSigDigest" */
+212,	/* "id-smime-aa-receiptRequest" */
+213,	/* "id-smime-aa-securityLabel" */
+239,	/* "id-smime-aa-signatureType" */
+223,	/* "id-smime-aa-signingCertificate" */
+224,	/* "id-smime-aa-smimeEncryptCerts" */
+225,	/* "id-smime-aa-timeStampToken" */
+192,	/* "id-smime-alg" */
+243,	/* "id-smime-alg-3DESwrap" */
+246,	/* "id-smime-alg-CMS3DESwrap" */
+247,	/* "id-smime-alg-CMSRC2wrap" */
+245,	/* "id-smime-alg-ESDH" */
+241,	/* "id-smime-alg-ESDHwith3DES" */
+242,	/* "id-smime-alg-ESDHwithRC2" */
+244,	/* "id-smime-alg-RC2wrap" */
+193,	/* "id-smime-cd" */
+248,	/* "id-smime-cd-ldap" */
+190,	/* "id-smime-ct" */
+210,	/* "id-smime-ct-DVCSRequestData" */
+211,	/* "id-smime-ct-DVCSResponseData" */
+208,	/* "id-smime-ct-TDTInfo" */
+207,	/* "id-smime-ct-TSTInfo" */
+205,	/* "id-smime-ct-authData" */
+786,	/* "id-smime-ct-compressedData" */
+209,	/* "id-smime-ct-contentInfo" */
+206,	/* "id-smime-ct-publishCert" */
+204,	/* "id-smime-ct-receipt" */
+195,	/* "id-smime-cti" */
+255,	/* "id-smime-cti-ets-proofOfApproval" */
+256,	/* "id-smime-cti-ets-proofOfCreation" */
+253,	/* "id-smime-cti-ets-proofOfDelivery" */
+251,	/* "id-smime-cti-ets-proofOfOrigin" */
+252,	/* "id-smime-cti-ets-proofOfReceipt" */
+254,	/* "id-smime-cti-ets-proofOfSender" */
+189,	/* "id-smime-mod" */
+196,	/* "id-smime-mod-cms" */
+197,	/* "id-smime-mod-ess" */
+202,	/* "id-smime-mod-ets-eSigPolicy-88" */
+203,	/* "id-smime-mod-ets-eSigPolicy-97" */
+200,	/* "id-smime-mod-ets-eSignature-88" */
+201,	/* "id-smime-mod-ets-eSignature-97" */
+199,	/* "id-smime-mod-msg-v3" */
+198,	/* "id-smime-mod-oid" */
+194,	/* "id-smime-spq" */
+250,	/* "id-smime-spq-ets-sqt-unotice" */
+249,	/* "id-smime-spq-ets-sqt-uri" */
+945,	/* "id-tc26-gost-28147-param-Z" */
+943,	/* "id-tc26-gost-3410-2012-512-paramSetA" */
+944,	/* "id-tc26-gost-3410-2012-512-paramSetB" */
+946,	/* "id-tc26-gost3410-2012-256" */
+947,	/* "id-tc26-gost3410-2012-512" */
+948,	/* "id-tc26-signwithdigest-gost3410-2012-256" */
+949,	/* "id-tc26-signwithdigest-gost3410-2012-512" */
+676,	/* "identified-organization" */
+461,	/* "info" */
+748,	/* "inhibitAnyPolicy" */
+101,	/* "initials" */
+647,	/* "international-organizations" */
+869,	/* "internationaliSDNNumber" */
+142,	/* "invalidityDate" */
+294,	/* "ipsecEndSystem" */
+295,	/* "ipsecTunnel" */
+296,	/* "ipsecUser" */
+86,	/* "issuerAltName" */
+770,	/* "issuingDistributionPoint" */
+492,	/* "janetMailbox" */
+150,	/* "keyBag" */
+83,	/* "keyUsage" */
+477,	/* "lastModifiedBy" */
+476,	/* "lastModifiedTime" */
+157,	/* "localKeyID" */
+480,	/* "mXRecord" */
+460,	/* "mail" */
+493,	/* "mailPreferenceOption" */
+467,	/* "manager" */
+809,	/* "md_gost94" */
+875,	/* "member" */
+182,	/* "member-body" */
+51,	/* "messageDigest" */
+383,	/* "mgmt" */
+504,	/* "mime-mhs" */
+506,	/* "mime-mhs-bodies" */
+505,	/* "mime-mhs-headings" */
+488,	/* "mobileTelephoneNumber" */
+136,	/* "msCTLSign" */
+135,	/* "msCodeCom" */
+134,	/* "msCodeInd" */
+138,	/* "msEFS" */
+171,	/* "msExtReq" */
+137,	/* "msSGC" */
+648,	/* "msSmartcardLogin" */
+649,	/* "msUPN" */
+481,	/* "nSRecord" */
+173,	/* "name" */
+666,	/* "nameConstraints" */
+369,	/* "noCheck" */
+403,	/* "noRevAvail" */
+72,	/* "nsBaseUrl" */
+76,	/* "nsCaPolicyUrl" */
+74,	/* "nsCaRevocationUrl" */
+58,	/* "nsCertExt" */
+79,	/* "nsCertSequence" */
+71,	/* "nsCertType" */
+78,	/* "nsComment" */
+59,	/* "nsDataType" */
+75,	/* "nsRenewalUrl" */
+73,	/* "nsRevocationUrl" */
+139,	/* "nsSGC" */
+77,	/* "nsSslServerName" */
+681,	/* "onBasis" */
+491,	/* "organizationalStatus" */
+475,	/* "otherMailbox" */
+876,	/* "owner" */
+489,	/* "pagerTelephoneNumber" */
+374,	/* "path" */
+112,	/* "pbeWithMD5AndCast5CBC" */
+499,	/* "personalSignature" */
+487,	/* "personalTitle" */
+464,	/* "photo" */
+863,	/* "physicalDeliveryOfficeName" */
+437,	/* "pilot" */
+439,	/* "pilotAttributeSyntax" */
+438,	/* "pilotAttributeType" */
+479,	/* "pilotAttributeType27" */
+456,	/* "pilotDSA" */
+441,	/* "pilotGroups" */
+444,	/* "pilotObject" */
+440,	/* "pilotObjectClass" */
+455,	/* "pilotOrganization" */
+445,	/* "pilotPerson" */
+ 2,	/* "pkcs" */
+186,	/* "pkcs1" */
+27,	/* "pkcs3" */
+187,	/* "pkcs5" */
+20,	/* "pkcs7" */
+21,	/* "pkcs7-data" */
+25,	/* "pkcs7-digestData" */
+26,	/* "pkcs7-encryptedData" */
+23,	/* "pkcs7-envelopedData" */
+24,	/* "pkcs7-signedAndEnvelopedData" */
+22,	/* "pkcs7-signedData" */
+151,	/* "pkcs8ShroudedKeyBag" */
+47,	/* "pkcs9" */
+401,	/* "policyConstraints" */
+747,	/* "policyMappings" */
+862,	/* "postOfficeBox" */
+861,	/* "postalAddress" */
+661,	/* "postalCode" */
+683,	/* "ppBasis" */
+872,	/* "preferredDeliveryMethod" */
+873,	/* "presentationAddress" */
+816,	/* "prf-gostr3411-94" */
+406,	/* "prime-field" */
+409,	/* "prime192v1" */
+410,	/* "prime192v2" */
+411,	/* "prime192v3" */
+412,	/* "prime239v1" */
+413,	/* "prime239v2" */
+414,	/* "prime239v3" */
+415,	/* "prime256v1" */
+385,	/* "private" */
+84,	/* "privateKeyUsagePeriod" */
+886,	/* "protocolInformation" */
+663,	/* "proxyCertInfo" */
+510,	/* "pseudonym" */
+435,	/* "pss" */
+286,	/* "qcStatements" */
+457,	/* "qualityLabelledData" */
+450,	/* "rFC822localPart" */
+870,	/* "registeredAddress" */
+400,	/* "role" */
+877,	/* "roleOccupant" */
+448,	/* "room" */
+463,	/* "roomNumber" */
+ 6,	/* "rsaEncryption" */
+644,	/* "rsaOAEPEncryptionSET" */
+377,	/* "rsaSignature" */
+ 1,	/* "rsadsi" */
+482,	/* "sOARecord" */
+155,	/* "safeContentsBag" */
+291,	/* "sbgp-autonomousSysNum" */
+290,	/* "sbgp-ipAddrBlock" */
+292,	/* "sbgp-routerIdentifier" */
+159,	/* "sdsiCertificate" */
+859,	/* "searchGuide" */
+704,	/* "secp112r1" */
+705,	/* "secp112r2" */
+706,	/* "secp128r1" */
+707,	/* "secp128r2" */
+708,	/* "secp160k1" */
+709,	/* "secp160r1" */
+710,	/* "secp160r2" */
+711,	/* "secp192k1" */
+712,	/* "secp224k1" */
+713,	/* "secp224r1" */
+714,	/* "secp256k1" */
+715,	/* "secp384r1" */
+716,	/* "secp521r1" */
+154,	/* "secretBag" */
+474,	/* "secretary" */
+717,	/* "sect113r1" */
+718,	/* "sect113r2" */
+719,	/* "sect131r1" */
+720,	/* "sect131r2" */
+721,	/* "sect163k1" */
+722,	/* "sect163r1" */
+723,	/* "sect163r2" */
+724,	/* "sect193r1" */
+725,	/* "sect193r2" */
+726,	/* "sect233k1" */
+727,	/* "sect233r1" */
+728,	/* "sect239k1" */
+729,	/* "sect283k1" */
+730,	/* "sect283r1" */
+731,	/* "sect409k1" */
+732,	/* "sect409r1" */
+733,	/* "sect571k1" */
+734,	/* "sect571r1" */
+386,	/* "security" */
+878,	/* "seeAlso" */
+394,	/* "selected-attribute-types" */
+105,	/* "serialNumber" */
+129,	/* "serverAuth" */
+371,	/* "serviceLocator" */
+625,	/* "set-addPolicy" */
+515,	/* "set-attr" */
+518,	/* "set-brand" */
+638,	/* "set-brand-AmericanExpress" */
+637,	/* "set-brand-Diners" */
+636,	/* "set-brand-IATA-ATA" */
+639,	/* "set-brand-JCB" */
+641,	/* "set-brand-MasterCard" */
+642,	/* "set-brand-Novus" */
+640,	/* "set-brand-Visa" */
+517,	/* "set-certExt" */
+513,	/* "set-ctype" */
+514,	/* "set-msgExt" */
+516,	/* "set-policy" */
+607,	/* "set-policy-root" */
+624,	/* "set-rootKeyThumb" */
+620,	/* "setAttr-Cert" */
+631,	/* "setAttr-GenCryptgrm" */
+623,	/* "setAttr-IssCap" */
+628,	/* "setAttr-IssCap-CVM" */
+630,	/* "setAttr-IssCap-Sig" */
+629,	/* "setAttr-IssCap-T2" */
+621,	/* "setAttr-PGWYcap" */
+635,	/* "setAttr-SecDevSig" */
+632,	/* "setAttr-T2Enc" */
+633,	/* "setAttr-T2cleartxt" */
+634,	/* "setAttr-TokICCsig" */
+627,	/* "setAttr-Token-B0Prime" */
+626,	/* "setAttr-Token-EMV" */
+622,	/* "setAttr-TokenType" */
+619,	/* "setCext-IssuerCapabilities" */
+615,	/* "setCext-PGWYcapabilities" */
+616,	/* "setCext-TokenIdentifier" */
+618,	/* "setCext-TokenType" */
+617,	/* "setCext-Track2Data" */
+611,	/* "setCext-cCertRequired" */
+609,	/* "setCext-certType" */
+608,	/* "setCext-hashedRoot" */
+610,	/* "setCext-merchData" */
+613,	/* "setCext-setExt" */
+614,	/* "setCext-setQualf" */
+612,	/* "setCext-tunneling" */
+540,	/* "setct-AcqCardCodeMsg" */
+576,	/* "setct-AcqCardCodeMsgTBE" */
+570,	/* "setct-AuthReqTBE" */
+534,	/* "setct-AuthReqTBS" */
+527,	/* "setct-AuthResBaggage" */
+571,	/* "setct-AuthResTBE" */
+572,	/* "setct-AuthResTBEX" */
+535,	/* "setct-AuthResTBS" */
+536,	/* "setct-AuthResTBSX" */
+528,	/* "setct-AuthRevReqBaggage" */
+577,	/* "setct-AuthRevReqTBE" */
+541,	/* "setct-AuthRevReqTBS" */
+529,	/* "setct-AuthRevResBaggage" */
+542,	/* "setct-AuthRevResData" */
+578,	/* "setct-AuthRevResTBE" */
+579,	/* "setct-AuthRevResTBEB" */
+543,	/* "setct-AuthRevResTBS" */
+573,	/* "setct-AuthTokenTBE" */
+537,	/* "setct-AuthTokenTBS" */
+600,	/* "setct-BCIDistributionTBS" */
+558,	/* "setct-BatchAdminReqData" */
+592,	/* "setct-BatchAdminReqTBE" */
+559,	/* "setct-BatchAdminResData" */
+593,	/* "setct-BatchAdminResTBE" */
+599,	/* "setct-CRLNotificationResTBS" */
+598,	/* "setct-CRLNotificationTBS" */
+580,	/* "setct-CapReqTBE" */
+581,	/* "setct-CapReqTBEX" */
+544,	/* "setct-CapReqTBS" */
+545,	/* "setct-CapReqTBSX" */
+546,	/* "setct-CapResData" */
+582,	/* "setct-CapResTBE" */
+583,	/* "setct-CapRevReqTBE" */
+584,	/* "setct-CapRevReqTBEX" */
+547,	/* "setct-CapRevReqTBS" */
+548,	/* "setct-CapRevReqTBSX" */
+549,	/* "setct-CapRevResData" */
+585,	/* "setct-CapRevResTBE" */
+538,	/* "setct-CapTokenData" */
+530,	/* "setct-CapTokenSeq" */
+574,	/* "setct-CapTokenTBE" */
+575,	/* "setct-CapTokenTBEX" */
+539,	/* "setct-CapTokenTBS" */
+560,	/* "setct-CardCInitResTBS" */
+566,	/* "setct-CertInqReqTBS" */
+563,	/* "setct-CertReqData" */
+595,	/* "setct-CertReqTBE" */
+596,	/* "setct-CertReqTBEX" */
+564,	/* "setct-CertReqTBS" */
+565,	/* "setct-CertResData" */
+597,	/* "setct-CertResTBE" */
+586,	/* "setct-CredReqTBE" */
+587,	/* "setct-CredReqTBEX" */
+550,	/* "setct-CredReqTBS" */
+551,	/* "setct-CredReqTBSX" */
+552,	/* "setct-CredResData" */
+588,	/* "setct-CredResTBE" */
+589,	/* "setct-CredRevReqTBE" */
+590,	/* "setct-CredRevReqTBEX" */
+553,	/* "setct-CredRevReqTBS" */
+554,	/* "setct-CredRevReqTBSX" */
+555,	/* "setct-CredRevResData" */
+591,	/* "setct-CredRevResTBE" */
+567,	/* "setct-ErrorTBS" */
+526,	/* "setct-HODInput" */
+561,	/* "setct-MeAqCInitResTBS" */
+522,	/* "setct-OIData" */
+519,	/* "setct-PANData" */
+521,	/* "setct-PANOnly" */
+520,	/* "setct-PANToken" */
+556,	/* "setct-PCertReqData" */
+557,	/* "setct-PCertResTBS" */
+523,	/* "setct-PI" */
+532,	/* "setct-PI-TBS" */
+524,	/* "setct-PIData" */
+525,	/* "setct-PIDataUnsigned" */
+568,	/* "setct-PIDualSignedTBE" */
+569,	/* "setct-PIUnsignedTBE" */
+531,	/* "setct-PInitResData" */
+533,	/* "setct-PResData" */
+594,	/* "setct-RegFormReqTBE" */
+562,	/* "setct-RegFormResTBS" */
+606,	/* "setext-cv" */
+601,	/* "setext-genCrypt" */
+602,	/* "setext-miAuth" */
+604,	/* "setext-pinAny" */
+603,	/* "setext-pinSecure" */
+605,	/* "setext-track2" */
+52,	/* "signingTime" */
+454,	/* "simpleSecurityObject" */
+496,	/* "singleLevelQuality" */
+387,	/* "snmpv2" */
+941,	/* "streebog256" */
+942,	/* "streebog512" */
+660,	/* "street" */
+85,	/* "subjectAltName" */
+769,	/* "subjectDirectoryAttributes" */
+398,	/* "subjectInfoAccess" */
+82,	/* "subjectKeyIdentifier" */
+498,	/* "subtreeMaximumQuality" */
+497,	/* "subtreeMinimumQuality" */
+890,	/* "supportedAlgorithms" */
+874,	/* "supportedApplicationContext" */
+402,	/* "targetInformation" */
+940,	/* "tc26" */
+864,	/* "telephoneNumber" */
+866,	/* "teletexTerminalIdentifier" */
+920,	/* "teletrust" */
+865,	/* "telexNumber" */
+459,	/* "textEncodedORAddress" */
+293,	/* "textNotice" */
+133,	/* "timeStamping" */
+106,	/* "title" */
+682,	/* "tpBasis" */
+375,	/* "trustRoot" */
+436,	/* "ucl" */
+888,	/* "uniqueMember" */
+55,	/* "unstructuredAddress" */
+49,	/* "unstructuredName" */
+880,	/* "userCertificate" */
+465,	/* "userClass" */
+879,	/* "userPassword" */
+373,	/* "valid" */
+678,	/* "wap" */
+679,	/* "wap-wsg" */
+735,	/* "wap-wsg-idm-ecid-wtls1" */
+743,	/* "wap-wsg-idm-ecid-wtls10" */
+744,	/* "wap-wsg-idm-ecid-wtls11" */
+745,	/* "wap-wsg-idm-ecid-wtls12" */
+736,	/* "wap-wsg-idm-ecid-wtls3" */
+737,	/* "wap-wsg-idm-ecid-wtls4" */
+738,	/* "wap-wsg-idm-ecid-wtls5" */
+739,	/* "wap-wsg-idm-ecid-wtls6" */
+740,	/* "wap-wsg-idm-ecid-wtls7" */
+741,	/* "wap-wsg-idm-ecid-wtls8" */
+742,	/* "wap-wsg-idm-ecid-wtls9" */
+804,	/* "whirlpool" */
+868,	/* "x121Address" */
+503,	/* "x500UniqueIdentifier" */
+158,	/* "x509Certificate" */
+160,	/* "x509Crl" */
+};
+
+static const unsigned int ln_objs[NUM_LN]={
+363,	/* "AD Time Stamping" */
+405,	/* "ANSI X9.62" */
+368,	/* "Acceptable OCSP Responses" */
+910,	/* "Any Extended Key Usage" */
+664,	/* "Any language" */
+177,	/* "Authority Information Access" */
+365,	/* "Basic OCSP Response" */
+285,	/* "Biometric Info" */
+179,	/* "CA Issuers" */
+785,	/* "CA Repository" */
+131,	/* "Code Signing" */
+783,	/* "Diffie-Hellman based MAC" */
+382,	/* "Directory" */
+392,	/* "Domain" */
+132,	/* "E-mail Protection" */
+389,	/* "Enterprises" */
+384,	/* "Experimental" */
+372,	/* "Extended OCSP Status" */
+172,	/* "Extension Request" */
+936,	/* "FRP256v1" */
+813,	/* "GOST 28147-89" */
+849,	/* "GOST 28147-89 Cryptocom ParamSet" */
+815,	/* "GOST 28147-89 MAC" */
+851,	/* "GOST 34.10-2001 Cryptocom" */
+850,	/* "GOST 34.10-94 Cryptocom" */
+942,	/* "GOST R 34-11-2012 (512 bit)" */
+811,	/* "GOST R 34.10-2001" */
+817,	/* "GOST R 34.10-2001 DH" */
+946,	/* "GOST R 34.10-2012 (256 bit)" */
+947,	/* "GOST R 34.10-2012 (512 bit)" */
+812,	/* "GOST R 34.10-94" */
+818,	/* "GOST R 34.10-94 DH" */
+941,	/* "GOST R 34.11-2012 (256 bit)" */
+948,	/* "GOST R 34.11-2012 with GOST R 34.10-2012 (256 bit)" */
+949,	/* "GOST R 34.11-2012 with GOST R 34.10-2012 (512 bit)" */
+809,	/* "GOST R 34.11-94" */
+816,	/* "GOST R 34.11-94 PRF" */
+807,	/* "GOST R 34.11-94 with GOST R 34.10-2001" */
+853,	/* "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" */
+808,	/* "GOST R 34.11-94 with GOST R 34.10-94" */
+852,	/* "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" */
+854,	/* "GOST R 3410-2001 Parameter Set Cryptocom" */
+810,	/* "HMAC GOST 34.11-94" */
+432,	/* "Hold Instruction Call Issuer" */
+430,	/* "Hold Instruction Code" */
+431,	/* "Hold Instruction None" */
+433,	/* "Hold Instruction Reject" */
+634,	/* "ICC or token signature" */
+294,	/* "IPSec End System" */
+295,	/* "IPSec Tunnel" */
+296,	/* "IPSec User" */
+182,	/* "ISO Member Body" */
+183,	/* "ISO US Member Body" */
+667,	/* "Independent" */
+665,	/* "Inherit all" */
+647,	/* "International Organizations" */
+142,	/* "Invalidity Date" */
+504,	/* "MIME MHS" */
+388,	/* "Mail" */
+383,	/* "Management" */
+417,	/* "Microsoft CSP Name" */
+135,	/* "Microsoft Commercial Code Signing" */
+138,	/* "Microsoft Encrypted File System" */
+171,	/* "Microsoft Extension Request" */
+134,	/* "Microsoft Individual Code Signing" */
+856,	/* "Microsoft Local Key set" */
+137,	/* "Microsoft Server Gated Crypto" */
+648,	/* "Microsoft Smartcardlogin" */
+136,	/* "Microsoft Trust List Signing" */
+649,	/* "Microsoft Universal Principal Name" */
+393,	/* "NULL" */
+404,	/* "NULL" */
+72,	/* "Netscape Base Url" */
+76,	/* "Netscape CA Policy Url" */
+74,	/* "Netscape CA Revocation Url" */
+71,	/* "Netscape Cert Type" */
+58,	/* "Netscape Certificate Extension" */
+79,	/* "Netscape Certificate Sequence" */
+78,	/* "Netscape Comment" */
+57,	/* "Netscape Communications Corp." */
+59,	/* "Netscape Data Type" */
+75,	/* "Netscape Renewal Url" */
+73,	/* "Netscape Revocation Url" */
+77,	/* "Netscape SSL Server Name" */
+139,	/* "Netscape Server Gated Crypto" */
+178,	/* "OCSP" */
+370,	/* "OCSP Archive Cutoff" */
+367,	/* "OCSP CRL ID" */
+369,	/* "OCSP No Check" */
+366,	/* "OCSP Nonce" */
+371,	/* "OCSP Service Locator" */
+180,	/* "OCSP Signing" */
+161,	/* "PBES2" */
+69,	/* "PBKDF2" */
+162,	/* "PBMAC1" */
+127,	/* "PKIX" */
+858,	/* "Permanent Identifier" */
+164,	/* "Policy Qualifier CPS" */
+165,	/* "Policy Qualifier User Notice" */
+385,	/* "Private" */
+663,	/* "Proxy Certificate Information" */
+ 1,	/* "RSA Data Security, Inc." */
+ 2,	/* "RSA Data Security, Inc. PKCS" */
+188,	/* "S/MIME" */
+167,	/* "S/MIME Capabilities" */
+387,	/* "SNMPv2" */
+512,	/* "Secure Electronic Transactions" */
+386,	/* "Security" */
+394,	/* "Selected Attribute Types" */
+143,	/* "Strong Extranet ID" */
+398,	/* "Subject Information Access" */
+130,	/* "TLS Web Client Authentication" */
+129,	/* "TLS Web Server Authentication" */
+133,	/* "Time Stamping" */
+375,	/* "Trust Root" */
+12,	/* "X509" */
+402,	/* "X509v3 AC Targeting" */
+746,	/* "X509v3 Any Policy" */
+90,	/* "X509v3 Authority Key Identifier" */
+87,	/* "X509v3 Basic Constraints" */
+103,	/* "X509v3 CRL Distribution Points" */
+88,	/* "X509v3 CRL Number" */
+141,	/* "X509v3 CRL Reason Code" */
+771,	/* "X509v3 Certificate Issuer" */
+89,	/* "X509v3 Certificate Policies" */
+140,	/* "X509v3 Delta CRL Indicator" */
+126,	/* "X509v3 Extended Key Usage" */
+857,	/* "X509v3 Freshest CRL" */
+748,	/* "X509v3 Inhibit Any Policy" */
+86,	/* "X509v3 Issuer Alternative Name" */
+770,	/* "X509v3 Issuing Distrubution Point" */
+83,	/* "X509v3 Key Usage" */
+666,	/* "X509v3 Name Constraints" */
+403,	/* "X509v3 No Revocation Available" */
+401,	/* "X509v3 Policy Constraints" */
+747,	/* "X509v3 Policy Mappings" */
+84,	/* "X509v3 Private Key Usage Period" */
+85,	/* "X509v3 Subject Alternative Name" */
+769,	/* "X509v3 Subject Directory Attributes" */
+82,	/* "X509v3 Subject Key Identifier" */
+184,	/* "X9.57" */
+185,	/* "X9.57 CM ?" */
+478,	/* "aRecord" */
+289,	/* "aaControls" */
+287,	/* "ac-auditEntity" */
+397,	/* "ac-proxying" */
+288,	/* "ac-targeting" */
+446,	/* "account" */
+364,	/* "ad dvcs" */
+606,	/* "additional verification" */
+419,	/* "aes-128-cbc" */
+916,	/* "aes-128-cbc-hmac-sha1" */
+896,	/* "aes-128-ccm" */
+421,	/* "aes-128-cfb" */
+650,	/* "aes-128-cfb1" */
+653,	/* "aes-128-cfb8" */
+904,	/* "aes-128-ctr" */
+418,	/* "aes-128-ecb" */
+895,	/* "aes-128-gcm" */
+420,	/* "aes-128-ofb" */
+913,	/* "aes-128-xts" */
+423,	/* "aes-192-cbc" */
+917,	/* "aes-192-cbc-hmac-sha1" */
+899,	/* "aes-192-ccm" */
+425,	/* "aes-192-cfb" */
+651,	/* "aes-192-cfb1" */
+654,	/* "aes-192-cfb8" */
+905,	/* "aes-192-ctr" */
+422,	/* "aes-192-ecb" */
+898,	/* "aes-192-gcm" */
+424,	/* "aes-192-ofb" */
+427,	/* "aes-256-cbc" */
+918,	/* "aes-256-cbc-hmac-sha1" */
+902,	/* "aes-256-ccm" */
+429,	/* "aes-256-cfb" */
+652,	/* "aes-256-cfb1" */
+655,	/* "aes-256-cfb8" */
+906,	/* "aes-256-ctr" */
+426,	/* "aes-256-ecb" */
+901,	/* "aes-256-gcm" */
+428,	/* "aes-256-ofb" */
+914,	/* "aes-256-xts" */
+376,	/* "algorithm" */
+484,	/* "associatedDomain" */
+485,	/* "associatedName" */
+501,	/* "audio" */
+882,	/* "authorityRevocationList" */
+91,	/* "bf-cbc" */
+93,	/* "bf-cfb" */
+92,	/* "bf-ecb" */
+94,	/* "bf-ofb" */
+921,	/* "brainpool" */
+922,	/* "brainpoolP160r1" */
+923,	/* "brainpoolP160t1" */
+924,	/* "brainpoolP192r1" */
+925,	/* "brainpoolP192t1" */
+926,	/* "brainpoolP224r1" */
+927,	/* "brainpoolP224t1" */
+928,	/* "brainpoolP256r1" */
+929,	/* "brainpoolP256t1" */
+930,	/* "brainpoolP320r1" */
+931,	/* "brainpoolP320t1" */
+932,	/* "brainpoolP384r1" */
+933,	/* "brainpoolP384t1" */
+934,	/* "brainpoolP512r1" */
+935,	/* "brainpoolP512t1" */
+494,	/* "buildingName" */
+860,	/* "businessCategory" */
+691,	/* "c2onb191v4" */
+692,	/* "c2onb191v5" */
+697,	/* "c2onb239v4" */
+698,	/* "c2onb239v5" */
+684,	/* "c2pnb163v1" */
+685,	/* "c2pnb163v2" */
+686,	/* "c2pnb163v3" */
+687,	/* "c2pnb176v1" */
+693,	/* "c2pnb208w1" */
+699,	/* "c2pnb272w1" */
+700,	/* "c2pnb304w1" */
+702,	/* "c2pnb368w1" */
+688,	/* "c2tnb191v1" */
+689,	/* "c2tnb191v2" */
+690,	/* "c2tnb191v3" */
+694,	/* "c2tnb239v1" */
+695,	/* "c2tnb239v2" */
+696,	/* "c2tnb239v3" */
+701,	/* "c2tnb359v1" */
+703,	/* "c2tnb431r1" */
+881,	/* "cACertificate" */
+483,	/* "cNAMERecord" */
+751,	/* "camellia-128-cbc" */
+757,	/* "camellia-128-cfb" */
+760,	/* "camellia-128-cfb1" */
+763,	/* "camellia-128-cfb8" */
+754,	/* "camellia-128-ecb" */
+766,	/* "camellia-128-ofb" */
+752,	/* "camellia-192-cbc" */
+758,	/* "camellia-192-cfb" */
+761,	/* "camellia-192-cfb1" */
+764,	/* "camellia-192-cfb8" */
+755,	/* "camellia-192-ecb" */
+767,	/* "camellia-192-ofb" */
+753,	/* "camellia-256-cbc" */
+759,	/* "camellia-256-cfb" */
+762,	/* "camellia-256-cfb1" */
+765,	/* "camellia-256-cfb8" */
+756,	/* "camellia-256-ecb" */
+768,	/* "camellia-256-ofb" */
+443,	/* "caseIgnoreIA5StringSyntax" */
+108,	/* "cast5-cbc" */
+110,	/* "cast5-cfb" */
+109,	/* "cast5-ecb" */
+111,	/* "cast5-ofb" */
+152,	/* "certBag" */
+677,	/* "certicom-arc" */
+517,	/* "certificate extensions" */
+883,	/* "certificateRevocationList" */
+937,	/* "chacha" */
+54,	/* "challengePassword" */
+407,	/* "characteristic-two-field" */
+395,	/* "clearance" */
+633,	/* "cleartext track 2" */
+894,	/* "cmac" */
+13,	/* "commonName" */
+513,	/* "content types" */
+50,	/* "contentType" */
+53,	/* "countersignature" */
+14,	/* "countryName" */
+153,	/* "crlBag" */
+884,	/* "crossCertificatePair" */
+806,	/* "cryptocom" */
+805,	/* "cryptopro" */
+500,	/* "dITRedirect" */
+451,	/* "dNSDomain" */
+495,	/* "dSAQuality" */
+434,	/* "data" */
+390,	/* "dcObject" */
+891,	/* "deltaRevocationList" */
+31,	/* "des-cbc" */
+643,	/* "des-cdmf" */
+30,	/* "des-cfb" */
+656,	/* "des-cfb1" */
+657,	/* "des-cfb8" */
+29,	/* "des-ecb" */
+32,	/* "des-ede" */
+43,	/* "des-ede-cbc" */
+60,	/* "des-ede-cfb" */
+62,	/* "des-ede-ofb" */
+33,	/* "des-ede3" */
+44,	/* "des-ede3-cbc" */
+61,	/* "des-ede3-cfb" */
+658,	/* "des-ede3-cfb1" */
+659,	/* "des-ede3-cfb8" */
+63,	/* "des-ede3-ofb" */
+45,	/* "des-ofb" */
+107,	/* "description" */
+871,	/* "destinationIndicator" */
+80,	/* "desx-cbc" */
+28,	/* "dhKeyAgreement" */
+11,	/* "directory services (X.500)" */
+378,	/* "directory services - algorithms" */
+887,	/* "distinguishedName" */
+892,	/* "dmdName" */
+174,	/* "dnQualifier" */
+447,	/* "document" */
+471,	/* "documentAuthor" */
+468,	/* "documentIdentifier" */
+472,	/* "documentLocation" */
+502,	/* "documentPublisher" */
+449,	/* "documentSeries" */
+469,	/* "documentTitle" */
+470,	/* "documentVersion" */
+380,	/* "dod" */
+391,	/* "domainComponent" */
+452,	/* "domainRelatedObject" */
+116,	/* "dsaEncryption" */
+67,	/* "dsaEncryption-old" */
+66,	/* "dsaWithSHA" */
+113,	/* "dsaWithSHA1" */
+70,	/* "dsaWithSHA1-old" */
+802,	/* "dsa_with_SHA224" */
+803,	/* "dsa_with_SHA256" */
+297,	/* "dvcs" */
+791,	/* "ecdsa-with-Recommended" */
+416,	/* "ecdsa-with-SHA1" */
+793,	/* "ecdsa-with-SHA224" */
+794,	/* "ecdsa-with-SHA256" */
+795,	/* "ecdsa-with-SHA384" */
+796,	/* "ecdsa-with-SHA512" */
+792,	/* "ecdsa-with-Specified" */
+48,	/* "emailAddress" */
+632,	/* "encrypted track 2" */
+885,	/* "enhancedSearchGuide" */
+56,	/* "extendedCertificateAttributes" */
+867,	/* "facsimileTelephoneNumber" */
+462,	/* "favouriteDrink" */
+453,	/* "friendlyCountry" */
+490,	/* "friendlyCountryName" */
+156,	/* "friendlyName" */
+631,	/* "generate cryptogram" */
+509,	/* "generationQualifier" */
+601,	/* "generic cryptogram" */
+99,	/* "givenName" */
+939,	/* "gost89-cbc" */
+814,	/* "gost89-cnt" */
+938,	/* "gost89-ecb" */
+855,	/* "hmac" */
+780,	/* "hmac-md5" */
+781,	/* "hmac-sha1" */
+797,	/* "hmacWithMD5" */
+163,	/* "hmacWithSHA1" */
+798,	/* "hmacWithSHA224" */
+799,	/* "hmacWithSHA256" */
+800,	/* "hmacWithSHA384" */
+801,	/* "hmacWithSHA512" */
+486,	/* "homePostalAddress" */
+473,	/* "homeTelephoneNumber" */
+466,	/* "host" */
+889,	/* "houseIdentifier" */
+442,	/* "iA5StringSyntax" */
+381,	/* "iana" */
+824,	/* "id-Gost28147-89-CryptoPro-A-ParamSet" */
+825,	/* "id-Gost28147-89-CryptoPro-B-ParamSet" */
+826,	/* "id-Gost28147-89-CryptoPro-C-ParamSet" */
+827,	/* "id-Gost28147-89-CryptoPro-D-ParamSet" */
+819,	/* "id-Gost28147-89-CryptoPro-KeyMeshing" */
+829,	/* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */
+828,	/* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */
+830,	/* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */
+820,	/* "id-Gost28147-89-None-KeyMeshing" */
+823,	/* "id-Gost28147-89-TestParamSet" */
+840,	/* "id-GostR3410-2001-CryptoPro-A-ParamSet" */
+841,	/* "id-GostR3410-2001-CryptoPro-B-ParamSet" */
+842,	/* "id-GostR3410-2001-CryptoPro-C-ParamSet" */
+843,	/* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */
+844,	/* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */
+839,	/* "id-GostR3410-2001-TestParamSet" */
+832,	/* "id-GostR3410-94-CryptoPro-A-ParamSet" */
+833,	/* "id-GostR3410-94-CryptoPro-B-ParamSet" */
+834,	/* "id-GostR3410-94-CryptoPro-C-ParamSet" */
+835,	/* "id-GostR3410-94-CryptoPro-D-ParamSet" */
+836,	/* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */
+837,	/* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */
+838,	/* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */
+831,	/* "id-GostR3410-94-TestParamSet" */
+845,	/* "id-GostR3410-94-a" */
+846,	/* "id-GostR3410-94-aBis" */
+847,	/* "id-GostR3410-94-b" */
+848,	/* "id-GostR3410-94-bBis" */
+822,	/* "id-GostR3411-94-CryptoProParamSet" */
+821,	/* "id-GostR3411-94-TestParamSet" */
+266,	/* "id-aca" */
+355,	/* "id-aca-accessIdentity" */
+354,	/* "id-aca-authenticationInfo" */
+356,	/* "id-aca-chargingIdentity" */
+399,	/* "id-aca-encAttrs" */
+357,	/* "id-aca-group" */
+358,	/* "id-aca-role" */
+176,	/* "id-ad" */
+788,	/* "id-aes128-wrap" */
+897,	/* "id-aes128-wrap-pad" */
+789,	/* "id-aes192-wrap" */
+900,	/* "id-aes192-wrap-pad" */
+790,	/* "id-aes256-wrap" */
+903,	/* "id-aes256-wrap-pad" */
+262,	/* "id-alg" */
+893,	/* "id-alg-PWRI-KEK" */
+323,	/* "id-alg-des40" */
+326,	/* "id-alg-dh-pop" */
+325,	/* "id-alg-dh-sig-hmac-sha1" */
+324,	/* "id-alg-noSignature" */
+907,	/* "id-camellia128-wrap" */
+908,	/* "id-camellia192-wrap" */
+909,	/* "id-camellia256-wrap" */
+268,	/* "id-cct" */
+361,	/* "id-cct-PKIData" */
+362,	/* "id-cct-PKIResponse" */
+360,	/* "id-cct-crs" */
+81,	/* "id-ce" */
+680,	/* "id-characteristic-two-basis" */
+263,	/* "id-cmc" */
+334,	/* "id-cmc-addExtensions" */
+346,	/* "id-cmc-confirmCertAcceptance" */
+330,	/* "id-cmc-dataReturn" */
+336,	/* "id-cmc-decryptedPOP" */
+335,	/* "id-cmc-encryptedPOP" */
+339,	/* "id-cmc-getCRL" */
+338,	/* "id-cmc-getCert" */
+328,	/* "id-cmc-identification" */
+329,	/* "id-cmc-identityProof" */
+337,	/* "id-cmc-lraPOPWitness" */
+344,	/* "id-cmc-popLinkRandom" */
+345,	/* "id-cmc-popLinkWitness" */
+343,	/* "id-cmc-queryPending" */
+333,	/* "id-cmc-recipientNonce" */
+341,	/* "id-cmc-regInfo" */
+342,	/* "id-cmc-responseInfo" */
+340,	/* "id-cmc-revokeRequest" */
+332,	/* "id-cmc-senderNonce" */
+327,	/* "id-cmc-statusInfo" */
+331,	/* "id-cmc-transactionId" */
+787,	/* "id-ct-asciiTextWithCRLF" */
+408,	/* "id-ecPublicKey" */
+508,	/* "id-hex-multipart-message" */
+507,	/* "id-hex-partial-message" */
+260,	/* "id-it" */
+302,	/* "id-it-caKeyUpdateInfo" */
+298,	/* "id-it-caProtEncCert" */
+311,	/* "id-it-confirmWaitTime" */
+303,	/* "id-it-currentCRL" */
+300,	/* "id-it-encKeyPairTypes" */
+310,	/* "id-it-implicitConfirm" */
+308,	/* "id-it-keyPairParamRep" */
+307,	/* "id-it-keyPairParamReq" */
+312,	/* "id-it-origPKIMessage" */
+301,	/* "id-it-preferredSymmAlg" */
+309,	/* "id-it-revPassphrase" */
+299,	/* "id-it-signKeyPairTypes" */
+305,	/* "id-it-subscriptionRequest" */
+306,	/* "id-it-subscriptionResponse" */
+784,	/* "id-it-suppLangTags" */
+304,	/* "id-it-unsupportedOIDs" */
+128,	/* "id-kp" */
+280,	/* "id-mod-attribute-cert" */
+274,	/* "id-mod-cmc" */
+277,	/* "id-mod-cmp" */
+284,	/* "id-mod-cmp2000" */
+273,	/* "id-mod-crmf" */
+283,	/* "id-mod-dvcs" */
+275,	/* "id-mod-kea-profile-88" */
+276,	/* "id-mod-kea-profile-93" */
+282,	/* "id-mod-ocsp" */
+278,	/* "id-mod-qualified-cert-88" */
+279,	/* "id-mod-qualified-cert-93" */
+281,	/* "id-mod-timestamp-protocol" */
+264,	/* "id-on" */
+347,	/* "id-on-personalData" */
+265,	/* "id-pda" */
+352,	/* "id-pda-countryOfCitizenship" */
+353,	/* "id-pda-countryOfResidence" */
+348,	/* "id-pda-dateOfBirth" */
+351,	/* "id-pda-gender" */
+349,	/* "id-pda-placeOfBirth" */
+175,	/* "id-pe" */
+261,	/* "id-pkip" */
+258,	/* "id-pkix-mod" */
+269,	/* "id-pkix1-explicit-88" */
+271,	/* "id-pkix1-explicit-93" */
+270,	/* "id-pkix1-implicit-88" */
+272,	/* "id-pkix1-implicit-93" */
+662,	/* "id-ppl" */
+267,	/* "id-qcs" */
+359,	/* "id-qcs-pkixQCSyntax-v1" */
+259,	/* "id-qt" */
+313,	/* "id-regCtrl" */
+316,	/* "id-regCtrl-authenticator" */
+319,	/* "id-regCtrl-oldCertID" */
+318,	/* "id-regCtrl-pkiArchiveOptions" */
+317,	/* "id-regCtrl-pkiPublicationInfo" */
+320,	/* "id-regCtrl-protocolEncrKey" */
+315,	/* "id-regCtrl-regToken" */
+314,	/* "id-regInfo" */
+322,	/* "id-regInfo-certReq" */
+321,	/* "id-regInfo-utf8Pairs" */
+191,	/* "id-smime-aa" */
+215,	/* "id-smime-aa-contentHint" */
+218,	/* "id-smime-aa-contentIdentifier" */
+221,	/* "id-smime-aa-contentReference" */
+240,	/* "id-smime-aa-dvcs-dvc" */
+217,	/* "id-smime-aa-encapContentType" */
+222,	/* "id-smime-aa-encrypKeyPref" */
+220,	/* "id-smime-aa-equivalentLabels" */
+232,	/* "id-smime-aa-ets-CertificateRefs" */
+233,	/* "id-smime-aa-ets-RevocationRefs" */
+238,	/* "id-smime-aa-ets-archiveTimeStamp" */
+237,	/* "id-smime-aa-ets-certCRLTimestamp" */
+234,	/* "id-smime-aa-ets-certValues" */
+227,	/* "id-smime-aa-ets-commitmentType" */
+231,	/* "id-smime-aa-ets-contentTimestamp" */
+236,	/* "id-smime-aa-ets-escTimeStamp" */
+230,	/* "id-smime-aa-ets-otherSigCert" */
+235,	/* "id-smime-aa-ets-revocationValues" */
+226,	/* "id-smime-aa-ets-sigPolicyId" */
+229,	/* "id-smime-aa-ets-signerAttr" */
+228,	/* "id-smime-aa-ets-signerLocation" */
+219,	/* "id-smime-aa-macValue" */
+214,	/* "id-smime-aa-mlExpandHistory" */
+216,	/* "id-smime-aa-msgSigDigest" */
+212,	/* "id-smime-aa-receiptRequest" */
+213,	/* "id-smime-aa-securityLabel" */
+239,	/* "id-smime-aa-signatureType" */
+223,	/* "id-smime-aa-signingCertificate" */
+224,	/* "id-smime-aa-smimeEncryptCerts" */
+225,	/* "id-smime-aa-timeStampToken" */
+192,	/* "id-smime-alg" */
+243,	/* "id-smime-alg-3DESwrap" */
+246,	/* "id-smime-alg-CMS3DESwrap" */
+247,	/* "id-smime-alg-CMSRC2wrap" */
+245,	/* "id-smime-alg-ESDH" */
+241,	/* "id-smime-alg-ESDHwith3DES" */
+242,	/* "id-smime-alg-ESDHwithRC2" */
+244,	/* "id-smime-alg-RC2wrap" */
+193,	/* "id-smime-cd" */
+248,	/* "id-smime-cd-ldap" */
+190,	/* "id-smime-ct" */
+210,	/* "id-smime-ct-DVCSRequestData" */
+211,	/* "id-smime-ct-DVCSResponseData" */
+208,	/* "id-smime-ct-TDTInfo" */
+207,	/* "id-smime-ct-TSTInfo" */
+205,	/* "id-smime-ct-authData" */
+786,	/* "id-smime-ct-compressedData" */
+209,	/* "id-smime-ct-contentInfo" */
+206,	/* "id-smime-ct-publishCert" */
+204,	/* "id-smime-ct-receipt" */
+195,	/* "id-smime-cti" */
+255,	/* "id-smime-cti-ets-proofOfApproval" */
+256,	/* "id-smime-cti-ets-proofOfCreation" */
+253,	/* "id-smime-cti-ets-proofOfDelivery" */
+251,	/* "id-smime-cti-ets-proofOfOrigin" */
+252,	/* "id-smime-cti-ets-proofOfReceipt" */
+254,	/* "id-smime-cti-ets-proofOfSender" */
+189,	/* "id-smime-mod" */
+196,	/* "id-smime-mod-cms" */
+197,	/* "id-smime-mod-ess" */
+202,	/* "id-smime-mod-ets-eSigPolicy-88" */
+203,	/* "id-smime-mod-ets-eSigPolicy-97" */
+200,	/* "id-smime-mod-ets-eSignature-88" */
+201,	/* "id-smime-mod-ets-eSignature-97" */
+199,	/* "id-smime-mod-msg-v3" */
+198,	/* "id-smime-mod-oid" */
+194,	/* "id-smime-spq" */
+250,	/* "id-smime-spq-ets-sqt-unotice" */
+249,	/* "id-smime-spq-ets-sqt-uri" */
+945,	/* "id-tc26-gost-28147-param-Z" */
+943,	/* "id-tc26-gost-3410-2012-512-paramSetA" */
+944,	/* "id-tc26-gost-3410-2012-512-paramSetB" */
+34,	/* "idea-cbc" */
+35,	/* "idea-cfb" */
+36,	/* "idea-ecb" */
+46,	/* "idea-ofb" */
+676,	/* "identified-organization" */
+461,	/* "info" */
+101,	/* "initials" */
+869,	/* "internationaliSDNNumber" */
+749,	/* "ipsec3" */
+750,	/* "ipsec4" */
+181,	/* "iso" */
+623,	/* "issuer capabilities" */
+645,	/* "itu-t" */
+492,	/* "janetMailbox" */
+646,	/* "joint-iso-itu-t" */
+150,	/* "keyBag" */
+773,	/* "kisa" */
+477,	/* "lastModifiedBy" */
+476,	/* "lastModifiedTime" */
+157,	/* "localKeyID" */
+15,	/* "localityName" */
+480,	/* "mXRecord" */
+493,	/* "mailPreferenceOption" */
+467,	/* "manager" */
+ 3,	/* "md2" */
+ 7,	/* "md2WithRSAEncryption" */
+257,	/* "md4" */
+396,	/* "md4WithRSAEncryption" */
+ 4,	/* "md5" */
+114,	/* "md5-sha1" */
+104,	/* "md5WithRSA" */
+ 8,	/* "md5WithRSAEncryption" */
+95,	/* "mdc2" */
+96,	/* "mdc2WithRSA" */
+875,	/* "member" */
+602,	/* "merchant initiated auth" */
+514,	/* "message extensions" */
+51,	/* "messageDigest" */
+911,	/* "mgf1" */
+506,	/* "mime-mhs-bodies" */
+505,	/* "mime-mhs-headings" */
+488,	/* "mobileTelephoneNumber" */
+481,	/* "nSRecord" */
+173,	/* "name" */
+681,	/* "onBasis" */
+379,	/* "org" */
+17,	/* "organizationName" */
+491,	/* "organizationalStatus" */
+18,	/* "organizationalUnitName" */
+475,	/* "otherMailbox" */
+876,	/* "owner" */
+489,	/* "pagerTelephoneNumber" */
+782,	/* "password based MAC" */
+374,	/* "path" */
+621,	/* "payment gateway capabilities" */
+ 9,	/* "pbeWithMD2AndDES-CBC" */
+168,	/* "pbeWithMD2AndRC2-CBC" */
+112,	/* "pbeWithMD5AndCast5CBC" */
+10,	/* "pbeWithMD5AndDES-CBC" */
+169,	/* "pbeWithMD5AndRC2-CBC" */
+148,	/* "pbeWithSHA1And128BitRC2-CBC" */
+144,	/* "pbeWithSHA1And128BitRC4" */
+147,	/* "pbeWithSHA1And2-KeyTripleDES-CBC" */
+146,	/* "pbeWithSHA1And3-KeyTripleDES-CBC" */
+149,	/* "pbeWithSHA1And40BitRC2-CBC" */
+145,	/* "pbeWithSHA1And40BitRC4" */
+170,	/* "pbeWithSHA1AndDES-CBC" */
+68,	/* "pbeWithSHA1AndRC2-CBC" */
+499,	/* "personalSignature" */
+487,	/* "personalTitle" */
+464,	/* "photo" */
+863,	/* "physicalDeliveryOfficeName" */
+437,	/* "pilot" */
+439,	/* "pilotAttributeSyntax" */
+438,	/* "pilotAttributeType" */
+479,	/* "pilotAttributeType27" */
+456,	/* "pilotDSA" */
+441,	/* "pilotGroups" */
+444,	/* "pilotObject" */
+440,	/* "pilotObjectClass" */
+455,	/* "pilotOrganization" */
+445,	/* "pilotPerson" */
+186,	/* "pkcs1" */
+27,	/* "pkcs3" */
+187,	/* "pkcs5" */
+20,	/* "pkcs7" */
+21,	/* "pkcs7-data" */
+25,	/* "pkcs7-digestData" */
+26,	/* "pkcs7-encryptedData" */
+23,	/* "pkcs7-envelopedData" */
+24,	/* "pkcs7-signedAndEnvelopedData" */
+22,	/* "pkcs7-signedData" */
+151,	/* "pkcs8ShroudedKeyBag" */
+47,	/* "pkcs9" */
+862,	/* "postOfficeBox" */
+861,	/* "postalAddress" */
+661,	/* "postalCode" */
+683,	/* "ppBasis" */
+872,	/* "preferredDeliveryMethod" */
+873,	/* "presentationAddress" */
+406,	/* "prime-field" */
+409,	/* "prime192v1" */
+410,	/* "prime192v2" */
+411,	/* "prime192v3" */
+412,	/* "prime239v1" */
+413,	/* "prime239v2" */
+414,	/* "prime239v3" */
+415,	/* "prime256v1" */
+886,	/* "protocolInformation" */
+510,	/* "pseudonym" */
+435,	/* "pss" */
+286,	/* "qcStatements" */
+457,	/* "qualityLabelledData" */
+450,	/* "rFC822localPart" */
+98,	/* "rc2-40-cbc" */
+166,	/* "rc2-64-cbc" */
+37,	/* "rc2-cbc" */
+39,	/* "rc2-cfb" */
+38,	/* "rc2-ecb" */
+40,	/* "rc2-ofb" */
+ 5,	/* "rc4" */
+97,	/* "rc4-40" */
+915,	/* "rc4-hmac-md5" */
+120,	/* "rc5-cbc" */
+122,	/* "rc5-cfb" */
+121,	/* "rc5-ecb" */
+123,	/* "rc5-ofb" */
+870,	/* "registeredAddress" */
+460,	/* "rfc822Mailbox" */
+117,	/* "ripemd160" */
+119,	/* "ripemd160WithRSA" */
+400,	/* "role" */
+877,	/* "roleOccupant" */
+448,	/* "room" */
+463,	/* "roomNumber" */
+19,	/* "rsa" */
+ 6,	/* "rsaEncryption" */
+644,	/* "rsaOAEPEncryptionSET" */
+377,	/* "rsaSignature" */
+919,	/* "rsaesOaep" */
+912,	/* "rsassaPss" */
+124,	/* "run length compression" */
+482,	/* "sOARecord" */
+155,	/* "safeContentsBag" */
+291,	/* "sbgp-autonomousSysNum" */
+290,	/* "sbgp-ipAddrBlock" */
+292,	/* "sbgp-routerIdentifier" */
+159,	/* "sdsiCertificate" */
+859,	/* "searchGuide" */
+704,	/* "secp112r1" */
+705,	/* "secp112r2" */
+706,	/* "secp128r1" */
+707,	/* "secp128r2" */
+708,	/* "secp160k1" */
+709,	/* "secp160r1" */
+710,	/* "secp160r2" */
+711,	/* "secp192k1" */
+712,	/* "secp224k1" */
+713,	/* "secp224r1" */
+714,	/* "secp256k1" */
+715,	/* "secp384r1" */
+716,	/* "secp521r1" */
+154,	/* "secretBag" */
+474,	/* "secretary" */
+717,	/* "sect113r1" */
+718,	/* "sect113r2" */
+719,	/* "sect131r1" */
+720,	/* "sect131r2" */
+721,	/* "sect163k1" */
+722,	/* "sect163r1" */
+723,	/* "sect163r2" */
+724,	/* "sect193r1" */
+725,	/* "sect193r2" */
+726,	/* "sect233k1" */
+727,	/* "sect233r1" */
+728,	/* "sect239k1" */
+729,	/* "sect283k1" */
+730,	/* "sect283r1" */
+731,	/* "sect409k1" */
+732,	/* "sect409r1" */
+733,	/* "sect571k1" */
+734,	/* "sect571r1" */
+635,	/* "secure device signature" */
+878,	/* "seeAlso" */
+777,	/* "seed-cbc" */
+779,	/* "seed-cfb" */
+776,	/* "seed-ecb" */
+778,	/* "seed-ofb" */
+105,	/* "serialNumber" */
+625,	/* "set-addPolicy" */
+515,	/* "set-attr" */
+518,	/* "set-brand" */
+638,	/* "set-brand-AmericanExpress" */
+637,	/* "set-brand-Diners" */
+636,	/* "set-brand-IATA-ATA" */
+639,	/* "set-brand-JCB" */
+641,	/* "set-brand-MasterCard" */
+642,	/* "set-brand-Novus" */
+640,	/* "set-brand-Visa" */
+516,	/* "set-policy" */
+607,	/* "set-policy-root" */
+624,	/* "set-rootKeyThumb" */
+620,	/* "setAttr-Cert" */
+628,	/* "setAttr-IssCap-CVM" */
+630,	/* "setAttr-IssCap-Sig" */
+629,	/* "setAttr-IssCap-T2" */
+627,	/* "setAttr-Token-B0Prime" */
+626,	/* "setAttr-Token-EMV" */
+622,	/* "setAttr-TokenType" */
+619,	/* "setCext-IssuerCapabilities" */
+615,	/* "setCext-PGWYcapabilities" */
+616,	/* "setCext-TokenIdentifier" */
+618,	/* "setCext-TokenType" */
+617,	/* "setCext-Track2Data" */
+611,	/* "setCext-cCertRequired" */
+609,	/* "setCext-certType" */
+608,	/* "setCext-hashedRoot" */
+610,	/* "setCext-merchData" */
+613,	/* "setCext-setExt" */
+614,	/* "setCext-setQualf" */
+612,	/* "setCext-tunneling" */
+540,	/* "setct-AcqCardCodeMsg" */
+576,	/* "setct-AcqCardCodeMsgTBE" */
+570,	/* "setct-AuthReqTBE" */
+534,	/* "setct-AuthReqTBS" */
+527,	/* "setct-AuthResBaggage" */
+571,	/* "setct-AuthResTBE" */
+572,	/* "setct-AuthResTBEX" */
+535,	/* "setct-AuthResTBS" */
+536,	/* "setct-AuthResTBSX" */
+528,	/* "setct-AuthRevReqBaggage" */
+577,	/* "setct-AuthRevReqTBE" */
+541,	/* "setct-AuthRevReqTBS" */
+529,	/* "setct-AuthRevResBaggage" */
+542,	/* "setct-AuthRevResData" */
+578,	/* "setct-AuthRevResTBE" */
+579,	/* "setct-AuthRevResTBEB" */
+543,	/* "setct-AuthRevResTBS" */
+573,	/* "setct-AuthTokenTBE" */
+537,	/* "setct-AuthTokenTBS" */
+600,	/* "setct-BCIDistributionTBS" */
+558,	/* "setct-BatchAdminReqData" */
+592,	/* "setct-BatchAdminReqTBE" */
+559,	/* "setct-BatchAdminResData" */
+593,	/* "setct-BatchAdminResTBE" */
+599,	/* "setct-CRLNotificationResTBS" */
+598,	/* "setct-CRLNotificationTBS" */
+580,	/* "setct-CapReqTBE" */
+581,	/* "setct-CapReqTBEX" */
+544,	/* "setct-CapReqTBS" */
+545,	/* "setct-CapReqTBSX" */
+546,	/* "setct-CapResData" */
+582,	/* "setct-CapResTBE" */
+583,	/* "setct-CapRevReqTBE" */
+584,	/* "setct-CapRevReqTBEX" */
+547,	/* "setct-CapRevReqTBS" */
+548,	/* "setct-CapRevReqTBSX" */
+549,	/* "setct-CapRevResData" */
+585,	/* "setct-CapRevResTBE" */
+538,	/* "setct-CapTokenData" */
+530,	/* "setct-CapTokenSeq" */
+574,	/* "setct-CapTokenTBE" */
+575,	/* "setct-CapTokenTBEX" */
+539,	/* "setct-CapTokenTBS" */
+560,	/* "setct-CardCInitResTBS" */
+566,	/* "setct-CertInqReqTBS" */
+563,	/* "setct-CertReqData" */
+595,	/* "setct-CertReqTBE" */
+596,	/* "setct-CertReqTBEX" */
+564,	/* "setct-CertReqTBS" */
+565,	/* "setct-CertResData" */
+597,	/* "setct-CertResTBE" */
+586,	/* "setct-CredReqTBE" */
+587,	/* "setct-CredReqTBEX" */
+550,	/* "setct-CredReqTBS" */
+551,	/* "setct-CredReqTBSX" */
+552,	/* "setct-CredResData" */
+588,	/* "setct-CredResTBE" */
+589,	/* "setct-CredRevReqTBE" */
+590,	/* "setct-CredRevReqTBEX" */
+553,	/* "setct-CredRevReqTBS" */
+554,	/* "setct-CredRevReqTBSX" */
+555,	/* "setct-CredRevResData" */
+591,	/* "setct-CredRevResTBE" */
+567,	/* "setct-ErrorTBS" */
+526,	/* "setct-HODInput" */
+561,	/* "setct-MeAqCInitResTBS" */
+522,	/* "setct-OIData" */
+519,	/* "setct-PANData" */
+521,	/* "setct-PANOnly" */
+520,	/* "setct-PANToken" */
+556,	/* "setct-PCertReqData" */
+557,	/* "setct-PCertResTBS" */
+523,	/* "setct-PI" */
+532,	/* "setct-PI-TBS" */
+524,	/* "setct-PIData" */
+525,	/* "setct-PIDataUnsigned" */
+568,	/* "setct-PIDualSignedTBE" */
+569,	/* "setct-PIUnsignedTBE" */
+531,	/* "setct-PInitResData" */
+533,	/* "setct-PResData" */
+594,	/* "setct-RegFormReqTBE" */
+562,	/* "setct-RegFormResTBS" */
+604,	/* "setext-pinAny" */
+603,	/* "setext-pinSecure" */
+605,	/* "setext-track2" */
+41,	/* "sha" */
+64,	/* "sha1" */
+115,	/* "sha1WithRSA" */
+65,	/* "sha1WithRSAEncryption" */
+675,	/* "sha224" */
+671,	/* "sha224WithRSAEncryption" */
+672,	/* "sha256" */
+668,	/* "sha256WithRSAEncryption" */
+673,	/* "sha384" */
+669,	/* "sha384WithRSAEncryption" */
+674,	/* "sha512" */
+670,	/* "sha512WithRSAEncryption" */
+42,	/* "shaWithRSAEncryption" */
+52,	/* "signingTime" */
+454,	/* "simpleSecurityObject" */
+496,	/* "singleLevelQuality" */
+16,	/* "stateOrProvinceName" */
+660,	/* "streetAddress" */
+498,	/* "subtreeMaximumQuality" */
+497,	/* "subtreeMinimumQuality" */
+890,	/* "supportedAlgorithms" */
+874,	/* "supportedApplicationContext" */
+100,	/* "surname" */
+940,	/* "tc26" */
+864,	/* "telephoneNumber" */
+866,	/* "teletexTerminalIdentifier" */
+920,	/* "teletrust" */
+865,	/* "telexNumber" */
+459,	/* "textEncodedORAddress" */
+293,	/* "textNotice" */
+106,	/* "title" */
+682,	/* "tpBasis" */
+436,	/* "ucl" */
+ 0,	/* "undefined" */
+888,	/* "uniqueMember" */
+55,	/* "unstructuredAddress" */
+49,	/* "unstructuredName" */
+880,	/* "userCertificate" */
+465,	/* "userClass" */
+458,	/* "userId" */
+879,	/* "userPassword" */
+373,	/* "valid" */
+678,	/* "wap" */
+679,	/* "wap-wsg" */
+735,	/* "wap-wsg-idm-ecid-wtls1" */
+743,	/* "wap-wsg-idm-ecid-wtls10" */
+744,	/* "wap-wsg-idm-ecid-wtls11" */
+745,	/* "wap-wsg-idm-ecid-wtls12" */
+736,	/* "wap-wsg-idm-ecid-wtls3" */
+737,	/* "wap-wsg-idm-ecid-wtls4" */
+738,	/* "wap-wsg-idm-ecid-wtls5" */
+739,	/* "wap-wsg-idm-ecid-wtls6" */
+740,	/* "wap-wsg-idm-ecid-wtls7" */
+741,	/* "wap-wsg-idm-ecid-wtls8" */
+742,	/* "wap-wsg-idm-ecid-wtls9" */
+804,	/* "whirlpool" */
+868,	/* "x121Address" */
+503,	/* "x500UniqueIdentifier" */
+158,	/* "x509Certificate" */
+160,	/* "x509Crl" */
+125,	/* "zlib compression" */
+};
+
+static const unsigned int obj_objs[NUM_OBJ]={
+ 0,	/* OBJ_undef                        0 */
+181,	/* OBJ_iso                          1 */
+393,	/* OBJ_joint_iso_ccitt              OBJ_joint_iso_itu_t */
+404,	/* OBJ_ccitt                        OBJ_itu_t */
+645,	/* OBJ_itu_t                        0 */
+646,	/* OBJ_joint_iso_itu_t              2 */
+434,	/* OBJ_data                         0 9 */
+182,	/* OBJ_member_body                  1 2 */
+379,	/* OBJ_org                          1 3 */
+676,	/* OBJ_identified_organization      1 3 */
+11,	/* OBJ_X500                         2 5 */
+647,	/* OBJ_international_organizations  2 23 */
+380,	/* OBJ_dod                          1 3 6 */
+920,	/* OBJ_teletrust                    1 3 36 */
+12,	/* OBJ_X509                         2 5 4 */
+378,	/* OBJ_X500algorithms               2 5 8 */
+81,	/* OBJ_id_ce                        2 5 29 */
+512,	/* OBJ_id_set                       2 23 42 */
+678,	/* OBJ_wap                          2 23 43 */
+435,	/* OBJ_pss                          0 9 2342 */
+183,	/* OBJ_ISO_US                       1 2 840 */
+381,	/* OBJ_iana                         1 3 6 1 */
+677,	/* OBJ_certicom_arc                 1 3 132 */
+394,	/* OBJ_selected_attribute_types     2 5 1 5 */
+13,	/* OBJ_commonName                   2 5 4 3 */
+100,	/* OBJ_surname                      2 5 4 4 */
+105,	/* OBJ_serialNumber                 2 5 4 5 */
+14,	/* OBJ_countryName                  2 5 4 6 */
+15,	/* OBJ_localityName                 2 5 4 7 */
+16,	/* OBJ_stateOrProvinceName          2 5 4 8 */
+660,	/* OBJ_streetAddress                2 5 4 9 */
+17,	/* OBJ_organizationName             2 5 4 10 */
+18,	/* OBJ_organizationalUnitName       2 5 4 11 */
+106,	/* OBJ_title                        2 5 4 12 */
+107,	/* OBJ_description                  2 5 4 13 */
+859,	/* OBJ_searchGuide                  2 5 4 14 */
+860,	/* OBJ_businessCategory             2 5 4 15 */
+861,	/* OBJ_postalAddress                2 5 4 16 */
+661,	/* OBJ_postalCode                   2 5 4 17 */
+862,	/* OBJ_postOfficeBox                2 5 4 18 */
+863,	/* OBJ_physicalDeliveryOfficeName   2 5 4 19 */
+864,	/* OBJ_telephoneNumber              2 5 4 20 */
+865,	/* OBJ_telexNumber                  2 5 4 21 */
+866,	/* OBJ_teletexTerminalIdentifier    2 5 4 22 */
+867,	/* OBJ_facsimileTelephoneNumber     2 5 4 23 */
+868,	/* OBJ_x121Address                  2 5 4 24 */
+869,	/* OBJ_internationaliSDNNumber      2 5 4 25 */
+870,	/* OBJ_registeredAddress            2 5 4 26 */
+871,	/* OBJ_destinationIndicator         2 5 4 27 */
+872,	/* OBJ_preferredDeliveryMethod      2 5 4 28 */
+873,	/* OBJ_presentationAddress          2 5 4 29 */
+874,	/* OBJ_supportedApplicationContext  2 5 4 30 */
+875,	/* OBJ_member                       2 5 4 31 */
+876,	/* OBJ_owner                        2 5 4 32 */
+877,	/* OBJ_roleOccupant                 2 5 4 33 */
+878,	/* OBJ_seeAlso                      2 5 4 34 */
+879,	/* OBJ_userPassword                 2 5 4 35 */
+880,	/* OBJ_userCertificate              2 5 4 36 */
+881,	/* OBJ_cACertificate                2 5 4 37 */
+882,	/* OBJ_authorityRevocationList      2 5 4 38 */
+883,	/* OBJ_certificateRevocationList    2 5 4 39 */
+884,	/* OBJ_crossCertificatePair         2 5 4 40 */
+173,	/* OBJ_name                         2 5 4 41 */
+99,	/* OBJ_givenName                    2 5 4 42 */
+101,	/* OBJ_initials                     2 5 4 43 */
+509,	/* OBJ_generationQualifier          2 5 4 44 */
+503,	/* OBJ_x500UniqueIdentifier         2 5 4 45 */
+174,	/* OBJ_dnQualifier                  2 5 4 46 */
+885,	/* OBJ_enhancedSearchGuide          2 5 4 47 */
+886,	/* OBJ_protocolInformation          2 5 4 48 */
+887,	/* OBJ_distinguishedName            2 5 4 49 */
+888,	/* OBJ_uniqueMember                 2 5 4 50 */
+889,	/* OBJ_houseIdentifier              2 5 4 51 */
+890,	/* OBJ_supportedAlgorithms          2 5 4 52 */
+891,	/* OBJ_deltaRevocationList          2 5 4 53 */
+892,	/* OBJ_dmdName                      2 5 4 54 */
+510,	/* OBJ_pseudonym                    2 5 4 65 */
+400,	/* OBJ_role                         2 5 4 72 */
+769,	/* OBJ_subject_directory_attributes 2 5 29 9 */
+82,	/* OBJ_subject_key_identifier       2 5 29 14 */
+83,	/* OBJ_key_usage                    2 5 29 15 */
+84,	/* OBJ_private_key_usage_period     2 5 29 16 */
+85,	/* OBJ_subject_alt_name             2 5 29 17 */
+86,	/* OBJ_issuer_alt_name              2 5 29 18 */
+87,	/* OBJ_basic_constraints            2 5 29 19 */
+88,	/* OBJ_crl_number                   2 5 29 20 */
+141,	/* OBJ_crl_reason                   2 5 29 21 */
+430,	/* OBJ_hold_instruction_code        2 5 29 23 */
+142,	/* OBJ_invalidity_date              2 5 29 24 */
+140,	/* OBJ_delta_crl                    2 5 29 27 */
+770,	/* OBJ_issuing_distribution_point   2 5 29 28 */
+771,	/* OBJ_certificate_issuer           2 5 29 29 */
+666,	/* OBJ_name_constraints             2 5 29 30 */
+103,	/* OBJ_crl_distribution_points      2 5 29 31 */
+89,	/* OBJ_certificate_policies         2 5 29 32 */
+747,	/* OBJ_policy_mappings              2 5 29 33 */
+90,	/* OBJ_authority_key_identifier     2 5 29 35 */
+401,	/* OBJ_policy_constraints           2 5 29 36 */
+126,	/* OBJ_ext_key_usage                2 5 29 37 */
+857,	/* OBJ_freshest_crl                 2 5 29 46 */
+748,	/* OBJ_inhibit_any_policy           2 5 29 54 */
+402,	/* OBJ_target_information           2 5 29 55 */
+403,	/* OBJ_no_rev_avail                 2 5 29 56 */
+513,	/* OBJ_set_ctype                    2 23 42 0 */
+514,	/* OBJ_set_msgExt                   2 23 42 1 */
+515,	/* OBJ_set_attr                     2 23 42 3 */
+516,	/* OBJ_set_policy                   2 23 42 5 */
+517,	/* OBJ_set_certExt                  2 23 42 7 */
+518,	/* OBJ_set_brand                    2 23 42 8 */
+679,	/* OBJ_wap_wsg                      2 23 43 1 */
+382,	/* OBJ_Directory                    1 3 6 1 1 */
+383,	/* OBJ_Management                   1 3 6 1 2 */
+384,	/* OBJ_Experimental                 1 3 6 1 3 */
+385,	/* OBJ_Private                      1 3 6 1 4 */
+386,	/* OBJ_Security                     1 3 6 1 5 */
+387,	/* OBJ_SNMPv2                       1 3 6 1 6 */
+388,	/* OBJ_Mail                         1 3 6 1 7 */
+376,	/* OBJ_algorithm                    1 3 14 3 2 */
+395,	/* OBJ_clearance                    2 5 1 5 55 */
+19,	/* OBJ_rsa                          2 5 8 1 1 */
+96,	/* OBJ_mdc2WithRSA                  2 5 8 3 100 */
+95,	/* OBJ_mdc2                         2 5 8 3 101 */
+746,	/* OBJ_any_policy                   2 5 29 32 0 */
+910,	/* OBJ_anyExtendedKeyUsage          2 5 29 37 0 */
+519,	/* OBJ_setct_PANData                2 23 42 0 0 */
+520,	/* OBJ_setct_PANToken               2 23 42 0 1 */
+521,	/* OBJ_setct_PANOnly                2 23 42 0 2 */
+522,	/* OBJ_setct_OIData                 2 23 42 0 3 */
+523,	/* OBJ_setct_PI                     2 23 42 0 4 */
+524,	/* OBJ_setct_PIData                 2 23 42 0 5 */
+525,	/* OBJ_setct_PIDataUnsigned         2 23 42 0 6 */
+526,	/* OBJ_setct_HODInput               2 23 42 0 7 */
+527,	/* OBJ_setct_AuthResBaggage         2 23 42 0 8 */
+528,	/* OBJ_setct_AuthRevReqBaggage      2 23 42 0 9 */
+529,	/* OBJ_setct_AuthRevResBaggage      2 23 42 0 10 */
+530,	/* OBJ_setct_CapTokenSeq            2 23 42 0 11 */
+531,	/* OBJ_setct_PInitResData           2 23 42 0 12 */
+532,	/* OBJ_setct_PI_TBS                 2 23 42 0 13 */
+533,	/* OBJ_setct_PResData               2 23 42 0 14 */
+534,	/* OBJ_setct_AuthReqTBS             2 23 42 0 16 */
+535,	/* OBJ_setct_AuthResTBS             2 23 42 0 17 */
+536,	/* OBJ_setct_AuthResTBSX            2 23 42 0 18 */
+537,	/* OBJ_setct_AuthTokenTBS           2 23 42 0 19 */
+538,	/* OBJ_setct_CapTokenData           2 23 42 0 20 */
+539,	/* OBJ_setct_CapTokenTBS            2 23 42 0 21 */
+540,	/* OBJ_setct_AcqCardCodeMsg         2 23 42 0 22 */
+541,	/* OBJ_setct_AuthRevReqTBS          2 23 42 0 23 */
+542,	/* OBJ_setct_AuthRevResData         2 23 42 0 24 */
+543,	/* OBJ_setct_AuthRevResTBS          2 23 42 0 25 */
+544,	/* OBJ_setct_CapReqTBS              2 23 42 0 26 */
+545,	/* OBJ_setct_CapReqTBSX             2 23 42 0 27 */
+546,	/* OBJ_setct_CapResData             2 23 42 0 28 */
+547,	/* OBJ_setct_CapRevReqTBS           2 23 42 0 29 */
+548,	/* OBJ_setct_CapRevReqTBSX          2 23 42 0 30 */
+549,	/* OBJ_setct_CapRevResData          2 23 42 0 31 */
+550,	/* OBJ_setct_CredReqTBS             2 23 42 0 32 */
+551,	/* OBJ_setct_CredReqTBSX            2 23 42 0 33 */
+552,	/* OBJ_setct_CredResData            2 23 42 0 34 */
+553,	/* OBJ_setct_CredRevReqTBS          2 23 42 0 35 */
+554,	/* OBJ_setct_CredRevReqTBSX         2 23 42 0 36 */
+555,	/* OBJ_setct_CredRevResData         2 23 42 0 37 */
+556,	/* OBJ_setct_PCertReqData           2 23 42 0 38 */
+557,	/* OBJ_setct_PCertResTBS            2 23 42 0 39 */
+558,	/* OBJ_setct_BatchAdminReqData      2 23 42 0 40 */
+559,	/* OBJ_setct_BatchAdminResData      2 23 42 0 41 */
+560,	/* OBJ_setct_CardCInitResTBS        2 23 42 0 42 */
+561,	/* OBJ_setct_MeAqCInitResTBS        2 23 42 0 43 */
+562,	/* OBJ_setct_RegFormResTBS          2 23 42 0 44 */
+563,	/* OBJ_setct_CertReqData            2 23 42 0 45 */
+564,	/* OBJ_setct_CertReqTBS             2 23 42 0 46 */
+565,	/* OBJ_setct_CertResData            2 23 42 0 47 */
+566,	/* OBJ_setct_CertInqReqTBS          2 23 42 0 48 */
+567,	/* OBJ_setct_ErrorTBS               2 23 42 0 49 */
+568,	/* OBJ_setct_PIDualSignedTBE        2 23 42 0 50 */
+569,	/* OBJ_setct_PIUnsignedTBE          2 23 42 0 51 */
+570,	/* OBJ_setct_AuthReqTBE             2 23 42 0 52 */
+571,	/* OBJ_setct_AuthResTBE             2 23 42 0 53 */
+572,	/* OBJ_setct_AuthResTBEX            2 23 42 0 54 */
+573,	/* OBJ_setct_AuthTokenTBE           2 23 42 0 55 */
+574,	/* OBJ_setct_CapTokenTBE            2 23 42 0 56 */
+575,	/* OBJ_setct_CapTokenTBEX           2 23 42 0 57 */
+576,	/* OBJ_setct_AcqCardCodeMsgTBE      2 23 42 0 58 */
+577,	/* OBJ_setct_AuthRevReqTBE          2 23 42 0 59 */
+578,	/* OBJ_setct_AuthRevResTBE          2 23 42 0 60 */
+579,	/* OBJ_setct_AuthRevResTBEB         2 23 42 0 61 */
+580,	/* OBJ_setct_CapReqTBE              2 23 42 0 62 */
+581,	/* OBJ_setct_CapReqTBEX             2 23 42 0 63 */
+582,	/* OBJ_setct_CapResTBE              2 23 42 0 64 */
+583,	/* OBJ_setct_CapRevReqTBE           2 23 42 0 65 */
+584,	/* OBJ_setct_CapRevReqTBEX          2 23 42 0 66 */
+585,	/* OBJ_setct_CapRevResTBE           2 23 42 0 67 */
+586,	/* OBJ_setct_CredReqTBE             2 23 42 0 68 */
+587,	/* OBJ_setct_CredReqTBEX            2 23 42 0 69 */
+588,	/* OBJ_setct_CredResTBE             2 23 42 0 70 */
+589,	/* OBJ_setct_CredRevReqTBE          2 23 42 0 71 */
+590,	/* OBJ_setct_CredRevReqTBEX         2 23 42 0 72 */
+591,	/* OBJ_setct_CredRevResTBE          2 23 42 0 73 */
+592,	/* OBJ_setct_BatchAdminReqTBE       2 23 42 0 74 */
+593,	/* OBJ_setct_BatchAdminResTBE       2 23 42 0 75 */
+594,	/* OBJ_setct_RegFormReqTBE          2 23 42 0 76 */
+595,	/* OBJ_setct_CertReqTBE             2 23 42 0 77 */
+596,	/* OBJ_setct_CertReqTBEX            2 23 42 0 78 */
+597,	/* OBJ_setct_CertResTBE             2 23 42 0 79 */
+598,	/* OBJ_setct_CRLNotificationTBS     2 23 42 0 80 */
+599,	/* OBJ_setct_CRLNotificationResTBS  2 23 42 0 81 */
+600,	/* OBJ_setct_BCIDistributionTBS     2 23 42 0 82 */
+601,	/* OBJ_setext_genCrypt              2 23 42 1 1 */
+602,	/* OBJ_setext_miAuth                2 23 42 1 3 */
+603,	/* OBJ_setext_pinSecure             2 23 42 1 4 */
+604,	/* OBJ_setext_pinAny                2 23 42 1 5 */
+605,	/* OBJ_setext_track2                2 23 42 1 7 */
+606,	/* OBJ_setext_cv                    2 23 42 1 8 */
+620,	/* OBJ_setAttr_Cert                 2 23 42 3 0 */
+621,	/* OBJ_setAttr_PGWYcap              2 23 42 3 1 */
+622,	/* OBJ_setAttr_TokenType            2 23 42 3 2 */
+623,	/* OBJ_setAttr_IssCap               2 23 42 3 3 */
+607,	/* OBJ_set_policy_root              2 23 42 5 0 */
+608,	/* OBJ_setCext_hashedRoot           2 23 42 7 0 */
+609,	/* OBJ_setCext_certType             2 23 42 7 1 */
+610,	/* OBJ_setCext_merchData            2 23 42 7 2 */
+611,	/* OBJ_setCext_cCertRequired        2 23 42 7 3 */
+612,	/* OBJ_setCext_tunneling            2 23 42 7 4 */
+613,	/* OBJ_setCext_setExt               2 23 42 7 5 */
+614,	/* OBJ_setCext_setQualf             2 23 42 7 6 */
+615,	/* OBJ_setCext_PGWYcapabilities     2 23 42 7 7 */
+616,	/* OBJ_setCext_TokenIdentifier      2 23 42 7 8 */
+617,	/* OBJ_setCext_Track2Data           2 23 42 7 9 */
+618,	/* OBJ_setCext_TokenType            2 23 42 7 10 */
+619,	/* OBJ_setCext_IssuerCapabilities   2 23 42 7 11 */
+636,	/* OBJ_set_brand_IATA_ATA           2 23 42 8 1 */
+640,	/* OBJ_set_brand_Visa               2 23 42 8 4 */
+641,	/* OBJ_set_brand_MasterCard         2 23 42 8 5 */
+637,	/* OBJ_set_brand_Diners             2 23 42 8 30 */
+638,	/* OBJ_set_brand_AmericanExpress    2 23 42 8 34 */
+639,	/* OBJ_set_brand_JCB                2 23 42 8 35 */
+805,	/* OBJ_cryptopro                    1 2 643 2 2 */
+806,	/* OBJ_cryptocom                    1 2 643 2 9 */
+940,	/* OBJ_tc26                         1 2 643 7 1 */
+184,	/* OBJ_X9_57                        1 2 840 10040 */
+405,	/* OBJ_ansi_X9_62                   1 2 840 10045 */
+389,	/* OBJ_Enterprises                  1 3 6 1 4 1 */
+504,	/* OBJ_mime_mhs                     1 3 6 1 7 1 */
+104,	/* OBJ_md5WithRSA                   1 3 14 3 2 3 */
+29,	/* OBJ_des_ecb                      1 3 14 3 2 6 */
+31,	/* OBJ_des_cbc                      1 3 14 3 2 7 */
+45,	/* OBJ_des_ofb64                    1 3 14 3 2 8 */
+30,	/* OBJ_des_cfb64                    1 3 14 3 2 9 */
+377,	/* OBJ_rsaSignature                 1 3 14 3 2 11 */
+67,	/* OBJ_dsa_2                        1 3 14 3 2 12 */
+66,	/* OBJ_dsaWithSHA                   1 3 14 3 2 13 */
+42,	/* OBJ_shaWithRSAEncryption         1 3 14 3 2 15 */
+32,	/* OBJ_des_ede_ecb                  1 3 14 3 2 17 */
+41,	/* OBJ_sha                          1 3 14 3 2 18 */
+64,	/* OBJ_sha1                         1 3 14 3 2 26 */
+70,	/* OBJ_dsaWithSHA1_2                1 3 14 3 2 27 */
+115,	/* OBJ_sha1WithRSA                  1 3 14 3 2 29 */
+117,	/* OBJ_ripemd160                    1 3 36 3 2 1 */
+143,	/* OBJ_sxnet                        1 3 101 1 4 1 */
+721,	/* OBJ_sect163k1                    1 3 132 0 1 */
+722,	/* OBJ_sect163r1                    1 3 132 0 2 */
+728,	/* OBJ_sect239k1                    1 3 132 0 3 */
+717,	/* OBJ_sect113r1                    1 3 132 0 4 */
+718,	/* OBJ_sect113r2                    1 3 132 0 5 */
+704,	/* OBJ_secp112r1                    1 3 132 0 6 */
+705,	/* OBJ_secp112r2                    1 3 132 0 7 */
+709,	/* OBJ_secp160r1                    1 3 132 0 8 */
+708,	/* OBJ_secp160k1                    1 3 132 0 9 */
+714,	/* OBJ_secp256k1                    1 3 132 0 10 */
+723,	/* OBJ_sect163r2                    1 3 132 0 15 */
+729,	/* OBJ_sect283k1                    1 3 132 0 16 */
+730,	/* OBJ_sect283r1                    1 3 132 0 17 */
+719,	/* OBJ_sect131r1                    1 3 132 0 22 */
+720,	/* OBJ_sect131r2                    1 3 132 0 23 */
+724,	/* OBJ_sect193r1                    1 3 132 0 24 */
+725,	/* OBJ_sect193r2                    1 3 132 0 25 */
+726,	/* OBJ_sect233k1                    1 3 132 0 26 */
+727,	/* OBJ_sect233r1                    1 3 132 0 27 */
+706,	/* OBJ_secp128r1                    1 3 132 0 28 */
+707,	/* OBJ_secp128r2                    1 3 132 0 29 */
+710,	/* OBJ_secp160r2                    1 3 132 0 30 */
+711,	/* OBJ_secp192k1                    1 3 132 0 31 */
+712,	/* OBJ_secp224k1                    1 3 132 0 32 */
+713,	/* OBJ_secp224r1                    1 3 132 0 33 */
+715,	/* OBJ_secp384r1                    1 3 132 0 34 */
+716,	/* OBJ_secp521r1                    1 3 132 0 35 */
+731,	/* OBJ_sect409k1                    1 3 132 0 36 */
+732,	/* OBJ_sect409r1                    1 3 132 0 37 */
+733,	/* OBJ_sect571k1                    1 3 132 0 38 */
+734,	/* OBJ_sect571r1                    1 3 132 0 39 */
+624,	/* OBJ_set_rootKeyThumb             2 23 42 3 0 0 */
+625,	/* OBJ_set_addPolicy                2 23 42 3 0 1 */
+626,	/* OBJ_setAttr_Token_EMV            2 23 42 3 2 1 */
+627,	/* OBJ_setAttr_Token_B0Prime        2 23 42 3 2 2 */
+628,	/* OBJ_setAttr_IssCap_CVM           2 23 42 3 3 3 */
+629,	/* OBJ_setAttr_IssCap_T2            2 23 42 3 3 4 */
+630,	/* OBJ_setAttr_IssCap_Sig           2 23 42 3 3 5 */
+642,	/* OBJ_set_brand_Novus              2 23 42 8 6011 */
+735,	/* OBJ_wap_wsg_idm_ecid_wtls1       2 23 43 1 4 1 */
+736,	/* OBJ_wap_wsg_idm_ecid_wtls3       2 23 43 1 4 3 */
+737,	/* OBJ_wap_wsg_idm_ecid_wtls4       2 23 43 1 4 4 */
+738,	/* OBJ_wap_wsg_idm_ecid_wtls5       2 23 43 1 4 5 */
+739,	/* OBJ_wap_wsg_idm_ecid_wtls6       2 23 43 1 4 6 */
+740,	/* OBJ_wap_wsg_idm_ecid_wtls7       2 23 43 1 4 7 */
+741,	/* OBJ_wap_wsg_idm_ecid_wtls8       2 23 43 1 4 8 */
+742,	/* OBJ_wap_wsg_idm_ecid_wtls9       2 23 43 1 4 9 */
+743,	/* OBJ_wap_wsg_idm_ecid_wtls10      2 23 43 1 4 10 */
+744,	/* OBJ_wap_wsg_idm_ecid_wtls11      2 23 43 1 4 11 */
+745,	/* OBJ_wap_wsg_idm_ecid_wtls12      2 23 43 1 4 12 */
+804,	/* OBJ_whirlpool                    1 0 10118 3 0 55 */
+124,	/* OBJ_rle_compression              1 1 1 1 666 1 */
+773,	/* OBJ_kisa                         1 2 410 200004 */
+807,	/* OBJ_id_GostR3411_94_with_GostR3410_2001 1 2 643 2 2 3 */
+808,	/* OBJ_id_GostR3411_94_with_GostR3410_94 1 2 643 2 2 4 */
+809,	/* OBJ_id_GostR3411_94              1 2 643 2 2 9 */
+810,	/* OBJ_id_HMACGostR3411_94          1 2 643 2 2 10 */
+811,	/* OBJ_id_GostR3410_2001            1 2 643 2 2 19 */
+812,	/* OBJ_id_GostR3410_94              1 2 643 2 2 20 */
+813,	/* OBJ_id_Gost28147_89              1 2 643 2 2 21 */
+815,	/* OBJ_id_Gost28147_89_MAC          1 2 643 2 2 22 */
+816,	/* OBJ_id_GostR3411_94_prf          1 2 643 2 2 23 */
+817,	/* OBJ_id_GostR3410_2001DH          1 2 643 2 2 98 */
+818,	/* OBJ_id_GostR3410_94DH            1 2 643 2 2 99 */
+ 1,	/* OBJ_rsadsi                       1 2 840 113549 */
+185,	/* OBJ_X9cm                         1 2 840 10040 4 */
+127,	/* OBJ_id_pkix                      1 3 6 1 5 5 7 */
+505,	/* OBJ_mime_mhs_headings            1 3 6 1 7 1 1 */
+506,	/* OBJ_mime_mhs_bodies              1 3 6 1 7 1 2 */
+119,	/* OBJ_ripemd160WithRSA             1 3 36 3 3 1 2 */
+631,	/* OBJ_setAttr_GenCryptgrm          2 23 42 3 3 3 1 */
+632,	/* OBJ_setAttr_T2Enc                2 23 42 3 3 4 1 */
+633,	/* OBJ_setAttr_T2cleartxt           2 23 42 3 3 4 2 */
+634,	/* OBJ_setAttr_TokICCsig            2 23 42 3 3 5 1 */
+635,	/* OBJ_setAttr_SecDevSig            2 23 42 3 3 5 2 */
+436,	/* OBJ_ucl                          0 9 2342 19200300 */
+820,	/* OBJ_id_Gost28147_89_None_KeyMeshing 1 2 643 2 2 14 0 */
+819,	/* OBJ_id_Gost28147_89_CryptoPro_KeyMeshing 1 2 643 2 2 14 1 */
+845,	/* OBJ_id_GostR3410_94_a            1 2 643 2 2 20 1 */
+846,	/* OBJ_id_GostR3410_94_aBis         1 2 643 2 2 20 2 */
+847,	/* OBJ_id_GostR3410_94_b            1 2 643 2 2 20 3 */
+848,	/* OBJ_id_GostR3410_94_bBis         1 2 643 2 2 20 4 */
+821,	/* OBJ_id_GostR3411_94_TestParamSet 1 2 643 2 2 30 0 */
+822,	/* OBJ_id_GostR3411_94_CryptoProParamSet 1 2 643 2 2 30 1 */
+823,	/* OBJ_id_Gost28147_89_TestParamSet 1 2 643 2 2 31 0 */
+824,	/* OBJ_id_Gost28147_89_CryptoPro_A_ParamSet 1 2 643 2 2 31 1 */
+825,	/* OBJ_id_Gost28147_89_CryptoPro_B_ParamSet 1 2 643 2 2 31 2 */
+826,	/* OBJ_id_Gost28147_89_CryptoPro_C_ParamSet 1 2 643 2 2 31 3 */
+827,	/* OBJ_id_Gost28147_89_CryptoPro_D_ParamSet 1 2 643 2 2 31 4 */
+828,	/* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 1 2 643 2 2 31 5 */
+829,	/* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 1 2 643 2 2 31 6 */
+830,	/* OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 1 2 643 2 2 31 7 */
+831,	/* OBJ_id_GostR3410_94_TestParamSet 1 2 643 2 2 32 0 */
+832,	/* OBJ_id_GostR3410_94_CryptoPro_A_ParamSet 1 2 643 2 2 32 2 */
+833,	/* OBJ_id_GostR3410_94_CryptoPro_B_ParamSet 1 2 643 2 2 32 3 */
+834,	/* OBJ_id_GostR3410_94_CryptoPro_C_ParamSet 1 2 643 2 2 32 4 */
+835,	/* OBJ_id_GostR3410_94_CryptoPro_D_ParamSet 1 2 643 2 2 32 5 */
+836,	/* OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet 1 2 643 2 2 33 1 */
+837,	/* OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet 1 2 643 2 2 33 2 */
+838,	/* OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet 1 2 643 2 2 33 3 */
+839,	/* OBJ_id_GostR3410_2001_TestParamSet 1 2 643 2 2 35 0 */
+840,	/* OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet 1 2 643 2 2 35 1 */
+841,	/* OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet 1 2 643 2 2 35 2 */
+842,	/* OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet 1 2 643 2 2 35 3 */
+843,	/* OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet 1 2 643 2 2 36 0 */
+844,	/* OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet 1 2 643 2 2 36 1 */
+ 2,	/* OBJ_pkcs                         1 2 840 113549 1 */
+431,	/* OBJ_hold_instruction_none        1 2 840 10040 2 1 */
+432,	/* OBJ_hold_instruction_call_issuer 1 2 840 10040 2 2 */
+433,	/* OBJ_hold_instruction_reject      1 2 840 10040 2 3 */
+116,	/* OBJ_dsa                          1 2 840 10040 4 1 */
+113,	/* OBJ_dsaWithSHA1                  1 2 840 10040 4 3 */
+406,	/* OBJ_X9_62_prime_field            1 2 840 10045 1 1 */
+407,	/* OBJ_X9_62_characteristic_two_field 1 2 840 10045 1 2 */
+408,	/* OBJ_X9_62_id_ecPublicKey         1 2 840 10045 2 1 */
+416,	/* OBJ_ecdsa_with_SHA1              1 2 840 10045 4 1 */
+791,	/* OBJ_ecdsa_with_Recommended       1 2 840 10045 4 2 */
+792,	/* OBJ_ecdsa_with_Specified         1 2 840 10045 4 3 */
+258,	/* OBJ_id_pkix_mod                  1 3 6 1 5 5 7 0 */
+175,	/* OBJ_id_pe                        1 3 6 1 5 5 7 1 */
+259,	/* OBJ_id_qt                        1 3 6 1 5 5 7 2 */
+128,	/* OBJ_id_kp                        1 3 6 1 5 5 7 3 */
+260,	/* OBJ_id_it                        1 3 6 1 5 5 7 4 */
+261,	/* OBJ_id_pkip                      1 3 6 1 5 5 7 5 */
+262,	/* OBJ_id_alg                       1 3 6 1 5 5 7 6 */
+263,	/* OBJ_id_cmc                       1 3 6 1 5 5 7 7 */
+264,	/* OBJ_id_on                        1 3 6 1 5 5 7 8 */
+265,	/* OBJ_id_pda                       1 3 6 1 5 5 7 9 */
+266,	/* OBJ_id_aca                       1 3 6 1 5 5 7 10 */
+267,	/* OBJ_id_qcs                       1 3 6 1 5 5 7 11 */
+268,	/* OBJ_id_cct                       1 3 6 1 5 5 7 12 */
+662,	/* OBJ_id_ppl                       1 3 6 1 5 5 7 21 */
+176,	/* OBJ_id_ad                        1 3 6 1 5 5 7 48 */
+507,	/* OBJ_id_hex_partial_message       1 3 6 1 7 1 1 1 */
+508,	/* OBJ_id_hex_multipart_message     1 3 6 1 7 1 1 2 */
+921,	/* OBJ_brainpool                    1 3 36 3 3 2 8 1 */
+57,	/* OBJ_netscape                     2 16 840 1 113730 */
+754,	/* OBJ_camellia_128_ecb             0 3 4401 5 3 1 9 1 */
+766,	/* OBJ_camellia_128_ofb128          0 3 4401 5 3 1 9 3 */
+757,	/* OBJ_camellia_128_cfb128          0 3 4401 5 3 1 9 4 */
+755,	/* OBJ_camellia_192_ecb             0 3 4401 5 3 1 9 21 */
+767,	/* OBJ_camellia_192_ofb128          0 3 4401 5 3 1 9 23 */
+758,	/* OBJ_camellia_192_cfb128          0 3 4401 5 3 1 9 24 */
+756,	/* OBJ_camellia_256_ecb             0 3 4401 5 3 1 9 41 */
+768,	/* OBJ_camellia_256_ofb128          0 3 4401 5 3 1 9 43 */
+759,	/* OBJ_camellia_256_cfb128          0 3 4401 5 3 1 9 44 */
+437,	/* OBJ_pilot                        0 9 2342 19200300 100 */
+776,	/* OBJ_seed_ecb                     1 2 410 200004 1 3 */
+777,	/* OBJ_seed_cbc                     1 2 410 200004 1 4 */
+779,	/* OBJ_seed_cfb128                  1 2 410 200004 1 5 */
+778,	/* OBJ_seed_ofb128                  1 2 410 200004 1 6 */
+852,	/* OBJ_id_GostR3411_94_with_GostR3410_94_cc 1 2 643 2 9 1 3 3 */
+853,	/* OBJ_id_GostR3411_94_with_GostR3410_2001_cc 1 2 643 2 9 1 3 4 */
+850,	/* OBJ_id_GostR3410_94_cc           1 2 643 2 9 1 5 3 */
+851,	/* OBJ_id_GostR3410_2001_cc         1 2 643 2 9 1 5 4 */
+849,	/* OBJ_id_Gost28147_89_cc           1 2 643 2 9 1 6 1 */
+854,	/* OBJ_id_GostR3410_2001_ParamSet_cc 1 2 643 2 9 1 8 1 */
+946,	/* OBJ_id_tc26_gost3410_2012_256    1 2 643 7 1 1 1 1 */
+947,	/* OBJ_id_tc26_gost3410_2012_512    1 2 643 7 1 1 1 2 */
+941,	/* OBJ_id_tc26_gost3411_2012_256    1 2 643 7 1 1 2 2 */
+942,	/* OBJ_id_tc26_gost3411_2012_512    1 2 643 7 1 1 2 3 */
+948,	/* OBJ_id_tc26_signwithdigest_gost3410_2012_256 1 2 643 7 1 1 3 2 */
+949,	/* OBJ_id_tc26_signwithdigest_gost3410_2012_512 1 2 643 7 1 1 3 3 */
+186,	/* OBJ_pkcs1                        1 2 840 113549 1 1 */
+27,	/* OBJ_pkcs3                        1 2 840 113549 1 3 */
+187,	/* OBJ_pkcs5                        1 2 840 113549 1 5 */
+20,	/* OBJ_pkcs7                        1 2 840 113549 1 7 */
+47,	/* OBJ_pkcs9                        1 2 840 113549 1 9 */
+ 3,	/* OBJ_md2                          1 2 840 113549 2 2 */
+257,	/* OBJ_md4                          1 2 840 113549 2 4 */
+ 4,	/* OBJ_md5                          1 2 840 113549 2 5 */
+797,	/* OBJ_hmacWithMD5                  1 2 840 113549 2 6 */
+163,	/* OBJ_hmacWithSHA1                 1 2 840 113549 2 7 */
+798,	/* OBJ_hmacWithSHA224               1 2 840 113549 2 8 */
+799,	/* OBJ_hmacWithSHA256               1 2 840 113549 2 9 */
+800,	/* OBJ_hmacWithSHA384               1 2 840 113549 2 10 */
+801,	/* OBJ_hmacWithSHA512               1 2 840 113549 2 11 */
+37,	/* OBJ_rc2_cbc                      1 2 840 113549 3 2 */
+ 5,	/* OBJ_rc4                          1 2 840 113549 3 4 */
+44,	/* OBJ_des_ede3_cbc                 1 2 840 113549 3 7 */
+120,	/* OBJ_rc5_cbc                      1 2 840 113549 3 8 */
+643,	/* OBJ_des_cdmf                     1 2 840 113549 3 10 */
+680,	/* OBJ_X9_62_id_characteristic_two_basis 1 2 840 10045 1 2 3 */
+684,	/* OBJ_X9_62_c2pnb163v1             1 2 840 10045 3 0 1 */
+685,	/* OBJ_X9_62_c2pnb163v2             1 2 840 10045 3 0 2 */
+686,	/* OBJ_X9_62_c2pnb163v3             1 2 840 10045 3 0 3 */
+687,	/* OBJ_X9_62_c2pnb176v1             1 2 840 10045 3 0 4 */
+688,	/* OBJ_X9_62_c2tnb191v1             1 2 840 10045 3 0 5 */
+689,	/* OBJ_X9_62_c2tnb191v2             1 2 840 10045 3 0 6 */
+690,	/* OBJ_X9_62_c2tnb191v3             1 2 840 10045 3 0 7 */
+691,	/* OBJ_X9_62_c2onb191v4             1 2 840 10045 3 0 8 */
+692,	/* OBJ_X9_62_c2onb191v5             1 2 840 10045 3 0 9 */
+693,	/* OBJ_X9_62_c2pnb208w1             1 2 840 10045 3 0 10 */
+694,	/* OBJ_X9_62_c2tnb239v1             1 2 840 10045 3 0 11 */
+695,	/* OBJ_X9_62_c2tnb239v2             1 2 840 10045 3 0 12 */
+696,	/* OBJ_X9_62_c2tnb239v3             1 2 840 10045 3 0 13 */
+697,	/* OBJ_X9_62_c2onb239v4             1 2 840 10045 3 0 14 */
+698,	/* OBJ_X9_62_c2onb239v5             1 2 840 10045 3 0 15 */
+699,	/* OBJ_X9_62_c2pnb272w1             1 2 840 10045 3 0 16 */
+700,	/* OBJ_X9_62_c2pnb304w1             1 2 840 10045 3 0 17 */
+701,	/* OBJ_X9_62_c2tnb359v1             1 2 840 10045 3 0 18 */
+702,	/* OBJ_X9_62_c2pnb368w1             1 2 840 10045 3 0 19 */
+703,	/* OBJ_X9_62_c2tnb431r1             1 2 840 10045 3 0 20 */
+409,	/* OBJ_X9_62_prime192v1             1 2 840 10045 3 1 1 */
+410,	/* OBJ_X9_62_prime192v2             1 2 840 10045 3 1 2 */
+411,	/* OBJ_X9_62_prime192v3             1 2 840 10045 3 1 3 */
+412,	/* OBJ_X9_62_prime239v1             1 2 840 10045 3 1 4 */
+413,	/* OBJ_X9_62_prime239v2             1 2 840 10045 3 1 5 */
+414,	/* OBJ_X9_62_prime239v3             1 2 840 10045 3 1 6 */
+415,	/* OBJ_X9_62_prime256v1             1 2 840 10045 3 1 7 */
+793,	/* OBJ_ecdsa_with_SHA224            1 2 840 10045 4 3 1 */
+794,	/* OBJ_ecdsa_with_SHA256            1 2 840 10045 4 3 2 */
+795,	/* OBJ_ecdsa_with_SHA384            1 2 840 10045 4 3 3 */
+796,	/* OBJ_ecdsa_with_SHA512            1 2 840 10045 4 3 4 */
+269,	/* OBJ_id_pkix1_explicit_88         1 3 6 1 5 5 7 0 1 */
+270,	/* OBJ_id_pkix1_implicit_88         1 3 6 1 5 5 7 0 2 */
+271,	/* OBJ_id_pkix1_explicit_93         1 3 6 1 5 5 7 0 3 */
+272,	/* OBJ_id_pkix1_implicit_93         1 3 6 1 5 5 7 0 4 */
+273,	/* OBJ_id_mod_crmf                  1 3 6 1 5 5 7 0 5 */
+274,	/* OBJ_id_mod_cmc                   1 3 6 1 5 5 7 0 6 */
+275,	/* OBJ_id_mod_kea_profile_88        1 3 6 1 5 5 7 0 7 */
+276,	/* OBJ_id_mod_kea_profile_93        1 3 6 1 5 5 7 0 8 */
+277,	/* OBJ_id_mod_cmp                   1 3 6 1 5 5 7 0 9 */
+278,	/* OBJ_id_mod_qualified_cert_88     1 3 6 1 5 5 7 0 10 */
+279,	/* OBJ_id_mod_qualified_cert_93     1 3 6 1 5 5 7 0 11 */
+280,	/* OBJ_id_mod_attribute_cert        1 3 6 1 5 5 7 0 12 */
+281,	/* OBJ_id_mod_timestamp_protocol    1 3 6 1 5 5 7 0 13 */
+282,	/* OBJ_id_mod_ocsp                  1 3 6 1 5 5 7 0 14 */
+283,	/* OBJ_id_mod_dvcs                  1 3 6 1 5 5 7 0 15 */
+284,	/* OBJ_id_mod_cmp2000               1 3 6 1 5 5 7 0 16 */
+177,	/* OBJ_info_access                  1 3 6 1 5 5 7 1 1 */
+285,	/* OBJ_biometricInfo                1 3 6 1 5 5 7 1 2 */
+286,	/* OBJ_qcStatements                 1 3 6 1 5 5 7 1 3 */
+287,	/* OBJ_ac_auditEntity               1 3 6 1 5 5 7 1 4 */
+288,	/* OBJ_ac_targeting                 1 3 6 1 5 5 7 1 5 */
+289,	/* OBJ_aaControls                   1 3 6 1 5 5 7 1 6 */
+290,	/* OBJ_sbgp_ipAddrBlock             1 3 6 1 5 5 7 1 7 */
+291,	/* OBJ_sbgp_autonomousSysNum        1 3 6 1 5 5 7 1 8 */
+292,	/* OBJ_sbgp_routerIdentifier        1 3 6 1 5 5 7 1 9 */
+397,	/* OBJ_ac_proxying                  1 3 6 1 5 5 7 1 10 */
+398,	/* OBJ_sinfo_access                 1 3 6 1 5 5 7 1 11 */
+663,	/* OBJ_proxyCertInfo                1 3 6 1 5 5 7 1 14 */
+164,	/* OBJ_id_qt_cps                    1 3 6 1 5 5 7 2 1 */
+165,	/* OBJ_id_qt_unotice                1 3 6 1 5 5 7 2 2 */
+293,	/* OBJ_textNotice                   1 3 6 1 5 5 7 2 3 */
+129,	/* OBJ_server_auth                  1 3 6 1 5 5 7 3 1 */
+130,	/* OBJ_client_auth                  1 3 6 1 5 5 7 3 2 */
+131,	/* OBJ_code_sign                    1 3 6 1 5 5 7 3 3 */
+132,	/* OBJ_email_protect                1 3 6 1 5 5 7 3 4 */
+294,	/* OBJ_ipsecEndSystem               1 3 6 1 5 5 7 3 5 */
+295,	/* OBJ_ipsecTunnel                  1 3 6 1 5 5 7 3 6 */
+296,	/* OBJ_ipsecUser                    1 3 6 1 5 5 7 3 7 */
+133,	/* OBJ_time_stamp                   1 3 6 1 5 5 7 3 8 */
+180,	/* OBJ_OCSP_sign                    1 3 6 1 5 5 7 3 9 */
+297,	/* OBJ_dvcs                         1 3 6 1 5 5 7 3 10 */
+298,	/* OBJ_id_it_caProtEncCert          1 3 6 1 5 5 7 4 1 */
+299,	/* OBJ_id_it_signKeyPairTypes       1 3 6 1 5 5 7 4 2 */
+300,	/* OBJ_id_it_encKeyPairTypes        1 3 6 1 5 5 7 4 3 */
+301,	/* OBJ_id_it_preferredSymmAlg       1 3 6 1 5 5 7 4 4 */
+302,	/* OBJ_id_it_caKeyUpdateInfo        1 3 6 1 5 5 7 4 5 */
+303,	/* OBJ_id_it_currentCRL             1 3 6 1 5 5 7 4 6 */
+304,	/* OBJ_id_it_unsupportedOIDs        1 3 6 1 5 5 7 4 7 */
+305,	/* OBJ_id_it_subscriptionRequest    1 3 6 1 5 5 7 4 8 */
+306,	/* OBJ_id_it_subscriptionResponse   1 3 6 1 5 5 7 4 9 */
+307,	/* OBJ_id_it_keyPairParamReq        1 3 6 1 5 5 7 4 10 */
+308,	/* OBJ_id_it_keyPairParamRep        1 3 6 1 5 5 7 4 11 */
+309,	/* OBJ_id_it_revPassphrase          1 3 6 1 5 5 7 4 12 */
+310,	/* OBJ_id_it_implicitConfirm        1 3 6 1 5 5 7 4 13 */
+311,	/* OBJ_id_it_confirmWaitTime        1 3 6 1 5 5 7 4 14 */
+312,	/* OBJ_id_it_origPKIMessage         1 3 6 1 5 5 7 4 15 */
+784,	/* OBJ_id_it_suppLangTags           1 3 6 1 5 5 7 4 16 */
+313,	/* OBJ_id_regCtrl                   1 3 6 1 5 5 7 5 1 */
+314,	/* OBJ_id_regInfo                   1 3 6 1 5 5 7 5 2 */
+323,	/* OBJ_id_alg_des40                 1 3 6 1 5 5 7 6 1 */
+324,	/* OBJ_id_alg_noSignature           1 3 6 1 5 5 7 6 2 */
+325,	/* OBJ_id_alg_dh_sig_hmac_sha1      1 3 6 1 5 5 7 6 3 */
+326,	/* OBJ_id_alg_dh_pop                1 3 6 1 5 5 7 6 4 */
+327,	/* OBJ_id_cmc_statusInfo            1 3 6 1 5 5 7 7 1 */
+328,	/* OBJ_id_cmc_identification        1 3 6 1 5 5 7 7 2 */
+329,	/* OBJ_id_cmc_identityProof         1 3 6 1 5 5 7 7 3 */
+330,	/* OBJ_id_cmc_dataReturn            1 3 6 1 5 5 7 7 4 */
+331,	/* OBJ_id_cmc_transactionId         1 3 6 1 5 5 7 7 5 */
+332,	/* OBJ_id_cmc_senderNonce           1 3 6 1 5 5 7 7 6 */
+333,	/* OBJ_id_cmc_recipientNonce        1 3 6 1 5 5 7 7 7 */
+334,	/* OBJ_id_cmc_addExtensions         1 3 6 1 5 5 7 7 8 */
+335,	/* OBJ_id_cmc_encryptedPOP          1 3 6 1 5 5 7 7 9 */
+336,	/* OBJ_id_cmc_decryptedPOP          1 3 6 1 5 5 7 7 10 */
+337,	/* OBJ_id_cmc_lraPOPWitness         1 3 6 1 5 5 7 7 11 */
+338,	/* OBJ_id_cmc_getCert               1 3 6 1 5 5 7 7 15 */
+339,	/* OBJ_id_cmc_getCRL                1 3 6 1 5 5 7 7 16 */
+340,	/* OBJ_id_cmc_revokeRequest         1 3 6 1 5 5 7 7 17 */
+341,	/* OBJ_id_cmc_regInfo               1 3 6 1 5 5 7 7 18 */
+342,	/* OBJ_id_cmc_responseInfo          1 3 6 1 5 5 7 7 19 */
+343,	/* OBJ_id_cmc_queryPending          1 3 6 1 5 5 7 7 21 */
+344,	/* OBJ_id_cmc_popLinkRandom         1 3 6 1 5 5 7 7 22 */
+345,	/* OBJ_id_cmc_popLinkWitness        1 3 6 1 5 5 7 7 23 */
+346,	/* OBJ_id_cmc_confirmCertAcceptance 1 3 6 1 5 5 7 7 24 */
+347,	/* OBJ_id_on_personalData           1 3 6 1 5 5 7 8 1 */
+858,	/* OBJ_id_on_permanentIdentifier    1 3 6 1 5 5 7 8 3 */
+348,	/* OBJ_id_pda_dateOfBirth           1 3 6 1 5 5 7 9 1 */
+349,	/* OBJ_id_pda_placeOfBirth          1 3 6 1 5 5 7 9 2 */
+351,	/* OBJ_id_pda_gender                1 3 6 1 5 5 7 9 3 */
+352,	/* OBJ_id_pda_countryOfCitizenship  1 3 6 1 5 5 7 9 4 */
+353,	/* OBJ_id_pda_countryOfResidence    1 3 6 1 5 5 7 9 5 */
+354,	/* OBJ_id_aca_authenticationInfo    1 3 6 1 5 5 7 10 1 */
+355,	/* OBJ_id_aca_accessIdentity        1 3 6 1 5 5 7 10 2 */
+356,	/* OBJ_id_aca_chargingIdentity      1 3 6 1 5 5 7 10 3 */
+357,	/* OBJ_id_aca_group                 1 3 6 1 5 5 7 10 4 */
+358,	/* OBJ_id_aca_role                  1 3 6 1 5 5 7 10 5 */
+399,	/* OBJ_id_aca_encAttrs              1 3 6 1 5 5 7 10 6 */
+359,	/* OBJ_id_qcs_pkixQCSyntax_v1       1 3 6 1 5 5 7 11 1 */
+360,	/* OBJ_id_cct_crs                   1 3 6 1 5 5 7 12 1 */
+361,	/* OBJ_id_cct_PKIData               1 3 6 1 5 5 7 12 2 */
+362,	/* OBJ_id_cct_PKIResponse           1 3 6 1 5 5 7 12 3 */
+664,	/* OBJ_id_ppl_anyLanguage           1 3 6 1 5 5 7 21 0 */
+665,	/* OBJ_id_ppl_inheritAll            1 3 6 1 5 5 7 21 1 */
+667,	/* OBJ_Independent                  1 3 6 1 5 5 7 21 2 */
+178,	/* OBJ_ad_OCSP                      1 3 6 1 5 5 7 48 1 */
+179,	/* OBJ_ad_ca_issuers                1 3 6 1 5 5 7 48 2 */
+363,	/* OBJ_ad_timeStamping              1 3 6 1 5 5 7 48 3 */
+364,	/* OBJ_ad_dvcs                      1 3 6 1 5 5 7 48 4 */
+785,	/* OBJ_caRepository                 1 3 6 1 5 5 7 48 5 */
+780,	/* OBJ_hmac_md5                     1 3 6 1 5 5 8 1 1 */
+781,	/* OBJ_hmac_sha1                    1 3 6 1 5 5 8 1 2 */
+58,	/* OBJ_netscape_cert_extension      2 16 840 1 113730 1 */
+59,	/* OBJ_netscape_data_type           2 16 840 1 113730 2 */
+438,	/* OBJ_pilotAttributeType           0 9 2342 19200300 100 1 */
+439,	/* OBJ_pilotAttributeSyntax         0 9 2342 19200300 100 3 */
+440,	/* OBJ_pilotObjectClass             0 9 2342 19200300 100 4 */
+441,	/* OBJ_pilotGroups                  0 9 2342 19200300 100 10 */
+943,	/* OBJ_id_tc26_gost_3410_2012_512_paramSetA 1 2 643 7 1 2 1 2 1 */
+944,	/* OBJ_id_tc26_gost_3410_2012_512_paramSetB 1 2 643 7 1 2 1 2 2 */
+945,	/* OBJ_id_tc26_gost_28147_param_Z   1 2 643 7 1 2 5 1 1 */
+108,	/* OBJ_cast5_cbc                    1 2 840 113533 7 66 10 */
+112,	/* OBJ_pbeWithMD5AndCast5_CBC       1 2 840 113533 7 66 12 */
+782,	/* OBJ_id_PasswordBasedMAC          1 2 840 113533 7 66 13 */
+783,	/* OBJ_id_DHBasedMac                1 2 840 113533 7 66 30 */
+ 6,	/* OBJ_rsaEncryption                1 2 840 113549 1 1 1 */
+ 7,	/* OBJ_md2WithRSAEncryption         1 2 840 113549 1 1 2 */
+396,	/* OBJ_md4WithRSAEncryption         1 2 840 113549 1 1 3 */
+ 8,	/* OBJ_md5WithRSAEncryption         1 2 840 113549 1 1 4 */
+65,	/* OBJ_sha1WithRSAEncryption        1 2 840 113549 1 1 5 */
+644,	/* OBJ_rsaOAEPEncryptionSET         1 2 840 113549 1 1 6 */
+919,	/* OBJ_rsaesOaep                    1 2 840 113549 1 1 7 */
+911,	/* OBJ_mgf1                         1 2 840 113549 1 1 8 */
+912,	/* OBJ_rsassaPss                    1 2 840 113549 1 1 10 */
+668,	/* OBJ_sha256WithRSAEncryption      1 2 840 113549 1 1 11 */
+669,	/* OBJ_sha384WithRSAEncryption      1 2 840 113549 1 1 12 */
+670,	/* OBJ_sha512WithRSAEncryption      1 2 840 113549 1 1 13 */
+671,	/* OBJ_sha224WithRSAEncryption      1 2 840 113549 1 1 14 */
+28,	/* OBJ_dhKeyAgreement               1 2 840 113549 1 3 1 */
+ 9,	/* OBJ_pbeWithMD2AndDES_CBC         1 2 840 113549 1 5 1 */
+10,	/* OBJ_pbeWithMD5AndDES_CBC         1 2 840 113549 1 5 3 */
+168,	/* OBJ_pbeWithMD2AndRC2_CBC         1 2 840 113549 1 5 4 */
+169,	/* OBJ_pbeWithMD5AndRC2_CBC         1 2 840 113549 1 5 6 */
+170,	/* OBJ_pbeWithSHA1AndDES_CBC        1 2 840 113549 1 5 10 */
+68,	/* OBJ_pbeWithSHA1AndRC2_CBC        1 2 840 113549 1 5 11 */
+69,	/* OBJ_id_pbkdf2                    1 2 840 113549 1 5 12 */
+161,	/* OBJ_pbes2                        1 2 840 113549 1 5 13 */
+162,	/* OBJ_pbmac1                       1 2 840 113549 1 5 14 */
+21,	/* OBJ_pkcs7_data                   1 2 840 113549 1 7 1 */
+22,	/* OBJ_pkcs7_signed                 1 2 840 113549 1 7 2 */
+23,	/* OBJ_pkcs7_enveloped              1 2 840 113549 1 7 3 */
+24,	/* OBJ_pkcs7_signedAndEnveloped     1 2 840 113549 1 7 4 */
+25,	/* OBJ_pkcs7_digest                 1 2 840 113549 1 7 5 */
+26,	/* OBJ_pkcs7_encrypted              1 2 840 113549 1 7 6 */
+48,	/* OBJ_pkcs9_emailAddress           1 2 840 113549 1 9 1 */
+49,	/* OBJ_pkcs9_unstructuredName       1 2 840 113549 1 9 2 */
+50,	/* OBJ_pkcs9_contentType            1 2 840 113549 1 9 3 */
+51,	/* OBJ_pkcs9_messageDigest          1 2 840 113549 1 9 4 */
+52,	/* OBJ_pkcs9_signingTime            1 2 840 113549 1 9 5 */
+53,	/* OBJ_pkcs9_countersignature       1 2 840 113549 1 9 6 */
+54,	/* OBJ_pkcs9_challengePassword      1 2 840 113549 1 9 7 */
+55,	/* OBJ_pkcs9_unstructuredAddress    1 2 840 113549 1 9 8 */
+56,	/* OBJ_pkcs9_extCertAttributes      1 2 840 113549 1 9 9 */
+172,	/* OBJ_ext_req                      1 2 840 113549 1 9 14 */
+167,	/* OBJ_SMIMECapabilities            1 2 840 113549 1 9 15 */
+188,	/* OBJ_SMIME                        1 2 840 113549 1 9 16 */
+156,	/* OBJ_friendlyName                 1 2 840 113549 1 9 20 */
+157,	/* OBJ_localKeyID                   1 2 840 113549 1 9 21 */
+681,	/* OBJ_X9_62_onBasis                1 2 840 10045 1 2 3 1 */
+682,	/* OBJ_X9_62_tpBasis                1 2 840 10045 1 2 3 2 */
+683,	/* OBJ_X9_62_ppBasis                1 2 840 10045 1 2 3 3 */
+417,	/* OBJ_ms_csp_name                  1 3 6 1 4 1 311 17 1 */
+856,	/* OBJ_LocalKeySet                  1 3 6 1 4 1 311 17 2 */
+390,	/* OBJ_dcObject                     1 3 6 1 4 1 1466 344 */
+91,	/* OBJ_bf_cbc                       1 3 6 1 4 1 3029 1 2 */
+315,	/* OBJ_id_regCtrl_regToken          1 3 6 1 5 5 7 5 1 1 */
+316,	/* OBJ_id_regCtrl_authenticator     1 3 6 1 5 5 7 5 1 2 */
+317,	/* OBJ_id_regCtrl_pkiPublicationInfo 1 3 6 1 5 5 7 5 1 3 */
+318,	/* OBJ_id_regCtrl_pkiArchiveOptions 1 3 6 1 5 5 7 5 1 4 */
+319,	/* OBJ_id_regCtrl_oldCertID         1 3 6 1 5 5 7 5 1 5 */
+320,	/* OBJ_id_regCtrl_protocolEncrKey   1 3 6 1 5 5 7 5 1 6 */
+321,	/* OBJ_id_regInfo_utf8Pairs         1 3 6 1 5 5 7 5 2 1 */
+322,	/* OBJ_id_regInfo_certReq           1 3 6 1 5 5 7 5 2 2 */
+365,	/* OBJ_id_pkix_OCSP_basic           1 3 6 1 5 5 7 48 1 1 */
+366,	/* OBJ_id_pkix_OCSP_Nonce           1 3 6 1 5 5 7 48 1 2 */
+367,	/* OBJ_id_pkix_OCSP_CrlID           1 3 6 1 5 5 7 48 1 3 */
+368,	/* OBJ_id_pkix_OCSP_acceptableResponses 1 3 6 1 5 5 7 48 1 4 */
+369,	/* OBJ_id_pkix_OCSP_noCheck         1 3 6 1 5 5 7 48 1 5 */
+370,	/* OBJ_id_pkix_OCSP_archiveCutoff   1 3 6 1 5 5 7 48 1 6 */
+371,	/* OBJ_id_pkix_OCSP_serviceLocator  1 3 6 1 5 5 7 48 1 7 */
+372,	/* OBJ_id_pkix_OCSP_extendedStatus  1 3 6 1 5 5 7 48 1 8 */
+373,	/* OBJ_id_pkix_OCSP_valid           1 3 6 1 5 5 7 48 1 9 */
+374,	/* OBJ_id_pkix_OCSP_path            1 3 6 1 5 5 7 48 1 10 */
+375,	/* OBJ_id_pkix_OCSP_trustRoot       1 3 6 1 5 5 7 48 1 11 */
+922,	/* OBJ_brainpoolP160r1              1 3 36 3 3 2 8 1 1 1 */
+923,	/* OBJ_brainpoolP160t1              1 3 36 3 3 2 8 1 1 2 */
+924,	/* OBJ_brainpoolP192r1              1 3 36 3 3 2 8 1 1 3 */
+925,	/* OBJ_brainpoolP192t1              1 3 36 3 3 2 8 1 1 4 */
+926,	/* OBJ_brainpoolP224r1              1 3 36 3 3 2 8 1 1 5 */
+927,	/* OBJ_brainpoolP224t1              1 3 36 3 3 2 8 1 1 6 */
+928,	/* OBJ_brainpoolP256r1              1 3 36 3 3 2 8 1 1 7 */
+929,	/* OBJ_brainpoolP256t1              1 3 36 3 3 2 8 1 1 8 */
+930,	/* OBJ_brainpoolP320r1              1 3 36 3 3 2 8 1 1 9 */
+931,	/* OBJ_brainpoolP320t1              1 3 36 3 3 2 8 1 1 10 */
+932,	/* OBJ_brainpoolP384r1              1 3 36 3 3 2 8 1 1 11 */
+933,	/* OBJ_brainpoolP384t1              1 3 36 3 3 2 8 1 1 12 */
+934,	/* OBJ_brainpoolP512r1              1 3 36 3 3 2 8 1 1 13 */
+935,	/* OBJ_brainpoolP512t1              1 3 36 3 3 2 8 1 1 14 */
+418,	/* OBJ_aes_128_ecb                  2 16 840 1 101 3 4 1 1 */
+419,	/* OBJ_aes_128_cbc                  2 16 840 1 101 3 4 1 2 */
+420,	/* OBJ_aes_128_ofb128               2 16 840 1 101 3 4 1 3 */
+421,	/* OBJ_aes_128_cfb128               2 16 840 1 101 3 4 1 4 */
+788,	/* OBJ_id_aes128_wrap               2 16 840 1 101 3 4 1 5 */
+895,	/* OBJ_aes_128_gcm                  2 16 840 1 101 3 4 1 6 */
+896,	/* OBJ_aes_128_ccm                  2 16 840 1 101 3 4 1 7 */
+897,	/* OBJ_id_aes128_wrap_pad           2 16 840 1 101 3 4 1 8 */
+422,	/* OBJ_aes_192_ecb                  2 16 840 1 101 3 4 1 21 */
+423,	/* OBJ_aes_192_cbc                  2 16 840 1 101 3 4 1 22 */
+424,	/* OBJ_aes_192_ofb128               2 16 840 1 101 3 4 1 23 */
+425,	/* OBJ_aes_192_cfb128               2 16 840 1 101 3 4 1 24 */
+789,	/* OBJ_id_aes192_wrap               2 16 840 1 101 3 4 1 25 */
+898,	/* OBJ_aes_192_gcm                  2 16 840 1 101 3 4 1 26 */
+899,	/* OBJ_aes_192_ccm                  2 16 840 1 101 3 4 1 27 */
+900,	/* OBJ_id_aes192_wrap_pad           2 16 840 1 101 3 4 1 28 */
+426,	/* OBJ_aes_256_ecb                  2 16 840 1 101 3 4 1 41 */
+427,	/* OBJ_aes_256_cbc                  2 16 840 1 101 3 4 1 42 */
+428,	/* OBJ_aes_256_ofb128               2 16 840 1 101 3 4 1 43 */
+429,	/* OBJ_aes_256_cfb128               2 16 840 1 101 3 4 1 44 */
+790,	/* OBJ_id_aes256_wrap               2 16 840 1 101 3 4 1 45 */
+901,	/* OBJ_aes_256_gcm                  2 16 840 1 101 3 4 1 46 */
+902,	/* OBJ_aes_256_ccm                  2 16 840 1 101 3 4 1 47 */
+903,	/* OBJ_id_aes256_wrap_pad           2 16 840 1 101 3 4 1 48 */
+672,	/* OBJ_sha256                       2 16 840 1 101 3 4 2 1 */
+673,	/* OBJ_sha384                       2 16 840 1 101 3 4 2 2 */
+674,	/* OBJ_sha512                       2 16 840 1 101 3 4 2 3 */
+675,	/* OBJ_sha224                       2 16 840 1 101 3 4 2 4 */
+802,	/* OBJ_dsa_with_SHA224              2 16 840 1 101 3 4 3 1 */
+803,	/* OBJ_dsa_with_SHA256              2 16 840 1 101 3 4 3 2 */
+71,	/* OBJ_netscape_cert_type           2 16 840 1 113730 1 1 */
+72,	/* OBJ_netscape_base_url            2 16 840 1 113730 1 2 */
+73,	/* OBJ_netscape_revocation_url      2 16 840 1 113730 1 3 */
+74,	/* OBJ_netscape_ca_revocation_url   2 16 840 1 113730 1 4 */
+75,	/* OBJ_netscape_renewal_url         2 16 840 1 113730 1 7 */
+76,	/* OBJ_netscape_ca_policy_url       2 16 840 1 113730 1 8 */
+77,	/* OBJ_netscape_ssl_server_name     2 16 840 1 113730 1 12 */
+78,	/* OBJ_netscape_comment             2 16 840 1 113730 1 13 */
+79,	/* OBJ_netscape_cert_sequence       2 16 840 1 113730 2 5 */
+139,	/* OBJ_ns_sgc                       2 16 840 1 113730 4 1 */
+458,	/* OBJ_userId                       0 9 2342 19200300 100 1 1 */
+459,	/* OBJ_textEncodedORAddress         0 9 2342 19200300 100 1 2 */
+460,	/* OBJ_rfc822Mailbox                0 9 2342 19200300 100 1 3 */
+461,	/* OBJ_info                         0 9 2342 19200300 100 1 4 */
+462,	/* OBJ_favouriteDrink               0 9 2342 19200300 100 1 5 */
+463,	/* OBJ_roomNumber                   0 9 2342 19200300 100 1 6 */
+464,	/* OBJ_photo                        0 9 2342 19200300 100 1 7 */
+465,	/* OBJ_userClass                    0 9 2342 19200300 100 1 8 */
+466,	/* OBJ_host                         0 9 2342 19200300 100 1 9 */
+467,	/* OBJ_manager                      0 9 2342 19200300 100 1 10 */
+468,	/* OBJ_documentIdentifier           0 9 2342 19200300 100 1 11 */
+469,	/* OBJ_documentTitle                0 9 2342 19200300 100 1 12 */
+470,	/* OBJ_documentVersion              0 9 2342 19200300 100 1 13 */
+471,	/* OBJ_documentAuthor               0 9 2342 19200300 100 1 14 */
+472,	/* OBJ_documentLocation             0 9 2342 19200300 100 1 15 */
+473,	/* OBJ_homeTelephoneNumber          0 9 2342 19200300 100 1 20 */
+474,	/* OBJ_secretary                    0 9 2342 19200300 100 1 21 */
+475,	/* OBJ_otherMailbox                 0 9 2342 19200300 100 1 22 */
+476,	/* OBJ_lastModifiedTime             0 9 2342 19200300 100 1 23 */
+477,	/* OBJ_lastModifiedBy               0 9 2342 19200300 100 1 24 */
+391,	/* OBJ_domainComponent              0 9 2342 19200300 100 1 25 */
+478,	/* OBJ_aRecord                      0 9 2342 19200300 100 1 26 */
+479,	/* OBJ_pilotAttributeType27         0 9 2342 19200300 100 1 27 */
+480,	/* OBJ_mXRecord                     0 9 2342 19200300 100 1 28 */
+481,	/* OBJ_nSRecord                     0 9 2342 19200300 100 1 29 */
+482,	/* OBJ_sOARecord                    0 9 2342 19200300 100 1 30 */
+483,	/* OBJ_cNAMERecord                  0 9 2342 19200300 100 1 31 */
+484,	/* OBJ_associatedDomain             0 9 2342 19200300 100 1 37 */
+485,	/* OBJ_associatedName               0 9 2342 19200300 100 1 38 */
+486,	/* OBJ_homePostalAddress            0 9 2342 19200300 100 1 39 */
+487,	/* OBJ_personalTitle                0 9 2342 19200300 100 1 40 */
+488,	/* OBJ_mobileTelephoneNumber        0 9 2342 19200300 100 1 41 */
+489,	/* OBJ_pagerTelephoneNumber         0 9 2342 19200300 100 1 42 */
+490,	/* OBJ_friendlyCountryName          0 9 2342 19200300 100 1 43 */
+491,	/* OBJ_organizationalStatus         0 9 2342 19200300 100 1 45 */
+492,	/* OBJ_janetMailbox                 0 9 2342 19200300 100 1 46 */
+493,	/* OBJ_mailPreferenceOption         0 9 2342 19200300 100 1 47 */
+494,	/* OBJ_buildingName                 0 9 2342 19200300 100 1 48 */
+495,	/* OBJ_dSAQuality                   0 9 2342 19200300 100 1 49 */
+496,	/* OBJ_singleLevelQuality           0 9 2342 19200300 100 1 50 */
+497,	/* OBJ_subtreeMinimumQuality        0 9 2342 19200300 100 1 51 */
+498,	/* OBJ_subtreeMaximumQuality        0 9 2342 19200300 100 1 52 */
+499,	/* OBJ_personalSignature            0 9 2342 19200300 100 1 53 */
+500,	/* OBJ_dITRedirect                  0 9 2342 19200300 100 1 54 */
+501,	/* OBJ_audio                        0 9 2342 19200300 100 1 55 */
+502,	/* OBJ_documentPublisher            0 9 2342 19200300 100 1 56 */
+442,	/* OBJ_iA5StringSyntax              0 9 2342 19200300 100 3 4 */
+443,	/* OBJ_caseIgnoreIA5StringSyntax    0 9 2342 19200300 100 3 5 */
+444,	/* OBJ_pilotObject                  0 9 2342 19200300 100 4 3 */
+445,	/* OBJ_pilotPerson                  0 9 2342 19200300 100 4 4 */
+446,	/* OBJ_account                      0 9 2342 19200300 100 4 5 */
+447,	/* OBJ_document                     0 9 2342 19200300 100 4 6 */
+448,	/* OBJ_room                         0 9 2342 19200300 100 4 7 */
+449,	/* OBJ_documentSeries               0 9 2342 19200300 100 4 9 */
+392,	/* OBJ_Domain                       0 9 2342 19200300 100 4 13 */
+450,	/* OBJ_rFC822localPart              0 9 2342 19200300 100 4 14 */
+451,	/* OBJ_dNSDomain                    0 9 2342 19200300 100 4 15 */
+452,	/* OBJ_domainRelatedObject          0 9 2342 19200300 100 4 17 */
+453,	/* OBJ_friendlyCountry              0 9 2342 19200300 100 4 18 */
+454,	/* OBJ_simpleSecurityObject         0 9 2342 19200300 100 4 19 */
+455,	/* OBJ_pilotOrganization            0 9 2342 19200300 100 4 20 */
+456,	/* OBJ_pilotDSA                     0 9 2342 19200300 100 4 21 */
+457,	/* OBJ_qualityLabelledData          0 9 2342 19200300 100 4 22 */
+936,	/* OBJ_FRP256v1                     1 2 250 1 223 101 256 1 */
+189,	/* OBJ_id_smime_mod                 1 2 840 113549 1 9 16 0 */
+190,	/* OBJ_id_smime_ct                  1 2 840 113549 1 9 16 1 */
+191,	/* OBJ_id_smime_aa                  1 2 840 113549 1 9 16 2 */
+192,	/* OBJ_id_smime_alg                 1 2 840 113549 1 9 16 3 */
+193,	/* OBJ_id_smime_cd                  1 2 840 113549 1 9 16 4 */
+194,	/* OBJ_id_smime_spq                 1 2 840 113549 1 9 16 5 */
+195,	/* OBJ_id_smime_cti                 1 2 840 113549 1 9 16 6 */
+158,	/* OBJ_x509Certificate              1 2 840 113549 1 9 22 1 */
+159,	/* OBJ_sdsiCertificate              1 2 840 113549 1 9 22 2 */
+160,	/* OBJ_x509Crl                      1 2 840 113549 1 9 23 1 */
+144,	/* OBJ_pbe_WithSHA1And128BitRC4     1 2 840 113549 1 12 1 1 */
+145,	/* OBJ_pbe_WithSHA1And40BitRC4      1 2 840 113549 1 12 1 2 */
+146,	/* OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC 1 2 840 113549 1 12 1 3 */
+147,	/* OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC 1 2 840 113549 1 12 1 4 */
+148,	/* OBJ_pbe_WithSHA1And128BitRC2_CBC 1 2 840 113549 1 12 1 5 */
+149,	/* OBJ_pbe_WithSHA1And40BitRC2_CBC  1 2 840 113549 1 12 1 6 */
+171,	/* OBJ_ms_ext_req                   1 3 6 1 4 1 311 2 1 14 */
+134,	/* OBJ_ms_code_ind                  1 3 6 1 4 1 311 2 1 21 */
+135,	/* OBJ_ms_code_com                  1 3 6 1 4 1 311 2 1 22 */
+136,	/* OBJ_ms_ctl_sign                  1 3 6 1 4 1 311 10 3 1 */
+137,	/* OBJ_ms_sgc                       1 3 6 1 4 1 311 10 3 3 */
+138,	/* OBJ_ms_efs                       1 3 6 1 4 1 311 10 3 4 */
+648,	/* OBJ_ms_smartcard_login           1 3 6 1 4 1 311 20 2 2 */
+649,	/* OBJ_ms_upn                       1 3 6 1 4 1 311 20 2 3 */
+751,	/* OBJ_camellia_128_cbc             1 2 392 200011 61 1 1 1 2 */
+752,	/* OBJ_camellia_192_cbc             1 2 392 200011 61 1 1 1 3 */
+753,	/* OBJ_camellia_256_cbc             1 2 392 200011 61 1 1 1 4 */
+907,	/* OBJ_id_camellia128_wrap          1 2 392 200011 61 1 1 3 2 */
+908,	/* OBJ_id_camellia192_wrap          1 2 392 200011 61 1 1 3 3 */
+909,	/* OBJ_id_camellia256_wrap          1 2 392 200011 61 1 1 3 4 */
+196,	/* OBJ_id_smime_mod_cms             1 2 840 113549 1 9 16 0 1 */
+197,	/* OBJ_id_smime_mod_ess             1 2 840 113549 1 9 16 0 2 */
+198,	/* OBJ_id_smime_mod_oid             1 2 840 113549 1 9 16 0 3 */
+199,	/* OBJ_id_smime_mod_msg_v3          1 2 840 113549 1 9 16 0 4 */
+200,	/* OBJ_id_smime_mod_ets_eSignature_88 1 2 840 113549 1 9 16 0 5 */
+201,	/* OBJ_id_smime_mod_ets_eSignature_97 1 2 840 113549 1 9 16 0 6 */
+202,	/* OBJ_id_smime_mod_ets_eSigPolicy_88 1 2 840 113549 1 9 16 0 7 */
+203,	/* OBJ_id_smime_mod_ets_eSigPolicy_97 1 2 840 113549 1 9 16 0 8 */
+204,	/* OBJ_id_smime_ct_receipt          1 2 840 113549 1 9 16 1 1 */
+205,	/* OBJ_id_smime_ct_authData         1 2 840 113549 1 9 16 1 2 */
+206,	/* OBJ_id_smime_ct_publishCert      1 2 840 113549 1 9 16 1 3 */
+207,	/* OBJ_id_smime_ct_TSTInfo          1 2 840 113549 1 9 16 1 4 */
+208,	/* OBJ_id_smime_ct_TDTInfo          1 2 840 113549 1 9 16 1 5 */
+209,	/* OBJ_id_smime_ct_contentInfo      1 2 840 113549 1 9 16 1 6 */
+210,	/* OBJ_id_smime_ct_DVCSRequestData  1 2 840 113549 1 9 16 1 7 */
+211,	/* OBJ_id_smime_ct_DVCSResponseData 1 2 840 113549 1 9 16 1 8 */
+786,	/* OBJ_id_smime_ct_compressedData   1 2 840 113549 1 9 16 1 9 */
+787,	/* OBJ_id_ct_asciiTextWithCRLF      1 2 840 113549 1 9 16 1 27 */
+212,	/* OBJ_id_smime_aa_receiptRequest   1 2 840 113549 1 9 16 2 1 */
+213,	/* OBJ_id_smime_aa_securityLabel    1 2 840 113549 1 9 16 2 2 */
+214,	/* OBJ_id_smime_aa_mlExpandHistory  1 2 840 113549 1 9 16 2 3 */
+215,	/* OBJ_id_smime_aa_contentHint      1 2 840 113549 1 9 16 2 4 */
+216,	/* OBJ_id_smime_aa_msgSigDigest     1 2 840 113549 1 9 16 2 5 */
+217,	/* OBJ_id_smime_aa_encapContentType 1 2 840 113549 1 9 16 2 6 */
+218,	/* OBJ_id_smime_aa_contentIdentifier 1 2 840 113549 1 9 16 2 7 */
+219,	/* OBJ_id_smime_aa_macValue         1 2 840 113549 1 9 16 2 8 */
+220,	/* OBJ_id_smime_aa_equivalentLabels 1 2 840 113549 1 9 16 2 9 */
+221,	/* OBJ_id_smime_aa_contentReference 1 2 840 113549 1 9 16 2 10 */
+222,	/* OBJ_id_smime_aa_encrypKeyPref    1 2 840 113549 1 9 16 2 11 */
+223,	/* OBJ_id_smime_aa_signingCertificate 1 2 840 113549 1 9 16 2 12 */
+224,	/* OBJ_id_smime_aa_smimeEncryptCerts 1 2 840 113549 1 9 16 2 13 */
+225,	/* OBJ_id_smime_aa_timeStampToken   1 2 840 113549 1 9 16 2 14 */
+226,	/* OBJ_id_smime_aa_ets_sigPolicyId  1 2 840 113549 1 9 16 2 15 */
+227,	/* OBJ_id_smime_aa_ets_commitmentType 1 2 840 113549 1 9 16 2 16 */
+228,	/* OBJ_id_smime_aa_ets_signerLocation 1 2 840 113549 1 9 16 2 17 */
+229,	/* OBJ_id_smime_aa_ets_signerAttr   1 2 840 113549 1 9 16 2 18 */
+230,	/* OBJ_id_smime_aa_ets_otherSigCert 1 2 840 113549 1 9 16 2 19 */
+231,	/* OBJ_id_smime_aa_ets_contentTimestamp 1 2 840 113549 1 9 16 2 20 */
+232,	/* OBJ_id_smime_aa_ets_CertificateRefs 1 2 840 113549 1 9 16 2 21 */
+233,	/* OBJ_id_smime_aa_ets_RevocationRefs 1 2 840 113549 1 9 16 2 22 */
+234,	/* OBJ_id_smime_aa_ets_certValues   1 2 840 113549 1 9 16 2 23 */
+235,	/* OBJ_id_smime_aa_ets_revocationValues 1 2 840 113549 1 9 16 2 24 */
+236,	/* OBJ_id_smime_aa_ets_escTimeStamp 1 2 840 113549 1 9 16 2 25 */
+237,	/* OBJ_id_smime_aa_ets_certCRLTimestamp 1 2 840 113549 1 9 16 2 26 */
+238,	/* OBJ_id_smime_aa_ets_archiveTimeStamp 1 2 840 113549 1 9 16 2 27 */
+239,	/* OBJ_id_smime_aa_signatureType    1 2 840 113549 1 9 16 2 28 */
+240,	/* OBJ_id_smime_aa_dvcs_dvc         1 2 840 113549 1 9 16 2 29 */
+241,	/* OBJ_id_smime_alg_ESDHwith3DES    1 2 840 113549 1 9 16 3 1 */
+242,	/* OBJ_id_smime_alg_ESDHwithRC2     1 2 840 113549 1 9 16 3 2 */
+243,	/* OBJ_id_smime_alg_3DESwrap        1 2 840 113549 1 9 16 3 3 */
+244,	/* OBJ_id_smime_alg_RC2wrap         1 2 840 113549 1 9 16 3 4 */
+245,	/* OBJ_id_smime_alg_ESDH            1 2 840 113549 1 9 16 3 5 */
+246,	/* OBJ_id_smime_alg_CMS3DESwrap     1 2 840 113549 1 9 16 3 6 */
+247,	/* OBJ_id_smime_alg_CMSRC2wrap      1 2 840 113549 1 9 16 3 7 */
+125,	/* OBJ_zlib_compression             1 2 840 113549 1 9 16 3 8 */
+893,	/* OBJ_id_alg_PWRI_KEK              1 2 840 113549 1 9 16 3 9 */
+248,	/* OBJ_id_smime_cd_ldap             1 2 840 113549 1 9 16 4 1 */
+249,	/* OBJ_id_smime_spq_ets_sqt_uri     1 2 840 113549 1 9 16 5 1 */
+250,	/* OBJ_id_smime_spq_ets_sqt_unotice 1 2 840 113549 1 9 16 5 2 */
+251,	/* OBJ_id_smime_cti_ets_proofOfOrigin 1 2 840 113549 1 9 16 6 1 */
+252,	/* OBJ_id_smime_cti_ets_proofOfReceipt 1 2 840 113549 1 9 16 6 2 */
+253,	/* OBJ_id_smime_cti_ets_proofOfDelivery 1 2 840 113549 1 9 16 6 3 */
+254,	/* OBJ_id_smime_cti_ets_proofOfSender 1 2 840 113549 1 9 16 6 4 */
+255,	/* OBJ_id_smime_cti_ets_proofOfApproval 1 2 840 113549 1 9 16 6 5 */
+256,	/* OBJ_id_smime_cti_ets_proofOfCreation 1 2 840 113549 1 9 16 6 6 */
+150,	/* OBJ_keyBag                       1 2 840 113549 1 12 10 1 1 */
+151,	/* OBJ_pkcs8ShroudedKeyBag          1 2 840 113549 1 12 10 1 2 */
+152,	/* OBJ_certBag                      1 2 840 113549 1 12 10 1 3 */
+153,	/* OBJ_crlBag                       1 2 840 113549 1 12 10 1 4 */
+154,	/* OBJ_secretBag                    1 2 840 113549 1 12 10 1 5 */
+155,	/* OBJ_safeContentsBag              1 2 840 113549 1 12 10 1 6 */
+34,	/* OBJ_idea_cbc                     1 3 6 1 4 1 188 7 1 1 2 */
+};
+
diff --git a/crypto/libressl/crypto/objects/obj_err.c b/crypto/libressl/crypto/objects/obj_err.c
new file mode 100644
index 0000000000..a4143b3b74
--- /dev/null
+++ b/crypto/libressl/crypto/objects/obj_err.c
@@ -0,0 +1,102 @@
+/* $OpenBSD: obj_err.c,v 1.10 2014/06/12 15:49:30 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_OBJ,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_OBJ,0,reason)
+
+static ERR_STRING_DATA OBJ_str_functs[] = {
+	{ERR_FUNC(OBJ_F_OBJ_ADD_OBJECT),	"OBJ_add_object"},
+	{ERR_FUNC(OBJ_F_OBJ_CREATE),	"OBJ_create"},
+	{ERR_FUNC(OBJ_F_OBJ_DUP),	"OBJ_dup"},
+	{ERR_FUNC(OBJ_F_OBJ_NAME_NEW_INDEX),	"OBJ_NAME_new_index"},
+	{ERR_FUNC(OBJ_F_OBJ_NID2LN),	"OBJ_nid2ln"},
+	{ERR_FUNC(OBJ_F_OBJ_NID2OBJ),	"OBJ_nid2obj"},
+	{ERR_FUNC(OBJ_F_OBJ_NID2SN),	"OBJ_nid2sn"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA OBJ_str_reasons[] = {
+	{ERR_REASON(OBJ_R_MALLOC_FAILURE)        , "malloc failure"},
+	{ERR_REASON(OBJ_R_UNKNOWN_NID)           , "unknown nid"},
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_OBJ_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(OBJ_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, OBJ_str_functs);
+		ERR_load_strings(0, OBJ_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/objects/obj_lib.c b/crypto/libressl/crypto/objects/obj_lib.c
new file mode 100644
index 0000000000..b06bca39cd
--- /dev/null
+++ b/crypto/libressl/crypto/objects/obj_lib.c
@@ -0,0 +1,130 @@
+/* $OpenBSD: obj_lib.c,v 1.12 2014/07/11 08:44:49 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+ASN1_OBJECT *
+OBJ_dup(const ASN1_OBJECT *o)
+{
+	ASN1_OBJECT *r;
+	char *ln = NULL, *sn = NULL;
+	unsigned char *data = NULL;
+
+	if (o == NULL)
+		return (NULL);
+	if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC))
+		return((ASN1_OBJECT *)o); /* XXX: ugh! Why? What kind of
+					     duplication is this??? */
+
+	r = ASN1_OBJECT_new();
+	if (r == NULL) {
+		OBJerr(OBJ_F_OBJ_DUP, ERR_R_ASN1_LIB);
+		return (NULL);
+	}
+	data = malloc(o->length);
+	if (data == NULL)
+		goto err;
+	if (o->data != NULL)
+		memcpy(data, o->data, o->length);
+	/* once data attached to object it remains const */
+	r->data = data;
+	r->length = o->length;
+	r->nid = o->nid;
+	r->ln = r->sn = NULL;
+	if (o->ln != NULL) {
+		ln = strdup(o->ln);
+		if (ln == NULL)
+			goto err;
+		r->ln = ln;
+	}
+
+	if (o->sn != NULL) {
+		sn = strdup(o->sn);
+		if (sn == NULL)
+			goto err;
+		r->sn = sn;
+	}
+	r->flags = o->flags | (ASN1_OBJECT_FLAG_DYNAMIC |
+	    ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA);
+	return (r);
+
+err:
+	OBJerr(OBJ_F_OBJ_DUP, ERR_R_MALLOC_FAILURE);
+	free(ln);
+	free(sn);
+	free(data);
+	free(r);
+	return (NULL);
+}
+
+int
+OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b)
+{
+	int ret;
+
+	ret = (a->length - b->length);
+	if (ret)
+		return (ret);
+	return (memcmp(a->data, b->data, a->length));
+}
diff --git a/crypto/libressl/crypto/objects/obj_xref.c b/crypto/libressl/crypto/objects/obj_xref.c
new file mode 100644
index 0000000000..572b3b5bbf
--- /dev/null
+++ b/crypto/libressl/crypto/objects/obj_xref.c
@@ -0,0 +1,205 @@
+/* $OpenBSD$ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include "obj_xref.h"
+
+DECLARE_STACK_OF(nid_triple)
+STACK_OF(nid_triple) *sig_app, *sigx_app;
+
+static int
+sig_cmp(const nid_triple *a, const nid_triple *b)
+{
+	return a->sign_id - b->sign_id;
+}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig);
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig);
+
+static int
+sig_sk_cmp(const nid_triple * const *a, const nid_triple * const *b)
+{
+	return (*a)->sign_id - (*b)->sign_id;
+}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx);
+
+static int
+sigx_cmp(const nid_triple * const *a, const nid_triple * const *b)
+{
+	int ret;
+
+	ret = (*a)->hash_id - (*b)->hash_id;
+	if (ret)
+		return ret;
+	return (*a)->pkey_id - (*b)->pkey_id;
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx);
+
+int
+OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid)
+{
+	nid_triple tmp;
+	const nid_triple *rv = NULL;
+	tmp.sign_id = signid;
+
+	if (sig_app) {
+		int idx = sk_nid_triple_find(sig_app, &tmp);
+		if (idx >= 0)
+			rv = sk_nid_triple_value(sig_app, idx);
+	}
+
+#ifndef OBJ_XREF_TEST2
+	if (rv == NULL) {
+		rv = OBJ_bsearch_sig(&tmp, sigoid_srt,
+		    sizeof(sigoid_srt) / sizeof(nid_triple));
+	}
+#endif
+	if (rv == NULL)
+		return 0;
+	if (pdig_nid)
+		*pdig_nid = rv->hash_id;
+	if (ppkey_nid)
+		*ppkey_nid = rv->pkey_id;
+	return 1;
+}
+
+int
+OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid)
+{
+	nid_triple tmp;
+	const nid_triple *t = &tmp;
+	const nid_triple **rv = NULL;
+
+	tmp.hash_id = dig_nid;
+	tmp.pkey_id = pkey_nid;
+
+	if (sigx_app) {
+		int idx = sk_nid_triple_find(sigx_app, &tmp);
+		if (idx >= 0) {
+			t = sk_nid_triple_value(sigx_app, idx);
+			rv = &t;
+		}
+	}
+
+#ifndef OBJ_XREF_TEST2
+	if (rv == NULL) {
+		rv = OBJ_bsearch_sigx(&t, sigoid_srt_xref,
+		    sizeof(sigoid_srt_xref) / sizeof(nid_triple *));
+	}
+#endif
+	if (rv == NULL)
+		return 0;
+	if (psignid)
+		*psignid = (*rv)->sign_id;
+	return 1;
+}
+
+int
+OBJ_add_sigid(int signid, int dig_id, int pkey_id)
+{
+	nid_triple *ntr;
+
+	if (!sig_app)
+		sig_app = sk_nid_triple_new(sig_sk_cmp);
+	if (!sig_app)
+		return 0;
+	if (!sigx_app)
+		sigx_app = sk_nid_triple_new(sigx_cmp);
+	if (!sigx_app)
+		return 0;
+	ntr = reallocarray(NULL, 3, sizeof(int));
+	if (!ntr)
+		return 0;
+	ntr->sign_id = signid;
+	ntr->hash_id = dig_id;
+	ntr->pkey_id = pkey_id;
+
+	if (!sk_nid_triple_push(sig_app, ntr)) {
+		free(ntr);
+		return 0;
+	}
+
+	if (!sk_nid_triple_push(sigx_app, ntr))
+		return 0;
+
+	sk_nid_triple_sort(sig_app);
+	sk_nid_triple_sort(sigx_app);
+
+	return 1;
+}
+
+static void
+sid_free(nid_triple *tt)
+{
+	free(tt);
+}
+
+void
+OBJ_sigid_free(void)
+{
+	if (sig_app) {
+		sk_nid_triple_pop_free(sig_app, sid_free);
+		sig_app = NULL;
+	}
+	if (sigx_app) {
+		sk_nid_triple_free(sigx_app);
+		sigx_app = NULL;
+	}
+}
diff --git a/crypto/libressl/crypto/objects/obj_xref.h b/crypto/libressl/crypto/objects/obj_xref.h
new file mode 100644
index 0000000000..f503cfea3a
--- /dev/null
+++ b/crypto/libressl/crypto/objects/obj_xref.h
@@ -0,0 +1,82 @@
+/* $OpenBSD: obj_xref.h,v 1.2 2014/06/12 15:49:30 deraadt Exp $ */
+/* AUTOGENERATED BY objxref.pl, DO NOT EDIT */
+
+typedef struct
+	{
+	int sign_id;
+	int hash_id;
+	int pkey_id;
+	} nid_triple;
+
+static const nid_triple sigoid_srt[] =
+	{
+	{NID_md2WithRSAEncryption, NID_md2, NID_rsaEncryption},
+	{NID_md5WithRSAEncryption, NID_md5, NID_rsaEncryption},
+	{NID_shaWithRSAEncryption, NID_sha, NID_rsaEncryption},
+	{NID_sha1WithRSAEncryption, NID_sha1, NID_rsaEncryption},
+	{NID_dsaWithSHA, NID_sha, NID_dsa},
+	{NID_dsaWithSHA1_2, NID_sha1, NID_dsa_2},
+	{NID_mdc2WithRSA, NID_mdc2, NID_rsaEncryption},
+	{NID_md5WithRSA, NID_md5, NID_rsa},
+	{NID_dsaWithSHA1, NID_sha1, NID_dsa},
+	{NID_sha1WithRSA, NID_sha1, NID_rsa},
+	{NID_ripemd160WithRSA, NID_ripemd160, NID_rsaEncryption},
+	{NID_md4WithRSAEncryption, NID_md4, NID_rsaEncryption},
+	{NID_ecdsa_with_SHA1, NID_sha1, NID_X9_62_id_ecPublicKey},
+	{NID_sha256WithRSAEncryption, NID_sha256, NID_rsaEncryption},
+	{NID_sha384WithRSAEncryption, NID_sha384, NID_rsaEncryption},
+	{NID_sha512WithRSAEncryption, NID_sha512, NID_rsaEncryption},
+	{NID_sha224WithRSAEncryption, NID_sha224, NID_rsaEncryption},
+	{NID_ecdsa_with_Recommended, NID_undef, NID_X9_62_id_ecPublicKey},
+	{NID_ecdsa_with_Specified, NID_undef, NID_X9_62_id_ecPublicKey},
+	{NID_ecdsa_with_SHA224, NID_sha224, NID_X9_62_id_ecPublicKey},
+	{NID_ecdsa_with_SHA256, NID_sha256, NID_X9_62_id_ecPublicKey},
+	{NID_ecdsa_with_SHA384, NID_sha384, NID_X9_62_id_ecPublicKey},
+	{NID_ecdsa_with_SHA512, NID_sha512, NID_X9_62_id_ecPublicKey},
+	{NID_dsa_with_SHA224, NID_sha224, NID_dsa},
+	{NID_dsa_with_SHA256, NID_sha256, NID_dsa},
+	{NID_id_GostR3411_94_with_GostR3410_2001, NID_id_GostR3411_94, NID_id_GostR3410_2001},
+	{NID_id_GostR3411_94_with_GostR3410_94, NID_id_GostR3411_94, NID_id_GostR3410_94},
+	{NID_id_GostR3411_94_with_GostR3410_94_cc, NID_id_GostR3411_94, NID_id_GostR3410_94_cc},
+	{NID_id_GostR3411_94_with_GostR3410_2001_cc, NID_id_GostR3411_94, NID_id_GostR3410_2001_cc},
+	{NID_rsassaPss, NID_undef, NID_rsaEncryption},
+	{NID_id_tc26_signwithdigest_gost3410_2012_256, NID_id_tc26_gost3411_2012_256, NID_id_GostR3410_2001},
+	{NID_id_tc26_signwithdigest_gost3410_2012_512, NID_id_tc26_gost3411_2012_512, NID_id_GostR3410_2001},
+	};
+
+static const nid_triple * const sigoid_srt_xref[] =
+	{
+	&sigoid_srt[29],
+	&sigoid_srt[17],
+	&sigoid_srt[18],
+	&sigoid_srt[0],
+	&sigoid_srt[1],
+	&sigoid_srt[7],
+	&sigoid_srt[2],
+	&sigoid_srt[4],
+	&sigoid_srt[3],
+	&sigoid_srt[9],
+	&sigoid_srt[5],
+	&sigoid_srt[8],
+	&sigoid_srt[12],
+	&sigoid_srt[6],
+	&sigoid_srt[10],
+	&sigoid_srt[11],
+	&sigoid_srt[13],
+	&sigoid_srt[24],
+	&sigoid_srt[20],
+	&sigoid_srt[14],
+	&sigoid_srt[21],
+	&sigoid_srt[15],
+	&sigoid_srt[22],
+	&sigoid_srt[16],
+	&sigoid_srt[23],
+	&sigoid_srt[19],
+	&sigoid_srt[25],
+	&sigoid_srt[26],
+	&sigoid_srt[27],
+	&sigoid_srt[28],
+	&sigoid_srt[30],
+	&sigoid_srt[31],
+	};
+
diff --git a/crypto/libressl/crypto/ocsp/ocsp_asn.c b/crypto/libressl/crypto/ocsp/ocsp_asn.c
new file mode 100644
index 0000000000..642638d29f
--- /dev/null
+++ b/crypto/libressl/crypto/ocsp/ocsp_asn.c
@@ -0,0 +1,962 @@
+/* $OpenBSD: ocsp_asn.c,v 1.7 2015/02/09 16:04:46 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include 
+#include 
+#include 
+
+static const ASN1_TEMPLATE OCSP_SIGNATURE_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_SIGNATURE, signatureAlgorithm),
+		.field_name = "signatureAlgorithm",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_SIGNATURE, signature),
+		.field_name = "signature",
+		.item = &ASN1_BIT_STRING_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(OCSP_SIGNATURE, certs),
+		.field_name = "certs",
+		.item = &X509_it,
+	},
+};
+
+const ASN1_ITEM OCSP_SIGNATURE_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = OCSP_SIGNATURE_seq_tt,
+	.tcount = sizeof(OCSP_SIGNATURE_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(OCSP_SIGNATURE),
+	.sname = "OCSP_SIGNATURE",
+};
+
+
+OCSP_SIGNATURE *
+d2i_OCSP_SIGNATURE(OCSP_SIGNATURE **a, const unsigned char **in, long len)
+{
+	return (OCSP_SIGNATURE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &OCSP_SIGNATURE_it);
+}
+
+int
+i2d_OCSP_SIGNATURE(OCSP_SIGNATURE *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_SIGNATURE_it);
+}
+
+OCSP_SIGNATURE *
+OCSP_SIGNATURE_new(void)
+{
+	return (OCSP_SIGNATURE *)ASN1_item_new(&OCSP_SIGNATURE_it);
+}
+
+void
+OCSP_SIGNATURE_free(OCSP_SIGNATURE *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &OCSP_SIGNATURE_it);
+}
+
+static const ASN1_TEMPLATE OCSP_CERTID_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_CERTID, hashAlgorithm),
+		.field_name = "hashAlgorithm",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_CERTID, issuerNameHash),
+		.field_name = "issuerNameHash",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_CERTID, issuerKeyHash),
+		.field_name = "issuerKeyHash",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_CERTID, serialNumber),
+		.field_name = "serialNumber",
+		.item = &ASN1_INTEGER_it,
+	},
+};
+
+const ASN1_ITEM OCSP_CERTID_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = OCSP_CERTID_seq_tt,
+	.tcount = sizeof(OCSP_CERTID_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(OCSP_CERTID),
+	.sname = "OCSP_CERTID",
+};
+
+
+OCSP_CERTID *
+d2i_OCSP_CERTID(OCSP_CERTID **a, const unsigned char **in, long len)
+{
+	return (OCSP_CERTID *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &OCSP_CERTID_it);
+}
+
+int
+i2d_OCSP_CERTID(OCSP_CERTID *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_CERTID_it);
+}
+
+OCSP_CERTID *
+OCSP_CERTID_new(void)
+{
+	return (OCSP_CERTID *)ASN1_item_new(&OCSP_CERTID_it);
+}
+
+void
+OCSP_CERTID_free(OCSP_CERTID *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &OCSP_CERTID_it);
+}
+
+static const ASN1_TEMPLATE OCSP_ONEREQ_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_ONEREQ, reqCert),
+		.field_name = "reqCert",
+		.item = &OCSP_CERTID_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(OCSP_ONEREQ, singleRequestExtensions),
+		.field_name = "singleRequestExtensions",
+		.item = &X509_EXTENSION_it,
+	},
+};
+
+const ASN1_ITEM OCSP_ONEREQ_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = OCSP_ONEREQ_seq_tt,
+	.tcount = sizeof(OCSP_ONEREQ_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(OCSP_ONEREQ),
+	.sname = "OCSP_ONEREQ",
+};
+
+
+OCSP_ONEREQ *
+d2i_OCSP_ONEREQ(OCSP_ONEREQ **a, const unsigned char **in, long len)
+{
+	return (OCSP_ONEREQ *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &OCSP_ONEREQ_it);
+}
+
+int
+i2d_OCSP_ONEREQ(OCSP_ONEREQ *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_ONEREQ_it);
+}
+
+OCSP_ONEREQ *
+OCSP_ONEREQ_new(void)
+{
+	return (OCSP_ONEREQ *)ASN1_item_new(&OCSP_ONEREQ_it);
+}
+
+void
+OCSP_ONEREQ_free(OCSP_ONEREQ *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &OCSP_ONEREQ_it);
+}
+
+static const ASN1_TEMPLATE OCSP_REQINFO_seq_tt[] = {
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(OCSP_REQINFO, version),
+		.field_name = "version",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 1,
+		.offset = offsetof(OCSP_REQINFO, requestorName),
+		.field_name = "requestorName",
+		.item = &GENERAL_NAME_it,
+	},
+	{
+		.flags = ASN1_TFLG_SEQUENCE_OF,
+		.tag = 0,
+		.offset = offsetof(OCSP_REQINFO, requestList),
+		.field_name = "requestList",
+		.item = &OCSP_ONEREQ_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
+		.tag = 2,
+		.offset = offsetof(OCSP_REQINFO, requestExtensions),
+		.field_name = "requestExtensions",
+		.item = &X509_EXTENSION_it,
+	},
+};
+
+const ASN1_ITEM OCSP_REQINFO_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = OCSP_REQINFO_seq_tt,
+	.tcount = sizeof(OCSP_REQINFO_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(OCSP_REQINFO),
+	.sname = "OCSP_REQINFO",
+};
+
+
+OCSP_REQINFO *
+d2i_OCSP_REQINFO(OCSP_REQINFO **a, const unsigned char **in, long len)
+{
+	return (OCSP_REQINFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &OCSP_REQINFO_it);
+}
+
+int
+i2d_OCSP_REQINFO(OCSP_REQINFO *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_REQINFO_it);
+}
+
+OCSP_REQINFO *
+OCSP_REQINFO_new(void)
+{
+	return (OCSP_REQINFO *)ASN1_item_new(&OCSP_REQINFO_it);
+}
+
+void
+OCSP_REQINFO_free(OCSP_REQINFO *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &OCSP_REQINFO_it);
+}
+
+static const ASN1_TEMPLATE OCSP_REQUEST_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_REQUEST, tbsRequest),
+		.field_name = "tbsRequest",
+		.item = &OCSP_REQINFO_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(OCSP_REQUEST, optionalSignature),
+		.field_name = "optionalSignature",
+		.item = &OCSP_SIGNATURE_it,
+	},
+};
+
+const ASN1_ITEM OCSP_REQUEST_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = OCSP_REQUEST_seq_tt,
+	.tcount = sizeof(OCSP_REQUEST_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(OCSP_REQUEST),
+	.sname = "OCSP_REQUEST",
+};
+
+
+OCSP_REQUEST *
+d2i_OCSP_REQUEST(OCSP_REQUEST **a, const unsigned char **in, long len)
+{
+	return (OCSP_REQUEST *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &OCSP_REQUEST_it);
+}
+
+int
+i2d_OCSP_REQUEST(OCSP_REQUEST *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_REQUEST_it);
+}
+
+OCSP_REQUEST *
+OCSP_REQUEST_new(void)
+{
+	return (OCSP_REQUEST *)ASN1_item_new(&OCSP_REQUEST_it);
+}
+
+void
+OCSP_REQUEST_free(OCSP_REQUEST *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &OCSP_REQUEST_it);
+}
+
+/* OCSP_RESPONSE templates */
+
+static const ASN1_TEMPLATE OCSP_RESPBYTES_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_RESPBYTES, responseType),
+		.field_name = "responseType",
+		.item = &ASN1_OBJECT_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_RESPBYTES, response),
+		.field_name = "response",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+};
+
+const ASN1_ITEM OCSP_RESPBYTES_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = OCSP_RESPBYTES_seq_tt,
+	.tcount = sizeof(OCSP_RESPBYTES_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(OCSP_RESPBYTES),
+	.sname = "OCSP_RESPBYTES",
+};
+
+
+OCSP_RESPBYTES *
+d2i_OCSP_RESPBYTES(OCSP_RESPBYTES **a, const unsigned char **in, long len)
+{
+	return (OCSP_RESPBYTES *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &OCSP_RESPBYTES_it);
+}
+
+int
+i2d_OCSP_RESPBYTES(OCSP_RESPBYTES *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_RESPBYTES_it);
+}
+
+OCSP_RESPBYTES *
+OCSP_RESPBYTES_new(void)
+{
+	return (OCSP_RESPBYTES *)ASN1_item_new(&OCSP_RESPBYTES_it);
+}
+
+void
+OCSP_RESPBYTES_free(OCSP_RESPBYTES *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &OCSP_RESPBYTES_it);
+}
+
+static const ASN1_TEMPLATE OCSP_RESPONSE_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_RESPONSE, responseStatus),
+		.field_name = "responseStatus",
+		.item = &ASN1_ENUMERATED_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(OCSP_RESPONSE, responseBytes),
+		.field_name = "responseBytes",
+		.item = &OCSP_RESPBYTES_it,
+	},
+};
+
+const ASN1_ITEM OCSP_RESPONSE_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = OCSP_RESPONSE_seq_tt,
+	.tcount = sizeof(OCSP_RESPONSE_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(OCSP_RESPONSE),
+	.sname = "OCSP_RESPONSE",
+};
+
+
+OCSP_RESPONSE *
+d2i_OCSP_RESPONSE(OCSP_RESPONSE **a, const unsigned char **in, long len)
+{
+	return (OCSP_RESPONSE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &OCSP_RESPONSE_it);
+}
+
+int
+i2d_OCSP_RESPONSE(OCSP_RESPONSE *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_RESPONSE_it);
+}
+
+OCSP_RESPONSE *
+OCSP_RESPONSE_new(void)
+{
+	return (OCSP_RESPONSE *)ASN1_item_new(&OCSP_RESPONSE_it);
+}
+
+void
+OCSP_RESPONSE_free(OCSP_RESPONSE *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &OCSP_RESPONSE_it);
+}
+
+static const ASN1_TEMPLATE OCSP_RESPID_ch_tt[] = {
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 1,
+		.offset = offsetof(OCSP_RESPID, value.byName),
+		.field_name = "value.byName",
+		.item = &X509_NAME_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT,
+		.tag = 2,
+		.offset = offsetof(OCSP_RESPID, value.byKey),
+		.field_name = "value.byKey",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+};
+
+const ASN1_ITEM OCSP_RESPID_it = {
+	.itype = ASN1_ITYPE_CHOICE,
+	.utype = offsetof(OCSP_RESPID, type),
+	.templates = OCSP_RESPID_ch_tt,
+	.tcount = sizeof(OCSP_RESPID_ch_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(OCSP_RESPID),
+	.sname = "OCSP_RESPID",
+};
+
+
+OCSP_RESPID *
+d2i_OCSP_RESPID(OCSP_RESPID **a, const unsigned char **in, long len)
+{
+	return (OCSP_RESPID *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &OCSP_RESPID_it);
+}
+
+int
+i2d_OCSP_RESPID(OCSP_RESPID *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_RESPID_it);
+}
+
+OCSP_RESPID *
+OCSP_RESPID_new(void)
+{
+	return (OCSP_RESPID *)ASN1_item_new(&OCSP_RESPID_it);
+}
+
+void
+OCSP_RESPID_free(OCSP_RESPID *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &OCSP_RESPID_it);
+}
+
+static const ASN1_TEMPLATE OCSP_REVOKEDINFO_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_REVOKEDINFO, revocationTime),
+		.field_name = "revocationTime",
+		.item = &ASN1_GENERALIZEDTIME_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(OCSP_REVOKEDINFO, revocationReason),
+		.field_name = "revocationReason",
+		.item = &ASN1_ENUMERATED_it,
+	},
+};
+
+const ASN1_ITEM OCSP_REVOKEDINFO_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = OCSP_REVOKEDINFO_seq_tt,
+	.tcount = sizeof(OCSP_REVOKEDINFO_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(OCSP_REVOKEDINFO),
+	.sname = "OCSP_REVOKEDINFO",
+};
+
+
+OCSP_REVOKEDINFO *
+d2i_OCSP_REVOKEDINFO(OCSP_REVOKEDINFO **a, const unsigned char **in, long len)
+{
+	return (OCSP_REVOKEDINFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &OCSP_REVOKEDINFO_it);
+}
+
+int
+i2d_OCSP_REVOKEDINFO(OCSP_REVOKEDINFO *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_REVOKEDINFO_it);
+}
+
+OCSP_REVOKEDINFO *
+OCSP_REVOKEDINFO_new(void)
+{
+	return (OCSP_REVOKEDINFO *)ASN1_item_new(&OCSP_REVOKEDINFO_it);
+}
+
+void
+OCSP_REVOKEDINFO_free(OCSP_REVOKEDINFO *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &OCSP_REVOKEDINFO_it);
+}
+
+static const ASN1_TEMPLATE OCSP_CERTSTATUS_ch_tt[] = {
+	{
+		.flags = ASN1_TFLG_IMPLICIT,
+		.tag = 0,
+		.offset = offsetof(OCSP_CERTSTATUS, value.good),
+		.field_name = "value.good",
+		.item = &ASN1_NULL_it,
+	},
+	{
+		.flags = ASN1_TFLG_IMPLICIT,
+		.tag = 1,
+		.offset = offsetof(OCSP_CERTSTATUS, value.revoked),
+		.field_name = "value.revoked",
+		.item = &OCSP_REVOKEDINFO_it,
+	},
+	{
+		.flags = ASN1_TFLG_IMPLICIT,
+		.tag = 2,
+		.offset = offsetof(OCSP_CERTSTATUS, value.unknown),
+		.field_name = "value.unknown",
+		.item = &ASN1_NULL_it,
+	},
+};
+
+const ASN1_ITEM OCSP_CERTSTATUS_it = {
+	.itype = ASN1_ITYPE_CHOICE,
+	.utype = offsetof(OCSP_CERTSTATUS, type),
+	.templates = OCSP_CERTSTATUS_ch_tt,
+	.tcount = sizeof(OCSP_CERTSTATUS_ch_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(OCSP_CERTSTATUS),
+	.sname = "OCSP_CERTSTATUS",
+};
+
+
+OCSP_CERTSTATUS *
+d2i_OCSP_CERTSTATUS(OCSP_CERTSTATUS **a, const unsigned char **in, long len)
+{
+	return (OCSP_CERTSTATUS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &OCSP_CERTSTATUS_it);
+}
+
+int
+i2d_OCSP_CERTSTATUS(OCSP_CERTSTATUS *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_CERTSTATUS_it);
+}
+
+OCSP_CERTSTATUS *
+OCSP_CERTSTATUS_new(void)
+{
+	return (OCSP_CERTSTATUS *)ASN1_item_new(&OCSP_CERTSTATUS_it);
+}
+
+void
+OCSP_CERTSTATUS_free(OCSP_CERTSTATUS *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &OCSP_CERTSTATUS_it);
+}
+
+static const ASN1_TEMPLATE OCSP_SINGLERESP_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_SINGLERESP, certId),
+		.field_name = "certId",
+		.item = &OCSP_CERTID_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_SINGLERESP, certStatus),
+		.field_name = "certStatus",
+		.item = &OCSP_CERTSTATUS_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_SINGLERESP, thisUpdate),
+		.field_name = "thisUpdate",
+		.item = &ASN1_GENERALIZEDTIME_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(OCSP_SINGLERESP, nextUpdate),
+		.field_name = "nextUpdate",
+		.item = &ASN1_GENERALIZEDTIME_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
+		.tag = 1,
+		.offset = offsetof(OCSP_SINGLERESP, singleExtensions),
+		.field_name = "singleExtensions",
+		.item = &X509_EXTENSION_it,
+	},
+};
+
+const ASN1_ITEM OCSP_SINGLERESP_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = OCSP_SINGLERESP_seq_tt,
+	.tcount = sizeof(OCSP_SINGLERESP_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(OCSP_SINGLERESP),
+	.sname = "OCSP_SINGLERESP",
+};
+
+
+OCSP_SINGLERESP *
+d2i_OCSP_SINGLERESP(OCSP_SINGLERESP **a, const unsigned char **in, long len)
+{
+	return (OCSP_SINGLERESP *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &OCSP_SINGLERESP_it);
+}
+
+int
+i2d_OCSP_SINGLERESP(OCSP_SINGLERESP *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_SINGLERESP_it);
+}
+
+OCSP_SINGLERESP *
+OCSP_SINGLERESP_new(void)
+{
+	return (OCSP_SINGLERESP *)ASN1_item_new(&OCSP_SINGLERESP_it);
+}
+
+void
+OCSP_SINGLERESP_free(OCSP_SINGLERESP *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &OCSP_SINGLERESP_it);
+}
+
+static const ASN1_TEMPLATE OCSP_RESPDATA_seq_tt[] = {
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(OCSP_RESPDATA, version),
+		.field_name = "version",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_RESPDATA, responderId),
+		.field_name = "responderId",
+		.item = &OCSP_RESPID_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_RESPDATA, producedAt),
+		.field_name = "producedAt",
+		.item = &ASN1_GENERALIZEDTIME_it,
+	},
+	{
+		.flags = ASN1_TFLG_SEQUENCE_OF,
+		.tag = 0,
+		.offset = offsetof(OCSP_RESPDATA, responses),
+		.field_name = "responses",
+		.item = &OCSP_SINGLERESP_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
+		.tag = 1,
+		.offset = offsetof(OCSP_RESPDATA, responseExtensions),
+		.field_name = "responseExtensions",
+		.item = &X509_EXTENSION_it,
+	},
+};
+
+const ASN1_ITEM OCSP_RESPDATA_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = OCSP_RESPDATA_seq_tt,
+	.tcount = sizeof(OCSP_RESPDATA_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(OCSP_RESPDATA),
+	.sname = "OCSP_RESPDATA",
+};
+
+
+OCSP_RESPDATA *
+d2i_OCSP_RESPDATA(OCSP_RESPDATA **a, const unsigned char **in, long len)
+{
+	return (OCSP_RESPDATA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &OCSP_RESPDATA_it);
+}
+
+int
+i2d_OCSP_RESPDATA(OCSP_RESPDATA *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_RESPDATA_it);
+}
+
+OCSP_RESPDATA *
+OCSP_RESPDATA_new(void)
+{
+	return (OCSP_RESPDATA *)ASN1_item_new(&OCSP_RESPDATA_it);
+}
+
+void
+OCSP_RESPDATA_free(OCSP_RESPDATA *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &OCSP_RESPDATA_it);
+}
+
+static const ASN1_TEMPLATE OCSP_BASICRESP_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_BASICRESP, tbsResponseData),
+		.field_name = "tbsResponseData",
+		.item = &OCSP_RESPDATA_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_BASICRESP, signatureAlgorithm),
+		.field_name = "signatureAlgorithm",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_BASICRESP, signature),
+		.field_name = "signature",
+		.item = &ASN1_BIT_STRING_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(OCSP_BASICRESP, certs),
+		.field_name = "certs",
+		.item = &X509_it,
+	},
+};
+
+const ASN1_ITEM OCSP_BASICRESP_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = OCSP_BASICRESP_seq_tt,
+	.tcount = sizeof(OCSP_BASICRESP_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(OCSP_BASICRESP),
+	.sname = "OCSP_BASICRESP",
+};
+
+
+OCSP_BASICRESP *
+d2i_OCSP_BASICRESP(OCSP_BASICRESP **a, const unsigned char **in, long len)
+{
+	return (OCSP_BASICRESP *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &OCSP_BASICRESP_it);
+}
+
+int
+i2d_OCSP_BASICRESP(OCSP_BASICRESP *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_BASICRESP_it);
+}
+
+OCSP_BASICRESP *
+OCSP_BASICRESP_new(void)
+{
+	return (OCSP_BASICRESP *)ASN1_item_new(&OCSP_BASICRESP_it);
+}
+
+void
+OCSP_BASICRESP_free(OCSP_BASICRESP *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &OCSP_BASICRESP_it);
+}
+
+static const ASN1_TEMPLATE OCSP_CRLID_seq_tt[] = {
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(OCSP_CRLID, crlUrl),
+		.field_name = "crlUrl",
+		.item = &ASN1_IA5STRING_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 1,
+		.offset = offsetof(OCSP_CRLID, crlNum),
+		.field_name = "crlNum",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 2,
+		.offset = offsetof(OCSP_CRLID, crlTime),
+		.field_name = "crlTime",
+		.item = &ASN1_GENERALIZEDTIME_it,
+	},
+};
+
+const ASN1_ITEM OCSP_CRLID_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = OCSP_CRLID_seq_tt,
+	.tcount = sizeof(OCSP_CRLID_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(OCSP_CRLID),
+	.sname = "OCSP_CRLID",
+};
+
+
+OCSP_CRLID *
+d2i_OCSP_CRLID(OCSP_CRLID **a, const unsigned char **in, long len)
+{
+	return (OCSP_CRLID *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &OCSP_CRLID_it);
+}
+
+int
+i2d_OCSP_CRLID(OCSP_CRLID *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_CRLID_it);
+}
+
+OCSP_CRLID *
+OCSP_CRLID_new(void)
+{
+	return (OCSP_CRLID *)ASN1_item_new(&OCSP_CRLID_it);
+}
+
+void
+OCSP_CRLID_free(OCSP_CRLID *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &OCSP_CRLID_it);
+}
+
+static const ASN1_TEMPLATE OCSP_SERVICELOC_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(OCSP_SERVICELOC, issuer),
+		.field_name = "issuer",
+		.item = &X509_NAME_it,
+	},
+	{
+		.flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(OCSP_SERVICELOC, locator),
+		.field_name = "locator",
+		.item = &ACCESS_DESCRIPTION_it,
+	},
+};
+
+const ASN1_ITEM OCSP_SERVICELOC_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = OCSP_SERVICELOC_seq_tt,
+	.tcount = sizeof(OCSP_SERVICELOC_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(OCSP_SERVICELOC),
+	.sname = "OCSP_SERVICELOC",
+};
+
+
+OCSP_SERVICELOC *
+d2i_OCSP_SERVICELOC(OCSP_SERVICELOC **a, const unsigned char **in, long len)
+{
+	return (OCSP_SERVICELOC *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &OCSP_SERVICELOC_it);
+}
+
+int
+i2d_OCSP_SERVICELOC(OCSP_SERVICELOC *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &OCSP_SERVICELOC_it);
+}
+
+OCSP_SERVICELOC *
+OCSP_SERVICELOC_new(void)
+{
+	return (OCSP_SERVICELOC *)ASN1_item_new(&OCSP_SERVICELOC_it);
+}
+
+void
+OCSP_SERVICELOC_free(OCSP_SERVICELOC *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &OCSP_SERVICELOC_it);
+}
diff --git a/crypto/libressl/crypto/ocsp/ocsp_cl.c b/crypto/libressl/crypto/ocsp/ocsp_cl.c
new file mode 100644
index 0000000000..13bb807c7d
--- /dev/null
+++ b/crypto/libressl/crypto/ocsp/ocsp_cl.c
@@ -0,0 +1,404 @@
+/* $OpenBSD: ocsp_cl.c,v 1.10 2016/07/05 03:24:38 beck Exp $ */
+/* Written by Tom Titchener  for the OpenSSL
+ * project. */
+
+/* History:
+   This file was transfered to Richard Levitte from CertCo by Kathy
+   Weinhold in mid-spring 2000 to be included in OpenSSL or released
+   as a patch kit. */
+
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+int asn1_time_parse(const char *, size_t, struct tm *, int);
+int asn1_tm_cmp(struct tm *, struct tm *);
+
+/* Utility functions related to sending OCSP requests and extracting
+ * relevant information from the response.
+ */
+
+/* Add an OCSP_CERTID to an OCSP request. Return new OCSP_ONEREQ
+ * pointer: useful if we want to add extensions.
+ */
+OCSP_ONEREQ *
+OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid)
+{
+	OCSP_ONEREQ *one = NULL;
+
+	if (!(one = OCSP_ONEREQ_new()))
+		goto err;
+	if (one->reqCert)
+		OCSP_CERTID_free(one->reqCert);
+	one->reqCert = cid;
+	if (req && !sk_OCSP_ONEREQ_push(req->tbsRequest->requestList, one))
+		goto err;
+	return one;
+
+err:
+	OCSP_ONEREQ_free(one);
+	return NULL;
+}
+
+/* Set requestorName from an X509_NAME structure */
+int
+OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm)
+{
+	GENERAL_NAME *gen;
+
+	gen = GENERAL_NAME_new();
+	if (gen == NULL)
+		return 0;
+	if (!X509_NAME_set(&gen->d.directoryName, nm)) {
+		GENERAL_NAME_free(gen);
+		return 0;
+	}
+	gen->type = GEN_DIRNAME;
+	if (req->tbsRequest->requestorName)
+		GENERAL_NAME_free(req->tbsRequest->requestorName);
+	req->tbsRequest->requestorName = gen;
+	return 1;
+}
+
+/* Add a certificate to an OCSP request */
+int
+OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert)
+{
+	OCSP_SIGNATURE *sig;
+
+	if (!req->optionalSignature)
+		req->optionalSignature = OCSP_SIGNATURE_new();
+	sig = req->optionalSignature;
+	if (!sig)
+		return 0;
+	if (!cert)
+		return 1;
+	if (!sig->certs && !(sig->certs = sk_X509_new_null()))
+		return 0;
+
+	if (!sk_X509_push(sig->certs, cert))
+		return 0;
+	CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
+	return 1;
+}
+
+/* Sign an OCSP request set the requestorName to the subjec
+ * name of an optional signers certificate and include one
+ * or more optional certificates in the request. Behaves
+ * like PKCS7_sign().
+ */
+int
+OCSP_request_sign(OCSP_REQUEST *req, X509 *signer, EVP_PKEY *key,
+    const EVP_MD *dgst, STACK_OF(X509) *certs, unsigned long flags)
+{
+	int i;
+	OCSP_SIGNATURE *sig;
+	X509 *x;
+
+	if (!OCSP_request_set1_name(req, X509_get_subject_name(signer)))
+		goto err;
+
+	if (!(req->optionalSignature = sig = OCSP_SIGNATURE_new()))
+		goto err;
+	if (key) {
+		if (!X509_check_private_key(signer, key)) {
+			OCSPerr(OCSP_F_OCSP_REQUEST_SIGN,
+			    OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+			goto err;
+		}
+		if (!OCSP_REQUEST_sign(req, key, dgst))
+			goto err;
+	}
+
+	if (!(flags & OCSP_NOCERTS)) {
+		if (!OCSP_request_add1_cert(req, signer))
+			goto err;
+		for (i = 0; i < sk_X509_num(certs); i++) {
+			x = sk_X509_value(certs, i);
+			if (!OCSP_request_add1_cert(req, x))
+				goto err;
+		}
+	}
+
+	return 1;
+
+err:
+	OCSP_SIGNATURE_free(req->optionalSignature);
+	req->optionalSignature = NULL;
+	return 0;
+}
+
+/* Get response status */
+int
+OCSP_response_status(OCSP_RESPONSE *resp)
+{
+	return ASN1_ENUMERATED_get(resp->responseStatus);
+}
+
+/* Extract basic response from OCSP_RESPONSE or NULL if
+ * no basic response present.
+ */
+OCSP_BASICRESP *
+OCSP_response_get1_basic(OCSP_RESPONSE *resp)
+{
+	OCSP_RESPBYTES *rb;
+
+	rb = resp->responseBytes;
+	if (!rb) {
+		OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC,
+		    OCSP_R_NO_RESPONSE_DATA);
+		return NULL;
+	}
+	if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) {
+		OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC,
+		    OCSP_R_NOT_BASIC_RESPONSE);
+		return NULL;
+	}
+
+	return ASN1_item_unpack(rb->response, ASN1_ITEM_rptr(OCSP_BASICRESP));
+}
+
+/* Return number of OCSP_SINGLERESP reponses present in
+ * a basic response.
+ */
+int
+OCSP_resp_count(OCSP_BASICRESP *bs)
+{
+	if (!bs)
+		return -1;
+	return sk_OCSP_SINGLERESP_num(bs->tbsResponseData->responses);
+}
+
+/* Extract an OCSP_SINGLERESP response with a given index */
+OCSP_SINGLERESP *
+OCSP_resp_get0(OCSP_BASICRESP *bs, int idx)
+{
+	if (!bs)
+		return NULL;
+	return sk_OCSP_SINGLERESP_value(bs->tbsResponseData->responses, idx);
+}
+
+/* Look single response matching a given certificate ID */
+int
+OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last)
+{
+	int i;
+	STACK_OF(OCSP_SINGLERESP) *sresp;
+	OCSP_SINGLERESP *single;
+
+	if (!bs)
+		return -1;
+	if (last < 0)
+		last = 0;
+	else
+		last++;
+	sresp = bs->tbsResponseData->responses;
+	for (i = last; i < sk_OCSP_SINGLERESP_num(sresp); i++) {
+		single = sk_OCSP_SINGLERESP_value(sresp, i);
+		if (!OCSP_id_cmp(id, single->certId))
+			return i;
+	}
+	return -1;
+}
+
+/* Extract status information from an OCSP_SINGLERESP structure.
+ * Note: the revtime and reason values are only set if the
+ * certificate status is revoked. Returns numerical value of
+ * status.
+ */
+int
+OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason,
+    ASN1_GENERALIZEDTIME **revtime, ASN1_GENERALIZEDTIME **thisupd,
+    ASN1_GENERALIZEDTIME **nextupd)
+{
+	int ret;
+	OCSP_CERTSTATUS *cst;
+
+	if (!single)
+		return -1;
+	cst = single->certStatus;
+	ret = cst->type;
+	if (ret == V_OCSP_CERTSTATUS_REVOKED) {
+		OCSP_REVOKEDINFO *rev = cst->value.revoked;
+
+		if (revtime)
+			*revtime = rev->revocationTime;
+		if (reason) {
+			if (rev->revocationReason)
+				*reason = ASN1_ENUMERATED_get(
+				    rev->revocationReason);
+			else
+				*reason = -1;
+		}
+	}
+	if (thisupd)
+		*thisupd = single->thisUpdate;
+	if (nextupd)
+		*nextupd = single->nextUpdate;
+	return ret;
+}
+
+/* This function combines the previous ones: look up a certificate ID and
+ * if found extract status information. Return 0 is successful.
+ */
+int
+OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status,
+    int *reason, ASN1_GENERALIZEDTIME **revtime, ASN1_GENERALIZEDTIME **thisupd,
+    ASN1_GENERALIZEDTIME **nextupd)
+{
+	int i;
+	OCSP_SINGLERESP *single;
+
+	i = OCSP_resp_find(bs, id, -1);
+	/* Maybe check for multiple responses and give an error? */
+	if (i < 0)
+		return 0;
+	single = OCSP_resp_get0(bs, i);
+	i = OCSP_single_get0_status(single, reason, revtime, thisupd, nextupd);
+	if (status)
+		*status = i;
+	return 1;
+}
+
+/* Check validity of thisUpdate and nextUpdate fields. It is possible that the request will
+ * take a few seconds to process and/or the time wont be totally accurate. Therefore to avoid
+ * rejecting otherwise valid time we allow the times to be within 'nsec' of the current time.
+ * Also to avoid accepting very old responses without a nextUpdate field an optional maxage
+ * parameter specifies the maximum age the thisUpdate field can be.
+ */
+int
+OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd,
+    ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec)
+{
+	time_t t_now, t_tmp;
+	struct tm tm_this, tm_next, tm_tmp;
+
+	time(&t_now);
+
+	/*
+	 * Times must explicitly be a GENERALIZEDTIME as per section
+	 * 4.2.2.1 of RFC 6960 - It is invalid to accept other times
+	 * (such as UTCTIME permitted/required by RFC 5280 for certificates)
+	 */
+
+	/* Check thisUpdate is valid and not more than nsec in the future */
+	if (asn1_time_parse(thisupd->data, thisupd->length, &tm_this,
+	    V_ASN1_GENERALIZEDTIME) != V_ASN1_GENERALIZEDTIME) {
+		OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY,
+		    OCSP_R_ERROR_IN_THISUPDATE_FIELD);
+		return 0;
+	} else {
+		t_tmp = t_now + nsec;
+		if (gmtime_r(&t_tmp, &tm_tmp) == NULL)
+			return 0;
+		if (asn1_tm_cmp(&tm_this, &tm_tmp) > 0) {
+			OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY,
+			    OCSP_R_STATUS_NOT_YET_VALID);
+			return 0;
+		}
+
+		/*
+		 * If maxsec specified check thisUpdate is not more than maxsec
+		 * in the past
+		 */
+		if (maxsec >= 0) {
+			t_tmp = t_now - maxsec;
+			if (gmtime_r(&t_tmp, &tm_tmp) == NULL)
+				return 0;
+			if (asn1_tm_cmp(&tm_this, &tm_tmp) < 0) {
+				OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY,
+				    OCSP_R_STATUS_TOO_OLD);
+				return 0;
+			}
+		}
+	}
+
+	if (!nextupd)
+		return 1;
+
+	/* Check nextUpdate is valid and not more than nsec in the past */
+	if (asn1_time_parse(nextupd->data, nextupd->length, &tm_next,
+	    V_ASN1_GENERALIZEDTIME) != V_ASN1_GENERALIZEDTIME) {
+		OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY,
+		    OCSP_R_ERROR_IN_NEXTUPDATE_FIELD);
+		return 0;
+	} else {
+		t_tmp = t_now - nsec;
+		if (gmtime_r(&t_tmp, &tm_tmp) == NULL)
+			return 0;
+		if (asn1_tm_cmp(&tm_next, &tm_tmp) < 0) {
+			OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY,
+			    OCSP_R_STATUS_EXPIRED);
+			return 0;
+		}
+	}
+
+	/* Also don't allow nextUpdate to precede thisUpdate */
+	if (asn1_tm_cmp(&tm_next, &tm_this) < 0) {
+		OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY,
+		    OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE);
+		return 0;
+	}
+
+	return 1;
+}
diff --git a/crypto/libressl/crypto/ocsp/ocsp_err.c b/crypto/libressl/crypto/ocsp/ocsp_err.c
new file mode 100644
index 0000000000..c5b09115cf
--- /dev/null
+++ b/crypto/libressl/crypto/ocsp/ocsp_err.c
@@ -0,0 +1,142 @@
+/* $OpenBSD: ocsp_err.c,v 1.6 2014/06/12 15:49:30 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_OCSP,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_OCSP,0,reason)
+
+static ERR_STRING_DATA OCSP_str_functs[]= {
+	{ERR_FUNC(OCSP_F_ASN1_STRING_ENCODE),	"ASN1_STRING_encode"},
+	{ERR_FUNC(OCSP_F_D2I_OCSP_NONCE),	"D2I_OCSP_NONCE"},
+	{ERR_FUNC(OCSP_F_OCSP_BASIC_ADD1_STATUS),	"OCSP_basic_add1_status"},
+	{ERR_FUNC(OCSP_F_OCSP_BASIC_SIGN),	"OCSP_basic_sign"},
+	{ERR_FUNC(OCSP_F_OCSP_BASIC_VERIFY),	"OCSP_basic_verify"},
+	{ERR_FUNC(OCSP_F_OCSP_CERT_ID_NEW),	"OCSP_cert_id_new"},
+	{ERR_FUNC(OCSP_F_OCSP_CHECK_DELEGATED),	"OCSP_CHECK_DELEGATED"},
+	{ERR_FUNC(OCSP_F_OCSP_CHECK_IDS),	"OCSP_CHECK_IDS"},
+	{ERR_FUNC(OCSP_F_OCSP_CHECK_ISSUER),	"OCSP_CHECK_ISSUER"},
+	{ERR_FUNC(OCSP_F_OCSP_CHECK_VALIDITY),	"OCSP_check_validity"},
+	{ERR_FUNC(OCSP_F_OCSP_MATCH_ISSUERID),	"OCSP_MATCH_ISSUERID"},
+	{ERR_FUNC(OCSP_F_OCSP_PARSE_URL),	"OCSP_parse_url"},
+	{ERR_FUNC(OCSP_F_OCSP_REQUEST_SIGN),	"OCSP_request_sign"},
+	{ERR_FUNC(OCSP_F_OCSP_REQUEST_VERIFY),	"OCSP_request_verify"},
+	{ERR_FUNC(OCSP_F_OCSP_RESPONSE_GET1_BASIC),	"OCSP_response_get1_basic"},
+	{ERR_FUNC(OCSP_F_OCSP_SENDREQ_BIO),	"OCSP_sendreq_bio"},
+	{ERR_FUNC(OCSP_F_OCSP_SENDREQ_NBIO),	"OCSP_sendreq_nbio"},
+	{ERR_FUNC(OCSP_F_PARSE_HTTP_LINE1),	"PARSE_HTTP_LINE1"},
+	{ERR_FUNC(OCSP_F_REQUEST_VERIFY),	"REQUEST_VERIFY"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA OCSP_str_reasons[]= {
+	{ERR_REASON(OCSP_R_BAD_DATA)             , "bad data"},
+	{ERR_REASON(OCSP_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"},
+	{ERR_REASON(OCSP_R_DIGEST_ERR)           , "digest err"},
+	{ERR_REASON(OCSP_R_ERROR_IN_NEXTUPDATE_FIELD), "error in nextupdate field"},
+	{ERR_REASON(OCSP_R_ERROR_IN_THISUPDATE_FIELD), "error in thisupdate field"},
+	{ERR_REASON(OCSP_R_ERROR_PARSING_URL)    , "error parsing url"},
+	{ERR_REASON(OCSP_R_MISSING_OCSPSIGNING_USAGE), "missing ocspsigning usage"},
+	{ERR_REASON(OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE), "nextupdate before thisupdate"},
+	{ERR_REASON(OCSP_R_NOT_BASIC_RESPONSE)   , "not basic response"},
+	{ERR_REASON(OCSP_R_NO_CERTIFICATES_IN_CHAIN), "no certificates in chain"},
+	{ERR_REASON(OCSP_R_NO_CONTENT)           , "no content"},
+	{ERR_REASON(OCSP_R_NO_PUBLIC_KEY)        , "no public key"},
+	{ERR_REASON(OCSP_R_NO_RESPONSE_DATA)     , "no response data"},
+	{ERR_REASON(OCSP_R_NO_REVOKED_TIME)      , "no revoked time"},
+	{ERR_REASON(OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), "private key does not match certificate"},
+	{ERR_REASON(OCSP_R_REQUEST_NOT_SIGNED)   , "request not signed"},
+	{ERR_REASON(OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA), "response contains no revocation data"},
+	{ERR_REASON(OCSP_R_ROOT_CA_NOT_TRUSTED)  , "root ca not trusted"},
+	{ERR_REASON(OCSP_R_SERVER_READ_ERROR)    , "server read error"},
+	{ERR_REASON(OCSP_R_SERVER_RESPONSE_ERROR), "server response error"},
+	{ERR_REASON(OCSP_R_SERVER_RESPONSE_PARSE_ERROR), "server response parse error"},
+	{ERR_REASON(OCSP_R_SERVER_WRITE_ERROR)   , "server write error"},
+	{ERR_REASON(OCSP_R_SIGNATURE_FAILURE)    , "signature failure"},
+	{ERR_REASON(OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND), "signer certificate not found"},
+	{ERR_REASON(OCSP_R_STATUS_EXPIRED)       , "status expired"},
+	{ERR_REASON(OCSP_R_STATUS_NOT_YET_VALID) , "status not yet valid"},
+	{ERR_REASON(OCSP_R_STATUS_TOO_OLD)       , "status too old"},
+	{ERR_REASON(OCSP_R_UNKNOWN_MESSAGE_DIGEST), "unknown message digest"},
+	{ERR_REASON(OCSP_R_UNKNOWN_NID)          , "unknown nid"},
+	{ERR_REASON(OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE), "unsupported requestorname type"},
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_OCSP_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(OCSP_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, OCSP_str_functs);
+		ERR_load_strings(0, OCSP_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/ocsp/ocsp_ext.c b/crypto/libressl/crypto/ocsp/ocsp_ext.c
new file mode 100644
index 0000000000..50fe2c4da4
--- /dev/null
+++ b/crypto/libressl/crypto/ocsp/ocsp_ext.c
@@ -0,0 +1,607 @@
+/* $OpenBSD: ocsp_ext.c,v 1.13 2014/10/28 05:46:56 miod Exp $ */
+/* Written by Tom Titchener  for the OpenSSL
+ * project. */
+
+/* History:
+   This file was transfered to Richard Levitte from CertCo by Kathy
+   Weinhold in mid-spring 2000 to be included in OpenSSL or released
+   as a patch kit. */
+
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+/* Standard wrapper functions for extensions */
+
+/* OCSP request extensions */
+
+int
+OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x)
+{
+	return X509v3_get_ext_count(x->tbsRequest->requestExtensions);
+}
+
+int
+OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos)
+{
+	return X509v3_get_ext_by_NID(x->tbsRequest->requestExtensions, nid,
+	    lastpos);
+}
+
+int
+OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, int lastpos)
+{
+	return X509v3_get_ext_by_OBJ(x->tbsRequest->requestExtensions, obj,
+	    lastpos);
+}
+
+int
+OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos)
+{
+	return X509v3_get_ext_by_critical(x->tbsRequest->requestExtensions,
+	    crit, lastpos);
+}
+
+X509_EXTENSION *
+OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc)
+{
+	return X509v3_get_ext(x->tbsRequest->requestExtensions, loc);
+}
+
+X509_EXTENSION *
+OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc)
+{
+	return X509v3_delete_ext(x->tbsRequest->requestExtensions, loc);
+}
+
+void *
+OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx)
+{
+	return X509V3_get_d2i(x->tbsRequest->requestExtensions, nid, crit, idx);
+}
+
+int
+OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit,
+    unsigned long flags)
+{
+	return X509V3_add1_i2d(&x->tbsRequest->requestExtensions, nid, value,
+	    crit, flags);
+}
+
+int
+OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc)
+{
+	return X509v3_add_ext(&(x->tbsRequest->requestExtensions), ex,
+	    loc) != NULL;
+}
+
+/* Single extensions */
+
+int
+OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x)
+{
+	return X509v3_get_ext_count(x->singleRequestExtensions);
+}
+
+int
+OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos)
+{
+	return X509v3_get_ext_by_NID(x->singleRequestExtensions, nid, lastpos);
+}
+
+int
+OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos)
+{
+	return X509v3_get_ext_by_OBJ(x->singleRequestExtensions, obj, lastpos);
+}
+
+int
+OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos)
+{
+	return X509v3_get_ext_by_critical(x->singleRequestExtensions, crit,
+	    lastpos);
+}
+
+X509_EXTENSION *
+OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc)
+{
+	return X509v3_get_ext(x->singleRequestExtensions, loc);
+}
+
+X509_EXTENSION *
+OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc)
+{
+	return X509v3_delete_ext(x->singleRequestExtensions, loc);
+}
+
+void *
+OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx)
+{
+	return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx);
+}
+
+int
+OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit,
+    unsigned long flags)
+{
+	return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit,
+	    flags);
+}
+
+int
+OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc)
+{
+	return X509v3_add_ext(&(x->singleRequestExtensions), ex, loc) != NULL;
+}
+
+/* OCSP Basic response */
+
+int
+OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x)
+{
+	return X509v3_get_ext_count(x->tbsResponseData->responseExtensions);
+}
+
+int
+OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos)
+{
+	return X509v3_get_ext_by_NID(x->tbsResponseData->responseExtensions,
+	    nid, lastpos);
+}
+
+int
+OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, int lastpos)
+{
+	return X509v3_get_ext_by_OBJ(x->tbsResponseData->responseExtensions,
+	    obj, lastpos);
+}
+
+int
+OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, int lastpos)
+{
+	return X509v3_get_ext_by_critical(
+	    x->tbsResponseData->responseExtensions, crit, lastpos);
+}
+
+X509_EXTENSION *
+OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc)
+{
+	return X509v3_get_ext(x->tbsResponseData->responseExtensions, loc);
+}
+
+X509_EXTENSION *
+OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc)
+{
+	return X509v3_delete_ext(x->tbsResponseData->responseExtensions, loc);
+}
+
+void *
+OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, int *idx)
+{
+	return X509V3_get_d2i(x->tbsResponseData->responseExtensions, nid,
+	    crit, idx);
+}
+
+int
+OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, int crit,
+    unsigned long flags)
+{
+	return X509V3_add1_i2d(&x->tbsResponseData->responseExtensions, nid,
+	    value, crit, flags);
+}
+
+int
+OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc)
+{
+	return X509v3_add_ext(&(x->tbsResponseData->responseExtensions), ex,
+	    loc) != NULL;
+}
+
+/* OCSP single response extensions */
+
+int
+OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x)
+{
+	return X509v3_get_ext_count(x->singleExtensions);
+}
+
+int
+OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos)
+{
+	return X509v3_get_ext_by_NID(x->singleExtensions, nid, lastpos);
+}
+
+int
+OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj,
+    int lastpos)
+{
+	return X509v3_get_ext_by_OBJ(x->singleExtensions, obj, lastpos);
+}
+
+int
+OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, int lastpos)
+{
+	return X509v3_get_ext_by_critical(x->singleExtensions, crit, lastpos);
+}
+
+X509_EXTENSION *
+OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc)
+{
+	return X509v3_get_ext(x->singleExtensions, loc);
+}
+
+X509_EXTENSION *
+OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc)
+{
+	return X509v3_delete_ext(x->singleExtensions, loc);
+}
+
+void *
+OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, int *idx)
+{
+	return X509V3_get_d2i(x->singleExtensions, nid, crit, idx);
+}
+
+int
+OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, int crit,
+    unsigned long flags)
+{
+	return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags);
+}
+
+int
+OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc)
+{
+	return X509v3_add_ext(&(x->singleExtensions), ex, loc) != NULL;
+}
+
+/* also CRL Entry Extensions */
+#if 0
+ASN1_STRING *
+ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d, void *data,
+    STACK_OF(ASN1_OBJECT) *sk)
+{
+	int i;
+	unsigned char *p, *b = NULL;
+
+	if (data) {
+		if ((i = i2d(data, NULL)) <= 0)
+			goto err;
+		if (!(b = p = malloc(i)))
+			goto err;
+		if (i2d(data, &p) <= 0)
+			goto err;
+	} else if (sk) {
+		if ((i = i2d_ASN1_SET_OF_ASN1_OBJECT(sk, NULL,
+		    (I2D_OF(ASN1_OBJECT))i2d, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL,
+		    IS_SEQUENCE)) <= 0)
+			goto err;
+		if (!(b = p = malloc(i)))
+			goto err;
+		if (i2d_ASN1_SET_OF_ASN1_OBJECT(sk, &p,
+		    (I2D_OF(ASN1_OBJECT))i2d, V_ASN1_SEQUENCE,
+		    V_ASN1_UNIVERSAL, IS_SEQUENCE) <= 0)
+			goto err;
+	} else {
+		OCSPerr(OCSP_F_ASN1_STRING_ENCODE, OCSP_R_BAD_DATA);
+		goto err;
+	}
+	if (!s && !(s = ASN1_STRING_new()))
+		goto err;
+	if (!(ASN1_STRING_set(s, b, i)))
+		goto err;
+	free(b);
+	return s;
+
+err:
+	free(b);
+	return NULL;
+}
+#endif
+
+/* Nonce handling functions */
+
+/* Add a nonce to an extension stack. A nonce can be specificed or if NULL
+ * a random nonce will be generated.
+ * Note: OpenSSL 0.9.7d and later create an OCTET STRING containing the
+ * nonce, previous versions used the raw nonce.
+ */
+
+static int
+ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts, unsigned char *val, int len)
+{
+	unsigned char *tmpval;
+	ASN1_OCTET_STRING os;
+	int ret = 0;
+
+	if (len <= 0)
+		len = OCSP_DEFAULT_NONCE_LENGTH;
+	/* Create the OCTET STRING manually by writing out the header and
+	 * appending the content octets. This avoids an extra memory allocation
+	 * operation in some cases. Applications should *NOT* do this because
+	 * it relies on library internals.
+	 */
+	os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING);
+	os.data = malloc(os.length);
+	if (os.data == NULL)
+		goto err;
+	tmpval = os.data;
+	ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL);
+	if (val)
+		memcpy(tmpval, val, len);
+	else
+		arc4random_buf(tmpval, len);
+	if (!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce, &os, 0,
+	    X509V3_ADD_REPLACE))
+		goto err;
+	ret = 1;
+
+err:
+	free(os.data);
+	return ret;
+}
+
+/* Add nonce to an OCSP request */
+int
+OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len)
+{
+	return ocsp_add1_nonce(&req->tbsRequest->requestExtensions, val, len);
+}
+
+/* Same as above but for a response */
+int
+OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len)
+{
+	return ocsp_add1_nonce(&resp->tbsResponseData->responseExtensions, val,
+	    len);
+}
+
+/* Check nonce validity in a request and response.
+ * Return value reflects result:
+ *  1: nonces present and equal.
+ *  2: nonces both absent.
+ *  3: nonce present in response only.
+ *  0: nonces both present and not equal.
+ * -1: nonce in request only.
+ *
+ *  For most responders clients can check return > 0.
+ *  If responder doesn't handle nonces return != 0 may be
+ *  necessary. return == 0 is always an error.
+ */
+int
+OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs)
+{
+	/*
+	 * Since we are only interested in the presence or absence of
+	 * the nonce and comparing its value there is no need to use
+	 * the X509V3 routines: this way we can avoid them allocating an
+	 * ASN1_OCTET_STRING structure for the value which would be
+	 * freed immediately anyway.
+	 */
+	int req_idx, resp_idx;
+	X509_EXTENSION *req_ext, *resp_ext;
+
+	req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
+	resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs,
+	    NID_id_pkix_OCSP_Nonce, -1);
+	/* Check both absent */
+	if (req_idx < 0 && resp_idx < 0)
+		return 2;
+	/* Check in request only */
+	if (req_idx >= 0 && resp_idx < 0)
+		return -1;
+	/* Check in response but not request */
+	if (req_idx < 0 && resp_idx >= 0)
+		return 3;
+	/* Otherwise nonce in request and response so retrieve the extensions */
+	req_ext = OCSP_REQUEST_get_ext(req, req_idx);
+	resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx);
+	if (ASN1_OCTET_STRING_cmp(req_ext->value, resp_ext->value))
+		return 0;
+	return 1;
+}
+
+/* Copy the nonce value (if any) from an OCSP request to
+ * a response.
+ */
+int
+OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req)
+{
+	X509_EXTENSION *req_ext;
+	int req_idx;
+
+	/* Check for nonce in request */
+	req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
+	/* If no nonce that's OK */
+	if (req_idx < 0)
+		return 2;
+	req_ext = OCSP_REQUEST_get_ext(req, req_idx);
+	return OCSP_BASICRESP_add_ext(resp, req_ext, -1);
+}
+
+X509_EXTENSION *
+OCSP_crlID_new(char *url, long *n, char *tim)
+{
+	X509_EXTENSION *x = NULL;
+	OCSP_CRLID *cid = NULL;
+
+	if (!(cid = OCSP_CRLID_new()))
+		goto err;
+	if (url) {
+		if (!(cid->crlUrl = ASN1_IA5STRING_new()))
+			goto err;
+		if (!(ASN1_STRING_set(cid->crlUrl, url, -1)))
+			goto err;
+	}
+	if (n) {
+		if (!(cid->crlNum = ASN1_INTEGER_new()))
+			goto err;
+		if (!(ASN1_INTEGER_set(cid->crlNum, *n)))
+			goto err;
+	}
+	if (tim) {
+		if (!(cid->crlTime = ASN1_GENERALIZEDTIME_new()))
+			goto err;
+		if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim)))
+			goto err;
+	}
+	x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid);
+
+err:
+	if (cid)
+		OCSP_CRLID_free(cid);
+	return x;
+}
+
+/*   AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */
+X509_EXTENSION *
+OCSP_accept_responses_new(char **oids)
+{
+	int nid;
+	STACK_OF(ASN1_OBJECT) *sk = NULL;
+	ASN1_OBJECT *o = NULL;
+	X509_EXTENSION *x = NULL;
+
+	if (!(sk = sk_ASN1_OBJECT_new_null()))
+		return NULL;
+	while (oids && *oids) {
+		if ((nid = OBJ_txt2nid(*oids)) != NID_undef &&
+		    (o = OBJ_nid2obj(nid)))
+			if (sk_ASN1_OBJECT_push(sk, o) == 0) {
+				sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free);
+				return NULL;
+			}
+		oids++;
+	}
+	x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk);
+	sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free);
+	return x;
+}
+
+/*  ArchiveCutoff ::= GeneralizedTime */
+X509_EXTENSION *
+OCSP_archive_cutoff_new(char* tim)
+{
+	X509_EXTENSION *x = NULL;
+	ASN1_GENERALIZEDTIME *gt = NULL;
+
+	if (!(gt = ASN1_GENERALIZEDTIME_new()))
+		return NULL;
+	if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim)))
+		goto err;
+	x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt);
+
+err:
+	if (gt)
+		ASN1_GENERALIZEDTIME_free(gt);
+	return x;
+}
+
+/* per ACCESS_DESCRIPTION parameter are oids, of which there are currently
+ * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value.  This
+ * method forces NID_ad_ocsp and uniformResourceLocator [6] IA5String.
+ */
+X509_EXTENSION *
+OCSP_url_svcloc_new(X509_NAME* issuer, char **urls)
+{
+	X509_EXTENSION *x = NULL;
+	ASN1_IA5STRING *ia5 = NULL;
+	OCSP_SERVICELOC *sloc = NULL;
+	ACCESS_DESCRIPTION *ad = NULL;
+
+	if (!(sloc = OCSP_SERVICELOC_new()))
+		goto err;
+	if (!(sloc->issuer = X509_NAME_dup(issuer)))
+		goto err;
+	if (urls && *urls &&
+	    !(sloc->locator = sk_ACCESS_DESCRIPTION_new_null()))
+		goto err;
+	while (urls && *urls) {
+		if (!(ad = ACCESS_DESCRIPTION_new()))
+			goto err;
+		if (!(ad->method = OBJ_nid2obj(NID_ad_OCSP)))
+			goto err;
+		if (!(ad->location = GENERAL_NAME_new()))
+			goto err;
+		if (!(ia5 = ASN1_IA5STRING_new()))
+			goto err;
+		if (!ASN1_STRING_set((ASN1_STRING*)ia5, *urls, -1))
+			goto err;
+		ad->location->type = GEN_URI;
+		ad->location->d.ia5 = ia5;
+		ia5 = NULL;
+		if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad))
+			goto err;
+		ad = NULL;
+		urls++;
+	}
+	x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc);
+
+err:
+	if (ia5)
+		ASN1_IA5STRING_free(ia5);
+	if (ad)
+		ACCESS_DESCRIPTION_free(ad);
+	if (sloc)
+		OCSP_SERVICELOC_free(sloc);
+	return x;
+}
diff --git a/crypto/libressl/crypto/ocsp/ocsp_ht.c b/crypto/libressl/crypto/ocsp/ocsp_ht.c
new file mode 100644
index 0000000000..68e0baf3c6
--- /dev/null
+++ b/crypto/libressl/crypto/ocsp/ocsp_ht.c
@@ -0,0 +1,463 @@
+/* $OpenBSD: ocsp_ht.c,v 1.21 2014/07/25 06:05:32 doug Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Stateful OCSP request code, supporting non-blocking I/O */
+
+/* Opaque OCSP request status structure */
+
+struct ocsp_req_ctx_st {
+	int state;		/* Current I/O state */
+	unsigned char *iobuf;	/* Line buffer */
+	int iobuflen;		/* Line buffer length */
+	BIO *io;		/* BIO to perform I/O with */
+	BIO *mem;		/* Memory BIO response is built into */
+	unsigned long asn1_len;	/* ASN1 length of response */
+};
+
+#define OCSP_MAX_REQUEST_LENGTH	(100 * 1024)
+#define OCSP_MAX_LINE_LEN	4096;
+
+/* OCSP states */
+
+/* If set no reading should be performed */
+#define OHS_NOREAD		0x1000
+/* Error condition */
+#define OHS_ERROR		(0 | OHS_NOREAD)
+/* First line being read */
+#define OHS_FIRSTLINE		1
+/* MIME headers being read */
+#define OHS_HEADERS		2
+/* OCSP initial header (tag + length) being read */
+#define OHS_ASN1_HEADER		3
+/* OCSP content octets being read */
+#define OHS_ASN1_CONTENT	4
+/* Request being sent */
+#define OHS_ASN1_WRITE		(6 | OHS_NOREAD)
+/* Request being flushed */
+#define OHS_ASN1_FLUSH		(7 | OHS_NOREAD)
+/* Completed */
+#define OHS_DONE		(8 | OHS_NOREAD)
+
+
+static int parse_http_line1(char *line);
+
+void
+OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx)
+{
+	if (rctx == NULL)
+		return;
+
+	BIO_free(rctx->mem);
+	free(rctx->iobuf);
+	free(rctx);
+}
+
+int
+OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req)
+{
+	if (BIO_printf(rctx->mem, "Content-Type: application/ocsp-request\r\n"
+	    "Content-Length: %d\r\n\r\n", i2d_OCSP_REQUEST(req, NULL)) <= 0)
+		return 0;
+	if (i2d_OCSP_REQUEST_bio(rctx->mem, req) <= 0)
+		return 0;
+	rctx->state = OHS_ASN1_WRITE;
+	rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL);
+	return 1;
+}
+
+int
+OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, const char *name,
+    const char *value)
+{
+	if (!name)
+		return 0;
+	if (BIO_puts(rctx->mem, name) <= 0)
+		return 0;
+	if (value) {
+		if (BIO_write(rctx->mem, ": ", 2) != 2)
+			return 0;
+		if (BIO_puts(rctx->mem, value) <= 0)
+			return 0;
+	}
+	if (BIO_write(rctx->mem, "\r\n", 2) != 2)
+		return 0;
+	return 1;
+}
+
+OCSP_REQ_CTX *
+OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req, int maxline)
+{
+	OCSP_REQ_CTX *rctx;
+
+	rctx = malloc(sizeof(OCSP_REQ_CTX));
+	if (rctx == NULL)
+		return NULL;
+	rctx->state = OHS_ERROR;
+	rctx->mem = BIO_new(BIO_s_mem());
+	rctx->io = io;
+	rctx->asn1_len = 0;
+	if (maxline > 0)
+		rctx->iobuflen = maxline;
+	else
+		rctx->iobuflen = OCSP_MAX_LINE_LEN;
+	rctx->iobuf = malloc(rctx->iobuflen);
+	if (!rctx->iobuf) {
+		BIO_free(rctx->mem);
+		free(rctx);
+		return NULL;
+	}
+	if (!path)
+		path = "/";
+
+	if (BIO_printf(rctx->mem, "POST %s HTTP/1.0\r\n", path) <= 0) {
+		free(rctx->iobuf);
+		BIO_free(rctx->mem);
+		free(rctx);
+		return NULL;
+	}
+
+	if (req && !OCSP_REQ_CTX_set1_req(rctx, req)) {
+		free(rctx->iobuf);
+		BIO_free(rctx->mem);
+		free(rctx);
+		return NULL;
+	}
+
+	return rctx;
+}
+
+/* Parse the HTTP response. This will look like this:
+ * "HTTP/1.0 200 OK". We need to obtain the numeric code and
+ * (optional) informational message.
+ */
+static int
+parse_http_line1(char *line)
+{
+	int retcode;
+	char *p, *q, *r;
+
+	/* Skip to first white space (passed protocol info) */
+	for (p = line; *p && !isspace((unsigned char)*p); p++)
+		continue;
+	if (!*p) {
+		OCSPerr(OCSP_F_PARSE_HTTP_LINE1,
+		    OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
+		return 0;
+	}
+
+	/* Skip past white space to start of response code */
+	while (*p && isspace((unsigned char)*p))
+		p++;
+	if (!*p) {
+		OCSPerr(OCSP_F_PARSE_HTTP_LINE1,
+		    OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
+		return 0;
+	}
+
+	/* Find end of response code: first whitespace after start of code */
+	for (q = p; *q && !isspace((unsigned char)*q); q++)
+		continue;
+	if (!*q) {
+		OCSPerr(OCSP_F_PARSE_HTTP_LINE1,
+		    OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
+		return 0;
+	}
+
+	/* Set end of response code and start of message */
+	*q++ = 0;
+
+	/* Attempt to parse numeric code */
+	retcode = strtoul(p, &r, 10);
+
+	if (*r)
+		return 0;
+
+	/* Skip over any leading white space in message */
+	while (*q && isspace((unsigned char)*q))
+		q++;
+	if (*q) {
+		/* Finally zap any trailing white space in message (include
+		 * CRLF) */
+
+		/* We know q has a non white space character so this is OK */
+		for (r = q + strlen(q) - 1; isspace((unsigned char)*r); r--)
+			*r = 0;
+	}
+	if (retcode != 200) {
+		OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_ERROR);
+		if (!*q)
+			ERR_asprintf_error_data("Code=%s", p);
+		else
+			ERR_asprintf_error_data("Code=%s,Reason=%s", p, q);
+		return 0;
+	}
+
+	return 1;
+}
+
+int
+OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx)
+{
+	int i, n;
+	const unsigned char *p;
+
+next_io:
+	if (!(rctx->state & OHS_NOREAD)) {
+		n = BIO_read(rctx->io, rctx->iobuf, rctx->iobuflen);
+
+		if (n <= 0) {
+			if (BIO_should_retry(rctx->io))
+				return -1;
+			return 0;
+		}
+
+		/* Write data to memory BIO */
+		if (BIO_write(rctx->mem, rctx->iobuf, n) != n)
+			return 0;
+	}
+
+	switch (rctx->state) {
+	case OHS_ASN1_WRITE:
+		n = BIO_get_mem_data(rctx->mem, &p);
+		i = BIO_write(rctx->io,
+		    p + (n - rctx->asn1_len), rctx->asn1_len);
+		if (i <= 0) {
+			if (BIO_should_retry(rctx->io))
+				return -1;
+			rctx->state = OHS_ERROR;
+			return 0;
+		}
+
+		rctx->asn1_len -= i;
+		if (rctx->asn1_len > 0)
+			goto next_io;
+
+		rctx->state = OHS_ASN1_FLUSH;
+
+		(void)BIO_reset(rctx->mem);
+		/* FALLTHROUGH */
+
+	case OHS_ASN1_FLUSH:
+		i = BIO_flush(rctx->io);
+		if (i > 0) {
+			rctx->state = OHS_FIRSTLINE;
+			goto next_io;
+		}
+
+		if (BIO_should_retry(rctx->io))
+			return -1;
+
+		rctx->state = OHS_ERROR;
+		return 0;
+
+	case OHS_ERROR:
+		return 0;
+
+	case OHS_FIRSTLINE:
+	case OHS_HEADERS:
+		/* Attempt to read a line in */
+next_line:
+		/* Due to &%^*$" memory BIO behaviour with BIO_gets we
+		 * have to check there's a complete line in there before
+		 * calling BIO_gets or we'll just get a partial read.
+		 */
+		n = BIO_get_mem_data(rctx->mem, &p);
+		if ((n <= 0) || !memchr(p, '\n', n)) {
+			if (n >= rctx->iobuflen) {
+				rctx->state = OHS_ERROR;
+				return 0;
+			}
+			goto next_io;
+		}
+		n = BIO_gets(rctx->mem, (char *)rctx->iobuf, rctx->iobuflen);
+		if (n <= 0) {
+			if (BIO_should_retry(rctx->mem))
+				goto next_io;
+			rctx->state = OHS_ERROR;
+			return 0;
+		}
+
+		/* Don't allow excessive lines */
+		if (n == rctx->iobuflen) {
+			rctx->state = OHS_ERROR;
+			return 0;
+		}
+
+		/* First line */
+		if (rctx->state == OHS_FIRSTLINE) {
+			if (parse_http_line1((char *)rctx->iobuf)) {
+				rctx->state = OHS_HEADERS;
+				goto next_line;
+			} else {
+				rctx->state = OHS_ERROR;
+				return 0;
+			}
+		} else {
+			/* Look for blank line: end of headers */
+			for (p = rctx->iobuf; *p; p++) {
+				if ((*p != '\r') && (*p != '\n'))
+					break;
+			}
+			if (*p)
+				goto next_line;
+
+			rctx->state = OHS_ASN1_HEADER;
+		}
+		/* FALLTRHOUGH */
+
+	case OHS_ASN1_HEADER:
+		/* Now reading ASN1 header: can read at least 2 bytes which
+		 * is enough for ASN1 SEQUENCE header and either length field
+		 * or at least the length of the length field.
+		 */
+		n = BIO_get_mem_data(rctx->mem, &p);
+		if (n < 2)
+			goto next_io;
+
+		/* Check it is an ASN1 SEQUENCE */
+		if (*p++ != (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) {
+			rctx->state = OHS_ERROR;
+			return 0;
+		}
+
+		/* Check out length field */
+		if (*p & 0x80) {
+			/* If MSB set on initial length octet we can now
+			 * always read 6 octets: make sure we have them.
+			 */
+			if (n < 6)
+				goto next_io;
+			n = *p & 0x7F;
+			/* Not NDEF or excessive length */
+			if (!n || (n > 4)) {
+				rctx->state = OHS_ERROR;
+				return 0;
+			}
+			p++;
+			rctx->asn1_len = 0;
+			for (i = 0; i < n; i++) {
+				rctx->asn1_len <<= 8;
+				rctx->asn1_len |= *p++;
+			}
+
+			if (rctx->asn1_len > OCSP_MAX_REQUEST_LENGTH) {
+				rctx->state = OHS_ERROR;
+				return 0;
+			}
+
+			rctx->asn1_len += n + 2;
+		} else
+			rctx->asn1_len = *p + 2;
+
+		rctx->state = OHS_ASN1_CONTENT;
+
+		/* FALLTHROUGH */
+
+	case OHS_ASN1_CONTENT:
+		n = BIO_get_mem_data(rctx->mem, &p);
+		if (n < (int)rctx->asn1_len)
+			goto next_io;
+
+		*presp = d2i_OCSP_RESPONSE(NULL, &p, rctx->asn1_len);
+		if (*presp) {
+			rctx->state = OHS_DONE;
+			return 1;
+		}
+
+		rctx->state = OHS_ERROR;
+		return 0;
+
+	case OHS_DONE:
+		return 1;
+	}
+
+	return 0;
+}
+
+/* Blocking OCSP request handler: now a special case of non-blocking I/O */
+OCSP_RESPONSE *
+OCSP_sendreq_bio(BIO *b, char *path, OCSP_REQUEST *req)
+{
+	OCSP_RESPONSE *resp = NULL;
+	OCSP_REQ_CTX *ctx;
+	int rv;
+
+	ctx = OCSP_sendreq_new(b, path, req, -1);
+	if (ctx == NULL)
+		return NULL;
+
+	do {
+		rv = OCSP_sendreq_nbio(&resp, ctx);
+	} while ((rv == -1) && BIO_should_retry(b));
+
+	OCSP_REQ_CTX_free(ctx);
+
+	if (rv)
+		return resp;
+
+	return NULL;
+}
diff --git a/crypto/libressl/crypto/ocsp/ocsp_lib.c b/crypto/libressl/crypto/ocsp/ocsp_lib.c
new file mode 100644
index 0000000000..d7cc1f8e14
--- /dev/null
+++ b/crypto/libressl/crypto/ocsp/ocsp_lib.c
@@ -0,0 +1,282 @@
+/* $OpenBSD: ocsp_lib.c,v 1.17 2015/02/10 04:21:50 jsing Exp $ */
+/* Written by Tom Titchener  for the OpenSSL
+ * project. */
+
+/* History:
+   This file was transfered to Richard Levitte from CertCo by Kathy
+   Weinhold in mid-spring 2000 to be included in OpenSSL or released
+   as a patch kit. */
+
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Convert a certificate and its issuer to an OCSP_CERTID */
+
+OCSP_CERTID *
+OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer)
+{
+	X509_NAME *iname;
+	ASN1_INTEGER *serial;
+	ASN1_BIT_STRING *ikey;
+
+#ifndef OPENSSL_NO_SHA1
+	if (!dgst)
+		dgst = EVP_sha1();
+#endif
+	if (subject) {
+		iname = X509_get_issuer_name(subject);
+		serial = X509_get_serialNumber(subject);
+	} else {
+		iname = X509_get_subject_name(issuer);
+		serial = NULL;
+	}
+	ikey = X509_get0_pubkey_bitstr(issuer);
+	return OCSP_cert_id_new(dgst, iname, ikey, serial);
+}
+
+OCSP_CERTID *
+OCSP_cert_id_new(const EVP_MD *dgst, X509_NAME *issuerName,
+    ASN1_BIT_STRING* issuerKey, ASN1_INTEGER *serialNumber)
+{
+	int nid;
+	unsigned int i;
+	X509_ALGOR *alg;
+	OCSP_CERTID *cid = NULL;
+	unsigned char md[EVP_MAX_MD_SIZE];
+
+	if (!(cid = OCSP_CERTID_new()))
+		goto err;
+
+	alg = cid->hashAlgorithm;
+	if (alg->algorithm != NULL)
+		ASN1_OBJECT_free(alg->algorithm);
+	if ((nid = EVP_MD_type(dgst)) == NID_undef) {
+		OCSPerr(OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_UNKNOWN_NID);
+		goto err;
+	}
+	if (!(alg->algorithm = OBJ_nid2obj(nid)))
+		goto err;
+	if ((alg->parameter = ASN1_TYPE_new()) == NULL)
+		goto err;
+	alg->parameter->type = V_ASN1_NULL;
+
+	if (!X509_NAME_digest(issuerName, dgst, md, &i))
+		goto digerr;
+	if (!(ASN1_OCTET_STRING_set(cid->issuerNameHash, md, i)))
+		goto err;
+
+	/* Calculate the issuerKey hash, excluding tag and length */
+	if (!EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst, NULL))
+		goto err;
+
+	if (!(ASN1_OCTET_STRING_set(cid->issuerKeyHash, md, i)))
+		goto err;
+
+	if (serialNumber) {
+		ASN1_INTEGER_free(cid->serialNumber);
+		if (!(cid->serialNumber = ASN1_INTEGER_dup(serialNumber)))
+			goto err;
+	}
+	return cid;
+
+digerr:
+	OCSPerr(OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_DIGEST_ERR);
+err:
+	if (cid)
+		OCSP_CERTID_free(cid);
+	return NULL;
+}
+
+int
+OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
+{
+	int ret;
+
+	ret = OBJ_cmp(a->hashAlgorithm->algorithm, b->hashAlgorithm->algorithm);
+	if (ret)
+		return ret;
+	ret = ASN1_OCTET_STRING_cmp(a->issuerNameHash, b->issuerNameHash);
+	if (ret)
+		return ret;
+	return ASN1_OCTET_STRING_cmp(a->issuerKeyHash, b->issuerKeyHash);
+}
+
+int
+OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
+{
+	int ret;
+
+	ret = OCSP_id_issuer_cmp(a, b);
+	if (ret)
+		return ret;
+	return ASN1_INTEGER_cmp(a->serialNumber, b->serialNumber);
+}
+
+/* Parse a URL and split it up into host, port and path components and whether
+ * it is SSL.
+ */
+int
+OCSP_parse_url(char *url, char **phost, char **pport, char **ppath, int *pssl)
+{
+	char *p, *buf;
+	char *host, *port;
+
+	*phost = NULL;
+	*pport = NULL;
+	*ppath = NULL;
+
+	/* dup the buffer since we are going to mess with it */
+	buf = url ? strdup(url) : NULL;
+	if (!buf)
+		goto mem_err;
+
+	/* Check for initial colon */
+	p = strchr(buf, ':');
+	if (!p)
+		goto parse_err;
+
+	*(p++) = '\0';
+
+	if (!strcmp(buf, "http")) {
+		*pssl = 0;
+		port = "80";
+	} else if (!strcmp(buf, "https")) {
+		*pssl = 1;
+		port = "443";
+	} else
+		goto parse_err;
+
+	/* Check for double slash */
+	if ((p[0] != '/') || (p[1] != '/'))
+		goto parse_err;
+
+	p += 2;
+
+	host = p;
+
+	/* Check for trailing part of path */
+	p = strchr(p, '/');
+	if (!p)
+		*ppath = strdup("/");
+	else {
+		*ppath = strdup(p);
+		/* Set start of path to 0 so hostname is valid */
+		*p = '\0';
+	}
+
+	if (!*ppath)
+		goto mem_err;
+
+	/* Look for optional ':' for port number */
+	if ((p = strchr(host, ':'))) {
+		*p = 0;
+		port = p + 1;
+	} else {
+		/* Not found: set default port */
+		if (*pssl)
+			port = "443";
+		else
+			port = "80";
+	}
+
+	*pport = strdup(port);
+	if (!*pport)
+		goto mem_err;
+
+	*phost = strdup(host);
+
+	if (!*phost)
+		goto mem_err;
+
+	free(buf);
+
+	return 1;
+
+mem_err:
+	OCSPerr(OCSP_F_OCSP_PARSE_URL, ERR_R_MALLOC_FAILURE);
+	goto err;
+
+parse_err:
+	OCSPerr(OCSP_F_OCSP_PARSE_URL, OCSP_R_ERROR_PARSING_URL);
+
+err:
+	free(buf);
+	free(*ppath);
+	free(*pport);
+	free(*phost);
+	*phost = NULL;
+	*pport = NULL;
+	*ppath = NULL;
+	return 0;
+}
+
+
+OCSP_CERTID *
+OCSP_CERTID_dup(OCSP_CERTID *x)
+{
+	return ASN1_item_dup(&OCSP_CERTID_it, x);
+}
diff --git a/crypto/libressl/crypto/ocsp/ocsp_prn.c b/crypto/libressl/crypto/ocsp/ocsp_prn.c
new file mode 100644
index 0000000000..e52e7aeae9
--- /dev/null
+++ b/crypto/libressl/crypto/ocsp/ocsp_prn.c
@@ -0,0 +1,312 @@
+/* $OpenBSD: ocsp_prn.c,v 1.7 2014/06/12 15:49:30 deraadt Exp $ */
+/* Written by Tom Titchener  for the OpenSSL
+ * project. */
+
+/* History:
+   This file was originally part of ocsp.c and was transfered to Richard
+   Levitte from CertCo by Kathy Weinhold in mid-spring 2000 to be included
+   in OpenSSL or released as a patch kit. */
+
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+static int
+ocsp_certid_print(BIO *bp, OCSP_CERTID* a, int indent)
+{
+	BIO_printf(bp, "%*sCertificate ID:\n", indent, "");
+	indent += 2;
+	BIO_printf(bp, "%*sHash Algorithm: ", indent, "");
+	i2a_ASN1_OBJECT(bp, a->hashAlgorithm->algorithm);
+	BIO_printf(bp, "\n%*sIssuer Name Hash: ", indent, "");
+	i2a_ASN1_STRING(bp, a->issuerNameHash, V_ASN1_OCTET_STRING);
+	BIO_printf(bp, "\n%*sIssuer Key Hash: ", indent, "");
+	i2a_ASN1_STRING(bp, a->issuerKeyHash, V_ASN1_OCTET_STRING);
+	BIO_printf(bp, "\n%*sSerial Number: ", indent, "");
+	i2a_ASN1_INTEGER(bp, a->serialNumber);
+	BIO_printf(bp, "\n");
+	return 1;
+}
+
+typedef struct {
+	long t;
+	const char *m;
+} OCSP_TBLSTR;
+
+static const char *
+table2string(long s, const OCSP_TBLSTR *ts, int len)
+{
+	const OCSP_TBLSTR *p;
+
+	for (p = ts; p < ts + len; p++)
+		if (p->t == s)
+			return p->m;
+	return "(UNKNOWN)";
+}
+
+const char *
+OCSP_response_status_str(long s)
+{
+	static const OCSP_TBLSTR rstat_tbl[] = {
+		{ OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful" },
+		{ OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest" },
+		{ OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror" },
+		{ OCSP_RESPONSE_STATUS_TRYLATER, "trylater" },
+		{ OCSP_RESPONSE_STATUS_SIGREQUIRED, "sigrequired" },
+		{ OCSP_RESPONSE_STATUS_UNAUTHORIZED, "unauthorized" }
+	};
+	return table2string(s, rstat_tbl, 6);
+}
+
+const char *
+OCSP_cert_status_str(long s)
+{
+	static const OCSP_TBLSTR cstat_tbl[] = {
+		{ V_OCSP_CERTSTATUS_GOOD, "good" },
+		{ V_OCSP_CERTSTATUS_REVOKED, "revoked" },
+		{ V_OCSP_CERTSTATUS_UNKNOWN, "unknown" }
+	};
+	return table2string(s, cstat_tbl, 3);
+}
+
+const char *
+OCSP_crl_reason_str(long s)
+{
+	static const OCSP_TBLSTR reason_tbl[] = {
+		{ OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified" },
+		{ OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise" },
+		{ OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise" },
+		{ OCSP_REVOKED_STATUS_AFFILIATIONCHANGED, "affiliationChanged" },
+		{ OCSP_REVOKED_STATUS_SUPERSEDED, "superseded" },
+		{ OCSP_REVOKED_STATUS_CESSATIONOFOPERATION, "cessationOfOperation" },
+		{ OCSP_REVOKED_STATUS_CERTIFICATEHOLD, "certificateHold" },
+		{ OCSP_REVOKED_STATUS_REMOVEFROMCRL, "removeFromCRL" }
+	};
+	return table2string(s, reason_tbl, 8);
+}
+
+int
+OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* o, unsigned long flags)
+{
+	int i;
+	long l;
+	OCSP_CERTID* cid = NULL;
+	OCSP_ONEREQ *one = NULL;
+	OCSP_REQINFO *inf = o->tbsRequest;
+	OCSP_SIGNATURE *sig = o->optionalSignature;
+
+	if (BIO_write(bp, "OCSP Request Data:\n", 19) <= 0)
+		goto err;
+	l = ASN1_INTEGER_get(inf->version);
+	if (BIO_printf(bp, "    Version: %lu (0x%lx)", l+1, l) <= 0)
+		goto err;
+	if (inf->requestorName != NULL) {
+		if (BIO_write(bp, "\n    Requestor Name: ", 21) <= 0)
+			goto err;
+		GENERAL_NAME_print(bp, inf->requestorName);
+	}
+	if (BIO_write(bp, "\n    Requestor List:\n", 21) <= 0)
+		goto err;
+	for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++) {
+		one = sk_OCSP_ONEREQ_value(inf->requestList, i);
+		cid = one->reqCert;
+		ocsp_certid_print(bp, cid, 8);
+		if (!X509V3_extensions_print(bp, "Request Single Extensions",
+		    one->singleRequestExtensions, flags, 8))
+			goto err;
+	}
+	if (!X509V3_extensions_print(bp, "Request Extensions",
+	    inf->requestExtensions, flags, 4))
+		goto err;
+	if (sig) {
+		if (X509_signature_print(bp, sig->signatureAlgorithm,
+		    sig->signature) == 0)
+			goto err;
+		for (i = 0; i < sk_X509_num(sig->certs); i++) {
+			if (X509_print(bp, sk_X509_value(sig->certs, i)) == 0)
+				goto err;
+			if (PEM_write_bio_X509(bp,
+			    sk_X509_value(sig->certs, i)) == 0)
+				goto err;
+		}
+	}
+	return 1;
+
+err:
+	return 0;
+}
+
+int
+OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags)
+{
+	int i, ret = 0;
+	long l;
+	OCSP_CERTID *cid = NULL;
+	OCSP_BASICRESP *br = NULL;
+	OCSP_RESPID *rid = NULL;
+	OCSP_RESPDATA  *rd = NULL;
+	OCSP_CERTSTATUS *cst = NULL;
+	OCSP_REVOKEDINFO *rev = NULL;
+	OCSP_SINGLERESP *single = NULL;
+	OCSP_RESPBYTES *rb = o->responseBytes;
+
+	if (BIO_puts(bp, "OCSP Response Data:\n") <= 0)
+		goto err;
+	l = ASN1_ENUMERATED_get(o->responseStatus);
+	if (BIO_printf(bp, "    OCSP Response Status: %s (0x%lx)\n",
+	    OCSP_response_status_str(l), l) <= 0)
+		goto err;
+	if (rb == NULL)
+		return 1;
+	if (BIO_puts(bp, "    Response Type: ") <= 0)
+		goto err;
+	if (i2a_ASN1_OBJECT(bp, rb->responseType) <= 0)
+		goto err;
+	if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) {
+		BIO_puts(bp, " (unknown response type)\n");
+		return 1;
+	}
+
+	i = ASN1_STRING_length(rb->response);
+	if (!(br = OCSP_response_get1_basic(o)))
+		goto err;
+	rd = br->tbsResponseData;
+	l = ASN1_INTEGER_get(rd->version);
+	if (BIO_printf(bp, "\n    Version: %lu (0x%lx)\n", l+1, l) <= 0)
+		goto err;
+	if (BIO_puts(bp, "    Responder Id: ") <= 0)
+		goto err;
+
+	rid = rd->responderId;
+	switch (rid->type) {
+	case V_OCSP_RESPID_NAME:
+		X509_NAME_print_ex(bp, rid->value.byName, 0, XN_FLAG_ONELINE);
+		break;
+	case V_OCSP_RESPID_KEY:
+		i2a_ASN1_STRING(bp, rid->value.byKey, V_ASN1_OCTET_STRING);
+		break;
+	}
+
+	if (BIO_printf(bp, "\n    Produced At: ")<=0)
+		goto err;
+	if (!ASN1_GENERALIZEDTIME_print(bp, rd->producedAt))
+		goto err;
+	if (BIO_printf(bp, "\n    Responses:\n") <= 0)
+		goto err;
+	for (i = 0; i < sk_OCSP_SINGLERESP_num(rd->responses); i++) {
+		if (! sk_OCSP_SINGLERESP_value(rd->responses, i))
+			continue;
+		single = sk_OCSP_SINGLERESP_value(rd->responses, i);
+		cid = single->certId;
+		if (ocsp_certid_print(bp, cid, 4) <= 0)
+			goto err;
+		cst = single->certStatus;
+		if (BIO_printf(bp, "    Cert Status: %s",
+		    OCSP_cert_status_str(cst->type)) <= 0)
+			goto err;
+		if (cst->type == V_OCSP_CERTSTATUS_REVOKED) {
+			rev = cst->value.revoked;
+			if (BIO_printf(bp, "\n    Revocation Time: ") <= 0)
+				goto err;
+			if (!ASN1_GENERALIZEDTIME_print(bp,
+			    rev->revocationTime))
+				goto err;
+			if (rev->revocationReason) {
+				l = ASN1_ENUMERATED_get(rev->revocationReason);
+				if (BIO_printf(bp,
+				    "\n    Revocation Reason: %s (0x%lx)",
+				    OCSP_crl_reason_str(l), l) <= 0)
+					goto err;
+			}
+		}
+		if (BIO_printf(bp, "\n    This Update: ") <= 0)
+			goto err;
+		if (!ASN1_GENERALIZEDTIME_print(bp, single->thisUpdate))
+			goto err;
+		if (single->nextUpdate) {
+			if (BIO_printf(bp, "\n    Next Update: ") <= 0)
+				goto err;
+			if (!ASN1_GENERALIZEDTIME_print(bp, single->nextUpdate))
+				goto err;
+		}
+		if (BIO_write(bp, "\n", 1) <= 0)
+			goto err;
+		if (!X509V3_extensions_print(bp, "Response Single Extensions",
+		    single->singleExtensions, flags, 8))
+			goto err;
+		if (BIO_write(bp, "\n", 1) <= 0)
+			goto err;
+	}
+	if (!X509V3_extensions_print(bp, "Response Extensions",
+	    rd->responseExtensions, flags, 4))
+		goto err;
+	if (X509_signature_print(bp, br->signatureAlgorithm, br->signature) <=
+	    0)
+		goto err;
+
+	for (i = 0; i < sk_X509_num(br->certs); i++) {
+		X509_print(bp, sk_X509_value(br->certs, i));
+		PEM_write_bio_X509(bp, sk_X509_value(br->certs, i));
+	}
+
+	ret = 1;
+
+err:
+	OCSP_BASICRESP_free(br);
+	return ret;
+}
diff --git a/crypto/libressl/crypto/ocsp/ocsp_srv.c b/crypto/libressl/crypto/ocsp/ocsp_srv.c
new file mode 100644
index 0000000000..20c99624f8
--- /dev/null
+++ b/crypto/libressl/crypto/ocsp/ocsp_srv.c
@@ -0,0 +1,276 @@
+/* $OpenBSD: ocsp_srv.c,v 1.7 2014/10/18 17:20:40 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Utility functions related to sending OCSP responses and extracting
+ * relevant information from the request.
+ */
+
+int
+OCSP_request_onereq_count(OCSP_REQUEST *req)
+{
+	return sk_OCSP_ONEREQ_num(req->tbsRequest->requestList);
+}
+
+OCSP_ONEREQ *
+OCSP_request_onereq_get0(OCSP_REQUEST *req, int i)
+{
+	return sk_OCSP_ONEREQ_value(req->tbsRequest->requestList, i);
+}
+
+OCSP_CERTID *
+OCSP_onereq_get0_id(OCSP_ONEREQ *one)
+{
+	return one->reqCert;
+}
+
+int
+OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd,
+    ASN1_OCTET_STRING **pikeyHash, ASN1_INTEGER **pserial, OCSP_CERTID *cid)
+{
+	if (!cid)
+		return 0;
+	if (pmd)
+		*pmd = cid->hashAlgorithm->algorithm;
+	if (piNameHash)
+		*piNameHash = cid->issuerNameHash;
+	if (pikeyHash)
+		*pikeyHash = cid->issuerKeyHash;
+	if (pserial)
+		*pserial = cid->serialNumber;
+	return 1;
+}
+
+int
+OCSP_request_is_signed(OCSP_REQUEST *req)
+{
+	if (req->optionalSignature)
+		return 1;
+	return 0;
+}
+
+/* Create an OCSP response and encode an optional basic response */
+OCSP_RESPONSE *
+OCSP_response_create(int status, OCSP_BASICRESP *bs)
+{
+	OCSP_RESPONSE *rsp = NULL;
+
+	if (!(rsp = OCSP_RESPONSE_new()))
+		goto err;
+	if (!(ASN1_ENUMERATED_set(rsp->responseStatus, status)))
+		goto err;
+	if (!bs)
+		return rsp;
+	if (!(rsp->responseBytes = OCSP_RESPBYTES_new()))
+		goto err;
+	rsp->responseBytes->responseType = OBJ_nid2obj(NID_id_pkix_OCSP_basic);
+	if (!ASN1_item_pack(bs, ASN1_ITEM_rptr(OCSP_BASICRESP),
+	    &rsp->responseBytes->response))
+		goto err;
+	return rsp;
+
+err:
+	if (rsp)
+		OCSP_RESPONSE_free(rsp);
+	return NULL;
+}
+
+OCSP_SINGLERESP *
+OCSP_basic_add1_status(OCSP_BASICRESP *rsp, OCSP_CERTID *cid, int status,
+    int reason, ASN1_TIME *revtime, ASN1_TIME *thisupd, ASN1_TIME *nextupd)
+{
+	OCSP_SINGLERESP *single = NULL;
+	OCSP_CERTSTATUS *cs;
+	OCSP_REVOKEDINFO *ri;
+
+	if (!rsp->tbsResponseData->responses &&
+	    !(rsp->tbsResponseData->responses = sk_OCSP_SINGLERESP_new_null()))
+		goto err;
+
+	if (!(single = OCSP_SINGLERESP_new()))
+		goto err;
+
+	if (!ASN1_TIME_to_generalizedtime(thisupd, &single->thisUpdate))
+		goto err;
+	if (nextupd &&
+	    !ASN1_TIME_to_generalizedtime(nextupd, &single->nextUpdate))
+		goto err;
+
+	OCSP_CERTID_free(single->certId);
+
+	if (!(single->certId = OCSP_CERTID_dup(cid)))
+		goto err;
+
+	cs = single->certStatus;
+	switch (cs->type = status) {
+	case V_OCSP_CERTSTATUS_REVOKED:
+		if (!revtime) {
+			OCSPerr(OCSP_F_OCSP_BASIC_ADD1_STATUS,
+			    OCSP_R_NO_REVOKED_TIME);
+			goto err;
+		}
+		if (!(cs->value.revoked = ri = OCSP_REVOKEDINFO_new()))
+			goto err;
+		if (!ASN1_TIME_to_generalizedtime(revtime, &ri->revocationTime))
+			goto err;
+		if (reason != OCSP_REVOKED_STATUS_NOSTATUS) {
+			if (!(ri->revocationReason = ASN1_ENUMERATED_new()))
+				goto err;
+			if (!(ASN1_ENUMERATED_set(ri->revocationReason,
+			    reason)))
+				goto err;
+		}
+		break;
+
+	case V_OCSP_CERTSTATUS_GOOD:
+		cs->value.good = ASN1_NULL_new();
+		break;
+
+	case V_OCSP_CERTSTATUS_UNKNOWN:
+		cs->value.unknown = ASN1_NULL_new();
+		break;
+
+	default:
+		goto err;
+	}
+	if (!(sk_OCSP_SINGLERESP_push(rsp->tbsResponseData->responses, single)))
+		goto err;
+	return single;
+
+err:
+	OCSP_SINGLERESP_free(single);
+	return NULL;
+}
+
+/* Add a certificate to an OCSP request */
+int
+OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert)
+{
+	if (!resp->certs && !(resp->certs = sk_X509_new_null()))
+		return 0;
+
+	if (!sk_X509_push(resp->certs, cert))
+		return 0;
+	CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
+	return 1;
+}
+
+int
+OCSP_basic_sign(OCSP_BASICRESP *brsp, X509 *signer, EVP_PKEY *key,
+    const EVP_MD *dgst, STACK_OF(X509) *certs, unsigned long flags)
+{
+	int i;
+	OCSP_RESPID *rid;
+
+	if (!X509_check_private_key(signer, key)) {
+		OCSPerr(OCSP_F_OCSP_BASIC_SIGN,
+		    OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+		goto err;
+	}
+
+	if (!(flags & OCSP_NOCERTS)) {
+		if (!OCSP_basic_add1_cert(brsp, signer))
+			goto err;
+		for (i = 0; i < sk_X509_num(certs); i++) {
+			X509 *tmpcert = sk_X509_value(certs, i);
+			if (!OCSP_basic_add1_cert(brsp, tmpcert))
+				goto err;
+		}
+	}
+
+	rid = brsp->tbsResponseData->responderId;
+	if (flags & OCSP_RESPID_KEY) {
+		unsigned char md[SHA_DIGEST_LENGTH];
+
+		X509_pubkey_digest(signer, EVP_sha1(), md, NULL);
+		if (!(rid->value.byKey = ASN1_OCTET_STRING_new()))
+			goto err;
+		if (!(ASN1_OCTET_STRING_set(rid->value.byKey, md,
+		    SHA_DIGEST_LENGTH)))
+			goto err;
+		rid->type = V_OCSP_RESPID_KEY;
+	} else {
+		if (!X509_NAME_set(&rid->value.byName,
+		    X509_get_subject_name(signer)))
+			goto err;
+		rid->type = V_OCSP_RESPID_NAME;
+	}
+
+	if (!(flags & OCSP_NOTIME) &&
+	    !ASN1_GENERALIZEDTIME_set(brsp->tbsResponseData->producedAt, time(NULL)))
+		goto err;
+
+	/* Right now, I think that not doing double hashing is the right
+	   thing.	-- Richard Levitte */
+
+	if (!OCSP_BASICRESP_sign(brsp, key, dgst, 0))
+		goto err;
+
+	return 1;
+
+err:
+	return 0;
+}
diff --git a/crypto/libressl/crypto/ocsp/ocsp_vfy.c b/crypto/libressl/crypto/ocsp/ocsp_vfy.c
new file mode 100644
index 0000000000..01e2dcd71a
--- /dev/null
+++ b/crypto/libressl/crypto/ocsp/ocsp_vfy.c
@@ -0,0 +1,462 @@
+/* $OpenBSD: ocsp_vfy.c,v 1.12 2014/07/09 19:08:10 tedu Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2004 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+
+static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs,
+    STACK_OF(X509) *certs, X509_STORE *st, unsigned long flags);
+static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id);
+static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain,
+    unsigned long flags);
+static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret);
+static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
+    STACK_OF(OCSP_SINGLERESP) *sresp);
+static int ocsp_check_delegated(X509 *x, int flags);
+static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req,
+    X509_NAME *nm, STACK_OF(X509) *certs, X509_STORE *st,
+    unsigned long flags);
+
+/* Verify a basic response message */
+int
+OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, X509_STORE *st,
+    unsigned long flags)
+{
+	X509 *signer, *x;
+	STACK_OF(X509) *chain = NULL;
+	STACK_OF(X509) *untrusted = NULL;
+	X509_STORE_CTX ctx;
+	int i, ret = 0;
+
+	ret = ocsp_find_signer(&signer, bs, certs, st, flags);
+	if (!ret) {
+		OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,
+		    OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
+		goto end;
+	}
+	if ((ret == 2) && (flags & OCSP_TRUSTOTHER))
+		flags |= OCSP_NOVERIFY;
+	if (!(flags & OCSP_NOSIGS)) {
+		EVP_PKEY *skey;
+
+		skey = X509_get_pubkey(signer);
+		if (skey) {
+			ret = OCSP_BASICRESP_verify(bs, skey, 0);
+			EVP_PKEY_free(skey);
+		}
+		if (!skey || ret <= 0) {
+			OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,
+			    OCSP_R_SIGNATURE_FAILURE);
+			goto end;
+		}
+	}
+	if (!(flags & OCSP_NOVERIFY)) {
+		int init_res;
+
+		if (flags & OCSP_NOCHAIN) {
+			untrusted = NULL;
+		} else if (bs->certs && certs) {
+			untrusted = sk_X509_dup(bs->certs);
+			for (i = 0; i < sk_X509_num(certs); i++) {
+				if (!sk_X509_push(untrusted,
+					sk_X509_value(certs, i))) {
+					OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,
+					    ERR_R_MALLOC_FAILURE);
+					goto end;
+				}
+			}
+		} else
+			untrusted = bs->certs;
+		init_res = X509_STORE_CTX_init(&ctx, st, signer, untrusted);
+		if (!init_res) {
+			ret = -1;
+			OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_X509_LIB);
+			goto end;
+		}
+
+		X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER);
+		ret = X509_verify_cert(&ctx);
+		chain = X509_STORE_CTX_get1_chain(&ctx);
+		X509_STORE_CTX_cleanup(&ctx);
+		if (ret <= 0) {
+			i = X509_STORE_CTX_get_error(&ctx);
+			OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,
+			    OCSP_R_CERTIFICATE_VERIFY_ERROR);
+			ERR_asprintf_error_data("Verify error:%s",
+			    X509_verify_cert_error_string(i));
+			goto end;
+		}
+		if (flags & OCSP_NOCHECKS) {
+			ret = 1;
+			goto end;
+		}
+		/* At this point we have a valid certificate chain
+		 * need to verify it against the OCSP issuer criteria.
+		 */
+		ret = ocsp_check_issuer(bs, chain, flags);
+
+		/* If fatal error or valid match then finish */
+		if (ret != 0)
+			goto end;
+
+		/* Easy case: explicitly trusted. Get root CA and
+		 * check for explicit trust
+		 */
+		if (flags & OCSP_NOEXPLICIT)
+			goto end;
+
+		x = sk_X509_value(chain, sk_X509_num(chain) - 1);
+		if (X509_check_trust(x, NID_OCSP_sign, 0) !=
+			X509_TRUST_TRUSTED) {
+			OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,
+			    OCSP_R_ROOT_CA_NOT_TRUSTED);
+			goto end;
+		}
+		ret = 1;
+	}
+
+end:
+	if (chain)
+		sk_X509_pop_free(chain, X509_free);
+	if (bs->certs && certs)
+		sk_X509_free(untrusted);
+	return ret;
+}
+
+static int
+ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
+    X509_STORE *st, unsigned long flags)
+{
+	X509 *signer;
+	OCSP_RESPID *rid = bs->tbsResponseData->responderId;
+
+	if ((signer = ocsp_find_signer_sk(certs, rid))) {
+		*psigner = signer;
+		return 2;
+	}
+	if (!(flags & OCSP_NOINTERN) &&
+	    (signer = ocsp_find_signer_sk(bs->certs, rid))) {
+		*psigner = signer;
+		return 1;
+	}
+	/* Maybe lookup from store if by subject name */
+
+	*psigner = NULL;
+	return 0;
+}
+
+static X509 *
+ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
+{
+	int i;
+	unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
+	X509 *x;
+
+	/* Easy if lookup by name */
+	if (id->type == V_OCSP_RESPID_NAME)
+		return X509_find_by_subject(certs, id->value.byName);
+
+	/* Lookup by key hash */
+
+	/* If key hash isn't SHA1 length then forget it */
+	if (id->value.byKey->length != SHA_DIGEST_LENGTH)
+		return NULL;
+	keyhash = id->value.byKey->data;
+	/* Calculate hash of each key and compare */
+	for (i = 0; i < sk_X509_num(certs); i++) {
+		x = sk_X509_value(certs, i);
+		X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
+		if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
+			return x;
+	}
+	return NULL;
+}
+
+static int
+ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain,
+    unsigned long flags)
+{
+	STACK_OF(OCSP_SINGLERESP) *sresp;
+	X509 *signer, *sca;
+	OCSP_CERTID *caid = NULL;
+	int i;
+
+	sresp = bs->tbsResponseData->responses;
+
+	if (sk_X509_num(chain) <= 0) {
+		OCSPerr(OCSP_F_OCSP_CHECK_ISSUER,
+		    OCSP_R_NO_CERTIFICATES_IN_CHAIN);
+		return -1;
+	}
+
+	/* See if the issuer IDs match. */
+	i = ocsp_check_ids(sresp, &caid);
+
+	/* If ID mismatch or other error then return */
+	if (i <= 0)
+		return i;
+
+	signer = sk_X509_value(chain, 0);
+	/* Check to see if OCSP responder CA matches request CA */
+	if (sk_X509_num(chain) > 1) {
+		sca = sk_X509_value(chain, 1);
+		i = ocsp_match_issuerid(sca, caid, sresp);
+		if (i < 0)
+			return i;
+		if (i) {
+			/* We have a match, if extensions OK then success */
+			if (ocsp_check_delegated(signer, flags))
+				return 1;
+			return 0;
+		}
+	}
+
+	/* Otherwise check if OCSP request signed directly by request CA */
+	return ocsp_match_issuerid(signer, caid, sresp);
+}
+
+/* Check the issuer certificate IDs for equality. If there is a mismatch with the same
+ * algorithm then there's no point trying to match any certificates against the issuer.
+ * If the issuer IDs all match then we just need to check equality against one of them.
+ */
+static int
+ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret)
+{
+	OCSP_CERTID *tmpid, *cid;
+	int i, idcount;
+
+	idcount = sk_OCSP_SINGLERESP_num(sresp);
+	if (idcount <= 0) {
+		OCSPerr(OCSP_F_OCSP_CHECK_IDS,
+		    OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA);
+		return -1;
+	}
+
+	cid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId;
+
+	*ret = NULL;
+
+	for (i = 1; i < idcount; i++) {
+		tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId;
+		/* Check to see if IDs match */
+		if (OCSP_id_issuer_cmp(cid, tmpid)) {
+			return 0;
+		}
+	}
+
+	/* All IDs match: only need to check one ID */
+	*ret = cid;
+	return 1;
+}
+
+static int
+ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
+    STACK_OF(OCSP_SINGLERESP) *sresp)
+{
+	/* If only one ID to match then do it */
+	if (cid) {
+		const EVP_MD *dgst;
+		X509_NAME *iname;
+		int mdlen;
+		unsigned char md[EVP_MAX_MD_SIZE];
+
+		if (!(dgst =
+		    EVP_get_digestbyobj(cid->hashAlgorithm->algorithm))) {
+			OCSPerr(OCSP_F_OCSP_MATCH_ISSUERID,
+			    OCSP_R_UNKNOWN_MESSAGE_DIGEST);
+			return -1;
+		}
+
+		mdlen = EVP_MD_size(dgst);
+		if (mdlen < 0)
+			return -1;
+		if (cid->issuerNameHash->length != mdlen ||
+		    cid->issuerKeyHash->length != mdlen)
+			return 0;
+		iname = X509_get_subject_name(cert);
+		if (!X509_NAME_digest(iname, dgst, md, NULL))
+			return -1;
+		if (memcmp(md, cid->issuerNameHash->data, mdlen))
+			return 0;
+		X509_pubkey_digest(cert, dgst, md, NULL);
+		if (memcmp(md, cid->issuerKeyHash->data, mdlen))
+			return 0;
+
+		return 1;
+	} else {
+		/* We have to match the whole lot */
+		int i, ret;
+		OCSP_CERTID *tmpid;
+
+		for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++) {
+			tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId;
+			ret = ocsp_match_issuerid(cert, tmpid, NULL);
+			if (ret <= 0)
+				return ret;
+		}
+		return 1;
+	}
+}
+
+static int
+ocsp_check_delegated(X509 *x, int flags)
+{
+	X509_check_purpose(x, -1, 0);
+	if ((x->ex_flags & EXFLAG_XKUSAGE) && (x->ex_xkusage & XKU_OCSP_SIGN))
+		return 1;
+	OCSPerr(OCSP_F_OCSP_CHECK_DELEGATED, OCSP_R_MISSING_OCSPSIGNING_USAGE);
+	return 0;
+}
+
+/* Verify an OCSP request. This is fortunately much easier than OCSP
+ * response verify. Just find the signers certificate and verify it
+ * against a given trust value.
+ */
+int
+OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, X509_STORE *store,
+    unsigned long flags)
+{
+	X509 *signer;
+	X509_NAME *nm;
+	GENERAL_NAME *gen;
+	int ret;
+	X509_STORE_CTX ctx;
+
+	if (!req->optionalSignature) {
+		OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_REQUEST_NOT_SIGNED);
+		return 0;
+	}
+	gen = req->tbsRequest->requestorName;
+	if (!gen || gen->type != GEN_DIRNAME) {
+		OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,
+		    OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE);
+		return 0;
+	}
+	nm = gen->d.directoryName;
+	ret = ocsp_req_find_signer(&signer, req, nm, certs, store, flags);
+	if (ret <= 0) {
+		OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,
+		    OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
+		return 0;
+	}
+	if ((ret == 2) && (flags & OCSP_TRUSTOTHER))
+		flags |= OCSP_NOVERIFY;
+	if (!(flags & OCSP_NOSIGS)) {
+		EVP_PKEY *skey;
+
+		skey = X509_get_pubkey(signer);
+		ret = OCSP_REQUEST_verify(req, skey);
+		EVP_PKEY_free(skey);
+		if (ret <= 0) {
+			OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,
+			    OCSP_R_SIGNATURE_FAILURE);
+			return 0;
+		}
+	}
+	if (!(flags & OCSP_NOVERIFY)) {
+		int init_res;
+
+		if (flags & OCSP_NOCHAIN)
+			init_res = X509_STORE_CTX_init(&ctx, store, signer,
+			    NULL);
+		else
+			init_res = X509_STORE_CTX_init(&ctx, store, signer,
+			    req->optionalSignature->certs);
+		if (!init_res) {
+			OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, ERR_R_X509_LIB);
+			return 0;
+		}
+
+		X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER);
+		X509_STORE_CTX_set_trust(&ctx, X509_TRUST_OCSP_REQUEST);
+		ret = X509_verify_cert(&ctx);
+		X509_STORE_CTX_cleanup(&ctx);
+		if (ret <= 0) {
+			ret = X509_STORE_CTX_get_error(&ctx);
+			OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,
+			    OCSP_R_CERTIFICATE_VERIFY_ERROR);
+			ERR_asprintf_error_data("Verify error:%s",
+			    X509_verify_cert_error_string(ret));
+			return 0;
+		}
+	}
+	return 1;
+}
+
+static int
+ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, X509_NAME *nm,
+    STACK_OF(X509) *certs, X509_STORE *st, unsigned long flags)
+{
+	X509 *signer;
+
+	if (!(flags & OCSP_NOINTERN)) {
+		signer = X509_find_by_subject(req->optionalSignature->certs, nm);
+		if (signer) {
+			*psigner = signer;
+			return 1;
+		}
+	}
+
+	signer = X509_find_by_subject(certs, nm);
+	if (signer) {
+		*psigner = signer;
+		return 2;
+	}
+	return 0;
+}
diff --git a/crypto/libressl/crypto/pem/pem_all.c b/crypto/libressl/crypto/pem/pem_all.c
new file mode 100644
index 0000000000..bc6e4afc47
--- /dev/null
+++ b/crypto/libressl/crypto/pem/pem_all.c
@@ -0,0 +1,313 @@
+/* $OpenBSD: pem_all.c,v 1.14 2014/07/10 22:45:57 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_DH
+#include 
+#endif
+#ifndef OPENSSL_NO_DSA
+#include 
+#endif
+#ifndef OPENSSL_NO_RSA
+#include 
+#endif
+
+#ifndef OPENSSL_NO_RSA
+static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa);
+#endif
+#ifndef OPENSSL_NO_DSA
+static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa);
+#endif
+
+#ifndef OPENSSL_NO_EC
+static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey);
+#endif
+
+IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ)
+
+IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ)
+
+IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL)
+
+IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7)
+
+IMPLEMENT_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE,
+    PEM_STRING_X509, NETSCAPE_CERT_SEQUENCE)
+
+
+#ifndef OPENSSL_NO_RSA
+
+/* We treat RSA or DSA private keys as a special case.
+ *
+ * For private keys we read in an EVP_PKEY structure with
+ * PEM_read_bio_PrivateKey() and extract the relevant private
+ * key: this means can handle "traditional" and PKCS#8 formats
+ * transparently.
+ */
+
+static RSA *
+pkey_get_rsa(EVP_PKEY *key, RSA **rsa)
+{
+	RSA *rtmp;
+
+	if (!key)
+		return NULL;
+	rtmp = EVP_PKEY_get1_RSA(key);
+	EVP_PKEY_free(key);
+	if (!rtmp)
+		return NULL;
+	if (rsa) {
+		RSA_free(*rsa);
+		*rsa = rtmp;
+	}
+	return rtmp;
+}
+
+RSA *
+PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb, void *u)
+{
+	EVP_PKEY *pktmp;
+
+	pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
+	return pkey_get_rsa(pktmp, rsa);
+}
+
+
+RSA *
+PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u)
+{
+	EVP_PKEY *pktmp;
+
+	pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
+	return pkey_get_rsa(pktmp, rsa);
+}
+
+
+IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey)
+
+IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey)
+IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY)
+
+#endif
+
+#ifndef OPENSSL_NO_DSA
+
+static DSA *
+pkey_get_dsa(EVP_PKEY *key, DSA **dsa)
+{
+	DSA *dtmp;
+
+	if (!key)
+		return NULL;
+	dtmp = EVP_PKEY_get1_DSA(key);
+	EVP_PKEY_free(key);
+	if (!dtmp)
+		return NULL;
+	if (dsa) {
+		DSA_free(*dsa);
+		*dsa = dtmp;
+	}
+	return dtmp;
+}
+
+DSA *
+PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb, void *u)
+{
+	EVP_PKEY *pktmp;
+
+	pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
+	return pkey_get_dsa(pktmp, dsa);	/* will free pktmp */
+}
+
+IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey)
+
+IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY)
+
+
+DSA *
+PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u)
+{
+	EVP_PKEY *pktmp;
+
+	pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
+	return pkey_get_dsa(pktmp, dsa);	/* will free pktmp */
+}
+
+
+IMPLEMENT_PEM_rw_const(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams)
+
+#endif
+
+
+#ifndef OPENSSL_NO_EC
+static EC_KEY *
+pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey)
+{
+	EC_KEY *dtmp;
+
+	if (!key)
+		return NULL;
+	dtmp = EVP_PKEY_get1_EC_KEY(key);
+	EVP_PKEY_free(key);
+	if (!dtmp)
+		return NULL;
+	if (eckey) {
+		EC_KEY_free(*eckey);
+		*eckey = dtmp;
+	}
+	return dtmp;
+}
+
+EC_KEY *
+PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb, void *u)
+{
+	EVP_PKEY *pktmp;
+	pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
+	return pkey_get_eckey(pktmp, key);	/* will free pktmp */
+}
+
+IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS,
+    ECPKParameters)
+
+IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY,
+    ECPrivateKey)
+
+IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY)
+
+
+EC_KEY *
+PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb, void *u)
+{
+	EVP_PKEY *pktmp;
+
+	pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
+	return pkey_get_eckey(pktmp, eckey);	/* will free pktmp */
+}
+
+
+#endif
+
+#ifndef OPENSSL_NO_DH
+
+IMPLEMENT_PEM_rw_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams)
+
+#endif
+
+IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)
diff --git a/crypto/libressl/crypto/pem/pem_err.c b/crypto/libressl/crypto/pem/pem_err.c
new file mode 100644
index 0000000000..13b5acdedd
--- /dev/null
+++ b/crypto/libressl/crypto/pem/pem_err.c
@@ -0,0 +1,161 @@
+/* $OpenBSD: pem_err.c,v 1.10 2014/06/12 15:49:30 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_PEM,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_PEM,0,reason)
+
+static ERR_STRING_DATA PEM_str_functs[] = {
+	{ERR_FUNC(PEM_F_B2I_DSS),	"B2I_DSS"},
+	{ERR_FUNC(PEM_F_B2I_PVK_BIO),	"b2i_PVK_bio"},
+	{ERR_FUNC(PEM_F_B2I_RSA),	"B2I_RSA"},
+	{ERR_FUNC(PEM_F_CHECK_BITLEN_DSA),	"CHECK_BITLEN_DSA"},
+	{ERR_FUNC(PEM_F_CHECK_BITLEN_RSA),	"CHECK_BITLEN_RSA"},
+	{ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_BIO),	"d2i_PKCS8PrivateKey_bio"},
+	{ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_FP),	"d2i_PKCS8PrivateKey_fp"},
+	{ERR_FUNC(PEM_F_DO_B2I),	"DO_B2I"},
+	{ERR_FUNC(PEM_F_DO_B2I_BIO),	"DO_B2I_BIO"},
+	{ERR_FUNC(PEM_F_DO_BLOB_HEADER),	"DO_BLOB_HEADER"},
+	{ERR_FUNC(PEM_F_DO_PK8PKEY),	"DO_PK8PKEY"},
+	{ERR_FUNC(PEM_F_DO_PK8PKEY_FP),	"DO_PK8PKEY_FP"},
+	{ERR_FUNC(PEM_F_DO_PVK_BODY),	"DO_PVK_BODY"},
+	{ERR_FUNC(PEM_F_DO_PVK_HEADER),	"DO_PVK_HEADER"},
+	{ERR_FUNC(PEM_F_I2B_PVK),	"I2B_PVK"},
+	{ERR_FUNC(PEM_F_I2B_PVK_BIO),	"i2b_PVK_bio"},
+	{ERR_FUNC(PEM_F_LOAD_IV),	"LOAD_IV"},
+	{ERR_FUNC(PEM_F_PEM_ASN1_READ),	"PEM_ASN1_read"},
+	{ERR_FUNC(PEM_F_PEM_ASN1_READ_BIO),	"PEM_ASN1_read_bio"},
+	{ERR_FUNC(PEM_F_PEM_ASN1_WRITE),	"PEM_ASN1_write"},
+	{ERR_FUNC(PEM_F_PEM_ASN1_WRITE_BIO),	"PEM_ASN1_write_bio"},
+	{ERR_FUNC(PEM_F_PEM_DEF_CALLBACK),	"PEM_def_callback"},
+	{ERR_FUNC(PEM_F_PEM_DO_HEADER),	"PEM_do_header"},
+	{ERR_FUNC(PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY),	"PEM_F_PEM_WRITE_PKCS8PRIVATEKEY"},
+	{ERR_FUNC(PEM_F_PEM_GET_EVP_CIPHER_INFO),	"PEM_get_EVP_CIPHER_INFO"},
+	{ERR_FUNC(PEM_F_PEM_PK8PKEY),	"PEM_PK8PKEY"},
+	{ERR_FUNC(PEM_F_PEM_READ),	"PEM_read"},
+	{ERR_FUNC(PEM_F_PEM_READ_BIO),	"PEM_read_bio"},
+	{ERR_FUNC(PEM_F_PEM_READ_BIO_PARAMETERS),	"PEM_read_bio_Parameters"},
+	{ERR_FUNC(PEM_F_PEM_READ_BIO_PRIVATEKEY),	"PEM_READ_BIO_PRIVATEKEY"},
+	{ERR_FUNC(PEM_F_PEM_READ_PRIVATEKEY),	"PEM_READ_PRIVATEKEY"},
+	{ERR_FUNC(PEM_F_PEM_SEALFINAL),	"PEM_SealFinal"},
+	{ERR_FUNC(PEM_F_PEM_SEALINIT),	"PEM_SealInit"},
+	{ERR_FUNC(PEM_F_PEM_SIGNFINAL),	"PEM_SignFinal"},
+	{ERR_FUNC(PEM_F_PEM_WRITE),	"PEM_write"},
+	{ERR_FUNC(PEM_F_PEM_WRITE_BIO),	"PEM_write_bio"},
+	{ERR_FUNC(PEM_F_PEM_WRITE_PRIVATEKEY),	"PEM_WRITE_PRIVATEKEY"},
+	{ERR_FUNC(PEM_F_PEM_X509_INFO_READ),	"PEM_X509_INFO_read"},
+	{ERR_FUNC(PEM_F_PEM_X509_INFO_READ_BIO),	"PEM_X509_INFO_read_bio"},
+	{ERR_FUNC(PEM_F_PEM_X509_INFO_WRITE_BIO),	"PEM_X509_INFO_write_bio"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA PEM_str_reasons[] = {
+	{ERR_REASON(PEM_R_BAD_BASE64_DECODE)     , "bad base64 decode"},
+	{ERR_REASON(PEM_R_BAD_DECRYPT)           , "bad decrypt"},
+	{ERR_REASON(PEM_R_BAD_END_LINE)          , "bad end line"},
+	{ERR_REASON(PEM_R_BAD_IV_CHARS)          , "bad iv chars"},
+	{ERR_REASON(PEM_R_BAD_MAGIC_NUMBER)      , "bad magic number"},
+	{ERR_REASON(PEM_R_BAD_PASSWORD_READ)     , "bad password read"},
+	{ERR_REASON(PEM_R_BAD_VERSION_NUMBER)    , "bad version number"},
+	{ERR_REASON(PEM_R_BIO_WRITE_FAILURE)     , "bio write failure"},
+	{ERR_REASON(PEM_R_CIPHER_IS_NULL)        , "cipher is null"},
+	{ERR_REASON(PEM_R_ERROR_CONVERTING_PRIVATE_KEY), "error converting private key"},
+	{ERR_REASON(PEM_R_EXPECTING_PRIVATE_KEY_BLOB), "expecting private key blob"},
+	{ERR_REASON(PEM_R_EXPECTING_PUBLIC_KEY_BLOB), "expecting public key blob"},
+	{ERR_REASON(PEM_R_INCONSISTENT_HEADER)   , "inconsistent header"},
+	{ERR_REASON(PEM_R_KEYBLOB_HEADER_PARSE_ERROR), "keyblob header parse error"},
+	{ERR_REASON(PEM_R_KEYBLOB_TOO_SHORT)     , "keyblob too short"},
+	{ERR_REASON(PEM_R_NOT_DEK_INFO)          , "not dek info"},
+	{ERR_REASON(PEM_R_NOT_ENCRYPTED)         , "not encrypted"},
+	{ERR_REASON(PEM_R_NOT_PROC_TYPE)         , "not proc type"},
+	{ERR_REASON(PEM_R_NO_START_LINE)         , "no start line"},
+	{ERR_REASON(PEM_R_PROBLEMS_GETTING_PASSWORD), "problems getting password"},
+	{ERR_REASON(PEM_R_PUBLIC_KEY_NO_RSA)     , "public key no rsa"},
+	{ERR_REASON(PEM_R_PVK_DATA_TOO_SHORT)    , "pvk data too short"},
+	{ERR_REASON(PEM_R_PVK_TOO_SHORT)         , "pvk too short"},
+	{ERR_REASON(PEM_R_READ_KEY)              , "read key"},
+	{ERR_REASON(PEM_R_SHORT_HEADER)          , "short header"},
+	{ERR_REASON(PEM_R_UNSUPPORTED_CIPHER)    , "unsupported cipher"},
+	{ERR_REASON(PEM_R_UNSUPPORTED_ENCRYPTION), "unsupported encryption"},
+	{ERR_REASON(PEM_R_UNSUPPORTED_KEY_COMPONENTS), "unsupported key components"},
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_PEM_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(PEM_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, PEM_str_functs);
+		ERR_load_strings(0, PEM_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/pem/pem_info.c b/crypto/libressl/crypto/pem/pem_info.c
new file mode 100644
index 0000000000..f0b73d7fdc
--- /dev/null
+++ b/crypto/libressl/crypto/pem/pem_info.c
@@ -0,0 +1,406 @@
+/* $OpenBSD: pem_info.c,v 1.20 2015/02/10 09:52:35 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_DSA
+#include 
+#endif
+#ifndef OPENSSL_NO_RSA
+#include 
+#endif
+
+STACK_OF(X509_INFO) *
+PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb,
+    void *u)
+{
+	BIO *b;
+	STACK_OF(X509_INFO) *ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL) {
+		PEMerr(PEM_F_PEM_X509_INFO_READ, ERR_R_BUF_LIB);
+		return (0);
+	}
+	BIO_set_fp(b, fp, BIO_NOCLOSE);
+	ret = PEM_X509_INFO_read_bio(b, sk, cb, u);
+	BIO_free(b);
+	return (ret);
+}
+
+STACK_OF(X509_INFO) *
+PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb,
+    void *u)
+{
+	X509_INFO *xi = NULL;
+	char *name = NULL, *header = NULL;
+	void *pp;
+	unsigned char *data = NULL;
+	const unsigned char *p;
+	long len, error = 0;
+	int ok = 0;
+	STACK_OF(X509_INFO) *ret = NULL;
+	unsigned int i, raw, ptype;
+	d2i_of_void *d2i = 0;
+
+	if (sk == NULL) {
+		if ((ret = sk_X509_INFO_new_null()) == NULL) {
+			PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,
+			    ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+	} else
+		ret = sk;
+
+	if ((xi = X509_INFO_new()) == NULL)
+		goto err;
+	for (;;) {
+		raw = 0;
+		ptype = 0;
+		i = PEM_read_bio(bp, &name, &header, &data, &len);
+		if (i == 0) {
+			error = ERR_GET_REASON(ERR_peek_last_error());
+			if (error == PEM_R_NO_START_LINE) {
+				ERR_clear_error();
+				break;
+			}
+			goto err;
+		}
+start:
+		if ((strcmp(name, PEM_STRING_X509) == 0) ||
+		    (strcmp(name, PEM_STRING_X509_OLD) == 0)) {
+			d2i = (D2I_OF(void))d2i_X509;
+			if (xi->x509 != NULL) {
+				if (!sk_X509_INFO_push(ret, xi))
+					goto err;
+				if ((xi = X509_INFO_new()) == NULL)
+					goto err;
+				goto start;
+			}
+			pp = &(xi->x509);
+		} else if ((strcmp(name, PEM_STRING_X509_TRUSTED) == 0)) {
+			d2i = (D2I_OF(void))d2i_X509_AUX;
+			if (xi->x509 != NULL) {
+				if (!sk_X509_INFO_push(ret, xi))
+					goto err;
+				if ((xi = X509_INFO_new()) == NULL)
+					goto err;
+				goto start;
+			}
+			pp = &(xi->x509);
+		} else if (strcmp(name, PEM_STRING_X509_CRL) == 0) {
+			d2i = (D2I_OF(void))d2i_X509_CRL;
+			if (xi->crl != NULL) {
+				if (!sk_X509_INFO_push(ret, xi))
+					goto err;
+				if ((xi = X509_INFO_new()) == NULL)
+					goto err;
+				goto start;
+			}
+			pp = &(xi->crl);
+		} else
+#ifndef OPENSSL_NO_RSA
+		if (strcmp(name, PEM_STRING_RSA) == 0) {
+			d2i = (D2I_OF(void))d2i_RSAPrivateKey;
+			if (xi->x_pkey != NULL) {
+				if (!sk_X509_INFO_push(ret, xi))
+					goto err;
+				if ((xi = X509_INFO_new()) == NULL)
+					goto err;
+				goto start;
+			}
+
+			xi->enc_data = NULL;
+			xi->enc_len = 0;
+
+			xi->x_pkey = X509_PKEY_new();
+			if (xi->x_pkey == NULL)
+				goto err;
+			ptype = EVP_PKEY_RSA;
+			pp = &xi->x_pkey->dec_pkey;
+			if (strlen(header) > 10) /* assume encrypted */
+				raw = 1;
+		} else
+#endif
+#ifndef OPENSSL_NO_DSA
+		if (strcmp(name, PEM_STRING_DSA) == 0) {
+			d2i = (D2I_OF(void))d2i_DSAPrivateKey;
+			if (xi->x_pkey != NULL) {
+				if (!sk_X509_INFO_push(ret, xi))
+					goto err;
+				if ((xi = X509_INFO_new()) == NULL)
+					goto err;
+				goto start;
+			}
+
+			xi->enc_data = NULL;
+			xi->enc_len = 0;
+
+			xi->x_pkey = X509_PKEY_new();
+			if (xi->x_pkey == NULL)
+				goto err;
+			ptype = EVP_PKEY_DSA;
+			pp = &xi->x_pkey->dec_pkey;
+			if (strlen(header) > 10) /* assume encrypted */
+				raw = 1;
+		} else
+#endif
+#ifndef OPENSSL_NO_EC
+		if (strcmp(name, PEM_STRING_ECPRIVATEKEY) == 0) {
+			d2i = (D2I_OF(void))d2i_ECPrivateKey;
+			if (xi->x_pkey != NULL) {
+				if (!sk_X509_INFO_push(ret, xi))
+					goto err;
+				if ((xi = X509_INFO_new()) == NULL)
+					goto err;
+				goto start;
+			}
+
+			xi->enc_data = NULL;
+			xi->enc_len = 0;
+
+			xi->x_pkey = X509_PKEY_new();
+			if (xi->x_pkey == NULL)
+				goto err;
+			ptype = EVP_PKEY_EC;
+			pp = &xi->x_pkey->dec_pkey;
+			if (strlen(header) > 10) /* assume encrypted */
+				raw = 1;
+		} else
+#endif
+		{
+			d2i = NULL;
+			pp = NULL;
+		}
+
+		if (d2i != NULL) {
+			if (!raw) {
+				EVP_CIPHER_INFO cipher;
+
+				if (!PEM_get_EVP_CIPHER_INFO(header, &cipher))
+					goto err;
+				if (!PEM_do_header(&cipher, data, &len, cb, u))
+					goto err;
+				p = data;
+				if (ptype) {
+					if (!d2i_PrivateKey(ptype, pp, &p,
+					    len)) {
+						PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,
+						    ERR_R_ASN1_LIB);
+						goto err;
+					}
+				} else if (d2i(pp, &p, len) == NULL) {
+					PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,
+					    ERR_R_ASN1_LIB);
+					goto err;
+				}
+			} else { /* encrypted RSA data */
+				if (!PEM_get_EVP_CIPHER_INFO(header,
+				    &xi->enc_cipher))
+					goto err;
+				xi->enc_data = (char *)data;
+				xi->enc_len = (int)len;
+				data = NULL;
+			}
+		} else {
+			/* unknown */
+		}
+		free(name);
+		free(header);
+		free(data);
+		name = NULL;
+		header = NULL;
+		data = NULL;
+	}
+
+	/* if the last one hasn't been pushed yet and there is anything
+	 * in it then add it to the stack ...
+	 */
+	if ((xi->x509 != NULL) || (xi->crl != NULL) ||
+	    (xi->x_pkey != NULL) || (xi->enc_data != NULL)) {
+		if (!sk_X509_INFO_push(ret, xi))
+			goto err;
+		xi = NULL;
+	}
+	ok = 1;
+
+err:
+	if (xi != NULL)
+		X509_INFO_free(xi);
+	if (!ok) {
+		for (i = 0; ((int)i) < sk_X509_INFO_num(ret); i++) {
+			xi = sk_X509_INFO_value(ret, i);
+			X509_INFO_free(xi);
+		}
+		if (ret != sk)
+			sk_X509_INFO_free(ret);
+		ret = NULL;
+	}
+
+	free(name);
+	free(header);
+	free(data);
+	return (ret);
+}
+
+
+/* A TJH addition */
+int
+PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
+    unsigned char *kstr, int klen, pem_password_cb *cb, void *u)
+{
+	EVP_CIPHER_CTX ctx;
+	int i, ret = 0;
+	unsigned char *data = NULL;
+	const char *objstr = NULL;
+	char buf[PEM_BUFSIZE];
+	unsigned char *iv = NULL;
+
+	if (enc != NULL) {
+		objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
+		if (objstr == NULL) {
+			PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,
+			    PEM_R_UNSUPPORTED_CIPHER);
+			goto err;
+		}
+	}
+
+	/* now for the fun part ... if we have a private key then
+	 * we have to be able to handle a not-yet-decrypted key
+	 * being written out correctly ... if it is decrypted or
+	 * it is non-encrypted then we use the base code
+	 */
+	if (xi->x_pkey != NULL) {
+		if ((xi->enc_data != NULL) && (xi->enc_len > 0) ) {
+			if (enc == NULL) {
+				PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,
+				    PEM_R_CIPHER_IS_NULL);
+				goto err;
+			}
+
+			/* copy from weirdo names into more normal things */
+			iv = xi->enc_cipher.iv;
+			data = (unsigned char *)xi->enc_data;
+			i = xi->enc_len;
+
+			/* we take the encryption data from the
+			 * internal stuff rather than what the
+			 * user has passed us ... as we have to
+			 * match exactly for some strange reason
+			 */
+			objstr = OBJ_nid2sn(
+			    EVP_CIPHER_nid(xi->enc_cipher.cipher));
+			if (objstr == NULL) {
+				PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,
+				    PEM_R_UNSUPPORTED_CIPHER);
+				goto err;
+			}
+
+			/* create the right magic header stuff */
+			if (strlen(objstr) + 23 + 2 * enc->iv_len + 13 >
+			    sizeof buf) {
+				PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,
+				    ASN1_R_BUFFER_TOO_SMALL);
+				goto err;
+			}
+			buf[0] = '\0';
+			PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
+			PEM_dek_info(buf, objstr, enc->iv_len, (char *)iv);
+
+			/* use the normal code to write things out */
+			i = PEM_write_bio(bp, PEM_STRING_RSA, buf, data, i);
+			if (i <= 0)
+				goto err;
+		} else {
+			/* Add DSA/DH */
+#ifndef OPENSSL_NO_RSA
+			/* normal optionally encrypted stuff */
+			if (PEM_write_bio_RSAPrivateKey(bp,
+			    xi->x_pkey->dec_pkey->pkey.rsa,
+			    enc, kstr, klen, cb, u) <= 0)
+				goto err;
+#endif
+		}
+	}
+
+	/* if we have a certificate then write it out now */
+	if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp, xi->x509) <= 0))
+		goto err;
+
+	/* we are ignoring anything else that is loaded into the X509_INFO
+	 * structure for the moment ... as I don't need it so I'm not
+	 * coding it here and Eric can do it when this makes it into the
+	 * base library --tjh
+	 */
+
+	ret = 1;
+
+err:
+	explicit_bzero((char *)&ctx, sizeof(ctx));
+	explicit_bzero(buf, PEM_BUFSIZE);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/pem/pem_lib.c b/crypto/libressl/crypto/pem/pem_lib.c
new file mode 100644
index 0000000000..ec4836b9c1
--- /dev/null
+++ b/crypto/libressl/crypto/pem/pem_lib.c
@@ -0,0 +1,872 @@
+/* $OpenBSD: pem_lib.c,v 1.41 2015/07/19 18:29:31 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_DES
+#include 
+#endif
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+
+#include "asn1_locl.h"
+
+#define MIN_LENGTH	4
+
+static int load_iv(char **fromp, unsigned char *to, int num);
+static int check_pem(const char *nm, const char *name);
+int pem_check_suffix(const char *pem_str, const char *suffix);
+
+/* XXX LSSL ABI XXX return value and `num' ought to be size_t */
+int
+PEM_def_callback(char *buf, int num, int w, void *key)
+{
+	size_t l;
+	int i;
+	const char *prompt;
+
+	if (num < 0)
+		return -1;
+
+	if (key) {
+		l = strlen(key);
+		if (l > (size_t)num)
+			l = (size_t)num;
+		memcpy(buf, key, l);
+		return (int)l;
+	}
+
+	prompt = EVP_get_pw_prompt();
+	if (prompt == NULL)
+		prompt = "Enter PEM pass phrase:";
+
+	for (;;) {
+		i = EVP_read_pw_string_min(buf, MIN_LENGTH, num, prompt, w);
+		if (i != 0) {
+			PEMerr(PEM_F_PEM_DEF_CALLBACK,
+			    PEM_R_PROBLEMS_GETTING_PASSWORD);
+			memset(buf, 0, num);
+			return (-1);
+		}
+		l = strlen(buf);
+		if (l < MIN_LENGTH) {
+			fprintf(stderr, "phrase is too short, "
+			    "needs to be at least %zu chars\n",
+			    (size_t)MIN_LENGTH);
+		} else
+			break;
+	}
+	return (int)l;
+}
+
+void
+PEM_proc_type(char *buf, int type)
+{
+	const char *str;
+
+	if (type == PEM_TYPE_ENCRYPTED)
+		str = "ENCRYPTED";
+	else if (type == PEM_TYPE_MIC_CLEAR)
+		str = "MIC-CLEAR";
+	else if (type == PEM_TYPE_MIC_ONLY)
+		str = "MIC-ONLY";
+	else
+		str = "BAD-TYPE";
+
+	strlcat(buf, "Proc-Type: 4,", PEM_BUFSIZE);
+	strlcat(buf, str, PEM_BUFSIZE);
+	strlcat(buf, "\n", PEM_BUFSIZE);
+}
+
+void
+PEM_dek_info(char *buf, const char *type, int len, char *str)
+{
+	static const unsigned char map[17] = "0123456789ABCDEF";
+	long i;
+	int j;
+
+	strlcat(buf, "DEK-Info: ", PEM_BUFSIZE);
+	strlcat(buf, type, PEM_BUFSIZE);
+	strlcat(buf, ",", PEM_BUFSIZE);
+	j = strlen(buf);
+	if (j + (len * 2) + 1 > PEM_BUFSIZE)
+		return;
+	for (i = 0; i < len; i++) {
+		buf[j + i * 2] = map[(str[i] >> 4) & 0x0f];
+		buf[j + i * 2 + 1] = map[(str[i]) & 0x0f];
+	}
+	buf[j + i * 2] = '\n';
+	buf[j + i * 2 + 1] = '\0';
+}
+
+void *
+PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
+    pem_password_cb *cb, void *u)
+{
+	BIO *b;
+	void *ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL) {
+		PEMerr(PEM_F_PEM_ASN1_READ, ERR_R_BUF_LIB);
+		return (0);
+	}
+	BIO_set_fp(b, fp, BIO_NOCLOSE);
+	ret = PEM_ASN1_read_bio(d2i, name, b, x, cb, u);
+	BIO_free(b);
+	return (ret);
+}
+
+static int
+check_pem(const char *nm, const char *name)
+{
+	/* Normal matching nm and name */
+	if (!strcmp(nm, name))
+		return 1;
+
+	/* Make PEM_STRING_EVP_PKEY match any private key */
+
+	if (!strcmp(name, PEM_STRING_EVP_PKEY)) {
+		int slen;
+		const EVP_PKEY_ASN1_METHOD *ameth;
+		if (!strcmp(nm, PEM_STRING_PKCS8))
+			return 1;
+		if (!strcmp(nm, PEM_STRING_PKCS8INF))
+			return 1;
+		slen = pem_check_suffix(nm, "PRIVATE KEY");
+		if (slen > 0) {
+			/* NB: ENGINE implementations wont contain
+			 * a deprecated old private key decode function
+			 * so don't look for them.
+			 */
+			ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
+			if (ameth && ameth->old_priv_decode)
+				return 1;
+		}
+		return 0;
+	}
+
+	if (!strcmp(name, PEM_STRING_PARAMETERS)) {
+		int slen;
+		const EVP_PKEY_ASN1_METHOD *ameth;
+		slen = pem_check_suffix(nm, "PARAMETERS");
+		if (slen > 0) {
+			ENGINE *e;
+			ameth = EVP_PKEY_asn1_find_str(&e, nm, slen);
+			if (ameth) {
+				int r;
+				if (ameth->param_decode)
+					r = 1;
+				else
+					r = 0;
+#ifndef OPENSSL_NO_ENGINE
+				if (e)
+					ENGINE_finish(e);
+#endif
+				return r;
+			}
+		}
+		return 0;
+	}
+
+	/* Permit older strings */
+
+	if (!strcmp(nm, PEM_STRING_X509_OLD) &&
+	    !strcmp(name, PEM_STRING_X509))
+		return 1;
+
+	if (!strcmp(nm, PEM_STRING_X509_REQ_OLD) &&
+	    !strcmp(name, PEM_STRING_X509_REQ))
+		return 1;
+
+	/* Allow normal certs to be read as trusted certs */
+	if (!strcmp(nm, PEM_STRING_X509) &&
+	    !strcmp(name, PEM_STRING_X509_TRUSTED))
+		return 1;
+
+	if (!strcmp(nm, PEM_STRING_X509_OLD) &&
+	    !strcmp(name, PEM_STRING_X509_TRUSTED))
+		return 1;
+
+	/* Some CAs use PKCS#7 with CERTIFICATE headers */
+	if (!strcmp(nm, PEM_STRING_X509) &&
+	    !strcmp(name, PEM_STRING_PKCS7))
+		return 1;
+
+	if (!strcmp(nm, PEM_STRING_PKCS7_SIGNED) &&
+	    !strcmp(name, PEM_STRING_PKCS7))
+		return 1;
+
+#ifndef OPENSSL_NO_CMS
+	if (!strcmp(nm, PEM_STRING_X509) &&
+	    !strcmp(name, PEM_STRING_CMS))
+		return 1;
+	/* Allow CMS to be read from PKCS#7 headers */
+	if (!strcmp(nm, PEM_STRING_PKCS7) &&
+	    !strcmp(name, PEM_STRING_CMS))
+		return 1;
+#endif
+
+	return 0;
+}
+
+int
+PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm,
+    const char *name, BIO *bp, pem_password_cb *cb, void *u)
+{
+	EVP_CIPHER_INFO cipher;
+	char *nm = NULL, *header = NULL;
+	unsigned char *data = NULL;
+	long len;
+	int ret = 0;
+
+	for (;;) {
+		if (!PEM_read_bio(bp, &nm, &header, &data, &len)) {
+			if (ERR_GET_REASON(ERR_peek_error()) ==
+			    PEM_R_NO_START_LINE)
+				ERR_asprintf_error_data("Expecting: %s", name);
+			return 0;
+		}
+		if (check_pem(nm, name))
+			break;
+		free(nm);
+		free(header);
+		free(data);
+	}
+	if (!PEM_get_EVP_CIPHER_INFO(header, &cipher))
+		goto err;
+	if (!PEM_do_header(&cipher, data, &len, cb, u))
+		goto err;
+
+	*pdata = data;
+	*plen = len;
+
+	if (pnm)
+		*pnm = nm;
+
+	ret = 1;
+
+err:
+	if (!ret || !pnm)
+		free(nm);
+	free(header);
+	if (!ret)
+		free(data);
+	return ret;
+}
+
+int
+PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, void *x,
+    const EVP_CIPHER *enc, unsigned char *kstr, int klen,
+    pem_password_cb *callback, void *u)
+{
+	BIO *b;
+	int ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL) {
+		PEMerr(PEM_F_PEM_ASN1_WRITE, ERR_R_BUF_LIB);
+		return (0);
+	}
+	BIO_set_fp(b, fp, BIO_NOCLOSE);
+	ret = PEM_ASN1_write_bio(i2d, name, b, x, enc, kstr, klen, callback, u);
+	BIO_free(b);
+	return (ret);
+}
+
+int
+PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x,
+    const EVP_CIPHER *enc, unsigned char *kstr, int klen,
+    pem_password_cb *callback, void *u)
+{
+	EVP_CIPHER_CTX ctx;
+	int dsize = 0, i, j, ret = 0;
+	unsigned char *p, *data = NULL;
+	const char *objstr = NULL;
+	char buf[PEM_BUFSIZE];
+	unsigned char key[EVP_MAX_KEY_LENGTH];
+	unsigned char iv[EVP_MAX_IV_LENGTH];
+
+	if (enc != NULL) {
+		objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
+		if (objstr == NULL) {
+			PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,
+			    PEM_R_UNSUPPORTED_CIPHER);
+			goto err;
+		}
+	}
+
+	if ((dsize = i2d(x, NULL)) < 0) {
+		PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_ASN1_LIB);
+		dsize = 0;
+		goto err;
+	}
+	/* dzise + 8 bytes are needed */
+	/* actually it needs the cipher block size extra... */
+	data = malloc(dsize + 20);
+	if (data == NULL) {
+		PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	p = data;
+	i = i2d(x, &p);
+
+	if (enc != NULL) {
+		if (kstr == NULL) {
+			if (callback == NULL)
+				klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u);
+			else
+				klen = (*callback)(buf, PEM_BUFSIZE, 1, u);
+			if (klen <= 0) {
+				PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,
+				    PEM_R_READ_KEY);
+				goto err;
+			}
+			kstr = (unsigned char *)buf;
+		}
+		if ((size_t)enc->iv_len > sizeof(iv)) {
+			PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, EVP_R_IV_TOO_LARGE);
+			goto err;
+		}
+		arc4random_buf(iv, enc->iv_len); /* Generate a salt */
+		/* The 'iv' is used as the iv and as a salt.  It is
+		 * NOT taken from the BytesToKey function */
+		if (!EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1,
+		    key, NULL))
+			goto err;
+
+		if (kstr == (unsigned char *)buf)
+			explicit_bzero(buf, PEM_BUFSIZE);
+
+		if (strlen(objstr) + 23 + 2 * enc->iv_len + 13 > sizeof buf) {
+			PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,
+			    ASN1_R_BUFFER_TOO_SMALL);
+			goto err;
+		}
+
+		buf[0] = '\0';
+		PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
+		PEM_dek_info(buf, objstr, enc->iv_len, (char *)iv);
+		/* k=strlen(buf); */
+
+		EVP_CIPHER_CTX_init(&ctx);
+		ret = 1;
+		if (!EVP_EncryptInit_ex(&ctx, enc, NULL, key, iv) ||
+		    !EVP_EncryptUpdate(&ctx, data, &j, data, i) ||
+		    !EVP_EncryptFinal_ex(&ctx, &(data[j]), &i))
+			ret = 0;
+		EVP_CIPHER_CTX_cleanup(&ctx);
+		if (ret == 0)
+			goto err;
+		i += j;
+	} else {
+		ret = 1;
+		buf[0] = '\0';
+	}
+	i = PEM_write_bio(bp, name, buf, data, i);
+	if (i <= 0)
+		ret = 0;
+err:
+	explicit_bzero(key, sizeof(key));
+	explicit_bzero(iv, sizeof(iv));
+	explicit_bzero((char *)&ctx, sizeof(ctx));
+	explicit_bzero(buf, PEM_BUFSIZE);
+	if (data != NULL) {
+		explicit_bzero(data, (unsigned int)dsize);
+		free(data);
+	}
+	return (ret);
+}
+
+int
+PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
+    pem_password_cb *callback, void *u)
+{
+	int i, j, o, klen;
+	long len;
+	EVP_CIPHER_CTX ctx;
+	unsigned char key[EVP_MAX_KEY_LENGTH];
+	char buf[PEM_BUFSIZE];
+
+	len = *plen;
+
+	if (cipher->cipher == NULL)
+		return (1);
+	if (callback == NULL)
+		klen = PEM_def_callback(buf, PEM_BUFSIZE, 0, u);
+	else
+		klen = callback(buf, PEM_BUFSIZE, 0, u);
+	if (klen <= 0) {
+		PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_BAD_PASSWORD_READ);
+		return (0);
+	}
+	if (!EVP_BytesToKey(cipher->cipher, EVP_md5(), &(cipher->iv[0]),
+	    (unsigned char *)buf, klen, 1, key, NULL))
+		return 0;
+
+	j = (int)len;
+	EVP_CIPHER_CTX_init(&ctx);
+	o = EVP_DecryptInit_ex(&ctx, cipher->cipher, NULL, key,
+	    &(cipher->iv[0]));
+	if (o)
+		o = EVP_DecryptUpdate(&ctx, data, &i, data, j);
+	if (o)
+		o = EVP_DecryptFinal_ex(&ctx, &(data[i]), &j);
+	EVP_CIPHER_CTX_cleanup(&ctx);
+	explicit_bzero((char *)buf, sizeof(buf));
+	explicit_bzero((char *)key, sizeof(key));
+	if (!o) {
+		PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_BAD_DECRYPT);
+		return (0);
+	}
+	*plen = j + i;
+	return (1);
+}
+
+int
+PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
+{
+	const EVP_CIPHER *enc = NULL;
+	char *p, c;
+	char **header_pp = &header;
+
+	cipher->cipher = NULL;
+	if ((header == NULL) || (*header == '\0') || (*header == '\n'))
+		return (1);
+	if (strncmp(header, "Proc-Type: ", 11) != 0) {
+		PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_PROC_TYPE);
+		return (0);
+	}
+	header += 11;
+	if (*header != '4')
+		return (0);
+	header++;
+	if (*header != ',')
+		return (0);
+	header++;
+	if (strncmp(header, "ENCRYPTED", 9) != 0) {
+		PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_ENCRYPTED);
+		return (0);
+	}
+	for (; (*header != '\n') && (*header != '\0'); header++)
+		;
+	if (*header == '\0') {
+		PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_SHORT_HEADER);
+		return (0);
+	}
+	header++;
+	if (strncmp(header, "DEK-Info: ", 10) != 0) {
+		PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_DEK_INFO);
+		return (0);
+	}
+	header += 10;
+
+	p = header;
+	for (;;) {
+		c= *header;
+		if (!(	((c >= 'A') && (c <= 'Z')) || (c == '-') ||
+		    ((c >= '0') && (c <= '9'))))
+			break;
+		header++;
+	}
+	*header = '\0';
+	cipher->cipher = enc = EVP_get_cipherbyname(p);
+	*header = c;
+	header++;
+
+	if (enc == NULL) {
+		PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,
+		    PEM_R_UNSUPPORTED_ENCRYPTION);
+		return (0);
+	}
+	if (!load_iv(header_pp, &(cipher->iv[0]), enc->iv_len))
+		return (0);
+
+	return (1);
+}
+
+static int
+load_iv(char **fromp, unsigned char *to, int num)
+{
+	int v, i;
+	char *from;
+
+	from= *fromp;
+	for (i = 0; i < num; i++)
+		to[i] = 0;
+	num *= 2;
+	for (i = 0; i < num; i++) {
+		if ((*from >= '0') && (*from <= '9'))
+			v = *from - '0';
+		else if ((*from >= 'A') && (*from <= 'F'))
+			v = *from - 'A' + 10;
+		else if ((*from >= 'a') && (*from <= 'f'))
+			v = *from - 'a' + 10;
+		else {
+			PEMerr(PEM_F_LOAD_IV, PEM_R_BAD_IV_CHARS);
+			return (0);
+		}
+		from++;
+		to[i / 2] |= v << (long)((!(i & 1)) * 4);
+	}
+
+	*fromp = from;
+	return (1);
+}
+
+int
+PEM_write(FILE *fp, char *name, char *header, unsigned char *data, long len)
+{
+	BIO *b;
+	int ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL) {
+		PEMerr(PEM_F_PEM_WRITE, ERR_R_BUF_LIB);
+		return (0);
+	}
+	BIO_set_fp(b, fp, BIO_NOCLOSE);
+	ret = PEM_write_bio(b, name, header, data, len);
+	BIO_free(b);
+	return (ret);
+}
+
+int
+PEM_write_bio(BIO *bp, const char *name, char *header, unsigned char *data,
+    long len)
+{
+	int nlen, n, i, j, outl;
+	unsigned char *buf = NULL;
+	EVP_ENCODE_CTX ctx;
+	int reason = ERR_R_BUF_LIB;
+
+	EVP_EncodeInit(&ctx);
+	nlen = strlen(name);
+
+	if ((BIO_write(bp, "-----BEGIN ", 11) != 11) ||
+	    (BIO_write(bp, name, nlen) != nlen) ||
+	    (BIO_write(bp, "-----\n", 6) != 6))
+		goto err;
+
+	i = strlen(header);
+	if (i > 0) {
+		if ((BIO_write(bp, header, i) != i) ||
+		    (BIO_write(bp, "\n", 1) != 1))
+			goto err;
+	}
+
+	buf = reallocarray(NULL, PEM_BUFSIZE, 8);
+	if (buf == NULL) {
+		reason = ERR_R_MALLOC_FAILURE;
+		goto err;
+	}
+
+	i = j = 0;
+	while (len > 0) {
+		n = (int)((len > (PEM_BUFSIZE * 5)) ? (PEM_BUFSIZE * 5) : len);
+		EVP_EncodeUpdate(&ctx, buf, &outl, &(data[j]), n);
+		if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl))
+			goto err;
+		i += outl;
+		len -= n;
+		j += n;
+	}
+	EVP_EncodeFinal(&ctx, buf, &outl);
+	if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl))
+		goto err;
+	explicit_bzero(buf, PEM_BUFSIZE * 8);
+	free(buf);
+	buf = NULL;
+	if ((BIO_write(bp, "-----END ", 9) != 9) ||
+	    (BIO_write(bp, name, nlen) != nlen) ||
+	    (BIO_write(bp, "-----\n", 6) != 6))
+		goto err;
+	return (i + outl);
+
+err:
+	if (buf) {
+		explicit_bzero(buf, PEM_BUFSIZE * 8);
+		free(buf);
+	}
+	PEMerr(PEM_F_PEM_WRITE_BIO, reason);
+	return (0);
+}
+
+int
+PEM_read(FILE *fp, char **name, char **header, unsigned char **data, long *len)
+{
+	BIO *b;
+	int ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL) {
+		PEMerr(PEM_F_PEM_READ, ERR_R_BUF_LIB);
+		return (0);
+	}
+	BIO_set_fp(b, fp, BIO_NOCLOSE);
+	ret = PEM_read_bio(b, name, header, data, len);
+	BIO_free(b);
+	return (ret);
+}
+
+int
+PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
+    long *len)
+{
+	EVP_ENCODE_CTX ctx;
+	int end = 0, i, k, bl = 0, hl = 0, nohead = 0;
+	char buf[256];
+	BUF_MEM *nameB;
+	BUF_MEM *headerB;
+	BUF_MEM *dataB, *tmpB;
+
+	nameB = BUF_MEM_new();
+	headerB = BUF_MEM_new();
+	dataB = BUF_MEM_new();
+	if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL)) {
+		BUF_MEM_free(nameB);
+		BUF_MEM_free(headerB);
+		BUF_MEM_free(dataB);
+		PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
+		return (0);
+	}
+
+	buf[254] = '\0';
+	for (;;) {
+		i = BIO_gets(bp, buf, 254);
+
+		if (i <= 0) {
+			PEMerr(PEM_F_PEM_READ_BIO, PEM_R_NO_START_LINE);
+			goto err;
+		}
+
+		while ((i >= 0) && (buf[i] <= ' '))
+			i--;
+		buf[++i] = '\n';
+		buf[++i] = '\0';
+
+		if (strncmp(buf, "-----BEGIN ", 11) == 0) {
+			i = strlen(&(buf[11]));
+
+			if (strncmp(&(buf[11 + i - 6]), "-----\n", 6) != 0)
+				continue;
+			if (!BUF_MEM_grow(nameB, i + 9)) {
+				PEMerr(PEM_F_PEM_READ_BIO,
+				    ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+			memcpy(nameB->data, &(buf[11]), i - 6);
+			nameB->data[i - 6] = '\0';
+			break;
+		}
+	}
+	hl = 0;
+	if (!BUF_MEM_grow(headerB, 256)) {
+		PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	headerB->data[0] = '\0';
+	for (;;) {
+		i = BIO_gets(bp, buf, 254);
+		if (i <= 0)
+			break;
+
+		while ((i >= 0) && (buf[i] <= ' '))
+			i--;
+		buf[++i] = '\n';
+		buf[++i] = '\0';
+
+		if (buf[0] == '\n')
+			break;
+		if (!BUF_MEM_grow(headerB, hl + i + 9)) {
+			PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		if (strncmp(buf, "-----END ", 9) == 0) {
+			nohead = 1;
+			break;
+		}
+		memcpy(&(headerB->data[hl]), buf, i);
+		headerB->data[hl + i] = '\0';
+		hl += i;
+	}
+
+	bl = 0;
+	if (!BUF_MEM_grow(dataB, 1024)) {
+		PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	dataB->data[0] = '\0';
+	if (!nohead) {
+		for (;;) {
+			i = BIO_gets(bp, buf, 254);
+			if (i <= 0)
+				break;
+
+			while ((i >= 0) && (buf[i] <= ' '))
+				i--;
+			buf[++i] = '\n';
+			buf[++i] = '\0';
+
+			if (i != 65)
+				end = 1;
+			if (strncmp(buf, "-----END ", 9) == 0)
+				break;
+			if (i > 65)
+				break;
+			if (!BUF_MEM_grow_clean(dataB, i + bl + 9)) {
+				PEMerr(PEM_F_PEM_READ_BIO,
+				    ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+			memcpy(&(dataB->data[bl]), buf, i);
+			dataB->data[bl + i] = '\0';
+			bl += i;
+			if (end) {
+				buf[0] = '\0';
+				i = BIO_gets(bp, buf, 254);
+				if (i <= 0)
+					break;
+
+				while ((i >= 0) && (buf[i] <= ' '))
+					i--;
+				buf[++i] = '\n';
+				buf[++i] = '\0';
+
+				break;
+			}
+		}
+	} else {
+		tmpB = headerB;
+		headerB = dataB;
+		dataB = tmpB;
+		bl = hl;
+	}
+	i = strlen(nameB->data);
+	if ((strncmp(buf, "-----END ", 9) != 0) ||
+	    (strncmp(nameB->data, &(buf[9]), i) != 0) ||
+	    (strncmp(&(buf[9 + i]), "-----\n", 6) != 0)) {
+		PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_END_LINE);
+		goto err;
+	}
+
+	EVP_DecodeInit(&ctx);
+	i = EVP_DecodeUpdate(&ctx,
+	    (unsigned char *)dataB->data, &bl,
+	    (unsigned char *)dataB->data, bl);
+	if (i < 0) {
+		PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_BASE64_DECODE);
+		goto err;
+	}
+	i = EVP_DecodeFinal(&ctx, (unsigned char *)&(dataB->data[bl]), &k);
+	if (i < 0) {
+		PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_BASE64_DECODE);
+		goto err;
+	}
+	bl += k;
+
+	if (bl == 0)
+		goto err;
+	*name = nameB->data;
+	*header = headerB->data;
+	*data = (unsigned char *)dataB->data;
+	*len = bl;
+	free(nameB);
+	free(headerB);
+	free(dataB);
+	return (1);
+
+err:
+	BUF_MEM_free(nameB);
+	BUF_MEM_free(headerB);
+	BUF_MEM_free(dataB);
+	return (0);
+}
+
+/* Check pem string and return prefix length.
+ * If for example the pem_str == "RSA PRIVATE KEY" and suffix = "PRIVATE KEY"
+ * the return value is 3 for the string "RSA".
+ */
+
+int
+pem_check_suffix(const char *pem_str, const char *suffix)
+{
+	int pem_len = strlen(pem_str);
+	int suffix_len = strlen(suffix);
+	const char *p;
+
+	if (suffix_len + 1 >= pem_len)
+		return 0;
+	p = pem_str + pem_len - suffix_len;
+	if (strcmp(p, suffix))
+		return 0;
+	p--;
+	if (*p != ' ')
+		return 0;
+	return p - pem_str;
+}
diff --git a/crypto/libressl/crypto/pem/pem_oth.c b/crypto/libressl/crypto/pem/pem_oth.c
new file mode 100644
index 0000000000..12e0c896e7
--- /dev/null
+++ b/crypto/libressl/crypto/pem/pem_oth.c
@@ -0,0 +1,87 @@
+/* $OpenBSD: pem_oth.c,v 1.6 2014/07/11 08:44:49 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Handle 'other' PEMs: not private keys */
+
+void *
+PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x,
+    pem_password_cb *cb, void *u)
+{
+	const unsigned char *p = NULL;
+	unsigned char *data = NULL;
+	long len;
+	char *ret = NULL;
+
+	if (!PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u))
+		return NULL;
+	p = data;
+	ret = d2i(x, &p, len);
+	if (ret == NULL)
+		PEMerr(PEM_F_PEM_ASN1_READ_BIO, ERR_R_ASN1_LIB);
+	free(data);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/pem/pem_pk8.c b/crypto/libressl/crypto/pem/pem_pk8.c
new file mode 100644
index 0000000000..a5afbb3a54
--- /dev/null
+++ b/crypto/libressl/crypto/pem/pem_pk8.c
@@ -0,0 +1,256 @@
+/* $OpenBSD: pem_pk8.c,v 1.9 2014/10/18 17:20:40 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid,
+    const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u);
+static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder, int nid,
+    const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u);
+
+/* These functions write a private key in PKCS#8 format: it is a "drop in"
+ * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc'
+ * is NULL then it uses the unencrypted private key form. The 'nid' versions
+ * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0.
+ */
+
+int
+PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, char *kstr,
+    int klen, pem_password_cb *cb, void *u)
+{
+	return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u);
+}
+
+int
+PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+    char *kstr, int klen, pem_password_cb *cb, void *u)
+{
+	return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u);
+}
+
+int
+i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+    char *kstr, int klen, pem_password_cb *cb, void *u)
+{
+	return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u);
+}
+
+int
+i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
+    char *kstr, int klen, pem_password_cb *cb, void *u)
+{
+	return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u);
+}
+
+static int
+do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc,
+    char *kstr, int klen, pem_password_cb *cb, void *u)
+{
+	X509_SIG *p8;
+	PKCS8_PRIV_KEY_INFO *p8inf;
+	char buf[PEM_BUFSIZE];
+	int ret;
+
+	if (!(p8inf = EVP_PKEY2PKCS8(x))) {
+		PEMerr(PEM_F_DO_PK8PKEY,
+		    PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
+		return 0;
+	}
+	if (enc || (nid != -1)) {
+		if (!kstr) {
+			if (!cb)
+				klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u);
+			else
+				klen = cb(buf, PEM_BUFSIZE, 1, u);
+			if (klen <= 0) {
+				PEMerr(PEM_F_DO_PK8PKEY, PEM_R_READ_KEY);
+				PKCS8_PRIV_KEY_INFO_free(p8inf);
+				return 0;
+			}
+
+			kstr = buf;
+		}
+		p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf);
+		if (kstr == buf)
+			explicit_bzero(buf, klen);
+		PKCS8_PRIV_KEY_INFO_free(p8inf);
+		if (isder)
+			ret = i2d_PKCS8_bio(bp, p8);
+		else
+			ret = PEM_write_bio_PKCS8(bp, p8);
+		X509_SIG_free(p8);
+		return ret;
+	} else {
+		if (isder)
+			ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
+		else
+			ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf);
+		PKCS8_PRIV_KEY_INFO_free(p8inf);
+		return ret;
+	}
+}
+
+EVP_PKEY *
+d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
+{
+	PKCS8_PRIV_KEY_INFO *p8inf = NULL;
+	X509_SIG *p8 = NULL;
+	int klen;
+	EVP_PKEY *ret;
+	char psbuf[PEM_BUFSIZE];
+
+	p8 = d2i_PKCS8_bio(bp, NULL);
+	if (!p8)
+		return NULL;
+	if (cb)
+		klen = cb(psbuf, PEM_BUFSIZE, 0, u);
+	else
+		klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
+	if (klen <= 0) {
+		PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ);
+		X509_SIG_free(p8);
+		return NULL;
+	}
+	p8inf = PKCS8_decrypt(p8, psbuf, klen);
+	X509_SIG_free(p8);
+	if (!p8inf)
+		return NULL;
+	ret = EVP_PKCS82PKEY(p8inf);
+	PKCS8_PRIV_KEY_INFO_free(p8inf);
+	if (!ret)
+		return NULL;
+	if (x) {
+		EVP_PKEY_free(*x);
+		*x = ret;
+	}
+	return ret;
+}
+
+
+int
+i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+    char *kstr, int klen, pem_password_cb *cb, void *u)
+{
+	return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u);
+}
+
+int
+i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, char *kstr,
+    int klen, pem_password_cb *cb, void *u)
+{
+	return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u);
+}
+
+int
+PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, char *kstr,
+    int klen, pem_password_cb *cb, void *u)
+{
+	return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u);
+}
+
+int
+PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+    char *kstr, int klen, pem_password_cb *cb, void *u)
+{
+	return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u);
+}
+
+static int
+do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc,
+    char *kstr, int klen, pem_password_cb *cb, void *u)
+{
+	BIO *bp;
+	int ret;
+
+	if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
+		PEMerr(PEM_F_DO_PK8PKEY_FP, ERR_R_BUF_LIB);
+		return (0);
+	}
+	ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u);
+	BIO_free(bp);
+	return ret;
+}
+
+EVP_PKEY *
+d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u)
+{
+	BIO *bp;
+	EVP_PKEY *ret;
+
+	if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
+		PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_FP, ERR_R_BUF_LIB);
+		return NULL;
+	}
+	ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u);
+	BIO_free(bp);
+	return ret;
+}
+
+
+IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG)
+IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF,
+    PKCS8_PRIV_KEY_INFO)
diff --git a/crypto/libressl/crypto/pem/pem_pkey.c b/crypto/libressl/crypto/pem/pem_pkey.c
new file mode 100644
index 0000000000..a6012a63e0
--- /dev/null
+++ b/crypto/libressl/crypto/pem/pem_pkey.c
@@ -0,0 +1,253 @@
+/* $OpenBSD: pem_pkey.c,v 1.20 2015/02/11 03:19:37 doug Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+
+#include "asn1_locl.h"
+
+int pem_check_suffix(const char *pem_str, const char *suffix);
+
+EVP_PKEY *
+PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
+{
+	char *nm = NULL;
+	const unsigned char *p = NULL;
+	unsigned char *data = NULL;
+	long len;
+	int slen;
+	EVP_PKEY *ret = NULL;
+
+	if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY,
+	    bp, cb, u))
+		return NULL;
+	p = data;
+
+	if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) {
+		PKCS8_PRIV_KEY_INFO *p8inf;
+		p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
+		if (!p8inf)
+			goto p8err;
+		ret = EVP_PKCS82PKEY(p8inf);
+		if (x) {
+			EVP_PKEY_free(*x);
+			*x = ret;
+		}
+		PKCS8_PRIV_KEY_INFO_free(p8inf);
+	} else if (strcmp(nm, PEM_STRING_PKCS8) == 0) {
+		PKCS8_PRIV_KEY_INFO *p8inf;
+		X509_SIG *p8;
+		int klen;
+		char psbuf[PEM_BUFSIZE];
+		p8 = d2i_X509_SIG(NULL, &p, len);
+		if (!p8)
+			goto p8err;
+		if (cb)
+			klen = cb(psbuf, PEM_BUFSIZE, 0, u);
+		else
+			klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
+		if (klen <= 0) {
+			PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY,
+			    PEM_R_BAD_PASSWORD_READ);
+			X509_SIG_free(p8);
+			goto err;
+		}
+		p8inf = PKCS8_decrypt(p8, psbuf, klen);
+		X509_SIG_free(p8);
+		if (!p8inf)
+			goto p8err;
+		ret = EVP_PKCS82PKEY(p8inf);
+		if (x) {
+			EVP_PKEY_free(*x);
+			*x = ret;
+		}
+		PKCS8_PRIV_KEY_INFO_free(p8inf);
+	} else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0) {
+		const EVP_PKEY_ASN1_METHOD *ameth;
+		ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
+		if (!ameth || !ameth->old_priv_decode)
+			goto p8err;
+		ret = d2i_PrivateKey(ameth->pkey_id, x, &p, len);
+	}
+
+p8err:
+	if (ret == NULL)
+		PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, ERR_R_ASN1_LIB);
+err:
+	free(nm);
+	explicit_bzero(data, len);
+	free(data);
+	return (ret);
+}
+
+int
+PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+    unsigned char *kstr, int klen, pem_password_cb *cb, void *u)
+{
+	char pem_str[80];
+
+	if (!x->ameth || x->ameth->priv_encode)
+		return PEM_write_bio_PKCS8PrivateKey(bp, x, enc,
+		    (char *)kstr, klen, cb, u);
+
+	(void) snprintf(pem_str, sizeof(pem_str), "%s PRIVATE KEY",
+	    x->ameth->pem_str);
+	return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey,
+	    pem_str, bp, x, enc, kstr, klen, cb, u);
+}
+
+EVP_PKEY *
+PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x)
+{
+	char *nm = NULL;
+	const unsigned char *p = NULL;
+	unsigned char *data = NULL;
+	long len;
+	int slen;
+	EVP_PKEY *ret = NULL;
+
+	if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_PARAMETERS,
+	    bp, 0, NULL))
+		return NULL;
+	p = data;
+
+	if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0) {
+		ret = EVP_PKEY_new();
+		if (!ret)
+			goto err;
+		if (!EVP_PKEY_set_type_str(ret, nm, slen) ||
+		    !ret->ameth->param_decode ||
+		    !ret->ameth->param_decode(ret, &p, len)) {
+			EVP_PKEY_free(ret);
+			ret = NULL;
+			goto err;
+		}
+		if (x) {
+			EVP_PKEY_free(*x);
+			*x = ret;
+		}
+	}
+
+err:
+	if (ret == NULL)
+		PEMerr(PEM_F_PEM_READ_BIO_PARAMETERS, ERR_R_ASN1_LIB);
+	free(nm);
+	free(data);
+	return (ret);
+}
+
+int
+PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x)
+{
+	char pem_str[80];
+
+	if (!x->ameth || !x->ameth->param_encode)
+		return 0;
+
+	(void) snprintf(pem_str, sizeof(pem_str), "%s PARAMETERS",
+	    x->ameth->pem_str);
+	return PEM_ASN1_write_bio((i2d_of_void *)x->ameth->param_encode,
+	    pem_str, bp, x, NULL, NULL, 0, 0, NULL);
+}
+
+EVP_PKEY *
+PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u)
+{
+	BIO *b;
+	EVP_PKEY *ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL) {
+		PEMerr(PEM_F_PEM_READ_PRIVATEKEY, ERR_R_BUF_LIB);
+		return (0);
+	}
+	BIO_set_fp(b, fp, BIO_NOCLOSE);
+	ret = PEM_read_bio_PrivateKey(b, x, cb, u);
+	BIO_free(b);
+	return (ret);
+}
+
+int
+PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+    unsigned char *kstr, int klen, pem_password_cb *cb, void *u)
+{
+	BIO *b;
+	int ret;
+
+	if ((b = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) {
+		PEMerr(PEM_F_PEM_WRITE_PRIVATEKEY, ERR_R_BUF_LIB);
+		return 0;
+	}
+	ret = PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u);
+	BIO_free(b);
+	return ret;
+}
+
diff --git a/crypto/libressl/crypto/pem/pem_seal.c b/crypto/libressl/crypto/pem/pem_seal.c
new file mode 100644
index 0000000000..eafc2028bc
--- /dev/null
+++ b/crypto/libressl/crypto/pem/pem_seal.c
@@ -0,0 +1,190 @@
+/* $OpenBSD: pem_seal.c,v 1.21 2014/10/18 17:20:40 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 	/* for OPENSSL_NO_RSA */
+
+#ifndef OPENSSL_NO_RSA
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+int
+PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type,
+    unsigned char **ek, int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk)
+{
+	unsigned char key[EVP_MAX_KEY_LENGTH];
+	int ret = -1;
+	int i, j, max = 0;
+	char *s = NULL;
+
+	for (i = 0; i < npubk; i++) {
+		if (pubk[i]->type != EVP_PKEY_RSA) {
+			PEMerr(PEM_F_PEM_SEALINIT, PEM_R_PUBLIC_KEY_NO_RSA);
+			goto err;
+		}
+		j = RSA_size(pubk[i]->pkey.rsa);
+		if (j > max)
+			max = j;
+	}
+	s = reallocarray(NULL, max, 2);
+	if (s == NULL) {
+		PEMerr(PEM_F_PEM_SEALINIT, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	EVP_EncodeInit(&ctx->encode);
+
+	EVP_MD_CTX_init(&ctx->md);
+	if (!EVP_SignInit(&ctx->md, md_type))
+		goto err;
+
+	EVP_CIPHER_CTX_init(&ctx->cipher);
+	ret = EVP_SealInit(&ctx->cipher, type, ek, ekl, iv, pubk, npubk);
+	if (ret <= 0)
+		goto err;
+
+	/* base64 encode the keys */
+	for (i = 0; i < npubk; i++) {
+		j = EVP_EncodeBlock((unsigned char *)s, ek[i],
+		    RSA_size(pubk[i]->pkey.rsa));
+		ekl[i] = j;
+		memcpy(ek[i], s, j + 1);
+	}
+
+	ret = npubk;
+
+err:
+	free(s);
+	explicit_bzero(key, EVP_MAX_KEY_LENGTH);
+	return (ret);
+}
+
+void
+PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl,
+    unsigned char *in, int inl)
+{
+	unsigned char buffer[1600];
+	int i, j;
+
+	*outl = 0;
+	EVP_SignUpdate(&ctx->md, in, inl);
+	for (;;) {
+		if (inl <= 0)
+			break;
+		if (inl > 1200)
+			i = 1200;
+		else
+			i = inl;
+		EVP_EncryptUpdate(&ctx->cipher, buffer, &j, in, i);
+		EVP_EncodeUpdate(&ctx->encode, out, &j, buffer, j);
+		*outl += j;
+		out += j;
+		in += i;
+		inl -= i;
+	}
+}
+
+int
+PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl,
+    unsigned char *out, int *outl, EVP_PKEY *priv)
+{
+	unsigned char *s = NULL;
+	int ret = 0, j;
+	unsigned int i;
+
+	if (priv->type != EVP_PKEY_RSA) {
+		PEMerr(PEM_F_PEM_SEALFINAL, PEM_R_PUBLIC_KEY_NO_RSA);
+		goto err;
+	}
+	i = RSA_size(priv->pkey.rsa);
+	if (i < 100)
+		i = 100;
+	s = reallocarray(NULL, i, 2);
+	if (s == NULL) {
+		PEMerr(PEM_F_PEM_SEALFINAL, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	if (!EVP_EncryptFinal_ex(&ctx->cipher, s, (int *)&i))
+		goto err;
+	EVP_EncodeUpdate(&ctx->encode, out, &j, s, i);
+	*outl = j;
+	out += j;
+	EVP_EncodeFinal(&ctx->encode, out, &j);
+	*outl += j;
+
+	if (!EVP_SignFinal(&ctx->md, s, &i, priv))
+		goto err;
+	*sigl = EVP_EncodeBlock(sig, s, i);
+
+	ret = 1;
+
+err:
+	EVP_MD_CTX_cleanup(&ctx->md);
+	EVP_CIPHER_CTX_cleanup(&ctx->cipher);
+	free(s);
+	return (ret);
+}
+#endif
diff --git a/crypto/libressl/crypto/pem/pem_sign.c b/crypto/libressl/crypto/pem/pem_sign.c
new file mode 100644
index 0000000000..a194183245
--- /dev/null
+++ b/crypto/libressl/crypto/pem/pem_sign.c
@@ -0,0 +1,105 @@
+/* $OpenBSD: pem_sign.c,v 1.11 2014/07/11 08:44:49 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+void
+PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type)
+{
+	EVP_DigestInit_ex(ctx, type, NULL);
+}
+
+void
+PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data,
+    unsigned int count)
+{
+	EVP_DigestUpdate(ctx, data, count);
+}
+
+int
+PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
+    EVP_PKEY *pkey)
+{
+	unsigned char *m;
+	int i, ret = 0;
+	unsigned int m_len;
+
+	m = malloc(EVP_PKEY_size(pkey) + 2);
+	if (m == NULL) {
+		PEMerr(PEM_F_PEM_SIGNFINAL, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	if (EVP_SignFinal(ctx, m, &m_len, pkey) <= 0)
+		goto err;
+
+	i = EVP_EncodeBlock(sigret, m, m_len);
+	*siglen = i;
+	ret = 1;
+
+err:
+	/* ctx has been zeroed by EVP_SignFinal() */
+	free(m);
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/pem/pem_x509.c b/crypto/libressl/crypto/pem/pem_x509.c
new file mode 100644
index 0000000000..fc1327197e
--- /dev/null
+++ b/crypto/libressl/crypto/pem/pem_x509.c
@@ -0,0 +1,67 @@
+/* $OpenBSD: pem_x509.c,v 1.5 2014/06/12 15:49:30 deraadt Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+IMPLEMENT_PEM_rw(X509, X509, PEM_STRING_X509, X509)
diff --git a/crypto/libressl/crypto/pem/pem_xaux.c b/crypto/libressl/crypto/pem/pem_xaux.c
new file mode 100644
index 0000000000..757093c33b
--- /dev/null
+++ b/crypto/libressl/crypto/pem/pem_xaux.c
@@ -0,0 +1,69 @@
+/* $OpenBSD: pem_xaux.c,v 1.6 2014/06/12 15:49:30 deraadt Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+IMPLEMENT_PEM_rw(X509_AUX, X509, PEM_STRING_X509_TRUSTED, X509_AUX)
+IMPLEMENT_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR, PEM_STRING_X509_PAIR,
+    X509_CERT_PAIR)
diff --git a/crypto/libressl/crypto/pem/pvkfmt.c b/crypto/libressl/crypto/pem/pvkfmt.c
new file mode 100644
index 0000000000..374b846272
--- /dev/null
+++ b/crypto/libressl/crypto/pem/pvkfmt.c
@@ -0,0 +1,939 @@
+/* $OpenBSD: pvkfmt.c,v 1.15 2016/03/02 05:02:35 beck Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Support for PVK format keys and related structures (such a PUBLICKEYBLOB
+ * and PRIVATEKEYBLOB).
+ */
+
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
+#include 
+#include 
+
+/* Utility function: read a DWORD (4 byte unsigned integer) in little endian
+ * format
+ */
+
+static unsigned int
+read_ledword(const unsigned char **in)
+{
+	const unsigned char *p = *in;
+	unsigned int ret;
+
+	ret = *p++;
+	ret |= (*p++ << 8);
+	ret |= (*p++ << 16);
+	ret |= (*p++ << 24);
+	*in = p;
+	return ret;
+}
+
+/* Read a BIGNUM in little endian format. The docs say that this should take up
+ * bitlen/8 bytes.
+ */
+
+static int
+read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r)
+{
+	const unsigned char *p;
+	unsigned char *tmpbuf, *q;
+	unsigned int i;
+
+	p = *in + nbyte - 1;
+	tmpbuf = malloc(nbyte);
+	if (!tmpbuf)
+		return 0;
+	q = tmpbuf;
+	for (i = 0; i < nbyte; i++)
+		*q++ = *p--;
+	*r = BN_bin2bn(tmpbuf, nbyte, NULL);
+	free(tmpbuf);
+	if (*r) {
+		*in += nbyte;
+		return 1;
+	} else
+		return 0;
+}
+
+
+/* Convert private key blob to EVP_PKEY: RSA and DSA keys supported */
+
+#define MS_PUBLICKEYBLOB	0x6
+#define MS_PRIVATEKEYBLOB	0x7
+#define MS_RSA1MAGIC		0x31415352L
+#define MS_RSA2MAGIC		0x32415352L
+#define MS_DSS1MAGIC		0x31535344L
+#define MS_DSS2MAGIC		0x32535344L
+
+#define MS_KEYALG_RSA_KEYX	0xa400
+#define MS_KEYALG_DSS_SIGN	0x2200
+
+#define MS_KEYTYPE_KEYX		0x1
+#define MS_KEYTYPE_SIGN		0x2
+
+/* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */
+#define MS_PVKMAGIC		0xb0b5f11eL
+/* Salt length for PVK files */
+#define PVK_SALTLEN		0x10
+
+static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length,
+    unsigned int bitlen, int ispub);
+static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length,
+    unsigned int bitlen, int ispub);
+
+static int
+do_blob_header(const unsigned char **in, unsigned int length,
+    unsigned int *pmagic, unsigned int *pbitlen, int *pisdss, int *pispub)
+{
+	const unsigned char *p = *in;
+
+	if (length < 16)
+		return 0;
+	/* bType */
+	if (*p == MS_PUBLICKEYBLOB) {
+		if (*pispub == 0) {
+			PEMerr(PEM_F_DO_BLOB_HEADER,
+			    PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
+			return 0;
+		}
+		*pispub = 1;
+	} else if (*p == MS_PRIVATEKEYBLOB) {
+		if (*pispub == 1) {
+			PEMerr(PEM_F_DO_BLOB_HEADER,
+			    PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
+			return 0;
+		}
+		*pispub = 0;
+	} else
+		return 0;
+	p++;
+	/* Version */
+	if (*p++ != 0x2) {
+		PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_VERSION_NUMBER);
+		return 0;
+	}
+	/* Ignore reserved, aiKeyAlg */
+	p += 6;
+	*pmagic = read_ledword(&p);
+	*pbitlen = read_ledword(&p);
+	if (*pbitlen > 65536) {
+		PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_INCONSISTENT_HEADER);
+		return 0;
+	}
+	*pisdss = 0;
+	switch (*pmagic) {
+
+	case MS_DSS1MAGIC:
+		*pisdss = 1;
+	case MS_RSA1MAGIC:
+		if (*pispub == 0) {
+			PEMerr(PEM_F_DO_BLOB_HEADER,
+			    PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
+			return 0;
+		}
+		break;
+
+	case MS_DSS2MAGIC:
+		*pisdss = 1;
+	case MS_RSA2MAGIC:
+		if (*pispub == 1) {
+			PEMerr(PEM_F_DO_BLOB_HEADER,
+			    PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
+			return 0;
+		}
+		break;
+
+	default:
+		PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_MAGIC_NUMBER);
+		return -1;
+	}
+	*in = p;
+	return 1;
+}
+
+static unsigned int
+blob_length(unsigned bitlen, int isdss, int ispub)
+{
+	unsigned int nbyte, hnbyte;
+
+	nbyte = (bitlen + 7) >> 3;
+	hnbyte = (bitlen + 15) >> 4;
+	if (isdss) {
+
+		/* Expected length: 20 for q + 3 components bitlen each + 24
+		 * for seed structure.
+		 */
+		if (ispub)
+			return 44 + 3 * nbyte;
+		/* Expected length: 20 for q, priv, 2 bitlen components + 24
+		 * for seed structure.
+		 */
+		else
+			return 64 + 2 * nbyte;
+	} else {
+		/* Expected length: 4 for 'e' + 'n' */
+		if (ispub)
+			return 4 + nbyte;
+		else
+		/* Expected length: 4 for 'e' and 7 other components.
+		 * 2 components are bitlen size, 5 are bitlen/2
+		 */
+				return 4 + 2*nbyte + 5*hnbyte;
+	}
+
+}
+
+static EVP_PKEY *
+do_b2i(const unsigned char **in, unsigned int length, int ispub)
+{
+	const unsigned char *p = *in;
+	unsigned int bitlen, magic;
+	int isdss;
+
+	if (do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0) {
+		PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_HEADER_PARSE_ERROR);
+		return NULL;
+	}
+	length -= 16;
+	if (length < blob_length(bitlen, isdss, ispub)) {
+		PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_TOO_SHORT);
+		return NULL;
+	}
+	if (isdss)
+		return b2i_dss(&p, length, bitlen, ispub);
+	else
+		return b2i_rsa(&p, length, bitlen, ispub);
+}
+
+static EVP_PKEY *
+do_b2i_bio(BIO *in, int ispub)
+{
+	const unsigned char *p;
+	unsigned char hdr_buf[16], *buf = NULL;
+	unsigned int bitlen, magic, length;
+	int isdss;
+	EVP_PKEY *ret = NULL;
+
+	if (BIO_read(in, hdr_buf, 16) != 16) {
+		PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT);
+		return NULL;
+	}
+	p = hdr_buf;
+	if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0)
+		return NULL;
+
+	length = blob_length(bitlen, isdss, ispub);
+	buf = malloc(length);
+	if (!buf) {
+		PEMerr(PEM_F_DO_B2I_BIO, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	p = buf;
+	if (BIO_read(in, buf, length) != (int)length) {
+		PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT);
+		goto err;
+	}
+
+	if (isdss)
+		ret = b2i_dss(&p, length, bitlen, ispub);
+	else
+		ret = b2i_rsa(&p, length, bitlen, ispub);
+
+err:
+	free(buf);
+	return ret;
+}
+
+static EVP_PKEY *
+b2i_dss(const unsigned char **in, unsigned int length, unsigned int bitlen,
+    int ispub)
+{
+	const unsigned char *p = *in;
+	EVP_PKEY *ret = NULL;
+	DSA *dsa = NULL;
+	BN_CTX *ctx = NULL;
+	unsigned int nbyte;
+
+	nbyte = (bitlen + 7) >> 3;
+
+	dsa = DSA_new();
+	ret = EVP_PKEY_new();
+	if (!dsa || !ret)
+		goto memerr;
+	if (!read_lebn(&p, nbyte, &dsa->p))
+		goto memerr;
+	if (!read_lebn(&p, 20, &dsa->q))
+		goto memerr;
+	if (!read_lebn(&p, nbyte, &dsa->g))
+		goto memerr;
+	if (ispub) {
+		if (!read_lebn(&p, nbyte, &dsa->pub_key))
+			goto memerr;
+	} else {
+		if (!read_lebn(&p, 20, &dsa->priv_key))
+			goto memerr;
+		/* Calculate public key */
+		if (!(dsa->pub_key = BN_new()))
+			goto memerr;
+		if (!(ctx = BN_CTX_new()))
+			goto memerr;
+		if (!BN_mod_exp(dsa->pub_key, dsa->g,
+		    dsa->priv_key, dsa->p, ctx))
+			goto memerr;
+		BN_CTX_free(ctx);
+	}
+
+	EVP_PKEY_set1_DSA(ret, dsa);
+	DSA_free(dsa);
+	*in = p;
+	return ret;
+
+memerr:
+	PEMerr(PEM_F_B2I_DSS, ERR_R_MALLOC_FAILURE);
+	DSA_free(dsa);
+	EVP_PKEY_free(ret);
+	BN_CTX_free(ctx);
+	return NULL;
+}
+
+static EVP_PKEY *
+b2i_rsa(const unsigned char **in, unsigned int length, unsigned int bitlen,
+    int ispub)
+{
+	const unsigned char *p = *in;
+	EVP_PKEY *ret = NULL;
+	RSA *rsa = NULL;
+	unsigned int nbyte, hnbyte;
+
+	nbyte = (bitlen + 7) >> 3;
+	hnbyte = (bitlen + 15) >> 4;
+	rsa = RSA_new();
+	ret = EVP_PKEY_new();
+	if (!rsa || !ret)
+		goto memerr;
+	rsa->e = BN_new();
+	if (!rsa->e)
+		goto memerr;
+	if (!BN_set_word(rsa->e, read_ledword(&p)))
+		goto memerr;
+	if (!read_lebn(&p, nbyte, &rsa->n))
+		goto memerr;
+	if (!ispub) {
+		if (!read_lebn(&p, hnbyte, &rsa->p))
+			goto memerr;
+		if (!read_lebn(&p, hnbyte, &rsa->q))
+			goto memerr;
+		if (!read_lebn(&p, hnbyte, &rsa->dmp1))
+			goto memerr;
+		if (!read_lebn(&p, hnbyte, &rsa->dmq1))
+			goto memerr;
+		if (!read_lebn(&p, hnbyte, &rsa->iqmp))
+			goto memerr;
+		if (!read_lebn(&p, nbyte, &rsa->d))
+			goto memerr;
+	}
+
+	EVP_PKEY_set1_RSA(ret, rsa);
+	RSA_free(rsa);
+	*in = p;
+	return ret;
+
+memerr:
+	PEMerr(PEM_F_B2I_RSA, ERR_R_MALLOC_FAILURE);
+	RSA_free(rsa);
+	EVP_PKEY_free(ret);
+	return NULL;
+}
+
+EVP_PKEY *
+b2i_PrivateKey(const unsigned char **in, long length)
+{
+	return do_b2i(in, length, 0);
+}
+
+EVP_PKEY *
+b2i_PublicKey(const unsigned char **in, long length)
+{
+	return do_b2i(in, length, 1);
+}
+
+EVP_PKEY *
+b2i_PrivateKey_bio(BIO *in)
+{
+	return do_b2i_bio(in, 0);
+}
+
+EVP_PKEY *
+b2i_PublicKey_bio(BIO *in)
+{
+	return do_b2i_bio(in, 1);
+}
+
+static void
+write_ledword(unsigned char **out, unsigned int dw)
+{
+	unsigned char *p = *out;
+
+	*p++ = dw & 0xff;
+	*p++ = (dw >> 8) & 0xff;
+	*p++ = (dw >> 16) & 0xff;
+	*p++ = (dw >> 24) & 0xff;
+	*out = p;
+}
+
+static void
+write_lebn(unsigned char **out, const BIGNUM *bn, int len)
+{
+	int nb, i;
+	unsigned char *p = *out, *q, c;
+
+	nb = BN_num_bytes(bn);
+	BN_bn2bin(bn, p);
+	q = p + nb - 1;
+	/* In place byte order reversal */
+	for (i = 0; i < nb / 2; i++) {
+		c = *p;
+		*p++ = *q;
+		*q-- = c;
+	}
+	*out += nb;
+	/* Pad with zeroes if we have to */
+	if (len > 0) {
+		len -= nb;
+		if (len > 0) {
+			memset(*out, 0, len);
+			*out += len;
+		}
+	}
+}
+
+
+static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *magic);
+static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *magic);
+
+static void write_rsa(unsigned char **out, RSA *rsa, int ispub);
+static void write_dsa(unsigned char **out, DSA *dsa, int ispub);
+
+static int
+do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub)
+{
+	unsigned char *p;
+	unsigned int bitlen, magic = 0, keyalg;
+	int outlen, noinc = 0;
+
+	if (pk->type == EVP_PKEY_DSA) {
+		bitlen = check_bitlen_dsa(pk->pkey.dsa, ispub, &magic);
+		keyalg = MS_KEYALG_DSS_SIGN;
+	} else if (pk->type == EVP_PKEY_RSA) {
+		bitlen = check_bitlen_rsa(pk->pkey.rsa, ispub, &magic);
+		keyalg = MS_KEYALG_RSA_KEYX;
+	} else
+		return -1;
+	if (bitlen == 0)
+		return -1;
+	outlen = 16 + blob_length(bitlen,
+	    keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub);
+	if (out == NULL)
+		return outlen;
+	if (*out)
+		p = *out;
+	else {
+		p = malloc(outlen);
+		if (!p)
+			return -1;
+		*out = p;
+		noinc = 1;
+	}
+	if (ispub)
+		*p++ = MS_PUBLICKEYBLOB;
+	else
+		*p++ = MS_PRIVATEKEYBLOB;
+	*p++ = 0x2;
+	*p++ = 0;
+	*p++ = 0;
+	write_ledword(&p, keyalg);
+	write_ledword(&p, magic);
+	write_ledword(&p, bitlen);
+	if (keyalg == MS_KEYALG_DSS_SIGN)
+		write_dsa(&p, pk->pkey.dsa, ispub);
+	else
+		write_rsa(&p, pk->pkey.rsa, ispub);
+	if (!noinc)
+		*out += outlen;
+	return outlen;
+}
+
+static int
+do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub)
+{
+	unsigned char *tmp = NULL;
+	int outlen, wrlen;
+
+	outlen = do_i2b(&tmp, pk, ispub);
+	if (outlen < 0)
+		return -1;
+	wrlen = BIO_write(out, tmp, outlen);
+	free(tmp);
+	if (wrlen == outlen)
+		return outlen;
+	return -1;
+}
+
+static int
+check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic)
+{
+	int bitlen;
+
+	bitlen = BN_num_bits(dsa->p);
+	if ((bitlen & 7) || (BN_num_bits(dsa->q) != 160) ||
+	    (BN_num_bits(dsa->g) > bitlen))
+		goto badkey;
+	if (ispub) {
+		if (BN_num_bits(dsa->pub_key) > bitlen)
+			goto badkey;
+		*pmagic = MS_DSS1MAGIC;
+	} else {
+		if (BN_num_bits(dsa->priv_key) > 160)
+			goto badkey;
+		*pmagic = MS_DSS2MAGIC;
+	}
+
+	return bitlen;
+
+badkey:
+	PEMerr(PEM_F_CHECK_BITLEN_DSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS);
+	return 0;
+}
+
+static int
+check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic)
+{
+	int nbyte, hnbyte, bitlen;
+
+	if (BN_num_bits(rsa->e) > 32)
+		goto badkey;
+	bitlen = BN_num_bits(rsa->n);
+	nbyte = BN_num_bytes(rsa->n);
+	hnbyte = (BN_num_bits(rsa->n) + 15) >> 4;
+	if (ispub) {
+		*pmagic = MS_RSA1MAGIC;
+		return bitlen;
+	} else {
+		*pmagic = MS_RSA2MAGIC;
+		/* For private key each component must fit within nbyte or
+		 * hnbyte.
+		 */
+		if (BN_num_bytes(rsa->d) > nbyte)
+			goto badkey;
+		if ((BN_num_bytes(rsa->iqmp) > hnbyte) ||
+		    (BN_num_bytes(rsa->p) > hnbyte) ||
+		    (BN_num_bytes(rsa->q) > hnbyte) ||
+		    (BN_num_bytes(rsa->dmp1) > hnbyte) ||
+		    (BN_num_bytes(rsa->dmq1) > hnbyte))
+			goto badkey;
+	}
+	return bitlen;
+
+badkey:
+	PEMerr(PEM_F_CHECK_BITLEN_RSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS);
+	return 0;
+}
+
+static void
+write_rsa(unsigned char **out, RSA *rsa, int ispub)
+{
+	int nbyte, hnbyte;
+
+	nbyte = BN_num_bytes(rsa->n);
+	hnbyte = (BN_num_bits(rsa->n) + 15) >> 4;
+	write_lebn(out, rsa->e, 4);
+	write_lebn(out, rsa->n, -1);
+	if (ispub)
+		return;
+	write_lebn(out, rsa->p, hnbyte);
+	write_lebn(out, rsa->q, hnbyte);
+	write_lebn(out, rsa->dmp1, hnbyte);
+	write_lebn(out, rsa->dmq1, hnbyte);
+	write_lebn(out, rsa->iqmp, hnbyte);
+	write_lebn(out, rsa->d, nbyte);
+}
+
+static void
+write_dsa(unsigned char **out, DSA *dsa, int ispub)
+{
+	int nbyte;
+
+	nbyte = BN_num_bytes(dsa->p);
+	write_lebn(out, dsa->p, nbyte);
+	write_lebn(out, dsa->q, 20);
+	write_lebn(out, dsa->g, nbyte);
+	if (ispub)
+		write_lebn(out, dsa->pub_key, nbyte);
+	else
+		write_lebn(out, dsa->priv_key, 20);
+	/* Set "invalid" for seed structure values */
+	memset(*out, 0xff, 24);
+	*out += 24;
+	return;
+}
+
+int
+i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk)
+{
+	return do_i2b_bio(out, pk, 0);
+}
+
+int
+i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk)
+{
+	return do_i2b_bio(out, pk, 1);
+}
+
+#ifndef OPENSSL_NO_RC4
+
+static int
+do_PVK_header(const unsigned char **in, unsigned int length, int skip_magic,
+    unsigned int *psaltlen, unsigned int *pkeylen)
+{
+	const unsigned char *p = *in;
+	unsigned int pvk_magic, is_encrypted;
+
+	if (skip_magic) {
+		if (length < 20) {
+			PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
+			return 0;
+		}
+		length -= 20;
+	} else {
+		if (length < 24) {
+			PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
+			return 0;
+		}
+		length -= 24;
+		pvk_magic = read_ledword(&p);
+		if (pvk_magic != MS_PVKMAGIC) {
+			PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_BAD_MAGIC_NUMBER);
+			return 0;
+		}
+	}
+	/* Skip reserved */
+	p += 4;
+	/*keytype = */read_ledword(&p);
+	is_encrypted = read_ledword(&p);
+	*psaltlen = read_ledword(&p);
+	*pkeylen = read_ledword(&p);
+	if (*psaltlen > 65536 || *pkeylen > 65536) {
+		PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
+		return 0;
+	}
+
+	if (is_encrypted && !*psaltlen) {
+		PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_INCONSISTENT_HEADER);
+		return 0;
+	}
+
+	*in = p;
+	return 1;
+}
+
+static int
+derive_pvk_key(unsigned char *key, const unsigned char *salt,
+    unsigned int saltlen, const unsigned char *pass, int passlen)
+{
+	EVP_MD_CTX mctx;
+	int rv = 1;
+
+	EVP_MD_CTX_init(&mctx);
+	if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL) ||
+	    !EVP_DigestUpdate(&mctx, salt, saltlen) ||
+	    !EVP_DigestUpdate(&mctx, pass, passlen) ||
+	    !EVP_DigestFinal_ex(&mctx, key, NULL))
+		rv = 0;
+
+	EVP_MD_CTX_cleanup(&mctx);
+	return rv;
+}
+
+static EVP_PKEY *
+do_PVK_body(const unsigned char **in, unsigned int saltlen,
+    unsigned int keylen, pem_password_cb *cb, void *u)
+{
+	EVP_PKEY *ret = NULL;
+	const unsigned char *p = *in;
+	unsigned int magic;
+	unsigned char *enctmp = NULL, *q;
+	EVP_CIPHER_CTX cctx;
+
+	EVP_CIPHER_CTX_init(&cctx);
+	if (saltlen) {
+		char psbuf[PEM_BUFSIZE];
+		unsigned char keybuf[20];
+		int enctmplen, inlen;
+
+		if (cb)
+			inlen = cb(psbuf, PEM_BUFSIZE, 0, u);
+		else
+			inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
+		if (inlen <= 0) {
+			PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_PASSWORD_READ);
+			goto err;
+		}
+		enctmp = malloc(keylen + 8);
+		if (!enctmp) {
+			PEMerr(PEM_F_DO_PVK_BODY, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		if (!derive_pvk_key(keybuf, p, saltlen, (unsigned char *)psbuf,
+		    inlen)) {
+			goto err;
+		}
+		p += saltlen;
+		/* Copy BLOBHEADER across, decrypt rest */
+		memcpy(enctmp, p, 8);
+		p += 8;
+		if (keylen < 8) {
+			PEMerr(PEM_F_DO_PVK_BODY, PEM_R_PVK_TOO_SHORT);
+			goto err;
+		}
+		inlen = keylen - 8;
+		q = enctmp + 8;
+		if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
+			goto err;
+		if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen))
+			goto err;
+		if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen))
+			goto err;
+		magic = read_ledword((const unsigned char **)&q);
+		if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
+			q = enctmp + 8;
+			memset(keybuf + 5, 0, 11);
+			if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf,
+			    NULL))
+				goto err;
+			explicit_bzero(keybuf, 20);
+			if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen))
+				goto err;
+			if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen,
+			    &enctmplen))
+				goto err;
+			magic = read_ledword((const unsigned char **)&q);
+			if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
+				PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT);
+				goto err;
+			}
+		} else
+			explicit_bzero(keybuf, 20);
+		p = enctmp;
+	}
+
+	ret = b2i_PrivateKey(&p, keylen);
+
+err:
+	EVP_CIPHER_CTX_cleanup(&cctx);
+	if (enctmp && saltlen)
+		free(enctmp);
+	return ret;
+}
+
+
+EVP_PKEY *
+b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u)
+{
+	unsigned char pvk_hdr[24], *buf = NULL;
+	const unsigned char *p;
+	size_t buflen;
+	EVP_PKEY *ret = NULL;
+	unsigned int saltlen, keylen;
+
+	if (BIO_read(in, pvk_hdr, 24) != 24) {
+		PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT);
+		return NULL;
+	}
+	p = pvk_hdr;
+
+	if (!do_PVK_header(&p, 24, 0, &saltlen, &keylen))
+		return 0;
+	buflen = keylen + saltlen;
+	buf = malloc(buflen);
+	if (!buf) {
+		PEMerr(PEM_F_B2I_PVK_BIO, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	p = buf;
+	if (BIO_read(in, buf, buflen) != buflen) {
+		PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT);
+		goto err;
+	}
+	ret = do_PVK_body(&p, saltlen, keylen, cb, u);
+
+err:
+	if (buf) {
+		explicit_bzero(buf, buflen);
+		free(buf);
+	}
+	return ret;
+}
+
+static int
+i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel, pem_password_cb *cb,
+    void *u)
+{
+	int outlen = 24, pklen;
+	unsigned char *p, *salt = NULL;
+	EVP_CIPHER_CTX cctx;
+
+	EVP_CIPHER_CTX_init(&cctx);
+	if (enclevel)
+		outlen += PVK_SALTLEN;
+	pklen = do_i2b(NULL, pk, 0);
+	if (pklen < 0)
+		return -1;
+	outlen += pklen;
+	if (!out)
+		return outlen;
+	if (*out)
+		p = *out;
+	else {
+		p = malloc(outlen);
+		if (!p) {
+			PEMerr(PEM_F_I2B_PVK, ERR_R_MALLOC_FAILURE);
+			return -1;
+		}
+		*out = p;
+	}
+
+	write_ledword(&p, MS_PVKMAGIC);
+	write_ledword(&p, 0);
+	if (pk->type == EVP_PKEY_DSA)
+		write_ledword(&p, MS_KEYTYPE_SIGN);
+	else
+		write_ledword(&p, MS_KEYTYPE_KEYX);
+	write_ledword(&p, enclevel ? 1 : 0);
+	write_ledword(&p, enclevel ? PVK_SALTLEN : 0);
+	write_ledword(&p, pklen);
+	if (enclevel) {
+		arc4random_buf(p, PVK_SALTLEN);
+		salt = p;
+		p += PVK_SALTLEN;
+	}
+	do_i2b(&p, pk, 0);
+	if (enclevel == 0)
+		return outlen;
+	else {
+		char psbuf[PEM_BUFSIZE];
+		unsigned char keybuf[20];
+		int enctmplen, inlen;
+		if (cb)
+			inlen = cb(psbuf, PEM_BUFSIZE, 1, u);
+		else
+			inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 1, u);
+		if (inlen <= 0) {
+			PEMerr(PEM_F_I2B_PVK, PEM_R_BAD_PASSWORD_READ);
+			goto error;
+		}
+		if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN,
+		    (unsigned char *)psbuf, inlen))
+			goto error;
+		if (enclevel == 1)
+			memset(keybuf + 5, 0, 11);
+		p = salt + PVK_SALTLEN + 8;
+		if (!EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
+			goto error;
+		explicit_bzero(keybuf, 20);
+		if (!EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8))
+			goto error;
+		if (!EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen))
+			goto error;
+	}
+	EVP_CIPHER_CTX_cleanup(&cctx);
+	return outlen;
+
+error:
+	EVP_CIPHER_CTX_cleanup(&cctx);
+	return -1;
+}
+
+int
+i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, pem_password_cb *cb, void *u)
+{
+	unsigned char *tmp = NULL;
+	int outlen, wrlen;
+
+	outlen = i2b_PVK(&tmp, pk, enclevel, cb, u);
+	if (outlen < 0)
+		return -1;
+	wrlen = BIO_write(out, tmp, outlen);
+	free(tmp);
+	if (wrlen == outlen) {
+		PEMerr(PEM_F_I2B_PVK_BIO, PEM_R_BIO_WRITE_FAILURE);
+		return outlen;
+	}
+	return -1;
+}
+
+#endif
+
+#endif
diff --git a/crypto/libressl/crypto/pkcs12/p12_add.c b/crypto/libressl/crypto/pkcs12/p12_add.c
new file mode 100644
index 0000000000..594b58ecf2
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs12/p12_add.c
@@ -0,0 +1,266 @@
+/* $OpenBSD: p12_add.c,v 1.12 2015/02/14 12:43:07 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+
+/* Pack an object into an OCTET STRING and turn into a safebag */
+
+PKCS12_SAFEBAG *
+PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, int nid1, int nid2)
+{
+	PKCS12_BAGS *bag;
+	PKCS12_SAFEBAG *safebag;
+
+	if (!(bag = PKCS12_BAGS_new())) {
+		PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG,
+		    ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	bag->type = OBJ_nid2obj(nid1);
+	if (!ASN1_item_pack(obj, it, &bag->value.octet)) {
+		PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG,
+		    ERR_R_MALLOC_FAILURE);
+		PKCS12_BAGS_free(bag);
+		return NULL;
+	}
+	if (!(safebag = PKCS12_SAFEBAG_new())) {
+		PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG,
+		    ERR_R_MALLOC_FAILURE);
+		PKCS12_BAGS_free(bag);
+		return NULL;
+	}
+	safebag->value.bag = bag;
+	safebag->type = OBJ_nid2obj(nid2);
+	return safebag;
+}
+
+/* Turn PKCS8 object into a keybag */
+
+PKCS12_SAFEBAG *
+PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8)
+{
+	PKCS12_SAFEBAG *bag;
+
+	if (!(bag = PKCS12_SAFEBAG_new())) {
+		PKCS12err(PKCS12_F_PKCS12_MAKE_KEYBAG, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	bag->type = OBJ_nid2obj(NID_keyBag);
+	bag->value.keybag = p8;
+	return bag;
+}
+
+/* Turn PKCS8 object into a shrouded keybag */
+
+PKCS12_SAFEBAG *
+PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass, int passlen,
+    unsigned char *salt, int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8)
+{
+	PKCS12_SAFEBAG *bag;
+	const EVP_CIPHER *pbe_ciph;
+
+	/* Set up the safe bag */
+	if (!(bag = PKCS12_SAFEBAG_new())) {
+		PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+
+	bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag);
+
+	pbe_ciph = EVP_get_cipherbynid(pbe_nid);
+
+	if (pbe_ciph)
+		pbe_nid = -1;
+
+	if (!(bag->value.shkeybag = PKCS8_encrypt(pbe_nid, pbe_ciph, pass,
+	    passlen, salt, saltlen, iter, p8))) {
+		PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE);
+		PKCS12_SAFEBAG_free(bag);
+		return NULL;
+	}
+
+	return bag;
+}
+
+/* Turn a stack of SAFEBAGS into a PKCS#7 data Contentinfo */
+PKCS7 *
+PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk)
+{
+	PKCS7 *p7;
+
+	if (!(p7 = PKCS7_new())) {
+		PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	p7->type = OBJ_nid2obj(NID_pkcs7_data);
+	if (!(p7->d.data = ASN1_OCTET_STRING_new())) {
+		PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	if (!ASN1_item_pack(sk, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), &p7->d.data)) {
+		PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA,
+		    PKCS12_R_CANT_PACK_STRUCTURE);
+		goto err;
+	}
+	return p7;
+
+err:
+	PKCS7_free(p7);
+	return NULL;
+}
+
+/* Unpack SAFEBAGS from PKCS#7 data ContentInfo */
+STACK_OF(PKCS12_SAFEBAG) *
+PKCS12_unpack_p7data(PKCS7 *p7)
+{
+	if (!PKCS7_type_is_data(p7)) {
+		PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA,
+		    PKCS12_R_CONTENT_TYPE_NOT_DATA);
+		return NULL;
+	}
+	return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS));
+}
+
+/* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */
+
+PKCS7 *
+PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
+    unsigned char *salt, int saltlen, int iter, STACK_OF(PKCS12_SAFEBAG) *bags)
+{
+	PKCS7 *p7;
+	X509_ALGOR *pbe;
+	const EVP_CIPHER *pbe_ciph;
+
+	if (!(p7 = PKCS7_new())) {
+		PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	if (!PKCS7_set_type(p7, NID_pkcs7_encrypted)) {
+		PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA,
+		    PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE);
+		goto err;
+	}
+
+	pbe_ciph = EVP_get_cipherbynid(pbe_nid);
+
+	if (pbe_ciph)
+		pbe = PKCS5_pbe2_set(pbe_ciph, iter, salt, saltlen);
+	else
+		pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen);
+
+	if (!pbe) {
+		PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	X509_ALGOR_free(p7->d.encrypted->enc_data->algorithm);
+	p7->d.encrypted->enc_data->algorithm = pbe;
+	ASN1_OCTET_STRING_free(p7->d.encrypted->enc_data->enc_data);
+	if (!(p7->d.encrypted->enc_data->enc_data = PKCS12_item_i2d_encrypt(
+	    pbe, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass, passlen, bags, 1))) {
+		PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA,
+		    PKCS12_R_ENCRYPT_ERROR);
+		goto err;
+	}
+
+	return p7;
+
+err:
+	PKCS7_free(p7);
+	return NULL;
+}
+
+STACK_OF(PKCS12_SAFEBAG) *
+PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, int passlen)
+{
+	if (!PKCS7_type_is_encrypted(p7))
+		return NULL;
+	return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm,
+	    ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass, passlen,
+	    p7->d.encrypted->enc_data->enc_data, 1);
+}
+
+PKCS8_PRIV_KEY_INFO *
+PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag, const char *pass, int passlen)
+{
+	return PKCS8_decrypt(bag->value.shkeybag, pass, passlen);
+}
+
+int
+PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes)
+{
+	if (ASN1_item_pack(safes, ASN1_ITEM_rptr(PKCS12_AUTHSAFES),
+	    &p12->authsafes->d.data))
+		return 1;
+	return 0;
+}
+
+STACK_OF(PKCS7) *
+PKCS12_unpack_authsafes(PKCS12 *p12)
+{
+	if (!PKCS7_type_is_data(p12->authsafes)) {
+		PKCS12err(PKCS12_F_PKCS12_UNPACK_AUTHSAFES,
+		    PKCS12_R_CONTENT_TYPE_NOT_DATA);
+		return NULL;
+	}
+	return ASN1_item_unpack(p12->authsafes->d.data,
+	    ASN1_ITEM_rptr(PKCS12_AUTHSAFES));
+}
diff --git a/crypto/libressl/crypto/pkcs12/p12_asn.c b/crypto/libressl/crypto/pkcs12/p12_asn.c
new file mode 100644
index 0000000000..0ab1ff8da7
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs12/p12_asn.c
@@ -0,0 +1,476 @@
+/* $OpenBSD: p12_asn.c,v 1.8 2015/07/25 15:42:14 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+
+/* PKCS#12 ASN1 module */
+
+static const ASN1_TEMPLATE PKCS12_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS12, version),
+		.field_name = "version",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS12, authsafes),
+		.field_name = "authsafes",
+		.item = &PKCS7_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(PKCS12, mac),
+		.field_name = "mac",
+		.item = &PKCS12_MAC_DATA_it,
+	},
+};
+
+const ASN1_ITEM PKCS12_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = PKCS12_seq_tt,
+	.tcount = sizeof(PKCS12_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(PKCS12),
+	.sname = "PKCS12",
+};
+
+
+PKCS12 *
+d2i_PKCS12(PKCS12 **a, const unsigned char **in, long len)
+{
+	return (PKCS12 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &PKCS12_it);
+}
+
+int
+i2d_PKCS12(PKCS12 *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS12_it);
+}
+
+PKCS12 *
+PKCS12_new(void)
+{
+	return (PKCS12 *)ASN1_item_new(&PKCS12_it);
+}
+
+void
+PKCS12_free(PKCS12 *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &PKCS12_it);
+}
+
+static const ASN1_TEMPLATE PKCS12_MAC_DATA_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS12_MAC_DATA, dinfo),
+		.field_name = "dinfo",
+		.item = &X509_SIG_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS12_MAC_DATA, salt),
+		.field_name = "salt",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(PKCS12_MAC_DATA, iter),
+		.field_name = "iter",
+		.item = &ASN1_INTEGER_it,
+	},
+};
+
+const ASN1_ITEM PKCS12_MAC_DATA_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = PKCS12_MAC_DATA_seq_tt,
+	.tcount = sizeof(PKCS12_MAC_DATA_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(PKCS12_MAC_DATA),
+	.sname = "PKCS12_MAC_DATA",
+};
+
+
+PKCS12_MAC_DATA *
+d2i_PKCS12_MAC_DATA(PKCS12_MAC_DATA **a, const unsigned char **in, long len)
+{
+	return (PKCS12_MAC_DATA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &PKCS12_MAC_DATA_it);
+}
+
+int
+i2d_PKCS12_MAC_DATA(PKCS12_MAC_DATA *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS12_MAC_DATA_it);
+}
+
+PKCS12_MAC_DATA *
+PKCS12_MAC_DATA_new(void)
+{
+	return (PKCS12_MAC_DATA *)ASN1_item_new(&PKCS12_MAC_DATA_it);
+}
+
+void
+PKCS12_MAC_DATA_free(PKCS12_MAC_DATA *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &PKCS12_MAC_DATA_it);
+}
+
+static const ASN1_TEMPLATE bag_default_tt = {
+	.flags = ASN1_TFLG_EXPLICIT,
+	.tag = 0,
+	.offset = offsetof(PKCS12_BAGS, value.other),
+	.field_name = "value.other",
+	.item = &ASN1_ANY_it,
+};
+
+static const ASN1_ADB_TABLE PKCS12_BAGS_adbtbl[] = {
+	{
+		.value = NID_x509Certificate,
+		.tt = {
+			.flags = ASN1_TFLG_EXPLICIT,
+			.tag = 0,
+			.offset = offsetof(PKCS12_BAGS, value.x509cert),
+			.field_name = "value.x509cert",
+			.item = &ASN1_OCTET_STRING_it,
+		},
+	
+	},
+	{
+		.value = NID_x509Crl,
+		.tt = {
+			.flags = ASN1_TFLG_EXPLICIT,
+			.tag = 0,
+			.offset = offsetof(PKCS12_BAGS, value.x509crl),
+			.field_name = "value.x509crl",
+			.item = &ASN1_OCTET_STRING_it,
+		},
+	
+	},
+	{
+		.value = NID_sdsiCertificate,
+		.tt = {
+			.flags = ASN1_TFLG_EXPLICIT,
+			.tag = 0,
+			.offset = offsetof(PKCS12_BAGS, value.sdsicert),
+			.field_name = "value.sdsicert",
+			.item = &ASN1_IA5STRING_it,
+		},
+	
+	},
+};
+
+static const ASN1_ADB PKCS12_BAGS_adb = {
+	.flags = 0,
+	.offset = offsetof(PKCS12_BAGS, type),
+	.app_items = 0,
+	.tbl = PKCS12_BAGS_adbtbl,
+	.tblcount = sizeof(PKCS12_BAGS_adbtbl) / sizeof(ASN1_ADB_TABLE),
+	.default_tt = &bag_default_tt,
+	.null_tt = NULL,
+};
+
+static const ASN1_TEMPLATE PKCS12_BAGS_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS12_BAGS, type),
+		.field_name = "type",
+		.item = &ASN1_OBJECT_it,
+	},
+	{
+		.flags = ASN1_TFLG_ADB_OID,
+		.tag = -1,
+		.offset = 0,
+		.field_name = "PKCS12_BAGS",
+		.item = (const ASN1_ITEM *)&PKCS12_BAGS_adb,
+	},
+};
+
+const ASN1_ITEM PKCS12_BAGS_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = PKCS12_BAGS_seq_tt,
+	.tcount = sizeof(PKCS12_BAGS_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(PKCS12_BAGS),
+	.sname = "PKCS12_BAGS",
+};
+
+
+PKCS12_BAGS *
+d2i_PKCS12_BAGS(PKCS12_BAGS **a, const unsigned char **in, long len)
+{
+	return (PKCS12_BAGS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &PKCS12_BAGS_it);
+}
+
+int
+i2d_PKCS12_BAGS(PKCS12_BAGS *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS12_BAGS_it);
+}
+
+PKCS12_BAGS *
+PKCS12_BAGS_new(void)
+{
+	return (PKCS12_BAGS *)ASN1_item_new(&PKCS12_BAGS_it);
+}
+
+void
+PKCS12_BAGS_free(PKCS12_BAGS *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &PKCS12_BAGS_it);
+}
+
+static const ASN1_TEMPLATE safebag_default_tt = {
+	.flags = ASN1_TFLG_EXPLICIT,
+	.tag = 0,
+	.offset = offsetof(PKCS12_SAFEBAG, value.other),
+	.field_name = "value.other",
+	.item = &ASN1_ANY_it,
+};
+
+static const ASN1_ADB_TABLE PKCS12_SAFEBAG_adbtbl[] = {
+	{
+		.value = NID_keyBag,
+		.tt = {
+			.flags = ASN1_TFLG_EXPLICIT,
+			.tag = 0,
+			.offset = offsetof(PKCS12_SAFEBAG, value.keybag),
+			.field_name = "value.keybag",
+			.item = &PKCS8_PRIV_KEY_INFO_it,
+		},
+	
+	},
+	{
+		.value = NID_pkcs8ShroudedKeyBag,
+		.tt = {
+			.flags = ASN1_TFLG_EXPLICIT,
+			.tag = 0,
+			.offset = offsetof(PKCS12_SAFEBAG, value.shkeybag),
+			.field_name = "value.shkeybag",
+			.item = &X509_SIG_it,
+		},
+	
+	},
+	{
+		.value = NID_safeContentsBag,
+		.tt = {
+			.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SET_OF,
+			.tag = 0,
+			.offset = offsetof(PKCS12_SAFEBAG, value.safes),
+			.field_name = "value.safes",
+			.item = &PKCS12_SAFEBAG_it,
+		},
+	},
+	{
+		.value = NID_certBag,
+		.tt = {
+			.flags = ASN1_TFLG_EXPLICIT,
+			.tag = 0,
+			.offset = offsetof(PKCS12_SAFEBAG, value.bag),
+			.field_name = "value.bag",
+			.item = &PKCS12_BAGS_it,
+		},
+	
+	},
+	{
+		.value = NID_crlBag,
+		.tt = {
+			.flags = ASN1_TFLG_EXPLICIT,
+			.tag = 0,
+			.offset = offsetof(PKCS12_SAFEBAG, value.bag),
+			.field_name = "value.bag",
+			.item = &PKCS12_BAGS_it,
+		},
+	
+	},
+	{
+		.value = NID_secretBag,
+		.tt = {
+			.flags = ASN1_TFLG_EXPLICIT,
+			.tag = 0,
+			.offset = offsetof(PKCS12_SAFEBAG, value.bag),
+			.field_name = "value.bag",
+			.item = &PKCS12_BAGS_it,
+		},
+	
+	},
+};
+
+static const ASN1_ADB PKCS12_SAFEBAG_adb = {
+	.flags = 0,
+	.offset = offsetof(PKCS12_SAFEBAG, type),
+	.app_items = 0,
+	.tbl = PKCS12_SAFEBAG_adbtbl,
+	.tblcount = sizeof(PKCS12_SAFEBAG_adbtbl) / sizeof(ASN1_ADB_TABLE),
+	.default_tt = &safebag_default_tt,
+	.null_tt = NULL,
+};
+
+static const ASN1_TEMPLATE PKCS12_SAFEBAG_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS12_SAFEBAG, type),
+		.field_name = "type",
+		.item = &ASN1_OBJECT_it,
+	},
+	{
+		.flags = ASN1_TFLG_ADB_OID,
+		.tag = -1,
+		.offset = 0,
+		.field_name = "PKCS12_SAFEBAG",
+		.item = (const ASN1_ITEM *)&PKCS12_SAFEBAG_adb,
+	},
+	{
+		.flags = ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(PKCS12_SAFEBAG, attrib),
+		.field_name = "attrib",
+		.item = &X509_ATTRIBUTE_it,
+	},
+};
+
+const ASN1_ITEM PKCS12_SAFEBAG_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = PKCS12_SAFEBAG_seq_tt,
+	.tcount = sizeof(PKCS12_SAFEBAG_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(PKCS12_SAFEBAG),
+	.sname = "PKCS12_SAFEBAG",
+};
+
+
+PKCS12_SAFEBAG *
+d2i_PKCS12_SAFEBAG(PKCS12_SAFEBAG **a, const unsigned char **in, long len)
+{
+	return (PKCS12_SAFEBAG *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &PKCS12_SAFEBAG_it);
+}
+
+int
+i2d_PKCS12_SAFEBAG(PKCS12_SAFEBAG *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS12_SAFEBAG_it);
+}
+
+PKCS12_SAFEBAG *
+PKCS12_SAFEBAG_new(void)
+{
+	return (PKCS12_SAFEBAG *)ASN1_item_new(&PKCS12_SAFEBAG_it);
+}
+
+void
+PKCS12_SAFEBAG_free(PKCS12_SAFEBAG *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &PKCS12_SAFEBAG_it);
+}
+
+/* SEQUENCE OF SafeBag */
+static const ASN1_TEMPLATE PKCS12_SAFEBAGS_item_tt = {
+	.flags = ASN1_TFLG_SEQUENCE_OF,
+	.tag = 0,
+	.offset = 0,
+	.field_name = "PKCS12_SAFEBAGS",
+	.item = &PKCS12_SAFEBAG_it,
+};
+
+const ASN1_ITEM PKCS12_SAFEBAGS_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = -1,
+	.templates = &PKCS12_SAFEBAGS_item_tt,
+	.tcount = 0,
+	.funcs = NULL,
+	.size = 0,
+	.sname = "PKCS12_SAFEBAGS",
+};
+
+/* Authsafes: SEQUENCE OF PKCS7 */
+static const ASN1_TEMPLATE PKCS12_AUTHSAFES_item_tt = {
+	.flags = ASN1_TFLG_SEQUENCE_OF,
+	.tag = 0,
+	.offset = 0,
+	.field_name = "PKCS12_AUTHSAFES",
+	.item = &PKCS7_it,
+};
+
+const ASN1_ITEM PKCS12_AUTHSAFES_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = -1,
+	.templates = &PKCS12_AUTHSAFES_item_tt,
+	.tcount = 0,
+	.funcs = NULL,
+	.size = 0,
+	.sname = "PKCS12_AUTHSAFES",
+};
+
diff --git a/crypto/libressl/crypto/pkcs12/p12_attr.c b/crypto/libressl/crypto/pkcs12/p12_attr.c
new file mode 100644
index 0000000000..fcb8472be8
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs12/p12_attr.c
@@ -0,0 +1,155 @@
+/* $OpenBSD: p12_attr.c,v 1.9 2014/07/08 09:24:53 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+/* Add a local keyid to a safebag */
+
+int
+PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen)
+{
+	if (X509at_add1_attr_by_NID(&bag->attrib, NID_localKeyID,
+	    V_ASN1_OCTET_STRING, name, namelen))
+		return 1;
+	else
+		return 0;
+}
+
+/* Add key usage to PKCS#8 structure */
+
+int
+PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage)
+{
+	unsigned char us_val;
+
+	us_val = (unsigned char) usage;
+	if (X509at_add1_attr_by_NID(&p8->attributes, NID_key_usage,
+	    V_ASN1_BIT_STRING, &us_val, 1))
+		return 1;
+	else
+		return 0;
+}
+
+/* Add a friendlyname to a safebag */
+
+int
+PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name, int namelen)
+{
+	if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName,
+	    MBSTRING_ASC, (unsigned char *)name, namelen))
+		return 1;
+	else
+		return 0;
+}
+
+
+int
+PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, const unsigned char *name,
+    int namelen)
+{
+	if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName,
+	    MBSTRING_BMP, name, namelen))
+		return 1;
+	else
+		return 0;
+}
+
+int
+PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, int namelen)
+{
+	if (X509at_add1_attr_by_NID(&bag->attrib, NID_ms_csp_name,
+	    MBSTRING_ASC, (unsigned char *)name, namelen))
+		return 1;
+	else
+		return 0;
+}
+
+ASN1_TYPE *
+PKCS12_get_attr_gen(STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid)
+{
+	X509_ATTRIBUTE *attrib;
+	int i;
+
+	if (!attrs)
+		return NULL;
+	for (i = 0; i < sk_X509_ATTRIBUTE_num (attrs); i++) {
+		attrib = sk_X509_ATTRIBUTE_value (attrs, i);
+		if (OBJ_obj2nid (attrib->object) == attr_nid) {
+			if (sk_ASN1_TYPE_num (attrib->value.set))
+				return sk_ASN1_TYPE_value(attrib->value.set, 0);
+			else
+				return NULL;
+		}
+	}
+	return NULL;
+}
+
+char *
+PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag)
+{
+	ASN1_TYPE *atype;
+
+	if (!(atype = PKCS12_get_attr(bag, NID_friendlyName)))
+		return NULL;
+	if (atype->type != V_ASN1_BMPSTRING)
+		return NULL;
+	return OPENSSL_uni2asc(atype->value.bmpstring->data,
+	    atype->value.bmpstring->length);
+}
diff --git a/crypto/libressl/crypto/pkcs12/p12_crpt.c b/crypto/libressl/crypto/pkcs12/p12_crpt.c
new file mode 100644
index 0000000000..21537aa2d0
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs12/p12_crpt.c
@@ -0,0 +1,118 @@
+/* $OpenBSD: p12_crpt.c,v 1.11 2014/07/11 08:44:49 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+
+/* PKCS#12 PBE algorithms now in static table */
+
+void
+PKCS12_PBE_add(void)
+{
+}
+
+int
+PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+    ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, int en_de)
+{
+	PBEPARAM *pbe;
+	int saltlen, iter, ret;
+	unsigned char *salt;
+	const unsigned char *pbuf;
+	unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
+
+	/* Extract useful info from parameter */
+	if (param == NULL || param->type != V_ASN1_SEQUENCE ||
+	    param->value.sequence == NULL) {
+		PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_DECODE_ERROR);
+		return 0;
+	}
+
+	pbuf = param->value.sequence->data;
+	if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) {
+		PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_DECODE_ERROR);
+		return 0;
+	}
+
+	if (!pbe->iter)
+		iter = 1;
+	else
+		iter = ASN1_INTEGER_get (pbe->iter);
+	salt = pbe->salt->data;
+	saltlen = pbe->salt->length;
+	if (!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_KEY_ID,
+	    iter, EVP_CIPHER_key_length(cipher), key, md)) {
+		PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_KEY_GEN_ERROR);
+		PBEPARAM_free(pbe);
+		return 0;
+	}
+	if (!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_IV_ID,
+	    iter, EVP_CIPHER_iv_length(cipher), iv, md)) {
+		PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_IV_GEN_ERROR);
+		PBEPARAM_free(pbe);
+		return 0;
+	}
+	PBEPARAM_free(pbe);
+	ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, en_de);
+	explicit_bzero(key, EVP_MAX_KEY_LENGTH);
+	explicit_bzero(iv, EVP_MAX_IV_LENGTH);
+	return ret;
+}
diff --git a/crypto/libressl/crypto/pkcs12/p12_crt.c b/crypto/libressl/crypto/pkcs12/p12_crt.c
new file mode 100644
index 0000000000..91d5e4917d
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs12/p12_crt.c
@@ -0,0 +1,350 @@
+/* $OpenBSD: p12_crt.c,v 1.15 2014/07/11 08:44:49 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+
+static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
+    PKCS12_SAFEBAG *bag);
+
+static int
+copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid)
+{
+	int idx;
+	X509_ATTRIBUTE *attr;
+
+	idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1);
+	if (idx < 0)
+		return 1;
+	attr = EVP_PKEY_get_attr(pkey, idx);
+	if (!X509at_add1_attr(&bag->attrib, attr))
+		return 0;
+	return 1;
+}
+
+PKCS12 *
+PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
+    STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, int mac_iter,
+    int keytype)
+{
+	PKCS12 *p12 = NULL;
+	STACK_OF(PKCS7) *safes = NULL;
+	STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
+	PKCS12_SAFEBAG *bag = NULL;
+	int i;
+	unsigned char keyid[EVP_MAX_MD_SIZE];
+	unsigned int keyidlen = 0;
+
+	/* Set defaults */
+	if (!nid_cert) {
+		nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC;
+	}
+	if (!nid_key)
+		nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+	if (!iter)
+		iter = PKCS12_DEFAULT_ITER;
+	if (!mac_iter)
+		mac_iter = 1;
+
+	if (!pkey && !cert && !ca) {
+		PKCS12err(PKCS12_F_PKCS12_CREATE,
+		    PKCS12_R_INVALID_NULL_ARGUMENT);
+		return NULL;
+	}
+
+	if (pkey && cert) {
+		if (!X509_check_private_key(cert, pkey))
+			return NULL;
+		X509_digest(cert, EVP_sha1(), keyid, &keyidlen);
+	}
+
+	if (cert) {
+		bag = PKCS12_add_cert(&bags, cert);
+		if (name && !PKCS12_add_friendlyname(bag, name, -1))
+			goto err;
+		if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
+			goto err;
+	}
+
+	/* Add all other certificates */
+	for (i = 0; i < sk_X509_num(ca); i++) {
+		if (!PKCS12_add_cert(&bags, sk_X509_value(ca, i)))
+			goto err;
+	}
+
+	if (bags && !PKCS12_add_safe(&safes, bags, nid_cert, iter, pass))
+		goto err;
+
+	sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+	bags = NULL;
+
+	if (pkey) {
+		bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass);
+
+		if (!bag)
+			goto err;
+
+		if (!copy_bag_attr(bag, pkey, NID_ms_csp_name))
+			goto err;
+		if (!copy_bag_attr(bag, pkey, NID_LocalKeySet))
+			goto err;
+
+		if (name && !PKCS12_add_friendlyname(bag, name, -1))
+			goto err;
+		if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
+			goto err;
+	}
+
+	if (bags && !PKCS12_add_safe(&safes, bags, -1, 0, NULL))
+		goto err;
+
+	sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+	bags = NULL;
+
+	p12 = PKCS12_add_safes(safes, 0);
+
+	if (!p12)
+		goto err;
+
+	sk_PKCS7_pop_free(safes, PKCS7_free);
+
+	safes = NULL;
+
+	if ((mac_iter != -1) &&
+	    !PKCS12_set_mac(p12, pass, -1, NULL, 0, mac_iter, NULL))
+		goto err;
+
+	return p12;
+
+err:
+	if (p12)
+		PKCS12_free(p12);
+	if (safes)
+		sk_PKCS7_pop_free(safes, PKCS7_free);
+	if (bags)
+		sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+	return NULL;
+}
+
+PKCS12_SAFEBAG *
+PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert)
+{
+	PKCS12_SAFEBAG *bag = NULL;
+	char *name;
+	int namelen = -1;
+	unsigned char *keyid;
+	int keyidlen = -1;
+
+	/* Add user certificate */
+	if (!(bag = PKCS12_x5092certbag(cert)))
+		goto err;
+
+	/* Use friendlyName and localKeyID in certificate.
+	 * (if present)
+	 */
+	name = (char *)X509_alias_get0(cert, &namelen);
+	if (name && !PKCS12_add_friendlyname(bag, name, namelen))
+		goto err;
+
+	keyid = X509_keyid_get0(cert, &keyidlen);
+
+	if (keyid && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
+		goto err;
+
+	if (!pkcs12_add_bag(pbags, bag))
+		goto err;
+
+	return bag;
+
+err:
+	if (bag)
+		PKCS12_SAFEBAG_free(bag);
+
+	return NULL;
+}
+
+PKCS12_SAFEBAG *
+PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, EVP_PKEY *key, int key_usage,
+    int iter, int nid_key, char *pass)
+{
+	PKCS12_SAFEBAG *bag = NULL;
+	PKCS8_PRIV_KEY_INFO *p8 = NULL;
+
+	/* Make a PKCS#8 structure */
+	if (!(p8 = EVP_PKEY2PKCS8(key)))
+		goto err;
+	if (key_usage && !PKCS8_add_keyusage(p8, key_usage))
+		goto err;
+	if (nid_key != -1) {
+		bag = PKCS12_MAKE_SHKEYBAG(nid_key, pass, -1, NULL, 0,
+		    iter, p8);
+		PKCS8_PRIV_KEY_INFO_free(p8);
+		p8 = NULL;
+	} else {
+		bag = PKCS12_MAKE_KEYBAG(p8);
+		if (bag != NULL)
+			p8 = NULL;
+	}
+
+	if (!bag)
+		goto err;
+
+	if (!pkcs12_add_bag(pbags, bag))
+		goto err;
+
+	return bag;
+
+err:
+	if (bag)
+		PKCS12_SAFEBAG_free(bag);
+	if (p8)
+		PKCS8_PRIV_KEY_INFO_free(p8);
+
+	return NULL;
+}
+
+int
+PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
+    int nid_safe, int iter, char *pass)
+{
+	PKCS7 *p7 = NULL;
+	int free_safes = 0;
+
+	if (!*psafes) {
+		*psafes = sk_PKCS7_new_null();
+		if (!*psafes)
+			return 0;
+		free_safes = 1;
+	} else
+		free_safes = 0;
+
+	if (nid_safe == 0)
+		nid_safe = NID_pbe_WithSHA1And40BitRC2_CBC;
+
+	if (nid_safe == -1)
+		p7 = PKCS12_pack_p7data(bags);
+	else
+		p7 = PKCS12_pack_p7encdata(nid_safe, pass, -1, NULL, 0,
+		    iter, bags);
+	if (!p7)
+		goto err;
+
+	if (!sk_PKCS7_push(*psafes, p7))
+		goto err;
+
+	return 1;
+
+err:
+	if (free_safes) {
+		sk_PKCS7_free(*psafes);
+		*psafes = NULL;
+	}
+
+	if (p7)
+		PKCS7_free(p7);
+
+	return 0;
+}
+
+static int
+pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag)
+{
+	int free_bags;
+
+	if (!pbags)
+		return 1;
+	if (!*pbags) {
+		*pbags = sk_PKCS12_SAFEBAG_new_null();
+		if (!*pbags)
+			return 0;
+		free_bags = 1;
+	} else
+		free_bags = 0;
+
+	if (!sk_PKCS12_SAFEBAG_push(*pbags, bag)) {
+		if (free_bags) {
+			sk_PKCS12_SAFEBAG_free(*pbags);
+			*pbags = NULL;
+		}
+		return 0;
+	}
+
+	return 1;
+}
+
+PKCS12 *
+PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7)
+{
+	PKCS12 *p12;
+
+	if (nid_p7 <= 0)
+		nid_p7 = NID_pkcs7_data;
+	p12 = PKCS12_init(nid_p7);
+
+	if (!p12)
+		return NULL;
+
+	if (!PKCS12_pack_authsafes(p12, safes)) {
+		PKCS12_free(p12);
+		return NULL;
+	}
+
+	return p12;
+}
diff --git a/crypto/libressl/crypto/pkcs12/p12_decr.c b/crypto/libressl/crypto/pkcs12/p12_decr.c
new file mode 100644
index 0000000000..1a5967fe98
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs12/p12_decr.c
@@ -0,0 +1,190 @@
+/* $OpenBSD: p12_decr.c,v 1.16 2015/09/10 15:56:25 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+
+/* Encrypt/Decrypt a buffer based on password and algor, result in a
+ * malloc'ed buffer
+ */
+
+unsigned char *
+PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass, int passlen,
+    unsigned char *in, int inlen, unsigned char **data, int *datalen, int en_de)
+{
+	unsigned char *out;
+	int outlen, i;
+	EVP_CIPHER_CTX ctx;
+
+	EVP_CIPHER_CTX_init(&ctx);
+	/* Decrypt data */
+	if (!EVP_PBE_CipherInit(algor->algorithm, pass, passlen,
+	    algor->parameter, &ctx, en_de)) {
+		out = NULL;
+		PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,
+		    PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR);
+		goto err;
+	}
+
+	if (!(out = malloc(inlen + EVP_CIPHER_CTX_block_size(&ctx)))) {
+		PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	if (!EVP_CipherUpdate(&ctx, out, &i, in, inlen)) {
+		free(out);
+		out = NULL;
+		PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_EVP_LIB);
+		goto err;
+	}
+
+	outlen = i;
+	if (!EVP_CipherFinal_ex(&ctx, out + i, &i)) {
+		free(out);
+		out = NULL;
+		PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,
+		    PKCS12_R_PKCS12_CIPHERFINAL_ERROR);
+		goto err;
+	}
+	outlen += i;
+	if (datalen)
+		*datalen = outlen;
+	if (data)
+		*data = out;
+
+err:
+	EVP_CIPHER_CTX_cleanup(&ctx);
+	return out;
+
+}
+
+/* Decrypt an OCTET STRING and decode ASN1 structure
+ * if zbuf set zero buffer after use.
+ */
+
+void *
+PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it,
+    const char *pass, int passlen, ASN1_OCTET_STRING *oct, int zbuf)
+{
+	unsigned char *out;
+	const unsigned char *p;
+	void *ret;
+	int outlen;
+
+	if (!PKCS12_pbe_crypt(algor, pass, passlen, oct->data, oct->length,
+	    &out, &outlen, 0)) {
+		PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I,
+		    PKCS12_R_PKCS12_PBE_CRYPT_ERROR);
+		return NULL;
+	}
+	p = out;
+	ret = ASN1_item_d2i(NULL, &p, outlen, it);
+	if (zbuf)
+		explicit_bzero(out, outlen);
+	if (!ret)
+		PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I,
+		    PKCS12_R_DECODE_ERROR);
+	free(out);
+	return ret;
+}
+
+/* Encode ASN1 structure and encrypt, return OCTET STRING
+ * if zbuf set zero encoding.
+ */
+
+ASN1_OCTET_STRING *
+PKCS12_item_i2d_encrypt(X509_ALGOR *algor, const ASN1_ITEM *it,
+    const char *pass, int passlen,
+    void *obj, int zbuf)
+{
+	ASN1_OCTET_STRING *oct;
+	unsigned char *in = NULL;
+	int inlen;
+
+	if (!(oct = ASN1_OCTET_STRING_new ())) {
+		PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT,
+		    ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	inlen = ASN1_item_i2d(obj, &in, it);
+	if (!in) {
+		PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT,
+		    PKCS12_R_ENCODE_ERROR);
+		goto err;
+	}
+	if (!PKCS12_pbe_crypt(algor, pass, passlen, in, inlen, &oct->data,
+	    &oct->length, 1)) {
+		PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT,
+		    PKCS12_R_ENCRYPT_ERROR);
+		goto err;
+	}
+	if (zbuf)
+		explicit_bzero(in, inlen);
+	free(in);
+	return oct;
+
+err:
+	free(in);
+	ASN1_OCTET_STRING_free(oct);
+	return NULL;
+}
+
+IMPLEMENT_PKCS12_STACK_OF(PKCS7)
diff --git a/crypto/libressl/crypto/pkcs12/p12_init.c b/crypto/libressl/crypto/pkcs12/p12_init.c
new file mode 100644
index 0000000000..d9383bca9b
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs12/p12_init.c
@@ -0,0 +1,97 @@
+/* $OpenBSD: p12_init.c,v 1.9 2014/07/11 08:44:49 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+
+/* Initialise a PKCS12 structure to take data */
+
+PKCS12 *
+PKCS12_init(int mode)
+{
+	PKCS12 *pkcs12;
+
+	if (!(pkcs12 = PKCS12_new())) {
+		PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	ASN1_INTEGER_set(pkcs12->version, 3);
+	pkcs12->authsafes->type = OBJ_nid2obj(mode);
+	switch (mode) {
+	case NID_pkcs7_data:
+		if (!(pkcs12->authsafes->d.data =
+		    ASN1_OCTET_STRING_new())) {
+			PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		break;
+	default:
+		PKCS12err(PKCS12_F_PKCS12_INIT,
+		    PKCS12_R_UNSUPPORTED_PKCS12_MODE);
+		goto err;
+	}
+
+	return pkcs12;
+
+err:
+	if (pkcs12 != NULL)
+		PKCS12_free(pkcs12);
+	return NULL;
+}
diff --git a/crypto/libressl/crypto/pkcs12/p12_key.c b/crypto/libressl/crypto/pkcs12/p12_key.c
new file mode 100644
index 0000000000..f4f62946c7
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs12/p12_key.c
@@ -0,0 +1,199 @@
+/* $OpenBSD: p12_key.c,v 1.22 2015/02/07 13:19:15 doug Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+/* PKCS12 compatible key/IV generation */
+#ifndef min
+#define min(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+int
+PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
+    int saltlen, int id, int iter, int n, unsigned char *out,
+    const EVP_MD *md_type)
+{
+	int ret;
+	unsigned char *unipass;
+	int uniplen;
+
+	if (!pass) {
+		unipass = NULL;
+		uniplen = 0;
+	} else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) {
+		PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen,
+	    id, iter, n, out, md_type);
+	if (ret <= 0)
+		return 0;
+	if (unipass) {
+		explicit_bzero(unipass, uniplen);
+		free(unipass);
+	}
+	return ret;
+}
+
+int
+PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
+    int saltlen, int id, int iter, int n, unsigned char *out,
+    const EVP_MD *md_type)
+{
+	unsigned char *B, *D, *I, *p, *Ai;
+	int Slen, Plen, Ilen, Ijlen;
+	int i, j, u, v;
+	int ret = 0;
+	BIGNUM *Ij, *Bpl1;	/* These hold Ij and B + 1 */
+	EVP_MD_CTX ctx;
+
+	EVP_MD_CTX_init(&ctx);
+	v = EVP_MD_block_size(md_type);
+	u = EVP_MD_size(md_type);
+	if (u < 0)
+		return 0;
+	D = malloc(v);
+	Ai = malloc(u);
+	B = malloc(v + 1);
+	Slen = v * ((saltlen + v - 1) / v);
+	if (passlen)
+		Plen = v * ((passlen + v - 1)/v);
+	else
+		Plen = 0;
+	Ilen = Slen + Plen;
+	I = malloc(Ilen);
+	Ij = BN_new();
+	Bpl1 = BN_new();
+	if (!D || !Ai || !B || !I || !Ij || !Bpl1)
+		goto err;
+	for (i = 0; i < v; i++)
+		D[i] = id;
+	p = I;
+	for (i = 0; i < Slen; i++)
+		*p++ = salt[i % saltlen];
+	for (i = 0; i < Plen; i++)
+		*p++ = pass[i % passlen];
+	for (;;) {
+		if (!EVP_DigestInit_ex(&ctx, md_type, NULL) ||
+		    !EVP_DigestUpdate(&ctx, D, v) ||
+		    !EVP_DigestUpdate(&ctx, I, Ilen) ||
+		    !EVP_DigestFinal_ex(&ctx, Ai, NULL))
+			goto err;
+		for (j = 1; j < iter; j++) {
+			if (!EVP_DigestInit_ex(&ctx, md_type, NULL) ||
+			    !EVP_DigestUpdate(&ctx, Ai, u) ||
+			    !EVP_DigestFinal_ex(&ctx, Ai, NULL))
+				goto err;
+		}
+		memcpy (out, Ai, min (n, u));
+		if (u >= n) {
+			ret = 1;
+			goto end;
+		}
+		n -= u;
+		out += u;
+		for (j = 0; j < v; j++)
+			B[j] = Ai[j % u];
+		/* Work out B + 1 first then can use B as tmp space */
+		if (!BN_bin2bn (B, v, Bpl1))
+			goto err;
+		if (!BN_add_word (Bpl1, 1))
+			goto err;
+		for (j = 0; j < Ilen; j += v) {
+			if (!BN_bin2bn(I + j, v, Ij))
+				goto err;
+			if (!BN_add(Ij, Ij, Bpl1))
+				goto err;
+			if (!BN_bn2bin(Ij, B))
+				goto err;
+			Ijlen = BN_num_bytes (Ij);
+			/* If more than 2^(v*8) - 1 cut off MSB */
+			if (Ijlen > v) {
+				if (!BN_bn2bin (Ij, B))
+					goto err;
+				memcpy (I + j, B + 1, v);
+#ifndef PKCS12_BROKEN_KEYGEN
+				/* If less than v bytes pad with zeroes */
+			} else if (Ijlen < v) {
+				memset(I + j, 0, v - Ijlen);
+				if (!BN_bn2bin(Ij, I + j + v - Ijlen))
+					goto err;
+#endif
+			} else if (!BN_bn2bin (Ij, I + j))
+				goto err;
+		}
+	}
+
+err:
+	PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_MALLOC_FAILURE);
+
+end:
+	free(Ai);
+	free(B);
+	free(D);
+	free(I);
+	BN_free(Ij);
+	BN_free(Bpl1);
+	EVP_MD_CTX_cleanup(&ctx);
+	return ret;
+}
diff --git a/crypto/libressl/crypto/pkcs12/p12_kiss.c b/crypto/libressl/crypto/pkcs12/p12_kiss.c
new file mode 100644
index 0000000000..978f57ee0d
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs12/p12_kiss.c
@@ -0,0 +1,297 @@
+/* $OpenBSD: p12_kiss.c,v 1.16 2014/07/11 08:44:49 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+
+/* Simplified PKCS#12 routines */
+
+static int parse_pk12( PKCS12 *p12, const char *pass, int passlen,
+    EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
+
+static int parse_bags( STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
+    int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
+
+static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen,
+    EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
+
+/* Parse and decrypt a PKCS#12 structure returning user key, user cert
+ * and other (CA) certs. Note either ca should be NULL, *ca should be NULL,
+ * or it should point to a valid STACK structure. pkey and cert can be
+ * passed unitialised.
+ */
+
+int
+PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
+    STACK_OF(X509) **ca)
+{
+	STACK_OF(X509) *ocerts = NULL;
+	X509 *x = NULL;
+	/* Check for NULL PKCS12 structure */
+
+	if (!p12) {
+		PKCS12err(PKCS12_F_PKCS12_PARSE,
+		    PKCS12_R_INVALID_NULL_PKCS12_POINTER);
+		return 0;
+	}
+
+	if (pkey)
+		*pkey = NULL;
+	if (cert)
+		*cert = NULL;
+
+	/* Check the mac */
+
+	/* If password is zero length or NULL then try verifying both cases
+	 * to determine which password is correct. The reason for this is that
+	 * under PKCS#12 password based encryption no password and a zero length
+	 * password are two different things...
+	 */
+
+	if (!pass || !*pass) {
+		if (PKCS12_verify_mac(p12, NULL, 0))
+			pass = NULL;
+		else if (PKCS12_verify_mac(p12, "", 0))
+			pass = "";
+		else {
+			PKCS12err(PKCS12_F_PKCS12_PARSE,
+			    PKCS12_R_MAC_VERIFY_FAILURE);
+			goto err;
+		}
+	} else if (!PKCS12_verify_mac(p12, pass, -1)) {
+		PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE);
+		goto err;
+	}
+
+	/* Allocate stack for other certificates */
+	ocerts = sk_X509_new_null();
+	if (!ocerts) {
+		PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+
+	if (!parse_pk12 (p12, pass, -1, pkey, ocerts)) {
+		PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_PARSE_ERROR);
+		goto err;
+	}
+
+	while ((x = sk_X509_pop(ocerts))) {
+		if (pkey && *pkey && cert && !*cert) {
+			if (X509_check_private_key(x, *pkey)) {
+				*cert = x;
+				x = NULL;
+			}
+		}
+
+		if (ca && x) {
+			if (!*ca)
+				*ca = sk_X509_new_null();
+			if (!*ca)
+				goto err;
+			if (!sk_X509_push(*ca, x))
+				goto err;
+			x = NULL;
+		}
+		X509_free(x);
+	}
+
+	if (ocerts)
+		sk_X509_pop_free(ocerts, X509_free);
+
+	return 1;
+
+err:
+	if (pkey && *pkey)
+		EVP_PKEY_free(*pkey);
+	if (cert)
+		X509_free(*cert);
+	X509_free(x);
+	if (ocerts)
+		sk_X509_pop_free(ocerts, X509_free);
+	return 0;
+}
+
+/* Parse the outer PKCS#12 structure */
+
+static int
+parse_pk12(PKCS12 *p12, const char *pass, int passlen, EVP_PKEY **pkey,
+    STACK_OF(X509) *ocerts)
+{
+	STACK_OF(PKCS7) *asafes;
+	STACK_OF(PKCS12_SAFEBAG) *bags;
+	int i, bagnid;
+	PKCS7 *p7;
+
+	if (!(asafes = PKCS12_unpack_authsafes (p12)))
+		return 0;
+	for (i = 0; i < sk_PKCS7_num (asafes); i++) {
+		p7 = sk_PKCS7_value (asafes, i);
+		bagnid = OBJ_obj2nid (p7->type);
+		if (bagnid == NID_pkcs7_data) {
+			bags = PKCS12_unpack_p7data(p7);
+		} else if (bagnid == NID_pkcs7_encrypted) {
+			bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
+		} else
+			continue;
+		if (!bags) {
+			sk_PKCS7_pop_free(asafes, PKCS7_free);
+			return 0;
+		}
+		if (!parse_bags(bags, pass, passlen, pkey, ocerts)) {
+			sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+			sk_PKCS7_pop_free(asafes, PKCS7_free);
+			return 0;
+		}
+		sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+	}
+	sk_PKCS7_pop_free(asafes, PKCS7_free);
+	return 1;
+}
+
+static int
+parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, int passlen,
+    EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
+{
+	int i;
+
+	for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
+		if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i), pass, passlen,
+		    pkey, ocerts))
+			return 0;
+	}
+	return 1;
+}
+
+static int
+parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, EVP_PKEY **pkey,
+    STACK_OF(X509) *ocerts)
+{
+	PKCS8_PRIV_KEY_INFO *p8;
+	X509 *x509;
+	ASN1_TYPE *attrib;
+	ASN1_BMPSTRING *fname = NULL;
+	ASN1_OCTET_STRING *lkid = NULL;
+
+	if ((attrib = PKCS12_get_attr (bag, NID_friendlyName)))
+		fname = attrib->value.bmpstring;
+
+	if ((attrib = PKCS12_get_attr (bag, NID_localKeyID)))
+		lkid = attrib->value.octet_string;
+
+	switch (M_PKCS12_bag_type(bag)) {
+	case NID_keyBag:
+		if (!pkey || *pkey)
+			return 1;
+		if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag)))
+			return 0;
+		break;
+
+	case NID_pkcs8ShroudedKeyBag:
+		if (!pkey || *pkey)
+			return 1;
+		if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
+			return 0;
+		*pkey = EVP_PKCS82PKEY(p8);
+		PKCS8_PRIV_KEY_INFO_free(p8);
+		if (!(*pkey))
+			return 0;
+		break;
+
+	case NID_certBag:
+		if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate )
+			return 1;
+		if (!(x509 = PKCS12_certbag2x509(bag)))
+			return 0;
+		if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) {
+			X509_free(x509);
+			return 0;
+		}
+		if (fname) {
+			int len, r;
+			unsigned char *data;
+			len = ASN1_STRING_to_UTF8(&data, fname);
+			if (len >= 0) {
+				r = X509_alias_set1(x509, data, len);
+				free(data);
+				if (!r) {
+					X509_free(x509);
+					return 0;
+				}
+			}
+		}
+
+		if (!sk_X509_push(ocerts, x509)) {
+			X509_free(x509);
+			return 0;
+		}
+
+		break;
+
+	case NID_safeContentsBag:
+		return parse_bags(bag->value.safes, pass, passlen,
+		    pkey, ocerts);
+		break;
+
+	default:
+		return 1;
+		break;
+	}
+	return 1;
+}
diff --git a/crypto/libressl/crypto/pkcs12/p12_mutl.c b/crypto/libressl/crypto/pkcs12/p12_mutl.c
new file mode 100644
index 0000000000..5e169b482f
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs12/p12_mutl.c
@@ -0,0 +1,210 @@
+/* $OpenBSD: p12_mutl.c,v 1.20 2015/07/29 14:58:34 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#ifndef OPENSSL_NO_HMAC
+
+#include 
+#include 
+#include 
+
+/* Generate a MAC */
+int
+PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
+    unsigned char *mac, unsigned int *maclen)
+{
+	const EVP_MD *md_type;
+	HMAC_CTX hmac;
+	unsigned char key[EVP_MAX_MD_SIZE], *salt;
+	int saltlen, iter;
+	int md_size;
+
+	if (!PKCS7_type_is_data(p12->authsafes)) {
+		PKCS12err(PKCS12_F_PKCS12_GEN_MAC,
+		    PKCS12_R_CONTENT_TYPE_NOT_DATA);
+		return 0;
+	}
+
+	salt = p12->mac->salt->data;
+	saltlen = p12->mac->salt->length;
+	if (!p12->mac->iter)
+		iter = 1;
+	else
+		iter = ASN1_INTEGER_get(p12->mac->iter);
+	if (!(md_type = EVP_get_digestbyobj(
+	    p12->mac->dinfo->algor->algorithm))) {
+		PKCS12err(PKCS12_F_PKCS12_GEN_MAC,
+		    PKCS12_R_UNKNOWN_DIGEST_ALGORITHM);
+		return 0;
+	}
+	md_size = EVP_MD_size(md_type);
+	if (md_size < 0)
+		return 0;
+	if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter,
+	    md_size, key, md_type)) {
+		PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR);
+		return 0;
+	}
+	HMAC_CTX_init(&hmac);
+	if (!HMAC_Init_ex(&hmac, key, md_size, md_type, NULL) ||
+	    !HMAC_Update(&hmac, p12->authsafes->d.data->data,
+	    p12->authsafes->d.data->length) ||
+	    !HMAC_Final(&hmac, mac, maclen)) {
+		HMAC_CTX_cleanup(&hmac);
+		return 0;
+	}
+	HMAC_CTX_cleanup(&hmac);
+	return 1;
+}
+
+/* Verify the mac */
+int
+PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen)
+{
+	unsigned char mac[EVP_MAX_MD_SIZE];
+	unsigned int maclen;
+
+	if (p12->mac == NULL) {
+		PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_ABSENT);
+		return 0;
+	}
+	if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) {
+		PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC,
+		    PKCS12_R_MAC_GENERATION_ERROR);
+		return 0;
+	}
+	if ((maclen != (unsigned int)p12->mac->dinfo->digest->length) ||
+	    memcmp(mac, p12->mac->dinfo->digest->data, maclen))
+		return 0;
+	return 1;
+}
+
+/* Set a mac */
+
+int
+PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, unsigned char *salt,
+    int saltlen, int iter, const EVP_MD *md_type)
+{
+	unsigned char mac[EVP_MAX_MD_SIZE];
+	unsigned int maclen;
+
+	if (!md_type)
+		md_type = EVP_sha1();
+	if (PKCS12_setup_mac(p12, iter, salt, saltlen, md_type) ==
+	    PKCS12_ERROR) {
+		PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_SETUP_ERROR);
+		return 0;
+	}
+	if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) {
+		PKCS12err(PKCS12_F_PKCS12_SET_MAC,
+		    PKCS12_R_MAC_GENERATION_ERROR);
+		return 0;
+	}
+	if (!(ASN1_STRING_set(p12->mac->dinfo->digest, mac, maclen))) {
+		PKCS12err(PKCS12_F_PKCS12_SET_MAC,
+		    PKCS12_R_MAC_STRING_SET_ERROR);
+		return 0;
+	}
+	return 1;
+}
+
+/* Set up a mac structure */
+int
+PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen,
+    const EVP_MD *md_type)
+{
+	if (!(p12->mac = PKCS12_MAC_DATA_new()))
+		return PKCS12_ERROR;
+	if (iter > 1) {
+		if (!(p12->mac->iter = ASN1_INTEGER_new())) {
+			PKCS12err(PKCS12_F_PKCS12_SETUP_MAC,
+			    ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		if (!ASN1_INTEGER_set(p12->mac->iter, iter)) {
+			PKCS12err(PKCS12_F_PKCS12_SETUP_MAC,
+			    ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+	}
+	if (!saltlen)
+		saltlen = PKCS12_SALT_LEN;
+	if (!(p12->mac->salt->data = malloc(saltlen))) {
+		PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	p12->mac->salt->length = saltlen;
+	if (!salt)
+		arc4random_buf(p12->mac->salt->data, saltlen);
+	else
+		memcpy (p12->mac->salt->data, salt, saltlen);
+	p12->mac->dinfo->algor->algorithm = OBJ_nid2obj(EVP_MD_type(md_type));
+	if (!(p12->mac->dinfo->algor->parameter = ASN1_TYPE_new())) {
+		PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	p12->mac->dinfo->algor->parameter->type = V_ASN1_NULL;
+
+	return 1;
+}
+#endif
diff --git a/crypto/libressl/crypto/pkcs12/p12_npas.c b/crypto/libressl/crypto/pkcs12/p12_npas.c
new file mode 100644
index 0000000000..aba62648c6
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs12/p12_npas.c
@@ -0,0 +1,244 @@
+/* $OpenBSD: p12_npas.c,v 1.9 2014/07/08 09:24:53 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* PKCS#12 password change routine */
+
+static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass);
+static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass,
+    char *newpass);
+static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass);
+static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen);
+
+/*
+ * Change the password on a PKCS#12 structure.
+ */
+
+int
+PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass)
+{
+	/* Check for NULL PKCS12 structure */
+
+	if (!p12) {
+		PKCS12err(PKCS12_F_PKCS12_NEWPASS,
+		    PKCS12_R_INVALID_NULL_PKCS12_POINTER);
+		return 0;
+	}
+
+	/* Check the mac */
+
+	if (!PKCS12_verify_mac(p12, oldpass, -1)) {
+		PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_MAC_VERIFY_FAILURE);
+		return 0;
+	}
+
+	if (!newpass_p12(p12, oldpass, newpass)) {
+		PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_PARSE_ERROR);
+		return 0;
+	}
+
+	return 1;
+}
+
+/* Parse the outer PKCS#12 structure */
+
+static int
+newpass_p12(PKCS12 *p12, char *oldpass, char *newpass)
+{
+	STACK_OF(PKCS7) *asafes, *newsafes;
+	STACK_OF(PKCS12_SAFEBAG) *bags;
+	int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0;
+	PKCS7 *p7, *p7new;
+	ASN1_OCTET_STRING *p12_data_tmp = NULL, *macnew = NULL;
+	unsigned char mac[EVP_MAX_MD_SIZE];
+	unsigned int maclen;
+
+	if (!(asafes = PKCS12_unpack_authsafes(p12)))
+		return 0;
+	if (!(newsafes = sk_PKCS7_new_null()))
+		return 0;
+	for (i = 0; i < sk_PKCS7_num(asafes); i++) {
+		p7 = sk_PKCS7_value(asafes, i);
+		bagnid = OBJ_obj2nid(p7->type);
+		if (bagnid == NID_pkcs7_data) {
+			bags = PKCS12_unpack_p7data(p7);
+		} else if (bagnid == NID_pkcs7_encrypted) {
+			bags = PKCS12_unpack_p7encdata(p7, oldpass, -1);
+			if (!alg_get(p7->d.encrypted->enc_data->algorithm,
+			    &pbe_nid, &pbe_iter, &pbe_saltlen)) {
+				sk_PKCS12_SAFEBAG_pop_free(bags,
+				    PKCS12_SAFEBAG_free);
+				bags = NULL;
+			}
+		} else
+			continue;
+		if (bags == NULL)
+			goto err;
+		if (!newpass_bags(bags, oldpass, newpass)) {
+			sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+			goto err;
+		}
+		/* Repack bag in same form with new password */
+		if (bagnid == NID_pkcs7_data)
+			p7new = PKCS12_pack_p7data(bags);
+		else
+			p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1,
+			    NULL, pbe_saltlen, pbe_iter, bags);
+		sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+		if (p7new == NULL)
+			goto err;
+		if (sk_PKCS7_push(newsafes, p7new) == 0)
+			goto err;
+	}
+	sk_PKCS7_pop_free(asafes, PKCS7_free);
+
+	/* Repack safe: save old safe in case of error */
+
+	p12_data_tmp = p12->authsafes->d.data;
+	if (!(p12->authsafes->d.data = ASN1_OCTET_STRING_new())) {
+		p12->authsafes->d.data = p12_data_tmp;
+		goto err;
+	}
+	if (!PKCS12_pack_authsafes(p12, newsafes))
+		goto saferr;
+
+	if (!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen))
+		goto saferr;
+	if (!(macnew = ASN1_OCTET_STRING_new()))
+		goto saferr;
+	if (!ASN1_OCTET_STRING_set(macnew, mac, maclen))
+		goto saferr;
+	ASN1_OCTET_STRING_free(p12->mac->dinfo->digest);
+	p12->mac->dinfo->digest = macnew;
+	ASN1_OCTET_STRING_free(p12_data_tmp);
+
+	return 1;
+
+saferr:
+	/* Restore old safe */
+	ASN1_OCTET_STRING_free(p12->authsafes->d.data);
+	ASN1_OCTET_STRING_free(macnew);
+	p12->authsafes->d.data = p12_data_tmp;
+	return 0;
+
+err:
+	sk_PKCS7_pop_free(asafes, PKCS7_free);
+	sk_PKCS7_pop_free(newsafes, PKCS7_free);
+	return 0;
+}
+
+
+static int
+newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass, char *newpass)
+{
+	int i;
+
+	for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
+		if (!newpass_bag(sk_PKCS12_SAFEBAG_value(bags, i),
+		    oldpass, newpass))
+			return 0;
+	}
+	return 1;
+}
+
+/* Change password of safebag: only needs handle shrouded keybags */
+
+static int
+newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass)
+{
+	PKCS8_PRIV_KEY_INFO *p8;
+	X509_SIG *p8new;
+	int p8_nid, p8_saltlen, p8_iter;
+
+	if (M_PKCS12_bag_type(bag) != NID_pkcs8ShroudedKeyBag)
+		return 1;
+
+	if (!(p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1)))
+		return 0;
+	if (!alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter,
+	    &p8_saltlen))
+		return 0;
+	if (!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen,
+	    p8_iter, p8))) return 0;
+	X509_SIG_free(bag->value.shkeybag);
+	bag->value.shkeybag = p8new;
+	return 1;
+}
+
+static int
+alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen)
+{
+	PBEPARAM *pbe;
+	const unsigned char *p;
+
+	p = alg->parameter->value.sequence->data;
+	pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length);
+	if (!pbe)
+		return 0;
+	*pnid = OBJ_obj2nid(alg->algorithm);
+	*piter = ASN1_INTEGER_get(pbe->iter);
+	*psaltlen = pbe->salt->length;
+	PBEPARAM_free(pbe);
+	return 1;
+}
diff --git a/crypto/libressl/crypto/pkcs12/p12_p8d.c b/crypto/libressl/crypto/pkcs12/p12_p8d.c
new file mode 100644
index 0000000000..f05c98c93a
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs12/p12_p8d.c
@@ -0,0 +1,68 @@
+/* $OpenBSD: p12_p8d.c,v 1.4 2014/07/08 09:24:53 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+PKCS8_PRIV_KEY_INFO *
+PKCS8_decrypt(X509_SIG *p8, const char *pass, int passlen)
+{
+	return PKCS12_item_decrypt_d2i(p8->algor,
+	    ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), pass, passlen, p8->digest, 1);
+}
diff --git a/crypto/libressl/crypto/pkcs12/p12_p8e.c b/crypto/libressl/crypto/pkcs12/p12_p8e.c
new file mode 100644
index 0000000000..7d29404109
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs12/p12_p8e.c
@@ -0,0 +1,100 @@
+/* $OpenBSD: p12_p8e.c,v 1.5 2014/07/11 08:44:49 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+
+X509_SIG *
+PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, const char *pass,
+    int passlen, unsigned char *salt, int saltlen, int iter,
+    PKCS8_PRIV_KEY_INFO *p8inf)
+{
+	X509_SIG *p8 = NULL;
+	X509_ALGOR *pbe;
+
+	if (!(p8 = X509_SIG_new())) {
+		PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	if (pbe_nid == -1)
+		pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen);
+	else
+		pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen);
+	if (!pbe) {
+		PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_ASN1_LIB);
+		goto err;
+	}
+	X509_ALGOR_free(p8->algor);
+	p8->algor = pbe;
+	ASN1_OCTET_STRING_free(p8->digest);
+	p8->digest = PKCS12_item_i2d_encrypt(pbe,
+	    ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), pass, passlen, p8inf, 1);
+	if (!p8->digest) {
+		PKCS12err(PKCS12_F_PKCS8_ENCRYPT, PKCS12_R_ENCRYPT_ERROR);
+		goto err;
+	}
+
+	return p8;
+
+err:
+	X509_SIG_free(p8);
+	return NULL;
+}
diff --git a/crypto/libressl/crypto/pkcs12/p12_utl.c b/crypto/libressl/crypto/pkcs12/p12_utl.c
new file mode 100644
index 0000000000..2e8b8ca905
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs12/p12_utl.c
@@ -0,0 +1,168 @@
+/* $OpenBSD: p12_utl.c,v 1.11 2014/07/10 13:58:23 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+
+/* Cheap and nasty Unicode stuff */
+
+unsigned char *
+OPENSSL_asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen)
+{
+	int ulen, i;
+	unsigned char *unitmp;
+
+	if (asclen == -1)
+		asclen = strlen(asc);
+	ulen = asclen * 2 + 2;
+	if (!(unitmp = malloc(ulen)))
+		return NULL;
+	for (i = 0; i < ulen - 2; i += 2) {
+		unitmp[i] = 0;
+		unitmp[i + 1] = asc[i >> 1];
+	}
+	/* Make result double null terminated */
+	unitmp[ulen - 2] = 0;
+	unitmp[ulen - 1] = 0;
+	if (unilen)
+		*unilen = ulen;
+	if (uni)
+		*uni = unitmp;
+	return unitmp;
+}
+
+char *
+OPENSSL_uni2asc(unsigned char *uni, int unilen)
+{
+	int asclen, i;
+	char *asctmp;
+
+	asclen = unilen / 2;
+	/* If no terminating zero allow for one */
+	if (!unilen || uni[unilen - 1])
+		asclen++;
+	uni++;
+	if (!(asctmp = malloc(asclen)))
+		return NULL;
+	for (i = 0; i < unilen; i += 2)
+		asctmp[i >> 1] = uni[i];
+	asctmp[asclen - 1] = 0;
+	return asctmp;
+}
+
+int
+i2d_PKCS12_bio(BIO *bp, PKCS12 *p12)
+{
+	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS12), bp, p12);
+}
+
+int
+i2d_PKCS12_fp(FILE *fp, PKCS12 *p12)
+{
+	return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS12), fp, p12);
+}
+
+PKCS12 *
+d2i_PKCS12_bio(BIO *bp, PKCS12 **p12)
+{
+	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS12), bp, p12);
+}
+
+PKCS12 *
+d2i_PKCS12_fp(FILE *fp, PKCS12 **p12)
+{
+	    return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS12), fp, p12);
+}
+
+PKCS12_SAFEBAG *
+PKCS12_x5092certbag(X509 *x509)
+{
+	return PKCS12_item_pack_safebag(x509, ASN1_ITEM_rptr(X509),
+	    NID_x509Certificate, NID_certBag);
+}
+
+PKCS12_SAFEBAG *
+PKCS12_x509crl2certbag(X509_CRL *crl)
+{
+	return PKCS12_item_pack_safebag(crl, ASN1_ITEM_rptr(X509_CRL),
+	    NID_x509Crl, NID_crlBag);
+}
+
+X509 *
+PKCS12_certbag2x509(PKCS12_SAFEBAG *bag)
+{
+	if (M_PKCS12_bag_type(bag) != NID_certBag)
+		return NULL;
+	if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate)
+		return NULL;
+	return ASN1_item_unpack(bag->value.bag->value.octet,
+	    ASN1_ITEM_rptr(X509));
+}
+
+X509_CRL *
+PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag)
+{
+	if (M_PKCS12_bag_type(bag) != NID_crlBag)
+		return NULL;
+	if (M_PKCS12_cert_bag_type(bag) != NID_x509Crl)
+		return NULL;
+	return ASN1_item_unpack(bag->value.bag->value.octet,
+	    ASN1_ITEM_rptr(X509_CRL));
+}
diff --git a/crypto/libressl/crypto/pkcs12/pk12err.c b/crypto/libressl/crypto/pkcs12/pk12err.c
new file mode 100644
index 0000000000..fe88858829
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs12/pk12err.c
@@ -0,0 +1,144 @@
+/* $OpenBSD: pk12err.c,v 1.9 2014/07/08 09:24:53 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS12,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS12,0,reason)
+
+static ERR_STRING_DATA PKCS12_str_functs[]= {
+	{ERR_FUNC(PKCS12_F_PARSE_BAG),	"PARSE_BAG"},
+	{ERR_FUNC(PKCS12_F_PARSE_BAGS),	"PARSE_BAGS"},
+	{ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME),	"PKCS12_ADD_FRIENDLYNAME"},
+	{ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC),	"PKCS12_add_friendlyname_asc"},
+	{ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI),	"PKCS12_add_friendlyname_uni"},
+	{ERR_FUNC(PKCS12_F_PKCS12_ADD_LOCALKEYID),	"PKCS12_add_localkeyid"},
+	{ERR_FUNC(PKCS12_F_PKCS12_CREATE),	"PKCS12_create"},
+	{ERR_FUNC(PKCS12_F_PKCS12_GEN_MAC),	"PKCS12_gen_mac"},
+	{ERR_FUNC(PKCS12_F_PKCS12_INIT),	"PKCS12_init"},
+	{ERR_FUNC(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I),	"PKCS12_item_decrypt_d2i"},
+	{ERR_FUNC(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT),	"PKCS12_item_i2d_encrypt"},
+	{ERR_FUNC(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG),	"PKCS12_item_pack_safebag"},
+	{ERR_FUNC(PKCS12_F_PKCS12_KEY_GEN_ASC),	"PKCS12_key_gen_asc"},
+	{ERR_FUNC(PKCS12_F_PKCS12_KEY_GEN_UNI),	"PKCS12_key_gen_uni"},
+	{ERR_FUNC(PKCS12_F_PKCS12_MAKE_KEYBAG),	"PKCS12_MAKE_KEYBAG"},
+	{ERR_FUNC(PKCS12_F_PKCS12_MAKE_SHKEYBAG),	"PKCS12_MAKE_SHKEYBAG"},
+	{ERR_FUNC(PKCS12_F_PKCS12_NEWPASS),	"PKCS12_newpass"},
+	{ERR_FUNC(PKCS12_F_PKCS12_PACK_P7DATA),	"PKCS12_pack_p7data"},
+	{ERR_FUNC(PKCS12_F_PKCS12_PACK_P7ENCDATA),	"PKCS12_pack_p7encdata"},
+	{ERR_FUNC(PKCS12_F_PKCS12_PARSE),	"PKCS12_parse"},
+	{ERR_FUNC(PKCS12_F_PKCS12_PBE_CRYPT),	"PKCS12_pbe_crypt"},
+	{ERR_FUNC(PKCS12_F_PKCS12_PBE_KEYIVGEN),	"PKCS12_PBE_keyivgen"},
+	{ERR_FUNC(PKCS12_F_PKCS12_SETUP_MAC),	"PKCS12_setup_mac"},
+	{ERR_FUNC(PKCS12_F_PKCS12_SET_MAC),	"PKCS12_set_mac"},
+	{ERR_FUNC(PKCS12_F_PKCS12_UNPACK_AUTHSAFES),	"PKCS12_unpack_authsafes"},
+	{ERR_FUNC(PKCS12_F_PKCS12_UNPACK_P7DATA),	"PKCS12_unpack_p7data"},
+	{ERR_FUNC(PKCS12_F_PKCS12_VERIFY_MAC),	"PKCS12_verify_mac"},
+	{ERR_FUNC(PKCS12_F_PKCS8_ADD_KEYUSAGE),	"PKCS8_add_keyusage"},
+	{ERR_FUNC(PKCS12_F_PKCS8_ENCRYPT),	"PKCS8_encrypt"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA PKCS12_str_reasons[]= {
+	{ERR_REASON(PKCS12_R_CANT_PACK_STRUCTURE), "cant pack structure"},
+	{ERR_REASON(PKCS12_R_CONTENT_TYPE_NOT_DATA), "content type not data"},
+	{ERR_REASON(PKCS12_R_DECODE_ERROR)       , "decode error"},
+	{ERR_REASON(PKCS12_R_ENCODE_ERROR)       , "encode error"},
+	{ERR_REASON(PKCS12_R_ENCRYPT_ERROR)      , "encrypt error"},
+	{ERR_REASON(PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE), "error setting encrypted data type"},
+	{ERR_REASON(PKCS12_R_INVALID_NULL_ARGUMENT), "invalid null argument"},
+	{ERR_REASON(PKCS12_R_INVALID_NULL_PKCS12_POINTER), "invalid null pkcs12 pointer"},
+	{ERR_REASON(PKCS12_R_IV_GEN_ERROR)       , "iv gen error"},
+	{ERR_REASON(PKCS12_R_KEY_GEN_ERROR)      , "key gen error"},
+	{ERR_REASON(PKCS12_R_MAC_ABSENT)         , "mac absent"},
+	{ERR_REASON(PKCS12_R_MAC_GENERATION_ERROR), "mac generation error"},
+	{ERR_REASON(PKCS12_R_MAC_SETUP_ERROR)    , "mac setup error"},
+	{ERR_REASON(PKCS12_R_MAC_STRING_SET_ERROR), "mac string set error"},
+	{ERR_REASON(PKCS12_R_MAC_VERIFY_ERROR)   , "mac verify error"},
+	{ERR_REASON(PKCS12_R_MAC_VERIFY_FAILURE) , "mac verify failure"},
+	{ERR_REASON(PKCS12_R_PARSE_ERROR)        , "parse error"},
+	{ERR_REASON(PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR), "pkcs12 algor cipherinit error"},
+	{ERR_REASON(PKCS12_R_PKCS12_CIPHERFINAL_ERROR), "pkcs12 cipherfinal error"},
+	{ERR_REASON(PKCS12_R_PKCS12_PBE_CRYPT_ERROR), "pkcs12 pbe crypt error"},
+	{ERR_REASON(PKCS12_R_UNKNOWN_DIGEST_ALGORITHM), "unknown digest algorithm"},
+	{ERR_REASON(PKCS12_R_UNSUPPORTED_PKCS12_MODE), "unsupported pkcs12 mode"},
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_PKCS12_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(PKCS12_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, PKCS12_str_functs);
+		ERR_load_strings(0, PKCS12_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/pkcs7/bio_pk7.c b/crypto/libressl/crypto/pkcs7/bio_pk7.c
new file mode 100644
index 0000000000..d9e386e100
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs7/bio_pk7.c
@@ -0,0 +1,66 @@
+/* $OpenBSD: bio_pk7.c,v 1.3 2014/06/12 15:49:30 deraadt Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+/* Streaming encode support for PKCS#7 */
+BIO *
+BIO_new_PKCS7(BIO *out, PKCS7 *p7)
+{
+	return BIO_new_NDEF(out, (ASN1_VALUE *)p7, ASN1_ITEM_rptr(PKCS7));
+}
diff --git a/crypto/libressl/crypto/pkcs7/pk7_asn1.c b/crypto/libressl/crypto/pkcs7/pk7_asn1.c
new file mode 100644
index 0000000000..d86675412d
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs7/pk7_asn1.c
@@ -0,0 +1,968 @@
+/* $OpenBSD: pk7_asn1.c,v 1.11 2015/02/10 06:37:38 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+/* PKCS#7 ASN1 module */
+
+/* This is the ANY DEFINED BY table for the top level PKCS#7 structure */
+
+static const ASN1_TEMPLATE p7default_tt = {
+	.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+	.tag = 0,
+	.offset = offsetof(PKCS7, d.other),
+	.field_name = "d.other",
+	.item = &ASN1_ANY_it,
+};
+
+static const ASN1_ADB_TABLE PKCS7_adbtbl[] = {
+	{
+		.value = NID_pkcs7_data,
+		.tt = {
+			.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF,
+			.tag = 0,
+			.offset = offsetof(PKCS7, d.data),
+			.field_name = "d.data",
+			.item = &ASN1_OCTET_STRING_NDEF_it,
+		},
+	
+	},
+	{
+		.value = NID_pkcs7_signed,
+		.tt = {
+			.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF,
+			.tag = 0,
+			.offset = offsetof(PKCS7, d.sign),
+			.field_name = "d.sign",
+			.item = &PKCS7_SIGNED_it,
+		},
+	
+	},
+	{
+		.value = NID_pkcs7_enveloped,
+		.tt = {
+			.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF,
+			.tag = 0,
+			.offset = offsetof(PKCS7, d.enveloped),
+			.field_name = "d.enveloped",
+			.item = &PKCS7_ENVELOPE_it,
+		},
+	
+	},
+	{
+		.value = NID_pkcs7_signedAndEnveloped,
+		.tt = {
+			.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF,
+			.tag = 0,
+			.offset = offsetof(PKCS7, d.signed_and_enveloped),
+			.field_name = "d.signed_and_enveloped",
+			.item = &PKCS7_SIGN_ENVELOPE_it,
+		},
+	
+	},
+	{
+		.value = NID_pkcs7_digest,
+		.tt = {
+			.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF,
+			.tag = 0,
+			.offset = offsetof(PKCS7, d.digest),
+			.field_name = "d.digest",
+			.item = &PKCS7_DIGEST_it,
+		},
+	
+	},
+	{
+		.value = NID_pkcs7_encrypted,
+		.tt = {
+			.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF,
+			.tag = 0,
+			.offset = offsetof(PKCS7, d.encrypted),
+			.field_name = "d.encrypted",
+			.item = &PKCS7_ENCRYPT_it,
+		},
+	
+	},
+};
+
+static const ASN1_ADB PKCS7_adb = {
+	.flags = 0,
+	.offset = offsetof(PKCS7, type),
+	.app_items = 0,
+	.tbl = PKCS7_adbtbl,
+	.tblcount = sizeof(PKCS7_adbtbl) / sizeof(ASN1_ADB_TABLE),
+	.default_tt = &p7default_tt,
+	.null_tt = NULL,
+};
+
+/* PKCS#7 streaming support */
+static int
+pk7_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
+{
+	ASN1_STREAM_ARG *sarg = exarg;
+	PKCS7 **pp7 = (PKCS7 **)pval;
+
+	switch (operation) {
+	case ASN1_OP_STREAM_PRE:
+		if (PKCS7_stream(&sarg->boundary, *pp7) <= 0)
+			return 0;
+
+	case ASN1_OP_DETACHED_PRE:
+		sarg->ndef_bio = PKCS7_dataInit(*pp7, sarg->out);
+		if (!sarg->ndef_bio)
+			return 0;
+		break;
+
+	case ASN1_OP_STREAM_POST:
+	case ASN1_OP_DETACHED_POST:
+		if (PKCS7_dataFinal(*pp7, sarg->ndef_bio) <= 0)
+			return 0;
+		break;
+	}
+	return 1;
+}
+
+static const ASN1_AUX PKCS7_aux = {
+	.app_data = NULL,
+	.flags = 0,
+	.ref_offset = 0,
+	.ref_lock = 0,
+	.asn1_cb = pk7_cb,
+	.enc_offset = 0,
+};
+static const ASN1_TEMPLATE PKCS7_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7, type),
+		.field_name = "type",
+		.item = &ASN1_OBJECT_it,
+	},
+	{
+		.flags = ASN1_TFLG_ADB_OID,
+		.tag = -1,
+		.offset = 0,
+		.field_name = "PKCS7",
+		.item = (const ASN1_ITEM *)&PKCS7_adb,
+	},
+};
+
+const ASN1_ITEM PKCS7_it = {
+	.itype = ASN1_ITYPE_NDEF_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = PKCS7_seq_tt,
+	.tcount = sizeof(PKCS7_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &PKCS7_aux,
+	.size = sizeof(PKCS7),
+	.sname = "PKCS7",
+};
+
+
+PKCS7 *
+d2i_PKCS7(PKCS7 **a, const unsigned char **in, long len)
+{
+	return (PKCS7 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &PKCS7_it);
+}
+
+int
+i2d_PKCS7(PKCS7 *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_it);
+}
+
+PKCS7 *
+PKCS7_new(void)
+{
+	return (PKCS7 *)ASN1_item_new(&PKCS7_it);
+}
+
+void
+PKCS7_free(PKCS7 *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &PKCS7_it);
+}
+
+int
+i2d_PKCS7_NDEF(PKCS7 *a, unsigned char **out)
+{
+	return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, &PKCS7_it);
+}
+
+PKCS7 *
+PKCS7_dup(PKCS7 *x)
+{
+	return ASN1_item_dup(&PKCS7_it, x);
+}
+
+static const ASN1_TEMPLATE PKCS7_SIGNED_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_SIGNED, version),
+		.field_name = "version",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_SET_OF,
+		.tag = 0,
+		.offset = offsetof(PKCS7_SIGNED, md_algs),
+		.field_name = "md_algs",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_SIGNED, contents),
+		.field_name = "contents",
+		.item = &PKCS7_it,
+	},
+	{
+		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(PKCS7_SIGNED, cert),
+		.field_name = "cert",
+		.item = &X509_it,
+	},
+	{
+		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
+		.tag = 1,
+		.offset = offsetof(PKCS7_SIGNED, crl),
+		.field_name = "crl",
+		.item = &X509_CRL_it,
+	},
+	{
+		.flags = ASN1_TFLG_SET_OF,
+		.tag = 0,
+		.offset = offsetof(PKCS7_SIGNED, signer_info),
+		.field_name = "signer_info",
+		.item = &PKCS7_SIGNER_INFO_it,
+	},
+};
+
+const ASN1_ITEM PKCS7_SIGNED_it = {
+	.itype = ASN1_ITYPE_NDEF_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = PKCS7_SIGNED_seq_tt,
+	.tcount = sizeof(PKCS7_SIGNED_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(PKCS7_SIGNED),
+	.sname = "PKCS7_SIGNED",
+};
+
+
+PKCS7_SIGNED *
+d2i_PKCS7_SIGNED(PKCS7_SIGNED **a, const unsigned char **in, long len)
+{
+	return (PKCS7_SIGNED *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &PKCS7_SIGNED_it);
+}
+
+int
+i2d_PKCS7_SIGNED(PKCS7_SIGNED *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_SIGNED_it);
+}
+
+PKCS7_SIGNED *
+PKCS7_SIGNED_new(void)
+{
+	return (PKCS7_SIGNED *)ASN1_item_new(&PKCS7_SIGNED_it);
+}
+
+void
+PKCS7_SIGNED_free(PKCS7_SIGNED *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &PKCS7_SIGNED_it);
+}
+
+/* Minor tweak to operation: free up EVP_PKEY */
+static int
+si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
+{
+	if (operation == ASN1_OP_FREE_POST) {
+		PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval;
+		EVP_PKEY_free(si->pkey);
+	}
+	return 1;
+}
+
+static const ASN1_AUX PKCS7_SIGNER_INFO_aux = {
+	.app_data = NULL,
+	.flags = 0,
+	.ref_offset = 0,
+	.ref_lock = 0,
+	.asn1_cb = si_cb,
+	.enc_offset = 0,
+};
+static const ASN1_TEMPLATE PKCS7_SIGNER_INFO_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_SIGNER_INFO, version),
+		.field_name = "version",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_SIGNER_INFO, issuer_and_serial),
+		.field_name = "issuer_and_serial",
+		.item = &PKCS7_ISSUER_AND_SERIAL_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_SIGNER_INFO, digest_alg),
+		.field_name = "digest_alg",
+		.item = &X509_ALGOR_it,
+	},
+	/* NB this should be a SET OF but we use a SEQUENCE OF so the
+	 * original order * is retained when the structure is reencoded.
+	 * Since the attributes are implicitly tagged this will not affect
+	 * the encoding.
+	 */
+	{
+		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(PKCS7_SIGNER_INFO, auth_attr),
+		.field_name = "auth_attr",
+		.item = &X509_ATTRIBUTE_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_SIGNER_INFO, digest_enc_alg),
+		.field_name = "digest_enc_alg",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_SIGNER_INFO, enc_digest),
+		.field_name = "enc_digest",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+	{
+		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
+		.tag = 1,
+		.offset = offsetof(PKCS7_SIGNER_INFO, unauth_attr),
+		.field_name = "unauth_attr",
+		.item = &X509_ATTRIBUTE_it,
+	},
+};
+
+const ASN1_ITEM PKCS7_SIGNER_INFO_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = PKCS7_SIGNER_INFO_seq_tt,
+	.tcount = sizeof(PKCS7_SIGNER_INFO_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &PKCS7_SIGNER_INFO_aux,
+	.size = sizeof(PKCS7_SIGNER_INFO),
+	.sname = "PKCS7_SIGNER_INFO",
+};
+
+
+PKCS7_SIGNER_INFO *
+d2i_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO **a, const unsigned char **in, long len)
+{
+	return (PKCS7_SIGNER_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &PKCS7_SIGNER_INFO_it);
+}
+
+int
+i2d_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_SIGNER_INFO_it);
+}
+
+PKCS7_SIGNER_INFO *
+PKCS7_SIGNER_INFO_new(void)
+{
+	return (PKCS7_SIGNER_INFO *)ASN1_item_new(&PKCS7_SIGNER_INFO_it);
+}
+
+void
+PKCS7_SIGNER_INFO_free(PKCS7_SIGNER_INFO *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &PKCS7_SIGNER_INFO_it);
+}
+
+static const ASN1_TEMPLATE PKCS7_ISSUER_AND_SERIAL_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_ISSUER_AND_SERIAL, issuer),
+		.field_name = "issuer",
+		.item = &X509_NAME_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_ISSUER_AND_SERIAL, serial),
+		.field_name = "serial",
+		.item = &ASN1_INTEGER_it,
+	},
+};
+
+const ASN1_ITEM PKCS7_ISSUER_AND_SERIAL_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = PKCS7_ISSUER_AND_SERIAL_seq_tt,
+	.tcount = sizeof(PKCS7_ISSUER_AND_SERIAL_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(PKCS7_ISSUER_AND_SERIAL),
+	.sname = "PKCS7_ISSUER_AND_SERIAL",
+};
+
+
+PKCS7_ISSUER_AND_SERIAL *
+d2i_PKCS7_ISSUER_AND_SERIAL(PKCS7_ISSUER_AND_SERIAL **a, const unsigned char **in, long len)
+{
+	return (PKCS7_ISSUER_AND_SERIAL *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &PKCS7_ISSUER_AND_SERIAL_it);
+}
+
+int
+i2d_PKCS7_ISSUER_AND_SERIAL(PKCS7_ISSUER_AND_SERIAL *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ISSUER_AND_SERIAL_it);
+}
+
+PKCS7_ISSUER_AND_SERIAL *
+PKCS7_ISSUER_AND_SERIAL_new(void)
+{
+	return (PKCS7_ISSUER_AND_SERIAL *)ASN1_item_new(&PKCS7_ISSUER_AND_SERIAL_it);
+}
+
+void
+PKCS7_ISSUER_AND_SERIAL_free(PKCS7_ISSUER_AND_SERIAL *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ISSUER_AND_SERIAL_it);
+}
+
+static const ASN1_TEMPLATE PKCS7_ENVELOPE_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_ENVELOPE, version),
+		.field_name = "version",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_SET_OF,
+		.tag = 0,
+		.offset = offsetof(PKCS7_ENVELOPE, recipientinfo),
+		.field_name = "recipientinfo",
+		.item = &PKCS7_RECIP_INFO_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_ENVELOPE, enc_data),
+		.field_name = "enc_data",
+		.item = &PKCS7_ENC_CONTENT_it,
+	},
+};
+
+const ASN1_ITEM PKCS7_ENVELOPE_it = {
+	.itype = ASN1_ITYPE_NDEF_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = PKCS7_ENVELOPE_seq_tt,
+	.tcount = sizeof(PKCS7_ENVELOPE_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(PKCS7_ENVELOPE),
+	.sname = "PKCS7_ENVELOPE",
+};
+
+
+PKCS7_ENVELOPE *
+d2i_PKCS7_ENVELOPE(PKCS7_ENVELOPE **a, const unsigned char **in, long len)
+{
+	return (PKCS7_ENVELOPE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &PKCS7_ENVELOPE_it);
+}
+
+int
+i2d_PKCS7_ENVELOPE(PKCS7_ENVELOPE *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ENVELOPE_it);
+}
+
+PKCS7_ENVELOPE *
+PKCS7_ENVELOPE_new(void)
+{
+	return (PKCS7_ENVELOPE *)ASN1_item_new(&PKCS7_ENVELOPE_it);
+}
+
+void
+PKCS7_ENVELOPE_free(PKCS7_ENVELOPE *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ENVELOPE_it);
+}
+
+/* Minor tweak to operation: free up X509 */
+static int
+ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
+{
+	if (operation == ASN1_OP_FREE_POST) {
+		PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval;
+		X509_free(ri->cert);
+	}
+	return 1;
+}
+
+static const ASN1_AUX PKCS7_RECIP_INFO_aux = {
+	.app_data = NULL,
+	.flags = 0,
+	.ref_offset = 0,
+	.ref_lock = 0,
+	.asn1_cb = ri_cb,
+	.enc_offset = 0,
+};
+static const ASN1_TEMPLATE PKCS7_RECIP_INFO_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_RECIP_INFO, version),
+		.field_name = "version",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_RECIP_INFO, issuer_and_serial),
+		.field_name = "issuer_and_serial",
+		.item = &PKCS7_ISSUER_AND_SERIAL_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_RECIP_INFO, key_enc_algor),
+		.field_name = "key_enc_algor",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_RECIP_INFO, enc_key),
+		.field_name = "enc_key",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+};
+
+const ASN1_ITEM PKCS7_RECIP_INFO_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = PKCS7_RECIP_INFO_seq_tt,
+	.tcount = sizeof(PKCS7_RECIP_INFO_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &PKCS7_RECIP_INFO_aux,
+	.size = sizeof(PKCS7_RECIP_INFO),
+	.sname = "PKCS7_RECIP_INFO",
+};
+
+
+PKCS7_RECIP_INFO *
+d2i_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO **a, const unsigned char **in, long len)
+{
+	return (PKCS7_RECIP_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &PKCS7_RECIP_INFO_it);
+}
+
+int
+i2d_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_RECIP_INFO_it);
+}
+
+PKCS7_RECIP_INFO *
+PKCS7_RECIP_INFO_new(void)
+{
+	return (PKCS7_RECIP_INFO *)ASN1_item_new(&PKCS7_RECIP_INFO_it);
+}
+
+void
+PKCS7_RECIP_INFO_free(PKCS7_RECIP_INFO *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &PKCS7_RECIP_INFO_it);
+}
+
+static const ASN1_TEMPLATE PKCS7_ENC_CONTENT_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_ENC_CONTENT, content_type),
+		.field_name = "content_type",
+		.item = &ASN1_OBJECT_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_ENC_CONTENT, algorithm),
+		.field_name = "algorithm",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(PKCS7_ENC_CONTENT, enc_data),
+		.field_name = "enc_data",
+		.item = &ASN1_OCTET_STRING_NDEF_it,
+	},
+};
+
+const ASN1_ITEM PKCS7_ENC_CONTENT_it = {
+	.itype = ASN1_ITYPE_NDEF_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = PKCS7_ENC_CONTENT_seq_tt,
+	.tcount = sizeof(PKCS7_ENC_CONTENT_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(PKCS7_ENC_CONTENT),
+	.sname = "PKCS7_ENC_CONTENT",
+};
+
+
+PKCS7_ENC_CONTENT *
+d2i_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT **a, const unsigned char **in, long len)
+{
+	return (PKCS7_ENC_CONTENT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &PKCS7_ENC_CONTENT_it);
+}
+
+int
+i2d_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ENC_CONTENT_it);
+}
+
+PKCS7_ENC_CONTENT *
+PKCS7_ENC_CONTENT_new(void)
+{
+	return (PKCS7_ENC_CONTENT *)ASN1_item_new(&PKCS7_ENC_CONTENT_it);
+}
+
+void
+PKCS7_ENC_CONTENT_free(PKCS7_ENC_CONTENT *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ENC_CONTENT_it);
+}
+
+static const ASN1_TEMPLATE PKCS7_SIGN_ENVELOPE_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_SIGN_ENVELOPE, version),
+		.field_name = "version",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_SET_OF,
+		.tag = 0,
+		.offset = offsetof(PKCS7_SIGN_ENVELOPE, recipientinfo),
+		.field_name = "recipientinfo",
+		.item = &PKCS7_RECIP_INFO_it,
+	},
+	{
+		.flags = ASN1_TFLG_SET_OF,
+		.tag = 0,
+		.offset = offsetof(PKCS7_SIGN_ENVELOPE, md_algs),
+		.field_name = "md_algs",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_SIGN_ENVELOPE, enc_data),
+		.field_name = "enc_data",
+		.item = &PKCS7_ENC_CONTENT_it,
+	},
+	{
+		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(PKCS7_SIGN_ENVELOPE, cert),
+		.field_name = "cert",
+		.item = &X509_it,
+	},
+	{
+		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
+		.tag = 1,
+		.offset = offsetof(PKCS7_SIGN_ENVELOPE, crl),
+		.field_name = "crl",
+		.item = &X509_CRL_it,
+	},
+	{
+		.flags = ASN1_TFLG_SET_OF,
+		.tag = 0,
+		.offset = offsetof(PKCS7_SIGN_ENVELOPE, signer_info),
+		.field_name = "signer_info",
+		.item = &PKCS7_SIGNER_INFO_it,
+	},
+};
+
+const ASN1_ITEM PKCS7_SIGN_ENVELOPE_it = {
+	.itype = ASN1_ITYPE_NDEF_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = PKCS7_SIGN_ENVELOPE_seq_tt,
+	.tcount = sizeof(PKCS7_SIGN_ENVELOPE_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(PKCS7_SIGN_ENVELOPE),
+	.sname = "PKCS7_SIGN_ENVELOPE",
+};
+
+
+PKCS7_SIGN_ENVELOPE *
+d2i_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE **a, const unsigned char **in, long len)
+{
+	return (PKCS7_SIGN_ENVELOPE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &PKCS7_SIGN_ENVELOPE_it);
+}
+
+int
+i2d_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_SIGN_ENVELOPE_it);
+}
+
+PKCS7_SIGN_ENVELOPE *
+PKCS7_SIGN_ENVELOPE_new(void)
+{
+	return (PKCS7_SIGN_ENVELOPE *)ASN1_item_new(&PKCS7_SIGN_ENVELOPE_it);
+}
+
+void
+PKCS7_SIGN_ENVELOPE_free(PKCS7_SIGN_ENVELOPE *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &PKCS7_SIGN_ENVELOPE_it);
+}
+
+static const ASN1_TEMPLATE PKCS7_ENCRYPT_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_ENCRYPT, version),
+		.field_name = "version",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_ENCRYPT, enc_data),
+		.field_name = "enc_data",
+		.item = &PKCS7_ENC_CONTENT_it,
+	},
+};
+
+const ASN1_ITEM PKCS7_ENCRYPT_it = {
+	.itype = ASN1_ITYPE_NDEF_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = PKCS7_ENCRYPT_seq_tt,
+	.tcount = sizeof(PKCS7_ENCRYPT_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(PKCS7_ENCRYPT),
+	.sname = "PKCS7_ENCRYPT",
+};
+
+
+PKCS7_ENCRYPT *
+d2i_PKCS7_ENCRYPT(PKCS7_ENCRYPT **a, const unsigned char **in, long len)
+{
+	return (PKCS7_ENCRYPT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &PKCS7_ENCRYPT_it);
+}
+
+int
+i2d_PKCS7_ENCRYPT(PKCS7_ENCRYPT *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ENCRYPT_it);
+}
+
+PKCS7_ENCRYPT *
+PKCS7_ENCRYPT_new(void)
+{
+	return (PKCS7_ENCRYPT *)ASN1_item_new(&PKCS7_ENCRYPT_it);
+}
+
+void
+PKCS7_ENCRYPT_free(PKCS7_ENCRYPT *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ENCRYPT_it);
+}
+
+static const ASN1_TEMPLATE PKCS7_DIGEST_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_DIGEST, version),
+		.field_name = "version",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_DIGEST, md),
+		.field_name = "md",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_DIGEST, contents),
+		.field_name = "contents",
+		.item = &PKCS7_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(PKCS7_DIGEST, digest),
+		.field_name = "digest",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+};
+
+const ASN1_ITEM PKCS7_DIGEST_it = {
+	.itype = ASN1_ITYPE_NDEF_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = PKCS7_DIGEST_seq_tt,
+	.tcount = sizeof(PKCS7_DIGEST_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(PKCS7_DIGEST),
+	.sname = "PKCS7_DIGEST",
+};
+
+
+PKCS7_DIGEST *
+d2i_PKCS7_DIGEST(PKCS7_DIGEST **a, const unsigned char **in, long len)
+{
+	return (PKCS7_DIGEST *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &PKCS7_DIGEST_it);
+}
+
+int
+i2d_PKCS7_DIGEST(PKCS7_DIGEST *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_DIGEST_it);
+}
+
+PKCS7_DIGEST *
+PKCS7_DIGEST_new(void)
+{
+	return (PKCS7_DIGEST *)ASN1_item_new(&PKCS7_DIGEST_it);
+}
+
+void
+PKCS7_DIGEST_free(PKCS7_DIGEST *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &PKCS7_DIGEST_it);
+}
+
+/* Specials for authenticated attributes */
+
+/* When signing attributes we want to reorder them to match the sorted
+ * encoding.
+ */
+
+static const ASN1_TEMPLATE PKCS7_ATTR_SIGN_item_tt = {
+	.flags = ASN1_TFLG_SET_ORDER,
+	.tag = 0,
+	.offset = 0,
+	.field_name = "PKCS7_ATTRIBUTES",
+	.item = &X509_ATTRIBUTE_it,
+};
+
+const ASN1_ITEM PKCS7_ATTR_SIGN_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = -1,
+	.templates = &PKCS7_ATTR_SIGN_item_tt,
+	.tcount = 0,
+	.funcs = NULL,
+	.size = 0,
+	.sname = "PKCS7_ATTR_SIGN",
+};
+
+/* When verifying attributes we need to use the received order. So
+ * we use SEQUENCE OF and tag it to SET OF
+ */
+
+static const ASN1_TEMPLATE PKCS7_ATTR_VERIFY_item_tt = {
+	.flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
+	.tag = V_ASN1_SET,
+	.offset = 0,
+	.field_name = "PKCS7_ATTRIBUTES",
+	.item = &X509_ATTRIBUTE_it,
+};
+
+const ASN1_ITEM PKCS7_ATTR_VERIFY_it = {
+	.itype = ASN1_ITYPE_PRIMITIVE,
+	.utype = -1,
+	.templates = &PKCS7_ATTR_VERIFY_item_tt,
+	.tcount = 0,
+	.funcs = NULL,
+	.size = 0,
+	.sname = "PKCS7_ATTR_VERIFY",
+};
+
+
+int
+PKCS7_print_ctx(BIO *out, PKCS7 *x, int indent, const ASN1_PCTX *pctx)
+{
+	return ASN1_item_print(out, (ASN1_VALUE *)x, indent,
+	    &PKCS7_it, pctx);
+}
diff --git a/crypto/libressl/crypto/pkcs7/pk7_attr.c b/crypto/libressl/crypto/pkcs7/pk7_attr.c
new file mode 100644
index 0000000000..2b84deb303
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs7/pk7_attr.c
@@ -0,0 +1,174 @@
+/* $OpenBSD: pk7_attr.c,v 1.9 2014/06/29 17:05:36 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001-2004 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+int
+PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK_OF(X509_ALGOR) *cap)
+{
+	ASN1_STRING *seq;
+	if (!(seq = ASN1_STRING_new())) {
+		PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,
+		    ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	seq->length = ASN1_item_i2d((ASN1_VALUE *)cap, &seq->data,
+	    ASN1_ITEM_rptr(X509_ALGORS));
+	return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities,
+	    V_ASN1_SEQUENCE, seq);
+}
+
+STACK_OF(X509_ALGOR) *
+PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si)
+{
+	ASN1_TYPE *cap;
+	const unsigned char *p;
+
+	cap = PKCS7_get_signed_attribute(si, NID_SMIMECapabilities);
+	if (!cap || (cap->type != V_ASN1_SEQUENCE))
+		return NULL;
+	p = cap->value.sequence->data;
+	return (STACK_OF(X509_ALGOR) *)
+	ASN1_item_d2i(NULL, &p, cap->value.sequence->length,
+	    ASN1_ITEM_rptr(X509_ALGORS));
+}
+
+/* Basic smime-capabilities OID and optional integer arg */
+int
+PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
+{
+	X509_ALGOR *alg;
+
+	if (!(alg = X509_ALGOR_new())) {
+		PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	ASN1_OBJECT_free(alg->algorithm);
+	alg->algorithm = OBJ_nid2obj(nid);
+	if (arg > 0) {
+		ASN1_INTEGER *nbit;
+
+		if (!(alg->parameter = ASN1_TYPE_new()))
+			goto err;
+		if (!(nbit = ASN1_INTEGER_new()))
+			goto err;
+		if (!ASN1_INTEGER_set(nbit, arg)) {
+			ASN1_INTEGER_free(nbit);
+			goto err;
+		}
+		alg->parameter->value.integer = nbit;
+		alg->parameter->type = V_ASN1_INTEGER;
+	}
+	if (sk_X509_ALGOR_push(sk, alg) == 0)
+		goto err;
+	return 1;
+
+err:
+	PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE);
+	X509_ALGOR_free(alg);
+	return 0;
+}
+
+int
+PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid)
+{
+	if (PKCS7_get_signed_attribute(si, NID_pkcs9_contentType))
+		return 0;
+	if (!coid)
+		coid = OBJ_nid2obj(NID_pkcs7_data);
+	return PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
+	    V_ASN1_OBJECT, coid);
+}
+
+int
+PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t)
+{
+	if (!t && !(t = X509_gmtime_adj(NULL, 0))) {
+		PKCS7err(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME,
+		    ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime,
+	    V_ASN1_UTCTIME, t);
+}
+
+int
+PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, const unsigned char *md,
+    int mdlen)
+{
+	ASN1_OCTET_STRING *os;
+
+	os = ASN1_OCTET_STRING_new();
+	if (!os)
+		return 0;
+	if (!ASN1_STRING_set(os, md, mdlen) ||
+	    !PKCS7_add_signed_attribute(si, NID_pkcs9_messageDigest,
+	    V_ASN1_OCTET_STRING, os)) {
+		ASN1_OCTET_STRING_free(os);
+		return 0;
+	}
+	return 1;
+}
diff --git a/crypto/libressl/crypto/pkcs7/pk7_doit.c b/crypto/libressl/crypto/pkcs7/pk7_doit.c
new file mode 100644
index 0000000000..378e2f9469
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs7/pk7_doit.c
@@ -0,0 +1,1287 @@
+/* $OpenBSD: pk7_doit.c,v 1.37 2015/09/10 15:56:25 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
+    void *value);
+static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid);
+
+static int
+PKCS7_type_is_other(PKCS7* p7)
+{
+	int isOther = 1;
+
+	int nid = OBJ_obj2nid(p7->type);
+
+	switch (nid ) {
+	case NID_pkcs7_data:
+	case NID_pkcs7_signed:
+	case NID_pkcs7_enveloped:
+	case NID_pkcs7_signedAndEnveloped:
+	case NID_pkcs7_digest:
+	case NID_pkcs7_encrypted:
+		isOther = 0;
+		break;
+	default:
+		isOther = 1;
+	}
+
+	return isOther;
+
+}
+
+static ASN1_OCTET_STRING *
+PKCS7_get_octet_string(PKCS7 *p7)
+{
+	if (PKCS7_type_is_data(p7))
+		return p7->d.data;
+	if (PKCS7_type_is_other(p7) && p7->d.other &&
+	    (p7->d.other->type == V_ASN1_OCTET_STRING))
+		return p7->d.other->value.octet_string;
+	return NULL;
+}
+
+static int
+PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg)
+{
+	BIO *btmp;
+	const EVP_MD *md;
+	if ((btmp = BIO_new(BIO_f_md())) == NULL) {
+		PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB);
+		goto err;
+	}
+
+	md = EVP_get_digestbyobj(alg->algorithm);
+	if (md == NULL) {
+		PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,
+		    PKCS7_R_UNKNOWN_DIGEST_TYPE);
+		goto err;
+	}
+
+	BIO_set_md(btmp, md);
+	if (*pbio == NULL)
+		*pbio = btmp;
+	else if (!BIO_push(*pbio, btmp)) {
+		PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB);
+		goto err;
+	}
+	btmp = NULL;
+
+	return 1;
+
+err:
+	BIO_free(btmp);
+	return 0;
+
+}
+
+static int
+pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, unsigned char *key, int keylen)
+{
+	EVP_PKEY_CTX *pctx = NULL;
+	EVP_PKEY *pkey = NULL;
+	unsigned char *ek = NULL;
+	int ret = 0;
+	size_t eklen;
+
+	pkey = X509_get_pubkey(ri->cert);
+	if (!pkey)
+		return 0;
+
+	pctx = EVP_PKEY_CTX_new(pkey, NULL);
+	if (!pctx)
+		return 0;
+
+	if (EVP_PKEY_encrypt_init(pctx) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
+	    EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0) {
+		PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR);
+		goto err;
+	}
+
+	if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0)
+		goto err;
+
+	ek = malloc(eklen);
+
+	if (ek == NULL) {
+		PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0)
+		goto err;
+
+	ASN1_STRING_set0(ri->enc_key, ek, eklen);
+	ek = NULL;
+
+	ret = 1;
+
+err:
+	EVP_PKEY_free(pkey);
+	EVP_PKEY_CTX_free(pctx);
+	free(ek);
+	return ret;
+}
+
+
+static int
+pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, PKCS7_RECIP_INFO *ri,
+    EVP_PKEY *pkey)
+{
+	EVP_PKEY_CTX *pctx = NULL;
+	unsigned char *ek = NULL;
+	size_t eklen;
+
+	int ret = -1;
+
+	pctx = EVP_PKEY_CTX_new(pkey, NULL);
+	if (!pctx)
+		return -1;
+
+	if (EVP_PKEY_decrypt_init(pctx) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
+	    EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0) {
+		PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR);
+		goto err;
+	}
+
+	if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
+	    ri->enc_key->data, ri->enc_key->length) <= 0)
+		goto err;
+
+	ek = malloc(eklen);
+	if (ek == NULL) {
+		PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	if (EVP_PKEY_decrypt(pctx, ek, &eklen,
+	    ri->enc_key->data, ri->enc_key->length) <= 0) {
+		ret = 0;
+		PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
+		goto err;
+	}
+
+	ret = 1;
+
+	if (*pek) {
+		explicit_bzero(*pek, *peklen);
+		free(*pek);
+	}
+
+	*pek = ek;
+	*peklen = eklen;
+
+err:
+	EVP_PKEY_CTX_free(pctx);
+	if (!ret && ek)
+		free(ek);
+
+	return ret;
+}
+
+BIO *
+PKCS7_dataInit(PKCS7 *p7, BIO *bio)
+{
+	int i;
+	BIO *out = NULL, *btmp = NULL;
+	X509_ALGOR *xa = NULL;
+	const EVP_CIPHER *evp_cipher = NULL;
+	STACK_OF(X509_ALGOR) *md_sk = NULL;
+	STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
+	X509_ALGOR *xalg = NULL;
+	PKCS7_RECIP_INFO *ri = NULL;
+	ASN1_OCTET_STRING *os = NULL;
+
+	if (p7 == NULL) {
+		PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER);
+		return NULL;
+	}
+
+	/*
+	 * The content field in the PKCS7 ContentInfo is optional,
+	 * but that really only applies to inner content (precisely,
+	 * detached signatures).
+	 *
+	 * When reading content, missing outer content is therefore
+	 * treated as an error.
+	 *
+	 * When creating content, PKCS7_content_new() must be called
+	 * before calling this method, so a NULL p7->d is always
+	 * an error.
+	 */
+	if (p7->d.ptr == NULL) {
+		PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT);
+		return NULL;
+	}
+
+	i = OBJ_obj2nid(p7->type);
+	p7->state = PKCS7_S_HEADER;
+
+	switch (i) {
+	case NID_pkcs7_signed:
+		md_sk = p7->d.sign->md_algs;
+		os = PKCS7_get_octet_string(p7->d.sign->contents);
+		break;
+	case NID_pkcs7_signedAndEnveloped:
+		rsk = p7->d.signed_and_enveloped->recipientinfo;
+		md_sk = p7->d.signed_and_enveloped->md_algs;
+		xalg = p7->d.signed_and_enveloped->enc_data->algorithm;
+		evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher;
+		if (evp_cipher == NULL) {
+			PKCS7err(PKCS7_F_PKCS7_DATAINIT,
+			    PKCS7_R_CIPHER_NOT_INITIALIZED);
+			goto err;
+		}
+		break;
+	case NID_pkcs7_enveloped:
+		rsk = p7->d.enveloped->recipientinfo;
+		xalg = p7->d.enveloped->enc_data->algorithm;
+		evp_cipher = p7->d.enveloped->enc_data->cipher;
+		if (evp_cipher == NULL) {
+			PKCS7err(PKCS7_F_PKCS7_DATAINIT,
+			    PKCS7_R_CIPHER_NOT_INITIALIZED);
+			goto err;
+		}
+		break;
+	case NID_pkcs7_digest:
+		xa = p7->d.digest->md;
+		os = PKCS7_get_octet_string(p7->d.digest->contents);
+		break;
+	case NID_pkcs7_data:
+		break;
+	default:
+		PKCS7err(PKCS7_F_PKCS7_DATAINIT,
+		    PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+		goto err;
+	}
+
+	for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++)
+		if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i)))
+			goto err;
+
+	if (xa && !PKCS7_bio_add_digest(&out, xa))
+		goto err;
+
+	if (evp_cipher != NULL) {
+		unsigned char key[EVP_MAX_KEY_LENGTH];
+		unsigned char iv[EVP_MAX_IV_LENGTH];
+		int keylen, ivlen;
+		EVP_CIPHER_CTX *ctx;
+
+		if ((btmp = BIO_new(BIO_f_cipher())) == NULL) {
+			PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB);
+			goto err;
+		}
+		BIO_get_cipher_ctx(btmp, &ctx);
+		keylen = EVP_CIPHER_key_length(evp_cipher);
+		ivlen = EVP_CIPHER_iv_length(evp_cipher);
+		xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
+		if (ivlen > 0)
+			arc4random_buf(iv, ivlen);
+		if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL,
+		    NULL, 1) <= 0)
+			goto err;
+		if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
+			goto err;
+		if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
+			goto err;
+
+		if (ivlen > 0) {
+			if (xalg->parameter == NULL) {
+				xalg->parameter = ASN1_TYPE_new();
+				if (xalg->parameter == NULL)
+					goto err;
+			}
+			if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
+				goto err;
+		}
+
+		/* Lets do the pub key stuff :-) */
+		for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
+			ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
+			if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
+				goto err;
+		}
+		explicit_bzero(key, keylen);
+
+		if (out == NULL)
+			out = btmp;
+		else
+			BIO_push(out, btmp);
+		btmp = NULL;
+	}
+
+	if (bio == NULL) {
+		if (PKCS7_is_detached(p7))
+			bio = BIO_new(BIO_s_null());
+		else if (os && os->length > 0)
+			bio = BIO_new_mem_buf(os->data, os->length);
+		if (bio == NULL) {
+			bio = BIO_new(BIO_s_mem());
+			if (bio == NULL)
+				goto err;
+			BIO_set_mem_eof_return(bio, 0);
+		}
+	}
+	if (out)
+		BIO_push(out, bio);
+	else
+		out = bio;
+	bio = NULL;
+	if (0) {
+err:
+		if (out != NULL)
+			BIO_free_all(out);
+		if (btmp != NULL)
+			BIO_free_all(btmp);
+		out = NULL;
+	}
+	return (out);
+}
+
+static int
+pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert)
+{
+	int ret;
+
+	ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
+	    pcert->cert_info->issuer);
+	if (ret)
+		return ret;
+	return ASN1_STRING_cmp(pcert->cert_info->serialNumber,
+	    ri->issuer_and_serial->serial);
+}
+
+/* int */
+BIO *
+PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
+{
+	int i, j;
+	BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL;
+	X509_ALGOR *xa;
+	ASN1_OCTET_STRING *data_body = NULL;
+	const EVP_MD *evp_md;
+	const EVP_CIPHER *evp_cipher = NULL;
+	EVP_CIPHER_CTX *evp_ctx = NULL;
+	X509_ALGOR *enc_alg = NULL;
+	STACK_OF(X509_ALGOR) *md_sk = NULL;
+	STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
+	PKCS7_RECIP_INFO *ri = NULL;
+	unsigned char *ek = NULL, *tkey = NULL;
+	int eklen = 0, tkeylen = 0;
+
+	if (p7 == NULL) {
+		PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+		    PKCS7_R_INVALID_NULL_POINTER);
+		return NULL;
+	}
+
+	if (p7->d.ptr == NULL) {
+		PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
+		return NULL;
+	}
+
+	i = OBJ_obj2nid(p7->type);
+	p7->state = PKCS7_S_HEADER;
+
+	switch (i) {
+	case NID_pkcs7_signed:
+		data_body = PKCS7_get_octet_string(p7->d.sign->contents);
+		md_sk = p7->d.sign->md_algs;
+		break;
+	case NID_pkcs7_signedAndEnveloped:
+		rsk = p7->d.signed_and_enveloped->recipientinfo;
+		md_sk = p7->d.signed_and_enveloped->md_algs;
+		data_body = p7->d.signed_and_enveloped->enc_data->enc_data;
+		enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm;
+		evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
+		if (evp_cipher == NULL) {
+			PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+			    PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
+			goto err;
+		}
+		break;
+	case NID_pkcs7_enveloped:
+		rsk = p7->d.enveloped->recipientinfo;
+		enc_alg = p7->d.enveloped->enc_data->algorithm;
+		data_body = p7->d.enveloped->enc_data->enc_data;
+		evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
+		if (evp_cipher == NULL) {
+			PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+			    PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
+			goto err;
+		}
+		break;
+	default:
+		PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+		    PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+		goto err;
+	}
+
+	/* We will be checking the signature */
+	if (md_sk != NULL) {
+		for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
+			xa = sk_X509_ALGOR_value(md_sk, i);
+			if ((btmp = BIO_new(BIO_f_md())) == NULL) {
+				PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+				    ERR_R_BIO_LIB);
+				goto err;
+			}
+
+			j = OBJ_obj2nid(xa->algorithm);
+			evp_md = EVP_get_digestbynid(j);
+			if (evp_md == NULL) {
+				PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+				    PKCS7_R_UNKNOWN_DIGEST_TYPE);
+				goto err;
+			}
+
+			BIO_set_md(btmp, evp_md);
+			if (out == NULL)
+				out = btmp;
+			else
+				BIO_push(out, btmp);
+			btmp = NULL;
+		}
+	}
+
+	if (evp_cipher != NULL) {
+		if ((etmp = BIO_new(BIO_f_cipher())) == NULL) {
+			PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB);
+			goto err;
+		}
+
+		/* It was encrypted, we need to decrypt the secret key
+		 * with the private key */
+
+		/* Find the recipientInfo which matches the passed certificate
+		 * (if any)
+		 */
+		if (pcert) {
+			for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
+				ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
+				if (!pkcs7_cmp_ri(ri, pcert))
+					break;
+				ri = NULL;
+			}
+			if (ri == NULL) {
+				PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+				    PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
+				goto err;
+			}
+		}
+
+		/* If we haven't got a certificate try each ri in turn */
+		if (pcert == NULL) {
+			/* Always attempt to decrypt all rinfo even
+			 * after sucess as a defence against MMA timing
+			 * attacks.
+			 */
+			for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
+				ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
+
+				if (pkcs7_decrypt_rinfo(&ek, &eklen,
+				    ri, pkey) < 0)
+					goto err;
+				ERR_clear_error();
+			}
+		} else {
+			/* Only exit on fatal errors, not decrypt failure */
+			if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
+				goto err;
+			ERR_clear_error();
+		}
+
+		evp_ctx = NULL;
+		BIO_get_cipher_ctx(etmp, &evp_ctx);
+		if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL,
+		    NULL, 0) <= 0)
+			goto err;
+		if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0)
+			goto err;
+		/* Generate random key as MMA defence */
+		tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx);
+		tkey = malloc(tkeylen);
+		if (!tkey)
+			goto err;
+		if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0)
+			goto err;
+		if (ek == NULL) {
+			ek = tkey;
+			eklen = tkeylen;
+			tkey = NULL;
+		}
+
+		if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) {
+			/* Some S/MIME clients don't use the same key
+			 * and effective key length. The key length is
+			 * determined by the size of the decrypted RSA key.
+			 */
+			if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) {
+				/* Use random key as MMA defence */
+				explicit_bzero(ek, eklen);
+				free(ek);
+				ek = tkey;
+				eklen = tkeylen;
+				tkey = NULL;
+			}
+		}
+		/* Clear errors so we don't leak information useful in MMA */
+		ERR_clear_error();
+		if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, ek, NULL, 0) <= 0)
+			goto err;
+
+		if (ek) {
+			explicit_bzero(ek, eklen);
+			free(ek);
+			ek = NULL;
+		}
+		if (tkey) {
+			explicit_bzero(tkey, tkeylen);
+			free(tkey);
+			tkey = NULL;
+		}
+
+		if (out == NULL)
+			out = etmp;
+		else
+			BIO_push(out, etmp);
+		etmp = NULL;
+	}
+
+	if (PKCS7_is_detached(p7) || (in_bio != NULL)) {
+		bio = in_bio;
+	} else {
+		if (data_body != NULL && data_body->length > 0)
+			bio = BIO_new_mem_buf(data_body->data, data_body->length);
+		else {
+			bio = BIO_new(BIO_s_mem());
+			BIO_set_mem_eof_return(bio, 0);
+		}
+		if (bio == NULL)
+			goto err;
+	}
+	BIO_push(out, bio);
+
+	if (0) {
+err:
+		if (ek) {
+			explicit_bzero(ek, eklen);
+			free(ek);
+		}
+		if (tkey) {
+			explicit_bzero(tkey, tkeylen);
+			free(tkey);
+		}
+		if (out != NULL)
+			BIO_free_all(out);
+		if (btmp != NULL)
+			BIO_free_all(btmp);
+		if (etmp != NULL)
+			BIO_free_all(etmp);
+		out = NULL;
+	}
+	return (out);
+}
+
+static BIO *
+PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid)
+{
+	for (;;) {
+		bio = BIO_find_type(bio, BIO_TYPE_MD);
+		if (bio == NULL) {
+			PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,
+			    PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
+			return NULL;
+		}
+		BIO_get_md_ctx(bio, pmd);
+		if (*pmd == NULL) {
+			PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,
+			    ERR_R_INTERNAL_ERROR);
+			return NULL;
+		}
+		if (EVP_MD_CTX_type(*pmd) == nid)
+			return bio;
+		bio = BIO_next(bio);
+	}
+	return NULL;
+}
+
+static int
+do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx)
+{
+	unsigned char md_data[EVP_MAX_MD_SIZE];
+	unsigned int md_len;
+
+	/* Add signing time if not already present */
+	if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) {
+		if (!PKCS7_add0_attrib_signing_time(si, NULL)) {
+			PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB,
+			    ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+	}
+
+	/* Add digest */
+	if (!EVP_DigestFinal_ex(mctx, md_data, &md_len)) {
+		PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_EVP_LIB);
+		return 0;
+	}
+	if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) {
+		PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+
+	/* Now sign the attributes */
+	if (!PKCS7_SIGNER_INFO_sign(si))
+		return 0;
+
+	return 1;
+}
+
+
+int
+PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
+{
+	int ret = 0;
+	int i, j;
+	BIO *btmp;
+	PKCS7_SIGNER_INFO *si;
+	EVP_MD_CTX *mdc, ctx_tmp;
+	STACK_OF(X509_ATTRIBUTE) *sk;
+	STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
+	ASN1_OCTET_STRING *os = NULL;
+
+	if (p7 == NULL) {
+		PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
+		    PKCS7_R_INVALID_NULL_POINTER);
+		return 0;
+	}
+
+	if (p7->d.ptr == NULL) {
+		PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT);
+		return 0;
+	}
+
+	EVP_MD_CTX_init(&ctx_tmp);
+	i = OBJ_obj2nid(p7->type);
+	p7->state = PKCS7_S_HEADER;
+
+	switch (i) {
+	case NID_pkcs7_data:
+		os = p7->d.data;
+		break;
+	case NID_pkcs7_signedAndEnveloped:
+		/* XXX */
+		si_sk = p7->d.signed_and_enveloped->signer_info;
+		os = p7->d.signed_and_enveloped->enc_data->enc_data;
+		if (!os) {
+			os = ASN1_OCTET_STRING_new();
+			if (!os) {
+				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
+				    ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+			p7->d.signed_and_enveloped->enc_data->enc_data = os;
+		}
+		break;
+	case NID_pkcs7_enveloped:
+		/* XXX */
+		os = p7->d.enveloped->enc_data->enc_data;
+		if (!os) {
+			os = ASN1_OCTET_STRING_new();
+			if (!os) {
+				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
+				    ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+			p7->d.enveloped->enc_data->enc_data = os;
+		}
+		break;
+	case NID_pkcs7_signed:
+		si_sk = p7->d.sign->signer_info;
+		os = PKCS7_get_octet_string(p7->d.sign->contents);
+		if (!PKCS7_is_detached(p7) && os == NULL) {
+			PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_DECODE_ERROR);
+			goto err;
+		}
+		/* If detached data then the content is excluded */
+		if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
+			ASN1_OCTET_STRING_free(os);
+			os = NULL;
+			p7->d.sign->contents->d.data = NULL;
+		}
+		break;
+
+	case NID_pkcs7_digest:
+		os = PKCS7_get_octet_string(p7->d.digest->contents);
+		if (os == NULL) {
+			PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_DECODE_ERROR);
+			goto err;
+		}
+		/* If detached data then the content is excluded */
+		if (PKCS7_type_is_data(p7->d.digest->contents) &&
+		    p7->detached) {
+			ASN1_OCTET_STRING_free(os);
+			os = NULL;
+			p7->d.digest->contents->d.data = NULL;
+		}
+		break;
+
+	default:
+		PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
+		    PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+		goto err;
+	}
+
+	if (si_sk != NULL) {
+		for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) {
+			si = sk_PKCS7_SIGNER_INFO_value(si_sk, i);
+			if (si->pkey == NULL)
+				continue;
+
+			j = OBJ_obj2nid(si->digest_alg->algorithm);
+
+			btmp = bio;
+
+			btmp = PKCS7_find_digest(&mdc, btmp, j);
+
+			if (btmp == NULL)
+				goto err;
+
+			/* We now have the EVP_MD_CTX, lets do the
+			 * signing. */
+			if (!EVP_MD_CTX_copy_ex(&ctx_tmp, mdc))
+				goto err;
+
+			sk = si->auth_attr;
+
+			/* If there are attributes, we add the digest
+			 * attribute and only sign the attributes */
+			if (sk_X509_ATTRIBUTE_num(sk) > 0) {
+				if (!do_pkcs7_signed_attrib(si, &ctx_tmp))
+					goto err;
+			} else {
+				unsigned char *abuf = NULL;
+				unsigned int abuflen;
+				abuflen = EVP_PKEY_size(si->pkey);
+				abuf = malloc(abuflen);
+				if (!abuf)
+					goto err;
+
+				if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen,
+				    si->pkey)) {
+					PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
+					    ERR_R_EVP_LIB);
+					goto err;
+				}
+				ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
+			}
+		}
+	} else if (i == NID_pkcs7_digest) {
+		unsigned char md_data[EVP_MAX_MD_SIZE];
+		unsigned int md_len;
+
+		if (!PKCS7_find_digest(&mdc, bio,
+		    OBJ_obj2nid(p7->d.digest->md->algorithm)))
+			goto err;
+		if (!EVP_DigestFinal_ex(mdc, md_data, &md_len))
+			goto err;
+		if (ASN1_STRING_set(p7->d.digest->digest, md_data,
+		    md_len) == 0)
+			goto err;
+	}
+
+	if (!PKCS7_is_detached(p7)) {
+		/*
+		 * NOTE: only reach os == NULL here because detached
+		 * digested data support is broken?
+		 */
+		if (os == NULL)
+			goto err;
+		if (!(os->flags & ASN1_STRING_FLAG_NDEF)) {
+			char *cont;
+			long contlen;
+
+			btmp = BIO_find_type(bio, BIO_TYPE_MEM);
+			if (btmp == NULL) {
+				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
+				    PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
+				goto err;
+			}
+			contlen = BIO_get_mem_data(btmp, &cont);
+			/*
+			 * Mark the BIO read only then we can use its copy
+			 * of the data instead of making an extra copy.
+			 */
+			BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
+			BIO_set_mem_eof_return(btmp, 0);
+			ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
+		}
+	}
+	ret = 1;
+err:
+	EVP_MD_CTX_cleanup(&ctx_tmp);
+	return (ret);
+}
+
+int
+PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
+{
+	EVP_MD_CTX mctx;
+	EVP_PKEY_CTX *pctx;
+	unsigned char *abuf = NULL;
+	int alen;
+	size_t siglen;
+	const EVP_MD *md = NULL;
+
+	md = EVP_get_digestbyobj(si->digest_alg->algorithm);
+	if (md == NULL)
+		return 0;
+
+	EVP_MD_CTX_init(&mctx);
+	if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
+	    EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) {
+		PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
+		goto err;
+	}
+
+	alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf,
+	    ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
+	if (!abuf)
+		goto err;
+	if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0)
+		goto err;
+	free(abuf);
+	abuf = NULL;
+	if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
+		goto err;
+	abuf = malloc(siglen);
+	if (!abuf)
+		goto err;
+	if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
+	    EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) {
+		PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
+		goto err;
+	}
+
+	EVP_MD_CTX_cleanup(&mctx);
+
+	ASN1_STRING_set0(si->enc_digest, abuf, siglen);
+
+	return 1;
+
+err:
+	free(abuf);
+	EVP_MD_CTX_cleanup(&mctx);
+	return 0;
+}
+
+int
+PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
+    PKCS7 *p7, PKCS7_SIGNER_INFO *si)
+{
+	PKCS7_ISSUER_AND_SERIAL *ias;
+	int ret = 0, i;
+	STACK_OF(X509) *cert;
+	X509 *x509;
+
+	if (p7 == NULL) {
+		PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,
+		    PKCS7_R_INVALID_NULL_POINTER);
+		return 0;
+	}
+
+	if (p7->d.ptr == NULL) {
+		PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT);
+		return 0;
+	}
+
+	if (PKCS7_type_is_signed(p7)) {
+		cert = p7->d.sign->cert;
+	} else if (PKCS7_type_is_signedAndEnveloped(p7)) {
+		cert = p7->d.signed_and_enveloped->cert;
+	} else {
+		PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_WRONG_PKCS7_TYPE);
+		goto err;
+	}
+	/* XXXX */
+	ias = si->issuer_and_serial;
+
+	x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial);
+
+	/* were we able to find the cert in passed to us */
+	if (x509 == NULL) {
+		PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,
+		    PKCS7_R_UNABLE_TO_FIND_CERTIFICATE);
+		goto err;
+	}
+
+	/* Lets verify */
+	if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) {
+		PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB);
+		goto err;
+	}
+	X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN);
+	i = X509_verify_cert(ctx);
+	if (i <= 0) {
+		PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB);
+		X509_STORE_CTX_cleanup(ctx);
+		goto err;
+	}
+	X509_STORE_CTX_cleanup(ctx);
+
+	return PKCS7_signatureVerify(bio, p7, si, x509);
+err:
+	
+	return ret;
+}
+
+int
+PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, X509 *x509)
+{
+	ASN1_OCTET_STRING *os;
+	EVP_MD_CTX mdc_tmp, *mdc;
+	int ret = 0, i;
+	int md_type;
+	STACK_OF(X509_ATTRIBUTE) *sk;
+	BIO *btmp;
+	EVP_PKEY *pkey;
+
+	EVP_MD_CTX_init(&mdc_tmp);
+
+	if (!PKCS7_type_is_signed(p7) &&
+	    !PKCS7_type_is_signedAndEnveloped(p7)) {
+		PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+		    PKCS7_R_WRONG_PKCS7_TYPE);
+		goto err;
+	}
+
+	md_type = OBJ_obj2nid(si->digest_alg->algorithm);
+
+	btmp = bio;
+	for (;;) {
+		if ((btmp == NULL) ||
+		    ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) {
+			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+			    PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
+			goto err;
+		}
+		BIO_get_md_ctx(btmp, &mdc);
+		if (mdc == NULL) {
+			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+			    ERR_R_INTERNAL_ERROR);
+			goto err;
+		}
+		if (EVP_MD_CTX_type(mdc) == md_type)
+			break;
+		/* Workaround for some broken clients that put the signature
+		 * OID instead of the digest OID in digest_alg->algorithm
+		 */
+		if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type)
+			break;
+		btmp = BIO_next(btmp);
+	}
+
+	/* mdc is the digest ctx that we want, unless there are attributes,
+	 * in which case the digest is the signed attributes */
+	if (!EVP_MD_CTX_copy_ex(&mdc_tmp, mdc))
+		goto err;
+
+	sk = si->auth_attr;
+	if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) {
+		unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
+		unsigned int md_len;
+		int alen;
+		ASN1_OCTET_STRING *message_digest;
+
+		if (!EVP_DigestFinal_ex(&mdc_tmp, md_dat, &md_len))
+			goto err;
+		message_digest = PKCS7_digest_from_attributes(sk);
+		if (!message_digest) {
+			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+			    PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
+			goto err;
+		}
+		if ((message_digest->length != (int)md_len) ||
+		    (memcmp(message_digest->data, md_dat, md_len))) {
+			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+			    PKCS7_R_DIGEST_FAILURE);
+			ret = -1;
+			goto err;
+		}
+
+		if (!EVP_VerifyInit_ex(&mdc_tmp, EVP_get_digestbynid(md_type),
+		    NULL))
+			goto err;
+
+		alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
+		    ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
+		if (alen <= 0) {
+			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_ASN1_LIB);
+			ret = -1;
+			goto err;
+		}
+		if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen))
+			goto err;
+
+		free(abuf);
+	}
+
+	os = si->enc_digest;
+	pkey = X509_get_pubkey(x509);
+	if (!pkey) {
+		ret = -1;
+		goto err;
+	}
+
+	i = EVP_VerifyFinal(&mdc_tmp, os->data, os->length, pkey);
+	EVP_PKEY_free(pkey);
+	if (i <= 0) {
+		PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+		    PKCS7_R_SIGNATURE_FAILURE);
+		ret = -1;
+		goto err;
+	} else
+		ret = 1;
+err:
+	EVP_MD_CTX_cleanup(&mdc_tmp);
+	return (ret);
+}
+
+PKCS7_ISSUER_AND_SERIAL *
+PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
+{
+	STACK_OF(PKCS7_RECIP_INFO) *rsk;
+	PKCS7_RECIP_INFO *ri;
+	int i;
+
+	i = OBJ_obj2nid(p7->type);
+	if (i != NID_pkcs7_signedAndEnveloped)
+		return NULL;
+	if (p7->d.signed_and_enveloped == NULL)
+		return NULL;
+	rsk = p7->d.signed_and_enveloped->recipientinfo;
+	if (rsk == NULL)
+		return NULL;
+	ri = sk_PKCS7_RECIP_INFO_value(rsk, 0);
+	if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx)
+		return (NULL);
+	ri = sk_PKCS7_RECIP_INFO_value(rsk, idx);
+	return (ri->issuer_and_serial);
+}
+
+ASN1_TYPE *
+PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid)
+{
+	return (get_attribute(si->auth_attr, nid));
+}
+
+ASN1_TYPE *
+PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid)
+{
+	return (get_attribute(si->unauth_attr, nid));
+}
+
+static ASN1_TYPE *
+get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid)
+{
+	int i;
+	X509_ATTRIBUTE *xa;
+	ASN1_OBJECT *o;
+
+	o = OBJ_nid2obj(nid);
+	if (!o || !sk)
+		return (NULL);
+	for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
+		xa = sk_X509_ATTRIBUTE_value(sk, i);
+		if (OBJ_cmp(xa->object, o) == 0) {
+			if (!xa->single && sk_ASN1_TYPE_num(xa->value.set))
+				return (sk_ASN1_TYPE_value(xa->value.set, 0));
+			else
+				return (NULL);
+		}
+	}
+	return (NULL);
+}
+
+ASN1_OCTET_STRING *
+PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk)
+{
+	ASN1_TYPE *astype;
+
+	if (!(astype = get_attribute(sk, NID_pkcs9_messageDigest)))
+		return NULL;
+	if (astype->type != V_ASN1_OCTET_STRING)
+		return NULL;
+	return astype->value.octet_string;
+}
+
+int
+PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
+    STACK_OF(X509_ATTRIBUTE) *sk)
+{
+	int i;
+
+	if (p7si->auth_attr != NULL)
+		sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr,
+		    X509_ATTRIBUTE_free);
+	p7si->auth_attr = sk_X509_ATTRIBUTE_dup(sk);
+	if (p7si->auth_attr == NULL)
+		return 0;
+	for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
+		if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr, i,
+		    X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk, i))))
+		    == NULL)
+			return (0);
+	}
+	return (1);
+}
+
+int
+PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk)
+{
+	int i;
+
+	if (p7si->unauth_attr != NULL)
+		sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr,
+		    X509_ATTRIBUTE_free);
+	p7si->unauth_attr = sk_X509_ATTRIBUTE_dup(sk);
+	if (p7si->unauth_attr == NULL)
+		return 0;
+	for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
+		if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr, i,
+		    X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk, i))))
+		    == NULL)
+			return (0);
+	}
+	return (1);
+}
+
+int
+PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
+    void *value)
+{
+	return (add_attribute(&(p7si->auth_attr), nid, atrtype, value));
+}
+
+int
+PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, void *value)
+{
+	return (add_attribute(&(p7si->unauth_attr), nid, atrtype, value));
+}
+
+static int
+add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, void *value)
+{
+	X509_ATTRIBUTE *attr = NULL;
+
+	if (*sk == NULL) {
+		*sk = sk_X509_ATTRIBUTE_new_null();
+		if (*sk == NULL)
+			return 0;
+new_attrib:
+		if (!(attr = X509_ATTRIBUTE_create(nid, atrtype, value)))
+			return 0;
+		if (!sk_X509_ATTRIBUTE_push(*sk, attr)) {
+			X509_ATTRIBUTE_free(attr);
+			return 0;
+		}
+	} else {
+		int i;
+
+		for (i = 0; i < sk_X509_ATTRIBUTE_num(*sk); i++) {
+			attr = sk_X509_ATTRIBUTE_value(*sk, i);
+			if (OBJ_obj2nid(attr->object) == nid) {
+				X509_ATTRIBUTE_free(attr);
+				attr = X509_ATTRIBUTE_create(nid, atrtype,
+				    value);
+				if (attr == NULL)
+					return 0;
+				if (!sk_X509_ATTRIBUTE_set(*sk, i, attr)) {
+					X509_ATTRIBUTE_free(attr);
+					return 0;
+				}
+				goto end;
+			}
+		}
+		goto new_attrib;
+	}
+end:
+	return (1);
+}
diff --git a/crypto/libressl/crypto/pkcs7/pk7_lib.c b/crypto/libressl/crypto/pkcs7/pk7_lib.c
new file mode 100644
index 0000000000..94174aaaa8
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs7/pk7_lib.c
@@ -0,0 +1,668 @@
+/* $OpenBSD: pk7_lib.c,v 1.17 2015/09/30 17:30:15 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include "asn1_locl.h"
+
+long
+PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg)
+{
+	int nid;
+	long ret;
+
+	nid = OBJ_obj2nid(p7->type);
+
+	switch (cmd) {
+	case PKCS7_OP_SET_DETACHED_SIGNATURE:
+		if (nid == NID_pkcs7_signed) {
+			ret = p7->detached = (int)larg;
+			if (ret && PKCS7_type_is_data(p7->d.sign->contents)) {
+				ASN1_OCTET_STRING *os;
+				os = p7->d.sign->contents->d.data;
+				ASN1_OCTET_STRING_free(os);
+				p7->d.sign->contents->d.data = NULL;
+			}
+		} else {
+			PKCS7err(PKCS7_F_PKCS7_CTRL,
+			    PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
+			ret = 0;
+		}
+		break;
+	case PKCS7_OP_GET_DETACHED_SIGNATURE:
+		if (nid == NID_pkcs7_signed) {
+			if (!p7->d.sign  || !p7->d.sign->contents->d.ptr)
+				ret = 1;
+			else
+				ret = 0;
+
+			p7->detached = ret;
+		} else {
+			PKCS7err(PKCS7_F_PKCS7_CTRL,
+			    PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
+			ret = 0;
+		}
+
+		break;
+	default:
+		PKCS7err(PKCS7_F_PKCS7_CTRL, PKCS7_R_UNKNOWN_OPERATION);
+		ret = 0;
+	}
+	return (ret);
+}
+
+int
+PKCS7_content_new(PKCS7 *p7, int type)
+{
+	PKCS7 *ret = NULL;
+
+	if ((ret = PKCS7_new()) == NULL)
+		goto err;
+	if (!PKCS7_set_type(ret, type))
+		goto err;
+	if (!PKCS7_set_content(p7, ret))
+		goto err;
+
+	return (1);
+err:
+	if (ret != NULL)
+		PKCS7_free(ret);
+	return (0);
+}
+
+int
+PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data)
+{
+	int i;
+
+	i = OBJ_obj2nid(p7->type);
+	switch (i) {
+	case NID_pkcs7_signed:
+		if (p7->d.sign->contents != NULL)
+			PKCS7_free(p7->d.sign->contents);
+		p7->d.sign->contents = p7_data;
+		break;
+	case NID_pkcs7_digest:
+		if (p7->d.digest->contents != NULL)
+			PKCS7_free(p7->d.digest->contents);
+		p7->d.digest->contents = p7_data;
+		break;
+	case NID_pkcs7_data:
+	case NID_pkcs7_enveloped:
+	case NID_pkcs7_signedAndEnveloped:
+	case NID_pkcs7_encrypted:
+	default:
+		PKCS7err(PKCS7_F_PKCS7_SET_CONTENT,
+		    PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+		goto err;
+	}
+	return (1);
+err:
+	return (0);
+}
+
+int
+PKCS7_set_type(PKCS7 *p7, int type)
+{
+	ASN1_OBJECT *obj;
+
+	/*PKCS7_content_free(p7);*/
+	obj=OBJ_nid2obj(type); /* will not fail */
+
+	switch (type) {
+	case NID_pkcs7_signed:
+		p7->type = obj;
+		if ((p7->d.sign = PKCS7_SIGNED_new()) == NULL)
+			goto err;
+		if (!ASN1_INTEGER_set(p7->d.sign->version, 1)) {
+			PKCS7_SIGNED_free(p7->d.sign);
+			p7->d.sign = NULL;
+			goto err;
+		}
+		break;
+	case NID_pkcs7_data:
+		p7->type = obj;
+		if ((p7->d.data = ASN1_OCTET_STRING_new()) == NULL)
+			goto err;
+		break;
+	case NID_pkcs7_signedAndEnveloped:
+		p7->type = obj;
+		if ((p7->d.signed_and_enveloped =
+		    PKCS7_SIGN_ENVELOPE_new()) == NULL)
+			goto err;
+		ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1);
+		if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1))
+			goto err;
+		p7->d.signed_and_enveloped->enc_data->content_type =
+		    OBJ_nid2obj(NID_pkcs7_data);
+		break;
+	case NID_pkcs7_enveloped:
+		p7->type = obj;
+		if ((p7->d.enveloped = PKCS7_ENVELOPE_new()) == NULL)
+			goto err;
+		if (!ASN1_INTEGER_set(p7->d.enveloped->version, 0))
+			goto err;
+		p7->d.enveloped->enc_data->content_type =
+		    OBJ_nid2obj(NID_pkcs7_data);
+		break;
+	case NID_pkcs7_encrypted:
+		p7->type = obj;
+		if ((p7->d.encrypted = PKCS7_ENCRYPT_new()) == NULL)
+			goto err;
+		if (!ASN1_INTEGER_set(p7->d.encrypted->version, 0))
+			goto err;
+		p7->d.encrypted->enc_data->content_type =
+		    OBJ_nid2obj(NID_pkcs7_data);
+		break;
+
+	case NID_pkcs7_digest:
+		p7->type = obj;
+		if ((p7->d.digest = PKCS7_DIGEST_new()) == NULL)
+			goto err;
+		if (!ASN1_INTEGER_set(p7->d.digest->version, 0))
+			goto err;
+		break;
+	default:
+		PKCS7err(PKCS7_F_PKCS7_SET_TYPE,
+		    PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+		goto err;
+	}
+	return (1);
+err:
+	return (0);
+}
+
+int
+PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other)
+{
+	p7->type = OBJ_nid2obj(type);
+	p7->d.other = other;
+	return 1;
+}
+
+int
+PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
+{
+	int i, j, nid;
+	X509_ALGOR *alg;
+	STACK_OF(PKCS7_SIGNER_INFO) *signer_sk;
+	STACK_OF(X509_ALGOR) *md_sk;
+
+	i = OBJ_obj2nid(p7->type);
+	switch (i) {
+	case NID_pkcs7_signed:
+		signer_sk = p7->d.sign->signer_info;
+		md_sk = p7->d.sign->md_algs;
+		break;
+	case NID_pkcs7_signedAndEnveloped:
+		signer_sk = p7->d.signed_and_enveloped->signer_info;
+		md_sk = p7->d.signed_and_enveloped->md_algs;
+		break;
+	default:
+		PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, PKCS7_R_WRONG_CONTENT_TYPE);
+		return (0);
+	}
+
+	nid = OBJ_obj2nid(psi->digest_alg->algorithm);
+
+	/* If the digest is not currently listed, add it */
+	j = 0;
+	for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
+		alg = sk_X509_ALGOR_value(md_sk, i);
+		if (OBJ_obj2nid(alg->algorithm) == nid) {
+			j = 1;
+			break;
+		}
+	}
+	if (!j) /* we need to add another algorithm */
+	{
+		if (!(alg = X509_ALGOR_new()) ||
+		    !(alg->parameter = ASN1_TYPE_new())) {
+			X509_ALGOR_free(alg);
+			PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,
+			    ERR_R_MALLOC_FAILURE);
+			return (0);
+		}
+		alg->algorithm = OBJ_nid2obj(nid);
+		alg->parameter->type = V_ASN1_NULL;
+		if (!sk_X509_ALGOR_push(md_sk, alg)) {
+			X509_ALGOR_free(alg);
+			return 0;
+		}
+	}
+
+	if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi))
+		return 0;
+	return (1);
+}
+
+int
+PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
+{
+	int i;
+	STACK_OF(X509) **sk;
+
+	i = OBJ_obj2nid(p7->type);
+	switch (i) {
+	case NID_pkcs7_signed:
+		sk = &(p7->d.sign->cert);
+		break;
+	case NID_pkcs7_signedAndEnveloped:
+		sk = &(p7->d.signed_and_enveloped->cert);
+		break;
+	default:
+		PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE,
+		    PKCS7_R_WRONG_CONTENT_TYPE);
+		return (0);
+	}
+
+	if (*sk == NULL)
+		*sk = sk_X509_new_null();
+	if (*sk == NULL) {
+		PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
+	if (!sk_X509_push(*sk, x509)) {
+		X509_free(x509);
+		return 0;
+	}
+	return (1);
+}
+
+int
+PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
+{
+	int i;
+	STACK_OF(X509_CRL) **sk;
+
+	i = OBJ_obj2nid(p7->type);
+	switch (i) {
+	case NID_pkcs7_signed:
+		sk = &(p7->d.sign->crl);
+		break;
+	case NID_pkcs7_signedAndEnveloped:
+		sk = &(p7->d.signed_and_enveloped->crl);
+		break;
+	default:
+		PKCS7err(PKCS7_F_PKCS7_ADD_CRL, PKCS7_R_WRONG_CONTENT_TYPE);
+		return (0);
+	}
+
+	if (*sk == NULL)
+		*sk = sk_X509_CRL_new_null();
+	if (*sk == NULL) {
+		PKCS7err(PKCS7_F_PKCS7_ADD_CRL, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+
+	CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
+	if (!sk_X509_CRL_push(*sk, crl)) {
+		X509_CRL_free(crl);
+		return 0;
+	}
+	return (1);
+}
+
+int
+PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
+    const EVP_MD *dgst)
+{
+	int ret;
+
+	/* We now need to add another PKCS7_SIGNER_INFO entry */
+	if (!ASN1_INTEGER_set(p7i->version, 1))
+		goto err;
+	if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
+	    X509_get_issuer_name(x509)))
+		goto err;
+
+	/* because ASN1_INTEGER_set is used to set a 'long' we will do
+	 * things the ugly way. */
+	ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
+	if (!(p7i->issuer_and_serial->serial =
+	    ASN1_STRING_dup(X509_get_serialNumber(x509))))
+		goto err;
+
+	/* lets keep the pkey around for a while */
+	CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+	p7i->pkey = pkey;
+
+	/* Set the algorithms */
+
+	X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)),
+	    V_ASN1_NULL, NULL);
+
+	if (pkey->ameth && pkey->ameth->pkey_ctrl) {
+		ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN,
+		    0, p7i);
+		if (ret > 0)
+			return 1;
+		if (ret != -2) {
+			PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
+			    PKCS7_R_SIGNING_CTRL_FAILURE);
+			return 0;
+		}
+	}
+	PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
+	    PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+err:
+	return 0;
+}
+
+PKCS7_SIGNER_INFO *
+PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, const EVP_MD *dgst)
+{
+	PKCS7_SIGNER_INFO *si = NULL;
+
+	if (dgst == NULL) {
+		int def_nid;
+		if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
+			goto err;
+		dgst = EVP_get_digestbynid(def_nid);
+		if (dgst == NULL) {
+			PKCS7err(PKCS7_F_PKCS7_ADD_SIGNATURE,
+			    PKCS7_R_NO_DEFAULT_DIGEST);
+			goto err;
+		}
+	}
+
+	if ((si = PKCS7_SIGNER_INFO_new()) == NULL)
+		goto err;
+	if (!PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst))
+		goto err;
+	if (!PKCS7_add_signer(p7, si))
+		goto err;
+	return (si);
+err:
+	if (si)
+		PKCS7_SIGNER_INFO_free(si);
+	return (NULL);
+}
+
+int
+PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
+{
+	if (PKCS7_type_is_digest(p7)) {
+		if (!(p7->d.digest->md->parameter = ASN1_TYPE_new())) {
+			PKCS7err(PKCS7_F_PKCS7_SET_DIGEST,
+			    ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		p7->d.digest->md->parameter->type = V_ASN1_NULL;
+		p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md));
+		return 1;
+	}
+
+	PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, PKCS7_R_WRONG_CONTENT_TYPE);
+	return 1;
+}
+
+STACK_OF(PKCS7_SIGNER_INFO) *
+PKCS7_get_signer_info(PKCS7 *p7)
+{
+	if (p7 == NULL || p7->d.ptr == NULL)
+		return (NULL);
+	if (PKCS7_type_is_signed(p7)) {
+		return (p7->d.sign->signer_info);
+	} else if (PKCS7_type_is_signedAndEnveloped(p7)) {
+		return (p7->d.signed_and_enveloped->signer_info);
+	} else
+		return (NULL);
+}
+
+void
+PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
+    X509_ALGOR **pdig, X509_ALGOR **psig)
+{
+	if (pk)
+		*pk = si->pkey;
+	if (pdig)
+		*pdig = si->digest_alg;
+	if (psig)
+		*psig = si->digest_enc_alg;
+}
+
+void
+PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc)
+{
+	if (penc)
+		*penc = ri->key_enc_algor;
+}
+
+PKCS7_RECIP_INFO *
+PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
+{
+	PKCS7_RECIP_INFO *ri;
+
+	if ((ri = PKCS7_RECIP_INFO_new()) == NULL)
+		goto err;
+	if (!PKCS7_RECIP_INFO_set(ri, x509))
+		goto err;
+	if (!PKCS7_add_recipient_info(p7, ri))
+		goto err;
+	return ri;
+err:
+	if (ri)
+		PKCS7_RECIP_INFO_free(ri);
+	return NULL;
+}
+
+int
+PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
+{
+	int i;
+	STACK_OF(PKCS7_RECIP_INFO) *sk;
+
+	i = OBJ_obj2nid(p7->type);
+	switch (i) {
+	case NID_pkcs7_signedAndEnveloped:
+		sk = p7->d.signed_and_enveloped->recipientinfo;
+		break;
+	case NID_pkcs7_enveloped:
+		sk = p7->d.enveloped->recipientinfo;
+		break;
+	default:
+		PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,
+		    PKCS7_R_WRONG_CONTENT_TYPE);
+		return (0);
+	}
+
+	if (!sk_PKCS7_RECIP_INFO_push(sk, ri))
+		return 0;
+	return (1);
+}
+
+int
+PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
+{
+	int ret;
+	EVP_PKEY *pkey = NULL;
+	if (!ASN1_INTEGER_set(p7i->version, 0))
+		return 0;
+	if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
+	    X509_get_issuer_name(x509)))
+		return 0;
+
+	ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
+	if (!(p7i->issuer_and_serial->serial =
+	    ASN1_STRING_dup(X509_get_serialNumber(x509))))
+		return 0;
+
+	pkey = X509_get_pubkey(x509);
+
+	if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl) {
+		PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
+		    PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+		goto err;
+	}
+
+	ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT,
+	    0, p7i);
+	if (ret == -2) {
+		PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
+		    PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+		goto err;
+	}
+	if (ret <= 0) {
+		PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
+		    PKCS7_R_ENCRYPTION_CTRL_FAILURE);
+		goto err;
+	}
+
+	EVP_PKEY_free(pkey);
+
+	CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
+	p7i->cert = x509;
+
+	return 1;
+
+err:
+	EVP_PKEY_free(pkey);
+	return 0;
+}
+
+X509 *
+PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
+{
+	if (PKCS7_type_is_signed(p7))
+		return(X509_find_by_issuer_and_serial(p7->d.sign->cert,
+		    si->issuer_and_serial->issuer,
+		    si->issuer_and_serial->serial));
+	else
+		return (NULL);
+}
+
+int
+PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
+{
+	int i;
+	PKCS7_ENC_CONTENT *ec;
+
+	i = OBJ_obj2nid(p7->type);
+	switch (i) {
+	case NID_pkcs7_signedAndEnveloped:
+		ec = p7->d.signed_and_enveloped->enc_data;
+		break;
+	case NID_pkcs7_enveloped:
+		ec = p7->d.enveloped->enc_data;
+		break;
+	default:
+		PKCS7err(PKCS7_F_PKCS7_SET_CIPHER, PKCS7_R_WRONG_CONTENT_TYPE);
+		return (0);
+	}
+
+	/* Check cipher OID exists and has data in it*/
+	i = EVP_CIPHER_type(cipher);
+	if (i == NID_undef) {
+		PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,
+		    PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
+		return (0);
+	}
+
+	ec->cipher = cipher;
+	return 1;
+}
+
+int
+PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
+{
+	ASN1_OCTET_STRING *os = NULL;
+
+	switch (OBJ_obj2nid(p7->type)) {
+	case NID_pkcs7_data:
+		os = p7->d.data;
+		break;
+
+	case NID_pkcs7_signedAndEnveloped:
+		os = p7->d.signed_and_enveloped->enc_data->enc_data;
+		if (os == NULL) {
+			os = ASN1_OCTET_STRING_new();
+			p7->d.signed_and_enveloped->enc_data->enc_data = os;
+		}
+		break;
+
+	case NID_pkcs7_enveloped:
+		os = p7->d.enveloped->enc_data->enc_data;
+		if (os == NULL) {
+			os = ASN1_OCTET_STRING_new();
+			p7->d.enveloped->enc_data->enc_data = os;
+		}
+		break;
+
+	case NID_pkcs7_signed:
+		os = p7->d.sign->contents->d.data;
+		break;
+
+	default:
+		os = NULL;
+		break;
+	}
+
+	if (os == NULL)
+		return 0;
+
+	os->flags |= ASN1_STRING_FLAG_NDEF;
+	*boundary = &os->data;
+
+	return 1;
+}
diff --git a/crypto/libressl/crypto/pkcs7/pk7_mime.c b/crypto/libressl/crypto/pkcs7/pk7_mime.c
new file mode 100644
index 0000000000..bd060df791
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs7/pk7_mime.c
@@ -0,0 +1,98 @@
+/* $OpenBSD: pk7_mime.c,v 1.11 2014/07/11 08:44:49 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+
+/* PKCS#7 wrappers round generalised stream and MIME routines */
+
+int
+i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags)
+{
+	return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)p7, in, flags,
+	    ASN1_ITEM_rptr(PKCS7));
+}
+
+int
+PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags)
+{
+	return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *) p7, in, flags,
+	    "PKCS7", ASN1_ITEM_rptr(PKCS7));
+}
+
+int
+SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
+{
+	STACK_OF(X509_ALGOR) *mdalgs;
+	int ctype_nid = OBJ_obj2nid(p7->type);
+	if (ctype_nid == NID_pkcs7_signed)
+		mdalgs = p7->d.sign->md_algs;
+	else
+		mdalgs = NULL;
+
+	flags ^= SMIME_OLDMIME;
+
+
+	return SMIME_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags,
+	    ctype_nid, NID_undef, mdalgs, ASN1_ITEM_rptr(PKCS7));
+}
+
+PKCS7 *
+SMIME_read_PKCS7(BIO *bio, BIO **bcont)
+{
+	return (PKCS7 *)SMIME_read_ASN1(bio, bcont, ASN1_ITEM_rptr(PKCS7));
+}
diff --git a/crypto/libressl/crypto/pkcs7/pk7_smime.c b/crypto/libressl/crypto/pkcs7/pk7_smime.c
new file mode 100644
index 0000000000..bc8288db4f
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs7/pk7_smime.c
@@ -0,0 +1,600 @@
+/* $OpenBSD: pk7_smime.c,v 1.19 2014/11/09 19:17:13 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Simple PKCS#7 processing functions */
+
+#include 
+
+#include 
+#include 
+#include 
+
+static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
+
+PKCS7 *
+PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data,
+    int flags)
+{
+	PKCS7 *p7;
+	int i;
+
+	if (!(p7 = PKCS7_new())) {
+		PKCS7err(PKCS7_F_PKCS7_SIGN, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+
+	if (!PKCS7_set_type(p7, NID_pkcs7_signed))
+		goto err;
+
+	if (!PKCS7_content_new(p7, NID_pkcs7_data))
+		goto err;
+
+	if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags)) {
+		PKCS7err(PKCS7_F_PKCS7_SIGN, PKCS7_R_PKCS7_ADD_SIGNER_ERROR);
+		goto err;
+	}
+
+	if (!(flags & PKCS7_NOCERTS)) {
+		for (i = 0; i < sk_X509_num(certs); i++) {
+			if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i)))
+				goto err;
+		}
+	}
+
+	if (flags & PKCS7_DETACHED)
+		PKCS7_set_detached(p7, 1);
+
+	if (flags & (PKCS7_STREAM|PKCS7_PARTIAL))
+		return p7;
+
+	if (PKCS7_final(p7, data, flags))
+		return p7;
+
+err:
+	PKCS7_free(p7);
+	return NULL;
+}
+
+int
+PKCS7_final(PKCS7 *p7, BIO *data, int flags)
+{
+	BIO *p7bio;
+	int ret = 0;
+
+	if (!(p7bio = PKCS7_dataInit(p7, NULL))) {
+		PKCS7err(PKCS7_F_PKCS7_FINAL, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+
+	SMIME_crlf_copy(data, p7bio, flags);
+
+	(void)BIO_flush(p7bio);
+
+	if (!PKCS7_dataFinal(p7, p7bio)) {
+		PKCS7err(PKCS7_F_PKCS7_FINAL, PKCS7_R_PKCS7_DATASIGN);
+		goto err;
+	}
+
+	ret = 1;
+
+err:
+	BIO_free_all(p7bio);
+
+	return ret;
+}
+
+/* Check to see if a cipher exists and if so add S/MIME capabilities */
+
+static int
+add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
+{
+	if (EVP_get_cipherbynid(nid))
+		return PKCS7_simple_smimecap(sk, nid, arg);
+	return 1;
+}
+
+static int
+add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
+{
+	if (EVP_get_digestbynid(nid))
+		return PKCS7_simple_smimecap(sk, nid, arg);
+	return 1;
+}
+
+PKCS7_SIGNER_INFO *
+PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, EVP_PKEY *pkey,
+    const EVP_MD *md, int flags)
+{
+	PKCS7_SIGNER_INFO *si = NULL;
+	STACK_OF(X509_ALGOR) *smcap = NULL;
+
+	if (!X509_check_private_key(signcert, pkey)) {
+		PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
+		    PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+		return NULL;
+	}
+
+	if (!(si = PKCS7_add_signature(p7, signcert, pkey, md))) {
+		PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
+		    PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR);
+		return NULL;
+	}
+
+	if (!(flags & PKCS7_NOCERTS)) {
+		if (!PKCS7_add_certificate(p7, signcert))
+			goto err;
+	}
+
+	if (!(flags & PKCS7_NOATTR)) {
+		if (!PKCS7_add_attrib_content_type(si, NULL))
+			goto err;
+		/* Add SMIMECapabilities */
+		if (!(flags & PKCS7_NOSMIMECAP)) {
+			if (!(smcap = sk_X509_ALGOR_new_null())) {
+				PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
+				    ERR_R_MALLOC_FAILURE);
+				goto err;
+			}
+			if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1) ||
+			    !add_digest_smcap(smcap, NID_id_GostR3411_94, -1) ||
+			    !add_digest_smcap(smcap, NID_id_tc26_gost3411_2012_256, -1) ||
+			    !add_digest_smcap(smcap, NID_id_tc26_gost3411_2012_512, -1) ||
+			    !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) ||
+			    !add_cipher_smcap(smcap, NID_aes_192_cbc, -1) ||
+			    !add_cipher_smcap(smcap, NID_aes_128_cbc, -1) ||
+			    !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) ||
+			    !add_cipher_smcap(smcap, NID_rc2_cbc, 128) ||
+			    !add_cipher_smcap(smcap, NID_rc2_cbc, 64) ||
+			    !add_cipher_smcap(smcap, NID_des_cbc, -1) ||
+			    !add_cipher_smcap(smcap, NID_rc2_cbc, 40) ||
+			    !PKCS7_add_attrib_smimecap(si, smcap))
+				goto err;
+			sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
+			smcap = NULL;
+		}
+		if (flags & PKCS7_REUSE_DIGEST) {
+			if (!pkcs7_copy_existing_digest(p7, si))
+				goto err;
+			if (!(flags & PKCS7_PARTIAL) &&
+			    !PKCS7_SIGNER_INFO_sign(si))
+				goto err;
+		}
+	}
+	return si;
+
+err:
+	if (smcap)
+		sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
+	return NULL;
+}
+
+/* Search for a digest matching SignerInfo digest type and if found
+ * copy across.
+ */
+
+static int
+pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
+{
+	int i;
+	STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
+	PKCS7_SIGNER_INFO *sitmp;
+	ASN1_OCTET_STRING *osdig = NULL;
+
+	sinfos = PKCS7_get_signer_info(p7);
+	for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
+		sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
+		if (si == sitmp)
+			break;
+		if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0)
+			continue;
+		if (!OBJ_cmp(si->digest_alg->algorithm,
+		    sitmp->digest_alg->algorithm)) {
+			osdig = PKCS7_digest_from_attributes(sitmp->auth_attr);
+			break;
+		}
+
+	}
+
+	if (osdig)
+		return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length);
+
+	PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST,
+	    PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND);
+	return 0;
+}
+
+int
+PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata,
+    BIO *out, int flags)
+{
+	STACK_OF(X509) *signers;
+	X509 *signer;
+	STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
+	PKCS7_SIGNER_INFO *si;
+	X509_STORE_CTX cert_ctx;
+	char buf[4096];
+	int i, j = 0, k, ret = 0;
+	BIO *p7bio;
+	BIO *tmpin, *tmpout;
+
+	if (!p7) {
+		PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_INVALID_NULL_POINTER);
+		return 0;
+	}
+
+	if (!PKCS7_type_is_signed(p7)) {
+		PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_WRONG_CONTENT_TYPE);
+		return 0;
+	}
+
+	/* Check for no data and no content: no data to verify signature */
+	if (PKCS7_get_detached(p7) && !indata) {
+		PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_CONTENT);
+		return 0;
+	}
+
+	/*
+	 * Very old Netscape illegally included empty content with
+	 * a detached signature.  Very old users should upgrade.
+	 */
+	/* Check for data and content: two sets of data */
+	if (!PKCS7_get_detached(p7) && indata) {
+		PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_CONTENT_AND_DATA_PRESENT);
+		return 0;
+	}
+
+	sinfos = PKCS7_get_signer_info(p7);
+
+	if (!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) {
+		PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_SIGNATURES_ON_DATA);
+		return 0;
+	}
+
+
+	signers = PKCS7_get0_signers(p7, certs, flags);
+
+	if (!signers)
+		return 0;
+
+	/* Now verify the certificates */
+
+	if (!(flags & PKCS7_NOVERIFY))
+		for (k = 0; k < sk_X509_num(signers); k++) {
+			signer = sk_X509_value (signers, k);
+			if  (!(flags & PKCS7_NOCHAIN)) {
+				if (!X509_STORE_CTX_init(&cert_ctx, store,
+				    signer, p7->d.sign->cert)) {
+					PKCS7err(PKCS7_F_PKCS7_VERIFY,
+					    ERR_R_X509_LIB);
+					sk_X509_free(signers);
+					return 0;
+				}
+				X509_STORE_CTX_set_default(&cert_ctx,
+				    "smime_sign");
+			} else if (!X509_STORE_CTX_init(&cert_ctx, store,
+			    signer, NULL)) {
+				PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB);
+				sk_X509_free(signers);
+				return 0;
+			}
+			if (!(flags & PKCS7_NOCRL))
+				X509_STORE_CTX_set0_crls(&cert_ctx, p7->d.sign->crl);
+			i = X509_verify_cert(&cert_ctx);
+			if (i <= 0)
+				j = X509_STORE_CTX_get_error(&cert_ctx);
+			X509_STORE_CTX_cleanup(&cert_ctx);
+			if (i <= 0) {
+				PKCS7err(PKCS7_F_PKCS7_VERIFY,
+				    PKCS7_R_CERTIFICATE_VERIFY_ERROR);
+				ERR_asprintf_error_data("Verify error:%s",
+				    X509_verify_cert_error_string(j));
+				sk_X509_free(signers);
+				return 0;
+			}
+			/* Check for revocation status here */
+		}
+
+	/*
+	 * Performance optimization: if the content is a memory BIO then
+	 * store its contents in a temporary read only memory BIO. This
+	 * avoids potentially large numbers of slow copies of data which will
+	 * occur when reading from a read write memory BIO when signatures
+	 * are calculated.
+	 */
+	if (indata && (BIO_method_type(indata) == BIO_TYPE_MEM)) {
+		char *ptr;
+		long len;
+
+		len = BIO_get_mem_data(indata, &ptr);
+		tmpin = BIO_new_mem_buf(ptr, len);
+		if (tmpin == NULL) {
+			PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+	} else
+		tmpin = indata;
+
+
+	if (!(p7bio = PKCS7_dataInit(p7, tmpin)))
+		goto err;
+
+	if (flags & PKCS7_TEXT) {
+		if (!(tmpout = BIO_new(BIO_s_mem()))) {
+			PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		BIO_set_mem_eof_return(tmpout, 0);
+	} else
+		tmpout = out;
+
+	/* We now have to 'read' from p7bio to calculate digests etc. */
+	for (;;) {
+		i = BIO_read(p7bio, buf, sizeof(buf));
+		if (i <= 0)
+			break;
+		if (tmpout)
+			BIO_write(tmpout, buf, i);
+	}
+
+	if (flags & PKCS7_TEXT) {
+		if (!SMIME_text(tmpout, out)) {
+			PKCS7err(PKCS7_F_PKCS7_VERIFY,
+			    PKCS7_R_SMIME_TEXT_ERROR);
+			BIO_free(tmpout);
+			goto err;
+		}
+		BIO_free(tmpout);
+	}
+
+	/* Now Verify All Signatures */
+	if (!(flags & PKCS7_NOSIGS))
+		for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
+			si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
+			signer = sk_X509_value (signers, i);
+			j = PKCS7_signatureVerify(p7bio, p7, si, signer);
+			if (j <= 0) {
+				PKCS7err(PKCS7_F_PKCS7_VERIFY,
+				    PKCS7_R_SIGNATURE_FAILURE);
+				goto err;
+			}
+		}
+
+	ret = 1;
+
+err:
+	if (tmpin == indata) {
+		if (indata)
+			BIO_pop(p7bio);
+	}
+	BIO_free_all(p7bio);
+	sk_X509_free(signers);
+
+	return ret;
+}
+
+STACK_OF(X509) *
+PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags)
+{
+	STACK_OF(X509) *signers;
+	STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
+	PKCS7_SIGNER_INFO *si;
+	PKCS7_ISSUER_AND_SERIAL *ias;
+	X509 *signer;
+	int i;
+
+	if (!p7) {
+		PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,
+		    PKCS7_R_INVALID_NULL_POINTER);
+		return NULL;
+	}
+
+	if (!PKCS7_type_is_signed(p7)) {
+		PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,
+		    PKCS7_R_WRONG_CONTENT_TYPE);
+		return NULL;
+	}
+
+	/* Collect all the signers together */
+	sinfos = PKCS7_get_signer_info(p7);
+	if (sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) {
+		PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_NO_SIGNERS);
+		return 0;
+	}
+
+	if (!(signers = sk_X509_new_null())) {
+		PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+
+	for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
+		si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
+		ias = si->issuer_and_serial;
+		signer = NULL;
+		/* If any certificates passed they take priority */
+		if (certs)
+			signer = X509_find_by_issuer_and_serial (certs,
+			    ias->issuer, ias->serial);
+		if (!signer && !(flags & PKCS7_NOINTERN) && p7->d.sign->cert)
+			signer =
+			    X509_find_by_issuer_and_serial(p7->d.sign->cert,
+			      ias->issuer, ias->serial);
+		if (!signer) {
+			PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,
+			    PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND);
+			sk_X509_free(signers);
+			return 0;
+		}
+
+		if (!sk_X509_push(signers, signer)) {
+			sk_X509_free(signers);
+			return NULL;
+		}
+	}
+	return signers;
+}
+
+/* Build a complete PKCS#7 enveloped data */
+
+PKCS7 *
+PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
+    int flags)
+{
+	PKCS7 *p7;
+	BIO *p7bio = NULL;
+	int i;
+	X509 *x509;
+
+	if (!(p7 = PKCS7_new())) {
+		PKCS7err(PKCS7_F_PKCS7_ENCRYPT, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+
+	if (!PKCS7_set_type(p7, NID_pkcs7_enveloped))
+		goto err;
+	if (!PKCS7_set_cipher(p7, cipher)) {
+		PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_SETTING_CIPHER);
+		goto err;
+	}
+
+	for (i = 0; i < sk_X509_num(certs); i++) {
+		x509 = sk_X509_value(certs, i);
+		if (!PKCS7_add_recipient(p7, x509)) {
+			PKCS7err(PKCS7_F_PKCS7_ENCRYPT,
+			    PKCS7_R_ERROR_ADDING_RECIPIENT);
+			goto err;
+		}
+	}
+
+	if (flags & PKCS7_STREAM)
+		return p7;
+
+	if (PKCS7_final(p7, in, flags))
+		return p7;
+
+err:
+	BIO_free_all(p7bio);
+	PKCS7_free(p7);
+	return NULL;
+}
+
+int
+PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags)
+{
+	BIO *tmpmem;
+	int ret, i;
+	char buf[4096];
+
+	if (!p7) {
+		PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_INVALID_NULL_POINTER);
+		return 0;
+	}
+
+	if (!PKCS7_type_is_enveloped(p7)) {
+		PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_WRONG_CONTENT_TYPE);
+		return 0;
+	}
+
+	if (cert && !X509_check_private_key(cert, pkey)) {
+		PKCS7err(PKCS7_F_PKCS7_DECRYPT,
+		    PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+		return 0;
+	}
+
+	if (!(tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert))) {
+		PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_DECRYPT_ERROR);
+		return 0;
+	}
+
+	if (flags & PKCS7_TEXT) {
+		BIO *tmpbuf;
+
+		/* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */
+		if (!(tmpbuf = BIO_new(BIO_f_buffer()))) {
+			PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
+			BIO_free_all(tmpmem);
+			return 0;
+		}
+		BIO_push(tmpbuf, tmpmem);
+		ret = SMIME_text(tmpbuf, data);
+		if (ret > 0 && BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) {
+			if (!BIO_get_cipher_status(tmpmem))
+				ret = 0;
+		}
+		BIO_free_all(tmpbuf);
+		return ret;
+	} else {
+		for (;;) {
+			i = BIO_read(tmpmem, buf, sizeof(buf));
+			if (i <= 0) {
+				ret = 1;
+				if (BIO_method_type(tmpmem) ==
+				    BIO_TYPE_CIPHER) {
+					if (!BIO_get_cipher_status(tmpmem))
+						ret = 0;
+				}
+				break;
+			}
+			if (BIO_write(data, buf, i) != i) {
+				ret = 0;
+				break;
+			}
+		}
+		BIO_free_all(tmpmem);
+		return ret;
+	}
+}
diff --git a/crypto/libressl/crypto/pkcs7/pkcs7err.c b/crypto/libressl/crypto/pkcs7/pkcs7err.c
new file mode 100644
index 0000000000..b4caeef2c0
--- /dev/null
+++ b/crypto/libressl/crypto/pkcs7/pkcs7err.c
@@ -0,0 +1,187 @@
+/* $OpenBSD: pkcs7err.c,v 1.10 2014/06/29 17:05:36 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS7,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS7,0,reason)
+
+static ERR_STRING_DATA PKCS7_str_functs[]= {
+	{ERR_FUNC(PKCS7_F_B64_READ_PKCS7),	"B64_READ_PKCS7"},
+	{ERR_FUNC(PKCS7_F_B64_WRITE_PKCS7),	"B64_WRITE_PKCS7"},
+	{ERR_FUNC(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB),	"DO_PKCS7_SIGNED_ATTRIB"},
+	{ERR_FUNC(PKCS7_F_I2D_PKCS7_BIO_STREAM),	"i2d_PKCS7_bio_stream"},
+	{ERR_FUNC(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME),	"PKCS7_add0_attrib_signing_time"},
+	{ERR_FUNC(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP),	"PKCS7_add_attrib_smimecap"},
+	{ERR_FUNC(PKCS7_F_PKCS7_ADD_CERTIFICATE),	"PKCS7_add_certificate"},
+	{ERR_FUNC(PKCS7_F_PKCS7_ADD_CRL),	"PKCS7_add_crl"},
+	{ERR_FUNC(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO),	"PKCS7_add_recipient_info"},
+	{ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNATURE),	"PKCS7_add_signature"},
+	{ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNER),	"PKCS7_add_signer"},
+	{ERR_FUNC(PKCS7_F_PKCS7_BIO_ADD_DIGEST),	"PKCS7_BIO_ADD_DIGEST"},
+	{ERR_FUNC(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST),	"PKCS7_COPY_EXISTING_DIGEST"},
+	{ERR_FUNC(PKCS7_F_PKCS7_CTRL),	"PKCS7_ctrl"},
+	{ERR_FUNC(PKCS7_F_PKCS7_DATADECODE),	"PKCS7_dataDecode"},
+	{ERR_FUNC(PKCS7_F_PKCS7_DATAFINAL),	"PKCS7_dataFinal"},
+	{ERR_FUNC(PKCS7_F_PKCS7_DATAINIT),	"PKCS7_dataInit"},
+	{ERR_FUNC(PKCS7_F_PKCS7_DATASIGN),	"PKCS7_DATASIGN"},
+	{ERR_FUNC(PKCS7_F_PKCS7_DATAVERIFY),	"PKCS7_dataVerify"},
+	{ERR_FUNC(PKCS7_F_PKCS7_DECRYPT),	"PKCS7_decrypt"},
+	{ERR_FUNC(PKCS7_F_PKCS7_DECRYPT_RINFO),	"PKCS7_DECRYPT_RINFO"},
+	{ERR_FUNC(PKCS7_F_PKCS7_ENCODE_RINFO),	"PKCS7_ENCODE_RINFO"},
+	{ERR_FUNC(PKCS7_F_PKCS7_ENCRYPT),	"PKCS7_encrypt"},
+	{ERR_FUNC(PKCS7_F_PKCS7_FINAL),	"PKCS7_final"},
+	{ERR_FUNC(PKCS7_F_PKCS7_FIND_DIGEST),	"PKCS7_FIND_DIGEST"},
+	{ERR_FUNC(PKCS7_F_PKCS7_GET0_SIGNERS),	"PKCS7_get0_signers"},
+	{ERR_FUNC(PKCS7_F_PKCS7_RECIP_INFO_SET),	"PKCS7_RECIP_INFO_set"},
+	{ERR_FUNC(PKCS7_F_PKCS7_SET_CIPHER),	"PKCS7_set_cipher"},
+	{ERR_FUNC(PKCS7_F_PKCS7_SET_CONTENT),	"PKCS7_set_content"},
+	{ERR_FUNC(PKCS7_F_PKCS7_SET_DIGEST),	"PKCS7_set_digest"},
+	{ERR_FUNC(PKCS7_F_PKCS7_SET_TYPE),	"PKCS7_set_type"},
+	{ERR_FUNC(PKCS7_F_PKCS7_SIGN),	"PKCS7_sign"},
+	{ERR_FUNC(PKCS7_F_PKCS7_SIGNATUREVERIFY),	"PKCS7_signatureVerify"},
+	{ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SET),	"PKCS7_SIGNER_INFO_set"},
+	{ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SIGN),	"PKCS7_SIGNER_INFO_sign"},
+	{ERR_FUNC(PKCS7_F_PKCS7_SIGN_ADD_SIGNER),	"PKCS7_sign_add_signer"},
+	{ERR_FUNC(PKCS7_F_PKCS7_SIMPLE_SMIMECAP),	"PKCS7_simple_smimecap"},
+	{ERR_FUNC(PKCS7_F_PKCS7_VERIFY),	"PKCS7_verify"},
+	{ERR_FUNC(PKCS7_F_SMIME_READ_PKCS7),	"SMIME_read_PKCS7"},
+	{ERR_FUNC(PKCS7_F_SMIME_TEXT),	"SMIME_text"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA PKCS7_str_reasons[]= {
+	{ERR_REASON(PKCS7_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"},
+	{ERR_REASON(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER), "cipher has no object identifier"},
+	{ERR_REASON(PKCS7_R_CIPHER_NOT_INITIALIZED), "cipher not initialized"},
+	{ERR_REASON(PKCS7_R_CONTENT_AND_DATA_PRESENT), "content and data present"},
+	{ERR_REASON(PKCS7_R_CTRL_ERROR)          , "ctrl error"},
+	{ERR_REASON(PKCS7_R_DECODE_ERROR)        , "decode error"},
+	{ERR_REASON(PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH), "decrypted key is wrong length"},
+	{ERR_REASON(PKCS7_R_DECRYPT_ERROR)       , "decrypt error"},
+	{ERR_REASON(PKCS7_R_DIGEST_FAILURE)      , "digest failure"},
+	{ERR_REASON(PKCS7_R_ENCRYPTION_CTRL_FAILURE), "encryption ctrl failure"},
+	{ERR_REASON(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE), "encryption not supported for this key type"},
+	{ERR_REASON(PKCS7_R_ERROR_ADDING_RECIPIENT), "error adding recipient"},
+	{ERR_REASON(PKCS7_R_ERROR_SETTING_CIPHER), "error setting cipher"},
+	{ERR_REASON(PKCS7_R_INVALID_MIME_TYPE)   , "invalid mime type"},
+	{ERR_REASON(PKCS7_R_INVALID_NULL_POINTER), "invalid null pointer"},
+	{ERR_REASON(PKCS7_R_MIME_NO_CONTENT_TYPE), "mime no content type"},
+	{ERR_REASON(PKCS7_R_MIME_PARSE_ERROR)    , "mime parse error"},
+	{ERR_REASON(PKCS7_R_MIME_SIG_PARSE_ERROR), "mime sig parse error"},
+	{ERR_REASON(PKCS7_R_MISSING_CERIPEND_INFO), "missing ceripend info"},
+	{ERR_REASON(PKCS7_R_NO_CONTENT)          , "no content"},
+	{ERR_REASON(PKCS7_R_NO_CONTENT_TYPE)     , "no content type"},
+	{ERR_REASON(PKCS7_R_NO_DEFAULT_DIGEST)   , "no default digest"},
+	{ERR_REASON(PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND), "no matching digest type found"},
+	{ERR_REASON(PKCS7_R_NO_MULTIPART_BODY_FAILURE), "no multipart body failure"},
+	{ERR_REASON(PKCS7_R_NO_MULTIPART_BOUNDARY), "no multipart boundary"},
+	{ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE), "no recipient matches certificate"},
+	{ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_KEY), "no recipient matches key"},
+	{ERR_REASON(PKCS7_R_NO_SIGNATURES_ON_DATA), "no signatures on data"},
+	{ERR_REASON(PKCS7_R_NO_SIGNERS)          , "no signers"},
+	{ERR_REASON(PKCS7_R_NO_SIG_CONTENT_TYPE) , "no sig content type"},
+	{ERR_REASON(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE), "operation not supported on this type"},
+	{ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR), "pkcs7 add signature error"},
+	{ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNER_ERROR), "pkcs7 add signer error"},
+	{ERR_REASON(PKCS7_R_PKCS7_DATAFINAL)     , "pkcs7 datafinal"},
+	{ERR_REASON(PKCS7_R_PKCS7_DATAFINAL_ERROR), "pkcs7 datafinal error"},
+	{ERR_REASON(PKCS7_R_PKCS7_DATASIGN)      , "pkcs7 datasign"},
+	{ERR_REASON(PKCS7_R_PKCS7_PARSE_ERROR)   , "pkcs7 parse error"},
+	{ERR_REASON(PKCS7_R_PKCS7_SIG_PARSE_ERROR), "pkcs7 sig parse error"},
+	{ERR_REASON(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), "private key does not match certificate"},
+	{ERR_REASON(PKCS7_R_SIGNATURE_FAILURE)   , "signature failure"},
+	{ERR_REASON(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND), "signer certificate not found"},
+	{ERR_REASON(PKCS7_R_SIGNING_CTRL_FAILURE), "signing ctrl failure"},
+	{ERR_REASON(PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE), "signing not supported for this key type"},
+	{ERR_REASON(PKCS7_R_SIG_INVALID_MIME_TYPE), "sig invalid mime type"},
+	{ERR_REASON(PKCS7_R_SMIME_TEXT_ERROR)    , "smime text error"},
+	{ERR_REASON(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE), "unable to find certificate"},
+	{ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MEM_BIO), "unable to find mem bio"},
+	{ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST), "unable to find message digest"},
+	{ERR_REASON(PKCS7_R_UNKNOWN_DIGEST_TYPE) , "unknown digest type"},
+	{ERR_REASON(PKCS7_R_UNKNOWN_OPERATION)   , "unknown operation"},
+	{ERR_REASON(PKCS7_R_UNSUPPORTED_CIPHER_TYPE), "unsupported cipher type"},
+	{ERR_REASON(PKCS7_R_UNSUPPORTED_CONTENT_TYPE), "unsupported content type"},
+	{ERR_REASON(PKCS7_R_WRONG_CONTENT_TYPE)  , "wrong content type"},
+	{ERR_REASON(PKCS7_R_WRONG_PKCS7_TYPE)    , "wrong pkcs7 type"},
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_PKCS7_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(PKCS7_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, PKCS7_str_functs);
+		ERR_load_strings(0, PKCS7_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/poly1305/poly1305-donna.c b/crypto/libressl/crypto/poly1305/poly1305-donna.c
new file mode 100644
index 0000000000..7bc3c56dd4
--- /dev/null
+++ b/crypto/libressl/crypto/poly1305/poly1305-donna.c
@@ -0,0 +1,321 @@
+/* $OpenBSD$ */
+/*
+ * Public Domain poly1305 from Andrew Moon
+ * Based on poly1305-donna.c, poly1305-donna-32.h and poly1305-donna.h from:
+ *   https://github.com/floodyberry/poly1305-donna
+ */
+
+#include 
+
+static inline void poly1305_init(poly1305_context *ctx,
+    const unsigned char key[32]);
+static inline void poly1305_update(poly1305_context *ctx,
+    const unsigned char *m, size_t bytes);
+static inline void poly1305_finish(poly1305_context *ctx,
+    unsigned char mac[16]);
+
+/*
+ * poly1305 implementation using 32 bit * 32 bit = 64 bit multiplication
+ * and 64 bit addition.
+ */
+
+#define poly1305_block_size 16
+
+/* 17 + sizeof(size_t) + 14*sizeof(unsigned long) */
+typedef struct poly1305_state_internal_t {
+	unsigned long r[5];
+	unsigned long h[5];
+	unsigned long pad[4];
+	size_t leftover;
+	unsigned char buffer[poly1305_block_size];
+	unsigned char final;
+} poly1305_state_internal_t;
+
+/* interpret four 8 bit unsigned integers as a 32 bit unsigned integer in little endian */
+static unsigned long
+U8TO32(const unsigned char *p)
+{
+	return (((unsigned long)(p[0] & 0xff)) |
+	    ((unsigned long)(p[1] & 0xff) <<  8) |
+	    ((unsigned long)(p[2] & 0xff) << 16) |
+	    ((unsigned long)(p[3] & 0xff) << 24));
+}
+
+/* store a 32 bit unsigned integer as four 8 bit unsigned integers in little endian */
+static void
+U32TO8(unsigned char *p, unsigned long v)
+{
+	p[0] = (v) & 0xff;
+	p[1] = (v >>  8) & 0xff;
+	p[2] = (v >> 16) & 0xff;
+	p[3] = (v >> 24) & 0xff;
+}
+
+static inline void
+poly1305_init(poly1305_context *ctx, const unsigned char key[32])
+{
+	poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
+
+	/* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
+	st->r[0] = (U8TO32(&key[0])) & 0x3ffffff;
+	st->r[1] = (U8TO32(&key[3]) >> 2) & 0x3ffff03;
+	st->r[2] = (U8TO32(&key[6]) >> 4) & 0x3ffc0ff;
+	st->r[3] = (U8TO32(&key[9]) >> 6) & 0x3f03fff;
+	st->r[4] = (U8TO32(&key[12]) >> 8) & 0x00fffff;
+
+	/* h = 0 */
+	st->h[0] = 0;
+	st->h[1] = 0;
+	st->h[2] = 0;
+	st->h[3] = 0;
+	st->h[4] = 0;
+
+	/* save pad for later */
+	st->pad[0] = U8TO32(&key[16]);
+	st->pad[1] = U8TO32(&key[20]);
+	st->pad[2] = U8TO32(&key[24]);
+	st->pad[3] = U8TO32(&key[28]);
+
+	st->leftover = 0;
+	st->final = 0;
+}
+
+static void
+poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t bytes)
+{
+	const unsigned long hibit = (st->final) ? 0 : (1 << 24); /* 1 << 128 */
+	unsigned long r0, r1, r2, r3, r4;
+	unsigned long s1, s2, s3, s4;
+	unsigned long h0, h1, h2, h3, h4;
+	unsigned long long d0, d1, d2, d3, d4;
+	unsigned long c;
+
+	r0 = st->r[0];
+	r1 = st->r[1];
+	r2 = st->r[2];
+	r3 = st->r[3];
+	r4 = st->r[4];
+
+	s1 = r1 * 5;
+	s2 = r2 * 5;
+	s3 = r3 * 5;
+	s4 = r4 * 5;
+
+	h0 = st->h[0];
+	h1 = st->h[1];
+	h2 = st->h[2];
+	h3 = st->h[3];
+	h4 = st->h[4];
+
+	while (bytes >= poly1305_block_size) {
+		/* h += m[i] */
+		h0 += (U8TO32(m + 0)) & 0x3ffffff;
+		h1 += (U8TO32(m + 3) >> 2) & 0x3ffffff;
+		h2 += (U8TO32(m + 6) >> 4) & 0x3ffffff;
+		h3 += (U8TO32(m + 9) >> 6) & 0x3ffffff;
+		h4 += (U8TO32(m + 12) >> 8) | hibit;
+
+		/* h *= r */
+		d0 = ((unsigned long long)h0 * r0) +
+		    ((unsigned long long)h1 * s4) +
+		    ((unsigned long long)h2 * s3) +
+		    ((unsigned long long)h3 * s2) +
+		    ((unsigned long long)h4 * s1);
+		d1 = ((unsigned long long)h0 * r1) +
+		    ((unsigned long long)h1 * r0) +
+		    ((unsigned long long)h2 * s4) +
+		    ((unsigned long long)h3 * s3) +
+		    ((unsigned long long)h4 * s2);
+		d2 = ((unsigned long long)h0 * r2) +
+		    ((unsigned long long)h1 * r1) +
+		    ((unsigned long long)h2 * r0) +
+		    ((unsigned long long)h3 * s4) +
+		    ((unsigned long long)h4 * s3);
+		d3 = ((unsigned long long)h0 * r3) +
+		    ((unsigned long long)h1 * r2) +
+		    ((unsigned long long)h2 * r1) +
+		    ((unsigned long long)h3 * r0) +
+		    ((unsigned long long)h4 * s4);
+		d4 = ((unsigned long long)h0 * r4) +
+		    ((unsigned long long)h1 * r3) +
+		    ((unsigned long long)h2 * r2) +
+		    ((unsigned long long)h3 * r1) +
+		    ((unsigned long long)h4 * r0);
+
+		/* (partial) h %= p */
+		c = (unsigned long)(d0 >> 26);
+		h0 = (unsigned long)d0 & 0x3ffffff;
+		d1 += c;
+		c = (unsigned long)(d1 >> 26);
+		h1 = (unsigned long)d1 & 0x3ffffff;
+		d2 += c;
+		c = (unsigned long)(d2 >> 26);
+		h2 = (unsigned long)d2 & 0x3ffffff;
+		d3 += c;
+		c = (unsigned long)(d3 >> 26);
+		h3 = (unsigned long)d3 & 0x3ffffff;
+		d4 += c;
+		c = (unsigned long)(d4 >> 26);
+		h4 = (unsigned long)d4 & 0x3ffffff;
+		h0 += c * 5;
+		c = (h0 >> 26);
+		h0 = h0 & 0x3ffffff;
+		h1 += c;
+
+		m += poly1305_block_size;
+		bytes -= poly1305_block_size;
+	}
+
+	st->h[0] = h0;
+	st->h[1] = h1;
+	st->h[2] = h2;
+	st->h[3] = h3;
+	st->h[4] = h4;
+}
+
+static inline void
+poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes)
+{
+	poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
+	size_t i;
+
+	/* handle leftover */
+	if (st->leftover) {
+		size_t want = (poly1305_block_size - st->leftover);
+		if (want > bytes)
+			want = bytes;
+		for (i = 0; i < want; i++)
+			st->buffer[st->leftover + i] = m[i];
+		bytes -= want;
+		m += want;
+		st->leftover += want;
+		if (st->leftover < poly1305_block_size)
+			return;
+		poly1305_blocks(st, st->buffer, poly1305_block_size);
+		st->leftover = 0;
+	}
+
+	/* process full blocks */
+	if (bytes >= poly1305_block_size) {
+		size_t want = (bytes & ~(poly1305_block_size - 1));
+		poly1305_blocks(st, m, want);
+		m += want;
+		bytes -= want;
+	}
+
+	/* store leftover */
+	if (bytes) {
+		for (i = 0; i < bytes; i++)
+			st->buffer[st->leftover + i] = m[i];
+		st->leftover += bytes;
+	}
+}
+
+static inline void
+poly1305_finish(poly1305_context *ctx, unsigned char mac[16])
+{
+	poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
+	unsigned long h0, h1, h2, h3, h4, c;
+	unsigned long g0, g1, g2, g3, g4;
+	unsigned long long f;
+	unsigned long mask;
+
+	/* process the remaining block */
+	if (st->leftover) {
+		size_t i = st->leftover;
+		st->buffer[i++] = 1;
+		for (; i < poly1305_block_size; i++)
+			st->buffer[i] = 0;
+		st->final = 1;
+		poly1305_blocks(st, st->buffer, poly1305_block_size);
+	}
+
+	/* fully carry h */
+	h0 = st->h[0];
+	h1 = st->h[1];
+	h2 = st->h[2];
+	h3 = st->h[3];
+	h4 = st->h[4];
+
+	c = h1 >> 26;
+	h1 = h1 & 0x3ffffff;
+	h2 += c;
+	c = h2 >> 26;
+	h2 = h2 & 0x3ffffff;
+	h3 += c;
+	c = h3 >> 26;
+	h3 = h3 & 0x3ffffff;
+	h4 += c;
+	c = h4 >> 26;
+	h4 = h4 & 0x3ffffff;
+	h0 += c * 5;
+	c = h0 >> 26;
+	h0 = h0 & 0x3ffffff;
+	h1 += c;
+
+	/* compute h + -p */
+	g0 = h0 + 5;
+	c = g0 >> 26;
+	g0 &= 0x3ffffff;
+	g1 = h1 + c;
+	c = g1 >> 26;
+	g1 &= 0x3ffffff;
+	g2 = h2 + c;
+	c = g2 >> 26;
+	g2 &= 0x3ffffff;
+	g3 = h3 + c;
+	c = g3 >> 26;
+	g3 &= 0x3ffffff;
+	g4 = h4 + c - (1 << 26);
+
+	/* select h if h < p, or h + -p if h >= p */
+	mask = (g4 >> ((sizeof(unsigned long) * 8) - 1)) - 1;
+	g0 &= mask;
+	g1 &= mask;
+	g2 &= mask;
+	g3 &= mask;
+	g4 &= mask;
+	mask = ~mask;
+	h0 = (h0 & mask) | g0;
+	h1 = (h1 & mask) | g1;
+	h2 = (h2 & mask) | g2;
+	h3 = (h3 & mask) | g3;
+	h4 = (h4 & mask) | g4;
+
+	/* h = h % (2^128) */
+	h0 = ((h0) | (h1 << 26)) & 0xffffffff;
+	h1 = ((h1 >>  6) | (h2 << 20)) & 0xffffffff;
+	h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff;
+	h3 = ((h3 >> 18) | (h4 <<  8)) & 0xffffffff;
+
+	/* mac = (h + pad) % (2^128) */
+	f = (unsigned long long)h0 + st->pad[0];
+	h0 = (unsigned long)f;
+	f = (unsigned long long)h1 + st->pad[1] + (f >> 32);
+	h1 = (unsigned long)f;
+	f = (unsigned long long)h2 + st->pad[2] + (f >> 32);
+	h2 = (unsigned long)f;
+	f = (unsigned long long)h3 + st->pad[3] + (f >> 32);
+	h3 = (unsigned long)f;
+
+	U32TO8(mac +  0, h0);
+	U32TO8(mac +  4, h1);
+	U32TO8(mac +  8, h2);
+	U32TO8(mac + 12, h3);
+
+	/* zero out the state */
+	st->h[0] = 0;
+	st->h[1] = 0;
+	st->h[2] = 0;
+	st->h[3] = 0;
+	st->h[4] = 0;
+	st->r[0] = 0;
+	st->r[1] = 0;
+	st->r[2] = 0;
+	st->r[3] = 0;
+	st->r[4] = 0;
+	st->pad[0] = 0;
+	st->pad[1] = 0;
+	st->pad[2] = 0;
+	st->pad[3] = 0;
+}
diff --git a/crypto/libressl/crypto/poly1305/poly1305.c b/crypto/libressl/crypto/poly1305/poly1305.c
new file mode 100644
index 0000000000..d4734657ec
--- /dev/null
+++ b/crypto/libressl/crypto/poly1305/poly1305.c
@@ -0,0 +1,38 @@
+/* $OpenBSD$ */
+/*
+ * Copyright (c) 2014 Joel Sing 
+ *
+ * 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 
+#include "poly1305-donna.c"
+
+void
+CRYPTO_poly1305_init(poly1305_context *ctx, const unsigned char key[32])
+{
+	poly1305_init(ctx, key);
+}
+
+void
+CRYPTO_poly1305_update(poly1305_context *ctx, const unsigned char *in,
+    size_t len)
+{
+	poly1305_update(ctx, in, len);
+}
+
+void
+CRYPTO_poly1305_finish(poly1305_context *ctx, unsigned char mac[16])
+{
+	poly1305_finish(ctx, mac);
+}
diff --git a/crypto/libressl/crypto/rand/rand_err.c b/crypto/libressl/crypto/rand/rand_err.c
new file mode 100644
index 0000000000..77546ebf8f
--- /dev/null
+++ b/crypto/libressl/crypto/rand/rand_err.c
@@ -0,0 +1,101 @@
+/* $OpenBSD: rand_err.c,v 1.13 2014/06/12 15:49:30 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2011 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_RAND,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_RAND,0,reason)
+
+static ERR_STRING_DATA RAND_str_functs[] = {
+	{ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD),	"RAND_get_rand_method"},
+	{ERR_FUNC(RAND_F_RAND_INIT_FIPS),	"RAND_init_fips"},
+	{ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES),	"SSLEAY_RAND_BYTES"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA RAND_str_reasons[] = {
+	{ERR_REASON(RAND_R_DUAL_EC_DRBG_DISABLED), "dual ec drbg disabled"},
+	{ERR_REASON(RAND_R_ERROR_INITIALISING_DRBG), "error initialising drbg"},
+	{ERR_REASON(RAND_R_ERROR_INSTANTIATING_DRBG), "error instantiating drbg"},
+	{ERR_REASON(RAND_R_NO_FIPS_RANDOM_METHOD_SET), "no fips random method set"},
+	{ERR_REASON(RAND_R_PRNG_NOT_SEEDED)      , "PRNG not seeded"},
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_RAND_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(RAND_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, RAND_str_functs);
+		ERR_load_strings(0, RAND_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/rand/rand_lib.c b/crypto/libressl/crypto/rand/rand_lib.c
new file mode 100644
index 0000000000..73da27747d
--- /dev/null
+++ b/crypto/libressl/crypto/rand/rand_lib.c
@@ -0,0 +1,100 @@
+/* $OpenBSD: rand_lib.c,v 1.19 2014/07/11 08:44:49 jsing Exp $ */
+/*
+ * Copyright (c) 2014 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 
+
+#include 
+
+#include 
+
+/*
+ * The useful functions in this file are at the bottom.
+ */
+int
+RAND_set_rand_method(const RAND_METHOD *meth)
+{
+	return 1;
+}
+
+const RAND_METHOD *
+RAND_get_rand_method(void)
+{
+	return NULL;
+}
+
+RAND_METHOD *
+RAND_SSLeay(void)
+{
+	return NULL;
+}
+
+#ifndef OPENSSL_NO_ENGINE
+int
+RAND_set_rand_engine(ENGINE *engine)
+{
+	return 1;
+}
+#endif
+
+void
+RAND_cleanup(void)
+{
+
+}
+
+void
+RAND_seed(const void *buf, int num)
+{
+
+}
+
+void
+RAND_add(const void *buf, int num, double entropy)
+{
+
+}
+
+int
+RAND_status(void)
+{
+	return 1;
+}
+
+int
+RAND_poll(void)
+{
+	return 1;
+}
+
+/*
+ * Hurray. You've made it to the good parts.
+ */
+int
+RAND_bytes(unsigned char *buf, int num)
+{
+	if (num > 0)
+		arc4random_buf(buf, num);
+	return 1;
+}
+
+int
+RAND_pseudo_bytes(unsigned char *buf, int num)
+{
+	if (num > 0)
+		arc4random_buf(buf, num);
+	return 1;
+}
diff --git a/crypto/libressl/crypto/rand/randfile.c b/crypto/libressl/crypto/rand/randfile.c
new file mode 100644
index 0000000000..c575c61565
--- /dev/null
+++ b/crypto/libressl/crypto/rand/randfile.c
@@ -0,0 +1,143 @@
+/* $OpenBSD: randfile.c,v 1.41 2015/07/18 22:46:42 beck Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#undef BUFSIZE
+#define BUFSIZE	1024
+#define RAND_DATA 1024
+
+/* Note that these functions should not be used. */
+
+int
+RAND_load_file(const char *file, long bytes)
+{
+	/* the "whole" file */
+	if (bytes == -1)
+		return 123456;
+	else
+		return bytes;
+}
+
+int
+RAND_write_file(const char *file)
+{
+	unsigned char buf[BUFSIZE];
+	int i, ret = 0;
+	FILE *out = NULL;
+	int n, fd;
+	struct stat sb;
+
+	/*
+	 * If this file is a device, avoid opening it.
+	 * XXX TOCTOU
+	 */
+	if (stat(file, &sb) != -1 &&
+	    (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode))) {
+		return (1);
+	}
+
+	fd = open(file, O_WRONLY|O_CREAT, 0600);
+	if (fd == -1)
+		return (1);
+	out = fdopen(fd, "wb");
+
+	if (out == NULL) {
+		close(fd);
+		return (1);
+	}
+
+	n = RAND_DATA;
+	for (;;) {
+		i = (n > BUFSIZE) ? BUFSIZE : n;
+		n -= BUFSIZE;
+		arc4random_buf(buf, i);
+		i = fwrite(buf, 1, i, out);
+		if (i <= 0) {
+			ret = 0;
+			break;
+		}
+		ret += i;
+		if (n <= 0)
+			break;
+	}
+
+	fclose(out);
+	explicit_bzero(buf, BUFSIZE);
+	return ret;
+}
+
+const char *
+RAND_file_name(char * buf, size_t size)
+{
+	if (strlcpy(buf, "/dev/urandom", size) >= size)
+		return (NULL);
+	return buf;
+}
diff --git a/crypto/libressl/crypto/rc2/rc2_cbc.c b/crypto/libressl/crypto/rc2/rc2_cbc.c
new file mode 100644
index 0000000000..82236925d9
--- /dev/null
+++ b/crypto/libressl/crypto/rc2/rc2_cbc.c
@@ -0,0 +1,226 @@
+/* $OpenBSD: rc2_cbc.c,v 1.4 2014/06/12 15:49:30 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include "rc2_locl.h"
+
+void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+	     RC2_KEY *ks, unsigned char *iv, int encrypt)
+	{
+	unsigned long tin0,tin1;
+	unsigned long tout0,tout1,xor0,xor1;
+	long l=length;
+	unsigned long tin[2];
+
+	if (encrypt)
+		{
+		c2l(iv,tout0);
+		c2l(iv,tout1);
+		iv-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			c2l(in,tin0);
+			c2l(in,tin1);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			RC2_encrypt(tin,ks);
+			tout0=tin[0]; l2c(tout0,out);
+			tout1=tin[1]; l2c(tout1,out);
+			}
+		if (l != -8)
+			{
+			c2ln(in,tin0,tin1,l+8);
+			tin0^=tout0;
+			tin1^=tout1;
+			tin[0]=tin0;
+			tin[1]=tin1;
+			RC2_encrypt(tin,ks);
+			tout0=tin[0]; l2c(tout0,out);
+			tout1=tin[1]; l2c(tout1,out);
+			}
+		l2c(tout0,iv);
+		l2c(tout1,iv);
+		}
+	else
+		{
+		c2l(iv,xor0);
+		c2l(iv,xor1);
+		iv-=8;
+		for (l-=8; l>=0; l-=8)
+			{
+			c2l(in,tin0); tin[0]=tin0;
+			c2l(in,tin1); tin[1]=tin1;
+			RC2_decrypt(tin,ks);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2c(tout0,out);
+			l2c(tout1,out);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		if (l != -8)
+			{
+			c2l(in,tin0); tin[0]=tin0;
+			c2l(in,tin1); tin[1]=tin1;
+			RC2_decrypt(tin,ks);
+			tout0=tin[0]^xor0;
+			tout1=tin[1]^xor1;
+			l2cn(tout0,tout1,out,l+8);
+			xor0=tin0;
+			xor1=tin1;
+			}
+		l2c(xor0,iv);
+		l2c(xor1,iv);
+		}
+	tin0=tin1=tout0=tout1=xor0=xor1=0;
+	tin[0]=tin[1]=0;
+	}
+
+void RC2_encrypt(unsigned long *d, RC2_KEY *key)
+	{
+	int i,n;
+	RC2_INT *p0,*p1;
+	RC2_INT x0,x1,x2,x3,t;
+	unsigned long l;
+
+	l=d[0];
+	x0=(RC2_INT)l&0xffff;
+	x1=(RC2_INT)(l>>16L);
+	l=d[1];
+	x2=(RC2_INT)l&0xffff;
+	x3=(RC2_INT)(l>>16L);
+
+	n=3;
+	i=5;
+
+	p0=p1= &(key->data[0]);
+	for (;;)
+		{
+		t=(x0+(x1& ~x3)+(x2&x3)+ *(p0++))&0xffff;
+		x0=(t<<1)|(t>>15);
+		t=(x1+(x2& ~x0)+(x3&x0)+ *(p0++))&0xffff;
+		x1=(t<<2)|(t>>14);
+		t=(x2+(x3& ~x1)+(x0&x1)+ *(p0++))&0xffff;
+		x2=(t<<3)|(t>>13);
+		t=(x3+(x0& ~x2)+(x1&x2)+ *(p0++))&0xffff;
+		x3=(t<<5)|(t>>11);
+
+		if (--i == 0)
+			{
+			if (--n == 0) break;
+			i=(n == 2)?6:5;
+
+			x0+=p1[x3&0x3f];
+			x1+=p1[x0&0x3f];
+			x2+=p1[x1&0x3f];
+			x3+=p1[x2&0x3f];
+			}
+		}
+
+	d[0]=(unsigned long)(x0&0xffff)|((unsigned long)(x1&0xffff)<<16L);
+	d[1]=(unsigned long)(x2&0xffff)|((unsigned long)(x3&0xffff)<<16L);
+	}
+
+void RC2_decrypt(unsigned long *d, RC2_KEY *key)
+	{
+	int i,n;
+	RC2_INT *p0,*p1;
+	RC2_INT x0,x1,x2,x3,t;
+	unsigned long l;
+
+	l=d[0];
+	x0=(RC2_INT)l&0xffff;
+	x1=(RC2_INT)(l>>16L);
+	l=d[1];
+	x2=(RC2_INT)l&0xffff;
+	x3=(RC2_INT)(l>>16L);
+
+	n=3;
+	i=5;
+
+	p0= &(key->data[63]);
+	p1= &(key->data[0]);
+	for (;;)
+		{
+		t=((x3<<11)|(x3>>5))&0xffff;
+		x3=(t-(x0& ~x2)-(x1&x2)- *(p0--))&0xffff;
+		t=((x2<<13)|(x2>>3))&0xffff;
+		x2=(t-(x3& ~x1)-(x0&x1)- *(p0--))&0xffff;
+		t=((x1<<14)|(x1>>2))&0xffff;
+		x1=(t-(x2& ~x0)-(x3&x0)- *(p0--))&0xffff;
+		t=((x0<<15)|(x0>>1))&0xffff;
+		x0=(t-(x1& ~x3)-(x2&x3)- *(p0--))&0xffff;
+
+		if (--i == 0)
+			{
+			if (--n == 0) break;
+			i=(n == 2)?6:5;
+
+			x3=(x3-p1[x2&0x3f])&0xffff;
+			x2=(x2-p1[x1&0x3f])&0xffff;
+			x1=(x1-p1[x0&0x3f])&0xffff;
+			x0=(x0-p1[x3&0x3f])&0xffff;
+			}
+		}
+
+	d[0]=(unsigned long)(x0&0xffff)|((unsigned long)(x1&0xffff)<<16L);
+	d[1]=(unsigned long)(x2&0xffff)|((unsigned long)(x3&0xffff)<<16L);
+	}
+
diff --git a/crypto/libressl/crypto/rc2/rc2_ecb.c b/crypto/libressl/crypto/rc2/rc2_ecb.c
new file mode 100644
index 0000000000..c9864aa1b1
--- /dev/null
+++ b/crypto/libressl/crypto/rc2/rc2_ecb.c
@@ -0,0 +1,86 @@
+/* $OpenBSD: rc2_ecb.c,v 1.5 2014/06/12 15:49:30 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include "rc2_locl.h"
+#include 
+
+/* RC2 as implemented frm a posting from
+ * Newsgroups: sci.crypt
+ * Sender: pgut01@cs.auckland.ac.nz (Peter Gutmann)
+ * Subject: Specification for Ron Rivests Cipher No.2
+ * Message-ID: <4fk39f$f70@net.auckland.ac.nz>
+ * Date: 11 Feb 1996 06:45:03 GMT
+ */
+
+void RC2_ecb_encrypt(const unsigned char *in, unsigned char *out, RC2_KEY *ks,
+		     int encrypt)
+	{
+	unsigned long l,d[2];
+
+	c2l(in,l); d[0]=l;
+	c2l(in,l); d[1]=l;
+	if (encrypt)
+		RC2_encrypt(d,ks);
+	else
+		RC2_decrypt(d,ks);
+	l=d[0]; l2c(l,out);
+	l=d[1]; l2c(l,out);
+	l=d[0]=d[1]=0;
+	}
+
diff --git a/crypto/libressl/crypto/rc2/rc2_locl.h b/crypto/libressl/crypto/rc2/rc2_locl.h
new file mode 100644
index 0000000000..52a0436909
--- /dev/null
+++ b/crypto/libressl/crypto/rc2/rc2_locl.h
@@ -0,0 +1,156 @@
+/* $OpenBSD$ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#undef c2l
+#define c2l(c,l)	(l =((unsigned long)(*((c)++)))    , \
+			 l|=((unsigned long)(*((c)++)))<< 8L, \
+			 l|=((unsigned long)(*((c)++)))<<16L, \
+			 l|=((unsigned long)(*((c)++)))<<24L)
+
+/* NOTE - c is not incremented as per c2l */
+#undef c2ln
+#define c2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
+			case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
+			case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
+			case 5: l2|=((unsigned long)(*(--(c))));     \
+			case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
+			case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
+			case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
+			case 1: l1|=((unsigned long)(*(--(c))));     \
+				} \
+			}
+
+#undef l2c
+#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)     )&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+#undef l2cn
+#define l2cn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
+				} \
+			}
+
+/* NOTE - c is not incremented as per n2l */
+#define n2ln(c,l1,l2,n)	{ \
+			c+=n; \
+			l1=l2=0; \
+			switch (n) { \
+			case 8: l2 =((unsigned long)(*(--(c))))    ; \
+			case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
+			case 6: l2|=((unsigned long)(*(--(c))))<<16; \
+			case 5: l2|=((unsigned long)(*(--(c))))<<24; \
+			case 4: l1 =((unsigned long)(*(--(c))))    ; \
+			case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
+			case 2: l1|=((unsigned long)(*(--(c))))<<16; \
+			case 1: l1|=((unsigned long)(*(--(c))))<<24; \
+				} \
+			}
+
+/* NOTE - c is not incremented as per l2n */
+#define l2nn(l1,l2,c,n)	{ \
+			c+=n; \
+			switch (n) { \
+			case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
+			case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+			case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+			case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+			case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
+			case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+			case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+			case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+				} \
+			}
+
+#undef n2l
+#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
+                         l|=((unsigned long)(*((c)++)))<<16L, \
+                         l|=((unsigned long)(*((c)++)))<< 8L, \
+                         l|=((unsigned long)(*((c)++))))
+
+#undef l2n
+#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)     )&0xff))
+
+#define C_RC2(n) \
+	t=(x0+(x1& ~x3)+(x2&x3)+ *(p0++))&0xffff; \
+	x0=(t<<1)|(t>>15); \
+	t=(x1+(x2& ~x0)+(x3&x0)+ *(p0++))&0xffff; \
+	x1=(t<<2)|(t>>14); \
+	t=(x2+(x3& ~x1)+(x0&x1)+ *(p0++))&0xffff; \
+	x2=(t<<3)|(t>>13); \
+	t=(x3+(x0& ~x2)+(x1&x2)+ *(p0++))&0xffff; \
+	x3=(t<<5)|(t>>11);
+
diff --git a/crypto/libressl/crypto/rc2/rc2_skey.c b/crypto/libressl/crypto/rc2/rc2_skey.c
new file mode 100644
index 0000000000..7988836f9d
--- /dev/null
+++ b/crypto/libressl/crypto/rc2/rc2_skey.c
@@ -0,0 +1,138 @@
+/* $OpenBSD$ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include "rc2_locl.h"
+
+static const unsigned char key_table[256]={
+	0xd9,0x78,0xf9,0xc4,0x19,0xdd,0xb5,0xed,0x28,0xe9,0xfd,0x79,
+	0x4a,0xa0,0xd8,0x9d,0xc6,0x7e,0x37,0x83,0x2b,0x76,0x53,0x8e,
+	0x62,0x4c,0x64,0x88,0x44,0x8b,0xfb,0xa2,0x17,0x9a,0x59,0xf5,
+	0x87,0xb3,0x4f,0x13,0x61,0x45,0x6d,0x8d,0x09,0x81,0x7d,0x32,
+	0xbd,0x8f,0x40,0xeb,0x86,0xb7,0x7b,0x0b,0xf0,0x95,0x21,0x22,
+	0x5c,0x6b,0x4e,0x82,0x54,0xd6,0x65,0x93,0xce,0x60,0xb2,0x1c,
+	0x73,0x56,0xc0,0x14,0xa7,0x8c,0xf1,0xdc,0x12,0x75,0xca,0x1f,
+	0x3b,0xbe,0xe4,0xd1,0x42,0x3d,0xd4,0x30,0xa3,0x3c,0xb6,0x26,
+	0x6f,0xbf,0x0e,0xda,0x46,0x69,0x07,0x57,0x27,0xf2,0x1d,0x9b,
+	0xbc,0x94,0x43,0x03,0xf8,0x11,0xc7,0xf6,0x90,0xef,0x3e,0xe7,
+	0x06,0xc3,0xd5,0x2f,0xc8,0x66,0x1e,0xd7,0x08,0xe8,0xea,0xde,
+	0x80,0x52,0xee,0xf7,0x84,0xaa,0x72,0xac,0x35,0x4d,0x6a,0x2a,
+	0x96,0x1a,0xd2,0x71,0x5a,0x15,0x49,0x74,0x4b,0x9f,0xd0,0x5e,
+	0x04,0x18,0xa4,0xec,0xc2,0xe0,0x41,0x6e,0x0f,0x51,0xcb,0xcc,
+	0x24,0x91,0xaf,0x50,0xa1,0xf4,0x70,0x39,0x99,0x7c,0x3a,0x85,
+	0x23,0xb8,0xb4,0x7a,0xfc,0x02,0x36,0x5b,0x25,0x55,0x97,0x31,
+	0x2d,0x5d,0xfa,0x98,0xe3,0x8a,0x92,0xae,0x05,0xdf,0x29,0x10,
+	0x67,0x6c,0xba,0xc9,0xd3,0x00,0xe6,0xcf,0xe1,0x9e,0xa8,0x2c,
+	0x63,0x16,0x01,0x3f,0x58,0xe2,0x89,0xa9,0x0d,0x38,0x34,0x1b,
+	0xab,0x33,0xff,0xb0,0xbb,0x48,0x0c,0x5f,0xb9,0xb1,0xcd,0x2e,
+	0xc5,0xf3,0xdb,0x47,0xe5,0xa5,0x9c,0x77,0x0a,0xa6,0x20,0x68,
+	0xfe,0x7f,0xc1,0xad,
+	};
+
+/* It has come to my attention that there are 2 versions of the RC2
+ * key schedule.  One which is normal, and anther which has a hook to
+ * use a reduced key length.
+ * BSAFE uses the 'retarded' version.  What I previously shipped is
+ * the same as specifying 1024 for the 'bits' parameter.  Bsafe uses
+ * a version where the bits parameter is the same as len*8 */
+void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits)
+	{
+	int i,j;
+	unsigned char *k;
+	RC2_INT *ki;
+	unsigned int c,d;
+
+	k= (unsigned char *)&(key->data[0]);
+	*k=0; /* for if there is a zero length key */
+
+	if (len > 128) len=128;
+	if (bits <= 0) bits=1024;
+	if (bits > 1024) bits=1024;
+
+	for (i=0; i>3;
+	i=128-j;
+	c= (0xff>>(-bits & 0x07));
+
+	d=key_table[k[i]&c];
+	k[i]=d;
+	while (i--)
+		{
+		d=key_table[k[i+j]^d];
+		k[i]=d;
+		}
+
+	/* copy from bytes into RC2_INT's */
+	ki= &(key->data[63]);
+	for (i=127; i>=0; i-=2)
+		*(ki--)=((k[i]<<8)|k[i-1])&0xffff;
+	}
diff --git a/crypto/libressl/crypto/rc2/rc2cfb64.c b/crypto/libressl/crypto/rc2/rc2cfb64.c
new file mode 100644
index 0000000000..d79569d6c8
--- /dev/null
+++ b/crypto/libressl/crypto/rc2/rc2cfb64.c
@@ -0,0 +1,122 @@
+/* $OpenBSD: rc2cfb64.c,v 1.4 2014/06/12 15:49:30 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include "rc2_locl.h"
+
+/* The input and output encrypted as though 64bit cfb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+
+void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+		       long length, RC2_KEY *schedule, unsigned char *ivec,
+		       int *num, int encrypt)
+	{
+	unsigned long v0,v1,t;
+	int n= *num;
+	long l=length;
+	unsigned long ti[2];
+	unsigned char *iv,c,cc;
+
+	iv=(unsigned char *)ivec;
+	if (encrypt)
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				c2l(iv,v0); ti[0]=v0;
+				c2l(iv,v1); ti[1]=v1;
+				RC2_encrypt((unsigned long *)ti,schedule);
+				iv=(unsigned char *)ivec;
+				t=ti[0]; l2c(t,iv);
+				t=ti[1]; l2c(t,iv);
+				iv=(unsigned char *)ivec;
+				}
+			c= *(in++)^iv[n];
+			*(out++)=c;
+			iv[n]=c;
+			n=(n+1)&0x07;
+			}
+		}
+	else
+		{
+		while (l--)
+			{
+			if (n == 0)
+				{
+				c2l(iv,v0); ti[0]=v0;
+				c2l(iv,v1); ti[1]=v1;
+				RC2_encrypt((unsigned long *)ti,schedule);
+				iv=(unsigned char *)ivec;
+				t=ti[0]; l2c(t,iv);
+				t=ti[1]; l2c(t,iv);
+				iv=(unsigned char *)ivec;
+				}
+			cc= *(in++);
+			c=iv[n];
+			iv[n]=cc;
+			*(out++)=c^cc;
+			n=(n+1)&0x07;
+			}
+		}
+	v0=v1=ti[0]=ti[1]=t=c=cc=0;
+	*num=n;
+	}
+
diff --git a/crypto/libressl/crypto/rc2/rc2ofb64.c b/crypto/libressl/crypto/rc2/rc2ofb64.c
new file mode 100644
index 0000000000..2499cf2668
--- /dev/null
+++ b/crypto/libressl/crypto/rc2/rc2ofb64.c
@@ -0,0 +1,111 @@
+/* $OpenBSD: rc2ofb64.c,v 1.4 2014/06/12 15:49:30 deraadt Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include "rc2_locl.h"
+
+/* The input and output encrypted as though 64bit ofb mode is being
+ * used.  The extra state information to record how much of the
+ * 64bit block we have used is contained in *num;
+ */
+void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+		       long length, RC2_KEY *schedule, unsigned char *ivec,
+		       int *num)
+	{
+	unsigned long v0,v1,t;
+	int n= *num;
+	long l=length;
+	unsigned char d[8];
+	char *dp;
+	unsigned long ti[2];
+	unsigned char *iv;
+	int save=0;
+
+	iv=(unsigned char *)ivec;
+	c2l(iv,v0);
+	c2l(iv,v1);
+	ti[0]=v0;
+	ti[1]=v1;
+	dp=(char *)d;
+	l2c(v0,dp);
+	l2c(v1,dp);
+	while (l--)
+		{
+		if (n == 0)
+			{
+			RC2_encrypt((unsigned long *)ti,schedule);
+			dp=(char *)d;
+			t=ti[0]; l2c(t,dp);
+			t=ti[1]; l2c(t,dp);
+			save++;
+			}
+		*(out++)= *(in++)^d[n];
+		n=(n+1)&0x07;
+		}
+	if (save)
+		{
+		v0=ti[0];
+		v1=ti[1];
+		iv=(unsigned char *)ivec;
+		l2c(v0,iv);
+		l2c(v1,iv);
+		}
+	t=v0=v1=ti[0]=ti[1]=0;
+	*num=n;
+	}
+
diff --git a/crypto/libressl/crypto/rc4/rc4-elf-x86_64.s b/crypto/libressl/crypto/rc4/rc4-elf-x86_64.s
new file mode 100644
index 0000000000..4bf7c5b6be
--- /dev/null
+++ b/crypto/libressl/crypto/rc4/rc4-elf-x86_64.s
@@ -0,0 +1,618 @@
+.text	
+
+
+.globl	RC4
+.type	RC4,@function
+.align	16
+RC4:	orq	%rsi,%rsi
+	jne	.Lentry
+	.byte	0xf3,0xc3
+.Lentry:
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+.Lprologue:
+	movq	%rsi,%r11
+	movq	%rdx,%r12
+	movq	%rcx,%r13
+	xorq	%r10,%r10
+	xorq	%rcx,%rcx
+
+	leaq	8(%rdi),%rdi
+	movb	-8(%rdi),%r10b
+	movb	-4(%rdi),%cl
+	cmpl	$-1,256(%rdi)
+	je	.LRC4_CHAR
+	movl	OPENSSL_ia32cap_P(%rip),%r8d
+	xorq	%rbx,%rbx
+	incb	%r10b
+	subq	%r10,%rbx
+	subq	%r12,%r13
+	movl	(%rdi,%r10,4),%eax
+	testq	$-16,%r11
+	jz	.Lloop1
+	btl	$30,%r8d
+	jc	.Lintel
+	andq	$7,%rbx
+	leaq	1(%r10),%rsi
+	jz	.Loop8
+	subq	%rbx,%r11
+.Loop8_warmup:
+	addb	%al,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	movl	%edx,(%rdi,%r10,4)
+	addb	%dl,%al
+	incb	%r10b
+	movl	(%rdi,%rax,4),%edx
+	movl	(%rdi,%r10,4),%eax
+	xorb	(%r12),%dl
+	movb	%dl,(%r13,%r12,1)
+	leaq	1(%r12),%r12
+	decq	%rbx
+	jnz	.Loop8_warmup
+
+	leaq	1(%r10),%rsi
+	jmp	.Loop8
+.align	16
+.Loop8:
+	addb	%al,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	movl	0(%rdi,%rsi,4),%ebx
+	rorq	$8,%r8
+	movl	%edx,0(%rdi,%r10,4)
+	addb	%al,%dl
+	movb	(%rdi,%rdx,4),%r8b
+	addb	%bl,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	movl	4(%rdi,%rsi,4),%eax
+	rorq	$8,%r8
+	movl	%edx,4(%rdi,%r10,4)
+	addb	%bl,%dl
+	movb	(%rdi,%rdx,4),%r8b
+	addb	%al,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	movl	8(%rdi,%rsi,4),%ebx
+	rorq	$8,%r8
+	movl	%edx,8(%rdi,%r10,4)
+	addb	%al,%dl
+	movb	(%rdi,%rdx,4),%r8b
+	addb	%bl,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	movl	12(%rdi,%rsi,4),%eax
+	rorq	$8,%r8
+	movl	%edx,12(%rdi,%r10,4)
+	addb	%bl,%dl
+	movb	(%rdi,%rdx,4),%r8b
+	addb	%al,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	movl	16(%rdi,%rsi,4),%ebx
+	rorq	$8,%r8
+	movl	%edx,16(%rdi,%r10,4)
+	addb	%al,%dl
+	movb	(%rdi,%rdx,4),%r8b
+	addb	%bl,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	movl	20(%rdi,%rsi,4),%eax
+	rorq	$8,%r8
+	movl	%edx,20(%rdi,%r10,4)
+	addb	%bl,%dl
+	movb	(%rdi,%rdx,4),%r8b
+	addb	%al,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	movl	24(%rdi,%rsi,4),%ebx
+	rorq	$8,%r8
+	movl	%edx,24(%rdi,%r10,4)
+	addb	%al,%dl
+	movb	(%rdi,%rdx,4),%r8b
+	addb	$8,%sil
+	addb	%bl,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	movl	-4(%rdi,%rsi,4),%eax
+	rorq	$8,%r8
+	movl	%edx,28(%rdi,%r10,4)
+	addb	%bl,%dl
+	movb	(%rdi,%rdx,4),%r8b
+	addb	$8,%r10b
+	rorq	$8,%r8
+	subq	$8,%r11
+
+	xorq	(%r12),%r8
+	movq	%r8,(%r13,%r12,1)
+	leaq	8(%r12),%r12
+
+	testq	$-8,%r11
+	jnz	.Loop8
+	cmpq	$0,%r11
+	jne	.Lloop1
+	jmp	.Lexit
+
+.align	16
+.Lintel:
+	testq	$-32,%r11
+	jz	.Lloop1
+	andq	$15,%rbx
+	jz	.Loop16_is_hot
+	subq	%rbx,%r11
+.Loop16_warmup:
+	addb	%al,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	movl	%edx,(%rdi,%r10,4)
+	addb	%dl,%al
+	incb	%r10b
+	movl	(%rdi,%rax,4),%edx
+	movl	(%rdi,%r10,4),%eax
+	xorb	(%r12),%dl
+	movb	%dl,(%r13,%r12,1)
+	leaq	1(%r12),%r12
+	decq	%rbx
+	jnz	.Loop16_warmup
+
+	movq	%rcx,%rbx
+	xorq	%rcx,%rcx
+	movb	%bl,%cl
+
+.Loop16_is_hot:
+	leaq	(%rdi,%r10,4),%rsi
+	addb	%al,%cl
+	movl	(%rdi,%rcx,4),%edx
+	pxor	%xmm0,%xmm0
+	movl	%eax,(%rdi,%rcx,4)
+	addb	%dl,%al
+	movl	4(%rsi),%ebx
+	movzbl	%al,%eax
+	movl	%edx,0(%rsi)
+	addb	%bl,%cl
+	pinsrw	$0,(%rdi,%rax,4),%xmm0
+	jmp	.Loop16_enter
+.align	16
+.Loop16:
+	addb	%al,%cl
+	movl	(%rdi,%rcx,4),%edx
+	pxor	%xmm0,%xmm2
+	psllq	$8,%xmm1
+	pxor	%xmm0,%xmm0
+	movl	%eax,(%rdi,%rcx,4)
+	addb	%dl,%al
+	movl	4(%rsi),%ebx
+	movzbl	%al,%eax
+	movl	%edx,0(%rsi)
+	pxor	%xmm1,%xmm2
+	addb	%bl,%cl
+	pinsrw	$0,(%rdi,%rax,4),%xmm0
+	movdqu	%xmm2,(%r13,%r12,1)
+	leaq	16(%r12),%r12
+.Loop16_enter:
+	movl	(%rdi,%rcx,4),%edx
+	pxor	%xmm1,%xmm1
+	movl	%ebx,(%rdi,%rcx,4)
+	addb	%dl,%bl
+	movl	8(%rsi),%eax
+	movzbl	%bl,%ebx
+	movl	%edx,4(%rsi)
+	addb	%al,%cl
+	pinsrw	$0,(%rdi,%rbx,4),%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	addb	%dl,%al
+	movl	12(%rsi),%ebx
+	movzbl	%al,%eax
+	movl	%edx,8(%rsi)
+	addb	%bl,%cl
+	pinsrw	$1,(%rdi,%rax,4),%xmm0
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	addb	%dl,%bl
+	movl	16(%rsi),%eax
+	movzbl	%bl,%ebx
+	movl	%edx,12(%rsi)
+	addb	%al,%cl
+	pinsrw	$1,(%rdi,%rbx,4),%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	addb	%dl,%al
+	movl	20(%rsi),%ebx
+	movzbl	%al,%eax
+	movl	%edx,16(%rsi)
+	addb	%bl,%cl
+	pinsrw	$2,(%rdi,%rax,4),%xmm0
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	addb	%dl,%bl
+	movl	24(%rsi),%eax
+	movzbl	%bl,%ebx
+	movl	%edx,20(%rsi)
+	addb	%al,%cl
+	pinsrw	$2,(%rdi,%rbx,4),%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	addb	%dl,%al
+	movl	28(%rsi),%ebx
+	movzbl	%al,%eax
+	movl	%edx,24(%rsi)
+	addb	%bl,%cl
+	pinsrw	$3,(%rdi,%rax,4),%xmm0
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	addb	%dl,%bl
+	movl	32(%rsi),%eax
+	movzbl	%bl,%ebx
+	movl	%edx,28(%rsi)
+	addb	%al,%cl
+	pinsrw	$3,(%rdi,%rbx,4),%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	addb	%dl,%al
+	movl	36(%rsi),%ebx
+	movzbl	%al,%eax
+	movl	%edx,32(%rsi)
+	addb	%bl,%cl
+	pinsrw	$4,(%rdi,%rax,4),%xmm0
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	addb	%dl,%bl
+	movl	40(%rsi),%eax
+	movzbl	%bl,%ebx
+	movl	%edx,36(%rsi)
+	addb	%al,%cl
+	pinsrw	$4,(%rdi,%rbx,4),%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	addb	%dl,%al
+	movl	44(%rsi),%ebx
+	movzbl	%al,%eax
+	movl	%edx,40(%rsi)
+	addb	%bl,%cl
+	pinsrw	$5,(%rdi,%rax,4),%xmm0
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	addb	%dl,%bl
+	movl	48(%rsi),%eax
+	movzbl	%bl,%ebx
+	movl	%edx,44(%rsi)
+	addb	%al,%cl
+	pinsrw	$5,(%rdi,%rbx,4),%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	addb	%dl,%al
+	movl	52(%rsi),%ebx
+	movzbl	%al,%eax
+	movl	%edx,48(%rsi)
+	addb	%bl,%cl
+	pinsrw	$6,(%rdi,%rax,4),%xmm0
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	addb	%dl,%bl
+	movl	56(%rsi),%eax
+	movzbl	%bl,%ebx
+	movl	%edx,52(%rsi)
+	addb	%al,%cl
+	pinsrw	$6,(%rdi,%rbx,4),%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	addb	%dl,%al
+	movl	60(%rsi),%ebx
+	movzbl	%al,%eax
+	movl	%edx,56(%rsi)
+	addb	%bl,%cl
+	pinsrw	$7,(%rdi,%rax,4),%xmm0
+	addb	$16,%r10b
+	movdqu	(%r12),%xmm2
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	addb	%dl,%bl
+	movzbl	%bl,%ebx
+	movl	%edx,60(%rsi)
+	leaq	(%rdi,%r10,4),%rsi
+	pinsrw	$7,(%rdi,%rbx,4),%xmm1
+	movl	(%rsi),%eax
+	movq	%rcx,%rbx
+	xorq	%rcx,%rcx
+	subq	$16,%r11
+	movb	%bl,%cl
+	testq	$-16,%r11
+	jnz	.Loop16
+
+	psllq	$8,%xmm1
+	pxor	%xmm0,%xmm2
+	pxor	%xmm1,%xmm2
+	movdqu	%xmm2,(%r13,%r12,1)
+	leaq	16(%r12),%r12
+
+	cmpq	$0,%r11
+	jne	.Lloop1
+	jmp	.Lexit
+
+.align	16
+.Lloop1:
+	addb	%al,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	movl	%edx,(%rdi,%r10,4)
+	addb	%dl,%al
+	incb	%r10b
+	movl	(%rdi,%rax,4),%edx
+	movl	(%rdi,%r10,4),%eax
+	xorb	(%r12),%dl
+	movb	%dl,(%r13,%r12,1)
+	leaq	1(%r12),%r12
+	decq	%r11
+	jnz	.Lloop1
+	jmp	.Lexit
+
+.align	16
+.LRC4_CHAR:
+	addb	$1,%r10b
+	movzbl	(%rdi,%r10,1),%eax
+	testq	$-8,%r11
+	jz	.Lcloop1
+	jmp	.Lcloop8
+.align	16
+.Lcloop8:
+	movl	(%r12),%r8d
+	movl	4(%r12),%r9d
+	addb	%al,%cl
+	leaq	1(%r10),%rsi
+	movzbl	(%rdi,%rcx,1),%edx
+	movzbl	%sil,%esi
+	movzbl	(%rdi,%rsi,1),%ebx
+	movb	%al,(%rdi,%rcx,1)
+	cmpq	%rsi,%rcx
+	movb	%dl,(%rdi,%r10,1)
+	jne	.Lcmov0			
+	movq	%rax,%rbx
+.Lcmov0:
+	addb	%al,%dl
+	xorb	(%rdi,%rdx,1),%r8b
+	rorl	$8,%r8d
+	addb	%bl,%cl
+	leaq	1(%rsi),%r10
+	movzbl	(%rdi,%rcx,1),%edx
+	movzbl	%r10b,%r10d
+	movzbl	(%rdi,%r10,1),%eax
+	movb	%bl,(%rdi,%rcx,1)
+	cmpq	%r10,%rcx
+	movb	%dl,(%rdi,%rsi,1)
+	jne	.Lcmov1			
+	movq	%rbx,%rax
+.Lcmov1:
+	addb	%bl,%dl
+	xorb	(%rdi,%rdx,1),%r8b
+	rorl	$8,%r8d
+	addb	%al,%cl
+	leaq	1(%r10),%rsi
+	movzbl	(%rdi,%rcx,1),%edx
+	movzbl	%sil,%esi
+	movzbl	(%rdi,%rsi,1),%ebx
+	movb	%al,(%rdi,%rcx,1)
+	cmpq	%rsi,%rcx
+	movb	%dl,(%rdi,%r10,1)
+	jne	.Lcmov2			
+	movq	%rax,%rbx
+.Lcmov2:
+	addb	%al,%dl
+	xorb	(%rdi,%rdx,1),%r8b
+	rorl	$8,%r8d
+	addb	%bl,%cl
+	leaq	1(%rsi),%r10
+	movzbl	(%rdi,%rcx,1),%edx
+	movzbl	%r10b,%r10d
+	movzbl	(%rdi,%r10,1),%eax
+	movb	%bl,(%rdi,%rcx,1)
+	cmpq	%r10,%rcx
+	movb	%dl,(%rdi,%rsi,1)
+	jne	.Lcmov3			
+	movq	%rbx,%rax
+.Lcmov3:
+	addb	%bl,%dl
+	xorb	(%rdi,%rdx,1),%r8b
+	rorl	$8,%r8d
+	addb	%al,%cl
+	leaq	1(%r10),%rsi
+	movzbl	(%rdi,%rcx,1),%edx
+	movzbl	%sil,%esi
+	movzbl	(%rdi,%rsi,1),%ebx
+	movb	%al,(%rdi,%rcx,1)
+	cmpq	%rsi,%rcx
+	movb	%dl,(%rdi,%r10,1)
+	jne	.Lcmov4			
+	movq	%rax,%rbx
+.Lcmov4:
+	addb	%al,%dl
+	xorb	(%rdi,%rdx,1),%r9b
+	rorl	$8,%r9d
+	addb	%bl,%cl
+	leaq	1(%rsi),%r10
+	movzbl	(%rdi,%rcx,1),%edx
+	movzbl	%r10b,%r10d
+	movzbl	(%rdi,%r10,1),%eax
+	movb	%bl,(%rdi,%rcx,1)
+	cmpq	%r10,%rcx
+	movb	%dl,(%rdi,%rsi,1)
+	jne	.Lcmov5			
+	movq	%rbx,%rax
+.Lcmov5:
+	addb	%bl,%dl
+	xorb	(%rdi,%rdx,1),%r9b
+	rorl	$8,%r9d
+	addb	%al,%cl
+	leaq	1(%r10),%rsi
+	movzbl	(%rdi,%rcx,1),%edx
+	movzbl	%sil,%esi
+	movzbl	(%rdi,%rsi,1),%ebx
+	movb	%al,(%rdi,%rcx,1)
+	cmpq	%rsi,%rcx
+	movb	%dl,(%rdi,%r10,1)
+	jne	.Lcmov6			
+	movq	%rax,%rbx
+.Lcmov6:
+	addb	%al,%dl
+	xorb	(%rdi,%rdx,1),%r9b
+	rorl	$8,%r9d
+	addb	%bl,%cl
+	leaq	1(%rsi),%r10
+	movzbl	(%rdi,%rcx,1),%edx
+	movzbl	%r10b,%r10d
+	movzbl	(%rdi,%r10,1),%eax
+	movb	%bl,(%rdi,%rcx,1)
+	cmpq	%r10,%rcx
+	movb	%dl,(%rdi,%rsi,1)
+	jne	.Lcmov7			
+	movq	%rbx,%rax
+.Lcmov7:
+	addb	%bl,%dl
+	xorb	(%rdi,%rdx,1),%r9b
+	rorl	$8,%r9d
+	leaq	-8(%r11),%r11
+	movl	%r8d,(%r13)
+	leaq	8(%r12),%r12
+	movl	%r9d,4(%r13)
+	leaq	8(%r13),%r13
+
+	testq	$-8,%r11
+	jnz	.Lcloop8
+	cmpq	$0,%r11
+	jne	.Lcloop1
+	jmp	.Lexit
+.align	16
+.Lcloop1:
+	addb	%al,%cl
+	movzbl	%cl,%ecx
+	movzbl	(%rdi,%rcx,1),%edx
+	movb	%al,(%rdi,%rcx,1)
+	movb	%dl,(%rdi,%r10,1)
+	addb	%al,%dl
+	addb	$1,%r10b
+	movzbl	%dl,%edx
+	movzbl	%r10b,%r10d
+	movzbl	(%rdi,%rdx,1),%edx
+	movzbl	(%rdi,%r10,1),%eax
+	xorb	(%r12),%dl
+	leaq	1(%r12),%r12
+	movb	%dl,(%r13)
+	leaq	1(%r13),%r13
+	subq	$1,%r11
+	jnz	.Lcloop1
+	jmp	.Lexit
+
+.align	16
+.Lexit:
+	subb	$1,%r10b
+	movl	%r10d,-8(%rdi)
+	movl	%ecx,-4(%rdi)
+
+	movq	(%rsp),%r13
+	movq	8(%rsp),%r12
+	movq	16(%rsp),%rbx
+	addq	$24,%rsp
+.Lepilogue:
+	.byte	0xf3,0xc3
+.size	RC4,.-RC4
+.globl	RC4_set_key
+.type	RC4_set_key,@function
+.align	16
+RC4_set_key:
+	leaq	8(%rdi),%rdi
+	leaq	(%rdx,%rsi,1),%rdx
+	negq	%rsi
+	movq	%rsi,%rcx
+	xorl	%eax,%eax
+	xorq	%r9,%r9
+	xorq	%r10,%r10
+	xorq	%r11,%r11
+
+	movl	OPENSSL_ia32cap_P(%rip),%r8d
+	btl	$20,%r8d
+	jc	.Lc1stloop
+	jmp	.Lw1stloop
+
+.align	16
+.Lw1stloop:
+	movl	%eax,(%rdi,%rax,4)
+	addb	$1,%al
+	jnc	.Lw1stloop
+
+	xorq	%r9,%r9
+	xorq	%r8,%r8
+.align	16
+.Lw2ndloop:
+	movl	(%rdi,%r9,4),%r10d
+	addb	(%rdx,%rsi,1),%r8b
+	addb	%r10b,%r8b
+	addq	$1,%rsi
+	movl	(%rdi,%r8,4),%r11d
+	cmovzq	%rcx,%rsi
+	movl	%r10d,(%rdi,%r8,4)
+	movl	%r11d,(%rdi,%r9,4)
+	addb	$1,%r9b
+	jnc	.Lw2ndloop
+	jmp	.Lexit_key
+
+.align	16
+.Lc1stloop:
+	movb	%al,(%rdi,%rax,1)
+	addb	$1,%al
+	jnc	.Lc1stloop
+
+	xorq	%r9,%r9
+	xorq	%r8,%r8
+.align	16
+.Lc2ndloop:
+	movb	(%rdi,%r9,1),%r10b
+	addb	(%rdx,%rsi,1),%r8b
+	addb	%r10b,%r8b
+	addq	$1,%rsi
+	movb	(%rdi,%r8,1),%r11b
+	jnz	.Lcnowrap
+	movq	%rcx,%rsi
+.Lcnowrap:
+	movb	%r10b,(%rdi,%r8,1)
+	movb	%r11b,(%rdi,%r9,1)
+	addb	$1,%r9b
+	jnc	.Lc2ndloop
+	movl	$-1,256(%rdi)
+
+.align	16
+.Lexit_key:
+	xorl	%eax,%eax
+	movl	%eax,-8(%rdi)
+	movl	%eax,-4(%rdi)
+	.byte	0xf3,0xc3
+.size	RC4_set_key,.-RC4_set_key
+
+.globl	RC4_options
+.type	RC4_options,@function
+.align	16
+RC4_options:
+	leaq	.Lopts(%rip),%rax
+	movl	OPENSSL_ia32cap_P(%rip),%edx
+	btl	$20,%edx
+	jc	.L8xchar
+	btl	$30,%edx
+	jnc	.Ldone
+	addq	$25,%rax
+	.byte	0xf3,0xc3
+.L8xchar:
+	addq	$12,%rax
+.Ldone:
+	.byte	0xf3,0xc3
+.align	64
+.Lopts:
+.byte	114,99,52,40,56,120,44,105,110,116,41,0
+.byte	114,99,52,40,56,120,44,99,104,97,114,41,0
+.byte	114,99,52,40,49,54,120,44,105,110,116,41,0
+.byte	82,67,52,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align	64
+.size	RC4_options,.-RC4_options
+#if defined(HAVE_GNU_STACK)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/crypto/libressl/crypto/rc4/rc4-macosx-x86_64.s b/crypto/libressl/crypto/rc4/rc4-macosx-x86_64.s
new file mode 100644
index 0000000000..1f86344347
--- /dev/null
+++ b/crypto/libressl/crypto/rc4/rc4-macosx-x86_64.s
@@ -0,0 +1,615 @@
+.text	
+
+
+.globl	_RC4
+
+.p2align	4
+_RC4:	orq	%rsi,%rsi
+	jne	L$entry
+	.byte	0xf3,0xc3
+L$entry:
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+L$prologue:
+	movq	%rsi,%r11
+	movq	%rdx,%r12
+	movq	%rcx,%r13
+	xorq	%r10,%r10
+	xorq	%rcx,%rcx
+
+	leaq	8(%rdi),%rdi
+	movb	-8(%rdi),%r10b
+	movb	-4(%rdi),%cl
+	cmpl	$-1,256(%rdi)
+	je	L$RC4_CHAR
+	movl	_OPENSSL_ia32cap_P(%rip),%r8d
+	xorq	%rbx,%rbx
+	incb	%r10b
+	subq	%r10,%rbx
+	subq	%r12,%r13
+	movl	(%rdi,%r10,4),%eax
+	testq	$-16,%r11
+	jz	L$loop1
+	btl	$30,%r8d
+	jc	L$intel
+	andq	$7,%rbx
+	leaq	1(%r10),%rsi
+	jz	L$oop8
+	subq	%rbx,%r11
+L$oop8_warmup:
+	addb	%al,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	movl	%edx,(%rdi,%r10,4)
+	addb	%dl,%al
+	incb	%r10b
+	movl	(%rdi,%rax,4),%edx
+	movl	(%rdi,%r10,4),%eax
+	xorb	(%r12),%dl
+	movb	%dl,(%r13,%r12,1)
+	leaq	1(%r12),%r12
+	decq	%rbx
+	jnz	L$oop8_warmup
+
+	leaq	1(%r10),%rsi
+	jmp	L$oop8
+.p2align	4
+L$oop8:
+	addb	%al,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	movl	0(%rdi,%rsi,4),%ebx
+	rorq	$8,%r8
+	movl	%edx,0(%rdi,%r10,4)
+	addb	%al,%dl
+	movb	(%rdi,%rdx,4),%r8b
+	addb	%bl,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	movl	4(%rdi,%rsi,4),%eax
+	rorq	$8,%r8
+	movl	%edx,4(%rdi,%r10,4)
+	addb	%bl,%dl
+	movb	(%rdi,%rdx,4),%r8b
+	addb	%al,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	movl	8(%rdi,%rsi,4),%ebx
+	rorq	$8,%r8
+	movl	%edx,8(%rdi,%r10,4)
+	addb	%al,%dl
+	movb	(%rdi,%rdx,4),%r8b
+	addb	%bl,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	movl	12(%rdi,%rsi,4),%eax
+	rorq	$8,%r8
+	movl	%edx,12(%rdi,%r10,4)
+	addb	%bl,%dl
+	movb	(%rdi,%rdx,4),%r8b
+	addb	%al,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	movl	16(%rdi,%rsi,4),%ebx
+	rorq	$8,%r8
+	movl	%edx,16(%rdi,%r10,4)
+	addb	%al,%dl
+	movb	(%rdi,%rdx,4),%r8b
+	addb	%bl,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	movl	20(%rdi,%rsi,4),%eax
+	rorq	$8,%r8
+	movl	%edx,20(%rdi,%r10,4)
+	addb	%bl,%dl
+	movb	(%rdi,%rdx,4),%r8b
+	addb	%al,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	movl	24(%rdi,%rsi,4),%ebx
+	rorq	$8,%r8
+	movl	%edx,24(%rdi,%r10,4)
+	addb	%al,%dl
+	movb	(%rdi,%rdx,4),%r8b
+	addb	$8,%sil
+	addb	%bl,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	movl	-4(%rdi,%rsi,4),%eax
+	rorq	$8,%r8
+	movl	%edx,28(%rdi,%r10,4)
+	addb	%bl,%dl
+	movb	(%rdi,%rdx,4),%r8b
+	addb	$8,%r10b
+	rorq	$8,%r8
+	subq	$8,%r11
+
+	xorq	(%r12),%r8
+	movq	%r8,(%r13,%r12,1)
+	leaq	8(%r12),%r12
+
+	testq	$-8,%r11
+	jnz	L$oop8
+	cmpq	$0,%r11
+	jne	L$loop1
+	jmp	L$exit
+
+.p2align	4
+L$intel:
+	testq	$-32,%r11
+	jz	L$loop1
+	andq	$15,%rbx
+	jz	L$oop16_is_hot
+	subq	%rbx,%r11
+L$oop16_warmup:
+	addb	%al,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	movl	%edx,(%rdi,%r10,4)
+	addb	%dl,%al
+	incb	%r10b
+	movl	(%rdi,%rax,4),%edx
+	movl	(%rdi,%r10,4),%eax
+	xorb	(%r12),%dl
+	movb	%dl,(%r13,%r12,1)
+	leaq	1(%r12),%r12
+	decq	%rbx
+	jnz	L$oop16_warmup
+
+	movq	%rcx,%rbx
+	xorq	%rcx,%rcx
+	movb	%bl,%cl
+
+L$oop16_is_hot:
+	leaq	(%rdi,%r10,4),%rsi
+	addb	%al,%cl
+	movl	(%rdi,%rcx,4),%edx
+	pxor	%xmm0,%xmm0
+	movl	%eax,(%rdi,%rcx,4)
+	addb	%dl,%al
+	movl	4(%rsi),%ebx
+	movzbl	%al,%eax
+	movl	%edx,0(%rsi)
+	addb	%bl,%cl
+	pinsrw	$0,(%rdi,%rax,4),%xmm0
+	jmp	L$oop16_enter
+.p2align	4
+L$oop16:
+	addb	%al,%cl
+	movl	(%rdi,%rcx,4),%edx
+	pxor	%xmm0,%xmm2
+	psllq	$8,%xmm1
+	pxor	%xmm0,%xmm0
+	movl	%eax,(%rdi,%rcx,4)
+	addb	%dl,%al
+	movl	4(%rsi),%ebx
+	movzbl	%al,%eax
+	movl	%edx,0(%rsi)
+	pxor	%xmm1,%xmm2
+	addb	%bl,%cl
+	pinsrw	$0,(%rdi,%rax,4),%xmm0
+	movdqu	%xmm2,(%r13,%r12,1)
+	leaq	16(%r12),%r12
+L$oop16_enter:
+	movl	(%rdi,%rcx,4),%edx
+	pxor	%xmm1,%xmm1
+	movl	%ebx,(%rdi,%rcx,4)
+	addb	%dl,%bl
+	movl	8(%rsi),%eax
+	movzbl	%bl,%ebx
+	movl	%edx,4(%rsi)
+	addb	%al,%cl
+	pinsrw	$0,(%rdi,%rbx,4),%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	addb	%dl,%al
+	movl	12(%rsi),%ebx
+	movzbl	%al,%eax
+	movl	%edx,8(%rsi)
+	addb	%bl,%cl
+	pinsrw	$1,(%rdi,%rax,4),%xmm0
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	addb	%dl,%bl
+	movl	16(%rsi),%eax
+	movzbl	%bl,%ebx
+	movl	%edx,12(%rsi)
+	addb	%al,%cl
+	pinsrw	$1,(%rdi,%rbx,4),%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	addb	%dl,%al
+	movl	20(%rsi),%ebx
+	movzbl	%al,%eax
+	movl	%edx,16(%rsi)
+	addb	%bl,%cl
+	pinsrw	$2,(%rdi,%rax,4),%xmm0
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	addb	%dl,%bl
+	movl	24(%rsi),%eax
+	movzbl	%bl,%ebx
+	movl	%edx,20(%rsi)
+	addb	%al,%cl
+	pinsrw	$2,(%rdi,%rbx,4),%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	addb	%dl,%al
+	movl	28(%rsi),%ebx
+	movzbl	%al,%eax
+	movl	%edx,24(%rsi)
+	addb	%bl,%cl
+	pinsrw	$3,(%rdi,%rax,4),%xmm0
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	addb	%dl,%bl
+	movl	32(%rsi),%eax
+	movzbl	%bl,%ebx
+	movl	%edx,28(%rsi)
+	addb	%al,%cl
+	pinsrw	$3,(%rdi,%rbx,4),%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	addb	%dl,%al
+	movl	36(%rsi),%ebx
+	movzbl	%al,%eax
+	movl	%edx,32(%rsi)
+	addb	%bl,%cl
+	pinsrw	$4,(%rdi,%rax,4),%xmm0
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	addb	%dl,%bl
+	movl	40(%rsi),%eax
+	movzbl	%bl,%ebx
+	movl	%edx,36(%rsi)
+	addb	%al,%cl
+	pinsrw	$4,(%rdi,%rbx,4),%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	addb	%dl,%al
+	movl	44(%rsi),%ebx
+	movzbl	%al,%eax
+	movl	%edx,40(%rsi)
+	addb	%bl,%cl
+	pinsrw	$5,(%rdi,%rax,4),%xmm0
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	addb	%dl,%bl
+	movl	48(%rsi),%eax
+	movzbl	%bl,%ebx
+	movl	%edx,44(%rsi)
+	addb	%al,%cl
+	pinsrw	$5,(%rdi,%rbx,4),%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	addb	%dl,%al
+	movl	52(%rsi),%ebx
+	movzbl	%al,%eax
+	movl	%edx,48(%rsi)
+	addb	%bl,%cl
+	pinsrw	$6,(%rdi,%rax,4),%xmm0
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	addb	%dl,%bl
+	movl	56(%rsi),%eax
+	movzbl	%bl,%ebx
+	movl	%edx,52(%rsi)
+	addb	%al,%cl
+	pinsrw	$6,(%rdi,%rbx,4),%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	addb	%dl,%al
+	movl	60(%rsi),%ebx
+	movzbl	%al,%eax
+	movl	%edx,56(%rsi)
+	addb	%bl,%cl
+	pinsrw	$7,(%rdi,%rax,4),%xmm0
+	addb	$16,%r10b
+	movdqu	(%r12),%xmm2
+	movl	(%rdi,%rcx,4),%edx
+	movl	%ebx,(%rdi,%rcx,4)
+	addb	%dl,%bl
+	movzbl	%bl,%ebx
+	movl	%edx,60(%rsi)
+	leaq	(%rdi,%r10,4),%rsi
+	pinsrw	$7,(%rdi,%rbx,4),%xmm1
+	movl	(%rsi),%eax
+	movq	%rcx,%rbx
+	xorq	%rcx,%rcx
+	subq	$16,%r11
+	movb	%bl,%cl
+	testq	$-16,%r11
+	jnz	L$oop16
+
+	psllq	$8,%xmm1
+	pxor	%xmm0,%xmm2
+	pxor	%xmm1,%xmm2
+	movdqu	%xmm2,(%r13,%r12,1)
+	leaq	16(%r12),%r12
+
+	cmpq	$0,%r11
+	jne	L$loop1
+	jmp	L$exit
+
+.p2align	4
+L$loop1:
+	addb	%al,%cl
+	movl	(%rdi,%rcx,4),%edx
+	movl	%eax,(%rdi,%rcx,4)
+	movl	%edx,(%rdi,%r10,4)
+	addb	%dl,%al
+	incb	%r10b
+	movl	(%rdi,%rax,4),%edx
+	movl	(%rdi,%r10,4),%eax
+	xorb	(%r12),%dl
+	movb	%dl,(%r13,%r12,1)
+	leaq	1(%r12),%r12
+	decq	%r11
+	jnz	L$loop1
+	jmp	L$exit
+
+.p2align	4
+L$RC4_CHAR:
+	addb	$1,%r10b
+	movzbl	(%rdi,%r10,1),%eax
+	testq	$-8,%r11
+	jz	L$cloop1
+	jmp	L$cloop8
+.p2align	4
+L$cloop8:
+	movl	(%r12),%r8d
+	movl	4(%r12),%r9d
+	addb	%al,%cl
+	leaq	1(%r10),%rsi
+	movzbl	(%rdi,%rcx,1),%edx
+	movzbl	%sil,%esi
+	movzbl	(%rdi,%rsi,1),%ebx
+	movb	%al,(%rdi,%rcx,1)
+	cmpq	%rsi,%rcx
+	movb	%dl,(%rdi,%r10,1)
+	jne	L$cmov0			
+	movq	%rax,%rbx
+L$cmov0:
+	addb	%al,%dl
+	xorb	(%rdi,%rdx,1),%r8b
+	rorl	$8,%r8d
+	addb	%bl,%cl
+	leaq	1(%rsi),%r10
+	movzbl	(%rdi,%rcx,1),%edx
+	movzbl	%r10b,%r10d
+	movzbl	(%rdi,%r10,1),%eax
+	movb	%bl,(%rdi,%rcx,1)
+	cmpq	%r10,%rcx
+	movb	%dl,(%rdi,%rsi,1)
+	jne	L$cmov1			
+	movq	%rbx,%rax
+L$cmov1:
+	addb	%bl,%dl
+	xorb	(%rdi,%rdx,1),%r8b
+	rorl	$8,%r8d
+	addb	%al,%cl
+	leaq	1(%r10),%rsi
+	movzbl	(%rdi,%rcx,1),%edx
+	movzbl	%sil,%esi
+	movzbl	(%rdi,%rsi,1),%ebx
+	movb	%al,(%rdi,%rcx,1)
+	cmpq	%rsi,%rcx
+	movb	%dl,(%rdi,%r10,1)
+	jne	L$cmov2			
+	movq	%rax,%rbx
+L$cmov2:
+	addb	%al,%dl
+	xorb	(%rdi,%rdx,1),%r8b
+	rorl	$8,%r8d
+	addb	%bl,%cl
+	leaq	1(%rsi),%r10
+	movzbl	(%rdi,%rcx,1),%edx
+	movzbl	%r10b,%r10d
+	movzbl	(%rdi,%r10,1),%eax
+	movb	%bl,(%rdi,%rcx,1)
+	cmpq	%r10,%rcx
+	movb	%dl,(%rdi,%rsi,1)
+	jne	L$cmov3			
+	movq	%rbx,%rax
+L$cmov3:
+	addb	%bl,%dl
+	xorb	(%rdi,%rdx,1),%r8b
+	rorl	$8,%r8d
+	addb	%al,%cl
+	leaq	1(%r10),%rsi
+	movzbl	(%rdi,%rcx,1),%edx
+	movzbl	%sil,%esi
+	movzbl	(%rdi,%rsi,1),%ebx
+	movb	%al,(%rdi,%rcx,1)
+	cmpq	%rsi,%rcx
+	movb	%dl,(%rdi,%r10,1)
+	jne	L$cmov4			
+	movq	%rax,%rbx
+L$cmov4:
+	addb	%al,%dl
+	xorb	(%rdi,%rdx,1),%r9b
+	rorl	$8,%r9d
+	addb	%bl,%cl
+	leaq	1(%rsi),%r10
+	movzbl	(%rdi,%rcx,1),%edx
+	movzbl	%r10b,%r10d
+	movzbl	(%rdi,%r10,1),%eax
+	movb	%bl,(%rdi,%rcx,1)
+	cmpq	%r10,%rcx
+	movb	%dl,(%rdi,%rsi,1)
+	jne	L$cmov5			
+	movq	%rbx,%rax
+L$cmov5:
+	addb	%bl,%dl
+	xorb	(%rdi,%rdx,1),%r9b
+	rorl	$8,%r9d
+	addb	%al,%cl
+	leaq	1(%r10),%rsi
+	movzbl	(%rdi,%rcx,1),%edx
+	movzbl	%sil,%esi
+	movzbl	(%rdi,%rsi,1),%ebx
+	movb	%al,(%rdi,%rcx,1)
+	cmpq	%rsi,%rcx
+	movb	%dl,(%rdi,%r10,1)
+	jne	L$cmov6			
+	movq	%rax,%rbx
+L$cmov6:
+	addb	%al,%dl
+	xorb	(%rdi,%rdx,1),%r9b
+	rorl	$8,%r9d
+	addb	%bl,%cl
+	leaq	1(%rsi),%r10
+	movzbl	(%rdi,%rcx,1),%edx
+	movzbl	%r10b,%r10d
+	movzbl	(%rdi,%r10,1),%eax
+	movb	%bl,(%rdi,%rcx,1)
+	cmpq	%r10,%rcx
+	movb	%dl,(%rdi,%rsi,1)
+	jne	L$cmov7			
+	movq	%rbx,%rax
+L$cmov7:
+	addb	%bl,%dl
+	xorb	(%rdi,%rdx,1),%r9b
+	rorl	$8,%r9d
+	leaq	-8(%r11),%r11
+	movl	%r8d,(%r13)
+	leaq	8(%r12),%r12
+	movl	%r9d,4(%r13)
+	leaq	8(%r13),%r13
+
+	testq	$-8,%r11
+	jnz	L$cloop8
+	cmpq	$0,%r11
+	jne	L$cloop1
+	jmp	L$exit
+.p2align	4
+L$cloop1:
+	addb	%al,%cl
+	movzbl	%cl,%ecx
+	movzbl	(%rdi,%rcx,1),%edx
+	movb	%al,(%rdi,%rcx,1)
+	movb	%dl,(%rdi,%r10,1)
+	addb	%al,%dl
+	addb	$1,%r10b
+	movzbl	%dl,%edx
+	movzbl	%r10b,%r10d
+	movzbl	(%rdi,%rdx,1),%edx
+	movzbl	(%rdi,%r10,1),%eax
+	xorb	(%r12),%dl
+	leaq	1(%r12),%r12
+	movb	%dl,(%r13)
+	leaq	1(%r13),%r13
+	subq	$1,%r11
+	jnz	L$cloop1
+	jmp	L$exit
+
+.p2align	4
+L$exit:
+	subb	$1,%r10b
+	movl	%r10d,-8(%rdi)
+	movl	%ecx,-4(%rdi)
+
+	movq	(%rsp),%r13
+	movq	8(%rsp),%r12
+	movq	16(%rsp),%rbx
+	addq	$24,%rsp
+L$epilogue:
+	.byte	0xf3,0xc3
+
+.globl	_RC4_set_key
+
+.p2align	4
+_RC4_set_key:
+	leaq	8(%rdi),%rdi
+	leaq	(%rdx,%rsi,1),%rdx
+	negq	%rsi
+	movq	%rsi,%rcx
+	xorl	%eax,%eax
+	xorq	%r9,%r9
+	xorq	%r10,%r10
+	xorq	%r11,%r11
+
+	movl	_OPENSSL_ia32cap_P(%rip),%r8d
+	btl	$20,%r8d
+	jc	L$c1stloop
+	jmp	L$w1stloop
+
+.p2align	4
+L$w1stloop:
+	movl	%eax,(%rdi,%rax,4)
+	addb	$1,%al
+	jnc	L$w1stloop
+
+	xorq	%r9,%r9
+	xorq	%r8,%r8
+.p2align	4
+L$w2ndloop:
+	movl	(%rdi,%r9,4),%r10d
+	addb	(%rdx,%rsi,1),%r8b
+	addb	%r10b,%r8b
+	addq	$1,%rsi
+	movl	(%rdi,%r8,4),%r11d
+	cmovzq	%rcx,%rsi
+	movl	%r10d,(%rdi,%r8,4)
+	movl	%r11d,(%rdi,%r9,4)
+	addb	$1,%r9b
+	jnc	L$w2ndloop
+	jmp	L$exit_key
+
+.p2align	4
+L$c1stloop:
+	movb	%al,(%rdi,%rax,1)
+	addb	$1,%al
+	jnc	L$c1stloop
+
+	xorq	%r9,%r9
+	xorq	%r8,%r8
+.p2align	4
+L$c2ndloop:
+	movb	(%rdi,%r9,1),%r10b
+	addb	(%rdx,%rsi,1),%r8b
+	addb	%r10b,%r8b
+	addq	$1,%rsi
+	movb	(%rdi,%r8,1),%r11b
+	jnz	L$cnowrap
+	movq	%rcx,%rsi
+L$cnowrap:
+	movb	%r10b,(%rdi,%r8,1)
+	movb	%r11b,(%rdi,%r9,1)
+	addb	$1,%r9b
+	jnc	L$c2ndloop
+	movl	$-1,256(%rdi)
+
+.p2align	4
+L$exit_key:
+	xorl	%eax,%eax
+	movl	%eax,-8(%rdi)
+	movl	%eax,-4(%rdi)
+	.byte	0xf3,0xc3
+
+
+.globl	_RC4_options
+
+.p2align	4
+_RC4_options:
+	leaq	L$opts(%rip),%rax
+	movl	_OPENSSL_ia32cap_P(%rip),%edx
+	btl	$20,%edx
+	jc	L$8xchar
+	btl	$30,%edx
+	jnc	L$done
+	addq	$25,%rax
+	.byte	0xf3,0xc3
+L$8xchar:
+	addq	$12,%rax
+L$done:
+	.byte	0xf3,0xc3
+.p2align	6
+L$opts:
+.byte	114,99,52,40,56,120,44,105,110,116,41,0
+.byte	114,99,52,40,56,120,44,99,104,97,114,41,0
+.byte	114,99,52,40,49,54,120,44,105,110,116,41,0
+.byte	82,67,52,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.p2align	6
+
diff --git a/crypto/libressl/crypto/rc4/rc4-md5-elf-x86_64.s b/crypto/libressl/crypto/rc4/rc4-md5-elf-x86_64.s
new file mode 100644
index 0000000000..ceed3f8c31
--- /dev/null
+++ b/crypto/libressl/crypto/rc4/rc4-md5-elf-x86_64.s
@@ -0,0 +1,1262 @@
+.text	
+.align	16
+
+.globl	rc4_md5_enc
+.type	rc4_md5_enc,@function
+rc4_md5_enc:
+	cmpq	$0,%r9
+	je	.Labort
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	subq	$40,%rsp
+.Lbody:
+	movq	%rcx,%r11
+	movq	%r9,%r12
+	movq	%rsi,%r13
+	movq	%rdx,%r14
+	movq	%r8,%r15
+	xorq	%rbp,%rbp
+	xorq	%rcx,%rcx
+
+	leaq	8(%rdi),%rdi
+	movb	-8(%rdi),%bpl
+	movb	-4(%rdi),%cl
+
+	incb	%bpl
+	subq	%r13,%r14
+	movl	(%rdi,%rbp,4),%eax
+	addb	%al,%cl
+	leaq	(%rdi,%rbp,4),%rsi
+	shlq	$6,%r12
+	addq	%r15,%r12
+	movq	%r12,16(%rsp)
+
+	movq	%r11,24(%rsp)
+	movl	0(%r11),%r8d
+	movl	4(%r11),%r9d
+	movl	8(%r11),%r10d
+	movl	12(%r11),%r11d
+	jmp	.Loop
+
+.align	16
+.Loop:
+	movl	%r8d,0(%rsp)
+	movl	%r9d,4(%rsp)
+	movl	%r10d,8(%rsp)
+	movl	%r11d,%r12d
+	movl	%r11d,12(%rsp)
+	pxor	%xmm0,%xmm0
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r9d,%r12d
+	addl	0(%r15),%r8d
+	addb	%dl,%al
+	movl	4(%rsi),%ebx
+	addl	$3614090360,%r8d
+	xorl	%r11d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,0(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$7,%r8d
+	movl	%r10d,%r12d
+	movd	(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	pxor	%xmm1,%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r8d,%r12d
+	addl	4(%r15),%r11d
+	addb	%dl,%bl
+	movl	8(%rsi),%eax
+	addl	$3905402710,%r11d
+	xorl	%r10d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,4(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$12,%r11d
+	movl	%r9d,%r12d
+	movd	(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r11d,%r12d
+	addl	8(%r15),%r10d
+	addb	%dl,%al
+	movl	12(%rsi),%ebx
+	addl	$606105819,%r10d
+	xorl	%r9d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,8(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$17,%r10d
+	movl	%r8d,%r12d
+	pinsrw	$1,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r10d,%r12d
+	addl	12(%r15),%r9d
+	addb	%dl,%bl
+	movl	16(%rsi),%eax
+	addl	$3250441966,%r9d
+	xorl	%r8d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,12(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$22,%r9d
+	movl	%r11d,%r12d
+	pinsrw	$1,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r9d,%r12d
+	addl	16(%r15),%r8d
+	addb	%dl,%al
+	movl	20(%rsi),%ebx
+	addl	$4118548399,%r8d
+	xorl	%r11d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,16(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$7,%r8d
+	movl	%r10d,%r12d
+	pinsrw	$2,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r8d,%r12d
+	addl	20(%r15),%r11d
+	addb	%dl,%bl
+	movl	24(%rsi),%eax
+	addl	$1200080426,%r11d
+	xorl	%r10d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,20(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$12,%r11d
+	movl	%r9d,%r12d
+	pinsrw	$2,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r11d,%r12d
+	addl	24(%r15),%r10d
+	addb	%dl,%al
+	movl	28(%rsi),%ebx
+	addl	$2821735955,%r10d
+	xorl	%r9d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,24(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$17,%r10d
+	movl	%r8d,%r12d
+	pinsrw	$3,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r10d,%r12d
+	addl	28(%r15),%r9d
+	addb	%dl,%bl
+	movl	32(%rsi),%eax
+	addl	$4249261313,%r9d
+	xorl	%r8d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,28(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$22,%r9d
+	movl	%r11d,%r12d
+	pinsrw	$3,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r9d,%r12d
+	addl	32(%r15),%r8d
+	addb	%dl,%al
+	movl	36(%rsi),%ebx
+	addl	$1770035416,%r8d
+	xorl	%r11d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,32(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$7,%r8d
+	movl	%r10d,%r12d
+	pinsrw	$4,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r8d,%r12d
+	addl	36(%r15),%r11d
+	addb	%dl,%bl
+	movl	40(%rsi),%eax
+	addl	$2336552879,%r11d
+	xorl	%r10d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,36(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$12,%r11d
+	movl	%r9d,%r12d
+	pinsrw	$4,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r11d,%r12d
+	addl	40(%r15),%r10d
+	addb	%dl,%al
+	movl	44(%rsi),%ebx
+	addl	$4294925233,%r10d
+	xorl	%r9d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,40(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$17,%r10d
+	movl	%r8d,%r12d
+	pinsrw	$5,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r10d,%r12d
+	addl	44(%r15),%r9d
+	addb	%dl,%bl
+	movl	48(%rsi),%eax
+	addl	$2304563134,%r9d
+	xorl	%r8d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,44(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$22,%r9d
+	movl	%r11d,%r12d
+	pinsrw	$5,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r9d,%r12d
+	addl	48(%r15),%r8d
+	addb	%dl,%al
+	movl	52(%rsi),%ebx
+	addl	$1804603682,%r8d
+	xorl	%r11d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,48(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$7,%r8d
+	movl	%r10d,%r12d
+	pinsrw	$6,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r8d,%r12d
+	addl	52(%r15),%r11d
+	addb	%dl,%bl
+	movl	56(%rsi),%eax
+	addl	$4254626195,%r11d
+	xorl	%r10d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,52(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$12,%r11d
+	movl	%r9d,%r12d
+	pinsrw	$6,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r11d,%r12d
+	addl	56(%r15),%r10d
+	addb	%dl,%al
+	movl	60(%rsi),%ebx
+	addl	$2792965006,%r10d
+	xorl	%r9d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,56(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$17,%r10d
+	movl	%r8d,%r12d
+	pinsrw	$7,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movdqu	(%r13),%xmm2
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r10d,%r12d
+	addl	60(%r15),%r9d
+	addb	%dl,%bl
+	movl	64(%rsi),%eax
+	addl	$1236535329,%r9d
+	xorl	%r8d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,60(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$22,%r9d
+	movl	%r10d,%r12d
+	pinsrw	$7,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	psllq	$8,%xmm1
+	pxor	%xmm0,%xmm2
+	pxor	%xmm1,%xmm2
+	pxor	%xmm0,%xmm0
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r11d,%r12d
+	addl	4(%r15),%r8d
+	addb	%dl,%al
+	movl	68(%rsi),%ebx
+	addl	$4129170786,%r8d
+	xorl	%r10d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,64(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$5,%r8d
+	movl	%r9d,%r12d
+	movd	(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	pxor	%xmm1,%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r10d,%r12d
+	addl	24(%r15),%r11d
+	addb	%dl,%bl
+	movl	72(%rsi),%eax
+	addl	$3225465664,%r11d
+	xorl	%r9d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,68(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$9,%r11d
+	movl	%r8d,%r12d
+	movd	(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r9d,%r12d
+	addl	44(%r15),%r10d
+	addb	%dl,%al
+	movl	76(%rsi),%ebx
+	addl	$643717713,%r10d
+	xorl	%r8d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,72(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$14,%r10d
+	movl	%r11d,%r12d
+	pinsrw	$1,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r8d,%r12d
+	addl	0(%r15),%r9d
+	addb	%dl,%bl
+	movl	80(%rsi),%eax
+	addl	$3921069994,%r9d
+	xorl	%r11d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,76(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$20,%r9d
+	movl	%r10d,%r12d
+	pinsrw	$1,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r11d,%r12d
+	addl	20(%r15),%r8d
+	addb	%dl,%al
+	movl	84(%rsi),%ebx
+	addl	$3593408605,%r8d
+	xorl	%r10d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,80(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$5,%r8d
+	movl	%r9d,%r12d
+	pinsrw	$2,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r10d,%r12d
+	addl	40(%r15),%r11d
+	addb	%dl,%bl
+	movl	88(%rsi),%eax
+	addl	$38016083,%r11d
+	xorl	%r9d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,84(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$9,%r11d
+	movl	%r8d,%r12d
+	pinsrw	$2,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r9d,%r12d
+	addl	60(%r15),%r10d
+	addb	%dl,%al
+	movl	92(%rsi),%ebx
+	addl	$3634488961,%r10d
+	xorl	%r8d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,88(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$14,%r10d
+	movl	%r11d,%r12d
+	pinsrw	$3,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r8d,%r12d
+	addl	16(%r15),%r9d
+	addb	%dl,%bl
+	movl	96(%rsi),%eax
+	addl	$3889429448,%r9d
+	xorl	%r11d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,92(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$20,%r9d
+	movl	%r10d,%r12d
+	pinsrw	$3,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r11d,%r12d
+	addl	36(%r15),%r8d
+	addb	%dl,%al
+	movl	100(%rsi),%ebx
+	addl	$568446438,%r8d
+	xorl	%r10d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,96(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$5,%r8d
+	movl	%r9d,%r12d
+	pinsrw	$4,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r10d,%r12d
+	addl	56(%r15),%r11d
+	addb	%dl,%bl
+	movl	104(%rsi),%eax
+	addl	$3275163606,%r11d
+	xorl	%r9d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,100(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$9,%r11d
+	movl	%r8d,%r12d
+	pinsrw	$4,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r9d,%r12d
+	addl	12(%r15),%r10d
+	addb	%dl,%al
+	movl	108(%rsi),%ebx
+	addl	$4107603335,%r10d
+	xorl	%r8d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,104(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$14,%r10d
+	movl	%r11d,%r12d
+	pinsrw	$5,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r8d,%r12d
+	addl	32(%r15),%r9d
+	addb	%dl,%bl
+	movl	112(%rsi),%eax
+	addl	$1163531501,%r9d
+	xorl	%r11d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,108(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$20,%r9d
+	movl	%r10d,%r12d
+	pinsrw	$5,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r11d,%r12d
+	addl	52(%r15),%r8d
+	addb	%dl,%al
+	movl	116(%rsi),%ebx
+	addl	$2850285829,%r8d
+	xorl	%r10d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,112(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$5,%r8d
+	movl	%r9d,%r12d
+	pinsrw	$6,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r10d,%r12d
+	addl	8(%r15),%r11d
+	addb	%dl,%bl
+	movl	120(%rsi),%eax
+	addl	$4243563512,%r11d
+	xorl	%r9d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,116(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$9,%r11d
+	movl	%r8d,%r12d
+	pinsrw	$6,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r9d,%r12d
+	addl	28(%r15),%r10d
+	addb	%dl,%al
+	movl	124(%rsi),%ebx
+	addl	$1735328473,%r10d
+	xorl	%r8d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,120(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$14,%r10d
+	movl	%r11d,%r12d
+	pinsrw	$7,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movdqu	16(%r13),%xmm3
+	addb	$32,%bpl
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r8d,%r12d
+	addl	48(%r15),%r9d
+	addb	%dl,%bl
+	movl	0(%rdi,%rbp,4),%eax
+	addl	$2368359562,%r9d
+	xorl	%r11d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,124(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$20,%r9d
+	movl	%r11d,%r12d
+	pinsrw	$7,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movq	%rcx,%rsi
+	xorq	%rcx,%rcx
+	movb	%sil,%cl
+	leaq	(%rdi,%rbp,4),%rsi
+	psllq	$8,%xmm1
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
+	pxor	%xmm0,%xmm0
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	xorl	%r9d,%r12d
+	addl	20(%r15),%r8d
+	addb	%dl,%al
+	movl	4(%rsi),%ebx
+	addl	$4294588738,%r8d
+	movzbl	%al,%eax
+	addl	%r12d,%r8d
+	movl	%edx,0(%rsi)
+	addb	%bl,%cl
+	roll	$4,%r8d
+	movl	%r10d,%r12d
+	movd	(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	pxor	%xmm1,%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	xorl	%r8d,%r12d
+	addl	32(%r15),%r11d
+	addb	%dl,%bl
+	movl	8(%rsi),%eax
+	addl	$2272392833,%r11d
+	movzbl	%bl,%ebx
+	addl	%r12d,%r11d
+	movl	%edx,4(%rsi)
+	addb	%al,%cl
+	roll	$11,%r11d
+	movl	%r9d,%r12d
+	movd	(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	xorl	%r11d,%r12d
+	addl	44(%r15),%r10d
+	addb	%dl,%al
+	movl	12(%rsi),%ebx
+	addl	$1839030562,%r10d
+	movzbl	%al,%eax
+	addl	%r12d,%r10d
+	movl	%edx,8(%rsi)
+	addb	%bl,%cl
+	roll	$16,%r10d
+	movl	%r8d,%r12d
+	pinsrw	$1,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	xorl	%r10d,%r12d
+	addl	56(%r15),%r9d
+	addb	%dl,%bl
+	movl	16(%rsi),%eax
+	addl	$4259657740,%r9d
+	movzbl	%bl,%ebx
+	addl	%r12d,%r9d
+	movl	%edx,12(%rsi)
+	addb	%al,%cl
+	roll	$23,%r9d
+	movl	%r11d,%r12d
+	pinsrw	$1,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	xorl	%r9d,%r12d
+	addl	4(%r15),%r8d
+	addb	%dl,%al
+	movl	20(%rsi),%ebx
+	addl	$2763975236,%r8d
+	movzbl	%al,%eax
+	addl	%r12d,%r8d
+	movl	%edx,16(%rsi)
+	addb	%bl,%cl
+	roll	$4,%r8d
+	movl	%r10d,%r12d
+	pinsrw	$2,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	xorl	%r8d,%r12d
+	addl	16(%r15),%r11d
+	addb	%dl,%bl
+	movl	24(%rsi),%eax
+	addl	$1272893353,%r11d
+	movzbl	%bl,%ebx
+	addl	%r12d,%r11d
+	movl	%edx,20(%rsi)
+	addb	%al,%cl
+	roll	$11,%r11d
+	movl	%r9d,%r12d
+	pinsrw	$2,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	xorl	%r11d,%r12d
+	addl	28(%r15),%r10d
+	addb	%dl,%al
+	movl	28(%rsi),%ebx
+	addl	$4139469664,%r10d
+	movzbl	%al,%eax
+	addl	%r12d,%r10d
+	movl	%edx,24(%rsi)
+	addb	%bl,%cl
+	roll	$16,%r10d
+	movl	%r8d,%r12d
+	pinsrw	$3,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	xorl	%r10d,%r12d
+	addl	40(%r15),%r9d
+	addb	%dl,%bl
+	movl	32(%rsi),%eax
+	addl	$3200236656,%r9d
+	movzbl	%bl,%ebx
+	addl	%r12d,%r9d
+	movl	%edx,28(%rsi)
+	addb	%al,%cl
+	roll	$23,%r9d
+	movl	%r11d,%r12d
+	pinsrw	$3,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	xorl	%r9d,%r12d
+	addl	52(%r15),%r8d
+	addb	%dl,%al
+	movl	36(%rsi),%ebx
+	addl	$681279174,%r8d
+	movzbl	%al,%eax
+	addl	%r12d,%r8d
+	movl	%edx,32(%rsi)
+	addb	%bl,%cl
+	roll	$4,%r8d
+	movl	%r10d,%r12d
+	pinsrw	$4,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	xorl	%r8d,%r12d
+	addl	0(%r15),%r11d
+	addb	%dl,%bl
+	movl	40(%rsi),%eax
+	addl	$3936430074,%r11d
+	movzbl	%bl,%ebx
+	addl	%r12d,%r11d
+	movl	%edx,36(%rsi)
+	addb	%al,%cl
+	roll	$11,%r11d
+	movl	%r9d,%r12d
+	pinsrw	$4,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	xorl	%r11d,%r12d
+	addl	12(%r15),%r10d
+	addb	%dl,%al
+	movl	44(%rsi),%ebx
+	addl	$3572445317,%r10d
+	movzbl	%al,%eax
+	addl	%r12d,%r10d
+	movl	%edx,40(%rsi)
+	addb	%bl,%cl
+	roll	$16,%r10d
+	movl	%r8d,%r12d
+	pinsrw	$5,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	xorl	%r10d,%r12d
+	addl	24(%r15),%r9d
+	addb	%dl,%bl
+	movl	48(%rsi),%eax
+	addl	$76029189,%r9d
+	movzbl	%bl,%ebx
+	addl	%r12d,%r9d
+	movl	%edx,44(%rsi)
+	addb	%al,%cl
+	roll	$23,%r9d
+	movl	%r11d,%r12d
+	pinsrw	$5,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	xorl	%r9d,%r12d
+	addl	36(%r15),%r8d
+	addb	%dl,%al
+	movl	52(%rsi),%ebx
+	addl	$3654602809,%r8d
+	movzbl	%al,%eax
+	addl	%r12d,%r8d
+	movl	%edx,48(%rsi)
+	addb	%bl,%cl
+	roll	$4,%r8d
+	movl	%r10d,%r12d
+	pinsrw	$6,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	xorl	%r8d,%r12d
+	addl	48(%r15),%r11d
+	addb	%dl,%bl
+	movl	56(%rsi),%eax
+	addl	$3873151461,%r11d
+	movzbl	%bl,%ebx
+	addl	%r12d,%r11d
+	movl	%edx,52(%rsi)
+	addb	%al,%cl
+	roll	$11,%r11d
+	movl	%r9d,%r12d
+	pinsrw	$6,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	xorl	%r11d,%r12d
+	addl	60(%r15),%r10d
+	addb	%dl,%al
+	movl	60(%rsi),%ebx
+	addl	$530742520,%r10d
+	movzbl	%al,%eax
+	addl	%r12d,%r10d
+	movl	%edx,56(%rsi)
+	addb	%bl,%cl
+	roll	$16,%r10d
+	movl	%r8d,%r12d
+	pinsrw	$7,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movdqu	32(%r13),%xmm4
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	xorl	%r10d,%r12d
+	addl	8(%r15),%r9d
+	addb	%dl,%bl
+	movl	64(%rsi),%eax
+	addl	$3299628645,%r9d
+	movzbl	%bl,%ebx
+	addl	%r12d,%r9d
+	movl	%edx,60(%rsi)
+	addb	%al,%cl
+	roll	$23,%r9d
+	movl	$-1,%r12d
+	pinsrw	$7,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	psllq	$8,%xmm1
+	pxor	%xmm0,%xmm4
+	pxor	%xmm1,%xmm4
+	pxor	%xmm0,%xmm0
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	orl	%r9d,%r12d
+	addl	0(%r15),%r8d
+	addb	%dl,%al
+	movl	68(%rsi),%ebx
+	addl	$4096336452,%r8d
+	movzbl	%al,%eax
+	xorl	%r10d,%r12d
+	movl	%edx,64(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$6,%r8d
+	movl	$-1,%r12d
+	movd	(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	pxor	%xmm1,%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	orl	%r8d,%r12d
+	addl	28(%r15),%r11d
+	addb	%dl,%bl
+	movl	72(%rsi),%eax
+	addl	$1126891415,%r11d
+	movzbl	%bl,%ebx
+	xorl	%r9d,%r12d
+	movl	%edx,68(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$10,%r11d
+	movl	$-1,%r12d
+	movd	(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	orl	%r11d,%r12d
+	addl	56(%r15),%r10d
+	addb	%dl,%al
+	movl	76(%rsi),%ebx
+	addl	$2878612391,%r10d
+	movzbl	%al,%eax
+	xorl	%r8d,%r12d
+	movl	%edx,72(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$15,%r10d
+	movl	$-1,%r12d
+	pinsrw	$1,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	orl	%r10d,%r12d
+	addl	20(%r15),%r9d
+	addb	%dl,%bl
+	movl	80(%rsi),%eax
+	addl	$4237533241,%r9d
+	movzbl	%bl,%ebx
+	xorl	%r11d,%r12d
+	movl	%edx,76(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$21,%r9d
+	movl	$-1,%r12d
+	pinsrw	$1,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	orl	%r9d,%r12d
+	addl	48(%r15),%r8d
+	addb	%dl,%al
+	movl	84(%rsi),%ebx
+	addl	$1700485571,%r8d
+	movzbl	%al,%eax
+	xorl	%r10d,%r12d
+	movl	%edx,80(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$6,%r8d
+	movl	$-1,%r12d
+	pinsrw	$2,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	orl	%r8d,%r12d
+	addl	12(%r15),%r11d
+	addb	%dl,%bl
+	movl	88(%rsi),%eax
+	addl	$2399980690,%r11d
+	movzbl	%bl,%ebx
+	xorl	%r9d,%r12d
+	movl	%edx,84(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$10,%r11d
+	movl	$-1,%r12d
+	pinsrw	$2,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	orl	%r11d,%r12d
+	addl	40(%r15),%r10d
+	addb	%dl,%al
+	movl	92(%rsi),%ebx
+	addl	$4293915773,%r10d
+	movzbl	%al,%eax
+	xorl	%r8d,%r12d
+	movl	%edx,88(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$15,%r10d
+	movl	$-1,%r12d
+	pinsrw	$3,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	orl	%r10d,%r12d
+	addl	4(%r15),%r9d
+	addb	%dl,%bl
+	movl	96(%rsi),%eax
+	addl	$2240044497,%r9d
+	movzbl	%bl,%ebx
+	xorl	%r11d,%r12d
+	movl	%edx,92(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$21,%r9d
+	movl	$-1,%r12d
+	pinsrw	$3,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	orl	%r9d,%r12d
+	addl	32(%r15),%r8d
+	addb	%dl,%al
+	movl	100(%rsi),%ebx
+	addl	$1873313359,%r8d
+	movzbl	%al,%eax
+	xorl	%r10d,%r12d
+	movl	%edx,96(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$6,%r8d
+	movl	$-1,%r12d
+	pinsrw	$4,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	orl	%r8d,%r12d
+	addl	60(%r15),%r11d
+	addb	%dl,%bl
+	movl	104(%rsi),%eax
+	addl	$4264355552,%r11d
+	movzbl	%bl,%ebx
+	xorl	%r9d,%r12d
+	movl	%edx,100(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$10,%r11d
+	movl	$-1,%r12d
+	pinsrw	$4,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	orl	%r11d,%r12d
+	addl	24(%r15),%r10d
+	addb	%dl,%al
+	movl	108(%rsi),%ebx
+	addl	$2734768916,%r10d
+	movzbl	%al,%eax
+	xorl	%r8d,%r12d
+	movl	%edx,104(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$15,%r10d
+	movl	$-1,%r12d
+	pinsrw	$5,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	orl	%r10d,%r12d
+	addl	52(%r15),%r9d
+	addb	%dl,%bl
+	movl	112(%rsi),%eax
+	addl	$1309151649,%r9d
+	movzbl	%bl,%ebx
+	xorl	%r11d,%r12d
+	movl	%edx,108(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$21,%r9d
+	movl	$-1,%r12d
+	pinsrw	$5,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	orl	%r9d,%r12d
+	addl	16(%r15),%r8d
+	addb	%dl,%al
+	movl	116(%rsi),%ebx
+	addl	$4149444226,%r8d
+	movzbl	%al,%eax
+	xorl	%r10d,%r12d
+	movl	%edx,112(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$6,%r8d
+	movl	$-1,%r12d
+	pinsrw	$6,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	orl	%r8d,%r12d
+	addl	44(%r15),%r11d
+	addb	%dl,%bl
+	movl	120(%rsi),%eax
+	addl	$3174756917,%r11d
+	movzbl	%bl,%ebx
+	xorl	%r9d,%r12d
+	movl	%edx,116(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$10,%r11d
+	movl	$-1,%r12d
+	pinsrw	$6,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	orl	%r11d,%r12d
+	addl	8(%r15),%r10d
+	addb	%dl,%al
+	movl	124(%rsi),%ebx
+	addl	$718787259,%r10d
+	movzbl	%al,%eax
+	xorl	%r8d,%r12d
+	movl	%edx,120(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$15,%r10d
+	movl	$-1,%r12d
+	pinsrw	$7,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movdqu	48(%r13),%xmm5
+	addb	$32,%bpl
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	orl	%r10d,%r12d
+	addl	36(%r15),%r9d
+	addb	%dl,%bl
+	movl	0(%rdi,%rbp,4),%eax
+	addl	$3951481745,%r9d
+	movzbl	%bl,%ebx
+	xorl	%r11d,%r12d
+	movl	%edx,124(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$21,%r9d
+	movl	$-1,%r12d
+	pinsrw	$7,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movq	%rbp,%rsi
+	xorq	%rbp,%rbp
+	movb	%sil,%bpl
+	movq	%rcx,%rsi
+	xorq	%rcx,%rcx
+	movb	%sil,%cl
+	leaq	(%rdi,%rbp,4),%rsi
+	psllq	$8,%xmm1
+	pxor	%xmm0,%xmm5
+	pxor	%xmm1,%xmm5
+	addl	0(%rsp),%r8d
+	addl	4(%rsp),%r9d
+	addl	8(%rsp),%r10d
+	addl	12(%rsp),%r11d
+
+	movdqu	%xmm2,(%r14,%r13,1)
+	movdqu	%xmm3,16(%r14,%r13,1)
+	movdqu	%xmm4,32(%r14,%r13,1)
+	movdqu	%xmm5,48(%r14,%r13,1)
+	leaq	64(%r15),%r15
+	leaq	64(%r13),%r13
+	cmpq	16(%rsp),%r15
+	jb	.Loop
+
+	movq	24(%rsp),%r12
+	subb	%al,%cl
+	movl	%r8d,0(%r12)
+	movl	%r9d,4(%r12)
+	movl	%r10d,8(%r12)
+	movl	%r11d,12(%r12)
+	subb	$1,%bpl
+	movl	%ebp,-8(%rdi)
+	movl	%ecx,-4(%rdi)
+
+	movq	40(%rsp),%r15
+	movq	48(%rsp),%r14
+	movq	56(%rsp),%r13
+	movq	64(%rsp),%r12
+	movq	72(%rsp),%rbp
+	movq	80(%rsp),%rbx
+	leaq	88(%rsp),%rsp
+.Lepilogue:
+.Labort:
+	.byte	0xf3,0xc3
+.size	rc4_md5_enc,.-rc4_md5_enc
+#if defined(HAVE_GNU_STACK)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/crypto/libressl/crypto/rc4/rc4-md5-macosx-x86_64.s b/crypto/libressl/crypto/rc4/rc4-md5-macosx-x86_64.s
new file mode 100644
index 0000000000..47dce361a6
--- /dev/null
+++ b/crypto/libressl/crypto/rc4/rc4-md5-macosx-x86_64.s
@@ -0,0 +1,1259 @@
+.text	
+.p2align	4
+
+.globl	_rc4_md5_enc
+
+_rc4_md5_enc:
+	cmpq	$0,%r9
+	je	L$abort
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	subq	$40,%rsp
+L$body:
+	movq	%rcx,%r11
+	movq	%r9,%r12
+	movq	%rsi,%r13
+	movq	%rdx,%r14
+	movq	%r8,%r15
+	xorq	%rbp,%rbp
+	xorq	%rcx,%rcx
+
+	leaq	8(%rdi),%rdi
+	movb	-8(%rdi),%bpl
+	movb	-4(%rdi),%cl
+
+	incb	%bpl
+	subq	%r13,%r14
+	movl	(%rdi,%rbp,4),%eax
+	addb	%al,%cl
+	leaq	(%rdi,%rbp,4),%rsi
+	shlq	$6,%r12
+	addq	%r15,%r12
+	movq	%r12,16(%rsp)
+
+	movq	%r11,24(%rsp)
+	movl	0(%r11),%r8d
+	movl	4(%r11),%r9d
+	movl	8(%r11),%r10d
+	movl	12(%r11),%r11d
+	jmp	L$oop
+
+.p2align	4
+L$oop:
+	movl	%r8d,0(%rsp)
+	movl	%r9d,4(%rsp)
+	movl	%r10d,8(%rsp)
+	movl	%r11d,%r12d
+	movl	%r11d,12(%rsp)
+	pxor	%xmm0,%xmm0
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r9d,%r12d
+	addl	0(%r15),%r8d
+	addb	%dl,%al
+	movl	4(%rsi),%ebx
+	addl	$3614090360,%r8d
+	xorl	%r11d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,0(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$7,%r8d
+	movl	%r10d,%r12d
+	movd	(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	pxor	%xmm1,%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r8d,%r12d
+	addl	4(%r15),%r11d
+	addb	%dl,%bl
+	movl	8(%rsi),%eax
+	addl	$3905402710,%r11d
+	xorl	%r10d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,4(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$12,%r11d
+	movl	%r9d,%r12d
+	movd	(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r11d,%r12d
+	addl	8(%r15),%r10d
+	addb	%dl,%al
+	movl	12(%rsi),%ebx
+	addl	$606105819,%r10d
+	xorl	%r9d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,8(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$17,%r10d
+	movl	%r8d,%r12d
+	pinsrw	$1,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r10d,%r12d
+	addl	12(%r15),%r9d
+	addb	%dl,%bl
+	movl	16(%rsi),%eax
+	addl	$3250441966,%r9d
+	xorl	%r8d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,12(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$22,%r9d
+	movl	%r11d,%r12d
+	pinsrw	$1,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r9d,%r12d
+	addl	16(%r15),%r8d
+	addb	%dl,%al
+	movl	20(%rsi),%ebx
+	addl	$4118548399,%r8d
+	xorl	%r11d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,16(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$7,%r8d
+	movl	%r10d,%r12d
+	pinsrw	$2,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r8d,%r12d
+	addl	20(%r15),%r11d
+	addb	%dl,%bl
+	movl	24(%rsi),%eax
+	addl	$1200080426,%r11d
+	xorl	%r10d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,20(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$12,%r11d
+	movl	%r9d,%r12d
+	pinsrw	$2,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r11d,%r12d
+	addl	24(%r15),%r10d
+	addb	%dl,%al
+	movl	28(%rsi),%ebx
+	addl	$2821735955,%r10d
+	xorl	%r9d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,24(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$17,%r10d
+	movl	%r8d,%r12d
+	pinsrw	$3,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r10d,%r12d
+	addl	28(%r15),%r9d
+	addb	%dl,%bl
+	movl	32(%rsi),%eax
+	addl	$4249261313,%r9d
+	xorl	%r8d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,28(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$22,%r9d
+	movl	%r11d,%r12d
+	pinsrw	$3,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r9d,%r12d
+	addl	32(%r15),%r8d
+	addb	%dl,%al
+	movl	36(%rsi),%ebx
+	addl	$1770035416,%r8d
+	xorl	%r11d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,32(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$7,%r8d
+	movl	%r10d,%r12d
+	pinsrw	$4,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r8d,%r12d
+	addl	36(%r15),%r11d
+	addb	%dl,%bl
+	movl	40(%rsi),%eax
+	addl	$2336552879,%r11d
+	xorl	%r10d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,36(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$12,%r11d
+	movl	%r9d,%r12d
+	pinsrw	$4,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r11d,%r12d
+	addl	40(%r15),%r10d
+	addb	%dl,%al
+	movl	44(%rsi),%ebx
+	addl	$4294925233,%r10d
+	xorl	%r9d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,40(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$17,%r10d
+	movl	%r8d,%r12d
+	pinsrw	$5,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r10d,%r12d
+	addl	44(%r15),%r9d
+	addb	%dl,%bl
+	movl	48(%rsi),%eax
+	addl	$2304563134,%r9d
+	xorl	%r8d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,44(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$22,%r9d
+	movl	%r11d,%r12d
+	pinsrw	$5,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r9d,%r12d
+	addl	48(%r15),%r8d
+	addb	%dl,%al
+	movl	52(%rsi),%ebx
+	addl	$1804603682,%r8d
+	xorl	%r11d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,48(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$7,%r8d
+	movl	%r10d,%r12d
+	pinsrw	$6,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r8d,%r12d
+	addl	52(%r15),%r11d
+	addb	%dl,%bl
+	movl	56(%rsi),%eax
+	addl	$4254626195,%r11d
+	xorl	%r10d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,52(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$12,%r11d
+	movl	%r9d,%r12d
+	pinsrw	$6,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r11d,%r12d
+	addl	56(%r15),%r10d
+	addb	%dl,%al
+	movl	60(%rsi),%ebx
+	addl	$2792965006,%r10d
+	xorl	%r9d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,56(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$17,%r10d
+	movl	%r8d,%r12d
+	pinsrw	$7,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movdqu	(%r13),%xmm2
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r10d,%r12d
+	addl	60(%r15),%r9d
+	addb	%dl,%bl
+	movl	64(%rsi),%eax
+	addl	$1236535329,%r9d
+	xorl	%r8d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,60(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$22,%r9d
+	movl	%r10d,%r12d
+	pinsrw	$7,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	psllq	$8,%xmm1
+	pxor	%xmm0,%xmm2
+	pxor	%xmm1,%xmm2
+	pxor	%xmm0,%xmm0
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r11d,%r12d
+	addl	4(%r15),%r8d
+	addb	%dl,%al
+	movl	68(%rsi),%ebx
+	addl	$4129170786,%r8d
+	xorl	%r10d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,64(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$5,%r8d
+	movl	%r9d,%r12d
+	movd	(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	pxor	%xmm1,%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r10d,%r12d
+	addl	24(%r15),%r11d
+	addb	%dl,%bl
+	movl	72(%rsi),%eax
+	addl	$3225465664,%r11d
+	xorl	%r9d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,68(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$9,%r11d
+	movl	%r8d,%r12d
+	movd	(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r9d,%r12d
+	addl	44(%r15),%r10d
+	addb	%dl,%al
+	movl	76(%rsi),%ebx
+	addl	$643717713,%r10d
+	xorl	%r8d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,72(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$14,%r10d
+	movl	%r11d,%r12d
+	pinsrw	$1,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r8d,%r12d
+	addl	0(%r15),%r9d
+	addb	%dl,%bl
+	movl	80(%rsi),%eax
+	addl	$3921069994,%r9d
+	xorl	%r11d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,76(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$20,%r9d
+	movl	%r10d,%r12d
+	pinsrw	$1,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r11d,%r12d
+	addl	20(%r15),%r8d
+	addb	%dl,%al
+	movl	84(%rsi),%ebx
+	addl	$3593408605,%r8d
+	xorl	%r10d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,80(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$5,%r8d
+	movl	%r9d,%r12d
+	pinsrw	$2,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r10d,%r12d
+	addl	40(%r15),%r11d
+	addb	%dl,%bl
+	movl	88(%rsi),%eax
+	addl	$38016083,%r11d
+	xorl	%r9d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,84(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$9,%r11d
+	movl	%r8d,%r12d
+	pinsrw	$2,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r9d,%r12d
+	addl	60(%r15),%r10d
+	addb	%dl,%al
+	movl	92(%rsi),%ebx
+	addl	$3634488961,%r10d
+	xorl	%r8d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,88(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$14,%r10d
+	movl	%r11d,%r12d
+	pinsrw	$3,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r8d,%r12d
+	addl	16(%r15),%r9d
+	addb	%dl,%bl
+	movl	96(%rsi),%eax
+	addl	$3889429448,%r9d
+	xorl	%r11d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,92(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$20,%r9d
+	movl	%r10d,%r12d
+	pinsrw	$3,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r11d,%r12d
+	addl	36(%r15),%r8d
+	addb	%dl,%al
+	movl	100(%rsi),%ebx
+	addl	$568446438,%r8d
+	xorl	%r10d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,96(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$5,%r8d
+	movl	%r9d,%r12d
+	pinsrw	$4,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r10d,%r12d
+	addl	56(%r15),%r11d
+	addb	%dl,%bl
+	movl	104(%rsi),%eax
+	addl	$3275163606,%r11d
+	xorl	%r9d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,100(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$9,%r11d
+	movl	%r8d,%r12d
+	pinsrw	$4,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r9d,%r12d
+	addl	12(%r15),%r10d
+	addb	%dl,%al
+	movl	108(%rsi),%ebx
+	addl	$4107603335,%r10d
+	xorl	%r8d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,104(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$14,%r10d
+	movl	%r11d,%r12d
+	pinsrw	$5,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r8d,%r12d
+	addl	32(%r15),%r9d
+	addb	%dl,%bl
+	movl	112(%rsi),%eax
+	addl	$1163531501,%r9d
+	xorl	%r11d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,108(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$20,%r9d
+	movl	%r10d,%r12d
+	pinsrw	$5,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r11d,%r12d
+	addl	52(%r15),%r8d
+	addb	%dl,%al
+	movl	116(%rsi),%ebx
+	addl	$2850285829,%r8d
+	xorl	%r10d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,112(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$5,%r8d
+	movl	%r9d,%r12d
+	pinsrw	$6,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r10d,%r12d
+	addl	8(%r15),%r11d
+	addb	%dl,%bl
+	movl	120(%rsi),%eax
+	addl	$4243563512,%r11d
+	xorl	%r9d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,116(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$9,%r11d
+	movl	%r8d,%r12d
+	pinsrw	$6,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	andl	%r9d,%r12d
+	addl	28(%r15),%r10d
+	addb	%dl,%al
+	movl	124(%rsi),%ebx
+	addl	$1735328473,%r10d
+	xorl	%r8d,%r12d
+	movzbl	%al,%eax
+	movl	%edx,120(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$14,%r10d
+	movl	%r11d,%r12d
+	pinsrw	$7,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movdqu	16(%r13),%xmm3
+	addb	$32,%bpl
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	andl	%r8d,%r12d
+	addl	48(%r15),%r9d
+	addb	%dl,%bl
+	movl	0(%rdi,%rbp,4),%eax
+	addl	$2368359562,%r9d
+	xorl	%r11d,%r12d
+	movzbl	%bl,%ebx
+	movl	%edx,124(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$20,%r9d
+	movl	%r11d,%r12d
+	pinsrw	$7,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movq	%rcx,%rsi
+	xorq	%rcx,%rcx
+	movb	%sil,%cl
+	leaq	(%rdi,%rbp,4),%rsi
+	psllq	$8,%xmm1
+	pxor	%xmm0,%xmm3
+	pxor	%xmm1,%xmm3
+	pxor	%xmm0,%xmm0
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	xorl	%r9d,%r12d
+	addl	20(%r15),%r8d
+	addb	%dl,%al
+	movl	4(%rsi),%ebx
+	addl	$4294588738,%r8d
+	movzbl	%al,%eax
+	addl	%r12d,%r8d
+	movl	%edx,0(%rsi)
+	addb	%bl,%cl
+	roll	$4,%r8d
+	movl	%r10d,%r12d
+	movd	(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	pxor	%xmm1,%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	xorl	%r8d,%r12d
+	addl	32(%r15),%r11d
+	addb	%dl,%bl
+	movl	8(%rsi),%eax
+	addl	$2272392833,%r11d
+	movzbl	%bl,%ebx
+	addl	%r12d,%r11d
+	movl	%edx,4(%rsi)
+	addb	%al,%cl
+	roll	$11,%r11d
+	movl	%r9d,%r12d
+	movd	(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	xorl	%r11d,%r12d
+	addl	44(%r15),%r10d
+	addb	%dl,%al
+	movl	12(%rsi),%ebx
+	addl	$1839030562,%r10d
+	movzbl	%al,%eax
+	addl	%r12d,%r10d
+	movl	%edx,8(%rsi)
+	addb	%bl,%cl
+	roll	$16,%r10d
+	movl	%r8d,%r12d
+	pinsrw	$1,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	xorl	%r10d,%r12d
+	addl	56(%r15),%r9d
+	addb	%dl,%bl
+	movl	16(%rsi),%eax
+	addl	$4259657740,%r9d
+	movzbl	%bl,%ebx
+	addl	%r12d,%r9d
+	movl	%edx,12(%rsi)
+	addb	%al,%cl
+	roll	$23,%r9d
+	movl	%r11d,%r12d
+	pinsrw	$1,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	xorl	%r9d,%r12d
+	addl	4(%r15),%r8d
+	addb	%dl,%al
+	movl	20(%rsi),%ebx
+	addl	$2763975236,%r8d
+	movzbl	%al,%eax
+	addl	%r12d,%r8d
+	movl	%edx,16(%rsi)
+	addb	%bl,%cl
+	roll	$4,%r8d
+	movl	%r10d,%r12d
+	pinsrw	$2,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	xorl	%r8d,%r12d
+	addl	16(%r15),%r11d
+	addb	%dl,%bl
+	movl	24(%rsi),%eax
+	addl	$1272893353,%r11d
+	movzbl	%bl,%ebx
+	addl	%r12d,%r11d
+	movl	%edx,20(%rsi)
+	addb	%al,%cl
+	roll	$11,%r11d
+	movl	%r9d,%r12d
+	pinsrw	$2,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	xorl	%r11d,%r12d
+	addl	28(%r15),%r10d
+	addb	%dl,%al
+	movl	28(%rsi),%ebx
+	addl	$4139469664,%r10d
+	movzbl	%al,%eax
+	addl	%r12d,%r10d
+	movl	%edx,24(%rsi)
+	addb	%bl,%cl
+	roll	$16,%r10d
+	movl	%r8d,%r12d
+	pinsrw	$3,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	xorl	%r10d,%r12d
+	addl	40(%r15),%r9d
+	addb	%dl,%bl
+	movl	32(%rsi),%eax
+	addl	$3200236656,%r9d
+	movzbl	%bl,%ebx
+	addl	%r12d,%r9d
+	movl	%edx,28(%rsi)
+	addb	%al,%cl
+	roll	$23,%r9d
+	movl	%r11d,%r12d
+	pinsrw	$3,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	xorl	%r9d,%r12d
+	addl	52(%r15),%r8d
+	addb	%dl,%al
+	movl	36(%rsi),%ebx
+	addl	$681279174,%r8d
+	movzbl	%al,%eax
+	addl	%r12d,%r8d
+	movl	%edx,32(%rsi)
+	addb	%bl,%cl
+	roll	$4,%r8d
+	movl	%r10d,%r12d
+	pinsrw	$4,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	xorl	%r8d,%r12d
+	addl	0(%r15),%r11d
+	addb	%dl,%bl
+	movl	40(%rsi),%eax
+	addl	$3936430074,%r11d
+	movzbl	%bl,%ebx
+	addl	%r12d,%r11d
+	movl	%edx,36(%rsi)
+	addb	%al,%cl
+	roll	$11,%r11d
+	movl	%r9d,%r12d
+	pinsrw	$4,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	xorl	%r11d,%r12d
+	addl	12(%r15),%r10d
+	addb	%dl,%al
+	movl	44(%rsi),%ebx
+	addl	$3572445317,%r10d
+	movzbl	%al,%eax
+	addl	%r12d,%r10d
+	movl	%edx,40(%rsi)
+	addb	%bl,%cl
+	roll	$16,%r10d
+	movl	%r8d,%r12d
+	pinsrw	$5,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	xorl	%r10d,%r12d
+	addl	24(%r15),%r9d
+	addb	%dl,%bl
+	movl	48(%rsi),%eax
+	addl	$76029189,%r9d
+	movzbl	%bl,%ebx
+	addl	%r12d,%r9d
+	movl	%edx,44(%rsi)
+	addb	%al,%cl
+	roll	$23,%r9d
+	movl	%r11d,%r12d
+	pinsrw	$5,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	xorl	%r9d,%r12d
+	addl	36(%r15),%r8d
+	addb	%dl,%al
+	movl	52(%rsi),%ebx
+	addl	$3654602809,%r8d
+	movzbl	%al,%eax
+	addl	%r12d,%r8d
+	movl	%edx,48(%rsi)
+	addb	%bl,%cl
+	roll	$4,%r8d
+	movl	%r10d,%r12d
+	pinsrw	$6,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	xorl	%r8d,%r12d
+	addl	48(%r15),%r11d
+	addb	%dl,%bl
+	movl	56(%rsi),%eax
+	addl	$3873151461,%r11d
+	movzbl	%bl,%ebx
+	addl	%r12d,%r11d
+	movl	%edx,52(%rsi)
+	addb	%al,%cl
+	roll	$11,%r11d
+	movl	%r9d,%r12d
+	pinsrw	$6,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	xorl	%r11d,%r12d
+	addl	60(%r15),%r10d
+	addb	%dl,%al
+	movl	60(%rsi),%ebx
+	addl	$530742520,%r10d
+	movzbl	%al,%eax
+	addl	%r12d,%r10d
+	movl	%edx,56(%rsi)
+	addb	%bl,%cl
+	roll	$16,%r10d
+	movl	%r8d,%r12d
+	pinsrw	$7,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movdqu	32(%r13),%xmm4
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	xorl	%r10d,%r12d
+	addl	8(%r15),%r9d
+	addb	%dl,%bl
+	movl	64(%rsi),%eax
+	addl	$3299628645,%r9d
+	movzbl	%bl,%ebx
+	addl	%r12d,%r9d
+	movl	%edx,60(%rsi)
+	addb	%al,%cl
+	roll	$23,%r9d
+	movl	$-1,%r12d
+	pinsrw	$7,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	psllq	$8,%xmm1
+	pxor	%xmm0,%xmm4
+	pxor	%xmm1,%xmm4
+	pxor	%xmm0,%xmm0
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	orl	%r9d,%r12d
+	addl	0(%r15),%r8d
+	addb	%dl,%al
+	movl	68(%rsi),%ebx
+	addl	$4096336452,%r8d
+	movzbl	%al,%eax
+	xorl	%r10d,%r12d
+	movl	%edx,64(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$6,%r8d
+	movl	$-1,%r12d
+	movd	(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	pxor	%xmm1,%xmm1
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	orl	%r8d,%r12d
+	addl	28(%r15),%r11d
+	addb	%dl,%bl
+	movl	72(%rsi),%eax
+	addl	$1126891415,%r11d
+	movzbl	%bl,%ebx
+	xorl	%r9d,%r12d
+	movl	%edx,68(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$10,%r11d
+	movl	$-1,%r12d
+	movd	(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	orl	%r11d,%r12d
+	addl	56(%r15),%r10d
+	addb	%dl,%al
+	movl	76(%rsi),%ebx
+	addl	$2878612391,%r10d
+	movzbl	%al,%eax
+	xorl	%r8d,%r12d
+	movl	%edx,72(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$15,%r10d
+	movl	$-1,%r12d
+	pinsrw	$1,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	orl	%r10d,%r12d
+	addl	20(%r15),%r9d
+	addb	%dl,%bl
+	movl	80(%rsi),%eax
+	addl	$4237533241,%r9d
+	movzbl	%bl,%ebx
+	xorl	%r11d,%r12d
+	movl	%edx,76(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$21,%r9d
+	movl	$-1,%r12d
+	pinsrw	$1,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	orl	%r9d,%r12d
+	addl	48(%r15),%r8d
+	addb	%dl,%al
+	movl	84(%rsi),%ebx
+	addl	$1700485571,%r8d
+	movzbl	%al,%eax
+	xorl	%r10d,%r12d
+	movl	%edx,80(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$6,%r8d
+	movl	$-1,%r12d
+	pinsrw	$2,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	orl	%r8d,%r12d
+	addl	12(%r15),%r11d
+	addb	%dl,%bl
+	movl	88(%rsi),%eax
+	addl	$2399980690,%r11d
+	movzbl	%bl,%ebx
+	xorl	%r9d,%r12d
+	movl	%edx,84(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$10,%r11d
+	movl	$-1,%r12d
+	pinsrw	$2,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	orl	%r11d,%r12d
+	addl	40(%r15),%r10d
+	addb	%dl,%al
+	movl	92(%rsi),%ebx
+	addl	$4293915773,%r10d
+	movzbl	%al,%eax
+	xorl	%r8d,%r12d
+	movl	%edx,88(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$15,%r10d
+	movl	$-1,%r12d
+	pinsrw	$3,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	orl	%r10d,%r12d
+	addl	4(%r15),%r9d
+	addb	%dl,%bl
+	movl	96(%rsi),%eax
+	addl	$2240044497,%r9d
+	movzbl	%bl,%ebx
+	xorl	%r11d,%r12d
+	movl	%edx,92(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$21,%r9d
+	movl	$-1,%r12d
+	pinsrw	$3,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	orl	%r9d,%r12d
+	addl	32(%r15),%r8d
+	addb	%dl,%al
+	movl	100(%rsi),%ebx
+	addl	$1873313359,%r8d
+	movzbl	%al,%eax
+	xorl	%r10d,%r12d
+	movl	%edx,96(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$6,%r8d
+	movl	$-1,%r12d
+	pinsrw	$4,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	orl	%r8d,%r12d
+	addl	60(%r15),%r11d
+	addb	%dl,%bl
+	movl	104(%rsi),%eax
+	addl	$4264355552,%r11d
+	movzbl	%bl,%ebx
+	xorl	%r9d,%r12d
+	movl	%edx,100(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$10,%r11d
+	movl	$-1,%r12d
+	pinsrw	$4,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	orl	%r11d,%r12d
+	addl	24(%r15),%r10d
+	addb	%dl,%al
+	movl	108(%rsi),%ebx
+	addl	$2734768916,%r10d
+	movzbl	%al,%eax
+	xorl	%r8d,%r12d
+	movl	%edx,104(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$15,%r10d
+	movl	$-1,%r12d
+	pinsrw	$5,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	orl	%r10d,%r12d
+	addl	52(%r15),%r9d
+	addb	%dl,%bl
+	movl	112(%rsi),%eax
+	addl	$1309151649,%r9d
+	movzbl	%bl,%ebx
+	xorl	%r11d,%r12d
+	movl	%edx,108(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$21,%r9d
+	movl	$-1,%r12d
+	pinsrw	$5,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r11d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	orl	%r9d,%r12d
+	addl	16(%r15),%r8d
+	addb	%dl,%al
+	movl	116(%rsi),%ebx
+	addl	$4149444226,%r8d
+	movzbl	%al,%eax
+	xorl	%r10d,%r12d
+	movl	%edx,112(%rsi)
+	addl	%r12d,%r8d
+	addb	%bl,%cl
+	roll	$6,%r8d
+	movl	$-1,%r12d
+	pinsrw	$6,(%rdi,%rax,4),%xmm0
+
+	addl	%r9d,%r8d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r10d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	orl	%r8d,%r12d
+	addl	44(%r15),%r11d
+	addb	%dl,%bl
+	movl	120(%rsi),%eax
+	addl	$3174756917,%r11d
+	movzbl	%bl,%ebx
+	xorl	%r9d,%r12d
+	movl	%edx,116(%rsi)
+	addl	%r12d,%r11d
+	addb	%al,%cl
+	roll	$10,%r11d
+	movl	$-1,%r12d
+	pinsrw	$6,(%rdi,%rbx,4),%xmm1
+
+	addl	%r8d,%r11d
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r9d,%r12d
+	movl	%eax,(%rdi,%rcx,4)
+	orl	%r11d,%r12d
+	addl	8(%r15),%r10d
+	addb	%dl,%al
+	movl	124(%rsi),%ebx
+	addl	$718787259,%r10d
+	movzbl	%al,%eax
+	xorl	%r8d,%r12d
+	movl	%edx,120(%rsi)
+	addl	%r12d,%r10d
+	addb	%bl,%cl
+	roll	$15,%r10d
+	movl	$-1,%r12d
+	pinsrw	$7,(%rdi,%rax,4),%xmm0
+
+	addl	%r11d,%r10d
+	movdqu	48(%r13),%xmm5
+	addb	$32,%bpl
+	movl	(%rdi,%rcx,4),%edx
+	xorl	%r8d,%r12d
+	movl	%ebx,(%rdi,%rcx,4)
+	orl	%r10d,%r12d
+	addl	36(%r15),%r9d
+	addb	%dl,%bl
+	movl	0(%rdi,%rbp,4),%eax
+	addl	$3951481745,%r9d
+	movzbl	%bl,%ebx
+	xorl	%r11d,%r12d
+	movl	%edx,124(%rsi)
+	addl	%r12d,%r9d
+	addb	%al,%cl
+	roll	$21,%r9d
+	movl	$-1,%r12d
+	pinsrw	$7,(%rdi,%rbx,4),%xmm1
+
+	addl	%r10d,%r9d
+	movq	%rbp,%rsi
+	xorq	%rbp,%rbp
+	movb	%sil,%bpl
+	movq	%rcx,%rsi
+	xorq	%rcx,%rcx
+	movb	%sil,%cl
+	leaq	(%rdi,%rbp,4),%rsi
+	psllq	$8,%xmm1
+	pxor	%xmm0,%xmm5
+	pxor	%xmm1,%xmm5
+	addl	0(%rsp),%r8d
+	addl	4(%rsp),%r9d
+	addl	8(%rsp),%r10d
+	addl	12(%rsp),%r11d
+
+	movdqu	%xmm2,(%r14,%r13,1)
+	movdqu	%xmm3,16(%r14,%r13,1)
+	movdqu	%xmm4,32(%r14,%r13,1)
+	movdqu	%xmm5,48(%r14,%r13,1)
+	leaq	64(%r15),%r15
+	leaq	64(%r13),%r13
+	cmpq	16(%rsp),%r15
+	jb	L$oop
+
+	movq	24(%rsp),%r12
+	subb	%al,%cl
+	movl	%r8d,0(%r12)
+	movl	%r9d,4(%r12)
+	movl	%r10d,8(%r12)
+	movl	%r11d,12(%r12)
+	subb	$1,%bpl
+	movl	%ebp,-8(%rdi)
+	movl	%ecx,-4(%rdi)
+
+	movq	40(%rsp),%r15
+	movq	48(%rsp),%r14
+	movq	56(%rsp),%r13
+	movq	64(%rsp),%r12
+	movq	72(%rsp),%rbp
+	movq	80(%rsp),%rbx
+	leaq	88(%rsp),%rsp
+L$epilogue:
+L$abort:
+	.byte	0xf3,0xc3
+
diff --git a/crypto/libressl/crypto/rc4/rc4_enc.c b/crypto/libressl/crypto/rc4/rc4_enc.c
new file mode 100644
index 0000000000..514956feb0
--- /dev/null
+++ b/crypto/libressl/crypto/rc4/rc4_enc.c
@@ -0,0 +1,253 @@
+/* $OpenBSD: rc4_enc.c,v 1.14 2015/10/20 15:50:13 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include "rc4_locl.h"
+
+/* RC4 as implemented from a posting from
+ * Newsgroups: sci.crypt
+ * From: sterndark@netcom.com (David Sterndark)
+ * Subject: RC4 Algorithm revealed.
+ * Message-ID: 
+ * Date: Wed, 14 Sep 1994 06:35:31 GMT
+ */
+
+void
+RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
+    unsigned char *outdata)
+{
+	RC4_INT *d;
+	RC4_INT x, y,tx, ty;
+	size_t i;
+
+	x = key->x;
+	y = key->y;
+	d = key->data;
+
+#if defined(RC4_CHUNK)
+	/*
+	 * The original reason for implementing this(*) was the fact that
+	 * pre-21164a Alpha CPUs don't have byte load/store instructions
+	 * and e.g. a byte store has to be done with 64-bit load, shift,
+	 * and, or and finally 64-bit store. Peaking data and operating
+	 * at natural word size made it possible to reduce amount of
+	 * instructions as well as to perform early read-ahead without
+	 * suffering from RAW (read-after-write) hazard. This resulted
+	 * in ~40%(**) performance improvement on 21064 box with gcc.
+	 * But it's not only Alpha users who win here:-) Thanks to the
+	 * early-n-wide read-ahead this implementation also exhibits
+	 * >40% speed-up on SPARC and 20-30% on 64-bit MIPS (depending
+	 * on sizeof(RC4_INT)).
+	 *
+	 * (*)	"this" means code which recognizes the case when input
+	 *	and output pointers appear to be aligned at natural CPU
+	 *	word boundary
+	 * (**)	i.e. according to 'apps/openssl speed rc4' benchmark,
+	 *	crypto/rc4/rc4speed.c exhibits almost 70% speed-up...
+	 *
+	 * Caveats.
+	 *
+	 * - RC4_CHUNK="unsigned long long" should be a #1 choice for
+	 *   UltraSPARC. Unfortunately gcc generates very slow code
+	 *   (2.5-3 times slower than one generated by Sun's WorkShop
+	 *   C) and therefore gcc (at least 2.95 and earlier) should
+	 *   always be told that RC4_CHUNK="unsigned long".
+	 *
+	 *					
+	 */
+
+# define RC4_STEP	( \
+			x=(x+1) &0xff,	\
+			tx=d[x],	\
+			y=(tx+y)&0xff,	\
+			ty=d[y],	\
+			d[y]=tx,	\
+			d[x]=ty,	\
+			(RC4_CHUNK)d[(tx+ty)&0xff]\
+			)
+
+	if ((((size_t)indata & (sizeof(RC4_CHUNK) - 1)) |
+	    ((size_t)outdata & (sizeof(RC4_CHUNK) - 1))) == 0 ) {
+		RC4_CHUNK ichunk, otp;
+
+		/*
+		 * I reckon we can afford to implement both endian
+		 * cases and to decide which way to take at run-time
+		 * because the machine code appears to be very compact
+		 * and redundant 1-2KB is perfectly tolerable (i.e.
+		 * in case the compiler fails to eliminate it:-). By
+		 * suggestion from Terrel Larson .
+		 *
+		 * Special notes.
+		 *
+		 * - compilers (those I've tried) don't seem to have
+		 *   problems eliminating either the operators guarded
+		 *   by "if (sizeof(RC4_CHUNK)==8)" or the condition
+		 *   expressions themselves so I've got 'em to replace
+		 *   corresponding #ifdefs from the previous version;
+		 * - I chose to let the redundant switch cases when
+		 *   sizeof(RC4_CHUNK)!=8 be (were also #ifdefed
+		 *   before);
+		 * - in case you wonder "&(sizeof(RC4_CHUNK)*8-1)" in
+		 *   [LB]ESHFT guards against "shift is out of range"
+		 *   warnings when sizeof(RC4_CHUNK)!=8
+		 *
+		 *			
+		 */
+		if (BYTE_ORDER != LITTLE_ENDIAN) {	/* BIG-ENDIAN CASE */
+# define BESHFT(c)	(((sizeof(RC4_CHUNK)-(c)-1)*8)&(sizeof(RC4_CHUNK)*8-1))
+			for (; len & (0 - sizeof(RC4_CHUNK)); len -= sizeof(RC4_CHUNK)) {
+				ichunk  = *(RC4_CHUNK *)indata;
+				otp = RC4_STEP << BESHFT(0);
+				otp |= RC4_STEP << BESHFT(1);
+				otp |= RC4_STEP << BESHFT(2);
+				otp |= RC4_STEP << BESHFT(3);
+				if (sizeof(RC4_CHUNK) == 8) {
+					otp |= RC4_STEP << BESHFT(4);
+					otp |= RC4_STEP << BESHFT(5);
+					otp |= RC4_STEP << BESHFT(6);
+					otp |= RC4_STEP << BESHFT(7);
+				}
+				*(RC4_CHUNK *)outdata = otp^ichunk;
+				indata += sizeof(RC4_CHUNK);
+				outdata += sizeof(RC4_CHUNK);
+			}
+		} else {	/* LITTLE-ENDIAN CASE */
+# define LESHFT(c)	(((c)*8)&(sizeof(RC4_CHUNK)*8-1))
+			for (; len & (0 - sizeof(RC4_CHUNK)); len -= sizeof(RC4_CHUNK)) {
+				ichunk = *(RC4_CHUNK *)indata;
+				otp = RC4_STEP;
+				otp |= RC4_STEP << 8;
+				otp |= RC4_STEP << 16;
+				otp |= RC4_STEP << 24;
+				if (sizeof(RC4_CHUNK) == 8) {
+					otp |= RC4_STEP << LESHFT(4);
+					otp |= RC4_STEP << LESHFT(5);
+					otp |= RC4_STEP << LESHFT(6);
+					otp |= RC4_STEP << LESHFT(7);
+				}
+				*(RC4_CHUNK *)outdata = otp ^ ichunk;
+				indata += sizeof(RC4_CHUNK);
+				outdata += sizeof(RC4_CHUNK);
+			}
+		}
+	}
+#endif
+#define LOOP(in,out) \
+		x=((x+1)&0xff); \
+		tx=d[x]; \
+		y=(tx+y)&0xff; \
+		d[x]=ty=d[y]; \
+		d[y]=tx; \
+		(out) = d[(tx+ty)&0xff]^ (in);
+
+#ifndef RC4_INDEX
+#define RC4_LOOP(a,b,i)	LOOP(*((a)++),*((b)++))
+#else
+#define RC4_LOOP(a,b,i)	LOOP(a[i],b[i])
+#endif
+
+	i = len >> 3;
+	if (i) {
+		for (;;) {
+			RC4_LOOP(indata, outdata, 0);
+			RC4_LOOP(indata, outdata, 1);
+			RC4_LOOP(indata, outdata, 2);
+			RC4_LOOP(indata, outdata, 3);
+			RC4_LOOP(indata, outdata, 4);
+			RC4_LOOP(indata, outdata, 5);
+			RC4_LOOP(indata, outdata, 6);
+			RC4_LOOP(indata, outdata, 7);
+#ifdef RC4_INDEX
+			indata += 8;
+			outdata += 8;
+#endif
+			if (--i == 0)
+				break;
+		}
+	}
+	i = len&0x07;
+	if (i) {
+		for (;;) {
+			RC4_LOOP(indata, outdata, 0);
+			if (--i == 0)
+				break;
+			RC4_LOOP(indata, outdata, 1);
+			if (--i == 0)
+				break;
+			RC4_LOOP(indata, outdata, 2);
+			if (--i == 0)
+				break;
+			RC4_LOOP(indata, outdata, 3);
+			if (--i == 0)
+				break;
+			RC4_LOOP(indata, outdata, 4);
+			if (--i == 0)
+				break;
+			RC4_LOOP(indata, outdata, 5);
+			if (--i == 0)
+				break;
+			RC4_LOOP(indata, outdata, 6);
+			if (--i == 0)
+				break;
+		}
+	}
+	key->x = x;
+	key->y = y;
+}
diff --git a/crypto/libressl/crypto/rc4/rc4_locl.h b/crypto/libressl/crypto/rc4/rc4_locl.h
new file mode 100644
index 0000000000..9717f69853
--- /dev/null
+++ b/crypto/libressl/crypto/rc4/rc4_locl.h
@@ -0,0 +1,5 @@
+/* $OpenBSD: rc4_locl.h,v 1.3 2014/06/12 15:49:30 deraadt Exp $ */
+
+#ifndef HEADER_RC4_LOCL_H
+#define HEADER_RC4_LOCL_H
+#endif
diff --git a/crypto/libressl/crypto/rc4/rc4_skey.c b/crypto/libressl/crypto/rc4/rc4_skey.c
new file mode 100644
index 0000000000..035ab60198
--- /dev/null
+++ b/crypto/libressl/crypto/rc4/rc4_skey.c
@@ -0,0 +1,115 @@
+/* $OpenBSD: rc4_skey.c,v 1.13 2014/10/28 07:35:59 jsg Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include "rc4_locl.h"
+#include 
+
+const char *
+RC4_options(void)
+{
+#ifdef RC4_INDEX
+	if (sizeof(RC4_INT) == 1)
+		return("rc4(idx,char)");
+	else
+		return("rc4(idx,int)");
+#else
+	if (sizeof(RC4_INT) == 1)
+		return("rc4(ptr,char)");
+	else
+		return("rc4(ptr,int)");
+#endif
+}
+
+/* RC4 as implemented from a posting from
+ * Newsgroups: sci.crypt
+ * From: sterndark@netcom.com (David Sterndark)
+ * Subject: RC4 Algorithm revealed.
+ * Message-ID: 
+ * Date: Wed, 14 Sep 1994 06:35:31 GMT
+ */
+
+void
+RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
+{
+	RC4_INT tmp;
+	int id1, id2;
+	RC4_INT *d;
+	unsigned int i;
+
+	d = &(key->data[0]);
+	key->x = 0;
+	key->y = 0;
+	id1 = id2 = 0;
+
+#define SK_LOOP(d,n) { \
+		tmp=d[(n)]; \
+		id2 = (data[id1] + tmp + id2) & 0xff; \
+		if (++id1 == len) id1=0; \
+		d[(n)]=d[id2]; \
+		d[id2]=tmp; }
+
+	for (i = 0; i < 256; i++)
+		d[i] = i;
+	for (i = 0; i < 256; i += 4) {
+		SK_LOOP(d, i + 0);
+		SK_LOOP(d, i + 1);
+		SK_LOOP(d, i + 2);
+		SK_LOOP(d, i + 3);
+	}
+}
diff --git a/crypto/libressl/crypto/ripemd/rmd_dgst.c b/crypto/libressl/crypto/ripemd/rmd_dgst.c
new file mode 100644
index 0000000000..ced7610168
--- /dev/null
+++ b/crypto/libressl/crypto/ripemd/rmd_dgst.c
@@ -0,0 +1,290 @@
+/* $OpenBSD: rmd_dgst.c,v 1.16 2014/08/18 19:11:48 bcook Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include "rmd_locl.h"
+#include 
+#include 
+
+#  ifdef RMD160_ASM
+     void ripemd160_block_x86(RIPEMD160_CTX *c, unsigned long *p,size_t num);
+#    define ripemd160_block ripemd160_block_x86
+#  else
+     void ripemd160_block(RIPEMD160_CTX *c, unsigned long *p,size_t num);
+#  endif
+
+int RIPEMD160_Init(RIPEMD160_CTX *c)
+	{
+	memset (c,0,sizeof(*c));
+	c->A=RIPEMD160_A;
+	c->B=RIPEMD160_B;
+	c->C=RIPEMD160_C;
+	c->D=RIPEMD160_D;
+	c->E=RIPEMD160_E;
+	return 1;
+	}
+
+#ifndef ripemd160_block_data_order
+#ifdef X
+#undef X
+#endif
+void ripemd160_block_data_order (RIPEMD160_CTX *ctx, const void *p, size_t num)
+	{
+	const unsigned char *data=p;
+	unsigned MD32_REG_T A,B,C,D,E;
+	unsigned MD32_REG_T a,b,c,d,e,l;
+#ifndef MD32_XARRAY
+	/* See comment in crypto/sha/sha_locl.h for details. */
+	unsigned MD32_REG_T	XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+				XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
+# define X(i)	XX##i
+#else
+	RIPEMD160_LONG	XX[16];
+# define X(i)	XX[i]
+#endif
+
+	for (;num--;)
+		{
+
+	A=ctx->A; B=ctx->B; C=ctx->C; D=ctx->D; E=ctx->E;
+
+	HOST_c2l(data,l); X( 0)=l;HOST_c2l(data,l); X( 1)=l;
+	RIP1(A,B,C,D,E,WL00,SL00);	HOST_c2l(data,l); X( 2)=l;
+	RIP1(E,A,B,C,D,WL01,SL01);	HOST_c2l(data,l); X( 3)=l;
+	RIP1(D,E,A,B,C,WL02,SL02);	HOST_c2l(data,l); X( 4)=l;
+	RIP1(C,D,E,A,B,WL03,SL03);	HOST_c2l(data,l); X( 5)=l;
+	RIP1(B,C,D,E,A,WL04,SL04);	HOST_c2l(data,l); X( 6)=l;
+	RIP1(A,B,C,D,E,WL05,SL05);	HOST_c2l(data,l); X( 7)=l;
+	RIP1(E,A,B,C,D,WL06,SL06);	HOST_c2l(data,l); X( 8)=l;
+	RIP1(D,E,A,B,C,WL07,SL07);	HOST_c2l(data,l); X( 9)=l;
+	RIP1(C,D,E,A,B,WL08,SL08);	HOST_c2l(data,l); X(10)=l;
+	RIP1(B,C,D,E,A,WL09,SL09);	HOST_c2l(data,l); X(11)=l;
+	RIP1(A,B,C,D,E,WL10,SL10);	HOST_c2l(data,l); X(12)=l;
+	RIP1(E,A,B,C,D,WL11,SL11);	HOST_c2l(data,l); X(13)=l;
+	RIP1(D,E,A,B,C,WL12,SL12);	HOST_c2l(data,l); X(14)=l;
+	RIP1(C,D,E,A,B,WL13,SL13);	HOST_c2l(data,l); X(15)=l;
+	RIP1(B,C,D,E,A,WL14,SL14);
+	RIP1(A,B,C,D,E,WL15,SL15);
+
+	RIP2(E,A,B,C,D,WL16,SL16,KL1);
+	RIP2(D,E,A,B,C,WL17,SL17,KL1);
+	RIP2(C,D,E,A,B,WL18,SL18,KL1);
+	RIP2(B,C,D,E,A,WL19,SL19,KL1);
+	RIP2(A,B,C,D,E,WL20,SL20,KL1);
+	RIP2(E,A,B,C,D,WL21,SL21,KL1);
+	RIP2(D,E,A,B,C,WL22,SL22,KL1);
+	RIP2(C,D,E,A,B,WL23,SL23,KL1);
+	RIP2(B,C,D,E,A,WL24,SL24,KL1);
+	RIP2(A,B,C,D,E,WL25,SL25,KL1);
+	RIP2(E,A,B,C,D,WL26,SL26,KL1);
+	RIP2(D,E,A,B,C,WL27,SL27,KL1);
+	RIP2(C,D,E,A,B,WL28,SL28,KL1);
+	RIP2(B,C,D,E,A,WL29,SL29,KL1);
+	RIP2(A,B,C,D,E,WL30,SL30,KL1);
+	RIP2(E,A,B,C,D,WL31,SL31,KL1);
+
+	RIP3(D,E,A,B,C,WL32,SL32,KL2);
+	RIP3(C,D,E,A,B,WL33,SL33,KL2);
+	RIP3(B,C,D,E,A,WL34,SL34,KL2);
+	RIP3(A,B,C,D,E,WL35,SL35,KL2);
+	RIP3(E,A,B,C,D,WL36,SL36,KL2);
+	RIP3(D,E,A,B,C,WL37,SL37,KL2);
+	RIP3(C,D,E,A,B,WL38,SL38,KL2);
+	RIP3(B,C,D,E,A,WL39,SL39,KL2);
+	RIP3(A,B,C,D,E,WL40,SL40,KL2);
+	RIP3(E,A,B,C,D,WL41,SL41,KL2);
+	RIP3(D,E,A,B,C,WL42,SL42,KL2);
+	RIP3(C,D,E,A,B,WL43,SL43,KL2);
+	RIP3(B,C,D,E,A,WL44,SL44,KL2);
+	RIP3(A,B,C,D,E,WL45,SL45,KL2);
+	RIP3(E,A,B,C,D,WL46,SL46,KL2);
+	RIP3(D,E,A,B,C,WL47,SL47,KL2);
+
+	RIP4(C,D,E,A,B,WL48,SL48,KL3);
+	RIP4(B,C,D,E,A,WL49,SL49,KL3);
+	RIP4(A,B,C,D,E,WL50,SL50,KL3);
+	RIP4(E,A,B,C,D,WL51,SL51,KL3);
+	RIP4(D,E,A,B,C,WL52,SL52,KL3);
+	RIP4(C,D,E,A,B,WL53,SL53,KL3);
+	RIP4(B,C,D,E,A,WL54,SL54,KL3);
+	RIP4(A,B,C,D,E,WL55,SL55,KL3);
+	RIP4(E,A,B,C,D,WL56,SL56,KL3);
+	RIP4(D,E,A,B,C,WL57,SL57,KL3);
+	RIP4(C,D,E,A,B,WL58,SL58,KL3);
+	RIP4(B,C,D,E,A,WL59,SL59,KL3);
+	RIP4(A,B,C,D,E,WL60,SL60,KL3);
+	RIP4(E,A,B,C,D,WL61,SL61,KL3);
+	RIP4(D,E,A,B,C,WL62,SL62,KL3);
+	RIP4(C,D,E,A,B,WL63,SL63,KL3);
+
+	RIP5(B,C,D,E,A,WL64,SL64,KL4);
+	RIP5(A,B,C,D,E,WL65,SL65,KL4);
+	RIP5(E,A,B,C,D,WL66,SL66,KL4);
+	RIP5(D,E,A,B,C,WL67,SL67,KL4);
+	RIP5(C,D,E,A,B,WL68,SL68,KL4);
+	RIP5(B,C,D,E,A,WL69,SL69,KL4);
+	RIP5(A,B,C,D,E,WL70,SL70,KL4);
+	RIP5(E,A,B,C,D,WL71,SL71,KL4);
+	RIP5(D,E,A,B,C,WL72,SL72,KL4);
+	RIP5(C,D,E,A,B,WL73,SL73,KL4);
+	RIP5(B,C,D,E,A,WL74,SL74,KL4);
+	RIP5(A,B,C,D,E,WL75,SL75,KL4);
+	RIP5(E,A,B,C,D,WL76,SL76,KL4);
+	RIP5(D,E,A,B,C,WL77,SL77,KL4);
+	RIP5(C,D,E,A,B,WL78,SL78,KL4);
+	RIP5(B,C,D,E,A,WL79,SL79,KL4);
+
+	a=A; b=B; c=C; d=D; e=E;
+	/* Do other half */
+	A=ctx->A; B=ctx->B; C=ctx->C; D=ctx->D; E=ctx->E;
+
+	RIP5(A,B,C,D,E,WR00,SR00,KR0);
+	RIP5(E,A,B,C,D,WR01,SR01,KR0);
+	RIP5(D,E,A,B,C,WR02,SR02,KR0);
+	RIP5(C,D,E,A,B,WR03,SR03,KR0);
+	RIP5(B,C,D,E,A,WR04,SR04,KR0);
+	RIP5(A,B,C,D,E,WR05,SR05,KR0);
+	RIP5(E,A,B,C,D,WR06,SR06,KR0);
+	RIP5(D,E,A,B,C,WR07,SR07,KR0);
+	RIP5(C,D,E,A,B,WR08,SR08,KR0);
+	RIP5(B,C,D,E,A,WR09,SR09,KR0);
+	RIP5(A,B,C,D,E,WR10,SR10,KR0);
+	RIP5(E,A,B,C,D,WR11,SR11,KR0);
+	RIP5(D,E,A,B,C,WR12,SR12,KR0);
+	RIP5(C,D,E,A,B,WR13,SR13,KR0);
+	RIP5(B,C,D,E,A,WR14,SR14,KR0);
+	RIP5(A,B,C,D,E,WR15,SR15,KR0);
+
+	RIP4(E,A,B,C,D,WR16,SR16,KR1);
+	RIP4(D,E,A,B,C,WR17,SR17,KR1);
+	RIP4(C,D,E,A,B,WR18,SR18,KR1);
+	RIP4(B,C,D,E,A,WR19,SR19,KR1);
+	RIP4(A,B,C,D,E,WR20,SR20,KR1);
+	RIP4(E,A,B,C,D,WR21,SR21,KR1);
+	RIP4(D,E,A,B,C,WR22,SR22,KR1);
+	RIP4(C,D,E,A,B,WR23,SR23,KR1);
+	RIP4(B,C,D,E,A,WR24,SR24,KR1);
+	RIP4(A,B,C,D,E,WR25,SR25,KR1);
+	RIP4(E,A,B,C,D,WR26,SR26,KR1);
+	RIP4(D,E,A,B,C,WR27,SR27,KR1);
+	RIP4(C,D,E,A,B,WR28,SR28,KR1);
+	RIP4(B,C,D,E,A,WR29,SR29,KR1);
+	RIP4(A,B,C,D,E,WR30,SR30,KR1);
+	RIP4(E,A,B,C,D,WR31,SR31,KR1);
+
+	RIP3(D,E,A,B,C,WR32,SR32,KR2);
+	RIP3(C,D,E,A,B,WR33,SR33,KR2);
+	RIP3(B,C,D,E,A,WR34,SR34,KR2);
+	RIP3(A,B,C,D,E,WR35,SR35,KR2);
+	RIP3(E,A,B,C,D,WR36,SR36,KR2);
+	RIP3(D,E,A,B,C,WR37,SR37,KR2);
+	RIP3(C,D,E,A,B,WR38,SR38,KR2);
+	RIP3(B,C,D,E,A,WR39,SR39,KR2);
+	RIP3(A,B,C,D,E,WR40,SR40,KR2);
+	RIP3(E,A,B,C,D,WR41,SR41,KR2);
+	RIP3(D,E,A,B,C,WR42,SR42,KR2);
+	RIP3(C,D,E,A,B,WR43,SR43,KR2);
+	RIP3(B,C,D,E,A,WR44,SR44,KR2);
+	RIP3(A,B,C,D,E,WR45,SR45,KR2);
+	RIP3(E,A,B,C,D,WR46,SR46,KR2);
+	RIP3(D,E,A,B,C,WR47,SR47,KR2);
+
+	RIP2(C,D,E,A,B,WR48,SR48,KR3);
+	RIP2(B,C,D,E,A,WR49,SR49,KR3);
+	RIP2(A,B,C,D,E,WR50,SR50,KR3);
+	RIP2(E,A,B,C,D,WR51,SR51,KR3);
+	RIP2(D,E,A,B,C,WR52,SR52,KR3);
+	RIP2(C,D,E,A,B,WR53,SR53,KR3);
+	RIP2(B,C,D,E,A,WR54,SR54,KR3);
+	RIP2(A,B,C,D,E,WR55,SR55,KR3);
+	RIP2(E,A,B,C,D,WR56,SR56,KR3);
+	RIP2(D,E,A,B,C,WR57,SR57,KR3);
+	RIP2(C,D,E,A,B,WR58,SR58,KR3);
+	RIP2(B,C,D,E,A,WR59,SR59,KR3);
+	RIP2(A,B,C,D,E,WR60,SR60,KR3);
+	RIP2(E,A,B,C,D,WR61,SR61,KR3);
+	RIP2(D,E,A,B,C,WR62,SR62,KR3);
+	RIP2(C,D,E,A,B,WR63,SR63,KR3);
+
+	RIP1(B,C,D,E,A,WR64,SR64);
+	RIP1(A,B,C,D,E,WR65,SR65);
+	RIP1(E,A,B,C,D,WR66,SR66);
+	RIP1(D,E,A,B,C,WR67,SR67);
+	RIP1(C,D,E,A,B,WR68,SR68);
+	RIP1(B,C,D,E,A,WR69,SR69);
+	RIP1(A,B,C,D,E,WR70,SR70);
+	RIP1(E,A,B,C,D,WR71,SR71);
+	RIP1(D,E,A,B,C,WR72,SR72);
+	RIP1(C,D,E,A,B,WR73,SR73);
+	RIP1(B,C,D,E,A,WR74,SR74);
+	RIP1(A,B,C,D,E,WR75,SR75);
+	RIP1(E,A,B,C,D,WR76,SR76);
+	RIP1(D,E,A,B,C,WR77,SR77);
+	RIP1(C,D,E,A,B,WR78,SR78);
+	RIP1(B,C,D,E,A,WR79,SR79);
+
+	D     =ctx->B+c+D;
+	ctx->B=ctx->C+d+E;
+	ctx->C=ctx->D+e+A;
+	ctx->D=ctx->E+a+B;
+	ctx->E=ctx->A+b+C;
+	ctx->A=D;
+
+		}
+	}
+#endif
diff --git a/crypto/libressl/crypto/ripemd/rmd_locl.h b/crypto/libressl/crypto/ripemd/rmd_locl.h
new file mode 100644
index 0000000000..a2efdd4425
--- /dev/null
+++ b/crypto/libressl/crypto/ripemd/rmd_locl.h
@@ -0,0 +1,146 @@
+/* $OpenBSD: rmd_locl.h,v 1.11 2014/08/18 19:11:48 bcook Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * DO EXAMINE COMMENTS IN crypto/md5/md5_locl.h & crypto/md5/md5_dgst.c
+ * FOR EXPLANATIONS ON FOLLOWING "CODE."
+ *					
+ */
+#ifdef RMD160_ASM
+# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__)
+#  define ripemd160_block_data_order ripemd160_block_asm_data_order
+# endif
+#endif
+
+void ripemd160_block_data_order (RIPEMD160_CTX *c, const void *p,size_t num);
+
+#define DATA_ORDER_IS_LITTLE_ENDIAN
+
+#define HASH_LONG               RIPEMD160_LONG
+#define HASH_CTX                RIPEMD160_CTX
+#define HASH_CBLOCK             RIPEMD160_CBLOCK
+#define HASH_UPDATE             RIPEMD160_Update
+#define HASH_TRANSFORM          RIPEMD160_Transform
+#define HASH_FINAL              RIPEMD160_Final
+#define	HASH_MAKE_STRING(c,s)	do {	\
+	unsigned long ll;		\
+	ll=(c)->A; HOST_l2c(ll,(s));	\
+	ll=(c)->B; HOST_l2c(ll,(s));	\
+	ll=(c)->C; HOST_l2c(ll,(s));	\
+	ll=(c)->D; HOST_l2c(ll,(s));	\
+	ll=(c)->E; HOST_l2c(ll,(s));	\
+	} while (0)
+#define HASH_BLOCK_DATA_ORDER   ripemd160_block_data_order
+
+#include "md32_common.h"
+
+#if 0
+#define F1(x,y,z)	 ((x)^(y)^(z))
+#define F2(x,y,z)	(((x)&(y))|((~x)&z))
+#define F3(x,y,z)	(((x)|(~y))^(z))
+#define F4(x,y,z)	(((x)&(z))|((y)&(~(z))))
+#define F5(x,y,z)	 ((x)^((y)|(~(z))))
+#else
+/*
+ * Transformed F2 and F4 are courtesy of Wei Dai 
+ */
+#define F1(x,y,z)	((x) ^ (y) ^ (z))
+#define F2(x,y,z)	((((y) ^ (z)) & (x)) ^ (z))
+#define F3(x,y,z)	(((~(y)) | (x)) ^ (z))
+#define F4(x,y,z)	((((x) ^ (y)) & (z)) ^ (y))
+#define F5(x,y,z)	(((~(z)) | (y)) ^ (x))
+#endif
+
+#define RIPEMD160_A	0x67452301L
+#define RIPEMD160_B	0xEFCDAB89L
+#define RIPEMD160_C	0x98BADCFEL
+#define RIPEMD160_D	0x10325476L
+#define RIPEMD160_E	0xC3D2E1F0L
+
+#include "rmdconst.h"
+
+#define RIP1(a,b,c,d,e,w,s) { \
+	a+=F1(b,c,d)+X(w); \
+        a=ROTATE(a,s)+e; \
+        c=ROTATE(c,10); }
+
+#define RIP2(a,b,c,d,e,w,s,K) { \
+	a+=F2(b,c,d)+X(w)+K; \
+        a=ROTATE(a,s)+e; \
+        c=ROTATE(c,10); }
+
+#define RIP3(a,b,c,d,e,w,s,K) { \
+	a+=F3(b,c,d)+X(w)+K; \
+        a=ROTATE(a,s)+e; \
+        c=ROTATE(c,10); }
+
+#define RIP4(a,b,c,d,e,w,s,K) { \
+	a+=F4(b,c,d)+X(w)+K; \
+        a=ROTATE(a,s)+e; \
+        c=ROTATE(c,10); }
+
+#define RIP5(a,b,c,d,e,w,s,K) { \
+	a+=F5(b,c,d)+X(w)+K; \
+        a=ROTATE(a,s)+e; \
+        c=ROTATE(c,10); }
+
diff --git a/crypto/libressl/crypto/ripemd/rmd_one.c b/crypto/libressl/crypto/ripemd/rmd_one.c
new file mode 100644
index 0000000000..6a5077ea7b
--- /dev/null
+++ b/crypto/libressl/crypto/ripemd/rmd_one.c
@@ -0,0 +1,78 @@
+/* $OpenBSD: rmd_one.c,v 1.8 2015/09/10 15:03:59 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+unsigned char *RIPEMD160(const unsigned char *d, size_t n,
+	     unsigned char *md)
+	{
+	RIPEMD160_CTX c;
+	static unsigned char m[RIPEMD160_DIGEST_LENGTH];
+
+	if (md == NULL) md=m;
+	if (!RIPEMD160_Init(&c))
+		return NULL;
+	RIPEMD160_Update(&c,d,n);
+	RIPEMD160_Final(md,&c);
+	explicit_bzero(&c,sizeof(c));
+	return(md);
+	}
+
diff --git a/crypto/libressl/crypto/ripemd/rmdconst.h b/crypto/libressl/crypto/ripemd/rmdconst.h
new file mode 100644
index 0000000000..c8957c5dee
--- /dev/null
+++ b/crypto/libressl/crypto/ripemd/rmdconst.h
@@ -0,0 +1,399 @@
+/* $OpenBSD$ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+#define KL0 0x00000000L
+#define KL1 0x5A827999L
+#define KL2 0x6ED9EBA1L
+#define KL3 0x8F1BBCDCL
+#define KL4 0xA953FD4EL
+
+#define KR0 0x50A28BE6L
+#define KR1 0x5C4DD124L
+#define KR2 0x6D703EF3L
+#define KR3 0x7A6D76E9L
+#define KR4 0x00000000L
+
+#define WL00  0
+#define SL00 11
+#define WL01  1
+#define SL01 14
+#define WL02  2
+#define SL02 15
+#define WL03  3
+#define SL03 12
+#define WL04  4
+#define SL04  5
+#define WL05  5
+#define SL05  8
+#define WL06  6
+#define SL06  7
+#define WL07  7
+#define SL07  9
+#define WL08  8
+#define SL08 11
+#define WL09  9
+#define SL09 13
+#define WL10 10
+#define SL10 14
+#define WL11 11
+#define SL11 15
+#define WL12 12
+#define SL12  6
+#define WL13 13
+#define SL13  7
+#define WL14 14
+#define SL14  9
+#define WL15 15
+#define SL15  8
+
+#define WL16  7
+#define SL16  7
+#define WL17  4
+#define SL17  6
+#define WL18 13
+#define SL18  8
+#define WL19  1
+#define SL19 13
+#define WL20 10
+#define SL20 11
+#define WL21  6
+#define SL21  9
+#define WL22 15
+#define SL22  7
+#define WL23  3
+#define SL23 15
+#define WL24 12
+#define SL24  7
+#define WL25  0
+#define SL25 12
+#define WL26  9
+#define SL26 15
+#define WL27  5
+#define SL27  9
+#define WL28  2
+#define SL28 11
+#define WL29 14
+#define SL29  7
+#define WL30 11
+#define SL30 13
+#define WL31  8
+#define SL31 12
+
+#define WL32  3
+#define SL32 11
+#define WL33 10
+#define SL33 13
+#define WL34 14
+#define SL34  6
+#define WL35  4
+#define SL35  7
+#define WL36  9
+#define SL36 14
+#define WL37 15
+#define SL37  9
+#define WL38  8
+#define SL38 13
+#define WL39  1
+#define SL39 15
+#define WL40  2
+#define SL40 14
+#define WL41  7
+#define SL41  8
+#define WL42  0
+#define SL42 13
+#define WL43  6
+#define SL43  6
+#define WL44 13
+#define SL44  5
+#define WL45 11
+#define SL45 12
+#define WL46  5
+#define SL46  7
+#define WL47 12
+#define SL47  5
+
+#define WL48  1
+#define SL48 11
+#define WL49  9
+#define SL49 12
+#define WL50 11
+#define SL50 14
+#define WL51 10
+#define SL51 15
+#define WL52  0
+#define SL52 14
+#define WL53  8
+#define SL53 15
+#define WL54 12
+#define SL54  9
+#define WL55  4
+#define SL55  8
+#define WL56 13
+#define SL56  9
+#define WL57  3
+#define SL57 14
+#define WL58  7
+#define SL58  5
+#define WL59 15
+#define SL59  6
+#define WL60 14
+#define SL60  8
+#define WL61  5
+#define SL61  6
+#define WL62  6
+#define SL62  5
+#define WL63  2
+#define SL63 12
+
+#define WL64  4
+#define SL64  9
+#define WL65  0
+#define SL65 15
+#define WL66  5
+#define SL66  5
+#define WL67  9
+#define SL67 11
+#define WL68  7
+#define SL68  6
+#define WL69 12
+#define SL69  8
+#define WL70  2
+#define SL70 13
+#define WL71 10
+#define SL71 12
+#define WL72 14
+#define SL72  5
+#define WL73  1
+#define SL73 12
+#define WL74  3
+#define SL74 13
+#define WL75  8
+#define SL75 14
+#define WL76 11
+#define SL76 11
+#define WL77  6
+#define SL77  8
+#define WL78 15
+#define SL78  5
+#define WL79 13
+#define SL79  6
+
+#define WR00  5
+#define SR00  8
+#define WR01 14
+#define SR01  9
+#define WR02  7
+#define SR02  9
+#define WR03  0
+#define SR03 11
+#define WR04  9
+#define SR04 13
+#define WR05  2
+#define SR05 15
+#define WR06 11
+#define SR06 15
+#define WR07  4
+#define SR07  5
+#define WR08 13
+#define SR08  7
+#define WR09  6
+#define SR09  7
+#define WR10 15
+#define SR10  8
+#define WR11  8
+#define SR11 11
+#define WR12  1
+#define SR12 14
+#define WR13 10
+#define SR13 14
+#define WR14  3
+#define SR14 12
+#define WR15 12
+#define SR15  6
+
+#define WR16  6
+#define SR16  9
+#define WR17 11
+#define SR17 13
+#define WR18  3
+#define SR18 15
+#define WR19  7
+#define SR19  7
+#define WR20  0
+#define SR20 12
+#define WR21 13
+#define SR21  8
+#define WR22  5
+#define SR22  9
+#define WR23 10
+#define SR23 11
+#define WR24 14
+#define SR24  7
+#define WR25 15
+#define SR25  7
+#define WR26  8
+#define SR26 12
+#define WR27 12
+#define SR27  7
+#define WR28  4
+#define SR28  6
+#define WR29  9
+#define SR29 15
+#define WR30  1
+#define SR30 13
+#define WR31  2
+#define SR31 11
+
+#define WR32 15
+#define SR32  9
+#define WR33  5
+#define SR33  7
+#define WR34  1
+#define SR34 15
+#define WR35  3
+#define SR35 11
+#define WR36  7
+#define SR36  8
+#define WR37 14
+#define SR37  6
+#define WR38  6
+#define SR38  6
+#define WR39  9
+#define SR39 14
+#define WR40 11
+#define SR40 12
+#define WR41  8
+#define SR41 13
+#define WR42 12
+#define SR42  5
+#define WR43  2
+#define SR43 14
+#define WR44 10
+#define SR44 13
+#define WR45  0
+#define SR45 13
+#define WR46  4
+#define SR46  7
+#define WR47 13
+#define SR47  5
+
+#define WR48  8
+#define SR48 15
+#define WR49  6
+#define SR49  5
+#define WR50  4
+#define SR50  8
+#define WR51  1
+#define SR51 11
+#define WR52  3
+#define SR52 14
+#define WR53 11
+#define SR53 14
+#define WR54 15
+#define SR54  6
+#define WR55  0
+#define SR55 14
+#define WR56  5
+#define SR56  6
+#define WR57 12
+#define SR57  9
+#define WR58  2
+#define SR58 12
+#define WR59 13
+#define SR59  9
+#define WR60  9
+#define SR60 12
+#define WR61  7
+#define SR61  5
+#define WR62 10
+#define SR62 15
+#define WR63 14
+#define SR63  8
+
+#define WR64 12
+#define SR64  8
+#define WR65 15
+#define SR65  5
+#define WR66 10
+#define SR66 12
+#define WR67  4
+#define SR67  9
+#define WR68  1
+#define SR68 12
+#define WR69  5
+#define SR69  5
+#define WR70  8
+#define SR70 14
+#define WR71  7
+#define SR71  6
+#define WR72  6
+#define SR72  8
+#define WR73  2
+#define SR73 13
+#define WR74 13
+#define SR74  6
+#define WR75 14
+#define SR75  5
+#define WR76  0
+#define SR76 15
+#define WR77  3
+#define SR77 13
+#define WR78  9
+#define SR78 11
+#define WR79 11
+#define SR79 11
+
diff --git a/crypto/libressl/crypto/rsa/rsa_ameth.c b/crypto/libressl/crypto/rsa/rsa_ameth.c
new file mode 100644
index 0000000000..ebf0b0fc5c
--- /dev/null
+++ b/crypto/libressl/crypto/rsa/rsa_ameth.c
@@ -0,0 +1,675 @@
+/* $OpenBSD: rsa_ameth.c,v 1.14 2015/02/11 04:05:14 beck Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_CMS
+#include 
+#endif
+
+#include "asn1_locl.h"
+
+static int
+rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
+{
+	unsigned char *penc = NULL;
+	int penclen;
+
+	penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc);
+	if (penclen <= 0)
+		return 0;
+	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA),
+	    V_ASN1_NULL, NULL, penc, penclen))
+		return 1;
+
+	free(penc);
+	return 0;
+}
+
+static int
+rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+{
+	const unsigned char *p;
+	int pklen;
+	RSA *rsa = NULL;
+
+	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey))
+		return 0;
+	if (!(rsa = d2i_RSAPublicKey(NULL, &p, pklen))) {
+		RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB);
+		return 0;
+	}
+	EVP_PKEY_assign_RSA (pkey, rsa);
+	return 1;
+}
+
+static int
+rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+	if (BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) != 0 ||
+	    BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) != 0)
+		return 0;
+	return 1;
+}
+
+static int
+old_rsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
+{
+	RSA *rsa;
+
+	if (!(rsa = d2i_RSAPrivateKey (NULL, pder, derlen))) {
+		RSAerr(RSA_F_OLD_RSA_PRIV_DECODE, ERR_R_RSA_LIB);
+		return 0;
+	}
+	EVP_PKEY_assign_RSA(pkey, rsa);
+	return 1;
+}
+
+static int
+old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
+{
+	return i2d_RSAPrivateKey(pkey->pkey.rsa, pder);
+}
+
+static int
+rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
+{
+	unsigned char *rk = NULL;
+	int rklen;
+
+	rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk);
+
+	if (rklen <= 0) {
+		RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+
+	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_rsaEncryption), 0,
+	    V_ASN1_NULL, NULL, rk, rklen)) {
+		RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+
+	return 1;
+}
+
+static int
+rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
+{
+	const unsigned char *p;
+	int pklen;
+
+	if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8))
+		return 0;
+	return old_rsa_priv_decode(pkey, &p, pklen);
+}
+
+static int
+int_rsa_size(const EVP_PKEY *pkey)
+{
+	return RSA_size(pkey->pkey.rsa);
+}
+
+static int
+rsa_bits(const EVP_PKEY *pkey)
+{
+	return BN_num_bits(pkey->pkey.rsa->n);
+}
+
+static void
+int_rsa_free(EVP_PKEY *pkey)
+{
+	RSA_free(pkey->pkey.rsa);
+}
+
+static void
+update_buflen(const BIGNUM *b, size_t *pbuflen)
+{
+	size_t i;
+
+	if (!b)
+		return;
+	if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
+		*pbuflen = i;
+}
+
+static int
+do_rsa_print(BIO *bp, const RSA *x, int off, int priv)
+{
+	char *str;
+	const char *s;
+	unsigned char *m = NULL;
+	int ret = 0, mod_len = 0;
+	size_t buf_len = 0;
+
+	update_buflen(x->n, &buf_len);
+	update_buflen(x->e, &buf_len);
+
+	if (priv) {
+		update_buflen(x->d, &buf_len);
+		update_buflen(x->p, &buf_len);
+		update_buflen(x->q, &buf_len);
+		update_buflen(x->dmp1, &buf_len);
+		update_buflen(x->dmq1, &buf_len);
+		update_buflen(x->iqmp, &buf_len);
+	}
+
+	m = malloc(buf_len + 10);
+	if (m == NULL) {
+		RSAerr(RSA_F_DO_RSA_PRINT, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	if (x->n != NULL)
+		mod_len = BN_num_bits(x->n);
+
+	if (!BIO_indent(bp, off, 128))
+		goto err;
+
+	if (priv && x->d) {
+		if (BIO_printf(bp, "Private-Key: (%d bit)\n", mod_len) <= 0)
+			goto err;
+		str = "modulus:";
+		s = "publicExponent:";
+	} else {
+		if (BIO_printf(bp, "Public-Key: (%d bit)\n", mod_len) <= 0)
+			goto err;
+		str = "Modulus:";
+		s= "Exponent:";
+	}
+	if (!ASN1_bn_print(bp, str, x->n, m, off))
+		goto err;
+	if (!ASN1_bn_print(bp, s, x->e, m, off))
+		goto err;
+	if (priv) {
+		if (!ASN1_bn_print(bp, "privateExponent:", x->d,m, off))
+			goto err;
+		if (!ASN1_bn_print(bp, "prime1:", x->p, m, off))
+			goto err;
+		if (!ASN1_bn_print(bp, "prime2:", x->q, m, off))
+			goto err;
+		if (!ASN1_bn_print(bp, "exponent1:", x->dmp1, m, off))
+			goto err;
+		if (!ASN1_bn_print(bp, "exponent2:", x->dmq1, m, off))
+			goto err;
+		if (!ASN1_bn_print(bp, "coefficient:", x->iqmp, m, off))
+			goto err;
+	}
+	ret = 1;
+err:
+	free(m);
+	return (ret);
+}
+
+static int
+rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
+{
+	return do_rsa_print(bp, pkey->pkey.rsa, indent, 0);
+}
+
+static int
+rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
+{
+	return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
+}
+
+static RSA_PSS_PARAMS *
+rsa_pss_decode(const X509_ALGOR *alg, X509_ALGOR **pmaskHash)
+{
+	const unsigned char *p;
+	int plen;
+	RSA_PSS_PARAMS *pss;
+
+	*pmaskHash = NULL;
+
+	if (!alg->parameter || alg->parameter->type != V_ASN1_SEQUENCE)
+		return NULL;
+
+	p = alg->parameter->value.sequence->data;
+	plen = alg->parameter->value.sequence->length;
+	pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen);
+
+	if (!pss)
+		return NULL;
+
+	if (pss->maskGenAlgorithm) {
+		ASN1_TYPE *param = pss->maskGenAlgorithm->parameter;
+		if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) == NID_mgf1 &&
+		    param && param->type == V_ASN1_SEQUENCE) {
+			p = param->value.sequence->data;
+			plen = param->value.sequence->length;
+			*pmaskHash = d2i_X509_ALGOR(NULL, &p, plen);
+		}
+	}
+
+	return pss;
+}
+
+static int
+rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss, X509_ALGOR *maskHash,
+    int indent)
+{
+	int rv = 0;
+
+	if (!pss) {
+		if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0)
+			return 0;
+		return 1;
+	}
+	if (BIO_puts(bp, "\n") <= 0)
+		goto err;
+	if (!BIO_indent(bp, indent, 128))
+		goto err;
+	if (BIO_puts(bp, "Hash Algorithm: ") <= 0)
+		goto err;
+
+	if (pss->hashAlgorithm) {
+		if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0)
+			goto err;
+	} else if (BIO_puts(bp, "sha1 (default)") <= 0)
+		goto err;
+
+	if (BIO_puts(bp, "\n") <= 0)
+		goto err;
+
+	if (!BIO_indent(bp, indent, 128))
+		goto err;
+
+	if (BIO_puts(bp, "Mask Algorithm: ") <= 0)
+		goto err;
+	if (pss->maskGenAlgorithm) {
+		if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0)
+			goto err;
+		if (BIO_puts(bp, " with ") <= 0)
+			goto err;
+		if (maskHash) {
+			if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0)
+				goto err;
+		} else if (BIO_puts(bp, "INVALID") <= 0)
+			goto err;
+	} else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0)
+		goto err;
+	BIO_puts(bp, "\n");
+
+	if (!BIO_indent(bp, indent, 128))
+		goto err;
+	if (BIO_puts(bp, "Salt Length: 0x") <= 0)
+		goto err;
+	if (pss->saltLength) {
+		if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0)
+			goto err;
+	} else if (BIO_puts(bp, "14 (default)") <= 0)
+		goto err;
+	BIO_puts(bp, "\n");
+
+	if (!BIO_indent(bp, indent, 128))
+		goto err;
+	if (BIO_puts(bp, "Trailer Field: 0x") <= 0)
+		goto err;
+	if (pss->trailerField) {
+		if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0)
+			goto err;
+	} else if (BIO_puts(bp, "BC (default)") <= 0)
+		goto err;
+	BIO_puts(bp, "\n");
+
+	rv = 1;
+
+err:
+	return rv;
+}
+
+static int
+rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig,
+    int indent, ASN1_PCTX *pctx)
+{
+	if (OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss) {
+		int rv;
+		RSA_PSS_PARAMS *pss;
+		X509_ALGOR *maskHash;
+		pss = rsa_pss_decode(sigalg, &maskHash);
+		rv = rsa_pss_param_print(bp, pss, maskHash, indent);
+		if (pss)
+			RSA_PSS_PARAMS_free(pss);
+		if (maskHash)
+			X509_ALGOR_free(maskHash);
+		if (!rv)
+			return 0;
+	} else if (!sig && BIO_puts(bp, "\n") <= 0)
+		return 0;
+	if (sig)
+		return X509_signature_dump(bp, sig, indent);
+	return 1;
+}
+
+static int
+rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+{
+	X509_ALGOR *alg = NULL;
+
+	switch (op) {
+	case ASN1_PKEY_CTRL_PKCS7_SIGN:
+		if (arg1 == 0)
+			PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg);
+		break;
+
+	case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
+		if (arg1 == 0)
+			PKCS7_RECIP_INFO_get0_alg(arg2, &alg);
+		break;
+#ifndef OPENSSL_NO_CMS
+	case ASN1_PKEY_CTRL_CMS_SIGN:
+		if (arg1 == 0)
+			CMS_SignerInfo_get0_algs(arg2, NULL, NULL, NULL, &alg);
+		break;
+
+	case ASN1_PKEY_CTRL_CMS_ENVELOPE:
+		if (arg1 == 0)
+			CMS_RecipientInfo_ktri_get0_algs(arg2, NULL, NULL, &alg);
+		break;
+#endif
+
+	case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+		*(int *)arg2 = NID_sha1;
+		return 1;
+
+	default:
+		return -2;
+	}
+
+	if (alg)
+		X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption),
+		    V_ASN1_NULL, 0);
+
+	return 1;
+}
+
+/* Customised RSA item verification routine. This is called
+ * when a signature is encountered requiring special handling. We
+ * currently only handle PSS.
+ */
+static int
+rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+    X509_ALGOR *sigalg, ASN1_BIT_STRING *sig, EVP_PKEY *pkey)
+{
+	int rv = -1;
+	int saltlen;
+	const EVP_MD *mgf1md = NULL, *md = NULL;
+	RSA_PSS_PARAMS *pss;
+	X509_ALGOR *maskHash;
+	EVP_PKEY_CTX *pkctx;
+
+	/* Sanity check: make sure it is PSS */
+	if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) {
+		RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE);
+		return -1;
+	}
+
+	/* Decode PSS parameters */
+	pss = rsa_pss_decode(sigalg, &maskHash);
+
+	if (pss == NULL) {
+		RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_PSS_PARAMETERS);
+		goto err;
+	}
+	/* Check mask and lookup mask hash algorithm */
+	if (pss->maskGenAlgorithm) {
+		if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) != NID_mgf1) {
+			RSAerr(RSA_F_RSA_ITEM_VERIFY,
+			    RSA_R_UNSUPPORTED_MASK_ALGORITHM);
+			goto err;
+		}
+		if (!maskHash) {
+			RSAerr(RSA_F_RSA_ITEM_VERIFY,
+			    RSA_R_UNSUPPORTED_MASK_PARAMETER);
+			goto err;
+		}
+		mgf1md = EVP_get_digestbyobj(maskHash->algorithm);
+		if (mgf1md == NULL) {
+			RSAerr(RSA_F_RSA_ITEM_VERIFY,
+			    RSA_R_UNKNOWN_MASK_DIGEST);
+			goto err;
+		}
+	} else
+		mgf1md = EVP_sha1();
+
+	if (pss->hashAlgorithm) {
+		md = EVP_get_digestbyobj(pss->hashAlgorithm->algorithm);
+		if (md == NULL) {
+			RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_PSS_DIGEST);
+			goto err;
+		}
+	} else
+		md = EVP_sha1();
+
+	if (pss->saltLength) {
+		saltlen = ASN1_INTEGER_get(pss->saltLength);
+
+		/* Could perform more salt length sanity checks but the main
+		 * RSA routines will trap other invalid values anyway.
+		 */
+		if (saltlen < 0) {
+			RSAerr(RSA_F_RSA_ITEM_VERIFY,
+			    RSA_R_INVALID_SALT_LENGTH);
+			goto err;
+		}
+	} else
+		saltlen = 20;
+
+	/* low-level routines support only trailer field 0xbc (value 1)
+	 * and PKCS#1 says we should reject any other value anyway.
+	 */
+	if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) {
+		RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_TRAILER);
+		goto err;
+	}
+
+	/* We have all parameters now set up context */
+
+	if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey))
+		goto err;
+
+	if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
+		goto err;
+	/* Carry on */
+	rv = 2;
+
+err:
+	RSA_PSS_PARAMS_free(pss);
+	if (maskHash)
+		X509_ALGOR_free(maskHash);
+	return rv;
+}
+
+static int
+rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+    X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig)
+{
+	int pad_mode;
+	EVP_PKEY_CTX *pkctx = ctx->pctx;
+
+	if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
+		return 0;
+	if (pad_mode == RSA_PKCS1_PADDING)
+		return 2;
+	if (pad_mode == RSA_PKCS1_PSS_PADDING) {
+		const EVP_MD *sigmd, *mgf1md;
+		RSA_PSS_PARAMS *pss = NULL;
+		X509_ALGOR *mgf1alg = NULL;
+		ASN1_STRING *os1 = NULL, *os2 = NULL;
+		EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx);
+		int saltlen, rv = 0;
+
+		sigmd = EVP_MD_CTX_md(ctx);
+		if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0)
+			goto err;
+		if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen))
+			goto err;
+		if (saltlen == -1)
+			saltlen = EVP_MD_size(sigmd);
+		else if (saltlen == -2) {
+			saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
+			if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0)
+				saltlen--;
+		}
+		pss = RSA_PSS_PARAMS_new();
+		if (!pss)
+			goto err;
+		if (saltlen != 20) {
+			pss->saltLength = ASN1_INTEGER_new();
+			if (!pss->saltLength)
+				goto err;
+			if (!ASN1_INTEGER_set(pss->saltLength, saltlen))
+				goto err;
+		}
+		if (EVP_MD_type(sigmd) != NID_sha1) {
+			pss->hashAlgorithm = X509_ALGOR_new();
+			if (!pss->hashAlgorithm)
+				goto err;
+			X509_ALGOR_set_md(pss->hashAlgorithm, sigmd);
+		}
+		if (EVP_MD_type(mgf1md) != NID_sha1) {
+			ASN1_STRING *stmp = NULL;
+			/* need to embed algorithm ID inside another */
+			mgf1alg = X509_ALGOR_new();
+			X509_ALGOR_set_md(mgf1alg, mgf1md);
+			if (!ASN1_item_pack(mgf1alg, ASN1_ITEM_rptr(X509_ALGOR),
+			    &stmp))
+				goto err;
+			pss->maskGenAlgorithm = X509_ALGOR_new();
+			if (!pss->maskGenAlgorithm)
+				goto err;
+			X509_ALGOR_set0(pss->maskGenAlgorithm,
+			    OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp);
+		}
+		/* Finally create string with pss parameter encoding. */
+		if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os1))
+			goto err;
+		if (alg2) {
+			os2 = ASN1_STRING_dup(os1);
+			if (!os2)
+				goto err;
+			X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_rsassaPss),
+			    V_ASN1_SEQUENCE, os2);
+		}
+		X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_rsassaPss),
+		    V_ASN1_SEQUENCE, os1);
+		os1 = os2 = NULL;
+		rv = 3;
+err:
+		if (mgf1alg)
+			X509_ALGOR_free(mgf1alg);
+		if (pss)
+			RSA_PSS_PARAMS_free(pss);
+		ASN1_STRING_free(os1);
+		return rv;
+	}
+	return 2;
+}
+
+const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = {
+	{
+		.pkey_id = EVP_PKEY_RSA,
+		.pkey_base_id = EVP_PKEY_RSA,
+		.pkey_flags = ASN1_PKEY_SIGPARAM_NULL,
+
+		.pem_str = "RSA",
+		.info = "OpenSSL RSA method",
+
+		.pub_decode = rsa_pub_decode,
+		.pub_encode = rsa_pub_encode,
+		.pub_cmp = rsa_pub_cmp,
+		.pub_print = rsa_pub_print,
+
+		.priv_decode = rsa_priv_decode,
+		.priv_encode = rsa_priv_encode,
+		.priv_print = rsa_priv_print,
+
+		.pkey_size = int_rsa_size,
+		.pkey_bits = rsa_bits,
+
+		.sig_print = rsa_sig_print,
+
+		.pkey_free = int_rsa_free,
+		.pkey_ctrl = rsa_pkey_ctrl,
+		.old_priv_decode = old_rsa_priv_decode,
+		.old_priv_encode = old_rsa_priv_encode,
+		.item_verify = rsa_item_verify,
+		.item_sign = rsa_item_sign
+	},
+
+	{
+		.pkey_id = EVP_PKEY_RSA2,
+		.pkey_base_id = EVP_PKEY_RSA,
+		.pkey_flags = ASN1_PKEY_ALIAS
+	}
+};
diff --git a/crypto/libressl/crypto/rsa/rsa_asn1.c b/crypto/libressl/crypto/rsa/rsa_asn1.c
new file mode 100644
index 0000000000..84a7b5f8d2
--- /dev/null
+++ b/crypto/libressl/crypto/rsa/rsa_asn1.c
@@ -0,0 +1,308 @@
+/* $OpenBSD: rsa_asn1.c,v 1.11 2015/02/10 05:12:23 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+/* Override the default free and new methods */
+static int
+rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
+{
+	if (operation == ASN1_OP_NEW_PRE) {
+		*pval = (ASN1_VALUE *)RSA_new();
+		if (*pval)
+			return 2;
+		return 0;
+	} else if (operation == ASN1_OP_FREE_PRE) {
+		RSA_free((RSA *)*pval);
+		*pval = NULL;
+		return 2;
+	}
+	return 1;
+}
+
+static const ASN1_AUX RSAPrivateKey_aux = {
+	.app_data = NULL,
+	.flags = 0,
+	.ref_offset = 0,
+	.ref_lock = 0,
+	.asn1_cb = rsa_cb,
+	.enc_offset = 0,
+};
+static const ASN1_TEMPLATE RSAPrivateKey_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(RSA, version),
+		.field_name = "version",
+		.item = &LONG_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(RSA, n),
+		.field_name = "n",
+		.item = &BIGNUM_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(RSA, e),
+		.field_name = "e",
+		.item = &BIGNUM_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(RSA, d),
+		.field_name = "d",
+		.item = &BIGNUM_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(RSA, p),
+		.field_name = "p",
+		.item = &BIGNUM_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(RSA, q),
+		.field_name = "q",
+		.item = &BIGNUM_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(RSA, dmp1),
+		.field_name = "dmp1",
+		.item = &BIGNUM_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(RSA, dmq1),
+		.field_name = "dmq1",
+		.item = &BIGNUM_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(RSA, iqmp),
+		.field_name = "iqmp",
+		.item = &BIGNUM_it,
+	},
+};
+
+const ASN1_ITEM RSAPrivateKey_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = RSAPrivateKey_seq_tt,
+	.tcount = sizeof(RSAPrivateKey_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &RSAPrivateKey_aux,
+	.size = sizeof(RSA),
+	.sname = "RSA",
+};
+
+
+static const ASN1_AUX RSAPublicKey_aux = {
+	.app_data = NULL,
+	.flags = 0,
+	.ref_offset = 0,
+	.ref_lock = 0,
+	.asn1_cb = rsa_cb,
+	.enc_offset = 0,
+};
+static const ASN1_TEMPLATE RSAPublicKey_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(RSA, n),
+		.field_name = "n",
+		.item = &BIGNUM_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(RSA, e),
+		.field_name = "e",
+		.item = &BIGNUM_it,
+	},
+};
+
+const ASN1_ITEM RSAPublicKey_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = RSAPublicKey_seq_tt,
+	.tcount = sizeof(RSAPublicKey_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &RSAPublicKey_aux,
+	.size = sizeof(RSA),
+	.sname = "RSA",
+};
+
+static const ASN1_TEMPLATE RSA_PSS_PARAMS_seq_tt[] = {
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(RSA_PSS_PARAMS, hashAlgorithm),
+		.field_name = "hashAlgorithm",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 1,
+		.offset = offsetof(RSA_PSS_PARAMS, maskGenAlgorithm),
+		.field_name = "maskGenAlgorithm",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 2,
+		.offset = offsetof(RSA_PSS_PARAMS, saltLength),
+		.field_name = "saltLength",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 3,
+		.offset = offsetof(RSA_PSS_PARAMS, trailerField),
+		.field_name = "trailerField",
+		.item = &ASN1_INTEGER_it,
+	},
+};
+
+const ASN1_ITEM RSA_PSS_PARAMS_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = RSA_PSS_PARAMS_seq_tt,
+	.tcount = sizeof(RSA_PSS_PARAMS_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(RSA_PSS_PARAMS),
+	.sname = "RSA_PSS_PARAMS",
+};
+
+
+RSA_PSS_PARAMS *
+d2i_RSA_PSS_PARAMS(RSA_PSS_PARAMS **a, const unsigned char **in, long len)
+{
+	return (RSA_PSS_PARAMS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &RSA_PSS_PARAMS_it);
+}
+
+int
+i2d_RSA_PSS_PARAMS(RSA_PSS_PARAMS *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &RSA_PSS_PARAMS_it);
+}
+
+RSA_PSS_PARAMS *
+RSA_PSS_PARAMS_new(void)
+{
+	return (RSA_PSS_PARAMS *)ASN1_item_new(&RSA_PSS_PARAMS_it);
+}
+
+void
+RSA_PSS_PARAMS_free(RSA_PSS_PARAMS *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &RSA_PSS_PARAMS_it);
+}
+
+
+RSA *
+d2i_RSAPrivateKey(RSA **a, const unsigned char **in, long len)
+{
+	return (RSA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &RSAPrivateKey_it);
+}
+
+int
+i2d_RSAPrivateKey(const RSA *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &RSAPrivateKey_it);
+}
+
+
+RSA *
+d2i_RSAPublicKey(RSA **a, const unsigned char **in, long len)
+{
+	return (RSA *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &RSAPublicKey_it);
+}
+
+int
+i2d_RSAPublicKey(const RSA *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &RSAPublicKey_it);
+}
+
+RSA *
+RSAPublicKey_dup(RSA *rsa)
+{
+	return ASN1_item_dup(ASN1_ITEM_rptr(RSAPublicKey), rsa);
+}
+
+RSA *
+RSAPrivateKey_dup(RSA *rsa)
+{
+	return ASN1_item_dup(ASN1_ITEM_rptr(RSAPrivateKey), rsa);
+}
diff --git a/crypto/libressl/crypto/rsa/rsa_chk.c b/crypto/libressl/crypto/rsa/rsa_chk.c
new file mode 100644
index 0000000000..6b7c77a0e5
--- /dev/null
+++ b/crypto/libressl/crypto/rsa/rsa_chk.c
@@ -0,0 +1,213 @@
+/* $OpenBSD: rsa_chk.c,v 1.8 2014/07/09 19:51:38 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include 
+#include 
+#include 
+
+int
+RSA_check_key(const RSA *key)
+{
+	BIGNUM *i, *j, *k, *l, *m;
+	BN_CTX *ctx;
+	int r;
+	int ret = 1;
+
+	if (!key->p || !key->q || !key->n || !key->e || !key->d) {
+		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_VALUE_MISSING);
+		return 0;
+	}
+
+	i = BN_new();
+	j = BN_new();
+	k = BN_new();
+	l = BN_new();
+	m = BN_new();
+	ctx = BN_CTX_new();
+	if (i == NULL || j == NULL || k == NULL || l == NULL || m == NULL ||
+	    ctx == NULL) {
+		ret = -1;
+		RSAerr(RSA_F_RSA_CHECK_KEY, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	/* p prime? */
+	r = BN_is_prime_ex(key->p, BN_prime_checks, NULL, NULL);
+	if (r != 1) {
+		ret = r;
+		if (r != 0)
+			goto err;
+		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_P_NOT_PRIME);
+	}
+
+	/* q prime? */
+	r = BN_is_prime_ex(key->q, BN_prime_checks, NULL, NULL);
+	if (r != 1) {
+		ret = r;
+		if (r != 0)
+			goto err;
+		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_Q_NOT_PRIME);
+	}
+
+	/* n = p*q? */
+	r = BN_mul(i, key->p, key->q, ctx);
+	if (!r) {
+		ret = -1;
+		goto err;
+	}
+
+	if (BN_cmp(i, key->n) != 0) {
+		ret = 0;
+		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_N_DOES_NOT_EQUAL_P_Q);
+	}
+
+	/* d*e = 1  mod lcm(p-1,q-1)? */
+
+	r = BN_sub(i, key->p, BN_value_one());
+	if (!r) {
+		ret = -1;
+		goto err;
+	}
+	r = BN_sub(j, key->q, BN_value_one());
+	if (!r) {
+		ret = -1;
+		goto err;
+	}
+
+	/* now compute k = lcm(i,j) */
+	r = BN_mul(l, i, j, ctx);
+	if (!r) {
+		ret = -1;
+		goto err;
+	}
+	r = BN_gcd(m, i, j, ctx);
+	if (!r) {
+		ret = -1;
+		goto err;
+	}
+	r = BN_div(k, NULL, l, m, ctx); /* remainder is 0 */
+	if (!r) {
+		ret = -1;
+		goto err;
+	}
+
+	r = BN_mod_mul(i, key->d, key->e, k, ctx);
+	if (!r) {
+		ret = -1;
+		goto err;
+	}
+
+	if (!BN_is_one(i)) {
+		ret = 0;
+		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_D_E_NOT_CONGRUENT_TO_1);
+	}
+
+	if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) {
+		/* dmp1 = d mod (p-1)? */
+		r = BN_sub(i, key->p, BN_value_one());
+		if (!r) {
+			ret = -1;
+			goto err;
+		}
+
+		r = BN_mod(j, key->d, i, ctx);
+		if (!r) {
+			ret = -1;
+			goto err;
+		}
+
+		if (BN_cmp(j, key->dmp1) != 0) {
+			ret = 0;
+			RSAerr(RSA_F_RSA_CHECK_KEY,
+			    RSA_R_DMP1_NOT_CONGRUENT_TO_D);
+		}
+
+		/* dmq1 = d mod (q-1)? */
+		r = BN_sub(i, key->q, BN_value_one());
+		if (!r) {
+			ret = -1;
+			goto err;
+		}
+
+		r = BN_mod(j, key->d, i, ctx);
+		if (!r) {
+			ret = -1;
+			goto err;
+		}
+
+		if (BN_cmp(j, key->dmq1) != 0) {
+			ret = 0;
+			RSAerr(RSA_F_RSA_CHECK_KEY,
+			    RSA_R_DMQ1_NOT_CONGRUENT_TO_D);
+		}
+
+		/* iqmp = q^-1 mod p? */
+		if (!BN_mod_inverse(i, key->q, key->p, ctx)) {
+			ret = -1;
+			goto err;
+		}
+
+		if (BN_cmp(i, key->iqmp) != 0) {
+			ret = 0;
+			RSAerr(RSA_F_RSA_CHECK_KEY,
+			    RSA_R_IQMP_NOT_INVERSE_OF_Q);
+		}
+	}
+
+err:
+	BN_free(i);
+	BN_free(j);
+	BN_free(k);
+	BN_free(l);
+	BN_free(m);
+	BN_CTX_free(ctx);
+
+	return (ret);
+}
diff --git a/crypto/libressl/crypto/rsa/rsa_crpt.c b/crypto/libressl/crypto/rsa/rsa_crpt.c
new file mode 100644
index 0000000000..8661a66ddc
--- /dev/null
+++ b/crypto/libressl/crypto/rsa/rsa_crpt.c
@@ -0,0 +1,214 @@
+/* $OpenBSD: rsa_crpt.c,v 1.15 2016/06/30 02:02:06 bcook Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+
+int
+RSA_size(const RSA *r)
+{
+	return BN_num_bytes(r->n);
+}
+
+int
+RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
+    RSA *rsa, int padding)
+{
+	return rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding);
+}
+
+int
+RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
+    RSA *rsa, int padding)
+{
+	return rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding);
+}
+
+int
+RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
+    RSA *rsa, int padding)
+{
+	return rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding);
+}
+
+int
+RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
+    RSA *rsa, int padding)
+{
+	return rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding);
+}
+
+int
+RSA_flags(const RSA *r)
+{
+	return r == NULL ? 0 : r->meth->flags;
+}
+
+void
+RSA_blinding_off(RSA *rsa)
+{
+	BN_BLINDING_free(rsa->blinding);
+	rsa->blinding = NULL;
+	rsa->flags |= RSA_FLAG_NO_BLINDING;
+}
+
+int
+RSA_blinding_on(RSA *rsa, BN_CTX *ctx)
+{
+	int ret = 0;
+
+	if (rsa->blinding != NULL)
+		RSA_blinding_off(rsa);
+
+	rsa->blinding = RSA_setup_blinding(rsa, ctx);
+	if (rsa->blinding == NULL)
+		goto err;
+
+	rsa->flags &= ~RSA_FLAG_NO_BLINDING;
+	ret = 1;
+err:
+	return (ret);
+}
+
+static BIGNUM *
+rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p, const BIGNUM *q,
+    BN_CTX *ctx)
+{
+	BIGNUM *ret = NULL, *r0, *r1, *r2;
+
+	if (d == NULL || p == NULL || q == NULL)
+		return NULL;
+
+	BN_CTX_start(ctx);
+	if ((r0 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((r1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((r2 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	if (!BN_sub(r1, p, BN_value_one()))
+		goto err;
+	if (!BN_sub(r2, q, BN_value_one()))
+		goto err;
+	if (!BN_mul(r0, r1, r2, ctx))
+		goto err;
+
+	ret = BN_mod_inverse(NULL, d, r0, ctx);
+err:
+	BN_CTX_end(ctx);
+	return ret;
+}
+
+BN_BLINDING *
+RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
+{
+	BIGNUM *e;
+	BIGNUM n;
+	BN_CTX *ctx;
+	BN_BLINDING *ret = NULL;
+
+	if (in_ctx == NULL) {
+		if ((ctx = BN_CTX_new()) == NULL)
+			return 0;
+	} else
+		ctx = in_ctx;
+
+	BN_CTX_start(ctx);
+
+	if (rsa->e == NULL) {
+		e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx);
+		if (e == NULL) {
+			RSAerr(RSA_F_RSA_SETUP_BLINDING,
+			    RSA_R_NO_PUBLIC_EXPONENT);
+			goto err;
+		}
+	} else
+		e = rsa->e;
+
+	BN_init(&n);
+	BN_with_flags(&n, rsa->n, BN_FLG_CONSTTIME);
+
+	ret = BN_BLINDING_create_param(NULL, e, &n, ctx, rsa->meth->bn_mod_exp,
+	    rsa->_method_mod_n);
+
+	if (ret == NULL) {
+		RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB);
+		goto err;
+	}
+	CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret));
+err:
+	BN_CTX_end(ctx);
+	if (in_ctx == NULL)
+		BN_CTX_free(ctx);
+	if (rsa->e == NULL)
+		BN_free(e);
+
+	return ret;
+}
diff --git a/crypto/libressl/crypto/rsa/rsa_depr.c b/crypto/libressl/crypto/rsa/rsa_depr.c
new file mode 100644
index 0000000000..16a537f12c
--- /dev/null
+++ b/crypto/libressl/crypto/rsa/rsa_depr.c
@@ -0,0 +1,101 @@
+/* $OpenBSD: rsa_depr.c,v 1.7 2014/07/10 22:45:57 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NB: This file contains deprecated functions (compatibility wrappers to the
+ * "new" versions). */
+
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+
+#ifndef OPENSSL_NO_DEPRECATED
+
+RSA *
+RSA_generate_key(int bits, unsigned long e_value,
+    void (*callback)(int, int, void *), void *cb_arg)
+{
+	BN_GENCB cb;
+	int i;
+	RSA *rsa = RSA_new();
+	BIGNUM *e = BN_new();
+
+	if (!rsa || !e)
+		goto err;
+
+	/* The problem is when building with 8, 16, or 32 BN_ULONG,
+	 * unsigned long can be larger */
+	for (i = 0; i < (int)sizeof(unsigned long) * 8; i++) {
+		if (e_value & (1UL << i))
+			if (BN_set_bit(e, i) == 0)
+				goto err;
+	}
+
+	BN_GENCB_set_old(&cb, callback, cb_arg);
+
+	if (RSA_generate_key_ex(rsa, bits, e, &cb)) {
+		BN_free(e);
+		return rsa;
+	}
+err:
+	BN_free(e);
+	RSA_free(rsa);
+
+	return 0;
+}
+#endif
diff --git a/crypto/libressl/crypto/rsa/rsa_eay.c b/crypto/libressl/crypto/rsa/rsa_eay.c
new file mode 100644
index 0000000000..e3770a5d27
--- /dev/null
+++ b/crypto/libressl/crypto/rsa/rsa_eay.c
@@ -0,0 +1,888 @@
+/* $OpenBSD: rsa_eay.c,v 1.41 2016/06/30 02:02:06 bcook Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
+static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
+    unsigned char *to, RSA *rsa, int padding);
+static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
+    unsigned char *to, RSA *rsa, int padding);
+static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
+    unsigned char *to, RSA *rsa, int padding);
+static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
+    unsigned char *to, RSA *rsa, int padding);
+static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa, BN_CTX *ctx);
+static int RSA_eay_init(RSA *rsa);
+static int RSA_eay_finish(RSA *rsa);
+
+static RSA_METHOD rsa_pkcs1_eay_meth = {
+	.name = "Eric Young's PKCS#1 RSA",
+	.rsa_pub_enc = RSA_eay_public_encrypt,
+	.rsa_pub_dec = RSA_eay_public_decrypt, /* signature verification */
+	.rsa_priv_enc = RSA_eay_private_encrypt, /* signing */
+	.rsa_priv_dec = RSA_eay_private_decrypt,
+	.rsa_mod_exp = RSA_eay_mod_exp,
+	.bn_mod_exp = BN_mod_exp_mont, /* XXX probably we should not use Montgomery if  e == 3 */
+	.init = RSA_eay_init,
+	.finish = RSA_eay_finish,
+};
+
+const RSA_METHOD *
+RSA_PKCS1_SSLeay(void)
+{
+	return &rsa_pkcs1_eay_meth;
+}
+
+static int
+RSA_eay_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
+    RSA *rsa, int padding)
+{
+	BIGNUM *f, *ret;
+	int i, j, k, num = 0, r = -1;
+	unsigned char *buf = NULL;
+	BN_CTX *ctx = NULL;
+
+	if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) {
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE);
+		return -1;
+	}
+
+	if (BN_ucmp(rsa->n, rsa->e) <= 0) {
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
+		return -1;
+	}
+
+	/* for large moduli, enforce exponent limit */
+	if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) {
+		if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
+			RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
+			return -1;
+		}
+	}
+
+	if ((ctx = BN_CTX_new()) == NULL)
+		goto err;
+
+	BN_CTX_start(ctx);
+	f = BN_CTX_get(ctx);
+	ret = BN_CTX_get(ctx);
+	num = BN_num_bytes(rsa->n);
+	buf = malloc(num);
+
+	if (f == NULL || ret == NULL || buf == NULL) {
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	switch (padding) {
+	case RSA_PKCS1_PADDING:
+		i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen);
+		break;
+#ifndef OPENSSL_NO_SHA
+	case RSA_PKCS1_OAEP_PADDING:
+		i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0);
+		break;
+#endif
+	case RSA_SSLV23_PADDING:
+		i = RSA_padding_add_SSLv23(buf, num, from, flen);
+		break;
+	case RSA_NO_PADDING:
+		i = RSA_padding_add_none(buf, num, from, flen);
+		break;
+	default:
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,
+		    RSA_R_UNKNOWN_PADDING_TYPE);
+		goto err;
+	}
+	if (i <= 0)
+		goto err;
+
+	if (BN_bin2bn(buf, num, f) == NULL)
+		goto err;
+
+	if (BN_ucmp(f, rsa->n) >= 0) {
+		/* usually the padding functions would catch this */
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,
+		    RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+		goto err;
+	}
+
+	if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+		if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n,
+		    CRYPTO_LOCK_RSA, rsa->n, ctx))
+			goto err;
+
+	if (!rsa->meth->bn_mod_exp(ret, f,rsa->e, rsa->n, ctx,
+	    rsa->_method_mod_n))
+		goto err;
+
+	/* put in leading 0 bytes if the number is less than the
+	 * length of the modulus */
+	j = BN_num_bytes(ret);
+	i = BN_bn2bin(ret, &(to[num - j]));
+	for (k = 0; k < num - i; k++)
+		to[k] = 0;
+
+	r = num;
+err:
+	if (ctx != NULL) {
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+	}
+	if (buf != NULL) {
+		explicit_bzero(buf, num);
+		free(buf);
+	}
+	return r;
+}
+
+static BN_BLINDING *
+rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
+{
+	BN_BLINDING *ret;
+	int got_write_lock = 0;
+	CRYPTO_THREADID cur;
+
+	CRYPTO_r_lock(CRYPTO_LOCK_RSA);
+
+	if (rsa->blinding == NULL) {
+		CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
+		CRYPTO_w_lock(CRYPTO_LOCK_RSA);
+		got_write_lock = 1;
+
+		if (rsa->blinding == NULL)
+			rsa->blinding = RSA_setup_blinding(rsa, ctx);
+	}
+
+	ret = rsa->blinding;
+	if (ret == NULL)
+		goto err;
+
+	CRYPTO_THREADID_current(&cur);
+	if (!CRYPTO_THREADID_cmp(&cur, BN_BLINDING_thread_id(ret))) {
+		/* rsa->blinding is ours! */
+		*local = 1;
+	} else {
+		/* resort to rsa->mt_blinding instead */
+		/*
+		 * Instruct rsa_blinding_convert(), rsa_blinding_invert()
+		 * that the BN_BLINDING is shared, meaning that accesses
+		 * require locks, and that the blinding factor must be
+		 * stored outside the BN_BLINDING
+		 */
+		*local = 0;
+
+		if (rsa->mt_blinding == NULL) {
+			if (!got_write_lock) {
+				CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
+				CRYPTO_w_lock(CRYPTO_LOCK_RSA);
+				got_write_lock = 1;
+			}
+
+			if (rsa->mt_blinding == NULL)
+				rsa->mt_blinding = RSA_setup_blinding(rsa, ctx);
+		}
+		ret = rsa->mt_blinding;
+	}
+
+err:
+	if (got_write_lock)
+		CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
+	else
+		CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
+	return ret;
+}
+
+static int
+rsa_blinding_convert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, BN_CTX *ctx)
+{
+	if (unblind == NULL)
+		/*
+		 * Local blinding: store the unblinding factor
+		 * in BN_BLINDING.
+		 */
+		return BN_BLINDING_convert_ex(f, NULL, b, ctx);
+	else {
+		/*
+		 * Shared blinding: store the unblinding factor
+		 * outside BN_BLINDING.
+		 */
+		int ret;
+		CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING);
+		ret = BN_BLINDING_convert_ex(f, unblind, b, ctx);
+		CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
+		return ret;
+	}
+}
+
+static int
+rsa_blinding_invert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, BN_CTX *ctx)
+{
+	/*
+	 * For local blinding, unblind is set to NULL, and BN_BLINDING_invert_ex
+	 * will use the unblinding factor stored in BN_BLINDING.
+	 * If BN_BLINDING is shared between threads, unblind must be non-null:
+	 * BN_BLINDING_invert_ex will then use the local unblinding factor,
+	 * and will only read the modulus from BN_BLINDING.
+	 * In both cases it's safe to access the blinding without a lock.
+	 */
+	return BN_BLINDING_invert_ex(f, unblind, b, ctx);
+}
+
+/* signing */
+static int
+RSA_eay_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
+    RSA *rsa, int padding)
+{
+	BIGNUM *f, *ret, *res;
+	int i, j, k, num = 0, r = -1;
+	unsigned char *buf = NULL;
+	BN_CTX *ctx = NULL;
+	int local_blinding = 0;
+	/*
+	 * Used only if the blinding structure is shared. A non-NULL unblind
+	 * instructs rsa_blinding_convert() and rsa_blinding_invert() to store
+	 * the unblinding factor outside the blinding structure.
+	 */
+	BIGNUM *unblind = NULL;
+	BN_BLINDING *blinding = NULL;
+
+	if ((ctx = BN_CTX_new()) == NULL)
+		goto err;
+
+	BN_CTX_start(ctx);
+	f = BN_CTX_get(ctx);
+	ret = BN_CTX_get(ctx);
+	num = BN_num_bytes(rsa->n);
+	buf = malloc(num);
+
+	if (f == NULL || ret == NULL || buf == NULL) {
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	switch (padding) {
+	case RSA_PKCS1_PADDING:
+		i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen);
+		break;
+	case RSA_X931_PADDING:
+		i = RSA_padding_add_X931(buf, num, from, flen);
+		break;
+	case RSA_NO_PADDING:
+		i = RSA_padding_add_none(buf, num, from, flen);
+		break;
+	case RSA_SSLV23_PADDING:
+	default:
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
+		    RSA_R_UNKNOWN_PADDING_TYPE);
+		goto err;
+	}
+	if (i <= 0)
+		goto err;
+
+	if (BN_bin2bn(buf, num, f) == NULL)
+		goto err;
+
+	if (BN_ucmp(f, rsa->n) >= 0) {
+		/* usually the padding functions would catch this */
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
+		    RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+		goto err;
+	}
+
+	if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) {
+		blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
+		if (blinding == NULL) {
+			RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
+			    ERR_R_INTERNAL_ERROR);
+			goto err;
+		}
+	}
+
+	if (blinding != NULL) {
+		if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) {
+			RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,
+			    ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		if (!rsa_blinding_convert(blinding, f, unblind, ctx))
+			goto err;
+	}
+
+	if ((rsa->flags & RSA_FLAG_EXT_PKEY) ||
+	    (rsa->p != NULL && rsa->q != NULL && rsa->dmp1 != NULL &&
+	    rsa->dmq1 != NULL && rsa->iqmp != NULL)) {
+		if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx))
+			goto err;
+	} else {
+		BIGNUM d;
+
+		BN_init(&d);
+		BN_with_flags(&d, rsa->d, BN_FLG_CONSTTIME);
+
+		if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+			if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n,
+			    CRYPTO_LOCK_RSA, rsa->n, ctx))
+				goto err;
+
+		if (!rsa->meth->bn_mod_exp(ret, f, &d, rsa->n, ctx,
+		    rsa->_method_mod_n)) {
+			goto err;
+		}
+	}
+
+	if (blinding)
+		if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
+			goto err;
+
+	if (padding == RSA_X931_PADDING) {
+		BN_sub(f, rsa->n, ret);
+		if (BN_cmp(ret, f) > 0)
+			res = f;
+		else
+			res = ret;
+	} else
+		res = ret;
+
+	/* put in leading 0 bytes if the number is less than the
+	 * length of the modulus */
+	j = BN_num_bytes(res);
+	i = BN_bn2bin(res, &(to[num - j]));
+	for (k = 0; k < num - i; k++)
+		to[k] = 0;
+
+	r = num;
+err:
+	if (ctx != NULL) {
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+	}
+	if (buf != NULL) {
+		explicit_bzero(buf, num);
+		free(buf);
+	}
+	return r;
+}
+
+static int
+RSA_eay_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
+    RSA *rsa, int padding)
+{
+	BIGNUM *f, *ret;
+	int j, num = 0, r = -1;
+	unsigned char *p;
+	unsigned char *buf = NULL;
+	BN_CTX *ctx = NULL;
+	int local_blinding = 0;
+	/*
+	 * Used only if the blinding structure is shared. A non-NULL unblind
+	 * instructs rsa_blinding_convert() and rsa_blinding_invert() to store
+	 * the unblinding factor outside the blinding structure.
+	 */
+	BIGNUM *unblind = NULL;
+	BN_BLINDING *blinding = NULL;
+
+	if ((ctx = BN_CTX_new()) == NULL)
+		goto err;
+
+	BN_CTX_start(ctx);
+	f = BN_CTX_get(ctx);
+	ret = BN_CTX_get(ctx);
+	num = BN_num_bytes(rsa->n);
+	buf = malloc(num);
+
+	if (!f || !ret || !buf) {
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	/* This check was for equality but PGP does evil things
+	 * and chops off the top '0' bytes */
+	if (flen > num) {
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,
+		    RSA_R_DATA_GREATER_THAN_MOD_LEN);
+		goto err;
+	}
+
+	/* make data into a big number */
+	if (BN_bin2bn(from, (int)flen, f) == NULL)
+		goto err;
+
+	if (BN_ucmp(f, rsa->n) >= 0) {
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,
+		    RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+		goto err;
+	}
+
+	if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) {
+		blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
+		if (blinding == NULL) {
+			RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,
+			    ERR_R_INTERNAL_ERROR);
+			goto err;
+		}
+	}
+
+	if (blinding != NULL) {
+		if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) {
+			RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,
+			    ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		if (!rsa_blinding_convert(blinding, f, unblind, ctx))
+			goto err;
+	}
+
+	/* do the decrypt */
+	if ((rsa->flags & RSA_FLAG_EXT_PKEY) ||
+	    (rsa->p != NULL && rsa->q != NULL && rsa->dmp1 != NULL &&
+	    rsa->dmq1 != NULL && rsa->iqmp != NULL)) {
+		if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx))
+			goto err;
+	} else {
+		BIGNUM d;
+
+		BN_init(&d);
+		BN_with_flags(&d, rsa->d, BN_FLG_CONSTTIME);
+
+		if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+			if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n,
+			    CRYPTO_LOCK_RSA, rsa->n, ctx))
+				goto err;
+
+		if (!rsa->meth->bn_mod_exp(ret, f, &d, rsa->n, ctx,
+		    rsa->_method_mod_n)) {
+			goto err;
+		}
+	}
+
+	if (blinding)
+		if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
+			goto err;
+
+	p = buf;
+	j = BN_bn2bin(ret, p); /* j is only used with no-padding mode */
+
+	switch (padding) {
+	case RSA_PKCS1_PADDING:
+		r = RSA_padding_check_PKCS1_type_2(to, num, buf, j, num);
+		break;
+#ifndef OPENSSL_NO_SHA
+	case RSA_PKCS1_OAEP_PADDING:
+		r = RSA_padding_check_PKCS1_OAEP(to, num, buf, j, num, NULL, 0);
+		break;
+#endif
+	case RSA_SSLV23_PADDING:
+		r = RSA_padding_check_SSLv23(to, num, buf, j, num);
+		break;
+	case RSA_NO_PADDING:
+		r = RSA_padding_check_none(to, num, buf, j, num);
+		break;
+	default:
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,
+		    RSA_R_UNKNOWN_PADDING_TYPE);
+		goto err;
+	}
+	if (r < 0)
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,
+		    RSA_R_PADDING_CHECK_FAILED);
+
+err:
+	if (ctx != NULL) {
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+	}
+	if (buf != NULL) {
+		explicit_bzero(buf, num);
+		free(buf);
+	}
+	return r;
+}
+
+/* signature verification */
+static int
+RSA_eay_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
+    RSA *rsa, int padding)
+{
+	BIGNUM *f, *ret;
+	int i, num = 0, r = -1;
+	unsigned char *p;
+	unsigned char *buf = NULL;
+	BN_CTX *ctx = NULL;
+
+	if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) {
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE);
+		return -1;
+	}
+
+	if (BN_ucmp(rsa->n, rsa->e) <= 0) {
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE);
+		return -1;
+	}
+
+	/* for large moduli, enforce exponent limit */
+	if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) {
+		if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
+			RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE);
+			return -1;
+		}
+	}
+
+	if ((ctx = BN_CTX_new()) == NULL)
+		goto err;
+
+	BN_CTX_start(ctx);
+	f = BN_CTX_get(ctx);
+	ret = BN_CTX_get(ctx);
+	num = BN_num_bytes(rsa->n);
+	buf = malloc(num);
+
+	if (!f || !ret || !buf) {
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	/* This check was for equality but PGP does evil things
+	 * and chops off the top '0' bytes */
+	if (flen > num) {
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,
+		    RSA_R_DATA_GREATER_THAN_MOD_LEN);
+		goto err;
+	}
+
+	if (BN_bin2bn(from, flen, f) == NULL)
+		goto err;
+
+	if (BN_ucmp(f, rsa->n) >= 0) {
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,
+		    RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+		goto err;
+	}
+
+	if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+		if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n,
+		    CRYPTO_LOCK_RSA, rsa->n, ctx))
+			goto err;
+
+	if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx,
+	    rsa->_method_mod_n))
+		goto err;
+
+	if (padding == RSA_X931_PADDING && (ret->d[0] & 0xf) != 12)
+		if (!BN_sub(ret, rsa->n, ret))
+			goto err;
+
+	p = buf;
+	i = BN_bn2bin(ret, p);
+
+	switch (padding) {
+	case RSA_PKCS1_PADDING:
+		r = RSA_padding_check_PKCS1_type_1(to, num, buf, i, num);
+		break;
+	case RSA_X931_PADDING:
+		r = RSA_padding_check_X931(to, num, buf, i, num);
+		break;
+	case RSA_NO_PADDING:
+		r = RSA_padding_check_none(to, num, buf, i, num);
+		break;
+	default:
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,
+		    RSA_R_UNKNOWN_PADDING_TYPE);
+		goto err;
+	}
+	if (r < 0)
+		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,
+		    RSA_R_PADDING_CHECK_FAILED);
+
+err:
+	if (ctx != NULL) {
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+	}
+	if (buf != NULL) {
+		explicit_bzero(buf, num);
+		free(buf);
+	}
+	return r;
+}
+
+static int
+RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+{
+	BIGNUM *r1, *m1, *vrfy;
+	BIGNUM dmp1, dmq1, c, pr1;
+	int ret = 0;
+
+	BN_CTX_start(ctx);
+	r1 = BN_CTX_get(ctx);
+	m1 = BN_CTX_get(ctx);
+	vrfy = BN_CTX_get(ctx);
+	if (r1 == NULL || m1 == NULL || vrfy == NULL) {
+		RSAerr(RSA_F_RSA_EAY_MOD_EXP, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	{
+		BIGNUM p, q;
+
+		/*
+		 * Make sure BN_mod_inverse in Montgomery intialization uses the
+		 * BN_FLG_CONSTTIME flag
+		 */
+		BN_init(&p);
+		BN_init(&q);
+		BN_with_flags(&p, rsa->p, BN_FLG_CONSTTIME);
+		BN_with_flags(&q, rsa->q, BN_FLG_CONSTTIME);
+
+		if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) {
+			if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p,
+			     CRYPTO_LOCK_RSA, &p, ctx) ||
+			    !BN_MONT_CTX_set_locked(&rsa->_method_mod_q,
+			     CRYPTO_LOCK_RSA, &q, ctx)) {
+				goto err;
+			}
+		}
+	}
+
+	if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+		if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n,
+		    CRYPTO_LOCK_RSA, rsa->n, ctx))
+			goto err;
+
+	/* compute I mod q */
+	BN_init(&c);
+	BN_with_flags(&c, I, BN_FLG_CONSTTIME);
+
+	if (!BN_mod(r1, &c, rsa->q, ctx))
+		goto err;
+
+	/* compute r1^dmq1 mod q */
+	BN_init(&dmq1);
+	BN_with_flags(&dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
+
+	if (!rsa->meth->bn_mod_exp(m1, r1, &dmq1, rsa->q, ctx,
+	    rsa->_method_mod_q))
+		goto err;
+
+	/* compute I mod p */
+	BN_with_flags(&c, I, BN_FLG_CONSTTIME);
+
+	if (!BN_mod(r1, &c, rsa->p, ctx))
+		goto err;
+
+	/* compute r1^dmp1 mod p */
+	BN_init(&dmp1);
+	BN_with_flags(&dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
+
+	if (!rsa->meth->bn_mod_exp(r0, r1, &dmp1, rsa->p, ctx,
+	    rsa->_method_mod_p))
+		goto err;
+
+	if (!BN_sub(r0, r0, m1))
+		goto err;
+
+	/*
+	 * This will help stop the size of r0 increasing, which does
+	 * affect the multiply if it optimised for a power of 2 size
+	 */
+	if (BN_is_negative(r0))
+		if (!BN_add(r0, r0, rsa->p))
+			goto err;
+
+	if (!BN_mul(r1, r0, rsa->iqmp, ctx))
+		goto err;
+
+	/* Turn BN_FLG_CONSTTIME flag on before division operation */
+	BN_init(&pr1);
+	BN_with_flags(&pr1, r1, BN_FLG_CONSTTIME);
+
+	if (!BN_mod(r0, &pr1, rsa->p, ctx))
+		goto err;
+
+	/*
+	 * If p < q it is occasionally possible for the correction of
+	 * adding 'p' if r0 is negative above to leave the result still
+	 * negative. This can break the private key operations: the following
+	 * second correction should *always* correct this rare occurrence.
+	 * This will *never* happen with OpenSSL generated keys because
+	 * they ensure p > q [steve]
+	 */
+	if (BN_is_negative(r0))
+		if (!BN_add(r0, r0, rsa->p))
+			goto err;
+	if (!BN_mul(r1, r0, rsa->q, ctx))
+		goto err;
+	if (!BN_add(r0, r1, m1))
+		goto err;
+
+	if (rsa->e && rsa->n) {
+		if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx,
+		    rsa->_method_mod_n))
+			goto err;
+		/*
+		 * If 'I' was greater than (or equal to) rsa->n, the operation
+		 * will be equivalent to using 'I mod n'. However, the result of
+		 * the verify will *always* be less than 'n' so we don't check
+		 * for absolute equality, just congruency.
+		 */
+		if (!BN_sub(vrfy, vrfy, I))
+			goto err;
+		if (!BN_mod(vrfy, vrfy, rsa->n, ctx))
+			goto err;
+		if (BN_is_negative(vrfy))
+			if (!BN_add(vrfy, vrfy, rsa->n))
+				goto err;
+		if (!BN_is_zero(vrfy)) {
+			/*
+			 * 'I' and 'vrfy' aren't congruent mod n. Don't leak
+			 * miscalculated CRT output, just do a raw (slower)
+			 * mod_exp and return that instead.
+			 */
+			BIGNUM d;
+
+			BN_init(&d);
+			BN_with_flags(&d, rsa->d, BN_FLG_CONSTTIME);
+
+			if (!rsa->meth->bn_mod_exp(r0, I, &d, rsa->n, ctx,
+			    rsa->_method_mod_n)) {
+				goto err;
+			}
+		}
+	}
+	ret = 1;
+err:
+	BN_CTX_end(ctx);
+	return ret;
+}
+
+static int
+RSA_eay_init(RSA *rsa)
+{
+	rsa->flags |= RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE;
+	return 1;
+}
+
+static int
+RSA_eay_finish(RSA *rsa)
+{
+	BN_MONT_CTX_free(rsa->_method_mod_n);
+	BN_MONT_CTX_free(rsa->_method_mod_p);
+	BN_MONT_CTX_free(rsa->_method_mod_q);
+
+	return 1;
+}
diff --git a/crypto/libressl/crypto/rsa/rsa_err.c b/crypto/libressl/crypto/rsa/rsa_err.c
new file mode 100644
index 0000000000..17c32ac561
--- /dev/null
+++ b/crypto/libressl/crypto/rsa/rsa_err.c
@@ -0,0 +1,210 @@
+/* $OpenBSD$ */
+/* ====================================================================
+ * Copyright (c) 1999-2011 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_RSA,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_RSA,0,reason)
+
+static ERR_STRING_DATA RSA_str_functs[] = {
+	{ERR_FUNC(RSA_F_CHECK_PADDING_MD), "CHECK_PADDING_MD"},
+	{ERR_FUNC(RSA_F_DO_RSA_PRINT), "DO_RSA_PRINT"},
+	{ERR_FUNC(RSA_F_INT_RSA_VERIFY), "INT_RSA_VERIFY"},
+	{ERR_FUNC(RSA_F_MEMORY_LOCK), "MEMORY_LOCK"},
+	{ERR_FUNC(RSA_F_OLD_RSA_PRIV_DECODE), "OLD_RSA_PRIV_DECODE"},
+	{ERR_FUNC(RSA_F_PKEY_RSA_CTRL), "PKEY_RSA_CTRL"},
+	{ERR_FUNC(RSA_F_PKEY_RSA_CTRL_STR), "PKEY_RSA_CTRL_STR"},
+	{ERR_FUNC(RSA_F_PKEY_RSA_SIGN), "PKEY_RSA_SIGN"},
+	{ERR_FUNC(RSA_F_PKEY_RSA_VERIFY), "PKEY_RSA_VERIFY"},
+	{ERR_FUNC(RSA_F_PKEY_RSA_VERIFYRECOVER), "PKEY_RSA_VERIFYRECOVER"},
+	{ERR_FUNC(RSA_F_RSA_BUILTIN_KEYGEN), "RSA_BUILTIN_KEYGEN"},
+	{ERR_FUNC(RSA_F_RSA_CHECK_KEY), "RSA_check_key"},
+	{ERR_FUNC(RSA_F_RSA_EAY_MOD_EXP), "RSA_EAY_MOD_EXP"},
+	{ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_DECRYPT), "RSA_EAY_PRIVATE_DECRYPT"},
+	{ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_ENCRYPT), "RSA_EAY_PRIVATE_ENCRYPT"},
+	{ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_DECRYPT), "RSA_EAY_PUBLIC_DECRYPT"},
+	{ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_ENCRYPT), "RSA_EAY_PUBLIC_ENCRYPT"},
+	{ERR_FUNC(RSA_F_RSA_GENERATE_KEY), "RSA_generate_key"},
+	{ERR_FUNC(RSA_F_RSA_GENERATE_KEY_EX), "RSA_generate_key_ex"},
+	{ERR_FUNC(RSA_F_RSA_ITEM_VERIFY), "RSA_ITEM_VERIFY"},
+	{ERR_FUNC(RSA_F_RSA_MEMORY_LOCK), "RSA_memory_lock"},
+	{ERR_FUNC(RSA_F_RSA_NEW_METHOD), "RSA_new_method"},
+	{ERR_FUNC(RSA_F_RSA_NULL), "RSA_NULL"},
+	{ERR_FUNC(RSA_F_RSA_NULL_MOD_EXP), "RSA_NULL_MOD_EXP"},
+	{ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_DECRYPT), "RSA_NULL_PRIVATE_DECRYPT"},
+	{ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_ENCRYPT), "RSA_NULL_PRIVATE_ENCRYPT"},
+	{ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_DECRYPT), "RSA_NULL_PUBLIC_DECRYPT"},
+	{ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_ENCRYPT), "RSA_NULL_PUBLIC_ENCRYPT"},
+	{ERR_FUNC(RSA_F_RSA_PADDING_ADD_NONE), "RSA_padding_add_none"},
+	{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP), "RSA_padding_add_PKCS1_OAEP"},
+	{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS), "RSA_padding_add_PKCS1_PSS"},
+	{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1), "RSA_padding_add_PKCS1_PSS_mgf1"},
+	{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1), "RSA_padding_add_PKCS1_type_1"},
+	{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2), "RSA_padding_add_PKCS1_type_2"},
+	{ERR_FUNC(RSA_F_RSA_PADDING_ADD_SSLV23), "RSA_padding_add_SSLv23"},
+	{ERR_FUNC(RSA_F_RSA_PADDING_ADD_X931), "RSA_padding_add_X931"},
+	{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_NONE), "RSA_padding_check_none"},
+	{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP), "RSA_padding_check_PKCS1_OAEP"},
+	{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1), "RSA_padding_check_PKCS1_type_1"},
+	{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2), "RSA_padding_check_PKCS1_type_2"},
+	{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_SSLV23), "RSA_padding_check_SSLv23"},
+	{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931), "RSA_padding_check_X931"},
+	{ERR_FUNC(RSA_F_RSA_PRINT), "RSA_print"},
+	{ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"},
+	{ERR_FUNC(RSA_F_RSA_PRIVATE_DECRYPT), "RSA_private_decrypt"},
+	{ERR_FUNC(RSA_F_RSA_PRIVATE_ENCRYPT), "RSA_private_encrypt"},
+	{ERR_FUNC(RSA_F_RSA_PRIV_DECODE), "RSA_PRIV_DECODE"},
+	{ERR_FUNC(RSA_F_RSA_PRIV_ENCODE), "RSA_PRIV_ENCODE"},
+	{ERR_FUNC(RSA_F_RSA_PUBLIC_DECRYPT), "RSA_public_decrypt"},
+	{ERR_FUNC(RSA_F_RSA_PUBLIC_ENCRYPT), "RSA_public_encrypt"},
+	{ERR_FUNC(RSA_F_RSA_PUB_DECODE), "RSA_PUB_DECODE"},
+	{ERR_FUNC(RSA_F_RSA_SETUP_BLINDING), "RSA_setup_blinding"},
+	{ERR_FUNC(RSA_F_RSA_SIGN), "RSA_sign"},
+	{ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING), "RSA_sign_ASN1_OCTET_STRING"},
+	{ERR_FUNC(RSA_F_RSA_VERIFY), "RSA_verify"},
+	{ERR_FUNC(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING), "RSA_verify_ASN1_OCTET_STRING"},
+	{ERR_FUNC(RSA_F_RSA_VERIFY_PKCS1_PSS), "RSA_verify_PKCS1_PSS"},
+	{ERR_FUNC(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1), "RSA_verify_PKCS1_PSS_mgf1"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA RSA_str_reasons[] = {
+	{ERR_REASON(RSA_R_ALGORITHM_MISMATCH)    , "algorithm mismatch"},
+	{ERR_REASON(RSA_R_BAD_E_VALUE)           , "bad e value"},
+	{ERR_REASON(RSA_R_BAD_FIXED_HEADER_DECRYPT), "bad fixed header decrypt"},
+	{ERR_REASON(RSA_R_BAD_PAD_BYTE_COUNT)    , "bad pad byte count"},
+	{ERR_REASON(RSA_R_BAD_SIGNATURE)         , "bad signature"},
+	{ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_01)  , "block type is not 01"},
+	{ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_02)  , "block type is not 02"},
+	{ERR_REASON(RSA_R_DATA_GREATER_THAN_MOD_LEN), "data greater than mod len"},
+	{ERR_REASON(RSA_R_DATA_TOO_LARGE)        , "data too large"},
+	{ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE), "data too large for key size"},
+	{ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_MODULUS), "data too large for modulus"},
+	{ERR_REASON(RSA_R_DATA_TOO_SMALL)        , "data too small"},
+	{ERR_REASON(RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE), "data too small for key size"},
+	{ERR_REASON(RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY), "digest too big for rsa key"},
+	{ERR_REASON(RSA_R_DMP1_NOT_CONGRUENT_TO_D), "dmp1 not congruent to d"},
+	{ERR_REASON(RSA_R_DMQ1_NOT_CONGRUENT_TO_D), "dmq1 not congruent to d"},
+	{ERR_REASON(RSA_R_D_E_NOT_CONGRUENT_TO_1), "d e not congruent to 1"},
+	{ERR_REASON(RSA_R_FIRST_OCTET_INVALID)   , "first octet invalid"},
+	{ERR_REASON(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE), "illegal or unsupported padding mode"},
+	{ERR_REASON(RSA_R_INVALID_DIGEST_LENGTH) , "invalid digest length"},
+	{ERR_REASON(RSA_R_INVALID_HEADER)        , "invalid header"},
+	{ERR_REASON(RSA_R_INVALID_KEYBITS)       , "invalid keybits"},
+	{ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH), "invalid message length"},
+	{ERR_REASON(RSA_R_INVALID_MGF1_MD)       , "invalid mgf1 md"},
+	{ERR_REASON(RSA_R_INVALID_PADDING)       , "invalid padding"},
+	{ERR_REASON(RSA_R_INVALID_PADDING_MODE)  , "invalid padding mode"},
+	{ERR_REASON(RSA_R_INVALID_PSS_PARAMETERS), "invalid pss parameters"},
+	{ERR_REASON(RSA_R_INVALID_PSS_SALTLEN)   , "invalid pss saltlen"},
+	{ERR_REASON(RSA_R_INVALID_SALT_LENGTH)   , "invalid salt length"},
+	{ERR_REASON(RSA_R_INVALID_TRAILER)       , "invalid trailer"},
+	{ERR_REASON(RSA_R_INVALID_X931_DIGEST)   , "invalid x931 digest"},
+	{ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q) , "iqmp not inverse of q"},
+	{ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL)    , "key size too small"},
+	{ERR_REASON(RSA_R_LAST_OCTET_INVALID)    , "last octet invalid"},
+	{ERR_REASON(RSA_R_MODULUS_TOO_LARGE)     , "modulus too large"},
+	{ERR_REASON(RSA_R_NON_FIPS_RSA_METHOD)   , "non fips rsa method"},
+	{ERR_REASON(RSA_R_NO_PUBLIC_EXPONENT)    , "no public exponent"},
+	{ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING), "null before block missing"},
+	{ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q)  , "n does not equal p q"},
+	{ERR_REASON(RSA_R_OAEP_DECODING_ERROR)   , "oaep decoding error"},
+	{ERR_REASON(RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE), "operation not allowed in fips mode"},
+	{ERR_REASON(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), "operation not supported for this keytype"},
+	{ERR_REASON(RSA_R_PADDING_CHECK_FAILED)  , "padding check failed"},
+	{ERR_REASON(RSA_R_P_NOT_PRIME)           , "p not prime"},
+	{ERR_REASON(RSA_R_Q_NOT_PRIME)           , "q not prime"},
+	{ERR_REASON(RSA_R_RSA_OPERATIONS_NOT_SUPPORTED), "rsa operations not supported"},
+	{ERR_REASON(RSA_R_SLEN_CHECK_FAILED)     , "salt length check failed"},
+	{ERR_REASON(RSA_R_SLEN_RECOVERY_FAILED)  , "salt length recovery failed"},
+	{ERR_REASON(RSA_R_SSLV3_ROLLBACK_ATTACK) , "sslv3 rollback attack"},
+	{ERR_REASON(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD), "the asn1 object identifier is not known for this md"},
+	{ERR_REASON(RSA_R_UNKNOWN_ALGORITHM_TYPE), "unknown algorithm type"},
+	{ERR_REASON(RSA_R_UNKNOWN_MASK_DIGEST)   , "unknown mask digest"},
+	{ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE)  , "unknown padding type"},
+	{ERR_REASON(RSA_R_UNKNOWN_PSS_DIGEST)    , "unknown pss digest"},
+	{ERR_REASON(RSA_R_UNSUPPORTED_MASK_ALGORITHM), "unsupported mask algorithm"},
+	{ERR_REASON(RSA_R_UNSUPPORTED_MASK_PARAMETER), "unsupported mask parameter"},
+	{ERR_REASON(RSA_R_UNSUPPORTED_SIGNATURE_TYPE), "unsupported signature type"},
+	{ERR_REASON(RSA_R_VALUE_MISSING)         , "value missing"},
+	{ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"},
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_RSA_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(RSA_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, RSA_str_functs);
+		ERR_load_strings(0, RSA_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/rsa/rsa_gen.c b/crypto/libressl/crypto/rsa/rsa_gen.c
new file mode 100644
index 0000000000..cef8081561
--- /dev/null
+++ b/crypto/libressl/crypto/rsa/rsa_gen.c
@@ -0,0 +1,229 @@
+/* $OpenBSD: rsa_gen.c,v 1.17 2015/02/09 15:49:22 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+
+/* NB: these functions have been "upgraded", the deprecated versions (which are
+ * compatibility wrappers using these functions) are in rsa_depr.c.
+ * - Geoff
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb);
+
+/*
+ * NB: this wrapper would normally be placed in rsa_lib.c and the static
+ * implementation would probably be in rsa_eay.c. Nonetheless, is kept here so
+ * that we don't introduce a new linker dependency. Eg. any application that
+ * wasn't previously linking object code related to key-generation won't have to
+ * now just because key-generation is part of RSA_METHOD.
+ */
+int
+RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
+{
+	if (rsa->meth->rsa_keygen)
+		return rsa->meth->rsa_keygen(rsa, bits, e_value, cb);
+	return rsa_builtin_keygen(rsa, bits, e_value, cb);
+}
+
+static int
+rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
+{
+	BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp;
+	BIGNUM pr0, d, p;
+	int bitsp, bitsq, ok = -1, n = 0;
+	BN_CTX *ctx = NULL;
+
+	ctx = BN_CTX_new();
+	if (ctx == NULL)
+		goto err;
+	BN_CTX_start(ctx);
+	if ((r0 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((r1 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((r2 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+	if ((r3 = BN_CTX_get(ctx)) == NULL)
+		goto err;
+
+	bitsp = (bits + 1) / 2;
+	bitsq = bits - bitsp;
+
+	/* We need the RSA components non-NULL */
+	if (!rsa->n && ((rsa->n = BN_new()) == NULL))
+		goto err;
+	if (!rsa->d && ((rsa->d = BN_new()) == NULL))
+		goto err;
+	if (!rsa->e && ((rsa->e = BN_new()) == NULL))
+		goto err;
+	if (!rsa->p && ((rsa->p = BN_new()) == NULL))
+		goto err;
+	if (!rsa->q && ((rsa->q = BN_new()) == NULL))
+		goto err;
+	if (!rsa->dmp1 && ((rsa->dmp1 = BN_new()) == NULL))
+		goto err;
+	if (!rsa->dmq1 && ((rsa->dmq1 = BN_new()) == NULL))
+		goto err;
+	if (!rsa->iqmp && ((rsa->iqmp = BN_new()) == NULL))
+		goto err;
+
+	BN_copy(rsa->e, e_value);
+
+	/* generate p and q */
+	for (;;) {
+		if (!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb))
+			goto err;
+		if (!BN_sub(r2, rsa->p, BN_value_one()))
+			goto err;
+		if (!BN_gcd(r1, r2, rsa->e, ctx))
+			goto err;
+		if (BN_is_one(r1))
+			break;
+		if (!BN_GENCB_call(cb, 2, n++))
+			goto err;
+	}
+	if (!BN_GENCB_call(cb, 3, 0))
+		goto err;
+	for (;;) {
+		/*
+		 * When generating ridiculously small keys, we can get stuck
+		 * continually regenerating the same prime values. Check for
+		 * this and bail if it happens 3 times.
+		 */
+		unsigned int degenerate = 0;
+		do {
+			if (!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL,
+			    cb))
+				goto err;
+		} while (BN_cmp(rsa->p, rsa->q) == 0 &&
+		    ++degenerate < 3);
+		if (degenerate == 3) {
+			ok = 0; /* we set our own err */
+			RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,
+			    RSA_R_KEY_SIZE_TOO_SMALL);
+			goto err;
+		}
+		if (!BN_sub(r2, rsa->q, BN_value_one()))
+			goto err;
+		if (!BN_gcd(r1, r2, rsa->e, ctx))
+			goto err;
+		if (BN_is_one(r1))
+			break;
+		if (!BN_GENCB_call(cb, 2, n++))
+			goto err;
+	}
+	if (!BN_GENCB_call(cb, 3, 1))
+		goto err;
+	if (BN_cmp(rsa->p, rsa->q) < 0) {
+		tmp = rsa->p;
+		rsa->p = rsa->q;
+		rsa->q = tmp;
+	}
+
+	/* calculate n */
+	if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx))
+		goto err;
+
+	/* calculate d */
+	if (!BN_sub(r1, rsa->p, BN_value_one()))	/* p-1 */
+		goto err;
+	if (!BN_sub(r2, rsa->q, BN_value_one()))	/* q-1 */
+		goto err;
+	if (!BN_mul(r0, r1, r2, ctx))			/* (p-1)(q-1) */
+		goto err;
+
+	BN_with_flags(&pr0, r0, BN_FLG_CONSTTIME);
+
+	if (!BN_mod_inverse(rsa->d, rsa->e, &pr0, ctx)) /* d */
+		goto err;
+
+	/* set up d for correct BN_FLG_CONSTTIME flag */
+	BN_with_flags(&d, rsa->d, BN_FLG_CONSTTIME);
+
+	/* calculate d mod (p-1) */
+	if (!BN_mod(rsa->dmp1, &d, r1, ctx))
+		goto err;
+
+	/* calculate d mod (q-1) */
+	if (!BN_mod(rsa->dmq1, &d, r2, ctx))
+		goto err;
+
+	/* calculate inverse of q mod p */
+	BN_with_flags(&p, rsa->p, BN_FLG_CONSTTIME);
+	if (!BN_mod_inverse(rsa->iqmp, rsa->q, &p, ctx))
+		goto err;
+
+	ok = 1;
+err:
+	if (ok == -1) {
+		RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, ERR_LIB_BN);
+		ok = 0;
+	}
+	if (ctx != NULL) {
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+	}
+
+	return ok;
+}
diff --git a/crypto/libressl/crypto/rsa/rsa_lib.c b/crypto/libressl/crypto/rsa/rsa_lib.c
new file mode 100644
index 0000000000..f1a7e21969
--- /dev/null
+++ b/crypto/libressl/crypto/rsa/rsa_lib.c
@@ -0,0 +1,258 @@
+/* $OpenBSD: rsa_lib.c,v 1.29 2014/10/18 17:20:40 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+
+static const RSA_METHOD *default_RSA_meth = NULL;
+
+RSA *
+RSA_new(void)
+{
+	RSA *r = RSA_new_method(NULL);
+
+	return r;
+}
+
+void
+RSA_set_default_method(const RSA_METHOD *meth)
+{
+	default_RSA_meth = meth;
+}
+
+const RSA_METHOD *
+RSA_get_default_method(void)
+{
+	if (default_RSA_meth == NULL)
+		default_RSA_meth = RSA_PKCS1_SSLeay();
+
+	return default_RSA_meth;
+}
+
+const RSA_METHOD *
+RSA_get_method(const RSA *rsa)
+{
+	return rsa->meth;
+}
+
+int
+RSA_set_method(RSA *rsa, const RSA_METHOD *meth)
+{
+	/*
+	 * NB: The caller is specifically setting a method, so it's not up to us
+	 * to deal with which ENGINE it comes from.
+	 */
+	const RSA_METHOD *mtmp;
+
+	mtmp = rsa->meth;
+	if (mtmp->finish)
+		mtmp->finish(rsa);
+#ifndef OPENSSL_NO_ENGINE
+	if (rsa->engine) {
+		ENGINE_finish(rsa->engine);
+		rsa->engine = NULL;
+	}
+#endif
+	rsa->meth = meth;
+	if (meth->init)
+		meth->init(rsa);
+	return 1;
+}
+
+RSA *
+RSA_new_method(ENGINE *engine)
+{
+	RSA *ret;
+
+	ret = malloc(sizeof(RSA));
+	if (ret == NULL) {
+		RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+
+	ret->meth = RSA_get_default_method();
+#ifndef OPENSSL_NO_ENGINE
+	if (engine) {
+		if (!ENGINE_init(engine)) {
+			RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB);
+			free(ret);
+			return NULL;
+		}
+		ret->engine = engine;
+	} else
+		ret->engine = ENGINE_get_default_RSA();
+	if (ret->engine) {
+		ret->meth = ENGINE_get_RSA(ret->engine);
+		if (!ret->meth) {
+			RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB);
+			ENGINE_finish(ret->engine);
+			free(ret);
+			return NULL;
+		}
+	}
+#endif
+
+	ret->pad = 0;
+	ret->version = 0;
+	ret->n = NULL;
+	ret->e = NULL;
+	ret->d = NULL;
+	ret->p = NULL;
+	ret->q = NULL;
+	ret->dmp1 = NULL;
+	ret->dmq1 = NULL;
+	ret->iqmp = NULL;
+	ret->references = 1;
+	ret->_method_mod_n = NULL;
+	ret->_method_mod_p = NULL;
+	ret->_method_mod_q = NULL;
+	ret->blinding = NULL;
+	ret->mt_blinding = NULL;
+	ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW;
+	if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) {
+#ifndef OPENSSL_NO_ENGINE
+		if (ret->engine)
+			ENGINE_finish(ret->engine);
+#endif
+		free(ret);
+		return NULL;
+	}
+
+	if (ret->meth->init != NULL && !ret->meth->init(ret)) {
+#ifndef OPENSSL_NO_ENGINE
+		if (ret->engine)
+			ENGINE_finish(ret->engine);
+#endif
+		CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data);
+		free(ret);
+		ret = NULL;
+	}
+	return ret;
+}
+
+void
+RSA_free(RSA *r)
+{
+	int i;
+
+	if (r == NULL)
+		return;
+
+	i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_RSA);
+	if (i > 0)
+		return;
+
+	if (r->meth->finish)
+		r->meth->finish(r);
+#ifndef OPENSSL_NO_ENGINE
+	if (r->engine)
+		ENGINE_finish(r->engine);
+#endif
+
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data);
+
+	BN_clear_free(r->n);
+	BN_clear_free(r->e);
+	BN_clear_free(r->d);
+	BN_clear_free(r->p);
+	BN_clear_free(r->q);
+	BN_clear_free(r->dmp1);
+	BN_clear_free(r->dmq1);
+	BN_clear_free(r->iqmp);
+	BN_BLINDING_free(r->blinding);
+	BN_BLINDING_free(r->mt_blinding);
+	free(r);
+}
+
+int
+RSA_up_ref(RSA *r)
+{
+	int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_RSA);
+	return i > 1 ? 1 : 0;
+}
+
+int
+RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+    CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+{
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, argl, argp,
+	    new_func, dup_func, free_func);
+}
+
+int
+RSA_set_ex_data(RSA *r, int idx, void *arg)
+{
+	return CRYPTO_set_ex_data(&r->ex_data, idx, arg);
+}
+
+void *
+RSA_get_ex_data(const RSA *r, int idx)
+{
+	return CRYPTO_get_ex_data(&r->ex_data, idx);
+}
diff --git a/crypto/libressl/crypto/rsa/rsa_locl.h b/crypto/libressl/crypto/rsa/rsa_locl.h
new file mode 100644
index 0000000000..fe465308ea
--- /dev/null
+++ b/crypto/libressl/crypto/rsa/rsa_locl.h
@@ -0,0 +1,4 @@
+/* $OpenBSD: rsa_locl.h,v 1.2 2014/06/12 15:49:30 deraadt Exp $ */
+extern int int_rsa_verify(int dtype, const unsigned char *m,
+    unsigned int m_len, unsigned char *rm, size_t *prm_len,
+    const unsigned char *sigbuf, size_t siglen, RSA *rsa);
diff --git a/crypto/libressl/crypto/rsa/rsa_none.c b/crypto/libressl/crypto/rsa/rsa_none.c
new file mode 100644
index 0000000000..6c9803f902
--- /dev/null
+++ b/crypto/libressl/crypto/rsa/rsa_none.c
@@ -0,0 +1,98 @@
+/* $OpenBSD: rsa_none.c,v 1.9 2014/07/11 08:44:49 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+int
+RSA_padding_add_none(unsigned char *to, int tlen, const unsigned char *from,
+    int flen)
+{
+	if (flen > tlen) {
+		RSAerr(RSA_F_RSA_PADDING_ADD_NONE,
+		    RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+		return 0;
+	}
+
+	if (flen < tlen) {
+		RSAerr(RSA_F_RSA_PADDING_ADD_NONE,
+		    RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE);
+		return 0;
+	}
+
+	memcpy(to, from, flen);
+	return 1;
+}
+
+int
+RSA_padding_check_none(unsigned char *to, int tlen, const unsigned char *from,
+    int flen, int num)
+{
+	if (flen > tlen) {
+		RSAerr(RSA_F_RSA_PADDING_CHECK_NONE, RSA_R_DATA_TOO_LARGE);
+		return -1;
+	}
+
+	memset(to, 0, tlen - flen);
+	memcpy(to + tlen - flen, from, flen);
+	return tlen;
+}
diff --git a/crypto/libressl/crypto/rsa/rsa_oaep.c b/crypto/libressl/crypto/rsa/rsa_oaep.c
new file mode 100644
index 0000000000..024e16341c
--- /dev/null
+++ b/crypto/libressl/crypto/rsa/rsa_oaep.c
@@ -0,0 +1,236 @@
+/* $OpenBSD: rsa_oaep.c,v 1.24 2014/10/22 13:02:04 jsing Exp $ */
+/* Written by Ulf Moeller. This software is distributed on an "AS IS"
+   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. */
+
+/* EME-OAEP as defined in RFC 2437 (PKCS #1 v2.0) */
+
+/* See Victor Shoup, "OAEP reconsidered," Nov. 2000,
+ * 
+ * for problems with the security proof for the
+ * original OAEP scheme, which EME-OAEP is based on.
+ *
+ * A new proof can be found in E. Fujisaki, T. Okamoto,
+ * D. Pointcheval, J. Stern, "RSA-OEAP is Still Alive!",
+ * Dec. 2000, .
+ * The new proof has stronger requirements for the
+ * underlying permutation: "partial-one-wayness" instead
+ * of one-wayness.  For the RSA function, this is
+ * an equivalent notion.
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int MGF1(unsigned char *mask, long len, const unsigned char *seed,
+    long seedlen);
+
+int
+RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
+    const unsigned char *from, int flen, const unsigned char *param, int plen)
+{
+	int i, emlen = tlen - 1;
+	unsigned char *db, *seed;
+	unsigned char *dbmask, seedmask[SHA_DIGEST_LENGTH];
+
+	if (flen > emlen - 2 * SHA_DIGEST_LENGTH - 1) {
+		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP,
+		    RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+		return 0;
+	}
+
+	if (emlen < 2 * SHA_DIGEST_LENGTH + 1) {
+		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP,
+		    RSA_R_KEY_SIZE_TOO_SMALL);
+		return 0;
+	}
+
+	to[0] = 0;
+	seed = to + 1;
+	db = to + SHA_DIGEST_LENGTH + 1;
+
+	if (!EVP_Digest((void *)param, plen, db, NULL, EVP_sha1(), NULL))
+		return 0;
+	memset(db + SHA_DIGEST_LENGTH, 0,
+	    emlen - flen - 2 * SHA_DIGEST_LENGTH - 1);
+	db[emlen - flen - SHA_DIGEST_LENGTH - 1] = 0x01;
+	memcpy(db + emlen - flen - SHA_DIGEST_LENGTH, from, flen);
+	arc4random_buf(seed, SHA_DIGEST_LENGTH);
+
+	dbmask = malloc(emlen - SHA_DIGEST_LENGTH);
+	if (dbmask == NULL) {
+		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+
+	if (MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed,
+	    SHA_DIGEST_LENGTH) < 0)
+		return 0;
+	for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++)
+		db[i] ^= dbmask[i];
+
+	if (MGF1(seedmask, SHA_DIGEST_LENGTH, db,
+	    emlen - SHA_DIGEST_LENGTH) < 0)
+		return 0;
+	for (i = 0; i < SHA_DIGEST_LENGTH; i++)
+		seed[i] ^= seedmask[i];
+
+	free(dbmask);
+	return 1;
+}
+
+int
+RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
+    const unsigned char *from, int flen, int num, const unsigned char *param,
+    int plen)
+{
+	int i, dblen, mlen = -1;
+	const unsigned char *maskeddb;
+	int lzero;
+	unsigned char *db = NULL;
+	unsigned char seed[SHA_DIGEST_LENGTH], phash[SHA_DIGEST_LENGTH];
+	unsigned char *padded_from;
+	int bad = 0;
+
+	if (--num < 2 * SHA_DIGEST_LENGTH + 1)
+		/*
+		 * 'num' is the length of the modulus, i.e. does not depend
+		 * on the particular ciphertext.
+		 */
+		goto decoding_err;
+
+	lzero = num - flen;
+	if (lzero < 0) {
+		/*
+		 * signalling this error immediately after detection might allow
+		 * for side-channel attacks (e.g. timing if 'plen' is huge
+		 * -- cf. James H. Manger, "A Chosen Ciphertext Attack on RSA
+		 * Optimal Asymmetric Encryption Padding (OAEP) [...]",
+		 * CRYPTO 2001), so we use a 'bad' flag
+		 */
+		bad = 1;
+		lzero = 0;
+		flen = num; /* don't overflow the memcpy to padded_from */
+	}
+
+	dblen = num - SHA_DIGEST_LENGTH;
+	db = malloc(dblen + num);
+	if (db == NULL) {
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP,
+		    ERR_R_MALLOC_FAILURE);
+		return -1;
+	}
+
+	/*
+	 * Always do this zero-padding copy (even when lzero == 0)
+	 * to avoid leaking timing info about the value of lzero.
+	 */
+	padded_from = db + dblen;
+	memset(padded_from, 0, lzero);
+	memcpy(padded_from + lzero, from, flen);
+
+	maskeddb = padded_from + SHA_DIGEST_LENGTH;
+
+	if (MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen))
+		return -1;
+	for (i = 0; i < SHA_DIGEST_LENGTH; i++)
+		seed[i] ^= padded_from[i];
+
+	if (MGF1(db, dblen, seed, SHA_DIGEST_LENGTH))
+		return -1;
+	for (i = 0; i < dblen; i++)
+		db[i] ^= maskeddb[i];
+
+	if (!EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL))
+		return -1;
+
+	if (timingsafe_memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
+		goto decoding_err;
+	else {
+		for (i = SHA_DIGEST_LENGTH; i < dblen; i++)
+			if (db[i] != 0x00)
+				break;
+		if (i == dblen || db[i] != 0x01)
+			goto decoding_err;
+		else {
+			/* everything looks OK */
+
+			mlen = dblen - ++i;
+			if (tlen < mlen) {
+				RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP,
+				    RSA_R_DATA_TOO_LARGE);
+				mlen = -1;
+			} else
+				memcpy(to, db + i, mlen);
+		}
+	}
+	free(db);
+	return mlen;
+
+decoding_err:
+	/*
+	 * To avoid chosen ciphertext attacks, the error message should not
+	 * reveal which kind of decoding error happened
+	 */
+	RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_OAEP_DECODING_ERROR);
+	free(db);
+	return -1;
+}
+
+int
+PKCS1_MGF1(unsigned char *mask, long len, const unsigned char *seed,
+    long seedlen, const EVP_MD *dgst)
+{
+	long i, outlen = 0;
+	unsigned char cnt[4];
+	EVP_MD_CTX c;
+	unsigned char md[EVP_MAX_MD_SIZE];
+	int mdlen;
+	int rv = -1;
+
+	EVP_MD_CTX_init(&c);
+	mdlen = EVP_MD_size(dgst);
+	if (mdlen < 0)
+		goto err;
+	for (i = 0; outlen < len; i++) {
+		cnt[0] = (unsigned char)((i >> 24) & 255);
+		cnt[1] = (unsigned char)((i >> 16) & 255);
+		cnt[2] = (unsigned char)((i >> 8)) & 255;
+		cnt[3] = (unsigned char)(i & 255);
+		if (!EVP_DigestInit_ex(&c, dgst, NULL) ||
+		    !EVP_DigestUpdate(&c, seed, seedlen) ||
+		    !EVP_DigestUpdate(&c, cnt, 4))
+			goto err;
+		if (outlen + mdlen <= len) {
+			if (!EVP_DigestFinal_ex(&c, mask + outlen, NULL))
+				goto err;
+			outlen += mdlen;
+		} else {
+			if (!EVP_DigestFinal_ex(&c, md, NULL))
+				goto err;
+			memcpy(mask + outlen, md, len - outlen);
+			outlen = len;
+		}
+	}
+	rv = 0;
+err:
+	EVP_MD_CTX_cleanup(&c);
+	return rv;
+}
+
+static int
+MGF1(unsigned char *mask, long len, const unsigned char *seed, long seedlen)
+{
+	return PKCS1_MGF1(mask, len, seed, seedlen, EVP_sha1());
+}
+#endif
diff --git a/crypto/libressl/crypto/rsa/rsa_pk1.c b/crypto/libressl/crypto/rsa/rsa_pk1.c
new file mode 100644
index 0000000000..61f35804ef
--- /dev/null
+++ b/crypto/libressl/crypto/rsa/rsa_pk1.c
@@ -0,0 +1,224 @@
+/* $OpenBSD: rsa_pk1.c,v 1.13 2014/07/11 08:44:49 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+int
+RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen,
+    const unsigned char *from, int flen)
+{
+	int j;
+	unsigned char *p;
+
+	if (flen > (tlen - RSA_PKCS1_PADDING_SIZE)) {
+		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1,
+		    RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+		return 0;
+	}
+
+	p = (unsigned char *)to;
+
+	*(p++) = 0;
+	*(p++) = 1; /* Private Key BT (Block Type) */
+
+	/* pad out with 0xff data */
+	j = tlen - 3 - flen;
+	memset(p, 0xff, j);
+	p += j;
+	*(p++) = '\0';
+	memcpy(p, from, flen);
+
+	return 1;
+}
+
+int
+RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen,
+    const unsigned char *from, int flen, int num)
+{
+	int i, j;
+	const unsigned char *p;
+
+	p = from;
+	if (num != flen + 1 || *(p++) != 01) {
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,
+		    RSA_R_BLOCK_TYPE_IS_NOT_01);
+		return -1;
+	}
+
+	/* scan over padding data */
+	j = flen - 1; /* one for type. */
+	for (i = 0; i < j; i++) {
+		if (*p != 0xff) {
+			/* should decrypt to 0xff */
+			if (*p == 0) {
+				p++;
+				break;
+			} else {
+				RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,
+				    RSA_R_BAD_FIXED_HEADER_DECRYPT);
+				return -1;
+			}
+		}
+		p++;
+	}
+
+	if (i == j) {
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,
+		    RSA_R_NULL_BEFORE_BLOCK_MISSING);
+		return -1;
+	}
+
+	if (i < 8) {
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,
+		    RSA_R_BAD_PAD_BYTE_COUNT);
+		return -1;
+	}
+	i++; /* Skip over the '\0' */
+	j -= i;
+	if (j > tlen) {
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,
+		    RSA_R_DATA_TOO_LARGE);
+		return -1;
+	}
+	memcpy(to, p, j);
+
+	return j;
+}
+
+int
+RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen,
+    const unsigned char *from, int flen)
+{
+	int i, j;
+	unsigned char *p;
+
+	if (flen > tlen - 11) {
+		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2,
+		    RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+		return 0;
+	}
+
+	p = (unsigned char *)to;
+
+	*(p++) = 0;
+	*(p++) = 2; /* Public Key BT (Block Type) */
+
+	/* pad out with non-zero random data */
+	j = tlen - 3 - flen;
+
+	arc4random_buf(p, j);
+	for (i = 0; i < j; i++) {
+		while (*p == '\0')
+			arc4random_buf(p, 1);
+		p++;
+	}
+
+	*(p++) = '\0';
+
+	memcpy(p, from, flen);
+	return 1;
+}
+
+int
+RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
+    const unsigned char *from, int flen, int num)
+{
+	int i, j;
+	const unsigned char *p;
+
+	p = from;
+	if (num != flen + 1 || *(p++) != 02) {
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,
+		    RSA_R_BLOCK_TYPE_IS_NOT_02);
+		return -1;
+	}
+
+	/* scan over padding data */
+	j = flen - 1; /* one for type. */
+	for (i = 0; i < j; i++)
+		if (*(p++) == 0)
+			break;
+
+	if (i == j) {
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,
+		    RSA_R_NULL_BEFORE_BLOCK_MISSING);
+		return -1;
+	}
+
+	if (i < 8) {
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,
+		    RSA_R_BAD_PAD_BYTE_COUNT);
+		return -1;
+	}
+	i++; /* Skip over the '\0' */
+	j -= i;
+	if (j > tlen) {
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,
+		    RSA_R_DATA_TOO_LARGE);
+		return -1;
+	}
+	memcpy(to, p, j);
+
+	return j;
+}
diff --git a/crypto/libressl/crypto/rsa/rsa_pmeth.c b/crypto/libressl/crypto/rsa/rsa_pmeth.c
new file mode 100644
index 0000000000..e6327803d3
--- /dev/null
+++ b/crypto/libressl/crypto/rsa/rsa_pmeth.c
@@ -0,0 +1,616 @@
+/* $OpenBSD: rsa_pmeth.c,v 1.16 2015/02/11 04:05:14 beck Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_CMS
+#include 
+#endif
+
+#include "evp_locl.h"
+#include "rsa_locl.h"
+
+/* RSA pkey context structure */
+
+typedef struct {
+	/* Key gen parameters */
+	int nbits;
+	BIGNUM *pub_exp;
+	/* Keygen callback info */
+	int gentmp[2];
+	/* RSA padding mode */
+	int pad_mode;
+	/* message digest */
+	const EVP_MD *md;
+	/* message digest for MGF1 */
+	const EVP_MD *mgf1md;
+	/* PSS/OAEP salt length */
+	int saltlen;
+	/* Temp buffer */
+	unsigned char *tbuf;
+} RSA_PKEY_CTX;
+
+static int
+pkey_rsa_init(EVP_PKEY_CTX *ctx)
+{
+	RSA_PKEY_CTX *rctx;
+
+	rctx = malloc(sizeof(RSA_PKEY_CTX));
+	if (!rctx)
+		return 0;
+	rctx->nbits = 2048;
+	rctx->pub_exp = NULL;
+	rctx->pad_mode = RSA_PKCS1_PADDING;
+	rctx->md = NULL;
+	rctx->mgf1md = NULL;
+	rctx->tbuf = NULL;
+
+	rctx->saltlen = -2;
+
+	ctx->data = rctx;
+	ctx->keygen_info = rctx->gentmp;
+	ctx->keygen_info_count = 2;
+
+	return 1;
+}
+
+static int
+pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+{
+	RSA_PKEY_CTX *dctx, *sctx;
+
+	if (!pkey_rsa_init(dst))
+		return 0;
+	sctx = src->data;
+	dctx = dst->data;
+	dctx->nbits = sctx->nbits;
+	if (sctx->pub_exp) {
+		dctx->pub_exp = BN_dup(sctx->pub_exp);
+		if (!dctx->pub_exp)
+			return 0;
+	}
+	dctx->pad_mode = sctx->pad_mode;
+	dctx->md = sctx->md;
+	return 1;
+}
+
+static int
+setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk)
+{
+	if (ctx->tbuf)
+		return 1;
+	ctx->tbuf = malloc(EVP_PKEY_size(pk->pkey));
+	if (!ctx->tbuf)
+		return 0;
+	return 1;
+}
+
+static void
+pkey_rsa_cleanup(EVP_PKEY_CTX *ctx)
+{
+	RSA_PKEY_CTX *rctx = ctx->data;
+
+	if (rctx) {
+		BN_free(rctx->pub_exp);
+		free(rctx->tbuf);
+		free(rctx);
+	}
+}
+
+static int
+pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+    const unsigned char *tbs, size_t tbslen)
+{
+	int ret;
+	RSA_PKEY_CTX *rctx = ctx->data;
+	RSA *rsa = ctx->pkey->pkey.rsa;
+
+	if (rctx->md) {
+		if (tbslen != (size_t)EVP_MD_size(rctx->md)) {
+			RSAerr(RSA_F_PKEY_RSA_SIGN,
+			    RSA_R_INVALID_DIGEST_LENGTH);
+			return -1;
+		}
+
+		if (rctx->pad_mode == RSA_X931_PADDING) {
+			if (!setup_tbuf(rctx, ctx))
+				return -1;
+			memcpy(rctx->tbuf, tbs, tbslen);
+			rctx->tbuf[tbslen] =
+			    RSA_X931_hash_id(EVP_MD_type(rctx->md));
+			ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, sig,
+			    rsa, RSA_X931_PADDING);
+		} else if (rctx->pad_mode == RSA_PKCS1_PADDING) {
+			unsigned int sltmp;
+
+			ret = RSA_sign(EVP_MD_type(rctx->md), tbs, tbslen, sig,
+			    &sltmp, rsa);
+			if (ret <= 0)
+				return ret;
+			ret = sltmp;
+		} else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) {
+			if (!setup_tbuf(rctx, ctx))
+				return -1;
+			if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, rctx->tbuf,
+			    tbs, rctx->md, rctx->mgf1md, rctx->saltlen))
+				return -1;
+			ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf,
+			    sig, rsa, RSA_NO_PADDING);
+		} else
+			return -1;
+	} else
+		ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
+		    rctx->pad_mode);
+	if (ret < 0)
+		return ret;
+	*siglen = ret;
+	return 1;
+}
+
+static int
+pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx, unsigned char *rout, size_t *routlen,
+    const unsigned char *sig, size_t siglen)
+{
+	int ret;
+	RSA_PKEY_CTX *rctx = ctx->data;
+
+	if (rctx->md) {
+		if (rctx->pad_mode == RSA_X931_PADDING) {
+			if (!setup_tbuf(rctx, ctx))
+				return -1;
+			ret = RSA_public_decrypt(siglen, sig, rctx->tbuf,
+			    ctx->pkey->pkey.rsa, RSA_X931_PADDING);
+			if (ret < 1)
+				return 0;
+			ret--;
+			if (rctx->tbuf[ret] !=
+				RSA_X931_hash_id(EVP_MD_type(rctx->md))) {
+				RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
+				    RSA_R_ALGORITHM_MISMATCH);
+				return 0;
+			}
+			if (ret != EVP_MD_size(rctx->md)) {
+				RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
+				    RSA_R_INVALID_DIGEST_LENGTH);
+				return 0;
+			}
+			if (rout)
+				memcpy(rout, rctx->tbuf, ret);
+		} else if (rctx->pad_mode == RSA_PKCS1_PADDING) {
+			size_t sltmp;
+
+			ret = int_rsa_verify(EVP_MD_type(rctx->md), NULL, 0,
+			    rout, &sltmp, sig, siglen, ctx->pkey->pkey.rsa);
+			if (ret <= 0)
+				return 0;
+			ret = sltmp;
+		} else
+			return -1;
+	} else
+		ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa,
+		    rctx->pad_mode);
+	if (ret < 0)
+		return ret;
+	*routlen = ret;
+	return 1;
+}
+
+static int
+pkey_rsa_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
+    const unsigned char *tbs, size_t tbslen)
+{
+	RSA_PKEY_CTX *rctx = ctx->data;
+	RSA *rsa = ctx->pkey->pkey.rsa;
+	size_t rslen;
+
+	if (rctx->md) {
+		if (rctx->pad_mode == RSA_PKCS1_PADDING)
+			return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
+			    sig, siglen, rsa);
+		if (rctx->pad_mode == RSA_X931_PADDING) {
+			if (pkey_rsa_verifyrecover(ctx, NULL, &rslen, sig,
+			    siglen) <= 0)
+				return 0;
+		} else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) {
+			int ret;
+
+			if (!setup_tbuf(rctx, ctx))
+				return -1;
+			ret = RSA_public_decrypt(siglen, sig, rctx->tbuf,
+			    rsa, RSA_NO_PADDING);
+			if (ret <= 0)
+				return 0;
+			ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs, rctx->md,
+			    rctx->mgf1md, rctx->tbuf, rctx->saltlen);
+			if (ret <= 0)
+				return 0;
+			return 1;
+		} else
+			return -1;
+	} else {
+		if (!setup_tbuf(rctx, ctx))
+			return -1;
+		rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf, rsa,
+		    rctx->pad_mode);
+		if (rslen == 0)
+			return 0;
+	}
+
+	if (rslen != tbslen || memcmp(tbs, rctx->tbuf, rslen))
+		return 0;
+
+	return 1;
+}
+
+static int
+pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+    const unsigned char *in, size_t inlen)
+{
+	int ret;
+	RSA_PKEY_CTX *rctx = ctx->data;
+
+	ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa,
+	    rctx->pad_mode);
+	if (ret < 0)
+		return ret;
+	*outlen = ret;
+	return 1;
+}
+
+static int
+pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+    const unsigned char *in, size_t inlen)
+{
+	int ret;
+	RSA_PKEY_CTX *rctx = ctx->data;
+
+	ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa,
+	    rctx->pad_mode);
+	if (ret < 0)
+		return ret;
+	*outlen = ret;
+	return 1;
+}
+
+static int
+check_padding_md(const EVP_MD *md, int padding)
+{
+	if (!md)
+		return 1;
+
+	if (padding == RSA_NO_PADDING) {
+		RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE);
+		return 0;
+	}
+
+	if (padding == RSA_X931_PADDING) {
+		if (RSA_X931_hash_id(EVP_MD_type(md)) == -1) {
+			RSAerr(RSA_F_CHECK_PADDING_MD,
+			    RSA_R_INVALID_X931_DIGEST);
+			return 0;
+		}
+		return 1;
+	}
+
+	return 1;
+}
+
+static int
+pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+	RSA_PKEY_CTX *rctx = ctx->data;
+
+	switch (type) {
+	case EVP_PKEY_CTRL_RSA_PADDING:
+		if (p1 >= RSA_PKCS1_PADDING && p1 <= RSA_PKCS1_PSS_PADDING) {
+			if (!check_padding_md(rctx->md, p1))
+				return 0;
+			if (p1 == RSA_PKCS1_PSS_PADDING) {
+				if (!(ctx->operation &
+				    (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY)))
+					goto bad_pad;
+				if (!rctx->md)
+					rctx->md = EVP_sha1();
+			}
+			if (p1 == RSA_PKCS1_OAEP_PADDING) {
+				if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))
+					goto bad_pad;
+				if (!rctx->md)
+					rctx->md = EVP_sha1();
+			}
+			rctx->pad_mode = p1;
+			return 1;
+		}
+bad_pad:
+		RSAerr(RSA_F_PKEY_RSA_CTRL,
+		    RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
+		return -2;
+
+	case EVP_PKEY_CTRL_GET_RSA_PADDING:
+		*(int *)p2 = rctx->pad_mode;
+		return 1;
+
+	case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
+	case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN:
+		if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) {
+			RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN);
+			return -2;
+		}
+		if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN)
+			*(int *)p2 = rctx->saltlen;
+		else {
+			if (p1 < -2)
+				return -2;
+			rctx->saltlen = p1;
+		}
+		return 1;
+
+	case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
+		if (p1 < 256) {
+			RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS);
+			return -2;
+		}
+		rctx->nbits = p1;
+		return 1;
+
+	case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
+		if (!p2)
+			return -2;
+		rctx->pub_exp = p2;
+		return 1;
+
+	case EVP_PKEY_CTRL_MD:
+		if (!check_padding_md(p2, rctx->pad_mode))
+			return 0;
+		rctx->md = p2;
+		return 1;
+
+	case EVP_PKEY_CTRL_RSA_MGF1_MD:
+	case EVP_PKEY_CTRL_GET_RSA_MGF1_MD:
+		if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) {
+			RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_MGF1_MD);
+			return -2;
+		}
+		if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) {
+			if (rctx->mgf1md)
+				*(const EVP_MD **)p2 = rctx->mgf1md;
+			else
+				*(const EVP_MD **)p2 = rctx->md;
+		} else
+			rctx->mgf1md = p2;
+		return 1;
+
+	case EVP_PKEY_CTRL_DIGESTINIT:
+	case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
+	case EVP_PKEY_CTRL_PKCS7_DECRYPT:
+	case EVP_PKEY_CTRL_PKCS7_SIGN:
+		return 1;
+#ifndef OPENSSL_NO_CMS
+	case EVP_PKEY_CTRL_CMS_DECRYPT:
+		{
+			X509_ALGOR *alg = NULL;
+			ASN1_OBJECT *encalg = NULL;
+
+			if (p2)
+				CMS_RecipientInfo_ktri_get0_algs(p2, NULL,
+				    NULL, &alg);
+			if (alg)
+				X509_ALGOR_get0(&encalg, NULL, NULL, alg);
+			if (encalg && OBJ_obj2nid(encalg) == NID_rsaesOaep)
+				rctx->pad_mode = RSA_PKCS1_OAEP_PADDING;
+		}
+		/* FALLTHROUGH */
+
+	case EVP_PKEY_CTRL_CMS_ENCRYPT:
+	case EVP_PKEY_CTRL_CMS_SIGN:
+		return 1;
+#endif
+	case EVP_PKEY_CTRL_PEER_KEY:
+		RSAerr(RSA_F_PKEY_RSA_CTRL,
+		    RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+		return -2;
+
+	default:
+		return -2;
+	}
+}
+
+static int
+pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value)
+{
+	long lval;
+	char *ep;
+
+	if (!value) {
+		RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING);
+		return 0;
+	}
+	if (!strcmp(type, "rsa_padding_mode")) {
+		int pm;
+		if (!strcmp(value, "pkcs1"))
+			pm = RSA_PKCS1_PADDING;
+		else if (!strcmp(value, "sslv23"))
+			pm = RSA_SSLV23_PADDING;
+		else if (!strcmp(value, "none"))
+			pm = RSA_NO_PADDING;
+		else if (!strcmp(value, "oeap"))
+			pm = RSA_PKCS1_OAEP_PADDING;
+		else if (!strcmp(value, "oaep"))
+			pm = RSA_PKCS1_OAEP_PADDING;
+		else if (!strcmp(value, "x931"))
+			pm = RSA_X931_PADDING;
+		else if (!strcmp(value, "pss"))
+			pm = RSA_PKCS1_PSS_PADDING;
+		else {
+			RSAerr(RSA_F_PKEY_RSA_CTRL_STR,
+			    RSA_R_UNKNOWN_PADDING_TYPE);
+			return -2;
+		}
+		return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
+	}
+
+	if (!strcmp(type, "rsa_pss_saltlen")) {
+		int saltlen;
+
+		errno = 0;
+		lval = strtol(value, &ep, 10);
+		if (value[0] == '\0' || *ep != '\0')
+			goto not_a_number;
+		if ((errno == ERANGE &&
+		    (lval == LONG_MAX || lval == LONG_MIN)) ||
+		    (lval > INT_MAX || lval < INT_MIN))
+			goto out_of_range;
+		saltlen = lval;
+		return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen);
+	}
+
+	if (!strcmp(type, "rsa_keygen_bits")) {
+		int nbits;
+
+		errno = 0;
+		lval = strtol(value, &ep, 10);
+		if (value[0] == '\0' || *ep != '\0')
+			goto not_a_number;
+		if ((errno == ERANGE &&
+		    (lval == LONG_MAX || lval == LONG_MIN)) ||
+		    (lval > INT_MAX || lval < INT_MIN))
+			goto out_of_range;
+		nbits = lval;
+		return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits);
+	}
+
+	if (!strcmp(type, "rsa_keygen_pubexp")) {
+		int ret;
+		BIGNUM *pubexp = NULL;
+
+		if (!BN_asc2bn(&pubexp, value))
+			return 0;
+		ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp);
+		if (ret <= 0)
+			BN_free(pubexp);
+		return ret;
+	}
+
+not_a_number:
+out_of_range:
+	return -2;
+}
+
+static int
+pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+	RSA *rsa = NULL;
+	RSA_PKEY_CTX *rctx = ctx->data;
+	BN_GENCB *pcb, cb;
+	int ret;
+
+	if (!rctx->pub_exp) {
+		rctx->pub_exp = BN_new();
+		if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4))
+			return 0;
+	}
+	rsa = RSA_new();
+	if (!rsa)
+		return 0;
+	if (ctx->pkey_gencb) {
+		pcb = &cb;
+		evp_pkey_set_cb_translate(pcb, ctx);
+	} else
+		pcb = NULL;
+	ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb);
+	if (ret > 0)
+		EVP_PKEY_assign_RSA(pkey, rsa);
+	else
+		RSA_free(rsa);
+	return ret;
+}
+
+const EVP_PKEY_METHOD rsa_pkey_meth = {
+	.pkey_id = EVP_PKEY_RSA,
+	.flags = EVP_PKEY_FLAG_AUTOARGLEN,
+
+	.init = pkey_rsa_init,
+	.copy = pkey_rsa_copy,
+	.cleanup = pkey_rsa_cleanup,
+
+	.keygen = pkey_rsa_keygen,
+
+	.sign = pkey_rsa_sign,
+
+	.verify = pkey_rsa_verify,
+
+	.verify_recover = pkey_rsa_verifyrecover,
+
+	.encrypt = pkey_rsa_encrypt,
+
+	.decrypt = pkey_rsa_decrypt,
+
+	.ctrl = pkey_rsa_ctrl,
+	.ctrl_str = pkey_rsa_ctrl_str
+};
diff --git a/crypto/libressl/crypto/rsa/rsa_prn.c b/crypto/libressl/crypto/rsa/rsa_prn.c
new file mode 100644
index 0000000000..8e98801569
--- /dev/null
+++ b/crypto/libressl/crypto/rsa/rsa_prn.c
@@ -0,0 +1,93 @@
+/* $OpenBSD: rsa_prn.c,v 1.5 2014/07/09 19:51:38 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+int
+RSA_print_fp(FILE *fp, const RSA *x, int off)
+{
+	BIO *b;
+	int ret;
+
+	if ((b = BIO_new(BIO_s_file())) == NULL) {
+		RSAerr(RSA_F_RSA_PRINT_FP, ERR_R_BUF_LIB);
+		return 0;
+	}
+	BIO_set_fp(b, fp, BIO_NOCLOSE);
+	ret = RSA_print(b, x, off);
+	BIO_free(b);
+	return ret;
+}
+
+int
+RSA_print(BIO *bp, const RSA *x, int off)
+{
+	EVP_PKEY *pk;
+	int ret;
+
+	pk = EVP_PKEY_new();
+	if (!pk || !EVP_PKEY_set1_RSA(pk, (RSA *)x))
+		return 0;
+	ret = EVP_PKEY_print_private(bp, pk, off, NULL);
+	EVP_PKEY_free(pk);
+	return ret;
+}
diff --git a/crypto/libressl/crypto/rsa/rsa_pss.c b/crypto/libressl/crypto/rsa/rsa_pss.c
new file mode 100644
index 0000000000..32b325b671
--- /dev/null
+++ b/crypto/libressl/crypto/rsa/rsa_pss.c
@@ -0,0 +1,289 @@
+/* $OpenBSD: rsa_pss.c,v 1.10 2014/07/13 12:53:46 miod Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static const unsigned char zeroes[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+int
+RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, const EVP_MD *Hash,
+    const unsigned char *EM, int sLen)
+{
+	return RSA_verify_PKCS1_PSS_mgf1(rsa, mHash, Hash, NULL, EM, sLen);
+}
+
+int
+RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
+    const EVP_MD *Hash, const EVP_MD *mgf1Hash, const unsigned char *EM,
+    int sLen)
+{
+	int i;
+	int ret = 0;
+	int hLen, maskedDBLen, MSBits, emLen;
+	const unsigned char *H;
+	unsigned char *DB = NULL;
+	EVP_MD_CTX ctx;
+	unsigned char H_[EVP_MAX_MD_SIZE];
+
+	EVP_MD_CTX_init(&ctx);
+
+	if (mgf1Hash == NULL)
+		mgf1Hash = Hash;
+
+	hLen = EVP_MD_size(Hash);
+	if (hLen < 0)
+		goto err;
+	/*
+	 * Negative sLen has special meanings:
+	 *	-1	sLen == hLen
+	 *	-2	salt length is autorecovered from signature
+	 *	-N	reserved
+	 */
+	if (sLen == -1)
+		sLen = hLen;
+	else if (sLen == -2)
+		sLen = -2;
+	else if (sLen < -2) {
+		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1,
+		    RSA_R_SLEN_CHECK_FAILED);
+		goto err;
+	}
+
+	MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
+	emLen = RSA_size(rsa);
+	if (EM[0] & (0xFF << MSBits)) {
+		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1,
+		    RSA_R_FIRST_OCTET_INVALID);
+		goto err;
+	}
+	if (MSBits == 0) {
+		EM++;
+		emLen--;
+	}
+	if (emLen < (hLen + sLen + 2)) {
+		/* sLen can be small negative */
+		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE);
+		goto err;
+	}
+	if (EM[emLen - 1] != 0xbc) {
+		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1,
+		    RSA_R_LAST_OCTET_INVALID);
+		goto err;
+	}
+	maskedDBLen = emLen - hLen - 1;
+	H = EM + maskedDBLen;
+	DB = malloc(maskedDBLen);
+	if (!DB) {
+		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0)
+		goto err;
+	for (i = 0; i < maskedDBLen; i++)
+		DB[i] ^= EM[i];
+	if (MSBits)
+		DB[0] &= 0xFF >> (8 - MSBits);
+	for (i = 0; DB[i] == 0 && i < (maskedDBLen - 1); i++)
+		;
+	if (DB[i++] != 0x1) {
+		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1,
+		    RSA_R_SLEN_RECOVERY_FAILED);
+		goto err;
+	}
+	if (sLen >= 0 && (maskedDBLen - i) != sLen) {
+		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1,
+		    RSA_R_SLEN_CHECK_FAILED);
+		goto err;
+	}
+	if (!EVP_DigestInit_ex(&ctx, Hash, NULL) ||
+	    !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes) ||
+	    !EVP_DigestUpdate(&ctx, mHash, hLen))
+		goto err;
+	if (maskedDBLen - i) {
+		if (!EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i))
+			goto err;
+	}
+	if (!EVP_DigestFinal_ex(&ctx, H_, NULL))
+		goto err;
+	if (memcmp(H_, H, hLen)) {
+		RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_BAD_SIGNATURE);
+		ret = 0;
+	} else
+		ret = 1;
+
+err:
+	free(DB);
+	EVP_MD_CTX_cleanup(&ctx);
+
+	return ret;
+}
+
+int
+RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
+    const unsigned char *mHash, const EVP_MD *Hash, int sLen)
+{
+	return RSA_padding_add_PKCS1_PSS_mgf1(rsa, EM, mHash, Hash, NULL, sLen);
+}
+
+int
+RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
+    const unsigned char *mHash, const EVP_MD *Hash, const EVP_MD *mgf1Hash,
+    int sLen)
+{
+	int i;
+	int ret = 0;
+	int hLen, maskedDBLen, MSBits, emLen;
+	unsigned char *H, *salt = NULL, *p;
+	EVP_MD_CTX ctx;
+
+	EVP_MD_CTX_init(&ctx);
+
+	if (mgf1Hash == NULL)
+		mgf1Hash = Hash;
+
+	hLen = EVP_MD_size(Hash);
+	if (hLen < 0)
+		goto err;
+	/*
+	 * Negative sLen has special meanings:
+	 *	-1	sLen == hLen
+	 *	-2	salt length is maximized
+	 *	-N	reserved
+	 */
+	if (sLen == -1)
+		sLen = hLen;
+	else if (sLen == -2)
+		sLen = -2;
+	else if (sLen < -2) {
+		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
+		    RSA_R_SLEN_CHECK_FAILED);
+		goto err;
+	}
+
+	MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
+	emLen = RSA_size(rsa);
+	if (MSBits == 0) {
+		*EM++ = 0;
+		emLen--;
+	}
+	if (sLen == -2)
+		sLen = emLen - hLen - 2;
+	else if (emLen < (hLen + sLen + 2)) {
+		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
+		    RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+		goto err;
+	}
+	if (sLen > 0) {
+		salt = malloc(sLen);
+		if (!salt) {
+			RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
+			    ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+		arc4random_buf(salt, sLen);
+	}
+	maskedDBLen = emLen - hLen - 1;
+	H = EM + maskedDBLen;
+	if (!EVP_DigestInit_ex(&ctx, Hash, NULL) ||
+	    !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes) ||
+	    !EVP_DigestUpdate(&ctx, mHash, hLen))
+		goto err;
+	if (sLen && !EVP_DigestUpdate(&ctx, salt, sLen))
+		goto err;
+	if (!EVP_DigestFinal_ex(&ctx, H, NULL))
+		goto err;
+
+	/* Generate dbMask in place then perform XOR on it */
+	if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash))
+		goto err;
+
+	p = EM;
+
+	/*
+	 * Initial PS XORs with all zeroes which is a NOP so just update
+	 * pointer. Note from a test above this value is guaranteed to
+	 * be non-negative.
+	 */
+	p += emLen - sLen - hLen - 2;
+	*p++ ^= 0x1;
+	if (sLen > 0) {
+		for (i = 0; i < sLen; i++)
+			*p++ ^= salt[i];
+	}
+	if (MSBits)
+		EM[0] &= 0xFF >> (8 - MSBits);
+
+	/* H is already in place so just set final 0xbc */
+	EM[emLen - 1] = 0xbc;
+
+	ret = 1;
+
+err:
+	free(salt);
+	EVP_MD_CTX_cleanup(&ctx);
+
+	return ret;
+}
diff --git a/crypto/libressl/crypto/rsa/rsa_saos.c b/crypto/libressl/crypto/rsa/rsa_saos.c
new file mode 100644
index 0000000000..902fd42355
--- /dev/null
+++ b/crypto/libressl/crypto/rsa/rsa_saos.c
@@ -0,0 +1,149 @@
+/* $OpenBSD: rsa_saos.c,v 1.18 2015/09/10 15:56:25 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+int
+RSA_sign_ASN1_OCTET_STRING(int type, const unsigned char *m, unsigned int m_len,
+    unsigned char *sigret, unsigned int *siglen, RSA *rsa)
+{
+	ASN1_OCTET_STRING sig;
+	int i, j, ret = 1;
+	unsigned char *p, *s;
+
+	sig.type = V_ASN1_OCTET_STRING;
+	sig.length = m_len;
+	sig.data = (unsigned char *)m;
+
+	i = i2d_ASN1_OCTET_STRING(&sig, NULL);
+	j = RSA_size(rsa);
+	if (i > (j - RSA_PKCS1_PADDING_SIZE)) {
+		RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING,
+		    RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
+		return 0;
+	}
+	s = malloc(j + 1);
+	if (s == NULL) {
+		RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	p = s;
+	i2d_ASN1_OCTET_STRING(&sig, &p);
+	i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING);
+	if (i <= 0)
+		ret = 0;
+	else
+		*siglen = i;
+
+	explicit_bzero(s, (unsigned int)j + 1);
+	free(s);
+	return ret;
+}
+
+int
+RSA_verify_ASN1_OCTET_STRING(int dtype, const unsigned char *m,
+    unsigned int m_len, unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
+{
+	int i, ret = 0;
+	unsigned char *s;
+	const unsigned char *p;
+	ASN1_OCTET_STRING *sig = NULL;
+
+	if (siglen != (unsigned int)RSA_size(rsa)) {
+		RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING,
+		    RSA_R_WRONG_SIGNATURE_LENGTH);
+		return 0;
+	}
+
+	s = malloc(siglen);
+	if (s == NULL) {
+		RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING,
+		    ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING);
+
+	if (i <= 0)
+		goto err;
+
+	p = s;
+	sig = d2i_ASN1_OCTET_STRING(NULL, &p, (long)i);
+	if (sig == NULL)
+		goto err;
+
+	if ((unsigned int)sig->length != m_len ||
+	    memcmp(m, sig->data, m_len) != 0) {
+		RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING,
+		    RSA_R_BAD_SIGNATURE);
+	} else
+		ret = 1;
+err:
+	ASN1_OCTET_STRING_free(sig);
+	if (s != NULL) {
+		explicit_bzero(s, (unsigned int)siglen);
+		free(s);
+	}
+	return ret;
+}
diff --git a/crypto/libressl/crypto/rsa/rsa_sign.c b/crypto/libressl/crypto/rsa/rsa_sign.c
new file mode 100644
index 0000000000..564c619854
--- /dev/null
+++ b/crypto/libressl/crypto/rsa/rsa_sign.c
@@ -0,0 +1,255 @@
+/* $OpenBSD: rsa_sign.c,v 1.24 2015/07/19 18:29:31 miod Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "rsa_locl.h"
+
+/* Size of an SSL signature: MD5+SHA1 */
+#define SSL_SIG_LENGTH	36
+
+int
+RSA_sign(int type, const unsigned char *m, unsigned int m_len,
+    unsigned char *sigret, unsigned int *siglen, RSA *rsa)
+{
+	X509_SIG sig;
+	ASN1_TYPE parameter;
+	int i, j, ret = 1;
+	unsigned char *p, *tmps = NULL;
+	const unsigned char *s = NULL;
+	X509_ALGOR algor;
+	ASN1_OCTET_STRING digest;
+
+	if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign)
+		return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa);
+
+	/* Special case: SSL signature, just check the length */
+	if (type == NID_md5_sha1) {
+		if (m_len != SSL_SIG_LENGTH) {
+			RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH);
+			return 0;
+		}
+		i = SSL_SIG_LENGTH;
+		s = m;
+	} else {
+		sig.algor = &algor;
+		sig.algor->algorithm = OBJ_nid2obj(type);
+		if (sig.algor->algorithm == NULL) {
+			RSAerr(RSA_F_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE);
+			return 0;
+		}
+		if (sig.algor->algorithm->length == 0) {
+			RSAerr(RSA_F_RSA_SIGN,
+			    RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
+			return 0;
+		}
+		parameter.type = V_ASN1_NULL;
+		parameter.value.ptr = NULL;
+		sig.algor->parameter = ¶meter;
+
+		sig.digest = &digest;
+		sig.digest->data = (unsigned char *)m; /* TMP UGLY CAST */
+		sig.digest->length = m_len;
+
+		i = i2d_X509_SIG(&sig, NULL);
+	}
+	j = RSA_size(rsa);
+	if (i > j - RSA_PKCS1_PADDING_SIZE) {
+		RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
+		return 0;
+	}
+	if (type != NID_md5_sha1) {
+		tmps = malloc(j + 1);
+		if (tmps == NULL) {
+			RSAerr(RSA_F_RSA_SIGN, ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+		p = tmps;
+		i2d_X509_SIG(&sig, &p);
+		s = tmps;
+	}
+	i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING);
+	if (i <= 0)
+		ret = 0;
+	else
+		*siglen = i;
+
+	if (type != NID_md5_sha1) {
+		explicit_bzero(tmps, (unsigned int)j + 1);
+		free(tmps);
+	}
+	return (ret);
+}
+
+int
+int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
+    unsigned char *rm, size_t *prm_len, const unsigned char *sigbuf,
+    size_t siglen, RSA *rsa)
+{
+	int i, ret = 0, sigtype;
+	unsigned char *s;
+	X509_SIG *sig = NULL;
+
+	if (siglen != (unsigned int)RSA_size(rsa)) {
+		RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH);
+		return 0;
+	}
+
+	if ((dtype == NID_md5_sha1) && rm) {
+		i = RSA_public_decrypt((int)siglen, sigbuf, rm, rsa,
+		    RSA_PKCS1_PADDING);
+		if (i <= 0)
+			return 0;
+		*prm_len = i;
+		return 1;
+	}
+
+	s = malloc(siglen);
+	if (s == NULL) {
+		RSAerr(RSA_F_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	if (dtype == NID_md5_sha1 && m_len != SSL_SIG_LENGTH) {
+		RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH);
+		goto err;
+	}
+	i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING);
+
+	if (i <= 0)
+		goto err;
+
+	/* Special case: SSL signature */
+	if (dtype == NID_md5_sha1) {
+		if (i != SSL_SIG_LENGTH || memcmp(s, m, SSL_SIG_LENGTH))
+			RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
+		else
+			ret = 1;
+	} else {
+		const unsigned char *p = s;
+
+		sig = d2i_X509_SIG(NULL, &p, (long)i);
+
+		if (sig == NULL)
+			goto err;
+
+		/* Excess data can be used to create forgeries */
+		if (p != s + i) {
+			RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
+			goto err;
+		}
+
+		/* Parameters to the signature algorithm can also be used to
+		   create forgeries */
+		if (sig->algor->parameter &&
+		    ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) {
+			RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
+			goto err;
+		}
+
+		sigtype = OBJ_obj2nid(sig->algor->algorithm);
+
+		if (sigtype != dtype) {
+			RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH);
+			goto err;
+		}
+		if (rm) {
+			const EVP_MD *md;
+
+			md = EVP_get_digestbynid(dtype);
+			if (md && (EVP_MD_size(md) != sig->digest->length))
+				RSAerr(RSA_F_INT_RSA_VERIFY,
+				    RSA_R_INVALID_DIGEST_LENGTH);
+			else {
+				memcpy(rm, sig->digest->data,
+				    sig->digest->length);
+				*prm_len = sig->digest->length;
+				ret = 1;
+			}
+		} else if ((unsigned int)sig->digest->length != m_len ||
+		    memcmp(m, sig->digest->data, m_len) != 0) {
+			RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
+		} else
+			ret = 1;
+	}
+err:
+	if (sig != NULL)
+		X509_SIG_free(sig);
+	if (s != NULL) {
+		explicit_bzero(s, (unsigned int)siglen);
+		free(s);
+	}
+	return ret;
+}
+
+int
+RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
+    const unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
+{
+	if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify)
+		return rsa->meth->rsa_verify(dtype, m, m_len, sigbuf, siglen,
+		    rsa);
+
+	return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa);
+}
diff --git a/crypto/libressl/crypto/rsa/rsa_ssl.c b/crypto/libressl/crypto/rsa/rsa_ssl.c
new file mode 100644
index 0000000000..4b16b4ad02
--- /dev/null
+++ b/crypto/libressl/crypto/rsa/rsa_ssl.c
@@ -0,0 +1,151 @@
+/* $OpenBSD: rsa_ssl.c,v 1.13 2014/07/11 08:44:49 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+int
+RSA_padding_add_SSLv23(unsigned char *to, int tlen, const unsigned char *from,
+    int flen)
+{
+	int i, j;
+	unsigned char *p;
+
+	if (flen > tlen - 11) {
+		RSAerr(RSA_F_RSA_PADDING_ADD_SSLV23,
+		    RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+		return 0;
+	}
+
+	p = (unsigned char *)to;
+
+	*(p++) = 0;
+	*(p++) = 2; /* Public Key BT (Block Type) */
+
+	/* pad out with non-zero random data */
+	j = tlen - 3 - 8 - flen;
+
+	arc4random_buf(p, j);
+	for (i = 0; i < j; i++) {
+		while (*p == '\0')
+			arc4random_buf(p, 1);
+		p++;
+	}
+
+	memset(p, 3, 8);
+	p += 8;
+	*(p++) = '\0';
+
+	memcpy(p, from, flen);
+	return 1;
+}
+
+int
+RSA_padding_check_SSLv23(unsigned char *to, int tlen, const unsigned char *from,
+    int flen, int num)
+{
+	int i, j, k;
+	const unsigned char *p;
+
+	p = from;
+	if (flen < 10) {
+		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_SMALL);
+		return -1;
+	}
+	if (num != flen + 1 || *(p++) != 02) {
+		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,
+		    RSA_R_BLOCK_TYPE_IS_NOT_02);
+		return -1;
+	}
+
+	/* scan over padding data */
+	j = flen - 1; /* one for type */
+	for (i = 0; i < j; i++)
+		if (*(p++) == 0)
+			break;
+
+	if (i == j || i < 8) {
+		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,
+		    RSA_R_NULL_BEFORE_BLOCK_MISSING);
+		return -1;
+	}
+	for (k = -9; k < -1; k++) {
+		if (p[k] !=  0x03)
+			break;
+	}
+	if (k == -1) {
+		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,
+		    RSA_R_SSLV3_ROLLBACK_ATTACK);
+		return -1;
+	}
+
+	i++; /* Skip over the '\0' */
+	j -= i;
+	if (j > tlen) {
+		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_LARGE);
+		return -1;
+	}
+	memcpy(to, p, j);
+
+	return j;
+}
diff --git a/crypto/libressl/crypto/rsa/rsa_x931.c b/crypto/libressl/crypto/rsa/rsa_x931.c
new file mode 100644
index 0000000000..9b83f0cce0
--- /dev/null
+++ b/crypto/libressl/crypto/rsa/rsa_x931.c
@@ -0,0 +1,167 @@
+/* $OpenBSD: rsa_x931.c,v 1.8 2014/07/11 08:44:49 jsing Exp $ */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+int
+RSA_padding_add_X931(unsigned char *to, int tlen, const unsigned char *from,
+    int flen)
+{
+	int j;
+	unsigned char *p;
+
+	/*
+	 * Absolute minimum amount of padding is 1 header nibble, 1 padding
+	 * nibble and 2 trailer bytes: but 1 hash if is already in 'from'.
+	 */
+	j = tlen - flen - 2;
+
+	if (j < 0) {
+		RSAerr(RSA_F_RSA_PADDING_ADD_X931,
+		    RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+		return -1;
+	}
+
+	p = (unsigned char *)to;
+
+	/* If no padding start and end nibbles are in one byte */
+	if (j == 0)
+		*p++ = 0x6A;
+	else {
+		*p++ = 0x6B;
+		if (j > 1) {
+			memset(p, 0xBB, j - 1);
+			p += j - 1;
+		}
+		*p++ = 0xBA;
+	}
+	memcpy(p, from, flen);
+	p += flen;
+	*p = 0xCC;
+	return 1;
+}
+
+int
+RSA_padding_check_X931(unsigned char *to, int tlen, const unsigned char *from,
+    int flen, int num)
+{
+	int i = 0, j;
+	const unsigned char *p = from;
+
+	if (num != flen || (*p != 0x6A && *p != 0x6B)) {
+		RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_HEADER);
+		return -1;
+	}
+
+	if (*p++ == 0x6B) {
+		j = flen - 3;
+		for (i = 0; i < j; i++) {
+			unsigned char c = *p++;
+			if (c == 0xBA)
+				break;
+			if (c != 0xBB) {
+				RSAerr(RSA_F_RSA_PADDING_CHECK_X931,
+				    RSA_R_INVALID_PADDING);
+				return -1;
+			}
+		}
+
+		if (i == 0) {
+			RSAerr(RSA_F_RSA_PADDING_CHECK_X931,
+			    RSA_R_INVALID_PADDING);
+			return -1;
+		}
+
+		j -= i;
+	} else
+		j = flen - 2;
+
+	if (j < 0 || p[j] != 0xCC) {
+		RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_TRAILER);
+		return -1;
+	}
+
+	memcpy(to, p, j);
+
+	return j;
+}
+
+/* Translate between X931 hash ids and NIDs */
+
+int
+RSA_X931_hash_id(int nid)
+{
+	switch (nid) {
+	case NID_sha1:
+		return 0x33;
+	case NID_sha256:
+		return 0x34;
+	case NID_sha384:
+		return 0x36;
+	case NID_sha512:
+		return 0x35;
+	}
+
+	return -1;
+}
diff --git a/crypto/libressl/crypto/sha/sha1-elf-x86_64.s b/crypto/libressl/crypto/sha/sha1-elf-x86_64.s
new file mode 100644
index 0000000000..e3c3ec47d4
--- /dev/null
+++ b/crypto/libressl/crypto/sha/sha1-elf-x86_64.s
@@ -0,0 +1,2489 @@
+.text	
+
+
+.globl	sha1_block_data_order
+.type	sha1_block_data_order,@function
+.align	16
+sha1_block_data_order:
+	movl	OPENSSL_ia32cap_P+0(%rip),%r9d
+	movl	OPENSSL_ia32cap_P+4(%rip),%r8d
+	testl	$512,%r8d
+	jz	.Lialu
+	jmp	_ssse3_shortcut
+
+.align	16
+.Lialu:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	movq	%rsp,%r11
+	movq	%rdi,%r8
+	subq	$72,%rsp
+	movq	%rsi,%r9
+	andq	$-64,%rsp
+	movq	%rdx,%r10
+	movq	%r11,64(%rsp)
+.Lprologue:
+
+	movl	0(%r8),%esi
+	movl	4(%r8),%edi
+	movl	8(%r8),%r11d
+	movl	12(%r8),%r12d
+	movl	16(%r8),%r13d
+	jmp	.Lloop
+
+.align	16
+.Lloop:
+	movl	0(%r9),%edx
+	bswapl	%edx
+	movl	%edx,0(%rsp)
+	movl	%r11d,%eax
+	movl	4(%r9),%ebp
+	movl	%esi,%ecx
+	xorl	%r12d,%eax
+	bswapl	%ebp
+	roll	$5,%ecx
+	leal	1518500249(%rdx,%r13,1),%r13d
+	andl	%edi,%eax
+	movl	%ebp,4(%rsp)
+	addl	%ecx,%r13d
+	xorl	%r12d,%eax
+	roll	$30,%edi
+	addl	%eax,%r13d
+	movl	%edi,%eax
+	movl	8(%r9),%edx
+	movl	%r13d,%ecx
+	xorl	%r11d,%eax
+	bswapl	%edx
+	roll	$5,%ecx
+	leal	1518500249(%rbp,%r12,1),%r12d
+	andl	%esi,%eax
+	movl	%edx,8(%rsp)
+	addl	%ecx,%r12d
+	xorl	%r11d,%eax
+	roll	$30,%esi
+	addl	%eax,%r12d
+	movl	%esi,%eax
+	movl	12(%r9),%ebp
+	movl	%r12d,%ecx
+	xorl	%edi,%eax
+	bswapl	%ebp
+	roll	$5,%ecx
+	leal	1518500249(%rdx,%r11,1),%r11d
+	andl	%r13d,%eax
+	movl	%ebp,12(%rsp)
+	addl	%ecx,%r11d
+	xorl	%edi,%eax
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	movl	%r13d,%eax
+	movl	16(%r9),%edx
+	movl	%r11d,%ecx
+	xorl	%esi,%eax
+	bswapl	%edx
+	roll	$5,%ecx
+	leal	1518500249(%rbp,%rdi,1),%edi
+	andl	%r12d,%eax
+	movl	%edx,16(%rsp)
+	addl	%ecx,%edi
+	xorl	%esi,%eax
+	roll	$30,%r12d
+	addl	%eax,%edi
+	movl	%r12d,%eax
+	movl	20(%r9),%ebp
+	movl	%edi,%ecx
+	xorl	%r13d,%eax
+	bswapl	%ebp
+	roll	$5,%ecx
+	leal	1518500249(%rdx,%rsi,1),%esi
+	andl	%r11d,%eax
+	movl	%ebp,20(%rsp)
+	addl	%ecx,%esi
+	xorl	%r13d,%eax
+	roll	$30,%r11d
+	addl	%eax,%esi
+	movl	%r11d,%eax
+	movl	24(%r9),%edx
+	movl	%esi,%ecx
+	xorl	%r12d,%eax
+	bswapl	%edx
+	roll	$5,%ecx
+	leal	1518500249(%rbp,%r13,1),%r13d
+	andl	%edi,%eax
+	movl	%edx,24(%rsp)
+	addl	%ecx,%r13d
+	xorl	%r12d,%eax
+	roll	$30,%edi
+	addl	%eax,%r13d
+	movl	%edi,%eax
+	movl	28(%r9),%ebp
+	movl	%r13d,%ecx
+	xorl	%r11d,%eax
+	bswapl	%ebp
+	roll	$5,%ecx
+	leal	1518500249(%rdx,%r12,1),%r12d
+	andl	%esi,%eax
+	movl	%ebp,28(%rsp)
+	addl	%ecx,%r12d
+	xorl	%r11d,%eax
+	roll	$30,%esi
+	addl	%eax,%r12d
+	movl	%esi,%eax
+	movl	32(%r9),%edx
+	movl	%r12d,%ecx
+	xorl	%edi,%eax
+	bswapl	%edx
+	roll	$5,%ecx
+	leal	1518500249(%rbp,%r11,1),%r11d
+	andl	%r13d,%eax
+	movl	%edx,32(%rsp)
+	addl	%ecx,%r11d
+	xorl	%edi,%eax
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	movl	%r13d,%eax
+	movl	36(%r9),%ebp
+	movl	%r11d,%ecx
+	xorl	%esi,%eax
+	bswapl	%ebp
+	roll	$5,%ecx
+	leal	1518500249(%rdx,%rdi,1),%edi
+	andl	%r12d,%eax
+	movl	%ebp,36(%rsp)
+	addl	%ecx,%edi
+	xorl	%esi,%eax
+	roll	$30,%r12d
+	addl	%eax,%edi
+	movl	%r12d,%eax
+	movl	40(%r9),%edx
+	movl	%edi,%ecx
+	xorl	%r13d,%eax
+	bswapl	%edx
+	roll	$5,%ecx
+	leal	1518500249(%rbp,%rsi,1),%esi
+	andl	%r11d,%eax
+	movl	%edx,40(%rsp)
+	addl	%ecx,%esi
+	xorl	%r13d,%eax
+	roll	$30,%r11d
+	addl	%eax,%esi
+	movl	%r11d,%eax
+	movl	44(%r9),%ebp
+	movl	%esi,%ecx
+	xorl	%r12d,%eax
+	bswapl	%ebp
+	roll	$5,%ecx
+	leal	1518500249(%rdx,%r13,1),%r13d
+	andl	%edi,%eax
+	movl	%ebp,44(%rsp)
+	addl	%ecx,%r13d
+	xorl	%r12d,%eax
+	roll	$30,%edi
+	addl	%eax,%r13d
+	movl	%edi,%eax
+	movl	48(%r9),%edx
+	movl	%r13d,%ecx
+	xorl	%r11d,%eax
+	bswapl	%edx
+	roll	$5,%ecx
+	leal	1518500249(%rbp,%r12,1),%r12d
+	andl	%esi,%eax
+	movl	%edx,48(%rsp)
+	addl	%ecx,%r12d
+	xorl	%r11d,%eax
+	roll	$30,%esi
+	addl	%eax,%r12d
+	movl	%esi,%eax
+	movl	52(%r9),%ebp
+	movl	%r12d,%ecx
+	xorl	%edi,%eax
+	bswapl	%ebp
+	roll	$5,%ecx
+	leal	1518500249(%rdx,%r11,1),%r11d
+	andl	%r13d,%eax
+	movl	%ebp,52(%rsp)
+	addl	%ecx,%r11d
+	xorl	%edi,%eax
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	movl	%r13d,%eax
+	movl	56(%r9),%edx
+	movl	%r11d,%ecx
+	xorl	%esi,%eax
+	bswapl	%edx
+	roll	$5,%ecx
+	leal	1518500249(%rbp,%rdi,1),%edi
+	andl	%r12d,%eax
+	movl	%edx,56(%rsp)
+	addl	%ecx,%edi
+	xorl	%esi,%eax
+	roll	$30,%r12d
+	addl	%eax,%edi
+	movl	%r12d,%eax
+	movl	60(%r9),%ebp
+	movl	%edi,%ecx
+	xorl	%r13d,%eax
+	bswapl	%ebp
+	roll	$5,%ecx
+	leal	1518500249(%rdx,%rsi,1),%esi
+	andl	%r11d,%eax
+	movl	%ebp,60(%rsp)
+	addl	%ecx,%esi
+	xorl	%r13d,%eax
+	roll	$30,%r11d
+	addl	%eax,%esi
+	movl	0(%rsp),%edx
+	movl	%r11d,%eax
+	movl	%esi,%ecx
+	xorl	8(%rsp),%edx
+	xorl	%r12d,%eax
+	roll	$5,%ecx
+	xorl	32(%rsp),%edx
+	andl	%edi,%eax
+	leal	1518500249(%rbp,%r13,1),%r13d
+	xorl	52(%rsp),%edx
+	xorl	%r12d,%eax
+	roll	$1,%edx
+	addl	%ecx,%r13d
+	roll	$30,%edi
+	movl	%edx,0(%rsp)
+	addl	%eax,%r13d
+	movl	4(%rsp),%ebp
+	movl	%edi,%eax
+	movl	%r13d,%ecx
+	xorl	12(%rsp),%ebp
+	xorl	%r11d,%eax
+	roll	$5,%ecx
+	xorl	36(%rsp),%ebp
+	andl	%esi,%eax
+	leal	1518500249(%rdx,%r12,1),%r12d
+	xorl	56(%rsp),%ebp
+	xorl	%r11d,%eax
+	roll	$1,%ebp
+	addl	%ecx,%r12d
+	roll	$30,%esi
+	movl	%ebp,4(%rsp)
+	addl	%eax,%r12d
+	movl	8(%rsp),%edx
+	movl	%esi,%eax
+	movl	%r12d,%ecx
+	xorl	16(%rsp),%edx
+	xorl	%edi,%eax
+	roll	$5,%ecx
+	xorl	40(%rsp),%edx
+	andl	%r13d,%eax
+	leal	1518500249(%rbp,%r11,1),%r11d
+	xorl	60(%rsp),%edx
+	xorl	%edi,%eax
+	roll	$1,%edx
+	addl	%ecx,%r11d
+	roll	$30,%r13d
+	movl	%edx,8(%rsp)
+	addl	%eax,%r11d
+	movl	12(%rsp),%ebp
+	movl	%r13d,%eax
+	movl	%r11d,%ecx
+	xorl	20(%rsp),%ebp
+	xorl	%esi,%eax
+	roll	$5,%ecx
+	xorl	44(%rsp),%ebp
+	andl	%r12d,%eax
+	leal	1518500249(%rdx,%rdi,1),%edi
+	xorl	0(%rsp),%ebp
+	xorl	%esi,%eax
+	roll	$1,%ebp
+	addl	%ecx,%edi
+	roll	$30,%r12d
+	movl	%ebp,12(%rsp)
+	addl	%eax,%edi
+	movl	16(%rsp),%edx
+	movl	%r12d,%eax
+	movl	%edi,%ecx
+	xorl	24(%rsp),%edx
+	xorl	%r13d,%eax
+	roll	$5,%ecx
+	xorl	48(%rsp),%edx
+	andl	%r11d,%eax
+	leal	1518500249(%rbp,%rsi,1),%esi
+	xorl	4(%rsp),%edx
+	xorl	%r13d,%eax
+	roll	$1,%edx
+	addl	%ecx,%esi
+	roll	$30,%r11d
+	movl	%edx,16(%rsp)
+	addl	%eax,%esi
+	movl	20(%rsp),%ebp
+	movl	%r11d,%eax
+	movl	%esi,%ecx
+	xorl	28(%rsp),%ebp
+	xorl	%edi,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rdx,%r13,1),%r13d
+	xorl	52(%rsp),%ebp
+	xorl	%r12d,%eax
+	addl	%ecx,%r13d
+	xorl	8(%rsp),%ebp
+	roll	$30,%edi
+	addl	%eax,%r13d
+	roll	$1,%ebp
+	movl	%ebp,20(%rsp)
+	movl	24(%rsp),%edx
+	movl	%edi,%eax
+	movl	%r13d,%ecx
+	xorl	32(%rsp),%edx
+	xorl	%esi,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rbp,%r12,1),%r12d
+	xorl	56(%rsp),%edx
+	xorl	%r11d,%eax
+	addl	%ecx,%r12d
+	xorl	12(%rsp),%edx
+	roll	$30,%esi
+	addl	%eax,%r12d
+	roll	$1,%edx
+	movl	%edx,24(%rsp)
+	movl	28(%rsp),%ebp
+	movl	%esi,%eax
+	movl	%r12d,%ecx
+	xorl	36(%rsp),%ebp
+	xorl	%r13d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rdx,%r11,1),%r11d
+	xorl	60(%rsp),%ebp
+	xorl	%edi,%eax
+	addl	%ecx,%r11d
+	xorl	16(%rsp),%ebp
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	roll	$1,%ebp
+	movl	%ebp,28(%rsp)
+	movl	32(%rsp),%edx
+	movl	%r13d,%eax
+	movl	%r11d,%ecx
+	xorl	40(%rsp),%edx
+	xorl	%r12d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rbp,%rdi,1),%edi
+	xorl	0(%rsp),%edx
+	xorl	%esi,%eax
+	addl	%ecx,%edi
+	xorl	20(%rsp),%edx
+	roll	$30,%r12d
+	addl	%eax,%edi
+	roll	$1,%edx
+	movl	%edx,32(%rsp)
+	movl	36(%rsp),%ebp
+	movl	%r12d,%eax
+	movl	%edi,%ecx
+	xorl	44(%rsp),%ebp
+	xorl	%r11d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rdx,%rsi,1),%esi
+	xorl	4(%rsp),%ebp
+	xorl	%r13d,%eax
+	addl	%ecx,%esi
+	xorl	24(%rsp),%ebp
+	roll	$30,%r11d
+	addl	%eax,%esi
+	roll	$1,%ebp
+	movl	%ebp,36(%rsp)
+	movl	40(%rsp),%edx
+	movl	%r11d,%eax
+	movl	%esi,%ecx
+	xorl	48(%rsp),%edx
+	xorl	%edi,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rbp,%r13,1),%r13d
+	xorl	8(%rsp),%edx
+	xorl	%r12d,%eax
+	addl	%ecx,%r13d
+	xorl	28(%rsp),%edx
+	roll	$30,%edi
+	addl	%eax,%r13d
+	roll	$1,%edx
+	movl	%edx,40(%rsp)
+	movl	44(%rsp),%ebp
+	movl	%edi,%eax
+	movl	%r13d,%ecx
+	xorl	52(%rsp),%ebp
+	xorl	%esi,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rdx,%r12,1),%r12d
+	xorl	12(%rsp),%ebp
+	xorl	%r11d,%eax
+	addl	%ecx,%r12d
+	xorl	32(%rsp),%ebp
+	roll	$30,%esi
+	addl	%eax,%r12d
+	roll	$1,%ebp
+	movl	%ebp,44(%rsp)
+	movl	48(%rsp),%edx
+	movl	%esi,%eax
+	movl	%r12d,%ecx
+	xorl	56(%rsp),%edx
+	xorl	%r13d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rbp,%r11,1),%r11d
+	xorl	16(%rsp),%edx
+	xorl	%edi,%eax
+	addl	%ecx,%r11d
+	xorl	36(%rsp),%edx
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	roll	$1,%edx
+	movl	%edx,48(%rsp)
+	movl	52(%rsp),%ebp
+	movl	%r13d,%eax
+	movl	%r11d,%ecx
+	xorl	60(%rsp),%ebp
+	xorl	%r12d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rdx,%rdi,1),%edi
+	xorl	20(%rsp),%ebp
+	xorl	%esi,%eax
+	addl	%ecx,%edi
+	xorl	40(%rsp),%ebp
+	roll	$30,%r12d
+	addl	%eax,%edi
+	roll	$1,%ebp
+	movl	%ebp,52(%rsp)
+	movl	56(%rsp),%edx
+	movl	%r12d,%eax
+	movl	%edi,%ecx
+	xorl	0(%rsp),%edx
+	xorl	%r11d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rbp,%rsi,1),%esi
+	xorl	24(%rsp),%edx
+	xorl	%r13d,%eax
+	addl	%ecx,%esi
+	xorl	44(%rsp),%edx
+	roll	$30,%r11d
+	addl	%eax,%esi
+	roll	$1,%edx
+	movl	%edx,56(%rsp)
+	movl	60(%rsp),%ebp
+	movl	%r11d,%eax
+	movl	%esi,%ecx
+	xorl	4(%rsp),%ebp
+	xorl	%edi,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rdx,%r13,1),%r13d
+	xorl	28(%rsp),%ebp
+	xorl	%r12d,%eax
+	addl	%ecx,%r13d
+	xorl	48(%rsp),%ebp
+	roll	$30,%edi
+	addl	%eax,%r13d
+	roll	$1,%ebp
+	movl	%ebp,60(%rsp)
+	movl	0(%rsp),%edx
+	movl	%edi,%eax
+	movl	%r13d,%ecx
+	xorl	8(%rsp),%edx
+	xorl	%esi,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rbp,%r12,1),%r12d
+	xorl	32(%rsp),%edx
+	xorl	%r11d,%eax
+	addl	%ecx,%r12d
+	xorl	52(%rsp),%edx
+	roll	$30,%esi
+	addl	%eax,%r12d
+	roll	$1,%edx
+	movl	%edx,0(%rsp)
+	movl	4(%rsp),%ebp
+	movl	%esi,%eax
+	movl	%r12d,%ecx
+	xorl	12(%rsp),%ebp
+	xorl	%r13d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rdx,%r11,1),%r11d
+	xorl	36(%rsp),%ebp
+	xorl	%edi,%eax
+	addl	%ecx,%r11d
+	xorl	56(%rsp),%ebp
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	roll	$1,%ebp
+	movl	%ebp,4(%rsp)
+	movl	8(%rsp),%edx
+	movl	%r13d,%eax
+	movl	%r11d,%ecx
+	xorl	16(%rsp),%edx
+	xorl	%r12d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rbp,%rdi,1),%edi
+	xorl	40(%rsp),%edx
+	xorl	%esi,%eax
+	addl	%ecx,%edi
+	xorl	60(%rsp),%edx
+	roll	$30,%r12d
+	addl	%eax,%edi
+	roll	$1,%edx
+	movl	%edx,8(%rsp)
+	movl	12(%rsp),%ebp
+	movl	%r12d,%eax
+	movl	%edi,%ecx
+	xorl	20(%rsp),%ebp
+	xorl	%r11d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rdx,%rsi,1),%esi
+	xorl	44(%rsp),%ebp
+	xorl	%r13d,%eax
+	addl	%ecx,%esi
+	xorl	0(%rsp),%ebp
+	roll	$30,%r11d
+	addl	%eax,%esi
+	roll	$1,%ebp
+	movl	%ebp,12(%rsp)
+	movl	16(%rsp),%edx
+	movl	%r11d,%eax
+	movl	%esi,%ecx
+	xorl	24(%rsp),%edx
+	xorl	%edi,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rbp,%r13,1),%r13d
+	xorl	48(%rsp),%edx
+	xorl	%r12d,%eax
+	addl	%ecx,%r13d
+	xorl	4(%rsp),%edx
+	roll	$30,%edi
+	addl	%eax,%r13d
+	roll	$1,%edx
+	movl	%edx,16(%rsp)
+	movl	20(%rsp),%ebp
+	movl	%edi,%eax
+	movl	%r13d,%ecx
+	xorl	28(%rsp),%ebp
+	xorl	%esi,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rdx,%r12,1),%r12d
+	xorl	52(%rsp),%ebp
+	xorl	%r11d,%eax
+	addl	%ecx,%r12d
+	xorl	8(%rsp),%ebp
+	roll	$30,%esi
+	addl	%eax,%r12d
+	roll	$1,%ebp
+	movl	%ebp,20(%rsp)
+	movl	24(%rsp),%edx
+	movl	%esi,%eax
+	movl	%r12d,%ecx
+	xorl	32(%rsp),%edx
+	xorl	%r13d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rbp,%r11,1),%r11d
+	xorl	56(%rsp),%edx
+	xorl	%edi,%eax
+	addl	%ecx,%r11d
+	xorl	12(%rsp),%edx
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	roll	$1,%edx
+	movl	%edx,24(%rsp)
+	movl	28(%rsp),%ebp
+	movl	%r13d,%eax
+	movl	%r11d,%ecx
+	xorl	36(%rsp),%ebp
+	xorl	%r12d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rdx,%rdi,1),%edi
+	xorl	60(%rsp),%ebp
+	xorl	%esi,%eax
+	addl	%ecx,%edi
+	xorl	16(%rsp),%ebp
+	roll	$30,%r12d
+	addl	%eax,%edi
+	roll	$1,%ebp
+	movl	%ebp,28(%rsp)
+	movl	32(%rsp),%edx
+	movl	%r12d,%eax
+	movl	%edi,%ecx
+	xorl	40(%rsp),%edx
+	xorl	%r11d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rbp,%rsi,1),%esi
+	xorl	0(%rsp),%edx
+	xorl	%r13d,%eax
+	addl	%ecx,%esi
+	xorl	20(%rsp),%edx
+	roll	$30,%r11d
+	addl	%eax,%esi
+	roll	$1,%edx
+	movl	%edx,32(%rsp)
+	movl	36(%rsp),%ebp
+	movl	%r11d,%eax
+	movl	%r11d,%ebx
+	xorl	44(%rsp),%ebp
+	andl	%r12d,%eax
+	movl	%esi,%ecx
+	xorl	4(%rsp),%ebp
+	xorl	%r12d,%ebx
+	leal	-1894007588(%rdx,%r13,1),%r13d
+	roll	$5,%ecx
+	xorl	24(%rsp),%ebp
+	addl	%eax,%r13d
+	andl	%edi,%ebx
+	roll	$1,%ebp
+	addl	%ebx,%r13d
+	roll	$30,%edi
+	movl	%ebp,36(%rsp)
+	addl	%ecx,%r13d
+	movl	40(%rsp),%edx
+	movl	%edi,%eax
+	movl	%edi,%ebx
+	xorl	48(%rsp),%edx
+	andl	%r11d,%eax
+	movl	%r13d,%ecx
+	xorl	8(%rsp),%edx
+	xorl	%r11d,%ebx
+	leal	-1894007588(%rbp,%r12,1),%r12d
+	roll	$5,%ecx
+	xorl	28(%rsp),%edx
+	addl	%eax,%r12d
+	andl	%esi,%ebx
+	roll	$1,%edx
+	addl	%ebx,%r12d
+	roll	$30,%esi
+	movl	%edx,40(%rsp)
+	addl	%ecx,%r12d
+	movl	44(%rsp),%ebp
+	movl	%esi,%eax
+	movl	%esi,%ebx
+	xorl	52(%rsp),%ebp
+	andl	%edi,%eax
+	movl	%r12d,%ecx
+	xorl	12(%rsp),%ebp
+	xorl	%edi,%ebx
+	leal	-1894007588(%rdx,%r11,1),%r11d
+	roll	$5,%ecx
+	xorl	32(%rsp),%ebp
+	addl	%eax,%r11d
+	andl	%r13d,%ebx
+	roll	$1,%ebp
+	addl	%ebx,%r11d
+	roll	$30,%r13d
+	movl	%ebp,44(%rsp)
+	addl	%ecx,%r11d
+	movl	48(%rsp),%edx
+	movl	%r13d,%eax
+	movl	%r13d,%ebx
+	xorl	56(%rsp),%edx
+	andl	%esi,%eax
+	movl	%r11d,%ecx
+	xorl	16(%rsp),%edx
+	xorl	%esi,%ebx
+	leal	-1894007588(%rbp,%rdi,1),%edi
+	roll	$5,%ecx
+	xorl	36(%rsp),%edx
+	addl	%eax,%edi
+	andl	%r12d,%ebx
+	roll	$1,%edx
+	addl	%ebx,%edi
+	roll	$30,%r12d
+	movl	%edx,48(%rsp)
+	addl	%ecx,%edi
+	movl	52(%rsp),%ebp
+	movl	%r12d,%eax
+	movl	%r12d,%ebx
+	xorl	60(%rsp),%ebp
+	andl	%r13d,%eax
+	movl	%edi,%ecx
+	xorl	20(%rsp),%ebp
+	xorl	%r13d,%ebx
+	leal	-1894007588(%rdx,%rsi,1),%esi
+	roll	$5,%ecx
+	xorl	40(%rsp),%ebp
+	addl	%eax,%esi
+	andl	%r11d,%ebx
+	roll	$1,%ebp
+	addl	%ebx,%esi
+	roll	$30,%r11d
+	movl	%ebp,52(%rsp)
+	addl	%ecx,%esi
+	movl	56(%rsp),%edx
+	movl	%r11d,%eax
+	movl	%r11d,%ebx
+	xorl	0(%rsp),%edx
+	andl	%r12d,%eax
+	movl	%esi,%ecx
+	xorl	24(%rsp),%edx
+	xorl	%r12d,%ebx
+	leal	-1894007588(%rbp,%r13,1),%r13d
+	roll	$5,%ecx
+	xorl	44(%rsp),%edx
+	addl	%eax,%r13d
+	andl	%edi,%ebx
+	roll	$1,%edx
+	addl	%ebx,%r13d
+	roll	$30,%edi
+	movl	%edx,56(%rsp)
+	addl	%ecx,%r13d
+	movl	60(%rsp),%ebp
+	movl	%edi,%eax
+	movl	%edi,%ebx
+	xorl	4(%rsp),%ebp
+	andl	%r11d,%eax
+	movl	%r13d,%ecx
+	xorl	28(%rsp),%ebp
+	xorl	%r11d,%ebx
+	leal	-1894007588(%rdx,%r12,1),%r12d
+	roll	$5,%ecx
+	xorl	48(%rsp),%ebp
+	addl	%eax,%r12d
+	andl	%esi,%ebx
+	roll	$1,%ebp
+	addl	%ebx,%r12d
+	roll	$30,%esi
+	movl	%ebp,60(%rsp)
+	addl	%ecx,%r12d
+	movl	0(%rsp),%edx
+	movl	%esi,%eax
+	movl	%esi,%ebx
+	xorl	8(%rsp),%edx
+	andl	%edi,%eax
+	movl	%r12d,%ecx
+	xorl	32(%rsp),%edx
+	xorl	%edi,%ebx
+	leal	-1894007588(%rbp,%r11,1),%r11d
+	roll	$5,%ecx
+	xorl	52(%rsp),%edx
+	addl	%eax,%r11d
+	andl	%r13d,%ebx
+	roll	$1,%edx
+	addl	%ebx,%r11d
+	roll	$30,%r13d
+	movl	%edx,0(%rsp)
+	addl	%ecx,%r11d
+	movl	4(%rsp),%ebp
+	movl	%r13d,%eax
+	movl	%r13d,%ebx
+	xorl	12(%rsp),%ebp
+	andl	%esi,%eax
+	movl	%r11d,%ecx
+	xorl	36(%rsp),%ebp
+	xorl	%esi,%ebx
+	leal	-1894007588(%rdx,%rdi,1),%edi
+	roll	$5,%ecx
+	xorl	56(%rsp),%ebp
+	addl	%eax,%edi
+	andl	%r12d,%ebx
+	roll	$1,%ebp
+	addl	%ebx,%edi
+	roll	$30,%r12d
+	movl	%ebp,4(%rsp)
+	addl	%ecx,%edi
+	movl	8(%rsp),%edx
+	movl	%r12d,%eax
+	movl	%r12d,%ebx
+	xorl	16(%rsp),%edx
+	andl	%r13d,%eax
+	movl	%edi,%ecx
+	xorl	40(%rsp),%edx
+	xorl	%r13d,%ebx
+	leal	-1894007588(%rbp,%rsi,1),%esi
+	roll	$5,%ecx
+	xorl	60(%rsp),%edx
+	addl	%eax,%esi
+	andl	%r11d,%ebx
+	roll	$1,%edx
+	addl	%ebx,%esi
+	roll	$30,%r11d
+	movl	%edx,8(%rsp)
+	addl	%ecx,%esi
+	movl	12(%rsp),%ebp
+	movl	%r11d,%eax
+	movl	%r11d,%ebx
+	xorl	20(%rsp),%ebp
+	andl	%r12d,%eax
+	movl	%esi,%ecx
+	xorl	44(%rsp),%ebp
+	xorl	%r12d,%ebx
+	leal	-1894007588(%rdx,%r13,1),%r13d
+	roll	$5,%ecx
+	xorl	0(%rsp),%ebp
+	addl	%eax,%r13d
+	andl	%edi,%ebx
+	roll	$1,%ebp
+	addl	%ebx,%r13d
+	roll	$30,%edi
+	movl	%ebp,12(%rsp)
+	addl	%ecx,%r13d
+	movl	16(%rsp),%edx
+	movl	%edi,%eax
+	movl	%edi,%ebx
+	xorl	24(%rsp),%edx
+	andl	%r11d,%eax
+	movl	%r13d,%ecx
+	xorl	48(%rsp),%edx
+	xorl	%r11d,%ebx
+	leal	-1894007588(%rbp,%r12,1),%r12d
+	roll	$5,%ecx
+	xorl	4(%rsp),%edx
+	addl	%eax,%r12d
+	andl	%esi,%ebx
+	roll	$1,%edx
+	addl	%ebx,%r12d
+	roll	$30,%esi
+	movl	%edx,16(%rsp)
+	addl	%ecx,%r12d
+	movl	20(%rsp),%ebp
+	movl	%esi,%eax
+	movl	%esi,%ebx
+	xorl	28(%rsp),%ebp
+	andl	%edi,%eax
+	movl	%r12d,%ecx
+	xorl	52(%rsp),%ebp
+	xorl	%edi,%ebx
+	leal	-1894007588(%rdx,%r11,1),%r11d
+	roll	$5,%ecx
+	xorl	8(%rsp),%ebp
+	addl	%eax,%r11d
+	andl	%r13d,%ebx
+	roll	$1,%ebp
+	addl	%ebx,%r11d
+	roll	$30,%r13d
+	movl	%ebp,20(%rsp)
+	addl	%ecx,%r11d
+	movl	24(%rsp),%edx
+	movl	%r13d,%eax
+	movl	%r13d,%ebx
+	xorl	32(%rsp),%edx
+	andl	%esi,%eax
+	movl	%r11d,%ecx
+	xorl	56(%rsp),%edx
+	xorl	%esi,%ebx
+	leal	-1894007588(%rbp,%rdi,1),%edi
+	roll	$5,%ecx
+	xorl	12(%rsp),%edx
+	addl	%eax,%edi
+	andl	%r12d,%ebx
+	roll	$1,%edx
+	addl	%ebx,%edi
+	roll	$30,%r12d
+	movl	%edx,24(%rsp)
+	addl	%ecx,%edi
+	movl	28(%rsp),%ebp
+	movl	%r12d,%eax
+	movl	%r12d,%ebx
+	xorl	36(%rsp),%ebp
+	andl	%r13d,%eax
+	movl	%edi,%ecx
+	xorl	60(%rsp),%ebp
+	xorl	%r13d,%ebx
+	leal	-1894007588(%rdx,%rsi,1),%esi
+	roll	$5,%ecx
+	xorl	16(%rsp),%ebp
+	addl	%eax,%esi
+	andl	%r11d,%ebx
+	roll	$1,%ebp
+	addl	%ebx,%esi
+	roll	$30,%r11d
+	movl	%ebp,28(%rsp)
+	addl	%ecx,%esi
+	movl	32(%rsp),%edx
+	movl	%r11d,%eax
+	movl	%r11d,%ebx
+	xorl	40(%rsp),%edx
+	andl	%r12d,%eax
+	movl	%esi,%ecx
+	xorl	0(%rsp),%edx
+	xorl	%r12d,%ebx
+	leal	-1894007588(%rbp,%r13,1),%r13d
+	roll	$5,%ecx
+	xorl	20(%rsp),%edx
+	addl	%eax,%r13d
+	andl	%edi,%ebx
+	roll	$1,%edx
+	addl	%ebx,%r13d
+	roll	$30,%edi
+	movl	%edx,32(%rsp)
+	addl	%ecx,%r13d
+	movl	36(%rsp),%ebp
+	movl	%edi,%eax
+	movl	%edi,%ebx
+	xorl	44(%rsp),%ebp
+	andl	%r11d,%eax
+	movl	%r13d,%ecx
+	xorl	4(%rsp),%ebp
+	xorl	%r11d,%ebx
+	leal	-1894007588(%rdx,%r12,1),%r12d
+	roll	$5,%ecx
+	xorl	24(%rsp),%ebp
+	addl	%eax,%r12d
+	andl	%esi,%ebx
+	roll	$1,%ebp
+	addl	%ebx,%r12d
+	roll	$30,%esi
+	movl	%ebp,36(%rsp)
+	addl	%ecx,%r12d
+	movl	40(%rsp),%edx
+	movl	%esi,%eax
+	movl	%esi,%ebx
+	xorl	48(%rsp),%edx
+	andl	%edi,%eax
+	movl	%r12d,%ecx
+	xorl	8(%rsp),%edx
+	xorl	%edi,%ebx
+	leal	-1894007588(%rbp,%r11,1),%r11d
+	roll	$5,%ecx
+	xorl	28(%rsp),%edx
+	addl	%eax,%r11d
+	andl	%r13d,%ebx
+	roll	$1,%edx
+	addl	%ebx,%r11d
+	roll	$30,%r13d
+	movl	%edx,40(%rsp)
+	addl	%ecx,%r11d
+	movl	44(%rsp),%ebp
+	movl	%r13d,%eax
+	movl	%r13d,%ebx
+	xorl	52(%rsp),%ebp
+	andl	%esi,%eax
+	movl	%r11d,%ecx
+	xorl	12(%rsp),%ebp
+	xorl	%esi,%ebx
+	leal	-1894007588(%rdx,%rdi,1),%edi
+	roll	$5,%ecx
+	xorl	32(%rsp),%ebp
+	addl	%eax,%edi
+	andl	%r12d,%ebx
+	roll	$1,%ebp
+	addl	%ebx,%edi
+	roll	$30,%r12d
+	movl	%ebp,44(%rsp)
+	addl	%ecx,%edi
+	movl	48(%rsp),%edx
+	movl	%r12d,%eax
+	movl	%r12d,%ebx
+	xorl	56(%rsp),%edx
+	andl	%r13d,%eax
+	movl	%edi,%ecx
+	xorl	16(%rsp),%edx
+	xorl	%r13d,%ebx
+	leal	-1894007588(%rbp,%rsi,1),%esi
+	roll	$5,%ecx
+	xorl	36(%rsp),%edx
+	addl	%eax,%esi
+	andl	%r11d,%ebx
+	roll	$1,%edx
+	addl	%ebx,%esi
+	roll	$30,%r11d
+	movl	%edx,48(%rsp)
+	addl	%ecx,%esi
+	movl	52(%rsp),%ebp
+	movl	%r11d,%eax
+	movl	%esi,%ecx
+	xorl	60(%rsp),%ebp
+	xorl	%edi,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rdx,%r13,1),%r13d
+	xorl	20(%rsp),%ebp
+	xorl	%r12d,%eax
+	addl	%ecx,%r13d
+	xorl	40(%rsp),%ebp
+	roll	$30,%edi
+	addl	%eax,%r13d
+	roll	$1,%ebp
+	movl	%ebp,52(%rsp)
+	movl	56(%rsp),%edx
+	movl	%edi,%eax
+	movl	%r13d,%ecx
+	xorl	0(%rsp),%edx
+	xorl	%esi,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rbp,%r12,1),%r12d
+	xorl	24(%rsp),%edx
+	xorl	%r11d,%eax
+	addl	%ecx,%r12d
+	xorl	44(%rsp),%edx
+	roll	$30,%esi
+	addl	%eax,%r12d
+	roll	$1,%edx
+	movl	%edx,56(%rsp)
+	movl	60(%rsp),%ebp
+	movl	%esi,%eax
+	movl	%r12d,%ecx
+	xorl	4(%rsp),%ebp
+	xorl	%r13d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rdx,%r11,1),%r11d
+	xorl	28(%rsp),%ebp
+	xorl	%edi,%eax
+	addl	%ecx,%r11d
+	xorl	48(%rsp),%ebp
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	roll	$1,%ebp
+	movl	%ebp,60(%rsp)
+	movl	0(%rsp),%edx
+	movl	%r13d,%eax
+	movl	%r11d,%ecx
+	xorl	8(%rsp),%edx
+	xorl	%r12d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rbp,%rdi,1),%edi
+	xorl	32(%rsp),%edx
+	xorl	%esi,%eax
+	addl	%ecx,%edi
+	xorl	52(%rsp),%edx
+	roll	$30,%r12d
+	addl	%eax,%edi
+	roll	$1,%edx
+	movl	%edx,0(%rsp)
+	movl	4(%rsp),%ebp
+	movl	%r12d,%eax
+	movl	%edi,%ecx
+	xorl	12(%rsp),%ebp
+	xorl	%r11d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rdx,%rsi,1),%esi
+	xorl	36(%rsp),%ebp
+	xorl	%r13d,%eax
+	addl	%ecx,%esi
+	xorl	56(%rsp),%ebp
+	roll	$30,%r11d
+	addl	%eax,%esi
+	roll	$1,%ebp
+	movl	%ebp,4(%rsp)
+	movl	8(%rsp),%edx
+	movl	%r11d,%eax
+	movl	%esi,%ecx
+	xorl	16(%rsp),%edx
+	xorl	%edi,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rbp,%r13,1),%r13d
+	xorl	40(%rsp),%edx
+	xorl	%r12d,%eax
+	addl	%ecx,%r13d
+	xorl	60(%rsp),%edx
+	roll	$30,%edi
+	addl	%eax,%r13d
+	roll	$1,%edx
+	movl	%edx,8(%rsp)
+	movl	12(%rsp),%ebp
+	movl	%edi,%eax
+	movl	%r13d,%ecx
+	xorl	20(%rsp),%ebp
+	xorl	%esi,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rdx,%r12,1),%r12d
+	xorl	44(%rsp),%ebp
+	xorl	%r11d,%eax
+	addl	%ecx,%r12d
+	xorl	0(%rsp),%ebp
+	roll	$30,%esi
+	addl	%eax,%r12d
+	roll	$1,%ebp
+	movl	%ebp,12(%rsp)
+	movl	16(%rsp),%edx
+	movl	%esi,%eax
+	movl	%r12d,%ecx
+	xorl	24(%rsp),%edx
+	xorl	%r13d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rbp,%r11,1),%r11d
+	xorl	48(%rsp),%edx
+	xorl	%edi,%eax
+	addl	%ecx,%r11d
+	xorl	4(%rsp),%edx
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	roll	$1,%edx
+	movl	%edx,16(%rsp)
+	movl	20(%rsp),%ebp
+	movl	%r13d,%eax
+	movl	%r11d,%ecx
+	xorl	28(%rsp),%ebp
+	xorl	%r12d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rdx,%rdi,1),%edi
+	xorl	52(%rsp),%ebp
+	xorl	%esi,%eax
+	addl	%ecx,%edi
+	xorl	8(%rsp),%ebp
+	roll	$30,%r12d
+	addl	%eax,%edi
+	roll	$1,%ebp
+	movl	%ebp,20(%rsp)
+	movl	24(%rsp),%edx
+	movl	%r12d,%eax
+	movl	%edi,%ecx
+	xorl	32(%rsp),%edx
+	xorl	%r11d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rbp,%rsi,1),%esi
+	xorl	56(%rsp),%edx
+	xorl	%r13d,%eax
+	addl	%ecx,%esi
+	xorl	12(%rsp),%edx
+	roll	$30,%r11d
+	addl	%eax,%esi
+	roll	$1,%edx
+	movl	%edx,24(%rsp)
+	movl	28(%rsp),%ebp
+	movl	%r11d,%eax
+	movl	%esi,%ecx
+	xorl	36(%rsp),%ebp
+	xorl	%edi,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rdx,%r13,1),%r13d
+	xorl	60(%rsp),%ebp
+	xorl	%r12d,%eax
+	addl	%ecx,%r13d
+	xorl	16(%rsp),%ebp
+	roll	$30,%edi
+	addl	%eax,%r13d
+	roll	$1,%ebp
+	movl	%ebp,28(%rsp)
+	movl	32(%rsp),%edx
+	movl	%edi,%eax
+	movl	%r13d,%ecx
+	xorl	40(%rsp),%edx
+	xorl	%esi,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rbp,%r12,1),%r12d
+	xorl	0(%rsp),%edx
+	xorl	%r11d,%eax
+	addl	%ecx,%r12d
+	xorl	20(%rsp),%edx
+	roll	$30,%esi
+	addl	%eax,%r12d
+	roll	$1,%edx
+	movl	%edx,32(%rsp)
+	movl	36(%rsp),%ebp
+	movl	%esi,%eax
+	movl	%r12d,%ecx
+	xorl	44(%rsp),%ebp
+	xorl	%r13d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rdx,%r11,1),%r11d
+	xorl	4(%rsp),%ebp
+	xorl	%edi,%eax
+	addl	%ecx,%r11d
+	xorl	24(%rsp),%ebp
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	roll	$1,%ebp
+	movl	%ebp,36(%rsp)
+	movl	40(%rsp),%edx
+	movl	%r13d,%eax
+	movl	%r11d,%ecx
+	xorl	48(%rsp),%edx
+	xorl	%r12d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rbp,%rdi,1),%edi
+	xorl	8(%rsp),%edx
+	xorl	%esi,%eax
+	addl	%ecx,%edi
+	xorl	28(%rsp),%edx
+	roll	$30,%r12d
+	addl	%eax,%edi
+	roll	$1,%edx
+	movl	%edx,40(%rsp)
+	movl	44(%rsp),%ebp
+	movl	%r12d,%eax
+	movl	%edi,%ecx
+	xorl	52(%rsp),%ebp
+	xorl	%r11d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rdx,%rsi,1),%esi
+	xorl	12(%rsp),%ebp
+	xorl	%r13d,%eax
+	addl	%ecx,%esi
+	xorl	32(%rsp),%ebp
+	roll	$30,%r11d
+	addl	%eax,%esi
+	roll	$1,%ebp
+	movl	%ebp,44(%rsp)
+	movl	48(%rsp),%edx
+	movl	%r11d,%eax
+	movl	%esi,%ecx
+	xorl	56(%rsp),%edx
+	xorl	%edi,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rbp,%r13,1),%r13d
+	xorl	16(%rsp),%edx
+	xorl	%r12d,%eax
+	addl	%ecx,%r13d
+	xorl	36(%rsp),%edx
+	roll	$30,%edi
+	addl	%eax,%r13d
+	roll	$1,%edx
+	movl	%edx,48(%rsp)
+	movl	52(%rsp),%ebp
+	movl	%edi,%eax
+	movl	%r13d,%ecx
+	xorl	60(%rsp),%ebp
+	xorl	%esi,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rdx,%r12,1),%r12d
+	xorl	20(%rsp),%ebp
+	xorl	%r11d,%eax
+	addl	%ecx,%r12d
+	xorl	40(%rsp),%ebp
+	roll	$30,%esi
+	addl	%eax,%r12d
+	roll	$1,%ebp
+	movl	56(%rsp),%edx
+	movl	%esi,%eax
+	movl	%r12d,%ecx
+	xorl	0(%rsp),%edx
+	xorl	%r13d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rbp,%r11,1),%r11d
+	xorl	24(%rsp),%edx
+	xorl	%edi,%eax
+	addl	%ecx,%r11d
+	xorl	44(%rsp),%edx
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	roll	$1,%edx
+	movl	60(%rsp),%ebp
+	movl	%r13d,%eax
+	movl	%r11d,%ecx
+	xorl	4(%rsp),%ebp
+	xorl	%r12d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rdx,%rdi,1),%edi
+	xorl	28(%rsp),%ebp
+	xorl	%esi,%eax
+	addl	%ecx,%edi
+	xorl	48(%rsp),%ebp
+	roll	$30,%r12d
+	addl	%eax,%edi
+	roll	$1,%ebp
+	movl	%r12d,%eax
+	movl	%edi,%ecx
+	xorl	%r11d,%eax
+	leal	-899497514(%rbp,%rsi,1),%esi
+	roll	$5,%ecx
+	xorl	%r13d,%eax
+	addl	%ecx,%esi
+	roll	$30,%r11d
+	addl	%eax,%esi
+	addl	0(%r8),%esi
+	addl	4(%r8),%edi
+	addl	8(%r8),%r11d
+	addl	12(%r8),%r12d
+	addl	16(%r8),%r13d
+	movl	%esi,0(%r8)
+	movl	%edi,4(%r8)
+	movl	%r11d,8(%r8)
+	movl	%r12d,12(%r8)
+	movl	%r13d,16(%r8)
+
+	subq	$1,%r10
+	leaq	64(%r9),%r9
+	jnz	.Lloop
+
+	movq	64(%rsp),%rsi
+	movq	(%rsi),%r13
+	movq	8(%rsi),%r12
+	movq	16(%rsi),%rbp
+	movq	24(%rsi),%rbx
+	leaq	32(%rsi),%rsp
+.Lepilogue:
+	.byte	0xf3,0xc3
+.size	sha1_block_data_order,.-sha1_block_data_order
+.type	sha1_block_data_order_ssse3,@function
+.align	16
+sha1_block_data_order_ssse3:
+_ssse3_shortcut:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	leaq	-64(%rsp),%rsp
+	movq	%rdi,%r8
+	movq	%rsi,%r9
+	movq	%rdx,%r10
+
+	shlq	$6,%r10
+	addq	%r9,%r10
+	leaq	K_XX_XX(%rip),%r11
+
+	movl	0(%r8),%eax
+	movl	4(%r8),%ebx
+	movl	8(%r8),%ecx
+	movl	12(%r8),%edx
+	movl	%ebx,%esi
+	movl	16(%r8),%ebp
+
+	movdqa	64(%r11),%xmm6
+	movdqa	0(%r11),%xmm9
+	movdqu	0(%r9),%xmm0
+	movdqu	16(%r9),%xmm1
+	movdqu	32(%r9),%xmm2
+	movdqu	48(%r9),%xmm3
+.byte	102,15,56,0,198
+	addq	$64,%r9
+.byte	102,15,56,0,206
+.byte	102,15,56,0,214
+.byte	102,15,56,0,222
+	paddd	%xmm9,%xmm0
+	paddd	%xmm9,%xmm1
+	paddd	%xmm9,%xmm2
+	movdqa	%xmm0,0(%rsp)
+	psubd	%xmm9,%xmm0
+	movdqa	%xmm1,16(%rsp)
+	psubd	%xmm9,%xmm1
+	movdqa	%xmm2,32(%rsp)
+	psubd	%xmm9,%xmm2
+	jmp	.Loop_ssse3
+.align	16
+.Loop_ssse3:
+	movdqa	%xmm1,%xmm4
+	addl	0(%rsp),%ebp
+	xorl	%edx,%ecx
+	movdqa	%xmm3,%xmm8
+.byte	102,15,58,15,224,8
+	movl	%eax,%edi
+	roll	$5,%eax
+	paddd	%xmm3,%xmm9
+	andl	%ecx,%esi
+	xorl	%edx,%ecx
+	psrldq	$4,%xmm8
+	xorl	%edx,%esi
+	addl	%eax,%ebp
+	pxor	%xmm0,%xmm4
+	rorl	$2,%ebx
+	addl	%esi,%ebp
+	pxor	%xmm2,%xmm8
+	addl	4(%rsp),%edx
+	xorl	%ecx,%ebx
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	pxor	%xmm8,%xmm4
+	andl	%ebx,%edi
+	xorl	%ecx,%ebx
+	movdqa	%xmm9,48(%rsp)
+	xorl	%ecx,%edi
+	addl	%ebp,%edx
+	movdqa	%xmm4,%xmm10
+	movdqa	%xmm4,%xmm8
+	rorl	$7,%eax
+	addl	%edi,%edx
+	addl	8(%rsp),%ecx
+	xorl	%ebx,%eax
+	pslldq	$12,%xmm10
+	paddd	%xmm4,%xmm4
+	movl	%edx,%edi
+	roll	$5,%edx
+	andl	%eax,%esi
+	xorl	%ebx,%eax
+	psrld	$31,%xmm8
+	xorl	%ebx,%esi
+	addl	%edx,%ecx
+	movdqa	%xmm10,%xmm9
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	psrld	$30,%xmm10
+	por	%xmm8,%xmm4
+	addl	12(%rsp),%ebx
+	xorl	%eax,%ebp
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	pslld	$2,%xmm9
+	pxor	%xmm10,%xmm4
+	andl	%ebp,%edi
+	xorl	%eax,%ebp
+	movdqa	0(%r11),%xmm10
+	xorl	%eax,%edi
+	addl	%ecx,%ebx
+	pxor	%xmm9,%xmm4
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	movdqa	%xmm2,%xmm5
+	addl	16(%rsp),%eax
+	xorl	%ebp,%edx
+	movdqa	%xmm4,%xmm9
+.byte	102,15,58,15,233,8
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	paddd	%xmm4,%xmm10
+	andl	%edx,%esi
+	xorl	%ebp,%edx
+	psrldq	$4,%xmm9
+	xorl	%ebp,%esi
+	addl	%ebx,%eax
+	pxor	%xmm1,%xmm5
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	pxor	%xmm3,%xmm9
+	addl	20(%rsp),%ebp
+	xorl	%edx,%ecx
+	movl	%eax,%esi
+	roll	$5,%eax
+	pxor	%xmm9,%xmm5
+	andl	%ecx,%edi
+	xorl	%edx,%ecx
+	movdqa	%xmm10,0(%rsp)
+	xorl	%edx,%edi
+	addl	%eax,%ebp
+	movdqa	%xmm5,%xmm8
+	movdqa	%xmm5,%xmm9
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	addl	24(%rsp),%edx
+	xorl	%ecx,%ebx
+	pslldq	$12,%xmm8
+	paddd	%xmm5,%xmm5
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	andl	%ebx,%esi
+	xorl	%ecx,%ebx
+	psrld	$31,%xmm9
+	xorl	%ecx,%esi
+	addl	%ebp,%edx
+	movdqa	%xmm8,%xmm10
+	rorl	$7,%eax
+	addl	%esi,%edx
+	psrld	$30,%xmm8
+	por	%xmm9,%xmm5
+	addl	28(%rsp),%ecx
+	xorl	%ebx,%eax
+	movl	%edx,%esi
+	roll	$5,%edx
+	pslld	$2,%xmm10
+	pxor	%xmm8,%xmm5
+	andl	%eax,%edi
+	xorl	%ebx,%eax
+	movdqa	16(%r11),%xmm8
+	xorl	%ebx,%edi
+	addl	%edx,%ecx
+	pxor	%xmm10,%xmm5
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	movdqa	%xmm3,%xmm6
+	addl	32(%rsp),%ebx
+	xorl	%eax,%ebp
+	movdqa	%xmm5,%xmm10
+.byte	102,15,58,15,242,8
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	paddd	%xmm5,%xmm8
+	andl	%ebp,%esi
+	xorl	%eax,%ebp
+	psrldq	$4,%xmm10
+	xorl	%eax,%esi
+	addl	%ecx,%ebx
+	pxor	%xmm2,%xmm6
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	pxor	%xmm4,%xmm10
+	addl	36(%rsp),%eax
+	xorl	%ebp,%edx
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	pxor	%xmm10,%xmm6
+	andl	%edx,%edi
+	xorl	%ebp,%edx
+	movdqa	%xmm8,16(%rsp)
+	xorl	%ebp,%edi
+	addl	%ebx,%eax
+	movdqa	%xmm6,%xmm9
+	movdqa	%xmm6,%xmm10
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	addl	40(%rsp),%ebp
+	xorl	%edx,%ecx
+	pslldq	$12,%xmm9
+	paddd	%xmm6,%xmm6
+	movl	%eax,%edi
+	roll	$5,%eax
+	andl	%ecx,%esi
+	xorl	%edx,%ecx
+	psrld	$31,%xmm10
+	xorl	%edx,%esi
+	addl	%eax,%ebp
+	movdqa	%xmm9,%xmm8
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	psrld	$30,%xmm9
+	por	%xmm10,%xmm6
+	addl	44(%rsp),%edx
+	xorl	%ecx,%ebx
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	pslld	$2,%xmm8
+	pxor	%xmm9,%xmm6
+	andl	%ebx,%edi
+	xorl	%ecx,%ebx
+	movdqa	16(%r11),%xmm9
+	xorl	%ecx,%edi
+	addl	%ebp,%edx
+	pxor	%xmm8,%xmm6
+	rorl	$7,%eax
+	addl	%edi,%edx
+	movdqa	%xmm4,%xmm7
+	addl	48(%rsp),%ecx
+	xorl	%ebx,%eax
+	movdqa	%xmm6,%xmm8
+.byte	102,15,58,15,251,8
+	movl	%edx,%edi
+	roll	$5,%edx
+	paddd	%xmm6,%xmm9
+	andl	%eax,%esi
+	xorl	%ebx,%eax
+	psrldq	$4,%xmm8
+	xorl	%ebx,%esi
+	addl	%edx,%ecx
+	pxor	%xmm3,%xmm7
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	pxor	%xmm5,%xmm8
+	addl	52(%rsp),%ebx
+	xorl	%eax,%ebp
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	pxor	%xmm8,%xmm7
+	andl	%ebp,%edi
+	xorl	%eax,%ebp
+	movdqa	%xmm9,32(%rsp)
+	xorl	%eax,%edi
+	addl	%ecx,%ebx
+	movdqa	%xmm7,%xmm10
+	movdqa	%xmm7,%xmm8
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	addl	56(%rsp),%eax
+	xorl	%ebp,%edx
+	pslldq	$12,%xmm10
+	paddd	%xmm7,%xmm7
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	andl	%edx,%esi
+	xorl	%ebp,%edx
+	psrld	$31,%xmm8
+	xorl	%ebp,%esi
+	addl	%ebx,%eax
+	movdqa	%xmm10,%xmm9
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	psrld	$30,%xmm10
+	por	%xmm8,%xmm7
+	addl	60(%rsp),%ebp
+	xorl	%edx,%ecx
+	movl	%eax,%esi
+	roll	$5,%eax
+	pslld	$2,%xmm9
+	pxor	%xmm10,%xmm7
+	andl	%ecx,%edi
+	xorl	%edx,%ecx
+	movdqa	16(%r11),%xmm10
+	xorl	%edx,%edi
+	addl	%eax,%ebp
+	pxor	%xmm9,%xmm7
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	movdqa	%xmm7,%xmm9
+	addl	0(%rsp),%edx
+	pxor	%xmm4,%xmm0
+.byte	102,68,15,58,15,206,8
+	xorl	%ecx,%ebx
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	pxor	%xmm1,%xmm0
+	andl	%ebx,%esi
+	xorl	%ecx,%ebx
+	movdqa	%xmm10,%xmm8
+	paddd	%xmm7,%xmm10
+	xorl	%ecx,%esi
+	addl	%ebp,%edx
+	pxor	%xmm9,%xmm0
+	rorl	$7,%eax
+	addl	%esi,%edx
+	addl	4(%rsp),%ecx
+	xorl	%ebx,%eax
+	movdqa	%xmm0,%xmm9
+	movdqa	%xmm10,48(%rsp)
+	movl	%edx,%esi
+	roll	$5,%edx
+	andl	%eax,%edi
+	xorl	%ebx,%eax
+	pslld	$2,%xmm0
+	xorl	%ebx,%edi
+	addl	%edx,%ecx
+	psrld	$30,%xmm9
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	addl	8(%rsp),%ebx
+	xorl	%eax,%ebp
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	por	%xmm9,%xmm0
+	andl	%ebp,%esi
+	xorl	%eax,%ebp
+	movdqa	%xmm0,%xmm10
+	xorl	%eax,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	addl	12(%rsp),%eax
+	xorl	%ebp,%edx
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	andl	%edx,%edi
+	xorl	%ebp,%edx
+	xorl	%ebp,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	addl	16(%rsp),%ebp
+	pxor	%xmm5,%xmm1
+.byte	102,68,15,58,15,215,8
+	xorl	%edx,%esi
+	movl	%eax,%edi
+	roll	$5,%eax
+	pxor	%xmm2,%xmm1
+	xorl	%ecx,%esi
+	addl	%eax,%ebp
+	movdqa	%xmm8,%xmm9
+	paddd	%xmm0,%xmm8
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	pxor	%xmm10,%xmm1
+	addl	20(%rsp),%edx
+	xorl	%ecx,%edi
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	movdqa	%xmm1,%xmm10
+	movdqa	%xmm8,0(%rsp)
+	xorl	%ebx,%edi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%edi,%edx
+	pslld	$2,%xmm1
+	addl	24(%rsp),%ecx
+	xorl	%ebx,%esi
+	psrld	$30,%xmm10
+	movl	%edx,%edi
+	roll	$5,%edx
+	xorl	%eax,%esi
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	por	%xmm10,%xmm1
+	addl	28(%rsp),%ebx
+	xorl	%eax,%edi
+	movdqa	%xmm1,%xmm8
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	xorl	%ebp,%edi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	addl	32(%rsp),%eax
+	pxor	%xmm6,%xmm2
+.byte	102,68,15,58,15,192,8
+	xorl	%ebp,%esi
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	pxor	%xmm3,%xmm2
+	xorl	%edx,%esi
+	addl	%ebx,%eax
+	movdqa	32(%r11),%xmm10
+	paddd	%xmm1,%xmm9
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	pxor	%xmm8,%xmm2
+	addl	36(%rsp),%ebp
+	xorl	%edx,%edi
+	movl	%eax,%esi
+	roll	$5,%eax
+	movdqa	%xmm2,%xmm8
+	movdqa	%xmm9,16(%rsp)
+	xorl	%ecx,%edi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	pslld	$2,%xmm2
+	addl	40(%rsp),%edx
+	xorl	%ecx,%esi
+	psrld	$30,%xmm8
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	xorl	%ebx,%esi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%esi,%edx
+	por	%xmm8,%xmm2
+	addl	44(%rsp),%ecx
+	xorl	%ebx,%edi
+	movdqa	%xmm2,%xmm9
+	movl	%edx,%esi
+	roll	$5,%edx
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	addl	48(%rsp),%ebx
+	pxor	%xmm7,%xmm3
+.byte	102,68,15,58,15,201,8
+	xorl	%eax,%esi
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	pxor	%xmm4,%xmm3
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	movdqa	%xmm10,%xmm8
+	paddd	%xmm2,%xmm10
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	pxor	%xmm9,%xmm3
+	addl	52(%rsp),%eax
+	xorl	%ebp,%edi
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	movdqa	%xmm3,%xmm9
+	movdqa	%xmm10,32(%rsp)
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	pslld	$2,%xmm3
+	addl	56(%rsp),%ebp
+	xorl	%edx,%esi
+	psrld	$30,%xmm9
+	movl	%eax,%edi
+	roll	$5,%eax
+	xorl	%ecx,%esi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	por	%xmm9,%xmm3
+	addl	60(%rsp),%edx
+	xorl	%ecx,%edi
+	movdqa	%xmm3,%xmm10
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	xorl	%ebx,%edi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%edi,%edx
+	addl	0(%rsp),%ecx
+	pxor	%xmm0,%xmm4
+.byte	102,68,15,58,15,210,8
+	xorl	%ebx,%esi
+	movl	%edx,%edi
+	roll	$5,%edx
+	pxor	%xmm5,%xmm4
+	xorl	%eax,%esi
+	addl	%edx,%ecx
+	movdqa	%xmm8,%xmm9
+	paddd	%xmm3,%xmm8
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	pxor	%xmm10,%xmm4
+	addl	4(%rsp),%ebx
+	xorl	%eax,%edi
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	movdqa	%xmm4,%xmm10
+	movdqa	%xmm8,48(%rsp)
+	xorl	%ebp,%edi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	pslld	$2,%xmm4
+	addl	8(%rsp),%eax
+	xorl	%ebp,%esi
+	psrld	$30,%xmm10
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	xorl	%edx,%esi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	por	%xmm10,%xmm4
+	addl	12(%rsp),%ebp
+	xorl	%edx,%edi
+	movdqa	%xmm4,%xmm8
+	movl	%eax,%esi
+	roll	$5,%eax
+	xorl	%ecx,%edi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	addl	16(%rsp),%edx
+	pxor	%xmm1,%xmm5
+.byte	102,68,15,58,15,195,8
+	xorl	%ecx,%esi
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	pxor	%xmm6,%xmm5
+	xorl	%ebx,%esi
+	addl	%ebp,%edx
+	movdqa	%xmm9,%xmm10
+	paddd	%xmm4,%xmm9
+	rorl	$7,%eax
+	addl	%esi,%edx
+	pxor	%xmm8,%xmm5
+	addl	20(%rsp),%ecx
+	xorl	%ebx,%edi
+	movl	%edx,%esi
+	roll	$5,%edx
+	movdqa	%xmm5,%xmm8
+	movdqa	%xmm9,0(%rsp)
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	pslld	$2,%xmm5
+	addl	24(%rsp),%ebx
+	xorl	%eax,%esi
+	psrld	$30,%xmm8
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	por	%xmm8,%xmm5
+	addl	28(%rsp),%eax
+	xorl	%ebp,%edi
+	movdqa	%xmm5,%xmm9
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	movl	%ecx,%edi
+	pxor	%xmm2,%xmm6
+.byte	102,68,15,58,15,204,8
+	xorl	%edx,%ecx
+	addl	32(%rsp),%ebp
+	andl	%edx,%edi
+	pxor	%xmm7,%xmm6
+	andl	%ecx,%esi
+	rorl	$7,%ebx
+	movdqa	%xmm10,%xmm8
+	paddd	%xmm5,%xmm10
+	addl	%edi,%ebp
+	movl	%eax,%edi
+	pxor	%xmm9,%xmm6
+	roll	$5,%eax
+	addl	%esi,%ebp
+	xorl	%edx,%ecx
+	addl	%eax,%ebp
+	movdqa	%xmm6,%xmm9
+	movdqa	%xmm10,16(%rsp)
+	movl	%ebx,%esi
+	xorl	%ecx,%ebx
+	addl	36(%rsp),%edx
+	andl	%ecx,%esi
+	pslld	$2,%xmm6
+	andl	%ebx,%edi
+	rorl	$7,%eax
+	psrld	$30,%xmm9
+	addl	%esi,%edx
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	addl	%edi,%edx
+	xorl	%ecx,%ebx
+	addl	%ebp,%edx
+	por	%xmm9,%xmm6
+	movl	%eax,%edi
+	xorl	%ebx,%eax
+	movdqa	%xmm6,%xmm10
+	addl	40(%rsp),%ecx
+	andl	%ebx,%edi
+	andl	%eax,%esi
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	movl	%edx,%edi
+	roll	$5,%edx
+	addl	%esi,%ecx
+	xorl	%ebx,%eax
+	addl	%edx,%ecx
+	movl	%ebp,%esi
+	xorl	%eax,%ebp
+	addl	44(%rsp),%ebx
+	andl	%eax,%esi
+	andl	%ebp,%edi
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	addl	%edi,%ebx
+	xorl	%eax,%ebp
+	addl	%ecx,%ebx
+	movl	%edx,%edi
+	pxor	%xmm3,%xmm7
+.byte	102,68,15,58,15,213,8
+	xorl	%ebp,%edx
+	addl	48(%rsp),%eax
+	andl	%ebp,%edi
+	pxor	%xmm0,%xmm7
+	andl	%edx,%esi
+	rorl	$7,%ecx
+	movdqa	48(%r11),%xmm9
+	paddd	%xmm6,%xmm8
+	addl	%edi,%eax
+	movl	%ebx,%edi
+	pxor	%xmm10,%xmm7
+	roll	$5,%ebx
+	addl	%esi,%eax
+	xorl	%ebp,%edx
+	addl	%ebx,%eax
+	movdqa	%xmm7,%xmm10
+	movdqa	%xmm8,32(%rsp)
+	movl	%ecx,%esi
+	xorl	%edx,%ecx
+	addl	52(%rsp),%ebp
+	andl	%edx,%esi
+	pslld	$2,%xmm7
+	andl	%ecx,%edi
+	rorl	$7,%ebx
+	psrld	$30,%xmm10
+	addl	%esi,%ebp
+	movl	%eax,%esi
+	roll	$5,%eax
+	addl	%edi,%ebp
+	xorl	%edx,%ecx
+	addl	%eax,%ebp
+	por	%xmm10,%xmm7
+	movl	%ebx,%edi
+	xorl	%ecx,%ebx
+	movdqa	%xmm7,%xmm8
+	addl	56(%rsp),%edx
+	andl	%ecx,%edi
+	andl	%ebx,%esi
+	rorl	$7,%eax
+	addl	%edi,%edx
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	addl	%esi,%edx
+	xorl	%ecx,%ebx
+	addl	%ebp,%edx
+	movl	%eax,%esi
+	xorl	%ebx,%eax
+	addl	60(%rsp),%ecx
+	andl	%ebx,%esi
+	andl	%eax,%edi
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	movl	%edx,%esi
+	roll	$5,%edx
+	addl	%edi,%ecx
+	xorl	%ebx,%eax
+	addl	%edx,%ecx
+	movl	%ebp,%edi
+	pxor	%xmm4,%xmm0
+.byte	102,68,15,58,15,198,8
+	xorl	%eax,%ebp
+	addl	0(%rsp),%ebx
+	andl	%eax,%edi
+	pxor	%xmm1,%xmm0
+	andl	%ebp,%esi
+	rorl	$7,%edx
+	movdqa	%xmm9,%xmm10
+	paddd	%xmm7,%xmm9
+	addl	%edi,%ebx
+	movl	%ecx,%edi
+	pxor	%xmm8,%xmm0
+	roll	$5,%ecx
+	addl	%esi,%ebx
+	xorl	%eax,%ebp
+	addl	%ecx,%ebx
+	movdqa	%xmm0,%xmm8
+	movdqa	%xmm9,48(%rsp)
+	movl	%edx,%esi
+	xorl	%ebp,%edx
+	addl	4(%rsp),%eax
+	andl	%ebp,%esi
+	pslld	$2,%xmm0
+	andl	%edx,%edi
+	rorl	$7,%ecx
+	psrld	$30,%xmm8
+	addl	%esi,%eax
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	addl	%edi,%eax
+	xorl	%ebp,%edx
+	addl	%ebx,%eax
+	por	%xmm8,%xmm0
+	movl	%ecx,%edi
+	xorl	%edx,%ecx
+	movdqa	%xmm0,%xmm9
+	addl	8(%rsp),%ebp
+	andl	%edx,%edi
+	andl	%ecx,%esi
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	movl	%eax,%edi
+	roll	$5,%eax
+	addl	%esi,%ebp
+	xorl	%edx,%ecx
+	addl	%eax,%ebp
+	movl	%ebx,%esi
+	xorl	%ecx,%ebx
+	addl	12(%rsp),%edx
+	andl	%ecx,%esi
+	andl	%ebx,%edi
+	rorl	$7,%eax
+	addl	%esi,%edx
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	addl	%edi,%edx
+	xorl	%ecx,%ebx
+	addl	%ebp,%edx
+	movl	%eax,%edi
+	pxor	%xmm5,%xmm1
+.byte	102,68,15,58,15,207,8
+	xorl	%ebx,%eax
+	addl	16(%rsp),%ecx
+	andl	%ebx,%edi
+	pxor	%xmm2,%xmm1
+	andl	%eax,%esi
+	rorl	$7,%ebp
+	movdqa	%xmm10,%xmm8
+	paddd	%xmm0,%xmm10
+	addl	%edi,%ecx
+	movl	%edx,%edi
+	pxor	%xmm9,%xmm1
+	roll	$5,%edx
+	addl	%esi,%ecx
+	xorl	%ebx,%eax
+	addl	%edx,%ecx
+	movdqa	%xmm1,%xmm9
+	movdqa	%xmm10,0(%rsp)
+	movl	%ebp,%esi
+	xorl	%eax,%ebp
+	addl	20(%rsp),%ebx
+	andl	%eax,%esi
+	pslld	$2,%xmm1
+	andl	%ebp,%edi
+	rorl	$7,%edx
+	psrld	$30,%xmm9
+	addl	%esi,%ebx
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	addl	%edi,%ebx
+	xorl	%eax,%ebp
+	addl	%ecx,%ebx
+	por	%xmm9,%xmm1
+	movl	%edx,%edi
+	xorl	%ebp,%edx
+	movdqa	%xmm1,%xmm10
+	addl	24(%rsp),%eax
+	andl	%ebp,%edi
+	andl	%edx,%esi
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	addl	%esi,%eax
+	xorl	%ebp,%edx
+	addl	%ebx,%eax
+	movl	%ecx,%esi
+	xorl	%edx,%ecx
+	addl	28(%rsp),%ebp
+	andl	%edx,%esi
+	andl	%ecx,%edi
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	movl	%eax,%esi
+	roll	$5,%eax
+	addl	%edi,%ebp
+	xorl	%edx,%ecx
+	addl	%eax,%ebp
+	movl	%ebx,%edi
+	pxor	%xmm6,%xmm2
+.byte	102,68,15,58,15,208,8
+	xorl	%ecx,%ebx
+	addl	32(%rsp),%edx
+	andl	%ecx,%edi
+	pxor	%xmm3,%xmm2
+	andl	%ebx,%esi
+	rorl	$7,%eax
+	movdqa	%xmm8,%xmm9
+	paddd	%xmm1,%xmm8
+	addl	%edi,%edx
+	movl	%ebp,%edi
+	pxor	%xmm10,%xmm2
+	roll	$5,%ebp
+	addl	%esi,%edx
+	xorl	%ecx,%ebx
+	addl	%ebp,%edx
+	movdqa	%xmm2,%xmm10
+	movdqa	%xmm8,16(%rsp)
+	movl	%eax,%esi
+	xorl	%ebx,%eax
+	addl	36(%rsp),%ecx
+	andl	%ebx,%esi
+	pslld	$2,%xmm2
+	andl	%eax,%edi
+	rorl	$7,%ebp
+	psrld	$30,%xmm10
+	addl	%esi,%ecx
+	movl	%edx,%esi
+	roll	$5,%edx
+	addl	%edi,%ecx
+	xorl	%ebx,%eax
+	addl	%edx,%ecx
+	por	%xmm10,%xmm2
+	movl	%ebp,%edi
+	xorl	%eax,%ebp
+	movdqa	%xmm2,%xmm8
+	addl	40(%rsp),%ebx
+	andl	%eax,%edi
+	andl	%ebp,%esi
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	addl	%esi,%ebx
+	xorl	%eax,%ebp
+	addl	%ecx,%ebx
+	movl	%edx,%esi
+	xorl	%ebp,%edx
+	addl	44(%rsp),%eax
+	andl	%ebp,%esi
+	andl	%edx,%edi
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	addl	%edi,%eax
+	xorl	%ebp,%edx
+	addl	%ebx,%eax
+	addl	48(%rsp),%ebp
+	pxor	%xmm7,%xmm3
+.byte	102,68,15,58,15,193,8
+	xorl	%edx,%esi
+	movl	%eax,%edi
+	roll	$5,%eax
+	pxor	%xmm4,%xmm3
+	xorl	%ecx,%esi
+	addl	%eax,%ebp
+	movdqa	%xmm9,%xmm10
+	paddd	%xmm2,%xmm9
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	pxor	%xmm8,%xmm3
+	addl	52(%rsp),%edx
+	xorl	%ecx,%edi
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	movdqa	%xmm3,%xmm8
+	movdqa	%xmm9,32(%rsp)
+	xorl	%ebx,%edi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%edi,%edx
+	pslld	$2,%xmm3
+	addl	56(%rsp),%ecx
+	xorl	%ebx,%esi
+	psrld	$30,%xmm8
+	movl	%edx,%edi
+	roll	$5,%edx
+	xorl	%eax,%esi
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	por	%xmm8,%xmm3
+	addl	60(%rsp),%ebx
+	xorl	%eax,%edi
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	xorl	%ebp,%edi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	addl	0(%rsp),%eax
+	paddd	%xmm3,%xmm10
+	xorl	%ebp,%esi
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	xorl	%edx,%esi
+	movdqa	%xmm10,48(%rsp)
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	addl	4(%rsp),%ebp
+	xorl	%edx,%edi
+	movl	%eax,%esi
+	roll	$5,%eax
+	xorl	%ecx,%edi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	addl	8(%rsp),%edx
+	xorl	%ecx,%esi
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	xorl	%ebx,%esi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%esi,%edx
+	addl	12(%rsp),%ecx
+	xorl	%ebx,%edi
+	movl	%edx,%esi
+	roll	$5,%edx
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	cmpq	%r10,%r9
+	je	.Ldone_ssse3
+	movdqa	64(%r11),%xmm6
+	movdqa	0(%r11),%xmm9
+	movdqu	0(%r9),%xmm0
+	movdqu	16(%r9),%xmm1
+	movdqu	32(%r9),%xmm2
+	movdqu	48(%r9),%xmm3
+.byte	102,15,56,0,198
+	addq	$64,%r9
+	addl	16(%rsp),%ebx
+	xorl	%eax,%esi
+.byte	102,15,56,0,206
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	paddd	%xmm9,%xmm0
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	movdqa	%xmm0,0(%rsp)
+	addl	20(%rsp),%eax
+	xorl	%ebp,%edi
+	psubd	%xmm9,%xmm0
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	addl	24(%rsp),%ebp
+	xorl	%edx,%esi
+	movl	%eax,%edi
+	roll	$5,%eax
+	xorl	%ecx,%esi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	addl	28(%rsp),%edx
+	xorl	%ecx,%edi
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	xorl	%ebx,%edi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%edi,%edx
+	addl	32(%rsp),%ecx
+	xorl	%ebx,%esi
+.byte	102,15,56,0,214
+	movl	%edx,%edi
+	roll	$5,%edx
+	paddd	%xmm9,%xmm1
+	xorl	%eax,%esi
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	movdqa	%xmm1,16(%rsp)
+	addl	36(%rsp),%ebx
+	xorl	%eax,%edi
+	psubd	%xmm9,%xmm1
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	xorl	%ebp,%edi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	addl	40(%rsp),%eax
+	xorl	%ebp,%esi
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	xorl	%edx,%esi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	addl	44(%rsp),%ebp
+	xorl	%edx,%edi
+	movl	%eax,%esi
+	roll	$5,%eax
+	xorl	%ecx,%edi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	addl	48(%rsp),%edx
+	xorl	%ecx,%esi
+.byte	102,15,56,0,222
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	paddd	%xmm9,%xmm2
+	xorl	%ebx,%esi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%esi,%edx
+	movdqa	%xmm2,32(%rsp)
+	addl	52(%rsp),%ecx
+	xorl	%ebx,%edi
+	psubd	%xmm9,%xmm2
+	movl	%edx,%esi
+	roll	$5,%edx
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	addl	56(%rsp),%ebx
+	xorl	%eax,%esi
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	addl	60(%rsp),%eax
+	xorl	%ebp,%edi
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	addl	0(%r8),%eax
+	addl	4(%r8),%esi
+	addl	8(%r8),%ecx
+	addl	12(%r8),%edx
+	movl	%eax,0(%r8)
+	addl	16(%r8),%ebp
+	movl	%esi,4(%r8)
+	movl	%esi,%ebx
+	movl	%ecx,8(%r8)
+	movl	%edx,12(%r8)
+	movl	%ebp,16(%r8)
+	jmp	.Loop_ssse3
+
+.align	16
+.Ldone_ssse3:
+	addl	16(%rsp),%ebx
+	xorl	%eax,%esi
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	addl	20(%rsp),%eax
+	xorl	%ebp,%edi
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	addl	24(%rsp),%ebp
+	xorl	%edx,%esi
+	movl	%eax,%edi
+	roll	$5,%eax
+	xorl	%ecx,%esi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	addl	28(%rsp),%edx
+	xorl	%ecx,%edi
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	xorl	%ebx,%edi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%edi,%edx
+	addl	32(%rsp),%ecx
+	xorl	%ebx,%esi
+	movl	%edx,%edi
+	roll	$5,%edx
+	xorl	%eax,%esi
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	addl	36(%rsp),%ebx
+	xorl	%eax,%edi
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	xorl	%ebp,%edi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	addl	40(%rsp),%eax
+	xorl	%ebp,%esi
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	xorl	%edx,%esi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	addl	44(%rsp),%ebp
+	xorl	%edx,%edi
+	movl	%eax,%esi
+	roll	$5,%eax
+	xorl	%ecx,%edi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	addl	48(%rsp),%edx
+	xorl	%ecx,%esi
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	xorl	%ebx,%esi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%esi,%edx
+	addl	52(%rsp),%ecx
+	xorl	%ebx,%edi
+	movl	%edx,%esi
+	roll	$5,%edx
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	addl	56(%rsp),%ebx
+	xorl	%eax,%esi
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	addl	60(%rsp),%eax
+	xorl	%ebp,%edi
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	addl	0(%r8),%eax
+	addl	4(%r8),%esi
+	addl	8(%r8),%ecx
+	movl	%eax,0(%r8)
+	addl	12(%r8),%edx
+	movl	%esi,4(%r8)
+	addl	16(%r8),%ebp
+	movl	%ecx,8(%r8)
+	movl	%edx,12(%r8)
+	movl	%ebp,16(%r8)
+	leaq	64(%rsp),%rsi
+	movq	0(%rsi),%r12
+	movq	8(%rsi),%rbp
+	movq	16(%rsi),%rbx
+	leaq	24(%rsi),%rsp
+.Lepilogue_ssse3:
+	.byte	0xf3,0xc3
+.size	sha1_block_data_order_ssse3,.-sha1_block_data_order_ssse3
+.align	64
+K_XX_XX:
+.long	0x5a827999,0x5a827999,0x5a827999,0x5a827999	
+.long	0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1	
+.long	0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc	
+.long	0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6	
+.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f	
+.byte	83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align	64
+#if defined(HAVE_GNU_STACK)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/crypto/libressl/crypto/sha/sha1-macosx-x86_64.s b/crypto/libressl/crypto/sha/sha1-macosx-x86_64.s
new file mode 100644
index 0000000000..7848f708ec
--- /dev/null
+++ b/crypto/libressl/crypto/sha/sha1-macosx-x86_64.s
@@ -0,0 +1,2486 @@
+.text	
+
+
+.globl	_sha1_block_data_order
+
+.p2align	4
+_sha1_block_data_order:
+	movl	_OPENSSL_ia32cap_P+0(%rip),%r9d
+	movl	_OPENSSL_ia32cap_P+4(%rip),%r8d
+	testl	$512,%r8d
+	jz	L$ialu
+	jmp	_ssse3_shortcut
+
+.p2align	4
+L$ialu:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	movq	%rsp,%r11
+	movq	%rdi,%r8
+	subq	$72,%rsp
+	movq	%rsi,%r9
+	andq	$-64,%rsp
+	movq	%rdx,%r10
+	movq	%r11,64(%rsp)
+L$prologue:
+
+	movl	0(%r8),%esi
+	movl	4(%r8),%edi
+	movl	8(%r8),%r11d
+	movl	12(%r8),%r12d
+	movl	16(%r8),%r13d
+	jmp	L$loop
+
+.p2align	4
+L$loop:
+	movl	0(%r9),%edx
+	bswapl	%edx
+	movl	%edx,0(%rsp)
+	movl	%r11d,%eax
+	movl	4(%r9),%ebp
+	movl	%esi,%ecx
+	xorl	%r12d,%eax
+	bswapl	%ebp
+	roll	$5,%ecx
+	leal	1518500249(%rdx,%r13,1),%r13d
+	andl	%edi,%eax
+	movl	%ebp,4(%rsp)
+	addl	%ecx,%r13d
+	xorl	%r12d,%eax
+	roll	$30,%edi
+	addl	%eax,%r13d
+	movl	%edi,%eax
+	movl	8(%r9),%edx
+	movl	%r13d,%ecx
+	xorl	%r11d,%eax
+	bswapl	%edx
+	roll	$5,%ecx
+	leal	1518500249(%rbp,%r12,1),%r12d
+	andl	%esi,%eax
+	movl	%edx,8(%rsp)
+	addl	%ecx,%r12d
+	xorl	%r11d,%eax
+	roll	$30,%esi
+	addl	%eax,%r12d
+	movl	%esi,%eax
+	movl	12(%r9),%ebp
+	movl	%r12d,%ecx
+	xorl	%edi,%eax
+	bswapl	%ebp
+	roll	$5,%ecx
+	leal	1518500249(%rdx,%r11,1),%r11d
+	andl	%r13d,%eax
+	movl	%ebp,12(%rsp)
+	addl	%ecx,%r11d
+	xorl	%edi,%eax
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	movl	%r13d,%eax
+	movl	16(%r9),%edx
+	movl	%r11d,%ecx
+	xorl	%esi,%eax
+	bswapl	%edx
+	roll	$5,%ecx
+	leal	1518500249(%rbp,%rdi,1),%edi
+	andl	%r12d,%eax
+	movl	%edx,16(%rsp)
+	addl	%ecx,%edi
+	xorl	%esi,%eax
+	roll	$30,%r12d
+	addl	%eax,%edi
+	movl	%r12d,%eax
+	movl	20(%r9),%ebp
+	movl	%edi,%ecx
+	xorl	%r13d,%eax
+	bswapl	%ebp
+	roll	$5,%ecx
+	leal	1518500249(%rdx,%rsi,1),%esi
+	andl	%r11d,%eax
+	movl	%ebp,20(%rsp)
+	addl	%ecx,%esi
+	xorl	%r13d,%eax
+	roll	$30,%r11d
+	addl	%eax,%esi
+	movl	%r11d,%eax
+	movl	24(%r9),%edx
+	movl	%esi,%ecx
+	xorl	%r12d,%eax
+	bswapl	%edx
+	roll	$5,%ecx
+	leal	1518500249(%rbp,%r13,1),%r13d
+	andl	%edi,%eax
+	movl	%edx,24(%rsp)
+	addl	%ecx,%r13d
+	xorl	%r12d,%eax
+	roll	$30,%edi
+	addl	%eax,%r13d
+	movl	%edi,%eax
+	movl	28(%r9),%ebp
+	movl	%r13d,%ecx
+	xorl	%r11d,%eax
+	bswapl	%ebp
+	roll	$5,%ecx
+	leal	1518500249(%rdx,%r12,1),%r12d
+	andl	%esi,%eax
+	movl	%ebp,28(%rsp)
+	addl	%ecx,%r12d
+	xorl	%r11d,%eax
+	roll	$30,%esi
+	addl	%eax,%r12d
+	movl	%esi,%eax
+	movl	32(%r9),%edx
+	movl	%r12d,%ecx
+	xorl	%edi,%eax
+	bswapl	%edx
+	roll	$5,%ecx
+	leal	1518500249(%rbp,%r11,1),%r11d
+	andl	%r13d,%eax
+	movl	%edx,32(%rsp)
+	addl	%ecx,%r11d
+	xorl	%edi,%eax
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	movl	%r13d,%eax
+	movl	36(%r9),%ebp
+	movl	%r11d,%ecx
+	xorl	%esi,%eax
+	bswapl	%ebp
+	roll	$5,%ecx
+	leal	1518500249(%rdx,%rdi,1),%edi
+	andl	%r12d,%eax
+	movl	%ebp,36(%rsp)
+	addl	%ecx,%edi
+	xorl	%esi,%eax
+	roll	$30,%r12d
+	addl	%eax,%edi
+	movl	%r12d,%eax
+	movl	40(%r9),%edx
+	movl	%edi,%ecx
+	xorl	%r13d,%eax
+	bswapl	%edx
+	roll	$5,%ecx
+	leal	1518500249(%rbp,%rsi,1),%esi
+	andl	%r11d,%eax
+	movl	%edx,40(%rsp)
+	addl	%ecx,%esi
+	xorl	%r13d,%eax
+	roll	$30,%r11d
+	addl	%eax,%esi
+	movl	%r11d,%eax
+	movl	44(%r9),%ebp
+	movl	%esi,%ecx
+	xorl	%r12d,%eax
+	bswapl	%ebp
+	roll	$5,%ecx
+	leal	1518500249(%rdx,%r13,1),%r13d
+	andl	%edi,%eax
+	movl	%ebp,44(%rsp)
+	addl	%ecx,%r13d
+	xorl	%r12d,%eax
+	roll	$30,%edi
+	addl	%eax,%r13d
+	movl	%edi,%eax
+	movl	48(%r9),%edx
+	movl	%r13d,%ecx
+	xorl	%r11d,%eax
+	bswapl	%edx
+	roll	$5,%ecx
+	leal	1518500249(%rbp,%r12,1),%r12d
+	andl	%esi,%eax
+	movl	%edx,48(%rsp)
+	addl	%ecx,%r12d
+	xorl	%r11d,%eax
+	roll	$30,%esi
+	addl	%eax,%r12d
+	movl	%esi,%eax
+	movl	52(%r9),%ebp
+	movl	%r12d,%ecx
+	xorl	%edi,%eax
+	bswapl	%ebp
+	roll	$5,%ecx
+	leal	1518500249(%rdx,%r11,1),%r11d
+	andl	%r13d,%eax
+	movl	%ebp,52(%rsp)
+	addl	%ecx,%r11d
+	xorl	%edi,%eax
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	movl	%r13d,%eax
+	movl	56(%r9),%edx
+	movl	%r11d,%ecx
+	xorl	%esi,%eax
+	bswapl	%edx
+	roll	$5,%ecx
+	leal	1518500249(%rbp,%rdi,1),%edi
+	andl	%r12d,%eax
+	movl	%edx,56(%rsp)
+	addl	%ecx,%edi
+	xorl	%esi,%eax
+	roll	$30,%r12d
+	addl	%eax,%edi
+	movl	%r12d,%eax
+	movl	60(%r9),%ebp
+	movl	%edi,%ecx
+	xorl	%r13d,%eax
+	bswapl	%ebp
+	roll	$5,%ecx
+	leal	1518500249(%rdx,%rsi,1),%esi
+	andl	%r11d,%eax
+	movl	%ebp,60(%rsp)
+	addl	%ecx,%esi
+	xorl	%r13d,%eax
+	roll	$30,%r11d
+	addl	%eax,%esi
+	movl	0(%rsp),%edx
+	movl	%r11d,%eax
+	movl	%esi,%ecx
+	xorl	8(%rsp),%edx
+	xorl	%r12d,%eax
+	roll	$5,%ecx
+	xorl	32(%rsp),%edx
+	andl	%edi,%eax
+	leal	1518500249(%rbp,%r13,1),%r13d
+	xorl	52(%rsp),%edx
+	xorl	%r12d,%eax
+	roll	$1,%edx
+	addl	%ecx,%r13d
+	roll	$30,%edi
+	movl	%edx,0(%rsp)
+	addl	%eax,%r13d
+	movl	4(%rsp),%ebp
+	movl	%edi,%eax
+	movl	%r13d,%ecx
+	xorl	12(%rsp),%ebp
+	xorl	%r11d,%eax
+	roll	$5,%ecx
+	xorl	36(%rsp),%ebp
+	andl	%esi,%eax
+	leal	1518500249(%rdx,%r12,1),%r12d
+	xorl	56(%rsp),%ebp
+	xorl	%r11d,%eax
+	roll	$1,%ebp
+	addl	%ecx,%r12d
+	roll	$30,%esi
+	movl	%ebp,4(%rsp)
+	addl	%eax,%r12d
+	movl	8(%rsp),%edx
+	movl	%esi,%eax
+	movl	%r12d,%ecx
+	xorl	16(%rsp),%edx
+	xorl	%edi,%eax
+	roll	$5,%ecx
+	xorl	40(%rsp),%edx
+	andl	%r13d,%eax
+	leal	1518500249(%rbp,%r11,1),%r11d
+	xorl	60(%rsp),%edx
+	xorl	%edi,%eax
+	roll	$1,%edx
+	addl	%ecx,%r11d
+	roll	$30,%r13d
+	movl	%edx,8(%rsp)
+	addl	%eax,%r11d
+	movl	12(%rsp),%ebp
+	movl	%r13d,%eax
+	movl	%r11d,%ecx
+	xorl	20(%rsp),%ebp
+	xorl	%esi,%eax
+	roll	$5,%ecx
+	xorl	44(%rsp),%ebp
+	andl	%r12d,%eax
+	leal	1518500249(%rdx,%rdi,1),%edi
+	xorl	0(%rsp),%ebp
+	xorl	%esi,%eax
+	roll	$1,%ebp
+	addl	%ecx,%edi
+	roll	$30,%r12d
+	movl	%ebp,12(%rsp)
+	addl	%eax,%edi
+	movl	16(%rsp),%edx
+	movl	%r12d,%eax
+	movl	%edi,%ecx
+	xorl	24(%rsp),%edx
+	xorl	%r13d,%eax
+	roll	$5,%ecx
+	xorl	48(%rsp),%edx
+	andl	%r11d,%eax
+	leal	1518500249(%rbp,%rsi,1),%esi
+	xorl	4(%rsp),%edx
+	xorl	%r13d,%eax
+	roll	$1,%edx
+	addl	%ecx,%esi
+	roll	$30,%r11d
+	movl	%edx,16(%rsp)
+	addl	%eax,%esi
+	movl	20(%rsp),%ebp
+	movl	%r11d,%eax
+	movl	%esi,%ecx
+	xorl	28(%rsp),%ebp
+	xorl	%edi,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rdx,%r13,1),%r13d
+	xorl	52(%rsp),%ebp
+	xorl	%r12d,%eax
+	addl	%ecx,%r13d
+	xorl	8(%rsp),%ebp
+	roll	$30,%edi
+	addl	%eax,%r13d
+	roll	$1,%ebp
+	movl	%ebp,20(%rsp)
+	movl	24(%rsp),%edx
+	movl	%edi,%eax
+	movl	%r13d,%ecx
+	xorl	32(%rsp),%edx
+	xorl	%esi,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rbp,%r12,1),%r12d
+	xorl	56(%rsp),%edx
+	xorl	%r11d,%eax
+	addl	%ecx,%r12d
+	xorl	12(%rsp),%edx
+	roll	$30,%esi
+	addl	%eax,%r12d
+	roll	$1,%edx
+	movl	%edx,24(%rsp)
+	movl	28(%rsp),%ebp
+	movl	%esi,%eax
+	movl	%r12d,%ecx
+	xorl	36(%rsp),%ebp
+	xorl	%r13d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rdx,%r11,1),%r11d
+	xorl	60(%rsp),%ebp
+	xorl	%edi,%eax
+	addl	%ecx,%r11d
+	xorl	16(%rsp),%ebp
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	roll	$1,%ebp
+	movl	%ebp,28(%rsp)
+	movl	32(%rsp),%edx
+	movl	%r13d,%eax
+	movl	%r11d,%ecx
+	xorl	40(%rsp),%edx
+	xorl	%r12d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rbp,%rdi,1),%edi
+	xorl	0(%rsp),%edx
+	xorl	%esi,%eax
+	addl	%ecx,%edi
+	xorl	20(%rsp),%edx
+	roll	$30,%r12d
+	addl	%eax,%edi
+	roll	$1,%edx
+	movl	%edx,32(%rsp)
+	movl	36(%rsp),%ebp
+	movl	%r12d,%eax
+	movl	%edi,%ecx
+	xorl	44(%rsp),%ebp
+	xorl	%r11d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rdx,%rsi,1),%esi
+	xorl	4(%rsp),%ebp
+	xorl	%r13d,%eax
+	addl	%ecx,%esi
+	xorl	24(%rsp),%ebp
+	roll	$30,%r11d
+	addl	%eax,%esi
+	roll	$1,%ebp
+	movl	%ebp,36(%rsp)
+	movl	40(%rsp),%edx
+	movl	%r11d,%eax
+	movl	%esi,%ecx
+	xorl	48(%rsp),%edx
+	xorl	%edi,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rbp,%r13,1),%r13d
+	xorl	8(%rsp),%edx
+	xorl	%r12d,%eax
+	addl	%ecx,%r13d
+	xorl	28(%rsp),%edx
+	roll	$30,%edi
+	addl	%eax,%r13d
+	roll	$1,%edx
+	movl	%edx,40(%rsp)
+	movl	44(%rsp),%ebp
+	movl	%edi,%eax
+	movl	%r13d,%ecx
+	xorl	52(%rsp),%ebp
+	xorl	%esi,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rdx,%r12,1),%r12d
+	xorl	12(%rsp),%ebp
+	xorl	%r11d,%eax
+	addl	%ecx,%r12d
+	xorl	32(%rsp),%ebp
+	roll	$30,%esi
+	addl	%eax,%r12d
+	roll	$1,%ebp
+	movl	%ebp,44(%rsp)
+	movl	48(%rsp),%edx
+	movl	%esi,%eax
+	movl	%r12d,%ecx
+	xorl	56(%rsp),%edx
+	xorl	%r13d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rbp,%r11,1),%r11d
+	xorl	16(%rsp),%edx
+	xorl	%edi,%eax
+	addl	%ecx,%r11d
+	xorl	36(%rsp),%edx
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	roll	$1,%edx
+	movl	%edx,48(%rsp)
+	movl	52(%rsp),%ebp
+	movl	%r13d,%eax
+	movl	%r11d,%ecx
+	xorl	60(%rsp),%ebp
+	xorl	%r12d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rdx,%rdi,1),%edi
+	xorl	20(%rsp),%ebp
+	xorl	%esi,%eax
+	addl	%ecx,%edi
+	xorl	40(%rsp),%ebp
+	roll	$30,%r12d
+	addl	%eax,%edi
+	roll	$1,%ebp
+	movl	%ebp,52(%rsp)
+	movl	56(%rsp),%edx
+	movl	%r12d,%eax
+	movl	%edi,%ecx
+	xorl	0(%rsp),%edx
+	xorl	%r11d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rbp,%rsi,1),%esi
+	xorl	24(%rsp),%edx
+	xorl	%r13d,%eax
+	addl	%ecx,%esi
+	xorl	44(%rsp),%edx
+	roll	$30,%r11d
+	addl	%eax,%esi
+	roll	$1,%edx
+	movl	%edx,56(%rsp)
+	movl	60(%rsp),%ebp
+	movl	%r11d,%eax
+	movl	%esi,%ecx
+	xorl	4(%rsp),%ebp
+	xorl	%edi,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rdx,%r13,1),%r13d
+	xorl	28(%rsp),%ebp
+	xorl	%r12d,%eax
+	addl	%ecx,%r13d
+	xorl	48(%rsp),%ebp
+	roll	$30,%edi
+	addl	%eax,%r13d
+	roll	$1,%ebp
+	movl	%ebp,60(%rsp)
+	movl	0(%rsp),%edx
+	movl	%edi,%eax
+	movl	%r13d,%ecx
+	xorl	8(%rsp),%edx
+	xorl	%esi,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rbp,%r12,1),%r12d
+	xorl	32(%rsp),%edx
+	xorl	%r11d,%eax
+	addl	%ecx,%r12d
+	xorl	52(%rsp),%edx
+	roll	$30,%esi
+	addl	%eax,%r12d
+	roll	$1,%edx
+	movl	%edx,0(%rsp)
+	movl	4(%rsp),%ebp
+	movl	%esi,%eax
+	movl	%r12d,%ecx
+	xorl	12(%rsp),%ebp
+	xorl	%r13d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rdx,%r11,1),%r11d
+	xorl	36(%rsp),%ebp
+	xorl	%edi,%eax
+	addl	%ecx,%r11d
+	xorl	56(%rsp),%ebp
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	roll	$1,%ebp
+	movl	%ebp,4(%rsp)
+	movl	8(%rsp),%edx
+	movl	%r13d,%eax
+	movl	%r11d,%ecx
+	xorl	16(%rsp),%edx
+	xorl	%r12d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rbp,%rdi,1),%edi
+	xorl	40(%rsp),%edx
+	xorl	%esi,%eax
+	addl	%ecx,%edi
+	xorl	60(%rsp),%edx
+	roll	$30,%r12d
+	addl	%eax,%edi
+	roll	$1,%edx
+	movl	%edx,8(%rsp)
+	movl	12(%rsp),%ebp
+	movl	%r12d,%eax
+	movl	%edi,%ecx
+	xorl	20(%rsp),%ebp
+	xorl	%r11d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rdx,%rsi,1),%esi
+	xorl	44(%rsp),%ebp
+	xorl	%r13d,%eax
+	addl	%ecx,%esi
+	xorl	0(%rsp),%ebp
+	roll	$30,%r11d
+	addl	%eax,%esi
+	roll	$1,%ebp
+	movl	%ebp,12(%rsp)
+	movl	16(%rsp),%edx
+	movl	%r11d,%eax
+	movl	%esi,%ecx
+	xorl	24(%rsp),%edx
+	xorl	%edi,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rbp,%r13,1),%r13d
+	xorl	48(%rsp),%edx
+	xorl	%r12d,%eax
+	addl	%ecx,%r13d
+	xorl	4(%rsp),%edx
+	roll	$30,%edi
+	addl	%eax,%r13d
+	roll	$1,%edx
+	movl	%edx,16(%rsp)
+	movl	20(%rsp),%ebp
+	movl	%edi,%eax
+	movl	%r13d,%ecx
+	xorl	28(%rsp),%ebp
+	xorl	%esi,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rdx,%r12,1),%r12d
+	xorl	52(%rsp),%ebp
+	xorl	%r11d,%eax
+	addl	%ecx,%r12d
+	xorl	8(%rsp),%ebp
+	roll	$30,%esi
+	addl	%eax,%r12d
+	roll	$1,%ebp
+	movl	%ebp,20(%rsp)
+	movl	24(%rsp),%edx
+	movl	%esi,%eax
+	movl	%r12d,%ecx
+	xorl	32(%rsp),%edx
+	xorl	%r13d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rbp,%r11,1),%r11d
+	xorl	56(%rsp),%edx
+	xorl	%edi,%eax
+	addl	%ecx,%r11d
+	xorl	12(%rsp),%edx
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	roll	$1,%edx
+	movl	%edx,24(%rsp)
+	movl	28(%rsp),%ebp
+	movl	%r13d,%eax
+	movl	%r11d,%ecx
+	xorl	36(%rsp),%ebp
+	xorl	%r12d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rdx,%rdi,1),%edi
+	xorl	60(%rsp),%ebp
+	xorl	%esi,%eax
+	addl	%ecx,%edi
+	xorl	16(%rsp),%ebp
+	roll	$30,%r12d
+	addl	%eax,%edi
+	roll	$1,%ebp
+	movl	%ebp,28(%rsp)
+	movl	32(%rsp),%edx
+	movl	%r12d,%eax
+	movl	%edi,%ecx
+	xorl	40(%rsp),%edx
+	xorl	%r11d,%eax
+	roll	$5,%ecx
+	leal	1859775393(%rbp,%rsi,1),%esi
+	xorl	0(%rsp),%edx
+	xorl	%r13d,%eax
+	addl	%ecx,%esi
+	xorl	20(%rsp),%edx
+	roll	$30,%r11d
+	addl	%eax,%esi
+	roll	$1,%edx
+	movl	%edx,32(%rsp)
+	movl	36(%rsp),%ebp
+	movl	%r11d,%eax
+	movl	%r11d,%ebx
+	xorl	44(%rsp),%ebp
+	andl	%r12d,%eax
+	movl	%esi,%ecx
+	xorl	4(%rsp),%ebp
+	xorl	%r12d,%ebx
+	leal	-1894007588(%rdx,%r13,1),%r13d
+	roll	$5,%ecx
+	xorl	24(%rsp),%ebp
+	addl	%eax,%r13d
+	andl	%edi,%ebx
+	roll	$1,%ebp
+	addl	%ebx,%r13d
+	roll	$30,%edi
+	movl	%ebp,36(%rsp)
+	addl	%ecx,%r13d
+	movl	40(%rsp),%edx
+	movl	%edi,%eax
+	movl	%edi,%ebx
+	xorl	48(%rsp),%edx
+	andl	%r11d,%eax
+	movl	%r13d,%ecx
+	xorl	8(%rsp),%edx
+	xorl	%r11d,%ebx
+	leal	-1894007588(%rbp,%r12,1),%r12d
+	roll	$5,%ecx
+	xorl	28(%rsp),%edx
+	addl	%eax,%r12d
+	andl	%esi,%ebx
+	roll	$1,%edx
+	addl	%ebx,%r12d
+	roll	$30,%esi
+	movl	%edx,40(%rsp)
+	addl	%ecx,%r12d
+	movl	44(%rsp),%ebp
+	movl	%esi,%eax
+	movl	%esi,%ebx
+	xorl	52(%rsp),%ebp
+	andl	%edi,%eax
+	movl	%r12d,%ecx
+	xorl	12(%rsp),%ebp
+	xorl	%edi,%ebx
+	leal	-1894007588(%rdx,%r11,1),%r11d
+	roll	$5,%ecx
+	xorl	32(%rsp),%ebp
+	addl	%eax,%r11d
+	andl	%r13d,%ebx
+	roll	$1,%ebp
+	addl	%ebx,%r11d
+	roll	$30,%r13d
+	movl	%ebp,44(%rsp)
+	addl	%ecx,%r11d
+	movl	48(%rsp),%edx
+	movl	%r13d,%eax
+	movl	%r13d,%ebx
+	xorl	56(%rsp),%edx
+	andl	%esi,%eax
+	movl	%r11d,%ecx
+	xorl	16(%rsp),%edx
+	xorl	%esi,%ebx
+	leal	-1894007588(%rbp,%rdi,1),%edi
+	roll	$5,%ecx
+	xorl	36(%rsp),%edx
+	addl	%eax,%edi
+	andl	%r12d,%ebx
+	roll	$1,%edx
+	addl	%ebx,%edi
+	roll	$30,%r12d
+	movl	%edx,48(%rsp)
+	addl	%ecx,%edi
+	movl	52(%rsp),%ebp
+	movl	%r12d,%eax
+	movl	%r12d,%ebx
+	xorl	60(%rsp),%ebp
+	andl	%r13d,%eax
+	movl	%edi,%ecx
+	xorl	20(%rsp),%ebp
+	xorl	%r13d,%ebx
+	leal	-1894007588(%rdx,%rsi,1),%esi
+	roll	$5,%ecx
+	xorl	40(%rsp),%ebp
+	addl	%eax,%esi
+	andl	%r11d,%ebx
+	roll	$1,%ebp
+	addl	%ebx,%esi
+	roll	$30,%r11d
+	movl	%ebp,52(%rsp)
+	addl	%ecx,%esi
+	movl	56(%rsp),%edx
+	movl	%r11d,%eax
+	movl	%r11d,%ebx
+	xorl	0(%rsp),%edx
+	andl	%r12d,%eax
+	movl	%esi,%ecx
+	xorl	24(%rsp),%edx
+	xorl	%r12d,%ebx
+	leal	-1894007588(%rbp,%r13,1),%r13d
+	roll	$5,%ecx
+	xorl	44(%rsp),%edx
+	addl	%eax,%r13d
+	andl	%edi,%ebx
+	roll	$1,%edx
+	addl	%ebx,%r13d
+	roll	$30,%edi
+	movl	%edx,56(%rsp)
+	addl	%ecx,%r13d
+	movl	60(%rsp),%ebp
+	movl	%edi,%eax
+	movl	%edi,%ebx
+	xorl	4(%rsp),%ebp
+	andl	%r11d,%eax
+	movl	%r13d,%ecx
+	xorl	28(%rsp),%ebp
+	xorl	%r11d,%ebx
+	leal	-1894007588(%rdx,%r12,1),%r12d
+	roll	$5,%ecx
+	xorl	48(%rsp),%ebp
+	addl	%eax,%r12d
+	andl	%esi,%ebx
+	roll	$1,%ebp
+	addl	%ebx,%r12d
+	roll	$30,%esi
+	movl	%ebp,60(%rsp)
+	addl	%ecx,%r12d
+	movl	0(%rsp),%edx
+	movl	%esi,%eax
+	movl	%esi,%ebx
+	xorl	8(%rsp),%edx
+	andl	%edi,%eax
+	movl	%r12d,%ecx
+	xorl	32(%rsp),%edx
+	xorl	%edi,%ebx
+	leal	-1894007588(%rbp,%r11,1),%r11d
+	roll	$5,%ecx
+	xorl	52(%rsp),%edx
+	addl	%eax,%r11d
+	andl	%r13d,%ebx
+	roll	$1,%edx
+	addl	%ebx,%r11d
+	roll	$30,%r13d
+	movl	%edx,0(%rsp)
+	addl	%ecx,%r11d
+	movl	4(%rsp),%ebp
+	movl	%r13d,%eax
+	movl	%r13d,%ebx
+	xorl	12(%rsp),%ebp
+	andl	%esi,%eax
+	movl	%r11d,%ecx
+	xorl	36(%rsp),%ebp
+	xorl	%esi,%ebx
+	leal	-1894007588(%rdx,%rdi,1),%edi
+	roll	$5,%ecx
+	xorl	56(%rsp),%ebp
+	addl	%eax,%edi
+	andl	%r12d,%ebx
+	roll	$1,%ebp
+	addl	%ebx,%edi
+	roll	$30,%r12d
+	movl	%ebp,4(%rsp)
+	addl	%ecx,%edi
+	movl	8(%rsp),%edx
+	movl	%r12d,%eax
+	movl	%r12d,%ebx
+	xorl	16(%rsp),%edx
+	andl	%r13d,%eax
+	movl	%edi,%ecx
+	xorl	40(%rsp),%edx
+	xorl	%r13d,%ebx
+	leal	-1894007588(%rbp,%rsi,1),%esi
+	roll	$5,%ecx
+	xorl	60(%rsp),%edx
+	addl	%eax,%esi
+	andl	%r11d,%ebx
+	roll	$1,%edx
+	addl	%ebx,%esi
+	roll	$30,%r11d
+	movl	%edx,8(%rsp)
+	addl	%ecx,%esi
+	movl	12(%rsp),%ebp
+	movl	%r11d,%eax
+	movl	%r11d,%ebx
+	xorl	20(%rsp),%ebp
+	andl	%r12d,%eax
+	movl	%esi,%ecx
+	xorl	44(%rsp),%ebp
+	xorl	%r12d,%ebx
+	leal	-1894007588(%rdx,%r13,1),%r13d
+	roll	$5,%ecx
+	xorl	0(%rsp),%ebp
+	addl	%eax,%r13d
+	andl	%edi,%ebx
+	roll	$1,%ebp
+	addl	%ebx,%r13d
+	roll	$30,%edi
+	movl	%ebp,12(%rsp)
+	addl	%ecx,%r13d
+	movl	16(%rsp),%edx
+	movl	%edi,%eax
+	movl	%edi,%ebx
+	xorl	24(%rsp),%edx
+	andl	%r11d,%eax
+	movl	%r13d,%ecx
+	xorl	48(%rsp),%edx
+	xorl	%r11d,%ebx
+	leal	-1894007588(%rbp,%r12,1),%r12d
+	roll	$5,%ecx
+	xorl	4(%rsp),%edx
+	addl	%eax,%r12d
+	andl	%esi,%ebx
+	roll	$1,%edx
+	addl	%ebx,%r12d
+	roll	$30,%esi
+	movl	%edx,16(%rsp)
+	addl	%ecx,%r12d
+	movl	20(%rsp),%ebp
+	movl	%esi,%eax
+	movl	%esi,%ebx
+	xorl	28(%rsp),%ebp
+	andl	%edi,%eax
+	movl	%r12d,%ecx
+	xorl	52(%rsp),%ebp
+	xorl	%edi,%ebx
+	leal	-1894007588(%rdx,%r11,1),%r11d
+	roll	$5,%ecx
+	xorl	8(%rsp),%ebp
+	addl	%eax,%r11d
+	andl	%r13d,%ebx
+	roll	$1,%ebp
+	addl	%ebx,%r11d
+	roll	$30,%r13d
+	movl	%ebp,20(%rsp)
+	addl	%ecx,%r11d
+	movl	24(%rsp),%edx
+	movl	%r13d,%eax
+	movl	%r13d,%ebx
+	xorl	32(%rsp),%edx
+	andl	%esi,%eax
+	movl	%r11d,%ecx
+	xorl	56(%rsp),%edx
+	xorl	%esi,%ebx
+	leal	-1894007588(%rbp,%rdi,1),%edi
+	roll	$5,%ecx
+	xorl	12(%rsp),%edx
+	addl	%eax,%edi
+	andl	%r12d,%ebx
+	roll	$1,%edx
+	addl	%ebx,%edi
+	roll	$30,%r12d
+	movl	%edx,24(%rsp)
+	addl	%ecx,%edi
+	movl	28(%rsp),%ebp
+	movl	%r12d,%eax
+	movl	%r12d,%ebx
+	xorl	36(%rsp),%ebp
+	andl	%r13d,%eax
+	movl	%edi,%ecx
+	xorl	60(%rsp),%ebp
+	xorl	%r13d,%ebx
+	leal	-1894007588(%rdx,%rsi,1),%esi
+	roll	$5,%ecx
+	xorl	16(%rsp),%ebp
+	addl	%eax,%esi
+	andl	%r11d,%ebx
+	roll	$1,%ebp
+	addl	%ebx,%esi
+	roll	$30,%r11d
+	movl	%ebp,28(%rsp)
+	addl	%ecx,%esi
+	movl	32(%rsp),%edx
+	movl	%r11d,%eax
+	movl	%r11d,%ebx
+	xorl	40(%rsp),%edx
+	andl	%r12d,%eax
+	movl	%esi,%ecx
+	xorl	0(%rsp),%edx
+	xorl	%r12d,%ebx
+	leal	-1894007588(%rbp,%r13,1),%r13d
+	roll	$5,%ecx
+	xorl	20(%rsp),%edx
+	addl	%eax,%r13d
+	andl	%edi,%ebx
+	roll	$1,%edx
+	addl	%ebx,%r13d
+	roll	$30,%edi
+	movl	%edx,32(%rsp)
+	addl	%ecx,%r13d
+	movl	36(%rsp),%ebp
+	movl	%edi,%eax
+	movl	%edi,%ebx
+	xorl	44(%rsp),%ebp
+	andl	%r11d,%eax
+	movl	%r13d,%ecx
+	xorl	4(%rsp),%ebp
+	xorl	%r11d,%ebx
+	leal	-1894007588(%rdx,%r12,1),%r12d
+	roll	$5,%ecx
+	xorl	24(%rsp),%ebp
+	addl	%eax,%r12d
+	andl	%esi,%ebx
+	roll	$1,%ebp
+	addl	%ebx,%r12d
+	roll	$30,%esi
+	movl	%ebp,36(%rsp)
+	addl	%ecx,%r12d
+	movl	40(%rsp),%edx
+	movl	%esi,%eax
+	movl	%esi,%ebx
+	xorl	48(%rsp),%edx
+	andl	%edi,%eax
+	movl	%r12d,%ecx
+	xorl	8(%rsp),%edx
+	xorl	%edi,%ebx
+	leal	-1894007588(%rbp,%r11,1),%r11d
+	roll	$5,%ecx
+	xorl	28(%rsp),%edx
+	addl	%eax,%r11d
+	andl	%r13d,%ebx
+	roll	$1,%edx
+	addl	%ebx,%r11d
+	roll	$30,%r13d
+	movl	%edx,40(%rsp)
+	addl	%ecx,%r11d
+	movl	44(%rsp),%ebp
+	movl	%r13d,%eax
+	movl	%r13d,%ebx
+	xorl	52(%rsp),%ebp
+	andl	%esi,%eax
+	movl	%r11d,%ecx
+	xorl	12(%rsp),%ebp
+	xorl	%esi,%ebx
+	leal	-1894007588(%rdx,%rdi,1),%edi
+	roll	$5,%ecx
+	xorl	32(%rsp),%ebp
+	addl	%eax,%edi
+	andl	%r12d,%ebx
+	roll	$1,%ebp
+	addl	%ebx,%edi
+	roll	$30,%r12d
+	movl	%ebp,44(%rsp)
+	addl	%ecx,%edi
+	movl	48(%rsp),%edx
+	movl	%r12d,%eax
+	movl	%r12d,%ebx
+	xorl	56(%rsp),%edx
+	andl	%r13d,%eax
+	movl	%edi,%ecx
+	xorl	16(%rsp),%edx
+	xorl	%r13d,%ebx
+	leal	-1894007588(%rbp,%rsi,1),%esi
+	roll	$5,%ecx
+	xorl	36(%rsp),%edx
+	addl	%eax,%esi
+	andl	%r11d,%ebx
+	roll	$1,%edx
+	addl	%ebx,%esi
+	roll	$30,%r11d
+	movl	%edx,48(%rsp)
+	addl	%ecx,%esi
+	movl	52(%rsp),%ebp
+	movl	%r11d,%eax
+	movl	%esi,%ecx
+	xorl	60(%rsp),%ebp
+	xorl	%edi,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rdx,%r13,1),%r13d
+	xorl	20(%rsp),%ebp
+	xorl	%r12d,%eax
+	addl	%ecx,%r13d
+	xorl	40(%rsp),%ebp
+	roll	$30,%edi
+	addl	%eax,%r13d
+	roll	$1,%ebp
+	movl	%ebp,52(%rsp)
+	movl	56(%rsp),%edx
+	movl	%edi,%eax
+	movl	%r13d,%ecx
+	xorl	0(%rsp),%edx
+	xorl	%esi,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rbp,%r12,1),%r12d
+	xorl	24(%rsp),%edx
+	xorl	%r11d,%eax
+	addl	%ecx,%r12d
+	xorl	44(%rsp),%edx
+	roll	$30,%esi
+	addl	%eax,%r12d
+	roll	$1,%edx
+	movl	%edx,56(%rsp)
+	movl	60(%rsp),%ebp
+	movl	%esi,%eax
+	movl	%r12d,%ecx
+	xorl	4(%rsp),%ebp
+	xorl	%r13d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rdx,%r11,1),%r11d
+	xorl	28(%rsp),%ebp
+	xorl	%edi,%eax
+	addl	%ecx,%r11d
+	xorl	48(%rsp),%ebp
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	roll	$1,%ebp
+	movl	%ebp,60(%rsp)
+	movl	0(%rsp),%edx
+	movl	%r13d,%eax
+	movl	%r11d,%ecx
+	xorl	8(%rsp),%edx
+	xorl	%r12d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rbp,%rdi,1),%edi
+	xorl	32(%rsp),%edx
+	xorl	%esi,%eax
+	addl	%ecx,%edi
+	xorl	52(%rsp),%edx
+	roll	$30,%r12d
+	addl	%eax,%edi
+	roll	$1,%edx
+	movl	%edx,0(%rsp)
+	movl	4(%rsp),%ebp
+	movl	%r12d,%eax
+	movl	%edi,%ecx
+	xorl	12(%rsp),%ebp
+	xorl	%r11d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rdx,%rsi,1),%esi
+	xorl	36(%rsp),%ebp
+	xorl	%r13d,%eax
+	addl	%ecx,%esi
+	xorl	56(%rsp),%ebp
+	roll	$30,%r11d
+	addl	%eax,%esi
+	roll	$1,%ebp
+	movl	%ebp,4(%rsp)
+	movl	8(%rsp),%edx
+	movl	%r11d,%eax
+	movl	%esi,%ecx
+	xorl	16(%rsp),%edx
+	xorl	%edi,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rbp,%r13,1),%r13d
+	xorl	40(%rsp),%edx
+	xorl	%r12d,%eax
+	addl	%ecx,%r13d
+	xorl	60(%rsp),%edx
+	roll	$30,%edi
+	addl	%eax,%r13d
+	roll	$1,%edx
+	movl	%edx,8(%rsp)
+	movl	12(%rsp),%ebp
+	movl	%edi,%eax
+	movl	%r13d,%ecx
+	xorl	20(%rsp),%ebp
+	xorl	%esi,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rdx,%r12,1),%r12d
+	xorl	44(%rsp),%ebp
+	xorl	%r11d,%eax
+	addl	%ecx,%r12d
+	xorl	0(%rsp),%ebp
+	roll	$30,%esi
+	addl	%eax,%r12d
+	roll	$1,%ebp
+	movl	%ebp,12(%rsp)
+	movl	16(%rsp),%edx
+	movl	%esi,%eax
+	movl	%r12d,%ecx
+	xorl	24(%rsp),%edx
+	xorl	%r13d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rbp,%r11,1),%r11d
+	xorl	48(%rsp),%edx
+	xorl	%edi,%eax
+	addl	%ecx,%r11d
+	xorl	4(%rsp),%edx
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	roll	$1,%edx
+	movl	%edx,16(%rsp)
+	movl	20(%rsp),%ebp
+	movl	%r13d,%eax
+	movl	%r11d,%ecx
+	xorl	28(%rsp),%ebp
+	xorl	%r12d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rdx,%rdi,1),%edi
+	xorl	52(%rsp),%ebp
+	xorl	%esi,%eax
+	addl	%ecx,%edi
+	xorl	8(%rsp),%ebp
+	roll	$30,%r12d
+	addl	%eax,%edi
+	roll	$1,%ebp
+	movl	%ebp,20(%rsp)
+	movl	24(%rsp),%edx
+	movl	%r12d,%eax
+	movl	%edi,%ecx
+	xorl	32(%rsp),%edx
+	xorl	%r11d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rbp,%rsi,1),%esi
+	xorl	56(%rsp),%edx
+	xorl	%r13d,%eax
+	addl	%ecx,%esi
+	xorl	12(%rsp),%edx
+	roll	$30,%r11d
+	addl	%eax,%esi
+	roll	$1,%edx
+	movl	%edx,24(%rsp)
+	movl	28(%rsp),%ebp
+	movl	%r11d,%eax
+	movl	%esi,%ecx
+	xorl	36(%rsp),%ebp
+	xorl	%edi,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rdx,%r13,1),%r13d
+	xorl	60(%rsp),%ebp
+	xorl	%r12d,%eax
+	addl	%ecx,%r13d
+	xorl	16(%rsp),%ebp
+	roll	$30,%edi
+	addl	%eax,%r13d
+	roll	$1,%ebp
+	movl	%ebp,28(%rsp)
+	movl	32(%rsp),%edx
+	movl	%edi,%eax
+	movl	%r13d,%ecx
+	xorl	40(%rsp),%edx
+	xorl	%esi,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rbp,%r12,1),%r12d
+	xorl	0(%rsp),%edx
+	xorl	%r11d,%eax
+	addl	%ecx,%r12d
+	xorl	20(%rsp),%edx
+	roll	$30,%esi
+	addl	%eax,%r12d
+	roll	$1,%edx
+	movl	%edx,32(%rsp)
+	movl	36(%rsp),%ebp
+	movl	%esi,%eax
+	movl	%r12d,%ecx
+	xorl	44(%rsp),%ebp
+	xorl	%r13d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rdx,%r11,1),%r11d
+	xorl	4(%rsp),%ebp
+	xorl	%edi,%eax
+	addl	%ecx,%r11d
+	xorl	24(%rsp),%ebp
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	roll	$1,%ebp
+	movl	%ebp,36(%rsp)
+	movl	40(%rsp),%edx
+	movl	%r13d,%eax
+	movl	%r11d,%ecx
+	xorl	48(%rsp),%edx
+	xorl	%r12d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rbp,%rdi,1),%edi
+	xorl	8(%rsp),%edx
+	xorl	%esi,%eax
+	addl	%ecx,%edi
+	xorl	28(%rsp),%edx
+	roll	$30,%r12d
+	addl	%eax,%edi
+	roll	$1,%edx
+	movl	%edx,40(%rsp)
+	movl	44(%rsp),%ebp
+	movl	%r12d,%eax
+	movl	%edi,%ecx
+	xorl	52(%rsp),%ebp
+	xorl	%r11d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rdx,%rsi,1),%esi
+	xorl	12(%rsp),%ebp
+	xorl	%r13d,%eax
+	addl	%ecx,%esi
+	xorl	32(%rsp),%ebp
+	roll	$30,%r11d
+	addl	%eax,%esi
+	roll	$1,%ebp
+	movl	%ebp,44(%rsp)
+	movl	48(%rsp),%edx
+	movl	%r11d,%eax
+	movl	%esi,%ecx
+	xorl	56(%rsp),%edx
+	xorl	%edi,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rbp,%r13,1),%r13d
+	xorl	16(%rsp),%edx
+	xorl	%r12d,%eax
+	addl	%ecx,%r13d
+	xorl	36(%rsp),%edx
+	roll	$30,%edi
+	addl	%eax,%r13d
+	roll	$1,%edx
+	movl	%edx,48(%rsp)
+	movl	52(%rsp),%ebp
+	movl	%edi,%eax
+	movl	%r13d,%ecx
+	xorl	60(%rsp),%ebp
+	xorl	%esi,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rdx,%r12,1),%r12d
+	xorl	20(%rsp),%ebp
+	xorl	%r11d,%eax
+	addl	%ecx,%r12d
+	xorl	40(%rsp),%ebp
+	roll	$30,%esi
+	addl	%eax,%r12d
+	roll	$1,%ebp
+	movl	56(%rsp),%edx
+	movl	%esi,%eax
+	movl	%r12d,%ecx
+	xorl	0(%rsp),%edx
+	xorl	%r13d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rbp,%r11,1),%r11d
+	xorl	24(%rsp),%edx
+	xorl	%edi,%eax
+	addl	%ecx,%r11d
+	xorl	44(%rsp),%edx
+	roll	$30,%r13d
+	addl	%eax,%r11d
+	roll	$1,%edx
+	movl	60(%rsp),%ebp
+	movl	%r13d,%eax
+	movl	%r11d,%ecx
+	xorl	4(%rsp),%ebp
+	xorl	%r12d,%eax
+	roll	$5,%ecx
+	leal	-899497514(%rdx,%rdi,1),%edi
+	xorl	28(%rsp),%ebp
+	xorl	%esi,%eax
+	addl	%ecx,%edi
+	xorl	48(%rsp),%ebp
+	roll	$30,%r12d
+	addl	%eax,%edi
+	roll	$1,%ebp
+	movl	%r12d,%eax
+	movl	%edi,%ecx
+	xorl	%r11d,%eax
+	leal	-899497514(%rbp,%rsi,1),%esi
+	roll	$5,%ecx
+	xorl	%r13d,%eax
+	addl	%ecx,%esi
+	roll	$30,%r11d
+	addl	%eax,%esi
+	addl	0(%r8),%esi
+	addl	4(%r8),%edi
+	addl	8(%r8),%r11d
+	addl	12(%r8),%r12d
+	addl	16(%r8),%r13d
+	movl	%esi,0(%r8)
+	movl	%edi,4(%r8)
+	movl	%r11d,8(%r8)
+	movl	%r12d,12(%r8)
+	movl	%r13d,16(%r8)
+
+	subq	$1,%r10
+	leaq	64(%r9),%r9
+	jnz	L$loop
+
+	movq	64(%rsp),%rsi
+	movq	(%rsi),%r13
+	movq	8(%rsi),%r12
+	movq	16(%rsi),%rbp
+	movq	24(%rsi),%rbx
+	leaq	32(%rsi),%rsp
+L$epilogue:
+	.byte	0xf3,0xc3
+
+
+.p2align	4
+sha1_block_data_order_ssse3:
+_ssse3_shortcut:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	leaq	-64(%rsp),%rsp
+	movq	%rdi,%r8
+	movq	%rsi,%r9
+	movq	%rdx,%r10
+
+	shlq	$6,%r10
+	addq	%r9,%r10
+	leaq	K_XX_XX(%rip),%r11
+
+	movl	0(%r8),%eax
+	movl	4(%r8),%ebx
+	movl	8(%r8),%ecx
+	movl	12(%r8),%edx
+	movl	%ebx,%esi
+	movl	16(%r8),%ebp
+
+	movdqa	64(%r11),%xmm6
+	movdqa	0(%r11),%xmm9
+	movdqu	0(%r9),%xmm0
+	movdqu	16(%r9),%xmm1
+	movdqu	32(%r9),%xmm2
+	movdqu	48(%r9),%xmm3
+.byte	102,15,56,0,198
+	addq	$64,%r9
+.byte	102,15,56,0,206
+.byte	102,15,56,0,214
+.byte	102,15,56,0,222
+	paddd	%xmm9,%xmm0
+	paddd	%xmm9,%xmm1
+	paddd	%xmm9,%xmm2
+	movdqa	%xmm0,0(%rsp)
+	psubd	%xmm9,%xmm0
+	movdqa	%xmm1,16(%rsp)
+	psubd	%xmm9,%xmm1
+	movdqa	%xmm2,32(%rsp)
+	psubd	%xmm9,%xmm2
+	jmp	L$oop_ssse3
+.p2align	4
+L$oop_ssse3:
+	movdqa	%xmm1,%xmm4
+	addl	0(%rsp),%ebp
+	xorl	%edx,%ecx
+	movdqa	%xmm3,%xmm8
+.byte	102,15,58,15,224,8
+	movl	%eax,%edi
+	roll	$5,%eax
+	paddd	%xmm3,%xmm9
+	andl	%ecx,%esi
+	xorl	%edx,%ecx
+	psrldq	$4,%xmm8
+	xorl	%edx,%esi
+	addl	%eax,%ebp
+	pxor	%xmm0,%xmm4
+	rorl	$2,%ebx
+	addl	%esi,%ebp
+	pxor	%xmm2,%xmm8
+	addl	4(%rsp),%edx
+	xorl	%ecx,%ebx
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	pxor	%xmm8,%xmm4
+	andl	%ebx,%edi
+	xorl	%ecx,%ebx
+	movdqa	%xmm9,48(%rsp)
+	xorl	%ecx,%edi
+	addl	%ebp,%edx
+	movdqa	%xmm4,%xmm10
+	movdqa	%xmm4,%xmm8
+	rorl	$7,%eax
+	addl	%edi,%edx
+	addl	8(%rsp),%ecx
+	xorl	%ebx,%eax
+	pslldq	$12,%xmm10
+	paddd	%xmm4,%xmm4
+	movl	%edx,%edi
+	roll	$5,%edx
+	andl	%eax,%esi
+	xorl	%ebx,%eax
+	psrld	$31,%xmm8
+	xorl	%ebx,%esi
+	addl	%edx,%ecx
+	movdqa	%xmm10,%xmm9
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	psrld	$30,%xmm10
+	por	%xmm8,%xmm4
+	addl	12(%rsp),%ebx
+	xorl	%eax,%ebp
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	pslld	$2,%xmm9
+	pxor	%xmm10,%xmm4
+	andl	%ebp,%edi
+	xorl	%eax,%ebp
+	movdqa	0(%r11),%xmm10
+	xorl	%eax,%edi
+	addl	%ecx,%ebx
+	pxor	%xmm9,%xmm4
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	movdqa	%xmm2,%xmm5
+	addl	16(%rsp),%eax
+	xorl	%ebp,%edx
+	movdqa	%xmm4,%xmm9
+.byte	102,15,58,15,233,8
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	paddd	%xmm4,%xmm10
+	andl	%edx,%esi
+	xorl	%ebp,%edx
+	psrldq	$4,%xmm9
+	xorl	%ebp,%esi
+	addl	%ebx,%eax
+	pxor	%xmm1,%xmm5
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	pxor	%xmm3,%xmm9
+	addl	20(%rsp),%ebp
+	xorl	%edx,%ecx
+	movl	%eax,%esi
+	roll	$5,%eax
+	pxor	%xmm9,%xmm5
+	andl	%ecx,%edi
+	xorl	%edx,%ecx
+	movdqa	%xmm10,0(%rsp)
+	xorl	%edx,%edi
+	addl	%eax,%ebp
+	movdqa	%xmm5,%xmm8
+	movdqa	%xmm5,%xmm9
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	addl	24(%rsp),%edx
+	xorl	%ecx,%ebx
+	pslldq	$12,%xmm8
+	paddd	%xmm5,%xmm5
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	andl	%ebx,%esi
+	xorl	%ecx,%ebx
+	psrld	$31,%xmm9
+	xorl	%ecx,%esi
+	addl	%ebp,%edx
+	movdqa	%xmm8,%xmm10
+	rorl	$7,%eax
+	addl	%esi,%edx
+	psrld	$30,%xmm8
+	por	%xmm9,%xmm5
+	addl	28(%rsp),%ecx
+	xorl	%ebx,%eax
+	movl	%edx,%esi
+	roll	$5,%edx
+	pslld	$2,%xmm10
+	pxor	%xmm8,%xmm5
+	andl	%eax,%edi
+	xorl	%ebx,%eax
+	movdqa	16(%r11),%xmm8
+	xorl	%ebx,%edi
+	addl	%edx,%ecx
+	pxor	%xmm10,%xmm5
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	movdqa	%xmm3,%xmm6
+	addl	32(%rsp),%ebx
+	xorl	%eax,%ebp
+	movdqa	%xmm5,%xmm10
+.byte	102,15,58,15,242,8
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	paddd	%xmm5,%xmm8
+	andl	%ebp,%esi
+	xorl	%eax,%ebp
+	psrldq	$4,%xmm10
+	xorl	%eax,%esi
+	addl	%ecx,%ebx
+	pxor	%xmm2,%xmm6
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	pxor	%xmm4,%xmm10
+	addl	36(%rsp),%eax
+	xorl	%ebp,%edx
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	pxor	%xmm10,%xmm6
+	andl	%edx,%edi
+	xorl	%ebp,%edx
+	movdqa	%xmm8,16(%rsp)
+	xorl	%ebp,%edi
+	addl	%ebx,%eax
+	movdqa	%xmm6,%xmm9
+	movdqa	%xmm6,%xmm10
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	addl	40(%rsp),%ebp
+	xorl	%edx,%ecx
+	pslldq	$12,%xmm9
+	paddd	%xmm6,%xmm6
+	movl	%eax,%edi
+	roll	$5,%eax
+	andl	%ecx,%esi
+	xorl	%edx,%ecx
+	psrld	$31,%xmm10
+	xorl	%edx,%esi
+	addl	%eax,%ebp
+	movdqa	%xmm9,%xmm8
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	psrld	$30,%xmm9
+	por	%xmm10,%xmm6
+	addl	44(%rsp),%edx
+	xorl	%ecx,%ebx
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	pslld	$2,%xmm8
+	pxor	%xmm9,%xmm6
+	andl	%ebx,%edi
+	xorl	%ecx,%ebx
+	movdqa	16(%r11),%xmm9
+	xorl	%ecx,%edi
+	addl	%ebp,%edx
+	pxor	%xmm8,%xmm6
+	rorl	$7,%eax
+	addl	%edi,%edx
+	movdqa	%xmm4,%xmm7
+	addl	48(%rsp),%ecx
+	xorl	%ebx,%eax
+	movdqa	%xmm6,%xmm8
+.byte	102,15,58,15,251,8
+	movl	%edx,%edi
+	roll	$5,%edx
+	paddd	%xmm6,%xmm9
+	andl	%eax,%esi
+	xorl	%ebx,%eax
+	psrldq	$4,%xmm8
+	xorl	%ebx,%esi
+	addl	%edx,%ecx
+	pxor	%xmm3,%xmm7
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	pxor	%xmm5,%xmm8
+	addl	52(%rsp),%ebx
+	xorl	%eax,%ebp
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	pxor	%xmm8,%xmm7
+	andl	%ebp,%edi
+	xorl	%eax,%ebp
+	movdqa	%xmm9,32(%rsp)
+	xorl	%eax,%edi
+	addl	%ecx,%ebx
+	movdqa	%xmm7,%xmm10
+	movdqa	%xmm7,%xmm8
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	addl	56(%rsp),%eax
+	xorl	%ebp,%edx
+	pslldq	$12,%xmm10
+	paddd	%xmm7,%xmm7
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	andl	%edx,%esi
+	xorl	%ebp,%edx
+	psrld	$31,%xmm8
+	xorl	%ebp,%esi
+	addl	%ebx,%eax
+	movdqa	%xmm10,%xmm9
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	psrld	$30,%xmm10
+	por	%xmm8,%xmm7
+	addl	60(%rsp),%ebp
+	xorl	%edx,%ecx
+	movl	%eax,%esi
+	roll	$5,%eax
+	pslld	$2,%xmm9
+	pxor	%xmm10,%xmm7
+	andl	%ecx,%edi
+	xorl	%edx,%ecx
+	movdqa	16(%r11),%xmm10
+	xorl	%edx,%edi
+	addl	%eax,%ebp
+	pxor	%xmm9,%xmm7
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	movdqa	%xmm7,%xmm9
+	addl	0(%rsp),%edx
+	pxor	%xmm4,%xmm0
+.byte	102,68,15,58,15,206,8
+	xorl	%ecx,%ebx
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	pxor	%xmm1,%xmm0
+	andl	%ebx,%esi
+	xorl	%ecx,%ebx
+	movdqa	%xmm10,%xmm8
+	paddd	%xmm7,%xmm10
+	xorl	%ecx,%esi
+	addl	%ebp,%edx
+	pxor	%xmm9,%xmm0
+	rorl	$7,%eax
+	addl	%esi,%edx
+	addl	4(%rsp),%ecx
+	xorl	%ebx,%eax
+	movdqa	%xmm0,%xmm9
+	movdqa	%xmm10,48(%rsp)
+	movl	%edx,%esi
+	roll	$5,%edx
+	andl	%eax,%edi
+	xorl	%ebx,%eax
+	pslld	$2,%xmm0
+	xorl	%ebx,%edi
+	addl	%edx,%ecx
+	psrld	$30,%xmm9
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	addl	8(%rsp),%ebx
+	xorl	%eax,%ebp
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	por	%xmm9,%xmm0
+	andl	%ebp,%esi
+	xorl	%eax,%ebp
+	movdqa	%xmm0,%xmm10
+	xorl	%eax,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	addl	12(%rsp),%eax
+	xorl	%ebp,%edx
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	andl	%edx,%edi
+	xorl	%ebp,%edx
+	xorl	%ebp,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	addl	16(%rsp),%ebp
+	pxor	%xmm5,%xmm1
+.byte	102,68,15,58,15,215,8
+	xorl	%edx,%esi
+	movl	%eax,%edi
+	roll	$5,%eax
+	pxor	%xmm2,%xmm1
+	xorl	%ecx,%esi
+	addl	%eax,%ebp
+	movdqa	%xmm8,%xmm9
+	paddd	%xmm0,%xmm8
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	pxor	%xmm10,%xmm1
+	addl	20(%rsp),%edx
+	xorl	%ecx,%edi
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	movdqa	%xmm1,%xmm10
+	movdqa	%xmm8,0(%rsp)
+	xorl	%ebx,%edi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%edi,%edx
+	pslld	$2,%xmm1
+	addl	24(%rsp),%ecx
+	xorl	%ebx,%esi
+	psrld	$30,%xmm10
+	movl	%edx,%edi
+	roll	$5,%edx
+	xorl	%eax,%esi
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	por	%xmm10,%xmm1
+	addl	28(%rsp),%ebx
+	xorl	%eax,%edi
+	movdqa	%xmm1,%xmm8
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	xorl	%ebp,%edi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	addl	32(%rsp),%eax
+	pxor	%xmm6,%xmm2
+.byte	102,68,15,58,15,192,8
+	xorl	%ebp,%esi
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	pxor	%xmm3,%xmm2
+	xorl	%edx,%esi
+	addl	%ebx,%eax
+	movdqa	32(%r11),%xmm10
+	paddd	%xmm1,%xmm9
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	pxor	%xmm8,%xmm2
+	addl	36(%rsp),%ebp
+	xorl	%edx,%edi
+	movl	%eax,%esi
+	roll	$5,%eax
+	movdqa	%xmm2,%xmm8
+	movdqa	%xmm9,16(%rsp)
+	xorl	%ecx,%edi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	pslld	$2,%xmm2
+	addl	40(%rsp),%edx
+	xorl	%ecx,%esi
+	psrld	$30,%xmm8
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	xorl	%ebx,%esi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%esi,%edx
+	por	%xmm8,%xmm2
+	addl	44(%rsp),%ecx
+	xorl	%ebx,%edi
+	movdqa	%xmm2,%xmm9
+	movl	%edx,%esi
+	roll	$5,%edx
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	addl	48(%rsp),%ebx
+	pxor	%xmm7,%xmm3
+.byte	102,68,15,58,15,201,8
+	xorl	%eax,%esi
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	pxor	%xmm4,%xmm3
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	movdqa	%xmm10,%xmm8
+	paddd	%xmm2,%xmm10
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	pxor	%xmm9,%xmm3
+	addl	52(%rsp),%eax
+	xorl	%ebp,%edi
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	movdqa	%xmm3,%xmm9
+	movdqa	%xmm10,32(%rsp)
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	pslld	$2,%xmm3
+	addl	56(%rsp),%ebp
+	xorl	%edx,%esi
+	psrld	$30,%xmm9
+	movl	%eax,%edi
+	roll	$5,%eax
+	xorl	%ecx,%esi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	por	%xmm9,%xmm3
+	addl	60(%rsp),%edx
+	xorl	%ecx,%edi
+	movdqa	%xmm3,%xmm10
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	xorl	%ebx,%edi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%edi,%edx
+	addl	0(%rsp),%ecx
+	pxor	%xmm0,%xmm4
+.byte	102,68,15,58,15,210,8
+	xorl	%ebx,%esi
+	movl	%edx,%edi
+	roll	$5,%edx
+	pxor	%xmm5,%xmm4
+	xorl	%eax,%esi
+	addl	%edx,%ecx
+	movdqa	%xmm8,%xmm9
+	paddd	%xmm3,%xmm8
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	pxor	%xmm10,%xmm4
+	addl	4(%rsp),%ebx
+	xorl	%eax,%edi
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	movdqa	%xmm4,%xmm10
+	movdqa	%xmm8,48(%rsp)
+	xorl	%ebp,%edi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	pslld	$2,%xmm4
+	addl	8(%rsp),%eax
+	xorl	%ebp,%esi
+	psrld	$30,%xmm10
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	xorl	%edx,%esi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	por	%xmm10,%xmm4
+	addl	12(%rsp),%ebp
+	xorl	%edx,%edi
+	movdqa	%xmm4,%xmm8
+	movl	%eax,%esi
+	roll	$5,%eax
+	xorl	%ecx,%edi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	addl	16(%rsp),%edx
+	pxor	%xmm1,%xmm5
+.byte	102,68,15,58,15,195,8
+	xorl	%ecx,%esi
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	pxor	%xmm6,%xmm5
+	xorl	%ebx,%esi
+	addl	%ebp,%edx
+	movdqa	%xmm9,%xmm10
+	paddd	%xmm4,%xmm9
+	rorl	$7,%eax
+	addl	%esi,%edx
+	pxor	%xmm8,%xmm5
+	addl	20(%rsp),%ecx
+	xorl	%ebx,%edi
+	movl	%edx,%esi
+	roll	$5,%edx
+	movdqa	%xmm5,%xmm8
+	movdqa	%xmm9,0(%rsp)
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	pslld	$2,%xmm5
+	addl	24(%rsp),%ebx
+	xorl	%eax,%esi
+	psrld	$30,%xmm8
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	por	%xmm8,%xmm5
+	addl	28(%rsp),%eax
+	xorl	%ebp,%edi
+	movdqa	%xmm5,%xmm9
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	movl	%ecx,%edi
+	pxor	%xmm2,%xmm6
+.byte	102,68,15,58,15,204,8
+	xorl	%edx,%ecx
+	addl	32(%rsp),%ebp
+	andl	%edx,%edi
+	pxor	%xmm7,%xmm6
+	andl	%ecx,%esi
+	rorl	$7,%ebx
+	movdqa	%xmm10,%xmm8
+	paddd	%xmm5,%xmm10
+	addl	%edi,%ebp
+	movl	%eax,%edi
+	pxor	%xmm9,%xmm6
+	roll	$5,%eax
+	addl	%esi,%ebp
+	xorl	%edx,%ecx
+	addl	%eax,%ebp
+	movdqa	%xmm6,%xmm9
+	movdqa	%xmm10,16(%rsp)
+	movl	%ebx,%esi
+	xorl	%ecx,%ebx
+	addl	36(%rsp),%edx
+	andl	%ecx,%esi
+	pslld	$2,%xmm6
+	andl	%ebx,%edi
+	rorl	$7,%eax
+	psrld	$30,%xmm9
+	addl	%esi,%edx
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	addl	%edi,%edx
+	xorl	%ecx,%ebx
+	addl	%ebp,%edx
+	por	%xmm9,%xmm6
+	movl	%eax,%edi
+	xorl	%ebx,%eax
+	movdqa	%xmm6,%xmm10
+	addl	40(%rsp),%ecx
+	andl	%ebx,%edi
+	andl	%eax,%esi
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	movl	%edx,%edi
+	roll	$5,%edx
+	addl	%esi,%ecx
+	xorl	%ebx,%eax
+	addl	%edx,%ecx
+	movl	%ebp,%esi
+	xorl	%eax,%ebp
+	addl	44(%rsp),%ebx
+	andl	%eax,%esi
+	andl	%ebp,%edi
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	addl	%edi,%ebx
+	xorl	%eax,%ebp
+	addl	%ecx,%ebx
+	movl	%edx,%edi
+	pxor	%xmm3,%xmm7
+.byte	102,68,15,58,15,213,8
+	xorl	%ebp,%edx
+	addl	48(%rsp),%eax
+	andl	%ebp,%edi
+	pxor	%xmm0,%xmm7
+	andl	%edx,%esi
+	rorl	$7,%ecx
+	movdqa	48(%r11),%xmm9
+	paddd	%xmm6,%xmm8
+	addl	%edi,%eax
+	movl	%ebx,%edi
+	pxor	%xmm10,%xmm7
+	roll	$5,%ebx
+	addl	%esi,%eax
+	xorl	%ebp,%edx
+	addl	%ebx,%eax
+	movdqa	%xmm7,%xmm10
+	movdqa	%xmm8,32(%rsp)
+	movl	%ecx,%esi
+	xorl	%edx,%ecx
+	addl	52(%rsp),%ebp
+	andl	%edx,%esi
+	pslld	$2,%xmm7
+	andl	%ecx,%edi
+	rorl	$7,%ebx
+	psrld	$30,%xmm10
+	addl	%esi,%ebp
+	movl	%eax,%esi
+	roll	$5,%eax
+	addl	%edi,%ebp
+	xorl	%edx,%ecx
+	addl	%eax,%ebp
+	por	%xmm10,%xmm7
+	movl	%ebx,%edi
+	xorl	%ecx,%ebx
+	movdqa	%xmm7,%xmm8
+	addl	56(%rsp),%edx
+	andl	%ecx,%edi
+	andl	%ebx,%esi
+	rorl	$7,%eax
+	addl	%edi,%edx
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	addl	%esi,%edx
+	xorl	%ecx,%ebx
+	addl	%ebp,%edx
+	movl	%eax,%esi
+	xorl	%ebx,%eax
+	addl	60(%rsp),%ecx
+	andl	%ebx,%esi
+	andl	%eax,%edi
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	movl	%edx,%esi
+	roll	$5,%edx
+	addl	%edi,%ecx
+	xorl	%ebx,%eax
+	addl	%edx,%ecx
+	movl	%ebp,%edi
+	pxor	%xmm4,%xmm0
+.byte	102,68,15,58,15,198,8
+	xorl	%eax,%ebp
+	addl	0(%rsp),%ebx
+	andl	%eax,%edi
+	pxor	%xmm1,%xmm0
+	andl	%ebp,%esi
+	rorl	$7,%edx
+	movdqa	%xmm9,%xmm10
+	paddd	%xmm7,%xmm9
+	addl	%edi,%ebx
+	movl	%ecx,%edi
+	pxor	%xmm8,%xmm0
+	roll	$5,%ecx
+	addl	%esi,%ebx
+	xorl	%eax,%ebp
+	addl	%ecx,%ebx
+	movdqa	%xmm0,%xmm8
+	movdqa	%xmm9,48(%rsp)
+	movl	%edx,%esi
+	xorl	%ebp,%edx
+	addl	4(%rsp),%eax
+	andl	%ebp,%esi
+	pslld	$2,%xmm0
+	andl	%edx,%edi
+	rorl	$7,%ecx
+	psrld	$30,%xmm8
+	addl	%esi,%eax
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	addl	%edi,%eax
+	xorl	%ebp,%edx
+	addl	%ebx,%eax
+	por	%xmm8,%xmm0
+	movl	%ecx,%edi
+	xorl	%edx,%ecx
+	movdqa	%xmm0,%xmm9
+	addl	8(%rsp),%ebp
+	andl	%edx,%edi
+	andl	%ecx,%esi
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	movl	%eax,%edi
+	roll	$5,%eax
+	addl	%esi,%ebp
+	xorl	%edx,%ecx
+	addl	%eax,%ebp
+	movl	%ebx,%esi
+	xorl	%ecx,%ebx
+	addl	12(%rsp),%edx
+	andl	%ecx,%esi
+	andl	%ebx,%edi
+	rorl	$7,%eax
+	addl	%esi,%edx
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	addl	%edi,%edx
+	xorl	%ecx,%ebx
+	addl	%ebp,%edx
+	movl	%eax,%edi
+	pxor	%xmm5,%xmm1
+.byte	102,68,15,58,15,207,8
+	xorl	%ebx,%eax
+	addl	16(%rsp),%ecx
+	andl	%ebx,%edi
+	pxor	%xmm2,%xmm1
+	andl	%eax,%esi
+	rorl	$7,%ebp
+	movdqa	%xmm10,%xmm8
+	paddd	%xmm0,%xmm10
+	addl	%edi,%ecx
+	movl	%edx,%edi
+	pxor	%xmm9,%xmm1
+	roll	$5,%edx
+	addl	%esi,%ecx
+	xorl	%ebx,%eax
+	addl	%edx,%ecx
+	movdqa	%xmm1,%xmm9
+	movdqa	%xmm10,0(%rsp)
+	movl	%ebp,%esi
+	xorl	%eax,%ebp
+	addl	20(%rsp),%ebx
+	andl	%eax,%esi
+	pslld	$2,%xmm1
+	andl	%ebp,%edi
+	rorl	$7,%edx
+	psrld	$30,%xmm9
+	addl	%esi,%ebx
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	addl	%edi,%ebx
+	xorl	%eax,%ebp
+	addl	%ecx,%ebx
+	por	%xmm9,%xmm1
+	movl	%edx,%edi
+	xorl	%ebp,%edx
+	movdqa	%xmm1,%xmm10
+	addl	24(%rsp),%eax
+	andl	%ebp,%edi
+	andl	%edx,%esi
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	addl	%esi,%eax
+	xorl	%ebp,%edx
+	addl	%ebx,%eax
+	movl	%ecx,%esi
+	xorl	%edx,%ecx
+	addl	28(%rsp),%ebp
+	andl	%edx,%esi
+	andl	%ecx,%edi
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	movl	%eax,%esi
+	roll	$5,%eax
+	addl	%edi,%ebp
+	xorl	%edx,%ecx
+	addl	%eax,%ebp
+	movl	%ebx,%edi
+	pxor	%xmm6,%xmm2
+.byte	102,68,15,58,15,208,8
+	xorl	%ecx,%ebx
+	addl	32(%rsp),%edx
+	andl	%ecx,%edi
+	pxor	%xmm3,%xmm2
+	andl	%ebx,%esi
+	rorl	$7,%eax
+	movdqa	%xmm8,%xmm9
+	paddd	%xmm1,%xmm8
+	addl	%edi,%edx
+	movl	%ebp,%edi
+	pxor	%xmm10,%xmm2
+	roll	$5,%ebp
+	addl	%esi,%edx
+	xorl	%ecx,%ebx
+	addl	%ebp,%edx
+	movdqa	%xmm2,%xmm10
+	movdqa	%xmm8,16(%rsp)
+	movl	%eax,%esi
+	xorl	%ebx,%eax
+	addl	36(%rsp),%ecx
+	andl	%ebx,%esi
+	pslld	$2,%xmm2
+	andl	%eax,%edi
+	rorl	$7,%ebp
+	psrld	$30,%xmm10
+	addl	%esi,%ecx
+	movl	%edx,%esi
+	roll	$5,%edx
+	addl	%edi,%ecx
+	xorl	%ebx,%eax
+	addl	%edx,%ecx
+	por	%xmm10,%xmm2
+	movl	%ebp,%edi
+	xorl	%eax,%ebp
+	movdqa	%xmm2,%xmm8
+	addl	40(%rsp),%ebx
+	andl	%eax,%edi
+	andl	%ebp,%esi
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	addl	%esi,%ebx
+	xorl	%eax,%ebp
+	addl	%ecx,%ebx
+	movl	%edx,%esi
+	xorl	%ebp,%edx
+	addl	44(%rsp),%eax
+	andl	%ebp,%esi
+	andl	%edx,%edi
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	addl	%edi,%eax
+	xorl	%ebp,%edx
+	addl	%ebx,%eax
+	addl	48(%rsp),%ebp
+	pxor	%xmm7,%xmm3
+.byte	102,68,15,58,15,193,8
+	xorl	%edx,%esi
+	movl	%eax,%edi
+	roll	$5,%eax
+	pxor	%xmm4,%xmm3
+	xorl	%ecx,%esi
+	addl	%eax,%ebp
+	movdqa	%xmm9,%xmm10
+	paddd	%xmm2,%xmm9
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	pxor	%xmm8,%xmm3
+	addl	52(%rsp),%edx
+	xorl	%ecx,%edi
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	movdqa	%xmm3,%xmm8
+	movdqa	%xmm9,32(%rsp)
+	xorl	%ebx,%edi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%edi,%edx
+	pslld	$2,%xmm3
+	addl	56(%rsp),%ecx
+	xorl	%ebx,%esi
+	psrld	$30,%xmm8
+	movl	%edx,%edi
+	roll	$5,%edx
+	xorl	%eax,%esi
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	por	%xmm8,%xmm3
+	addl	60(%rsp),%ebx
+	xorl	%eax,%edi
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	xorl	%ebp,%edi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	addl	0(%rsp),%eax
+	paddd	%xmm3,%xmm10
+	xorl	%ebp,%esi
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	xorl	%edx,%esi
+	movdqa	%xmm10,48(%rsp)
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	addl	4(%rsp),%ebp
+	xorl	%edx,%edi
+	movl	%eax,%esi
+	roll	$5,%eax
+	xorl	%ecx,%edi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	addl	8(%rsp),%edx
+	xorl	%ecx,%esi
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	xorl	%ebx,%esi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%esi,%edx
+	addl	12(%rsp),%ecx
+	xorl	%ebx,%edi
+	movl	%edx,%esi
+	roll	$5,%edx
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	cmpq	%r10,%r9
+	je	L$done_ssse3
+	movdqa	64(%r11),%xmm6
+	movdqa	0(%r11),%xmm9
+	movdqu	0(%r9),%xmm0
+	movdqu	16(%r9),%xmm1
+	movdqu	32(%r9),%xmm2
+	movdqu	48(%r9),%xmm3
+.byte	102,15,56,0,198
+	addq	$64,%r9
+	addl	16(%rsp),%ebx
+	xorl	%eax,%esi
+.byte	102,15,56,0,206
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	paddd	%xmm9,%xmm0
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	movdqa	%xmm0,0(%rsp)
+	addl	20(%rsp),%eax
+	xorl	%ebp,%edi
+	psubd	%xmm9,%xmm0
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	addl	24(%rsp),%ebp
+	xorl	%edx,%esi
+	movl	%eax,%edi
+	roll	$5,%eax
+	xorl	%ecx,%esi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	addl	28(%rsp),%edx
+	xorl	%ecx,%edi
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	xorl	%ebx,%edi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%edi,%edx
+	addl	32(%rsp),%ecx
+	xorl	%ebx,%esi
+.byte	102,15,56,0,214
+	movl	%edx,%edi
+	roll	$5,%edx
+	paddd	%xmm9,%xmm1
+	xorl	%eax,%esi
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	movdqa	%xmm1,16(%rsp)
+	addl	36(%rsp),%ebx
+	xorl	%eax,%edi
+	psubd	%xmm9,%xmm1
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	xorl	%ebp,%edi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	addl	40(%rsp),%eax
+	xorl	%ebp,%esi
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	xorl	%edx,%esi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	addl	44(%rsp),%ebp
+	xorl	%edx,%edi
+	movl	%eax,%esi
+	roll	$5,%eax
+	xorl	%ecx,%edi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	addl	48(%rsp),%edx
+	xorl	%ecx,%esi
+.byte	102,15,56,0,222
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	paddd	%xmm9,%xmm2
+	xorl	%ebx,%esi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%esi,%edx
+	movdqa	%xmm2,32(%rsp)
+	addl	52(%rsp),%ecx
+	xorl	%ebx,%edi
+	psubd	%xmm9,%xmm2
+	movl	%edx,%esi
+	roll	$5,%edx
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	addl	56(%rsp),%ebx
+	xorl	%eax,%esi
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	addl	60(%rsp),%eax
+	xorl	%ebp,%edi
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	addl	0(%r8),%eax
+	addl	4(%r8),%esi
+	addl	8(%r8),%ecx
+	addl	12(%r8),%edx
+	movl	%eax,0(%r8)
+	addl	16(%r8),%ebp
+	movl	%esi,4(%r8)
+	movl	%esi,%ebx
+	movl	%ecx,8(%r8)
+	movl	%edx,12(%r8)
+	movl	%ebp,16(%r8)
+	jmp	L$oop_ssse3
+
+.p2align	4
+L$done_ssse3:
+	addl	16(%rsp),%ebx
+	xorl	%eax,%esi
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	addl	20(%rsp),%eax
+	xorl	%ebp,%edi
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	addl	24(%rsp),%ebp
+	xorl	%edx,%esi
+	movl	%eax,%edi
+	roll	$5,%eax
+	xorl	%ecx,%esi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%esi,%ebp
+	addl	28(%rsp),%edx
+	xorl	%ecx,%edi
+	movl	%ebp,%esi
+	roll	$5,%ebp
+	xorl	%ebx,%edi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%edi,%edx
+	addl	32(%rsp),%ecx
+	xorl	%ebx,%esi
+	movl	%edx,%edi
+	roll	$5,%edx
+	xorl	%eax,%esi
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%esi,%ecx
+	addl	36(%rsp),%ebx
+	xorl	%eax,%edi
+	movl	%ecx,%esi
+	roll	$5,%ecx
+	xorl	%ebp,%edi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%edi,%ebx
+	addl	40(%rsp),%eax
+	xorl	%ebp,%esi
+	movl	%ebx,%edi
+	roll	$5,%ebx
+	xorl	%edx,%esi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%esi,%eax
+	addl	44(%rsp),%ebp
+	xorl	%edx,%edi
+	movl	%eax,%esi
+	roll	$5,%eax
+	xorl	%ecx,%edi
+	addl	%eax,%ebp
+	rorl	$7,%ebx
+	addl	%edi,%ebp
+	addl	48(%rsp),%edx
+	xorl	%ecx,%esi
+	movl	%ebp,%edi
+	roll	$5,%ebp
+	xorl	%ebx,%esi
+	addl	%ebp,%edx
+	rorl	$7,%eax
+	addl	%esi,%edx
+	addl	52(%rsp),%ecx
+	xorl	%ebx,%edi
+	movl	%edx,%esi
+	roll	$5,%edx
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	rorl	$7,%ebp
+	addl	%edi,%ecx
+	addl	56(%rsp),%ebx
+	xorl	%eax,%esi
+	movl	%ecx,%edi
+	roll	$5,%ecx
+	xorl	%ebp,%esi
+	addl	%ecx,%ebx
+	rorl	$7,%edx
+	addl	%esi,%ebx
+	addl	60(%rsp),%eax
+	xorl	%ebp,%edi
+	movl	%ebx,%esi
+	roll	$5,%ebx
+	xorl	%edx,%edi
+	addl	%ebx,%eax
+	rorl	$7,%ecx
+	addl	%edi,%eax
+	addl	0(%r8),%eax
+	addl	4(%r8),%esi
+	addl	8(%r8),%ecx
+	movl	%eax,0(%r8)
+	addl	12(%r8),%edx
+	movl	%esi,4(%r8)
+	addl	16(%r8),%ebp
+	movl	%ecx,8(%r8)
+	movl	%edx,12(%r8)
+	movl	%ebp,16(%r8)
+	leaq	64(%rsp),%rsi
+	movq	0(%rsi),%r12
+	movq	8(%rsi),%rbp
+	movq	16(%rsi),%rbx
+	leaq	24(%rsi),%rsp
+L$epilogue_ssse3:
+	.byte	0xf3,0xc3
+
+.p2align	6
+K_XX_XX:
+.long	0x5a827999,0x5a827999,0x5a827999,0x5a827999	
+.long	0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1	
+.long	0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc	
+.long	0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6	
+.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f	
+.byte	83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.p2align	6
diff --git a/crypto/libressl/crypto/sha/sha1_one.c b/crypto/libressl/crypto/sha/sha1_one.c
new file mode 100644
index 0000000000..7ec50af026
--- /dev/null
+++ b/crypto/libressl/crypto/sha/sha1_one.c
@@ -0,0 +1,81 @@
+/* $OpenBSD: sha1_one.c,v 1.11 2014/07/10 22:45:58 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+
+#ifndef OPENSSL_NO_SHA1
+unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md)
+	{
+	SHA_CTX c;
+	static unsigned char m[SHA_DIGEST_LENGTH];
+
+	if (md == NULL) md=m;
+	if (!SHA1_Init(&c))
+		return NULL;
+	SHA1_Update(&c,d,n);
+	SHA1_Final(md,&c);
+	explicit_bzero(&c,sizeof(c));
+	return(md);
+	}
+#endif
diff --git a/crypto/libressl/crypto/sha/sha1dgst.c b/crypto/libressl/crypto/sha/sha1dgst.c
new file mode 100644
index 0000000000..39a4f5410a
--- /dev/null
+++ b/crypto/libressl/crypto/sha/sha1dgst.c
@@ -0,0 +1,72 @@
+/* $OpenBSD: sha1dgst.c,v 1.13 2014/07/10 22:45:58 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#if !defined(OPENSSL_NO_SHA1) && !defined(OPENSSL_NO_SHA)
+
+#include 
+
+/* The implementation is in ../md32_common.h */
+
+#include "sha_locl.h"
+
+#endif
+
diff --git a/crypto/libressl/crypto/sha/sha256-elf-x86_64.S b/crypto/libressl/crypto/sha/sha256-elf-x86_64.S
new file mode 100644
index 0000000000..f4f6fc6fe1
--- /dev/null
+++ b/crypto/libressl/crypto/sha/sha256-elf-x86_64.S
@@ -0,0 +1,1781 @@
+.text	
+
+.globl	sha256_block_data_order
+.type	sha256_block_data_order,@function
+.align	16
+sha256_block_data_order:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	movq	%rsp,%r11
+	shlq	$4,%rdx
+	subq	$64+32,%rsp
+	leaq	(%rsi,%rdx,4),%rdx
+	andq	$-64,%rsp
+	movq	%rdi,64+0(%rsp)
+	movq	%rsi,64+8(%rsp)
+	movq	%rdx,64+16(%rsp)
+	movq	%r11,64+24(%rsp)
+.Lprologue:
+
+	leaq	K256(%rip),%rbp
+
+	movl	0(%rdi),%eax
+	movl	4(%rdi),%ebx
+	movl	8(%rdi),%ecx
+	movl	12(%rdi),%edx
+	movl	16(%rdi),%r8d
+	movl	20(%rdi),%r9d
+	movl	24(%rdi),%r10d
+	movl	28(%rdi),%r11d
+	jmp	.Lloop
+
+.align	16
+.Lloop:
+	xorq	%rdi,%rdi
+	movl	0(%rsi),%r12d
+	movl	%r8d,%r13d
+	movl	%eax,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%r9d,%r15d
+	movl	%r12d,0(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r11d,%r12d
+	xorl	%eax,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r8d,%r15d
+	movl	%ebx,%r11d
+
+	rorl	$11,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r15d
+
+	xorl	%ecx,%r11d
+	xorl	%eax,%r14d
+	addl	%r15d,%r12d
+	movl	%ebx,%r15d
+
+	rorl	$6,%r13d
+	andl	%eax,%r11d
+	andl	%ecx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r11d
+
+	addl	%r12d,%edx
+	addl	%r12d,%r11d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r11d
+
+	movl	4(%rsi),%r12d
+	movl	%edx,%r13d
+	movl	%r11d,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%r8d,%r15d
+	movl	%r12d,4(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%edx,%r13d
+	xorl	%r9d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r10d,%r12d
+	xorl	%r11d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%edx,%r15d
+	movl	%eax,%r10d
+
+	rorl	$11,%r14d
+	xorl	%edx,%r13d
+	xorl	%r9d,%r15d
+
+	xorl	%ebx,%r10d
+	xorl	%r11d,%r14d
+	addl	%r15d,%r12d
+	movl	%eax,%r15d
+
+	rorl	$6,%r13d
+	andl	%r11d,%r10d
+	andl	%ebx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r10d
+
+	addl	%r12d,%ecx
+	addl	%r12d,%r10d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r10d
+
+	movl	8(%rsi),%r12d
+	movl	%ecx,%r13d
+	movl	%r10d,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%edx,%r15d
+	movl	%r12d,8(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%ecx,%r13d
+	xorl	%r8d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r9d,%r12d
+	xorl	%r10d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%ecx,%r15d
+	movl	%r11d,%r9d
+
+	rorl	$11,%r14d
+	xorl	%ecx,%r13d
+	xorl	%r8d,%r15d
+
+	xorl	%eax,%r9d
+	xorl	%r10d,%r14d
+	addl	%r15d,%r12d
+	movl	%r11d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r10d,%r9d
+	andl	%eax,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r9d
+
+	addl	%r12d,%ebx
+	addl	%r12d,%r9d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r9d
+
+	movl	12(%rsi),%r12d
+	movl	%ebx,%r13d
+	movl	%r9d,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%ecx,%r15d
+	movl	%r12d,12(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r15d
+
+	rorl	$5,%r13d
+	addl	%r8d,%r12d
+	xorl	%r9d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%ebx,%r15d
+	movl	%r10d,%r8d
+
+	rorl	$11,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r15d
+
+	xorl	%r11d,%r8d
+	xorl	%r9d,%r14d
+	addl	%r15d,%r12d
+	movl	%r10d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r9d,%r8d
+	andl	%r11d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r8d
+
+	addl	%r12d,%eax
+	addl	%r12d,%r8d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r8d
+
+	movl	16(%rsi),%r12d
+	movl	%eax,%r13d
+	movl	%r8d,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%ebx,%r15d
+	movl	%r12d,16(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r15d
+
+	rorl	$5,%r13d
+	addl	%edx,%r12d
+	xorl	%r8d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%eax,%r15d
+	movl	%r9d,%edx
+
+	rorl	$11,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r15d
+
+	xorl	%r10d,%edx
+	xorl	%r8d,%r14d
+	addl	%r15d,%r12d
+	movl	%r9d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r8d,%edx
+	andl	%r10d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%edx
+
+	addl	%r12d,%r11d
+	addl	%r12d,%edx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%edx
+
+	movl	20(%rsi),%r12d
+	movl	%r11d,%r13d
+	movl	%edx,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%eax,%r15d
+	movl	%r12d,20(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r15d
+
+	rorl	$5,%r13d
+	addl	%ecx,%r12d
+	xorl	%edx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r11d,%r15d
+	movl	%r8d,%ecx
+
+	rorl	$11,%r14d
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r15d
+
+	xorl	%r9d,%ecx
+	xorl	%edx,%r14d
+	addl	%r15d,%r12d
+	movl	%r8d,%r15d
+
+	rorl	$6,%r13d
+	andl	%edx,%ecx
+	andl	%r9d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%ecx
+
+	addl	%r12d,%r10d
+	addl	%r12d,%ecx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%ecx
+
+	movl	24(%rsi),%r12d
+	movl	%r10d,%r13d
+	movl	%ecx,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%r11d,%r15d
+	movl	%r12d,24(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r10d,%r13d
+	xorl	%eax,%r15d
+
+	rorl	$5,%r13d
+	addl	%ebx,%r12d
+	xorl	%ecx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r10d,%r15d
+	movl	%edx,%ebx
+
+	rorl	$11,%r14d
+	xorl	%r10d,%r13d
+	xorl	%eax,%r15d
+
+	xorl	%r8d,%ebx
+	xorl	%ecx,%r14d
+	addl	%r15d,%r12d
+	movl	%edx,%r15d
+
+	rorl	$6,%r13d
+	andl	%ecx,%ebx
+	andl	%r8d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%ebx
+
+	addl	%r12d,%r9d
+	addl	%r12d,%ebx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%ebx
+
+	movl	28(%rsi),%r12d
+	movl	%r9d,%r13d
+	movl	%ebx,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%r10d,%r15d
+	movl	%r12d,28(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r15d
+
+	rorl	$5,%r13d
+	addl	%eax,%r12d
+	xorl	%ebx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r9d,%r15d
+	movl	%ecx,%eax
+
+	rorl	$11,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r15d
+
+	xorl	%edx,%eax
+	xorl	%ebx,%r14d
+	addl	%r15d,%r12d
+	movl	%ecx,%r15d
+
+	rorl	$6,%r13d
+	andl	%ebx,%eax
+	andl	%edx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%eax
+
+	addl	%r12d,%r8d
+	addl	%r12d,%eax
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%eax
+
+	movl	32(%rsi),%r12d
+	movl	%r8d,%r13d
+	movl	%eax,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%r9d,%r15d
+	movl	%r12d,32(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r11d,%r12d
+	xorl	%eax,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r8d,%r15d
+	movl	%ebx,%r11d
+
+	rorl	$11,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r15d
+
+	xorl	%ecx,%r11d
+	xorl	%eax,%r14d
+	addl	%r15d,%r12d
+	movl	%ebx,%r15d
+
+	rorl	$6,%r13d
+	andl	%eax,%r11d
+	andl	%ecx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r11d
+
+	addl	%r12d,%edx
+	addl	%r12d,%r11d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r11d
+
+	movl	36(%rsi),%r12d
+	movl	%edx,%r13d
+	movl	%r11d,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%r8d,%r15d
+	movl	%r12d,36(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%edx,%r13d
+	xorl	%r9d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r10d,%r12d
+	xorl	%r11d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%edx,%r15d
+	movl	%eax,%r10d
+
+	rorl	$11,%r14d
+	xorl	%edx,%r13d
+	xorl	%r9d,%r15d
+
+	xorl	%ebx,%r10d
+	xorl	%r11d,%r14d
+	addl	%r15d,%r12d
+	movl	%eax,%r15d
+
+	rorl	$6,%r13d
+	andl	%r11d,%r10d
+	andl	%ebx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r10d
+
+	addl	%r12d,%ecx
+	addl	%r12d,%r10d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r10d
+
+	movl	40(%rsi),%r12d
+	movl	%ecx,%r13d
+	movl	%r10d,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%edx,%r15d
+	movl	%r12d,40(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%ecx,%r13d
+	xorl	%r8d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r9d,%r12d
+	xorl	%r10d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%ecx,%r15d
+	movl	%r11d,%r9d
+
+	rorl	$11,%r14d
+	xorl	%ecx,%r13d
+	xorl	%r8d,%r15d
+
+	xorl	%eax,%r9d
+	xorl	%r10d,%r14d
+	addl	%r15d,%r12d
+	movl	%r11d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r10d,%r9d
+	andl	%eax,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r9d
+
+	addl	%r12d,%ebx
+	addl	%r12d,%r9d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r9d
+
+	movl	44(%rsi),%r12d
+	movl	%ebx,%r13d
+	movl	%r9d,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%ecx,%r15d
+	movl	%r12d,44(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r15d
+
+	rorl	$5,%r13d
+	addl	%r8d,%r12d
+	xorl	%r9d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%ebx,%r15d
+	movl	%r10d,%r8d
+
+	rorl	$11,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r15d
+
+	xorl	%r11d,%r8d
+	xorl	%r9d,%r14d
+	addl	%r15d,%r12d
+	movl	%r10d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r9d,%r8d
+	andl	%r11d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r8d
+
+	addl	%r12d,%eax
+	addl	%r12d,%r8d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r8d
+
+	movl	48(%rsi),%r12d
+	movl	%eax,%r13d
+	movl	%r8d,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%ebx,%r15d
+	movl	%r12d,48(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r15d
+
+	rorl	$5,%r13d
+	addl	%edx,%r12d
+	xorl	%r8d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%eax,%r15d
+	movl	%r9d,%edx
+
+	rorl	$11,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r15d
+
+	xorl	%r10d,%edx
+	xorl	%r8d,%r14d
+	addl	%r15d,%r12d
+	movl	%r9d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r8d,%edx
+	andl	%r10d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%edx
+
+	addl	%r12d,%r11d
+	addl	%r12d,%edx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%edx
+
+	movl	52(%rsi),%r12d
+	movl	%r11d,%r13d
+	movl	%edx,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%eax,%r15d
+	movl	%r12d,52(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r15d
+
+	rorl	$5,%r13d
+	addl	%ecx,%r12d
+	xorl	%edx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r11d,%r15d
+	movl	%r8d,%ecx
+
+	rorl	$11,%r14d
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r15d
+
+	xorl	%r9d,%ecx
+	xorl	%edx,%r14d
+	addl	%r15d,%r12d
+	movl	%r8d,%r15d
+
+	rorl	$6,%r13d
+	andl	%edx,%ecx
+	andl	%r9d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%ecx
+
+	addl	%r12d,%r10d
+	addl	%r12d,%ecx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%ecx
+
+	movl	56(%rsi),%r12d
+	movl	%r10d,%r13d
+	movl	%ecx,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%r11d,%r15d
+	movl	%r12d,56(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r10d,%r13d
+	xorl	%eax,%r15d
+
+	rorl	$5,%r13d
+	addl	%ebx,%r12d
+	xorl	%ecx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r10d,%r15d
+	movl	%edx,%ebx
+
+	rorl	$11,%r14d
+	xorl	%r10d,%r13d
+	xorl	%eax,%r15d
+
+	xorl	%r8d,%ebx
+	xorl	%ecx,%r14d
+	addl	%r15d,%r12d
+	movl	%edx,%r15d
+
+	rorl	$6,%r13d
+	andl	%ecx,%ebx
+	andl	%r8d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%ebx
+
+	addl	%r12d,%r9d
+	addl	%r12d,%ebx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%ebx
+
+	movl	60(%rsi),%r12d
+	movl	%r9d,%r13d
+	movl	%ebx,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%r10d,%r15d
+	movl	%r12d,60(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r15d
+
+	rorl	$5,%r13d
+	addl	%eax,%r12d
+	xorl	%ebx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r9d,%r15d
+	movl	%ecx,%eax
+
+	rorl	$11,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r15d
+
+	xorl	%edx,%eax
+	xorl	%ebx,%r14d
+	addl	%r15d,%r12d
+	movl	%ecx,%r15d
+
+	rorl	$6,%r13d
+	andl	%ebx,%eax
+	andl	%edx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%eax
+
+	addl	%r12d,%r8d
+	addl	%r12d,%eax
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%eax
+
+	jmp	.Lrounds_16_xx
+.align	16
+.Lrounds_16_xx:
+	movl	4(%rsp),%r13d
+	movl	56(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	36(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	0(%rsp),%r12d
+	movl	%r8d,%r13d
+	addl	%r14d,%r12d
+	movl	%eax,%r14d
+	rorl	$14,%r13d
+	movl	%r9d,%r15d
+	movl	%r12d,0(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r11d,%r12d
+	xorl	%eax,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r8d,%r15d
+	movl	%ebx,%r11d
+
+	rorl	$11,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r15d
+
+	xorl	%ecx,%r11d
+	xorl	%eax,%r14d
+	addl	%r15d,%r12d
+	movl	%ebx,%r15d
+
+	rorl	$6,%r13d
+	andl	%eax,%r11d
+	andl	%ecx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r11d
+
+	addl	%r12d,%edx
+	addl	%r12d,%r11d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r11d
+
+	movl	8(%rsp),%r13d
+	movl	60(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	40(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	4(%rsp),%r12d
+	movl	%edx,%r13d
+	addl	%r14d,%r12d
+	movl	%r11d,%r14d
+	rorl	$14,%r13d
+	movl	%r8d,%r15d
+	movl	%r12d,4(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%edx,%r13d
+	xorl	%r9d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r10d,%r12d
+	xorl	%r11d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%edx,%r15d
+	movl	%eax,%r10d
+
+	rorl	$11,%r14d
+	xorl	%edx,%r13d
+	xorl	%r9d,%r15d
+
+	xorl	%ebx,%r10d
+	xorl	%r11d,%r14d
+	addl	%r15d,%r12d
+	movl	%eax,%r15d
+
+	rorl	$6,%r13d
+	andl	%r11d,%r10d
+	andl	%ebx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r10d
+
+	addl	%r12d,%ecx
+	addl	%r12d,%r10d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r10d
+
+	movl	12(%rsp),%r13d
+	movl	0(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	44(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	8(%rsp),%r12d
+	movl	%ecx,%r13d
+	addl	%r14d,%r12d
+	movl	%r10d,%r14d
+	rorl	$14,%r13d
+	movl	%edx,%r15d
+	movl	%r12d,8(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%ecx,%r13d
+	xorl	%r8d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r9d,%r12d
+	xorl	%r10d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%ecx,%r15d
+	movl	%r11d,%r9d
+
+	rorl	$11,%r14d
+	xorl	%ecx,%r13d
+	xorl	%r8d,%r15d
+
+	xorl	%eax,%r9d
+	xorl	%r10d,%r14d
+	addl	%r15d,%r12d
+	movl	%r11d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r10d,%r9d
+	andl	%eax,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r9d
+
+	addl	%r12d,%ebx
+	addl	%r12d,%r9d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r9d
+
+	movl	16(%rsp),%r13d
+	movl	4(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	48(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	12(%rsp),%r12d
+	movl	%ebx,%r13d
+	addl	%r14d,%r12d
+	movl	%r9d,%r14d
+	rorl	$14,%r13d
+	movl	%ecx,%r15d
+	movl	%r12d,12(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r15d
+
+	rorl	$5,%r13d
+	addl	%r8d,%r12d
+	xorl	%r9d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%ebx,%r15d
+	movl	%r10d,%r8d
+
+	rorl	$11,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r15d
+
+	xorl	%r11d,%r8d
+	xorl	%r9d,%r14d
+	addl	%r15d,%r12d
+	movl	%r10d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r9d,%r8d
+	andl	%r11d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r8d
+
+	addl	%r12d,%eax
+	addl	%r12d,%r8d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r8d
+
+	movl	20(%rsp),%r13d
+	movl	8(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	52(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	16(%rsp),%r12d
+	movl	%eax,%r13d
+	addl	%r14d,%r12d
+	movl	%r8d,%r14d
+	rorl	$14,%r13d
+	movl	%ebx,%r15d
+	movl	%r12d,16(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r15d
+
+	rorl	$5,%r13d
+	addl	%edx,%r12d
+	xorl	%r8d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%eax,%r15d
+	movl	%r9d,%edx
+
+	rorl	$11,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r15d
+
+	xorl	%r10d,%edx
+	xorl	%r8d,%r14d
+	addl	%r15d,%r12d
+	movl	%r9d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r8d,%edx
+	andl	%r10d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%edx
+
+	addl	%r12d,%r11d
+	addl	%r12d,%edx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%edx
+
+	movl	24(%rsp),%r13d
+	movl	12(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	56(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	20(%rsp),%r12d
+	movl	%r11d,%r13d
+	addl	%r14d,%r12d
+	movl	%edx,%r14d
+	rorl	$14,%r13d
+	movl	%eax,%r15d
+	movl	%r12d,20(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r15d
+
+	rorl	$5,%r13d
+	addl	%ecx,%r12d
+	xorl	%edx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r11d,%r15d
+	movl	%r8d,%ecx
+
+	rorl	$11,%r14d
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r15d
+
+	xorl	%r9d,%ecx
+	xorl	%edx,%r14d
+	addl	%r15d,%r12d
+	movl	%r8d,%r15d
+
+	rorl	$6,%r13d
+	andl	%edx,%ecx
+	andl	%r9d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%ecx
+
+	addl	%r12d,%r10d
+	addl	%r12d,%ecx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%ecx
+
+	movl	28(%rsp),%r13d
+	movl	16(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	60(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	24(%rsp),%r12d
+	movl	%r10d,%r13d
+	addl	%r14d,%r12d
+	movl	%ecx,%r14d
+	rorl	$14,%r13d
+	movl	%r11d,%r15d
+	movl	%r12d,24(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r10d,%r13d
+	xorl	%eax,%r15d
+
+	rorl	$5,%r13d
+	addl	%ebx,%r12d
+	xorl	%ecx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r10d,%r15d
+	movl	%edx,%ebx
+
+	rorl	$11,%r14d
+	xorl	%r10d,%r13d
+	xorl	%eax,%r15d
+
+	xorl	%r8d,%ebx
+	xorl	%ecx,%r14d
+	addl	%r15d,%r12d
+	movl	%edx,%r15d
+
+	rorl	$6,%r13d
+	andl	%ecx,%ebx
+	andl	%r8d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%ebx
+
+	addl	%r12d,%r9d
+	addl	%r12d,%ebx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%ebx
+
+	movl	32(%rsp),%r13d
+	movl	20(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	0(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	28(%rsp),%r12d
+	movl	%r9d,%r13d
+	addl	%r14d,%r12d
+	movl	%ebx,%r14d
+	rorl	$14,%r13d
+	movl	%r10d,%r15d
+	movl	%r12d,28(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r15d
+
+	rorl	$5,%r13d
+	addl	%eax,%r12d
+	xorl	%ebx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r9d,%r15d
+	movl	%ecx,%eax
+
+	rorl	$11,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r15d
+
+	xorl	%edx,%eax
+	xorl	%ebx,%r14d
+	addl	%r15d,%r12d
+	movl	%ecx,%r15d
+
+	rorl	$6,%r13d
+	andl	%ebx,%eax
+	andl	%edx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%eax
+
+	addl	%r12d,%r8d
+	addl	%r12d,%eax
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%eax
+
+	movl	36(%rsp),%r13d
+	movl	24(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	4(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	32(%rsp),%r12d
+	movl	%r8d,%r13d
+	addl	%r14d,%r12d
+	movl	%eax,%r14d
+	rorl	$14,%r13d
+	movl	%r9d,%r15d
+	movl	%r12d,32(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r11d,%r12d
+	xorl	%eax,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r8d,%r15d
+	movl	%ebx,%r11d
+
+	rorl	$11,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r15d
+
+	xorl	%ecx,%r11d
+	xorl	%eax,%r14d
+	addl	%r15d,%r12d
+	movl	%ebx,%r15d
+
+	rorl	$6,%r13d
+	andl	%eax,%r11d
+	andl	%ecx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r11d
+
+	addl	%r12d,%edx
+	addl	%r12d,%r11d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r11d
+
+	movl	40(%rsp),%r13d
+	movl	28(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	8(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	36(%rsp),%r12d
+	movl	%edx,%r13d
+	addl	%r14d,%r12d
+	movl	%r11d,%r14d
+	rorl	$14,%r13d
+	movl	%r8d,%r15d
+	movl	%r12d,36(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%edx,%r13d
+	xorl	%r9d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r10d,%r12d
+	xorl	%r11d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%edx,%r15d
+	movl	%eax,%r10d
+
+	rorl	$11,%r14d
+	xorl	%edx,%r13d
+	xorl	%r9d,%r15d
+
+	xorl	%ebx,%r10d
+	xorl	%r11d,%r14d
+	addl	%r15d,%r12d
+	movl	%eax,%r15d
+
+	rorl	$6,%r13d
+	andl	%r11d,%r10d
+	andl	%ebx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r10d
+
+	addl	%r12d,%ecx
+	addl	%r12d,%r10d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r10d
+
+	movl	44(%rsp),%r13d
+	movl	32(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	12(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	40(%rsp),%r12d
+	movl	%ecx,%r13d
+	addl	%r14d,%r12d
+	movl	%r10d,%r14d
+	rorl	$14,%r13d
+	movl	%edx,%r15d
+	movl	%r12d,40(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%ecx,%r13d
+	xorl	%r8d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r9d,%r12d
+	xorl	%r10d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%ecx,%r15d
+	movl	%r11d,%r9d
+
+	rorl	$11,%r14d
+	xorl	%ecx,%r13d
+	xorl	%r8d,%r15d
+
+	xorl	%eax,%r9d
+	xorl	%r10d,%r14d
+	addl	%r15d,%r12d
+	movl	%r11d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r10d,%r9d
+	andl	%eax,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r9d
+
+	addl	%r12d,%ebx
+	addl	%r12d,%r9d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r9d
+
+	movl	48(%rsp),%r13d
+	movl	36(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	16(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	44(%rsp),%r12d
+	movl	%ebx,%r13d
+	addl	%r14d,%r12d
+	movl	%r9d,%r14d
+	rorl	$14,%r13d
+	movl	%ecx,%r15d
+	movl	%r12d,44(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r15d
+
+	rorl	$5,%r13d
+	addl	%r8d,%r12d
+	xorl	%r9d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%ebx,%r15d
+	movl	%r10d,%r8d
+
+	rorl	$11,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r15d
+
+	xorl	%r11d,%r8d
+	xorl	%r9d,%r14d
+	addl	%r15d,%r12d
+	movl	%r10d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r9d,%r8d
+	andl	%r11d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r8d
+
+	addl	%r12d,%eax
+	addl	%r12d,%r8d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r8d
+
+	movl	52(%rsp),%r13d
+	movl	40(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	20(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	48(%rsp),%r12d
+	movl	%eax,%r13d
+	addl	%r14d,%r12d
+	movl	%r8d,%r14d
+	rorl	$14,%r13d
+	movl	%ebx,%r15d
+	movl	%r12d,48(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r15d
+
+	rorl	$5,%r13d
+	addl	%edx,%r12d
+	xorl	%r8d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%eax,%r15d
+	movl	%r9d,%edx
+
+	rorl	$11,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r15d
+
+	xorl	%r10d,%edx
+	xorl	%r8d,%r14d
+	addl	%r15d,%r12d
+	movl	%r9d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r8d,%edx
+	andl	%r10d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%edx
+
+	addl	%r12d,%r11d
+	addl	%r12d,%edx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%edx
+
+	movl	56(%rsp),%r13d
+	movl	44(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	24(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	52(%rsp),%r12d
+	movl	%r11d,%r13d
+	addl	%r14d,%r12d
+	movl	%edx,%r14d
+	rorl	$14,%r13d
+	movl	%eax,%r15d
+	movl	%r12d,52(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r15d
+
+	rorl	$5,%r13d
+	addl	%ecx,%r12d
+	xorl	%edx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r11d,%r15d
+	movl	%r8d,%ecx
+
+	rorl	$11,%r14d
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r15d
+
+	xorl	%r9d,%ecx
+	xorl	%edx,%r14d
+	addl	%r15d,%r12d
+	movl	%r8d,%r15d
+
+	rorl	$6,%r13d
+	andl	%edx,%ecx
+	andl	%r9d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%ecx
+
+	addl	%r12d,%r10d
+	addl	%r12d,%ecx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%ecx
+
+	movl	60(%rsp),%r13d
+	movl	48(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	28(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	56(%rsp),%r12d
+	movl	%r10d,%r13d
+	addl	%r14d,%r12d
+	movl	%ecx,%r14d
+	rorl	$14,%r13d
+	movl	%r11d,%r15d
+	movl	%r12d,56(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r10d,%r13d
+	xorl	%eax,%r15d
+
+	rorl	$5,%r13d
+	addl	%ebx,%r12d
+	xorl	%ecx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r10d,%r15d
+	movl	%edx,%ebx
+
+	rorl	$11,%r14d
+	xorl	%r10d,%r13d
+	xorl	%eax,%r15d
+
+	xorl	%r8d,%ebx
+	xorl	%ecx,%r14d
+	addl	%r15d,%r12d
+	movl	%edx,%r15d
+
+	rorl	$6,%r13d
+	andl	%ecx,%ebx
+	andl	%r8d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%ebx
+
+	addl	%r12d,%r9d
+	addl	%r12d,%ebx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%ebx
+
+	movl	0(%rsp),%r13d
+	movl	52(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	32(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	60(%rsp),%r12d
+	movl	%r9d,%r13d
+	addl	%r14d,%r12d
+	movl	%ebx,%r14d
+	rorl	$14,%r13d
+	movl	%r10d,%r15d
+	movl	%r12d,60(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r15d
+
+	rorl	$5,%r13d
+	addl	%eax,%r12d
+	xorl	%ebx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r9d,%r15d
+	movl	%ecx,%eax
+
+	rorl	$11,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r15d
+
+	xorl	%edx,%eax
+	xorl	%ebx,%r14d
+	addl	%r15d,%r12d
+	movl	%ecx,%r15d
+
+	rorl	$6,%r13d
+	andl	%ebx,%eax
+	andl	%edx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%eax
+
+	addl	%r12d,%r8d
+	addl	%r12d,%eax
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%eax
+
+	cmpq	$64,%rdi
+	jb	.Lrounds_16_xx
+
+	movq	64+0(%rsp),%rdi
+	leaq	64(%rsi),%rsi
+
+	addl	0(%rdi),%eax
+	addl	4(%rdi),%ebx
+	addl	8(%rdi),%ecx
+	addl	12(%rdi),%edx
+	addl	16(%rdi),%r8d
+	addl	20(%rdi),%r9d
+	addl	24(%rdi),%r10d
+	addl	28(%rdi),%r11d
+
+	cmpq	64+16(%rsp),%rsi
+
+	movl	%eax,0(%rdi)
+	movl	%ebx,4(%rdi)
+	movl	%ecx,8(%rdi)
+	movl	%edx,12(%rdi)
+	movl	%r8d,16(%rdi)
+	movl	%r9d,20(%rdi)
+	movl	%r10d,24(%rdi)
+	movl	%r11d,28(%rdi)
+	jb	.Lloop
+
+	movq	64+24(%rsp),%rsi
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+.Lepilogue:
+	.byte	0xf3,0xc3
+.size	sha256_block_data_order,.-sha256_block_data_order
+.align	64
+.type	K256,@object
+K256:
+.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+#if defined(HAVE_GNU_STACK)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/crypto/libressl/crypto/sha/sha256-macosx-x86_64.S b/crypto/libressl/crypto/sha/sha256-macosx-x86_64.S
new file mode 100644
index 0000000000..294fa901cf
--- /dev/null
+++ b/crypto/libressl/crypto/sha/sha256-macosx-x86_64.S
@@ -0,0 +1,1778 @@
+.text	
+
+.globl	_sha256_block_data_order
+
+.p2align	4
+_sha256_block_data_order:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	movq	%rsp,%r11
+	shlq	$4,%rdx
+	subq	$64+32,%rsp
+	leaq	(%rsi,%rdx,4),%rdx
+	andq	$-64,%rsp
+	movq	%rdi,64+0(%rsp)
+	movq	%rsi,64+8(%rsp)
+	movq	%rdx,64+16(%rsp)
+	movq	%r11,64+24(%rsp)
+L$prologue:
+
+	leaq	K256(%rip),%rbp
+
+	movl	0(%rdi),%eax
+	movl	4(%rdi),%ebx
+	movl	8(%rdi),%ecx
+	movl	12(%rdi),%edx
+	movl	16(%rdi),%r8d
+	movl	20(%rdi),%r9d
+	movl	24(%rdi),%r10d
+	movl	28(%rdi),%r11d
+	jmp	L$loop
+
+.p2align	4
+L$loop:
+	xorq	%rdi,%rdi
+	movl	0(%rsi),%r12d
+	movl	%r8d,%r13d
+	movl	%eax,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%r9d,%r15d
+	movl	%r12d,0(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r11d,%r12d
+	xorl	%eax,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r8d,%r15d
+	movl	%ebx,%r11d
+
+	rorl	$11,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r15d
+
+	xorl	%ecx,%r11d
+	xorl	%eax,%r14d
+	addl	%r15d,%r12d
+	movl	%ebx,%r15d
+
+	rorl	$6,%r13d
+	andl	%eax,%r11d
+	andl	%ecx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r11d
+
+	addl	%r12d,%edx
+	addl	%r12d,%r11d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r11d
+
+	movl	4(%rsi),%r12d
+	movl	%edx,%r13d
+	movl	%r11d,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%r8d,%r15d
+	movl	%r12d,4(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%edx,%r13d
+	xorl	%r9d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r10d,%r12d
+	xorl	%r11d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%edx,%r15d
+	movl	%eax,%r10d
+
+	rorl	$11,%r14d
+	xorl	%edx,%r13d
+	xorl	%r9d,%r15d
+
+	xorl	%ebx,%r10d
+	xorl	%r11d,%r14d
+	addl	%r15d,%r12d
+	movl	%eax,%r15d
+
+	rorl	$6,%r13d
+	andl	%r11d,%r10d
+	andl	%ebx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r10d
+
+	addl	%r12d,%ecx
+	addl	%r12d,%r10d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r10d
+
+	movl	8(%rsi),%r12d
+	movl	%ecx,%r13d
+	movl	%r10d,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%edx,%r15d
+	movl	%r12d,8(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%ecx,%r13d
+	xorl	%r8d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r9d,%r12d
+	xorl	%r10d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%ecx,%r15d
+	movl	%r11d,%r9d
+
+	rorl	$11,%r14d
+	xorl	%ecx,%r13d
+	xorl	%r8d,%r15d
+
+	xorl	%eax,%r9d
+	xorl	%r10d,%r14d
+	addl	%r15d,%r12d
+	movl	%r11d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r10d,%r9d
+	andl	%eax,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r9d
+
+	addl	%r12d,%ebx
+	addl	%r12d,%r9d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r9d
+
+	movl	12(%rsi),%r12d
+	movl	%ebx,%r13d
+	movl	%r9d,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%ecx,%r15d
+	movl	%r12d,12(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r15d
+
+	rorl	$5,%r13d
+	addl	%r8d,%r12d
+	xorl	%r9d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%ebx,%r15d
+	movl	%r10d,%r8d
+
+	rorl	$11,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r15d
+
+	xorl	%r11d,%r8d
+	xorl	%r9d,%r14d
+	addl	%r15d,%r12d
+	movl	%r10d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r9d,%r8d
+	andl	%r11d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r8d
+
+	addl	%r12d,%eax
+	addl	%r12d,%r8d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r8d
+
+	movl	16(%rsi),%r12d
+	movl	%eax,%r13d
+	movl	%r8d,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%ebx,%r15d
+	movl	%r12d,16(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r15d
+
+	rorl	$5,%r13d
+	addl	%edx,%r12d
+	xorl	%r8d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%eax,%r15d
+	movl	%r9d,%edx
+
+	rorl	$11,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r15d
+
+	xorl	%r10d,%edx
+	xorl	%r8d,%r14d
+	addl	%r15d,%r12d
+	movl	%r9d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r8d,%edx
+	andl	%r10d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%edx
+
+	addl	%r12d,%r11d
+	addl	%r12d,%edx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%edx
+
+	movl	20(%rsi),%r12d
+	movl	%r11d,%r13d
+	movl	%edx,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%eax,%r15d
+	movl	%r12d,20(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r15d
+
+	rorl	$5,%r13d
+	addl	%ecx,%r12d
+	xorl	%edx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r11d,%r15d
+	movl	%r8d,%ecx
+
+	rorl	$11,%r14d
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r15d
+
+	xorl	%r9d,%ecx
+	xorl	%edx,%r14d
+	addl	%r15d,%r12d
+	movl	%r8d,%r15d
+
+	rorl	$6,%r13d
+	andl	%edx,%ecx
+	andl	%r9d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%ecx
+
+	addl	%r12d,%r10d
+	addl	%r12d,%ecx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%ecx
+
+	movl	24(%rsi),%r12d
+	movl	%r10d,%r13d
+	movl	%ecx,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%r11d,%r15d
+	movl	%r12d,24(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r10d,%r13d
+	xorl	%eax,%r15d
+
+	rorl	$5,%r13d
+	addl	%ebx,%r12d
+	xorl	%ecx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r10d,%r15d
+	movl	%edx,%ebx
+
+	rorl	$11,%r14d
+	xorl	%r10d,%r13d
+	xorl	%eax,%r15d
+
+	xorl	%r8d,%ebx
+	xorl	%ecx,%r14d
+	addl	%r15d,%r12d
+	movl	%edx,%r15d
+
+	rorl	$6,%r13d
+	andl	%ecx,%ebx
+	andl	%r8d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%ebx
+
+	addl	%r12d,%r9d
+	addl	%r12d,%ebx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%ebx
+
+	movl	28(%rsi),%r12d
+	movl	%r9d,%r13d
+	movl	%ebx,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%r10d,%r15d
+	movl	%r12d,28(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r15d
+
+	rorl	$5,%r13d
+	addl	%eax,%r12d
+	xorl	%ebx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r9d,%r15d
+	movl	%ecx,%eax
+
+	rorl	$11,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r15d
+
+	xorl	%edx,%eax
+	xorl	%ebx,%r14d
+	addl	%r15d,%r12d
+	movl	%ecx,%r15d
+
+	rorl	$6,%r13d
+	andl	%ebx,%eax
+	andl	%edx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%eax
+
+	addl	%r12d,%r8d
+	addl	%r12d,%eax
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%eax
+
+	movl	32(%rsi),%r12d
+	movl	%r8d,%r13d
+	movl	%eax,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%r9d,%r15d
+	movl	%r12d,32(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r11d,%r12d
+	xorl	%eax,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r8d,%r15d
+	movl	%ebx,%r11d
+
+	rorl	$11,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r15d
+
+	xorl	%ecx,%r11d
+	xorl	%eax,%r14d
+	addl	%r15d,%r12d
+	movl	%ebx,%r15d
+
+	rorl	$6,%r13d
+	andl	%eax,%r11d
+	andl	%ecx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r11d
+
+	addl	%r12d,%edx
+	addl	%r12d,%r11d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r11d
+
+	movl	36(%rsi),%r12d
+	movl	%edx,%r13d
+	movl	%r11d,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%r8d,%r15d
+	movl	%r12d,36(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%edx,%r13d
+	xorl	%r9d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r10d,%r12d
+	xorl	%r11d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%edx,%r15d
+	movl	%eax,%r10d
+
+	rorl	$11,%r14d
+	xorl	%edx,%r13d
+	xorl	%r9d,%r15d
+
+	xorl	%ebx,%r10d
+	xorl	%r11d,%r14d
+	addl	%r15d,%r12d
+	movl	%eax,%r15d
+
+	rorl	$6,%r13d
+	andl	%r11d,%r10d
+	andl	%ebx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r10d
+
+	addl	%r12d,%ecx
+	addl	%r12d,%r10d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r10d
+
+	movl	40(%rsi),%r12d
+	movl	%ecx,%r13d
+	movl	%r10d,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%edx,%r15d
+	movl	%r12d,40(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%ecx,%r13d
+	xorl	%r8d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r9d,%r12d
+	xorl	%r10d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%ecx,%r15d
+	movl	%r11d,%r9d
+
+	rorl	$11,%r14d
+	xorl	%ecx,%r13d
+	xorl	%r8d,%r15d
+
+	xorl	%eax,%r9d
+	xorl	%r10d,%r14d
+	addl	%r15d,%r12d
+	movl	%r11d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r10d,%r9d
+	andl	%eax,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r9d
+
+	addl	%r12d,%ebx
+	addl	%r12d,%r9d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r9d
+
+	movl	44(%rsi),%r12d
+	movl	%ebx,%r13d
+	movl	%r9d,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%ecx,%r15d
+	movl	%r12d,44(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r15d
+
+	rorl	$5,%r13d
+	addl	%r8d,%r12d
+	xorl	%r9d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%ebx,%r15d
+	movl	%r10d,%r8d
+
+	rorl	$11,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r15d
+
+	xorl	%r11d,%r8d
+	xorl	%r9d,%r14d
+	addl	%r15d,%r12d
+	movl	%r10d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r9d,%r8d
+	andl	%r11d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r8d
+
+	addl	%r12d,%eax
+	addl	%r12d,%r8d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r8d
+
+	movl	48(%rsi),%r12d
+	movl	%eax,%r13d
+	movl	%r8d,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%ebx,%r15d
+	movl	%r12d,48(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r15d
+
+	rorl	$5,%r13d
+	addl	%edx,%r12d
+	xorl	%r8d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%eax,%r15d
+	movl	%r9d,%edx
+
+	rorl	$11,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r15d
+
+	xorl	%r10d,%edx
+	xorl	%r8d,%r14d
+	addl	%r15d,%r12d
+	movl	%r9d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r8d,%edx
+	andl	%r10d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%edx
+
+	addl	%r12d,%r11d
+	addl	%r12d,%edx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%edx
+
+	movl	52(%rsi),%r12d
+	movl	%r11d,%r13d
+	movl	%edx,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%eax,%r15d
+	movl	%r12d,52(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r15d
+
+	rorl	$5,%r13d
+	addl	%ecx,%r12d
+	xorl	%edx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r11d,%r15d
+	movl	%r8d,%ecx
+
+	rorl	$11,%r14d
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r15d
+
+	xorl	%r9d,%ecx
+	xorl	%edx,%r14d
+	addl	%r15d,%r12d
+	movl	%r8d,%r15d
+
+	rorl	$6,%r13d
+	andl	%edx,%ecx
+	andl	%r9d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%ecx
+
+	addl	%r12d,%r10d
+	addl	%r12d,%ecx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%ecx
+
+	movl	56(%rsi),%r12d
+	movl	%r10d,%r13d
+	movl	%ecx,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%r11d,%r15d
+	movl	%r12d,56(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r10d,%r13d
+	xorl	%eax,%r15d
+
+	rorl	$5,%r13d
+	addl	%ebx,%r12d
+	xorl	%ecx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r10d,%r15d
+	movl	%edx,%ebx
+
+	rorl	$11,%r14d
+	xorl	%r10d,%r13d
+	xorl	%eax,%r15d
+
+	xorl	%r8d,%ebx
+	xorl	%ecx,%r14d
+	addl	%r15d,%r12d
+	movl	%edx,%r15d
+
+	rorl	$6,%r13d
+	andl	%ecx,%ebx
+	andl	%r8d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%ebx
+
+	addl	%r12d,%r9d
+	addl	%r12d,%ebx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%ebx
+
+	movl	60(%rsi),%r12d
+	movl	%r9d,%r13d
+	movl	%ebx,%r14d
+	bswapl	%r12d
+	rorl	$14,%r13d
+	movl	%r10d,%r15d
+	movl	%r12d,60(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r15d
+
+	rorl	$5,%r13d
+	addl	%eax,%r12d
+	xorl	%ebx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r9d,%r15d
+	movl	%ecx,%eax
+
+	rorl	$11,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r15d
+
+	xorl	%edx,%eax
+	xorl	%ebx,%r14d
+	addl	%r15d,%r12d
+	movl	%ecx,%r15d
+
+	rorl	$6,%r13d
+	andl	%ebx,%eax
+	andl	%edx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%eax
+
+	addl	%r12d,%r8d
+	addl	%r12d,%eax
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%eax
+
+	jmp	L$rounds_16_xx
+.p2align	4
+L$rounds_16_xx:
+	movl	4(%rsp),%r13d
+	movl	56(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	36(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	0(%rsp),%r12d
+	movl	%r8d,%r13d
+	addl	%r14d,%r12d
+	movl	%eax,%r14d
+	rorl	$14,%r13d
+	movl	%r9d,%r15d
+	movl	%r12d,0(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r11d,%r12d
+	xorl	%eax,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r8d,%r15d
+	movl	%ebx,%r11d
+
+	rorl	$11,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r15d
+
+	xorl	%ecx,%r11d
+	xorl	%eax,%r14d
+	addl	%r15d,%r12d
+	movl	%ebx,%r15d
+
+	rorl	$6,%r13d
+	andl	%eax,%r11d
+	andl	%ecx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r11d
+
+	addl	%r12d,%edx
+	addl	%r12d,%r11d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r11d
+
+	movl	8(%rsp),%r13d
+	movl	60(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	40(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	4(%rsp),%r12d
+	movl	%edx,%r13d
+	addl	%r14d,%r12d
+	movl	%r11d,%r14d
+	rorl	$14,%r13d
+	movl	%r8d,%r15d
+	movl	%r12d,4(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%edx,%r13d
+	xorl	%r9d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r10d,%r12d
+	xorl	%r11d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%edx,%r15d
+	movl	%eax,%r10d
+
+	rorl	$11,%r14d
+	xorl	%edx,%r13d
+	xorl	%r9d,%r15d
+
+	xorl	%ebx,%r10d
+	xorl	%r11d,%r14d
+	addl	%r15d,%r12d
+	movl	%eax,%r15d
+
+	rorl	$6,%r13d
+	andl	%r11d,%r10d
+	andl	%ebx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r10d
+
+	addl	%r12d,%ecx
+	addl	%r12d,%r10d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r10d
+
+	movl	12(%rsp),%r13d
+	movl	0(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	44(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	8(%rsp),%r12d
+	movl	%ecx,%r13d
+	addl	%r14d,%r12d
+	movl	%r10d,%r14d
+	rorl	$14,%r13d
+	movl	%edx,%r15d
+	movl	%r12d,8(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%ecx,%r13d
+	xorl	%r8d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r9d,%r12d
+	xorl	%r10d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%ecx,%r15d
+	movl	%r11d,%r9d
+
+	rorl	$11,%r14d
+	xorl	%ecx,%r13d
+	xorl	%r8d,%r15d
+
+	xorl	%eax,%r9d
+	xorl	%r10d,%r14d
+	addl	%r15d,%r12d
+	movl	%r11d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r10d,%r9d
+	andl	%eax,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r9d
+
+	addl	%r12d,%ebx
+	addl	%r12d,%r9d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r9d
+
+	movl	16(%rsp),%r13d
+	movl	4(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	48(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	12(%rsp),%r12d
+	movl	%ebx,%r13d
+	addl	%r14d,%r12d
+	movl	%r9d,%r14d
+	rorl	$14,%r13d
+	movl	%ecx,%r15d
+	movl	%r12d,12(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r15d
+
+	rorl	$5,%r13d
+	addl	%r8d,%r12d
+	xorl	%r9d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%ebx,%r15d
+	movl	%r10d,%r8d
+
+	rorl	$11,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r15d
+
+	xorl	%r11d,%r8d
+	xorl	%r9d,%r14d
+	addl	%r15d,%r12d
+	movl	%r10d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r9d,%r8d
+	andl	%r11d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r8d
+
+	addl	%r12d,%eax
+	addl	%r12d,%r8d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r8d
+
+	movl	20(%rsp),%r13d
+	movl	8(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	52(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	16(%rsp),%r12d
+	movl	%eax,%r13d
+	addl	%r14d,%r12d
+	movl	%r8d,%r14d
+	rorl	$14,%r13d
+	movl	%ebx,%r15d
+	movl	%r12d,16(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r15d
+
+	rorl	$5,%r13d
+	addl	%edx,%r12d
+	xorl	%r8d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%eax,%r15d
+	movl	%r9d,%edx
+
+	rorl	$11,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r15d
+
+	xorl	%r10d,%edx
+	xorl	%r8d,%r14d
+	addl	%r15d,%r12d
+	movl	%r9d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r8d,%edx
+	andl	%r10d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%edx
+
+	addl	%r12d,%r11d
+	addl	%r12d,%edx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%edx
+
+	movl	24(%rsp),%r13d
+	movl	12(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	56(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	20(%rsp),%r12d
+	movl	%r11d,%r13d
+	addl	%r14d,%r12d
+	movl	%edx,%r14d
+	rorl	$14,%r13d
+	movl	%eax,%r15d
+	movl	%r12d,20(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r15d
+
+	rorl	$5,%r13d
+	addl	%ecx,%r12d
+	xorl	%edx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r11d,%r15d
+	movl	%r8d,%ecx
+
+	rorl	$11,%r14d
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r15d
+
+	xorl	%r9d,%ecx
+	xorl	%edx,%r14d
+	addl	%r15d,%r12d
+	movl	%r8d,%r15d
+
+	rorl	$6,%r13d
+	andl	%edx,%ecx
+	andl	%r9d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%ecx
+
+	addl	%r12d,%r10d
+	addl	%r12d,%ecx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%ecx
+
+	movl	28(%rsp),%r13d
+	movl	16(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	60(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	24(%rsp),%r12d
+	movl	%r10d,%r13d
+	addl	%r14d,%r12d
+	movl	%ecx,%r14d
+	rorl	$14,%r13d
+	movl	%r11d,%r15d
+	movl	%r12d,24(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r10d,%r13d
+	xorl	%eax,%r15d
+
+	rorl	$5,%r13d
+	addl	%ebx,%r12d
+	xorl	%ecx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r10d,%r15d
+	movl	%edx,%ebx
+
+	rorl	$11,%r14d
+	xorl	%r10d,%r13d
+	xorl	%eax,%r15d
+
+	xorl	%r8d,%ebx
+	xorl	%ecx,%r14d
+	addl	%r15d,%r12d
+	movl	%edx,%r15d
+
+	rorl	$6,%r13d
+	andl	%ecx,%ebx
+	andl	%r8d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%ebx
+
+	addl	%r12d,%r9d
+	addl	%r12d,%ebx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%ebx
+
+	movl	32(%rsp),%r13d
+	movl	20(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	0(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	28(%rsp),%r12d
+	movl	%r9d,%r13d
+	addl	%r14d,%r12d
+	movl	%ebx,%r14d
+	rorl	$14,%r13d
+	movl	%r10d,%r15d
+	movl	%r12d,28(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r15d
+
+	rorl	$5,%r13d
+	addl	%eax,%r12d
+	xorl	%ebx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r9d,%r15d
+	movl	%ecx,%eax
+
+	rorl	$11,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r15d
+
+	xorl	%edx,%eax
+	xorl	%ebx,%r14d
+	addl	%r15d,%r12d
+	movl	%ecx,%r15d
+
+	rorl	$6,%r13d
+	andl	%ebx,%eax
+	andl	%edx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%eax
+
+	addl	%r12d,%r8d
+	addl	%r12d,%eax
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%eax
+
+	movl	36(%rsp),%r13d
+	movl	24(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	4(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	32(%rsp),%r12d
+	movl	%r8d,%r13d
+	addl	%r14d,%r12d
+	movl	%eax,%r14d
+	rorl	$14,%r13d
+	movl	%r9d,%r15d
+	movl	%r12d,32(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r11d,%r12d
+	xorl	%eax,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r8d,%r15d
+	movl	%ebx,%r11d
+
+	rorl	$11,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r15d
+
+	xorl	%ecx,%r11d
+	xorl	%eax,%r14d
+	addl	%r15d,%r12d
+	movl	%ebx,%r15d
+
+	rorl	$6,%r13d
+	andl	%eax,%r11d
+	andl	%ecx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r11d
+
+	addl	%r12d,%edx
+	addl	%r12d,%r11d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r11d
+
+	movl	40(%rsp),%r13d
+	movl	28(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	8(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	36(%rsp),%r12d
+	movl	%edx,%r13d
+	addl	%r14d,%r12d
+	movl	%r11d,%r14d
+	rorl	$14,%r13d
+	movl	%r8d,%r15d
+	movl	%r12d,36(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%edx,%r13d
+	xorl	%r9d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r10d,%r12d
+	xorl	%r11d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%edx,%r15d
+	movl	%eax,%r10d
+
+	rorl	$11,%r14d
+	xorl	%edx,%r13d
+	xorl	%r9d,%r15d
+
+	xorl	%ebx,%r10d
+	xorl	%r11d,%r14d
+	addl	%r15d,%r12d
+	movl	%eax,%r15d
+
+	rorl	$6,%r13d
+	andl	%r11d,%r10d
+	andl	%ebx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r10d
+
+	addl	%r12d,%ecx
+	addl	%r12d,%r10d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r10d
+
+	movl	44(%rsp),%r13d
+	movl	32(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	12(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	40(%rsp),%r12d
+	movl	%ecx,%r13d
+	addl	%r14d,%r12d
+	movl	%r10d,%r14d
+	rorl	$14,%r13d
+	movl	%edx,%r15d
+	movl	%r12d,40(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%ecx,%r13d
+	xorl	%r8d,%r15d
+
+	rorl	$5,%r13d
+	addl	%r9d,%r12d
+	xorl	%r10d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%ecx,%r15d
+	movl	%r11d,%r9d
+
+	rorl	$11,%r14d
+	xorl	%ecx,%r13d
+	xorl	%r8d,%r15d
+
+	xorl	%eax,%r9d
+	xorl	%r10d,%r14d
+	addl	%r15d,%r12d
+	movl	%r11d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r10d,%r9d
+	andl	%eax,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r9d
+
+	addl	%r12d,%ebx
+	addl	%r12d,%r9d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r9d
+
+	movl	48(%rsp),%r13d
+	movl	36(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	16(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	44(%rsp),%r12d
+	movl	%ebx,%r13d
+	addl	%r14d,%r12d
+	movl	%r9d,%r14d
+	rorl	$14,%r13d
+	movl	%ecx,%r15d
+	movl	%r12d,44(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r15d
+
+	rorl	$5,%r13d
+	addl	%r8d,%r12d
+	xorl	%r9d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%ebx,%r15d
+	movl	%r10d,%r8d
+
+	rorl	$11,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r15d
+
+	xorl	%r11d,%r8d
+	xorl	%r9d,%r14d
+	addl	%r15d,%r12d
+	movl	%r10d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r9d,%r8d
+	andl	%r11d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%r8d
+
+	addl	%r12d,%eax
+	addl	%r12d,%r8d
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%r8d
+
+	movl	52(%rsp),%r13d
+	movl	40(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	20(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	48(%rsp),%r12d
+	movl	%eax,%r13d
+	addl	%r14d,%r12d
+	movl	%r8d,%r14d
+	rorl	$14,%r13d
+	movl	%ebx,%r15d
+	movl	%r12d,48(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r15d
+
+	rorl	$5,%r13d
+	addl	%edx,%r12d
+	xorl	%r8d,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%eax,%r15d
+	movl	%r9d,%edx
+
+	rorl	$11,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r15d
+
+	xorl	%r10d,%edx
+	xorl	%r8d,%r14d
+	addl	%r15d,%r12d
+	movl	%r9d,%r15d
+
+	rorl	$6,%r13d
+	andl	%r8d,%edx
+	andl	%r10d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%edx
+
+	addl	%r12d,%r11d
+	addl	%r12d,%edx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%edx
+
+	movl	56(%rsp),%r13d
+	movl	44(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	24(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	52(%rsp),%r12d
+	movl	%r11d,%r13d
+	addl	%r14d,%r12d
+	movl	%edx,%r14d
+	rorl	$14,%r13d
+	movl	%eax,%r15d
+	movl	%r12d,52(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r15d
+
+	rorl	$5,%r13d
+	addl	%ecx,%r12d
+	xorl	%edx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r11d,%r15d
+	movl	%r8d,%ecx
+
+	rorl	$11,%r14d
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r15d
+
+	xorl	%r9d,%ecx
+	xorl	%edx,%r14d
+	addl	%r15d,%r12d
+	movl	%r8d,%r15d
+
+	rorl	$6,%r13d
+	andl	%edx,%ecx
+	andl	%r9d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%ecx
+
+	addl	%r12d,%r10d
+	addl	%r12d,%ecx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%ecx
+
+	movl	60(%rsp),%r13d
+	movl	48(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	28(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	56(%rsp),%r12d
+	movl	%r10d,%r13d
+	addl	%r14d,%r12d
+	movl	%ecx,%r14d
+	rorl	$14,%r13d
+	movl	%r11d,%r15d
+	movl	%r12d,56(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r10d,%r13d
+	xorl	%eax,%r15d
+
+	rorl	$5,%r13d
+	addl	%ebx,%r12d
+	xorl	%ecx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r10d,%r15d
+	movl	%edx,%ebx
+
+	rorl	$11,%r14d
+	xorl	%r10d,%r13d
+	xorl	%eax,%r15d
+
+	xorl	%r8d,%ebx
+	xorl	%ecx,%r14d
+	addl	%r15d,%r12d
+	movl	%edx,%r15d
+
+	rorl	$6,%r13d
+	andl	%ecx,%ebx
+	andl	%r8d,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%ebx
+
+	addl	%r12d,%r9d
+	addl	%r12d,%ebx
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%ebx
+
+	movl	0(%rsp),%r13d
+	movl	52(%rsp),%r14d
+	movl	%r13d,%r12d
+	movl	%r14d,%r15d
+
+	rorl	$11,%r12d
+	xorl	%r13d,%r12d
+	shrl	$3,%r13d
+
+	rorl	$7,%r12d
+	xorl	%r12d,%r13d
+	movl	32(%rsp),%r12d
+
+	rorl	$2,%r15d
+	xorl	%r14d,%r15d
+	shrl	$10,%r14d
+
+	rorl	$17,%r15d
+	addl	%r13d,%r12d
+	xorl	%r15d,%r14d
+
+	addl	60(%rsp),%r12d
+	movl	%r9d,%r13d
+	addl	%r14d,%r12d
+	movl	%ebx,%r14d
+	rorl	$14,%r13d
+	movl	%r10d,%r15d
+	movl	%r12d,60(%rsp)
+
+	rorl	$9,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r15d
+
+	rorl	$5,%r13d
+	addl	%eax,%r12d
+	xorl	%ebx,%r14d
+
+	addl	(%rbp,%rdi,4),%r12d
+	andl	%r9d,%r15d
+	movl	%ecx,%eax
+
+	rorl	$11,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r15d
+
+	xorl	%edx,%eax
+	xorl	%ebx,%r14d
+	addl	%r15d,%r12d
+	movl	%ecx,%r15d
+
+	rorl	$6,%r13d
+	andl	%ebx,%eax
+	andl	%edx,%r15d
+
+	rorl	$2,%r14d
+	addl	%r13d,%r12d
+	addl	%r15d,%eax
+
+	addl	%r12d,%r8d
+	addl	%r12d,%eax
+	leaq	1(%rdi),%rdi
+	addl	%r14d,%eax
+
+	cmpq	$64,%rdi
+	jb	L$rounds_16_xx
+
+	movq	64+0(%rsp),%rdi
+	leaq	64(%rsi),%rsi
+
+	addl	0(%rdi),%eax
+	addl	4(%rdi),%ebx
+	addl	8(%rdi),%ecx
+	addl	12(%rdi),%edx
+	addl	16(%rdi),%r8d
+	addl	20(%rdi),%r9d
+	addl	24(%rdi),%r10d
+	addl	28(%rdi),%r11d
+
+	cmpq	64+16(%rsp),%rsi
+
+	movl	%eax,0(%rdi)
+	movl	%ebx,4(%rdi)
+	movl	%ecx,8(%rdi)
+	movl	%edx,12(%rdi)
+	movl	%r8d,16(%rdi)
+	movl	%r9d,20(%rdi)
+	movl	%r10d,24(%rdi)
+	movl	%r11d,28(%rdi)
+	jb	L$loop
+
+	movq	64+24(%rsp),%rsi
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+L$epilogue:
+	.byte	0xf3,0xc3
+
+.p2align	6
+
+K256:
+.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
diff --git a/crypto/libressl/crypto/sha/sha256.c b/crypto/libressl/crypto/sha/sha256.c
new file mode 100644
index 0000000000..85e91c6b96
--- /dev/null
+++ b/crypto/libressl/crypto/sha/sha256.c
@@ -0,0 +1,284 @@
+/* $OpenBSD: sha256.c,v 1.8 2014/08/18 19:11:48 bcook Exp $ */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved
+ * according to the OpenSSL license [found in ../../LICENSE].
+ * ====================================================================
+ */
+
+#include 
+
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256)
+
+#include 
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+int SHA224_Init(SHA256_CTX *c)
+	{
+	memset (c,0,sizeof(*c));
+	c->h[0]=0xc1059ed8UL;	c->h[1]=0x367cd507UL;
+	c->h[2]=0x3070dd17UL;	c->h[3]=0xf70e5939UL;
+	c->h[4]=0xffc00b31UL;	c->h[5]=0x68581511UL;
+	c->h[6]=0x64f98fa7UL;	c->h[7]=0xbefa4fa4UL;
+	c->md_len=SHA224_DIGEST_LENGTH;
+	return 1;
+	}
+
+int SHA256_Init(SHA256_CTX *c)
+	{
+	memset (c,0,sizeof(*c));
+	c->h[0]=0x6a09e667UL;	c->h[1]=0xbb67ae85UL;
+	c->h[2]=0x3c6ef372UL;	c->h[3]=0xa54ff53aUL;
+	c->h[4]=0x510e527fUL;	c->h[5]=0x9b05688cUL;
+	c->h[6]=0x1f83d9abUL;	c->h[7]=0x5be0cd19UL;
+	c->md_len=SHA256_DIGEST_LENGTH;
+	return 1;
+	}
+
+unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md)
+	{
+	SHA256_CTX c;
+	static unsigned char m[SHA224_DIGEST_LENGTH];
+
+	if (md == NULL) md=m;
+	SHA224_Init(&c);
+	SHA256_Update(&c,d,n);
+	SHA256_Final(md,&c);
+	explicit_bzero(&c,sizeof(c));
+	return(md);
+	}
+
+unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md)
+	{
+	SHA256_CTX c;
+	static unsigned char m[SHA256_DIGEST_LENGTH];
+
+	if (md == NULL) md=m;
+	SHA256_Init(&c);
+	SHA256_Update(&c,d,n);
+	SHA256_Final(md,&c);
+	explicit_bzero(&c,sizeof(c));
+	return(md);
+	}
+
+int SHA224_Update(SHA256_CTX *c, const void *data, size_t len)
+{   return SHA256_Update (c,data,len);   }
+int SHA224_Final (unsigned char *md, SHA256_CTX *c)
+{   return SHA256_Final (md,c);   }
+
+#define	DATA_ORDER_IS_BIG_ENDIAN
+
+#define	HASH_LONG		SHA_LONG
+#define	HASH_CTX		SHA256_CTX
+#define	HASH_CBLOCK		SHA_CBLOCK
+/*
+ * Note that FIPS180-2 discusses "Truncation of the Hash Function Output."
+ * default: case below covers for it. It's not clear however if it's
+ * permitted to truncate to amount of bytes not divisible by 4. I bet not,
+ * but if it is, then default: case shall be extended. For reference.
+ * Idea behind separate cases for pre-defined lenghts is to let the
+ * compiler decide if it's appropriate to unroll small loops.
+ */
+#define	HASH_MAKE_STRING(c,s)	do {	\
+	unsigned long ll;		\
+	unsigned int  nn;		\
+	switch ((c)->md_len)		\
+	{   case SHA224_DIGEST_LENGTH:	\
+		for (nn=0;nnh[nn]; HOST_l2c(ll,(s));   }	\
+		break;			\
+	    case SHA256_DIGEST_LENGTH:	\
+		for (nn=0;nnh[nn]; HOST_l2c(ll,(s));   }	\
+		break;			\
+	    default:			\
+		if ((c)->md_len > SHA256_DIGEST_LENGTH)	\
+		    return 0;				\
+		for (nn=0;nn<(c)->md_len/4;nn++)		\
+		{   ll=(c)->h[nn]; HOST_l2c(ll,(s));   }	\
+		break;			\
+	}				\
+	} while (0)
+
+#define	HASH_UPDATE		SHA256_Update
+#define	HASH_TRANSFORM		SHA256_Transform
+#define	HASH_FINAL		SHA256_Final
+#define	HASH_BLOCK_DATA_ORDER	sha256_block_data_order
+#ifndef SHA256_ASM
+static
+#endif
+void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num);
+
+#include "md32_common.h"
+
+#ifndef SHA256_ASM
+static const SHA_LONG K256[64] = {
+	0x428a2f98UL,0x71374491UL,0xb5c0fbcfUL,0xe9b5dba5UL,
+	0x3956c25bUL,0x59f111f1UL,0x923f82a4UL,0xab1c5ed5UL,
+	0xd807aa98UL,0x12835b01UL,0x243185beUL,0x550c7dc3UL,
+	0x72be5d74UL,0x80deb1feUL,0x9bdc06a7UL,0xc19bf174UL,
+	0xe49b69c1UL,0xefbe4786UL,0x0fc19dc6UL,0x240ca1ccUL,
+	0x2de92c6fUL,0x4a7484aaUL,0x5cb0a9dcUL,0x76f988daUL,
+	0x983e5152UL,0xa831c66dUL,0xb00327c8UL,0xbf597fc7UL,
+	0xc6e00bf3UL,0xd5a79147UL,0x06ca6351UL,0x14292967UL,
+	0x27b70a85UL,0x2e1b2138UL,0x4d2c6dfcUL,0x53380d13UL,
+	0x650a7354UL,0x766a0abbUL,0x81c2c92eUL,0x92722c85UL,
+	0xa2bfe8a1UL,0xa81a664bUL,0xc24b8b70UL,0xc76c51a3UL,
+	0xd192e819UL,0xd6990624UL,0xf40e3585UL,0x106aa070UL,
+	0x19a4c116UL,0x1e376c08UL,0x2748774cUL,0x34b0bcb5UL,
+	0x391c0cb3UL,0x4ed8aa4aUL,0x5b9cca4fUL,0x682e6ff3UL,
+	0x748f82eeUL,0x78a5636fUL,0x84c87814UL,0x8cc70208UL,
+	0x90befffaUL,0xa4506cebUL,0xbef9a3f7UL,0xc67178f2UL };
+
+/*
+ * FIPS specification refers to right rotations, while our ROTATE macro
+ * is left one. This is why you might notice that rotation coefficients
+ * differ from those observed in FIPS document by 32-N...
+ */
+#define Sigma0(x)	(ROTATE((x),30) ^ ROTATE((x),19) ^ ROTATE((x),10))
+#define Sigma1(x)	(ROTATE((x),26) ^ ROTATE((x),21) ^ ROTATE((x),7))
+#define sigma0(x)	(ROTATE((x),25) ^ ROTATE((x),14) ^ ((x)>>3))
+#define sigma1(x)	(ROTATE((x),15) ^ ROTATE((x),13) ^ ((x)>>10))
+
+#define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z)))
+#define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+#ifdef OPENSSL_SMALL_FOOTPRINT
+
+static void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num)
+	{
+	unsigned MD32_REG_T a,b,c,d,e,f,g,h,s0,s1,T1,T2;
+	SHA_LONG	X[16],l;
+	int i;
+	const unsigned char *data=in;
+
+			while (num--) {
+
+	a = ctx->h[0];	b = ctx->h[1];	c = ctx->h[2];	d = ctx->h[3];
+	e = ctx->h[4];	f = ctx->h[5];	g = ctx->h[6];	h = ctx->h[7];
+
+	for (i=0;i<16;i++)
+		{
+		HOST_c2l(data,l); T1 = X[i] = l;
+		T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i];
+		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;
+		}
+
+	for (;i<64;i++)
+		{
+		s0 = X[(i+1)&0x0f];	s0 = sigma0(s0);
+		s1 = X[(i+14)&0x0f];	s1 = sigma1(s1);
+
+		T1 = X[i&0xf] += s0 + s1 + X[(i+9)&0xf];
+		T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i];
+		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;
+		}
+
+	ctx->h[0] += a;	ctx->h[1] += b;	ctx->h[2] += c;	ctx->h[3] += d;
+	ctx->h[4] += e;	ctx->h[5] += f;	ctx->h[6] += g;	ctx->h[7] += h;
+
+			}
+}
+
+#else
+
+#define	ROUND_00_15(i,a,b,c,d,e,f,g,h)		do {	\
+	T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i];	\
+	h = Sigma0(a) + Maj(a,b,c);			\
+	d += T1;	h += T1;		} while (0)
+
+#define	ROUND_16_63(i,a,b,c,d,e,f,g,h,X)	do {	\
+	s0 = X[(i+1)&0x0f];	s0 = sigma0(s0);	\
+	s1 = X[(i+14)&0x0f];	s1 = sigma1(s1);	\
+	T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f];	\
+	ROUND_00_15(i,a,b,c,d,e,f,g,h);		} while (0)
+
+static void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num)
+	{
+	unsigned MD32_REG_T a,b,c,d,e,f,g,h,s0,s1,T1;
+	SHA_LONG	X[16];
+	int i;
+	const unsigned char *data=in;
+
+			while (num--) {
+
+	a = ctx->h[0];	b = ctx->h[1];	c = ctx->h[2];	d = ctx->h[3];
+	e = ctx->h[4];	f = ctx->h[5];	g = ctx->h[6];	h = ctx->h[7];
+
+	if (BYTE_ORDER != LITTLE_ENDIAN &&
+	    sizeof(SHA_LONG)==4 && ((size_t)in%4)==0)
+		{
+		const SHA_LONG *W=(const SHA_LONG *)data;
+
+		T1 = X[0] = W[0];	ROUND_00_15(0,a,b,c,d,e,f,g,h);
+		T1 = X[1] = W[1];	ROUND_00_15(1,h,a,b,c,d,e,f,g);
+		T1 = X[2] = W[2];	ROUND_00_15(2,g,h,a,b,c,d,e,f);
+		T1 = X[3] = W[3];	ROUND_00_15(3,f,g,h,a,b,c,d,e);
+		T1 = X[4] = W[4];	ROUND_00_15(4,e,f,g,h,a,b,c,d);
+		T1 = X[5] = W[5];	ROUND_00_15(5,d,e,f,g,h,a,b,c);
+		T1 = X[6] = W[6];	ROUND_00_15(6,c,d,e,f,g,h,a,b);
+		T1 = X[7] = W[7];	ROUND_00_15(7,b,c,d,e,f,g,h,a);
+		T1 = X[8] = W[8];	ROUND_00_15(8,a,b,c,d,e,f,g,h);
+		T1 = X[9] = W[9];	ROUND_00_15(9,h,a,b,c,d,e,f,g);
+		T1 = X[10] = W[10];	ROUND_00_15(10,g,h,a,b,c,d,e,f);
+		T1 = X[11] = W[11];	ROUND_00_15(11,f,g,h,a,b,c,d,e);
+		T1 = X[12] = W[12];	ROUND_00_15(12,e,f,g,h,a,b,c,d);
+		T1 = X[13] = W[13];	ROUND_00_15(13,d,e,f,g,h,a,b,c);
+		T1 = X[14] = W[14];	ROUND_00_15(14,c,d,e,f,g,h,a,b);
+		T1 = X[15] = W[15];	ROUND_00_15(15,b,c,d,e,f,g,h,a);
+
+		data += SHA256_CBLOCK;
+		}
+	else
+		{
+		SHA_LONG l;
+
+		HOST_c2l(data,l); T1 = X[0] = l;  ROUND_00_15(0,a,b,c,d,e,f,g,h);
+		HOST_c2l(data,l); T1 = X[1] = l;  ROUND_00_15(1,h,a,b,c,d,e,f,g);
+		HOST_c2l(data,l); T1 = X[2] = l;  ROUND_00_15(2,g,h,a,b,c,d,e,f);
+		HOST_c2l(data,l); T1 = X[3] = l;  ROUND_00_15(3,f,g,h,a,b,c,d,e);
+		HOST_c2l(data,l); T1 = X[4] = l;  ROUND_00_15(4,e,f,g,h,a,b,c,d);
+		HOST_c2l(data,l); T1 = X[5] = l;  ROUND_00_15(5,d,e,f,g,h,a,b,c);
+		HOST_c2l(data,l); T1 = X[6] = l;  ROUND_00_15(6,c,d,e,f,g,h,a,b);
+		HOST_c2l(data,l); T1 = X[7] = l;  ROUND_00_15(7,b,c,d,e,f,g,h,a);
+		HOST_c2l(data,l); T1 = X[8] = l;  ROUND_00_15(8,a,b,c,d,e,f,g,h);
+		HOST_c2l(data,l); T1 = X[9] = l;  ROUND_00_15(9,h,a,b,c,d,e,f,g);
+		HOST_c2l(data,l); T1 = X[10] = l; ROUND_00_15(10,g,h,a,b,c,d,e,f);
+		HOST_c2l(data,l); T1 = X[11] = l; ROUND_00_15(11,f,g,h,a,b,c,d,e);
+		HOST_c2l(data,l); T1 = X[12] = l; ROUND_00_15(12,e,f,g,h,a,b,c,d);
+		HOST_c2l(data,l); T1 = X[13] = l; ROUND_00_15(13,d,e,f,g,h,a,b,c);
+		HOST_c2l(data,l); T1 = X[14] = l; ROUND_00_15(14,c,d,e,f,g,h,a,b);
+		HOST_c2l(data,l); T1 = X[15] = l; ROUND_00_15(15,b,c,d,e,f,g,h,a);
+		}
+
+	for (i=16;i<64;i+=8)
+		{
+		ROUND_16_63(i+0,a,b,c,d,e,f,g,h,X);
+		ROUND_16_63(i+1,h,a,b,c,d,e,f,g,X);
+		ROUND_16_63(i+2,g,h,a,b,c,d,e,f,X);
+		ROUND_16_63(i+3,f,g,h,a,b,c,d,e,X);
+		ROUND_16_63(i+4,e,f,g,h,a,b,c,d,X);
+		ROUND_16_63(i+5,d,e,f,g,h,a,b,c,X);
+		ROUND_16_63(i+6,c,d,e,f,g,h,a,b,X);
+		ROUND_16_63(i+7,b,c,d,e,f,g,h,a,X);
+		}
+
+	ctx->h[0] += a;	ctx->h[1] += b;	ctx->h[2] += c;	ctx->h[3] += d;
+	ctx->h[4] += e;	ctx->h[5] += f;	ctx->h[6] += g;	ctx->h[7] += h;
+
+			}
+	}
+
+#endif
+#endif /* SHA256_ASM */
+
+#endif /* OPENSSL_NO_SHA256 */
diff --git a/crypto/libressl/crypto/sha/sha512-elf-x86_64.S b/crypto/libressl/crypto/sha/sha512-elf-x86_64.S
new file mode 100644
index 0000000000..b640176ca0
--- /dev/null
+++ b/crypto/libressl/crypto/sha/sha512-elf-x86_64.S
@@ -0,0 +1,1805 @@
+.text	
+
+.globl	sha512_block_data_order
+.type	sha512_block_data_order,@function
+.align	16
+sha512_block_data_order:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	movq	%rsp,%r11
+	shlq	$4,%rdx
+	subq	$128+32,%rsp
+	leaq	(%rsi,%rdx,8),%rdx
+	andq	$-64,%rsp
+	movq	%rdi,128+0(%rsp)
+	movq	%rsi,128+8(%rsp)
+	movq	%rdx,128+16(%rsp)
+	movq	%r11,128+24(%rsp)
+.Lprologue:
+
+	leaq	K512(%rip),%rbp
+
+	movq	0(%rdi),%rax
+	movq	8(%rdi),%rbx
+	movq	16(%rdi),%rcx
+	movq	24(%rdi),%rdx
+	movq	32(%rdi),%r8
+	movq	40(%rdi),%r9
+	movq	48(%rdi),%r10
+	movq	56(%rdi),%r11
+	jmp	.Lloop
+
+.align	16
+.Lloop:
+	xorq	%rdi,%rdi
+	movq	0(%rsi),%r12
+	movq	%r8,%r13
+	movq	%rax,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%r9,%r15
+	movq	%r12,0(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r15
+
+	rorq	$4,%r13
+	addq	%r11,%r12
+	xorq	%rax,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r8,%r15
+	movq	%rbx,%r11
+
+	rorq	$6,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r15
+
+	xorq	%rcx,%r11
+	xorq	%rax,%r14
+	addq	%r15,%r12
+	movq	%rbx,%r15
+
+	rorq	$14,%r13
+	andq	%rax,%r11
+	andq	%rcx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r11
+
+	addq	%r12,%rdx
+	addq	%r12,%r11
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r11
+
+	movq	8(%rsi),%r12
+	movq	%rdx,%r13
+	movq	%r11,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%r8,%r15
+	movq	%r12,8(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r15
+
+	rorq	$4,%r13
+	addq	%r10,%r12
+	xorq	%r11,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rdx,%r15
+	movq	%rax,%r10
+
+	rorq	$6,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r15
+
+	xorq	%rbx,%r10
+	xorq	%r11,%r14
+	addq	%r15,%r12
+	movq	%rax,%r15
+
+	rorq	$14,%r13
+	andq	%r11,%r10
+	andq	%rbx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r10
+
+	addq	%r12,%rcx
+	addq	%r12,%r10
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r10
+
+	movq	16(%rsi),%r12
+	movq	%rcx,%r13
+	movq	%r10,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%rdx,%r15
+	movq	%r12,16(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r15
+
+	rorq	$4,%r13
+	addq	%r9,%r12
+	xorq	%r10,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rcx,%r15
+	movq	%r11,%r9
+
+	rorq	$6,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r15
+
+	xorq	%rax,%r9
+	xorq	%r10,%r14
+	addq	%r15,%r12
+	movq	%r11,%r15
+
+	rorq	$14,%r13
+	andq	%r10,%r9
+	andq	%rax,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r9
+
+	addq	%r12,%rbx
+	addq	%r12,%r9
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r9
+
+	movq	24(%rsi),%r12
+	movq	%rbx,%r13
+	movq	%r9,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%rcx,%r15
+	movq	%r12,24(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r15
+
+	rorq	$4,%r13
+	addq	%r8,%r12
+	xorq	%r9,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rbx,%r15
+	movq	%r10,%r8
+
+	rorq	$6,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r15
+
+	xorq	%r11,%r8
+	xorq	%r9,%r14
+	addq	%r15,%r12
+	movq	%r10,%r15
+
+	rorq	$14,%r13
+	andq	%r9,%r8
+	andq	%r11,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r8
+
+	addq	%r12,%rax
+	addq	%r12,%r8
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r8
+
+	movq	32(%rsi),%r12
+	movq	%rax,%r13
+	movq	%r8,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%rbx,%r15
+	movq	%r12,32(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r15
+
+	rorq	$4,%r13
+	addq	%rdx,%r12
+	xorq	%r8,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rax,%r15
+	movq	%r9,%rdx
+
+	rorq	$6,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r15
+
+	xorq	%r10,%rdx
+	xorq	%r8,%r14
+	addq	%r15,%r12
+	movq	%r9,%r15
+
+	rorq	$14,%r13
+	andq	%r8,%rdx
+	andq	%r10,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rdx
+
+	addq	%r12,%r11
+	addq	%r12,%rdx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rdx
+
+	movq	40(%rsi),%r12
+	movq	%r11,%r13
+	movq	%rdx,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%rax,%r15
+	movq	%r12,40(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r15
+
+	rorq	$4,%r13
+	addq	%rcx,%r12
+	xorq	%rdx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r11,%r15
+	movq	%r8,%rcx
+
+	rorq	$6,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r15
+
+	xorq	%r9,%rcx
+	xorq	%rdx,%r14
+	addq	%r15,%r12
+	movq	%r8,%r15
+
+	rorq	$14,%r13
+	andq	%rdx,%rcx
+	andq	%r9,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rcx
+
+	addq	%r12,%r10
+	addq	%r12,%rcx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rcx
+
+	movq	48(%rsi),%r12
+	movq	%r10,%r13
+	movq	%rcx,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%r11,%r15
+	movq	%r12,48(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r15
+
+	rorq	$4,%r13
+	addq	%rbx,%r12
+	xorq	%rcx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r10,%r15
+	movq	%rdx,%rbx
+
+	rorq	$6,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r15
+
+	xorq	%r8,%rbx
+	xorq	%rcx,%r14
+	addq	%r15,%r12
+	movq	%rdx,%r15
+
+	rorq	$14,%r13
+	andq	%rcx,%rbx
+	andq	%r8,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rbx
+
+	addq	%r12,%r9
+	addq	%r12,%rbx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rbx
+
+	movq	56(%rsi),%r12
+	movq	%r9,%r13
+	movq	%rbx,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%r10,%r15
+	movq	%r12,56(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r15
+
+	rorq	$4,%r13
+	addq	%rax,%r12
+	xorq	%rbx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r9,%r15
+	movq	%rcx,%rax
+
+	rorq	$6,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r15
+
+	xorq	%rdx,%rax
+	xorq	%rbx,%r14
+	addq	%r15,%r12
+	movq	%rcx,%r15
+
+	rorq	$14,%r13
+	andq	%rbx,%rax
+	andq	%rdx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rax
+
+	addq	%r12,%r8
+	addq	%r12,%rax
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rax
+
+	movq	64(%rsi),%r12
+	movq	%r8,%r13
+	movq	%rax,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%r9,%r15
+	movq	%r12,64(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r15
+
+	rorq	$4,%r13
+	addq	%r11,%r12
+	xorq	%rax,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r8,%r15
+	movq	%rbx,%r11
+
+	rorq	$6,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r15
+
+	xorq	%rcx,%r11
+	xorq	%rax,%r14
+	addq	%r15,%r12
+	movq	%rbx,%r15
+
+	rorq	$14,%r13
+	andq	%rax,%r11
+	andq	%rcx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r11
+
+	addq	%r12,%rdx
+	addq	%r12,%r11
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r11
+
+	movq	72(%rsi),%r12
+	movq	%rdx,%r13
+	movq	%r11,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%r8,%r15
+	movq	%r12,72(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r15
+
+	rorq	$4,%r13
+	addq	%r10,%r12
+	xorq	%r11,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rdx,%r15
+	movq	%rax,%r10
+
+	rorq	$6,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r15
+
+	xorq	%rbx,%r10
+	xorq	%r11,%r14
+	addq	%r15,%r12
+	movq	%rax,%r15
+
+	rorq	$14,%r13
+	andq	%r11,%r10
+	andq	%rbx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r10
+
+	addq	%r12,%rcx
+	addq	%r12,%r10
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r10
+
+	movq	80(%rsi),%r12
+	movq	%rcx,%r13
+	movq	%r10,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%rdx,%r15
+	movq	%r12,80(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r15
+
+	rorq	$4,%r13
+	addq	%r9,%r12
+	xorq	%r10,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rcx,%r15
+	movq	%r11,%r9
+
+	rorq	$6,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r15
+
+	xorq	%rax,%r9
+	xorq	%r10,%r14
+	addq	%r15,%r12
+	movq	%r11,%r15
+
+	rorq	$14,%r13
+	andq	%r10,%r9
+	andq	%rax,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r9
+
+	addq	%r12,%rbx
+	addq	%r12,%r9
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r9
+
+	movq	88(%rsi),%r12
+	movq	%rbx,%r13
+	movq	%r9,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%rcx,%r15
+	movq	%r12,88(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r15
+
+	rorq	$4,%r13
+	addq	%r8,%r12
+	xorq	%r9,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rbx,%r15
+	movq	%r10,%r8
+
+	rorq	$6,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r15
+
+	xorq	%r11,%r8
+	xorq	%r9,%r14
+	addq	%r15,%r12
+	movq	%r10,%r15
+
+	rorq	$14,%r13
+	andq	%r9,%r8
+	andq	%r11,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r8
+
+	addq	%r12,%rax
+	addq	%r12,%r8
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r8
+
+	movq	96(%rsi),%r12
+	movq	%rax,%r13
+	movq	%r8,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%rbx,%r15
+	movq	%r12,96(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r15
+
+	rorq	$4,%r13
+	addq	%rdx,%r12
+	xorq	%r8,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rax,%r15
+	movq	%r9,%rdx
+
+	rorq	$6,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r15
+
+	xorq	%r10,%rdx
+	xorq	%r8,%r14
+	addq	%r15,%r12
+	movq	%r9,%r15
+
+	rorq	$14,%r13
+	andq	%r8,%rdx
+	andq	%r10,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rdx
+
+	addq	%r12,%r11
+	addq	%r12,%rdx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rdx
+
+	movq	104(%rsi),%r12
+	movq	%r11,%r13
+	movq	%rdx,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%rax,%r15
+	movq	%r12,104(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r15
+
+	rorq	$4,%r13
+	addq	%rcx,%r12
+	xorq	%rdx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r11,%r15
+	movq	%r8,%rcx
+
+	rorq	$6,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r15
+
+	xorq	%r9,%rcx
+	xorq	%rdx,%r14
+	addq	%r15,%r12
+	movq	%r8,%r15
+
+	rorq	$14,%r13
+	andq	%rdx,%rcx
+	andq	%r9,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rcx
+
+	addq	%r12,%r10
+	addq	%r12,%rcx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rcx
+
+	movq	112(%rsi),%r12
+	movq	%r10,%r13
+	movq	%rcx,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%r11,%r15
+	movq	%r12,112(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r15
+
+	rorq	$4,%r13
+	addq	%rbx,%r12
+	xorq	%rcx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r10,%r15
+	movq	%rdx,%rbx
+
+	rorq	$6,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r15
+
+	xorq	%r8,%rbx
+	xorq	%rcx,%r14
+	addq	%r15,%r12
+	movq	%rdx,%r15
+
+	rorq	$14,%r13
+	andq	%rcx,%rbx
+	andq	%r8,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rbx
+
+	addq	%r12,%r9
+	addq	%r12,%rbx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rbx
+
+	movq	120(%rsi),%r12
+	movq	%r9,%r13
+	movq	%rbx,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%r10,%r15
+	movq	%r12,120(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r15
+
+	rorq	$4,%r13
+	addq	%rax,%r12
+	xorq	%rbx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r9,%r15
+	movq	%rcx,%rax
+
+	rorq	$6,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r15
+
+	xorq	%rdx,%rax
+	xorq	%rbx,%r14
+	addq	%r15,%r12
+	movq	%rcx,%r15
+
+	rorq	$14,%r13
+	andq	%rbx,%rax
+	andq	%rdx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rax
+
+	addq	%r12,%r8
+	addq	%r12,%rax
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rax
+
+	jmp	.Lrounds_16_xx
+.align	16
+.Lrounds_16_xx:
+	movq	8(%rsp),%r13
+	movq	112(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	72(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	0(%rsp),%r12
+	movq	%r8,%r13
+	addq	%r14,%r12
+	movq	%rax,%r14
+	rorq	$23,%r13
+	movq	%r9,%r15
+	movq	%r12,0(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r15
+
+	rorq	$4,%r13
+	addq	%r11,%r12
+	xorq	%rax,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r8,%r15
+	movq	%rbx,%r11
+
+	rorq	$6,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r15
+
+	xorq	%rcx,%r11
+	xorq	%rax,%r14
+	addq	%r15,%r12
+	movq	%rbx,%r15
+
+	rorq	$14,%r13
+	andq	%rax,%r11
+	andq	%rcx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r11
+
+	addq	%r12,%rdx
+	addq	%r12,%r11
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r11
+
+	movq	16(%rsp),%r13
+	movq	120(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	80(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	8(%rsp),%r12
+	movq	%rdx,%r13
+	addq	%r14,%r12
+	movq	%r11,%r14
+	rorq	$23,%r13
+	movq	%r8,%r15
+	movq	%r12,8(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r15
+
+	rorq	$4,%r13
+	addq	%r10,%r12
+	xorq	%r11,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rdx,%r15
+	movq	%rax,%r10
+
+	rorq	$6,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r15
+
+	xorq	%rbx,%r10
+	xorq	%r11,%r14
+	addq	%r15,%r12
+	movq	%rax,%r15
+
+	rorq	$14,%r13
+	andq	%r11,%r10
+	andq	%rbx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r10
+
+	addq	%r12,%rcx
+	addq	%r12,%r10
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r10
+
+	movq	24(%rsp),%r13
+	movq	0(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	88(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	16(%rsp),%r12
+	movq	%rcx,%r13
+	addq	%r14,%r12
+	movq	%r10,%r14
+	rorq	$23,%r13
+	movq	%rdx,%r15
+	movq	%r12,16(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r15
+
+	rorq	$4,%r13
+	addq	%r9,%r12
+	xorq	%r10,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rcx,%r15
+	movq	%r11,%r9
+
+	rorq	$6,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r15
+
+	xorq	%rax,%r9
+	xorq	%r10,%r14
+	addq	%r15,%r12
+	movq	%r11,%r15
+
+	rorq	$14,%r13
+	andq	%r10,%r9
+	andq	%rax,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r9
+
+	addq	%r12,%rbx
+	addq	%r12,%r9
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r9
+
+	movq	32(%rsp),%r13
+	movq	8(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	96(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	24(%rsp),%r12
+	movq	%rbx,%r13
+	addq	%r14,%r12
+	movq	%r9,%r14
+	rorq	$23,%r13
+	movq	%rcx,%r15
+	movq	%r12,24(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r15
+
+	rorq	$4,%r13
+	addq	%r8,%r12
+	xorq	%r9,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rbx,%r15
+	movq	%r10,%r8
+
+	rorq	$6,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r15
+
+	xorq	%r11,%r8
+	xorq	%r9,%r14
+	addq	%r15,%r12
+	movq	%r10,%r15
+
+	rorq	$14,%r13
+	andq	%r9,%r8
+	andq	%r11,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r8
+
+	addq	%r12,%rax
+	addq	%r12,%r8
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r8
+
+	movq	40(%rsp),%r13
+	movq	16(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	104(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	32(%rsp),%r12
+	movq	%rax,%r13
+	addq	%r14,%r12
+	movq	%r8,%r14
+	rorq	$23,%r13
+	movq	%rbx,%r15
+	movq	%r12,32(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r15
+
+	rorq	$4,%r13
+	addq	%rdx,%r12
+	xorq	%r8,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rax,%r15
+	movq	%r9,%rdx
+
+	rorq	$6,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r15
+
+	xorq	%r10,%rdx
+	xorq	%r8,%r14
+	addq	%r15,%r12
+	movq	%r9,%r15
+
+	rorq	$14,%r13
+	andq	%r8,%rdx
+	andq	%r10,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rdx
+
+	addq	%r12,%r11
+	addq	%r12,%rdx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rdx
+
+	movq	48(%rsp),%r13
+	movq	24(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	112(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	40(%rsp),%r12
+	movq	%r11,%r13
+	addq	%r14,%r12
+	movq	%rdx,%r14
+	rorq	$23,%r13
+	movq	%rax,%r15
+	movq	%r12,40(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r15
+
+	rorq	$4,%r13
+	addq	%rcx,%r12
+	xorq	%rdx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r11,%r15
+	movq	%r8,%rcx
+
+	rorq	$6,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r15
+
+	xorq	%r9,%rcx
+	xorq	%rdx,%r14
+	addq	%r15,%r12
+	movq	%r8,%r15
+
+	rorq	$14,%r13
+	andq	%rdx,%rcx
+	andq	%r9,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rcx
+
+	addq	%r12,%r10
+	addq	%r12,%rcx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rcx
+
+	movq	56(%rsp),%r13
+	movq	32(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	120(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	48(%rsp),%r12
+	movq	%r10,%r13
+	addq	%r14,%r12
+	movq	%rcx,%r14
+	rorq	$23,%r13
+	movq	%r11,%r15
+	movq	%r12,48(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r15
+
+	rorq	$4,%r13
+	addq	%rbx,%r12
+	xorq	%rcx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r10,%r15
+	movq	%rdx,%rbx
+
+	rorq	$6,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r15
+
+	xorq	%r8,%rbx
+	xorq	%rcx,%r14
+	addq	%r15,%r12
+	movq	%rdx,%r15
+
+	rorq	$14,%r13
+	andq	%rcx,%rbx
+	andq	%r8,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rbx
+
+	addq	%r12,%r9
+	addq	%r12,%rbx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rbx
+
+	movq	64(%rsp),%r13
+	movq	40(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	0(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	56(%rsp),%r12
+	movq	%r9,%r13
+	addq	%r14,%r12
+	movq	%rbx,%r14
+	rorq	$23,%r13
+	movq	%r10,%r15
+	movq	%r12,56(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r15
+
+	rorq	$4,%r13
+	addq	%rax,%r12
+	xorq	%rbx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r9,%r15
+	movq	%rcx,%rax
+
+	rorq	$6,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r15
+
+	xorq	%rdx,%rax
+	xorq	%rbx,%r14
+	addq	%r15,%r12
+	movq	%rcx,%r15
+
+	rorq	$14,%r13
+	andq	%rbx,%rax
+	andq	%rdx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rax
+
+	addq	%r12,%r8
+	addq	%r12,%rax
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rax
+
+	movq	72(%rsp),%r13
+	movq	48(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	8(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	64(%rsp),%r12
+	movq	%r8,%r13
+	addq	%r14,%r12
+	movq	%rax,%r14
+	rorq	$23,%r13
+	movq	%r9,%r15
+	movq	%r12,64(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r15
+
+	rorq	$4,%r13
+	addq	%r11,%r12
+	xorq	%rax,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r8,%r15
+	movq	%rbx,%r11
+
+	rorq	$6,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r15
+
+	xorq	%rcx,%r11
+	xorq	%rax,%r14
+	addq	%r15,%r12
+	movq	%rbx,%r15
+
+	rorq	$14,%r13
+	andq	%rax,%r11
+	andq	%rcx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r11
+
+	addq	%r12,%rdx
+	addq	%r12,%r11
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r11
+
+	movq	80(%rsp),%r13
+	movq	56(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	16(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	72(%rsp),%r12
+	movq	%rdx,%r13
+	addq	%r14,%r12
+	movq	%r11,%r14
+	rorq	$23,%r13
+	movq	%r8,%r15
+	movq	%r12,72(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r15
+
+	rorq	$4,%r13
+	addq	%r10,%r12
+	xorq	%r11,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rdx,%r15
+	movq	%rax,%r10
+
+	rorq	$6,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r15
+
+	xorq	%rbx,%r10
+	xorq	%r11,%r14
+	addq	%r15,%r12
+	movq	%rax,%r15
+
+	rorq	$14,%r13
+	andq	%r11,%r10
+	andq	%rbx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r10
+
+	addq	%r12,%rcx
+	addq	%r12,%r10
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r10
+
+	movq	88(%rsp),%r13
+	movq	64(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	24(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	80(%rsp),%r12
+	movq	%rcx,%r13
+	addq	%r14,%r12
+	movq	%r10,%r14
+	rorq	$23,%r13
+	movq	%rdx,%r15
+	movq	%r12,80(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r15
+
+	rorq	$4,%r13
+	addq	%r9,%r12
+	xorq	%r10,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rcx,%r15
+	movq	%r11,%r9
+
+	rorq	$6,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r15
+
+	xorq	%rax,%r9
+	xorq	%r10,%r14
+	addq	%r15,%r12
+	movq	%r11,%r15
+
+	rorq	$14,%r13
+	andq	%r10,%r9
+	andq	%rax,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r9
+
+	addq	%r12,%rbx
+	addq	%r12,%r9
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r9
+
+	movq	96(%rsp),%r13
+	movq	72(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	32(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	88(%rsp),%r12
+	movq	%rbx,%r13
+	addq	%r14,%r12
+	movq	%r9,%r14
+	rorq	$23,%r13
+	movq	%rcx,%r15
+	movq	%r12,88(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r15
+
+	rorq	$4,%r13
+	addq	%r8,%r12
+	xorq	%r9,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rbx,%r15
+	movq	%r10,%r8
+
+	rorq	$6,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r15
+
+	xorq	%r11,%r8
+	xorq	%r9,%r14
+	addq	%r15,%r12
+	movq	%r10,%r15
+
+	rorq	$14,%r13
+	andq	%r9,%r8
+	andq	%r11,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r8
+
+	addq	%r12,%rax
+	addq	%r12,%r8
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r8
+
+	movq	104(%rsp),%r13
+	movq	80(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	40(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	96(%rsp),%r12
+	movq	%rax,%r13
+	addq	%r14,%r12
+	movq	%r8,%r14
+	rorq	$23,%r13
+	movq	%rbx,%r15
+	movq	%r12,96(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r15
+
+	rorq	$4,%r13
+	addq	%rdx,%r12
+	xorq	%r8,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rax,%r15
+	movq	%r9,%rdx
+
+	rorq	$6,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r15
+
+	xorq	%r10,%rdx
+	xorq	%r8,%r14
+	addq	%r15,%r12
+	movq	%r9,%r15
+
+	rorq	$14,%r13
+	andq	%r8,%rdx
+	andq	%r10,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rdx
+
+	addq	%r12,%r11
+	addq	%r12,%rdx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rdx
+
+	movq	112(%rsp),%r13
+	movq	88(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	48(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	104(%rsp),%r12
+	movq	%r11,%r13
+	addq	%r14,%r12
+	movq	%rdx,%r14
+	rorq	$23,%r13
+	movq	%rax,%r15
+	movq	%r12,104(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r15
+
+	rorq	$4,%r13
+	addq	%rcx,%r12
+	xorq	%rdx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r11,%r15
+	movq	%r8,%rcx
+
+	rorq	$6,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r15
+
+	xorq	%r9,%rcx
+	xorq	%rdx,%r14
+	addq	%r15,%r12
+	movq	%r8,%r15
+
+	rorq	$14,%r13
+	andq	%rdx,%rcx
+	andq	%r9,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rcx
+
+	addq	%r12,%r10
+	addq	%r12,%rcx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rcx
+
+	movq	120(%rsp),%r13
+	movq	96(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	56(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	112(%rsp),%r12
+	movq	%r10,%r13
+	addq	%r14,%r12
+	movq	%rcx,%r14
+	rorq	$23,%r13
+	movq	%r11,%r15
+	movq	%r12,112(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r15
+
+	rorq	$4,%r13
+	addq	%rbx,%r12
+	xorq	%rcx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r10,%r15
+	movq	%rdx,%rbx
+
+	rorq	$6,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r15
+
+	xorq	%r8,%rbx
+	xorq	%rcx,%r14
+	addq	%r15,%r12
+	movq	%rdx,%r15
+
+	rorq	$14,%r13
+	andq	%rcx,%rbx
+	andq	%r8,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rbx
+
+	addq	%r12,%r9
+	addq	%r12,%rbx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rbx
+
+	movq	0(%rsp),%r13
+	movq	104(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	64(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	120(%rsp),%r12
+	movq	%r9,%r13
+	addq	%r14,%r12
+	movq	%rbx,%r14
+	rorq	$23,%r13
+	movq	%r10,%r15
+	movq	%r12,120(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r15
+
+	rorq	$4,%r13
+	addq	%rax,%r12
+	xorq	%rbx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r9,%r15
+	movq	%rcx,%rax
+
+	rorq	$6,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r15
+
+	xorq	%rdx,%rax
+	xorq	%rbx,%r14
+	addq	%r15,%r12
+	movq	%rcx,%r15
+
+	rorq	$14,%r13
+	andq	%rbx,%rax
+	andq	%rdx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rax
+
+	addq	%r12,%r8
+	addq	%r12,%rax
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rax
+
+	cmpq	$80,%rdi
+	jb	.Lrounds_16_xx
+
+	movq	128+0(%rsp),%rdi
+	leaq	128(%rsi),%rsi
+
+	addq	0(%rdi),%rax
+	addq	8(%rdi),%rbx
+	addq	16(%rdi),%rcx
+	addq	24(%rdi),%rdx
+	addq	32(%rdi),%r8
+	addq	40(%rdi),%r9
+	addq	48(%rdi),%r10
+	addq	56(%rdi),%r11
+
+	cmpq	128+16(%rsp),%rsi
+
+	movq	%rax,0(%rdi)
+	movq	%rbx,8(%rdi)
+	movq	%rcx,16(%rdi)
+	movq	%rdx,24(%rdi)
+	movq	%r8,32(%rdi)
+	movq	%r9,40(%rdi)
+	movq	%r10,48(%rdi)
+	movq	%r11,56(%rdi)
+	jb	.Lloop
+
+	movq	128+24(%rsp),%rsi
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+.Lepilogue:
+	.byte	0xf3,0xc3
+.size	sha512_block_data_order,.-sha512_block_data_order
+.align	64
+.type	K512,@object
+K512:
+.quad	0x428a2f98d728ae22,0x7137449123ef65cd
+.quad	0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
+.quad	0x3956c25bf348b538,0x59f111f1b605d019
+.quad	0x923f82a4af194f9b,0xab1c5ed5da6d8118
+.quad	0xd807aa98a3030242,0x12835b0145706fbe
+.quad	0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
+.quad	0x72be5d74f27b896f,0x80deb1fe3b1696b1
+.quad	0x9bdc06a725c71235,0xc19bf174cf692694
+.quad	0xe49b69c19ef14ad2,0xefbe4786384f25e3
+.quad	0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
+.quad	0x2de92c6f592b0275,0x4a7484aa6ea6e483
+.quad	0x5cb0a9dcbd41fbd4,0x76f988da831153b5
+.quad	0x983e5152ee66dfab,0xa831c66d2db43210
+.quad	0xb00327c898fb213f,0xbf597fc7beef0ee4
+.quad	0xc6e00bf33da88fc2,0xd5a79147930aa725
+.quad	0x06ca6351e003826f,0x142929670a0e6e70
+.quad	0x27b70a8546d22ffc,0x2e1b21385c26c926
+.quad	0x4d2c6dfc5ac42aed,0x53380d139d95b3df
+.quad	0x650a73548baf63de,0x766a0abb3c77b2a8
+.quad	0x81c2c92e47edaee6,0x92722c851482353b
+.quad	0xa2bfe8a14cf10364,0xa81a664bbc423001
+.quad	0xc24b8b70d0f89791,0xc76c51a30654be30
+.quad	0xd192e819d6ef5218,0xd69906245565a910
+.quad	0xf40e35855771202a,0x106aa07032bbd1b8
+.quad	0x19a4c116b8d2d0c8,0x1e376c085141ab53
+.quad	0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
+.quad	0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
+.quad	0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
+.quad	0x748f82ee5defb2fc,0x78a5636f43172f60
+.quad	0x84c87814a1f0ab72,0x8cc702081a6439ec
+.quad	0x90befffa23631e28,0xa4506cebde82bde9
+.quad	0xbef9a3f7b2c67915,0xc67178f2e372532b
+.quad	0xca273eceea26619c,0xd186b8c721c0c207
+.quad	0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
+.quad	0x06f067aa72176fba,0x0a637dc5a2c898a6
+.quad	0x113f9804bef90dae,0x1b710b35131c471b
+.quad	0x28db77f523047d84,0x32caab7b40c72493
+.quad	0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
+.quad	0x4cc5d4becb3e42b6,0x597f299cfc657e2a
+.quad	0x5fcb6fab3ad6faec,0x6c44198c4a475817
+#if defined(HAVE_GNU_STACK)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/crypto/libressl/crypto/sha/sha512-macosx-x86_64.S b/crypto/libressl/crypto/sha/sha512-macosx-x86_64.S
new file mode 100644
index 0000000000..0afcef739b
--- /dev/null
+++ b/crypto/libressl/crypto/sha/sha512-macosx-x86_64.S
@@ -0,0 +1,1802 @@
+.text	
+
+.globl	_sha512_block_data_order
+
+.p2align	4
+_sha512_block_data_order:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	movq	%rsp,%r11
+	shlq	$4,%rdx
+	subq	$128+32,%rsp
+	leaq	(%rsi,%rdx,8),%rdx
+	andq	$-64,%rsp
+	movq	%rdi,128+0(%rsp)
+	movq	%rsi,128+8(%rsp)
+	movq	%rdx,128+16(%rsp)
+	movq	%r11,128+24(%rsp)
+L$prologue:
+
+	leaq	K512(%rip),%rbp
+
+	movq	0(%rdi),%rax
+	movq	8(%rdi),%rbx
+	movq	16(%rdi),%rcx
+	movq	24(%rdi),%rdx
+	movq	32(%rdi),%r8
+	movq	40(%rdi),%r9
+	movq	48(%rdi),%r10
+	movq	56(%rdi),%r11
+	jmp	L$loop
+
+.p2align	4
+L$loop:
+	xorq	%rdi,%rdi
+	movq	0(%rsi),%r12
+	movq	%r8,%r13
+	movq	%rax,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%r9,%r15
+	movq	%r12,0(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r15
+
+	rorq	$4,%r13
+	addq	%r11,%r12
+	xorq	%rax,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r8,%r15
+	movq	%rbx,%r11
+
+	rorq	$6,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r15
+
+	xorq	%rcx,%r11
+	xorq	%rax,%r14
+	addq	%r15,%r12
+	movq	%rbx,%r15
+
+	rorq	$14,%r13
+	andq	%rax,%r11
+	andq	%rcx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r11
+
+	addq	%r12,%rdx
+	addq	%r12,%r11
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r11
+
+	movq	8(%rsi),%r12
+	movq	%rdx,%r13
+	movq	%r11,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%r8,%r15
+	movq	%r12,8(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r15
+
+	rorq	$4,%r13
+	addq	%r10,%r12
+	xorq	%r11,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rdx,%r15
+	movq	%rax,%r10
+
+	rorq	$6,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r15
+
+	xorq	%rbx,%r10
+	xorq	%r11,%r14
+	addq	%r15,%r12
+	movq	%rax,%r15
+
+	rorq	$14,%r13
+	andq	%r11,%r10
+	andq	%rbx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r10
+
+	addq	%r12,%rcx
+	addq	%r12,%r10
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r10
+
+	movq	16(%rsi),%r12
+	movq	%rcx,%r13
+	movq	%r10,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%rdx,%r15
+	movq	%r12,16(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r15
+
+	rorq	$4,%r13
+	addq	%r9,%r12
+	xorq	%r10,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rcx,%r15
+	movq	%r11,%r9
+
+	rorq	$6,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r15
+
+	xorq	%rax,%r9
+	xorq	%r10,%r14
+	addq	%r15,%r12
+	movq	%r11,%r15
+
+	rorq	$14,%r13
+	andq	%r10,%r9
+	andq	%rax,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r9
+
+	addq	%r12,%rbx
+	addq	%r12,%r9
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r9
+
+	movq	24(%rsi),%r12
+	movq	%rbx,%r13
+	movq	%r9,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%rcx,%r15
+	movq	%r12,24(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r15
+
+	rorq	$4,%r13
+	addq	%r8,%r12
+	xorq	%r9,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rbx,%r15
+	movq	%r10,%r8
+
+	rorq	$6,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r15
+
+	xorq	%r11,%r8
+	xorq	%r9,%r14
+	addq	%r15,%r12
+	movq	%r10,%r15
+
+	rorq	$14,%r13
+	andq	%r9,%r8
+	andq	%r11,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r8
+
+	addq	%r12,%rax
+	addq	%r12,%r8
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r8
+
+	movq	32(%rsi),%r12
+	movq	%rax,%r13
+	movq	%r8,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%rbx,%r15
+	movq	%r12,32(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r15
+
+	rorq	$4,%r13
+	addq	%rdx,%r12
+	xorq	%r8,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rax,%r15
+	movq	%r9,%rdx
+
+	rorq	$6,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r15
+
+	xorq	%r10,%rdx
+	xorq	%r8,%r14
+	addq	%r15,%r12
+	movq	%r9,%r15
+
+	rorq	$14,%r13
+	andq	%r8,%rdx
+	andq	%r10,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rdx
+
+	addq	%r12,%r11
+	addq	%r12,%rdx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rdx
+
+	movq	40(%rsi),%r12
+	movq	%r11,%r13
+	movq	%rdx,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%rax,%r15
+	movq	%r12,40(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r15
+
+	rorq	$4,%r13
+	addq	%rcx,%r12
+	xorq	%rdx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r11,%r15
+	movq	%r8,%rcx
+
+	rorq	$6,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r15
+
+	xorq	%r9,%rcx
+	xorq	%rdx,%r14
+	addq	%r15,%r12
+	movq	%r8,%r15
+
+	rorq	$14,%r13
+	andq	%rdx,%rcx
+	andq	%r9,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rcx
+
+	addq	%r12,%r10
+	addq	%r12,%rcx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rcx
+
+	movq	48(%rsi),%r12
+	movq	%r10,%r13
+	movq	%rcx,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%r11,%r15
+	movq	%r12,48(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r15
+
+	rorq	$4,%r13
+	addq	%rbx,%r12
+	xorq	%rcx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r10,%r15
+	movq	%rdx,%rbx
+
+	rorq	$6,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r15
+
+	xorq	%r8,%rbx
+	xorq	%rcx,%r14
+	addq	%r15,%r12
+	movq	%rdx,%r15
+
+	rorq	$14,%r13
+	andq	%rcx,%rbx
+	andq	%r8,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rbx
+
+	addq	%r12,%r9
+	addq	%r12,%rbx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rbx
+
+	movq	56(%rsi),%r12
+	movq	%r9,%r13
+	movq	%rbx,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%r10,%r15
+	movq	%r12,56(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r15
+
+	rorq	$4,%r13
+	addq	%rax,%r12
+	xorq	%rbx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r9,%r15
+	movq	%rcx,%rax
+
+	rorq	$6,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r15
+
+	xorq	%rdx,%rax
+	xorq	%rbx,%r14
+	addq	%r15,%r12
+	movq	%rcx,%r15
+
+	rorq	$14,%r13
+	andq	%rbx,%rax
+	andq	%rdx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rax
+
+	addq	%r12,%r8
+	addq	%r12,%rax
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rax
+
+	movq	64(%rsi),%r12
+	movq	%r8,%r13
+	movq	%rax,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%r9,%r15
+	movq	%r12,64(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r15
+
+	rorq	$4,%r13
+	addq	%r11,%r12
+	xorq	%rax,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r8,%r15
+	movq	%rbx,%r11
+
+	rorq	$6,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r15
+
+	xorq	%rcx,%r11
+	xorq	%rax,%r14
+	addq	%r15,%r12
+	movq	%rbx,%r15
+
+	rorq	$14,%r13
+	andq	%rax,%r11
+	andq	%rcx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r11
+
+	addq	%r12,%rdx
+	addq	%r12,%r11
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r11
+
+	movq	72(%rsi),%r12
+	movq	%rdx,%r13
+	movq	%r11,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%r8,%r15
+	movq	%r12,72(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r15
+
+	rorq	$4,%r13
+	addq	%r10,%r12
+	xorq	%r11,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rdx,%r15
+	movq	%rax,%r10
+
+	rorq	$6,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r15
+
+	xorq	%rbx,%r10
+	xorq	%r11,%r14
+	addq	%r15,%r12
+	movq	%rax,%r15
+
+	rorq	$14,%r13
+	andq	%r11,%r10
+	andq	%rbx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r10
+
+	addq	%r12,%rcx
+	addq	%r12,%r10
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r10
+
+	movq	80(%rsi),%r12
+	movq	%rcx,%r13
+	movq	%r10,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%rdx,%r15
+	movq	%r12,80(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r15
+
+	rorq	$4,%r13
+	addq	%r9,%r12
+	xorq	%r10,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rcx,%r15
+	movq	%r11,%r9
+
+	rorq	$6,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r15
+
+	xorq	%rax,%r9
+	xorq	%r10,%r14
+	addq	%r15,%r12
+	movq	%r11,%r15
+
+	rorq	$14,%r13
+	andq	%r10,%r9
+	andq	%rax,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r9
+
+	addq	%r12,%rbx
+	addq	%r12,%r9
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r9
+
+	movq	88(%rsi),%r12
+	movq	%rbx,%r13
+	movq	%r9,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%rcx,%r15
+	movq	%r12,88(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r15
+
+	rorq	$4,%r13
+	addq	%r8,%r12
+	xorq	%r9,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rbx,%r15
+	movq	%r10,%r8
+
+	rorq	$6,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r15
+
+	xorq	%r11,%r8
+	xorq	%r9,%r14
+	addq	%r15,%r12
+	movq	%r10,%r15
+
+	rorq	$14,%r13
+	andq	%r9,%r8
+	andq	%r11,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r8
+
+	addq	%r12,%rax
+	addq	%r12,%r8
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r8
+
+	movq	96(%rsi),%r12
+	movq	%rax,%r13
+	movq	%r8,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%rbx,%r15
+	movq	%r12,96(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r15
+
+	rorq	$4,%r13
+	addq	%rdx,%r12
+	xorq	%r8,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rax,%r15
+	movq	%r9,%rdx
+
+	rorq	$6,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r15
+
+	xorq	%r10,%rdx
+	xorq	%r8,%r14
+	addq	%r15,%r12
+	movq	%r9,%r15
+
+	rorq	$14,%r13
+	andq	%r8,%rdx
+	andq	%r10,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rdx
+
+	addq	%r12,%r11
+	addq	%r12,%rdx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rdx
+
+	movq	104(%rsi),%r12
+	movq	%r11,%r13
+	movq	%rdx,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%rax,%r15
+	movq	%r12,104(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r15
+
+	rorq	$4,%r13
+	addq	%rcx,%r12
+	xorq	%rdx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r11,%r15
+	movq	%r8,%rcx
+
+	rorq	$6,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r15
+
+	xorq	%r9,%rcx
+	xorq	%rdx,%r14
+	addq	%r15,%r12
+	movq	%r8,%r15
+
+	rorq	$14,%r13
+	andq	%rdx,%rcx
+	andq	%r9,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rcx
+
+	addq	%r12,%r10
+	addq	%r12,%rcx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rcx
+
+	movq	112(%rsi),%r12
+	movq	%r10,%r13
+	movq	%rcx,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%r11,%r15
+	movq	%r12,112(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r15
+
+	rorq	$4,%r13
+	addq	%rbx,%r12
+	xorq	%rcx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r10,%r15
+	movq	%rdx,%rbx
+
+	rorq	$6,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r15
+
+	xorq	%r8,%rbx
+	xorq	%rcx,%r14
+	addq	%r15,%r12
+	movq	%rdx,%r15
+
+	rorq	$14,%r13
+	andq	%rcx,%rbx
+	andq	%r8,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rbx
+
+	addq	%r12,%r9
+	addq	%r12,%rbx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rbx
+
+	movq	120(%rsi),%r12
+	movq	%r9,%r13
+	movq	%rbx,%r14
+	bswapq	%r12
+	rorq	$23,%r13
+	movq	%r10,%r15
+	movq	%r12,120(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r15
+
+	rorq	$4,%r13
+	addq	%rax,%r12
+	xorq	%rbx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r9,%r15
+	movq	%rcx,%rax
+
+	rorq	$6,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r15
+
+	xorq	%rdx,%rax
+	xorq	%rbx,%r14
+	addq	%r15,%r12
+	movq	%rcx,%r15
+
+	rorq	$14,%r13
+	andq	%rbx,%rax
+	andq	%rdx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rax
+
+	addq	%r12,%r8
+	addq	%r12,%rax
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rax
+
+	jmp	L$rounds_16_xx
+.p2align	4
+L$rounds_16_xx:
+	movq	8(%rsp),%r13
+	movq	112(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	72(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	0(%rsp),%r12
+	movq	%r8,%r13
+	addq	%r14,%r12
+	movq	%rax,%r14
+	rorq	$23,%r13
+	movq	%r9,%r15
+	movq	%r12,0(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r15
+
+	rorq	$4,%r13
+	addq	%r11,%r12
+	xorq	%rax,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r8,%r15
+	movq	%rbx,%r11
+
+	rorq	$6,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r15
+
+	xorq	%rcx,%r11
+	xorq	%rax,%r14
+	addq	%r15,%r12
+	movq	%rbx,%r15
+
+	rorq	$14,%r13
+	andq	%rax,%r11
+	andq	%rcx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r11
+
+	addq	%r12,%rdx
+	addq	%r12,%r11
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r11
+
+	movq	16(%rsp),%r13
+	movq	120(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	80(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	8(%rsp),%r12
+	movq	%rdx,%r13
+	addq	%r14,%r12
+	movq	%r11,%r14
+	rorq	$23,%r13
+	movq	%r8,%r15
+	movq	%r12,8(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r15
+
+	rorq	$4,%r13
+	addq	%r10,%r12
+	xorq	%r11,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rdx,%r15
+	movq	%rax,%r10
+
+	rorq	$6,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r15
+
+	xorq	%rbx,%r10
+	xorq	%r11,%r14
+	addq	%r15,%r12
+	movq	%rax,%r15
+
+	rorq	$14,%r13
+	andq	%r11,%r10
+	andq	%rbx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r10
+
+	addq	%r12,%rcx
+	addq	%r12,%r10
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r10
+
+	movq	24(%rsp),%r13
+	movq	0(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	88(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	16(%rsp),%r12
+	movq	%rcx,%r13
+	addq	%r14,%r12
+	movq	%r10,%r14
+	rorq	$23,%r13
+	movq	%rdx,%r15
+	movq	%r12,16(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r15
+
+	rorq	$4,%r13
+	addq	%r9,%r12
+	xorq	%r10,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rcx,%r15
+	movq	%r11,%r9
+
+	rorq	$6,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r15
+
+	xorq	%rax,%r9
+	xorq	%r10,%r14
+	addq	%r15,%r12
+	movq	%r11,%r15
+
+	rorq	$14,%r13
+	andq	%r10,%r9
+	andq	%rax,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r9
+
+	addq	%r12,%rbx
+	addq	%r12,%r9
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r9
+
+	movq	32(%rsp),%r13
+	movq	8(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	96(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	24(%rsp),%r12
+	movq	%rbx,%r13
+	addq	%r14,%r12
+	movq	%r9,%r14
+	rorq	$23,%r13
+	movq	%rcx,%r15
+	movq	%r12,24(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r15
+
+	rorq	$4,%r13
+	addq	%r8,%r12
+	xorq	%r9,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rbx,%r15
+	movq	%r10,%r8
+
+	rorq	$6,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r15
+
+	xorq	%r11,%r8
+	xorq	%r9,%r14
+	addq	%r15,%r12
+	movq	%r10,%r15
+
+	rorq	$14,%r13
+	andq	%r9,%r8
+	andq	%r11,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r8
+
+	addq	%r12,%rax
+	addq	%r12,%r8
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r8
+
+	movq	40(%rsp),%r13
+	movq	16(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	104(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	32(%rsp),%r12
+	movq	%rax,%r13
+	addq	%r14,%r12
+	movq	%r8,%r14
+	rorq	$23,%r13
+	movq	%rbx,%r15
+	movq	%r12,32(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r15
+
+	rorq	$4,%r13
+	addq	%rdx,%r12
+	xorq	%r8,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rax,%r15
+	movq	%r9,%rdx
+
+	rorq	$6,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r15
+
+	xorq	%r10,%rdx
+	xorq	%r8,%r14
+	addq	%r15,%r12
+	movq	%r9,%r15
+
+	rorq	$14,%r13
+	andq	%r8,%rdx
+	andq	%r10,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rdx
+
+	addq	%r12,%r11
+	addq	%r12,%rdx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rdx
+
+	movq	48(%rsp),%r13
+	movq	24(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	112(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	40(%rsp),%r12
+	movq	%r11,%r13
+	addq	%r14,%r12
+	movq	%rdx,%r14
+	rorq	$23,%r13
+	movq	%rax,%r15
+	movq	%r12,40(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r15
+
+	rorq	$4,%r13
+	addq	%rcx,%r12
+	xorq	%rdx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r11,%r15
+	movq	%r8,%rcx
+
+	rorq	$6,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r15
+
+	xorq	%r9,%rcx
+	xorq	%rdx,%r14
+	addq	%r15,%r12
+	movq	%r8,%r15
+
+	rorq	$14,%r13
+	andq	%rdx,%rcx
+	andq	%r9,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rcx
+
+	addq	%r12,%r10
+	addq	%r12,%rcx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rcx
+
+	movq	56(%rsp),%r13
+	movq	32(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	120(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	48(%rsp),%r12
+	movq	%r10,%r13
+	addq	%r14,%r12
+	movq	%rcx,%r14
+	rorq	$23,%r13
+	movq	%r11,%r15
+	movq	%r12,48(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r15
+
+	rorq	$4,%r13
+	addq	%rbx,%r12
+	xorq	%rcx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r10,%r15
+	movq	%rdx,%rbx
+
+	rorq	$6,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r15
+
+	xorq	%r8,%rbx
+	xorq	%rcx,%r14
+	addq	%r15,%r12
+	movq	%rdx,%r15
+
+	rorq	$14,%r13
+	andq	%rcx,%rbx
+	andq	%r8,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rbx
+
+	addq	%r12,%r9
+	addq	%r12,%rbx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rbx
+
+	movq	64(%rsp),%r13
+	movq	40(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	0(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	56(%rsp),%r12
+	movq	%r9,%r13
+	addq	%r14,%r12
+	movq	%rbx,%r14
+	rorq	$23,%r13
+	movq	%r10,%r15
+	movq	%r12,56(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r15
+
+	rorq	$4,%r13
+	addq	%rax,%r12
+	xorq	%rbx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r9,%r15
+	movq	%rcx,%rax
+
+	rorq	$6,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r15
+
+	xorq	%rdx,%rax
+	xorq	%rbx,%r14
+	addq	%r15,%r12
+	movq	%rcx,%r15
+
+	rorq	$14,%r13
+	andq	%rbx,%rax
+	andq	%rdx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rax
+
+	addq	%r12,%r8
+	addq	%r12,%rax
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rax
+
+	movq	72(%rsp),%r13
+	movq	48(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	8(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	64(%rsp),%r12
+	movq	%r8,%r13
+	addq	%r14,%r12
+	movq	%rax,%r14
+	rorq	$23,%r13
+	movq	%r9,%r15
+	movq	%r12,64(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r15
+
+	rorq	$4,%r13
+	addq	%r11,%r12
+	xorq	%rax,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r8,%r15
+	movq	%rbx,%r11
+
+	rorq	$6,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r15
+
+	xorq	%rcx,%r11
+	xorq	%rax,%r14
+	addq	%r15,%r12
+	movq	%rbx,%r15
+
+	rorq	$14,%r13
+	andq	%rax,%r11
+	andq	%rcx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r11
+
+	addq	%r12,%rdx
+	addq	%r12,%r11
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r11
+
+	movq	80(%rsp),%r13
+	movq	56(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	16(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	72(%rsp),%r12
+	movq	%rdx,%r13
+	addq	%r14,%r12
+	movq	%r11,%r14
+	rorq	$23,%r13
+	movq	%r8,%r15
+	movq	%r12,72(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r15
+
+	rorq	$4,%r13
+	addq	%r10,%r12
+	xorq	%r11,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rdx,%r15
+	movq	%rax,%r10
+
+	rorq	$6,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r15
+
+	xorq	%rbx,%r10
+	xorq	%r11,%r14
+	addq	%r15,%r12
+	movq	%rax,%r15
+
+	rorq	$14,%r13
+	andq	%r11,%r10
+	andq	%rbx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r10
+
+	addq	%r12,%rcx
+	addq	%r12,%r10
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r10
+
+	movq	88(%rsp),%r13
+	movq	64(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	24(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	80(%rsp),%r12
+	movq	%rcx,%r13
+	addq	%r14,%r12
+	movq	%r10,%r14
+	rorq	$23,%r13
+	movq	%rdx,%r15
+	movq	%r12,80(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r15
+
+	rorq	$4,%r13
+	addq	%r9,%r12
+	xorq	%r10,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rcx,%r15
+	movq	%r11,%r9
+
+	rorq	$6,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r15
+
+	xorq	%rax,%r9
+	xorq	%r10,%r14
+	addq	%r15,%r12
+	movq	%r11,%r15
+
+	rorq	$14,%r13
+	andq	%r10,%r9
+	andq	%rax,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r9
+
+	addq	%r12,%rbx
+	addq	%r12,%r9
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r9
+
+	movq	96(%rsp),%r13
+	movq	72(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	32(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	88(%rsp),%r12
+	movq	%rbx,%r13
+	addq	%r14,%r12
+	movq	%r9,%r14
+	rorq	$23,%r13
+	movq	%rcx,%r15
+	movq	%r12,88(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r15
+
+	rorq	$4,%r13
+	addq	%r8,%r12
+	xorq	%r9,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rbx,%r15
+	movq	%r10,%r8
+
+	rorq	$6,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r15
+
+	xorq	%r11,%r8
+	xorq	%r9,%r14
+	addq	%r15,%r12
+	movq	%r10,%r15
+
+	rorq	$14,%r13
+	andq	%r9,%r8
+	andq	%r11,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%r8
+
+	addq	%r12,%rax
+	addq	%r12,%r8
+	leaq	1(%rdi),%rdi
+	addq	%r14,%r8
+
+	movq	104(%rsp),%r13
+	movq	80(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	40(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	96(%rsp),%r12
+	movq	%rax,%r13
+	addq	%r14,%r12
+	movq	%r8,%r14
+	rorq	$23,%r13
+	movq	%rbx,%r15
+	movq	%r12,96(%rsp)
+
+	rorq	$5,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r15
+
+	rorq	$4,%r13
+	addq	%rdx,%r12
+	xorq	%r8,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%rax,%r15
+	movq	%r9,%rdx
+
+	rorq	$6,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r15
+
+	xorq	%r10,%rdx
+	xorq	%r8,%r14
+	addq	%r15,%r12
+	movq	%r9,%r15
+
+	rorq	$14,%r13
+	andq	%r8,%rdx
+	andq	%r10,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rdx
+
+	addq	%r12,%r11
+	addq	%r12,%rdx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rdx
+
+	movq	112(%rsp),%r13
+	movq	88(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	48(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	104(%rsp),%r12
+	movq	%r11,%r13
+	addq	%r14,%r12
+	movq	%rdx,%r14
+	rorq	$23,%r13
+	movq	%rax,%r15
+	movq	%r12,104(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r15
+
+	rorq	$4,%r13
+	addq	%rcx,%r12
+	xorq	%rdx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r11,%r15
+	movq	%r8,%rcx
+
+	rorq	$6,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r15
+
+	xorq	%r9,%rcx
+	xorq	%rdx,%r14
+	addq	%r15,%r12
+	movq	%r8,%r15
+
+	rorq	$14,%r13
+	andq	%rdx,%rcx
+	andq	%r9,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rcx
+
+	addq	%r12,%r10
+	addq	%r12,%rcx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rcx
+
+	movq	120(%rsp),%r13
+	movq	96(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	56(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	112(%rsp),%r12
+	movq	%r10,%r13
+	addq	%r14,%r12
+	movq	%rcx,%r14
+	rorq	$23,%r13
+	movq	%r11,%r15
+	movq	%r12,112(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r15
+
+	rorq	$4,%r13
+	addq	%rbx,%r12
+	xorq	%rcx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r10,%r15
+	movq	%rdx,%rbx
+
+	rorq	$6,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r15
+
+	xorq	%r8,%rbx
+	xorq	%rcx,%r14
+	addq	%r15,%r12
+	movq	%rdx,%r15
+
+	rorq	$14,%r13
+	andq	%rcx,%rbx
+	andq	%r8,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rbx
+
+	addq	%r12,%r9
+	addq	%r12,%rbx
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rbx
+
+	movq	0(%rsp),%r13
+	movq	104(%rsp),%r14
+	movq	%r13,%r12
+	movq	%r14,%r15
+
+	rorq	$7,%r12
+	xorq	%r13,%r12
+	shrq	$7,%r13
+
+	rorq	$1,%r12
+	xorq	%r12,%r13
+	movq	64(%rsp),%r12
+
+	rorq	$42,%r15
+	xorq	%r14,%r15
+	shrq	$6,%r14
+
+	rorq	$19,%r15
+	addq	%r13,%r12
+	xorq	%r15,%r14
+
+	addq	120(%rsp),%r12
+	movq	%r9,%r13
+	addq	%r14,%r12
+	movq	%rbx,%r14
+	rorq	$23,%r13
+	movq	%r10,%r15
+	movq	%r12,120(%rsp)
+
+	rorq	$5,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r15
+
+	rorq	$4,%r13
+	addq	%rax,%r12
+	xorq	%rbx,%r14
+
+	addq	(%rbp,%rdi,8),%r12
+	andq	%r9,%r15
+	movq	%rcx,%rax
+
+	rorq	$6,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r15
+
+	xorq	%rdx,%rax
+	xorq	%rbx,%r14
+	addq	%r15,%r12
+	movq	%rcx,%r15
+
+	rorq	$14,%r13
+	andq	%rbx,%rax
+	andq	%rdx,%r15
+
+	rorq	$28,%r14
+	addq	%r13,%r12
+	addq	%r15,%rax
+
+	addq	%r12,%r8
+	addq	%r12,%rax
+	leaq	1(%rdi),%rdi
+	addq	%r14,%rax
+
+	cmpq	$80,%rdi
+	jb	L$rounds_16_xx
+
+	movq	128+0(%rsp),%rdi
+	leaq	128(%rsi),%rsi
+
+	addq	0(%rdi),%rax
+	addq	8(%rdi),%rbx
+	addq	16(%rdi),%rcx
+	addq	24(%rdi),%rdx
+	addq	32(%rdi),%r8
+	addq	40(%rdi),%r9
+	addq	48(%rdi),%r10
+	addq	56(%rdi),%r11
+
+	cmpq	128+16(%rsp),%rsi
+
+	movq	%rax,0(%rdi)
+	movq	%rbx,8(%rdi)
+	movq	%rcx,16(%rdi)
+	movq	%rdx,24(%rdi)
+	movq	%r8,32(%rdi)
+	movq	%r9,40(%rdi)
+	movq	%r10,48(%rdi)
+	movq	%r11,56(%rdi)
+	jb	L$loop
+
+	movq	128+24(%rsp),%rsi
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+L$epilogue:
+	.byte	0xf3,0xc3
+
+.p2align	6
+
+K512:
+.quad	0x428a2f98d728ae22,0x7137449123ef65cd
+.quad	0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
+.quad	0x3956c25bf348b538,0x59f111f1b605d019
+.quad	0x923f82a4af194f9b,0xab1c5ed5da6d8118
+.quad	0xd807aa98a3030242,0x12835b0145706fbe
+.quad	0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
+.quad	0x72be5d74f27b896f,0x80deb1fe3b1696b1
+.quad	0x9bdc06a725c71235,0xc19bf174cf692694
+.quad	0xe49b69c19ef14ad2,0xefbe4786384f25e3
+.quad	0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
+.quad	0x2de92c6f592b0275,0x4a7484aa6ea6e483
+.quad	0x5cb0a9dcbd41fbd4,0x76f988da831153b5
+.quad	0x983e5152ee66dfab,0xa831c66d2db43210
+.quad	0xb00327c898fb213f,0xbf597fc7beef0ee4
+.quad	0xc6e00bf33da88fc2,0xd5a79147930aa725
+.quad	0x06ca6351e003826f,0x142929670a0e6e70
+.quad	0x27b70a8546d22ffc,0x2e1b21385c26c926
+.quad	0x4d2c6dfc5ac42aed,0x53380d139d95b3df
+.quad	0x650a73548baf63de,0x766a0abb3c77b2a8
+.quad	0x81c2c92e47edaee6,0x92722c851482353b
+.quad	0xa2bfe8a14cf10364,0xa81a664bbc423001
+.quad	0xc24b8b70d0f89791,0xc76c51a30654be30
+.quad	0xd192e819d6ef5218,0xd69906245565a910
+.quad	0xf40e35855771202a,0x106aa07032bbd1b8
+.quad	0x19a4c116b8d2d0c8,0x1e376c085141ab53
+.quad	0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
+.quad	0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
+.quad	0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
+.quad	0x748f82ee5defb2fc,0x78a5636f43172f60
+.quad	0x84c87814a1f0ab72,0x8cc702081a6439ec
+.quad	0x90befffa23631e28,0xa4506cebde82bde9
+.quad	0xbef9a3f7b2c67915,0xc67178f2e372532b
+.quad	0xca273eceea26619c,0xd186b8c721c0c207
+.quad	0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
+.quad	0x06f067aa72176fba,0x0a637dc5a2c898a6
+.quad	0x113f9804bef90dae,0x1b710b35131c471b
+.quad	0x28db77f523047d84,0x32caab7b40c72493
+.quad	0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
+.quad	0x4cc5d4becb3e42b6,0x597f299cfc657e2a
+.quad	0x5fcb6fab3ad6faec,0x6c44198c4a475817
diff --git a/crypto/libressl/crypto/sha/sha512.c b/crypto/libressl/crypto/sha/sha512.c
new file mode 100644
index 0000000000..e58717cf27
--- /dev/null
+++ b/crypto/libressl/crypto/sha/sha512.c
@@ -0,0 +1,558 @@
+/* $OpenBSD: sha512.c,v 1.13 2014/07/11 08:44:49 jsing Exp $ */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved
+ * according to the OpenSSL license [found in ../../LICENSE].
+ * ====================================================================
+ */
+
+#include 
+
+#include 
+#include 
+
+#include 
+
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512)
+/*
+ * IMPLEMENTATION NOTES.
+ *
+ * As you might have noticed 32-bit hash algorithms:
+ *
+ * - permit SHA_LONG to be wider than 32-bit (case on CRAY);
+ * - optimized versions implement two transform functions: one operating
+ *   on [aligned] data in host byte order and one - on data in input
+ *   stream byte order;
+ * - share common byte-order neutral collector and padding function
+ *   implementations, ../md32_common.h;
+ *
+ * Neither of the above applies to this SHA-512 implementations. Reasons
+ * [in reverse order] are:
+ *
+ * - it's the only 64-bit hash algorithm for the moment of this writing,
+ *   there is no need for common collector/padding implementation [yet];
+ * - by supporting only one transform function [which operates on
+ *   *aligned* data in input stream byte order, big-endian in this case]
+ *   we minimize burden of maintenance in two ways: a) collector/padding
+ *   function is simpler; b) only one transform function to stare at;
+ * - SHA_LONG64 is required to be exactly 64-bit in order to be able to
+ *   apply a number of optimizations to mitigate potential performance
+ *   penalties caused by previous design decision;
+ *
+ * Caveat lector.
+ *
+ * Implementation relies on the fact that "long long" is 64-bit on
+ * both 32- and 64-bit platforms. If some compiler vendor comes up
+ * with 128-bit long long, adjustment to sha.h would be required.
+ * As this implementation relies on 64-bit integer type, it's totally
+ * inappropriate for platforms which don't support it, most notably
+ * 16-bit platforms.
+ *					
+ */
+
+#include 
+#include 
+#include 
+
+#if !defined(__STRICT_ALIGNMENT) || defined(SHA512_ASM)
+#define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
+#endif
+
+int SHA384_Init(SHA512_CTX *c)
+	{
+	c->h[0]=U64(0xcbbb9d5dc1059ed8);
+	c->h[1]=U64(0x629a292a367cd507);
+	c->h[2]=U64(0x9159015a3070dd17);
+	c->h[3]=U64(0x152fecd8f70e5939);
+	c->h[4]=U64(0x67332667ffc00b31);
+	c->h[5]=U64(0x8eb44a8768581511);
+	c->h[6]=U64(0xdb0c2e0d64f98fa7);
+	c->h[7]=U64(0x47b5481dbefa4fa4);
+
+        c->Nl=0;        c->Nh=0;
+        c->num=0;       c->md_len=SHA384_DIGEST_LENGTH;
+        return 1;
+	}
+
+int SHA512_Init(SHA512_CTX *c)
+	{
+	c->h[0]=U64(0x6a09e667f3bcc908);
+	c->h[1]=U64(0xbb67ae8584caa73b);
+	c->h[2]=U64(0x3c6ef372fe94f82b);
+	c->h[3]=U64(0xa54ff53a5f1d36f1);
+	c->h[4]=U64(0x510e527fade682d1);
+	c->h[5]=U64(0x9b05688c2b3e6c1f);
+	c->h[6]=U64(0x1f83d9abfb41bd6b);
+	c->h[7]=U64(0x5be0cd19137e2179);
+
+        c->Nl=0;        c->Nh=0;
+        c->num=0;       c->md_len=SHA512_DIGEST_LENGTH;
+        return 1;
+	}
+
+#ifndef SHA512_ASM
+static
+#endif
+void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num);
+
+int SHA512_Final (unsigned char *md, SHA512_CTX *c)
+	{
+	unsigned char *p=(unsigned char *)c->u.p;
+	size_t n=c->num;
+
+	p[n]=0x80;	/* There always is a room for one */
+	n++;
+	if (n > (sizeof(c->u)-16))
+		memset (p+n,0,sizeof(c->u)-n), n=0,
+		sha512_block_data_order (c,p,1);
+
+	memset (p+n,0,sizeof(c->u)-16-n);
+#if BYTE_ORDER == BIG_ENDIAN
+	c->u.d[SHA_LBLOCK-2] = c->Nh;
+	c->u.d[SHA_LBLOCK-1] = c->Nl;
+#else
+	p[sizeof(c->u)-1]  = (unsigned char)(c->Nl);
+	p[sizeof(c->u)-2]  = (unsigned char)(c->Nl>>8);
+	p[sizeof(c->u)-3]  = (unsigned char)(c->Nl>>16);
+	p[sizeof(c->u)-4]  = (unsigned char)(c->Nl>>24);
+	p[sizeof(c->u)-5]  = (unsigned char)(c->Nl>>32);
+	p[sizeof(c->u)-6]  = (unsigned char)(c->Nl>>40);
+	p[sizeof(c->u)-7]  = (unsigned char)(c->Nl>>48);
+	p[sizeof(c->u)-8]  = (unsigned char)(c->Nl>>56);
+	p[sizeof(c->u)-9]  = (unsigned char)(c->Nh);
+	p[sizeof(c->u)-10] = (unsigned char)(c->Nh>>8);
+	p[sizeof(c->u)-11] = (unsigned char)(c->Nh>>16);
+	p[sizeof(c->u)-12] = (unsigned char)(c->Nh>>24);
+	p[sizeof(c->u)-13] = (unsigned char)(c->Nh>>32);
+	p[sizeof(c->u)-14] = (unsigned char)(c->Nh>>40);
+	p[sizeof(c->u)-15] = (unsigned char)(c->Nh>>48);
+	p[sizeof(c->u)-16] = (unsigned char)(c->Nh>>56);
+#endif
+
+	sha512_block_data_order (c,p,1);
+
+	if (md==0) return 0;
+
+	switch (c->md_len)
+		{
+		/* Let compiler decide if it's appropriate to unroll... */
+		case SHA384_DIGEST_LENGTH:
+			for (n=0;nh[n];
+
+				*(md++)	= (unsigned char)(t>>56);
+				*(md++)	= (unsigned char)(t>>48);
+				*(md++)	= (unsigned char)(t>>40);
+				*(md++)	= (unsigned char)(t>>32);
+				*(md++)	= (unsigned char)(t>>24);
+				*(md++)	= (unsigned char)(t>>16);
+				*(md++)	= (unsigned char)(t>>8);
+				*(md++)	= (unsigned char)(t);
+				}
+			break;
+		case SHA512_DIGEST_LENGTH:
+			for (n=0;nh[n];
+
+				*(md++)	= (unsigned char)(t>>56);
+				*(md++)	= (unsigned char)(t>>48);
+				*(md++)	= (unsigned char)(t>>40);
+				*(md++)	= (unsigned char)(t>>32);
+				*(md++)	= (unsigned char)(t>>24);
+				*(md++)	= (unsigned char)(t>>16);
+				*(md++)	= (unsigned char)(t>>8);
+				*(md++)	= (unsigned char)(t);
+				}
+			break;
+		/* ... as well as make sure md_len is not abused. */
+		default:	return 0;
+		}
+
+	return 1;
+	}
+
+int SHA384_Final (unsigned char *md,SHA512_CTX *c)
+{   return SHA512_Final (md,c);   }
+
+int SHA512_Update (SHA512_CTX *c, const void *_data, size_t len)
+	{
+	SHA_LONG64	l;
+	unsigned char  *p=c->u.p;
+	const unsigned char *data=(const unsigned char *)_data;
+
+	if (len==0) return  1;
+
+	l = (c->Nl+(((SHA_LONG64)len)<<3))&U64(0xffffffffffffffff);
+	if (l < c->Nl)		c->Nh++;
+	if (sizeof(len)>=8)	c->Nh+=(((SHA_LONG64)len)>>61);
+	c->Nl=l;
+
+	if (c->num != 0)
+		{
+		size_t n = sizeof(c->u) - c->num;
+
+		if (len < n)
+			{
+			memcpy (p+c->num,data,len), c->num += (unsigned int)len;
+			return 1;
+			}
+		else	{
+			memcpy (p+c->num,data,n), c->num = 0;
+			len-=n, data+=n;
+			sha512_block_data_order (c,p,1);
+			}
+		}
+
+	if (len >= sizeof(c->u))
+		{
+#ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
+		if ((size_t)data%sizeof(c->u.d[0]) != 0)
+			while (len >= sizeof(c->u))
+				memcpy (p,data,sizeof(c->u)),
+				sha512_block_data_order (c,p,1),
+				len  -= sizeof(c->u),
+				data += sizeof(c->u);
+		else
+#endif
+			sha512_block_data_order (c,data,len/sizeof(c->u)),
+			data += len,
+			len  %= sizeof(c->u),
+			data -= len;
+		}
+
+	if (len != 0)	memcpy (p,data,len), c->num = (int)len;
+
+	return 1;
+	}
+
+int SHA384_Update (SHA512_CTX *c, const void *data, size_t len)
+{   return SHA512_Update (c,data,len);   }
+
+void SHA512_Transform (SHA512_CTX *c, const unsigned char *data)
+	{
+#ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
+	if ((size_t)data%sizeof(c->u.d[0]) != 0)
+		memcpy(c->u.p,data,sizeof(c->u.p)),
+		data = c->u.p;
+#endif
+	sha512_block_data_order (c,data,1);
+	}
+
+unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md)
+	{
+	SHA512_CTX c;
+	static unsigned char m[SHA384_DIGEST_LENGTH];
+
+	if (md == NULL) md=m;
+	SHA384_Init(&c);
+	SHA512_Update(&c,d,n);
+	SHA512_Final(md,&c);
+	explicit_bzero(&c,sizeof(c));
+	return(md);
+	}
+
+unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md)
+	{
+	SHA512_CTX c;
+	static unsigned char m[SHA512_DIGEST_LENGTH];
+
+	if (md == NULL) md=m;
+	SHA512_Init(&c);
+	SHA512_Update(&c,d,n);
+	SHA512_Final(md,&c);
+	explicit_bzero(&c,sizeof(c));
+	return(md);
+	}
+
+#ifndef SHA512_ASM
+static const SHA_LONG64 K512[80] = {
+        U64(0x428a2f98d728ae22),U64(0x7137449123ef65cd),
+        U64(0xb5c0fbcfec4d3b2f),U64(0xe9b5dba58189dbbc),
+        U64(0x3956c25bf348b538),U64(0x59f111f1b605d019),
+        U64(0x923f82a4af194f9b),U64(0xab1c5ed5da6d8118),
+        U64(0xd807aa98a3030242),U64(0x12835b0145706fbe),
+        U64(0x243185be4ee4b28c),U64(0x550c7dc3d5ffb4e2),
+        U64(0x72be5d74f27b896f),U64(0x80deb1fe3b1696b1),
+        U64(0x9bdc06a725c71235),U64(0xc19bf174cf692694),
+        U64(0xe49b69c19ef14ad2),U64(0xefbe4786384f25e3),
+        U64(0x0fc19dc68b8cd5b5),U64(0x240ca1cc77ac9c65),
+        U64(0x2de92c6f592b0275),U64(0x4a7484aa6ea6e483),
+        U64(0x5cb0a9dcbd41fbd4),U64(0x76f988da831153b5),
+        U64(0x983e5152ee66dfab),U64(0xa831c66d2db43210),
+        U64(0xb00327c898fb213f),U64(0xbf597fc7beef0ee4),
+        U64(0xc6e00bf33da88fc2),U64(0xd5a79147930aa725),
+        U64(0x06ca6351e003826f),U64(0x142929670a0e6e70),
+        U64(0x27b70a8546d22ffc),U64(0x2e1b21385c26c926),
+        U64(0x4d2c6dfc5ac42aed),U64(0x53380d139d95b3df),
+        U64(0x650a73548baf63de),U64(0x766a0abb3c77b2a8),
+        U64(0x81c2c92e47edaee6),U64(0x92722c851482353b),
+        U64(0xa2bfe8a14cf10364),U64(0xa81a664bbc423001),
+        U64(0xc24b8b70d0f89791),U64(0xc76c51a30654be30),
+        U64(0xd192e819d6ef5218),U64(0xd69906245565a910),
+        U64(0xf40e35855771202a),U64(0x106aa07032bbd1b8),
+        U64(0x19a4c116b8d2d0c8),U64(0x1e376c085141ab53),
+        U64(0x2748774cdf8eeb99),U64(0x34b0bcb5e19b48a8),
+        U64(0x391c0cb3c5c95a63),U64(0x4ed8aa4ae3418acb),
+        U64(0x5b9cca4f7763e373),U64(0x682e6ff3d6b2b8a3),
+        U64(0x748f82ee5defb2fc),U64(0x78a5636f43172f60),
+        U64(0x84c87814a1f0ab72),U64(0x8cc702081a6439ec),
+        U64(0x90befffa23631e28),U64(0xa4506cebde82bde9),
+        U64(0xbef9a3f7b2c67915),U64(0xc67178f2e372532b),
+        U64(0xca273eceea26619c),U64(0xd186b8c721c0c207),
+        U64(0xeada7dd6cde0eb1e),U64(0xf57d4f7fee6ed178),
+        U64(0x06f067aa72176fba),U64(0x0a637dc5a2c898a6),
+        U64(0x113f9804bef90dae),U64(0x1b710b35131c471b),
+        U64(0x28db77f523047d84),U64(0x32caab7b40c72493),
+        U64(0x3c9ebe0a15c9bebc),U64(0x431d67c49c100d4c),
+        U64(0x4cc5d4becb3e42b6),U64(0x597f299cfc657e2a),
+        U64(0x5fcb6fab3ad6faec),U64(0x6c44198c4a475817) };
+
+#if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+# if defined(__x86_64) || defined(__x86_64__)
+#  define ROTR(a,n)	({ SHA_LONG64 ret;		\
+				asm ("rorq %1,%0"	\
+				: "=r"(ret)		\
+				: "J"(n),"0"(a)		\
+				: "cc"); ret;		})
+#   define PULL64(x) ({ SHA_LONG64 ret=*((const SHA_LONG64 *)(&(x)));	\
+				asm ("bswapq	%0"		\
+				: "=r"(ret)			\
+				: "0"(ret)); ret;		})
+# elif (defined(__i386) || defined(__i386__))
+#  if defined(I386_ONLY)
+#   define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\
+			 unsigned int hi=p[0],lo=p[1];		\
+				asm("xchgb %%ah,%%al;xchgb %%dh,%%dl;"\
+				    "roll $16,%%eax; roll $16,%%edx; "\
+				    "xchgb %%ah,%%al;xchgb %%dh,%%dl;" \
+				: "=a"(lo),"=d"(hi)		\
+				: "0"(lo),"1"(hi) : "cc");	\
+				((SHA_LONG64)hi)<<32|lo;	})
+#  else
+#   define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\
+			 unsigned int hi=p[0],lo=p[1];		\
+				asm ("bswapl %0; bswapl %1;"	\
+				: "=r"(lo),"=r"(hi)		\
+				: "0"(lo),"1"(hi));		\
+				((SHA_LONG64)hi)<<32|lo;	})
+#  endif
+# elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64)
+#  define ROTR(a,n)	({ SHA_LONG64 ret;		\
+				asm ("rotrdi %0,%1,%2"	\
+				: "=r"(ret)		\
+				: "r"(a),"K"(n)); ret;	})
+# endif
+#endif
+
+#ifndef PULL64
+#define B(x,j)    (((SHA_LONG64)(*(((const unsigned char *)(&x))+j)))<<((7-j)*8))
+#define PULL64(x) (B(x,0)|B(x,1)|B(x,2)|B(x,3)|B(x,4)|B(x,5)|B(x,6)|B(x,7))
+#endif
+
+#ifndef ROTR
+#define ROTR(x,s)	(((x)>>s) | (x)<<(64-s))
+#endif
+
+#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)  ^ ((x)>>7))
+#define sigma1(x)	(ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
+
+#define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z)))
+#define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+
+#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
+/*
+ * This code should give better results on 32-bit CPU with less than
+ * ~24 registers, both size and performance wise...
+ */
+static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num)
+	{
+	const SHA_LONG64 *W=in;
+	SHA_LONG64	A,E,T;
+	SHA_LONG64	X[9+80],*F;
+	int i;
+
+			while (num--) {
+
+	F    = X+80;
+	A    = ctx->h[0];	F[1] = ctx->h[1];
+	F[2] = ctx->h[2];	F[3] = ctx->h[3];
+	E    = ctx->h[4];	F[5] = ctx->h[5];
+	F[6] = ctx->h[6];	F[7] = ctx->h[7];
+
+	for (i=0;i<16;i++,F--)
+		{
+		T = PULL64(W[i]);
+		F[0] = A;
+		F[4] = E;
+		F[8] = T;
+		T   += F[7] + Sigma1(E) + Ch(E,F[5],F[6]) + K512[i];
+		E    = F[3] + T;
+		A    = T + Sigma0(A) + Maj(A,F[1],F[2]);
+		}
+
+	for (;i<80;i++,F--)
+		{
+		T    = sigma0(F[8+16-1]);
+		T   += sigma1(F[8+16-14]);
+		T   += F[8+16] + F[8+16-9];
+
+		F[0] = A;
+		F[4] = E;
+		F[8] = T;
+		T   += F[7] + Sigma1(E) + Ch(E,F[5],F[6]) + K512[i];
+		E    = F[3] + T;
+		A    = T + Sigma0(A) + Maj(A,F[1],F[2]);
+		}
+
+	ctx->h[0] += A;		ctx->h[1] += F[1];
+	ctx->h[2] += F[2];	ctx->h[3] += F[3];
+	ctx->h[4] += E;		ctx->h[5] += F[5];
+	ctx->h[6] += F[6];	ctx->h[7] += F[7];
+
+			W+=SHA_LBLOCK;
+			}
+	}
+
+#elif defined(OPENSSL_SMALL_FOOTPRINT)
+
+static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num)
+	{
+	const SHA_LONG64 *W=in;
+	SHA_LONG64	a,b,c,d,e,f,g,h,s0,s1,T1,T2;
+	SHA_LONG64	X[16];
+	int i;
+
+			while (num--) {
+
+	a = ctx->h[0];	b = ctx->h[1];	c = ctx->h[2];	d = ctx->h[3];
+	e = ctx->h[4];	f = ctx->h[5];	g = ctx->h[6];	h = ctx->h[7];
+
+	for (i=0;i<16;i++)
+		{
+#if BYTE_ORDER == BIG_ENDIAN
+		T1 = X[i] = W[i];
+#else
+		T1 = X[i] = PULL64(W[i]);
+#endif
+		T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i];
+		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;
+		}
+
+	for (;i<80;i++)
+		{
+		s0 = X[(i+1)&0x0f];	s0 = sigma0(s0);
+		s1 = X[(i+14)&0x0f];	s1 = sigma1(s1);
+
+		T1 = X[i&0xf] += s0 + s1 + X[(i+9)&0xf];
+		T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i];
+		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;
+		}
+
+	ctx->h[0] += a;	ctx->h[1] += b;	ctx->h[2] += c;	ctx->h[3] += d;
+	ctx->h[4] += e;	ctx->h[5] += f;	ctx->h[6] += g;	ctx->h[7] += h;
+
+			W+=SHA_LBLOCK;
+			}
+	}
+
+#else
+
+#define	ROUND_00_15(i,a,b,c,d,e,f,g,h)		do {	\
+	T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i];	\
+	h = Sigma0(a) + Maj(a,b,c);			\
+	d += T1;	h += T1;		} while (0)
+
+#define	ROUND_16_80(i,j,a,b,c,d,e,f,g,h,X)	do {	\
+	s0 = X[(j+1)&0x0f];	s0 = sigma0(s0);	\
+	s1 = X[(j+14)&0x0f];	s1 = sigma1(s1);	\
+	T1 = X[(j)&0x0f] += s0 + s1 + X[(j+9)&0x0f];	\
+	ROUND_00_15(i+j,a,b,c,d,e,f,g,h);		} while (0)
+
+static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num)
+	{
+	const SHA_LONG64 *W=in;
+	SHA_LONG64	a,b,c,d,e,f,g,h,s0,s1,T1;
+	SHA_LONG64	X[16];
+	int i;
+
+			while (num--) {
+
+	a = ctx->h[0];	b = ctx->h[1];	c = ctx->h[2];	d = ctx->h[3];
+	e = ctx->h[4];	f = ctx->h[5];	g = ctx->h[6];	h = ctx->h[7];
+
+#if BYTE_ORDER == BIG_ENDIAN
+	T1 = X[0] = W[0];	ROUND_00_15(0,a,b,c,d,e,f,g,h);
+	T1 = X[1] = W[1];	ROUND_00_15(1,h,a,b,c,d,e,f,g);
+	T1 = X[2] = W[2];	ROUND_00_15(2,g,h,a,b,c,d,e,f);
+	T1 = X[3] = W[3];	ROUND_00_15(3,f,g,h,a,b,c,d,e);
+	T1 = X[4] = W[4];	ROUND_00_15(4,e,f,g,h,a,b,c,d);
+	T1 = X[5] = W[5];	ROUND_00_15(5,d,e,f,g,h,a,b,c);
+	T1 = X[6] = W[6];	ROUND_00_15(6,c,d,e,f,g,h,a,b);
+	T1 = X[7] = W[7];	ROUND_00_15(7,b,c,d,e,f,g,h,a);
+	T1 = X[8] = W[8];	ROUND_00_15(8,a,b,c,d,e,f,g,h);
+	T1 = X[9] = W[9];	ROUND_00_15(9,h,a,b,c,d,e,f,g);
+	T1 = X[10] = W[10];	ROUND_00_15(10,g,h,a,b,c,d,e,f);
+	T1 = X[11] = W[11];	ROUND_00_15(11,f,g,h,a,b,c,d,e);
+	T1 = X[12] = W[12];	ROUND_00_15(12,e,f,g,h,a,b,c,d);
+	T1 = X[13] = W[13];	ROUND_00_15(13,d,e,f,g,h,a,b,c);
+	T1 = X[14] = W[14];	ROUND_00_15(14,c,d,e,f,g,h,a,b);
+	T1 = X[15] = W[15];	ROUND_00_15(15,b,c,d,e,f,g,h,a);
+#else
+	T1 = X[0]  = PULL64(W[0]);	ROUND_00_15(0,a,b,c,d,e,f,g,h);
+	T1 = X[1]  = PULL64(W[1]);	ROUND_00_15(1,h,a,b,c,d,e,f,g);
+	T1 = X[2]  = PULL64(W[2]);	ROUND_00_15(2,g,h,a,b,c,d,e,f);
+	T1 = X[3]  = PULL64(W[3]);	ROUND_00_15(3,f,g,h,a,b,c,d,e);
+	T1 = X[4]  = PULL64(W[4]);	ROUND_00_15(4,e,f,g,h,a,b,c,d);
+	T1 = X[5]  = PULL64(W[5]);	ROUND_00_15(5,d,e,f,g,h,a,b,c);
+	T1 = X[6]  = PULL64(W[6]);	ROUND_00_15(6,c,d,e,f,g,h,a,b);
+	T1 = X[7]  = PULL64(W[7]);	ROUND_00_15(7,b,c,d,e,f,g,h,a);
+	T1 = X[8]  = PULL64(W[8]);	ROUND_00_15(8,a,b,c,d,e,f,g,h);
+	T1 = X[9]  = PULL64(W[9]);	ROUND_00_15(9,h,a,b,c,d,e,f,g);
+	T1 = X[10] = PULL64(W[10]);	ROUND_00_15(10,g,h,a,b,c,d,e,f);
+	T1 = X[11] = PULL64(W[11]);	ROUND_00_15(11,f,g,h,a,b,c,d,e);
+	T1 = X[12] = PULL64(W[12]);	ROUND_00_15(12,e,f,g,h,a,b,c,d);
+	T1 = X[13] = PULL64(W[13]);	ROUND_00_15(13,d,e,f,g,h,a,b,c);
+	T1 = X[14] = PULL64(W[14]);	ROUND_00_15(14,c,d,e,f,g,h,a,b);
+	T1 = X[15] = PULL64(W[15]);	ROUND_00_15(15,b,c,d,e,f,g,h,a);
+#endif
+
+	for (i=16;i<80;i+=16)
+		{
+		ROUND_16_80(i, 0,a,b,c,d,e,f,g,h,X);
+		ROUND_16_80(i, 1,h,a,b,c,d,e,f,g,X);
+		ROUND_16_80(i, 2,g,h,a,b,c,d,e,f,X);
+		ROUND_16_80(i, 3,f,g,h,a,b,c,d,e,X);
+		ROUND_16_80(i, 4,e,f,g,h,a,b,c,d,X);
+		ROUND_16_80(i, 5,d,e,f,g,h,a,b,c,X);
+		ROUND_16_80(i, 6,c,d,e,f,g,h,a,b,X);
+		ROUND_16_80(i, 7,b,c,d,e,f,g,h,a,X);
+		ROUND_16_80(i, 8,a,b,c,d,e,f,g,h,X);
+		ROUND_16_80(i, 9,h,a,b,c,d,e,f,g,X);
+		ROUND_16_80(i,10,g,h,a,b,c,d,e,f,X);
+		ROUND_16_80(i,11,f,g,h,a,b,c,d,e,X);
+		ROUND_16_80(i,12,e,f,g,h,a,b,c,d,X);
+		ROUND_16_80(i,13,d,e,f,g,h,a,b,c,X);
+		ROUND_16_80(i,14,c,d,e,f,g,h,a,b,X);
+		ROUND_16_80(i,15,b,c,d,e,f,g,h,a,X);
+		}
+
+	ctx->h[0] += a;	ctx->h[1] += b;	ctx->h[2] += c;	ctx->h[3] += d;
+	ctx->h[4] += e;	ctx->h[5] += f;	ctx->h[6] += g;	ctx->h[7] += h;
+
+			W+=SHA_LBLOCK;
+			}
+	}
+
+#endif
+
+#endif /* SHA512_ASM */
+
+#endif /* !OPENSSL_NO_SHA512 */
diff --git a/crypto/libressl/crypto/sha/sha_locl.h b/crypto/libressl/crypto/sha/sha_locl.h
new file mode 100644
index 0000000000..6bb37ae239
--- /dev/null
+++ b/crypto/libressl/crypto/sha/sha_locl.h
@@ -0,0 +1,414 @@
+/* $OpenBSD: sha_locl.h,v 1.20 2015/09/13 21:09:56 doug Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+
+#define DATA_ORDER_IS_BIG_ENDIAN
+
+#define HASH_LONG               SHA_LONG
+#define HASH_CTX                SHA_CTX
+#define HASH_CBLOCK             SHA_CBLOCK
+#define HASH_MAKE_STRING(c,s)   do {	\
+	unsigned long ll;		\
+	ll=(c)->h0; HOST_l2c(ll,(s));	\
+	ll=(c)->h1; HOST_l2c(ll,(s));	\
+	ll=(c)->h2; HOST_l2c(ll,(s));	\
+	ll=(c)->h3; HOST_l2c(ll,(s));	\
+	ll=(c)->h4; HOST_l2c(ll,(s));	\
+	} while (0)
+
+# define HASH_UPDATE             	SHA1_Update
+# define HASH_TRANSFORM          	SHA1_Transform
+# define HASH_FINAL              	SHA1_Final
+# define HASH_INIT			SHA1_Init
+# define HASH_BLOCK_DATA_ORDER   	sha1_block_data_order
+# define Xupdate(a,ix,ia,ib,ic,id)	( (a)=(ia^ib^ic^id),	\
+					  ix=(a)=ROTATE((a),1)	\
+					)
+
+#ifndef SHA1_ASM
+static
+#endif
+void sha1_block_data_order (SHA_CTX *c, const void *p,size_t num);
+
+#include "md32_common.h"
+
+#define INIT_DATA_h0 0x67452301UL
+#define INIT_DATA_h1 0xefcdab89UL
+#define INIT_DATA_h2 0x98badcfeUL
+#define INIT_DATA_h3 0x10325476UL
+#define INIT_DATA_h4 0xc3d2e1f0UL
+
+int SHA1_Init(SHA_CTX *c)
+	{
+	memset (c,0,sizeof(*c));
+	c->h0=INIT_DATA_h0;
+	c->h1=INIT_DATA_h1;
+	c->h2=INIT_DATA_h2;
+	c->h3=INIT_DATA_h3;
+	c->h4=INIT_DATA_h4;
+	return 1;
+	}
+
+#define K_00_19	0x5a827999UL
+#define K_20_39 0x6ed9eba1UL
+#define K_40_59 0x8f1bbcdcUL
+#define K_60_79 0xca62c1d6UL
+
+/* As  pointed out by Wei Dai , F() below can be
+ * simplified to the code in F_00_19.  Wei attributes these optimisations
+ * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
+ * #define F(x,y,z) (((x) & (y))  |  ((~(x)) & (z)))
+ * I've just become aware of another tweak to be made, again from Wei Dai,
+ * in F_40_59, (x&a)|(y&a) -> (x|y)&a
+ */
+#define	F_00_19(b,c,d)	((((c) ^ (d)) & (b)) ^ (d)) 
+#define	F_20_39(b,c,d)	((b) ^ (c) ^ (d))
+#define F_40_59(b,c,d)	(((b) & (c)) | (((b)|(c)) & (d))) 
+#define	F_60_79(b,c,d)	F_20_39(b,c,d)
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+
+#define BODY_00_15(i,a,b,c,d,e,f,xi) \
+	(f)=xi+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#define BODY_16_19(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
+	Xupdate(f,xi,xa,xb,xc,xd); \
+	(f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#define BODY_20_31(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
+	Xupdate(f,xi,xa,xb,xc,xd); \
+	(f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#define BODY_32_39(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+	Xupdate(f,xa,xa,xb,xc,xd); \
+	(f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#define BODY_40_59(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+	Xupdate(f,xa,xa,xb,xc,xd); \
+	(f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#define BODY_60_79(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+	Xupdate(f,xa,xa,xb,xc,xd); \
+	(f)=xa+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#ifdef X
+#undef X
+#endif
+#ifndef MD32_XARRAY
+  /*
+   * Originally X was an array. As it's automatic it's natural
+   * to expect RISC compiler to accommodate at least part of it in
+   * the register bank, isn't it? Unfortunately not all compilers
+   * "find" this expectation reasonable:-( On order to make such
+   * compilers generate better code I replace X[] with a bunch of
+   * X0, X1, etc. See the function body below...
+   *					
+   */
+# define X(i)	XX##i
+#else
+  /*
+   * However! Some compilers (most notably HP C) get overwhelmed by
+   * that many local variables so that we have to have the way to
+   * fall down to the original behavior.
+   */
+# define X(i)	XX[i]
+#endif
+
+#if !defined(SHA1_ASM)
+#include 
+static void HASH_BLOCK_DATA_ORDER (SHA_CTX *c, const void *p, size_t num)
+	{
+	const unsigned char *data=p;
+	unsigned MD32_REG_T A,B,C,D,E,T,l;
+#ifndef MD32_XARRAY
+	unsigned MD32_REG_T	XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+				XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
+#else
+	SHA_LONG	XX[16];
+#endif
+
+	A=c->h0;
+	B=c->h1;
+	C=c->h2;
+	D=c->h3;
+	E=c->h4;
+
+	for (;;)
+			{
+
+	if (BYTE_ORDER != LITTLE_ENDIAN &&
+	    sizeof(SHA_LONG)==4 && ((size_t)p%4)==0)
+		{
+		const SHA_LONG *W=(const SHA_LONG *)data;
+
+		X( 0) = W[0];				X( 1) = W[ 1];
+		BODY_00_15( 0,A,B,C,D,E,T,X( 0));	X( 2) = W[ 2];
+		BODY_00_15( 1,T,A,B,C,D,E,X( 1));	X( 3) = W[ 3];
+		BODY_00_15( 2,E,T,A,B,C,D,X( 2));	X( 4) = W[ 4];
+		BODY_00_15( 3,D,E,T,A,B,C,X( 3));	X( 5) = W[ 5];
+		BODY_00_15( 4,C,D,E,T,A,B,X( 4));	X( 6) = W[ 6];
+		BODY_00_15( 5,B,C,D,E,T,A,X( 5));	X( 7) = W[ 7];
+		BODY_00_15( 6,A,B,C,D,E,T,X( 6));	X( 8) = W[ 8];
+		BODY_00_15( 7,T,A,B,C,D,E,X( 7));	X( 9) = W[ 9];
+		BODY_00_15( 8,E,T,A,B,C,D,X( 8));	X(10) = W[10];
+		BODY_00_15( 9,D,E,T,A,B,C,X( 9));	X(11) = W[11];
+		BODY_00_15(10,C,D,E,T,A,B,X(10));	X(12) = W[12];
+		BODY_00_15(11,B,C,D,E,T,A,X(11));	X(13) = W[13];
+		BODY_00_15(12,A,B,C,D,E,T,X(12));	X(14) = W[14];
+		BODY_00_15(13,T,A,B,C,D,E,X(13));	X(15) = W[15];
+		BODY_00_15(14,E,T,A,B,C,D,X(14));
+		BODY_00_15(15,D,E,T,A,B,C,X(15));
+
+		data += SHA_CBLOCK;
+		}
+	else
+		{
+		HOST_c2l(data,l); X( 0)=l;		HOST_c2l(data,l); X( 1)=l;
+		BODY_00_15( 0,A,B,C,D,E,T,X( 0));	HOST_c2l(data,l); X( 2)=l;
+		BODY_00_15( 1,T,A,B,C,D,E,X( 1));	HOST_c2l(data,l); X( 3)=l;
+		BODY_00_15( 2,E,T,A,B,C,D,X( 2));	HOST_c2l(data,l); X( 4)=l;
+		BODY_00_15( 3,D,E,T,A,B,C,X( 3));	HOST_c2l(data,l); X( 5)=l;
+		BODY_00_15( 4,C,D,E,T,A,B,X( 4));	HOST_c2l(data,l); X( 6)=l;
+		BODY_00_15( 5,B,C,D,E,T,A,X( 5));	HOST_c2l(data,l); X( 7)=l;
+		BODY_00_15( 6,A,B,C,D,E,T,X( 6));	HOST_c2l(data,l); X( 8)=l;
+		BODY_00_15( 7,T,A,B,C,D,E,X( 7));	HOST_c2l(data,l); X( 9)=l;
+		BODY_00_15( 8,E,T,A,B,C,D,X( 8));	HOST_c2l(data,l); X(10)=l;
+		BODY_00_15( 9,D,E,T,A,B,C,X( 9));	HOST_c2l(data,l); X(11)=l;
+		BODY_00_15(10,C,D,E,T,A,B,X(10));	HOST_c2l(data,l); X(12)=l;
+		BODY_00_15(11,B,C,D,E,T,A,X(11));	HOST_c2l(data,l); X(13)=l;
+		BODY_00_15(12,A,B,C,D,E,T,X(12));	HOST_c2l(data,l); X(14)=l;
+		BODY_00_15(13,T,A,B,C,D,E,X(13));	HOST_c2l(data,l); X(15)=l;
+		BODY_00_15(14,E,T,A,B,C,D,X(14));
+		BODY_00_15(15,D,E,T,A,B,C,X(15));
+		}
+
+	BODY_16_19(16,C,D,E,T,A,B,X( 0),X( 0),X( 2),X( 8),X(13));
+	BODY_16_19(17,B,C,D,E,T,A,X( 1),X( 1),X( 3),X( 9),X(14));
+	BODY_16_19(18,A,B,C,D,E,T,X( 2),X( 2),X( 4),X(10),X(15));
+	BODY_16_19(19,T,A,B,C,D,E,X( 3),X( 3),X( 5),X(11),X( 0));
+
+	BODY_20_31(20,E,T,A,B,C,D,X( 4),X( 4),X( 6),X(12),X( 1));
+	BODY_20_31(21,D,E,T,A,B,C,X( 5),X( 5),X( 7),X(13),X( 2));
+	BODY_20_31(22,C,D,E,T,A,B,X( 6),X( 6),X( 8),X(14),X( 3));
+	BODY_20_31(23,B,C,D,E,T,A,X( 7),X( 7),X( 9),X(15),X( 4));
+	BODY_20_31(24,A,B,C,D,E,T,X( 8),X( 8),X(10),X( 0),X( 5));
+	BODY_20_31(25,T,A,B,C,D,E,X( 9),X( 9),X(11),X( 1),X( 6));
+	BODY_20_31(26,E,T,A,B,C,D,X(10),X(10),X(12),X( 2),X( 7));
+	BODY_20_31(27,D,E,T,A,B,C,X(11),X(11),X(13),X( 3),X( 8));
+	BODY_20_31(28,C,D,E,T,A,B,X(12),X(12),X(14),X( 4),X( 9));
+	BODY_20_31(29,B,C,D,E,T,A,X(13),X(13),X(15),X( 5),X(10));
+	BODY_20_31(30,A,B,C,D,E,T,X(14),X(14),X( 0),X( 6),X(11));
+	BODY_20_31(31,T,A,B,C,D,E,X(15),X(15),X( 1),X( 7),X(12));
+
+	BODY_32_39(32,E,T,A,B,C,D,X( 0),X( 2),X( 8),X(13));
+	BODY_32_39(33,D,E,T,A,B,C,X( 1),X( 3),X( 9),X(14));
+	BODY_32_39(34,C,D,E,T,A,B,X( 2),X( 4),X(10),X(15));
+	BODY_32_39(35,B,C,D,E,T,A,X( 3),X( 5),X(11),X( 0));
+	BODY_32_39(36,A,B,C,D,E,T,X( 4),X( 6),X(12),X( 1));
+	BODY_32_39(37,T,A,B,C,D,E,X( 5),X( 7),X(13),X( 2));
+	BODY_32_39(38,E,T,A,B,C,D,X( 6),X( 8),X(14),X( 3));
+	BODY_32_39(39,D,E,T,A,B,C,X( 7),X( 9),X(15),X( 4));
+
+	BODY_40_59(40,C,D,E,T,A,B,X( 8),X(10),X( 0),X( 5));
+	BODY_40_59(41,B,C,D,E,T,A,X( 9),X(11),X( 1),X( 6));
+	BODY_40_59(42,A,B,C,D,E,T,X(10),X(12),X( 2),X( 7));
+	BODY_40_59(43,T,A,B,C,D,E,X(11),X(13),X( 3),X( 8));
+	BODY_40_59(44,E,T,A,B,C,D,X(12),X(14),X( 4),X( 9));
+	BODY_40_59(45,D,E,T,A,B,C,X(13),X(15),X( 5),X(10));
+	BODY_40_59(46,C,D,E,T,A,B,X(14),X( 0),X( 6),X(11));
+	BODY_40_59(47,B,C,D,E,T,A,X(15),X( 1),X( 7),X(12));
+	BODY_40_59(48,A,B,C,D,E,T,X( 0),X( 2),X( 8),X(13));
+	BODY_40_59(49,T,A,B,C,D,E,X( 1),X( 3),X( 9),X(14));
+	BODY_40_59(50,E,T,A,B,C,D,X( 2),X( 4),X(10),X(15));
+	BODY_40_59(51,D,E,T,A,B,C,X( 3),X( 5),X(11),X( 0));
+	BODY_40_59(52,C,D,E,T,A,B,X( 4),X( 6),X(12),X( 1));
+	BODY_40_59(53,B,C,D,E,T,A,X( 5),X( 7),X(13),X( 2));
+	BODY_40_59(54,A,B,C,D,E,T,X( 6),X( 8),X(14),X( 3));
+	BODY_40_59(55,T,A,B,C,D,E,X( 7),X( 9),X(15),X( 4));
+	BODY_40_59(56,E,T,A,B,C,D,X( 8),X(10),X( 0),X( 5));
+	BODY_40_59(57,D,E,T,A,B,C,X( 9),X(11),X( 1),X( 6));
+	BODY_40_59(58,C,D,E,T,A,B,X(10),X(12),X( 2),X( 7));
+	BODY_40_59(59,B,C,D,E,T,A,X(11),X(13),X( 3),X( 8));
+
+	BODY_60_79(60,A,B,C,D,E,T,X(12),X(14),X( 4),X( 9));
+	BODY_60_79(61,T,A,B,C,D,E,X(13),X(15),X( 5),X(10));
+	BODY_60_79(62,E,T,A,B,C,D,X(14),X( 0),X( 6),X(11));
+	BODY_60_79(63,D,E,T,A,B,C,X(15),X( 1),X( 7),X(12));
+	BODY_60_79(64,C,D,E,T,A,B,X( 0),X( 2),X( 8),X(13));
+	BODY_60_79(65,B,C,D,E,T,A,X( 1),X( 3),X( 9),X(14));
+	BODY_60_79(66,A,B,C,D,E,T,X( 2),X( 4),X(10),X(15));
+	BODY_60_79(67,T,A,B,C,D,E,X( 3),X( 5),X(11),X( 0));
+	BODY_60_79(68,E,T,A,B,C,D,X( 4),X( 6),X(12),X( 1));
+	BODY_60_79(69,D,E,T,A,B,C,X( 5),X( 7),X(13),X( 2));
+	BODY_60_79(70,C,D,E,T,A,B,X( 6),X( 8),X(14),X( 3));
+	BODY_60_79(71,B,C,D,E,T,A,X( 7),X( 9),X(15),X( 4));
+	BODY_60_79(72,A,B,C,D,E,T,X( 8),X(10),X( 0),X( 5));
+	BODY_60_79(73,T,A,B,C,D,E,X( 9),X(11),X( 1),X( 6));
+	BODY_60_79(74,E,T,A,B,C,D,X(10),X(12),X( 2),X( 7));
+	BODY_60_79(75,D,E,T,A,B,C,X(11),X(13),X( 3),X( 8));
+	BODY_60_79(76,C,D,E,T,A,B,X(12),X(14),X( 4),X( 9));
+	BODY_60_79(77,B,C,D,E,T,A,X(13),X(15),X( 5),X(10));
+	BODY_60_79(78,A,B,C,D,E,T,X(14),X( 0),X( 6),X(11));
+	BODY_60_79(79,T,A,B,C,D,E,X(15),X( 1),X( 7),X(12));
+	
+	c->h0=(c->h0+E)&0xffffffffL; 
+	c->h1=(c->h1+T)&0xffffffffL;
+	c->h2=(c->h2+A)&0xffffffffL;
+	c->h3=(c->h3+B)&0xffffffffL;
+	c->h4=(c->h4+C)&0xffffffffL;
+
+	if (--num == 0) break;
+
+	A=c->h0;
+	B=c->h1;
+	C=c->h2;
+	D=c->h3;
+	E=c->h4;
+
+			}
+	}
+#endif
+
+#else	/* OPENSSL_SMALL_FOOTPRINT */
+
+#define BODY_00_15(xi)		 do {	\
+	T=E+K_00_19+F_00_19(B,C,D);	\
+	E=D, D=C, C=ROTATE(B,30), B=A;	\
+	A=ROTATE(A,5)+T+xi;	    } while(0)
+
+#define BODY_16_19(xa,xb,xc,xd)	 do {	\
+	Xupdate(T,xa,xa,xb,xc,xd);	\
+	T+=E+K_00_19+F_00_19(B,C,D);	\
+	E=D, D=C, C=ROTATE(B,30), B=A;	\
+	A=ROTATE(A,5)+T;	    } while(0)
+
+#define BODY_20_39(xa,xb,xc,xd)	 do {	\
+	Xupdate(T,xa,xa,xb,xc,xd);	\
+	T+=E+K_20_39+F_20_39(B,C,D);	\
+	E=D, D=C, C=ROTATE(B,30), B=A;	\
+	A=ROTATE(A,5)+T;	    } while(0)
+
+#define BODY_40_59(xa,xb,xc,xd)	 do {	\
+	Xupdate(T,xa,xa,xb,xc,xd);	\
+	T+=E+K_40_59+F_40_59(B,C,D);	\
+	E=D, D=C, C=ROTATE(B,30), B=A;	\
+	A=ROTATE(A,5)+T;	    } while(0)
+
+#define BODY_60_79(xa,xb,xc,xd)	 do {	\
+	Xupdate(T,xa,xa,xb,xc,xd);	\
+	T=E+K_60_79+F_60_79(B,C,D);	\
+	E=D, D=C, C=ROTATE(B,30), B=A;	\
+	A=ROTATE(A,5)+T+xa;	    } while(0)
+
+#if !defined(SHA1_ASM)
+static void HASH_BLOCK_DATA_ORDER (SHA_CTX *c, const void *p, size_t num)
+	{
+	const unsigned char *data=p;
+	unsigned MD32_REG_T A,B,C,D,E,T,l;
+	int i;
+	SHA_LONG	X[16];
+
+	A=c->h0;
+	B=c->h1;
+	C=c->h2;
+	D=c->h3;
+	E=c->h4;
+
+	for (;;)
+		{
+	for (i=0;i<16;i++)
+	{ HOST_c2l(data,l); X[i]=l; BODY_00_15(X[i]); }
+	for (i=0;i<4;i++)
+	{ BODY_16_19(X[i],       X[i+2],      X[i+8],     X[(i+13)&15]); }
+	for (;i<24;i++)
+	{ BODY_20_39(X[i&15],    X[(i+2)&15], X[(i+8)&15],X[(i+13)&15]); }
+	for (i=0;i<20;i++)
+	{ BODY_40_59(X[(i+8)&15],X[(i+10)&15],X[i&15],    X[(i+5)&15]);  }
+	for (i=4;i<24;i++)
+	{ BODY_60_79(X[(i+8)&15],X[(i+10)&15],X[i&15],    X[(i+5)&15]);  }
+
+	c->h0=(c->h0+A)&0xffffffffL; 
+	c->h1=(c->h1+B)&0xffffffffL;
+	c->h2=(c->h2+C)&0xffffffffL;
+	c->h3=(c->h3+D)&0xffffffffL;
+	c->h4=(c->h4+E)&0xffffffffL;
+
+	if (--num == 0) break;
+
+	A=c->h0;
+	B=c->h1;
+	C=c->h2;
+	D=c->h3;
+	E=c->h4;
+
+		}
+	}
+#endif
+
+#endif
diff --git a/crypto/libressl/crypto/stack/stack.c b/crypto/libressl/crypto/stack/stack.c
new file mode 100644
index 0000000000..ae980a57ea
--- /dev/null
+++ b/crypto/libressl/crypto/stack/stack.c
@@ -0,0 +1,341 @@
+/* $OpenBSD: stack.c,v 1.18 2014/07/11 08:44:49 jsing Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+
+#undef MIN_NODES
+#define MIN_NODES	4
+
+#include 
+
+int
+(*sk_set_cmp_func(_STACK *sk, int (*c)(const void *, const void *)))(
+    const void *, const void *)
+{
+	int (*old)(const void *, const void *) = sk->comp;
+
+	if (sk->comp != c)
+		sk->sorted = 0;
+	sk->comp = c;
+
+	return old;
+}
+
+_STACK *
+sk_dup(_STACK *sk)
+{
+	_STACK *ret;
+	char **s;
+
+	if ((ret = sk_new(sk->comp)) == NULL)
+		goto err;
+	s = reallocarray(ret->data, sk->num_alloc, sizeof(char *));
+	if (s == NULL)
+		goto err;
+	ret->data = s;
+
+	ret->num = sk->num;
+	memcpy(ret->data, sk->data, sizeof(char *) * sk->num);
+	ret->sorted = sk->sorted;
+	ret->num_alloc = sk->num_alloc;
+	ret->comp = sk->comp;
+	return (ret);
+
+err:
+	if (ret)
+		sk_free(ret);
+	return (NULL);
+}
+
+_STACK *
+sk_new_null(void)
+{
+	return sk_new((int (*)(const void *, const void *))0);
+}
+
+_STACK *
+sk_new(int (*c)(const void *, const void *))
+{
+	_STACK *ret;
+	int i;
+
+	if ((ret = malloc(sizeof(_STACK))) == NULL)
+		goto err;
+	if ((ret->data = reallocarray(NULL, MIN_NODES, sizeof(char *))) == NULL)
+		goto err;
+	for (i = 0; i < MIN_NODES; i++)
+		ret->data[i] = NULL;
+	ret->comp = c;
+	ret->num_alloc = MIN_NODES;
+	ret->num = 0;
+	ret->sorted = 0;
+	return (ret);
+
+err:
+	free(ret);
+	return (NULL);
+}
+
+int
+sk_insert(_STACK *st, void *data, int loc)
+{
+	char **s;
+
+	if (st == NULL)
+		return 0;
+	if (st->num_alloc <= st->num + 1) {
+		s = reallocarray(st->data, st->num_alloc, 2 * sizeof(char *));
+		if (s == NULL)
+			return (0);
+		st->data = s;
+		st->num_alloc *= 2;
+	}
+	if ((loc >= (int)st->num) || (loc < 0))
+		st->data[st->num] = data;
+	else {
+		memmove(&(st->data[loc + 1]), &(st->data[loc]),
+		    sizeof(char *)*(st->num - loc));
+		st->data[loc] = data;
+	}
+	st->num++;
+	st->sorted = 0;
+	return (st->num);
+}
+
+void *
+sk_delete_ptr(_STACK *st, void *p)
+{
+	int i;
+
+	for (i = 0; i < st->num; i++)
+		if (st->data[i] == p)
+			return (sk_delete(st, i));
+	return (NULL);
+}
+
+void *
+sk_delete(_STACK *st, int loc)
+{
+	char *ret;
+
+	if (!st || (loc < 0) || (loc >= st->num))
+		return NULL;
+
+	ret = st->data[loc];
+	if (loc != st->num - 1) {
+		memmove(&(st->data[loc]), &(st->data[loc + 1]),
+		    sizeof(char *)*(st->num - 1 - loc));
+	}
+	st->num--;
+	return (ret);
+}
+
+static int
+internal_find(_STACK *st, void *data, int ret_val_options)
+{
+	const void * const *r;
+	int i;
+
+	if (st == NULL)
+		return -1;
+
+	if (st->comp == NULL) {
+		for (i = 0; i < st->num; i++)
+			if (st->data[i] == data)
+				return (i);
+		return (-1);
+	}
+	sk_sort(st);
+	if (data == NULL)
+		return (-1);
+	r = OBJ_bsearch_ex_(&data, st->data, st->num, sizeof(void *), st->comp,
+	    ret_val_options);
+	if (r == NULL)
+		return (-1);
+	return (int)((char **)r - st->data);
+}
+
+int
+sk_find(_STACK *st, void *data)
+{
+	return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH);
+}
+
+int
+sk_find_ex(_STACK *st, void *data)
+{
+	return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH);
+}
+
+int
+sk_push(_STACK *st, void *data)
+{
+	return (sk_insert(st, data, st->num));
+}
+
+int
+sk_unshift(_STACK *st, void *data)
+{
+	return (sk_insert(st, data, 0));
+}
+
+void *
+sk_shift(_STACK *st)
+{
+	if (st == NULL)
+		return (NULL);
+	if (st->num <= 0)
+		return (NULL);
+	return (sk_delete(st, 0));
+}
+
+void *
+sk_pop(_STACK *st)
+{
+	if (st == NULL)
+		return (NULL);
+	if (st->num <= 0)
+		return (NULL);
+	return (sk_delete(st, st->num - 1));
+}
+
+void
+sk_zero(_STACK *st)
+{
+	if (st == NULL)
+		return;
+	if (st->num <= 0)
+		return;
+	memset(st->data, 0, sizeof(st->data)*st->num);
+	st->num = 0;
+}
+
+void
+sk_pop_free(_STACK *st, void (*func)(void *))
+{
+	int i;
+
+	if (st == NULL)
+		return;
+	for (i = 0; i < st->num; i++)
+		if (st->data[i] != NULL)
+			func(st->data[i]);
+	sk_free(st);
+}
+
+void
+sk_free(_STACK *st)
+{
+	if (st == NULL)
+		return;
+	free(st->data);
+	free(st);
+}
+
+int
+sk_num(const _STACK *st)
+{
+	if (st == NULL)
+		return -1;
+	return st->num;
+}
+
+void *
+sk_value(const _STACK *st, int i)
+{
+	if (!st || (i < 0) || (i >= st->num))
+		return NULL;
+	return st->data[i];
+}
+
+void *
+sk_set(_STACK *st, int i, void *value)
+{
+	if (!st || (i < 0) || (i >= st->num))
+		return NULL;
+	return (st->data[i] = value);
+}
+
+void
+sk_sort(_STACK *st)
+{
+	if (st && !st->sorted) {
+		int (*comp_func)(const void *, const void *);
+
+		/* same comment as in sk_find ... previously st->comp was declared
+		 * as a (void*,void*) callback type, but this made the population
+		 * of the callback pointer illogical - our callbacks compare
+		 * type** with type**, so we leave the casting until absolutely
+		 * necessary (ie. "now"). */
+		comp_func = (int (*)(const void *, const void *))(st->comp);
+		qsort(st->data, st->num, sizeof(char *), comp_func);
+		st->sorted = 1;
+	}
+}
+
+int
+sk_is_sorted(const _STACK *st)
+{
+	if (!st)
+		return 1;
+	return st->sorted;
+}
diff --git a/crypto/libressl/crypto/ts/ts_asn1.c b/crypto/libressl/crypto/ts/ts_asn1.c
new file mode 100644
index 0000000000..8ebc829074
--- /dev/null
+++ b/crypto/libressl/crypto/ts/ts_asn1.c
@@ -0,0 +1,895 @@
+/* $OpenBSD: ts_asn1.c,v 1.8 2015/02/10 05:25:45 jsing Exp $ */
+/* Written by Nils Larsch for the OpenSSL project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+static const ASN1_TEMPLATE TS_MSG_IMPRINT_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(TS_MSG_IMPRINT, hash_algo),
+		.field_name = "hash_algo",
+		.item = &X509_ALGOR_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(TS_MSG_IMPRINT, hashed_msg),
+		.field_name = "hashed_msg",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+};
+
+const ASN1_ITEM TS_MSG_IMPRINT_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = TS_MSG_IMPRINT_seq_tt,
+	.tcount = sizeof(TS_MSG_IMPRINT_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(TS_MSG_IMPRINT),
+	.sname = "TS_MSG_IMPRINT",
+};
+
+
+TS_MSG_IMPRINT *
+d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a, const unsigned char **in, long len)
+{
+	return (TS_MSG_IMPRINT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &TS_MSG_IMPRINT_it);
+}
+
+int
+i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &TS_MSG_IMPRINT_it);
+}
+
+TS_MSG_IMPRINT *
+TS_MSG_IMPRINT_new(void)
+{
+	return (TS_MSG_IMPRINT *)ASN1_item_new(&TS_MSG_IMPRINT_it);
+}
+
+void
+TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &TS_MSG_IMPRINT_it);
+}
+
+TS_MSG_IMPRINT *
+TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *x)
+{
+	return ASN1_item_dup(&TS_MSG_IMPRINT_it, x);
+}
+
+#ifndef OPENSSL_NO_BIO
+TS_MSG_IMPRINT *
+d2i_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT **a)
+{
+	return ASN1_d2i_bio_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new,
+	    d2i_TS_MSG_IMPRINT, bp, a);
+}
+
+int
+i2d_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT *a)
+{
+	return ASN1_i2d_bio_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, bp, a);
+}
+#endif
+
+TS_MSG_IMPRINT *
+d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a)
+{
+	return ASN1_d2i_fp_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new,
+	    d2i_TS_MSG_IMPRINT, fp, a);
+}
+
+int
+i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a)
+{
+	return ASN1_i2d_fp_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, fp, a);
+}
+
+static const ASN1_TEMPLATE TS_REQ_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(TS_REQ, version),
+		.field_name = "version",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(TS_REQ, msg_imprint),
+		.field_name = "msg_imprint",
+		.item = &TS_MSG_IMPRINT_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(TS_REQ, policy_id),
+		.field_name = "policy_id",
+		.item = &ASN1_OBJECT_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(TS_REQ, nonce),
+		.field_name = "nonce",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(TS_REQ, cert_req),
+		.field_name = "cert_req",
+		.item = &ASN1_FBOOLEAN_it,
+	},
+	{
+		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(TS_REQ, extensions),
+		.field_name = "extensions",
+		.item = &X509_EXTENSION_it,
+	},
+};
+
+const ASN1_ITEM TS_REQ_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = TS_REQ_seq_tt,
+	.tcount = sizeof(TS_REQ_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(TS_REQ),
+	.sname = "TS_REQ",
+};
+
+
+TS_REQ *
+d2i_TS_REQ(TS_REQ **a, const unsigned char **in, long len)
+{
+	return (TS_REQ *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &TS_REQ_it);
+}
+
+int
+i2d_TS_REQ(const TS_REQ *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &TS_REQ_it);
+}
+
+TS_REQ *
+TS_REQ_new(void)
+{
+	return (TS_REQ *)ASN1_item_new(&TS_REQ_it);
+}
+
+void
+TS_REQ_free(TS_REQ *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &TS_REQ_it);
+}
+
+TS_REQ *
+TS_REQ_dup(TS_REQ *x)
+{
+	return ASN1_item_dup(&TS_REQ_it, x);
+}
+
+#ifndef OPENSSL_NO_BIO
+TS_REQ *
+d2i_TS_REQ_bio(BIO *bp, TS_REQ **a)
+{
+	return ASN1_d2i_bio_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, bp, a);
+}
+
+int
+i2d_TS_REQ_bio(BIO *bp, TS_REQ *a)
+{
+	return ASN1_i2d_bio_of_const(TS_REQ, i2d_TS_REQ, bp, a);
+}
+#endif
+
+TS_REQ *
+d2i_TS_REQ_fp(FILE *fp, TS_REQ **a)
+{
+	return ASN1_d2i_fp_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, fp, a);
+}
+
+int
+i2d_TS_REQ_fp(FILE *fp, TS_REQ *a)
+{
+	return ASN1_i2d_fp_of_const(TS_REQ, i2d_TS_REQ, fp, a);
+}
+
+static const ASN1_TEMPLATE TS_ACCURACY_seq_tt[] = {
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(TS_ACCURACY, seconds),
+		.field_name = "seconds",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(TS_ACCURACY, millis),
+		.field_name = "millis",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 1,
+		.offset = offsetof(TS_ACCURACY, micros),
+		.field_name = "micros",
+		.item = &ASN1_INTEGER_it,
+	},
+};
+
+const ASN1_ITEM TS_ACCURACY_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = TS_ACCURACY_seq_tt,
+	.tcount = sizeof(TS_ACCURACY_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(TS_ACCURACY),
+	.sname = "TS_ACCURACY",
+};
+
+
+TS_ACCURACY *
+d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **in, long len)
+{
+	return (TS_ACCURACY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &TS_ACCURACY_it);
+}
+
+int
+i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &TS_ACCURACY_it);
+}
+
+TS_ACCURACY *
+TS_ACCURACY_new(void)
+{
+	return (TS_ACCURACY *)ASN1_item_new(&TS_ACCURACY_it);
+}
+
+void
+TS_ACCURACY_free(TS_ACCURACY *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &TS_ACCURACY_it);
+}
+
+TS_ACCURACY *
+TS_ACCURACY_dup(TS_ACCURACY *x)
+{
+	return ASN1_item_dup(&TS_ACCURACY_it, x);
+}
+
+static const ASN1_TEMPLATE TS_TST_INFO_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(TS_TST_INFO, version),
+		.field_name = "version",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(TS_TST_INFO, policy_id),
+		.field_name = "policy_id",
+		.item = &ASN1_OBJECT_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(TS_TST_INFO, msg_imprint),
+		.field_name = "msg_imprint",
+		.item = &TS_MSG_IMPRINT_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(TS_TST_INFO, serial),
+		.field_name = "serial",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(TS_TST_INFO, time),
+		.field_name = "time",
+		.item = &ASN1_GENERALIZEDTIME_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(TS_TST_INFO, accuracy),
+		.field_name = "accuracy",
+		.item = &TS_ACCURACY_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(TS_TST_INFO, ordering),
+		.field_name = "ordering",
+		.item = &ASN1_FBOOLEAN_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(TS_TST_INFO, nonce),
+		.field_name = "nonce",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(TS_TST_INFO, tsa),
+		.field_name = "tsa",
+		.item = &GENERAL_NAME_it,
+	},
+	{
+		.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
+		.tag = 1,
+		.offset = offsetof(TS_TST_INFO, extensions),
+		.field_name = "extensions",
+		.item = &X509_EXTENSION_it,
+	},
+};
+
+const ASN1_ITEM TS_TST_INFO_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = TS_TST_INFO_seq_tt,
+	.tcount = sizeof(TS_TST_INFO_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(TS_TST_INFO),
+	.sname = "TS_TST_INFO",
+};
+
+
+TS_TST_INFO *
+d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **in, long len)
+{
+	return (TS_TST_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &TS_TST_INFO_it);
+}
+
+int
+i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &TS_TST_INFO_it);
+}
+
+TS_TST_INFO *
+TS_TST_INFO_new(void)
+{
+	return (TS_TST_INFO *)ASN1_item_new(&TS_TST_INFO_it);
+}
+
+void
+TS_TST_INFO_free(TS_TST_INFO *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &TS_TST_INFO_it);
+}
+
+TS_TST_INFO *
+TS_TST_INFO_dup(TS_TST_INFO *x)
+{
+	return ASN1_item_dup(&TS_TST_INFO_it, x);
+}
+
+#ifndef OPENSSL_NO_BIO
+TS_TST_INFO *
+d2i_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO **a)
+{
+	return ASN1_d2i_bio_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO,
+	    bp, a);
+}
+
+int
+i2d_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO *a)
+{
+	return ASN1_i2d_bio_of_const(TS_TST_INFO, i2d_TS_TST_INFO, bp, a);
+}
+#endif
+
+TS_TST_INFO *
+d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a)
+{
+	return ASN1_d2i_fp_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO,
+	    fp, a);
+}
+
+int
+i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a)
+{
+	return ASN1_i2d_fp_of_const(TS_TST_INFO, i2d_TS_TST_INFO, fp, a);
+}
+
+static const ASN1_TEMPLATE TS_STATUS_INFO_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(TS_STATUS_INFO, status),
+		.field_name = "status",
+		.item = &ASN1_INTEGER_it,
+	},
+	{
+		.flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(TS_STATUS_INFO, text),
+		.field_name = "text",
+		.item = &ASN1_UTF8STRING_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(TS_STATUS_INFO, failure_info),
+		.field_name = "failure_info",
+		.item = &ASN1_BIT_STRING_it,
+	},
+};
+
+const ASN1_ITEM TS_STATUS_INFO_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = TS_STATUS_INFO_seq_tt,
+	.tcount = sizeof(TS_STATUS_INFO_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(TS_STATUS_INFO),
+	.sname = "TS_STATUS_INFO",
+};
+
+
+TS_STATUS_INFO *
+d2i_TS_STATUS_INFO(TS_STATUS_INFO **a, const unsigned char **in, long len)
+{
+	return (TS_STATUS_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &TS_STATUS_INFO_it);
+}
+
+int
+i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &TS_STATUS_INFO_it);
+}
+
+TS_STATUS_INFO *
+TS_STATUS_INFO_new(void)
+{
+	return (TS_STATUS_INFO *)ASN1_item_new(&TS_STATUS_INFO_it);
+}
+
+void
+TS_STATUS_INFO_free(TS_STATUS_INFO *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &TS_STATUS_INFO_it);
+}
+
+TS_STATUS_INFO *
+TS_STATUS_INFO_dup(TS_STATUS_INFO *x)
+{
+	return ASN1_item_dup(&TS_STATUS_INFO_it, x);
+}
+
+static int
+ts_resp_set_tst_info(TS_RESP *a)
+{
+	long    status;
+
+	status = ASN1_INTEGER_get(a->status_info->status);
+
+	if (a->token) {
+		if (status != 0 && status != 1) {
+			TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_PRESENT);
+			return 0;
+		}
+		if (a->tst_info != NULL)
+			TS_TST_INFO_free(a->tst_info);
+		a->tst_info = PKCS7_to_TS_TST_INFO(a->token);
+		if (!a->tst_info) {
+			TSerr(TS_F_TS_RESP_SET_TST_INFO,
+			    TS_R_PKCS7_TO_TS_TST_INFO_FAILED);
+			return 0;
+		}
+	} else if (status == 0 || status == 1) {
+		TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_NOT_PRESENT);
+		return 0;
+	}
+
+	return 1;
+}
+
+static int
+ts_resp_cb(int op, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
+{
+	TS_RESP *ts_resp = (TS_RESP *)*pval;
+
+	if (op == ASN1_OP_NEW_POST) {
+		ts_resp->tst_info = NULL;
+	} else if (op == ASN1_OP_FREE_POST) {
+		if (ts_resp->tst_info != NULL)
+			TS_TST_INFO_free(ts_resp->tst_info);
+	} else if (op == ASN1_OP_D2I_POST) {
+		if (ts_resp_set_tst_info(ts_resp) == 0)
+			return 0;
+	}
+	return 1;
+}
+
+static const ASN1_AUX TS_RESP_aux = {
+	.app_data = NULL,
+	.flags = 0,
+	.ref_offset = 0,
+	.ref_lock = 0,
+	.asn1_cb = ts_resp_cb,
+	.enc_offset = 0,
+};
+static const ASN1_TEMPLATE TS_RESP_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(TS_RESP, status_info),
+		.field_name = "status_info",
+		.item = &TS_STATUS_INFO_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(TS_RESP, token),
+		.field_name = "token",
+		.item = &PKCS7_it,
+	},
+};
+
+const ASN1_ITEM TS_RESP_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = TS_RESP_seq_tt,
+	.tcount = sizeof(TS_RESP_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = &TS_RESP_aux,
+	.size = sizeof(TS_RESP),
+	.sname = "TS_RESP",
+};
+
+
+TS_RESP *
+d2i_TS_RESP(TS_RESP **a, const unsigned char **in, long len)
+{
+	return (TS_RESP *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &TS_RESP_it);
+}
+
+int
+i2d_TS_RESP(const TS_RESP *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &TS_RESP_it);
+}
+
+TS_RESP *
+TS_RESP_new(void)
+{
+	return (TS_RESP *)ASN1_item_new(&TS_RESP_it);
+}
+
+void
+TS_RESP_free(TS_RESP *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &TS_RESP_it);
+}
+
+TS_RESP *
+TS_RESP_dup(TS_RESP *x)
+{
+	return ASN1_item_dup(&TS_RESP_it, x);
+}
+
+#ifndef OPENSSL_NO_BIO
+TS_RESP *
+d2i_TS_RESP_bio(BIO *bp, TS_RESP **a)
+{
+	return ASN1_d2i_bio_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, bp, a);
+}
+
+int
+i2d_TS_RESP_bio(BIO *bp, TS_RESP *a)
+{
+	return ASN1_i2d_bio_of_const(TS_RESP, i2d_TS_RESP, bp, a);
+}
+#endif
+
+TS_RESP *
+d2i_TS_RESP_fp(FILE *fp, TS_RESP **a)
+{
+	return ASN1_d2i_fp_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, fp, a);
+}
+
+int
+i2d_TS_RESP_fp(FILE *fp, TS_RESP *a)
+{
+	return ASN1_i2d_fp_of_const(TS_RESP, i2d_TS_RESP, fp, a);
+}
+
+static const ASN1_TEMPLATE ESS_ISSUER_SERIAL_seq_tt[] = {
+	{
+		.flags = ASN1_TFLG_SEQUENCE_OF,
+		.tag = 0,
+		.offset = offsetof(ESS_ISSUER_SERIAL, issuer),
+		.field_name = "issuer",
+		.item = &GENERAL_NAME_it,
+	},
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(ESS_ISSUER_SERIAL, serial),
+		.field_name = "serial",
+		.item = &ASN1_INTEGER_it,
+	},
+};
+
+const ASN1_ITEM ESS_ISSUER_SERIAL_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = ESS_ISSUER_SERIAL_seq_tt,
+	.tcount = sizeof(ESS_ISSUER_SERIAL_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(ESS_ISSUER_SERIAL),
+	.sname = "ESS_ISSUER_SERIAL",
+};
+
+
+ESS_ISSUER_SERIAL *
+d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a, const unsigned char **in, long len)
+{
+	return (ESS_ISSUER_SERIAL *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ESS_ISSUER_SERIAL_it);
+}
+
+int
+i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ESS_ISSUER_SERIAL_it);
+}
+
+ESS_ISSUER_SERIAL *
+ESS_ISSUER_SERIAL_new(void)
+{
+	return (ESS_ISSUER_SERIAL *)ASN1_item_new(&ESS_ISSUER_SERIAL_it);
+}
+
+void
+ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ESS_ISSUER_SERIAL_it);
+}
+
+ESS_ISSUER_SERIAL *
+ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *x)
+{
+	return ASN1_item_dup(&ESS_ISSUER_SERIAL_it, x);
+}
+
+static const ASN1_TEMPLATE ESS_CERT_ID_seq_tt[] = {
+	{
+		.flags = 0,
+		.tag = 0,
+		.offset = offsetof(ESS_CERT_ID, hash),
+		.field_name = "hash",
+		.item = &ASN1_OCTET_STRING_it,
+	},
+	{
+		.flags = ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(ESS_CERT_ID, issuer_serial),
+		.field_name = "issuer_serial",
+		.item = &ESS_ISSUER_SERIAL_it,
+	},
+};
+
+const ASN1_ITEM ESS_CERT_ID_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = ESS_CERT_ID_seq_tt,
+	.tcount = sizeof(ESS_CERT_ID_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(ESS_CERT_ID),
+	.sname = "ESS_CERT_ID",
+};
+
+
+ESS_CERT_ID *
+d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **in, long len)
+{
+	return (ESS_CERT_ID *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ESS_CERT_ID_it);
+}
+
+int
+i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ESS_CERT_ID_it);
+}
+
+ESS_CERT_ID *
+ESS_CERT_ID_new(void)
+{
+	return (ESS_CERT_ID *)ASN1_item_new(&ESS_CERT_ID_it);
+}
+
+void
+ESS_CERT_ID_free(ESS_CERT_ID *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ESS_CERT_ID_it);
+}
+
+ESS_CERT_ID *
+ESS_CERT_ID_dup(ESS_CERT_ID *x)
+{
+	return ASN1_item_dup(&ESS_CERT_ID_it, x);
+}
+
+static const ASN1_TEMPLATE ESS_SIGNING_CERT_seq_tt[] = {
+	{
+		.flags = ASN1_TFLG_SEQUENCE_OF,
+		.tag = 0,
+		.offset = offsetof(ESS_SIGNING_CERT, cert_ids),
+		.field_name = "cert_ids",
+		.item = &ESS_CERT_ID_it,
+	},
+	{
+		.flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
+		.tag = 0,
+		.offset = offsetof(ESS_SIGNING_CERT, policy_info),
+		.field_name = "policy_info",
+		.item = &POLICYINFO_it,
+	},
+};
+
+const ASN1_ITEM ESS_SIGNING_CERT_it = {
+	.itype = ASN1_ITYPE_SEQUENCE,
+	.utype = V_ASN1_SEQUENCE,
+	.templates = ESS_SIGNING_CERT_seq_tt,
+	.tcount = sizeof(ESS_SIGNING_CERT_seq_tt) / sizeof(ASN1_TEMPLATE),
+	.funcs = NULL,
+	.size = sizeof(ESS_SIGNING_CERT),
+	.sname = "ESS_SIGNING_CERT",
+};
+
+
+ESS_SIGNING_CERT *
+d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a, const unsigned char **in, long len)
+{
+	return (ESS_SIGNING_CERT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
+	    &ESS_SIGNING_CERT_it);
+}
+
+int
+i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, unsigned char **out)
+{
+	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ESS_SIGNING_CERT_it);
+}
+
+ESS_SIGNING_CERT *
+ESS_SIGNING_CERT_new(void)
+{
+	return (ESS_SIGNING_CERT *)ASN1_item_new(&ESS_SIGNING_CERT_it);
+}
+
+void
+ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a)
+{
+	ASN1_item_free((ASN1_VALUE *)a, &ESS_SIGNING_CERT_it);
+}
+
+ESS_SIGNING_CERT *
+ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *x)
+{
+	return ASN1_item_dup(&ESS_SIGNING_CERT_it, x);
+}
+
+/* Getting encapsulated TS_TST_INFO object from PKCS7. */
+TS_TST_INFO *
+PKCS7_to_TS_TST_INFO(PKCS7 *token)
+{
+	PKCS7_SIGNED *pkcs7_signed;
+	PKCS7 *enveloped;
+	ASN1_TYPE *tst_info_wrapper;
+	ASN1_OCTET_STRING *tst_info_der;
+	const unsigned char *p;
+
+	if (!PKCS7_type_is_signed(token)) {
+		TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE);
+		return NULL;
+	}
+
+	/* Content must be present. */
+	if (PKCS7_get_detached(token)) {
+		TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_DETACHED_CONTENT);
+		return NULL;
+	}
+
+	/* We have a signed data with content. */
+	pkcs7_signed = token->d.sign;
+	enveloped = pkcs7_signed->contents;
+	if (OBJ_obj2nid(enveloped->type) != NID_id_smime_ct_TSTInfo) {
+		TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE);
+		return NULL;
+	}
+
+	/* We have a DER encoded TST_INFO as the signed data. */
+	tst_info_wrapper = enveloped->d.other;
+	if (tst_info_wrapper->type != V_ASN1_OCTET_STRING) {
+		TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_TYPE);
+		return NULL;
+	}
+
+	/* We have the correct ASN1_OCTET_STRING type. */
+	tst_info_der = tst_info_wrapper->value.octet_string;
+	/* At last, decode the TST_INFO. */
+	p = tst_info_der->data;
+	return d2i_TS_TST_INFO(NULL, &p, tst_info_der->length);
+}
diff --git a/crypto/libressl/crypto/ts/ts_conf.c b/crypto/libressl/crypto/ts/ts_conf.c
new file mode 100644
index 0000000000..f807c0a0ac
--- /dev/null
+++ b/crypto/libressl/crypto/ts/ts_conf.c
@@ -0,0 +1,532 @@
+/* $OpenBSD: ts_conf.c,v 1.8 2014/10/28 05:46:56 miod Exp $ */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#ifndef OPENSSL_NO_ENGINE
+#include 
+#endif
+
+/* Macro definitions for the configuration file. */
+
+#define	BASE_SECTION			"tsa"
+#define	ENV_DEFAULT_TSA			"default_tsa"
+#define	ENV_SERIAL			"serial"
+#define ENV_CRYPTO_DEVICE		"crypto_device"
+#define	ENV_SIGNER_CERT			"signer_cert"
+#define	ENV_CERTS			"certs"
+#define	ENV_SIGNER_KEY			"signer_key"
+#define	ENV_DEFAULT_POLICY		"default_policy"
+#define	ENV_OTHER_POLICIES		"other_policies"
+#define	ENV_DIGESTS			"digests"
+#define	ENV_ACCURACY			"accuracy"
+#define	ENV_ORDERING			"ordering"
+#define	ENV_TSA_NAME			"tsa_name"
+#define	ENV_ESS_CERT_ID_CHAIN		"ess_cert_id_chain"
+#define	ENV_VALUE_SECS			"secs"
+#define	ENV_VALUE_MILLISECS		"millisecs"
+#define	ENV_VALUE_MICROSECS		"microsecs"
+#define	ENV_CLOCK_PRECISION_DIGITS	"clock_precision_digits"
+#define	ENV_VALUE_YES			"yes"
+#define	ENV_VALUE_NO			"no"
+
+/* Function definitions for certificate and key loading. */
+
+X509 *
+TS_CONF_load_cert(const char *file)
+{
+	BIO *cert = NULL;
+	X509 *x = NULL;
+
+	if ((cert = BIO_new_file(file, "r")) == NULL)
+		goto end;
+	x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL);
+
+end:
+	if (x == NULL)
+		fprintf(stderr, "unable to load certificate: %s\n", file);
+	BIO_free(cert);
+	return x;
+}
+
+STACK_OF(X509) *
+TS_CONF_load_certs(const char *file)
+{
+	BIO *certs = NULL;
+	STACK_OF(X509) *othercerts = NULL;
+	STACK_OF(X509_INFO) *allcerts = NULL;
+	int i;
+
+	if (!(certs = BIO_new_file(file, "r")))
+		goto end;
+
+	if (!(othercerts = sk_X509_new_null()))
+		goto end;
+	allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL);
+	for (i = 0; i < sk_X509_INFO_num(allcerts); i++) {
+		X509_INFO *xi = sk_X509_INFO_value(allcerts, i);
+		if (xi->x509) {
+			if (sk_X509_push(othercerts, xi->x509) == 0) {
+				sk_X509_pop_free(othercerts, X509_free);
+				othercerts = NULL;
+				goto end;
+			}
+			xi->x509 = NULL;
+		}
+	}
+
+end:
+	if (othercerts == NULL)
+		fprintf(stderr, "unable to load certificates: %s\n", file);
+	sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
+	BIO_free(certs);
+	return othercerts;
+}
+
+EVP_PKEY *
+TS_CONF_load_key(const char *file, const char *pass)
+{
+	BIO *key = NULL;
+	EVP_PKEY *pkey = NULL;
+
+	if (!(key = BIO_new_file(file, "r")))
+		goto end;
+	pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, (char *) pass);
+
+end:
+	if (pkey == NULL)
+		fprintf(stderr, "unable to load private key: %s\n", file);
+	BIO_free(key);
+	return pkey;
+}
+
+/* Function definitions for handling configuration options. */
+
+static void
+TS_CONF_lookup_fail(const char *name, const char *tag)
+{
+	fprintf(stderr, "variable lookup failed for %s::%s\n", name, tag);
+}
+
+static void
+TS_CONF_invalid(const char *name, const char *tag)
+{
+	fprintf(stderr, "invalid variable value for %s::%s\n", name, tag);
+}
+
+const char *
+TS_CONF_get_tsa_section(CONF *conf, const char *section)
+{
+	if (!section) {
+		section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_TSA);
+		if (!section)
+			TS_CONF_lookup_fail(BASE_SECTION, ENV_DEFAULT_TSA);
+	}
+	return section;
+}
+
+int
+TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb,
+    TS_RESP_CTX *ctx)
+{
+	int ret = 0;
+	char *serial = NCONF_get_string(conf, section, ENV_SERIAL);
+
+	if (!serial) {
+		TS_CONF_lookup_fail(section, ENV_SERIAL);
+		goto err;
+	}
+	TS_RESP_CTX_set_serial_cb(ctx, cb, serial);
+
+	ret = 1;
+
+err:
+	return ret;
+}
+
+#ifndef OPENSSL_NO_ENGINE
+
+int
+TS_CONF_set_crypto_device(CONF *conf, const char *section, const char *device)
+{
+	int ret = 0;
+
+	if (!device)
+		device = NCONF_get_string(conf, section, ENV_CRYPTO_DEVICE);
+
+	if (device && !TS_CONF_set_default_engine(device)) {
+		TS_CONF_invalid(section, ENV_CRYPTO_DEVICE);
+		goto err;
+	}
+	ret = 1;
+
+err:
+	return ret;
+}
+
+int
+TS_CONF_set_default_engine(const char *name)
+{
+	ENGINE *e = NULL;
+	int ret = 0;
+
+	/* Leave the default if builtin specified. */
+	if (strcmp(name, "builtin") == 0)
+		return 1;
+
+	if (!(e = ENGINE_by_id(name)))
+		goto err;
+	/* All the operations are going to be carried out by the engine. */
+	if (!ENGINE_set_default(e, ENGINE_METHOD_ALL))
+		goto err;
+	ret = 1;
+
+err:
+	if (!ret) {
+		TSerr(TS_F_TS_CONF_SET_DEFAULT_ENGINE,
+		    TS_R_COULD_NOT_SET_ENGINE);
+		ERR_asprintf_error_data("engine:%s", name);
+	}
+	if (e)
+		ENGINE_free(e);
+	return ret;
+}
+
+#endif
+
+int
+TS_CONF_set_signer_cert(CONF *conf, const char *section, const char *cert,
+    TS_RESP_CTX *ctx)
+{
+	int ret = 0;
+	X509 *cert_obj = NULL;
+
+	if (!cert)
+		cert = NCONF_get_string(conf, section, ENV_SIGNER_CERT);
+	if (!cert) {
+		TS_CONF_lookup_fail(section, ENV_SIGNER_CERT);
+		goto err;
+	}
+	if (!(cert_obj = TS_CONF_load_cert(cert)))
+		goto err;
+	if (!TS_RESP_CTX_set_signer_cert(ctx, cert_obj))
+		goto err;
+
+	ret = 1;
+
+err:
+	X509_free(cert_obj);
+	return ret;
+}
+
+int
+TS_CONF_set_certs(CONF *conf, const char *section, const char *certs,
+    TS_RESP_CTX *ctx)
+{
+	int ret = 0;
+	STACK_OF(X509) *certs_obj = NULL;
+
+	if (!certs)
+		certs = NCONF_get_string(conf, section, ENV_CERTS);
+	/* Certificate chain is optional. */
+	if (!certs)
+		goto end;
+	if (!(certs_obj = TS_CONF_load_certs(certs)))
+		goto err;
+	if (!TS_RESP_CTX_set_certs(ctx, certs_obj))
+		goto err;
+
+end:
+	ret = 1;
+err:
+	sk_X509_pop_free(certs_obj, X509_free);
+	return ret;
+}
+
+int
+TS_CONF_set_signer_key(CONF *conf, const char *section, const char *key,
+    const char *pass, TS_RESP_CTX *ctx)
+{
+	int ret = 0;
+	EVP_PKEY *key_obj = NULL;
+
+	if (!key)
+		key = NCONF_get_string(conf, section, ENV_SIGNER_KEY);
+	if (!key) {
+		TS_CONF_lookup_fail(section, ENV_SIGNER_KEY);
+		goto err;
+	}
+	if (!(key_obj = TS_CONF_load_key(key, pass)))
+		goto err;
+	if (!TS_RESP_CTX_set_signer_key(ctx, key_obj))
+		goto err;
+
+	ret = 1;
+
+err:
+	EVP_PKEY_free(key_obj);
+	return ret;
+}
+
+int
+TS_CONF_set_def_policy(CONF *conf, const char *section, const char *policy,
+    TS_RESP_CTX *ctx)
+{
+	int ret = 0;
+	ASN1_OBJECT *policy_obj = NULL;
+
+    	if (!policy)
+		policy = NCONF_get_string(conf, section, ENV_DEFAULT_POLICY);
+	if (!policy) {
+		TS_CONF_lookup_fail(section, ENV_DEFAULT_POLICY);
+		goto err;
+	}
+	if (!(policy_obj = OBJ_txt2obj(policy, 0))) {
+		TS_CONF_invalid(section, ENV_DEFAULT_POLICY);
+		goto err;
+	}
+	if (!TS_RESP_CTX_set_def_policy(ctx, policy_obj))
+		goto err;
+
+	ret = 1;
+
+err:
+	ASN1_OBJECT_free(policy_obj);
+	return ret;
+}
+
+int
+TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx)
+{
+	int ret = 0;
+	int i;
+	STACK_OF(CONF_VALUE) *list = NULL;
+	char *policies = NCONF_get_string(conf, section, ENV_OTHER_POLICIES);
+
+	/* If no other policy is specified, that's fine. */
+	if (policies && !(list = X509V3_parse_list(policies))) {
+		TS_CONF_invalid(section, ENV_OTHER_POLICIES);
+		goto err;
+	}
+	for (i = 0; i < sk_CONF_VALUE_num(list); ++i) {
+		CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
+		const char *extval = val->value ? val->value : val->name;
+		ASN1_OBJECT *objtmp;
+		if (!(objtmp = OBJ_txt2obj(extval, 0))) {
+			TS_CONF_invalid(section, ENV_OTHER_POLICIES);
+			goto err;
+		}
+		if (!TS_RESP_CTX_add_policy(ctx, objtmp))
+			goto err;
+		ASN1_OBJECT_free(objtmp);
+	}
+
+	ret = 1;
+
+err:
+	sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
+	return ret;
+}
+
+int
+TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx)
+{
+	int ret = 0;
+	int i;
+	STACK_OF(CONF_VALUE) *list = NULL;
+	char *digests = NCONF_get_string(conf, section, ENV_DIGESTS);
+
+	if (!digests) {
+		TS_CONF_lookup_fail(section, ENV_DIGESTS);
+		goto err;
+	}
+	if (!(list = X509V3_parse_list(digests))) {
+		TS_CONF_invalid(section, ENV_DIGESTS);
+		goto err;
+	}
+	if (sk_CONF_VALUE_num(list) == 0) {
+		TS_CONF_invalid(section, ENV_DIGESTS);
+		goto err;
+	}
+	for (i = 0; i < sk_CONF_VALUE_num(list); ++i) {
+		CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
+		const char *extval = val->value ? val->value : val->name;
+		const EVP_MD *md;
+		if (!(md = EVP_get_digestbyname(extval))) {
+			TS_CONF_invalid(section, ENV_DIGESTS);
+			goto err;
+		}
+		if (!TS_RESP_CTX_add_md(ctx, md))
+			goto err;
+	}
+
+	ret = 1;
+
+err:
+	sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
+	return ret;
+}
+
+int
+TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx)
+{
+	int ret = 0;
+	int i;
+	int secs = 0, millis = 0, micros = 0;
+	STACK_OF(CONF_VALUE) *list = NULL;
+	char *accuracy = NCONF_get_string(conf, section, ENV_ACCURACY);
+
+	if (accuracy && !(list = X509V3_parse_list(accuracy))) {
+		TS_CONF_invalid(section, ENV_ACCURACY);
+		goto err;
+	}
+	for (i = 0; i < sk_CONF_VALUE_num(list); ++i) {
+		CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
+		if (strcmp(val->name, ENV_VALUE_SECS) == 0) {
+			if (val->value)
+				secs = atoi(val->value);
+		} else if (strcmp(val->name, ENV_VALUE_MILLISECS) == 0) {
+			if (val->value)
+				millis = atoi(val->value);
+		} else if (strcmp(val->name, ENV_VALUE_MICROSECS) == 0) {
+			if (val->value)
+				micros = atoi(val->value);
+		} else {
+			TS_CONF_invalid(section, ENV_ACCURACY);
+			goto err;
+		}
+	}
+	if (!TS_RESP_CTX_set_accuracy(ctx, secs, millis, micros))
+		goto err;
+
+	ret = 1;
+
+err:
+	sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
+	return ret;
+}
+
+int
+TS_CONF_set_clock_precision_digits(CONF *conf, const char *section,
+    TS_RESP_CTX *ctx)
+{
+	int ret = 0;
+	long digits = 0;
+
+	/* If not specified, set the default value to 0, i.e. sec  precision */
+	if (!NCONF_get_number_e(conf, section, ENV_CLOCK_PRECISION_DIGITS,
+	    &digits))
+		digits = 0;
+	if (digits < 0 || digits > TS_MAX_CLOCK_PRECISION_DIGITS) {
+		TS_CONF_invalid(section, ENV_CLOCK_PRECISION_DIGITS);
+		goto err;
+	}
+
+	if (!TS_RESP_CTX_set_clock_precision_digits(ctx, digits))
+		goto err;
+
+	return 1;
+
+err:
+	return ret;
+}
+
+static int
+TS_CONF_add_flag(CONF *conf, const char *section, const char *field, int flag,
+    TS_RESP_CTX *ctx)
+{
+	/* Default is false. */
+	const char *value = NCONF_get_string(conf, section, field);
+
+	if (value) {
+		if (strcmp(value, ENV_VALUE_YES) == 0)
+			TS_RESP_CTX_add_flags(ctx, flag);
+		else if (strcmp(value, ENV_VALUE_NO) != 0) {
+			TS_CONF_invalid(section, field);
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
+int
+TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx)
+{
+	return TS_CONF_add_flag(conf, section, ENV_ORDERING, TS_ORDERING, ctx);
+}
+
+int
+TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx)
+{
+	return TS_CONF_add_flag(conf, section, ENV_TSA_NAME, TS_TSA_NAME, ctx);
+}
+
+int
+TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section, TS_RESP_CTX *ctx)
+{
+	return TS_CONF_add_flag(conf, section, ENV_ESS_CERT_ID_CHAIN,
+	    TS_ESS_CERT_ID_CHAIN, ctx);
+}
diff --git a/crypto/libressl/crypto/ts/ts_err.c b/crypto/libressl/crypto/ts/ts_err.c
new file mode 100644
index 0000000000..d7dd85ecec
--- /dev/null
+++ b/crypto/libressl/crypto/ts/ts_err.c
@@ -0,0 +1,179 @@
+/* $OpenBSD: ts_err.c,v 1.3 2014/06/12 15:49:31 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_TS,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_TS,0,reason)
+
+static ERR_STRING_DATA TS_str_functs[] = {
+	{ERR_FUNC(TS_F_D2I_TS_RESP),	"d2i_TS_RESP"},
+	{ERR_FUNC(TS_F_DEF_SERIAL_CB),	"DEF_SERIAL_CB"},
+	{ERR_FUNC(TS_F_DEF_TIME_CB),	"DEF_TIME_CB"},
+	{ERR_FUNC(TS_F_ESS_ADD_SIGNING_CERT),	"ESS_ADD_SIGNING_CERT"},
+	{ERR_FUNC(TS_F_ESS_CERT_ID_NEW_INIT),	"ESS_CERT_ID_NEW_INIT"},
+	{ERR_FUNC(TS_F_ESS_SIGNING_CERT_NEW_INIT),	"ESS_SIGNING_CERT_NEW_INIT"},
+	{ERR_FUNC(TS_F_INT_TS_RESP_VERIFY_TOKEN),	"INT_TS_RESP_VERIFY_TOKEN"},
+	{ERR_FUNC(TS_F_PKCS7_TO_TS_TST_INFO),	"PKCS7_to_TS_TST_INFO"},
+	{ERR_FUNC(TS_F_TS_ACCURACY_SET_MICROS),	"TS_ACCURACY_set_micros"},
+	{ERR_FUNC(TS_F_TS_ACCURACY_SET_MILLIS),	"TS_ACCURACY_set_millis"},
+	{ERR_FUNC(TS_F_TS_ACCURACY_SET_SECONDS),	"TS_ACCURACY_set_seconds"},
+	{ERR_FUNC(TS_F_TS_CHECK_IMPRINTS),	"TS_CHECK_IMPRINTS"},
+	{ERR_FUNC(TS_F_TS_CHECK_NONCES),	"TS_CHECK_NONCES"},
+	{ERR_FUNC(TS_F_TS_CHECK_POLICY),	"TS_CHECK_POLICY"},
+	{ERR_FUNC(TS_F_TS_CHECK_SIGNING_CERTS),	"TS_CHECK_SIGNING_CERTS"},
+	{ERR_FUNC(TS_F_TS_CHECK_STATUS_INFO),	"TS_CHECK_STATUS_INFO"},
+	{ERR_FUNC(TS_F_TS_COMPUTE_IMPRINT),	"TS_COMPUTE_IMPRINT"},
+	{ERR_FUNC(TS_F_TS_CONF_SET_DEFAULT_ENGINE),	"TS_CONF_set_default_engine"},
+	{ERR_FUNC(TS_F_TS_GET_STATUS_TEXT),	"TS_GET_STATUS_TEXT"},
+	{ERR_FUNC(TS_F_TS_MSG_IMPRINT_SET_ALGO),	"TS_MSG_IMPRINT_set_algo"},
+	{ERR_FUNC(TS_F_TS_REQ_SET_MSG_IMPRINT),	"TS_REQ_set_msg_imprint"},
+	{ERR_FUNC(TS_F_TS_REQ_SET_NONCE),	"TS_REQ_set_nonce"},
+	{ERR_FUNC(TS_F_TS_REQ_SET_POLICY_ID),	"TS_REQ_set_policy_id"},
+	{ERR_FUNC(TS_F_TS_RESP_CREATE_RESPONSE),	"TS_RESP_create_response"},
+	{ERR_FUNC(TS_F_TS_RESP_CREATE_TST_INFO),	"TS_RESP_CREATE_TST_INFO"},
+	{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO),	"TS_RESP_CTX_add_failure_info"},
+	{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_MD),	"TS_RESP_CTX_add_md"},
+	{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_POLICY),	"TS_RESP_CTX_add_policy"},
+	{ERR_FUNC(TS_F_TS_RESP_CTX_NEW),	"TS_RESP_CTX_new"},
+	{ERR_FUNC(TS_F_TS_RESP_CTX_SET_ACCURACY),	"TS_RESP_CTX_set_accuracy"},
+	{ERR_FUNC(TS_F_TS_RESP_CTX_SET_CERTS),	"TS_RESP_CTX_set_certs"},
+	{ERR_FUNC(TS_F_TS_RESP_CTX_SET_DEF_POLICY),	"TS_RESP_CTX_set_def_policy"},
+	{ERR_FUNC(TS_F_TS_RESP_CTX_SET_SIGNER_CERT),	"TS_RESP_CTX_set_signer_cert"},
+	{ERR_FUNC(TS_F_TS_RESP_CTX_SET_STATUS_INFO),	"TS_RESP_CTX_set_status_info"},
+	{ERR_FUNC(TS_F_TS_RESP_GET_POLICY),	"TS_RESP_GET_POLICY"},
+	{ERR_FUNC(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION),	"TS_RESP_SET_GENTIME_WITH_PRECISION"},
+	{ERR_FUNC(TS_F_TS_RESP_SET_STATUS_INFO),	"TS_RESP_set_status_info"},
+	{ERR_FUNC(TS_F_TS_RESP_SET_TST_INFO),	"TS_RESP_set_tst_info"},
+	{ERR_FUNC(TS_F_TS_RESP_SIGN),	"TS_RESP_SIGN"},
+	{ERR_FUNC(TS_F_TS_RESP_VERIFY_SIGNATURE),	"TS_RESP_verify_signature"},
+	{ERR_FUNC(TS_F_TS_RESP_VERIFY_TOKEN),	"TS_RESP_verify_token"},
+	{ERR_FUNC(TS_F_TS_TST_INFO_SET_ACCURACY),	"TS_TST_INFO_set_accuracy"},
+	{ERR_FUNC(TS_F_TS_TST_INFO_SET_MSG_IMPRINT),	"TS_TST_INFO_set_msg_imprint"},
+	{ERR_FUNC(TS_F_TS_TST_INFO_SET_NONCE),	"TS_TST_INFO_set_nonce"},
+	{ERR_FUNC(TS_F_TS_TST_INFO_SET_POLICY_ID),	"TS_TST_INFO_set_policy_id"},
+	{ERR_FUNC(TS_F_TS_TST_INFO_SET_SERIAL),	"TS_TST_INFO_set_serial"},
+	{ERR_FUNC(TS_F_TS_TST_INFO_SET_TIME),	"TS_TST_INFO_set_time"},
+	{ERR_FUNC(TS_F_TS_TST_INFO_SET_TSA),	"TS_TST_INFO_set_tsa"},
+	{ERR_FUNC(TS_F_TS_VERIFY),	"TS_VERIFY"},
+	{ERR_FUNC(TS_F_TS_VERIFY_CERT),	"TS_VERIFY_CERT"},
+	{ERR_FUNC(TS_F_TS_VERIFY_CTX_NEW),	"TS_VERIFY_CTX_new"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA TS_str_reasons[]= {
+	{ERR_REASON(TS_R_BAD_PKCS7_TYPE)         , "bad pkcs7 type"},
+	{ERR_REASON(TS_R_BAD_TYPE)               , "bad type"},
+	{ERR_REASON(TS_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"},
+	{ERR_REASON(TS_R_COULD_NOT_SET_ENGINE)   , "could not set engine"},
+	{ERR_REASON(TS_R_COULD_NOT_SET_TIME)     , "could not set time"},
+	{ERR_REASON(TS_R_D2I_TS_RESP_INT_FAILED) , "d2i ts resp int failed"},
+	{ERR_REASON(TS_R_DETACHED_CONTENT)       , "detached content"},
+	{ERR_REASON(TS_R_ESS_ADD_SIGNING_CERT_ERROR), "ess add signing cert error"},
+	{ERR_REASON(TS_R_ESS_SIGNING_CERTIFICATE_ERROR), "ess signing certificate error"},
+	{ERR_REASON(TS_R_INVALID_NULL_POINTER)   , "invalid null pointer"},
+	{ERR_REASON(TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE), "invalid signer certificate purpose"},
+	{ERR_REASON(TS_R_MESSAGE_IMPRINT_MISMATCH), "message imprint mismatch"},
+	{ERR_REASON(TS_R_NONCE_MISMATCH)         , "nonce mismatch"},
+	{ERR_REASON(TS_R_NONCE_NOT_RETURNED)     , "nonce not returned"},
+	{ERR_REASON(TS_R_NO_CONTENT)             , "no content"},
+	{ERR_REASON(TS_R_NO_TIME_STAMP_TOKEN)    , "no time stamp token"},
+	{ERR_REASON(TS_R_PKCS7_ADD_SIGNATURE_ERROR), "pkcs7 add signature error"},
+	{ERR_REASON(TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR), "pkcs7 add signed attr error"},
+	{ERR_REASON(TS_R_PKCS7_TO_TS_TST_INFO_FAILED), "pkcs7 to ts tst info failed"},
+	{ERR_REASON(TS_R_POLICY_MISMATCH)        , "policy mismatch"},
+	{ERR_REASON(TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), "private key does not match certificate"},
+	{ERR_REASON(TS_R_RESPONSE_SETUP_ERROR)   , "response setup error"},
+	{ERR_REASON(TS_R_SIGNATURE_FAILURE)      , "signature failure"},
+	{ERR_REASON(TS_R_THERE_MUST_BE_ONE_SIGNER), "there must be one signer"},
+	{ERR_REASON(TS_R_TIME_SYSCALL_ERROR)     , "time syscall error"},
+	{ERR_REASON(TS_R_TOKEN_NOT_PRESENT)      , "token not present"},
+	{ERR_REASON(TS_R_TOKEN_PRESENT)          , "token present"},
+	{ERR_REASON(TS_R_TSA_NAME_MISMATCH)      , "tsa name mismatch"},
+	{ERR_REASON(TS_R_TSA_UNTRUSTED)          , "tsa untrusted"},
+	{ERR_REASON(TS_R_TST_INFO_SETUP_ERROR)   , "tst info setup error"},
+	{ERR_REASON(TS_R_TS_DATASIGN)            , "ts datasign"},
+	{ERR_REASON(TS_R_UNACCEPTABLE_POLICY)    , "unacceptable policy"},
+	{ERR_REASON(TS_R_UNSUPPORTED_MD_ALGORITHM), "unsupported md algorithm"},
+	{ERR_REASON(TS_R_UNSUPPORTED_VERSION)    , "unsupported version"},
+	{ERR_REASON(TS_R_WRONG_CONTENT_TYPE)     , "wrong content type"},
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_TS_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(TS_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, TS_str_functs);
+		ERR_load_strings(0, TS_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/ts/ts_lib.c b/crypto/libressl/crypto/ts/ts_lib.c
new file mode 100644
index 0000000000..b0cb89c4d3
--- /dev/null
+++ b/crypto/libressl/crypto/ts/ts_lib.c
@@ -0,0 +1,150 @@
+/* $OpenBSD: ts_lib.c,v 1.9 2015/07/29 14:58:34 jsing Exp $ */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+/* Local function declarations. */
+
+/* Function definitions. */
+
+int
+TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num)
+{
+	BIGNUM num_bn;
+	int result = 0;
+	char *hex;
+
+	BN_init(&num_bn);
+	ASN1_INTEGER_to_BN(num, &num_bn);
+	if ((hex = BN_bn2hex(&num_bn))) {
+		result = BIO_write(bio, "0x", 2) > 0;
+		result = result && BIO_write(bio, hex, strlen(hex)) > 0;
+		free(hex);
+	}
+	BN_free(&num_bn);
+
+	return result;
+}
+
+int
+TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj)
+{
+	char obj_txt[128];
+
+	int len = OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0);
+	if (len >= sizeof(obj_txt))
+		len = sizeof(obj_txt) - 1;
+	BIO_write(bio, obj_txt, len);
+	BIO_write(bio, "\n", 1);
+	return 1;
+}
+
+int
+TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions)
+{
+	int i, critical, n;
+	X509_EXTENSION *ex;
+	ASN1_OBJECT *obj;
+
+	BIO_printf(bio, "Extensions:\n");
+	n = X509v3_get_ext_count(extensions);
+	for (i = 0; i < n; i++) {
+		ex = X509v3_get_ext(extensions, i);
+		obj = X509_EXTENSION_get_object(ex);
+		i2a_ASN1_OBJECT(bio, obj);
+		critical = X509_EXTENSION_get_critical(ex);
+		BIO_printf(bio, ": %s\n", critical ? "critical" : "");
+		if (!X509V3_EXT_print(bio, ex, 0, 4)) {
+			BIO_printf(bio, "%4s", "");
+			ASN1_STRING_print(bio, ex->value);
+		}
+		BIO_write(bio, "\n", 1);
+	}
+
+	return 1;
+}
+
+int
+TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg)
+{
+	int i = OBJ_obj2nid(alg->algorithm);
+
+	return BIO_printf(bio, "Hash Algorithm: %s\n",
+	    (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
+}
+
+int
+TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *a)
+{
+	ASN1_OCTET_STRING *msg;
+
+	TS_X509_ALGOR_print_bio(bio, TS_MSG_IMPRINT_get_algo(a));
+
+	BIO_printf(bio, "Message data:\n");
+	msg = TS_MSG_IMPRINT_get_msg(a);
+	BIO_dump_indent(bio, (const char *)ASN1_STRING_data(msg),
+	    ASN1_STRING_length(msg), 4);
+
+	return 1;
+}
diff --git a/crypto/libressl/crypto/ts/ts_req_print.c b/crypto/libressl/crypto/ts/ts_req_print.c
new file mode 100644
index 0000000000..372fb929e0
--- /dev/null
+++ b/crypto/libressl/crypto/ts/ts_req_print.c
@@ -0,0 +1,104 @@
+/* $OpenBSD: ts_req_print.c,v 1.3 2014/06/12 15:49:31 deraadt Exp $ */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+/* Function definitions. */
+
+int
+TS_REQ_print_bio(BIO *bio, TS_REQ *a)
+{
+	int v;
+	ASN1_OBJECT *policy_id;
+	const ASN1_INTEGER *nonce;
+
+	if (a == NULL)
+		return 0;
+
+	v = TS_REQ_get_version(a);
+	BIO_printf(bio, "Version: %d\n", v);
+
+	TS_MSG_IMPRINT_print_bio(bio, TS_REQ_get_msg_imprint(a));
+
+	BIO_printf(bio, "Policy OID: ");
+	policy_id = TS_REQ_get_policy_id(a);
+	if (policy_id == NULL)
+		BIO_printf(bio, "unspecified\n");
+	else
+		TS_OBJ_print_bio(bio, policy_id);
+
+	BIO_printf(bio, "Nonce: ");
+	nonce = TS_REQ_get_nonce(a);
+	if (nonce == NULL)
+		BIO_printf(bio, "unspecified");
+	else
+		TS_ASN1_INTEGER_print_bio(bio, nonce);
+	BIO_write(bio, "\n", 1);
+
+	BIO_printf(bio, "Certificate required: %s\n",
+	    TS_REQ_get_cert_req(a) ? "yes" : "no");
+
+	TS_ext_print_bio(bio, TS_REQ_get_exts(a));
+
+	return 1;
+}
diff --git a/crypto/libressl/crypto/ts/ts_req_utils.c b/crypto/libressl/crypto/ts/ts_req_utils.c
new file mode 100644
index 0000000000..0fdbd59b3a
--- /dev/null
+++ b/crypto/libressl/crypto/ts/ts_req_utils.c
@@ -0,0 +1,255 @@
+/* $OpenBSD: ts_req_utils.c,v 1.3 2014/06/12 15:49:31 deraadt Exp $ */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+int
+TS_REQ_set_version(TS_REQ *a, long version)
+{
+	return ASN1_INTEGER_set(a->version, version);
+}
+
+long
+TS_REQ_get_version(const TS_REQ *a)
+{
+	return ASN1_INTEGER_get(a->version);
+}
+
+int
+TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint)
+{
+	TS_MSG_IMPRINT *new_msg_imprint;
+
+	if (a->msg_imprint == msg_imprint)
+		return 1;
+	new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint);
+	if (new_msg_imprint == NULL) {
+		TSerr(TS_F_TS_REQ_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	TS_MSG_IMPRINT_free(a->msg_imprint);
+	a->msg_imprint = new_msg_imprint;
+	return 1;
+}
+
+TS_MSG_IMPRINT *
+TS_REQ_get_msg_imprint(TS_REQ *a)
+{
+	return a->msg_imprint;
+}
+
+int
+TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg)
+{
+	X509_ALGOR *new_alg;
+
+	if (a->hash_algo == alg)
+		return 1;
+	new_alg = X509_ALGOR_dup(alg);
+	if (new_alg == NULL) {
+		TSerr(TS_F_TS_MSG_IMPRINT_SET_ALGO, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	X509_ALGOR_free(a->hash_algo);
+	a->hash_algo = new_alg;
+	return 1;
+}
+
+X509_ALGOR *
+TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a)
+{
+	return a->hash_algo;
+}
+
+int
+TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len)
+{
+	return ASN1_OCTET_STRING_set(a->hashed_msg, d, len);
+}
+
+ASN1_OCTET_STRING *
+TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a)
+{
+	return a->hashed_msg;
+}
+
+int
+TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy)
+{
+	ASN1_OBJECT *new_policy;
+
+	if (a->policy_id == policy)
+		return 1;
+	new_policy = OBJ_dup(policy);
+	if (new_policy == NULL) {
+		TSerr(TS_F_TS_REQ_SET_POLICY_ID, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	ASN1_OBJECT_free(a->policy_id);
+	a->policy_id = new_policy;
+	return 1;
+}
+
+ASN1_OBJECT *
+TS_REQ_get_policy_id(TS_REQ *a)
+{
+	return a->policy_id;
+}
+
+int
+TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce)
+{
+	ASN1_INTEGER *new_nonce;
+
+	if (a->nonce == nonce)
+		return 1;
+	new_nonce = ASN1_INTEGER_dup(nonce);
+	if (new_nonce == NULL) {
+		TSerr(TS_F_TS_REQ_SET_NONCE, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	ASN1_INTEGER_free(a->nonce);
+	a->nonce = new_nonce;
+	return 1;
+}
+
+const ASN1_INTEGER *
+TS_REQ_get_nonce(const TS_REQ *a)
+{
+	return a->nonce;
+}
+
+int
+TS_REQ_set_cert_req(TS_REQ *a, int cert_req)
+{
+	a->cert_req = cert_req ? 0xFF : 0x00;
+	return 1;
+}
+
+int
+TS_REQ_get_cert_req(const TS_REQ *a)
+{
+	return a->cert_req ? 1 : 0;
+}
+
+STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a)
+{
+	return a->extensions;
+}
+
+void
+TS_REQ_ext_free(TS_REQ *a)
+{
+	if (!a)
+		return;
+	sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free);
+	a->extensions = NULL;
+}
+
+int
+TS_REQ_get_ext_count(TS_REQ *a)
+{
+	return X509v3_get_ext_count(a->extensions);
+}
+
+int
+TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos)
+{
+	return X509v3_get_ext_by_NID(a->extensions, nid, lastpos);
+}
+
+int
+TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos)
+{
+	return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos);
+}
+
+int
+TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos)
+{
+	return X509v3_get_ext_by_critical(a->extensions, crit, lastpos);
+}
+
+X509_EXTENSION *
+TS_REQ_get_ext(TS_REQ *a, int loc)
+{
+	return X509v3_get_ext(a->extensions, loc);
+}
+
+X509_EXTENSION *
+TS_REQ_delete_ext(TS_REQ *a, int loc)
+{
+	return X509v3_delete_ext(a->extensions, loc);
+}
+
+int
+TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc)
+{
+	return X509v3_add_ext(&a->extensions, ex, loc) != NULL;
+}
+
+void *
+TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx)
+{
+	return X509V3_get_d2i(a->extensions, nid, crit, idx);
+}
diff --git a/crypto/libressl/crypto/ts/ts_rsp_print.c b/crypto/libressl/crypto/ts/ts_rsp_print.c
new file mode 100644
index 0000000000..77a0e3a0ca
--- /dev/null
+++ b/crypto/libressl/crypto/ts/ts_rsp_print.c
@@ -0,0 +1,301 @@
+/* $OpenBSD: ts_rsp_print.c,v 1.4 2014/06/12 15:49:31 deraadt Exp $ */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+struct status_map_st {
+	int bit;
+	const char *text;
+};
+
+/* Local function declarations. */
+
+static int TS_status_map_print(BIO *bio, struct status_map_st *a,
+    ASN1_BIT_STRING *v);
+static int TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy);
+
+/* Function definitions. */
+
+int
+TS_RESP_print_bio(BIO *bio, TS_RESP *a)
+{
+	TS_TST_INFO *tst_info;
+
+	BIO_printf(bio, "Status info:\n");
+	TS_STATUS_INFO_print_bio(bio, TS_RESP_get_status_info(a));
+
+	BIO_printf(bio, "\nTST info:\n");
+	tst_info = TS_RESP_get_tst_info(a);
+	if (tst_info != NULL)
+		TS_TST_INFO_print_bio(bio, TS_RESP_get_tst_info(a));
+	else
+		BIO_printf(bio, "Not included.\n");
+
+	return 1;
+}
+
+int
+TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a)
+{
+	static const char *status_map[] = {
+		"Granted.",
+		"Granted with modifications.",
+		"Rejected.",
+		"Waiting.",
+		"Revocation warning.",
+		"Revoked."
+	};
+	static struct status_map_st failure_map[] = {
+		{
+			TS_INFO_BAD_ALG,
+			"unrecognized or unsupported algorithm identifier"
+		},
+		{
+			TS_INFO_BAD_REQUEST,
+			"transaction not permitted or supported"
+		},
+		{
+			TS_INFO_BAD_DATA_FORMAT,
+			"the data submitted has the wrong format"
+		},
+		{
+			TS_INFO_TIME_NOT_AVAILABLE,
+			"the TSA's time source is not available"
+		},
+		{
+			TS_INFO_UNACCEPTED_POLICY,
+			"the requested TSA policy is not supported by the TSA"
+		},
+		{
+			TS_INFO_UNACCEPTED_EXTENSION,
+			"the requested extension is not supported by the TSA"
+		},
+		{
+			TS_INFO_ADD_INFO_NOT_AVAILABLE,
+			"the additional information requested could not be understood "
+			"or is not available"
+		},
+		{
+			TS_INFO_SYSTEM_FAILURE,
+			"the request cannot be handled due to system failure"
+		},
+		{ -1, NULL }
+	};
+	long status;
+	int i, lines = 0;
+
+	/* Printing status code. */
+	BIO_printf(bio, "Status: ");
+	status = ASN1_INTEGER_get(a->status);
+	if (0 <= status &&
+	    status < (long)(sizeof(status_map) / sizeof(status_map[0])))
+		BIO_printf(bio, "%s\n", status_map[status]);
+	else
+		BIO_printf(bio, "out of bounds\n");
+
+	/* Printing status description. */
+	BIO_printf(bio, "Status description: ");
+	for (i = 0; i < sk_ASN1_UTF8STRING_num(a->text); ++i) {
+		if (i > 0)
+			BIO_puts(bio, "\t");
+		ASN1_STRING_print_ex(bio, sk_ASN1_UTF8STRING_value(a->text, i),
+		    0);
+		BIO_puts(bio, "\n");
+	}
+	if (i == 0)
+		BIO_printf(bio, "unspecified\n");
+
+	/* Printing failure information. */
+	BIO_printf(bio, "Failure info: ");
+	if (a->failure_info != NULL)
+		lines = TS_status_map_print(bio, failure_map, a->failure_info);
+	if (lines == 0)
+		BIO_printf(bio, "unspecified");
+	BIO_printf(bio, "\n");
+
+	return 1;
+}
+
+static int
+TS_status_map_print(BIO *bio, struct status_map_st *a, ASN1_BIT_STRING *v)
+{
+	int lines = 0;
+
+	for (; a->bit >= 0; ++a) {
+		if (ASN1_BIT_STRING_get_bit(v, a->bit)) {
+			if (++lines > 1)
+				BIO_printf(bio, ", ");
+			BIO_printf(bio, "%s", a->text);
+		}
+	}
+
+	return lines;
+}
+
+int
+TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a)
+{
+	int v;
+	ASN1_OBJECT *policy_id;
+	const ASN1_INTEGER *serial;
+	const ASN1_GENERALIZEDTIME *gtime;
+	TS_ACCURACY *accuracy;
+	const ASN1_INTEGER *nonce;
+	GENERAL_NAME *tsa_name;
+
+	if (a == NULL)
+		return 0;
+
+	/* Print version. */
+	v = TS_TST_INFO_get_version(a);
+	BIO_printf(bio, "Version: %d\n", v);
+
+	/* Print policy id. */
+	BIO_printf(bio, "Policy OID: ");
+	policy_id = TS_TST_INFO_get_policy_id(a);
+	TS_OBJ_print_bio(bio, policy_id);
+
+	/* Print message imprint. */
+	TS_MSG_IMPRINT_print_bio(bio, TS_TST_INFO_get_msg_imprint(a));
+
+	/* Print serial number. */
+	BIO_printf(bio, "Serial number: ");
+	serial = TS_TST_INFO_get_serial(a);
+	if (serial == NULL)
+		BIO_printf(bio, "unspecified");
+	else
+		TS_ASN1_INTEGER_print_bio(bio, serial);
+	BIO_write(bio, "\n", 1);
+
+	/* Print time stamp. */
+	BIO_printf(bio, "Time stamp: ");
+	gtime = TS_TST_INFO_get_time(a);
+	ASN1_GENERALIZEDTIME_print(bio, gtime);
+	BIO_write(bio, "\n", 1);
+
+	/* Print accuracy. */
+	BIO_printf(bio, "Accuracy: ");
+	accuracy = TS_TST_INFO_get_accuracy(a);
+	if (accuracy == NULL)
+		BIO_printf(bio, "unspecified");
+	else
+		TS_ACCURACY_print_bio(bio, accuracy);
+	BIO_write(bio, "\n", 1);
+
+	/* Print ordering. */
+	BIO_printf(bio, "Ordering: %s\n",
+	    TS_TST_INFO_get_ordering(a) ? "yes" : "no");
+
+	/* Print nonce. */
+	BIO_printf(bio, "Nonce: ");
+	nonce = TS_TST_INFO_get_nonce(a);
+	if (nonce == NULL)
+		BIO_printf(bio, "unspecified");
+	else
+		TS_ASN1_INTEGER_print_bio(bio, nonce);
+	BIO_write(bio, "\n", 1);
+
+	/* Print TSA name. */
+	BIO_printf(bio, "TSA: ");
+	tsa_name = TS_TST_INFO_get_tsa(a);
+	if (tsa_name == NULL)
+		BIO_printf(bio, "unspecified");
+	else {
+		STACK_OF(CONF_VALUE) *nval;
+		if ((nval = i2v_GENERAL_NAME(NULL, tsa_name, NULL)))
+			X509V3_EXT_val_prn(bio, nval, 0, 0);
+		sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
+	}
+	BIO_write(bio, "\n", 1);
+
+	/* Print extensions. */
+	TS_ext_print_bio(bio, TS_TST_INFO_get_exts(a));
+
+	return 1;
+}
+
+static int
+TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy)
+{
+	const ASN1_INTEGER *seconds = TS_ACCURACY_get_seconds(accuracy);
+	const ASN1_INTEGER *millis = TS_ACCURACY_get_millis(accuracy);
+	const ASN1_INTEGER *micros = TS_ACCURACY_get_micros(accuracy);
+
+	if (seconds != NULL)
+		TS_ASN1_INTEGER_print_bio(bio, seconds);
+	else
+		BIO_printf(bio, "unspecified");
+	BIO_printf(bio, " seconds, ");
+	if (millis != NULL)
+		TS_ASN1_INTEGER_print_bio(bio, millis);
+	else
+		BIO_printf(bio, "unspecified");
+	BIO_printf(bio, " millis, ");
+	if (micros != NULL)
+		TS_ASN1_INTEGER_print_bio(bio, micros);
+	else
+		BIO_printf(bio, "unspecified");
+	BIO_printf(bio, " micros");
+
+	return 1;
+}
diff --git a/crypto/libressl/crypto/ts/ts_rsp_sign.c b/crypto/libressl/crypto/ts/ts_rsp_sign.c
new file mode 100644
index 0000000000..e16138d842
--- /dev/null
+++ b/crypto/libressl/crypto/ts/ts_rsp_sign.c
@@ -0,0 +1,1022 @@
+/* $OpenBSD: ts_rsp_sign.c,v 1.19 2015/09/30 18:04:02 jsing Exp $ */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+/* Private function declarations. */
+
+static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *);
+static int def_time_cb(struct TS_resp_ctx *, void *, time_t *sec, long *usec);
+static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *);
+
+static void TS_RESP_CTX_init(TS_RESP_CTX *ctx);
+static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx);
+static int TS_RESP_check_request(TS_RESP_CTX *ctx);
+static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx);
+static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx,
+    ASN1_OBJECT *policy);
+static int TS_RESP_process_extensions(TS_RESP_CTX *ctx);
+static int TS_RESP_sign(TS_RESP_CTX *ctx);
+
+static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert,
+    STACK_OF(X509) *certs);
+static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed);
+static int TS_TST_INFO_content_new(PKCS7 *p7);
+static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc);
+
+static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision(
+    ASN1_GENERALIZEDTIME *, time_t, long, unsigned);
+
+/* Default callbacks for response generation. */
+
+static ASN1_INTEGER *
+def_serial_cb(struct TS_resp_ctx *ctx, void *data)
+{
+	ASN1_INTEGER *serial = ASN1_INTEGER_new();
+
+	if (!serial)
+		goto err;
+	if (!ASN1_INTEGER_set(serial, 1))
+		goto err;
+	return serial;
+
+err:
+	TSerr(TS_F_DEF_SERIAL_CB, ERR_R_MALLOC_FAILURE);
+	TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+	    "Error during serial number generation.");
+	return NULL;
+}
+
+/* Use the gettimeofday function call. */
+static int
+def_time_cb(struct TS_resp_ctx *ctx, void *data, time_t *sec, long *usec)
+{
+	struct timeval tv;
+
+	if (gettimeofday(&tv, NULL) != 0) {
+		TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR);
+		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+		    "Time is not available.");
+		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
+		return 0;
+	}
+	/* Return time to caller. */
+	*sec = tv.tv_sec;
+	*usec = tv.tv_usec;
+
+	return 1;
+}
+
+static int
+def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext, void *data)
+{
+	/* No extensions are processed here. */
+	TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+	    "Unsupported extension.");
+	TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION);
+	return 0;
+}
+
+/* TS_RESP_CTX management functions. */
+
+TS_RESP_CTX *
+TS_RESP_CTX_new(void)
+{
+	TS_RESP_CTX *ctx;
+
+	if (!(ctx = calloc(1, sizeof(TS_RESP_CTX)))) {
+		TSerr(TS_F_TS_RESP_CTX_NEW, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+
+	/* Setting default callbacks. */
+	ctx->serial_cb = def_serial_cb;
+	ctx->time_cb = def_time_cb;
+	ctx->extension_cb = def_extension_cb;
+
+	return ctx;
+}
+
+void
+TS_RESP_CTX_free(TS_RESP_CTX *ctx)
+{
+	if (!ctx)
+		return;
+
+	X509_free(ctx->signer_cert);
+	EVP_PKEY_free(ctx->signer_key);
+	sk_X509_pop_free(ctx->certs, X509_free);
+	sk_ASN1_OBJECT_pop_free(ctx->policies, ASN1_OBJECT_free);
+	ASN1_OBJECT_free(ctx->default_policy);
+	sk_EVP_MD_free(ctx->mds);	/* No EVP_MD_free method exists. */
+	ASN1_INTEGER_free(ctx->seconds);
+	ASN1_INTEGER_free(ctx->millis);
+	ASN1_INTEGER_free(ctx->micros);
+	free(ctx);
+}
+
+int
+TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer)
+{
+	if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1) {
+		TSerr(TS_F_TS_RESP_CTX_SET_SIGNER_CERT,
+		    TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE);
+		return 0;
+	}
+	X509_free(ctx->signer_cert);
+	ctx->signer_cert = signer;
+	CRYPTO_add(&ctx->signer_cert->references, +1, CRYPTO_LOCK_X509);
+	return 1;
+}
+
+int
+TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key)
+{
+	EVP_PKEY_free(ctx->signer_key);
+	ctx->signer_key = key;
+	CRYPTO_add(&ctx->signer_key->references, +1, CRYPTO_LOCK_EVP_PKEY);
+
+	return 1;
+}
+
+int
+TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy)
+{
+	if (ctx->default_policy)
+		ASN1_OBJECT_free(ctx->default_policy);
+	if (!(ctx->default_policy = OBJ_dup(def_policy)))
+		goto err;
+	return 1;
+
+err:
+	TSerr(TS_F_TS_RESP_CTX_SET_DEF_POLICY, ERR_R_MALLOC_FAILURE);
+	return 0;
+}
+
+int
+TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs)
+{
+	int i;
+
+	if (ctx->certs) {
+		sk_X509_pop_free(ctx->certs, X509_free);
+		ctx->certs = NULL;
+	}
+	if (!certs)
+		return 1;
+	if (!(ctx->certs = sk_X509_dup(certs))) {
+		TSerr(TS_F_TS_RESP_CTX_SET_CERTS, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	for (i = 0; i < sk_X509_num(ctx->certs); ++i) {
+		X509 *cert = sk_X509_value(ctx->certs, i);
+		CRYPTO_add(&cert->references, +1, CRYPTO_LOCK_X509);
+	}
+
+	return 1;
+}
+
+int
+TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy)
+{
+	ASN1_OBJECT *copy = NULL;
+
+	/* Create new policy stack if necessary. */
+	if (!ctx->policies && !(ctx->policies = sk_ASN1_OBJECT_new_null()))
+		goto err;
+	if (!(copy = OBJ_dup(policy)))
+		goto err;
+	if (!sk_ASN1_OBJECT_push(ctx->policies, copy))
+		goto err;
+
+	return 1;
+
+err:
+	TSerr(TS_F_TS_RESP_CTX_ADD_POLICY, ERR_R_MALLOC_FAILURE);
+	ASN1_OBJECT_free(copy);
+	return 0;
+}
+
+int
+TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md)
+{
+	/* Create new md stack if necessary. */
+	if (!ctx->mds && !(ctx->mds = sk_EVP_MD_new_null()))
+		goto err;
+	/* Add the shared md, no copy needed. */
+	if (!sk_EVP_MD_push(ctx->mds, (EVP_MD *)md))
+		goto err;
+
+	return 1;
+
+err:
+	TSerr(TS_F_TS_RESP_CTX_ADD_MD, ERR_R_MALLOC_FAILURE);
+	return 0;
+}
+
+#define TS_RESP_CTX_accuracy_free(ctx)		\
+	ASN1_INTEGER_free(ctx->seconds);	\
+	ctx->seconds = NULL;			\
+	ASN1_INTEGER_free(ctx->millis);		\
+	ctx->millis = NULL;			\
+	ASN1_INTEGER_free(ctx->micros);		\
+	ctx->micros = NULL;
+
+int
+TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, int secs, int millis, int micros)
+{
+	TS_RESP_CTX_accuracy_free(ctx);
+	if (secs && (!(ctx->seconds = ASN1_INTEGER_new()) ||
+	    !ASN1_INTEGER_set(ctx->seconds, secs)))
+		goto err;
+	if (millis && (!(ctx->millis = ASN1_INTEGER_new()) ||
+	    !ASN1_INTEGER_set(ctx->millis, millis)))
+		goto err;
+	if (micros && (!(ctx->micros = ASN1_INTEGER_new()) ||
+	    !ASN1_INTEGER_set(ctx->micros, micros)))
+		goto err;
+
+	return 1;
+
+err:
+	TS_RESP_CTX_accuracy_free(ctx);
+	TSerr(TS_F_TS_RESP_CTX_SET_ACCURACY, ERR_R_MALLOC_FAILURE);
+	return 0;
+}
+
+void
+TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags)
+{
+	ctx->flags |= flags;
+}
+
+void
+TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data)
+{
+	ctx->serial_cb = cb;
+	ctx->serial_cb_data = data;
+}
+
+void
+TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, TS_extension_cb cb, void *data)
+{
+	ctx->extension_cb = cb;
+	ctx->extension_cb_data = data;
+}
+
+int
+TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, int status, const char *text)
+{
+	TS_STATUS_INFO *si = NULL;
+	ASN1_UTF8STRING *utf8_text = NULL;
+	int ret = 0;
+
+	if (!(si = TS_STATUS_INFO_new()))
+		goto err;
+	if (!ASN1_INTEGER_set(si->status, status))
+		goto err;
+	if (text) {
+		if (!(utf8_text = ASN1_UTF8STRING_new()) ||
+		    !ASN1_STRING_set(utf8_text, text, strlen(text)))
+			goto err;
+		if (!si->text && !(si->text = sk_ASN1_UTF8STRING_new_null()))
+			goto err;
+		if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text))
+			goto err;
+		utf8_text = NULL;	/* Ownership is lost. */
+	}
+	if (!TS_RESP_set_status_info(ctx->response, si))
+		goto err;
+	ret = 1;
+
+err:
+	if (!ret)
+		TSerr(TS_F_TS_RESP_CTX_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE);
+	TS_STATUS_INFO_free(si);
+	ASN1_UTF8STRING_free(utf8_text);
+	return ret;
+}
+
+int
+TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, int status, const char *text)
+{
+	int ret = 1;
+	TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response);
+
+	if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED) {
+		/* Status has not been set, set it now. */
+		ret = TS_RESP_CTX_set_status_info(ctx, status, text);
+	}
+	return ret;
+}
+
+int
+TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure)
+{
+	TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response);
+
+	if (!si->failure_info && !(si->failure_info = ASN1_BIT_STRING_new()))
+		goto err;
+	if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1))
+		goto err;
+	return 1;
+
+err:
+	TSerr(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO, ERR_R_MALLOC_FAILURE);
+	return 0;
+}
+
+TS_REQ *
+TS_RESP_CTX_get_request(TS_RESP_CTX *ctx)
+{
+	return ctx->request;
+}
+
+TS_TST_INFO *
+TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx)
+{
+	return ctx->tst_info;
+}
+
+int
+TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, unsigned precision)
+{
+	if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
+		return 0;
+	ctx->clock_precision_digits = precision;
+	return 1;
+}
+
+/* Main entry method of the response generation. */
+TS_RESP *
+TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio)
+{
+	ASN1_OBJECT *policy;
+	TS_RESP *response;
+	int result = 0;
+
+	TS_RESP_CTX_init(ctx);
+
+	/* Creating the response object. */
+	if (!(ctx->response = TS_RESP_new())) {
+		TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE);
+		goto end;
+	}
+
+	/* Parsing DER request. */
+	if (!(ctx->request = d2i_TS_REQ_bio(req_bio, NULL))) {
+		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+		    "Bad request format or "
+		    "system error.");
+		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
+		goto end;
+	}
+
+	/* Setting default status info. */
+	if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL))
+		goto end;
+
+	/* Checking the request format. */
+	if (!TS_RESP_check_request(ctx))
+		goto end;
+
+	/* Checking acceptable policies. */
+	if (!(policy = TS_RESP_get_policy(ctx)))
+		goto end;
+
+	/* Creating the TS_TST_INFO object. */
+	if (!(ctx->tst_info = TS_RESP_create_tst_info(ctx, policy)))
+		goto end;
+
+	/* Processing extensions. */
+	if (!TS_RESP_process_extensions(ctx))
+		goto end;
+
+	/* Generating the signature. */
+	if (!TS_RESP_sign(ctx))
+		goto end;
+
+	/* Everything was successful. */
+	result = 1;
+
+end:
+	if (!result) {
+		TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR);
+		if (ctx->response != NULL) {
+			if (TS_RESP_CTX_set_status_info_cond(ctx,
+			    TS_STATUS_REJECTION, "Error during response "
+			    "generation.") == 0) {
+				TS_RESP_free(ctx->response);
+				ctx->response = NULL;
+			}
+		}
+	}
+	response = ctx->response;
+	ctx->response = NULL;	/* Ownership will be returned to caller. */
+	TS_RESP_CTX_cleanup(ctx);
+	return response;
+}
+
+/* Initializes the variable part of the context. */
+static void
+TS_RESP_CTX_init(TS_RESP_CTX *ctx)
+{
+	ctx->request = NULL;
+	ctx->response = NULL;
+	ctx->tst_info = NULL;
+}
+
+/* Cleans up the variable part of the context. */
+static void
+TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx)
+{
+	TS_REQ_free(ctx->request);
+	ctx->request = NULL;
+	TS_RESP_free(ctx->response);
+	ctx->response = NULL;
+	TS_TST_INFO_free(ctx->tst_info);
+	ctx->tst_info = NULL;
+}
+
+/* Checks the format and content of the request. */
+static int
+TS_RESP_check_request(TS_RESP_CTX *ctx)
+{
+	TS_REQ *request = ctx->request;
+	TS_MSG_IMPRINT *msg_imprint;
+	X509_ALGOR *md_alg;
+	int md_alg_id;
+	const ASN1_OCTET_STRING *digest;
+	EVP_MD *md = NULL;
+	int i;
+
+	/* Checking request version. */
+	if (TS_REQ_get_version(request) != 1) {
+		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+		    "Bad request version.");
+		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_REQUEST);
+		return 0;
+	}
+
+	/* Checking message digest algorithm. */
+	msg_imprint = TS_REQ_get_msg_imprint(request);
+	md_alg = TS_MSG_IMPRINT_get_algo(msg_imprint);
+	md_alg_id = OBJ_obj2nid(md_alg->algorithm);
+	for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i) {
+		EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i);
+		if (md_alg_id == EVP_MD_type(current_md))
+			md = current_md;
+	}
+	if (!md) {
+		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+		    "Message digest algorithm is "
+		    "not supported.");
+		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
+		return 0;
+	}
+
+	/* No message digest takes parameter. */
+	if (md_alg->parameter &&
+	    ASN1_TYPE_get(md_alg->parameter) != V_ASN1_NULL) {
+		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+		    "Superfluous message digest "
+		    "parameter.");
+		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
+		return 0;
+	}
+	/* Checking message digest size. */
+	digest = TS_MSG_IMPRINT_get_msg(msg_imprint);
+	if (digest->length != EVP_MD_size(md)) {
+		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+		    "Bad message digest.");
+		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
+		return 0;
+	}
+
+	return 1;
+}
+
+/* Returns the TSA policy based on the requested and acceptable policies. */
+static ASN1_OBJECT *
+TS_RESP_get_policy(TS_RESP_CTX *ctx)
+{
+	ASN1_OBJECT *requested = TS_REQ_get_policy_id(ctx->request);
+	ASN1_OBJECT *policy = NULL;
+	int i;
+
+	if (ctx->default_policy == NULL) {
+		TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_INVALID_NULL_POINTER);
+		return NULL;
+	}
+	/* Return the default policy if none is requested or the default is
+	   requested. */
+	if (!requested || !OBJ_cmp(requested, ctx->default_policy))
+		policy = ctx->default_policy;
+
+	/* Check if the policy is acceptable. */
+	for (i = 0; !policy && i < sk_ASN1_OBJECT_num(ctx->policies); ++i) {
+		ASN1_OBJECT *current = sk_ASN1_OBJECT_value(ctx->policies, i);
+		if (!OBJ_cmp(requested, current))
+			policy = current;
+	}
+	if (!policy) {
+		TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_UNACCEPTABLE_POLICY);
+		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+		    "Requested policy is not "
+		    "supported.");
+		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY);
+	}
+	return policy;
+}
+
+/* Creates the TS_TST_INFO object based on the settings of the context. */
+static TS_TST_INFO *
+TS_RESP_create_tst_info(TS_RESP_CTX *ctx, ASN1_OBJECT *policy)
+{
+	int result = 0;
+	TS_TST_INFO *tst_info = NULL;
+	ASN1_INTEGER *serial = NULL;
+	ASN1_GENERALIZEDTIME *asn1_time = NULL;
+	time_t sec;
+	long usec;
+	TS_ACCURACY *accuracy = NULL;
+	const ASN1_INTEGER *nonce;
+	GENERAL_NAME *tsa_name = NULL;
+
+	if (!(tst_info = TS_TST_INFO_new()))
+		goto end;
+	if (!TS_TST_INFO_set_version(tst_info, 1))
+		goto end;
+	if (!TS_TST_INFO_set_policy_id(tst_info, policy))
+		goto end;
+	if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint))
+		goto end;
+	if (!(serial = (*ctx->serial_cb)(ctx, ctx->serial_cb_data)) ||
+	    !TS_TST_INFO_set_serial(tst_info, serial))
+		goto end;
+	if (!(*ctx->time_cb)(ctx, ctx->time_cb_data, &sec, &usec) ||
+	    !(asn1_time = TS_RESP_set_genTime_with_precision(NULL, sec, usec,
+	    ctx->clock_precision_digits)) ||
+	    !TS_TST_INFO_set_time(tst_info, asn1_time))
+		goto end;
+
+	/* Setting accuracy if needed. */
+	if ((ctx->seconds || ctx->millis || ctx->micros) &&
+	    !(accuracy = TS_ACCURACY_new()))
+		goto end;
+
+	if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds))
+		goto end;
+	if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis))
+		goto end;
+	if (ctx->micros && !TS_ACCURACY_set_micros(accuracy, ctx->micros))
+		goto end;
+	if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy))
+		goto end;
+
+	/* Setting ordering. */
+	if ((ctx->flags & TS_ORDERING) &&
+	    !TS_TST_INFO_set_ordering(tst_info, 1))
+		goto end;
+
+	/* Setting nonce if needed. */
+	if ((nonce = TS_REQ_get_nonce(ctx->request)) != NULL &&
+	    !TS_TST_INFO_set_nonce(tst_info, nonce))
+		goto end;
+
+	/* Setting TSA name to subject of signer certificate. */
+	if (ctx->flags & TS_TSA_NAME) {
+		if (!(tsa_name = GENERAL_NAME_new()))
+			goto end;
+		tsa_name->type = GEN_DIRNAME;
+		tsa_name->d.dirn =
+		    X509_NAME_dup(ctx->signer_cert->cert_info->subject);
+		if (!tsa_name->d.dirn)
+			goto end;
+		if (!TS_TST_INFO_set_tsa(tst_info, tsa_name))
+			goto end;
+	}
+
+	result = 1;
+
+end:
+	if (!result) {
+		TS_TST_INFO_free(tst_info);
+		tst_info = NULL;
+		TSerr(TS_F_TS_RESP_CREATE_TST_INFO, TS_R_TST_INFO_SETUP_ERROR);
+		TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
+		    "Error during TSTInfo "
+		    "generation.");
+	}
+	GENERAL_NAME_free(tsa_name);
+	TS_ACCURACY_free(accuracy);
+	ASN1_GENERALIZEDTIME_free(asn1_time);
+	ASN1_INTEGER_free(serial);
+
+	return tst_info;
+}
+
+/* Processing the extensions of the request. */
+static int
+TS_RESP_process_extensions(TS_RESP_CTX *ctx)
+{
+	STACK_OF(X509_EXTENSION) *exts = TS_REQ_get_exts(ctx->request);
+	int i;
+	int ok = 1;
+
+	for (i = 0; ok && i < sk_X509_EXTENSION_num(exts); ++i) {
+		X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
+		/* XXXXX The last argument was previously
+		   (void *)ctx->extension_cb, but ISO C doesn't permit
+		   converting a function pointer to void *.  For lack of
+		   better information, I'm placing a NULL there instead.
+		   The callback can pick its own address out from the ctx
+		   anyway...
+		*/
+		ok = (*ctx->extension_cb)(ctx, ext, NULL);
+	}
+
+	return ok;
+}
+
+/* Functions for signing the TS_TST_INFO structure of the context. */
+static int
+TS_RESP_sign(TS_RESP_CTX *ctx)
+{
+	int ret = 0;
+	PKCS7 *p7 = NULL;
+	PKCS7_SIGNER_INFO *si;
+	STACK_OF(X509) *certs;	/* Certificates to include in sc. */
+	ESS_SIGNING_CERT *sc = NULL;
+	ASN1_OBJECT *oid;
+	BIO *p7bio = NULL;
+	int i;
+
+	/* Check if signcert and pkey match. */
+	if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) {
+		TSerr(TS_F_TS_RESP_SIGN,
+		    TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+		goto err;
+	}
+
+	/* Create a new PKCS7 signed object. */
+	if (!(p7 = PKCS7_new())) {
+		TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	if (!PKCS7_set_type(p7, NID_pkcs7_signed))
+		goto err;
+
+	/* Force SignedData version to be 3 instead of the default 1. */
+	if (!ASN1_INTEGER_set(p7->d.sign->version, 3))
+		goto err;
+
+	/* Add signer certificate and optional certificate chain. */
+	if (TS_REQ_get_cert_req(ctx->request)) {
+		PKCS7_add_certificate(p7, ctx->signer_cert);
+		if (ctx->certs) {
+			for (i = 0; i < sk_X509_num(ctx->certs); ++i) {
+				X509 *cert = sk_X509_value(ctx->certs, i);
+				PKCS7_add_certificate(p7, cert);
+			}
+		}
+	}
+
+	/* Add a new signer info. */
+	if (!(si = PKCS7_add_signature(p7, ctx->signer_cert,
+	    ctx->signer_key, EVP_sha1()))) {
+		TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNATURE_ERROR);
+		goto err;
+	}
+
+	/* Add content type signed attribute to the signer info. */
+	oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
+	if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
+	    V_ASN1_OBJECT, oid)) {
+		TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR);
+		goto err;
+	}
+
+	/* Create the ESS SigningCertificate attribute which contains
+	   the signer certificate id and optionally the certificate chain. */
+	certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL;
+	if (!(sc = ESS_SIGNING_CERT_new_init(ctx->signer_cert, certs)))
+		goto err;
+
+	/* Add SigningCertificate signed attribute to the signer info. */
+	if (!ESS_add_signing_cert(si, sc)) {
+		TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR);
+		goto err;
+	}
+
+	/* Add a new empty NID_id_smime_ct_TSTInfo encapsulated content. */
+	if (!TS_TST_INFO_content_new(p7))
+		goto err;
+
+	/* Add the DER encoded tst_info to the PKCS7 structure. */
+	if (!(p7bio = PKCS7_dataInit(p7, NULL))) {
+		TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	/* Convert tst_info to DER. */
+	if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info)) {
+		TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
+		goto err;
+	}
+
+	/* Create the signature and add it to the signer info. */
+	if (!PKCS7_dataFinal(p7, p7bio)) {
+		TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
+		goto err;
+	}
+
+	/* Set new PKCS7 and TST_INFO objects. */
+	TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info);
+	p7 = NULL;		/* Ownership is lost. */
+	ctx->tst_info = NULL;	/* Ownership is lost. */
+
+	ret = 1;
+
+err:
+	if (!ret)
+		TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
+	    "Error during signature "
+	    "generation.");
+	BIO_free_all(p7bio);
+	ESS_SIGNING_CERT_free(sc);
+	PKCS7_free(p7);
+	return ret;
+}
+
+static ESS_SIGNING_CERT *
+ESS_SIGNING_CERT_new_init(X509 *signcert, STACK_OF(X509) *certs)
+{
+	ESS_CERT_ID *cid;
+	ESS_SIGNING_CERT *sc = NULL;
+	int i;
+
+	/* Creating the ESS_CERT_ID stack. */
+	if (!(sc = ESS_SIGNING_CERT_new()))
+		goto err;
+	if (!sc->cert_ids && !(sc->cert_ids = sk_ESS_CERT_ID_new_null()))
+		goto err;
+
+	/* Adding the signing certificate id. */
+	if (!(cid = ESS_CERT_ID_new_init(signcert, 0)) ||
+	    !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
+		goto err;
+	/* Adding the certificate chain ids. */
+	for (i = 0; i < sk_X509_num(certs); ++i) {
+		X509 *cert = sk_X509_value(certs, i);
+		if (!(cid = ESS_CERT_ID_new_init(cert, 1)) ||
+		    !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
+			goto err;
+	}
+
+	return sc;
+
+err:
+	ESS_SIGNING_CERT_free(sc);
+	TSerr(TS_F_ESS_SIGNING_CERT_NEW_INIT, ERR_R_MALLOC_FAILURE);
+	return NULL;
+}
+
+static ESS_CERT_ID *
+ESS_CERT_ID_new_init(X509 *cert, int issuer_needed)
+{
+	ESS_CERT_ID *cid = NULL;
+	GENERAL_NAME *name = NULL;
+
+	/* Recompute SHA1 hash of certificate if necessary (side effect). */
+	X509_check_purpose(cert, -1, 0);
+
+	if (!(cid = ESS_CERT_ID_new()))
+		goto err;
+	if (!ASN1_OCTET_STRING_set(cid->hash, cert->sha1_hash,
+	    sizeof(cert->sha1_hash)))
+		goto err;
+
+	/* Setting the issuer/serial if requested. */
+	if (issuer_needed) {
+		/* Creating issuer/serial structure. */
+		if (!cid->issuer_serial &&
+		    !(cid->issuer_serial = ESS_ISSUER_SERIAL_new()))
+			goto err;
+		/* Creating general name from the certificate issuer. */
+		if (!(name = GENERAL_NAME_new()))
+			goto err;
+		name->type = GEN_DIRNAME;
+		if (!(name->d.dirn = X509_NAME_dup(cert->cert_info->issuer)))
+			goto err;
+		if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name))
+			goto err;
+		name = NULL;	/* Ownership is lost. */
+		/* Setting the serial number. */
+		ASN1_INTEGER_free(cid->issuer_serial->serial);
+		if (!(cid->issuer_serial->serial =
+		    ASN1_INTEGER_dup(cert->cert_info->serialNumber)))
+			goto err;
+	}
+
+	return cid;
+
+err:
+	GENERAL_NAME_free(name);
+	ESS_CERT_ID_free(cid);
+	TSerr(TS_F_ESS_CERT_ID_NEW_INIT, ERR_R_MALLOC_FAILURE);
+	return NULL;
+}
+
+static int
+TS_TST_INFO_content_new(PKCS7 *p7)
+{
+	PKCS7 *ret = NULL;
+	ASN1_OCTET_STRING *octet_string = NULL;
+
+	/* Create new encapsulated NID_id_smime_ct_TSTInfo content. */
+	if (!(ret = PKCS7_new()))
+		goto err;
+	if (!(ret->d.other = ASN1_TYPE_new()))
+		goto err;
+	ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
+	if (!(octet_string = ASN1_OCTET_STRING_new()))
+		goto err;
+	ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string);
+	octet_string = NULL;
+
+	/* Add encapsulated content to signed PKCS7 structure. */
+	if (!PKCS7_set_content(p7, ret))
+		goto err;
+
+	return 1;
+
+err:
+	ASN1_OCTET_STRING_free(octet_string);
+	PKCS7_free(ret);
+	return 0;
+}
+
+static int
+ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc)
+{
+	ASN1_STRING *seq = NULL;
+	unsigned char *p, *pp = NULL;
+	int len;
+
+	len = i2d_ESS_SIGNING_CERT(sc, NULL);
+	if (!(pp = malloc(len))) {
+		TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	p = pp;
+	i2d_ESS_SIGNING_CERT(sc, &p);
+	if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len)) {
+		TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+	free(pp);
+	pp = NULL;
+	return PKCS7_add_signed_attribute(si,
+	    NID_id_smime_aa_signingCertificate, V_ASN1_SEQUENCE, seq);
+
+err:
+	ASN1_STRING_free(seq);
+	free(pp);
+
+	return 0;
+}
+
+
+static ASN1_GENERALIZEDTIME *
+TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time,
+    time_t sec, long usec, unsigned precision)
+{
+	struct tm *tm = NULL;
+	char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS];
+	char usecstr[TS_MAX_CLOCK_PRECISION_DIGITS + 2];
+	char *p;
+	int rv;
+
+	if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
+		goto err;
+
+	if (!(tm = gmtime(&sec)))
+		goto err;
+
+	/*
+	 * Put "genTime_str" in GeneralizedTime format.  We work around the
+	 * restrictions imposed by rfc3280 (i.e. "GeneralizedTime values MUST
+	 * NOT include fractional seconds") and OpenSSL related functions to
+	 * meet the rfc3161 requirement: "GeneralizedTime syntax can include
+	 * fraction-of-second details".
+	 */
+	if (precision > 0) {
+		/* To make things a bit harder, X.690 | ISO/IEC 8825-1 provides
+		   the following restrictions for a DER-encoding, which OpenSSL
+		   (specifically ASN1_GENERALIZEDTIME_check() function) doesn't
+		   support:
+		   "The encoding MUST terminate with a "Z" (which means "Zulu"
+		   time). The decimal point element, if present, MUST be the
+		   point option ".". The fractional-seconds elements,
+		   if present, MUST omit all trailing 0's;
+		   if the elements correspond to 0, they MUST be wholly
+		   omitted, and the decimal point element also MUST be
+		   omitted." */
+		(void) snprintf(usecstr, sizeof(usecstr), ".%06ld", usec);
+		/* truncate and trim trailing 0 */
+		usecstr[precision + 1] = '\0';
+		p = usecstr + strlen(usecstr) - 1;
+		while (p > usecstr && *p == '0')
+			*p-- = '\0';
+		/* if we've reached the beginning, delete the . too */
+		if (p == usecstr)
+			*p = '\0';
+
+	} else {
+		/* empty */
+		usecstr[0] = '\0';
+	}
+	rv = snprintf(genTime_str, sizeof(genTime_str),
+	    "%04d%02d%02d%02d%02d%02d%sZ",
+	    tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+	    tm->tm_hour, tm->tm_min, tm->tm_sec, usecstr);
+	if (rv == -1 || rv >= sizeof(genTime_str))
+		goto err;
+
+	/* Now call OpenSSL to check and set our genTime value */
+	if (!asn1_time && !(asn1_time = ASN1_GENERALIZEDTIME_new()))
+		goto err;
+	if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str)) {
+		ASN1_GENERALIZEDTIME_free(asn1_time);
+		goto err;
+	}
+
+	return asn1_time;
+
+err:
+	TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, TS_R_COULD_NOT_SET_TIME);
+	return NULL;
+}
diff --git a/crypto/libressl/crypto/ts/ts_rsp_utils.c b/crypto/libressl/crypto/ts/ts_rsp_utils.c
new file mode 100644
index 0000000000..6ff96ed780
--- /dev/null
+++ b/crypto/libressl/crypto/ts/ts_rsp_utils.c
@@ -0,0 +1,436 @@
+/* $OpenBSD: ts_rsp_utils.c,v 1.4 2014/07/11 08:44:49 jsing Exp $ */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+/* Function definitions. */
+
+int
+TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *status_info)
+{
+	TS_STATUS_INFO *new_status_info;
+
+	if (a->status_info == status_info)
+		return 1;
+	new_status_info = TS_STATUS_INFO_dup(status_info);
+	if (new_status_info == NULL) {
+		TSerr(TS_F_TS_RESP_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	TS_STATUS_INFO_free(a->status_info);
+	a->status_info = new_status_info;
+
+	return 1;
+}
+
+TS_STATUS_INFO *
+TS_RESP_get_status_info(TS_RESP *a)
+{
+	return a->status_info;
+}
+
+/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */
+void
+TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info)
+{
+	/* Set new PKCS7 and TST_INFO objects. */
+	PKCS7_free(a->token);
+	a->token = p7;
+	TS_TST_INFO_free(a->tst_info);
+	a->tst_info = tst_info;
+}
+
+PKCS7 *
+TS_RESP_get_token(TS_RESP *a)
+{
+	return a->token;
+}
+
+TS_TST_INFO *
+TS_RESP_get_tst_info(TS_RESP *a)
+{
+	return a->tst_info;
+}
+
+int
+TS_TST_INFO_set_version(TS_TST_INFO *a, long version)
+{
+	return ASN1_INTEGER_set(a->version, version);
+}
+
+long
+TS_TST_INFO_get_version(const TS_TST_INFO *a)
+{
+	return ASN1_INTEGER_get(a->version);
+}
+
+int
+TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy)
+{
+	ASN1_OBJECT *new_policy;
+
+	if (a->policy_id == policy)
+		return 1;
+	new_policy = OBJ_dup(policy);
+	if (new_policy == NULL) {
+		TSerr(TS_F_TS_TST_INFO_SET_POLICY_ID, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	ASN1_OBJECT_free(a->policy_id);
+	a->policy_id = new_policy;
+	return 1;
+}
+
+ASN1_OBJECT *
+TS_TST_INFO_get_policy_id(TS_TST_INFO *a)
+{
+	return a->policy_id;
+}
+
+int
+TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint)
+{
+	TS_MSG_IMPRINT *new_msg_imprint;
+
+	if (a->msg_imprint == msg_imprint)
+		return 1;
+	new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint);
+	if (new_msg_imprint == NULL) {
+		TSerr(TS_F_TS_TST_INFO_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	TS_MSG_IMPRINT_free(a->msg_imprint);
+	a->msg_imprint = new_msg_imprint;
+	return 1;
+}
+
+TS_MSG_IMPRINT *
+TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a)
+{
+	return a->msg_imprint;
+}
+
+int
+TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial)
+{
+	ASN1_INTEGER *new_serial;
+
+	if (a->serial == serial)
+		return 1;
+	new_serial = ASN1_INTEGER_dup(serial);
+	if (new_serial == NULL) {
+		TSerr(TS_F_TS_TST_INFO_SET_SERIAL, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	ASN1_INTEGER_free(a->serial);
+	a->serial = new_serial;
+	return 1;
+}
+
+const ASN1_INTEGER *
+TS_TST_INFO_get_serial(const TS_TST_INFO *a)
+{
+	return a->serial;
+}
+
+int
+TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime)
+{
+	ASN1_GENERALIZEDTIME *new_time;
+
+	if (a->time == gtime)
+		return 1;
+	new_time = ASN1_STRING_dup(gtime);
+	if (new_time == NULL) {
+		TSerr(TS_F_TS_TST_INFO_SET_TIME, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	ASN1_GENERALIZEDTIME_free(a->time);
+	a->time = new_time;
+	return 1;
+}
+
+const ASN1_GENERALIZEDTIME *
+TS_TST_INFO_get_time(const TS_TST_INFO *a)
+{
+	return a->time;
+}
+
+int
+TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy)
+{
+	TS_ACCURACY *new_accuracy;
+
+	if (a->accuracy == accuracy)
+		return 1;
+	new_accuracy = TS_ACCURACY_dup(accuracy);
+	if (new_accuracy == NULL) {
+		TSerr(TS_F_TS_TST_INFO_SET_ACCURACY, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	TS_ACCURACY_free(a->accuracy);
+	a->accuracy = new_accuracy;
+	return 1;
+}
+
+TS_ACCURACY *
+TS_TST_INFO_get_accuracy(TS_TST_INFO *a)
+{
+	return a->accuracy;
+}
+
+int
+TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds)
+{
+	ASN1_INTEGER *new_seconds;
+
+	if (a->seconds == seconds)
+		return 1;
+	new_seconds = ASN1_INTEGER_dup(seconds);
+	if (new_seconds == NULL) {
+		TSerr(TS_F_TS_ACCURACY_SET_SECONDS, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	ASN1_INTEGER_free(a->seconds);
+	a->seconds = new_seconds;
+	return 1;
+}
+
+const ASN1_INTEGER *
+TS_ACCURACY_get_seconds(const TS_ACCURACY *a)
+{
+	return a->seconds;
+}
+
+int
+TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis)
+{
+	ASN1_INTEGER *new_millis = NULL;
+
+	if (a->millis == millis)
+		return 1;
+	if (millis != NULL) {
+		new_millis = ASN1_INTEGER_dup(millis);
+		if (new_millis == NULL) {
+			TSerr(TS_F_TS_ACCURACY_SET_MILLIS,
+			    ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+	}
+	ASN1_INTEGER_free(a->millis);
+	a->millis = new_millis;
+	return 1;
+}
+
+const ASN1_INTEGER *
+TS_ACCURACY_get_millis(const TS_ACCURACY *a)
+{
+	return a->millis;
+}
+
+int
+TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros)
+{
+	ASN1_INTEGER *new_micros = NULL;
+
+	if (a->micros == micros)
+		return 1;
+	if (micros != NULL) {
+		new_micros = ASN1_INTEGER_dup(micros);
+		if (new_micros == NULL) {
+			TSerr(TS_F_TS_ACCURACY_SET_MICROS,
+			    ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+	}
+	ASN1_INTEGER_free(a->micros);
+	a->micros = new_micros;
+	return 1;
+}
+
+const ASN1_INTEGER *
+TS_ACCURACY_get_micros(const TS_ACCURACY *a)
+{
+	return a->micros;
+}
+
+int
+TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering)
+{
+	a->ordering = ordering ? 0xFF : 0x00;
+	return 1;
+}
+
+int
+TS_TST_INFO_get_ordering(const TS_TST_INFO *a)
+{
+	return a->ordering ? 1 : 0;
+}
+
+int
+TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce)
+{
+	ASN1_INTEGER *new_nonce;
+
+	if (a->nonce == nonce)
+		return 1;
+	new_nonce = ASN1_INTEGER_dup(nonce);
+	if (new_nonce == NULL) {
+		TSerr(TS_F_TS_TST_INFO_SET_NONCE, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	ASN1_INTEGER_free(a->nonce);
+	a->nonce = new_nonce;
+	return 1;
+}
+
+const ASN1_INTEGER *
+TS_TST_INFO_get_nonce(const TS_TST_INFO *a)
+{
+	return a->nonce;
+}
+
+int
+TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa)
+{
+	GENERAL_NAME *new_tsa;
+
+	if (a->tsa == tsa)
+		return 1;
+	new_tsa = GENERAL_NAME_dup(tsa);
+	if (new_tsa == NULL) {
+		TSerr(TS_F_TS_TST_INFO_SET_TSA, ERR_R_MALLOC_FAILURE);
+		return 0;
+	}
+	GENERAL_NAME_free(a->tsa);
+	a->tsa = new_tsa;
+	return 1;
+}
+
+GENERAL_NAME *
+TS_TST_INFO_get_tsa(TS_TST_INFO *a)
+{
+	return a->tsa;
+}
+
+STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a)
+{
+	return a->extensions;
+}
+
+void
+TS_TST_INFO_ext_free(TS_TST_INFO *a)
+{
+	if (!a)
+		return;
+	sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free);
+	a->extensions = NULL;
+}
+
+int
+TS_TST_INFO_get_ext_count(TS_TST_INFO *a)
+{
+	return X509v3_get_ext_count(a->extensions);
+}
+
+int
+TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos)
+{
+	return X509v3_get_ext_by_NID(a->extensions, nid, lastpos);
+}
+
+int
+TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos)
+{
+	return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos);
+}
+
+int
+TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos)
+{
+	return X509v3_get_ext_by_critical(a->extensions, crit, lastpos);
+}
+
+X509_EXTENSION *
+TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc)
+{
+	return X509v3_get_ext(a->extensions, loc);
+}
+
+X509_EXTENSION *
+TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc)
+{
+	return X509v3_delete_ext(a->extensions, loc);
+}
+
+int
+TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc)
+{
+	return X509v3_add_ext(&a->extensions, ex, loc) != NULL;
+}
+
+void *
+TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx)
+{
+	return X509V3_get_d2i(a->extensions, nid, crit, idx);
+}
diff --git a/crypto/libressl/crypto/ts/ts_rsp_verify.c b/crypto/libressl/crypto/ts/ts_rsp_verify.c
new file mode 100644
index 0000000000..cf1705cc0c
--- /dev/null
+++ b/crypto/libressl/crypto/ts/ts_rsp_verify.c
@@ -0,0 +1,745 @@
+/* $OpenBSD: ts_rsp_verify.c,v 1.15 2015/07/19 05:42:55 miod Exp $ */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+/* Private function declarations. */
+
+static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
+    X509 *signer, STACK_OF(X509) **chain);
+static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain);
+static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si);
+static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert);
+static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo);
+static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx,
+    PKCS7 *token, TS_TST_INFO *tst_info);
+static int TS_check_status_info(TS_RESP *response);
+static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text);
+static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info);
+static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
+    X509_ALGOR **md_alg,
+    unsigned char **imprint, unsigned *imprint_len);
+static int TS_check_imprints(X509_ALGOR *algor_a,
+    unsigned char *imprint_a, unsigned len_a,
+    TS_TST_INFO *tst_info);
+static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info);
+static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer);
+static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name);
+
+/*
+ * Local mapping between response codes and descriptions.
+ * Don't forget to change TS_STATUS_BUF_SIZE when modifying
+ * the elements of this array.
+ */
+static const char *TS_status_text[] = {
+	"granted",
+	"grantedWithMods",
+	"rejection",
+	"waiting",
+	"revocationWarning",
+	"revocationNotification"
+};
+
+#define TS_STATUS_TEXT_SIZE	(sizeof(TS_status_text)/sizeof(*TS_status_text))
+
+/*
+ * This must be greater or equal to the sum of the strings in TS_status_text
+ * plus the number of its elements.
+ */
+#define TS_STATUS_BUF_SIZE	256
+
+static struct {
+	int code;
+	const char *text;
+} TS_failure_info[] = {
+	{ TS_INFO_BAD_ALG, "badAlg" },
+	{ TS_INFO_BAD_REQUEST, "badRequest" },
+	{ TS_INFO_BAD_DATA_FORMAT, "badDataFormat" },
+	{ TS_INFO_TIME_NOT_AVAILABLE, "timeNotAvailable" },
+	{ TS_INFO_UNACCEPTED_POLICY, "unacceptedPolicy" },
+	{ TS_INFO_UNACCEPTED_EXTENSION, "unacceptedExtension" },
+	{ TS_INFO_ADD_INFO_NOT_AVAILABLE, "addInfoNotAvailable" },
+	{ TS_INFO_SYSTEM_FAILURE, "systemFailure" }
+};
+
+#define TS_FAILURE_INFO_SIZE	(sizeof(TS_failure_info) / \
+				sizeof(*TS_failure_info))
+
+/* Functions for verifying a signed TS_TST_INFO structure. */
+
+/*
+ * This function carries out the following tasks:
+ *	- Checks if there is one and only one signer.
+ *	- Search for the signing certificate in 'certs' and in the response.
+ *	- Check the extended key usage and key usage fields of the signer
+ *	certificate (done by the path validation).
+ *	- Build and validate the certificate path.
+ *	- Check if the certificate path meets the requirements of the
+ *	SigningCertificate ESS signed attribute.
+ *	- Verify the signature value.
+ *	- Returns the signer certificate in 'signer', if 'signer' is not NULL.
+ */
+int
+TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
+    X509_STORE *store, X509 **signer_out)
+{
+	STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL;
+	PKCS7_SIGNER_INFO *si;
+	STACK_OF(X509) *signers = NULL;
+	X509	*signer;
+	STACK_OF(X509) *chain = NULL;
+	char	buf[4096];
+	int	i, j = 0, ret = 0;
+	BIO	*p7bio = NULL;
+
+	/* Some sanity checks first. */
+	if (!token) {
+		TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_INVALID_NULL_POINTER);
+		goto err;
+	}
+
+	/* Check for the correct content type */
+	if (!PKCS7_type_is_signed(token)) {
+		TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_WRONG_CONTENT_TYPE);
+		goto err;
+	}
+
+	/* Check if there is one and only one signer. */
+	sinfos = PKCS7_get_signer_info(token);
+	if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos) != 1) {
+		TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE,
+		    TS_R_THERE_MUST_BE_ONE_SIGNER);
+		goto err;
+	}
+	si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0);
+
+	/* Check for no content: no data to verify signature. */
+	if (PKCS7_get_detached(token)) {
+		TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_NO_CONTENT);
+		goto err;
+	}
+
+	/* Get hold of the signer certificate, search only internal
+	   certificates if it was requested. */
+	signers = PKCS7_get0_signers(token, certs, 0);
+	if (!signers || sk_X509_num(signers) != 1)
+		goto err;
+	signer = sk_X509_value(signers, 0);
+
+	/* Now verify the certificate. */
+	if (!TS_verify_cert(store, certs, signer, &chain))
+		goto err;
+
+	/* Check if the signer certificate is consistent with the
+	   ESS extension. */
+	if (!TS_check_signing_certs(si, chain))
+		goto err;
+
+	/* Creating the message digest. */
+	p7bio = PKCS7_dataInit(token, NULL);
+
+	/* We now have to 'read' from p7bio to calculate digests etc. */
+	while ((i = BIO_read(p7bio, buf, sizeof(buf))) > 0)
+		;
+
+	/* Verifying the signature. */
+	j = PKCS7_signatureVerify(p7bio, token, si, signer);
+	if (j <= 0) {
+		TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_SIGNATURE_FAILURE);
+		goto err;
+	}
+
+	/* Return the signer certificate if needed. */
+	if (signer_out) {
+		*signer_out = signer;
+		CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
+	}
+
+	ret = 1;
+
+err:
+	BIO_free_all(p7bio);
+	sk_X509_pop_free(chain, X509_free);
+	sk_X509_free(signers);
+
+	return ret;
+}
+
+/*
+ * The certificate chain is returned in chain. Caller is responsible for
+ * freeing the vector.
+ */
+static int
+TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, X509 *signer,
+    STACK_OF(X509) **chain)
+{
+	X509_STORE_CTX cert_ctx;
+	int i;
+	int ret = 0;
+
+	/* chain is an out argument. */
+	*chain = NULL;
+	if (X509_STORE_CTX_init(&cert_ctx, store, signer, untrusted) == 0) {
+		TSerr(TS_F_TS_VERIFY_CERT, ERR_R_X509_LIB);
+		goto err;
+	}
+	X509_STORE_CTX_set_purpose(&cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN);
+	i = X509_verify_cert(&cert_ctx);
+	if (i <= 0) {
+		int j = X509_STORE_CTX_get_error(&cert_ctx);
+
+		TSerr(TS_F_TS_VERIFY_CERT, TS_R_CERTIFICATE_VERIFY_ERROR);
+		ERR_asprintf_error_data("Verify error:%s",
+		    X509_verify_cert_error_string(j));
+		goto err;
+	} else {
+		/* Get a copy of the certificate chain. */
+		*chain = X509_STORE_CTX_get1_chain(&cert_ctx);
+		ret = 1;
+	}
+
+err:
+	X509_STORE_CTX_cleanup(&cert_ctx);
+
+	return ret;
+}
+
+static int
+TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain)
+{
+	ESS_SIGNING_CERT *ss = ESS_get_signing_cert(si);
+	STACK_OF(ESS_CERT_ID) *cert_ids = NULL;
+	X509 *cert;
+	int i = 0;
+	int ret = 0;
+
+	if (!ss)
+		goto err;
+	cert_ids = ss->cert_ids;
+	/* The signer certificate must be the first in cert_ids. */
+	cert = sk_X509_value(chain, 0);
+	if (TS_find_cert(cert_ids, cert) != 0)
+		goto err;
+
+	/* Check the other certificates of the chain if there are more
+	   than one certificate ids in cert_ids. */
+	if (sk_ESS_CERT_ID_num(cert_ids) > 1) {
+		/* All the certificates of the chain must be in cert_ids. */
+		for (i = 1; i < sk_X509_num(chain); ++i) {
+			cert = sk_X509_value(chain, i);
+			if (TS_find_cert(cert_ids, cert) < 0)
+				goto err;
+		}
+	}
+	ret = 1;
+
+err:
+	if (!ret)
+		TSerr(TS_F_TS_CHECK_SIGNING_CERTS,
+		    TS_R_ESS_SIGNING_CERTIFICATE_ERROR);
+	ESS_SIGNING_CERT_free(ss);
+	return ret;
+}
+
+static ESS_SIGNING_CERT *
+ESS_get_signing_cert(PKCS7_SIGNER_INFO *si)
+{
+	ASN1_TYPE *attr;
+	const unsigned char *p;
+
+	attr = PKCS7_get_signed_attribute(si,
+	    NID_id_smime_aa_signingCertificate);
+	if (!attr)
+		return NULL;
+	if (attr->type != V_ASN1_SEQUENCE)
+		return NULL;
+	p = attr->value.sequence->data;
+	return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length);
+}
+
+/* Returns < 0 if certificate is not found, certificate index otherwise. */
+static int
+TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert)
+{
+	int i;
+
+	if (!cert_ids || !cert)
+		return -1;
+
+	/* Recompute SHA1 hash of certificate if necessary (side effect). */
+	X509_check_purpose(cert, -1, 0);
+
+	/* Look for cert in the cert_ids vector. */
+	for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) {
+		ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i);
+
+		/* Check the SHA-1 hash first. */
+		if (cid->hash->length == sizeof(cert->sha1_hash) &&
+		    !memcmp(cid->hash->data, cert->sha1_hash,
+			sizeof(cert->sha1_hash))) {
+			/* Check the issuer/serial as well if specified. */
+			ESS_ISSUER_SERIAL *is = cid->issuer_serial;
+			if (!is || !TS_issuer_serial_cmp(is, cert->cert_info))
+				return i;
+		}
+	}
+
+	return -1;
+}
+
+static int
+TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo)
+{
+	GENERAL_NAME *issuer;
+
+	if (!is || !cinfo || sk_GENERAL_NAME_num(is->issuer) != 1)
+		return -1;
+
+	/* Check the issuer first. It must be a directory name. */
+	issuer = sk_GENERAL_NAME_value(is->issuer, 0);
+	if (issuer->type != GEN_DIRNAME ||
+	    X509_NAME_cmp(issuer->d.dirn, cinfo->issuer))
+		return -1;
+
+	/* Check the serial number, too. */
+	if (ASN1_INTEGER_cmp(is->serial, cinfo->serialNumber))
+		return -1;
+
+	return 0;
+}
+
+/*
+ * Verifies whether 'response' contains a valid response with regards
+ * to the settings of the context:
+ *	- Gives an error message if the TS_TST_INFO is not present.
+ *	- Calls _TS_RESP_verify_token to verify the token content.
+ */
+int
+TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response)
+{
+	PKCS7 *token = TS_RESP_get_token(response);
+	TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response);
+	int ret = 0;
+
+	/* Check if we have a successful TS_TST_INFO object in place. */
+	if (!TS_check_status_info(response))
+		goto err;
+
+	/* Check the contents of the time stamp token. */
+	if (!int_TS_RESP_verify_token(ctx, token, tst_info))
+		goto err;
+
+	ret = 1;
+
+err:
+	return ret;
+}
+
+/*
+ * Tries to extract a TS_TST_INFO structure from the PKCS7 token and
+ * calls the internal int_TS_RESP_verify_token function for verifying it.
+ */
+int
+TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token)
+{
+	TS_TST_INFO *tst_info = PKCS7_to_TS_TST_INFO(token);
+	int ret = 0;
+
+	if (tst_info) {
+		ret = int_TS_RESP_verify_token(ctx, token, tst_info);
+		TS_TST_INFO_free(tst_info);
+	}
+	return ret;
+}
+
+/*
+ * Verifies whether the 'token' contains a valid time stamp token
+ * with regards to the settings of the context. Only those checks are
+ * carried out that are specified in the context:
+ *	- Verifies the signature of the TS_TST_INFO.
+ *	- Checks the version number of the response.
+ *	- Check if the requested and returned policies math.
+ *	- Check if the message imprints are the same.
+ *	- Check if the nonces are the same.
+ *	- Check if the TSA name matches the signer.
+ *	- Check if the TSA name is the expected TSA.
+ */
+static int
+int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token,
+    TS_TST_INFO *tst_info)
+{
+	X509 *signer = NULL;
+	GENERAL_NAME *tsa_name = TS_TST_INFO_get_tsa(tst_info);
+	X509_ALGOR *md_alg = NULL;
+	unsigned char *imprint = NULL;
+	unsigned imprint_len = 0;
+	int ret = 0;
+
+	/* Verify the signature. */
+	if ((ctx->flags & TS_VFY_SIGNATURE) &&
+	    !TS_RESP_verify_signature(token, ctx->certs, ctx->store, &signer))
+		goto err;
+
+	/* Check version number of response. */
+	if ((ctx->flags & TS_VFY_VERSION) &&
+	    TS_TST_INFO_get_version(tst_info) != 1) {
+		TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_UNSUPPORTED_VERSION);
+		goto err;
+	}
+
+	/* Check policies. */
+	if ((ctx->flags & TS_VFY_POLICY) &&
+	    !TS_check_policy(ctx->policy, tst_info))
+		goto err;
+
+	/* Check message imprints. */
+	if ((ctx->flags & TS_VFY_IMPRINT) &&
+	    !TS_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len,
+		tst_info))
+		goto err;
+
+	/* Compute and check message imprints. */
+	if ((ctx->flags & TS_VFY_DATA) &&
+	    (!TS_compute_imprint(ctx->data, tst_info,
+	    &md_alg, &imprint, &imprint_len) ||
+	    !TS_check_imprints(md_alg, imprint, imprint_len, tst_info)))
+		goto err;
+
+	/* Check nonces. */
+	if ((ctx->flags & TS_VFY_NONCE) &&
+	    !TS_check_nonces(ctx->nonce, tst_info))
+		goto err;
+
+	/* Check whether TSA name and signer certificate match. */
+	if ((ctx->flags & TS_VFY_SIGNER) &&
+	    tsa_name && !TS_check_signer_name(tsa_name, signer)) {
+		TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_NAME_MISMATCH);
+		goto err;
+	}
+
+	/* Check whether the TSA is the expected one. */
+	if ((ctx->flags & TS_VFY_TSA_NAME) &&
+	    !TS_check_signer_name(ctx->tsa_name, signer)) {
+		TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_UNTRUSTED);
+		goto err;
+	}
+
+	ret = 1;
+
+err:
+	X509_free(signer);
+	X509_ALGOR_free(md_alg);
+	free(imprint);
+	return ret;
+}
+
+static int
+TS_check_status_info(TS_RESP *response)
+{
+	TS_STATUS_INFO *info = TS_RESP_get_status_info(response);
+	long status = ASN1_INTEGER_get(info->status);
+	const char *status_text = NULL;
+	char *embedded_status_text = NULL;
+	char failure_text[TS_STATUS_BUF_SIZE] = "";
+
+	/* Check if everything went fine. */
+	if (status == 0 || status == 1)
+		return 1;
+
+	/* There was an error, get the description in status_text. */
+	if (0 <= status && status < (long)TS_STATUS_TEXT_SIZE)
+		status_text = TS_status_text[status];
+	else
+		status_text = "unknown code";
+
+	/* Set the embedded_status_text to the returned description. */
+	if (sk_ASN1_UTF8STRING_num(info->text) > 0 &&
+	    !(embedded_status_text = TS_get_status_text(info->text)))
+		return 0;
+
+	/* Filling in failure_text with the failure information. */
+	if (info->failure_info) {
+		int i;
+		int first = 1;
+		for (i = 0; i < (int)TS_FAILURE_INFO_SIZE; ++i) {
+			if (ASN1_BIT_STRING_get_bit(info->failure_info,
+			    TS_failure_info[i].code)) {
+				if (!first)
+					strlcat(failure_text, ",",
+					    TS_STATUS_BUF_SIZE);
+				else
+					first = 0;
+				strlcat(failure_text, TS_failure_info[i].text,
+				    TS_STATUS_BUF_SIZE);
+			}
+		}
+	}
+	if (failure_text[0] == '\0')
+		strlcpy(failure_text, "unspecified", TS_STATUS_BUF_SIZE);
+
+	/* Making up the error string. */
+	TSerr(TS_F_TS_CHECK_STATUS_INFO, TS_R_NO_TIME_STAMP_TOKEN);
+	ERR_asprintf_error_data
+	    ("status code: %s, status text: %s, failure codes: %s",
+	    status_text,
+	    embedded_status_text ? embedded_status_text : "unspecified",
+	    failure_text);
+	free(embedded_status_text);
+
+	return 0;
+}
+
+static char *
+TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text)
+{
+	int i;
+	unsigned int length = 0;
+	char *result = NULL;
+
+	/* Determine length first. */
+	for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) {
+		ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i);
+		length += ASN1_STRING_length(current);
+		length += 1;	/* separator character */
+	}
+	/* Allocate memory (closing '\0' included). */
+	if (!(result = malloc(length))) {
+		TSerr(TS_F_TS_GET_STATUS_TEXT, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	/* Concatenate the descriptions. */
+	result[0] = '\0';
+	for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) {
+		ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i);
+		if (i > 0)
+			strlcat(result, "/", length);
+		strlcat(result, (const char *)ASN1_STRING_data(current), length);
+	}
+	return result;
+}
+
+static int
+TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info)
+{
+	ASN1_OBJECT *resp_oid = TS_TST_INFO_get_policy_id(tst_info);
+
+	if (OBJ_cmp(req_oid, resp_oid) != 0) {
+		TSerr(TS_F_TS_CHECK_POLICY, TS_R_POLICY_MISMATCH);
+		return 0;
+	}
+
+	return 1;
+}
+
+static int
+TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, X509_ALGOR **md_alg,
+    unsigned char **imprint, unsigned *imprint_len)
+{
+	TS_MSG_IMPRINT *msg_imprint = TS_TST_INFO_get_msg_imprint(tst_info);
+	X509_ALGOR *md_alg_resp = TS_MSG_IMPRINT_get_algo(msg_imprint);
+	const EVP_MD *md;
+	EVP_MD_CTX md_ctx;
+	unsigned char buffer[4096];
+	int length;
+
+	*md_alg = NULL;
+	*imprint = NULL;
+
+	/* Return the MD algorithm of the response. */
+	if (!(*md_alg = X509_ALGOR_dup(md_alg_resp)))
+		goto err;
+
+	/* Getting the MD object. */
+	if (!(md = EVP_get_digestbyobj((*md_alg)->algorithm))) {
+		TSerr(TS_F_TS_COMPUTE_IMPRINT, TS_R_UNSUPPORTED_MD_ALGORITHM);
+		goto err;
+	}
+
+	/* Compute message digest. */
+	length = EVP_MD_size(md);
+	if (length < 0)
+		goto err;
+	*imprint_len = length;
+	if (!(*imprint = malloc(*imprint_len))) {
+		TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE);
+		goto err;
+	}
+
+	if (!EVP_DigestInit(&md_ctx, md))
+		goto err;
+	while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0) {
+		if (!EVP_DigestUpdate(&md_ctx, buffer, length))
+			goto err;
+	}
+	if (!EVP_DigestFinal(&md_ctx, *imprint, NULL))
+		goto err;
+
+	return 1;
+
+err:
+	X509_ALGOR_free(*md_alg);
+	free(*imprint);
+	*imprint = NULL;
+	*imprint_len = 0;
+	return 0;
+}
+
+static int
+TS_check_imprints(X509_ALGOR *algor_a, unsigned char *imprint_a, unsigned len_a,
+    TS_TST_INFO *tst_info)
+{
+	TS_MSG_IMPRINT *b = TS_TST_INFO_get_msg_imprint(tst_info);
+	X509_ALGOR *algor_b = TS_MSG_IMPRINT_get_algo(b);
+	int ret = 0;
+
+	/* algor_a is optional. */
+	if (algor_a) {
+		/* Compare algorithm OIDs. */
+		if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm))
+			goto err;
+
+		/* The parameter must be NULL in both. */
+		if ((algor_a->parameter &&
+		    ASN1_TYPE_get(algor_a->parameter) != V_ASN1_NULL) ||
+		    (algor_b->parameter &&
+		    ASN1_TYPE_get(algor_b->parameter) != V_ASN1_NULL))
+			goto err;
+	}
+
+	/* Compare octet strings. */
+	ret = len_a == (unsigned) ASN1_STRING_length(b->hashed_msg) &&
+	    memcmp(imprint_a, ASN1_STRING_data(b->hashed_msg), len_a) == 0;
+
+err:
+	if (!ret)
+		TSerr(TS_F_TS_CHECK_IMPRINTS, TS_R_MESSAGE_IMPRINT_MISMATCH);
+	return ret;
+}
+
+static int
+TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info)
+{
+	const ASN1_INTEGER *b = TS_TST_INFO_get_nonce(tst_info);
+
+	/* Error if nonce is missing. */
+	if (!b) {
+		TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_NOT_RETURNED);
+		return 0;
+	}
+
+	/* No error if a nonce is returned without being requested. */
+	if (ASN1_INTEGER_cmp(a, b) != 0) {
+		TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_MISMATCH);
+		return 0;
+	}
+
+	return 1;
+}
+
+/* Check if the specified TSA name matches either the subject
+   or one of the subject alternative names of the TSA certificate. */
+static int
+TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer)
+{
+	STACK_OF(GENERAL_NAME) *gen_names = NULL;
+	int idx = -1;
+	int found = 0;
+
+	if (signer == NULL)
+		return 0;
+
+	/* Check the subject name first. */
+	if (tsa_name->type == GEN_DIRNAME &&
+	    X509_name_cmp(tsa_name->d.dirn, signer->cert_info->subject) == 0)
+		return 1;
+
+	/* Check all the alternative names. */
+	gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name,
+	    NULL, &idx);
+	while (gen_names != NULL &&
+	    !(found = (TS_find_name(gen_names, tsa_name) >= 0))) {
+		/* Get the next subject alternative name,
+		   although there should be no more than one. */
+		GENERAL_NAMES_free(gen_names);
+		gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name,
+		    NULL, &idx);
+	}
+	if (gen_names)
+		GENERAL_NAMES_free(gen_names);
+
+	return found;
+}
+
+/* Returns 1 if name is in gen_names, 0 otherwise. */
+static int
+TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name)
+{
+	int i, found;
+	for (i = 0, found = 0; !found && i < sk_GENERAL_NAME_num(gen_names);
+	    ++i) {
+		GENERAL_NAME *current = sk_GENERAL_NAME_value(gen_names, i);
+		found = GENERAL_NAME_cmp(current, name) == 0;
+	}
+	return found ? i - 1 : -1;
+}
diff --git a/crypto/libressl/crypto/ts/ts_verify_ctx.c b/crypto/libressl/crypto/ts/ts_verify_ctx.c
new file mode 100644
index 0000000000..333ea8f346
--- /dev/null
+++ b/crypto/libressl/crypto/ts/ts_verify_ctx.c
@@ -0,0 +1,166 @@
+/* $OpenBSD: ts_verify_ctx.c,v 1.7 2014/07/11 08:44:49 jsing Exp $ */
+/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
+ * project 2003.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+TS_VERIFY_CTX *
+TS_VERIFY_CTX_new(void)
+{
+	TS_VERIFY_CTX *ctx = calloc(1, sizeof(TS_VERIFY_CTX));
+
+	if (!ctx)
+		TSerr(TS_F_TS_VERIFY_CTX_NEW, ERR_R_MALLOC_FAILURE);
+
+	return ctx;
+}
+
+void
+TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx)
+{
+	memset(ctx, 0, sizeof(TS_VERIFY_CTX));
+}
+
+void
+TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx)
+{
+	if (!ctx)
+		return;
+
+	TS_VERIFY_CTX_cleanup(ctx);
+	free(ctx);
+}
+
+void
+TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx)
+{
+	if (!ctx)
+		return;
+
+	X509_STORE_free(ctx->store);
+	sk_X509_pop_free(ctx->certs, X509_free);
+
+	ASN1_OBJECT_free(ctx->policy);
+
+	X509_ALGOR_free(ctx->md_alg);
+	free(ctx->imprint);
+
+	BIO_free_all(ctx->data);
+
+	ASN1_INTEGER_free(ctx->nonce);
+
+	GENERAL_NAME_free(ctx->tsa_name);
+
+	TS_VERIFY_CTX_init(ctx);
+}
+
+TS_VERIFY_CTX *
+TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx)
+{
+	TS_VERIFY_CTX *ret = ctx;
+	ASN1_OBJECT *policy;
+	TS_MSG_IMPRINT *imprint;
+	X509_ALGOR *md_alg;
+	ASN1_OCTET_STRING *msg;
+	const ASN1_INTEGER *nonce;
+
+	if (ret)
+		TS_VERIFY_CTX_cleanup(ret);
+	else if (!(ret = TS_VERIFY_CTX_new()))
+		return NULL;
+
+	/* Setting flags. */
+	ret->flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE);
+
+	/* Setting policy. */
+	if ((policy = TS_REQ_get_policy_id(req)) != NULL) {
+		if (!(ret->policy = OBJ_dup(policy)))
+			goto err;
+	} else
+		ret->flags &= ~TS_VFY_POLICY;
+
+	/* Setting md_alg, imprint and imprint_len. */
+	imprint = TS_REQ_get_msg_imprint(req);
+	md_alg = TS_MSG_IMPRINT_get_algo(imprint);
+	if (!(ret->md_alg = X509_ALGOR_dup(md_alg)))
+		goto err;
+	msg = TS_MSG_IMPRINT_get_msg(imprint);
+	ret->imprint_len = ASN1_STRING_length(msg);
+	if (!(ret->imprint = malloc(ret->imprint_len)))
+		goto err;
+	memcpy(ret->imprint, ASN1_STRING_data(msg), ret->imprint_len);
+
+	/* Setting nonce. */
+	if ((nonce = TS_REQ_get_nonce(req)) != NULL) {
+		if (!(ret->nonce = ASN1_INTEGER_dup(nonce)))
+			goto err;
+	} else
+		ret->flags &= ~TS_VFY_NONCE;
+
+	return ret;
+
+err:
+	if (ctx)
+		TS_VERIFY_CTX_cleanup(ctx);
+	else
+		TS_VERIFY_CTX_free(ret);
+	return NULL;
+}
diff --git a/crypto/libressl/crypto/txt_db/txt_db.c b/crypto/libressl/crypto/txt_db/txt_db.c
new file mode 100644
index 0000000000..411ca73044
--- /dev/null
+++ b/crypto/libressl/crypto/txt_db/txt_db.c
@@ -0,0 +1,372 @@
+/* $OpenBSD: txt_db.c,v 1.17 2014/07/09 11:10:51 bcook Exp $ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#undef BUFSIZE
+#define BUFSIZE	512
+
+TXT_DB *
+TXT_DB_read(BIO *in, int num)
+{
+	TXT_DB *ret = NULL;
+	int er = 1;
+	int esc = 0;
+	long ln = 0;
+	int i, add, n;
+	int size = BUFSIZE;
+	int offset = 0;
+	char *p, *f;
+	OPENSSL_STRING *pp;
+	BUF_MEM *buf = NULL;
+
+	if ((buf = BUF_MEM_new()) == NULL)
+		goto err;
+	if (!BUF_MEM_grow(buf, size))
+		goto err;
+
+	if ((ret = malloc(sizeof(TXT_DB))) == NULL)
+		goto err;
+	ret->num_fields = num;
+	ret->index = NULL;
+	ret->qual = NULL;
+	if ((ret->data = sk_OPENSSL_PSTRING_new_null()) == NULL)
+		goto err;
+	if ((ret->index = reallocarray(NULL, num, sizeof(*ret->index))) == NULL)
+		goto err;
+	if ((ret->qual = reallocarray(NULL, num, sizeof(*(ret->qual)))) == NULL)
+		goto err;
+	for (i = 0; i < num; i++) {
+		ret->index[i] = NULL;
+		ret->qual[i] = NULL;
+	}
+
+	add = (num + 1)*sizeof(char *);
+	buf->data[size-1] = '\0';
+	offset = 0;
+	for (;;) {
+		if (offset != 0) {
+			size += BUFSIZE;
+			if (!BUF_MEM_grow_clean(buf, size))
+				goto err;
+		}
+		buf->data[offset] = '\0';
+		BIO_gets(in, &(buf->data[offset]), size - offset);
+		ln++;
+		if (buf->data[offset] == '\0')
+			break;
+		if ((offset == 0) && (buf->data[0] == '#'))
+			continue;
+		i = strlen(&(buf->data[offset]));
+		offset += i;
+		if (buf->data[offset-1] != '\n')
+			continue;
+		else {
+			buf->data[offset-1] = '\0'; /* blat the '\n' */
+			if (!(p = malloc(add + offset)))
+				goto err;
+			offset = 0;
+		}
+		pp = (char **)p;
+		p += add;
+		n = 0;
+		pp[n++] = p;
+		i = 0;
+		f = buf->data;
+
+		esc = 0;
+		for (;;) {
+			if (*f == '\0')
+				break;
+			if (*f == '\t') {
+				if (esc)
+					p--;
+				else {
+					*(p++)='\0';
+					f++;
+					if (n >= num)
+						break;
+					pp[n++] = p;
+					continue;
+				}
+			}
+			esc=(*f == '\\');
+			*(p++)= *(f++);
+		}
+		*(p++)='\0';
+		if ((n != num) || (*f != '\0')) {
+			fprintf(stderr, "wrong number of fields on line %ld (looking for field %d, got %d, '%s' left)\n",ln,num,n,f);
+			er = 2;
+			goto err;
+		}
+		pp[n] = p;
+		if (!sk_OPENSSL_PSTRING_push(ret->data, pp)) {
+			fprintf(stderr, "failure in sk_push\n");
+			er = 2;
+			goto err;
+		}
+	}
+	er = 0;
+
+err:
+	BUF_MEM_free(buf);
+	if (er) {
+		if (er == 1)
+			fprintf(stderr, "malloc failure\n");
+		if (ret != NULL) {
+			if (ret->data != NULL)
+				sk_OPENSSL_PSTRING_free(ret->data);
+			free(ret->index);
+			free(ret->qual);
+			free(ret);
+		}
+		return (NULL);
+	} else
+		return (ret);
+}
+
+OPENSSL_STRING *
+TXT_DB_get_by_index(TXT_DB *db, int idx, OPENSSL_STRING *value)
+{
+	OPENSSL_STRING *ret;
+	LHASH_OF(OPENSSL_STRING) *lh;
+
+	if (idx >= db->num_fields) {
+		db->error = DB_ERROR_INDEX_OUT_OF_RANGE;
+		return (NULL);
+	}
+	lh = db->index[idx];
+	if (lh == NULL) {
+		db->error = DB_ERROR_NO_INDEX;
+		return (NULL);
+	}
+	ret = lh_OPENSSL_STRING_retrieve(lh, value);
+	db->error = DB_ERROR_OK;
+	return (ret);
+}
+
+int
+TXT_DB_create_index(TXT_DB *db, int field, int (*qual)(OPENSSL_STRING *),
+    LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp)
+{
+	LHASH_OF(OPENSSL_STRING) *idx;
+	OPENSSL_STRING *r;
+	int i, n;
+
+	if (field >= db->num_fields) {
+		db->error = DB_ERROR_INDEX_OUT_OF_RANGE;
+		return (0);
+	}
+	/* FIXME: we lose type checking at this point */
+	if ((idx = (LHASH_OF(OPENSSL_STRING) *)lh_new(hash, cmp)) == NULL) {
+		db->error = DB_ERROR_MALLOC;
+		return (0);
+	}
+	n = sk_OPENSSL_PSTRING_num(db->data);
+	for (i = 0; i < n; i++) {
+		r = sk_OPENSSL_PSTRING_value(db->data, i);
+		if ((qual != NULL) && (qual(r) == 0))
+			continue;
+		if ((r = lh_OPENSSL_STRING_insert(idx, r)) != NULL) {
+			db->error = DB_ERROR_INDEX_CLASH;
+			db->arg1 = sk_OPENSSL_PSTRING_find(db->data, r);
+			db->arg2 = i;
+			lh_OPENSSL_STRING_free(idx);
+			return (0);
+		}
+	}
+	if (db->index[field] != NULL)
+		lh_OPENSSL_STRING_free(db->index[field]);
+	db->index[field] = idx;
+	db->qual[field] = qual;
+	return (1);
+}
+
+long
+TXT_DB_write(BIO *out, TXT_DB *db)
+{
+	long i, j,n, nn, l, tot = 0;
+	char *p, **pp, *f;
+	BUF_MEM *buf = NULL;
+	long ret = -1;
+
+	if ((buf = BUF_MEM_new()) == NULL)
+		goto err;
+	n = sk_OPENSSL_PSTRING_num(db->data);
+	nn = db->num_fields;
+	for (i = 0; i < n; i++) {
+		pp = sk_OPENSSL_PSTRING_value(db->data, i);
+
+		l = 0;
+		for (j = 0; j < nn; j++) {
+			if (pp[j] != NULL)
+				l += strlen(pp[j]);
+		}
+		if (!BUF_MEM_grow_clean(buf, (int)(l*2 + nn)))
+			goto err;
+
+		p = buf->data;
+		for (j = 0; j < nn; j++) {
+			f = pp[j];
+			if (f != NULL)
+				for (;;) {
+					if (*f == '\0')
+						break;
+					if (*f == '\t')
+						*(p++) = '\\';
+					*(p++) = *(f++);
+				}
+			*(p++) = '\t';
+		}
+		p[-1] = '\n';
+		j = p - buf->data;
+		if (BIO_write(out, buf->data, (int)j) != j)
+			goto err;
+		tot += j;
+	}
+	ret = tot;
+
+err:
+	if (buf != NULL)
+		BUF_MEM_free(buf);
+	return (ret);
+}
+
+int
+TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *row)
+{
+	int i;
+	OPENSSL_STRING *r;
+
+	for (i = 0; i < db->num_fields; i++) {
+		if (db->index[i] != NULL) {
+			if ((db->qual[i] != NULL) && (db->qual[i](row) == 0))
+				continue;
+			r = lh_OPENSSL_STRING_retrieve(db->index[i], row);
+			if (r != NULL) {
+				db->error = DB_ERROR_INDEX_CLASH;
+				db->arg1 = i;
+				db->arg_row = r;
+				goto err;
+			}
+		}
+	}
+	/* We have passed the index checks, now just append and insert */
+	if (!sk_OPENSSL_PSTRING_push(db->data, row)) {
+		db->error = DB_ERROR_MALLOC;
+		goto err;
+	}
+
+	for (i = 0; i < db->num_fields; i++) {
+		if (db->index[i] != NULL) {
+			if ((db->qual[i] != NULL) && (db->qual[i](row) == 0))
+				continue;
+			(void)lh_OPENSSL_STRING_insert(db->index[i], row);
+		}
+	}
+	return (1);
+
+err:
+	return (0);
+}
+
+void
+TXT_DB_free(TXT_DB *db)
+{
+	int i, n;
+	char **p, *max;
+
+	if (db == NULL)
+		return;
+
+	if (db->index != NULL) {
+		for (i = db->num_fields - 1; i >= 0; i--)
+			if (db->index[i] != NULL)
+				lh_OPENSSL_STRING_free(db->index[i]);
+		free(db->index);
+	}
+	free(db->qual);
+	if (db->data != NULL) {
+		for (i = sk_OPENSSL_PSTRING_num(db->data) - 1; i >= 0; i--) {
+			/* check if any 'fields' have been allocated
+			 * from outside of the initial block */
+			p = sk_OPENSSL_PSTRING_value(db->data, i);
+			max = p[db->num_fields]; /* last address */
+			if (max == NULL) /* new row */
+			{
+				for (n = 0; n < db->num_fields; n++)
+					free(p[n]);
+			} else {
+				for (n = 0; n < db->num_fields; n++) {
+					if (((p[n] < (char *)p) ||
+					    (p[n] > max)) &&
+					    (p[n] != NULL))
+						free(p[n]);
+				}
+			}
+			free(sk_OPENSSL_PSTRING_value(db->data, i));
+		}
+		sk_OPENSSL_PSTRING_free(db->data);
+	}
+	free(db);
+}
diff --git a/crypto/libressl/crypto/ui/ui_err.c b/crypto/libressl/crypto/ui/ui_err.c
new file mode 100644
index 0000000000..1a10927ea9
--- /dev/null
+++ b/crypto/libressl/crypto/ui/ui_err.c
@@ -0,0 +1,112 @@
+/* $OpenBSD: ui_err.c,v 1.7 2014/06/12 15:49:31 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 1999-2006 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_UI,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_UI,0,reason)
+
+static ERR_STRING_DATA UI_str_functs[] = {
+	{ERR_FUNC(UI_F_GENERAL_ALLOCATE_BOOLEAN), "GENERAL_ALLOCATE_BOOLEAN"},
+	{ERR_FUNC(UI_F_GENERAL_ALLOCATE_PROMPT), "GENERAL_ALLOCATE_PROMPT"},
+	{ERR_FUNC(UI_F_GENERAL_ALLOCATE_STRING), "GENERAL_ALLOCATE_STRING"},
+	{ERR_FUNC(UI_F_UI_CTRL), "UI_ctrl"},
+	{ERR_FUNC(UI_F_UI_DUP_ERROR_STRING), "UI_dup_error_string"},
+	{ERR_FUNC(UI_F_UI_DUP_INFO_STRING), "UI_dup_info_string"},
+	{ERR_FUNC(UI_F_UI_DUP_INPUT_BOOLEAN), "UI_dup_input_boolean"},
+	{ERR_FUNC(UI_F_UI_DUP_INPUT_STRING), "UI_dup_input_string"},
+	{ERR_FUNC(UI_F_UI_DUP_VERIFY_STRING), "UI_dup_verify_string"},
+	{ERR_FUNC(UI_F_UI_GET0_RESULT), "UI_get0_result"},
+	{ERR_FUNC(UI_F_UI_NEW_METHOD), "UI_new_method"},
+	{ERR_FUNC(UI_F_UI_SET_RESULT), "UI_set_result"},
+	{0, NULL}
+};
+
+static ERR_STRING_DATA UI_str_reasons[] = {
+	{ERR_REASON(UI_R_COMMON_OK_AND_CANCEL_CHARACTERS), "common ok and cancel characters"},
+	{ERR_REASON(UI_R_INDEX_TOO_LARGE), "index too large"},
+	{ERR_REASON(UI_R_INDEX_TOO_SMALL), "index too small"},
+	{ERR_REASON(UI_R_NO_RESULT_BUFFER), "no result buffer"},
+	{ERR_REASON(UI_R_RESULT_TOO_LARGE), "result too large"},
+	{ERR_REASON(UI_R_RESULT_TOO_SMALL), "result too small"},
+	{ERR_REASON(UI_R_UNKNOWN_CONTROL_COMMAND), "unknown control command"},
+	{0, NULL}
+};
+
+#endif
+
+void
+ERR_load_UI_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(UI_str_functs[0].error) == NULL) {
+		ERR_load_strings(0, UI_str_functs);
+		ERR_load_strings(0, UI_str_reasons);
+	}
+#endif
+}
diff --git a/crypto/libressl/crypto/ui/ui_lib.c b/crypto/libressl/crypto/ui/ui_lib.c
new file mode 100644
index 0000000000..189c7a17ae
--- /dev/null
+++ b/crypto/libressl/crypto/ui/ui_lib.c
@@ -0,0 +1,885 @@
+/* $OpenBSD: ui_lib.c,v 1.30 2015/02/10 11:22:21 jsing Exp $ */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include "ui_locl.h"
+
+static const UI_METHOD *default_UI_meth = NULL;
+
+UI *
+UI_new(void)
+{
+	return (UI_new_method(NULL));
+}
+
+UI *
+UI_new_method(const UI_METHOD *method)
+{
+	UI *ret;
+
+	ret = malloc(sizeof(UI));
+	if (ret == NULL) {
+		UIerr(UI_F_UI_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+		return NULL;
+	}
+	if (method == NULL)
+		ret->meth = UI_get_default_method();
+	else
+		ret->meth = method;
+
+	ret->strings = NULL;
+	ret->user_data = NULL;
+	ret->flags = 0;
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI, ret, &ret->ex_data);
+	return ret;
+}
+
+static void
+free_string(UI_STRING *uis)
+{
+	if (uis->flags & OUT_STRING_FREEABLE) {
+		free((char *) uis->out_string);
+		switch (uis->type) {
+		case UIT_BOOLEAN:
+			free((char *)uis->_.boolean_data.action_desc);
+			free((char *)uis->_.boolean_data.ok_chars);
+			free((char *)uis->_.boolean_data.cancel_chars);
+			break;
+		default:
+			break;
+		}
+	}
+	free(uis);
+}
+
+void
+UI_free(UI *ui)
+{
+	if (ui == NULL)
+		return;
+	sk_UI_STRING_pop_free(ui->strings, free_string);
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_UI, ui, &ui->ex_data);
+	free(ui);
+}
+
+static int
+allocate_string_stack(UI *ui)
+{
+	if (ui->strings == NULL) {
+		ui->strings = sk_UI_STRING_new_null();
+		if (ui->strings == NULL) {
+			return -1;
+		}
+	}
+	return 0;
+}
+
+static UI_STRING *
+general_allocate_prompt(UI *ui, const char *prompt, int prompt_freeable,
+    enum UI_string_types type, int input_flags, char *result_buf)
+{
+	UI_STRING *ret = NULL;
+
+	if (prompt == NULL) {
+		UIerr(UI_F_GENERAL_ALLOCATE_PROMPT,
+		    ERR_R_PASSED_NULL_PARAMETER);
+	} else if ((type == UIT_PROMPT || type == UIT_VERIFY ||
+	    type == UIT_BOOLEAN) && result_buf == NULL) {
+		UIerr(UI_F_GENERAL_ALLOCATE_PROMPT, UI_R_NO_RESULT_BUFFER);
+	} else if ((ret = malloc(sizeof(UI_STRING)))) {
+		ret->out_string = prompt;
+		ret->flags = prompt_freeable ? OUT_STRING_FREEABLE : 0;
+		ret->input_flags = input_flags;
+		ret->type = type;
+		ret->result_buf = result_buf;
+	}
+	return ret;
+}
+
+static int
+general_allocate_string(UI *ui, const char *prompt, int prompt_freeable,
+    enum UI_string_types type, int input_flags, char *result_buf, int minsize,
+    int maxsize, const char *test_buf)
+{
+	int ret = -1;
+	UI_STRING *s = general_allocate_prompt(ui, prompt, prompt_freeable,
+	    type, input_flags, result_buf);
+
+	if (s) {
+		if (allocate_string_stack(ui) >= 0) {
+			s->_.string_data.result_minsize = minsize;
+			s->_.string_data.result_maxsize = maxsize;
+			s->_.string_data.test_buf = test_buf;
+			ret = sk_UI_STRING_push(ui->strings, s);
+			/* sk_push() returns 0 on error.  Let's adapt that */
+			if (ret <= 0)
+				ret--;
+		} else
+			free_string(s);
+	}
+	return ret;
+}
+
+static int
+general_allocate_boolean(UI *ui, const char *prompt, const char *action_desc,
+    const char *ok_chars, const char *cancel_chars, int prompt_freeable,
+    enum UI_string_types type, int input_flags, char *result_buf)
+{
+	int ret = -1;
+	UI_STRING *s;
+	const char *p;
+
+	if (ok_chars == NULL) {
+		UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,
+		    ERR_R_PASSED_NULL_PARAMETER);
+	} else if (cancel_chars == NULL) {
+		UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,
+		    ERR_R_PASSED_NULL_PARAMETER);
+	} else {
+		for (p = ok_chars; *p; p++) {
+			if (strchr(cancel_chars, *p)) {
+				UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,
+				    UI_R_COMMON_OK_AND_CANCEL_CHARACTERS);
+			}
+		}
+
+		s = general_allocate_prompt(ui, prompt, prompt_freeable,
+		    type, input_flags, result_buf);
+
+		if (s) {
+			if (allocate_string_stack(ui) >= 0) {
+				s->_.boolean_data.action_desc = action_desc;
+				s->_.boolean_data.ok_chars = ok_chars;
+				s->_.boolean_data.cancel_chars = cancel_chars;
+				ret = sk_UI_STRING_push(ui->strings, s);
+				/*
+				 * sk_push() returns 0 on error. Let's adapt
+				 * that
+				 */
+				if (ret <= 0)
+					ret--;
+			} else
+				free_string(s);
+		}
+	}
+	return ret;
+}
+
+/* Returns the index to the place in the stack or -1 for error.  Uses a
+   direct reference to the prompt.  */
+int
+UI_add_input_string(UI *ui, const char *prompt, int flags, char *result_buf,
+    int minsize, int maxsize)
+{
+	return general_allocate_string(ui, prompt, 0, UIT_PROMPT, flags,
+	    result_buf, minsize, maxsize, NULL);
+}
+
+/* Same as UI_add_input_string(), excepts it takes a copy of the prompt */
+int
+UI_dup_input_string(UI *ui, const char *prompt, int flags, char *result_buf,
+    int minsize, int maxsize)
+{
+	char *prompt_copy = NULL;
+
+	if (prompt) {
+		prompt_copy = strdup(prompt);
+		if (prompt_copy == NULL) {
+			UIerr(UI_F_UI_DUP_INPUT_STRING, ERR_R_MALLOC_FAILURE);
+			return 0;
+		}
+	}
+	return general_allocate_string(ui, prompt_copy, 1, UIT_PROMPT, flags,
+	    result_buf, minsize, maxsize, NULL);
+}
+
+int
+UI_add_verify_string(UI *ui, const char *prompt, int flags, char *result_buf,
+    int minsize, int maxsize, const char *test_buf)
+{
+	return general_allocate_string(ui, prompt, 0, UIT_VERIFY, flags,
+	    result_buf, minsize, maxsize, test_buf);
+}
+
+int
+UI_dup_verify_string(UI *ui, const char *prompt, int flags,
+    char *result_buf, int minsize, int maxsize, const char *test_buf)
+{
+	char *prompt_copy = NULL;
+
+	if (prompt) {
+		prompt_copy = strdup(prompt);
+		if (prompt_copy == NULL) {
+			UIerr(UI_F_UI_DUP_VERIFY_STRING, ERR_R_MALLOC_FAILURE);
+			return -1;
+		}
+	}
+	return general_allocate_string(ui, prompt_copy, 1, UIT_VERIFY, flags,
+	    result_buf, minsize, maxsize, test_buf);
+}
+
+int
+UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
+    const char *ok_chars, const char *cancel_chars, int flags, char *result_buf)
+{
+	return general_allocate_boolean(ui, prompt, action_desc, ok_chars,
+	    cancel_chars, 0, UIT_BOOLEAN, flags, result_buf);
+}
+
+int
+UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
+    const char *ok_chars, const char *cancel_chars, int flags, char *result_buf)
+{
+	char *prompt_copy = NULL;
+	char *action_desc_copy = NULL;
+	char *ok_chars_copy = NULL;
+	char *cancel_chars_copy = NULL;
+
+	if (prompt) {
+		prompt_copy = strdup(prompt);
+		if (prompt_copy == NULL) {
+			UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+	}
+	if (action_desc) {
+		action_desc_copy = strdup(action_desc);
+		if (action_desc_copy == NULL) {
+			UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+	}
+	if (ok_chars) {
+		ok_chars_copy = strdup(ok_chars);
+		if (ok_chars_copy == NULL) {
+			UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+	}
+	if (cancel_chars) {
+		cancel_chars_copy = strdup(cancel_chars);
+		if (cancel_chars_copy == NULL) {
+			UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
+	}
+	return general_allocate_boolean(ui, prompt_copy, action_desc_copy,
+	    ok_chars_copy, cancel_chars_copy, 1, UIT_BOOLEAN, flags,
+	    result_buf);
+
+err:
+	free(prompt_copy);
+	free(action_desc_copy);
+	free(ok_chars_copy);
+	free(cancel_chars_copy);
+	return -1;
+}
+
+int
+UI_add_info_string(UI *ui, const char *text)
+{
+	return general_allocate_string(ui, text, 0, UIT_INFO, 0, NULL, 0, 0,
+	    NULL);
+}
+
+int
+UI_dup_info_string(UI *ui, const char *text)
+{
+	char *text_copy = NULL;
+
+	if (text) {
+		text_copy = strdup(text);
+		if (text_copy == NULL) {
+			UIerr(UI_F_UI_DUP_INFO_STRING, ERR_R_MALLOC_FAILURE);
+			return -1;
+		}
+	}
+	return general_allocate_string(ui, text_copy, 1, UIT_INFO, 0, NULL,
+	    0, 0, NULL);
+}
+
+int
+UI_add_error_string(UI *ui, const char *text)
+{
+	return general_allocate_string(ui, text, 0, UIT_ERROR, 0, NULL, 0, 0,
+	    NULL);
+}
+
+int
+UI_dup_error_string(UI *ui, const char *text)
+{
+	char *text_copy = NULL;
+
+	if (text) {
+		text_copy = strdup(text);
+		if (text_copy == NULL) {
+			UIerr(UI_F_UI_DUP_ERROR_STRING, ERR_R_MALLOC_FAILURE);
+			return -1;
+		}
+	}
+	return general_allocate_string(ui, text_copy, 1, UIT_ERROR, 0, NULL,
+	    0, 0, NULL);
+}
+
+char *
+UI_construct_prompt(UI *ui, const char *object_desc, const char *object_name)
+{
+	char *prompt;
+
+	if (ui->meth->ui_construct_prompt)
+		return ui->meth->ui_construct_prompt(ui, object_desc,
+		    object_name);
+
+	if (object_desc == NULL)
+		return NULL;
+
+	if (object_name == NULL) {
+		if (asprintf(&prompt, "Enter %s:", object_desc) == -1)
+			return (NULL);
+	} else {
+		if (asprintf(&prompt, "Enter %s for %s:", object_desc,
+		    object_name) == -1)
+			return (NULL);
+	}
+
+	return prompt;
+}
+
+void *
+UI_add_user_data(UI *ui, void *user_data)
+{
+	void *old_data = ui->user_data;
+
+	ui->user_data = user_data;
+	return old_data;
+}
+
+void *
+UI_get0_user_data(UI *ui)
+{
+	return ui->user_data;
+}
+
+const char *
+UI_get0_result(UI *ui, int i)
+{
+	if (i < 0) {
+		UIerr(UI_F_UI_GET0_RESULT, UI_R_INDEX_TOO_SMALL);
+		return NULL;
+	}
+	if (i >= sk_UI_STRING_num(ui->strings)) {
+		UIerr(UI_F_UI_GET0_RESULT, UI_R_INDEX_TOO_LARGE);
+		return NULL;
+	}
+	return UI_get0_result_string(sk_UI_STRING_value(ui->strings, i));
+}
+
+static int
+print_error(const char *str, size_t len, UI *ui)
+{
+	UI_STRING uis;
+
+	memset(&uis, 0, sizeof(uis));
+	uis.type = UIT_ERROR;
+	uis.out_string = str;
+
+	if (ui->meth->ui_write_string &&
+	    !ui->meth->ui_write_string(ui, &uis))
+		return -1;
+	return 0;
+}
+
+int
+UI_process(UI *ui)
+{
+	int i, ok = 0;
+
+	if (ui->meth->ui_open_session && !ui->meth->ui_open_session(ui))
+		return -1;
+
+	if (ui->flags & UI_FLAG_PRINT_ERRORS)
+		ERR_print_errors_cb(
+		    (int (*)(const char *, size_t, void *)) print_error,
+		    (void *)ui);
+
+	for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) {
+		if (ui->meth->ui_write_string &&
+		    !ui->meth->ui_write_string(ui,
+			sk_UI_STRING_value(ui->strings, i))) {
+			ok = -1;
+			goto err;
+		}
+	}
+
+	if (ui->meth->ui_flush)
+		switch (ui->meth->ui_flush(ui)) {
+		case -1:	/* Interrupt/Cancel/something... */
+			ok = -2;
+			goto err;
+		case 0:		/* Errors */
+			ok = -1;
+			goto err;
+		default:	/* Success */
+			ok = 0;
+			break;
+		}
+
+	for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) {
+		if (ui->meth->ui_read_string) {
+			switch (ui->meth->ui_read_string(ui,
+			    sk_UI_STRING_value(ui->strings, i))) {
+			case -1:	/* Interrupt/Cancel/something... */
+				ui->flags &= ~UI_FLAG_REDOABLE;
+				ok = -2;
+				goto err;
+			case 0:		/* Errors */
+				ok = -1;
+				goto err;
+			default:	/* Success */
+				ok = 0;
+				break;
+			}
+		}
+	}
+
+err:
+	if (ui->meth->ui_close_session && !ui->meth->ui_close_session(ui))
+		return -1;
+	return ok;
+}
+
+int
+UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void))
+{
+	if (ui == NULL) {
+		UIerr(UI_F_UI_CTRL, ERR_R_PASSED_NULL_PARAMETER);
+		return -1;
+	}
+	switch (cmd) {
+	case UI_CTRL_PRINT_ERRORS:
+		{
+			int save_flag = !!(ui->flags & UI_FLAG_PRINT_ERRORS);
+			if (i)
+				ui->flags |= UI_FLAG_PRINT_ERRORS;
+			else
+				ui->flags &= ~UI_FLAG_PRINT_ERRORS;
+			return save_flag;
+		}
+	case UI_CTRL_IS_REDOABLE:
+		return !!(ui->flags & UI_FLAG_REDOABLE);
+	default:
+		break;
+	}
+	UIerr(UI_F_UI_CTRL, UI_R_UNKNOWN_CONTROL_COMMAND);
+	return -1;
+}
+
+int
+UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+    CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+{
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI, argl, argp,
+	    new_func, dup_func, free_func);
+}
+
+int
+UI_set_ex_data(UI *r, int idx, void *arg)
+{
+	return (CRYPTO_set_ex_data(&r->ex_data, idx, arg));
+}
+
+void *
+UI_get_ex_data(UI *r, int idx)
+{
+	return (CRYPTO_get_ex_data(&r->ex_data, idx));
+}
+
+void
+UI_set_default_method(const UI_METHOD *meth)
+{
+	default_UI_meth = meth;
+}
+
+const UI_METHOD *
+UI_get_default_method(void)
+{
+	if (default_UI_meth == NULL) {
+		default_UI_meth = UI_OpenSSL();
+	}
+	return default_UI_meth;
+}
+
+const UI_METHOD *
+UI_get_method(UI *ui)
+{
+	return ui->meth;
+}
+
+const UI_METHOD *
+UI_set_method(UI *ui, const UI_METHOD *meth)
+{
+	ui->meth = meth;
+	return ui->meth;
+}
+
+
+UI_METHOD *
+UI_create_method(char *name)
+{
+	UI_METHOD *ui_method = calloc(1, sizeof(UI_METHOD));
+
+	if (ui_method && name)
+		ui_method->name = strdup(name);
+
+	return ui_method;
+}
+
+/* BIG FSCKING WARNING!!!!  If you use this on a statically allocated method
+   (that is, it hasn't been allocated using UI_create_method(), you deserve
+   anything Murphy can throw at you and more!  You have been warned. */
+void
+UI_destroy_method(UI_METHOD *ui_method)
+{
+	free(ui_method->name);
+	ui_method->name = NULL;
+	free(ui_method);
+}
+
+int
+UI_method_set_opener(UI_METHOD *method, int (*opener)(UI *ui))
+{
+	if (method) {
+		method->ui_open_session = opener;
+		return 0;
+	} else
+		return -1;
+}
+
+int
+UI_method_set_writer(UI_METHOD *method, int (*writer)(UI *ui, UI_STRING *uis))
+{
+	if (method) {
+		method->ui_write_string = writer;
+		return 0;
+	} else
+		return -1;
+}
+
+int
+UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui))
+{
+	if (method) {
+		method->ui_flush = flusher;
+		return 0;
+	} else
+		return -1;
+}
+
+int
+UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis))
+{
+	if (method) {
+		method->ui_read_string = reader;
+		return 0;
+	} else
+		return -1;
+}
+
+int
+UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui))
+{
+	if (method) {
+		method->ui_close_session = closer;
+		return 0;
+	} else
+		return -1;
+}
+
+int
+UI_method_set_prompt_constructor(UI_METHOD *method,
+    char *(*prompt_constructor)(UI *ui, const char *object_desc,
+    const char *object_name))
+{
+	if (method) {
+		method->ui_construct_prompt = prompt_constructor;
+		return 0;
+	} else
+		return -1;
+}
+
+int
+(*UI_method_get_opener(UI_METHOD * method))(UI *)
+{
+	if (method)
+		return method->ui_open_session;
+	else
+		return NULL;
+}
+
+int
+(*UI_method_get_writer(UI_METHOD *method))(UI *, UI_STRING *)
+{
+	if (method)
+		return method->ui_write_string;
+	else
+		return NULL;
+}
+
+int
+(*UI_method_get_flusher(UI_METHOD *method)) (UI *)
+{
+	if (method)
+		return method->ui_flush;
+	else
+		return NULL;
+}
+
+int
+(*UI_method_get_reader(UI_METHOD *method))(UI *, UI_STRING *)
+{
+	if (method)
+		return method->ui_read_string;
+	else
+		return NULL;
+}
+
+int
+(*UI_method_get_closer(UI_METHOD *method))(UI *)
+{
+	if (method)
+		return method->ui_close_session;
+	else
+		return NULL;
+}
+
+char *
+(*UI_method_get_prompt_constructor(UI_METHOD *method))(UI *, const char *,
+    const char *)
+{
+	if (method)
+		return method->ui_construct_prompt;
+	else
+		return NULL;
+}
+
+enum UI_string_types
+UI_get_string_type(UI_STRING *uis)
+{
+	if (!uis)
+		return UIT_NONE;
+	return uis->type;
+}
+
+int
+UI_get_input_flags(UI_STRING *uis)
+{
+	if (!uis)
+		return 0;
+	return uis->input_flags;
+}
+
+const char *
+UI_get0_output_string(UI_STRING *uis)
+{
+	if (!uis)
+		return NULL;
+	return uis->out_string;
+}
+
+const char *
+UI_get0_action_string(UI_STRING *uis)
+{
+	if (!uis)
+		return NULL;
+	switch (uis->type) {
+	case UIT_PROMPT:
+	case UIT_BOOLEAN:
+		return uis->_.boolean_data.action_desc;
+	default:
+		return NULL;
+	}
+}
+
+const char *
+UI_get0_result_string(UI_STRING *uis)
+{
+	if (!uis)
+		return NULL;
+	switch (uis->type) {
+	case UIT_PROMPT:
+	case UIT_VERIFY:
+		return uis->result_buf;
+	default:
+		return NULL;
+	}
+}
+
+const char *
+UI_get0_test_string(UI_STRING *uis)
+{
+	if (!uis)
+		return NULL;
+	switch (uis->type) {
+	case UIT_VERIFY:
+		return uis->_.string_data.test_buf;
+	default:
+		return NULL;
+	}
+}
+
+int
+UI_get_result_minsize(UI_STRING *uis)
+{
+	if (!uis)
+		return -1;
+	switch (uis->type) {
+	case UIT_PROMPT:
+	case UIT_VERIFY:
+		return uis->_.string_data.result_minsize;
+	default:
+		return -1;
+	}
+}
+
+int
+UI_get_result_maxsize(UI_STRING *uis)
+{
+	if (!uis)
+		return -1;
+	switch (uis->type) {
+	case UIT_PROMPT:
+	case UIT_VERIFY:
+		return uis->_.string_data.result_maxsize;
+	default:
+		return -1;
+	}
+}
+
+int
+UI_set_result(UI *ui, UI_STRING *uis, const char *result)
+{
+	int l = strlen(result);
+
+	ui->flags &= ~UI_FLAG_REDOABLE;
+
+	if (!uis)
+		return -1;
+	switch (uis->type) {
+	case UIT_PROMPT:
+	case UIT_VERIFY:
+		if (l < uis->_.string_data.result_minsize) {
+			ui->flags |= UI_FLAG_REDOABLE;
+			UIerr(UI_F_UI_SET_RESULT,
+			    UI_R_RESULT_TOO_SMALL);
+			ERR_asprintf_error_data
+			    ("You must type in %d to %d characters",
+				uis->_.string_data.result_minsize,
+				uis->_.string_data.result_maxsize);
+			return -1;
+		}
+		if (l > uis->_.string_data.result_maxsize) {
+			ui->flags |= UI_FLAG_REDOABLE;
+			UIerr(UI_F_UI_SET_RESULT,
+			    UI_R_RESULT_TOO_LARGE);
+			ERR_asprintf_error_data
+			    ("You must type in %d to %d characters",
+				uis->_.string_data.result_minsize,
+				uis->_.string_data.result_maxsize);
+			return -1;
+		}
+		if (!uis->result_buf) {
+			UIerr(UI_F_UI_SET_RESULT, UI_R_NO_RESULT_BUFFER);
+			return -1;
+		}
+		strlcpy(uis->result_buf, result,
+		    uis->_.string_data.result_maxsize + 1);
+		break;
+	case UIT_BOOLEAN:
+		{
+			const char *p;
+
+			if (!uis->result_buf) {
+				UIerr(UI_F_UI_SET_RESULT, UI_R_NO_RESULT_BUFFER);
+				return -1;
+			}
+			uis->result_buf[0] = '\0';
+			for (p = result; *p; p++) {
+				if (strchr(uis->_.boolean_data.ok_chars, *p)) {
+					uis->result_buf[0] =
+					    uis->_.boolean_data.ok_chars[0];
+					break;
+				}
+				if (strchr(uis->_.boolean_data.cancel_chars, *p)) {
+					uis->result_buf[0] =
+					    uis->_.boolean_data.cancel_chars[0];
+					break;
+				}
+			}
+		default:
+			break;
+		}
+	}
+	return 0;
+}
diff --git a/crypto/libressl/crypto/ui/ui_locl.h b/crypto/libressl/crypto/ui/ui_locl.h
new file mode 100644
index 0000000000..020e878248
--- /dev/null
+++ b/crypto/libressl/crypto/ui/ui_locl.h
@@ -0,0 +1,148 @@
+/* $OpenBSD$ */
+
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_UI_LOCL_H
+#define HEADER_UI_LOCL_H
+
+#include 
+#include 
+
+#ifdef _
+#undef _
+#endif
+
+struct ui_method_st {
+	char *name;
+
+	/* All the functions return 1 or non-NULL for success and 0 or NULL
+	   for failure */
+
+	/* Open whatever channel for this, be it the console, an X window
+	   or whatever.
+	   This function should use the ex_data structure to save
+	   intermediate data. */
+	int (*ui_open_session)(UI *ui);
+
+	int (*ui_write_string)(UI *ui, UI_STRING *uis);
+
+	/* Flush the output.  If a GUI dialog box is used, this function can
+	   be used to actually display it. */
+	int (*ui_flush)(UI *ui);
+
+	int (*ui_read_string)(UI *ui, UI_STRING *uis);
+
+	int (*ui_close_session)(UI *ui);
+
+	/* Construct a prompt in a user-defined manner.  object_desc is a
+	   textual short description of the object, for example "pass phrase",
+	   and object_name is the name of the object (might be a card name or
+	   a file name.
+	   The returned string shall always be allocated on the heap with
+	   malloc(), and need to be free'd with free(). */
+	char *(*ui_construct_prompt)(UI *ui, const char *object_desc,
+	    const char *object_name);
+};
+
+struct ui_string_st {
+	enum UI_string_types type; /* Input */
+	const char *out_string;	/* Input */
+	int input_flags;	/* Flags from the user */
+
+	/* The following parameters are completely irrelevant for UIT_INFO,
+	   and can therefore be set to 0 or NULL */
+	char *result_buf;	/* Input and Output: If not NULL, user-defined
+				   with size in result_maxsize.  Otherwise, it
+				   may be allocated by the UI routine, meaning
+				   result_minsize is going to be overwritten.*/
+	union {
+		struct {
+			int result_minsize;	/* Input: minimum required
+						   size of the result.
+						*/
+			int result_maxsize;	/* Input: maximum permitted
+						   size of the result */
+
+			const char *test_buf;	/* Input: test string to verify
+						   against */
+		} string_data;
+		struct {
+			const char *action_desc; /* Input */
+			const char *ok_chars; /* Input */
+			const char *cancel_chars; /* Input */
+		} boolean_data;
+	} _;
+
+#define OUT_STRING_FREEABLE 0x01
+	int flags;		/* flags for internal use */
+};
+
+struct ui_st {
+	const UI_METHOD *meth;
+	STACK_OF(UI_STRING) *strings; /* We might want to prompt for more
+					 than one thing at a time, and
+					 with different echoing status.  */
+	void *user_data;
+	CRYPTO_EX_DATA ex_data;
+
+#define UI_FLAG_REDOABLE	0x0001
+#define UI_FLAG_PRINT_ERRORS	0x0100
+	int flags;
+};
+
+#endif
diff --git a/crypto/libressl/crypto/ui/ui_openssl.c b/crypto/libressl/crypto/ui/ui_openssl.c
new file mode 100644
index 0000000000..581ac89c9c
--- /dev/null
+++ b/crypto/libressl/crypto/ui/ui_openssl.c
@@ -0,0 +1,397 @@
+/* $OpenBSD: ui_openssl.c,v 1.24 2015/07/16 02:46:49 guenther Exp $ */
+/* Written by Richard Levitte (richard@levitte.org) and others
+ * for the OpenSSL project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* The lowest level part of this file was previously in crypto/des/read_pwd.c,
+ * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ui_locl.h"
+
+#ifndef NX509_SIG
+#define NX509_SIG 32
+#endif
+
+/* Define globals.  They are protected by a lock */
+static struct sigaction savsig[NX509_SIG];
+
+static struct termios tty_orig;
+static FILE *tty_in, *tty_out;
+static int is_a_tty;
+
+/* Declare static functions */
+static int read_till_nl(FILE *);
+static void recsig(int);
+static void pushsig(void);
+static void popsig(void);
+static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl);
+
+static int read_string(UI *ui, UI_STRING *uis);
+static int write_string(UI *ui, UI_STRING *uis);
+
+static int open_console(UI *ui);
+static int echo_console(UI *ui);
+static int noecho_console(UI *ui);
+static int close_console(UI *ui);
+
+static UI_METHOD ui_openssl = {
+	.name = "OpenSSL default user interface",
+	.ui_open_session = open_console,
+	.ui_write_string = write_string,
+	.ui_read_string = read_string,
+	.ui_close_session = close_console,
+};
+
+/* The method with all the built-in thingies */
+UI_METHOD *
+UI_OpenSSL(void)
+{
+	return &ui_openssl;
+}
+
+/* The following function makes sure that info and error strings are printed
+   before any prompt. */
+static int
+write_string(UI *ui, UI_STRING *uis)
+{
+	switch (UI_get_string_type(uis)) {
+	case UIT_ERROR:
+	case UIT_INFO:
+		fputs(UI_get0_output_string(uis), tty_out);
+		fflush(tty_out);
+		break;
+	default:
+		break;
+	}
+	return 1;
+}
+
+static int
+read_string(UI *ui, UI_STRING *uis)
+{
+	int ok = 0;
+
+	switch (UI_get_string_type(uis)) {
+	case UIT_BOOLEAN:
+		fputs(UI_get0_output_string(uis), tty_out);
+		fputs(UI_get0_action_string(uis), tty_out);
+		fflush(tty_out);
+		return read_string_inner(ui, uis,
+		    UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 0);
+	case UIT_PROMPT:
+		fputs(UI_get0_output_string(uis), tty_out);
+		fflush(tty_out);
+		return read_string_inner(ui, uis,
+		    UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 1);
+	case UIT_VERIFY:
+		fprintf(tty_out, "Verifying - %s",
+		    UI_get0_output_string(uis));
+		fflush(tty_out);
+		if ((ok = read_string_inner(ui, uis, UI_get_input_flags(uis) &
+		    UI_INPUT_FLAG_ECHO, 1)) <= 0)
+			return ok;
+		if (strcmp(UI_get0_result_string(uis),
+		    UI_get0_test_string(uis)) != 0) {
+			fprintf(tty_out, "Verify failure\n");
+			fflush(tty_out);
+			return 0;
+		}
+		break;
+	default:
+		break;
+	}
+	return 1;
+}
+
+
+/* Internal functions to read a string without echoing */
+static int
+read_till_nl(FILE *in)
+{
+#define SIZE 4
+	char buf[SIZE + 1];
+
+	do {
+		if (!fgets(buf, SIZE, in))
+			return 0;
+	} while (strchr(buf, '\n') == NULL);
+	return 1;
+}
+
+static volatile sig_atomic_t intr_signal;
+
+static int
+read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl)
+{
+	static int ps;
+	int ok;
+	char result[BUFSIZ];
+	int maxsize = BUFSIZ - 1;
+	char *p;
+
+	intr_signal = 0;
+	ok = 0;
+	ps = 0;
+
+	pushsig();
+	ps = 1;
+
+	if (!echo && !noecho_console(ui))
+		goto error;
+	ps = 2;
+
+	result[0] = '\0';
+	p = fgets(result, maxsize, tty_in);
+	if (!p)
+		goto error;
+	if (feof(tty_in))
+		goto error;
+	if (ferror(tty_in))
+		goto error;
+	if ((p = strchr(result, '\n')) != NULL) {
+		if (strip_nl)
+			*p = '\0';
+	} else if (!read_till_nl(tty_in))
+		goto error;
+	if (UI_set_result(ui, uis, result) >= 0)
+		ok = 1;
+
+error:
+	if (intr_signal == SIGINT)
+		ok = -1;
+	if (!echo)
+		fprintf(tty_out, "\n");
+	if (ps >= 2 && !echo && !echo_console(ui))
+		ok = 0;
+
+	if (ps >= 1)
+		popsig();
+
+	explicit_bzero(result, BUFSIZ);
+	return ok;
+}
+
+
+/* Internal functions to open, handle and close a channel to the console.  */
+static int
+open_console(UI *ui)
+{
+	CRYPTO_w_lock(CRYPTO_LOCK_UI);
+	is_a_tty = 1;
+
+#define DEV_TTY "/dev/tty"
+	if ((tty_in = fopen(DEV_TTY, "r")) == NULL)
+		tty_in = stdin;
+	if ((tty_out = fopen(DEV_TTY, "w")) == NULL)
+		tty_out = stderr;
+
+	if (tcgetattr(fileno(tty_in), &tty_orig) == -1) {
+		if (errno == ENOTTY)
+			is_a_tty = 0;
+		else
+			/*
+			 * Ariel Glenn ariel@columbia.edu reports that
+			 * solaris can return EINVAL instead.  This should be
+			 * ok
+			 */
+			if (errno == EINVAL)
+				is_a_tty = 0;
+		else
+			return 0;
+	}
+
+	return 1;
+}
+
+static int
+noecho_console(UI *ui)
+{
+	struct termios tty_new = tty_orig;
+
+	tty_new.c_lflag &= ~ECHO;
+	if (is_a_tty && (tcsetattr(fileno(tty_in), TCSANOW, &tty_new) == -1))
+		return 0;
+	return 1;
+}
+
+static int
+echo_console(UI *ui)
+{
+	if (is_a_tty && (tcsetattr(fileno(tty_in), TCSANOW, &tty_orig) == -1))
+		return 0;
+	return 1;
+}
+
+static int
+close_console(UI *ui)
+{
+	if (tty_in != stdin)
+		fclose(tty_in);
+	if (tty_out != stderr)
+		fclose(tty_out);
+	CRYPTO_w_unlock(CRYPTO_LOCK_UI);
+
+	return 1;
+}
+
+
+/* Internal functions to handle signals and act on them */
+static void
+pushsig(void)
+{
+	int i;
+	struct sigaction sa;
+
+	memset(&sa, 0, sizeof sa);
+	sa.sa_handler = recsig;
+
+	for (i = 1; i < NX509_SIG; i++) {
+		if (i == SIGUSR1)
+			continue;
+		if (i == SIGUSR2)
+			continue;
+		if (i == SIGKILL)	/* We can't make any action on that. */
+			continue;
+		sigaction(i, &sa, &savsig[i]);
+	}
+
+	signal(SIGWINCH, SIG_DFL);
+}
+
+static void
+popsig(void)
+{
+	int i;
+	for (i = 1; i < NX509_SIG; i++) {
+		if (i == SIGUSR1)
+			continue;
+		if (i == SIGUSR2)
+			continue;
+		sigaction(i, &savsig[i], NULL);
+	}
+}
+
+static void
+recsig(int i)
+{
+	intr_signal = i;
+}
diff --git a/crypto/libressl/crypto/ui/ui_openssl_win.c b/crypto/libressl/crypto/ui/ui_openssl_win.c
new file mode 100644
index 0000000000..ad9e91569d
--- /dev/null
+++ b/crypto/libressl/crypto/ui/ui_openssl_win.c
@@ -0,0 +1,379 @@
+/* $OpenBSD: ui_openssl.c,v 1.22 2014/07/11 08:44:49 jsing Exp $ */
+/* Written by Richard Levitte (richard@levitte.org) and others
+ * for the OpenSSL project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* The lowest level part of this file was previously in crypto/des/read_pwd.c,
+ * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ui_locl.h"
+
+#ifndef NX509_SIG
+#define NX509_SIG 32
+#endif
+
+/* Define globals.  They are protected by a lock */
+static void (*savsig[NX509_SIG])(int );
+
+DWORD console_mode;
+static FILE *tty_in, *tty_out;
+static int is_a_tty;
+
+/* Declare static functions */
+static int read_till_nl(FILE *);
+static void recsig(int);
+static void pushsig(void);
+static void popsig(void);
+static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl);
+
+static int read_string(UI *ui, UI_STRING *uis);
+static int write_string(UI *ui, UI_STRING *uis);
+
+static int open_console(UI *ui);
+static int echo_console(UI *ui);
+static int noecho_console(UI *ui);
+static int close_console(UI *ui);
+
+static UI_METHOD ui_openssl = {
+	.name = "OpenSSL default user interface",
+	.ui_open_session = open_console,
+	.ui_write_string = write_string,
+	.ui_read_string = read_string,
+	.ui_close_session = close_console,
+};
+
+/* The method with all the built-in thingies */
+UI_METHOD *
+UI_OpenSSL(void)
+{
+	return &ui_openssl;
+}
+
+/* The following function makes sure that info and error strings are printed
+   before any prompt. */
+static int
+write_string(UI *ui, UI_STRING *uis)
+{
+	switch (UI_get_string_type(uis)) {
+	case UIT_ERROR:
+	case UIT_INFO:
+		fputs(UI_get0_output_string(uis), tty_out);
+		fflush(tty_out);
+		break;
+	default:
+		break;
+	}
+	return 1;
+}
+
+static int
+read_string(UI *ui, UI_STRING *uis)
+{
+	int ok = 0;
+
+	switch (UI_get_string_type(uis)) {
+	case UIT_BOOLEAN:
+		fputs(UI_get0_output_string(uis), tty_out);
+		fputs(UI_get0_action_string(uis), tty_out);
+		fflush(tty_out);
+		return read_string_inner(ui, uis,
+		    UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 0);
+	case UIT_PROMPT:
+		fputs(UI_get0_output_string(uis), tty_out);
+		fflush(tty_out);
+		return read_string_inner(ui, uis,
+		    UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 1);
+	case UIT_VERIFY:
+		fprintf(tty_out, "Verifying - %s",
+		    UI_get0_output_string(uis));
+		fflush(tty_out);
+		if ((ok = read_string_inner(ui, uis, UI_get_input_flags(uis) &
+		    UI_INPUT_FLAG_ECHO, 1)) <= 0)
+			return ok;
+		if (strcmp(UI_get0_result_string(uis),
+		    UI_get0_test_string(uis)) != 0) {
+			fprintf(tty_out, "Verify failure\n");
+			fflush(tty_out);
+			return 0;
+		}
+		break;
+	default:
+		break;
+	}
+	return 1;
+}
+
+
+/* Internal functions to read a string without echoing */
+static int
+read_till_nl(FILE *in)
+{
+#define SIZE 4
+	char buf[SIZE + 1];
+
+	do {
+		if (!fgets(buf, SIZE, in))
+			return 0;
+	} while (strchr(buf, '\n') == NULL);
+	return 1;
+}
+
+static volatile sig_atomic_t intr_signal;
+
+static int
+read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl)
+{
+	static int ps;
+	int ok;
+	char result[BUFSIZ];
+	int maxsize = BUFSIZ - 1;
+	char *p;
+
+	intr_signal = 0;
+	ok = 0;
+	ps = 0;
+
+	pushsig();
+
+	ps = 1;
+
+	if (!echo && !noecho_console(ui))
+		goto error;
+	ps = 2;
+
+	result[0] = '\0';
+	p = fgets(result, maxsize, tty_in);
+	if (!p)
+		goto error;
+	if (feof(tty_in))
+		goto error;
+	if (ferror(tty_in))
+		goto error;
+	if ((p = strchr(result, '\n')) != NULL) {
+		if (strip_nl)
+			*p = '\0';
+	} else if (!read_till_nl(tty_in))
+		goto error;
+	if (UI_set_result(ui, uis, result) >= 0)
+		ok = 1;
+
+error:
+	if (intr_signal == SIGINT)
+		ok = -1;
+	if (!echo)
+		fprintf(tty_out, "\n");
+	if (ps >= 2 && !echo && !echo_console(ui))
+		ok = 0;
+
+	if (ps >= 1)
+		popsig();
+
+	explicit_bzero(result, BUFSIZ);
+	return ok;
+}
+
+
+/* Internal functions to open, handle and close a channel to the console.  */
+static int
+open_console(UI *ui)
+{
+	CRYPTO_w_lock(CRYPTO_LOCK_UI);
+	is_a_tty = 1;
+
+	tty_in = stdin;
+	tty_out = stderr;
+
+	HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
+	if (handle != NULL && handle != INVALID_HANDLE_VALUE) {
+		if (GetFileType(handle) == FILE_TYPE_CHAR)
+			return GetConsoleMode(handle, &console_mode);
+		else
+			return 1;
+	}
+	return 0;
+}
+
+static int
+noecho_console(UI *ui)
+{
+	HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
+	if (handle != NULL && handle != INVALID_HANDLE_VALUE) {
+		if (GetFileType(handle) == FILE_TYPE_CHAR)
+			return SetConsoleMode(handle, console_mode & ~ENABLE_ECHO_INPUT);
+		else
+			return 1;
+	}
+	return 0;
+}
+
+static int
+echo_console(UI *ui)
+{
+	HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
+	if (handle != NULL && handle != INVALID_HANDLE_VALUE) {
+		if (GetFileType(handle) == FILE_TYPE_CHAR)
+			return SetConsoleMode(handle, console_mode);
+		else
+			return 1;
+	}
+	return 0;
+}
+
+static int
+close_console(UI *ui)
+{
+	if (tty_in != stdin)
+		fclose(tty_in);
+	if (tty_out != stderr)
+		fclose(tty_out);
+	CRYPTO_w_unlock(CRYPTO_LOCK_UI);
+
+	return 1;
+}
+
+/* Internal functions to handle signals and act on them */
+static void
+pushsig(void)
+{
+	savsig[SIGABRT] = signal(SIGABRT, recsig);
+	savsig[SIGFPE]  = signal(SIGFPE,  recsig);
+	savsig[SIGILL]  = signal(SIGILL,  recsig);
+	savsig[SIGINT]  = signal(SIGINT,  recsig);
+	savsig[SIGSEGV] = signal(SIGSEGV, recsig);
+	savsig[SIGTERM] = signal(SIGTERM, recsig);
+}
+
+static void
+popsig(void)
+{
+	signal(SIGABRT, savsig[SIGABRT]);
+	signal(SIGFPE,  savsig[SIGFPE]);
+	signal(SIGILL,  savsig[SIGILL]);
+	signal(SIGINT,  savsig[SIGINT]);
+	signal(SIGSEGV, savsig[SIGSEGV]);
+	signal(SIGTERM, savsig[SIGTERM]);
+}
+
+static void
+recsig(int i)
+{
+	intr_signal = i;
+}
diff --git a/crypto/libressl/crypto/ui/ui_util.c b/crypto/libressl/crypto/ui/ui_util.c
new file mode 100644
index 0000000000..c4c1960dd3
--- /dev/null
+++ b/crypto/libressl/crypto/ui/ui_util.c
@@ -0,0 +1,111 @@
+/* $OpenBSD: ui_util.c,v 1.9 2014/06/12 15:49:31 deraadt Exp $ */
+/* ====================================================================
+ * Copyright (c) 2001-2002 The OpenSSL Project.  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 acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include 
+
+#include 
+
+#include "ui_locl.h"
+
+int
+UI_UTIL_read_pw_string(char *buf, int length, const char *prompt, int verify)
+{
+	char buff[BUFSIZ];
+	int ret;
+
+	ret = UI_UTIL_read_pw(buf, buff, (length > BUFSIZ) ? BUFSIZ : length,
+	    prompt, verify);
+	explicit_bzero(buff, BUFSIZ);
+	return (ret);
+}
+
+int
+UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt, int verify)
+{
+	int ok = 0;
+	UI *ui;
+
+	if (size < 1)
+		return -1;
+
+	ui = UI_new();
+	if (ui) {
+		ok = UI_add_input_string(ui, prompt, 0, buf, 0, size - 1);
+		if (ok >= 0 && verify)
+			ok = UI_add_verify_string(ui, prompt, 0, buff, 0,
+			    size - 1, buf);
+		if (ok >= 0)
+			ok = UI_process(ui);
+		UI_free(ui);
+	}
+	if (ok > 0)
+		ok = 0;
+	return (ok);
+}
+
+/*
+ * Old compatibility glue - see comment in ui_compat.h.
+ */
+int
+_ossl_old_des_read_pw_string(char *buf, int length, const char *prompt, int verify)
+{
+	return UI_UTIL_read_pw_string(buf, length, prompt, verify);
+}
+
+int
+_ossl_old_des_read_pw(char *buf, char *buff, int size, const char *prompt, int verify)
+{
+	return UI_UTIL_read_pw(buf, buff, size, prompt, verify);
+}
diff --git a/crypto/libressl/crypto/whrlpool/wp-elf-x86_64.s b/crypto/libressl/crypto/whrlpool/wp-elf-x86_64.s
new file mode 100644
index 0000000000..bd5d3beeac
--- /dev/null
+++ b/crypto/libressl/crypto/whrlpool/wp-elf-x86_64.s
@@ -0,0 +1,861 @@
+.text	
+
+.globl	whirlpool_block
+.type	whirlpool_block,@function
+.align	16
+whirlpool_block:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+
+	movq	%rsp,%r11
+	subq	$128+40,%rsp
+	andq	$-64,%rsp
+
+	leaq	128(%rsp),%r10
+	movq	%rdi,0(%r10)
+	movq	%rsi,8(%r10)
+	movq	%rdx,16(%r10)
+	movq	%r11,32(%r10)
+.Lprologue:
+
+	movq	%r10,%rbx
+	leaq	.Ltable(%rip),%rbp
+
+	xorq	%rcx,%rcx
+	xorq	%rdx,%rdx
+	movq	0(%rdi),%r8
+	movq	8(%rdi),%r9
+	movq	16(%rdi),%r10
+	movq	24(%rdi),%r11
+	movq	32(%rdi),%r12
+	movq	40(%rdi),%r13
+	movq	48(%rdi),%r14
+	movq	56(%rdi),%r15
+.Louterloop:
+	movq	%r8,0(%rsp)
+	movq	%r9,8(%rsp)
+	movq	%r10,16(%rsp)
+	movq	%r11,24(%rsp)
+	movq	%r12,32(%rsp)
+	movq	%r13,40(%rsp)
+	movq	%r14,48(%rsp)
+	movq	%r15,56(%rsp)
+	xorq	0(%rsi),%r8
+	xorq	8(%rsi),%r9
+	xorq	16(%rsi),%r10
+	xorq	24(%rsi),%r11
+	xorq	32(%rsi),%r12
+	xorq	40(%rsi),%r13
+	xorq	48(%rsi),%r14
+	xorq	56(%rsi),%r15
+	movq	%r8,64+0(%rsp)
+	movq	%r9,64+8(%rsp)
+	movq	%r10,64+16(%rsp)
+	movq	%r11,64+24(%rsp)
+	movq	%r12,64+32(%rsp)
+	movq	%r13,64+40(%rsp)
+	movq	%r14,64+48(%rsp)
+	movq	%r15,64+56(%rsp)
+	xorq	%rsi,%rsi
+	movq	%rsi,24(%rbx)
+.align	16
+.Lround:
+	movq	4096(%rbp,%rsi,8),%r8
+	movl	0(%rsp),%eax
+	movl	4(%rsp),%ebx
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r8
+	movq	7(%rbp,%rdi,8),%r9
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	0+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	movq	6(%rbp,%rsi,8),%r10
+	movq	5(%rbp,%rdi,8),%r11
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	movq	4(%rbp,%rsi,8),%r12
+	movq	3(%rbp,%rdi,8),%r13
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	0+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	movq	2(%rbp,%rsi,8),%r14
+	movq	1(%rbp,%rdi,8),%r15
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r9
+	xorq	7(%rbp,%rdi,8),%r10
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	8+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r11
+	xorq	5(%rbp,%rdi,8),%r12
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r13
+	xorq	3(%rbp,%rdi,8),%r14
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	8+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r15
+	xorq	1(%rbp,%rdi,8),%r8
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r10
+	xorq	7(%rbp,%rdi,8),%r11
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	16+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r12
+	xorq	5(%rbp,%rdi,8),%r13
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r14
+	xorq	3(%rbp,%rdi,8),%r15
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	16+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r8
+	xorq	1(%rbp,%rdi,8),%r9
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r11
+	xorq	7(%rbp,%rdi,8),%r12
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	24+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r13
+	xorq	5(%rbp,%rdi,8),%r14
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r15
+	xorq	3(%rbp,%rdi,8),%r8
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	24+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r9
+	xorq	1(%rbp,%rdi,8),%r10
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r12
+	xorq	7(%rbp,%rdi,8),%r13
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	32+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r14
+	xorq	5(%rbp,%rdi,8),%r15
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r8
+	xorq	3(%rbp,%rdi,8),%r9
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	32+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r10
+	xorq	1(%rbp,%rdi,8),%r11
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r13
+	xorq	7(%rbp,%rdi,8),%r14
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	40+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r15
+	xorq	5(%rbp,%rdi,8),%r8
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r9
+	xorq	3(%rbp,%rdi,8),%r10
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	40+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r11
+	xorq	1(%rbp,%rdi,8),%r12
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r14
+	xorq	7(%rbp,%rdi,8),%r15
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	48+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r8
+	xorq	5(%rbp,%rdi,8),%r9
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r10
+	xorq	3(%rbp,%rdi,8),%r11
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	48+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r12
+	xorq	1(%rbp,%rdi,8),%r13
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r15
+	xorq	7(%rbp,%rdi,8),%r8
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	56+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r9
+	xorq	5(%rbp,%rdi,8),%r10
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r11
+	xorq	3(%rbp,%rdi,8),%r12
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	56+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r13
+	xorq	1(%rbp,%rdi,8),%r14
+	movq	%r8,0(%rsp)
+	movq	%r9,8(%rsp)
+	movq	%r10,16(%rsp)
+	movq	%r11,24(%rsp)
+	movq	%r12,32(%rsp)
+	movq	%r13,40(%rsp)
+	movq	%r14,48(%rsp)
+	movq	%r15,56(%rsp)
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r8
+	xorq	7(%rbp,%rdi,8),%r9
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	64+0+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r10
+	xorq	5(%rbp,%rdi,8),%r11
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r12
+	xorq	3(%rbp,%rdi,8),%r13
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	64+0+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r14
+	xorq	1(%rbp,%rdi,8),%r15
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r9
+	xorq	7(%rbp,%rdi,8),%r10
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	64+8+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r11
+	xorq	5(%rbp,%rdi,8),%r12
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r13
+	xorq	3(%rbp,%rdi,8),%r14
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	64+8+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r15
+	xorq	1(%rbp,%rdi,8),%r8
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r10
+	xorq	7(%rbp,%rdi,8),%r11
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	64+16+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r12
+	xorq	5(%rbp,%rdi,8),%r13
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r14
+	xorq	3(%rbp,%rdi,8),%r15
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	64+16+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r8
+	xorq	1(%rbp,%rdi,8),%r9
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r11
+	xorq	7(%rbp,%rdi,8),%r12
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	64+24+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r13
+	xorq	5(%rbp,%rdi,8),%r14
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r15
+	xorq	3(%rbp,%rdi,8),%r8
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	64+24+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r9
+	xorq	1(%rbp,%rdi,8),%r10
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r12
+	xorq	7(%rbp,%rdi,8),%r13
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	64+32+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r14
+	xorq	5(%rbp,%rdi,8),%r15
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r8
+	xorq	3(%rbp,%rdi,8),%r9
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	64+32+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r10
+	xorq	1(%rbp,%rdi,8),%r11
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r13
+	xorq	7(%rbp,%rdi,8),%r14
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	64+40+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r15
+	xorq	5(%rbp,%rdi,8),%r8
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r9
+	xorq	3(%rbp,%rdi,8),%r10
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	64+40+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r11
+	xorq	1(%rbp,%rdi,8),%r12
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r14
+	xorq	7(%rbp,%rdi,8),%r15
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	64+48+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r8
+	xorq	5(%rbp,%rdi,8),%r9
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r10
+	xorq	3(%rbp,%rdi,8),%r11
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	64+48+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r12
+	xorq	1(%rbp,%rdi,8),%r13
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r15
+	xorq	7(%rbp,%rdi,8),%r8
+	movb	%al,%cl
+	movb	%ah,%dl
+
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r9
+	xorq	5(%rbp,%rdi,8),%r10
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r11
+	xorq	3(%rbp,%rdi,8),%r12
+	movb	%bl,%cl
+	movb	%bh,%dl
+
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r13
+	xorq	1(%rbp,%rdi,8),%r14
+	leaq	128(%rsp),%rbx
+	movq	24(%rbx),%rsi
+	addq	$1,%rsi
+	cmpq	$10,%rsi
+	je	.Lroundsdone
+
+	movq	%rsi,24(%rbx)
+	movq	%r8,64+0(%rsp)
+	movq	%r9,64+8(%rsp)
+	movq	%r10,64+16(%rsp)
+	movq	%r11,64+24(%rsp)
+	movq	%r12,64+32(%rsp)
+	movq	%r13,64+40(%rsp)
+	movq	%r14,64+48(%rsp)
+	movq	%r15,64+56(%rsp)
+	jmp	.Lround
+.align	16
+.Lroundsdone:
+	movq	0(%rbx),%rdi
+	movq	8(%rbx),%rsi
+	movq	16(%rbx),%rax
+	xorq	0(%rsi),%r8
+	xorq	8(%rsi),%r9
+	xorq	16(%rsi),%r10
+	xorq	24(%rsi),%r11
+	xorq	32(%rsi),%r12
+	xorq	40(%rsi),%r13
+	xorq	48(%rsi),%r14
+	xorq	56(%rsi),%r15
+	xorq	0(%rdi),%r8
+	xorq	8(%rdi),%r9
+	xorq	16(%rdi),%r10
+	xorq	24(%rdi),%r11
+	xorq	32(%rdi),%r12
+	xorq	40(%rdi),%r13
+	xorq	48(%rdi),%r14
+	xorq	56(%rdi),%r15
+	movq	%r8,0(%rdi)
+	movq	%r9,8(%rdi)
+	movq	%r10,16(%rdi)
+	movq	%r11,24(%rdi)
+	movq	%r12,32(%rdi)
+	movq	%r13,40(%rdi)
+	movq	%r14,48(%rdi)
+	movq	%r15,56(%rdi)
+	leaq	64(%rsi),%rsi
+	subq	$1,%rax
+	jz	.Lalldone
+	movq	%rsi,8(%rbx)
+	movq	%rax,16(%rbx)
+	jmp	.Louterloop
+.Lalldone:
+	movq	32(%rbx),%rsi
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+.Lepilogue:
+	.byte	0xf3,0xc3
+.size	whirlpool_block,.-whirlpool_block
+
+.align	64
+.type	.Ltable,@object
+.Ltable:
+.byte	24,24,96,24,192,120,48,216,24,24,96,24,192,120,48,216
+.byte	35,35,140,35,5,175,70,38,35,35,140,35,5,175,70,38
+.byte	198,198,63,198,126,249,145,184,198,198,63,198,126,249,145,184
+.byte	232,232,135,232,19,111,205,251,232,232,135,232,19,111,205,251
+.byte	135,135,38,135,76,161,19,203,135,135,38,135,76,161,19,203
+.byte	184,184,218,184,169,98,109,17,184,184,218,184,169,98,109,17
+.byte	1,1,4,1,8,5,2,9,1,1,4,1,8,5,2,9
+.byte	79,79,33,79,66,110,158,13,79,79,33,79,66,110,158,13
+.byte	54,54,216,54,173,238,108,155,54,54,216,54,173,238,108,155
+.byte	166,166,162,166,89,4,81,255,166,166,162,166,89,4,81,255
+.byte	210,210,111,210,222,189,185,12,210,210,111,210,222,189,185,12
+.byte	245,245,243,245,251,6,247,14,245,245,243,245,251,6,247,14
+.byte	121,121,249,121,239,128,242,150,121,121,249,121,239,128,242,150
+.byte	111,111,161,111,95,206,222,48,111,111,161,111,95,206,222,48
+.byte	145,145,126,145,252,239,63,109,145,145,126,145,252,239,63,109
+.byte	82,82,85,82,170,7,164,248,82,82,85,82,170,7,164,248
+.byte	96,96,157,96,39,253,192,71,96,96,157,96,39,253,192,71
+.byte	188,188,202,188,137,118,101,53,188,188,202,188,137,118,101,53
+.byte	155,155,86,155,172,205,43,55,155,155,86,155,172,205,43,55
+.byte	142,142,2,142,4,140,1,138,142,142,2,142,4,140,1,138
+.byte	163,163,182,163,113,21,91,210,163,163,182,163,113,21,91,210
+.byte	12,12,48,12,96,60,24,108,12,12,48,12,96,60,24,108
+.byte	123,123,241,123,255,138,246,132,123,123,241,123,255,138,246,132
+.byte	53,53,212,53,181,225,106,128,53,53,212,53,181,225,106,128
+.byte	29,29,116,29,232,105,58,245,29,29,116,29,232,105,58,245
+.byte	224,224,167,224,83,71,221,179,224,224,167,224,83,71,221,179
+.byte	215,215,123,215,246,172,179,33,215,215,123,215,246,172,179,33
+.byte	194,194,47,194,94,237,153,156,194,194,47,194,94,237,153,156
+.byte	46,46,184,46,109,150,92,67,46,46,184,46,109,150,92,67
+.byte	75,75,49,75,98,122,150,41,75,75,49,75,98,122,150,41
+.byte	254,254,223,254,163,33,225,93,254,254,223,254,163,33,225,93
+.byte	87,87,65,87,130,22,174,213,87,87,65,87,130,22,174,213
+.byte	21,21,84,21,168,65,42,189,21,21,84,21,168,65,42,189
+.byte	119,119,193,119,159,182,238,232,119,119,193,119,159,182,238,232
+.byte	55,55,220,55,165,235,110,146,55,55,220,55,165,235,110,146
+.byte	229,229,179,229,123,86,215,158,229,229,179,229,123,86,215,158
+.byte	159,159,70,159,140,217,35,19,159,159,70,159,140,217,35,19
+.byte	240,240,231,240,211,23,253,35,240,240,231,240,211,23,253,35
+.byte	74,74,53,74,106,127,148,32,74,74,53,74,106,127,148,32
+.byte	218,218,79,218,158,149,169,68,218,218,79,218,158,149,169,68
+.byte	88,88,125,88,250,37,176,162,88,88,125,88,250,37,176,162
+.byte	201,201,3,201,6,202,143,207,201,201,3,201,6,202,143,207
+.byte	41,41,164,41,85,141,82,124,41,41,164,41,85,141,82,124
+.byte	10,10,40,10,80,34,20,90,10,10,40,10,80,34,20,90
+.byte	177,177,254,177,225,79,127,80,177,177,254,177,225,79,127,80
+.byte	160,160,186,160,105,26,93,201,160,160,186,160,105,26,93,201
+.byte	107,107,177,107,127,218,214,20,107,107,177,107,127,218,214,20
+.byte	133,133,46,133,92,171,23,217,133,133,46,133,92,171,23,217
+.byte	189,189,206,189,129,115,103,60,189,189,206,189,129,115,103,60
+.byte	93,93,105,93,210,52,186,143,93,93,105,93,210,52,186,143
+.byte	16,16,64,16,128,80,32,144,16,16,64,16,128,80,32,144
+.byte	244,244,247,244,243,3,245,7,244,244,247,244,243,3,245,7
+.byte	203,203,11,203,22,192,139,221,203,203,11,203,22,192,139,221
+.byte	62,62,248,62,237,198,124,211,62,62,248,62,237,198,124,211
+.byte	5,5,20,5,40,17,10,45,5,5,20,5,40,17,10,45
+.byte	103,103,129,103,31,230,206,120,103,103,129,103,31,230,206,120
+.byte	228,228,183,228,115,83,213,151,228,228,183,228,115,83,213,151
+.byte	39,39,156,39,37,187,78,2,39,39,156,39,37,187,78,2
+.byte	65,65,25,65,50,88,130,115,65,65,25,65,50,88,130,115
+.byte	139,139,22,139,44,157,11,167,139,139,22,139,44,157,11,167
+.byte	167,167,166,167,81,1,83,246,167,167,166,167,81,1,83,246
+.byte	125,125,233,125,207,148,250,178,125,125,233,125,207,148,250,178
+.byte	149,149,110,149,220,251,55,73,149,149,110,149,220,251,55,73
+.byte	216,216,71,216,142,159,173,86,216,216,71,216,142,159,173,86
+.byte	251,251,203,251,139,48,235,112,251,251,203,251,139,48,235,112
+.byte	238,238,159,238,35,113,193,205,238,238,159,238,35,113,193,205
+.byte	124,124,237,124,199,145,248,187,124,124,237,124,199,145,248,187
+.byte	102,102,133,102,23,227,204,113,102,102,133,102,23,227,204,113
+.byte	221,221,83,221,166,142,167,123,221,221,83,221,166,142,167,123
+.byte	23,23,92,23,184,75,46,175,23,23,92,23,184,75,46,175
+.byte	71,71,1,71,2,70,142,69,71,71,1,71,2,70,142,69
+.byte	158,158,66,158,132,220,33,26,158,158,66,158,132,220,33,26
+.byte	202,202,15,202,30,197,137,212,202,202,15,202,30,197,137,212
+.byte	45,45,180,45,117,153,90,88,45,45,180,45,117,153,90,88
+.byte	191,191,198,191,145,121,99,46,191,191,198,191,145,121,99,46
+.byte	7,7,28,7,56,27,14,63,7,7,28,7,56,27,14,63
+.byte	173,173,142,173,1,35,71,172,173,173,142,173,1,35,71,172
+.byte	90,90,117,90,234,47,180,176,90,90,117,90,234,47,180,176
+.byte	131,131,54,131,108,181,27,239,131,131,54,131,108,181,27,239
+.byte	51,51,204,51,133,255,102,182,51,51,204,51,133,255,102,182
+.byte	99,99,145,99,63,242,198,92,99,99,145,99,63,242,198,92
+.byte	2,2,8,2,16,10,4,18,2,2,8,2,16,10,4,18
+.byte	170,170,146,170,57,56,73,147,170,170,146,170,57,56,73,147
+.byte	113,113,217,113,175,168,226,222,113,113,217,113,175,168,226,222
+.byte	200,200,7,200,14,207,141,198,200,200,7,200,14,207,141,198
+.byte	25,25,100,25,200,125,50,209,25,25,100,25,200,125,50,209
+.byte	73,73,57,73,114,112,146,59,73,73,57,73,114,112,146,59
+.byte	217,217,67,217,134,154,175,95,217,217,67,217,134,154,175,95
+.byte	242,242,239,242,195,29,249,49,242,242,239,242,195,29,249,49
+.byte	227,227,171,227,75,72,219,168,227,227,171,227,75,72,219,168
+.byte	91,91,113,91,226,42,182,185,91,91,113,91,226,42,182,185
+.byte	136,136,26,136,52,146,13,188,136,136,26,136,52,146,13,188
+.byte	154,154,82,154,164,200,41,62,154,154,82,154,164,200,41,62
+.byte	38,38,152,38,45,190,76,11,38,38,152,38,45,190,76,11
+.byte	50,50,200,50,141,250,100,191,50,50,200,50,141,250,100,191
+.byte	176,176,250,176,233,74,125,89,176,176,250,176,233,74,125,89
+.byte	233,233,131,233,27,106,207,242,233,233,131,233,27,106,207,242
+.byte	15,15,60,15,120,51,30,119,15,15,60,15,120,51,30,119
+.byte	213,213,115,213,230,166,183,51,213,213,115,213,230,166,183,51
+.byte	128,128,58,128,116,186,29,244,128,128,58,128,116,186,29,244
+.byte	190,190,194,190,153,124,97,39,190,190,194,190,153,124,97,39
+.byte	205,205,19,205,38,222,135,235,205,205,19,205,38,222,135,235
+.byte	52,52,208,52,189,228,104,137,52,52,208,52,189,228,104,137
+.byte	72,72,61,72,122,117,144,50,72,72,61,72,122,117,144,50
+.byte	255,255,219,255,171,36,227,84,255,255,219,255,171,36,227,84
+.byte	122,122,245,122,247,143,244,141,122,122,245,122,247,143,244,141
+.byte	144,144,122,144,244,234,61,100,144,144,122,144,244,234,61,100
+.byte	95,95,97,95,194,62,190,157,95,95,97,95,194,62,190,157
+.byte	32,32,128,32,29,160,64,61,32,32,128,32,29,160,64,61
+.byte	104,104,189,104,103,213,208,15,104,104,189,104,103,213,208,15
+.byte	26,26,104,26,208,114,52,202,26,26,104,26,208,114,52,202
+.byte	174,174,130,174,25,44,65,183,174,174,130,174,25,44,65,183
+.byte	180,180,234,180,201,94,117,125,180,180,234,180,201,94,117,125
+.byte	84,84,77,84,154,25,168,206,84,84,77,84,154,25,168,206
+.byte	147,147,118,147,236,229,59,127,147,147,118,147,236,229,59,127
+.byte	34,34,136,34,13,170,68,47,34,34,136,34,13,170,68,47
+.byte	100,100,141,100,7,233,200,99,100,100,141,100,7,233,200,99
+.byte	241,241,227,241,219,18,255,42,241,241,227,241,219,18,255,42
+.byte	115,115,209,115,191,162,230,204,115,115,209,115,191,162,230,204
+.byte	18,18,72,18,144,90,36,130,18,18,72,18,144,90,36,130
+.byte	64,64,29,64,58,93,128,122,64,64,29,64,58,93,128,122
+.byte	8,8,32,8,64,40,16,72,8,8,32,8,64,40,16,72
+.byte	195,195,43,195,86,232,155,149,195,195,43,195,86,232,155,149
+.byte	236,236,151,236,51,123,197,223,236,236,151,236,51,123,197,223
+.byte	219,219,75,219,150,144,171,77,219,219,75,219,150,144,171,77
+.byte	161,161,190,161,97,31,95,192,161,161,190,161,97,31,95,192
+.byte	141,141,14,141,28,131,7,145,141,141,14,141,28,131,7,145
+.byte	61,61,244,61,245,201,122,200,61,61,244,61,245,201,122,200
+.byte	151,151,102,151,204,241,51,91,151,151,102,151,204,241,51,91
+.byte	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+.byte	207,207,27,207,54,212,131,249,207,207,27,207,54,212,131,249
+.byte	43,43,172,43,69,135,86,110,43,43,172,43,69,135,86,110
+.byte	118,118,197,118,151,179,236,225,118,118,197,118,151,179,236,225
+.byte	130,130,50,130,100,176,25,230,130,130,50,130,100,176,25,230
+.byte	214,214,127,214,254,169,177,40,214,214,127,214,254,169,177,40
+.byte	27,27,108,27,216,119,54,195,27,27,108,27,216,119,54,195
+.byte	181,181,238,181,193,91,119,116,181,181,238,181,193,91,119,116
+.byte	175,175,134,175,17,41,67,190,175,175,134,175,17,41,67,190
+.byte	106,106,181,106,119,223,212,29,106,106,181,106,119,223,212,29
+.byte	80,80,93,80,186,13,160,234,80,80,93,80,186,13,160,234
+.byte	69,69,9,69,18,76,138,87,69,69,9,69,18,76,138,87
+.byte	243,243,235,243,203,24,251,56,243,243,235,243,203,24,251,56
+.byte	48,48,192,48,157,240,96,173,48,48,192,48,157,240,96,173
+.byte	239,239,155,239,43,116,195,196,239,239,155,239,43,116,195,196
+.byte	63,63,252,63,229,195,126,218,63,63,252,63,229,195,126,218
+.byte	85,85,73,85,146,28,170,199,85,85,73,85,146,28,170,199
+.byte	162,162,178,162,121,16,89,219,162,162,178,162,121,16,89,219
+.byte	234,234,143,234,3,101,201,233,234,234,143,234,3,101,201,233
+.byte	101,101,137,101,15,236,202,106,101,101,137,101,15,236,202,106
+.byte	186,186,210,186,185,104,105,3,186,186,210,186,185,104,105,3
+.byte	47,47,188,47,101,147,94,74,47,47,188,47,101,147,94,74
+.byte	192,192,39,192,78,231,157,142,192,192,39,192,78,231,157,142
+.byte	222,222,95,222,190,129,161,96,222,222,95,222,190,129,161,96
+.byte	28,28,112,28,224,108,56,252,28,28,112,28,224,108,56,252
+.byte	253,253,211,253,187,46,231,70,253,253,211,253,187,46,231,70
+.byte	77,77,41,77,82,100,154,31,77,77,41,77,82,100,154,31
+.byte	146,146,114,146,228,224,57,118,146,146,114,146,228,224,57,118
+.byte	117,117,201,117,143,188,234,250,117,117,201,117,143,188,234,250
+.byte	6,6,24,6,48,30,12,54,6,6,24,6,48,30,12,54
+.byte	138,138,18,138,36,152,9,174,138,138,18,138,36,152,9,174
+.byte	178,178,242,178,249,64,121,75,178,178,242,178,249,64,121,75
+.byte	230,230,191,230,99,89,209,133,230,230,191,230,99,89,209,133
+.byte	14,14,56,14,112,54,28,126,14,14,56,14,112,54,28,126
+.byte	31,31,124,31,248,99,62,231,31,31,124,31,248,99,62,231
+.byte	98,98,149,98,55,247,196,85,98,98,149,98,55,247,196,85
+.byte	212,212,119,212,238,163,181,58,212,212,119,212,238,163,181,58
+.byte	168,168,154,168,41,50,77,129,168,168,154,168,41,50,77,129
+.byte	150,150,98,150,196,244,49,82,150,150,98,150,196,244,49,82
+.byte	249,249,195,249,155,58,239,98,249,249,195,249,155,58,239,98
+.byte	197,197,51,197,102,246,151,163,197,197,51,197,102,246,151,163
+.byte	37,37,148,37,53,177,74,16,37,37,148,37,53,177,74,16
+.byte	89,89,121,89,242,32,178,171,89,89,121,89,242,32,178,171
+.byte	132,132,42,132,84,174,21,208,132,132,42,132,84,174,21,208
+.byte	114,114,213,114,183,167,228,197,114,114,213,114,183,167,228,197
+.byte	57,57,228,57,213,221,114,236,57,57,228,57,213,221,114,236
+.byte	76,76,45,76,90,97,152,22,76,76,45,76,90,97,152,22
+.byte	94,94,101,94,202,59,188,148,94,94,101,94,202,59,188,148
+.byte	120,120,253,120,231,133,240,159,120,120,253,120,231,133,240,159
+.byte	56,56,224,56,221,216,112,229,56,56,224,56,221,216,112,229
+.byte	140,140,10,140,20,134,5,152,140,140,10,140,20,134,5,152
+.byte	209,209,99,209,198,178,191,23,209,209,99,209,198,178,191,23
+.byte	165,165,174,165,65,11,87,228,165,165,174,165,65,11,87,228
+.byte	226,226,175,226,67,77,217,161,226,226,175,226,67,77,217,161
+.byte	97,97,153,97,47,248,194,78,97,97,153,97,47,248,194,78
+.byte	179,179,246,179,241,69,123,66,179,179,246,179,241,69,123,66
+.byte	33,33,132,33,21,165,66,52,33,33,132,33,21,165,66,52
+.byte	156,156,74,156,148,214,37,8,156,156,74,156,148,214,37,8
+.byte	30,30,120,30,240,102,60,238,30,30,120,30,240,102,60,238
+.byte	67,67,17,67,34,82,134,97,67,67,17,67,34,82,134,97
+.byte	199,199,59,199,118,252,147,177,199,199,59,199,118,252,147,177
+.byte	252,252,215,252,179,43,229,79,252,252,215,252,179,43,229,79
+.byte	4,4,16,4,32,20,8,36,4,4,16,4,32,20,8,36
+.byte	81,81,89,81,178,8,162,227,81,81,89,81,178,8,162,227
+.byte	153,153,94,153,188,199,47,37,153,153,94,153,188,199,47,37
+.byte	109,109,169,109,79,196,218,34,109,109,169,109,79,196,218,34
+.byte	13,13,52,13,104,57,26,101,13,13,52,13,104,57,26,101
+.byte	250,250,207,250,131,53,233,121,250,250,207,250,131,53,233,121
+.byte	223,223,91,223,182,132,163,105,223,223,91,223,182,132,163,105
+.byte	126,126,229,126,215,155,252,169,126,126,229,126,215,155,252,169
+.byte	36,36,144,36,61,180,72,25,36,36,144,36,61,180,72,25
+.byte	59,59,236,59,197,215,118,254,59,59,236,59,197,215,118,254
+.byte	171,171,150,171,49,61,75,154,171,171,150,171,49,61,75,154
+.byte	206,206,31,206,62,209,129,240,206,206,31,206,62,209,129,240
+.byte	17,17,68,17,136,85,34,153,17,17,68,17,136,85,34,153
+.byte	143,143,6,143,12,137,3,131,143,143,6,143,12,137,3,131
+.byte	78,78,37,78,74,107,156,4,78,78,37,78,74,107,156,4
+.byte	183,183,230,183,209,81,115,102,183,183,230,183,209,81,115,102
+.byte	235,235,139,235,11,96,203,224,235,235,139,235,11,96,203,224
+.byte	60,60,240,60,253,204,120,193,60,60,240,60,253,204,120,193
+.byte	129,129,62,129,124,191,31,253,129,129,62,129,124,191,31,253
+.byte	148,148,106,148,212,254,53,64,148,148,106,148,212,254,53,64
+.byte	247,247,251,247,235,12,243,28,247,247,251,247,235,12,243,28
+.byte	185,185,222,185,161,103,111,24,185,185,222,185,161,103,111,24
+.byte	19,19,76,19,152,95,38,139,19,19,76,19,152,95,38,139
+.byte	44,44,176,44,125,156,88,81,44,44,176,44,125,156,88,81
+.byte	211,211,107,211,214,184,187,5,211,211,107,211,214,184,187,5
+.byte	231,231,187,231,107,92,211,140,231,231,187,231,107,92,211,140
+.byte	110,110,165,110,87,203,220,57,110,110,165,110,87,203,220,57
+.byte	196,196,55,196,110,243,149,170,196,196,55,196,110,243,149,170
+.byte	3,3,12,3,24,15,6,27,3,3,12,3,24,15,6,27
+.byte	86,86,69,86,138,19,172,220,86,86,69,86,138,19,172,220
+.byte	68,68,13,68,26,73,136,94,68,68,13,68,26,73,136,94
+.byte	127,127,225,127,223,158,254,160,127,127,225,127,223,158,254,160
+.byte	169,169,158,169,33,55,79,136,169,169,158,169,33,55,79,136
+.byte	42,42,168,42,77,130,84,103,42,42,168,42,77,130,84,103
+.byte	187,187,214,187,177,109,107,10,187,187,214,187,177,109,107,10
+.byte	193,193,35,193,70,226,159,135,193,193,35,193,70,226,159,135
+.byte	83,83,81,83,162,2,166,241,83,83,81,83,162,2,166,241
+.byte	220,220,87,220,174,139,165,114,220,220,87,220,174,139,165,114
+.byte	11,11,44,11,88,39,22,83,11,11,44,11,88,39,22,83
+.byte	157,157,78,157,156,211,39,1,157,157,78,157,156,211,39,1
+.byte	108,108,173,108,71,193,216,43,108,108,173,108,71,193,216,43
+.byte	49,49,196,49,149,245,98,164,49,49,196,49,149,245,98,164
+.byte	116,116,205,116,135,185,232,243,116,116,205,116,135,185,232,243
+.byte	246,246,255,246,227,9,241,21,246,246,255,246,227,9,241,21
+.byte	70,70,5,70,10,67,140,76,70,70,5,70,10,67,140,76
+.byte	172,172,138,172,9,38,69,165,172,172,138,172,9,38,69,165
+.byte	137,137,30,137,60,151,15,181,137,137,30,137,60,151,15,181
+.byte	20,20,80,20,160,68,40,180,20,20,80,20,160,68,40,180
+.byte	225,225,163,225,91,66,223,186,225,225,163,225,91,66,223,186
+.byte	22,22,88,22,176,78,44,166,22,22,88,22,176,78,44,166
+.byte	58,58,232,58,205,210,116,247,58,58,232,58,205,210,116,247
+.byte	105,105,185,105,111,208,210,6,105,105,185,105,111,208,210,6
+.byte	9,9,36,9,72,45,18,65,9,9,36,9,72,45,18,65
+.byte	112,112,221,112,167,173,224,215,112,112,221,112,167,173,224,215
+.byte	182,182,226,182,217,84,113,111,182,182,226,182,217,84,113,111
+.byte	208,208,103,208,206,183,189,30,208,208,103,208,206,183,189,30
+.byte	237,237,147,237,59,126,199,214,237,237,147,237,59,126,199,214
+.byte	204,204,23,204,46,219,133,226,204,204,23,204,46,219,133,226
+.byte	66,66,21,66,42,87,132,104,66,66,21,66,42,87,132,104
+.byte	152,152,90,152,180,194,45,44,152,152,90,152,180,194,45,44
+.byte	164,164,170,164,73,14,85,237,164,164,170,164,73,14,85,237
+.byte	40,40,160,40,93,136,80,117,40,40,160,40,93,136,80,117
+.byte	92,92,109,92,218,49,184,134,92,92,109,92,218,49,184,134
+.byte	248,248,199,248,147,63,237,107,248,248,199,248,147,63,237,107
+.byte	134,134,34,134,68,164,17,194,134,134,34,134,68,164,17,194
+.byte	24,35,198,232,135,184,1,79
+.byte	54,166,210,245,121,111,145,82
+.byte	96,188,155,142,163,12,123,53
+.byte	29,224,215,194,46,75,254,87
+.byte	21,119,55,229,159,240,74,218
+.byte	88,201,41,10,177,160,107,133
+.byte	189,93,16,244,203,62,5,103
+.byte	228,39,65,139,167,125,149,216
+.byte	251,238,124,102,221,23,71,158
+.byte	202,45,191,7,173,90,131,51
+#if defined(HAVE_GNU_STACK)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/crypto/libressl/crypto/whrlpool/wp-macosx-x86_64.s b/crypto/libressl/crypto/whrlpool/wp-macosx-x86_64.s
new file mode 100644
index 0000000000..ea7d73f995
--- /dev/null
+++ b/crypto/libressl/crypto/whrlpool/wp-macosx-x86_64.s
@@ -0,0 +1,858 @@
+.text	
+
+.globl	_whirlpool_block
+
+.p2align	4
+_whirlpool_block:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+
+	movq	%rsp,%r11
+	subq	$128+40,%rsp
+	andq	$-64,%rsp
+
+	leaq	128(%rsp),%r10
+	movq	%rdi,0(%r10)
+	movq	%rsi,8(%r10)
+	movq	%rdx,16(%r10)
+	movq	%r11,32(%r10)
+L$prologue:
+
+	movq	%r10,%rbx
+	leaq	L$table(%rip),%rbp
+
+	xorq	%rcx,%rcx
+	xorq	%rdx,%rdx
+	movq	0(%rdi),%r8
+	movq	8(%rdi),%r9
+	movq	16(%rdi),%r10
+	movq	24(%rdi),%r11
+	movq	32(%rdi),%r12
+	movq	40(%rdi),%r13
+	movq	48(%rdi),%r14
+	movq	56(%rdi),%r15
+L$outerloop:
+	movq	%r8,0(%rsp)
+	movq	%r9,8(%rsp)
+	movq	%r10,16(%rsp)
+	movq	%r11,24(%rsp)
+	movq	%r12,32(%rsp)
+	movq	%r13,40(%rsp)
+	movq	%r14,48(%rsp)
+	movq	%r15,56(%rsp)
+	xorq	0(%rsi),%r8
+	xorq	8(%rsi),%r9
+	xorq	16(%rsi),%r10
+	xorq	24(%rsi),%r11
+	xorq	32(%rsi),%r12
+	xorq	40(%rsi),%r13
+	xorq	48(%rsi),%r14
+	xorq	56(%rsi),%r15
+	movq	%r8,64+0(%rsp)
+	movq	%r9,64+8(%rsp)
+	movq	%r10,64+16(%rsp)
+	movq	%r11,64+24(%rsp)
+	movq	%r12,64+32(%rsp)
+	movq	%r13,64+40(%rsp)
+	movq	%r14,64+48(%rsp)
+	movq	%r15,64+56(%rsp)
+	xorq	%rsi,%rsi
+	movq	%rsi,24(%rbx)
+.p2align	4
+L$round:
+	movq	4096(%rbp,%rsi,8),%r8
+	movl	0(%rsp),%eax
+	movl	4(%rsp),%ebx
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r8
+	movq	7(%rbp,%rdi,8),%r9
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	0+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	movq	6(%rbp,%rsi,8),%r10
+	movq	5(%rbp,%rdi,8),%r11
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	movq	4(%rbp,%rsi,8),%r12
+	movq	3(%rbp,%rdi,8),%r13
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	0+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	movq	2(%rbp,%rsi,8),%r14
+	movq	1(%rbp,%rdi,8),%r15
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r9
+	xorq	7(%rbp,%rdi,8),%r10
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	8+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r11
+	xorq	5(%rbp,%rdi,8),%r12
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r13
+	xorq	3(%rbp,%rdi,8),%r14
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	8+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r15
+	xorq	1(%rbp,%rdi,8),%r8
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r10
+	xorq	7(%rbp,%rdi,8),%r11
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	16+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r12
+	xorq	5(%rbp,%rdi,8),%r13
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r14
+	xorq	3(%rbp,%rdi,8),%r15
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	16+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r8
+	xorq	1(%rbp,%rdi,8),%r9
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r11
+	xorq	7(%rbp,%rdi,8),%r12
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	24+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r13
+	xorq	5(%rbp,%rdi,8),%r14
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r15
+	xorq	3(%rbp,%rdi,8),%r8
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	24+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r9
+	xorq	1(%rbp,%rdi,8),%r10
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r12
+	xorq	7(%rbp,%rdi,8),%r13
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	32+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r14
+	xorq	5(%rbp,%rdi,8),%r15
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r8
+	xorq	3(%rbp,%rdi,8),%r9
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	32+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r10
+	xorq	1(%rbp,%rdi,8),%r11
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r13
+	xorq	7(%rbp,%rdi,8),%r14
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	40+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r15
+	xorq	5(%rbp,%rdi,8),%r8
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r9
+	xorq	3(%rbp,%rdi,8),%r10
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	40+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r11
+	xorq	1(%rbp,%rdi,8),%r12
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r14
+	xorq	7(%rbp,%rdi,8),%r15
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	48+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r8
+	xorq	5(%rbp,%rdi,8),%r9
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r10
+	xorq	3(%rbp,%rdi,8),%r11
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	48+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r12
+	xorq	1(%rbp,%rdi,8),%r13
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r15
+	xorq	7(%rbp,%rdi,8),%r8
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	56+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r9
+	xorq	5(%rbp,%rdi,8),%r10
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r11
+	xorq	3(%rbp,%rdi,8),%r12
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	56+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r13
+	xorq	1(%rbp,%rdi,8),%r14
+	movq	%r8,0(%rsp)
+	movq	%r9,8(%rsp)
+	movq	%r10,16(%rsp)
+	movq	%r11,24(%rsp)
+	movq	%r12,32(%rsp)
+	movq	%r13,40(%rsp)
+	movq	%r14,48(%rsp)
+	movq	%r15,56(%rsp)
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r8
+	xorq	7(%rbp,%rdi,8),%r9
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	64+0+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r10
+	xorq	5(%rbp,%rdi,8),%r11
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r12
+	xorq	3(%rbp,%rdi,8),%r13
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	64+0+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r14
+	xorq	1(%rbp,%rdi,8),%r15
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r9
+	xorq	7(%rbp,%rdi,8),%r10
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	64+8+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r11
+	xorq	5(%rbp,%rdi,8),%r12
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r13
+	xorq	3(%rbp,%rdi,8),%r14
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	64+8+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r15
+	xorq	1(%rbp,%rdi,8),%r8
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r10
+	xorq	7(%rbp,%rdi,8),%r11
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	64+16+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r12
+	xorq	5(%rbp,%rdi,8),%r13
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r14
+	xorq	3(%rbp,%rdi,8),%r15
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	64+16+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r8
+	xorq	1(%rbp,%rdi,8),%r9
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r11
+	xorq	7(%rbp,%rdi,8),%r12
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	64+24+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r13
+	xorq	5(%rbp,%rdi,8),%r14
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r15
+	xorq	3(%rbp,%rdi,8),%r8
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	64+24+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r9
+	xorq	1(%rbp,%rdi,8),%r10
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r12
+	xorq	7(%rbp,%rdi,8),%r13
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	64+32+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r14
+	xorq	5(%rbp,%rdi,8),%r15
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r8
+	xorq	3(%rbp,%rdi,8),%r9
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	64+32+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r10
+	xorq	1(%rbp,%rdi,8),%r11
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r13
+	xorq	7(%rbp,%rdi,8),%r14
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	64+40+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r15
+	xorq	5(%rbp,%rdi,8),%r8
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r9
+	xorq	3(%rbp,%rdi,8),%r10
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	64+40+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r11
+	xorq	1(%rbp,%rdi,8),%r12
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r14
+	xorq	7(%rbp,%rdi,8),%r15
+	movb	%al,%cl
+	movb	%ah,%dl
+	movl	64+48+8(%rsp),%eax
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r8
+	xorq	5(%rbp,%rdi,8),%r9
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r10
+	xorq	3(%rbp,%rdi,8),%r11
+	movb	%bl,%cl
+	movb	%bh,%dl
+	movl	64+48+8+4(%rsp),%ebx
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r12
+	xorq	1(%rbp,%rdi,8),%r13
+	movb	%al,%cl
+	movb	%ah,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%eax
+	xorq	0(%rbp,%rsi,8),%r15
+	xorq	7(%rbp,%rdi,8),%r8
+	movb	%al,%cl
+	movb	%ah,%dl
+
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	6(%rbp,%rsi,8),%r9
+	xorq	5(%rbp,%rdi,8),%r10
+	movb	%bl,%cl
+	movb	%bh,%dl
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	shrl	$16,%ebx
+	xorq	4(%rbp,%rsi,8),%r11
+	xorq	3(%rbp,%rdi,8),%r12
+	movb	%bl,%cl
+	movb	%bh,%dl
+
+	leaq	(%rcx,%rcx,1),%rsi
+	leaq	(%rdx,%rdx,1),%rdi
+	xorq	2(%rbp,%rsi,8),%r13
+	xorq	1(%rbp,%rdi,8),%r14
+	leaq	128(%rsp),%rbx
+	movq	24(%rbx),%rsi
+	addq	$1,%rsi
+	cmpq	$10,%rsi
+	je	L$roundsdone
+
+	movq	%rsi,24(%rbx)
+	movq	%r8,64+0(%rsp)
+	movq	%r9,64+8(%rsp)
+	movq	%r10,64+16(%rsp)
+	movq	%r11,64+24(%rsp)
+	movq	%r12,64+32(%rsp)
+	movq	%r13,64+40(%rsp)
+	movq	%r14,64+48(%rsp)
+	movq	%r15,64+56(%rsp)
+	jmp	L$round
+.p2align	4
+L$roundsdone:
+	movq	0(%rbx),%rdi
+	movq	8(%rbx),%rsi
+	movq	16(%rbx),%rax
+	xorq	0(%rsi),%r8
+	xorq	8(%rsi),%r9
+	xorq	16(%rsi),%r10
+	xorq	24(%rsi),%r11
+	xorq	32(%rsi),%r12
+	xorq	40(%rsi),%r13
+	xorq	48(%rsi),%r14
+	xorq	56(%rsi),%r15
+	xorq	0(%rdi),%r8
+	xorq	8(%rdi),%r9
+	xorq	16(%rdi),%r10
+	xorq	24(%rdi),%r11
+	xorq	32(%rdi),%r12
+	xorq	40(%rdi),%r13
+	xorq	48(%rdi),%r14
+	xorq	56(%rdi),%r15
+	movq	%r8,0(%rdi)
+	movq	%r9,8(%rdi)
+	movq	%r10,16(%rdi)
+	movq	%r11,24(%rdi)
+	movq	%r12,32(%rdi)
+	movq	%r13,40(%rdi)
+	movq	%r14,48(%rdi)
+	movq	%r15,56(%rdi)
+	leaq	64(%rsi),%rsi
+	subq	$1,%rax
+	jz	L$alldone
+	movq	%rsi,8(%rbx)
+	movq	%rax,16(%rbx)
+	jmp	L$outerloop
+L$alldone:
+	movq	32(%rbx),%rsi
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+L$epilogue:
+	.byte	0xf3,0xc3
+
+
+.p2align	6
+
+L$table:
+.byte	24,24,96,24,192,120,48,216,24,24,96,24,192,120,48,216
+.byte	35,35,140,35,5,175,70,38,35,35,140,35,5,175,70,38
+.byte	198,198,63,198,126,249,145,184,198,198,63,198,126,249,145,184
+.byte	232,232,135,232,19,111,205,251,232,232,135,232,19,111,205,251
+.byte	135,135,38,135,76,161,19,203,135,135,38,135,76,161,19,203
+.byte	184,184,218,184,169,98,109,17,184,184,218,184,169,98,109,17
+.byte	1,1,4,1,8,5,2,9,1,1,4,1,8,5,2,9
+.byte	79,79,33,79,66,110,158,13,79,79,33,79,66,110,158,13
+.byte	54,54,216,54,173,238,108,155,54,54,216,54,173,238,108,155
+.byte	166,166,162,166,89,4,81,255,166,166,162,166,89,4,81,255
+.byte	210,210,111,210,222,189,185,12,210,210,111,210,222,189,185,12
+.byte	245,245,243,245,251,6,247,14,245,245,243,245,251,6,247,14
+.byte	121,121,249,121,239,128,242,150,121,121,249,121,239,128,242,150
+.byte	111,111,161,111,95,206,222,48,111,111,161,111,95,206,222,48
+.byte	145,145,126,145,252,239,63,109,145,145,126,145,252,239,63,109
+.byte	82,82,85,82,170,7,164,248,82,82,85,82,170,7,164,248
+.byte	96,96,157,96,39,253,192,71,96,96,157,96,39,253,192,71
+.byte	188,188,202,188,137,118,101,53,188,188,202,188,137,118,101,53
+.byte	155,155,86,155,172,205,43,55,155,155,86,155,172,205,43,55
+.byte	142,142,2,142,4,140,1,138,142,142,2,142,4,140,1,138
+.byte	163,163,182,163,113,21,91,210,163,163,182,163,113,21,91,210
+.byte	12,12,48,12,96,60,24,108,12,12,48,12,96,60,24,108
+.byte	123,123,241,123,255,138,246,132,123,123,241,123,255,138,246,132
+.byte	53,53,212,53,181,225,106,128,53,53,212,53,181,225,106,128
+.byte	29,29,116,29,232,105,58,245,29,29,116,29,232,105,58,245
+.byte	224,224,167,224,83,71,221,179,224,224,167,224,83,71,221,179
+.byte	215,215,123,215,246,172,179,33,215,215,123,215,246,172,179,33
+.byte	194,194,47,194,94,237,153,156,194,194,47,194,94,237,153,156
+.byte	46,46,184,46,109,150,92,67,46,46,184,46,109,150,92,67
+.byte	75,75,49,75,98,122,150,41,75,75,49,75,98,122,150,41
+.byte	254,254,223,254,163,33,225,93,254,254,223,254,163,33,225,93
+.byte	87,87,65,87,130,22,174,213,87,87,65,87,130,22,174,213
+.byte	21,21,84,21,168,65,42,189,21,21,84,21,168,65,42,189
+.byte	119,119,193,119,159,182,238,232,119,119,193,119,159,182,238,232
+.byte	55,55,220,55,165,235,110,146,55,55,220,55,165,235,110,146
+.byte	229,229,179,229,123,86,215,158,229,229,179,229,123,86,215,158
+.byte	159,159,70,159,140,217,35,19,159,159,70,159,140,217,35,19
+.byte	240,240,231,240,211,23,253,35,240,240,231,240,211,23,253,35
+.byte	74,74,53,74,106,127,148,32,74,74,53,74,106,127,148,32
+.byte	218,218,79,218,158,149,169,68,218,218,79,218,158,149,169,68
+.byte	88,88,125,88,250,37,176,162,88,88,125,88,250,37,176,162
+.byte	201,201,3,201,6,202,143,207,201,201,3,201,6,202,143,207
+.byte	41,41,164,41,85,141,82,124,41,41,164,41,85,141,82,124
+.byte	10,10,40,10,80,34,20,90,10,10,40,10,80,34,20,90
+.byte	177,177,254,177,225,79,127,80,177,177,254,177,225,79,127,80
+.byte	160,160,186,160,105,26,93,201,160,160,186,160,105,26,93,201
+.byte	107,107,177,107,127,218,214,20,107,107,177,107,127,218,214,20
+.byte	133,133,46,133,92,171,23,217,133,133,46,133,92,171,23,217
+.byte	189,189,206,189,129,115,103,60,189,189,206,189,129,115,103,60
+.byte	93,93,105,93,210,52,186,143,93,93,105,93,210,52,186,143
+.byte	16,16,64,16,128,80,32,144,16,16,64,16,128,80,32,144
+.byte	244,244,247,244,243,3,245,7,244,244,247,244,243,3,245,7
+.byte	203,203,11,203,22,192,139,221,203,203,11,203,22,192,139,221
+.byte	62,62,248,62,237,198,124,211,62,62,248,62,237,198,124,211
+.byte	5,5,20,5,40,17,10,45,5,5,20,5,40,17,10,45
+.byte	103,103,129,103,31,230,206,120,103,103,129,103,31,230,206,120
+.byte	228,228,183,228,115,83,213,151,228,228,183,228,115,83,213,151
+.byte	39,39,156,39,37,187,78,2,39,39,156,39,37,187,78,2
+.byte	65,65,25,65,50,88,130,115,65,65,25,65,50,88,130,115
+.byte	139,139,22,139,44,157,11,167,139,139,22,139,44,157,11,167
+.byte	167,167,166,167,81,1,83,246,167,167,166,167,81,1,83,246
+.byte	125,125,233,125,207,148,250,178,125,125,233,125,207,148,250,178
+.byte	149,149,110,149,220,251,55,73,149,149,110,149,220,251,55,73
+.byte	216,216,71,216,142,159,173,86,216,216,71,216,142,159,173,86
+.byte	251,251,203,251,139,48,235,112,251,251,203,251,139,48,235,112
+.byte	238,238,159,238,35,113,193,205,238,238,159,238,35,113,193,205
+.byte	124,124,237,124,199,145,248,187,124,124,237,124,199,145,248,187
+.byte	102,102,133,102,23,227,204,113,102,102,133,102,23,227,204,113
+.byte	221,221,83,221,166,142,167,123,221,221,83,221,166,142,167,123
+.byte	23,23,92,23,184,75,46,175,23,23,92,23,184,75,46,175
+.byte	71,71,1,71,2,70,142,69,71,71,1,71,2,70,142,69
+.byte	158,158,66,158,132,220,33,26,158,158,66,158,132,220,33,26
+.byte	202,202,15,202,30,197,137,212,202,202,15,202,30,197,137,212
+.byte	45,45,180,45,117,153,90,88,45,45,180,45,117,153,90,88
+.byte	191,191,198,191,145,121,99,46,191,191,198,191,145,121,99,46
+.byte	7,7,28,7,56,27,14,63,7,7,28,7,56,27,14,63
+.byte	173,173,142,173,1,35,71,172,173,173,142,173,1,35,71,172
+.byte	90,90,117,90,234,47,180,176,90,90,117,90,234,47,180,176
+.byte	131,131,54,131,108,181,27,239,131,131,54,131,108,181,27,239
+.byte	51,51,204,51,133,255,102,182,51,51,204,51,133,255,102,182
+.byte	99,99,145,99,63,242,198,92,99,99,145,99,63,242,198,92
+.byte	2,2,8,2,16,10,4,18,2,2,8,2,16,10,4,18
+.byte	170,170,146,170,57,56,73,147,170,170,146,170,57,56,73,147
+.byte	113,113,217,113,175,168,226,222,113,113,217,113,175,168,226,222
+.byte	200,200,7,200,14,207,141,198,200,200,7,200,14,207,141,198
+.byte	25,25,100,25,200,125,50,209,25,25,100,25,200,125,50,209
+.byte	73,73,57,73,114,112,146,59,73,73,57,73,114,112,146,59
+.byte	217,217,67,217,134,154,175,95,217,217,67,217,134,154,175,95
+.byte	242,242,239,242,195,29,249,49,242,242,239,242,195,29,249,49
+.byte	227,227,171,227,75,72,219,168,227,227,171,227,75,72,219,168
+.byte	91,91,113,91,226,42,182,185,91,91,113,91,226,42,182,185
+.byte	136,136,26,136,52,146,13,188,136,136,26,136,52,146,13,188
+.byte	154,154,82,154,164,200,41,62,154,154,82,154,164,200,41,62
+.byte	38,38,152,38,45,190,76,11,38,38,152,38,45,190,76,11
+.byte	50,50,200,50,141,250,100,191,50,50,200,50,141,250,100,191
+.byte	176,176,250,176,233,74,125,89,176,176,250,176,233,74,125,89
+.byte	233,233,131,233,27,106,207,242,233,233,131,233,27,106,207,242
+.byte	15,15,60,15,120,51,30,119,15,15,60,15,120,51,30,119
+.byte	213,213,115,213,230,166,183,51,213,213,115,213,230,166,183,51
+.byte	128,128,58,128,116,186,29,244,128,128,58,128,116,186,29,244
+.byte	190,190,194,190,153,124,97,39,190,190,194,190,153,124,97,39
+.byte	205,205,19,205,38,222,135,235,205,205,19,205,38,222,135,235
+.byte	52,52,208,52,189,228,104,137,52,52,208,52,189,228,104,137
+.byte	72,72,61,72,122,117,144,50,72,72,61,72,122,117,144,50
+.byte	255,255,219,255,171,36,227,84,255,255,219,255,171,36,227,84
+.byte	122,122,245,122,247,143,244,141,122,122,245,122,247,143,244,141
+.byte	144,144,122,144,244,234,61,100,144,144,122,144,244,234,61,100
+.byte	95,95,97,95,194,62,190,157,95,95,97,95,194,62,190,157
+.byte	32,32,128,32,29,160,64,61,32,32,128,32,29,160,64,61
+.byte	104,104,189,104,103,213,208,15,104,104,189,104,103,213,208,15
+.byte	26,26,104,26,208,114,52,202,26,26,104,26,208,114,52,202
+.byte	174,174,130,174,25,44,65,183,174,174,130,174,25,44,65,183
+.byte	180,180,234,180,201,94,117,125,180,180,234,180,201,94,117,125
+.byte	84,84,77,84,154,25,168,206,84,84,77,84,154,25,168,206
+.byte	147,147,118,147,236,229,59,127,147,147,118,147,236,229,59,127
+.byte	34,34,136,34,13,170,68,47,34,34,136,34,13,170,68,47
+.byte	100,100,141,100,7,233,200,99,100,100,141,100,7,233,200,99
+.byte	241,241,227,241,219,18,255,42,241,241,227,241,219,18,255,42
+.byte	115,115,209,115,191,162,230,204,115,115,209,115,191,162,230,204
+.byte	18,18,72,18,144,90,36,130,18,18,72,18,144,90,36,130
+.byte	64,64,29,64,58,93,128,122,64,64,29,64,58,93,128,122
+.byte	8,8,32,8,64,40,16,72,8,8,32,8,64,40,16,72
+.byte	195,195,43,195,86,232,155,149,195,195,43,195,86,232,155,149
+.byte	236,236,151,236,51,123,197,223,236,236,151,236,51,123,197,223
+.byte	219,219,75,219,150,144,171,77,219,219,75,219,150,144,171,77
+.byte	161,161,190,161,97,31,95,192,161,161,190,161,97,31,95,192
+.byte	141,141,14,141,28,131,7,145,141,141,14,141,28,131,7,145
+.byte	61,61,244,61,245,201,122,200,61,61,244,61,245,201,122,200
+.byte	151,151,102,151,204,241,51,91,151,151,102,151,204,241,51,91
+.byte	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+.byte	207,207,27,207,54,212,131,249,207,207,27,207,54,212,131,249
+.byte	43,43,172,43,69,135,86,110,43,43,172,43,69,135,86,110
+.byte	118,118,197,118,151,179,236,225,118,118,197,118,151,179,236,225
+.byte	130,130,50,130,100,176,25,230,130,130,50,130,100,176,25,230
+.byte	214,214,127,214,254,169,177,40,214,214,127,214,254,169,177,40
+.byte	27,27,108,27,216,119,54,195,27,27,108,27,216,119,54,195
+.byte	181,181,238,181,193,91,119,116,181,181,238,181,193,91,119,116
+.byte	175,175,134,175,17,41,67,190,175,175,134,175,17,41,67,190
+.byte	106,106,181,106,119,223,212,29,106,106,181,106,119,223,212,29
+.byte	80,80,93,80,186,13,160,234,80,80,93,80,186,13,160,234
+.byte	69,69,9,69,18,76,138,87,69,69,9,69,18,76,138,87
+.byte	243,243,235,243,203,24,251,56,243,243,235,243,203,24,251,56
+.byte	48,48,192,48,157,240,96,173,48,48,192,48,157,240,96,173
+.byte	239,239,155,239,43,116,195,196,239,239,155,239,43,116,195,196
+.byte	63,63,252,63,229,195,126,218,63,63,252,63,229,195,126,218
+.byte	85,85,73,85,146,28,170,199,85,85,73,85,146,28,170,199
+.byte	162,162,178,162,121,16,89,219,162,162,178,162,121,16,89,219
+.byte	234,234,143,234,3,101,201,233,234,234,143,234,3,101,201,233
+.byte	101,101,137,101,15,236,202,106,101,101,137,101,15,236,202,106
+.byte	186,186,210,186,185,104,105,3,186,186,210,186,185,104,105,3
+.byte	47,47,188,47,101,147,94,74,47,47,188,47,101,147,94,74
+.byte	192,192,39,192,78,231,157,142,192,192,39,192,78,231,157,142
+.byte	222,222,95,222,190,129,161,96,222,222,95,222,190,129,161,96
+.byte	28,28,112,28,224,108,56,252,28,28,112,28,224,108,56,252
+.byte	253,253,211,253,187,46,231,70,253,253,211,253,187,46,231,70
+.byte	77,77,41,77,82,100,154,31,77,77,41,77,82,100,154,31
+.byte	146,146,114,146,228,224,57,118,146,146,114,146,228,224,57,118
+.byte	117,117,201,117,143,188,234,250,117,117,201,117,143,188,234,250
+.byte	6,6,24,6,48,30,12,54,6,6,24,6,48,30,12,54
+.byte	138,138,18,138,36,152,9,174,138,138,18,138,36,152,9,174
+.byte	178,178,242,178,249,64,121,75,178,178,242,178,249,64,121,75
+.byte	230,230,191,230,99,89,209,133,230,230,191,230,99,89,209,133
+.byte	14,14,56,14,112,54,28,126,14,14,56,14,112,54,28,126
+.byte	31,31,124,31,248,99,62,231,31,31,124,31,248,99,62,231
+.byte	98,98,149,98,55,247,196,85,98,98,149,98,55,247,196,85
+.byte	212,212,119,212,238,163,181,58,212,212,119,212,238,163,181,58
+.byte	168,168,154,168,41,50,77,129,168,168,154,168,41,50,77,129
+.byte	150,150,98,150,196,244,49,82,150,150,98,150,196,244,49,82
+.byte	249,249,195,249,155,58,239,98,249,249,195,249,155,58,239,98
+.byte	197,197,51,197,102,246,151,163,197,197,51,197,102,246,151,163
+.byte	37,37,148,37,53,177,74,16,37,37,148,37,53,177,74,16
+.byte	89,89,121,89,242,32,178,171,89,89,121,89,242,32,178,171
+.byte	132,132,42,132,84,174,21,208,132,132,42,132,84,174,21,208
+.byte	114,114,213,114,183,167,228,197,114,114,213,114,183,167,228,197
+.byte	57,57,228,57,213,221,114,236,57,57,228,57,213,221,114,236
+.byte	76,76,45,76,90,97,152,22,76,76,45,76,90,97,152,22
+.byte	94,94,101,94,202,59,188,148,94,94,101,94,202,59,188,148
+.byte	120,120,253,120,231,133,240,159,120,120,253,120,231,133,240,159
+.byte	56,56,224,56,221,216,112,229,56,56,224,56,221,216,112,229
+.byte	140,140,10,140,20,134,5,152,140,140,10,140,20,134,5,152
+.byte	209,209,99,209,198,178,191,23,209,209,99,209,198,178,191,23
+.byte	165,165,174,165,65,11,87,228,165,165,174,165,65,11,87,228
+.byte	226,226,175,226,67,77,217,161,226,226,175,226,67,77,217,161
+.byte	97,97,153,97,47,248,194,78,97,97,153,97,47,248,194,78
+.byte	179,179,246,179,241,69,123,66,179,179,246,179,241,69,123,66
+.byte	33,33,132,33,21,165,66,52,33,33,132,33,21,165,66,52
+.byte	156,156,74,156,148,214,37,8,156,156,74,156,148,214,37,8
+.byte	30,30,120,30,240,102,60,238,30,30,120,30,240,102,60,238
+.byte	67,67,17,67,34,82,134,97,67,67,17,67,34,82,134,97
+.byte	199,199,59,199,118,252,147,177,199,199,59,199,118,252,147,177
+.byte	252,252,215,252,179,43,229,79,252,252,215,252,179,43,229,79
+.byte	4,4,16,4,32,20,8,36,4,4,16,4,32,20,8,36
+.byte	81,81,89,81,178,8,162,227,81,81,89,81,178,8,162,227
+.byte	153,153,94,153,188,199,47,37,153,153,94,153,188,199,47,37
+.byte	109,109,169,109,79,196,218,34,109,109,169,109,79,196,218,34
+.byte	13,13,52,13,104,57,26,101,13,13,52,13,104,57,26,101
+.byte	250,250,207,250,131,53,233,121,250,250,207,250,131,53,233,121
+.byte	223,223,91,223,182,132,163,105,223,223,91,223,182,132,163,105
+.byte	126,126,229,126,215,155,252,169,126,126,229,126,215,155,252,169
+.byte	36,36,144,36,61,180,72,25,36,36,144,36,61,180,72,25
+.byte	59,59,236,59,197,215,118,254,59,59,236,59,197,215,118,254
+.byte	171,171,150,171,49,61,75,154,171,171,150,171,49,61,75,154
+.byte	206,206,31,206,62,209,129,240,206,206,31,206,62,209,129,240
+.byte	17,17,68,17,136,85,34,153,17,17,68,17,136,85,34,153
+.byte	143,143,6,143,12,137,3,131,143,143,6,143,12,137,3,131
+.byte	78,78,37,78,74,107,156,4,78,78,37,78,74,107,156,4
+.byte	183,183,230,183,209,81,115,102,183,183,230,183,209,81,115,102
+.byte	235,235,139,235,11,96,203,224,235,235,139,235,11,96,203,224
+.byte	60,60,240,60,253,204,120,193,60,60,240,60,253,204,120,193
+.byte	129,129,62,129,124,191,31,253,129,129,62,129,124,191,31,253
+.byte	148,148,106,148,212,254,53,64,148,148,106,148,212,254,53,64
+.byte	247,247,251,247,235,12,243,28,247,247,251,247,235,12,243,28
+.byte	185,185,222,185,161,103,111,24,185,185,222,185,161,103,111,24
+.byte	19,19,76,19,152,95,38,139,19,19,76,19,152,95,38,139
+.byte	44,44,176,44,125,156,88,81,44,44,176,44,125,156,88,81
+.byte	211,211,107,211,214,184,187,5,211,211,107,211,214,184,187,5
+.byte	231,231,187,231,107,92,211,140,231,231,187,231,107,92,211,140
+.byte	110,110,165,110,87,203,220,57,110,110,165,110,87,203,220,57
+.byte	196,196,55,196,110,243,149,170,196,196,55,196,110,243,149,170
+.byte	3,3,12,3,24,15,6,27,3,3,12,3,24,15,6,27
+.byte	86,86,69,86,138,19,172,220,86,86,69,86,138,19,172,220
+.byte	68,68,13,68,26,73,136,94,68,68,13,68,26,73,136,94
+.byte	127,127,225,127,223,158,254,160,127,127,225,127,223,158,254,160
+.byte	169,169,158,169,33,55,79,136,169,169,158,169,33,55,79,136
+.byte	42,42,168,42,77,130,84,103,42,42,168,42,77,130,84,103
+.byte	187,187,214,187,177,109,107,10,187,187,214,187,177,109,107,10
+.byte	193,193,35,193,70,226,159,135,193,193,35,193,70,226,159,135
+.byte	83,83,81,83,162,2,166,241,83,83,81,83,162,2,166,241
+.byte	220,220,87,220,174,139,165,114,220,220,87,220,174,139,165,114
+.byte	11,11,44,11,88,39,22,83,11,11,44,11,88,39,22,83
+.byte	157,157,78,157,156,211,39,1,157,157,78,157,156,211,39,1
+.byte	108,108,173,108,71,193,216,43,108,108,173,108,71,193,216,43
+.byte	49,49,196,49,149,245,98,164,49,49,196,49,149,245,98,164
+.byte	116,116,205,116,135,185,232,243,116,116,205,116,135,185,232,243
+.byte	246,246,255,246,227,9,241,21,246,246,255,246,227,9,241,21
+.byte	70,70,5,70,10,67,140,76,70,70,5,70,10,67,140,76
+.byte	172,172,138,172,9,38,69,165,172,172,138,172,9,38,69,165
+.byte	137,137,30,137,60,151,15,181,137,137,30,137,60,151,15,181
+.byte	20,20,80,20,160,68,40,180,20,20,80,20,160,68,40,180
+.byte	225,225,163,225,91,66,223,186,225,225,163,225,91,66,223,186
+.byte	22,22,88,22,176,78,44,166,22,22,88,22,176,78,44,166
+.byte	58,58,232,58,205,210,116,247,58,58,232,58,205,210,116,247
+.byte	105,105,185,105,111,208,210,6,105,105,185,105,111,208,210,6
+.byte	9,9,36,9,72,45,18,65,9,9,36,9,72,45,18,65
+.byte	112,112,221,112,167,173,224,215,112,112,221,112,167,173,224,215
+.byte	182,182,226,182,217,84,113,111,182,182,226,182,217,84,113,111
+.byte	208,208,103,208,206,183,189,30,208,208,103,208,206,183,189,30
+.byte	237,237,147,237,59,126,199,214,237,237,147,237,59,126,199,214
+.byte	204,204,23,204,46,219,133,226,204,204,23,204,46,219,133,226
+.byte	66,66,21,66,42,87,132,104,66,66,21,66,42,87,132,104
+.byte	152,152,90,152,180,194,45,44,152,152,90,152,180,194,45,44
+.byte	164,164,170,164,73,14,85,237,164,164,170,164,73,14,85,237
+.byte	40,40,160,40,93,136,80,117,40,40,160,40,93,136,80,117
+.byte	92,92,109,92,218,49,184,134,92,92,109,92,218,49,184,134
+.byte	248,248,199,248,147,63,237,107,248,248,199,248,147,63,237,107
+.byte	134,134,34,134,68,164,17,194,134,134,34,134,68,164,17,194
+.byte	24,35,198,232,135,184,1,79
+.byte	54,166,210,245,121,111,145,82
+.byte	96,188,155,142,163,12,123,53
+.byte	29,224,215,194,46,75,254,87
+.byte	21,119,55,229,159,240,74,218
+.byte	88,201,41,10,177,160,107,133
+.byte	189,93,16,244,203,62,5,103
+.byte	228,39,65,139,167,125,149,216
+.byte	251,238,124,102,221,23,71,158
+.byte	202,45,191,7,173,90,131,51
diff --git a/crypto/libressl/crypto/whrlpool/wp_block.c b/crypto/libressl/crypto/whrlpool/wp_block.c
new file mode 100644
index 0000000000..639b824579
--- /dev/null
+++ b/crypto/libressl/crypto/whrlpool/wp_block.c
@@ -0,0 +1,634 @@
+/* $OpenBSD: wp_block.c,v 1.9 2014/07/09 16:06:13 miod Exp $ */
+/**
+ * The Whirlpool hashing function.
+ *
+ * 

+ * References + * + *

+ * The Whirlpool algorithm was developed by + * Paulo S. L. M. Barreto and + * Vincent Rijmen. + * + * See + * P.S.L.M. Barreto, V. Rijmen, + * ``The Whirlpool hashing function,'' + * NESSIE submission, 2000 (tweaked version, 2001), + * + * + * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and + * Vincent Rijmen. Lookup "reference implementations" on + * + * + * ============================================================================= + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "wp_locl.h" +#include +#include + +typedef unsigned char u8; +#if defined(_LP64) +typedef unsigned long u64; +#else +typedef unsigned long long u64; +#endif + +#define ROUNDS 10 + +#undef SMALL_REGISTER_BANK +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) +# define SMALL_REGISTER_BANK +# if defined(WHIRLPOOL_ASM) +# ifndef OPENSSL_SMALL_FOOTPRINT +# define OPENSSL_SMALL_FOOTPRINT /* it appears that for elder non-MMX + CPUs this is actually faster! */ +# endif +# define GO_FOR_MMX(ctx,inp,num) do { \ + extern unsigned int OPENSSL_ia32cap_P[]; \ + void whirlpool_block_mmx(void *,const void *,size_t); \ + if (!(OPENSSL_ia32cap_P[0] & (1<<23))) break; \ + whirlpool_block_mmx(ctx->H.c,inp,num); return; \ + } while (0) +# endif +#elif defined(__arm__) +# define SMALL_REGISTER_BANK +#elif defined(__vax__) +# define SMALL_REGISTER_BANK +#endif + +#undef ROTATE +#if defined(__GNUC__) && __GNUC__>=2 +# if defined(__x86_64) || defined(__x86_64__) +# define ROTATE(a,n) ({ u64 ret; asm ("rolq %1,%0" \ + : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; }) +# elif defined(__ia64) || defined(__ia64__) +# if BYTE_ORDER == LITTLE_ENDIAN +# define ROTATE(a,n) ({ u64 ret; asm ("shrp %0=%1,%1,%2" \ + : "=r"(ret) : "r"(a),"M"(64-(n))); ret; }) +# else +# define ROTATE(a,n) ({ u64 ret; asm ("shrp %0=%1,%1,%2" \ + : "=r"(ret) : "r"(a),"M"(n)); ret; }) +# endif +# endif +#endif + +#if defined(OPENSSL_SMALL_FOOTPRINT) +# if !defined(ROTATE) +# if BYTE_ORDER == LITTLE_ENDIAN /* little-endians have to rotate left */ +# define ROTATE(i,n) ((i)<<(n) ^ (i)>>(64-n)) +# else /* big-endians have to rotate right */ +# define ROTATE(i,n) ((i)>>(n) ^ (i)<<(64-n)) +# endif +# endif +# if defined(ROTATE) && !defined(__STRICT_ALIGNMENT) +# define __STRICT_ALIGNMENT /* ensure smallest table size */ +# endif +#endif + +/* + * Table size depends on __STRICT_ALIGNMENT and whether or not endian- + * specific ROTATE macro is defined. If __STRICT_ALIGNMENT is not + * defined, which is normally the case on x86[_64] CPUs, the table is + * 4KB large unconditionally. Otherwise if ROTATE is defined, the + * table is 2KB large, and otherwise - 16KB. 2KB table requires a + * whole bunch of additional rotations, but I'm willing to "trade," + * because 16KB table certainly trashes L1 cache. I wish all CPUs + * could handle unaligned load as 4KB table doesn't trash the cache, + * nor does it require additional rotations. + */ +/* + * Note that every Cn macro expands as two loads: one byte load and + * one quadword load. One can argue that that many single-byte loads + * is too excessive, as one could load a quadword and "milk" it for + * eight 8-bit values instead. Well, yes, but in order to do so *and* + * avoid excessive loads you have to accommodate a handful of 64-bit + * values in the register bank and issue a bunch of shifts and mask. + * It's a tradeoff: loads vs. shift and mask in big register bank[!]. + * On most CPUs eight single-byte loads are faster and I let other + * ones to depend on smart compiler to fold byte loads if beneficial. + * Hand-coded assembler would be another alternative:-) + */ +#ifdef __STRICT_ALIGNMENT +# if defined(ROTATE) +# define N 1 +# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7 +# define C0(K,i) (Cx.q[K.c[(i)*8+0]]) +# define C1(K,i) ROTATE(Cx.q[K.c[(i)*8+1]],8) +# define C2(K,i) ROTATE(Cx.q[K.c[(i)*8+2]],16) +# define C3(K,i) ROTATE(Cx.q[K.c[(i)*8+3]],24) +# define C4(K,i) ROTATE(Cx.q[K.c[(i)*8+4]],32) +# define C5(K,i) ROTATE(Cx.q[K.c[(i)*8+5]],40) +# define C6(K,i) ROTATE(Cx.q[K.c[(i)*8+6]],48) +# define C7(K,i) ROTATE(Cx.q[K.c[(i)*8+7]],56) +# else +# define N 8 +# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7, \ + c7,c0,c1,c2,c3,c4,c5,c6, \ + c6,c7,c0,c1,c2,c3,c4,c5, \ + c5,c6,c7,c0,c1,c2,c3,c4, \ + c4,c5,c6,c7,c0,c1,c2,c3, \ + c3,c4,c5,c6,c7,c0,c1,c2, \ + c2,c3,c4,c5,c6,c7,c0,c1, \ + c1,c2,c3,c4,c5,c6,c7,c0 +# define C0(K,i) (Cx.q[0+8*K.c[(i)*8+0]]) +# define C1(K,i) (Cx.q[1+8*K.c[(i)*8+1]]) +# define C2(K,i) (Cx.q[2+8*K.c[(i)*8+2]]) +# define C3(K,i) (Cx.q[3+8*K.c[(i)*8+3]]) +# define C4(K,i) (Cx.q[4+8*K.c[(i)*8+4]]) +# define C5(K,i) (Cx.q[5+8*K.c[(i)*8+5]]) +# define C6(K,i) (Cx.q[6+8*K.c[(i)*8+6]]) +# define C7(K,i) (Cx.q[7+8*K.c[(i)*8+7]]) +# endif +#else +# define N 2 +# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7, \ + c0,c1,c2,c3,c4,c5,c6,c7 +# define C0(K,i) (((u64*)(Cx.c+0))[2*K.c[(i)*8+0]]) +# define C1(K,i) (((u64*)(Cx.c+7))[2*K.c[(i)*8+1]]) +# define C2(K,i) (((u64*)(Cx.c+6))[2*K.c[(i)*8+2]]) +# define C3(K,i) (((u64*)(Cx.c+5))[2*K.c[(i)*8+3]]) +# define C4(K,i) (((u64*)(Cx.c+4))[2*K.c[(i)*8+4]]) +# define C5(K,i) (((u64*)(Cx.c+3))[2*K.c[(i)*8+5]]) +# define C6(K,i) (((u64*)(Cx.c+2))[2*K.c[(i)*8+6]]) +# define C7(K,i) (((u64*)(Cx.c+1))[2*K.c[(i)*8+7]]) +#endif + +static const +union { + u8 c[(256*N+ROUNDS)*sizeof(u64)]; + u64 q[(256*N+ROUNDS)]; + } Cx = { { + /* Note endian-neutral representation:-) */ + LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8), + LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26), + LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8), + LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb), + LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb), + LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11), + LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09), + LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d), + LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b), + LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff), + LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c), + LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e), + LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96), + LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30), + LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d), + LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8), + LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47), + LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35), + LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37), + LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a), + LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2), + LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c), + LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84), + LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80), + LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5), + LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3), + LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21), + LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c), + LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43), + LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29), + LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d), + LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5), + LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd), + LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8), + LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92), + LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e), + LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13), + LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23), + LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20), + LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44), + LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2), + LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf), + LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c), + LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a), + LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50), + LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9), + LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14), + LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9), + LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c), + LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f), + LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90), + LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07), + LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd), + LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3), + LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d), + LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78), + LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97), + LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02), + LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73), + LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7), + LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6), + LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2), + LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49), + LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56), + LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70), + LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd), + LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb), + LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71), + LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b), + LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf), + LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45), + LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a), + LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4), + LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58), + LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e), + LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f), + LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac), + LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0), + LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef), + LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6), + LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c), + LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12), + LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93), + LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde), + LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6), + LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1), + LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b), + LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f), + LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31), + LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8), + LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9), + LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc), + LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e), + LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b), + LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf), + LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59), + LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2), + LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77), + LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33), + LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4), + LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27), + LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb), + LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89), + LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32), + LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54), + LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d), + LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64), + LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d), + LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d), + LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f), + LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca), + LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7), + LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d), + LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce), + LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f), + LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f), + LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63), + LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a), + LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc), + LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82), + LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a), + LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48), + LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95), + LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf), + LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d), + LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0), + LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91), + LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8), + LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b), + LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00), + LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9), + LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e), + LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1), + LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6), + LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28), + LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3), + LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74), + LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe), + LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d), + LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea), + LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57), + LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38), + LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad), + LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4), + LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda), + LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7), + LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb), + LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9), + LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a), + LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03), + LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a), + LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e), + LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60), + LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc), + LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46), + LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f), + LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76), + LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa), + LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36), + LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae), + LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b), + LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85), + LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e), + LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7), + LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55), + LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a), + LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81), + LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52), + LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62), + LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3), + LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10), + LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab), + LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0), + LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5), + LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec), + LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16), + LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94), + LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f), + LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5), + LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98), + LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17), + LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4), + LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1), + LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e), + LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42), + LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34), + LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08), + LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee), + LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61), + LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1), + LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f), + LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24), + LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3), + LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25), + LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22), + LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65), + LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79), + LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69), + LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9), + LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19), + LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe), + LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a), + LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0), + LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99), + LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83), + LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04), + LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66), + LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0), + LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1), + LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd), + LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40), + LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c), + LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18), + LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b), + LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51), + LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05), + LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c), + LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39), + LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa), + LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b), + LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc), + LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e), + LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0), + LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88), + LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67), + LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a), + LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87), + LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1), + LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72), + LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53), + LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01), + LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b), + LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4), + LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3), + LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15), + LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c), + LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5), + LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5), + LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4), + LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba), + LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6), + LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7), + LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06), + LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41), + LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7), + LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f), + LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e), + LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6), + LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2), + LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68), + LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c), + LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed), + LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75), + LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86), + LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b), + LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2), +#define RC (&(Cx.q[256*N])) + 0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f, /* rc[ROUNDS] */ + 0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52, + 0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35, + 0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57, + 0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda, + 0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85, + 0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67, + 0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8, + 0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e, + 0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33 + } +}; + +void whirlpool_block(WHIRLPOOL_CTX *ctx,const void *inp,size_t n) + { + int r; + const u8 *p=inp; + union { u64 q[8]; u8 c[64]; } S,K,*H=(void *)ctx->H.q; + +#ifdef GO_FOR_MMX + GO_FOR_MMX(ctx,inp,n); +#endif + do { +#ifdef OPENSSL_SMALL_FOOTPRINT + u64 L[8]; + int i; + + for (i=0;i<64;i++) S.c[i] = (K.c[i] = H->c[i]) ^ p[i]; + for (r=0;rc[i] ^= S.c[i] ^ p[i]; +#else + u64 L0,L1,L2,L3,L4,L5,L6,L7; + +#ifdef __STRICT_ALIGNMENT + if ((size_t)p & 7) + { + memcpy (S.c,p,64); + S.q[0] ^= (K.q[0] = H->q[0]); + S.q[1] ^= (K.q[1] = H->q[1]); + S.q[2] ^= (K.q[2] = H->q[2]); + S.q[3] ^= (K.q[3] = H->q[3]); + S.q[4] ^= (K.q[4] = H->q[4]); + S.q[5] ^= (K.q[5] = H->q[5]); + S.q[6] ^= (K.q[6] = H->q[6]); + S.q[7] ^= (K.q[7] = H->q[7]); + } + else +#endif + { + const u64 *pa = (const u64*)p; + S.q[0] = (K.q[0] = H->q[0]) ^ pa[0]; + S.q[1] = (K.q[1] = H->q[1]) ^ pa[1]; + S.q[2] = (K.q[2] = H->q[2]) ^ pa[2]; + S.q[3] = (K.q[3] = H->q[3]) ^ pa[3]; + S.q[4] = (K.q[4] = H->q[4]) ^ pa[4]; + S.q[5] = (K.q[5] = H->q[5]) ^ pa[5]; + S.q[6] = (K.q[6] = H->q[6]) ^ pa[6]; + S.q[7] = (K.q[7] = H->q[7]) ^ pa[7]; + } + + for(r=0;rc[i] ^= S.c[i] ^ p[i]; + } + else +#endif + { + const u64 *pa=(const u64 *)p; + H->q[0] ^= S.q[0] ^ pa[0]; + H->q[1] ^= S.q[1] ^ pa[1]; + H->q[2] ^= S.q[2] ^ pa[2]; + H->q[3] ^= S.q[3] ^ pa[3]; + H->q[4] ^= S.q[4] ^ pa[4]; + H->q[5] ^= S.q[5] ^ pa[5]; + H->q[6] ^= S.q[6] ^ pa[6]; + H->q[7] ^= S.q[7] ^ pa[7]; + } +#endif + p += 64; + } while(--n); + } diff --git a/crypto/libressl/crypto/whrlpool/wp_dgst.c b/crypto/libressl/crypto/whrlpool/wp_dgst.c new file mode 100644 index 0000000000..66d671d899 --- /dev/null +++ b/crypto/libressl/crypto/whrlpool/wp_dgst.c @@ -0,0 +1,266 @@ +/* $OpenBSD: wp_dgst.c,v 1.3 2014/06/12 15:49:31 deraadt Exp $ */ +/** + * The Whirlpool hashing function. + * + *

+ * References + * + *

+ * The Whirlpool algorithm was developed by + * Paulo S. L. M. Barreto and + * Vincent Rijmen. + * + * See + * P.S.L.M. Barreto, V. Rijmen, + * ``The Whirlpool hashing function,'' + * NESSIE submission, 2000 (tweaked version, 2001), + * + * + * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and + * Vincent Rijmen. Lookup "reference implementations" on + * + * + * ============================================================================= + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * OpenSSL-specific implementation notes. + * + * WHIRLPOOL_Update as well as one-stroke WHIRLPOOL both expect + * number of *bytes* as input length argument. Bit-oriented routine + * as specified by authors is called WHIRLPOOL_BitUpdate[!] and + * does not have one-stroke counterpart. + * + * WHIRLPOOL_BitUpdate implements byte-oriented loop, essentially + * to serve WHIRLPOOL_Update. This is done for performance. + * + * Unlike authors' reference implementation, block processing + * routine whirlpool_block is designed to operate on multi-block + * input. This is done for performance. + */ + +#include "wp_locl.h" +#include +#include + +int WHIRLPOOL_Init(WHIRLPOOL_CTX *c) + { + memset (c,0,sizeof(*c)); + return(1); + } + +int WHIRLPOOL_Update (WHIRLPOOL_CTX *c,const void *_inp,size_t bytes) + { + /* Well, largest suitable chunk size actually is + * (1<<(sizeof(size_t)*8-3))-64, but below number + * is large enough for not to care about excessive + * calls to WHIRLPOOL_BitUpdate... */ + size_t chunk = ((size_t)1)<<(sizeof(size_t)*8-4); + const unsigned char *inp = _inp; + + while (bytes>=chunk) + { + WHIRLPOOL_BitUpdate(c,inp,chunk*8); + bytes -= chunk; + inp += chunk; + } + if (bytes) + WHIRLPOOL_BitUpdate(c,inp,bytes*8); + + return(1); + } + +void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c,const void *_inp,size_t bits) + { + size_t n; + unsigned int bitoff = c->bitoff, + bitrem = bitoff%8, + inpgap = (8-(unsigned int)bits%8)&7; + const unsigned char *inp=_inp; + + /* This 256-bit increment procedure relies on the size_t + * being natural size of CPU register, so that we don't + * have to mask the value in order to detect overflows. */ + c->bitlen[0] += bits; + if (c->bitlen[0] < bits) /* overflow */ + { + n = 1; + do { c->bitlen[n]++; + } while(c->bitlen[n]==0 + && ++n<(WHIRLPOOL_COUNTER/sizeof(size_t))); + } + +#ifndef OPENSSL_SMALL_FOOTPRINT + reconsider: + if (inpgap==0 && bitrem==0) /* byte-oriented loop */ + { + while (bits) + { + if (bitoff==0 && (n=bits/WHIRLPOOL_BBLOCK)) + { + whirlpool_block(c,inp,n); + inp += n*WHIRLPOOL_BBLOCK/8; + bits %= WHIRLPOOL_BBLOCK; + } + else + { + unsigned int byteoff = bitoff/8; + + bitrem = WHIRLPOOL_BBLOCK - bitoff;/* re-use bitrem */ + if (bits >= bitrem) + { + bits -= bitrem; + bitrem /= 8; + memcpy(c->data+byteoff,inp,bitrem); + inp += bitrem; + whirlpool_block(c,c->data,1); + bitoff = 0; + } + else + { + memcpy(c->data+byteoff,inp,bits/8); + bitoff += (unsigned int)bits; + bits = 0; + } + c->bitoff = bitoff; + } + } + } + else /* bit-oriented loop */ +#endif + { + /* + inp + | + +-------+-------+------- + ||||||||||||||||||||| + +-------+-------+------- + +-------+-------+-------+-------+------- + |||||||||||||| c->data + +-------+-------+-------+-------+------- + | + c->bitoff/8 + */ + while (bits) + { + unsigned int byteoff = bitoff/8; + unsigned char b; + +#ifndef OPENSSL_SMALL_FOOTPRINT + if (bitrem==inpgap) + { + c->data[byteoff++] |= inp[0] & (0xff>>inpgap); + inpgap = 8-inpgap; + bitoff += inpgap; bitrem = 0; /* bitoff%8 */ + bits -= inpgap; inpgap = 0; /* bits%8 */ + inp++; + if (bitoff==WHIRLPOOL_BBLOCK) + { + whirlpool_block(c,c->data,1); + bitoff = 0; + } + c->bitoff = bitoff; + goto reconsider; + } + else +#endif + if (bits>=8) + { + b = ((inp[0]<>(8-inpgap))); + b &= 0xff; + if (bitrem) c->data[byteoff++] |= b>>bitrem; + else c->data[byteoff++] = b; + bitoff += 8; + bits -= 8; + inp++; + if (bitoff>=WHIRLPOOL_BBLOCK) + { + whirlpool_block(c,c->data,1); + byteoff = 0; + bitoff %= WHIRLPOOL_BBLOCK; + } + if (bitrem) c->data[byteoff] = b<<(8-bitrem); + } + else /* remaining less than 8 bits */ + { + b = (inp[0]<data[byteoff++] |= b>>bitrem; + else c->data[byteoff++] = b; + bitoff += (unsigned int)bits; + if (bitoff==WHIRLPOOL_BBLOCK) + { + whirlpool_block(c,c->data,1); + byteoff = 0; + bitoff %= WHIRLPOOL_BBLOCK; + } + if (bitrem) c->data[byteoff] = b<<(8-bitrem); + bits = 0; + } + c->bitoff = bitoff; + } + } + } + +int WHIRLPOOL_Final (unsigned char *md,WHIRLPOOL_CTX *c) + { + unsigned int bitoff = c->bitoff, + byteoff = bitoff/8; + size_t i,j,v; + unsigned char *p; + + bitoff %= 8; + if (bitoff) c->data[byteoff] |= 0x80>>bitoff; + else c->data[byteoff] = 0x80; + byteoff++; + + /* pad with zeros */ + if (byteoff > (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER)) + { + if (byteoffdata[byteoff],0,WHIRLPOOL_BBLOCK/8-byteoff); + whirlpool_block(c,c->data,1); + byteoff = 0; + } + if (byteoff < (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER)) + memset(&c->data[byteoff],0, + (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER)-byteoff); + /* smash 256-bit c->bitlen in big-endian order */ + p = &c->data[WHIRLPOOL_BBLOCK/8-1]; /* last byte in c->data */ + for(i=0;ibitlen[i],j=0;j>=8) + *p-- = (unsigned char)(v&0xff); + + whirlpool_block(c,c->data,1); + + if (md) { + memcpy(md,c->H.c,WHIRLPOOL_DIGEST_LENGTH); + memset(c,0,sizeof(*c)); + return(1); + } + return(0); + } + +unsigned char *WHIRLPOOL(const void *inp, size_t bytes,unsigned char *md) + { + WHIRLPOOL_CTX ctx; + static unsigned char m[WHIRLPOOL_DIGEST_LENGTH]; + + if (md == NULL) md=m; + WHIRLPOOL_Init(&ctx); + WHIRLPOOL_Update(&ctx,inp,bytes); + WHIRLPOOL_Final(md,&ctx); + return(md); + } diff --git a/crypto/libressl/crypto/whrlpool/wp_locl.h b/crypto/libressl/crypto/whrlpool/wp_locl.h new file mode 100644 index 0000000000..d1b6c985cd --- /dev/null +++ b/crypto/libressl/crypto/whrlpool/wp_locl.h @@ -0,0 +1,5 @@ +/* $OpenBSD$ */ + +#include + +void whirlpool_block(WHIRLPOOL_CTX *,const void *,size_t); diff --git a/crypto/libressl/crypto/x509/by_dir.c b/crypto/libressl/crypto/x509/by_dir.c new file mode 100644 index 0000000000..0318a90858 --- /dev/null +++ b/crypto/libressl/crypto/x509/by_dir.c @@ -0,0 +1,422 @@ +/* $OpenBSD: by_dir.c,v 1.36 2015/02/12 03:54:07 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +# include + +typedef struct lookup_dir_hashes_st { + unsigned long hash; + int suffix; +} BY_DIR_HASH; + +typedef struct lookup_dir_entry_st { + char *dir; + int dir_type; + STACK_OF(BY_DIR_HASH) *hashes; +} BY_DIR_ENTRY; + +typedef struct lookup_dir_st { + BUF_MEM *buffer; + STACK_OF(BY_DIR_ENTRY) *dirs; +} BY_DIR; + +DECLARE_STACK_OF(BY_DIR_HASH) +DECLARE_STACK_OF(BY_DIR_ENTRY) + +static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, + char **ret); +static int new_dir(X509_LOOKUP *lu); +static void free_dir(X509_LOOKUP *lu); +static int add_cert_dir(BY_DIR *ctx, const char *dir, int type); +static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, + X509_OBJECT *ret); + +static X509_LOOKUP_METHOD x509_dir_lookup = { + .name = "Load certs from files in a directory", + .new_item = new_dir, + .free = free_dir, + .init = NULL, + .shutdown = NULL, + .ctrl = dir_ctrl, + .get_by_subject = get_cert_by_subject, + .get_by_issuer_serial = NULL, + .get_by_fingerprint = NULL, + .get_by_alias = NULL, +}; + +X509_LOOKUP_METHOD * +X509_LOOKUP_hash_dir(void) +{ + return (&x509_dir_lookup); +} + +static int +dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, + char **retp) +{ + int ret = 0; + BY_DIR *ld; + + ld = (BY_DIR *)ctx->method_data; + + switch (cmd) { + case X509_L_ADD_DIR: + if (argl == X509_FILETYPE_DEFAULT) { + ret = add_cert_dir(ld, X509_get_default_cert_dir(), + X509_FILETYPE_PEM); + if (!ret) { + X509err(X509_F_DIR_CTRL, X509_R_LOADING_CERT_DIR); + } + } else + ret = add_cert_dir(ld, argp, (int)argl); + break; + } + return (ret); +} + +static int +new_dir(X509_LOOKUP *lu) +{ + BY_DIR *a; + + if ((a = malloc(sizeof(BY_DIR))) == NULL) + return (0); + if ((a->buffer = BUF_MEM_new()) == NULL) { + free(a); + return (0); + } + a->dirs = NULL; + lu->method_data = (char *)a; + return (1); +} + +static void +by_dir_hash_free(BY_DIR_HASH *hash) +{ + free(hash); +} + +static int +by_dir_hash_cmp(const BY_DIR_HASH * const *a, + const BY_DIR_HASH * const *b) +{ + if ((*a)->hash > (*b)->hash) + return 1; + if ((*a)->hash < (*b)->hash) + return -1; + return 0; +} + +static void +by_dir_entry_free(BY_DIR_ENTRY *ent) +{ + free(ent->dir); + if (ent->hashes) + sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free); + free(ent); +} + +static void +free_dir(X509_LOOKUP *lu) +{ + BY_DIR *a; + + a = (BY_DIR *)lu->method_data; + if (a->dirs != NULL) + sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free); + if (a->buffer != NULL) + BUF_MEM_free(a->buffer); + free(a); +} + +static int +add_cert_dir(BY_DIR *ctx, const char *dir, int type) +{ + int j; + const char *s, *ss, *p; + ptrdiff_t len; + + if (dir == NULL || !*dir) { + X509err(X509_F_ADD_CERT_DIR, X509_R_INVALID_DIRECTORY); + return 0; + } + + s = dir; + p = s; + do { + if ((*p == ':') || (*p == '\0')) { + BY_DIR_ENTRY *ent; + ss = s; + s = p + 1; + len = p - ss; + if (len == 0) + continue; + for (j = 0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++) { + ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j); + if (strlen(ent->dir) == (size_t)len && + strncmp(ent->dir, ss, (size_t)len) == 0) + break; + } + if (j < sk_BY_DIR_ENTRY_num(ctx->dirs)) + continue; + if (ctx->dirs == NULL) { + ctx->dirs = sk_BY_DIR_ENTRY_new_null(); + if (!ctx->dirs) { + X509err(X509_F_ADD_CERT_DIR, ERR_R_MALLOC_FAILURE); + return 0; + } + } + ent = malloc(sizeof(BY_DIR_ENTRY)); + if (!ent) { + X509err(X509_F_ADD_CERT_DIR, ERR_R_MALLOC_FAILURE); + return 0; + } + ent->dir_type = type; + ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp); + ent->dir = strndup(ss, (size_t)len); + if (!ent->dir || !ent->hashes) { + X509err(X509_F_ADD_CERT_DIR, ERR_R_MALLOC_FAILURE); + by_dir_entry_free(ent); + return 0; + } + if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) { + X509err(X509_F_ADD_CERT_DIR, ERR_R_MALLOC_FAILURE); + by_dir_entry_free(ent); + return 0; + } + } + } while (*p++ != '\0'); + return 1; +} + +static int +get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, + X509_OBJECT *ret) +{ + BY_DIR *ctx; + union { + struct { + X509 st_x509; + X509_CINF st_x509_cinf; + } x509; + struct { + X509_CRL st_crl; + X509_CRL_INFO st_crl_info; + } crl; + } data; + int ok = 0; + int i, j, k; + unsigned long h; + BUF_MEM *b = NULL; + X509_OBJECT stmp, *tmp; + const char *postfix=""; + + if (name == NULL) + return (0); + + stmp.type = type; + if (type == X509_LU_X509) { + data.x509.st_x509.cert_info = &data.x509.st_x509_cinf; + data.x509.st_x509_cinf.subject = name; + stmp.data.x509 = &data.x509.st_x509; + postfix=""; + } else if (type == X509_LU_CRL) { + data.crl.st_crl.crl = &data.crl.st_crl_info; + data.crl.st_crl_info.issuer = name; + stmp.data.crl = &data.crl.st_crl; + postfix="r"; + } else { + X509err(X509_F_GET_CERT_BY_SUBJECT, X509_R_WRONG_LOOKUP_TYPE); + goto finish; + } + + if ((b = BUF_MEM_new()) == NULL) { + X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_BUF_LIB); + goto finish; + } + + ctx = (BY_DIR *)xl->method_data; + + h = X509_NAME_hash(name); + for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) { + BY_DIR_ENTRY *ent; + int idx; + BY_DIR_HASH htmp, *hent; + ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i); + j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1; + if (!BUF_MEM_grow(b, j)) { + X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE); + goto finish; + } + if (type == X509_LU_CRL && ent->hashes) { + htmp.hash = h; + CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE); + idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp); + if (idx >= 0) { + hent = sk_BY_DIR_HASH_value(ent->hashes, idx); + k = hent->suffix; + } else { + hent = NULL; + k = 0; + } + CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); + } else { + k = 0; + hent = NULL; + } + for (;;) { + (void) snprintf(b->data, b->max, "%s/%08lx.%s%d", + ent->dir, h, postfix, k); + + { + struct stat st; + if (stat(b->data, &st) < 0) + break; + } + /* found one. */ + if (type == X509_LU_X509) { + if ((X509_load_cert_file(xl, b->data, + ent->dir_type)) == 0) + break; + } else if (type == X509_LU_CRL) { + if ((X509_load_crl_file(xl, b->data, + ent->dir_type)) == 0) + break; + } + /* else case will caught higher up */ + k++; + } + + /* we have added it to the cache so now pull it out again */ + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + j = sk_X509_OBJECT_find(xl->store_ctx->objs, &stmp); + if (j != -1) + tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j); + else + tmp = NULL; + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + /* If a CRL, update the last file suffix added for this */ + if (type == X509_LU_CRL) { + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + /* + * Look for entry again in case another thread added + * an entry first. + */ + if (!hent) { + htmp.hash = h; + idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp); + if (idx >= 0) + hent = sk_BY_DIR_HASH_value( + ent->hashes, idx); + } + if (!hent) { + hent = malloc(sizeof(BY_DIR_HASH)); + if (!hent) { + X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE); + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + ok = 0; + goto finish; + } + hent->hash = h; + hent->suffix = k; + if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) { + X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE); + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + free(hent); + ok = 0; + goto finish; + } + } else if (hent->suffix < k) + hent->suffix = k; + + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + } + + if (tmp != NULL) { + ok = 1; + ret->type = tmp->type; + memcpy(&ret->data, &tmp->data, sizeof(ret->data)); + /* + * If we were going to up the reference count, + * we would need to do it on a perl 'type' basis + */ + /* CRYPTO_add(&tmp->data.x509->references,1, + CRYPTO_LOCK_X509);*/ + goto finish; + } + } +finish: + if (b != NULL) + BUF_MEM_free(b); + return (ok); +} diff --git a/crypto/libressl/crypto/x509/by_file.c b/crypto/libressl/crypto/x509/by_file.c new file mode 100644 index 0000000000..74e7b3b5c9 --- /dev/null +++ b/crypto/libressl/crypto/x509/by_file.c @@ -0,0 +1,274 @@ +/* $OpenBSD: by_file.c,v 1.19 2015/04/11 16:03:21 deraadt Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); + +static X509_LOOKUP_METHOD x509_file_lookup = { + .name = "Load file into cache", + .new_item = NULL, + .free = NULL, + .init = NULL, + .shutdown = NULL, + .ctrl = by_file_ctrl, + .get_by_subject = NULL, + .get_by_issuer_serial = NULL, + .get_by_fingerprint = NULL, + .get_by_alias = NULL, +}; + +X509_LOOKUP_METHOD * +X509_LOOKUP_file(void) +{ + return (&x509_file_lookup); +} + +static int +by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, + char **ret) +{ + int ok = 0; + + switch (cmd) { + case X509_L_FILE_LOAD: + if (argl == X509_FILETYPE_DEFAULT) { + ok = (X509_load_cert_crl_file(ctx, + X509_get_default_cert_file(), + X509_FILETYPE_PEM) != 0); + if (!ok) { + X509err(X509_F_BY_FILE_CTRL, + X509_R_LOADING_DEFAULTS); + } + } else { + if (argl == X509_FILETYPE_PEM) + ok = (X509_load_cert_crl_file(ctx, argp, + X509_FILETYPE_PEM) != 0); + else + ok = (X509_load_cert_file(ctx, + argp, (int)argl) != 0); + } + break; + } + return (ok); +} + +int +X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) +{ + int ret = 0; + BIO *in = NULL; + int i, count = 0; + X509 *x = NULL; + + if (file == NULL) + return (1); + in = BIO_new(BIO_s_file_internal()); + + if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { + X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_SYS_LIB); + goto err; + } + + if (type == X509_FILETYPE_PEM) { + for (;;) { + x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL); + if (x == NULL) { + if ((ERR_GET_REASON(ERR_peek_last_error()) == + PEM_R_NO_START_LINE) && (count > 0)) { + ERR_clear_error(); + break; + } else { + X509err(X509_F_X509_LOAD_CERT_FILE, + ERR_R_PEM_LIB); + goto err; + } + } + i = X509_STORE_add_cert(ctx->store_ctx, x); + if (!i) + goto err; + count++; + X509_free(x); + x = NULL; + } + ret = count; + } else if (type == X509_FILETYPE_ASN1) { + x = d2i_X509_bio(in, NULL); + if (x == NULL) { + X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_ASN1_LIB); + goto err; + } + i = X509_STORE_add_cert(ctx->store_ctx, x); + if (!i) + goto err; + ret = i; + } else { + X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_BAD_X509_FILETYPE); + goto err; + } +err: + X509_free(x); + BIO_free(in); + return (ret); +} + +int +X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) +{ + int ret = 0; + BIO *in = NULL; + int i, count = 0; + X509_CRL *x = NULL; + + if (file == NULL) + return (1); + in = BIO_new(BIO_s_file_internal()); + + if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { + X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_SYS_LIB); + goto err; + } + + if (type == X509_FILETYPE_PEM) { + for (;;) { + x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); + if (x == NULL) { + if ((ERR_GET_REASON(ERR_peek_last_error()) == + PEM_R_NO_START_LINE) && (count > 0)) { + ERR_clear_error(); + break; + } else { + X509err(X509_F_X509_LOAD_CRL_FILE, + ERR_R_PEM_LIB); + goto err; + } + } + i = X509_STORE_add_crl(ctx->store_ctx, x); + if (!i) + goto err; + count++; + X509_CRL_free(x); + x = NULL; + } + ret = count; + } else if (type == X509_FILETYPE_ASN1) { + x = d2i_X509_CRL_bio(in, NULL); + if (x == NULL) { + X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_ASN1_LIB); + goto err; + } + i = X509_STORE_add_crl(ctx->store_ctx, x); + if (!i) + goto err; + ret = i; + } else { + X509err(X509_F_X509_LOAD_CRL_FILE, X509_R_BAD_X509_FILETYPE); + goto err; + } +err: + if (x != NULL) + X509_CRL_free(x); + BIO_free(in); + return (ret); +} + +int +X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) +{ + STACK_OF(X509_INFO) *inf; + X509_INFO *itmp; + BIO *in; + int i, count = 0; + if (type != X509_FILETYPE_PEM) + return X509_load_cert_file(ctx, file, type); + in = BIO_new_file(file, "r"); + if (!in) { + X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_SYS_LIB); + return 0; + } + inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); + BIO_free(in); + if (!inf) { + X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_PEM_LIB); + return 0; + } + for (i = 0; i < sk_X509_INFO_num(inf); i++) { + itmp = sk_X509_INFO_value(inf, i); + if (itmp->x509) { + X509_STORE_add_cert(ctx->store_ctx, itmp->x509); + count++; + } + if (itmp->crl) { + X509_STORE_add_crl(ctx->store_ctx, itmp->crl); + count++; + } + } + sk_X509_INFO_pop_free(inf, X509_INFO_free); + return count; +} + diff --git a/crypto/libressl/crypto/x509/by_mem.c b/crypto/libressl/crypto/x509/by_mem.c new file mode 100644 index 0000000000..5723c61ed5 --- /dev/null +++ b/crypto/libressl/crypto/x509/by_mem.c @@ -0,0 +1,138 @@ +/* $OpenBSD: by_mem.c,v 1.2 2015/01/22 11:16:56 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static int by_mem_ctrl(X509_LOOKUP *, int, const char *, long, char **); + +static X509_LOOKUP_METHOD x509_mem_lookup = { + .name = "Load cert from memory", + .new_item = NULL, + .free = NULL, + .init = NULL, + .shutdown = NULL, + .ctrl = by_mem_ctrl, + .get_by_subject = NULL, + .get_by_issuer_serial = NULL, + .get_by_fingerprint = NULL, + .get_by_alias = NULL, +}; + +X509_LOOKUP_METHOD * +X509_LOOKUP_mem(void) +{ + return (&x509_mem_lookup); +} + +static int +by_mem_ctrl(X509_LOOKUP *lu, int cmd, const char *buf, + long type, char **ret) +{ + STACK_OF(X509_INFO) *inf = NULL; + const struct iovec *iov; + X509_INFO *itmp; + BIO *in = NULL; + int i, count = 0, ok = 0; + + iov = (const struct iovec *)buf; + + if (!(cmd == X509_L_MEM && type == X509_FILETYPE_PEM)) + goto done; + + if ((in = BIO_new_mem_buf(iov->iov_base, iov->iov_len)) == NULL) + goto done; + + if ((inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL)) == NULL) + goto done; + + for (i = 0; i < sk_X509_INFO_num(inf); i++) { + itmp = sk_X509_INFO_value(inf, i); + if (itmp->x509) { + ok = X509_STORE_add_cert(lu->store_ctx, itmp->x509); + if (!ok) + goto done; + count++; + } + if (itmp->crl) { + ok = X509_STORE_add_crl(lu->store_ctx, itmp->crl); + if (!ok) + goto done; + count++; + } + } + + ok = count != 0; + done: + if (count == 0) + X509err(X509_F_X509_LOAD_CERT_CRL_FILE,ERR_R_PEM_LIB); + if (inf != NULL) + sk_X509_INFO_pop_free(inf, X509_INFO_free); + if (in != NULL) + BIO_free(in); + return (ok); +} diff --git a/crypto/libressl/crypto/x509/x509_att.c b/crypto/libressl/crypto/x509/x509_att.c new file mode 100644 index 0000000000..0d4b960226 --- /dev/null +++ b/crypto/libressl/crypto/x509/x509_att.c @@ -0,0 +1,403 @@ +/* $OpenBSD: x509_att.c,v 1.13 2014/09/29 16:20:40 miod Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +int +X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x) +{ + return sk_X509_ATTRIBUTE_num(x); +} + +int +X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, int lastpos) +{ + ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) + return (-2); + return (X509at_get_attr_by_OBJ(x, obj, lastpos)); +} + +int +X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, ASN1_OBJECT *obj, + int lastpos) +{ + int n; + X509_ATTRIBUTE *ex; + + if (sk == NULL) + return (-1); + lastpos++; + if (lastpos < 0) + lastpos = 0; + n = sk_X509_ATTRIBUTE_num(sk); + for (; lastpos < n; lastpos++) { + ex = sk_X509_ATTRIBUTE_value(sk, lastpos); + if (OBJ_cmp(ex->object, obj) == 0) + return (lastpos); + } + return (-1); +} + +X509_ATTRIBUTE * +X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc) +{ + if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0) + return NULL; + else + return sk_X509_ATTRIBUTE_value(x, loc); +} + +X509_ATTRIBUTE * +X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc) +{ + X509_ATTRIBUTE *ret; + + if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0) + return (NULL); + ret = sk_X509_ATTRIBUTE_delete(x, loc); + return (ret); +} + +STACK_OF(X509_ATTRIBUTE) * +X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, X509_ATTRIBUTE *attr) +{ + X509_ATTRIBUTE *new_attr = NULL; + STACK_OF(X509_ATTRIBUTE) *sk = NULL; + + if (x == NULL) { + X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + + if (*x == NULL) { + if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL) + goto err; + } else + sk = *x; + + if ((new_attr = X509_ATTRIBUTE_dup(attr)) == NULL) + goto err2; + if (!sk_X509_ATTRIBUTE_push(sk, new_attr)) + goto err; + if (*x == NULL) + *x = sk; + return (sk); + +err: + X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_MALLOC_FAILURE); +err2: + if (new_attr != NULL) + X509_ATTRIBUTE_free(new_attr); + if (sk != NULL && sk != *x) + sk_X509_ATTRIBUTE_free(sk); + return (NULL); +} + +STACK_OF(X509_ATTRIBUTE) * +X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x, const ASN1_OBJECT *obj, + int type, const unsigned char *bytes, int len) +{ + X509_ATTRIBUTE *attr; + STACK_OF(X509_ATTRIBUTE) *ret; + + attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len); + if (!attr) + return 0; + ret = X509at_add1_attr(x, attr); + X509_ATTRIBUTE_free(attr); + return ret; +} + +STACK_OF(X509_ATTRIBUTE) * +X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x, int nid, int type, + const unsigned char *bytes, int len) +{ + X509_ATTRIBUTE *attr; + STACK_OF(X509_ATTRIBUTE) *ret; + + attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len); + if (!attr) + return 0; + ret = X509at_add1_attr(x, attr); + X509_ATTRIBUTE_free(attr); + return ret; +} + +STACK_OF(X509_ATTRIBUTE) * +X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x, const char *attrname, + int type, const unsigned char *bytes, int len) +{ + X509_ATTRIBUTE *attr; + STACK_OF(X509_ATTRIBUTE) *ret; + + attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len); + if (!attr) + return 0; + ret = X509at_add1_attr(x, attr); + X509_ATTRIBUTE_free(attr); + return ret; +} + +void * +X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, ASN1_OBJECT *obj, + int lastpos, int type) +{ + int i; + X509_ATTRIBUTE *at; + + i = X509at_get_attr_by_OBJ(x, obj, lastpos); + if (i == -1) + return NULL; + if ((lastpos <= -2) && (X509at_get_attr_by_OBJ(x, obj, i) != -1)) + return NULL; + at = X509at_get_attr(x, i); + if (lastpos <= -3 && (X509_ATTRIBUTE_count(at) != 1)) + return NULL; + return X509_ATTRIBUTE_get0_data(at, 0, type, NULL); +} + +X509_ATTRIBUTE * +X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, int atrtype, + const void *data, int len) +{ + ASN1_OBJECT *obj; + X509_ATTRIBUTE *ret; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_NID, + X509_R_UNKNOWN_NID); + return (NULL); + } + ret = X509_ATTRIBUTE_create_by_OBJ(attr, obj, atrtype, data, len); + if (ret == NULL) + ASN1_OBJECT_free(obj); + return (ret); +} + +X509_ATTRIBUTE * +X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, const ASN1_OBJECT *obj, + int atrtype, const void *data, int len) +{ + X509_ATTRIBUTE *ret; + + if ((attr == NULL) || (*attr == NULL)) { + if ((ret = X509_ATTRIBUTE_new()) == NULL) { + X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ, + ERR_R_MALLOC_FAILURE); + return (NULL); + } + } else + ret= *attr; + + if (!X509_ATTRIBUTE_set1_object(ret, obj)) + goto err; + if (!X509_ATTRIBUTE_set1_data(ret, atrtype, data, len)) + goto err; + + if ((attr != NULL) && (*attr == NULL)) + *attr = ret; + return (ret); + +err: + if ((attr == NULL) || (ret != *attr)) + X509_ATTRIBUTE_free(ret); + return (NULL); +} + +X509_ATTRIBUTE * +X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, const char *atrname, + int type, const unsigned char *bytes, int len) +{ + ASN1_OBJECT *obj; + X509_ATTRIBUTE *nattr; + + obj = OBJ_txt2obj(atrname, 0); + if (obj == NULL) { + X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT, + X509_R_INVALID_FIELD_NAME); + ERR_asprintf_error_data("name=%s", atrname); + return (NULL); + } + nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len); + ASN1_OBJECT_free(obj); + return nattr; +} + +int +X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj) +{ + if ((attr == NULL) || (obj == NULL)) + return (0); + ASN1_OBJECT_free(attr->object); + attr->object = OBJ_dup(obj); + return attr->object != NULL; +} + +int +X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, + int len) +{ + ASN1_TYPE *ttmp = NULL; + ASN1_STRING *stmp = NULL; + int atype = 0; + + if (!attr) + return 0; + if (attrtype & MBSTRING_FLAG) { + stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype, + OBJ_obj2nid(attr->object)); + if (!stmp) { + X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, + ERR_R_ASN1_LIB); + return 0; + } + atype = stmp->type; + } else if (len != -1){ + if (!(stmp = ASN1_STRING_type_new(attrtype))) + goto err; + if (!ASN1_STRING_set(stmp, data, len)) + goto err; + atype = attrtype; + } + if (!(attr->value.set = sk_ASN1_TYPE_new_null())) + goto err; + attr->single = 0; + /* This is a bit naughty because the attribute should really have + * at least one value but some types use and zero length SET and + * require this. + */ + if (attrtype == 0) { + ASN1_STRING_free(stmp); + return 1; + } + + if (!(ttmp = ASN1_TYPE_new())) + goto err; + if ((len == -1) && !(attrtype & MBSTRING_FLAG)) { + if (!ASN1_TYPE_set1(ttmp, attrtype, data)) + goto err; + } else + ASN1_TYPE_set(ttmp, atype, stmp); + if (!sk_ASN1_TYPE_push(attr->value.set, ttmp)) + goto err; + return 1; + +err: + ASN1_TYPE_free(ttmp); + ASN1_STRING_free(stmp); + X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_MALLOC_FAILURE); + return 0; +} + +int +X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr) +{ + if (!attr->single) + return sk_ASN1_TYPE_num(attr->value.set); + if (attr->value.single) + return 1; + return 0; +} + +ASN1_OBJECT * +X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr) +{ + if (attr == NULL) + return (NULL); + return (attr->object); +} + +void * +X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype, void *data) +{ + ASN1_TYPE *ttmp; + + ttmp = X509_ATTRIBUTE_get0_type(attr, idx); + if (!ttmp) + return NULL; + if (atrtype != ASN1_TYPE_get(ttmp)){ + X509err(X509_F_X509_ATTRIBUTE_GET0_DATA, X509_R_WRONG_TYPE); + return NULL; + } + return ttmp->value.ptr; +} + +ASN1_TYPE * +X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx) +{ + if (attr == NULL) + return (NULL); + if (idx >= X509_ATTRIBUTE_count(attr)) + return NULL; + if (!attr->single) + return sk_ASN1_TYPE_value(attr->value.set, idx); + else + return attr->value.single; +} diff --git a/crypto/libressl/crypto/x509/x509_cmp.c b/crypto/libressl/crypto/x509/x509_cmp.c new file mode 100644 index 0000000000..d95ff5d273 --- /dev/null +++ b/crypto/libressl/crypto/x509/x509_cmp.c @@ -0,0 +1,369 @@ +/* $OpenBSD: x509_cmp.c,v 1.25 2014/09/26 19:31:09 miod Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +int +X509_issuer_and_serial_cmp(const X509 *a, const X509 *b) +{ + int i; + X509_CINF *ai, *bi; + + ai = a->cert_info; + bi = b->cert_info; + i = ASN1_STRING_cmp(ai->serialNumber, bi->serialNumber); + if (i) + return (i); + return (X509_NAME_cmp(ai->issuer, bi->issuer)); +} + +#ifndef OPENSSL_NO_MD5 +unsigned long +X509_issuer_and_serial_hash(X509 *a) +{ + unsigned long ret = 0; + EVP_MD_CTX ctx; + unsigned char md[16]; + char *f; + + EVP_MD_CTX_init(&ctx); + f = X509_NAME_oneline(a->cert_info->issuer, NULL, 0); + if (f == NULL) + goto err; + if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL)) + goto err; + if (!EVP_DigestUpdate(&ctx, (unsigned char *)f, strlen(f))) + goto err; + free(f); + f = NULL; + if (!EVP_DigestUpdate(&ctx, + (unsigned char *)a->cert_info->serialNumber->data, + (unsigned long)a->cert_info->serialNumber->length)) + goto err; + if (!EVP_DigestFinal_ex(&ctx, &(md[0]), NULL)) + goto err; + ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | + ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)) & + 0xffffffffL; + +err: + EVP_MD_CTX_cleanup(&ctx); + free(f); + return (ret); +} +#endif + +int +X509_issuer_name_cmp(const X509 *a, const X509 *b) +{ + return (X509_NAME_cmp(a->cert_info->issuer, b->cert_info->issuer)); +} + +int +X509_subject_name_cmp(const X509 *a, const X509 *b) +{ + return (X509_NAME_cmp(a->cert_info->subject, b->cert_info->subject)); +} + +int +X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b) +{ + return (X509_NAME_cmp(a->crl->issuer, b->crl->issuer)); +} + +#ifndef OPENSSL_NO_SHA +int +X509_CRL_match(const X509_CRL *a, const X509_CRL *b) +{ + return memcmp(a->sha1_hash, b->sha1_hash, 20); +} +#endif + +X509_NAME * +X509_get_issuer_name(X509 *a) +{ + return (a->cert_info->issuer); +} + +unsigned long +X509_issuer_name_hash(X509 *x) +{ + return (X509_NAME_hash(x->cert_info->issuer)); +} + +#ifndef OPENSSL_NO_MD5 +unsigned long +X509_issuer_name_hash_old(X509 *x) +{ + return (X509_NAME_hash_old(x->cert_info->issuer)); +} +#endif + +X509_NAME * +X509_get_subject_name(X509 *a) +{ + return (a->cert_info->subject); +} + +ASN1_INTEGER * +X509_get_serialNumber(X509 *a) +{ + return (a->cert_info->serialNumber); +} + +unsigned long +X509_subject_name_hash(X509 *x) +{ + return (X509_NAME_hash(x->cert_info->subject)); +} + +#ifndef OPENSSL_NO_MD5 +unsigned long +X509_subject_name_hash_old(X509 *x) +{ + return (X509_NAME_hash_old(x->cert_info->subject)); +} +#endif + +#ifndef OPENSSL_NO_SHA +/* Compare two certificates: they must be identical for + * this to work. NB: Although "cmp" operations are generally + * prototyped to take "const" arguments (eg. for use in + * STACKs), the way X509 handling is - these operations may + * involve ensuring the hashes are up-to-date and ensuring + * certain cert information is cached. So this is the point + * where the "depth-first" constification tree has to halt + * with an evil cast. + */ +int +X509_cmp(const X509 *a, const X509 *b) +{ + /* ensure hash is valid */ + X509_check_purpose((X509 *)a, -1, 0); + X509_check_purpose((X509 *)b, -1, 0); + + return memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH); +} +#endif + +int +X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) +{ + int ret; + + /* Ensure canonical encoding is present and up to date */ + if (!a->canon_enc || a->modified) { + ret = i2d_X509_NAME((X509_NAME *)a, NULL); + if (ret < 0) + return -2; + } + if (!b->canon_enc || b->modified) { + ret = i2d_X509_NAME((X509_NAME *)b, NULL); + if (ret < 0) + return -2; + } + ret = a->canon_enclen - b->canon_enclen; + if (ret) + return ret; + return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen); +} + +unsigned long +X509_NAME_hash(X509_NAME *x) +{ + unsigned long ret = 0; + unsigned char md[SHA_DIGEST_LENGTH]; + + /* Make sure X509_NAME structure contains valid cached encoding */ + i2d_X509_NAME(x, NULL); + if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(), + NULL)) + return 0; + + ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | + ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)) & + 0xffffffffL; + return (ret); +} + + +#ifndef OPENSSL_NO_MD5 +/* I now DER encode the name and hash it. Since I cache the DER encoding, + * this is reasonably efficient. */ + +unsigned long +X509_NAME_hash_old(X509_NAME *x) +{ + EVP_MD_CTX md_ctx; + unsigned long ret = 0; + unsigned char md[16]; + + /* Make sure X509_NAME structure contains valid cached encoding */ + i2d_X509_NAME(x, NULL); + EVP_MD_CTX_init(&md_ctx); + if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL) && + EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length) && + EVP_DigestFinal_ex(&md_ctx, md, NULL)) + ret = (((unsigned long)md[0]) | + ((unsigned long)md[1] << 8L) | + ((unsigned long)md[2] << 16L) | + ((unsigned long)md[3] << 24L)) & + 0xffffffffL; + EVP_MD_CTX_cleanup(&md_ctx); + + return (ret); +} +#endif + +/* Search a stack of X509 for a match */ +X509 * +X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name, + ASN1_INTEGER *serial) +{ + int i; + X509_CINF cinf; + X509 x, *x509 = NULL; + + if (!sk) + return NULL; + + x.cert_info = &cinf; + cinf.serialNumber = serial; + cinf.issuer = name; + + for (i = 0; i < sk_X509_num(sk); i++) { + x509 = sk_X509_value(sk, i); + if (X509_issuer_and_serial_cmp(x509, &x) == 0) + return (x509); + } + return (NULL); +} + +X509 * +X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name) +{ + X509 *x509; + int i; + + for (i = 0; i < sk_X509_num(sk); i++) { + x509 = sk_X509_value(sk, i); + if (X509_NAME_cmp(X509_get_subject_name(x509), name) == 0) + return (x509); + } + return (NULL); +} + +EVP_PKEY * +X509_get_pubkey(X509 *x) +{ + if ((x == NULL) || (x->cert_info == NULL)) + return (NULL); + return (X509_PUBKEY_get(x->cert_info->key)); +} + +ASN1_BIT_STRING * +X509_get0_pubkey_bitstr(const X509 *x) +{ + if (!x) + return NULL; + return x->cert_info->key->public_key; +} + +int +X509_check_private_key(X509 *x, EVP_PKEY *k) +{ + EVP_PKEY *xk; + int ret; + + xk = X509_get_pubkey(x); + + if (xk) + ret = EVP_PKEY_cmp(xk, k); + else + ret = -2; + + switch (ret) { + case 1: + break; + case 0: + X509err(X509_F_X509_CHECK_PRIVATE_KEY, + X509_R_KEY_VALUES_MISMATCH); + break; + case -1: + X509err(X509_F_X509_CHECK_PRIVATE_KEY, + X509_R_KEY_TYPE_MISMATCH); + break; + case -2: + X509err(X509_F_X509_CHECK_PRIVATE_KEY, + X509_R_UNKNOWN_KEY_TYPE); + } + EVP_PKEY_free(xk); + if (ret > 0) + return 1; + return 0; +} diff --git a/crypto/libressl/crypto/x509/x509_d2.c b/crypto/libressl/crypto/x509/x509_d2.c new file mode 100644 index 0000000000..4d8f0b2147 --- /dev/null +++ b/crypto/libressl/crypto/x509/x509_d2.c @@ -0,0 +1,128 @@ +/* $OpenBSD: x509_d2.c,v 1.9 2014/07/11 08:44:49 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include +#include + +int +X509_STORE_set_default_paths(X509_STORE *ctx) +{ + X509_LOOKUP *lookup; + + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); + if (lookup == NULL) + return (0); + X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); + + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); + if (lookup == NULL) + return (0); + X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); + + /* clear any errors */ + ERR_clear_error(); + + return (1); +} + +int +X509_STORE_load_locations(X509_STORE *ctx, const char *file, const char *path) +{ + X509_LOOKUP *lookup; + + if (file != NULL) { + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); + if (lookup == NULL) + return (0); + if (X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) != 1) + return (0); + } + if (path != NULL) { + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); + if (lookup == NULL) + return (0); + if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1) + return (0); + } + if ((path == NULL) && (file == NULL)) + return (0); + return (1); +} + +int +X509_STORE_load_mem(X509_STORE *ctx, void *buf, int len) +{ + X509_LOOKUP *lookup; + struct iovec iov; + + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_mem()); + if (lookup == NULL) + return (0); + + iov.iov_base = buf; + iov.iov_len = len; + + if (X509_LOOKUP_add_mem(lookup, &iov, X509_FILETYPE_PEM) != 1) + return (0); + + return (1); +} diff --git a/crypto/libressl/crypto/x509/x509_def.c b/crypto/libressl/crypto/x509/x509_def.c new file mode 100644 index 0000000000..1c88bdfc9a --- /dev/null +++ b/crypto/libressl/crypto/x509/x509_def.c @@ -0,0 +1,98 @@ +/* $OpenBSD$ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include + +const char * +X509_get_default_private_dir(void) +{ + return (X509_PRIVATE_DIR); +} + +const char * +X509_get_default_cert_area(void) +{ + return (X509_CERT_AREA); +} + +const char * +X509_get_default_cert_dir(void) +{ + return (X509_CERT_DIR); +} + +const char * +X509_get_default_cert_file(void) +{ + return (X509_CERT_FILE); +} + +const char * +X509_get_default_cert_dir_env(void) +{ + return (X509_CERT_DIR_EVP); +} + +const char * +X509_get_default_cert_file_env(void) +{ + return (X509_CERT_FILE_EVP); +} diff --git a/crypto/libressl/crypto/x509/x509_err.c b/crypto/libressl/crypto/x509/x509_err.c new file mode 100644 index 0000000000..0712421a95 --- /dev/null +++ b/crypto/libressl/crypto/x509/x509_err.c @@ -0,0 +1,164 @@ +/* $OpenBSD: x509_err.c,v 1.11 2014/06/12 15:49:31 deraadt Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include + +#include + +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509,0,reason) + +static ERR_STRING_DATA X509_str_functs[] = { + {ERR_FUNC(X509_F_ADD_CERT_DIR), "ADD_CERT_DIR"}, + {ERR_FUNC(X509_F_BY_FILE_CTRL), "BY_FILE_CTRL"}, + {ERR_FUNC(X509_F_CHECK_POLICY), "CHECK_POLICY"}, + {ERR_FUNC(X509_F_DIR_CTRL), "DIR_CTRL"}, + {ERR_FUNC(X509_F_GET_CERT_BY_SUBJECT), "GET_CERT_BY_SUBJECT"}, + {ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_DECODE), "NETSCAPE_SPKI_b64_decode"}, + {ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_ENCODE), "NETSCAPE_SPKI_b64_encode"}, + {ERR_FUNC(X509_F_X509AT_ADD1_ATTR), "X509at_add1_attr"}, + {ERR_FUNC(X509_F_X509V3_ADD_EXT), "X509v3_add_ext"}, + {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_NID), "X509_ATTRIBUTE_create_by_NID"}, + {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ), "X509_ATTRIBUTE_create_by_OBJ"}, + {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT), "X509_ATTRIBUTE_create_by_txt"}, + {ERR_FUNC(X509_F_X509_ATTRIBUTE_GET0_DATA), "X509_ATTRIBUTE_get0_data"}, + {ERR_FUNC(X509_F_X509_ATTRIBUTE_SET1_DATA), "X509_ATTRIBUTE_set1_data"}, + {ERR_FUNC(X509_F_X509_CHECK_PRIVATE_KEY), "X509_check_private_key"}, + {ERR_FUNC(X509_F_X509_CRL_PRINT_FP), "X509_CRL_print_fp"}, + {ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_NID), "X509_EXTENSION_create_by_NID"}, + {ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_OBJ), "X509_EXTENSION_create_by_OBJ"}, + {ERR_FUNC(X509_F_X509_GET_PUBKEY_PARAMETERS), "X509_get_pubkey_parameters"}, + {ERR_FUNC(X509_F_X509_LOAD_CERT_CRL_FILE), "X509_load_cert_crl_file"}, + {ERR_FUNC(X509_F_X509_LOAD_CERT_FILE), "X509_load_cert_file"}, + {ERR_FUNC(X509_F_X509_LOAD_CRL_FILE), "X509_load_crl_file"}, + {ERR_FUNC(X509_F_X509_NAME_ADD_ENTRY), "X509_NAME_add_entry"}, + {ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_NID), "X509_NAME_ENTRY_create_by_NID"}, + {ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT), "X509_NAME_ENTRY_create_by_txt"}, + {ERR_FUNC(X509_F_X509_NAME_ENTRY_SET_OBJECT), "X509_NAME_ENTRY_set_object"}, + {ERR_FUNC(X509_F_X509_NAME_ONELINE), "X509_NAME_oneline"}, + {ERR_FUNC(X509_F_X509_NAME_PRINT), "X509_NAME_print"}, + {ERR_FUNC(X509_F_X509_PRINT_EX_FP), "X509_print_ex_fp"}, + {ERR_FUNC(X509_F_X509_PUBKEY_GET), "X509_PUBKEY_get"}, + {ERR_FUNC(X509_F_X509_PUBKEY_SET), "X509_PUBKEY_set"}, + {ERR_FUNC(X509_F_X509_REQ_CHECK_PRIVATE_KEY), "X509_REQ_check_private_key"}, + {ERR_FUNC(X509_F_X509_REQ_PRINT_EX), "X509_REQ_print_ex"}, + {ERR_FUNC(X509_F_X509_REQ_PRINT_FP), "X509_REQ_print_fp"}, + {ERR_FUNC(X509_F_X509_REQ_TO_X509), "X509_REQ_to_X509"}, + {ERR_FUNC(X509_F_X509_STORE_ADD_CERT), "X509_STORE_add_cert"}, + {ERR_FUNC(X509_F_X509_STORE_ADD_CRL), "X509_STORE_add_crl"}, + {ERR_FUNC(X509_F_X509_STORE_CTX_GET1_ISSUER), "X509_STORE_CTX_get1_issuer"}, + {ERR_FUNC(X509_F_X509_STORE_CTX_INIT), "X509_STORE_CTX_init"}, + {ERR_FUNC(X509_F_X509_STORE_CTX_NEW), "X509_STORE_CTX_new"}, + {ERR_FUNC(X509_F_X509_STORE_CTX_PURPOSE_INHERIT), "X509_STORE_CTX_purpose_inherit"}, + {ERR_FUNC(X509_F_X509_TO_X509_REQ), "X509_to_X509_REQ"}, + {ERR_FUNC(X509_F_X509_TRUST_ADD), "X509_TRUST_add"}, + {ERR_FUNC(X509_F_X509_TRUST_SET), "X509_TRUST_set"}, + {ERR_FUNC(X509_F_X509_VERIFY_CERT), "X509_verify_cert"}, + {0, NULL} +}; + +static ERR_STRING_DATA X509_str_reasons[] = { + {ERR_REASON(X509_R_BAD_X509_FILETYPE) , "bad x509 filetype"}, + {ERR_REASON(X509_R_BASE64_DECODE_ERROR) , "base64 decode error"}, + {ERR_REASON(X509_R_CANT_CHECK_DH_KEY) , "cant check dh key"}, + {ERR_REASON(X509_R_CERT_ALREADY_IN_HASH_TABLE), "cert already in hash table"}, + {ERR_REASON(X509_R_ERR_ASN1_LIB) , "err asn1 lib"}, + {ERR_REASON(X509_R_INVALID_DIRECTORY) , "invalid directory"}, + {ERR_REASON(X509_R_INVALID_FIELD_NAME) , "invalid field name"}, + {ERR_REASON(X509_R_INVALID_TRUST) , "invalid trust"}, + {ERR_REASON(X509_R_KEY_TYPE_MISMATCH) , "key type mismatch"}, + {ERR_REASON(X509_R_KEY_VALUES_MISMATCH) , "key values mismatch"}, + {ERR_REASON(X509_R_LOADING_CERT_DIR) , "loading cert dir"}, + {ERR_REASON(X509_R_LOADING_DEFAULTS) , "loading defaults"}, + {ERR_REASON(X509_R_METHOD_NOT_SUPPORTED) , "method not supported"}, + {ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY), "no cert set for us to verify"}, + {ERR_REASON(X509_R_PUBLIC_KEY_DECODE_ERROR), "public key decode error"}, + {ERR_REASON(X509_R_PUBLIC_KEY_ENCODE_ERROR), "public key encode error"}, + {ERR_REASON(X509_R_SHOULD_RETRY) , "should retry"}, + {ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN), "unable to find parameters in chain"}, + {ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY), "unable to get certs public key"}, + {ERR_REASON(X509_R_UNKNOWN_KEY_TYPE) , "unknown key type"}, + {ERR_REASON(X509_R_UNKNOWN_NID) , "unknown nid"}, + {ERR_REASON(X509_R_UNKNOWN_PURPOSE_ID) , "unknown purpose id"}, + {ERR_REASON(X509_R_UNKNOWN_TRUST_ID) , "unknown trust id"}, + {ERR_REASON(X509_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"}, + {ERR_REASON(X509_R_WRONG_LOOKUP_TYPE) , "wrong lookup type"}, + {ERR_REASON(X509_R_WRONG_TYPE) , "wrong type"}, + {0, NULL} +}; + +#endif + +void +ERR_load_X509_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(X509_str_functs[0].error) == NULL) { + ERR_load_strings(0, X509_str_functs); + ERR_load_strings(0, X509_str_reasons); + } +#endif +} diff --git a/crypto/libressl/crypto/x509/x509_ext.c b/crypto/libressl/crypto/x509/x509_ext.c new file mode 100644 index 0000000000..1c938eebe0 --- /dev/null +++ b/crypto/libressl/crypto/x509/x509_ext.c @@ -0,0 +1,232 @@ +/* $OpenBSD: x509_ext.c,v 1.8 2014/07/11 08:44:49 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include +#include +#include + +int +X509_CRL_get_ext_count(X509_CRL *x) +{ + return (X509v3_get_ext_count(x->crl->extensions)); +} + +int +X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID(x->crl->extensions, nid, lastpos)); +} + +int +X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos) +{ + return (X509v3_get_ext_by_OBJ(x->crl->extensions, obj, lastpos)); +} + +int +X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos) +{ + return (X509v3_get_ext_by_critical(x->crl->extensions, crit, lastpos)); +} + +X509_EXTENSION * +X509_CRL_get_ext(X509_CRL *x, int loc) +{ + return (X509v3_get_ext(x->crl->extensions, loc)); +} + +X509_EXTENSION * +X509_CRL_delete_ext(X509_CRL *x, int loc) +{ + return (X509v3_delete_ext(x->crl->extensions, loc)); +} + +void * +X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->crl->extensions, nid, crit, idx); +} + +int +X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->crl->extensions, nid, value, crit, flags); +} + +int +X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->crl->extensions), ex, loc) != NULL); +} + +int +X509_get_ext_count(X509 *x) +{ + return (X509v3_get_ext_count(x->cert_info->extensions)); +} + +int +X509_get_ext_by_NID(X509 *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID(x->cert_info->extensions, nid, lastpos)); +} + +int +X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos) +{ + return (X509v3_get_ext_by_OBJ(x->cert_info->extensions, obj, lastpos)); +} + +int +X509_get_ext_by_critical(X509 *x, int crit, int lastpos) +{ + return (X509v3_get_ext_by_critical(x->cert_info->extensions, crit, + lastpos)); +} + +X509_EXTENSION * +X509_get_ext(X509 *x, int loc) +{ + return (X509v3_get_ext(x->cert_info->extensions, loc)); +} + +X509_EXTENSION * +X509_delete_ext(X509 *x, int loc) +{ + return (X509v3_delete_ext(x->cert_info->extensions, loc)); +} + +int +X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->cert_info->extensions), ex, loc) != NULL); +} + +void * +X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->cert_info->extensions, nid, crit, idx); +} + +int +X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, unsigned long flags) +{ + return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit, + flags); +} + +int +X509_REVOKED_get_ext_count(X509_REVOKED *x) +{ + return (X509v3_get_ext_count(x->extensions)); +} + +int +X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID(x->extensions, nid, lastpos)); +} + +int +X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj, int lastpos) +{ + return (X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos)); +} + +int +X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos) +{ + return (X509v3_get_ext_by_critical(x->extensions, crit, lastpos)); +} + +X509_EXTENSION * +X509_REVOKED_get_ext(X509_REVOKED *x, int loc) +{ + return (X509v3_get_ext(x->extensions, loc)); +} + +X509_EXTENSION * +X509_REVOKED_delete_ext(X509_REVOKED *x, int loc) +{ + return (X509v3_delete_ext(x->extensions, loc)); +} + +int +X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->extensions), ex, loc) != NULL); +} + +void * +X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->extensions, nid, crit, idx); +} + +int +X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags); +} diff --git a/crypto/libressl/crypto/x509/x509_lcl.h b/crypto/libressl/crypto/x509/x509_lcl.h new file mode 100644 index 0000000000..9ffdd01e61 --- /dev/null +++ b/crypto/libressl/crypto/x509/x509_lcl.h @@ -0,0 +1,61 @@ +/* x509_lcl.h */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2013. + */ +/* ==================================================================== + * Copyright (c) 2013 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +int x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int quiet); +int asn1_time_parse(const char *, size_t, struct tm *, int); +int asn1_tm_cmp(struct tm *tm1, struct tm *tm2); diff --git a/crypto/libressl/crypto/x509/x509_lu.c b/crypto/libressl/crypto/x509/x509_lu.c new file mode 100644 index 0000000000..3f923b2ed8 --- /dev/null +++ b/crypto/libressl/crypto/x509/x509_lu.c @@ -0,0 +1,739 @@ +/* $OpenBSD: x509_lu.c,v 1.19 2015/02/10 11:22:21 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include +#include "x509_lcl.h" + +X509_LOOKUP * +X509_LOOKUP_new(X509_LOOKUP_METHOD *method) +{ + X509_LOOKUP *ret; + + ret = malloc(sizeof(X509_LOOKUP)); + if (ret == NULL) + return NULL; + + ret->init = 0; + ret->skip = 0; + ret->method = method; + ret->method_data = NULL; + ret->store_ctx = NULL; + if ((method->new_item != NULL) && !method->new_item(ret)) { + free(ret); + return NULL; + } + return ret; +} + +void +X509_LOOKUP_free(X509_LOOKUP *ctx) +{ + if (ctx == NULL) + return; + if ((ctx->method != NULL) && (ctx->method->free != NULL)) + (*ctx->method->free)(ctx); + free(ctx); +} + +int +X509_LOOKUP_init(X509_LOOKUP *ctx) +{ + if (ctx->method == NULL) + return 0; + if (ctx->method->init != NULL) + return ctx->method->init(ctx); + else + return 1; +} + +int +X509_LOOKUP_shutdown(X509_LOOKUP *ctx) +{ + if (ctx->method == NULL) + return 0; + if (ctx->method->shutdown != NULL) + return ctx->method->shutdown(ctx); + else + return 1; +} + +int +X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret) +{ + if (ctx->method == NULL) + return -1; + if (ctx->method->ctrl != NULL) + return ctx->method->ctrl(ctx, cmd, argc, argl, ret); + else + return 1; +} + +int +X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret) +{ + if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) + return X509_LU_FAIL; + if (ctx->skip) + return 0; + return ctx->method->get_by_subject(ctx, type, name, ret); +} + +int +X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, + ASN1_INTEGER *serial, X509_OBJECT *ret) +{ + if ((ctx->method == NULL) || + (ctx->method->get_by_issuer_serial == NULL)) + return X509_LU_FAIL; + return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret); +} + +int +X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, unsigned char *bytes, + int len, X509_OBJECT *ret) +{ + if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL)) + return X509_LU_FAIL; + return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret); +} + +int +X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len, + X509_OBJECT *ret) +{ + if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL)) + return X509_LU_FAIL; + return ctx->method->get_by_alias(ctx, type, str, len, ret); +} + +static int +x509_object_cmp(const X509_OBJECT * const *a, const X509_OBJECT * const *b) +{ + int ret; + + ret = ((*a)->type - (*b)->type); + if (ret) + return ret; + switch ((*a)->type) { + case X509_LU_X509: + ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509); + break; + case X509_LU_CRL: + ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl); + break; + default: + /* abort(); */ + return 0; + } + return ret; +} + +X509_STORE * +X509_STORE_new(void) +{ + X509_STORE *ret; + + if ((ret = malloc(sizeof(X509_STORE))) == NULL) + return NULL; + ret->objs = sk_X509_OBJECT_new(x509_object_cmp); + ret->cache = 1; + ret->get_cert_methods = sk_X509_LOOKUP_new_null(); + ret->verify = 0; + ret->verify_cb = 0; + + if ((ret->param = X509_VERIFY_PARAM_new()) == NULL) + goto err; + + ret->get_issuer = 0; + ret->check_issued = 0; + ret->check_revocation = 0; + ret->get_crl = 0; + ret->check_crl = 0; + ret->cert_crl = 0; + ret->lookup_certs = 0; + ret->lookup_crls = 0; + ret->cleanup = 0; + + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) + goto err; + + ret->references = 1; + return ret; + +err: + X509_VERIFY_PARAM_free(ret->param); + sk_X509_LOOKUP_free(ret->get_cert_methods); + sk_X509_OBJECT_free(ret->objs); + free(ret); + return NULL; +} + +static void +cleanup(X509_OBJECT *a) +{ + if (a->type == X509_LU_X509) { + X509_free(a->data.x509); + } else if (a->type == X509_LU_CRL) { + X509_CRL_free(a->data.crl); + } else { + /* abort(); */ + } + + free(a); +} + +void +X509_STORE_free(X509_STORE *vfy) +{ + int i; + STACK_OF(X509_LOOKUP) *sk; + X509_LOOKUP *lu; + + if (vfy == NULL) + return; + + i = CRYPTO_add(&vfy->references, -1, CRYPTO_LOCK_X509_STORE); + if (i > 0) + return; + + sk = vfy->get_cert_methods; + for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { + lu = sk_X509_LOOKUP_value(sk, i); + X509_LOOKUP_shutdown(lu); + X509_LOOKUP_free(lu); + } + sk_X509_LOOKUP_free(sk); + sk_X509_OBJECT_pop_free(vfy->objs, cleanup); + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data); + X509_VERIFY_PARAM_free(vfy->param); + free(vfy); +} + +X509_LOOKUP * +X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) +{ + int i; + STACK_OF(X509_LOOKUP) *sk; + X509_LOOKUP *lu; + + sk = v->get_cert_methods; + for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { + lu = sk_X509_LOOKUP_value(sk, i); + if (m == lu->method) { + return lu; + } + } + /* a new one */ + lu = X509_LOOKUP_new(m); + if (lu == NULL) + return NULL; + else { + lu->store_ctx = v; + if (sk_X509_LOOKUP_push(v->get_cert_methods, lu)) + return lu; + else { + X509_LOOKUP_free(lu); + return NULL; + } + } +} + +int +X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, + X509_OBJECT *ret) +{ + X509_STORE *ctx = vs->ctx; + X509_LOOKUP *lu; + X509_OBJECT stmp, *tmp; + int i, j; + + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name); + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + if (tmp == NULL || type == X509_LU_CRL) { + for (i = vs->current_method; + i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) { + lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i); + j = X509_LOOKUP_by_subject(lu, type, name, &stmp); + if (j < 0) { + vs->current_method = j; + return j; + } else if (j) { + tmp = &stmp; + break; + } + } + vs->current_method = 0; + if (tmp == NULL) + return 0; + } + +/* if (ret->data.ptr != NULL) + X509_OBJECT_free_contents(ret); */ + + ret->type = tmp->type; + ret->data.ptr = tmp->data.ptr; + + X509_OBJECT_up_ref_count(ret); + + return 1; +} + +int +X509_STORE_add_cert(X509_STORE *ctx, X509 *x) +{ + X509_OBJECT *obj; + int ret = 1; + + if (x == NULL) + return 0; + obj = malloc(sizeof(X509_OBJECT)); + if (obj == NULL) { + X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE); + return 0; + } + obj->type = X509_LU_X509; + obj->data.x509 = x; + + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + + X509_OBJECT_up_ref_count(obj); + + if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { + X509_OBJECT_free_contents(obj); + free(obj); + X509err(X509_F_X509_STORE_ADD_CERT, + X509_R_CERT_ALREADY_IN_HASH_TABLE); + ret = 0; + } else + sk_X509_OBJECT_push(ctx->objs, obj); + + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + return ret; +} + +int +X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) +{ + X509_OBJECT *obj; + int ret = 1; + + if (x == NULL) + return 0; + obj = malloc(sizeof(X509_OBJECT)); + if (obj == NULL) { + X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE); + return 0; + } + obj->type = X509_LU_CRL; + obj->data.crl = x; + + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + + X509_OBJECT_up_ref_count(obj); + + if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { + X509_OBJECT_free_contents(obj); + free(obj); + X509err(X509_F_X509_STORE_ADD_CRL, + X509_R_CERT_ALREADY_IN_HASH_TABLE); + ret = 0; + } else + sk_X509_OBJECT_push(ctx->objs, obj); + + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + return ret; +} + +void +X509_OBJECT_up_ref_count(X509_OBJECT *a) +{ + switch (a->type) { + case X509_LU_X509: + CRYPTO_add(&a->data.x509->references, 1, CRYPTO_LOCK_X509); + break; + case X509_LU_CRL: + CRYPTO_add(&a->data.crl->references, 1, CRYPTO_LOCK_X509_CRL); + break; + } +} + +void +X509_OBJECT_free_contents(X509_OBJECT *a) +{ + switch (a->type) { + case X509_LU_X509: + X509_free(a->data.x509); + break; + case X509_LU_CRL: + X509_CRL_free(a->data.crl); + break; + } +} + +static int +x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, X509_NAME *name, + int *pnmatch) +{ + X509_OBJECT stmp; + X509 x509_s; + X509_CINF cinf_s; + X509_CRL crl_s; + X509_CRL_INFO crl_info_s; + int idx; + + stmp.type = type; + switch (type) { + case X509_LU_X509: + stmp.data.x509 = &x509_s; + x509_s.cert_info = &cinf_s; + cinf_s.subject = name; + break; + case X509_LU_CRL: + stmp.data.crl = &crl_s; + crl_s.crl = &crl_info_s; + crl_info_s.issuer = name; + break; + default: + /* abort(); */ + return -1; + } + + idx = sk_X509_OBJECT_find(h, &stmp); + if (idx >= 0 && pnmatch) { + int tidx; + const X509_OBJECT *tobj, *pstmp; + *pnmatch = 1; + pstmp = &stmp; + for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) { + tobj = sk_X509_OBJECT_value(h, tidx); + if (x509_object_cmp(&tobj, &pstmp)) + break; + (*pnmatch)++; + } + } + return idx; +} + +int +X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, X509_NAME *name) +{ + return x509_object_idx_cnt(h, type, name, NULL); +} + +X509_OBJECT * +X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name) +{ + int idx; + + idx = X509_OBJECT_idx_by_subject(h, type, name); + if (idx == -1) + return NULL; + return sk_X509_OBJECT_value(h, idx); +} + +STACK_OF(X509) * +X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) +{ + int i, idx, cnt; + STACK_OF(X509) *sk; + X509 *x; + X509_OBJECT *obj; + + sk = sk_X509_new_null(); + if (sk == NULL) + return NULL; + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); + if (idx < 0) { + /* Nothing found in cache: do lookup to possibly add new + * objects to cache + */ + X509_OBJECT xobj; + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) { + sk_X509_free(sk); + return NULL; + } + X509_OBJECT_free_contents(&xobj); + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + idx = x509_object_idx_cnt(ctx->ctx->objs, + X509_LU_X509, nm, &cnt); + if (idx < 0) { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + sk_X509_free(sk); + return NULL; + } + } + for (i = 0; i < cnt; i++, idx++) { + obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); + x = obj->data.x509; + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + if (!sk_X509_push(sk, x)) { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + X509_free(x); + sk_X509_pop_free(sk, X509_free); + return NULL; + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + return sk; + +} + +STACK_OF(X509_CRL) * +X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) +{ + int i, idx, cnt; + STACK_OF(X509_CRL) *sk; + X509_CRL *x; + X509_OBJECT *obj, xobj; + + sk = sk_X509_CRL_new_null(); + if (sk == NULL) + return NULL; + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + /* Check cache first */ + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt); + + /* Always do lookup to possibly add new CRLs to cache + */ + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) { + sk_X509_CRL_free(sk); + return NULL; + } + X509_OBJECT_free_contents(&xobj); + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt); + if (idx < 0) { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + sk_X509_CRL_free(sk); + return NULL; + } + + for (i = 0; i < cnt; i++, idx++) { + obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); + x = obj->data.crl; + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL); + if (!sk_X509_CRL_push(sk, x)) { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + X509_CRL_free(x); + sk_X509_CRL_pop_free(sk, X509_CRL_free); + return NULL; + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + return sk; +} + +X509_OBJECT * +X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x) +{ + int idx, i; + X509_OBJECT *obj; + + idx = sk_X509_OBJECT_find(h, x); + if (idx == -1) + return NULL; + if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL)) + return sk_X509_OBJECT_value(h, idx); + for (i = idx; i < sk_X509_OBJECT_num(h); i++) { + obj = sk_X509_OBJECT_value(h, i); + if (x509_object_cmp((const X509_OBJECT **)&obj, + (const X509_OBJECT **)&x)) + return NULL; + if (x->type == X509_LU_X509) { + if (!X509_cmp(obj->data.x509, x->data.x509)) + return obj; + } else if (x->type == X509_LU_CRL) { + if (!X509_CRL_match(obj->data.crl, x->data.crl)) + return obj; + } else + return obj; + } + return NULL; +} + + +/* Try to get issuer certificate from store. Due to limitations + * of the API this can only retrieve a single certificate matching + * a given subject name. However it will fill the cache with all + * matching certificates, so we can examine the cache for all + * matches. + * + * Return values are: + * 1 lookup successful. + * 0 certificate not found. + * -1 some other error. + */ +int +X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) +{ + X509_NAME *xn; + X509_OBJECT obj, *pobj; + int i, ok, idx, ret; + + *issuer = NULL; + xn = X509_get_issuer_name(x); + ok = X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj); + if (ok != X509_LU_X509) { + if (ok == X509_LU_RETRY) { + X509_OBJECT_free_contents(&obj); + X509err(X509_F_X509_STORE_CTX_GET1_ISSUER, + X509_R_SHOULD_RETRY); + return -1; + } else if (ok != X509_LU_FAIL) { + X509_OBJECT_free_contents(&obj); + /* not good :-(, break anyway */ + return -1; + } + return 0; + } + /* If certificate matches all OK */ + if (ctx->check_issued(ctx, x, obj.data.x509)) { + if (x509_check_cert_time(ctx, obj.data.x509, 1)) { + *issuer = obj.data.x509; + return 1; + } + } + X509_OBJECT_free_contents(&obj); + + /* Else find index of first cert accepted by 'check_issued' */ + ret = 0; + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn); + if (idx != -1) /* should be true as we've had at least one match */ { + /* Look through all matching certs for suitable issuer */ + for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) { + pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i); + /* See if we've run past the matches */ + if (pobj->type != X509_LU_X509) + break; + if (X509_NAME_cmp(xn, + X509_get_subject_name(pobj->data.x509))) + break; + if (ctx->check_issued(ctx, x, pobj->data.x509)) { + *issuer = pobj->data.x509; + ret = 1; + /* + * If times check, exit with match, + * otherwise keep looking. Leave last + * match in issuer so we return nearest + * match if no certificate time is OK. + */ + if (x509_check_cert_time(ctx, *issuer, 1)) + break; + } + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + if (*issuer) + CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509); + return ret; +} + +int +X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags) +{ + return X509_VERIFY_PARAM_set_flags(ctx->param, flags); +} + +int +X509_STORE_set_depth(X509_STORE *ctx, int depth) +{ + X509_VERIFY_PARAM_set_depth(ctx->param, depth); + return 1; +} + +int +X509_STORE_set_purpose(X509_STORE *ctx, int purpose) +{ + return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); +} + +int +X509_STORE_set_trust(X509_STORE *ctx, int trust) +{ + return X509_VERIFY_PARAM_set_trust(ctx->param, trust); +} + +int +X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) +{ + return X509_VERIFY_PARAM_set1(ctx->param, param); +} + +void +X509_STORE_set_verify_cb(X509_STORE *ctx, + int (*verify_cb)(int, X509_STORE_CTX *)) +{ + ctx->verify_cb = verify_cb; +} diff --git a/crypto/libressl/crypto/x509/x509_obj.c b/crypto/libressl/crypto/x509/x509_obj.c new file mode 100644 index 0000000000..0ff04d5c9b --- /dev/null +++ b/crypto/libressl/crypto/x509/x509_obj.c @@ -0,0 +1,179 @@ +/* $OpenBSD: x509_obj.c,v 1.15 2014/07/10 13:58:23 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include +#include +#include +#include + +char * +X509_NAME_oneline(X509_NAME *a, char *buf, int len) +{ + X509_NAME_ENTRY *ne; + int i; + int n, lold, l, l1, l2, num, j, type; + const char *s; + char *p; + unsigned char *q; + BUF_MEM *b = NULL; + static const char hex[17] = "0123456789ABCDEF"; + int gs_doit[4]; + char tmp_buf[80]; + + if (buf == NULL) { + if ((b = BUF_MEM_new()) == NULL) + goto err; + if (!BUF_MEM_grow(b, 200)) + goto err; + b->data[0] = '\0'; + len = 200; + } + if (a == NULL) { + if (b) { + buf = b->data; + free(b); + } + strlcpy(buf, "NO X509_NAME", len); + return buf; + } + + len--; /* space for '\0' */ + l = 0; + for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { + ne = sk_X509_NAME_ENTRY_value(a->entries, i); + n = OBJ_obj2nid(ne->object); + if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) { + i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object); + s = tmp_buf; + } + l1 = strlen(s); + + type = ne->value->type; + num = ne->value->length; + q = ne->value->data; + if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) { + gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0; + for (j = 0; j < num; j++) + if (q[j] != 0) + gs_doit[j & 3] = 1; + + if (gs_doit[0]|gs_doit[1]|gs_doit[2]) + gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; + else { + gs_doit[0] = gs_doit[1] = gs_doit[2] = 0; + gs_doit[3] = 1; + } + } else + gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; + + for (l2 = j=0; j < num; j++) { + if (!gs_doit[j&3]) + continue; + l2++; + if ((q[j] < ' ') || (q[j] > '~')) + l2 += 3; + } + + lold = l; + l += 1 + l1 + 1 + l2; + if (b != NULL) { + if (!BUF_MEM_grow(b, l + 1)) + goto err; + p = &(b->data[lold]); + } else if (l > len) { + break; + } else + p = &(buf[lold]); + *(p++) = '/'; + memcpy(p, s, l1); + p += l1; + *(p++) = '='; + q = ne->value->data; + for (j = 0; j < num; j++) { + if (!gs_doit[j & 3]) + continue; + n = q[j]; + if ((n < ' ') || (n > '~')) { + *(p++) = '\\'; + *(p++) = 'x'; + *(p++) = hex[(n >> 4) & 0x0f]; + *(p++) = hex[n & 0x0f]; + } else + *(p++) = n; + } + *p = '\0'; + } + if (b != NULL) { + p = b->data; + free(b); + } else + p = buf; + if (i == 0) + *p = '\0'; + return (p); + +err: + X509err(X509_F_X509_NAME_ONELINE, ERR_R_MALLOC_FAILURE); + if (b != NULL) + BUF_MEM_free(b); + return (NULL); +} diff --git a/crypto/libressl/crypto/x509/x509_r2x.c b/crypto/libressl/crypto/x509/x509_r2x.c new file mode 100644 index 0000000000..0de8af5c7c --- /dev/null +++ b/crypto/libressl/crypto/x509/x509_r2x.c @@ -0,0 +1,115 @@ +/* $OpenBSD: x509_r2x.c,v 1.9 2014/07/11 08:44:49 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +X509 * +X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey) +{ + X509 *ret = NULL; + X509_CINF *xi = NULL; + X509_NAME *xn; + + if ((ret = X509_new()) == NULL) { + X509err(X509_F_X509_REQ_TO_X509, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* duplicate the request */ + xi = ret->cert_info; + + if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0) { + if ((xi->version = ASN1_INTEGER_new()) == NULL) + goto err; + if (!ASN1_INTEGER_set(xi->version, 2)) + goto err; +/* xi->extensions=ri->attributes; <- bad, should not ever be done + ri->attributes=NULL; */ + } + + xn = X509_REQ_get_subject_name(r); + if (X509_set_subject_name(ret, X509_NAME_dup(xn)) == 0) + goto err; + if (X509_set_issuer_name(ret, X509_NAME_dup(xn)) == 0) + goto err; + + if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL) + goto err; + if (X509_gmtime_adj(xi->validity->notAfter, + (long)60 * 60 * 24 * days) == NULL) + goto err; + + X509_set_pubkey(ret, X509_REQ_get_pubkey(r)); + + if (!X509_sign(ret, pkey, EVP_md5())) + goto err; + if (0) { +err: + X509_free(ret); + ret = NULL; + } + return (ret); +} diff --git a/crypto/libressl/crypto/x509/x509_req.c b/crypto/libressl/crypto/x509/x509_req.c new file mode 100644 index 0000000000..fb7e66eedb --- /dev/null +++ b/crypto/libressl/crypto/x509/x509_req.c @@ -0,0 +1,347 @@ +/* $OpenBSD: x509_req.c,v 1.17 2015/03/15 22:52:17 doug Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +X509_REQ * +X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + X509_REQ *ret; + X509_REQ_INFO *ri; + int i; + EVP_PKEY *pktmp; + + ret = X509_REQ_new(); + if (ret == NULL) { + X509err(X509_F_X509_TO_X509_REQ, ERR_R_MALLOC_FAILURE); + goto err; + } + + ri = ret->req_info; + + if ((ri->version = ASN1_INTEGER_new()) == NULL) + goto err; + if (ASN1_INTEGER_set(ri->version, 0) == 0) + goto err; + + if (!X509_REQ_set_subject_name(ret, X509_get_subject_name(x))) + goto err; + + if ((pktmp = X509_get_pubkey(x)) == NULL) + goto err; + + i = X509_REQ_set_pubkey(ret, pktmp); + EVP_PKEY_free(pktmp); + if (!i) + goto err; + + if (pkey != NULL) { + if (!X509_REQ_sign(ret, pkey, md)) + goto err; + } + return (ret); + +err: + X509_REQ_free(ret); + return (NULL); +} + +EVP_PKEY * +X509_REQ_get_pubkey(X509_REQ *req) +{ + if ((req == NULL) || (req->req_info == NULL)) + return (NULL); + return (X509_PUBKEY_get(req->req_info->pubkey)); +} + +int +X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k) +{ + EVP_PKEY *xk = NULL; + int ok = 0; + + xk = X509_REQ_get_pubkey(x); + switch (EVP_PKEY_cmp(xk, k)) { + case 1: + ok = 1; + break; + case 0: + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, + X509_R_KEY_VALUES_MISMATCH); + break; + case -1: + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, + X509_R_KEY_TYPE_MISMATCH); + break; + case -2: +#ifndef OPENSSL_NO_EC + if (k->type == EVP_PKEY_EC) { + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, + ERR_R_EC_LIB); + break; + } +#endif +#ifndef OPENSSL_NO_DH + if (k->type == EVP_PKEY_DH) { + /* No idea */ + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, + X509_R_CANT_CHECK_DH_KEY); + break; + } +#endif + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, + X509_R_UNKNOWN_KEY_TYPE); + } + + EVP_PKEY_free(xk); + return (ok); +} + +/* It seems several organisations had the same idea of including a list of + * extensions in a certificate request. There are at least two OIDs that are + * used and there may be more: so the list is configurable. + */ + +static int ext_nid_list[] = {NID_ext_req, NID_ms_ext_req, NID_undef}; + +static int *ext_nids = ext_nid_list; + +int +X509_REQ_extension_nid(int req_nid) +{ + int i, nid; + + for (i = 0; ; i++) { + nid = ext_nids[i]; + if (nid == NID_undef) + return 0; + else if (req_nid == nid) + return 1; + } +} + +int * +X509_REQ_get_extension_nids(void) +{ + return ext_nids; +} + +void +X509_REQ_set_extension_nids(int *nids) +{ + ext_nids = nids; +} + +STACK_OF(X509_EXTENSION) * +X509_REQ_get_extensions(X509_REQ *req) +{ + X509_ATTRIBUTE *attr; + ASN1_TYPE *ext = NULL; + int idx, *pnid; + const unsigned char *p; + + if ((req == NULL) || (req->req_info == NULL) || !ext_nids) + return (NULL); + for (pnid = ext_nids; *pnid != NID_undef; pnid++) { + idx = X509_REQ_get_attr_by_NID(req, *pnid, -1); + if (idx == -1) + continue; + attr = X509_REQ_get_attr(req, idx); + if (attr->single) + ext = attr->value.single; + else if (sk_ASN1_TYPE_num(attr->value.set)) + ext = sk_ASN1_TYPE_value(attr->value.set, 0); + break; + } + if (!ext || (ext->type != V_ASN1_SEQUENCE)) + return NULL; + p = ext->value.sequence->data; + return (STACK_OF(X509_EXTENSION) *)ASN1_item_d2i(NULL, &p, + ext->value.sequence->length, ASN1_ITEM_rptr(X509_EXTENSIONS)); +} + +/* Add a STACK_OF extensions to a certificate request: allow alternative OIDs + * in case we want to create a non standard one. + */ + +int +X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, + int nid) +{ + ASN1_TYPE *at = NULL; + X509_ATTRIBUTE *attr = NULL; + + if (!(at = ASN1_TYPE_new()) || + !(at->value.sequence = ASN1_STRING_new())) + goto err; + + at->type = V_ASN1_SEQUENCE; + /* Generate encoding of extensions */ + at->value.sequence->length = ASN1_item_i2d((ASN1_VALUE *)exts, + &at->value.sequence->data, ASN1_ITEM_rptr(X509_EXTENSIONS)); + if (!(attr = X509_ATTRIBUTE_new())) + goto err; + if (!(attr->value.set = sk_ASN1_TYPE_new_null())) + goto err; + if (!sk_ASN1_TYPE_push(attr->value.set, at)) + goto err; + at = NULL; + attr->single = 0; + attr->object = OBJ_nid2obj(nid); + if (!req->req_info->attributes) { + if (!(req->req_info->attributes = sk_X509_ATTRIBUTE_new_null())) + goto err; + } + if (!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr)) + goto err; + return 1; + +err: + X509_ATTRIBUTE_free(attr); + ASN1_TYPE_free(at); + return 0; +} + +/* This is the normal usage: use the "official" OID */ +int +X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts) +{ + return X509_REQ_add_extensions_nid(req, exts, NID_ext_req); +} + +/* Request attribute functions */ + +int +X509_REQ_get_attr_count(const X509_REQ *req) +{ + return X509at_get_attr_count(req->req_info->attributes); +} + +int +X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos) +{ + return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos); +} + +int +X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj, int lastpos) +{ + return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos); +} + +X509_ATTRIBUTE * +X509_REQ_get_attr(const X509_REQ *req, int loc) +{ + return X509at_get_attr(req->req_info->attributes, loc); +} + +X509_ATTRIBUTE * +X509_REQ_delete_attr(X509_REQ *req, int loc) +{ + return X509at_delete_attr(req->req_info->attributes, loc); +} + +int +X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr) +{ + if (X509at_add1_attr(&req->req_info->attributes, attr)) + return 1; + return 0; +} + +int +X509_REQ_add1_attr_by_OBJ(X509_REQ *req, const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj, + type, bytes, len)) + return 1; + return 0; +} + +int +X509_REQ_add1_attr_by_NID(X509_REQ *req, int nid, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_NID(&req->req_info->attributes, nid, + type, bytes, len)) + return 1; + return 0; +} + +int +X509_REQ_add1_attr_by_txt(X509_REQ *req, const char *attrname, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_txt(&req->req_info->attributes, attrname, + type, bytes, len)) + return 1; + return 0; +} diff --git a/crypto/libressl/crypto/x509/x509_set.c b/crypto/libressl/crypto/x509/x509_set.c new file mode 100644 index 0000000000..e968d44911 --- /dev/null +++ b/crypto/libressl/crypto/x509/x509_set.c @@ -0,0 +1,154 @@ +/* $OpenBSD: x509_set.c,v 1.11 2015/09/30 17:30:16 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include + +int +X509_set_version(X509 *x, long version) +{ + if (x == NULL) + return (0); + if (x->cert_info->version == NULL) { + if ((x->cert_info->version = ASN1_INTEGER_new()) == NULL) + return (0); + } + return (ASN1_INTEGER_set(x->cert_info->version, version)); +} + +int +X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial) +{ + ASN1_INTEGER *in; + + if (x == NULL) + return (0); + in = x->cert_info->serialNumber; + if (in != serial) { + in = ASN1_INTEGER_dup(serial); + if (in != NULL) { + ASN1_INTEGER_free(x->cert_info->serialNumber); + x->cert_info->serialNumber = in; + } + } + return (in != NULL); +} + +int +X509_set_issuer_name(X509 *x, X509_NAME *name) +{ + if ((x == NULL) || (x->cert_info == NULL)) + return (0); + return (X509_NAME_set(&x->cert_info->issuer, name)); +} + +int +X509_set_subject_name(X509 *x, X509_NAME *name) +{ + if ((x == NULL) || (x->cert_info == NULL)) + return (0); + return (X509_NAME_set(&x->cert_info->subject, name)); +} + +int +X509_set_notBefore(X509 *x, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if ((x == NULL) || (x->cert_info->validity == NULL)) + return (0); + in = x->cert_info->validity->notBefore; + if (in != tm) { + in = ASN1_STRING_dup(tm); + if (in != NULL) { + ASN1_TIME_free(x->cert_info->validity->notBefore); + x->cert_info->validity->notBefore = in; + } + } + return (in != NULL); +} + +int +X509_set_notAfter(X509 *x, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if ((x == NULL) || (x->cert_info->validity == NULL)) + return (0); + in = x->cert_info->validity->notAfter; + if (in != tm) { + in = ASN1_STRING_dup(tm); + if (in != NULL) { + ASN1_TIME_free(x->cert_info->validity->notAfter); + x->cert_info->validity->notAfter = in; + } + } + return (in != NULL); +} + +int +X509_set_pubkey(X509 *x, EVP_PKEY *pkey) +{ + if ((x == NULL) || (x->cert_info == NULL)) + return (0); + return (X509_PUBKEY_set(&(x->cert_info->key), pkey)); +} diff --git a/crypto/libressl/crypto/x509/x509_trs.c b/crypto/libressl/crypto/x509/x509_trs.c new file mode 100644 index 0000000000..7a748dd565 --- /dev/null +++ b/crypto/libressl/crypto/x509/x509_trs.c @@ -0,0 +1,332 @@ +/* $OpenBSD: x509_trs.c,v 1.19 2014/12/06 19:26:37 doug Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include + +static int tr_cmp(const X509_TRUST * const *a, const X509_TRUST * const *b); +static void trtable_free(X509_TRUST *p); + +static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags); +static int trust_1oid(X509_TRUST *trust, X509 *x, int flags); +static int trust_compat(X509_TRUST *trust, X509 *x, int flags); + +static int obj_trust(int id, X509 *x, int flags); +static int (*default_trust)(int id, X509 *x, int flags) = obj_trust; + +/* WARNING: the following table should be kept in order of trust + * and without any gaps so we can just subtract the minimum trust + * value to get an index into the table + */ + +static X509_TRUST trstandard[] = { + {X509_TRUST_COMPAT, 0, trust_compat, "compatible", 0, NULL}, + {X509_TRUST_SSL_CLIENT, 0, trust_1oidany, "SSL Client", NID_client_auth, NULL}, + {X509_TRUST_SSL_SERVER, 0, trust_1oidany, "SSL Server", NID_server_auth, NULL}, + {X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect, NULL}, + {X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, "Object Signer", NID_code_sign, NULL}, + {X509_TRUST_OCSP_SIGN, 0, trust_1oid, "OCSP responder", NID_OCSP_sign, NULL}, + {X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP, NULL}, + {X509_TRUST_TSA, 0, trust_1oidany, "TSA server", NID_time_stamp, NULL} +}; + +#define X509_TRUST_COUNT (sizeof(trstandard)/sizeof(X509_TRUST)) + +static STACK_OF(X509_TRUST) *trtable = NULL; + +static int +tr_cmp(const X509_TRUST * const *a, const X509_TRUST * const *b) +{ + return (*a)->trust - (*b)->trust; +} + +int +(*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int) +{ + int (*oldtrust)(int , X509 *, int); + + oldtrust = default_trust; + default_trust = trust; + return oldtrust; +} + +int +X509_check_trust(X509 *x, int id, int flags) +{ + X509_TRUST *pt; + int idx; + + if (id == -1) + return 1; + idx = X509_TRUST_get_by_id(id); + if (idx == -1) + return default_trust(id, x, flags); + pt = X509_TRUST_get0(idx); + return pt->check_trust(pt, x, flags); +} + +int +X509_TRUST_get_count(void) +{ + if (!trtable) + return X509_TRUST_COUNT; + return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT; +} + +X509_TRUST * +X509_TRUST_get0(int idx) +{ + if (idx < 0) + return NULL; + if (idx < (int)X509_TRUST_COUNT) + return trstandard + idx; + return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT); +} + +int +X509_TRUST_get_by_id(int id) +{ + X509_TRUST tmp; + int idx; + + if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX)) + return id - X509_TRUST_MIN; + tmp.trust = id; + if (!trtable) + return -1; + idx = sk_X509_TRUST_find(trtable, &tmp); + if (idx == -1) + return -1; + return idx + X509_TRUST_COUNT; +} + +int +X509_TRUST_set(int *t, int trust) +{ + if (X509_TRUST_get_by_id(trust) == -1) { + X509err(X509_F_X509_TRUST_SET, X509_R_INVALID_TRUST); + return 0; + } + *t = trust; + return 1; +} + +int +X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int), + char *name, int arg1, void *arg2) +{ + int idx; + X509_TRUST *trtmp; + char *name_dup; + + /* This is set according to what we change: application can't set it */ + flags &= ~X509_TRUST_DYNAMIC; + /* This will always be set for application modified trust entries */ + flags |= X509_TRUST_DYNAMIC_NAME; + /* Get existing entry if any */ + idx = X509_TRUST_get_by_id(id); + /* Need a new entry */ + if (idx == -1) { + if (!(trtmp = malloc(sizeof(X509_TRUST)))) { + X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + trtmp->flags = X509_TRUST_DYNAMIC; + } else { + trtmp = X509_TRUST_get0(idx); + if (trtmp == NULL) { + X509err(X509_F_X509_TRUST_ADD, X509_R_INVALID_TRUST); + return 0; + } + } + + if ((name_dup = strdup(name)) == NULL) + goto err; + + /* free existing name if dynamic */ + if (trtmp->flags & X509_TRUST_DYNAMIC_NAME) + free(trtmp->name); + /* dup supplied name */ + trtmp->name = name_dup; + /* Keep the dynamic flag of existing entry */ + trtmp->flags &= X509_TRUST_DYNAMIC; + /* Set all other flags */ + trtmp->flags |= flags; + + trtmp->trust = id; + trtmp->check_trust = ck; + trtmp->arg1 = arg1; + trtmp->arg2 = arg2; + + /* If it's a new entry, manage the dynamic table */ + if (idx == -1) { + if (trtable == NULL && + (trtable = sk_X509_TRUST_new(tr_cmp)) == NULL) + goto err; + if (sk_X509_TRUST_push(trtable, trtmp) == 0) + goto err; + } + return 1; + +err: + free(name_dup); + if (idx == -1) + free(trtmp); + X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); + return 0; +} + +static void +trtable_free(X509_TRUST *p) +{ + if (!p) + return; + if (p->flags & X509_TRUST_DYNAMIC) { + if (p->flags & X509_TRUST_DYNAMIC_NAME) + free(p->name); + free(p); + } +} + +void +X509_TRUST_cleanup(void) +{ + unsigned int i; + + for (i = 0; i < X509_TRUST_COUNT; i++) + trtable_free(trstandard + i); + sk_X509_TRUST_pop_free(trtable, trtable_free); + trtable = NULL; +} + +int +X509_TRUST_get_flags(X509_TRUST *xp) +{ + return xp->flags; +} + +char * +X509_TRUST_get0_name(X509_TRUST *xp) +{ + return xp->name; +} + +int +X509_TRUST_get_trust(X509_TRUST *xp) +{ + return xp->trust; +} + +static int +trust_1oidany(X509_TRUST *trust, X509 *x, int flags) +{ + if (x->aux && (x->aux->trust || x->aux->reject)) + return obj_trust(trust->arg1, x, flags); + /* we don't have any trust settings: for compatibility + * we return trusted if it is self signed + */ + return trust_compat(trust, x, flags); +} + +static int +trust_1oid(X509_TRUST *trust, X509 *x, int flags) +{ + if (x->aux) + return obj_trust(trust->arg1, x, flags); + return X509_TRUST_UNTRUSTED; +} + +static int +trust_compat(X509_TRUST *trust, X509 *x, int flags) +{ + X509_check_purpose(x, -1, 0); + if (x->ex_flags & EXFLAG_SS) + return X509_TRUST_TRUSTED; + else + return X509_TRUST_UNTRUSTED; +} + +static int +obj_trust(int id, X509 *x, int flags) +{ + ASN1_OBJECT *obj; + int i; + X509_CERT_AUX *ax; + + ax = x->aux; + if (!ax) + return X509_TRUST_UNTRUSTED; + if (ax->reject) { + for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) { + obj = sk_ASN1_OBJECT_value(ax->reject, i); + if (OBJ_obj2nid(obj) == id) + return X509_TRUST_REJECTED; + } + } + if (ax->trust) { + for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) { + obj = sk_ASN1_OBJECT_value(ax->trust, i); + if (OBJ_obj2nid(obj) == id) + return X509_TRUST_TRUSTED; + } + } + return X509_TRUST_UNTRUSTED; +} diff --git a/crypto/libressl/crypto/x509/x509_txt.c b/crypto/libressl/crypto/x509/x509_txt.c new file mode 100644 index 0000000000..f017425b11 --- /dev/null +++ b/crypto/libressl/crypto/x509/x509_txt.c @@ -0,0 +1,189 @@ +/* $OpenBSD: x509_txt.c,v 1.18 2014/06/12 15:49:31 deraadt Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +const char * +X509_verify_cert_error_string(long n) +{ + static char buf[100]; + + switch ((int)n) { + case X509_V_OK: + return("ok"); + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: + return("unable to get issuer certificate"); + case X509_V_ERR_UNABLE_TO_GET_CRL: + return("unable to get certificate CRL"); + case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: + return("unable to decrypt certificate's signature"); + case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: + return("unable to decrypt CRL's signature"); + case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: + return("unable to decode issuer public key"); + case X509_V_ERR_CERT_SIGNATURE_FAILURE: + return("certificate signature failure"); + case X509_V_ERR_CRL_SIGNATURE_FAILURE: + return("CRL signature failure"); + case X509_V_ERR_CERT_NOT_YET_VALID: + return("certificate is not yet valid"); + case X509_V_ERR_CRL_NOT_YET_VALID: + return("CRL is not yet valid"); + case X509_V_ERR_CERT_HAS_EXPIRED: + return("certificate has expired"); + case X509_V_ERR_CRL_HAS_EXPIRED: + return("CRL has expired"); + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: + return("format error in certificate's notBefore field"); + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: + return("format error in certificate's notAfter field"); + case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: + return("format error in CRL's lastUpdate field"); + case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: + return("format error in CRL's nextUpdate field"); + case X509_V_ERR_OUT_OF_MEM: + return("out of memory"); + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + return("self signed certificate"); + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: + return("self signed certificate in certificate chain"); + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: + return("unable to get local issuer certificate"); + case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: + return("unable to verify the first certificate"); + case X509_V_ERR_CERT_CHAIN_TOO_LONG: + return("certificate chain too long"); + case X509_V_ERR_CERT_REVOKED: + return("certificate revoked"); + case X509_V_ERR_INVALID_CA: + return ("invalid CA certificate"); + case X509_V_ERR_INVALID_NON_CA: + return ("invalid non-CA certificate (has CA markings)"); + case X509_V_ERR_PATH_LENGTH_EXCEEDED: + return ("path length constraint exceeded"); + case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: + return("proxy path length constraint exceeded"); + case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: + return("proxy certificates not allowed, please set the appropriate flag"); + case X509_V_ERR_INVALID_PURPOSE: + return ("unsupported certificate purpose"); + case X509_V_ERR_CERT_UNTRUSTED: + return ("certificate not trusted"); + case X509_V_ERR_CERT_REJECTED: + return ("certificate rejected"); + case X509_V_ERR_APPLICATION_VERIFICATION: + return("application verification failure"); + case X509_V_ERR_SUBJECT_ISSUER_MISMATCH: + return("subject issuer mismatch"); + case X509_V_ERR_AKID_SKID_MISMATCH: + return("authority and subject key identifier mismatch"); + case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: + return("authority and issuer serial number mismatch"); + case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: + return("key usage does not include certificate signing"); + case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: + return("unable to get CRL issuer certificate"); + case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: + return("unhandled critical extension"); + case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: + return("key usage does not include CRL signing"); + case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: + return("key usage does not include digital signature"); + case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: + return("unhandled critical CRL extension"); + case X509_V_ERR_INVALID_EXTENSION: + return("invalid or inconsistent certificate extension"); + case X509_V_ERR_INVALID_POLICY_EXTENSION: + return("invalid or inconsistent certificate policy extension"); + case X509_V_ERR_NO_EXPLICIT_POLICY: + return("no explicit policy"); + case X509_V_ERR_DIFFERENT_CRL_SCOPE: + return("Different CRL scope"); + case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: + return("Unsupported extension feature"); + case X509_V_ERR_UNNESTED_RESOURCE: + return("RFC 3779 resource not subset of parent's resources"); + case X509_V_ERR_PERMITTED_VIOLATION: + return("permitted subtree violation"); + case X509_V_ERR_EXCLUDED_VIOLATION: + return("excluded subtree violation"); + case X509_V_ERR_SUBTREE_MINMAX: + return("name constraints minimum and maximum not supported"); + case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: + return("unsupported name constraint type"); + case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: + return("unsupported or invalid name constraint syntax"); + case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: + return("unsupported or invalid name syntax"); + case X509_V_ERR_CRL_PATH_VALIDATION_ERROR: + return("CRL path validation error"); + + default: + (void) snprintf(buf, sizeof buf, "error number %ld", n); + return(buf); + } +} diff --git a/crypto/libressl/crypto/x509/x509_v3.c b/crypto/libressl/crypto/x509/x509_v3.c new file mode 100644 index 0000000000..31300d4b7b --- /dev/null +++ b/crypto/libressl/crypto/x509/x509_v3.c @@ -0,0 +1,300 @@ +/* $OpenBSD: x509_v3.c,v 1.12 2015/07/29 14:58:34 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +int +X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x) +{ + if (x == NULL) + return (0); + return (sk_X509_EXTENSION_num(x)); +} + +int +X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid, int lastpos) +{ + ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) + return (-2); + return (X509v3_get_ext_by_OBJ(x, obj, lastpos)); +} + +int +X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk, ASN1_OBJECT *obj, + int lastpos) +{ + int n; + X509_EXTENSION *ex; + + if (sk == NULL) + return (-1); + lastpos++; + if (lastpos < 0) + lastpos = 0; + n = sk_X509_EXTENSION_num(sk); + for (; lastpos < n; lastpos++) { + ex = sk_X509_EXTENSION_value(sk, lastpos); + if (OBJ_cmp(ex->object, obj) == 0) + return (lastpos); + } + return (-1); +} + +int +X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit, + int lastpos) +{ + int n; + X509_EXTENSION *ex; + + if (sk == NULL) + return (-1); + lastpos++; + if (lastpos < 0) + lastpos = 0; + n = sk_X509_EXTENSION_num(sk); + for (; lastpos < n; lastpos++) { + ex = sk_X509_EXTENSION_value(sk, lastpos); + if (((ex->critical > 0) && crit) || + ((ex->critical <= 0) && !crit)) + return (lastpos); + } + return (-1); +} + +X509_EXTENSION * +X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc) +{ + if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0) + return NULL; + else + return sk_X509_EXTENSION_value(x, loc); +} + +X509_EXTENSION * +X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc) +{ + X509_EXTENSION *ret; + + if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0) + return (NULL); + ret = sk_X509_EXTENSION_delete(x, loc); + return (ret); +} + +STACK_OF(X509_EXTENSION) * +X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, X509_EXTENSION *ex, int loc) +{ + X509_EXTENSION *new_ex = NULL; + int n; + STACK_OF(X509_EXTENSION) *sk = NULL; + + if (x == NULL) { + X509err(X509_F_X509V3_ADD_EXT, ERR_R_PASSED_NULL_PARAMETER); + goto err2; + } + + if (*x == NULL) { + if ((sk = sk_X509_EXTENSION_new_null()) == NULL) + goto err; + } else + sk= *x; + + n = sk_X509_EXTENSION_num(sk); + if (loc > n) + loc = n; + else if (loc < 0) + loc = n; + + if ((new_ex = X509_EXTENSION_dup(ex)) == NULL) + goto err2; + if (!sk_X509_EXTENSION_insert(sk, new_ex, loc)) + goto err; + if (*x == NULL) + *x = sk; + return (sk); + +err: + X509err(X509_F_X509V3_ADD_EXT, ERR_R_MALLOC_FAILURE); +err2: + if (new_ex != NULL) + X509_EXTENSION_free(new_ex); + if (sk != NULL && (x != NULL && sk != *x)) + sk_X509_EXTENSION_free(sk); + return (NULL); +} + +X509_EXTENSION * +X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, int crit, + ASN1_OCTET_STRING *data) +{ + ASN1_OBJECT *obj; + X509_EXTENSION *ret; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + X509err(X509_F_X509_EXTENSION_CREATE_BY_NID, + X509_R_UNKNOWN_NID); + return (NULL); + } + ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data); + if (ret == NULL) + ASN1_OBJECT_free(obj); + return (ret); +} + +X509_EXTENSION * +X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, ASN1_OBJECT *obj, int crit, + ASN1_OCTET_STRING *data) +{ + X509_EXTENSION *ret; + + if ((ex == NULL) || (*ex == NULL)) { + if ((ret = X509_EXTENSION_new()) == NULL) { + X509err(X509_F_X509_EXTENSION_CREATE_BY_OBJ, + ERR_R_MALLOC_FAILURE); + return (NULL); + } + } else + ret= *ex; + + if (!X509_EXTENSION_set_object(ret, obj)) + goto err; + if (!X509_EXTENSION_set_critical(ret, crit)) + goto err; + if (!X509_EXTENSION_set_data(ret, data)) + goto err; + + if ((ex != NULL) && (*ex == NULL)) + *ex = ret; + return (ret); + +err: + if ((ex == NULL) || (ret != *ex)) + X509_EXTENSION_free(ret); + return (NULL); +} + +int +X509_EXTENSION_set_object(X509_EXTENSION *ex, ASN1_OBJECT *obj) +{ + if ((ex == NULL) || (obj == NULL)) + return (0); + ASN1_OBJECT_free(ex->object); + ex->object = OBJ_dup(obj); + return ex->object != NULL; +} + +int +X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit) +{ + if (ex == NULL) + return (0); + ex->critical = (crit) ? 0xFF : -1; + return (1); +} + +int +X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data) +{ + int i; + + if (ex == NULL) + return (0); + i = ASN1_STRING_set(ex->value, data->data, data->length); + if (!i) + return (0); + return (1); +} + +ASN1_OBJECT * +X509_EXTENSION_get_object(X509_EXTENSION *ex) +{ + if (ex == NULL) + return (NULL); + return (ex->object); +} + +ASN1_OCTET_STRING * +X509_EXTENSION_get_data(X509_EXTENSION *ex) +{ + if (ex == NULL) + return (NULL); + return (ex->value); +} + +int +X509_EXTENSION_get_critical(X509_EXTENSION *ex) +{ + if (ex == NULL) + return (0); + if (ex->critical > 0) + return 1; + return 0; +} diff --git a/crypto/libressl/crypto/x509/x509_vfy.c b/crypto/libressl/crypto/x509/x509_vfy.c new file mode 100644 index 0000000000..2bddd264de --- /dev/null +++ b/crypto/libressl/crypto/x509/x509_vfy.c @@ -0,0 +1,2157 @@ +/* $OpenBSD: x509_vfy.c,v 1.48 2015/12/14 03:38:13 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "x509_lcl.h" + +/* CRL score values */ + +/* No unhandled critical extensions */ + +#define CRL_SCORE_NOCRITICAL 0x100 + +/* certificate is within CRL scope */ + +#define CRL_SCORE_SCOPE 0x080 + +/* CRL times valid */ + +#define CRL_SCORE_TIME 0x040 + +/* Issuer name matches certificate */ + +#define CRL_SCORE_ISSUER_NAME 0x020 + +/* If this score or above CRL is probably valid */ + +#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE) + +/* CRL issuer is certificate issuer */ + +#define CRL_SCORE_ISSUER_CERT 0x018 + +/* CRL issuer is on certificate path */ + +#define CRL_SCORE_SAME_PATH 0x008 + +/* CRL issuer matches CRL AKID */ + +#define CRL_SCORE_AKID 0x004 + +/* Have a delta CRL with valid times */ + +#define CRL_SCORE_TIME_DELTA 0x002 + +static int null_callback(int ok, X509_STORE_CTX *e); +static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); +static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); +static int check_chain_extensions(X509_STORE_CTX *ctx); +static int check_name_constraints(X509_STORE_CTX *ctx); +static int check_trust(X509_STORE_CTX *ctx); +static int check_revocation(X509_STORE_CTX *ctx); +static int check_cert(X509_STORE_CTX *ctx); +static int check_policy(X509_STORE_CTX *ctx); + +static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, + unsigned int *preasons, X509_CRL *crl, X509 *x); +static int get_crl_delta(X509_STORE_CTX *ctx, + X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x); +static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pcrl_score, + X509_CRL *base, STACK_OF(X509_CRL) *crls); +static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer, + int *pcrl_score); +static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, + unsigned int *preasons); +static int check_crl_path(X509_STORE_CTX *ctx, X509 *x); +static int check_crl_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *cert_path, + STACK_OF(X509) *crl_path); + +static int internal_verify(X509_STORE_CTX *ctx); + +static int +null_callback(int ok, X509_STORE_CTX *e) +{ + return ok; +} + +#if 0 +static int +x509_subject_cmp(X509 **a, X509 **b) +{ + return X509_subject_name_cmp(*a, *b); +} +#endif + +int +X509_verify_cert(X509_STORE_CTX *ctx) +{ + X509 *x, *xtmp, *chain_ss = NULL; + int bad_chain = 0; + X509_VERIFY_PARAM *param = ctx->param; + int depth, i, ok = 0; + int num; + int (*cb)(int xok, X509_STORE_CTX *xctx); + STACK_OF(X509) *sktmp = NULL; + + if (ctx->cert == NULL) { + X509err(X509_F_X509_VERIFY_CERT, + X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); + return -1; + } + + cb = ctx->verify_cb; + + /* first we make sure the chain we are going to build is + * present and that the first entry is in place */ + if (ctx->chain == NULL) { + if (((ctx->chain = sk_X509_new_null()) == NULL) || + (!sk_X509_push(ctx->chain, ctx->cert))) { + X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + goto end; + } + CRYPTO_add(&ctx->cert->references, 1, CRYPTO_LOCK_X509); + ctx->last_untrusted = 1; + } + + /* We use a temporary STACK so we can chop and hack at it */ + if (ctx->untrusted != NULL && + (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) { + X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + goto end; + } + + num = sk_X509_num(ctx->chain); + x = sk_X509_value(ctx->chain, num - 1); + depth = param->depth; + + for (;;) { + /* If we have enough, we break */ + if (depth < num) + break; /* FIXME: If this happens, we should take + * note of it and, if appropriate, use the + * X509_V_ERR_CERT_CHAIN_TOO_LONG error + * code later. + */ + + /* If we are self signed, we break */ + if (ctx->check_issued(ctx, x, x)) + break; + + /* If we were passed a cert chain, use it first */ + if (ctx->untrusted != NULL) { + xtmp = find_issuer(ctx, sktmp, x); + if (xtmp != NULL) { + if (!sk_X509_push(ctx->chain, xtmp)) { + X509err(X509_F_X509_VERIFY_CERT, + ERR_R_MALLOC_FAILURE); + goto end; + } + CRYPTO_add(&xtmp->references, 1, + CRYPTO_LOCK_X509); + (void)sk_X509_delete_ptr(sktmp, xtmp); + ctx->last_untrusted++; + x = xtmp; + num++; + /* reparse the full chain for + * the next one */ + continue; + } + } + break; + } + sk_X509_free(sktmp); + sktmp = NULL; + + /* at this point, chain should contain a list of untrusted + * certificates. We now need to add at least one trusted one, + * if possible, otherwise we complain. */ + + /* Examine last certificate in chain and see if it + * is self signed. + */ + + i = sk_X509_num(ctx->chain); + x = sk_X509_value(ctx->chain, i - 1); + if (ctx->check_issued(ctx, x, x)) { + /* we have a self signed certificate */ + if (sk_X509_num(ctx->chain) == 1) { + /* We have a single self signed certificate: see if + * we can find it in the store. We must have an exact + * match to avoid possible impersonation. + */ + ok = ctx->get_issuer(&xtmp, ctx, x); + if ((ok <= 0) || X509_cmp(x, xtmp)) { + ctx->error = + X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; + ctx->current_cert = x; + ctx->error_depth = i - 1; + if (ok == 1) + X509_free(xtmp); + bad_chain = 1; + ok = cb(0, ctx); + if (!ok) + goto end; + } else { + /* We have a match: replace certificate with store version + * so we get any trust settings. + */ + X509_free(x); + x = xtmp; + (void)sk_X509_set(ctx->chain, i - 1, x); + ctx->last_untrusted = 0; + } + } else { + /* extract and save self signed certificate for later use */ + chain_ss = sk_X509_pop(ctx->chain); + ctx->last_untrusted--; + num--; + x = sk_X509_value(ctx->chain, num - 1); + } + } + + /* We now lookup certs from the certificate store */ + for (;;) { + /* If we have enough, we break */ + if (depth < num) + break; + + /* If we are self signed, we break */ + if (ctx->check_issued(ctx, x, x)) + break; + + ok = ctx->get_issuer(&xtmp, ctx, x); + if (ok < 0) + return ok; + if (ok == 0) + break; + + x = xtmp; + if (!sk_X509_push(ctx->chain, x)) { + X509_free(xtmp); + X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + return 0; + } + num++; + } + + /* we now have our chain, lets check it... */ + + /* Is last certificate looked up self signed? */ + if (!ctx->check_issued(ctx, x, x)) { + if ((chain_ss == NULL) || + !ctx->check_issued(ctx, x, chain_ss)) { + if (ctx->last_untrusted >= num) + ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; + else + ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; + ctx->current_cert = x; + } else { + + if (!sk_X509_push(ctx->chain, chain_ss)) { + X509_free(chain_ss); + X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + return 0; + } + num++; + ctx->last_untrusted = num; + ctx->current_cert = chain_ss; + ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; + chain_ss = NULL; + } + + ctx->error_depth = num - 1; + bad_chain = 1; + ok = cb(0, ctx); + if (!ok) + goto end; + } + + /* We have the chain complete: now we need to check its purpose */ + ok = check_chain_extensions(ctx); + + if (!ok) + goto end; + + /* Check name constraints */ + + ok = check_name_constraints(ctx); + + if (!ok) + goto end; + + /* The chain extensions are OK: check trust */ + + if (param->trust > 0) + ok = check_trust(ctx); + + if (!ok) + goto end; + + /* We may as well copy down any DSA parameters that are required */ + X509_get_pubkey_parameters(NULL, ctx->chain); + + /* Check revocation status: we do this after copying parameters + * because they may be needed for CRL signature verification. + */ + + ok = ctx->check_revocation(ctx); + if (!ok) + goto end; + + /* At this point, we have a chain and need to verify it */ + if (ctx->verify != NULL) + ok = ctx->verify(ctx); + else + ok = internal_verify(ctx); + if (!ok) + goto end; + + /* If we get this far evaluate policies */ + if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK)) + ok = ctx->check_policy(ctx); + if (!ok) + goto end; + if (0) { +end: + X509_get_pubkey_parameters(NULL, ctx->chain); + } + if (sktmp != NULL) + sk_X509_free(sktmp); + X509_free(chain_ss); + return ok; +} + + +/* Given a STACK_OF(X509) find the issuer of cert (if any) + */ + +static X509 * +find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) +{ + int i; + X509 *issuer, *rv = NULL; + + for (i = 0; i < sk_X509_num(sk); i++) { + issuer = sk_X509_value(sk, i); + if (ctx->check_issued(ctx, x, issuer)) { + rv = issuer; + if (x509_check_cert_time(ctx, rv, 1)) + break; + } + } + return rv; +} + +/* Given a possible certificate and issuer check them */ + +static int +check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) +{ + int ret; + + ret = X509_check_issued(issuer, x); + if (ret == X509_V_OK) + return 1; + /* If we haven't asked for issuer errors don't set ctx */ + if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK)) + return 0; + + ctx->error = ret; + ctx->current_cert = x; + ctx->current_issuer = issuer; + return ctx->verify_cb(0, ctx); +} + +/* Alternative lookup method: look from a STACK stored in other_ctx */ + +static int +get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) +{ + *issuer = find_issuer(ctx, ctx->other_ctx, x); + if (*issuer) { + CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509); + return 1; + } else + return 0; +} + +/* Check a certificate chains extensions for consistency + * with the supplied purpose + */ + +static int +check_chain_extensions(X509_STORE_CTX *ctx) +{ +#ifdef OPENSSL_NO_CHAIN_VERIFY + return 1; +#else + int i, ok = 0, must_be_ca, plen = 0; + X509 *x; + int (*cb)(int xok, X509_STORE_CTX *xctx); + int proxy_path_length = 0; + int purpose; + int allow_proxy_certs; + + cb = ctx->verify_cb; + + /* must_be_ca can have 1 of 3 values: + -1: we accept both CA and non-CA certificates, to allow direct + use of self-signed certificates (which are marked as CA). + 0: we only accept non-CA certificates. This is currently not + used, but the possibility is present for future extensions. + 1: we only accept CA certificates. This is currently used for + all certificates in the chain except the leaf certificate. + */ + must_be_ca = -1; + + /* CRL path validation */ + if (ctx->parent) { + allow_proxy_certs = 0; + purpose = X509_PURPOSE_CRL_SIGN; + } else { + allow_proxy_certs = + !!(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS); + purpose = ctx->param->purpose; + } + + /* Check all untrusted certificates */ + for (i = 0; i < ctx->last_untrusted; i++) { + int ret; + x = sk_X509_value(ctx->chain, i); + if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) && + (x->ex_flags & EXFLAG_CRITICAL)) { + ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) { + ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED; + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + ret = X509_check_ca(x); + switch (must_be_ca) { + case -1: + if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) && + (ret != 1) && (ret != 0)) { + ret = 0; + ctx->error = X509_V_ERR_INVALID_CA; + } else + ret = 1; + break; + case 0: + if (ret != 0) { + ret = 0; + ctx->error = X509_V_ERR_INVALID_NON_CA; + } else + ret = 1; + break; + default: + if ((ret == 0) || + ((ctx->param->flags & X509_V_FLAG_X509_STRICT) && + (ret != 1))) { + ret = 0; + ctx->error = X509_V_ERR_INVALID_CA; + } else + ret = 1; + break; + } + if (ret == 0) { + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + if (ctx->param->purpose > 0) { + ret = X509_check_purpose(x, purpose, must_be_ca > 0); + if ((ret == 0) || + ((ctx->param->flags & X509_V_FLAG_X509_STRICT) && + (ret != 1))) { + ctx->error = X509_V_ERR_INVALID_PURPOSE; + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + } + /* Check pathlen if not self issued */ + if ((i > 1) && !(x->ex_flags & EXFLAG_SI) && + (x->ex_pathlen != -1) && + (plen > (x->ex_pathlen + proxy_path_length + 1))) { + ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED; + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + /* Increment path length if not self issued */ + if (!(x->ex_flags & EXFLAG_SI)) + plen++; + /* If this certificate is a proxy certificate, the next + certificate must be another proxy certificate or a EE + certificate. If not, the next certificate must be a + CA certificate. */ + if (x->ex_flags & EXFLAG_PROXY) { + if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) { + ctx->error = + X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED; + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + proxy_path_length++; + must_be_ca = 0; + } else + must_be_ca = 1; + } + ok = 1; + +end: + return ok; +#endif +} + +static int +check_name_constraints(X509_STORE_CTX *ctx) +{ + X509 *x; + int i, j, rv; + + /* Check name constraints for all certificates */ + for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--) { + x = sk_X509_value(ctx->chain, i); + /* Ignore self issued certs unless last in chain */ + if (i && (x->ex_flags & EXFLAG_SI)) + continue; + /* Check against constraints for all certificates higher in + * chain including trust anchor. Trust anchor not strictly + * speaking needed but if it includes constraints it is to be + * assumed it expects them to be obeyed. + */ + for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) { + NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc; + if (nc) { + rv = NAME_CONSTRAINTS_check(x, nc); + if (rv != X509_V_OK) { + ctx->error = rv; + ctx->error_depth = i; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + } + } + } + return 1; +} + +static int +check_trust(X509_STORE_CTX *ctx) +{ +#ifdef OPENSSL_NO_CHAIN_VERIFY + return 1; +#else + int i, ok; + X509 *x; + int (*cb)(int xok, X509_STORE_CTX *xctx); + + cb = ctx->verify_cb; + /* For now just check the last certificate in the chain */ + i = sk_X509_num(ctx->chain) - 1; + x = sk_X509_value(ctx->chain, i); + ok = X509_check_trust(x, ctx->param->trust, 0); + if (ok == X509_TRUST_TRUSTED) + return 1; + ctx->error_depth = i; + ctx->current_cert = x; + if (ok == X509_TRUST_REJECTED) + ctx->error = X509_V_ERR_CERT_REJECTED; + else + ctx->error = X509_V_ERR_CERT_UNTRUSTED; + ok = cb(0, ctx); + return ok; +#endif +} + +static int +check_revocation(X509_STORE_CTX *ctx) +{ + int i, last, ok; + + if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK)) + return 1; + if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL) + last = sk_X509_num(ctx->chain) - 1; + else { + /* If checking CRL paths this isn't the EE certificate */ + if (ctx->parent) + return 1; + last = 0; + } + for (i = 0; i <= last; i++) { + ctx->error_depth = i; + ok = check_cert(ctx); + if (!ok) + return ok; + } + return 1; +} + +static int +check_cert(X509_STORE_CTX *ctx) +{ + X509_CRL *crl = NULL, *dcrl = NULL; + X509 *x; + int ok = 0, cnum; + unsigned int last_reasons; + + cnum = ctx->error_depth; + x = sk_X509_value(ctx->chain, cnum); + ctx->current_cert = x; + ctx->current_issuer = NULL; + ctx->current_crl_score = 0; + ctx->current_reasons = 0; + while (ctx->current_reasons != CRLDP_ALL_REASONS) { + last_reasons = ctx->current_reasons; + /* Try to retrieve relevant CRL */ + if (ctx->get_crl) + ok = ctx->get_crl(ctx, &crl, x); + else + ok = get_crl_delta(ctx, &crl, &dcrl, x); + /* If error looking up CRL, nothing we can do except + * notify callback + */ + if (!ok) { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; + ok = ctx->verify_cb(0, ctx); + goto err; + } + ctx->current_crl = crl; + ok = ctx->check_crl(ctx, crl); + if (!ok) + goto err; + + if (dcrl) { + ok = ctx->check_crl(ctx, dcrl); + if (!ok) + goto err; + ok = ctx->cert_crl(ctx, dcrl, x); + if (!ok) + goto err; + } else + ok = 1; + + /* Don't look in full CRL if delta reason is removefromCRL */ + if (ok != 2) { + ok = ctx->cert_crl(ctx, crl, x); + if (!ok) + goto err; + } + + ctx->current_crl = NULL; + X509_CRL_free(crl); + X509_CRL_free(dcrl); + crl = NULL; + dcrl = NULL; + /* If reasons not updated we wont get anywhere by + * another iteration, so exit loop. + */ + if (last_reasons == ctx->current_reasons) { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; + ok = ctx->verify_cb(0, ctx); + goto err; + } + } + +err: + ctx->current_crl = NULL; + X509_CRL_free(crl); + X509_CRL_free(dcrl); + return ok; +} + +/* Check CRL times against values in X509_STORE_CTX */ + +static int +check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) +{ + time_t *ptime = NULL; + int i; + + if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) + return (1); + + if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) + ptime = &ctx->param->check_time; + + if (notify) + ctx->current_crl = crl; + + i = X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime); + if (i == 0) { + if (!notify) + return 0; + ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + if (i > 0) { + if (!notify) + return 0; + ctx->error = X509_V_ERR_CRL_NOT_YET_VALID; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + if (X509_CRL_get_nextUpdate(crl)) { + i = X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime); + + if (i == 0) { + if (!notify) + return 0; + ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + /* Ignore expiry of base CRL is delta is valid */ + if ((i < 0) && + !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) { + if (!notify) + return 0; + ctx->error = X509_V_ERR_CRL_HAS_EXPIRED; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + } + + if (notify) + ctx->current_crl = NULL; + + return 1; +} + +static int +get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, + X509 **pissuer, int *pscore, unsigned int *preasons, + STACK_OF(X509_CRL) *crls) +{ + int i, crl_score, best_score = *pscore; + unsigned int reasons, best_reasons = 0; + X509 *x = ctx->current_cert; + X509_CRL *crl, *best_crl = NULL; + X509 *crl_issuer = NULL, *best_crl_issuer = NULL; + + for (i = 0; i < sk_X509_CRL_num(crls); i++) { + crl = sk_X509_CRL_value(crls, i); + reasons = *preasons; + crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x); + + if (crl_score > best_score) { + best_crl = crl; + best_crl_issuer = crl_issuer; + best_score = crl_score; + best_reasons = reasons; + } + } + + if (best_crl) { + if (*pcrl) + X509_CRL_free(*pcrl); + *pcrl = best_crl; + *pissuer = best_crl_issuer; + *pscore = best_score; + *preasons = best_reasons; + CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL); + if (*pdcrl) { + X509_CRL_free(*pdcrl); + *pdcrl = NULL; + } + get_delta_sk(ctx, pdcrl, pscore, best_crl, crls); + } + + if (best_score >= CRL_SCORE_VALID) + return 1; + + return 0; +} + +/* Compare two CRL extensions for delta checking purposes. They should be + * both present or both absent. If both present all fields must be identical. + */ + +static int +crl_extension_match(X509_CRL *a, X509_CRL *b, int nid) +{ + ASN1_OCTET_STRING *exta, *extb; + int i; + + i = X509_CRL_get_ext_by_NID(a, nid, -1); + if (i >= 0) { + /* Can't have multiple occurrences */ + if (X509_CRL_get_ext_by_NID(a, nid, i) != -1) + return 0; + exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i)); + } else + exta = NULL; + + i = X509_CRL_get_ext_by_NID(b, nid, -1); + + if (i >= 0) { + if (X509_CRL_get_ext_by_NID(b, nid, i) != -1) + return 0; + extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i)); + } else + extb = NULL; + + if (!exta && !extb) + return 1; + + if (!exta || !extb) + return 0; + + if (ASN1_OCTET_STRING_cmp(exta, extb)) + return 0; + + return 1; +} + +/* See if a base and delta are compatible */ + +static int +check_delta_base(X509_CRL *delta, X509_CRL *base) +{ + /* Delta CRL must be a delta */ + if (!delta->base_crl_number) + return 0; + /* Base must have a CRL number */ + if (!base->crl_number) + return 0; + /* Issuer names must match */ + if (X509_NAME_cmp(X509_CRL_get_issuer(base), + X509_CRL_get_issuer(delta))) + return 0; + /* AKID and IDP must match */ + if (!crl_extension_match(delta, base, NID_authority_key_identifier)) + return 0; + if (!crl_extension_match(delta, base, NID_issuing_distribution_point)) + return 0; + /* Delta CRL base number must not exceed Full CRL number. */ + if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0) + return 0; + /* Delta CRL number must exceed full CRL number */ + if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0) + return 1; + return 0; +} + +/* For a given base CRL find a delta... maybe extend to delta scoring + * or retrieve a chain of deltas... + */ + +static void +get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore, X509_CRL *base, + STACK_OF(X509_CRL) *crls) +{ + X509_CRL *delta; + int i; + + if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS)) + return; + if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST)) + return; + for (i = 0; i < sk_X509_CRL_num(crls); i++) { + delta = sk_X509_CRL_value(crls, i); + if (check_delta_base(delta, base)) { + if (check_crl_time(ctx, delta, 0)) + *pscore |= CRL_SCORE_TIME_DELTA; + CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL); + *dcrl = delta; + return; + } + } + *dcrl = NULL; +} + +/* For a given CRL return how suitable it is for the supplied certificate 'x'. + * The return value is a mask of several criteria. + * If the issuer is not the certificate issuer this is returned in *pissuer. + * The reasons mask is also used to determine if the CRL is suitable: if + * no new reasons the CRL is rejected, otherwise reasons is updated. + */ + +static int +get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, unsigned int *preasons, + X509_CRL *crl, X509 *x) +{ + int crl_score = 0; + unsigned int tmp_reasons = *preasons, crl_reasons; + + /* First see if we can reject CRL straight away */ + + /* Invalid IDP cannot be processed */ + if (crl->idp_flags & IDP_INVALID) + return 0; + /* Reason codes or indirect CRLs need extended CRL support */ + if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) { + if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS)) + return 0; + } else if (crl->idp_flags & IDP_REASONS) { + /* If no new reasons reject */ + if (!(crl->idp_reasons & ~tmp_reasons)) + return 0; + } + /* Don't process deltas at this stage */ + else if (crl->base_crl_number) + return 0; + /* If issuer name doesn't match certificate need indirect CRL */ + if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) { + if (!(crl->idp_flags & IDP_INDIRECT)) + return 0; + } else + crl_score |= CRL_SCORE_ISSUER_NAME; + + if (!(crl->flags & EXFLAG_CRITICAL)) + crl_score |= CRL_SCORE_NOCRITICAL; + + /* Check expiry */ + if (check_crl_time(ctx, crl, 0)) + crl_score |= CRL_SCORE_TIME; + + /* Check authority key ID and locate certificate issuer */ + crl_akid_check(ctx, crl, pissuer, &crl_score); + + /* If we can't locate certificate issuer at this point forget it */ + + if (!(crl_score & CRL_SCORE_AKID)) + return 0; + + /* Check cert for matching CRL distribution points */ + + if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) { + /* If no new reasons reject */ + if (!(crl_reasons & ~tmp_reasons)) + return 0; + tmp_reasons |= crl_reasons; + crl_score |= CRL_SCORE_SCOPE; + } + + *preasons = tmp_reasons; + + return crl_score; +} + +static void +crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer, + int *pcrl_score) +{ + X509 *crl_issuer = NULL; + X509_NAME *cnm = X509_CRL_get_issuer(crl); + int cidx = ctx->error_depth; + int i; + + if (cidx != sk_X509_num(ctx->chain) - 1) + cidx++; + + crl_issuer = sk_X509_value(ctx->chain, cidx); + + if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { + if (*pcrl_score & CRL_SCORE_ISSUER_NAME) { + *pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_ISSUER_CERT; + *pissuer = crl_issuer; + return; + } + } + + for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++) { + crl_issuer = sk_X509_value(ctx->chain, cidx); + if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) + continue; + if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { + *pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_SAME_PATH; + *pissuer = crl_issuer; + return; + } + } + + /* Anything else needs extended CRL support */ + + if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) + return; + + /* Otherwise the CRL issuer is not on the path. Look for it in the + * set of untrusted certificates. + */ + for (i = 0; i < sk_X509_num(ctx->untrusted); i++) { + crl_issuer = sk_X509_value(ctx->untrusted, i); + if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) + continue; + if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { + *pissuer = crl_issuer; + *pcrl_score |= CRL_SCORE_AKID; + return; + } + } +} + +/* Check the path of a CRL issuer certificate. This creates a new + * X509_STORE_CTX and populates it with most of the parameters from the + * parent. This could be optimised somewhat since a lot of path checking + * will be duplicated by the parent, but this will rarely be used in + * practice. + */ + +static int +check_crl_path(X509_STORE_CTX *ctx, X509 *x) +{ + X509_STORE_CTX crl_ctx; + int ret; + + /* Don't allow recursive CRL path validation */ + if (ctx->parent) + return 0; + if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted)) { + ret = -1; + goto err; + } + + crl_ctx.crls = ctx->crls; + /* Copy verify params across */ + X509_STORE_CTX_set0_param(&crl_ctx, ctx->param); + + crl_ctx.parent = ctx; + crl_ctx.verify_cb = ctx->verify_cb; + + /* Verify CRL issuer */ + ret = X509_verify_cert(&crl_ctx); + + if (ret <= 0) + goto err; + + /* Check chain is acceptable */ + ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain); + +err: + X509_STORE_CTX_cleanup(&crl_ctx); + return ret; +} + +/* RFC3280 says nothing about the relationship between CRL path + * and certificate path, which could lead to situations where a + * certificate could be revoked or validated by a CA not authorised + * to do so. RFC5280 is more strict and states that the two paths must + * end in the same trust anchor, though some discussions remain... + * until this is resolved we use the RFC5280 version + */ + +static int +check_crl_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *cert_path, + STACK_OF(X509) *crl_path) +{ + X509 *cert_ta, *crl_ta; + + cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1); + crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1); + if (!X509_cmp(cert_ta, crl_ta)) + return 1; + return 0; +} + +/* Check for match between two dist point names: three separate cases. + * 1. Both are relative names and compare X509_NAME types. + * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES. + * 3. Both are full names and compare two GENERAL_NAMES. + * 4. One is NULL: automatic match. + */ + +static int +idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) +{ + X509_NAME *nm = NULL; + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gena, *genb; + int i, j; + + if (!a || !b) + return 1; + if (a->type == 1) { + if (!a->dpname) + return 0; + /* Case 1: two X509_NAME */ + if (b->type == 1) { + if (!b->dpname) + return 0; + if (!X509_NAME_cmp(a->dpname, b->dpname)) + return 1; + else + return 0; + } + /* Case 2: set name and GENERAL_NAMES appropriately */ + nm = a->dpname; + gens = b->name.fullname; + } else if (b->type == 1) { + if (!b->dpname) + return 0; + /* Case 2: set name and GENERAL_NAMES appropriately */ + gens = a->name.fullname; + nm = b->dpname; + } + + /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */ + if (nm) { + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + gena = sk_GENERAL_NAME_value(gens, i); + if (gena->type != GEN_DIRNAME) + continue; + if (!X509_NAME_cmp(nm, gena->d.directoryName)) + return 1; + } + return 0; + } + + /* Else case 3: two GENERAL_NAMES */ + + for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) { + gena = sk_GENERAL_NAME_value(a->name.fullname, i); + for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) { + genb = sk_GENERAL_NAME_value(b->name.fullname, j); + if (!GENERAL_NAME_cmp(gena, genb)) + return 1; + } + } + + return 0; +} + +static int +crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score) +{ + int i; + X509_NAME *nm = X509_CRL_get_issuer(crl); + + /* If no CRLissuer return is successful iff don't need a match */ + if (!dp->CRLissuer) + return !!(crl_score & CRL_SCORE_ISSUER_NAME); + for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); + if (gen->type != GEN_DIRNAME) + continue; + if (!X509_NAME_cmp(gen->d.directoryName, nm)) + return 1; + } + return 0; +} + +/* Check CRLDP and IDP */ + +static int +crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, unsigned int *preasons) +{ + int i; + + if (crl->idp_flags & IDP_ONLYATTR) + return 0; + if (x->ex_flags & EXFLAG_CA) { + if (crl->idp_flags & IDP_ONLYUSER) + return 0; + } else { + if (crl->idp_flags & IDP_ONLYCA) + return 0; + } + *preasons = crl->idp_reasons; + for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) { + DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i); + if (crldp_check_crlissuer(dp, crl, crl_score)) { + if (!crl->idp || + idp_check_dp(dp->distpoint, crl->idp->distpoint)) { + *preasons &= dp->dp_reasons; + return 1; + } + } + } + if ((!crl->idp || !crl->idp->distpoint) && + (crl_score & CRL_SCORE_ISSUER_NAME)) + return 1; + return 0; +} + +/* Retrieve CRL corresponding to current certificate. + * If deltas enabled try to find a delta CRL too + */ + +static int +get_crl_delta(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x) +{ + int ok; + X509 *issuer = NULL; + int crl_score = 0; + unsigned int reasons; + X509_CRL *crl = NULL, *dcrl = NULL; + STACK_OF(X509_CRL) *skcrl; + X509_NAME *nm = X509_get_issuer_name(x); + + reasons = ctx->current_reasons; + ok = get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, + ctx->crls); + if (ok) + goto done; + + /* Lookup CRLs from store */ + skcrl = ctx->lookup_crls(ctx, nm); + + /* If no CRLs found and a near match from get_crl_sk use that */ + if (!skcrl && crl) + goto done; + + get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl); + + sk_X509_CRL_pop_free(skcrl, X509_CRL_free); + +done: + + /* If we got any kind of CRL use it and return success */ + if (crl) { + ctx->current_issuer = issuer; + ctx->current_crl_score = crl_score; + ctx->current_reasons = reasons; + *pcrl = crl; + *pdcrl = dcrl; + return 1; + } + + return 0; +} + +/* Check CRL validity */ +static int +check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) +{ + X509 *issuer = NULL; + EVP_PKEY *ikey = NULL; + int ok = 0, chnum, cnum; + + cnum = ctx->error_depth; + chnum = sk_X509_num(ctx->chain) - 1; + /* if we have an alternative CRL issuer cert use that */ + if (ctx->current_issuer) { + issuer = ctx->current_issuer; + } else if (cnum < chnum) { + /* Else find CRL issuer: if not last certificate then issuer + * is next certificate in chain. + */ + issuer = sk_X509_value(ctx->chain, cnum + 1); + } else { + issuer = sk_X509_value(ctx->chain, chnum); + /* If not self signed, can't check signature */ + if (!ctx->check_issued(ctx, issuer, issuer)) { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + } + + if (issuer) { + /* Skip most tests for deltas because they have already + * been done + */ + if (!crl->base_crl_number) { + /* Check for cRLSign bit if keyUsage present */ + if ((issuer->ex_flags & EXFLAG_KUSAGE) && + !(issuer->ex_kusage & KU_CRL_SIGN)) { + ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + + if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) { + ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + + if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) { + if (check_crl_path(ctx, + ctx->current_issuer) <= 0) { + ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + } + + if (crl->idp_flags & IDP_INVALID) { + ctx->error = X509_V_ERR_INVALID_EXTENSION; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + + + } + + if (!(ctx->current_crl_score & CRL_SCORE_TIME)) { + ok = check_crl_time(ctx, crl, 1); + if (!ok) + goto err; + } + + /* Attempt to get issuer certificate public key */ + ikey = X509_get_pubkey(issuer); + + if (!ikey) { + ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } else { + /* Verify CRL signature */ + if (X509_CRL_verify(crl, ikey) <= 0) { + ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + } + } + + ok = 1; + +err: + EVP_PKEY_free(ikey); + return ok; +} + +/* Check certificate against CRL */ +static int +cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) +{ + int ok; + X509_REVOKED *rev; + + /* The rules changed for this... previously if a CRL contained + * unhandled critical extensions it could still be used to indicate + * a certificate was revoked. This has since been changed since + * critical extension can change the meaning of CRL entries. + */ + if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) && + (crl->flags & EXFLAG_CRITICAL)) { + ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; + ok = ctx->verify_cb(0, ctx); + if (!ok) + return 0; + } + /* Look for serial number of certificate in CRL + * If found make sure reason is not removeFromCRL. + */ + if (X509_CRL_get0_by_cert(crl, &rev, x)) { + if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) + return 2; + ctx->error = X509_V_ERR_CERT_REVOKED; + ok = ctx->verify_cb(0, ctx); + if (!ok) + return 0; + } + + return 1; +} + +static int +check_policy(X509_STORE_CTX *ctx) +{ + int ret; + + if (ctx->parent) + return 1; + ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain, + ctx->param->policies, ctx->param->flags); + if (ret == 0) { + X509err(X509_F_CHECK_POLICY, ERR_R_MALLOC_FAILURE); + return 0; + } + /* Invalid or inconsistent extensions */ + if (ret == -1) { + /* Locate certificates with bad extensions and notify + * callback. + */ + X509 *x; + int i; + for (i = 1; i < sk_X509_num(ctx->chain); i++) { + x = sk_X509_value(ctx->chain, i); + if (!(x->ex_flags & EXFLAG_INVALID_POLICY)) + continue; + ctx->current_cert = x; + ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + return 1; + } + if (ret == -2) { + ctx->current_cert = NULL; + ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY; + return ctx->verify_cb(0, ctx); + } + + if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) { + ctx->current_cert = NULL; + ctx->error = X509_V_OK; + if (!ctx->verify_cb(2, ctx)) + return 0; + } + + return 1; +} + +int +x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int quiet) +{ + time_t *ptime = NULL; + int i; + + if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) + return (1); + + if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) + ptime = &ctx->param->check_time; + + i = X509_cmp_time(X509_get_notBefore(x), ptime); + if (i == 0) { + if (quiet) + return 0; + ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + if (i > 0) { + if (quiet) + return 0; + ctx->error = X509_V_ERR_CERT_NOT_YET_VALID; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + i = X509_cmp_time(X509_get_notAfter(x), ptime); + if (i == 0) { + if (quiet) + return 0; + ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + if (i < 0) { + if (quiet) + return 0; + ctx->error = X509_V_ERR_CERT_HAS_EXPIRED; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + return 1; +} + +static int +internal_verify(X509_STORE_CTX *ctx) +{ + int ok = 0, n; + X509 *xs, *xi; + EVP_PKEY *pkey = NULL; + int (*cb)(int xok, X509_STORE_CTX *xctx); + + cb = ctx->verify_cb; + + n = sk_X509_num(ctx->chain); + ctx->error_depth = n - 1; + n--; + xi = sk_X509_value(ctx->chain, n); + + if (ctx->check_issued(ctx, xi, xi)) + xs = xi; + else { + if (n <= 0) { + ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; + ctx->current_cert = xi; + ok = cb(0, ctx); + goto end; + } else { + n--; + ctx->error_depth = n; + xs = sk_X509_value(ctx->chain, n); + } + } + +/* ctx->error=0; not needed */ + while (n >= 0) { + ctx->error_depth = n; + + /* Skip signature check for self signed certificates unless + * explicitly asked for. It doesn't add any security and + * just wastes time. + */ + if (!xs->valid && (xs != xi || + (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE))) { + if ((pkey = X509_get_pubkey(xi)) == NULL) { + ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; + ctx->current_cert = xi; + ok = (*cb)(0, ctx); + if (!ok) + goto end; + } else if (X509_verify(xs, pkey) <= 0) { + ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE; + ctx->current_cert = xs; + ok = (*cb)(0, ctx); + if (!ok) { + EVP_PKEY_free(pkey); + goto end; + } + } + EVP_PKEY_free(pkey); + pkey = NULL; + } + + xs->valid = 1; + + ok = x509_check_cert_time(ctx, xs, 0); + if (!ok) + goto end; + + /* The last error (if any) is still in the error value */ + ctx->current_issuer = xi; + ctx->current_cert = xs; + ok = (*cb)(1, ctx); + if (!ok) + goto end; + + n--; + if (n >= 0) { + xi = xs; + xs = sk_X509_value(ctx->chain, n); + } + } + ok = 1; + +end: + return ok; +} + +int +X509_cmp_current_time(const ASN1_TIME *ctm) +{ + return X509_cmp_time(ctm, NULL); +} + +/* + * Compare a possibly unvalidated ASN1_TIME string against a time_t + * using RFC 5280 rules for the time string. If *cmp_time is NULL + * the current system time is used. + * + * XXX NOTE that unlike what you expect a "cmp" function to do in C, + * XXX this one is "special", and returns 0 for error. + * + * Returns: + * -1 if the ASN1_time is earlier than OR the same as *cmp_time. + * 1 if the ASN1_time is later than *cmp_time. + * 0 on error. + */ +int +X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) +{ + time_t time1, time2; + struct tm tm1, tm2; + int ret = 0; + int type; + + if (cmp_time == NULL) + time2 = time(NULL); + else + time2 = *cmp_time; + + memset(&tm1, 0, sizeof(tm1)); + + if ((type = asn1_time_parse(ctm->data, ctm->length, &tm1, 0)) == -1) + goto out; /* invalid time */ + + /* RFC 5280 section 4.1.2.5 */ + if (tm1.tm_year < 150 && type != V_ASN1_UTCTIME) + goto out; + if (tm1.tm_year >= 150 && type != V_ASN1_GENERALIZEDTIME) + goto out; + + /* + * Defensively fail if the time string is not representable as + * a time_t. A time_t must be sane if you care about times after + * Jan 19 2038. + */ + if ((time1 = timegm(&tm1)) == -1) + goto out; + + if (gmtime_r(&time2, &tm2) == NULL) + goto out; + + ret = asn1_tm_cmp(&tm1, &tm2); + if (ret == 0) + ret = -1; /* 0 is used for error, so map same to less than */ + out: + return (ret); +} + +ASN1_TIME * +X509_gmtime_adj(ASN1_TIME *s, long adj) +{ + return X509_time_adj(s, adj, NULL); +} + +ASN1_TIME * +X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_time) +{ + return X509_time_adj_ex(s, 0, offset_sec, in_time); +} + +ASN1_TIME * +X509_time_adj_ex(ASN1_TIME *s, int offset_day, long offset_sec, time_t *in_time) +{ + time_t t; + if (in_time == NULL) + t = time(NULL); + else + t = *in_time; + + return ASN1_TIME_adj(s, t, offset_day, offset_sec); +} + +int +X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain) +{ + EVP_PKEY *ktmp = NULL, *ktmp2; + int i, j; + + if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey)) + return 1; + + for (i = 0; i < sk_X509_num(chain); i++) { + ktmp = X509_get_pubkey(sk_X509_value(chain, i)); + if (ktmp == NULL) { + X509err(X509_F_X509_GET_PUBKEY_PARAMETERS, + X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY); + return 0; + } + if (!EVP_PKEY_missing_parameters(ktmp)) + break; + else { + EVP_PKEY_free(ktmp); + ktmp = NULL; + } + } + if (ktmp == NULL) { + X509err(X509_F_X509_GET_PUBKEY_PARAMETERS, + X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN); + return 0; + } + + /* first, populate the other certs */ + for (j = i - 1; j >= 0; j--) { + ktmp2 = X509_get_pubkey(sk_X509_value(chain, j)); + EVP_PKEY_copy_parameters(ktmp2, ktmp); + EVP_PKEY_free(ktmp2); + } + + if (pkey != NULL) + EVP_PKEY_copy_parameters(pkey, ktmp); + EVP_PKEY_free(ktmp); + return 1; +} + +int +X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + /* This function is (usually) called only once, by + * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). */ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, + argl, argp, new_func, dup_func, free_func); +} + +int +X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data) +{ + return CRYPTO_set_ex_data(&ctx->ex_data, idx, data); +} + +void * +X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx) +{ + return CRYPTO_get_ex_data(&ctx->ex_data, idx); +} + +int +X509_STORE_CTX_get_error(X509_STORE_CTX *ctx) +{ + return ctx->error; +} + +void +X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err) +{ + ctx->error = err; +} + +int +X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx) +{ + return ctx->error_depth; +} + +X509 * +X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx) +{ + return ctx->current_cert; +} + +STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx) +{ + return ctx->chain; +} + +STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx) +{ + int i; + X509 *x; + STACK_OF(X509) *chain; + + if (!ctx->chain || !(chain = sk_X509_dup(ctx->chain))) + return NULL; + for (i = 0; i < sk_X509_num(chain); i++) { + x = sk_X509_value(chain, i); + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + } + return chain; +} + +X509 * +X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx) +{ + return ctx->current_issuer; +} + +X509_CRL * +X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx) +{ + return ctx->current_crl; +} + +X509_STORE_CTX * +X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx) +{ + return ctx->parent; +} + +void +X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x) +{ + ctx->cert = x; +} + +void +X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) +{ + ctx->untrusted = sk; +} + +void +X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk) +{ + ctx->crls = sk; +} + +int +X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) +{ + return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0); +} + +int +X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) +{ + return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust); +} + +/* This function is used to set the X509_STORE_CTX purpose and trust + * values. This is intended to be used when another structure has its + * own trust and purpose values which (if set) will be inherited by + * the ctx. If they aren't set then we will usually have a default + * purpose in mind which should then be used to set the trust value. + * An example of this is SSL use: an SSL structure will have its own + * purpose and trust settings which the application can set: if they + * aren't set then we use the default of SSL client/server. + */ + +int +X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, + int purpose, int trust) +{ + int idx; + + /* If purpose not set use default */ + if (!purpose) + purpose = def_purpose; + /* If we have a purpose then check it is valid */ + if (purpose) { + X509_PURPOSE *ptmp; + idx = X509_PURPOSE_get_by_id(purpose); + if (idx == -1) { + X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, + X509_R_UNKNOWN_PURPOSE_ID); + return 0; + } + ptmp = X509_PURPOSE_get0(idx); + if (ptmp->trust == X509_TRUST_DEFAULT) { + idx = X509_PURPOSE_get_by_id(def_purpose); + if (idx == -1) { + X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, + X509_R_UNKNOWN_PURPOSE_ID); + return 0; + } + ptmp = X509_PURPOSE_get0(idx); + } + /* If trust not set then get from purpose default */ + if (!trust) + trust = ptmp->trust; + } + if (trust) { + idx = X509_TRUST_get_by_id(trust); + if (idx == -1) { + X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, + X509_R_UNKNOWN_TRUST_ID); + return 0; + } + } + + if (purpose && !ctx->param->purpose) + ctx->param->purpose = purpose; + if (trust && !ctx->param->trust) + ctx->param->trust = trust; + return 1; +} + +X509_STORE_CTX * +X509_STORE_CTX_new(void) +{ + X509_STORE_CTX *ctx; + + ctx = calloc(1, sizeof(X509_STORE_CTX)); + if (!ctx) { + X509err(X509_F_X509_STORE_CTX_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + return ctx; +} + +void +X509_STORE_CTX_free(X509_STORE_CTX *ctx) +{ + if (ctx == NULL) + return; + + X509_STORE_CTX_cleanup(ctx); + free(ctx); +} + +int +X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, + STACK_OF(X509) *chain) +{ + int param_ret = 1; + + /* + * Make sure everything is initialized properly even in case of an + * early return due to an error. + * + * While this 'ctx' can be reused, X509_STORE_CTX_cleanup() will have + * freed everything and memset ex_data anyway. This also allows us + * to safely use X509_STORE_CTX variables from the stack which will + * have uninitialized data. + */ + memset(ctx, 0, sizeof(*ctx)); + + /* + * Set values other than 0. Keep this in the same order as + * X509_STORE_CTX except for values that may fail. All fields that + * may fail should go last to make sure 'ctx' is as consistent as + * possible even on early exits. + */ + ctx->ctx = store; + ctx->cert = x509; + ctx->untrusted = chain; + + if (store && store->verify) + ctx->verify = store->verify; + else + ctx->verify = internal_verify; + + if (store && store->verify_cb) + ctx->verify_cb = store->verify_cb; + else + ctx->verify_cb = null_callback; + + if (store && store->get_issuer) + ctx->get_issuer = store->get_issuer; + else + ctx->get_issuer = X509_STORE_CTX_get1_issuer; + + if (store && store->check_issued) + ctx->check_issued = store->check_issued; + else + ctx->check_issued = check_issued; + + if (store && store->check_revocation) + ctx->check_revocation = store->check_revocation; + else + ctx->check_revocation = check_revocation; + + if (store && store->get_crl) + ctx->get_crl = store->get_crl; + else + ctx->get_crl = NULL; + + if (store && store->check_crl) + ctx->check_crl = store->check_crl; + else + ctx->check_crl = check_crl; + + if (store && store->cert_crl) + ctx->cert_crl = store->cert_crl; + else + ctx->cert_crl = cert_crl; + + ctx->check_policy = check_policy; + + if (store && store->lookup_certs) + ctx->lookup_certs = store->lookup_certs; + else + ctx->lookup_certs = X509_STORE_get1_certs; + + if (store && store->lookup_crls) + ctx->lookup_crls = store->lookup_crls; + else + ctx->lookup_crls = X509_STORE_get1_crls; + + if (store && store->cleanup) + ctx->cleanup = store->cleanup; + else + ctx->cleanup = NULL; + + ctx->param = X509_VERIFY_PARAM_new(); + if (!ctx->param) { + X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE); + return 0; + } + + /* Inherit callbacks and flags from X509_STORE if not set + * use defaults. + */ + if (store) + param_ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param); + else + ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT|X509_VP_FLAG_ONCE; + + if (param_ret) + param_ret = X509_VERIFY_PARAM_inherit(ctx->param, + X509_VERIFY_PARAM_lookup("default")); + + if (param_ret == 0) { + X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, + &(ctx->ex_data)) == 0) { + X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +/* Set alternative lookup method: just a STACK of trusted certificates. + * This avoids X509_STORE nastiness where it isn't needed. + */ + +void +X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) +{ + ctx->other_ctx = sk; + ctx->get_issuer = get_issuer_sk; +} + +void +X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) +{ + if (ctx->cleanup) + ctx->cleanup(ctx); + if (ctx->param != NULL) { + if (ctx->parent == NULL) + X509_VERIFY_PARAM_free(ctx->param); + ctx->param = NULL; + } + if (ctx->tree != NULL) { + X509_policy_tree_free(ctx->tree); + ctx->tree = NULL; + } + if (ctx->chain != NULL) { + sk_X509_pop_free(ctx->chain, X509_free); + ctx->chain = NULL; + } + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, + ctx, &(ctx->ex_data)); + memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA)); +} + +void +X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth) +{ + X509_VERIFY_PARAM_set_depth(ctx->param, depth); +} + +void +X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags) +{ + X509_VERIFY_PARAM_set_flags(ctx->param, flags); +} + +void +X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, time_t t) +{ + X509_VERIFY_PARAM_set_time(ctx->param, t); +} + +void +X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + int (*verify_cb)(int, X509_STORE_CTX *)) +{ + ctx->verify_cb = verify_cb; +} + +X509_POLICY_TREE * +X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx) +{ + return ctx->tree; +} + +int +X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx) +{ + return ctx->explicit_policy; +} + +int +X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name) +{ + const X509_VERIFY_PARAM *param; + param = X509_VERIFY_PARAM_lookup(name); + if (!param) + return 0; + return X509_VERIFY_PARAM_inherit(ctx->param, param); +} + +X509_VERIFY_PARAM * +X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx) +{ + return ctx->param; +} + +void +X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param) +{ + if (ctx->param) + X509_VERIFY_PARAM_free(ctx->param); + ctx->param = param; +} diff --git a/crypto/libressl/crypto/x509/x509_vpm.c b/crypto/libressl/crypto/x509/x509_vpm.c new file mode 100644 index 0000000000..f205cb6676 --- /dev/null +++ b/crypto/libressl/crypto/x509/x509_vpm.c @@ -0,0 +1,449 @@ +/* $OpenBSD: x509_vpm.c,v 1.10 2014/07/22 02:21:20 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +/* X509_VERIFY_PARAM functions */ + +static void +x509_verify_param_zero(X509_VERIFY_PARAM *param) +{ + if (!param) + return; + param->name = NULL; + param->purpose = 0; + param->trust = 0; + /*param->inh_flags = X509_VP_FLAG_DEFAULT;*/ + param->inh_flags = 0; + param->flags = 0; + param->depth = -1; + if (param->policies) { + sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); + param->policies = NULL; + } +} + +X509_VERIFY_PARAM * +X509_VERIFY_PARAM_new(void) +{ + X509_VERIFY_PARAM *param; + + param = calloc(1, sizeof(X509_VERIFY_PARAM)); + x509_verify_param_zero(param); + return param; +} + +void +X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) +{ + x509_verify_param_zero(param); + free(param); +} + +/* This function determines how parameters are "inherited" from one structure + * to another. There are several different ways this can happen. + * + * 1. If a child structure needs to have its values initialized from a parent + * they are simply copied across. For example SSL_CTX copied to SSL. + * 2. If the structure should take on values only if they are currently unset. + * For example the values in an SSL structure will take appropriate value + * for SSL servers or clients but only if the application has not set new + * ones. + * + * The "inh_flags" field determines how this function behaves. + * + * Normally any values which are set in the default are not copied from the + * destination and verify flags are ORed together. + * + * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied + * to the destination. Effectively the values in "to" become default values + * which will be used only if nothing new is set in "from". + * + * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether + * they are set or not. Flags is still Ored though. + * + * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead + * of ORed. + * + * If X509_VP_FLAG_LOCKED is set then no values are copied. + * + * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed + * after the next call. + */ + +/* Macro to test if a field should be copied from src to dest */ + +#define test_x509_verify_param_copy(field, def) \ + (to_overwrite || \ + ((src->field != def) && (to_default || (dest->field == def)))) + +/* Macro to test and copy a field if necessary */ + +#define x509_verify_param_copy(field, def) \ + if (test_x509_verify_param_copy(field, def)) \ + dest->field = src->field + + +int +X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, const X509_VERIFY_PARAM *src) +{ + unsigned long inh_flags; + int to_default, to_overwrite; + + if (!src) + return 1; + inh_flags = dest->inh_flags | src->inh_flags; + + if (inh_flags & X509_VP_FLAG_ONCE) + dest->inh_flags = 0; + + if (inh_flags & X509_VP_FLAG_LOCKED) + return 1; + + if (inh_flags & X509_VP_FLAG_DEFAULT) + to_default = 1; + else + to_default = 0; + + if (inh_flags & X509_VP_FLAG_OVERWRITE) + to_overwrite = 1; + else + to_overwrite = 0; + + x509_verify_param_copy(purpose, 0); + x509_verify_param_copy(trust, 0); + x509_verify_param_copy(depth, -1); + + /* If overwrite or check time not set, copy across */ + + if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) { + dest->check_time = src->check_time; + dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME; + /* Don't need to copy flag: that is done below */ + } + + if (inh_flags & X509_VP_FLAG_RESET_FLAGS) + dest->flags = 0; + + dest->flags |= src->flags; + + if (test_x509_verify_param_copy(policies, NULL)) { + if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies)) + return 0; + } + + return 1; +} + +int +X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, const X509_VERIFY_PARAM *from) +{ + unsigned long save_flags = to->inh_flags; + int ret; + + to->inh_flags |= X509_VP_FLAG_DEFAULT; + ret = X509_VERIFY_PARAM_inherit(to, from); + to->inh_flags = save_flags; + return ret; +} + +int +X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) +{ + free(param->name); + param->name = NULL; + if (name == NULL) + return 1; + param->name = strdup(name); + if (param->name) + return 1; + return 0; +} + +int +X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags) +{ + param->flags |= flags; + if (flags & X509_V_FLAG_POLICY_MASK) + param->flags |= X509_V_FLAG_POLICY_CHECK; + return 1; +} + +int +X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, unsigned long flags) +{ + param->flags &= ~flags; + return 1; +} + +unsigned long +X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param) +{ + return param->flags; +} + +int +X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose) +{ + return X509_PURPOSE_set(¶m->purpose, purpose); +} + +int +X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust) +{ + return X509_TRUST_set(¶m->trust, trust); +} + +void +X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth) +{ + param->depth = depth; +} + +void +X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t) +{ + param->check_time = t; + param->flags |= X509_V_FLAG_USE_CHECK_TIME; +} + +int +X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy) +{ + if (!param->policies) { + param->policies = sk_ASN1_OBJECT_new_null(); + if (!param->policies) + return 0; + } + if (!sk_ASN1_OBJECT_push(param->policies, policy)) + return 0; + return 1; +} + +int +X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, + STACK_OF(ASN1_OBJECT) *policies) +{ + int i; + ASN1_OBJECT *oid, *doid; + + if (!param) + return 0; + if (param->policies) + sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); + + if (!policies) { + param->policies = NULL; + return 1; + } + + param->policies = sk_ASN1_OBJECT_new_null(); + if (!param->policies) + return 0; + + for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) { + oid = sk_ASN1_OBJECT_value(policies, i); + doid = OBJ_dup(oid); + if (!doid) + return 0; + if (!sk_ASN1_OBJECT_push(param->policies, doid)) { + ASN1_OBJECT_free(doid); + return 0; + } + } + param->flags |= X509_V_FLAG_POLICY_CHECK; + return 1; +} + +int +X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param) +{ + return param->depth; +} + +/* Default verify parameters: these are used for various + * applications and can be overridden by the user specified table. + * NB: the 'name' field *must* be in alphabetical order because it + * will be searched using OBJ_search. + */ + +static const X509_VERIFY_PARAM default_table[] = { + { + "default", /* X509 default parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + 0, /* purpose */ + 0, /* trust */ + 100, /* depth */ + NULL /* policies */ + }, + { + "pkcs7", /* S/MIME sign parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + X509_PURPOSE_SMIME_SIGN, /* purpose */ + X509_TRUST_EMAIL, /* trust */ + -1, /* depth */ + NULL /* policies */ + }, + { + "smime_sign", /* S/MIME sign parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + X509_PURPOSE_SMIME_SIGN, /* purpose */ + X509_TRUST_EMAIL, /* trust */ + -1, /* depth */ + NULL /* policies */ + }, + { + "ssl_client", /* SSL/TLS client parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + X509_PURPOSE_SSL_CLIENT, /* purpose */ + X509_TRUST_SSL_CLIENT, /* trust */ + -1, /* depth */ + NULL /* policies */ + }, + { + "ssl_server", /* SSL/TLS server parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + X509_PURPOSE_SSL_SERVER, /* purpose */ + X509_TRUST_SSL_SERVER, /* trust */ + -1, /* depth */ + NULL /* policies */ + } +}; + +static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; + +static int +table_cmp(const X509_VERIFY_PARAM *a, const X509_VERIFY_PARAM *b) +{ + return strcmp(a->name, b->name); +} + +DECLARE_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table); +IMPLEMENT_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table); + +static int +param_cmp(const X509_VERIFY_PARAM * const *a, + const X509_VERIFY_PARAM * const *b) +{ + return strcmp((*a)->name, (*b)->name); +} + +int +X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) +{ + int idx; + X509_VERIFY_PARAM *ptmp; + + if (!param_table) { + param_table = sk_X509_VERIFY_PARAM_new(param_cmp); + if (!param_table) + return 0; + } else { + idx = sk_X509_VERIFY_PARAM_find(param_table, param); + if (idx != -1) { + ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx); + X509_VERIFY_PARAM_free(ptmp); + (void)sk_X509_VERIFY_PARAM_delete(param_table, idx); + } + } + if (!sk_X509_VERIFY_PARAM_push(param_table, param)) + return 0; + return 1; +} + +const X509_VERIFY_PARAM * +X509_VERIFY_PARAM_lookup(const char *name) +{ + int idx; + X509_VERIFY_PARAM pm; + + pm.name = (char *)name; + if (param_table) { + idx = sk_X509_VERIFY_PARAM_find(param_table, &pm); + if (idx != -1) + return sk_X509_VERIFY_PARAM_value(param_table, idx); + } + return OBJ_bsearch_table(&pm, default_table, + sizeof(default_table)/sizeof(X509_VERIFY_PARAM)); +} + +void +X509_VERIFY_PARAM_table_cleanup(void) +{ + if (param_table) + sk_X509_VERIFY_PARAM_pop_free(param_table, + X509_VERIFY_PARAM_free); + param_table = NULL; +} diff --git a/crypto/libressl/crypto/x509/x509cset.c b/crypto/libressl/crypto/x509/x509cset.c new file mode 100644 index 0000000000..5fa84e599a --- /dev/null +++ b/crypto/libressl/crypto/x509/x509cset.c @@ -0,0 +1,173 @@ +/* $OpenBSD: x509cset.c,v 1.10 2015/09/30 17:30:16 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include + +int +X509_CRL_set_version(X509_CRL *x, long version) +{ + if (x == NULL) + return (0); + if (x->crl->version == NULL) { + if ((x->crl->version = ASN1_INTEGER_new()) == NULL) + return (0); + } + return (ASN1_INTEGER_set(x->crl->version, version)); +} + +int +X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) +{ + if ((x == NULL) || (x->crl == NULL)) + return (0); + return (X509_NAME_set(&x->crl->issuer, name)); +} + +int +X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if (x == NULL) + return (0); + in = x->crl->lastUpdate; + if (in != tm) { + in = ASN1_STRING_dup(tm); + if (in != NULL) { + ASN1_TIME_free(x->crl->lastUpdate); + x->crl->lastUpdate = in; + } + } + return (in != NULL); +} + +int +X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if (x == NULL) + return (0); + in = x->crl->nextUpdate; + if (in != tm) { + in = ASN1_STRING_dup(tm); + if (in != NULL) { + ASN1_TIME_free(x->crl->nextUpdate); + x->crl->nextUpdate = in; + } + } + return (in != NULL); +} + +int +X509_CRL_sort(X509_CRL *c) +{ + int i; + X509_REVOKED *r; + + /* sort the data so it will be written in serial + * number order */ + sk_X509_REVOKED_sort(c->crl->revoked); + for (i = 0; i < sk_X509_REVOKED_num(c->crl->revoked); i++) { + r = sk_X509_REVOKED_value(c->crl->revoked, i); + r->sequence = i; + } + c->crl->enc.modified = 1; + return 1; +} + +int +X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if (x == NULL) + return (0); + in = x->revocationDate; + if (in != tm) { + in = ASN1_STRING_dup(tm); + if (in != NULL) { + ASN1_TIME_free(x->revocationDate); + x->revocationDate = in; + } + } + return (in != NULL); +} + +int +X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial) +{ + ASN1_INTEGER *in; + + if (x == NULL) + return (0); + in = x->serialNumber; + if (in != serial) { + in = ASN1_INTEGER_dup(serial); + if (in != NULL) { + ASN1_INTEGER_free(x->serialNumber); + x->serialNumber = in; + } + } + return (in != NULL); +} diff --git a/crypto/libressl/crypto/x509/x509name.c b/crypto/libressl/crypto/x509/x509name.c new file mode 100644 index 0000000000..2cd044b232 --- /dev/null +++ b/crypto/libressl/crypto/x509/x509name.c @@ -0,0 +1,410 @@ +/* $OpenBSD: x509name.c,v 1.12 2014/07/11 08:44:49 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +int +X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len) +{ + ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) + return (-1); + return (X509_NAME_get_text_by_OBJ(name, obj, buf, len)); +} + +int +X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, char *buf, + int len) +{ + int i; + ASN1_STRING *data; + + i = X509_NAME_get_index_by_OBJ(name, obj, -1); + if (i < 0) + return (-1); + data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i)); + i = (data->length > (len - 1)) ? (len - 1) : data->length; + if (buf == NULL) + return (data->length); + if (i >= 0) { + memcpy(buf, data->data, i); + buf[i] = '\0'; + } + return (i); +} + +int +X509_NAME_entry_count(X509_NAME *name) +{ + if (name == NULL) + return (0); + return (sk_X509_NAME_ENTRY_num(name->entries)); +} + +int +X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos) +{ + ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) + return (-2); + return (X509_NAME_get_index_by_OBJ(name, obj, lastpos)); +} + +/* NOTE: you should be passsing -1, not 0 as lastpos */ +int +X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int lastpos) +{ + int n; + X509_NAME_ENTRY *ne; + STACK_OF(X509_NAME_ENTRY) *sk; + + if (name == NULL) + return (-1); + if (lastpos < 0) + lastpos = -1; + sk = name->entries; + n = sk_X509_NAME_ENTRY_num(sk); + for (lastpos++; lastpos < n; lastpos++) { + ne = sk_X509_NAME_ENTRY_value(sk, lastpos); + if (OBJ_cmp(ne->object, obj) == 0) + return (lastpos); + } + return (-1); +} + +X509_NAME_ENTRY * +X509_NAME_get_entry(X509_NAME *name, int loc) +{ + if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc || + loc < 0) + return (NULL); + else + return (sk_X509_NAME_ENTRY_value(name->entries, loc)); +} + +X509_NAME_ENTRY * +X509_NAME_delete_entry(X509_NAME *name, int loc) +{ + X509_NAME_ENTRY *ret; + int i, n, set_prev, set_next; + STACK_OF(X509_NAME_ENTRY) *sk; + + if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc || + loc < 0) + return (NULL); + sk = name->entries; + ret = sk_X509_NAME_ENTRY_delete(sk, loc); + n = sk_X509_NAME_ENTRY_num(sk); + name->modified = 1; + if (loc == n) + return (ret); + + /* else we need to fixup the set field */ + if (loc != 0) + set_prev = (sk_X509_NAME_ENTRY_value(sk, loc - 1))->set; + else + set_prev = ret->set - 1; + set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set; + + /* set_prev is the previous set + * set is the current set + * set_next is the following + * prev 1 1 1 1 1 1 1 1 + * set 1 1 2 2 + * next 1 1 2 2 2 2 3 2 + * so basically only if prev and next differ by 2, then + * re-number down by 1 */ + if (set_prev + 1 < set_next) + for (i = loc; i < n; i++) + sk_X509_NAME_ENTRY_value(sk, i)->set--; + return (ret); +} + +int +X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, + unsigned char *bytes, int len, int loc, int set) +{ + X509_NAME_ENTRY *ne; + int ret; + + ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len); + if (!ne) + return 0; + ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; +} + +int +X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, + unsigned char *bytes, int len, int loc, int set) +{ + X509_NAME_ENTRY *ne; + int ret; + + ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len); + if (!ne) + return 0; + ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; +} + +int +X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, + const unsigned char *bytes, int len, int loc, int set) +{ + X509_NAME_ENTRY *ne; + int ret; + + ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len); + if (!ne) + return 0; + ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; +} + +/* if set is -1, append to previous set, 0 'a new one', and 1, + * prepend to the guy we are about to stomp on. */ +int +X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc, int set) +{ + X509_NAME_ENTRY *new_name = NULL; + int n, i, inc; + STACK_OF(X509_NAME_ENTRY) *sk; + + if (name == NULL) + return (0); + sk = name->entries; + n = sk_X509_NAME_ENTRY_num(sk); + if (loc > n) + loc = n; + else if (loc < 0) + loc = n; + + name->modified = 1; + + if (set == -1) { + if (loc == 0) { + set = 0; + inc = 1; + } else { + set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set; + inc = 0; + } + } else /* if (set >= 0) */ { + if (loc >= n) { + if (loc != 0) + set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1; + else + set = 0; + } else + set = sk_X509_NAME_ENTRY_value(sk, loc)->set; + inc = (set == 0) ? 1 : 0; + } + + if ((new_name = X509_NAME_ENTRY_dup(ne)) == NULL) + goto err; + new_name->set = set; + if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) { + X509err(X509_F_X509_NAME_ADD_ENTRY, ERR_R_MALLOC_FAILURE); + goto err; + } + if (inc) { + n = sk_X509_NAME_ENTRY_num(sk); + for (i = loc + 1; i < n; i++) + sk_X509_NAME_ENTRY_value(sk, i - 1)->set += 1; + } + return (1); + +err: + if (new_name != NULL) + X509_NAME_ENTRY_free(new_name); + return (0); +} + +X509_NAME_ENTRY * +X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, + const char *field, int type, const unsigned char *bytes, int len) +{ + ASN1_OBJECT *obj; + X509_NAME_ENTRY *nentry; + + obj = OBJ_txt2obj(field, 0); + if (obj == NULL) { + X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT, + X509_R_INVALID_FIELD_NAME); + ERR_asprintf_error_data("name=%s", field); + return (NULL); + } + nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); + ASN1_OBJECT_free(obj); + return nentry; +} + +X509_NAME_ENTRY * +X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, int type, + unsigned char *bytes, int len) +{ + ASN1_OBJECT *obj; + X509_NAME_ENTRY *nentry; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_NID, + X509_R_UNKNOWN_NID); + return (NULL); + } + nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); + ASN1_OBJECT_free(obj); + return nentry; +} + +X509_NAME_ENTRY * +X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len) +{ + X509_NAME_ENTRY *ret; + + if ((ne == NULL) || (*ne == NULL)) { + if ((ret = X509_NAME_ENTRY_new()) == NULL) + return (NULL); + } else + ret= *ne; + + if (!X509_NAME_ENTRY_set_object(ret, obj)) + goto err; + if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len)) + goto err; + + if ((ne != NULL) && (*ne == NULL)) + *ne = ret; + return (ret); + +err: + if ((ne == NULL) || (ret != *ne)) + X509_NAME_ENTRY_free(ret); + return (NULL); +} + +int +X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj) +{ + if ((ne == NULL) || (obj == NULL)) { + X509err(X509_F_X509_NAME_ENTRY_SET_OBJECT, + ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + ASN1_OBJECT_free(ne->object); + ne->object = OBJ_dup(obj); + return ((ne->object == NULL) ? 0 : 1); +} + +int +X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, + const unsigned char *bytes, int len) +{ + int i; + + if ((ne == NULL) || ((bytes == NULL) && (len != 0))) + return (0); + if ((type > 0) && (type & MBSTRING_FLAG)) + return ASN1_STRING_set_by_NID(&ne->value, bytes, len, type, + OBJ_obj2nid(ne->object)) ? 1 : 0; + if (len < 0) + len = strlen((const char *)bytes); + i = ASN1_STRING_set(ne->value, bytes, len); + if (!i) + return (0); + if (type != V_ASN1_UNDEF) { + if (type == V_ASN1_APP_CHOOSE) + ne->value->type = ASN1_PRINTABLE_type(bytes, len); + else + ne->value->type = type; + } + return (1); +} + +ASN1_OBJECT * +X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne) +{ + if (ne == NULL) + return (NULL); + return (ne->object); +} + +ASN1_STRING * +X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne) +{ + if (ne == NULL) + return (NULL); + return (ne->value); +} diff --git a/crypto/libressl/crypto/x509/x509rset.c b/crypto/libressl/crypto/x509/x509rset.c new file mode 100644 index 0000000000..94b028b20c --- /dev/null +++ b/crypto/libressl/crypto/x509/x509rset.c @@ -0,0 +1,88 @@ +/* $OpenBSD: x509rset.c,v 1.5 2014/06/12 15:49:31 deraadt Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include +#include + +int +X509_REQ_set_version(X509_REQ *x, long version) +{ + if (x == NULL) + return (0); + return (ASN1_INTEGER_set(x->req_info->version, version)); +} + +int +X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name) +{ + if ((x == NULL) || (x->req_info == NULL)) + return (0); + return (X509_NAME_set(&x->req_info->subject, name)); +} + +int +X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey) +{ + if ((x == NULL) || (x->req_info == NULL)) + return (0); + return (X509_PUBKEY_set(&x->req_info->pubkey, pkey)); +} diff --git a/crypto/libressl/crypto/x509/x509spki.c b/crypto/libressl/crypto/x509/x509spki.c new file mode 100644 index 0000000000..1e69945dec --- /dev/null +++ b/crypto/libressl/crypto/x509/x509spki.c @@ -0,0 +1,132 @@ +/* $OpenBSD: x509spki.c,v 1.11 2014/07/10 13:58:23 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include + +int +NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey) +{ + if ((x == NULL) || (x->spkac == NULL)) + return (0); + return (X509_PUBKEY_set(&(x->spkac->pubkey), pkey)); +} + +EVP_PKEY * +NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x) +{ + if ((x == NULL) || (x->spkac == NULL)) + return (NULL); + return (X509_PUBKEY_get(x->spkac->pubkey)); +} + +/* Load a Netscape SPKI from a base64 encoded string */ + +NETSCAPE_SPKI * +NETSCAPE_SPKI_b64_decode(const char *str, int len) +{ + unsigned char *spki_der; + const unsigned char *p; + int spki_len; + NETSCAPE_SPKI *spki; + + if (len <= 0) + len = strlen(str); + if (!(spki_der = malloc(len + 1))) { + X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, ERR_R_MALLOC_FAILURE); + return NULL; + } + spki_len = EVP_DecodeBlock(spki_der, (const unsigned char *)str, len); + if (spki_len < 0) { + X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, + X509_R_BASE64_DECODE_ERROR); + free(spki_der); + return NULL; + } + p = spki_der; + spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len); + free(spki_der); + return spki; +} + +/* Generate a base64 encoded string from an SPKI */ + +char * +NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki) +{ + unsigned char *der_spki, *p; + char *b64_str; + int der_len; + der_len = i2d_NETSCAPE_SPKI(spki, NULL); + der_spki = malloc(der_len); + b64_str = reallocarray(NULL, der_len, 2); + if (!der_spki || !b64_str) { + X509err(X509_F_NETSCAPE_SPKI_B64_ENCODE, ERR_R_MALLOC_FAILURE); + free(der_spki); + free(b64_str); + return NULL; + } + p = der_spki; + i2d_NETSCAPE_SPKI(spki, &p); + EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len); + free(der_spki); + return b64_str; +} diff --git a/crypto/libressl/crypto/x509/x509type.c b/crypto/libressl/crypto/x509/x509type.c new file mode 100644 index 0000000000..f5c2ea6663 --- /dev/null +++ b/crypto/libressl/crypto/x509/x509type.c @@ -0,0 +1,130 @@ +/* $OpenBSD: x509type.c,v 1.11 2014/07/11 08:44:49 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include +#include + +int +X509_certificate_type(X509 *x, EVP_PKEY *pkey) +{ + EVP_PKEY *pk; + int ret = 0, i; + + if (x == NULL) + return (0); + + if (pkey == NULL) + pk = X509_get_pubkey(x); + else + pk = pkey; + + if (pk == NULL) + return (0); + + switch (pk->type) { + case EVP_PKEY_RSA: + ret = EVP_PK_RSA|EVP_PKT_SIGN; +/* if (!sign only extension) */ + ret |= EVP_PKT_ENC; + break; + case EVP_PKEY_DSA: + ret = EVP_PK_DSA|EVP_PKT_SIGN; + break; + case EVP_PKEY_EC: + ret = EVP_PK_EC|EVP_PKT_SIGN|EVP_PKT_EXCH; + break; + case EVP_PKEY_DH: + ret = EVP_PK_DH|EVP_PKT_EXCH; + break; + case NID_id_GostR3410_94: + case NID_id_GostR3410_2001: + ret = EVP_PKT_EXCH|EVP_PKT_SIGN; + break; + default: + break; + } + + i = OBJ_obj2nid(x->sig_alg->algorithm); + if (i && OBJ_find_sigid_algs(i, NULL, &i)) { + switch (i) { + case NID_rsaEncryption: + case NID_rsa: + ret |= EVP_PKS_RSA; + break; + case NID_dsa: + case NID_dsa_2: + ret |= EVP_PKS_DSA; + break; + case NID_X9_62_id_ecPublicKey: + ret |= EVP_PKS_EC; + break; + default: + break; + } + } + + /* /8 because it's 1024 bits we look for, not bytes */ + if (EVP_PKEY_size(pk) <= 1024 / 8) + ret |= EVP_PKT_EXP; + if (pkey == NULL) + EVP_PKEY_free(pk); + return (ret); +} diff --git a/crypto/libressl/crypto/x509/x_all.c b/crypto/libressl/crypto/x509/x_all.c new file mode 100644 index 0000000000..3bda2a73f1 --- /dev/null +++ b/crypto/libressl/crypto/x509/x_all.c @@ -0,0 +1,602 @@ +/* $OpenBSD: x_all.c,v 1.20 2015/09/13 15:59:30 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include + +#include +#include +#include +#include +#include + +#ifndef OPENSSL_NO_DSA +#include +#endif +#ifndef OPENSSL_NO_RSA +#include +#endif + +X509 * +d2i_X509_bio(BIO *bp, X509 **x509) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509), bp, x509); +} + +int +i2d_X509_bio(BIO *bp, X509 *x509) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509); +} + +X509 * +d2i_X509_fp(FILE *fp, X509 **x509) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509); +} + +int +i2d_X509_fp(FILE *fp, X509 *x509) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509), fp, x509); +} + +X509_CRL * +d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); +} + +int +i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); +} + +X509_CRL * +d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); +} + +int +i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); +} + +PKCS7 * +d2i_PKCS7_bio(BIO *bp, PKCS7 **p7) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bp, p7); +} + +int +i2d_PKCS7_bio(BIO *bp, PKCS7 *p7) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS7), bp, p7); +} + +PKCS7 * +d2i_PKCS7_fp(FILE *fp, PKCS7 **p7) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7); +} + +int +i2d_PKCS7_fp(FILE *fp, PKCS7 *p7) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS7), fp, p7); +} + +X509_REQ * +d2i_X509_REQ_bio(BIO *bp, X509_REQ **req) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req); +} + +int +i2d_X509_REQ_bio(BIO *bp, X509_REQ *req) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req); +} + +X509_REQ * +d2i_X509_REQ_fp(FILE *fp, X509_REQ **req) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req); +} + +int +i2d_X509_REQ_fp(FILE *fp, X509_REQ *req) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req); +} + +#ifndef OPENSSL_NO_RSA +RSA * +d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa); +} + +int +i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa); +} + +RSA * +d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa); +} + +int +i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa); +} + +RSA * +d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa); +} + +int +i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa); +} + +RSA * +d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa); +} + +int +i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa); +} + +RSA * +d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa) +{ + return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSA_PUBKEY, bp, rsa); +} + +int +i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa) +{ + return ASN1_i2d_bio_of(RSA, i2d_RSA_PUBKEY, bp, rsa); +} + +int +i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa) +{ + return ASN1_i2d_fp((I2D_OF(void))i2d_RSA_PUBKEY, fp, rsa); +} + +RSA * +d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa) +{ + return ASN1_d2i_fp((void *(*)(void))RSA_new, + (D2I_OF(void))d2i_RSA_PUBKEY, fp, (void **)rsa); +} +#endif + +#ifndef OPENSSL_NO_DSA +DSA * +d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(DSAPrivateKey), bp, dsa); +} + +int +i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(DSAPrivateKey), bp, dsa); +} + +DSA * +d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(DSAPrivateKey), fp, dsa); +} + +int +i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(DSAPrivateKey), fp, dsa); +} + +DSA * +d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa) +{ + return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSA_PUBKEY, bp, dsa); +} + +int +i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa) +{ + return ASN1_i2d_bio_of(DSA, i2d_DSA_PUBKEY, bp, dsa); +} + +DSA * +d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa) +{ + return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSA_PUBKEY, fp, dsa); +} + +int +i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa) +{ + return ASN1_i2d_fp_of(DSA, i2d_DSA_PUBKEY, fp, dsa); +} +#endif + +#ifndef OPENSSL_NO_EC +EC_KEY * +d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey) +{ + return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, bp, eckey); +} + +int +i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey) +{ + return ASN1_i2d_bio_of(EC_KEY, i2d_ECPrivateKey, bp, eckey); +} + +EC_KEY * +d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey) +{ + return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, fp, eckey); +} + +int +i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey) +{ + return ASN1_i2d_fp_of(EC_KEY, i2d_ECPrivateKey, fp, eckey); +} + +EC_KEY * +d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey) +{ + return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, bp, eckey); +} + +int +i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *ecdsa) +{ + return ASN1_i2d_bio_of(EC_KEY, i2d_EC_PUBKEY, bp, ecdsa); +} +EC_KEY * +d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey) +{ + return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, fp, eckey); +} + +int +i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey) +{ + return ASN1_i2d_fp_of(EC_KEY, i2d_EC_PUBKEY, fp, eckey); +} +#endif + +X509_SIG * +d2i_PKCS8_bio(BIO *bp, X509_SIG **p8) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_SIG), bp, p8); +} + +int +i2d_PKCS8_bio(BIO *bp, X509_SIG *p8) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_SIG), bp, p8); +} + +X509_SIG * +d2i_PKCS8_fp(FILE *fp, X509_SIG **p8) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_SIG), fp, p8); +} + +int +i2d_PKCS8_fp(FILE *fp, X509_SIG *p8) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_SIG), fp, p8); +} + +PKCS8_PRIV_KEY_INFO * +d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO **p8inf) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), bp, + p8inf); +} + +int +i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), bp, + p8inf); +} + +PKCS8_PRIV_KEY_INFO * +d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO **p8inf) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), fp, + p8inf); +} + +int +i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), fp, + p8inf); +} + +EVP_PKEY * +d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a) +{ + return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, + bp, a); +} + +int +i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey) +{ + return ASN1_i2d_bio_of(EVP_PKEY, i2d_PrivateKey, bp, pkey); +} + +EVP_PKEY * +d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a) +{ + return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, + fp, a); +} + +int +i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey) +{ + return ASN1_i2d_fp_of(EVP_PKEY, i2d_PrivateKey, fp, pkey); +} + +EVP_PKEY * +d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a) +{ + return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, bp, a); +} + +int +i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey) +{ + return ASN1_i2d_bio_of(EVP_PKEY, i2d_PUBKEY, bp, pkey); +} + +int +i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey) +{ + return ASN1_i2d_fp_of(EVP_PKEY, i2d_PUBKEY, fp, pkey); +} + +EVP_PKEY * +d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a) +{ + return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, fp, a); +} + +int +i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key) +{ + PKCS8_PRIV_KEY_INFO *p8inf; + int ret; + + p8inf = EVP_PKEY2PKCS8(key); + if (!p8inf) + return 0; + ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return ret; +} + +int +i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key) +{ + PKCS8_PRIV_KEY_INFO *p8inf; + int ret; + p8inf = EVP_PKEY2PKCS8(key); + if (!p8inf) + return 0; + ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return ret; +} + +int +X509_verify(X509 *a, EVP_PKEY *r) +{ + if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature)) + return 0; + return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), a->sig_alg, + a->signature, a->cert_info, r)); +} + +int +X509_REQ_verify(X509_REQ *a, EVP_PKEY *r) +{ + return (ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO), + a->sig_alg, a->signature, a->req_info, r)); +} + +int +NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r) +{ + return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), + a->sig_algor, a->signature, a->spkac, r)); +} + +int +X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + x->cert_info->enc.modified = 1; + return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), + x->cert_info->signature, x->sig_alg, x->signature, + x->cert_info, pkey, md)); +} + +int +X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) +{ + x->cert_info->enc.modified = 1; + return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF), + x->cert_info->signature, x->sig_alg, x->signature, + x->cert_info, ctx); +} + +int +X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + return (ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), + x->sig_alg, NULL, x->signature, x->req_info, pkey, md)); +} + +int +X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx) +{ + return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO), + x->sig_alg, NULL, x->signature, x->req_info, ctx); +} + +int +X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + x->crl->enc.modified = 1; + return(ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg, + x->sig_alg, x->signature, x->crl, pkey, md)); +} + +int +X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) +{ + x->crl->enc.modified = 1; + return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO), + x->crl->sig_alg, x->sig_alg, x->signature, x->crl, ctx); +} + +int +NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + return (ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), + x->sig_algor, NULL, x->signature, x->spkac, pkey, md)); +} + +int +X509_pubkey_digest(const X509 *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) +{ + ASN1_BIT_STRING *key; + key = X509_get0_pubkey_bitstr(data); + if (!key) + return 0; + return EVP_Digest(key->data, key->length, md, len, type, NULL); +} + +int +X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) +{ + return (ASN1_item_digest(ASN1_ITEM_rptr(X509), type, (char *)data, + md, len)); +} + +int +X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) +{ + return (ASN1_item_digest(ASN1_ITEM_rptr(X509_CRL), type, (char *)data, + md, len)); +} + +int +X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) +{ + return (ASN1_item_digest(ASN1_ITEM_rptr(X509_REQ), type, (char *)data, + md, len)); +} + +int +X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) +{ + return (ASN1_item_digest(ASN1_ITEM_rptr(X509_NAME), type, (char *)data, + md, len)); +} + +int +PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, + const EVP_MD *type, unsigned char *md, unsigned int *len) +{ + return(ASN1_item_digest(ASN1_ITEM_rptr(PKCS7_ISSUER_AND_SERIAL), type, + (char *)data, md, len)); +} diff --git a/crypto/libressl/crypto/x509v3/ext_dat.h b/crypto/libressl/crypto/x509v3/ext_dat.h new file mode 100644 index 0000000000..332550848f --- /dev/null +++ b/crypto/libressl/crypto/x509v3/ext_dat.h @@ -0,0 +1,129 @@ +/* $OpenBSD: ext_dat.h,v 1.11 2014/07/10 22:45:58 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +/* This file contains a table of "standard" extensions */ + +extern X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku; +extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo; +extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id; +extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate; +extern X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl; +extern X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff; +extern X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc; +extern X509V3_EXT_METHOD v3_crl_hold, v3_pci; +extern X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints; +extern X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp; +extern X509V3_EXT_METHOD v3_addr, v3_asid; + +/* This table will be searched using OBJ_bsearch so it *must* kept in + * order of the ext_nid values. + */ + +static const X509V3_EXT_METHOD *standard_exts[] = { + &v3_nscert, + &v3_ns_ia5_list[0], + &v3_ns_ia5_list[1], + &v3_ns_ia5_list[2], + &v3_ns_ia5_list[3], + &v3_ns_ia5_list[4], + &v3_ns_ia5_list[5], + &v3_ns_ia5_list[6], + &v3_skey_id, + &v3_key_usage, + &v3_pkey_usage_period, + &v3_alt[0], + &v3_alt[1], + &v3_bcons, + &v3_crl_num, + &v3_cpols, + &v3_akey_id, + &v3_crld, + &v3_ext_ku, + &v3_delta_crl, + &v3_crl_reason, +#ifndef OPENSSL_NO_OCSP + &v3_crl_invdate, +#endif + &v3_sxnet, + &v3_info, +#ifndef OPENSSL_NO_OCSP + &v3_ocsp_nonce, + &v3_ocsp_crlid, + &v3_ocsp_accresp, + &v3_ocsp_nocheck, + &v3_ocsp_acutoff, + &v3_ocsp_serviceloc, +#endif + &v3_sinfo, + &v3_policy_constraints, +#ifndef OPENSSL_NO_OCSP + &v3_crl_hold, +#endif + &v3_pci, + &v3_name_constraints, + &v3_policy_mappings, + &v3_inhibit_anyp, + &v3_idp, + &v3_alt[2], + &v3_freshest_crl, +}; + +/* Number of standard extensions */ +#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts)/sizeof(X509V3_EXT_METHOD *)) diff --git a/crypto/libressl/crypto/x509v3/pcy_cache.c b/crypto/libressl/crypto/x509v3/pcy_cache.c new file mode 100644 index 0000000000..7df3686fcc --- /dev/null +++ b/crypto/libressl/crypto/x509v3/pcy_cache.c @@ -0,0 +1,271 @@ +/* $OpenBSD: pcy_cache.c,v 1.4 2014/06/12 15:49:31 deraadt Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include "pcy_int.h" + +static int policy_data_cmp(const X509_POLICY_DATA * const *a, + const X509_POLICY_DATA * const *b); +static int policy_cache_set_int(long *out, ASN1_INTEGER *value); + +/* Set cache entry according to CertificatePolicies extension. + * Note: this destroys the passed CERTIFICATEPOLICIES structure. + */ + +static int +policy_cache_create(X509 *x, CERTIFICATEPOLICIES *policies, int crit) +{ + int i; + int ret = 0; + X509_POLICY_CACHE *cache = x->policy_cache; + X509_POLICY_DATA *data = NULL; + POLICYINFO *policy; + + if (sk_POLICYINFO_num(policies) == 0) + goto bad_policy; + cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp); + if (!cache->data) + goto bad_policy; + for (i = 0; i < sk_POLICYINFO_num(policies); i++) { + policy = sk_POLICYINFO_value(policies, i); + data = policy_data_new(policy, NULL, crit); + if (!data) + goto bad_policy; + /* Duplicate policy OIDs are illegal: reject if matches + * found. + */ + if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) { + if (cache->anyPolicy) { + ret = -1; + goto bad_policy; + } + cache->anyPolicy = data; + } else if (sk_X509_POLICY_DATA_find(cache->data, data) != -1) { + ret = -1; + goto bad_policy; + } else if (!sk_X509_POLICY_DATA_push(cache->data, data)) + goto bad_policy; + data = NULL; + } + ret = 1; + +bad_policy: + if (ret == -1) + x->ex_flags |= EXFLAG_INVALID_POLICY; + if (data) + policy_data_free(data); + sk_POLICYINFO_pop_free(policies, POLICYINFO_free); + if (ret <= 0) { + sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free); + cache->data = NULL; + } + return ret; +} + +static int +policy_cache_new(X509 *x) +{ + X509_POLICY_CACHE *cache; + ASN1_INTEGER *ext_any = NULL; + POLICY_CONSTRAINTS *ext_pcons = NULL; + CERTIFICATEPOLICIES *ext_cpols = NULL; + POLICY_MAPPINGS *ext_pmaps = NULL; + int i; + + cache = malloc(sizeof(X509_POLICY_CACHE)); + if (!cache) + return 0; + cache->anyPolicy = NULL; + cache->data = NULL; + cache->any_skip = -1; + cache->explicit_skip = -1; + cache->map_skip = -1; + + x->policy_cache = cache; + + /* Handle requireExplicitPolicy *first*. Need to process this + * even if we don't have any policies. + */ + ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL); + + if (!ext_pcons) { + if (i != -1) + goto bad_cache; + } else { + if (!ext_pcons->requireExplicitPolicy && + !ext_pcons->inhibitPolicyMapping) + goto bad_cache; + if (!policy_cache_set_int(&cache->explicit_skip, + ext_pcons->requireExplicitPolicy)) + goto bad_cache; + if (!policy_cache_set_int(&cache->map_skip, + ext_pcons->inhibitPolicyMapping)) + goto bad_cache; + } + + /* Process CertificatePolicies */ + + ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL); + /* If no CertificatePolicies extension or problem decoding then + * there is no point continuing because the valid policies will be + * NULL. + */ + if (!ext_cpols) { + /* If not absent some problem with extension */ + if (i != -1) + goto bad_cache; + return 1; + } + + i = policy_cache_create(x, ext_cpols, i); + + /* NB: ext_cpols freed by policy_cache_set_policies */ + + if (i <= 0) + return i; + + ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL); + + if (!ext_pmaps) { + /* If not absent some problem with extension */ + if (i != -1) + goto bad_cache; + } else { + i = policy_cache_set_mapping(x, ext_pmaps); + if (i <= 0) + goto bad_cache; + } + + ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL); + + if (!ext_any) { + if (i != -1) + goto bad_cache; + } else if (!policy_cache_set_int(&cache->any_skip, ext_any)) + goto bad_cache; + + if (0) { +bad_cache: + x->ex_flags |= EXFLAG_INVALID_POLICY; + } + + if (ext_pcons) + POLICY_CONSTRAINTS_free(ext_pcons); + + if (ext_any) + ASN1_INTEGER_free(ext_any); + + return 1; +} + +void +policy_cache_free(X509_POLICY_CACHE *cache) +{ + if (!cache) + return; + if (cache->anyPolicy) + policy_data_free(cache->anyPolicy); + if (cache->data) + sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free); + free(cache); +} + +const X509_POLICY_CACHE * +policy_cache_set(X509 *x) +{ + if (x->policy_cache == NULL) { + CRYPTO_w_lock(CRYPTO_LOCK_X509); + policy_cache_new(x); + CRYPTO_w_unlock(CRYPTO_LOCK_X509); + } + + return x->policy_cache; +} + +X509_POLICY_DATA * +policy_cache_find_data(const X509_POLICY_CACHE *cache, const ASN1_OBJECT *id) +{ + int idx; + X509_POLICY_DATA tmp; + + tmp.valid_policy = (ASN1_OBJECT *)id; + idx = sk_X509_POLICY_DATA_find(cache->data, &tmp); + if (idx == -1) + return NULL; + return sk_X509_POLICY_DATA_value(cache->data, idx); +} + +static int +policy_data_cmp(const X509_POLICY_DATA * const *a, + const X509_POLICY_DATA * const *b) +{ + return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy); +} + +static int +policy_cache_set_int(long *out, ASN1_INTEGER *value) +{ + if (value == NULL) + return 1; + if (value->type == V_ASN1_NEG_INTEGER) + return 0; + *out = ASN1_INTEGER_get(value); + return 1; +} diff --git a/crypto/libressl/crypto/x509v3/pcy_data.c b/crypto/libressl/crypto/x509v3/pcy_data.c new file mode 100644 index 0000000000..9fc33427c5 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/pcy_data.c @@ -0,0 +1,129 @@ +/* $OpenBSD: pcy_data.c,v 1.8 2014/07/11 08:44:49 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include "pcy_int.h" + +/* Policy Node routines */ + +void +policy_data_free(X509_POLICY_DATA *data) +{ + ASN1_OBJECT_free(data->valid_policy); + /* Don't free qualifiers if shared */ + if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS)) + sk_POLICYQUALINFO_pop_free(data->qualifier_set, + POLICYQUALINFO_free); + sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free); + free(data); +} + +/* Create a data based on an existing policy. If 'id' is NULL use the + * oid in the policy, otherwise use 'id'. This behaviour covers the two + * types of data in RFC3280: data with from a CertificatePolcies extension + * and additional data with just the qualifiers of anyPolicy and ID from + * another source. + */ + +X509_POLICY_DATA * +policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *cid, int crit) +{ + X509_POLICY_DATA *ret = NULL; + ASN1_OBJECT *id = NULL; + + if (policy == NULL && cid == NULL) + return NULL; + if (cid != NULL) { + id = OBJ_dup(cid); + if (id == NULL) + return NULL; + } + ret = malloc(sizeof(X509_POLICY_DATA)); + if (ret == NULL) + goto err; + ret->expected_policy_set = sk_ASN1_OBJECT_new_null(); + if (ret->expected_policy_set == NULL) + goto err; + + if (crit) + ret->flags = POLICY_DATA_FLAG_CRITICAL; + else + ret->flags = 0; + + if (id != NULL) + ret->valid_policy = id; + else { + ret->valid_policy = policy->policyid; + policy->policyid = NULL; + } + + if (policy != NULL) { + ret->qualifier_set = policy->qualifiers; + policy->qualifiers = NULL; + } else + ret->qualifier_set = NULL; + + return ret; + +err: + free(ret); + ASN1_OBJECT_free(id); + return NULL; +} diff --git a/crypto/libressl/crypto/x509v3/pcy_int.h b/crypto/libressl/crypto/x509v3/pcy_int.h new file mode 100644 index 0000000000..f2b0242eb1 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/pcy_int.h @@ -0,0 +1,206 @@ +/* $OpenBSD: pcy_int.h,v 1.3 2014/06/12 15:49:31 deraadt Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + +typedef struct X509_POLICY_DATA_st X509_POLICY_DATA; + +DECLARE_STACK_OF(X509_POLICY_DATA) + +/* Internal structures */ + +/* This structure and the field names correspond to the Policy 'node' of + * RFC3280. NB this structure contains no pointers to parent or child + * data: X509_POLICY_NODE contains that. This means that the main policy data + * can be kept static and cached with the certificate. + */ + +struct X509_POLICY_DATA_st { + unsigned int flags; + /* Policy OID and qualifiers for this data */ + ASN1_OBJECT *valid_policy; + STACK_OF(POLICYQUALINFO) *qualifier_set; + STACK_OF(ASN1_OBJECT) *expected_policy_set; +}; + +/* X509_POLICY_DATA flags values */ + +/* This flag indicates the structure has been mapped using a policy mapping + * extension. If policy mapping is not active its references get deleted. + */ + +#define POLICY_DATA_FLAG_MAPPED 0x1 + +/* This flag indicates the data doesn't correspond to a policy in Certificate + * Policies: it has been mapped to any policy. + */ + +#define POLICY_DATA_FLAG_MAPPED_ANY 0x2 + +/* AND with flags to see if any mapping has occurred */ + +#define POLICY_DATA_FLAG_MAP_MASK 0x3 + +/* qualifiers are shared and shouldn't be freed */ + +#define POLICY_DATA_FLAG_SHARED_QUALIFIERS 0x4 + +/* Parent node is an extra node and should be freed */ + +#define POLICY_DATA_FLAG_EXTRA_NODE 0x8 + +/* Corresponding CertificatePolicies is critical */ + +#define POLICY_DATA_FLAG_CRITICAL 0x10 + +/* This structure is cached with a certificate */ + +struct X509_POLICY_CACHE_st { + /* anyPolicy data or NULL if no anyPolicy */ + X509_POLICY_DATA *anyPolicy; + /* other policy data */ + STACK_OF(X509_POLICY_DATA) *data; + /* If InhibitAnyPolicy present this is its value or -1 if absent. */ + long any_skip; + /* If policyConstraints and requireExplicitPolicy present this is its + * value or -1 if absent. + */ + long explicit_skip; + /* If policyConstraints and policyMapping present this is its + * value or -1 if absent. + */ + long map_skip; +}; + +/*#define POLICY_CACHE_FLAG_CRITICAL POLICY_DATA_FLAG_CRITICAL*/ + +/* This structure represents the relationship between nodes */ + +struct X509_POLICY_NODE_st { + /* node data this refers to */ + const X509_POLICY_DATA *data; + /* Parent node */ + X509_POLICY_NODE *parent; + /* Number of child nodes */ + int nchild; +}; + +struct X509_POLICY_LEVEL_st { + /* Cert for this level */ + X509 *cert; + /* nodes at this level */ + STACK_OF(X509_POLICY_NODE) *nodes; + /* anyPolicy node */ + X509_POLICY_NODE *anyPolicy; + /* Extra data */ + /*STACK_OF(X509_POLICY_DATA) *extra_data;*/ + unsigned int flags; +}; + +struct X509_POLICY_TREE_st { + /* This is the tree 'level' data */ + X509_POLICY_LEVEL *levels; + int nlevel; + /* Extra policy data when additional nodes (not from the certificate) + * are required. + */ + STACK_OF(X509_POLICY_DATA) *extra_data; + /* This is the authority constained policy set */ + STACK_OF(X509_POLICY_NODE) *auth_policies; + STACK_OF(X509_POLICY_NODE) *user_policies; + unsigned int flags; +}; + +/* Set if anyPolicy present in user policies */ +#define POLICY_FLAG_ANY_POLICY 0x2 + +/* Useful macros */ + +#define node_data_critical(data) (data->flags & POLICY_DATA_FLAG_CRITICAL) +#define node_critical(node) node_data_critical(node->data) + +/* Internal functions */ + +X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id, + int crit); +void policy_data_free(X509_POLICY_DATA *data); + +X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache, + const ASN1_OBJECT *id); +int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps); + + +STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void); + +void policy_cache_init(void); + +void policy_cache_free(X509_POLICY_CACHE *cache); + +X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, + const X509_POLICY_NODE *parent, const ASN1_OBJECT *id); + +X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk, + const ASN1_OBJECT *id); + +int level_add_node(X509_POLICY_LEVEL *level, + const X509_POLICY_DATA *data, X509_POLICY_NODE *parent, + X509_POLICY_TREE *tree, X509_POLICY_NODE **nodep); +void policy_node_free(X509_POLICY_NODE *node); +int policy_node_match(const X509_POLICY_LEVEL *lvl, + const X509_POLICY_NODE *node, const ASN1_OBJECT *oid); + +const X509_POLICY_CACHE *policy_cache_set(X509 *x); diff --git a/crypto/libressl/crypto/x509v3/pcy_lib.c b/crypto/libressl/crypto/x509v3/pcy_lib.c new file mode 100644 index 0000000000..b8b0af8a66 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/pcy_lib.c @@ -0,0 +1,157 @@ +/* $OpenBSD: pcy_lib.c,v 1.4 2014/07/11 08:44:49 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include "pcy_int.h" + +/* accessor functions */ + +/* X509_POLICY_TREE stuff */ + +int +X509_policy_tree_level_count(const X509_POLICY_TREE *tree) +{ + if (!tree) + return 0; + return tree->nlevel; +} + +X509_POLICY_LEVEL * +X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i) +{ + if (!tree || (i < 0) || (i >= tree->nlevel)) + return NULL; + return tree->levels + i; +} + +STACK_OF(X509_POLICY_NODE) * +X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree) +{ + if (!tree) + return NULL; + return tree->auth_policies; +} + +STACK_OF(X509_POLICY_NODE) * +X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree) +{ + if (!tree) + return NULL; + if (tree->flags & POLICY_FLAG_ANY_POLICY) + return tree->auth_policies; + else + return tree->user_policies; +} + +/* X509_POLICY_LEVEL stuff */ + +int +X509_policy_level_node_count(X509_POLICY_LEVEL *level) +{ + int n; + if (!level) + return 0; + if (level->anyPolicy) + n = 1; + else + n = 0; + if (level->nodes) + n += sk_X509_POLICY_NODE_num(level->nodes); + return n; +} + +X509_POLICY_NODE * +X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i) +{ + if (!level) + return NULL; + if (level->anyPolicy) { + if (i == 0) + return level->anyPolicy; + i--; + } + return sk_X509_POLICY_NODE_value(level->nodes, i); +} + +/* X509_POLICY_NODE stuff */ + +const ASN1_OBJECT * +X509_policy_node_get0_policy(const X509_POLICY_NODE *node) +{ + if (!node) + return NULL; + return node->data->valid_policy; +} + +STACK_OF(POLICYQUALINFO) * +X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node) +{ + if (!node) + return NULL; + return node->data->qualifier_set; +} + +const X509_POLICY_NODE * +X509_policy_node_get0_parent(const X509_POLICY_NODE *node) +{ + if (!node) + return NULL; + return node->parent; +} diff --git a/crypto/libressl/crypto/x509v3/pcy_map.c b/crypto/libressl/crypto/x509v3/pcy_map.c new file mode 100644 index 0000000000..43b05750e5 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/pcy_map.c @@ -0,0 +1,126 @@ +/* $OpenBSD: pcy_map.c,v 1.3 2014/06/12 15:49:31 deraadt Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include "pcy_int.h" + +/* Set policy mapping entries in cache. + * Note: this modifies the passed POLICY_MAPPINGS structure + */ + +int +policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) +{ + POLICY_MAPPING *map; + X509_POLICY_DATA *data; + X509_POLICY_CACHE *cache = x->policy_cache; + int i; + int ret = 0; + + if (sk_POLICY_MAPPING_num(maps) == 0) { + ret = -1; + goto bad_mapping; + } + for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) { + map = sk_POLICY_MAPPING_value(maps, i); + /* Reject if map to or from anyPolicy */ + if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy) || + (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy)) { + ret = -1; + goto bad_mapping; + } + + /* Attempt to find matching policy data */ + data = policy_cache_find_data(cache, map->issuerDomainPolicy); + /* If we don't have anyPolicy can't map */ + if (!data && !cache->anyPolicy) + continue; + + /* Create a NODE from anyPolicy */ + if (!data) { + data = policy_data_new(NULL, map->issuerDomainPolicy, + cache->anyPolicy->flags & + POLICY_DATA_FLAG_CRITICAL); + if (!data) + goto bad_mapping; + data->qualifier_set = cache->anyPolicy->qualifier_set; + /*map->issuerDomainPolicy = NULL;*/ + data->flags |= POLICY_DATA_FLAG_MAPPED_ANY; + data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; + if (!sk_X509_POLICY_DATA_push(cache->data, data)) { + policy_data_free(data); + goto bad_mapping; + } + } else + data->flags |= POLICY_DATA_FLAG_MAPPED; + if (!sk_ASN1_OBJECT_push(data->expected_policy_set, + map->subjectDomainPolicy)) + goto bad_mapping; + map->subjectDomainPolicy = NULL; + } + + ret = 1; + +bad_mapping: + if (ret == -1) + x->ex_flags |= EXFLAG_INVALID_POLICY; + sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free); + return ret; +} diff --git a/crypto/libressl/crypto/x509v3/pcy_node.c b/crypto/libressl/crypto/x509v3/pcy_node.c new file mode 100644 index 0000000000..eb4a30f70b --- /dev/null +++ b/crypto/libressl/crypto/x509v3/pcy_node.c @@ -0,0 +1,199 @@ +/* $OpenBSD: pcy_node.c,v 1.5 2014/07/23 20:49:52 miod Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include "pcy_int.h" + +static int +node_cmp(const X509_POLICY_NODE * const *a, const X509_POLICY_NODE * const *b) +{ + return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy); +} + +STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void) +{ + return sk_X509_POLICY_NODE_new(node_cmp); +} + +X509_POLICY_NODE * +tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes, const ASN1_OBJECT *id) +{ + X509_POLICY_DATA n; + X509_POLICY_NODE l; + int idx; + + n.valid_policy = (ASN1_OBJECT *)id; + l.data = &n; + + idx = sk_X509_POLICY_NODE_find(nodes, &l); + if (idx == -1) + return NULL; + + return sk_X509_POLICY_NODE_value(nodes, idx); +} + +X509_POLICY_NODE * +level_find_node(const X509_POLICY_LEVEL *level, const X509_POLICY_NODE *parent, + const ASN1_OBJECT *id) +{ + X509_POLICY_NODE *node; + int i; + + for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { + node = sk_X509_POLICY_NODE_value(level->nodes, i); + if (node->parent == parent) { + if (!OBJ_cmp(node->data->valid_policy, id)) + return node; + } + } + return NULL; +} + + +int +level_add_node(X509_POLICY_LEVEL *level, const X509_POLICY_DATA *data, + X509_POLICY_NODE *parent, X509_POLICY_TREE *tree, X509_POLICY_NODE **nodep) +{ + X509_POLICY_NODE *node = NULL; + + if (level) { + node = malloc(sizeof(X509_POLICY_NODE)); + if (!node) + goto node_error; + node->data = data; + node->parent = parent; + node->nchild = 0; + if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) { + if (level->anyPolicy) + goto node_error; + level->anyPolicy = node; + if (parent) + parent->nchild++; + } else { + + if (!level->nodes) + level->nodes = policy_node_cmp_new(); + if (!level->nodes) + goto node_error; + if (!sk_X509_POLICY_NODE_push(level->nodes, node)) + goto node_error; + if (parent) + parent->nchild++; + } + } + + if (tree) { + if (!tree->extra_data) + tree->extra_data = sk_X509_POLICY_DATA_new_null(); + if (!tree->extra_data) + goto node_error_cond; + if (!sk_X509_POLICY_DATA_push(tree->extra_data, data)) + goto node_error_cond; + } + + if (nodep) + *nodep = node; + + return 1; + +node_error_cond: + if (level) + node = NULL; +node_error: + policy_node_free(node); + node = NULL; + if (nodep) + *nodep = node; + return 0; +} + +void +policy_node_free(X509_POLICY_NODE *node) +{ + free(node); +} + +/* See if a policy node matches a policy OID. If mapping enabled look through + * expected policy set otherwise just valid policy. + */ + +int +policy_node_match(const X509_POLICY_LEVEL *lvl, const X509_POLICY_NODE *node, + const ASN1_OBJECT *oid) +{ + int i; + ASN1_OBJECT *policy_oid; + const X509_POLICY_DATA *x = node->data; + + if ((lvl->flags & X509_V_FLAG_INHIBIT_MAP) || + !(x->flags & POLICY_DATA_FLAG_MAP_MASK)) { + if (!OBJ_cmp(x->valid_policy, oid)) + return 1; + return 0; + } + + for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++) { + policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i); + if (!OBJ_cmp(policy_oid, oid)) + return 1; + } + return 0; +} diff --git a/crypto/libressl/crypto/x509v3/pcy_tree.c b/crypto/libressl/crypto/x509v3/pcy_tree.c new file mode 100644 index 0000000000..5503d249e5 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/pcy_tree.c @@ -0,0 +1,768 @@ +/* $OpenBSD: pcy_tree.c,v 1.15 2015/07/18 00:01:05 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include "pcy_int.h" + +/* Enable this to print out the complete policy tree at various point during + * evaluation. + */ + +/*#define OPENSSL_POLICY_DEBUG*/ + +#ifdef OPENSSL_POLICY_DEBUG + +static void +expected_print(BIO *err, X509_POLICY_LEVEL *lev, X509_POLICY_NODE *node, + int indent) +{ + if ((lev->flags & X509_V_FLAG_INHIBIT_MAP) || + !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK)) + BIO_puts(err, " Not Mapped\n"); + else { + int i; + STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set; + ASN1_OBJECT *oid; + BIO_puts(err, " Expected: "); + for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) { + oid = sk_ASN1_OBJECT_value(pset, i); + if (i) + BIO_puts(err, ", "); + i2a_ASN1_OBJECT(err, oid); + } + BIO_puts(err, "\n"); + } +} + +static void +tree_print(char *str, X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr) +{ + X509_POLICY_LEVEL *plev; + X509_POLICY_NODE *node; + int i; + BIO *err; + + err = BIO_new_fp(stderr, BIO_NOCLOSE); + if (!curr) + curr = tree->levels + tree->nlevel; + else + curr++; + BIO_printf(err, "Level print after %s\n", str); + BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels); + for (plev = tree->levels; plev != curr; plev++) { + BIO_printf(err, "Level %ld, flags = %x\n", + plev - tree->levels, plev->flags); + for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) { + node = sk_X509_POLICY_NODE_value(plev->nodes, i); + X509_POLICY_NODE_print(err, node, 2); + expected_print(err, plev, node, 2); + BIO_printf(err, " Flags: %x\n", node->data->flags); + } + if (plev->anyPolicy) + X509_POLICY_NODE_print(err, plev->anyPolicy, 2); + } + + BIO_free(err); +} +#else + +#define tree_print(a,b,c) /* */ + +#endif + +/* Initialize policy tree. Return values: + * 0 Some internal error occured. + * -1 Inconsistent or invalid extensions in certificates. + * 1 Tree initialized OK. + * 2 Policy tree is empty. + * 5 Tree OK and requireExplicitPolicy true. + * 6 Tree empty and requireExplicitPolicy true. + */ + +static int +tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, unsigned int flags) +{ + X509_POLICY_TREE *tree; + X509_POLICY_LEVEL *level; + const X509_POLICY_CACHE *cache; + X509_POLICY_DATA *data = NULL; + X509 *x; + int ret = 1; + int i, n; + int explicit_policy; + int any_skip; + int map_skip; + + *ptree = NULL; + n = sk_X509_num(certs); + + if (flags & X509_V_FLAG_EXPLICIT_POLICY) + explicit_policy = 0; + else + explicit_policy = n + 1; + + if (flags & X509_V_FLAG_INHIBIT_ANY) + any_skip = 0; + else + any_skip = n + 1; + + if (flags & X509_V_FLAG_INHIBIT_MAP) + map_skip = 0; + else + map_skip = n + 1; + + /* Can't do anything with just a trust anchor */ + if (n == 1) + return 1; + /* First setup policy cache in all certificates apart from the + * trust anchor. Note any bad cache results on the way. Also can + * calculate explicit_policy value at this point. + */ + for (i = n - 2; i >= 0; i--) { + x = sk_X509_value(certs, i); + X509_check_purpose(x, -1, -1); + cache = policy_cache_set(x); + /* If cache NULL something bad happened: return immediately */ + if (cache == NULL) + return 0; + /* If inconsistent extensions keep a note of it but continue */ + if (x->ex_flags & EXFLAG_INVALID_POLICY) + ret = -1; + /* Otherwise if we have no data (hence no CertificatePolicies) + * and haven't already set an inconsistent code note it. + */ + else if ((ret == 1) && !cache->data) + ret = 2; + if (explicit_policy > 0) { + if (!(x->ex_flags & EXFLAG_SI)) + explicit_policy--; + if ((cache->explicit_skip != -1) && + (cache->explicit_skip < explicit_policy)) + explicit_policy = cache->explicit_skip; + } + } + + if (ret != 1) { + if (ret == 2 && !explicit_policy) + return 6; + return ret; + } + + + /* If we get this far initialize the tree */ + + tree = malloc(sizeof(X509_POLICY_TREE)); + + if (!tree) + return 0; + + tree->flags = 0; + tree->levels = calloc(n, sizeof(X509_POLICY_LEVEL)); + tree->nlevel = 0; + tree->extra_data = NULL; + tree->auth_policies = NULL; + tree->user_policies = NULL; + + if (!tree->levels) { + free(tree); + return 0; + } + + tree->nlevel = n; + + level = tree->levels; + + /* Root data: initialize to anyPolicy */ + + data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0); + + if (!data || !level_add_node(level, data, NULL, tree, NULL)) + goto bad_tree; + + for (i = n - 2; i >= 0; i--) { + level++; + x = sk_X509_value(certs, i); + cache = policy_cache_set(x); + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + level->cert = x; + + if (!cache->anyPolicy) + level->flags |= X509_V_FLAG_INHIBIT_ANY; + + /* Determine inhibit any and inhibit map flags */ + if (any_skip == 0) { + /* Any matching allowed if certificate is self + * issued and not the last in the chain. + */ + if (!(x->ex_flags & EXFLAG_SI) || (i == 0)) + level->flags |= X509_V_FLAG_INHIBIT_ANY; + } else { + if (!(x->ex_flags & EXFLAG_SI)) + any_skip--; + if ((cache->any_skip >= 0) && + (cache->any_skip < any_skip)) + any_skip = cache->any_skip; + } + + if (map_skip == 0) + level->flags |= X509_V_FLAG_INHIBIT_MAP; + else { + if (!(x->ex_flags & EXFLAG_SI)) + map_skip--; + if ((cache->map_skip >= 0) && + (cache->map_skip < map_skip)) + map_skip = cache->map_skip; + } + + } + + *ptree = tree; + + if (explicit_policy) + return 1; + else + return 5; + +bad_tree: + X509_policy_tree_free(tree); + + return 0; +} + +static int +tree_link_matching_nodes(X509_POLICY_LEVEL *curr, const X509_POLICY_DATA *data) +{ + X509_POLICY_LEVEL *last = curr - 1; + X509_POLICY_NODE *node; + int i, matched = 0; + + /* Iterate through all in nodes linking matches */ + for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) { + node = sk_X509_POLICY_NODE_value(last->nodes, i); + if (policy_node_match(last, node, data->valid_policy)) { + if (!level_add_node(curr, data, node, NULL, NULL)) + return 0; + matched = 1; + } + } + if (!matched && last->anyPolicy) { + if (!level_add_node(curr, data, last->anyPolicy, NULL, NULL)) + return 0; + } + return 1; +} + +/* This corresponds to RFC3280 6.1.3(d)(1): + * link any data from CertificatePolicies onto matching parent + * or anyPolicy if no match. + */ + +static int +tree_link_nodes(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache) +{ + int i; + X509_POLICY_DATA *data; + + for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) { + data = sk_X509_POLICY_DATA_value(cache->data, i); + /* Look for matching nodes in previous level */ + if (!tree_link_matching_nodes(curr, data)) + return 0; + } + return 1; +} + +/* This corresponds to RFC3280 6.1.3(d)(2): + * Create new data for any unmatched policies in the parent and link + * to anyPolicy. + */ + +static int +tree_add_unmatched(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache, + const ASN1_OBJECT *id, X509_POLICY_NODE *node, X509_POLICY_TREE *tree) +{ + X509_POLICY_DATA *data; + + if (id == NULL) + id = node->data->valid_policy; + /* Create a new node with qualifiers from anyPolicy and + * id from unmatched node. + */ + data = policy_data_new(NULL, id, node_critical(node)); + + if (data == NULL) + return 0; + /* Curr may not have anyPolicy */ + data->qualifier_set = cache->anyPolicy->qualifier_set; + data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; + if (!level_add_node(curr, data, node, tree, NULL)) { + policy_data_free(data); + return 0; + } + + return 1; +} + +static int +tree_link_unmatched(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache, + X509_POLICY_NODE *node, X509_POLICY_TREE *tree) +{ + const X509_POLICY_LEVEL *last = curr - 1; + int i; + + if ((last->flags & X509_V_FLAG_INHIBIT_MAP) || + !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) { + /* If no policy mapping: matched if one child present */ + if (node->nchild) + return 1; + if (!tree_add_unmatched(curr, cache, NULL, node, tree)) + return 0; + /* Add it */ + } else { + /* If mapping: matched if one child per expected policy set */ + STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set; + if (node->nchild == sk_ASN1_OBJECT_num(expset)) + return 1; + /* Locate unmatched nodes */ + for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) { + ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i); + if (level_find_node(curr, node, oid)) + continue; + if (!tree_add_unmatched(curr, cache, oid, node, tree)) + return 0; + } + } + + return 1; +} + +static int +tree_link_any(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache, + X509_POLICY_TREE *tree) +{ + int i; + X509_POLICY_NODE *node; + X509_POLICY_LEVEL *last = curr - 1; + + for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) { + node = sk_X509_POLICY_NODE_value(last->nodes, i); + + if (!tree_link_unmatched(curr, cache, node, tree)) + return 0; + } + /* Finally add link to anyPolicy */ + if (last->anyPolicy) { + if (!level_add_node(curr, cache->anyPolicy, + last->anyPolicy, NULL, NULL)) + return 0; + } + return 1; +} + +/* Prune the tree: delete any child mapped child data on the current level + * then proceed up the tree deleting any data with no children. If we ever + * have no data on a level we can halt because the tree will be empty. + */ + +static int +tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr) +{ + STACK_OF(X509_POLICY_NODE) *nodes; + X509_POLICY_NODE *node; + int i; + + nodes = curr->nodes; + if (curr->flags & X509_V_FLAG_INHIBIT_MAP) { + for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) { + node = sk_X509_POLICY_NODE_value(nodes, i); + /* Delete any mapped data: see RFC3280 XXXX */ + if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) { + node->parent->nchild--; + free(node); + (void)sk_X509_POLICY_NODE_delete(nodes, i); + } + } + } + + for (;;) { + --curr; + nodes = curr->nodes; + for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) { + node = sk_X509_POLICY_NODE_value(nodes, i); + if (node->nchild == 0) { + node->parent->nchild--; + free(node); + (void)sk_X509_POLICY_NODE_delete(nodes, i); + } + } + if (curr->anyPolicy && !curr->anyPolicy->nchild) { + if (curr->anyPolicy->parent) + curr->anyPolicy->parent->nchild--; + free(curr->anyPolicy); + curr->anyPolicy = NULL; + } + if (curr == tree->levels) { + /* If we zapped anyPolicy at top then tree is empty */ + if (!curr->anyPolicy) + return 2; + return 1; + } + } + + return 1; +} + +static int +tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes, X509_POLICY_NODE *pcy) +{ + if (!*pnodes) { + *pnodes = policy_node_cmp_new(); + if (!*pnodes) + return 0; + } else if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1) + return 1; + + if (!sk_X509_POLICY_NODE_push(*pnodes, pcy)) + return 0; + + return 1; +} + +/* Calculate the authority set based on policy tree. + * The 'pnodes' parameter is used as a store for the set of policy nodes + * used to calculate the user set. If the authority set is not anyPolicy + * then pnodes will just point to the authority set. If however the authority + * set is anyPolicy then the set of valid policies (other than anyPolicy) + * is store in pnodes. The return value of '2' is used in this case to indicate + * that pnodes should be freed. + */ + +static int +tree_calculate_authority_set(X509_POLICY_TREE *tree, + STACK_OF(X509_POLICY_NODE) **pnodes) +{ + X509_POLICY_LEVEL *curr; + X509_POLICY_NODE *node, *anyptr; + STACK_OF(X509_POLICY_NODE) **addnodes; + int i, j; + + curr = tree->levels + tree->nlevel - 1; + + /* If last level contains anyPolicy set is anyPolicy */ + if (curr->anyPolicy) { + if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy)) + return 0; + addnodes = pnodes; + } else + /* Add policies to authority set */ + addnodes = &tree->auth_policies; + + curr = tree->levels; + for (i = 1; i < tree->nlevel; i++) { + /* If no anyPolicy node on this this level it can't + * appear on lower levels so end search. + */ + if (!(anyptr = curr->anyPolicy)) + break; + curr++; + for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) { + node = sk_X509_POLICY_NODE_value(curr->nodes, j); + if ((node->parent == anyptr) && + !tree_add_auth_node(addnodes, node)) + return 0; + } + } + + if (addnodes == pnodes) + return 2; + + *pnodes = tree->auth_policies; + + return 1; +} + +static int +tree_calculate_user_set(X509_POLICY_TREE *tree, + STACK_OF(ASN1_OBJECT) *policy_oids, STACK_OF(X509_POLICY_NODE) *auth_nodes) +{ + int i; + X509_POLICY_NODE *node; + ASN1_OBJECT *oid; + X509_POLICY_NODE *anyPolicy; + X509_POLICY_DATA *extra; + + /* Check if anyPolicy present in authority constrained policy set: + * this will happen if it is a leaf node. + */ + + if (sk_ASN1_OBJECT_num(policy_oids) <= 0) + return 1; + + anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy; + + for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) { + oid = sk_ASN1_OBJECT_value(policy_oids, i); + if (OBJ_obj2nid(oid) == NID_any_policy) { + tree->flags |= POLICY_FLAG_ANY_POLICY; + return 1; + } + } + + for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) { + oid = sk_ASN1_OBJECT_value(policy_oids, i); + node = tree_find_sk(auth_nodes, oid); + if (!node) { + if (!anyPolicy) + continue; + /* Create a new node with policy ID from user set + * and qualifiers from anyPolicy. + */ + extra = policy_data_new(NULL, oid, + node_critical(anyPolicy)); + if (!extra) + return 0; + extra->qualifier_set = anyPolicy->data->qualifier_set; + extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS | + POLICY_DATA_FLAG_EXTRA_NODE; + (void) level_add_node(NULL, extra, anyPolicy->parent, + tree, &node); + } + if (!tree->user_policies) { + tree->user_policies = sk_X509_POLICY_NODE_new_null(); + if (!tree->user_policies) + return 1; + } + if (!sk_X509_POLICY_NODE_push(tree->user_policies, node)) + return 0; + } + return 1; +} + +static int +tree_evaluate(X509_POLICY_TREE *tree) +{ + int ret, i; + X509_POLICY_LEVEL *curr = tree->levels + 1; + const X509_POLICY_CACHE *cache; + + for (i = 1; i < tree->nlevel; i++, curr++) { + cache = policy_cache_set(curr->cert); + if (!tree_link_nodes(curr, cache)) + return 0; + + if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) && + !tree_link_any(curr, cache, tree)) + return 0; + tree_print("before tree_prune()", tree, curr); + ret = tree_prune(tree, curr); + if (ret != 1) + return ret; + } + + return 1; +} + +static void +exnode_free(X509_POLICY_NODE *node) +{ + if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE)) + free(node); +} + +void +X509_policy_tree_free(X509_POLICY_TREE *tree) +{ + X509_POLICY_LEVEL *curr; + int i; + + if (!tree) + return; + + sk_X509_POLICY_NODE_free(tree->auth_policies); + sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free); + + for (i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) { + X509_free(curr->cert); + if (curr->nodes) + sk_X509_POLICY_NODE_pop_free(curr->nodes, + policy_node_free); + if (curr->anyPolicy) + policy_node_free(curr->anyPolicy); + } + + if (tree->extra_data) + sk_X509_POLICY_DATA_pop_free(tree->extra_data, + policy_data_free); + + free(tree->levels); + free(tree); +} + +/* Application policy checking function. + * Return codes: + * 0 Internal Error. + * 1 Successful. + * -1 One or more certificates contain invalid or inconsistent extensions + * -2 User constrained policy set empty and requireExplicit true. + */ + +int +X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, + STACK_OF(X509) *certs, STACK_OF(ASN1_OBJECT) *policy_oids, + unsigned int flags) +{ + int ret, ret2; + X509_POLICY_TREE *tree = NULL; + STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL; + + *ptree = NULL; + *pexplicit_policy = 0; + ret = tree_init(&tree, certs, flags); + + switch (ret) { + + /* Tree empty requireExplicit False: OK */ + case 2: + return 1; + + /* Some internal error */ + case -1: + return -1; + + /* Some internal error */ + case 0: + return 0; + + /* Tree empty requireExplicit True: Error */ + + case 6: + *pexplicit_policy = 1; + return -2; + + /* Tree OK requireExplicit True: OK and continue */ + case 5: + *pexplicit_policy = 1; + break; + + /* Tree OK: continue */ + + case 1: + if (!tree) + /* + * tree_init() returns success and a null tree + * if it's just looking at a trust anchor. + * I'm not sure that returning success here is + * correct, but I'm sure that reporting this + * as an internal error which our caller + * interprets as a malloc failure is wrong. + */ + return 1; + break; + } + + if (!tree) + goto error; + ret = tree_evaluate(tree); + + tree_print("tree_evaluate()", tree, NULL); + + if (ret <= 0) + goto error; + + /* Return value 2 means tree empty */ + if (ret == 2) { + X509_policy_tree_free(tree); + if (*pexplicit_policy) + return -2; + else + return 1; + } + + /* Tree is not empty: continue */ + + ret = tree_calculate_authority_set(tree, &auth_nodes); + if (ret == 0) + goto error; + + ret2 = tree_calculate_user_set(tree, policy_oids, auth_nodes); + + /* Return value 2 means auth_nodes needs to be freed */ + if (ret == 2) + sk_X509_POLICY_NODE_free(auth_nodes); + + if (ret2 == 0) + goto error; + + if (tree) + *ptree = tree; + + if (*pexplicit_policy) { + nodes = X509_policy_tree_get0_user_policies(tree); + if (sk_X509_POLICY_NODE_num(nodes) <= 0) + return -2; + } + + return 1; + +error: + X509_policy_tree_free(tree); + + return 0; +} diff --git a/crypto/libressl/crypto/x509v3/v3_akey.c b/crypto/libressl/crypto/x509v3/v3_akey.c new file mode 100644 index 0000000000..8d05e97e5f --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_akey.c @@ -0,0 +1,215 @@ +/* $OpenBSD: v3_akey.c,v 1.16 2015/09/30 17:30:16 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, + AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist); +static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); + +const X509V3_EXT_METHOD v3_akey_id = { + .ext_nid = NID_authority_key_identifier, + .ext_flags = X509V3_EXT_MULTILINE, + .it = ASN1_ITEM_ref(AUTHORITY_KEYID), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = (X509V3_EXT_I2V)i2v_AUTHORITY_KEYID, + .v2i = (X509V3_EXT_V2I)v2i_AUTHORITY_KEYID, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +static +STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, + AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist) +{ + char *tmp; + + if (akeyid->keyid) { + tmp = hex_to_string(akeyid->keyid->data, akeyid->keyid->length); + X509V3_add_value("keyid", tmp, &extlist); + free(tmp); + } + if (akeyid->issuer) + extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist); + if (akeyid->serial) { + tmp = hex_to_string(akeyid->serial->data, + akeyid->serial->length); + X509V3_add_value("serial", tmp, &extlist); + free(tmp); + } + return extlist; +} + +/* Currently two options: + * keyid: use the issuers subject keyid, the value 'always' means its is + * an error if the issuer certificate doesn't have a key id. + * issuer: use the issuers cert issuer and serial number. The default is + * to only use this if keyid is not present. With the option 'always' + * this is always included. + */ + +static AUTHORITY_KEYID * +v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values) +{ + char keyid = 0, issuer = 0; + int i; + CONF_VALUE *cnf; + ASN1_OCTET_STRING *ikeyid = NULL; + X509_NAME *isname = NULL; + STACK_OF(GENERAL_NAME) *gens = NULL; + GENERAL_NAME *gen = NULL; + ASN1_INTEGER *serial = NULL; + X509_EXTENSION *ext; + X509 *cert; + AUTHORITY_KEYID *akeyid = NULL; + + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + cnf = sk_CONF_VALUE_value(values, i); + if (!strcmp(cnf->name, "keyid")) { + keyid = 1; + if (cnf->value && !strcmp(cnf->value, "always")) + keyid = 2; + } + else if (!strcmp(cnf->name, "issuer")) { + issuer = 1; + if (cnf->value && !strcmp(cnf->value, "always")) + issuer = 2; + } else { + X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, + X509V3_R_UNKNOWN_OPTION); + ERR_asprintf_error_data("name=%s", cnf->name); + return NULL; + } + } + + if (!ctx || !ctx->issuer_cert) { + if (ctx && (ctx->flags == CTX_TEST)) + return AUTHORITY_KEYID_new(); + X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, + X509V3_R_NO_ISSUER_CERTIFICATE); + return NULL; + } + + cert = ctx->issuer_cert; + + if (keyid) { + i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1); + if ((i >= 0) && (ext = X509_get_ext(cert, i))) + ikeyid = X509V3_EXT_d2i(ext); + if (keyid == 2 && !ikeyid) { + X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, + X509V3_R_UNABLE_TO_GET_ISSUER_KEYID); + return NULL; + } + } + + if ((issuer && !ikeyid) || (issuer == 2)) { + isname = X509_NAME_dup(X509_get_issuer_name(cert)); + serial = ASN1_INTEGER_dup(X509_get_serialNumber(cert)); + if (!isname || !serial) { + X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, + X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS); + goto err; + } + } + + if (!(akeyid = AUTHORITY_KEYID_new())) + goto err; + + if (isname) { + if (!(gens = sk_GENERAL_NAME_new_null()) || + !(gen = GENERAL_NAME_new()) || + !sk_GENERAL_NAME_push(gens, gen)) { + X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, + ERR_R_MALLOC_FAILURE); + goto err; + } + gen->type = GEN_DIRNAME; + gen->d.dirn = isname; + } + + akeyid->issuer = gens; + akeyid->serial = serial; + akeyid->keyid = ikeyid; + + return akeyid; + +err: + AUTHORITY_KEYID_free(akeyid); + GENERAL_NAME_free(gen); + sk_GENERAL_NAME_free(gens); + X509_NAME_free(isname); + ASN1_INTEGER_free(serial); + ASN1_OCTET_STRING_free(ikeyid); + return NULL; +} diff --git a/crypto/libressl/crypto/x509v3/v3_akeya.c b/crypto/libressl/crypto/x509v3/v3_akeya.c new file mode 100644 index 0000000000..bbbed934fe --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_akeya.c @@ -0,0 +1,124 @@ +/* $OpenBSD: v3_akeya.c,v 1.6 2015/02/09 16:03:11 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include + +static const ASN1_TEMPLATE AUTHORITY_KEYID_seq_tt[] = { + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(AUTHORITY_KEYID, keyid), + .field_name = "keyid", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(AUTHORITY_KEYID, issuer), + .field_name = "issuer", + .item = &GENERAL_NAME_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 2, + .offset = offsetof(AUTHORITY_KEYID, serial), + .field_name = "serial", + .item = &ASN1_INTEGER_it, + }, +}; + +const ASN1_ITEM AUTHORITY_KEYID_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = AUTHORITY_KEYID_seq_tt, + .tcount = sizeof(AUTHORITY_KEYID_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(AUTHORITY_KEYID), + .sname = "AUTHORITY_KEYID", +}; + + +AUTHORITY_KEYID * +d2i_AUTHORITY_KEYID(AUTHORITY_KEYID **a, const unsigned char **in, long len) +{ + return (AUTHORITY_KEYID *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &AUTHORITY_KEYID_it); +} + +int +i2d_AUTHORITY_KEYID(AUTHORITY_KEYID *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &AUTHORITY_KEYID_it); +} + +AUTHORITY_KEYID * +AUTHORITY_KEYID_new(void) +{ + return (AUTHORITY_KEYID *)ASN1_item_new(&AUTHORITY_KEYID_it); +} + +void +AUTHORITY_KEYID_free(AUTHORITY_KEYID *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &AUTHORITY_KEYID_it); +} diff --git a/crypto/libressl/crypto/x509v3/v3_alt.c b/crypto/libressl/crypto/x509v3/v3_alt.c new file mode 100644 index 0000000000..36db31b272 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_alt.c @@ -0,0 +1,671 @@ +/* $OpenBSD: v3_alt.c,v 1.24 2015/07/29 16:13:48 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2003 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include + +static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); +static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); +static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx); +static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx); + +const X509V3_EXT_METHOD v3_alt[] = { + { + .ext_nid = NID_subject_alt_name, + .ext_flags = 0, + .it = ASN1_ITEM_ref(GENERAL_NAMES), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = (X509V3_EXT_I2V)i2v_GENERAL_NAMES, + .v2i = (X509V3_EXT_V2I)v2i_subject_alt, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, + { + .ext_nid = NID_issuer_alt_name, + .ext_flags = 0, + .it = ASN1_ITEM_ref(GENERAL_NAMES), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = (X509V3_EXT_I2V)i2v_GENERAL_NAMES, + .v2i = (X509V3_EXT_V2I)v2i_issuer_alt, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, + { + .ext_nid = NID_certificate_issuer, + .ext_flags = 0, + .it = ASN1_ITEM_ref(GENERAL_NAMES), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = (X509V3_EXT_I2V)i2v_GENERAL_NAMES, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, +}; + +STACK_OF(CONF_VALUE) * +i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, GENERAL_NAMES *gens, + STACK_OF(CONF_VALUE) *ret) +{ + int i; + GENERAL_NAME *gen; + + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + gen = sk_GENERAL_NAME_value(gens, i); + ret = i2v_GENERAL_NAME(method, gen, ret); + } + if (!ret) + return sk_CONF_VALUE_new_null(); + return ret; +} + +STACK_OF(CONF_VALUE) * +i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen, + STACK_OF(CONF_VALUE) *ret) +{ + unsigned char *p; + char oline[256], htmp[5]; + int i; + + switch (gen->type) { + case GEN_OTHERNAME: + X509V3_add_value("othername", "", &ret); + break; + + case GEN_X400: + X509V3_add_value("X400Name", "", &ret); + break; + + case GEN_EDIPARTY: + X509V3_add_value("EdiPartyName", "", &ret); + break; + + case GEN_EMAIL: + X509V3_add_value_uchar("email", gen->d.ia5->data, &ret); + break; + + case GEN_DNS: + X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret); + break; + + case GEN_URI: + X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret); + break; + + case GEN_DIRNAME: + X509_NAME_oneline(gen->d.dirn, oline, 256); + X509V3_add_value("DirName", oline, &ret); + break; + + case GEN_IPADD: + p = gen->d.ip->data; + if (gen->d.ip->length == 4) + (void) snprintf(oline, sizeof oline, + "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); + else if (gen->d.ip->length == 16) { + oline[0] = 0; + for (i = 0; i < 8; i++) { + (void) snprintf(htmp, sizeof htmp, + "%X", p[0] << 8 | p[1]); + p += 2; + strlcat(oline, htmp, sizeof(oline)); + if (i != 7) + strlcat(oline, ":", sizeof(oline)); + } + } else { + X509V3_add_value("IP Address", "", &ret); + break; + } + X509V3_add_value("IP Address", oline, &ret); + break; + + case GEN_RID: + i2t_ASN1_OBJECT(oline, 256, gen->d.rid); + X509V3_add_value("Registered ID", oline, &ret); + break; + } + return ret; +} + +int +GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) +{ + unsigned char *p; + int i; + + switch (gen->type) { + case GEN_OTHERNAME: + BIO_printf(out, "othername:"); + break; + + case GEN_X400: + BIO_printf(out, "X400Name:"); + break; + + case GEN_EDIPARTY: + /* Maybe fix this: it is supported now */ + BIO_printf(out, "EdiPartyName:"); + break; + + case GEN_EMAIL: + BIO_printf(out, "email:%s", gen->d.ia5->data); + break; + + case GEN_DNS: + BIO_printf(out, "DNS:%s", gen->d.ia5->data); + break; + + case GEN_URI: + BIO_printf(out, "URI:%s", gen->d.ia5->data); + break; + + case GEN_DIRNAME: + BIO_printf(out, "DirName: "); + X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE); + break; + + case GEN_IPADD: + p = gen->d.ip->data; + if (gen->d.ip->length == 4) + BIO_printf(out, "IP Address:%d.%d.%d.%d", + p[0], p[1], p[2], p[3]); + else if (gen->d.ip->length == 16) { + BIO_printf(out, "IP Address"); + for (i = 0; i < 8; i++) { + BIO_printf(out, ":%X", p[0] << 8 | p[1]); + p += 2; + } + BIO_puts(out, "\n"); + } else { + BIO_printf(out, "IP Address:"); + break; + } + break; + + case GEN_RID: + BIO_printf(out, "Registered ID"); + i2a_ASN1_OBJECT(out, gen->d.rid); + break; + } + return 1; +} + +static GENERAL_NAMES * +v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + GENERAL_NAMES *gens = NULL; + CONF_VALUE *cnf; + int i; + + if ((gens = sk_GENERAL_NAME_new_null()) == NULL) { + X509V3err(X509V3_F_V2I_ISSUER_ALT, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (name_cmp(cnf->name, "issuer") == 0 && cnf->value != NULL && + strcmp(cnf->value, "copy") == 0) { + if (!copy_issuer(ctx, gens)) + goto err; + } else { + GENERAL_NAME *gen; + if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL) + goto err; + if (sk_GENERAL_NAME_push(gens, gen) == 0) { + GENERAL_NAME_free(gen); + goto err; + } + } + } + return gens; + +err: + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return NULL; +} + +/* Append subject altname of issuer to issuer alt name of subject */ + +static int +copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) +{ + GENERAL_NAMES *ialt; + GENERAL_NAME *gen; + X509_EXTENSION *ext; + int i; + + if (ctx && (ctx->flags == CTX_TEST)) + return 1; + if (!ctx || !ctx->issuer_cert) { + X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_NO_ISSUER_DETAILS); + goto err; + } + i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); + if (i < 0) + return 1; + if (!(ext = X509_get_ext(ctx->issuer_cert, i)) || + !(ialt = X509V3_EXT_d2i(ext))) { + X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_ISSUER_DECODE_ERROR); + goto err; + } + + for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) { + gen = sk_GENERAL_NAME_value(ialt, i); + if (!sk_GENERAL_NAME_push(gens, gen)) { + X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE); + goto err; + } + } + sk_GENERAL_NAME_free(ialt); + + return 1; + +err: + return 0; + +} + +static GENERAL_NAMES * +v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + GENERAL_NAMES *gens = NULL; + CONF_VALUE *cnf; + int i; + + if (!(gens = sk_GENERAL_NAME_new_null())) { + X509V3err(X509V3_F_V2I_SUBJECT_ALT, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (!name_cmp(cnf->name, "email") && cnf->value && + !strcmp(cnf->value, "copy")) { + if (!copy_email(ctx, gens, 0)) + goto err; + } else if (!name_cmp(cnf->name, "email") && cnf->value && + !strcmp(cnf->value, "move")) { + if (!copy_email(ctx, gens, 1)) + goto err; + } else { + GENERAL_NAME *gen; + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + if (sk_GENERAL_NAME_push(gens, gen) == 0) { + GENERAL_NAME_free(gen); + goto err; + } + } + } + return gens; + +err: + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return NULL; +} + +/* Copy any email addresses in a certificate or request to + * GENERAL_NAMES + */ + +static int +copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) +{ + X509_NAME *nm; + ASN1_IA5STRING *email = NULL; + X509_NAME_ENTRY *ne; + GENERAL_NAME *gen = NULL; + int i; + + if (ctx != NULL && ctx->flags == CTX_TEST) + return 1; + if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) { + X509V3err(X509V3_F_COPY_EMAIL, X509V3_R_NO_SUBJECT_DETAILS); + goto err; + } + /* Find the subject name */ + if (ctx->subject_cert) + nm = X509_get_subject_name(ctx->subject_cert); + else + nm = X509_REQ_get_subject_name(ctx->subject_req); + + /* Now add any email address(es) to STACK */ + i = -1; + while ((i = X509_NAME_get_index_by_NID(nm, + NID_pkcs9_emailAddress, i)) >= 0) { + ne = X509_NAME_get_entry(nm, i); + email = ASN1_STRING_dup(X509_NAME_ENTRY_get_data(ne)); + if (move_p) { + X509_NAME_delete_entry(nm, i); + X509_NAME_ENTRY_free(ne); + i--; + } + if (!email || !(gen = GENERAL_NAME_new())) { + X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); + goto err; + } + gen->d.ia5 = email; + email = NULL; + gen->type = GEN_EMAIL; + if (!sk_GENERAL_NAME_push(gens, gen)) { + X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); + goto err; + } + gen = NULL; + } + + return 1; + +err: + GENERAL_NAME_free(gen); + ASN1_IA5STRING_free(email); + return 0; +} + +GENERAL_NAMES * +v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + GENERAL_NAME *gen; + GENERAL_NAMES *gens = NULL; + CONF_VALUE *cnf; + int i; + + if (!(gens = sk_GENERAL_NAME_new_null())) { + X509V3err(X509V3_F_V2I_GENERAL_NAMES, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + if (sk_GENERAL_NAME_push(gens, gen) == 0) { + GENERAL_NAME_free(gen); + goto err; + } + } + return gens; + +err: + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return NULL; +} + +GENERAL_NAME * +v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + CONF_VALUE *cnf) +{ + return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0); +} + +GENERAL_NAME * +a2i_GENERAL_NAME(GENERAL_NAME *out, const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, int gen_type, char *value, int is_nc) +{ + char is_string = 0; + GENERAL_NAME *gen = NULL; + + if (!value) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_MISSING_VALUE); + return NULL; + } + + if (out) + gen = out; + else { + gen = GENERAL_NAME_new(); + if (gen == NULL) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, + ERR_R_MALLOC_FAILURE); + return NULL; + } + } + + switch (gen_type) { + case GEN_URI: + case GEN_EMAIL: + case GEN_DNS: + is_string = 1; + break; + + case GEN_RID: + { + ASN1_OBJECT *obj; + if (!(obj = OBJ_txt2obj(value, 0))) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, + X509V3_R_BAD_OBJECT); + ERR_asprintf_error_data("value=%s", value); + goto err; + } + gen->d.rid = obj; + } + break; + + case GEN_IPADD: + if (is_nc) + gen->d.ip = a2i_IPADDRESS_NC(value); + else + gen->d.ip = a2i_IPADDRESS(value); + if (gen->d.ip == NULL) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, + X509V3_R_BAD_IP_ADDRESS); + ERR_asprintf_error_data("value=%s", value); + goto err; + } + break; + + case GEN_DIRNAME: + if (!do_dirname(gen, value, ctx)) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, + X509V3_R_DIRNAME_ERROR); + goto err; + } + break; + + case GEN_OTHERNAME: + if (!do_othername(gen, value, ctx)) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, + X509V3_R_OTHERNAME_ERROR); + goto err; + } + break; + + default: + X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_UNSUPPORTED_TYPE); + goto err; + } + + if (is_string) { + if (!(gen->d.ia5 = ASN1_IA5STRING_new()) || + !ASN1_STRING_set(gen->d.ia5, (unsigned char*)value, + strlen(value))) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, + ERR_R_MALLOC_FAILURE); + goto err; + } + } + + gen->type = gen_type; + + return gen; + +err: + if (out == NULL) + GENERAL_NAME_free(gen); + return NULL; +} + +GENERAL_NAME * +v2i_GENERAL_NAME_ex(GENERAL_NAME *out, const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc) +{ + int type; + char *name, *value; + + name = cnf->name; + value = cnf->value; + + if (!value) { + X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_MISSING_VALUE); + return NULL; + } + + if (!name_cmp(name, "email")) + type = GEN_EMAIL; + else if (!name_cmp(name, "URI")) + type = GEN_URI; + else if (!name_cmp(name, "DNS")) + type = GEN_DNS; + else if (!name_cmp(name, "RID")) + type = GEN_RID; + else if (!name_cmp(name, "IP")) + type = GEN_IPADD; + else if (!name_cmp(name, "dirName")) + type = GEN_DIRNAME; + else if (!name_cmp(name, "otherName")) + type = GEN_OTHERNAME; + else { + X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, + X509V3_R_UNSUPPORTED_OPTION); + ERR_asprintf_error_data("name=%s", name); + return NULL; + } + + return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc); +} + +static int +do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) +{ + char *objtmp = NULL, *p; + int objlen; + + if (!(p = strchr(value, ';'))) + return 0; + if (!(gen->d.otherName = OTHERNAME_new())) + return 0; + /* Free this up because we will overwrite it. + * no need to free type_id because it is static + */ + ASN1_TYPE_free(gen->d.otherName->value); + if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx))) + return 0; + objlen = p - value; + objtmp = malloc(objlen + 1); + if (objtmp) { + strlcpy(objtmp, value, objlen + 1); + gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0); + free(objtmp); + } else + gen->d.otherName->type_id = NULL; + if (!gen->d.otherName->type_id) + return 0; + return 1; +} + +static int +do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) +{ + int ret; + STACK_OF(CONF_VALUE) *sk; + X509_NAME *nm; + + if (!(nm = X509_NAME_new())) + return 0; + sk = X509V3_get_section(ctx, value); + if (!sk) { + X509V3err(X509V3_F_DO_DIRNAME, X509V3_R_SECTION_NOT_FOUND); + ERR_asprintf_error_data("section=%s", value); + X509_NAME_free(nm); + return 0; + } + /* FIXME: should allow other character types... */ + ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC); + if (!ret) + X509_NAME_free(nm); + gen->d.dirn = nm; + X509V3_section_free(ctx, sk); + + return ret; +} diff --git a/crypto/libressl/crypto/x509v3/v3_bcons.c b/crypto/libressl/crypto/x509v3/v3_bcons.c new file mode 100644 index 0000000000..8255557531 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_bcons.c @@ -0,0 +1,185 @@ +/* $OpenBSD: v3_bcons.c,v 1.12 2015/07/25 16:00:14 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, + BASIC_CONSTRAINTS *bcons, STACK_OF(CONF_VALUE) *extlist); +static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); + +const X509V3_EXT_METHOD v3_bcons = { + .ext_nid = NID_basic_constraints, + .ext_flags = 0, + .it = ASN1_ITEM_ref(BASIC_CONSTRAINTS), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = (X509V3_EXT_I2V)i2v_BASIC_CONSTRAINTS, + .v2i = (X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +static const ASN1_TEMPLATE BASIC_CONSTRAINTS_seq_tt[] = { + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(BASIC_CONSTRAINTS, ca), + .field_name = "ca", + .item = &ASN1_FBOOLEAN_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(BASIC_CONSTRAINTS, pathlen), + .field_name = "pathlen", + .item = &ASN1_INTEGER_it, + }, +}; + +const ASN1_ITEM BASIC_CONSTRAINTS_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = BASIC_CONSTRAINTS_seq_tt, + .tcount = sizeof(BASIC_CONSTRAINTS_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(BASIC_CONSTRAINTS), + .sname = "BASIC_CONSTRAINTS", +}; + + +BASIC_CONSTRAINTS * +d2i_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS **a, const unsigned char **in, long len) +{ + return (BASIC_CONSTRAINTS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &BASIC_CONSTRAINTS_it); +} + +int +i2d_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &BASIC_CONSTRAINTS_it); +} + +BASIC_CONSTRAINTS * +BASIC_CONSTRAINTS_new(void) +{ + return (BASIC_CONSTRAINTS *)ASN1_item_new(&BASIC_CONSTRAINTS_it); +} + +void +BASIC_CONSTRAINTS_free(BASIC_CONSTRAINTS *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &BASIC_CONSTRAINTS_it); +} + + +static STACK_OF(CONF_VALUE) * +i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, BASIC_CONSTRAINTS *bcons, + STACK_OF(CONF_VALUE) *extlist) +{ + X509V3_add_value_bool("CA", bcons->ca, &extlist); + X509V3_add_value_int("pathlen", bcons->pathlen, &extlist); + return extlist; +} + +static BASIC_CONSTRAINTS * +v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values) +{ + BASIC_CONSTRAINTS *bcons = NULL; + CONF_VALUE *val; + int i; + + if (!(bcons = BASIC_CONSTRAINTS_new())) { + X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + val = sk_CONF_VALUE_value(values, i); + if (!strcmp(val->name, "CA")) { + if (!X509V3_get_value_bool(val, &bcons->ca)) + goto err; + } else if (!strcmp(val->name, "pathlen")) { + if (!X509V3_get_value_int(val, &bcons->pathlen)) + goto err; + } else { + X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, + X509V3_R_INVALID_NAME); + X509V3_conf_err(val); + goto err; + } + } + return bcons; + +err: + BASIC_CONSTRAINTS_free(bcons); + return NULL; +} diff --git a/crypto/libressl/crypto/x509v3/v3_bitst.c b/crypto/libressl/crypto/x509v3/v3_bitst.c new file mode 100644 index 0000000000..2381625531 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_bitst.c @@ -0,0 +1,175 @@ +/* $OpenBSD: v3_bitst.c,v 1.11 2015/07/29 16:13:48 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include + +static BIT_STRING_BITNAME ns_cert_type_table[] = { + {0, "SSL Client", "client"}, + {1, "SSL Server", "server"}, + {2, "S/MIME", "email"}, + {3, "Object Signing", "objsign"}, + {4, "Unused", "reserved"}, + {5, "SSL CA", "sslCA"}, + {6, "S/MIME CA", "emailCA"}, + {7, "Object Signing CA", "objCA"}, + {-1, NULL, NULL} +}; + +static BIT_STRING_BITNAME key_usage_type_table[] = { + {0, "Digital Signature", "digitalSignature"}, + {1, "Non Repudiation", "nonRepudiation"}, + {2, "Key Encipherment", "keyEncipherment"}, + {3, "Data Encipherment", "dataEncipherment"}, + {4, "Key Agreement", "keyAgreement"}, + {5, "Certificate Sign", "keyCertSign"}, + {6, "CRL Sign", "cRLSign"}, + {7, "Encipher Only", "encipherOnly"}, + {8, "Decipher Only", "decipherOnly"}, + {-1, NULL, NULL} +}; + +const X509V3_EXT_METHOD v3_nscert = { + .ext_nid = NID_netscape_cert_type, + .ext_flags = 0, + .it = ASN1_ITEM_ref(ASN1_BIT_STRING), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, + .v2i = (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, + .i2r = NULL, + .r2i = NULL, + .usr_data = ns_cert_type_table, +}; + +const X509V3_EXT_METHOD v3_key_usage = { + .ext_nid = NID_key_usage, + .ext_flags = 0, + .it = ASN1_ITEM_ref(ASN1_BIT_STRING), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, + .v2i = (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, + .i2r = NULL, + .r2i = NULL, + .usr_data = key_usage_type_table, +}; + +STACK_OF(CONF_VALUE) * +i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, ASN1_BIT_STRING *bits, + STACK_OF(CONF_VALUE) *ret) +{ + BIT_STRING_BITNAME *bnam; + + for (bnam = method->usr_data; bnam->lname; bnam++) { + if (ASN1_BIT_STRING_get_bit(bits, bnam->bitnum)) + X509V3_add_value(bnam->lname, NULL, &ret); + } + return ret; +} + +ASN1_BIT_STRING * +v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + CONF_VALUE *val; + ASN1_BIT_STRING *bs; + int i; + BIT_STRING_BITNAME *bnam; + + if (!(bs = ASN1_BIT_STRING_new())) { + X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + for (bnam = method->usr_data; bnam->lname; bnam++) { + if (!strcmp(bnam->sname, val->name) || + !strcmp(bnam->lname, val->name) ) { + if (!ASN1_BIT_STRING_set_bit(bs, + bnam->bitnum, 1)) { + X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, + ERR_R_MALLOC_FAILURE); + ASN1_BIT_STRING_free(bs); + return NULL; + } + break; + } + } + if (!bnam->lname) { + X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, + X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT); + X509V3_conf_err(val); + ASN1_BIT_STRING_free(bs); + return NULL; + } + } + return bs; +} diff --git a/crypto/libressl/crypto/x509v3/v3_conf.c b/crypto/libressl/crypto/x509v3/v3_conf.c new file mode 100644 index 0000000000..b5679d7fad --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_conf.c @@ -0,0 +1,576 @@ +/* $OpenBSD: v3_conf.c,v 1.18 2015/09/30 18:41:06 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2002 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* extension creation utilities */ + +#include +#include +#include + +#include +#include +#include +#include + +static int v3_check_critical(char **value); +static int v3_check_generic(char **value); +static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, + int crit, char *value); +static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, + int crit, int type, X509V3_CTX *ctx); +static char *conf_lhash_get_string(void *db, char *section, char *value); +static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section); +static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid, + int crit, void *ext_struc); +static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len); + +/* CONF *conf: Config file */ +/* char *name: Name */ +/* char *value: Value */ +X509_EXTENSION * +X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, char *value) +{ + int crit; + int ext_type; + X509_EXTENSION *ret; + + crit = v3_check_critical(&value); + if ((ext_type = v3_check_generic(&value))) + return v3_generic_extension(name, value, crit, ext_type, ctx); + ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value); + if (!ret) { + X509V3err(X509V3_F_X509V3_EXT_NCONF, + X509V3_R_ERROR_IN_EXTENSION); + ERR_asprintf_error_data("name=%s, value=%s", name, value); + } + return ret; +} + +/* CONF *conf: Config file */ +/* char *value: Value */ +X509_EXTENSION * +X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, char *value) +{ + int crit; + int ext_type; + + crit = v3_check_critical(&value); + if ((ext_type = v3_check_generic(&value))) + return v3_generic_extension(OBJ_nid2sn(ext_nid), + value, crit, ext_type, ctx); + return do_ext_nconf(conf, ctx, ext_nid, crit, value); +} + +/* CONF *conf: Config file */ +/* char *value: Value */ +static X509_EXTENSION * +do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, int crit, char *value) +{ + const X509V3_EXT_METHOD *method; + X509_EXTENSION *ext; + void *ext_struc; + + if (ext_nid == NID_undef) { + X509V3err(X509V3_F_DO_EXT_NCONF, + X509V3_R_UNKNOWN_EXTENSION_NAME); + return NULL; + } + if (!(method = X509V3_EXT_get_nid(ext_nid))) { + X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_UNKNOWN_EXTENSION); + return NULL; + } + /* Now get internal extension representation based on type */ + if (method->v2i) { + STACK_OF(CONF_VALUE) *nval; + + if (*value == '@') + nval = NCONF_get_section(conf, value + 1); + else + nval = X509V3_parse_list(value); + if (sk_CONF_VALUE_num(nval) <= 0) { + X509V3err(X509V3_F_DO_EXT_NCONF, + X509V3_R_INVALID_EXTENSION_STRING); + ERR_asprintf_error_data("name=%s,section=%s", + OBJ_nid2sn(ext_nid), value); + if (*value != '@') + sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); + return NULL; + } + ext_struc = method->v2i(method, ctx, nval); + if (*value != '@') + sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); + } else if (method->s2i) { + ext_struc = method->s2i(method, ctx, value); + } else if (method->r2i) { + if (!ctx->db || !ctx->db_meth) { + X509V3err(X509V3_F_DO_EXT_NCONF, + X509V3_R_NO_CONFIG_DATABASE); + return NULL; + } + ext_struc = method->r2i(method, ctx, value); + } else { + X509V3err(X509V3_F_DO_EXT_NCONF, + X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED); + ERR_asprintf_error_data("name=%s", OBJ_nid2sn(ext_nid)); + return NULL; + } + if (ext_struc == NULL) + return NULL; + + ext = do_ext_i2d(method, ext_nid, crit, ext_struc); + if (method->it) + ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it)); + else + method->ext_free(ext_struc); + return ext; +} + +static X509_EXTENSION * +do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid, int crit, + void *ext_struc) +{ + unsigned char *ext_der; + int ext_len; + ASN1_OCTET_STRING *ext_oct = NULL; + X509_EXTENSION *ext; + + /* Convert internal representation to DER */ + if (method->it) { + ext_der = NULL; + ext_len = ASN1_item_i2d(ext_struc, &ext_der, + ASN1_ITEM_ptr(method->it)); + if (ext_len < 0) + goto merr; + } else { + unsigned char *p; + ext_len = method->i2d(ext_struc, NULL); + if (!(ext_der = malloc(ext_len))) + goto merr; + p = ext_der; + method->i2d(ext_struc, &p); + } + if (!(ext_oct = ASN1_OCTET_STRING_new())) + goto merr; + ext_oct->data = ext_der; + ext_oct->length = ext_len; + + ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct); + if (!ext) + goto merr; + ASN1_OCTET_STRING_free(ext_oct); + + return ext; + +merr: + ASN1_OCTET_STRING_free(ext_oct); + X509V3err(X509V3_F_DO_EXT_I2D, ERR_R_MALLOC_FAILURE); + return NULL; + +} + +/* Given an internal structure, nid and critical flag create an extension */ + +X509_EXTENSION * +X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc) +{ + const X509V3_EXT_METHOD *method; + + if (!(method = X509V3_EXT_get_nid(ext_nid))) { + X509V3err(X509V3_F_X509V3_EXT_I2D, X509V3_R_UNKNOWN_EXTENSION); + return NULL; + } + return do_ext_i2d(method, ext_nid, crit, ext_struc); +} + +/* Check the extension string for critical flag */ +static int +v3_check_critical(char **value) +{ + char *p = *value; + + if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) + return 0; + p += 9; + while (isspace((unsigned char)*p)) p++; + *value = p; + return 1; +} + +/* Check extension string for generic extension and return the type */ +static int +v3_check_generic(char **value) +{ + int gen_type = 0; + char *p = *value; + + if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4)) { + p += 4; + gen_type = 1; + } else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5)) { + p += 5; + gen_type = 2; + } else + return 0; + + while (isspace((unsigned char)*p)) + p++; + *value = p; + return gen_type; +} + +/* Create a generic extension: for now just handle DER type */ +static X509_EXTENSION * +v3_generic_extension(const char *ext, char *value, int crit, int gen_type, + X509V3_CTX *ctx) +{ + unsigned char *ext_der = NULL; + long ext_len = 0; + ASN1_OBJECT *obj = NULL; + ASN1_OCTET_STRING *oct = NULL; + X509_EXTENSION *extension = NULL; + + if (!(obj = OBJ_txt2obj(ext, 0))) { + X509V3err(X509V3_F_V3_GENERIC_EXTENSION, + X509V3_R_EXTENSION_NAME_ERROR); + ERR_asprintf_error_data("name=%s", ext); + goto err; + } + + if (gen_type == 1) + ext_der = string_to_hex(value, &ext_len); + else if (gen_type == 2) + ext_der = generic_asn1(value, ctx, &ext_len); + else { + ERR_asprintf_error_data("Unexpected generic extension type %d", gen_type); + goto err; + } + + if (ext_der == NULL) { + X509V3err(X509V3_F_V3_GENERIC_EXTENSION, + X509V3_R_EXTENSION_VALUE_ERROR); + ERR_asprintf_error_data("value=%s", value); + goto err; + } + + if (!(oct = ASN1_OCTET_STRING_new())) { + X509V3err(X509V3_F_V3_GENERIC_EXTENSION, ERR_R_MALLOC_FAILURE); + goto err; + } + + oct->data = ext_der; + oct->length = ext_len; + ext_der = NULL; + + extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct); + +err: + ASN1_OBJECT_free(obj); + ASN1_OCTET_STRING_free(oct); + free(ext_der); + return extension; +} + +static unsigned char * +generic_asn1(char *value, X509V3_CTX *ctx, long *ext_len) +{ + ASN1_TYPE *typ; + unsigned char *ext_der = NULL; + + typ = ASN1_generate_v3(value, ctx); + if (typ == NULL) + return NULL; + *ext_len = i2d_ASN1_TYPE(typ, &ext_der); + ASN1_TYPE_free(typ); + return ext_der; +} + +/* This is the main function: add a bunch of extensions based on a config file + * section to an extension STACK. + */ + +int +X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, + STACK_OF(X509_EXTENSION) **sk) +{ + X509_EXTENSION *ext; + STACK_OF(CONF_VALUE) *nval; + CONF_VALUE *val; + int i; + + if (!(nval = NCONF_get_section(conf, section))) + return 0; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value))) + return 0; + if (sk) + X509v3_add_ext(sk, ext, -1); + X509_EXTENSION_free(ext); + } + return 1; +} + +/* Convenience functions to add extensions to a certificate, CRL and request */ + +int +X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509 *cert) +{ + STACK_OF(X509_EXTENSION) **sk = NULL; + + if (cert) + sk = &cert->cert_info->extensions; + return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); +} + +/* Same as above but for a CRL */ + +int +X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, + X509_CRL *crl) +{ + STACK_OF(X509_EXTENSION) **sk = NULL; + + if (crl) + sk = &crl->crl->extensions; + return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); +} + +/* Add extensions to certificate request */ + +int +X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, + X509_REQ *req) +{ + STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL; + int i; + + if (req) + sk = &extlist; + i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); + if (!i || !sk) + return i; + i = X509_REQ_add_extensions(req, extlist); + sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free); + return i; +} + +/* Config database functions */ + +char * +X509V3_get_string(X509V3_CTX *ctx, char *name, char *section) +{ + if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string) { + X509V3err(X509V3_F_X509V3_GET_STRING, + X509V3_R_OPERATION_NOT_DEFINED); + return NULL; + } + if (ctx->db_meth->get_string) + return ctx->db_meth->get_string(ctx->db, name, section); + return NULL; +} + +STACK_OF(CONF_VALUE) * +X509V3_get_section(X509V3_CTX *ctx, char *section) +{ + if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section) { + X509V3err(X509V3_F_X509V3_GET_SECTION, + X509V3_R_OPERATION_NOT_DEFINED); + return NULL; + } + if (ctx->db_meth->get_section) + return ctx->db_meth->get_section(ctx->db, section); + return NULL; +} + +void +X509V3_string_free(X509V3_CTX *ctx, char *str) +{ + if (!str) + return; + if (ctx->db_meth->free_string) + ctx->db_meth->free_string(ctx->db, str); +} + +void +X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section) +{ + if (!section) + return; + if (ctx->db_meth->free_section) + ctx->db_meth->free_section(ctx->db, section); +} + +static char * +nconf_get_string(void *db, char *section, char *value) +{ + return NCONF_get_string(db, section, value); +} + +static +STACK_OF(CONF_VALUE) *nconf_get_section(void *db, char *section) +{ + return NCONF_get_section(db, section); +} + +static X509V3_CONF_METHOD nconf_method = { + nconf_get_string, + nconf_get_section, + NULL, + NULL +}; + +void +X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf) +{ + ctx->db_meth = &nconf_method; + ctx->db = conf; +} + +void +X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req, + X509_CRL *crl, int flags) +{ + ctx->issuer_cert = issuer; + ctx->subject_cert = subj; + ctx->crl = crl; + ctx->subject_req = req; + ctx->flags = flags; +} + +/* Old conf compatibility functions */ + +X509_EXTENSION * +X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, char *name, + char *value) +{ + CONF ctmp; + + CONF_set_nconf(&ctmp, conf); + return X509V3_EXT_nconf(&ctmp, ctx, name, value); +} + +/* LHASH *conf: Config file */ +/* char *value: Value */ +X509_EXTENSION * +X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, int ext_nid, + char *value) +{ + CONF ctmp; + + CONF_set_nconf(&ctmp, conf); + return X509V3_EXT_nconf_nid(&ctmp, ctx, ext_nid, value); +} + +static char * +conf_lhash_get_string(void *db, char *section, char *value) +{ + return CONF_get_string(db, section, value); +} + +static STACK_OF(CONF_VALUE) * +conf_lhash_get_section(void *db, char *section) +{ + return CONF_get_section(db, section); +} + +static X509V3_CONF_METHOD conf_lhash_method = { + conf_lhash_get_string, + conf_lhash_get_section, + NULL, + NULL +}; + +void +X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash) +{ + ctx->db_meth = &conf_lhash_method; + ctx->db = lhash; +} + +int +X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, char *section, + X509 *cert) +{ + CONF ctmp; + + CONF_set_nconf(&ctmp, conf); + return X509V3_EXT_add_nconf(&ctmp, ctx, section, cert); +} + +/* Same as above but for a CRL */ + +int +X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509_CRL *crl) +{ + CONF ctmp; + + CONF_set_nconf(&ctmp, conf); + return X509V3_EXT_CRL_add_nconf(&ctmp, ctx, section, crl); +} + +/* Add extensions to certificate request */ + +int +X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509_REQ *req) +{ + CONF ctmp; + + CONF_set_nconf(&ctmp, conf); + return X509V3_EXT_REQ_add_nconf(&ctmp, ctx, section, req); +} diff --git a/crypto/libressl/crypto/x509v3/v3_cpols.c b/crypto/libressl/crypto/x509v3/v3_cpols.c new file mode 100644 index 0000000000..1981ba7f57 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_cpols.c @@ -0,0 +1,775 @@ +/* $OpenBSD: v3_cpols.c,v 1.22 2015/07/29 16:13:48 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "pcy_int.h" + +/* Certificate policies extension support: this one is a bit complex... */ + +static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, + BIO *out, int indent); +static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *value); +static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, + int indent); +static void print_notice(BIO *out, USERNOTICE *notice, int indent); +static POLICYINFO *policy_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *polstrs, int ia5org); +static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *unot, int ia5org); +static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos); + +const X509V3_EXT_METHOD v3_cpols = { + .ext_nid = NID_certificate_policies, + .ext_flags = 0, + .it = ASN1_ITEM_ref(CERTIFICATEPOLICIES), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = (X509V3_EXT_I2R)i2r_certpol, + .r2i = (X509V3_EXT_R2I)r2i_certpol, + .usr_data = NULL, +}; + +static const ASN1_TEMPLATE CERTIFICATEPOLICIES_item_tt = { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = 0, + .field_name = "CERTIFICATEPOLICIES", + .item = &POLICYINFO_it, +}; + +const ASN1_ITEM CERTIFICATEPOLICIES_it = { + .itype = ASN1_ITYPE_PRIMITIVE, + .utype = -1, + .templates = &CERTIFICATEPOLICIES_item_tt, + .tcount = 0, + .funcs = NULL, + .size = 0, + .sname = "CERTIFICATEPOLICIES", +}; + + +CERTIFICATEPOLICIES * +d2i_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES **a, const unsigned char **in, long len) +{ + return (CERTIFICATEPOLICIES *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &CERTIFICATEPOLICIES_it); +} + +int +i2d_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &CERTIFICATEPOLICIES_it); +} + +CERTIFICATEPOLICIES * +CERTIFICATEPOLICIES_new(void) +{ + return (CERTIFICATEPOLICIES *)ASN1_item_new(&CERTIFICATEPOLICIES_it); +} + +void +CERTIFICATEPOLICIES_free(CERTIFICATEPOLICIES *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &CERTIFICATEPOLICIES_it); +} + +static const ASN1_TEMPLATE POLICYINFO_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(POLICYINFO, policyid), + .field_name = "policyid", + .item = &ASN1_OBJECT_it, + }, + { + .flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(POLICYINFO, qualifiers), + .field_name = "qualifiers", + .item = &POLICYQUALINFO_it, + }, +}; + +const ASN1_ITEM POLICYINFO_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = POLICYINFO_seq_tt, + .tcount = sizeof(POLICYINFO_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(POLICYINFO), + .sname = "POLICYINFO", +}; + + +POLICYINFO * +d2i_POLICYINFO(POLICYINFO **a, const unsigned char **in, long len) +{ + return (POLICYINFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &POLICYINFO_it); +} + +int +i2d_POLICYINFO(POLICYINFO *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &POLICYINFO_it); +} + +POLICYINFO * +POLICYINFO_new(void) +{ + return (POLICYINFO *)ASN1_item_new(&POLICYINFO_it); +} + +void +POLICYINFO_free(POLICYINFO *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &POLICYINFO_it); +} + +static const ASN1_TEMPLATE policydefault_tt = { + .flags = 0, + .tag = 0, + .offset = offsetof(POLICYQUALINFO, d.other), + .field_name = "d.other", + .item = &ASN1_ANY_it, +}; + +static const ASN1_ADB_TABLE POLICYQUALINFO_adbtbl[] = { + { + .value = NID_id_qt_cps, + .tt = { + .flags = 0, + .tag = 0, + .offset = offsetof(POLICYQUALINFO, d.cpsuri), + .field_name = "d.cpsuri", + .item = &ASN1_IA5STRING_it, + }, + + }, + { + .value = NID_id_qt_unotice, + .tt = { + .flags = 0, + .tag = 0, + .offset = offsetof(POLICYQUALINFO, d.usernotice), + .field_name = "d.usernotice", + .item = &USERNOTICE_it, + }, + + }, +}; + +static const ASN1_ADB POLICYQUALINFO_adb = { + .flags = 0, + .offset = offsetof(POLICYQUALINFO, pqualid), + .app_items = 0, + .tbl = POLICYQUALINFO_adbtbl, + .tblcount = sizeof(POLICYQUALINFO_adbtbl) / sizeof(ASN1_ADB_TABLE), + .default_tt = &policydefault_tt, + .null_tt = NULL, +}; + +static const ASN1_TEMPLATE POLICYQUALINFO_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(POLICYQUALINFO, pqualid), + .field_name = "pqualid", + .item = &ASN1_OBJECT_it, + }, + { + .flags = ASN1_TFLG_ADB_OID, + .tag = -1, + .offset = 0, + .field_name = "POLICYQUALINFO", + .item = (const ASN1_ITEM *)&POLICYQUALINFO_adb, + }, +}; + +const ASN1_ITEM POLICYQUALINFO_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = POLICYQUALINFO_seq_tt, + .tcount = sizeof(POLICYQUALINFO_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(POLICYQUALINFO), + .sname = "POLICYQUALINFO", +}; + + +POLICYQUALINFO * +d2i_POLICYQUALINFO(POLICYQUALINFO **a, const unsigned char **in, long len) +{ + return (POLICYQUALINFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &POLICYQUALINFO_it); +} + +int +i2d_POLICYQUALINFO(POLICYQUALINFO *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &POLICYQUALINFO_it); +} + +POLICYQUALINFO * +POLICYQUALINFO_new(void) +{ + return (POLICYQUALINFO *)ASN1_item_new(&POLICYQUALINFO_it); +} + +void +POLICYQUALINFO_free(POLICYQUALINFO *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &POLICYQUALINFO_it); +} + +static const ASN1_TEMPLATE USERNOTICE_seq_tt[] = { + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(USERNOTICE, noticeref), + .field_name = "noticeref", + .item = &NOTICEREF_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(USERNOTICE, exptext), + .field_name = "exptext", + .item = &DISPLAYTEXT_it, + }, +}; + +const ASN1_ITEM USERNOTICE_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = USERNOTICE_seq_tt, + .tcount = sizeof(USERNOTICE_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(USERNOTICE), + .sname = "USERNOTICE", +}; + + +USERNOTICE * +d2i_USERNOTICE(USERNOTICE **a, const unsigned char **in, long len) +{ + return (USERNOTICE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &USERNOTICE_it); +} + +int +i2d_USERNOTICE(USERNOTICE *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &USERNOTICE_it); +} + +USERNOTICE * +USERNOTICE_new(void) +{ + return (USERNOTICE *)ASN1_item_new(&USERNOTICE_it); +} + +void +USERNOTICE_free(USERNOTICE *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &USERNOTICE_it); +} + +static const ASN1_TEMPLATE NOTICEREF_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(NOTICEREF, organization), + .field_name = "organization", + .item = &DISPLAYTEXT_it, + }, + { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = offsetof(NOTICEREF, noticenos), + .field_name = "noticenos", + .item = &ASN1_INTEGER_it, + }, +}; + +const ASN1_ITEM NOTICEREF_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = NOTICEREF_seq_tt, + .tcount = sizeof(NOTICEREF_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(NOTICEREF), + .sname = "NOTICEREF", +}; + + +NOTICEREF * +d2i_NOTICEREF(NOTICEREF **a, const unsigned char **in, long len) +{ + return (NOTICEREF *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &NOTICEREF_it); +} + +int +i2d_NOTICEREF(NOTICEREF *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &NOTICEREF_it); +} + +NOTICEREF * +NOTICEREF_new(void) +{ + return (NOTICEREF *)ASN1_item_new(&NOTICEREF_it); +} + +void +NOTICEREF_free(NOTICEREF *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &NOTICEREF_it); +} + +static +STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + char *value) +{ + STACK_OF(POLICYINFO) *pols = NULL; + char *pstr; + POLICYINFO *pol; + ASN1_OBJECT *pobj; + STACK_OF(CONF_VALUE) *vals; + CONF_VALUE *cnf; + int i, ia5org; + + pols = sk_POLICYINFO_new_null(); + if (pols == NULL) { + X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE); + return NULL; + } + vals = X509V3_parse_list(value); + if (vals == NULL) { + X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_X509V3_LIB); + goto err; + } + ia5org = 0; + for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { + cnf = sk_CONF_VALUE_value(vals, i); + if (cnf->value || !cnf->name) { + X509V3err(X509V3_F_R2I_CERTPOL, + X509V3_R_INVALID_POLICY_IDENTIFIER); + X509V3_conf_err(cnf); + goto err; + } + pstr = cnf->name; + if (!strcmp(pstr, "ia5org")) { + ia5org = 1; + continue; + } else if (*pstr == '@') { + STACK_OF(CONF_VALUE) *polsect; + polsect = X509V3_get_section(ctx, pstr + 1); + if (!polsect) { + X509V3err(X509V3_F_R2I_CERTPOL, + X509V3_R_INVALID_SECTION); + X509V3_conf_err(cnf); + goto err; + } + pol = policy_section(ctx, polsect, ia5org); + X509V3_section_free(ctx, polsect); + if (!pol) + goto err; + } else { + if (!(pobj = OBJ_txt2obj(cnf->name, 0))) { + X509V3err(X509V3_F_R2I_CERTPOL, + X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(cnf); + goto err; + } + pol = POLICYINFO_new(); + pol->policyid = pobj; + } + if (!sk_POLICYINFO_push(pols, pol)){ + POLICYINFO_free(pol); + X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE); + goto err; + } + } + sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); + return pols; + +err: + sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); + sk_POLICYINFO_pop_free(pols, POLICYINFO_free); + return NULL; +} + +static POLICYINFO * +policy_section(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *polstrs, int ia5org) +{ + int i; + CONF_VALUE *cnf; + POLICYINFO *pol; + POLICYQUALINFO *nqual = NULL; + + if ((pol = POLICYINFO_new()) == NULL) + goto merr; + for (i = 0; i < sk_CONF_VALUE_num(polstrs); i++) { + cnf = sk_CONF_VALUE_value(polstrs, i); + if (strcmp(cnf->name, "policyIdentifier") == 0) { + ASN1_OBJECT *pobj; + + if ((pobj = OBJ_txt2obj(cnf->value, 0)) == NULL) { + X509V3err(X509V3_F_POLICY_SECTION, + X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(cnf); + goto err; + } + pol->policyid = pobj; + } else if (name_cmp(cnf->name, "CPS") == 0) { + if ((nqual = POLICYQUALINFO_new()) == NULL) + goto merr; + nqual->pqualid = OBJ_nid2obj(NID_id_qt_cps); + nqual->d.cpsuri = ASN1_IA5STRING_new(); + if (nqual->d.cpsuri == NULL) + goto merr; + if (ASN1_STRING_set(nqual->d.cpsuri, cnf->value, + strlen(cnf->value)) == 0) + goto merr; + + if (pol->qualifiers == NULL) { + pol->qualifiers = sk_POLICYQUALINFO_new_null(); + if (pol->qualifiers == NULL) + goto merr; + } + if (sk_POLICYQUALINFO_push(pol->qualifiers, nqual) == 0) + goto merr; + nqual = NULL; + } else if (name_cmp(cnf->name, "userNotice") == 0) { + STACK_OF(CONF_VALUE) *unot; + POLICYQUALINFO *qual; + + if (*cnf->value != '@') { + X509V3err(X509V3_F_POLICY_SECTION, + X509V3_R_EXPECTED_A_SECTION_NAME); + X509V3_conf_err(cnf); + goto err; + } + unot = X509V3_get_section(ctx, cnf->value + 1); + if (unot == NULL) { + X509V3err(X509V3_F_POLICY_SECTION, + X509V3_R_INVALID_SECTION); + X509V3_conf_err(cnf); + goto err; + } + qual = notice_section(ctx, unot, ia5org); + X509V3_section_free(ctx, unot); + if (qual == NULL) + goto err; + + if (pol->qualifiers == NULL) { + pol->qualifiers = sk_POLICYQUALINFO_new_null(); + if (pol->qualifiers == NULL) + goto merr; + } + if (sk_POLICYQUALINFO_push(pol->qualifiers, qual) == 0) + goto merr; + } else { + X509V3err(X509V3_F_POLICY_SECTION, + X509V3_R_INVALID_OPTION); + X509V3_conf_err(cnf); + goto err; + } + } + if (pol->policyid == NULL) { + X509V3err(X509V3_F_POLICY_SECTION, + X509V3_R_NO_POLICY_IDENTIFIER); + goto err; + } + + return pol; + +merr: + X509V3err(X509V3_F_POLICY_SECTION, ERR_R_MALLOC_FAILURE); + +err: + POLICYQUALINFO_free(nqual); + POLICYINFO_free(pol); + return NULL; +} + +static POLICYQUALINFO * +notice_section(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *unot, int ia5org) +{ + int i, ret; + CONF_VALUE *cnf; + USERNOTICE *not; + POLICYQUALINFO *qual; + + if (!(qual = POLICYQUALINFO_new())) + goto merr; + qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice); + if (!(not = USERNOTICE_new())) + goto merr; + qual->d.usernotice = not; + for (i = 0; i < sk_CONF_VALUE_num(unot); i++) { + cnf = sk_CONF_VALUE_value(unot, i); + if (!strcmp(cnf->name, "explicitText")) { + if (not->exptext == NULL) { + not->exptext = ASN1_VISIBLESTRING_new(); + if (not->exptext == NULL) + goto merr; + } + if (!ASN1_STRING_set(not->exptext, cnf->value, + strlen(cnf->value))) + goto merr; + } else if (!strcmp(cnf->name, "organization")) { + NOTICEREF *nref; + if (!not->noticeref) { + if (!(nref = NOTICEREF_new())) + goto merr; + not->noticeref = nref; + } else + nref = not->noticeref; + if (ia5org) + nref->organization->type = V_ASN1_IA5STRING; + else + nref->organization->type = V_ASN1_VISIBLESTRING; + if (!ASN1_STRING_set(nref->organization, cnf->value, + strlen(cnf->value))) + goto merr; + } else if (!strcmp(cnf->name, "noticeNumbers")) { + NOTICEREF *nref; + STACK_OF(CONF_VALUE) *nos; + if (!not->noticeref) { + if (!(nref = NOTICEREF_new())) + goto merr; + not->noticeref = nref; + } else + nref = not->noticeref; + nos = X509V3_parse_list(cnf->value); + if (!nos || !sk_CONF_VALUE_num(nos)) { + X509V3err(X509V3_F_NOTICE_SECTION, + X509V3_R_INVALID_NUMBERS); + X509V3_conf_err(cnf); + if (nos != NULL) + sk_CONF_VALUE_pop_free(nos, + X509V3_conf_free); + goto err; + } + ret = nref_nos(nref->noticenos, nos); + sk_CONF_VALUE_pop_free(nos, X509V3_conf_free); + if (!ret) + goto err; + } else { + X509V3err(X509V3_F_NOTICE_SECTION, + X509V3_R_INVALID_OPTION); + X509V3_conf_err(cnf); + goto err; + } + } + + if (not->noticeref && + (!not->noticeref->noticenos || !not->noticeref->organization)) { + X509V3err(X509V3_F_NOTICE_SECTION, + X509V3_R_NEED_ORGANIZATION_AND_NUMBERS); + goto err; + } + + return qual; + +merr: + X509V3err(X509V3_F_NOTICE_SECTION, ERR_R_MALLOC_FAILURE); + +err: + POLICYQUALINFO_free(qual); + return NULL; +} + +static int +nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos) +{ + CONF_VALUE *cnf; + ASN1_INTEGER *aint; + int i; + + for (i = 0; i < sk_CONF_VALUE_num(nos); i++) { + cnf = sk_CONF_VALUE_value(nos, i); + if (!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) { + X509V3err(X509V3_F_NREF_NOS, X509V3_R_INVALID_NUMBER); + goto err; + } + if (!sk_ASN1_INTEGER_push(nnums, aint)) + goto merr; + } + return 1; + +merr: + X509V3err(X509V3_F_NREF_NOS, ERR_R_MALLOC_FAILURE); + +err: + sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free); + return 0; +} + +static int +i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, BIO *out, + int indent) +{ + int i; + POLICYINFO *pinfo; + + /* First print out the policy OIDs */ + for (i = 0; i < sk_POLICYINFO_num(pol); i++) { + pinfo = sk_POLICYINFO_value(pol, i); + BIO_printf(out, "%*sPolicy: ", indent, ""); + i2a_ASN1_OBJECT(out, pinfo->policyid); + BIO_puts(out, "\n"); + if (pinfo->qualifiers) + print_qualifiers(out, pinfo->qualifiers, indent + 2); + } + return 1; +} + +static void +print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, int indent) +{ + POLICYQUALINFO *qualinfo; + int i; + + for (i = 0; i < sk_POLICYQUALINFO_num(quals); i++) { + qualinfo = sk_POLICYQUALINFO_value(quals, i); + switch (OBJ_obj2nid(qualinfo->pqualid)) { + case NID_id_qt_cps: + BIO_printf(out, "%*sCPS: %s\n", indent, "", + qualinfo->d.cpsuri->data); + break; + + case NID_id_qt_unotice: + BIO_printf(out, "%*sUser Notice:\n", indent, ""); + print_notice(out, qualinfo->d.usernotice, indent + 2); + break; + + default: + BIO_printf(out, "%*sUnknown Qualifier: ", + indent + 2, ""); + + i2a_ASN1_OBJECT(out, qualinfo->pqualid); + BIO_puts(out, "\n"); + break; + } + } +} + +static void +print_notice(BIO *out, USERNOTICE *notice, int indent) +{ + int i; + + if (notice->noticeref) { + NOTICEREF *ref; + ref = notice->noticeref; + BIO_printf(out, "%*sOrganization: %s\n", indent, "", + ref->organization->data); + BIO_printf(out, "%*sNumber%s: ", indent, "", + sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : ""); + for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) { + ASN1_INTEGER *num; + char *tmp; + num = sk_ASN1_INTEGER_value(ref->noticenos, i); + if (i) + BIO_puts(out, ", "); + tmp = i2s_ASN1_INTEGER(NULL, num); + BIO_puts(out, tmp); + free(tmp); + } + BIO_puts(out, "\n"); + } + if (notice->exptext) + BIO_printf(out, "%*sExplicit Text: %s\n", indent, "", + notice->exptext->data); +} + +void +X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent) +{ + const X509_POLICY_DATA *dat = node->data; + + BIO_printf(out, "%*sPolicy: ", indent, ""); + + i2a_ASN1_OBJECT(out, dat->valid_policy); + BIO_puts(out, "\n"); + BIO_printf(out, "%*s%s\n", indent + 2, "", + node_data_critical(dat) ? "Critical" : "Non Critical"); + if (dat->qualifier_set) + print_qualifiers(out, dat->qualifier_set, indent + 2); + else + BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, ""); +} diff --git a/crypto/libressl/crypto/x509v3/v3_crld.c b/crypto/libressl/crypto/x509v3/v3_crld.c new file mode 100644 index 0000000000..1da58186ae --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_crld.c @@ -0,0 +1,816 @@ +/* $OpenBSD: v3_crld.c,v 1.18 2015/07/25 16:14:29 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2008 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +static void *v2i_crld(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, + int indent); + +const X509V3_EXT_METHOD v3_crld = { + .ext_nid = NID_crl_distribution_points, + .ext_flags = 0, + .it = ASN1_ITEM_ref(CRL_DIST_POINTS), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = v2i_crld, + .i2r = i2r_crldp, + .r2i = NULL, + .usr_data = NULL, +}; + +const X509V3_EXT_METHOD v3_freshest_crl = { + .ext_nid = NID_freshest_crl, + .ext_flags = 0, + .it = ASN1_ITEM_ref(CRL_DIST_POINTS), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = v2i_crld, + .i2r = i2r_crldp, + .r2i = NULL, + .usr_data = NULL, +}; + +static +STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, char *sect) +{ + STACK_OF(CONF_VALUE) *gnsect; + STACK_OF(GENERAL_NAME) *gens; + + if (*sect == '@') + gnsect = X509V3_get_section(ctx, sect + 1); + else + gnsect = X509V3_parse_list(sect); + if (!gnsect) { + X509V3err(X509V3_F_GNAMES_FROM_SECTNAME, + X509V3_R_SECTION_NOT_FOUND); + return NULL; + } + gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect); + if (*sect == '@') + X509V3_section_free(ctx, gnsect); + else + sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free); + return gens; +} + +static int +set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx, CONF_VALUE *cnf) +{ + STACK_OF(GENERAL_NAME) *fnm = NULL; + STACK_OF(X509_NAME_ENTRY) *rnm = NULL; + + if (!strncmp(cnf->name, "fullname", 9)) { + fnm = gnames_from_sectname(ctx, cnf->value); + if (!fnm) + goto err; + } else if (!strcmp(cnf->name, "relativename")) { + int ret; + STACK_OF(CONF_VALUE) *dnsect; + X509_NAME *nm; + nm = X509_NAME_new(); + if (!nm) + return -1; + dnsect = X509V3_get_section(ctx, cnf->value); + if (!dnsect) { + X509V3err(X509V3_F_SET_DIST_POINT_NAME, + X509V3_R_SECTION_NOT_FOUND); + X509_NAME_free(nm); + return -1; + } + ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC); + X509V3_section_free(ctx, dnsect); + rnm = nm->entries; + nm->entries = NULL; + X509_NAME_free(nm); + if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0) + goto err; + /* Since its a name fragment can't have more than one + * RDNSequence + */ + if (sk_X509_NAME_ENTRY_value(rnm, + sk_X509_NAME_ENTRY_num(rnm) - 1)->set) { + X509V3err(X509V3_F_SET_DIST_POINT_NAME, + X509V3_R_INVALID_MULTIPLE_RDNS); + goto err; + } + } else + return 0; + + if (*pdp) { + X509V3err(X509V3_F_SET_DIST_POINT_NAME, + X509V3_R_DISTPOINT_ALREADY_SET); + goto err; + } + + *pdp = DIST_POINT_NAME_new(); + if (!*pdp) + goto err; + if (fnm) { + (*pdp)->type = 0; + (*pdp)->name.fullname = fnm; + } else { + (*pdp)->type = 1; + (*pdp)->name.relativename = rnm; + } + + return 1; + +err: + if (fnm) + sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free); + if (rnm) + sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free); + return -1; +} + +static const BIT_STRING_BITNAME reason_flags[] = { + {0, "Unused", "unused"}, + {1, "Key Compromise", "keyCompromise"}, + {2, "CA Compromise", "CACompromise"}, + {3, "Affiliation Changed", "affiliationChanged"}, + {4, "Superseded", "superseded"}, + {5, "Cessation Of Operation", "cessationOfOperation"}, + {6, "Certificate Hold", "certificateHold"}, + {7, "Privilege Withdrawn", "privilegeWithdrawn"}, + {8, "AA Compromise", "AACompromise"}, + {-1, NULL, NULL} +}; + +static int +set_reasons(ASN1_BIT_STRING **preas, char *value) +{ + STACK_OF(CONF_VALUE) *rsk = NULL; + const BIT_STRING_BITNAME *pbn; + const char *bnam; + int i, ret = 0; + + if (*preas != NULL) + return 0; + rsk = X509V3_parse_list(value); + if (rsk == NULL) + return 0; + for (i = 0; i < sk_CONF_VALUE_num(rsk); i++) { + bnam = sk_CONF_VALUE_value(rsk, i)->name; + if (!*preas) { + *preas = ASN1_BIT_STRING_new(); + if (!*preas) + goto err; + } + for (pbn = reason_flags; pbn->lname; pbn++) { + if (!strcmp(pbn->sname, bnam)) { + if (!ASN1_BIT_STRING_set_bit(*preas, + pbn->bitnum, 1)) + goto err; + break; + } + } + if (!pbn->lname) + goto err; + } + ret = 1; + +err: + sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free); + return ret; +} + +static int +print_reasons(BIO *out, const char *rname, ASN1_BIT_STRING *rflags, int indent) +{ + int first = 1; + const BIT_STRING_BITNAME *pbn; + + BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, ""); + for (pbn = reason_flags; pbn->lname; pbn++) { + if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) { + if (first) + first = 0; + else + BIO_puts(out, ", "); + BIO_puts(out, pbn->lname); + } + } + if (first) + BIO_puts(out, "\n"); + else + BIO_puts(out, "\n"); + return 1; +} + +static DIST_POINT * +crldp_from_section(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +{ + int i; + CONF_VALUE *cnf; + DIST_POINT *point = NULL; + + point = DIST_POINT_new(); + if (!point) + goto err; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + int ret; + cnf = sk_CONF_VALUE_value(nval, i); + ret = set_dist_point_name(&point->distpoint, ctx, cnf); + if (ret > 0) + continue; + if (ret < 0) + goto err; + if (!strcmp(cnf->name, "reasons")) { + if (!set_reasons(&point->reasons, cnf->value)) + goto err; + } + else if (!strcmp(cnf->name, "CRLissuer")) { + point->CRLissuer = + gnames_from_sectname(ctx, cnf->value); + if (!point->CRLissuer) + goto err; + } + } + + return point; + +err: + if (point) + DIST_POINT_free(point); + return NULL; +} + +static void * +v2i_crld(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + STACK_OF(DIST_POINT) *crld = NULL; + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gen = NULL; + CONF_VALUE *cnf; + int i; + + if (!(crld = sk_DIST_POINT_new_null())) + goto merr; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + DIST_POINT *point; + cnf = sk_CONF_VALUE_value(nval, i); + if (!cnf->value) { + STACK_OF(CONF_VALUE) *dpsect; + dpsect = X509V3_get_section(ctx, cnf->name); + if (!dpsect) + goto err; + point = crldp_from_section(ctx, dpsect); + X509V3_section_free(ctx, dpsect); + if (!point) + goto err; + if (!sk_DIST_POINT_push(crld, point)) { + DIST_POINT_free(point); + goto merr; + } + } else { + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + if (!(gens = GENERAL_NAMES_new())) + goto merr; + if (!sk_GENERAL_NAME_push(gens, gen)) + goto merr; + gen = NULL; + if (!(point = DIST_POINT_new())) + goto merr; + if (!sk_DIST_POINT_push(crld, point)) { + DIST_POINT_free(point); + goto merr; + } + if (!(point->distpoint = DIST_POINT_NAME_new())) + goto merr; + point->distpoint->name.fullname = gens; + point->distpoint->type = 0; + gens = NULL; + } + } + return crld; + +merr: + X509V3err(X509V3_F_V2I_CRLD, ERR_R_MALLOC_FAILURE); +err: + GENERAL_NAME_free(gen); + GENERAL_NAMES_free(gens); + sk_DIST_POINT_pop_free(crld, DIST_POINT_free); + return NULL; +} + +static int +dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) +{ + DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval; + + switch (operation) { + case ASN1_OP_NEW_POST: + dpn->dpname = NULL; + break; + + case ASN1_OP_FREE_POST: + if (dpn->dpname) + X509_NAME_free(dpn->dpname); + break; + } + return 1; +} + + +static const ASN1_AUX DIST_POINT_NAME_aux = { + .app_data = NULL, + .flags = 0, + .ref_offset = 0, + .ref_lock = 0, + .asn1_cb = dpn_cb, + .enc_offset = 0, +}; +static const ASN1_TEMPLATE DIST_POINT_NAME_ch_tt[] = { + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = offsetof(DIST_POINT_NAME, name.fullname), + .field_name = "name.fullname", + .item = &GENERAL_NAME_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF, + .tag = 1, + .offset = offsetof(DIST_POINT_NAME, name.relativename), + .field_name = "name.relativename", + .item = &X509_NAME_ENTRY_it, + }, +}; + +const ASN1_ITEM DIST_POINT_NAME_it = { + .itype = ASN1_ITYPE_CHOICE, + .utype = offsetof(DIST_POINT_NAME, type), + .templates = DIST_POINT_NAME_ch_tt, + .tcount = sizeof(DIST_POINT_NAME_ch_tt) / sizeof(ASN1_TEMPLATE), + .funcs = &DIST_POINT_NAME_aux, + .size = sizeof(DIST_POINT_NAME), + .sname = "DIST_POINT_NAME", +}; + + + +DIST_POINT_NAME * +d2i_DIST_POINT_NAME(DIST_POINT_NAME **a, const unsigned char **in, long len) +{ + return (DIST_POINT_NAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &DIST_POINT_NAME_it); +} + +int +i2d_DIST_POINT_NAME(DIST_POINT_NAME *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &DIST_POINT_NAME_it); +} + +DIST_POINT_NAME * +DIST_POINT_NAME_new(void) +{ + return (DIST_POINT_NAME *)ASN1_item_new(&DIST_POINT_NAME_it); +} + +void +DIST_POINT_NAME_free(DIST_POINT_NAME *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &DIST_POINT_NAME_it); +} + +static const ASN1_TEMPLATE DIST_POINT_seq_tt[] = { + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(DIST_POINT, distpoint), + .field_name = "distpoint", + .item = &DIST_POINT_NAME_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(DIST_POINT, reasons), + .field_name = "reasons", + .item = &ASN1_BIT_STRING_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 2, + .offset = offsetof(DIST_POINT, CRLissuer), + .field_name = "CRLissuer", + .item = &GENERAL_NAME_it, + }, +}; + +const ASN1_ITEM DIST_POINT_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = DIST_POINT_seq_tt, + .tcount = sizeof(DIST_POINT_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(DIST_POINT), + .sname = "DIST_POINT", +}; + + +DIST_POINT * +d2i_DIST_POINT(DIST_POINT **a, const unsigned char **in, long len) +{ + return (DIST_POINT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &DIST_POINT_it); +} + +int +i2d_DIST_POINT(DIST_POINT *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &DIST_POINT_it); +} + +DIST_POINT * +DIST_POINT_new(void) +{ + return (DIST_POINT *)ASN1_item_new(&DIST_POINT_it); +} + +void +DIST_POINT_free(DIST_POINT *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &DIST_POINT_it); +} + +static const ASN1_TEMPLATE CRL_DIST_POINTS_item_tt = { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = 0, + .field_name = "CRLDistributionPoints", + .item = &DIST_POINT_it, +}; + +const ASN1_ITEM CRL_DIST_POINTS_it = { + .itype = ASN1_ITYPE_PRIMITIVE, + .utype = -1, + .templates = &CRL_DIST_POINTS_item_tt, + .tcount = 0, + .funcs = NULL, + .size = 0, + .sname = "CRL_DIST_POINTS", +}; + + +CRL_DIST_POINTS * +d2i_CRL_DIST_POINTS(CRL_DIST_POINTS **a, const unsigned char **in, long len) +{ + return (CRL_DIST_POINTS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &CRL_DIST_POINTS_it); +} + +int +i2d_CRL_DIST_POINTS(CRL_DIST_POINTS *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &CRL_DIST_POINTS_it); +} + +CRL_DIST_POINTS * +CRL_DIST_POINTS_new(void) +{ + return (CRL_DIST_POINTS *)ASN1_item_new(&CRL_DIST_POINTS_it); +} + +void +CRL_DIST_POINTS_free(CRL_DIST_POINTS *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &CRL_DIST_POINTS_it); +} + +static const ASN1_TEMPLATE ISSUING_DIST_POINT_seq_tt[] = { + { + .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(ISSUING_DIST_POINT, distpoint), + .field_name = "distpoint", + .item = &DIST_POINT_NAME_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(ISSUING_DIST_POINT, onlyuser), + .field_name = "onlyuser", + .item = &ASN1_FBOOLEAN_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 2, + .offset = offsetof(ISSUING_DIST_POINT, onlyCA), + .field_name = "onlyCA", + .item = &ASN1_FBOOLEAN_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 3, + .offset = offsetof(ISSUING_DIST_POINT, onlysomereasons), + .field_name = "onlysomereasons", + .item = &ASN1_BIT_STRING_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 4, + .offset = offsetof(ISSUING_DIST_POINT, indirectCRL), + .field_name = "indirectCRL", + .item = &ASN1_FBOOLEAN_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 5, + .offset = offsetof(ISSUING_DIST_POINT, onlyattr), + .field_name = "onlyattr", + .item = &ASN1_FBOOLEAN_it, + }, +}; + +const ASN1_ITEM ISSUING_DIST_POINT_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = ISSUING_DIST_POINT_seq_tt, + .tcount = sizeof(ISSUING_DIST_POINT_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(ISSUING_DIST_POINT), + .sname = "ISSUING_DIST_POINT", +}; + + +ISSUING_DIST_POINT * +d2i_ISSUING_DIST_POINT(ISSUING_DIST_POINT **a, const unsigned char **in, long len) +{ + return (ISSUING_DIST_POINT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &ISSUING_DIST_POINT_it); +} + +int +i2d_ISSUING_DIST_POINT(ISSUING_DIST_POINT *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &ISSUING_DIST_POINT_it); +} + +ISSUING_DIST_POINT * +ISSUING_DIST_POINT_new(void) +{ + return (ISSUING_DIST_POINT *)ASN1_item_new(&ISSUING_DIST_POINT_it); +} + +void +ISSUING_DIST_POINT_free(ISSUING_DIST_POINT *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &ISSUING_DIST_POINT_it); +} + +static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, + int indent); +static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); + +const X509V3_EXT_METHOD v3_idp = { + NID_issuing_distribution_point, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(ISSUING_DIST_POINT), + 0, 0, 0, 0, + 0, 0, + 0, + v2i_idp, + i2r_idp, 0, + NULL +}; + +static void * +v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + ISSUING_DIST_POINT *idp = NULL; + CONF_VALUE *cnf; + char *name, *val; + int i, ret; + + idp = ISSUING_DIST_POINT_new(); + if (!idp) + goto merr; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + name = cnf->name; + val = cnf->value; + ret = set_dist_point_name(&idp->distpoint, ctx, cnf); + if (ret > 0) + continue; + if (ret < 0) + goto err; + if (!strcmp(name, "onlyuser")) { + if (!X509V3_get_value_bool(cnf, &idp->onlyuser)) + goto err; + } + else if (!strcmp(name, "onlyCA")) { + if (!X509V3_get_value_bool(cnf, &idp->onlyCA)) + goto err; + } + else if (!strcmp(name, "onlyAA")) { + if (!X509V3_get_value_bool(cnf, &idp->onlyattr)) + goto err; + } + else if (!strcmp(name, "indirectCRL")) { + if (!X509V3_get_value_bool(cnf, &idp->indirectCRL)) + goto err; + } + else if (!strcmp(name, "onlysomereasons")) { + if (!set_reasons(&idp->onlysomereasons, val)) + goto err; + } else { + X509V3err(X509V3_F_V2I_IDP, X509V3_R_INVALID_NAME); + X509V3_conf_err(cnf); + goto err; + } + } + return idp; + +merr: + X509V3err(X509V3_F_V2I_IDP, ERR_R_MALLOC_FAILURE); +err: + ISSUING_DIST_POINT_free(idp); + return NULL; +} + +static int +print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent) +{ + int i; + + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + BIO_printf(out, "%*s", indent + 2, ""); + GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i)); + BIO_puts(out, "\n"); + } + return 1; +} + +static int +print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent) +{ + if (dpn->type == 0) { + BIO_printf(out, "%*sFull Name:\n", indent, ""); + print_gens(out, dpn->name.fullname, indent); + } else { + X509_NAME ntmp; + ntmp.entries = dpn->name.relativename; + BIO_printf(out, "%*sRelative Name:\n%*s", + indent, "", indent + 2, ""); + X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE); + BIO_puts(out, "\n"); + } + return 1; +} + +static int +i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, int indent) +{ + ISSUING_DIST_POINT *idp = pidp; + + if (idp->distpoint) + print_distpoint(out, idp->distpoint, indent); + if (idp->onlyuser > 0) + BIO_printf(out, "%*sOnly User Certificates\n", indent, ""); + if (idp->onlyCA > 0) + BIO_printf(out, "%*sOnly CA Certificates\n", indent, ""); + if (idp->indirectCRL > 0) + BIO_printf(out, "%*sIndirect CRL\n", indent, ""); + if (idp->onlysomereasons) + print_reasons(out, "Only Some Reasons", + idp->onlysomereasons, indent); + if (idp->onlyattr > 0) + BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, ""); + if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0) && + (idp->indirectCRL <= 0) && !idp->onlysomereasons && + (idp->onlyattr <= 0)) + BIO_printf(out, "%*s\n", indent, ""); + + return 1; +} + +static int +i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, int indent) +{ + STACK_OF(DIST_POINT) *crld = pcrldp; + DIST_POINT *point; + int i; + + for (i = 0; i < sk_DIST_POINT_num(crld); i++) { + BIO_puts(out, "\n"); + point = sk_DIST_POINT_value(crld, i); + if (point->distpoint) + print_distpoint(out, point->distpoint, indent); + if (point->reasons) + print_reasons(out, "Reasons", point->reasons, + indent); + if (point->CRLissuer) { + BIO_printf(out, "%*sCRL Issuer:\n", indent, ""); + print_gens(out, point->CRLissuer, indent); + } + } + return 1; +} + +int +DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname) +{ + int i; + STACK_OF(X509_NAME_ENTRY) *frag; + X509_NAME_ENTRY *ne; + + if (!dpn || (dpn->type != 1)) + return 1; + frag = dpn->name.relativename; + dpn->dpname = X509_NAME_dup(iname); + if (!dpn->dpname) + return 0; + for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) { + ne = sk_X509_NAME_ENTRY_value(frag, i); + if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) { + X509_NAME_free(dpn->dpname); + dpn->dpname = NULL; + return 0; + } + } + /* generate cached encoding of name */ + if (i2d_X509_NAME(dpn->dpname, NULL) < 0) { + X509_NAME_free(dpn->dpname); + dpn->dpname = NULL; + return 0; + } + return 1; +} diff --git a/crypto/libressl/crypto/x509v3/v3_enum.c b/crypto/libressl/crypto/x509v3/v3_enum.c new file mode 100644 index 0000000000..3b418d04a1 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_enum.c @@ -0,0 +1,107 @@ +/* $OpenBSD: v3_enum.c,v 1.10 2014/07/13 16:03:10 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +static ENUMERATED_NAMES crl_reasons[] = { + {CRL_REASON_UNSPECIFIED, "Unspecified", "unspecified"}, + {CRL_REASON_KEY_COMPROMISE, "Key Compromise", "keyCompromise"}, + {CRL_REASON_CA_COMPROMISE, "CA Compromise", "CACompromise"}, + {CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", "affiliationChanged"}, + {CRL_REASON_SUPERSEDED, "Superseded", "superseded"}, + {CRL_REASON_CESSATION_OF_OPERATION, + "Cessation Of Operation", "cessationOfOperation"}, + {CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold"}, + {CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL"}, + {CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", "privilegeWithdrawn"}, + {CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise"}, + {-1, NULL, NULL} +}; + +const X509V3_EXT_METHOD v3_crl_reason = { + .ext_nid = NID_crl_reason, + .ext_flags = 0, + .it = ASN1_ITEM_ref(ASN1_ENUMERATED), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = crl_reasons, +}; + +char * +i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *e) +{ + ENUMERATED_NAMES *enam; + long strval; + + strval = ASN1_ENUMERATED_get(e); + for (enam = method->usr_data; enam->lname; enam++) { + if (strval == enam->bitnum) + return strdup(enam->lname); + } + return i2s_ASN1_ENUMERATED(method, e); +} diff --git a/crypto/libressl/crypto/x509v3/v3_extku.c b/crypto/libressl/crypto/x509v3/v3_extku.c new file mode 100644 index 0000000000..978b5c9e10 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_extku.c @@ -0,0 +1,205 @@ +/* $OpenBSD: v3_extku.c,v 1.12 2015/07/25 16:00:14 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include + +static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE( + const X509V3_EXT_METHOD *method, void *eku, STACK_OF(CONF_VALUE) *extlist); + +const X509V3_EXT_METHOD v3_ext_ku = { + .ext_nid = NID_ext_key_usage, + .ext_flags = 0, + .it = ASN1_ITEM_ref(EXTENDED_KEY_USAGE), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = i2v_EXTENDED_KEY_USAGE, + .v2i = v2i_EXTENDED_KEY_USAGE, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +/* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */ +const X509V3_EXT_METHOD v3_ocsp_accresp = { + .ext_nid = NID_id_pkix_OCSP_acceptableResponses, + .ext_flags = 0, + .it = ASN1_ITEM_ref(EXTENDED_KEY_USAGE), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = i2v_EXTENDED_KEY_USAGE, + .v2i = v2i_EXTENDED_KEY_USAGE, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +static const ASN1_TEMPLATE EXTENDED_KEY_USAGE_item_tt = { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = 0, + .field_name = "EXTENDED_KEY_USAGE", + .item = &ASN1_OBJECT_it, +}; + +const ASN1_ITEM EXTENDED_KEY_USAGE_it = { + .itype = ASN1_ITYPE_PRIMITIVE, + .utype = -1, + .templates = &EXTENDED_KEY_USAGE_item_tt, + .tcount = 0, + .funcs = NULL, + .size = 0, + .sname = "EXTENDED_KEY_USAGE", +}; + + +EXTENDED_KEY_USAGE * +d2i_EXTENDED_KEY_USAGE(EXTENDED_KEY_USAGE **a, const unsigned char **in, long len) +{ + return (EXTENDED_KEY_USAGE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &EXTENDED_KEY_USAGE_it); +} + +int +i2d_EXTENDED_KEY_USAGE(EXTENDED_KEY_USAGE *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &EXTENDED_KEY_USAGE_it); +} + +EXTENDED_KEY_USAGE * +EXTENDED_KEY_USAGE_new(void) +{ + return (EXTENDED_KEY_USAGE *)ASN1_item_new(&EXTENDED_KEY_USAGE_it); +} + +void +EXTENDED_KEY_USAGE_free(EXTENDED_KEY_USAGE *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &EXTENDED_KEY_USAGE_it); +} + +static STACK_OF(CONF_VALUE) * +i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, void *a, + STACK_OF(CONF_VALUE) *ext_list) +{ + EXTENDED_KEY_USAGE *eku = a; + int i; + ASN1_OBJECT *obj; + char obj_tmp[80]; + + for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) { + obj = sk_ASN1_OBJECT_value(eku, i); + i2t_ASN1_OBJECT(obj_tmp, 80, obj); + X509V3_add_value(NULL, obj_tmp, &ext_list); + } + return ext_list; +} + +static void * +v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + EXTENDED_KEY_USAGE *extku; + char *extval; + ASN1_OBJECT *objtmp; + CONF_VALUE *val; + int i; + + if (!(extku = sk_ASN1_OBJECT_new_null())) { + X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE, + ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (val->value) + extval = val->value; + else + extval = val->name; + if (!(objtmp = OBJ_txt2obj(extval, 0))) { + sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free); + X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE, + X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return NULL; + } + if (sk_ASN1_OBJECT_push(extku, objtmp) == 0) { + ASN1_OBJECT_free(objtmp); + sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free); + X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE, + ERR_R_MALLOC_FAILURE); + return NULL; + } + } + return extku; +} diff --git a/crypto/libressl/crypto/x509v3/v3_genn.c b/crypto/libressl/crypto/x509v3/v3_genn.c new file mode 100644 index 0000000000..c76f9a97fe --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_genn.c @@ -0,0 +1,474 @@ +/* $OpenBSD: v3_genn.c,v 1.11 2015/07/25 16:00:14 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2008 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + +#include + +#include +#include +#include + +static const ASN1_TEMPLATE OTHERNAME_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(OTHERNAME, type_id), + .field_name = "type_id", + .item = &ASN1_OBJECT_it, + }, + /* Maybe have a true ANY DEFINED BY later */ + { + .flags = ASN1_TFLG_EXPLICIT, + .tag = 0, + .offset = offsetof(OTHERNAME, value), + .field_name = "value", + .item = &ASN1_ANY_it, + }, +}; + +const ASN1_ITEM OTHERNAME_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = OTHERNAME_seq_tt, + .tcount = sizeof(OTHERNAME_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(OTHERNAME), + .sname = "OTHERNAME", +}; + + +OTHERNAME * +d2i_OTHERNAME(OTHERNAME **a, const unsigned char **in, long len) +{ + return (OTHERNAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &OTHERNAME_it); +} + +int +i2d_OTHERNAME(OTHERNAME *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &OTHERNAME_it); +} + +OTHERNAME * +OTHERNAME_new(void) +{ + return (OTHERNAME *)ASN1_item_new(&OTHERNAME_it); +} + +void +OTHERNAME_free(OTHERNAME *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &OTHERNAME_it); +} + +static const ASN1_TEMPLATE EDIPARTYNAME_seq_tt[] = { + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(EDIPARTYNAME, nameAssigner), + .field_name = "nameAssigner", + .item = &DIRECTORYSTRING_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(EDIPARTYNAME, partyName), + .field_name = "partyName", + .item = &DIRECTORYSTRING_it, + }, +}; + +const ASN1_ITEM EDIPARTYNAME_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = EDIPARTYNAME_seq_tt, + .tcount = sizeof(EDIPARTYNAME_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(EDIPARTYNAME), + .sname = "EDIPARTYNAME", +}; + + +EDIPARTYNAME * +d2i_EDIPARTYNAME(EDIPARTYNAME **a, const unsigned char **in, long len) +{ + return (EDIPARTYNAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &EDIPARTYNAME_it); +} + +int +i2d_EDIPARTYNAME(EDIPARTYNAME *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &EDIPARTYNAME_it); +} + +EDIPARTYNAME * +EDIPARTYNAME_new(void) +{ + return (EDIPARTYNAME *)ASN1_item_new(&EDIPARTYNAME_it); +} + +void +EDIPARTYNAME_free(EDIPARTYNAME *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &EDIPARTYNAME_it); +} + +static const ASN1_TEMPLATE GENERAL_NAME_ch_tt[] = { + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = GEN_OTHERNAME, + .offset = offsetof(GENERAL_NAME, d.otherName), + .field_name = "d.otherName", + .item = &OTHERNAME_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = GEN_EMAIL, + .offset = offsetof(GENERAL_NAME, d.rfc822Name), + .field_name = "d.rfc822Name", + .item = &ASN1_IA5STRING_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = GEN_DNS, + .offset = offsetof(GENERAL_NAME, d.dNSName), + .field_name = "d.dNSName", + .item = &ASN1_IA5STRING_it, + }, + /* Don't decode this */ + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = GEN_X400, + .offset = offsetof(GENERAL_NAME, d.x400Address), + .field_name = "d.x400Address", + .item = &ASN1_SEQUENCE_it, + }, + /* X509_NAME is a CHOICE type so use EXPLICIT */ + { + .flags = ASN1_TFLG_EXPLICIT, + .tag = GEN_DIRNAME, + .offset = offsetof(GENERAL_NAME, d.directoryName), + .field_name = "d.directoryName", + .item = &X509_NAME_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = GEN_EDIPARTY, + .offset = offsetof(GENERAL_NAME, d.ediPartyName), + .field_name = "d.ediPartyName", + .item = &EDIPARTYNAME_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = GEN_URI, + .offset = offsetof(GENERAL_NAME, d.uniformResourceIdentifier), + .field_name = "d.uniformResourceIdentifier", + .item = &ASN1_IA5STRING_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = GEN_IPADD, + .offset = offsetof(GENERAL_NAME, d.iPAddress), + .field_name = "d.iPAddress", + .item = &ASN1_OCTET_STRING_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT, + .tag = GEN_RID, + .offset = offsetof(GENERAL_NAME, d.registeredID), + .field_name = "d.registeredID", + .item = &ASN1_OBJECT_it, + }, +}; + +const ASN1_ITEM GENERAL_NAME_it = { + .itype = ASN1_ITYPE_CHOICE, + .utype = offsetof(GENERAL_NAME, type), + .templates = GENERAL_NAME_ch_tt, + .tcount = sizeof(GENERAL_NAME_ch_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(GENERAL_NAME), + .sname = "GENERAL_NAME", +}; + + +GENERAL_NAME * +d2i_GENERAL_NAME(GENERAL_NAME **a, const unsigned char **in, long len) +{ + return (GENERAL_NAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &GENERAL_NAME_it); +} + +int +i2d_GENERAL_NAME(GENERAL_NAME *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &GENERAL_NAME_it); +} + +GENERAL_NAME * +GENERAL_NAME_new(void) +{ + return (GENERAL_NAME *)ASN1_item_new(&GENERAL_NAME_it); +} + +void +GENERAL_NAME_free(GENERAL_NAME *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &GENERAL_NAME_it); +} + +static const ASN1_TEMPLATE GENERAL_NAMES_item_tt = { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = 0, + .field_name = "GeneralNames", + .item = &GENERAL_NAME_it, +}; + +const ASN1_ITEM GENERAL_NAMES_it = { + .itype = ASN1_ITYPE_PRIMITIVE, + .utype = -1, + .templates = &GENERAL_NAMES_item_tt, + .tcount = 0, + .funcs = NULL, + .size = 0, + .sname = "GENERAL_NAMES", +}; + + +GENERAL_NAMES * +d2i_GENERAL_NAMES(GENERAL_NAMES **a, const unsigned char **in, long len) +{ + return (GENERAL_NAMES *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &GENERAL_NAMES_it); +} + +int +i2d_GENERAL_NAMES(GENERAL_NAMES *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &GENERAL_NAMES_it); +} + +GENERAL_NAMES * +GENERAL_NAMES_new(void) +{ + return (GENERAL_NAMES *)ASN1_item_new(&GENERAL_NAMES_it); +} + +void +GENERAL_NAMES_free(GENERAL_NAMES *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &GENERAL_NAMES_it); +} + +GENERAL_NAME * +GENERAL_NAME_dup(GENERAL_NAME *a) +{ + return ASN1_item_dup(&GENERAL_NAME_it, a); +} + +/* Returns 0 if they are equal, != 0 otherwise. */ +int +GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b) +{ + int result = -1; + + if (!a || !b || a->type != b->type) + return -1; + switch (a->type) { + case GEN_X400: + case GEN_EDIPARTY: + result = ASN1_TYPE_cmp(a->d.other, b->d.other); + break; + + case GEN_OTHERNAME: + result = OTHERNAME_cmp(a->d.otherName, b->d.otherName); + break; + + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5); + break; + + case GEN_DIRNAME: + result = X509_NAME_cmp(a->d.dirn, b->d.dirn); + break; + + case GEN_IPADD: + result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip); + break; + + case GEN_RID: + result = OBJ_cmp(a->d.rid, b->d.rid); + break; + } + return result; +} + +/* Returns 0 if they are equal, != 0 otherwise. */ +int +OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b) +{ + int result = -1; + + if (!a || !b) + return -1; + /* Check their type first. */ + if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0) + return result; + /* Check the value. */ + result = ASN1_TYPE_cmp(a->value, b->value); + return result; +} + +void +GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value) +{ + switch (type) { + case GEN_X400: + case GEN_EDIPARTY: + a->d.other = value; + break; + + case GEN_OTHERNAME: + a->d.otherName = value; + break; + + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + a->d.ia5 = value; + break; + + case GEN_DIRNAME: + a->d.dirn = value; + break; + + case GEN_IPADD: + a->d.ip = value; + break; + + case GEN_RID: + a->d.rid = value; + break; + } + a->type = type; +} + +void * +GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype) +{ + if (ptype) + *ptype = a->type; + switch (a->type) { + case GEN_X400: + case GEN_EDIPARTY: + return a->d.other; + + case GEN_OTHERNAME: + return a->d.otherName; + + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + return a->d.ia5; + + case GEN_DIRNAME: + return a->d.dirn; + + case GEN_IPADD: + return a->d.ip; + + case GEN_RID: + return a->d.rid; + + default: + return NULL; + } +} + +int +GENERAL_NAME_set0_othername(GENERAL_NAME *gen, ASN1_OBJECT *oid, + ASN1_TYPE *value) +{ + OTHERNAME *oth; + + oth = OTHERNAME_new(); + if (!oth) + return 0; + oth->type_id = oid; + oth->value = value; + GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth); + return 1; +} + +int +GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, ASN1_OBJECT **poid, + ASN1_TYPE **pvalue) +{ + if (gen->type != GEN_OTHERNAME) + return 0; + if (poid) + *poid = gen->d.otherName->type_id; + if (pvalue) + *pvalue = gen->d.otherName->value; + return 1; +} diff --git a/crypto/libressl/crypto/x509v3/v3_ia5.c b/crypto/libressl/crypto/x509v3/v3_ia5.c new file mode 100644 index 0000000000..75a436cd12 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_ia5.c @@ -0,0 +1,239 @@ +/* $OpenBSD: v3_ia5.c,v 1.14 2015/07/29 16:13:48 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include + +static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5); +static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str); + +const X509V3_EXT_METHOD v3_ns_ia5_list[] = { + { + .ext_nid = NID_netscape_base_url, + .ext_flags = 0, + .it = ASN1_ITEM_ref(ASN1_IA5STRING), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, + .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, + { + .ext_nid = NID_netscape_revocation_url, + .ext_flags = 0, + .it = ASN1_ITEM_ref(ASN1_IA5STRING), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, + .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, + { + .ext_nid = NID_netscape_ca_revocation_url, + .ext_flags = 0, + .it = ASN1_ITEM_ref(ASN1_IA5STRING), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, + .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, + { + .ext_nid = NID_netscape_renewal_url, + .ext_flags = 0, + .it = ASN1_ITEM_ref(ASN1_IA5STRING), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, + .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, + { + .ext_nid = NID_netscape_ca_policy_url, + .ext_flags = 0, + .it = ASN1_ITEM_ref(ASN1_IA5STRING), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, + .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, + { + .ext_nid = NID_netscape_ssl_server_name, + .ext_flags = 0, + .it = ASN1_ITEM_ref(ASN1_IA5STRING), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, + .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, + { + .ext_nid = NID_netscape_comment, + .ext_flags = 0, + .it = ASN1_ITEM_ref(ASN1_IA5STRING), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, + .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, + { + .ext_nid = -1, + .ext_flags = 0, + .it = NULL, + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, + }, +}; + +static char * +i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5) +{ + char *tmp; + + if (!ia5 || !ia5->length) + return NULL; + if (!(tmp = malloc(ia5->length + 1))) { + X509V3err(X509V3_F_I2S_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE); + return NULL; + } + memcpy(tmp, ia5->data, ia5->length); + tmp[ia5->length] = 0; + return tmp; +} + +static ASN1_IA5STRING * +s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str) +{ + ASN1_IA5STRING *ia5; + if (!str) { + X509V3err(X509V3_F_S2I_ASN1_IA5STRING, + X509V3_R_INVALID_NULL_ARGUMENT); + return NULL; + } + if (!(ia5 = ASN1_IA5STRING_new())) + goto err; + if (!ASN1_STRING_set((ASN1_STRING *)ia5, (unsigned char*)str, + strlen(str))) { + ASN1_IA5STRING_free(ia5); + goto err; + } + return ia5; + +err: + X509V3err(X509V3_F_S2I_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE); + return NULL; +} diff --git a/crypto/libressl/crypto/x509v3/v3_info.c b/crypto/libressl/crypto/x509v3/v3_info.c new file mode 100644 index 0000000000..69643ac0d5 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_info.c @@ -0,0 +1,307 @@ +/* $OpenBSD: v3_info.c,v 1.22 2015/07/25 16:00:14 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS( + X509V3_EXT_METHOD *method, AUTHORITY_INFO_ACCESS *ainfo, + STACK_OF(CONF_VALUE) *ret); +static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS( + X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); + +const X509V3_EXT_METHOD v3_info = { + .ext_nid = NID_info_access, + .ext_flags = X509V3_EXT_MULTILINE, + .it = ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = (X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS, + .v2i = (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +const X509V3_EXT_METHOD v3_sinfo = { + .ext_nid = NID_sinfo_access, + .ext_flags = X509V3_EXT_MULTILINE, + .it = ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = (X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS, + .v2i = (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +static const ASN1_TEMPLATE ACCESS_DESCRIPTION_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(ACCESS_DESCRIPTION, method), + .field_name = "method", + .item = &ASN1_OBJECT_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(ACCESS_DESCRIPTION, location), + .field_name = "location", + .item = &GENERAL_NAME_it, + }, +}; + +const ASN1_ITEM ACCESS_DESCRIPTION_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = ACCESS_DESCRIPTION_seq_tt, + .tcount = sizeof(ACCESS_DESCRIPTION_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(ACCESS_DESCRIPTION), + .sname = "ACCESS_DESCRIPTION", +}; + + +ACCESS_DESCRIPTION * +d2i_ACCESS_DESCRIPTION(ACCESS_DESCRIPTION **a, const unsigned char **in, long len) +{ + return (ACCESS_DESCRIPTION *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &ACCESS_DESCRIPTION_it); +} + +int +i2d_ACCESS_DESCRIPTION(ACCESS_DESCRIPTION *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &ACCESS_DESCRIPTION_it); +} + +ACCESS_DESCRIPTION * +ACCESS_DESCRIPTION_new(void) +{ + return (ACCESS_DESCRIPTION *)ASN1_item_new(&ACCESS_DESCRIPTION_it); +} + +void +ACCESS_DESCRIPTION_free(ACCESS_DESCRIPTION *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &ACCESS_DESCRIPTION_it); +} + +static const ASN1_TEMPLATE AUTHORITY_INFO_ACCESS_item_tt = { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = 0, + .field_name = "GeneralNames", + .item = &ACCESS_DESCRIPTION_it, +}; + +const ASN1_ITEM AUTHORITY_INFO_ACCESS_it = { + .itype = ASN1_ITYPE_PRIMITIVE, + .utype = -1, + .templates = &AUTHORITY_INFO_ACCESS_item_tt, + .tcount = 0, + .funcs = NULL, + .size = 0, + .sname = "AUTHORITY_INFO_ACCESS", +}; + + +AUTHORITY_INFO_ACCESS * +d2i_AUTHORITY_INFO_ACCESS(AUTHORITY_INFO_ACCESS **a, const unsigned char **in, long len) +{ + return (AUTHORITY_INFO_ACCESS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &AUTHORITY_INFO_ACCESS_it); +} + +int +i2d_AUTHORITY_INFO_ACCESS(AUTHORITY_INFO_ACCESS *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &AUTHORITY_INFO_ACCESS_it); +} + +AUTHORITY_INFO_ACCESS * +AUTHORITY_INFO_ACCESS_new(void) +{ + return (AUTHORITY_INFO_ACCESS *)ASN1_item_new(&AUTHORITY_INFO_ACCESS_it); +} + +void +AUTHORITY_INFO_ACCESS_free(AUTHORITY_INFO_ACCESS *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &AUTHORITY_INFO_ACCESS_it); +} + +static STACK_OF(CONF_VALUE) * +i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method, + AUTHORITY_INFO_ACCESS *ainfo, STACK_OF(CONF_VALUE) *ret) +{ + ACCESS_DESCRIPTION *desc; + int i, nlen; + char objtmp[80], *ntmp; + CONF_VALUE *vtmp; + + for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) { + desc = sk_ACCESS_DESCRIPTION_value(ainfo, i); + ret = i2v_GENERAL_NAME(method, desc->location, ret); + if (!ret) + break; + vtmp = sk_CONF_VALUE_value(ret, i); + i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method); + nlen = strlen(objtmp) + strlen(vtmp->name) + 5; + ntmp = malloc(nlen); + if (!ntmp) { + X509V3err(X509V3_F_I2V_AUTHORITY_INFO_ACCESS, + ERR_R_MALLOC_FAILURE); + return NULL; + } + strlcpy(ntmp, objtmp, nlen); + strlcat(ntmp, " - ", nlen); + strlcat(ntmp, vtmp->name, nlen); + free(vtmp->name); + vtmp->name = ntmp; + + } + if (!ret) + return sk_CONF_VALUE_new_null(); + return ret; +} + +static AUTHORITY_INFO_ACCESS * +v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + AUTHORITY_INFO_ACCESS *ainfo = NULL; + CONF_VALUE *cnf, ctmp; + ACCESS_DESCRIPTION *acc; + int i, objlen; + char *objtmp, *ptmp; + + if (!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) { + X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, + ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if ((acc = ACCESS_DESCRIPTION_new()) == NULL) { + X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, + ERR_R_MALLOC_FAILURE); + goto err; + } + if (sk_ACCESS_DESCRIPTION_push(ainfo, acc) == 0) { + ACCESS_DESCRIPTION_free(acc); + X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, + ERR_R_MALLOC_FAILURE); + goto err; + } + ptmp = strchr(cnf->name, ';'); + if (!ptmp) { + X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, + X509V3_R_INVALID_SYNTAX); + goto err; + } + objlen = ptmp - cnf->name; + ctmp.name = ptmp + 1; + ctmp.value = cnf->value; + if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0)) + goto err; + if (!(objtmp = malloc(objlen + 1))) { + X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, + ERR_R_MALLOC_FAILURE); + goto err; + } + strlcpy(objtmp, cnf->name, objlen + 1); + acc->method = OBJ_txt2obj(objtmp, 0); + if (!acc->method) { + X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, + X509V3_R_BAD_OBJECT); + ERR_asprintf_error_data("value=%s", objtmp); + free(objtmp); + goto err; + } + free(objtmp); + } + return ainfo; + +err: + sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free); + return NULL; +} + +int +i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION* a) +{ + i2a_ASN1_OBJECT(bp, a->method); + return 2; +} diff --git a/crypto/libressl/crypto/x509v3/v3_int.c b/crypto/libressl/crypto/x509v3/v3_int.c new file mode 100644 index 0000000000..a745958158 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_int.c @@ -0,0 +1,110 @@ +/* $OpenBSD: v3_int.c,v 1.9 2014/07/11 08:44:49 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +const X509V3_EXT_METHOD v3_crl_num = { + .ext_nid = NID_crl_number, + .ext_flags = 0, + .it = ASN1_ITEM_ref(ASN1_INTEGER), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_INTEGER, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +const X509V3_EXT_METHOD v3_delta_crl = { + .ext_nid = NID_delta_crl, + .ext_flags = 0, + .it = ASN1_ITEM_ref(ASN1_INTEGER), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_INTEGER, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +static void * +s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx, char *value) +{ + return s2i_ASN1_INTEGER(meth, value); +} + +const X509V3_EXT_METHOD v3_inhibit_anyp = { + NID_inhibit_any_policy, 0, ASN1_ITEM_ref(ASN1_INTEGER), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_ASN1_INTEGER, + (X509V3_EXT_S2I)s2i_asn1_int, + 0, 0, 0, 0, + NULL +}; diff --git a/crypto/libressl/crypto/x509v3/v3_lib.c b/crypto/libressl/crypto/x509v3/v3_lib.c new file mode 100644 index 0000000000..f3eed71b8a --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_lib.c @@ -0,0 +1,345 @@ +/* $OpenBSD: v3_lib.c,v 1.13 2014/07/11 08:44:49 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* X509 v3 extension utilities */ + +#include + +#include +#include +#include + +#include "ext_dat.h" + +static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL; + +static int ext_cmp(const X509V3_EXT_METHOD * const *a, + const X509V3_EXT_METHOD * const *b); +static void ext_list_free(X509V3_EXT_METHOD *ext); + +int +X509V3_EXT_add(X509V3_EXT_METHOD *ext) +{ + if (!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_cmp))) { + X509V3err(X509V3_F_X509V3_EXT_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) { + X509V3err(X509V3_F_X509V3_EXT_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +static int +ext_cmp(const X509V3_EXT_METHOD * const *a, const X509V3_EXT_METHOD * const *b) +{ + return ((*a)->ext_nid - (*b)->ext_nid); +} + +DECLARE_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *, + const X509V3_EXT_METHOD *, ext); +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *, + const X509V3_EXT_METHOD *, ext); + +const X509V3_EXT_METHOD * +X509V3_EXT_get_nid(int nid) +{ + X509V3_EXT_METHOD tmp; + const X509V3_EXT_METHOD *t = &tmp, * const *ret; + int idx; + + if (nid < 0) + return NULL; + tmp.ext_nid = nid; + ret = OBJ_bsearch_ext(&t, standard_exts, STANDARD_EXTENSION_COUNT); + if (ret) + return *ret; + if (!ext_list) + return NULL; + idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp); + if (idx == -1) + return NULL; + return sk_X509V3_EXT_METHOD_value(ext_list, idx); +} + +const X509V3_EXT_METHOD * +X509V3_EXT_get(X509_EXTENSION *ext) +{ + int nid; + + if ((nid = OBJ_obj2nid(ext->object)) == NID_undef) + return NULL; + return X509V3_EXT_get_nid(nid); +} + +int +X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist) +{ + for (; extlist->ext_nid!=-1; extlist++) + if (!X509V3_EXT_add(extlist)) + return 0; + return 1; +} + +int +X509V3_EXT_add_alias(int nid_to, int nid_from) +{ + const X509V3_EXT_METHOD *ext; + X509V3_EXT_METHOD *tmpext; + + if (!(ext = X509V3_EXT_get_nid(nid_from))) { + X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS, + X509V3_R_EXTENSION_NOT_FOUND); + return 0; + } + if (!(tmpext = malloc(sizeof(X509V3_EXT_METHOD)))) { + X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS, ERR_R_MALLOC_FAILURE); + return 0; + } + *tmpext = *ext; + tmpext->ext_nid = nid_to; + tmpext->ext_flags |= X509V3_EXT_DYNAMIC; + return X509V3_EXT_add(tmpext); +} + +void +X509V3_EXT_cleanup(void) +{ + sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free); + ext_list = NULL; +} + +static void +ext_list_free(X509V3_EXT_METHOD *ext) +{ + if (ext->ext_flags & X509V3_EXT_DYNAMIC) + free(ext); +} + +/* Legacy function: we don't need to add standard extensions + * any more because they are now kept in ext_dat.h. + */ + +int +X509V3_add_standard_extensions(void) +{ + return 1; +} + +/* Return an extension internal structure */ + +void * +X509V3_EXT_d2i(X509_EXTENSION *ext) +{ + const X509V3_EXT_METHOD *method; + const unsigned char *p; + + if (!(method = X509V3_EXT_get(ext))) + return NULL; + p = ext->value->data; + if (method->it) + return ASN1_item_d2i(NULL, &p, ext->value->length, + ASN1_ITEM_ptr(method->it)); + return method->d2i(NULL, &p, ext->value->length); +} + +/* Get critical flag and decoded version of extension from a NID. + * The "idx" variable returns the last found extension and can + * be used to retrieve multiple extensions of the same NID. + * However multiple extensions with the same NID is usually + * due to a badly encoded certificate so if idx is NULL we + * choke if multiple extensions exist. + * The "crit" variable is set to the critical value. + * The return value is the decoded extension or NULL on + * error. The actual error can have several different causes, + * the value of *crit reflects the cause: + * >= 0, extension found but not decoded (reflects critical value). + * -1 extension not found. + * -2 extension occurs more than once. + */ + +void * +X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx) +{ + int lastpos, i; + X509_EXTENSION *ex, *found_ex = NULL; + + if (!x) { + if (idx) + *idx = -1; + if (crit) + *crit = -1; + return NULL; + } + if (idx) + lastpos = *idx + 1; + else + lastpos = 0; + if (lastpos < 0) + lastpos = 0; + for (i = lastpos; i < sk_X509_EXTENSION_num(x); i++) { + ex = sk_X509_EXTENSION_value(x, i); + if (OBJ_obj2nid(ex->object) == nid) { + if (idx) { + *idx = i; + found_ex = ex; + break; + } else if (found_ex) { + /* Found more than one */ + if (crit) + *crit = -2; + return NULL; + } + found_ex = ex; + } + } + if (found_ex) { + /* Found it */ + if (crit) + *crit = X509_EXTENSION_get_critical(found_ex); + return X509V3_EXT_d2i(found_ex); + } + + /* Extension not found */ + if (idx) + *idx = -1; + if (crit) + *crit = -1; + return NULL; +} + +/* This function is a general extension append, replace and delete utility. + * The precise operation is governed by the 'flags' value. The 'crit' and + * 'value' arguments (if relevant) are the extensions internal structure. + */ + +int +X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, + int crit, unsigned long flags) +{ + int extidx = -1; + int errcode; + X509_EXTENSION *ext, *extmp; + unsigned long ext_op = flags & X509V3_ADD_OP_MASK; + + /* If appending we don't care if it exists, otherwise + * look for existing extension. + */ + if (ext_op != X509V3_ADD_APPEND) + extidx = X509v3_get_ext_by_NID(*x, nid, -1); + + /* See if extension exists */ + if (extidx >= 0) { + /* If keep existing, nothing to do */ + if (ext_op == X509V3_ADD_KEEP_EXISTING) + return 1; + /* If default then its an error */ + if (ext_op == X509V3_ADD_DEFAULT) { + errcode = X509V3_R_EXTENSION_EXISTS; + goto err; + } + /* If delete, just delete it */ + if (ext_op == X509V3_ADD_DELETE) { + if (!sk_X509_EXTENSION_delete(*x, extidx)) + return -1; + return 1; + } + } else { + /* If replace existing or delete, error since + * extension must exist + */ + if ((ext_op == X509V3_ADD_REPLACE_EXISTING) || + (ext_op == X509V3_ADD_DELETE)) { + errcode = X509V3_R_EXTENSION_NOT_FOUND; + goto err; + } + } + + /* If we get this far then we have to create an extension: + * could have some flags for alternative encoding schemes... + */ + + ext = X509V3_EXT_i2d(nid, crit, value); + + if (!ext) { + X509V3err(X509V3_F_X509V3_ADD1_I2D, + X509V3_R_ERROR_CREATING_EXTENSION); + return 0; + } + + /* If extension exists replace it.. */ + if (extidx >= 0) { + extmp = sk_X509_EXTENSION_value(*x, extidx); + X509_EXTENSION_free(extmp); + if (!sk_X509_EXTENSION_set(*x, extidx, ext)) + return -1; + return 1; + } + + if (!*x && !(*x = sk_X509_EXTENSION_new_null())) + return -1; + if (!sk_X509_EXTENSION_push(*x, ext)) + return -1; + + return 1; + +err: + if (!(flags & X509V3_ADD_SILENT)) + X509V3err(X509V3_F_X509V3_ADD1_I2D, errcode); + return 0; +} diff --git a/crypto/libressl/crypto/x509v3/v3_ncons.c b/crypto/libressl/crypto/x509v3/v3_ncons.c new file mode 100644 index 0000000000..b69801295c --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_ncons.c @@ -0,0 +1,560 @@ +/* $OpenBSD: v3_ncons.c,v 1.8 2015/07/25 16:14:29 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include + +static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, + void *a, BIO *bp, int ind); +static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, + STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp, int ind, char *name); +static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip); + +static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc); +static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen); +static int nc_dn(X509_NAME *sub, X509_NAME *nm); +static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns); +static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml); +static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base); + +const X509V3_EXT_METHOD v3_name_constraints = { + .ext_nid = NID_name_constraints, + .ext_flags = 0, + .it = ASN1_ITEM_ref(NAME_CONSTRAINTS), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = v2i_NAME_CONSTRAINTS, + .i2r = i2r_NAME_CONSTRAINTS, + .r2i = NULL, + .usr_data = NULL, +}; + +static const ASN1_TEMPLATE GENERAL_SUBTREE_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(GENERAL_SUBTREE, base), + .field_name = "base", + .item = &GENERAL_NAME_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(GENERAL_SUBTREE, minimum), + .field_name = "minimum", + .item = &ASN1_INTEGER_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(GENERAL_SUBTREE, maximum), + .field_name = "maximum", + .item = &ASN1_INTEGER_it, + }, +}; + +const ASN1_ITEM GENERAL_SUBTREE_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = GENERAL_SUBTREE_seq_tt, + .tcount = sizeof(GENERAL_SUBTREE_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(GENERAL_SUBTREE), + .sname = "GENERAL_SUBTREE", +}; + +static const ASN1_TEMPLATE NAME_CONSTRAINTS_seq_tt[] = { + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(NAME_CONSTRAINTS, permittedSubtrees), + .field_name = "permittedSubtrees", + .item = &GENERAL_SUBTREE_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(NAME_CONSTRAINTS, excludedSubtrees), + .field_name = "excludedSubtrees", + .item = &GENERAL_SUBTREE_it, + }, +}; + +const ASN1_ITEM NAME_CONSTRAINTS_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = NAME_CONSTRAINTS_seq_tt, + .tcount = sizeof(NAME_CONSTRAINTS_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(NAME_CONSTRAINTS), + .sname = "NAME_CONSTRAINTS", +}; + + +GENERAL_SUBTREE * +GENERAL_SUBTREE_new(void) +{ + return (GENERAL_SUBTREE*)ASN1_item_new(&GENERAL_SUBTREE_it); +} + +void +GENERAL_SUBTREE_free(GENERAL_SUBTREE *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &GENERAL_SUBTREE_it); +} + +NAME_CONSTRAINTS * +NAME_CONSTRAINTS_new(void) +{ + return (NAME_CONSTRAINTS*)ASN1_item_new(&NAME_CONSTRAINTS_it); +} + +void +NAME_CONSTRAINTS_free(NAME_CONSTRAINTS *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &NAME_CONSTRAINTS_it); +} + +static void * +v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + int i; + CONF_VALUE tval, *val; + STACK_OF(GENERAL_SUBTREE) **ptree = NULL; + NAME_CONSTRAINTS *ncons = NULL; + GENERAL_SUBTREE *sub = NULL; + + ncons = NAME_CONSTRAINTS_new(); + if (!ncons) + goto memerr; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (!strncmp(val->name, "permitted", 9) && val->name[9]) { + ptree = &ncons->permittedSubtrees; + tval.name = val->name + 10; + } else if (!strncmp(val->name, "excluded", 8) && val->name[8]) { + ptree = &ncons->excludedSubtrees; + tval.name = val->name + 9; + } else { + X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, + X509V3_R_INVALID_SYNTAX); + goto err; + } + tval.value = val->value; + sub = GENERAL_SUBTREE_new(); + if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1)) + goto err; + if (!*ptree) + *ptree = sk_GENERAL_SUBTREE_new_null(); + if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub)) + goto memerr; + sub = NULL; + } + + return ncons; + +memerr: + X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE); +err: + if (ncons) + NAME_CONSTRAINTS_free(ncons); + if (sub) + GENERAL_SUBTREE_free(sub); + + return NULL; +} + +static int +i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, BIO *bp, int ind) +{ + NAME_CONSTRAINTS *ncons = a; + + do_i2r_name_constraints(method, ncons->permittedSubtrees, + bp, ind, "Permitted"); + do_i2r_name_constraints(method, ncons->excludedSubtrees, + bp, ind, "Excluded"); + return 1; +} + +static int +do_i2r_name_constraints(const X509V3_EXT_METHOD *method, + STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp, int ind, char *name) +{ + GENERAL_SUBTREE *tree; + int i; + + if (sk_GENERAL_SUBTREE_num(trees) > 0) + BIO_printf(bp, "%*s%s:\n", ind, "", name); + for (i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) { + tree = sk_GENERAL_SUBTREE_value(trees, i); + BIO_printf(bp, "%*s", ind + 2, ""); + if (tree->base->type == GEN_IPADD) + print_nc_ipadd(bp, tree->base->d.ip); + else + GENERAL_NAME_print(bp, tree->base); + BIO_puts(bp, "\n"); + } + return 1; +} + +static int +print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip) +{ + int i, len; + unsigned char *p; + + p = ip->data; + len = ip->length; + BIO_puts(bp, "IP:"); + if (len == 8) { + BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); + } else if (len == 32) { + for (i = 0; i < 16; i++) { + BIO_printf(bp, "%X", p[0] << 8 | p[1]); + p += 2; + if (i == 7) + BIO_puts(bp, "/"); + else if (i != 15) + BIO_puts(bp, ":"); + } + } else + BIO_printf(bp, "IP Address:"); + return 1; +} + +/* Check a certificate conforms to a specified set of constraints. + * Return values: + * X509_V_OK: All constraints obeyed. + * X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation. + * X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation. + * X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type. + * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type. + * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax. + * X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name + */ + +int +NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc) +{ + int r, i; + X509_NAME *nm; + + nm = X509_get_subject_name(x); + + if (X509_NAME_entry_count(nm) > 0) { + GENERAL_NAME gntmp; + gntmp.type = GEN_DIRNAME; + gntmp.d.directoryName = nm; + + r = nc_match(&gntmp, nc); + + if (r != X509_V_OK) + return r; + + gntmp.type = GEN_EMAIL; + + /* Process any email address attributes in subject name */ + + for (i = -1;;) { + X509_NAME_ENTRY *ne; + i = X509_NAME_get_index_by_NID(nm, + NID_pkcs9_emailAddress, i); + if (i == -1) + break; + ne = X509_NAME_get_entry(nm, i); + gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne); + if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + + r = nc_match(&gntmp, nc); + + if (r != X509_V_OK) + return r; + } + + } + + for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i); + r = nc_match(gen, nc); + if (r != X509_V_OK) + return r; + } + + return X509_V_OK; +} + +static int +nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) +{ + GENERAL_SUBTREE *sub; + int i, r, match = 0; + + /* Permitted subtrees: if any subtrees exist of matching the type + * at least one subtree must match. + */ + + for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) { + sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); + if (gen->type != sub->base->type) + continue; + if (sub->minimum || sub->maximum) + return X509_V_ERR_SUBTREE_MINMAX; + /* If we already have a match don't bother trying any more */ + if (match == 2) + continue; + if (match == 0) + match = 1; + r = nc_match_single(gen, sub->base); + if (r == X509_V_OK) + match = 2; + else if (r != X509_V_ERR_PERMITTED_VIOLATION) + return r; + } + + if (match == 1) + return X509_V_ERR_PERMITTED_VIOLATION; + + /* Excluded subtrees: must not match any of these */ + + for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) { + sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i); + if (gen->type != sub->base->type) + continue; + if (sub->minimum || sub->maximum) + return X509_V_ERR_SUBTREE_MINMAX; + + r = nc_match_single(gen, sub->base); + if (r == X509_V_OK) + return X509_V_ERR_EXCLUDED_VIOLATION; + else if (r != X509_V_ERR_PERMITTED_VIOLATION) + return r; + + } + + return X509_V_OK; +} + +static int +nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base) +{ + switch (base->type) { + case GEN_DIRNAME: + return nc_dn(gen->d.directoryName, base->d.directoryName); + + case GEN_DNS: + return nc_dns(gen->d.dNSName, base->d.dNSName); + + case GEN_EMAIL: + return nc_email(gen->d.rfc822Name, base->d.rfc822Name); + + case GEN_URI: + return nc_uri(gen->d.uniformResourceIdentifier, + base->d.uniformResourceIdentifier); + + default: + return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE; + } +} + +/* directoryName name constraint matching. + * The canonical encoding of X509_NAME makes this comparison easy. It is + * matched if the subtree is a subset of the name. + */ + +static int +nc_dn(X509_NAME *nm, X509_NAME *base) +{ + /* Ensure canonical encodings are up to date. */ + if (nm->modified && i2d_X509_NAME(nm, NULL) < 0) + return X509_V_ERR_OUT_OF_MEM; + if (base->modified && i2d_X509_NAME(base, NULL) < 0) + return X509_V_ERR_OUT_OF_MEM; + if (base->canon_enclen > nm->canon_enclen) + return X509_V_ERR_PERMITTED_VIOLATION; + if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen)) + return X509_V_ERR_PERMITTED_VIOLATION; + return X509_V_OK; +} + +static int +nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base) +{ + char *baseptr = (char *)base->data; + char *dnsptr = (char *)dns->data; + + /* Empty matches everything */ + if (!*baseptr) + return X509_V_OK; + /* Otherwise can add zero or more components on the left so + * compare RHS and if dns is longer and expect '.' as preceding + * character. + */ + if (dns->length > base->length) { + dnsptr += dns->length - base->length; + if (dnsptr[-1] != '.') + return X509_V_ERR_PERMITTED_VIOLATION; + } + + if (strcasecmp(baseptr, dnsptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + + return X509_V_OK; +} + +static int +nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) +{ + const char *baseptr = (char *)base->data; + const char *emlptr = (char *)eml->data; + const char *baseat = strchr(baseptr, '@'); + const char *emlat = strchr(emlptr, '@'); + + if (!emlat) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + /* Special case: inital '.' is RHS match */ + if (!baseat && (*baseptr == '.')) { + if (eml->length > base->length) { + emlptr += eml->length - base->length; + if (!strcasecmp(baseptr, emlptr)) + return X509_V_OK; + } + return X509_V_ERR_PERMITTED_VIOLATION; + } + + /* If we have anything before '@' match local part */ + + if (baseat) { + if (baseat != baseptr) { + if ((baseat - baseptr) != (emlat - emlptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + /* Case sensitive match of local part */ + if (strncmp(baseptr, emlptr, emlat - emlptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + } + /* Position base after '@' */ + baseptr = baseat + 1; + } + emlptr = emlat + 1; + /* Just have hostname left to match: case insensitive */ + if (strcasecmp(baseptr, emlptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + + return X509_V_OK; +} + +static int +nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base) +{ + const char *baseptr = (char *)base->data; + const char *hostptr = (char *)uri->data; + const char *p = strchr(hostptr, ':'); + int hostlen; + + /* Check for foo:// and skip past it */ + if (!p || (p[1] != '/') || (p[2] != '/')) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + hostptr = p + 3; + + /* Determine length of hostname part of URI */ + + /* Look for a port indicator as end of hostname first */ + + p = strchr(hostptr, ':'); + /* Otherwise look for trailing slash */ + if (!p) + p = strchr(hostptr, '/'); + + if (!p) + hostlen = strlen(hostptr); + else + hostlen = p - hostptr; + + if (hostlen == 0) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + + /* Special case: inital '.' is RHS match */ + if (*baseptr == '.') { + if (hostlen > base->length) { + p = hostptr + hostlen - base->length; + if (!strncasecmp(p, baseptr, base->length)) + return X509_V_OK; + } + return X509_V_ERR_PERMITTED_VIOLATION; + } + + if ((base->length != (int)hostlen) || + strncasecmp(hostptr, baseptr, hostlen)) + return X509_V_ERR_PERMITTED_VIOLATION; + + return X509_V_OK; +} diff --git a/crypto/libressl/crypto/x509v3/v3_ocsp.c b/crypto/libressl/crypto/x509v3/v3_ocsp.c new file mode 100644 index 0000000000..28d467153d --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_ocsp.c @@ -0,0 +1,380 @@ +/* $OpenBSD: v3_ocsp.c,v 1.12 2015/07/29 16:13:49 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include + +#ifndef OPENSSL_NO_OCSP + +#include +#include +#include +#include +#include + +/* OCSP extensions and a couple of CRL entry extensions + */ + +static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *nonce, + BIO *out, int indent); +static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce, + BIO *out, int indent); +static int i2r_object(const X509V3_EXT_METHOD *method, void *obj, BIO *out, + int indent); + +static void *ocsp_nonce_new(void); +static int i2d_ocsp_nonce(void *a, unsigned char **pp); +static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length); +static void ocsp_nonce_free(void *a); +static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce, + BIO *out, int indent); + +static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, + void *nocheck, BIO *out, int indent); +static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + const char *str); +static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in, + BIO *bp, int ind); + +const X509V3_EXT_METHOD v3_ocsp_crlid = { + .ext_nid = NID_id_pkix_OCSP_CrlID, + .ext_flags = 0, + .it = ASN1_ITEM_ref(OCSP_CRLID), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = i2r_ocsp_crlid, + .r2i = NULL, + .usr_data = NULL, +}; + +const X509V3_EXT_METHOD v3_ocsp_acutoff = { + .ext_nid = NID_id_pkix_OCSP_archiveCutoff, + .ext_flags = 0, + .it = ASN1_ITEM_ref(ASN1_GENERALIZEDTIME), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = i2r_ocsp_acutoff, + .r2i = NULL, + .usr_data = NULL, +}; + +const X509V3_EXT_METHOD v3_crl_invdate = { + .ext_nid = NID_invalidity_date, + .ext_flags = 0, + .it = ASN1_ITEM_ref(ASN1_GENERALIZEDTIME), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = i2r_ocsp_acutoff, + .r2i = NULL, + .usr_data = NULL, +}; + +const X509V3_EXT_METHOD v3_crl_hold = { + .ext_nid = NID_hold_instruction_code, + .ext_flags = 0, + .it = ASN1_ITEM_ref(ASN1_OBJECT), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = i2r_object, + .r2i = NULL, + .usr_data = NULL, +}; + +const X509V3_EXT_METHOD v3_ocsp_nonce = { + .ext_nid = NID_id_pkix_OCSP_Nonce, + .ext_flags = 0, + .it = NULL, + .ext_new = ocsp_nonce_new, + .ext_free = ocsp_nonce_free, + .d2i = d2i_ocsp_nonce, + .i2d = i2d_ocsp_nonce, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = i2r_ocsp_nonce, + .r2i = NULL, + .usr_data = NULL, +}; + +const X509V3_EXT_METHOD v3_ocsp_nocheck = { + .ext_nid = NID_id_pkix_OCSP_noCheck, + .ext_flags = 0, + .it = ASN1_ITEM_ref(ASN1_NULL), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = s2i_ocsp_nocheck, + .i2v = NULL, + .v2i = NULL, + .i2r = i2r_ocsp_nocheck, + .r2i = NULL, + .usr_data = NULL, +}; + +const X509V3_EXT_METHOD v3_ocsp_serviceloc = { + .ext_nid = NID_id_pkix_OCSP_serviceLocator, + .ext_flags = 0, + .it = ASN1_ITEM_ref(OCSP_SERVICELOC), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = i2r_ocsp_serviceloc, + .r2i = NULL, + .usr_data = NULL, +}; + +static int +i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind) +{ + OCSP_CRLID *a = in; + if (a->crlUrl) { + if (BIO_printf(bp, "%*scrlUrl: ", ind, "") <= 0) + goto err; + if (!ASN1_STRING_print(bp, (ASN1_STRING*)a->crlUrl)) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (a->crlNum) { + if (BIO_printf(bp, "%*scrlNum: ", ind, "") <= 0) + goto err; + if (i2a_ASN1_INTEGER(bp, a->crlNum) <= 0) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (a->crlTime) { + if (BIO_printf(bp, "%*scrlTime: ", ind, "") <= 0) + goto err; + if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime)) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + return 1; + +err: + return 0; +} + +static int +i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *cutoff, BIO *bp, + int ind) +{ + if (BIO_printf(bp, "%*s", ind, "") <= 0) + return 0; + if (!ASN1_GENERALIZEDTIME_print(bp, cutoff)) + return 0; + return 1; +} + +static int +i2r_object(const X509V3_EXT_METHOD *method, void *oid, BIO *bp, int ind) +{ + if (BIO_printf(bp, "%*s", ind, "") <= 0) + return 0; + if (i2a_ASN1_OBJECT(bp, oid) <= 0) + return 0; + return 1; +} + +/* OCSP nonce. This is needs special treatment because it doesn't have + * an ASN1 encoding at all: it just contains arbitrary data. + */ + +static void * +ocsp_nonce_new(void) +{ + return ASN1_OCTET_STRING_new(); +} + +static int +i2d_ocsp_nonce(void *a, unsigned char **pp) +{ + ASN1_OCTET_STRING *os = a; + + if (pp) { + memcpy(*pp, os->data, os->length); + *pp += os->length; + } + return os->length; +} + +static void * +d2i_ocsp_nonce(void *a, const unsigned char **pp, long length) +{ + ASN1_OCTET_STRING *os, **pos; + + pos = a; + if (pos == NULL || *pos == NULL) { + os = ASN1_OCTET_STRING_new(); + if (os == NULL) + goto err; + } else + os = *pos; + if (ASN1_OCTET_STRING_set(os, *pp, length) == 0) + goto err; + + *pp += length; + + if (pos != NULL) + *pos = os; + return os; + +err: + if (pos == NULL || *pos != os) + ASN1_OCTET_STRING_free(os); + OCSPerr(OCSP_F_D2I_OCSP_NONCE, ERR_R_MALLOC_FAILURE); + return NULL; +} + +static void +ocsp_nonce_free(void *a) +{ + ASN1_OCTET_STRING_free(a); +} + +static int +i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce, BIO *out, + int indent) +{ + if (BIO_printf(out, "%*s", indent, "") <= 0) + return 0; + if (i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0) + return 0; + return 1; +} + +/* Nocheck is just a single NULL. Don't print anything and always set it */ + +static int +i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck, BIO *out, + int indent) +{ + return 1; +} + +static void * +s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + const char *str) +{ + return ASN1_NULL_new(); +} + +static int +i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind) +{ + int i; + OCSP_SERVICELOC *a = in; + ACCESS_DESCRIPTION *ad; + + if (BIO_printf(bp, "%*sIssuer: ", ind, "") <= 0) + goto err; + if (X509_NAME_print_ex(bp, a->issuer, 0, XN_FLAG_ONELINE) <= 0) + goto err; + for (i = 0; i < sk_ACCESS_DESCRIPTION_num(a->locator); i++) { + ad = sk_ACCESS_DESCRIPTION_value(a->locator, i); + if (BIO_printf(bp, "\n%*s", (2 * ind), "") <= 0) + goto err; + if (i2a_ASN1_OBJECT(bp, ad->method) <= 0) + goto err; + if (BIO_puts(bp, " - ") <= 0) + goto err; + if (GENERAL_NAME_print(bp, ad->location) <= 0) + goto err; + } + return 1; + +err: + return 0; +} +#endif diff --git a/crypto/libressl/crypto/x509v3/v3_pci.c b/crypto/libressl/crypto/x509v3/v3_pci.c new file mode 100644 index 0000000000..ceeef1932e --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_pci.c @@ -0,0 +1,332 @@ +/* $OpenBSD: v3_pci.c,v 1.9 2015/07/19 01:20:32 doug Exp $ */ +/* Contributed to the OpenSSL Project 2004 + * by Richard Levitte (richard@levitte.org) + */ +/* Copyright (c) 2004 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include +#include +#include + +static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext, + BIO *out, int indent); +static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str); + +const X509V3_EXT_METHOD v3_pci = { + .ext_nid = NID_proxyCertInfo, + .ext_flags = 0, + .it = ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = (X509V3_EXT_I2R)i2r_pci, + .r2i = (X509V3_EXT_R2I)r2i_pci, + .usr_data = NULL, +}; + +static int +i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci, BIO *out, + int indent) +{ + BIO_printf(out, "%*sPath Length Constraint: ", indent, ""); + if (pci->pcPathLengthConstraint) + i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint); + else + BIO_printf(out, "infinite"); + BIO_puts(out, "\n"); + BIO_printf(out, "%*sPolicy Language: ", indent, ""); + i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage); + BIO_puts(out, "\n"); + if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data) + BIO_printf(out, "%*sPolicy Text: %s\n", indent, "", + pci->proxyPolicy->policy->data); + return 1; +} + +static int +process_pci_value(CONF_VALUE *val, ASN1_OBJECT **language, + ASN1_INTEGER **pathlen, ASN1_OCTET_STRING **policy) +{ + int free_policy = 0; + + if (strcmp(val->name, "language") == 0) { + if (*language) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED); + X509V3_conf_err(val); + return 0; + } + if (!(*language = OBJ_txt2obj(val->value, 0))) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return 0; + } + } + else if (strcmp(val->name, "pathlen") == 0) { + if (*pathlen) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED); + X509V3_conf_err(val); + return 0; + } + if (!X509V3_get_value_int(val, pathlen)) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + X509V3_R_POLICY_PATH_LENGTH); + X509V3_conf_err(val); + return 0; + } + } + else if (strcmp(val->name, "policy") == 0) { + unsigned char *tmp_data = NULL; + long val_len; + if (!*policy) { + *policy = ASN1_OCTET_STRING_new(); + if (!*policy) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + return 0; + } + free_policy = 1; + } + if (strncmp(val->value, "hex:", 4) == 0) { + unsigned char *tmp_data2 = + string_to_hex(val->value + 4, &val_len); + + if (!tmp_data2) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + X509V3_R_ILLEGAL_HEX_DIGIT); + X509V3_conf_err(val); + goto err; + } + + tmp_data = realloc((*policy)->data, + (*policy)->length + val_len + 1); + if (tmp_data) { + (*policy)->data = tmp_data; + memcpy(&(*policy)->data[(*policy)->length], + tmp_data2, val_len); + (*policy)->length += val_len; + (*policy)->data[(*policy)->length] = '\0'; + } else { + free(tmp_data2); + free((*policy)->data); + (*policy)->data = NULL; + (*policy)->length = 0; + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + goto err; + } + free(tmp_data2); + } + else if (strncmp(val->value, "file:", 5) == 0) { + unsigned char buf[2048]; + int n; + BIO *b = BIO_new_file(val->value + 5, "r"); + if (!b) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + ERR_R_BIO_LIB); + X509V3_conf_err(val); + goto err; + } + while ((n = BIO_read(b, buf, sizeof(buf))) > 0 || + (n == 0 && BIO_should_retry(b))) { + if (!n) + continue; + + tmp_data = realloc((*policy)->data, + (*policy)->length + n + 1); + + if (!tmp_data) + break; + + (*policy)->data = tmp_data; + memcpy(&(*policy)->data[(*policy)->length], + buf, n); + (*policy)->length += n; + (*policy)->data[(*policy)->length] = '\0'; + } + BIO_free_all(b); + + if (n < 0) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + ERR_R_BIO_LIB); + X509V3_conf_err(val); + goto err; + } + } + else if (strncmp(val->value, "text:", 5) == 0) { + val_len = strlen(val->value + 5); + tmp_data = realloc((*policy)->data, + (*policy)->length + val_len + 1); + if (tmp_data) { + (*policy)->data = tmp_data; + memcpy(&(*policy)->data[(*policy)->length], + val->value + 5, val_len); + (*policy)->length += val_len; + (*policy)->data[(*policy)->length] = '\0'; + } else { + free((*policy)->data); + (*policy)->data = NULL; + (*policy)->length = 0; + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + goto err; + } + } else { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + X509V3_R_INCORRECT_POLICY_SYNTAX_TAG); + X509V3_conf_err(val); + goto err; + } + if (!tmp_data) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + goto err; + } + } + return 1; + +err: + if (free_policy) { + ASN1_OCTET_STRING_free(*policy); + *policy = NULL; + } + return 0; +} + +static PROXY_CERT_INFO_EXTENSION * +r2i_pci(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *value) +{ + PROXY_CERT_INFO_EXTENSION *pci = NULL; + STACK_OF(CONF_VALUE) *vals; + ASN1_OBJECT *language = NULL; + ASN1_INTEGER *pathlen = NULL; + ASN1_OCTET_STRING *policy = NULL; + int i, j; + + vals = X509V3_parse_list(value); + for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { + CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i); + if (!cnf->name || (*cnf->name != '@' && !cnf->value)) { + X509V3err(X509V3_F_R2I_PCI, + X509V3_R_INVALID_PROXY_POLICY_SETTING); + X509V3_conf_err(cnf); + goto err; + } + if (*cnf->name == '@') { + STACK_OF(CONF_VALUE) *sect; + int success_p = 1; + + sect = X509V3_get_section(ctx, cnf->name + 1); + if (!sect) { + X509V3err(X509V3_F_R2I_PCI, + X509V3_R_INVALID_SECTION); + X509V3_conf_err(cnf); + goto err; + } + for (j = 0; success_p && + j < sk_CONF_VALUE_num(sect); j++) { + success_p = process_pci_value( + sk_CONF_VALUE_value(sect, j), + &language, &pathlen, &policy); + } + X509V3_section_free(ctx, sect); + if (!success_p) + goto err; + } else { + if (!process_pci_value(cnf, + &language, &pathlen, &policy)) { + X509V3_conf_err(cnf); + goto err; + } + } + } + + /* Language is mandatory */ + if (!language) { + X509V3err(X509V3_F_R2I_PCI, + X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED); + goto err; + } + i = OBJ_obj2nid(language); + if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy) { + X509V3err(X509V3_F_R2I_PCI, + X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY); + goto err; + } + + pci = PROXY_CERT_INFO_EXTENSION_new(); + if (!pci) { + X509V3err(X509V3_F_R2I_PCI, ERR_R_MALLOC_FAILURE); + goto err; + } + + pci->proxyPolicy->policyLanguage = language; + language = NULL; + pci->proxyPolicy->policy = policy; + policy = NULL; + pci->pcPathLengthConstraint = pathlen; + pathlen = NULL; + goto end; + +err: + if (language) { + ASN1_OBJECT_free(language); + language = NULL; + } + if (pathlen) { + ASN1_INTEGER_free(pathlen); + pathlen = NULL; + } + if (policy) { + ASN1_OCTET_STRING_free(policy); + policy = NULL; + } +end: + sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); + return pci; +} diff --git a/crypto/libressl/crypto/x509v3/v3_pcia.c b/crypto/libressl/crypto/x509v3/v3_pcia.c new file mode 100644 index 0000000000..d0027e7259 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_pcia.c @@ -0,0 +1,145 @@ +/* $OpenBSD: v3_pcia.c,v 1.5 2015/02/09 16:03:11 jsing Exp $ */ +/* Contributed to the OpenSSL Project 2004 + * by Richard Levitte (richard@levitte.org) + */ +/* Copyright (c) 2004 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +static const ASN1_TEMPLATE PROXY_POLICY_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(PROXY_POLICY, policyLanguage), + .field_name = "policyLanguage", + .item = &ASN1_OBJECT_it, + }, + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(PROXY_POLICY, policy), + .field_name = "policy", + .item = &ASN1_OCTET_STRING_it, + }, +}; + +const ASN1_ITEM PROXY_POLICY_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = PROXY_POLICY_seq_tt, + .tcount = sizeof(PROXY_POLICY_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(PROXY_POLICY), + .sname = "PROXY_POLICY", +}; + + +PROXY_POLICY * +d2i_PROXY_POLICY(PROXY_POLICY **a, const unsigned char **in, long len) +{ + return (PROXY_POLICY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &PROXY_POLICY_it); +} + +int +i2d_PROXY_POLICY(PROXY_POLICY *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &PROXY_POLICY_it); +} + +PROXY_POLICY * +PROXY_POLICY_new(void) +{ + return (PROXY_POLICY *)ASN1_item_new(&PROXY_POLICY_it); +} + +void +PROXY_POLICY_free(PROXY_POLICY *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &PROXY_POLICY_it); +} + +static const ASN1_TEMPLATE PROXY_CERT_INFO_EXTENSION_seq_tt[] = { + { + .flags = ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(PROXY_CERT_INFO_EXTENSION, pcPathLengthConstraint), + .field_name = "pcPathLengthConstraint", + .item = &ASN1_INTEGER_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(PROXY_CERT_INFO_EXTENSION, proxyPolicy), + .field_name = "proxyPolicy", + .item = &PROXY_POLICY_it, + }, +}; + +const ASN1_ITEM PROXY_CERT_INFO_EXTENSION_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = PROXY_CERT_INFO_EXTENSION_seq_tt, + .tcount = sizeof(PROXY_CERT_INFO_EXTENSION_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(PROXY_CERT_INFO_EXTENSION), + .sname = "PROXY_CERT_INFO_EXTENSION", +}; + + +PROXY_CERT_INFO_EXTENSION * +d2i_PROXY_CERT_INFO_EXTENSION(PROXY_CERT_INFO_EXTENSION **a, const unsigned char **in, long len) +{ + return (PROXY_CERT_INFO_EXTENSION *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &PROXY_CERT_INFO_EXTENSION_it); +} + +int +i2d_PROXY_CERT_INFO_EXTENSION(PROXY_CERT_INFO_EXTENSION *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &PROXY_CERT_INFO_EXTENSION_it); +} + +PROXY_CERT_INFO_EXTENSION * +PROXY_CERT_INFO_EXTENSION_new(void) +{ + return (PROXY_CERT_INFO_EXTENSION *)ASN1_item_new(&PROXY_CERT_INFO_EXTENSION_it); +} + +void +PROXY_CERT_INFO_EXTENSION_free(PROXY_CERT_INFO_EXTENSION *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &PROXY_CERT_INFO_EXTENSION_it); +} diff --git a/crypto/libressl/crypto/x509v3/v3_pcons.c b/crypto/libressl/crypto/x509v3/v3_pcons.c new file mode 100644 index 0000000000..0ed5ac1606 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_pcons.c @@ -0,0 +1,183 @@ +/* $OpenBSD: v3_pcons.c,v 1.8 2015/07/25 16:14:29 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +static STACK_OF(CONF_VALUE) * +i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *bcons, + STACK_OF(CONF_VALUE) *extlist); +static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); + +const X509V3_EXT_METHOD v3_policy_constraints = { + .ext_nid = NID_policy_constraints, + .ext_flags = 0, + .it = ASN1_ITEM_ref(POLICY_CONSTRAINTS), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = i2v_POLICY_CONSTRAINTS, + .v2i = v2i_POLICY_CONSTRAINTS, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +static const ASN1_TEMPLATE POLICY_CONSTRAINTS_seq_tt[] = { + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(POLICY_CONSTRAINTS, requireExplicitPolicy), + .field_name = "requireExplicitPolicy", + .item = &ASN1_INTEGER_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(POLICY_CONSTRAINTS, inhibitPolicyMapping), + .field_name = "inhibitPolicyMapping", + .item = &ASN1_INTEGER_it, + }, +}; + +const ASN1_ITEM POLICY_CONSTRAINTS_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = POLICY_CONSTRAINTS_seq_tt, + .tcount = sizeof(POLICY_CONSTRAINTS_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(POLICY_CONSTRAINTS), + .sname = "POLICY_CONSTRAINTS", +}; + + +POLICY_CONSTRAINTS * +POLICY_CONSTRAINTS_new(void) +{ + return (POLICY_CONSTRAINTS*)ASN1_item_new(&POLICY_CONSTRAINTS_it); +} + +void +POLICY_CONSTRAINTS_free(POLICY_CONSTRAINTS *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &POLICY_CONSTRAINTS_it); +} + +static STACK_OF(CONF_VALUE) * +i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, + STACK_OF(CONF_VALUE) *extlist) +{ + POLICY_CONSTRAINTS *pcons = a; + + X509V3_add_value_int("Require Explicit Policy", + pcons->requireExplicitPolicy, &extlist); + X509V3_add_value_int("Inhibit Policy Mapping", + pcons->inhibitPolicyMapping, &extlist); + return extlist; +} + +static void * +v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values) +{ + POLICY_CONSTRAINTS *pcons = NULL; + CONF_VALUE *val; + int i; + + if (!(pcons = POLICY_CONSTRAINTS_new())) { + X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, + ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + val = sk_CONF_VALUE_value(values, i); + if (!strcmp(val->name, "requireExplicitPolicy")) { + if (!X509V3_get_value_int(val, + &pcons->requireExplicitPolicy)) goto err; + } else if (!strcmp(val->name, "inhibitPolicyMapping")) { + if (!X509V3_get_value_int(val, + &pcons->inhibitPolicyMapping)) goto err; + } else { + X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, + X509V3_R_INVALID_NAME); + X509V3_conf_err(val); + goto err; + } + } + if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) { + X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, + X509V3_R_ILLEGAL_EMPTY_EXTENSION); + goto err; + } + + return pcons; + +err: + POLICY_CONSTRAINTS_free(pcons); + return NULL; +} diff --git a/crypto/libressl/crypto/x509v3/v3_pku.c b/crypto/libressl/crypto/x509v3/v3_pku.c new file mode 100644 index 0000000000..79bef3b893 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_pku.c @@ -0,0 +1,166 @@ +/* $OpenBSD: v3_pku.c,v 1.11 2015/07/25 16:00:14 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include + +static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, + PKEY_USAGE_PERIOD *usage, BIO *out, int indent); +/* +static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); +*/ +const X509V3_EXT_METHOD v3_pkey_usage_period = { + .ext_nid = NID_private_key_usage_period, + .ext_flags = 0, + .it = ASN1_ITEM_ref(PKEY_USAGE_PERIOD), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, + .v2i = NULL, + .i2r = (X509V3_EXT_I2R)i2r_PKEY_USAGE_PERIOD, + .r2i = NULL, + .usr_data = NULL, +}; + +static const ASN1_TEMPLATE PKEY_USAGE_PERIOD_seq_tt[] = { + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(PKEY_USAGE_PERIOD, notBefore), + .field_name = "notBefore", + .item = &ASN1_GENERALIZEDTIME_it, + }, + { + .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 1, + .offset = offsetof(PKEY_USAGE_PERIOD, notAfter), + .field_name = "notAfter", + .item = &ASN1_GENERALIZEDTIME_it, + }, +}; + +const ASN1_ITEM PKEY_USAGE_PERIOD_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = PKEY_USAGE_PERIOD_seq_tt, + .tcount = sizeof(PKEY_USAGE_PERIOD_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(PKEY_USAGE_PERIOD), + .sname = "PKEY_USAGE_PERIOD", +}; + + +PKEY_USAGE_PERIOD * +d2i_PKEY_USAGE_PERIOD(PKEY_USAGE_PERIOD **a, const unsigned char **in, long len) +{ + return (PKEY_USAGE_PERIOD *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &PKEY_USAGE_PERIOD_it); +} + +int +i2d_PKEY_USAGE_PERIOD(PKEY_USAGE_PERIOD *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKEY_USAGE_PERIOD_it); +} + +PKEY_USAGE_PERIOD * +PKEY_USAGE_PERIOD_new(void) +{ + return (PKEY_USAGE_PERIOD *)ASN1_item_new(&PKEY_USAGE_PERIOD_it); +} + +void +PKEY_USAGE_PERIOD_free(PKEY_USAGE_PERIOD *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &PKEY_USAGE_PERIOD_it); +} + +static int +i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, PKEY_USAGE_PERIOD *usage, + BIO *out, int indent) +{ + BIO_printf(out, "%*s", indent, ""); + if (usage->notBefore) { + BIO_write(out, "Not Before: ", 12); + ASN1_GENERALIZEDTIME_print(out, usage->notBefore); + if (usage->notAfter) + BIO_write(out, ", ", 2); + } + if (usage->notAfter) { + BIO_write(out, "Not After: ", 11); + ASN1_GENERALIZEDTIME_print(out, usage->notAfter); + } + return 1; +} + +/* +static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(method, ctx, values) +X509V3_EXT_METHOD *method; +X509V3_CTX *ctx; +STACK_OF(CONF_VALUE) *values; +{ +return NULL; +} +*/ diff --git a/crypto/libressl/crypto/x509v3/v3_pmaps.c b/crypto/libressl/crypto/x509v3/v3_pmaps.c new file mode 100644 index 0000000000..8214d733fe --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_pmaps.c @@ -0,0 +1,218 @@ +/* $OpenBSD: v3_pmaps.c,v 1.8 2015/07/25 16:00:14 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + +#include + +#include +#include +#include +#include + +static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS( + const X509V3_EXT_METHOD *method, void *pmps, STACK_OF(CONF_VALUE) *extlist); + +const X509V3_EXT_METHOD v3_policy_mappings = { + .ext_nid = NID_policy_mappings, + .ext_flags = 0, + .it = ASN1_ITEM_ref(POLICY_MAPPINGS), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = i2v_POLICY_MAPPINGS, + .v2i = v2i_POLICY_MAPPINGS, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +static const ASN1_TEMPLATE POLICY_MAPPING_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(POLICY_MAPPING, issuerDomainPolicy), + .field_name = "issuerDomainPolicy", + .item = &ASN1_OBJECT_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(POLICY_MAPPING, subjectDomainPolicy), + .field_name = "subjectDomainPolicy", + .item = &ASN1_OBJECT_it, + }, +}; + +const ASN1_ITEM POLICY_MAPPING_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = POLICY_MAPPING_seq_tt, + .tcount = sizeof(POLICY_MAPPING_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(POLICY_MAPPING), + .sname = "POLICY_MAPPING", +}; + +static const ASN1_TEMPLATE POLICY_MAPPINGS_item_tt = { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = 0, + .field_name = "POLICY_MAPPINGS", + .item = &POLICY_MAPPING_it, +}; + +const ASN1_ITEM POLICY_MAPPINGS_it = { + .itype = ASN1_ITYPE_PRIMITIVE, + .utype = -1, + .templates = &POLICY_MAPPINGS_item_tt, + .tcount = 0, + .funcs = NULL, + .size = 0, + .sname = "POLICY_MAPPINGS", +}; + + +POLICY_MAPPING * +POLICY_MAPPING_new(void) +{ + return (POLICY_MAPPING*)ASN1_item_new(&POLICY_MAPPING_it); +} + +void +POLICY_MAPPING_free(POLICY_MAPPING *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &POLICY_MAPPING_it); +} + +static STACK_OF(CONF_VALUE) * +i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *a, + STACK_OF(CONF_VALUE) *ext_list) +{ + POLICY_MAPPINGS *pmaps = a; + POLICY_MAPPING *pmap; + int i; + char obj_tmp1[80]; + char obj_tmp2[80]; + + for (i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) { + pmap = sk_POLICY_MAPPING_value(pmaps, i); + i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy); + i2t_ASN1_OBJECT(obj_tmp2, 80, pmap->subjectDomainPolicy); + X509V3_add_value(obj_tmp1, obj_tmp2, &ext_list); + } + return ext_list; +} + +static void * +v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + POLICY_MAPPINGS *pmaps = NULL; + POLICY_MAPPING *pmap = NULL; + ASN1_OBJECT *obj1 = NULL, *obj2 = NULL; + CONF_VALUE *val; + int i, rc; + + if (!(pmaps = sk_POLICY_MAPPING_new_null())) { + X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (!val->value || !val->name) { + rc = X509V3_R_INVALID_OBJECT_IDENTIFIER; + goto err; + } + obj1 = OBJ_txt2obj(val->name, 0); + obj2 = OBJ_txt2obj(val->value, 0); + if (!obj1 || !obj2) { + rc = X509V3_R_INVALID_OBJECT_IDENTIFIER; + goto err; + } + pmap = POLICY_MAPPING_new(); + if (!pmap) { + rc = ERR_R_MALLOC_FAILURE; + goto err; + } + pmap->issuerDomainPolicy = obj1; + pmap->subjectDomainPolicy = obj2; + obj1 = obj2 = NULL; + if (sk_POLICY_MAPPING_push(pmaps, pmap) == 0) { + rc = ERR_R_MALLOC_FAILURE; + goto err; + } + pmap = NULL; + } + return pmaps; + +err: + sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); + X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, rc); + if (rc == X509V3_R_INVALID_OBJECT_IDENTIFIER) + X509V3_conf_err(val); + ASN1_OBJECT_free(obj1); + ASN1_OBJECT_free(obj2); + POLICY_MAPPING_free(pmap); + return NULL; +} diff --git a/crypto/libressl/crypto/x509v3/v3_prn.c b/crypto/libressl/crypto/x509v3/v3_prn.c new file mode 100644 index 0000000000..3c883bed08 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_prn.c @@ -0,0 +1,225 @@ +/* $OpenBSD: v3_prn.c,v 1.17 2014/07/11 08:44:49 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* X509 v3 extension utilities */ + +#include + +#include +#include + +/* Extension printing routines */ + +static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, + int indent, int supported); + +/* Print out a name+value stack */ + +void +X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, int ml) +{ + int i; + CONF_VALUE *nval; + + if (!val) + return; + if (!ml || !sk_CONF_VALUE_num(val)) { + BIO_printf(out, "%*s", indent, ""); + if (!sk_CONF_VALUE_num(val)) + BIO_puts(out, "\n"); + } + for (i = 0; i < sk_CONF_VALUE_num(val); i++) { + if (ml) + BIO_printf(out, "%*s", indent, ""); + else if (i > 0) BIO_printf(out, ", "); + nval = sk_CONF_VALUE_value(val, i); + if (!nval->name) + BIO_puts(out, nval->value); + else if (!nval->value) + BIO_puts(out, nval->name); + else + BIO_printf(out, "%s:%s", nval->name, nval->value); + if (ml) + BIO_puts(out, "\n"); + } +} + +/* Main routine: print out a general extension */ + +int +X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent) +{ + void *ext_str = NULL; + char *value = NULL; + const unsigned char *p; + const X509V3_EXT_METHOD *method; + STACK_OF(CONF_VALUE) *nval = NULL; + int ok = 1; + + if (!(method = X509V3_EXT_get(ext))) + return unknown_ext_print(out, ext, flag, indent, 0); + p = ext->value->data; + if (method->it) + ext_str = ASN1_item_d2i(NULL, &p, ext->value->length, + ASN1_ITEM_ptr(method->it)); + else + ext_str = method->d2i(NULL, &p, ext->value->length); + + if (!ext_str) + return unknown_ext_print(out, ext, flag, indent, 1); + + if (method->i2s) { + if (!(value = method->i2s(method, ext_str))) { + ok = 0; + goto err; + } + BIO_printf(out, "%*s%s", indent, "", value); + } else if (method->i2v) { + if (!(nval = method->i2v(method, ext_str, NULL))) { + ok = 0; + goto err; + } + X509V3_EXT_val_prn(out, nval, indent, + method->ext_flags & X509V3_EXT_MULTILINE); + } else if (method->i2r) { + if (!method->i2r(method, ext_str, out, indent)) + ok = 0; + } else + ok = 0; + +err: + sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); + free(value); + if (method->it) + ASN1_item_free(ext_str, ASN1_ITEM_ptr(method->it)); + else + method->ext_free(ext_str); + return ok; +} + +int +X509V3_extensions_print(BIO *bp, char *title, STACK_OF(X509_EXTENSION) *exts, + unsigned long flag, int indent) +{ + int i, j; + + if (sk_X509_EXTENSION_num(exts) <= 0) + return 1; + + if (title) { + BIO_printf(bp, "%*s%s:\n",indent, "", title); + indent += 4; + } + + for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { + ASN1_OBJECT *obj; + X509_EXTENSION *ex; + ex = sk_X509_EXTENSION_value(exts, i); + if (indent && BIO_printf(bp, "%*s",indent, "") <= 0) + return 0; + obj = X509_EXTENSION_get_object(ex); + i2a_ASN1_OBJECT(bp, obj); + j = X509_EXTENSION_get_critical(ex); + if (BIO_printf(bp, ": %s\n",j?"critical":"") <= 0) + return 0; + if (!X509V3_EXT_print(bp, ex, flag, indent + 4)) { + BIO_printf(bp, "%*s", indent + 4, ""); + ASN1_STRING_print(bp, ex->value); + } + if (BIO_write(bp, "\n",1) <= 0) + return 0; + } + return 1; +} + +static int +unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, + int indent, int supported) +{ + switch (flag & X509V3_EXT_UNKNOWN_MASK) { + case X509V3_EXT_DEFAULT: + return 0; + case X509V3_EXT_ERROR_UNKNOWN: + if (supported) + BIO_printf(out, "%*s", indent, ""); + else + BIO_printf(out, "%*s", indent, ""); + return 1; + case X509V3_EXT_PARSE_UNKNOWN: + return ASN1_parse_dump(out, + ext->value->data, ext->value->length, indent, -1); + case X509V3_EXT_DUMP_UNKNOWN: + return BIO_dump_indent(out, (char *)ext->value->data, + ext->value->length, indent); + default: + return 1; + } +} + + +int +X509V3_EXT_print_fp(FILE *fp, X509_EXTENSION *ext, int flag, int indent) +{ + BIO *bio_tmp; + int ret; + + if (!(bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE))) + return 0; + ret = X509V3_EXT_print(bio_tmp, ext, flag, indent); + BIO_free(bio_tmp); + return ret; +} diff --git a/crypto/libressl/crypto/x509v3/v3_purp.c b/crypto/libressl/crypto/x509v3/v3_purp.c new file mode 100644 index 0000000000..12c879ef81 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_purp.c @@ -0,0 +1,861 @@ +/* $OpenBSD: v3_purp.c,v 1.25 2015/02/10 11:22:22 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include + +#include +#include +#include + +static void x509v3_cache_extensions(X509 *x); + +static int check_ssl_ca(const X509 *x); +static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int purpose_smime(const X509 *x, int ca); +static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca); +static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca); + +static int xp_cmp(const X509_PURPOSE * const *a, const X509_PURPOSE * const *b); +static void xptable_free(X509_PURPOSE *p); + +static X509_PURPOSE xstandard[] = { + {X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0, check_purpose_ssl_client, "SSL client", "sslclient", NULL}, + {X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ssl_server, "SSL server", "sslserver", NULL}, + {X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ns_ssl_server, "Netscape SSL server", "nssslserver", NULL}, + {X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, "S/MIME signing", "smimesign", NULL}, + {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, check_purpose_smime_encrypt, "S/MIME encryption", "smimeencrypt", NULL}, + {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, "CRL signing", "crlsign", NULL}, + {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, "Any Purpose", "any", NULL}, + {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, "OCSP helper", "ocsphelper", NULL}, + {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, check_purpose_timestamp_sign, "Time Stamp signing", "timestampsign", NULL}, +}; + +#define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE)) + +static STACK_OF(X509_PURPOSE) *xptable = NULL; + +static int +xp_cmp(const X509_PURPOSE * const *a, const X509_PURPOSE * const *b) +{ + return (*a)->purpose - (*b)->purpose; +} + +/* As much as I'd like to make X509_check_purpose use a "const" X509* + * I really can't because it does recalculate hashes and do other non-const + * things. */ +int +X509_check_purpose(X509 *x, int id, int ca) +{ + int idx; + const X509_PURPOSE *pt; + + if (!(x->ex_flags & EXFLAG_SET)) { + CRYPTO_w_lock(CRYPTO_LOCK_X509); + x509v3_cache_extensions(x); + CRYPTO_w_unlock(CRYPTO_LOCK_X509); + } + if (id == -1) + return 1; + idx = X509_PURPOSE_get_by_id(id); + if (idx == -1) + return -1; + pt = X509_PURPOSE_get0(idx); + return pt->check_purpose(pt, x, ca); +} + +int +X509_PURPOSE_set(int *p, int purpose) +{ + if (X509_PURPOSE_get_by_id(purpose) == -1) { + X509V3err(X509V3_F_X509_PURPOSE_SET, X509V3_R_INVALID_PURPOSE); + return 0; + } + *p = purpose; + return 1; +} + +int +X509_PURPOSE_get_count(void) +{ + if (!xptable) + return X509_PURPOSE_COUNT; + return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT; +} + +X509_PURPOSE * +X509_PURPOSE_get0(int idx) +{ + if (idx < 0) + return NULL; + if (idx < (int)X509_PURPOSE_COUNT) + return xstandard + idx; + return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT); +} + +int +X509_PURPOSE_get_by_sname(char *sname) +{ + int i; + X509_PURPOSE *xptmp; + + for (i = 0; i < X509_PURPOSE_get_count(); i++) { + xptmp = X509_PURPOSE_get0(i); + if (!strcmp(xptmp->sname, sname)) + return i; + } + return -1; +} + +int +X509_PURPOSE_get_by_id(int purpose) +{ + X509_PURPOSE tmp; + int idx; + + if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX)) + return purpose - X509_PURPOSE_MIN; + tmp.purpose = purpose; + if (!xptable) + return -1; + idx = sk_X509_PURPOSE_find(xptable, &tmp); + if (idx == -1) + return -1; + return idx + X509_PURPOSE_COUNT; +} + +int +X509_PURPOSE_add(int id, int trust, int flags, + int (*ck)(const X509_PURPOSE *, const X509 *, int), char *name, + char *sname, void *arg) +{ + int idx; + X509_PURPOSE *ptmp; + char *name_dup, *sname_dup; + + name_dup = sname_dup = NULL; + + if (name == NULL || sname == NULL) { + X509V3err(X509V3_F_X509_PURPOSE_ADD, + X509V3_R_INVALID_NULL_ARGUMENT); + return 0; + } + + /* This is set according to what we change: application can't set it */ + flags &= ~X509_PURPOSE_DYNAMIC; + /* This will always be set for application modified trust entries */ + flags |= X509_PURPOSE_DYNAMIC_NAME; + /* Get existing entry if any */ + idx = X509_PURPOSE_get_by_id(id); + /* Need a new entry */ + if (idx == -1) { + if ((ptmp = malloc(sizeof(X509_PURPOSE))) == NULL) { + X509V3err(X509V3_F_X509_PURPOSE_ADD, + ERR_R_MALLOC_FAILURE); + return 0; + } + ptmp->flags = X509_PURPOSE_DYNAMIC; + } else + ptmp = X509_PURPOSE_get0(idx); + + if ((name_dup = strdup(name)) == NULL) + goto err; + if ((sname_dup = strdup(sname)) == NULL) + goto err; + + /* free existing name if dynamic */ + if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) { + free(ptmp->name); + free(ptmp->sname); + } + /* dup supplied name */ + ptmp->name = name_dup; + ptmp->sname = sname_dup; + /* Keep the dynamic flag of existing entry */ + ptmp->flags &= X509_PURPOSE_DYNAMIC; + /* Set all other flags */ + ptmp->flags |= flags; + + ptmp->purpose = id; + ptmp->trust = trust; + ptmp->check_purpose = ck; + ptmp->usr_data = arg; + + /* If its a new entry manage the dynamic table */ + if (idx == -1) { + if (xptable == NULL && + (xptable = sk_X509_PURPOSE_new(xp_cmp)) == NULL) + goto err; + if (sk_X509_PURPOSE_push(xptable, ptmp) == 0) + goto err; + } + return 1; + +err: + free(name_dup); + free(sname_dup); + if (idx == -1) + free(ptmp); + X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); + return 0; +} + +static void +xptable_free(X509_PURPOSE *p) +{ + if (!p) + return; + if (p->flags & X509_PURPOSE_DYNAMIC) { + if (p->flags & X509_PURPOSE_DYNAMIC_NAME) { + free(p->name); + free(p->sname); + } + free(p); + } +} + +void +X509_PURPOSE_cleanup(void) +{ + unsigned int i; + + sk_X509_PURPOSE_pop_free(xptable, xptable_free); + for(i = 0; i < X509_PURPOSE_COUNT; i++) + xptable_free(xstandard + i); + xptable = NULL; +} + +int +X509_PURPOSE_get_id(X509_PURPOSE *xp) +{ + return xp->purpose; +} + +char * +X509_PURPOSE_get0_name(X509_PURPOSE *xp) +{ + return xp->name; +} + +char * +X509_PURPOSE_get0_sname(X509_PURPOSE *xp) +{ + return xp->sname; +} + +int +X509_PURPOSE_get_trust(X509_PURPOSE *xp) +{ + return xp->trust; +} + +static int +nid_cmp(const int *a, const int *b) +{ + return *a - *b; +} + +DECLARE_OBJ_BSEARCH_CMP_FN(int, int, nid); +IMPLEMENT_OBJ_BSEARCH_CMP_FN(int, int, nid); + +int +X509_supported_extension(X509_EXTENSION *ex) +{ + /* This table is a list of the NIDs of supported extensions: + * that is those which are used by the verify process. If + * an extension is critical and doesn't appear in this list + * then the verify process will normally reject the certificate. + * The list must be kept in numerical order because it will be + * searched using bsearch. + */ + + static const int supported_nids[] = { + NID_netscape_cert_type, /* 71 */ + NID_key_usage, /* 83 */ + NID_subject_alt_name, /* 85 */ + NID_basic_constraints, /* 87 */ + NID_certificate_policies, /* 89 */ + NID_ext_key_usage, /* 126 */ + NID_policy_constraints, /* 401 */ + NID_proxyCertInfo, /* 663 */ + NID_name_constraints, /* 666 */ + NID_policy_mappings, /* 747 */ + NID_inhibit_any_policy /* 748 */ + }; + + int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex)); + + if (ex_nid == NID_undef) + return 0; + + if (OBJ_bsearch_nid(&ex_nid, supported_nids, + sizeof(supported_nids) / sizeof(int))) + return 1; + return 0; +} + +static void +setup_dp(X509 *x, DIST_POINT *dp) +{ + X509_NAME *iname = NULL; + int i; + + if (dp->reasons) { + if (dp->reasons->length > 0) + dp->dp_reasons = dp->reasons->data[0]; + if (dp->reasons->length > 1) + dp->dp_reasons |= (dp->reasons->data[1] << 8); + dp->dp_reasons &= CRLDP_ALL_REASONS; + } else + dp->dp_reasons = CRLDP_ALL_REASONS; + if (!dp->distpoint || (dp->distpoint->type != 1)) + return; + for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); + if (gen->type == GEN_DIRNAME) { + iname = gen->d.directoryName; + break; + } + } + if (!iname) + iname = X509_get_issuer_name(x); + + DIST_POINT_set_dpname(dp->distpoint, iname); + +} + +static void +setup_crldp(X509 *x) +{ + int i; + + x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL); + for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) + setup_dp(x, sk_DIST_POINT_value(x->crldp, i)); +} + +static void +x509v3_cache_extensions(X509 *x) +{ + BASIC_CONSTRAINTS *bs; + PROXY_CERT_INFO_EXTENSION *pci; + ASN1_BIT_STRING *usage; + ASN1_BIT_STRING *ns; + EXTENDED_KEY_USAGE *extusage; + X509_EXTENSION *ex; + + int i; + if (x->ex_flags & EXFLAG_SET) + return; +#ifndef OPENSSL_NO_SHA + X509_digest(x, EVP_sha1(), x->sha1_hash, NULL); +#endif + /* Does subject name match issuer ? */ + if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) + x->ex_flags |= EXFLAG_SI; + /* V1 should mean no extensions ... */ + if (!X509_get_version(x)) + x->ex_flags |= EXFLAG_V1; + /* Handle basic constraints */ + if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) { + if (bs->ca) + x->ex_flags |= EXFLAG_CA; + if (bs->pathlen) { + if ((bs->pathlen->type == V_ASN1_NEG_INTEGER) || + !bs->ca) { + x->ex_flags |= EXFLAG_INVALID; + x->ex_pathlen = 0; + } else + x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen); + } else + x->ex_pathlen = -1; + BASIC_CONSTRAINTS_free(bs); + x->ex_flags |= EXFLAG_BCONS; + } + /* Handle proxy certificates */ + if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) { + if (x->ex_flags & EXFLAG_CA || + X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0 || + X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) { + x->ex_flags |= EXFLAG_INVALID; + } + if (pci->pcPathLengthConstraint) { + x->ex_pcpathlen = + ASN1_INTEGER_get(pci->pcPathLengthConstraint); + } else + x->ex_pcpathlen = -1; + PROXY_CERT_INFO_EXTENSION_free(pci); + x->ex_flags |= EXFLAG_PROXY; + } + /* Handle key usage */ + if ((usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) { + if (usage->length > 0) { + x->ex_kusage = usage->data[0]; + if (usage->length > 1) + x->ex_kusage |= usage->data[1] << 8; + } else + x->ex_kusage = 0; + x->ex_flags |= EXFLAG_KUSAGE; + ASN1_BIT_STRING_free(usage); + } + x->ex_xkusage = 0; + if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) { + x->ex_flags |= EXFLAG_XKUSAGE; + for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) { + switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) { + case NID_server_auth: + x->ex_xkusage |= XKU_SSL_SERVER; + break; + + case NID_client_auth: + x->ex_xkusage |= XKU_SSL_CLIENT; + break; + + case NID_email_protect: + x->ex_xkusage |= XKU_SMIME; + break; + + case NID_code_sign: + x->ex_xkusage |= XKU_CODE_SIGN; + break; + + case NID_ms_sgc: + case NID_ns_sgc: + x->ex_xkusage |= XKU_SGC; + break; + + case NID_OCSP_sign: + x->ex_xkusage |= XKU_OCSP_SIGN; + break; + + case NID_time_stamp: + x->ex_xkusage |= XKU_TIMESTAMP; + break; + + case NID_dvcs: + x->ex_xkusage |= XKU_DVCS; + break; + } + } + sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free); + } + + if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) { + if (ns->length > 0) + x->ex_nscert = ns->data[0]; + else + x->ex_nscert = 0; + x->ex_flags |= EXFLAG_NSCERT; + ASN1_BIT_STRING_free(ns); + } + + x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL); + x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL); + x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); + x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL); + if (!x->nc && (i != -1)) + x->ex_flags |= EXFLAG_INVALID; + setup_crldp(x); + + for (i = 0; i < X509_get_ext_count(x); i++) { + ex = X509_get_ext(x, i); + if (OBJ_obj2nid(X509_EXTENSION_get_object(ex)) == + NID_freshest_crl) + x->ex_flags |= EXFLAG_FRESHEST; + if (!X509_EXTENSION_get_critical(ex)) + continue; + if (!X509_supported_extension(ex)) { + x->ex_flags |= EXFLAG_CRITICAL; + break; + } + } + x->ex_flags |= EXFLAG_SET; +} + +/* CA checks common to all purposes + * return codes: + * 0 not a CA + * 1 is a CA + * 2 basicConstraints absent so "maybe" a CA + * 3 basicConstraints absent but self signed V1. + * 4 basicConstraints absent but keyUsage present and keyCertSign asserted. + */ + +#define V1_ROOT (EXFLAG_V1|EXFLAG_SS) +#define ku_reject(x, usage) \ + (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) +#define xku_reject(x, usage) \ + (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage))) +#define ns_reject(x, usage) \ + (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage))) + +static int +check_ca(const X509 *x) +{ + /* keyUsage if present should allow cert signing */ + if (ku_reject(x, KU_KEY_CERT_SIGN)) + return 0; + if (x->ex_flags & EXFLAG_BCONS) { + if (x->ex_flags & EXFLAG_CA) + return 1; + /* If basicConstraints says not a CA then say so */ + else + return 0; + } else { + /* we support V1 roots for... uh, I don't really know why. */ + if ((x->ex_flags & V1_ROOT) == V1_ROOT) + return 3; + /* If key usage present it must have certSign so tolerate it */ + else if (x->ex_flags & EXFLAG_KUSAGE) + return 4; + /* Older certificates could have Netscape-specific CA types */ + else if (x->ex_flags & EXFLAG_NSCERT && + x->ex_nscert & NS_ANY_CA) + return 5; + /* can this still be regarded a CA certificate? I doubt it */ + return 0; + } +} + +int +X509_check_ca(X509 *x) +{ + if (!(x->ex_flags & EXFLAG_SET)) { + CRYPTO_w_lock(CRYPTO_LOCK_X509); + x509v3_cache_extensions(x); + CRYPTO_w_unlock(CRYPTO_LOCK_X509); + } + + return check_ca(x); +} + +/* Check SSL CA: common checks for SSL client and server */ +static int +check_ssl_ca(const X509 *x) +{ + int ca_ret; + + ca_ret = check_ca(x); + if (!ca_ret) + return 0; + /* check nsCertType if present */ + if (ca_ret != 5 || x->ex_nscert & NS_SSL_CA) + return ca_ret; + else + return 0; +} + +static int +check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + if (xku_reject(x, XKU_SSL_CLIENT)) + return 0; + if (ca) + return check_ssl_ca(x); + /* We need to do digital signatures with it */ + if (ku_reject(x, KU_DIGITAL_SIGNATURE)) + return 0; + /* nsCertType if present should allow SSL client use */ + if (ns_reject(x, NS_SSL_CLIENT)) + return 0; + return 1; +} + +static int +check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + if (xku_reject(x, XKU_SSL_SERVER|XKU_SGC)) + return 0; + if (ca) + return check_ssl_ca(x); + + if (ns_reject(x, NS_SSL_SERVER)) + return 0; + /* Now as for keyUsage: we'll at least need to sign OR encipher */ + if (ku_reject(x, KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT)) + return 0; + + return 1; +} + +static int +check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + int ret; + + ret = check_purpose_ssl_server(xp, x, ca); + if (!ret || ca) + return ret; + /* We need to encipher or Netscape complains */ + if (ku_reject(x, KU_KEY_ENCIPHERMENT)) + return 0; + return ret; +} + +/* common S/MIME checks */ +static int +purpose_smime(const X509 *x, int ca) +{ + if (xku_reject(x, XKU_SMIME)) + return 0; + if (ca) { + int ca_ret; + ca_ret = check_ca(x); + if (!ca_ret) + return 0; + /* check nsCertType if present */ + if (ca_ret != 5 || x->ex_nscert & NS_SMIME_CA) + return ca_ret; + else + return 0; + } + if (x->ex_flags & EXFLAG_NSCERT) { + if (x->ex_nscert & NS_SMIME) + return 1; + /* Workaround for some buggy certificates */ + if (x->ex_nscert & NS_SSL_CLIENT) + return 2; + return 0; + } + return 1; +} + +static int +check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + int ret; + + ret = purpose_smime(x, ca); + if (!ret || ca) + return ret; + if (ku_reject(x, KU_DIGITAL_SIGNATURE|KU_NON_REPUDIATION)) + return 0; + return ret; +} + +static int +check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + int ret; + + ret = purpose_smime(x, ca); + if (!ret || ca) + return ret; + if (ku_reject(x, KU_KEY_ENCIPHERMENT)) + return 0; + return ret; +} + +static int +check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + if (ca) { + int ca_ret; + if ((ca_ret = check_ca(x)) != 2) + return ca_ret; + else + return 0; + } + if (ku_reject(x, KU_CRL_SIGN)) + return 0; + return 1; +} + +/* OCSP helper: this is *not* a full OCSP check. It just checks that + * each CA is valid. Additional checks must be made on the chain. + */ +static int +ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + /* Must be a valid CA. Should we really support the "I don't know" + value (2)? */ + if (ca) + return check_ca(x); + /* leaf certificate is checked in OCSP_verify() */ + return 1; +} + +static int +check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + int i_ext; + + /* If ca is true we must return if this is a valid CA certificate. */ + if (ca) + return check_ca(x); + + /* + * Check the optional key usage field: + * if Key Usage is present, it must be one of digitalSignature + * and/or nonRepudiation (other values are not consistent and shall + * be rejected). + */ + if ((x->ex_flags & EXFLAG_KUSAGE) && + ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) || + !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)))) + return 0; + + /* Only time stamp key usage is permitted and it's required. */ + if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP) + return 0; + + /* Extended Key Usage MUST be critical */ + i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, -1); + if (i_ext >= 0) { + X509_EXTENSION *ext = X509_get_ext((X509 *) x, i_ext); + if (!X509_EXTENSION_get_critical(ext)) + return 0; + } + + return 1; +} + +static int +no_check(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + return 1; +} + +/* Various checks to see if one certificate issued the second. + * This can be used to prune a set of possible issuer certificates + * which have been looked up using some simple method such as by + * subject name. + * These are: + * 1. Check issuer_name(subject) == subject_name(issuer) + * 2. If akid(subject) exists check it matches issuer + * 3. If key_usage(issuer) exists check it supports certificate signing + * returns 0 for OK, positive for reason for mismatch, reasons match + * codes for X509_verify_cert() + */ + +int +X509_check_issued(X509 *issuer, X509 *subject) +{ + if (X509_NAME_cmp(X509_get_subject_name(issuer), + X509_get_issuer_name(subject))) + return X509_V_ERR_SUBJECT_ISSUER_MISMATCH; + x509v3_cache_extensions(issuer); + x509v3_cache_extensions(subject); + + if (subject->akid) { + int ret = X509_check_akid(issuer, subject->akid); + if (ret != X509_V_OK) + return ret; + } + + if (subject->ex_flags & EXFLAG_PROXY) { + if (ku_reject(issuer, KU_DIGITAL_SIGNATURE)) + return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; + } else if (ku_reject(issuer, KU_KEY_CERT_SIGN)) + return X509_V_ERR_KEYUSAGE_NO_CERTSIGN; + return X509_V_OK; +} + +int +X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid) +{ + if (!akid) + return X509_V_OK; + + /* Check key ids (if present) */ + if (akid->keyid && issuer->skid && + ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid) ) + return X509_V_ERR_AKID_SKID_MISMATCH; + /* Check serial number */ + if (akid->serial && + ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial)) + return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; + /* Check issuer name */ + if (akid->issuer) { + /* Ugh, for some peculiar reason AKID includes + * SEQUENCE OF GeneralName. So look for a DirName. + * There may be more than one but we only take any + * notice of the first. + */ + GENERAL_NAMES *gens; + GENERAL_NAME *gen; + X509_NAME *nm = NULL; + int i; + gens = akid->issuer; + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + gen = sk_GENERAL_NAME_value(gens, i); + if (gen->type == GEN_DIRNAME) { + nm = gen->d.dirn; + break; + } + } + if (nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer))) + return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; + } + return X509_V_OK; +} diff --git a/crypto/libressl/crypto/x509v3/v3_skey.c b/crypto/libressl/crypto/x509v3/v3_skey.c new file mode 100644 index 0000000000..8b9b83eb73 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_skey.c @@ -0,0 +1,160 @@ +/* $OpenBSD: v3_skey.c,v 1.12 2015/07/29 16:13:49 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include + +static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str); + +const X509V3_EXT_METHOD v3_skey_id = { + .ext_nid = NID_subject_key_identifier, + .ext_flags = 0, + .it = ASN1_ITEM_ref(ASN1_OCTET_STRING), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING, + .s2i = (X509V3_EXT_S2I)s2i_skey_id, + .i2v = NULL, + .v2i = NULL, + .i2r = NULL, + .r2i = NULL, + .usr_data = NULL, +}; + +char * +i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct) +{ + return hex_to_string(oct->data, oct->length); +} + +ASN1_OCTET_STRING * +s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str) +{ + ASN1_OCTET_STRING *oct; + long length; + + if (!(oct = ASN1_OCTET_STRING_new())) { + X509V3err(X509V3_F_S2I_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!(oct->data = string_to_hex(str, &length))) { + ASN1_OCTET_STRING_free(oct); + return NULL; + } + + oct->length = length; + + return oct; +} + +static ASN1_OCTET_STRING * +s2i_skey_id(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str) +{ + ASN1_OCTET_STRING *oct; + ASN1_BIT_STRING *pk; + unsigned char pkey_dig[EVP_MAX_MD_SIZE]; + unsigned int diglen; + + if (strcmp(str, "hash")) + return s2i_ASN1_OCTET_STRING(method, ctx, str); + + if (!(oct = ASN1_OCTET_STRING_new())) { + X509V3err(X509V3_F_S2I_SKEY_ID, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (ctx && (ctx->flags == CTX_TEST)) + return oct; + + if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) { + X509V3err(X509V3_F_S2I_SKEY_ID, X509V3_R_NO_PUBLIC_KEY); + goto err; + } + + if (ctx->subject_req) + pk = ctx->subject_req->req_info->pubkey->public_key; + else + pk = ctx->subject_cert->cert_info->key->public_key; + + if (!pk) { + X509V3err(X509V3_F_S2I_SKEY_ID, X509V3_R_NO_PUBLIC_KEY); + goto err; + } + + if (!EVP_Digest(pk->data, pk->length, pkey_dig, &diglen, + EVP_sha1(), NULL)) + goto err; + + if (!ASN1_STRING_set(oct, pkey_dig, diglen)) { + X509V3err(X509V3_F_S2I_SKEY_ID, ERR_R_MALLOC_FAILURE); + goto err; + } + + return oct; + +err: + ASN1_OCTET_STRING_free(oct); + return NULL; +} diff --git a/crypto/libressl/crypto/x509v3/v3_sxnet.c b/crypto/libressl/crypto/x509v3/v3_sxnet.c new file mode 100644 index 0000000000..ed19a3a917 --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_sxnet.c @@ -0,0 +1,386 @@ +/* $OpenBSD: v3_sxnet.c,v 1.16 2015/07/29 16:13:49 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +/* Support for Thawte strong extranet extension */ + +#define SXNET_TEST + +static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, + int indent); +#ifdef SXNET_TEST +static SXNET * sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +#endif + +const X509V3_EXT_METHOD v3_sxnet = { + .ext_nid = NID_sxnet, + .ext_flags = X509V3_EXT_MULTILINE, + .it = ASN1_ITEM_ref(SXNET), + .ext_new = NULL, + .ext_free = NULL, + .d2i = NULL, + .i2d = NULL, + .i2s = NULL, + .s2i = NULL, + .i2v = NULL, +#ifdef SXNET_TEST + .v2i = (X509V3_EXT_V2I)sxnet_v2i, +#else + .v2i = NULL, +#endif + .i2r = (X509V3_EXT_I2R)sxnet_i2r, + .r2i = NULL, + .usr_data = NULL, +}; + +static const ASN1_TEMPLATE SXNETID_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(SXNETID, zone), + .field_name = "zone", + .item = &ASN1_INTEGER_it, + }, + { + .flags = 0, + .tag = 0, + .offset = offsetof(SXNETID, user), + .field_name = "user", + .item = &ASN1_OCTET_STRING_it, + }, +}; + +const ASN1_ITEM SXNETID_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = SXNETID_seq_tt, + .tcount = sizeof(SXNETID_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(SXNETID), + .sname = "SXNETID", +}; + + +SXNETID * +d2i_SXNETID(SXNETID **a, const unsigned char **in, long len) +{ + return (SXNETID *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &SXNETID_it); +} + +int +i2d_SXNETID(SXNETID *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &SXNETID_it); +} + +SXNETID * +SXNETID_new(void) +{ + return (SXNETID *)ASN1_item_new(&SXNETID_it); +} + +void +SXNETID_free(SXNETID *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &SXNETID_it); +} + +static const ASN1_TEMPLATE SXNET_seq_tt[] = { + { + .flags = 0, + .tag = 0, + .offset = offsetof(SXNET, version), + .field_name = "version", + .item = &ASN1_INTEGER_it, + }, + { + .flags = ASN1_TFLG_SEQUENCE_OF, + .tag = 0, + .offset = offsetof(SXNET, ids), + .field_name = "ids", + .item = &SXNETID_it, + }, +}; + +const ASN1_ITEM SXNET_it = { + .itype = ASN1_ITYPE_SEQUENCE, + .utype = V_ASN1_SEQUENCE, + .templates = SXNET_seq_tt, + .tcount = sizeof(SXNET_seq_tt) / sizeof(ASN1_TEMPLATE), + .funcs = NULL, + .size = sizeof(SXNET), + .sname = "SXNET", +}; + + +SXNET * +d2i_SXNET(SXNET **a, const unsigned char **in, long len) +{ + return (SXNET *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + &SXNET_it); +} + +int +i2d_SXNET(SXNET *a, unsigned char **out) +{ + return ASN1_item_i2d((ASN1_VALUE *)a, out, &SXNET_it); +} + +SXNET * +SXNET_new(void) +{ + return (SXNET *)ASN1_item_new(&SXNET_it); +} + +void +SXNET_free(SXNET *a) +{ + ASN1_item_free((ASN1_VALUE *)a, &SXNET_it); +} + +static int +sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, int indent) +{ + long v; + char *tmp; + SXNETID *id; + int i; + + v = ASN1_INTEGER_get(sx->version); + BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", v + 1, v); + for (i = 0; i < sk_SXNETID_num(sx->ids); i++) { + id = sk_SXNETID_value(sx->ids, i); + tmp = i2s_ASN1_INTEGER(NULL, id->zone); + BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp); + free(tmp); + ASN1_STRING_print(out, id->user); + } + return 1; +} + +#ifdef SXNET_TEST + +/* NBB: this is used for testing only. It should *not* be used for anything + * else because it will just take static IDs from the configuration file and + * they should really be separate values for each user. + */ + +static SXNET * +sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + CONF_VALUE *cnf; + SXNET *sx = NULL; + int i; + + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1)) + return NULL; + } + return sx; +} + +#endif + +/* Strong Extranet utility functions */ + +/* Add an id given the zone as an ASCII number */ + +int +SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen) +{ + ASN1_INTEGER *izone = NULL; + + if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) { + X509V3err(X509V3_F_SXNET_ADD_ID_ASC, + X509V3_R_ERROR_CONVERTING_ZONE); + return 0; + } + return SXNET_add_id_INTEGER(psx, izone, user, userlen); +} + +/* Add an id given the zone as an unsigned long */ + +int +SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user, int userlen) +{ + ASN1_INTEGER *izone = NULL; + + if (!(izone = ASN1_INTEGER_new()) || + !ASN1_INTEGER_set(izone, lzone)) { + X509V3err(X509V3_F_SXNET_ADD_ID_ULONG, ERR_R_MALLOC_FAILURE); + ASN1_INTEGER_free(izone); + return 0; + } + return SXNET_add_id_INTEGER(psx, izone, user, userlen); +} + +/* Add an id given the zone as an ASN1_INTEGER. + * Note this version uses the passed integer and doesn't make a copy so don't + * free it up afterwards. + */ + +int +SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user, int userlen) +{ + SXNET *sx = NULL; + SXNETID *id = NULL; + + if (!psx || !zone || !user) { + X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, + X509V3_R_INVALID_NULL_ARGUMENT); + return 0; + } + if (userlen == -1) + userlen = strlen(user); + if (userlen > 64) { + X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, + X509V3_R_USER_TOO_LONG); + return 0; + } + if (!*psx) { + if (!(sx = SXNET_new())) + goto err; + if (!ASN1_INTEGER_set(sx->version, 0)) + goto err; + *psx = sx; + } else + sx = *psx; + if (SXNET_get_id_INTEGER(sx, zone)) { + X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, + X509V3_R_DUPLICATE_ZONE_ID); + return 0; + } + + if (!(id = SXNETID_new())) + goto err; + if (userlen == -1) + userlen = strlen(user); + + if (!ASN1_STRING_set(id->user, user, userlen)) + goto err; + if (!sk_SXNETID_push(sx->ids, id)) + goto err; + id->zone = zone; + return 1; + +err: + X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, ERR_R_MALLOC_FAILURE); + SXNETID_free(id); + SXNET_free(sx); + *psx = NULL; + return 0; +} + +ASN1_OCTET_STRING * +SXNET_get_id_asc(SXNET *sx, char *zone) +{ + ASN1_INTEGER *izone = NULL; + ASN1_OCTET_STRING *oct; + + if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) { + X509V3err(X509V3_F_SXNET_GET_ID_ASC, + X509V3_R_ERROR_CONVERTING_ZONE); + return NULL; + } + oct = SXNET_get_id_INTEGER(sx, izone); + ASN1_INTEGER_free(izone); + return oct; +} + +ASN1_OCTET_STRING * +SXNET_get_id_ulong(SXNET *sx, unsigned long lzone) +{ + ASN1_INTEGER *izone = NULL; + ASN1_OCTET_STRING *oct; + + if (!(izone = ASN1_INTEGER_new()) || + !ASN1_INTEGER_set(izone, lzone)) { + X509V3err(X509V3_F_SXNET_GET_ID_ULONG, ERR_R_MALLOC_FAILURE); + ASN1_INTEGER_free(izone); + return NULL; + } + oct = SXNET_get_id_INTEGER(sx, izone); + ASN1_INTEGER_free(izone); + return oct; +} + +ASN1_OCTET_STRING * +SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone) +{ + SXNETID *id; + int i; + + for (i = 0; i < sk_SXNETID_num(sx->ids); i++) { + id = sk_SXNETID_value(sx->ids, i); + if (!ASN1_STRING_cmp(id->zone, zone)) + return id->user; + } + return NULL; +} diff --git a/crypto/libressl/crypto/x509v3/v3_utl.c b/crypto/libressl/crypto/x509v3/v3_utl.c new file mode 100644 index 0000000000..49c2ea6acd --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3_utl.c @@ -0,0 +1,925 @@ +/* $OpenBSD: v3_utl.c,v 1.23 2014/07/13 16:03:10 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2003 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* X509 v3 extension utilities */ + +#include +#include +#include + +#include +#include +#include +#include + +static char *strip_spaces(char *name); +static int sk_strcmp(const char * const *a, const char * const *b); +static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, + GENERAL_NAMES *gens); +static void str_free(OPENSSL_STRING str); +static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email); + +static int ipv4_from_asc(unsigned char *v4, const char *in); +static int ipv6_from_asc(unsigned char *v6, const char *in); +static int ipv6_cb(const char *elem, int len, void *usr); +static int ipv6_hex(unsigned char *out, const char *in, int inlen); + +/* Add a CONF_VALUE name value pair to stack */ + +int +X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist) +{ + CONF_VALUE *vtmp = NULL; + char *tname = NULL, *tvalue = NULL; + + if (name && !(tname = strdup(name))) + goto err; + if (value && !(tvalue = strdup(value))) + goto err; + if (!(vtmp = malloc(sizeof(CONF_VALUE)))) + goto err; + if (!*extlist && !(*extlist = sk_CONF_VALUE_new_null())) + goto err; + vtmp->section = NULL; + vtmp->name = tname; + vtmp->value = tvalue; + if (!sk_CONF_VALUE_push(*extlist, vtmp)) + goto err; + return 1; + +err: + X509V3err(X509V3_F_X509V3_ADD_VALUE, ERR_R_MALLOC_FAILURE); + free(vtmp); + free(tname); + free(tvalue); + return 0; +} + +int +X509V3_add_value_uchar(const char *name, const unsigned char *value, + STACK_OF(CONF_VALUE) **extlist) +{ + return X509V3_add_value(name, (const char *)value, extlist); +} + +/* Free function for STACK_OF(CONF_VALUE) */ + +void +X509V3_conf_free(CONF_VALUE *conf) +{ + if (!conf) + return; + free(conf->name); + free(conf->value); + free(conf->section); + free(conf); +} + +int +X509V3_add_value_bool(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist) +{ + if (asn1_bool) + return X509V3_add_value(name, "TRUE", extlist); + return X509V3_add_value(name, "FALSE", extlist); +} + +int +X509V3_add_value_bool_nf(char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist) +{ + if (asn1_bool) + return X509V3_add_value(name, "TRUE", extlist); + return 1; +} + + +char * +i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *a) +{ + BIGNUM *bntmp = NULL; + char *strtmp = NULL; + + if (!a) + return NULL; + if (!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) || + !(strtmp = BN_bn2dec(bntmp))) + X509V3err(X509V3_F_I2S_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE); + BN_free(bntmp); + return strtmp; +} + +char * +i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, ASN1_INTEGER *a) +{ + BIGNUM *bntmp = NULL; + char *strtmp = NULL; + + if (!a) + return NULL; + if (!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) || + !(strtmp = BN_bn2dec(bntmp))) + X509V3err(X509V3_F_I2S_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); + BN_free(bntmp); + return strtmp; +} + +ASN1_INTEGER * +s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value) +{ + BIGNUM *bn = NULL; + ASN1_INTEGER *aint; + int isneg, ishex; + int ret; + + if (!value) { + X509V3err(X509V3_F_S2I_ASN1_INTEGER, + X509V3_R_INVALID_NULL_VALUE); + return 0; + } + bn = BN_new(); + if (value[0] == '-') { + value++; + isneg = 1; + } else + isneg = 0; + + if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) { + value += 2; + ishex = 1; + } else + ishex = 0; + + if (ishex) + ret = BN_hex2bn(&bn, value); + else + ret = BN_dec2bn(&bn, value); + + if (!ret || value[ret]) { + BN_free(bn); + X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_BN_DEC2BN_ERROR); + return 0; + } + + if (isneg && BN_is_zero(bn)) + isneg = 0; + + aint = BN_to_ASN1_INTEGER(bn, NULL); + BN_free(bn); + if (!aint) { + X509V3err(X509V3_F_S2I_ASN1_INTEGER, + X509V3_R_BN_TO_ASN1_INTEGER_ERROR); + return 0; + } + if (isneg) + aint->type |= V_ASN1_NEG; + return aint; +} + +int +X509V3_add_value_int(const char *name, ASN1_INTEGER *aint, + STACK_OF(CONF_VALUE) **extlist) +{ + char *strtmp; + int ret; + + if (!aint) + return 1; + if (!(strtmp = i2s_ASN1_INTEGER(NULL, aint))) + return 0; + ret = X509V3_add_value(name, strtmp, extlist); + free(strtmp); + return ret; +} + +int +X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool) +{ + char *btmp; + + if (!(btmp = value->value)) + goto err; + if (!strcmp(btmp, "TRUE") || !strcmp(btmp, "true") || + !strcmp(btmp, "Y") || !strcmp(btmp, "y") || + !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) { + *asn1_bool = 0xff; + return 1; + } else if (!strcmp(btmp, "FALSE") || !strcmp(btmp, "false") || + !strcmp(btmp, "N") || !strcmp(btmp, "n") || + !strcmp(btmp, "NO") || !strcmp(btmp, "no")) { + *asn1_bool = 0; + return 1; + } + +err: + X509V3err(X509V3_F_X509V3_GET_VALUE_BOOL, + X509V3_R_INVALID_BOOLEAN_STRING); + X509V3_conf_err(value); + return 0; +} + +int +X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint) +{ + ASN1_INTEGER *itmp; + + if (!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) { + X509V3_conf_err(value); + return 0; + } + *aint = itmp; + return 1; +} + +#define HDR_NAME 1 +#define HDR_VALUE 2 + +/*#define DEBUG*/ + +STACK_OF(CONF_VALUE) * +X509V3_parse_list(const char *line) +{ + char *p, *q, c; + char *ntmp, *vtmp; + STACK_OF(CONF_VALUE) *values = NULL; + char *linebuf; + int state; + + /* We are going to modify the line so copy it first */ + if ((linebuf = strdup(line)) == NULL) { + X509V3err(X509V3_F_X509V3_PARSE_LIST, ERR_R_MALLOC_FAILURE); + goto err; + } + state = HDR_NAME; + ntmp = NULL; + + /* Go through all characters */ + for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && + (c != '\n'); p++) { + + switch (state) { + case HDR_NAME: + if (c == ':') { + state = HDR_VALUE; + *p = 0; + ntmp = strip_spaces(q); + if (!ntmp) { + X509V3err(X509V3_F_X509V3_PARSE_LIST, + X509V3_R_INVALID_NULL_NAME); + goto err; + } + q = p + 1; + } else if (c == ',') { + *p = 0; + ntmp = strip_spaces(q); + q = p + 1; + if (!ntmp) { + X509V3err(X509V3_F_X509V3_PARSE_LIST, + X509V3_R_INVALID_NULL_NAME); + goto err; + } + X509V3_add_value(ntmp, NULL, &values); + } + break; + + case HDR_VALUE: + if (c == ',') { + state = HDR_NAME; + *p = 0; + vtmp = strip_spaces(q); + if (!vtmp) { + X509V3err(X509V3_F_X509V3_PARSE_LIST, + X509V3_R_INVALID_NULL_VALUE); + goto err; + } + X509V3_add_value(ntmp, vtmp, &values); + ntmp = NULL; + q = p + 1; + } + + } + } + + if (state == HDR_VALUE) { + vtmp = strip_spaces(q); + if (!vtmp) { + X509V3err(X509V3_F_X509V3_PARSE_LIST, + X509V3_R_INVALID_NULL_VALUE); + goto err; + } + X509V3_add_value(ntmp, vtmp, &values); + } else { + ntmp = strip_spaces(q); + if (!ntmp) { + X509V3err(X509V3_F_X509V3_PARSE_LIST, + X509V3_R_INVALID_NULL_NAME); + goto err; + } + X509V3_add_value(ntmp, NULL, &values); + } + free(linebuf); + return values; + +err: + free(linebuf); + sk_CONF_VALUE_pop_free(values, X509V3_conf_free); + return NULL; + +} + +/* Delete leading and trailing spaces from a string */ +static char * +strip_spaces(char *name) +{ + char *p, *q; + + /* Skip over leading spaces */ + p = name; + while (*p && isspace((unsigned char)*p)) + p++; + if (!*p) + return NULL; + q = p + strlen(p) - 1; + while ((q != p) && isspace((unsigned char)*q)) + q--; + if (p != q) + q[1] = 0; + if (!*p) + return NULL; + return p; +} + +/* hex string utilities */ + +/* Given a buffer of length 'len' return a malloc'ed string with its + * hex representation + */ +char * +hex_to_string(const unsigned char *buffer, long len) +{ + char *tmp, *q; + const unsigned char *p; + int i; + static const char hexdig[] = "0123456789ABCDEF"; + + if (!buffer || !len) + return NULL; + if (!(tmp = malloc(len * 3 + 1))) { + X509V3err(X509V3_F_HEX_TO_STRING, ERR_R_MALLOC_FAILURE); + return NULL; + } + q = tmp; + for (i = 0, p = buffer; i < len; i++, p++) { + *q++ = hexdig[(*p >> 4) & 0xf]; + *q++ = hexdig[*p & 0xf]; + *q++ = ':'; + } + q[-1] = 0; + return tmp; +} + +/* Give a string of hex digits convert to + * a buffer + */ + +unsigned char * +string_to_hex(const char *str, long *len) +{ + unsigned char *hexbuf, *q; + unsigned char ch, cl, *p; + if (!str) { + X509V3err(X509V3_F_STRING_TO_HEX, + X509V3_R_INVALID_NULL_ARGUMENT); + return NULL; + } + if (!(hexbuf = malloc(strlen(str) >> 1))) + goto err; + for (p = (unsigned char *)str, q = hexbuf; *p; ) { + ch = *p++; + if (ch == ':') + continue; + cl = *p++; + if (!cl) { + X509V3err(X509V3_F_STRING_TO_HEX, + X509V3_R_ODD_NUMBER_OF_DIGITS); + free(hexbuf); + return NULL; + } + ch = tolower(ch); + cl = tolower(cl); + + if ((ch >= '0') && (ch <= '9')) + ch -= '0'; + else if ((ch >= 'a') && (ch <= 'f')) + ch -= 'a' - 10; + else + goto badhex; + + if ((cl >= '0') && (cl <= '9')) + cl -= '0'; + else if ((cl >= 'a') && (cl <= 'f')) + cl -= 'a' - 10; + else + goto badhex; + + *q++ = (ch << 4) | cl; + } + + if (len) + *len = q - hexbuf; + + return hexbuf; + +err: + free(hexbuf); + X509V3err(X509V3_F_STRING_TO_HEX, ERR_R_MALLOC_FAILURE); + return NULL; + +badhex: + free(hexbuf); + X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_ILLEGAL_HEX_DIGIT); + return NULL; +} + +/* V2I name comparison function: returns zero if 'name' matches + * cmp or cmp.* + */ + +int +name_cmp(const char *name, const char *cmp) +{ + int len, ret; + char c; + + len = strlen(cmp); + if ((ret = strncmp(name, cmp, len))) + return ret; + c = name[len]; + if (!c || (c=='.')) + return 0; + return 1; +} + +static int +sk_strcmp(const char * const *a, const char * const *b) +{ + return strcmp(*a, *b); +} + +STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x) +{ + GENERAL_NAMES *gens; + STACK_OF(OPENSSL_STRING) *ret; + + gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); + ret = get_email(X509_get_subject_name(x), gens); + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return ret; +} + +STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x) +{ + AUTHORITY_INFO_ACCESS *info; + STACK_OF(OPENSSL_STRING) *ret = NULL; + int i; + + info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL); + if (!info) + return NULL; + for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) { + ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i); + if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) { + if (ad->location->type == GEN_URI) { + if (!append_ia5(&ret, + ad->location->d.uniformResourceIdentifier)) + break; + } + } + } + AUTHORITY_INFO_ACCESS_free(info); + return ret; +} + +STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x) +{ + GENERAL_NAMES *gens; + STACK_OF(X509_EXTENSION) *exts; + STACK_OF(OPENSSL_STRING) *ret; + + exts = X509_REQ_get_extensions(x); + gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL); + ret = get_email(X509_REQ_get_subject_name(x), gens); + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + return ret; +} + + +static +STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, GENERAL_NAMES *gens) +{ + STACK_OF(OPENSSL_STRING) *ret = NULL; + X509_NAME_ENTRY *ne; + ASN1_IA5STRING *email; + GENERAL_NAME *gen; + int i; + + /* Now add any email address(es) to STACK */ + i = -1; + + /* First supplied X509_NAME */ + while ((i = X509_NAME_get_index_by_NID(name, + NID_pkcs9_emailAddress, i)) >= 0) { + ne = X509_NAME_get_entry(name, i); + email = X509_NAME_ENTRY_get_data(ne); + if (!append_ia5(&ret, email)) + return NULL; + } + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + gen = sk_GENERAL_NAME_value(gens, i); + if (gen->type != GEN_EMAIL) + continue; + if (!append_ia5(&ret, gen->d.ia5)) + return NULL; + } + return ret; +} + +static void +str_free(OPENSSL_STRING str) +{ + free(str); +} + +static int +append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email) +{ + char *emtmp; + + /* First some sanity checks */ + if (email->type != V_ASN1_IA5STRING) + return 1; + if (!email->data || !email->length) + return 1; + if (!*sk) + *sk = sk_OPENSSL_STRING_new(sk_strcmp); + if (!*sk) + return 0; + /* Don't add duplicates */ + if (sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1) + return 1; + emtmp = strdup((char *)email->data); + if (!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) { + X509_email_free(*sk); + *sk = NULL; + return 0; + } + return 1; +} + +void +X509_email_free(STACK_OF(OPENSSL_STRING) *sk) +{ + sk_OPENSSL_STRING_pop_free(sk, str_free); +} + +/* Convert IP addresses both IPv4 and IPv6 into an + * OCTET STRING compatible with RFC3280. + */ + +ASN1_OCTET_STRING * +a2i_IPADDRESS(const char *ipasc) +{ + unsigned char ipout[16]; + ASN1_OCTET_STRING *ret; + int iplen; + + /* If string contains a ':' assume IPv6 */ + + iplen = a2i_ipadd(ipout, ipasc); + + if (!iplen) + return NULL; + + ret = ASN1_OCTET_STRING_new(); + if (!ret) + return NULL; + if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) { + ASN1_OCTET_STRING_free(ret); + return NULL; + } + return ret; +} + +ASN1_OCTET_STRING * +a2i_IPADDRESS_NC(const char *ipasc) +{ + ASN1_OCTET_STRING *ret = NULL; + unsigned char ipout[32]; + char *iptmp = NULL, *p; + int iplen1, iplen2; + + p = strchr(ipasc, '/'); + if (!p) + return NULL; + iptmp = strdup(ipasc); + if (!iptmp) + return NULL; + p = iptmp + (p - ipasc); + *p++ = 0; + + iplen1 = a2i_ipadd(ipout, iptmp); + + if (!iplen1) + goto err; + + iplen2 = a2i_ipadd(ipout + iplen1, p); + + free(iptmp); + iptmp = NULL; + + if (!iplen2 || (iplen1 != iplen2)) + goto err; + + ret = ASN1_OCTET_STRING_new(); + if (!ret) + goto err; + if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2)) + goto err; + + return ret; + +err: + free(iptmp); + if (ret) + ASN1_OCTET_STRING_free(ret); + return NULL; +} + + +int +a2i_ipadd(unsigned char *ipout, const char *ipasc) +{ + /* If string contains a ':' assume IPv6 */ + + if (strchr(ipasc, ':')) { + if (!ipv6_from_asc(ipout, ipasc)) + return 0; + return 16; + } else { + if (!ipv4_from_asc(ipout, ipasc)) + return 0; + return 4; + } +} + +static int +ipv4_from_asc(unsigned char *v4, const char *in) +{ + int a0, a1, a2, a3; + if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4) + return 0; + if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255) || + (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255)) + return 0; + v4[0] = a0; + v4[1] = a1; + v4[2] = a2; + v4[3] = a3; + return 1; +} + +typedef struct { + /* Temporary store for IPV6 output */ + unsigned char tmp[16]; + /* Total number of bytes in tmp */ + int total; + /* The position of a zero (corresponding to '::') */ + int zero_pos; + /* Number of zeroes */ + int zero_cnt; +} IPV6_STAT; + + +static int +ipv6_from_asc(unsigned char *v6, const char *in) +{ + IPV6_STAT v6stat; + + v6stat.total = 0; + v6stat.zero_pos = -1; + v6stat.zero_cnt = 0; + + /* Treat the IPv6 representation as a list of values + * separated by ':'. The presence of a '::' will parse + * as one, two or three zero length elements. + */ + if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat)) + return 0; + + /* Now for some sanity checks */ + + if (v6stat.zero_pos == -1) { + /* If no '::' must have exactly 16 bytes */ + if (v6stat.total != 16) + return 0; + } else { + /* If '::' must have less than 16 bytes */ + if (v6stat.total == 16) + return 0; + /* More than three zeroes is an error */ + if (v6stat.zero_cnt > 3) + return 0; + /* Can only have three zeroes if nothing else present */ + else if (v6stat.zero_cnt == 3) { + if (v6stat.total > 0) + return 0; + } + /* Can only have two zeroes if at start or end */ + else if (v6stat.zero_cnt == 2) { + if ((v6stat.zero_pos != 0) && + (v6stat.zero_pos != v6stat.total)) + return 0; + } else + /* Can only have one zero if *not* start or end */ + { + if ((v6stat.zero_pos == 0) || + (v6stat.zero_pos == v6stat.total)) + return 0; + } + } + + /* Format result */ + + if (v6stat.zero_pos >= 0) { + /* Copy initial part */ + memcpy(v6, v6stat.tmp, v6stat.zero_pos); + /* Zero middle */ + memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total); + /* Copy final part */ + if (v6stat.total != v6stat.zero_pos) + memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total, + v6stat.tmp + v6stat.zero_pos, + v6stat.total - v6stat.zero_pos); + } else + memcpy(v6, v6stat.tmp, 16); + + return 1; +} + +static int +ipv6_cb(const char *elem, int len, void *usr) +{ + IPV6_STAT *s = usr; + + /* Error if 16 bytes written */ + if (s->total == 16) + return 0; + if (len == 0) { + /* Zero length element, corresponds to '::' */ + if (s->zero_pos == -1) + s->zero_pos = s->total; + /* If we've already got a :: its an error */ + else if (s->zero_pos != s->total) + return 0; + s->zero_cnt++; + } else { + /* If more than 4 characters could be final a.b.c.d form */ + if (len > 4) { + /* Need at least 4 bytes left */ + if (s->total > 12) + return 0; + /* Must be end of string */ + if (elem[len]) + return 0; + if (!ipv4_from_asc(s->tmp + s->total, elem)) + return 0; + s->total += 4; + } else { + if (!ipv6_hex(s->tmp + s->total, elem, len)) + return 0; + s->total += 2; + } + } + return 1; +} + +/* Convert a string of up to 4 hex digits into the corresponding + * IPv6 form. + */ + +static int +ipv6_hex(unsigned char *out, const char *in, int inlen) +{ + unsigned char c; + unsigned int num = 0; + + if (inlen > 4) + return 0; + while (inlen--) { + c = *in++; + num <<= 4; + if ((c >= '0') && (c <= '9')) + num |= c - '0'; + else if ((c >= 'A') && (c <= 'F')) + num |= c - 'A' + 10; + else if ((c >= 'a') && (c <= 'f')) + num |= c - 'a' + 10; + else + return 0; + } + out[0] = num >> 8; + out[1] = num & 0xff; + return 1; +} + +int +X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk, + unsigned long chtype) +{ + CONF_VALUE *v; + int i, mval; + char *p, *type; + + if (!nm) + return 0; + + for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) { + v = sk_CONF_VALUE_value(dn_sk, i); + type = v->name; + /* Skip past any leading X. X: X, etc to allow for + * multiple instances + */ + for (p = type; *p; p++) + if ((*p == ':') || (*p == ',') || (*p == '.')) { + p++; + if (*p) + type = p; + break; + } + if (*type == '+') { + mval = -1; + type++; + } else + mval = 0; + if (!X509_NAME_add_entry_by_txt(nm, type, chtype, + (unsigned char *) v->value, -1, -1, mval)) + return 0; + } + return 1; +} diff --git a/crypto/libressl/crypto/x509v3/v3err.c b/crypto/libressl/crypto/x509v3/v3err.c new file mode 100644 index 0000000000..e6b6bfffbf --- /dev/null +++ b/crypto/libressl/crypto/x509v3/v3err.c @@ -0,0 +1,226 @@ +/* $OpenBSD: v3err.c,v 1.10 2014/06/12 15:49:31 deraadt Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include + +#include + +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509V3,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509V3,0,reason) + +static ERR_STRING_DATA X509V3_str_functs[] = { + {ERR_FUNC(X509V3_F_A2I_GENERAL_NAME), "A2I_GENERAL_NAME"}, + {ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE), "ASIDENTIFIERCHOICE_CANONIZE"}, + {ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL), "ASIDENTIFIERCHOICE_IS_CANONICAL"}, + {ERR_FUNC(X509V3_F_COPY_EMAIL), "COPY_EMAIL"}, + {ERR_FUNC(X509V3_F_COPY_ISSUER), "COPY_ISSUER"}, + {ERR_FUNC(X509V3_F_DO_DIRNAME), "DO_DIRNAME"}, + {ERR_FUNC(X509V3_F_DO_EXT_CONF), "DO_EXT_CONF"}, + {ERR_FUNC(X509V3_F_DO_EXT_I2D), "DO_EXT_I2D"}, + {ERR_FUNC(X509V3_F_DO_EXT_NCONF), "DO_EXT_NCONF"}, + {ERR_FUNC(X509V3_F_DO_I2V_NAME_CONSTRAINTS), "DO_I2V_NAME_CONSTRAINTS"}, + {ERR_FUNC(X509V3_F_GNAMES_FROM_SECTNAME), "GNAMES_FROM_SECTNAME"}, + {ERR_FUNC(X509V3_F_HEX_TO_STRING), "hex_to_string"}, + {ERR_FUNC(X509V3_F_I2S_ASN1_ENUMERATED), "i2s_ASN1_ENUMERATED"}, + {ERR_FUNC(X509V3_F_I2S_ASN1_IA5STRING), "I2S_ASN1_IA5STRING"}, + {ERR_FUNC(X509V3_F_I2S_ASN1_INTEGER), "i2s_ASN1_INTEGER"}, + {ERR_FUNC(X509V3_F_I2V_AUTHORITY_INFO_ACCESS), "I2V_AUTHORITY_INFO_ACCESS"}, + {ERR_FUNC(X509V3_F_NOTICE_SECTION), "NOTICE_SECTION"}, + {ERR_FUNC(X509V3_F_NREF_NOS), "NREF_NOS"}, + {ERR_FUNC(X509V3_F_POLICY_SECTION), "POLICY_SECTION"}, + {ERR_FUNC(X509V3_F_PROCESS_PCI_VALUE), "PROCESS_PCI_VALUE"}, + {ERR_FUNC(X509V3_F_R2I_CERTPOL), "R2I_CERTPOL"}, + {ERR_FUNC(X509V3_F_R2I_PCI), "R2I_PCI"}, + {ERR_FUNC(X509V3_F_S2I_ASN1_IA5STRING), "S2I_ASN1_IA5STRING"}, + {ERR_FUNC(X509V3_F_S2I_ASN1_INTEGER), "s2i_ASN1_INTEGER"}, + {ERR_FUNC(X509V3_F_S2I_ASN1_OCTET_STRING), "s2i_ASN1_OCTET_STRING"}, + {ERR_FUNC(X509V3_F_S2I_ASN1_SKEY_ID), "S2I_ASN1_SKEY_ID"}, + {ERR_FUNC(X509V3_F_S2I_SKEY_ID), "S2I_SKEY_ID"}, + {ERR_FUNC(X509V3_F_SET_DIST_POINT_NAME), "SET_DIST_POINT_NAME"}, + {ERR_FUNC(X509V3_F_STRING_TO_HEX), "string_to_hex"}, + {ERR_FUNC(X509V3_F_SXNET_ADD_ID_ASC), "SXNET_add_id_asc"}, + {ERR_FUNC(X509V3_F_SXNET_ADD_ID_INTEGER), "SXNET_add_id_INTEGER"}, + {ERR_FUNC(X509V3_F_SXNET_ADD_ID_ULONG), "SXNET_add_id_ulong"}, + {ERR_FUNC(X509V3_F_SXNET_GET_ID_ASC), "SXNET_get_id_asc"}, + {ERR_FUNC(X509V3_F_SXNET_GET_ID_ULONG), "SXNET_get_id_ulong"}, + {ERR_FUNC(X509V3_F_V2I_ASIDENTIFIERS), "V2I_ASIDENTIFIERS"}, + {ERR_FUNC(X509V3_F_V2I_ASN1_BIT_STRING), "v2i_ASN1_BIT_STRING"}, + {ERR_FUNC(X509V3_F_V2I_AUTHORITY_INFO_ACCESS), "V2I_AUTHORITY_INFO_ACCESS"}, + {ERR_FUNC(X509V3_F_V2I_AUTHORITY_KEYID), "V2I_AUTHORITY_KEYID"}, + {ERR_FUNC(X509V3_F_V2I_BASIC_CONSTRAINTS), "V2I_BASIC_CONSTRAINTS"}, + {ERR_FUNC(X509V3_F_V2I_CRLD), "V2I_CRLD"}, + {ERR_FUNC(X509V3_F_V2I_EXTENDED_KEY_USAGE), "V2I_EXTENDED_KEY_USAGE"}, + {ERR_FUNC(X509V3_F_V2I_GENERAL_NAMES), "v2i_GENERAL_NAMES"}, + {ERR_FUNC(X509V3_F_V2I_GENERAL_NAME_EX), "v2i_GENERAL_NAME_ex"}, + {ERR_FUNC(X509V3_F_V2I_IDP), "V2I_IDP"}, + {ERR_FUNC(X509V3_F_V2I_IPADDRBLOCKS), "V2I_IPADDRBLOCKS"}, + {ERR_FUNC(X509V3_F_V2I_ISSUER_ALT), "V2I_ISSUER_ALT"}, + {ERR_FUNC(X509V3_F_V2I_NAME_CONSTRAINTS), "V2I_NAME_CONSTRAINTS"}, + {ERR_FUNC(X509V3_F_V2I_POLICY_CONSTRAINTS), "V2I_POLICY_CONSTRAINTS"}, + {ERR_FUNC(X509V3_F_V2I_POLICY_MAPPINGS), "V2I_POLICY_MAPPINGS"}, + {ERR_FUNC(X509V3_F_V2I_SUBJECT_ALT), "V2I_SUBJECT_ALT"}, + {ERR_FUNC(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL), "V3_ADDR_VALIDATE_PATH_INTERNAL"}, + {ERR_FUNC(X509V3_F_V3_GENERIC_EXTENSION), "V3_GENERIC_EXTENSION"}, + {ERR_FUNC(X509V3_F_X509V3_ADD1_I2D), "X509V3_add1_i2d"}, + {ERR_FUNC(X509V3_F_X509V3_ADD_VALUE), "X509V3_add_value"}, + {ERR_FUNC(X509V3_F_X509V3_EXT_ADD), "X509V3_EXT_add"}, + {ERR_FUNC(X509V3_F_X509V3_EXT_ADD_ALIAS), "X509V3_EXT_add_alias"}, + {ERR_FUNC(X509V3_F_X509V3_EXT_CONF), "X509V3_EXT_conf"}, + {ERR_FUNC(X509V3_F_X509V3_EXT_I2D), "X509V3_EXT_i2d"}, + {ERR_FUNC(X509V3_F_X509V3_EXT_NCONF), "X509V3_EXT_nconf"}, + {ERR_FUNC(X509V3_F_X509V3_GET_SECTION), "X509V3_get_section"}, + {ERR_FUNC(X509V3_F_X509V3_GET_STRING), "X509V3_get_string"}, + {ERR_FUNC(X509V3_F_X509V3_GET_VALUE_BOOL), "X509V3_get_value_bool"}, + {ERR_FUNC(X509V3_F_X509V3_PARSE_LIST), "X509V3_parse_list"}, + {ERR_FUNC(X509V3_F_X509_PURPOSE_ADD), "X509_PURPOSE_add"}, + {ERR_FUNC(X509V3_F_X509_PURPOSE_SET), "X509_PURPOSE_set"}, + {0, NULL} +}; + +static ERR_STRING_DATA X509V3_str_reasons[] = { + {ERR_REASON(X509V3_R_BAD_IP_ADDRESS) , "bad ip address"}, + {ERR_REASON(X509V3_R_BAD_OBJECT) , "bad object"}, + {ERR_REASON(X509V3_R_BN_DEC2BN_ERROR) , "bn dec2bn error"}, + {ERR_REASON(X509V3_R_BN_TO_ASN1_INTEGER_ERROR), "bn to asn1 integer error"}, + {ERR_REASON(X509V3_R_DIRNAME_ERROR) , "dirname error"}, + {ERR_REASON(X509V3_R_DISTPOINT_ALREADY_SET), "distpoint already set"}, + {ERR_REASON(X509V3_R_DUPLICATE_ZONE_ID) , "duplicate zone id"}, + {ERR_REASON(X509V3_R_ERROR_CONVERTING_ZONE), "error converting zone"}, + {ERR_REASON(X509V3_R_ERROR_CREATING_EXTENSION), "error creating extension"}, + {ERR_REASON(X509V3_R_ERROR_IN_EXTENSION) , "error in extension"}, + {ERR_REASON(X509V3_R_EXPECTED_A_SECTION_NAME), "expected a section name"}, + {ERR_REASON(X509V3_R_EXTENSION_EXISTS) , "extension exists"}, + {ERR_REASON(X509V3_R_EXTENSION_NAME_ERROR), "extension name error"}, + {ERR_REASON(X509V3_R_EXTENSION_NOT_FOUND), "extension not found"}, + {ERR_REASON(X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED), "extension setting not supported"}, + {ERR_REASON(X509V3_R_EXTENSION_VALUE_ERROR), "extension value error"}, + {ERR_REASON(X509V3_R_ILLEGAL_EMPTY_EXTENSION), "illegal empty extension"}, + {ERR_REASON(X509V3_R_ILLEGAL_HEX_DIGIT) , "illegal hex digit"}, + {ERR_REASON(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG), "incorrect policy syntax tag"}, + {ERR_REASON(X509V3_R_INVALID_MULTIPLE_RDNS), "invalid multiple rdns"}, + {ERR_REASON(X509V3_R_INVALID_ASNUMBER) , "invalid asnumber"}, + {ERR_REASON(X509V3_R_INVALID_ASRANGE) , "invalid asrange"}, + {ERR_REASON(X509V3_R_INVALID_BOOLEAN_STRING), "invalid boolean string"}, + {ERR_REASON(X509V3_R_INVALID_EXTENSION_STRING), "invalid extension string"}, + {ERR_REASON(X509V3_R_INVALID_INHERITANCE), "invalid inheritance"}, + {ERR_REASON(X509V3_R_INVALID_IPADDRESS) , "invalid ipaddress"}, + {ERR_REASON(X509V3_R_INVALID_NAME) , "invalid name"}, + {ERR_REASON(X509V3_R_INVALID_NULL_ARGUMENT), "invalid null argument"}, + {ERR_REASON(X509V3_R_INVALID_NULL_NAME) , "invalid null name"}, + {ERR_REASON(X509V3_R_INVALID_NULL_VALUE) , "invalid null value"}, + {ERR_REASON(X509V3_R_INVALID_NUMBER) , "invalid number"}, + {ERR_REASON(X509V3_R_INVALID_NUMBERS) , "invalid numbers"}, + {ERR_REASON(X509V3_R_INVALID_OBJECT_IDENTIFIER), "invalid object identifier"}, + {ERR_REASON(X509V3_R_INVALID_OPTION) , "invalid option"}, + {ERR_REASON(X509V3_R_INVALID_POLICY_IDENTIFIER), "invalid policy identifier"}, + {ERR_REASON(X509V3_R_INVALID_PROXY_POLICY_SETTING), "invalid proxy policy setting"}, + {ERR_REASON(X509V3_R_INVALID_PURPOSE) , "invalid purpose"}, + {ERR_REASON(X509V3_R_INVALID_SAFI) , "invalid safi"}, + {ERR_REASON(X509V3_R_INVALID_SECTION) , "invalid section"}, + {ERR_REASON(X509V3_R_INVALID_SYNTAX) , "invalid syntax"}, + {ERR_REASON(X509V3_R_ISSUER_DECODE_ERROR), "issuer decode error"}, + {ERR_REASON(X509V3_R_MISSING_VALUE) , "missing value"}, + {ERR_REASON(X509V3_R_NEED_ORGANIZATION_AND_NUMBERS), "need organization and numbers"}, + {ERR_REASON(X509V3_R_NO_CONFIG_DATABASE) , "no config database"}, + {ERR_REASON(X509V3_R_NO_ISSUER_CERTIFICATE), "no issuer certificate"}, + {ERR_REASON(X509V3_R_NO_ISSUER_DETAILS) , "no issuer details"}, + {ERR_REASON(X509V3_R_NO_POLICY_IDENTIFIER), "no policy identifier"}, + {ERR_REASON(X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED), "no proxy cert policy language defined"}, + {ERR_REASON(X509V3_R_NO_PUBLIC_KEY) , "no public key"}, + {ERR_REASON(X509V3_R_NO_SUBJECT_DETAILS) , "no subject details"}, + {ERR_REASON(X509V3_R_ODD_NUMBER_OF_DIGITS), "odd number of digits"}, + {ERR_REASON(X509V3_R_OPERATION_NOT_DEFINED), "operation not defined"}, + {ERR_REASON(X509V3_R_OTHERNAME_ERROR) , "othername error"}, + {ERR_REASON(X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED), "policy language already defined"}, + {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH) , "policy path length"}, + {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED), "policy path length already defined"}, + {ERR_REASON(X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED), "policy syntax not currently supported"}, + {ERR_REASON(X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY), "policy when proxy language requires no policy"}, + {ERR_REASON(X509V3_R_SECTION_NOT_FOUND) , "section not found"}, + {ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS), "unable to get issuer details"}, + {ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_KEYID), "unable to get issuer keyid"}, + {ERR_REASON(X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT), "unknown bit string argument"}, + {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION) , "unknown extension"}, + {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION_NAME), "unknown extension name"}, + {ERR_REASON(X509V3_R_UNKNOWN_OPTION) , "unknown option"}, + {ERR_REASON(X509V3_R_UNSUPPORTED_OPTION) , "unsupported option"}, + {ERR_REASON(X509V3_R_UNSUPPORTED_TYPE) , "unsupported type"}, + {ERR_REASON(X509V3_R_USER_TOO_LONG) , "user too long"}, + {0, NULL} +}; + +#endif + +void +ERR_load_X509V3_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_func_error_string(X509V3_str_functs[0].error) == NULL) { + ERR_load_strings(0, X509V3_str_functs); + ERR_load_strings(0, X509V3_str_reasons); + } +#endif +} diff --git a/crypto/libressl/include/compat/arpa/inet.h b/crypto/libressl/include/compat/arpa/inet.h new file mode 100644 index 0000000000..0cea8c439d --- /dev/null +++ b/crypto/libressl/include/compat/arpa/inet.h @@ -0,0 +1,19 @@ +/* + * Public domain + * arpa/inet.h compatibility shim + */ + +#ifndef _WIN32 +#include_next +#else +#include + +#ifndef AI_ADDRCONFIG +#define AI_ADDRCONFIG 0x00000400 +#endif + +#endif + +#ifndef HAVE_INET_PTON +int inet_pton(int af, const char * src, void * dst); +#endif diff --git a/crypto/libressl/include/compat/arpa/nameser.h b/crypto/libressl/include/compat/arpa/nameser.h new file mode 100644 index 0000000000..0126a604a5 --- /dev/null +++ b/crypto/libressl/include/compat/arpa/nameser.h @@ -0,0 +1,23 @@ +/* + * Public domain + * arpa/inet.h compatibility shim + */ + +#ifndef _WIN32 +#include_next +#else +#include + +#ifndef INADDRSZ +#define INADDRSZ 4 +#endif + +#ifndef IN6ADDRSZ +#define IN6ADDRSZ 16 +#endif + +#ifndef INT16SZ +#define INT16SZ 2 +#endif + +#endif diff --git a/crypto/libressl/include/compat/dirent.h b/crypto/libressl/include/compat/dirent.h new file mode 100644 index 0000000000..753e4a08e3 --- /dev/null +++ b/crypto/libressl/include/compat/dirent.h @@ -0,0 +1,17 @@ +/* + * Public domain + * dirent.h compatibility shim + */ + +#ifndef LIBCRYPTOCOMPAT_DIRENT_H +#define LIBCRYPTOCOMPAT_DIRENT_H + +#ifdef _MSC_VER +#include +#include +#else +#include_next +#endif + +#endif + diff --git a/crypto/libressl/include/compat/dirent_msvc.h b/crypto/libressl/include/compat/dirent_msvc.h new file mode 100644 index 0000000000..67f295f197 --- /dev/null +++ b/crypto/libressl/include/compat/dirent_msvc.h @@ -0,0 +1,611 @@ +/* + * dirent.h - dirent API for Microsoft Visual Studio + * + * Copyright (C) 2006-2012 Toni Ronkko + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * ``Software''), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * $Id: dirent.h,v 1.20 2014/03/19 17:52:23 tronkko Exp $ + */ +#ifndef DIRENT_MSVC_H +#define DIRENT_MSVC_H + +#include + +#if _MSC_VER >= 1900 +#include <../ucrt/stdio.h> +#include <../ucrt/wchar.h> +#include <../ucrt/string.h> +#include <../ucrt/stdlib.h> +#include <../ucrt/sys/types.h> +#include <../ucrt/errno.h> +#else +#include <../include/stdio.h> +#include <../include/wchar.h> +#include <../include/string.h> +#include <../include/stdlib.h> +#include <../include/sys/types.h> +#include <../include/errno.h> +#endif + +#include +#include + +/* Indicates that d_type field is available in dirent structure */ +#define _DIRENT_HAVE_D_TYPE + +/* Indicates that d_namlen field is available in dirent structure */ +#define _DIRENT_HAVE_D_NAMLEN + +/* Maximum length of file name */ +#if !defined(PATH_MAX) +# define PATH_MAX MAX_PATH +#endif +#if !defined(FILENAME_MAX) +# define FILENAME_MAX MAX_PATH +#endif +#if !defined(NAME_MAX) +# define NAME_MAX FILENAME_MAX +#endif + +/* Return the exact length of d_namlen without zero terminator */ +#define _D_EXACT_NAMLEN(p)((p)->d_namlen) + +/* Return number of bytes needed to store d_namlen */ +#define _D_ALLOC_NAMLEN(p)(PATH_MAX) + +/* Wide-character version */ +struct _wdirent { + long d_ino; /* Always zero */ + unsigned short d_reclen; /* Structure size */ + size_t d_namlen; /* Length of name without \0 */ + int d_type; /* File type */ + wchar_t d_name[PATH_MAX]; /* File name */ +}; +typedef struct _wdirent _wdirent; + +struct _WDIR { + struct _wdirent ent; /* Current directory entry */ + WIN32_FIND_DATAW data; /* Private file data */ + int cached; /* True if data is valid */ + HANDLE handle; /* Win32 search handle */ + wchar_t *patt; /* Initial directory name */ +}; +typedef struct _WDIR _WDIR; + +static _WDIR *_wopendir(const wchar_t *dirname); +static struct _wdirent *_wreaddir(_WDIR *dirp); +static int _wclosedir(_WDIR *dirp); +static void _wrewinddir(_WDIR* dirp); + +/* Multi-byte character versions */ +struct dirent { + long d_ino; /* Always zero */ + unsigned short d_reclen; /* Structure size */ + size_t d_namlen; /* Length of name without \0 */ + int d_type; /* File type */ + char d_name[PATH_MAX]; /* File name */ +}; +typedef struct dirent dirent; + +struct DIR { + struct dirent ent; + struct _WDIR *wdirp; +}; +typedef struct DIR DIR; + +static DIR *opendir(const char *dirname); +static struct dirent *readdir(DIR *dirp); +static int closedir(DIR *dirp); +static void rewinddir(DIR* dirp); + +/* Internal utility functions */ +static WIN32_FIND_DATAW *dirent_first(_WDIR *dirp); +static WIN32_FIND_DATAW *dirent_next(_WDIR *dirp); + +static int dirent_mbstowcs_s( + size_t *pReturnValue, + wchar_t *wcstr, + size_t sizeInWords, + const char *mbstr, + size_t count); + +static int dirent_wcstombs_s( + size_t *pReturnValue, + char *mbstr, + size_t sizeInBytes, + const wchar_t *wcstr, + size_t count); + +/* + * Open directory stream DIRNAME for read and return a pointer to the + * internal working area that is used to retrieve individual directory + * entries. + */ +static _WDIR* +_wopendir(const wchar_t *dirname) +{ + _WDIR *dirp = NULL; + int error; + + /* Must have directory name */ + if (dirname == NULL || dirname[0] == '\0') { + _set_errno(ENOENT); + return NULL; + } + + /* Allocate new _WDIR structure */ + dirp =(_WDIR*) malloc(sizeof(struct _WDIR)); + if (dirp != NULL) { + DWORD n; + + /* Reset _WDIR structure */ + dirp->handle = INVALID_HANDLE_VALUE; + dirp->patt = NULL; + dirp->cached = 0; + + /* Compute the length of full path plus zero terminator */ + n = GetFullPathNameW(dirname, 0, NULL, NULL); + + /* Allocate room for absolute directory name and search pattern */ + dirp->patt =(wchar_t*) malloc(sizeof(wchar_t) * n + 16); + if (dirp->patt) { + + /* + * Convert relative directory name to an absolute one. This + * allows rewinddir() to function correctly even when current + * working directory is changed between opendir() and rewinddir(). + */ + n = GetFullPathNameW(dirname, n, dirp->patt, NULL); + if (n > 0) { + wchar_t *p; + + /* Append search pattern \* to the directory name */ + p = dirp->patt + n; + if (dirp->patt < p) { + switch(p[-1]) { + case '\\': + case '/': + case ':': + /* Directory ends in path separator, e.g. c:\temp\ */ + /*NOP*/; + break; + + default: + /* Directory name doesn't end in path separator */ + *p++ = '\\'; + } + } + *p++ = '*'; + *p = '\0'; + + /* Open directory stream and retrieve the first entry */ + if (dirent_first(dirp)) { + /* Directory stream opened successfully */ + error = 0; + } else { + /* Cannot retrieve first entry */ + error = 1; + _set_errno(ENOENT); + } + + } else { + /* Cannot retrieve full path name */ + _set_errno(ENOENT); + error = 1; + } + + } else { + /* Cannot allocate memory for search pattern */ + error = 1; + } + + } else { + /* Cannot allocate _WDIR structure */ + error = 1; + } + + /* Clean up in case of error */ + if (error && dirp) { + _wclosedir(dirp); + dirp = NULL; + } + + return dirp; +} + +/* + * Read next directory entry. The directory entry is returned in dirent + * structure in the d_name field. Individual directory entries returned by + * this function include regular files, sub-directories, pseudo-directories + * "." and ".." as well as volume labels, hidden files and system files. + */ +static struct _wdirent* +_wreaddir(_WDIR *dirp) +{ + WIN32_FIND_DATAW *datap; + struct _wdirent *entp; + + /* Read next directory entry */ + datap = dirent_next(dirp); + if (datap) { + size_t n; + DWORD attr; + + /* Pointer to directory entry to return */ + entp = &dirp->ent; + + /* + * Copy file name as wide-character string. If the file name is too + * long to fit in to the destination buffer, then truncate file name + * to PATH_MAX characters and zero-terminate the buffer. + */ + n = 0; + while(n + 1 < PATH_MAX && datap->cFileName[n] != 0) { + entp->d_name[n] = datap->cFileName[n]; + n++; + } + dirp->ent.d_name[n] = 0; + + /* Length of file name excluding zero terminator */ + entp->d_namlen = n; + + /* File type */ + attr = datap->dwFileAttributes; + if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { + entp->d_type = DT_CHR; + } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { + entp->d_type = DT_DIR; + } else { + entp->d_type = DT_REG; + } + + /* Reset dummy fields */ + entp->d_ino = 0; + entp->d_reclen = sizeof(struct _wdirent); + + } else { + + /* Last directory entry read */ + entp = NULL; + + } + + return entp; +} + +/* + * Close directory stream opened by opendir() function. This invalidates the + * DIR structure as well as any directory entry read previously by + * _wreaddir(). + */ +static int +_wclosedir(_WDIR *dirp) +{ + int ok; + if (dirp) { + + /* Release search handle */ + if (dirp->handle != INVALID_HANDLE_VALUE) { + FindClose(dirp->handle); + dirp->handle = INVALID_HANDLE_VALUE; + } + + /* Release search pattern */ + if (dirp->patt) { + free(dirp->patt); + dirp->patt = NULL; + } + + /* Release directory structure */ + free(dirp); + ok = /*success*/0; + + } else { + /* Invalid directory stream */ + _set_errno(EBADF); + ok = /*failure*/-1; + } + return ok; +} + +/* + * Rewind directory stream such that _wreaddir() returns the very first + * file name again. + */ +static void +_wrewinddir(_WDIR* dirp) +{ + if (dirp) { + /* Release existing search handle */ + if (dirp->handle != INVALID_HANDLE_VALUE) { + FindClose(dirp->handle); + } + + /* Open new search handle */ + dirent_first(dirp); + } +} + +/* Get first directory entry(internal) */ +static WIN32_FIND_DATAW* +dirent_first(_WDIR *dirp) +{ + WIN32_FIND_DATAW *datap; + + /* Open directory and retrieve the first entry */ + dirp->handle = FindFirstFileW(dirp->patt, &dirp->data); + if (dirp->handle != INVALID_HANDLE_VALUE) { + + /* a directory entry is now waiting in memory */ + datap = &dirp->data; + dirp->cached = 1; + + } else { + + /* Failed to re-open directory: no directory entry in memory */ + dirp->cached = 0; + datap = NULL; + + } + return datap; +} + +/* Get next directory entry(internal) */ +static WIN32_FIND_DATAW* +dirent_next(_WDIR *dirp) +{ + WIN32_FIND_DATAW *p; + + /* Get next directory entry */ + if (dirp->cached != 0) { + + /* A valid directory entry already in memory */ + p = &dirp->data; + dirp->cached = 0; + + } else if (dirp->handle != INVALID_HANDLE_VALUE) { + + /* Get the next directory entry from stream */ + if (FindNextFileW(dirp->handle, &dirp->data) != FALSE) { + /* Got a file */ + p = &dirp->data; + } else { + /* The very last entry has been processed or an error occured */ + FindClose(dirp->handle); + dirp->handle = INVALID_HANDLE_VALUE; + p = NULL; + } + + } else { + + /* End of directory stream reached */ + p = NULL; + + } + + return p; +} + +/* + * Open directory stream using plain old C-string. + */ +static DIR* +opendir(const char *dirname) +{ + struct DIR *dirp; + int error; + + /* Must have directory name */ + if (dirname == NULL || dirname[0] == '\0') { + _set_errno(ENOENT); + return NULL; + } + + /* Allocate memory for DIR structure */ + dirp =(DIR*) malloc(sizeof(struct DIR)); + if (dirp) { + wchar_t wname[PATH_MAX]; + size_t n; + + /* Convert directory name to wide-character string */ + error = dirent_mbstowcs_s(&n, wname, PATH_MAX, dirname, PATH_MAX); + if (!error) { + + /* Open directory stream using wide-character name */ + dirp->wdirp = _wopendir(wname); + if (dirp->wdirp) { + /* Directory stream opened */ + error = 0; + } else { + /* Failed to open directory stream */ + error = 1; + } + + } else { + /* + * Cannot convert file name to wide-character string. This + * occurs if the string contains invalid multi-byte sequences or + * the output buffer is too small to contain the resulting + * string. + */ + error = 1; + } + + } else { + /* Cannot allocate DIR structure */ + error = 1; + } + + /* Clean up in case of error */ + if (error && dirp) { + free(dirp); + dirp = NULL; + } + + return dirp; +} + +/* + * Read next directory entry. + * + * When working with text consoles, please note that file names returned by + * readdir() are represented in the default ANSI code page while any output to + * console is typically formatted on another code page. Thus, non-ASCII + * characters in file names will not usually display correctly on console. The + * problem can be fixed in two ways:(1) change the character set of console + * to 1252 using chcp utility and use Lucida Console font, or(2) use + * _cprintf function when writing to console. The _cprinf() will re-encode + * ANSI strings to the console code page so many non-ASCII characters will + * display correcly. + */ +static struct dirent* +readdir(DIR *dirp) +{ + WIN32_FIND_DATAW *datap; + struct dirent *entp; + + /* Read next directory entry */ + datap = dirent_next(dirp->wdirp); + if (datap) { + size_t n; + int error; + + /* Attempt to convert file name to multi-byte string */ + error = dirent_wcstombs_s( + &n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX); + + /* + * If the file name cannot be represented by a multi-byte string, + * then attempt to use old 8+3 file name. This allows traditional + * Unix-code to access some file names despite of unicode + * characters, although file names may seem unfamiliar to the user. + * + * Be ware that the code below cannot come up with a short file + * name unless the file system provides one. At least + * VirtualBox shared folders fail to do this. + */ + if (error && datap->cAlternateFileName[0] != '\0') { + error = dirent_wcstombs_s( + &n, dirp->ent.d_name, PATH_MAX, + datap->cAlternateFileName, PATH_MAX); + } + + if (!error) { + DWORD attr; + + /* Initialize directory entry for return */ + entp = &dirp->ent; + + /* Length of file name excluding zero terminator */ + entp->d_namlen = n - 1; + + /* File attributes */ + attr = datap->dwFileAttributes; + if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { + entp->d_type = DT_CHR; + } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { + entp->d_type = DT_DIR; + } else { + entp->d_type = DT_REG; + } + + /* Reset dummy fields */ + entp->d_ino = 0; + entp->d_reclen = sizeof(struct dirent); + + } else { + /* + * Cannot convert file name to multi-byte string so construct + * an errornous directory entry and return that. Note that + * we cannot return NULL as that would stop the processing + * of directory entries completely. + */ + entp = &dirp->ent; + entp->d_name[0] = '?'; + entp->d_name[1] = '\0'; + entp->d_namlen = 1; + entp->d_type = DT_UNKNOWN; + entp->d_ino = 0; + entp->d_reclen = 0; + } + + } else { + /* No more directory entries */ + entp = NULL; + } + + return entp; +} + +/* + * Close directory stream. + */ +static int +closedir(DIR *dirp) +{ + int ok; + if (dirp) { + + /* Close wide-character directory stream */ + ok = _wclosedir(dirp->wdirp); + dirp->wdirp = NULL; + + /* Release multi-byte character version */ + free(dirp); + + } else { + + /* Invalid directory stream */ + _set_errno(EBADF); + ok = /*failure*/-1; + + } + return ok; +} + +/* + * Rewind directory stream to beginning. + */ +static void +rewinddir(DIR* dirp) +{ + /* Rewind wide-character string directory stream */ + _wrewinddir(dirp->wdirp); +} + +/* Convert multi-byte string to wide character string */ +static int +dirent_mbstowcs_s(size_t *pReturnValue, wchar_t *wcstr, + size_t sizeInWords, const char *mbstr, size_t count) +{ + return mbstowcs_s(pReturnValue, wcstr, sizeInWords, mbstr, count); +} + +/* Convert wide-character string to multi-byte string */ +static int +dirent_wcstombs_s(size_t *pReturnValue, char *mbstr, + size_t sizeInBytes, /* max size of mbstr */ + const wchar_t *wcstr, size_t count) +{ + return wcstombs_s(pReturnValue, mbstr, sizeInBytes, wcstr, count); +} + +#endif /*DIRENT_H*/ diff --git a/crypto/libressl/include/compat/err.h b/crypto/libressl/include/compat/err.h new file mode 100644 index 0000000000..65a760fbd0 --- /dev/null +++ b/crypto/libressl/include/compat/err.h @@ -0,0 +1,79 @@ +/* + * Public domain + * err.h compatibility shim + */ + +#ifdef HAVE_ERR_H + +#include_next + +#else + +#ifndef LIBCRYPTOCOMPAT_ERR_H +#define LIBCRYPTOCOMPAT_ERR_H + +#include +#include +#include +#include +#include + +static inline void +err(int eval, const char *fmt, ...) +{ + int sverrno = errno; + va_list ap; + + va_start(ap, fmt); + if (fmt != NULL) { + vfprintf(stderr, fmt, ap); + fprintf(stderr, ": "); + } + fprintf(stderr, "%s\n", strerror(sverrno)); + exit(eval); + va_end(ap); +} + +static inline void +errx(int eval, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (fmt != NULL) + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + exit(eval); + va_end(ap); +} + +static inline void +warn(const char *fmt, ...) +{ + int sverrno = errno; + va_list ap; + + va_start(ap, fmt); + if (fmt != NULL) { + vfprintf(stderr, fmt, ap); + fprintf(stderr, ": "); + } + fprintf(stderr, "%s\n", strerror(sverrno)); + va_end(ap); +} + +static inline void +warnx(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (fmt != NULL) + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); +} + +#endif + +#endif diff --git a/crypto/libressl/include/compat/limits.h b/crypto/libressl/include/compat/limits.h new file mode 100644 index 0000000000..a3a04a5598 --- /dev/null +++ b/crypto/libressl/include/compat/limits.h @@ -0,0 +1,17 @@ +/* + * Public domain + * limits.h compatibility shim + */ + +#ifdef _MSC_VER +#include <../include/limits.h> +#else +#include_next +#endif + +#ifdef __hpux +#include +#ifndef PATH_MAX +#define PATH_MAX MAXPATHLEN +#endif +#endif diff --git a/crypto/libressl/include/compat/machine/endian.h b/crypto/libressl/include/compat/machine/endian.h new file mode 100644 index 0000000000..5ec39af021 --- /dev/null +++ b/crypto/libressl/include/compat/machine/endian.h @@ -0,0 +1,40 @@ +/* + * Public domain + * machine/endian.h compatibility shim + */ + +#ifndef LIBCRYPTOCOMPAT_BYTE_ORDER_H_ +#define LIBCRYPTOCOMPAT_BYTE_ORDER_H_ + +#if defined(_WIN32) + +#define LITTLE_ENDIAN 1234 +#define BIG_ENDIAN 4321 +#define PDP_ENDIAN 3412 + +/* + * Use GCC and Visual Studio compiler defines to determine endian. + */ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define BYTE_ORDER LITTLE_ENDIAN +#else +#define BYTE_ORDER BIG_ENDIAN +#endif + +#elif defined(__linux__) +#include + +#elif defined(__sun) || defined(_AIX) || defined(__hpux) +#include +#include + +#elif defined(__sgi) +#include +#include + +#else +#include_next + +#endif + +#endif diff --git a/crypto/libressl/include/compat/netdb.h b/crypto/libressl/include/compat/netdb.h new file mode 100644 index 0000000000..d36b91dbae --- /dev/null +++ b/crypto/libressl/include/compat/netdb.h @@ -0,0 +1,10 @@ +/* + * Public domain + * netdb.h compatibility shim + */ + +#ifndef _WIN32 +#include_next +#else +#include +#endif diff --git a/crypto/libressl/include/compat/netinet/in.h b/crypto/libressl/include/compat/netinet/in.h new file mode 100644 index 0000000000..20e57b82e0 --- /dev/null +++ b/crypto/libressl/include/compat/netinet/in.h @@ -0,0 +1,10 @@ +/* + * Public domain + * netinet/in.h compatibility shim + */ + +#ifndef _WIN32 +#include_next +#else +#include +#endif diff --git a/crypto/libressl/include/compat/netinet/ip.h b/crypto/libressl/include/compat/netinet/ip.h new file mode 100644 index 0000000000..6019f7dcd1 --- /dev/null +++ b/crypto/libressl/include/compat/netinet/ip.h @@ -0,0 +1,47 @@ +/* + * Public domain + * netinet/ip.h compatibility shim + */ + +#if defined(__hpux) +#include +#endif + +#ifndef _WIN32 +#include_next +#else +#include +#endif + +/* + * Definitions for DiffServ Codepoints as per RFC2474 + */ +#ifndef IPTOS_DSCP_CS0 +#define IPTOS_DSCP_CS0 0x00 +#define IPTOS_DSCP_CS1 0x20 +#define IPTOS_DSCP_CS2 0x40 +#define IPTOS_DSCP_CS3 0x60 +#define IPTOS_DSCP_CS4 0x80 +#define IPTOS_DSCP_CS5 0xa0 +#define IPTOS_DSCP_CS6 0xc0 +#define IPTOS_DSCP_CS7 0xe0 +#endif + +#ifndef IPTOS_DSCP_AF11 +#define IPTOS_DSCP_AF11 0x28 +#define IPTOS_DSCP_AF12 0x30 +#define IPTOS_DSCP_AF13 0x38 +#define IPTOS_DSCP_AF21 0x48 +#define IPTOS_DSCP_AF22 0x50 +#define IPTOS_DSCP_AF23 0x58 +#define IPTOS_DSCP_AF31 0x68 +#define IPTOS_DSCP_AF32 0x70 +#define IPTOS_DSCP_AF33 0x78 +#define IPTOS_DSCP_AF41 0x88 +#define IPTOS_DSCP_AF42 0x90 +#define IPTOS_DSCP_AF43 0x98 +#endif + +#ifndef IPTOS_DSCP_EF +#define IPTOS_DSCP_EF 0xb8 +#endif diff --git a/crypto/libressl/include/compat/netinet/tcp.h b/crypto/libressl/include/compat/netinet/tcp.h new file mode 100644 index 0000000000..c98cf7412d --- /dev/null +++ b/crypto/libressl/include/compat/netinet/tcp.h @@ -0,0 +1,10 @@ +/* + * Public domain + * netinet/tcp.h compatibility shim + */ + +#ifndef _WIN32 +#include_next +#else +#include +#endif diff --git a/crypto/libressl/include/compat/poll.h b/crypto/libressl/include/compat/poll.h new file mode 100644 index 0000000000..e9204cf2cf --- /dev/null +++ b/crypto/libressl/include/compat/poll.h @@ -0,0 +1,63 @@ +/* + * Public domain + * + * poll(2) emulation for Windows + * + * This emulates just-enough poll functionality on Windows to work in the + * context of the openssl(1) program. This is not a replacement for + * POSIX.1-2001 poll(2). + * + * Dongsheng Song + * Brent Cook + */ + +#ifndef LIBCRYPTOCOMPAT_POLL_H +#define LIBCRYPTOCOMPAT_POLL_H + +#ifndef _WIN32 +#include_next +#else + +#include + +/* Type used for the number of file descriptors. */ +typedef unsigned long int nfds_t; + +#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0600) +/* Data structure describing a polling request. */ +struct pollfd { + int fd; /* file descriptor */ + short events; /* requested events */ + short revents; /* returned events */ +}; + +/* Event types that can be polled */ +#define POLLIN 0x001 /* There is data to read. */ +#define POLLPRI 0x002 /* There is urgent data to read. */ +#define POLLOUT 0x004 /* Writing now will not block. */ + +# define POLLRDNORM 0x040 /* Normal data may be read. */ +# define POLLRDBAND 0x080 /* Priority data may be read. */ +# define POLLWRNORM 0x100 /* Writing now will not block. */ +# define POLLWRBAND 0x200 /* Priority data may be written. */ + +/* Event types always implicitly polled. */ +#define POLLERR 0x008 /* Error condition. */ +#define POLLHUP 0x010 /* Hung up. */ +#define POLLNVAL 0x020 /* Invalid polling request. */ + +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +int poll(struct pollfd *pfds, nfds_t nfds, int timeout); + +#ifdef __cplusplus +} +#endif + +#endif /* HAVE_POLL */ + +#endif /* LIBCRYPTOCOMPAT_POLL_H */ diff --git a/crypto/libressl/include/compat/readpassphrase.h b/crypto/libressl/include/compat/readpassphrase.h new file mode 100644 index 0000000000..3416919414 --- /dev/null +++ b/crypto/libressl/include/compat/readpassphrase.h @@ -0,0 +1,44 @@ +/* $OpenBSD: readpassphrase.h,v 1.5 2003/06/17 21:56:23 millert Exp $ */ + +/* + * Copyright (c) 2000, 2002 Todd C. 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. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ + +#ifdef HAVE_READPASSPHRASE_H + +#include_next + +#else + +#ifndef _READPASSPHRASE_H_ +#define _READPASSPHRASE_H_ + +#define RPP_ECHO_OFF 0x00 /* Turn off echo (default). */ +#define RPP_ECHO_ON 0x01 /* Leave echo on. */ +#define RPP_REQUIRE_TTY 0x02 /* Fail if there is no tty. */ +#define RPP_FORCELOWER 0x04 /* Force input to lower case. */ +#define RPP_FORCEUPPER 0x08 /* Force input to upper case. */ +#define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */ +#define RPP_STDIN 0x20 /* Read from stdin, not /dev/tty */ + +char * readpassphrase(const char *, char *, size_t, int); + +#endif /* !_READPASSPHRASE_H_ */ + +#endif diff --git a/crypto/libressl/include/compat/resolv.h b/crypto/libressl/include/compat/resolv.h new file mode 100644 index 0000000000..42dec07b64 --- /dev/null +++ b/crypto/libressl/include/compat/resolv.h @@ -0,0 +1,24 @@ +/* + * Public domain + * resolv.h compatibility shim + */ + +#ifndef LIBCRYPTOCOMPAT_RESOLV_H +#define LIBCRYPTOCOMPAT_RESOLV_H + +#ifdef _MSC_VER +#if _MSC_VER >= 1900 +#include <../ucrt/resolv.h> +#else +#include <../include/resolv.h> +#endif +#else +#include_next +#endif + +#ifndef HAVE_B64_NTOP +int b64_ntop(unsigned char const *, size_t, char *, size_t); +int b64_pton(char const *, unsigned char *, size_t); +#endif + +#endif diff --git a/crypto/libressl/include/compat/stdio.h b/crypto/libressl/include/compat/stdio.h new file mode 100644 index 0000000000..a0dda6f11b --- /dev/null +++ b/crypto/libressl/include/compat/stdio.h @@ -0,0 +1,47 @@ +/* + * Public domain + * stdio.h compatibility shim + */ + +#ifndef LIBCRYPTOCOMPAT_STDIO_H +#define LIBCRYPTOCOMPAT_STDIO_H + +#ifdef _MSC_VER +#if _MSC_VER >= 1900 +#include <../ucrt/stdlib.h> +#include <../ucrt/corecrt_io.h> +#include <../ucrt/stdio.h> +#else +#include <../include/stdio.h> +#endif +#else +#include_next +#endif + +#ifndef HAVE_ASPRINTF +#include +int vasprintf(char **str, const char *fmt, va_list ap); +int asprintf(char **str, const char *fmt, ...); +#endif + +#ifdef _WIN32 + +void posix_perror(const char *s); +FILE * posix_fopen(const char *path, const char *mode); +char * posix_fgets(char *s, int size, FILE *stream); +int posix_rename(const char *oldpath, const char *newpath); + +#ifndef NO_REDEF_POSIX_FUNCTIONS +#define perror(errnum) posix_perror(errnum) +#define fopen(path, mode) posix_fopen(path, mode) +#define fgets(s, size, stream) posix_fgets(s, size, stream) +#define rename(oldpath, newpath) posix_rename(oldpath, newpath) +#endif + +#ifdef _MSC_VER +#define snprintf _snprintf +#endif + +#endif + +#endif diff --git a/crypto/libressl/include/compat/stdlib.h b/crypto/libressl/include/compat/stdlib.h new file mode 100644 index 0000000000..781be77421 --- /dev/null +++ b/crypto/libressl/include/compat/stdlib.h @@ -0,0 +1,37 @@ +/* + * stdlib.h compatibility shim + * Public domain + */ + +#ifdef _MSC_VER +#if _MSC_VER >= 1900 +#include <../ucrt/stdlib.h> +#else +#include <../include/stdlib.h> +#endif +#else +#include_next +#endif + +#ifndef LIBCRYPTOCOMPAT_STDLIB_H +#define LIBCRYPTOCOMPAT_STDLIB_H + +#include +#include + +#ifndef HAVE_ARC4RANDOM_BUF +uint32_t arc4random(void); +void arc4random_buf(void *_buf, size_t n); +uint32_t arc4random_uniform(uint32_t upper_bound); +#endif + +#ifndef HAVE_REALLOCARRAY +void *reallocarray(void *, size_t, size_t); +#endif + +#ifndef HAVE_STRTONUM +long long strtonum(const char *nptr, long long minval, + long long maxval, const char **errstr); +#endif + +#endif diff --git a/crypto/libressl/include/compat/string.h b/crypto/libressl/include/compat/string.h new file mode 100644 index 0000000000..4bf7519b5b --- /dev/null +++ b/crypto/libressl/include/compat/string.h @@ -0,0 +1,87 @@ +/* + * Public domain + * string.h compatibility shim + */ + +#ifndef LIBCRYPTOCOMPAT_STRING_H +#define LIBCRYPTOCOMPAT_STRING_H + +#ifdef _MSC_VER +#if _MSC_VER >= 1900 +#include <../ucrt/string.h> +#else +#include <../include/string.h> +#endif +#else +#include_next +#endif + +#include + +#if defined(__sun) || defined(_AIX) || defined(__hpux) +/* Some functions historically defined in string.h were placed in strings.h by + * SUS. Use the same hack as OS X and FreeBSD use to work around on AIX, + * Solaris, and HPUX. + */ +#include +#endif + +#ifndef HAVE_STRCASECMP +int strcasecmp(const char *s1, const char *s2); +int strncasecmp(const char *s1, const char *s2, size_t len); +#endif + +#ifndef HAVE_STRLCPY +size_t strlcpy(char *dst, const char *src, size_t siz); +#endif + +#ifndef HAVE_STRLCAT +size_t strlcat(char *dst, const char *src, size_t siz); +#endif + +#ifndef HAVE_STRNDUP +char * strndup(const char *str, size_t maxlen); +/* the only user of strnlen is strndup, so only build it if needed */ +#ifndef HAVE_STRNLEN +size_t strnlen(const char *str, size_t maxlen); +#endif +#endif + +#ifndef HAVE_STRSEP +char *strsep(char **stringp, const char *delim); +#endif + +#ifndef HAVE_EXPLICIT_BZERO +void explicit_bzero(void *, size_t); +#endif + +#ifndef HAVE_TIMINGSAFE_BCMP +int timingsafe_bcmp(const void *b1, const void *b2, size_t n); +#endif + +#ifndef HAVE_TIMINGSAFE_MEMCMP +int timingsafe_memcmp(const void *b1, const void *b2, size_t len); +#endif + +#ifndef HAVE_MEMMEM +void * memmem(const void *big, size_t big_len, const void *little, + size_t little_len); +#endif + +#ifdef _WIN32 +#include + +static inline char * +posix_strerror(int errnum) +{ + if (errnum == ECONNREFUSED) { + return "Connection refused"; + } + return strerror(errnum); +} + +#define strerror(errnum) posix_strerror(errnum) + +#endif + +#endif diff --git a/crypto/libressl/include/compat/sys/cdefs.h b/crypto/libressl/include/compat/sys/cdefs.h new file mode 100644 index 0000000000..21ef0311fa --- /dev/null +++ b/crypto/libressl/include/compat/sys/cdefs.h @@ -0,0 +1,31 @@ +/* + * Public domain + * sys/cdefs.h compatibility shim + */ + +#ifndef LIBCRYPTOCOMPAT_SYS_CDEFS_H +#define LIBCRYPTOCOMPAT_SYS_CDEFS_H + +#ifdef _WIN32 + +#define __warn_references(sym,msg) + +#else + +#include_next + +#ifndef __warn_references + +#if defined(__GNUC__) && defined (HAS_GNU_WARNING_LONG) +#define __warn_references(sym,msg) \ + __asm__(".section .gnu.warning." __STRING(sym) \ + " ; .ascii \"" msg "\" ; .text"); +#else +#define __warn_references(sym,msg) +#endif + +#endif /* __warn_references */ + +#endif /* _WIN32 */ + +#endif /* LIBCRYPTOCOMPAT_SYS_CDEFS_H */ diff --git a/crypto/libressl/include/compat/sys/ioctl.h b/crypto/libressl/include/compat/sys/ioctl.h new file mode 100644 index 0000000000..a255506c5c --- /dev/null +++ b/crypto/libressl/include/compat/sys/ioctl.h @@ -0,0 +1,11 @@ +/* + * Public domain + * sys/ioctl.h compatibility shim + */ + +#ifndef _WIN32 +#include_next +#else +#include +#define ioctl(fd, type, arg) ioctlsocket(fd, type, arg) +#endif diff --git a/crypto/libressl/include/compat/sys/mman.h b/crypto/libressl/include/compat/sys/mman.h new file mode 100644 index 0000000000..d9eb6a9572 --- /dev/null +++ b/crypto/libressl/include/compat/sys/mman.h @@ -0,0 +1,19 @@ +/* + * Public domain + * sys/mman.h compatibility shim + */ + +#include_next + +#ifndef LIBCRYPTOCOMPAT_MMAN_H +#define LIBCRYPTOCOMPAT_MMAN_H + +#ifndef MAP_ANON +#ifdef MAP_ANONYMOUS +#define MAP_ANON MAP_ANONYMOUS +#else +#error "System does not support mapping anonymous pages?" +#endif +#endif + +#endif diff --git a/crypto/libressl/include/compat/sys/param.h b/crypto/libressl/include/compat/sys/param.h new file mode 100644 index 0000000000..70488f828c --- /dev/null +++ b/crypto/libressl/include/compat/sys/param.h @@ -0,0 +1,15 @@ +/* + * Public domain + * sys/param.h compatibility shim + */ + +#ifndef LIBCRYPTOCOMPAT_SYS_PARAM_H +#define LIBCRYPTOCOMPAT_SYS_PARAM_H + +#ifdef _MSC_VER +#include +#else +#include_next +#endif + +#endif diff --git a/crypto/libressl/include/compat/sys/select.h b/crypto/libressl/include/compat/sys/select.h new file mode 100644 index 0000000000..5ca0ea156a --- /dev/null +++ b/crypto/libressl/include/compat/sys/select.h @@ -0,0 +1,10 @@ +/* + * Public domain + * sys/select.h compatibility shim + */ + +#ifndef _WIN32 +#include_next +#else +#include +#endif diff --git a/crypto/libressl/include/compat/sys/socket.h b/crypto/libressl/include/compat/sys/socket.h new file mode 100644 index 0000000000..17e84f168d --- /dev/null +++ b/crypto/libressl/include/compat/sys/socket.h @@ -0,0 +1,10 @@ +/* + * Public domain + * sys/socket.h compatibility shim + */ + +#ifndef _WIN32 +#include_next +#else +#include +#endif diff --git a/crypto/libressl/include/compat/sys/stat.h b/crypto/libressl/include/compat/sys/stat.h new file mode 100644 index 0000000000..0e04553675 --- /dev/null +++ b/crypto/libressl/include/compat/sys/stat.h @@ -0,0 +1,100 @@ +/* + * Public domain + * sys/stat.h compatibility shim + */ + +#ifndef LIBCRYPTOCOMPAT_SYS_STAT_H +#define LIBCRYPTOCOMPAT_SYS_STAT_H + +#ifndef _MSC_VER +#include_next +#else + +#include +#if _MSC_VER >= 1900 +#include <../ucrt/sys/stat.h> +#else +#include <../include/sys/stat.h> +#endif + +/* File type and permission flags for stat() */ +#if !defined(S_IFMT) +# define S_IFMT _S_IFMT /* File type mask */ +#endif +#if !defined(S_IFDIR) +# define S_IFDIR _S_IFDIR /* Directory */ +#endif +#if !defined(S_IFCHR) +# define S_IFCHR _S_IFCHR /* Character device */ +#endif +#if !defined(S_IFFIFO) +# define S_IFFIFO _S_IFFIFO /* Pipe */ +#endif +#if !defined(S_IFREG) +# define S_IFREG _S_IFREG /* Regular file */ +#endif +#if !defined(S_IREAD) +# define S_IREAD _S_IREAD /* Read permission */ +#endif +#if !defined(S_IWRITE) +# define S_IWRITE _S_IWRITE /* Write permission */ +#endif +#if !defined(S_IEXEC) +# define S_IEXEC _S_IEXEC /* Execute permission */ +#endif +#if !defined(S_IFIFO) +# define S_IFIFO _S_IFIFO /* Pipe */ +#endif +#if !defined(S_IFBLK) +# define S_IFBLK 0 /* Block device */ +#endif +#if !defined(S_IFLNK) +# define S_IFLNK 0 /* Link */ +#endif +#if !defined(S_IFSOCK) +# define S_IFSOCK 0 /* Socket */ +#endif + +#if defined(_MSC_VER) +# define S_IRUSR S_IREAD /* Read user */ +# define S_IWUSR S_IWRITE /* Write user */ +# define S_IXUSR 0 /* Execute user */ +# define S_IRGRP 0 /* Read group */ +# define S_IWGRP 0 /* Write group */ +# define S_IXGRP 0 /* Execute group */ +# define S_IROTH 0 /* Read others */ +# define S_IWOTH 0 /* Write others */ +# define S_IXOTH 0 /* Execute others */ +#endif + +/* File type flags for d_type */ +#define DT_UNKNOWN 0 +#define DT_REG S_IFREG +#define DT_DIR S_IFDIR +#define DT_FIFO S_IFIFO +#define DT_SOCK S_IFSOCK +#define DT_CHR S_IFCHR +#define DT_BLK S_IFBLK +#define DT_LNK S_IFLNK + +/* Macros for converting between st_mode and d_type */ +#define IFTODT(mode) ((mode) & S_IFMT) +#define DTTOIF(type) (type) + +/* + * File type macros. Note that block devices, sockets and links cannot be + * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are + * only defined for compatibility. These macros should always return false + * on Windows. + */ +#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) +#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) +#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) +#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) + +#endif + +#endif diff --git a/crypto/libressl/include/compat/sys/time.h b/crypto/libressl/include/compat/sys/time.h new file mode 100644 index 0000000000..235bc6eea5 --- /dev/null +++ b/crypto/libressl/include/compat/sys/time.h @@ -0,0 +1,16 @@ +/* + * Public domain + * sys/time.h compatibility shim + */ + +#ifndef LIBCRYPTOCOMPAT_SYS_TIME_H +#define LIBCRYPTOCOMPAT_SYS_TIME_H + +#ifdef _MSC_VER +#include +int gettimeofday(struct timeval *tp, void *tzp); +#else +#include_next +#endif + +#endif diff --git a/crypto/libressl/include/compat/sys/types.h b/crypto/libressl/include/compat/sys/types.h new file mode 100644 index 0000000000..1e9979fed0 --- /dev/null +++ b/crypto/libressl/include/compat/sys/types.h @@ -0,0 +1,47 @@ +/* + * Public domain + * sys/types.h compatibility shim + */ + +#ifdef _MSC_VER +#if _MSC_VER >= 1900 +#include <../ucrt/sys/types.h> +#else +#include <../include/sys/types.h> +#endif +#else +#include_next +#endif + +#ifndef LIBCRYPTOCOMPAT_SYS_TYPES_H +#define LIBCRYPTOCOMPAT_SYS_TYPES_H + +#include + +#ifdef __MINGW32__ +#include <_bsd_types.h> +#endif + +#ifdef _MSC_VER +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; + +#include +typedef SSIZE_T ssize_t; + +#ifndef SSIZE_MAX +#ifdef _WIN64 +#define SSIZE_MAX _I64_MAX +#else +#define SSIZE_MAX INT_MAX +#endif +#endif + +#endif + +#if !defined(HAVE_ATTRIBUTE__BOUNDED__) && !defined(__bounded__) +# define __bounded__(x, y, z) +#endif + +#endif diff --git a/crypto/libressl/include/compat/sys/uio.h b/crypto/libressl/include/compat/sys/uio.h new file mode 100644 index 0000000000..b4aee9e3b6 --- /dev/null +++ b/crypto/libressl/include/compat/sys/uio.h @@ -0,0 +1,17 @@ +/* + * Public domain + * sys/select.h compatibility shim + */ + +#ifndef _WIN32 +#include_next +#else + +#include + +struct iovec { + void *iov_base; + size_t iov_len; +}; + +#endif diff --git a/crypto/libressl/include/compat/time.h b/crypto/libressl/include/compat/time.h new file mode 100644 index 0000000000..99a2001fea --- /dev/null +++ b/crypto/libressl/include/compat/time.h @@ -0,0 +1,23 @@ +/* + * Public domain + * sys/time.h compatibility shim + */ + +#ifdef _MSC_VER +#if _MSC_VER >= 1900 +#include <../ucrt/time.h> +#else +#include <../include/time.h> +#endif +#else +#include_next +#endif + +#ifdef _WIN32 +struct tm *__gmtime_r(const time_t * t, struct tm * tm); +#define gmtime_r(tp, tm) __gmtime_r(tp, tm) +#endif + +#ifndef HAVE_TIMEGM +time_t timegm(struct tm *tm); +#endif diff --git a/crypto/libressl/include/compat/unistd.h b/crypto/libressl/include/compat/unistd.h new file mode 100644 index 0000000000..6c83e767ac --- /dev/null +++ b/crypto/libressl/include/compat/unistd.h @@ -0,0 +1,41 @@ +/* + * Public domain + * unistd.h compatibility shim + */ + +#ifndef LIBCRYPTOCOMPAT_UNISTD_H +#define LIBCRYPTOCOMPAT_UNISTD_H + +#ifndef _MSC_VER +#include_next +#else + +#include +#include +#include + +#define R_OK 4 +#define W_OK 2 +#define X_OK 0 +#define F_OK 0 + +#define access _access + +unsigned int sleep(unsigned int seconds); + +#endif + +#ifndef HAVE_GETENTROPY +int getentropy(void *buf, size_t buflen); +#else +/* + * Solaris 11.3 adds getentropy(2), but defines the function in sys/random.h + */ +#if defined(__sun) +#include +#endif +#endif + +#define pledge(request, paths) 0 + +#endif diff --git a/crypto/libressl/include/compat/win32netcompat.h b/crypto/libressl/include/compat/win32netcompat.h new file mode 100644 index 0000000000..933f083ed4 --- /dev/null +++ b/crypto/libressl/include/compat/win32netcompat.h @@ -0,0 +1,53 @@ +/* + * Public domain + * + * BSD socket emulation code for Winsock2 + * Brent Cook + */ + +#ifndef LIBCRYPTOCOMPAT_WIN32NETCOMPAT_H +#define LIBCRYPTOCOMPAT_WIN32NETCOMPAT_H + +#ifdef _WIN32 + +#include +#include +#include + +#ifndef SHUT_RDWR +#define SHUT_RDWR SD_BOTH +#endif +#ifndef SHUT_RD +#define SHUT_RD SD_RECEIVE +#endif +#ifndef SHUT_WR +#define SHUT_WR SD_SEND +#endif + +int posix_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); + +int posix_close(int fd); +ssize_t posix_read(int fd, void *buf, size_t count); + +ssize_t posix_write(int fd, const void *buf, size_t count); + +int posix_getsockopt(int sockfd, int level, int optname, + void *optval, socklen_t *optlen); + +int posix_setsockopt(int sockfd, int level, int optname, + const void *optval, socklen_t optlen); + +#ifndef NO_REDEF_POSIX_FUNCTIONS +#define connect(sockfd, addr, addrlen) posix_connect(sockfd, addr, addrlen) +#define close(fd) posix_close(fd) +#define read(fd, buf, count) posix_read(fd, buf, count) +#define write(fd, buf, count) posix_write(fd, buf, count) +#define getsockopt(sockfd, level, optname, optval, optlen) \ + posix_getsockopt(sockfd, level, optname, optval, optlen) +#define setsockopt(sockfd, level, optname, optval, optlen) \ + posix_setsockopt(sockfd, level, optname, optval, optlen) +#endif + +#endif + +#endif diff --git a/crypto/libressl/include/openssl/aes.h b/crypto/libressl/include/openssl/aes.h new file mode 100644 index 0000000000..13efe391d6 --- /dev/null +++ b/crypto/libressl/include/openssl/aes.h @@ -0,0 +1,126 @@ +/* $OpenBSD: aes.h,v 1.13 2014/06/12 15:49:27 deraadt Exp $ */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#ifndef HEADER_AES_H +#define HEADER_AES_H + +#include + +#ifdef OPENSSL_NO_AES +#error AES is disabled. +#endif + +#include + +#define AES_ENCRYPT 1 +#define AES_DECRYPT 0 + +/* Because array size can't be a const in C, the following two are macros. + Both sizes are in bytes. */ +#define AES_MAXNR 14 +#define AES_BLOCK_SIZE 16 + +#ifdef __cplusplus +extern "C" { +#endif + +/* This should be a hidden type, but EVP requires that the size be known */ +struct aes_key_st { + unsigned int rd_key[4 *(AES_MAXNR + 1)]; + int rounds; +}; +typedef struct aes_key_st AES_KEY; + +const char *AES_options(void); + +int AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); +int AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); + +void AES_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void AES_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); + +void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key, const int enc); +void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, unsigned char *ivec, const int enc); +void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, unsigned char *ivec, int *num, + const int enc); +void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, unsigned char *ivec, int *num, + const int enc); +void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, unsigned char *ivec, int *num, + const int enc); +void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, unsigned char *ivec, int *num); +void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], + unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); +/* NB: the IV is _two_ blocks long */ +void AES_ige_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, unsigned char *ivec, const int enc); + +int AES_wrap_key(AES_KEY *key, const unsigned char *iv, unsigned char *out, + const unsigned char *in, unsigned int inlen); +int AES_unwrap_key(AES_KEY *key, const unsigned char *iv, unsigned char *out, + const unsigned char *in, unsigned int inlen); + + +#ifdef __cplusplus +} +#endif + +#endif /* !HEADER_AES_H */ diff --git a/crypto/libressl/include/openssl/asn1.h b/crypto/libressl/include/openssl/asn1.h new file mode 100644 index 0000000000..af7f6c0c25 --- /dev/null +++ b/crypto/libressl/include/openssl/asn1.h @@ -0,0 +1,1363 @@ +/* $OpenBSD: asn1.h,v 1.33 2015/10/08 02:42:58 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_ASN1_H +#define HEADER_ASN1_H + +#include + +#include + +#ifndef OPENSSL_NO_BIO +#include +#endif +#include +#include + +#include +#ifndef OPENSSL_NO_DEPRECATED +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define V_ASN1_UNIVERSAL 0x00 +#define V_ASN1_APPLICATION 0x40 +#define V_ASN1_CONTEXT_SPECIFIC 0x80 +#define V_ASN1_PRIVATE 0xc0 + +#define V_ASN1_CONSTRUCTED 0x20 +#define V_ASN1_PRIMITIVE_TAG 0x1f +#define V_ASN1_PRIMATIVE_TAG 0x1f + +#define V_ASN1_APP_CHOOSE -2 /* let the recipient choose */ +#define V_ASN1_OTHER -3 /* used in ASN1_TYPE */ +#define V_ASN1_ANY -4 /* used in ASN1 template code */ + +#define V_ASN1_NEG 0x100 /* negative flag */ + +#define V_ASN1_UNDEF -1 +#define V_ASN1_EOC 0 +#define V_ASN1_BOOLEAN 1 /**/ +#define V_ASN1_INTEGER 2 +#define V_ASN1_NEG_INTEGER (2 | V_ASN1_NEG) +#define V_ASN1_BIT_STRING 3 +#define V_ASN1_OCTET_STRING 4 +#define V_ASN1_NULL 5 +#define V_ASN1_OBJECT 6 +#define V_ASN1_OBJECT_DESCRIPTOR 7 +#define V_ASN1_EXTERNAL 8 +#define V_ASN1_REAL 9 +#define V_ASN1_ENUMERATED 10 +#define V_ASN1_NEG_ENUMERATED (10 | V_ASN1_NEG) +#define V_ASN1_UTF8STRING 12 +#define V_ASN1_SEQUENCE 16 +#define V_ASN1_SET 17 +#define V_ASN1_NUMERICSTRING 18 /**/ +#define V_ASN1_PRINTABLESTRING 19 +#define V_ASN1_T61STRING 20 +#define V_ASN1_TELETEXSTRING 20 /* alias */ +#define V_ASN1_VIDEOTEXSTRING 21 /**/ +#define V_ASN1_IA5STRING 22 +#define V_ASN1_UTCTIME 23 +#define V_ASN1_GENERALIZEDTIME 24 /**/ +#define V_ASN1_GRAPHICSTRING 25 /**/ +#define V_ASN1_ISO64STRING 26 /**/ +#define V_ASN1_VISIBLESTRING 26 /* alias */ +#define V_ASN1_GENERALSTRING 27 /**/ +#define V_ASN1_UNIVERSALSTRING 28 /**/ +#define V_ASN1_BMPSTRING 30 + +/* For use with d2i_ASN1_type_bytes() */ +#define B_ASN1_NUMERICSTRING 0x0001 +#define B_ASN1_PRINTABLESTRING 0x0002 +#define B_ASN1_T61STRING 0x0004 +#define B_ASN1_TELETEXSTRING 0x0004 +#define B_ASN1_VIDEOTEXSTRING 0x0008 +#define B_ASN1_IA5STRING 0x0010 +#define B_ASN1_GRAPHICSTRING 0x0020 +#define B_ASN1_ISO64STRING 0x0040 +#define B_ASN1_VISIBLESTRING 0x0040 +#define B_ASN1_GENERALSTRING 0x0080 +#define B_ASN1_UNIVERSALSTRING 0x0100 +#define B_ASN1_OCTET_STRING 0x0200 +#define B_ASN1_BIT_STRING 0x0400 +#define B_ASN1_BMPSTRING 0x0800 +#define B_ASN1_UNKNOWN 0x1000 +#define B_ASN1_UTF8STRING 0x2000 +#define B_ASN1_UTCTIME 0x4000 +#define B_ASN1_GENERALIZEDTIME 0x8000 +#define B_ASN1_SEQUENCE 0x10000 + +/* For use with ASN1_mbstring_copy() */ +#define MBSTRING_FLAG 0x1000 +#define MBSTRING_UTF8 (MBSTRING_FLAG) +#define MBSTRING_ASC (MBSTRING_FLAG|1) +#define MBSTRING_BMP (MBSTRING_FLAG|2) +#define MBSTRING_UNIV (MBSTRING_FLAG|4) + +#define SMIME_OLDMIME 0x400 +#define SMIME_CRLFEOL 0x800 +#define SMIME_STREAM 0x1000 + +struct X509_algor_st; +DECLARE_STACK_OF(X509_ALGOR) + +#define DECLARE_ASN1_SET_OF(type) /* filled in by mkstack.pl */ +#define IMPLEMENT_ASN1_SET_OF(type) /* nothing, no longer needed */ + +/* We MUST make sure that, except for constness, asn1_ctx_st and + asn1_const_ctx are exactly the same. Fortunately, as soon as + the old ASN1 parsing macros are gone, we can throw this away + as well... */ +typedef struct asn1_ctx_st { + unsigned char *p;/* work char pointer */ + int eos; /* end of sequence read for indefinite encoding */ + int error; /* error code to use when returning an error */ + int inf; /* constructed if 0x20, indefinite is 0x21 */ + int tag; /* tag from last 'get object' */ + int xclass; /* class from last 'get object' */ + long slen; /* length of last 'get object' */ + unsigned char *max; /* largest value of p allowed */ + unsigned char *q;/* temporary variable */ + unsigned char **pp;/* variable */ + int line; /* used in error processing */ +} ASN1_CTX; + +typedef struct asn1_const_ctx_st { + const unsigned char *p;/* work char pointer */ + int eos; /* end of sequence read for indefinite encoding */ + int error; /* error code to use when returning an error */ + int inf; /* constructed if 0x20, indefinite is 0x21 */ + int tag; /* tag from last 'get object' */ + int xclass; /* class from last 'get object' */ + long slen; /* length of last 'get object' */ + const unsigned char *max; /* largest value of p allowed */ + const unsigned char *q;/* temporary variable */ + const unsigned char **pp;/* variable */ + int line; /* used in error processing */ +} ASN1_const_CTX; + +/* These are used internally in the ASN1_OBJECT to keep track of + * whether the names and data need to be free()ed */ +#define ASN1_OBJECT_FLAG_DYNAMIC 0x01 /* internal use */ +#define ASN1_OBJECT_FLAG_CRITICAL 0x02 /* critical x509v3 object id */ +#define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04 /* internal use */ +#define ASN1_OBJECT_FLAG_DYNAMIC_DATA 0x08 /* internal use */ +typedef struct asn1_object_st { + const char *sn, *ln; + int nid; + int length; + const unsigned char *data; /* data remains const after init */ + int flags; /* Should we free this one */ +} ASN1_OBJECT; + +#define ASN1_STRING_FLAG_BITS_LEFT 0x08 /* Set if 0x07 has bits left value */ +/* This indicates that the ASN1_STRING is not a real value but just a place + * holder for the location where indefinite length constructed data should + * be inserted in the memory buffer + */ +#define ASN1_STRING_FLAG_NDEF 0x010 + +/* This flag is used by the CMS code to indicate that a string is not + * complete and is a place holder for content when it had all been + * accessed. The flag will be reset when content has been written to it. + */ + +#define ASN1_STRING_FLAG_CONT 0x020 +/* This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING + * type. + */ +#define ASN1_STRING_FLAG_MSTRING 0x040 +/* This is the base type that holds just about everything :-) */ +struct asn1_string_st { + int length; + int type; + unsigned char *data; + /* The value of the following field depends on the type being + * held. It is mostly being used for BIT_STRING so if the + * input data has a non-zero 'unused bits' value, it will be + * handled correctly */ + long flags; +}; + +/* ASN1_ENCODING structure: this is used to save the received + * encoding of an ASN1 type. This is useful to get round + * problems with invalid encodings which can break signatures. + */ + +typedef struct ASN1_ENCODING_st { + unsigned char *enc; /* DER encoding */ + long len; /* Length of encoding */ + int modified; /* set to 1 if 'enc' is invalid */ +} ASN1_ENCODING; + +/* Used with ASN1 LONG type: if a long is set to this it is omitted */ +#define ASN1_LONG_UNDEF 0x7fffffffL + +#define STABLE_FLAGS_MALLOC 0x01 +#define STABLE_NO_MASK 0x02 +#define DIRSTRING_TYPE \ + (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING) +#define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING) + +typedef struct asn1_string_table_st { + int nid; + long minsize; + long maxsize; + unsigned long mask; + unsigned long flags; +} ASN1_STRING_TABLE; + +DECLARE_STACK_OF(ASN1_STRING_TABLE) + +/* size limits: this stuff is taken straight from RFC2459 */ + +#define ub_name 32768 +#define ub_common_name 64 +#define ub_locality_name 128 +#define ub_state_name 128 +#define ub_organization_name 64 +#define ub_organization_unit_name 64 +#define ub_title 64 +#define ub_email_address 128 + +/* Declarations for template structures: for full definitions + * see asn1t.h + */ +typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE; +typedef struct ASN1_TLC_st ASN1_TLC; +/* This is just an opaque pointer */ +typedef struct ASN1_VALUE_st ASN1_VALUE; + +/* Declare ASN1 functions: the implement macro in in asn1t.h */ + +#define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type) + +#define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type) + +#define DECLARE_ASN1_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) + +#define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) + +#define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \ + type *d2i_##name(type **a, const unsigned char **in, long len); \ + int i2d_##name(type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(itname) + +#define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \ + type *d2i_##name(type **a, const unsigned char **in, long len); \ + int i2d_##name(const type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(name) + +#define DECLARE_ASN1_NDEF_FUNCTION(name) \ + int i2d_##name##_NDEF(name *a, unsigned char **out); + +#define DECLARE_ASN1_FUNCTIONS_const(name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS(name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name) + +#define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + type *name##_new(void); \ + void name##_free(type *a); + +#define DECLARE_ASN1_PRINT_FUNCTION(stname) \ + DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname) + +#define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \ + int fname##_print_ctx(BIO *out, stname *x, int indent, \ + const ASN1_PCTX *pctx); + +#define D2I_OF(type) type *(*)(type **,const unsigned char **,long) +#define I2D_OF(type) int (*)(type *,unsigned char **) +#define I2D_OF_const(type) int (*)(const type *,unsigned char **) + +#define CHECKED_D2I_OF(type, d2i) \ + ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0))) +#define CHECKED_I2D_OF(type, i2d) \ + ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0))) +#define CHECKED_NEW_OF(type, xnew) \ + ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0))) +#define CHECKED_PTR_OF(type, p) \ + ((void*) (1 ? p : (type*)0)) +#define CHECKED_PPTR_OF(type, p) \ + ((void**) (1 ? p : (type**)0)) + +#define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long) +#define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **) +#define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type) + +TYPEDEF_D2I2D_OF(void); + +/* The following macros and typedefs allow an ASN1_ITEM + * to be embedded in a structure and referenced. Since + * the ASN1_ITEM pointers need to be globally accessible + * (possibly from shared libraries) they may exist in + * different forms. On platforms that support it the + * ASN1_ITEM structure itself will be globally exported. + * Other platforms will export a function that returns + * an ASN1_ITEM pointer. + * + * To handle both cases transparently the macros below + * should be used instead of hard coding an ASN1_ITEM + * pointer in a structure. + * + * The structure will look like this: + * + * typedef struct SOMETHING_st { + * ... + * ASN1_ITEM_EXP *iptr; + * ... + * } SOMETHING; + * + * It would be initialised as e.g.: + * + * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...}; + * + * and the actual pointer extracted with: + * + * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr); + * + * Finally an ASN1_ITEM pointer can be extracted from an + * appropriate reference with: ASN1_ITEM_rptr(X509). This + * would be used when a function takes an ASN1_ITEM * argument. + * + */ + + +/* ASN1_ITEM pointer exported type */ +typedef const ASN1_ITEM ASN1_ITEM_EXP; + +/* Macro to obtain ASN1_ITEM pointer from exported type */ +#define ASN1_ITEM_ptr(iptr) (iptr) + +/* Macro to include ASN1_ITEM pointer from base type */ +#define ASN1_ITEM_ref(iptr) (&(iptr##_it)) + +#define ASN1_ITEM_rptr(ref) (&(ref##_it)) + +#define DECLARE_ASN1_ITEM(name) \ + extern const ASN1_ITEM name##_it; + + +/* Parameters used by ASN1_STRING_print_ex() */ + +/* These determine which characters to escape: + * RFC2253 special characters, control characters and + * MSB set characters + */ + +#define ASN1_STRFLGS_ESC_2253 1 +#define ASN1_STRFLGS_ESC_CTRL 2 +#define ASN1_STRFLGS_ESC_MSB 4 + + +/* This flag determines how we do escaping: normally + * RC2253 backslash only, set this to use backslash and + * quote. + */ + +#define ASN1_STRFLGS_ESC_QUOTE 8 + + +/* These three flags are internal use only. */ + +/* Character is a valid PrintableString character */ +#define CHARTYPE_PRINTABLESTRING 0x10 +/* Character needs escaping if it is the first character */ +#define CHARTYPE_FIRST_ESC_2253 0x20 +/* Character needs escaping if it is the last character */ +#define CHARTYPE_LAST_ESC_2253 0x40 + +/* NB the internal flags are safely reused below by flags + * handled at the top level. + */ + +/* If this is set we convert all character strings + * to UTF8 first + */ + +#define ASN1_STRFLGS_UTF8_CONVERT 0x10 + +/* If this is set we don't attempt to interpret content: + * just assume all strings are 1 byte per character. This + * will produce some pretty odd looking output! + */ + +#define ASN1_STRFLGS_IGNORE_TYPE 0x20 + +/* If this is set we include the string type in the output */ +#define ASN1_STRFLGS_SHOW_TYPE 0x40 + +/* This determines which strings to display and which to + * 'dump' (hex dump of content octets or DER encoding). We can + * only dump non character strings or everything. If we + * don't dump 'unknown' they are interpreted as character + * strings with 1 octet per character and are subject to + * the usual escaping options. + */ + +#define ASN1_STRFLGS_DUMP_ALL 0x80 +#define ASN1_STRFLGS_DUMP_UNKNOWN 0x100 + +/* These determine what 'dumping' does, we can dump the + * content octets or the DER encoding: both use the + * RFC2253 #NNNNN notation. + */ + +#define ASN1_STRFLGS_DUMP_DER 0x200 + +/* All the string flags consistent with RFC2253, + * escaping control characters isn't essential in + * RFC2253 but it is advisable anyway. + */ + +#define ASN1_STRFLGS_RFC2253 (ASN1_STRFLGS_ESC_2253 | \ + ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + ASN1_STRFLGS_UTF8_CONVERT | \ + ASN1_STRFLGS_DUMP_UNKNOWN | \ + ASN1_STRFLGS_DUMP_DER) + +DECLARE_STACK_OF(ASN1_INTEGER) +DECLARE_ASN1_SET_OF(ASN1_INTEGER) + +DECLARE_STACK_OF(ASN1_GENERALSTRING) + +typedef struct asn1_type_st { + int type; + union { + char *ptr; + ASN1_BOOLEAN boolean; + ASN1_STRING * asn1_string; + ASN1_OBJECT * object; + ASN1_INTEGER * integer; + ASN1_ENUMERATED * enumerated; + ASN1_BIT_STRING * bit_string; + ASN1_OCTET_STRING * octet_string; + ASN1_PRINTABLESTRING * printablestring; + ASN1_T61STRING * t61string; + ASN1_IA5STRING * ia5string; + ASN1_GENERALSTRING * generalstring; + ASN1_BMPSTRING * bmpstring; + ASN1_UNIVERSALSTRING * universalstring; + ASN1_UTCTIME * utctime; + ASN1_GENERALIZEDTIME * generalizedtime; + ASN1_VISIBLESTRING * visiblestring; + ASN1_UTF8STRING * utf8string; + /* set and sequence are left complete and still + * contain the set or sequence bytes */ + ASN1_STRING * set; + ASN1_STRING * sequence; + ASN1_VALUE * asn1_value; + } value; +} ASN1_TYPE; + +DECLARE_STACK_OF(ASN1_TYPE) +DECLARE_ASN1_SET_OF(ASN1_TYPE) + +typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY; + +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY) + +typedef struct NETSCAPE_X509_st { + ASN1_OCTET_STRING *header; + X509 *cert; +} NETSCAPE_X509; + +/* This is used to contain a list of bit names */ +typedef struct BIT_STRING_BITNAME_st { + int bitnum; + const char *lname; + const char *sname; +} BIT_STRING_BITNAME; + +#ifndef LIBRESSL_INTERNAL + +#define M_ASN1_STRING_length(x) ((x)->length) +#define M_ASN1_STRING_length_set(x, n) ((x)->length = (n)) +#define M_ASN1_STRING_type(x) ((x)->type) +#define M_ASN1_STRING_data(x) ((x)->data) + +/* Macros for string operations */ +#define M_ASN1_BIT_STRING_new() (ASN1_BIT_STRING *)\ + ASN1_STRING_type_new(V_ASN1_BIT_STRING) +#define M_ASN1_BIT_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) +#define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\ + (const ASN1_STRING *)a,(const ASN1_STRING *)b) +#define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c) + +#define M_ASN1_INTEGER_new() (ASN1_INTEGER *)\ + ASN1_STRING_type_new(V_ASN1_INTEGER) +#define M_ASN1_INTEGER_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) +#define M_ASN1_INTEGER_cmp(a,b) ASN1_STRING_cmp(\ + (const ASN1_STRING *)a,(const ASN1_STRING *)b) + +#define M_ASN1_ENUMERATED_new() (ASN1_ENUMERATED *)\ + ASN1_STRING_type_new(V_ASN1_ENUMERATED) +#define M_ASN1_ENUMERATED_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) +#define M_ASN1_ENUMERATED_cmp(a,b) ASN1_STRING_cmp(\ + (const ASN1_STRING *)a,(const ASN1_STRING *)b) + +#define M_ASN1_OCTET_STRING_new() (ASN1_OCTET_STRING *)\ + ASN1_STRING_type_new(V_ASN1_OCTET_STRING) +#define M_ASN1_OCTET_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) +#define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\ + (const ASN1_STRING *)a,(const ASN1_STRING *)b) +#define M_ASN1_OCTET_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c) +#define M_ASN1_OCTET_STRING_print(a,b) ASN1_STRING_print(a,(ASN1_STRING *)b) +#define M_i2d_ASN1_OCTET_STRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_OCTET_STRING,\ + V_ASN1_UNIVERSAL) + +#define M_ASN1_PRINTABLE_new() ASN1_STRING_type_new(V_ASN1_T61STRING) +#define M_ASN1_PRINTABLE_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_i2d_ASN1_PRINTABLE(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\ + pp,a->type,V_ASN1_UNIVERSAL) +#define M_d2i_ASN1_PRINTABLE(a,pp,l) \ + d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \ + B_ASN1_PRINTABLE) + +#define M_DIRECTORYSTRING_new() ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING) +#define M_DIRECTORYSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_i2d_DIRECTORYSTRING(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\ + pp,a->type,V_ASN1_UNIVERSAL) +#define M_d2i_DIRECTORYSTRING(a,pp,l) \ + d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \ + B_ASN1_DIRECTORYSTRING) + +#define M_DISPLAYTEXT_new() ASN1_STRING_type_new(V_ASN1_VISIBLESTRING) +#define M_DISPLAYTEXT_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_i2d_DISPLAYTEXT(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\ + pp,a->type,V_ASN1_UNIVERSAL) +#define M_d2i_DISPLAYTEXT(a,pp,l) \ + d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \ + B_ASN1_DISPLAYTEXT) + +#define M_ASN1_PRINTABLESTRING_new() (ASN1_PRINTABLESTRING *)\ + ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING) +#define M_ASN1_PRINTABLESTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_i2d_ASN1_PRINTABLESTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_PRINTABLESTRING,\ + V_ASN1_UNIVERSAL) +#define M_d2i_ASN1_PRINTABLESTRING(a,pp,l) \ + (ASN1_PRINTABLESTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_PRINTABLESTRING) + +#define M_ASN1_T61STRING_new() (ASN1_T61STRING *)\ + ASN1_STRING_type_new(V_ASN1_T61STRING) +#define M_ASN1_T61STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_i2d_ASN1_T61STRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_T61STRING,\ + V_ASN1_UNIVERSAL) +#define M_d2i_ASN1_T61STRING(a,pp,l) \ + (ASN1_T61STRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_T61STRING) + +#define M_ASN1_IA5STRING_new() (ASN1_IA5STRING *)\ + ASN1_STRING_type_new(V_ASN1_IA5STRING) +#define M_ASN1_IA5STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_ASN1_IA5STRING_dup(a) \ + (ASN1_IA5STRING *)ASN1_STRING_dup((const ASN1_STRING *)a) +#define M_i2d_ASN1_IA5STRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\ + V_ASN1_UNIVERSAL) +#define M_d2i_ASN1_IA5STRING(a,pp,l) \ + (ASN1_IA5STRING *)d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l,\ + B_ASN1_IA5STRING) + +#define M_ASN1_UTCTIME_new() (ASN1_UTCTIME *)\ + ASN1_STRING_type_new(V_ASN1_UTCTIME) +#define M_ASN1_UTCTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) + +#define M_ASN1_GENERALIZEDTIME_new() (ASN1_GENERALIZEDTIME *)\ + ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME) +#define M_ASN1_GENERALIZEDTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\ + (const ASN1_STRING *)a) + +#define M_ASN1_TIME_new() (ASN1_TIME *)\ + ASN1_STRING_type_new(V_ASN1_UTCTIME) +#define M_ASN1_TIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_ASN1_TIME_dup(a) (ASN1_TIME *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) + +#define M_ASN1_GENERALSTRING_new() (ASN1_GENERALSTRING *)\ + ASN1_STRING_type_new(V_ASN1_GENERALSTRING) +#define M_ASN1_GENERALSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_i2d_ASN1_GENERALSTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_GENERALSTRING,\ + V_ASN1_UNIVERSAL) +#define M_d2i_ASN1_GENERALSTRING(a,pp,l) \ + (ASN1_GENERALSTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_GENERALSTRING) + +#define M_ASN1_UNIVERSALSTRING_new() (ASN1_UNIVERSALSTRING *)\ + ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING) +#define M_ASN1_UNIVERSALSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_i2d_ASN1_UNIVERSALSTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UNIVERSALSTRING,\ + V_ASN1_UNIVERSAL) +#define M_d2i_ASN1_UNIVERSALSTRING(a,pp,l) \ + (ASN1_UNIVERSALSTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_UNIVERSALSTRING) + +#define M_ASN1_BMPSTRING_new() (ASN1_BMPSTRING *)\ + ASN1_STRING_type_new(V_ASN1_BMPSTRING) +#define M_ASN1_BMPSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_i2d_ASN1_BMPSTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_BMPSTRING,\ + V_ASN1_UNIVERSAL) +#define M_d2i_ASN1_BMPSTRING(a,pp,l) \ + (ASN1_BMPSTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_BMPSTRING) + +#define M_ASN1_VISIBLESTRING_new() (ASN1_VISIBLESTRING *)\ + ASN1_STRING_type_new(V_ASN1_VISIBLESTRING) +#define M_ASN1_VISIBLESTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_i2d_ASN1_VISIBLESTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_VISIBLESTRING,\ + V_ASN1_UNIVERSAL) +#define M_d2i_ASN1_VISIBLESTRING(a,pp,l) \ + (ASN1_VISIBLESTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_VISIBLESTRING) + +#define M_ASN1_UTF8STRING_new() (ASN1_UTF8STRING *)\ + ASN1_STRING_type_new(V_ASN1_UTF8STRING) +#define M_ASN1_UTF8STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_i2d_ASN1_UTF8STRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UTF8STRING,\ + V_ASN1_UNIVERSAL) +#define M_d2i_ASN1_UTF8STRING(a,pp,l) \ + (ASN1_UTF8STRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_UTF8STRING) + +#endif + +#define B_ASN1_TIME \ + B_ASN1_UTCTIME | \ + B_ASN1_GENERALIZEDTIME + +#define B_ASN1_PRINTABLE \ + B_ASN1_NUMERICSTRING| \ + B_ASN1_PRINTABLESTRING| \ + B_ASN1_T61STRING| \ + B_ASN1_IA5STRING| \ + B_ASN1_BIT_STRING| \ + B_ASN1_UNIVERSALSTRING|\ + B_ASN1_BMPSTRING|\ + B_ASN1_UTF8STRING|\ + B_ASN1_SEQUENCE|\ + B_ASN1_UNKNOWN + +#define B_ASN1_DIRECTORYSTRING \ + B_ASN1_PRINTABLESTRING| \ + B_ASN1_TELETEXSTRING|\ + B_ASN1_BMPSTRING|\ + B_ASN1_UNIVERSALSTRING|\ + B_ASN1_UTF8STRING + +#define B_ASN1_DISPLAYTEXT \ + B_ASN1_IA5STRING| \ + B_ASN1_VISIBLESTRING| \ + B_ASN1_BMPSTRING|\ + B_ASN1_UTF8STRING + +/* for the is_set parameter to i2d_ASN1_SET */ +#define IS_SEQUENCE 0 +#define IS_SET 1 + +DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE) + +int ASN1_TYPE_get(ASN1_TYPE *a); +void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value); +int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value); +int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b); + +ASN1_OBJECT *ASN1_OBJECT_new(void ); +void ASN1_OBJECT_free(ASN1_OBJECT *a); +int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp); +ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long length); +ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long length); + +DECLARE_ASN1_ITEM(ASN1_OBJECT) + +DECLARE_STACK_OF(ASN1_OBJECT) +DECLARE_ASN1_SET_OF(ASN1_OBJECT) + +ASN1_STRING *ASN1_STRING_new(void); +void ASN1_STRING_free(ASN1_STRING *a); +int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str); +ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *a); +ASN1_STRING *ASN1_STRING_type_new(int type ); +int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b); + /* Since this is used to store all sorts of things, via macros, for now, make + its data void * */ +int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); +void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len); +int ASN1_STRING_length(const ASN1_STRING *x); +void ASN1_STRING_length_set(ASN1_STRING *x, int n); +int ASN1_STRING_type(ASN1_STRING *x); +unsigned char * ASN1_STRING_data(ASN1_STRING *x); + +DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING) +int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp); +ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, + const unsigned char **pp, long length); +int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length ); +int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value); +int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n); +int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a, + unsigned char *flags, int flags_len); + +#ifndef OPENSSL_NO_BIO +int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs, + BIT_STRING_BITNAME *tbl, int indent); +#endif +int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl); +int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value, + BIT_STRING_BITNAME *tbl); + +int i2d_ASN1_BOOLEAN(int a, unsigned char **pp); +int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length); + +DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER) +int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp); +ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, + long length); +ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, + long length); +ASN1_INTEGER * ASN1_INTEGER_dup(const ASN1_INTEGER *x); +int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y); + +DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED) + +int ASN1_UTCTIME_check(ASN1_UTCTIME *a); +ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t); +ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, + int offset_day, long offset_sec); +int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str); +#ifndef LIBRESSL_INTERNAL +int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t); +#endif +int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *a); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, + time_t t); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, + time_t t, int offset_day, long offset_sec); +int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str); + +DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING) +ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a); +int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, + const ASN1_OCTET_STRING *b); +int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, + int len); + +DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_NULL) +DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING) + +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE) + +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING) +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT) +DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME) +DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME) +DECLARE_ASN1_FUNCTIONS(ASN1_TIME) + +DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF) + +ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t); +ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, int offset_day, + long offset_sec); +int ASN1_TIME_check(ASN1_TIME *t); +ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, + ASN1_GENERALIZEDTIME **out); +int ASN1_TIME_set_string(ASN1_TIME *s, const char *str); + +int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp, + i2d_of_void *i2d, int ex_tag, int ex_class, int is_set); +STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a, + const unsigned char **pp, long length, d2i_of_void *d2i, + void (*free_func)(OPENSSL_BLOCK), int ex_tag, int ex_class); + +#ifndef OPENSSL_NO_BIO +int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a); +int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size); +int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a); +int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size); +int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a); +int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size); +int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type); +#endif +int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a); + +int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num); +ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len, + const char *sn, const char *ln); + +int ASN1_INTEGER_set(ASN1_INTEGER *a, long v); +long ASN1_INTEGER_get(const ASN1_INTEGER *a); +ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai); +BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn); + +int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v); +long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a); +ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai); +BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn); + +/* General */ +/* given a string, return the correct type, max is the maximum length */ +int ASN1_PRINTABLE_type(const unsigned char *s, int max); + +int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass); +ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp, + long length, int Ptag, int Pclass); +unsigned long ASN1_tag2bit(int tag); +/* type is one or more of the B_ASN1_ values. */ +ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp, + long length, int type); + +/* PARSING */ +int asn1_Finish(ASN1_CTX *c); +int asn1_const_Finish(ASN1_const_CTX *c); + +/* SPECIALS */ +int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, + int *pclass, long omax); +int ASN1_check_infinite_end(unsigned char **p, long len); +int ASN1_const_check_infinite_end(const unsigned char **p, long len); +void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag, + int xclass); +int ASN1_put_eoc(unsigned char **pp); +int ASN1_object_size(int constructed, int length, int tag); + +void *ASN1_item_dup(const ASN1_ITEM *it, void *x); + +#ifndef LIBRESSL_INTERNAL + +/* Used to implement other functions */ +void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x); + +#define ASN1_dup_of(type,i2d,d2i,x) \ + ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(type, x))) + +#define ASN1_dup_of_const(type,i2d,d2i,x) \ + ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(const type, x))) + +/* ASN1 alloc/free macros for when a type is only used internally */ + +#define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type)) +#define M_ASN1_free_of(x, type) \ + ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type)) + +#endif + +void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x); + +#define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + +void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x); +int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x); + +#define ASN1_i2d_fp_of(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + +#define ASN1_i2d_fp_of_const(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + +int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x); +int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags); + +int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in); + +#ifndef OPENSSL_NO_BIO +void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x); + +#define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + +void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x); +int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x); + +#define ASN1_i2d_bio_of(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + +#define ASN1_i2d_bio_of_const(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + +int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x); +int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a); +int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a); +int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a); +int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v); +int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags); +int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num, + unsigned char *buf, int off); +int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent); +int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, int dump); +#endif +const char *ASN1_tag2str(int tag); + +/* Used to load and write netscape format cert */ + +DECLARE_ASN1_FUNCTIONS(NETSCAPE_X509) + +int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s); + +int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len); +int ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data, int max_len); +int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, unsigned char *data, + int len); +int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num, unsigned char *data, + int max_len); + +STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len, + d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK)); +unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d, + unsigned char **buf, int *len ); +void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i); +void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it); +ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, + ASN1_OCTET_STRING **oct); + +ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, + ASN1_OCTET_STRING **oct); + +void ASN1_STRING_set_default_mask(unsigned long mask); +int ASN1_STRING_set_default_mask_asc(const char *p); +unsigned long ASN1_STRING_get_default_mask(void); +int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask); +int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask, long minsize, long maxsize); + +ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, + const unsigned char *in, int inlen, int inform, int nid); +ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid); +int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long); +void ASN1_STRING_TABLE_cleanup(void); + +/* ASN1 template functions */ + +/* Old API compatible functions */ +ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it); +void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it); +ASN1_VALUE * ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, + long len, const ASN1_ITEM *it); +int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it); +int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it); + +void ASN1_add_oid_module(void); + +ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf); +ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf); + +/* ASN1 Print flags */ + +/* Indicate missing OPTIONAL fields */ +#define ASN1_PCTX_FLAGS_SHOW_ABSENT 0x001 +/* Mark start and end of SEQUENCE */ +#define ASN1_PCTX_FLAGS_SHOW_SEQUENCE 0x002 +/* Mark start and end of SEQUENCE/SET OF */ +#define ASN1_PCTX_FLAGS_SHOW_SSOF 0x004 +/* Show the ASN1 type of primitives */ +#define ASN1_PCTX_FLAGS_SHOW_TYPE 0x008 +/* Don't show ASN1 type of ANY */ +#define ASN1_PCTX_FLAGS_NO_ANY_TYPE 0x010 +/* Don't show ASN1 type of MSTRINGs */ +#define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE 0x020 +/* Don't show field names in SEQUENCE */ +#define ASN1_PCTX_FLAGS_NO_FIELD_NAME 0x040 +/* Show structure names of each SEQUENCE field */ +#define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME 0x080 +/* Don't show structure name even at top level */ +#define ASN1_PCTX_FLAGS_NO_STRUCT_NAME 0x100 + +int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, + const ASN1_ITEM *it, const ASN1_PCTX *pctx); +ASN1_PCTX *ASN1_PCTX_new(void); +void ASN1_PCTX_free(ASN1_PCTX *p); +unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags); + +BIO_METHOD *BIO_f_asn1(void); + +BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it); + +int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const ASN1_ITEM *it); +int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const char *hdr, const ASN1_ITEM *it); +int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, + int ctype_nid, int econt_nid, STACK_OF(X509_ALGOR) *mdalgs, + const ASN1_ITEM *it); +ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it); +int SMIME_crlf_copy(BIO *in, BIO *out, int flags); +int SMIME_text(BIO *in, BIO *out); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_ASN1_strings(void); + +/* Error codes for the ASN1 functions. */ + +/* Function codes. */ +#define ASN1_F_A2D_ASN1_OBJECT 100 +#define ASN1_F_A2I_ASN1_ENUMERATED 101 +#define ASN1_F_A2I_ASN1_INTEGER 102 +#define ASN1_F_A2I_ASN1_STRING 103 +#define ASN1_F_APPEND_EXP 176 +#define ASN1_F_ASN1_BIT_STRING_SET_BIT 183 +#define ASN1_F_ASN1_CB 177 +#define ASN1_F_ASN1_CHECK_TLEN 104 +#define ASN1_F_ASN1_COLLATE_PRIMITIVE 105 +#define ASN1_F_ASN1_COLLECT 106 +#define ASN1_F_ASN1_D2I_EX_PRIMITIVE 108 +#define ASN1_F_ASN1_D2I_FP 109 +#define ASN1_F_ASN1_D2I_READ_BIO 107 +#define ASN1_F_ASN1_DIGEST 184 +#define ASN1_F_ASN1_DO_ADB 110 +#define ASN1_F_ASN1_DUP 111 +#define ASN1_F_ASN1_ENUMERATED_SET 112 +#define ASN1_F_ASN1_ENUMERATED_TO_BN 113 +#define ASN1_F_ASN1_EX_C2I 204 +#define ASN1_F_ASN1_FIND_END 190 +#define ASN1_F_ASN1_GENERALIZEDTIME_ADJ 216 +#define ASN1_F_ASN1_GENERALIZEDTIME_SET 185 +#define ASN1_F_ASN1_GENERATE_V3 178 +#define ASN1_F_ASN1_GET_OBJECT 114 +#define ASN1_F_ASN1_HEADER_NEW 115 +#define ASN1_F_ASN1_I2D_BIO 116 +#define ASN1_F_ASN1_I2D_FP 117 +#define ASN1_F_ASN1_INTEGER_SET 118 +#define ASN1_F_ASN1_INTEGER_TO_BN 119 +#define ASN1_F_ASN1_ITEM_D2I_FP 206 +#define ASN1_F_ASN1_ITEM_DUP 191 +#define ASN1_F_ASN1_ITEM_EX_COMBINE_NEW 121 +#define ASN1_F_ASN1_ITEM_EX_D2I 120 +#define ASN1_F_ASN1_ITEM_I2D_BIO 192 +#define ASN1_F_ASN1_ITEM_I2D_FP 193 +#define ASN1_F_ASN1_ITEM_PACK 198 +#define ASN1_F_ASN1_ITEM_SIGN 195 +#define ASN1_F_ASN1_ITEM_SIGN_CTX 220 +#define ASN1_F_ASN1_ITEM_UNPACK 199 +#define ASN1_F_ASN1_ITEM_VERIFY 197 +#define ASN1_F_ASN1_MBSTRING_NCOPY 122 +#define ASN1_F_ASN1_OBJECT_NEW 123 +#define ASN1_F_ASN1_OUTPUT_DATA 214 +#define ASN1_F_ASN1_PACK_STRING 124 +#define ASN1_F_ASN1_PCTX_NEW 205 +#define ASN1_F_ASN1_PKCS5_PBE_SET 125 +#define ASN1_F_ASN1_SEQ_PACK 126 +#define ASN1_F_ASN1_SEQ_UNPACK 127 +#define ASN1_F_ASN1_SIGN 128 +#define ASN1_F_ASN1_STR2TYPE 179 +#define ASN1_F_ASN1_STRING_SET 186 +#define ASN1_F_ASN1_STRING_TABLE_ADD 129 +#define ASN1_F_ASN1_STRING_TYPE_NEW 130 +#define ASN1_F_ASN1_TEMPLATE_EX_D2I 132 +#define ASN1_F_ASN1_TEMPLATE_NEW 133 +#define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I 131 +#define ASN1_F_ASN1_TIME_ADJ 217 +#define ASN1_F_ASN1_TIME_SET 175 +#define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING 134 +#define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 135 +#define ASN1_F_ASN1_UNPACK_STRING 136 +#define ASN1_F_ASN1_UTCTIME_ADJ 218 +#define ASN1_F_ASN1_UTCTIME_SET 187 +#define ASN1_F_ASN1_VERIFY 137 +#define ASN1_F_B64_READ_ASN1 209 +#define ASN1_F_B64_WRITE_ASN1 210 +#define ASN1_F_BIO_NEW_NDEF 208 +#define ASN1_F_BITSTR_CB 180 +#define ASN1_F_BN_TO_ASN1_ENUMERATED 138 +#define ASN1_F_BN_TO_ASN1_INTEGER 139 +#define ASN1_F_C2I_ASN1_BIT_STRING 189 +#define ASN1_F_C2I_ASN1_INTEGER 194 +#define ASN1_F_C2I_ASN1_OBJECT 196 +#define ASN1_F_COLLECT_DATA 140 +#define ASN1_F_D2I_ASN1_BIT_STRING 141 +#define ASN1_F_D2I_ASN1_BOOLEAN 142 +#define ASN1_F_D2I_ASN1_BYTES 143 +#define ASN1_F_D2I_ASN1_GENERALIZEDTIME 144 +#define ASN1_F_D2I_ASN1_HEADER 145 +#define ASN1_F_D2I_ASN1_INTEGER 146 +#define ASN1_F_D2I_ASN1_OBJECT 147 +#define ASN1_F_D2I_ASN1_SET 148 +#define ASN1_F_D2I_ASN1_TYPE_BYTES 149 +#define ASN1_F_D2I_ASN1_UINTEGER 150 +#define ASN1_F_D2I_ASN1_UTCTIME 151 +#define ASN1_F_D2I_AUTOPRIVATEKEY 207 +#define ASN1_F_D2I_NETSCAPE_RSA 152 +#define ASN1_F_D2I_NETSCAPE_RSA_2 153 +#define ASN1_F_D2I_PRIVATEKEY 154 +#define ASN1_F_D2I_PUBLICKEY 155 +#define ASN1_F_D2I_RSA_NET 200 +#define ASN1_F_D2I_RSA_NET_2 201 +#define ASN1_F_D2I_X509 156 +#define ASN1_F_D2I_X509_CINF 157 +#define ASN1_F_D2I_X509_PKEY 159 +#define ASN1_F_I2D_ASN1_BIO_STREAM 211 +#define ASN1_F_I2D_ASN1_SET 188 +#define ASN1_F_I2D_ASN1_TIME 160 +#define ASN1_F_I2D_DSA_PUBKEY 161 +#define ASN1_F_I2D_EC_PUBKEY 181 +#define ASN1_F_I2D_PRIVATEKEY 163 +#define ASN1_F_I2D_PUBLICKEY 164 +#define ASN1_F_I2D_RSA_NET 162 +#define ASN1_F_I2D_RSA_PUBKEY 165 +#define ASN1_F_LONG_C2I 166 +#define ASN1_F_OID_MODULE_INIT 174 +#define ASN1_F_PARSE_TAGGING 182 +#define ASN1_F_PKCS5_PBE2_SET_IV 167 +#define ASN1_F_PKCS5_PBE_SET 202 +#define ASN1_F_PKCS5_PBE_SET0_ALGOR 215 +#define ASN1_F_PKCS5_PBKDF2_SET 219 +#define ASN1_F_SMIME_READ_ASN1 212 +#define ASN1_F_SMIME_TEXT 213 +#define ASN1_F_X509_CINF_NEW 168 +#define ASN1_F_X509_CRL_ADD0_REVOKED 169 +#define ASN1_F_X509_INFO_NEW 170 +#define ASN1_F_X509_NAME_ENCODE 203 +#define ASN1_F_X509_NAME_EX_D2I 158 +#define ASN1_F_X509_NAME_EX_NEW 171 +#define ASN1_F_X509_NEW 172 +#define ASN1_F_X509_PKEY_NEW 173 + +/* Reason codes. */ +#define ASN1_R_ADDING_OBJECT 171 +#define ASN1_R_ASN1_PARSE_ERROR 203 +#define ASN1_R_ASN1_SIG_PARSE_ERROR 204 +#define ASN1_R_AUX_ERROR 100 +#define ASN1_R_BAD_CLASS 101 +#define ASN1_R_BAD_OBJECT_HEADER 102 +#define ASN1_R_BAD_PASSWORD_READ 103 +#define ASN1_R_BAD_TAG 104 +#define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214 +#define ASN1_R_BN_LIB 105 +#define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106 +#define ASN1_R_BUFFER_TOO_SMALL 107 +#define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 108 +#define ASN1_R_CONTEXT_NOT_INITIALISED 217 +#define ASN1_R_DATA_IS_WRONG 109 +#define ASN1_R_DECODE_ERROR 110 +#define ASN1_R_DECODING_ERROR 111 +#define ASN1_R_DEPTH_EXCEEDED 174 +#define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 198 +#define ASN1_R_ENCODE_ERROR 112 +#define ASN1_R_ERROR_GETTING_TIME 173 +#define ASN1_R_ERROR_LOADING_SECTION 172 +#define ASN1_R_ERROR_PARSING_SET_ELEMENT 113 +#define ASN1_R_ERROR_SETTING_CIPHER_PARAMS 114 +#define ASN1_R_EXPECTING_AN_INTEGER 115 +#define ASN1_R_EXPECTING_AN_OBJECT 116 +#define ASN1_R_EXPECTING_A_BOOLEAN 117 +#define ASN1_R_EXPECTING_A_TIME 118 +#define ASN1_R_EXPLICIT_LENGTH_MISMATCH 119 +#define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 120 +#define ASN1_R_FIELD_MISSING 121 +#define ASN1_R_FIRST_NUM_TOO_LARGE 122 +#define ASN1_R_HEADER_TOO_LONG 123 +#define ASN1_R_ILLEGAL_BITSTRING_FORMAT 175 +#define ASN1_R_ILLEGAL_BOOLEAN 176 +#define ASN1_R_ILLEGAL_CHARACTERS 124 +#define ASN1_R_ILLEGAL_FORMAT 177 +#define ASN1_R_ILLEGAL_HEX 178 +#define ASN1_R_ILLEGAL_IMPLICIT_TAG 179 +#define ASN1_R_ILLEGAL_INTEGER 180 +#define ASN1_R_ILLEGAL_NESTED_TAGGING 181 +#define ASN1_R_ILLEGAL_NULL 125 +#define ASN1_R_ILLEGAL_NULL_VALUE 182 +#define ASN1_R_ILLEGAL_OBJECT 183 +#define ASN1_R_ILLEGAL_OPTIONAL_ANY 126 +#define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 170 +#define ASN1_R_ILLEGAL_TAGGED_ANY 127 +#define ASN1_R_ILLEGAL_TIME_VALUE 184 +#define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185 +#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128 +#define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 220 +#define ASN1_R_INVALID_BMPSTRING_LENGTH 129 +#define ASN1_R_INVALID_DIGIT 130 +#define ASN1_R_INVALID_MIME_TYPE 205 +#define ASN1_R_INVALID_MODIFIER 186 +#define ASN1_R_INVALID_NUMBER 187 +#define ASN1_R_INVALID_OBJECT_ENCODING 216 +#define ASN1_R_INVALID_SEPARATOR 131 +#define ASN1_R_INVALID_TIME_FORMAT 132 +#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133 +#define ASN1_R_INVALID_UTF8STRING 134 +#define ASN1_R_IV_TOO_LARGE 135 +#define ASN1_R_LENGTH_ERROR 136 +#define ASN1_R_LIST_ERROR 188 +#define ASN1_R_MIME_NO_CONTENT_TYPE 206 +#define ASN1_R_MIME_PARSE_ERROR 207 +#define ASN1_R_MIME_SIG_PARSE_ERROR 208 +#define ASN1_R_MISSING_EOC 137 +#define ASN1_R_MISSING_SECOND_NUMBER 138 +#define ASN1_R_MISSING_VALUE 189 +#define ASN1_R_MSTRING_NOT_UNIVERSAL 139 +#define ASN1_R_MSTRING_WRONG_TAG 140 +#define ASN1_R_NESTED_ASN1_STRING 197 +#define ASN1_R_NON_HEX_CHARACTERS 141 +#define ASN1_R_NOT_ASCII_FORMAT 190 +#define ASN1_R_NOT_ENOUGH_DATA 142 +#define ASN1_R_NO_CONTENT_TYPE 209 +#define ASN1_R_NO_DEFAULT_DIGEST 201 +#define ASN1_R_NO_MATCHING_CHOICE_TYPE 143 +#define ASN1_R_NO_MULTIPART_BODY_FAILURE 210 +#define ASN1_R_NO_MULTIPART_BOUNDARY 211 +#define ASN1_R_NO_SIG_CONTENT_TYPE 212 +#define ASN1_R_NULL_IS_WRONG_LENGTH 144 +#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 191 +#define ASN1_R_ODD_NUMBER_OF_CHARS 145 +#define ASN1_R_PRIVATE_KEY_HEADER_MISSING 146 +#define ASN1_R_SECOND_NUMBER_TOO_LARGE 147 +#define ASN1_R_SEQUENCE_LENGTH_MISMATCH 148 +#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 149 +#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 192 +#define ASN1_R_SHORT_LINE 150 +#define ASN1_R_SIG_INVALID_MIME_TYPE 213 +#define ASN1_R_STREAMING_NOT_SUPPORTED 202 +#define ASN1_R_STRING_TOO_LONG 151 +#define ASN1_R_STRING_TOO_SHORT 152 +#define ASN1_R_TAG_VALUE_TOO_HIGH 153 +#define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154 +#define ASN1_R_TIME_NOT_ASCII_FORMAT 193 +#define ASN1_R_TOO_LONG 155 +#define ASN1_R_TYPE_NOT_CONSTRUCTED 156 +#define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157 +#define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY 158 +#define ASN1_R_UNEXPECTED_EOC 159 +#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 215 +#define ASN1_R_UNKNOWN_FORMAT 160 +#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161 +#define ASN1_R_UNKNOWN_OBJECT_TYPE 162 +#define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE 163 +#define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM 199 +#define ASN1_R_UNKNOWN_TAG 194 +#define ASN1_R_UNKOWN_FORMAT 195 +#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 164 +#define ASN1_R_UNSUPPORTED_CIPHER 165 +#define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM 166 +#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 167 +#define ASN1_R_UNSUPPORTED_TYPE 196 +#define ASN1_R_WRONG_PUBLIC_KEY_TYPE 200 +#define ASN1_R_WRONG_TAG 168 +#define ASN1_R_WRONG_TYPE 169 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/asn1_mac.h b/crypto/libressl/include/openssl/asn1_mac.h new file mode 100644 index 0000000000..8dab289a65 --- /dev/null +++ b/crypto/libressl/include/openssl/asn1_mac.h @@ -0,0 +1,426 @@ +/* $OpenBSD: asn1_mac.h,v 1.13 2014/06/12 15:49:27 deraadt Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_ASN1_MAC_H +#define HEADER_ASN1_MAC_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ASN1_MAC_ERR_LIB +#define ASN1_MAC_ERR_LIB ERR_LIB_ASN1 +#endif + +#define ASN1_MAC_H_err(f,r,line) \ + ERR_PUT_error(ASN1_MAC_ERR_LIB,(f),(r),__FILE__,(line)) + +#define M_ASN1_D2I_vars(a,type,func) \ + ASN1_const_CTX c; \ + type ret=NULL; \ + \ + c.pp=(const unsigned char **)pp; \ + c.q= *(const unsigned char **)pp; \ + c.error=ERR_R_NESTED_ASN1_ERROR; \ + if ((a == NULL) || ((*a) == NULL)) \ + { if ((ret=(type)func()) == NULL) \ + { c.line=__LINE__; goto err; } } \ + else ret=(*a); + +#define M_ASN1_D2I_Init() \ + c.p= *(const unsigned char **)pp; \ + c.max=(length == 0)?0:(c.p+length); + +#define M_ASN1_D2I_Finish_2(a) \ + if (!asn1_const_Finish(&c)) \ + { c.line=__LINE__; goto err; } \ + *(const unsigned char **)pp=c.p; \ + if (a != NULL) (*a)=ret; \ + return(ret); + +#define M_ASN1_D2I_Finish(a,func,e) \ + M_ASN1_D2I_Finish_2(a); \ +err:\ + ASN1_MAC_H_err((e),c.error,c.line); \ + asn1_add_error(*(const unsigned char **)pp,(int)(c.q- *pp)); \ + if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \ + return(NULL) + +#define M_ASN1_D2I_start_sequence() \ + if (!asn1_GetSequence(&c,&length)) \ + { c.line=__LINE__; goto err; } +/* Begin reading ASN1 without a surrounding sequence */ +#define M_ASN1_D2I_begin() \ + c.slen = length; + +/* End reading ASN1 with no check on length */ +#define M_ASN1_D2I_Finish_nolen(a, func, e) \ + *pp=c.p; \ + if (a != NULL) (*a)=ret; \ + return(ret); \ +err:\ + ASN1_MAC_H_err((e),c.error,c.line); \ + asn1_add_error(*pp,(int)(c.q- *pp)); \ + if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \ + return(NULL) + +#define M_ASN1_D2I_end_sequence() \ + (((c.inf&1) == 0)?(c.slen <= 0): \ + (c.eos=ASN1_const_check_infinite_end(&c.p,c.slen))) + +/* Don't use this with d2i_ASN1_BOOLEAN() */ +#define M_ASN1_D2I_get(b, func) \ + c.q=c.p; \ + if (func(&(b),&c.p,c.slen) == NULL) \ + {c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +/* Don't use this with d2i_ASN1_BOOLEAN() */ +#define M_ASN1_D2I_get_x(type,b,func) \ + c.q=c.p; \ + if (((D2I_OF(type))func)(&(b),&c.p,c.slen) == NULL) \ + {c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +/* use this instead () */ +#define M_ASN1_D2I_get_int(b,func) \ + c.q=c.p; \ + if (func(&(b),&c.p,c.slen) < 0) \ + {c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +#define M_ASN1_D2I_get_opt(b,func,type) \ + if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \ + == (V_ASN1_UNIVERSAL|(type)))) \ + { \ + M_ASN1_D2I_get(b,func); \ + } + +#define M_ASN1_D2I_get_int_opt(b,func,type) \ + if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \ + == (V_ASN1_UNIVERSAL|(type)))) \ + { \ + M_ASN1_D2I_get_int(b,func); \ + } + +#define M_ASN1_D2I_get_imp(b,func, type) \ + M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \ + c.q=c.p; \ + if (func(&(b),&c.p,c.slen) == NULL) \ + {c.line=__LINE__; M_ASN1_next_prev = _tmp; goto err; } \ + c.slen-=(c.p-c.q);\ + M_ASN1_next_prev=_tmp; + +#define M_ASN1_D2I_get_IMP_opt(b,func,tag,type) \ + if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) == \ + (V_ASN1_CONTEXT_SPECIFIC|(tag)))) \ + { \ + unsigned char _tmp = M_ASN1_next; \ + M_ASN1_D2I_get_imp(b,func, type);\ + } + +#define M_ASN1_D2I_get_set_type(type,r,func,free_func) \ + M_ASN1_D2I_get_imp_set_type(type,r,func,free_func, \ + V_ASN1_SET,V_ASN1_UNIVERSAL); + +#define M_ASN1_D2I_get_set_opt_type(type,r,func,free_func) \ + if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ + V_ASN1_CONSTRUCTED|V_ASN1_SET)))\ + { M_ASN1_D2I_get_set_type(type,r,func,free_func); } + +#define M_ASN1_I2D_len_SET_opt(a,f) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + M_ASN1_I2D_len_SET(a,f); + +#define M_ASN1_I2D_put_SET_opt(a,f) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + M_ASN1_I2D_put_SET(a,f); + +#define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + M_ASN1_I2D_put_SEQUENCE(a,f); + +#define M_ASN1_I2D_put_SEQUENCE_opt_type(type,a,f) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + M_ASN1_I2D_put_SEQUENCE_type(type,a,f); + +#define M_ASN1_D2I_get_IMP_set_opt_type(type,b,func,free_func,tag) \ + if ((c.slen != 0) && \ + (M_ASN1_next == \ + (V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\ + { \ + M_ASN1_D2I_get_imp_set_type(type,b,func,free_func,\ + tag,V_ASN1_CONTEXT_SPECIFIC); \ + } + +#define M_ASN1_D2I_get_seq_type(type,r,func,free_func) \ + M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\ + V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL) + +#define M_ASN1_D2I_get_seq_opt_type(type,r,func,free_func) \ + if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ + V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\ + { M_ASN1_D2I_get_seq_type(type,r,func,free_func); } + +#define M_ASN1_D2I_get_IMP_set_type(type,r,func,free_func,x) \ + M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\ + x,V_ASN1_CONTEXT_SPECIFIC); + +#define M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,a,b) \ + c.q=c.p; \ + if (d2i_ASN1_SET_OF_##type(&(r),&c.p,c.slen,func,\ + free_func,a,b) == NULL) \ + { c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +#define M_ASN1_D2I_get_set_strings(r,func,a,b) \ + c.q=c.p; \ + if (d2i_ASN1_STRING_SET(&(r),&c.p,c.slen,a,b) == NULL) \ + { c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +#define M_ASN1_D2I_get_EXP_opt(r,func,tag) \ + if ((c.slen != 0L) && (M_ASN1_next == \ + (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \ + { \ + int Tinf,Ttag,Tclass; \ + long Tlen; \ + \ + c.q=c.p; \ + Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \ + if (Tinf & 0x80) \ + { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \ + c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) \ + Tlen = c.slen - (c.p - c.q) - 2; \ + if (func(&(r),&c.p,Tlen) == NULL) \ + { c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ + Tlen = c.slen - (c.p - c.q); \ + if(!ASN1_const_check_infinite_end(&c.p, Tlen)) \ + { c.error=ERR_R_MISSING_ASN1_EOS; \ + c.line=__LINE__; goto err; } \ + }\ + c.slen-=(c.p-c.q); \ + } + +#define M_ASN1_D2I_get_EXP_set_opt_type(type,r,func,free_func,tag,b) \ + if ((c.slen != 0) && (M_ASN1_next == \ + (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \ + { \ + int Tinf,Ttag,Tclass; \ + long Tlen; \ + \ + c.q=c.p; \ + Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \ + if (Tinf & 0x80) \ + { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \ + c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) \ + Tlen = c.slen - (c.p - c.q) - 2; \ + if (d2i_ASN1_SET_OF_##type(&(r),&c.p,Tlen,func, \ + free_func,b,V_ASN1_UNIVERSAL) == NULL) \ + { c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ + Tlen = c.slen - (c.p - c.q); \ + if(!ASN1_check_infinite_end(&c.p, Tlen)) \ + { c.error=ERR_R_MISSING_ASN1_EOS; \ + c.line=__LINE__; goto err; } \ + }\ + c.slen-=(c.p-c.q); \ + } + +/* BIG UGLY WARNING! This is so damn ugly I wanna puke. Unfortunately, + some macros that use ASN1_const_CTX still insist on writing in the input + stream. ARGH! ARGH! ARGH! Let's get rid of this macro package. + Please? -- Richard Levitte */ +#define M_ASN1_next (*((unsigned char *)(c.p))) +#define M_ASN1_next_prev (*((unsigned char *)(c.q))) + +/*************************************************/ + +#define M_ASN1_I2D_vars(a) int r=0,ret=0; \ + unsigned char *p; \ + if (a == NULL) return(0) + +/* Length Macros */ +#define M_ASN1_I2D_len(a,f) ret+=f(a,NULL) +#define M_ASN1_I2D_len_IMP_opt(a,f) if (a != NULL) M_ASN1_I2D_len(a,f) + +#define M_ASN1_I2D_len_SET_type(type,a,f) \ + ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SET, \ + V_ASN1_UNIVERSAL,IS_SET); + +#define M_ASN1_I2D_len_SEQUENCE_type(type,a,f) \ + ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SEQUENCE, \ + V_ASN1_UNIVERSAL,IS_SEQUENCE) + +#define M_ASN1_I2D_len_SEQUENCE_opt(a,f) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + M_ASN1_I2D_len_SEQUENCE(a,f); + +#define M_ASN1_I2D_len_SEQUENCE_opt_type(type,a,f) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + M_ASN1_I2D_len_SEQUENCE_type(type,a,f); + +#define M_ASN1_I2D_len_IMP_SET_type(type,a,f,x) \ + ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \ + V_ASN1_CONTEXT_SPECIFIC,IS_SET); + +#define M_ASN1_I2D_len_IMP_SET_opt_type(type,a,f,x) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \ + V_ASN1_CONTEXT_SPECIFIC,IS_SET); + +#define M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(type,a,f,x) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \ + V_ASN1_CONTEXT_SPECIFIC, \ + IS_SEQUENCE); + +#define M_ASN1_I2D_len_EXP_opt(a,f,mtag,v) \ + if (a != NULL)\ + { \ + v=f(a,NULL); \ + ret+=ASN1_object_size(1,v,mtag); \ + } + +#define M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \ + if ((a != NULL) && (sk_##type##_num(a) != 0))\ + { \ + v=i2d_ASN1_SET_OF_##type(a,NULL,f,tag, \ + V_ASN1_UNIVERSAL, \ + IS_SEQUENCE); \ + ret+=ASN1_object_size(1,v,mtag); \ + } + +/* Put Macros */ +#define M_ASN1_I2D_put(a,f) f(a,&p) + +#define M_ASN1_I2D_put_IMP_opt(a,f,t) \ + if (a != NULL) \ + { \ + unsigned char *q=p; \ + f(a,&p); \ + *q=(V_ASN1_CONTEXT_SPECIFIC|t|(*q&V_ASN1_CONSTRUCTED));\ + } + +#define M_ASN1_I2D_put_SET_type(type,a,f) \ + i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET) +#define M_ASN1_I2D_put_IMP_SET_type(type,a,f,x) \ + i2d_ASN1_SET_OF_##type(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET) + +#define M_ASN1_I2D_put_SEQUENCE_type(type,a,f) \ + i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \ + IS_SEQUENCE) + +#define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + M_ASN1_I2D_put_SEQUENCE(a,f); + +#define M_ASN1_I2D_put_IMP_SET_opt_type(type,a,f,x) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + { i2d_ASN1_SET_OF_##type(a,&p,f,x, \ + V_ASN1_CONTEXT_SPECIFIC, \ + IS_SET); } + +#define M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(type,a,f,x) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + { i2d_ASN1_SET_OF_##type(a,&p,f,x, \ + V_ASN1_CONTEXT_SPECIFIC, \ + IS_SEQUENCE); } + +#define M_ASN1_I2D_put_EXP_opt(a,f,tag,v) \ + if (a != NULL) \ + { \ + ASN1_put_object(&p,1,v,tag,V_ASN1_CONTEXT_SPECIFIC); \ + f(a,&p); \ + } + +#define M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + { \ + ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \ + i2d_ASN1_SET_OF_##type(a,&p,f,tag,V_ASN1_UNIVERSAL, \ + IS_SEQUENCE); \ + } + +#define M_ASN1_I2D_seq_total() \ + r=ASN1_object_size(1,ret,V_ASN1_SEQUENCE); \ + if (pp == NULL) return(r); \ + p= *pp; \ + ASN1_put_object(&p,1,ret,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL) + +#define M_ASN1_I2D_INF_seq_start(tag,ctx) \ + *(p++)=(V_ASN1_CONSTRUCTED|(tag)|(ctx)); \ + *(p++)=0x80 + +#define M_ASN1_I2D_INF_seq_end() *(p++)=0x00; *(p++)=0x00 + +#define M_ASN1_I2D_finish() *pp=p; \ + return(r); + +int asn1_GetSequence(ASN1_const_CTX *c, long *length); +void asn1_add_error(const unsigned char *address, int offset); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/libressl/include/openssl/asn1t.h b/crypto/libressl/include/openssl/asn1t.h new file mode 100644 index 0000000000..fe757be941 --- /dev/null +++ b/crypto/libressl/include/openssl/asn1t.h @@ -0,0 +1,880 @@ +/* $OpenBSD: asn1t.h,v 1.12 2015/02/14 19:41:39 miod Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_ASN1T_H +#define HEADER_ASN1T_H + +#include + +#include + +#include + +/* ASN1 template defines, structures and functions */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef LIBRESSL_INTERNAL + +/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ +#define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr)) + + +/* Macros for start and end of ASN1_ITEM definition */ + +#define ASN1_ITEM_start(itname) \ + const ASN1_ITEM itname##_it = { + +#define ASN1_ITEM_end(itname) \ + }; + + + +/* Macros to aid ASN1 template writing */ + +#define ASN1_ITEM_TEMPLATE(tname) \ + static const ASN1_TEMPLATE tname##_item_tt + +#define ASN1_ITEM_TEMPLATE_END(tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_PRIMITIVE,\ + -1,\ + &tname##_item_tt,\ + 0,\ + NULL,\ + 0,\ + #tname \ + ASN1_ITEM_end(tname) + + +/* This is a ASN1 type which just embeds a template */ + +/* This pair helps declare a SEQUENCE. We can do: + * + * ASN1_SEQUENCE(stname) = { + * ... SEQUENCE components ... + * } ASN1_SEQUENCE_END(stname) + * + * This will produce an ASN1_ITEM called stname_it + * for a structure called stname. + * + * If you want the same structure but a different + * name then use: + * + * ASN1_SEQUENCE(itname) = { + * ... SEQUENCE components ... + * } ASN1_SEQUENCE_END_name(stname, itname) + * + * This will create an item called itname_it using + * a structure called stname. + */ + +#define ASN1_SEQUENCE(tname) \ + static const ASN1_TEMPLATE tname##_seq_tt[] + +#define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname) + +#define ASN1_SEQUENCE_END_name(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +#define ASN1_NDEF_SEQUENCE(tname) \ + ASN1_SEQUENCE(tname) + +#define ASN1_NDEF_SEQUENCE_cb(tname, cb) \ + ASN1_SEQUENCE_cb(tname, cb) + +#define ASN1_SEQUENCE_cb(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ + ASN1_SEQUENCE(tname) + +#define ASN1_BROKEN_SEQUENCE(tname) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \ + ASN1_SEQUENCE(tname) + +#define ASN1_SEQUENCE_ref(tname, cb, lck) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \ + ASN1_SEQUENCE(tname) + +#define ASN1_SEQUENCE_enc(tname, enc, cb) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \ + ASN1_SEQUENCE(tname) + +#define ASN1_NDEF_SEQUENCE_END(tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(tname),\ + #tname \ + ASN1_ITEM_end(tname) + +#define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname) + +#define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) + +#define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) + +#define ASN1_SEQUENCE_END_ref(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +#define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + + +/* This pair helps declare a CHOICE type. We can do: + * + * ASN1_CHOICE(chname) = { + * ... CHOICE options ... + * ASN1_CHOICE_END(chname) + * + * This will produce an ASN1_ITEM called chname_it + * for a structure called chname. The structure + * definition must look like this: + * typedef struct { + * int type; + * union { + * ASN1_SOMETHING *opt1; + * ASN1_SOMEOTHER *opt2; + * } value; + * } chname; + * + * the name of the selector must be 'type'. + * to use an alternative selector name use the + * ASN1_CHOICE_END_selector() version. + */ + +#define ASN1_CHOICE(tname) \ + static const ASN1_TEMPLATE tname##_ch_tt[] + +#define ASN1_CHOICE_cb(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ + ASN1_CHOICE(tname) + +#define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname) + +#define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type) + +#define ASN1_CHOICE_END_selector(stname, tname, selname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +#define ASN1_CHOICE_END_cb(stname, tname, selname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +/* This helps with the template wrapper form of ASN1_ITEM */ + +#define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \ + (flags), (tag), 0,\ + #name, ASN1_ITEM_ref(type) } + +/* These help with SEQUENCE or CHOICE components */ + +/* used to declare other types */ + +#define ASN1_EX_TYPE(flags, tag, stname, field, type) { \ + (flags), (tag), offsetof(stname, field),\ + #field, ASN1_ITEM_ref(type) } + +/* used when the structure is combined with the parent */ + +#define ASN1_EX_COMBINE(flags, tag, type) { \ + (flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) } + +/* implicit and explicit helper macros */ + +#define ASN1_IMP_EX(stname, field, type, tag, ex) \ + ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type) + +#define ASN1_EXP_EX(stname, field, type, tag, ex) \ + ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type) + +/* Any defined by macros: the field used is in the table itself */ + +#define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } +#define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } +/* Plain simple type */ +#define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type) + +/* OPTIONAL simple type */ +#define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* IMPLICIT tagged simple type */ +#define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0) + +/* IMPLICIT tagged OPTIONAL simple type */ +#define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) + +/* Same as above but EXPLICIT */ + +#define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0) +#define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) + +/* SEQUENCE OF type */ +#define ASN1_SEQUENCE_OF(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type) + +/* OPTIONAL SEQUENCE OF */ +#define ASN1_SEQUENCE_OF_OPT(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* Same as above but for SET OF */ + +#define ASN1_SET_OF(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type) + +#define ASN1_SET_OF_OPT(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */ + +#define ASN1_IMP_SET_OF(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) + +#define ASN1_EXP_SET_OF(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) + +#define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) + +#define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) + +#define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) + +#define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) + +#define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) + +#define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) + +/* EXPLICIT using indefinite length constructed form */ +#define ASN1_NDEF_EXP(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF) + +/* EXPLICIT OPTIONAL using indefinite length constructed form */ +#define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF) + +/* Macros for the ASN1_ADB structure */ + +#define ASN1_ADB(name) \ + static const ASN1_ADB_TABLE name##_adbtbl[] + + +#define ASN1_ADB_END(name, flags, field, app_table, def, none) \ + ;\ + static const ASN1_ADB name##_adb = {\ + flags,\ + offsetof(name, field),\ + app_table,\ + name##_adbtbl,\ + sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ + def,\ + none\ + } + + +#define ADB_ENTRY(val, template) {val, template} + +#define ASN1_ADB_TEMPLATE(name) \ + static const ASN1_TEMPLATE name##_tt + +#endif /* !LIBRESSL_INTERNAL */ + +/* This is the ASN1 template structure that defines + * a wrapper round the actual type. It determines the + * actual position of the field in the value structure, + * various flags such as OPTIONAL and the field name. + */ + +struct ASN1_TEMPLATE_st { +unsigned long flags; /* Various flags */ +long tag; /* tag, not used if no tagging */ +unsigned long offset; /* Offset of this field in structure */ +#ifndef NO_ASN1_FIELD_NAMES +const char *field_name; /* Field name */ +#endif +ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */ +}; + +/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */ + +#define ASN1_TEMPLATE_item(t) (t->item_ptr) +#define ASN1_TEMPLATE_adb(t) (t->item_ptr) + +typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE; +typedef struct ASN1_ADB_st ASN1_ADB; + +struct ASN1_ADB_st { + unsigned long flags; /* Various flags */ + unsigned long offset; /* Offset of selector field */ + STACK_OF(ASN1_ADB_TABLE) **app_items; /* Application defined items */ + const ASN1_ADB_TABLE *tbl; /* Table of possible types */ + long tblcount; /* Number of entries in tbl */ + const ASN1_TEMPLATE *default_tt; /* Type to use if no match */ + const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */ +}; + +struct ASN1_ADB_TABLE_st { + long value; /* NID for an object or value for an int */ + const ASN1_TEMPLATE tt; /* item for this value */ +}; + +/* template flags */ + +/* Field is optional */ +#define ASN1_TFLG_OPTIONAL (0x1) + +/* Field is a SET OF */ +#define ASN1_TFLG_SET_OF (0x1 << 1) + +/* Field is a SEQUENCE OF */ +#define ASN1_TFLG_SEQUENCE_OF (0x2 << 1) + +/* Special case: this refers to a SET OF that + * will be sorted into DER order when encoded *and* + * the corresponding STACK will be modified to match + * the new order. + */ +#define ASN1_TFLG_SET_ORDER (0x3 << 1) + +/* Mask for SET OF or SEQUENCE OF */ +#define ASN1_TFLG_SK_MASK (0x3 << 1) + +/* These flags mean the tag should be taken from the + * tag field. If EXPLICIT then the underlying type + * is used for the inner tag. + */ + +/* IMPLICIT tagging */ +#define ASN1_TFLG_IMPTAG (0x1 << 3) + + +/* EXPLICIT tagging, inner tag from underlying type */ +#define ASN1_TFLG_EXPTAG (0x2 << 3) + +#define ASN1_TFLG_TAG_MASK (0x3 << 3) + +/* context specific IMPLICIT */ +#define ASN1_TFLG_IMPLICIT ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT + +/* context specific EXPLICIT */ +#define ASN1_TFLG_EXPLICIT ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT + +/* If tagging is in force these determine the + * type of tag to use. Otherwise the tag is + * determined by the underlying type. These + * values reflect the actual octet format. + */ + +/* Universal tag */ +#define ASN1_TFLG_UNIVERSAL (0x0<<6) +/* Application tag */ +#define ASN1_TFLG_APPLICATION (0x1<<6) +/* Context specific tag */ +#define ASN1_TFLG_CONTEXT (0x2<<6) +/* Private tag */ +#define ASN1_TFLG_PRIVATE (0x3<<6) + +#define ASN1_TFLG_TAG_CLASS (0x3<<6) + +/* These are for ANY DEFINED BY type. In this case + * the 'item' field points to an ASN1_ADB structure + * which contains a table of values to decode the + * relevant type + */ + +#define ASN1_TFLG_ADB_MASK (0x3<<8) + +#define ASN1_TFLG_ADB_OID (0x1<<8) + +#define ASN1_TFLG_ADB_INT (0x1<<9) + +/* This flag means a parent structure is passed + * instead of the field: this is useful is a + * SEQUENCE is being combined with a CHOICE for + * example. Since this means the structure and + * item name will differ we need to use the + * ASN1_CHOICE_END_name() macro for example. + */ + +#define ASN1_TFLG_COMBINE (0x1<<10) + +/* This flag when present in a SEQUENCE OF, SET OF + * or EXPLICIT causes indefinite length constructed + * encoding to be used if required. + */ + +#define ASN1_TFLG_NDEF (0x1<<11) + +/* This is the actual ASN1 item itself */ + +struct ASN1_ITEM_st { +char itype; /* The item type, primitive, SEQUENCE, CHOICE or extern */ +long utype; /* underlying type */ +const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains the contents */ +long tcount; /* Number of templates if SEQUENCE or CHOICE */ +const void *funcs; /* functions that handle this type */ +long size; /* Structure size (usually)*/ +#ifndef NO_ASN1_FIELD_NAMES +const char *sname; /* Structure name */ +#endif +}; + +/* These are values for the itype field and + * determine how the type is interpreted. + * + * For PRIMITIVE types the underlying type + * determines the behaviour if items is NULL. + * + * Otherwise templates must contain a single + * template and the type is treated in the + * same way as the type specified in the template. + * + * For SEQUENCE types the templates field points + * to the members, the size field is the + * structure size. + * + * For CHOICE types the templates field points + * to each possible member (typically a union) + * and the 'size' field is the offset of the + * selector. + * + * The 'funcs' field is used for application + * specific functions. + * + * The EXTERN type uses a new style d2i/i2d. + * The new style should be used where possible + * because it avoids things like the d2i IMPLICIT + * hack. + * + * MSTRING is a multiple string type, it is used + * for a CHOICE of character strings where the + * actual strings all occupy an ASN1_STRING + * structure. In this case the 'utype' field + * has a special meaning, it is used as a mask + * of acceptable types using the B_ASN1 constants. + * + * NDEF_SEQUENCE is the same as SEQUENCE except + * that it will use indefinite length constructed + * encoding if requested. + * + */ + +#define ASN1_ITYPE_PRIMITIVE 0x0 + +#define ASN1_ITYPE_SEQUENCE 0x1 + +#define ASN1_ITYPE_CHOICE 0x2 + +#define ASN1_ITYPE_EXTERN 0x4 + +#define ASN1_ITYPE_MSTRING 0x5 + +#define ASN1_ITYPE_NDEF_SEQUENCE 0x6 + +/* Cache for ASN1 tag and length, so we + * don't keep re-reading it for things + * like CHOICE + */ + +struct ASN1_TLC_st{ + char valid; /* Values below are valid */ + int ret; /* return value */ + long plen; /* length */ + int ptag; /* class value */ + int pclass; /* class value */ + int hdrlen; /* header length */ +}; + +/* Typedefs for ASN1 function pointers */ + +typedef ASN1_VALUE * ASN1_new_func(void); +typedef void ASN1_free_func(ASN1_VALUE *a); +typedef ASN1_VALUE * ASN1_d2i_func(ASN1_VALUE **a, const unsigned char ** in, long length); +typedef int ASN1_i2d_func(ASN1_VALUE * a, unsigned char **in); + +typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx); + +typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); +typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it); +typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); + +typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval, + int indent, const char *fname, + const ASN1_PCTX *pctx); + +typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it); +typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); +typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx); + +typedef struct ASN1_EXTERN_FUNCS_st { + void *app_data; + ASN1_ex_new_func *asn1_ex_new; + ASN1_ex_free_func *asn1_ex_free; + ASN1_ex_free_func *asn1_ex_clear; + ASN1_ex_d2i *asn1_ex_d2i; + ASN1_ex_i2d *asn1_ex_i2d; + ASN1_ex_print_func *asn1_ex_print; +} ASN1_EXTERN_FUNCS; + +typedef struct ASN1_PRIMITIVE_FUNCS_st { + void *app_data; + unsigned long flags; + ASN1_ex_new_func *prim_new; + ASN1_ex_free_func *prim_free; + ASN1_ex_free_func *prim_clear; + ASN1_primitive_c2i *prim_c2i; + ASN1_primitive_i2c *prim_i2c; + ASN1_primitive_print *prim_print; +} ASN1_PRIMITIVE_FUNCS; + +/* This is the ASN1_AUX structure: it handles various + * miscellaneous requirements. For example the use of + * reference counts and an informational callback. + * + * The "informational callback" is called at various + * points during the ASN1 encoding and decoding. It can + * be used to provide minor customisation of the structures + * used. This is most useful where the supplied routines + * *almost* do the right thing but need some extra help + * at a few points. If the callback returns zero then + * it is assumed a fatal error has occurred and the + * main operation should be abandoned. + * + * If major changes in the default behaviour are required + * then an external type is more appropriate. + */ + +typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it, + void *exarg); + +typedef struct ASN1_AUX_st { + void *app_data; + int flags; + int ref_offset; /* Offset of reference value */ + int ref_lock; /* Lock type to use */ + ASN1_aux_cb *asn1_cb; + int enc_offset; /* Offset of ASN1_ENCODING structure */ +} ASN1_AUX; + +/* For print related callbacks exarg points to this structure */ +typedef struct ASN1_PRINT_ARG_st { + BIO *out; + int indent; + const ASN1_PCTX *pctx; +} ASN1_PRINT_ARG; + +/* For streaming related callbacks exarg points to this structure */ +typedef struct ASN1_STREAM_ARG_st { + /* BIO to stream through */ + BIO *out; + /* BIO with filters appended */ + BIO *ndef_bio; + /* Streaming I/O boundary */ + unsigned char **boundary; +} ASN1_STREAM_ARG; + +/* Flags in ASN1_AUX */ + +/* Use a reference count */ +#define ASN1_AFLG_REFCOUNT 1 +/* Save the encoding of structure (useful for signatures) */ +#define ASN1_AFLG_ENCODING 2 +/* The Sequence length is invalid */ +#define ASN1_AFLG_BROKEN 4 + +/* operation values for asn1_cb */ + +#define ASN1_OP_NEW_PRE 0 +#define ASN1_OP_NEW_POST 1 +#define ASN1_OP_FREE_PRE 2 +#define ASN1_OP_FREE_POST 3 +#define ASN1_OP_D2I_PRE 4 +#define ASN1_OP_D2I_POST 5 +#define ASN1_OP_I2D_PRE 6 +#define ASN1_OP_I2D_POST 7 +#define ASN1_OP_PRINT_PRE 8 +#define ASN1_OP_PRINT_POST 9 +#define ASN1_OP_STREAM_PRE 10 +#define ASN1_OP_STREAM_POST 11 +#define ASN1_OP_DETACHED_PRE 12 +#define ASN1_OP_DETACHED_POST 13 + +#ifndef LIBRESSL_INTERNAL + +/* Macro to implement a primitive type */ +#define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0) +#define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \ + ASN1_ITEM_start(itname) \ + ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \ + ASN1_ITEM_end(itname) + +/* Macro to implement a multi string type */ +#define IMPLEMENT_ASN1_MSTRING(itname, mask) \ + ASN1_ITEM_start(itname) \ + ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \ + ASN1_ITEM_end(itname) +#define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \ + ASN1_ITEM_start(sname) \ + ASN1_ITYPE_EXTERN, \ + tag, \ + NULL, \ + 0, \ + &fptrs, \ + 0, \ + #sname \ + ASN1_ITEM_end(sname) + +/* Macro to implement standard functions in terms of ASN1_ITEM structures */ + +#define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname) + +#define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname) + +#define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \ + IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname) + +#define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname) + +#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname) + +#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \ + pre stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + pre void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + +#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \ + stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + +#define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) + +#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ + stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ + } \ + int i2d_##fname(stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ + } + +#define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \ + int i2d_##stname##_NDEF(stname *a, unsigned char **out) \ + { \ + return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\ + } + +/* This includes evil casts to remove const: they will go away when full + * ASN1 constification is done. + */ +#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ + stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ + } \ + int i2d_##fname(const stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ + } + +#define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \ + stname * stname##_dup(stname *x) \ + { \ + return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \ + } + +#define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \ + IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname) + +#define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \ + int fname##_print_ctx(BIO *out, stname *x, int indent, \ + const ASN1_PCTX *pctx) \ + { \ + return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \ + ASN1_ITEM_rptr(itname), pctx); \ + } + +#define IMPLEMENT_ASN1_FUNCTIONS_const(name) \ + IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name) + +#define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) + +#endif /* !LIBRESSL_INTERNAL */ + +/* external definitions for primitive types */ + +DECLARE_ASN1_ITEM(ASN1_BOOLEAN) +DECLARE_ASN1_ITEM(ASN1_TBOOLEAN) +DECLARE_ASN1_ITEM(ASN1_FBOOLEAN) +DECLARE_ASN1_ITEM(ASN1_SEQUENCE) +DECLARE_ASN1_ITEM(CBIGNUM) +DECLARE_ASN1_ITEM(BIGNUM) +DECLARE_ASN1_ITEM(LONG) +DECLARE_ASN1_ITEM(ZLONG) + +DECLARE_STACK_OF(ASN1_VALUE) + +/* Functions used internally by the ASN1 code */ + +int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it); +void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it); +int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); +int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it); + +void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); +int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt); +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx); + +int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); +int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt); +void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it); + +int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); + +int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it); +int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it); + +ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); + +const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr); + +int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it); + +void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it); +void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it); +int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it); +int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, const ASN1_ITEM *it); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/bio.h b/crypto/libressl/include/openssl/bio.h new file mode 100644 index 0000000000..d530b279c2 --- /dev/null +++ b/crypto/libressl/include/openssl/bio.h @@ -0,0 +1,774 @@ +/* $OpenBSD: bio.h,v 1.28 2015/02/09 10:55:33 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BIO_H +#define HEADER_BIO_H +#if !defined(HAVE_ATTRIBUTE__BOUNDED__) && !defined(__OpenBSD__) +#define __bounded__(x, y, z) +#endif +#include + +# include +#include + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +/* These are the 'types' of BIOs */ +#define BIO_TYPE_NONE 0 +#define BIO_TYPE_MEM (1|0x0400) +#define BIO_TYPE_FILE (2|0x0400) + +#define BIO_TYPE_FD (4|0x0400|0x0100) +#define BIO_TYPE_SOCKET (5|0x0400|0x0100) +#define BIO_TYPE_NULL (6|0x0400) +#define BIO_TYPE_SSL (7|0x0200) +#define BIO_TYPE_MD (8|0x0200) /* passive filter */ +#define BIO_TYPE_BUFFER (9|0x0200) /* filter */ +#define BIO_TYPE_CIPHER (10|0x0200) /* filter */ +#define BIO_TYPE_BASE64 (11|0x0200) /* filter */ +#define BIO_TYPE_CONNECT (12|0x0400|0x0100) /* socket - connect */ +#define BIO_TYPE_ACCEPT (13|0x0400|0x0100) /* socket for accept */ +#define BIO_TYPE_PROXY_CLIENT (14|0x0200) /* client proxy BIO */ +#define BIO_TYPE_PROXY_SERVER (15|0x0200) /* server proxy BIO */ +#define BIO_TYPE_NBIO_TEST (16|0x0200) /* server proxy BIO */ +#define BIO_TYPE_NULL_FILTER (17|0x0200) +#define BIO_TYPE_BER (18|0x0200) /* BER -> bin filter */ +#define BIO_TYPE_BIO (19|0x0400) /* (half a) BIO pair */ +#define BIO_TYPE_LINEBUFFER (20|0x0200) /* filter */ +#define BIO_TYPE_DGRAM (21|0x0400|0x0100) +#define BIO_TYPE_ASN1 (22|0x0200) /* filter */ +#define BIO_TYPE_COMP (23|0x0200) /* filter */ + +#define BIO_TYPE_DESCRIPTOR 0x0100 /* socket, fd, connect or accept */ +#define BIO_TYPE_FILTER 0x0200 +#define BIO_TYPE_SOURCE_SINK 0x0400 + +/* BIO_FILENAME_READ|BIO_CLOSE to open or close on free. + * BIO_set_fp(in,stdin,BIO_NOCLOSE); */ +#define BIO_NOCLOSE 0x00 +#define BIO_CLOSE 0x01 + +/* These are used in the following macros and are passed to + * BIO_ctrl() */ +#define BIO_CTRL_RESET 1 /* opt - rewind/zero etc */ +#define BIO_CTRL_EOF 2 /* opt - are we at the eof */ +#define BIO_CTRL_INFO 3 /* opt - extra tit-bits */ +#define BIO_CTRL_SET 4 /* man - set the 'IO' type */ +#define BIO_CTRL_GET 5 /* man - get the 'IO' type */ +#define BIO_CTRL_PUSH 6 /* opt - internal, used to signify change */ +#define BIO_CTRL_POP 7 /* opt - internal, used to signify change */ +#define BIO_CTRL_GET_CLOSE 8 /* man - set the 'close' on free */ +#define BIO_CTRL_SET_CLOSE 9 /* man - set the 'close' on free */ +#define BIO_CTRL_PENDING 10 /* opt - is their more data buffered */ +#define BIO_CTRL_FLUSH 11 /* opt - 'flush' buffered output */ +#define BIO_CTRL_DUP 12 /* man - extra stuff for 'duped' BIO */ +#define BIO_CTRL_WPENDING 13 /* opt - number of bytes still to write */ +/* callback is int cb(BIO *bio,state,ret); */ +#define BIO_CTRL_SET_CALLBACK 14 /* opt - set callback function */ +#define BIO_CTRL_GET_CALLBACK 15 /* opt - set callback function */ + +#define BIO_CTRL_SET_FILENAME 30 /* BIO_s_file special */ + +/* dgram BIO stuff */ +#define BIO_CTRL_DGRAM_CONNECT 31 /* BIO dgram special */ +#define BIO_CTRL_DGRAM_SET_CONNECTED 32 /* allow for an externally + * connected socket to be + * passed in */ +#define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33 /* setsockopt, essentially */ +#define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34 /* getsockopt, essentially */ +#define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35 /* setsockopt, essentially */ +#define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36 /* getsockopt, essentially */ + +#define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37 /* flag whether the last */ +#define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38 /* I/O operation tiemd out */ + +/* #ifdef IP_MTU_DISCOVER */ +#define BIO_CTRL_DGRAM_MTU_DISCOVER 39 /* set DF bit on egress packets */ +/* #endif */ + +#define BIO_CTRL_DGRAM_QUERY_MTU 40 /* as kernel for current MTU */ +#define BIO_CTRL_DGRAM_GET_FALLBACK_MTU 47 +#define BIO_CTRL_DGRAM_GET_MTU 41 /* get cached value for MTU */ +#define BIO_CTRL_DGRAM_SET_MTU 42 /* set cached value for + * MTU. want to use this + * if asking the kernel + * fails */ + +#define BIO_CTRL_DGRAM_MTU_EXCEEDED 43 /* check whether the MTU + * was exceed in the + * previous write + * operation */ + +#define BIO_CTRL_DGRAM_GET_PEER 46 +#define BIO_CTRL_DGRAM_SET_PEER 44 /* Destination for the data */ + +#define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45 /* Next DTLS handshake timeout to + * adjust socket timeouts */ + + +/* modifiers */ +#define BIO_FP_READ 0x02 +#define BIO_FP_WRITE 0x04 +#define BIO_FP_APPEND 0x08 +#define BIO_FP_TEXT 0x10 + +#define BIO_FLAGS_READ 0x01 +#define BIO_FLAGS_WRITE 0x02 +#define BIO_FLAGS_IO_SPECIAL 0x04 +#define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL) +#define BIO_FLAGS_SHOULD_RETRY 0x08 + +/* Used in BIO_gethostbyname() */ +#define BIO_GHBN_CTRL_HITS 1 +#define BIO_GHBN_CTRL_MISSES 2 +#define BIO_GHBN_CTRL_CACHE_SIZE 3 +#define BIO_GHBN_CTRL_GET_ENTRY 4 +#define BIO_GHBN_CTRL_FLUSH 5 + +/* Mostly used in the SSL BIO */ +/* Not used anymore + * #define BIO_FLAGS_PROTOCOL_DELAYED_READ 0x10 + * #define BIO_FLAGS_PROTOCOL_DELAYED_WRITE 0x20 + * #define BIO_FLAGS_PROTOCOL_STARTUP 0x40 + */ + +#define BIO_FLAGS_BASE64_NO_NL 0x100 + +/* This is used with memory BIOs: it means we shouldn't free up or change the + * data in any way. + */ +#define BIO_FLAGS_MEM_RDONLY 0x200 + +typedef struct bio_st BIO; + +void BIO_set_flags(BIO *b, int flags); +int BIO_test_flags(const BIO *b, int flags); +void BIO_clear_flags(BIO *b, int flags); + +#define BIO_get_flags(b) BIO_test_flags(b, ~(0x0)) +#define BIO_set_retry_special(b) \ + BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY)) +#define BIO_set_retry_read(b) \ + BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY)) +#define BIO_set_retry_write(b) \ + BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY)) + +/* These are normally used internally in BIOs */ +#define BIO_clear_retry_flags(b) \ + BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) +#define BIO_get_retry_flags(b) \ + BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) + +/* These should be used by the application to tell why we should retry */ +#define BIO_should_read(a) BIO_test_flags(a, BIO_FLAGS_READ) +#define BIO_should_write(a) BIO_test_flags(a, BIO_FLAGS_WRITE) +#define BIO_should_io_special(a) BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL) +#define BIO_retry_type(a) BIO_test_flags(a, BIO_FLAGS_RWS) +#define BIO_should_retry(a) BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY) + +/* The next three are used in conjunction with the + * BIO_should_io_special() condition. After this returns true, + * BIO *BIO_get_retry_BIO(BIO *bio, int *reason); will walk the BIO + * stack and return the 'reason' for the special and the offending BIO. + * Given a BIO, BIO_get_retry_reason(bio) will return the code. */ +/* Returned from the SSL bio when the certificate retrieval code had an error */ +#define BIO_RR_SSL_X509_LOOKUP 0x01 +/* Returned from the connect BIO when a connect would have blocked */ +#define BIO_RR_CONNECT 0x02 +/* Returned from the accept BIO when an accept would have blocked */ +#define BIO_RR_ACCEPT 0x03 + +/* These are passed by the BIO callback */ +#define BIO_CB_FREE 0x01 +#define BIO_CB_READ 0x02 +#define BIO_CB_WRITE 0x03 +#define BIO_CB_PUTS 0x04 +#define BIO_CB_GETS 0x05 +#define BIO_CB_CTRL 0x06 + +/* The callback is called before and after the underling operation, + * The BIO_CB_RETURN flag indicates if it is after the call */ +#define BIO_CB_RETURN 0x80 +#define BIO_CB_return(a) ((a)|BIO_CB_RETURN)) +#define BIO_cb_pre(a) (!((a)&BIO_CB_RETURN)) +#define BIO_cb_post(a) ((a)&BIO_CB_RETURN) + +long (*BIO_get_callback(const BIO *b))(struct bio_st *, int, const char *, + int, long, long); +void BIO_set_callback(BIO *b, + long (*callback)(struct bio_st *, int, const char *, int, long, long)); +char *BIO_get_callback_arg(const BIO *b); +void BIO_set_callback_arg(BIO *b, char *arg); + +const char * BIO_method_name(const BIO *b); +int BIO_method_type(const BIO *b); + +typedef void bio_info_cb(struct bio_st *, int, const char *, int, long, long); + +typedef struct bio_method_st { + int type; + const char *name; + int (*bwrite)(BIO *, const char *, int); + int (*bread)(BIO *, char *, int); + int (*bputs)(BIO *, const char *); + int (*bgets)(BIO *, char *, int); + long (*ctrl)(BIO *, int, long, void *); + int (*create)(BIO *); + int (*destroy)(BIO *); + long (*callback_ctrl)(BIO *, int, bio_info_cb *); +} BIO_METHOD; + +struct bio_st { + BIO_METHOD *method; + /* bio, mode, argp, argi, argl, ret */ + long (*callback)(struct bio_st *, int, const char *, int, long, long); + char *cb_arg; /* first argument for the callback */ + + int init; + int shutdown; + int flags; /* extra storage */ + int retry_reason; + int num; + void *ptr; + struct bio_st *next_bio; /* used by filter BIOs */ + struct bio_st *prev_bio; /* used by filter BIOs */ + int references; + unsigned long num_read; + unsigned long num_write; + + CRYPTO_EX_DATA ex_data; +}; + +DECLARE_STACK_OF(BIO) + +typedef struct bio_f_buffer_ctx_struct { + /* Buffers are setup like this: + * + * <---------------------- size -----------------------> + * +---------------------------------------------------+ + * | consumed | remaining | free space | + * +---------------------------------------------------+ + * <-- off --><------- len -------> + */ + + /* BIO *bio; */ /* this is now in the BIO struct */ + int ibuf_size; /* how big is the input buffer */ + int obuf_size; /* how big is the output buffer */ + + char *ibuf; /* the char array */ + int ibuf_len; /* how many bytes are in it */ + int ibuf_off; /* write/read offset */ + + char *obuf; /* the char array */ + int obuf_len; /* how many bytes are in it */ + int obuf_off; /* write/read offset */ +} BIO_F_BUFFER_CTX; + +/* Prefix and suffix callback in ASN1 BIO */ +typedef int asn1_ps_func(BIO *b, unsigned char **pbuf, int *plen, void *parg); + + +/* connect BIO stuff */ +#define BIO_CONN_S_BEFORE 1 +#define BIO_CONN_S_GET_IP 2 +#define BIO_CONN_S_GET_PORT 3 +#define BIO_CONN_S_CREATE_SOCKET 4 +#define BIO_CONN_S_CONNECT 5 +#define BIO_CONN_S_OK 6 +#define BIO_CONN_S_BLOCKED_CONNECT 7 +#define BIO_CONN_S_NBIO 8 +/*#define BIO_CONN_get_param_hostname BIO_ctrl */ + +#define BIO_C_SET_CONNECT 100 +#define BIO_C_DO_STATE_MACHINE 101 +#define BIO_C_SET_NBIO 102 +#define BIO_C_SET_PROXY_PARAM 103 +#define BIO_C_SET_FD 104 +#define BIO_C_GET_FD 105 +#define BIO_C_SET_FILE_PTR 106 +#define BIO_C_GET_FILE_PTR 107 +#define BIO_C_SET_FILENAME 108 +#define BIO_C_SET_SSL 109 +#define BIO_C_GET_SSL 110 +#define BIO_C_SET_MD 111 +#define BIO_C_GET_MD 112 +#define BIO_C_GET_CIPHER_STATUS 113 +#define BIO_C_SET_BUF_MEM 114 +#define BIO_C_GET_BUF_MEM_PTR 115 +#define BIO_C_GET_BUFF_NUM_LINES 116 +#define BIO_C_SET_BUFF_SIZE 117 +#define BIO_C_SET_ACCEPT 118 +#define BIO_C_SSL_MODE 119 +#define BIO_C_GET_MD_CTX 120 +#define BIO_C_GET_PROXY_PARAM 121 +#define BIO_C_SET_BUFF_READ_DATA 122 /* data to read first */ +#define BIO_C_GET_CONNECT 123 +#define BIO_C_GET_ACCEPT 124 +#define BIO_C_SET_SSL_RENEGOTIATE_BYTES 125 +#define BIO_C_GET_SSL_NUM_RENEGOTIATES 126 +#define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT 127 +#define BIO_C_FILE_SEEK 128 +#define BIO_C_GET_CIPHER_CTX 129 +#define BIO_C_SET_BUF_MEM_EOF_RETURN 130/*return end of input value*/ +#define BIO_C_SET_BIND_MODE 131 +#define BIO_C_GET_BIND_MODE 132 +#define BIO_C_FILE_TELL 133 +#define BIO_C_GET_SOCKS 134 +#define BIO_C_SET_SOCKS 135 + +#define BIO_C_SET_WRITE_BUF_SIZE 136/* for BIO_s_bio */ +#define BIO_C_GET_WRITE_BUF_SIZE 137 +#define BIO_C_MAKE_BIO_PAIR 138 +#define BIO_C_DESTROY_BIO_PAIR 139 +#define BIO_C_GET_WRITE_GUARANTEE 140 +#define BIO_C_GET_READ_REQUEST 141 +#define BIO_C_SHUTDOWN_WR 142 +#define BIO_C_NREAD0 143 +#define BIO_C_NREAD 144 +#define BIO_C_NWRITE0 145 +#define BIO_C_NWRITE 146 +#define BIO_C_RESET_READ_REQUEST 147 +#define BIO_C_SET_MD_CTX 148 + +#define BIO_C_SET_PREFIX 149 +#define BIO_C_GET_PREFIX 150 +#define BIO_C_SET_SUFFIX 151 +#define BIO_C_GET_SUFFIX 152 + +#define BIO_C_SET_EX_ARG 153 +#define BIO_C_GET_EX_ARG 154 + +#define BIO_set_app_data(s,arg) BIO_set_ex_data(s,0,arg) +#define BIO_get_app_data(s) BIO_get_ex_data(s,0) + +/* BIO_s_connect() and BIO_s_socks4a_connect() */ +#define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name) +#define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port) +#define BIO_set_conn_ip(b,ip) BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)ip) +#define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port) +#define BIO_get_conn_hostname(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0) +#define BIO_get_conn_port(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1) +#define BIO_get_conn_ip(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2) +#define BIO_get_conn_int_port(b) BIO_int_ctrl(b,BIO_C_GET_CONNECT,3,0) + + +#define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) + +/* BIO_s_accept_socket() */ +#define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name) +#define BIO_get_accept_port(b) BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0) +/* #define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */ +#define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?(void *)"a":NULL) +#define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio) + +#define BIO_BIND_NORMAL 0 +#define BIO_BIND_REUSEADDR_IF_UNUSED 1 +#define BIO_BIND_REUSEADDR 2 +#define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL) +#define BIO_get_bind_mode(b,mode) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL) + +#define BIO_do_connect(b) BIO_do_handshake(b) +#define BIO_do_accept(b) BIO_do_handshake(b) +#define BIO_do_handshake(b) BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL) + +/* BIO_s_proxy_client() */ +#define BIO_set_url(b,url) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,0,(char *)(url)) +#define BIO_set_proxies(b,p) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,1,(char *)(p)) +/* BIO_set_nbio(b,n) */ +#define BIO_set_filter_bio(b,s) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,2,(char *)(s)) +/* BIO *BIO_get_filter_bio(BIO *bio); */ +#define BIO_set_proxy_cb(b,cb) BIO_callback_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(void *(*cb)())) +#define BIO_set_proxy_header(b,sk) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,4,(char *)sk) +#define BIO_set_no_connect_return(b,bool) BIO_int_ctrl(b,BIO_C_SET_PROXY_PARAM,5,bool) + +#define BIO_get_proxy_header(b,skp) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,0,(char *)skp) +#define BIO_get_proxies(b,pxy_p) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,1,(char *)(pxy_p)) +#define BIO_get_url(b,url) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,2,(char *)(url)) +#define BIO_get_no_connect_return(b) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,5,NULL) + +#define BIO_set_fd(b,fd,c) BIO_int_ctrl(b,BIO_C_SET_FD,c,fd) +#define BIO_get_fd(b,c) BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c) + +#define BIO_set_fp(b,fp,c) BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp) +#define BIO_get_fp(b,fpp) BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)fpp) + +#define BIO_seek(b,ofs) (int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL) +#define BIO_tell(b) (int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL) + +/* name is cast to lose const, but might be better to route through a function + so we can do it safely */ +#define BIO_read_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ,(char *)name) +#define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_WRITE,name) +#define BIO_append_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_APPEND,name) +#define BIO_rw_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name) + +/* WARNING WARNING, this ups the reference count on the read bio of the + * SSL structure. This is because the ssl read BIO is now pointed to by + * the next_bio field in the bio. So when you free the BIO, make sure + * you are doing a BIO_free_all() to catch the underlying BIO. */ +#define BIO_set_ssl(b,ssl,c) BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl) +#define BIO_get_ssl(b,sslp) BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp) +#define BIO_set_ssl_mode(b,client) BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL) +#define BIO_set_ssl_renegotiate_bytes(b,num) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL); +#define BIO_get_num_renegotiates(b) \ + BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL); +#define BIO_set_ssl_renegotiate_timeout(b,seconds) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL); + +/* defined in evp.h */ +/* #define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */ + +#define BIO_get_mem_data(b,pp) BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp) +#define BIO_set_mem_buf(b,bm,c) BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)bm) +#define BIO_get_mem_ptr(b,pp) BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0,(char *)pp) +#define BIO_set_mem_eof_return(b,v) \ + BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL) + +/* For the BIO_f_buffer() type */ +#define BIO_get_buffer_num_lines(b) BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL) +#define BIO_set_buffer_size(b,size) BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL) +#define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0) +#define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1) +#define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf) + +/* Don't use the next one unless you know what you are doing :-) */ +#define BIO_dup_state(b,ret) BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret)) + +#define BIO_reset(b) (int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL) +#define BIO_eof(b) (int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL) +#define BIO_set_close(b,c) (int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL) +#define BIO_get_close(b) (int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL) +#define BIO_pending(b) (int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL) +#define BIO_wpending(b) (int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL) +/* ...pending macros have inappropriate return type */ +size_t BIO_ctrl_pending(BIO *b); +size_t BIO_ctrl_wpending(BIO *b); +#define BIO_flush(b) (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL) +#define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \ + cbp) +#define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb) + +/* For the BIO_f_buffer() type */ +#define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL) + +/* For BIO_s_bio() */ +#define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL) +#define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL) +#define BIO_make_bio_pair(b1,b2) (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2) +#define BIO_destroy_bio_pair(b) (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL) +#define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL) +/* macros with inappropriate type -- but ...pending macros use int too: */ +#define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL) +#define BIO_get_read_request(b) (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL) +size_t BIO_ctrl_get_write_guarantee(BIO *b); +size_t BIO_ctrl_get_read_request(BIO *b); +int BIO_ctrl_reset_read_request(BIO *b); + +/* ctrl macros for dgram */ +#define BIO_ctrl_dgram_connect(b,peer) \ + (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)peer) +#define BIO_ctrl_set_connected(b, state, peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, state, (char *)peer) +#define BIO_dgram_recv_timedout(b) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL) +#define BIO_dgram_send_timedout(b) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL) +#define BIO_dgram_get_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer) +#define BIO_dgram_set_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer) + +/* These two aren't currently implemented */ +/* int BIO_get_ex_num(BIO *bio); */ +/* void BIO_set_ex_free_func(BIO *bio,int idx,void (*cb)()); */ +int BIO_set_ex_data(BIO *bio, int idx, void *data); +void *BIO_get_ex_data(BIO *bio, int idx); +int +BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, +CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +unsigned long BIO_number_read(BIO *bio); +unsigned long BIO_number_written(BIO *bio); + +/* For BIO_f_asn1() */ +int +BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, +asn1_ps_func *prefix_free); +int +BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, +asn1_ps_func **pprefix_free); +int +BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, +asn1_ps_func *suffix_free); +int +BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, +asn1_ps_func **psuffix_free); + +BIO_METHOD *BIO_s_file(void ); +BIO *BIO_new_file(const char *filename, const char *mode); +BIO *BIO_new_fp(FILE *stream, int close_flag); +# define BIO_s_file_internal BIO_s_file +BIO * BIO_new(BIO_METHOD *type); +int BIO_set(BIO *a, BIO_METHOD *type); +int BIO_free(BIO *a); +void BIO_vfree(BIO *a); +int BIO_read(BIO *b, void *data, int len) + __attribute__((__bounded__(__buffer__,2,3))); +int BIO_gets(BIO *bp, char *buf, int size) + __attribute__((__bounded__ (__string__,2,3))); +int BIO_write(BIO *b, const void *data, int len) + __attribute__((__bounded__(__buffer__,2,3))); +int BIO_puts(BIO *bp, const char *buf); +int BIO_indent(BIO *b, int indent, int max); +long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg); +long BIO_callback_ctrl(BIO *b, int cmd, + void (*fp)(struct bio_st *, int, const char *, int, long, long)); +char * BIO_ptr_ctrl(BIO *bp, int cmd, long larg); +long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg); +BIO * BIO_push(BIO *b, BIO *append); +BIO * BIO_pop(BIO *b); +void BIO_free_all(BIO *a); +BIO * BIO_find_type(BIO *b, int bio_type); +BIO * BIO_next(BIO *b); +BIO * BIO_get_retry_BIO(BIO *bio, int *reason); +int BIO_get_retry_reason(BIO *bio); +BIO * BIO_dup_chain(BIO *in); + +int BIO_nread0(BIO *bio, char **buf); +int BIO_nread(BIO *bio, char **buf, int num); +int BIO_nwrite0(BIO *bio, char **buf); +int BIO_nwrite(BIO *bio, char **buf, int num); + +long BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi, + long argl, long ret); + +BIO_METHOD *BIO_s_mem(void); +BIO *BIO_new_mem_buf(void *buf, int len); +BIO_METHOD *BIO_s_socket(void); +BIO_METHOD *BIO_s_connect(void); +BIO_METHOD *BIO_s_accept(void); +BIO_METHOD *BIO_s_fd(void); +BIO_METHOD *BIO_s_log(void); +BIO_METHOD *BIO_s_bio(void); +BIO_METHOD *BIO_s_null(void); +BIO_METHOD *BIO_f_null(void); +BIO_METHOD *BIO_f_buffer(void); +BIO_METHOD *BIO_f_nbio_test(void); +#ifndef OPENSSL_NO_DGRAM +BIO_METHOD *BIO_s_datagram(void); +#endif + +/* BIO_METHOD *BIO_f_ber(void); */ + +int BIO_sock_should_retry(int i); +int BIO_sock_non_fatal_error(int _error); +int BIO_dgram_non_fatal_error(int _error); + +int BIO_fd_should_retry(int i); +int BIO_fd_non_fatal_error(int _error); +int +BIO_dump_cb(int (*cb)(const void *data, size_t len, void *u), +void *u, const char *s, int len); +int +BIO_dump_indent_cb(int (*cb)(const void *data, size_t len, void *u), +void *u, const char *s, int len, int indent); +int BIO_dump(BIO *b, const char *bytes, int len); +int BIO_dump_indent(BIO *b, const char *bytes, int len, int indent); +int BIO_dump_fp(FILE *fp, const char *s, int len); +int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent); +struct hostent *BIO_gethostbyname(const char *name); +/* We might want a thread-safe interface too: + * struct hostent *BIO_gethostbyname_r(const char *name, + * struct hostent *result, void *buffer, size_t buflen); + * or something similar (caller allocates a struct hostent, + * pointed to by "result", and additional buffer space for the various + * substructures; if the buffer does not suffice, NULL is returned + * and an appropriate error code is set). + */ +int BIO_sock_error(int sock); +int BIO_socket_ioctl(int fd, long type, void *arg); +int BIO_socket_nbio(int fd, int mode); +int BIO_get_port(const char *str, unsigned short *port_ptr); +int BIO_get_host_ip(const char *str, unsigned char *ip); +int BIO_get_accept_socket(char *host_port, int mode); +int BIO_accept(int sock, char **ip_port); +int BIO_sock_init(void ); +void BIO_sock_cleanup(void); +int BIO_set_tcp_ndelay(int sock, int turn_on); + +BIO *BIO_new_socket(int sock, int close_flag); +BIO *BIO_new_dgram(int fd, int close_flag); +BIO *BIO_new_fd(int fd, int close_flag); +BIO *BIO_new_connect(char *host_port); +BIO *BIO_new_accept(char *host_port); + +int +BIO_new_bio_pair(BIO **bio1, size_t writebuf1, +BIO **bio2, size_t writebuf2); +/* If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints. + * Otherwise returns 0 and sets *bio1 and *bio2 to NULL. + * Size 0 uses default value. + */ + +void BIO_copy_next_retry(BIO *b); + +/*long BIO_ghbn_ctrl(int cmd,int iarg,char *parg);*/ + +int +BIO_printf(BIO *bio, const char *format, ...) + __attribute__((__format__(__printf__, 2, 3), __nonnull__(2))); +int +BIO_vprintf(BIO *bio, const char *format, va_list args) + __attribute__((__format__(__printf__, 2, 0), __nonnull__(2))); +int +BIO_snprintf(char *buf, size_t n, const char *format, ...) + __attribute__((__deprecated__, __format__(__printf__, 3, 4), + __nonnull__(3))); +int +BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) + __attribute__((__deprecated__, __format__(__printf__, 3, 0), + __nonnull__(3))); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_BIO_strings(void); + +/* Error codes for the BIO functions. */ + +/* Function codes. */ +#define BIO_F_ACPT_STATE 100 +#define BIO_F_BIO_ACCEPT 101 +#define BIO_F_BIO_BER_GET_HEADER 102 +#define BIO_F_BIO_CALLBACK_CTRL 131 +#define BIO_F_BIO_CTRL 103 +#define BIO_F_BIO_GETHOSTBYNAME 120 +#define BIO_F_BIO_GETS 104 +#define BIO_F_BIO_GET_ACCEPT_SOCKET 105 +#define BIO_F_BIO_GET_HOST_IP 106 +#define BIO_F_BIO_GET_PORT 107 +#define BIO_F_BIO_MAKE_PAIR 121 +#define BIO_F_BIO_NEW 108 +#define BIO_F_BIO_NEW_FILE 109 +#define BIO_F_BIO_NEW_MEM_BUF 126 +#define BIO_F_BIO_NREAD 123 +#define BIO_F_BIO_NREAD0 124 +#define BIO_F_BIO_NWRITE 125 +#define BIO_F_BIO_NWRITE0 122 +#define BIO_F_BIO_PUTS 110 +#define BIO_F_BIO_READ 111 +#define BIO_F_BIO_SOCK_INIT 112 +#define BIO_F_BIO_WRITE 113 +#define BIO_F_BUFFER_CTRL 114 +#define BIO_F_CONN_CTRL 127 +#define BIO_F_CONN_STATE 115 +#define BIO_F_DGRAM_SCTP_READ 132 +#define BIO_F_FILE_CTRL 116 +#define BIO_F_FILE_READ 130 +#define BIO_F_LINEBUFFER_CTRL 129 +#define BIO_F_MEM_READ 128 +#define BIO_F_MEM_WRITE 117 +#define BIO_F_SSL_NEW 118 +#define BIO_F_WSASTARTUP 119 + +/* Reason codes. */ +#define BIO_R_ACCEPT_ERROR 100 +#define BIO_R_BAD_FOPEN_MODE 101 +#define BIO_R_BAD_HOSTNAME_LOOKUP 102 +#define BIO_R_BROKEN_PIPE 124 +#define BIO_R_CONNECT_ERROR 103 +#define BIO_R_EOF_ON_MEMORY_BIO 127 +#define BIO_R_ERROR_SETTING_NBIO 104 +#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET 105 +#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET 106 +#define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107 +#define BIO_R_INVALID_ARGUMENT 125 +#define BIO_R_INVALID_IP_ADDRESS 108 +#define BIO_R_INVALID_PORT_NUMBER 129 +#define BIO_R_IN_USE 123 +#define BIO_R_KEEPALIVE 109 +#define BIO_R_NBIO_CONNECT_ERROR 110 +#define BIO_R_NO_ACCEPT_PORT_SPECIFIED 111 +#define BIO_R_NO_HOSTNAME_SPECIFIED 112 +#define BIO_R_NO_PORT_DEFINED 113 +#define BIO_R_NO_PORT_SPECIFIED 114 +#define BIO_R_NO_SUCH_FILE 128 +#define BIO_R_NULL_PARAMETER 115 +#define BIO_R_TAG_MISMATCH 116 +#define BIO_R_UNABLE_TO_BIND_SOCKET 117 +#define BIO_R_UNABLE_TO_CREATE_SOCKET 118 +#define BIO_R_UNABLE_TO_LISTEN_SOCKET 119 +#define BIO_R_UNINITIALIZED 120 +#define BIO_R_UNSUPPORTED_METHOD 121 +#define BIO_R_WRITE_TO_READ_ONLY_BIO 126 +#define BIO_R_WSASTARTUP 122 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/blowfish.h b/crypto/libressl/include/openssl/blowfish.h new file mode 100644 index 0000000000..0b53ae7790 --- /dev/null +++ b/crypto/libressl/include/openssl/blowfish.h @@ -0,0 +1,112 @@ +/* $OpenBSD: blowfish.h,v 1.13 2014/06/12 15:49:28 deraadt Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BLOWFISH_H +#define HEADER_BLOWFISH_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENSSL_NO_BF +#error BF is disabled. +#endif + +#define BF_ENCRYPT 1 +#define BF_DECRYPT 0 + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! BF_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! BF_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +#define BF_LONG unsigned int + +#define BF_ROUNDS 16 +#define BF_BLOCK 8 + +typedef struct bf_key_st + { + BF_LONG P[BF_ROUNDS+2]; + BF_LONG S[4*256]; + } BF_KEY; + +void BF_set_key(BF_KEY *key, int len, const unsigned char *data); + +void BF_encrypt(BF_LONG *data,const BF_KEY *key); +void BF_decrypt(BF_LONG *data,const BF_KEY *key); + +void BF_ecb_encrypt(const unsigned char *in, unsigned char *out, + const BF_KEY *key, int enc); +void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int enc); +void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int *num, int enc); +void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int *num); +const char *BF_options(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/libressl/include/openssl/bn.h b/crypto/libressl/include/openssl/bn.h new file mode 100644 index 0000000000..a9234a6ef7 --- /dev/null +++ b/crypto/libressl/include/openssl/bn.h @@ -0,0 +1,820 @@ +/* $OpenBSD: bn.h,v 1.30 2016/03/04 16:06:38 doug Exp $ */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the Eric Young open source + * license provided above. + * + * The binary polynomial arithmetic software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#ifndef HEADER_BN_H +#define HEADER_BN_H + +#include +#include + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* These preprocessor symbols control various aspects of the bignum headers and + * library code. They're not defined by any "normal" configuration, as they are + * intended for development and testing purposes. NB: defining all three can be + * useful for debugging application code as well as openssl itself. + * + * BN_DEBUG - turn on various debugging alterations to the bignum code + * BN_DEBUG_RAND - uses random poisoning of unused words to trip up + * mismanagement of bignum internals. You must also define BN_DEBUG. + */ +/* #define BN_DEBUG */ +/* #define BN_DEBUG_RAND */ + +#ifndef OPENSSL_SMALL_FOOTPRINT +#define BN_MUL_COMBA +#define BN_SQR_COMBA +#define BN_RECURSION +#endif + +/* This next option uses the C libraries (2 word)/(1 word) function. + * If it is not defined, I use my C version (which is slower). + * The reason for this flag is that when the particular C compiler + * library routine is used, and the library is linked with a different + * compiler, the library is missing. This mostly happens when the + * library is built with gcc and then linked using normal cc. This would + * be a common occurrence because gcc normally produces code that is + * 2 times faster than system compilers for the big number stuff. + * For machines with only one compiler (or shared libraries), this should + * be on. Again this in only really a problem on machines + * using "long long's", are 32bit, and are not using my assembler code. */ +/* #define BN_DIV2W */ + +#ifdef _LP64 +#undef BN_LLONG +#define BN_ULONG unsigned long +#define BN_LONG long +#define BN_BITS 128 +#define BN_BYTES 8 +#define BN_BITS2 64 +#define BN_BITS4 32 +#define BN_MASK2 (0xffffffffffffffffL) +#define BN_MASK2l (0xffffffffL) +#define BN_MASK2h (0xffffffff00000000L) +#define BN_MASK2h1 (0xffffffff80000000L) +#define BN_TBIT (0x8000000000000000L) +#define BN_DEC_CONV (10000000000000000000UL) +#define BN_DEC_FMT1 "%lu" +#define BN_DEC_FMT2 "%019lu" +#define BN_DEC_NUM 19 +#define BN_HEX_FMT1 "%lX" +#define BN_HEX_FMT2 "%016lX" +#else +#define BN_ULLONG unsigned long long +#define BN_LLONG +#define BN_ULONG unsigned int +#define BN_LONG int +#define BN_BITS 64 +#define BN_BYTES 4 +#define BN_BITS2 32 +#define BN_BITS4 16 +#define BN_MASK (0xffffffffffffffffLL) +#define BN_MASK2 (0xffffffffL) +#define BN_MASK2l (0xffff) +#define BN_MASK2h1 (0xffff8000L) +#define BN_MASK2h (0xffff0000L) +#define BN_TBIT (0x80000000L) +#define BN_DEC_CONV (1000000000L) +#define BN_DEC_FMT1 "%u" +#define BN_DEC_FMT2 "%09u" +#define BN_DEC_NUM 9 +#define BN_HEX_FMT1 "%X" +#define BN_HEX_FMT2 "%08X" +#endif + +#define BN_FLG_MALLOCED 0x01 +#define BN_FLG_STATIC_DATA 0x02 +#define BN_FLG_CONSTTIME 0x04 /* avoid leaking exponent information through timing, + * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime, + * BN_div() will call BN_div_no_branch, + * BN_mod_inverse() will call BN_mod_inverse_no_branch. + */ + +#ifndef OPENSSL_NO_DEPRECATED +#define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME /* deprecated name for the flag */ + /* avoid leaking exponent information through timings + * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) */ +#endif + +#ifndef OPENSSL_NO_DEPRECATED +#define BN_FLG_FREE 0x8000 /* used for debuging */ +#endif +#define BN_set_flags(b,n) ((b)->flags|=(n)) +#define BN_get_flags(b,n) ((b)->flags&(n)) + +/* get a clone of a BIGNUM with changed flags, for *temporary* use only + * (the two BIGNUMs cannot not be used in parallel!) */ +#define BN_with_flags(dest,b,n) ((dest)->d=(b)->d, \ + (dest)->top=(b)->top, \ + (dest)->dmax=(b)->dmax, \ + (dest)->neg=(b)->neg, \ + (dest)->flags=(((dest)->flags & BN_FLG_MALLOCED) \ + | ((b)->flags & ~BN_FLG_MALLOCED) \ + | BN_FLG_STATIC_DATA \ + | (n))) + +struct bignum_st { + BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */ + int top; /* Index of last used d +1. */ + /* The next are internal book keeping for bn_expand. */ + int dmax; /* Size of the d array. */ + int neg; /* one if the number is negative */ + int flags; +}; + +/* Used for montgomery multiplication */ +struct bn_mont_ctx_st { + int ri; /* number of bits in R */ + BIGNUM RR; /* used to convert to montgomery form */ + BIGNUM N; /* The modulus */ + BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1 + * (Ni is only stored for bignum algorithm) */ + BN_ULONG n0[2];/* least significant word(s) of Ni; + (type changed with 0.9.9, was "BN_ULONG n0;" before) */ + int flags; +}; + +/* Used for reciprocal division/mod functions + * It cannot be shared between threads + */ +struct bn_recp_ctx_st { + BIGNUM N; /* the divisor */ + BIGNUM Nr; /* the reciprocal */ + int num_bits; + int shift; + int flags; +}; + +/* Used for slow "generation" functions. */ +struct bn_gencb_st { + unsigned int ver; /* To handle binary (in)compatibility */ + void *arg; /* callback-specific data */ + union { + /* if(ver==1) - handles old style callbacks */ + void (*cb_1)(int, int, void *); + /* if(ver==2) - new callback style */ + int (*cb_2)(int, int, BN_GENCB *); + } cb; +}; +/* Wrapper function to make using BN_GENCB easier, */ +int BN_GENCB_call(BN_GENCB *cb, int a, int b); +/* Macro to populate a BN_GENCB structure with an "old"-style callback */ +#define BN_GENCB_set_old(gencb, callback, cb_arg) { \ + BN_GENCB *tmp_gencb = (gencb); \ + tmp_gencb->ver = 1; \ + tmp_gencb->arg = (cb_arg); \ + tmp_gencb->cb.cb_1 = (callback); } +/* Macro to populate a BN_GENCB structure with a "new"-style callback */ +#define BN_GENCB_set(gencb, callback, cb_arg) { \ + BN_GENCB *tmp_gencb = (gencb); \ + tmp_gencb->ver = 2; \ + tmp_gencb->arg = (cb_arg); \ + tmp_gencb->cb.cb_2 = (callback); } + +#define BN_prime_checks 0 /* default: select number of iterations + based on the size of the number */ + +/* number of Miller-Rabin iterations for an error rate of less than 2^-80 + * for random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook + * of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996]; + * original paper: Damgaard, Landrock, Pomerance: Average case error estimates + * for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */ +#define BN_prime_checks_for_size(b) ((b) >= 1300 ? 2 : \ + (b) >= 850 ? 3 : \ + (b) >= 650 ? 4 : \ + (b) >= 550 ? 5 : \ + (b) >= 450 ? 6 : \ + (b) >= 400 ? 7 : \ + (b) >= 350 ? 8 : \ + (b) >= 300 ? 9 : \ + (b) >= 250 ? 12 : \ + (b) >= 200 ? 15 : \ + (b) >= 150 ? 18 : \ + /* b >= 100 */ 27) + +#define BN_num_bytes(a) ((BN_num_bits(a)+7)/8) + +/* Note that BN_abs_is_word didn't work reliably for w == 0 until 0.9.8 */ +#define BN_abs_is_word(a,w) ((((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) || \ + (((w) == 0) && ((a)->top == 0))) +#define BN_is_zero(a) ((a)->top == 0) +#define BN_is_one(a) (BN_abs_is_word((a),1) && !(a)->neg) +#define BN_is_word(a,w) (BN_abs_is_word((a),(w)) && (!(w) || !(a)->neg)) +#define BN_is_odd(a) (((a)->top > 0) && ((a)->d[0] & 1)) + +#define BN_one(a) (BN_set_word((a),1)) +#define BN_zero_ex(a) \ + do { \ + BIGNUM *_tmp_bn = (a); \ + _tmp_bn->top = 0; \ + _tmp_bn->neg = 0; \ + } while(0) + +#ifdef OPENSSL_NO_DEPRECATED +#define BN_zero(a) BN_zero_ex(a) +#else +#define BN_zero(a) (BN_set_word((a),0)) +#endif + +const BIGNUM *BN_value_one(void); +char * BN_options(void); +BN_CTX *BN_CTX_new(void); +#ifndef OPENSSL_NO_DEPRECATED +void BN_CTX_init(BN_CTX *c); +#endif +void BN_CTX_free(BN_CTX *c); +void BN_CTX_start(BN_CTX *ctx); +BIGNUM *BN_CTX_get(BN_CTX *ctx); +void BN_CTX_end(BN_CTX *ctx); +int BN_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_num_bits(const BIGNUM *a); +int BN_num_bits_word(BN_ULONG); +BIGNUM *BN_new(void); +void BN_init(BIGNUM *); +void BN_clear_free(BIGNUM *a); +BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b); +void BN_swap(BIGNUM *a, BIGNUM *b); +BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); +int BN_bn2bin(const BIGNUM *a, unsigned char *to); +BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret); +int BN_bn2mpi(const BIGNUM *a, unsigned char *to); +int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); +/** BN_set_negative sets sign of a BIGNUM + * \param b pointer to the BIGNUM object + * \param n 0 if the BIGNUM b should be positive and a value != 0 otherwise + */ +void BN_set_negative(BIGNUM *b, int n); +/** BN_is_negative returns 1 if the BIGNUM is negative + * \param a pointer to the BIGNUM object + * \return 1 if a < 0 and 0 otherwise + */ +#define BN_is_negative(a) ((a)->neg != 0) + +int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, + BN_CTX *ctx); +#define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx)) +int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx); +int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m); +int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m); +int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx); +int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m); +int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m); + +BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w); +BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w); +int BN_mul_word(BIGNUM *a, BN_ULONG w); +int BN_add_word(BIGNUM *a, BN_ULONG w); +int BN_sub_word(BIGNUM *a, BN_ULONG w); +int BN_set_word(BIGNUM *a, BN_ULONG w); +BN_ULONG BN_get_word(const BIGNUM *a); + +int BN_cmp(const BIGNUM *a, const BIGNUM *b); +void BN_free(BIGNUM *a); +int BN_is_bit_set(const BIGNUM *a, int n); +int BN_lshift(BIGNUM *r, const BIGNUM *a, int n); +int BN_lshift1(BIGNUM *r, const BIGNUM *a); +int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); + +int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont); +int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1, + const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + +int BN_mask_bits(BIGNUM *a, int n); +int BN_print_fp(FILE *fp, const BIGNUM *a); +int BN_print(BIO *fp, const BIGNUM *a); +int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx); +int BN_rshift(BIGNUM *r, const BIGNUM *a, int n); +int BN_rshift1(BIGNUM *r, const BIGNUM *a); +void BN_clear(BIGNUM *a); +BIGNUM *BN_dup(const BIGNUM *a); +int BN_ucmp(const BIGNUM *a, const BIGNUM *b); +int BN_set_bit(BIGNUM *a, int n); +int BN_clear_bit(BIGNUM *a, int n); +char * BN_bn2hex(const BIGNUM *a); +char * BN_bn2dec(const BIGNUM *a); +int BN_hex2bn(BIGNUM **a, const char *str); +int BN_dec2bn(BIGNUM **a, const char *str); +int BN_asc2bn(BIGNUM **a, const char *str); +int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int BN_kronecker(const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx); /* returns -2 for error */ +BIGNUM *BN_mod_inverse(BIGNUM *ret, + const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); +BIGNUM *BN_mod_sqrt(BIGNUM *ret, + const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); + +void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords); + +/* Deprecated versions */ +#ifndef OPENSSL_NO_DEPRECATED +BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, const BIGNUM *rem, + void (*callback)(int, int, void *), void *cb_arg); +int BN_is_prime(const BIGNUM *p, int nchecks, + void (*callback)(int, int, void *), + BN_CTX *ctx, void *cb_arg); +int BN_is_prime_fasttest(const BIGNUM *p, int nchecks, + void (*callback)(int, int, void *), BN_CTX *ctx, void *cb_arg, + int do_trial_division); +#endif /* !defined(OPENSSL_NO_DEPRECATED) */ + +/* Newer versions */ +int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, + const BIGNUM *rem, BN_GENCB *cb); +int BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, BN_GENCB *cb); +int BN_is_prime_fasttest_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, + int do_trial_division, BN_GENCB *cb); + +int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx); + +int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, + const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2, + const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb); +int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, + BIGNUM *Xp1, BIGNUM *Xp2, + const BIGNUM *Xp, + const BIGNUM *e, BN_CTX *ctx, + BN_GENCB *cb); + +BN_MONT_CTX *BN_MONT_CTX_new(void ); +void BN_MONT_CTX_init(BN_MONT_CTX *ctx); +int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_MONT_CTX *mont, BN_CTX *ctx); +#define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\ + (r),(a),&((mont)->RR),(mont),(ctx)) +int BN_from_montgomery(BIGNUM *r, const BIGNUM *a, + BN_MONT_CTX *mont, BN_CTX *ctx); +void BN_MONT_CTX_free(BN_MONT_CTX *mont); +int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx); +BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from); +BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, + const BIGNUM *mod, BN_CTX *ctx); + +/* BN_BLINDING flags */ +#define BN_BLINDING_NO_UPDATE 0x00000001 +#define BN_BLINDING_NO_RECREATE 0x00000002 + +BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod); +void BN_BLINDING_free(BN_BLINDING *b); +int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *); +int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *); +#ifndef OPENSSL_NO_DEPRECATED +unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *); +void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long); +#endif +CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *); +unsigned long BN_BLINDING_get_flags(const BN_BLINDING *); +void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long); +BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, + const BIGNUM *e, BIGNUM *m, BN_CTX *ctx, + int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx), + BN_MONT_CTX *m_ctx); + +#ifndef OPENSSL_NO_DEPRECATED +void BN_set_params(int mul, int high, int low, int mont); +int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */ +#endif + +void BN_RECP_CTX_init(BN_RECP_CTX *recp); +BN_RECP_CTX *BN_RECP_CTX_new(void); +void BN_RECP_CTX_free(BN_RECP_CTX *recp); +int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *rdiv, BN_CTX *ctx); +int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, + BN_RECP_CTX *recp, BN_CTX *ctx); +int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, + BN_RECP_CTX *recp, BN_CTX *ctx); + +#ifndef OPENSSL_NO_EC2M + +/* Functions for arithmetic over binary polynomials represented by BIGNUMs. + * + * The BIGNUM::neg property of BIGNUMs representing binary polynomials is + * ignored. + * + * Note that input arguments are not const so that their bit arrays can + * be expanded to the appropriate size if needed. + */ + +int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); /*r = a + b*/ +#define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b) +int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p); /*r=a mod p*/ +int +BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); /* r = (a * b) mod p */ +int +BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); /* r = (a * a) mod p */ +int +BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p, + BN_CTX *ctx); /* r = (1 / b) mod p */ +int +BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); /* r = (a / b) mod p */ +int +BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); /* r = (a ^ b) mod p */ +int +BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); /* r = sqrt(a) mod p */ +int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); /* r^2 + r = a mod p */ +#define BN_GF2m_cmp(a, b) BN_ucmp((a), (b)) +/* Some functions allow for representation of the irreducible polynomials + * as an unsigned int[], say p. The irreducible f(t) is then of the form: + * t^p[0] + t^p[1] + ... + t^p[k] + * where m = p[0] > p[1] > ... > p[k] = 0. + */ +int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]); +/* r = a mod p */ +int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); /* r = (a * b) mod p */ +int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], + BN_CTX *ctx); /* r = (a * a) mod p */ +int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[], + BN_CTX *ctx); /* r = (1 / b) mod p */ +int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); /* r = (a / b) mod p */ +int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); /* r = (a ^ b) mod p */ +int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, + const int p[], BN_CTX *ctx); /* r = sqrt(a) mod p */ +int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a, + const int p[], BN_CTX *ctx); /* r^2 + r = a mod p */ +int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max); +int BN_GF2m_arr2poly(const int p[], BIGNUM *a); + +#endif + +/* faster mod functions for the 'NIST primes' + * 0 <= a < p^2 */ +int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); + +const BIGNUM *BN_get0_nist_prime_192(void); +const BIGNUM *BN_get0_nist_prime_224(void); +const BIGNUM *BN_get0_nist_prime_256(void); +const BIGNUM *BN_get0_nist_prime_384(void); +const BIGNUM *BN_get0_nist_prime_521(void); + +/* library internal functions */ + +#define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words))) +BIGNUM *bn_expand2(BIGNUM *a, int words); +BIGNUM *bn_expand(BIGNUM *a, int bits); + +#ifndef OPENSSL_NO_DEPRECATED +BIGNUM *bn_dup_expand(const BIGNUM *a, int words); /* unused */ +#endif + +/* Bignum consistency macros + * There is one "API" macro, bn_fix_top(), for stripping leading zeroes from + * bignum data after direct manipulations on the data. There is also an + * "internal" macro, bn_check_top(), for verifying that there are no leading + * zeroes. Unfortunately, some auditing is required due to the fact that + * bn_fix_top() has become an overabused duct-tape because bignum data is + * occasionally passed around in an inconsistent state. So the following + * changes have been made to sort this out; + * - bn_fix_top()s implementation has been moved to bn_correct_top() + * - if BN_DEBUG isn't defined, bn_fix_top() maps to bn_correct_top(), and + * bn_check_top() is as before. + * - if BN_DEBUG *is* defined; + * - bn_check_top() tries to pollute unused words even if the bignum 'top' is + * consistent. (ed: only if BN_DEBUG_RAND is defined) + * - bn_fix_top() maps to bn_check_top() rather than "fixing" anything. + * The idea is to have debug builds flag up inconsistent bignums when they + * occur. If that occurs in a bn_fix_top(), we examine the code in question; if + * the use of bn_fix_top() was appropriate (ie. it follows directly after code + * that manipulates the bignum) it is converted to bn_correct_top(), and if it + * was not appropriate, we convert it permanently to bn_check_top() and track + * down the cause of the bug. Eventually, no internal code should be using the + * bn_fix_top() macro. External applications and libraries should try this with + * their own code too, both in terms of building against the openssl headers + * with BN_DEBUG defined *and* linking with a version of OpenSSL built with it + * defined. This not only improves external code, it provides more test + * coverage for openssl's own code. + */ + +#ifdef BN_DEBUG + +/* We only need assert() when debugging */ +#include + +#ifdef BN_DEBUG_RAND +#define bn_pollute(a) \ + do { \ + const BIGNUM *_bnum1 = (a); \ + if(_bnum1->top < _bnum1->dmax) { \ + unsigned char _tmp_char; \ + /* We cast away const without the compiler knowing, any \ + * *genuinely* constant variables that aren't mutable \ + * wouldn't be constructed with top!=dmax. */ \ + BN_ULONG *_not_const; \ + memcpy(&_not_const, &_bnum1->d, sizeof(BN_ULONG*)); \ + arc4random_buf(&_tmp_char, 1); \ + memset((unsigned char *)(_not_const + _bnum1->top), _tmp_char, \ + (_bnum1->dmax - _bnum1->top) * sizeof(BN_ULONG)); \ + } \ + } while(0) +#else +#define bn_pollute(a) +#endif + +#define bn_check_top(a) \ + do { \ + const BIGNUM *_bnum2 = (a); \ + if (_bnum2 != NULL) { \ + assert((_bnum2->top == 0) || \ + (_bnum2->d[_bnum2->top - 1] != 0)); \ + bn_pollute(_bnum2); \ + } \ + } while(0) + +#define bn_fix_top(a) bn_check_top(a) + +#define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits+BN_BITS2-1))/BN_BITS2) +#define bn_wcheck_size(bn, words) \ + do { \ + const BIGNUM *_bnum2 = (bn); \ + assert(words <= (_bnum2)->dmax && words >= (_bnum2)->top); \ + } while(0) + +#else /* !BN_DEBUG */ + +#define bn_pollute(a) +#define bn_check_top(a) +#define bn_fix_top(a) bn_correct_top(a) +#define bn_check_size(bn, bits) +#define bn_wcheck_size(bn, words) + +#endif + +#define bn_correct_top(a) \ + { \ + BN_ULONG *ftl; \ + int tmp_top = (a)->top; \ + if (tmp_top > 0) \ + { \ + for (ftl= &((a)->d[tmp_top-1]); tmp_top > 0; tmp_top--) \ + if (*(ftl--)) break; \ + (a)->top = tmp_top; \ + } \ + bn_pollute(a); \ + } + + BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w); +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w); +void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num); +BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d); +BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, int num); +BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, int num); + +/* Primes from RFC 2409 */ +BIGNUM *get_rfc2409_prime_768(BIGNUM *bn); +BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn); + +/* Primes from RFC 3526 */ +BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn); + +int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_BN_strings(void); + +/* Error codes for the BN functions. */ + +/* Function codes. */ +#define BN_F_BNRAND 127 +#define BN_F_BN_BLINDING_CONVERT_EX 100 +#define BN_F_BN_BLINDING_CREATE_PARAM 128 +#define BN_F_BN_BLINDING_INVERT_EX 101 +#define BN_F_BN_BLINDING_NEW 102 +#define BN_F_BN_BLINDING_UPDATE 103 +#define BN_F_BN_BN2DEC 104 +#define BN_F_BN_BN2HEX 105 +#define BN_F_BN_CTX_GET 116 +#define BN_F_BN_CTX_NEW 106 +#define BN_F_BN_CTX_START 129 +#define BN_F_BN_DIV 107 +#define BN_F_BN_DIV_NO_BRANCH 138 +#define BN_F_BN_DIV_RECP 130 +#define BN_F_BN_EXP 123 +#define BN_F_BN_EXPAND2 108 +#define BN_F_BN_GENERATE_PRIME_EX 140 +#define BN_F_BN_EXPAND_INTERNAL 120 +#define BN_F_BN_GF2M_MOD 131 +#define BN_F_BN_GF2M_MOD_EXP 132 +#define BN_F_BN_GF2M_MOD_MUL 133 +#define BN_F_BN_GF2M_MOD_SOLVE_QUAD 134 +#define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR 135 +#define BN_F_BN_GF2M_MOD_SQR 136 +#define BN_F_BN_GF2M_MOD_SQRT 137 +#define BN_F_BN_MOD_EXP2_MONT 118 +#define BN_F_BN_MOD_EXP_MONT 109 +#define BN_F_BN_MOD_EXP_MONT_CONSTTIME 124 +#define BN_F_BN_MOD_EXP_MONT_WORD 117 +#define BN_F_BN_MOD_EXP_RECP 125 +#define BN_F_BN_MOD_EXP_SIMPLE 126 +#define BN_F_BN_MOD_INVERSE 110 +#define BN_F_BN_MOD_INVERSE_NO_BRANCH 139 +#define BN_F_BN_MOD_LSHIFT_QUICK 119 +#define BN_F_BN_MOD_MUL_RECIPROCAL 111 +#define BN_F_BN_MOD_SQRT 121 +#define BN_F_BN_MPI2BN 112 +#define BN_F_BN_NEW 113 +#define BN_F_BN_RAND 114 +#define BN_F_BN_RAND_RANGE 122 +#define BN_F_BN_USUB 115 + +/* Reason codes. */ +#define BN_R_ARG2_LT_ARG3 100 +#define BN_R_BAD_RECIPROCAL 101 +#define BN_R_BIGNUM_TOO_LONG 114 +#define BN_R_BITS_TOO_SMALL 117 +#define BN_R_CALLED_WITH_EVEN_MODULUS 102 +#define BN_R_DIV_BY_ZERO 103 +#define BN_R_ENCODING_ERROR 104 +#define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 105 +#define BN_R_INPUT_NOT_REDUCED 110 +#define BN_R_INVALID_LENGTH 106 +#define BN_R_INVALID_RANGE 115 +#define BN_R_NOT_A_SQUARE 111 +#define BN_R_NOT_INITIALIZED 107 +#define BN_R_NO_INVERSE 108 +#define BN_R_NO_SOLUTION 116 +#define BN_R_P_IS_NOT_PRIME 112 +#define BN_R_TOO_MANY_ITERATIONS 113 +#define BN_R_TOO_MANY_TEMPORARY_VARIABLES 109 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/buffer.h b/crypto/libressl/include/openssl/buffer.h new file mode 100644 index 0000000000..f36f10e6e6 --- /dev/null +++ b/crypto/libressl/include/openssl/buffer.h @@ -0,0 +1,122 @@ +/* $OpenBSD: buffer.h,v 1.14 2014/10/16 03:19:02 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BUFFER_H +#define HEADER_BUFFER_H +#if !defined(HAVE_ATTRIBUTE__BOUNDED__) && !defined(__OpenBSD__) +#define __bounded__(x, y, z) +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* Already declared in ossl_typ.h */ +/* typedef struct buf_mem_st BUF_MEM; */ + +struct buf_mem_st { + size_t length; /* current number of bytes */ + char *data; + size_t max; /* size of buffer */ +}; + +BUF_MEM *BUF_MEM_new(void); +void BUF_MEM_free(BUF_MEM *a); +int BUF_MEM_grow(BUF_MEM *str, size_t len); +int BUF_MEM_grow_clean(BUF_MEM *str, size_t len); + +#ifndef LIBRESSL_INTERNAL +char * BUF_strdup(const char *str); +char * BUF_strndup(const char *str, size_t siz); +void * BUF_memdup(const void *data, size_t siz); +void BUF_reverse(unsigned char *out, const unsigned char *in, size_t siz); + +/* safe string functions */ +size_t BUF_strlcpy(char *dst, const char *src, size_t siz) + __attribute__ ((__bounded__(__string__,1,3))); +size_t BUF_strlcat(char *dst, const char *src, size_t siz) + __attribute__ ((__bounded__(__string__,1,3))); +#endif + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_BUF_strings(void); + +/* Error codes for the BUF functions. */ + +/* Function codes. */ +#define BUF_F_BUF_MEMDUP 103 +#define BUF_F_BUF_MEM_GROW 100 +#define BUF_F_BUF_MEM_GROW_CLEAN 105 +#define BUF_F_BUF_MEM_NEW 101 +#define BUF_F_BUF_STRDUP 102 +#define BUF_F_BUF_STRNDUP 104 + +/* Reason codes. */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/camellia.h b/crypto/libressl/include/openssl/camellia.h new file mode 100644 index 0000000000..ead271bc7f --- /dev/null +++ b/crypto/libressl/include/openssl/camellia.h @@ -0,0 +1,125 @@ +/* $OpenBSD: camellia.h,v 1.4 2014/06/12 15:49:28 deraadt Exp $ */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#ifndef HEADER_CAMELLIA_H +#define HEADER_CAMELLIA_H + +#include + +#ifdef OPENSSL_NO_CAMELLIA +#error CAMELLIA is disabled. +#endif + +#include + +#define CAMELLIA_ENCRYPT 1 +#define CAMELLIA_DECRYPT 0 + +/* Because array size can't be a const in C, the following two are macros. + Both sizes are in bytes. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* This should be a hidden type, but EVP requires that the size be known */ + +#define CAMELLIA_BLOCK_SIZE 16 +#define CAMELLIA_TABLE_BYTE_LEN 272 +#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) + +typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match with WORD */ + +struct camellia_key_st { + union { + double d; /* ensures 64-bit align */ + KEY_TABLE_TYPE rd_key; + } u; + int grand_rounds; +}; +typedef struct camellia_key_st CAMELLIA_KEY; + +int Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key); + +void Camellia_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); +void Camellia_decrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); + +void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key, const int enc); +void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, const int enc); +void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num); +void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char ivec[CAMELLIA_BLOCK_SIZE], + unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], + unsigned int *num); + +#ifdef __cplusplus +} +#endif + +#endif /* !HEADER_Camellia_H */ diff --git a/crypto/libressl/include/openssl/cast.h b/crypto/libressl/include/openssl/cast.h new file mode 100644 index 0000000000..9a13a1c763 --- /dev/null +++ b/crypto/libressl/include/openssl/cast.h @@ -0,0 +1,104 @@ +/* $OpenBSD: cast.h,v 1.11 2014/06/12 15:49:28 deraadt Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CAST_H +#define HEADER_CAST_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENSSL_NO_CAST +#error CAST is disabled. +#endif + +#define CAST_ENCRYPT 1 +#define CAST_DECRYPT 0 + +#define CAST_LONG unsigned int + +#define CAST_BLOCK 8 +#define CAST_KEY_LENGTH 16 + +typedef struct cast_key_st + { + CAST_LONG data[32]; + int short_key; /* Use reduced rounds for short key */ + } CAST_KEY; + +void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); +void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, const CAST_KEY *key, + int enc); +void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key); +void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key); +void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + const CAST_KEY *ks, unsigned char *iv, int enc); +void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, unsigned char *ivec, + int *num, int enc); +void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, unsigned char *ivec, + int *num); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/libressl/include/openssl/chacha.h b/crypto/libressl/include/openssl/chacha.h new file mode 100644 index 0000000000..4812fd7da6 --- /dev/null +++ b/crypto/libressl/include/openssl/chacha.h @@ -0,0 +1,54 @@ +/* $OpenBSD: chacha.h,v 1.6 2014/07/25 14:04:51 jsing Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * 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 HEADER_CHACHA_H +#define HEADER_CHACHA_H + +#include + +#if defined(OPENSSL_NO_CHACHA) +#error ChaCha is disabled. +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + unsigned int input[16]; + unsigned char ks[64]; + unsigned char unused; +} ChaCha_ctx; + +void ChaCha_set_key(ChaCha_ctx *ctx, const unsigned char *key, + unsigned int keybits); +void ChaCha_set_iv(ChaCha_ctx *ctx, const unsigned char *iv, + const unsigned char *counter); +void ChaCha(ChaCha_ctx *ctx, unsigned char *out, const unsigned char *in, + size_t len); + +void CRYPTO_chacha_20(unsigned char *out, const unsigned char *in, size_t len, + const unsigned char key[32], const unsigned char iv[8], uint64_t counter); + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_CHACHA_H */ diff --git a/crypto/libressl/include/openssl/cmac.h b/crypto/libressl/include/openssl/cmac.h new file mode 100644 index 0000000000..c6312a935b --- /dev/null +++ b/crypto/libressl/include/openssl/cmac.h @@ -0,0 +1,82 @@ +/* $OpenBSD: cmac.h,v 1.2 2014/06/12 15:49:28 deraadt Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + + +#ifndef HEADER_CMAC_H +#define HEADER_CMAC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Opaque */ +typedef struct CMAC_CTX_st CMAC_CTX; + +CMAC_CTX *CMAC_CTX_new(void); +void CMAC_CTX_cleanup(CMAC_CTX *ctx); +void CMAC_CTX_free(CMAC_CTX *ctx); +EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx); +int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in); + +int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, + const EVP_CIPHER *cipher, ENGINE *impl); +int CMAC_Update(CMAC_CTX *ctx, const void *data, size_t dlen); +int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen); +int CMAC_resume(CMAC_CTX *ctx); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/cms.h b/crypto/libressl/include/openssl/cms.h new file mode 100644 index 0000000000..3fc801dec4 --- /dev/null +++ b/crypto/libressl/include/openssl/cms.h @@ -0,0 +1,473 @@ +/* $OpenBSD: cms.h,v 1.6 2015/02/11 03:55:42 beck Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_CMS_H +#define HEADER_CMS_H + +#include + +#include + +#ifdef OPENSSL_NO_CMS +#error CMS is disabled. +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct CMS_ContentInfo_st CMS_ContentInfo; +typedef struct CMS_SignerInfo_st CMS_SignerInfo; +typedef struct CMS_CertificateChoices CMS_CertificateChoices; +typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice; +typedef struct CMS_RecipientInfo_st CMS_RecipientInfo; +typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest; +typedef struct CMS_Receipt_st CMS_Receipt; + +DECLARE_STACK_OF(CMS_SignerInfo) +DECLARE_STACK_OF(GENERAL_NAMES) +DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) +DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest) +DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo) + +#define CMS_SIGNERINFO_ISSUER_SERIAL 0 +#define CMS_SIGNERINFO_KEYIDENTIFIER 1 + +#define CMS_RECIPINFO_TRANS 0 +#define CMS_RECIPINFO_AGREE 1 +#define CMS_RECIPINFO_KEK 2 +#define CMS_RECIPINFO_PASS 3 +#define CMS_RECIPINFO_OTHER 4 + +/* S/MIME related flags */ + +#define CMS_TEXT 0x1 +#define CMS_NOCERTS 0x2 +#define CMS_NO_CONTENT_VERIFY 0x4 +#define CMS_NO_ATTR_VERIFY 0x8 +#define CMS_NOSIGS \ + (CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY) +#define CMS_NOINTERN 0x10 +#define CMS_NO_SIGNER_CERT_VERIFY 0x20 +#define CMS_NOVERIFY 0x20 +#define CMS_DETACHED 0x40 +#define CMS_BINARY 0x80 +#define CMS_NOATTR 0x100 +#define CMS_NOSMIMECAP 0x200 +#define CMS_NOOLDMIMETYPE 0x400 +#define CMS_CRLFEOL 0x800 +#define CMS_STREAM 0x1000 +#define CMS_NOCRL 0x2000 +#define CMS_PARTIAL 0x4000 +#define CMS_REUSE_DIGEST 0x8000 +#define CMS_USE_KEYID 0x10000 +#define CMS_DEBUG_DECRYPT 0x20000 + +const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms); + +BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont); +int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio); + +ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms); +int CMS_is_detached(CMS_ContentInfo *cms); +int CMS_set_detached(CMS_ContentInfo *cms, int detached); + +#ifdef HEADER_PEM_H +DECLARE_PEM_rw_const(CMS, CMS_ContentInfo) +#endif + +int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms); +CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms); +int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms); + +BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms); +int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags); +int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, + int flags); +CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont); +int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags); + +int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags); + +CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, BIO *data, unsigned int flags); + +CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, X509 *signcert, + EVP_PKEY *pkey, STACK_OF(X509) *certs, unsigned int flags); + +int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags); +CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags); + +int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags); +CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, + unsigned int flags); + +int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, const unsigned char *key, + size_t keylen, BIO *dcont, BIO *out, unsigned int flags); + +CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, + const unsigned char *key, size_t keylen, unsigned int flags); + +int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, + const unsigned char *key, size_t keylen); + +int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, + X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags); + +int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, + STACK_OF(X509) *certs, X509_STORE *store, unsigned int flags); + +STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms); + +CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in, + const EVP_CIPHER *cipher, unsigned int flags); + +int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, BIO *dcont, + BIO *out, unsigned int flags); + +int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert); +int CMS_decrypt_set1_key(CMS_ContentInfo *cms, unsigned char *key, + size_t keylen, unsigned char *id, size_t idlen); +int CMS_decrypt_set1_password(CMS_ContentInfo *cms, unsigned char *pass, + ssize_t passlen); + +STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms); +int CMS_RecipientInfo_type(CMS_RecipientInfo *ri); +CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher); +CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip, + unsigned int flags); +int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey); +int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert); +int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, EVP_PKEY **pk, + X509 **recip, X509_ALGOR **palg); +int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, + ASN1_OCTET_STRING **keyid, X509_NAME **issuer, ASN1_INTEGER **sno); + +CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, + unsigned char *key, size_t keylen, unsigned char *id, size_t idlen, + ASN1_GENERALIZEDTIME *date, ASN1_OBJECT *otherTypeId, + ASN1_TYPE *otherType); + +int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, X509_ALGOR **palg, + ASN1_OCTET_STRING **pid, ASN1_GENERALIZEDTIME **pdate, + ASN1_OBJECT **potherid, ASN1_TYPE **pothertype); + +int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, unsigned char *key, + size_t keylen); + +int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, + const unsigned char *id, size_t idlen); + +int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, unsigned char *pass, + ssize_t passlen); + +CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, int iter, + int wrap_nid, int pbe_nid, unsigned char *pass, ssize_t passlen, + const EVP_CIPHER *kekciph); + +int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); + +int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags); +CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags); + +int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid); +const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms); + +CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms); +int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert); +int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert); +STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms); + +CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms); +int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl); +int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl); +STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms); + +int CMS_SignedData_init(CMS_ContentInfo *cms); +CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, X509 *signer, + EVP_PKEY *pk, const EVP_MD *md, unsigned int flags); +STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms); + +void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer); +int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, + ASN1_OCTET_STRING **keyid, X509_NAME **issuer, ASN1_INTEGER **sno); +int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert); +int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs, + unsigned int flags); +void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer, + X509_ALGOR **pdig, X509_ALGOR **psig); +int CMS_SignerInfo_sign(CMS_SignerInfo *si); +int CMS_SignerInfo_verify(CMS_SignerInfo *si); +int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain); + +int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs); +int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, int algnid, + int keysize); +int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap); + +int CMS_signed_get_attr_count(const CMS_SignerInfo *si); +int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid, int lastpos); +int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc); +X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc); +int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); +int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si, const ASN1_OBJECT *obj, + int type, const void *bytes, int len); +int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si, int nid, int type, + const void *bytes, int len); +int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si, const char *attrname, + int type, const void *bytes, int len); +void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, + int lastpos, int type); + +int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si); +int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid, + int lastpos); +int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc); +X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc); +int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); +int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si, const ASN1_OBJECT *obj, + int type, const void *bytes, int len); +int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si, int nid, int type, + const void *bytes, int len); +int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si, const char *attrname, + int type, const void *bytes, int len); +void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, + int lastpos, int type); + +#ifdef HEADER_X509V3_H + +int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr); +CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, + int allorfirst, STACK_OF(GENERAL_NAMES) *receiptList, + STACK_OF(GENERAL_NAMES) *receiptsTo); +int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr); +void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, ASN1_STRING **pcid, + int *pallorfirst, STACK_OF(GENERAL_NAMES) **plist, + STACK_OF(GENERAL_NAMES) **prto); + +#endif + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_CMS_strings(void); + +/* Error codes for the CMS functions. */ + +/* Function codes. */ +#define CMS_F_CHECK_CONTENT 99 +#define CMS_F_CMS_ADD0_CERT 164 +#define CMS_F_CMS_ADD0_RECIPIENT_KEY 100 +#define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD 165 +#define CMS_F_CMS_ADD1_RECEIPTREQUEST 158 +#define CMS_F_CMS_ADD1_RECIPIENT_CERT 101 +#define CMS_F_CMS_ADD1_SIGNER 102 +#define CMS_F_CMS_ADD1_SIGNINGTIME 103 +#define CMS_F_CMS_COMPRESS 104 +#define CMS_F_CMS_COMPRESSEDDATA_CREATE 105 +#define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO 106 +#define CMS_F_CMS_COPY_CONTENT 107 +#define CMS_F_CMS_COPY_MESSAGEDIGEST 108 +#define CMS_F_CMS_DATA 109 +#define CMS_F_CMS_DATAFINAL 110 +#define CMS_F_CMS_DATAINIT 111 +#define CMS_F_CMS_DECRYPT 112 +#define CMS_F_CMS_DECRYPT_SET1_KEY 113 +#define CMS_F_CMS_DECRYPT_SET1_PASSWORD 166 +#define CMS_F_CMS_DECRYPT_SET1_PKEY 114 +#define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX 115 +#define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO 116 +#define CMS_F_CMS_DIGESTEDDATA_DO_FINAL 117 +#define CMS_F_CMS_DIGEST_VERIFY 118 +#define CMS_F_CMS_ENCODE_RECEIPT 161 +#define CMS_F_CMS_ENCRYPT 119 +#define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO 120 +#define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT 121 +#define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT 122 +#define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY 123 +#define CMS_F_CMS_ENVELOPEDDATA_CREATE 124 +#define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO 125 +#define CMS_F_CMS_ENVELOPED_DATA_INIT 126 +#define CMS_F_CMS_FINAL 127 +#define CMS_F_CMS_GET0_CERTIFICATE_CHOICES 128 +#define CMS_F_CMS_GET0_CONTENT 129 +#define CMS_F_CMS_GET0_ECONTENT_TYPE 130 +#define CMS_F_CMS_GET0_ENVELOPED 131 +#define CMS_F_CMS_GET0_REVOCATION_CHOICES 132 +#define CMS_F_CMS_GET0_SIGNED 133 +#define CMS_F_CMS_MSGSIGDIGEST_ADD1 162 +#define CMS_F_CMS_RECEIPTREQUEST_CREATE0 159 +#define CMS_F_CMS_RECEIPT_VERIFY 160 +#define CMS_F_CMS_RECIPIENTINFO_DECRYPT 134 +#define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT 135 +#define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT 136 +#define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID 137 +#define CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP 138 +#define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP 139 +#define CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT 140 +#define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT 141 +#define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS 142 +#define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID 143 +#define CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT 167 +#define CMS_F_CMS_RECIPIENTINFO_SET0_KEY 144 +#define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD 168 +#define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY 145 +#define CMS_F_CMS_SET1_SIGNERIDENTIFIER 146 +#define CMS_F_CMS_SET_DETACHED 147 +#define CMS_F_CMS_SIGN 148 +#define CMS_F_CMS_SIGNED_DATA_INIT 149 +#define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN 150 +#define CMS_F_CMS_SIGNERINFO_SIGN 151 +#define CMS_F_CMS_SIGNERINFO_VERIFY 152 +#define CMS_F_CMS_SIGNERINFO_VERIFY_CERT 153 +#define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT 154 +#define CMS_F_CMS_SIGN_RECEIPT 163 +#define CMS_F_CMS_STREAM 155 +#define CMS_F_CMS_UNCOMPRESS 156 +#define CMS_F_CMS_VERIFY 157 + +/* Reason codes. */ +#define CMS_R_ADD_SIGNER_ERROR 99 +#define CMS_R_CERTIFICATE_ALREADY_PRESENT 175 +#define CMS_R_CERTIFICATE_HAS_NO_KEYID 160 +#define CMS_R_CERTIFICATE_VERIFY_ERROR 100 +#define CMS_R_CIPHER_INITIALISATION_ERROR 101 +#define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR 102 +#define CMS_R_CMS_DATAFINAL_ERROR 103 +#define CMS_R_CMS_LIB 104 +#define CMS_R_CONTENTIDENTIFIER_MISMATCH 170 +#define CMS_R_CONTENT_NOT_FOUND 105 +#define CMS_R_CONTENT_TYPE_MISMATCH 171 +#define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA 106 +#define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA 107 +#define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA 108 +#define CMS_R_CONTENT_VERIFY_ERROR 109 +#define CMS_R_CTRL_ERROR 110 +#define CMS_R_CTRL_FAILURE 111 +#define CMS_R_DECRYPT_ERROR 112 +#define CMS_R_DIGEST_ERROR 161 +#define CMS_R_ERROR_GETTING_PUBLIC_KEY 113 +#define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 114 +#define CMS_R_ERROR_SETTING_KEY 115 +#define CMS_R_ERROR_SETTING_RECIPIENTINFO 116 +#define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH 117 +#define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER 176 +#define CMS_R_INVALID_KEY_LENGTH 118 +#define CMS_R_MD_BIO_INIT_ERROR 119 +#define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH 120 +#define CMS_R_MESSAGEDIGEST_WRONG_LENGTH 121 +#define CMS_R_MSGSIGDIGEST_ERROR 172 +#define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE 162 +#define CMS_R_MSGSIGDIGEST_WRONG_LENGTH 163 +#define CMS_R_NEED_ONE_SIGNER 164 +#define CMS_R_NOT_A_SIGNED_RECEIPT 165 +#define CMS_R_NOT_ENCRYPTED_DATA 122 +#define CMS_R_NOT_KEK 123 +#define CMS_R_NOT_KEY_TRANSPORT 124 +#define CMS_R_NOT_PWRI 177 +#define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 125 +#define CMS_R_NO_CIPHER 126 +#define CMS_R_NO_CONTENT 127 +#define CMS_R_NO_CONTENT_TYPE 173 +#define CMS_R_NO_DEFAULT_DIGEST 128 +#define CMS_R_NO_DIGEST_SET 129 +#define CMS_R_NO_KEY 130 +#define CMS_R_NO_KEY_OR_CERT 174 +#define CMS_R_NO_MATCHING_DIGEST 131 +#define CMS_R_NO_MATCHING_RECIPIENT 132 +#define CMS_R_NO_MATCHING_SIGNATURE 166 +#define CMS_R_NO_MSGSIGDIGEST 167 +#define CMS_R_NO_PASSWORD 178 +#define CMS_R_NO_PRIVATE_KEY 133 +#define CMS_R_NO_PUBLIC_KEY 134 +#define CMS_R_NO_RECEIPT_REQUEST 168 +#define CMS_R_NO_SIGNERS 135 +#define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 136 +#define CMS_R_RECEIPT_DECODE_ERROR 169 +#define CMS_R_RECIPIENT_ERROR 137 +#define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND 138 +#define CMS_R_SIGNFINAL_ERROR 139 +#define CMS_R_SMIME_TEXT_ERROR 140 +#define CMS_R_STORE_INIT_ERROR 141 +#define CMS_R_TYPE_NOT_COMPRESSED_DATA 142 +#define CMS_R_TYPE_NOT_DATA 143 +#define CMS_R_TYPE_NOT_DIGESTED_DATA 144 +#define CMS_R_TYPE_NOT_ENCRYPTED_DATA 145 +#define CMS_R_TYPE_NOT_ENVELOPED_DATA 146 +#define CMS_R_UNABLE_TO_FINALIZE_CONTEXT 147 +#define CMS_R_UNKNOWN_CIPHER 148 +#define CMS_R_UNKNOWN_DIGEST_ALGORIHM 149 +#define CMS_R_UNKNOWN_ID 150 +#define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM 151 +#define CMS_R_UNSUPPORTED_CONTENT_TYPE 152 +#define CMS_R_UNSUPPORTED_KEK_ALGORITHM 153 +#define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM 179 +#define CMS_R_UNSUPPORTED_RECIPIENT_TYPE 154 +#define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE 155 +#define CMS_R_UNSUPPORTED_TYPE 156 +#define CMS_R_UNWRAP_ERROR 157 +#define CMS_R_UNWRAP_FAILURE 180 +#define CMS_R_VERIFICATION_FAILURE 158 +#define CMS_R_WRAP_ERROR 159 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/comp.h b/crypto/libressl/include/openssl/comp.h new file mode 100644 index 0000000000..9b4dc0fc27 --- /dev/null +++ b/crypto/libressl/include/openssl/comp.h @@ -0,0 +1,73 @@ +/* $OpenBSD: comp.h,v 1.7 2014/06/12 15:49:28 deraadt Exp $ */ + +#ifndef HEADER_COMP_H +#define HEADER_COMP_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct comp_ctx_st COMP_CTX; + +typedef struct comp_method_st { + int type; /* NID for compression library */ + const char *name; /* A text string to identify the library */ + int (*init)(COMP_CTX *ctx); + void (*finish)(COMP_CTX *ctx); + int (*compress)(COMP_CTX *ctx, unsigned char *out, unsigned int olen, + unsigned char *in, unsigned int ilen); + int (*expand)(COMP_CTX *ctx, unsigned char *out, unsigned int olen, + unsigned char *in, unsigned int ilen); + /* The following two do NOTHING, but are kept for backward compatibility */ + long (*ctrl)(void); + long (*callback_ctrl)(void); +} COMP_METHOD; + +struct comp_ctx_st { + COMP_METHOD *meth; + unsigned long compress_in; + unsigned long compress_out; + unsigned long expand_in; + unsigned long expand_out; + + CRYPTO_EX_DATA ex_data; +}; + + +COMP_CTX *COMP_CTX_new(COMP_METHOD *meth); +void COMP_CTX_free(COMP_CTX *ctx); +int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen, + unsigned char *in, int ilen); +int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen, + unsigned char *in, int ilen); +COMP_METHOD *COMP_rle(void ); +COMP_METHOD *COMP_zlib(void ); +void COMP_zlib_cleanup(void); + +#ifdef HEADER_BIO_H +#ifdef ZLIB +BIO_METHOD *BIO_f_zlib(void); +#endif +#endif + +void ERR_load_COMP_strings(void); + +/* Error codes for the COMP functions. */ + +/* Function codes. */ +#define COMP_F_BIO_ZLIB_FLUSH 99 +#define COMP_F_BIO_ZLIB_NEW 100 +#define COMP_F_BIO_ZLIB_READ 101 +#define COMP_F_BIO_ZLIB_WRITE 102 + +/* Reason codes. */ +#define COMP_R_ZLIB_DEFLATE_ERROR 99 +#define COMP_R_ZLIB_INFLATE_ERROR 100 +#define COMP_R_ZLIB_NOT_SUPPORTED 101 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/conf.h b/crypto/libressl/include/openssl/conf.h new file mode 100644 index 0000000000..a3ddff6364 --- /dev/null +++ b/crypto/libressl/include/openssl/conf.h @@ -0,0 +1,249 @@ +/* $OpenBSD: conf.h,v 1.13 2014/06/12 15:49:28 deraadt Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CONF_H +#define HEADER_CONF_H + +#include + +#include +#include +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + char *section; + char *name; + char *value; +} CONF_VALUE; + +DECLARE_STACK_OF(CONF_VALUE) +DECLARE_LHASH_OF(CONF_VALUE); + +struct conf_st; +struct conf_method_st; +typedef struct conf_method_st CONF_METHOD; + +struct conf_method_st { + const char *name; + CONF *(*create)(CONF_METHOD *meth); + int (*init)(CONF *conf); + int (*destroy)(CONF *conf); + int (*destroy_data)(CONF *conf); + int (*load_bio)(CONF *conf, BIO *bp, long *eline); + int (*dump)(const CONF *conf, BIO *bp); + int (*is_number)(const CONF *conf, char c); + int (*to_int)(const CONF *conf, char c); + int (*load)(CONF *conf, const char *name, long *eline); +}; + +/* Module definitions */ + +typedef struct conf_imodule_st CONF_IMODULE; +typedef struct conf_module_st CONF_MODULE; + +DECLARE_STACK_OF(CONF_MODULE) +DECLARE_STACK_OF(CONF_IMODULE) + +/* DSO module function typedefs */ +typedef int conf_init_func(CONF_IMODULE *md, const CONF *cnf); +typedef void conf_finish_func(CONF_IMODULE *md); + +#define CONF_MFLAGS_IGNORE_ERRORS 0x1 +#define CONF_MFLAGS_IGNORE_RETURN_CODES 0x2 +#define CONF_MFLAGS_SILENT 0x4 +#define CONF_MFLAGS_NO_DSO 0x8 +#define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10 +#define CONF_MFLAGS_DEFAULT_SECTION 0x20 + +int CONF_set_default_method(CONF_METHOD *meth); +void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash); +LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, + long *eline); +LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, + long *eline); +LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp, long *eline); +STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, + const char *section); +char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name); +long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name); +void CONF_free(LHASH_OF(CONF_VALUE) *conf); +int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out); +int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out); + +void OPENSSL_config(const char *config_name); +void OPENSSL_no_config(void); + +/* New conf code. The semantics are different from the functions above. + If that wasn't the case, the above functions would have been replaced */ + +struct conf_st { + CONF_METHOD *meth; + void *meth_data; + LHASH_OF(CONF_VALUE) *data; +}; + +CONF *NCONF_new(CONF_METHOD *meth); +CONF_METHOD *NCONF_default(void); +CONF_METHOD *NCONF_WIN32(void); +void NCONF_free(CONF *conf); +void NCONF_free_data(CONF *conf); + +int NCONF_load(CONF *conf, const char *file, long *eline); +int NCONF_load_fp(CONF *conf, FILE *fp, long *eline); +int NCONF_load_bio(CONF *conf, BIO *bp, long *eline); +STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section); +char *NCONF_get_string(const CONF *conf, const char *group, const char *name); +int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, + long *result); +int NCONF_dump_fp(const CONF *conf, FILE *out); +int NCONF_dump_bio(const CONF *conf, BIO *out); + +#define NCONF_get_number(c,g,n,r) NCONF_get_number_e(c,g,n,r) + +/* Module functions */ + +int CONF_modules_load(const CONF *cnf, const char *appname, + unsigned long flags); +int CONF_modules_load_file(const char *filename, const char *appname, + unsigned long flags); +void CONF_modules_unload(int all); +void CONF_modules_finish(void); +void CONF_modules_free(void); +int CONF_module_add(const char *name, conf_init_func *ifunc, + conf_finish_func *ffunc); + +const char *CONF_imodule_get_name(const CONF_IMODULE *md); +const char *CONF_imodule_get_value(const CONF_IMODULE *md); +void *CONF_imodule_get_usr_data(const CONF_IMODULE *md); +void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data); +CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md); +unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md); +void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags); +void *CONF_module_get_usr_data(CONF_MODULE *pmod); +void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data); + +char *CONF_get1_default_config_file(void); + +int CONF_parse_list(const char *list, int sep, int nospc, + int (*list_cb)(const char *elem, int len, void *usr), void *arg); + +void OPENSSL_load_builtin_modules(void); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_CONF_strings(void); + +/* Error codes for the CONF functions. */ + +/* Function codes. */ +#define CONF_F_CONF_DUMP_FP 104 +#define CONF_F_CONF_LOAD 100 +#define CONF_F_CONF_LOAD_BIO 102 +#define CONF_F_CONF_LOAD_FP 103 +#define CONF_F_CONF_MODULES_LOAD 116 +#define CONF_F_CONF_PARSE_LIST 119 +#define CONF_F_DEF_LOAD 120 +#define CONF_F_DEF_LOAD_BIO 121 +#define CONF_F_MODULE_INIT 115 +#define CONF_F_MODULE_LOAD_DSO 117 +#define CONF_F_MODULE_RUN 118 +#define CONF_F_NCONF_DUMP_BIO 105 +#define CONF_F_NCONF_DUMP_FP 106 +#define CONF_F_NCONF_GET_NUMBER 107 +#define CONF_F_NCONF_GET_NUMBER_E 112 +#define CONF_F_NCONF_GET_SECTION 108 +#define CONF_F_NCONF_GET_STRING 109 +#define CONF_F_NCONF_LOAD 113 +#define CONF_F_NCONF_LOAD_BIO 110 +#define CONF_F_NCONF_LOAD_FP 114 +#define CONF_F_NCONF_NEW 111 +#define CONF_F_STR_COPY 101 + +/* Reason codes. */ +#define CONF_R_ERROR_LOADING_DSO 110 +#define CONF_R_LIST_CANNOT_BE_NULL 115 +#define CONF_R_MISSING_CLOSE_SQUARE_BRACKET 100 +#define CONF_R_MISSING_EQUAL_SIGN 101 +#define CONF_R_MISSING_FINISH_FUNCTION 111 +#define CONF_R_MISSING_INIT_FUNCTION 112 +#define CONF_R_MODULE_INITIALIZATION_ERROR 109 +#define CONF_R_NO_CLOSE_BRACE 102 +#define CONF_R_NO_CONF 105 +#define CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE 106 +#define CONF_R_NO_SECTION 107 +#define CONF_R_NO_SUCH_FILE 114 +#define CONF_R_NO_VALUE 108 +#define CONF_R_UNABLE_TO_CREATE_NEW_SECTION 103 +#define CONF_R_UNKNOWN_MODULE_NAME 113 +#define CONF_R_VARIABLE_HAS_NO_VALUE 104 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/conf_api.h b/crypto/libressl/include/openssl/conf_api.h new file mode 100644 index 0000000000..d6fc838def --- /dev/null +++ b/crypto/libressl/include/openssl/conf_api.h @@ -0,0 +1,88 @@ +/* $OpenBSD$ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CONF_API_H +#define HEADER_CONF_API_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Up until OpenSSL 0.9.5a, this was new_section */ +CONF_VALUE *_CONF_new_section(CONF *conf, const char *section); +/* Up until OpenSSL 0.9.5a, this was get_section */ +CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section); +/* Up until OpenSSL 0.9.5a, this was CONF_get_section */ +STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf, + const char *section); + +int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value); +char *_CONF_get_string(const CONF *conf, const char *section, + const char *name); +long _CONF_get_number(const CONF *conf, const char *section, const char *name); + +int _CONF_new_data(CONF *conf); +void _CONF_free_data(CONF *conf); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/crypto.h b/crypto/libressl/include/openssl/crypto.h new file mode 100644 index 0000000000..a039a6b76f --- /dev/null +++ b/crypto/libressl/include/openssl/crypto.h @@ -0,0 +1,540 @@ +/* $OpenBSD: crypto.h,v 1.39 2015/09/13 16:56:11 miod Exp $ */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include +#include +#include + +#ifndef HEADER_CRYPTO_H +#define HEADER_CRYPTO_H + +#include + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Backward compatibility to SSLeay */ +/* This is more to be used to check the correct DLL is being used + * in the MS world. */ +#define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER +#define SSLEAY_VERSION 0 +/* #define SSLEAY_OPTIONS 1 no longer supported */ +#define SSLEAY_CFLAGS 2 +#define SSLEAY_BUILT_ON 3 +#define SSLEAY_PLATFORM 4 +#define SSLEAY_DIR 5 + +/* A generic structure to pass assorted data in a expandable way */ +typedef struct openssl_item_st { + int code; + void *value; /* Not used for flag attributes */ + size_t value_size; /* Max size of value for output, length for input */ + size_t *value_length; /* Returned length of value for output */ +} OPENSSL_ITEM; + + +/* When changing the CRYPTO_LOCK_* list, be sure to maintain the text lock + * names in cryptlib.c + */ + +#define CRYPTO_LOCK_ERR 1 +#define CRYPTO_LOCK_EX_DATA 2 +#define CRYPTO_LOCK_X509 3 +#define CRYPTO_LOCK_X509_INFO 4 +#define CRYPTO_LOCK_X509_PKEY 5 +#define CRYPTO_LOCK_X509_CRL 6 +#define CRYPTO_LOCK_X509_REQ 7 +#define CRYPTO_LOCK_DSA 8 +#define CRYPTO_LOCK_RSA 9 +#define CRYPTO_LOCK_EVP_PKEY 10 +#define CRYPTO_LOCK_X509_STORE 11 +#define CRYPTO_LOCK_SSL_CTX 12 +#define CRYPTO_LOCK_SSL_CERT 13 +#define CRYPTO_LOCK_SSL_SESSION 14 +#define CRYPTO_LOCK_SSL_SESS_CERT 15 +#define CRYPTO_LOCK_SSL 16 +#define CRYPTO_LOCK_SSL_METHOD 17 +#define CRYPTO_LOCK_RAND 18 +#define CRYPTO_LOCK_RAND2 19 +#define CRYPTO_LOCK_MALLOC 20 +#define CRYPTO_LOCK_BIO 21 +#define CRYPTO_LOCK_GETHOSTBYNAME 22 +#define CRYPTO_LOCK_GETSERVBYNAME 23 +#define CRYPTO_LOCK_READDIR 24 +#define CRYPTO_LOCK_RSA_BLINDING 25 +#define CRYPTO_LOCK_DH 26 +#define CRYPTO_LOCK_MALLOC2 27 +#define CRYPTO_LOCK_DSO 28 +#define CRYPTO_LOCK_DYNLOCK 29 +#define CRYPTO_LOCK_ENGINE 30 +#define CRYPTO_LOCK_UI 31 +#define CRYPTO_LOCK_ECDSA 32 +#define CRYPTO_LOCK_EC 33 +#define CRYPTO_LOCK_ECDH 34 +#define CRYPTO_LOCK_BN 35 +#define CRYPTO_LOCK_EC_PRE_COMP 36 +#define CRYPTO_LOCK_STORE 37 +#define CRYPTO_LOCK_COMP 38 +#define CRYPTO_LOCK_FIPS 39 +#define CRYPTO_LOCK_FIPS2 40 +#define CRYPTO_NUM_LOCKS 41 + +#define CRYPTO_LOCK 1 +#define CRYPTO_UNLOCK 2 +#define CRYPTO_READ 4 +#define CRYPTO_WRITE 8 + +#ifndef OPENSSL_NO_LOCKING +#ifndef CRYPTO_w_lock +#define CRYPTO_w_lock(type) \ + CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) +#define CRYPTO_w_unlock(type) \ + CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) +#define CRYPTO_r_lock(type) \ + CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__) +#define CRYPTO_r_unlock(type) \ + CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__) +#define CRYPTO_add(addr,amount,type) \ + CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__) +#endif +#else +#define CRYPTO_w_lock(a) +#define CRYPTO_w_unlock(a) +#define CRYPTO_r_lock(a) +#define CRYPTO_r_unlock(a) +#define CRYPTO_add(a,b,c) ((*(a))+=(b)) +#endif + +/* Some applications as well as some parts of OpenSSL need to allocate + and deallocate locks in a dynamic fashion. The following typedef + makes this possible in a type-safe manner. */ +/* struct CRYPTO_dynlock_value has to be defined by the application. */ +typedef struct { + int references; + struct CRYPTO_dynlock_value *data; +} CRYPTO_dynlock; + + +/* The following can be used to detect memory leaks in the SSLeay library. + * It used, it turns on malloc checking */ + +#define CRYPTO_MEM_CHECK_OFF 0x0 /* an enume */ +#define CRYPTO_MEM_CHECK_ON 0x1 /* a bit */ +#define CRYPTO_MEM_CHECK_ENABLE 0x2 /* a bit */ +#define CRYPTO_MEM_CHECK_DISABLE 0x3 /* an enume */ + +/* The following are bit values to turn on or off options connected to the + * malloc checking functionality */ + +/* Adds time to the memory checking information */ +#define V_CRYPTO_MDEBUG_TIME 0x1 /* a bit */ +/* Adds thread number to the memory checking information */ +#define V_CRYPTO_MDEBUG_THREAD 0x2 /* a bit */ + +#define V_CRYPTO_MDEBUG_ALL (V_CRYPTO_MDEBUG_TIME | V_CRYPTO_MDEBUG_THREAD) + + +/* predec of the BIO type */ +typedef struct bio_st BIO_dummy; + +struct crypto_ex_data_st { + STACK_OF(void) *sk; +}; +DECLARE_STACK_OF(void) + +/* This stuff is basically class callback functions + * The current classes are SSL_CTX, SSL, SSL_SESSION, and a few more */ + +typedef struct crypto_ex_data_func_st { + long argl; /* Arbitary long */ + void *argp; /* Arbitary void * */ + CRYPTO_EX_new *new_func; + CRYPTO_EX_free *free_func; + CRYPTO_EX_dup *dup_func; +} CRYPTO_EX_DATA_FUNCS; + +DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS) + +/* Per class, we have a STACK of CRYPTO_EX_DATA_FUNCS for each CRYPTO_EX_DATA + * entry. + */ + +#define CRYPTO_EX_INDEX_BIO 0 +#define CRYPTO_EX_INDEX_SSL 1 +#define CRYPTO_EX_INDEX_SSL_CTX 2 +#define CRYPTO_EX_INDEX_SSL_SESSION 3 +#define CRYPTO_EX_INDEX_X509_STORE 4 +#define CRYPTO_EX_INDEX_X509_STORE_CTX 5 +#define CRYPTO_EX_INDEX_RSA 6 +#define CRYPTO_EX_INDEX_DSA 7 +#define CRYPTO_EX_INDEX_DH 8 +#define CRYPTO_EX_INDEX_ENGINE 9 +#define CRYPTO_EX_INDEX_X509 10 +#define CRYPTO_EX_INDEX_UI 11 +#define CRYPTO_EX_INDEX_ECDSA 12 +#define CRYPTO_EX_INDEX_ECDH 13 +#define CRYPTO_EX_INDEX_COMP 14 +#define CRYPTO_EX_INDEX_STORE 15 + +/* Dynamically assigned indexes start from this value (don't use directly, use + * via CRYPTO_ex_data_new_class). */ +#define CRYPTO_EX_INDEX_USER 100 + +#define CRYPTO_malloc_init() (0) +#define CRYPTO_malloc_debug_init() (0) + +#if defined CRYPTO_MDEBUG_ALL || defined CRYPTO_MDEBUG_TIME || defined CRYPTO_MDEBUG_THREAD +# ifndef CRYPTO_MDEBUG /* avoid duplicate #define */ +# define CRYPTO_MDEBUG +# endif +#endif + +int CRYPTO_mem_ctrl(int mode); +int CRYPTO_is_mem_check_on(void); + +/* for applications */ +#define MemCheck_start() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) +#define MemCheck_stop() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF) + +#define OPENSSL_malloc(num) CRYPTO_malloc((int)num,__FILE__,__LINE__) +#define OPENSSL_strdup(str) CRYPTO_strdup((str),__FILE__,__LINE__) +#define OPENSSL_realloc(addr,num) \ + CRYPTO_realloc((char *)addr,(int)num,__FILE__,__LINE__) +#define OPENSSL_realloc_clean(addr,old_num,num) \ + CRYPTO_realloc_clean(addr,old_num,num,__FILE__,__LINE__) +#define OPENSSL_remalloc(addr,num) \ + CRYPTO_remalloc((char **)addr,(int)num,__FILE__,__LINE__) +#define OPENSSL_freeFunc CRYPTO_free +#define OPENSSL_free(addr) CRYPTO_free(addr) + +#define OPENSSL_malloc_locked(num) \ + CRYPTO_malloc_locked((int)num,__FILE__,__LINE__) +#define OPENSSL_free_locked(addr) CRYPTO_free_locked(addr) + + +const char *SSLeay_version(int type); +unsigned long SSLeay(void); + +/* An opaque type representing an implementation of "ex_data" support */ +typedef struct st_CRYPTO_EX_DATA_IMPL CRYPTO_EX_DATA_IMPL; +/* Return an opaque pointer to the current "ex_data" implementation */ +const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void); +/* Sets the "ex_data" implementation to be used (if it's not too late) */ +int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i); +/* Get a new "ex_data" class, and return the corresponding "class_index" */ +int CRYPTO_ex_data_new_class(void); +/* Within a given class, get/register a new index */ +int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +/* Initialise/duplicate/free CRYPTO_EX_DATA variables corresponding to a given + * class (invokes whatever per-class callbacks are applicable) */ +int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, + CRYPTO_EX_DATA *from); +void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +/* Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular index + * (relative to the class type involved) */ +int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val); +void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx); +/* This function cleans up all "ex_data" state. It mustn't be called under + * potential race-conditions. */ +void CRYPTO_cleanup_all_ex_data(void); + +int CRYPTO_get_new_lockid(char *name); + +int CRYPTO_num_locks(void); /* return CRYPTO_NUM_LOCKS (shared libs!) */ +void CRYPTO_lock(int mode, int type, const char *file, int line); +void CRYPTO_set_locking_callback(void (*func)(int mode, int type, + const char *file, int line)); +void (*CRYPTO_get_locking_callback(void))(int mode, int type, + const char *file, int line); +void CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int type, + const char *file, int line)); +int (*CRYPTO_get_add_lock_callback(void))(int *num, int mount, int type, + const char *file, int line); + +/* Don't use this structure directly. */ +typedef struct crypto_threadid_st { + void *ptr; + unsigned long val; +} CRYPTO_THREADID; +/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */ +void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val); +void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr); +int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *)); +void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *); +void CRYPTO_THREADID_current(CRYPTO_THREADID *id); +int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b); +void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src); +unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id); +#ifndef OPENSSL_NO_DEPRECATED +void CRYPTO_set_id_callback(unsigned long (*func)(void)); +unsigned long (*CRYPTO_get_id_callback(void))(void); +unsigned long CRYPTO_thread_id(void); +#endif + +const char *CRYPTO_get_lock_name(int type); +int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, + int line); + +int CRYPTO_get_new_dynlockid(void); +void CRYPTO_destroy_dynlockid(int i); +struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i); +void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*dyn_create_function)(const char *file, int line)); +void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)); +void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function)(struct CRYPTO_dynlock_value *l, const char *file, int line)); +struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))(const char *file, int line); +void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line); +void (*CRYPTO_get_dynlock_destroy_callback(void))(struct CRYPTO_dynlock_value *l, const char *file, int line); + +/* CRYPTO_set_mem_functions includes CRYPTO_set_locked_mem_functions -- + * call the latter last if you need different functions */ +int CRYPTO_set_mem_functions(void *(*m)(size_t), void *(*r)(void *, size_t), void (*f)(void *)); +int CRYPTO_set_locked_mem_functions(void *(*m)(size_t), void (*free_func)(void *)); +int CRYPTO_set_mem_ex_functions(void *(*m)(size_t, const char *, int), + void *(*r)(void *, size_t, const char *, int), void (*f)(void *)); +int CRYPTO_set_locked_mem_ex_functions(void *(*m)(size_t, const char *, int), + void (*free_func)(void *)); +int CRYPTO_set_mem_debug_functions( + void (*m)(void *, int, const char *, int, int), + void (*r)(void *, void *, int, const char *, int, int), + void (*f)(void *, int), void (*so)(long), long (*go)(void)); +void CRYPTO_get_mem_functions(void *(**m)(size_t), void *(**r)(void *, size_t), + void (**f)(void *)); +void CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *)); +void CRYPTO_get_mem_ex_functions(void *(**m)(size_t, const char *, int), + void *(**r)(void *, size_t, const char *, int), void (**f)(void *)); +void CRYPTO_get_locked_mem_ex_functions(void *(**m)(size_t, const char *, int), + void (**f)(void *)); +void CRYPTO_get_mem_debug_functions( + void (**m)(void *, int, const char *, int, int), + void (**r)(void *, void *, int, const char *, int, int), + void (**f)(void *, int), void (**so)(long), long (**go)(void)); + +#ifndef LIBRESSL_INTERNAL +void *CRYPTO_malloc_locked(int num, const char *file, int line); +void CRYPTO_free_locked(void *ptr); +void *CRYPTO_malloc(int num, const char *file, int line); +char *CRYPTO_strdup(const char *str, const char *file, int line); +void CRYPTO_free(void *ptr); +void *CRYPTO_realloc(void *addr, int num, const char *file, int line); +#endif + +void *CRYPTO_realloc_clean(void *addr, int old_num, int num, + const char *file, int line); +void *CRYPTO_remalloc(void *addr, int num, const char *file, int line); + +#ifndef LIBRESSL_INTERNAL +void OPENSSL_cleanse(void *ptr, size_t len); +#endif + +void CRYPTO_set_mem_debug_options(long bits); +long CRYPTO_get_mem_debug_options(void); + +#define CRYPTO_push_info(info) \ + CRYPTO_push_info_(info, __FILE__, __LINE__); +int CRYPTO_push_info_(const char *info, const char *file, int line); +int CRYPTO_pop_info(void); +int CRYPTO_remove_all_info(void); + + +/* Default debugging functions (enabled by CRYPTO_malloc_debug_init() macro; + * used as default in CRYPTO_MDEBUG compilations): */ +/* The last argument has the following significance: + * + * 0: called before the actual memory allocation has taken place + * 1: called after the actual memory allocation has taken place + */ +void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, int before_p) + __attribute__ ((deprecated)); +void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num, const char *file, int line, int before_p) + __attribute__ ((deprecated)); +void CRYPTO_dbg_free(void *addr, int before_p) + __attribute__ ((deprecated)); +/* Tell the debugging code about options. By default, the following values + * apply: + * + * 0: Clear all options. + * V_CRYPTO_MDEBUG_TIME (1): Set the "Show Time" option. + * V_CRYPTO_MDEBUG_THREAD (2): Set the "Show Thread Number" option. + * V_CRYPTO_MDEBUG_ALL (3): 1 + 2 + */ +void CRYPTO_dbg_set_options(long bits) + __attribute__ ((deprecated)); +long CRYPTO_dbg_get_options(void) + __attribute__ ((deprecated)); + + +void CRYPTO_mem_leaks_fp(FILE *); +void CRYPTO_mem_leaks(struct bio_st *bio); +/* unsigned long order, char *file, int line, int num_bytes, char *addr */ +typedef void *CRYPTO_MEM_LEAK_CB(unsigned long, const char *, int, int, void *); +void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb); + +/* die if we have to */ +void OpenSSLDie(const char *file, int line, const char *assertion); +#define OPENSSL_assert(e) (void)((e) ? 0 : (OpenSSLDie(__FILE__, __LINE__, #e),1)) + +uint64_t OPENSSL_cpu_caps(void); + +int OPENSSL_isservice(void); + +void OPENSSL_init(void); + +#ifndef LIBRESSL_INTERNAL +/* CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. It + * takes an amount of time dependent on |len|, but independent of the contents + * of |a| and |b|. Unlike memcmp, it cannot be used to put elements into a + * defined order as the return value when a != b is undefined, other than to be + * non-zero. */ +int CRYPTO_memcmp(const void *a, const void *b, size_t len); +#endif + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_CRYPTO_strings(void); + +/* Error codes for the CRYPTO functions. */ + +/* Function codes. */ +#define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX 100 +#define CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID 103 +#define CRYPTO_F_CRYPTO_GET_NEW_LOCKID 101 +#define CRYPTO_F_CRYPTO_SET_EX_DATA 102 +#define CRYPTO_F_DEF_ADD_INDEX 104 +#define CRYPTO_F_DEF_GET_CLASS 105 +#define CRYPTO_F_FIPS_MODE_SET 109 +#define CRYPTO_F_INT_DUP_EX_DATA 106 +#define CRYPTO_F_INT_FREE_EX_DATA 107 +#define CRYPTO_F_INT_NEW_EX_DATA 108 + +/* Reason codes. */ +#define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED 101 +#define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK 100 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/des.h b/crypto/libressl/include/openssl/des.h new file mode 100644 index 0000000000..3942c15480 --- /dev/null +++ b/crypto/libressl/include/openssl/des.h @@ -0,0 +1,219 @@ +/* $OpenBSD: des.h,v 1.18 2014/06/12 15:49:28 deraadt Exp $ */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_NEW_DES_H +#define HEADER_NEW_DES_H + +#include + +#ifdef OPENSSL_NO_DES +#error DES is disabled. +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned char DES_cblock[8]; +typedef /* const */ unsigned char const_DES_cblock[8]; +/* With "const", gcc 2.8.1 on Solaris thinks that DES_cblock * + * and const_DES_cblock * are incompatible pointer types. */ + +typedef struct DES_ks + { + union + { + DES_cblock cblock; + /* make sure things are correct size on machines with + * 8 byte longs */ + DES_LONG deslong[2]; + } ks[16]; + } DES_key_schedule; + +#define DES_KEY_SZ (sizeof(DES_cblock)) +#define DES_SCHEDULE_SZ (sizeof(DES_key_schedule)) + +#define DES_ENCRYPT 1 +#define DES_DECRYPT 0 + +#define DES_CBC_MODE 0 +#define DES_PCBC_MODE 1 + +#define DES_ecb2_encrypt(i,o,k1,k2,e) \ + DES_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) + +#define DES_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ + DES_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) + +#define DES_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ + DES_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) + +#define DES_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ + DES_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) + +extern int DES_check_key; /* defaults to false */ +extern int DES_rw_mode; /* defaults to DES_PCBC_MODE */ + +const char *DES_options(void); +void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks1,DES_key_schedule *ks2, + DES_key_schedule *ks3, int enc); +DES_LONG DES_cbc_cksum(const unsigned char *input,DES_cblock *output, + long length,DES_key_schedule *schedule, + const_DES_cblock *ivec); +/* DES_cbc_encrypt does not update the IV! Use DES_ncbc_encrypt instead. */ +void DES_cbc_encrypt(const unsigned char *input,unsigned char *output, + long length,DES_key_schedule *schedule,DES_cblock *ivec, + int enc); +void DES_ncbc_encrypt(const unsigned char *input,unsigned char *output, + long length,DES_key_schedule *schedule,DES_cblock *ivec, + int enc); +void DES_xcbc_encrypt(const unsigned char *input,unsigned char *output, + long length,DES_key_schedule *schedule,DES_cblock *ivec, + const_DES_cblock *inw,const_DES_cblock *outw,int enc); +void DES_cfb_encrypt(const unsigned char *in,unsigned char *out,int numbits, + long length,DES_key_schedule *schedule,DES_cblock *ivec, + int enc); +void DES_ecb_encrypt(const_DES_cblock *input,DES_cblock *output, + DES_key_schedule *ks,int enc); + +/* This is the DES encryption function that gets called by just about + every other DES routine in the library. You should not use this + function except to implement 'modes' of DES. I say this because the + functions that call this routine do the conversion from 'char *' to + long, and this needs to be done to make sure 'non-aligned' memory + access do not occur. The characters are loaded 'little endian'. + Data is a pointer to 2 unsigned long's and ks is the + DES_key_schedule to use. enc, is non zero specifies encryption, + zero if decryption. */ +void DES_encrypt1(DES_LONG *data,DES_key_schedule *ks, int enc); + +/* This functions is the same as DES_encrypt1() except that the DES + initial permutation (IP) and final permutation (FP) have been left + out. As for DES_encrypt1(), you should not use this function. + It is used by the routines in the library that implement triple DES. + IP() DES_encrypt2() DES_encrypt2() DES_encrypt2() FP() is the same + as DES_encrypt1() DES_encrypt1() DES_encrypt1() except faster :-). */ +void DES_encrypt2(DES_LONG *data,DES_key_schedule *ks, int enc); + +void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3); +void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3); +void DES_ede3_cbc_encrypt(const unsigned char *input,unsigned char *output, + long length, + DES_key_schedule *ks1,DES_key_schedule *ks2, + DES_key_schedule *ks3,DES_cblock *ivec,int enc); +void DES_ede3_cbcm_encrypt(const unsigned char *in,unsigned char *out, + long length, + DES_key_schedule *ks1,DES_key_schedule *ks2, + DES_key_schedule *ks3, + DES_cblock *ivec1,DES_cblock *ivec2, + int enc); +void DES_ede3_cfb64_encrypt(const unsigned char *in,unsigned char *out, + long length,DES_key_schedule *ks1, + DES_key_schedule *ks2,DES_key_schedule *ks3, + DES_cblock *ivec,int *num,int enc); +void DES_ede3_cfb_encrypt(const unsigned char *in,unsigned char *out, + int numbits,long length,DES_key_schedule *ks1, + DES_key_schedule *ks2,DES_key_schedule *ks3, + DES_cblock *ivec,int enc); +void DES_ede3_ofb64_encrypt(const unsigned char *in,unsigned char *out, + long length,DES_key_schedule *ks1, + DES_key_schedule *ks2,DES_key_schedule *ks3, + DES_cblock *ivec,int *num); +int DES_enc_read(int fd,void *buf,int len,DES_key_schedule *sched, + DES_cblock *iv); +int DES_enc_write(int fd,const void *buf,int len,DES_key_schedule *sched, + DES_cblock *iv); +char *DES_fcrypt(const char *buf,const char *salt, char *ret); +char *DES_crypt(const char *buf,const char *salt); +void DES_ofb_encrypt(const unsigned char *in,unsigned char *out,int numbits, + long length,DES_key_schedule *schedule,DES_cblock *ivec); +void DES_pcbc_encrypt(const unsigned char *input,unsigned char *output, + long length,DES_key_schedule *schedule,DES_cblock *ivec, + int enc); +DES_LONG DES_quad_cksum(const unsigned char *input,DES_cblock output[], + long length,int out_count,DES_cblock *seed); +int DES_random_key(DES_cblock *ret); +void DES_set_odd_parity(DES_cblock *key); +int DES_check_key_parity(const_DES_cblock *key); +int DES_is_weak_key(const_DES_cblock *key); +/* DES_set_key (= set_key = DES_key_sched = key_sched) calls + * DES_set_key_checked if global variable DES_check_key is set, + * DES_set_key_unchecked otherwise. */ +int DES_set_key(const_DES_cblock *key,DES_key_schedule *schedule); +int DES_key_sched(const_DES_cblock *key,DES_key_schedule *schedule); +int DES_set_key_checked(const_DES_cblock *key,DES_key_schedule *schedule); +void DES_set_key_unchecked(const_DES_cblock *key,DES_key_schedule *schedule); +void DES_string_to_key(const char *str,DES_cblock *key); +void DES_string_to_2keys(const char *str,DES_cblock *key1,DES_cblock *key2); +void DES_cfb64_encrypt(const unsigned char *in,unsigned char *out,long length, + DES_key_schedule *schedule,DES_cblock *ivec,int *num, + int enc); +void DES_ofb64_encrypt(const unsigned char *in,unsigned char *out,long length, + DES_key_schedule *schedule,DES_cblock *ivec,int *num); + +#define DES_fixup_key_parity DES_set_odd_parity + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/libressl/include/openssl/dh.h b/crypto/libressl/include/openssl/dh.h new file mode 100644 index 0000000000..32eb6b99f1 --- /dev/null +++ b/crypto/libressl/include/openssl/dh.h @@ -0,0 +1,271 @@ +/* $OpenBSD: dh.h,v 1.16 2014/06/12 15:49:28 deraadt Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_DH_H +#define HEADER_DH_H + +#include + +#ifdef OPENSSL_NO_DH +#error DH is disabled. +#endif + +#ifndef OPENSSL_NO_BIO +#include +#endif +#include +#ifndef OPENSSL_NO_DEPRECATED +#include +#endif + +#ifndef OPENSSL_DH_MAX_MODULUS_BITS +# define OPENSSL_DH_MAX_MODULUS_BITS 10000 +#endif + +#define DH_FLAG_CACHE_MONT_P 0x01 + +/* If this flag is set the DH method is FIPS compliant and can be used + * in FIPS mode. This is set in the validated module method. If an + * application sets this flag in its own methods it is its reposibility + * to ensure the result is compliant. + */ + +#define DH_FLAG_FIPS_METHOD 0x0400 + +/* If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +#define DH_FLAG_NON_FIPS_ALLOW 0x0400 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Already defined in ossl_typ.h */ +/* typedef struct dh_st DH; */ +/* typedef struct dh_method DH_METHOD; */ + +struct dh_method + { + const char *name; + /* Methods here */ + int (*generate_key)(DH *dh); + int (*compute_key)(unsigned char *key,const BIGNUM *pub_key,DH *dh); + int (*bn_mod_exp)(const DH *dh, BIGNUM *r, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); /* Can be null */ + + int (*init)(DH *dh); + int (*finish)(DH *dh); + int flags; + char *app_data; + /* If this is non-NULL, it will be used to generate parameters */ + int (*generate_params)(DH *dh, int prime_len, int generator, BN_GENCB *cb); + }; + +struct dh_st + { + /* This first argument is used to pick up errors when + * a DH is passed instead of a EVP_PKEY */ + int pad; + int version; + BIGNUM *p; + BIGNUM *g; + long length; /* optional */ + BIGNUM *pub_key; /* g^x */ + BIGNUM *priv_key; /* x */ + + int flags; + BN_MONT_CTX *method_mont_p; + /* Place holders if we want to do X9.42 DH */ + BIGNUM *q; + BIGNUM *j; + unsigned char *seed; + int seedlen; + BIGNUM *counter; + + int references; + CRYPTO_EX_DATA ex_data; + const DH_METHOD *meth; + ENGINE *engine; + }; + +#define DH_GENERATOR_2 2 +/* #define DH_GENERATOR_3 3 */ +#define DH_GENERATOR_5 5 + +/* DH_check error codes */ +#define DH_CHECK_P_NOT_PRIME 0x01 +#define DH_CHECK_P_NOT_SAFE_PRIME 0x02 +#define DH_UNABLE_TO_CHECK_GENERATOR 0x04 +#define DH_NOT_SUITABLE_GENERATOR 0x08 + +/* DH_check_pub_key error codes */ +#define DH_CHECK_PUBKEY_TOO_SMALL 0x01 +#define DH_CHECK_PUBKEY_TOO_LARGE 0x02 + +/* primes p where (p-1)/2 is prime too are called "safe"; we define + this for backward compatibility: */ +#define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME + +#define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ + (char *(*)())d2i_DHparams,(fp),(unsigned char **)(x)) +#define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \ + (unsigned char *)(x)) +#define d2i_DHparams_bio(bp,x) ASN1_d2i_bio_of(DH,DH_new,d2i_DHparams,bp,x) +#define i2d_DHparams_bio(bp,x) ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x) + +DH *DHparams_dup(DH *); + +const DH_METHOD *DH_OpenSSL(void); + +void DH_set_default_method(const DH_METHOD *meth); +const DH_METHOD *DH_get_default_method(void); +int DH_set_method(DH *dh, const DH_METHOD *meth); +DH *DH_new_method(ENGINE *engine); + +DH * DH_new(void); +void DH_free(DH *dh); +int DH_up_ref(DH *dh); +int DH_size(const DH *dh); +int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int DH_set_ex_data(DH *d, int idx, void *arg); +void *DH_get_ex_data(DH *d, int idx); + +/* Deprecated version */ +#ifndef OPENSSL_NO_DEPRECATED +DH * DH_generate_parameters(int prime_len,int generator, + void (*callback)(int,int,void *),void *cb_arg); +#endif /* !defined(OPENSSL_NO_DEPRECATED) */ + +/* New version */ +int DH_generate_parameters_ex(DH *dh, int prime_len,int generator, BN_GENCB *cb); + +int DH_check(const DH *dh,int *codes); +int DH_check_pub_key(const DH *dh,const BIGNUM *pub_key, int *codes); +int DH_generate_key(DH *dh); +int DH_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh); +DH * d2i_DHparams(DH **a,const unsigned char **pp, long length); +int i2d_DHparams(const DH *a,unsigned char **pp); +int DHparams_print_fp(FILE *fp, const DH *x); +#ifndef OPENSSL_NO_BIO +int DHparams_print(BIO *bp, const DH *x); +#else +int DHparams_print(char *bp, const DH *x); +#endif + +#define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL) + +#define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL) + +#define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN (EVP_PKEY_ALG_CTRL + 1) +#define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR (EVP_PKEY_ALG_CTRL + 2) + + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_DH_strings(void); + +/* Error codes for the DH functions. */ + +/* Function codes. */ +#define DH_F_COMPUTE_KEY 102 +#define DH_F_DHPARAMS_PRINT_FP 101 +#define DH_F_DH_BUILTIN_GENPARAMS 106 +#define DH_F_DH_COMPUTE_KEY 114 +#define DH_F_DH_GENERATE_KEY 115 +#define DH_F_DH_GENERATE_PARAMETERS_EX 116 +#define DH_F_DH_NEW_METHOD 105 +#define DH_F_DH_PARAM_DECODE 107 +#define DH_F_DH_PRIV_DECODE 110 +#define DH_F_DH_PRIV_ENCODE 111 +#define DH_F_DH_PUB_DECODE 108 +#define DH_F_DH_PUB_ENCODE 109 +#define DH_F_DO_DH_PRINT 100 +#define DH_F_GENERATE_KEY 103 +#define DH_F_GENERATE_PARAMETERS 104 +#define DH_F_PKEY_DH_DERIVE 112 +#define DH_F_PKEY_DH_KEYGEN 113 + +/* Reason codes. */ +#define DH_R_BAD_GENERATOR 101 +#define DH_R_BN_DECODE_ERROR 109 +#define DH_R_BN_ERROR 106 +#define DH_R_DECODE_ERROR 104 +#define DH_R_INVALID_PUBKEY 102 +#define DH_R_KEYS_NOT_SET 108 +#define DH_R_KEY_SIZE_TOO_SMALL 110 +#define DH_R_MODULUS_TOO_LARGE 103 +#define DH_R_NON_FIPS_METHOD 111 +#define DH_R_NO_PARAMETERS_SET 107 +#define DH_R_NO_PRIVATE_VALUE 100 +#define DH_R_PARAMETER_ENCODING_ERROR 105 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/dsa.h b/crypto/libressl/include/openssl/dsa.h new file mode 100644 index 0000000000..976c8dd5ab --- /dev/null +++ b/crypto/libressl/include/openssl/dsa.h @@ -0,0 +1,323 @@ +/* $OpenBSD: dsa.h,v 1.20 2016/06/21 04:16:53 bcook Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * The DSS routines are based on patches supplied by + * Steven Schoch . He basically did the + * work and I have just tweaked them a little to fit into my + * stylistic vision for SSLeay :-) */ + +#ifndef HEADER_DSA_H +#define HEADER_DSA_H + +#include + +#ifdef OPENSSL_NO_DSA +#error DSA is disabled. +#endif + +#ifndef OPENSSL_NO_BIO +#include +#endif +#include +#include + +#ifndef OPENSSL_NO_DEPRECATED +#include +#ifndef OPENSSL_NO_DH +# include +#endif +#endif + +#ifndef OPENSSL_DSA_MAX_MODULUS_BITS +# define OPENSSL_DSA_MAX_MODULUS_BITS 10000 +#endif + +#define DSA_FLAG_CACHE_MONT_P 0x01 + +/* If this flag is set the DSA method is FIPS compliant and can be used + * in FIPS mode. This is set in the validated module method. If an + * application sets this flag in its own methods it is its reposibility + * to ensure the result is compliant. + */ + +#define DSA_FLAG_FIPS_METHOD 0x0400 + +/* If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +#define DSA_FLAG_NON_FIPS_ALLOW 0x0400 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Already defined in ossl_typ.h */ +/* typedef struct dsa_st DSA; */ +/* typedef struct dsa_method DSA_METHOD; */ + +typedef struct DSA_SIG_st + { + BIGNUM *r; + BIGNUM *s; + } DSA_SIG; + +struct dsa_method + { + const char *name; + DSA_SIG * (*dsa_do_sign)(const unsigned char *dgst, int dlen, DSA *dsa); + int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp); + int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); + int (*dsa_mod_exp)(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, + BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont); + int (*bn_mod_exp)(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); /* Can be null */ + int (*init)(DSA *dsa); + int (*finish)(DSA *dsa); + int flags; + char *app_data; + /* If this is non-NULL, it is used to generate DSA parameters */ + int (*dsa_paramgen)(DSA *dsa, int bits, + const unsigned char *seed, int seed_len, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb); + /* If this is non-NULL, it is used to generate DSA keys */ + int (*dsa_keygen)(DSA *dsa); + }; + +struct dsa_st + { + /* This first variable is used to pick up errors where + * a DSA is passed instead of of a EVP_PKEY */ + int pad; + long version; + int write_params; + BIGNUM *p; + BIGNUM *q; /* == 20 */ + BIGNUM *g; + + BIGNUM *pub_key; /* y public key */ + BIGNUM *priv_key; /* x private key */ + + BIGNUM *kinv; /* Signing pre-calc */ + BIGNUM *r; /* Signing pre-calc */ + + int flags; + /* Normally used to cache montgomery values */ + BN_MONT_CTX *method_mont_p; + int references; + CRYPTO_EX_DATA ex_data; + const DSA_METHOD *meth; + /* functional reference if 'meth' is ENGINE-provided */ + ENGINE *engine; + }; + +#define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \ + (char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x)) +#define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \ + (unsigned char *)(x)) +#define d2i_DSAparams_bio(bp,x) ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAparams,bp,x) +#define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x) + + +DSA *DSAparams_dup(DSA *x); +DSA_SIG * DSA_SIG_new(void); +void DSA_SIG_free(DSA_SIG *a); +int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp); +DSA_SIG * d2i_DSA_SIG(DSA_SIG **v, const unsigned char **pp, long length); + +DSA_SIG * DSA_do_sign(const unsigned char *dgst,int dlen,DSA *dsa); +int DSA_do_verify(const unsigned char *dgst,int dgst_len, + DSA_SIG *sig,DSA *dsa); + +const DSA_METHOD *DSA_OpenSSL(void); + +void DSA_set_default_method(const DSA_METHOD *); +const DSA_METHOD *DSA_get_default_method(void); +int DSA_set_method(DSA *dsa, const DSA_METHOD *); + +DSA * DSA_new(void); +DSA * DSA_new_method(ENGINE *engine); +void DSA_free(DSA *r); +/* "up" the DSA object's reference count */ +int DSA_up_ref(DSA *r); +int DSA_size(const DSA *); + /* next 4 return -1 on error */ +int DSA_sign_setup( DSA *dsa,BN_CTX *ctx_in,BIGNUM **kinvp,BIGNUM **rp); +int DSA_sign(int type,const unsigned char *dgst,int dlen, + unsigned char *sig, unsigned int *siglen, DSA *dsa); +int DSA_verify(int type,const unsigned char *dgst,int dgst_len, + const unsigned char *sigbuf, int siglen, DSA *dsa); +int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int DSA_set_ex_data(DSA *d, int idx, void *arg); +void *DSA_get_ex_data(DSA *d, int idx); + +DSA *d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length); +int i2d_DSAPublicKey(const DSA *a, unsigned char **pp); +extern const ASN1_ITEM DSAPublicKey_it; + +DSA *d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length); +int i2d_DSAPrivateKey(const DSA *a, unsigned char **pp); +extern const ASN1_ITEM DSAPrivateKey_it; + +DSA *d2i_DSAparams(DSA **a, const unsigned char **pp, long length); +int i2d_DSAparams(const DSA *a,unsigned char **pp); +extern const ASN1_ITEM DSAparams_it; + +/* Deprecated version */ +#ifndef OPENSSL_NO_DEPRECATED +DSA * DSA_generate_parameters(int bits, + unsigned char *seed,int seed_len, + int *counter_ret, unsigned long *h_ret,void + (*callback)(int, int, void *),void *cb_arg); +#endif /* !defined(OPENSSL_NO_DEPRECATED) */ + +/* New version */ +int DSA_generate_parameters_ex(DSA *dsa, int bits, + const unsigned char *seed,int seed_len, + int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); + +int DSA_generate_key(DSA *a); + +#ifndef OPENSSL_NO_BIO +int DSAparams_print(BIO *bp, const DSA *x); +int DSA_print(BIO *bp, const DSA *x, int off); +#endif +int DSAparams_print_fp(FILE *fp, const DSA *x); +int DSA_print_fp(FILE *bp, const DSA *x, int off); + +#define DSS_prime_checks 50 +/* Primality test according to FIPS PUB 186[-1], Appendix 2.1: + * 50 rounds of Rabin-Miller */ +#define DSA_is_prime(n, callback, cb_arg) \ + BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg) + +#ifndef OPENSSL_NO_DH +/* Convert DSA structure (key or just parameters) into DH structure + * (be careful to avoid small subgroup attacks when using this!) */ +DH *DSA_dup_DH(const DSA *r); +#endif + +#define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL) + +#define EVP_PKEY_CTRL_DSA_PARAMGEN_BITS (EVP_PKEY_ALG_CTRL + 1) +#define EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS (EVP_PKEY_ALG_CTRL + 2) +#define EVP_PKEY_CTRL_DSA_PARAMGEN_MD (EVP_PKEY_ALG_CTRL + 3) + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_DSA_strings(void); + +/* Error codes for the DSA functions. */ + +/* Function codes. */ +#define DSA_F_D2I_DSA_SIG 110 +#define DSA_F_DO_DSA_PRINT 104 +#define DSA_F_DSAPARAMS_PRINT 100 +#define DSA_F_DSAPARAMS_PRINT_FP 101 +#define DSA_F_DSA_DO_SIGN 112 +#define DSA_F_DSA_DO_VERIFY 113 +#define DSA_F_DSA_GENERATE_KEY 124 +#define DSA_F_DSA_GENERATE_PARAMETERS_EX 123 +#define DSA_F_DSA_NEW_METHOD 103 +#define DSA_F_DSA_PARAM_DECODE 119 +#define DSA_F_DSA_PRINT_FP 105 +#define DSA_F_DSA_PRIV_DECODE 115 +#define DSA_F_DSA_PRIV_ENCODE 116 +#define DSA_F_DSA_PUB_DECODE 117 +#define DSA_F_DSA_PUB_ENCODE 118 +#define DSA_F_DSA_SIGN 106 +#define DSA_F_DSA_SIGN_SETUP 107 +#define DSA_F_DSA_SIG_NEW 109 +#define DSA_F_DSA_SIG_PRINT 125 +#define DSA_F_DSA_VERIFY 108 +#define DSA_F_I2D_DSA_SIG 111 +#define DSA_F_OLD_DSA_PRIV_DECODE 122 +#define DSA_F_PKEY_DSA_CTRL 120 +#define DSA_F_PKEY_DSA_KEYGEN 121 +#define DSA_F_SIG_CB 114 + +/* Reason codes. */ +#define DSA_R_BAD_Q_VALUE 102 +#define DSA_R_BN_DECODE_ERROR 108 +#define DSA_R_BN_ERROR 109 +#define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 100 +#define DSA_R_DECODE_ERROR 104 +#define DSA_R_INVALID_DIGEST_TYPE 106 +#define DSA_R_MISSING_PARAMETERS 101 +#define DSA_R_MODULUS_TOO_LARGE 103 +#define DSA_R_NEED_NEW_SETUP_VALUES 110 +#define DSA_R_NON_FIPS_DSA_METHOD 111 +#define DSA_R_NO_PARAMETERS_SET 107 +#define DSA_R_PARAMETER_ENCODING_ERROR 105 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/dso.h b/crypto/libressl/include/openssl/dso.h new file mode 100644 index 0000000000..0c8ac9deaf --- /dev/null +++ b/crypto/libressl/include/openssl/dso.h @@ -0,0 +1,386 @@ +/* $OpenBSD: dso.h,v 1.11 2015/02/07 13:19:15 doug Exp $ */ +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_DSO_H +#define HEADER_DSO_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* These values are used as commands to DSO_ctrl() */ +#define DSO_CTRL_GET_FLAGS 1 +#define DSO_CTRL_SET_FLAGS 2 +#define DSO_CTRL_OR_FLAGS 3 + +/* By default, DSO_load() will translate the provided filename into a form + * typical for the platform (more specifically the DSO_METHOD) using the + * dso_name_converter function of the method. Eg. win32 will transform "blah" + * into "blah.dll", and dlfcn will transform it into "libblah.so". The + * behaviour can be overridden by setting the name_converter callback in the DSO + * object (using DSO_set_name_converter()). This callback could even utilise + * the DSO_METHOD's converter too if it only wants to override behaviour for + * one or two possible DSO methods. However, the following flag can be set in a + * DSO to prevent *any* native name-translation at all - eg. if the caller has + * prompted the user for a path to a driver library so the filename should be + * interpreted as-is. */ +#define DSO_FLAG_NO_NAME_TRANSLATION 0x01 +/* An extra flag to give if only the extension should be added as + * translation. This is obviously only of importance on Unix and + * other operating systems where the translation also may prefix + * the name with something, like 'lib', and ignored everywhere else. + * This flag is also ignored if DSO_FLAG_NO_NAME_TRANSLATION is used + * at the same time. */ +#define DSO_FLAG_NAME_TRANSLATION_EXT_ONLY 0x02 + +/* The following flag controls the translation of symbol names to upper + * case. This is currently only being implemented for OpenVMS. + */ +#define DSO_FLAG_UPCASE_SYMBOL 0x10 + +/* This flag loads the library with public symbols. + * Meaning: The exported symbols of this library are public + * to all libraries loaded after this library. + * At the moment only implemented in unix. + */ +#define DSO_FLAG_GLOBAL_SYMBOLS 0x20 + + +typedef void (*DSO_FUNC_TYPE)(void); + +typedef struct dso_st DSO; + +/* The function prototype used for method functions (or caller-provided + * callbacks) that transform filenames. They are passed a DSO structure pointer + * (or NULL if they are to be used independantly of a DSO object) and a + * filename to transform. They should either return NULL (if there is an error + * condition) or a newly allocated string containing the transformed form that + * the caller will need to free with free() when done. */ +typedef char* (*DSO_NAME_CONVERTER_FUNC)(DSO *, const char *); +/* The function prototype used for method functions (or caller-provided + * callbacks) that merge two file specifications. They are passed a + * DSO structure pointer (or NULL if they are to be used independantly of + * a DSO object) and two file specifications to merge. They should + * either return NULL (if there is an error condition) or a newly allocated + * string containing the result of merging that the caller will need + * to free with free() when done. + * Here, merging means that bits and pieces are taken from each of the + * file specifications and added together in whatever fashion that is + * sensible for the DSO method in question. The only rule that really + * applies is that if the two specification contain pieces of the same + * type, the copy from the first string takes priority. One could see + * it as the first specification is the one given by the user and the + * second being a bunch of defaults to add on if they're missing in the + * first. */ +typedef char* (*DSO_MERGER_FUNC)(DSO *, const char *, const char *); + +typedef struct dso_meth_st { + const char *name; + /* Loads a shared library, NB: new DSO_METHODs must ensure that a + * successful load populates the loaded_filename field, and likewise a + * successful unload frees and NULLs it out. */ + int (*dso_load)(DSO *dso); + /* Unloads a shared library */ + int (*dso_unload)(DSO *dso); + /* Binds a variable */ + void *(*dso_bind_var)(DSO *dso, const char *symname); + /* Binds a function - assumes a return type of DSO_FUNC_TYPE. + * This should be cast to the real function prototype by the + * caller. Platforms that don't have compatible representations + * for different prototypes (this is possible within ANSI C) + * are highly unlikely to have shared libraries at all, let + * alone a DSO_METHOD implemented for them. */ + DSO_FUNC_TYPE (*dso_bind_func)(DSO *dso, const char *symname); + + /* The generic (yuck) "ctrl()" function. NB: Negative return + * values (rather than zero) indicate errors. */ + long (*dso_ctrl)(DSO *dso, int cmd, long larg, void *parg); + /* The default DSO_METHOD-specific function for converting filenames to + * a canonical native form. */ + DSO_NAME_CONVERTER_FUNC dso_name_converter; + /* The default DSO_METHOD-specific function for converting filenames to + * a canonical native form. */ + DSO_MERGER_FUNC dso_merger; + + /* [De]Initialisation handlers. */ + int (*init)(DSO *dso); + int (*finish)(DSO *dso); + + /* Return pathname of the module containing location */ + int (*pathbyaddr)(void *addr, char *path, int sz); + /* Perform global symbol lookup, i.e. among *all* modules */ + void *(*globallookup)(const char *symname); +} DSO_METHOD; + +/**********************************************************************/ +/* The low-level handle type used to refer to a loaded shared library */ + +struct dso_st { + DSO_METHOD *meth; + /* Standard dlopen uses a (void *). Win32 uses a HANDLE. VMS + * doesn't use anything but will need to cache the filename + * for use in the dso_bind handler. All in all, let each + * method control its own destiny. "Handles" and such go in + * a STACK. */ + STACK_OF(void) *meth_data; + int references; + int flags; + /* For use by applications etc ... use this for your bits'n'pieces, + * don't touch meth_data! */ + CRYPTO_EX_DATA ex_data; + /* If this callback function pointer is set to non-NULL, then it will + * be used in DSO_load() in place of meth->dso_name_converter. NB: This + * should normally set using DSO_set_name_converter(). */ + DSO_NAME_CONVERTER_FUNC name_converter; + /* If this callback function pointer is set to non-NULL, then it will + * be used in DSO_load() in place of meth->dso_merger. NB: This + * should normally set using DSO_set_merger(). */ + DSO_MERGER_FUNC merger; + /* This is populated with (a copy of) the platform-independant + * filename used for this DSO. */ + char *filename; + /* This is populated with (a copy of) the translated filename by which + * the DSO was actually loaded. It is NULL iff the DSO is not currently + * loaded. NB: This is here because the filename translation process + * may involve a callback being invoked more than once not only to + * convert to a platform-specific form, but also to try different + * filenames in the process of trying to perform a load. As such, this + * variable can be used to indicate (a) whether this DSO structure + * corresponds to a loaded library or not, and (b) the filename with + * which it was actually loaded. */ + char *loaded_filename; +}; + + +DSO * DSO_new(void); +DSO * DSO_new_method(DSO_METHOD *method); +int DSO_free(DSO *dso); +int DSO_flags(DSO *dso); +int DSO_up_ref(DSO *dso); +long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg); + +/* This function sets the DSO's name_converter callback. If it is non-NULL, + * then it will be used instead of the associated DSO_METHOD's function. If + * oldcb is non-NULL then it is set to the function pointer value being + * replaced. Return value is non-zero for success. */ +int DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb, + DSO_NAME_CONVERTER_FUNC *oldcb); +/* These functions can be used to get/set the platform-independant filename + * used for a DSO. NB: set will fail if the DSO is already loaded. */ +const char *DSO_get_filename(DSO *dso); +int DSO_set_filename(DSO *dso, const char *filename); +/* This function will invoke the DSO's name_converter callback to translate a + * filename, or if the callback isn't set it will instead use the DSO_METHOD's + * converter. If "filename" is NULL, the "filename" in the DSO itself will be + * used. If the DSO_FLAG_NO_NAME_TRANSLATION flag is set, then the filename is + * simply duplicated. NB: This function is usually called from within a + * DSO_METHOD during the processing of a DSO_load() call, and is exposed so that + * caller-created DSO_METHODs can do the same thing. A non-NULL return value + * will need to be free()'d. */ +char *DSO_convert_filename(DSO *dso, const char *filename); +/* This function will invoke the DSO's merger callback to merge two file + * specifications, or if the callback isn't set it will instead use the + * DSO_METHOD's merger. A non-NULL return value will need to be + * free()'d. */ +char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2); +/* If the DSO is currently loaded, this returns the filename that it was loaded + * under, otherwise it returns NULL. So it is also useful as a test as to + * whether the DSO is currently loaded. NB: This will not necessarily return + * the same value as DSO_convert_filename(dso, dso->filename), because the + * DSO_METHOD's load function may have tried a variety of filenames (with + * and/or without the aid of the converters) before settling on the one it + * actually loaded. */ +const char *DSO_get_loaded_filename(DSO *dso); + +void DSO_set_default_method(DSO_METHOD *meth); +DSO_METHOD *DSO_get_default_method(void); +DSO_METHOD *DSO_get_method(DSO *dso); +DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth); + +/* The all-singing all-dancing load function, you normally pass NULL + * for the first and third parameters. Use DSO_up and DSO_free for + * subsequent reference count handling. Any flags passed in will be set + * in the constructed DSO after its init() function but before the + * load operation. If 'dso' is non-NULL, 'flags' is ignored. */ +DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags); + +/* This function binds to a variable inside a shared library. */ +void *DSO_bind_var(DSO *dso, const char *symname); + +/* This function binds to a function inside a shared library. */ +DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname); + +/* This method is the default, but will beg, borrow, or steal whatever + * method should be the default on any particular platform (including + * DSO_METH_null() if necessary). */ +DSO_METHOD *DSO_METHOD_openssl(void); + +/* This method is defined for all platforms - if a platform has no + * DSO support then this will be the only method! */ +DSO_METHOD *DSO_METHOD_null(void); + +/* If DSO_DLFCN is defined, the standard dlfcn.h-style functions + * (dlopen, dlclose, dlsym, etc) will be used and incorporated into + * this method. If not, this method will return NULL. */ +DSO_METHOD *DSO_METHOD_dlfcn(void); + +/* This function writes null-terminated pathname of DSO module + * containing 'addr' into 'sz' large caller-provided 'path' and + * returns the number of characters [including trailing zero] + * written to it. If 'sz' is 0 or negative, 'path' is ignored and + * required amount of charachers [including trailing zero] to + * accommodate pathname is returned. If 'addr' is NULL, then + * pathname of cryptolib itself is returned. Negative or zero + * return value denotes error. + */ +int DSO_pathbyaddr(void *addr, char *path, int sz); + +/* This function should be used with caution! It looks up symbols in + * *all* loaded modules and if module gets unloaded by somebody else + * attempt to dereference the pointer is doomed to have fatal + * consequences. Primary usage for this function is to probe *core* + * system functionality, e.g. check if getnameinfo(3) is available + * at run-time without bothering about OS-specific details such as + * libc.so.versioning or where does it actually reside: in libc + * itself or libsocket. */ +void *DSO_global_lookup(const char *name); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_DSO_strings(void); + +/* Error codes for the DSO functions. */ + +/* Function codes. */ +#define DSO_F_BEOS_BIND_FUNC 144 +#define DSO_F_BEOS_BIND_VAR 145 +#define DSO_F_BEOS_LOAD 146 +#define DSO_F_BEOS_NAME_CONVERTER 147 +#define DSO_F_BEOS_UNLOAD 148 +#define DSO_F_DLFCN_BIND_FUNC 100 +#define DSO_F_DLFCN_BIND_VAR 101 +#define DSO_F_DLFCN_LOAD 102 +#define DSO_F_DLFCN_MERGER 130 +#define DSO_F_DLFCN_NAME_CONVERTER 123 +#define DSO_F_DLFCN_UNLOAD 103 +#define DSO_F_DL_BIND_FUNC 104 +#define DSO_F_DL_BIND_VAR 105 +#define DSO_F_DL_LOAD 106 +#define DSO_F_DL_MERGER 131 +#define DSO_F_DL_NAME_CONVERTER 124 +#define DSO_F_DL_UNLOAD 107 +#define DSO_F_DSO_BIND_FUNC 108 +#define DSO_F_DSO_BIND_VAR 109 +#define DSO_F_DSO_CONVERT_FILENAME 126 +#define DSO_F_DSO_CTRL 110 +#define DSO_F_DSO_FREE 111 +#define DSO_F_DSO_GET_FILENAME 127 +#define DSO_F_DSO_GET_LOADED_FILENAME 128 +#define DSO_F_DSO_GLOBAL_LOOKUP 139 +#define DSO_F_DSO_LOAD 112 +#define DSO_F_DSO_MERGE 132 +#define DSO_F_DSO_NEW_METHOD 113 +#define DSO_F_DSO_PATHBYADDR 140 +#define DSO_F_DSO_SET_FILENAME 129 +#define DSO_F_DSO_SET_NAME_CONVERTER 122 +#define DSO_F_DSO_UP_REF 114 +#define DSO_F_GLOBAL_LOOKUP_FUNC 138 +#define DSO_F_PATHBYADDR 137 +#define DSO_F_VMS_BIND_SYM 115 +#define DSO_F_VMS_LOAD 116 +#define DSO_F_VMS_MERGER 133 +#define DSO_F_VMS_UNLOAD 117 +#define DSO_F_WIN32_BIND_FUNC 118 +#define DSO_F_WIN32_BIND_VAR 119 +#define DSO_F_WIN32_GLOBALLOOKUP 142 +#define DSO_F_WIN32_GLOBALLOOKUP_FUNC 143 +#define DSO_F_WIN32_JOINER 135 +#define DSO_F_WIN32_LOAD 120 +#define DSO_F_WIN32_MERGER 134 +#define DSO_F_WIN32_NAME_CONVERTER 125 +#define DSO_F_WIN32_PATHBYADDR 141 +#define DSO_F_WIN32_SPLITTER 136 +#define DSO_F_WIN32_UNLOAD 121 + +/* Reason codes. */ +#define DSO_R_CTRL_FAILED 100 +#define DSO_R_DSO_ALREADY_LOADED 110 +#define DSO_R_EMPTY_FILE_STRUCTURE 113 +#define DSO_R_FAILURE 114 +#define DSO_R_FILENAME_TOO_BIG 101 +#define DSO_R_FINISH_FAILED 102 +#define DSO_R_INCORRECT_FILE_SYNTAX 115 +#define DSO_R_LOAD_FAILED 103 +#define DSO_R_NAME_TRANSLATION_FAILED 109 +#define DSO_R_NO_FILENAME 111 +#define DSO_R_NO_FILE_SPECIFICATION 116 +#define DSO_R_NULL_HANDLE 104 +#define DSO_R_SET_FILENAME_FAILED 112 +#define DSO_R_STACK_ERROR 105 +#define DSO_R_SYM_FAILURE 106 +#define DSO_R_UNLOAD_FAILED 107 +#define DSO_R_UNSUPPORTED 108 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/dtls1.h b/crypto/libressl/include/openssl/dtls1.h new file mode 100644 index 0000000000..dc5a7ac759 --- /dev/null +++ b/crypto/libressl/include/openssl/dtls1.h @@ -0,0 +1,249 @@ +/* $OpenBSD: dtls1.h,v 1.17 2015/02/09 10:53:28 jsing Exp $ */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_DTLS1_H +#define HEADER_DTLS1_H + +#if defined(_WIN32) +#include +#else +#include +#endif + +#include +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define DTLS1_VERSION 0xFEFF + +/* lengths of messages */ +#define DTLS1_COOKIE_LENGTH 256 + +#define DTLS1_RT_HEADER_LENGTH 13 + +#define DTLS1_HM_HEADER_LENGTH 12 + +#define DTLS1_HM_BAD_FRAGMENT -2 +#define DTLS1_HM_FRAGMENT_RETRY -3 + +#define DTLS1_CCS_HEADER_LENGTH 1 + +#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE +#define DTLS1_AL_HEADER_LENGTH 7 +#else +#define DTLS1_AL_HEADER_LENGTH 2 +#endif + +#ifndef OPENSSL_NO_SSL_INTERN + + +typedef struct dtls1_bitmap_st { + unsigned long map; /* track 32 packets on 32-bit systems + and 64 - on 64-bit systems */ + unsigned char max_seq_num[8]; /* max record number seen so far, + 64-bit value in big-endian + encoding */ +} DTLS1_BITMAP; + +struct dtls1_retransmit_state { + EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ + EVP_MD_CTX *write_hash; /* used for mac generation */ + SSL_SESSION *session; + unsigned short epoch; +}; + +struct hm_header_st { + unsigned char type; + unsigned long msg_len; + unsigned short seq; + unsigned long frag_off; + unsigned long frag_len; + unsigned int is_ccs; + struct dtls1_retransmit_state saved_retransmit_state; +}; + +struct ccs_header_st { + unsigned char type; + unsigned short seq; +}; + +struct dtls1_timeout_st { + /* Number of read timeouts so far */ + unsigned int read_timeouts; + + /* Number of write timeouts so far */ + unsigned int write_timeouts; + + /* Number of alerts received so far */ + unsigned int num_alerts; +}; + +struct _pqueue; + +typedef struct record_pqueue_st { + unsigned short epoch; + struct _pqueue *q; +} record_pqueue; + +typedef struct hm_fragment_st { + struct hm_header_st msg_header; + unsigned char *fragment; + unsigned char *reassembly; +} hm_fragment; + +typedef struct dtls1_state_st { + unsigned int send_cookie; + unsigned char cookie[DTLS1_COOKIE_LENGTH]; + unsigned char rcvd_cookie[DTLS1_COOKIE_LENGTH]; + unsigned int cookie_len; + + /* + * The current data and handshake epoch. This is initially + * undefined, and starts at zero once the initial handshake is + * completed + */ + unsigned short r_epoch; + unsigned short w_epoch; + + /* records being received in the current epoch */ + DTLS1_BITMAP bitmap; + + /* renegotiation starts a new set of sequence numbers */ + DTLS1_BITMAP next_bitmap; + + /* handshake message numbers */ + unsigned short handshake_write_seq; + unsigned short next_handshake_write_seq; + + unsigned short handshake_read_seq; + + /* save last sequence number for retransmissions */ + unsigned char last_write_sequence[8]; + + /* Received handshake records (processed and unprocessed) */ + record_pqueue unprocessed_rcds; + record_pqueue processed_rcds; + + /* Buffered handshake messages */ + struct _pqueue *buffered_messages; + + /* Buffered (sent) handshake records */ + struct _pqueue *sent_messages; + + /* Buffered application records. + * Only for records between CCS and Finished + * to prevent either protocol violation or + * unnecessary message loss. + */ + record_pqueue buffered_app_data; + + /* Is set when listening for new connections with dtls1_listen() */ + unsigned int listen; + + unsigned int mtu; /* max DTLS packet size */ + + struct hm_header_st w_msg_hdr; + struct hm_header_st r_msg_hdr; + + struct dtls1_timeout_st timeout; + + /* Indicates when the last handshake msg or heartbeat sent will timeout */ + struct timeval next_timeout; + + /* Timeout duration */ + unsigned short timeout_duration; + + /* storage for Alert/Handshake protocol data received but not + * yet processed by ssl3_read_bytes: */ + unsigned char alert_fragment[DTLS1_AL_HEADER_LENGTH]; + unsigned int alert_fragment_len; + unsigned char handshake_fragment[DTLS1_HM_HEADER_LENGTH]; + unsigned int handshake_fragment_len; + + unsigned int retransmitting; + unsigned int change_cipher_spec_ok; + + +} DTLS1_STATE; + +typedef struct dtls1_record_data_st { + unsigned char *packet; + unsigned int packet_length; + SSL3_BUFFER rbuf; + SSL3_RECORD rrec; +} DTLS1_RECORD_DATA; + +#endif + +/* Timeout multipliers (timeout slice is defined in apps/timeouts.h */ +#define DTLS1_TMO_READ_COUNT 2 +#define DTLS1_TMO_WRITE_COUNT 2 + +#define DTLS1_TMO_ALERT_COUNT 12 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/ec.h b/crypto/libressl/include/openssl/ec.h new file mode 100644 index 0000000000..4284e37466 --- /dev/null +++ b/crypto/libressl/include/openssl/ec.h @@ -0,0 +1,1163 @@ +/* $OpenBSD: ec.h,v 1.10 2015/06/20 13:26:08 jsing Exp $ */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/** + * \file crypto/ec/ec.h Include file for the OpenSSL EC functions + * \author Originally written by Bodo Moeller for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#ifndef HEADER_EC_H +#define HEADER_EC_H + +#include + +#ifdef OPENSSL_NO_EC +#error EC is disabled. +#endif + +#include +#ifndef OPENSSL_NO_DEPRECATED +#include +#endif + +#ifdef __cplusplus +extern "C" { +#elif defined(__SUNPRO_C) +# if __SUNPRO_C >= 0x520 +# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) +# endif +#endif + + +#ifndef OPENSSL_ECC_MAX_FIELD_BITS +# define OPENSSL_ECC_MAX_FIELD_BITS 661 +#endif + +/** Enum for the point conversion form as defined in X9.62 (ECDSA) + * for the encoding of a elliptic curve point (x,y) */ +typedef enum { + /** the point is encoded as z||x, where the octet z specifies + * which solution of the quadratic equation y is */ + POINT_CONVERSION_COMPRESSED = 2, + /** the point is encoded as z||x||y, where z is the octet 0x02 */ + POINT_CONVERSION_UNCOMPRESSED = 4, + /** the point is encoded as z||x||y, where the octet z specifies + * which solution of the quadratic equation y is */ + POINT_CONVERSION_HYBRID = 6 +} point_conversion_form_t; + + +typedef struct ec_method_st EC_METHOD; + +typedef struct ec_group_st + /* + EC_METHOD *meth; + -- field definition + -- curve coefficients + -- optional generator with associated information (order, cofactor) + -- optional extra data (precomputed table for fast computation of multiples of generator) + -- ASN1 stuff + */ + EC_GROUP; + +typedef struct ec_point_st EC_POINT; + + +/********************************************************************/ +/* EC_METHODs for curves over GF(p) */ +/********************************************************************/ + +/** Returns the basic GFp ec methods which provides the basis for the + * optimized methods. + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_simple_method(void); + +/** Returns GFp methods using montgomery multiplication. + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_mont_method(void); + +/** Returns GFp methods using optimized methods for NIST recommended curves + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nist_method(void); + +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +/** Returns 64-bit optimized methods for nistp224 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp224_method(void); + +/** Returns 64-bit optimized methods for nistp256 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp256_method(void); + +/** Returns 64-bit optimized methods for nistp521 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp521_method(void); +#endif + +#ifndef OPENSSL_NO_EC2M +/********************************************************************/ +/* EC_METHOD for curves over GF(2^m) */ +/********************************************************************/ + +/** Returns the basic GF2m ec method + * \return EC_METHOD object + */ +const EC_METHOD *EC_GF2m_simple_method(void); + +#endif + + +/********************************************************************/ +/* EC_GROUP functions */ +/********************************************************************/ + +/** Creates a new EC_GROUP object + * \param meth EC_METHOD to use + * \return newly created EC_GROUP object or NULL in case of an error. + */ +EC_GROUP *EC_GROUP_new(const EC_METHOD *meth); + +/** Frees a EC_GROUP object + * \param group EC_GROUP object to be freed. + */ +void EC_GROUP_free(EC_GROUP *group); + +/** Clears and frees a EC_GROUP object + * \param group EC_GROUP object to be cleared and freed. + */ +void EC_GROUP_clear_free(EC_GROUP *group); + +/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD. + * \param dst destination EC_GROUP object + * \param src source EC_GROUP object + * \return 1 on success and 0 if an error occurred. + */ +int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src); + +/** Creates a new EC_GROUP object and copies the copies the content + * form src to the newly created EC_KEY object + * \param src source EC_GROUP object + * \return newly created EC_GROUP object or NULL in case of an error. + */ +EC_GROUP *EC_GROUP_dup(const EC_GROUP *src); + +/** Returns the EC_METHOD of the EC_GROUP object. + * \param group EC_GROUP object + * \return EC_METHOD used in this EC_GROUP object. + */ +const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group); + +/** Returns the field type of the EC_METHOD. + * \param meth EC_METHOD object + * \return NID of the underlying field type OID. + */ +int EC_METHOD_get_field_type(const EC_METHOD *meth); + +/** Sets the generator and it's order/cofactor of a EC_GROUP object. + * \param group EC_GROUP object + * \param generator EC_POINT object with the generator. + * \param order the order of the group generated by the generator. + * \param cofactor the index of the sub-group generated by the generator + * in the group of all points on the elliptic curve. + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor); + +/** Returns the generator of a EC_GROUP object. + * \param group EC_GROUP object + * \return the currently used generator (possibly NULL). + */ +const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group); + +/** Gets the order of a EC_GROUP + * \param group EC_GROUP object + * \param order BIGNUM to which the order is copied + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); + +/** Gets the cofactor of a EC_GROUP + * \param group EC_GROUP object + * \param cofactor BIGNUM to which the cofactor is copied + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx); + +/** Sets the name of a EC_GROUP object + * \param group EC_GROUP object + * \param nid NID of the curve name OID + */ +void EC_GROUP_set_curve_name(EC_GROUP *group, int nid); + +/** Returns the curve name of a EC_GROUP object + * \param group EC_GROUP object + * \return NID of the curve name OID or 0 if not set. + */ +int EC_GROUP_get_curve_name(const EC_GROUP *group); + +void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); +int EC_GROUP_get_asn1_flag(const EC_GROUP *group); + +void EC_GROUP_set_point_conversion_form(EC_GROUP *group, point_conversion_form_t form); +point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *); + +unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x); +size_t EC_GROUP_get_seed_len(const EC_GROUP *); +size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len); + +/** Sets the parameter of a ec over GFp defined by y^2 = x^3 + a*x + b + * \param group EC_GROUP object + * \param p BIGNUM with the prime number + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); + +/** Gets the parameter of the ec over GFp defined by y^2 = x^3 + a*x + b + * \param group EC_GROUP object + * \param p BIGNUM for the prime number + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx); + +#ifndef OPENSSL_NO_EC2M +/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b + * \param group EC_GROUP object + * \param p BIGNUM with the polynomial defining the underlying field + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); + +/** Gets the parameter of the ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b + * \param group EC_GROUP object + * \param p BIGNUM for the polynomial defining the underlying field + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx); +#endif +/** Returns the number of bits needed to represent a field element + * \param group EC_GROUP object + * \return number of bits needed to represent a field element + */ +int EC_GROUP_get_degree(const EC_GROUP *group); + +/** Checks whether the parameter in the EC_GROUP define a valid ec group + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 if group is a valid ec group and 0 otherwise + */ +int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx); + +/** Checks whether the discriminant of the elliptic curve is zero or not + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 if the discriminant is not zero and 0 otherwise + */ +int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx); + +/** Compares two EC_GROUP objects + * \param a first EC_GROUP object + * \param b second EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 0 if both groups are equal and 1 otherwise + */ +int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx); + +/* EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*() + * after choosing an appropriate EC_METHOD */ + +/** Creates a new EC_GROUP object with the specified parameters defined + * over GFp (defined by the equation y^2 = x^3 + a*x + b) + * \param p BIGNUM with the prime number + * \param a BIGNUM with the parameter a of the equation + * \param b BIGNUM with the parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return newly created EC_GROUP object with the specified parameters + */ +EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +#ifndef OPENSSL_NO_EC2M +/** Creates a new EC_GROUP object with the specified parameters defined + * over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b) + * \param p BIGNUM with the polynomial defining the underlying field + * \param a BIGNUM with the parameter a of the equation + * \param b BIGNUM with the parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return newly created EC_GROUP object with the specified parameters + */ +EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +#endif +/** Creates a EC_GROUP object with a curve specified by a NID + * \param nid NID of the OID of the curve name + * \return newly created EC_GROUP object with specified curve or NULL + * if an error occurred + */ +EC_GROUP *EC_GROUP_new_by_curve_name(int nid); + + +/********************************************************************/ +/* handling of internal curves */ +/********************************************************************/ + +typedef struct { + int nid; + const char *comment; + } EC_builtin_curve; + +/* EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number + * of all available curves or zero if a error occurred. + * In case r ist not zero nitems EC_builtin_curve structures + * are filled with the data of the first nitems internal groups */ +size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems); + +const char *EC_curve_nid2nist(int nid); +int EC_curve_nist2nid(const char *name); + +/********************************************************************/ +/* EC_POINT functions */ +/********************************************************************/ + +/** Creates a new EC_POINT object for the specified EC_GROUP + * \param group EC_GROUP the underlying EC_GROUP object + * \return newly created EC_POINT object or NULL if an error occurred + */ +EC_POINT *EC_POINT_new(const EC_GROUP *group); + +/** Frees a EC_POINT object + * \param point EC_POINT object to be freed + */ +void EC_POINT_free(EC_POINT *point); + +/** Clears and frees a EC_POINT object + * \param point EC_POINT object to be cleared and freed + */ +void EC_POINT_clear_free(EC_POINT *point); + +/** Copies EC_POINT object + * \param dst destination EC_POINT object + * \param src source EC_POINT object + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src); + +/** Creates a new EC_POINT object and copies the content of the supplied + * EC_POINT + * \param src source EC_POINT object + * \param group underlying the EC_GROUP object + * \return newly created EC_POINT object or NULL if an error occurred + */ +EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group); + +/** Returns the EC_METHOD used in EC_POINT object + * \param point EC_POINT object + * \return the EC_METHOD used + */ +const EC_METHOD *EC_POINT_method_of(const EC_POINT *point); + +/** Sets a point to infinity (neutral element) + * \param group underlying EC_GROUP object + * \param point EC_POINT to set to infinity + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point); + +/** Sets the jacobian projective coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param z BIGNUM with the z-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx); + +/** Gets the jacobian projective coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param z BIGNUM for the z-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx); + +/** Sets the affine coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx); + +/** Gets the affine coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx); + +/** Sets the x9.62 compressed coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, int y_bit, BN_CTX *ctx); +#ifndef OPENSSL_NO_EC2M +/** Sets the affine coordinates of a EC_POINT over GF2m + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx); + +/** Gets the affine coordinates of a EC_POINT over GF2m + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx); + +/** Sets the x9.62 compressed coordinates of a EC_POINT over GF2m + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, int y_bit, BN_CTX *ctx); +#endif +/** Encodes a EC_POINT object to a octet string + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param form point conversion form + * \param buf memory buffer for the result. If NULL the function returns + * required buffer size. + * \param len length of the memory buffer + * \param ctx BN_CTX object (optional) + * \return the length of the encoded octet string or 0 if an error occurred + */ +size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *ctx); + +/** Decodes a EC_POINT from a octet string + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param buf memory buffer with the encoded ec point + * \param len length of the encoded ec point + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p, + const unsigned char *buf, size_t len, BN_CTX *ctx); + +/* other interfaces to point2oct/oct2point: */ +BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BIGNUM *, BN_CTX *); +EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *, + EC_POINT *, BN_CTX *); +char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BN_CTX *); +EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *, + EC_POINT *, BN_CTX *); + + +/********************************************************************/ +/* functions for doing EC_POINT arithmetic */ +/********************************************************************/ + +/** Computes the sum of two EC_POINT + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result (r = a + b) + * \param a EC_POINT object with the first summand + * \param b EC_POINT object with the second summand + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx); + +/** Computes the double of a EC_POINT + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result (r = 2 * a) + * \param a EC_POINT object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx); + +/** Computes the inverse of a EC_POINT + * \param group underlying EC_GROUP object + * \param a EC_POINT object to be inverted (it's used for the result as well) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx); + +/** Checks whether the point is the neutral element of the group + * \param group the underlying EC_GROUP object + * \param p EC_POINT object + * \return 1 if the point is the neutral element and 0 otherwise + */ +int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p); + +/** Checks whether the point is on the curve + * \param group underlying EC_GROUP object + * \param point EC_POINT object to check + * \param ctx BN_CTX object (optional) + * \return 1 if point if on the curve and 0 otherwise + */ +int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx); + +/** Compares two EC_POINTs + * \param group underlying EC_GROUP object + * \param a first EC_POINT object + * \param b second EC_POINT object + * \param ctx BN_CTX object (optional) + * \return 0 if both points are equal and a value != 0 otherwise + */ +int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx); + +int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx); +int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx); + +/** Computes r = generator * n sum_{i=0}^num p[i] * m[i] + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result + * \param n BIGNUM with the multiplier for the group generator (optional) + * \param num number futher summands + * \param p array of size num of EC_POINT objects + * \param m array of size num of BIGNUM objects + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, size_t num, const EC_POINT *p[], const BIGNUM *m[], BN_CTX *ctx); + +/** Computes r = generator * n + q * m + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result + * \param n BIGNUM with the multiplier for the group generator (optional) + * \param q EC_POINT object with the first factor of the second summand + * \param m BIGNUM with the second factor of the second summand + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx); + +/** Stores multiples of generator for faster point multiplication + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx); + +/** Reports whether a precomputation has been done + * \param group EC_GROUP object + * \return 1 if a pre-computation has been done and 0 otherwise + */ +int EC_GROUP_have_precompute_mult(const EC_GROUP *group); + + +/********************************************************************/ +/* ASN1 stuff */ +/********************************************************************/ + +/* EC_GROUP_get_basis_type() returns the NID of the basis type + * used to represent the field elements */ +int EC_GROUP_get_basis_type(const EC_GROUP *); +#ifndef OPENSSL_NO_EC2M +int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k); +int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1, + unsigned int *k2, unsigned int *k3); +#endif + +#define OPENSSL_EC_NAMED_CURVE 0x001 + +typedef struct ecpk_parameters_st ECPKPARAMETERS; + +EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len); +int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out); + +#define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x) +#define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x) +#define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \ + (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x)) +#define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \ + (unsigned char *)(x)) + +#ifndef OPENSSL_NO_BIO +int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off); +#endif +int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off); + + +/********************************************************************/ +/* EC_KEY functions */ +/********************************************************************/ + +typedef struct ec_key_st EC_KEY; + +/* some values for the encoding_flag */ +#define EC_PKEY_NO_PARAMETERS 0x001 +#define EC_PKEY_NO_PUBKEY 0x002 + +/* some values for the flags field */ +#define EC_FLAG_NON_FIPS_ALLOW 0x1 +#define EC_FLAG_FIPS_CHECKED 0x2 + +/** Creates a new EC_KEY object. + * \return EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_new(void); + +int EC_KEY_get_flags(const EC_KEY *key); + +void EC_KEY_set_flags(EC_KEY *key, int flags); + +void EC_KEY_clear_flags(EC_KEY *key, int flags); + +/** Creates a new EC_KEY object using a named curve as underlying + * EC_GROUP object. + * \param nid NID of the named curve. + * \return EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_new_by_curve_name(int nid); + +/** Frees a EC_KEY object. + * \param key EC_KEY object to be freed. + */ +void EC_KEY_free(EC_KEY *key); + +/** Copies a EC_KEY object. + * \param dst destination EC_KEY object + * \param src src EC_KEY object + * \return dst or NULL if an error occurred. + */ +EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src); + +/** Creates a new EC_KEY object and copies the content from src to it. + * \param src the source EC_KEY object + * \return newly created EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_dup(const EC_KEY *src); + +/** Increases the internal reference count of a EC_KEY object. + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_up_ref(EC_KEY *key); + +/** Returns the EC_GROUP object of a EC_KEY object + * \param key EC_KEY object + * \return the EC_GROUP object (possibly NULL). + */ +const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key); + +/** Sets the EC_GROUP of a EC_KEY object. + * \param key EC_KEY object + * \param group EC_GROUP to use in the EC_KEY object (note: the EC_KEY + * object will use an own copy of the EC_GROUP). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group); + +/** Returns the private key of a EC_KEY object. + * \param key EC_KEY object + * \return a BIGNUM with the private key (possibly NULL). + */ +const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key); + +/** Sets the private key of a EC_KEY object. + * \param key EC_KEY object + * \param prv BIGNUM with the private key (note: the EC_KEY object + * will use an own copy of the BIGNUM). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv); + +/** Returns the public key of a EC_KEY object. + * \param key the EC_KEY object + * \return a EC_POINT object with the public key (possibly NULL) + */ +const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key); + +/** Sets the public key of a EC_KEY object. + * \param key EC_KEY object + * \param pub EC_POINT object with the public key (note: the EC_KEY object + * will use an own copy of the EC_POINT object). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); + +unsigned EC_KEY_get_enc_flags(const EC_KEY *key); +void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags); +point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key); +void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform); +/* functions to set/get method specific data */ +void *EC_KEY_get_key_method_data(EC_KEY *key, + void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)); +/** Sets the key method data of an EC_KEY object, if none has yet been set. + * \param key EC_KEY object + * \param data opaque data to install. + * \param dup_func a function that duplicates |data|. + * \param free_func a function that frees |data|. + * \param clear_free_func a function that wipes and frees |data|. + * \return the previously set data pointer, or NULL if |data| was inserted. + */ +void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data, + void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)); +/* wrapper functions for the underlying EC_GROUP object */ +void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag); + +/** Creates a table of pre-computed multiples of the generator to + * accelerate further EC_KEY operations. + * \param key EC_KEY object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx); + +/** Creates a new ec private (and optional a new public) key. + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_generate_key(EC_KEY *key); + +/** Verifies that a private and/or public key is valid. + * \param key the EC_KEY object + * \return 1 on success and 0 otherwise. + */ +int EC_KEY_check_key(const EC_KEY *key); + +/** Sets a public key from affine coordindates performing + * neccessary NIST PKV tests. + * \param key the EC_KEY object + * \param x public key x coordinate + * \param y public key y coordinate + * \return 1 on success and 0 otherwise. + */ +int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y); + + +/********************************************************************/ +/* de- and encoding functions for SEC1 ECPrivateKey */ +/********************************************************************/ + +/** Decodes a private key from a memory buffer. + * \param key a pointer to a EC_KEY object which should be used (or NULL) + * \param in pointer to memory with the DER encoded private key + * \param len length of the DER encoded private key + * \return the decoded private key or NULL if an error occurred. + */ +EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes a private key object and stores the result in a buffer. + * \param key the EC_KEY object to encode + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred. + */ +int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out); + + +/********************************************************************/ +/* de- and encoding functions for EC parameters */ +/********************************************************************/ + +/** Decodes ec parameter from a memory buffer. + * \param key a pointer to a EC_KEY object which should be used (or NULL) + * \param in pointer to memory with the DER encoded ec parameters + * \param len length of the DER encoded ec parameters + * \return a EC_KEY object with the decoded parameters or NULL if an error + * occurred. + */ +EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes ec parameter and stores the result in a buffer. + * \param key the EC_KEY object with ec paramters to encode + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred. + */ +int i2d_ECParameters(EC_KEY *key, unsigned char **out); + + +/********************************************************************/ +/* de- and encoding functions for EC public key */ +/* (octet string, not DER -- hence 'o2i' and 'i2o') */ +/********************************************************************/ + +/** Decodes a ec public key from a octet string. + * \param key a pointer to a EC_KEY object which should be used + * \param in memory buffer with the encoded public key + * \param len length of the encoded public key + * \return EC_KEY object with decoded public key or NULL if an error + * occurred. + */ +EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes a ec public key in an octet string. + * \param key the EC_KEY object with the public key + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred + */ +int i2o_ECPublicKey(EC_KEY *key, unsigned char **out); + +#ifndef OPENSSL_NO_BIO +/** Prints out the ec parameters on human readable form. + * \param bp BIO object to which the information is printed + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred + */ +int ECParameters_print(BIO *bp, const EC_KEY *key); + +/** Prints out the contents of a EC_KEY object + * \param bp BIO object to which the information is printed + * \param key EC_KEY object + * \param off line offset + * \return 1 on success and 0 if an error occurred + */ +int EC_KEY_print(BIO *bp, const EC_KEY *key, int off); + +#endif +/** Prints out the ec parameters on human readable form. + * \param fp file descriptor to which the information is printed + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred + */ +int ECParameters_print_fp(FILE *fp, const EC_KEY *key); + +/** Prints out the contents of a EC_KEY object + * \param fp file descriptor to which the information is printed + * \param key EC_KEY object + * \param off line offset + * \return 1 on success and 0 if an error occurred + */ +int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off); + +EC_KEY *ECParameters_dup(EC_KEY *key); + +#ifndef __cplusplus +#if defined(__SUNPRO_C) +# if __SUNPRO_C >= 0x520 +# pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) +# endif +# endif +#endif + +#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL) + + +#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1) + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_EC_strings(void); + +/* Error codes for the EC functions. */ + +/* Function codes. */ +#define EC_F_BN_TO_FELEM 224 +#define EC_F_COMPUTE_WNAF 143 +#define EC_F_D2I_ECPARAMETERS 144 +#define EC_F_D2I_ECPKPARAMETERS 145 +#define EC_F_D2I_ECPRIVATEKEY 146 +#define EC_F_DO_EC_KEY_PRINT 221 +#define EC_F_ECKEY_PARAM2TYPE 223 +#define EC_F_ECKEY_PARAM_DECODE 212 +#define EC_F_ECKEY_PRIV_DECODE 213 +#define EC_F_ECKEY_PRIV_ENCODE 214 +#define EC_F_ECKEY_PUB_DECODE 215 +#define EC_F_ECKEY_PUB_ENCODE 216 +#define EC_F_ECKEY_TYPE2PARAM 220 +#define EC_F_ECPARAMETERS_PRINT 147 +#define EC_F_ECPARAMETERS_PRINT_FP 148 +#define EC_F_ECPKPARAMETERS_PRINT 149 +#define EC_F_ECPKPARAMETERS_PRINT_FP 150 +#define EC_F_ECP_NIST_MOD_192 203 +#define EC_F_ECP_NIST_MOD_224 204 +#define EC_F_ECP_NIST_MOD_256 205 +#define EC_F_ECP_NIST_MOD_521 206 +#define EC_F_EC_ASN1_GROUP2CURVE 153 +#define EC_F_EC_ASN1_GROUP2FIELDID 154 +#define EC_F_EC_ASN1_GROUP2PARAMETERS 155 +#define EC_F_EC_ASN1_GROUP2PKPARAMETERS 156 +#define EC_F_EC_ASN1_PARAMETERS2GROUP 157 +#define EC_F_EC_ASN1_PKPARAMETERS2GROUP 158 +#define EC_F_EC_EX_DATA_SET_DATA 211 +#define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY 208 +#define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT 159 +#define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE 195 +#define EC_F_EC_GF2M_SIMPLE_OCT2POINT 160 +#define EC_F_EC_GF2M_SIMPLE_POINT2OCT 161 +#define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162 +#define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163 +#define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES 164 +#define EC_F_EC_GFP_MONT_FIELD_DECODE 133 +#define EC_F_EC_GFP_MONT_FIELD_ENCODE 134 +#define EC_F_EC_GFP_MONT_FIELD_MUL 131 +#define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE 209 +#define EC_F_EC_GFP_MONT_FIELD_SQR 132 +#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE 189 +#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP 135 +#define EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE 225 +#define EC_F_EC_GFP_NISTP224_POINTS_MUL 228 +#define EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES 226 +#define EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE 230 +#define EC_F_EC_GFP_NISTP256_POINTS_MUL 231 +#define EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES 232 +#define EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE 233 +#define EC_F_EC_GFP_NISTP521_POINTS_MUL 234 +#define EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES 235 +#define EC_F_EC_GFP_NIST_FIELD_MUL 200 +#define EC_F_EC_GFP_NIST_FIELD_SQR 201 +#define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202 +#define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165 +#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166 +#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP 100 +#define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR 101 +#define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102 +#define EC_F_EC_GFP_SIMPLE_OCT2POINT 103 +#define EC_F_EC_GFP_SIMPLE_POINT2OCT 104 +#define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE 137 +#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES 167 +#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105 +#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES 168 +#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128 +#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES 169 +#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129 +#define EC_F_EC_GROUP_CHECK 170 +#define EC_F_EC_GROUP_CHECK_DISCRIMINANT 171 +#define EC_F_EC_GROUP_COPY 106 +#define EC_F_EC_GROUP_GET0_GENERATOR 139 +#define EC_F_EC_GROUP_GET_COFACTOR 140 +#define EC_F_EC_GROUP_GET_CURVE_GF2M 172 +#define EC_F_EC_GROUP_GET_CURVE_GFP 130 +#define EC_F_EC_GROUP_GET_DEGREE 173 +#define EC_F_EC_GROUP_GET_ORDER 141 +#define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS 193 +#define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS 194 +#define EC_F_EC_GROUP_NEW 108 +#define EC_F_EC_GROUP_NEW_BY_CURVE_NAME 174 +#define EC_F_EC_GROUP_NEW_FROM_DATA 175 +#define EC_F_EC_GROUP_PRECOMPUTE_MULT 142 +#define EC_F_EC_GROUP_SET_CURVE_GF2M 176 +#define EC_F_EC_GROUP_SET_CURVE_GFP 109 +#define EC_F_EC_GROUP_SET_EXTRA_DATA 110 +#define EC_F_EC_GROUP_SET_GENERATOR 111 +#define EC_F_EC_KEY_CHECK_KEY 177 +#define EC_F_EC_KEY_COPY 178 +#define EC_F_EC_KEY_GENERATE_KEY 179 +#define EC_F_EC_KEY_NEW 182 +#define EC_F_EC_KEY_PRINT 180 +#define EC_F_EC_KEY_PRINT_FP 181 +#define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES 229 +#define EC_F_EC_POINTS_MAKE_AFFINE 136 +#define EC_F_EC_POINT_ADD 112 +#define EC_F_EC_POINT_CMP 113 +#define EC_F_EC_POINT_COPY 114 +#define EC_F_EC_POINT_DBL 115 +#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M 183 +#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 116 +#define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 117 +#define EC_F_EC_POINT_INVERT 210 +#define EC_F_EC_POINT_IS_AT_INFINITY 118 +#define EC_F_EC_POINT_IS_ON_CURVE 119 +#define EC_F_EC_POINT_MAKE_AFFINE 120 +#define EC_F_EC_POINT_MUL 184 +#define EC_F_EC_POINT_NEW 121 +#define EC_F_EC_POINT_OCT2POINT 122 +#define EC_F_EC_POINT_POINT2OCT 123 +#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M 185 +#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 124 +#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M 186 +#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP 125 +#define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126 +#define EC_F_EC_POINT_SET_TO_INFINITY 127 +#define EC_F_EC_PRE_COMP_DUP 207 +#define EC_F_EC_PRE_COMP_NEW 196 +#define EC_F_EC_WNAF_MUL 187 +#define EC_F_EC_WNAF_PRECOMPUTE_MULT 188 +#define EC_F_I2D_ECPARAMETERS 190 +#define EC_F_I2D_ECPKPARAMETERS 191 +#define EC_F_I2D_ECPRIVATEKEY 192 +#define EC_F_I2O_ECPUBLICKEY 151 +#define EC_F_NISTP224_PRE_COMP_NEW 227 +#define EC_F_NISTP256_PRE_COMP_NEW 236 +#define EC_F_NISTP521_PRE_COMP_NEW 237 +#define EC_F_O2I_ECPUBLICKEY 152 +#define EC_F_OLD_EC_PRIV_DECODE 222 +#define EC_F_PKEY_EC_CTRL 197 +#define EC_F_PKEY_EC_CTRL_STR 198 +#define EC_F_PKEY_EC_DERIVE 217 +#define EC_F_PKEY_EC_KEYGEN 199 +#define EC_F_PKEY_EC_PARAMGEN 219 +#define EC_F_PKEY_EC_SIGN 218 + +/* Reason codes. */ +#define EC_R_ASN1_ERROR 115 +#define EC_R_ASN1_UNKNOWN_FIELD 116 +#define EC_R_BIGNUM_OUT_OF_RANGE 144 +#define EC_R_BUFFER_TOO_SMALL 100 +#define EC_R_COORDINATES_OUT_OF_RANGE 146 +#define EC_R_D2I_ECPKPARAMETERS_FAILURE 117 +#define EC_R_DECODE_ERROR 142 +#define EC_R_DISCRIMINANT_IS_ZERO 118 +#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119 +#define EC_R_FIELD_TOO_LARGE 143 +#define EC_R_GF2M_NOT_SUPPORTED 147 +#define EC_R_GROUP2PKPARAMETERS_FAILURE 120 +#define EC_R_I2D_ECPKPARAMETERS_FAILURE 121 +#define EC_R_INCOMPATIBLE_OBJECTS 101 +#define EC_R_INVALID_ARGUMENT 112 +#define EC_R_INVALID_COMPRESSED_POINT 110 +#define EC_R_INVALID_COMPRESSION_BIT 109 +#define EC_R_INVALID_CURVE 141 +#define EC_R_INVALID_DIGEST_TYPE 138 +#define EC_R_INVALID_ENCODING 102 +#define EC_R_INVALID_FIELD 103 +#define EC_R_INVALID_FORM 104 +#define EC_R_INVALID_GROUP_ORDER 122 +#define EC_R_INVALID_PENTANOMIAL_BASIS 132 +#define EC_R_INVALID_PRIVATE_KEY 123 +#define EC_R_INVALID_TRINOMIAL_BASIS 137 +#define EC_R_KEYS_NOT_SET 140 +#define EC_R_MISSING_PARAMETERS 124 +#define EC_R_MISSING_PRIVATE_KEY 125 +#define EC_R_NOT_A_NIST_PRIME 135 +#define EC_R_NOT_A_SUPPORTED_NIST_PRIME 136 +#define EC_R_NOT_IMPLEMENTED 126 +#define EC_R_NOT_INITIALIZED 111 +#define EC_R_NO_FIELD_MOD 133 +#define EC_R_NO_PARAMETERS_SET 139 +#define EC_R_PASSED_NULL_PARAMETER 134 +#define EC_R_PKPARAMETERS2GROUP_FAILURE 127 +#define EC_R_POINT_AT_INFINITY 106 +#define EC_R_POINT_IS_NOT_ON_CURVE 107 +#define EC_R_SLOT_FULL 108 +#define EC_R_UNDEFINED_GENERATOR 113 +#define EC_R_UNDEFINED_ORDER 128 +#define EC_R_UNKNOWN_GROUP 129 +#define EC_R_UNKNOWN_ORDER 114 +#define EC_R_UNSUPPORTED_FIELD 131 +#define EC_R_WRONG_CURVE_PARAMETERS 145 +#define EC_R_WRONG_ORDER 130 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/ecdh.h b/crypto/libressl/include/openssl/ecdh.h new file mode 100644 index 0000000000..4990cf5753 --- /dev/null +++ b/crypto/libressl/include/openssl/ecdh.h @@ -0,0 +1,128 @@ +/* $OpenBSD: ecdh.h,v 1.4 2015/09/13 11:49:44 jsing Exp $ */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The ECDH software is originally written by Douglas Stebila of + * Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 2000-2002 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_ECDH_H +#define HEADER_ECDH_H + +#include + +#ifdef OPENSSL_NO_ECDH +#error ECDH is disabled. +#endif + +#include +#include +#ifndef OPENSSL_NO_DEPRECATED +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +const ECDH_METHOD *ECDH_OpenSSL(void); + +void ECDH_set_default_method(const ECDH_METHOD *); +const ECDH_METHOD *ECDH_get_default_method(void); +int ECDH_set_method(EC_KEY *, const ECDH_METHOD *); + +int ECDH_size(const EC_KEY *ecdh); +int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, + EC_KEY *ecdh, + void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen)); + +int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new +*new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg); +void *ECDH_get_ex_data(EC_KEY *d, int idx); + + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_ECDH_strings(void); + +/* Error codes for the ECDH functions. */ + +/* Function codes. */ +#define ECDH_F_ECDH_CHECK 102 +#define ECDH_F_ECDH_COMPUTE_KEY 100 +#define ECDH_F_ECDH_DATA_NEW_METHOD 101 + +/* Reason codes. */ +#define ECDH_R_KDF_FAILED 102 +#define ECDH_R_KEY_TRUNCATION 104 +#define ECDH_R_NON_FIPS_METHOD 103 +#define ECDH_R_NO_PRIVATE_VALUE 100 +#define ECDH_R_POINT_ARITHMETIC_FAILURE 101 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/ecdsa.h b/crypto/libressl/include/openssl/ecdsa.h new file mode 100644 index 0000000000..c39f29d228 --- /dev/null +++ b/crypto/libressl/include/openssl/ecdsa.h @@ -0,0 +1,286 @@ +/* $OpenBSD: ecdsa.h,v 1.3 2014/11/17 20:25:50 miod Exp $ */ +/** + * \file crypto/ecdsa/ecdsa.h Include file for the OpenSSL ECDSA functions + * \author Written by Nils Larsch for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_ECDSA_H +#define HEADER_ECDSA_H + +#include + +#ifdef OPENSSL_NO_ECDSA +#error ECDSA is disabled. +#endif + +#include +#include +#ifndef OPENSSL_NO_DEPRECATED +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ECDSA_SIG_st ECDSA_SIG; + +struct ecdsa_method { + const char *name; + ECDSA_SIG *(*ecdsa_do_sign)(const unsigned char *dgst, int dgst_len, + const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey); + int (*ecdsa_sign_setup)(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, + BIGNUM **r); + int (*ecdsa_do_verify)(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey); +#if 0 + int (*init)(EC_KEY *eckey); + int (*finish)(EC_KEY *eckey); +#endif + int flags; + char *app_data; +}; + +/* If this flag is set the ECDSA method is FIPS compliant and can be used + * in FIPS mode. This is set in the validated module method. If an + * application sets this flag in its own methods it is its responsibility + * to ensure the result is compliant. + */ + +#define ECDSA_FLAG_FIPS_METHOD 0x1 + +struct ECDSA_SIG_st { + BIGNUM *r; + BIGNUM *s; +}; + +/** Allocates and initialize a ECDSA_SIG structure + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_SIG_new(void); + +/** frees a ECDSA_SIG structure + * \param sig pointer to the ECDSA_SIG structure + */ +void ECDSA_SIG_free(ECDSA_SIG *sig); + +/** DER encode content of ECDSA_SIG object (note: this function modifies *pp + * (*pp += length of the DER encoded signature)). + * \param sig pointer to the ECDSA_SIG object + * \param pp pointer to a unsigned char pointer for the output or NULL + * \return the length of the DER encoded ECDSA_SIG object or 0 + */ +int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp); + +/** Decodes a DER encoded ECDSA signature (note: this function changes *pp + * (*pp += len)). + * \param sig pointer to ECDSA_SIG pointer (may be NULL) + * \param pp memory buffer with the DER encoded signature + * \param len length of the buffer + * \return pointer to the decoded ECDSA_SIG structure (or NULL) + */ +ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len); + +/** Computes the ECDSA signature of the given hash value using + * the supplied private key and returns the created signature. + * \param dgst pointer to the hash value + * \param dgst_len length of the hash value + * \param eckey EC_KEY object containing a private EC key + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dgst_len, + EC_KEY *eckey); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param kinv BIGNUM with a pre-computed inverse k (optional) + * \param rp BIGNUM with a pre-computed rp value (optioanl), + * see ECDSA_sign_setup + * \param eckey EC_KEY object containing a private EC key + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, + const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey); + +/** Verifies that the supplied signature is a valid ECDSA + * signature of the supplied hash value using the supplied public key. + * \param dgst pointer to the hash value + * \param dgst_len length of the hash value + * \param sig ECDSA_SIG structure + * \param eckey EC_KEY object containing a public EC key + * \return 1 if the signature is valid, 0 if the signature is invalid + * and -1 on error + */ +int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY* eckey); + +const ECDSA_METHOD *ECDSA_OpenSSL(void); + +/** Sets the default ECDSA method + * \param meth new default ECDSA_METHOD + */ +void ECDSA_set_default_method(const ECDSA_METHOD *meth); + +/** Returns the default ECDSA method + * \return pointer to ECDSA_METHOD structure containing the default method + */ +const ECDSA_METHOD *ECDSA_get_default_method(void); + +/** Sets method to be used for the ECDSA operations + * \param eckey EC_KEY object + * \param meth new method + * \return 1 on success and 0 otherwise + */ +int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth); + +/** Returns the maximum length of the DER encoded signature + * \param eckey EC_KEY object + * \return numbers of bytes required for the DER encoded signature + */ +int ECDSA_size(const EC_KEY *eckey); + +/** Precompute parts of the signing operation + * \param eckey EC_KEY object containing a private EC key + * \param ctx BN_CTX object (optional) + * \param kinv BIGNUM pointer for the inverse of k + * \param rp BIGNUM pointer for x coordinate of k * generator + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, + BIGNUM **rp); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param type this parameter is ignored + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param sig memory for the DER encoded created signature + * \param siglen pointer to the length of the returned signature + * \param eckey EC_KEY object containing a private EC key + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, EC_KEY *eckey); + + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param type this parameter is ignored + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param sig buffer to hold the DER encoded signature + * \param siglen pointer to the length of the returned signature + * \param kinv BIGNUM with a pre-computed inverse k (optional) + * \param rp BIGNUM with a pre-computed rp value (optioanl), + * see ECDSA_sign_setup + * \param eckey EC_KEY object containing a private EC key + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, + const BIGNUM *rp, EC_KEY *eckey); + +/** Verifies that the given signature is valid ECDSA signature + * of the supplied hash value using the specified public key. + * \param type this parameter is ignored + * \param dgst pointer to the hash value + * \param dgstlen length of the hash value + * \param sig pointer to the DER encoded signature + * \param siglen length of the DER encoded signature + * \param eckey EC_KEY object containing a public EC key + * \return 1 if the signature is valid, 0 if the signature is invalid + * and -1 on error + */ +int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, + const unsigned char *sig, int siglen, EC_KEY *eckey); + +/* the standard ex_data functions */ +int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg); +void *ECDSA_get_ex_data(EC_KEY *d, int idx); + + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_ECDSA_strings(void); + +/* Error codes for the ECDSA functions. */ + +/* Function codes. */ +#define ECDSA_F_ECDSA_CHECK 104 +#define ECDSA_F_ECDSA_DATA_NEW_METHOD 100 +#define ECDSA_F_ECDSA_DO_SIGN 101 +#define ECDSA_F_ECDSA_DO_VERIFY 102 +#define ECDSA_F_ECDSA_SIGN_SETUP 103 + +/* Reason codes. */ +#define ECDSA_R_BAD_SIGNATURE 100 +#define ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 101 +#define ECDSA_R_ERR_EC_LIB 102 +#define ECDSA_R_MISSING_PARAMETERS 103 +#define ECDSA_R_NEED_NEW_SETUP_VALUES 106 +#define ECDSA_R_NON_FIPS_METHOD 107 +#define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED 104 +#define ECDSA_R_SIGNATURE_MALLOC_FAILED 105 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/engine.h b/crypto/libressl/include/openssl/engine.h new file mode 100644 index 0000000000..dd084d1b23 --- /dev/null +++ b/crypto/libressl/include/openssl/engine.h @@ -0,0 +1,807 @@ +/* $OpenBSD: engine.h,v 1.30 2014/10/18 17:20:40 jsing Exp $ */ +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_ENGINE_H +#define HEADER_ENGINE_H + +#include + +#ifdef OPENSSL_NO_ENGINE +#error ENGINE is disabled. +#endif + +#ifndef OPENSSL_NO_DEPRECATED +#include +#ifndef OPENSSL_NO_RSA +#include +#endif +#ifndef OPENSSL_NO_DSA +#include +#endif +#ifndef OPENSSL_NO_DH +#include +#endif +#ifndef OPENSSL_NO_ECDH +#include +#endif +#ifndef OPENSSL_NO_ECDSA +#include +#endif +#include +#include +#endif + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* These flags are used to control combinations of algorithm (methods) + * by bitwise "OR"ing. */ +#define ENGINE_METHOD_RSA (unsigned int)0x0001 +#define ENGINE_METHOD_DSA (unsigned int)0x0002 +#define ENGINE_METHOD_DH (unsigned int)0x0004 +#define ENGINE_METHOD_RAND (unsigned int)0x0008 +#define ENGINE_METHOD_ECDH (unsigned int)0x0010 +#define ENGINE_METHOD_ECDSA (unsigned int)0x0020 +#define ENGINE_METHOD_CIPHERS (unsigned int)0x0040 +#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080 +#define ENGINE_METHOD_STORE (unsigned int)0x0100 +#define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200 +#define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400 +/* Obvious all-or-nothing cases. */ +#define ENGINE_METHOD_ALL (unsigned int)0xFFFF +#define ENGINE_METHOD_NONE (unsigned int)0x0000 + +/* This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used + * internally to control registration of ENGINE implementations, and can be set + * by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to + * initialise registered ENGINEs if they are not already initialised. */ +#define ENGINE_TABLE_FLAG_NOINIT (unsigned int)0x0001 + +/* ENGINE flags that can be set by ENGINE_set_flags(). */ +/* #define ENGINE_FLAGS_MALLOCED 0x0001 */ /* Not used */ + +/* This flag is for ENGINEs that wish to handle the various 'CMD'-related + * control commands on their own. Without this flag, ENGINE_ctrl() handles these + * control commands on behalf of the ENGINE using their "cmd_defns" data. */ +#define ENGINE_FLAGS_MANUAL_CMD_CTRL (int)0x0002 + +/* This flag is for ENGINEs who return new duplicate structures when found via + * "ENGINE_by_id()". When an ENGINE must store state (eg. if ENGINE_ctrl() + * commands are called in sequence as part of some stateful process like + * key-generation setup and execution), it can set this flag - then each attempt + * to obtain the ENGINE will result in it being copied into a new structure. + * Normally, ENGINEs don't declare this flag so ENGINE_by_id() just increments + * the existing ENGINE's structural reference count. */ +#define ENGINE_FLAGS_BY_ID_COPY (int)0x0004 + +/* This flag if for an ENGINE that does not want its methods registered as + * part of ENGINE_register_all_complete() for example if the methods are + * not usable as default methods. + */ + +#define ENGINE_FLAGS_NO_REGISTER_ALL (int)0x0008 + +/* ENGINEs can support their own command types, and these flags are used in + * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input each + * command expects. Currently only numeric and string input is supported. If a + * control command supports none of the _NUMERIC, _STRING, or _NO_INPUT options, + * then it is regarded as an "internal" control command - and not for use in + * config setting situations. As such, they're not available to the + * ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() access. Changes to + * this list of 'command types' should be reflected carefully in + * ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). */ + +/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */ +#define ENGINE_CMD_FLAG_NUMERIC (unsigned int)0x0001 +/* accepts string input (cast from 'void*' to 'const char *', 4th parameter to + * ENGINE_ctrl) */ +#define ENGINE_CMD_FLAG_STRING (unsigned int)0x0002 +/* Indicates that the control command takes *no* input. Ie. the control command + * is unparameterised. */ +#define ENGINE_CMD_FLAG_NO_INPUT (unsigned int)0x0004 +/* Indicates that the control command is internal. This control command won't + * be shown in any output, and is only usable through the ENGINE_ctrl_cmd() + * function. */ +#define ENGINE_CMD_FLAG_INTERNAL (unsigned int)0x0008 + +/* NB: These 3 control commands are deprecated and should not be used. ENGINEs + * relying on these commands should compile conditional support for + * compatibility (eg. if these symbols are defined) but should also migrate the + * same functionality to their own ENGINE-specific control functions that can be + * "discovered" by calling applications. The fact these control commands + * wouldn't be "executable" (ie. usable by text-based config) doesn't change the + * fact that application code can find and use them without requiring per-ENGINE + * hacking. */ + +/* These flags are used to tell the ctrl function what should be done. + * All command numbers are shared between all engines, even if some don't + * make sense to some engines. In such a case, they do nothing but return + * the error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. */ +#define ENGINE_CTRL_SET_LOGSTREAM 1 +#define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2 +#define ENGINE_CTRL_HUP 3 /* Close and reinitialise any + handles/connections etc. */ +#define ENGINE_CTRL_SET_USER_INTERFACE 4 /* Alternative to callback */ +#define ENGINE_CTRL_SET_CALLBACK_DATA 5 /* User-specific data, used + when calling the password + callback and the user + interface */ +#define ENGINE_CTRL_LOAD_CONFIGURATION 6 /* Load a configuration, given + a string that represents a + file name or so */ +#define ENGINE_CTRL_LOAD_SECTION 7 /* Load data from a given + section in the already loaded + configuration */ + +/* These control commands allow an application to deal with an arbitrary engine + * in a dynamic way. Warn: Negative return values indicate errors FOR THESE + * COMMANDS because zero is used to indicate 'end-of-list'. Other commands, + * including ENGINE-specific command types, return zero for an error. + * + * An ENGINE can choose to implement these ctrl functions, and can internally + * manage things however it chooses - it does so by setting the + * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise the + * ENGINE_ctrl() code handles this on the ENGINE's behalf using the cmd_defns + * data (set using ENGINE_set_cmd_defns()). This means an ENGINE's ctrl() + * handler need only implement its own commands - the above "meta" commands will + * be taken care of. */ + +/* Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", then + * all the remaining control commands will return failure, so it is worth + * checking this first if the caller is trying to "discover" the engine's + * capabilities and doesn't want errors generated unnecessarily. */ +#define ENGINE_CTRL_HAS_CTRL_FUNCTION 10 +/* Returns a positive command number for the first command supported by the + * engine. Returns zero if no ctrl commands are supported. */ +#define ENGINE_CTRL_GET_FIRST_CMD_TYPE 11 +/* The 'long' argument specifies a command implemented by the engine, and the + * return value is the next command supported, or zero if there are no more. */ +#define ENGINE_CTRL_GET_NEXT_CMD_TYPE 12 +/* The 'void*' argument is a command name (cast from 'const char *'), and the + * return value is the command that corresponds to it. */ +#define ENGINE_CTRL_GET_CMD_FROM_NAME 13 +/* The next two allow a command to be converted into its corresponding string + * form. In each case, the 'long' argument supplies the command. In the NAME_LEN + * case, the return value is the length of the command name (not counting a + * trailing EOL). In the NAME case, the 'void*' argument must be a string buffer + * large enough, and it will be populated with the name of the command (WITH a + * trailing EOL). */ +#define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD 14 +#define ENGINE_CTRL_GET_NAME_FROM_CMD 15 +/* The next two are similar but give a "short description" of a command. */ +#define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD 16 +#define ENGINE_CTRL_GET_DESC_FROM_CMD 17 +/* With this command, the return value is the OR'd combination of + * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given + * engine-specific ctrl command expects. */ +#define ENGINE_CTRL_GET_CMD_FLAGS 18 + +/* ENGINE implementations should start the numbering of their own control + * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). */ +#define ENGINE_CMD_BASE 200 + +/* If an ENGINE supports its own specific control commands and wishes the + * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on its + * behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN entries + * to ENGINE_set_cmd_defns(). It should also implement a ctrl() handler that + * supports the stated commands (ie. the "cmd_num" entries as described by the + * array). NB: The array must be ordered in increasing order of cmd_num. + * "null-terminated" means that the last ENGINE_CMD_DEFN element has cmd_num set + * to zero and/or cmd_name set to NULL. */ +typedef struct ENGINE_CMD_DEFN_st { + unsigned int cmd_num; /* The command number */ + const char *cmd_name; /* The command name itself */ + const char *cmd_desc; /* A short description of the command */ + unsigned int cmd_flags; /* The input the command expects */ +} ENGINE_CMD_DEFN; + +/* Generic function pointer */ +typedef int (*ENGINE_GEN_FUNC_PTR)(void); +/* Generic function pointer taking no arguments */ +typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *); +/* Specific control function pointer */ +typedef int (*ENGINE_CTRL_FUNC_PTR)(ENGINE *, int, long, void *, + void (*f)(void)); +/* Generic load_key function pointer */ +typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *, + UI_METHOD *ui_method, void *callback_data); +typedef int (*ENGINE_SSL_CLIENT_CERT_PTR)(ENGINE *, SSL *ssl, + STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey, + STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data); + +/* These callback types are for an ENGINE's handler for cipher and digest logic. + * These handlers have these prototypes; + * int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid); + * int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid); + * Looking at how to implement these handlers in the case of cipher support, if + * the framework wants the EVP_CIPHER for 'nid', it will call; + * foo(e, &p_evp_cipher, NULL, nid); (return zero for failure) + * If the framework wants a list of supported 'nid's, it will call; + * foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error) + */ +/* Returns to a pointer to the array of supported cipher 'nid's. If the second + * parameter is non-NULL it is set to the size of the returned array. */ +typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, + const int **, int); +typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int); +typedef int (*ENGINE_PKEY_METHS_PTR)(ENGINE *, EVP_PKEY_METHOD **, + const int **, int); +typedef int (*ENGINE_PKEY_ASN1_METHS_PTR)(ENGINE *, EVP_PKEY_ASN1_METHOD **, + const int **, int); + +/* STRUCTURE functions ... all of these functions deal with pointers to ENGINE + * structures where the pointers have a "structural reference". This means that + * their reference is to allowed access to the structure but it does not imply + * that the structure is functional. To simply increment or decrement the + * structural reference count, use ENGINE_by_id and ENGINE_free. NB: This is not + * required when iterating using ENGINE_get_next as it will automatically + * decrement the structural reference count of the "current" ENGINE and + * increment the structural reference count of the ENGINE it returns (unless it + * is NULL). */ + +/* Get the first/last "ENGINE" type available. */ +ENGINE *ENGINE_get_first(void); +ENGINE *ENGINE_get_last(void); +/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */ +ENGINE *ENGINE_get_next(ENGINE *e); +ENGINE *ENGINE_get_prev(ENGINE *e); +/* Add another "ENGINE" type into the array. */ +int ENGINE_add(ENGINE *e); +/* Remove an existing "ENGINE" type from the array. */ +int ENGINE_remove(ENGINE *e); +/* Retrieve an engine from the list by its unique "id" value. */ +ENGINE *ENGINE_by_id(const char *id); +/* Add all the built-in engines. */ +void ENGINE_load_openssl(void); +void ENGINE_load_dynamic(void); +#ifndef OPENSSL_NO_STATIC_ENGINE +void ENGINE_load_padlock(void); +#endif +void ENGINE_load_builtin_engines(void); + +/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation + * "registry" handling. */ +unsigned int ENGINE_get_table_flags(void); +void ENGINE_set_table_flags(unsigned int flags); + +/* Manage registration of ENGINEs per "table". For each type, there are 3 + * functions; + * ENGINE_register_***(e) - registers the implementation from 'e' (if it has one) + * ENGINE_unregister_***(e) - unregister the implementation from 'e' + * ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list + * Cleanup is automatically registered from each table when required, so + * ENGINE_cleanup() will reverse any "register" operations. */ + +int ENGINE_register_RSA(ENGINE *e); +void ENGINE_unregister_RSA(ENGINE *e); +void ENGINE_register_all_RSA(void); + +int ENGINE_register_DSA(ENGINE *e); +void ENGINE_unregister_DSA(ENGINE *e); +void ENGINE_register_all_DSA(void); + +int ENGINE_register_ECDH(ENGINE *e); +void ENGINE_unregister_ECDH(ENGINE *e); +void ENGINE_register_all_ECDH(void); + +int ENGINE_register_ECDSA(ENGINE *e); +void ENGINE_unregister_ECDSA(ENGINE *e); +void ENGINE_register_all_ECDSA(void); + +int ENGINE_register_DH(ENGINE *e); +void ENGINE_unregister_DH(ENGINE *e); +void ENGINE_register_all_DH(void); + +int ENGINE_register_RAND(ENGINE *e); +void ENGINE_unregister_RAND(ENGINE *e); +void ENGINE_register_all_RAND(void); + +int ENGINE_register_STORE(ENGINE *e); +void ENGINE_unregister_STORE(ENGINE *e); +void ENGINE_register_all_STORE(void); + +int ENGINE_register_ciphers(ENGINE *e); +void ENGINE_unregister_ciphers(ENGINE *e); +void ENGINE_register_all_ciphers(void); + +int ENGINE_register_digests(ENGINE *e); +void ENGINE_unregister_digests(ENGINE *e); +void ENGINE_register_all_digests(void); + +int ENGINE_register_pkey_meths(ENGINE *e); +void ENGINE_unregister_pkey_meths(ENGINE *e); +void ENGINE_register_all_pkey_meths(void); + +int ENGINE_register_pkey_asn1_meths(ENGINE *e); +void ENGINE_unregister_pkey_asn1_meths(ENGINE *e); +void ENGINE_register_all_pkey_asn1_meths(void); + +/* These functions register all support from the above categories. Note, use of + * these functions can result in static linkage of code your application may not + * need. If you only need a subset of functionality, consider using more + * selective initialisation. */ +int ENGINE_register_complete(ENGINE *e); +int ENGINE_register_all_complete(void); + +/* Send parametrised control commands to the engine. The possibilities to send + * down an integer, a pointer to data or a function pointer are provided. Any of + * the parameters may or may not be NULL, depending on the command number. In + * actuality, this function only requires a structural (rather than functional) + * reference to an engine, but many control commands may require the engine be + * functional. The caller should be aware of trying commands that require an + * operational ENGINE, and only use functional references in such situations. */ +int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)); + +/* This function tests if an ENGINE-specific command is usable as a "setting". + * Eg. in an application's config file that gets processed through + * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to + * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). */ +int ENGINE_cmd_is_executable(ENGINE *e, int cmd); + +/* This function works like ENGINE_ctrl() with the exception of taking a + * command name instead of a command number, and can handle optional commands. + * See the comment on ENGINE_ctrl_cmd_string() for an explanation on how to + * use the cmd_name and cmd_optional. */ +int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, + long i, void *p, void (*f)(void), int cmd_optional); + +/* This function passes a command-name and argument to an ENGINE. The cmd_name + * is converted to a command number and the control command is called using + * 'arg' as an argument (unless the ENGINE doesn't support such a command, in + * which case no control command is called). The command is checked for input + * flags, and if necessary the argument will be converted to a numeric value. If + * cmd_optional is non-zero, then if the ENGINE doesn't support the given + * cmd_name the return value will be success anyway. This function is intended + * for applications to use so that users (or config files) can supply + * engine-specific config data to the ENGINE at run-time to control behaviour of + * specific engines. As such, it shouldn't be used for calling ENGINE_ctrl() + * functions that return data, deal with binary data, or that are otherwise + * supposed to be used directly through ENGINE_ctrl() in application code. Any + * "return" data from an ENGINE_ctrl() operation in this function will be lost - + * the return value is interpreted as failure if the return value is zero, + * success otherwise, and this function returns a boolean value as a result. In + * other words, vendors of 'ENGINE'-enabled devices should write ENGINE + * implementations with parameterisations that work in this scheme, so that + * compliant ENGINE-based applications can work consistently with the same + * configuration for the same ENGINE-enabled devices, across applications. */ +int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, + int cmd_optional); + +/* These functions are useful for manufacturing new ENGINE structures. They + * don't address reference counting at all - one uses them to populate an ENGINE + * structure with personalised implementations of things prior to using it + * directly or adding it to the builtin ENGINE list in OpenSSL. These are also + * here so that the ENGINE structure doesn't have to be exposed and break binary + * compatibility! */ +ENGINE *ENGINE_new(void); +int ENGINE_free(ENGINE *e); +int ENGINE_up_ref(ENGINE *e); +int ENGINE_set_id(ENGINE *e, const char *id); +int ENGINE_set_name(ENGINE *e, const char *name); +int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth); +int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth); +int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth); +int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth); +int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth); +int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth); +int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth); +int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f); +int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f); +int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); +int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f); +int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f); +int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f); +int ENGINE_set_load_ssl_client_cert_function(ENGINE *e, + ENGINE_SSL_CLIENT_CERT_PTR loadssl_f); +int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f); +int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f); +int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f); +int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f); +int ENGINE_set_flags(ENGINE *e, int flags); +int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns); +/* These functions allow control over any per-structure ENGINE data. */ +int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg); +void *ENGINE_get_ex_data(const ENGINE *e, int idx); + +/* This function cleans up anything that needs it. Eg. the ENGINE_add() function + * automatically ensures the list cleanup function is registered to be called + * from ENGINE_cleanup(). Similarly, all ENGINE_register_*** functions ensure + * ENGINE_cleanup() will clean up after them. */ +void ENGINE_cleanup(void); + +/* These return values from within the ENGINE structure. These can be useful + * with functional references as well as structural references - it depends + * which you obtained. Using the result for functional purposes if you only + * obtained a structural reference may be problematic! */ +const char *ENGINE_get_id(const ENGINE *e); +const char *ENGINE_get_name(const ENGINE *e); +const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e); +const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e); +const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e); +const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e); +const DH_METHOD *ENGINE_get_DH(const ENGINE *e); +const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e); +const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e); +ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e); +ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e); +ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e); +ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e); +ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e); +ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e); +ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e); +ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e); +const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid); +const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid); +const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid); +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid); +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e, + const char *str, int len); +const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe, + const char *str, int len); +const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e); +int ENGINE_get_flags(const ENGINE *e); + +/* FUNCTIONAL functions. These functions deal with ENGINE structures + * that have (or will) be initialised for use. Broadly speaking, the + * structural functions are useful for iterating the list of available + * engine types, creating new engine types, and other "list" operations. + * These functions actually deal with ENGINEs that are to be used. As + * such these functions can fail (if applicable) when particular + * engines are unavailable - eg. if a hardware accelerator is not + * attached or not functioning correctly. Each ENGINE has 2 reference + * counts; structural and functional. Every time a functional reference + * is obtained or released, a corresponding structural reference is + * automatically obtained or released too. */ + +/* Initialise a engine type for use (or up its reference count if it's + * already in use). This will fail if the engine is not currently + * operational and cannot initialise. */ +int ENGINE_init(ENGINE *e); +/* Free a functional reference to a engine type. This does not require + * a corresponding call to ENGINE_free as it also releases a structural + * reference. */ +int ENGINE_finish(ENGINE *e); + +/* The following functions handle keys that are stored in some secondary + * location, handled by the engine. The storage may be on a card or + * whatever. */ +EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s, + STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey, + STACK_OF(X509) **pother, + UI_METHOD *ui_method, void *callback_data); + +/* This returns a pointer for the current ENGINE structure that + * is (by default) performing any RSA operations. The value returned + * is an incremented reference, so it should be free'd (ENGINE_finish) + * before it is discarded. */ +ENGINE *ENGINE_get_default_RSA(void); +/* Same for the other "methods" */ +ENGINE *ENGINE_get_default_DSA(void); +ENGINE *ENGINE_get_default_ECDH(void); +ENGINE *ENGINE_get_default_ECDSA(void); +ENGINE *ENGINE_get_default_DH(void); +ENGINE *ENGINE_get_default_RAND(void); +/* These functions can be used to get a functional reference to perform + * ciphering or digesting corresponding to "nid". */ +ENGINE *ENGINE_get_cipher_engine(int nid); +ENGINE *ENGINE_get_digest_engine(int nid); +ENGINE *ENGINE_get_pkey_meth_engine(int nid); +ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid); + +/* This sets a new default ENGINE structure for performing RSA + * operations. If the result is non-zero (success) then the ENGINE + * structure will have had its reference count up'd so the caller + * should still free their own reference 'e'. */ +int ENGINE_set_default_RSA(ENGINE *e); +int ENGINE_set_default_string(ENGINE *e, const char *def_list); +/* Same for the other "methods" */ +int ENGINE_set_default_DSA(ENGINE *e); +int ENGINE_set_default_ECDH(ENGINE *e); +int ENGINE_set_default_ECDSA(ENGINE *e); +int ENGINE_set_default_DH(ENGINE *e); +int ENGINE_set_default_RAND(ENGINE *e); +int ENGINE_set_default_ciphers(ENGINE *e); +int ENGINE_set_default_digests(ENGINE *e); +int ENGINE_set_default_pkey_meths(ENGINE *e); +int ENGINE_set_default_pkey_asn1_meths(ENGINE *e); + +/* The combination "set" - the flags are bitwise "OR"d from the + * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()" + * function, this function can result in unnecessary static linkage. If your + * application requires only specific functionality, consider using more + * selective functions. */ +int ENGINE_set_default(ENGINE *e, unsigned int flags); + +void ENGINE_add_conf_module(void); + +/* Deprecated functions ... */ +/* int ENGINE_clear_defaults(void); */ + +/**************************/ +/* DYNAMIC ENGINE SUPPORT */ +/**************************/ + +/* Binary/behaviour compatibility levels */ +#define OSSL_DYNAMIC_VERSION (unsigned long)0x00020000 +/* Binary versions older than this are too old for us (whether we're a loader or + * a loadee) */ +#define OSSL_DYNAMIC_OLDEST (unsigned long)0x00020000 + +/* When compiling an ENGINE entirely as an external shared library, loadable by + * the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' structure + * type provides the calling application's (or library's) error functionality + * and memory management function pointers to the loaded library. These should + * be used/set in the loaded library code so that the loading application's + * 'state' will be used/changed in all operations. The 'static_state' pointer + * allows the loaded library to know if it shares the same static data as the + * calling application (or library), and thus whether these callbacks need to be + * set or not. */ +typedef void *(*dyn_MEM_malloc_cb)(size_t); +typedef void *(*dyn_MEM_realloc_cb)(void *, size_t); +typedef void (*dyn_MEM_free_cb)(void *); +typedef struct st_dynamic_MEM_fns { + dyn_MEM_malloc_cb malloc_cb; + dyn_MEM_realloc_cb realloc_cb; + dyn_MEM_free_cb free_cb; +} dynamic_MEM_fns; +/* FIXME: Perhaps the memory and locking code (crypto.h) should declare and use + * these types so we (and any other dependant code) can simplify a bit?? */ +typedef void (*dyn_lock_locking_cb)(int, int, const char *, int); +typedef int (*dyn_lock_add_lock_cb)(int*, int, int, const char *, int); +typedef struct CRYPTO_dynlock_value *(*dyn_dynlock_create_cb)( + const char *, int); +typedef void (*dyn_dynlock_lock_cb)(int, struct CRYPTO_dynlock_value *, + const char *, int); +typedef void (*dyn_dynlock_destroy_cb)(struct CRYPTO_dynlock_value *, + const char *, int); +typedef struct st_dynamic_LOCK_fns { + dyn_lock_locking_cb lock_locking_cb; + dyn_lock_add_lock_cb lock_add_lock_cb; + dyn_dynlock_create_cb dynlock_create_cb; + dyn_dynlock_lock_cb dynlock_lock_cb; + dyn_dynlock_destroy_cb dynlock_destroy_cb; +} dynamic_LOCK_fns; +/* The top-level structure */ +typedef struct st_dynamic_fns { + void *static_state; + const ERR_FNS *err_fns; + const CRYPTO_EX_DATA_IMPL *ex_data_fns; + dynamic_MEM_fns mem_fns; + dynamic_LOCK_fns lock_fns; +} dynamic_fns; + +/* The version checking function should be of this prototype. NB: The + * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading code. + * If this function returns zero, it indicates a (potential) version + * incompatibility and the loaded library doesn't believe it can proceed. + * Otherwise, the returned value is the (latest) version supported by the + * loading library. The loader may still decide that the loaded code's version + * is unsatisfactory and could veto the load. The function is expected to + * be implemented with the symbol name "v_check", and a default implementation + * can be fully instantiated with IMPLEMENT_DYNAMIC_CHECK_FN(). */ +typedef unsigned long (*dynamic_v_check_fn)(unsigned long ossl_version); +#define IMPLEMENT_DYNAMIC_CHECK_FN() \ + extern unsigned long v_check(unsigned long v); \ + extern unsigned long v_check(unsigned long v) { \ + if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \ + return 0; } + +/* This function is passed the ENGINE structure to initialise with its own + * function and command settings. It should not adjust the structural or + * functional reference counts. If this function returns zero, (a) the load will + * be aborted, (b) the previous ENGINE state will be memcpy'd back onto the + * structure, and (c) the shared library will be unloaded. So implementations + * should do their own internal cleanup in failure circumstances otherwise they + * could leak. The 'id' parameter, if non-NULL, represents the ENGINE id that + * the loader is looking for. If this is NULL, the shared library can choose to + * return failure or to initialise a 'default' ENGINE. If non-NULL, the shared + * library must initialise only an ENGINE matching the passed 'id'. The function + * is expected to be implemented with the symbol name "bind_engine". A standard + * implementation can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where + * the parameter 'fn' is a callback function that populates the ENGINE structure + * and returns an int value (zero for failure). 'fn' should have prototype; + * [static] int fn(ENGINE *e, const char *id); */ +typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id, + const dynamic_fns *fns); +#define IMPLEMENT_DYNAMIC_BIND_FN(fn) \ + extern \ + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); \ + extern \ + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \ + if(ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \ + if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \ + fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \ + return 0; \ + CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \ + CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \ + CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \ + CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \ + CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \ + if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \ + return 0; \ + if(!ERR_set_implementation(fns->err_fns)) return 0; \ + skip_cbs: \ + if(!fn(e,id)) return 0; \ + return 1; } + +/* If the loading application (or library) and the loaded ENGINE library share + * the same static data (eg. they're both dynamically linked to the same + * libcrypto.so) we need a way to avoid trying to set system callbacks - this + * would fail, and for the same reason that it's unnecessary to try. If the + * loaded ENGINE has (or gets from through the loader) its own copy of the + * libcrypto static data, we will need to set the callbacks. The easiest way to + * detect this is to have a function that returns a pointer to some static data + * and let the loading application and loaded ENGINE compare their respective + * values. */ + void *ENGINE_get_static_state(void); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_ENGINE_strings(void); + +/* Error codes for the ENGINE functions. */ + +/* Function codes. */ +#define ENGINE_F_DYNAMIC_CTRL 180 +#define ENGINE_F_DYNAMIC_GET_DATA_CTX 181 +#define ENGINE_F_DYNAMIC_LOAD 182 +#define ENGINE_F_DYNAMIC_SET_DATA_CTX 183 +#define ENGINE_F_ENGINE_ADD 105 +#define ENGINE_F_ENGINE_BY_ID 106 +#define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170 +#define ENGINE_F_ENGINE_CTRL 142 +#define ENGINE_F_ENGINE_CTRL_CMD 178 +#define ENGINE_F_ENGINE_CTRL_CMD_STRING 171 +#define ENGINE_F_ENGINE_FINISH 107 +#define ENGINE_F_ENGINE_FREE_UTIL 108 +#define ENGINE_F_ENGINE_GET_CIPHER 185 +#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177 +#define ENGINE_F_ENGINE_GET_DIGEST 186 +#define ENGINE_F_ENGINE_GET_NEXT 115 +#define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH 193 +#define ENGINE_F_ENGINE_GET_PKEY_METH 192 +#define ENGINE_F_ENGINE_GET_PREV 116 +#define ENGINE_F_ENGINE_INIT 119 +#define ENGINE_F_ENGINE_LIST_ADD 120 +#define ENGINE_F_ENGINE_LIST_REMOVE 121 +#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150 +#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151 +#define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 194 +#define ENGINE_F_ENGINE_NEW 122 +#define ENGINE_F_ENGINE_REMOVE 123 +#define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189 +#define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126 +#define ENGINE_F_ENGINE_SET_ID 129 +#define ENGINE_F_ENGINE_SET_NAME 130 +#define ENGINE_F_ENGINE_TABLE_REGISTER 184 +#define ENGINE_F_ENGINE_UNLOAD_KEY 152 +#define ENGINE_F_ENGINE_UNLOCKED_FINISH 191 +#define ENGINE_F_ENGINE_UP_REF 190 +#define ENGINE_F_INT_CTRL_HELPER 172 +#define ENGINE_F_INT_ENGINE_CONFIGURE 188 +#define ENGINE_F_INT_ENGINE_MODULE_INIT 187 +#define ENGINE_F_LOG_MESSAGE 141 + +/* Reason codes. */ +#define ENGINE_R_ALREADY_LOADED 100 +#define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER 133 +#define ENGINE_R_CMD_NOT_EXECUTABLE 134 +#define ENGINE_R_COMMAND_TAKES_INPUT 135 +#define ENGINE_R_COMMAND_TAKES_NO_INPUT 136 +#define ENGINE_R_CONFLICTING_ENGINE_ID 103 +#define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119 +#define ENGINE_R_DH_NOT_IMPLEMENTED 139 +#define ENGINE_R_DSA_NOT_IMPLEMENTED 140 +#define ENGINE_R_DSO_FAILURE 104 +#define ENGINE_R_DSO_NOT_FOUND 132 +#define ENGINE_R_ENGINES_SECTION_ERROR 148 +#define ENGINE_R_ENGINE_CONFIGURATION_ERROR 102 +#define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105 +#define ENGINE_R_ENGINE_SECTION_ERROR 149 +#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128 +#define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129 +#define ENGINE_R_FINISH_FAILED 106 +#define ENGINE_R_GET_HANDLE_FAILED 107 +#define ENGINE_R_ID_OR_NAME_MISSING 108 +#define ENGINE_R_INIT_FAILED 109 +#define ENGINE_R_INTERNAL_LIST_ERROR 110 +#define ENGINE_R_INVALID_ARGUMENT 143 +#define ENGINE_R_INVALID_CMD_NAME 137 +#define ENGINE_R_INVALID_CMD_NUMBER 138 +#define ENGINE_R_INVALID_INIT_VALUE 151 +#define ENGINE_R_INVALID_STRING 150 +#define ENGINE_R_NOT_INITIALISED 117 +#define ENGINE_R_NOT_LOADED 112 +#define ENGINE_R_NO_CONTROL_FUNCTION 120 +#define ENGINE_R_NO_INDEX 144 +#define ENGINE_R_NO_LOAD_FUNCTION 125 +#define ENGINE_R_NO_REFERENCE 130 +#define ENGINE_R_NO_SUCH_ENGINE 116 +#define ENGINE_R_NO_UNLOAD_FUNCTION 126 +#define ENGINE_R_PROVIDE_PARAMETERS 113 +#define ENGINE_R_RSA_NOT_IMPLEMENTED 141 +#define ENGINE_R_UNIMPLEMENTED_CIPHER 146 +#define ENGINE_R_UNIMPLEMENTED_DIGEST 147 +#define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD 101 +#define ENGINE_R_VERSION_INCOMPATIBILITY 145 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/err.h b/crypto/libressl/include/openssl/err.h new file mode 100644 index 0000000000..161af0089a --- /dev/null +++ b/crypto/libressl/include/openssl/err.h @@ -0,0 +1,381 @@ +/* $OpenBSD: err.h,v 1.21 2014/07/11 09:25:24 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_ERR_H +#define HEADER_ERR_H + +#include + +#include +#include + +#include +#ifndef OPENSSL_NO_BIO +#include +#endif +#ifndef OPENSSL_NO_LHASH +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef OPENSSL_NO_ERR +#define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,d,e) +#else +#define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,NULL,0) +#endif + +#include + +#define ERR_TXT_MALLOCED 0x01 +#define ERR_TXT_STRING 0x02 + +#define ERR_FLAG_MARK 0x01 + +#define ERR_NUM_ERRORS 16 +typedef struct err_state_st { + CRYPTO_THREADID tid; + int err_flags[ERR_NUM_ERRORS]; + unsigned long err_buffer[ERR_NUM_ERRORS]; + char *err_data[ERR_NUM_ERRORS]; + int err_data_flags[ERR_NUM_ERRORS]; + const char *err_file[ERR_NUM_ERRORS]; + int err_line[ERR_NUM_ERRORS]; + int top, bottom; +} ERR_STATE; + +/* library */ +#define ERR_LIB_NONE 1 +#define ERR_LIB_SYS 2 +#define ERR_LIB_BN 3 +#define ERR_LIB_RSA 4 +#define ERR_LIB_DH 5 +#define ERR_LIB_EVP 6 +#define ERR_LIB_BUF 7 +#define ERR_LIB_OBJ 8 +#define ERR_LIB_PEM 9 +#define ERR_LIB_DSA 10 +#define ERR_LIB_X509 11 +/* #define ERR_LIB_METH 12 */ +#define ERR_LIB_ASN1 13 +#define ERR_LIB_CONF 14 +#define ERR_LIB_CRYPTO 15 +#define ERR_LIB_EC 16 +#define ERR_LIB_SSL 20 +/* #define ERR_LIB_SSL23 21 */ +/* #define ERR_LIB_SSL2 22 */ +/* #define ERR_LIB_SSL3 23 */ +/* #define ERR_LIB_RSAREF 30 */ +/* #define ERR_LIB_PROXY 31 */ +#define ERR_LIB_BIO 32 +#define ERR_LIB_PKCS7 33 +#define ERR_LIB_X509V3 34 +#define ERR_LIB_PKCS12 35 +#define ERR_LIB_RAND 36 +#define ERR_LIB_DSO 37 +#define ERR_LIB_ENGINE 38 +#define ERR_LIB_OCSP 39 +#define ERR_LIB_UI 40 +#define ERR_LIB_COMP 41 +#define ERR_LIB_ECDSA 42 +#define ERR_LIB_ECDH 43 +#define ERR_LIB_STORE 44 +#define ERR_LIB_FIPS 45 +#define ERR_LIB_CMS 46 +#define ERR_LIB_TS 47 +#define ERR_LIB_HMAC 48 +#define ERR_LIB_JPAKE 49 +#define ERR_LIB_GOST 50 + +#define ERR_LIB_USER 128 + +#define SYSerr(f,r) ERR_PUT_error(ERR_LIB_SYS,(f),(r),__FILE__,__LINE__) +#define BNerr(f,r) ERR_PUT_error(ERR_LIB_BN,(f),(r),__FILE__,__LINE__) +#define RSAerr(f,r) ERR_PUT_error(ERR_LIB_RSA,(f),(r),__FILE__,__LINE__) +#define DHerr(f,r) ERR_PUT_error(ERR_LIB_DH,(f),(r),__FILE__,__LINE__) +#define EVPerr(f,r) ERR_PUT_error(ERR_LIB_EVP,(f),(r),__FILE__,__LINE__) +#define BUFerr(f,r) ERR_PUT_error(ERR_LIB_BUF,(f),(r),__FILE__,__LINE__) +#define OBJerr(f,r) ERR_PUT_error(ERR_LIB_OBJ,(f),(r),__FILE__,__LINE__) +#define PEMerr(f,r) ERR_PUT_error(ERR_LIB_PEM,(f),(r),__FILE__,__LINE__) +#define DSAerr(f,r) ERR_PUT_error(ERR_LIB_DSA,(f),(r),__FILE__,__LINE__) +#define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),__FILE__,__LINE__) +#define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),__FILE__,__LINE__) +#define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),__FILE__,__LINE__) +#define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),__FILE__,__LINE__) +#define ECerr(f,r) ERR_PUT_error(ERR_LIB_EC,(f),(r),__FILE__,__LINE__) +#define SSLerr(f,r) ERR_PUT_error(ERR_LIB_SSL,(f),(r),__FILE__,__LINE__) +#define BIOerr(f,r) ERR_PUT_error(ERR_LIB_BIO,(f),(r),__FILE__,__LINE__) +#define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),__FILE__,__LINE__) +#define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),__FILE__,__LINE__) +#define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),__FILE__,__LINE__) +#define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),__FILE__,__LINE__) +#define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),__FILE__,__LINE__) +#define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),__FILE__,__LINE__) +#define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,(f),(r),__FILE__,__LINE__) +#define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,(f),(r),__FILE__,__LINE__) +#define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,(f),(r),__FILE__,__LINE__) +#define ECDSAerr(f,r) ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),__FILE__,__LINE__) +#define ECDHerr(f,r) ERR_PUT_error(ERR_LIB_ECDH,(f),(r),__FILE__,__LINE__) +#define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__) +#define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),__FILE__,__LINE__) +#define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),__FILE__,__LINE__) +#define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),__FILE__,__LINE__) +#define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),__FILE__,__LINE__) +#define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),__FILE__,__LINE__) +#define GOSTerr(f,r) ERR_PUT_error(ERR_LIB_GOST,(f),(r),__FILE__,__LINE__) + +#define ERR_PACK(l,f,r) (((((unsigned long)l)&0xffL)<<24L)| \ + ((((unsigned long)f)&0xfffL)<<12L)| \ + ((((unsigned long)r)&0xfffL))) +#define ERR_GET_LIB(l) (int)((((unsigned long)l)>>24L)&0xffL) +#define ERR_GET_FUNC(l) (int)((((unsigned long)l)>>12L)&0xfffL) +#define ERR_GET_REASON(l) (int)((l)&0xfffL) +#define ERR_FATAL_ERROR(l) (int)((l)&ERR_R_FATAL) + + +/* OS functions */ +#define SYS_F_FOPEN 1 +#define SYS_F_CONNECT 2 +#define SYS_F_GETSERVBYNAME 3 +#define SYS_F_SOCKET 4 +#define SYS_F_IOCTLSOCKET 5 +#define SYS_F_BIND 6 +#define SYS_F_LISTEN 7 +#define SYS_F_ACCEPT 8 +#define SYS_F_WSASTARTUP 9 /* Winsock stuff */ +#define SYS_F_OPENDIR 10 +#define SYS_F_FREAD 11 + + +/* reasons */ +#define ERR_R_SYS_LIB ERR_LIB_SYS /* 2 */ +#define ERR_R_BN_LIB ERR_LIB_BN /* 3 */ +#define ERR_R_RSA_LIB ERR_LIB_RSA /* 4 */ +#define ERR_R_DH_LIB ERR_LIB_DH /* 5 */ +#define ERR_R_EVP_LIB ERR_LIB_EVP /* 6 */ +#define ERR_R_BUF_LIB ERR_LIB_BUF /* 7 */ +#define ERR_R_OBJ_LIB ERR_LIB_OBJ /* 8 */ +#define ERR_R_PEM_LIB ERR_LIB_PEM /* 9 */ +#define ERR_R_DSA_LIB ERR_LIB_DSA /* 10 */ +#define ERR_R_X509_LIB ERR_LIB_X509 /* 11 */ +#define ERR_R_ASN1_LIB ERR_LIB_ASN1 /* 13 */ +#define ERR_R_CONF_LIB ERR_LIB_CONF /* 14 */ +#define ERR_R_CRYPTO_LIB ERR_LIB_CRYPTO /* 15 */ +#define ERR_R_EC_LIB ERR_LIB_EC /* 16 */ +#define ERR_R_SSL_LIB ERR_LIB_SSL /* 20 */ +#define ERR_R_BIO_LIB ERR_LIB_BIO /* 32 */ +#define ERR_R_PKCS7_LIB ERR_LIB_PKCS7 /* 33 */ +#define ERR_R_X509V3_LIB ERR_LIB_X509V3 /* 34 */ +#define ERR_R_PKCS12_LIB ERR_LIB_PKCS12 /* 35 */ +#define ERR_R_RAND_LIB ERR_LIB_RAND /* 36 */ +#define ERR_R_DSO_LIB ERR_LIB_DSO /* 37 */ +#define ERR_R_ENGINE_LIB ERR_LIB_ENGINE /* 38 */ +#define ERR_R_OCSP_LIB ERR_LIB_OCSP /* 39 */ +#define ERR_R_UI_LIB ERR_LIB_UI /* 40 */ +#define ERR_R_COMP_LIB ERR_LIB_COMP /* 41 */ +#define ERR_R_ECDSA_LIB ERR_LIB_ECDSA /* 42 */ +#define ERR_R_ECDH_LIB ERR_LIB_ECDH /* 43 */ +#define ERR_R_STORE_LIB ERR_LIB_STORE /* 44 */ +#define ERR_R_TS_LIB ERR_LIB_TS /* 45 */ + +#define ERR_R_NESTED_ASN1_ERROR 58 +#define ERR_R_BAD_ASN1_OBJECT_HEADER 59 +#define ERR_R_BAD_GET_ASN1_OBJECT_CALL 60 +#define ERR_R_EXPECTING_AN_ASN1_SEQUENCE 61 +#define ERR_R_ASN1_LENGTH_MISMATCH 62 +#define ERR_R_MISSING_ASN1_EOS 63 + +/* fatal error */ +#define ERR_R_FATAL 64 +#define ERR_R_MALLOC_FAILURE (1|ERR_R_FATAL) +#define ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED (2|ERR_R_FATAL) +#define ERR_R_PASSED_NULL_PARAMETER (3|ERR_R_FATAL) +#define ERR_R_INTERNAL_ERROR (4|ERR_R_FATAL) +#define ERR_R_DISABLED (5|ERR_R_FATAL) + +/* 99 is the maximum possible ERR_R_... code, higher values + * are reserved for the individual libraries */ + + +typedef struct ERR_string_data_st { + unsigned long error; + const char *string; +} ERR_STRING_DATA; + +void ERR_put_error(int lib, int func, int reason, const char *file, int line); +void ERR_set_error_data(char *data, int flags); + +unsigned long ERR_get_error(void); +unsigned long ERR_get_error_line(const char **file, int *line); +unsigned long ERR_get_error_line_data(const char **file, int *line, + const char **data, int *flags); +unsigned long ERR_peek_error(void); +unsigned long ERR_peek_error_line(const char **file, int *line); +unsigned long ERR_peek_error_line_data(const char **file, int *line, + const char **data, int *flags); +unsigned long ERR_peek_last_error(void); +unsigned long ERR_peek_last_error_line(const char **file, int *line); +unsigned long ERR_peek_last_error_line_data(const char **file, int *line, + const char **data, int *flags); +void ERR_clear_error(void ); +char *ERR_error_string(unsigned long e, char *buf); +void ERR_error_string_n(unsigned long e, char *buf, size_t len); +const char *ERR_lib_error_string(unsigned long e); +const char *ERR_func_error_string(unsigned long e); +const char *ERR_reason_error_string(unsigned long e); +void ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u), + void *u); +void ERR_print_errors_fp(FILE *fp); +#ifndef OPENSSL_NO_BIO +void ERR_print_errors(BIO *bp); +#endif +void ERR_asprintf_error_data(char * format, ...); +void ERR_add_error_data(int num, ...); +void ERR_add_error_vdata(int num, va_list args); +void ERR_load_strings(int lib, ERR_STRING_DATA str[]); +void ERR_unload_strings(int lib, ERR_STRING_DATA str[]); +void ERR_load_ERR_strings(void); +void ERR_load_crypto_strings(void); +void ERR_free_strings(void); + +void ERR_remove_thread_state(const CRYPTO_THREADID *tid); +#ifndef OPENSSL_NO_DEPRECATED +void ERR_remove_state(unsigned long pid); /* if zero we look it up */ +#endif +ERR_STATE *ERR_get_state(void); + +#ifndef OPENSSL_NO_LHASH +LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void); +LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void); +void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash); +#endif + +int ERR_get_next_error_library(void); + +int ERR_set_mark(void); +int ERR_pop_to_mark(void); + +/* Already defined in ossl_typ.h */ +/* typedef struct st_ERR_FNS ERR_FNS; */ +/* An application can use this function and provide the return value to loaded + * modules that should use the application's ERR state/functionality */ +const ERR_FNS *ERR_get_implementation(void); +/* A loaded module should call this function prior to any ERR operations using + * the application's "ERR_FNS". */ +int ERR_set_implementation(const ERR_FNS *fns); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/libressl/include/openssl/evp.h b/crypto/libressl/include/openssl/evp.h new file mode 100644 index 0000000000..bdc6328e55 --- /dev/null +++ b/crypto/libressl/include/openssl/evp.h @@ -0,0 +1,1501 @@ +/* $OpenBSD: evp.h,v 1.50 2016/04/28 16:06:53 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_ENVELOPE_H +#define HEADER_ENVELOPE_H + +#include + +#include + +#ifndef OPENSSL_NO_BIO +#include +#endif + +/* +#define EVP_RC2_KEY_SIZE 16 +#define EVP_RC4_KEY_SIZE 16 +#define EVP_BLOWFISH_KEY_SIZE 16 +#define EVP_CAST5_KEY_SIZE 16 +#define EVP_RC5_32_12_16_KEY_SIZE 16 +*/ +#define EVP_MAX_MD_SIZE 64 /* longest known is SHA512 */ +#define EVP_MAX_KEY_LENGTH 64 +#define EVP_MAX_IV_LENGTH 16 +#define EVP_MAX_BLOCK_LENGTH 32 + +#define PKCS5_SALT_LEN 8 +/* Default PKCS#5 iteration count */ +#define PKCS5_DEFAULT_ITER 2048 + +#include + +#define EVP_PK_RSA 0x0001 +#define EVP_PK_DSA 0x0002 +#define EVP_PK_DH 0x0004 +#define EVP_PK_EC 0x0008 +#define EVP_PKT_SIGN 0x0010 +#define EVP_PKT_ENC 0x0020 +#define EVP_PKT_EXCH 0x0040 +#define EVP_PKS_RSA 0x0100 +#define EVP_PKS_DSA 0x0200 +#define EVP_PKS_EC 0x0400 +#define EVP_PKT_EXP 0x1000 /* <= 512 bit key */ + +#define EVP_PKEY_NONE NID_undef +#define EVP_PKEY_RSA NID_rsaEncryption +#define EVP_PKEY_RSA2 NID_rsa +#define EVP_PKEY_DSA NID_dsa +#define EVP_PKEY_DSA1 NID_dsa_2 +#define EVP_PKEY_DSA2 NID_dsaWithSHA +#define EVP_PKEY_DSA3 NID_dsaWithSHA1 +#define EVP_PKEY_DSA4 NID_dsaWithSHA1_2 +#define EVP_PKEY_DH NID_dhKeyAgreement +#define EVP_PKEY_EC NID_X9_62_id_ecPublicKey +#define EVP_PKEY_GOSTR01 NID_id_GostR3410_2001 +#define EVP_PKEY_GOSTIMIT NID_id_Gost28147_89_MAC +#define EVP_PKEY_HMAC NID_hmac +#define EVP_PKEY_CMAC NID_cmac +#define EVP_PKEY_GOSTR12_256 NID_id_tc26_gost3410_2012_256 +#define EVP_PKEY_GOSTR12_512 NID_id_tc26_gost3410_2012_512 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Type needs to be a bit field + * Sub-type needs to be for variations on the method, as in, can it do + * arbitrary encryption.... */ +struct evp_pkey_st { + int type; + int save_type; + int references; + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *engine; + union { + char *ptr; +#ifndef OPENSSL_NO_RSA + struct rsa_st *rsa; /* RSA */ +#endif +#ifndef OPENSSL_NO_DSA + struct dsa_st *dsa; /* DSA */ +#endif +#ifndef OPENSSL_NO_DH + struct dh_st *dh; /* DH */ +#endif +#ifndef OPENSSL_NO_EC + struct ec_key_st *ec; /* ECC */ +#endif +#ifndef OPENSSL_NO_GOST + struct gost_key_st *gost; /* GOST */ +#endif + } pkey; + int save_parameters; + STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ +} /* EVP_PKEY */; + +#define EVP_PKEY_MO_SIGN 0x0001 +#define EVP_PKEY_MO_VERIFY 0x0002 +#define EVP_PKEY_MO_ENCRYPT 0x0004 +#define EVP_PKEY_MO_DECRYPT 0x0008 + +typedef int evp_sign_method(int type, const unsigned char *m, + unsigned int m_length, unsigned char *sigret, unsigned int *siglen, + void *key); +typedef int evp_verify_method(int type, const unsigned char *m, + unsigned int m_length, const unsigned char *sigbuf, unsigned int siglen, + void *key); + +#ifndef EVP_MD +struct env_md_st { + int type; + int pkey_type; + int md_size; + unsigned long flags; + int (*init)(EVP_MD_CTX *ctx); + int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count); + int (*final)(EVP_MD_CTX *ctx, unsigned char *md); + int (*copy)(EVP_MD_CTX *to, const EVP_MD_CTX *from); + int (*cleanup)(EVP_MD_CTX *ctx); + + evp_sign_method *sign; + evp_verify_method *verify; + int required_pkey_type[5]; /*EVP_PKEY_xxx */ + int block_size; + int ctx_size; /* how big does the ctx->md_data need to be */ + /* control function */ + int (*md_ctrl)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2); +} /* EVP_MD */; + +#define EVP_MD_FLAG_ONESHOT 0x0001 /* digest can only handle a single + * block */ + +#define EVP_MD_FLAG_PKEY_DIGEST 0x0002 /* digest is a "clone" digest used + * which is a copy of an existing + * one for a specific public key type. + * EVP_dss1() etc */ + +/* Digest uses EVP_PKEY_METHOD for signing instead of MD specific signing */ + +#define EVP_MD_FLAG_PKEY_METHOD_SIGNATURE 0x0004 + +/* DigestAlgorithmIdentifier flags... */ + +#define EVP_MD_FLAG_DIGALGID_MASK 0x0018 + +/* NULL or absent parameter accepted. Use NULL */ + +#define EVP_MD_FLAG_DIGALGID_NULL 0x0000 + +/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */ + +#define EVP_MD_FLAG_DIGALGID_ABSENT 0x0008 + +/* Custom handling via ctrl */ + +#define EVP_MD_FLAG_DIGALGID_CUSTOM 0x0018 + +#define EVP_MD_FLAG_FIPS 0x0400 /* Note if suitable for use in FIPS mode */ + +/* Digest ctrls */ + +#define EVP_MD_CTRL_DIGALGID 0x1 +#define EVP_MD_CTRL_MICALG 0x2 +#define EVP_MD_CTRL_SET_KEY 0x3 +#define EVP_MD_CTRL_GOST_SET_SBOX 0x4 + +/* Minimum Algorithm specific ctrl value */ + +#define EVP_MD_CTRL_ALG_CTRL 0x1000 + +#define EVP_PKEY_NULL_method NULL,NULL,{0,0,0,0} + +#ifndef OPENSSL_NO_DSA +#define EVP_PKEY_DSA_method (evp_sign_method *)DSA_sign, \ + (evp_verify_method *)DSA_verify, \ + {EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3, \ + EVP_PKEY_DSA4,0} +#else +#define EVP_PKEY_DSA_method EVP_PKEY_NULL_method +#endif + +#ifndef OPENSSL_NO_ECDSA +#define EVP_PKEY_ECDSA_method (evp_sign_method *)ECDSA_sign, \ + (evp_verify_method *)ECDSA_verify, \ + {EVP_PKEY_EC,0,0,0} +#else +#define EVP_PKEY_ECDSA_method EVP_PKEY_NULL_method +#endif + +#ifndef OPENSSL_NO_RSA +#define EVP_PKEY_RSA_method (evp_sign_method *)RSA_sign, \ + (evp_verify_method *)RSA_verify, \ + {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0} +#define EVP_PKEY_RSA_ASN1_OCTET_STRING_method \ + (evp_sign_method *)RSA_sign_ASN1_OCTET_STRING, \ + (evp_verify_method *)RSA_verify_ASN1_OCTET_STRING, \ + {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0} +#else +#define EVP_PKEY_RSA_method EVP_PKEY_NULL_method +#define EVP_PKEY_RSA_ASN1_OCTET_STRING_method EVP_PKEY_NULL_method +#endif + +#endif /* !EVP_MD */ + +struct env_md_ctx_st { + const EVP_MD *digest; + ENGINE *engine; /* functional reference if 'digest' is ENGINE-provided */ + unsigned long flags; + void *md_data; + /* Public key context for sign/verify */ + EVP_PKEY_CTX *pctx; + /* Update function: usually copied from EVP_MD */ + int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count); +} /* EVP_MD_CTX */; + +/* values for EVP_MD_CTX flags */ + +#define EVP_MD_CTX_FLAG_ONESHOT 0x0001 /* digest update will be called + * once only */ +#define EVP_MD_CTX_FLAG_CLEANED 0x0002 /* context has already been + * cleaned */ +#define EVP_MD_CTX_FLAG_REUSE 0x0004 /* Don't free up ctx->md_data + * in EVP_MD_CTX_cleanup */ +/* FIPS and pad options are ignored in 1.0.0, definitions are here + * so we don't accidentally reuse the values for other purposes. + */ + +#define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0x0008 /* Allow use of non FIPS digest + * in FIPS mode */ + +/* The following PAD options are also currently ignored in 1.0.0, digest + * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*() + * instead. + */ +#define EVP_MD_CTX_FLAG_PAD_MASK 0xF0 /* RSA mode to use */ +#define EVP_MD_CTX_FLAG_PAD_PKCS1 0x00 /* PKCS#1 v1.5 mode */ +#define EVP_MD_CTX_FLAG_PAD_X931 0x10 /* X9.31 mode */ +#define EVP_MD_CTX_FLAG_PAD_PSS 0x20 /* PSS mode */ + +#define EVP_MD_CTX_FLAG_NO_INIT 0x0100 /* Don't initialize md_data */ + +struct evp_cipher_st { + int nid; + int block_size; + int key_len; /* Default value for variable length ciphers */ + int iv_len; + unsigned long flags; /* Various flags */ + int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); /* init key */ + int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl);/* encrypt/decrypt data */ + int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */ + int ctx_size; /* how big ctx->cipher_data needs to be */ + int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */ + int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */ + int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Miscellaneous operations */ + void *app_data; /* Application data */ +} /* EVP_CIPHER */; + +/* Values for cipher flags */ + +/* Modes for ciphers */ + +#define EVP_CIPH_STREAM_CIPHER 0x0 +#define EVP_CIPH_ECB_MODE 0x1 +#define EVP_CIPH_CBC_MODE 0x2 +#define EVP_CIPH_CFB_MODE 0x3 +#define EVP_CIPH_OFB_MODE 0x4 +#define EVP_CIPH_CTR_MODE 0x5 +#define EVP_CIPH_GCM_MODE 0x6 +#define EVP_CIPH_CCM_MODE 0x7 +#define EVP_CIPH_XTS_MODE 0x10001 +#define EVP_CIPH_MODE 0xF0007 +/* Set if variable length cipher */ +#define EVP_CIPH_VARIABLE_LENGTH 0x8 +/* Set if the iv handling should be done by the cipher itself */ +#define EVP_CIPH_CUSTOM_IV 0x10 +/* Set if the cipher's init() function should be called if key is NULL */ +#define EVP_CIPH_ALWAYS_CALL_INIT 0x20 +/* Call ctrl() to init cipher parameters */ +#define EVP_CIPH_CTRL_INIT 0x40 +/* Don't use standard key length function */ +#define EVP_CIPH_CUSTOM_KEY_LENGTH 0x80 +/* Don't use standard block padding */ +#define EVP_CIPH_NO_PADDING 0x100 +/* cipher handles random key generation */ +#define EVP_CIPH_RAND_KEY 0x200 +/* cipher has its own additional copying logic */ +#define EVP_CIPH_CUSTOM_COPY 0x400 +/* Allow use default ASN1 get/set iv */ +#define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000 +/* Buffer length in bits not bytes: CFB1 mode only */ +#define EVP_CIPH_FLAG_LENGTH_BITS 0x2000 +/* Note if suitable for use in FIPS mode */ +#define EVP_CIPH_FLAG_FIPS 0x4000 +/* Allow non FIPS cipher in FIPS mode */ +#define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x8000 +/* Cipher handles any and all padding logic as well + * as finalisation. + */ +#define EVP_CIPH_FLAG_CUSTOM_CIPHER 0x100000 +#define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 + +/* ctrl() values */ + +#define EVP_CTRL_INIT 0x0 +#define EVP_CTRL_SET_KEY_LENGTH 0x1 +#define EVP_CTRL_GET_RC2_KEY_BITS 0x2 +#define EVP_CTRL_SET_RC2_KEY_BITS 0x3 +#define EVP_CTRL_GET_RC5_ROUNDS 0x4 +#define EVP_CTRL_SET_RC5_ROUNDS 0x5 +#define EVP_CTRL_RAND_KEY 0x6 +#define EVP_CTRL_PBE_PRF_NID 0x7 +#define EVP_CTRL_COPY 0x8 +#define EVP_CTRL_GCM_SET_IVLEN 0x9 +#define EVP_CTRL_GCM_GET_TAG 0x10 +#define EVP_CTRL_GCM_SET_TAG 0x11 +#define EVP_CTRL_GCM_SET_IV_FIXED 0x12 +#define EVP_CTRL_GCM_IV_GEN 0x13 +#define EVP_CTRL_CCM_SET_IVLEN EVP_CTRL_GCM_SET_IVLEN +#define EVP_CTRL_CCM_GET_TAG EVP_CTRL_GCM_GET_TAG +#define EVP_CTRL_CCM_SET_TAG EVP_CTRL_GCM_SET_TAG +#define EVP_CTRL_CCM_SET_L 0x14 +#define EVP_CTRL_CCM_SET_MSGLEN 0x15 +/* AEAD cipher deduces payload length and returns number of bytes + * required to store MAC and eventual padding. Subsequent call to + * EVP_Cipher even appends/verifies MAC. + */ +#define EVP_CTRL_AEAD_TLS1_AAD 0x16 +/* Used by composite AEAD ciphers, no-op in GCM, CCM... */ +#define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 +/* Set the GCM invocation field, decrypt only */ +#define EVP_CTRL_GCM_SET_IV_INV 0x18 +/* Set the S-BOX NID for GOST ciphers */ +#define EVP_CTRL_GOST_SET_SBOX 0x19 + +/* GCM TLS constants */ +/* Length of fixed part of IV derived from PRF */ +#define EVP_GCM_TLS_FIXED_IV_LEN 4 +/* Length of explicit part of IV part of TLS records */ +#define EVP_GCM_TLS_EXPLICIT_IV_LEN 8 +/* Length of tag for TLS */ +#define EVP_GCM_TLS_TAG_LEN 16 + +typedef struct evp_cipher_info_st { + const EVP_CIPHER *cipher; + unsigned char iv[EVP_MAX_IV_LENGTH]; +} EVP_CIPHER_INFO; + +struct evp_cipher_ctx_st { + const EVP_CIPHER *cipher; + ENGINE *engine; /* functional reference if 'cipher' is ENGINE-provided */ + int encrypt; /* encrypt or decrypt */ + int buf_len; /* number we have left */ + + unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */ + unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */ + unsigned char buf[EVP_MAX_BLOCK_LENGTH];/* saved partial block */ + int num; /* used by cfb/ofb/ctr mode */ + + void *app_data; /* application stuff */ + int key_len; /* May change for variable length cipher */ + unsigned long flags; /* Various flags */ + void *cipher_data; /* per EVP data */ + int final_used; + int block_mask; + unsigned char final[EVP_MAX_BLOCK_LENGTH];/* possible final block */ +} /* EVP_CIPHER_CTX */; + +typedef struct evp_Encode_Ctx_st { + int num; /* number saved in a partial encode/decode */ + int length; /* The length is either the output line length + * (in input bytes) or the shortest input line + * length that is ok. Once decoding begins, + * the length is adjusted up each time a longer + * line is decoded */ + unsigned char enc_data[80]; /* data to encode */ + int line_num; /* number read on current line */ + int expect_nl; +} EVP_ENCODE_CTX; + +/* Password based encryption function */ +typedef int (EVP_PBE_KEYGEN)(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, int en_de); + +#ifndef OPENSSL_NO_RSA +#define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\ + (char *)(rsa)) +#endif + +#ifndef OPENSSL_NO_DSA +#define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\ + (char *)(dsa)) +#endif + +#ifndef OPENSSL_NO_DH +#define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\ + (char *)(dh)) +#endif + +#ifndef OPENSSL_NO_EC +#define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\ + (char *)(eckey)) +#endif + +#ifndef OPENSSL_NO_GOST +#define EVP_PKEY_assign_GOST(pkey,gostkey) EVP_PKEY_assign((pkey),EVP_PKEY_GOSTR01,\ + (char *)(gostkey)) +#endif + +/* Add some extra combinations */ +#define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a)) +#define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a)) +#define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a)) +#define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a)) + +int EVP_MD_type(const EVP_MD *md); +#define EVP_MD_nid(e) EVP_MD_type(e) +#define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_nid(e)) +int EVP_MD_pkey_type(const EVP_MD *md); +int EVP_MD_size(const EVP_MD *md); +int EVP_MD_block_size(const EVP_MD *md); +unsigned long EVP_MD_flags(const EVP_MD *md); + +const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx); +#define EVP_MD_CTX_size(e) EVP_MD_size(EVP_MD_CTX_md(e)) +#define EVP_MD_CTX_block_size(e) EVP_MD_block_size(EVP_MD_CTX_md(e)) +#define EVP_MD_CTX_type(e) EVP_MD_type(EVP_MD_CTX_md(e)) + +int EVP_CIPHER_nid(const EVP_CIPHER *cipher); +#define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e)) +int EVP_CIPHER_block_size(const EVP_CIPHER *cipher); +int EVP_CIPHER_key_length(const EVP_CIPHER *cipher); +int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher); +unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher); +#define EVP_CIPHER_mode(e) (EVP_CIPHER_flags(e) & EVP_CIPH_MODE) + +const EVP_CIPHER * EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in); +void * EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx); +void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data); +#define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c)) +unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx); +#define EVP_CIPHER_CTX_mode(e) (EVP_CIPHER_CTX_flags(e) & EVP_CIPH_MODE) + +#define EVP_ENCODE_LENGTH(l) (((l+2)/3*4)+(l/48+1)*2+80) +#define EVP_DECODE_LENGTH(l) ((l+3)/4*3+80) + +#define EVP_SignInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c) +#define EVP_SignInit(a,b) EVP_DigestInit(a,b) +#define EVP_SignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +#define EVP_VerifyInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c) +#define EVP_VerifyInit(a,b) EVP_DigestInit(a,b) +#define EVP_VerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +#define EVP_OpenUpdate(a,b,c,d,e) EVP_DecryptUpdate(a,b,c,d,e) +#define EVP_SealUpdate(a,b,c,d,e) EVP_EncryptUpdate(a,b,c,d,e) +#define EVP_DigestSignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +#define EVP_DigestVerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) + +#define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,0,(char *)md) +#define BIO_get_md(b,mdp) BIO_ctrl(b,BIO_C_GET_MD,0,(char *)mdp) +#define BIO_get_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_GET_MD_CTX,0,(char *)mdcp) +#define BIO_set_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_SET_MD_CTX,0,(char *)mdcp) +#define BIO_get_cipher_status(b) BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL) +#define BIO_get_cipher_ctx(b,c_pp) BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(char *)c_pp) + +int EVP_Cipher(EVP_CIPHER_CTX *c, unsigned char *out, const unsigned char *in, + unsigned int inl); + +#define EVP_add_cipher_alias(n,alias) \ + OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n)) +#define EVP_add_digest_alias(n,alias) \ + OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n)) +#define EVP_delete_cipher_alias(alias) \ + OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS); +#define EVP_delete_digest_alias(alias) \ + OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS); + +void EVP_MD_CTX_init(EVP_MD_CTX *ctx); +int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx); +EVP_MD_CTX *EVP_MD_CTX_create(void); +void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx); +int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in); +void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags); +void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags); +int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr); +int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags); +int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl); +int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt); +int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s); +int EVP_Digest(const void *data, size_t count, unsigned char *md, + unsigned int *size, const EVP_MD *type, ENGINE *impl); + +int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in); +int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); +int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s); + +int EVP_read_pw_string(char *buf, int length, const char *prompt, int verify); +int EVP_read_pw_string_min(char *buf, int minlen, int maxlen, + const char *prompt, int verify); +void EVP_set_pw_prompt(const char *prompt); +char *EVP_get_pw_prompt(void); + +int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, + const unsigned char *salt, const unsigned char *data, int datal, int count, + unsigned char *key, unsigned char *iv); + +void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags); +void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags); +int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags); + +int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv); +int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, const unsigned char *iv); +int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); +#ifndef LIBRESSL_INTERNAL +int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); +#endif + +int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv); +int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, const unsigned char *iv); +int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); +#ifndef LIBRESSL_INTERNAL +int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); +#endif + +int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, int enc); +int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, const unsigned char *iv, int enc); +int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); +#ifndef LIBRESSL_INTERNAL +int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); +#endif + +int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s, + EVP_PKEY *pkey); + +int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, + unsigned int siglen, EVP_PKEY *pkey); + +int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); +int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen); + +int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); +int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen); + +int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + const unsigned char *ek, int ekl, const unsigned char *iv, EVP_PKEY *priv); +int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); + +int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + unsigned char **ek, int *ekl, unsigned char *iv, EVP_PKEY **pubk, + int npubk); +int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); + +void EVP_EncodeInit(EVP_ENCODE_CTX *ctx); +void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl); +int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n); + +void EVP_DecodeInit(EVP_ENCODE_CTX *ctx); +int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl); +int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n); + +void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a); +int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a); +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *a); +int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen); +int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad); +int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); +int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key); + +#ifndef OPENSSL_NO_BIO +BIO_METHOD *BIO_f_md(void); +BIO_METHOD *BIO_f_base64(void); +BIO_METHOD *BIO_f_cipher(void); +void BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k, + const unsigned char *i, int enc); +#endif + +const EVP_MD *EVP_md_null(void); +#ifndef OPENSSL_NO_MD4 +const EVP_MD *EVP_md4(void); +#endif +#ifndef OPENSSL_NO_MD5 +const EVP_MD *EVP_md5(void); +#endif +#ifndef OPENSSL_NO_SHA +const EVP_MD *EVP_sha1(void); +const EVP_MD *EVP_dss(void); +const EVP_MD *EVP_dss1(void); +const EVP_MD *EVP_ecdsa(void); +#endif +#ifndef OPENSSL_NO_SHA256 +const EVP_MD *EVP_sha224(void); +const EVP_MD *EVP_sha256(void); +#endif +#ifndef OPENSSL_NO_SHA512 +const EVP_MD *EVP_sha384(void); +const EVP_MD *EVP_sha512(void); +#endif +#ifndef OPENSSL_NO_RIPEMD +const EVP_MD *EVP_ripemd160(void); +#endif +#ifndef OPENSSL_NO_WHIRLPOOL +const EVP_MD *EVP_whirlpool(void); +#endif +#ifndef OPENSSL_NO_GOST +const EVP_MD *EVP_gostr341194(void); +const EVP_MD *EVP_gost2814789imit(void); +const EVP_MD *EVP_streebog256(void); +const EVP_MD *EVP_streebog512(void); +#endif +const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */ +#ifndef OPENSSL_NO_DES +const EVP_CIPHER *EVP_des_ecb(void); +const EVP_CIPHER *EVP_des_ede(void); +const EVP_CIPHER *EVP_des_ede3(void); +const EVP_CIPHER *EVP_des_ede_ecb(void); +const EVP_CIPHER *EVP_des_ede3_ecb(void); +const EVP_CIPHER *EVP_des_cfb64(void); +# define EVP_des_cfb EVP_des_cfb64 +const EVP_CIPHER *EVP_des_cfb1(void); +const EVP_CIPHER *EVP_des_cfb8(void); +const EVP_CIPHER *EVP_des_ede_cfb64(void); +# define EVP_des_ede_cfb EVP_des_ede_cfb64 +const EVP_CIPHER *EVP_des_ede3_cfb64(void); +# define EVP_des_ede3_cfb EVP_des_ede3_cfb64 +const EVP_CIPHER *EVP_des_ede3_cfb1(void); +const EVP_CIPHER *EVP_des_ede3_cfb8(void); +const EVP_CIPHER *EVP_des_ofb(void); +const EVP_CIPHER *EVP_des_ede_ofb(void); +const EVP_CIPHER *EVP_des_ede3_ofb(void); +const EVP_CIPHER *EVP_des_cbc(void); +const EVP_CIPHER *EVP_des_ede_cbc(void); +const EVP_CIPHER *EVP_des_ede3_cbc(void); +const EVP_CIPHER *EVP_desx_cbc(void); +#endif +#ifndef OPENSSL_NO_RC4 +const EVP_CIPHER *EVP_rc4(void); +const EVP_CIPHER *EVP_rc4_40(void); +#ifndef OPENSSL_NO_MD5 +const EVP_CIPHER *EVP_rc4_hmac_md5(void); +#endif +#endif +#ifndef OPENSSL_NO_IDEA +const EVP_CIPHER *EVP_idea_ecb(void); +const EVP_CIPHER *EVP_idea_cfb64(void); +# define EVP_idea_cfb EVP_idea_cfb64 +const EVP_CIPHER *EVP_idea_ofb(void); +const EVP_CIPHER *EVP_idea_cbc(void); +#endif +#ifndef OPENSSL_NO_RC2 +const EVP_CIPHER *EVP_rc2_ecb(void); +const EVP_CIPHER *EVP_rc2_cbc(void); +const EVP_CIPHER *EVP_rc2_40_cbc(void); +const EVP_CIPHER *EVP_rc2_64_cbc(void); +const EVP_CIPHER *EVP_rc2_cfb64(void); +# define EVP_rc2_cfb EVP_rc2_cfb64 +const EVP_CIPHER *EVP_rc2_ofb(void); +#endif +#ifndef OPENSSL_NO_BF +const EVP_CIPHER *EVP_bf_ecb(void); +const EVP_CIPHER *EVP_bf_cbc(void); +const EVP_CIPHER *EVP_bf_cfb64(void); +# define EVP_bf_cfb EVP_bf_cfb64 +const EVP_CIPHER *EVP_bf_ofb(void); +#endif +#ifndef OPENSSL_NO_CAST +const EVP_CIPHER *EVP_cast5_ecb(void); +const EVP_CIPHER *EVP_cast5_cbc(void); +const EVP_CIPHER *EVP_cast5_cfb64(void); +# define EVP_cast5_cfb EVP_cast5_cfb64 +const EVP_CIPHER *EVP_cast5_ofb(void); +#endif +#ifndef OPENSSL_NO_AES +const EVP_CIPHER *EVP_aes_128_ecb(void); +const EVP_CIPHER *EVP_aes_128_cbc(void); +const EVP_CIPHER *EVP_aes_128_cfb1(void); +const EVP_CIPHER *EVP_aes_128_cfb8(void); +const EVP_CIPHER *EVP_aes_128_cfb128(void); +# define EVP_aes_128_cfb EVP_aes_128_cfb128 +const EVP_CIPHER *EVP_aes_128_ofb(void); +const EVP_CIPHER *EVP_aes_128_ctr(void); +const EVP_CIPHER *EVP_aes_128_ccm(void); +const EVP_CIPHER *EVP_aes_128_gcm(void); +const EVP_CIPHER *EVP_aes_128_xts(void); +const EVP_CIPHER *EVP_aes_192_ecb(void); +const EVP_CIPHER *EVP_aes_192_cbc(void); +const EVP_CIPHER *EVP_aes_192_cfb1(void); +const EVP_CIPHER *EVP_aes_192_cfb8(void); +const EVP_CIPHER *EVP_aes_192_cfb128(void); +# define EVP_aes_192_cfb EVP_aes_192_cfb128 +const EVP_CIPHER *EVP_aes_192_ofb(void); +const EVP_CIPHER *EVP_aes_192_ctr(void); +const EVP_CIPHER *EVP_aes_192_ccm(void); +const EVP_CIPHER *EVP_aes_192_gcm(void); +const EVP_CIPHER *EVP_aes_256_ecb(void); +const EVP_CIPHER *EVP_aes_256_cbc(void); +const EVP_CIPHER *EVP_aes_256_cfb1(void); +const EVP_CIPHER *EVP_aes_256_cfb8(void); +const EVP_CIPHER *EVP_aes_256_cfb128(void); +# define EVP_aes_256_cfb EVP_aes_256_cfb128 +const EVP_CIPHER *EVP_aes_256_ofb(void); +const EVP_CIPHER *EVP_aes_256_ctr(void); +const EVP_CIPHER *EVP_aes_256_ccm(void); +const EVP_CIPHER *EVP_aes_256_gcm(void); +const EVP_CIPHER *EVP_aes_256_xts(void); +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void); +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void); +#endif +#endif +#ifndef OPENSSL_NO_CAMELLIA +const EVP_CIPHER *EVP_camellia_128_ecb(void); +const EVP_CIPHER *EVP_camellia_128_cbc(void); +const EVP_CIPHER *EVP_camellia_128_cfb1(void); +const EVP_CIPHER *EVP_camellia_128_cfb8(void); +const EVP_CIPHER *EVP_camellia_128_cfb128(void); +# define EVP_camellia_128_cfb EVP_camellia_128_cfb128 +const EVP_CIPHER *EVP_camellia_128_ofb(void); +const EVP_CIPHER *EVP_camellia_192_ecb(void); +const EVP_CIPHER *EVP_camellia_192_cbc(void); +const EVP_CIPHER *EVP_camellia_192_cfb1(void); +const EVP_CIPHER *EVP_camellia_192_cfb8(void); +const EVP_CIPHER *EVP_camellia_192_cfb128(void); +# define EVP_camellia_192_cfb EVP_camellia_192_cfb128 +const EVP_CIPHER *EVP_camellia_192_ofb(void); +const EVP_CIPHER *EVP_camellia_256_ecb(void); +const EVP_CIPHER *EVP_camellia_256_cbc(void); +const EVP_CIPHER *EVP_camellia_256_cfb1(void); +const EVP_CIPHER *EVP_camellia_256_cfb8(void); +const EVP_CIPHER *EVP_camellia_256_cfb128(void); +# define EVP_camellia_256_cfb EVP_camellia_256_cfb128 +const EVP_CIPHER *EVP_camellia_256_ofb(void); +#endif + +#ifndef OPENSSL_NO_CHACHA +const EVP_CIPHER *EVP_chacha20(void); +#endif + +#ifndef OPENSSL_NO_GOST +const EVP_CIPHER *EVP_gost2814789_ecb(void); +const EVP_CIPHER *EVP_gost2814789_cfb64(void); +const EVP_CIPHER *EVP_gost2814789_cnt(void); +#endif + +void OPENSSL_add_all_algorithms_noconf(void); +void OPENSSL_add_all_algorithms_conf(void); + +#ifdef OPENSSL_LOAD_CONF +#define OpenSSL_add_all_algorithms() OPENSSL_add_all_algorithms_conf() +#else +#define OpenSSL_add_all_algorithms() OPENSSL_add_all_algorithms_noconf() +#endif + +void OpenSSL_add_all_ciphers(void); +void OpenSSL_add_all_digests(void); + +#define SSLeay_add_all_algorithms() OpenSSL_add_all_algorithms() +#define SSLeay_add_all_ciphers() OpenSSL_add_all_ciphers() +#define SSLeay_add_all_digests() OpenSSL_add_all_digests() + +int EVP_add_cipher(const EVP_CIPHER *cipher); +int EVP_add_digest(const EVP_MD *digest); + +const EVP_CIPHER *EVP_get_cipherbyname(const char *name); +const EVP_MD *EVP_get_digestbyname(const char *name); +void EVP_cleanup(void); + +void EVP_CIPHER_do_all(void (*fn)(const EVP_CIPHER *ciph, const char *from, + const char *to, void *x), void *arg); +void EVP_CIPHER_do_all_sorted(void (*fn)(const EVP_CIPHER *ciph, + const char *from, const char *to, void *x), void *arg); + +void EVP_MD_do_all(void (*fn)(const EVP_MD *ciph, const char *from, + const char *to, void *x), void *arg); +void EVP_MD_do_all_sorted(void (*fn)(const EVP_MD *ciph, const char *from, + const char *to, void *x), void *arg); + +int EVP_PKEY_decrypt_old(unsigned char *dec_key, const unsigned char *enc_key, + int enc_key_len, EVP_PKEY *private_key); +int EVP_PKEY_encrypt_old(unsigned char *enc_key, const unsigned char *key, + int key_len, EVP_PKEY *pub_key); +int EVP_PKEY_type(int type); +int EVP_PKEY_id(const EVP_PKEY *pkey); +int EVP_PKEY_base_id(const EVP_PKEY *pkey); +int EVP_PKEY_bits(EVP_PKEY *pkey); +int EVP_PKEY_size(EVP_PKEY *pkey); +int EVP_PKEY_set_type(EVP_PKEY *pkey, int type); +int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len); +int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); +void *EVP_PKEY_get0(EVP_PKEY *pkey); + +#ifndef OPENSSL_NO_RSA +struct rsa_st; +int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key); +struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey); +#endif +#ifndef OPENSSL_NO_DSA +struct dsa_st; +int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, struct dsa_st *key); +struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey); +#endif +#ifndef OPENSSL_NO_DH +struct dh_st; +int EVP_PKEY_set1_DH(EVP_PKEY *pkey, struct dh_st *key); +struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey); +#endif +#ifndef OPENSSL_NO_EC +struct ec_key_st; +int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key); +struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); +#endif +#ifndef OPENSSL_NO_GOST +struct gost_key_st; +#endif + +EVP_PKEY *EVP_PKEY_new(void); +void EVP_PKEY_free(EVP_PKEY *pkey); + +EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length); +int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp); + +EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length); +EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, + long length); +int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp); + +int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from); +int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey); +int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode); +int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b); + +int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); + +int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); +int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); +int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + +int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid); + +int EVP_CIPHER_type(const EVP_CIPHER *ctx); + +/* calls methods */ +int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + +/* These are used by EVP_CIPHER methods */ +int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + +/* PKCS5 password based encryption */ +int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, int en_de); +int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, int keylen, + unsigned char *out); +int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, const unsigned char *salt, + int saltlen, int iter, const EVP_MD *digest, int keylen, + unsigned char *out); +int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, + int en_de); + +void PKCS5_PBE_add(void); + +int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen, + ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de); + +/* PBE type */ + +/* Can appear as the outermost AlgorithmIdentifier */ +#define EVP_PBE_TYPE_OUTER 0x0 +/* Is an PRF type OID */ +#define EVP_PBE_TYPE_PRF 0x1 + +int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid, + EVP_PBE_KEYGEN *keygen); +int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, + EVP_PBE_KEYGEN *keygen); +int EVP_PBE_find(int type, int pbe_nid, int *pcnid, int *pmnid, + EVP_PBE_KEYGEN **pkeygen); +void EVP_PBE_cleanup(void); + +#define ASN1_PKEY_ALIAS 0x1 +#define ASN1_PKEY_DYNAMIC 0x2 +#define ASN1_PKEY_SIGPARAM_NULL 0x4 + +#define ASN1_PKEY_CTRL_PKCS7_SIGN 0x1 +#define ASN1_PKEY_CTRL_PKCS7_ENCRYPT 0x2 +#define ASN1_PKEY_CTRL_DEFAULT_MD_NID 0x3 +#define ASN1_PKEY_CTRL_CMS_SIGN 0x5 +#define ASN1_PKEY_CTRL_CMS_ENVELOPE 0x7 + +int EVP_PKEY_asn1_get_count(void); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, + const char *str, int len); +int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth); +int EVP_PKEY_asn1_add_alias(int to, int from); +int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id, int *ppkey_flags, + const char **pinfo, const char **ppem_str, + const EVP_PKEY_ASN1_METHOD *ameth); + +const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey); +EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags, const char *pem_str, + const char *info); +void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, + const EVP_PKEY_ASN1_METHOD *src); +void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth); +void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, + int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub), + int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk), + int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b), + int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx), + int (*pkey_size)(const EVP_PKEY *pk), + int (*pkey_bits)(const EVP_PKEY *pk)); +void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth, + int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf), + int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk), + int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx)); +void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth, + int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder, int derlen), + int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder), + int (*param_missing)(const EVP_PKEY *pk), + int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from), + int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b), + int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx)); + +void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth, + void (*pkey_free)(EVP_PKEY *pkey)); +void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2)); + +#define EVP_PKEY_OP_UNDEFINED 0 +#define EVP_PKEY_OP_PARAMGEN (1<<1) +#define EVP_PKEY_OP_KEYGEN (1<<2) +#define EVP_PKEY_OP_SIGN (1<<3) +#define EVP_PKEY_OP_VERIFY (1<<4) +#define EVP_PKEY_OP_VERIFYRECOVER (1<<5) +#define EVP_PKEY_OP_SIGNCTX (1<<6) +#define EVP_PKEY_OP_VERIFYCTX (1<<7) +#define EVP_PKEY_OP_ENCRYPT (1<<8) +#define EVP_PKEY_OP_DECRYPT (1<<9) +#define EVP_PKEY_OP_DERIVE (1<<10) + +#define EVP_PKEY_OP_TYPE_SIG \ + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \ + | EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX) + +#define EVP_PKEY_OP_TYPE_CRYPT \ + (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT) + +#define EVP_PKEY_OP_TYPE_NOGEN \ + (EVP_PKEY_OP_SIG | EVP_PKEY_OP_CRYPT | EVP_PKEY_OP_DERIVE) + +#define EVP_PKEY_OP_TYPE_GEN \ + (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN) + +#define EVP_PKEY_CTX_set_signature_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \ + EVP_PKEY_CTRL_MD, 0, (void *)md) + +#define EVP_PKEY_CTRL_MD 1 +#define EVP_PKEY_CTRL_PEER_KEY 2 + +#define EVP_PKEY_CTRL_PKCS7_ENCRYPT 3 +#define EVP_PKEY_CTRL_PKCS7_DECRYPT 4 + +#define EVP_PKEY_CTRL_PKCS7_SIGN 5 + +#define EVP_PKEY_CTRL_SET_MAC_KEY 6 + +#define EVP_PKEY_CTRL_DIGESTINIT 7 + +/* Used by GOST key encryption in TLS */ +#define EVP_PKEY_CTRL_SET_IV 8 + +#define EVP_PKEY_CTRL_CMS_ENCRYPT 9 +#define EVP_PKEY_CTRL_CMS_DECRYPT 10 +#define EVP_PKEY_CTRL_CMS_SIGN 11 + +#define EVP_PKEY_CTRL_CIPHER 12 + +#define EVP_PKEY_ALG_CTRL 0x1000 + + +#define EVP_PKEY_FLAG_AUTOARGLEN 2 +/* Method handles all operations: don't assume any digest related + * defaults. + */ +#define EVP_PKEY_FLAG_SIGCTX_CUSTOM 4 + +const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type); +EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags); +void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, + const EVP_PKEY_METHOD *meth); +void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src); +void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth); +int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth); + +EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx); +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, + int p1, void *p2); +int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, + const char *value); + +int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx); +void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen); + +EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, const unsigned char *key, + int keylen); + +void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data); +void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx); +EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx); + +EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx); + +void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data); +void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); +int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen); +int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, unsigned char *rout, + size_t *routlen, const unsigned char *sig, size_t siglen); +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); + +typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); + +void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb); +EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx); + +void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, + int (*init)(EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, + int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)); + +void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, + void (*cleanup)(EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, + int (*paramgen_init)(EVP_PKEY_CTX *ctx), + int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, + int (*keygen_init)(EVP_PKEY_CTX *ctx), + int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, + int (*sign_init)(EVP_PKEY_CTX *ctx), + int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen)); + +void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, + int (*verify_init)(EVP_PKEY_CTX *ctx), + int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen)); + +void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, + int (*verify_recover_init)(EVP_PKEY_CTX *ctx), + int (*verify_recover)(EVP_PKEY_CTX *ctx, unsigned char *sig, + size_t *siglen, const unsigned char *tbs, size_t tbslen)); + +void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, + int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx), + int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, + int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx), + int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, + int (*encrypt_init)(EVP_PKEY_CTX *ctx), + int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen)); + +void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, + int (*decrypt_init)(EVP_PKEY_CTX *ctx), + int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen)); + +void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, + int (*derive_init)(EVP_PKEY_CTX *ctx), + int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)); + +void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, + int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2), + int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value)); + +/* Authenticated Encryption with Additional Data. + * + * AEAD couples confidentiality and integrity in a single primtive. AEAD + * algorithms take a key and then can seal and open individual messages. Each + * message has a unique, per-message nonce and, optionally, additional data + * which is authenticated but not included in the output. */ + +struct evp_aead_st; +typedef struct evp_aead_st EVP_AEAD; + +#ifndef OPENSSL_NO_AES +/* EVP_aes_128_gcm is AES-128 in Galois Counter Mode. */ +const EVP_AEAD *EVP_aead_aes_128_gcm(void); +/* EVP_aes_256_gcm is AES-256 in Galois Counter Mode. */ +const EVP_AEAD *EVP_aead_aes_256_gcm(void); +#endif + +#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) +/* EVP_aead_chacha20_poly1305 is ChaCha20 with a Poly1305 authenticator. */ +const EVP_AEAD *EVP_aead_chacha20_poly1305(void); +const EVP_AEAD *EVP_aead_chacha20_poly1305_old(void); +#endif + +/* EVP_AEAD_key_length returns the length of the keys used. */ +size_t EVP_AEAD_key_length(const EVP_AEAD *aead); + +/* EVP_AEAD_nonce_length returns the length of the per-message nonce. */ +size_t EVP_AEAD_nonce_length(const EVP_AEAD *aead); + +/* EVP_AEAD_max_overhead returns the maximum number of additional bytes added + * by the act of sealing data with the AEAD. */ +size_t EVP_AEAD_max_overhead(const EVP_AEAD *aead); + +/* EVP_AEAD_max_tag_len returns the maximum tag length when using this AEAD. + * This * is the largest value that can be passed as a tag length to + * EVP_AEAD_CTX_init. */ +size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead); + +/* An EVP_AEAD_CTX represents an AEAD algorithm configured with a specific key + * and message-independent IV. */ +typedef struct evp_aead_ctx_st { + const EVP_AEAD *aead; + /* aead_state is an opaque pointer to the AEAD specific state. */ + void *aead_state; +} EVP_AEAD_CTX; + +/* EVP_AEAD_MAX_TAG_LENGTH is the maximum tag length used by any AEAD + * defined in this header. */ +#define EVP_AEAD_MAX_TAG_LENGTH 16 + +/* EVP_AEAD_DEFAULT_TAG_LENGTH is a magic value that can be passed to + * EVP_AEAD_CTX_init to indicate that the default tag length for an AEAD + * should be used. */ +#define EVP_AEAD_DEFAULT_TAG_LENGTH 0 + +/* EVP_AEAD_init initializes the context for the given AEAD algorithm. + * The implementation argument may be NULL to choose the default implementation. + * Authentication tags may be truncated by passing a tag length. A tag length + * of zero indicates the default tag length should be used. */ +int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, + const unsigned char *key, size_t key_len, size_t tag_len, ENGINE *impl); + +/* EVP_AEAD_CTX_cleanup frees any data allocated for this context. */ +void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx); + +/* EVP_AEAD_CTX_seal encrypts and authenticates the input and authenticates + * any additional data (AD), the result being written as output. One is + * returned on success, otherwise zero. + * + * This function may be called (with the same EVP_AEAD_CTX) concurrently with + * itself or EVP_AEAD_CTX_open. + * + * At most max_out_len bytes are written as output and, in order to ensure + * success, this value should be the length of the input plus the result of + * EVP_AEAD_overhead. On successful return, out_len is set to the actual + * number of bytes written. + * + * The length of the nonce is must be equal to the result of + * EVP_AEAD_nonce_length for this AEAD. + * + * EVP_AEAD_CTX_seal never results in a partial output. If max_out_len is + * insufficient, zero will be returned and out_len will be set to zero. + * + * If the input and output are aliased then out must be <= in. */ +int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, + size_t *out_len, size_t max_out_len, const unsigned char *nonce, + size_t nonce_len, const unsigned char *in, size_t in_len, + const unsigned char *ad, size_t ad_len); + +/* EVP_AEAD_CTX_open authenticates the input and additional data, decrypting + * the input and writing it as output. One is returned on success, otherwise + * zero. + * + * This function may be called (with the same EVP_AEAD_CTX) concurrently with + * itself or EVP_AEAD_CTX_seal. + * + * At most the number of input bytes are written as output. In order to ensure + * success, max_out_len should be at least the same as the input length. On + * successful return out_len is set to the actual number of bytes written. + * + * The length of nonce must be equal to the result of EVP_AEAD_nonce_length + * for this AEAD. + * + * EVP_AEAD_CTX_open never results in a partial output. If max_out_len is + * insufficient, zero will be returned and out_len will be set to zero. + * + * If the input and output are aliased then out must be <= in. */ +int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, unsigned char *out, + size_t *out_len, size_t max_out_len, const unsigned char *nonce, + size_t nonce_len, const unsigned char *in, size_t in_len, + const unsigned char *ad, size_t ad_len); + +void EVP_add_alg_module(void); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_EVP_strings(void); + +/* Error codes for the EVP functions. */ + +/* Function codes. */ +#define EVP_F_AEAD_AES_GCM_INIT 187 +#define EVP_F_AEAD_AES_GCM_OPEN 188 +#define EVP_F_AEAD_AES_GCM_SEAL 189 +#define EVP_F_AEAD_CHACHA20_POLY1305_INIT 192 +#define EVP_F_AEAD_CHACHA20_POLY1305_OPEN 193 +#define EVP_F_AEAD_CHACHA20_POLY1305_SEAL 194 +#define EVP_F_AEAD_CTX_OPEN 185 +#define EVP_F_AEAD_CTX_SEAL 186 +#define EVP_F_AESNI_INIT_KEY 165 +#define EVP_F_AESNI_XTS_CIPHER 176 +#define EVP_F_AES_INIT_KEY 133 +#define EVP_F_AES_XTS 172 +#define EVP_F_AES_XTS_CIPHER 175 +#define EVP_F_ALG_MODULE_INIT 177 +#define EVP_F_CAMELLIA_INIT_KEY 159 +#define EVP_F_CMAC_INIT 173 +#define EVP_F_D2I_PKEY 100 +#define EVP_F_DO_SIGVER_INIT 161 +#define EVP_F_DSAPKEY2PKCS8 134 +#define EVP_F_DSA_PKEY2PKCS8 135 +#define EVP_F_ECDSA_PKEY2PKCS8 129 +#define EVP_F_ECKEY_PKEY2PKCS8 132 +#define EVP_F_EVP_AEAD_CTX_INIT 180 +#define EVP_F_EVP_AEAD_CTX_OPEN 190 +#define EVP_F_EVP_AEAD_CTX_SEAL 191 +#define EVP_F_EVP_BYTESTOKEY 200 +#define EVP_F_EVP_CIPHERINIT_EX 123 +#define EVP_F_EVP_CIPHER_CTX_COPY 163 +#define EVP_F_EVP_CIPHER_CTX_CTRL 124 +#define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122 +#define EVP_F_EVP_CIPHER_GET_ASN1_IV 201 +#define EVP_F_EVP_CIPHER_SET_ASN1_IV 202 +#define EVP_F_EVP_DECRYPTFINAL_EX 101 +#define EVP_F_EVP_DECRYPTUPDATE 199 +#define EVP_F_EVP_DIGESTFINAL_EX 196 +#define EVP_F_EVP_DIGESTINIT_EX 128 +#define EVP_F_EVP_ENCRYPTFINAL_EX 127 +#define EVP_F_EVP_ENCRYPTUPDATE 198 +#define EVP_F_EVP_MD_CTX_COPY_EX 110 +#define EVP_F_EVP_MD_CTX_CTRL 195 +#define EVP_F_EVP_MD_SIZE 162 +#define EVP_F_EVP_OPENINIT 102 +#define EVP_F_EVP_PBE_ALG_ADD 115 +#define EVP_F_EVP_PBE_ALG_ADD_TYPE 160 +#define EVP_F_EVP_PBE_CIPHERINIT 116 +#define EVP_F_EVP_PKCS82PKEY 111 +#define EVP_F_EVP_PKCS82PKEY_BROKEN 136 +#define EVP_F_EVP_PKEY2PKCS8_BROKEN 113 +#define EVP_F_EVP_PKEY_COPY_PARAMETERS 103 +#define EVP_F_EVP_PKEY_CTX_CTRL 137 +#define EVP_F_EVP_PKEY_CTX_CTRL_STR 150 +#define EVP_F_EVP_PKEY_CTX_DUP 156 +#define EVP_F_EVP_PKEY_DECRYPT 104 +#define EVP_F_EVP_PKEY_DECRYPT_INIT 138 +#define EVP_F_EVP_PKEY_DECRYPT_OLD 151 +#define EVP_F_EVP_PKEY_DERIVE 153 +#define EVP_F_EVP_PKEY_DERIVE_INIT 154 +#define EVP_F_EVP_PKEY_DERIVE_SET_PEER 155 +#define EVP_F_EVP_PKEY_ENCRYPT 105 +#define EVP_F_EVP_PKEY_ENCRYPT_INIT 139 +#define EVP_F_EVP_PKEY_ENCRYPT_OLD 152 +#define EVP_F_EVP_PKEY_GET1_DH 119 +#define EVP_F_EVP_PKEY_GET1_DSA 120 +#define EVP_F_EVP_PKEY_GET1_ECDSA 130 +#define EVP_F_EVP_PKEY_GET1_EC_KEY 131 +#define EVP_F_EVP_PKEY_GET1_RSA 121 +#define EVP_F_EVP_PKEY_KEYGEN 146 +#define EVP_F_EVP_PKEY_KEYGEN_INIT 147 +#define EVP_F_EVP_PKEY_NEW 106 +#define EVP_F_EVP_PKEY_PARAMGEN 148 +#define EVP_F_EVP_PKEY_PARAMGEN_INIT 149 +#define EVP_F_EVP_PKEY_SIGN 140 +#define EVP_F_EVP_PKEY_SIGN_INIT 141 +#define EVP_F_EVP_PKEY_VERIFY 142 +#define EVP_F_EVP_PKEY_VERIFY_INIT 143 +#define EVP_F_EVP_PKEY_VERIFY_RECOVER 144 +#define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT 145 +#define EVP_F_EVP_RIJNDAEL 126 +#define EVP_F_EVP_SIGNFINAL 107 +#define EVP_F_EVP_VERIFYFINAL 108 +#define EVP_F_FIPS_CIPHERINIT 166 +#define EVP_F_FIPS_CIPHER_CTX_COPY 170 +#define EVP_F_FIPS_CIPHER_CTX_CTRL 167 +#define EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH 171 +#define EVP_F_FIPS_DIGESTINIT 168 +#define EVP_F_FIPS_MD_CTX_COPY 169 +#define EVP_F_HMAC_INIT_EX 174 +#define EVP_F_INT_CTX_NEW 157 +#define EVP_F_PKCS5_PBE_KEYIVGEN 117 +#define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118 +#define EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN 164 +#define EVP_F_PKCS8_SET_BROKEN 112 +#define EVP_F_PKEY_SET_TYPE 158 +#define EVP_F_RC2_GET_ASN1_TYPE_AND_IV 197 +#define EVP_F_RC2_MAGIC_TO_METH 109 +#define EVP_F_RC5_CTRL 125 + +/* Reason codes. */ +#define EVP_R_AES_IV_SETUP_FAILED 162 +#define EVP_R_AES_KEY_SETUP_FAILED 143 +#define EVP_R_ASN1_LIB 140 +#define EVP_R_BAD_BLOCK_LENGTH 136 +#define EVP_R_BAD_DECRYPT 100 +#define EVP_R_BAD_KEY_LENGTH 137 +#define EVP_R_BN_DECODE_ERROR 112 +#define EVP_R_BN_PUBKEY_ERROR 113 +#define EVP_R_BUFFER_TOO_SMALL 155 +#define EVP_R_CAMELLIA_KEY_SETUP_FAILED 157 +#define EVP_R_CIPHER_PARAMETER_ERROR 122 +#define EVP_R_COMMAND_NOT_SUPPORTED 147 +#define EVP_R_CTRL_NOT_IMPLEMENTED 132 +#define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED 133 +#define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138 +#define EVP_R_DECODE_ERROR 114 +#define EVP_R_DIFFERENT_KEY_TYPES 101 +#define EVP_R_DIFFERENT_PARAMETERS 153 +#define EVP_R_DISABLED_FOR_FIPS 163 +#define EVP_R_ENCODE_ERROR 115 +#define EVP_R_ERROR_LOADING_SECTION 165 +#define EVP_R_ERROR_SETTING_FIPS_MODE 166 +#define EVP_R_EVP_PBE_CIPHERINIT_ERROR 119 +#define EVP_R_EXPECTING_AN_RSA_KEY 127 +#define EVP_R_EXPECTING_A_DH_KEY 128 +#define EVP_R_EXPECTING_A_DSA_KEY 129 +#define EVP_R_EXPECTING_A_ECDSA_KEY 141 +#define EVP_R_EXPECTING_A_EC_KEY 142 +#define EVP_R_FIPS_MODE_NOT_SUPPORTED 167 +#define EVP_R_INITIALIZATION_ERROR 134 +#define EVP_R_INPUT_NOT_INITIALIZED 111 +#define EVP_R_INVALID_DIGEST 152 +#define EVP_R_INVALID_FIPS_MODE 168 +#define EVP_R_INVALID_KEY_LENGTH 130 +#define EVP_R_INVALID_OPERATION 148 +#define EVP_R_IV_TOO_LARGE 102 +#define EVP_R_KEYGEN_FAILURE 120 +#define EVP_R_MESSAGE_DIGEST_IS_NULL 159 +#define EVP_R_METHOD_NOT_SUPPORTED 144 +#define EVP_R_MISSING_PARAMETERS 103 +#define EVP_R_NO_CIPHER_SET 131 +#define EVP_R_NO_DEFAULT_DIGEST 158 +#define EVP_R_NO_DIGEST_SET 139 +#define EVP_R_NO_DSA_PARAMETERS 116 +#define EVP_R_NO_KEY_SET 154 +#define EVP_R_NO_OPERATION_SET 149 +#define EVP_R_NO_SIGN_FUNCTION_CONFIGURED 104 +#define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105 +#define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150 +#define EVP_R_OPERATON_NOT_INITIALIZED 151 +#define EVP_R_OUTPUT_ALIASES_INPUT 172 +#define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE 117 +#define EVP_R_PRIVATE_KEY_DECODE_ERROR 145 +#define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146 +#define EVP_R_PUBLIC_KEY_NOT_RSA 106 +#define EVP_R_TAG_TOO_LARGE 171 +#define EVP_R_TOO_LARGE 164 +#define EVP_R_UNKNOWN_CIPHER 160 +#define EVP_R_UNKNOWN_DIGEST 161 +#define EVP_R_UNKNOWN_OPTION 169 +#define EVP_R_UNKNOWN_PBE_ALGORITHM 121 +#define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS 135 +#define EVP_R_UNSUPPORTED_ALGORITHM 156 +#define EVP_R_UNSUPPORTED_CIPHER 107 +#define EVP_R_UNSUPPORTED_KEYLENGTH 123 +#define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 124 +#define EVP_R_UNSUPPORTED_KEY_SIZE 108 +#define EVP_R_UNSUPPORTED_PRF 125 +#define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM 118 +#define EVP_R_UNSUPPORTED_SALT_TYPE 126 +#define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109 +#define EVP_R_WRONG_PUBLIC_KEY_TYPE 110 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/gost.h b/crypto/libressl/include/openssl/gost.h new file mode 100644 index 0000000000..f6f1007763 --- /dev/null +++ b/crypto/libressl/include/openssl/gost.h @@ -0,0 +1,262 @@ +/* $OpenBSD: gost.h,v 1.1 2014/11/09 19:17:13 miod Exp $ */ +/* + * Copyright (c) 2014 Dmitry Eremin-Solenikov + * Copyright (c) 2005-2006 Cryptocom LTD + * + * 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_GOST_H +#define HEADER_GOST_H + +#include + +#ifdef OPENSSL_NO_GOST +#error GOST is disabled. +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct gost2814789_key_st { + unsigned int key[8]; + unsigned int k87[256],k65[256],k43[256],k21[256]; + unsigned int count; + unsigned key_meshing : 1; +} GOST2814789_KEY; + +int Gost2814789_set_sbox(GOST2814789_KEY *key, int nid); +int Gost2814789_set_key(GOST2814789_KEY *key, + const unsigned char *userKey, const int bits); +void Gost2814789_ecb_encrypt(const unsigned char *in, unsigned char *out, + GOST2814789_KEY *key, const int enc); +void Gost2814789_cfb64_encrypt(const unsigned char *in, unsigned char *out, + size_t length, GOST2814789_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Gost2814789_cnt_encrypt(const unsigned char *in, unsigned char *out, + size_t length, GOST2814789_KEY *key, + unsigned char *ivec, unsigned char *cnt_buf, int *num); + +typedef struct { + ASN1_OCTET_STRING *iv; + ASN1_OBJECT *enc_param_set; +} GOST_CIPHER_PARAMS; + +DECLARE_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS) + +#define GOST2814789IMIT_LENGTH 4 +#define GOST2814789IMIT_CBLOCK 8 +#define GOST2814789IMIT_LONG unsigned int + +typedef struct GOST2814789IMITstate_st { + GOST2814789IMIT_LONG Nl, Nh; + unsigned char data[GOST2814789IMIT_CBLOCK]; + unsigned int num; + + GOST2814789_KEY cipher; + unsigned char mac[GOST2814789IMIT_CBLOCK]; +} GOST2814789IMIT_CTX; + +/* Note, also removed second parameter and removed dctx->cipher setting */ +int GOST2814789IMIT_Init(GOST2814789IMIT_CTX *c, int nid); +int GOST2814789IMIT_Update(GOST2814789IMIT_CTX *c, const void *data, size_t len); +int GOST2814789IMIT_Final(unsigned char *md, GOST2814789IMIT_CTX *c); +void GOST2814789IMIT_Transform(GOST2814789IMIT_CTX *c, const unsigned char *data); +unsigned char *GOST2814789IMIT(const unsigned char *d, size_t n, + unsigned char *md, int nid, + const unsigned char *key, const unsigned char *iv); + +#define GOSTR341194_LONG unsigned int + +#define GOSTR341194_LENGTH 32 +#define GOSTR341194_CBLOCK 32 +#define GOSTR341194_LBLOCK (GOSTR341194_CBLOCK/4) + +typedef struct GOSTR341194state_st { + GOSTR341194_LONG Nl, Nh; + GOSTR341194_LONG data[GOSTR341194_LBLOCK]; + unsigned int num; + + GOST2814789_KEY cipher; + unsigned char H[GOSTR341194_CBLOCK]; + unsigned char S[GOSTR341194_CBLOCK]; +} GOSTR341194_CTX; + +/* Note, also removed second parameter and removed dctx->cipher setting */ +int GOSTR341194_Init(GOSTR341194_CTX *c, int nid); +int GOSTR341194_Update(GOSTR341194_CTX *c, const void *data, size_t len); +int GOSTR341194_Final(unsigned char *md, GOSTR341194_CTX *c); +void GOSTR341194_Transform(GOSTR341194_CTX *c, const unsigned char *data); +unsigned char *GOSTR341194(const unsigned char *d, size_t n,unsigned char *md, int nid); + +#if defined(_LP64) +#define STREEBOG_LONG64 unsigned long +#define U64(C) C##UL +#else +#define STREEBOG_LONG64 unsigned long long +#define U64(C) C##ULL +#endif + +#define STREEBOG_LBLOCK 8 +#define STREEBOG_CBLOCK 64 +#define STREEBOG256_LENGTH 32 +#define STREEBOG512_LENGTH 64 + +typedef struct STREEBOGstate_st { + STREEBOG_LONG64 data[STREEBOG_LBLOCK]; + unsigned int num; + unsigned int md_len; + STREEBOG_LONG64 h[STREEBOG_LBLOCK]; + STREEBOG_LONG64 N[STREEBOG_LBLOCK]; + STREEBOG_LONG64 Sigma[STREEBOG_LBLOCK]; +} STREEBOG_CTX; + +int STREEBOG256_Init(STREEBOG_CTX *c); +int STREEBOG256_Update(STREEBOG_CTX *c, const void *data, size_t len); +int STREEBOG256_Final(unsigned char *md, STREEBOG_CTX *c); +void STREEBOG256_Transform(STREEBOG_CTX *c, const unsigned char *data); +unsigned char *STREEBOG256(const unsigned char *d, size_t n,unsigned char *md); + +int STREEBOG512_Init(STREEBOG_CTX *c); +int STREEBOG512_Update(STREEBOG_CTX *c, const void *data, size_t len); +int STREEBOG512_Final(unsigned char *md, STREEBOG_CTX *c); +void STREEBOG512_Transform(STREEBOG_CTX *c, const unsigned char *data); +unsigned char *STREEBOG512(const unsigned char *d, size_t n,unsigned char *md); + +typedef struct gost_key_st GOST_KEY; +GOST_KEY *GOST_KEY_new(void); +void GOST_KEY_free(GOST_KEY * r); +int GOST_KEY_check_key(const GOST_KEY * eckey); +int GOST_KEY_set_public_key_affine_coordinates(GOST_KEY * key, BIGNUM * x, BIGNUM * y); +const EC_GROUP * GOST_KEY_get0_group(const GOST_KEY * key); +int GOST_KEY_set_group(GOST_KEY * key, const EC_GROUP * group); +int GOST_KEY_get_digest(const GOST_KEY * key); +int GOST_KEY_set_digest(GOST_KEY * key, int digest_nid); +const BIGNUM * GOST_KEY_get0_private_key(const GOST_KEY * key); +int GOST_KEY_set_private_key(GOST_KEY * key, const BIGNUM * priv_key); +const EC_POINT * GOST_KEY_get0_public_key(const GOST_KEY * key); +int GOST_KEY_set_public_key(GOST_KEY * key, const EC_POINT * pub_key); +size_t GOST_KEY_get_size(const GOST_KEY * r); + +/* Gost-specific pmeth control-function parameters */ +/* For GOST R34.10 parameters */ +#define EVP_PKEY_CTRL_GOST_PARAMSET (EVP_PKEY_ALG_CTRL+1) +#define EVP_PKEY_CTRL_GOST_SIG_FORMAT (EVP_PKEY_ALG_CTRL+2) +#define EVP_PKEY_CTRL_GOST_SET_DIGEST (EVP_PKEY_ALG_CTRL+3) +#define EVP_PKEY_CTRL_GOST_GET_DIGEST (EVP_PKEY_ALG_CTRL+4) + +#define GOST_SIG_FORMAT_SR_BE 0 +#define GOST_SIG_FORMAT_RS_LE 1 + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_GOST_strings(void); + +/* Error codes for the GOST functions. */ + +/* Function codes. */ +#define GOST_F_DECODE_GOST01_ALGOR_PARAMS 104 +#define GOST_F_ENCODE_GOST01_ALGOR_PARAMS 105 +#define GOST_F_GOST2001_COMPUTE_PUBLIC 106 +#define GOST_F_GOST2001_DO_SIGN 107 +#define GOST_F_GOST2001_DO_VERIFY 108 +#define GOST_F_GOST2001_KEYGEN 109 +#define GOST_F_GOST89_GET_ASN1_PARAMETERS 102 +#define GOST_F_GOST89_SET_ASN1_PARAMETERS 103 +#define GOST_F_GOST_KEY_CHECK_KEY 124 +#define GOST_F_GOST_KEY_NEW 125 +#define GOST_F_GOST_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES 126 +#define GOST_F_PARAM_COPY_GOST01 110 +#define GOST_F_PARAM_DECODE_GOST01 111 +#define GOST_F_PKEY_GOST01_CTRL 116 +#define GOST_F_PKEY_GOST01_DECRYPT 112 +#define GOST_F_PKEY_GOST01_DERIVE 113 +#define GOST_F_PKEY_GOST01_ENCRYPT 114 +#define GOST_F_PKEY_GOST01_PARAMGEN 115 +#define GOST_F_PKEY_GOST01_SIGN 123 +#define GOST_F_PKEY_GOST_MAC_CTRL 100 +#define GOST_F_PKEY_GOST_MAC_KEYGEN 101 +#define GOST_F_PRIV_DECODE_GOST01 117 +#define GOST_F_PUB_DECODE_GOST01 118 +#define GOST_F_PUB_ENCODE_GOST01 119 +#define GOST_F_PUB_PRINT_GOST01 120 +#define GOST_F_UNPACK_SIGNATURE_CP 121 +#define GOST_F_UNPACK_SIGNATURE_LE 122 + +/* Reason codes. */ +#define GOST_R_BAD_KEY_PARAMETERS_FORMAT 104 +#define GOST_R_BAD_PKEY_PARAMETERS_FORMAT 105 +#define GOST_R_CANNOT_PACK_EPHEMERAL_KEY 106 +#define GOST_R_CTRL_CALL_FAILED 107 +#define GOST_R_ERROR_COMPUTING_SHARED_KEY 108 +#define GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO 109 +#define GOST_R_INCOMPATIBLE_ALGORITHMS 110 +#define GOST_R_INCOMPATIBLE_PEER_KEY 111 +#define GOST_R_INVALID_DIGEST_TYPE 100 +#define GOST_R_INVALID_IV_LENGTH 103 +#define GOST_R_INVALID_MAC_KEY_LENGTH 101 +#define GOST_R_KEY_IS_NOT_INITIALIZED 112 +#define GOST_R_KEY_PARAMETERS_MISSING 113 +#define GOST_R_MAC_KEY_NOT_SET 102 +#define GOST_R_NO_PARAMETERS_SET 115 +#define GOST_R_NO_PEER_KEY 116 +#define GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR 117 +#define GOST_R_PUBLIC_KEY_UNDEFINED 118 +#define GOST_R_RANDOM_NUMBER_GENERATOR_FAILED 120 +#define GOST_R_SIGNATURE_MISMATCH 121 +#define GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q 122 +#define GOST_R_UKM_NOT_SET 123 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/hmac.h b/crypto/libressl/include/openssl/hmac.h new file mode 100644 index 0000000000..700413907e --- /dev/null +++ b/crypto/libressl/include/openssl/hmac.h @@ -0,0 +1,108 @@ +/* $OpenBSD: hmac.h,v 1.11 2014/06/12 15:49:29 deraadt Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +#ifndef HEADER_HMAC_H +#define HEADER_HMAC_H + +#include + +#ifdef OPENSSL_NO_HMAC +#error HMAC is disabled. +#endif + +#include + +#define HMAC_MAX_MD_CBLOCK 128 /* largest known is SHA512 */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct hmac_ctx_st { + const EVP_MD *md; + EVP_MD_CTX md_ctx; + EVP_MD_CTX i_ctx; + EVP_MD_CTX o_ctx; + unsigned int key_length; + unsigned char key[HMAC_MAX_MD_CBLOCK]; +} HMAC_CTX; + +#define HMAC_size(e) (EVP_MD_size((e)->md)) + + +void HMAC_CTX_init(HMAC_CTX *ctx); +void HMAC_CTX_cleanup(HMAC_CTX *ctx); + +#define HMAC_cleanup(ctx) HMAC_CTX_cleanup(ctx) /* deprecated */ + +int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, + const EVP_MD *md); /* deprecated */ +int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, + ENGINE *impl); +int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len); +int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len); +unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, + const unsigned char *d, size_t n, unsigned char *md, unsigned int *md_len); +int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx); + +void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/libressl/include/openssl/idea.h b/crypto/libressl/include/openssl/idea.h new file mode 100644 index 0000000000..f8e069714b --- /dev/null +++ b/crypto/libressl/include/openssl/idea.h @@ -0,0 +1,100 @@ +/* $OpenBSD$ */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_IDEA_H +#define HEADER_IDEA_H + +#include /* IDEA_INT, OPENSSL_NO_IDEA */ + +#ifdef OPENSSL_NO_IDEA +#error IDEA is disabled. +#endif + +#define IDEA_ENCRYPT 1 +#define IDEA_DECRYPT 0 + +#define IDEA_BLOCK 8 +#define IDEA_KEY_LENGTH 16 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct idea_key_st + { + IDEA_INT data[9][6]; + } IDEA_KEY_SCHEDULE; + +const char *idea_options(void); +void idea_ecb_encrypt(const unsigned char *in, unsigned char *out, + IDEA_KEY_SCHEDULE *ks); +void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks); +void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk); +void idea_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,int enc); +void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int *num,int enc); +void idea_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, int *num); +void idea_encrypt(unsigned long *in, IDEA_KEY_SCHEDULE *ks); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/libressl/include/openssl/krb5_asn.h b/crypto/libressl/include/openssl/krb5_asn.h new file mode 100644 index 0000000000..648f5bcfc4 --- /dev/null +++ b/crypto/libressl/include/openssl/krb5_asn.h @@ -0,0 +1,256 @@ +/* $OpenBSD$ */ +/* Written by Vern Staats for the OpenSSL project, +** using ocsp/{*.h,*asn*.c} as a starting point +*/ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_KRB5_ASN_H +#define HEADER_KRB5_ASN_H + +/* +#include +*/ +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* ASN.1 from Kerberos RFC 1510 +*/ + +/* EncryptedData ::= SEQUENCE { +** etype[0] INTEGER, -- EncryptionType +** kvno[1] INTEGER OPTIONAL, +** cipher[2] OCTET STRING -- ciphertext +** } +*/ +typedef struct krb5_encdata_st + { + ASN1_INTEGER *etype; + ASN1_INTEGER *kvno; + ASN1_OCTET_STRING *cipher; + } KRB5_ENCDATA; + +DECLARE_STACK_OF(KRB5_ENCDATA) + +/* PrincipalName ::= SEQUENCE { +** name-type[0] INTEGER, +** name-string[1] SEQUENCE OF GeneralString +** } +*/ +typedef struct krb5_princname_st + { + ASN1_INTEGER *nametype; + STACK_OF(ASN1_GENERALSTRING) *namestring; + } KRB5_PRINCNAME; + +DECLARE_STACK_OF(KRB5_PRINCNAME) + + +/* Ticket ::= [APPLICATION 1] SEQUENCE { +** tkt-vno[0] INTEGER, +** realm[1] Realm, +** sname[2] PrincipalName, +** enc-part[3] EncryptedData +** } +*/ +typedef struct krb5_tktbody_st + { + ASN1_INTEGER *tktvno; + ASN1_GENERALSTRING *realm; + KRB5_PRINCNAME *sname; + KRB5_ENCDATA *encdata; + } KRB5_TKTBODY; + +typedef STACK_OF(KRB5_TKTBODY) KRB5_TICKET; +DECLARE_STACK_OF(KRB5_TKTBODY) + + +/* AP-REQ ::= [APPLICATION 14] SEQUENCE { +** pvno[0] INTEGER, +** msg-type[1] INTEGER, +** ap-options[2] APOptions, +** ticket[3] Ticket, +** authenticator[4] EncryptedData +** } +** +** APOptions ::= BIT STRING { +** reserved(0), use-session-key(1), mutual-required(2) } +*/ +typedef struct krb5_ap_req_st + { + ASN1_INTEGER *pvno; + ASN1_INTEGER *msgtype; + ASN1_BIT_STRING *apoptions; + KRB5_TICKET *ticket; + KRB5_ENCDATA *authenticator; + } KRB5_APREQBODY; + +typedef STACK_OF(KRB5_APREQBODY) KRB5_APREQ; +DECLARE_STACK_OF(KRB5_APREQBODY) + + +/* Authenticator Stuff */ + + +/* Checksum ::= SEQUENCE { +** cksumtype[0] INTEGER, +** checksum[1] OCTET STRING +** } +*/ +typedef struct krb5_checksum_st + { + ASN1_INTEGER *ctype; + ASN1_OCTET_STRING *checksum; + } KRB5_CHECKSUM; + +DECLARE_STACK_OF(KRB5_CHECKSUM) + + +/* EncryptionKey ::= SEQUENCE { +** keytype[0] INTEGER, +** keyvalue[1] OCTET STRING +** } +*/ +typedef struct krb5_encryptionkey_st + { + ASN1_INTEGER *ktype; + ASN1_OCTET_STRING *keyvalue; + } KRB5_ENCKEY; + +DECLARE_STACK_OF(KRB5_ENCKEY) + + +/* AuthorizationData ::= SEQUENCE OF SEQUENCE { +** ad-type[0] INTEGER, +** ad-data[1] OCTET STRING +** } +*/ +typedef struct krb5_authorization_st + { + ASN1_INTEGER *adtype; + ASN1_OCTET_STRING *addata; + } KRB5_AUTHDATA; + +DECLARE_STACK_OF(KRB5_AUTHDATA) + + +/* -- Unencrypted authenticator +** Authenticator ::= [APPLICATION 2] SEQUENCE { +** authenticator-vno[0] INTEGER, +** crealm[1] Realm, +** cname[2] PrincipalName, +** cksum[3] Checksum OPTIONAL, +** cusec[4] INTEGER, +** ctime[5] KerberosTime, +** subkey[6] EncryptionKey OPTIONAL, +** seq-number[7] INTEGER OPTIONAL, +** authorization-data[8] AuthorizationData OPTIONAL +** } +*/ +typedef struct krb5_authenticator_st + { + ASN1_INTEGER *avno; + ASN1_GENERALSTRING *crealm; + KRB5_PRINCNAME *cname; + KRB5_CHECKSUM *cksum; + ASN1_INTEGER *cusec; + ASN1_GENERALIZEDTIME *ctime; + KRB5_ENCKEY *subkey; + ASN1_INTEGER *seqnum; + KRB5_AUTHDATA *authorization; + } KRB5_AUTHENTBODY; + +typedef STACK_OF(KRB5_AUTHENTBODY) KRB5_AUTHENT; +DECLARE_STACK_OF(KRB5_AUTHENTBODY) + + +/* DECLARE_ASN1_FUNCTIONS(type) = DECLARE_ASN1_FUNCTIONS_name(type, type) = +** type *name##_new(void); +** void name##_free(type *a); +** DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) = +** DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) = +** type *d2i_##name(type **a, const unsigned char **in, long len); +** int i2d_##name(type *a, unsigned char **out); +** DECLARE_ASN1_ITEM(itname) = extern const ASN1_ITEM itname##_it +*/ + +DECLARE_ASN1_FUNCTIONS(KRB5_ENCDATA) +DECLARE_ASN1_FUNCTIONS(KRB5_PRINCNAME) +DECLARE_ASN1_FUNCTIONS(KRB5_TKTBODY) +DECLARE_ASN1_FUNCTIONS(KRB5_APREQBODY) +DECLARE_ASN1_FUNCTIONS(KRB5_TICKET) +DECLARE_ASN1_FUNCTIONS(KRB5_APREQ) + +DECLARE_ASN1_FUNCTIONS(KRB5_CHECKSUM) +DECLARE_ASN1_FUNCTIONS(KRB5_ENCKEY) +DECLARE_ASN1_FUNCTIONS(KRB5_AUTHDATA) +DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENTBODY) +DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENT) + + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/crypto/libressl/include/openssl/lhash.h b/crypto/libressl/include/openssl/lhash.h new file mode 100644 index 0000000000..dcaa4ff6ab --- /dev/null +++ b/crypto/libressl/include/openssl/lhash.h @@ -0,0 +1,235 @@ +/* $OpenBSD$ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Header for dynamic hash table routines + * Author - Eric Young + */ + +#ifndef HEADER_LHASH_H +#define HEADER_LHASH_H + +#include + +#include + +#ifndef OPENSSL_NO_BIO +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct lhash_node_st { + void *data; + struct lhash_node_st *next; +#ifndef OPENSSL_NO_HASH_COMP + unsigned long hash; +#endif +} LHASH_NODE; + +typedef int (*LHASH_COMP_FN_TYPE)(const void *, const void *); +typedef unsigned long (*LHASH_HASH_FN_TYPE)(const void *); +typedef void (*LHASH_DOALL_FN_TYPE)(void *); +typedef void (*LHASH_DOALL_ARG_FN_TYPE)(void *, void *); + +/* Macros for declaring and implementing type-safe wrappers for LHASH callbacks. + * This way, callbacks can be provided to LHASH structures without function + * pointer casting and the macro-defined callbacks provide per-variable casting + * before deferring to the underlying type-specific callbacks. NB: It is + * possible to place a "static" in front of both the DECLARE and IMPLEMENT + * macros if the functions are strictly internal. */ + +/* First: "hash" functions */ +#define DECLARE_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *); +#define IMPLEMENT_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *arg) { \ + const o_type *a = arg; \ + return name##_hash(a); } +#define LHASH_HASH_FN(name) name##_LHASH_HASH + +/* Second: "compare" functions */ +#define DECLARE_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *, const void *); +#define IMPLEMENT_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *arg1, const void *arg2) { \ + const o_type *a = arg1; \ + const o_type *b = arg2; \ + return name##_cmp(a,b); } +#define LHASH_COMP_FN(name) name##_LHASH_COMP + +/* Third: "doall" functions */ +#define DECLARE_LHASH_DOALL_FN(name, o_type) \ + void name##_LHASH_DOALL(void *); +#define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \ + void name##_LHASH_DOALL(void *arg) { \ + o_type *a = arg; \ + name##_doall(a); } +#define LHASH_DOALL_FN(name) name##_LHASH_DOALL + +/* Fourth: "doall_arg" functions */ +#define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *, void *); +#define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \ + o_type *a = arg1; \ + a_type *b = arg2; \ + name##_doall_arg(a, b); } +#define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG + +typedef struct lhash_st { + LHASH_NODE **b; + LHASH_COMP_FN_TYPE comp; + LHASH_HASH_FN_TYPE hash; + unsigned int num_nodes; + unsigned int num_alloc_nodes; + unsigned int p; + unsigned int pmax; + unsigned long up_load; /* load times 256 */ + unsigned long down_load; /* load times 256 */ + unsigned long num_items; + + unsigned long num_expands; + unsigned long num_expand_reallocs; + unsigned long num_contracts; + unsigned long num_contract_reallocs; + unsigned long num_hash_calls; + unsigned long num_comp_calls; + unsigned long num_insert; + unsigned long num_replace; + unsigned long num_delete; + unsigned long num_no_delete; + unsigned long num_retrieve; + unsigned long num_retrieve_miss; + unsigned long num_hash_comps; + + int error; +} _LHASH; /* Do not use _LHASH directly, use LHASH_OF + * and friends */ + +#define LH_LOAD_MULT 256 + +/* Indicates a malloc() error in the last call, this is only bad + * in lh_insert(). */ +#define lh_error(lh) ((lh)->error) + +_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c); +void lh_free(_LHASH *lh); +void *lh_insert(_LHASH *lh, void *data); +void *lh_delete(_LHASH *lh, const void *data); +void *lh_retrieve(_LHASH *lh, const void *data); +void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func); +void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg); +unsigned long lh_strhash(const char *c); +unsigned long lh_num_items(const _LHASH *lh); + +void lh_stats(const _LHASH *lh, FILE *out); +void lh_node_stats(const _LHASH *lh, FILE *out); +void lh_node_usage_stats(const _LHASH *lh, FILE *out); + +#ifndef OPENSSL_NO_BIO +void lh_stats_bio(const _LHASH *lh, BIO *out); +void lh_node_stats_bio(const _LHASH *lh, BIO *out); +void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out); +#endif + +/* Type checking... */ + +#define LHASH_OF(type) struct lhash_st_##type + +#define DECLARE_LHASH_OF(type) LHASH_OF(type) { int dummy; } + +#define CHECKED_LHASH_OF(type,lh) \ + ((_LHASH *)CHECKED_PTR_OF(LHASH_OF(type),lh)) + +/* Define wrapper functions. */ +#define LHM_lh_new(type, name) \ + ((LHASH_OF(type) *)lh_new(LHASH_HASH_FN(name), LHASH_COMP_FN(name))) +#define LHM_lh_error(type, lh) \ + lh_error(CHECKED_LHASH_OF(type,lh)) +#define LHM_lh_insert(type, lh, inst) \ + ((type *)lh_insert(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +#define LHM_lh_retrieve(type, lh, inst) \ + ((type *)lh_retrieve(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +#define LHM_lh_delete(type, lh, inst) \ + ((type *)lh_delete(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +#define LHM_lh_doall(type, lh,fn) lh_doall(CHECKED_LHASH_OF(type, lh), fn) +#define LHM_lh_doall_arg(type, lh, fn, arg_type, arg) \ + lh_doall_arg(CHECKED_LHASH_OF(type, lh), fn, CHECKED_PTR_OF(arg_type, arg)) +#define LHM_lh_num_items(type, lh) lh_num_items(CHECKED_LHASH_OF(type, lh)) +#define LHM_lh_down_load(type, lh) (CHECKED_LHASH_OF(type, lh)->down_load) +#define LHM_lh_node_stats_bio(type, lh, out) \ + lh_node_stats_bio(CHECKED_LHASH_OF(type, lh), out) +#define LHM_lh_node_usage_stats_bio(type, lh, out) \ + lh_node_usage_stats_bio(CHECKED_LHASH_OF(type, lh), out) +#define LHM_lh_stats_bio(type, lh, out) \ + lh_stats_bio(CHECKED_LHASH_OF(type, lh), out) +#define LHM_lh_free(type, lh) lh_free(CHECKED_LHASH_OF(type, lh)) + +DECLARE_LHASH_OF(OPENSSL_STRING); +DECLARE_LHASH_OF(OPENSSL_CSTRING); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/libressl/include/openssl/md4.h b/crypto/libressl/include/openssl/md4.h new file mode 100644 index 0000000000..fe9b036508 --- /dev/null +++ b/crypto/libressl/include/openssl/md4.h @@ -0,0 +1,103 @@ +/* $OpenBSD$ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#ifndef HEADER_MD4_H +#define HEADER_MD4_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENSSL_NO_MD4 +#error MD4 is disabled. +#endif + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! MD4_LONG has to be at least 32 bits wide. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +#define MD4_LONG unsigned int + +#define MD4_CBLOCK 64 +#define MD4_LBLOCK (MD4_CBLOCK/4) +#define MD4_DIGEST_LENGTH 16 + +typedef struct MD4state_st + { + MD4_LONG A,B,C,D; + MD4_LONG Nl,Nh; + MD4_LONG data[MD4_LBLOCK]; + unsigned int num; + } MD4_CTX; + +int MD4_Init(MD4_CTX *c); +int MD4_Update(MD4_CTX *c, const void *data, size_t len); +int MD4_Final(unsigned char *md, MD4_CTX *c); +unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md); +void MD4_Transform(MD4_CTX *c, const unsigned char *b); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/libressl/include/openssl/md5.h b/crypto/libressl/include/openssl/md5.h new file mode 100644 index 0000000000..90c3a501c4 --- /dev/null +++ b/crypto/libressl/include/openssl/md5.h @@ -0,0 +1,108 @@ +/* $OpenBSD: md5.h,v 1.19 2014/07/13 14:13:27 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#ifndef HEADER_MD5_H +#define HEADER_MD5_H +#if !defined(HAVE_ATTRIBUTE__BOUNDED__) && !defined(__OpenBSD__) +#define __bounded__(x, y, z) +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENSSL_NO_MD5 +#error MD5 is disabled. +#endif + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! MD5_LONG has to be at least 32 bits wide. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +#define MD5_LONG unsigned int + +#define MD5_CBLOCK 64 +#define MD5_LBLOCK (MD5_CBLOCK/4) +#define MD5_DIGEST_LENGTH 16 + +typedef struct MD5state_st + { + MD5_LONG A,B,C,D; + MD5_LONG Nl,Nh; + MD5_LONG data[MD5_LBLOCK]; + unsigned int num; + } MD5_CTX; + +int MD5_Init(MD5_CTX *c); +int MD5_Update(MD5_CTX *c, const void *data, size_t len) + __attribute__ ((__bounded__(__buffer__,2,3))); +int MD5_Final(unsigned char *md, MD5_CTX *c); +unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md) + __attribute__ ((__bounded__(__buffer__,1,2))); +void MD5_Transform(MD5_CTX *c, const unsigned char *b); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/libressl/include/openssl/modes.h b/crypto/libressl/include/openssl/modes.h new file mode 100644 index 0000000000..d58743de26 --- /dev/null +++ b/crypto/libressl/include/openssl/modes.h @@ -0,0 +1,136 @@ +/* $OpenBSD$ */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Rights for redistribution and usage in source and binary + * forms are granted according to the OpenSSL license. + */ + +#include + +typedef void (*block128_f)(const unsigned char in[16], + unsigned char out[16], + const void *key); + +typedef void (*cbc128_f)(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int enc); + +typedef void (*ctr128_f)(const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + const unsigned char ivec[16]); + +typedef void (*ccm128_f)(const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + const unsigned char ivec[16],unsigned char cmac[16]); + +void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); +void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); + +void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], unsigned char ecount_buf[16], + unsigned int *num, block128_f block); + +void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], unsigned char ecount_buf[16], + unsigned int *num, ctr128_f ctr); + +void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + block128_f block); + +void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); +void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); +void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, + size_t bits, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); + +size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); +size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); +size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); +size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); + +size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); +size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); +size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); +size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); + +typedef struct gcm128_context GCM128_CONTEXT; + +GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block); +void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx,void *key,block128_f block); +void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, + size_t len); +int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad, + size_t len); +int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len); +int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len); +int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream); +int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream); +int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx,const unsigned char *tag, + size_t len); +void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len); +void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx); + +typedef struct ccm128_context CCM128_CONTEXT; + +void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, + unsigned int M, unsigned int L, void *key,block128_f block); +int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, + const unsigned char *nonce, size_t nlen, size_t mlen); +void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, + const unsigned char *aad, size_t alen); +int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, size_t len); +int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, size_t len); +int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, size_t len, + ccm128_f stream); +int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, size_t len, + ccm128_f stream); +size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len); + +typedef struct xts128_context XTS128_CONTEXT; + +int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char iv[16], + const unsigned char *inp, unsigned char *out, size_t len, int enc); diff --git a/crypto/libressl/include/openssl/obj_mac.h b/crypto/libressl/include/openssl/obj_mac.h new file mode 100644 index 0000000000..f727262b7c --- /dev/null +++ b/crypto/libressl/include/openssl/obj_mac.h @@ -0,0 +1,4156 @@ +/* crypto/objects/obj_mac.h */ + +/* THIS FILE IS GENERATED FROM objects.txt by objects.pl via the + * following command: + * perl objects.pl objects.txt obj_mac.num obj_mac.h + */ + +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#define SN_undef "UNDEF" +#define LN_undef "undefined" +#define NID_undef 0 +#define OBJ_undef 0L + +#define SN_itu_t "ITU-T" +#define LN_itu_t "itu-t" +#define NID_itu_t 645 +#define OBJ_itu_t 0L + +#define NID_ccitt 404 +#define OBJ_ccitt OBJ_itu_t + +#define SN_iso "ISO" +#define LN_iso "iso" +#define NID_iso 181 +#define OBJ_iso 1L + +#define SN_joint_iso_itu_t "JOINT-ISO-ITU-T" +#define LN_joint_iso_itu_t "joint-iso-itu-t" +#define NID_joint_iso_itu_t 646 +#define OBJ_joint_iso_itu_t 2L + +#define NID_joint_iso_ccitt 393 +#define OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t + +#define SN_member_body "member-body" +#define LN_member_body "ISO Member Body" +#define NID_member_body 182 +#define OBJ_member_body OBJ_iso,2L + +#define SN_identified_organization "identified-organization" +#define NID_identified_organization 676 +#define OBJ_identified_organization OBJ_iso,3L + +#define SN_hmac_md5 "HMAC-MD5" +#define LN_hmac_md5 "hmac-md5" +#define NID_hmac_md5 780 +#define OBJ_hmac_md5 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L + +#define SN_hmac_sha1 "HMAC-SHA1" +#define LN_hmac_sha1 "hmac-sha1" +#define NID_hmac_sha1 781 +#define OBJ_hmac_sha1 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L + +#define SN_certicom_arc "certicom-arc" +#define NID_certicom_arc 677 +#define OBJ_certicom_arc OBJ_identified_organization,132L + +#define SN_international_organizations "international-organizations" +#define LN_international_organizations "International Organizations" +#define NID_international_organizations 647 +#define OBJ_international_organizations OBJ_joint_iso_itu_t,23L + +#define SN_wap "wap" +#define NID_wap 678 +#define OBJ_wap OBJ_international_organizations,43L + +#define SN_wap_wsg "wap-wsg" +#define NID_wap_wsg 679 +#define OBJ_wap_wsg OBJ_wap,1L + +#define SN_selected_attribute_types "selected-attribute-types" +#define LN_selected_attribute_types "Selected Attribute Types" +#define NID_selected_attribute_types 394 +#define OBJ_selected_attribute_types OBJ_joint_iso_itu_t,5L,1L,5L + +#define SN_clearance "clearance" +#define NID_clearance 395 +#define OBJ_clearance OBJ_selected_attribute_types,55L + +#define SN_ISO_US "ISO-US" +#define LN_ISO_US "ISO US Member Body" +#define NID_ISO_US 183 +#define OBJ_ISO_US OBJ_member_body,840L + +#define SN_X9_57 "X9-57" +#define LN_X9_57 "X9.57" +#define NID_X9_57 184 +#define OBJ_X9_57 OBJ_ISO_US,10040L + +#define SN_X9cm "X9cm" +#define LN_X9cm "X9.57 CM ?" +#define NID_X9cm 185 +#define OBJ_X9cm OBJ_X9_57,4L + +#define SN_dsa "DSA" +#define LN_dsa "dsaEncryption" +#define NID_dsa 116 +#define OBJ_dsa OBJ_X9cm,1L + +#define SN_dsaWithSHA1 "DSA-SHA1" +#define LN_dsaWithSHA1 "dsaWithSHA1" +#define NID_dsaWithSHA1 113 +#define OBJ_dsaWithSHA1 OBJ_X9cm,3L + +#define SN_ansi_X9_62 "ansi-X9-62" +#define LN_ansi_X9_62 "ANSI X9.62" +#define NID_ansi_X9_62 405 +#define OBJ_ansi_X9_62 OBJ_ISO_US,10045L + +#define OBJ_X9_62_id_fieldType OBJ_ansi_X9_62,1L + +#define SN_X9_62_prime_field "prime-field" +#define NID_X9_62_prime_field 406 +#define OBJ_X9_62_prime_field OBJ_X9_62_id_fieldType,1L + +#define SN_X9_62_characteristic_two_field "characteristic-two-field" +#define NID_X9_62_characteristic_two_field 407 +#define OBJ_X9_62_characteristic_two_field OBJ_X9_62_id_fieldType,2L + +#define SN_X9_62_id_characteristic_two_basis "id-characteristic-two-basis" +#define NID_X9_62_id_characteristic_two_basis 680 +#define OBJ_X9_62_id_characteristic_two_basis OBJ_X9_62_characteristic_two_field,3L + +#define SN_X9_62_onBasis "onBasis" +#define NID_X9_62_onBasis 681 +#define OBJ_X9_62_onBasis OBJ_X9_62_id_characteristic_two_basis,1L + +#define SN_X9_62_tpBasis "tpBasis" +#define NID_X9_62_tpBasis 682 +#define OBJ_X9_62_tpBasis OBJ_X9_62_id_characteristic_two_basis,2L + +#define SN_X9_62_ppBasis "ppBasis" +#define NID_X9_62_ppBasis 683 +#define OBJ_X9_62_ppBasis OBJ_X9_62_id_characteristic_two_basis,3L + +#define OBJ_X9_62_id_publicKeyType OBJ_ansi_X9_62,2L + +#define SN_X9_62_id_ecPublicKey "id-ecPublicKey" +#define NID_X9_62_id_ecPublicKey 408 +#define OBJ_X9_62_id_ecPublicKey OBJ_X9_62_id_publicKeyType,1L + +#define OBJ_X9_62_ellipticCurve OBJ_ansi_X9_62,3L + +#define OBJ_X9_62_c_TwoCurve OBJ_X9_62_ellipticCurve,0L + +#define SN_X9_62_c2pnb163v1 "c2pnb163v1" +#define NID_X9_62_c2pnb163v1 684 +#define OBJ_X9_62_c2pnb163v1 OBJ_X9_62_c_TwoCurve,1L + +#define SN_X9_62_c2pnb163v2 "c2pnb163v2" +#define NID_X9_62_c2pnb163v2 685 +#define OBJ_X9_62_c2pnb163v2 OBJ_X9_62_c_TwoCurve,2L + +#define SN_X9_62_c2pnb163v3 "c2pnb163v3" +#define NID_X9_62_c2pnb163v3 686 +#define OBJ_X9_62_c2pnb163v3 OBJ_X9_62_c_TwoCurve,3L + +#define SN_X9_62_c2pnb176v1 "c2pnb176v1" +#define NID_X9_62_c2pnb176v1 687 +#define OBJ_X9_62_c2pnb176v1 OBJ_X9_62_c_TwoCurve,4L + +#define SN_X9_62_c2tnb191v1 "c2tnb191v1" +#define NID_X9_62_c2tnb191v1 688 +#define OBJ_X9_62_c2tnb191v1 OBJ_X9_62_c_TwoCurve,5L + +#define SN_X9_62_c2tnb191v2 "c2tnb191v2" +#define NID_X9_62_c2tnb191v2 689 +#define OBJ_X9_62_c2tnb191v2 OBJ_X9_62_c_TwoCurve,6L + +#define SN_X9_62_c2tnb191v3 "c2tnb191v3" +#define NID_X9_62_c2tnb191v3 690 +#define OBJ_X9_62_c2tnb191v3 OBJ_X9_62_c_TwoCurve,7L + +#define SN_X9_62_c2onb191v4 "c2onb191v4" +#define NID_X9_62_c2onb191v4 691 +#define OBJ_X9_62_c2onb191v4 OBJ_X9_62_c_TwoCurve,8L + +#define SN_X9_62_c2onb191v5 "c2onb191v5" +#define NID_X9_62_c2onb191v5 692 +#define OBJ_X9_62_c2onb191v5 OBJ_X9_62_c_TwoCurve,9L + +#define SN_X9_62_c2pnb208w1 "c2pnb208w1" +#define NID_X9_62_c2pnb208w1 693 +#define OBJ_X9_62_c2pnb208w1 OBJ_X9_62_c_TwoCurve,10L + +#define SN_X9_62_c2tnb239v1 "c2tnb239v1" +#define NID_X9_62_c2tnb239v1 694 +#define OBJ_X9_62_c2tnb239v1 OBJ_X9_62_c_TwoCurve,11L + +#define SN_X9_62_c2tnb239v2 "c2tnb239v2" +#define NID_X9_62_c2tnb239v2 695 +#define OBJ_X9_62_c2tnb239v2 OBJ_X9_62_c_TwoCurve,12L + +#define SN_X9_62_c2tnb239v3 "c2tnb239v3" +#define NID_X9_62_c2tnb239v3 696 +#define OBJ_X9_62_c2tnb239v3 OBJ_X9_62_c_TwoCurve,13L + +#define SN_X9_62_c2onb239v4 "c2onb239v4" +#define NID_X9_62_c2onb239v4 697 +#define OBJ_X9_62_c2onb239v4 OBJ_X9_62_c_TwoCurve,14L + +#define SN_X9_62_c2onb239v5 "c2onb239v5" +#define NID_X9_62_c2onb239v5 698 +#define OBJ_X9_62_c2onb239v5 OBJ_X9_62_c_TwoCurve,15L + +#define SN_X9_62_c2pnb272w1 "c2pnb272w1" +#define NID_X9_62_c2pnb272w1 699 +#define OBJ_X9_62_c2pnb272w1 OBJ_X9_62_c_TwoCurve,16L + +#define SN_X9_62_c2pnb304w1 "c2pnb304w1" +#define NID_X9_62_c2pnb304w1 700 +#define OBJ_X9_62_c2pnb304w1 OBJ_X9_62_c_TwoCurve,17L + +#define SN_X9_62_c2tnb359v1 "c2tnb359v1" +#define NID_X9_62_c2tnb359v1 701 +#define OBJ_X9_62_c2tnb359v1 OBJ_X9_62_c_TwoCurve,18L + +#define SN_X9_62_c2pnb368w1 "c2pnb368w1" +#define NID_X9_62_c2pnb368w1 702 +#define OBJ_X9_62_c2pnb368w1 OBJ_X9_62_c_TwoCurve,19L + +#define SN_X9_62_c2tnb431r1 "c2tnb431r1" +#define NID_X9_62_c2tnb431r1 703 +#define OBJ_X9_62_c2tnb431r1 OBJ_X9_62_c_TwoCurve,20L + +#define OBJ_X9_62_primeCurve OBJ_X9_62_ellipticCurve,1L + +#define SN_X9_62_prime192v1 "prime192v1" +#define NID_X9_62_prime192v1 409 +#define OBJ_X9_62_prime192v1 OBJ_X9_62_primeCurve,1L + +#define SN_X9_62_prime192v2 "prime192v2" +#define NID_X9_62_prime192v2 410 +#define OBJ_X9_62_prime192v2 OBJ_X9_62_primeCurve,2L + +#define SN_X9_62_prime192v3 "prime192v3" +#define NID_X9_62_prime192v3 411 +#define OBJ_X9_62_prime192v3 OBJ_X9_62_primeCurve,3L + +#define SN_X9_62_prime239v1 "prime239v1" +#define NID_X9_62_prime239v1 412 +#define OBJ_X9_62_prime239v1 OBJ_X9_62_primeCurve,4L + +#define SN_X9_62_prime239v2 "prime239v2" +#define NID_X9_62_prime239v2 413 +#define OBJ_X9_62_prime239v2 OBJ_X9_62_primeCurve,5L + +#define SN_X9_62_prime239v3 "prime239v3" +#define NID_X9_62_prime239v3 414 +#define OBJ_X9_62_prime239v3 OBJ_X9_62_primeCurve,6L + +#define SN_X9_62_prime256v1 "prime256v1" +#define NID_X9_62_prime256v1 415 +#define OBJ_X9_62_prime256v1 OBJ_X9_62_primeCurve,7L + +#define OBJ_X9_62_id_ecSigType OBJ_ansi_X9_62,4L + +#define SN_ecdsa_with_SHA1 "ecdsa-with-SHA1" +#define NID_ecdsa_with_SHA1 416 +#define OBJ_ecdsa_with_SHA1 OBJ_X9_62_id_ecSigType,1L + +#define SN_ecdsa_with_Recommended "ecdsa-with-Recommended" +#define NID_ecdsa_with_Recommended 791 +#define OBJ_ecdsa_with_Recommended OBJ_X9_62_id_ecSigType,2L + +#define SN_ecdsa_with_Specified "ecdsa-with-Specified" +#define NID_ecdsa_with_Specified 792 +#define OBJ_ecdsa_with_Specified OBJ_X9_62_id_ecSigType,3L + +#define SN_ecdsa_with_SHA224 "ecdsa-with-SHA224" +#define NID_ecdsa_with_SHA224 793 +#define OBJ_ecdsa_with_SHA224 OBJ_ecdsa_with_Specified,1L + +#define SN_ecdsa_with_SHA256 "ecdsa-with-SHA256" +#define NID_ecdsa_with_SHA256 794 +#define OBJ_ecdsa_with_SHA256 OBJ_ecdsa_with_Specified,2L + +#define SN_ecdsa_with_SHA384 "ecdsa-with-SHA384" +#define NID_ecdsa_with_SHA384 795 +#define OBJ_ecdsa_with_SHA384 OBJ_ecdsa_with_Specified,3L + +#define SN_ecdsa_with_SHA512 "ecdsa-with-SHA512" +#define NID_ecdsa_with_SHA512 796 +#define OBJ_ecdsa_with_SHA512 OBJ_ecdsa_with_Specified,4L + +#define OBJ_secg_ellipticCurve OBJ_certicom_arc,0L + +#define SN_secp112r1 "secp112r1" +#define NID_secp112r1 704 +#define OBJ_secp112r1 OBJ_secg_ellipticCurve,6L + +#define SN_secp112r2 "secp112r2" +#define NID_secp112r2 705 +#define OBJ_secp112r2 OBJ_secg_ellipticCurve,7L + +#define SN_secp128r1 "secp128r1" +#define NID_secp128r1 706 +#define OBJ_secp128r1 OBJ_secg_ellipticCurve,28L + +#define SN_secp128r2 "secp128r2" +#define NID_secp128r2 707 +#define OBJ_secp128r2 OBJ_secg_ellipticCurve,29L + +#define SN_secp160k1 "secp160k1" +#define NID_secp160k1 708 +#define OBJ_secp160k1 OBJ_secg_ellipticCurve,9L + +#define SN_secp160r1 "secp160r1" +#define NID_secp160r1 709 +#define OBJ_secp160r1 OBJ_secg_ellipticCurve,8L + +#define SN_secp160r2 "secp160r2" +#define NID_secp160r2 710 +#define OBJ_secp160r2 OBJ_secg_ellipticCurve,30L + +#define SN_secp192k1 "secp192k1" +#define NID_secp192k1 711 +#define OBJ_secp192k1 OBJ_secg_ellipticCurve,31L + +#define SN_secp224k1 "secp224k1" +#define NID_secp224k1 712 +#define OBJ_secp224k1 OBJ_secg_ellipticCurve,32L + +#define SN_secp224r1 "secp224r1" +#define NID_secp224r1 713 +#define OBJ_secp224r1 OBJ_secg_ellipticCurve,33L + +#define SN_secp256k1 "secp256k1" +#define NID_secp256k1 714 +#define OBJ_secp256k1 OBJ_secg_ellipticCurve,10L + +#define SN_secp384r1 "secp384r1" +#define NID_secp384r1 715 +#define OBJ_secp384r1 OBJ_secg_ellipticCurve,34L + +#define SN_secp521r1 "secp521r1" +#define NID_secp521r1 716 +#define OBJ_secp521r1 OBJ_secg_ellipticCurve,35L + +#define SN_sect113r1 "sect113r1" +#define NID_sect113r1 717 +#define OBJ_sect113r1 OBJ_secg_ellipticCurve,4L + +#define SN_sect113r2 "sect113r2" +#define NID_sect113r2 718 +#define OBJ_sect113r2 OBJ_secg_ellipticCurve,5L + +#define SN_sect131r1 "sect131r1" +#define NID_sect131r1 719 +#define OBJ_sect131r1 OBJ_secg_ellipticCurve,22L + +#define SN_sect131r2 "sect131r2" +#define NID_sect131r2 720 +#define OBJ_sect131r2 OBJ_secg_ellipticCurve,23L + +#define SN_sect163k1 "sect163k1" +#define NID_sect163k1 721 +#define OBJ_sect163k1 OBJ_secg_ellipticCurve,1L + +#define SN_sect163r1 "sect163r1" +#define NID_sect163r1 722 +#define OBJ_sect163r1 OBJ_secg_ellipticCurve,2L + +#define SN_sect163r2 "sect163r2" +#define NID_sect163r2 723 +#define OBJ_sect163r2 OBJ_secg_ellipticCurve,15L + +#define SN_sect193r1 "sect193r1" +#define NID_sect193r1 724 +#define OBJ_sect193r1 OBJ_secg_ellipticCurve,24L + +#define SN_sect193r2 "sect193r2" +#define NID_sect193r2 725 +#define OBJ_sect193r2 OBJ_secg_ellipticCurve,25L + +#define SN_sect233k1 "sect233k1" +#define NID_sect233k1 726 +#define OBJ_sect233k1 OBJ_secg_ellipticCurve,26L + +#define SN_sect233r1 "sect233r1" +#define NID_sect233r1 727 +#define OBJ_sect233r1 OBJ_secg_ellipticCurve,27L + +#define SN_sect239k1 "sect239k1" +#define NID_sect239k1 728 +#define OBJ_sect239k1 OBJ_secg_ellipticCurve,3L + +#define SN_sect283k1 "sect283k1" +#define NID_sect283k1 729 +#define OBJ_sect283k1 OBJ_secg_ellipticCurve,16L + +#define SN_sect283r1 "sect283r1" +#define NID_sect283r1 730 +#define OBJ_sect283r1 OBJ_secg_ellipticCurve,17L + +#define SN_sect409k1 "sect409k1" +#define NID_sect409k1 731 +#define OBJ_sect409k1 OBJ_secg_ellipticCurve,36L + +#define SN_sect409r1 "sect409r1" +#define NID_sect409r1 732 +#define OBJ_sect409r1 OBJ_secg_ellipticCurve,37L + +#define SN_sect571k1 "sect571k1" +#define NID_sect571k1 733 +#define OBJ_sect571k1 OBJ_secg_ellipticCurve,38L + +#define SN_sect571r1 "sect571r1" +#define NID_sect571r1 734 +#define OBJ_sect571r1 OBJ_secg_ellipticCurve,39L + +#define OBJ_wap_wsg_idm_ecid OBJ_wap_wsg,4L + +#define SN_wap_wsg_idm_ecid_wtls1 "wap-wsg-idm-ecid-wtls1" +#define NID_wap_wsg_idm_ecid_wtls1 735 +#define OBJ_wap_wsg_idm_ecid_wtls1 OBJ_wap_wsg_idm_ecid,1L + +#define SN_wap_wsg_idm_ecid_wtls3 "wap-wsg-idm-ecid-wtls3" +#define NID_wap_wsg_idm_ecid_wtls3 736 +#define OBJ_wap_wsg_idm_ecid_wtls3 OBJ_wap_wsg_idm_ecid,3L + +#define SN_wap_wsg_idm_ecid_wtls4 "wap-wsg-idm-ecid-wtls4" +#define NID_wap_wsg_idm_ecid_wtls4 737 +#define OBJ_wap_wsg_idm_ecid_wtls4 OBJ_wap_wsg_idm_ecid,4L + +#define SN_wap_wsg_idm_ecid_wtls5 "wap-wsg-idm-ecid-wtls5" +#define NID_wap_wsg_idm_ecid_wtls5 738 +#define OBJ_wap_wsg_idm_ecid_wtls5 OBJ_wap_wsg_idm_ecid,5L + +#define SN_wap_wsg_idm_ecid_wtls6 "wap-wsg-idm-ecid-wtls6" +#define NID_wap_wsg_idm_ecid_wtls6 739 +#define OBJ_wap_wsg_idm_ecid_wtls6 OBJ_wap_wsg_idm_ecid,6L + +#define SN_wap_wsg_idm_ecid_wtls7 "wap-wsg-idm-ecid-wtls7" +#define NID_wap_wsg_idm_ecid_wtls7 740 +#define OBJ_wap_wsg_idm_ecid_wtls7 OBJ_wap_wsg_idm_ecid,7L + +#define SN_wap_wsg_idm_ecid_wtls8 "wap-wsg-idm-ecid-wtls8" +#define NID_wap_wsg_idm_ecid_wtls8 741 +#define OBJ_wap_wsg_idm_ecid_wtls8 OBJ_wap_wsg_idm_ecid,8L + +#define SN_wap_wsg_idm_ecid_wtls9 "wap-wsg-idm-ecid-wtls9" +#define NID_wap_wsg_idm_ecid_wtls9 742 +#define OBJ_wap_wsg_idm_ecid_wtls9 OBJ_wap_wsg_idm_ecid,9L + +#define SN_wap_wsg_idm_ecid_wtls10 "wap-wsg-idm-ecid-wtls10" +#define NID_wap_wsg_idm_ecid_wtls10 743 +#define OBJ_wap_wsg_idm_ecid_wtls10 OBJ_wap_wsg_idm_ecid,10L + +#define SN_wap_wsg_idm_ecid_wtls11 "wap-wsg-idm-ecid-wtls11" +#define NID_wap_wsg_idm_ecid_wtls11 744 +#define OBJ_wap_wsg_idm_ecid_wtls11 OBJ_wap_wsg_idm_ecid,11L + +#define SN_wap_wsg_idm_ecid_wtls12 "wap-wsg-idm-ecid-wtls12" +#define NID_wap_wsg_idm_ecid_wtls12 745 +#define OBJ_wap_wsg_idm_ecid_wtls12 OBJ_wap_wsg_idm_ecid,12L + +#define SN_cast5_cbc "CAST5-CBC" +#define LN_cast5_cbc "cast5-cbc" +#define NID_cast5_cbc 108 +#define OBJ_cast5_cbc OBJ_ISO_US,113533L,7L,66L,10L + +#define SN_cast5_ecb "CAST5-ECB" +#define LN_cast5_ecb "cast5-ecb" +#define NID_cast5_ecb 109 + +#define SN_cast5_cfb64 "CAST5-CFB" +#define LN_cast5_cfb64 "cast5-cfb" +#define NID_cast5_cfb64 110 + +#define SN_cast5_ofb64 "CAST5-OFB" +#define LN_cast5_ofb64 "cast5-ofb" +#define NID_cast5_ofb64 111 + +#define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC" +#define NID_pbeWithMD5AndCast5_CBC 112 +#define OBJ_pbeWithMD5AndCast5_CBC OBJ_ISO_US,113533L,7L,66L,12L + +#define SN_id_PasswordBasedMAC "id-PasswordBasedMAC" +#define LN_id_PasswordBasedMAC "password based MAC" +#define NID_id_PasswordBasedMAC 782 +#define OBJ_id_PasswordBasedMAC OBJ_ISO_US,113533L,7L,66L,13L + +#define SN_id_DHBasedMac "id-DHBasedMac" +#define LN_id_DHBasedMac "Diffie-Hellman based MAC" +#define NID_id_DHBasedMac 783 +#define OBJ_id_DHBasedMac OBJ_ISO_US,113533L,7L,66L,30L + +#define SN_rsadsi "rsadsi" +#define LN_rsadsi "RSA Data Security, Inc." +#define NID_rsadsi 1 +#define OBJ_rsadsi OBJ_ISO_US,113549L + +#define SN_pkcs "pkcs" +#define LN_pkcs "RSA Data Security, Inc. PKCS" +#define NID_pkcs 2 +#define OBJ_pkcs OBJ_rsadsi,1L + +#define SN_pkcs1 "pkcs1" +#define NID_pkcs1 186 +#define OBJ_pkcs1 OBJ_pkcs,1L + +#define LN_rsaEncryption "rsaEncryption" +#define NID_rsaEncryption 6 +#define OBJ_rsaEncryption OBJ_pkcs1,1L + +#define SN_md2WithRSAEncryption "RSA-MD2" +#define LN_md2WithRSAEncryption "md2WithRSAEncryption" +#define NID_md2WithRSAEncryption 7 +#define OBJ_md2WithRSAEncryption OBJ_pkcs1,2L + +#define SN_md4WithRSAEncryption "RSA-MD4" +#define LN_md4WithRSAEncryption "md4WithRSAEncryption" +#define NID_md4WithRSAEncryption 396 +#define OBJ_md4WithRSAEncryption OBJ_pkcs1,3L + +#define SN_md5WithRSAEncryption "RSA-MD5" +#define LN_md5WithRSAEncryption "md5WithRSAEncryption" +#define NID_md5WithRSAEncryption 8 +#define OBJ_md5WithRSAEncryption OBJ_pkcs1,4L + +#define SN_sha1WithRSAEncryption "RSA-SHA1" +#define LN_sha1WithRSAEncryption "sha1WithRSAEncryption" +#define NID_sha1WithRSAEncryption 65 +#define OBJ_sha1WithRSAEncryption OBJ_pkcs1,5L + +#define SN_rsaesOaep "RSAES-OAEP" +#define LN_rsaesOaep "rsaesOaep" +#define NID_rsaesOaep 919 +#define OBJ_rsaesOaep OBJ_pkcs1,7L + +#define SN_mgf1 "MGF1" +#define LN_mgf1 "mgf1" +#define NID_mgf1 911 +#define OBJ_mgf1 OBJ_pkcs1,8L + +#define SN_rsassaPss "RSASSA-PSS" +#define LN_rsassaPss "rsassaPss" +#define NID_rsassaPss 912 +#define OBJ_rsassaPss OBJ_pkcs1,10L + +#define SN_sha256WithRSAEncryption "RSA-SHA256" +#define LN_sha256WithRSAEncryption "sha256WithRSAEncryption" +#define NID_sha256WithRSAEncryption 668 +#define OBJ_sha256WithRSAEncryption OBJ_pkcs1,11L + +#define SN_sha384WithRSAEncryption "RSA-SHA384" +#define LN_sha384WithRSAEncryption "sha384WithRSAEncryption" +#define NID_sha384WithRSAEncryption 669 +#define OBJ_sha384WithRSAEncryption OBJ_pkcs1,12L + +#define SN_sha512WithRSAEncryption "RSA-SHA512" +#define LN_sha512WithRSAEncryption "sha512WithRSAEncryption" +#define NID_sha512WithRSAEncryption 670 +#define OBJ_sha512WithRSAEncryption OBJ_pkcs1,13L + +#define SN_sha224WithRSAEncryption "RSA-SHA224" +#define LN_sha224WithRSAEncryption "sha224WithRSAEncryption" +#define NID_sha224WithRSAEncryption 671 +#define OBJ_sha224WithRSAEncryption OBJ_pkcs1,14L + +#define SN_pkcs3 "pkcs3" +#define NID_pkcs3 27 +#define OBJ_pkcs3 OBJ_pkcs,3L + +#define LN_dhKeyAgreement "dhKeyAgreement" +#define NID_dhKeyAgreement 28 +#define OBJ_dhKeyAgreement OBJ_pkcs3,1L + +#define SN_pkcs5 "pkcs5" +#define NID_pkcs5 187 +#define OBJ_pkcs5 OBJ_pkcs,5L + +#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES" +#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC" +#define NID_pbeWithMD2AndDES_CBC 9 +#define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs5,1L + +#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES" +#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC" +#define NID_pbeWithMD5AndDES_CBC 10 +#define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs5,3L + +#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64" +#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC" +#define NID_pbeWithMD2AndRC2_CBC 168 +#define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs5,4L + +#define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64" +#define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC" +#define NID_pbeWithMD5AndRC2_CBC 169 +#define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs5,6L + +#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES" +#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC" +#define NID_pbeWithSHA1AndDES_CBC 170 +#define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs5,10L + +#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64" +#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC" +#define NID_pbeWithSHA1AndRC2_CBC 68 +#define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs5,11L + +#define LN_id_pbkdf2 "PBKDF2" +#define NID_id_pbkdf2 69 +#define OBJ_id_pbkdf2 OBJ_pkcs5,12L + +#define LN_pbes2 "PBES2" +#define NID_pbes2 161 +#define OBJ_pbes2 OBJ_pkcs5,13L + +#define LN_pbmac1 "PBMAC1" +#define NID_pbmac1 162 +#define OBJ_pbmac1 OBJ_pkcs5,14L + +#define SN_pkcs7 "pkcs7" +#define NID_pkcs7 20 +#define OBJ_pkcs7 OBJ_pkcs,7L + +#define LN_pkcs7_data "pkcs7-data" +#define NID_pkcs7_data 21 +#define OBJ_pkcs7_data OBJ_pkcs7,1L + +#define LN_pkcs7_signed "pkcs7-signedData" +#define NID_pkcs7_signed 22 +#define OBJ_pkcs7_signed OBJ_pkcs7,2L + +#define LN_pkcs7_enveloped "pkcs7-envelopedData" +#define NID_pkcs7_enveloped 23 +#define OBJ_pkcs7_enveloped OBJ_pkcs7,3L + +#define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData" +#define NID_pkcs7_signedAndEnveloped 24 +#define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L + +#define LN_pkcs7_digest "pkcs7-digestData" +#define NID_pkcs7_digest 25 +#define OBJ_pkcs7_digest OBJ_pkcs7,5L + +#define LN_pkcs7_encrypted "pkcs7-encryptedData" +#define NID_pkcs7_encrypted 26 +#define OBJ_pkcs7_encrypted OBJ_pkcs7,6L + +#define SN_pkcs9 "pkcs9" +#define NID_pkcs9 47 +#define OBJ_pkcs9 OBJ_pkcs,9L + +#define LN_pkcs9_emailAddress "emailAddress" +#define NID_pkcs9_emailAddress 48 +#define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L + +#define LN_pkcs9_unstructuredName "unstructuredName" +#define NID_pkcs9_unstructuredName 49 +#define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L + +#define LN_pkcs9_contentType "contentType" +#define NID_pkcs9_contentType 50 +#define OBJ_pkcs9_contentType OBJ_pkcs9,3L + +#define LN_pkcs9_messageDigest "messageDigest" +#define NID_pkcs9_messageDigest 51 +#define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L + +#define LN_pkcs9_signingTime "signingTime" +#define NID_pkcs9_signingTime 52 +#define OBJ_pkcs9_signingTime OBJ_pkcs9,5L + +#define LN_pkcs9_countersignature "countersignature" +#define NID_pkcs9_countersignature 53 +#define OBJ_pkcs9_countersignature OBJ_pkcs9,6L + +#define LN_pkcs9_challengePassword "challengePassword" +#define NID_pkcs9_challengePassword 54 +#define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L + +#define LN_pkcs9_unstructuredAddress "unstructuredAddress" +#define NID_pkcs9_unstructuredAddress 55 +#define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L + +#define LN_pkcs9_extCertAttributes "extendedCertificateAttributes" +#define NID_pkcs9_extCertAttributes 56 +#define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L + +#define SN_ext_req "extReq" +#define LN_ext_req "Extension Request" +#define NID_ext_req 172 +#define OBJ_ext_req OBJ_pkcs9,14L + +#define SN_SMIMECapabilities "SMIME-CAPS" +#define LN_SMIMECapabilities "S/MIME Capabilities" +#define NID_SMIMECapabilities 167 +#define OBJ_SMIMECapabilities OBJ_pkcs9,15L + +#define SN_SMIME "SMIME" +#define LN_SMIME "S/MIME" +#define NID_SMIME 188 +#define OBJ_SMIME OBJ_pkcs9,16L + +#define SN_id_smime_mod "id-smime-mod" +#define NID_id_smime_mod 189 +#define OBJ_id_smime_mod OBJ_SMIME,0L + +#define SN_id_smime_ct "id-smime-ct" +#define NID_id_smime_ct 190 +#define OBJ_id_smime_ct OBJ_SMIME,1L + +#define SN_id_smime_aa "id-smime-aa" +#define NID_id_smime_aa 191 +#define OBJ_id_smime_aa OBJ_SMIME,2L + +#define SN_id_smime_alg "id-smime-alg" +#define NID_id_smime_alg 192 +#define OBJ_id_smime_alg OBJ_SMIME,3L + +#define SN_id_smime_cd "id-smime-cd" +#define NID_id_smime_cd 193 +#define OBJ_id_smime_cd OBJ_SMIME,4L + +#define SN_id_smime_spq "id-smime-spq" +#define NID_id_smime_spq 194 +#define OBJ_id_smime_spq OBJ_SMIME,5L + +#define SN_id_smime_cti "id-smime-cti" +#define NID_id_smime_cti 195 +#define OBJ_id_smime_cti OBJ_SMIME,6L + +#define SN_id_smime_mod_cms "id-smime-mod-cms" +#define NID_id_smime_mod_cms 196 +#define OBJ_id_smime_mod_cms OBJ_id_smime_mod,1L + +#define SN_id_smime_mod_ess "id-smime-mod-ess" +#define NID_id_smime_mod_ess 197 +#define OBJ_id_smime_mod_ess OBJ_id_smime_mod,2L + +#define SN_id_smime_mod_oid "id-smime-mod-oid" +#define NID_id_smime_mod_oid 198 +#define OBJ_id_smime_mod_oid OBJ_id_smime_mod,3L + +#define SN_id_smime_mod_msg_v3 "id-smime-mod-msg-v3" +#define NID_id_smime_mod_msg_v3 199 +#define OBJ_id_smime_mod_msg_v3 OBJ_id_smime_mod,4L + +#define SN_id_smime_mod_ets_eSignature_88 "id-smime-mod-ets-eSignature-88" +#define NID_id_smime_mod_ets_eSignature_88 200 +#define OBJ_id_smime_mod_ets_eSignature_88 OBJ_id_smime_mod,5L + +#define SN_id_smime_mod_ets_eSignature_97 "id-smime-mod-ets-eSignature-97" +#define NID_id_smime_mod_ets_eSignature_97 201 +#define OBJ_id_smime_mod_ets_eSignature_97 OBJ_id_smime_mod,6L + +#define SN_id_smime_mod_ets_eSigPolicy_88 "id-smime-mod-ets-eSigPolicy-88" +#define NID_id_smime_mod_ets_eSigPolicy_88 202 +#define OBJ_id_smime_mod_ets_eSigPolicy_88 OBJ_id_smime_mod,7L + +#define SN_id_smime_mod_ets_eSigPolicy_97 "id-smime-mod-ets-eSigPolicy-97" +#define NID_id_smime_mod_ets_eSigPolicy_97 203 +#define OBJ_id_smime_mod_ets_eSigPolicy_97 OBJ_id_smime_mod,8L + +#define SN_id_smime_ct_receipt "id-smime-ct-receipt" +#define NID_id_smime_ct_receipt 204 +#define OBJ_id_smime_ct_receipt OBJ_id_smime_ct,1L + +#define SN_id_smime_ct_authData "id-smime-ct-authData" +#define NID_id_smime_ct_authData 205 +#define OBJ_id_smime_ct_authData OBJ_id_smime_ct,2L + +#define SN_id_smime_ct_publishCert "id-smime-ct-publishCert" +#define NID_id_smime_ct_publishCert 206 +#define OBJ_id_smime_ct_publishCert OBJ_id_smime_ct,3L + +#define SN_id_smime_ct_TSTInfo "id-smime-ct-TSTInfo" +#define NID_id_smime_ct_TSTInfo 207 +#define OBJ_id_smime_ct_TSTInfo OBJ_id_smime_ct,4L + +#define SN_id_smime_ct_TDTInfo "id-smime-ct-TDTInfo" +#define NID_id_smime_ct_TDTInfo 208 +#define OBJ_id_smime_ct_TDTInfo OBJ_id_smime_ct,5L + +#define SN_id_smime_ct_contentInfo "id-smime-ct-contentInfo" +#define NID_id_smime_ct_contentInfo 209 +#define OBJ_id_smime_ct_contentInfo OBJ_id_smime_ct,6L + +#define SN_id_smime_ct_DVCSRequestData "id-smime-ct-DVCSRequestData" +#define NID_id_smime_ct_DVCSRequestData 210 +#define OBJ_id_smime_ct_DVCSRequestData OBJ_id_smime_ct,7L + +#define SN_id_smime_ct_DVCSResponseData "id-smime-ct-DVCSResponseData" +#define NID_id_smime_ct_DVCSResponseData 211 +#define OBJ_id_smime_ct_DVCSResponseData OBJ_id_smime_ct,8L + +#define SN_id_smime_ct_compressedData "id-smime-ct-compressedData" +#define NID_id_smime_ct_compressedData 786 +#define OBJ_id_smime_ct_compressedData OBJ_id_smime_ct,9L + +#define SN_id_ct_asciiTextWithCRLF "id-ct-asciiTextWithCRLF" +#define NID_id_ct_asciiTextWithCRLF 787 +#define OBJ_id_ct_asciiTextWithCRLF OBJ_id_smime_ct,27L + +#define SN_id_smime_aa_receiptRequest "id-smime-aa-receiptRequest" +#define NID_id_smime_aa_receiptRequest 212 +#define OBJ_id_smime_aa_receiptRequest OBJ_id_smime_aa,1L + +#define SN_id_smime_aa_securityLabel "id-smime-aa-securityLabel" +#define NID_id_smime_aa_securityLabel 213 +#define OBJ_id_smime_aa_securityLabel OBJ_id_smime_aa,2L + +#define SN_id_smime_aa_mlExpandHistory "id-smime-aa-mlExpandHistory" +#define NID_id_smime_aa_mlExpandHistory 214 +#define OBJ_id_smime_aa_mlExpandHistory OBJ_id_smime_aa,3L + +#define SN_id_smime_aa_contentHint "id-smime-aa-contentHint" +#define NID_id_smime_aa_contentHint 215 +#define OBJ_id_smime_aa_contentHint OBJ_id_smime_aa,4L + +#define SN_id_smime_aa_msgSigDigest "id-smime-aa-msgSigDigest" +#define NID_id_smime_aa_msgSigDigest 216 +#define OBJ_id_smime_aa_msgSigDigest OBJ_id_smime_aa,5L + +#define SN_id_smime_aa_encapContentType "id-smime-aa-encapContentType" +#define NID_id_smime_aa_encapContentType 217 +#define OBJ_id_smime_aa_encapContentType OBJ_id_smime_aa,6L + +#define SN_id_smime_aa_contentIdentifier "id-smime-aa-contentIdentifier" +#define NID_id_smime_aa_contentIdentifier 218 +#define OBJ_id_smime_aa_contentIdentifier OBJ_id_smime_aa,7L + +#define SN_id_smime_aa_macValue "id-smime-aa-macValue" +#define NID_id_smime_aa_macValue 219 +#define OBJ_id_smime_aa_macValue OBJ_id_smime_aa,8L + +#define SN_id_smime_aa_equivalentLabels "id-smime-aa-equivalentLabels" +#define NID_id_smime_aa_equivalentLabels 220 +#define OBJ_id_smime_aa_equivalentLabels OBJ_id_smime_aa,9L + +#define SN_id_smime_aa_contentReference "id-smime-aa-contentReference" +#define NID_id_smime_aa_contentReference 221 +#define OBJ_id_smime_aa_contentReference OBJ_id_smime_aa,10L + +#define SN_id_smime_aa_encrypKeyPref "id-smime-aa-encrypKeyPref" +#define NID_id_smime_aa_encrypKeyPref 222 +#define OBJ_id_smime_aa_encrypKeyPref OBJ_id_smime_aa,11L + +#define SN_id_smime_aa_signingCertificate "id-smime-aa-signingCertificate" +#define NID_id_smime_aa_signingCertificate 223 +#define OBJ_id_smime_aa_signingCertificate OBJ_id_smime_aa,12L + +#define SN_id_smime_aa_smimeEncryptCerts "id-smime-aa-smimeEncryptCerts" +#define NID_id_smime_aa_smimeEncryptCerts 224 +#define OBJ_id_smime_aa_smimeEncryptCerts OBJ_id_smime_aa,13L + +#define SN_id_smime_aa_timeStampToken "id-smime-aa-timeStampToken" +#define NID_id_smime_aa_timeStampToken 225 +#define OBJ_id_smime_aa_timeStampToken OBJ_id_smime_aa,14L + +#define SN_id_smime_aa_ets_sigPolicyId "id-smime-aa-ets-sigPolicyId" +#define NID_id_smime_aa_ets_sigPolicyId 226 +#define OBJ_id_smime_aa_ets_sigPolicyId OBJ_id_smime_aa,15L + +#define SN_id_smime_aa_ets_commitmentType "id-smime-aa-ets-commitmentType" +#define NID_id_smime_aa_ets_commitmentType 227 +#define OBJ_id_smime_aa_ets_commitmentType OBJ_id_smime_aa,16L + +#define SN_id_smime_aa_ets_signerLocation "id-smime-aa-ets-signerLocation" +#define NID_id_smime_aa_ets_signerLocation 228 +#define OBJ_id_smime_aa_ets_signerLocation OBJ_id_smime_aa,17L + +#define SN_id_smime_aa_ets_signerAttr "id-smime-aa-ets-signerAttr" +#define NID_id_smime_aa_ets_signerAttr 229 +#define OBJ_id_smime_aa_ets_signerAttr OBJ_id_smime_aa,18L + +#define SN_id_smime_aa_ets_otherSigCert "id-smime-aa-ets-otherSigCert" +#define NID_id_smime_aa_ets_otherSigCert 230 +#define OBJ_id_smime_aa_ets_otherSigCert OBJ_id_smime_aa,19L + +#define SN_id_smime_aa_ets_contentTimestamp "id-smime-aa-ets-contentTimestamp" +#define NID_id_smime_aa_ets_contentTimestamp 231 +#define OBJ_id_smime_aa_ets_contentTimestamp OBJ_id_smime_aa,20L + +#define SN_id_smime_aa_ets_CertificateRefs "id-smime-aa-ets-CertificateRefs" +#define NID_id_smime_aa_ets_CertificateRefs 232 +#define OBJ_id_smime_aa_ets_CertificateRefs OBJ_id_smime_aa,21L + +#define SN_id_smime_aa_ets_RevocationRefs "id-smime-aa-ets-RevocationRefs" +#define NID_id_smime_aa_ets_RevocationRefs 233 +#define OBJ_id_smime_aa_ets_RevocationRefs OBJ_id_smime_aa,22L + +#define SN_id_smime_aa_ets_certValues "id-smime-aa-ets-certValues" +#define NID_id_smime_aa_ets_certValues 234 +#define OBJ_id_smime_aa_ets_certValues OBJ_id_smime_aa,23L + +#define SN_id_smime_aa_ets_revocationValues "id-smime-aa-ets-revocationValues" +#define NID_id_smime_aa_ets_revocationValues 235 +#define OBJ_id_smime_aa_ets_revocationValues OBJ_id_smime_aa,24L + +#define SN_id_smime_aa_ets_escTimeStamp "id-smime-aa-ets-escTimeStamp" +#define NID_id_smime_aa_ets_escTimeStamp 236 +#define OBJ_id_smime_aa_ets_escTimeStamp OBJ_id_smime_aa,25L + +#define SN_id_smime_aa_ets_certCRLTimestamp "id-smime-aa-ets-certCRLTimestamp" +#define NID_id_smime_aa_ets_certCRLTimestamp 237 +#define OBJ_id_smime_aa_ets_certCRLTimestamp OBJ_id_smime_aa,26L + +#define SN_id_smime_aa_ets_archiveTimeStamp "id-smime-aa-ets-archiveTimeStamp" +#define NID_id_smime_aa_ets_archiveTimeStamp 238 +#define OBJ_id_smime_aa_ets_archiveTimeStamp OBJ_id_smime_aa,27L + +#define SN_id_smime_aa_signatureType "id-smime-aa-signatureType" +#define NID_id_smime_aa_signatureType 239 +#define OBJ_id_smime_aa_signatureType OBJ_id_smime_aa,28L + +#define SN_id_smime_aa_dvcs_dvc "id-smime-aa-dvcs-dvc" +#define NID_id_smime_aa_dvcs_dvc 240 +#define OBJ_id_smime_aa_dvcs_dvc OBJ_id_smime_aa,29L + +#define SN_id_smime_alg_ESDHwith3DES "id-smime-alg-ESDHwith3DES" +#define NID_id_smime_alg_ESDHwith3DES 241 +#define OBJ_id_smime_alg_ESDHwith3DES OBJ_id_smime_alg,1L + +#define SN_id_smime_alg_ESDHwithRC2 "id-smime-alg-ESDHwithRC2" +#define NID_id_smime_alg_ESDHwithRC2 242 +#define OBJ_id_smime_alg_ESDHwithRC2 OBJ_id_smime_alg,2L + +#define SN_id_smime_alg_3DESwrap "id-smime-alg-3DESwrap" +#define NID_id_smime_alg_3DESwrap 243 +#define OBJ_id_smime_alg_3DESwrap OBJ_id_smime_alg,3L + +#define SN_id_smime_alg_RC2wrap "id-smime-alg-RC2wrap" +#define NID_id_smime_alg_RC2wrap 244 +#define OBJ_id_smime_alg_RC2wrap OBJ_id_smime_alg,4L + +#define SN_id_smime_alg_ESDH "id-smime-alg-ESDH" +#define NID_id_smime_alg_ESDH 245 +#define OBJ_id_smime_alg_ESDH OBJ_id_smime_alg,5L + +#define SN_id_smime_alg_CMS3DESwrap "id-smime-alg-CMS3DESwrap" +#define NID_id_smime_alg_CMS3DESwrap 246 +#define OBJ_id_smime_alg_CMS3DESwrap OBJ_id_smime_alg,6L + +#define SN_id_smime_alg_CMSRC2wrap "id-smime-alg-CMSRC2wrap" +#define NID_id_smime_alg_CMSRC2wrap 247 +#define OBJ_id_smime_alg_CMSRC2wrap OBJ_id_smime_alg,7L + +#define SN_id_alg_PWRI_KEK "id-alg-PWRI-KEK" +#define NID_id_alg_PWRI_KEK 893 +#define OBJ_id_alg_PWRI_KEK OBJ_id_smime_alg,9L + +#define SN_id_smime_cd_ldap "id-smime-cd-ldap" +#define NID_id_smime_cd_ldap 248 +#define OBJ_id_smime_cd_ldap OBJ_id_smime_cd,1L + +#define SN_id_smime_spq_ets_sqt_uri "id-smime-spq-ets-sqt-uri" +#define NID_id_smime_spq_ets_sqt_uri 249 +#define OBJ_id_smime_spq_ets_sqt_uri OBJ_id_smime_spq,1L + +#define SN_id_smime_spq_ets_sqt_unotice "id-smime-spq-ets-sqt-unotice" +#define NID_id_smime_spq_ets_sqt_unotice 250 +#define OBJ_id_smime_spq_ets_sqt_unotice OBJ_id_smime_spq,2L + +#define SN_id_smime_cti_ets_proofOfOrigin "id-smime-cti-ets-proofOfOrigin" +#define NID_id_smime_cti_ets_proofOfOrigin 251 +#define OBJ_id_smime_cti_ets_proofOfOrigin OBJ_id_smime_cti,1L + +#define SN_id_smime_cti_ets_proofOfReceipt "id-smime-cti-ets-proofOfReceipt" +#define NID_id_smime_cti_ets_proofOfReceipt 252 +#define OBJ_id_smime_cti_ets_proofOfReceipt OBJ_id_smime_cti,2L + +#define SN_id_smime_cti_ets_proofOfDelivery "id-smime-cti-ets-proofOfDelivery" +#define NID_id_smime_cti_ets_proofOfDelivery 253 +#define OBJ_id_smime_cti_ets_proofOfDelivery OBJ_id_smime_cti,3L + +#define SN_id_smime_cti_ets_proofOfSender "id-smime-cti-ets-proofOfSender" +#define NID_id_smime_cti_ets_proofOfSender 254 +#define OBJ_id_smime_cti_ets_proofOfSender OBJ_id_smime_cti,4L + +#define SN_id_smime_cti_ets_proofOfApproval "id-smime-cti-ets-proofOfApproval" +#define NID_id_smime_cti_ets_proofOfApproval 255 +#define OBJ_id_smime_cti_ets_proofOfApproval OBJ_id_smime_cti,5L + +#define SN_id_smime_cti_ets_proofOfCreation "id-smime-cti-ets-proofOfCreation" +#define NID_id_smime_cti_ets_proofOfCreation 256 +#define OBJ_id_smime_cti_ets_proofOfCreation OBJ_id_smime_cti,6L + +#define LN_friendlyName "friendlyName" +#define NID_friendlyName 156 +#define OBJ_friendlyName OBJ_pkcs9,20L + +#define LN_localKeyID "localKeyID" +#define NID_localKeyID 157 +#define OBJ_localKeyID OBJ_pkcs9,21L + +#define SN_ms_csp_name "CSPName" +#define LN_ms_csp_name "Microsoft CSP Name" +#define NID_ms_csp_name 417 +#define OBJ_ms_csp_name 1L,3L,6L,1L,4L,1L,311L,17L,1L + +#define SN_LocalKeySet "LocalKeySet" +#define LN_LocalKeySet "Microsoft Local Key set" +#define NID_LocalKeySet 856 +#define OBJ_LocalKeySet 1L,3L,6L,1L,4L,1L,311L,17L,2L + +#define OBJ_certTypes OBJ_pkcs9,22L + +#define LN_x509Certificate "x509Certificate" +#define NID_x509Certificate 158 +#define OBJ_x509Certificate OBJ_certTypes,1L + +#define LN_sdsiCertificate "sdsiCertificate" +#define NID_sdsiCertificate 159 +#define OBJ_sdsiCertificate OBJ_certTypes,2L + +#define OBJ_crlTypes OBJ_pkcs9,23L + +#define LN_x509Crl "x509Crl" +#define NID_x509Crl 160 +#define OBJ_x509Crl OBJ_crlTypes,1L + +#define OBJ_pkcs12 OBJ_pkcs,12L + +#define OBJ_pkcs12_pbeids OBJ_pkcs12,1L + +#define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128" +#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4" +#define NID_pbe_WithSHA1And128BitRC4 144 +#define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids,1L + +#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40" +#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4" +#define NID_pbe_WithSHA1And40BitRC4 145 +#define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids,2L + +#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES" +#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146 +#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids,3L + +#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES" +#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147 +#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids,4L + +#define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128" +#define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC" +#define NID_pbe_WithSHA1And128BitRC2_CBC 148 +#define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids,5L + +#define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40" +#define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC" +#define NID_pbe_WithSHA1And40BitRC2_CBC 149 +#define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids,6L + +#define OBJ_pkcs12_Version1 OBJ_pkcs12,10L + +#define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1,1L + +#define LN_keyBag "keyBag" +#define NID_keyBag 150 +#define OBJ_keyBag OBJ_pkcs12_BagIds,1L + +#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag" +#define NID_pkcs8ShroudedKeyBag 151 +#define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds,2L + +#define LN_certBag "certBag" +#define NID_certBag 152 +#define OBJ_certBag OBJ_pkcs12_BagIds,3L + +#define LN_crlBag "crlBag" +#define NID_crlBag 153 +#define OBJ_crlBag OBJ_pkcs12_BagIds,4L + +#define LN_secretBag "secretBag" +#define NID_secretBag 154 +#define OBJ_secretBag OBJ_pkcs12_BagIds,5L + +#define LN_safeContentsBag "safeContentsBag" +#define NID_safeContentsBag 155 +#define OBJ_safeContentsBag OBJ_pkcs12_BagIds,6L + +#define SN_md2 "MD2" +#define LN_md2 "md2" +#define NID_md2 3 +#define OBJ_md2 OBJ_rsadsi,2L,2L + +#define SN_md4 "MD4" +#define LN_md4 "md4" +#define NID_md4 257 +#define OBJ_md4 OBJ_rsadsi,2L,4L + +#define SN_md5 "MD5" +#define LN_md5 "md5" +#define NID_md5 4 +#define OBJ_md5 OBJ_rsadsi,2L,5L + +#define SN_md5_sha1 "MD5-SHA1" +#define LN_md5_sha1 "md5-sha1" +#define NID_md5_sha1 114 + +#define LN_hmacWithMD5 "hmacWithMD5" +#define NID_hmacWithMD5 797 +#define OBJ_hmacWithMD5 OBJ_rsadsi,2L,6L + +#define LN_hmacWithSHA1 "hmacWithSHA1" +#define NID_hmacWithSHA1 163 +#define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L + +#define LN_hmacWithSHA224 "hmacWithSHA224" +#define NID_hmacWithSHA224 798 +#define OBJ_hmacWithSHA224 OBJ_rsadsi,2L,8L + +#define LN_hmacWithSHA256 "hmacWithSHA256" +#define NID_hmacWithSHA256 799 +#define OBJ_hmacWithSHA256 OBJ_rsadsi,2L,9L + +#define LN_hmacWithSHA384 "hmacWithSHA384" +#define NID_hmacWithSHA384 800 +#define OBJ_hmacWithSHA384 OBJ_rsadsi,2L,10L + +#define LN_hmacWithSHA512 "hmacWithSHA512" +#define NID_hmacWithSHA512 801 +#define OBJ_hmacWithSHA512 OBJ_rsadsi,2L,11L + +#define SN_rc2_cbc "RC2-CBC" +#define LN_rc2_cbc "rc2-cbc" +#define NID_rc2_cbc 37 +#define OBJ_rc2_cbc OBJ_rsadsi,3L,2L + +#define SN_rc2_ecb "RC2-ECB" +#define LN_rc2_ecb "rc2-ecb" +#define NID_rc2_ecb 38 + +#define SN_rc2_cfb64 "RC2-CFB" +#define LN_rc2_cfb64 "rc2-cfb" +#define NID_rc2_cfb64 39 + +#define SN_rc2_ofb64 "RC2-OFB" +#define LN_rc2_ofb64 "rc2-ofb" +#define NID_rc2_ofb64 40 + +#define SN_rc2_40_cbc "RC2-40-CBC" +#define LN_rc2_40_cbc "rc2-40-cbc" +#define NID_rc2_40_cbc 98 + +#define SN_rc2_64_cbc "RC2-64-CBC" +#define LN_rc2_64_cbc "rc2-64-cbc" +#define NID_rc2_64_cbc 166 + +#define SN_rc4 "RC4" +#define LN_rc4 "rc4" +#define NID_rc4 5 +#define OBJ_rc4 OBJ_rsadsi,3L,4L + +#define SN_rc4_40 "RC4-40" +#define LN_rc4_40 "rc4-40" +#define NID_rc4_40 97 + +#define SN_des_ede3_cbc "DES-EDE3-CBC" +#define LN_des_ede3_cbc "des-ede3-cbc" +#define NID_des_ede3_cbc 44 +#define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L + +#define SN_rc5_cbc "RC5-CBC" +#define LN_rc5_cbc "rc5-cbc" +#define NID_rc5_cbc 120 +#define OBJ_rc5_cbc OBJ_rsadsi,3L,8L + +#define SN_rc5_ecb "RC5-ECB" +#define LN_rc5_ecb "rc5-ecb" +#define NID_rc5_ecb 121 + +#define SN_rc5_cfb64 "RC5-CFB" +#define LN_rc5_cfb64 "rc5-cfb" +#define NID_rc5_cfb64 122 + +#define SN_rc5_ofb64 "RC5-OFB" +#define LN_rc5_ofb64 "rc5-ofb" +#define NID_rc5_ofb64 123 + +#define SN_ms_ext_req "msExtReq" +#define LN_ms_ext_req "Microsoft Extension Request" +#define NID_ms_ext_req 171 +#define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L + +#define SN_ms_code_ind "msCodeInd" +#define LN_ms_code_ind "Microsoft Individual Code Signing" +#define NID_ms_code_ind 134 +#define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L + +#define SN_ms_code_com "msCodeCom" +#define LN_ms_code_com "Microsoft Commercial Code Signing" +#define NID_ms_code_com 135 +#define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L + +#define SN_ms_ctl_sign "msCTLSign" +#define LN_ms_ctl_sign "Microsoft Trust List Signing" +#define NID_ms_ctl_sign 136 +#define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L + +#define SN_ms_sgc "msSGC" +#define LN_ms_sgc "Microsoft Server Gated Crypto" +#define NID_ms_sgc 137 +#define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L + +#define SN_ms_efs "msEFS" +#define LN_ms_efs "Microsoft Encrypted File System" +#define NID_ms_efs 138 +#define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L + +#define SN_ms_smartcard_login "msSmartcardLogin" +#define LN_ms_smartcard_login "Microsoft Smartcardlogin" +#define NID_ms_smartcard_login 648 +#define OBJ_ms_smartcard_login 1L,3L,6L,1L,4L,1L,311L,20L,2L,2L + +#define SN_ms_upn "msUPN" +#define LN_ms_upn "Microsoft Universal Principal Name" +#define NID_ms_upn 649 +#define OBJ_ms_upn 1L,3L,6L,1L,4L,1L,311L,20L,2L,3L + +#define SN_idea_cbc "IDEA-CBC" +#define LN_idea_cbc "idea-cbc" +#define NID_idea_cbc 34 +#define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L + +#define SN_idea_ecb "IDEA-ECB" +#define LN_idea_ecb "idea-ecb" +#define NID_idea_ecb 36 + +#define SN_idea_cfb64 "IDEA-CFB" +#define LN_idea_cfb64 "idea-cfb" +#define NID_idea_cfb64 35 + +#define SN_idea_ofb64 "IDEA-OFB" +#define LN_idea_ofb64 "idea-ofb" +#define NID_idea_ofb64 46 + +#define SN_bf_cbc "BF-CBC" +#define LN_bf_cbc "bf-cbc" +#define NID_bf_cbc 91 +#define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L + +#define SN_bf_ecb "BF-ECB" +#define LN_bf_ecb "bf-ecb" +#define NID_bf_ecb 92 + +#define SN_bf_cfb64 "BF-CFB" +#define LN_bf_cfb64 "bf-cfb" +#define NID_bf_cfb64 93 + +#define SN_bf_ofb64 "BF-OFB" +#define LN_bf_ofb64 "bf-ofb" +#define NID_bf_ofb64 94 + +#define SN_id_pkix "PKIX" +#define NID_id_pkix 127 +#define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L + +#define SN_id_pkix_mod "id-pkix-mod" +#define NID_id_pkix_mod 258 +#define OBJ_id_pkix_mod OBJ_id_pkix,0L + +#define SN_id_pe "id-pe" +#define NID_id_pe 175 +#define OBJ_id_pe OBJ_id_pkix,1L + +#define SN_id_qt "id-qt" +#define NID_id_qt 259 +#define OBJ_id_qt OBJ_id_pkix,2L + +#define SN_id_kp "id-kp" +#define NID_id_kp 128 +#define OBJ_id_kp OBJ_id_pkix,3L + +#define SN_id_it "id-it" +#define NID_id_it 260 +#define OBJ_id_it OBJ_id_pkix,4L + +#define SN_id_pkip "id-pkip" +#define NID_id_pkip 261 +#define OBJ_id_pkip OBJ_id_pkix,5L + +#define SN_id_alg "id-alg" +#define NID_id_alg 262 +#define OBJ_id_alg OBJ_id_pkix,6L + +#define SN_id_cmc "id-cmc" +#define NID_id_cmc 263 +#define OBJ_id_cmc OBJ_id_pkix,7L + +#define SN_id_on "id-on" +#define NID_id_on 264 +#define OBJ_id_on OBJ_id_pkix,8L + +#define SN_id_pda "id-pda" +#define NID_id_pda 265 +#define OBJ_id_pda OBJ_id_pkix,9L + +#define SN_id_aca "id-aca" +#define NID_id_aca 266 +#define OBJ_id_aca OBJ_id_pkix,10L + +#define SN_id_qcs "id-qcs" +#define NID_id_qcs 267 +#define OBJ_id_qcs OBJ_id_pkix,11L + +#define SN_id_cct "id-cct" +#define NID_id_cct 268 +#define OBJ_id_cct OBJ_id_pkix,12L + +#define SN_id_ppl "id-ppl" +#define NID_id_ppl 662 +#define OBJ_id_ppl OBJ_id_pkix,21L + +#define SN_id_ad "id-ad" +#define NID_id_ad 176 +#define OBJ_id_ad OBJ_id_pkix,48L + +#define SN_id_pkix1_explicit_88 "id-pkix1-explicit-88" +#define NID_id_pkix1_explicit_88 269 +#define OBJ_id_pkix1_explicit_88 OBJ_id_pkix_mod,1L + +#define SN_id_pkix1_implicit_88 "id-pkix1-implicit-88" +#define NID_id_pkix1_implicit_88 270 +#define OBJ_id_pkix1_implicit_88 OBJ_id_pkix_mod,2L + +#define SN_id_pkix1_explicit_93 "id-pkix1-explicit-93" +#define NID_id_pkix1_explicit_93 271 +#define OBJ_id_pkix1_explicit_93 OBJ_id_pkix_mod,3L + +#define SN_id_pkix1_implicit_93 "id-pkix1-implicit-93" +#define NID_id_pkix1_implicit_93 272 +#define OBJ_id_pkix1_implicit_93 OBJ_id_pkix_mod,4L + +#define SN_id_mod_crmf "id-mod-crmf" +#define NID_id_mod_crmf 273 +#define OBJ_id_mod_crmf OBJ_id_pkix_mod,5L + +#define SN_id_mod_cmc "id-mod-cmc" +#define NID_id_mod_cmc 274 +#define OBJ_id_mod_cmc OBJ_id_pkix_mod,6L + +#define SN_id_mod_kea_profile_88 "id-mod-kea-profile-88" +#define NID_id_mod_kea_profile_88 275 +#define OBJ_id_mod_kea_profile_88 OBJ_id_pkix_mod,7L + +#define SN_id_mod_kea_profile_93 "id-mod-kea-profile-93" +#define NID_id_mod_kea_profile_93 276 +#define OBJ_id_mod_kea_profile_93 OBJ_id_pkix_mod,8L + +#define SN_id_mod_cmp "id-mod-cmp" +#define NID_id_mod_cmp 277 +#define OBJ_id_mod_cmp OBJ_id_pkix_mod,9L + +#define SN_id_mod_qualified_cert_88 "id-mod-qualified-cert-88" +#define NID_id_mod_qualified_cert_88 278 +#define OBJ_id_mod_qualified_cert_88 OBJ_id_pkix_mod,10L + +#define SN_id_mod_qualified_cert_93 "id-mod-qualified-cert-93" +#define NID_id_mod_qualified_cert_93 279 +#define OBJ_id_mod_qualified_cert_93 OBJ_id_pkix_mod,11L + +#define SN_id_mod_attribute_cert "id-mod-attribute-cert" +#define NID_id_mod_attribute_cert 280 +#define OBJ_id_mod_attribute_cert OBJ_id_pkix_mod,12L + +#define SN_id_mod_timestamp_protocol "id-mod-timestamp-protocol" +#define NID_id_mod_timestamp_protocol 281 +#define OBJ_id_mod_timestamp_protocol OBJ_id_pkix_mod,13L + +#define SN_id_mod_ocsp "id-mod-ocsp" +#define NID_id_mod_ocsp 282 +#define OBJ_id_mod_ocsp OBJ_id_pkix_mod,14L + +#define SN_id_mod_dvcs "id-mod-dvcs" +#define NID_id_mod_dvcs 283 +#define OBJ_id_mod_dvcs OBJ_id_pkix_mod,15L + +#define SN_id_mod_cmp2000 "id-mod-cmp2000" +#define NID_id_mod_cmp2000 284 +#define OBJ_id_mod_cmp2000 OBJ_id_pkix_mod,16L + +#define SN_info_access "authorityInfoAccess" +#define LN_info_access "Authority Information Access" +#define NID_info_access 177 +#define OBJ_info_access OBJ_id_pe,1L + +#define SN_biometricInfo "biometricInfo" +#define LN_biometricInfo "Biometric Info" +#define NID_biometricInfo 285 +#define OBJ_biometricInfo OBJ_id_pe,2L + +#define SN_qcStatements "qcStatements" +#define NID_qcStatements 286 +#define OBJ_qcStatements OBJ_id_pe,3L + +#define SN_ac_auditEntity "ac-auditEntity" +#define NID_ac_auditEntity 287 +#define OBJ_ac_auditEntity OBJ_id_pe,4L + +#define SN_ac_targeting "ac-targeting" +#define NID_ac_targeting 288 +#define OBJ_ac_targeting OBJ_id_pe,5L + +#define SN_aaControls "aaControls" +#define NID_aaControls 289 +#define OBJ_aaControls OBJ_id_pe,6L + +#define SN_sbgp_ipAddrBlock "sbgp-ipAddrBlock" +#define NID_sbgp_ipAddrBlock 290 +#define OBJ_sbgp_ipAddrBlock OBJ_id_pe,7L + +#define SN_sbgp_autonomousSysNum "sbgp-autonomousSysNum" +#define NID_sbgp_autonomousSysNum 291 +#define OBJ_sbgp_autonomousSysNum OBJ_id_pe,8L + +#define SN_sbgp_routerIdentifier "sbgp-routerIdentifier" +#define NID_sbgp_routerIdentifier 292 +#define OBJ_sbgp_routerIdentifier OBJ_id_pe,9L + +#define SN_ac_proxying "ac-proxying" +#define NID_ac_proxying 397 +#define OBJ_ac_proxying OBJ_id_pe,10L + +#define SN_sinfo_access "subjectInfoAccess" +#define LN_sinfo_access "Subject Information Access" +#define NID_sinfo_access 398 +#define OBJ_sinfo_access OBJ_id_pe,11L + +#define SN_proxyCertInfo "proxyCertInfo" +#define LN_proxyCertInfo "Proxy Certificate Information" +#define NID_proxyCertInfo 663 +#define OBJ_proxyCertInfo OBJ_id_pe,14L + +#define SN_id_qt_cps "id-qt-cps" +#define LN_id_qt_cps "Policy Qualifier CPS" +#define NID_id_qt_cps 164 +#define OBJ_id_qt_cps OBJ_id_qt,1L + +#define SN_id_qt_unotice "id-qt-unotice" +#define LN_id_qt_unotice "Policy Qualifier User Notice" +#define NID_id_qt_unotice 165 +#define OBJ_id_qt_unotice OBJ_id_qt,2L + +#define SN_textNotice "textNotice" +#define NID_textNotice 293 +#define OBJ_textNotice OBJ_id_qt,3L + +#define SN_server_auth "serverAuth" +#define LN_server_auth "TLS Web Server Authentication" +#define NID_server_auth 129 +#define OBJ_server_auth OBJ_id_kp,1L + +#define SN_client_auth "clientAuth" +#define LN_client_auth "TLS Web Client Authentication" +#define NID_client_auth 130 +#define OBJ_client_auth OBJ_id_kp,2L + +#define SN_code_sign "codeSigning" +#define LN_code_sign "Code Signing" +#define NID_code_sign 131 +#define OBJ_code_sign OBJ_id_kp,3L + +#define SN_email_protect "emailProtection" +#define LN_email_protect "E-mail Protection" +#define NID_email_protect 132 +#define OBJ_email_protect OBJ_id_kp,4L + +#define SN_ipsecEndSystem "ipsecEndSystem" +#define LN_ipsecEndSystem "IPSec End System" +#define NID_ipsecEndSystem 294 +#define OBJ_ipsecEndSystem OBJ_id_kp,5L + +#define SN_ipsecTunnel "ipsecTunnel" +#define LN_ipsecTunnel "IPSec Tunnel" +#define NID_ipsecTunnel 295 +#define OBJ_ipsecTunnel OBJ_id_kp,6L + +#define SN_ipsecUser "ipsecUser" +#define LN_ipsecUser "IPSec User" +#define NID_ipsecUser 296 +#define OBJ_ipsecUser OBJ_id_kp,7L + +#define SN_time_stamp "timeStamping" +#define LN_time_stamp "Time Stamping" +#define NID_time_stamp 133 +#define OBJ_time_stamp OBJ_id_kp,8L + +#define SN_OCSP_sign "OCSPSigning" +#define LN_OCSP_sign "OCSP Signing" +#define NID_OCSP_sign 180 +#define OBJ_OCSP_sign OBJ_id_kp,9L + +#define SN_dvcs "DVCS" +#define LN_dvcs "dvcs" +#define NID_dvcs 297 +#define OBJ_dvcs OBJ_id_kp,10L + +#define SN_id_it_caProtEncCert "id-it-caProtEncCert" +#define NID_id_it_caProtEncCert 298 +#define OBJ_id_it_caProtEncCert OBJ_id_it,1L + +#define SN_id_it_signKeyPairTypes "id-it-signKeyPairTypes" +#define NID_id_it_signKeyPairTypes 299 +#define OBJ_id_it_signKeyPairTypes OBJ_id_it,2L + +#define SN_id_it_encKeyPairTypes "id-it-encKeyPairTypes" +#define NID_id_it_encKeyPairTypes 300 +#define OBJ_id_it_encKeyPairTypes OBJ_id_it,3L + +#define SN_id_it_preferredSymmAlg "id-it-preferredSymmAlg" +#define NID_id_it_preferredSymmAlg 301 +#define OBJ_id_it_preferredSymmAlg OBJ_id_it,4L + +#define SN_id_it_caKeyUpdateInfo "id-it-caKeyUpdateInfo" +#define NID_id_it_caKeyUpdateInfo 302 +#define OBJ_id_it_caKeyUpdateInfo OBJ_id_it,5L + +#define SN_id_it_currentCRL "id-it-currentCRL" +#define NID_id_it_currentCRL 303 +#define OBJ_id_it_currentCRL OBJ_id_it,6L + +#define SN_id_it_unsupportedOIDs "id-it-unsupportedOIDs" +#define NID_id_it_unsupportedOIDs 304 +#define OBJ_id_it_unsupportedOIDs OBJ_id_it,7L + +#define SN_id_it_subscriptionRequest "id-it-subscriptionRequest" +#define NID_id_it_subscriptionRequest 305 +#define OBJ_id_it_subscriptionRequest OBJ_id_it,8L + +#define SN_id_it_subscriptionResponse "id-it-subscriptionResponse" +#define NID_id_it_subscriptionResponse 306 +#define OBJ_id_it_subscriptionResponse OBJ_id_it,9L + +#define SN_id_it_keyPairParamReq "id-it-keyPairParamReq" +#define NID_id_it_keyPairParamReq 307 +#define OBJ_id_it_keyPairParamReq OBJ_id_it,10L + +#define SN_id_it_keyPairParamRep "id-it-keyPairParamRep" +#define NID_id_it_keyPairParamRep 308 +#define OBJ_id_it_keyPairParamRep OBJ_id_it,11L + +#define SN_id_it_revPassphrase "id-it-revPassphrase" +#define NID_id_it_revPassphrase 309 +#define OBJ_id_it_revPassphrase OBJ_id_it,12L + +#define SN_id_it_implicitConfirm "id-it-implicitConfirm" +#define NID_id_it_implicitConfirm 310 +#define OBJ_id_it_implicitConfirm OBJ_id_it,13L + +#define SN_id_it_confirmWaitTime "id-it-confirmWaitTime" +#define NID_id_it_confirmWaitTime 311 +#define OBJ_id_it_confirmWaitTime OBJ_id_it,14L + +#define SN_id_it_origPKIMessage "id-it-origPKIMessage" +#define NID_id_it_origPKIMessage 312 +#define OBJ_id_it_origPKIMessage OBJ_id_it,15L + +#define SN_id_it_suppLangTags "id-it-suppLangTags" +#define NID_id_it_suppLangTags 784 +#define OBJ_id_it_suppLangTags OBJ_id_it,16L + +#define SN_id_regCtrl "id-regCtrl" +#define NID_id_regCtrl 313 +#define OBJ_id_regCtrl OBJ_id_pkip,1L + +#define SN_id_regInfo "id-regInfo" +#define NID_id_regInfo 314 +#define OBJ_id_regInfo OBJ_id_pkip,2L + +#define SN_id_regCtrl_regToken "id-regCtrl-regToken" +#define NID_id_regCtrl_regToken 315 +#define OBJ_id_regCtrl_regToken OBJ_id_regCtrl,1L + +#define SN_id_regCtrl_authenticator "id-regCtrl-authenticator" +#define NID_id_regCtrl_authenticator 316 +#define OBJ_id_regCtrl_authenticator OBJ_id_regCtrl,2L + +#define SN_id_regCtrl_pkiPublicationInfo "id-regCtrl-pkiPublicationInfo" +#define NID_id_regCtrl_pkiPublicationInfo 317 +#define OBJ_id_regCtrl_pkiPublicationInfo OBJ_id_regCtrl,3L + +#define SN_id_regCtrl_pkiArchiveOptions "id-regCtrl-pkiArchiveOptions" +#define NID_id_regCtrl_pkiArchiveOptions 318 +#define OBJ_id_regCtrl_pkiArchiveOptions OBJ_id_regCtrl,4L + +#define SN_id_regCtrl_oldCertID "id-regCtrl-oldCertID" +#define NID_id_regCtrl_oldCertID 319 +#define OBJ_id_regCtrl_oldCertID OBJ_id_regCtrl,5L + +#define SN_id_regCtrl_protocolEncrKey "id-regCtrl-protocolEncrKey" +#define NID_id_regCtrl_protocolEncrKey 320 +#define OBJ_id_regCtrl_protocolEncrKey OBJ_id_regCtrl,6L + +#define SN_id_regInfo_utf8Pairs "id-regInfo-utf8Pairs" +#define NID_id_regInfo_utf8Pairs 321 +#define OBJ_id_regInfo_utf8Pairs OBJ_id_regInfo,1L + +#define SN_id_regInfo_certReq "id-regInfo-certReq" +#define NID_id_regInfo_certReq 322 +#define OBJ_id_regInfo_certReq OBJ_id_regInfo,2L + +#define SN_id_alg_des40 "id-alg-des40" +#define NID_id_alg_des40 323 +#define OBJ_id_alg_des40 OBJ_id_alg,1L + +#define SN_id_alg_noSignature "id-alg-noSignature" +#define NID_id_alg_noSignature 324 +#define OBJ_id_alg_noSignature OBJ_id_alg,2L + +#define SN_id_alg_dh_sig_hmac_sha1 "id-alg-dh-sig-hmac-sha1" +#define NID_id_alg_dh_sig_hmac_sha1 325 +#define OBJ_id_alg_dh_sig_hmac_sha1 OBJ_id_alg,3L + +#define SN_id_alg_dh_pop "id-alg-dh-pop" +#define NID_id_alg_dh_pop 326 +#define OBJ_id_alg_dh_pop OBJ_id_alg,4L + +#define SN_id_cmc_statusInfo "id-cmc-statusInfo" +#define NID_id_cmc_statusInfo 327 +#define OBJ_id_cmc_statusInfo OBJ_id_cmc,1L + +#define SN_id_cmc_identification "id-cmc-identification" +#define NID_id_cmc_identification 328 +#define OBJ_id_cmc_identification OBJ_id_cmc,2L + +#define SN_id_cmc_identityProof "id-cmc-identityProof" +#define NID_id_cmc_identityProof 329 +#define OBJ_id_cmc_identityProof OBJ_id_cmc,3L + +#define SN_id_cmc_dataReturn "id-cmc-dataReturn" +#define NID_id_cmc_dataReturn 330 +#define OBJ_id_cmc_dataReturn OBJ_id_cmc,4L + +#define SN_id_cmc_transactionId "id-cmc-transactionId" +#define NID_id_cmc_transactionId 331 +#define OBJ_id_cmc_transactionId OBJ_id_cmc,5L + +#define SN_id_cmc_senderNonce "id-cmc-senderNonce" +#define NID_id_cmc_senderNonce 332 +#define OBJ_id_cmc_senderNonce OBJ_id_cmc,6L + +#define SN_id_cmc_recipientNonce "id-cmc-recipientNonce" +#define NID_id_cmc_recipientNonce 333 +#define OBJ_id_cmc_recipientNonce OBJ_id_cmc,7L + +#define SN_id_cmc_addExtensions "id-cmc-addExtensions" +#define NID_id_cmc_addExtensions 334 +#define OBJ_id_cmc_addExtensions OBJ_id_cmc,8L + +#define SN_id_cmc_encryptedPOP "id-cmc-encryptedPOP" +#define NID_id_cmc_encryptedPOP 335 +#define OBJ_id_cmc_encryptedPOP OBJ_id_cmc,9L + +#define SN_id_cmc_decryptedPOP "id-cmc-decryptedPOP" +#define NID_id_cmc_decryptedPOP 336 +#define OBJ_id_cmc_decryptedPOP OBJ_id_cmc,10L + +#define SN_id_cmc_lraPOPWitness "id-cmc-lraPOPWitness" +#define NID_id_cmc_lraPOPWitness 337 +#define OBJ_id_cmc_lraPOPWitness OBJ_id_cmc,11L + +#define SN_id_cmc_getCert "id-cmc-getCert" +#define NID_id_cmc_getCert 338 +#define OBJ_id_cmc_getCert OBJ_id_cmc,15L + +#define SN_id_cmc_getCRL "id-cmc-getCRL" +#define NID_id_cmc_getCRL 339 +#define OBJ_id_cmc_getCRL OBJ_id_cmc,16L + +#define SN_id_cmc_revokeRequest "id-cmc-revokeRequest" +#define NID_id_cmc_revokeRequest 340 +#define OBJ_id_cmc_revokeRequest OBJ_id_cmc,17L + +#define SN_id_cmc_regInfo "id-cmc-regInfo" +#define NID_id_cmc_regInfo 341 +#define OBJ_id_cmc_regInfo OBJ_id_cmc,18L + +#define SN_id_cmc_responseInfo "id-cmc-responseInfo" +#define NID_id_cmc_responseInfo 342 +#define OBJ_id_cmc_responseInfo OBJ_id_cmc,19L + +#define SN_id_cmc_queryPending "id-cmc-queryPending" +#define NID_id_cmc_queryPending 343 +#define OBJ_id_cmc_queryPending OBJ_id_cmc,21L + +#define SN_id_cmc_popLinkRandom "id-cmc-popLinkRandom" +#define NID_id_cmc_popLinkRandom 344 +#define OBJ_id_cmc_popLinkRandom OBJ_id_cmc,22L + +#define SN_id_cmc_popLinkWitness "id-cmc-popLinkWitness" +#define NID_id_cmc_popLinkWitness 345 +#define OBJ_id_cmc_popLinkWitness OBJ_id_cmc,23L + +#define SN_id_cmc_confirmCertAcceptance "id-cmc-confirmCertAcceptance" +#define NID_id_cmc_confirmCertAcceptance 346 +#define OBJ_id_cmc_confirmCertAcceptance OBJ_id_cmc,24L + +#define SN_id_on_personalData "id-on-personalData" +#define NID_id_on_personalData 347 +#define OBJ_id_on_personalData OBJ_id_on,1L + +#define SN_id_on_permanentIdentifier "id-on-permanentIdentifier" +#define LN_id_on_permanentIdentifier "Permanent Identifier" +#define NID_id_on_permanentIdentifier 858 +#define OBJ_id_on_permanentIdentifier OBJ_id_on,3L + +#define SN_id_pda_dateOfBirth "id-pda-dateOfBirth" +#define NID_id_pda_dateOfBirth 348 +#define OBJ_id_pda_dateOfBirth OBJ_id_pda,1L + +#define SN_id_pda_placeOfBirth "id-pda-placeOfBirth" +#define NID_id_pda_placeOfBirth 349 +#define OBJ_id_pda_placeOfBirth OBJ_id_pda,2L + +#define SN_id_pda_gender "id-pda-gender" +#define NID_id_pda_gender 351 +#define OBJ_id_pda_gender OBJ_id_pda,3L + +#define SN_id_pda_countryOfCitizenship "id-pda-countryOfCitizenship" +#define NID_id_pda_countryOfCitizenship 352 +#define OBJ_id_pda_countryOfCitizenship OBJ_id_pda,4L + +#define SN_id_pda_countryOfResidence "id-pda-countryOfResidence" +#define NID_id_pda_countryOfResidence 353 +#define OBJ_id_pda_countryOfResidence OBJ_id_pda,5L + +#define SN_id_aca_authenticationInfo "id-aca-authenticationInfo" +#define NID_id_aca_authenticationInfo 354 +#define OBJ_id_aca_authenticationInfo OBJ_id_aca,1L + +#define SN_id_aca_accessIdentity "id-aca-accessIdentity" +#define NID_id_aca_accessIdentity 355 +#define OBJ_id_aca_accessIdentity OBJ_id_aca,2L + +#define SN_id_aca_chargingIdentity "id-aca-chargingIdentity" +#define NID_id_aca_chargingIdentity 356 +#define OBJ_id_aca_chargingIdentity OBJ_id_aca,3L + +#define SN_id_aca_group "id-aca-group" +#define NID_id_aca_group 357 +#define OBJ_id_aca_group OBJ_id_aca,4L + +#define SN_id_aca_role "id-aca-role" +#define NID_id_aca_role 358 +#define OBJ_id_aca_role OBJ_id_aca,5L + +#define SN_id_aca_encAttrs "id-aca-encAttrs" +#define NID_id_aca_encAttrs 399 +#define OBJ_id_aca_encAttrs OBJ_id_aca,6L + +#define SN_id_qcs_pkixQCSyntax_v1 "id-qcs-pkixQCSyntax-v1" +#define NID_id_qcs_pkixQCSyntax_v1 359 +#define OBJ_id_qcs_pkixQCSyntax_v1 OBJ_id_qcs,1L + +#define SN_id_cct_crs "id-cct-crs" +#define NID_id_cct_crs 360 +#define OBJ_id_cct_crs OBJ_id_cct,1L + +#define SN_id_cct_PKIData "id-cct-PKIData" +#define NID_id_cct_PKIData 361 +#define OBJ_id_cct_PKIData OBJ_id_cct,2L + +#define SN_id_cct_PKIResponse "id-cct-PKIResponse" +#define NID_id_cct_PKIResponse 362 +#define OBJ_id_cct_PKIResponse OBJ_id_cct,3L + +#define SN_id_ppl_anyLanguage "id-ppl-anyLanguage" +#define LN_id_ppl_anyLanguage "Any language" +#define NID_id_ppl_anyLanguage 664 +#define OBJ_id_ppl_anyLanguage OBJ_id_ppl,0L + +#define SN_id_ppl_inheritAll "id-ppl-inheritAll" +#define LN_id_ppl_inheritAll "Inherit all" +#define NID_id_ppl_inheritAll 665 +#define OBJ_id_ppl_inheritAll OBJ_id_ppl,1L + +#define SN_Independent "id-ppl-independent" +#define LN_Independent "Independent" +#define NID_Independent 667 +#define OBJ_Independent OBJ_id_ppl,2L + +#define SN_ad_OCSP "OCSP" +#define LN_ad_OCSP "OCSP" +#define NID_ad_OCSP 178 +#define OBJ_ad_OCSP OBJ_id_ad,1L + +#define SN_ad_ca_issuers "caIssuers" +#define LN_ad_ca_issuers "CA Issuers" +#define NID_ad_ca_issuers 179 +#define OBJ_ad_ca_issuers OBJ_id_ad,2L + +#define SN_ad_timeStamping "ad_timestamping" +#define LN_ad_timeStamping "AD Time Stamping" +#define NID_ad_timeStamping 363 +#define OBJ_ad_timeStamping OBJ_id_ad,3L + +#define SN_ad_dvcs "AD_DVCS" +#define LN_ad_dvcs "ad dvcs" +#define NID_ad_dvcs 364 +#define OBJ_ad_dvcs OBJ_id_ad,4L + +#define SN_caRepository "caRepository" +#define LN_caRepository "CA Repository" +#define NID_caRepository 785 +#define OBJ_caRepository OBJ_id_ad,5L + +#define OBJ_id_pkix_OCSP OBJ_ad_OCSP + +#define SN_id_pkix_OCSP_basic "basicOCSPResponse" +#define LN_id_pkix_OCSP_basic "Basic OCSP Response" +#define NID_id_pkix_OCSP_basic 365 +#define OBJ_id_pkix_OCSP_basic OBJ_id_pkix_OCSP,1L + +#define SN_id_pkix_OCSP_Nonce "Nonce" +#define LN_id_pkix_OCSP_Nonce "OCSP Nonce" +#define NID_id_pkix_OCSP_Nonce 366 +#define OBJ_id_pkix_OCSP_Nonce OBJ_id_pkix_OCSP,2L + +#define SN_id_pkix_OCSP_CrlID "CrlID" +#define LN_id_pkix_OCSP_CrlID "OCSP CRL ID" +#define NID_id_pkix_OCSP_CrlID 367 +#define OBJ_id_pkix_OCSP_CrlID OBJ_id_pkix_OCSP,3L + +#define SN_id_pkix_OCSP_acceptableResponses "acceptableResponses" +#define LN_id_pkix_OCSP_acceptableResponses "Acceptable OCSP Responses" +#define NID_id_pkix_OCSP_acceptableResponses 368 +#define OBJ_id_pkix_OCSP_acceptableResponses OBJ_id_pkix_OCSP,4L + +#define SN_id_pkix_OCSP_noCheck "noCheck" +#define LN_id_pkix_OCSP_noCheck "OCSP No Check" +#define NID_id_pkix_OCSP_noCheck 369 +#define OBJ_id_pkix_OCSP_noCheck OBJ_id_pkix_OCSP,5L + +#define SN_id_pkix_OCSP_archiveCutoff "archiveCutoff" +#define LN_id_pkix_OCSP_archiveCutoff "OCSP Archive Cutoff" +#define NID_id_pkix_OCSP_archiveCutoff 370 +#define OBJ_id_pkix_OCSP_archiveCutoff OBJ_id_pkix_OCSP,6L + +#define SN_id_pkix_OCSP_serviceLocator "serviceLocator" +#define LN_id_pkix_OCSP_serviceLocator "OCSP Service Locator" +#define NID_id_pkix_OCSP_serviceLocator 371 +#define OBJ_id_pkix_OCSP_serviceLocator OBJ_id_pkix_OCSP,7L + +#define SN_id_pkix_OCSP_extendedStatus "extendedStatus" +#define LN_id_pkix_OCSP_extendedStatus "Extended OCSP Status" +#define NID_id_pkix_OCSP_extendedStatus 372 +#define OBJ_id_pkix_OCSP_extendedStatus OBJ_id_pkix_OCSP,8L + +#define SN_id_pkix_OCSP_valid "valid" +#define NID_id_pkix_OCSP_valid 373 +#define OBJ_id_pkix_OCSP_valid OBJ_id_pkix_OCSP,9L + +#define SN_id_pkix_OCSP_path "path" +#define NID_id_pkix_OCSP_path 374 +#define OBJ_id_pkix_OCSP_path OBJ_id_pkix_OCSP,10L + +#define SN_id_pkix_OCSP_trustRoot "trustRoot" +#define LN_id_pkix_OCSP_trustRoot "Trust Root" +#define NID_id_pkix_OCSP_trustRoot 375 +#define OBJ_id_pkix_OCSP_trustRoot OBJ_id_pkix_OCSP,11L + +#define SN_algorithm "algorithm" +#define LN_algorithm "algorithm" +#define NID_algorithm 376 +#define OBJ_algorithm 1L,3L,14L,3L,2L + +#define SN_md5WithRSA "RSA-NP-MD5" +#define LN_md5WithRSA "md5WithRSA" +#define NID_md5WithRSA 104 +#define OBJ_md5WithRSA OBJ_algorithm,3L + +#define SN_des_ecb "DES-ECB" +#define LN_des_ecb "des-ecb" +#define NID_des_ecb 29 +#define OBJ_des_ecb OBJ_algorithm,6L + +#define SN_des_cbc "DES-CBC" +#define LN_des_cbc "des-cbc" +#define NID_des_cbc 31 +#define OBJ_des_cbc OBJ_algorithm,7L + +#define SN_des_ofb64 "DES-OFB" +#define LN_des_ofb64 "des-ofb" +#define NID_des_ofb64 45 +#define OBJ_des_ofb64 OBJ_algorithm,8L + +#define SN_des_cfb64 "DES-CFB" +#define LN_des_cfb64 "des-cfb" +#define NID_des_cfb64 30 +#define OBJ_des_cfb64 OBJ_algorithm,9L + +#define SN_rsaSignature "rsaSignature" +#define NID_rsaSignature 377 +#define OBJ_rsaSignature OBJ_algorithm,11L + +#define SN_dsa_2 "DSA-old" +#define LN_dsa_2 "dsaEncryption-old" +#define NID_dsa_2 67 +#define OBJ_dsa_2 OBJ_algorithm,12L + +#define SN_dsaWithSHA "DSA-SHA" +#define LN_dsaWithSHA "dsaWithSHA" +#define NID_dsaWithSHA 66 +#define OBJ_dsaWithSHA OBJ_algorithm,13L + +#define SN_shaWithRSAEncryption "RSA-SHA" +#define LN_shaWithRSAEncryption "shaWithRSAEncryption" +#define NID_shaWithRSAEncryption 42 +#define OBJ_shaWithRSAEncryption OBJ_algorithm,15L + +#define SN_des_ede_ecb "DES-EDE" +#define LN_des_ede_ecb "des-ede" +#define NID_des_ede_ecb 32 +#define OBJ_des_ede_ecb OBJ_algorithm,17L + +#define SN_des_ede3_ecb "DES-EDE3" +#define LN_des_ede3_ecb "des-ede3" +#define NID_des_ede3_ecb 33 + +#define SN_des_ede_cbc "DES-EDE-CBC" +#define LN_des_ede_cbc "des-ede-cbc" +#define NID_des_ede_cbc 43 + +#define SN_des_ede_cfb64 "DES-EDE-CFB" +#define LN_des_ede_cfb64 "des-ede-cfb" +#define NID_des_ede_cfb64 60 + +#define SN_des_ede3_cfb64 "DES-EDE3-CFB" +#define LN_des_ede3_cfb64 "des-ede3-cfb" +#define NID_des_ede3_cfb64 61 + +#define SN_des_ede_ofb64 "DES-EDE-OFB" +#define LN_des_ede_ofb64 "des-ede-ofb" +#define NID_des_ede_ofb64 62 + +#define SN_des_ede3_ofb64 "DES-EDE3-OFB" +#define LN_des_ede3_ofb64 "des-ede3-ofb" +#define NID_des_ede3_ofb64 63 + +#define SN_desx_cbc "DESX-CBC" +#define LN_desx_cbc "desx-cbc" +#define NID_desx_cbc 80 + +#define SN_sha "SHA" +#define LN_sha "sha" +#define NID_sha 41 +#define OBJ_sha OBJ_algorithm,18L + +#define SN_sha1 "SHA1" +#define LN_sha1 "sha1" +#define NID_sha1 64 +#define OBJ_sha1 OBJ_algorithm,26L + +#define SN_dsaWithSHA1_2 "DSA-SHA1-old" +#define LN_dsaWithSHA1_2 "dsaWithSHA1-old" +#define NID_dsaWithSHA1_2 70 +#define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L + +#define SN_sha1WithRSA "RSA-SHA1-2" +#define LN_sha1WithRSA "sha1WithRSA" +#define NID_sha1WithRSA 115 +#define OBJ_sha1WithRSA OBJ_algorithm,29L + +#define SN_ripemd160 "RIPEMD160" +#define LN_ripemd160 "ripemd160" +#define NID_ripemd160 117 +#define OBJ_ripemd160 1L,3L,36L,3L,2L,1L + +#define SN_ripemd160WithRSA "RSA-RIPEMD160" +#define LN_ripemd160WithRSA "ripemd160WithRSA" +#define NID_ripemd160WithRSA 119 +#define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L + +#define SN_sxnet "SXNetID" +#define LN_sxnet "Strong Extranet ID" +#define NID_sxnet 143 +#define OBJ_sxnet 1L,3L,101L,1L,4L,1L + +#define SN_X500 "X500" +#define LN_X500 "directory services (X.500)" +#define NID_X500 11 +#define OBJ_X500 2L,5L + +#define SN_X509 "X509" +#define NID_X509 12 +#define OBJ_X509 OBJ_X500,4L + +#define SN_commonName "CN" +#define LN_commonName "commonName" +#define NID_commonName 13 +#define OBJ_commonName OBJ_X509,3L + +#define SN_surname "SN" +#define LN_surname "surname" +#define NID_surname 100 +#define OBJ_surname OBJ_X509,4L + +#define LN_serialNumber "serialNumber" +#define NID_serialNumber 105 +#define OBJ_serialNumber OBJ_X509,5L + +#define SN_countryName "C" +#define LN_countryName "countryName" +#define NID_countryName 14 +#define OBJ_countryName OBJ_X509,6L + +#define SN_localityName "L" +#define LN_localityName "localityName" +#define NID_localityName 15 +#define OBJ_localityName OBJ_X509,7L + +#define SN_stateOrProvinceName "ST" +#define LN_stateOrProvinceName "stateOrProvinceName" +#define NID_stateOrProvinceName 16 +#define OBJ_stateOrProvinceName OBJ_X509,8L + +#define SN_streetAddress "street" +#define LN_streetAddress "streetAddress" +#define NID_streetAddress 660 +#define OBJ_streetAddress OBJ_X509,9L + +#define SN_organizationName "O" +#define LN_organizationName "organizationName" +#define NID_organizationName 17 +#define OBJ_organizationName OBJ_X509,10L + +#define SN_organizationalUnitName "OU" +#define LN_organizationalUnitName "organizationalUnitName" +#define NID_organizationalUnitName 18 +#define OBJ_organizationalUnitName OBJ_X509,11L + +#define SN_title "title" +#define LN_title "title" +#define NID_title 106 +#define OBJ_title OBJ_X509,12L + +#define LN_description "description" +#define NID_description 107 +#define OBJ_description OBJ_X509,13L + +#define LN_searchGuide "searchGuide" +#define NID_searchGuide 859 +#define OBJ_searchGuide OBJ_X509,14L + +#define LN_businessCategory "businessCategory" +#define NID_businessCategory 860 +#define OBJ_businessCategory OBJ_X509,15L + +#define LN_postalAddress "postalAddress" +#define NID_postalAddress 861 +#define OBJ_postalAddress OBJ_X509,16L + +#define LN_postalCode "postalCode" +#define NID_postalCode 661 +#define OBJ_postalCode OBJ_X509,17L + +#define LN_postOfficeBox "postOfficeBox" +#define NID_postOfficeBox 862 +#define OBJ_postOfficeBox OBJ_X509,18L + +#define LN_physicalDeliveryOfficeName "physicalDeliveryOfficeName" +#define NID_physicalDeliveryOfficeName 863 +#define OBJ_physicalDeliveryOfficeName OBJ_X509,19L + +#define LN_telephoneNumber "telephoneNumber" +#define NID_telephoneNumber 864 +#define OBJ_telephoneNumber OBJ_X509,20L + +#define LN_telexNumber "telexNumber" +#define NID_telexNumber 865 +#define OBJ_telexNumber OBJ_X509,21L + +#define LN_teletexTerminalIdentifier "teletexTerminalIdentifier" +#define NID_teletexTerminalIdentifier 866 +#define OBJ_teletexTerminalIdentifier OBJ_X509,22L + +#define LN_facsimileTelephoneNumber "facsimileTelephoneNumber" +#define NID_facsimileTelephoneNumber 867 +#define OBJ_facsimileTelephoneNumber OBJ_X509,23L + +#define LN_x121Address "x121Address" +#define NID_x121Address 868 +#define OBJ_x121Address OBJ_X509,24L + +#define LN_internationaliSDNNumber "internationaliSDNNumber" +#define NID_internationaliSDNNumber 869 +#define OBJ_internationaliSDNNumber OBJ_X509,25L + +#define LN_registeredAddress "registeredAddress" +#define NID_registeredAddress 870 +#define OBJ_registeredAddress OBJ_X509,26L + +#define LN_destinationIndicator "destinationIndicator" +#define NID_destinationIndicator 871 +#define OBJ_destinationIndicator OBJ_X509,27L + +#define LN_preferredDeliveryMethod "preferredDeliveryMethod" +#define NID_preferredDeliveryMethod 872 +#define OBJ_preferredDeliveryMethod OBJ_X509,28L + +#define LN_presentationAddress "presentationAddress" +#define NID_presentationAddress 873 +#define OBJ_presentationAddress OBJ_X509,29L + +#define LN_supportedApplicationContext "supportedApplicationContext" +#define NID_supportedApplicationContext 874 +#define OBJ_supportedApplicationContext OBJ_X509,30L + +#define SN_member "member" +#define NID_member 875 +#define OBJ_member OBJ_X509,31L + +#define SN_owner "owner" +#define NID_owner 876 +#define OBJ_owner OBJ_X509,32L + +#define LN_roleOccupant "roleOccupant" +#define NID_roleOccupant 877 +#define OBJ_roleOccupant OBJ_X509,33L + +#define SN_seeAlso "seeAlso" +#define NID_seeAlso 878 +#define OBJ_seeAlso OBJ_X509,34L + +#define LN_userPassword "userPassword" +#define NID_userPassword 879 +#define OBJ_userPassword OBJ_X509,35L + +#define LN_userCertificate "userCertificate" +#define NID_userCertificate 880 +#define OBJ_userCertificate OBJ_X509,36L + +#define LN_cACertificate "cACertificate" +#define NID_cACertificate 881 +#define OBJ_cACertificate OBJ_X509,37L + +#define LN_authorityRevocationList "authorityRevocationList" +#define NID_authorityRevocationList 882 +#define OBJ_authorityRevocationList OBJ_X509,38L + +#define LN_certificateRevocationList "certificateRevocationList" +#define NID_certificateRevocationList 883 +#define OBJ_certificateRevocationList OBJ_X509,39L + +#define LN_crossCertificatePair "crossCertificatePair" +#define NID_crossCertificatePair 884 +#define OBJ_crossCertificatePair OBJ_X509,40L + +#define SN_name "name" +#define LN_name "name" +#define NID_name 173 +#define OBJ_name OBJ_X509,41L + +#define SN_givenName "GN" +#define LN_givenName "givenName" +#define NID_givenName 99 +#define OBJ_givenName OBJ_X509,42L + +#define SN_initials "initials" +#define LN_initials "initials" +#define NID_initials 101 +#define OBJ_initials OBJ_X509,43L + +#define LN_generationQualifier "generationQualifier" +#define NID_generationQualifier 509 +#define OBJ_generationQualifier OBJ_X509,44L + +#define LN_x500UniqueIdentifier "x500UniqueIdentifier" +#define NID_x500UniqueIdentifier 503 +#define OBJ_x500UniqueIdentifier OBJ_X509,45L + +#define SN_dnQualifier "dnQualifier" +#define LN_dnQualifier "dnQualifier" +#define NID_dnQualifier 174 +#define OBJ_dnQualifier OBJ_X509,46L + +#define LN_enhancedSearchGuide "enhancedSearchGuide" +#define NID_enhancedSearchGuide 885 +#define OBJ_enhancedSearchGuide OBJ_X509,47L + +#define LN_protocolInformation "protocolInformation" +#define NID_protocolInformation 886 +#define OBJ_protocolInformation OBJ_X509,48L + +#define LN_distinguishedName "distinguishedName" +#define NID_distinguishedName 887 +#define OBJ_distinguishedName OBJ_X509,49L + +#define LN_uniqueMember "uniqueMember" +#define NID_uniqueMember 888 +#define OBJ_uniqueMember OBJ_X509,50L + +#define LN_houseIdentifier "houseIdentifier" +#define NID_houseIdentifier 889 +#define OBJ_houseIdentifier OBJ_X509,51L + +#define LN_supportedAlgorithms "supportedAlgorithms" +#define NID_supportedAlgorithms 890 +#define OBJ_supportedAlgorithms OBJ_X509,52L + +#define LN_deltaRevocationList "deltaRevocationList" +#define NID_deltaRevocationList 891 +#define OBJ_deltaRevocationList OBJ_X509,53L + +#define SN_dmdName "dmdName" +#define NID_dmdName 892 +#define OBJ_dmdName OBJ_X509,54L + +#define LN_pseudonym "pseudonym" +#define NID_pseudonym 510 +#define OBJ_pseudonym OBJ_X509,65L + +#define SN_role "role" +#define LN_role "role" +#define NID_role 400 +#define OBJ_role OBJ_X509,72L + +#define SN_X500algorithms "X500algorithms" +#define LN_X500algorithms "directory services - algorithms" +#define NID_X500algorithms 378 +#define OBJ_X500algorithms OBJ_X500,8L + +#define SN_rsa "RSA" +#define LN_rsa "rsa" +#define NID_rsa 19 +#define OBJ_rsa OBJ_X500algorithms,1L,1L + +#define SN_mdc2WithRSA "RSA-MDC2" +#define LN_mdc2WithRSA "mdc2WithRSA" +#define NID_mdc2WithRSA 96 +#define OBJ_mdc2WithRSA OBJ_X500algorithms,3L,100L + +#define SN_mdc2 "MDC2" +#define LN_mdc2 "mdc2" +#define NID_mdc2 95 +#define OBJ_mdc2 OBJ_X500algorithms,3L,101L + +#define SN_id_ce "id-ce" +#define NID_id_ce 81 +#define OBJ_id_ce OBJ_X500,29L + +#define SN_subject_directory_attributes "subjectDirectoryAttributes" +#define LN_subject_directory_attributes "X509v3 Subject Directory Attributes" +#define NID_subject_directory_attributes 769 +#define OBJ_subject_directory_attributes OBJ_id_ce,9L + +#define SN_subject_key_identifier "subjectKeyIdentifier" +#define LN_subject_key_identifier "X509v3 Subject Key Identifier" +#define NID_subject_key_identifier 82 +#define OBJ_subject_key_identifier OBJ_id_ce,14L + +#define SN_key_usage "keyUsage" +#define LN_key_usage "X509v3 Key Usage" +#define NID_key_usage 83 +#define OBJ_key_usage OBJ_id_ce,15L + +#define SN_private_key_usage_period "privateKeyUsagePeriod" +#define LN_private_key_usage_period "X509v3 Private Key Usage Period" +#define NID_private_key_usage_period 84 +#define OBJ_private_key_usage_period OBJ_id_ce,16L + +#define SN_subject_alt_name "subjectAltName" +#define LN_subject_alt_name "X509v3 Subject Alternative Name" +#define NID_subject_alt_name 85 +#define OBJ_subject_alt_name OBJ_id_ce,17L + +#define SN_issuer_alt_name "issuerAltName" +#define LN_issuer_alt_name "X509v3 Issuer Alternative Name" +#define NID_issuer_alt_name 86 +#define OBJ_issuer_alt_name OBJ_id_ce,18L + +#define SN_basic_constraints "basicConstraints" +#define LN_basic_constraints "X509v3 Basic Constraints" +#define NID_basic_constraints 87 +#define OBJ_basic_constraints OBJ_id_ce,19L + +#define SN_crl_number "crlNumber" +#define LN_crl_number "X509v3 CRL Number" +#define NID_crl_number 88 +#define OBJ_crl_number OBJ_id_ce,20L + +#define SN_crl_reason "CRLReason" +#define LN_crl_reason "X509v3 CRL Reason Code" +#define NID_crl_reason 141 +#define OBJ_crl_reason OBJ_id_ce,21L + +#define SN_invalidity_date "invalidityDate" +#define LN_invalidity_date "Invalidity Date" +#define NID_invalidity_date 142 +#define OBJ_invalidity_date OBJ_id_ce,24L + +#define SN_delta_crl "deltaCRL" +#define LN_delta_crl "X509v3 Delta CRL Indicator" +#define NID_delta_crl 140 +#define OBJ_delta_crl OBJ_id_ce,27L + +#define SN_issuing_distribution_point "issuingDistributionPoint" +#define LN_issuing_distribution_point "X509v3 Issuing Distrubution Point" +#define NID_issuing_distribution_point 770 +#define OBJ_issuing_distribution_point OBJ_id_ce,28L + +#define SN_certificate_issuer "certificateIssuer" +#define LN_certificate_issuer "X509v3 Certificate Issuer" +#define NID_certificate_issuer 771 +#define OBJ_certificate_issuer OBJ_id_ce,29L + +#define SN_name_constraints "nameConstraints" +#define LN_name_constraints "X509v3 Name Constraints" +#define NID_name_constraints 666 +#define OBJ_name_constraints OBJ_id_ce,30L + +#define SN_crl_distribution_points "crlDistributionPoints" +#define LN_crl_distribution_points "X509v3 CRL Distribution Points" +#define NID_crl_distribution_points 103 +#define OBJ_crl_distribution_points OBJ_id_ce,31L + +#define SN_certificate_policies "certificatePolicies" +#define LN_certificate_policies "X509v3 Certificate Policies" +#define NID_certificate_policies 89 +#define OBJ_certificate_policies OBJ_id_ce,32L + +#define SN_any_policy "anyPolicy" +#define LN_any_policy "X509v3 Any Policy" +#define NID_any_policy 746 +#define OBJ_any_policy OBJ_certificate_policies,0L + +#define SN_policy_mappings "policyMappings" +#define LN_policy_mappings "X509v3 Policy Mappings" +#define NID_policy_mappings 747 +#define OBJ_policy_mappings OBJ_id_ce,33L + +#define SN_authority_key_identifier "authorityKeyIdentifier" +#define LN_authority_key_identifier "X509v3 Authority Key Identifier" +#define NID_authority_key_identifier 90 +#define OBJ_authority_key_identifier OBJ_id_ce,35L + +#define SN_policy_constraints "policyConstraints" +#define LN_policy_constraints "X509v3 Policy Constraints" +#define NID_policy_constraints 401 +#define OBJ_policy_constraints OBJ_id_ce,36L + +#define SN_ext_key_usage "extendedKeyUsage" +#define LN_ext_key_usage "X509v3 Extended Key Usage" +#define NID_ext_key_usage 126 +#define OBJ_ext_key_usage OBJ_id_ce,37L + +#define SN_freshest_crl "freshestCRL" +#define LN_freshest_crl "X509v3 Freshest CRL" +#define NID_freshest_crl 857 +#define OBJ_freshest_crl OBJ_id_ce,46L + +#define SN_inhibit_any_policy "inhibitAnyPolicy" +#define LN_inhibit_any_policy "X509v3 Inhibit Any Policy" +#define NID_inhibit_any_policy 748 +#define OBJ_inhibit_any_policy OBJ_id_ce,54L + +#define SN_target_information "targetInformation" +#define LN_target_information "X509v3 AC Targeting" +#define NID_target_information 402 +#define OBJ_target_information OBJ_id_ce,55L + +#define SN_no_rev_avail "noRevAvail" +#define LN_no_rev_avail "X509v3 No Revocation Available" +#define NID_no_rev_avail 403 +#define OBJ_no_rev_avail OBJ_id_ce,56L + +#define SN_anyExtendedKeyUsage "anyExtendedKeyUsage" +#define LN_anyExtendedKeyUsage "Any Extended Key Usage" +#define NID_anyExtendedKeyUsage 910 +#define OBJ_anyExtendedKeyUsage OBJ_ext_key_usage,0L + +#define SN_netscape "Netscape" +#define LN_netscape "Netscape Communications Corp." +#define NID_netscape 57 +#define OBJ_netscape 2L,16L,840L,1L,113730L + +#define SN_netscape_cert_extension "nsCertExt" +#define LN_netscape_cert_extension "Netscape Certificate Extension" +#define NID_netscape_cert_extension 58 +#define OBJ_netscape_cert_extension OBJ_netscape,1L + +#define SN_netscape_data_type "nsDataType" +#define LN_netscape_data_type "Netscape Data Type" +#define NID_netscape_data_type 59 +#define OBJ_netscape_data_type OBJ_netscape,2L + +#define SN_netscape_cert_type "nsCertType" +#define LN_netscape_cert_type "Netscape Cert Type" +#define NID_netscape_cert_type 71 +#define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L + +#define SN_netscape_base_url "nsBaseUrl" +#define LN_netscape_base_url "Netscape Base Url" +#define NID_netscape_base_url 72 +#define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L + +#define SN_netscape_revocation_url "nsRevocationUrl" +#define LN_netscape_revocation_url "Netscape Revocation Url" +#define NID_netscape_revocation_url 73 +#define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L + +#define SN_netscape_ca_revocation_url "nsCaRevocationUrl" +#define LN_netscape_ca_revocation_url "Netscape CA Revocation Url" +#define NID_netscape_ca_revocation_url 74 +#define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L + +#define SN_netscape_renewal_url "nsRenewalUrl" +#define LN_netscape_renewal_url "Netscape Renewal Url" +#define NID_netscape_renewal_url 75 +#define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L + +#define SN_netscape_ca_policy_url "nsCaPolicyUrl" +#define LN_netscape_ca_policy_url "Netscape CA Policy Url" +#define NID_netscape_ca_policy_url 76 +#define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L + +#define SN_netscape_ssl_server_name "nsSslServerName" +#define LN_netscape_ssl_server_name "Netscape SSL Server Name" +#define NID_netscape_ssl_server_name 77 +#define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L + +#define SN_netscape_comment "nsComment" +#define LN_netscape_comment "Netscape Comment" +#define NID_netscape_comment 78 +#define OBJ_netscape_comment OBJ_netscape_cert_extension,13L + +#define SN_netscape_cert_sequence "nsCertSequence" +#define LN_netscape_cert_sequence "Netscape Certificate Sequence" +#define NID_netscape_cert_sequence 79 +#define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L + +#define SN_ns_sgc "nsSGC" +#define LN_ns_sgc "Netscape Server Gated Crypto" +#define NID_ns_sgc 139 +#define OBJ_ns_sgc OBJ_netscape,4L,1L + +#define SN_org "ORG" +#define LN_org "org" +#define NID_org 379 +#define OBJ_org OBJ_iso,3L + +#define SN_dod "DOD" +#define LN_dod "dod" +#define NID_dod 380 +#define OBJ_dod OBJ_org,6L + +#define SN_iana "IANA" +#define LN_iana "iana" +#define NID_iana 381 +#define OBJ_iana OBJ_dod,1L + +#define OBJ_internet OBJ_iana + +#define SN_Directory "directory" +#define LN_Directory "Directory" +#define NID_Directory 382 +#define OBJ_Directory OBJ_internet,1L + +#define SN_Management "mgmt" +#define LN_Management "Management" +#define NID_Management 383 +#define OBJ_Management OBJ_internet,2L + +#define SN_Experimental "experimental" +#define LN_Experimental "Experimental" +#define NID_Experimental 384 +#define OBJ_Experimental OBJ_internet,3L + +#define SN_Private "private" +#define LN_Private "Private" +#define NID_Private 385 +#define OBJ_Private OBJ_internet,4L + +#define SN_Security "security" +#define LN_Security "Security" +#define NID_Security 386 +#define OBJ_Security OBJ_internet,5L + +#define SN_SNMPv2 "snmpv2" +#define LN_SNMPv2 "SNMPv2" +#define NID_SNMPv2 387 +#define OBJ_SNMPv2 OBJ_internet,6L + +#define LN_Mail "Mail" +#define NID_Mail 388 +#define OBJ_Mail OBJ_internet,7L + +#define SN_Enterprises "enterprises" +#define LN_Enterprises "Enterprises" +#define NID_Enterprises 389 +#define OBJ_Enterprises OBJ_Private,1L + +#define SN_dcObject "dcobject" +#define LN_dcObject "dcObject" +#define NID_dcObject 390 +#define OBJ_dcObject OBJ_Enterprises,1466L,344L + +#define SN_mime_mhs "mime-mhs" +#define LN_mime_mhs "MIME MHS" +#define NID_mime_mhs 504 +#define OBJ_mime_mhs OBJ_Mail,1L + +#define SN_mime_mhs_headings "mime-mhs-headings" +#define LN_mime_mhs_headings "mime-mhs-headings" +#define NID_mime_mhs_headings 505 +#define OBJ_mime_mhs_headings OBJ_mime_mhs,1L + +#define SN_mime_mhs_bodies "mime-mhs-bodies" +#define LN_mime_mhs_bodies "mime-mhs-bodies" +#define NID_mime_mhs_bodies 506 +#define OBJ_mime_mhs_bodies OBJ_mime_mhs,2L + +#define SN_id_hex_partial_message "id-hex-partial-message" +#define LN_id_hex_partial_message "id-hex-partial-message" +#define NID_id_hex_partial_message 507 +#define OBJ_id_hex_partial_message OBJ_mime_mhs_headings,1L + +#define SN_id_hex_multipart_message "id-hex-multipart-message" +#define LN_id_hex_multipart_message "id-hex-multipart-message" +#define NID_id_hex_multipart_message 508 +#define OBJ_id_hex_multipart_message OBJ_mime_mhs_headings,2L + +#define SN_rle_compression "RLE" +#define LN_rle_compression "run length compression" +#define NID_rle_compression 124 +#define OBJ_rle_compression 1L,1L,1L,1L,666L,1L + +#define SN_zlib_compression "ZLIB" +#define LN_zlib_compression "zlib compression" +#define NID_zlib_compression 125 +#define OBJ_zlib_compression OBJ_id_smime_alg,8L + +#define OBJ_csor 2L,16L,840L,1L,101L,3L + +#define OBJ_nistAlgorithms OBJ_csor,4L + +#define OBJ_aes OBJ_nistAlgorithms,1L + +#define SN_aes_128_ecb "AES-128-ECB" +#define LN_aes_128_ecb "aes-128-ecb" +#define NID_aes_128_ecb 418 +#define OBJ_aes_128_ecb OBJ_aes,1L + +#define SN_aes_128_cbc "AES-128-CBC" +#define LN_aes_128_cbc "aes-128-cbc" +#define NID_aes_128_cbc 419 +#define OBJ_aes_128_cbc OBJ_aes,2L + +#define SN_aes_128_ofb128 "AES-128-OFB" +#define LN_aes_128_ofb128 "aes-128-ofb" +#define NID_aes_128_ofb128 420 +#define OBJ_aes_128_ofb128 OBJ_aes,3L + +#define SN_aes_128_cfb128 "AES-128-CFB" +#define LN_aes_128_cfb128 "aes-128-cfb" +#define NID_aes_128_cfb128 421 +#define OBJ_aes_128_cfb128 OBJ_aes,4L + +#define SN_id_aes128_wrap "id-aes128-wrap" +#define NID_id_aes128_wrap 788 +#define OBJ_id_aes128_wrap OBJ_aes,5L + +#define SN_aes_128_gcm "id-aes128-GCM" +#define LN_aes_128_gcm "aes-128-gcm" +#define NID_aes_128_gcm 895 +#define OBJ_aes_128_gcm OBJ_aes,6L + +#define SN_aes_128_ccm "id-aes128-CCM" +#define LN_aes_128_ccm "aes-128-ccm" +#define NID_aes_128_ccm 896 +#define OBJ_aes_128_ccm OBJ_aes,7L + +#define SN_id_aes128_wrap_pad "id-aes128-wrap-pad" +#define NID_id_aes128_wrap_pad 897 +#define OBJ_id_aes128_wrap_pad OBJ_aes,8L + +#define SN_aes_192_ecb "AES-192-ECB" +#define LN_aes_192_ecb "aes-192-ecb" +#define NID_aes_192_ecb 422 +#define OBJ_aes_192_ecb OBJ_aes,21L + +#define SN_aes_192_cbc "AES-192-CBC" +#define LN_aes_192_cbc "aes-192-cbc" +#define NID_aes_192_cbc 423 +#define OBJ_aes_192_cbc OBJ_aes,22L + +#define SN_aes_192_ofb128 "AES-192-OFB" +#define LN_aes_192_ofb128 "aes-192-ofb" +#define NID_aes_192_ofb128 424 +#define OBJ_aes_192_ofb128 OBJ_aes,23L + +#define SN_aes_192_cfb128 "AES-192-CFB" +#define LN_aes_192_cfb128 "aes-192-cfb" +#define NID_aes_192_cfb128 425 +#define OBJ_aes_192_cfb128 OBJ_aes,24L + +#define SN_id_aes192_wrap "id-aes192-wrap" +#define NID_id_aes192_wrap 789 +#define OBJ_id_aes192_wrap OBJ_aes,25L + +#define SN_aes_192_gcm "id-aes192-GCM" +#define LN_aes_192_gcm "aes-192-gcm" +#define NID_aes_192_gcm 898 +#define OBJ_aes_192_gcm OBJ_aes,26L + +#define SN_aes_192_ccm "id-aes192-CCM" +#define LN_aes_192_ccm "aes-192-ccm" +#define NID_aes_192_ccm 899 +#define OBJ_aes_192_ccm OBJ_aes,27L + +#define SN_id_aes192_wrap_pad "id-aes192-wrap-pad" +#define NID_id_aes192_wrap_pad 900 +#define OBJ_id_aes192_wrap_pad OBJ_aes,28L + +#define SN_aes_256_ecb "AES-256-ECB" +#define LN_aes_256_ecb "aes-256-ecb" +#define NID_aes_256_ecb 426 +#define OBJ_aes_256_ecb OBJ_aes,41L + +#define SN_aes_256_cbc "AES-256-CBC" +#define LN_aes_256_cbc "aes-256-cbc" +#define NID_aes_256_cbc 427 +#define OBJ_aes_256_cbc OBJ_aes,42L + +#define SN_aes_256_ofb128 "AES-256-OFB" +#define LN_aes_256_ofb128 "aes-256-ofb" +#define NID_aes_256_ofb128 428 +#define OBJ_aes_256_ofb128 OBJ_aes,43L + +#define SN_aes_256_cfb128 "AES-256-CFB" +#define LN_aes_256_cfb128 "aes-256-cfb" +#define NID_aes_256_cfb128 429 +#define OBJ_aes_256_cfb128 OBJ_aes,44L + +#define SN_id_aes256_wrap "id-aes256-wrap" +#define NID_id_aes256_wrap 790 +#define OBJ_id_aes256_wrap OBJ_aes,45L + +#define SN_aes_256_gcm "id-aes256-GCM" +#define LN_aes_256_gcm "aes-256-gcm" +#define NID_aes_256_gcm 901 +#define OBJ_aes_256_gcm OBJ_aes,46L + +#define SN_aes_256_ccm "id-aes256-CCM" +#define LN_aes_256_ccm "aes-256-ccm" +#define NID_aes_256_ccm 902 +#define OBJ_aes_256_ccm OBJ_aes,47L + +#define SN_id_aes256_wrap_pad "id-aes256-wrap-pad" +#define NID_id_aes256_wrap_pad 903 +#define OBJ_id_aes256_wrap_pad OBJ_aes,48L + +#define SN_aes_128_cfb1 "AES-128-CFB1" +#define LN_aes_128_cfb1 "aes-128-cfb1" +#define NID_aes_128_cfb1 650 + +#define SN_aes_192_cfb1 "AES-192-CFB1" +#define LN_aes_192_cfb1 "aes-192-cfb1" +#define NID_aes_192_cfb1 651 + +#define SN_aes_256_cfb1 "AES-256-CFB1" +#define LN_aes_256_cfb1 "aes-256-cfb1" +#define NID_aes_256_cfb1 652 + +#define SN_aes_128_cfb8 "AES-128-CFB8" +#define LN_aes_128_cfb8 "aes-128-cfb8" +#define NID_aes_128_cfb8 653 + +#define SN_aes_192_cfb8 "AES-192-CFB8" +#define LN_aes_192_cfb8 "aes-192-cfb8" +#define NID_aes_192_cfb8 654 + +#define SN_aes_256_cfb8 "AES-256-CFB8" +#define LN_aes_256_cfb8 "aes-256-cfb8" +#define NID_aes_256_cfb8 655 + +#define SN_aes_128_ctr "AES-128-CTR" +#define LN_aes_128_ctr "aes-128-ctr" +#define NID_aes_128_ctr 904 + +#define SN_aes_192_ctr "AES-192-CTR" +#define LN_aes_192_ctr "aes-192-ctr" +#define NID_aes_192_ctr 905 + +#define SN_aes_256_ctr "AES-256-CTR" +#define LN_aes_256_ctr "aes-256-ctr" +#define NID_aes_256_ctr 906 + +#define SN_aes_128_xts "AES-128-XTS" +#define LN_aes_128_xts "aes-128-xts" +#define NID_aes_128_xts 913 + +#define SN_aes_256_xts "AES-256-XTS" +#define LN_aes_256_xts "aes-256-xts" +#define NID_aes_256_xts 914 + +#define SN_des_cfb1 "DES-CFB1" +#define LN_des_cfb1 "des-cfb1" +#define NID_des_cfb1 656 + +#define SN_des_cfb8 "DES-CFB8" +#define LN_des_cfb8 "des-cfb8" +#define NID_des_cfb8 657 + +#define SN_des_ede3_cfb1 "DES-EDE3-CFB1" +#define LN_des_ede3_cfb1 "des-ede3-cfb1" +#define NID_des_ede3_cfb1 658 + +#define SN_des_ede3_cfb8 "DES-EDE3-CFB8" +#define LN_des_ede3_cfb8 "des-ede3-cfb8" +#define NID_des_ede3_cfb8 659 + +#define OBJ_nist_hashalgs OBJ_nistAlgorithms,2L + +#define SN_sha256 "SHA256" +#define LN_sha256 "sha256" +#define NID_sha256 672 +#define OBJ_sha256 OBJ_nist_hashalgs,1L + +#define SN_sha384 "SHA384" +#define LN_sha384 "sha384" +#define NID_sha384 673 +#define OBJ_sha384 OBJ_nist_hashalgs,2L + +#define SN_sha512 "SHA512" +#define LN_sha512 "sha512" +#define NID_sha512 674 +#define OBJ_sha512 OBJ_nist_hashalgs,3L + +#define SN_sha224 "SHA224" +#define LN_sha224 "sha224" +#define NID_sha224 675 +#define OBJ_sha224 OBJ_nist_hashalgs,4L + +#define OBJ_dsa_with_sha2 OBJ_nistAlgorithms,3L + +#define SN_dsa_with_SHA224 "dsa_with_SHA224" +#define NID_dsa_with_SHA224 802 +#define OBJ_dsa_with_SHA224 OBJ_dsa_with_sha2,1L + +#define SN_dsa_with_SHA256 "dsa_with_SHA256" +#define NID_dsa_with_SHA256 803 +#define OBJ_dsa_with_SHA256 OBJ_dsa_with_sha2,2L + +#define SN_hold_instruction_code "holdInstructionCode" +#define LN_hold_instruction_code "Hold Instruction Code" +#define NID_hold_instruction_code 430 +#define OBJ_hold_instruction_code OBJ_id_ce,23L + +#define OBJ_holdInstruction OBJ_X9_57,2L + +#define SN_hold_instruction_none "holdInstructionNone" +#define LN_hold_instruction_none "Hold Instruction None" +#define NID_hold_instruction_none 431 +#define OBJ_hold_instruction_none OBJ_holdInstruction,1L + +#define SN_hold_instruction_call_issuer "holdInstructionCallIssuer" +#define LN_hold_instruction_call_issuer "Hold Instruction Call Issuer" +#define NID_hold_instruction_call_issuer 432 +#define OBJ_hold_instruction_call_issuer OBJ_holdInstruction,2L + +#define SN_hold_instruction_reject "holdInstructionReject" +#define LN_hold_instruction_reject "Hold Instruction Reject" +#define NID_hold_instruction_reject 433 +#define OBJ_hold_instruction_reject OBJ_holdInstruction,3L + +#define SN_data "data" +#define NID_data 434 +#define OBJ_data OBJ_itu_t,9L + +#define SN_pss "pss" +#define NID_pss 435 +#define OBJ_pss OBJ_data,2342L + +#define SN_ucl "ucl" +#define NID_ucl 436 +#define OBJ_ucl OBJ_pss,19200300L + +#define SN_pilot "pilot" +#define NID_pilot 437 +#define OBJ_pilot OBJ_ucl,100L + +#define LN_pilotAttributeType "pilotAttributeType" +#define NID_pilotAttributeType 438 +#define OBJ_pilotAttributeType OBJ_pilot,1L + +#define LN_pilotAttributeSyntax "pilotAttributeSyntax" +#define NID_pilotAttributeSyntax 439 +#define OBJ_pilotAttributeSyntax OBJ_pilot,3L + +#define LN_pilotObjectClass "pilotObjectClass" +#define NID_pilotObjectClass 440 +#define OBJ_pilotObjectClass OBJ_pilot,4L + +#define LN_pilotGroups "pilotGroups" +#define NID_pilotGroups 441 +#define OBJ_pilotGroups OBJ_pilot,10L + +#define LN_iA5StringSyntax "iA5StringSyntax" +#define NID_iA5StringSyntax 442 +#define OBJ_iA5StringSyntax OBJ_pilotAttributeSyntax,4L + +#define LN_caseIgnoreIA5StringSyntax "caseIgnoreIA5StringSyntax" +#define NID_caseIgnoreIA5StringSyntax 443 +#define OBJ_caseIgnoreIA5StringSyntax OBJ_pilotAttributeSyntax,5L + +#define LN_pilotObject "pilotObject" +#define NID_pilotObject 444 +#define OBJ_pilotObject OBJ_pilotObjectClass,3L + +#define LN_pilotPerson "pilotPerson" +#define NID_pilotPerson 445 +#define OBJ_pilotPerson OBJ_pilotObjectClass,4L + +#define SN_account "account" +#define NID_account 446 +#define OBJ_account OBJ_pilotObjectClass,5L + +#define SN_document "document" +#define NID_document 447 +#define OBJ_document OBJ_pilotObjectClass,6L + +#define SN_room "room" +#define NID_room 448 +#define OBJ_room OBJ_pilotObjectClass,7L + +#define LN_documentSeries "documentSeries" +#define NID_documentSeries 449 +#define OBJ_documentSeries OBJ_pilotObjectClass,9L + +#define SN_Domain "domain" +#define LN_Domain "Domain" +#define NID_Domain 392 +#define OBJ_Domain OBJ_pilotObjectClass,13L + +#define LN_rFC822localPart "rFC822localPart" +#define NID_rFC822localPart 450 +#define OBJ_rFC822localPart OBJ_pilotObjectClass,14L + +#define LN_dNSDomain "dNSDomain" +#define NID_dNSDomain 451 +#define OBJ_dNSDomain OBJ_pilotObjectClass,15L + +#define LN_domainRelatedObject "domainRelatedObject" +#define NID_domainRelatedObject 452 +#define OBJ_domainRelatedObject OBJ_pilotObjectClass,17L + +#define LN_friendlyCountry "friendlyCountry" +#define NID_friendlyCountry 453 +#define OBJ_friendlyCountry OBJ_pilotObjectClass,18L + +#define LN_simpleSecurityObject "simpleSecurityObject" +#define NID_simpleSecurityObject 454 +#define OBJ_simpleSecurityObject OBJ_pilotObjectClass,19L + +#define LN_pilotOrganization "pilotOrganization" +#define NID_pilotOrganization 455 +#define OBJ_pilotOrganization OBJ_pilotObjectClass,20L + +#define LN_pilotDSA "pilotDSA" +#define NID_pilotDSA 456 +#define OBJ_pilotDSA OBJ_pilotObjectClass,21L + +#define LN_qualityLabelledData "qualityLabelledData" +#define NID_qualityLabelledData 457 +#define OBJ_qualityLabelledData OBJ_pilotObjectClass,22L + +#define SN_userId "UID" +#define LN_userId "userId" +#define NID_userId 458 +#define OBJ_userId OBJ_pilotAttributeType,1L + +#define LN_textEncodedORAddress "textEncodedORAddress" +#define NID_textEncodedORAddress 459 +#define OBJ_textEncodedORAddress OBJ_pilotAttributeType,2L + +#define SN_rfc822Mailbox "mail" +#define LN_rfc822Mailbox "rfc822Mailbox" +#define NID_rfc822Mailbox 460 +#define OBJ_rfc822Mailbox OBJ_pilotAttributeType,3L + +#define SN_info "info" +#define NID_info 461 +#define OBJ_info OBJ_pilotAttributeType,4L + +#define LN_favouriteDrink "favouriteDrink" +#define NID_favouriteDrink 462 +#define OBJ_favouriteDrink OBJ_pilotAttributeType,5L + +#define LN_roomNumber "roomNumber" +#define NID_roomNumber 463 +#define OBJ_roomNumber OBJ_pilotAttributeType,6L + +#define SN_photo "photo" +#define NID_photo 464 +#define OBJ_photo OBJ_pilotAttributeType,7L + +#define LN_userClass "userClass" +#define NID_userClass 465 +#define OBJ_userClass OBJ_pilotAttributeType,8L + +#define SN_host "host" +#define NID_host 466 +#define OBJ_host OBJ_pilotAttributeType,9L + +#define SN_manager "manager" +#define NID_manager 467 +#define OBJ_manager OBJ_pilotAttributeType,10L + +#define LN_documentIdentifier "documentIdentifier" +#define NID_documentIdentifier 468 +#define OBJ_documentIdentifier OBJ_pilotAttributeType,11L + +#define LN_documentTitle "documentTitle" +#define NID_documentTitle 469 +#define OBJ_documentTitle OBJ_pilotAttributeType,12L + +#define LN_documentVersion "documentVersion" +#define NID_documentVersion 470 +#define OBJ_documentVersion OBJ_pilotAttributeType,13L + +#define LN_documentAuthor "documentAuthor" +#define NID_documentAuthor 471 +#define OBJ_documentAuthor OBJ_pilotAttributeType,14L + +#define LN_documentLocation "documentLocation" +#define NID_documentLocation 472 +#define OBJ_documentLocation OBJ_pilotAttributeType,15L + +#define LN_homeTelephoneNumber "homeTelephoneNumber" +#define NID_homeTelephoneNumber 473 +#define OBJ_homeTelephoneNumber OBJ_pilotAttributeType,20L + +#define SN_secretary "secretary" +#define NID_secretary 474 +#define OBJ_secretary OBJ_pilotAttributeType,21L + +#define LN_otherMailbox "otherMailbox" +#define NID_otherMailbox 475 +#define OBJ_otherMailbox OBJ_pilotAttributeType,22L + +#define LN_lastModifiedTime "lastModifiedTime" +#define NID_lastModifiedTime 476 +#define OBJ_lastModifiedTime OBJ_pilotAttributeType,23L + +#define LN_lastModifiedBy "lastModifiedBy" +#define NID_lastModifiedBy 477 +#define OBJ_lastModifiedBy OBJ_pilotAttributeType,24L + +#define SN_domainComponent "DC" +#define LN_domainComponent "domainComponent" +#define NID_domainComponent 391 +#define OBJ_domainComponent OBJ_pilotAttributeType,25L + +#define LN_aRecord "aRecord" +#define NID_aRecord 478 +#define OBJ_aRecord OBJ_pilotAttributeType,26L + +#define LN_pilotAttributeType27 "pilotAttributeType27" +#define NID_pilotAttributeType27 479 +#define OBJ_pilotAttributeType27 OBJ_pilotAttributeType,27L + +#define LN_mXRecord "mXRecord" +#define NID_mXRecord 480 +#define OBJ_mXRecord OBJ_pilotAttributeType,28L + +#define LN_nSRecord "nSRecord" +#define NID_nSRecord 481 +#define OBJ_nSRecord OBJ_pilotAttributeType,29L + +#define LN_sOARecord "sOARecord" +#define NID_sOARecord 482 +#define OBJ_sOARecord OBJ_pilotAttributeType,30L + +#define LN_cNAMERecord "cNAMERecord" +#define NID_cNAMERecord 483 +#define OBJ_cNAMERecord OBJ_pilotAttributeType,31L + +#define LN_associatedDomain "associatedDomain" +#define NID_associatedDomain 484 +#define OBJ_associatedDomain OBJ_pilotAttributeType,37L + +#define LN_associatedName "associatedName" +#define NID_associatedName 485 +#define OBJ_associatedName OBJ_pilotAttributeType,38L + +#define LN_homePostalAddress "homePostalAddress" +#define NID_homePostalAddress 486 +#define OBJ_homePostalAddress OBJ_pilotAttributeType,39L + +#define LN_personalTitle "personalTitle" +#define NID_personalTitle 487 +#define OBJ_personalTitle OBJ_pilotAttributeType,40L + +#define LN_mobileTelephoneNumber "mobileTelephoneNumber" +#define NID_mobileTelephoneNumber 488 +#define OBJ_mobileTelephoneNumber OBJ_pilotAttributeType,41L + +#define LN_pagerTelephoneNumber "pagerTelephoneNumber" +#define NID_pagerTelephoneNumber 489 +#define OBJ_pagerTelephoneNumber OBJ_pilotAttributeType,42L + +#define LN_friendlyCountryName "friendlyCountryName" +#define NID_friendlyCountryName 490 +#define OBJ_friendlyCountryName OBJ_pilotAttributeType,43L + +#define LN_organizationalStatus "organizationalStatus" +#define NID_organizationalStatus 491 +#define OBJ_organizationalStatus OBJ_pilotAttributeType,45L + +#define LN_janetMailbox "janetMailbox" +#define NID_janetMailbox 492 +#define OBJ_janetMailbox OBJ_pilotAttributeType,46L + +#define LN_mailPreferenceOption "mailPreferenceOption" +#define NID_mailPreferenceOption 493 +#define OBJ_mailPreferenceOption OBJ_pilotAttributeType,47L + +#define LN_buildingName "buildingName" +#define NID_buildingName 494 +#define OBJ_buildingName OBJ_pilotAttributeType,48L + +#define LN_dSAQuality "dSAQuality" +#define NID_dSAQuality 495 +#define OBJ_dSAQuality OBJ_pilotAttributeType,49L + +#define LN_singleLevelQuality "singleLevelQuality" +#define NID_singleLevelQuality 496 +#define OBJ_singleLevelQuality OBJ_pilotAttributeType,50L + +#define LN_subtreeMinimumQuality "subtreeMinimumQuality" +#define NID_subtreeMinimumQuality 497 +#define OBJ_subtreeMinimumQuality OBJ_pilotAttributeType,51L + +#define LN_subtreeMaximumQuality "subtreeMaximumQuality" +#define NID_subtreeMaximumQuality 498 +#define OBJ_subtreeMaximumQuality OBJ_pilotAttributeType,52L + +#define LN_personalSignature "personalSignature" +#define NID_personalSignature 499 +#define OBJ_personalSignature OBJ_pilotAttributeType,53L + +#define LN_dITRedirect "dITRedirect" +#define NID_dITRedirect 500 +#define OBJ_dITRedirect OBJ_pilotAttributeType,54L + +#define SN_audio "audio" +#define NID_audio 501 +#define OBJ_audio OBJ_pilotAttributeType,55L + +#define LN_documentPublisher "documentPublisher" +#define NID_documentPublisher 502 +#define OBJ_documentPublisher OBJ_pilotAttributeType,56L + +#define SN_id_set "id-set" +#define LN_id_set "Secure Electronic Transactions" +#define NID_id_set 512 +#define OBJ_id_set OBJ_international_organizations,42L + +#define SN_set_ctype "set-ctype" +#define LN_set_ctype "content types" +#define NID_set_ctype 513 +#define OBJ_set_ctype OBJ_id_set,0L + +#define SN_set_msgExt "set-msgExt" +#define LN_set_msgExt "message extensions" +#define NID_set_msgExt 514 +#define OBJ_set_msgExt OBJ_id_set,1L + +#define SN_set_attr "set-attr" +#define NID_set_attr 515 +#define OBJ_set_attr OBJ_id_set,3L + +#define SN_set_policy "set-policy" +#define NID_set_policy 516 +#define OBJ_set_policy OBJ_id_set,5L + +#define SN_set_certExt "set-certExt" +#define LN_set_certExt "certificate extensions" +#define NID_set_certExt 517 +#define OBJ_set_certExt OBJ_id_set,7L + +#define SN_set_brand "set-brand" +#define NID_set_brand 518 +#define OBJ_set_brand OBJ_id_set,8L + +#define SN_setct_PANData "setct-PANData" +#define NID_setct_PANData 519 +#define OBJ_setct_PANData OBJ_set_ctype,0L + +#define SN_setct_PANToken "setct-PANToken" +#define NID_setct_PANToken 520 +#define OBJ_setct_PANToken OBJ_set_ctype,1L + +#define SN_setct_PANOnly "setct-PANOnly" +#define NID_setct_PANOnly 521 +#define OBJ_setct_PANOnly OBJ_set_ctype,2L + +#define SN_setct_OIData "setct-OIData" +#define NID_setct_OIData 522 +#define OBJ_setct_OIData OBJ_set_ctype,3L + +#define SN_setct_PI "setct-PI" +#define NID_setct_PI 523 +#define OBJ_setct_PI OBJ_set_ctype,4L + +#define SN_setct_PIData "setct-PIData" +#define NID_setct_PIData 524 +#define OBJ_setct_PIData OBJ_set_ctype,5L + +#define SN_setct_PIDataUnsigned "setct-PIDataUnsigned" +#define NID_setct_PIDataUnsigned 525 +#define OBJ_setct_PIDataUnsigned OBJ_set_ctype,6L + +#define SN_setct_HODInput "setct-HODInput" +#define NID_setct_HODInput 526 +#define OBJ_setct_HODInput OBJ_set_ctype,7L + +#define SN_setct_AuthResBaggage "setct-AuthResBaggage" +#define NID_setct_AuthResBaggage 527 +#define OBJ_setct_AuthResBaggage OBJ_set_ctype,8L + +#define SN_setct_AuthRevReqBaggage "setct-AuthRevReqBaggage" +#define NID_setct_AuthRevReqBaggage 528 +#define OBJ_setct_AuthRevReqBaggage OBJ_set_ctype,9L + +#define SN_setct_AuthRevResBaggage "setct-AuthRevResBaggage" +#define NID_setct_AuthRevResBaggage 529 +#define OBJ_setct_AuthRevResBaggage OBJ_set_ctype,10L + +#define SN_setct_CapTokenSeq "setct-CapTokenSeq" +#define NID_setct_CapTokenSeq 530 +#define OBJ_setct_CapTokenSeq OBJ_set_ctype,11L + +#define SN_setct_PInitResData "setct-PInitResData" +#define NID_setct_PInitResData 531 +#define OBJ_setct_PInitResData OBJ_set_ctype,12L + +#define SN_setct_PI_TBS "setct-PI-TBS" +#define NID_setct_PI_TBS 532 +#define OBJ_setct_PI_TBS OBJ_set_ctype,13L + +#define SN_setct_PResData "setct-PResData" +#define NID_setct_PResData 533 +#define OBJ_setct_PResData OBJ_set_ctype,14L + +#define SN_setct_AuthReqTBS "setct-AuthReqTBS" +#define NID_setct_AuthReqTBS 534 +#define OBJ_setct_AuthReqTBS OBJ_set_ctype,16L + +#define SN_setct_AuthResTBS "setct-AuthResTBS" +#define NID_setct_AuthResTBS 535 +#define OBJ_setct_AuthResTBS OBJ_set_ctype,17L + +#define SN_setct_AuthResTBSX "setct-AuthResTBSX" +#define NID_setct_AuthResTBSX 536 +#define OBJ_setct_AuthResTBSX OBJ_set_ctype,18L + +#define SN_setct_AuthTokenTBS "setct-AuthTokenTBS" +#define NID_setct_AuthTokenTBS 537 +#define OBJ_setct_AuthTokenTBS OBJ_set_ctype,19L + +#define SN_setct_CapTokenData "setct-CapTokenData" +#define NID_setct_CapTokenData 538 +#define OBJ_setct_CapTokenData OBJ_set_ctype,20L + +#define SN_setct_CapTokenTBS "setct-CapTokenTBS" +#define NID_setct_CapTokenTBS 539 +#define OBJ_setct_CapTokenTBS OBJ_set_ctype,21L + +#define SN_setct_AcqCardCodeMsg "setct-AcqCardCodeMsg" +#define NID_setct_AcqCardCodeMsg 540 +#define OBJ_setct_AcqCardCodeMsg OBJ_set_ctype,22L + +#define SN_setct_AuthRevReqTBS "setct-AuthRevReqTBS" +#define NID_setct_AuthRevReqTBS 541 +#define OBJ_setct_AuthRevReqTBS OBJ_set_ctype,23L + +#define SN_setct_AuthRevResData "setct-AuthRevResData" +#define NID_setct_AuthRevResData 542 +#define OBJ_setct_AuthRevResData OBJ_set_ctype,24L + +#define SN_setct_AuthRevResTBS "setct-AuthRevResTBS" +#define NID_setct_AuthRevResTBS 543 +#define OBJ_setct_AuthRevResTBS OBJ_set_ctype,25L + +#define SN_setct_CapReqTBS "setct-CapReqTBS" +#define NID_setct_CapReqTBS 544 +#define OBJ_setct_CapReqTBS OBJ_set_ctype,26L + +#define SN_setct_CapReqTBSX "setct-CapReqTBSX" +#define NID_setct_CapReqTBSX 545 +#define OBJ_setct_CapReqTBSX OBJ_set_ctype,27L + +#define SN_setct_CapResData "setct-CapResData" +#define NID_setct_CapResData 546 +#define OBJ_setct_CapResData OBJ_set_ctype,28L + +#define SN_setct_CapRevReqTBS "setct-CapRevReqTBS" +#define NID_setct_CapRevReqTBS 547 +#define OBJ_setct_CapRevReqTBS OBJ_set_ctype,29L + +#define SN_setct_CapRevReqTBSX "setct-CapRevReqTBSX" +#define NID_setct_CapRevReqTBSX 548 +#define OBJ_setct_CapRevReqTBSX OBJ_set_ctype,30L + +#define SN_setct_CapRevResData "setct-CapRevResData" +#define NID_setct_CapRevResData 549 +#define OBJ_setct_CapRevResData OBJ_set_ctype,31L + +#define SN_setct_CredReqTBS "setct-CredReqTBS" +#define NID_setct_CredReqTBS 550 +#define OBJ_setct_CredReqTBS OBJ_set_ctype,32L + +#define SN_setct_CredReqTBSX "setct-CredReqTBSX" +#define NID_setct_CredReqTBSX 551 +#define OBJ_setct_CredReqTBSX OBJ_set_ctype,33L + +#define SN_setct_CredResData "setct-CredResData" +#define NID_setct_CredResData 552 +#define OBJ_setct_CredResData OBJ_set_ctype,34L + +#define SN_setct_CredRevReqTBS "setct-CredRevReqTBS" +#define NID_setct_CredRevReqTBS 553 +#define OBJ_setct_CredRevReqTBS OBJ_set_ctype,35L + +#define SN_setct_CredRevReqTBSX "setct-CredRevReqTBSX" +#define NID_setct_CredRevReqTBSX 554 +#define OBJ_setct_CredRevReqTBSX OBJ_set_ctype,36L + +#define SN_setct_CredRevResData "setct-CredRevResData" +#define NID_setct_CredRevResData 555 +#define OBJ_setct_CredRevResData OBJ_set_ctype,37L + +#define SN_setct_PCertReqData "setct-PCertReqData" +#define NID_setct_PCertReqData 556 +#define OBJ_setct_PCertReqData OBJ_set_ctype,38L + +#define SN_setct_PCertResTBS "setct-PCertResTBS" +#define NID_setct_PCertResTBS 557 +#define OBJ_setct_PCertResTBS OBJ_set_ctype,39L + +#define SN_setct_BatchAdminReqData "setct-BatchAdminReqData" +#define NID_setct_BatchAdminReqData 558 +#define OBJ_setct_BatchAdminReqData OBJ_set_ctype,40L + +#define SN_setct_BatchAdminResData "setct-BatchAdminResData" +#define NID_setct_BatchAdminResData 559 +#define OBJ_setct_BatchAdminResData OBJ_set_ctype,41L + +#define SN_setct_CardCInitResTBS "setct-CardCInitResTBS" +#define NID_setct_CardCInitResTBS 560 +#define OBJ_setct_CardCInitResTBS OBJ_set_ctype,42L + +#define SN_setct_MeAqCInitResTBS "setct-MeAqCInitResTBS" +#define NID_setct_MeAqCInitResTBS 561 +#define OBJ_setct_MeAqCInitResTBS OBJ_set_ctype,43L + +#define SN_setct_RegFormResTBS "setct-RegFormResTBS" +#define NID_setct_RegFormResTBS 562 +#define OBJ_setct_RegFormResTBS OBJ_set_ctype,44L + +#define SN_setct_CertReqData "setct-CertReqData" +#define NID_setct_CertReqData 563 +#define OBJ_setct_CertReqData OBJ_set_ctype,45L + +#define SN_setct_CertReqTBS "setct-CertReqTBS" +#define NID_setct_CertReqTBS 564 +#define OBJ_setct_CertReqTBS OBJ_set_ctype,46L + +#define SN_setct_CertResData "setct-CertResData" +#define NID_setct_CertResData 565 +#define OBJ_setct_CertResData OBJ_set_ctype,47L + +#define SN_setct_CertInqReqTBS "setct-CertInqReqTBS" +#define NID_setct_CertInqReqTBS 566 +#define OBJ_setct_CertInqReqTBS OBJ_set_ctype,48L + +#define SN_setct_ErrorTBS "setct-ErrorTBS" +#define NID_setct_ErrorTBS 567 +#define OBJ_setct_ErrorTBS OBJ_set_ctype,49L + +#define SN_setct_PIDualSignedTBE "setct-PIDualSignedTBE" +#define NID_setct_PIDualSignedTBE 568 +#define OBJ_setct_PIDualSignedTBE OBJ_set_ctype,50L + +#define SN_setct_PIUnsignedTBE "setct-PIUnsignedTBE" +#define NID_setct_PIUnsignedTBE 569 +#define OBJ_setct_PIUnsignedTBE OBJ_set_ctype,51L + +#define SN_setct_AuthReqTBE "setct-AuthReqTBE" +#define NID_setct_AuthReqTBE 570 +#define OBJ_setct_AuthReqTBE OBJ_set_ctype,52L + +#define SN_setct_AuthResTBE "setct-AuthResTBE" +#define NID_setct_AuthResTBE 571 +#define OBJ_setct_AuthResTBE OBJ_set_ctype,53L + +#define SN_setct_AuthResTBEX "setct-AuthResTBEX" +#define NID_setct_AuthResTBEX 572 +#define OBJ_setct_AuthResTBEX OBJ_set_ctype,54L + +#define SN_setct_AuthTokenTBE "setct-AuthTokenTBE" +#define NID_setct_AuthTokenTBE 573 +#define OBJ_setct_AuthTokenTBE OBJ_set_ctype,55L + +#define SN_setct_CapTokenTBE "setct-CapTokenTBE" +#define NID_setct_CapTokenTBE 574 +#define OBJ_setct_CapTokenTBE OBJ_set_ctype,56L + +#define SN_setct_CapTokenTBEX "setct-CapTokenTBEX" +#define NID_setct_CapTokenTBEX 575 +#define OBJ_setct_CapTokenTBEX OBJ_set_ctype,57L + +#define SN_setct_AcqCardCodeMsgTBE "setct-AcqCardCodeMsgTBE" +#define NID_setct_AcqCardCodeMsgTBE 576 +#define OBJ_setct_AcqCardCodeMsgTBE OBJ_set_ctype,58L + +#define SN_setct_AuthRevReqTBE "setct-AuthRevReqTBE" +#define NID_setct_AuthRevReqTBE 577 +#define OBJ_setct_AuthRevReqTBE OBJ_set_ctype,59L + +#define SN_setct_AuthRevResTBE "setct-AuthRevResTBE" +#define NID_setct_AuthRevResTBE 578 +#define OBJ_setct_AuthRevResTBE OBJ_set_ctype,60L + +#define SN_setct_AuthRevResTBEB "setct-AuthRevResTBEB" +#define NID_setct_AuthRevResTBEB 579 +#define OBJ_setct_AuthRevResTBEB OBJ_set_ctype,61L + +#define SN_setct_CapReqTBE "setct-CapReqTBE" +#define NID_setct_CapReqTBE 580 +#define OBJ_setct_CapReqTBE OBJ_set_ctype,62L + +#define SN_setct_CapReqTBEX "setct-CapReqTBEX" +#define NID_setct_CapReqTBEX 581 +#define OBJ_setct_CapReqTBEX OBJ_set_ctype,63L + +#define SN_setct_CapResTBE "setct-CapResTBE" +#define NID_setct_CapResTBE 582 +#define OBJ_setct_CapResTBE OBJ_set_ctype,64L + +#define SN_setct_CapRevReqTBE "setct-CapRevReqTBE" +#define NID_setct_CapRevReqTBE 583 +#define OBJ_setct_CapRevReqTBE OBJ_set_ctype,65L + +#define SN_setct_CapRevReqTBEX "setct-CapRevReqTBEX" +#define NID_setct_CapRevReqTBEX 584 +#define OBJ_setct_CapRevReqTBEX OBJ_set_ctype,66L + +#define SN_setct_CapRevResTBE "setct-CapRevResTBE" +#define NID_setct_CapRevResTBE 585 +#define OBJ_setct_CapRevResTBE OBJ_set_ctype,67L + +#define SN_setct_CredReqTBE "setct-CredReqTBE" +#define NID_setct_CredReqTBE 586 +#define OBJ_setct_CredReqTBE OBJ_set_ctype,68L + +#define SN_setct_CredReqTBEX "setct-CredReqTBEX" +#define NID_setct_CredReqTBEX 587 +#define OBJ_setct_CredReqTBEX OBJ_set_ctype,69L + +#define SN_setct_CredResTBE "setct-CredResTBE" +#define NID_setct_CredResTBE 588 +#define OBJ_setct_CredResTBE OBJ_set_ctype,70L + +#define SN_setct_CredRevReqTBE "setct-CredRevReqTBE" +#define NID_setct_CredRevReqTBE 589 +#define OBJ_setct_CredRevReqTBE OBJ_set_ctype,71L + +#define SN_setct_CredRevReqTBEX "setct-CredRevReqTBEX" +#define NID_setct_CredRevReqTBEX 590 +#define OBJ_setct_CredRevReqTBEX OBJ_set_ctype,72L + +#define SN_setct_CredRevResTBE "setct-CredRevResTBE" +#define NID_setct_CredRevResTBE 591 +#define OBJ_setct_CredRevResTBE OBJ_set_ctype,73L + +#define SN_setct_BatchAdminReqTBE "setct-BatchAdminReqTBE" +#define NID_setct_BatchAdminReqTBE 592 +#define OBJ_setct_BatchAdminReqTBE OBJ_set_ctype,74L + +#define SN_setct_BatchAdminResTBE "setct-BatchAdminResTBE" +#define NID_setct_BatchAdminResTBE 593 +#define OBJ_setct_BatchAdminResTBE OBJ_set_ctype,75L + +#define SN_setct_RegFormReqTBE "setct-RegFormReqTBE" +#define NID_setct_RegFormReqTBE 594 +#define OBJ_setct_RegFormReqTBE OBJ_set_ctype,76L + +#define SN_setct_CertReqTBE "setct-CertReqTBE" +#define NID_setct_CertReqTBE 595 +#define OBJ_setct_CertReqTBE OBJ_set_ctype,77L + +#define SN_setct_CertReqTBEX "setct-CertReqTBEX" +#define NID_setct_CertReqTBEX 596 +#define OBJ_setct_CertReqTBEX OBJ_set_ctype,78L + +#define SN_setct_CertResTBE "setct-CertResTBE" +#define NID_setct_CertResTBE 597 +#define OBJ_setct_CertResTBE OBJ_set_ctype,79L + +#define SN_setct_CRLNotificationTBS "setct-CRLNotificationTBS" +#define NID_setct_CRLNotificationTBS 598 +#define OBJ_setct_CRLNotificationTBS OBJ_set_ctype,80L + +#define SN_setct_CRLNotificationResTBS "setct-CRLNotificationResTBS" +#define NID_setct_CRLNotificationResTBS 599 +#define OBJ_setct_CRLNotificationResTBS OBJ_set_ctype,81L + +#define SN_setct_BCIDistributionTBS "setct-BCIDistributionTBS" +#define NID_setct_BCIDistributionTBS 600 +#define OBJ_setct_BCIDistributionTBS OBJ_set_ctype,82L + +#define SN_setext_genCrypt "setext-genCrypt" +#define LN_setext_genCrypt "generic cryptogram" +#define NID_setext_genCrypt 601 +#define OBJ_setext_genCrypt OBJ_set_msgExt,1L + +#define SN_setext_miAuth "setext-miAuth" +#define LN_setext_miAuth "merchant initiated auth" +#define NID_setext_miAuth 602 +#define OBJ_setext_miAuth OBJ_set_msgExt,3L + +#define SN_setext_pinSecure "setext-pinSecure" +#define NID_setext_pinSecure 603 +#define OBJ_setext_pinSecure OBJ_set_msgExt,4L + +#define SN_setext_pinAny "setext-pinAny" +#define NID_setext_pinAny 604 +#define OBJ_setext_pinAny OBJ_set_msgExt,5L + +#define SN_setext_track2 "setext-track2" +#define NID_setext_track2 605 +#define OBJ_setext_track2 OBJ_set_msgExt,7L + +#define SN_setext_cv "setext-cv" +#define LN_setext_cv "additional verification" +#define NID_setext_cv 606 +#define OBJ_setext_cv OBJ_set_msgExt,8L + +#define SN_set_policy_root "set-policy-root" +#define NID_set_policy_root 607 +#define OBJ_set_policy_root OBJ_set_policy,0L + +#define SN_setCext_hashedRoot "setCext-hashedRoot" +#define NID_setCext_hashedRoot 608 +#define OBJ_setCext_hashedRoot OBJ_set_certExt,0L + +#define SN_setCext_certType "setCext-certType" +#define NID_setCext_certType 609 +#define OBJ_setCext_certType OBJ_set_certExt,1L + +#define SN_setCext_merchData "setCext-merchData" +#define NID_setCext_merchData 610 +#define OBJ_setCext_merchData OBJ_set_certExt,2L + +#define SN_setCext_cCertRequired "setCext-cCertRequired" +#define NID_setCext_cCertRequired 611 +#define OBJ_setCext_cCertRequired OBJ_set_certExt,3L + +#define SN_setCext_tunneling "setCext-tunneling" +#define NID_setCext_tunneling 612 +#define OBJ_setCext_tunneling OBJ_set_certExt,4L + +#define SN_setCext_setExt "setCext-setExt" +#define NID_setCext_setExt 613 +#define OBJ_setCext_setExt OBJ_set_certExt,5L + +#define SN_setCext_setQualf "setCext-setQualf" +#define NID_setCext_setQualf 614 +#define OBJ_setCext_setQualf OBJ_set_certExt,6L + +#define SN_setCext_PGWYcapabilities "setCext-PGWYcapabilities" +#define NID_setCext_PGWYcapabilities 615 +#define OBJ_setCext_PGWYcapabilities OBJ_set_certExt,7L + +#define SN_setCext_TokenIdentifier "setCext-TokenIdentifier" +#define NID_setCext_TokenIdentifier 616 +#define OBJ_setCext_TokenIdentifier OBJ_set_certExt,8L + +#define SN_setCext_Track2Data "setCext-Track2Data" +#define NID_setCext_Track2Data 617 +#define OBJ_setCext_Track2Data OBJ_set_certExt,9L + +#define SN_setCext_TokenType "setCext-TokenType" +#define NID_setCext_TokenType 618 +#define OBJ_setCext_TokenType OBJ_set_certExt,10L + +#define SN_setCext_IssuerCapabilities "setCext-IssuerCapabilities" +#define NID_setCext_IssuerCapabilities 619 +#define OBJ_setCext_IssuerCapabilities OBJ_set_certExt,11L + +#define SN_setAttr_Cert "setAttr-Cert" +#define NID_setAttr_Cert 620 +#define OBJ_setAttr_Cert OBJ_set_attr,0L + +#define SN_setAttr_PGWYcap "setAttr-PGWYcap" +#define LN_setAttr_PGWYcap "payment gateway capabilities" +#define NID_setAttr_PGWYcap 621 +#define OBJ_setAttr_PGWYcap OBJ_set_attr,1L + +#define SN_setAttr_TokenType "setAttr-TokenType" +#define NID_setAttr_TokenType 622 +#define OBJ_setAttr_TokenType OBJ_set_attr,2L + +#define SN_setAttr_IssCap "setAttr-IssCap" +#define LN_setAttr_IssCap "issuer capabilities" +#define NID_setAttr_IssCap 623 +#define OBJ_setAttr_IssCap OBJ_set_attr,3L + +#define SN_set_rootKeyThumb "set-rootKeyThumb" +#define NID_set_rootKeyThumb 624 +#define OBJ_set_rootKeyThumb OBJ_setAttr_Cert,0L + +#define SN_set_addPolicy "set-addPolicy" +#define NID_set_addPolicy 625 +#define OBJ_set_addPolicy OBJ_setAttr_Cert,1L + +#define SN_setAttr_Token_EMV "setAttr-Token-EMV" +#define NID_setAttr_Token_EMV 626 +#define OBJ_setAttr_Token_EMV OBJ_setAttr_TokenType,1L + +#define SN_setAttr_Token_B0Prime "setAttr-Token-B0Prime" +#define NID_setAttr_Token_B0Prime 627 +#define OBJ_setAttr_Token_B0Prime OBJ_setAttr_TokenType,2L + +#define SN_setAttr_IssCap_CVM "setAttr-IssCap-CVM" +#define NID_setAttr_IssCap_CVM 628 +#define OBJ_setAttr_IssCap_CVM OBJ_setAttr_IssCap,3L + +#define SN_setAttr_IssCap_T2 "setAttr-IssCap-T2" +#define NID_setAttr_IssCap_T2 629 +#define OBJ_setAttr_IssCap_T2 OBJ_setAttr_IssCap,4L + +#define SN_setAttr_IssCap_Sig "setAttr-IssCap-Sig" +#define NID_setAttr_IssCap_Sig 630 +#define OBJ_setAttr_IssCap_Sig OBJ_setAttr_IssCap,5L + +#define SN_setAttr_GenCryptgrm "setAttr-GenCryptgrm" +#define LN_setAttr_GenCryptgrm "generate cryptogram" +#define NID_setAttr_GenCryptgrm 631 +#define OBJ_setAttr_GenCryptgrm OBJ_setAttr_IssCap_CVM,1L + +#define SN_setAttr_T2Enc "setAttr-T2Enc" +#define LN_setAttr_T2Enc "encrypted track 2" +#define NID_setAttr_T2Enc 632 +#define OBJ_setAttr_T2Enc OBJ_setAttr_IssCap_T2,1L + +#define SN_setAttr_T2cleartxt "setAttr-T2cleartxt" +#define LN_setAttr_T2cleartxt "cleartext track 2" +#define NID_setAttr_T2cleartxt 633 +#define OBJ_setAttr_T2cleartxt OBJ_setAttr_IssCap_T2,2L + +#define SN_setAttr_TokICCsig "setAttr-TokICCsig" +#define LN_setAttr_TokICCsig "ICC or token signature" +#define NID_setAttr_TokICCsig 634 +#define OBJ_setAttr_TokICCsig OBJ_setAttr_IssCap_Sig,1L + +#define SN_setAttr_SecDevSig "setAttr-SecDevSig" +#define LN_setAttr_SecDevSig "secure device signature" +#define NID_setAttr_SecDevSig 635 +#define OBJ_setAttr_SecDevSig OBJ_setAttr_IssCap_Sig,2L + +#define SN_set_brand_IATA_ATA "set-brand-IATA-ATA" +#define NID_set_brand_IATA_ATA 636 +#define OBJ_set_brand_IATA_ATA OBJ_set_brand,1L + +#define SN_set_brand_Diners "set-brand-Diners" +#define NID_set_brand_Diners 637 +#define OBJ_set_brand_Diners OBJ_set_brand,30L + +#define SN_set_brand_AmericanExpress "set-brand-AmericanExpress" +#define NID_set_brand_AmericanExpress 638 +#define OBJ_set_brand_AmericanExpress OBJ_set_brand,34L + +#define SN_set_brand_JCB "set-brand-JCB" +#define NID_set_brand_JCB 639 +#define OBJ_set_brand_JCB OBJ_set_brand,35L + +#define SN_set_brand_Visa "set-brand-Visa" +#define NID_set_brand_Visa 640 +#define OBJ_set_brand_Visa OBJ_set_brand,4L + +#define SN_set_brand_MasterCard "set-brand-MasterCard" +#define NID_set_brand_MasterCard 641 +#define OBJ_set_brand_MasterCard OBJ_set_brand,5L + +#define SN_set_brand_Novus "set-brand-Novus" +#define NID_set_brand_Novus 642 +#define OBJ_set_brand_Novus OBJ_set_brand,6011L + +#define SN_des_cdmf "DES-CDMF" +#define LN_des_cdmf "des-cdmf" +#define NID_des_cdmf 643 +#define OBJ_des_cdmf OBJ_rsadsi,3L,10L + +#define SN_rsaOAEPEncryptionSET "rsaOAEPEncryptionSET" +#define NID_rsaOAEPEncryptionSET 644 +#define OBJ_rsaOAEPEncryptionSET OBJ_rsadsi,1L,1L,6L + +#define SN_ipsec3 "Oakley-EC2N-3" +#define LN_ipsec3 "ipsec3" +#define NID_ipsec3 749 + +#define SN_ipsec4 "Oakley-EC2N-4" +#define LN_ipsec4 "ipsec4" +#define NID_ipsec4 750 + +#define SN_whirlpool "whirlpool" +#define NID_whirlpool 804 +#define OBJ_whirlpool OBJ_iso,0L,10118L,3L,0L,55L + +#define SN_cryptopro "cryptopro" +#define NID_cryptopro 805 +#define OBJ_cryptopro OBJ_member_body,643L,2L,2L + +#define SN_cryptocom "cryptocom" +#define NID_cryptocom 806 +#define OBJ_cryptocom OBJ_member_body,643L,2L,9L + +#define SN_id_GostR3411_94_with_GostR3410_2001 "id-GostR3411-94-with-GostR3410-2001" +#define LN_id_GostR3411_94_with_GostR3410_2001 "GOST R 34.11-94 with GOST R 34.10-2001" +#define NID_id_GostR3411_94_with_GostR3410_2001 807 +#define OBJ_id_GostR3411_94_with_GostR3410_2001 OBJ_cryptopro,3L + +#define SN_id_GostR3411_94_with_GostR3410_94 "id-GostR3411-94-with-GostR3410-94" +#define LN_id_GostR3411_94_with_GostR3410_94 "GOST R 34.11-94 with GOST R 34.10-94" +#define NID_id_GostR3411_94_with_GostR3410_94 808 +#define OBJ_id_GostR3411_94_with_GostR3410_94 OBJ_cryptopro,4L + +#define SN_id_GostR3411_94 "md_gost94" +#define LN_id_GostR3411_94 "GOST R 34.11-94" +#define NID_id_GostR3411_94 809 +#define OBJ_id_GostR3411_94 OBJ_cryptopro,9L + +#define SN_id_HMACGostR3411_94 "id-HMACGostR3411-94" +#define LN_id_HMACGostR3411_94 "HMAC GOST 34.11-94" +#define NID_id_HMACGostR3411_94 810 +#define OBJ_id_HMACGostR3411_94 OBJ_cryptopro,10L + +#define SN_id_GostR3410_2001 "gost2001" +#define LN_id_GostR3410_2001 "GOST R 34.10-2001" +#define NID_id_GostR3410_2001 811 +#define OBJ_id_GostR3410_2001 OBJ_cryptopro,19L + +#define SN_id_GostR3410_94 "gost94" +#define LN_id_GostR3410_94 "GOST R 34.10-94" +#define NID_id_GostR3410_94 812 +#define OBJ_id_GostR3410_94 OBJ_cryptopro,20L + +#define SN_id_Gost28147_89 "gost89" +#define LN_id_Gost28147_89 "GOST 28147-89" +#define NID_id_Gost28147_89 813 +#define OBJ_id_Gost28147_89 OBJ_cryptopro,21L + +#define SN_gost89_cnt "gost89-cnt" +#define NID_gost89_cnt 814 + +#define SN_id_Gost28147_89_MAC "gost-mac" +#define LN_id_Gost28147_89_MAC "GOST 28147-89 MAC" +#define NID_id_Gost28147_89_MAC 815 +#define OBJ_id_Gost28147_89_MAC OBJ_cryptopro,22L + +#define SN_id_GostR3411_94_prf "prf-gostr3411-94" +#define LN_id_GostR3411_94_prf "GOST R 34.11-94 PRF" +#define NID_id_GostR3411_94_prf 816 +#define OBJ_id_GostR3411_94_prf OBJ_cryptopro,23L + +#define SN_id_GostR3410_2001DH "id-GostR3410-2001DH" +#define LN_id_GostR3410_2001DH "GOST R 34.10-2001 DH" +#define NID_id_GostR3410_2001DH 817 +#define OBJ_id_GostR3410_2001DH OBJ_cryptopro,98L + +#define SN_id_GostR3410_94DH "id-GostR3410-94DH" +#define LN_id_GostR3410_94DH "GOST R 34.10-94 DH" +#define NID_id_GostR3410_94DH 818 +#define OBJ_id_GostR3410_94DH OBJ_cryptopro,99L + +#define SN_id_Gost28147_89_CryptoPro_KeyMeshing "id-Gost28147-89-CryptoPro-KeyMeshing" +#define NID_id_Gost28147_89_CryptoPro_KeyMeshing 819 +#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing OBJ_cryptopro,14L,1L + +#define SN_id_Gost28147_89_None_KeyMeshing "id-Gost28147-89-None-KeyMeshing" +#define NID_id_Gost28147_89_None_KeyMeshing 820 +#define OBJ_id_Gost28147_89_None_KeyMeshing OBJ_cryptopro,14L,0L + +#define SN_id_GostR3411_94_TestParamSet "id-GostR3411-94-TestParamSet" +#define NID_id_GostR3411_94_TestParamSet 821 +#define OBJ_id_GostR3411_94_TestParamSet OBJ_cryptopro,30L,0L + +#define SN_id_GostR3411_94_CryptoProParamSet "id-GostR3411-94-CryptoProParamSet" +#define NID_id_GostR3411_94_CryptoProParamSet 822 +#define OBJ_id_GostR3411_94_CryptoProParamSet OBJ_cryptopro,30L,1L + +#define SN_id_Gost28147_89_TestParamSet "id-Gost28147-89-TestParamSet" +#define NID_id_Gost28147_89_TestParamSet 823 +#define OBJ_id_Gost28147_89_TestParamSet OBJ_cryptopro,31L,0L + +#define SN_id_Gost28147_89_CryptoPro_A_ParamSet "id-Gost28147-89-CryptoPro-A-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_A_ParamSet 824 +#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet OBJ_cryptopro,31L,1L + +#define SN_id_Gost28147_89_CryptoPro_B_ParamSet "id-Gost28147-89-CryptoPro-B-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_B_ParamSet 825 +#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet OBJ_cryptopro,31L,2L + +#define SN_id_Gost28147_89_CryptoPro_C_ParamSet "id-Gost28147-89-CryptoPro-C-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_C_ParamSet 826 +#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet OBJ_cryptopro,31L,3L + +#define SN_id_Gost28147_89_CryptoPro_D_ParamSet "id-Gost28147-89-CryptoPro-D-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_D_ParamSet 827 +#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet OBJ_cryptopro,31L,4L + +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 828 +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet OBJ_cryptopro,31L,5L + +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 829 +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet OBJ_cryptopro,31L,6L + +#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 830 +#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet OBJ_cryptopro,31L,7L + +#define SN_id_GostR3410_94_TestParamSet "id-GostR3410-94-TestParamSet" +#define NID_id_GostR3410_94_TestParamSet 831 +#define OBJ_id_GostR3410_94_TestParamSet OBJ_cryptopro,32L,0L + +#define SN_id_GostR3410_94_CryptoPro_A_ParamSet "id-GostR3410-94-CryptoPro-A-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_A_ParamSet 832 +#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet OBJ_cryptopro,32L,2L + +#define SN_id_GostR3410_94_CryptoPro_B_ParamSet "id-GostR3410-94-CryptoPro-B-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_B_ParamSet 833 +#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet OBJ_cryptopro,32L,3L + +#define SN_id_GostR3410_94_CryptoPro_C_ParamSet "id-GostR3410-94-CryptoPro-C-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_C_ParamSet 834 +#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet OBJ_cryptopro,32L,4L + +#define SN_id_GostR3410_94_CryptoPro_D_ParamSet "id-GostR3410-94-CryptoPro-D-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_D_ParamSet 835 +#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet OBJ_cryptopro,32L,5L + +#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet "id-GostR3410-94-CryptoPro-XchA-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet 836 +#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet OBJ_cryptopro,33L,1L + +#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet "id-GostR3410-94-CryptoPro-XchB-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet 837 +#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet OBJ_cryptopro,33L,2L + +#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet "id-GostR3410-94-CryptoPro-XchC-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet 838 +#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet OBJ_cryptopro,33L,3L + +#define SN_id_GostR3410_2001_TestParamSet "id-GostR3410-2001-TestParamSet" +#define NID_id_GostR3410_2001_TestParamSet 839 +#define OBJ_id_GostR3410_2001_TestParamSet OBJ_cryptopro,35L,0L + +#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet "id-GostR3410-2001-CryptoPro-A-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet 840 +#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet OBJ_cryptopro,35L,1L + +#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet "id-GostR3410-2001-CryptoPro-B-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet 841 +#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet OBJ_cryptopro,35L,2L + +#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet "id-GostR3410-2001-CryptoPro-C-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet 842 +#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet OBJ_cryptopro,35L,3L + +#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet "id-GostR3410-2001-CryptoPro-XchA-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet 843 +#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet OBJ_cryptopro,36L,0L + +#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet "id-GostR3410-2001-CryptoPro-XchB-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet 844 +#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet OBJ_cryptopro,36L,1L + +#define SN_id_GostR3410_94_a "id-GostR3410-94-a" +#define NID_id_GostR3410_94_a 845 +#define OBJ_id_GostR3410_94_a OBJ_id_GostR3410_94,1L + +#define SN_id_GostR3410_94_aBis "id-GostR3410-94-aBis" +#define NID_id_GostR3410_94_aBis 846 +#define OBJ_id_GostR3410_94_aBis OBJ_id_GostR3410_94,2L + +#define SN_id_GostR3410_94_b "id-GostR3410-94-b" +#define NID_id_GostR3410_94_b 847 +#define OBJ_id_GostR3410_94_b OBJ_id_GostR3410_94,3L + +#define SN_id_GostR3410_94_bBis "id-GostR3410-94-bBis" +#define NID_id_GostR3410_94_bBis 848 +#define OBJ_id_GostR3410_94_bBis OBJ_id_GostR3410_94,4L + +#define SN_id_Gost28147_89_cc "id-Gost28147-89-cc" +#define LN_id_Gost28147_89_cc "GOST 28147-89 Cryptocom ParamSet" +#define NID_id_Gost28147_89_cc 849 +#define OBJ_id_Gost28147_89_cc OBJ_cryptocom,1L,6L,1L + +#define SN_id_GostR3410_94_cc "gost94cc" +#define LN_id_GostR3410_94_cc "GOST 34.10-94 Cryptocom" +#define NID_id_GostR3410_94_cc 850 +#define OBJ_id_GostR3410_94_cc OBJ_cryptocom,1L,5L,3L + +#define SN_id_GostR3410_2001_cc "gost2001cc" +#define LN_id_GostR3410_2001_cc "GOST 34.10-2001 Cryptocom" +#define NID_id_GostR3410_2001_cc 851 +#define OBJ_id_GostR3410_2001_cc OBJ_cryptocom,1L,5L,4L + +#define SN_id_GostR3411_94_with_GostR3410_94_cc "id-GostR3411-94-with-GostR3410-94-cc" +#define LN_id_GostR3411_94_with_GostR3410_94_cc "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" +#define NID_id_GostR3411_94_with_GostR3410_94_cc 852 +#define OBJ_id_GostR3411_94_with_GostR3410_94_cc OBJ_cryptocom,1L,3L,3L + +#define SN_id_GostR3411_94_with_GostR3410_2001_cc "id-GostR3411-94-with-GostR3410-2001-cc" +#define LN_id_GostR3411_94_with_GostR3410_2001_cc "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" +#define NID_id_GostR3411_94_with_GostR3410_2001_cc 853 +#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc OBJ_cryptocom,1L,3L,4L + +#define SN_id_GostR3410_2001_ParamSet_cc "id-GostR3410-2001-ParamSet-cc" +#define LN_id_GostR3410_2001_ParamSet_cc "GOST R 3410-2001 Parameter Set Cryptocom" +#define NID_id_GostR3410_2001_ParamSet_cc 854 +#define OBJ_id_GostR3410_2001_ParamSet_cc OBJ_cryptocom,1L,8L,1L + +#define SN_camellia_128_cbc "CAMELLIA-128-CBC" +#define LN_camellia_128_cbc "camellia-128-cbc" +#define NID_camellia_128_cbc 751 +#define OBJ_camellia_128_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,2L + +#define SN_camellia_192_cbc "CAMELLIA-192-CBC" +#define LN_camellia_192_cbc "camellia-192-cbc" +#define NID_camellia_192_cbc 752 +#define OBJ_camellia_192_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,3L + +#define SN_camellia_256_cbc "CAMELLIA-256-CBC" +#define LN_camellia_256_cbc "camellia-256-cbc" +#define NID_camellia_256_cbc 753 +#define OBJ_camellia_256_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,4L + +#define SN_id_camellia128_wrap "id-camellia128-wrap" +#define NID_id_camellia128_wrap 907 +#define OBJ_id_camellia128_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,2L + +#define SN_id_camellia192_wrap "id-camellia192-wrap" +#define NID_id_camellia192_wrap 908 +#define OBJ_id_camellia192_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,3L + +#define SN_id_camellia256_wrap "id-camellia256-wrap" +#define NID_id_camellia256_wrap 909 +#define OBJ_id_camellia256_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,4L + +#define OBJ_ntt_ds 0L,3L,4401L,5L + +#define OBJ_camellia OBJ_ntt_ds,3L,1L,9L + +#define SN_camellia_128_ecb "CAMELLIA-128-ECB" +#define LN_camellia_128_ecb "camellia-128-ecb" +#define NID_camellia_128_ecb 754 +#define OBJ_camellia_128_ecb OBJ_camellia,1L + +#define SN_camellia_128_ofb128 "CAMELLIA-128-OFB" +#define LN_camellia_128_ofb128 "camellia-128-ofb" +#define NID_camellia_128_ofb128 766 +#define OBJ_camellia_128_ofb128 OBJ_camellia,3L + +#define SN_camellia_128_cfb128 "CAMELLIA-128-CFB" +#define LN_camellia_128_cfb128 "camellia-128-cfb" +#define NID_camellia_128_cfb128 757 +#define OBJ_camellia_128_cfb128 OBJ_camellia,4L + +#define SN_camellia_192_ecb "CAMELLIA-192-ECB" +#define LN_camellia_192_ecb "camellia-192-ecb" +#define NID_camellia_192_ecb 755 +#define OBJ_camellia_192_ecb OBJ_camellia,21L + +#define SN_camellia_192_ofb128 "CAMELLIA-192-OFB" +#define LN_camellia_192_ofb128 "camellia-192-ofb" +#define NID_camellia_192_ofb128 767 +#define OBJ_camellia_192_ofb128 OBJ_camellia,23L + +#define SN_camellia_192_cfb128 "CAMELLIA-192-CFB" +#define LN_camellia_192_cfb128 "camellia-192-cfb" +#define NID_camellia_192_cfb128 758 +#define OBJ_camellia_192_cfb128 OBJ_camellia,24L + +#define SN_camellia_256_ecb "CAMELLIA-256-ECB" +#define LN_camellia_256_ecb "camellia-256-ecb" +#define NID_camellia_256_ecb 756 +#define OBJ_camellia_256_ecb OBJ_camellia,41L + +#define SN_camellia_256_ofb128 "CAMELLIA-256-OFB" +#define LN_camellia_256_ofb128 "camellia-256-ofb" +#define NID_camellia_256_ofb128 768 +#define OBJ_camellia_256_ofb128 OBJ_camellia,43L + +#define SN_camellia_256_cfb128 "CAMELLIA-256-CFB" +#define LN_camellia_256_cfb128 "camellia-256-cfb" +#define NID_camellia_256_cfb128 759 +#define OBJ_camellia_256_cfb128 OBJ_camellia,44L + +#define SN_camellia_128_cfb1 "CAMELLIA-128-CFB1" +#define LN_camellia_128_cfb1 "camellia-128-cfb1" +#define NID_camellia_128_cfb1 760 + +#define SN_camellia_192_cfb1 "CAMELLIA-192-CFB1" +#define LN_camellia_192_cfb1 "camellia-192-cfb1" +#define NID_camellia_192_cfb1 761 + +#define SN_camellia_256_cfb1 "CAMELLIA-256-CFB1" +#define LN_camellia_256_cfb1 "camellia-256-cfb1" +#define NID_camellia_256_cfb1 762 + +#define SN_camellia_128_cfb8 "CAMELLIA-128-CFB8" +#define LN_camellia_128_cfb8 "camellia-128-cfb8" +#define NID_camellia_128_cfb8 763 + +#define SN_camellia_192_cfb8 "CAMELLIA-192-CFB8" +#define LN_camellia_192_cfb8 "camellia-192-cfb8" +#define NID_camellia_192_cfb8 764 + +#define SN_camellia_256_cfb8 "CAMELLIA-256-CFB8" +#define LN_camellia_256_cfb8 "camellia-256-cfb8" +#define NID_camellia_256_cfb8 765 + +#define SN_kisa "KISA" +#define LN_kisa "kisa" +#define NID_kisa 773 +#define OBJ_kisa OBJ_member_body,410L,200004L + +#define SN_seed_ecb "SEED-ECB" +#define LN_seed_ecb "seed-ecb" +#define NID_seed_ecb 776 +#define OBJ_seed_ecb OBJ_kisa,1L,3L + +#define SN_seed_cbc "SEED-CBC" +#define LN_seed_cbc "seed-cbc" +#define NID_seed_cbc 777 +#define OBJ_seed_cbc OBJ_kisa,1L,4L + +#define SN_seed_cfb128 "SEED-CFB" +#define LN_seed_cfb128 "seed-cfb" +#define NID_seed_cfb128 779 +#define OBJ_seed_cfb128 OBJ_kisa,1L,5L + +#define SN_seed_ofb128 "SEED-OFB" +#define LN_seed_ofb128 "seed-ofb" +#define NID_seed_ofb128 778 +#define OBJ_seed_ofb128 OBJ_kisa,1L,6L + +#define SN_hmac "HMAC" +#define LN_hmac "hmac" +#define NID_hmac 855 + +#define SN_cmac "CMAC" +#define LN_cmac "cmac" +#define NID_cmac 894 + +#define SN_rc4_hmac_md5 "RC4-HMAC-MD5" +#define LN_rc4_hmac_md5 "rc4-hmac-md5" +#define NID_rc4_hmac_md5 915 + +#define SN_aes_128_cbc_hmac_sha1 "AES-128-CBC-HMAC-SHA1" +#define LN_aes_128_cbc_hmac_sha1 "aes-128-cbc-hmac-sha1" +#define NID_aes_128_cbc_hmac_sha1 916 + +#define SN_aes_192_cbc_hmac_sha1 "AES-192-CBC-HMAC-SHA1" +#define LN_aes_192_cbc_hmac_sha1 "aes-192-cbc-hmac-sha1" +#define NID_aes_192_cbc_hmac_sha1 917 + +#define SN_aes_256_cbc_hmac_sha1 "AES-256-CBC-HMAC-SHA1" +#define LN_aes_256_cbc_hmac_sha1 "aes-256-cbc-hmac-sha1" +#define NID_aes_256_cbc_hmac_sha1 918 + +#define SN_teletrust "teletrust" +#define NID_teletrust 920 +#define OBJ_teletrust OBJ_identified_organization,36L + +#define SN_brainpool "brainpool" +#define NID_brainpool 921 +#define OBJ_brainpool OBJ_teletrust,3L,3L,2L,8L,1L + +#define SN_brainpoolP160r1 "brainpoolP160r1" +#define NID_brainpoolP160r1 922 +#define OBJ_brainpoolP160r1 OBJ_brainpool,1L,1L + +#define SN_brainpoolP160t1 "brainpoolP160t1" +#define NID_brainpoolP160t1 923 +#define OBJ_brainpoolP160t1 OBJ_brainpool,1L,2L + +#define SN_brainpoolP192r1 "brainpoolP192r1" +#define NID_brainpoolP192r1 924 +#define OBJ_brainpoolP192r1 OBJ_brainpool,1L,3L + +#define SN_brainpoolP192t1 "brainpoolP192t1" +#define NID_brainpoolP192t1 925 +#define OBJ_brainpoolP192t1 OBJ_brainpool,1L,4L + +#define SN_brainpoolP224r1 "brainpoolP224r1" +#define NID_brainpoolP224r1 926 +#define OBJ_brainpoolP224r1 OBJ_brainpool,1L,5L + +#define SN_brainpoolP224t1 "brainpoolP224t1" +#define NID_brainpoolP224t1 927 +#define OBJ_brainpoolP224t1 OBJ_brainpool,1L,6L + +#define SN_brainpoolP256r1 "brainpoolP256r1" +#define NID_brainpoolP256r1 928 +#define OBJ_brainpoolP256r1 OBJ_brainpool,1L,7L + +#define SN_brainpoolP256t1 "brainpoolP256t1" +#define NID_brainpoolP256t1 929 +#define OBJ_brainpoolP256t1 OBJ_brainpool,1L,8L + +#define SN_brainpoolP320r1 "brainpoolP320r1" +#define NID_brainpoolP320r1 930 +#define OBJ_brainpoolP320r1 OBJ_brainpool,1L,9L + +#define SN_brainpoolP320t1 "brainpoolP320t1" +#define NID_brainpoolP320t1 931 +#define OBJ_brainpoolP320t1 OBJ_brainpool,1L,10L + +#define SN_brainpoolP384r1 "brainpoolP384r1" +#define NID_brainpoolP384r1 932 +#define OBJ_brainpoolP384r1 OBJ_brainpool,1L,11L + +#define SN_brainpoolP384t1 "brainpoolP384t1" +#define NID_brainpoolP384t1 933 +#define OBJ_brainpoolP384t1 OBJ_brainpool,1L,12L + +#define SN_brainpoolP512r1 "brainpoolP512r1" +#define NID_brainpoolP512r1 934 +#define OBJ_brainpoolP512r1 OBJ_brainpool,1L,13L + +#define SN_brainpoolP512t1 "brainpoolP512t1" +#define NID_brainpoolP512t1 935 +#define OBJ_brainpoolP512t1 OBJ_brainpool,1L,14L + +#define SN_FRP256v1 "FRP256v1" +#define NID_FRP256v1 936 +#define OBJ_FRP256v1 1L,2L,250L,1L,223L,101L,256L,1L + +#define SN_chacha20 "ChaCha" +#define LN_chacha20 "chacha" +#define NID_chacha20 937 + +#define SN_gost89_ecb "gost89-ecb" +#define NID_gost89_ecb 938 + +#define SN_gost89_cbc "gost89-cbc" +#define NID_gost89_cbc 939 + +#define SN_tc26 "tc26" +#define NID_tc26 940 +#define OBJ_tc26 OBJ_member_body,643L,7L,1L + +#define SN_id_tc26_gost3411_2012_256 "streebog256" +#define LN_id_tc26_gost3411_2012_256 "GOST R 34.11-2012 (256 bit)" +#define NID_id_tc26_gost3411_2012_256 941 +#define OBJ_id_tc26_gost3411_2012_256 OBJ_tc26,1L,2L,2L + +#define SN_id_tc26_gost3411_2012_512 "streebog512" +#define LN_id_tc26_gost3411_2012_512 "GOST R 34-11-2012 (512 bit)" +#define NID_id_tc26_gost3411_2012_512 942 +#define OBJ_id_tc26_gost3411_2012_512 OBJ_tc26,1L,2L,3L + +#define SN_id_tc26_gost_3410_2012_512_paramSetA "id-tc26-gost-3410-2012-512-paramSetA" +#define NID_id_tc26_gost_3410_2012_512_paramSetA 943 +#define OBJ_id_tc26_gost_3410_2012_512_paramSetA OBJ_tc26,2L,1L,2L,1L + +#define SN_id_tc26_gost_3410_2012_512_paramSetB "id-tc26-gost-3410-2012-512-paramSetB" +#define NID_id_tc26_gost_3410_2012_512_paramSetB 944 +#define OBJ_id_tc26_gost_3410_2012_512_paramSetB OBJ_tc26,2L,1L,2L,2L + +#define SN_id_tc26_gost_28147_param_Z "id-tc26-gost-28147-param-Z" +#define NID_id_tc26_gost_28147_param_Z 945 +#define OBJ_id_tc26_gost_28147_param_Z OBJ_tc26,2L,5L,1L,1L + +#define SN_id_tc26_gost3410_2012_256 "id-tc26-gost3410-2012-256" +#define LN_id_tc26_gost3410_2012_256 "GOST R 34.10-2012 (256 bit)" +#define NID_id_tc26_gost3410_2012_256 946 +#define OBJ_id_tc26_gost3410_2012_256 OBJ_tc26,1L,1L,1L + +#define SN_id_tc26_gost3410_2012_512 "id-tc26-gost3410-2012-512" +#define LN_id_tc26_gost3410_2012_512 "GOST R 34.10-2012 (512 bit)" +#define NID_id_tc26_gost3410_2012_512 947 +#define OBJ_id_tc26_gost3410_2012_512 OBJ_tc26,1L,1L,2L + +#define SN_id_tc26_signwithdigest_gost3410_2012_256 "id-tc26-signwithdigest-gost3410-2012-256" +#define LN_id_tc26_signwithdigest_gost3410_2012_256 "GOST R 34.11-2012 with GOST R 34.10-2012 (256 bit)" +#define NID_id_tc26_signwithdigest_gost3410_2012_256 948 +#define OBJ_id_tc26_signwithdigest_gost3410_2012_256 OBJ_tc26,1L,3L,2L + +#define SN_id_tc26_signwithdigest_gost3410_2012_512 "id-tc26-signwithdigest-gost3410-2012-512" +#define LN_id_tc26_signwithdigest_gost3410_2012_512 "GOST R 34.11-2012 with GOST R 34.10-2012 (512 bit)" +#define NID_id_tc26_signwithdigest_gost3410_2012_512 949 +#define OBJ_id_tc26_signwithdigest_gost3410_2012_512 OBJ_tc26,1L,3L,3L + diff --git a/crypto/libressl/include/openssl/objects.h b/crypto/libressl/include/openssl/objects.h new file mode 100644 index 0000000000..4098a01c37 --- /dev/null +++ b/crypto/libressl/include/openssl/objects.h @@ -0,0 +1,1136 @@ +/* $OpenBSD$ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_OBJECTS_H +#define HEADER_OBJECTS_H + +#define USE_OBJ_MAC + +#ifdef USE_OBJ_MAC +#include +#else +#define SN_undef "UNDEF" +#define LN_undef "undefined" +#define NID_undef 0 +#define OBJ_undef 0L + +#define SN_Algorithm "Algorithm" +#define LN_algorithm "algorithm" +#define NID_algorithm 38 +#define OBJ_algorithm 1L,3L,14L,3L,2L + +#define LN_rsadsi "rsadsi" +#define NID_rsadsi 1 +#define OBJ_rsadsi 1L,2L,840L,113549L + +#define LN_pkcs "pkcs" +#define NID_pkcs 2 +#define OBJ_pkcs OBJ_rsadsi,1L + +#define SN_md2 "MD2" +#define LN_md2 "md2" +#define NID_md2 3 +#define OBJ_md2 OBJ_rsadsi,2L,2L + +#define SN_md5 "MD5" +#define LN_md5 "md5" +#define NID_md5 4 +#define OBJ_md5 OBJ_rsadsi,2L,5L + +#define SN_rc4 "RC4" +#define LN_rc4 "rc4" +#define NID_rc4 5 +#define OBJ_rc4 OBJ_rsadsi,3L,4L + +#define LN_rsaEncryption "rsaEncryption" +#define NID_rsaEncryption 6 +#define OBJ_rsaEncryption OBJ_pkcs,1L,1L + +#define SN_md2WithRSAEncryption "RSA-MD2" +#define LN_md2WithRSAEncryption "md2WithRSAEncryption" +#define NID_md2WithRSAEncryption 7 +#define OBJ_md2WithRSAEncryption OBJ_pkcs,1L,2L + +#define SN_md5WithRSAEncryption "RSA-MD5" +#define LN_md5WithRSAEncryption "md5WithRSAEncryption" +#define NID_md5WithRSAEncryption 8 +#define OBJ_md5WithRSAEncryption OBJ_pkcs,1L,4L + +#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES" +#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC" +#define NID_pbeWithMD2AndDES_CBC 9 +#define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs,5L,1L + +#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES" +#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC" +#define NID_pbeWithMD5AndDES_CBC 10 +#define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs,5L,3L + +#define LN_X500 "X500" +#define NID_X500 11 +#define OBJ_X500 2L,5L + +#define LN_X509 "X509" +#define NID_X509 12 +#define OBJ_X509 OBJ_X500,4L + +#define SN_commonName "CN" +#define LN_commonName "commonName" +#define NID_commonName 13 +#define OBJ_commonName OBJ_X509,3L + +#define SN_countryName "C" +#define LN_countryName "countryName" +#define NID_countryName 14 +#define OBJ_countryName OBJ_X509,6L + +#define SN_localityName "L" +#define LN_localityName "localityName" +#define NID_localityName 15 +#define OBJ_localityName OBJ_X509,7L + +/* Postal Address? PA */ + +/* should be "ST" (rfc1327) but MS uses 'S' */ +#define SN_stateOrProvinceName "ST" +#define LN_stateOrProvinceName "stateOrProvinceName" +#define NID_stateOrProvinceName 16 +#define OBJ_stateOrProvinceName OBJ_X509,8L + +#define SN_organizationName "O" +#define LN_organizationName "organizationName" +#define NID_organizationName 17 +#define OBJ_organizationName OBJ_X509,10L + +#define SN_organizationalUnitName "OU" +#define LN_organizationalUnitName "organizationalUnitName" +#define NID_organizationalUnitName 18 +#define OBJ_organizationalUnitName OBJ_X509,11L + +#define SN_rsa "RSA" +#define LN_rsa "rsa" +#define NID_rsa 19 +#define OBJ_rsa OBJ_X500,8L,1L,1L + +#define LN_pkcs7 "pkcs7" +#define NID_pkcs7 20 +#define OBJ_pkcs7 OBJ_pkcs,7L + +#define LN_pkcs7_data "pkcs7-data" +#define NID_pkcs7_data 21 +#define OBJ_pkcs7_data OBJ_pkcs7,1L + +#define LN_pkcs7_signed "pkcs7-signedData" +#define NID_pkcs7_signed 22 +#define OBJ_pkcs7_signed OBJ_pkcs7,2L + +#define LN_pkcs7_enveloped "pkcs7-envelopedData" +#define NID_pkcs7_enveloped 23 +#define OBJ_pkcs7_enveloped OBJ_pkcs7,3L + +#define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData" +#define NID_pkcs7_signedAndEnveloped 24 +#define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L + +#define LN_pkcs7_digest "pkcs7-digestData" +#define NID_pkcs7_digest 25 +#define OBJ_pkcs7_digest OBJ_pkcs7,5L + +#define LN_pkcs7_encrypted "pkcs7-encryptedData" +#define NID_pkcs7_encrypted 26 +#define OBJ_pkcs7_encrypted OBJ_pkcs7,6L + +#define LN_pkcs3 "pkcs3" +#define NID_pkcs3 27 +#define OBJ_pkcs3 OBJ_pkcs,3L + +#define LN_dhKeyAgreement "dhKeyAgreement" +#define NID_dhKeyAgreement 28 +#define OBJ_dhKeyAgreement OBJ_pkcs3,1L + +#define SN_des_ecb "DES-ECB" +#define LN_des_ecb "des-ecb" +#define NID_des_ecb 29 +#define OBJ_des_ecb OBJ_algorithm,6L + +#define SN_des_cfb64 "DES-CFB" +#define LN_des_cfb64 "des-cfb" +#define NID_des_cfb64 30 +/* IV + num */ +#define OBJ_des_cfb64 OBJ_algorithm,9L + +#define SN_des_cbc "DES-CBC" +#define LN_des_cbc "des-cbc" +#define NID_des_cbc 31 +/* IV */ +#define OBJ_des_cbc OBJ_algorithm,7L + +#define SN_des_ede "DES-EDE" +#define LN_des_ede "des-ede" +#define NID_des_ede 32 +/* ?? */ +#define OBJ_des_ede OBJ_algorithm,17L + +#define SN_des_ede3 "DES-EDE3" +#define LN_des_ede3 "des-ede3" +#define NID_des_ede3 33 + +#define SN_idea_cbc "IDEA-CBC" +#define LN_idea_cbc "idea-cbc" +#define NID_idea_cbc 34 +#define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L + +#define SN_idea_cfb64 "IDEA-CFB" +#define LN_idea_cfb64 "idea-cfb" +#define NID_idea_cfb64 35 + +#define SN_idea_ecb "IDEA-ECB" +#define LN_idea_ecb "idea-ecb" +#define NID_idea_ecb 36 + +#define SN_rc2_cbc "RC2-CBC" +#define LN_rc2_cbc "rc2-cbc" +#define NID_rc2_cbc 37 +#define OBJ_rc2_cbc OBJ_rsadsi,3L,2L + +#define SN_rc2_ecb "RC2-ECB" +#define LN_rc2_ecb "rc2-ecb" +#define NID_rc2_ecb 38 + +#define SN_rc2_cfb64 "RC2-CFB" +#define LN_rc2_cfb64 "rc2-cfb" +#define NID_rc2_cfb64 39 + +#define SN_rc2_ofb64 "RC2-OFB" +#define LN_rc2_ofb64 "rc2-ofb" +#define NID_rc2_ofb64 40 + +#define SN_sha "SHA" +#define LN_sha "sha" +#define NID_sha 41 +#define OBJ_sha OBJ_algorithm,18L + +#define SN_shaWithRSAEncryption "RSA-SHA" +#define LN_shaWithRSAEncryption "shaWithRSAEncryption" +#define NID_shaWithRSAEncryption 42 +#define OBJ_shaWithRSAEncryption OBJ_algorithm,15L + +#define SN_des_ede_cbc "DES-EDE-CBC" +#define LN_des_ede_cbc "des-ede-cbc" +#define NID_des_ede_cbc 43 + +#define SN_des_ede3_cbc "DES-EDE3-CBC" +#define LN_des_ede3_cbc "des-ede3-cbc" +#define NID_des_ede3_cbc 44 +#define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L + +#define SN_des_ofb64 "DES-OFB" +#define LN_des_ofb64 "des-ofb" +#define NID_des_ofb64 45 +#define OBJ_des_ofb64 OBJ_algorithm,8L + +#define SN_idea_ofb64 "IDEA-OFB" +#define LN_idea_ofb64 "idea-ofb" +#define NID_idea_ofb64 46 + +#define LN_pkcs9 "pkcs9" +#define NID_pkcs9 47 +#define OBJ_pkcs9 OBJ_pkcs,9L + +#define SN_pkcs9_emailAddress "Email" +#define LN_pkcs9_emailAddress "emailAddress" +#define NID_pkcs9_emailAddress 48 +#define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L + +#define LN_pkcs9_unstructuredName "unstructuredName" +#define NID_pkcs9_unstructuredName 49 +#define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L + +#define LN_pkcs9_contentType "contentType" +#define NID_pkcs9_contentType 50 +#define OBJ_pkcs9_contentType OBJ_pkcs9,3L + +#define LN_pkcs9_messageDigest "messageDigest" +#define NID_pkcs9_messageDigest 51 +#define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L + +#define LN_pkcs9_signingTime "signingTime" +#define NID_pkcs9_signingTime 52 +#define OBJ_pkcs9_signingTime OBJ_pkcs9,5L + +#define LN_pkcs9_countersignature "countersignature" +#define NID_pkcs9_countersignature 53 +#define OBJ_pkcs9_countersignature OBJ_pkcs9,6L + +#define LN_pkcs9_challengePassword "challengePassword" +#define NID_pkcs9_challengePassword 54 +#define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L + +#define LN_pkcs9_unstructuredAddress "unstructuredAddress" +#define NID_pkcs9_unstructuredAddress 55 +#define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L + +#define LN_pkcs9_extCertAttributes "extendedCertificateAttributes" +#define NID_pkcs9_extCertAttributes 56 +#define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L + +#define SN_netscape "Netscape" +#define LN_netscape "Netscape Communications Corp." +#define NID_netscape 57 +#define OBJ_netscape 2L,16L,840L,1L,113730L + +#define SN_netscape_cert_extension "nsCertExt" +#define LN_netscape_cert_extension "Netscape Certificate Extension" +#define NID_netscape_cert_extension 58 +#define OBJ_netscape_cert_extension OBJ_netscape,1L + +#define SN_netscape_data_type "nsDataType" +#define LN_netscape_data_type "Netscape Data Type" +#define NID_netscape_data_type 59 +#define OBJ_netscape_data_type OBJ_netscape,2L + +#define SN_des_ede_cfb64 "DES-EDE-CFB" +#define LN_des_ede_cfb64 "des-ede-cfb" +#define NID_des_ede_cfb64 60 + +#define SN_des_ede3_cfb64 "DES-EDE3-CFB" +#define LN_des_ede3_cfb64 "des-ede3-cfb" +#define NID_des_ede3_cfb64 61 + +#define SN_des_ede_ofb64 "DES-EDE-OFB" +#define LN_des_ede_ofb64 "des-ede-ofb" +#define NID_des_ede_ofb64 62 + +#define SN_des_ede3_ofb64 "DES-EDE3-OFB" +#define LN_des_ede3_ofb64 "des-ede3-ofb" +#define NID_des_ede3_ofb64 63 + +/* I'm not sure about the object ID */ +#define SN_sha1 "SHA1" +#define LN_sha1 "sha1" +#define NID_sha1 64 +#define OBJ_sha1 OBJ_algorithm,26L +/* 28 Jun 1996 - eay */ +/* #define OBJ_sha1 1L,3L,14L,2L,26L,05L <- wrong */ + +#define SN_sha1WithRSAEncryption "RSA-SHA1" +#define LN_sha1WithRSAEncryption "sha1WithRSAEncryption" +#define NID_sha1WithRSAEncryption 65 +#define OBJ_sha1WithRSAEncryption OBJ_pkcs,1L,5L + +#define SN_dsaWithSHA "DSA-SHA" +#define LN_dsaWithSHA "dsaWithSHA" +#define NID_dsaWithSHA 66 +#define OBJ_dsaWithSHA OBJ_algorithm,13L + +#define SN_dsa_2 "DSA-old" +#define LN_dsa_2 "dsaEncryption-old" +#define NID_dsa_2 67 +#define OBJ_dsa_2 OBJ_algorithm,12L + +/* proposed by microsoft to RSA */ +#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64" +#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC" +#define NID_pbeWithSHA1AndRC2_CBC 68 +#define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs,5L,11L + +/* proposed by microsoft to RSA as pbeWithSHA1AndRC4: it is now + * defined explicitly in PKCS#5 v2.0 as id-PBKDF2 which is something + * completely different. + */ +#define LN_id_pbkdf2 "PBKDF2" +#define NID_id_pbkdf2 69 +#define OBJ_id_pbkdf2 OBJ_pkcs,5L,12L + +#define SN_dsaWithSHA1_2 "DSA-SHA1-old" +#define LN_dsaWithSHA1_2 "dsaWithSHA1-old" +#define NID_dsaWithSHA1_2 70 +/* Got this one from 'sdn706r20.pdf' which is actually an NSA document :-) */ +#define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L + +#define SN_netscape_cert_type "nsCertType" +#define LN_netscape_cert_type "Netscape Cert Type" +#define NID_netscape_cert_type 71 +#define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L + +#define SN_netscape_base_url "nsBaseUrl" +#define LN_netscape_base_url "Netscape Base Url" +#define NID_netscape_base_url 72 +#define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L + +#define SN_netscape_revocation_url "nsRevocationUrl" +#define LN_netscape_revocation_url "Netscape Revocation Url" +#define NID_netscape_revocation_url 73 +#define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L + +#define SN_netscape_ca_revocation_url "nsCaRevocationUrl" +#define LN_netscape_ca_revocation_url "Netscape CA Revocation Url" +#define NID_netscape_ca_revocation_url 74 +#define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L + +#define SN_netscape_renewal_url "nsRenewalUrl" +#define LN_netscape_renewal_url "Netscape Renewal Url" +#define NID_netscape_renewal_url 75 +#define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L + +#define SN_netscape_ca_policy_url "nsCaPolicyUrl" +#define LN_netscape_ca_policy_url "Netscape CA Policy Url" +#define NID_netscape_ca_policy_url 76 +#define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L + +#define SN_netscape_ssl_server_name "nsSslServerName" +#define LN_netscape_ssl_server_name "Netscape SSL Server Name" +#define NID_netscape_ssl_server_name 77 +#define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L + +#define SN_netscape_comment "nsComment" +#define LN_netscape_comment "Netscape Comment" +#define NID_netscape_comment 78 +#define OBJ_netscape_comment OBJ_netscape_cert_extension,13L + +#define SN_netscape_cert_sequence "nsCertSequence" +#define LN_netscape_cert_sequence "Netscape Certificate Sequence" +#define NID_netscape_cert_sequence 79 +#define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L + +#define SN_desx_cbc "DESX-CBC" +#define LN_desx_cbc "desx-cbc" +#define NID_desx_cbc 80 + +#define SN_id_ce "id-ce" +#define NID_id_ce 81 +#define OBJ_id_ce 2L,5L,29L + +#define SN_subject_key_identifier "subjectKeyIdentifier" +#define LN_subject_key_identifier "X509v3 Subject Key Identifier" +#define NID_subject_key_identifier 82 +#define OBJ_subject_key_identifier OBJ_id_ce,14L + +#define SN_key_usage "keyUsage" +#define LN_key_usage "X509v3 Key Usage" +#define NID_key_usage 83 +#define OBJ_key_usage OBJ_id_ce,15L + +#define SN_private_key_usage_period "privateKeyUsagePeriod" +#define LN_private_key_usage_period "X509v3 Private Key Usage Period" +#define NID_private_key_usage_period 84 +#define OBJ_private_key_usage_period OBJ_id_ce,16L + +#define SN_subject_alt_name "subjectAltName" +#define LN_subject_alt_name "X509v3 Subject Alternative Name" +#define NID_subject_alt_name 85 +#define OBJ_subject_alt_name OBJ_id_ce,17L + +#define SN_issuer_alt_name "issuerAltName" +#define LN_issuer_alt_name "X509v3 Issuer Alternative Name" +#define NID_issuer_alt_name 86 +#define OBJ_issuer_alt_name OBJ_id_ce,18L + +#define SN_basic_constraints "basicConstraints" +#define LN_basic_constraints "X509v3 Basic Constraints" +#define NID_basic_constraints 87 +#define OBJ_basic_constraints OBJ_id_ce,19L + +#define SN_crl_number "crlNumber" +#define LN_crl_number "X509v3 CRL Number" +#define NID_crl_number 88 +#define OBJ_crl_number OBJ_id_ce,20L + +#define SN_certificate_policies "certificatePolicies" +#define LN_certificate_policies "X509v3 Certificate Policies" +#define NID_certificate_policies 89 +#define OBJ_certificate_policies OBJ_id_ce,32L + +#define SN_authority_key_identifier "authorityKeyIdentifier" +#define LN_authority_key_identifier "X509v3 Authority Key Identifier" +#define NID_authority_key_identifier 90 +#define OBJ_authority_key_identifier OBJ_id_ce,35L + +#define SN_bf_cbc "BF-CBC" +#define LN_bf_cbc "bf-cbc" +#define NID_bf_cbc 91 +#define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L + +#define SN_bf_ecb "BF-ECB" +#define LN_bf_ecb "bf-ecb" +#define NID_bf_ecb 92 + +#define SN_bf_cfb64 "BF-CFB" +#define LN_bf_cfb64 "bf-cfb" +#define NID_bf_cfb64 93 + +#define SN_bf_ofb64 "BF-OFB" +#define LN_bf_ofb64 "bf-ofb" +#define NID_bf_ofb64 94 + +#define SN_mdc2 "MDC2" +#define LN_mdc2 "mdc2" +#define NID_mdc2 95 +#define OBJ_mdc2 2L,5L,8L,3L,101L +/* An alternative? 1L,3L,14L,3L,2L,19L */ + +#define SN_mdc2WithRSA "RSA-MDC2" +#define LN_mdc2WithRSA "mdc2withRSA" +#define NID_mdc2WithRSA 96 +#define OBJ_mdc2WithRSA 2L,5L,8L,3L,100L + +#define SN_rc4_40 "RC4-40" +#define LN_rc4_40 "rc4-40" +#define NID_rc4_40 97 + +#define SN_rc2_40_cbc "RC2-40-CBC" +#define LN_rc2_40_cbc "rc2-40-cbc" +#define NID_rc2_40_cbc 98 + +#define SN_givenName "G" +#define LN_givenName "givenName" +#define NID_givenName 99 +#define OBJ_givenName OBJ_X509,42L + +#define SN_surname "S" +#define LN_surname "surname" +#define NID_surname 100 +#define OBJ_surname OBJ_X509,4L + +#define SN_initials "I" +#define LN_initials "initials" +#define NID_initials 101 +#define OBJ_initials OBJ_X509,43L + +#define SN_uniqueIdentifier "UID" +#define LN_uniqueIdentifier "uniqueIdentifier" +#define NID_uniqueIdentifier 102 +#define OBJ_uniqueIdentifier OBJ_X509,45L + +#define SN_crl_distribution_points "crlDistributionPoints" +#define LN_crl_distribution_points "X509v3 CRL Distribution Points" +#define NID_crl_distribution_points 103 +#define OBJ_crl_distribution_points OBJ_id_ce,31L + +#define SN_md5WithRSA "RSA-NP-MD5" +#define LN_md5WithRSA "md5WithRSA" +#define NID_md5WithRSA 104 +#define OBJ_md5WithRSA OBJ_algorithm,3L + +#define SN_serialNumber "SN" +#define LN_serialNumber "serialNumber" +#define NID_serialNumber 105 +#define OBJ_serialNumber OBJ_X509,5L + +#define SN_title "T" +#define LN_title "title" +#define NID_title 106 +#define OBJ_title OBJ_X509,12L + +#define SN_description "D" +#define LN_description "description" +#define NID_description 107 +#define OBJ_description OBJ_X509,13L + +/* CAST5 is CAST-128, I'm just sticking with the documentation */ +#define SN_cast5_cbc "CAST5-CBC" +#define LN_cast5_cbc "cast5-cbc" +#define NID_cast5_cbc 108 +#define OBJ_cast5_cbc 1L,2L,840L,113533L,7L,66L,10L + +#define SN_cast5_ecb "CAST5-ECB" +#define LN_cast5_ecb "cast5-ecb" +#define NID_cast5_ecb 109 + +#define SN_cast5_cfb64 "CAST5-CFB" +#define LN_cast5_cfb64 "cast5-cfb" +#define NID_cast5_cfb64 110 + +#define SN_cast5_ofb64 "CAST5-OFB" +#define LN_cast5_ofb64 "cast5-ofb" +#define NID_cast5_ofb64 111 + +#define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC" +#define NID_pbeWithMD5AndCast5_CBC 112 +#define OBJ_pbeWithMD5AndCast5_CBC 1L,2L,840L,113533L,7L,66L,12L + +/* This is one sun will soon be using :-( + * id-dsa-with-sha1 ID ::= { + * iso(1) member-body(2) us(840) x9-57 (10040) x9cm(4) 3 } + */ +#define SN_dsaWithSHA1 "DSA-SHA1" +#define LN_dsaWithSHA1 "dsaWithSHA1" +#define NID_dsaWithSHA1 113 +#define OBJ_dsaWithSHA1 1L,2L,840L,10040L,4L,3L + +#define NID_md5_sha1 114 +#define SN_md5_sha1 "MD5-SHA1" +#define LN_md5_sha1 "md5-sha1" + +#define SN_sha1WithRSA "RSA-SHA1-2" +#define LN_sha1WithRSA "sha1WithRSA" +#define NID_sha1WithRSA 115 +#define OBJ_sha1WithRSA OBJ_algorithm,29L + +#define SN_dsa "DSA" +#define LN_dsa "dsaEncryption" +#define NID_dsa 116 +#define OBJ_dsa 1L,2L,840L,10040L,4L,1L + +#define SN_ripemd160 "RIPEMD160" +#define LN_ripemd160 "ripemd160" +#define NID_ripemd160 117 +#define OBJ_ripemd160 1L,3L,36L,3L,2L,1L + +/* The name should actually be rsaSignatureWithripemd160, but I'm going + * to continue using the convention I'm using with the other ciphers */ +#define SN_ripemd160WithRSA "RSA-RIPEMD160" +#define LN_ripemd160WithRSA "ripemd160WithRSA" +#define NID_ripemd160WithRSA 119 +#define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L + +/* Taken from rfc2040 + * RC5_CBC_Parameters ::= SEQUENCE { + * version INTEGER (v1_0(16)), + * rounds INTEGER (8..127), + * blockSizeInBits INTEGER (64, 128), + * iv OCTET STRING OPTIONAL + * } + */ +#define SN_rc5_cbc "RC5-CBC" +#define LN_rc5_cbc "rc5-cbc" +#define NID_rc5_cbc 120 +#define OBJ_rc5_cbc OBJ_rsadsi,3L,8L + +#define SN_rc5_ecb "RC5-ECB" +#define LN_rc5_ecb "rc5-ecb" +#define NID_rc5_ecb 121 + +#define SN_rc5_cfb64 "RC5-CFB" +#define LN_rc5_cfb64 "rc5-cfb" +#define NID_rc5_cfb64 122 + +#define SN_rc5_ofb64 "RC5-OFB" +#define LN_rc5_ofb64 "rc5-ofb" +#define NID_rc5_ofb64 123 + +#define SN_rle_compression "RLE" +#define LN_rle_compression "run length compression" +#define NID_rle_compression 124 +#define OBJ_rle_compression 1L,1L,1L,1L,666L,1L + +#define SN_zlib_compression "ZLIB" +#define LN_zlib_compression "zlib compression" +#define NID_zlib_compression 125 +#define OBJ_zlib_compression 1L,1L,1L,1L,666L,2L + +#define SN_ext_key_usage "extendedKeyUsage" +#define LN_ext_key_usage "X509v3 Extended Key Usage" +#define NID_ext_key_usage 126 +#define OBJ_ext_key_usage OBJ_id_ce,37 + +#define SN_id_pkix "PKIX" +#define NID_id_pkix 127 +#define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L + +#define SN_id_kp "id-kp" +#define NID_id_kp 128 +#define OBJ_id_kp OBJ_id_pkix,3L + +/* PKIX extended key usage OIDs */ + +#define SN_server_auth "serverAuth" +#define LN_server_auth "TLS Web Server Authentication" +#define NID_server_auth 129 +#define OBJ_server_auth OBJ_id_kp,1L + +#define SN_client_auth "clientAuth" +#define LN_client_auth "TLS Web Client Authentication" +#define NID_client_auth 130 +#define OBJ_client_auth OBJ_id_kp,2L + +#define SN_code_sign "codeSigning" +#define LN_code_sign "Code Signing" +#define NID_code_sign 131 +#define OBJ_code_sign OBJ_id_kp,3L + +#define SN_email_protect "emailProtection" +#define LN_email_protect "E-mail Protection" +#define NID_email_protect 132 +#define OBJ_email_protect OBJ_id_kp,4L + +#define SN_time_stamp "timeStamping" +#define LN_time_stamp "Time Stamping" +#define NID_time_stamp 133 +#define OBJ_time_stamp OBJ_id_kp,8L + +/* Additional extended key usage OIDs: Microsoft */ + +#define SN_ms_code_ind "msCodeInd" +#define LN_ms_code_ind "Microsoft Individual Code Signing" +#define NID_ms_code_ind 134 +#define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L + +#define SN_ms_code_com "msCodeCom" +#define LN_ms_code_com "Microsoft Commercial Code Signing" +#define NID_ms_code_com 135 +#define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L + +#define SN_ms_ctl_sign "msCTLSign" +#define LN_ms_ctl_sign "Microsoft Trust List Signing" +#define NID_ms_ctl_sign 136 +#define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L + +#define SN_ms_sgc "msSGC" +#define LN_ms_sgc "Microsoft Server Gated Crypto" +#define NID_ms_sgc 137 +#define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L + +#define SN_ms_efs "msEFS" +#define LN_ms_efs "Microsoft Encrypted File System" +#define NID_ms_efs 138 +#define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L + +/* Additional usage: Netscape */ + +#define SN_ns_sgc "nsSGC" +#define LN_ns_sgc "Netscape Server Gated Crypto" +#define NID_ns_sgc 139 +#define OBJ_ns_sgc OBJ_netscape,4L,1L + +#define SN_delta_crl "deltaCRL" +#define LN_delta_crl "X509v3 Delta CRL Indicator" +#define NID_delta_crl 140 +#define OBJ_delta_crl OBJ_id_ce,27L + +#define SN_crl_reason "CRLReason" +#define LN_crl_reason "CRL Reason Code" +#define NID_crl_reason 141 +#define OBJ_crl_reason OBJ_id_ce,21L + +#define SN_invalidity_date "invalidityDate" +#define LN_invalidity_date "Invalidity Date" +#define NID_invalidity_date 142 +#define OBJ_invalidity_date OBJ_id_ce,24L + +#define SN_sxnet "SXNetID" +#define LN_sxnet "Strong Extranet ID" +#define NID_sxnet 143 +#define OBJ_sxnet 1L,3L,101L,1L,4L,1L + +/* PKCS12 and related OBJECT IDENTIFIERS */ + +#define OBJ_pkcs12 OBJ_pkcs,12L +#define OBJ_pkcs12_pbeids OBJ_pkcs12, 1 + +#define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128" +#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4" +#define NID_pbe_WithSHA1And128BitRC4 144 +#define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids, 1L + +#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40" +#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4" +#define NID_pbe_WithSHA1And40BitRC4 145 +#define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids, 2L + +#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES" +#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146 +#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids, 3L + +#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES" +#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147 +#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids, 4L + +#define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128" +#define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC" +#define NID_pbe_WithSHA1And128BitRC2_CBC 148 +#define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids, 5L + +#define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40" +#define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC" +#define NID_pbe_WithSHA1And40BitRC2_CBC 149 +#define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids, 6L + +#define OBJ_pkcs12_Version1 OBJ_pkcs12, 10L + +#define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1, 1L + +#define LN_keyBag "keyBag" +#define NID_keyBag 150 +#define OBJ_keyBag OBJ_pkcs12_BagIds, 1L + +#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag" +#define NID_pkcs8ShroudedKeyBag 151 +#define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds, 2L + +#define LN_certBag "certBag" +#define NID_certBag 152 +#define OBJ_certBag OBJ_pkcs12_BagIds, 3L + +#define LN_crlBag "crlBag" +#define NID_crlBag 153 +#define OBJ_crlBag OBJ_pkcs12_BagIds, 4L + +#define LN_secretBag "secretBag" +#define NID_secretBag 154 +#define OBJ_secretBag OBJ_pkcs12_BagIds, 5L + +#define LN_safeContentsBag "safeContentsBag" +#define NID_safeContentsBag 155 +#define OBJ_safeContentsBag OBJ_pkcs12_BagIds, 6L + +#define LN_friendlyName "friendlyName" +#define NID_friendlyName 156 +#define OBJ_friendlyName OBJ_pkcs9, 20L + +#define LN_localKeyID "localKeyID" +#define NID_localKeyID 157 +#define OBJ_localKeyID OBJ_pkcs9, 21L + +#define OBJ_certTypes OBJ_pkcs9, 22L + +#define LN_x509Certificate "x509Certificate" +#define NID_x509Certificate 158 +#define OBJ_x509Certificate OBJ_certTypes, 1L + +#define LN_sdsiCertificate "sdsiCertificate" +#define NID_sdsiCertificate 159 +#define OBJ_sdsiCertificate OBJ_certTypes, 2L + +#define OBJ_crlTypes OBJ_pkcs9, 23L + +#define LN_x509Crl "x509Crl" +#define NID_x509Crl 160 +#define OBJ_x509Crl OBJ_crlTypes, 1L + +/* PKCS#5 v2 OIDs */ + +#define LN_pbes2 "PBES2" +#define NID_pbes2 161 +#define OBJ_pbes2 OBJ_pkcs,5L,13L + +#define LN_pbmac1 "PBMAC1" +#define NID_pbmac1 162 +#define OBJ_pbmac1 OBJ_pkcs,5L,14L + +#define LN_hmacWithSHA1 "hmacWithSHA1" +#define NID_hmacWithSHA1 163 +#define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L + +/* Policy Qualifier Ids */ + +#define LN_id_qt_cps "Policy Qualifier CPS" +#define SN_id_qt_cps "id-qt-cps" +#define NID_id_qt_cps 164 +#define OBJ_id_qt_cps OBJ_id_pkix,2L,1L + +#define LN_id_qt_unotice "Policy Qualifier User Notice" +#define SN_id_qt_unotice "id-qt-unotice" +#define NID_id_qt_unotice 165 +#define OBJ_id_qt_unotice OBJ_id_pkix,2L,2L + +#define SN_rc2_64_cbc "RC2-64-CBC" +#define LN_rc2_64_cbc "rc2-64-cbc" +#define NID_rc2_64_cbc 166 + +#define SN_SMIMECapabilities "SMIME-CAPS" +#define LN_SMIMECapabilities "S/MIME Capabilities" +#define NID_SMIMECapabilities 167 +#define OBJ_SMIMECapabilities OBJ_pkcs9,15L + +#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64" +#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC" +#define NID_pbeWithMD2AndRC2_CBC 168 +#define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs,5L,4L + +#define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64" +#define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC" +#define NID_pbeWithMD5AndRC2_CBC 169 +#define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs,5L,6L + +#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES" +#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC" +#define NID_pbeWithSHA1AndDES_CBC 170 +#define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs,5L,10L + +/* Extension request OIDs */ + +#define LN_ms_ext_req "Microsoft Extension Request" +#define SN_ms_ext_req "msExtReq" +#define NID_ms_ext_req 171 +#define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L + +#define LN_ext_req "Extension Request" +#define SN_ext_req "extReq" +#define NID_ext_req 172 +#define OBJ_ext_req OBJ_pkcs9,14L + +#define SN_name "name" +#define LN_name "name" +#define NID_name 173 +#define OBJ_name OBJ_X509,41L + +#define SN_dnQualifier "dnQualifier" +#define LN_dnQualifier "dnQualifier" +#define NID_dnQualifier 174 +#define OBJ_dnQualifier OBJ_X509,46L + +#define SN_id_pe "id-pe" +#define NID_id_pe 175 +#define OBJ_id_pe OBJ_id_pkix,1L + +#define SN_id_ad "id-ad" +#define NID_id_ad 176 +#define OBJ_id_ad OBJ_id_pkix,48L + +#define SN_info_access "authorityInfoAccess" +#define LN_info_access "Authority Information Access" +#define NID_info_access 177 +#define OBJ_info_access OBJ_id_pe,1L + +#define SN_ad_OCSP "OCSP" +#define LN_ad_OCSP "OCSP" +#define NID_ad_OCSP 178 +#define OBJ_ad_OCSP OBJ_id_ad,1L + +#define SN_ad_ca_issuers "caIssuers" +#define LN_ad_ca_issuers "CA Issuers" +#define NID_ad_ca_issuers 179 +#define OBJ_ad_ca_issuers OBJ_id_ad,2L + +#define SN_OCSP_sign "OCSPSigning" +#define LN_OCSP_sign "OCSP Signing" +#define NID_OCSP_sign 180 +#define OBJ_OCSP_sign OBJ_id_kp,9L +#endif /* USE_OBJ_MAC */ + +#include +#include + +#define OBJ_NAME_TYPE_UNDEF 0x00 +#define OBJ_NAME_TYPE_MD_METH 0x01 +#define OBJ_NAME_TYPE_CIPHER_METH 0x02 +#define OBJ_NAME_TYPE_PKEY_METH 0x03 +#define OBJ_NAME_TYPE_COMP_METH 0x04 +#define OBJ_NAME_TYPE_NUM 0x05 + +#define OBJ_NAME_ALIAS 0x8000 + +#define OBJ_BSEARCH_VALUE_ON_NOMATCH 0x01 +#define OBJ_BSEARCH_FIRST_VALUE_ON_MATCH 0x02 + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct obj_name_st { + int type; + int alias; + const char *name; + const char *data; +} OBJ_NAME; + +#define OBJ_create_and_add_object(a,b,c) OBJ_create(a,b,c) + + +int OBJ_NAME_init(void); +int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *), + int (*cmp_func)(const char *, const char *), + void (*free_func)(const char *, int, const char *)); +const char *OBJ_NAME_get(const char *name, int type); +int OBJ_NAME_add(const char *name, int type, const char *data); +int OBJ_NAME_remove(const char *name, int type); +void OBJ_NAME_cleanup(int type); /* -1 for everything */ +void OBJ_NAME_do_all(int type, void (*fn)(const OBJ_NAME *, void *arg), + void *arg); +void OBJ_NAME_do_all_sorted(int type, void (*fn)(const OBJ_NAME *, void *arg), + void *arg); + +ASN1_OBJECT * OBJ_dup(const ASN1_OBJECT *o); +ASN1_OBJECT * OBJ_nid2obj(int n); +const char * OBJ_nid2ln(int n); +const char * OBJ_nid2sn(int n); +int OBJ_obj2nid(const ASN1_OBJECT *o); +ASN1_OBJECT * OBJ_txt2obj(const char *s, int no_name); +int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name); +int OBJ_txt2nid(const char *s); +int OBJ_ln2nid(const char *s); +int OBJ_sn2nid(const char *s); +int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b); +const void * OBJ_bsearch_(const void *key, const void *base, int num, + int size, int (*cmp)(const void *, const void *)); +const void * OBJ_bsearch_ex_(const void *key, const void *base, int num, + int size, int (*cmp)(const void *, const void *), + int flags); + +#define _DECLARE_OBJ_BSEARCH_CMP_FN(scope, type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *, const void *); \ + static int nm##_cmp(type1 const *, type2 const *); \ + scope type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) + +#define DECLARE_OBJ_BSEARCH_CMP_FN(type1, type2, cmp) \ + _DECLARE_OBJ_BSEARCH_CMP_FN(static, type1, type2, cmp) +#define DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \ + type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) + +/* + * Unsolved problem: if a type is actually a pointer type, like + * nid_triple is, then its impossible to get a const where you need + * it. Consider: + * + * typedef int nid_triple[3]; + * const void *a_; + * const nid_triple const *a = a_; + * + * The assignement discards a const because what you really want is: + * + * const int const * const *a = a_; + * + * But if you do that, you lose the fact that a is an array of 3 ints, + * which breaks comparison functions. + * + * Thus we end up having to cast, sadly, or unpack the + * declarations. Or, as I finally did in this case, delcare nid_triple + * to be a struct, which it should have been in the first place. + * + * Ben, August 2008. + * + * Also, strictly speaking not all types need be const, but handling + * the non-constness means a lot of complication, and in practice + * comparison routines do always not touch their arguments. + */ + +#define IMPLEMENT_OBJ_BSEARCH_CMP_FN(type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \ + { \ + type1 const *a = a_; \ + type2 const *b = b_; \ + return nm##_cmp(a,b); \ + } \ + static type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \ + { \ + return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \ + nm##_cmp_BSEARCH_CMP_FN); \ + } \ + extern void dummy_prototype(void) + +#define IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \ + { \ + type1 const *a = a_; \ + type2 const *b = b_; \ + return nm##_cmp(a,b); \ + } \ + type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \ + { \ + return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \ + nm##_cmp_BSEARCH_CMP_FN); \ + } \ + extern void dummy_prototype(void) + +#define OBJ_bsearch(type1,key,type2,base,num,cmp) \ + ((type2 *)OBJ_bsearch_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \ + num,sizeof(type2), \ + ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \ + (void)CHECKED_PTR_OF(type2,cmp##_type_2), \ + cmp##_BSEARCH_CMP_FN))) + +#define OBJ_bsearch_ex(type1,key,type2,base,num,cmp,flags) \ + ((type2 *)OBJ_bsearch_ex_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \ + num,sizeof(type2), \ + ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \ + (void)type_2=CHECKED_PTR_OF(type2,cmp##_type_2), \ + cmp##_BSEARCH_CMP_FN)),flags) + +int OBJ_new_nid(int num); +int OBJ_add_object(const ASN1_OBJECT *obj); +int OBJ_create(const char *oid, const char *sn, const char *ln); +void OBJ_cleanup(void ); +int OBJ_create_objects(BIO *in); + +int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid); +int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid); +int OBJ_add_sigid(int signid, int dig_id, int pkey_id); +void OBJ_sigid_free(void); + +extern int obj_cleanup_defer; +void check_defer(int nid); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_OBJ_strings(void); + +/* Error codes for the OBJ functions. */ + +/* Function codes. */ +#define OBJ_F_OBJ_ADD_OBJECT 105 +#define OBJ_F_OBJ_CREATE 100 +#define OBJ_F_OBJ_DUP 101 +#define OBJ_F_OBJ_NAME_NEW_INDEX 106 +#define OBJ_F_OBJ_NID2LN 102 +#define OBJ_F_OBJ_NID2OBJ 103 +#define OBJ_F_OBJ_NID2SN 104 + +/* Reason codes. */ +#define OBJ_R_MALLOC_FAILURE 100 +#define OBJ_R_UNKNOWN_NID 101 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/ocsp.h b/crypto/libressl/include/openssl/ocsp.h new file mode 100644 index 0000000000..1d78fd5aa8 --- /dev/null +++ b/crypto/libressl/include/openssl/ocsp.h @@ -0,0 +1,615 @@ +/* $OpenBSD: ocsp.h,v 1.6 2014/06/12 15:49:30 deraadt Exp $ */ +/* Written by Tom Titchener for the OpenSSL + * project. */ + +/* History: + This file was transfered to Richard Levitte from CertCo by Kathy + Weinhold in mid-spring 2000 to be included in OpenSSL or released + as a patch kit. */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_OCSP_H +#define HEADER_OCSP_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Various flags and values */ + +#define OCSP_DEFAULT_NONCE_LENGTH 16 + +#define OCSP_NOCERTS 0x1 +#define OCSP_NOINTERN 0x2 +#define OCSP_NOSIGS 0x4 +#define OCSP_NOCHAIN 0x8 +#define OCSP_NOVERIFY 0x10 +#define OCSP_NOEXPLICIT 0x20 +#define OCSP_NOCASIGN 0x40 +#define OCSP_NODELEGATED 0x80 +#define OCSP_NOCHECKS 0x100 +#define OCSP_TRUSTOTHER 0x200 +#define OCSP_RESPID_KEY 0x400 +#define OCSP_NOTIME 0x800 + +/* CertID ::= SEQUENCE { + * hashAlgorithm AlgorithmIdentifier, + * issuerNameHash OCTET STRING, -- Hash of Issuer's DN + * issuerKeyHash OCTET STRING, -- Hash of Issuers public key (excluding the tag & length fields) + * serialNumber CertificateSerialNumber } + */ +typedef struct ocsp_cert_id_st { + X509_ALGOR *hashAlgorithm; + ASN1_OCTET_STRING *issuerNameHash; + ASN1_OCTET_STRING *issuerKeyHash; + ASN1_INTEGER *serialNumber; +} OCSP_CERTID; + +DECLARE_STACK_OF(OCSP_CERTID) + +/* Request ::= SEQUENCE { + * reqCert CertID, + * singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL } + */ +typedef struct ocsp_one_request_st { + OCSP_CERTID *reqCert; + STACK_OF(X509_EXTENSION) *singleRequestExtensions; +} OCSP_ONEREQ; + +DECLARE_STACK_OF(OCSP_ONEREQ) +DECLARE_ASN1_SET_OF(OCSP_ONEREQ) + + +/* TBSRequest ::= SEQUENCE { + * version [0] EXPLICIT Version DEFAULT v1, + * requestorName [1] EXPLICIT GeneralName OPTIONAL, + * requestList SEQUENCE OF Request, + * requestExtensions [2] EXPLICIT Extensions OPTIONAL } + */ +typedef struct ocsp_req_info_st { + ASN1_INTEGER *version; + GENERAL_NAME *requestorName; + STACK_OF(OCSP_ONEREQ) *requestList; + STACK_OF(X509_EXTENSION) *requestExtensions; +} OCSP_REQINFO; + +/* Signature ::= SEQUENCE { + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING, + * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } + */ +typedef struct ocsp_signature_st { + X509_ALGOR *signatureAlgorithm; + ASN1_BIT_STRING *signature; + STACK_OF(X509) *certs; +} OCSP_SIGNATURE; + +/* OCSPRequest ::= SEQUENCE { + * tbsRequest TBSRequest, + * optionalSignature [0] EXPLICIT Signature OPTIONAL } + */ +typedef struct ocsp_request_st { + OCSP_REQINFO *tbsRequest; + OCSP_SIGNATURE *optionalSignature; /* OPTIONAL */ +} OCSP_REQUEST; + +/* OCSPResponseStatus ::= ENUMERATED { + * successful (0), --Response has valid confirmations + * malformedRequest (1), --Illegal confirmation request + * internalError (2), --Internal error in issuer + * tryLater (3), --Try again later + * --(4) is not used + * sigRequired (5), --Must sign the request + * unauthorized (6) --Request unauthorized + * } + */ +#define OCSP_RESPONSE_STATUS_SUCCESSFUL 0 +#define OCSP_RESPONSE_STATUS_MALFORMEDREQUEST 1 +#define OCSP_RESPONSE_STATUS_INTERNALERROR 2 +#define OCSP_RESPONSE_STATUS_TRYLATER 3 +#define OCSP_RESPONSE_STATUS_SIGREQUIRED 5 +#define OCSP_RESPONSE_STATUS_UNAUTHORIZED 6 + +/* ResponseBytes ::= SEQUENCE { + * responseType OBJECT IDENTIFIER, + * response OCTET STRING } + */ +typedef struct ocsp_resp_bytes_st { + ASN1_OBJECT *responseType; + ASN1_OCTET_STRING *response; +} OCSP_RESPBYTES; + +/* OCSPResponse ::= SEQUENCE { + * responseStatus OCSPResponseStatus, + * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL } + */ +struct ocsp_response_st { + ASN1_ENUMERATED *responseStatus; + OCSP_RESPBYTES *responseBytes; +}; + +/* ResponderID ::= CHOICE { + * byName [1] Name, + * byKey [2] KeyHash } + */ +#define V_OCSP_RESPID_NAME 0 +#define V_OCSP_RESPID_KEY 1 +struct ocsp_responder_id_st { + int type; + union { + X509_NAME* byName; + ASN1_OCTET_STRING *byKey; + } value; +}; + +DECLARE_STACK_OF(OCSP_RESPID) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPID) + +/* KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key + * --(excluding the tag and length fields) + */ + +/* RevokedInfo ::= SEQUENCE { + * revocationTime GeneralizedTime, + * revocationReason [0] EXPLICIT CRLReason OPTIONAL } + */ +typedef struct ocsp_revoked_info_st { + ASN1_GENERALIZEDTIME *revocationTime; + ASN1_ENUMERATED *revocationReason; +} OCSP_REVOKEDINFO; + +/* CertStatus ::= CHOICE { + * good [0] IMPLICIT NULL, + * revoked [1] IMPLICIT RevokedInfo, + * unknown [2] IMPLICIT UnknownInfo } + */ +#define V_OCSP_CERTSTATUS_GOOD 0 +#define V_OCSP_CERTSTATUS_REVOKED 1 +#define V_OCSP_CERTSTATUS_UNKNOWN 2 +typedef struct ocsp_cert_status_st { + int type; + union { + ASN1_NULL *good; + OCSP_REVOKEDINFO *revoked; + ASN1_NULL *unknown; + } value; +} OCSP_CERTSTATUS; + +/* SingleResponse ::= SEQUENCE { + * certID CertID, + * certStatus CertStatus, + * thisUpdate GeneralizedTime, + * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL, + * singleExtensions [1] EXPLICIT Extensions OPTIONAL } + */ +typedef struct ocsp_single_response_st { + OCSP_CERTID *certId; + OCSP_CERTSTATUS *certStatus; + ASN1_GENERALIZEDTIME *thisUpdate; + ASN1_GENERALIZEDTIME *nextUpdate; + STACK_OF(X509_EXTENSION) *singleExtensions; +} OCSP_SINGLERESP; + +DECLARE_STACK_OF(OCSP_SINGLERESP) +DECLARE_ASN1_SET_OF(OCSP_SINGLERESP) + +/* ResponseData ::= SEQUENCE { + * version [0] EXPLICIT Version DEFAULT v1, + * responderID ResponderID, + * producedAt GeneralizedTime, + * responses SEQUENCE OF SingleResponse, + * responseExtensions [1] EXPLICIT Extensions OPTIONAL } + */ +typedef struct ocsp_response_data_st { + ASN1_INTEGER *version; + OCSP_RESPID *responderId; + ASN1_GENERALIZEDTIME *producedAt; + STACK_OF(OCSP_SINGLERESP) *responses; + STACK_OF(X509_EXTENSION) *responseExtensions; +} OCSP_RESPDATA; + +/* BasicOCSPResponse ::= SEQUENCE { + * tbsResponseData ResponseData, + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING, + * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } + */ + /* Note 1: + The value for "signature" is specified in the OCSP rfc2560 as follows: + "The value for the signature SHALL be computed on the hash of the DER + encoding ResponseData." This means that you must hash the DER-encoded + tbsResponseData, and then run it through a crypto-signing function, which + will (at least w/RSA) do a hash-'n'-private-encrypt operation. This seems + a bit odd, but that's the spec. Also note that the data structures do not + leave anywhere to independently specify the algorithm used for the initial + hash. So, we look at the signature-specification algorithm, and try to do + something intelligent. -- Kathy Weinhold, CertCo */ + /* Note 2: + It seems that the mentioned passage from RFC 2560 (section 4.2.1) is open + for interpretation. I've done tests against another responder, and found + that it doesn't do the double hashing that the RFC seems to say one + should. Therefore, all relevant functions take a flag saying which + variant should be used. -- Richard Levitte, OpenSSL team and CeloCom */ +typedef struct ocsp_basic_response_st { + OCSP_RESPDATA *tbsResponseData; + X509_ALGOR *signatureAlgorithm; + ASN1_BIT_STRING *signature; + STACK_OF(X509) *certs; +} OCSP_BASICRESP; + +/* + * CRLReason ::= ENUMERATED { + * unspecified (0), + * keyCompromise (1), + * cACompromise (2), + * affiliationChanged (3), + * superseded (4), + * cessationOfOperation (5), + * certificateHold (6), + * removeFromCRL (8) } + */ +#define OCSP_REVOKED_STATUS_NOSTATUS -1 +#define OCSP_REVOKED_STATUS_UNSPECIFIED 0 +#define OCSP_REVOKED_STATUS_KEYCOMPROMISE 1 +#define OCSP_REVOKED_STATUS_CACOMPROMISE 2 +#define OCSP_REVOKED_STATUS_AFFILIATIONCHANGED 3 +#define OCSP_REVOKED_STATUS_SUPERSEDED 4 +#define OCSP_REVOKED_STATUS_CESSATIONOFOPERATION 5 +#define OCSP_REVOKED_STATUS_CERTIFICATEHOLD 6 +#define OCSP_REVOKED_STATUS_REMOVEFROMCRL 8 + +/* CrlID ::= SEQUENCE { + * crlUrl [0] EXPLICIT IA5String OPTIONAL, + * crlNum [1] EXPLICIT INTEGER OPTIONAL, + * crlTime [2] EXPLICIT GeneralizedTime OPTIONAL } + */ +typedef struct ocsp_crl_id_st { + ASN1_IA5STRING *crlUrl; + ASN1_INTEGER *crlNum; + ASN1_GENERALIZEDTIME *crlTime; +} OCSP_CRLID; + +/* ServiceLocator ::= SEQUENCE { + * issuer Name, + * locator AuthorityInfoAccessSyntax OPTIONAL } + */ +typedef struct ocsp_service_locator_st { + X509_NAME* issuer; + STACK_OF(ACCESS_DESCRIPTION) *locator; +} OCSP_SERVICELOC; + +#define PEM_STRING_OCSP_REQUEST "OCSP REQUEST" +#define PEM_STRING_OCSP_RESPONSE "OCSP RESPONSE" + +#define d2i_OCSP_REQUEST_bio(bp,p) \ + ASN1_d2i_bio_of(OCSP_REQUEST,OCSP_REQUEST_new,d2i_OCSP_REQUEST,bp,p) + +#define d2i_OCSP_RESPONSE_bio(bp,p) \ + ASN1_d2i_bio_of(OCSP_RESPONSE,OCSP_RESPONSE_new,d2i_OCSP_RESPONSE,bp,p) + +#define PEM_read_bio_OCSP_REQUEST(bp,x,cb) \ + (OCSP_REQUEST *)PEM_ASN1_read_bio((char *(*)())d2i_OCSP_REQUEST, \ + PEM_STRING_OCSP_REQUEST,bp,(char **)x,cb,NULL) + +#define PEM_read_bio_OCSP_RESPONSE(bp,x,cb) \ + (OCSP_RESPONSE *)PEM_ASN1_read_bio((char *(*)())d2i_OCSP_RESPONSE, \ + PEM_STRING_OCSP_RESPONSE,bp,(char **)x,cb,NULL) + +#define PEM_write_bio_OCSP_REQUEST(bp,o) \ + PEM_ASN1_write_bio((int (*)())i2d_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,\ + bp,(char *)o, NULL,NULL,0,NULL,NULL) + +#define PEM_write_bio_OCSP_RESPONSE(bp,o) \ + PEM_ASN1_write_bio((int (*)())i2d_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,\ + bp,(char *)o, NULL,NULL,0,NULL,NULL) + +#define i2d_OCSP_RESPONSE_bio(bp,o) \ + ASN1_i2d_bio_of(OCSP_RESPONSE,i2d_OCSP_RESPONSE,bp,o) + +#define i2d_OCSP_REQUEST_bio(bp,o) \ + ASN1_i2d_bio_of(OCSP_REQUEST,i2d_OCSP_REQUEST,bp,o) + +#define OCSP_REQUEST_sign(o,pkey,md) \ + ASN1_item_sign(ASN1_ITEM_rptr(OCSP_REQINFO), \ + o->optionalSignature->signatureAlgorithm,NULL, \ + o->optionalSignature->signature,o->tbsRequest,pkey,md) + +#define OCSP_BASICRESP_sign(o,pkey,md,d) \ + ASN1_item_sign(ASN1_ITEM_rptr(OCSP_RESPDATA),o->signatureAlgorithm,NULL, \ + o->signature,o->tbsResponseData,pkey,md) + +#define OCSP_REQUEST_verify(a,r) \ + ASN1_item_verify(ASN1_ITEM_rptr(OCSP_REQINFO), \ + a->optionalSignature->signatureAlgorithm, \ + a->optionalSignature->signature,a->tbsRequest,r) + +#define OCSP_BASICRESP_verify(a,r,d) \ + ASN1_item_verify(ASN1_ITEM_rptr(OCSP_RESPDATA), \ + a->signatureAlgorithm,a->signature,a->tbsResponseData,r) + +#define ASN1_BIT_STRING_digest(data,type,md,len) \ + ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len) + +#define OCSP_CERTSTATUS_dup(cs) \ + ASN1_item_dup(&OCSP_CERTSTATUS_it, cs) + +OCSP_CERTID *OCSP_CERTID_dup(OCSP_CERTID *id); + +OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, char *path, OCSP_REQUEST *req); +OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req, + int maxline); +int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx); +void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx); +int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req); +int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, const char *name, + const char *value); + +OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer); + +OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, X509_NAME *issuerName, + ASN1_BIT_STRING* issuerKey, ASN1_INTEGER *serialNumber); + +OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid); + +int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len); +int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len); +int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs); +int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req); + +int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm); +int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert); + +int OCSP_request_sign(OCSP_REQUEST *req, X509 *signer, EVP_PKEY *key, + const EVP_MD *dgst, STACK_OF(X509) *certs, unsigned long flags); + +int OCSP_response_status(OCSP_RESPONSE *resp); +OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp); + +int OCSP_resp_count(OCSP_BASICRESP *bs); +OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx); +int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last); +int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, + ASN1_GENERALIZEDTIME **revtime, ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd); +int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, + int *reason, ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, ASN1_GENERALIZEDTIME **nextupd); +int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, + ASN1_GENERALIZEDTIME *nextupd, long sec, long maxsec); + +int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, + X509_STORE *store, unsigned long flags); + +int OCSP_parse_url(char *url, char **phost, char **pport, char **ppath, + int *pssl); + +int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b); +int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b); + +int OCSP_request_onereq_count(OCSP_REQUEST *req); +OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i); +OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one); +int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, + ASN1_OCTET_STRING **pikeyHash, ASN1_INTEGER **pserial, + OCSP_CERTID *cid); +int OCSP_request_is_signed(OCSP_REQUEST *req); +OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs); +OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp, OCSP_CERTID *cid, + int status, int reason, ASN1_TIME *revtime, ASN1_TIME *thisupd, + ASN1_TIME *nextupd); +int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert); +int OCSP_basic_sign(OCSP_BASICRESP *brsp, X509 *signer, EVP_PKEY *key, + const EVP_MD *dgst, STACK_OF(X509) *certs, unsigned long flags); + +X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim); + +X509_EXTENSION *OCSP_accept_responses_new(char **oids); + +X509_EXTENSION *OCSP_archive_cutoff_new(char* tim); + +X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME* issuer, char **urls); + +int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x); +int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos); +int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, + int lastpos); +int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, + int lastpos); +X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc); +X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc); +void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx); +int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, + int crit, unsigned long flags); +int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc); + +int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x); +int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos); +int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, + int lastpos); +int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos); +X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc); +X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc); +void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx); +int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, + unsigned long flags); +int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc); + +int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x); +int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos); +int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, + int lastpos); +int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, + int lastpos); +X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc); +X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc); +void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, + int *idx); +int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, + int crit, unsigned long flags); +int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc); + +int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x); +int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, + int lastpos); +int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, + int lastpos); +int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, + int lastpos); +X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc); +X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc); +void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, + int *idx); +int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, + int crit, unsigned long flags); +int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, + int loc); + +DECLARE_ASN1_FUNCTIONS(OCSP_SINGLERESP) +DECLARE_ASN1_FUNCTIONS(OCSP_CERTSTATUS) +DECLARE_ASN1_FUNCTIONS(OCSP_REVOKEDINFO) +DECLARE_ASN1_FUNCTIONS(OCSP_BASICRESP) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPDATA) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPID) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPONSE) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPBYTES) +DECLARE_ASN1_FUNCTIONS(OCSP_ONEREQ) +DECLARE_ASN1_FUNCTIONS(OCSP_CERTID) +DECLARE_ASN1_FUNCTIONS(OCSP_REQUEST) +DECLARE_ASN1_FUNCTIONS(OCSP_SIGNATURE) +DECLARE_ASN1_FUNCTIONS(OCSP_REQINFO) +DECLARE_ASN1_FUNCTIONS(OCSP_CRLID) +DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC) + +const char *OCSP_response_status_str(long s); +const char *OCSP_cert_status_str(long s); +const char *OCSP_crl_reason_str(long s); + +int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* a, unsigned long flags); +int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags); + +int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, + X509_STORE *st, unsigned long flags); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_OCSP_strings(void); + +/* Error codes for the OCSP functions. */ + +/* Function codes. */ +#define OCSP_F_ASN1_STRING_ENCODE 100 +#define OCSP_F_D2I_OCSP_NONCE 102 +#define OCSP_F_OCSP_BASIC_ADD1_STATUS 103 +#define OCSP_F_OCSP_BASIC_SIGN 104 +#define OCSP_F_OCSP_BASIC_VERIFY 105 +#define OCSP_F_OCSP_CERT_ID_NEW 101 +#define OCSP_F_OCSP_CHECK_DELEGATED 106 +#define OCSP_F_OCSP_CHECK_IDS 107 +#define OCSP_F_OCSP_CHECK_ISSUER 108 +#define OCSP_F_OCSP_CHECK_VALIDITY 115 +#define OCSP_F_OCSP_MATCH_ISSUERID 109 +#define OCSP_F_OCSP_PARSE_URL 114 +#define OCSP_F_OCSP_REQUEST_SIGN 110 +#define OCSP_F_OCSP_REQUEST_VERIFY 116 +#define OCSP_F_OCSP_RESPONSE_GET1_BASIC 111 +#define OCSP_F_OCSP_SENDREQ_BIO 112 +#define OCSP_F_OCSP_SENDREQ_NBIO 117 +#define OCSP_F_PARSE_HTTP_LINE1 118 +#define OCSP_F_REQUEST_VERIFY 113 + +/* Reason codes. */ +#define OCSP_R_BAD_DATA 100 +#define OCSP_R_CERTIFICATE_VERIFY_ERROR 101 +#define OCSP_R_DIGEST_ERR 102 +#define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD 122 +#define OCSP_R_ERROR_IN_THISUPDATE_FIELD 123 +#define OCSP_R_ERROR_PARSING_URL 121 +#define OCSP_R_MISSING_OCSPSIGNING_USAGE 103 +#define OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE 124 +#define OCSP_R_NOT_BASIC_RESPONSE 104 +#define OCSP_R_NO_CERTIFICATES_IN_CHAIN 105 +#define OCSP_R_NO_CONTENT 106 +#define OCSP_R_NO_PUBLIC_KEY 107 +#define OCSP_R_NO_RESPONSE_DATA 108 +#define OCSP_R_NO_REVOKED_TIME 109 +#define OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 110 +#define OCSP_R_REQUEST_NOT_SIGNED 128 +#define OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA 111 +#define OCSP_R_ROOT_CA_NOT_TRUSTED 112 +#define OCSP_R_SERVER_READ_ERROR 113 +#define OCSP_R_SERVER_RESPONSE_ERROR 114 +#define OCSP_R_SERVER_RESPONSE_PARSE_ERROR 115 +#define OCSP_R_SERVER_WRITE_ERROR 116 +#define OCSP_R_SIGNATURE_FAILURE 117 +#define OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND 118 +#define OCSP_R_STATUS_EXPIRED 125 +#define OCSP_R_STATUS_NOT_YET_VALID 126 +#define OCSP_R_STATUS_TOO_OLD 127 +#define OCSP_R_UNKNOWN_MESSAGE_DIGEST 119 +#define OCSP_R_UNKNOWN_NID 120 +#define OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE 129 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/opensslconf.h b/crypto/libressl/include/openssl/opensslconf.h new file mode 100644 index 0000000000..71dbe826e1 --- /dev/null +++ b/crypto/libressl/include/openssl/opensslconf.h @@ -0,0 +1,156 @@ +#include +/* crypto/opensslconf.h.in */ + +#if defined(_MSC_VER) && !defined(__attribute__) +#define __attribute__(a) +#endif + +/* Generate 80386 code? */ +#undef I386_ONLY + +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define OPENSSLDIR "/etc/ssl" +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#define RC4_CHUNK unsigned long +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned int +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#undef BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +#define SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#undef THIRTY_TWO_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#undef RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#undef BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#undef DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependancies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very mucy CPU dependant */ +#ifndef DES_UNROLL +#define DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ diff --git a/crypto/libressl/include/openssl/opensslfeatures.h b/crypto/libressl/include/openssl/opensslfeatures.h new file mode 100644 index 0000000000..ba4dbba959 --- /dev/null +++ b/crypto/libressl/include/openssl/opensslfeatures.h @@ -0,0 +1,26 @@ +# define OPENSSL_NO_EC_NISTP_64_GCC_128 +# define OPENSSL_NO_CMS +# define OPENSSL_NO_COMP +# define OPENSSL_NO_EGD +# define OPENSSL_NO_GMP +# define OPENSSL_NO_JPAKE +# define OPENSSL_NO_KRB5 +# define OPENSSL_NO_MD2 +# define OPENSSL_NO_MDC2 +# define OPENSSL_NO_PSK +# define OPENSSL_NO_RC5 +# define OPENSSL_NO_RFC3779 +# define OPENSSL_NO_RSAX +# define OPENSSL_NO_SCTP +# define OPENSSL_NO_SEED +# define OPENSSL_NO_SHA0 +# define OPENSSL_NO_SRP +# define OPENSSL_NO_SSL2 +# define OPENSSL_NO_SSL3 +# define OPENSSL_NO_SSL3_METHOD +# define OPENSSL_NO_STORE +# define OPENSSL_NO_BUF_FREELISTS +# define OPENSSL_NO_HEARTBEATS +# define OPENSSL_NO_DYNAMIC_ENGINE + +# define OPENSSL_THREADS diff --git a/crypto/libressl/include/openssl/opensslv.h b/crypto/libressl/include/openssl/opensslv.h new file mode 100644 index 0000000000..14239e0a84 --- /dev/null +++ b/crypto/libressl/include/openssl/opensslv.h @@ -0,0 +1,17 @@ +/* $OpenBSD: opensslv.h,v 1.35 2016/06/06 09:50:15 bcook Exp $ */ +#ifndef HEADER_OPENSSLV_H +#define HEADER_OPENSSLV_H + +/* These will change with each release of LibreSSL-portable */ +#define LIBRESSL_VERSION_NUMBER 0x2040200fL +#define LIBRESSL_VERSION_TEXT "LibreSSL 2.4.2" + +/* These will never change */ +#define OPENSSL_VERSION_NUMBER 0x20000000L +#define OPENSSL_VERSION_TEXT LIBRESSL_VERSION_TEXT +#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT + +#define SHLIB_VERSION_HISTORY "" +#define SHLIB_VERSION_NUMBER "1.0.0" + +#endif /* HEADER_OPENSSLV_H */ diff --git a/crypto/libressl/include/openssl/ossl_typ.h b/crypto/libressl/include/openssl/ossl_typ.h new file mode 100644 index 0000000000..3d23fb0a3d --- /dev/null +++ b/crypto/libressl/include/openssl/ossl_typ.h @@ -0,0 +1,190 @@ +/* $OpenBSD: ossl_typ.h,v 1.12 2014/06/12 15:49:27 deraadt Exp $ */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_OPENSSL_TYPES_H +#define HEADER_OPENSSL_TYPES_H + +#include + +typedef struct asn1_string_st ASN1_INTEGER; +typedef struct asn1_string_st ASN1_ENUMERATED; +typedef struct asn1_string_st ASN1_BIT_STRING; +typedef struct asn1_string_st ASN1_OCTET_STRING; +typedef struct asn1_string_st ASN1_PRINTABLESTRING; +typedef struct asn1_string_st ASN1_T61STRING; +typedef struct asn1_string_st ASN1_IA5STRING; +typedef struct asn1_string_st ASN1_GENERALSTRING; +typedef struct asn1_string_st ASN1_UNIVERSALSTRING; +typedef struct asn1_string_st ASN1_BMPSTRING; +typedef struct asn1_string_st ASN1_UTCTIME; +typedef struct asn1_string_st ASN1_TIME; +typedef struct asn1_string_st ASN1_GENERALIZEDTIME; +typedef struct asn1_string_st ASN1_VISIBLESTRING; +typedef struct asn1_string_st ASN1_UTF8STRING; +typedef struct asn1_string_st ASN1_STRING; +typedef int ASN1_BOOLEAN; +typedef int ASN1_NULL; + +typedef struct ASN1_ITEM_st ASN1_ITEM; +typedef struct asn1_pctx_st ASN1_PCTX; + +#if defined(_WIN32) && defined(__WINCRYPT_H__) +#ifndef LIBRESSL_INTERNAL +#ifdef _MSC_VER +#pragma message("Warning, overriding WinCrypt defines") +#else +#warning overriding WinCrypt defines +#endif +#endif +#undef X509_NAME +#undef X509_CERT_PAIR +#undef X509_EXTENSIONS +#undef OCSP_REQUEST +#undef OCSP_RESPONSE +#undef PKCS7_ISSUER_AND_SERIAL +#endif + +#ifdef BIGNUM +#undef BIGNUM +#endif +typedef struct bignum_st BIGNUM; +typedef struct bignum_ctx BN_CTX; +typedef struct bn_blinding_st BN_BLINDING; +typedef struct bn_mont_ctx_st BN_MONT_CTX; +typedef struct bn_recp_ctx_st BN_RECP_CTX; +typedef struct bn_gencb_st BN_GENCB; + +typedef struct buf_mem_st BUF_MEM; + +typedef struct evp_cipher_st EVP_CIPHER; +typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX; +typedef struct env_md_st EVP_MD; +typedef struct env_md_ctx_st EVP_MD_CTX; +typedef struct evp_pkey_st EVP_PKEY; + +typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; + +typedef struct evp_pkey_method_st EVP_PKEY_METHOD; +typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; + +typedef struct dh_st DH; +typedef struct dh_method DH_METHOD; + +typedef struct dsa_st DSA; +typedef struct dsa_method DSA_METHOD; + +typedef struct rsa_st RSA; +typedef struct rsa_meth_st RSA_METHOD; + +typedef struct rand_meth_st RAND_METHOD; + +typedef struct ecdh_method ECDH_METHOD; +typedef struct ecdsa_method ECDSA_METHOD; + +typedef struct x509_st X509; +typedef struct X509_algor_st X509_ALGOR; +typedef struct X509_crl_st X509_CRL; +typedef struct x509_crl_method_st X509_CRL_METHOD; +typedef struct x509_revoked_st X509_REVOKED; +typedef struct X509_name_st X509_NAME; +typedef struct X509_pubkey_st X509_PUBKEY; +typedef struct x509_store_st X509_STORE; +typedef struct x509_store_ctx_st X509_STORE_CTX; + +typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO; + +typedef struct v3_ext_ctx X509V3_CTX; +typedef struct conf_st CONF; + +typedef struct store_st STORE; +typedef struct store_method_st STORE_METHOD; + +typedef struct ui_st UI; +typedef struct ui_method_st UI_METHOD; + +typedef struct st_ERR_FNS ERR_FNS; + +typedef struct engine_st ENGINE; +typedef struct ssl_st SSL; +typedef struct ssl_ctx_st SSL_CTX; + +typedef struct X509_POLICY_NODE_st X509_POLICY_NODE; +typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL; +typedef struct X509_POLICY_TREE_st X509_POLICY_TREE; +typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE; + +typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID; +typedef struct DIST_POINT_st DIST_POINT; +typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT; +typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS; + +/* If placed in pkcs12.h, we end up with a circular depency with pkcs7.h */ +#define DECLARE_PKCS12_STACK_OF(type) /* Nothing */ +#define IMPLEMENT_PKCS12_STACK_OF(type) /* Nothing */ + +typedef struct crypto_ex_data_st CRYPTO_EX_DATA; +/* Callback types for crypto.h */ +typedef int CRYPTO_EX_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, + void *from_d, int idx, long argl, void *argp); + +typedef struct ocsp_req_ctx_st OCSP_REQ_CTX; +typedef struct ocsp_response_st OCSP_RESPONSE; +typedef struct ocsp_responder_id_st OCSP_RESPID; + +#endif /* def HEADER_OPENSSL_TYPES_H */ diff --git a/crypto/libressl/include/openssl/pem.h b/crypto/libressl/include/openssl/pem.h new file mode 100644 index 0000000000..ee63aff4b2 --- /dev/null +++ b/crypto/libressl/include/openssl/pem.h @@ -0,0 +1,616 @@ +/* $OpenBSD$ */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_PEM_H +#define HEADER_PEM_H + +#include + +#ifndef OPENSSL_NO_BIO +#include +#endif +#ifndef OPENSSL_NO_STACK +#include +#endif +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define PEM_BUFSIZE 1024 + +#define PEM_OBJ_UNDEF 0 +#define PEM_OBJ_X509 1 +#define PEM_OBJ_X509_REQ 2 +#define PEM_OBJ_CRL 3 +#define PEM_OBJ_SSL_SESSION 4 +#define PEM_OBJ_PRIV_KEY 10 +#define PEM_OBJ_PRIV_RSA 11 +#define PEM_OBJ_PRIV_DSA 12 +#define PEM_OBJ_PRIV_DH 13 +#define PEM_OBJ_PUB_RSA 14 +#define PEM_OBJ_PUB_DSA 15 +#define PEM_OBJ_PUB_DH 16 +#define PEM_OBJ_DHPARAMS 17 +#define PEM_OBJ_DSAPARAMS 18 +#define PEM_OBJ_PRIV_RSA_PUBLIC 19 +#define PEM_OBJ_PRIV_ECDSA 20 +#define PEM_OBJ_PUB_ECDSA 21 +#define PEM_OBJ_ECPARAMETERS 22 + +#define PEM_ERROR 30 +#define PEM_DEK_DES_CBC 40 +#define PEM_DEK_IDEA_CBC 45 +#define PEM_DEK_DES_EDE 50 +#define PEM_DEK_DES_ECB 60 +#define PEM_DEK_RSA 70 +#define PEM_DEK_RSA_MD2 80 +#define PEM_DEK_RSA_MD5 90 + +#define PEM_MD_MD2 NID_md2 +#define PEM_MD_MD5 NID_md5 +#define PEM_MD_SHA NID_sha +#define PEM_MD_MD2_RSA NID_md2WithRSAEncryption +#define PEM_MD_MD5_RSA NID_md5WithRSAEncryption +#define PEM_MD_SHA_RSA NID_sha1WithRSAEncryption + +#define PEM_STRING_X509_OLD "X509 CERTIFICATE" +#define PEM_STRING_X509 "CERTIFICATE" +#define PEM_STRING_X509_PAIR "CERTIFICATE PAIR" +#define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE" +#define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST" +#define PEM_STRING_X509_REQ "CERTIFICATE REQUEST" +#define PEM_STRING_X509_CRL "X509 CRL" +#define PEM_STRING_EVP_PKEY "ANY PRIVATE KEY" +#define PEM_STRING_PUBLIC "PUBLIC KEY" +#define PEM_STRING_RSA "RSA PRIVATE KEY" +#define PEM_STRING_RSA_PUBLIC "RSA PUBLIC KEY" +#define PEM_STRING_DSA "DSA PRIVATE KEY" +#define PEM_STRING_DSA_PUBLIC "DSA PUBLIC KEY" +#define PEM_STRING_PKCS7 "PKCS7" +#define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA" +#define PEM_STRING_PKCS8 "ENCRYPTED PRIVATE KEY" +#define PEM_STRING_PKCS8INF "PRIVATE KEY" +#define PEM_STRING_DHPARAMS "DH PARAMETERS" +#define PEM_STRING_SSL_SESSION "SSL SESSION PARAMETERS" +#define PEM_STRING_DSAPARAMS "DSA PARAMETERS" +#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY" +#define PEM_STRING_ECPARAMETERS "EC PARAMETERS" +#define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" +#define PEM_STRING_PARAMETERS "PARAMETERS" +#define PEM_STRING_CMS "CMS" + + /* Note that this structure is initialised by PEM_SealInit and cleaned up + by PEM_SealFinal (at least for now) */ +typedef struct PEM_Encode_Seal_st { + EVP_ENCODE_CTX encode; + EVP_MD_CTX md; + EVP_CIPHER_CTX cipher; +} PEM_ENCODE_SEAL_CTX; + +/* enc_type is one off */ +#define PEM_TYPE_ENCRYPTED 10 +#define PEM_TYPE_MIC_ONLY 20 +#define PEM_TYPE_MIC_CLEAR 30 +#define PEM_TYPE_CLEAR 40 + +typedef struct pem_recip_st { + char *name; + X509_NAME *dn; + + int cipher; + int key_enc; + /* char iv[8]; unused and wrong size */ +} PEM_USER; + +typedef struct pem_ctx_st { + int type; /* what type of object */ + + struct { + int version; + int mode; + } proc_type; + + char *domain; + + struct { + int cipher; + /* unused, and wrong size + unsigned char iv[8]; */ + } DEK_info; + + PEM_USER *originator; + + int num_recipient; + PEM_USER **recipient; + + /* XXX(ben): don#t think this is used! + STACK *x509_chain; / * certificate chain */ + EVP_MD *md; /* signature type */ + + int md_enc; /* is the md encrypted or not? */ + int md_len; /* length of md_data */ + char *md_data; /* message digest, could be pkey encrypted */ + + EVP_CIPHER *dec; /* date encryption cipher */ + int key_len; /* key length */ + unsigned char *key; /* key */ + /* unused, and wrong size + unsigned char iv[8]; */ + + int data_enc; /* is the data encrypted */ + int data_len; + unsigned char *data; +} PEM_CTX; + +/* These macros make the PEM_read/PEM_write functions easier to maintain and + * write. Now they are all implemented with either: + * IMPLEMENT_PEM_rw(...) or IMPLEMENT_PEM_rw_cb(...) + */ + + +#define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \ +type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \ +} + +#define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x) \ +{ \ +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \ +} + +#define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, const type *x) \ +{ \ +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \ +} + +#define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, \ + void *u) \ + { \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ + } + +#define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, \ + void *u) \ + { \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ + } + + +#define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ +type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \ +} + +#define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x) \ +{ \ +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \ +} + +#define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, const type *x) \ +{ \ +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \ +} + +#define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ + { \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \ + } + +#define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ + { \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \ + } + +#define IMPLEMENT_PEM_write(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp(name, type, str, asn1) + +#define IMPLEMENT_PEM_write_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) + +#define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) + +#define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) + +#define IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_read_fp(name, type, str, asn1) + +#define IMPLEMENT_PEM_rw(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write(name, type, str, asn1) + +#define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_const(name, type, str, asn1) + +#define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb(name, type, str, asn1) + +/* These are the same except they are for the declarations */ + + +#define DECLARE_PEM_read_fp(name, type) \ + type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u); + +#define DECLARE_PEM_write_fp(name, type) \ + int PEM_write_##name(FILE *fp, type *x); + +#define DECLARE_PEM_write_fp_const(name, type) \ + int PEM_write_##name(FILE *fp, const type *x); + +#define DECLARE_PEM_write_cb_fp(name, type) \ + int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + + +#ifndef OPENSSL_NO_BIO +#define DECLARE_PEM_read_bio(name, type) \ + type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u); + +#define DECLARE_PEM_write_bio(name, type) \ + int PEM_write_bio_##name(BIO *bp, type *x); + +#define DECLARE_PEM_write_bio_const(name, type) \ + int PEM_write_bio_##name(BIO *bp, const type *x); + +#define DECLARE_PEM_write_cb_bio(name, type) \ + int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + +#else + +#define DECLARE_PEM_read_bio(name, type) /**/ +#define DECLARE_PEM_write_bio(name, type) /**/ +#define DECLARE_PEM_write_bio_const(name, type) /**/ +#define DECLARE_PEM_write_cb_bio(name, type) /**/ + +#endif + +#define DECLARE_PEM_write(name, type) \ + DECLARE_PEM_write_bio(name, type) \ + DECLARE_PEM_write_fp(name, type) + +#define DECLARE_PEM_write_const(name, type) \ + DECLARE_PEM_write_bio_const(name, type) \ + DECLARE_PEM_write_fp_const(name, type) + +#define DECLARE_PEM_write_cb(name, type) \ + DECLARE_PEM_write_cb_bio(name, type) \ + DECLARE_PEM_write_cb_fp(name, type) + +#define DECLARE_PEM_read(name, type) \ + DECLARE_PEM_read_bio(name, type) \ + DECLARE_PEM_read_fp(name, type) + +#define DECLARE_PEM_rw(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write(name, type) + +#define DECLARE_PEM_rw_const(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write_const(name, type) + +#define DECLARE_PEM_rw_cb(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write_cb(name, type) + +typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata); + +int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher); +int PEM_do_header (EVP_CIPHER_INFO *cipher, unsigned char *data, long *len, + pem_password_cb *callback, void *u); + +#ifndef OPENSSL_NO_BIO +int PEM_read_bio(BIO *bp, char **name, char **header, + unsigned char **data, long *len); +int PEM_write_bio(BIO *bp, const char *name, char *hdr, unsigned char *data, + long len); +int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, + const char *name, BIO *bp, pem_password_cb *cb, void *u); +void * PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, + void **x, pem_password_cb *cb, void *u); +int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x, + const EVP_CIPHER *enc, unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); + +STACK_OF(X509_INFO) * PEM_X509_INFO_read_bio(BIO *bp, + STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); +int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, + unsigned char *kstr, int klen, pem_password_cb *cd, void *u); +#endif + +int PEM_read(FILE *fp, char **name, char **header, + unsigned char **data, long *len); +int PEM_write(FILE *fp, char *name, char *hdr, unsigned char *data, + long len); +void * PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, + pem_password_cb *cb, void *u); +int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, + void *x, const EVP_CIPHER *enc, unsigned char *kstr, + int klen, pem_password_cb *callback, void *u); +STACK_OF(X509_INFO) * PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u); + +int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, + EVP_MD *md_type, unsigned char **ek, int *ekl, + unsigned char *iv, EVP_PKEY **pubk, int npubk); +void PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl, + unsigned char *in, int inl); +int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl, + unsigned char *out, int *outl, EVP_PKEY *priv); + +void PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type); +void PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *d, unsigned int cnt); +int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + unsigned int *siglen, EVP_PKEY *pkey); + +int PEM_def_callback(char *buf, int num, int w, void *key); +void PEM_proc_type(char *buf, int type); +void PEM_dek_info(char *buf, const char *type, int len, char *str); + + +DECLARE_PEM_rw(X509, X509) + +DECLARE_PEM_rw(X509_AUX, X509) + +DECLARE_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR) + +DECLARE_PEM_rw(X509_REQ, X509_REQ) +DECLARE_PEM_write(X509_REQ_NEW, X509_REQ) + +DECLARE_PEM_rw(X509_CRL, X509_CRL) + +DECLARE_PEM_rw(PKCS7, PKCS7) + +DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE) + +DECLARE_PEM_rw(PKCS8, X509_SIG) + +DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) + +#ifndef OPENSSL_NO_RSA + +DECLARE_PEM_rw_cb(RSAPrivateKey, RSA) + +DECLARE_PEM_rw_const(RSAPublicKey, RSA) +DECLARE_PEM_rw(RSA_PUBKEY, RSA) + +#endif + +#ifndef OPENSSL_NO_DSA + +DECLARE_PEM_rw_cb(DSAPrivateKey, DSA) + +DECLARE_PEM_rw(DSA_PUBKEY, DSA) + +DECLARE_PEM_rw_const(DSAparams, DSA) + +#endif + +#ifndef OPENSSL_NO_EC +DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP) +DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY) +DECLARE_PEM_rw(EC_PUBKEY, EC_KEY) +#endif + +#ifndef OPENSSL_NO_DH + +DECLARE_PEM_rw_const(DHparams, DH) + +#endif + +DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY) + +DECLARE_PEM_rw(PUBKEY, EVP_PKEY) + +int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *, + char *, int, pem_password_cb *, void *); +int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, + void *u); + +int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); + +EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, + void *u); + +int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cd, void *u); + +EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x); +int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x); + + +EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PrivateKey_bio(BIO *in); +EVP_PKEY *b2i_PublicKey_bio(BIO *in); +int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk); +int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk); +#ifndef OPENSSL_NO_RC4 +EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u); +int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, pem_password_cb *cb, + void *u); +#endif + + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_PEM_strings(void); + +/* Error codes for the PEM functions. */ + +/* Function codes. */ +#define PEM_F_B2I_DSS 127 +#define PEM_F_B2I_PVK_BIO 128 +#define PEM_F_B2I_RSA 129 +#define PEM_F_CHECK_BITLEN_DSA 130 +#define PEM_F_CHECK_BITLEN_RSA 131 +#define PEM_F_D2I_PKCS8PRIVATEKEY_BIO 120 +#define PEM_F_D2I_PKCS8PRIVATEKEY_FP 121 +#define PEM_F_DO_B2I 132 +#define PEM_F_DO_B2I_BIO 133 +#define PEM_F_DO_BLOB_HEADER 134 +#define PEM_F_DO_PK8PKEY 126 +#define PEM_F_DO_PK8PKEY_FP 125 +#define PEM_F_DO_PVK_BODY 135 +#define PEM_F_DO_PVK_HEADER 136 +#define PEM_F_I2B_PVK 137 +#define PEM_F_I2B_PVK_BIO 138 +#define PEM_F_LOAD_IV 101 +#define PEM_F_PEM_ASN1_READ 102 +#define PEM_F_PEM_ASN1_READ_BIO 103 +#define PEM_F_PEM_ASN1_WRITE 104 +#define PEM_F_PEM_ASN1_WRITE_BIO 105 +#define PEM_F_PEM_DEF_CALLBACK 100 +#define PEM_F_PEM_DO_HEADER 106 +#define PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY 118 +#define PEM_F_PEM_GET_EVP_CIPHER_INFO 107 +#define PEM_F_PEM_PK8PKEY 119 +#define PEM_F_PEM_READ 108 +#define PEM_F_PEM_READ_BIO 109 +#define PEM_F_PEM_READ_BIO_PARAMETERS 140 +#define PEM_F_PEM_READ_BIO_PRIVATEKEY 123 +#define PEM_F_PEM_READ_PRIVATEKEY 124 +#define PEM_F_PEM_SEALFINAL 110 +#define PEM_F_PEM_SEALINIT 111 +#define PEM_F_PEM_SIGNFINAL 112 +#define PEM_F_PEM_WRITE 113 +#define PEM_F_PEM_WRITE_BIO 114 +#define PEM_F_PEM_WRITE_PRIVATEKEY 139 +#define PEM_F_PEM_X509_INFO_READ 115 +#define PEM_F_PEM_X509_INFO_READ_BIO 116 +#define PEM_F_PEM_X509_INFO_WRITE_BIO 117 + +/* Reason codes. */ +#define PEM_R_BAD_BASE64_DECODE 100 +#define PEM_R_BAD_DECRYPT 101 +#define PEM_R_BAD_END_LINE 102 +#define PEM_R_BAD_IV_CHARS 103 +#define PEM_R_BAD_MAGIC_NUMBER 116 +#define PEM_R_BAD_PASSWORD_READ 104 +#define PEM_R_BAD_VERSION_NUMBER 117 +#define PEM_R_BIO_WRITE_FAILURE 118 +#define PEM_R_CIPHER_IS_NULL 127 +#define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 115 +#define PEM_R_EXPECTING_PRIVATE_KEY_BLOB 119 +#define PEM_R_EXPECTING_PUBLIC_KEY_BLOB 120 +#define PEM_R_INCONSISTENT_HEADER 121 +#define PEM_R_KEYBLOB_HEADER_PARSE_ERROR 122 +#define PEM_R_KEYBLOB_TOO_SHORT 123 +#define PEM_R_NOT_DEK_INFO 105 +#define PEM_R_NOT_ENCRYPTED 106 +#define PEM_R_NOT_PROC_TYPE 107 +#define PEM_R_NO_START_LINE 108 +#define PEM_R_PROBLEMS_GETTING_PASSWORD 109 +#define PEM_R_PUBLIC_KEY_NO_RSA 110 +#define PEM_R_PVK_DATA_TOO_SHORT 124 +#define PEM_R_PVK_TOO_SHORT 125 +#define PEM_R_READ_KEY 111 +#define PEM_R_SHORT_HEADER 112 +#define PEM_R_UNSUPPORTED_CIPHER 113 +#define PEM_R_UNSUPPORTED_ENCRYPTION 114 +#define PEM_R_UNSUPPORTED_KEY_COMPONENTS 126 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/pem2.h b/crypto/libressl/include/openssl/pem2.h new file mode 100644 index 0000000000..1bae25b9f4 --- /dev/null +++ b/crypto/libressl/include/openssl/pem2.h @@ -0,0 +1,71 @@ +/* $OpenBSD$ */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * This header only exists to break a circular dependency between pem and err + * Ben 30 Jan 1999. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HEADER_PEM_H +void ERR_load_PEM_strings(void); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/crypto/libressl/include/openssl/pkcs12.h b/crypto/libressl/include/openssl/pkcs12.h new file mode 100644 index 0000000000..de082f3e3e --- /dev/null +++ b/crypto/libressl/include/openssl/pkcs12.h @@ -0,0 +1,331 @@ +/* $OpenBSD: pkcs12.h,v 1.12 2014/06/12 15:49:30 deraadt Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_PKCS12_H +#define HEADER_PKCS12_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define PKCS12_KEY_ID 1 +#define PKCS12_IV_ID 2 +#define PKCS12_MAC_ID 3 + +/* Default iteration count */ +#ifndef PKCS12_DEFAULT_ITER +#define PKCS12_DEFAULT_ITER PKCS5_DEFAULT_ITER +#endif + +#define PKCS12_MAC_KEY_LENGTH 20 + +#define PKCS12_SALT_LEN 8 + +/* Uncomment out next line for unicode password and names, otherwise ASCII */ + +/*#define PBE_UNICODE*/ + +#ifdef PBE_UNICODE +#define PKCS12_key_gen PKCS12_key_gen_uni +#define PKCS12_add_friendlyname PKCS12_add_friendlyname_uni +#else +#define PKCS12_key_gen PKCS12_key_gen_asc +#define PKCS12_add_friendlyname PKCS12_add_friendlyname_asc +#endif + +/* MS key usage constants */ + +#define KEY_EX 0x10 +#define KEY_SIG 0x80 + +typedef struct { + X509_SIG *dinfo; + ASN1_OCTET_STRING *salt; + ASN1_INTEGER *iter; /* defaults to 1 */ +} PKCS12_MAC_DATA; + +typedef struct { + ASN1_INTEGER *version; + PKCS12_MAC_DATA *mac; + PKCS7 *authsafes; +} PKCS12; + +typedef struct { + ASN1_OBJECT *type; + union { + struct pkcs12_bag_st *bag; /* secret, crl and certbag */ + struct pkcs8_priv_key_info_st *keybag; /* keybag */ + X509_SIG *shkeybag; /* shrouded key bag */ + STACK_OF(PKCS12_SAFEBAG) *safes; + ASN1_TYPE *other; + } value; + STACK_OF(X509_ATTRIBUTE) *attrib; +} PKCS12_SAFEBAG; + +DECLARE_STACK_OF(PKCS12_SAFEBAG) +DECLARE_ASN1_SET_OF(PKCS12_SAFEBAG) +DECLARE_PKCS12_STACK_OF(PKCS12_SAFEBAG) + +typedef struct pkcs12_bag_st { + ASN1_OBJECT *type; + union { + ASN1_OCTET_STRING *x509cert; + ASN1_OCTET_STRING *x509crl; + ASN1_OCTET_STRING *octet; + ASN1_IA5STRING *sdsicert; + ASN1_TYPE *other; /* Secret or other bag */ + } value; +} PKCS12_BAGS; + +#define PKCS12_ERROR 0 +#define PKCS12_OK 1 + +/* Compatibility macros */ + +#define M_PKCS12_x5092certbag PKCS12_x5092certbag +#define M_PKCS12_x509crl2certbag PKCS12_x509crl2certbag + +#define M_PKCS12_certbag2x509 PKCS12_certbag2x509 +#define M_PKCS12_certbag2x509crl PKCS12_certbag2x509crl + +#define M_PKCS12_unpack_p7data PKCS12_unpack_p7data +#define M_PKCS12_pack_authsafes PKCS12_pack_authsafes +#define M_PKCS12_unpack_authsafes PKCS12_unpack_authsafes +#define M_PKCS12_unpack_p7encdata PKCS12_unpack_p7encdata + +#define M_PKCS12_decrypt_skey PKCS12_decrypt_skey +#define M_PKCS8_decrypt PKCS8_decrypt + +#define M_PKCS12_bag_type(bg) OBJ_obj2nid((bg)->type) +#define M_PKCS12_cert_bag_type(bg) OBJ_obj2nid((bg)->value.bag->type) +#define M_PKCS12_crl_bag_type M_PKCS12_cert_bag_type + +#define PKCS12_get_attr(bag, attr_nid) \ + PKCS12_get_attr_gen(bag->attrib, attr_nid) + +#define PKCS8_get_attr(p8, attr_nid) \ + PKCS12_get_attr_gen(p8->attributes, attr_nid) + +#define PKCS12_mac_present(p12) ((p12)->mac ? 1 : 0) + + +PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509); +PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl); +X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag); +X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag); + +PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, + int nid1, int nid2); +PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8); +PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass, int passlen); +PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag, const char *pass, + int passlen); +X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, + const char *pass, int passlen, unsigned char *salt, int saltlen, int iter, + PKCS8_PRIV_KEY_INFO *p8); +PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass, + int passlen, unsigned char *salt, int saltlen, int iter, + PKCS8_PRIV_KEY_INFO *p8); +PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk); +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7); +PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, STACK_OF(PKCS12_SAFEBAG) *bags); +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, + int passlen); + +int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes); +STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12); + +int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, + int namelen); +int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, const unsigned char *name, + int namelen); +int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage); +ASN1_TYPE *PKCS12_get_attr_gen(STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid); +char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag); +unsigned char *PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass, + int passlen, unsigned char *in, int inlen, unsigned char **data, + int *datalen, int en_de); +void * PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it, + const char *pass, int passlen, ASN1_OCTET_STRING *oct, int zbuf); +ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, + const ASN1_ITEM *it, const char *pass, int passlen, void *obj, int zbuf); +PKCS12 *PKCS12_init(int mode); +int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, unsigned char *out, + const EVP_MD *md_type); +int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, unsigned char *out, + const EVP_MD *md_type); +int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md_type, + int en_de); +int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *mac, unsigned int *maclen); +int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen); +int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + const EVP_MD *md_type); +int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, + int saltlen, const EVP_MD *md_type); +unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, + unsigned char **uni, int *unilen); +char *OPENSSL_uni2asc(unsigned char *uni, int unilen); + +DECLARE_ASN1_FUNCTIONS(PKCS12) +DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA) +DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG) +DECLARE_ASN1_FUNCTIONS(PKCS12_BAGS) + +DECLARE_ASN1_ITEM(PKCS12_SAFEBAGS) +DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES) + +void PKCS12_PBE_add(void); +int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, + STACK_OF(X509) **ca); +PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, + STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, + int mac_iter, int keytype); + +PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert); +PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, EVP_PKEY *key, + int key_usage, int iter, int key_nid, char *pass); +int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, + int safe_nid, int iter, char *pass); +PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid); + +int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12); +int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12); +PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12); +PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12); +int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_PKCS12_strings(void); + +/* Error codes for the PKCS12 functions. */ + +/* Function codes. */ +#define PKCS12_F_PARSE_BAG 129 +#define PKCS12_F_PARSE_BAGS 103 +#define PKCS12_F_PKCS12_ADD_FRIENDLYNAME 100 +#define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC 127 +#define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI 102 +#define PKCS12_F_PKCS12_ADD_LOCALKEYID 104 +#define PKCS12_F_PKCS12_CREATE 105 +#define PKCS12_F_PKCS12_GEN_MAC 107 +#define PKCS12_F_PKCS12_INIT 109 +#define PKCS12_F_PKCS12_ITEM_DECRYPT_D2I 106 +#define PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT 108 +#define PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG 117 +#define PKCS12_F_PKCS12_KEY_GEN_ASC 110 +#define PKCS12_F_PKCS12_KEY_GEN_UNI 111 +#define PKCS12_F_PKCS12_MAKE_KEYBAG 112 +#define PKCS12_F_PKCS12_MAKE_SHKEYBAG 113 +#define PKCS12_F_PKCS12_NEWPASS 128 +#define PKCS12_F_PKCS12_PACK_P7DATA 114 +#define PKCS12_F_PKCS12_PACK_P7ENCDATA 115 +#define PKCS12_F_PKCS12_PARSE 118 +#define PKCS12_F_PKCS12_PBE_CRYPT 119 +#define PKCS12_F_PKCS12_PBE_KEYIVGEN 120 +#define PKCS12_F_PKCS12_SETUP_MAC 122 +#define PKCS12_F_PKCS12_SET_MAC 123 +#define PKCS12_F_PKCS12_UNPACK_AUTHSAFES 130 +#define PKCS12_F_PKCS12_UNPACK_P7DATA 131 +#define PKCS12_F_PKCS12_VERIFY_MAC 126 +#define PKCS12_F_PKCS8_ADD_KEYUSAGE 124 +#define PKCS12_F_PKCS8_ENCRYPT 125 + +/* Reason codes. */ +#define PKCS12_R_CANT_PACK_STRUCTURE 100 +#define PKCS12_R_CONTENT_TYPE_NOT_DATA 121 +#define PKCS12_R_DECODE_ERROR 101 +#define PKCS12_R_ENCODE_ERROR 102 +#define PKCS12_R_ENCRYPT_ERROR 103 +#define PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE 120 +#define PKCS12_R_INVALID_NULL_ARGUMENT 104 +#define PKCS12_R_INVALID_NULL_PKCS12_POINTER 105 +#define PKCS12_R_IV_GEN_ERROR 106 +#define PKCS12_R_KEY_GEN_ERROR 107 +#define PKCS12_R_MAC_ABSENT 108 +#define PKCS12_R_MAC_GENERATION_ERROR 109 +#define PKCS12_R_MAC_SETUP_ERROR 110 +#define PKCS12_R_MAC_STRING_SET_ERROR 111 +#define PKCS12_R_MAC_VERIFY_ERROR 112 +#define PKCS12_R_MAC_VERIFY_FAILURE 113 +#define PKCS12_R_PARSE_ERROR 114 +#define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR 115 +#define PKCS12_R_PKCS12_CIPHERFINAL_ERROR 116 +#define PKCS12_R_PKCS12_PBE_CRYPT_ERROR 117 +#define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM 118 +#define PKCS12_R_UNSUPPORTED_PKCS12_MODE 119 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/pkcs7.h b/crypto/libressl/include/openssl/pkcs7.h new file mode 100644 index 0000000000..67329d1431 --- /dev/null +++ b/crypto/libressl/include/openssl/pkcs7.h @@ -0,0 +1,492 @@ +/* $OpenBSD: pkcs7.h,v 1.13 2014/06/12 15:49:30 deraadt Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_PKCS7_H +#define HEADER_PKCS7_H + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WIN32) && defined(__WINCRYPT_H__) +#ifndef LIBRESSL_INTERNAL +#ifdef _MSC_VER +#pragma message("Warning, overriding WinCrypt defines") +#else +#warning overriding WinCrypt defines +#endif +#endif +#undef PKCS7_ISSUER_AND_SERIAL +#undef PKCS7_SIGNER_INFO +#endif + +/* +Encryption_ID DES-CBC +Digest_ID MD5 +Digest_Encryption_ID rsaEncryption +Key_Encryption_ID rsaEncryption +*/ + +typedef struct pkcs7_issuer_and_serial_st { + X509_NAME *issuer; + ASN1_INTEGER *serial; +} PKCS7_ISSUER_AND_SERIAL; + +typedef struct pkcs7_signer_info_st { + ASN1_INTEGER *version; /* version 1 */ + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *digest_alg; + STACK_OF(X509_ATTRIBUTE) *auth_attr; /* [ 0 ] */ + X509_ALGOR *digest_enc_alg; + ASN1_OCTET_STRING *enc_digest; + STACK_OF(X509_ATTRIBUTE) *unauth_attr; /* [ 1 ] */ + + /* The private key to sign with */ + EVP_PKEY *pkey; +} PKCS7_SIGNER_INFO; + +DECLARE_STACK_OF(PKCS7_SIGNER_INFO) +DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO) + +typedef struct pkcs7_recip_info_st { + ASN1_INTEGER *version; /* version 0 */ + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *key_enc_algor; + ASN1_OCTET_STRING *enc_key; + X509 *cert; /* get the pub-key from this */ +} PKCS7_RECIP_INFO; + +DECLARE_STACK_OF(PKCS7_RECIP_INFO) +DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO) + +typedef struct pkcs7_signed_st { + ASN1_INTEGER *version; /* version 1 */ + STACK_OF(X509_ALGOR) *md_algs; /* md used */ + STACK_OF(X509) *cert; /* [ 0 ] */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; + + struct pkcs7_st *contents; +} PKCS7_SIGNED; +/* The above structure is very very similar to PKCS7_SIGN_ENVELOPE. + * How about merging the two */ + +typedef struct pkcs7_enc_content_st { + ASN1_OBJECT *content_type; + X509_ALGOR *algorithm; + ASN1_OCTET_STRING *enc_data; /* [ 0 ] */ + const EVP_CIPHER *cipher; +} PKCS7_ENC_CONTENT; + +typedef struct pkcs7_enveloped_st { + ASN1_INTEGER *version; /* version 0 */ + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; + PKCS7_ENC_CONTENT *enc_data; +} PKCS7_ENVELOPE; + +typedef struct pkcs7_signedandenveloped_st { + ASN1_INTEGER *version; /* version 1 */ + STACK_OF(X509_ALGOR) *md_algs; /* md used */ + STACK_OF(X509) *cert; /* [ 0 ] */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; + + PKCS7_ENC_CONTENT *enc_data; + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; +} PKCS7_SIGN_ENVELOPE; + +typedef struct pkcs7_digest_st { + ASN1_INTEGER *version; /* version 0 */ + X509_ALGOR *md; /* md used */ + struct pkcs7_st *contents; + ASN1_OCTET_STRING *digest; +} PKCS7_DIGEST; + +typedef struct pkcs7_encrypted_st { + ASN1_INTEGER *version; /* version 0 */ + PKCS7_ENC_CONTENT *enc_data; +} PKCS7_ENCRYPT; + +typedef struct pkcs7_st { + /* The following is non NULL if it contains ASN1 encoding of + * this structure */ + unsigned char *asn1; + long length; + +#define PKCS7_S_HEADER 0 +#define PKCS7_S_BODY 1 +#define PKCS7_S_TAIL 2 + int state; /* used during processing */ + + int detached; + + ASN1_OBJECT *type; + /* content as defined by the type */ + /* all encryption/message digests are applied to the 'contents', + * leaving out the 'type' field. */ + union { + char *ptr; + + /* NID_pkcs7_data */ + ASN1_OCTET_STRING *data; + + /* NID_pkcs7_signed */ + PKCS7_SIGNED *sign; + + /* NID_pkcs7_enveloped */ + PKCS7_ENVELOPE *enveloped; + + /* NID_pkcs7_signedAndEnveloped */ + PKCS7_SIGN_ENVELOPE *signed_and_enveloped; + + /* NID_pkcs7_digest */ + PKCS7_DIGEST *digest; + + /* NID_pkcs7_encrypted */ + PKCS7_ENCRYPT *encrypted; + + /* Anything else */ + ASN1_TYPE *other; + } d; +} PKCS7; + +DECLARE_STACK_OF(PKCS7) +DECLARE_ASN1_SET_OF(PKCS7) +DECLARE_PKCS12_STACK_OF(PKCS7) + +#define PKCS7_OP_SET_DETACHED_SIGNATURE 1 +#define PKCS7_OP_GET_DETACHED_SIGNATURE 2 + +#define PKCS7_get_signed_attributes(si) ((si)->auth_attr) +#define PKCS7_get_attributes(si) ((si)->unauth_attr) + +#define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed) +#define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted) +#define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped) +#define PKCS7_type_is_signedAndEnveloped(a) \ + (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped) +#define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data) +#define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest) +#define PKCS7_type_is_encrypted(a) \ + (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted) + +#define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest) + +#define PKCS7_set_detached(p,v) \ + PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL) +#define PKCS7_get_detached(p) \ + PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL) + +#define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7)) + +/* S/MIME related flags */ + +#define PKCS7_TEXT 0x1 +#define PKCS7_NOCERTS 0x2 +#define PKCS7_NOSIGS 0x4 +#define PKCS7_NOCHAIN 0x8 +#define PKCS7_NOINTERN 0x10 +#define PKCS7_NOVERIFY 0x20 +#define PKCS7_DETACHED 0x40 +#define PKCS7_BINARY 0x80 +#define PKCS7_NOATTR 0x100 +#define PKCS7_NOSMIMECAP 0x200 +#define PKCS7_NOOLDMIMETYPE 0x400 +#define PKCS7_CRLFEOL 0x800 +#define PKCS7_STREAM 0x1000 +#define PKCS7_NOCRL 0x2000 +#define PKCS7_PARTIAL 0x4000 +#define PKCS7_REUSE_DIGEST 0x8000 + +/* Flags: for compatibility with older code */ + +#define SMIME_TEXT PKCS7_TEXT +#define SMIME_NOCERTS PKCS7_NOCERTS +#define SMIME_NOSIGS PKCS7_NOSIGS +#define SMIME_NOCHAIN PKCS7_NOCHAIN +#define SMIME_NOINTERN PKCS7_NOINTERN +#define SMIME_NOVERIFY PKCS7_NOVERIFY +#define SMIME_DETACHED PKCS7_DETACHED +#define SMIME_BINARY PKCS7_BINARY +#define SMIME_NOATTR PKCS7_NOATTR + +DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL) + +int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, + const EVP_MD *type, unsigned char *md, unsigned int *len); +PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7); +int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7); +PKCS7 *PKCS7_dup(PKCS7 *p7); +PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7); +int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7); +int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); +int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); + +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO) +DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNED) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENVELOPE) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE) +DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT) +DECLARE_ASN1_FUNCTIONS(PKCS7) + +DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN) +DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY) + +DECLARE_ASN1_NDEF_FUNCTION(PKCS7) +DECLARE_ASN1_PRINT_FUNCTION(PKCS7) + +long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg); + +int PKCS7_set_type(PKCS7 *p7, int type); +int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other); +int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data); +int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, + const EVP_MD *dgst); +int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si); +int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i); +int PKCS7_add_certificate(PKCS7 *p7, X509 *x509); +int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509); +int PKCS7_content_new(PKCS7 *p7, int nid); +int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, + BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si); +int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, + X509 *x509); + +BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio); +int PKCS7_dataFinal(PKCS7 *p7, BIO *bio); +BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert); + + +PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, + EVP_PKEY *pkey, const EVP_MD *dgst); +X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si); +int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md); +STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7); + +PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509); +void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, + X509_ALGOR **pdig, X509_ALGOR **psig); +void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc); +int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri); +int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509); +int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher); +int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7); + +PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx); +ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk); +int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int type, + void *data); +int PKCS7_add_attribute (PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, + void *value); +ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid); +ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid); +int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk); +int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk); + + +PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, int flags); + +PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, + X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md, + int flags); + +int PKCS7_final(PKCS7 *p7, BIO *data, int flags); +int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, + BIO *indata, BIO *out, int flags); +STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags); +PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, + int flags); +int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags); + +int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, + STACK_OF(X509_ALGOR) *cap); +STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si); +int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg); + +int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid); +int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t); +int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, + const unsigned char *md, int mdlen); + +int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags); +PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont); + +BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7); + + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_PKCS7_strings(void); + +/* Error codes for the PKCS7 functions. */ + +/* Function codes. */ +#define PKCS7_F_B64_READ_PKCS7 120 +#define PKCS7_F_B64_WRITE_PKCS7 121 +#define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB 136 +#define PKCS7_F_I2D_PKCS7_BIO_STREAM 140 +#define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME 135 +#define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP 118 +#define PKCS7_F_PKCS7_ADD_CERTIFICATE 100 +#define PKCS7_F_PKCS7_ADD_CRL 101 +#define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102 +#define PKCS7_F_PKCS7_ADD_SIGNATURE 131 +#define PKCS7_F_PKCS7_ADD_SIGNER 103 +#define PKCS7_F_PKCS7_BIO_ADD_DIGEST 125 +#define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST 138 +#define PKCS7_F_PKCS7_CTRL 104 +#define PKCS7_F_PKCS7_DATADECODE 112 +#define PKCS7_F_PKCS7_DATAFINAL 128 +#define PKCS7_F_PKCS7_DATAINIT 105 +#define PKCS7_F_PKCS7_DATASIGN 106 +#define PKCS7_F_PKCS7_DATAVERIFY 107 +#define PKCS7_F_PKCS7_DECRYPT 114 +#define PKCS7_F_PKCS7_DECRYPT_RINFO 133 +#define PKCS7_F_PKCS7_ENCODE_RINFO 132 +#define PKCS7_F_PKCS7_ENCRYPT 115 +#define PKCS7_F_PKCS7_FINAL 134 +#define PKCS7_F_PKCS7_FIND_DIGEST 127 +#define PKCS7_F_PKCS7_GET0_SIGNERS 124 +#define PKCS7_F_PKCS7_RECIP_INFO_SET 130 +#define PKCS7_F_PKCS7_SET_CIPHER 108 +#define PKCS7_F_PKCS7_SET_CONTENT 109 +#define PKCS7_F_PKCS7_SET_DIGEST 126 +#define PKCS7_F_PKCS7_SET_TYPE 110 +#define PKCS7_F_PKCS7_SIGN 116 +#define PKCS7_F_PKCS7_SIGNATUREVERIFY 113 +#define PKCS7_F_PKCS7_SIGNER_INFO_SET 129 +#define PKCS7_F_PKCS7_SIGNER_INFO_SIGN 139 +#define PKCS7_F_PKCS7_SIGN_ADD_SIGNER 137 +#define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119 +#define PKCS7_F_PKCS7_VERIFY 117 +#define PKCS7_F_SMIME_READ_PKCS7 122 +#define PKCS7_F_SMIME_TEXT 123 + +/* Reason codes. */ +#define PKCS7_R_CERTIFICATE_VERIFY_ERROR 117 +#define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144 +#define PKCS7_R_CIPHER_NOT_INITIALIZED 116 +#define PKCS7_R_CONTENT_AND_DATA_PRESENT 118 +#define PKCS7_R_CTRL_ERROR 152 +#define PKCS7_R_DECODE_ERROR 130 +#define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH 100 +#define PKCS7_R_DECRYPT_ERROR 119 +#define PKCS7_R_DIGEST_FAILURE 101 +#define PKCS7_R_ENCRYPTION_CTRL_FAILURE 149 +#define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150 +#define PKCS7_R_ERROR_ADDING_RECIPIENT 120 +#define PKCS7_R_ERROR_SETTING_CIPHER 121 +#define PKCS7_R_INVALID_MIME_TYPE 131 +#define PKCS7_R_INVALID_NULL_POINTER 143 +#define PKCS7_R_MIME_NO_CONTENT_TYPE 132 +#define PKCS7_R_MIME_PARSE_ERROR 133 +#define PKCS7_R_MIME_SIG_PARSE_ERROR 134 +#define PKCS7_R_MISSING_CERIPEND_INFO 103 +#define PKCS7_R_NO_CONTENT 122 +#define PKCS7_R_NO_CONTENT_TYPE 135 +#define PKCS7_R_NO_DEFAULT_DIGEST 151 +#define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND 154 +#define PKCS7_R_NO_MULTIPART_BODY_FAILURE 136 +#define PKCS7_R_NO_MULTIPART_BOUNDARY 137 +#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115 +#define PKCS7_R_NO_RECIPIENT_MATCHES_KEY 146 +#define PKCS7_R_NO_SIGNATURES_ON_DATA 123 +#define PKCS7_R_NO_SIGNERS 142 +#define PKCS7_R_NO_SIG_CONTENT_TYPE 138 +#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104 +#define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124 +#define PKCS7_R_PKCS7_ADD_SIGNER_ERROR 153 +#define PKCS7_R_PKCS7_DATAFINAL 126 +#define PKCS7_R_PKCS7_DATAFINAL_ERROR 125 +#define PKCS7_R_PKCS7_DATASIGN 145 +#define PKCS7_R_PKCS7_PARSE_ERROR 139 +#define PKCS7_R_PKCS7_SIG_PARSE_ERROR 140 +#define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127 +#define PKCS7_R_SIGNATURE_FAILURE 105 +#define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128 +#define PKCS7_R_SIGNING_CTRL_FAILURE 147 +#define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 148 +#define PKCS7_R_SIG_INVALID_MIME_TYPE 141 +#define PKCS7_R_SMIME_TEXT_ERROR 129 +#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106 +#define PKCS7_R_UNABLE_TO_FIND_MEM_BIO 107 +#define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST 108 +#define PKCS7_R_UNKNOWN_DIGEST_TYPE 109 +#define PKCS7_R_UNKNOWN_OPERATION 110 +#define PKCS7_R_UNSUPPORTED_CIPHER_TYPE 111 +#define PKCS7_R_UNSUPPORTED_CONTENT_TYPE 112 +#define PKCS7_R_WRONG_CONTENT_TYPE 113 +#define PKCS7_R_WRONG_PKCS7_TYPE 114 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/poly1305.h b/crypto/libressl/include/openssl/poly1305.h new file mode 100644 index 0000000000..9644236dfc --- /dev/null +++ b/crypto/libressl/include/openssl/poly1305.h @@ -0,0 +1,49 @@ +/* $OpenBSD: poly1305.h,v 1.2 2014/06/12 15:49:30 deraadt Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * 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 HEADER_POLY1305_H +#define HEADER_POLY1305_H + +#include + +#if defined(OPENSSL_NO_POLY1305) +#error Poly1305 is disabled. +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct poly1305_context { + size_t aligner; + unsigned char opaque[136]; +} poly1305_context; + +typedef struct poly1305_context poly1305_state; + +void CRYPTO_poly1305_init(poly1305_context *ctx, const unsigned char key[32]); +void CRYPTO_poly1305_update(poly1305_context *ctx, const unsigned char *in, + size_t len); +void CRYPTO_poly1305_finish(poly1305_context *ctx, unsigned char mac[16]); + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_POLY1305_H */ diff --git a/crypto/libressl/include/openssl/rand.h b/crypto/libressl/include/openssl/rand.h new file mode 100644 index 0000000000..dbd242b9b1 --- /dev/null +++ b/crypto/libressl/include/openssl/rand.h @@ -0,0 +1,127 @@ +/* $OpenBSD: rand.h,v 1.21 2014/07/10 22:45:57 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#ifndef HEADER_RAND_H +#define HEADER_RAND_H + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Already defined in ossl_typ.h */ +/* typedef struct rand_meth_st RAND_METHOD; */ + +struct rand_meth_st { + void (*seed)(const void *buf, int num); + int (*bytes)(unsigned char *buf, int num); + void (*cleanup)(void); + void (*add)(const void *buf, int num, double entropy); + int (*pseudorand)(unsigned char *buf, int num); + int (*status)(void); +}; + +int RAND_set_rand_method(const RAND_METHOD *meth); +const RAND_METHOD *RAND_get_rand_method(void); +#ifndef OPENSSL_NO_ENGINE +int RAND_set_rand_engine(ENGINE *engine); +#endif +RAND_METHOD *RAND_SSLeay(void); + +#ifndef LIBRESSL_INTERNAL +void RAND_cleanup(void ); +int RAND_bytes(unsigned char *buf, int num); +int RAND_pseudo_bytes(unsigned char *buf, int num); +void RAND_seed(const void *buf, int num); +void RAND_add(const void *buf, int num, double entropy); +int RAND_load_file(const char *file, long max_bytes); +int RAND_write_file(const char *file); +const char *RAND_file_name(char *file, size_t num); +int RAND_status(void); +int RAND_poll(void); +#endif + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_RAND_strings(void); + +/* Error codes for the RAND functions. (no longer used) */ + +/* Function codes. */ +#define RAND_F_RAND_GET_RAND_METHOD 101 +#define RAND_F_RAND_INIT_FIPS 102 +#define RAND_F_SSLEAY_RAND_BYTES 100 + +/* Reason codes. */ +#define RAND_R_DUAL_EC_DRBG_DISABLED 104 +#define RAND_R_ERROR_INITIALISING_DRBG 102 +#define RAND_R_ERROR_INSTANTIATING_DRBG 103 +#define RAND_R_NO_FIPS_RANDOM_METHOD_SET 101 +#define RAND_R_PRNG_NOT_SEEDED 100 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/rc2.h b/crypto/libressl/include/openssl/rc2.h new file mode 100644 index 0000000000..6bdb28d157 --- /dev/null +++ b/crypto/libressl/include/openssl/rc2.h @@ -0,0 +1,101 @@ +/* $OpenBSD: rc2.h,v 1.10 2014/06/12 15:49:30 deraadt Exp $ */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RC2_H +#define HEADER_RC2_H + +#include /* OPENSSL_NO_RC2, RC2_INT */ + +#ifdef OPENSSL_NO_RC2 +#error RC2 is disabled. +#endif + +#define RC2_ENCRYPT 1 +#define RC2_DECRYPT 0 + +#define RC2_BLOCK 8 +#define RC2_KEY_LENGTH 16 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct rc2_key_st + { + RC2_INT data[64]; + } RC2_KEY; + +void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,int bits); +void RC2_ecb_encrypt(const unsigned char *in,unsigned char *out,RC2_KEY *key, + int enc); +void RC2_encrypt(unsigned long *data,RC2_KEY *key); +void RC2_decrypt(unsigned long *data,RC2_KEY *key); +void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + RC2_KEY *ks, unsigned char *iv, int enc); +void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num, int enc); +void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/libressl/include/openssl/rc4.h b/crypto/libressl/include/openssl/rc4.h new file mode 100644 index 0000000000..bf6993b6eb --- /dev/null +++ b/crypto/libressl/include/openssl/rc4.h @@ -0,0 +1,89 @@ +/* $OpenBSD: rc4.h,v 1.12 2014/07/10 22:45:57 jsing Exp $ */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RC4_H +#define HEADER_RC4_H + +#include /* OPENSSL_NO_RC4, RC4_INT */ + +#ifdef OPENSSL_NO_RC4 +#error RC4 is disabled. +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct rc4_key_st { + RC4_INT x, y; + RC4_INT data[256]; +} RC4_KEY; + +const char *RC4_options(void); +void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); +void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); +void RC4(RC4_KEY *key, size_t len, const unsigned char *indata, + unsigned char *outdata); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/libressl/include/openssl/ripemd.h b/crypto/libressl/include/openssl/ripemd.h new file mode 100644 index 0000000000..38da5ff2e9 --- /dev/null +++ b/crypto/libressl/include/openssl/ripemd.h @@ -0,0 +1,105 @@ +/* $OpenBSD: ripemd.h,v 1.13 2014/06/12 15:49:30 deraadt Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#ifndef HEADER_RIPEMD_H +#define HEADER_RIPEMD_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENSSL_NO_RIPEMD +#error RIPEMD is disabled. +#endif + +#if defined(__LP32__) +#define RIPEMD160_LONG unsigned long +#elif defined(__ILP64__) +#define RIPEMD160_LONG unsigned long +#define RIPEMD160_LONG_LOG2 3 +#else +#define RIPEMD160_LONG unsigned int +#endif + +#define RIPEMD160_CBLOCK 64 +#define RIPEMD160_LBLOCK (RIPEMD160_CBLOCK/4) +#define RIPEMD160_DIGEST_LENGTH 20 + +typedef struct RIPEMD160state_st + { + RIPEMD160_LONG A,B,C,D,E; + RIPEMD160_LONG Nl,Nh; + RIPEMD160_LONG data[RIPEMD160_LBLOCK]; + unsigned int num; + } RIPEMD160_CTX; + +int RIPEMD160_Init(RIPEMD160_CTX *c); +int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len); +int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c); +unsigned char *RIPEMD160(const unsigned char *d, size_t n, + unsigned char *md); +void RIPEMD160_Transform(RIPEMD160_CTX *c, const unsigned char *b); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/libressl/include/openssl/rsa.h b/crypto/libressl/include/openssl/rsa.h new file mode 100644 index 0000000000..a7d28e4531 --- /dev/null +++ b/crypto/libressl/include/openssl/rsa.h @@ -0,0 +1,548 @@ +/* $OpenBSD: rsa.h,v 1.27 2015/02/14 15:10:39 miod Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RSA_H +#define HEADER_RSA_H + +#include + +#include + +#ifndef OPENSSL_NO_BIO +#include +#endif +#include +#include +#ifndef OPENSSL_NO_DEPRECATED +#include +#endif + +#ifdef OPENSSL_NO_RSA +#error RSA is disabled. +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Declared already in ossl_typ.h */ +/* typedef struct rsa_st RSA; */ +/* typedef struct rsa_meth_st RSA_METHOD; */ + +struct rsa_meth_st { + const char *name; + int (*rsa_pub_enc)(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + int (*rsa_pub_dec)(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + int (*rsa_priv_enc)(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + int (*rsa_priv_dec)(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + int (*rsa_mod_exp)(BIGNUM *r0, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx); /* Can be null */ + int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); /* Can be null */ + int (*init)(RSA *rsa); /* called at new */ + int (*finish)(RSA *rsa); /* called at free */ + int flags; /* RSA_METHOD_FLAG_* things */ + char *app_data; /* may be needed! */ +/* New sign and verify functions: some libraries don't allow arbitrary data + * to be signed/verified: this allows them to be used. Note: for this to work + * the RSA_public_decrypt() and RSA_private_encrypt() should *NOT* be used + * RSA_sign(), RSA_verify() should be used instead. Note: for backwards + * compatibility this functionality is only enabled if the RSA_FLAG_SIGN_VER + * option is set in 'flags'. + */ + int (*rsa_sign)(int type, const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, const RSA *rsa); + int (*rsa_verify)(int dtype, const unsigned char *m, + unsigned int m_length, const unsigned char *sigbuf, + unsigned int siglen, const RSA *rsa); +/* If this callback is NULL, the builtin software RSA key-gen will be used. This + * is for behavioural compatibility whilst the code gets rewired, but one day + * it would be nice to assume there are no such things as "builtin software" + * implementations. */ + int (*rsa_keygen)(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); +}; + +struct rsa_st { + /* The first parameter is used to pickup errors where + * this is passed instead of aEVP_PKEY, it is set to 0 */ + int pad; + long version; + const RSA_METHOD *meth; + /* functional reference if 'meth' is ENGINE-provided */ + ENGINE *engine; + BIGNUM *n; + BIGNUM *e; + BIGNUM *d; + BIGNUM *p; + BIGNUM *q; + BIGNUM *dmp1; + BIGNUM *dmq1; + BIGNUM *iqmp; + /* be careful using this if the RSA structure is shared */ + CRYPTO_EX_DATA ex_data; + int references; + int flags; + + /* Used to cache montgomery values */ + BN_MONT_CTX *_method_mod_n; + BN_MONT_CTX *_method_mod_p; + BN_MONT_CTX *_method_mod_q; + + /* all BIGNUM values are actually in the following data, if it is not + * NULL */ + BN_BLINDING *blinding; + BN_BLINDING *mt_blinding; +}; + +#ifndef OPENSSL_RSA_MAX_MODULUS_BITS +# define OPENSSL_RSA_MAX_MODULUS_BITS 16384 +#endif + +#ifndef OPENSSL_RSA_SMALL_MODULUS_BITS +# define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 +#endif +#ifndef OPENSSL_RSA_MAX_PUBEXP_BITS +# define OPENSSL_RSA_MAX_PUBEXP_BITS 64 /* exponent limit enforced for "large" modulus only */ +#endif + +#define RSA_3 0x3L +#define RSA_F4 0x10001L + +/* Don't check pub/private match. */ +#define RSA_METHOD_FLAG_NO_CHECK 0x0001 + +#define RSA_FLAG_CACHE_PUBLIC 0x0002 +#define RSA_FLAG_CACHE_PRIVATE 0x0004 +#define RSA_FLAG_BLINDING 0x0008 +#define RSA_FLAG_THREAD_SAFE 0x0010 + +/* + * This flag means the private key operations will be handled by rsa_mod_exp + * and that they do not depend on the private key components being present: + * for example a key stored in external hardware. Without this flag bn_mod_exp + * gets called when private key components are absent. + */ +#define RSA_FLAG_EXT_PKEY 0x0020 + +/* + * This flag in the RSA_METHOD enables the new rsa_sign, rsa_verify functions. + */ +#define RSA_FLAG_SIGN_VER 0x0040 + +/* + * The built-in RSA implementation uses blinding by default, but other engines + * might not need it. + */ +#define RSA_FLAG_NO_BLINDING 0x0080 + +#define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, \ + pad, NULL) + +#define EVP_PKEY_CTX_get_rsa_padding(ctx, ppad) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, \ + EVP_PKEY_CTRL_GET_RSA_PADDING, 0, ppad) + +#define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \ + (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, \ + len, NULL) + +#define EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \ + (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ + EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, \ + 0, plen) + +#define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL) + +#define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp) + +#define EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_SIG, \ + EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)md) + +#define EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_SIG, \ + EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)pmd) + +#define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1) +#define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 2) + +#define EVP_PKEY_CTRL_RSA_KEYGEN_BITS (EVP_PKEY_ALG_CTRL + 3) +#define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 4) +#define EVP_PKEY_CTRL_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 5) + +#define EVP_PKEY_CTRL_GET_RSA_PADDING (EVP_PKEY_ALG_CTRL + 6) +#define EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 7) +#define EVP_PKEY_CTRL_GET_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 8) + +#define RSA_PKCS1_PADDING 1 +#define RSA_SSLV23_PADDING 2 +#define RSA_NO_PADDING 3 +#define RSA_PKCS1_OAEP_PADDING 4 +#define RSA_X931_PADDING 5 +/* EVP_PKEY_ only */ +#define RSA_PKCS1_PSS_PADDING 6 + +#define RSA_PKCS1_PADDING_SIZE 11 + +#define RSA_set_app_data(s,arg) RSA_set_ex_data(s,0,arg) +#define RSA_get_app_data(s) RSA_get_ex_data(s,0) + +RSA *RSA_new(void); +RSA *RSA_new_method(ENGINE *engine); +int RSA_size(const RSA *rsa); + +/* Deprecated version */ +#ifndef OPENSSL_NO_DEPRECATED +RSA *RSA_generate_key(int bits, unsigned long e, + void (*callback)(int, int, void *), void *cb_arg); +#endif /* !defined(OPENSSL_NO_DEPRECATED) */ + +/* New version */ +int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); + +int RSA_check_key(const RSA *); +/* next 4 return -1 on error */ +int RSA_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +void RSA_free(RSA *r); +/* "up" the RSA object's reference count */ +int RSA_up_ref(RSA *r); + +int RSA_flags(const RSA *r); + +void RSA_set_default_method(const RSA_METHOD *meth); +const RSA_METHOD *RSA_get_default_method(void); +const RSA_METHOD *RSA_get_method(const RSA *rsa); +int RSA_set_method(RSA *rsa, const RSA_METHOD *meth); + +/* these are the actual SSLeay RSA functions */ +const RSA_METHOD *RSA_PKCS1_SSLeay(void); + +const RSA_METHOD *RSA_null_method(void); + +DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPublicKey) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPrivateKey) + +typedef struct rsa_pss_params_st { + X509_ALGOR *hashAlgorithm; + X509_ALGOR *maskGenAlgorithm; + ASN1_INTEGER *saltLength; + ASN1_INTEGER *trailerField; +} RSA_PSS_PARAMS; + +DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS) + +int RSA_print_fp(FILE *fp, const RSA *r, int offset); + +#ifndef OPENSSL_NO_BIO +int RSA_print(BIO *bp, const RSA *r, int offset); +#endif + +#ifndef OPENSSL_NO_RC4 +int i2d_RSA_NET(const RSA *a, unsigned char **pp, + int (*cb)(char *buf, int len, const char *prompt, int verify), int sgckey); +RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length, + int (*cb)(char *buf, int len, const char *prompt, int verify), int sgckey); + +int i2d_Netscape_RSA(const RSA *a, unsigned char **pp, + int (*cb)(char *buf, int len, const char *prompt, int verify)); +RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length, + int (*cb)(char *buf, int len, const char *prompt, int verify)); +#endif + +/* The following 2 functions sign and verify a X509_SIG ASN1 object + * inside PKCS#1 padded RSA encryption */ +int RSA_sign(int type, const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, RSA *rsa); +int RSA_verify(int type, const unsigned char *m, unsigned int m_length, + const unsigned char *sigbuf, unsigned int siglen, RSA *rsa); + +/* The following 2 function sign and verify a ASN1_OCTET_STRING + * object inside PKCS#1 padded RSA encryption */ +int RSA_sign_ASN1_OCTET_STRING(int type, const unsigned char *m, + unsigned int m_length, unsigned char *sigret, unsigned int *siglen, + RSA *rsa); +int RSA_verify_ASN1_OCTET_STRING(int type, const unsigned char *m, + unsigned int m_length, unsigned char *sigbuf, unsigned int siglen, + RSA *rsa); + +int RSA_blinding_on(RSA *rsa, BN_CTX *ctx); +void RSA_blinding_off(RSA *rsa); +BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx); + +int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int PKCS1_MGF1(unsigned char *mask, long len, + const unsigned char *seed, long seedlen, const EVP_MD *dgst); +int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *f, int fl, + const unsigned char *p, int pl); +int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len, + const unsigned char *p, int pl); +int RSA_padding_add_SSLv23(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_SSLv23(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_padding_add_none(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_none(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_padding_add_X931(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_X931(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_X931_hash_id(int nid); + +int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const unsigned char *EM, int sLen); +int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, const EVP_MD *Hash, int sLen); + +int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, const unsigned char *EM, + int sLen); + +int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, const EVP_MD *Hash, const EVP_MD *mgf1Hash, + int sLen); + +int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int RSA_set_ex_data(RSA *r, int idx, void *arg); +void *RSA_get_ex_data(const RSA *r, int idx); + +RSA *RSAPublicKey_dup(RSA *rsa); +RSA *RSAPrivateKey_dup(RSA *rsa); + +/* If this flag is set the RSA method is FIPS compliant and can be used + * in FIPS mode. This is set in the validated module method. If an + * application sets this flag in its own methods it is its responsibility + * to ensure the result is compliant. + */ + +#define RSA_FLAG_FIPS_METHOD 0x0400 + +/* If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +#define RSA_FLAG_NON_FIPS_ALLOW 0x0400 +/* Application has decided PRNG is good enough to generate a key: don't + * check. + */ +#define RSA_FLAG_CHECKED 0x0800 + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_RSA_strings(void); + +/* Error codes for the RSA functions. */ + +/* Function codes. */ +#define RSA_F_CHECK_PADDING_MD 140 +#define RSA_F_DO_RSA_PRINT 146 +#define RSA_F_INT_RSA_VERIFY 145 +#define RSA_F_MEMORY_LOCK 100 +#define RSA_F_OLD_RSA_PRIV_DECODE 147 +#define RSA_F_PKEY_RSA_CTRL 143 +#define RSA_F_PKEY_RSA_CTRL_STR 144 +#define RSA_F_PKEY_RSA_SIGN 142 +#define RSA_F_PKEY_RSA_VERIFY 154 +#define RSA_F_PKEY_RSA_VERIFYRECOVER 141 +#define RSA_F_RSA_BUILTIN_KEYGEN 129 +#define RSA_F_RSA_CHECK_KEY 123 +#define RSA_F_RSA_EAY_MOD_EXP 157 +#define RSA_F_RSA_EAY_PRIVATE_DECRYPT 101 +#define RSA_F_RSA_EAY_PRIVATE_ENCRYPT 102 +#define RSA_F_RSA_EAY_PUBLIC_DECRYPT 103 +#define RSA_F_RSA_EAY_PUBLIC_ENCRYPT 104 +#define RSA_F_RSA_GENERATE_KEY 105 +#define RSA_F_RSA_GENERATE_KEY_EX 155 +#define RSA_F_RSA_ITEM_VERIFY 156 +#define RSA_F_RSA_MEMORY_LOCK 130 +#define RSA_F_RSA_NEW_METHOD 106 +#define RSA_F_RSA_NULL 124 +#define RSA_F_RSA_NULL_MOD_EXP 131 +#define RSA_F_RSA_NULL_PRIVATE_DECRYPT 132 +#define RSA_F_RSA_NULL_PRIVATE_ENCRYPT 133 +#define RSA_F_RSA_NULL_PUBLIC_DECRYPT 134 +#define RSA_F_RSA_NULL_PUBLIC_ENCRYPT 135 +#define RSA_F_RSA_PADDING_ADD_NONE 107 +#define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP 121 +#define RSA_F_RSA_PADDING_ADD_PKCS1_PSS 125 +#define RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1 148 +#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1 108 +#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2 109 +#define RSA_F_RSA_PADDING_ADD_SSLV23 110 +#define RSA_F_RSA_PADDING_ADD_X931 127 +#define RSA_F_RSA_PADDING_CHECK_NONE 111 +#define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP 122 +#define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1 112 +#define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2 113 +#define RSA_F_RSA_PADDING_CHECK_SSLV23 114 +#define RSA_F_RSA_PADDING_CHECK_X931 128 +#define RSA_F_RSA_PRINT 115 +#define RSA_F_RSA_PRINT_FP 116 +#define RSA_F_RSA_PRIVATE_DECRYPT 150 +#define RSA_F_RSA_PRIVATE_ENCRYPT 151 +#define RSA_F_RSA_PRIV_DECODE 137 +#define RSA_F_RSA_PRIV_ENCODE 138 +#define RSA_F_RSA_PUBLIC_DECRYPT 152 +#define RSA_F_RSA_PUBLIC_ENCRYPT 153 +#define RSA_F_RSA_PUB_DECODE 139 +#define RSA_F_RSA_SETUP_BLINDING 136 +#define RSA_F_RSA_SIGN 117 +#define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118 +#define RSA_F_RSA_VERIFY 119 +#define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING 120 +#define RSA_F_RSA_VERIFY_PKCS1_PSS 126 +#define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1 149 + +/* Reason codes. */ +#define RSA_R_ALGORITHM_MISMATCH 100 +#define RSA_R_BAD_E_VALUE 101 +#define RSA_R_BAD_FIXED_HEADER_DECRYPT 102 +#define RSA_R_BAD_PAD_BYTE_COUNT 103 +#define RSA_R_BAD_SIGNATURE 104 +#define RSA_R_BLOCK_TYPE_IS_NOT_01 106 +#define RSA_R_BLOCK_TYPE_IS_NOT_02 107 +#define RSA_R_DATA_GREATER_THAN_MOD_LEN 108 +#define RSA_R_DATA_TOO_LARGE 109 +#define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 110 +#define RSA_R_DATA_TOO_LARGE_FOR_MODULUS 132 +#define RSA_R_DATA_TOO_SMALL 111 +#define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE 122 +#define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY 112 +#define RSA_R_DMP1_NOT_CONGRUENT_TO_D 124 +#define RSA_R_DMQ1_NOT_CONGRUENT_TO_D 125 +#define RSA_R_D_E_NOT_CONGRUENT_TO_1 123 +#define RSA_R_FIRST_OCTET_INVALID 133 +#define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 144 +#define RSA_R_INVALID_DIGEST_LENGTH 143 +#define RSA_R_INVALID_HEADER 137 +#define RSA_R_INVALID_KEYBITS 145 +#define RSA_R_INVALID_MESSAGE_LENGTH 131 +#define RSA_R_INVALID_MGF1_MD 156 +#define RSA_R_INVALID_PADDING 138 +#define RSA_R_INVALID_PADDING_MODE 141 +#define RSA_R_INVALID_PSS_PARAMETERS 149 +#define RSA_R_INVALID_PSS_SALTLEN 146 +#define RSA_R_INVALID_SALT_LENGTH 150 +#define RSA_R_INVALID_TRAILER 139 +#define RSA_R_INVALID_X931_DIGEST 142 +#define RSA_R_IQMP_NOT_INVERSE_OF_Q 126 +#define RSA_R_KEY_SIZE_TOO_SMALL 120 +#define RSA_R_LAST_OCTET_INVALID 134 +#define RSA_R_MODULUS_TOO_LARGE 105 +#define RSA_R_NON_FIPS_RSA_METHOD 157 +#define RSA_R_NO_PUBLIC_EXPONENT 140 +#define RSA_R_NULL_BEFORE_BLOCK_MISSING 113 +#define RSA_R_N_DOES_NOT_EQUAL_P_Q 127 +#define RSA_R_OAEP_DECODING_ERROR 121 +#define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 158 +#define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148 +#define RSA_R_PADDING_CHECK_FAILED 114 +#define RSA_R_P_NOT_PRIME 128 +#define RSA_R_Q_NOT_PRIME 129 +#define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED 130 +#define RSA_R_SLEN_CHECK_FAILED 136 +#define RSA_R_SLEN_RECOVERY_FAILED 135 +#define RSA_R_SSLV3_ROLLBACK_ATTACK 115 +#define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116 +#define RSA_R_UNKNOWN_ALGORITHM_TYPE 117 +#define RSA_R_UNKNOWN_MASK_DIGEST 151 +#define RSA_R_UNKNOWN_PADDING_TYPE 118 +#define RSA_R_UNKNOWN_PSS_DIGEST 152 +#define RSA_R_UNSUPPORTED_MASK_ALGORITHM 153 +#define RSA_R_UNSUPPORTED_MASK_PARAMETER 154 +#define RSA_R_UNSUPPORTED_SIGNATURE_TYPE 155 +#define RSA_R_VALUE_MISSING 147 +#define RSA_R_WRONG_SIGNATURE_LENGTH 119 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/safestack.h b/crypto/libressl/include/openssl/safestack.h new file mode 100644 index 0000000000..7f5ca554a5 --- /dev/null +++ b/crypto/libressl/include/openssl/safestack.h @@ -0,0 +1,2664 @@ +/* $OpenBSD$ */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_SAFESTACK_H +#define HEADER_SAFESTACK_H + +#include + +#ifndef CHECKED_PTR_OF +#define CHECKED_PTR_OF(type, p) \ + ((void*) (1 ? p : (type*)0)) +#endif + +/* In C++ we get problems because an explicit cast is needed from (void *) + * we use CHECKED_STACK_OF to ensure the correct type is passed in the macros + * below. + */ + +#define CHECKED_STACK_OF(type, p) \ + ((_STACK*) (1 ? p : (STACK_OF(type)*)0)) + +#define CHECKED_SK_FREE_FUNC(type, p) \ + ((void (*)(void *)) ((1 ? p : (void (*)(type *))0))) + +#define CHECKED_SK_FREE_FUNC2(type, p) \ + ((void (*)(void *)) ((1 ? p : (void (*)(type))0))) + +#define CHECKED_SK_CMP_FUNC(type, p) \ + ((int (*)(const void *, const void *)) \ + ((1 ? p : (int (*)(const type * const *, const type * const *))0))) + +#define STACK_OF(type) struct stack_st_##type +#define PREDECLARE_STACK_OF(type) STACK_OF(type); + +#define DECLARE_STACK_OF(type) \ +STACK_OF(type) \ + { \ + _STACK stack; \ + }; +#define DECLARE_SPECIAL_STACK_OF(type, type2) \ +STACK_OF(type) \ + { \ + _STACK stack; \ + }; + +#define IMPLEMENT_STACK_OF(type) /* nada (obsolete in new safestack approach)*/ + + +/* Strings are special: normally an lhash entry will point to a single + * (somewhat) mutable object. In the case of strings: + * + * a) Instead of a single char, there is an array of chars, NUL-terminated. + * b) The string may have be immutable. + * + * So, they need their own declarations. Especially important for + * type-checking tools, such as Deputy. + * +o * In practice, however, it appears to be hard to have a const + * string. For now, I'm settling for dealing with the fact it is a + * string at all. + */ +typedef char *OPENSSL_STRING; + +typedef const char *OPENSSL_CSTRING; + +/* Confusingly, LHASH_OF(STRING) deals with char ** throughout, but + * STACK_OF(STRING) is really more like STACK_OF(char), only, as + * mentioned above, instead of a single char each entry is a + * NUL-terminated array of chars. So, we have to implement STRING + * specially for STACK_OF. This is dealt with in the autogenerated + * macros below. + */ + +DECLARE_SPECIAL_STACK_OF(OPENSSL_STRING, char) + +/* Similarly, we sometimes use a block of characters, NOT + * nul-terminated. These should also be distinguished from "normal" + * stacks. */ + +typedef void *OPENSSL_BLOCK; +DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void) + +/* SKM_sk_... stack macros are internal to safestack.h: + * never use them directly, use sk__... instead */ +#define SKM_sk_new(type, cmp) \ + ((STACK_OF(type) *)sk_new(CHECKED_SK_CMP_FUNC(type, cmp))) +#define SKM_sk_new_null(type) \ + ((STACK_OF(type) *)sk_new_null()) +#define SKM_sk_free(type, st) \ + sk_free(CHECKED_STACK_OF(type, st)) +#define SKM_sk_num(type, st) \ + sk_num(CHECKED_STACK_OF(type, st)) +#define SKM_sk_value(type, st,i) \ + ((type *)sk_value(CHECKED_STACK_OF(type, st), i)) +#define SKM_sk_set(type, st,i,val) \ + sk_set(CHECKED_STACK_OF(type, st), i, CHECKED_PTR_OF(type, val)) +#define SKM_sk_zero(type, st) \ + sk_zero(CHECKED_STACK_OF(type, st)) +#define SKM_sk_push(type, st, val) \ + sk_push(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +#define SKM_sk_unshift(type, st, val) \ + sk_unshift(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +#define SKM_sk_find(type, st, val) \ + sk_find(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +#define SKM_sk_find_ex(type, st, val) \ + sk_find_ex(CHECKED_STACK_OF(type, st), \ + CHECKED_PTR_OF(type, val)) +#define SKM_sk_delete(type, st, i) \ + (type *)sk_delete(CHECKED_STACK_OF(type, st), i) +#define SKM_sk_delete_ptr(type, st, ptr) \ + (type *)sk_delete_ptr(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, ptr)) +#define SKM_sk_insert(type, st,val, i) \ + sk_insert(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val), i) +#define SKM_sk_set_cmp_func(type, st, cmp) \ + ((int (*)(const type * const *,const type * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(type, st), CHECKED_SK_CMP_FUNC(type, cmp))) +#define SKM_sk_dup(type, st) \ + (STACK_OF(type) *)sk_dup(CHECKED_STACK_OF(type, st)) +#define SKM_sk_pop_free(type, st, free_func) \ + sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func)) +#define SKM_sk_shift(type, st) \ + (type *)sk_shift(CHECKED_STACK_OF(type, st)) +#define SKM_sk_pop(type, st) \ + (type *)sk_pop(CHECKED_STACK_OF(type, st)) +#define SKM_sk_sort(type, st) \ + sk_sort(CHECKED_STACK_OF(type, st)) +#define SKM_sk_is_sorted(type, st) \ + sk_is_sorted(CHECKED_STACK_OF(type, st)) + +#define SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + (STACK_OF(type) *)d2i_ASN1_SET( \ + (STACK_OF(OPENSSL_BLOCK) **)CHECKED_PTR_OF(STACK_OF(type)*, st), \ + pp, length, \ + CHECKED_D2I_OF(type, d2i_func), \ + CHECKED_SK_FREE_FUNC(type, free_func), \ + ex_tag, ex_class) + +#define SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \ + i2d_ASN1_SET((STACK_OF(OPENSSL_BLOCK) *)CHECKED_STACK_OF(type, st), pp, \ + CHECKED_I2D_OF(type, i2d_func), \ + ex_tag, ex_class, is_set) + +#define SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \ + ASN1_seq_pack(CHECKED_PTR_OF(STACK_OF(type), st), \ + CHECKED_I2D_OF(type, i2d_func), buf, len) + +#define SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \ + (STACK_OF(type) *)ASN1_seq_unpack(buf, len, CHECKED_D2I_OF(type, d2i_func), CHECKED_SK_FREE_FUNC(type, free_func)) + +#define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \ + (STACK_OF(type) *)PKCS12_decrypt_d2i(algor, \ + CHECKED_D2I_OF(type, d2i_func), \ + CHECKED_SK_FREE_FUNC(type, free_func), \ + pass, passlen, oct, seq) + +/* This block of defines is updated by util/mkstack.pl, please do not touch! */ +#define sk_ACCESS_DESCRIPTION_new(cmp) SKM_sk_new(ACCESS_DESCRIPTION, (cmp)) +#define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION) +#define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st)) +#define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st)) +#define sk_ACCESS_DESCRIPTION_value(st, i) SKM_sk_value(ACCESS_DESCRIPTION, (st), (i)) +#define sk_ACCESS_DESCRIPTION_set(st, i, val) SKM_sk_set(ACCESS_DESCRIPTION, (st), (i), (val)) +#define sk_ACCESS_DESCRIPTION_zero(st) SKM_sk_zero(ACCESS_DESCRIPTION, (st)) +#define sk_ACCESS_DESCRIPTION_push(st, val) SKM_sk_push(ACCESS_DESCRIPTION, (st), (val)) +#define sk_ACCESS_DESCRIPTION_unshift(st, val) SKM_sk_unshift(ACCESS_DESCRIPTION, (st), (val)) +#define sk_ACCESS_DESCRIPTION_find(st, val) SKM_sk_find(ACCESS_DESCRIPTION, (st), (val)) +#define sk_ACCESS_DESCRIPTION_find_ex(st, val) SKM_sk_find_ex(ACCESS_DESCRIPTION, (st), (val)) +#define sk_ACCESS_DESCRIPTION_delete(st, i) SKM_sk_delete(ACCESS_DESCRIPTION, (st), (i)) +#define sk_ACCESS_DESCRIPTION_delete_ptr(st, ptr) SKM_sk_delete_ptr(ACCESS_DESCRIPTION, (st), (ptr)) +#define sk_ACCESS_DESCRIPTION_insert(st, val, i) SKM_sk_insert(ACCESS_DESCRIPTION, (st), (val), (i)) +#define sk_ACCESS_DESCRIPTION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ACCESS_DESCRIPTION, (st), (cmp)) +#define sk_ACCESS_DESCRIPTION_dup(st) SKM_sk_dup(ACCESS_DESCRIPTION, st) +#define sk_ACCESS_DESCRIPTION_pop_free(st, free_func) SKM_sk_pop_free(ACCESS_DESCRIPTION, (st), (free_func)) +#define sk_ACCESS_DESCRIPTION_shift(st) SKM_sk_shift(ACCESS_DESCRIPTION, (st)) +#define sk_ACCESS_DESCRIPTION_pop(st) SKM_sk_pop(ACCESS_DESCRIPTION, (st)) +#define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st)) +#define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st)) + +#define sk_ASIdOrRange_new(cmp) SKM_sk_new(ASIdOrRange, (cmp)) +#define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange) +#define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st)) +#define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st)) +#define sk_ASIdOrRange_value(st, i) SKM_sk_value(ASIdOrRange, (st), (i)) +#define sk_ASIdOrRange_set(st, i, val) SKM_sk_set(ASIdOrRange, (st), (i), (val)) +#define sk_ASIdOrRange_zero(st) SKM_sk_zero(ASIdOrRange, (st)) +#define sk_ASIdOrRange_push(st, val) SKM_sk_push(ASIdOrRange, (st), (val)) +#define sk_ASIdOrRange_unshift(st, val) SKM_sk_unshift(ASIdOrRange, (st), (val)) +#define sk_ASIdOrRange_find(st, val) SKM_sk_find(ASIdOrRange, (st), (val)) +#define sk_ASIdOrRange_find_ex(st, val) SKM_sk_find_ex(ASIdOrRange, (st), (val)) +#define sk_ASIdOrRange_delete(st, i) SKM_sk_delete(ASIdOrRange, (st), (i)) +#define sk_ASIdOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASIdOrRange, (st), (ptr)) +#define sk_ASIdOrRange_insert(st, val, i) SKM_sk_insert(ASIdOrRange, (st), (val), (i)) +#define sk_ASIdOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASIdOrRange, (st), (cmp)) +#define sk_ASIdOrRange_dup(st) SKM_sk_dup(ASIdOrRange, st) +#define sk_ASIdOrRange_pop_free(st, free_func) SKM_sk_pop_free(ASIdOrRange, (st), (free_func)) +#define sk_ASIdOrRange_shift(st) SKM_sk_shift(ASIdOrRange, (st)) +#define sk_ASIdOrRange_pop(st) SKM_sk_pop(ASIdOrRange, (st)) +#define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st)) +#define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st)) + +#define sk_ASN1_GENERALSTRING_new(cmp) SKM_sk_new(ASN1_GENERALSTRING, (cmp)) +#define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING) +#define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st)) +#define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st)) +#define sk_ASN1_GENERALSTRING_value(st, i) SKM_sk_value(ASN1_GENERALSTRING, (st), (i)) +#define sk_ASN1_GENERALSTRING_set(st, i, val) SKM_sk_set(ASN1_GENERALSTRING, (st), (i), (val)) +#define sk_ASN1_GENERALSTRING_zero(st) SKM_sk_zero(ASN1_GENERALSTRING, (st)) +#define sk_ASN1_GENERALSTRING_push(st, val) SKM_sk_push(ASN1_GENERALSTRING, (st), (val)) +#define sk_ASN1_GENERALSTRING_unshift(st, val) SKM_sk_unshift(ASN1_GENERALSTRING, (st), (val)) +#define sk_ASN1_GENERALSTRING_find(st, val) SKM_sk_find(ASN1_GENERALSTRING, (st), (val)) +#define sk_ASN1_GENERALSTRING_find_ex(st, val) SKM_sk_find_ex(ASN1_GENERALSTRING, (st), (val)) +#define sk_ASN1_GENERALSTRING_delete(st, i) SKM_sk_delete(ASN1_GENERALSTRING, (st), (i)) +#define sk_ASN1_GENERALSTRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_GENERALSTRING, (st), (ptr)) +#define sk_ASN1_GENERALSTRING_insert(st, val, i) SKM_sk_insert(ASN1_GENERALSTRING, (st), (val), (i)) +#define sk_ASN1_GENERALSTRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_GENERALSTRING, (st), (cmp)) +#define sk_ASN1_GENERALSTRING_dup(st) SKM_sk_dup(ASN1_GENERALSTRING, st) +#define sk_ASN1_GENERALSTRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_GENERALSTRING, (st), (free_func)) +#define sk_ASN1_GENERALSTRING_shift(st) SKM_sk_shift(ASN1_GENERALSTRING, (st)) +#define sk_ASN1_GENERALSTRING_pop(st) SKM_sk_pop(ASN1_GENERALSTRING, (st)) +#define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st)) +#define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st)) + +#define sk_ASN1_INTEGER_new(cmp) SKM_sk_new(ASN1_INTEGER, (cmp)) +#define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER) +#define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st)) +#define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st)) +#define sk_ASN1_INTEGER_value(st, i) SKM_sk_value(ASN1_INTEGER, (st), (i)) +#define sk_ASN1_INTEGER_set(st, i, val) SKM_sk_set(ASN1_INTEGER, (st), (i), (val)) +#define sk_ASN1_INTEGER_zero(st) SKM_sk_zero(ASN1_INTEGER, (st)) +#define sk_ASN1_INTEGER_push(st, val) SKM_sk_push(ASN1_INTEGER, (st), (val)) +#define sk_ASN1_INTEGER_unshift(st, val) SKM_sk_unshift(ASN1_INTEGER, (st), (val)) +#define sk_ASN1_INTEGER_find(st, val) SKM_sk_find(ASN1_INTEGER, (st), (val)) +#define sk_ASN1_INTEGER_find_ex(st, val) SKM_sk_find_ex(ASN1_INTEGER, (st), (val)) +#define sk_ASN1_INTEGER_delete(st, i) SKM_sk_delete(ASN1_INTEGER, (st), (i)) +#define sk_ASN1_INTEGER_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_INTEGER, (st), (ptr)) +#define sk_ASN1_INTEGER_insert(st, val, i) SKM_sk_insert(ASN1_INTEGER, (st), (val), (i)) +#define sk_ASN1_INTEGER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_INTEGER, (st), (cmp)) +#define sk_ASN1_INTEGER_dup(st) SKM_sk_dup(ASN1_INTEGER, st) +#define sk_ASN1_INTEGER_pop_free(st, free_func) SKM_sk_pop_free(ASN1_INTEGER, (st), (free_func)) +#define sk_ASN1_INTEGER_shift(st) SKM_sk_shift(ASN1_INTEGER, (st)) +#define sk_ASN1_INTEGER_pop(st) SKM_sk_pop(ASN1_INTEGER, (st)) +#define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st)) +#define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st)) + +#define sk_ASN1_OBJECT_new(cmp) SKM_sk_new(ASN1_OBJECT, (cmp)) +#define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT) +#define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st)) +#define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st)) +#define sk_ASN1_OBJECT_value(st, i) SKM_sk_value(ASN1_OBJECT, (st), (i)) +#define sk_ASN1_OBJECT_set(st, i, val) SKM_sk_set(ASN1_OBJECT, (st), (i), (val)) +#define sk_ASN1_OBJECT_zero(st) SKM_sk_zero(ASN1_OBJECT, (st)) +#define sk_ASN1_OBJECT_push(st, val) SKM_sk_push(ASN1_OBJECT, (st), (val)) +#define sk_ASN1_OBJECT_unshift(st, val) SKM_sk_unshift(ASN1_OBJECT, (st), (val)) +#define sk_ASN1_OBJECT_find(st, val) SKM_sk_find(ASN1_OBJECT, (st), (val)) +#define sk_ASN1_OBJECT_find_ex(st, val) SKM_sk_find_ex(ASN1_OBJECT, (st), (val)) +#define sk_ASN1_OBJECT_delete(st, i) SKM_sk_delete(ASN1_OBJECT, (st), (i)) +#define sk_ASN1_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_OBJECT, (st), (ptr)) +#define sk_ASN1_OBJECT_insert(st, val, i) SKM_sk_insert(ASN1_OBJECT, (st), (val), (i)) +#define sk_ASN1_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_OBJECT, (st), (cmp)) +#define sk_ASN1_OBJECT_dup(st) SKM_sk_dup(ASN1_OBJECT, st) +#define sk_ASN1_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(ASN1_OBJECT, (st), (free_func)) +#define sk_ASN1_OBJECT_shift(st) SKM_sk_shift(ASN1_OBJECT, (st)) +#define sk_ASN1_OBJECT_pop(st) SKM_sk_pop(ASN1_OBJECT, (st)) +#define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st)) +#define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st)) + +#define sk_ASN1_STRING_TABLE_new(cmp) SKM_sk_new(ASN1_STRING_TABLE, (cmp)) +#define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE) +#define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st)) +#define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st)) +#define sk_ASN1_STRING_TABLE_value(st, i) SKM_sk_value(ASN1_STRING_TABLE, (st), (i)) +#define sk_ASN1_STRING_TABLE_set(st, i, val) SKM_sk_set(ASN1_STRING_TABLE, (st), (i), (val)) +#define sk_ASN1_STRING_TABLE_zero(st) SKM_sk_zero(ASN1_STRING_TABLE, (st)) +#define sk_ASN1_STRING_TABLE_push(st, val) SKM_sk_push(ASN1_STRING_TABLE, (st), (val)) +#define sk_ASN1_STRING_TABLE_unshift(st, val) SKM_sk_unshift(ASN1_STRING_TABLE, (st), (val)) +#define sk_ASN1_STRING_TABLE_find(st, val) SKM_sk_find(ASN1_STRING_TABLE, (st), (val)) +#define sk_ASN1_STRING_TABLE_find_ex(st, val) SKM_sk_find_ex(ASN1_STRING_TABLE, (st), (val)) +#define sk_ASN1_STRING_TABLE_delete(st, i) SKM_sk_delete(ASN1_STRING_TABLE, (st), (i)) +#define sk_ASN1_STRING_TABLE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_STRING_TABLE, (st), (ptr)) +#define sk_ASN1_STRING_TABLE_insert(st, val, i) SKM_sk_insert(ASN1_STRING_TABLE, (st), (val), (i)) +#define sk_ASN1_STRING_TABLE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_STRING_TABLE, (st), (cmp)) +#define sk_ASN1_STRING_TABLE_dup(st) SKM_sk_dup(ASN1_STRING_TABLE, st) +#define sk_ASN1_STRING_TABLE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_STRING_TABLE, (st), (free_func)) +#define sk_ASN1_STRING_TABLE_shift(st) SKM_sk_shift(ASN1_STRING_TABLE, (st)) +#define sk_ASN1_STRING_TABLE_pop(st) SKM_sk_pop(ASN1_STRING_TABLE, (st)) +#define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st)) +#define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st)) + +#define sk_ASN1_TYPE_new(cmp) SKM_sk_new(ASN1_TYPE, (cmp)) +#define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE) +#define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st)) +#define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st)) +#define sk_ASN1_TYPE_value(st, i) SKM_sk_value(ASN1_TYPE, (st), (i)) +#define sk_ASN1_TYPE_set(st, i, val) SKM_sk_set(ASN1_TYPE, (st), (i), (val)) +#define sk_ASN1_TYPE_zero(st) SKM_sk_zero(ASN1_TYPE, (st)) +#define sk_ASN1_TYPE_push(st, val) SKM_sk_push(ASN1_TYPE, (st), (val)) +#define sk_ASN1_TYPE_unshift(st, val) SKM_sk_unshift(ASN1_TYPE, (st), (val)) +#define sk_ASN1_TYPE_find(st, val) SKM_sk_find(ASN1_TYPE, (st), (val)) +#define sk_ASN1_TYPE_find_ex(st, val) SKM_sk_find_ex(ASN1_TYPE, (st), (val)) +#define sk_ASN1_TYPE_delete(st, i) SKM_sk_delete(ASN1_TYPE, (st), (i)) +#define sk_ASN1_TYPE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_TYPE, (st), (ptr)) +#define sk_ASN1_TYPE_insert(st, val, i) SKM_sk_insert(ASN1_TYPE, (st), (val), (i)) +#define sk_ASN1_TYPE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_TYPE, (st), (cmp)) +#define sk_ASN1_TYPE_dup(st) SKM_sk_dup(ASN1_TYPE, st) +#define sk_ASN1_TYPE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_TYPE, (st), (free_func)) +#define sk_ASN1_TYPE_shift(st) SKM_sk_shift(ASN1_TYPE, (st)) +#define sk_ASN1_TYPE_pop(st) SKM_sk_pop(ASN1_TYPE, (st)) +#define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st)) +#define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st)) + +#define sk_ASN1_UTF8STRING_new(cmp) SKM_sk_new(ASN1_UTF8STRING, (cmp)) +#define sk_ASN1_UTF8STRING_new_null() SKM_sk_new_null(ASN1_UTF8STRING) +#define sk_ASN1_UTF8STRING_free(st) SKM_sk_free(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_num(st) SKM_sk_num(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_value(st, i) SKM_sk_value(ASN1_UTF8STRING, (st), (i)) +#define sk_ASN1_UTF8STRING_set(st, i, val) SKM_sk_set(ASN1_UTF8STRING, (st), (i), (val)) +#define sk_ASN1_UTF8STRING_zero(st) SKM_sk_zero(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_push(st, val) SKM_sk_push(ASN1_UTF8STRING, (st), (val)) +#define sk_ASN1_UTF8STRING_unshift(st, val) SKM_sk_unshift(ASN1_UTF8STRING, (st), (val)) +#define sk_ASN1_UTF8STRING_find(st, val) SKM_sk_find(ASN1_UTF8STRING, (st), (val)) +#define sk_ASN1_UTF8STRING_find_ex(st, val) SKM_sk_find_ex(ASN1_UTF8STRING, (st), (val)) +#define sk_ASN1_UTF8STRING_delete(st, i) SKM_sk_delete(ASN1_UTF8STRING, (st), (i)) +#define sk_ASN1_UTF8STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_UTF8STRING, (st), (ptr)) +#define sk_ASN1_UTF8STRING_insert(st, val, i) SKM_sk_insert(ASN1_UTF8STRING, (st), (val), (i)) +#define sk_ASN1_UTF8STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_UTF8STRING, (st), (cmp)) +#define sk_ASN1_UTF8STRING_dup(st) SKM_sk_dup(ASN1_UTF8STRING, st) +#define sk_ASN1_UTF8STRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_UTF8STRING, (st), (free_func)) +#define sk_ASN1_UTF8STRING_shift(st) SKM_sk_shift(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_pop(st) SKM_sk_pop(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_sort(st) SKM_sk_sort(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_is_sorted(st) SKM_sk_is_sorted(ASN1_UTF8STRING, (st)) + +#define sk_ASN1_VALUE_new(cmp) SKM_sk_new(ASN1_VALUE, (cmp)) +#define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE) +#define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st)) +#define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st)) +#define sk_ASN1_VALUE_value(st, i) SKM_sk_value(ASN1_VALUE, (st), (i)) +#define sk_ASN1_VALUE_set(st, i, val) SKM_sk_set(ASN1_VALUE, (st), (i), (val)) +#define sk_ASN1_VALUE_zero(st) SKM_sk_zero(ASN1_VALUE, (st)) +#define sk_ASN1_VALUE_push(st, val) SKM_sk_push(ASN1_VALUE, (st), (val)) +#define sk_ASN1_VALUE_unshift(st, val) SKM_sk_unshift(ASN1_VALUE, (st), (val)) +#define sk_ASN1_VALUE_find(st, val) SKM_sk_find(ASN1_VALUE, (st), (val)) +#define sk_ASN1_VALUE_find_ex(st, val) SKM_sk_find_ex(ASN1_VALUE, (st), (val)) +#define sk_ASN1_VALUE_delete(st, i) SKM_sk_delete(ASN1_VALUE, (st), (i)) +#define sk_ASN1_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_VALUE, (st), (ptr)) +#define sk_ASN1_VALUE_insert(st, val, i) SKM_sk_insert(ASN1_VALUE, (st), (val), (i)) +#define sk_ASN1_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_VALUE, (st), (cmp)) +#define sk_ASN1_VALUE_dup(st) SKM_sk_dup(ASN1_VALUE, st) +#define sk_ASN1_VALUE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_VALUE, (st), (free_func)) +#define sk_ASN1_VALUE_shift(st) SKM_sk_shift(ASN1_VALUE, (st)) +#define sk_ASN1_VALUE_pop(st) SKM_sk_pop(ASN1_VALUE, (st)) +#define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st)) +#define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st)) + +#define sk_BIO_new(cmp) SKM_sk_new(BIO, (cmp)) +#define sk_BIO_new_null() SKM_sk_new_null(BIO) +#define sk_BIO_free(st) SKM_sk_free(BIO, (st)) +#define sk_BIO_num(st) SKM_sk_num(BIO, (st)) +#define sk_BIO_value(st, i) SKM_sk_value(BIO, (st), (i)) +#define sk_BIO_set(st, i, val) SKM_sk_set(BIO, (st), (i), (val)) +#define sk_BIO_zero(st) SKM_sk_zero(BIO, (st)) +#define sk_BIO_push(st, val) SKM_sk_push(BIO, (st), (val)) +#define sk_BIO_unshift(st, val) SKM_sk_unshift(BIO, (st), (val)) +#define sk_BIO_find(st, val) SKM_sk_find(BIO, (st), (val)) +#define sk_BIO_find_ex(st, val) SKM_sk_find_ex(BIO, (st), (val)) +#define sk_BIO_delete(st, i) SKM_sk_delete(BIO, (st), (i)) +#define sk_BIO_delete_ptr(st, ptr) SKM_sk_delete_ptr(BIO, (st), (ptr)) +#define sk_BIO_insert(st, val, i) SKM_sk_insert(BIO, (st), (val), (i)) +#define sk_BIO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BIO, (st), (cmp)) +#define sk_BIO_dup(st) SKM_sk_dup(BIO, st) +#define sk_BIO_pop_free(st, free_func) SKM_sk_pop_free(BIO, (st), (free_func)) +#define sk_BIO_shift(st) SKM_sk_shift(BIO, (st)) +#define sk_BIO_pop(st) SKM_sk_pop(BIO, (st)) +#define sk_BIO_sort(st) SKM_sk_sort(BIO, (st)) +#define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st)) + +#define sk_BY_DIR_ENTRY_new(cmp) SKM_sk_new(BY_DIR_ENTRY, (cmp)) +#define sk_BY_DIR_ENTRY_new_null() SKM_sk_new_null(BY_DIR_ENTRY) +#define sk_BY_DIR_ENTRY_free(st) SKM_sk_free(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_num(st) SKM_sk_num(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_value(st, i) SKM_sk_value(BY_DIR_ENTRY, (st), (i)) +#define sk_BY_DIR_ENTRY_set(st, i, val) SKM_sk_set(BY_DIR_ENTRY, (st), (i), (val)) +#define sk_BY_DIR_ENTRY_zero(st) SKM_sk_zero(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_push(st, val) SKM_sk_push(BY_DIR_ENTRY, (st), (val)) +#define sk_BY_DIR_ENTRY_unshift(st, val) SKM_sk_unshift(BY_DIR_ENTRY, (st), (val)) +#define sk_BY_DIR_ENTRY_find(st, val) SKM_sk_find(BY_DIR_ENTRY, (st), (val)) +#define sk_BY_DIR_ENTRY_find_ex(st, val) SKM_sk_find_ex(BY_DIR_ENTRY, (st), (val)) +#define sk_BY_DIR_ENTRY_delete(st, i) SKM_sk_delete(BY_DIR_ENTRY, (st), (i)) +#define sk_BY_DIR_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_ENTRY, (st), (ptr)) +#define sk_BY_DIR_ENTRY_insert(st, val, i) SKM_sk_insert(BY_DIR_ENTRY, (st), (val), (i)) +#define sk_BY_DIR_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_ENTRY, (st), (cmp)) +#define sk_BY_DIR_ENTRY_dup(st) SKM_sk_dup(BY_DIR_ENTRY, st) +#define sk_BY_DIR_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_ENTRY, (st), (free_func)) +#define sk_BY_DIR_ENTRY_shift(st) SKM_sk_shift(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_pop(st) SKM_sk_pop(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_sort(st) SKM_sk_sort(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_is_sorted(st) SKM_sk_is_sorted(BY_DIR_ENTRY, (st)) + +#define sk_BY_DIR_HASH_new(cmp) SKM_sk_new(BY_DIR_HASH, (cmp)) +#define sk_BY_DIR_HASH_new_null() SKM_sk_new_null(BY_DIR_HASH) +#define sk_BY_DIR_HASH_free(st) SKM_sk_free(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_num(st) SKM_sk_num(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_value(st, i) SKM_sk_value(BY_DIR_HASH, (st), (i)) +#define sk_BY_DIR_HASH_set(st, i, val) SKM_sk_set(BY_DIR_HASH, (st), (i), (val)) +#define sk_BY_DIR_HASH_zero(st) SKM_sk_zero(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_push(st, val) SKM_sk_push(BY_DIR_HASH, (st), (val)) +#define sk_BY_DIR_HASH_unshift(st, val) SKM_sk_unshift(BY_DIR_HASH, (st), (val)) +#define sk_BY_DIR_HASH_find(st, val) SKM_sk_find(BY_DIR_HASH, (st), (val)) +#define sk_BY_DIR_HASH_find_ex(st, val) SKM_sk_find_ex(BY_DIR_HASH, (st), (val)) +#define sk_BY_DIR_HASH_delete(st, i) SKM_sk_delete(BY_DIR_HASH, (st), (i)) +#define sk_BY_DIR_HASH_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_HASH, (st), (ptr)) +#define sk_BY_DIR_HASH_insert(st, val, i) SKM_sk_insert(BY_DIR_HASH, (st), (val), (i)) +#define sk_BY_DIR_HASH_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_HASH, (st), (cmp)) +#define sk_BY_DIR_HASH_dup(st) SKM_sk_dup(BY_DIR_HASH, st) +#define sk_BY_DIR_HASH_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_HASH, (st), (free_func)) +#define sk_BY_DIR_HASH_shift(st) SKM_sk_shift(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_pop(st) SKM_sk_pop(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_sort(st) SKM_sk_sort(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_is_sorted(st) SKM_sk_is_sorted(BY_DIR_HASH, (st)) + +#define sk_CMS_CertificateChoices_new(cmp) SKM_sk_new(CMS_CertificateChoices, (cmp)) +#define sk_CMS_CertificateChoices_new_null() SKM_sk_new_null(CMS_CertificateChoices) +#define sk_CMS_CertificateChoices_free(st) SKM_sk_free(CMS_CertificateChoices, (st)) +#define sk_CMS_CertificateChoices_num(st) SKM_sk_num(CMS_CertificateChoices, (st)) +#define sk_CMS_CertificateChoices_value(st, i) SKM_sk_value(CMS_CertificateChoices, (st), (i)) +#define sk_CMS_CertificateChoices_set(st, i, val) SKM_sk_set(CMS_CertificateChoices, (st), (i), (val)) +#define sk_CMS_CertificateChoices_zero(st) SKM_sk_zero(CMS_CertificateChoices, (st)) +#define sk_CMS_CertificateChoices_push(st, val) SKM_sk_push(CMS_CertificateChoices, (st), (val)) +#define sk_CMS_CertificateChoices_unshift(st, val) SKM_sk_unshift(CMS_CertificateChoices, (st), (val)) +#define sk_CMS_CertificateChoices_find(st, val) SKM_sk_find(CMS_CertificateChoices, (st), (val)) +#define sk_CMS_CertificateChoices_find_ex(st, val) SKM_sk_find_ex(CMS_CertificateChoices, (st), (val)) +#define sk_CMS_CertificateChoices_delete(st, i) SKM_sk_delete(CMS_CertificateChoices, (st), (i)) +#define sk_CMS_CertificateChoices_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_CertificateChoices, (st), (ptr)) +#define sk_CMS_CertificateChoices_insert(st, val, i) SKM_sk_insert(CMS_CertificateChoices, (st), (val), (i)) +#define sk_CMS_CertificateChoices_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_CertificateChoices, (st), (cmp)) +#define sk_CMS_CertificateChoices_dup(st) SKM_sk_dup(CMS_CertificateChoices, st) +#define sk_CMS_CertificateChoices_pop_free(st, free_func) SKM_sk_pop_free(CMS_CertificateChoices, (st), (free_func)) +#define sk_CMS_CertificateChoices_shift(st) SKM_sk_shift(CMS_CertificateChoices, (st)) +#define sk_CMS_CertificateChoices_pop(st) SKM_sk_pop(CMS_CertificateChoices, (st)) +#define sk_CMS_CertificateChoices_sort(st) SKM_sk_sort(CMS_CertificateChoices, (st)) +#define sk_CMS_CertificateChoices_is_sorted(st) SKM_sk_is_sorted(CMS_CertificateChoices, (st)) + +#define sk_CMS_RecipientInfo_new(cmp) SKM_sk_new(CMS_RecipientInfo, (cmp)) +#define sk_CMS_RecipientInfo_new_null() SKM_sk_new_null(CMS_RecipientInfo) +#define sk_CMS_RecipientInfo_free(st) SKM_sk_free(CMS_RecipientInfo, (st)) +#define sk_CMS_RecipientInfo_num(st) SKM_sk_num(CMS_RecipientInfo, (st)) +#define sk_CMS_RecipientInfo_value(st, i) SKM_sk_value(CMS_RecipientInfo, (st), (i)) +#define sk_CMS_RecipientInfo_set(st, i, val) SKM_sk_set(CMS_RecipientInfo, (st), (i), (val)) +#define sk_CMS_RecipientInfo_zero(st) SKM_sk_zero(CMS_RecipientInfo, (st)) +#define sk_CMS_RecipientInfo_push(st, val) SKM_sk_push(CMS_RecipientInfo, (st), (val)) +#define sk_CMS_RecipientInfo_unshift(st, val) SKM_sk_unshift(CMS_RecipientInfo, (st), (val)) +#define sk_CMS_RecipientInfo_find(st, val) SKM_sk_find(CMS_RecipientInfo, (st), (val)) +#define sk_CMS_RecipientInfo_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientInfo, (st), (val)) +#define sk_CMS_RecipientInfo_delete(st, i) SKM_sk_delete(CMS_RecipientInfo, (st), (i)) +#define sk_CMS_RecipientInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientInfo, (st), (ptr)) +#define sk_CMS_RecipientInfo_insert(st, val, i) SKM_sk_insert(CMS_RecipientInfo, (st), (val), (i)) +#define sk_CMS_RecipientInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientInfo, (st), (cmp)) +#define sk_CMS_RecipientInfo_dup(st) SKM_sk_dup(CMS_RecipientInfo, st) +#define sk_CMS_RecipientInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientInfo, (st), (free_func)) +#define sk_CMS_RecipientInfo_shift(st) SKM_sk_shift(CMS_RecipientInfo, (st)) +#define sk_CMS_RecipientInfo_pop(st) SKM_sk_pop(CMS_RecipientInfo, (st)) +#define sk_CMS_RecipientInfo_sort(st) SKM_sk_sort(CMS_RecipientInfo, (st)) +#define sk_CMS_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientInfo, (st)) + +#define sk_CMS_RevocationInfoChoice_new(cmp) SKM_sk_new(CMS_RevocationInfoChoice, (cmp)) +#define sk_CMS_RevocationInfoChoice_new_null() SKM_sk_new_null(CMS_RevocationInfoChoice) +#define sk_CMS_RevocationInfoChoice_free(st) SKM_sk_free(CMS_RevocationInfoChoice, (st)) +#define sk_CMS_RevocationInfoChoice_num(st) SKM_sk_num(CMS_RevocationInfoChoice, (st)) +#define sk_CMS_RevocationInfoChoice_value(st, i) SKM_sk_value(CMS_RevocationInfoChoice, (st), (i)) +#define sk_CMS_RevocationInfoChoice_set(st, i, val) SKM_sk_set(CMS_RevocationInfoChoice, (st), (i), (val)) +#define sk_CMS_RevocationInfoChoice_zero(st) SKM_sk_zero(CMS_RevocationInfoChoice, (st)) +#define sk_CMS_RevocationInfoChoice_push(st, val) SKM_sk_push(CMS_RevocationInfoChoice, (st), (val)) +#define sk_CMS_RevocationInfoChoice_unshift(st, val) SKM_sk_unshift(CMS_RevocationInfoChoice, (st), (val)) +#define sk_CMS_RevocationInfoChoice_find(st, val) SKM_sk_find(CMS_RevocationInfoChoice, (st), (val)) +#define sk_CMS_RevocationInfoChoice_find_ex(st, val) SKM_sk_find_ex(CMS_RevocationInfoChoice, (st), (val)) +#define sk_CMS_RevocationInfoChoice_delete(st, i) SKM_sk_delete(CMS_RevocationInfoChoice, (st), (i)) +#define sk_CMS_RevocationInfoChoice_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RevocationInfoChoice, (st), (ptr)) +#define sk_CMS_RevocationInfoChoice_insert(st, val, i) SKM_sk_insert(CMS_RevocationInfoChoice, (st), (val), (i)) +#define sk_CMS_RevocationInfoChoice_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RevocationInfoChoice, (st), (cmp)) +#define sk_CMS_RevocationInfoChoice_dup(st) SKM_sk_dup(CMS_RevocationInfoChoice, st) +#define sk_CMS_RevocationInfoChoice_pop_free(st, free_func) SKM_sk_pop_free(CMS_RevocationInfoChoice, (st), (free_func)) +#define sk_CMS_RevocationInfoChoice_shift(st) SKM_sk_shift(CMS_RevocationInfoChoice, (st)) +#define sk_CMS_RevocationInfoChoice_pop(st) SKM_sk_pop(CMS_RevocationInfoChoice, (st)) +#define sk_CMS_RevocationInfoChoice_sort(st) SKM_sk_sort(CMS_RevocationInfoChoice, (st)) +#define sk_CMS_RevocationInfoChoice_is_sorted(st) SKM_sk_is_sorted(CMS_RevocationInfoChoice, (st)) + +#define sk_CMS_SignerInfo_new(cmp) SKM_sk_new(CMS_SignerInfo, (cmp)) +#define sk_CMS_SignerInfo_new_null() SKM_sk_new_null(CMS_SignerInfo) +#define sk_CMS_SignerInfo_free(st) SKM_sk_free(CMS_SignerInfo, (st)) +#define sk_CMS_SignerInfo_num(st) SKM_sk_num(CMS_SignerInfo, (st)) +#define sk_CMS_SignerInfo_value(st, i) SKM_sk_value(CMS_SignerInfo, (st), (i)) +#define sk_CMS_SignerInfo_set(st, i, val) SKM_sk_set(CMS_SignerInfo, (st), (i), (val)) +#define sk_CMS_SignerInfo_zero(st) SKM_sk_zero(CMS_SignerInfo, (st)) +#define sk_CMS_SignerInfo_push(st, val) SKM_sk_push(CMS_SignerInfo, (st), (val)) +#define sk_CMS_SignerInfo_unshift(st, val) SKM_sk_unshift(CMS_SignerInfo, (st), (val)) +#define sk_CMS_SignerInfo_find(st, val) SKM_sk_find(CMS_SignerInfo, (st), (val)) +#define sk_CMS_SignerInfo_find_ex(st, val) SKM_sk_find_ex(CMS_SignerInfo, (st), (val)) +#define sk_CMS_SignerInfo_delete(st, i) SKM_sk_delete(CMS_SignerInfo, (st), (i)) +#define sk_CMS_SignerInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_SignerInfo, (st), (ptr)) +#define sk_CMS_SignerInfo_insert(st, val, i) SKM_sk_insert(CMS_SignerInfo, (st), (val), (i)) +#define sk_CMS_SignerInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_SignerInfo, (st), (cmp)) +#define sk_CMS_SignerInfo_dup(st) SKM_sk_dup(CMS_SignerInfo, st) +#define sk_CMS_SignerInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_SignerInfo, (st), (free_func)) +#define sk_CMS_SignerInfo_shift(st) SKM_sk_shift(CMS_SignerInfo, (st)) +#define sk_CMS_SignerInfo_pop(st) SKM_sk_pop(CMS_SignerInfo, (st)) +#define sk_CMS_SignerInfo_sort(st) SKM_sk_sort(CMS_SignerInfo, (st)) +#define sk_CMS_SignerInfo_is_sorted(st) SKM_sk_is_sorted(CMS_SignerInfo, (st)) + +#define sk_CONF_IMODULE_new(cmp) SKM_sk_new(CONF_IMODULE, (cmp)) +#define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE) +#define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st)) +#define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st)) +#define sk_CONF_IMODULE_value(st, i) SKM_sk_value(CONF_IMODULE, (st), (i)) +#define sk_CONF_IMODULE_set(st, i, val) SKM_sk_set(CONF_IMODULE, (st), (i), (val)) +#define sk_CONF_IMODULE_zero(st) SKM_sk_zero(CONF_IMODULE, (st)) +#define sk_CONF_IMODULE_push(st, val) SKM_sk_push(CONF_IMODULE, (st), (val)) +#define sk_CONF_IMODULE_unshift(st, val) SKM_sk_unshift(CONF_IMODULE, (st), (val)) +#define sk_CONF_IMODULE_find(st, val) SKM_sk_find(CONF_IMODULE, (st), (val)) +#define sk_CONF_IMODULE_find_ex(st, val) SKM_sk_find_ex(CONF_IMODULE, (st), (val)) +#define sk_CONF_IMODULE_delete(st, i) SKM_sk_delete(CONF_IMODULE, (st), (i)) +#define sk_CONF_IMODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_IMODULE, (st), (ptr)) +#define sk_CONF_IMODULE_insert(st, val, i) SKM_sk_insert(CONF_IMODULE, (st), (val), (i)) +#define sk_CONF_IMODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_IMODULE, (st), (cmp)) +#define sk_CONF_IMODULE_dup(st) SKM_sk_dup(CONF_IMODULE, st) +#define sk_CONF_IMODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_IMODULE, (st), (free_func)) +#define sk_CONF_IMODULE_shift(st) SKM_sk_shift(CONF_IMODULE, (st)) +#define sk_CONF_IMODULE_pop(st) SKM_sk_pop(CONF_IMODULE, (st)) +#define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st)) +#define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st)) + +#define sk_CONF_MODULE_new(cmp) SKM_sk_new(CONF_MODULE, (cmp)) +#define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE) +#define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st)) +#define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st)) +#define sk_CONF_MODULE_value(st, i) SKM_sk_value(CONF_MODULE, (st), (i)) +#define sk_CONF_MODULE_set(st, i, val) SKM_sk_set(CONF_MODULE, (st), (i), (val)) +#define sk_CONF_MODULE_zero(st) SKM_sk_zero(CONF_MODULE, (st)) +#define sk_CONF_MODULE_push(st, val) SKM_sk_push(CONF_MODULE, (st), (val)) +#define sk_CONF_MODULE_unshift(st, val) SKM_sk_unshift(CONF_MODULE, (st), (val)) +#define sk_CONF_MODULE_find(st, val) SKM_sk_find(CONF_MODULE, (st), (val)) +#define sk_CONF_MODULE_find_ex(st, val) SKM_sk_find_ex(CONF_MODULE, (st), (val)) +#define sk_CONF_MODULE_delete(st, i) SKM_sk_delete(CONF_MODULE, (st), (i)) +#define sk_CONF_MODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_MODULE, (st), (ptr)) +#define sk_CONF_MODULE_insert(st, val, i) SKM_sk_insert(CONF_MODULE, (st), (val), (i)) +#define sk_CONF_MODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_MODULE, (st), (cmp)) +#define sk_CONF_MODULE_dup(st) SKM_sk_dup(CONF_MODULE, st) +#define sk_CONF_MODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_MODULE, (st), (free_func)) +#define sk_CONF_MODULE_shift(st) SKM_sk_shift(CONF_MODULE, (st)) +#define sk_CONF_MODULE_pop(st) SKM_sk_pop(CONF_MODULE, (st)) +#define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st)) +#define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st)) + +#define sk_CONF_VALUE_new(cmp) SKM_sk_new(CONF_VALUE, (cmp)) +#define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE) +#define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st)) +#define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st)) +#define sk_CONF_VALUE_value(st, i) SKM_sk_value(CONF_VALUE, (st), (i)) +#define sk_CONF_VALUE_set(st, i, val) SKM_sk_set(CONF_VALUE, (st), (i), (val)) +#define sk_CONF_VALUE_zero(st) SKM_sk_zero(CONF_VALUE, (st)) +#define sk_CONF_VALUE_push(st, val) SKM_sk_push(CONF_VALUE, (st), (val)) +#define sk_CONF_VALUE_unshift(st, val) SKM_sk_unshift(CONF_VALUE, (st), (val)) +#define sk_CONF_VALUE_find(st, val) SKM_sk_find(CONF_VALUE, (st), (val)) +#define sk_CONF_VALUE_find_ex(st, val) SKM_sk_find_ex(CONF_VALUE, (st), (val)) +#define sk_CONF_VALUE_delete(st, i) SKM_sk_delete(CONF_VALUE, (st), (i)) +#define sk_CONF_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_VALUE, (st), (ptr)) +#define sk_CONF_VALUE_insert(st, val, i) SKM_sk_insert(CONF_VALUE, (st), (val), (i)) +#define sk_CONF_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_VALUE, (st), (cmp)) +#define sk_CONF_VALUE_dup(st) SKM_sk_dup(CONF_VALUE, st) +#define sk_CONF_VALUE_pop_free(st, free_func) SKM_sk_pop_free(CONF_VALUE, (st), (free_func)) +#define sk_CONF_VALUE_shift(st) SKM_sk_shift(CONF_VALUE, (st)) +#define sk_CONF_VALUE_pop(st) SKM_sk_pop(CONF_VALUE, (st)) +#define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st)) +#define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st)) + +#define sk_CRYPTO_EX_DATA_FUNCS_new(cmp) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (cmp)) +#define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS) +#define sk_CRYPTO_EX_DATA_FUNCS_free(st) SKM_sk_free(CRYPTO_EX_DATA_FUNCS, (st)) +#define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st)) +#define sk_CRYPTO_EX_DATA_FUNCS_value(st, i) SKM_sk_value(CRYPTO_EX_DATA_FUNCS, (st), (i)) +#define sk_CRYPTO_EX_DATA_FUNCS_set(st, i, val) SKM_sk_set(CRYPTO_EX_DATA_FUNCS, (st), (i), (val)) +#define sk_CRYPTO_EX_DATA_FUNCS_zero(st) SKM_sk_zero(CRYPTO_EX_DATA_FUNCS, (st)) +#define sk_CRYPTO_EX_DATA_FUNCS_push(st, val) SKM_sk_push(CRYPTO_EX_DATA_FUNCS, (st), (val)) +#define sk_CRYPTO_EX_DATA_FUNCS_unshift(st, val) SKM_sk_unshift(CRYPTO_EX_DATA_FUNCS, (st), (val)) +#define sk_CRYPTO_EX_DATA_FUNCS_find(st, val) SKM_sk_find(CRYPTO_EX_DATA_FUNCS, (st), (val)) +#define sk_CRYPTO_EX_DATA_FUNCS_find_ex(st, val) SKM_sk_find_ex(CRYPTO_EX_DATA_FUNCS, (st), (val)) +#define sk_CRYPTO_EX_DATA_FUNCS_delete(st, i) SKM_sk_delete(CRYPTO_EX_DATA_FUNCS, (st), (i)) +#define sk_CRYPTO_EX_DATA_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_EX_DATA_FUNCS, (st), (ptr)) +#define sk_CRYPTO_EX_DATA_FUNCS_insert(st, val, i) SKM_sk_insert(CRYPTO_EX_DATA_FUNCS, (st), (val), (i)) +#define sk_CRYPTO_EX_DATA_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_EX_DATA_FUNCS, (st), (cmp)) +#define sk_CRYPTO_EX_DATA_FUNCS_dup(st) SKM_sk_dup(CRYPTO_EX_DATA_FUNCS, st) +#define sk_CRYPTO_EX_DATA_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_EX_DATA_FUNCS, (st), (free_func)) +#define sk_CRYPTO_EX_DATA_FUNCS_shift(st) SKM_sk_shift(CRYPTO_EX_DATA_FUNCS, (st)) +#define sk_CRYPTO_EX_DATA_FUNCS_pop(st) SKM_sk_pop(CRYPTO_EX_DATA_FUNCS, (st)) +#define sk_CRYPTO_EX_DATA_FUNCS_sort(st) SKM_sk_sort(CRYPTO_EX_DATA_FUNCS, (st)) +#define sk_CRYPTO_EX_DATA_FUNCS_is_sorted(st) SKM_sk_is_sorted(CRYPTO_EX_DATA_FUNCS, (st)) + +#define sk_CRYPTO_dynlock_new(cmp) SKM_sk_new(CRYPTO_dynlock, (cmp)) +#define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock) +#define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st)) +#define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st)) +#define sk_CRYPTO_dynlock_value(st, i) SKM_sk_value(CRYPTO_dynlock, (st), (i)) +#define sk_CRYPTO_dynlock_set(st, i, val) SKM_sk_set(CRYPTO_dynlock, (st), (i), (val)) +#define sk_CRYPTO_dynlock_zero(st) SKM_sk_zero(CRYPTO_dynlock, (st)) +#define sk_CRYPTO_dynlock_push(st, val) SKM_sk_push(CRYPTO_dynlock, (st), (val)) +#define sk_CRYPTO_dynlock_unshift(st, val) SKM_sk_unshift(CRYPTO_dynlock, (st), (val)) +#define sk_CRYPTO_dynlock_find(st, val) SKM_sk_find(CRYPTO_dynlock, (st), (val)) +#define sk_CRYPTO_dynlock_find_ex(st, val) SKM_sk_find_ex(CRYPTO_dynlock, (st), (val)) +#define sk_CRYPTO_dynlock_delete(st, i) SKM_sk_delete(CRYPTO_dynlock, (st), (i)) +#define sk_CRYPTO_dynlock_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_dynlock, (st), (ptr)) +#define sk_CRYPTO_dynlock_insert(st, val, i) SKM_sk_insert(CRYPTO_dynlock, (st), (val), (i)) +#define sk_CRYPTO_dynlock_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_dynlock, (st), (cmp)) +#define sk_CRYPTO_dynlock_dup(st) SKM_sk_dup(CRYPTO_dynlock, st) +#define sk_CRYPTO_dynlock_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_dynlock, (st), (free_func)) +#define sk_CRYPTO_dynlock_shift(st) SKM_sk_shift(CRYPTO_dynlock, (st)) +#define sk_CRYPTO_dynlock_pop(st) SKM_sk_pop(CRYPTO_dynlock, (st)) +#define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st)) +#define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st)) + +#define sk_DIST_POINT_new(cmp) SKM_sk_new(DIST_POINT, (cmp)) +#define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT) +#define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st)) +#define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st)) +#define sk_DIST_POINT_value(st, i) SKM_sk_value(DIST_POINT, (st), (i)) +#define sk_DIST_POINT_set(st, i, val) SKM_sk_set(DIST_POINT, (st), (i), (val)) +#define sk_DIST_POINT_zero(st) SKM_sk_zero(DIST_POINT, (st)) +#define sk_DIST_POINT_push(st, val) SKM_sk_push(DIST_POINT, (st), (val)) +#define sk_DIST_POINT_unshift(st, val) SKM_sk_unshift(DIST_POINT, (st), (val)) +#define sk_DIST_POINT_find(st, val) SKM_sk_find(DIST_POINT, (st), (val)) +#define sk_DIST_POINT_find_ex(st, val) SKM_sk_find_ex(DIST_POINT, (st), (val)) +#define sk_DIST_POINT_delete(st, i) SKM_sk_delete(DIST_POINT, (st), (i)) +#define sk_DIST_POINT_delete_ptr(st, ptr) SKM_sk_delete_ptr(DIST_POINT, (st), (ptr)) +#define sk_DIST_POINT_insert(st, val, i) SKM_sk_insert(DIST_POINT, (st), (val), (i)) +#define sk_DIST_POINT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(DIST_POINT, (st), (cmp)) +#define sk_DIST_POINT_dup(st) SKM_sk_dup(DIST_POINT, st) +#define sk_DIST_POINT_pop_free(st, free_func) SKM_sk_pop_free(DIST_POINT, (st), (free_func)) +#define sk_DIST_POINT_shift(st) SKM_sk_shift(DIST_POINT, (st)) +#define sk_DIST_POINT_pop(st) SKM_sk_pop(DIST_POINT, (st)) +#define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st)) +#define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st)) + +#define sk_ENGINE_new(cmp) SKM_sk_new(ENGINE, (cmp)) +#define sk_ENGINE_new_null() SKM_sk_new_null(ENGINE) +#define sk_ENGINE_free(st) SKM_sk_free(ENGINE, (st)) +#define sk_ENGINE_num(st) SKM_sk_num(ENGINE, (st)) +#define sk_ENGINE_value(st, i) SKM_sk_value(ENGINE, (st), (i)) +#define sk_ENGINE_set(st, i, val) SKM_sk_set(ENGINE, (st), (i), (val)) +#define sk_ENGINE_zero(st) SKM_sk_zero(ENGINE, (st)) +#define sk_ENGINE_push(st, val) SKM_sk_push(ENGINE, (st), (val)) +#define sk_ENGINE_unshift(st, val) SKM_sk_unshift(ENGINE, (st), (val)) +#define sk_ENGINE_find(st, val) SKM_sk_find(ENGINE, (st), (val)) +#define sk_ENGINE_find_ex(st, val) SKM_sk_find_ex(ENGINE, (st), (val)) +#define sk_ENGINE_delete(st, i) SKM_sk_delete(ENGINE, (st), (i)) +#define sk_ENGINE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE, (st), (ptr)) +#define sk_ENGINE_insert(st, val, i) SKM_sk_insert(ENGINE, (st), (val), (i)) +#define sk_ENGINE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE, (st), (cmp)) +#define sk_ENGINE_dup(st) SKM_sk_dup(ENGINE, st) +#define sk_ENGINE_pop_free(st, free_func) SKM_sk_pop_free(ENGINE, (st), (free_func)) +#define sk_ENGINE_shift(st) SKM_sk_shift(ENGINE, (st)) +#define sk_ENGINE_pop(st) SKM_sk_pop(ENGINE, (st)) +#define sk_ENGINE_sort(st) SKM_sk_sort(ENGINE, (st)) +#define sk_ENGINE_is_sorted(st) SKM_sk_is_sorted(ENGINE, (st)) + +#define sk_ENGINE_CLEANUP_ITEM_new(cmp) SKM_sk_new(ENGINE_CLEANUP_ITEM, (cmp)) +#define sk_ENGINE_CLEANUP_ITEM_new_null() SKM_sk_new_null(ENGINE_CLEANUP_ITEM) +#define sk_ENGINE_CLEANUP_ITEM_free(st) SKM_sk_free(ENGINE_CLEANUP_ITEM, (st)) +#define sk_ENGINE_CLEANUP_ITEM_num(st) SKM_sk_num(ENGINE_CLEANUP_ITEM, (st)) +#define sk_ENGINE_CLEANUP_ITEM_value(st, i) SKM_sk_value(ENGINE_CLEANUP_ITEM, (st), (i)) +#define sk_ENGINE_CLEANUP_ITEM_set(st, i, val) SKM_sk_set(ENGINE_CLEANUP_ITEM, (st), (i), (val)) +#define sk_ENGINE_CLEANUP_ITEM_zero(st) SKM_sk_zero(ENGINE_CLEANUP_ITEM, (st)) +#define sk_ENGINE_CLEANUP_ITEM_push(st, val) SKM_sk_push(ENGINE_CLEANUP_ITEM, (st), (val)) +#define sk_ENGINE_CLEANUP_ITEM_unshift(st, val) SKM_sk_unshift(ENGINE_CLEANUP_ITEM, (st), (val)) +#define sk_ENGINE_CLEANUP_ITEM_find(st, val) SKM_sk_find(ENGINE_CLEANUP_ITEM, (st), (val)) +#define sk_ENGINE_CLEANUP_ITEM_find_ex(st, val) SKM_sk_find_ex(ENGINE_CLEANUP_ITEM, (st), (val)) +#define sk_ENGINE_CLEANUP_ITEM_delete(st, i) SKM_sk_delete(ENGINE_CLEANUP_ITEM, (st), (i)) +#define sk_ENGINE_CLEANUP_ITEM_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE_CLEANUP_ITEM, (st), (ptr)) +#define sk_ENGINE_CLEANUP_ITEM_insert(st, val, i) SKM_sk_insert(ENGINE_CLEANUP_ITEM, (st), (val), (i)) +#define sk_ENGINE_CLEANUP_ITEM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE_CLEANUP_ITEM, (st), (cmp)) +#define sk_ENGINE_CLEANUP_ITEM_dup(st) SKM_sk_dup(ENGINE_CLEANUP_ITEM, st) +#define sk_ENGINE_CLEANUP_ITEM_pop_free(st, free_func) SKM_sk_pop_free(ENGINE_CLEANUP_ITEM, (st), (free_func)) +#define sk_ENGINE_CLEANUP_ITEM_shift(st) SKM_sk_shift(ENGINE_CLEANUP_ITEM, (st)) +#define sk_ENGINE_CLEANUP_ITEM_pop(st) SKM_sk_pop(ENGINE_CLEANUP_ITEM, (st)) +#define sk_ENGINE_CLEANUP_ITEM_sort(st) SKM_sk_sort(ENGINE_CLEANUP_ITEM, (st)) +#define sk_ENGINE_CLEANUP_ITEM_is_sorted(st) SKM_sk_is_sorted(ENGINE_CLEANUP_ITEM, (st)) + +#define sk_ESS_CERT_ID_new(cmp) SKM_sk_new(ESS_CERT_ID, (cmp)) +#define sk_ESS_CERT_ID_new_null() SKM_sk_new_null(ESS_CERT_ID) +#define sk_ESS_CERT_ID_free(st) SKM_sk_free(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_num(st) SKM_sk_num(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_value(st, i) SKM_sk_value(ESS_CERT_ID, (st), (i)) +#define sk_ESS_CERT_ID_set(st, i, val) SKM_sk_set(ESS_CERT_ID, (st), (i), (val)) +#define sk_ESS_CERT_ID_zero(st) SKM_sk_zero(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_push(st, val) SKM_sk_push(ESS_CERT_ID, (st), (val)) +#define sk_ESS_CERT_ID_unshift(st, val) SKM_sk_unshift(ESS_CERT_ID, (st), (val)) +#define sk_ESS_CERT_ID_find(st, val) SKM_sk_find(ESS_CERT_ID, (st), (val)) +#define sk_ESS_CERT_ID_find_ex(st, val) SKM_sk_find_ex(ESS_CERT_ID, (st), (val)) +#define sk_ESS_CERT_ID_delete(st, i) SKM_sk_delete(ESS_CERT_ID, (st), (i)) +#define sk_ESS_CERT_ID_delete_ptr(st, ptr) SKM_sk_delete_ptr(ESS_CERT_ID, (st), (ptr)) +#define sk_ESS_CERT_ID_insert(st, val, i) SKM_sk_insert(ESS_CERT_ID, (st), (val), (i)) +#define sk_ESS_CERT_ID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ESS_CERT_ID, (st), (cmp)) +#define sk_ESS_CERT_ID_dup(st) SKM_sk_dup(ESS_CERT_ID, st) +#define sk_ESS_CERT_ID_pop_free(st, free_func) SKM_sk_pop_free(ESS_CERT_ID, (st), (free_func)) +#define sk_ESS_CERT_ID_shift(st) SKM_sk_shift(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_pop(st) SKM_sk_pop(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_sort(st) SKM_sk_sort(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_is_sorted(st) SKM_sk_is_sorted(ESS_CERT_ID, (st)) + +#define sk_EVP_MD_new(cmp) SKM_sk_new(EVP_MD, (cmp)) +#define sk_EVP_MD_new_null() SKM_sk_new_null(EVP_MD) +#define sk_EVP_MD_free(st) SKM_sk_free(EVP_MD, (st)) +#define sk_EVP_MD_num(st) SKM_sk_num(EVP_MD, (st)) +#define sk_EVP_MD_value(st, i) SKM_sk_value(EVP_MD, (st), (i)) +#define sk_EVP_MD_set(st, i, val) SKM_sk_set(EVP_MD, (st), (i), (val)) +#define sk_EVP_MD_zero(st) SKM_sk_zero(EVP_MD, (st)) +#define sk_EVP_MD_push(st, val) SKM_sk_push(EVP_MD, (st), (val)) +#define sk_EVP_MD_unshift(st, val) SKM_sk_unshift(EVP_MD, (st), (val)) +#define sk_EVP_MD_find(st, val) SKM_sk_find(EVP_MD, (st), (val)) +#define sk_EVP_MD_find_ex(st, val) SKM_sk_find_ex(EVP_MD, (st), (val)) +#define sk_EVP_MD_delete(st, i) SKM_sk_delete(EVP_MD, (st), (i)) +#define sk_EVP_MD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_MD, (st), (ptr)) +#define sk_EVP_MD_insert(st, val, i) SKM_sk_insert(EVP_MD, (st), (val), (i)) +#define sk_EVP_MD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_MD, (st), (cmp)) +#define sk_EVP_MD_dup(st) SKM_sk_dup(EVP_MD, st) +#define sk_EVP_MD_pop_free(st, free_func) SKM_sk_pop_free(EVP_MD, (st), (free_func)) +#define sk_EVP_MD_shift(st) SKM_sk_shift(EVP_MD, (st)) +#define sk_EVP_MD_pop(st) SKM_sk_pop(EVP_MD, (st)) +#define sk_EVP_MD_sort(st) SKM_sk_sort(EVP_MD, (st)) +#define sk_EVP_MD_is_sorted(st) SKM_sk_is_sorted(EVP_MD, (st)) + +#define sk_EVP_PBE_CTL_new(cmp) SKM_sk_new(EVP_PBE_CTL, (cmp)) +#define sk_EVP_PBE_CTL_new_null() SKM_sk_new_null(EVP_PBE_CTL) +#define sk_EVP_PBE_CTL_free(st) SKM_sk_free(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_num(st) SKM_sk_num(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_value(st, i) SKM_sk_value(EVP_PBE_CTL, (st), (i)) +#define sk_EVP_PBE_CTL_set(st, i, val) SKM_sk_set(EVP_PBE_CTL, (st), (i), (val)) +#define sk_EVP_PBE_CTL_zero(st) SKM_sk_zero(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_push(st, val) SKM_sk_push(EVP_PBE_CTL, (st), (val)) +#define sk_EVP_PBE_CTL_unshift(st, val) SKM_sk_unshift(EVP_PBE_CTL, (st), (val)) +#define sk_EVP_PBE_CTL_find(st, val) SKM_sk_find(EVP_PBE_CTL, (st), (val)) +#define sk_EVP_PBE_CTL_find_ex(st, val) SKM_sk_find_ex(EVP_PBE_CTL, (st), (val)) +#define sk_EVP_PBE_CTL_delete(st, i) SKM_sk_delete(EVP_PBE_CTL, (st), (i)) +#define sk_EVP_PBE_CTL_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PBE_CTL, (st), (ptr)) +#define sk_EVP_PBE_CTL_insert(st, val, i) SKM_sk_insert(EVP_PBE_CTL, (st), (val), (i)) +#define sk_EVP_PBE_CTL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PBE_CTL, (st), (cmp)) +#define sk_EVP_PBE_CTL_dup(st) SKM_sk_dup(EVP_PBE_CTL, st) +#define sk_EVP_PBE_CTL_pop_free(st, free_func) SKM_sk_pop_free(EVP_PBE_CTL, (st), (free_func)) +#define sk_EVP_PBE_CTL_shift(st) SKM_sk_shift(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_pop(st) SKM_sk_pop(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_sort(st) SKM_sk_sort(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_is_sorted(st) SKM_sk_is_sorted(EVP_PBE_CTL, (st)) + +#define sk_EVP_PKEY_ASN1_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_ASN1_METHOD, (cmp)) +#define sk_EVP_PKEY_ASN1_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_ASN1_METHOD) +#define sk_EVP_PKEY_ASN1_METHOD_free(st) SKM_sk_free(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_num(st) SKM_sk_num(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_ASN1_METHOD, (st), (i)) +#define sk_EVP_PKEY_ASN1_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_ASN1_METHOD, (st), (i), (val)) +#define sk_EVP_PKEY_ASN1_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_ASN1_METHOD, (st), (val)) +#define sk_EVP_PKEY_ASN1_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_ASN1_METHOD, (st), (val)) +#define sk_EVP_PKEY_ASN1_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_ASN1_METHOD, (st), (val)) +#define sk_EVP_PKEY_ASN1_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_ASN1_METHOD, (st), (val)) +#define sk_EVP_PKEY_ASN1_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_ASN1_METHOD, (st), (i)) +#define sk_EVP_PKEY_ASN1_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_ASN1_METHOD, (st), (ptr)) +#define sk_EVP_PKEY_ASN1_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_ASN1_METHOD, (st), (val), (i)) +#define sk_EVP_PKEY_ASN1_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_ASN1_METHOD, (st), (cmp)) +#define sk_EVP_PKEY_ASN1_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_ASN1_METHOD, st) +#define sk_EVP_PKEY_ASN1_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_ASN1_METHOD, (st), (free_func)) +#define sk_EVP_PKEY_ASN1_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_ASN1_METHOD, (st)) + +#define sk_EVP_PKEY_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_METHOD, (cmp)) +#define sk_EVP_PKEY_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_METHOD) +#define sk_EVP_PKEY_METHOD_free(st) SKM_sk_free(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_num(st) SKM_sk_num(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_METHOD, (st), (i)) +#define sk_EVP_PKEY_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_METHOD, (st), (i), (val)) +#define sk_EVP_PKEY_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_METHOD, (st), (val)) +#define sk_EVP_PKEY_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_METHOD, (st), (val)) +#define sk_EVP_PKEY_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_METHOD, (st), (val)) +#define sk_EVP_PKEY_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_METHOD, (st), (val)) +#define sk_EVP_PKEY_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_METHOD, (st), (i)) +#define sk_EVP_PKEY_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_METHOD, (st), (ptr)) +#define sk_EVP_PKEY_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_METHOD, (st), (val), (i)) +#define sk_EVP_PKEY_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_METHOD, (st), (cmp)) +#define sk_EVP_PKEY_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_METHOD, st) +#define sk_EVP_PKEY_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_METHOD, (st), (free_func)) +#define sk_EVP_PKEY_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_METHOD, (st)) + +#define sk_GENERAL_NAME_new(cmp) SKM_sk_new(GENERAL_NAME, (cmp)) +#define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME) +#define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st)) +#define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st)) +#define sk_GENERAL_NAME_value(st, i) SKM_sk_value(GENERAL_NAME, (st), (i)) +#define sk_GENERAL_NAME_set(st, i, val) SKM_sk_set(GENERAL_NAME, (st), (i), (val)) +#define sk_GENERAL_NAME_zero(st) SKM_sk_zero(GENERAL_NAME, (st)) +#define sk_GENERAL_NAME_push(st, val) SKM_sk_push(GENERAL_NAME, (st), (val)) +#define sk_GENERAL_NAME_unshift(st, val) SKM_sk_unshift(GENERAL_NAME, (st), (val)) +#define sk_GENERAL_NAME_find(st, val) SKM_sk_find(GENERAL_NAME, (st), (val)) +#define sk_GENERAL_NAME_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAME, (st), (val)) +#define sk_GENERAL_NAME_delete(st, i) SKM_sk_delete(GENERAL_NAME, (st), (i)) +#define sk_GENERAL_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAME, (st), (ptr)) +#define sk_GENERAL_NAME_insert(st, val, i) SKM_sk_insert(GENERAL_NAME, (st), (val), (i)) +#define sk_GENERAL_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAME, (st), (cmp)) +#define sk_GENERAL_NAME_dup(st) SKM_sk_dup(GENERAL_NAME, st) +#define sk_GENERAL_NAME_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAME, (st), (free_func)) +#define sk_GENERAL_NAME_shift(st) SKM_sk_shift(GENERAL_NAME, (st)) +#define sk_GENERAL_NAME_pop(st) SKM_sk_pop(GENERAL_NAME, (st)) +#define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st)) +#define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st)) + +#define sk_GENERAL_NAMES_new(cmp) SKM_sk_new(GENERAL_NAMES, (cmp)) +#define sk_GENERAL_NAMES_new_null() SKM_sk_new_null(GENERAL_NAMES) +#define sk_GENERAL_NAMES_free(st) SKM_sk_free(GENERAL_NAMES, (st)) +#define sk_GENERAL_NAMES_num(st) SKM_sk_num(GENERAL_NAMES, (st)) +#define sk_GENERAL_NAMES_value(st, i) SKM_sk_value(GENERAL_NAMES, (st), (i)) +#define sk_GENERAL_NAMES_set(st, i, val) SKM_sk_set(GENERAL_NAMES, (st), (i), (val)) +#define sk_GENERAL_NAMES_zero(st) SKM_sk_zero(GENERAL_NAMES, (st)) +#define sk_GENERAL_NAMES_push(st, val) SKM_sk_push(GENERAL_NAMES, (st), (val)) +#define sk_GENERAL_NAMES_unshift(st, val) SKM_sk_unshift(GENERAL_NAMES, (st), (val)) +#define sk_GENERAL_NAMES_find(st, val) SKM_sk_find(GENERAL_NAMES, (st), (val)) +#define sk_GENERAL_NAMES_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAMES, (st), (val)) +#define sk_GENERAL_NAMES_delete(st, i) SKM_sk_delete(GENERAL_NAMES, (st), (i)) +#define sk_GENERAL_NAMES_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAMES, (st), (ptr)) +#define sk_GENERAL_NAMES_insert(st, val, i) SKM_sk_insert(GENERAL_NAMES, (st), (val), (i)) +#define sk_GENERAL_NAMES_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAMES, (st), (cmp)) +#define sk_GENERAL_NAMES_dup(st) SKM_sk_dup(GENERAL_NAMES, st) +#define sk_GENERAL_NAMES_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAMES, (st), (free_func)) +#define sk_GENERAL_NAMES_shift(st) SKM_sk_shift(GENERAL_NAMES, (st)) +#define sk_GENERAL_NAMES_pop(st) SKM_sk_pop(GENERAL_NAMES, (st)) +#define sk_GENERAL_NAMES_sort(st) SKM_sk_sort(GENERAL_NAMES, (st)) +#define sk_GENERAL_NAMES_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAMES, (st)) + +#define sk_GENERAL_SUBTREE_new(cmp) SKM_sk_new(GENERAL_SUBTREE, (cmp)) +#define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE) +#define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st)) +#define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st)) +#define sk_GENERAL_SUBTREE_value(st, i) SKM_sk_value(GENERAL_SUBTREE, (st), (i)) +#define sk_GENERAL_SUBTREE_set(st, i, val) SKM_sk_set(GENERAL_SUBTREE, (st), (i), (val)) +#define sk_GENERAL_SUBTREE_zero(st) SKM_sk_zero(GENERAL_SUBTREE, (st)) +#define sk_GENERAL_SUBTREE_push(st, val) SKM_sk_push(GENERAL_SUBTREE, (st), (val)) +#define sk_GENERAL_SUBTREE_unshift(st, val) SKM_sk_unshift(GENERAL_SUBTREE, (st), (val)) +#define sk_GENERAL_SUBTREE_find(st, val) SKM_sk_find(GENERAL_SUBTREE, (st), (val)) +#define sk_GENERAL_SUBTREE_find_ex(st, val) SKM_sk_find_ex(GENERAL_SUBTREE, (st), (val)) +#define sk_GENERAL_SUBTREE_delete(st, i) SKM_sk_delete(GENERAL_SUBTREE, (st), (i)) +#define sk_GENERAL_SUBTREE_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_SUBTREE, (st), (ptr)) +#define sk_GENERAL_SUBTREE_insert(st, val, i) SKM_sk_insert(GENERAL_SUBTREE, (st), (val), (i)) +#define sk_GENERAL_SUBTREE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_SUBTREE, (st), (cmp)) +#define sk_GENERAL_SUBTREE_dup(st) SKM_sk_dup(GENERAL_SUBTREE, st) +#define sk_GENERAL_SUBTREE_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_SUBTREE, (st), (free_func)) +#define sk_GENERAL_SUBTREE_shift(st) SKM_sk_shift(GENERAL_SUBTREE, (st)) +#define sk_GENERAL_SUBTREE_pop(st) SKM_sk_pop(GENERAL_SUBTREE, (st)) +#define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st)) +#define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st)) + +#define sk_IPAddressFamily_new(cmp) SKM_sk_new(IPAddressFamily, (cmp)) +#define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily) +#define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st)) +#define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st)) +#define sk_IPAddressFamily_value(st, i) SKM_sk_value(IPAddressFamily, (st), (i)) +#define sk_IPAddressFamily_set(st, i, val) SKM_sk_set(IPAddressFamily, (st), (i), (val)) +#define sk_IPAddressFamily_zero(st) SKM_sk_zero(IPAddressFamily, (st)) +#define sk_IPAddressFamily_push(st, val) SKM_sk_push(IPAddressFamily, (st), (val)) +#define sk_IPAddressFamily_unshift(st, val) SKM_sk_unshift(IPAddressFamily, (st), (val)) +#define sk_IPAddressFamily_find(st, val) SKM_sk_find(IPAddressFamily, (st), (val)) +#define sk_IPAddressFamily_find_ex(st, val) SKM_sk_find_ex(IPAddressFamily, (st), (val)) +#define sk_IPAddressFamily_delete(st, i) SKM_sk_delete(IPAddressFamily, (st), (i)) +#define sk_IPAddressFamily_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressFamily, (st), (ptr)) +#define sk_IPAddressFamily_insert(st, val, i) SKM_sk_insert(IPAddressFamily, (st), (val), (i)) +#define sk_IPAddressFamily_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressFamily, (st), (cmp)) +#define sk_IPAddressFamily_dup(st) SKM_sk_dup(IPAddressFamily, st) +#define sk_IPAddressFamily_pop_free(st, free_func) SKM_sk_pop_free(IPAddressFamily, (st), (free_func)) +#define sk_IPAddressFamily_shift(st) SKM_sk_shift(IPAddressFamily, (st)) +#define sk_IPAddressFamily_pop(st) SKM_sk_pop(IPAddressFamily, (st)) +#define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st)) +#define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st)) + +#define sk_IPAddressOrRange_new(cmp) SKM_sk_new(IPAddressOrRange, (cmp)) +#define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange) +#define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st)) +#define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st)) +#define sk_IPAddressOrRange_value(st, i) SKM_sk_value(IPAddressOrRange, (st), (i)) +#define sk_IPAddressOrRange_set(st, i, val) SKM_sk_set(IPAddressOrRange, (st), (i), (val)) +#define sk_IPAddressOrRange_zero(st) SKM_sk_zero(IPAddressOrRange, (st)) +#define sk_IPAddressOrRange_push(st, val) SKM_sk_push(IPAddressOrRange, (st), (val)) +#define sk_IPAddressOrRange_unshift(st, val) SKM_sk_unshift(IPAddressOrRange, (st), (val)) +#define sk_IPAddressOrRange_find(st, val) SKM_sk_find(IPAddressOrRange, (st), (val)) +#define sk_IPAddressOrRange_find_ex(st, val) SKM_sk_find_ex(IPAddressOrRange, (st), (val)) +#define sk_IPAddressOrRange_delete(st, i) SKM_sk_delete(IPAddressOrRange, (st), (i)) +#define sk_IPAddressOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressOrRange, (st), (ptr)) +#define sk_IPAddressOrRange_insert(st, val, i) SKM_sk_insert(IPAddressOrRange, (st), (val), (i)) +#define sk_IPAddressOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressOrRange, (st), (cmp)) +#define sk_IPAddressOrRange_dup(st) SKM_sk_dup(IPAddressOrRange, st) +#define sk_IPAddressOrRange_pop_free(st, free_func) SKM_sk_pop_free(IPAddressOrRange, (st), (free_func)) +#define sk_IPAddressOrRange_shift(st) SKM_sk_shift(IPAddressOrRange, (st)) +#define sk_IPAddressOrRange_pop(st) SKM_sk_pop(IPAddressOrRange, (st)) +#define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st)) +#define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st)) + +#define sk_KRB5_APREQBODY_new(cmp) SKM_sk_new(KRB5_APREQBODY, (cmp)) +#define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY) +#define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st)) +#define sk_KRB5_APREQBODY_num(st) SKM_sk_num(KRB5_APREQBODY, (st)) +#define sk_KRB5_APREQBODY_value(st, i) SKM_sk_value(KRB5_APREQBODY, (st), (i)) +#define sk_KRB5_APREQBODY_set(st, i, val) SKM_sk_set(KRB5_APREQBODY, (st), (i), (val)) +#define sk_KRB5_APREQBODY_zero(st) SKM_sk_zero(KRB5_APREQBODY, (st)) +#define sk_KRB5_APREQBODY_push(st, val) SKM_sk_push(KRB5_APREQBODY, (st), (val)) +#define sk_KRB5_APREQBODY_unshift(st, val) SKM_sk_unshift(KRB5_APREQBODY, (st), (val)) +#define sk_KRB5_APREQBODY_find(st, val) SKM_sk_find(KRB5_APREQBODY, (st), (val)) +#define sk_KRB5_APREQBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_APREQBODY, (st), (val)) +#define sk_KRB5_APREQBODY_delete(st, i) SKM_sk_delete(KRB5_APREQBODY, (st), (i)) +#define sk_KRB5_APREQBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_APREQBODY, (st), (ptr)) +#define sk_KRB5_APREQBODY_insert(st, val, i) SKM_sk_insert(KRB5_APREQBODY, (st), (val), (i)) +#define sk_KRB5_APREQBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_APREQBODY, (st), (cmp)) +#define sk_KRB5_APREQBODY_dup(st) SKM_sk_dup(KRB5_APREQBODY, st) +#define sk_KRB5_APREQBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_APREQBODY, (st), (free_func)) +#define sk_KRB5_APREQBODY_shift(st) SKM_sk_shift(KRB5_APREQBODY, (st)) +#define sk_KRB5_APREQBODY_pop(st) SKM_sk_pop(KRB5_APREQBODY, (st)) +#define sk_KRB5_APREQBODY_sort(st) SKM_sk_sort(KRB5_APREQBODY, (st)) +#define sk_KRB5_APREQBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_APREQBODY, (st)) + +#define sk_KRB5_AUTHDATA_new(cmp) SKM_sk_new(KRB5_AUTHDATA, (cmp)) +#define sk_KRB5_AUTHDATA_new_null() SKM_sk_new_null(KRB5_AUTHDATA) +#define sk_KRB5_AUTHDATA_free(st) SKM_sk_free(KRB5_AUTHDATA, (st)) +#define sk_KRB5_AUTHDATA_num(st) SKM_sk_num(KRB5_AUTHDATA, (st)) +#define sk_KRB5_AUTHDATA_value(st, i) SKM_sk_value(KRB5_AUTHDATA, (st), (i)) +#define sk_KRB5_AUTHDATA_set(st, i, val) SKM_sk_set(KRB5_AUTHDATA, (st), (i), (val)) +#define sk_KRB5_AUTHDATA_zero(st) SKM_sk_zero(KRB5_AUTHDATA, (st)) +#define sk_KRB5_AUTHDATA_push(st, val) SKM_sk_push(KRB5_AUTHDATA, (st), (val)) +#define sk_KRB5_AUTHDATA_unshift(st, val) SKM_sk_unshift(KRB5_AUTHDATA, (st), (val)) +#define sk_KRB5_AUTHDATA_find(st, val) SKM_sk_find(KRB5_AUTHDATA, (st), (val)) +#define sk_KRB5_AUTHDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHDATA, (st), (val)) +#define sk_KRB5_AUTHDATA_delete(st, i) SKM_sk_delete(KRB5_AUTHDATA, (st), (i)) +#define sk_KRB5_AUTHDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHDATA, (st), (ptr)) +#define sk_KRB5_AUTHDATA_insert(st, val, i) SKM_sk_insert(KRB5_AUTHDATA, (st), (val), (i)) +#define sk_KRB5_AUTHDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHDATA, (st), (cmp)) +#define sk_KRB5_AUTHDATA_dup(st) SKM_sk_dup(KRB5_AUTHDATA, st) +#define sk_KRB5_AUTHDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHDATA, (st), (free_func)) +#define sk_KRB5_AUTHDATA_shift(st) SKM_sk_shift(KRB5_AUTHDATA, (st)) +#define sk_KRB5_AUTHDATA_pop(st) SKM_sk_pop(KRB5_AUTHDATA, (st)) +#define sk_KRB5_AUTHDATA_sort(st) SKM_sk_sort(KRB5_AUTHDATA, (st)) +#define sk_KRB5_AUTHDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHDATA, (st)) + +#define sk_KRB5_AUTHENTBODY_new(cmp) SKM_sk_new(KRB5_AUTHENTBODY, (cmp)) +#define sk_KRB5_AUTHENTBODY_new_null() SKM_sk_new_null(KRB5_AUTHENTBODY) +#define sk_KRB5_AUTHENTBODY_free(st) SKM_sk_free(KRB5_AUTHENTBODY, (st)) +#define sk_KRB5_AUTHENTBODY_num(st) SKM_sk_num(KRB5_AUTHENTBODY, (st)) +#define sk_KRB5_AUTHENTBODY_value(st, i) SKM_sk_value(KRB5_AUTHENTBODY, (st), (i)) +#define sk_KRB5_AUTHENTBODY_set(st, i, val) SKM_sk_set(KRB5_AUTHENTBODY, (st), (i), (val)) +#define sk_KRB5_AUTHENTBODY_zero(st) SKM_sk_zero(KRB5_AUTHENTBODY, (st)) +#define sk_KRB5_AUTHENTBODY_push(st, val) SKM_sk_push(KRB5_AUTHENTBODY, (st), (val)) +#define sk_KRB5_AUTHENTBODY_unshift(st, val) SKM_sk_unshift(KRB5_AUTHENTBODY, (st), (val)) +#define sk_KRB5_AUTHENTBODY_find(st, val) SKM_sk_find(KRB5_AUTHENTBODY, (st), (val)) +#define sk_KRB5_AUTHENTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHENTBODY, (st), (val)) +#define sk_KRB5_AUTHENTBODY_delete(st, i) SKM_sk_delete(KRB5_AUTHENTBODY, (st), (i)) +#define sk_KRB5_AUTHENTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHENTBODY, (st), (ptr)) +#define sk_KRB5_AUTHENTBODY_insert(st, val, i) SKM_sk_insert(KRB5_AUTHENTBODY, (st), (val), (i)) +#define sk_KRB5_AUTHENTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHENTBODY, (st), (cmp)) +#define sk_KRB5_AUTHENTBODY_dup(st) SKM_sk_dup(KRB5_AUTHENTBODY, st) +#define sk_KRB5_AUTHENTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHENTBODY, (st), (free_func)) +#define sk_KRB5_AUTHENTBODY_shift(st) SKM_sk_shift(KRB5_AUTHENTBODY, (st)) +#define sk_KRB5_AUTHENTBODY_pop(st) SKM_sk_pop(KRB5_AUTHENTBODY, (st)) +#define sk_KRB5_AUTHENTBODY_sort(st) SKM_sk_sort(KRB5_AUTHENTBODY, (st)) +#define sk_KRB5_AUTHENTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHENTBODY, (st)) + +#define sk_KRB5_CHECKSUM_new(cmp) SKM_sk_new(KRB5_CHECKSUM, (cmp)) +#define sk_KRB5_CHECKSUM_new_null() SKM_sk_new_null(KRB5_CHECKSUM) +#define sk_KRB5_CHECKSUM_free(st) SKM_sk_free(KRB5_CHECKSUM, (st)) +#define sk_KRB5_CHECKSUM_num(st) SKM_sk_num(KRB5_CHECKSUM, (st)) +#define sk_KRB5_CHECKSUM_value(st, i) SKM_sk_value(KRB5_CHECKSUM, (st), (i)) +#define sk_KRB5_CHECKSUM_set(st, i, val) SKM_sk_set(KRB5_CHECKSUM, (st), (i), (val)) +#define sk_KRB5_CHECKSUM_zero(st) SKM_sk_zero(KRB5_CHECKSUM, (st)) +#define sk_KRB5_CHECKSUM_push(st, val) SKM_sk_push(KRB5_CHECKSUM, (st), (val)) +#define sk_KRB5_CHECKSUM_unshift(st, val) SKM_sk_unshift(KRB5_CHECKSUM, (st), (val)) +#define sk_KRB5_CHECKSUM_find(st, val) SKM_sk_find(KRB5_CHECKSUM, (st), (val)) +#define sk_KRB5_CHECKSUM_find_ex(st, val) SKM_sk_find_ex(KRB5_CHECKSUM, (st), (val)) +#define sk_KRB5_CHECKSUM_delete(st, i) SKM_sk_delete(KRB5_CHECKSUM, (st), (i)) +#define sk_KRB5_CHECKSUM_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_CHECKSUM, (st), (ptr)) +#define sk_KRB5_CHECKSUM_insert(st, val, i) SKM_sk_insert(KRB5_CHECKSUM, (st), (val), (i)) +#define sk_KRB5_CHECKSUM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_CHECKSUM, (st), (cmp)) +#define sk_KRB5_CHECKSUM_dup(st) SKM_sk_dup(KRB5_CHECKSUM, st) +#define sk_KRB5_CHECKSUM_pop_free(st, free_func) SKM_sk_pop_free(KRB5_CHECKSUM, (st), (free_func)) +#define sk_KRB5_CHECKSUM_shift(st) SKM_sk_shift(KRB5_CHECKSUM, (st)) +#define sk_KRB5_CHECKSUM_pop(st) SKM_sk_pop(KRB5_CHECKSUM, (st)) +#define sk_KRB5_CHECKSUM_sort(st) SKM_sk_sort(KRB5_CHECKSUM, (st)) +#define sk_KRB5_CHECKSUM_is_sorted(st) SKM_sk_is_sorted(KRB5_CHECKSUM, (st)) + +#define sk_KRB5_ENCDATA_new(cmp) SKM_sk_new(KRB5_ENCDATA, (cmp)) +#define sk_KRB5_ENCDATA_new_null() SKM_sk_new_null(KRB5_ENCDATA) +#define sk_KRB5_ENCDATA_free(st) SKM_sk_free(KRB5_ENCDATA, (st)) +#define sk_KRB5_ENCDATA_num(st) SKM_sk_num(KRB5_ENCDATA, (st)) +#define sk_KRB5_ENCDATA_value(st, i) SKM_sk_value(KRB5_ENCDATA, (st), (i)) +#define sk_KRB5_ENCDATA_set(st, i, val) SKM_sk_set(KRB5_ENCDATA, (st), (i), (val)) +#define sk_KRB5_ENCDATA_zero(st) SKM_sk_zero(KRB5_ENCDATA, (st)) +#define sk_KRB5_ENCDATA_push(st, val) SKM_sk_push(KRB5_ENCDATA, (st), (val)) +#define sk_KRB5_ENCDATA_unshift(st, val) SKM_sk_unshift(KRB5_ENCDATA, (st), (val)) +#define sk_KRB5_ENCDATA_find(st, val) SKM_sk_find(KRB5_ENCDATA, (st), (val)) +#define sk_KRB5_ENCDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCDATA, (st), (val)) +#define sk_KRB5_ENCDATA_delete(st, i) SKM_sk_delete(KRB5_ENCDATA, (st), (i)) +#define sk_KRB5_ENCDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCDATA, (st), (ptr)) +#define sk_KRB5_ENCDATA_insert(st, val, i) SKM_sk_insert(KRB5_ENCDATA, (st), (val), (i)) +#define sk_KRB5_ENCDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCDATA, (st), (cmp)) +#define sk_KRB5_ENCDATA_dup(st) SKM_sk_dup(KRB5_ENCDATA, st) +#define sk_KRB5_ENCDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCDATA, (st), (free_func)) +#define sk_KRB5_ENCDATA_shift(st) SKM_sk_shift(KRB5_ENCDATA, (st)) +#define sk_KRB5_ENCDATA_pop(st) SKM_sk_pop(KRB5_ENCDATA, (st)) +#define sk_KRB5_ENCDATA_sort(st) SKM_sk_sort(KRB5_ENCDATA, (st)) +#define sk_KRB5_ENCDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCDATA, (st)) + +#define sk_KRB5_ENCKEY_new(cmp) SKM_sk_new(KRB5_ENCKEY, (cmp)) +#define sk_KRB5_ENCKEY_new_null() SKM_sk_new_null(KRB5_ENCKEY) +#define sk_KRB5_ENCKEY_free(st) SKM_sk_free(KRB5_ENCKEY, (st)) +#define sk_KRB5_ENCKEY_num(st) SKM_sk_num(KRB5_ENCKEY, (st)) +#define sk_KRB5_ENCKEY_value(st, i) SKM_sk_value(KRB5_ENCKEY, (st), (i)) +#define sk_KRB5_ENCKEY_set(st, i, val) SKM_sk_set(KRB5_ENCKEY, (st), (i), (val)) +#define sk_KRB5_ENCKEY_zero(st) SKM_sk_zero(KRB5_ENCKEY, (st)) +#define sk_KRB5_ENCKEY_push(st, val) SKM_sk_push(KRB5_ENCKEY, (st), (val)) +#define sk_KRB5_ENCKEY_unshift(st, val) SKM_sk_unshift(KRB5_ENCKEY, (st), (val)) +#define sk_KRB5_ENCKEY_find(st, val) SKM_sk_find(KRB5_ENCKEY, (st), (val)) +#define sk_KRB5_ENCKEY_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCKEY, (st), (val)) +#define sk_KRB5_ENCKEY_delete(st, i) SKM_sk_delete(KRB5_ENCKEY, (st), (i)) +#define sk_KRB5_ENCKEY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCKEY, (st), (ptr)) +#define sk_KRB5_ENCKEY_insert(st, val, i) SKM_sk_insert(KRB5_ENCKEY, (st), (val), (i)) +#define sk_KRB5_ENCKEY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCKEY, (st), (cmp)) +#define sk_KRB5_ENCKEY_dup(st) SKM_sk_dup(KRB5_ENCKEY, st) +#define sk_KRB5_ENCKEY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCKEY, (st), (free_func)) +#define sk_KRB5_ENCKEY_shift(st) SKM_sk_shift(KRB5_ENCKEY, (st)) +#define sk_KRB5_ENCKEY_pop(st) SKM_sk_pop(KRB5_ENCKEY, (st)) +#define sk_KRB5_ENCKEY_sort(st) SKM_sk_sort(KRB5_ENCKEY, (st)) +#define sk_KRB5_ENCKEY_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCKEY, (st)) + +#define sk_KRB5_PRINCNAME_new(cmp) SKM_sk_new(KRB5_PRINCNAME, (cmp)) +#define sk_KRB5_PRINCNAME_new_null() SKM_sk_new_null(KRB5_PRINCNAME) +#define sk_KRB5_PRINCNAME_free(st) SKM_sk_free(KRB5_PRINCNAME, (st)) +#define sk_KRB5_PRINCNAME_num(st) SKM_sk_num(KRB5_PRINCNAME, (st)) +#define sk_KRB5_PRINCNAME_value(st, i) SKM_sk_value(KRB5_PRINCNAME, (st), (i)) +#define sk_KRB5_PRINCNAME_set(st, i, val) SKM_sk_set(KRB5_PRINCNAME, (st), (i), (val)) +#define sk_KRB5_PRINCNAME_zero(st) SKM_sk_zero(KRB5_PRINCNAME, (st)) +#define sk_KRB5_PRINCNAME_push(st, val) SKM_sk_push(KRB5_PRINCNAME, (st), (val)) +#define sk_KRB5_PRINCNAME_unshift(st, val) SKM_sk_unshift(KRB5_PRINCNAME, (st), (val)) +#define sk_KRB5_PRINCNAME_find(st, val) SKM_sk_find(KRB5_PRINCNAME, (st), (val)) +#define sk_KRB5_PRINCNAME_find_ex(st, val) SKM_sk_find_ex(KRB5_PRINCNAME, (st), (val)) +#define sk_KRB5_PRINCNAME_delete(st, i) SKM_sk_delete(KRB5_PRINCNAME, (st), (i)) +#define sk_KRB5_PRINCNAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_PRINCNAME, (st), (ptr)) +#define sk_KRB5_PRINCNAME_insert(st, val, i) SKM_sk_insert(KRB5_PRINCNAME, (st), (val), (i)) +#define sk_KRB5_PRINCNAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_PRINCNAME, (st), (cmp)) +#define sk_KRB5_PRINCNAME_dup(st) SKM_sk_dup(KRB5_PRINCNAME, st) +#define sk_KRB5_PRINCNAME_pop_free(st, free_func) SKM_sk_pop_free(KRB5_PRINCNAME, (st), (free_func)) +#define sk_KRB5_PRINCNAME_shift(st) SKM_sk_shift(KRB5_PRINCNAME, (st)) +#define sk_KRB5_PRINCNAME_pop(st) SKM_sk_pop(KRB5_PRINCNAME, (st)) +#define sk_KRB5_PRINCNAME_sort(st) SKM_sk_sort(KRB5_PRINCNAME, (st)) +#define sk_KRB5_PRINCNAME_is_sorted(st) SKM_sk_is_sorted(KRB5_PRINCNAME, (st)) + +#define sk_KRB5_TKTBODY_new(cmp) SKM_sk_new(KRB5_TKTBODY, (cmp)) +#define sk_KRB5_TKTBODY_new_null() SKM_sk_new_null(KRB5_TKTBODY) +#define sk_KRB5_TKTBODY_free(st) SKM_sk_free(KRB5_TKTBODY, (st)) +#define sk_KRB5_TKTBODY_num(st) SKM_sk_num(KRB5_TKTBODY, (st)) +#define sk_KRB5_TKTBODY_value(st, i) SKM_sk_value(KRB5_TKTBODY, (st), (i)) +#define sk_KRB5_TKTBODY_set(st, i, val) SKM_sk_set(KRB5_TKTBODY, (st), (i), (val)) +#define sk_KRB5_TKTBODY_zero(st) SKM_sk_zero(KRB5_TKTBODY, (st)) +#define sk_KRB5_TKTBODY_push(st, val) SKM_sk_push(KRB5_TKTBODY, (st), (val)) +#define sk_KRB5_TKTBODY_unshift(st, val) SKM_sk_unshift(KRB5_TKTBODY, (st), (val)) +#define sk_KRB5_TKTBODY_find(st, val) SKM_sk_find(KRB5_TKTBODY, (st), (val)) +#define sk_KRB5_TKTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_TKTBODY, (st), (val)) +#define sk_KRB5_TKTBODY_delete(st, i) SKM_sk_delete(KRB5_TKTBODY, (st), (i)) +#define sk_KRB5_TKTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_TKTBODY, (st), (ptr)) +#define sk_KRB5_TKTBODY_insert(st, val, i) SKM_sk_insert(KRB5_TKTBODY, (st), (val), (i)) +#define sk_KRB5_TKTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_TKTBODY, (st), (cmp)) +#define sk_KRB5_TKTBODY_dup(st) SKM_sk_dup(KRB5_TKTBODY, st) +#define sk_KRB5_TKTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_TKTBODY, (st), (free_func)) +#define sk_KRB5_TKTBODY_shift(st) SKM_sk_shift(KRB5_TKTBODY, (st)) +#define sk_KRB5_TKTBODY_pop(st) SKM_sk_pop(KRB5_TKTBODY, (st)) +#define sk_KRB5_TKTBODY_sort(st) SKM_sk_sort(KRB5_TKTBODY, (st)) +#define sk_KRB5_TKTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_TKTBODY, (st)) + +#define sk_MEM_OBJECT_DATA_new(cmp) SKM_sk_new(MEM_OBJECT_DATA, (cmp)) +#define sk_MEM_OBJECT_DATA_new_null() SKM_sk_new_null(MEM_OBJECT_DATA) +#define sk_MEM_OBJECT_DATA_free(st) SKM_sk_free(MEM_OBJECT_DATA, (st)) +#define sk_MEM_OBJECT_DATA_num(st) SKM_sk_num(MEM_OBJECT_DATA, (st)) +#define sk_MEM_OBJECT_DATA_value(st, i) SKM_sk_value(MEM_OBJECT_DATA, (st), (i)) +#define sk_MEM_OBJECT_DATA_set(st, i, val) SKM_sk_set(MEM_OBJECT_DATA, (st), (i), (val)) +#define sk_MEM_OBJECT_DATA_zero(st) SKM_sk_zero(MEM_OBJECT_DATA, (st)) +#define sk_MEM_OBJECT_DATA_push(st, val) SKM_sk_push(MEM_OBJECT_DATA, (st), (val)) +#define sk_MEM_OBJECT_DATA_unshift(st, val) SKM_sk_unshift(MEM_OBJECT_DATA, (st), (val)) +#define sk_MEM_OBJECT_DATA_find(st, val) SKM_sk_find(MEM_OBJECT_DATA, (st), (val)) +#define sk_MEM_OBJECT_DATA_find_ex(st, val) SKM_sk_find_ex(MEM_OBJECT_DATA, (st), (val)) +#define sk_MEM_OBJECT_DATA_delete(st, i) SKM_sk_delete(MEM_OBJECT_DATA, (st), (i)) +#define sk_MEM_OBJECT_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(MEM_OBJECT_DATA, (st), (ptr)) +#define sk_MEM_OBJECT_DATA_insert(st, val, i) SKM_sk_insert(MEM_OBJECT_DATA, (st), (val), (i)) +#define sk_MEM_OBJECT_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MEM_OBJECT_DATA, (st), (cmp)) +#define sk_MEM_OBJECT_DATA_dup(st) SKM_sk_dup(MEM_OBJECT_DATA, st) +#define sk_MEM_OBJECT_DATA_pop_free(st, free_func) SKM_sk_pop_free(MEM_OBJECT_DATA, (st), (free_func)) +#define sk_MEM_OBJECT_DATA_shift(st) SKM_sk_shift(MEM_OBJECT_DATA, (st)) +#define sk_MEM_OBJECT_DATA_pop(st) SKM_sk_pop(MEM_OBJECT_DATA, (st)) +#define sk_MEM_OBJECT_DATA_sort(st) SKM_sk_sort(MEM_OBJECT_DATA, (st)) +#define sk_MEM_OBJECT_DATA_is_sorted(st) SKM_sk_is_sorted(MEM_OBJECT_DATA, (st)) + +#define sk_MIME_HEADER_new(cmp) SKM_sk_new(MIME_HEADER, (cmp)) +#define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER) +#define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st)) +#define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st)) +#define sk_MIME_HEADER_value(st, i) SKM_sk_value(MIME_HEADER, (st), (i)) +#define sk_MIME_HEADER_set(st, i, val) SKM_sk_set(MIME_HEADER, (st), (i), (val)) +#define sk_MIME_HEADER_zero(st) SKM_sk_zero(MIME_HEADER, (st)) +#define sk_MIME_HEADER_push(st, val) SKM_sk_push(MIME_HEADER, (st), (val)) +#define sk_MIME_HEADER_unshift(st, val) SKM_sk_unshift(MIME_HEADER, (st), (val)) +#define sk_MIME_HEADER_find(st, val) SKM_sk_find(MIME_HEADER, (st), (val)) +#define sk_MIME_HEADER_find_ex(st, val) SKM_sk_find_ex(MIME_HEADER, (st), (val)) +#define sk_MIME_HEADER_delete(st, i) SKM_sk_delete(MIME_HEADER, (st), (i)) +#define sk_MIME_HEADER_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_HEADER, (st), (ptr)) +#define sk_MIME_HEADER_insert(st, val, i) SKM_sk_insert(MIME_HEADER, (st), (val), (i)) +#define sk_MIME_HEADER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_HEADER, (st), (cmp)) +#define sk_MIME_HEADER_dup(st) SKM_sk_dup(MIME_HEADER, st) +#define sk_MIME_HEADER_pop_free(st, free_func) SKM_sk_pop_free(MIME_HEADER, (st), (free_func)) +#define sk_MIME_HEADER_shift(st) SKM_sk_shift(MIME_HEADER, (st)) +#define sk_MIME_HEADER_pop(st) SKM_sk_pop(MIME_HEADER, (st)) +#define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st)) +#define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st)) + +#define sk_MIME_PARAM_new(cmp) SKM_sk_new(MIME_PARAM, (cmp)) +#define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM) +#define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st)) +#define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st)) +#define sk_MIME_PARAM_value(st, i) SKM_sk_value(MIME_PARAM, (st), (i)) +#define sk_MIME_PARAM_set(st, i, val) SKM_sk_set(MIME_PARAM, (st), (i), (val)) +#define sk_MIME_PARAM_zero(st) SKM_sk_zero(MIME_PARAM, (st)) +#define sk_MIME_PARAM_push(st, val) SKM_sk_push(MIME_PARAM, (st), (val)) +#define sk_MIME_PARAM_unshift(st, val) SKM_sk_unshift(MIME_PARAM, (st), (val)) +#define sk_MIME_PARAM_find(st, val) SKM_sk_find(MIME_PARAM, (st), (val)) +#define sk_MIME_PARAM_find_ex(st, val) SKM_sk_find_ex(MIME_PARAM, (st), (val)) +#define sk_MIME_PARAM_delete(st, i) SKM_sk_delete(MIME_PARAM, (st), (i)) +#define sk_MIME_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_PARAM, (st), (ptr)) +#define sk_MIME_PARAM_insert(st, val, i) SKM_sk_insert(MIME_PARAM, (st), (val), (i)) +#define sk_MIME_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_PARAM, (st), (cmp)) +#define sk_MIME_PARAM_dup(st) SKM_sk_dup(MIME_PARAM, st) +#define sk_MIME_PARAM_pop_free(st, free_func) SKM_sk_pop_free(MIME_PARAM, (st), (free_func)) +#define sk_MIME_PARAM_shift(st) SKM_sk_shift(MIME_PARAM, (st)) +#define sk_MIME_PARAM_pop(st) SKM_sk_pop(MIME_PARAM, (st)) +#define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st)) +#define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st)) + +#define sk_NAME_FUNCS_new(cmp) SKM_sk_new(NAME_FUNCS, (cmp)) +#define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS) +#define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st)) +#define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st)) +#define sk_NAME_FUNCS_value(st, i) SKM_sk_value(NAME_FUNCS, (st), (i)) +#define sk_NAME_FUNCS_set(st, i, val) SKM_sk_set(NAME_FUNCS, (st), (i), (val)) +#define sk_NAME_FUNCS_zero(st) SKM_sk_zero(NAME_FUNCS, (st)) +#define sk_NAME_FUNCS_push(st, val) SKM_sk_push(NAME_FUNCS, (st), (val)) +#define sk_NAME_FUNCS_unshift(st, val) SKM_sk_unshift(NAME_FUNCS, (st), (val)) +#define sk_NAME_FUNCS_find(st, val) SKM_sk_find(NAME_FUNCS, (st), (val)) +#define sk_NAME_FUNCS_find_ex(st, val) SKM_sk_find_ex(NAME_FUNCS, (st), (val)) +#define sk_NAME_FUNCS_delete(st, i) SKM_sk_delete(NAME_FUNCS, (st), (i)) +#define sk_NAME_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(NAME_FUNCS, (st), (ptr)) +#define sk_NAME_FUNCS_insert(st, val, i) SKM_sk_insert(NAME_FUNCS, (st), (val), (i)) +#define sk_NAME_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(NAME_FUNCS, (st), (cmp)) +#define sk_NAME_FUNCS_dup(st) SKM_sk_dup(NAME_FUNCS, st) +#define sk_NAME_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(NAME_FUNCS, (st), (free_func)) +#define sk_NAME_FUNCS_shift(st) SKM_sk_shift(NAME_FUNCS, (st)) +#define sk_NAME_FUNCS_pop(st) SKM_sk_pop(NAME_FUNCS, (st)) +#define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st)) +#define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st)) + +#define sk_OCSP_CERTID_new(cmp) SKM_sk_new(OCSP_CERTID, (cmp)) +#define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID) +#define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st)) +#define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st)) +#define sk_OCSP_CERTID_value(st, i) SKM_sk_value(OCSP_CERTID, (st), (i)) +#define sk_OCSP_CERTID_set(st, i, val) SKM_sk_set(OCSP_CERTID, (st), (i), (val)) +#define sk_OCSP_CERTID_zero(st) SKM_sk_zero(OCSP_CERTID, (st)) +#define sk_OCSP_CERTID_push(st, val) SKM_sk_push(OCSP_CERTID, (st), (val)) +#define sk_OCSP_CERTID_unshift(st, val) SKM_sk_unshift(OCSP_CERTID, (st), (val)) +#define sk_OCSP_CERTID_find(st, val) SKM_sk_find(OCSP_CERTID, (st), (val)) +#define sk_OCSP_CERTID_find_ex(st, val) SKM_sk_find_ex(OCSP_CERTID, (st), (val)) +#define sk_OCSP_CERTID_delete(st, i) SKM_sk_delete(OCSP_CERTID, (st), (i)) +#define sk_OCSP_CERTID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_CERTID, (st), (ptr)) +#define sk_OCSP_CERTID_insert(st, val, i) SKM_sk_insert(OCSP_CERTID, (st), (val), (i)) +#define sk_OCSP_CERTID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_CERTID, (st), (cmp)) +#define sk_OCSP_CERTID_dup(st) SKM_sk_dup(OCSP_CERTID, st) +#define sk_OCSP_CERTID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_CERTID, (st), (free_func)) +#define sk_OCSP_CERTID_shift(st) SKM_sk_shift(OCSP_CERTID, (st)) +#define sk_OCSP_CERTID_pop(st) SKM_sk_pop(OCSP_CERTID, (st)) +#define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st)) +#define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st)) + +#define sk_OCSP_ONEREQ_new(cmp) SKM_sk_new(OCSP_ONEREQ, (cmp)) +#define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ) +#define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st)) +#define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st)) +#define sk_OCSP_ONEREQ_value(st, i) SKM_sk_value(OCSP_ONEREQ, (st), (i)) +#define sk_OCSP_ONEREQ_set(st, i, val) SKM_sk_set(OCSP_ONEREQ, (st), (i), (val)) +#define sk_OCSP_ONEREQ_zero(st) SKM_sk_zero(OCSP_ONEREQ, (st)) +#define sk_OCSP_ONEREQ_push(st, val) SKM_sk_push(OCSP_ONEREQ, (st), (val)) +#define sk_OCSP_ONEREQ_unshift(st, val) SKM_sk_unshift(OCSP_ONEREQ, (st), (val)) +#define sk_OCSP_ONEREQ_find(st, val) SKM_sk_find(OCSP_ONEREQ, (st), (val)) +#define sk_OCSP_ONEREQ_find_ex(st, val) SKM_sk_find_ex(OCSP_ONEREQ, (st), (val)) +#define sk_OCSP_ONEREQ_delete(st, i) SKM_sk_delete(OCSP_ONEREQ, (st), (i)) +#define sk_OCSP_ONEREQ_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_ONEREQ, (st), (ptr)) +#define sk_OCSP_ONEREQ_insert(st, val, i) SKM_sk_insert(OCSP_ONEREQ, (st), (val), (i)) +#define sk_OCSP_ONEREQ_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_ONEREQ, (st), (cmp)) +#define sk_OCSP_ONEREQ_dup(st) SKM_sk_dup(OCSP_ONEREQ, st) +#define sk_OCSP_ONEREQ_pop_free(st, free_func) SKM_sk_pop_free(OCSP_ONEREQ, (st), (free_func)) +#define sk_OCSP_ONEREQ_shift(st) SKM_sk_shift(OCSP_ONEREQ, (st)) +#define sk_OCSP_ONEREQ_pop(st) SKM_sk_pop(OCSP_ONEREQ, (st)) +#define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st)) +#define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st)) + +#define sk_OCSP_RESPID_new(cmp) SKM_sk_new(OCSP_RESPID, (cmp)) +#define sk_OCSP_RESPID_new_null() SKM_sk_new_null(OCSP_RESPID) +#define sk_OCSP_RESPID_free(st) SKM_sk_free(OCSP_RESPID, (st)) +#define sk_OCSP_RESPID_num(st) SKM_sk_num(OCSP_RESPID, (st)) +#define sk_OCSP_RESPID_value(st, i) SKM_sk_value(OCSP_RESPID, (st), (i)) +#define sk_OCSP_RESPID_set(st, i, val) SKM_sk_set(OCSP_RESPID, (st), (i), (val)) +#define sk_OCSP_RESPID_zero(st) SKM_sk_zero(OCSP_RESPID, (st)) +#define sk_OCSP_RESPID_push(st, val) SKM_sk_push(OCSP_RESPID, (st), (val)) +#define sk_OCSP_RESPID_unshift(st, val) SKM_sk_unshift(OCSP_RESPID, (st), (val)) +#define sk_OCSP_RESPID_find(st, val) SKM_sk_find(OCSP_RESPID, (st), (val)) +#define sk_OCSP_RESPID_find_ex(st, val) SKM_sk_find_ex(OCSP_RESPID, (st), (val)) +#define sk_OCSP_RESPID_delete(st, i) SKM_sk_delete(OCSP_RESPID, (st), (i)) +#define sk_OCSP_RESPID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_RESPID, (st), (ptr)) +#define sk_OCSP_RESPID_insert(st, val, i) SKM_sk_insert(OCSP_RESPID, (st), (val), (i)) +#define sk_OCSP_RESPID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_RESPID, (st), (cmp)) +#define sk_OCSP_RESPID_dup(st) SKM_sk_dup(OCSP_RESPID, st) +#define sk_OCSP_RESPID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_RESPID, (st), (free_func)) +#define sk_OCSP_RESPID_shift(st) SKM_sk_shift(OCSP_RESPID, (st)) +#define sk_OCSP_RESPID_pop(st) SKM_sk_pop(OCSP_RESPID, (st)) +#define sk_OCSP_RESPID_sort(st) SKM_sk_sort(OCSP_RESPID, (st)) +#define sk_OCSP_RESPID_is_sorted(st) SKM_sk_is_sorted(OCSP_RESPID, (st)) + +#define sk_OCSP_SINGLERESP_new(cmp) SKM_sk_new(OCSP_SINGLERESP, (cmp)) +#define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP) +#define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st)) +#define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st)) +#define sk_OCSP_SINGLERESP_value(st, i) SKM_sk_value(OCSP_SINGLERESP, (st), (i)) +#define sk_OCSP_SINGLERESP_set(st, i, val) SKM_sk_set(OCSP_SINGLERESP, (st), (i), (val)) +#define sk_OCSP_SINGLERESP_zero(st) SKM_sk_zero(OCSP_SINGLERESP, (st)) +#define sk_OCSP_SINGLERESP_push(st, val) SKM_sk_push(OCSP_SINGLERESP, (st), (val)) +#define sk_OCSP_SINGLERESP_unshift(st, val) SKM_sk_unshift(OCSP_SINGLERESP, (st), (val)) +#define sk_OCSP_SINGLERESP_find(st, val) SKM_sk_find(OCSP_SINGLERESP, (st), (val)) +#define sk_OCSP_SINGLERESP_find_ex(st, val) SKM_sk_find_ex(OCSP_SINGLERESP, (st), (val)) +#define sk_OCSP_SINGLERESP_delete(st, i) SKM_sk_delete(OCSP_SINGLERESP, (st), (i)) +#define sk_OCSP_SINGLERESP_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_SINGLERESP, (st), (ptr)) +#define sk_OCSP_SINGLERESP_insert(st, val, i) SKM_sk_insert(OCSP_SINGLERESP, (st), (val), (i)) +#define sk_OCSP_SINGLERESP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_SINGLERESP, (st), (cmp)) +#define sk_OCSP_SINGLERESP_dup(st) SKM_sk_dup(OCSP_SINGLERESP, st) +#define sk_OCSP_SINGLERESP_pop_free(st, free_func) SKM_sk_pop_free(OCSP_SINGLERESP, (st), (free_func)) +#define sk_OCSP_SINGLERESP_shift(st) SKM_sk_shift(OCSP_SINGLERESP, (st)) +#define sk_OCSP_SINGLERESP_pop(st) SKM_sk_pop(OCSP_SINGLERESP, (st)) +#define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st)) +#define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st)) + +#define sk_PKCS12_SAFEBAG_new(cmp) SKM_sk_new(PKCS12_SAFEBAG, (cmp)) +#define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG) +#define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st)) +#define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st)) +#define sk_PKCS12_SAFEBAG_value(st, i) SKM_sk_value(PKCS12_SAFEBAG, (st), (i)) +#define sk_PKCS12_SAFEBAG_set(st, i, val) SKM_sk_set(PKCS12_SAFEBAG, (st), (i), (val)) +#define sk_PKCS12_SAFEBAG_zero(st) SKM_sk_zero(PKCS12_SAFEBAG, (st)) +#define sk_PKCS12_SAFEBAG_push(st, val) SKM_sk_push(PKCS12_SAFEBAG, (st), (val)) +#define sk_PKCS12_SAFEBAG_unshift(st, val) SKM_sk_unshift(PKCS12_SAFEBAG, (st), (val)) +#define sk_PKCS12_SAFEBAG_find(st, val) SKM_sk_find(PKCS12_SAFEBAG, (st), (val)) +#define sk_PKCS12_SAFEBAG_find_ex(st, val) SKM_sk_find_ex(PKCS12_SAFEBAG, (st), (val)) +#define sk_PKCS12_SAFEBAG_delete(st, i) SKM_sk_delete(PKCS12_SAFEBAG, (st), (i)) +#define sk_PKCS12_SAFEBAG_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS12_SAFEBAG, (st), (ptr)) +#define sk_PKCS12_SAFEBAG_insert(st, val, i) SKM_sk_insert(PKCS12_SAFEBAG, (st), (val), (i)) +#define sk_PKCS12_SAFEBAG_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS12_SAFEBAG, (st), (cmp)) +#define sk_PKCS12_SAFEBAG_dup(st) SKM_sk_dup(PKCS12_SAFEBAG, st) +#define sk_PKCS12_SAFEBAG_pop_free(st, free_func) SKM_sk_pop_free(PKCS12_SAFEBAG, (st), (free_func)) +#define sk_PKCS12_SAFEBAG_shift(st) SKM_sk_shift(PKCS12_SAFEBAG, (st)) +#define sk_PKCS12_SAFEBAG_pop(st) SKM_sk_pop(PKCS12_SAFEBAG, (st)) +#define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st)) +#define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st)) + +#define sk_PKCS7_new(cmp) SKM_sk_new(PKCS7, (cmp)) +#define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7) +#define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st)) +#define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st)) +#define sk_PKCS7_value(st, i) SKM_sk_value(PKCS7, (st), (i)) +#define sk_PKCS7_set(st, i, val) SKM_sk_set(PKCS7, (st), (i), (val)) +#define sk_PKCS7_zero(st) SKM_sk_zero(PKCS7, (st)) +#define sk_PKCS7_push(st, val) SKM_sk_push(PKCS7, (st), (val)) +#define sk_PKCS7_unshift(st, val) SKM_sk_unshift(PKCS7, (st), (val)) +#define sk_PKCS7_find(st, val) SKM_sk_find(PKCS7, (st), (val)) +#define sk_PKCS7_find_ex(st, val) SKM_sk_find_ex(PKCS7, (st), (val)) +#define sk_PKCS7_delete(st, i) SKM_sk_delete(PKCS7, (st), (i)) +#define sk_PKCS7_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7, (st), (ptr)) +#define sk_PKCS7_insert(st, val, i) SKM_sk_insert(PKCS7, (st), (val), (i)) +#define sk_PKCS7_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7, (st), (cmp)) +#define sk_PKCS7_dup(st) SKM_sk_dup(PKCS7, st) +#define sk_PKCS7_pop_free(st, free_func) SKM_sk_pop_free(PKCS7, (st), (free_func)) +#define sk_PKCS7_shift(st) SKM_sk_shift(PKCS7, (st)) +#define sk_PKCS7_pop(st) SKM_sk_pop(PKCS7, (st)) +#define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st)) +#define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st)) + +#define sk_PKCS7_RECIP_INFO_new(cmp) SKM_sk_new(PKCS7_RECIP_INFO, (cmp)) +#define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO) +#define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st)) +#define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st)) +#define sk_PKCS7_RECIP_INFO_value(st, i) SKM_sk_value(PKCS7_RECIP_INFO, (st), (i)) +#define sk_PKCS7_RECIP_INFO_set(st, i, val) SKM_sk_set(PKCS7_RECIP_INFO, (st), (i), (val)) +#define sk_PKCS7_RECIP_INFO_zero(st) SKM_sk_zero(PKCS7_RECIP_INFO, (st)) +#define sk_PKCS7_RECIP_INFO_push(st, val) SKM_sk_push(PKCS7_RECIP_INFO, (st), (val)) +#define sk_PKCS7_RECIP_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_RECIP_INFO, (st), (val)) +#define sk_PKCS7_RECIP_INFO_find(st, val) SKM_sk_find(PKCS7_RECIP_INFO, (st), (val)) +#define sk_PKCS7_RECIP_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_RECIP_INFO, (st), (val)) +#define sk_PKCS7_RECIP_INFO_delete(st, i) SKM_sk_delete(PKCS7_RECIP_INFO, (st), (i)) +#define sk_PKCS7_RECIP_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_RECIP_INFO, (st), (ptr)) +#define sk_PKCS7_RECIP_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_RECIP_INFO, (st), (val), (i)) +#define sk_PKCS7_RECIP_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_RECIP_INFO, (st), (cmp)) +#define sk_PKCS7_RECIP_INFO_dup(st) SKM_sk_dup(PKCS7_RECIP_INFO, st) +#define sk_PKCS7_RECIP_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_RECIP_INFO, (st), (free_func)) +#define sk_PKCS7_RECIP_INFO_shift(st) SKM_sk_shift(PKCS7_RECIP_INFO, (st)) +#define sk_PKCS7_RECIP_INFO_pop(st) SKM_sk_pop(PKCS7_RECIP_INFO, (st)) +#define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st)) +#define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st)) + +#define sk_PKCS7_SIGNER_INFO_new(cmp) SKM_sk_new(PKCS7_SIGNER_INFO, (cmp)) +#define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO) +#define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st)) +#define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st)) +#define sk_PKCS7_SIGNER_INFO_value(st, i) SKM_sk_value(PKCS7_SIGNER_INFO, (st), (i)) +#define sk_PKCS7_SIGNER_INFO_set(st, i, val) SKM_sk_set(PKCS7_SIGNER_INFO, (st), (i), (val)) +#define sk_PKCS7_SIGNER_INFO_zero(st) SKM_sk_zero(PKCS7_SIGNER_INFO, (st)) +#define sk_PKCS7_SIGNER_INFO_push(st, val) SKM_sk_push(PKCS7_SIGNER_INFO, (st), (val)) +#define sk_PKCS7_SIGNER_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_SIGNER_INFO, (st), (val)) +#define sk_PKCS7_SIGNER_INFO_find(st, val) SKM_sk_find(PKCS7_SIGNER_INFO, (st), (val)) +#define sk_PKCS7_SIGNER_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_SIGNER_INFO, (st), (val)) +#define sk_PKCS7_SIGNER_INFO_delete(st, i) SKM_sk_delete(PKCS7_SIGNER_INFO, (st), (i)) +#define sk_PKCS7_SIGNER_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_SIGNER_INFO, (st), (ptr)) +#define sk_PKCS7_SIGNER_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_SIGNER_INFO, (st), (val), (i)) +#define sk_PKCS7_SIGNER_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_SIGNER_INFO, (st), (cmp)) +#define sk_PKCS7_SIGNER_INFO_dup(st) SKM_sk_dup(PKCS7_SIGNER_INFO, st) +#define sk_PKCS7_SIGNER_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_SIGNER_INFO, (st), (free_func)) +#define sk_PKCS7_SIGNER_INFO_shift(st) SKM_sk_shift(PKCS7_SIGNER_INFO, (st)) +#define sk_PKCS7_SIGNER_INFO_pop(st) SKM_sk_pop(PKCS7_SIGNER_INFO, (st)) +#define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st)) +#define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st)) + +#define sk_POLICYINFO_new(cmp) SKM_sk_new(POLICYINFO, (cmp)) +#define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO) +#define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st)) +#define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st)) +#define sk_POLICYINFO_value(st, i) SKM_sk_value(POLICYINFO, (st), (i)) +#define sk_POLICYINFO_set(st, i, val) SKM_sk_set(POLICYINFO, (st), (i), (val)) +#define sk_POLICYINFO_zero(st) SKM_sk_zero(POLICYINFO, (st)) +#define sk_POLICYINFO_push(st, val) SKM_sk_push(POLICYINFO, (st), (val)) +#define sk_POLICYINFO_unshift(st, val) SKM_sk_unshift(POLICYINFO, (st), (val)) +#define sk_POLICYINFO_find(st, val) SKM_sk_find(POLICYINFO, (st), (val)) +#define sk_POLICYINFO_find_ex(st, val) SKM_sk_find_ex(POLICYINFO, (st), (val)) +#define sk_POLICYINFO_delete(st, i) SKM_sk_delete(POLICYINFO, (st), (i)) +#define sk_POLICYINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYINFO, (st), (ptr)) +#define sk_POLICYINFO_insert(st, val, i) SKM_sk_insert(POLICYINFO, (st), (val), (i)) +#define sk_POLICYINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYINFO, (st), (cmp)) +#define sk_POLICYINFO_dup(st) SKM_sk_dup(POLICYINFO, st) +#define sk_POLICYINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYINFO, (st), (free_func)) +#define sk_POLICYINFO_shift(st) SKM_sk_shift(POLICYINFO, (st)) +#define sk_POLICYINFO_pop(st) SKM_sk_pop(POLICYINFO, (st)) +#define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st)) +#define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st)) + +#define sk_POLICYQUALINFO_new(cmp) SKM_sk_new(POLICYQUALINFO, (cmp)) +#define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO) +#define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st)) +#define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st)) +#define sk_POLICYQUALINFO_value(st, i) SKM_sk_value(POLICYQUALINFO, (st), (i)) +#define sk_POLICYQUALINFO_set(st, i, val) SKM_sk_set(POLICYQUALINFO, (st), (i), (val)) +#define sk_POLICYQUALINFO_zero(st) SKM_sk_zero(POLICYQUALINFO, (st)) +#define sk_POLICYQUALINFO_push(st, val) SKM_sk_push(POLICYQUALINFO, (st), (val)) +#define sk_POLICYQUALINFO_unshift(st, val) SKM_sk_unshift(POLICYQUALINFO, (st), (val)) +#define sk_POLICYQUALINFO_find(st, val) SKM_sk_find(POLICYQUALINFO, (st), (val)) +#define sk_POLICYQUALINFO_find_ex(st, val) SKM_sk_find_ex(POLICYQUALINFO, (st), (val)) +#define sk_POLICYQUALINFO_delete(st, i) SKM_sk_delete(POLICYQUALINFO, (st), (i)) +#define sk_POLICYQUALINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYQUALINFO, (st), (ptr)) +#define sk_POLICYQUALINFO_insert(st, val, i) SKM_sk_insert(POLICYQUALINFO, (st), (val), (i)) +#define sk_POLICYQUALINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYQUALINFO, (st), (cmp)) +#define sk_POLICYQUALINFO_dup(st) SKM_sk_dup(POLICYQUALINFO, st) +#define sk_POLICYQUALINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYQUALINFO, (st), (free_func)) +#define sk_POLICYQUALINFO_shift(st) SKM_sk_shift(POLICYQUALINFO, (st)) +#define sk_POLICYQUALINFO_pop(st) SKM_sk_pop(POLICYQUALINFO, (st)) +#define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st)) +#define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st)) + +#define sk_POLICY_MAPPING_new(cmp) SKM_sk_new(POLICY_MAPPING, (cmp)) +#define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING) +#define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st)) +#define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st)) +#define sk_POLICY_MAPPING_value(st, i) SKM_sk_value(POLICY_MAPPING, (st), (i)) +#define sk_POLICY_MAPPING_set(st, i, val) SKM_sk_set(POLICY_MAPPING, (st), (i), (val)) +#define sk_POLICY_MAPPING_zero(st) SKM_sk_zero(POLICY_MAPPING, (st)) +#define sk_POLICY_MAPPING_push(st, val) SKM_sk_push(POLICY_MAPPING, (st), (val)) +#define sk_POLICY_MAPPING_unshift(st, val) SKM_sk_unshift(POLICY_MAPPING, (st), (val)) +#define sk_POLICY_MAPPING_find(st, val) SKM_sk_find(POLICY_MAPPING, (st), (val)) +#define sk_POLICY_MAPPING_find_ex(st, val) SKM_sk_find_ex(POLICY_MAPPING, (st), (val)) +#define sk_POLICY_MAPPING_delete(st, i) SKM_sk_delete(POLICY_MAPPING, (st), (i)) +#define sk_POLICY_MAPPING_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICY_MAPPING, (st), (ptr)) +#define sk_POLICY_MAPPING_insert(st, val, i) SKM_sk_insert(POLICY_MAPPING, (st), (val), (i)) +#define sk_POLICY_MAPPING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICY_MAPPING, (st), (cmp)) +#define sk_POLICY_MAPPING_dup(st) SKM_sk_dup(POLICY_MAPPING, st) +#define sk_POLICY_MAPPING_pop_free(st, free_func) SKM_sk_pop_free(POLICY_MAPPING, (st), (free_func)) +#define sk_POLICY_MAPPING_shift(st) SKM_sk_shift(POLICY_MAPPING, (st)) +#define sk_POLICY_MAPPING_pop(st) SKM_sk_pop(POLICY_MAPPING, (st)) +#define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st)) +#define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st)) + +#define sk_SRP_gN_new(cmp) SKM_sk_new(SRP_gN, (cmp)) +#define sk_SRP_gN_new_null() SKM_sk_new_null(SRP_gN) +#define sk_SRP_gN_free(st) SKM_sk_free(SRP_gN, (st)) +#define sk_SRP_gN_num(st) SKM_sk_num(SRP_gN, (st)) +#define sk_SRP_gN_value(st, i) SKM_sk_value(SRP_gN, (st), (i)) +#define sk_SRP_gN_set(st, i, val) SKM_sk_set(SRP_gN, (st), (i), (val)) +#define sk_SRP_gN_zero(st) SKM_sk_zero(SRP_gN, (st)) +#define sk_SRP_gN_push(st, val) SKM_sk_push(SRP_gN, (st), (val)) +#define sk_SRP_gN_unshift(st, val) SKM_sk_unshift(SRP_gN, (st), (val)) +#define sk_SRP_gN_find(st, val) SKM_sk_find(SRP_gN, (st), (val)) +#define sk_SRP_gN_find_ex(st, val) SKM_sk_find_ex(SRP_gN, (st), (val)) +#define sk_SRP_gN_delete(st, i) SKM_sk_delete(SRP_gN, (st), (i)) +#define sk_SRP_gN_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN, (st), (ptr)) +#define sk_SRP_gN_insert(st, val, i) SKM_sk_insert(SRP_gN, (st), (val), (i)) +#define sk_SRP_gN_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN, (st), (cmp)) +#define sk_SRP_gN_dup(st) SKM_sk_dup(SRP_gN, st) +#define sk_SRP_gN_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN, (st), (free_func)) +#define sk_SRP_gN_shift(st) SKM_sk_shift(SRP_gN, (st)) +#define sk_SRP_gN_pop(st) SKM_sk_pop(SRP_gN, (st)) +#define sk_SRP_gN_sort(st) SKM_sk_sort(SRP_gN, (st)) +#define sk_SRP_gN_is_sorted(st) SKM_sk_is_sorted(SRP_gN, (st)) + +#define sk_SRP_gN_cache_new(cmp) SKM_sk_new(SRP_gN_cache, (cmp)) +#define sk_SRP_gN_cache_new_null() SKM_sk_new_null(SRP_gN_cache) +#define sk_SRP_gN_cache_free(st) SKM_sk_free(SRP_gN_cache, (st)) +#define sk_SRP_gN_cache_num(st) SKM_sk_num(SRP_gN_cache, (st)) +#define sk_SRP_gN_cache_value(st, i) SKM_sk_value(SRP_gN_cache, (st), (i)) +#define sk_SRP_gN_cache_set(st, i, val) SKM_sk_set(SRP_gN_cache, (st), (i), (val)) +#define sk_SRP_gN_cache_zero(st) SKM_sk_zero(SRP_gN_cache, (st)) +#define sk_SRP_gN_cache_push(st, val) SKM_sk_push(SRP_gN_cache, (st), (val)) +#define sk_SRP_gN_cache_unshift(st, val) SKM_sk_unshift(SRP_gN_cache, (st), (val)) +#define sk_SRP_gN_cache_find(st, val) SKM_sk_find(SRP_gN_cache, (st), (val)) +#define sk_SRP_gN_cache_find_ex(st, val) SKM_sk_find_ex(SRP_gN_cache, (st), (val)) +#define sk_SRP_gN_cache_delete(st, i) SKM_sk_delete(SRP_gN_cache, (st), (i)) +#define sk_SRP_gN_cache_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN_cache, (st), (ptr)) +#define sk_SRP_gN_cache_insert(st, val, i) SKM_sk_insert(SRP_gN_cache, (st), (val), (i)) +#define sk_SRP_gN_cache_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN_cache, (st), (cmp)) +#define sk_SRP_gN_cache_dup(st) SKM_sk_dup(SRP_gN_cache, st) +#define sk_SRP_gN_cache_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN_cache, (st), (free_func)) +#define sk_SRP_gN_cache_shift(st) SKM_sk_shift(SRP_gN_cache, (st)) +#define sk_SRP_gN_cache_pop(st) SKM_sk_pop(SRP_gN_cache, (st)) +#define sk_SRP_gN_cache_sort(st) SKM_sk_sort(SRP_gN_cache, (st)) +#define sk_SRP_gN_cache_is_sorted(st) SKM_sk_is_sorted(SRP_gN_cache, (st)) + +#define sk_SRP_user_pwd_new(cmp) SKM_sk_new(SRP_user_pwd, (cmp)) +#define sk_SRP_user_pwd_new_null() SKM_sk_new_null(SRP_user_pwd) +#define sk_SRP_user_pwd_free(st) SKM_sk_free(SRP_user_pwd, (st)) +#define sk_SRP_user_pwd_num(st) SKM_sk_num(SRP_user_pwd, (st)) +#define sk_SRP_user_pwd_value(st, i) SKM_sk_value(SRP_user_pwd, (st), (i)) +#define sk_SRP_user_pwd_set(st, i, val) SKM_sk_set(SRP_user_pwd, (st), (i), (val)) +#define sk_SRP_user_pwd_zero(st) SKM_sk_zero(SRP_user_pwd, (st)) +#define sk_SRP_user_pwd_push(st, val) SKM_sk_push(SRP_user_pwd, (st), (val)) +#define sk_SRP_user_pwd_unshift(st, val) SKM_sk_unshift(SRP_user_pwd, (st), (val)) +#define sk_SRP_user_pwd_find(st, val) SKM_sk_find(SRP_user_pwd, (st), (val)) +#define sk_SRP_user_pwd_find_ex(st, val) SKM_sk_find_ex(SRP_user_pwd, (st), (val)) +#define sk_SRP_user_pwd_delete(st, i) SKM_sk_delete(SRP_user_pwd, (st), (i)) +#define sk_SRP_user_pwd_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_user_pwd, (st), (ptr)) +#define sk_SRP_user_pwd_insert(st, val, i) SKM_sk_insert(SRP_user_pwd, (st), (val), (i)) +#define sk_SRP_user_pwd_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_user_pwd, (st), (cmp)) +#define sk_SRP_user_pwd_dup(st) SKM_sk_dup(SRP_user_pwd, st) +#define sk_SRP_user_pwd_pop_free(st, free_func) SKM_sk_pop_free(SRP_user_pwd, (st), (free_func)) +#define sk_SRP_user_pwd_shift(st) SKM_sk_shift(SRP_user_pwd, (st)) +#define sk_SRP_user_pwd_pop(st) SKM_sk_pop(SRP_user_pwd, (st)) +#define sk_SRP_user_pwd_sort(st) SKM_sk_sort(SRP_user_pwd, (st)) +#define sk_SRP_user_pwd_is_sorted(st) SKM_sk_is_sorted(SRP_user_pwd, (st)) + +#define sk_SRTP_PROTECTION_PROFILE_new(cmp) SKM_sk_new(SRTP_PROTECTION_PROFILE, (cmp)) +#define sk_SRTP_PROTECTION_PROFILE_new_null() SKM_sk_new_null(SRTP_PROTECTION_PROFILE) +#define sk_SRTP_PROTECTION_PROFILE_free(st) SKM_sk_free(SRTP_PROTECTION_PROFILE, (st)) +#define sk_SRTP_PROTECTION_PROFILE_num(st) SKM_sk_num(SRTP_PROTECTION_PROFILE, (st)) +#define sk_SRTP_PROTECTION_PROFILE_value(st, i) SKM_sk_value(SRTP_PROTECTION_PROFILE, (st), (i)) +#define sk_SRTP_PROTECTION_PROFILE_set(st, i, val) SKM_sk_set(SRTP_PROTECTION_PROFILE, (st), (i), (val)) +#define sk_SRTP_PROTECTION_PROFILE_zero(st) SKM_sk_zero(SRTP_PROTECTION_PROFILE, (st)) +#define sk_SRTP_PROTECTION_PROFILE_push(st, val) SKM_sk_push(SRTP_PROTECTION_PROFILE, (st), (val)) +#define sk_SRTP_PROTECTION_PROFILE_unshift(st, val) SKM_sk_unshift(SRTP_PROTECTION_PROFILE, (st), (val)) +#define sk_SRTP_PROTECTION_PROFILE_find(st, val) SKM_sk_find(SRTP_PROTECTION_PROFILE, (st), (val)) +#define sk_SRTP_PROTECTION_PROFILE_find_ex(st, val) SKM_sk_find_ex(SRTP_PROTECTION_PROFILE, (st), (val)) +#define sk_SRTP_PROTECTION_PROFILE_delete(st, i) SKM_sk_delete(SRTP_PROTECTION_PROFILE, (st), (i)) +#define sk_SRTP_PROTECTION_PROFILE_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRTP_PROTECTION_PROFILE, (st), (ptr)) +#define sk_SRTP_PROTECTION_PROFILE_insert(st, val, i) SKM_sk_insert(SRTP_PROTECTION_PROFILE, (st), (val), (i)) +#define sk_SRTP_PROTECTION_PROFILE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRTP_PROTECTION_PROFILE, (st), (cmp)) +#define sk_SRTP_PROTECTION_PROFILE_dup(st) SKM_sk_dup(SRTP_PROTECTION_PROFILE, st) +#define sk_SRTP_PROTECTION_PROFILE_pop_free(st, free_func) SKM_sk_pop_free(SRTP_PROTECTION_PROFILE, (st), (free_func)) +#define sk_SRTP_PROTECTION_PROFILE_shift(st) SKM_sk_shift(SRTP_PROTECTION_PROFILE, (st)) +#define sk_SRTP_PROTECTION_PROFILE_pop(st) SKM_sk_pop(SRTP_PROTECTION_PROFILE, (st)) +#define sk_SRTP_PROTECTION_PROFILE_sort(st) SKM_sk_sort(SRTP_PROTECTION_PROFILE, (st)) +#define sk_SRTP_PROTECTION_PROFILE_is_sorted(st) SKM_sk_is_sorted(SRTP_PROTECTION_PROFILE, (st)) + +#define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp)) +#define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER) +#define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st)) +#define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st)) +#define sk_SSL_CIPHER_value(st, i) SKM_sk_value(SSL_CIPHER, (st), (i)) +#define sk_SSL_CIPHER_set(st, i, val) SKM_sk_set(SSL_CIPHER, (st), (i), (val)) +#define sk_SSL_CIPHER_zero(st) SKM_sk_zero(SSL_CIPHER, (st)) +#define sk_SSL_CIPHER_push(st, val) SKM_sk_push(SSL_CIPHER, (st), (val)) +#define sk_SSL_CIPHER_unshift(st, val) SKM_sk_unshift(SSL_CIPHER, (st), (val)) +#define sk_SSL_CIPHER_find(st, val) SKM_sk_find(SSL_CIPHER, (st), (val)) +#define sk_SSL_CIPHER_find_ex(st, val) SKM_sk_find_ex(SSL_CIPHER, (st), (val)) +#define sk_SSL_CIPHER_delete(st, i) SKM_sk_delete(SSL_CIPHER, (st), (i)) +#define sk_SSL_CIPHER_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_CIPHER, (st), (ptr)) +#define sk_SSL_CIPHER_insert(st, val, i) SKM_sk_insert(SSL_CIPHER, (st), (val), (i)) +#define sk_SSL_CIPHER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_CIPHER, (st), (cmp)) +#define sk_SSL_CIPHER_dup(st) SKM_sk_dup(SSL_CIPHER, st) +#define sk_SSL_CIPHER_pop_free(st, free_func) SKM_sk_pop_free(SSL_CIPHER, (st), (free_func)) +#define sk_SSL_CIPHER_shift(st) SKM_sk_shift(SSL_CIPHER, (st)) +#define sk_SSL_CIPHER_pop(st) SKM_sk_pop(SSL_CIPHER, (st)) +#define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st)) +#define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st)) + +#define sk_SSL_COMP_new(cmp) SKM_sk_new(SSL_COMP, (cmp)) +#define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP) +#define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st)) +#define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st)) +#define sk_SSL_COMP_value(st, i) SKM_sk_value(SSL_COMP, (st), (i)) +#define sk_SSL_COMP_set(st, i, val) SKM_sk_set(SSL_COMP, (st), (i), (val)) +#define sk_SSL_COMP_zero(st) SKM_sk_zero(SSL_COMP, (st)) +#define sk_SSL_COMP_push(st, val) SKM_sk_push(SSL_COMP, (st), (val)) +#define sk_SSL_COMP_unshift(st, val) SKM_sk_unshift(SSL_COMP, (st), (val)) +#define sk_SSL_COMP_find(st, val) SKM_sk_find(SSL_COMP, (st), (val)) +#define sk_SSL_COMP_find_ex(st, val) SKM_sk_find_ex(SSL_COMP, (st), (val)) +#define sk_SSL_COMP_delete(st, i) SKM_sk_delete(SSL_COMP, (st), (i)) +#define sk_SSL_COMP_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_COMP, (st), (ptr)) +#define sk_SSL_COMP_insert(st, val, i) SKM_sk_insert(SSL_COMP, (st), (val), (i)) +#define sk_SSL_COMP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_COMP, (st), (cmp)) +#define sk_SSL_COMP_dup(st) SKM_sk_dup(SSL_COMP, st) +#define sk_SSL_COMP_pop_free(st, free_func) SKM_sk_pop_free(SSL_COMP, (st), (free_func)) +#define sk_SSL_COMP_shift(st) SKM_sk_shift(SSL_COMP, (st)) +#define sk_SSL_COMP_pop(st) SKM_sk_pop(SSL_COMP, (st)) +#define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st)) +#define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st)) + +#define sk_STACK_OF_X509_NAME_ENTRY_new(cmp) SKM_sk_new(STACK_OF_X509_NAME_ENTRY, (cmp)) +#define sk_STACK_OF_X509_NAME_ENTRY_new_null() SKM_sk_new_null(STACK_OF_X509_NAME_ENTRY) +#define sk_STACK_OF_X509_NAME_ENTRY_free(st) SKM_sk_free(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_num(st) SKM_sk_num(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_value(st, i) SKM_sk_value(STACK_OF_X509_NAME_ENTRY, (st), (i)) +#define sk_STACK_OF_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(STACK_OF_X509_NAME_ENTRY, (st), (i), (val)) +#define sk_STACK_OF_X509_NAME_ENTRY_zero(st) SKM_sk_zero(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_push(st, val) SKM_sk_push(STACK_OF_X509_NAME_ENTRY, (st), (val)) +#define sk_STACK_OF_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(STACK_OF_X509_NAME_ENTRY, (st), (val)) +#define sk_STACK_OF_X509_NAME_ENTRY_find(st, val) SKM_sk_find(STACK_OF_X509_NAME_ENTRY, (st), (val)) +#define sk_STACK_OF_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(STACK_OF_X509_NAME_ENTRY, (st), (val)) +#define sk_STACK_OF_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(STACK_OF_X509_NAME_ENTRY, (st), (i)) +#define sk_STACK_OF_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(STACK_OF_X509_NAME_ENTRY, (st), (ptr)) +#define sk_STACK_OF_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(STACK_OF_X509_NAME_ENTRY, (st), (val), (i)) +#define sk_STACK_OF_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STACK_OF_X509_NAME_ENTRY, (st), (cmp)) +#define sk_STACK_OF_X509_NAME_ENTRY_dup(st) SKM_sk_dup(STACK_OF_X509_NAME_ENTRY, st) +#define sk_STACK_OF_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(STACK_OF_X509_NAME_ENTRY, (st), (free_func)) +#define sk_STACK_OF_X509_NAME_ENTRY_shift(st) SKM_sk_shift(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_pop(st) SKM_sk_pop(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_sort(st) SKM_sk_sort(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(STACK_OF_X509_NAME_ENTRY, (st)) + +#define sk_STORE_ATTR_INFO_new(cmp) SKM_sk_new(STORE_ATTR_INFO, (cmp)) +#define sk_STORE_ATTR_INFO_new_null() SKM_sk_new_null(STORE_ATTR_INFO) +#define sk_STORE_ATTR_INFO_free(st) SKM_sk_free(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_num(st) SKM_sk_num(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_value(st, i) SKM_sk_value(STORE_ATTR_INFO, (st), (i)) +#define sk_STORE_ATTR_INFO_set(st, i, val) SKM_sk_set(STORE_ATTR_INFO, (st), (i), (val)) +#define sk_STORE_ATTR_INFO_zero(st) SKM_sk_zero(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_push(st, val) SKM_sk_push(STORE_ATTR_INFO, (st), (val)) +#define sk_STORE_ATTR_INFO_unshift(st, val) SKM_sk_unshift(STORE_ATTR_INFO, (st), (val)) +#define sk_STORE_ATTR_INFO_find(st, val) SKM_sk_find(STORE_ATTR_INFO, (st), (val)) +#define sk_STORE_ATTR_INFO_find_ex(st, val) SKM_sk_find_ex(STORE_ATTR_INFO, (st), (val)) +#define sk_STORE_ATTR_INFO_delete(st, i) SKM_sk_delete(STORE_ATTR_INFO, (st), (i)) +#define sk_STORE_ATTR_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_ATTR_INFO, (st), (ptr)) +#define sk_STORE_ATTR_INFO_insert(st, val, i) SKM_sk_insert(STORE_ATTR_INFO, (st), (val), (i)) +#define sk_STORE_ATTR_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_ATTR_INFO, (st), (cmp)) +#define sk_STORE_ATTR_INFO_dup(st) SKM_sk_dup(STORE_ATTR_INFO, st) +#define sk_STORE_ATTR_INFO_pop_free(st, free_func) SKM_sk_pop_free(STORE_ATTR_INFO, (st), (free_func)) +#define sk_STORE_ATTR_INFO_shift(st) SKM_sk_shift(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_pop(st) SKM_sk_pop(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_sort(st) SKM_sk_sort(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_is_sorted(st) SKM_sk_is_sorted(STORE_ATTR_INFO, (st)) + +#define sk_STORE_OBJECT_new(cmp) SKM_sk_new(STORE_OBJECT, (cmp)) +#define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT) +#define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st)) +#define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st)) +#define sk_STORE_OBJECT_value(st, i) SKM_sk_value(STORE_OBJECT, (st), (i)) +#define sk_STORE_OBJECT_set(st, i, val) SKM_sk_set(STORE_OBJECT, (st), (i), (val)) +#define sk_STORE_OBJECT_zero(st) SKM_sk_zero(STORE_OBJECT, (st)) +#define sk_STORE_OBJECT_push(st, val) SKM_sk_push(STORE_OBJECT, (st), (val)) +#define sk_STORE_OBJECT_unshift(st, val) SKM_sk_unshift(STORE_OBJECT, (st), (val)) +#define sk_STORE_OBJECT_find(st, val) SKM_sk_find(STORE_OBJECT, (st), (val)) +#define sk_STORE_OBJECT_find_ex(st, val) SKM_sk_find_ex(STORE_OBJECT, (st), (val)) +#define sk_STORE_OBJECT_delete(st, i) SKM_sk_delete(STORE_OBJECT, (st), (i)) +#define sk_STORE_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_OBJECT, (st), (ptr)) +#define sk_STORE_OBJECT_insert(st, val, i) SKM_sk_insert(STORE_OBJECT, (st), (val), (i)) +#define sk_STORE_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_OBJECT, (st), (cmp)) +#define sk_STORE_OBJECT_dup(st) SKM_sk_dup(STORE_OBJECT, st) +#define sk_STORE_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(STORE_OBJECT, (st), (free_func)) +#define sk_STORE_OBJECT_shift(st) SKM_sk_shift(STORE_OBJECT, (st)) +#define sk_STORE_OBJECT_pop(st) SKM_sk_pop(STORE_OBJECT, (st)) +#define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st)) +#define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st)) + +#define sk_SXNETID_new(cmp) SKM_sk_new(SXNETID, (cmp)) +#define sk_SXNETID_new_null() SKM_sk_new_null(SXNETID) +#define sk_SXNETID_free(st) SKM_sk_free(SXNETID, (st)) +#define sk_SXNETID_num(st) SKM_sk_num(SXNETID, (st)) +#define sk_SXNETID_value(st, i) SKM_sk_value(SXNETID, (st), (i)) +#define sk_SXNETID_set(st, i, val) SKM_sk_set(SXNETID, (st), (i), (val)) +#define sk_SXNETID_zero(st) SKM_sk_zero(SXNETID, (st)) +#define sk_SXNETID_push(st, val) SKM_sk_push(SXNETID, (st), (val)) +#define sk_SXNETID_unshift(st, val) SKM_sk_unshift(SXNETID, (st), (val)) +#define sk_SXNETID_find(st, val) SKM_sk_find(SXNETID, (st), (val)) +#define sk_SXNETID_find_ex(st, val) SKM_sk_find_ex(SXNETID, (st), (val)) +#define sk_SXNETID_delete(st, i) SKM_sk_delete(SXNETID, (st), (i)) +#define sk_SXNETID_delete_ptr(st, ptr) SKM_sk_delete_ptr(SXNETID, (st), (ptr)) +#define sk_SXNETID_insert(st, val, i) SKM_sk_insert(SXNETID, (st), (val), (i)) +#define sk_SXNETID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SXNETID, (st), (cmp)) +#define sk_SXNETID_dup(st) SKM_sk_dup(SXNETID, st) +#define sk_SXNETID_pop_free(st, free_func) SKM_sk_pop_free(SXNETID, (st), (free_func)) +#define sk_SXNETID_shift(st) SKM_sk_shift(SXNETID, (st)) +#define sk_SXNETID_pop(st) SKM_sk_pop(SXNETID, (st)) +#define sk_SXNETID_sort(st) SKM_sk_sort(SXNETID, (st)) +#define sk_SXNETID_is_sorted(st) SKM_sk_is_sorted(SXNETID, (st)) + +#define sk_UI_STRING_new(cmp) SKM_sk_new(UI_STRING, (cmp)) +#define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING) +#define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st)) +#define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st)) +#define sk_UI_STRING_value(st, i) SKM_sk_value(UI_STRING, (st), (i)) +#define sk_UI_STRING_set(st, i, val) SKM_sk_set(UI_STRING, (st), (i), (val)) +#define sk_UI_STRING_zero(st) SKM_sk_zero(UI_STRING, (st)) +#define sk_UI_STRING_push(st, val) SKM_sk_push(UI_STRING, (st), (val)) +#define sk_UI_STRING_unshift(st, val) SKM_sk_unshift(UI_STRING, (st), (val)) +#define sk_UI_STRING_find(st, val) SKM_sk_find(UI_STRING, (st), (val)) +#define sk_UI_STRING_find_ex(st, val) SKM_sk_find_ex(UI_STRING, (st), (val)) +#define sk_UI_STRING_delete(st, i) SKM_sk_delete(UI_STRING, (st), (i)) +#define sk_UI_STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(UI_STRING, (st), (ptr)) +#define sk_UI_STRING_insert(st, val, i) SKM_sk_insert(UI_STRING, (st), (val), (i)) +#define sk_UI_STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(UI_STRING, (st), (cmp)) +#define sk_UI_STRING_dup(st) SKM_sk_dup(UI_STRING, st) +#define sk_UI_STRING_pop_free(st, free_func) SKM_sk_pop_free(UI_STRING, (st), (free_func)) +#define sk_UI_STRING_shift(st) SKM_sk_shift(UI_STRING, (st)) +#define sk_UI_STRING_pop(st) SKM_sk_pop(UI_STRING, (st)) +#define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st)) +#define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st)) + +#define sk_X509_new(cmp) SKM_sk_new(X509, (cmp)) +#define sk_X509_new_null() SKM_sk_new_null(X509) +#define sk_X509_free(st) SKM_sk_free(X509, (st)) +#define sk_X509_num(st) SKM_sk_num(X509, (st)) +#define sk_X509_value(st, i) SKM_sk_value(X509, (st), (i)) +#define sk_X509_set(st, i, val) SKM_sk_set(X509, (st), (i), (val)) +#define sk_X509_zero(st) SKM_sk_zero(X509, (st)) +#define sk_X509_push(st, val) SKM_sk_push(X509, (st), (val)) +#define sk_X509_unshift(st, val) SKM_sk_unshift(X509, (st), (val)) +#define sk_X509_find(st, val) SKM_sk_find(X509, (st), (val)) +#define sk_X509_find_ex(st, val) SKM_sk_find_ex(X509, (st), (val)) +#define sk_X509_delete(st, i) SKM_sk_delete(X509, (st), (i)) +#define sk_X509_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509, (st), (ptr)) +#define sk_X509_insert(st, val, i) SKM_sk_insert(X509, (st), (val), (i)) +#define sk_X509_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509, (st), (cmp)) +#define sk_X509_dup(st) SKM_sk_dup(X509, st) +#define sk_X509_pop_free(st, free_func) SKM_sk_pop_free(X509, (st), (free_func)) +#define sk_X509_shift(st) SKM_sk_shift(X509, (st)) +#define sk_X509_pop(st) SKM_sk_pop(X509, (st)) +#define sk_X509_sort(st) SKM_sk_sort(X509, (st)) +#define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st)) + +#define sk_X509V3_EXT_METHOD_new(cmp) SKM_sk_new(X509V3_EXT_METHOD, (cmp)) +#define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD) +#define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st)) +#define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st)) +#define sk_X509V3_EXT_METHOD_value(st, i) SKM_sk_value(X509V3_EXT_METHOD, (st), (i)) +#define sk_X509V3_EXT_METHOD_set(st, i, val) SKM_sk_set(X509V3_EXT_METHOD, (st), (i), (val)) +#define sk_X509V3_EXT_METHOD_zero(st) SKM_sk_zero(X509V3_EXT_METHOD, (st)) +#define sk_X509V3_EXT_METHOD_push(st, val) SKM_sk_push(X509V3_EXT_METHOD, (st), (val)) +#define sk_X509V3_EXT_METHOD_unshift(st, val) SKM_sk_unshift(X509V3_EXT_METHOD, (st), (val)) +#define sk_X509V3_EXT_METHOD_find(st, val) SKM_sk_find(X509V3_EXT_METHOD, (st), (val)) +#define sk_X509V3_EXT_METHOD_find_ex(st, val) SKM_sk_find_ex(X509V3_EXT_METHOD, (st), (val)) +#define sk_X509V3_EXT_METHOD_delete(st, i) SKM_sk_delete(X509V3_EXT_METHOD, (st), (i)) +#define sk_X509V3_EXT_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509V3_EXT_METHOD, (st), (ptr)) +#define sk_X509V3_EXT_METHOD_insert(st, val, i) SKM_sk_insert(X509V3_EXT_METHOD, (st), (val), (i)) +#define sk_X509V3_EXT_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509V3_EXT_METHOD, (st), (cmp)) +#define sk_X509V3_EXT_METHOD_dup(st) SKM_sk_dup(X509V3_EXT_METHOD, st) +#define sk_X509V3_EXT_METHOD_pop_free(st, free_func) SKM_sk_pop_free(X509V3_EXT_METHOD, (st), (free_func)) +#define sk_X509V3_EXT_METHOD_shift(st) SKM_sk_shift(X509V3_EXT_METHOD, (st)) +#define sk_X509V3_EXT_METHOD_pop(st) SKM_sk_pop(X509V3_EXT_METHOD, (st)) +#define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st)) +#define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st)) + +#define sk_X509_ALGOR_new(cmp) SKM_sk_new(X509_ALGOR, (cmp)) +#define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR) +#define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st)) +#define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st)) +#define sk_X509_ALGOR_value(st, i) SKM_sk_value(X509_ALGOR, (st), (i)) +#define sk_X509_ALGOR_set(st, i, val) SKM_sk_set(X509_ALGOR, (st), (i), (val)) +#define sk_X509_ALGOR_zero(st) SKM_sk_zero(X509_ALGOR, (st)) +#define sk_X509_ALGOR_push(st, val) SKM_sk_push(X509_ALGOR, (st), (val)) +#define sk_X509_ALGOR_unshift(st, val) SKM_sk_unshift(X509_ALGOR, (st), (val)) +#define sk_X509_ALGOR_find(st, val) SKM_sk_find(X509_ALGOR, (st), (val)) +#define sk_X509_ALGOR_find_ex(st, val) SKM_sk_find_ex(X509_ALGOR, (st), (val)) +#define sk_X509_ALGOR_delete(st, i) SKM_sk_delete(X509_ALGOR, (st), (i)) +#define sk_X509_ALGOR_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ALGOR, (st), (ptr)) +#define sk_X509_ALGOR_insert(st, val, i) SKM_sk_insert(X509_ALGOR, (st), (val), (i)) +#define sk_X509_ALGOR_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ALGOR, (st), (cmp)) +#define sk_X509_ALGOR_dup(st) SKM_sk_dup(X509_ALGOR, st) +#define sk_X509_ALGOR_pop_free(st, free_func) SKM_sk_pop_free(X509_ALGOR, (st), (free_func)) +#define sk_X509_ALGOR_shift(st) SKM_sk_shift(X509_ALGOR, (st)) +#define sk_X509_ALGOR_pop(st) SKM_sk_pop(X509_ALGOR, (st)) +#define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st)) +#define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st)) + +#define sk_X509_ATTRIBUTE_new(cmp) SKM_sk_new(X509_ATTRIBUTE, (cmp)) +#define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE) +#define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st)) +#define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st)) +#define sk_X509_ATTRIBUTE_value(st, i) SKM_sk_value(X509_ATTRIBUTE, (st), (i)) +#define sk_X509_ATTRIBUTE_set(st, i, val) SKM_sk_set(X509_ATTRIBUTE, (st), (i), (val)) +#define sk_X509_ATTRIBUTE_zero(st) SKM_sk_zero(X509_ATTRIBUTE, (st)) +#define sk_X509_ATTRIBUTE_push(st, val) SKM_sk_push(X509_ATTRIBUTE, (st), (val)) +#define sk_X509_ATTRIBUTE_unshift(st, val) SKM_sk_unshift(X509_ATTRIBUTE, (st), (val)) +#define sk_X509_ATTRIBUTE_find(st, val) SKM_sk_find(X509_ATTRIBUTE, (st), (val)) +#define sk_X509_ATTRIBUTE_find_ex(st, val) SKM_sk_find_ex(X509_ATTRIBUTE, (st), (val)) +#define sk_X509_ATTRIBUTE_delete(st, i) SKM_sk_delete(X509_ATTRIBUTE, (st), (i)) +#define sk_X509_ATTRIBUTE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ATTRIBUTE, (st), (ptr)) +#define sk_X509_ATTRIBUTE_insert(st, val, i) SKM_sk_insert(X509_ATTRIBUTE, (st), (val), (i)) +#define sk_X509_ATTRIBUTE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ATTRIBUTE, (st), (cmp)) +#define sk_X509_ATTRIBUTE_dup(st) SKM_sk_dup(X509_ATTRIBUTE, st) +#define sk_X509_ATTRIBUTE_pop_free(st, free_func) SKM_sk_pop_free(X509_ATTRIBUTE, (st), (free_func)) +#define sk_X509_ATTRIBUTE_shift(st) SKM_sk_shift(X509_ATTRIBUTE, (st)) +#define sk_X509_ATTRIBUTE_pop(st) SKM_sk_pop(X509_ATTRIBUTE, (st)) +#define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st)) +#define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st)) + +#define sk_X509_CRL_new(cmp) SKM_sk_new(X509_CRL, (cmp)) +#define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL) +#define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st)) +#define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st)) +#define sk_X509_CRL_value(st, i) SKM_sk_value(X509_CRL, (st), (i)) +#define sk_X509_CRL_set(st, i, val) SKM_sk_set(X509_CRL, (st), (i), (val)) +#define sk_X509_CRL_zero(st) SKM_sk_zero(X509_CRL, (st)) +#define sk_X509_CRL_push(st, val) SKM_sk_push(X509_CRL, (st), (val)) +#define sk_X509_CRL_unshift(st, val) SKM_sk_unshift(X509_CRL, (st), (val)) +#define sk_X509_CRL_find(st, val) SKM_sk_find(X509_CRL, (st), (val)) +#define sk_X509_CRL_find_ex(st, val) SKM_sk_find_ex(X509_CRL, (st), (val)) +#define sk_X509_CRL_delete(st, i) SKM_sk_delete(X509_CRL, (st), (i)) +#define sk_X509_CRL_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_CRL, (st), (ptr)) +#define sk_X509_CRL_insert(st, val, i) SKM_sk_insert(X509_CRL, (st), (val), (i)) +#define sk_X509_CRL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_CRL, (st), (cmp)) +#define sk_X509_CRL_dup(st) SKM_sk_dup(X509_CRL, st) +#define sk_X509_CRL_pop_free(st, free_func) SKM_sk_pop_free(X509_CRL, (st), (free_func)) +#define sk_X509_CRL_shift(st) SKM_sk_shift(X509_CRL, (st)) +#define sk_X509_CRL_pop(st) SKM_sk_pop(X509_CRL, (st)) +#define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st)) +#define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st)) + +#define sk_X509_EXTENSION_new(cmp) SKM_sk_new(X509_EXTENSION, (cmp)) +#define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION) +#define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st)) +#define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st)) +#define sk_X509_EXTENSION_value(st, i) SKM_sk_value(X509_EXTENSION, (st), (i)) +#define sk_X509_EXTENSION_set(st, i, val) SKM_sk_set(X509_EXTENSION, (st), (i), (val)) +#define sk_X509_EXTENSION_zero(st) SKM_sk_zero(X509_EXTENSION, (st)) +#define sk_X509_EXTENSION_push(st, val) SKM_sk_push(X509_EXTENSION, (st), (val)) +#define sk_X509_EXTENSION_unshift(st, val) SKM_sk_unshift(X509_EXTENSION, (st), (val)) +#define sk_X509_EXTENSION_find(st, val) SKM_sk_find(X509_EXTENSION, (st), (val)) +#define sk_X509_EXTENSION_find_ex(st, val) SKM_sk_find_ex(X509_EXTENSION, (st), (val)) +#define sk_X509_EXTENSION_delete(st, i) SKM_sk_delete(X509_EXTENSION, (st), (i)) +#define sk_X509_EXTENSION_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_EXTENSION, (st), (ptr)) +#define sk_X509_EXTENSION_insert(st, val, i) SKM_sk_insert(X509_EXTENSION, (st), (val), (i)) +#define sk_X509_EXTENSION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_EXTENSION, (st), (cmp)) +#define sk_X509_EXTENSION_dup(st) SKM_sk_dup(X509_EXTENSION, st) +#define sk_X509_EXTENSION_pop_free(st, free_func) SKM_sk_pop_free(X509_EXTENSION, (st), (free_func)) +#define sk_X509_EXTENSION_shift(st) SKM_sk_shift(X509_EXTENSION, (st)) +#define sk_X509_EXTENSION_pop(st) SKM_sk_pop(X509_EXTENSION, (st)) +#define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st)) +#define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st)) + +#define sk_X509_INFO_new(cmp) SKM_sk_new(X509_INFO, (cmp)) +#define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO) +#define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st)) +#define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st)) +#define sk_X509_INFO_value(st, i) SKM_sk_value(X509_INFO, (st), (i)) +#define sk_X509_INFO_set(st, i, val) SKM_sk_set(X509_INFO, (st), (i), (val)) +#define sk_X509_INFO_zero(st) SKM_sk_zero(X509_INFO, (st)) +#define sk_X509_INFO_push(st, val) SKM_sk_push(X509_INFO, (st), (val)) +#define sk_X509_INFO_unshift(st, val) SKM_sk_unshift(X509_INFO, (st), (val)) +#define sk_X509_INFO_find(st, val) SKM_sk_find(X509_INFO, (st), (val)) +#define sk_X509_INFO_find_ex(st, val) SKM_sk_find_ex(X509_INFO, (st), (val)) +#define sk_X509_INFO_delete(st, i) SKM_sk_delete(X509_INFO, (st), (i)) +#define sk_X509_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_INFO, (st), (ptr)) +#define sk_X509_INFO_insert(st, val, i) SKM_sk_insert(X509_INFO, (st), (val), (i)) +#define sk_X509_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_INFO, (st), (cmp)) +#define sk_X509_INFO_dup(st) SKM_sk_dup(X509_INFO, st) +#define sk_X509_INFO_pop_free(st, free_func) SKM_sk_pop_free(X509_INFO, (st), (free_func)) +#define sk_X509_INFO_shift(st) SKM_sk_shift(X509_INFO, (st)) +#define sk_X509_INFO_pop(st) SKM_sk_pop(X509_INFO, (st)) +#define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st)) +#define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st)) + +#define sk_X509_LOOKUP_new(cmp) SKM_sk_new(X509_LOOKUP, (cmp)) +#define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP) +#define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st)) +#define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st)) +#define sk_X509_LOOKUP_value(st, i) SKM_sk_value(X509_LOOKUP, (st), (i)) +#define sk_X509_LOOKUP_set(st, i, val) SKM_sk_set(X509_LOOKUP, (st), (i), (val)) +#define sk_X509_LOOKUP_zero(st) SKM_sk_zero(X509_LOOKUP, (st)) +#define sk_X509_LOOKUP_push(st, val) SKM_sk_push(X509_LOOKUP, (st), (val)) +#define sk_X509_LOOKUP_unshift(st, val) SKM_sk_unshift(X509_LOOKUP, (st), (val)) +#define sk_X509_LOOKUP_find(st, val) SKM_sk_find(X509_LOOKUP, (st), (val)) +#define sk_X509_LOOKUP_find_ex(st, val) SKM_sk_find_ex(X509_LOOKUP, (st), (val)) +#define sk_X509_LOOKUP_delete(st, i) SKM_sk_delete(X509_LOOKUP, (st), (i)) +#define sk_X509_LOOKUP_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_LOOKUP, (st), (ptr)) +#define sk_X509_LOOKUP_insert(st, val, i) SKM_sk_insert(X509_LOOKUP, (st), (val), (i)) +#define sk_X509_LOOKUP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_LOOKUP, (st), (cmp)) +#define sk_X509_LOOKUP_dup(st) SKM_sk_dup(X509_LOOKUP, st) +#define sk_X509_LOOKUP_pop_free(st, free_func) SKM_sk_pop_free(X509_LOOKUP, (st), (free_func)) +#define sk_X509_LOOKUP_shift(st) SKM_sk_shift(X509_LOOKUP, (st)) +#define sk_X509_LOOKUP_pop(st) SKM_sk_pop(X509_LOOKUP, (st)) +#define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st)) +#define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st)) + +#define sk_X509_NAME_new(cmp) SKM_sk_new(X509_NAME, (cmp)) +#define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME) +#define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st)) +#define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st)) +#define sk_X509_NAME_value(st, i) SKM_sk_value(X509_NAME, (st), (i)) +#define sk_X509_NAME_set(st, i, val) SKM_sk_set(X509_NAME, (st), (i), (val)) +#define sk_X509_NAME_zero(st) SKM_sk_zero(X509_NAME, (st)) +#define sk_X509_NAME_push(st, val) SKM_sk_push(X509_NAME, (st), (val)) +#define sk_X509_NAME_unshift(st, val) SKM_sk_unshift(X509_NAME, (st), (val)) +#define sk_X509_NAME_find(st, val) SKM_sk_find(X509_NAME, (st), (val)) +#define sk_X509_NAME_find_ex(st, val) SKM_sk_find_ex(X509_NAME, (st), (val)) +#define sk_X509_NAME_delete(st, i) SKM_sk_delete(X509_NAME, (st), (i)) +#define sk_X509_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME, (st), (ptr)) +#define sk_X509_NAME_insert(st, val, i) SKM_sk_insert(X509_NAME, (st), (val), (i)) +#define sk_X509_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME, (st), (cmp)) +#define sk_X509_NAME_dup(st) SKM_sk_dup(X509_NAME, st) +#define sk_X509_NAME_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME, (st), (free_func)) +#define sk_X509_NAME_shift(st) SKM_sk_shift(X509_NAME, (st)) +#define sk_X509_NAME_pop(st) SKM_sk_pop(X509_NAME, (st)) +#define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st)) +#define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st)) + +#define sk_X509_NAME_ENTRY_new(cmp) SKM_sk_new(X509_NAME_ENTRY, (cmp)) +#define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY) +#define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st)) +#define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st)) +#define sk_X509_NAME_ENTRY_value(st, i) SKM_sk_value(X509_NAME_ENTRY, (st), (i)) +#define sk_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(X509_NAME_ENTRY, (st), (i), (val)) +#define sk_X509_NAME_ENTRY_zero(st) SKM_sk_zero(X509_NAME_ENTRY, (st)) +#define sk_X509_NAME_ENTRY_push(st, val) SKM_sk_push(X509_NAME_ENTRY, (st), (val)) +#define sk_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(X509_NAME_ENTRY, (st), (val)) +#define sk_X509_NAME_ENTRY_find(st, val) SKM_sk_find(X509_NAME_ENTRY, (st), (val)) +#define sk_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(X509_NAME_ENTRY, (st), (val)) +#define sk_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(X509_NAME_ENTRY, (st), (i)) +#define sk_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME_ENTRY, (st), (ptr)) +#define sk_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(X509_NAME_ENTRY, (st), (val), (i)) +#define sk_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME_ENTRY, (st), (cmp)) +#define sk_X509_NAME_ENTRY_dup(st) SKM_sk_dup(X509_NAME_ENTRY, st) +#define sk_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME_ENTRY, (st), (free_func)) +#define sk_X509_NAME_ENTRY_shift(st) SKM_sk_shift(X509_NAME_ENTRY, (st)) +#define sk_X509_NAME_ENTRY_pop(st) SKM_sk_pop(X509_NAME_ENTRY, (st)) +#define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st)) +#define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st)) + +#define sk_X509_OBJECT_new(cmp) SKM_sk_new(X509_OBJECT, (cmp)) +#define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT) +#define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st)) +#define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st)) +#define sk_X509_OBJECT_value(st, i) SKM_sk_value(X509_OBJECT, (st), (i)) +#define sk_X509_OBJECT_set(st, i, val) SKM_sk_set(X509_OBJECT, (st), (i), (val)) +#define sk_X509_OBJECT_zero(st) SKM_sk_zero(X509_OBJECT, (st)) +#define sk_X509_OBJECT_push(st, val) SKM_sk_push(X509_OBJECT, (st), (val)) +#define sk_X509_OBJECT_unshift(st, val) SKM_sk_unshift(X509_OBJECT, (st), (val)) +#define sk_X509_OBJECT_find(st, val) SKM_sk_find(X509_OBJECT, (st), (val)) +#define sk_X509_OBJECT_find_ex(st, val) SKM_sk_find_ex(X509_OBJECT, (st), (val)) +#define sk_X509_OBJECT_delete(st, i) SKM_sk_delete(X509_OBJECT, (st), (i)) +#define sk_X509_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_OBJECT, (st), (ptr)) +#define sk_X509_OBJECT_insert(st, val, i) SKM_sk_insert(X509_OBJECT, (st), (val), (i)) +#define sk_X509_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_OBJECT, (st), (cmp)) +#define sk_X509_OBJECT_dup(st) SKM_sk_dup(X509_OBJECT, st) +#define sk_X509_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(X509_OBJECT, (st), (free_func)) +#define sk_X509_OBJECT_shift(st) SKM_sk_shift(X509_OBJECT, (st)) +#define sk_X509_OBJECT_pop(st) SKM_sk_pop(X509_OBJECT, (st)) +#define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st)) +#define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st)) + +#define sk_X509_POLICY_DATA_new(cmp) SKM_sk_new(X509_POLICY_DATA, (cmp)) +#define sk_X509_POLICY_DATA_new_null() SKM_sk_new_null(X509_POLICY_DATA) +#define sk_X509_POLICY_DATA_free(st) SKM_sk_free(X509_POLICY_DATA, (st)) +#define sk_X509_POLICY_DATA_num(st) SKM_sk_num(X509_POLICY_DATA, (st)) +#define sk_X509_POLICY_DATA_value(st, i) SKM_sk_value(X509_POLICY_DATA, (st), (i)) +#define sk_X509_POLICY_DATA_set(st, i, val) SKM_sk_set(X509_POLICY_DATA, (st), (i), (val)) +#define sk_X509_POLICY_DATA_zero(st) SKM_sk_zero(X509_POLICY_DATA, (st)) +#define sk_X509_POLICY_DATA_push(st, val) SKM_sk_push(X509_POLICY_DATA, (st), (val)) +#define sk_X509_POLICY_DATA_unshift(st, val) SKM_sk_unshift(X509_POLICY_DATA, (st), (val)) +#define sk_X509_POLICY_DATA_find(st, val) SKM_sk_find(X509_POLICY_DATA, (st), (val)) +#define sk_X509_POLICY_DATA_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_DATA, (st), (val)) +#define sk_X509_POLICY_DATA_delete(st, i) SKM_sk_delete(X509_POLICY_DATA, (st), (i)) +#define sk_X509_POLICY_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_DATA, (st), (ptr)) +#define sk_X509_POLICY_DATA_insert(st, val, i) SKM_sk_insert(X509_POLICY_DATA, (st), (val), (i)) +#define sk_X509_POLICY_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_DATA, (st), (cmp)) +#define sk_X509_POLICY_DATA_dup(st) SKM_sk_dup(X509_POLICY_DATA, st) +#define sk_X509_POLICY_DATA_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_DATA, (st), (free_func)) +#define sk_X509_POLICY_DATA_shift(st) SKM_sk_shift(X509_POLICY_DATA, (st)) +#define sk_X509_POLICY_DATA_pop(st) SKM_sk_pop(X509_POLICY_DATA, (st)) +#define sk_X509_POLICY_DATA_sort(st) SKM_sk_sort(X509_POLICY_DATA, (st)) +#define sk_X509_POLICY_DATA_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_DATA, (st)) + +#define sk_X509_POLICY_NODE_new(cmp) SKM_sk_new(X509_POLICY_NODE, (cmp)) +#define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE) +#define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st)) +#define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st)) +#define sk_X509_POLICY_NODE_value(st, i) SKM_sk_value(X509_POLICY_NODE, (st), (i)) +#define sk_X509_POLICY_NODE_set(st, i, val) SKM_sk_set(X509_POLICY_NODE, (st), (i), (val)) +#define sk_X509_POLICY_NODE_zero(st) SKM_sk_zero(X509_POLICY_NODE, (st)) +#define sk_X509_POLICY_NODE_push(st, val) SKM_sk_push(X509_POLICY_NODE, (st), (val)) +#define sk_X509_POLICY_NODE_unshift(st, val) SKM_sk_unshift(X509_POLICY_NODE, (st), (val)) +#define sk_X509_POLICY_NODE_find(st, val) SKM_sk_find(X509_POLICY_NODE, (st), (val)) +#define sk_X509_POLICY_NODE_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_NODE, (st), (val)) +#define sk_X509_POLICY_NODE_delete(st, i) SKM_sk_delete(X509_POLICY_NODE, (st), (i)) +#define sk_X509_POLICY_NODE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_NODE, (st), (ptr)) +#define sk_X509_POLICY_NODE_insert(st, val, i) SKM_sk_insert(X509_POLICY_NODE, (st), (val), (i)) +#define sk_X509_POLICY_NODE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_NODE, (st), (cmp)) +#define sk_X509_POLICY_NODE_dup(st) SKM_sk_dup(X509_POLICY_NODE, st) +#define sk_X509_POLICY_NODE_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_NODE, (st), (free_func)) +#define sk_X509_POLICY_NODE_shift(st) SKM_sk_shift(X509_POLICY_NODE, (st)) +#define sk_X509_POLICY_NODE_pop(st) SKM_sk_pop(X509_POLICY_NODE, (st)) +#define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st)) +#define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st)) + +#define sk_X509_PURPOSE_new(cmp) SKM_sk_new(X509_PURPOSE, (cmp)) +#define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE) +#define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st)) +#define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st)) +#define sk_X509_PURPOSE_value(st, i) SKM_sk_value(X509_PURPOSE, (st), (i)) +#define sk_X509_PURPOSE_set(st, i, val) SKM_sk_set(X509_PURPOSE, (st), (i), (val)) +#define sk_X509_PURPOSE_zero(st) SKM_sk_zero(X509_PURPOSE, (st)) +#define sk_X509_PURPOSE_push(st, val) SKM_sk_push(X509_PURPOSE, (st), (val)) +#define sk_X509_PURPOSE_unshift(st, val) SKM_sk_unshift(X509_PURPOSE, (st), (val)) +#define sk_X509_PURPOSE_find(st, val) SKM_sk_find(X509_PURPOSE, (st), (val)) +#define sk_X509_PURPOSE_find_ex(st, val) SKM_sk_find_ex(X509_PURPOSE, (st), (val)) +#define sk_X509_PURPOSE_delete(st, i) SKM_sk_delete(X509_PURPOSE, (st), (i)) +#define sk_X509_PURPOSE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_PURPOSE, (st), (ptr)) +#define sk_X509_PURPOSE_insert(st, val, i) SKM_sk_insert(X509_PURPOSE, (st), (val), (i)) +#define sk_X509_PURPOSE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_PURPOSE, (st), (cmp)) +#define sk_X509_PURPOSE_dup(st) SKM_sk_dup(X509_PURPOSE, st) +#define sk_X509_PURPOSE_pop_free(st, free_func) SKM_sk_pop_free(X509_PURPOSE, (st), (free_func)) +#define sk_X509_PURPOSE_shift(st) SKM_sk_shift(X509_PURPOSE, (st)) +#define sk_X509_PURPOSE_pop(st) SKM_sk_pop(X509_PURPOSE, (st)) +#define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st)) +#define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st)) + +#define sk_X509_REVOKED_new(cmp) SKM_sk_new(X509_REVOKED, (cmp)) +#define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED) +#define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st)) +#define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st)) +#define sk_X509_REVOKED_value(st, i) SKM_sk_value(X509_REVOKED, (st), (i)) +#define sk_X509_REVOKED_set(st, i, val) SKM_sk_set(X509_REVOKED, (st), (i), (val)) +#define sk_X509_REVOKED_zero(st) SKM_sk_zero(X509_REVOKED, (st)) +#define sk_X509_REVOKED_push(st, val) SKM_sk_push(X509_REVOKED, (st), (val)) +#define sk_X509_REVOKED_unshift(st, val) SKM_sk_unshift(X509_REVOKED, (st), (val)) +#define sk_X509_REVOKED_find(st, val) SKM_sk_find(X509_REVOKED, (st), (val)) +#define sk_X509_REVOKED_find_ex(st, val) SKM_sk_find_ex(X509_REVOKED, (st), (val)) +#define sk_X509_REVOKED_delete(st, i) SKM_sk_delete(X509_REVOKED, (st), (i)) +#define sk_X509_REVOKED_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_REVOKED, (st), (ptr)) +#define sk_X509_REVOKED_insert(st, val, i) SKM_sk_insert(X509_REVOKED, (st), (val), (i)) +#define sk_X509_REVOKED_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_REVOKED, (st), (cmp)) +#define sk_X509_REVOKED_dup(st) SKM_sk_dup(X509_REVOKED, st) +#define sk_X509_REVOKED_pop_free(st, free_func) SKM_sk_pop_free(X509_REVOKED, (st), (free_func)) +#define sk_X509_REVOKED_shift(st) SKM_sk_shift(X509_REVOKED, (st)) +#define sk_X509_REVOKED_pop(st) SKM_sk_pop(X509_REVOKED, (st)) +#define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st)) +#define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st)) + +#define sk_X509_TRUST_new(cmp) SKM_sk_new(X509_TRUST, (cmp)) +#define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST) +#define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st)) +#define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st)) +#define sk_X509_TRUST_value(st, i) SKM_sk_value(X509_TRUST, (st), (i)) +#define sk_X509_TRUST_set(st, i, val) SKM_sk_set(X509_TRUST, (st), (i), (val)) +#define sk_X509_TRUST_zero(st) SKM_sk_zero(X509_TRUST, (st)) +#define sk_X509_TRUST_push(st, val) SKM_sk_push(X509_TRUST, (st), (val)) +#define sk_X509_TRUST_unshift(st, val) SKM_sk_unshift(X509_TRUST, (st), (val)) +#define sk_X509_TRUST_find(st, val) SKM_sk_find(X509_TRUST, (st), (val)) +#define sk_X509_TRUST_find_ex(st, val) SKM_sk_find_ex(X509_TRUST, (st), (val)) +#define sk_X509_TRUST_delete(st, i) SKM_sk_delete(X509_TRUST, (st), (i)) +#define sk_X509_TRUST_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_TRUST, (st), (ptr)) +#define sk_X509_TRUST_insert(st, val, i) SKM_sk_insert(X509_TRUST, (st), (val), (i)) +#define sk_X509_TRUST_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_TRUST, (st), (cmp)) +#define sk_X509_TRUST_dup(st) SKM_sk_dup(X509_TRUST, st) +#define sk_X509_TRUST_pop_free(st, free_func) SKM_sk_pop_free(X509_TRUST, (st), (free_func)) +#define sk_X509_TRUST_shift(st) SKM_sk_shift(X509_TRUST, (st)) +#define sk_X509_TRUST_pop(st) SKM_sk_pop(X509_TRUST, (st)) +#define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st)) +#define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st)) + +#define sk_X509_VERIFY_PARAM_new(cmp) SKM_sk_new(X509_VERIFY_PARAM, (cmp)) +#define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM) +#define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st)) +#define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st)) +#define sk_X509_VERIFY_PARAM_value(st, i) SKM_sk_value(X509_VERIFY_PARAM, (st), (i)) +#define sk_X509_VERIFY_PARAM_set(st, i, val) SKM_sk_set(X509_VERIFY_PARAM, (st), (i), (val)) +#define sk_X509_VERIFY_PARAM_zero(st) SKM_sk_zero(X509_VERIFY_PARAM, (st)) +#define sk_X509_VERIFY_PARAM_push(st, val) SKM_sk_push(X509_VERIFY_PARAM, (st), (val)) +#define sk_X509_VERIFY_PARAM_unshift(st, val) SKM_sk_unshift(X509_VERIFY_PARAM, (st), (val)) +#define sk_X509_VERIFY_PARAM_find(st, val) SKM_sk_find(X509_VERIFY_PARAM, (st), (val)) +#define sk_X509_VERIFY_PARAM_find_ex(st, val) SKM_sk_find_ex(X509_VERIFY_PARAM, (st), (val)) +#define sk_X509_VERIFY_PARAM_delete(st, i) SKM_sk_delete(X509_VERIFY_PARAM, (st), (i)) +#define sk_X509_VERIFY_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_VERIFY_PARAM, (st), (ptr)) +#define sk_X509_VERIFY_PARAM_insert(st, val, i) SKM_sk_insert(X509_VERIFY_PARAM, (st), (val), (i)) +#define sk_X509_VERIFY_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_VERIFY_PARAM, (st), (cmp)) +#define sk_X509_VERIFY_PARAM_dup(st) SKM_sk_dup(X509_VERIFY_PARAM, st) +#define sk_X509_VERIFY_PARAM_pop_free(st, free_func) SKM_sk_pop_free(X509_VERIFY_PARAM, (st), (free_func)) +#define sk_X509_VERIFY_PARAM_shift(st) SKM_sk_shift(X509_VERIFY_PARAM, (st)) +#define sk_X509_VERIFY_PARAM_pop(st) SKM_sk_pop(X509_VERIFY_PARAM, (st)) +#define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st)) +#define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st)) + +#define sk_nid_triple_new(cmp) SKM_sk_new(nid_triple, (cmp)) +#define sk_nid_triple_new_null() SKM_sk_new_null(nid_triple) +#define sk_nid_triple_free(st) SKM_sk_free(nid_triple, (st)) +#define sk_nid_triple_num(st) SKM_sk_num(nid_triple, (st)) +#define sk_nid_triple_value(st, i) SKM_sk_value(nid_triple, (st), (i)) +#define sk_nid_triple_set(st, i, val) SKM_sk_set(nid_triple, (st), (i), (val)) +#define sk_nid_triple_zero(st) SKM_sk_zero(nid_triple, (st)) +#define sk_nid_triple_push(st, val) SKM_sk_push(nid_triple, (st), (val)) +#define sk_nid_triple_unshift(st, val) SKM_sk_unshift(nid_triple, (st), (val)) +#define sk_nid_triple_find(st, val) SKM_sk_find(nid_triple, (st), (val)) +#define sk_nid_triple_find_ex(st, val) SKM_sk_find_ex(nid_triple, (st), (val)) +#define sk_nid_triple_delete(st, i) SKM_sk_delete(nid_triple, (st), (i)) +#define sk_nid_triple_delete_ptr(st, ptr) SKM_sk_delete_ptr(nid_triple, (st), (ptr)) +#define sk_nid_triple_insert(st, val, i) SKM_sk_insert(nid_triple, (st), (val), (i)) +#define sk_nid_triple_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(nid_triple, (st), (cmp)) +#define sk_nid_triple_dup(st) SKM_sk_dup(nid_triple, st) +#define sk_nid_triple_pop_free(st, free_func) SKM_sk_pop_free(nid_triple, (st), (free_func)) +#define sk_nid_triple_shift(st) SKM_sk_shift(nid_triple, (st)) +#define sk_nid_triple_pop(st) SKM_sk_pop(nid_triple, (st)) +#define sk_nid_triple_sort(st) SKM_sk_sort(nid_triple, (st)) +#define sk_nid_triple_is_sorted(st) SKM_sk_is_sorted(nid_triple, (st)) + +#define sk_void_new(cmp) SKM_sk_new(void, (cmp)) +#define sk_void_new_null() SKM_sk_new_null(void) +#define sk_void_free(st) SKM_sk_free(void, (st)) +#define sk_void_num(st) SKM_sk_num(void, (st)) +#define sk_void_value(st, i) SKM_sk_value(void, (st), (i)) +#define sk_void_set(st, i, val) SKM_sk_set(void, (st), (i), (val)) +#define sk_void_zero(st) SKM_sk_zero(void, (st)) +#define sk_void_push(st, val) SKM_sk_push(void, (st), (val)) +#define sk_void_unshift(st, val) SKM_sk_unshift(void, (st), (val)) +#define sk_void_find(st, val) SKM_sk_find(void, (st), (val)) +#define sk_void_find_ex(st, val) SKM_sk_find_ex(void, (st), (val)) +#define sk_void_delete(st, i) SKM_sk_delete(void, (st), (i)) +#define sk_void_delete_ptr(st, ptr) SKM_sk_delete_ptr(void, (st), (ptr)) +#define sk_void_insert(st, val, i) SKM_sk_insert(void, (st), (val), (i)) +#define sk_void_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(void, (st), (cmp)) +#define sk_void_dup(st) SKM_sk_dup(void, st) +#define sk_void_pop_free(st, free_func) SKM_sk_pop_free(void, (st), (free_func)) +#define sk_void_shift(st) SKM_sk_shift(void, (st)) +#define sk_void_pop(st) SKM_sk_pop(void, (st)) +#define sk_void_sort(st) SKM_sk_sort(void, (st)) +#define sk_void_is_sorted(st) SKM_sk_is_sorted(void, (st)) + +#define sk_OPENSSL_STRING_new(cmp) ((STACK_OF(OPENSSL_STRING) *)sk_new(CHECKED_SK_CMP_FUNC(char, cmp))) +#define sk_OPENSSL_STRING_new_null() ((STACK_OF(OPENSSL_STRING) *)sk_new_null()) +#define sk_OPENSSL_STRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) +#define sk_OPENSSL_STRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) +#define sk_OPENSSL_STRING_value(st, i) ((OPENSSL_STRING)sk_value(CHECKED_STACK_OF(OPENSSL_STRING, st), i)) +#define sk_OPENSSL_STRING_num(st) SKM_sk_num(OPENSSL_STRING, st) +#define sk_OPENSSL_STRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_FREE_FUNC2(OPENSSL_STRING, free_func)) +#define sk_OPENSSL_STRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val), i) +#define sk_OPENSSL_STRING_free(st) SKM_sk_free(OPENSSL_STRING, st) +#define sk_OPENSSL_STRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_STRING, st), i, CHECKED_PTR_OF(char, val)) +#define sk_OPENSSL_STRING_zero(st) SKM_sk_zero(OPENSSL_STRING, (st)) +#define sk_OPENSSL_STRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) +#define sk_OPENSSL_STRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_CONST_PTR_OF(char, val)) +#define sk_OPENSSL_STRING_delete(st, i) SKM_sk_delete(OPENSSL_STRING, (st), (i)) +#define sk_OPENSSL_STRING_delete_ptr(st, ptr) (OPENSSL_STRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, ptr)) +#define sk_OPENSSL_STRING_set_cmp_func(st, cmp) \ + ((int (*)(const char * const *,const char * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_CMP_FUNC(char, cmp))) +#define sk_OPENSSL_STRING_dup(st) SKM_sk_dup(OPENSSL_STRING, st) +#define sk_OPENSSL_STRING_shift(st) SKM_sk_shift(OPENSSL_STRING, (st)) +#define sk_OPENSSL_STRING_pop(st) (char *)sk_pop(CHECKED_STACK_OF(OPENSSL_STRING, st)) +#define sk_OPENSSL_STRING_sort(st) SKM_sk_sort(OPENSSL_STRING, (st)) +#define sk_OPENSSL_STRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_STRING, (st)) + + +#define sk_OPENSSL_BLOCK_new(cmp) ((STACK_OF(OPENSSL_BLOCK) *)sk_new(CHECKED_SK_CMP_FUNC(void, cmp))) +#define sk_OPENSSL_BLOCK_new_null() ((STACK_OF(OPENSSL_BLOCK) *)sk_new_null()) +#define sk_OPENSSL_BLOCK_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val)) +#define sk_OPENSSL_BLOCK_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val)) +#define sk_OPENSSL_BLOCK_value(st, i) ((OPENSSL_BLOCK)sk_value(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i)) +#define sk_OPENSSL_BLOCK_num(st) SKM_sk_num(OPENSSL_BLOCK, st) +#define sk_OPENSSL_BLOCK_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_FREE_FUNC2(OPENSSL_BLOCK, free_func)) +#define sk_OPENSSL_BLOCK_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val), i) +#define sk_OPENSSL_BLOCK_free(st) SKM_sk_free(OPENSSL_BLOCK, st) +#define sk_OPENSSL_BLOCK_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i, CHECKED_PTR_OF(void, val)) +#define sk_OPENSSL_BLOCK_zero(st) SKM_sk_zero(OPENSSL_BLOCK, (st)) +#define sk_OPENSSL_BLOCK_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val)) +#define sk_OPENSSL_BLOCK_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_CONST_PTR_OF(void, val)) +#define sk_OPENSSL_BLOCK_delete(st, i) SKM_sk_delete(OPENSSL_BLOCK, (st), (i)) +#define sk_OPENSSL_BLOCK_delete_ptr(st, ptr) (OPENSSL_BLOCK *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, ptr)) +#define sk_OPENSSL_BLOCK_set_cmp_func(st, cmp) \ + ((int (*)(const void * const *,const void * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_CMP_FUNC(void, cmp))) +#define sk_OPENSSL_BLOCK_dup(st) SKM_sk_dup(OPENSSL_BLOCK, st) +#define sk_OPENSSL_BLOCK_shift(st) SKM_sk_shift(OPENSSL_BLOCK, (st)) +#define sk_OPENSSL_BLOCK_pop(st) (void *)sk_pop(CHECKED_STACK_OF(OPENSSL_BLOCK, st)) +#define sk_OPENSSL_BLOCK_sort(st) SKM_sk_sort(OPENSSL_BLOCK, (st)) +#define sk_OPENSSL_BLOCK_is_sorted(st) SKM_sk_is_sorted(OPENSSL_BLOCK, (st)) + + +#define sk_OPENSSL_PSTRING_new(cmp) ((STACK_OF(OPENSSL_PSTRING) *)sk_new(CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp))) +#define sk_OPENSSL_PSTRING_new_null() ((STACK_OF(OPENSSL_PSTRING) *)sk_new_null()) +#define sk_OPENSSL_PSTRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +#define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +#define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i)) +#define sk_OPENSSL_PSTRING_num(st) SKM_sk_num(OPENSSL_PSTRING, st) +#define sk_OPENSSL_PSTRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_FREE_FUNC2(OPENSSL_PSTRING, free_func)) +#define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val), i) +#define sk_OPENSSL_PSTRING_free(st) SKM_sk_free(OPENSSL_PSTRING, st) +#define sk_OPENSSL_PSTRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i, CHECKED_PTR_OF(OPENSSL_STRING, val)) +#define sk_OPENSSL_PSTRING_zero(st) SKM_sk_zero(OPENSSL_PSTRING, (st)) +#define sk_OPENSSL_PSTRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +#define sk_OPENSSL_PSTRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_CONST_PTR_OF(OPENSSL_STRING, val)) +#define sk_OPENSSL_PSTRING_delete(st, i) SKM_sk_delete(OPENSSL_PSTRING, (st), (i)) +#define sk_OPENSSL_PSTRING_delete_ptr(st, ptr) (OPENSSL_PSTRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, ptr)) +#define sk_OPENSSL_PSTRING_set_cmp_func(st, cmp) \ + ((int (*)(const OPENSSL_STRING * const *,const OPENSSL_STRING * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp))) +#define sk_OPENSSL_PSTRING_dup(st) SKM_sk_dup(OPENSSL_PSTRING, st) +#define sk_OPENSSL_PSTRING_shift(st) SKM_sk_shift(OPENSSL_PSTRING, (st)) +#define sk_OPENSSL_PSTRING_pop(st) (OPENSSL_STRING *)sk_pop(CHECKED_STACK_OF(OPENSSL_PSTRING, st)) +#define sk_OPENSSL_PSTRING_sort(st) SKM_sk_sort(OPENSSL_PSTRING, (st)) +#define sk_OPENSSL_PSTRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_PSTRING, (st)) + + +#define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ACCESS_DESCRIPTION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_ACCESS_DESCRIPTION(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ACCESS_DESCRIPTION, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_ACCESS_DESCRIPTION(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ACCESS_DESCRIPTION, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_ASN1_INTEGER(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_INTEGER, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_ASN1_INTEGER(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_INTEGER, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_ASN1_INTEGER(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_INTEGER, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_ASN1_INTEGER(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_INTEGER, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_ASN1_OBJECT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_OBJECT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_ASN1_OBJECT(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_OBJECT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_ASN1_OBJECT(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_OBJECT, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_ASN1_OBJECT(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_OBJECT, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_ASN1_TYPE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_TYPE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_ASN1_TYPE(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_TYPE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_ASN1_TYPE(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_TYPE, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_ASN1_TYPE(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_TYPE, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_UTF8STRING, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_UTF8STRING, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_ASN1_UTF8STRING(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_UTF8STRING, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_ASN1_UTF8STRING(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_UTF8STRING, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_DIST_POINT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(DIST_POINT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_DIST_POINT(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(DIST_POINT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_DIST_POINT(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(DIST_POINT, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_DIST_POINT(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(DIST_POINT, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_ESS_CERT_ID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ESS_CERT_ID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_ESS_CERT_ID(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ESS_CERT_ID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_ESS_CERT_ID(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ESS_CERT_ID, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_ESS_CERT_ID(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ESS_CERT_ID, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_EVP_MD(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(EVP_MD, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_EVP_MD(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(EVP_MD, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_EVP_MD(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(EVP_MD, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_EVP_MD(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(EVP_MD, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_GENERAL_NAME(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(GENERAL_NAME, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_GENERAL_NAME(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(GENERAL_NAME, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_GENERAL_NAME(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(GENERAL_NAME, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_GENERAL_NAME(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(GENERAL_NAME, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_OCSP_ONEREQ(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(OCSP_ONEREQ, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_OCSP_ONEREQ(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(OCSP_ONEREQ, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_OCSP_ONEREQ(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(OCSP_ONEREQ, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_OCSP_ONEREQ(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(OCSP_ONEREQ, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(OCSP_SINGLERESP, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(OCSP_SINGLERESP, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_OCSP_SINGLERESP(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(OCSP_SINGLERESP, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_OCSP_SINGLERESP(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(OCSP_SINGLERESP, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(PKCS12_SAFEBAG, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(PKCS12_SAFEBAG, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_PKCS12_SAFEBAG(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(PKCS12_SAFEBAG, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_PKCS12_SAFEBAG(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(PKCS12_SAFEBAG, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_PKCS7(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(PKCS7, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_PKCS7(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(PKCS7, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_PKCS7(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(PKCS7, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_PKCS7(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(PKCS7, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(PKCS7_RECIP_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(PKCS7_RECIP_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_PKCS7_RECIP_INFO(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(PKCS7_RECIP_INFO, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_PKCS7_RECIP_INFO(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(PKCS7_RECIP_INFO, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(PKCS7_SIGNER_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(PKCS7_SIGNER_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_PKCS7_SIGNER_INFO(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(PKCS7_SIGNER_INFO, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_PKCS7_SIGNER_INFO(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(PKCS7_SIGNER_INFO, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_POLICYINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(POLICYINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_POLICYINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(POLICYINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_POLICYINFO(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(POLICYINFO, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_POLICYINFO(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(POLICYINFO, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_POLICYQUALINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(POLICYQUALINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_POLICYQUALINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(POLICYQUALINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_POLICYQUALINFO(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(POLICYQUALINFO, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_POLICYQUALINFO(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(POLICYQUALINFO, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_SXNETID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(SXNETID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_SXNETID(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(SXNETID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_SXNETID(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(SXNETID, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_SXNETID(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(SXNETID, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_X509(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_X509(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_X509(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_X509(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_X509_ALGOR(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_ALGOR, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_X509_ALGOR(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_ALGOR, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_X509_ALGOR(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_ALGOR, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_X509_ALGOR(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_ALGOR, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_ATTRIBUTE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_ATTRIBUTE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_X509_ATTRIBUTE(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_ATTRIBUTE, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_X509_ATTRIBUTE(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_ATTRIBUTE, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_X509_CRL(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_CRL, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_X509_CRL(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_CRL, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_X509_CRL(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_CRL, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_X509_CRL(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_CRL, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_X509_EXTENSION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_EXTENSION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_X509_EXTENSION(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_EXTENSION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_X509_EXTENSION(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_EXTENSION, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_X509_EXTENSION(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_EXTENSION, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_NAME_ENTRY, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_NAME_ENTRY, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_X509_NAME_ENTRY(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_NAME_ENTRY, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_X509_NAME_ENTRY(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_NAME_ENTRY, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_X509_REVOKED(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_REVOKED, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_X509_REVOKED(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_REVOKED, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_X509_REVOKED(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_REVOKED, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_X509_REVOKED(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_REVOKED, (buf), (len), (d2i_func), (free_func)) + +#define PKCS12_decrypt_d2i_PKCS12_SAFEBAG(algor, d2i_func, free_func, pass, passlen, oct, seq) \ + SKM_PKCS12_decrypt_d2i(PKCS12_SAFEBAG, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq)) + +#define PKCS12_decrypt_d2i_PKCS7(algor, d2i_func, free_func, pass, passlen, oct, seq) \ + SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq)) + +#define lh_ADDED_OBJ_new() LHM_lh_new(ADDED_OBJ,added_obj) +#define lh_ADDED_OBJ_insert(lh,inst) LHM_lh_insert(ADDED_OBJ,lh,inst) +#define lh_ADDED_OBJ_retrieve(lh,inst) LHM_lh_retrieve(ADDED_OBJ,lh,inst) +#define lh_ADDED_OBJ_delete(lh,inst) LHM_lh_delete(ADDED_OBJ,lh,inst) +#define lh_ADDED_OBJ_doall(lh,fn) LHM_lh_doall(ADDED_OBJ,lh,fn) +#define lh_ADDED_OBJ_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ADDED_OBJ,lh,fn,arg_type,arg) +#define lh_ADDED_OBJ_error(lh) LHM_lh_error(ADDED_OBJ,lh) +#define lh_ADDED_OBJ_num_items(lh) LHM_lh_num_items(ADDED_OBJ,lh) +#define lh_ADDED_OBJ_down_load(lh) LHM_lh_down_load(ADDED_OBJ,lh) +#define lh_ADDED_OBJ_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ADDED_OBJ,lh,out) +#define lh_ADDED_OBJ_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ADDED_OBJ,lh,out) +#define lh_ADDED_OBJ_stats_bio(lh,out) \ + LHM_lh_stats_bio(ADDED_OBJ,lh,out) +#define lh_ADDED_OBJ_free(lh) LHM_lh_free(ADDED_OBJ,lh) + +#define lh_APP_INFO_new() LHM_lh_new(APP_INFO,app_info) +#define lh_APP_INFO_insert(lh,inst) LHM_lh_insert(APP_INFO,lh,inst) +#define lh_APP_INFO_retrieve(lh,inst) LHM_lh_retrieve(APP_INFO,lh,inst) +#define lh_APP_INFO_delete(lh,inst) LHM_lh_delete(APP_INFO,lh,inst) +#define lh_APP_INFO_doall(lh,fn) LHM_lh_doall(APP_INFO,lh,fn) +#define lh_APP_INFO_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(APP_INFO,lh,fn,arg_type,arg) +#define lh_APP_INFO_error(lh) LHM_lh_error(APP_INFO,lh) +#define lh_APP_INFO_num_items(lh) LHM_lh_num_items(APP_INFO,lh) +#define lh_APP_INFO_down_load(lh) LHM_lh_down_load(APP_INFO,lh) +#define lh_APP_INFO_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(APP_INFO,lh,out) +#define lh_APP_INFO_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(APP_INFO,lh,out) +#define lh_APP_INFO_stats_bio(lh,out) \ + LHM_lh_stats_bio(APP_INFO,lh,out) +#define lh_APP_INFO_free(lh) LHM_lh_free(APP_INFO,lh) + +#define lh_CONF_VALUE_new() LHM_lh_new(CONF_VALUE,conf_value) +#define lh_CONF_VALUE_insert(lh,inst) LHM_lh_insert(CONF_VALUE,lh,inst) +#define lh_CONF_VALUE_retrieve(lh,inst) LHM_lh_retrieve(CONF_VALUE,lh,inst) +#define lh_CONF_VALUE_delete(lh,inst) LHM_lh_delete(CONF_VALUE,lh,inst) +#define lh_CONF_VALUE_doall(lh,fn) LHM_lh_doall(CONF_VALUE,lh,fn) +#define lh_CONF_VALUE_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(CONF_VALUE,lh,fn,arg_type,arg) +#define lh_CONF_VALUE_error(lh) LHM_lh_error(CONF_VALUE,lh) +#define lh_CONF_VALUE_num_items(lh) LHM_lh_num_items(CONF_VALUE,lh) +#define lh_CONF_VALUE_down_load(lh) LHM_lh_down_load(CONF_VALUE,lh) +#define lh_CONF_VALUE_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(CONF_VALUE,lh,out) +#define lh_CONF_VALUE_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(CONF_VALUE,lh,out) +#define lh_CONF_VALUE_stats_bio(lh,out) \ + LHM_lh_stats_bio(CONF_VALUE,lh,out) +#define lh_CONF_VALUE_free(lh) LHM_lh_free(CONF_VALUE,lh) + +#define lh_ENGINE_PILE_new() LHM_lh_new(ENGINE_PILE,engine_pile) +#define lh_ENGINE_PILE_insert(lh,inst) LHM_lh_insert(ENGINE_PILE,lh,inst) +#define lh_ENGINE_PILE_retrieve(lh,inst) LHM_lh_retrieve(ENGINE_PILE,lh,inst) +#define lh_ENGINE_PILE_delete(lh,inst) LHM_lh_delete(ENGINE_PILE,lh,inst) +#define lh_ENGINE_PILE_doall(lh,fn) LHM_lh_doall(ENGINE_PILE,lh,fn) +#define lh_ENGINE_PILE_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ENGINE_PILE,lh,fn,arg_type,arg) +#define lh_ENGINE_PILE_error(lh) LHM_lh_error(ENGINE_PILE,lh) +#define lh_ENGINE_PILE_num_items(lh) LHM_lh_num_items(ENGINE_PILE,lh) +#define lh_ENGINE_PILE_down_load(lh) LHM_lh_down_load(ENGINE_PILE,lh) +#define lh_ENGINE_PILE_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ENGINE_PILE,lh,out) +#define lh_ENGINE_PILE_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ENGINE_PILE,lh,out) +#define lh_ENGINE_PILE_stats_bio(lh,out) \ + LHM_lh_stats_bio(ENGINE_PILE,lh,out) +#define lh_ENGINE_PILE_free(lh) LHM_lh_free(ENGINE_PILE,lh) + +#define lh_ERR_STATE_new() LHM_lh_new(ERR_STATE,err_state) +#define lh_ERR_STATE_insert(lh,inst) LHM_lh_insert(ERR_STATE,lh,inst) +#define lh_ERR_STATE_retrieve(lh,inst) LHM_lh_retrieve(ERR_STATE,lh,inst) +#define lh_ERR_STATE_delete(lh,inst) LHM_lh_delete(ERR_STATE,lh,inst) +#define lh_ERR_STATE_doall(lh,fn) LHM_lh_doall(ERR_STATE,lh,fn) +#define lh_ERR_STATE_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ERR_STATE,lh,fn,arg_type,arg) +#define lh_ERR_STATE_error(lh) LHM_lh_error(ERR_STATE,lh) +#define lh_ERR_STATE_num_items(lh) LHM_lh_num_items(ERR_STATE,lh) +#define lh_ERR_STATE_down_load(lh) LHM_lh_down_load(ERR_STATE,lh) +#define lh_ERR_STATE_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ERR_STATE,lh,out) +#define lh_ERR_STATE_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ERR_STATE,lh,out) +#define lh_ERR_STATE_stats_bio(lh,out) \ + LHM_lh_stats_bio(ERR_STATE,lh,out) +#define lh_ERR_STATE_free(lh) LHM_lh_free(ERR_STATE,lh) + +#define lh_ERR_STRING_DATA_new() LHM_lh_new(ERR_STRING_DATA,err_string_data) +#define lh_ERR_STRING_DATA_insert(lh,inst) LHM_lh_insert(ERR_STRING_DATA,lh,inst) +#define lh_ERR_STRING_DATA_retrieve(lh,inst) LHM_lh_retrieve(ERR_STRING_DATA,lh,inst) +#define lh_ERR_STRING_DATA_delete(lh,inst) LHM_lh_delete(ERR_STRING_DATA,lh,inst) +#define lh_ERR_STRING_DATA_doall(lh,fn) LHM_lh_doall(ERR_STRING_DATA,lh,fn) +#define lh_ERR_STRING_DATA_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ERR_STRING_DATA,lh,fn,arg_type,arg) +#define lh_ERR_STRING_DATA_error(lh) LHM_lh_error(ERR_STRING_DATA,lh) +#define lh_ERR_STRING_DATA_num_items(lh) LHM_lh_num_items(ERR_STRING_DATA,lh) +#define lh_ERR_STRING_DATA_down_load(lh) LHM_lh_down_load(ERR_STRING_DATA,lh) +#define lh_ERR_STRING_DATA_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ERR_STRING_DATA,lh,out) +#define lh_ERR_STRING_DATA_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ERR_STRING_DATA,lh,out) +#define lh_ERR_STRING_DATA_stats_bio(lh,out) \ + LHM_lh_stats_bio(ERR_STRING_DATA,lh,out) +#define lh_ERR_STRING_DATA_free(lh) LHM_lh_free(ERR_STRING_DATA,lh) + +#define lh_EX_CLASS_ITEM_new() LHM_lh_new(EX_CLASS_ITEM,ex_class_item) +#define lh_EX_CLASS_ITEM_insert(lh,inst) LHM_lh_insert(EX_CLASS_ITEM,lh,inst) +#define lh_EX_CLASS_ITEM_retrieve(lh,inst) LHM_lh_retrieve(EX_CLASS_ITEM,lh,inst) +#define lh_EX_CLASS_ITEM_delete(lh,inst) LHM_lh_delete(EX_CLASS_ITEM,lh,inst) +#define lh_EX_CLASS_ITEM_doall(lh,fn) LHM_lh_doall(EX_CLASS_ITEM,lh,fn) +#define lh_EX_CLASS_ITEM_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(EX_CLASS_ITEM,lh,fn,arg_type,arg) +#define lh_EX_CLASS_ITEM_error(lh) LHM_lh_error(EX_CLASS_ITEM,lh) +#define lh_EX_CLASS_ITEM_num_items(lh) LHM_lh_num_items(EX_CLASS_ITEM,lh) +#define lh_EX_CLASS_ITEM_down_load(lh) LHM_lh_down_load(EX_CLASS_ITEM,lh) +#define lh_EX_CLASS_ITEM_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(EX_CLASS_ITEM,lh,out) +#define lh_EX_CLASS_ITEM_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(EX_CLASS_ITEM,lh,out) +#define lh_EX_CLASS_ITEM_stats_bio(lh,out) \ + LHM_lh_stats_bio(EX_CLASS_ITEM,lh,out) +#define lh_EX_CLASS_ITEM_free(lh) LHM_lh_free(EX_CLASS_ITEM,lh) + +#define lh_FUNCTION_new() LHM_lh_new(FUNCTION,function) +#define lh_FUNCTION_insert(lh,inst) LHM_lh_insert(FUNCTION,lh,inst) +#define lh_FUNCTION_retrieve(lh,inst) LHM_lh_retrieve(FUNCTION,lh,inst) +#define lh_FUNCTION_delete(lh,inst) LHM_lh_delete(FUNCTION,lh,inst) +#define lh_FUNCTION_doall(lh,fn) LHM_lh_doall(FUNCTION,lh,fn) +#define lh_FUNCTION_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(FUNCTION,lh,fn,arg_type,arg) +#define lh_FUNCTION_error(lh) LHM_lh_error(FUNCTION,lh) +#define lh_FUNCTION_num_items(lh) LHM_lh_num_items(FUNCTION,lh) +#define lh_FUNCTION_down_load(lh) LHM_lh_down_load(FUNCTION,lh) +#define lh_FUNCTION_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(FUNCTION,lh,out) +#define lh_FUNCTION_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(FUNCTION,lh,out) +#define lh_FUNCTION_stats_bio(lh,out) \ + LHM_lh_stats_bio(FUNCTION,lh,out) +#define lh_FUNCTION_free(lh) LHM_lh_free(FUNCTION,lh) + +#define lh_MEM_new() LHM_lh_new(MEM,mem) +#define lh_MEM_insert(lh,inst) LHM_lh_insert(MEM,lh,inst) +#define lh_MEM_retrieve(lh,inst) LHM_lh_retrieve(MEM,lh,inst) +#define lh_MEM_delete(lh,inst) LHM_lh_delete(MEM,lh,inst) +#define lh_MEM_doall(lh,fn) LHM_lh_doall(MEM,lh,fn) +#define lh_MEM_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(MEM,lh,fn,arg_type,arg) +#define lh_MEM_error(lh) LHM_lh_error(MEM,lh) +#define lh_MEM_num_items(lh) LHM_lh_num_items(MEM,lh) +#define lh_MEM_down_load(lh) LHM_lh_down_load(MEM,lh) +#define lh_MEM_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(MEM,lh,out) +#define lh_MEM_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(MEM,lh,out) +#define lh_MEM_stats_bio(lh,out) \ + LHM_lh_stats_bio(MEM,lh,out) +#define lh_MEM_free(lh) LHM_lh_free(MEM,lh) + +#define lh_OBJ_NAME_new() LHM_lh_new(OBJ_NAME,obj_name) +#define lh_OBJ_NAME_insert(lh,inst) LHM_lh_insert(OBJ_NAME,lh,inst) +#define lh_OBJ_NAME_retrieve(lh,inst) LHM_lh_retrieve(OBJ_NAME,lh,inst) +#define lh_OBJ_NAME_delete(lh,inst) LHM_lh_delete(OBJ_NAME,lh,inst) +#define lh_OBJ_NAME_doall(lh,fn) LHM_lh_doall(OBJ_NAME,lh,fn) +#define lh_OBJ_NAME_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(OBJ_NAME,lh,fn,arg_type,arg) +#define lh_OBJ_NAME_error(lh) LHM_lh_error(OBJ_NAME,lh) +#define lh_OBJ_NAME_num_items(lh) LHM_lh_num_items(OBJ_NAME,lh) +#define lh_OBJ_NAME_down_load(lh) LHM_lh_down_load(OBJ_NAME,lh) +#define lh_OBJ_NAME_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(OBJ_NAME,lh,out) +#define lh_OBJ_NAME_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(OBJ_NAME,lh,out) +#define lh_OBJ_NAME_stats_bio(lh,out) \ + LHM_lh_stats_bio(OBJ_NAME,lh,out) +#define lh_OBJ_NAME_free(lh) LHM_lh_free(OBJ_NAME,lh) + +#define lh_OPENSSL_CSTRING_new() LHM_lh_new(OPENSSL_CSTRING,openssl_cstring) +#define lh_OPENSSL_CSTRING_insert(lh,inst) LHM_lh_insert(OPENSSL_CSTRING,lh,inst) +#define lh_OPENSSL_CSTRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_CSTRING,lh,inst) +#define lh_OPENSSL_CSTRING_delete(lh,inst) LHM_lh_delete(OPENSSL_CSTRING,lh,inst) +#define lh_OPENSSL_CSTRING_doall(lh,fn) LHM_lh_doall(OPENSSL_CSTRING,lh,fn) +#define lh_OPENSSL_CSTRING_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(OPENSSL_CSTRING,lh,fn,arg_type,arg) +#define lh_OPENSSL_CSTRING_error(lh) LHM_lh_error(OPENSSL_CSTRING,lh) +#define lh_OPENSSL_CSTRING_num_items(lh) LHM_lh_num_items(OPENSSL_CSTRING,lh) +#define lh_OPENSSL_CSTRING_down_load(lh) LHM_lh_down_load(OPENSSL_CSTRING,lh) +#define lh_OPENSSL_CSTRING_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(OPENSSL_CSTRING,lh,out) +#define lh_OPENSSL_CSTRING_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(OPENSSL_CSTRING,lh,out) +#define lh_OPENSSL_CSTRING_stats_bio(lh,out) \ + LHM_lh_stats_bio(OPENSSL_CSTRING,lh,out) +#define lh_OPENSSL_CSTRING_free(lh) LHM_lh_free(OPENSSL_CSTRING,lh) + +#define lh_OPENSSL_STRING_new() LHM_lh_new(OPENSSL_STRING,openssl_string) +#define lh_OPENSSL_STRING_insert(lh,inst) LHM_lh_insert(OPENSSL_STRING,lh,inst) +#define lh_OPENSSL_STRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_STRING,lh,inst) +#define lh_OPENSSL_STRING_delete(lh,inst) LHM_lh_delete(OPENSSL_STRING,lh,inst) +#define lh_OPENSSL_STRING_doall(lh,fn) LHM_lh_doall(OPENSSL_STRING,lh,fn) +#define lh_OPENSSL_STRING_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(OPENSSL_STRING,lh,fn,arg_type,arg) +#define lh_OPENSSL_STRING_error(lh) LHM_lh_error(OPENSSL_STRING,lh) +#define lh_OPENSSL_STRING_num_items(lh) LHM_lh_num_items(OPENSSL_STRING,lh) +#define lh_OPENSSL_STRING_down_load(lh) LHM_lh_down_load(OPENSSL_STRING,lh) +#define lh_OPENSSL_STRING_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(OPENSSL_STRING,lh,out) +#define lh_OPENSSL_STRING_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(OPENSSL_STRING,lh,out) +#define lh_OPENSSL_STRING_stats_bio(lh,out) \ + LHM_lh_stats_bio(OPENSSL_STRING,lh,out) +#define lh_OPENSSL_STRING_free(lh) LHM_lh_free(OPENSSL_STRING,lh) + +#define lh_SSL_SESSION_new() LHM_lh_new(SSL_SESSION,ssl_session) +#define lh_SSL_SESSION_insert(lh,inst) LHM_lh_insert(SSL_SESSION,lh,inst) +#define lh_SSL_SESSION_retrieve(lh,inst) LHM_lh_retrieve(SSL_SESSION,lh,inst) +#define lh_SSL_SESSION_delete(lh,inst) LHM_lh_delete(SSL_SESSION,lh,inst) +#define lh_SSL_SESSION_doall(lh,fn) LHM_lh_doall(SSL_SESSION,lh,fn) +#define lh_SSL_SESSION_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(SSL_SESSION,lh,fn,arg_type,arg) +#define lh_SSL_SESSION_error(lh) LHM_lh_error(SSL_SESSION,lh) +#define lh_SSL_SESSION_num_items(lh) LHM_lh_num_items(SSL_SESSION,lh) +#define lh_SSL_SESSION_down_load(lh) LHM_lh_down_load(SSL_SESSION,lh) +#define lh_SSL_SESSION_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(SSL_SESSION,lh,out) +#define lh_SSL_SESSION_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(SSL_SESSION,lh,out) +#define lh_SSL_SESSION_stats_bio(lh,out) \ + LHM_lh_stats_bio(SSL_SESSION,lh,out) +#define lh_SSL_SESSION_free(lh) LHM_lh_free(SSL_SESSION,lh) +/* End of util/mkstack.pl block, you may now edit :-) */ + +#endif /* !defined HEADER_SAFESTACK_H */ diff --git a/crypto/libressl/include/openssl/sha.h b/crypto/libressl/include/openssl/sha.h new file mode 100644 index 0000000000..50c2ed1d64 --- /dev/null +++ b/crypto/libressl/include/openssl/sha.h @@ -0,0 +1,192 @@ +/* $OpenBSD: sha.h,v 1.20 2014/10/20 13:06:54 bcook Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#ifndef HEADER_SHA_H +#define HEADER_SHA_H +#if !defined(HAVE_ATTRIBUTE__BOUNDED__) && !defined(__OpenBSD__) +#define __bounded__(x, y, z) +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA1) +#error SHA is disabled. +#endif + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! SHA_LONG has to be at least 32 bits wide. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +#define SHA_LONG unsigned int + +#define SHA_LBLOCK 16 +#define SHA_CBLOCK (SHA_LBLOCK*4) /* SHA treats input data as a + * contiguous array of 32 bit + * wide big-endian values. */ +#define SHA_LAST_BLOCK (SHA_CBLOCK-8) +#define SHA_DIGEST_LENGTH 20 + +typedef struct SHAstate_st + { + SHA_LONG h0,h1,h2,h3,h4; + SHA_LONG Nl,Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num; + } SHA_CTX; + +#ifndef OPENSSL_NO_SHA1 +int SHA1_Init(SHA_CTX *c); +int SHA1_Update(SHA_CTX *c, const void *data, size_t len) + __attribute__ ((__bounded__(__buffer__,2,3))); +int SHA1_Final(unsigned char *md, SHA_CTX *c); +unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md) + __attribute__ ((__bounded__(__buffer__,1,2))); +void SHA1_Transform(SHA_CTX *c, const unsigned char *data); +#endif + +#define SHA256_CBLOCK (SHA_LBLOCK*4) /* SHA-256 treats input data as a + * contiguous array of 32 bit + * wide big-endian values. */ +#define SHA224_DIGEST_LENGTH 28 +#define SHA256_DIGEST_LENGTH 32 + +typedef struct SHA256state_st + { + SHA_LONG h[8]; + SHA_LONG Nl,Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num,md_len; + } SHA256_CTX; + +#ifndef OPENSSL_NO_SHA256 +int SHA224_Init(SHA256_CTX *c); +int SHA224_Update(SHA256_CTX *c, const void *data, size_t len) + __attribute__ ((__bounded__(__buffer__,2,3))); +int SHA224_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA224(const unsigned char *d, size_t n,unsigned char *md) + __attribute__ ((__bounded__(__buffer__,1,2))); +int SHA256_Init(SHA256_CTX *c); +int SHA256_Update(SHA256_CTX *c, const void *data, size_t len) + __attribute__ ((__bounded__(__buffer__,2,3))); +int SHA256_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA256(const unsigned char *d, size_t n,unsigned char *md) + __attribute__ ((__bounded__(__buffer__,1,2))); +void SHA256_Transform(SHA256_CTX *c, const unsigned char *data); +#endif + +#define SHA384_DIGEST_LENGTH 48 +#define SHA512_DIGEST_LENGTH 64 + +#ifndef OPENSSL_NO_SHA512 +/* + * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64 + * being exactly 64-bit wide. See Implementation Notes in sha512.c + * for further details. + */ +#define SHA512_CBLOCK (SHA_LBLOCK*8) /* SHA-512 treats input data as a + * contiguous array of 64 bit + * wide big-endian values. */ +#if defined(_LP64) +#define SHA_LONG64 unsigned long +#define U64(C) C##UL +#else +#define SHA_LONG64 unsigned long long +#define U64(C) C##ULL +#endif + +typedef struct SHA512state_st + { + SHA_LONG64 h[8]; + SHA_LONG64 Nl,Nh; + union { + SHA_LONG64 d[SHA_LBLOCK]; + unsigned char p[SHA512_CBLOCK]; + } u; + unsigned int num,md_len; + } SHA512_CTX; +#endif + +#ifndef OPENSSL_NO_SHA512 +int SHA384_Init(SHA512_CTX *c); +int SHA384_Update(SHA512_CTX *c, const void *data, size_t len) + __attribute__ ((__bounded__(__buffer__,2,3))); +int SHA384_Final(unsigned char *md, SHA512_CTX *c); +unsigned char *SHA384(const unsigned char *d, size_t n,unsigned char *md) + __attribute__ ((__bounded__(__buffer__,1,2))); +int SHA512_Init(SHA512_CTX *c); +int SHA512_Update(SHA512_CTX *c, const void *data, size_t len) + __attribute__ ((__bounded__(__buffer__,2,3))); +int SHA512_Final(unsigned char *md, SHA512_CTX *c); +unsigned char *SHA512(const unsigned char *d, size_t n,unsigned char *md) + __attribute__ ((__bounded__(__buffer__,1,2))); +void SHA512_Transform(SHA512_CTX *c, const unsigned char *data); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/libressl/include/openssl/srtp.h b/crypto/libressl/include/openssl/srtp.h new file mode 100644 index 0000000000..5b6f0868ad --- /dev/null +++ b/crypto/libressl/include/openssl/srtp.h @@ -0,0 +1,142 @@ +/* $OpenBSD: srtp.h,v 1.5 2014/12/14 15:30:50 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* + * DTLS code by Eric Rescorla + * + * Copyright (C) 2006, Network Resonance, Inc. + * Copyright (C) 2011, RTFM, Inc. + */ + +#ifndef HEADER_D1_SRTP_H +#define HEADER_D1_SRTP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define SRTP_AES128_CM_SHA1_80 0x0001 +#define SRTP_AES128_CM_SHA1_32 0x0002 +#define SRTP_AES128_F8_SHA1_80 0x0003 +#define SRTP_AES128_F8_SHA1_32 0x0004 +#define SRTP_NULL_SHA1_80 0x0005 +#define SRTP_NULL_SHA1_32 0x0006 + +int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles); +int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles); + +STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl); +SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/libressl/include/openssl/ssl.h b/crypto/libressl/include/openssl/ssl.h new file mode 100644 index 0000000000..b90855e93d --- /dev/null +++ b/crypto/libressl/include/openssl/ssl.h @@ -0,0 +1,2382 @@ +/* $OpenBSD: ssl.h,v 1.95 2015/10/25 15:58:57 doug Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifndef HEADER_SSL_H +#define HEADER_SSL_H + +#include + +#include +#include +#include +#include + +#ifndef OPENSSL_NO_BIO +#include +#endif + +#ifndef OPENSSL_NO_DEPRECATED +#include +#include +#include + +#ifndef OPENSSL_NO_X509 +#include +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* SSLeay version number for ASN.1 encoding of the session information */ +/* Version 0 - initial version + * Version 1 - added the optional peer certificate + */ +#define SSL_SESSION_ASN1_VERSION 0x0001 + +/* text strings for the ciphers */ +#define SSL_TXT_NULL_WITH_MD5 SSL2_TXT_NULL_WITH_MD5 +#define SSL_TXT_RC4_128_WITH_MD5 SSL2_TXT_RC4_128_WITH_MD5 +#define SSL_TXT_RC4_128_EXPORT40_WITH_MD5 SSL2_TXT_RC4_128_EXPORT40_WITH_MD5 +#define SSL_TXT_RC2_128_CBC_WITH_MD5 SSL2_TXT_RC2_128_CBC_WITH_MD5 +#define SSL_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 +#define SSL_TXT_IDEA_128_CBC_WITH_MD5 SSL2_TXT_IDEA_128_CBC_WITH_MD5 +#define SSL_TXT_DES_64_CBC_WITH_MD5 SSL2_TXT_DES_64_CBC_WITH_MD5 +#define SSL_TXT_DES_64_CBC_WITH_SHA SSL2_TXT_DES_64_CBC_WITH_SHA +#define SSL_TXT_DES_192_EDE3_CBC_WITH_MD5 SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5 +#define SSL_TXT_DES_192_EDE3_CBC_WITH_SHA SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA + +/* VRS Additional Kerberos5 entries + */ +#define SSL_TXT_KRB5_DES_64_CBC_SHA SSL3_TXT_KRB5_DES_64_CBC_SHA +#define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA +#define SSL_TXT_KRB5_RC4_128_SHA SSL3_TXT_KRB5_RC4_128_SHA +#define SSL_TXT_KRB5_IDEA_128_CBC_SHA SSL3_TXT_KRB5_IDEA_128_CBC_SHA +#define SSL_TXT_KRB5_DES_64_CBC_MD5 SSL3_TXT_KRB5_DES_64_CBC_MD5 +#define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5 +#define SSL_TXT_KRB5_RC4_128_MD5 SSL3_TXT_KRB5_RC4_128_MD5 +#define SSL_TXT_KRB5_IDEA_128_CBC_MD5 SSL3_TXT_KRB5_IDEA_128_CBC_MD5 + +#define SSL_TXT_KRB5_DES_40_CBC_SHA SSL3_TXT_KRB5_DES_40_CBC_SHA +#define SSL_TXT_KRB5_RC2_40_CBC_SHA SSL3_TXT_KRB5_RC2_40_CBC_SHA +#define SSL_TXT_KRB5_RC4_40_SHA SSL3_TXT_KRB5_RC4_40_SHA +#define SSL_TXT_KRB5_DES_40_CBC_MD5 SSL3_TXT_KRB5_DES_40_CBC_MD5 +#define SSL_TXT_KRB5_RC2_40_CBC_MD5 SSL3_TXT_KRB5_RC2_40_CBC_MD5 +#define SSL_TXT_KRB5_RC4_40_MD5 SSL3_TXT_KRB5_RC4_40_MD5 + +#define SSL_TXT_KRB5_DES_40_CBC_SHA SSL3_TXT_KRB5_DES_40_CBC_SHA +#define SSL_TXT_KRB5_DES_40_CBC_MD5 SSL3_TXT_KRB5_DES_40_CBC_MD5 +#define SSL_TXT_KRB5_DES_64_CBC_SHA SSL3_TXT_KRB5_DES_64_CBC_SHA +#define SSL_TXT_KRB5_DES_64_CBC_MD5 SSL3_TXT_KRB5_DES_64_CBC_MD5 +#define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA +#define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5 +#define SSL_MAX_KRB5_PRINCIPAL_LENGTH 256 + +#define SSL_MAX_SSL_SESSION_ID_LENGTH 32 +#define SSL_MAX_SID_CTX_LENGTH 32 + +#define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES (512/8) +#define SSL_MAX_KEY_ARG_LENGTH 8 +#define SSL_MAX_MASTER_KEY_LENGTH 48 + + +/* These are used to specify which ciphers to use and not to use */ + +#define SSL_TXT_LOW "LOW" +#define SSL_TXT_MEDIUM "MEDIUM" +#define SSL_TXT_HIGH "HIGH" + +#define SSL_TXT_kFZA "kFZA" /* unused! */ +#define SSL_TXT_aFZA "aFZA" /* unused! */ +#define SSL_TXT_eFZA "eFZA" /* unused! */ +#define SSL_TXT_FZA "FZA" /* unused! */ + +#define SSL_TXT_aNULL "aNULL" +#define SSL_TXT_eNULL "eNULL" +#define SSL_TXT_NULL "NULL" + +#define SSL_TXT_kRSA "kRSA" +#define SSL_TXT_kDHr "kDHr" /* no such ciphersuites supported! */ +#define SSL_TXT_kDHd "kDHd" /* no such ciphersuites supported! */ +#define SSL_TXT_kDH "kDH" /* no such ciphersuites supported! */ +#define SSL_TXT_kEDH "kEDH" +#define SSL_TXT_kKRB5 "kKRB5" +#define SSL_TXT_kECDHr "kECDHr" +#define SSL_TXT_kECDHe "kECDHe" +#define SSL_TXT_kECDH "kECDH" +#define SSL_TXT_kEECDH "kEECDH" +#define SSL_TXT_kPSK "kPSK" +#define SSL_TXT_kGOST "kGOST" +#define SSL_TXT_kSRP "kSRP" + +#define SSL_TXT_aRSA "aRSA" +#define SSL_TXT_aDSS "aDSS" +#define SSL_TXT_aDH "aDH" /* no such ciphersuites supported! */ +#define SSL_TXT_aECDH "aECDH" +#define SSL_TXT_aKRB5 "aKRB5" +#define SSL_TXT_aECDSA "aECDSA" +#define SSL_TXT_aPSK "aPSK" +#define SSL_TXT_aGOST94 "aGOST94" +#define SSL_TXT_aGOST01 "aGOST01" +#define SSL_TXT_aGOST "aGOST" + +#define SSL_TXT_DSS "DSS" +#define SSL_TXT_DH "DH" +#define SSL_TXT_DHE "DHE" /* same as "kDHE:-ADH" */ +#define SSL_TXT_EDH "EDH" /* previous name for DHE */ +#define SSL_TXT_ADH "ADH" +#define SSL_TXT_RSA "RSA" +#define SSL_TXT_ECDH "ECDH" +#define SSL_TXT_ECDHE "ECDHE" /* same as "kECDHE:-AECDH" */ +#define SSL_TXT_EECDH "EECDH" /* previous name for ECDHE */ +#define SSL_TXT_AECDH "AECDH" +#define SSL_TXT_ECDSA "ECDSA" +#define SSL_TXT_KRB5 "KRB5" +#define SSL_TXT_PSK "PSK" +#define SSL_TXT_SRP "SRP" + +#define SSL_TXT_DES "DES" +#define SSL_TXT_3DES "3DES" +#define SSL_TXT_RC4 "RC4" +#define SSL_TXT_RC2 "RC2" +#define SSL_TXT_IDEA "IDEA" +#define SSL_TXT_SEED "SEED" +#define SSL_TXT_AES128 "AES128" +#define SSL_TXT_AES256 "AES256" +#define SSL_TXT_AES "AES" +#define SSL_TXT_AES_GCM "AESGCM" +#define SSL_TXT_CAMELLIA128 "CAMELLIA128" +#define SSL_TXT_CAMELLIA256 "CAMELLIA256" +#define SSL_TXT_CAMELLIA "CAMELLIA" +#define SSL_TXT_CHACHA20 "CHACHA20" + +#define SSL_TXT_AEAD "AEAD" +#define SSL_TXT_MD5 "MD5" +#define SSL_TXT_SHA1 "SHA1" +#define SSL_TXT_SHA "SHA" /* same as "SHA1" */ +#define SSL_TXT_GOST94 "GOST94" +#define SSL_TXT_GOST89MAC "GOST89MAC" +#define SSL_TXT_SHA256 "SHA256" +#define SSL_TXT_SHA384 "SHA384" +#define SSL_TXT_STREEBOG256 "STREEBOG256" +#define SSL_TXT_STREEBOG512 "STREEBOG512" + +#define SSL_TXT_DTLS1 "DTLSv1" +#define SSL_TXT_SSLV2 "SSLv2" +#define SSL_TXT_SSLV3 "SSLv3" +#define SSL_TXT_TLSV1 "TLSv1" +#define SSL_TXT_TLSV1_1 "TLSv1.1" +#define SSL_TXT_TLSV1_2 "TLSv1.2" + +#define SSL_TXT_EXP "EXP" +#define SSL_TXT_EXPORT "EXPORT" + +#define SSL_TXT_ALL "ALL" + +/* + * COMPLEMENTOF* definitions. These identifiers are used to (de-select) + * ciphers normally not being used. + * Example: "RC4" will activate all ciphers using RC4 including ciphers + * without authentication, which would normally disabled by DEFAULT (due + * the "!ADH" being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT" + * will make sure that it is also disabled in the specific selection. + * COMPLEMENTOF* identifiers are portable between version, as adjustments + * to the default cipher setup will also be included here. + * + * COMPLEMENTOFDEFAULT does not experience the same special treatment that + * DEFAULT gets, as only selection is being done and no sorting as needed + * for DEFAULT. + */ +#define SSL_TXT_CMPALL "COMPLEMENTOFALL" +#define SSL_TXT_CMPDEF "COMPLEMENTOFDEFAULT" + +/* The following cipher list is used by default. + * It also is substituted when an application-defined cipher list string + * starts with 'DEFAULT'. */ +#define SSL_DEFAULT_CIPHER_LIST "ALL:!aNULL:!eNULL:!SSLv2" +/* As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always + * starts with a reasonable order, and all we have to do for DEFAULT is + * throwing out anonymous and unencrypted ciphersuites! + * (The latter are not actually enabled by ALL, but "ALL:RSA" would enable + * some of them.) + */ + +/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ +#define SSL_SENT_SHUTDOWN 1 +#define SSL_RECEIVED_SHUTDOWN 2 + + +#define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1 +#define SSL_FILETYPE_PEM X509_FILETYPE_PEM + +/* This is needed to stop compilers complaining about the + * 'struct ssl_st *' function parameters used to prototype callbacks + * in SSL_CTX. */ +typedef struct ssl_st *ssl_crock_st; +typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT; +typedef struct ssl_method_st SSL_METHOD; +typedef struct ssl_cipher_st SSL_CIPHER; +typedef struct ssl_session_st SSL_SESSION; + +DECLARE_STACK_OF(SSL_CIPHER) + +/* SRTP protection profiles for use with the use_srtp extension (RFC 5764)*/ +typedef struct srtp_protection_profile_st { + const char *name; + unsigned long id; +} SRTP_PROTECTION_PROFILE; + +DECLARE_STACK_OF(SRTP_PROTECTION_PROFILE) + +typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data, + int len, void *arg); +typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, + STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg); + +#ifndef OPENSSL_NO_SSL_INTERN + +/* used to hold info on the particular ciphers used */ +struct ssl_cipher_st { + int valid; + const char *name; /* text name */ + unsigned long id; /* id, 4 bytes, first is version */ + + unsigned long algorithm_mkey; /* key exchange algorithm */ + unsigned long algorithm_auth; /* server authentication */ + unsigned long algorithm_enc; /* symmetric encryption */ + unsigned long algorithm_mac; /* symmetric authentication */ + unsigned long algorithm_ssl; /* (major) protocol version */ + + unsigned long algo_strength; /* strength and export flags */ + unsigned long algorithm2; /* Extra flags */ + int strength_bits; /* Number of bits really used */ + int alg_bits; /* Number of bits for algorithm */ +}; + + +/* Used to hold functions for SSLv3/TLSv1 functions */ +struct ssl_method_st { + int version; + int (*ssl_new)(SSL *s); + void (*ssl_clear)(SSL *s); + void (*ssl_free)(SSL *s); + int (*ssl_accept)(SSL *s); + int (*ssl_connect)(SSL *s); + int (*ssl_read)(SSL *s, void *buf, int len); + int (*ssl_peek)(SSL *s, void *buf, int len); + int (*ssl_write)(SSL *s, const void *buf, int len); + int (*ssl_shutdown)(SSL *s); + int (*ssl_renegotiate)(SSL *s); + int (*ssl_renegotiate_check)(SSL *s); + long (*ssl_get_message)(SSL *s, int st1, int stn, int mt, + long max, int *ok); + int (*ssl_read_bytes)(SSL *s, int type, unsigned char *buf, + int len, int peek); + int (*ssl_write_bytes)(SSL *s, int type, const void *buf_, int len); + int (*ssl_dispatch_alert)(SSL *s); + long (*ssl_ctrl)(SSL *s, int cmd, long larg, void *parg); + long (*ssl_ctx_ctrl)(SSL_CTX *ctx, int cmd, long larg, void *parg); + const SSL_CIPHER *(*get_cipher_by_char)(const unsigned char *ptr); + int (*put_cipher_by_char)(const SSL_CIPHER *cipher, unsigned char *ptr); + int (*ssl_pending)(const SSL *s); + int (*num_ciphers)(void); + const SSL_CIPHER *(*get_cipher)(unsigned ncipher); + const struct ssl_method_st *(*get_ssl_method)(int version); + long (*get_timeout)(void); + struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */ + int (*ssl_version)(void); + long (*ssl_callback_ctrl)(SSL *s, int cb_id, void (*fp)(void)); + long (*ssl_ctx_callback_ctrl)(SSL_CTX *s, int cb_id, void (*fp)(void)); +}; + +/* Lets make this into an ASN.1 type structure as follows + * SSL_SESSION_ID ::= SEQUENCE { + * version INTEGER, -- structure version number + * SSLversion INTEGER, -- SSL version number + * Cipher OCTET STRING, -- the 3 byte cipher ID + * Session_ID OCTET STRING, -- the Session ID + * Master_key OCTET STRING, -- the master key + * KRB5_principal OCTET STRING -- optional Kerberos principal + * Time [ 1 ] EXPLICIT INTEGER, -- optional Start Time + * Timeout [ 2 ] EXPLICIT INTEGER, -- optional Timeout ins seconds + * Peer [ 3 ] EXPLICIT X509, -- optional Peer Certificate + * Session_ID_context [ 4 ] EXPLICIT OCTET STRING, -- the Session ID context + * Verify_result [ 5 ] EXPLICIT INTEGER, -- X509_V_... code for `Peer' + * HostName [ 6 ] EXPLICIT OCTET STRING, -- optional HostName from servername TLS extension + * PSK_identity_hint [ 7 ] EXPLICIT OCTET STRING, -- optional PSK identity hint + * PSK_identity [ 8 ] EXPLICIT OCTET STRING, -- optional PSK identity + * Ticket_lifetime_hint [9] EXPLICIT INTEGER, -- server's lifetime hint for session ticket + * Ticket [10] EXPLICIT OCTET STRING, -- session ticket (clients only) + * Compression_meth [11] EXPLICIT OCTET STRING, -- optional compression method + * SRP_username [ 12 ] EXPLICIT OCTET STRING -- optional SRP username + * } + * Look in ssl/ssl_asn1.c for more details + * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-). + */ +struct ssl_session_st { + int ssl_version; /* what ssl version session info is + * being kept in here? */ + + int master_key_length; + unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH]; + /* session_id - valid? */ + unsigned int session_id_length; + unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH]; + /* this is used to determine whether the session is being reused in + * the appropriate context. It is up to the application to set this, + * via SSL_new */ + unsigned int sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + + /* Used to indicate that session resumption is not allowed. + * Applications can also set this bit for a new session via + * not_resumable_session_cb to disable session caching and tickets. */ + int not_resumable; + + /* The cert is the certificate used to establish this connection */ + struct sess_cert_st /* SESS_CERT */ *sess_cert; + + /* This is the cert for the other end. + * On clients, it will be the same as sess_cert->peer_key->x509 + * (the latter is not enough as sess_cert is not retained + * in the external representation of sessions, see ssl_asn1.c). */ + X509 *peer; + /* when app_verify_callback accepts a session where the peer's certificate + * is not ok, we must remember the error for session reuse: */ + long verify_result; /* only for servers */ + + long timeout; + time_t time; + int references; + + const SSL_CIPHER *cipher; + unsigned long cipher_id; /* when ASN.1 loaded, this + * needs to be used to load + * the 'cipher' structure */ + + STACK_OF(SSL_CIPHER) *ciphers; /* shared ciphers? */ + + CRYPTO_EX_DATA ex_data; /* application specific data */ + + /* These are used to make removal of session-ids more + * efficient and to implement a maximum cache size. */ + struct ssl_session_st *prev, *next; + char *tlsext_hostname; + size_t tlsext_ecpointformatlist_length; + uint8_t *tlsext_ecpointformatlist; /* peer's list */ + size_t tlsext_ellipticcurvelist_length; + uint16_t *tlsext_ellipticcurvelist; /* peer's list */ + + /* RFC4507 info */ + unsigned char *tlsext_tick; /* Session ticket */ + size_t tlsext_ticklen; /* Session ticket length */ + long tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */ +}; + +#endif + +/* Allow initial connection to servers that don't support RI */ +#define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L +#define SSL_OP_TLSEXT_PADDING 0x00000010L + +/* Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added + * in OpenSSL 0.9.6d. Usually (depending on the application protocol) + * the workaround is not needed. + * Unfortunately some broken SSL/TLS implementations cannot handle it + * at all, which is why it was previously included in SSL_OP_ALL. + * Now it's not. + */ +#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0x00000800L + +/* DTLS options */ +#define SSL_OP_NO_QUERY_MTU 0x00001000L +/* Turn on Cookie Exchange (on relevant for servers) */ +#define SSL_OP_COOKIE_EXCHANGE 0x00002000L +/* Don't use RFC4507 ticket extension */ +#define SSL_OP_NO_TICKET 0x00004000L + +/* As server, disallow session resumption on renegotiation */ +#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000L +/* If set, always create a new key when using tmp_ecdh parameters */ +#define SSL_OP_SINGLE_ECDH_USE 0x00080000L +/* If set, always create a new key when using tmp_dh parameters */ +#define SSL_OP_SINGLE_DH_USE 0x00100000L +/* Set on servers to choose the cipher according to the server's + * preferences */ +#define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L +/* If set, a server will allow a client to issue a SSLv3.0 version number + * as latest version supported in the premaster secret, even when TLSv1.0 + * (version 3.1) was announced in the client hello. Normally this is + * forbidden to prevent version rollback attacks. */ +#define SSL_OP_TLS_ROLLBACK_BUG 0x00800000L + +#define SSL_OP_NO_TLSv1 0x04000000L +#define SSL_OP_NO_TLSv1_2 0x08000000L +#define SSL_OP_NO_TLSv1_1 0x10000000L + +/* Make server add server-hello extension from early version of + * cryptopro draft, when GOST ciphersuite is negotiated. + * Required for interoperability with CryptoPro CSP 3.x + */ +#define SSL_OP_CRYPTOPRO_TLSEXT_BUG 0x80000000L + +/* SSL_OP_ALL: various bug workarounds that should be rather harmless. */ +#define SSL_OP_ALL \ + (SSL_OP_LEGACY_SERVER_CONNECT | \ + SSL_OP_TLSEXT_PADDING | \ + SSL_OP_CRYPTOPRO_TLSEXT_BUG) + +/* Obsolete flags kept for compatibility. No sane code should use them. */ +#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x0 +#define SSL_OP_CISCO_ANYCONNECT 0x0 +#define SSL_OP_EPHEMERAL_RSA 0x0 +#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x0 +#define SSL_OP_MICROSOFT_SESS_ID_BUG 0x0 +#define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x0 +#define SSL_OP_NETSCAPE_CA_DN_BUG 0x0 +#define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x0 +#define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0x0 +#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x0 +#define SSL_OP_NO_COMPRESSION 0x0 +#define SSL_OP_NO_SSLv2 0x0 +#define SSL_OP_NO_SSLv3 0x0 +#define SSL_OP_PKCS1_CHECK_1 0x0 +#define SSL_OP_PKCS1_CHECK_2 0x0 +#define SSL_OP_SAFARI_ECDHE_ECDSA_BUG 0x0 +#define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0x0 +#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x0 +#define SSL_OP_TLS_BLOCK_PADDING_BUG 0x0 +#define SSL_OP_TLS_D5_BUG 0x0 + +/* Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success + * when just a single record has been written): */ +#define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001L +/* Make it possible to retry SSL_write() with changed buffer location + * (buffer contents must stay the same!); this is not the default to avoid + * the misconception that non-blocking SSL_write() behaves like + * non-blocking write(): */ +#define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L +/* Never bother the application with retries if the transport + * is blocking: */ +#define SSL_MODE_AUTO_RETRY 0x00000004L +/* Don't attempt to automatically build certificate chain */ +#define SSL_MODE_NO_AUTO_CHAIN 0x00000008L +/* Save RAM by releasing read and write buffers when they're empty. (SSL3 and + * TLS only.) "Released" buffers are put onto a free-list in the context + * or just freed (depending on the context's setting for freelist_max_len). */ +#define SSL_MODE_RELEASE_BUFFERS 0x00000010L + +/* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, + * they cannot be used to clear bits. */ + +#define SSL_CTX_set_options(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL) +#define SSL_CTX_clear_options(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_OPTIONS,(op),NULL) +#define SSL_CTX_get_options(ctx) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,0,NULL) +#define SSL_set_options(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),NULL) +#define SSL_clear_options(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_OPTIONS,(op),NULL) +#define SSL_get_options(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_OPTIONS,0,NULL) + +#define SSL_CTX_set_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL) +#define SSL_CTX_clear_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_MODE,(op),NULL) +#define SSL_CTX_get_mode(ctx) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL) +#define SSL_clear_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_MODE,(op),NULL) +#define SSL_set_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL) +#define SSL_get_mode(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL) +#define SSL_set_mtu(ssl, mtu) \ + SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL) + +#define SSL_get_secure_renegotiation_support(ssl) \ + SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL) + +void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, + int version, int content_type, const void *buf, size_t len, SSL *ssl, + void *arg)); +void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, + int content_type, const void *buf, size_t len, SSL *ssl, void *arg)); +#define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) +#define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) + +struct ssl_aead_ctx_st; +typedef struct ssl_aead_ctx_st SSL_AEAD_CTX; + +#define SSL_MAX_CERT_LIST_DEFAULT 1024*100 /* 100k max cert list :-) */ + +#define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024*20) + +/* This callback type is used inside SSL_CTX, SSL, and in the functions that set + * them. It is used to override the generation of SSL/TLS session IDs in a + * server. Return value should be zero on an error, non-zero to proceed. Also, + * callbacks should themselves check if the id they generate is unique otherwise + * the SSL handshake will fail with an error - callbacks can do this using the + * 'ssl' value they're passed by; + * SSL_has_matching_session_id(ssl, id, *id_len) + * The length value passed in is set at the maximum size the session ID can be. + * In SSLv2 this is 16 bytes, whereas SSLv3/TLSv1 it is 32 bytes. The callback + * can alter this length to be less if desired, but under SSLv2 session IDs are + * supposed to be fixed at 16 bytes so the id will be padded after the callback + * returns in this case. It is also an error for the callback to set the size to + * zero. */ +typedef int (*GEN_SESSION_CB)(const SSL *ssl, unsigned char *id, + unsigned int *id_len); + +typedef struct ssl_comp_st SSL_COMP; + +#ifndef OPENSSL_NO_SSL_INTERN + +struct ssl_comp_st { + int id; + const char *name; +}; + +DECLARE_STACK_OF(SSL_COMP) +DECLARE_LHASH_OF(SSL_SESSION); + +struct ssl_ctx_st { + const SSL_METHOD *method; + + STACK_OF(SSL_CIPHER) *cipher_list; + /* same as above but sorted for lookup */ + STACK_OF(SSL_CIPHER) *cipher_list_by_id; + + struct x509_store_st /* X509_STORE */ *cert_store; + LHASH_OF(SSL_SESSION) *sessions; + /* Most session-ids that will be cached, default is + * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited. */ + unsigned long session_cache_size; + struct ssl_session_st *session_cache_head; + struct ssl_session_st *session_cache_tail; + + /* This can have one of 2 values, ored together, + * SSL_SESS_CACHE_CLIENT, + * SSL_SESS_CACHE_SERVER, + * Default is SSL_SESSION_CACHE_SERVER, which means only + * SSL_accept which cache SSL_SESSIONS. */ + int session_cache_mode; + + /* If timeout is not 0, it is the default timeout value set + * when SSL_new() is called. This has been put in to make + * life easier to set things up */ + long session_timeout; + + /* If this callback is not null, it will be called each + * time a session id is added to the cache. If this function + * returns 1, it means that the callback will do a + * SSL_SESSION_free() when it has finished using it. Otherwise, + * on 0, it means the callback has finished with it. + * If remove_session_cb is not null, it will be called when + * a session-id is removed from the cache. After the call, + * OpenSSL will SSL_SESSION_free() it. */ + int (*new_session_cb)(struct ssl_st *ssl, SSL_SESSION *sess); + void (*remove_session_cb)(struct ssl_ctx_st *ctx, SSL_SESSION *sess); + SSL_SESSION *(*get_session_cb)(struct ssl_st *ssl, + unsigned char *data, int len, int *copy); + + struct { + int sess_connect; /* SSL new conn - started */ + int sess_connect_renegotiate;/* SSL reneg - requested */ + int sess_connect_good; /* SSL new conne/reneg - finished */ + int sess_accept; /* SSL new accept - started */ + int sess_accept_renegotiate;/* SSL reneg - requested */ + int sess_accept_good; /* SSL accept/reneg - finished */ + int sess_miss; /* session lookup misses */ + int sess_timeout; /* reuse attempt on timeouted session */ + int sess_cache_full; /* session removed due to full cache */ + int sess_hit; /* session reuse actually done */ + int sess_cb_hit; /* session-id that was not + * in the cache was + * passed back via the callback. This + * indicates that the application is + * supplying session-id's from other + * processes - spooky :-) */ + } stats; + + int references; + + /* if defined, these override the X509_verify_cert() calls */ + int (*app_verify_callback)(X509_STORE_CTX *, void *); + void *app_verify_arg; + + /* Default password callback. */ + pem_password_cb *default_passwd_callback; + + /* Default password callback user data. */ + void *default_passwd_callback_userdata; + + /* get client cert callback */ + int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey); + + /* cookie generate callback */ + int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, + unsigned int *cookie_len); + + /* verify cookie callback */ + int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, + unsigned int cookie_len); + + CRYPTO_EX_DATA ex_data; + + const EVP_MD *md5; /* For SSLv3/TLSv1 'ssl3-md5' */ + const EVP_MD *sha1; /* For SSLv3/TLSv1 'ssl3-sha1' */ + + STACK_OF(X509) *extra_certs; + + /* Default values used when no per-SSL value is defined follow */ + + void (*info_callback)(const SSL *ssl,int type,int val); /* used if SSL's info_callback is NULL */ + + /* what we put in client cert requests */ + STACK_OF(X509_NAME) *client_CA; + + + /* Default values to use in SSL structures follow (these are copied by SSL_new) */ + + unsigned long options; + unsigned long mode; + long max_cert_list; + + struct cert_st /* CERT */ *cert; + int read_ahead; + + /* callback that allows applications to peek at protocol messages */ + void (*msg_callback)(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); + void *msg_callback_arg; + + int verify_mode; + unsigned int sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + int (*default_verify_callback)(int ok,X509_STORE_CTX *ctx); /* called 'verify_callback' in the SSL */ + + /* Default generate session ID callback. */ + GEN_SESSION_CB generate_session_id; + + X509_VERIFY_PARAM *param; + + int quiet_shutdown; + + /* Maximum amount of data to send in one fragment. + * actual record size can be more than this due to + * padding and MAC overheads. + */ + unsigned int max_send_fragment; + +#ifndef OPENSSL_NO_ENGINE + /* Engine to pass requests for client certs to + */ + ENGINE *client_cert_engine; +#endif + + /* TLS extensions servername callback */ + int (*tlsext_servername_callback)(SSL*, int *, void *); + void *tlsext_servername_arg; + /* RFC 4507 session ticket keys */ + unsigned char tlsext_tick_key_name[16]; + unsigned char tlsext_tick_hmac_key[16]; + unsigned char tlsext_tick_aes_key[16]; + /* Callback to support customisation of ticket key setting */ + int (*tlsext_ticket_key_cb)(SSL *ssl, unsigned char *name, + unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc); + + /* certificate status request info */ + /* Callback for status request */ + int (*tlsext_status_cb)(SSL *ssl, void *arg); + void *tlsext_status_arg; + + + + + /* Next protocol negotiation information */ + /* (for experimental NPN extension). */ + + /* For a server, this contains a callback function by which the set of + * advertised protocols can be provided. */ + int (*next_protos_advertised_cb)(SSL *s, const unsigned char **buf, + unsigned int *len, void *arg); + void *next_protos_advertised_cb_arg; + /* For a client, this contains a callback function that selects the + * next protocol from the list provided by the server. */ + int (*next_proto_select_cb)(SSL *s, unsigned char **out, + unsigned char *outlen, const unsigned char *in, + unsigned int inlen, void *arg); + void *next_proto_select_cb_arg; + + /* + * ALPN information + * (we are in the process of transitioning from NPN to ALPN). + */ + + /* + * Server callback function that allows the server to select the + * protocol for the connection. + * out: on successful return, this must point to the raw protocol + * name (without the length prefix). + * outlen: on successful return, this contains the length of out. + * in: points to the client's list of supported protocols in + * wire-format. + * inlen: the length of in. + */ + int (*alpn_select_cb)(SSL *s, const unsigned char **out, + unsigned char *outlen, const unsigned char *in, unsigned int inlen, + void *arg); + void *alpn_select_cb_arg; + + /* Client list of supported protocols in wire format. */ + unsigned char *alpn_client_proto_list; + unsigned int alpn_client_proto_list_len; + + /* SRTP profiles we are willing to do from RFC 5764 */ + STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; +}; + +#endif + +#define SSL_SESS_CACHE_OFF 0x0000 +#define SSL_SESS_CACHE_CLIENT 0x0001 +#define SSL_SESS_CACHE_SERVER 0x0002 +#define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER) +#define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080 +/* enough comments already ... see SSL_CTX_set_session_cache_mode(3) */ +#define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100 +#define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200 +#define SSL_SESS_CACHE_NO_INTERNAL \ + (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE) + +LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx); +#define SSL_CTX_sess_number(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL) +#define SSL_CTX_sess_connect(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT,0,NULL) +#define SSL_CTX_sess_connect_good(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_GOOD,0,NULL) +#define SSL_CTX_sess_connect_renegotiate(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_RENEGOTIATE,0,NULL) +#define SSL_CTX_sess_accept(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT,0,NULL) +#define SSL_CTX_sess_accept_renegotiate(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_RENEGOTIATE,0,NULL) +#define SSL_CTX_sess_accept_good(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_GOOD,0,NULL) +#define SSL_CTX_sess_hits(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_HIT,0,NULL) +#define SSL_CTX_sess_cb_hits(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CB_HIT,0,NULL) +#define SSL_CTX_sess_misses(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_MISSES,0,NULL) +#define SSL_CTX_sess_timeouts(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL) +#define SSL_CTX_sess_cache_full(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL) + +void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, + int (*new_session_cb)(struct ssl_st *ssl, SSL_SESSION *sess)); +int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(struct ssl_st *ssl, + SSL_SESSION *sess); +void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, + void (*remove_session_cb)(struct ssl_ctx_st *ctx, SSL_SESSION *sess)); +void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(struct ssl_ctx_st *ctx, + SSL_SESSION *sess); +void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, + SSL_SESSION *(*get_session_cb)(struct ssl_st *ssl, unsigned char *data, + int len, int *copy)); +SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(struct ssl_st *ssl, + unsigned char *Data, int len, int *copy); +void SSL_CTX_set_info_callback(SSL_CTX *ctx, void (*cb)(const SSL *ssl, + int type, int val)); +void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl, int type, + int val); +void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, + int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey)); +int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509, + EVP_PKEY **pkey); +#ifndef OPENSSL_NO_ENGINE +int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e); +#endif +void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, + int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, + unsigned int *cookie_len)); +void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, + int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, + unsigned int cookie_len)); +void +SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s, int (*cb)(SSL *ssl, + const unsigned char **out, unsigned int *outlen, void *arg), void *arg); +void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s, int (*cb)(SSL *ssl, + unsigned char **out, unsigned char *outlen, const unsigned char *in, + unsigned int inlen, void *arg), void *arg); + +int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, const unsigned char *client, + unsigned int client_len); +void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, + unsigned *len); + +#define OPENSSL_NPN_UNSUPPORTED 0 +#define OPENSSL_NPN_NEGOTIATED 1 +#define OPENSSL_NPN_NO_OVERLAP 2 + +int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, + unsigned int protos_len); +int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, + unsigned int protos_len); +void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, + int (*cb)(SSL *ssl, const unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, void *arg), void *arg); +void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, + unsigned int *len); + +#define SSL_NOTHING 1 +#define SSL_WRITING 2 +#define SSL_READING 3 +#define SSL_X509_LOOKUP 4 + +/* These will only be used when doing non-blocking IO */ +#define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING) +#define SSL_want_read(s) (SSL_want(s) == SSL_READING) +#define SSL_want_write(s) (SSL_want(s) == SSL_WRITING) +#define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP) + +#define SSL_MAC_FLAG_READ_MAC_STREAM 1 +#define SSL_MAC_FLAG_WRITE_MAC_STREAM 2 + +#ifndef OPENSSL_NO_SSL_INTERN + +struct ssl_st { + /* protocol version + * (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION, DTLS1_VERSION) + */ + int version; + int type; /* SSL_ST_CONNECT or SSL_ST_ACCEPT */ + + const SSL_METHOD *method; /* SSLv3 */ + + /* There are 2 BIO's even though they are normally both the + * same. This is so data can be read and written to different + * handlers */ + +#ifndef OPENSSL_NO_BIO + BIO *rbio; /* used by SSL_read */ + BIO *wbio; /* used by SSL_write */ + BIO *bbio; /* used during session-id reuse to concatenate + * messages */ +#else + char *rbio; /* used by SSL_read */ + char *wbio; /* used by SSL_write */ + char *bbio; +#endif + /* This holds a variable that indicates what we were doing + * when a 0 or -1 is returned. This is needed for + * non-blocking IO so we know what request needs re-doing when + * in SSL_accept or SSL_connect */ + int rwstate; + + /* true when we are actually in SSL_accept() or SSL_connect() */ + int in_handshake; + int (*handshake_func)(SSL *); + + /* Imagine that here's a boolean member "init" that is + * switched as soon as SSL_set_{accept/connect}_state + * is called for the first time, so that "state" and + * "handshake_func" are properly initialized. But as + * handshake_func is == 0 until then, we use this + * test instead of an "init" member. + */ + + int server; /* are we the server side? - mostly used by SSL_clear*/ + + int new_session;/* Generate a new session or reuse an old one. + * NB: For servers, the 'new' session may actually be a previously + * cached session or even the previous session unless + * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */ + int quiet_shutdown;/* don't send shutdown packets */ + int shutdown; /* we have shut things down, 0x01 sent, 0x02 + * for received */ + int state; /* where we are */ + int rstate; /* where we are when reading */ + + BUF_MEM *init_buf; /* buffer used during init */ + void *init_msg; /* pointer to handshake message body, set by ssl3_get_message() */ + int init_num; /* amount read/written */ + int init_off; /* amount read/written */ + + /* used internally to point at a raw packet */ + unsigned char *packet; + unsigned int packet_length; + + struct ssl3_state_st *s3; /* SSLv3 variables */ + struct dtls1_state_st *d1; /* DTLSv1 variables */ + + int read_ahead; /* Read as many input bytes as possible + * (for non-blocking reads) */ + + /* callback that allows applications to peek at protocol messages */ + void (*msg_callback)(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); + void *msg_callback_arg; + + int hit; /* reusing a previous session */ + + X509_VERIFY_PARAM *param; + + /* crypto */ + STACK_OF(SSL_CIPHER) *cipher_list; + STACK_OF(SSL_CIPHER) *cipher_list_by_id; + + /* These are the ones being used, the ones in SSL_SESSION are + * the ones to be 'copied' into these ones */ + int mac_flags; + + SSL_AEAD_CTX *aead_read_ctx; /* AEAD context. If non-NULL, then + enc_read_ctx and read_hash are + ignored. */ + + EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */ + EVP_MD_CTX *read_hash; /* used for mac generation */ + + SSL_AEAD_CTX *aead_write_ctx; /* AEAD context. If non-NULL, then + enc_write_ctx and write_hash are + ignored. */ + + EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ + EVP_MD_CTX *write_hash; /* used for mac generation */ + + /* session info */ + + /* client cert? */ + /* This is used to hold the server certificate used */ + struct cert_st /* CERT */ *cert; + + /* the session_id_context is used to ensure sessions are only reused + * in the appropriate context */ + unsigned int sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + + /* This can also be in the session once a session is established */ + SSL_SESSION *session; + + /* Default generate session ID callback. */ + GEN_SESSION_CB generate_session_id; + + /* Used in SSL2 and SSL3 */ + int verify_mode; /* 0 don't care about verify failure. + * 1 fail if verify fails */ + int (*verify_callback)(int ok,X509_STORE_CTX *ctx); /* fail if callback returns 0 */ + + void (*info_callback)(const SSL *ssl,int type,int val); /* optional informational callback */ + + int error; /* error bytes to be written */ + int error_code; /* actual code */ + + + + SSL_CTX *ctx; + /* set this flag to 1 and a sleep(1) is put into all SSL_read() + * and SSL_write() calls, good for nbio debuging :-) */ + int debug; + + + /* extra application data */ + long verify_result; + CRYPTO_EX_DATA ex_data; + + /* for server side, keep the list of CA_dn we can use */ + STACK_OF(X509_NAME) *client_CA; + + int references; + unsigned long options; /* protocol behaviour */ + unsigned long mode; /* API behaviour */ + long max_cert_list; + int first_packet; + int client_version; /* what was passed, used for + * SSLv3/TLS rollback check */ + unsigned int max_send_fragment; + /* TLS extension debug callback */ + void (*tlsext_debug_cb)(SSL *s, int client_server, int type, + unsigned char *data, int len, void *arg); + void *tlsext_debug_arg; + char *tlsext_hostname; + int servername_done; /* no further mod of servername + 0 : call the servername extension callback. + 1 : prepare 2, allow last ack just after in server callback. + 2 : don't call servername callback, no ack in server hello + */ + /* certificate status request info */ + /* Status type or -1 if no status type */ + int tlsext_status_type; + /* Expect OCSP CertificateStatus message */ + int tlsext_status_expected; + /* OCSP status request only */ + STACK_OF(OCSP_RESPID) *tlsext_ocsp_ids; + X509_EXTENSIONS *tlsext_ocsp_exts; + /* OCSP response received or to be sent */ + unsigned char *tlsext_ocsp_resp; + int tlsext_ocsp_resplen; + + /* RFC4507 session ticket expected to be received or sent */ + int tlsext_ticket_expected; + size_t tlsext_ecpointformatlist_length; + uint8_t *tlsext_ecpointformatlist; /* our list */ + size_t tlsext_ellipticcurvelist_length; + uint16_t *tlsext_ellipticcurvelist; /* our list */ + + /* TLS Session Ticket extension override */ + TLS_SESSION_TICKET_EXT *tlsext_session_ticket; + + /* TLS Session Ticket extension callback */ + tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb; + void *tls_session_ticket_ext_cb_arg; + + /* TLS pre-shared secret session resumption */ + tls_session_secret_cb_fn tls_session_secret_cb; + void *tls_session_secret_cb_arg; + + SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */ + + /* Next protocol negotiation. For the client, this is the protocol that + * we sent in NextProtocol and is set when handling ServerHello + * extensions. + * + * For a server, this is the client's selected_protocol from + * NextProtocol and is set when handling the NextProtocol message, + * before the Finished message. */ + unsigned char *next_proto_negotiated; + unsigned char next_proto_negotiated_len; + +#define session_ctx initial_ctx + + STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; /* What we'll do */ + SRTP_PROTECTION_PROFILE *srtp_profile; /* What's been chosen */ + + unsigned int tlsext_heartbeat; /* Is use of the Heartbeat extension negotiated? + 0: disabled + 1: enabled + 2: enabled, but not allowed to send Requests + */ + unsigned int tlsext_hb_pending; /* Indicates if a HeartbeatRequest is in flight */ + unsigned int tlsext_hb_seq; /* HeartbeatRequest sequence number */ + + /* Client list of supported protocols in wire format. */ + unsigned char *alpn_client_proto_list; + unsigned int alpn_client_proto_list_len; + + int renegotiate;/* 1 if we are renegotiating. + * 2 if we are a server and are inside a handshake + * (i.e. not just sending a HelloRequest) */ + +}; + +#endif + +#ifdef __cplusplus +} +#endif + +#include +#include +#include /* This is mostly sslv3 with a few tweaks */ +#include /* Datagram TLS */ +#include +#include /* Support for the use_srtp extension */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* compatibility */ +#define SSL_set_app_data(s,arg) (SSL_set_ex_data(s,0,(char *)arg)) +#define SSL_get_app_data(s) (SSL_get_ex_data(s,0)) +#define SSL_SESSION_set_app_data(s,a) (SSL_SESSION_set_ex_data(s,0,(char *)a)) +#define SSL_SESSION_get_app_data(s) (SSL_SESSION_get_ex_data(s,0)) +#define SSL_CTX_get_app_data(ctx) (SSL_CTX_get_ex_data(ctx,0)) +#define SSL_CTX_set_app_data(ctx,arg) (SSL_CTX_set_ex_data(ctx,0,(char *)arg)) + +/* The following are the possible values for ssl->state are are + * used to indicate where we are up to in the SSL connection establishment. + * The macros that follow are about the only things you should need to use + * and even then, only when using non-blocking IO. + * It can also be useful to work out where you were when the connection + * failed */ + +#define SSL_ST_CONNECT 0x1000 +#define SSL_ST_ACCEPT 0x2000 +#define SSL_ST_MASK 0x0FFF +#define SSL_ST_INIT (SSL_ST_CONNECT|SSL_ST_ACCEPT) +#define SSL_ST_BEFORE 0x4000 +#define SSL_ST_OK 0x03 +#define SSL_ST_RENEGOTIATE (0x04|SSL_ST_INIT) + +#define SSL_CB_LOOP 0x01 +#define SSL_CB_EXIT 0x02 +#define SSL_CB_READ 0x04 +#define SSL_CB_WRITE 0x08 +#define SSL_CB_ALERT 0x4000 /* used in callback */ +#define SSL_CB_READ_ALERT (SSL_CB_ALERT|SSL_CB_READ) +#define SSL_CB_WRITE_ALERT (SSL_CB_ALERT|SSL_CB_WRITE) +#define SSL_CB_ACCEPT_LOOP (SSL_ST_ACCEPT|SSL_CB_LOOP) +#define SSL_CB_ACCEPT_EXIT (SSL_ST_ACCEPT|SSL_CB_EXIT) +#define SSL_CB_CONNECT_LOOP (SSL_ST_CONNECT|SSL_CB_LOOP) +#define SSL_CB_CONNECT_EXIT (SSL_ST_CONNECT|SSL_CB_EXIT) +#define SSL_CB_HANDSHAKE_START 0x10 +#define SSL_CB_HANDSHAKE_DONE 0x20 + +/* Is the SSL_connection established? */ +#define SSL_get_state(a) SSL_state(a) +#define SSL_is_init_finished(a) (SSL_state(a) == SSL_ST_OK) +#define SSL_in_init(a) (SSL_state(a)&SSL_ST_INIT) +#define SSL_in_before(a) (SSL_state(a)&SSL_ST_BEFORE) +#define SSL_in_connect_init(a) (SSL_state(a)&SSL_ST_CONNECT) +#define SSL_in_accept_init(a) (SSL_state(a)&SSL_ST_ACCEPT) + +/* The following 2 states are kept in ssl->rstate when reads fail, + * you should not need these */ +#define SSL_ST_READ_HEADER 0xF0 +#define SSL_ST_READ_BODY 0xF1 +#define SSL_ST_READ_DONE 0xF2 + +/* Obtain latest Finished message + * -- that we sent (SSL_get_finished) + * -- that we expected from peer (SSL_get_peer_finished). + * Returns length (0 == no Finished so far), copies up to 'count' bytes. */ +size_t SSL_get_finished(const SSL *s, void *buf, size_t count); +size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count); + +/* use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 2 options + * are 'ored' with SSL_VERIFY_PEER if they are desired */ +#define SSL_VERIFY_NONE 0x00 +#define SSL_VERIFY_PEER 0x01 +#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 +#define SSL_VERIFY_CLIENT_ONCE 0x04 + +#define OpenSSL_add_ssl_algorithms() SSL_library_init() +#define SSLeay_add_ssl_algorithms() SSL_library_init() + +/* More backward compatibility */ +#define SSL_get_cipher(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +#define SSL_get_cipher_bits(s,np) \ + SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np) +#define SSL_get_cipher_version(s) \ + SSL_CIPHER_get_version(SSL_get_current_cipher(s)) +#define SSL_get_cipher_name(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +#define SSL_get_time(a) SSL_SESSION_get_time(a) +#define SSL_set_time(a,b) SSL_SESSION_set_time((a),(b)) +#define SSL_get_timeout(a) SSL_SESSION_get_timeout(a) +#define SSL_set_timeout(a,b) SSL_SESSION_set_timeout((a),(b)) + +#define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id) +#define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id) + +DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) + +#define SSL_AD_REASON_OFFSET 1000 /* offset to get SSL_R_... value from SSL_AD_... */ + +/* These alert types are for SSLv3 and TLSv1 */ +#define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY +#define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE /* fatal */ +#define SSL_AD_BAD_RECORD_MAC SSL3_AD_BAD_RECORD_MAC /* fatal */ +#define SSL_AD_DECRYPTION_FAILED TLS1_AD_DECRYPTION_FAILED +#define SSL_AD_RECORD_OVERFLOW TLS1_AD_RECORD_OVERFLOW +#define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE/* fatal */ +#define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE/* fatal */ +#define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE /* Not for TLS */ +#define SSL_AD_BAD_CERTIFICATE SSL3_AD_BAD_CERTIFICATE +#define SSL_AD_UNSUPPORTED_CERTIFICATE SSL3_AD_UNSUPPORTED_CERTIFICATE +#define SSL_AD_CERTIFICATE_REVOKED SSL3_AD_CERTIFICATE_REVOKED +#define SSL_AD_CERTIFICATE_EXPIRED SSL3_AD_CERTIFICATE_EXPIRED +#define SSL_AD_CERTIFICATE_UNKNOWN SSL3_AD_CERTIFICATE_UNKNOWN +#define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER /* fatal */ +#define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA /* fatal */ +#define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED /* fatal */ +#define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR /* fatal */ +#define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR +#define SSL_AD_EXPORT_RESTRICTION TLS1_AD_EXPORT_RESTRICTION/* fatal */ +#define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION /* fatal */ +#define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY/* fatal */ +#define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR /* fatal */ +#define SSL_AD_INAPPROPRIATE_FALLBACK TLS1_AD_INAPPROPRIATE_FALLBACK /* fatal */ +#define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED +#define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION +#define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION +#define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE +#define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME +#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE +#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE +#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */ + +#define SSL_ERROR_NONE 0 +#define SSL_ERROR_SSL 1 +#define SSL_ERROR_WANT_READ 2 +#define SSL_ERROR_WANT_WRITE 3 +#define SSL_ERROR_WANT_X509_LOOKUP 4 +#define SSL_ERROR_SYSCALL 5 /* look at error stack/return value/errno */ +#define SSL_ERROR_ZERO_RETURN 6 +#define SSL_ERROR_WANT_CONNECT 7 +#define SSL_ERROR_WANT_ACCEPT 8 + +#define SSL_CTRL_NEED_TMP_RSA 1 +#define SSL_CTRL_SET_TMP_RSA 2 +#define SSL_CTRL_SET_TMP_DH 3 +#define SSL_CTRL_SET_TMP_ECDH 4 +#define SSL_CTRL_SET_TMP_RSA_CB 5 +#define SSL_CTRL_SET_TMP_DH_CB 6 +#define SSL_CTRL_SET_TMP_ECDH_CB 7 + +#define SSL_CTRL_GET_SESSION_REUSED 8 +#define SSL_CTRL_GET_CLIENT_CERT_REQUEST 9 +#define SSL_CTRL_GET_NUM_RENEGOTIATIONS 10 +#define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS 11 +#define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS 12 +#define SSL_CTRL_GET_FLAGS 13 +#define SSL_CTRL_EXTRA_CHAIN_CERT 14 + +#define SSL_CTRL_SET_MSG_CALLBACK 15 +#define SSL_CTRL_SET_MSG_CALLBACK_ARG 16 + +/* only applies to datagram connections */ +#define SSL_CTRL_SET_MTU 17 +/* Stats */ +#define SSL_CTRL_SESS_NUMBER 20 +#define SSL_CTRL_SESS_CONNECT 21 +#define SSL_CTRL_SESS_CONNECT_GOOD 22 +#define SSL_CTRL_SESS_CONNECT_RENEGOTIATE 23 +#define SSL_CTRL_SESS_ACCEPT 24 +#define SSL_CTRL_SESS_ACCEPT_GOOD 25 +#define SSL_CTRL_SESS_ACCEPT_RENEGOTIATE 26 +#define SSL_CTRL_SESS_HIT 27 +#define SSL_CTRL_SESS_CB_HIT 28 +#define SSL_CTRL_SESS_MISSES 29 +#define SSL_CTRL_SESS_TIMEOUTS 30 +#define SSL_CTRL_SESS_CACHE_FULL 31 +#define SSL_CTRL_OPTIONS 32 +#define SSL_CTRL_MODE 33 + +#define SSL_CTRL_GET_READ_AHEAD 40 +#define SSL_CTRL_SET_READ_AHEAD 41 +#define SSL_CTRL_SET_SESS_CACHE_SIZE 42 +#define SSL_CTRL_GET_SESS_CACHE_SIZE 43 +#define SSL_CTRL_SET_SESS_CACHE_MODE 44 +#define SSL_CTRL_GET_SESS_CACHE_MODE 45 + +#define SSL_CTRL_GET_MAX_CERT_LIST 50 +#define SSL_CTRL_SET_MAX_CERT_LIST 51 + +#define SSL_CTRL_SET_MAX_SEND_FRAGMENT 52 + +/* see tls1.h for macros based on these */ +#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 53 +#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG 54 +#define SSL_CTRL_SET_TLSEXT_HOSTNAME 55 +#define SSL_CTRL_SET_TLSEXT_DEBUG_CB 56 +#define SSL_CTRL_SET_TLSEXT_DEBUG_ARG 57 +#define SSL_CTRL_GET_TLSEXT_TICKET_KEYS 58 +#define SSL_CTRL_SET_TLSEXT_TICKET_KEYS 59 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB 63 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG 64 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE 65 +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS 66 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS 67 +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS 68 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS 69 +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP 70 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP 71 + +#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72 + +#define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB 75 +#define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB 76 +#define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB 77 + +#define SSL_CTRL_SET_SRP_ARG 78 +#define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME 79 +#define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH 80 +#define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD 81 + +#define DTLS_CTRL_GET_TIMEOUT 73 +#define DTLS_CTRL_HANDLE_TIMEOUT 74 +#define DTLS_CTRL_LISTEN 75 + +#define SSL_CTRL_GET_RI_SUPPORT 76 +#define SSL_CTRL_CLEAR_OPTIONS 77 +#define SSL_CTRL_CLEAR_MODE 78 + +#define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82 +#define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83 + +#define SSL_CTRL_SET_ECDH_AUTO 94 + +#define SSL_CTRL_SET_DH_AUTO 118 + +#define DTLSv1_get_timeout(ssl, arg) \ + SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg) +#define DTLSv1_handle_timeout(ssl) \ + SSL_ctrl(ssl,DTLS_CTRL_HANDLE_TIMEOUT,0, NULL) +#define DTLSv1_listen(ssl, peer) \ + SSL_ctrl(ssl,DTLS_CTRL_LISTEN,0, (void *)peer) + +#define SSL_session_reused(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL) +#define SSL_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL) +#define SSL_clear_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL) +#define SSL_total_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL) + +#define SSL_CTX_need_tmp_RSA(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_NEED_TMP_RSA,0,NULL) +#define SSL_CTX_set_tmp_rsa(ctx,rsa) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa) +#define SSL_CTX_set_tmp_dh(ctx,dh) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)dh) +#define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh) +#define SSL_CTX_set_dh_auto(ctx, onoff) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_DH_AUTO,onoff,NULL) +#define SSL_CTX_set_ecdh_auto(ctx, onoff) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL) + +#define SSL_need_tmp_RSA(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_NEED_TMP_RSA,0,NULL) +#define SSL_set_tmp_rsa(ssl,rsa) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa) +#define SSL_set_tmp_dh(ssl,dh) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)dh) +#define SSL_set_tmp_ecdh(ssl,ecdh) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh) +#define SSL_set_dh_auto(s, onoff) \ + SSL_ctrl(s,SSL_CTRL_SET_DH_AUTO,onoff,NULL) +#define SSL_set_ecdh_auto(s, onoff) \ + SSL_ctrl(s,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL) + +#define SSL_CTX_add_extra_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509) +#define SSL_CTX_get_extra_chain_certs(ctx,px509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,0,px509) +#define SSL_CTX_clear_extra_chain_certs(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS,0,NULL) + +#ifndef OPENSSL_NO_BIO +BIO_METHOD *BIO_f_ssl(void); +BIO *BIO_new_ssl(SSL_CTX *ctx, int client); +BIO *BIO_new_ssl_connect(SSL_CTX *ctx); +BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx); +int BIO_ssl_copy_session_id(BIO *to, BIO *from); +void BIO_ssl_shutdown(BIO *ssl_bio); +#endif + +int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str); +SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth); +void SSL_CTX_free(SSL_CTX *); +long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); +long SSL_CTX_get_timeout(const SSL_CTX *ctx); +X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *); +void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *); +int SSL_want(const SSL *s); +int SSL_clear(SSL *s); + +void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm); + +const SSL_CIPHER *SSL_get_current_cipher(const SSL *s); +const SSL_CIPHER *SSL_CIPHER_get_by_id(unsigned int id); +const SSL_CIPHER *SSL_CIPHER_get_by_value(uint16_t value); +int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits); +char * SSL_CIPHER_get_version(const SSL_CIPHER *c); +const char * SSL_CIPHER_get_name(const SSL_CIPHER *c); +unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c); +uint16_t SSL_CIPHER_get_value(const SSL_CIPHER *c); + +int SSL_get_fd(const SSL *s); +int SSL_get_rfd(const SSL *s); +int SSL_get_wfd(const SSL *s); +const char * SSL_get_cipher_list(const SSL *s, int n); +char * SSL_get_shared_ciphers(const SSL *s, char *buf, int len); +int SSL_get_read_ahead(const SSL * s); +int SSL_pending(const SSL *s); +int SSL_set_fd(SSL *s, int fd); +int SSL_set_rfd(SSL *s, int fd); +int SSL_set_wfd(SSL *s, int fd); +#ifndef OPENSSL_NO_BIO +void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio); +BIO * SSL_get_rbio(const SSL *s); +BIO * SSL_get_wbio(const SSL *s); +#endif +int SSL_set_cipher_list(SSL *s, const char *str); +void SSL_set_read_ahead(SSL *s, int yes); +int SSL_get_verify_mode(const SSL *s); +int SSL_get_verify_depth(const SSL *s); +int (*SSL_get_verify_callback(const SSL *s))(int, X509_STORE_CTX *); +void SSL_set_verify(SSL *s, int mode, + int (*callback)(int ok, X509_STORE_CTX *ctx)); +void SSL_set_verify_depth(SSL *s, int depth); +int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa); +int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len); +int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey); +int SSL_use_PrivateKey_ASN1(int pk, SSL *ssl, const unsigned char *d, long len); +int SSL_use_certificate(SSL *ssl, X509 *x); +int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len); + +int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type); +int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type); +int SSL_use_certificate_file(SSL *ssl, const char *file, int type); +int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type); +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type); +int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type); +int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); /* PEM type */ +int SSL_CTX_use_certificate_chain_mem(SSL_CTX *ctx, void *buf, int len); +STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file); +int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *file); +int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *dir); + +void SSL_load_error_strings(void ); +const char *SSL_state_string(const SSL *s); +const char *SSL_rstate_string(const SSL *s); +const char *SSL_state_string_long(const SSL *s); +const char *SSL_rstate_string_long(const SSL *s); +long SSL_SESSION_get_time(const SSL_SESSION *s); +long SSL_SESSION_set_time(SSL_SESSION *s, long t); +long SSL_SESSION_get_timeout(const SSL_SESSION *s); +long SSL_SESSION_set_timeout(SSL_SESSION *s, long t); +void SSL_copy_session_id(SSL *to, const SSL *from); +X509 *SSL_SESSION_get0_peer(SSL_SESSION *s); +int +SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, +unsigned int sid_ctx_len); + +SSL_SESSION *SSL_SESSION_new(void); +const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, + unsigned int *len); +unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s); +int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *ses); +#ifndef OPENSSL_NO_BIO +int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses); +#endif +void SSL_SESSION_free(SSL_SESSION *ses); +int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp); +int SSL_set_session(SSL *to, SSL_SESSION *session); +int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c); +int SSL_CTX_remove_session(SSL_CTX *, SSL_SESSION *c); +int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB); +int SSL_set_generate_session_id(SSL *, GEN_SESSION_CB); +int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, + unsigned int id_len); +SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, + long length); + +#ifdef HEADER_X509_H +X509 * SSL_get_peer_certificate(const SSL *s); +#endif + +STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s); + +int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); +int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); +int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int, X509_STORE_CTX *); +void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, + int (*callback)(int, X509_STORE_CTX *)); +void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); +void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *, void *), void *arg); +int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len); +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); +int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, const unsigned char *d, long len); +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d); + +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb); +void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u); + +int SSL_CTX_check_private_key(const SSL_CTX *ctx); +int SSL_check_private_key(const SSL *ctx); + +int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx, unsigned int sid_ctx_len); + +SSL *SSL_new(SSL_CTX *ctx); +int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, unsigned int sid_ctx_len); + +int SSL_CTX_set_purpose(SSL_CTX *s, int purpose); +int SSL_set_purpose(SSL *s, int purpose); +int SSL_CTX_set_trust(SSL_CTX *s, int trust); +int SSL_set_trust(SSL *s, int trust); + +int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm); +int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm); + + +void SSL_free(SSL *ssl); +int SSL_accept(SSL *ssl); +int SSL_connect(SSL *ssl); +int SSL_read(SSL *ssl, void *buf, int num); +int SSL_peek(SSL *ssl, void *buf, int num); +int SSL_write(SSL *ssl, const void *buf, int num); +long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg); +long SSL_callback_ctrl(SSL *, int, void (*)(void)); +long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg); +long SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void)); + +int SSL_get_error(const SSL *s, int ret_code); +const char *SSL_get_version(const SSL *s); + +/* This sets the 'default' SSL version that SSL_new() will create */ +int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); + +const SSL_METHOD *SSLv23_method(void); /* SSLv3 or TLSv1.* */ +const SSL_METHOD *SSLv23_server_method(void); /* SSLv3 or TLSv1.* */ +const SSL_METHOD *SSLv23_client_method(void); /* SSLv3 or TLSv1.* */ + +const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */ +const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */ +const SSL_METHOD *TLSv1_client_method(void); /* TLSv1.0 */ + +const SSL_METHOD *TLSv1_1_method(void); /* TLSv1.1 */ +const SSL_METHOD *TLSv1_1_server_method(void); /* TLSv1.1 */ +const SSL_METHOD *TLSv1_1_client_method(void); /* TLSv1.1 */ + +const SSL_METHOD *TLSv1_2_method(void); /* TLSv1.2 */ +const SSL_METHOD *TLSv1_2_server_method(void); /* TLSv1.2 */ +const SSL_METHOD *TLSv1_2_client_method(void); /* TLSv1.2 */ + +const SSL_METHOD *TLS_method(void); /* TLS v1.0 or later */ +const SSL_METHOD *TLS_server_method(void); /* TLS v1.0 or later */ +const SSL_METHOD *TLS_client_method(void); /* TLS v1.0 or later */ + +const SSL_METHOD *DTLSv1_method(void); /* DTLSv1.0 */ +const SSL_METHOD *DTLSv1_server_method(void); /* DTLSv1.0 */ +const SSL_METHOD *DTLSv1_client_method(void); /* DTLSv1.0 */ + +STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s); + +int SSL_do_handshake(SSL *s); +int SSL_renegotiate(SSL *s); +int SSL_renegotiate_abbreviated(SSL *s); +int SSL_renegotiate_pending(SSL *s); +int SSL_shutdown(SSL *s); + +const SSL_METHOD *SSL_get_ssl_method(SSL *s); +int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method); +const char *SSL_alert_type_string_long(int value); +const char *SSL_alert_type_string(int value); +const char *SSL_alert_desc_string_long(int value); +const char *SSL_alert_desc_string(int value); + +void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list); +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); +STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s); +STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s); +int SSL_add_client_CA(SSL *ssl, X509 *x); +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); + +void SSL_set_connect_state(SSL *s); +void SSL_set_accept_state(SSL *s); + +long SSL_get_default_timeout(const SSL *s); + +int SSL_library_init(void ); + +char *SSL_CIPHER_description(const SSL_CIPHER *, char *buf, int size); +STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk); + +SSL *SSL_dup(SSL *ssl); + +X509 *SSL_get_certificate(const SSL *ssl); +/* EVP_PKEY */ struct evp_pkey_st *SSL_get_privatekey(SSL *ssl); + +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx,int mode); +int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); +void SSL_set_quiet_shutdown(SSL *ssl,int mode); +int SSL_get_quiet_shutdown(const SSL *ssl); +void SSL_set_shutdown(SSL *ssl,int mode); +int SSL_get_shutdown(const SSL *ssl); +int SSL_version(const SSL *ssl); +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, + const char *CApath); +int SSL_CTX_load_verify_mem(SSL_CTX *ctx, void *buf, int len); +#define SSL_get0_session SSL_get_session /* just peek at pointer */ +SSL_SESSION *SSL_get_session(const SSL *ssl); +SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */ +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx); +void SSL_set_info_callback(SSL *ssl, + void (*cb)(const SSL *ssl, int type, int val)); +void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl, int type, int val); +int SSL_state(const SSL *ssl); +void SSL_set_state(SSL *ssl, int state); + +void SSL_set_verify_result(SSL *ssl, long v); +long SSL_get_verify_result(const SSL *ssl); + +int SSL_set_ex_data(SSL *ssl, int idx, void *data); +void *SSL_get_ex_data(const SSL *ssl, int idx); +int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); + +int SSL_SESSION_set_ex_data(SSL_SESSION *ss, int idx, void *data); +void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss, int idx); +int SSL_SESSION_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); + +int SSL_CTX_set_ex_data(SSL_CTX *ssl, int idx, void *data); +void *SSL_CTX_get_ex_data(const SSL_CTX *ssl, int idx); +int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); + +int SSL_get_ex_data_X509_STORE_CTX_idx(void ); + +#define SSL_CTX_sess_set_cache_size(ctx,t) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL) +#define SSL_CTX_sess_get_cache_size(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_SIZE,0,NULL) +#define SSL_CTX_set_session_cache_mode(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL) +#define SSL_CTX_get_session_cache_mode(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL) + +#define SSL_CTX_get_default_read_ahead(ctx) SSL_CTX_get_read_ahead(ctx) +#define SSL_CTX_set_default_read_ahead(ctx,m) SSL_CTX_set_read_ahead(ctx,m) +#define SSL_CTX_get_read_ahead(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL) +#define SSL_CTX_set_read_ahead(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL) +#define SSL_CTX_get_max_cert_list(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) +#define SSL_CTX_set_max_cert_list(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) +#define SSL_get_max_cert_list(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) +#define SSL_set_max_cert_list(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) + +#define SSL_CTX_set_max_send_fragment(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) +#define SSL_set_max_send_fragment(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) + +/* NB: the keylength is only applicable when is_export is true */ +void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx, + RSA *(*cb)(SSL *ssl, int is_export, int keylength)); + +void SSL_set_tmp_rsa_callback(SSL *ssl, + RSA *(*cb)(SSL *ssl, int is_export, int keylength)); +void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, + DH *(*dh)(SSL *ssl, int is_export, int keylength)); +void SSL_set_tmp_dh_callback(SSL *ssl, + DH *(*dh)(SSL *ssl, int is_export, int keylength)); +void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx, + EC_KEY *(*ecdh)(SSL *ssl, int is_export, int keylength)); +void SSL_set_tmp_ecdh_callback(SSL *ssl, + EC_KEY *(*ecdh)(SSL *ssl, int is_export, int keylength)); + +const void *SSL_get_current_compression(SSL *s); +const void *SSL_get_current_expansion(SSL *s); + +const char *SSL_COMP_get_name(const void *comp); +void *SSL_COMP_get_compression_methods(void); +int SSL_COMP_add_compression_method(int id, void *cm); + +/* TLS extensions functions */ +int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len); + +int SSL_set_session_ticket_ext_cb(SSL *s, + tls_session_ticket_ext_cb_fn cb, void *arg); + +/* Pre-shared secret session resumption functions */ +int SSL_set_session_secret_cb(SSL *s, + tls_session_secret_cb_fn tls_session_secret_cb, void *arg); + +void SSL_set_debug(SSL *s, int debug); +int SSL_cache_hit(SSL *s); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_SSL_strings(void); + +/* Error codes for the SSL functions. */ + +/* Function codes. */ +#define SSL_F_CLIENT_CERTIFICATE 100 +#define SSL_F_CLIENT_FINISHED 167 +#define SSL_F_CLIENT_HELLO 101 +#define SSL_F_CLIENT_MASTER_KEY 102 +#define SSL_F_D2I_SSL_SESSION 103 +#define SSL_F_DO_DTLS1_WRITE 245 +#define SSL_F_DO_SSL3_WRITE 104 +#define SSL_F_DTLS1_ACCEPT 246 +#define SSL_F_DTLS1_ADD_CERT_TO_BUF 295 +#define SSL_F_DTLS1_BUFFER_RECORD 247 +#define SSL_F_DTLS1_CHECK_TIMEOUT_NUM 316 +#define SSL_F_DTLS1_CLIENT_HELLO 248 +#define SSL_F_DTLS1_CONNECT 249 +#define SSL_F_DTLS1_ENC 250 +#define SSL_F_DTLS1_GET_HELLO_VERIFY 251 +#define SSL_F_DTLS1_GET_MESSAGE 252 +#define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT 253 +#define SSL_F_DTLS1_GET_RECORD 254 +#define SSL_F_DTLS1_HANDLE_TIMEOUT 297 +#define SSL_F_DTLS1_HEARTBEAT 305 +#define SSL_F_DTLS1_OUTPUT_CERT_CHAIN 255 +#define SSL_F_DTLS1_PREPROCESS_FRAGMENT 288 +#define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256 +#define SSL_F_DTLS1_PROCESS_RECORD 257 +#define SSL_F_DTLS1_READ_BYTES 258 +#define SSL_F_DTLS1_READ_FAILED 259 +#define SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST 260 +#define SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE 261 +#define SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE 262 +#define SSL_F_DTLS1_SEND_CLIENT_VERIFY 263 +#define SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST 264 +#define SSL_F_DTLS1_SEND_SERVER_CERTIFICATE 265 +#define SSL_F_DTLS1_SEND_SERVER_HELLO 266 +#define SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE 267 +#define SSL_F_DTLS1_WRITE_APP_DATA_BYTES 268 +#define SSL_F_GET_CLIENT_FINISHED 105 +#define SSL_F_GET_CLIENT_HELLO 106 +#define SSL_F_GET_CLIENT_MASTER_KEY 107 +#define SSL_F_GET_SERVER_FINISHED 108 +#define SSL_F_GET_SERVER_HELLO 109 +#define SSL_F_GET_SERVER_VERIFY 110 +#define SSL_F_I2D_SSL_SESSION 111 +#define SSL_F_READ_N 112 +#define SSL_F_REQUEST_CERTIFICATE 113 +#define SSL_F_SERVER_FINISH 239 +#define SSL_F_SERVER_HELLO 114 +#define SSL_F_SERVER_VERIFY 240 +#define SSL_F_SSL23_ACCEPT 115 +#define SSL_F_SSL23_CLIENT_HELLO 116 +#define SSL_F_SSL23_CONNECT 117 +#define SSL_F_SSL23_GET_CLIENT_HELLO 118 +#define SSL_F_SSL23_GET_SERVER_HELLO 119 +#define SSL_F_SSL23_PEEK 237 +#define SSL_F_SSL23_READ 120 +#define SSL_F_SSL23_WRITE 121 +#define SSL_F_SSL2_ACCEPT 122 +#define SSL_F_SSL2_CONNECT 123 +#define SSL_F_SSL2_ENC_INIT 124 +#define SSL_F_SSL2_GENERATE_KEY_MATERIAL 241 +#define SSL_F_SSL2_PEEK 234 +#define SSL_F_SSL2_READ 125 +#define SSL_F_SSL2_READ_INTERNAL 236 +#define SSL_F_SSL2_SET_CERTIFICATE 126 +#define SSL_F_SSL2_WRITE 127 +#define SSL_F_SSL3_ACCEPT 128 +#define SSL_F_SSL3_ADD_CERT_TO_BUF 296 +#define SSL_F_SSL3_CALLBACK_CTRL 233 +#define SSL_F_SSL3_CHANGE_CIPHER_STATE 129 +#define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM 130 +#define SSL_F_SSL3_CHECK_CLIENT_HELLO 304 +#define SSL_F_SSL3_CLIENT_HELLO 131 +#define SSL_F_SSL3_CONNECT 132 +#define SSL_F_SSL3_CTRL 213 +#define SSL_F_SSL3_CTX_CTRL 133 +#define SSL_F_SSL3_DIGEST_CACHED_RECORDS 293 +#define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC 292 +#define SSL_F_SSL3_ENC 134 +#define SSL_F_SSL3_GENERATE_KEY_BLOCK 238 +#define SSL_F_SSL3_GET_CERTIFICATE_REQUEST 135 +#define SSL_F_SSL3_GET_CERT_STATUS 289 +#define SSL_F_SSL3_GET_CERT_VERIFY 136 +#define SSL_F_SSL3_GET_CLIENT_CERTIFICATE 137 +#define SSL_F_SSL3_GET_CLIENT_HELLO 138 +#define SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE 139 +#define SSL_F_SSL3_GET_FINISHED 140 +#define SSL_F_SSL3_GET_KEY_EXCHANGE 141 +#define SSL_F_SSL3_GET_MESSAGE 142 +#define SSL_F_SSL3_GET_NEW_SESSION_TICKET 283 +#define SSL_F_SSL3_GET_NEXT_PROTO 306 +#define SSL_F_SSL3_GET_RECORD 143 +#define SSL_F_SSL3_GET_SERVER_CERTIFICATE 144 +#define SSL_F_SSL3_GET_SERVER_DONE 145 +#define SSL_F_SSL3_GET_SERVER_HELLO 146 +#define SSL_F_SSL3_HANDSHAKE_MAC 285 +#define SSL_F_SSL3_NEW_SESSION_TICKET 287 +#define SSL_F_SSL3_OUTPUT_CERT_CHAIN 147 +#define SSL_F_SSL3_PEEK 235 +#define SSL_F_SSL3_READ_BYTES 148 +#define SSL_F_SSL3_READ_N 149 +#define SSL_F_SSL3_SEND_CERTIFICATE_REQUEST 150 +#define SSL_F_SSL3_SEND_CLIENT_CERTIFICATE 151 +#define SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE 152 +#define SSL_F_SSL3_SEND_CLIENT_VERIFY 153 +#define SSL_F_SSL3_SEND_SERVER_CERTIFICATE 154 +#define SSL_F_SSL3_SEND_SERVER_HELLO 242 +#define SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE 155 +#define SSL_F_SSL3_SETUP_KEY_BLOCK 157 +#define SSL_F_SSL3_SETUP_READ_BUFFER 156 +#define SSL_F_SSL3_SETUP_WRITE_BUFFER 291 +#define SSL_F_SSL3_WRITE_BYTES 158 +#define SSL_F_SSL3_WRITE_PENDING 159 +#define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT 298 +#define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT 277 +#define SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT 307 +#define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK 215 +#define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK 216 +#define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT 299 +#define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT 278 +#define SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT 308 +#define SSL_F_SSL_BAD_METHOD 160 +#define SSL_F_SSL_BYTES_TO_CIPHER_LIST 161 +#define SSL_F_SSL_CERT_DUP 221 +#define SSL_F_SSL_CERT_INST 222 +#define SSL_F_SSL_CERT_INSTANTIATE 214 +#define SSL_F_SSL_CERT_NEW 162 +#define SSL_F_SSL_CHECK_PRIVATE_KEY 163 +#define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT 280 +#define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG 279 +#define SSL_F_SSL_CIPHER_PROCESS_RULESTR 230 +#define SSL_F_SSL_CIPHER_STRENGTH_SORT 231 +#define SSL_F_SSL_CLEAR 164 +#define SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD 165 +#define SSL_F_SSL_CREATE_CIPHER_LIST 166 +#define SSL_F_SSL_CTRL 232 +#define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY 168 +#define SSL_F_SSL_CTX_MAKE_PROFILES 309 +#define SSL_F_SSL_CTX_NEW 169 +#define SSL_F_SSL_CTX_SET_CIPHER_LIST 269 +#define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE 290 +#define SSL_F_SSL_CTX_SET_PURPOSE 226 +#define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT 219 +#define SSL_F_SSL_CTX_SET_SSL_VERSION 170 +#define SSL_F_SSL_CTX_SET_TRUST 229 +#define SSL_F_SSL_CTX_USE_CERTIFICATE 171 +#define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 172 +#define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE 220 +#define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE 173 +#define SSL_F_SSL_CTX_USE_PRIVATEKEY 174 +#define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1 175 +#define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE 176 +#define SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT 272 +#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY 177 +#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1 178 +#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE 179 +#define SSL_F_SSL_DO_HANDSHAKE 180 +#define SSL_F_SSL_GET_NEW_SESSION 181 +#define SSL_F_SSL_GET_PREV_SESSION 217 +#define SSL_F_SSL_GET_SERVER_SEND_CERT 182 +#define SSL_F_SSL_GET_SERVER_SEND_PKEY 317 +#define SSL_F_SSL_GET_SIGN_PKEY 183 +#define SSL_F_SSL_INIT_WBIO_BUFFER 184 +#define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185 +#define SSL_F_SSL_NEW 186 +#define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT 300 +#define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT 302 +#define SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT 310 +#define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT 301 +#define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT 303 +#define SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT 311 +#define SSL_F_SSL_PEEK 270 +#define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT 281 +#define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT 282 +#define SSL_F_SSL_READ 223 +#define SSL_F_SSL_RSA_PRIVATE_DECRYPT 187 +#define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 188 +#define SSL_F_SSL_SESSION_NEW 189 +#define SSL_F_SSL_SESSION_PRINT_FP 190 +#define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312 +#define SSL_F_SSL_SESS_CERT_NEW 225 +#define SSL_F_SSL_SET_CERT 191 +#define SSL_F_SSL_SET_CIPHER_LIST 271 +#define SSL_F_SSL_SET_FD 192 +#define SSL_F_SSL_SET_PKEY 193 +#define SSL_F_SSL_SET_PURPOSE 227 +#define SSL_F_SSL_SET_RFD 194 +#define SSL_F_SSL_SET_SESSION 195 +#define SSL_F_SSL_SET_SESSION_ID_CONTEXT 218 +#define SSL_F_SSL_SET_SESSION_TICKET_EXT 294 +#define SSL_F_SSL_SET_TRUST 228 +#define SSL_F_SSL_SET_WFD 196 +#define SSL_F_SSL_SHUTDOWN 224 +#define SSL_F_SSL_SRP_CTX_INIT 313 +#define SSL_F_SSL_UNDEFINED_CONST_FUNCTION 243 +#define SSL_F_SSL_UNDEFINED_FUNCTION 197 +#define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244 +#define SSL_F_SSL_USE_CERTIFICATE 198 +#define SSL_F_SSL_USE_CERTIFICATE_ASN1 199 +#define SSL_F_SSL_USE_CERTIFICATE_FILE 200 +#define SSL_F_SSL_USE_PRIVATEKEY 201 +#define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202 +#define SSL_F_SSL_USE_PRIVATEKEY_FILE 203 +#define SSL_F_SSL_USE_PSK_IDENTITY_HINT 273 +#define SSL_F_SSL_USE_RSAPRIVATEKEY 204 +#define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1 205 +#define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE 206 +#define SSL_F_SSL_VERIFY_CERT_CHAIN 207 +#define SSL_F_SSL_WRITE 208 +#define SSL_F_TLS1_AEAD_CTX_INIT 339 +#define SSL_F_TLS1_CERT_VERIFY_MAC 286 +#define SSL_F_TLS1_CHANGE_CIPHER_STATE 209 +#define SSL_F_TLS1_CHANGE_CIPHER_STATE_AEAD 340 +#define SSL_F_TLS1_CHANGE_CIPHER_STATE_CIPHER 338 +#define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT 274 +#define SSL_F_TLS1_ENC 210 +#define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 314 +#define SSL_F_TLS1_HEARTBEAT 315 +#define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT 275 +#define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT 276 +#define SSL_F_TLS1_PRF 284 +#define SSL_F_TLS1_SETUP_KEY_BLOCK 211 +#define SSL_F_WRITE_PENDING 212 + +/* Reason codes. */ +#define SSL_R_APP_DATA_IN_HANDSHAKE 100 +#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272 +#define SSL_R_BAD_ALERT_RECORD 101 +#define SSL_R_BAD_AUTHENTICATION_TYPE 102 +#define SSL_R_BAD_CHANGE_CIPHER_SPEC 103 +#define SSL_R_BAD_CHECKSUM 104 +#define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK 106 +#define SSL_R_BAD_DECOMPRESSION 107 +#define SSL_R_BAD_DH_G_LENGTH 108 +#define SSL_R_BAD_DH_PUB_KEY_LENGTH 109 +#define SSL_R_BAD_DH_P_LENGTH 110 +#define SSL_R_BAD_DIGEST_LENGTH 111 +#define SSL_R_BAD_DSA_SIGNATURE 112 +#define SSL_R_BAD_ECC_CERT 304 +#define SSL_R_BAD_ECDSA_SIGNATURE 305 +#define SSL_R_BAD_ECPOINT 306 +#define SSL_R_BAD_HANDSHAKE_LENGTH 332 +#define SSL_R_BAD_HELLO_REQUEST 105 +#define SSL_R_BAD_LENGTH 271 +#define SSL_R_BAD_MAC_DECODE 113 +#define SSL_R_BAD_MAC_LENGTH 333 +#define SSL_R_BAD_MESSAGE_TYPE 114 +#define SSL_R_BAD_PACKET_LENGTH 115 +#define SSL_R_BAD_PROTOCOL_VERSION_NUMBER 116 +#define SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH 316 +#define SSL_R_BAD_RESPONSE_ARGUMENT 117 +#define SSL_R_BAD_RSA_DECRYPT 118 +#define SSL_R_BAD_RSA_ENCRYPT 119 +#define SSL_R_BAD_RSA_E_LENGTH 120 +#define SSL_R_BAD_RSA_MODULUS_LENGTH 121 +#define SSL_R_BAD_RSA_SIGNATURE 122 +#define SSL_R_BAD_SIGNATURE 123 +#define SSL_R_BAD_SRP_A_LENGTH 347 +#define SSL_R_BAD_SRP_B_LENGTH 348 +#define SSL_R_BAD_SRP_G_LENGTH 349 +#define SSL_R_BAD_SRP_N_LENGTH 350 +#define SSL_R_BAD_SRP_S_LENGTH 351 +#define SSL_R_BAD_SRTP_MKI_VALUE 352 +#define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST 353 +#define SSL_R_BAD_SSL_FILETYPE 124 +#define SSL_R_BAD_SSL_SESSION_ID_LENGTH 125 +#define SSL_R_BAD_STATE 126 +#define SSL_R_BAD_WRITE_RETRY 127 +#define SSL_R_BIO_NOT_SET 128 +#define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 129 +#define SSL_R_BN_LIB 130 +#define SSL_R_CA_DN_LENGTH_MISMATCH 131 +#define SSL_R_CA_DN_TOO_LONG 132 +#define SSL_R_CCS_RECEIVED_EARLY 133 +#define SSL_R_CERTIFICATE_VERIFY_FAILED 134 +#define SSL_R_CERT_LENGTH_MISMATCH 135 +#define SSL_R_CHALLENGE_IS_DIFFERENT 136 +#define SSL_R_CIPHER_CODE_WRONG_LENGTH 137 +#define SSL_R_CIPHER_COMPRESSION_UNAVAILABLE 371 +#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 138 +#define SSL_R_CIPHER_TABLE_SRC_ERROR 139 +#define SSL_R_CLIENTHELLO_TLSEXT 226 +#define SSL_R_COMPRESSED_LENGTH_TOO_LONG 140 +#define SSL_R_COMPRESSION_DISABLED 343 +#define SSL_R_COMPRESSION_FAILURE 141 +#define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE 307 +#define SSL_R_COMPRESSION_LIBRARY_ERROR 142 +#define SSL_R_CONNECTION_ID_IS_DIFFERENT 143 +#define SSL_R_CONNECTION_TYPE_NOT_SET 144 +#define SSL_R_COOKIE_MISMATCH 308 +#define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 145 +#define SSL_R_DATA_LENGTH_TOO_LONG 146 +#define SSL_R_DECRYPTION_FAILED 147 +#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 281 +#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 148 +#define SSL_R_DIGEST_CHECK_FAILED 149 +#define SSL_R_DTLS_MESSAGE_TOO_BIG 334 +#define SSL_R_DUPLICATE_COMPRESSION_ID 309 +#define SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT 317 +#define SSL_R_ECC_CERT_NOT_FOR_SIGNING 318 +#define SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE 322 +#define SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE 323 +#define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER 310 +#define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST 354 +#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150 +#define SSL_R_ERROR_GENERATING_TMP_RSA_KEY 282 +#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 151 +#define SSL_R_EXCESSIVE_MESSAGE_SIZE 152 +#define SSL_R_EXTRA_DATA_IN_MESSAGE 153 +#define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154 +#define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS 355 +#define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 356 +#define SSL_R_HTTPS_PROXY_REQUEST 155 +#define SSL_R_HTTP_REQUEST 156 +#define SSL_R_ILLEGAL_PADDING 283 +#define SSL_R_INAPPROPRIATE_FALLBACK 373 +#define SSL_R_INCONSISTENT_COMPRESSION 340 +#define SSL_R_INVALID_CHALLENGE_LENGTH 158 +#define SSL_R_INVALID_COMMAND 280 +#define SSL_R_INVALID_COMPRESSION_ALGORITHM 341 +#define SSL_R_INVALID_PURPOSE 278 +#define SSL_R_INVALID_SRP_USERNAME 357 +#define SSL_R_INVALID_STATUS_RESPONSE 328 +#define SSL_R_INVALID_TICKET_KEYS_LENGTH 325 +#define SSL_R_INVALID_TRUST 279 +#define SSL_R_KEY_ARG_TOO_LONG 284 +#define SSL_R_KRB5 285 +#define SSL_R_KRB5_C_CC_PRINC 286 +#define SSL_R_KRB5_C_GET_CRED 287 +#define SSL_R_KRB5_C_INIT 288 +#define SSL_R_KRB5_C_MK_REQ 289 +#define SSL_R_KRB5_S_BAD_TICKET 290 +#define SSL_R_KRB5_S_INIT 291 +#define SSL_R_KRB5_S_RD_REQ 292 +#define SSL_R_KRB5_S_TKT_EXPIRED 293 +#define SSL_R_KRB5_S_TKT_NYV 294 +#define SSL_R_KRB5_S_TKT_SKEW 295 +#define SSL_R_LENGTH_MISMATCH 159 +#define SSL_R_LENGTH_TOO_SHORT 160 +#define SSL_R_LIBRARY_BUG 274 +#define SSL_R_LIBRARY_HAS_NO_CIPHERS 161 +#define SSL_R_MESSAGE_TOO_LONG 296 +#define SSL_R_MISSING_DH_DSA_CERT 162 +#define SSL_R_MISSING_DH_KEY 163 +#define SSL_R_MISSING_DH_RSA_CERT 164 +#define SSL_R_MISSING_DSA_SIGNING_CERT 165 +#define SSL_R_MISSING_EXPORT_TMP_DH_KEY 166 +#define SSL_R_MISSING_EXPORT_TMP_RSA_KEY 167 +#define SSL_R_MISSING_RSA_CERTIFICATE 168 +#define SSL_R_MISSING_RSA_ENCRYPTING_CERT 169 +#define SSL_R_MISSING_RSA_SIGNING_CERT 170 +#define SSL_R_MISSING_SRP_PARAM 358 +#define SSL_R_MISSING_TMP_DH_KEY 171 +#define SSL_R_MISSING_TMP_ECDH_KEY 311 +#define SSL_R_MISSING_TMP_RSA_KEY 172 +#define SSL_R_MISSING_TMP_RSA_PKEY 173 +#define SSL_R_MISSING_VERIFY_MESSAGE 174 +#define SSL_R_MULTIPLE_SGC_RESTARTS 346 +#define SSL_R_NON_SSLV2_INITIAL_PACKET 175 +#define SSL_R_NO_CERTIFICATES_RETURNED 176 +#define SSL_R_NO_CERTIFICATE_ASSIGNED 177 +#define SSL_R_NO_CERTIFICATE_RETURNED 178 +#define SSL_R_NO_CERTIFICATE_SET 179 +#define SSL_R_NO_CERTIFICATE_SPECIFIED 180 +#define SSL_R_NO_CIPHERS_AVAILABLE 181 +#define SSL_R_NO_CIPHERS_PASSED 182 +#define SSL_R_NO_CIPHERS_SPECIFIED 183 +#define SSL_R_NO_CIPHER_LIST 184 +#define SSL_R_NO_CIPHER_MATCH 185 +#define SSL_R_NO_CLIENT_CERT_METHOD 331 +#define SSL_R_NO_CLIENT_CERT_RECEIVED 186 +#define SSL_R_NO_COMPRESSION_SPECIFIED 187 +#define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER 330 +#define SSL_R_NO_METHOD_SPECIFIED 188 +#define SSL_R_NO_PRIVATEKEY 189 +#define SSL_R_NO_PRIVATE_KEY_ASSIGNED 190 +#define SSL_R_NO_PROTOCOLS_AVAILABLE 191 +#define SSL_R_NO_PUBLICKEY 192 +#define SSL_R_NO_RENEGOTIATION 339 +#define SSL_R_NO_REQUIRED_DIGEST 324 +#define SSL_R_NO_SHARED_CIPHER 193 +#define SSL_R_NO_SRTP_PROFILES 359 +#define SSL_R_NO_VERIFY_CALLBACK 194 +#define SSL_R_NULL_SSL_CTX 195 +#define SSL_R_NULL_SSL_METHOD_PASSED 196 +#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 197 +#define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344 +#define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE 297 +#define SSL_R_PACKET_LENGTH_TOO_LONG 198 +#define SSL_R_PARSE_TLSEXT 227 +#define SSL_R_PATH_TOO_LONG 270 +#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 199 +#define SSL_R_PEER_ERROR 200 +#define SSL_R_PEER_ERROR_CERTIFICATE 201 +#define SSL_R_PEER_ERROR_NO_CERTIFICATE 202 +#define SSL_R_PEER_ERROR_NO_CIPHER 203 +#define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 204 +#define SSL_R_PRE_MAC_LENGTH_TOO_LONG 205 +#define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS 206 +#define SSL_R_PROTOCOL_IS_SHUTDOWN 207 +#define SSL_R_PSK_IDENTITY_NOT_FOUND 223 +#define SSL_R_PSK_NO_CLIENT_CB 224 +#define SSL_R_PSK_NO_SERVER_CB 225 +#define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR 208 +#define SSL_R_PUBLIC_KEY_IS_NOT_RSA 209 +#define SSL_R_PUBLIC_KEY_NOT_RSA 210 +#define SSL_R_READ_BIO_NOT_SET 211 +#define SSL_R_READ_TIMEOUT_EXPIRED 312 +#define SSL_R_READ_WRONG_PACKET_TYPE 212 +#define SSL_R_RECORD_LENGTH_MISMATCH 213 +#define SSL_R_RECORD_TOO_LARGE 214 +#define SSL_R_RECORD_TOO_SMALL 298 +#define SSL_R_RENEGOTIATE_EXT_TOO_LONG 335 +#define SSL_R_RENEGOTIATION_ENCODING_ERR 336 +#define SSL_R_RENEGOTIATION_MISMATCH 337 +#define SSL_R_REQUIRED_CIPHER_MISSING 215 +#define SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING 342 +#define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO 216 +#define SSL_R_REUSE_CERT_TYPE_NOT_ZERO 217 +#define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO 218 +#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345 +#define SSL_R_SERVERHELLO_TLSEXT 275 +#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277 +#define SSL_R_SHORT_READ 219 +#define SSL_R_SIGNATURE_ALGORITHMS_ERROR 360 +#define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220 +#define SSL_R_SRP_A_CALC 361 +#define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES 362 +#define SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG 363 +#define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE 364 +#define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221 +#define SSL_R_SSL2_CONNECTION_ID_TOO_LONG 299 +#define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT 321 +#define SSL_R_SSL3_EXT_INVALID_SERVERNAME 319 +#define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE 320 +#define SSL_R_SSL3_SESSION_ID_TOO_LONG 300 +#define SSL_R_SSL3_SESSION_ID_TOO_SHORT 222 +#define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 +#define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED 1045 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED 1044 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN 1046 +#define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE 1030 +#define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE 1040 +#define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER 1047 +#define SSL_R_SSLV3_ALERT_NO_CERTIFICATE 1041 +#define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 +#define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE 1043 +#define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 228 +#define SSL_R_SSL_HANDSHAKE_FAILURE 229 +#define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS 230 +#define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED 301 +#define SSL_R_SSL_SESSION_ID_CONFLICT 302 +#define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG 273 +#define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH 303 +#define SSL_R_SSL_SESSION_ID_IS_DIFFERENT 231 +#define SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049 +#define SSL_R_TLSV1_ALERT_DECODE_ERROR 1050 +#define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 +#define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 +#define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 +#define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086 +#define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 +#define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 +#define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 +#define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070 +#define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022 +#define SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048 +#define SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 +#define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114 +#define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113 +#define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111 +#define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112 +#define SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110 +#define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER 232 +#define SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT 365 +#define SSL_R_TLS_HEARTBEAT_PENDING 366 +#define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL 367 +#define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 157 +#define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233 +#define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 234 +#define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER 235 +#define SSL_R_UNABLE_TO_DECODE_DH_CERTS 236 +#define SSL_R_UNABLE_TO_DECODE_ECDH_CERTS 313 +#define SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY 237 +#define SSL_R_UNABLE_TO_FIND_DH_PARAMETERS 238 +#define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 314 +#define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 239 +#define SSL_R_UNABLE_TO_FIND_SSL_METHOD 240 +#define SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES 241 +#define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES 242 +#define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES 243 +#define SSL_R_UNEXPECTED_MESSAGE 244 +#define SSL_R_UNEXPECTED_RECORD 245 +#define SSL_R_UNINITIALIZED 276 +#define SSL_R_UNKNOWN_ALERT_TYPE 246 +#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 247 +#define SSL_R_UNKNOWN_CIPHER_RETURNED 248 +#define SSL_R_UNKNOWN_CIPHER_TYPE 249 +#define SSL_R_UNKNOWN_DIGEST 368 +#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 250 +#define SSL_R_UNKNOWN_PKEY_TYPE 251 +#define SSL_R_UNKNOWN_PROTOCOL 252 +#define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE 253 +#define SSL_R_UNKNOWN_SSL_VERSION 254 +#define SSL_R_UNKNOWN_STATE 255 +#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 338 +#define SSL_R_UNSUPPORTED_CIPHER 256 +#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 257 +#define SSL_R_UNSUPPORTED_DIGEST_TYPE 326 +#define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 315 +#define SSL_R_UNSUPPORTED_PROTOCOL 258 +#define SSL_R_UNSUPPORTED_SSL_VERSION 259 +#define SSL_R_UNSUPPORTED_STATUS_TYPE 329 +#define SSL_R_USE_SRTP_NOT_NEGOTIATED 369 +#define SSL_R_WRITE_BIO_NOT_SET 260 +#define SSL_R_WRONG_CIPHER_RETURNED 261 +#define SSL_R_WRONG_CURVE 378 +#define SSL_R_WRONG_MESSAGE_TYPE 262 +#define SSL_R_WRONG_NUMBER_OF_KEY_BITS 263 +#define SSL_R_WRONG_SIGNATURE_LENGTH 264 +#define SSL_R_WRONG_SIGNATURE_SIZE 265 +#define SSL_R_WRONG_SIGNATURE_TYPE 370 +#define SSL_R_WRONG_SSL_VERSION 266 +#define SSL_R_WRONG_VERSION_NUMBER 267 +#define SSL_R_X509_LIB 268 +#define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 269 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/ssl2.h b/crypto/libressl/include/openssl/ssl2.h new file mode 100644 index 0000000000..3a45dd7150 --- /dev/null +++ b/crypto/libressl/include/openssl/ssl2.h @@ -0,0 +1,153 @@ +/* $OpenBSD: ssl2.h,v 1.11 2014/08/11 04:45:19 miod Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_SSL2_H +#define HEADER_SSL2_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Protocol Version Codes */ +#define SSL2_VERSION 0x0002 +#define SSL2_VERSION_MAJOR 0x00 +#define SSL2_VERSION_MINOR 0x02 +/* #define SSL2_CLIENT_VERSION 0x0002 */ +/* #define SSL2_SERVER_VERSION 0x0002 */ + +/* Protocol Message Codes */ +#define SSL2_MT_ERROR 0 +#define SSL2_MT_CLIENT_HELLO 1 +#define SSL2_MT_CLIENT_MASTER_KEY 2 +#define SSL2_MT_CLIENT_FINISHED 3 +#define SSL2_MT_SERVER_HELLO 4 +#define SSL2_MT_SERVER_VERIFY 5 +#define SSL2_MT_SERVER_FINISHED 6 +#define SSL2_MT_REQUEST_CERTIFICATE 7 +#define SSL2_MT_CLIENT_CERTIFICATE 8 + +/* Error Message Codes */ +#define SSL2_PE_UNDEFINED_ERROR 0x0000 +#define SSL2_PE_NO_CIPHER 0x0001 +#define SSL2_PE_NO_CERTIFICATE 0x0002 +#define SSL2_PE_BAD_CERTIFICATE 0x0004 +#define SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE 0x0006 + +/* Cipher Kind Values */ +#define SSL2_CK_NULL_WITH_MD5 0x02000000 /* v3 */ +#define SSL2_CK_RC4_128_WITH_MD5 0x02010080 +#define SSL2_CK_RC4_128_EXPORT40_WITH_MD5 0x02020080 +#define SSL2_CK_RC2_128_CBC_WITH_MD5 0x02030080 +#define SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5 0x02040080 +#define SSL2_CK_IDEA_128_CBC_WITH_MD5 0x02050080 +#define SSL2_CK_DES_64_CBC_WITH_MD5 0x02060040 +#define SSL2_CK_DES_64_CBC_WITH_SHA 0x02060140 /* v3 */ +#define SSL2_CK_DES_192_EDE3_CBC_WITH_MD5 0x020700c0 +#define SSL2_CK_DES_192_EDE3_CBC_WITH_SHA 0x020701c0 /* v3 */ +#define SSL2_CK_RC4_64_WITH_MD5 0x02080080 /* MS hack */ + +#define SSL2_CK_DES_64_CFB64_WITH_MD5_1 0x02ff0800 /* SSLeay */ +#define SSL2_CK_NULL 0x02ff0810 /* SSLeay */ + +#define SSL2_TXT_DES_64_CFB64_WITH_MD5_1 "DES-CFB-M1" +#define SSL2_TXT_NULL_WITH_MD5 "NULL-MD5" +#define SSL2_TXT_RC4_128_WITH_MD5 "RC4-MD5" +#define SSL2_TXT_RC4_128_EXPORT40_WITH_MD5 "EXP-RC4-MD5" +#define SSL2_TXT_RC2_128_CBC_WITH_MD5 "RC2-CBC-MD5" +#define SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 "EXP-RC2-CBC-MD5" +#define SSL2_TXT_IDEA_128_CBC_WITH_MD5 "IDEA-CBC-MD5" +#define SSL2_TXT_DES_64_CBC_WITH_MD5 "DES-CBC-MD5" +#define SSL2_TXT_DES_64_CBC_WITH_SHA "DES-CBC-SHA" +#define SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5 "DES-CBC3-MD5" +#define SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA "DES-CBC3-SHA" +#define SSL2_TXT_RC4_64_WITH_MD5 "RC4-64-MD5" + +#define SSL2_TXT_NULL "NULL" + +/* Flags for the SSL_CIPHER.algorithm2 field */ +#define SSL2_CF_5_BYTE_ENC 0x01 +#define SSL2_CF_8_BYTE_ENC 0x02 + +/* Certificate Type Codes */ +#define SSL2_CT_X509_CERTIFICATE 0x01 + +/* Authentication Type Code */ +#define SSL2_AT_MD5_WITH_RSA_ENCRYPTION 0x01 + +#define SSL2_MAX_SSL_SESSION_ID_LENGTH 32 + +/* Upper/Lower Bounds */ +#define SSL2_MAX_MASTER_KEY_LENGTH_IN_BITS 256 +#define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER 32767u /* 2^15-1 */ +#define SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER 16383 /* 2^14-1 */ + +#define SSL2_CHALLENGE_LENGTH 16 +/*#define SSL2_CHALLENGE_LENGTH 32 */ +#define SSL2_MIN_CHALLENGE_LENGTH 16 +#define SSL2_MAX_CHALLENGE_LENGTH 32 +#define SSL2_CONNECTION_ID_LENGTH 16 +#define SSL2_MAX_CONNECTION_ID_LENGTH 16 +#define SSL2_SSL_SESSION_ID_LENGTH 16 +#define SSL2_MAX_CERT_CHALLENGE_LENGTH 32 +#define SSL2_MIN_CERT_CHALLENGE_LENGTH 16 +#define SSL2_MAX_KEY_MATERIAL_LENGTH 24 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/ssl23.h b/crypto/libressl/include/openssl/ssl23.h new file mode 100644 index 0000000000..cd75afff41 --- /dev/null +++ b/crypto/libressl/include/openssl/ssl23.h @@ -0,0 +1,82 @@ +/* $OpenBSD: ssl23.h,v 1.3 2014/06/12 15:49:31 deraadt Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_SSL23_H +#define HEADER_SSL23_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*client */ +/* write to server */ +#define SSL23_ST_CW_CLNT_HELLO_A (0x210|SSL_ST_CONNECT) +#define SSL23_ST_CW_CLNT_HELLO_B (0x211|SSL_ST_CONNECT) +/* read from server */ +#define SSL23_ST_CR_SRVR_HELLO_A (0x220|SSL_ST_CONNECT) +#define SSL23_ST_CR_SRVR_HELLO_B (0x221|SSL_ST_CONNECT) + +/* server */ +/* read from client */ +#define SSL23_ST_SR_CLNT_HELLO_A (0x210|SSL_ST_ACCEPT) +#define SSL23_ST_SR_CLNT_HELLO_B (0x211|SSL_ST_ACCEPT) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/ssl3.h b/crypto/libressl/include/openssl/ssl3.h new file mode 100644 index 0000000000..25e3cd2da6 --- /dev/null +++ b/crypto/libressl/include/openssl/ssl3.h @@ -0,0 +1,617 @@ +/* $OpenBSD: ssl3.h,v 1.40 2015/07/18 19:41:54 doug Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_SSL3_H +#define HEADER_SSL3_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* TLS_EMPTY_RENEGOTIATION_INFO_SCSV from RFC 5746. */ +#define SSL3_CK_SCSV 0x030000FF + +/* TLS_FALLBACK_SCSV from draft-ietf-tls-downgrade-scsv-03. */ +#define SSL3_CK_FALLBACK_SCSV 0x03005600 + +#define SSL3_CK_RSA_NULL_MD5 0x03000001 +#define SSL3_CK_RSA_NULL_SHA 0x03000002 +#define SSL3_CK_RSA_RC4_40_MD5 0x03000003 +#define SSL3_CK_RSA_RC4_128_MD5 0x03000004 +#define SSL3_CK_RSA_RC4_128_SHA 0x03000005 +#define SSL3_CK_RSA_RC2_40_MD5 0x03000006 +#define SSL3_CK_RSA_IDEA_128_SHA 0x03000007 +#define SSL3_CK_RSA_DES_40_CBC_SHA 0x03000008 +#define SSL3_CK_RSA_DES_64_CBC_SHA 0x03000009 +#define SSL3_CK_RSA_DES_192_CBC3_SHA 0x0300000A + +#define SSL3_CK_DH_DSS_DES_40_CBC_SHA 0x0300000B +#define SSL3_CK_DH_DSS_DES_64_CBC_SHA 0x0300000C +#define SSL3_CK_DH_DSS_DES_192_CBC3_SHA 0x0300000D +#define SSL3_CK_DH_RSA_DES_40_CBC_SHA 0x0300000E +#define SSL3_CK_DH_RSA_DES_64_CBC_SHA 0x0300000F +#define SSL3_CK_DH_RSA_DES_192_CBC3_SHA 0x03000010 + +#define SSL3_CK_EDH_DSS_DES_40_CBC_SHA 0x03000011 +#define SSL3_CK_EDH_DSS_DES_64_CBC_SHA 0x03000012 +#define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA 0x03000013 +#define SSL3_CK_EDH_RSA_DES_40_CBC_SHA 0x03000014 +#define SSL3_CK_EDH_RSA_DES_64_CBC_SHA 0x03000015 +#define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA 0x03000016 + +#define SSL3_CK_ADH_RC4_40_MD5 0x03000017 +#define SSL3_CK_ADH_RC4_128_MD5 0x03000018 +#define SSL3_CK_ADH_DES_40_CBC_SHA 0x03000019 +#define SSL3_CK_ADH_DES_64_CBC_SHA 0x0300001A +#define SSL3_CK_ADH_DES_192_CBC_SHA 0x0300001B + +/* VRS Additional Kerberos5 entries + */ +#define SSL3_CK_KRB5_DES_64_CBC_SHA 0x0300001E +#define SSL3_CK_KRB5_DES_192_CBC3_SHA 0x0300001F +#define SSL3_CK_KRB5_RC4_128_SHA 0x03000020 +#define SSL3_CK_KRB5_IDEA_128_CBC_SHA 0x03000021 +#define SSL3_CK_KRB5_DES_64_CBC_MD5 0x03000022 +#define SSL3_CK_KRB5_DES_192_CBC3_MD5 0x03000023 +#define SSL3_CK_KRB5_RC4_128_MD5 0x03000024 +#define SSL3_CK_KRB5_IDEA_128_CBC_MD5 0x03000025 + +#define SSL3_CK_KRB5_DES_40_CBC_SHA 0x03000026 +#define SSL3_CK_KRB5_RC2_40_CBC_SHA 0x03000027 +#define SSL3_CK_KRB5_RC4_40_SHA 0x03000028 +#define SSL3_CK_KRB5_DES_40_CBC_MD5 0x03000029 +#define SSL3_CK_KRB5_RC2_40_CBC_MD5 0x0300002A +#define SSL3_CK_KRB5_RC4_40_MD5 0x0300002B + +#define SSL3_TXT_RSA_NULL_MD5 "NULL-MD5" +#define SSL3_TXT_RSA_NULL_SHA "NULL-SHA" +#define SSL3_TXT_RSA_RC4_40_MD5 "EXP-RC4-MD5" +#define SSL3_TXT_RSA_RC4_128_MD5 "RC4-MD5" +#define SSL3_TXT_RSA_RC4_128_SHA "RC4-SHA" +#define SSL3_TXT_RSA_RC2_40_MD5 "EXP-RC2-CBC-MD5" +#define SSL3_TXT_RSA_IDEA_128_SHA "IDEA-CBC-SHA" +#define SSL3_TXT_RSA_DES_40_CBC_SHA "EXP-DES-CBC-SHA" +#define SSL3_TXT_RSA_DES_64_CBC_SHA "DES-CBC-SHA" +#define SSL3_TXT_RSA_DES_192_CBC3_SHA "DES-CBC3-SHA" + +#define SSL3_TXT_DH_DSS_DES_40_CBC_SHA "EXP-DH-DSS-DES-CBC-SHA" +#define SSL3_TXT_DH_DSS_DES_64_CBC_SHA "DH-DSS-DES-CBC-SHA" +#define SSL3_TXT_DH_DSS_DES_192_CBC3_SHA "DH-DSS-DES-CBC3-SHA" +#define SSL3_TXT_DH_RSA_DES_40_CBC_SHA "EXP-DH-RSA-DES-CBC-SHA" +#define SSL3_TXT_DH_RSA_DES_64_CBC_SHA "DH-RSA-DES-CBC-SHA" +#define SSL3_TXT_DH_RSA_DES_192_CBC3_SHA "DH-RSA-DES-CBC3-SHA" + +#define SSL3_TXT_EDH_DSS_DES_40_CBC_SHA "EXP-EDH-DSS-DES-CBC-SHA" +#define SSL3_TXT_EDH_DSS_DES_64_CBC_SHA "EDH-DSS-DES-CBC-SHA" +#define SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA "EDH-DSS-DES-CBC3-SHA" +#define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA "EXP-EDH-RSA-DES-CBC-SHA" +#define SSL3_TXT_EDH_RSA_DES_64_CBC_SHA "EDH-RSA-DES-CBC-SHA" +#define SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA "EDH-RSA-DES-CBC3-SHA" + +#define SSL3_TXT_ADH_RC4_40_MD5 "EXP-ADH-RC4-MD5" +#define SSL3_TXT_ADH_RC4_128_MD5 "ADH-RC4-MD5" +#define SSL3_TXT_ADH_DES_40_CBC_SHA "EXP-ADH-DES-CBC-SHA" +#define SSL3_TXT_ADH_DES_64_CBC_SHA "ADH-DES-CBC-SHA" +#define SSL3_TXT_ADH_DES_192_CBC_SHA "ADH-DES-CBC3-SHA" + +#define SSL3_TXT_KRB5_DES_64_CBC_SHA "KRB5-DES-CBC-SHA" +#define SSL3_TXT_KRB5_DES_192_CBC3_SHA "KRB5-DES-CBC3-SHA" +#define SSL3_TXT_KRB5_RC4_128_SHA "KRB5-RC4-SHA" +#define SSL3_TXT_KRB5_IDEA_128_CBC_SHA "KRB5-IDEA-CBC-SHA" +#define SSL3_TXT_KRB5_DES_64_CBC_MD5 "KRB5-DES-CBC-MD5" +#define SSL3_TXT_KRB5_DES_192_CBC3_MD5 "KRB5-DES-CBC3-MD5" +#define SSL3_TXT_KRB5_RC4_128_MD5 "KRB5-RC4-MD5" +#define SSL3_TXT_KRB5_IDEA_128_CBC_MD5 "KRB5-IDEA-CBC-MD5" + +#define SSL3_TXT_KRB5_DES_40_CBC_SHA "EXP-KRB5-DES-CBC-SHA" +#define SSL3_TXT_KRB5_RC2_40_CBC_SHA "EXP-KRB5-RC2-CBC-SHA" +#define SSL3_TXT_KRB5_RC4_40_SHA "EXP-KRB5-RC4-SHA" +#define SSL3_TXT_KRB5_DES_40_CBC_MD5 "EXP-KRB5-DES-CBC-MD5" +#define SSL3_TXT_KRB5_RC2_40_CBC_MD5 "EXP-KRB5-RC2-CBC-MD5" +#define SSL3_TXT_KRB5_RC4_40_MD5 "EXP-KRB5-RC4-MD5" + +#define SSL3_SSL_SESSION_ID_LENGTH 32 +#define SSL3_MAX_SSL_SESSION_ID_LENGTH 32 + +#define SSL3_MASTER_SECRET_SIZE 48 +#define SSL3_RANDOM_SIZE 32 +#define SSL3_SEQUENCE_SIZE 8 +#define SSL3_SESSION_ID_SIZE 32 +#define SSL3_CIPHER_VALUE_SIZE 2 + +#define SSL3_RT_HEADER_LENGTH 5 +#define SSL3_HM_HEADER_LENGTH 4 + +#define SSL3_ALIGN_PAYLOAD 8 + +/* This is the maximum MAC (digest) size used by the SSL library. + * Currently maximum of 20 is used by SHA1, but we reserve for + * future extension for 512-bit hashes. + */ + +#define SSL3_RT_MAX_MD_SIZE 64 + +/* Maximum block size used in all ciphersuites. Currently 16 for AES. + */ + +#define SSL_RT_MAX_CIPHER_BLOCK_SIZE 16 + +#define SSL3_RT_MAX_EXTRA (16384) + +/* Maximum plaintext length: defined by SSL/TLS standards */ +#define SSL3_RT_MAX_PLAIN_LENGTH 16384 +/* Maximum compression overhead: defined by SSL/TLS standards */ +#define SSL3_RT_MAX_COMPRESSED_OVERHEAD 1024 + +/* The standards give a maximum encryption overhead of 1024 bytes. + * In practice the value is lower than this. The overhead is the maximum + * number of padding bytes (256) plus the mac size. + */ +#define SSL3_RT_MAX_ENCRYPTED_OVERHEAD (256 + SSL3_RT_MAX_MD_SIZE) + +/* OpenSSL currently only uses a padding length of at most one block so + * the send overhead is smaller. + */ + +#define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \ + (SSL_RT_MAX_CIPHER_BLOCK_SIZE + SSL3_RT_MAX_MD_SIZE) + +/* If compression isn't used don't include the compression overhead */ +#define SSL3_RT_MAX_COMPRESSED_LENGTH SSL3_RT_MAX_PLAIN_LENGTH +#define SSL3_RT_MAX_ENCRYPTED_LENGTH \ + (SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH) +#define SSL3_RT_MAX_PACKET_SIZE \ + (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH) + +#define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54" +#define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52" + +#define SSL3_VERSION 0x0300 +#define SSL3_VERSION_MAJOR 0x03 +#define SSL3_VERSION_MINOR 0x00 + +#define SSL3_RT_CHANGE_CIPHER_SPEC 20 +#define SSL3_RT_ALERT 21 +#define SSL3_RT_HANDSHAKE 22 +#define SSL3_RT_APPLICATION_DATA 23 +#define TLS1_RT_HEARTBEAT 24 + +#define SSL3_AL_WARNING 1 +#define SSL3_AL_FATAL 2 + +#define SSL3_AD_CLOSE_NOTIFY 0 +#define SSL3_AD_UNEXPECTED_MESSAGE 10 /* fatal */ +#define SSL3_AD_BAD_RECORD_MAC 20 /* fatal */ +#define SSL3_AD_DECOMPRESSION_FAILURE 30 /* fatal */ +#define SSL3_AD_HANDSHAKE_FAILURE 40 /* fatal */ +#define SSL3_AD_NO_CERTIFICATE 41 +#define SSL3_AD_BAD_CERTIFICATE 42 +#define SSL3_AD_UNSUPPORTED_CERTIFICATE 43 +#define SSL3_AD_CERTIFICATE_REVOKED 44 +#define SSL3_AD_CERTIFICATE_EXPIRED 45 +#define SSL3_AD_CERTIFICATE_UNKNOWN 46 +#define SSL3_AD_ILLEGAL_PARAMETER 47 /* fatal */ + +#define TLS1_HB_REQUEST 1 +#define TLS1_HB_RESPONSE 2 + +#ifndef OPENSSL_NO_SSL_INTERN + +typedef struct ssl3_record_st { +/*r */ int type; /* type of record */ +/*rw*/ unsigned int length; /* How many bytes available */ +/*r */ unsigned int off; /* read/write offset into 'buf' */ +/*rw*/ unsigned char *data; /* pointer to the record data */ +/*rw*/ unsigned char *input; /* where the decode bytes are */ +/*r */ unsigned long epoch; /* epoch number, needed by DTLS1 */ +/*r */ unsigned char seq_num[8]; /* sequence number, needed by DTLS1 */ +} SSL3_RECORD; + +typedef struct ssl3_buffer_st { + unsigned char *buf; /* at least SSL3_RT_MAX_PACKET_SIZE bytes, + * see ssl3_setup_buffers() */ + size_t len; /* buffer size */ + int offset; /* where to 'copy from' */ + int left; /* how many bytes left */ +} SSL3_BUFFER; + +#endif + +#define SSL3_CT_RSA_SIGN 1 +#define SSL3_CT_DSS_SIGN 2 +#define SSL3_CT_RSA_FIXED_DH 3 +#define SSL3_CT_DSS_FIXED_DH 4 +#define SSL3_CT_RSA_EPHEMERAL_DH 5 +#define SSL3_CT_DSS_EPHEMERAL_DH 6 +#define SSL3_CT_FORTEZZA_DMS 20 +/* SSL3_CT_NUMBER is used to size arrays and it must be large + * enough to contain all of the cert types defined either for + * SSLv3 and TLSv1. + */ +#define SSL3_CT_NUMBER 11 + + +#define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS 0x0001 +#define SSL3_FLAGS_DELAY_CLIENT_FINISHED 0x0002 +#define SSL3_FLAGS_POP_BUFFER 0x0004 +#define TLS1_FLAGS_TLS_PADDING_BUG 0x0 +#define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010 +#define TLS1_FLAGS_KEEP_HANDSHAKE 0x0020 +#define SSL3_FLAGS_CCS_OK 0x0080 + +#ifndef OPENSSL_NO_SSL_INTERN + +typedef struct ssl3_state_st { + long flags; + int delay_buf_pop_ret; + + unsigned char read_sequence[SSL3_SEQUENCE_SIZE]; + int read_mac_secret_size; + unsigned char read_mac_secret[EVP_MAX_MD_SIZE]; + unsigned char write_sequence[SSL3_SEQUENCE_SIZE]; + int write_mac_secret_size; + unsigned char write_mac_secret[EVP_MAX_MD_SIZE]; + + unsigned char server_random[SSL3_RANDOM_SIZE]; + unsigned char client_random[SSL3_RANDOM_SIZE]; + + /* flags for countermeasure against known-IV weakness */ + int need_empty_fragments; + int empty_fragment_done; + + SSL3_BUFFER rbuf; /* read IO goes into here */ + SSL3_BUFFER wbuf; /* write IO goes into here */ + + SSL3_RECORD rrec; /* each decoded record goes in here */ + SSL3_RECORD wrec; /* goes out from here */ + + /* storage for Alert/Handshake protocol data received but not + * yet processed by ssl3_read_bytes: */ + unsigned char alert_fragment[2]; + unsigned int alert_fragment_len; + unsigned char handshake_fragment[4]; + unsigned int handshake_fragment_len; + + /* partial write - check the numbers match */ + unsigned int wnum; /* number of bytes sent so far */ + int wpend_tot; /* number bytes written */ + int wpend_type; + int wpend_ret; /* number of bytes submitted */ + const unsigned char *wpend_buf; + + /* used during startup, digest all incoming/outgoing packets */ + BIO *handshake_buffer; + /* When set of handshake digests is determined, buffer is hashed + * and freed and MD_CTX-es for all required digests are stored in + * this array */ + EVP_MD_CTX **handshake_dgst; + /* this is set whenerver we see a change_cipher_spec message + * come in when we are not looking for one */ + int change_cipher_spec; + + int warn_alert; + int fatal_alert; + /* we allow one fatal and one warning alert to be outstanding, + * send close alert via the warning alert */ + int alert_dispatch; + unsigned char send_alert[2]; + + /* This flag is set when we should renegotiate ASAP, basically when + * there is no more data in the read or write buffers */ + int renegotiate; + int total_renegotiations; + int num_renegotiations; + + int in_read_app_data; + + struct { + /* actually only needs to be 16+20 */ + unsigned char cert_verify_md[EVP_MAX_MD_SIZE*2]; + + /* actually only need to be 16+20 for SSLv3 and 12 for TLS */ + unsigned char finish_md[EVP_MAX_MD_SIZE*2]; + int finish_md_len; + unsigned char peer_finish_md[EVP_MAX_MD_SIZE*2]; + int peer_finish_md_len; + + unsigned long message_size; + int message_type; + + /* used to hold the new cipher we are going to use */ + const SSL_CIPHER *new_cipher; + DH *dh; + + EC_KEY *ecdh; /* holds short lived ECDH key */ + + /* used when SSL_ST_FLUSH_DATA is entered */ + int next_state; + + int reuse_message; + + /* used for certificate requests */ + int cert_req; + int ctype_num; + char ctype[SSL3_CT_NUMBER]; + STACK_OF(X509_NAME) *ca_names; + + int key_block_length; + unsigned char *key_block; + + const EVP_CIPHER *new_sym_enc; + const EVP_AEAD *new_aead; + const EVP_MD *new_hash; + int new_mac_pkey_type; + int new_mac_secret_size; + int cert_request; + } tmp; + + /* Connection binding to prevent renegotiation attacks */ + unsigned char previous_client_finished[EVP_MAX_MD_SIZE]; + unsigned char previous_client_finished_len; + unsigned char previous_server_finished[EVP_MAX_MD_SIZE]; + unsigned char previous_server_finished_len; + int send_connection_binding; /* TODOEKR */ + + /* Set if we saw the Next Protocol Negotiation extension from our peer. + */ + int next_proto_neg_seen; + + /* + * ALPN information + * (we are in the process of transitioning from NPN to ALPN). + */ + + /* + * In a server these point to the selected ALPN protocol after the + * ClientHello has been processed. In a client these contain the + * protocol that the server selected once the ServerHello has been + * processed. + */ + unsigned char *alpn_selected; + unsigned int alpn_selected_len; +} SSL3_STATE; + +#endif + +/* SSLv3 */ +/*client */ +/* extra state */ +#define SSL3_ST_CW_FLUSH (0x100|SSL_ST_CONNECT) +/* write to server */ +#define SSL3_ST_CW_CLNT_HELLO_A (0x110|SSL_ST_CONNECT) +#define SSL3_ST_CW_CLNT_HELLO_B (0x111|SSL_ST_CONNECT) +/* read from server */ +#define SSL3_ST_CR_SRVR_HELLO_A (0x120|SSL_ST_CONNECT) +#define SSL3_ST_CR_SRVR_HELLO_B (0x121|SSL_ST_CONNECT) +#define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A (0x126|SSL_ST_CONNECT) +#define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B (0x127|SSL_ST_CONNECT) +#define SSL3_ST_CR_CERT_A (0x130|SSL_ST_CONNECT) +#define SSL3_ST_CR_CERT_B (0x131|SSL_ST_CONNECT) +#define SSL3_ST_CR_KEY_EXCH_A (0x140|SSL_ST_CONNECT) +#define SSL3_ST_CR_KEY_EXCH_B (0x141|SSL_ST_CONNECT) +#define SSL3_ST_CR_CERT_REQ_A (0x150|SSL_ST_CONNECT) +#define SSL3_ST_CR_CERT_REQ_B (0x151|SSL_ST_CONNECT) +#define SSL3_ST_CR_SRVR_DONE_A (0x160|SSL_ST_CONNECT) +#define SSL3_ST_CR_SRVR_DONE_B (0x161|SSL_ST_CONNECT) +/* write to server */ +#define SSL3_ST_CW_CERT_A (0x170|SSL_ST_CONNECT) +#define SSL3_ST_CW_CERT_B (0x171|SSL_ST_CONNECT) +#define SSL3_ST_CW_CERT_C (0x172|SSL_ST_CONNECT) +#define SSL3_ST_CW_CERT_D (0x173|SSL_ST_CONNECT) +#define SSL3_ST_CW_KEY_EXCH_A (0x180|SSL_ST_CONNECT) +#define SSL3_ST_CW_KEY_EXCH_B (0x181|SSL_ST_CONNECT) +#define SSL3_ST_CW_CERT_VRFY_A (0x190|SSL_ST_CONNECT) +#define SSL3_ST_CW_CERT_VRFY_B (0x191|SSL_ST_CONNECT) +#define SSL3_ST_CW_CHANGE_A (0x1A0|SSL_ST_CONNECT) +#define SSL3_ST_CW_CHANGE_B (0x1A1|SSL_ST_CONNECT) +#define SSL3_ST_CW_NEXT_PROTO_A (0x200|SSL_ST_CONNECT) +#define SSL3_ST_CW_NEXT_PROTO_B (0x201|SSL_ST_CONNECT) +#define SSL3_ST_CW_FINISHED_A (0x1B0|SSL_ST_CONNECT) +#define SSL3_ST_CW_FINISHED_B (0x1B1|SSL_ST_CONNECT) +/* read from server */ +#define SSL3_ST_CR_CHANGE_A (0x1C0|SSL_ST_CONNECT) +#define SSL3_ST_CR_CHANGE_B (0x1C1|SSL_ST_CONNECT) +#define SSL3_ST_CR_FINISHED_A (0x1D0|SSL_ST_CONNECT) +#define SSL3_ST_CR_FINISHED_B (0x1D1|SSL_ST_CONNECT) +#define SSL3_ST_CR_SESSION_TICKET_A (0x1E0|SSL_ST_CONNECT) +#define SSL3_ST_CR_SESSION_TICKET_B (0x1E1|SSL_ST_CONNECT) +#define SSL3_ST_CR_CERT_STATUS_A (0x1F0|SSL_ST_CONNECT) +#define SSL3_ST_CR_CERT_STATUS_B (0x1F1|SSL_ST_CONNECT) + +/* server */ +/* extra state */ +#define SSL3_ST_SW_FLUSH (0x100|SSL_ST_ACCEPT) +/* read from client */ +/* Do not change the number values, they do matter */ +#define SSL3_ST_SR_CLNT_HELLO_A (0x110|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CLNT_HELLO_B (0x111|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CLNT_HELLO_C (0x112|SSL_ST_ACCEPT) +/* write to client */ +#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT) +#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT) +#define SSL3_ST_SW_HELLO_REQ_A (0x120|SSL_ST_ACCEPT) +#define SSL3_ST_SW_HELLO_REQ_B (0x121|SSL_ST_ACCEPT) +#define SSL3_ST_SW_HELLO_REQ_C (0x122|SSL_ST_ACCEPT) +#define SSL3_ST_SW_SRVR_HELLO_A (0x130|SSL_ST_ACCEPT) +#define SSL3_ST_SW_SRVR_HELLO_B (0x131|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CERT_A (0x140|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CERT_B (0x141|SSL_ST_ACCEPT) +#define SSL3_ST_SW_KEY_EXCH_A (0x150|SSL_ST_ACCEPT) +#define SSL3_ST_SW_KEY_EXCH_B (0x151|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CERT_REQ_A (0x160|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CERT_REQ_B (0x161|SSL_ST_ACCEPT) +#define SSL3_ST_SW_SRVR_DONE_A (0x170|SSL_ST_ACCEPT) +#define SSL3_ST_SW_SRVR_DONE_B (0x171|SSL_ST_ACCEPT) +/* read from client */ +#define SSL3_ST_SR_CERT_A (0x180|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CERT_B (0x181|SSL_ST_ACCEPT) +#define SSL3_ST_SR_KEY_EXCH_A (0x190|SSL_ST_ACCEPT) +#define SSL3_ST_SR_KEY_EXCH_B (0x191|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CERT_VRFY_A (0x1A0|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CERT_VRFY_B (0x1A1|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CHANGE_A (0x1B0|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CHANGE_B (0x1B1|SSL_ST_ACCEPT) +#define SSL3_ST_SR_NEXT_PROTO_A (0x210|SSL_ST_ACCEPT) +#define SSL3_ST_SR_NEXT_PROTO_B (0x211|SSL_ST_ACCEPT) +#define SSL3_ST_SR_FINISHED_A (0x1C0|SSL_ST_ACCEPT) +#define SSL3_ST_SR_FINISHED_B (0x1C1|SSL_ST_ACCEPT) +/* write to client */ +#define SSL3_ST_SW_CHANGE_A (0x1D0|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CHANGE_B (0x1D1|SSL_ST_ACCEPT) +#define SSL3_ST_SW_FINISHED_A (0x1E0|SSL_ST_ACCEPT) +#define SSL3_ST_SW_FINISHED_B (0x1E1|SSL_ST_ACCEPT) +#define SSL3_ST_SW_SESSION_TICKET_A (0x1F0|SSL_ST_ACCEPT) +#define SSL3_ST_SW_SESSION_TICKET_B (0x1F1|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CERT_STATUS_A (0x200|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CERT_STATUS_B (0x201|SSL_ST_ACCEPT) + +#define SSL3_MT_HELLO_REQUEST 0 +#define SSL3_MT_CLIENT_HELLO 1 +#define SSL3_MT_SERVER_HELLO 2 +#define SSL3_MT_NEWSESSION_TICKET 4 +#define SSL3_MT_CERTIFICATE 11 +#define SSL3_MT_SERVER_KEY_EXCHANGE 12 +#define SSL3_MT_CERTIFICATE_REQUEST 13 +#define SSL3_MT_SERVER_DONE 14 +#define SSL3_MT_CERTIFICATE_VERIFY 15 +#define SSL3_MT_CLIENT_KEY_EXCHANGE 16 +#define SSL3_MT_FINISHED 20 +#define SSL3_MT_CERTIFICATE_STATUS 22 + +#define SSL3_MT_NEXT_PROTO 67 + +#define DTLS1_MT_HELLO_VERIFY_REQUEST 3 + +#define SSL3_MT_CCS 1 + +/* These are used when changing over to a new cipher */ +#define SSL3_CC_READ 0x01 +#define SSL3_CC_WRITE 0x02 +#define SSL3_CC_CLIENT 0x10 +#define SSL3_CC_SERVER 0x20 +#define SSL3_CHANGE_CIPHER_CLIENT_WRITE (SSL3_CC_CLIENT|SSL3_CC_WRITE) +#define SSL3_CHANGE_CIPHER_SERVER_READ (SSL3_CC_SERVER|SSL3_CC_READ) +#define SSL3_CHANGE_CIPHER_CLIENT_READ (SSL3_CC_CLIENT|SSL3_CC_READ) +#define SSL3_CHANGE_CIPHER_SERVER_WRITE (SSL3_CC_SERVER|SSL3_CC_WRITE) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/stack.h b/crypto/libressl/include/openssl/stack.h new file mode 100644 index 0000000000..2a54dded72 --- /dev/null +++ b/crypto/libressl/include/openssl/stack.h @@ -0,0 +1,107 @@ +/* $OpenBSD$ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_STACK_H +#define HEADER_STACK_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct stack_st { + int num; + char **data; + int sorted; + + int num_alloc; + int (*comp)(const void *, const void *); +} _STACK; /* Use STACK_OF(...) instead */ + +#define M_sk_num(sk) ((sk) ? (sk)->num:-1) +#define M_sk_value(sk,n) ((sk) ? (sk)->data[n] : NULL) + +int sk_num(const _STACK *); +void *sk_value(const _STACK *, int); + +void *sk_set(_STACK *, int, void *); + +_STACK *sk_new(int (*cmp)(const void *, const void *)); +_STACK *sk_new_null(void); +void sk_free(_STACK *); +void sk_pop_free(_STACK *st, void (*func)(void *)); +int sk_insert(_STACK *sk, void *data, int where); +void *sk_delete(_STACK *st, int loc); +void *sk_delete_ptr(_STACK *st, void *p); +int sk_find(_STACK *st, void *data); +int sk_find_ex(_STACK *st, void *data); +int sk_push(_STACK *st, void *data); +int sk_unshift(_STACK *st, void *data); +void *sk_shift(_STACK *st); +void *sk_pop(_STACK *st); +void sk_zero(_STACK *st); +int (*sk_set_cmp_func(_STACK *sk, int (*c)(const void *, const void *)))( + const void *, const void *); +_STACK *sk_dup(_STACK *st); +void sk_sort(_STACK *st); +int sk_is_sorted(const _STACK *st); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/libressl/include/openssl/tls1.h b/crypto/libressl/include/openssl/tls1.h new file mode 100644 index 0000000000..ee07fdf27e --- /dev/null +++ b/crypto/libressl/include/openssl/tls1.h @@ -0,0 +1,758 @@ +/* $OpenBSD: tls1.h,v 1.27 2016/03/07 19:33:26 mmcc Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifndef HEADER_TLS1_H +#define HEADER_TLS1_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES 0 + +#define TLS1_2_VERSION 0x0303 +#define TLS1_2_VERSION_MAJOR 0x03 +#define TLS1_2_VERSION_MINOR 0x03 + +#define TLS1_1_VERSION 0x0302 +#define TLS1_1_VERSION_MAJOR 0x03 +#define TLS1_1_VERSION_MINOR 0x02 + +#define TLS1_VERSION 0x0301 +#define TLS1_VERSION_MAJOR 0x03 +#define TLS1_VERSION_MINOR 0x01 + +#define TLS1_get_version(s) \ + ((s->version >> 8) == TLS1_VERSION_MAJOR ? s->version : 0) + +#define TLS1_get_client_version(s) \ + ((s->client_version >> 8) == TLS1_VERSION_MAJOR ? s->client_version : 0) + +/* + * TLS Alert codes. + * + * https://www.iana.org/assignments/tls-parameters/#tls-parameters-6 + */ + +#define TLS1_AD_DECRYPTION_FAILED 21 +#define TLS1_AD_RECORD_OVERFLOW 22 +#define TLS1_AD_UNKNOWN_CA 48 /* fatal */ +#define TLS1_AD_ACCESS_DENIED 49 /* fatal */ +#define TLS1_AD_DECODE_ERROR 50 /* fatal */ +#define TLS1_AD_DECRYPT_ERROR 51 +#define TLS1_AD_EXPORT_RESTRICTION 60 /* fatal */ +#define TLS1_AD_PROTOCOL_VERSION 70 /* fatal */ +#define TLS1_AD_INSUFFICIENT_SECURITY 71 /* fatal */ +#define TLS1_AD_INTERNAL_ERROR 80 /* fatal */ +/* Code 86 from RFC 7507. */ +#define TLS1_AD_INAPPROPRIATE_FALLBACK 86 /* fatal */ +#define TLS1_AD_USER_CANCELLED 90 +#define TLS1_AD_NO_RENEGOTIATION 100 +/* Codes 110-114 from RFC 3546. */ +#define TLS1_AD_UNSUPPORTED_EXTENSION 110 +#define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111 +#define TLS1_AD_UNRECOGNIZED_NAME 112 +#define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113 +#define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114 +/* Code 115 from RFC 4279. */ +#define TLS1_AD_UNKNOWN_PSK_IDENTITY 115 /* fatal */ + +/* + * TLS ExtensionType values. + * + * https://www.iana.org/assignments/tls-extensiontype-values/ + */ + +/* ExtensionType values from RFC 3546, RFC 4366 and RFC 6066. */ +#define TLSEXT_TYPE_server_name 0 +#define TLSEXT_TYPE_max_fragment_length 1 +#define TLSEXT_TYPE_client_certificate_url 2 +#define TLSEXT_TYPE_trusted_ca_keys 3 +#define TLSEXT_TYPE_truncated_hmac 4 +#define TLSEXT_TYPE_status_request 5 + +/* ExtensionType values from RFC 4681. */ +#define TLSEXT_TYPE_user_mapping 6 + +/* ExtensionType values from RFC 5878. */ +#define TLSEXT_TYPE_client_authz 7 +#define TLSEXT_TYPE_server_authz 8 + +/* ExtensionType values from RFC 6091. */ +#define TLSEXT_TYPE_cert_type 9 + +/* ExtensionType values from RFC 4492. */ +#define TLSEXT_TYPE_elliptic_curves 10 +#define TLSEXT_TYPE_ec_point_formats 11 + +/* ExtensionType value from RFC 5054. */ +#define TLSEXT_TYPE_srp 12 + +/* ExtensionType values from RFC 5246. */ +#define TLSEXT_TYPE_signature_algorithms 13 + +/* ExtensionType value from RFC 5764. */ +#define TLSEXT_TYPE_use_srtp 14 + +/* ExtensionType value from RFC 5620. */ +#define TLSEXT_TYPE_heartbeat 15 + +/* ExtensionType value from RFC 7301. */ +#define TLSEXT_TYPE_application_layer_protocol_negotiation 16 + +/* ExtensionType value for TLS padding extension. + * (TEMPORARY - registered 2014-03-12, expires 2015-03-12) + * https://tools.ietf.org/html/draft-agl-tls-padding-03 + */ +#define TLSEXT_TYPE_padding 21 + +/* ExtensionType value from RFC 4507. */ +#define TLSEXT_TYPE_session_ticket 35 + +/* Temporary extension type */ +#define TLSEXT_TYPE_renegotiate 0xff01 + +/* This is not an IANA defined extension number */ +#define TLSEXT_TYPE_next_proto_neg 13172 + +/* NameType value from RFC 3546. */ +#define TLSEXT_NAMETYPE_host_name 0 +/* status request value from RFC 3546 */ +#define TLSEXT_STATUSTYPE_ocsp 1 + +/* ECPointFormat values from RFC 4492. */ +#define TLSEXT_ECPOINTFORMAT_first 0 +#define TLSEXT_ECPOINTFORMAT_uncompressed 0 +#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime 1 +#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 2 +#define TLSEXT_ECPOINTFORMAT_last 2 + +/* Signature and hash algorithms from RFC 5246. */ + +#define TLSEXT_signature_anonymous 0 +#define TLSEXT_signature_rsa 1 +#define TLSEXT_signature_dsa 2 +#define TLSEXT_signature_ecdsa 3 +/* FIXME IANA */ +#define TLSEXT_signature_gostr01 237 +#define TLSEXT_signature_gostr12_256 238 +#define TLSEXT_signature_gostr12_512 239 + +#define TLSEXT_hash_none 0 +#define TLSEXT_hash_md5 1 +#define TLSEXT_hash_sha1 2 +#define TLSEXT_hash_sha224 3 +#define TLSEXT_hash_sha256 4 +#define TLSEXT_hash_sha384 5 +#define TLSEXT_hash_sha512 6 +/* FIXME IANA */ +#define TLSEXT_hash_gost94 237 +#define TLSEXT_hash_streebog_256 238 +#define TLSEXT_hash_streebog_512 239 + +#define TLSEXT_MAXLEN_host_name 255 + +const char *SSL_get_servername(const SSL *s, const int type); +int SSL_get_servername_type(const SSL *s); +/* SSL_export_keying_material exports a value derived from the master secret, + * as specified in RFC 5705. It writes |olen| bytes to |out| given a label and + * optional context. (Since a zero length context is allowed, the |use_context| + * flag controls whether a context is included.) + * + * It returns 1 on success and zero otherwise. + */ +int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, const unsigned char *p, size_t plen, + int use_context); + +#define SSL_set_tlsext_host_name(s,name) \ +SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name) + +#define SSL_set_tlsext_debug_callback(ssl, cb) \ +SSL_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_CB,(void (*)(void))cb) + +#define SSL_set_tlsext_debug_arg(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_ARG,0, (void *)arg) + +#define SSL_set_tlsext_status_type(ssl, type) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,type, NULL) + +#define SSL_get_tlsext_status_exts(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg) + +#define SSL_set_tlsext_status_exts(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg) + +#define SSL_get_tlsext_status_ids(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg) + +#define SSL_set_tlsext_status_ids(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg) + +#define SSL_get_tlsext_status_ocsp_resp(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP,0, (void *)arg) + +#define SSL_set_tlsext_status_ocsp_resp(ssl, arg, arglen) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,arglen, (void *)arg) + +#define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \ +SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,(void (*)(void))cb) + +#define SSL_TLSEXT_ERR_OK 0 +#define SSL_TLSEXT_ERR_ALERT_WARNING 1 +#define SSL_TLSEXT_ERR_ALERT_FATAL 2 +#define SSL_TLSEXT_ERR_NOACK 3 + +#define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \ +SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0, (void *)arg) + +#define SSL_CTX_get_tlsext_ticket_keys(ctx, keys, keylen) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_GET_TLSEXT_TICKET_KEYS,(keylen),(keys)) +#define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_SET_TLSEXT_TICKET_KEYS,(keylen),(keys)) + +#define SSL_CTX_set_tlsext_status_cb(ssl, cb) \ +SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,(void (*)(void))cb) + +#define SSL_CTX_set_tlsext_status_arg(ssl, arg) \ +SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0, (void *)arg) + +#define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \ +SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) + +/* PSK ciphersuites from RFC 4279. */ +#define TLS1_CK_PSK_WITH_RC4_128_SHA 0x0300008A +#define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA 0x0300008B +#define TLS1_CK_PSK_WITH_AES_128_CBC_SHA 0x0300008C +#define TLS1_CK_PSK_WITH_AES_256_CBC_SHA 0x0300008D + +/* Additional TLS ciphersuites from expired Internet Draft + * draft-ietf-tls-56-bit-ciphersuites-01.txt + * (available if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see + * s3_lib.c). We actually treat them like SSL 3.0 ciphers, which we probably + * shouldn't. Note that the first two are actually not in the IDs. */ +#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5 0x03000060 /* not in ID */ +#define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 0x03000061 /* not in ID */ +#define TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA 0x03000062 +#define TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA 0x03000063 +#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA 0x03000064 +#define TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA 0x03000065 +#define TLS1_CK_DHE_DSS_WITH_RC4_128_SHA 0x03000066 + +/* AES ciphersuites from RFC 3268. */ + +#define TLS1_CK_RSA_WITH_AES_128_SHA 0x0300002F +#define TLS1_CK_DH_DSS_WITH_AES_128_SHA 0x03000030 +#define TLS1_CK_DH_RSA_WITH_AES_128_SHA 0x03000031 +#define TLS1_CK_DHE_DSS_WITH_AES_128_SHA 0x03000032 +#define TLS1_CK_DHE_RSA_WITH_AES_128_SHA 0x03000033 +#define TLS1_CK_ADH_WITH_AES_128_SHA 0x03000034 + +#define TLS1_CK_RSA_WITH_AES_256_SHA 0x03000035 +#define TLS1_CK_DH_DSS_WITH_AES_256_SHA 0x03000036 +#define TLS1_CK_DH_RSA_WITH_AES_256_SHA 0x03000037 +#define TLS1_CK_DHE_DSS_WITH_AES_256_SHA 0x03000038 +#define TLS1_CK_DHE_RSA_WITH_AES_256_SHA 0x03000039 +#define TLS1_CK_ADH_WITH_AES_256_SHA 0x0300003A + +/* TLS v1.2 ciphersuites */ +#define TLS1_CK_RSA_WITH_NULL_SHA256 0x0300003B +#define TLS1_CK_RSA_WITH_AES_128_SHA256 0x0300003C +#define TLS1_CK_RSA_WITH_AES_256_SHA256 0x0300003D +#define TLS1_CK_DH_DSS_WITH_AES_128_SHA256 0x0300003E +#define TLS1_CK_DH_RSA_WITH_AES_128_SHA256 0x0300003F +#define TLS1_CK_DHE_DSS_WITH_AES_128_SHA256 0x03000040 + +/* Camellia ciphersuites from RFC 4132. */ +#define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000041 +#define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000042 +#define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000043 +#define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000044 +#define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000045 +#define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA 0x03000046 + +/* TLS v1.2 ciphersuites */ +#define TLS1_CK_DHE_RSA_WITH_AES_128_SHA256 0x03000067 +#define TLS1_CK_DH_DSS_WITH_AES_256_SHA256 0x03000068 +#define TLS1_CK_DH_RSA_WITH_AES_256_SHA256 0x03000069 +#define TLS1_CK_DHE_DSS_WITH_AES_256_SHA256 0x0300006A +#define TLS1_CK_DHE_RSA_WITH_AES_256_SHA256 0x0300006B +#define TLS1_CK_ADH_WITH_AES_128_SHA256 0x0300006C +#define TLS1_CK_ADH_WITH_AES_256_SHA256 0x0300006D + +/* Camellia ciphersuites from RFC 4132. */ +#define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000084 +#define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000085 +#define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000086 +#define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000087 +#define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000088 +#define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA 0x03000089 + +/* SEED ciphersuites from RFC 4162. */ +#define TLS1_CK_RSA_WITH_SEED_SHA 0x03000096 +#define TLS1_CK_DH_DSS_WITH_SEED_SHA 0x03000097 +#define TLS1_CK_DH_RSA_WITH_SEED_SHA 0x03000098 +#define TLS1_CK_DHE_DSS_WITH_SEED_SHA 0x03000099 +#define TLS1_CK_DHE_RSA_WITH_SEED_SHA 0x0300009A +#define TLS1_CK_ADH_WITH_SEED_SHA 0x0300009B + +/* TLS v1.2 GCM ciphersuites from RFC 5288. */ +#define TLS1_CK_RSA_WITH_AES_128_GCM_SHA256 0x0300009C +#define TLS1_CK_RSA_WITH_AES_256_GCM_SHA384 0x0300009D +#define TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256 0x0300009E +#define TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384 0x0300009F +#define TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256 0x030000A0 +#define TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384 0x030000A1 +#define TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256 0x030000A2 +#define TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384 0x030000A3 +#define TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256 0x030000A4 +#define TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384 0x030000A5 +#define TLS1_CK_ADH_WITH_AES_128_GCM_SHA256 0x030000A6 +#define TLS1_CK_ADH_WITH_AES_256_GCM_SHA384 0x030000A7 + +/* TLS 1.2 Camellia SHA-256 ciphersuites from RFC5932 */ +#define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x030000BA +#define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 0x030000BB +#define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x030000BC +#define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 0x030000BD +#define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x030000BE +#define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA256 0x030000BF + +#define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA256 0x030000C0 +#define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 0x030000C1 +#define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 0x030000C2 +#define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 0x030000C3 +#define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 0x030000C4 +#define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA256 0x030000C5 + +/* ECC ciphersuites from RFC 4492. */ +#define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA 0x0300C001 +#define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA 0x0300C002 +#define TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C003 +#define TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0x0300C004 +#define TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0x0300C005 + +#define TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA 0x0300C006 +#define TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA 0x0300C007 +#define TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C008 +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0x0300C009 +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0x0300C00A + +#define TLS1_CK_ECDH_RSA_WITH_NULL_SHA 0x0300C00B +#define TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA 0x0300C00C +#define TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA 0x0300C00D +#define TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA 0x0300C00E +#define TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA 0x0300C00F + +#define TLS1_CK_ECDHE_RSA_WITH_NULL_SHA 0x0300C010 +#define TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA 0x0300C011 +#define TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA 0x0300C012 +#define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA 0x0300C013 +#define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA 0x0300C014 + +#define TLS1_CK_ECDH_anon_WITH_NULL_SHA 0x0300C015 +#define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA 0x0300C016 +#define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA 0x0300C017 +#define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA 0x0300C018 +#define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA 0x0300C019 + +/* SRP ciphersuites from RFC 5054. */ +#define TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA 0x0300C01A +#define TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA 0x0300C01B +#define TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA 0x0300C01C +#define TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA 0x0300C01D +#define TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA 0x0300C01E +#define TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA 0x0300C01F +#define TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA 0x0300C020 +#define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA 0x0300C021 +#define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA 0x0300C022 + +/* ECDH HMAC based ciphersuites from RFC 5289. */ +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256 0x0300C023 +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384 0x0300C024 +#define TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256 0x0300C025 +#define TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384 0x0300C026 +#define TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256 0x0300C027 +#define TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384 0x0300C028 +#define TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256 0x0300C029 +#define TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384 0x0300C02A + +/* ECDH GCM based ciphersuites from RFC 5289. */ +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02B +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02C +#define TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02D +#define TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02E +#define TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0x0300C02F +#define TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0x0300C030 +#define TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256 0x0300C031 +#define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384 0x0300C032 + +/* ChaCha20-Poly1305 based ciphersuites. */ +#define TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD 0x0300CC13 +#define TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD 0x0300CC14 +#define TLS1_CK_DHE_RSA_CHACHA20_POLY1305_OLD 0x0300CC15 +#define TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305 0x0300CCA8 +#define TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305 0x0300CCA9 +#define TLS1_CK_DHE_RSA_CHACHA20_POLY1305 0x0300CCAA + +#define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5 "EXP1024-RC4-MD5" +#define TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 "EXP1024-RC2-CBC-MD5" +#define TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA "EXP1024-DES-CBC-SHA" +#define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA "EXP1024-DHE-DSS-DES-CBC-SHA" +#define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA "EXP1024-RC4-SHA" +#define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA "EXP1024-DHE-DSS-RC4-SHA" +#define TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA "DHE-DSS-RC4-SHA" + +/* AES ciphersuites from RFC 3268. */ +#define TLS1_TXT_RSA_WITH_AES_128_SHA "AES128-SHA" +#define TLS1_TXT_DH_DSS_WITH_AES_128_SHA "DH-DSS-AES128-SHA" +#define TLS1_TXT_DH_RSA_WITH_AES_128_SHA "DH-RSA-AES128-SHA" +#define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA "DHE-DSS-AES128-SHA" +#define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA "DHE-RSA-AES128-SHA" +#define TLS1_TXT_ADH_WITH_AES_128_SHA "ADH-AES128-SHA" + +#define TLS1_TXT_RSA_WITH_AES_256_SHA "AES256-SHA" +#define TLS1_TXT_DH_DSS_WITH_AES_256_SHA "DH-DSS-AES256-SHA" +#define TLS1_TXT_DH_RSA_WITH_AES_256_SHA "DH-RSA-AES256-SHA" +#define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA "DHE-DSS-AES256-SHA" +#define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA "DHE-RSA-AES256-SHA" +#define TLS1_TXT_ADH_WITH_AES_256_SHA "ADH-AES256-SHA" + +/* ECC ciphersuites from draft-ietf-tls-ecc-01.txt (Mar 15, 2001) */ +#define TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA "ECDH-ECDSA-NULL-SHA" +#define TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA "ECDH-ECDSA-RC4-SHA" +#define TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA "ECDH-ECDSA-DES-CBC3-SHA" +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA "ECDH-ECDSA-AES128-SHA" +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA "ECDH-ECDSA-AES256-SHA" + +#define TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA "ECDHE-ECDSA-NULL-SHA" +#define TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA "ECDHE-ECDSA-RC4-SHA" +#define TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA "ECDHE-ECDSA-DES-CBC3-SHA" +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA "ECDHE-ECDSA-AES128-SHA" +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA "ECDHE-ECDSA-AES256-SHA" + +#define TLS1_TXT_ECDH_RSA_WITH_NULL_SHA "ECDH-RSA-NULL-SHA" +#define TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA "ECDH-RSA-RC4-SHA" +#define TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA "ECDH-RSA-DES-CBC3-SHA" +#define TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA "ECDH-RSA-AES128-SHA" +#define TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA "ECDH-RSA-AES256-SHA" + +#define TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA "ECDHE-RSA-NULL-SHA" +#define TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA "ECDHE-RSA-RC4-SHA" +#define TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA "ECDHE-RSA-DES-CBC3-SHA" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA "ECDHE-RSA-AES128-SHA" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA "ECDHE-RSA-AES256-SHA" + +#define TLS1_TXT_ECDH_anon_WITH_NULL_SHA "AECDH-NULL-SHA" +#define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA "AECDH-RC4-SHA" +#define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA "AECDH-DES-CBC3-SHA" +#define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA "AECDH-AES128-SHA" +#define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA "AECDH-AES256-SHA" + +/* PSK ciphersuites from RFC 4279. */ +#define TLS1_TXT_PSK_WITH_RC4_128_SHA "PSK-RC4-SHA" +#define TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA "PSK-3DES-EDE-CBC-SHA" +#define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA "PSK-AES128-CBC-SHA" +#define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA "PSK-AES256-CBC-SHA" + +/* SRP ciphersuite from RFC 5054. */ +#define TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA "SRP-3DES-EDE-CBC-SHA" +#define TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA "SRP-RSA-3DES-EDE-CBC-SHA" +#define TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA "SRP-DSS-3DES-EDE-CBC-SHA" +#define TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA "SRP-AES-128-CBC-SHA" +#define TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA "SRP-RSA-AES-128-CBC-SHA" +#define TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA "SRP-DSS-AES-128-CBC-SHA" +#define TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA "SRP-AES-256-CBC-SHA" +#define TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA "SRP-RSA-AES-256-CBC-SHA" +#define TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA "SRP-DSS-AES-256-CBC-SHA" + +/* Camellia ciphersuites from RFC 4132. */ +#define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA "CAMELLIA128-SHA" +#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA "DH-DSS-CAMELLIA128-SHA" +#define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA "DH-RSA-CAMELLIA128-SHA" +#define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA "DHE-DSS-CAMELLIA128-SHA" +#define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA "DHE-RSA-CAMELLIA128-SHA" +#define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA "ADH-CAMELLIA128-SHA" + +#define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA "CAMELLIA256-SHA" +#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA "DH-DSS-CAMELLIA256-SHA" +#define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA "DH-RSA-CAMELLIA256-SHA" +#define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA "DHE-DSS-CAMELLIA256-SHA" +#define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA "DHE-RSA-CAMELLIA256-SHA" +#define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA "ADH-CAMELLIA256-SHA" + +/* TLS 1.2 Camellia SHA-256 ciphersuites from RFC5932 */ +#define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA256 "CAMELLIA128-SHA256" +#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 "DH-DSS-CAMELLIA128-SHA256" +#define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 "DH-RSA-CAMELLIA128-SHA256" +#define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 "DHE-DSS-CAMELLIA128-SHA256" +#define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 "DHE-RSA-CAMELLIA128-SHA256" +#define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA256 "ADH-CAMELLIA128-SHA256" + +#define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA256 "CAMELLIA256-SHA256" +#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 "DH-DSS-CAMELLIA256-SHA256" +#define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 "DH-RSA-CAMELLIA256-SHA256" +#define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 "DHE-DSS-CAMELLIA256-SHA256" +#define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 "DHE-RSA-CAMELLIA256-SHA256" +#define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA256 "ADH-CAMELLIA256-SHA256" + +/* SEED ciphersuites from RFC 4162. */ +#define TLS1_TXT_RSA_WITH_SEED_SHA "SEED-SHA" +#define TLS1_TXT_DH_DSS_WITH_SEED_SHA "DH-DSS-SEED-SHA" +#define TLS1_TXT_DH_RSA_WITH_SEED_SHA "DH-RSA-SEED-SHA" +#define TLS1_TXT_DHE_DSS_WITH_SEED_SHA "DHE-DSS-SEED-SHA" +#define TLS1_TXT_DHE_RSA_WITH_SEED_SHA "DHE-RSA-SEED-SHA" +#define TLS1_TXT_ADH_WITH_SEED_SHA "ADH-SEED-SHA" + +/* TLS v1.2 ciphersuites. */ +#define TLS1_TXT_RSA_WITH_NULL_SHA256 "NULL-SHA256" +#define TLS1_TXT_RSA_WITH_AES_128_SHA256 "AES128-SHA256" +#define TLS1_TXT_RSA_WITH_AES_256_SHA256 "AES256-SHA256" +#define TLS1_TXT_DH_DSS_WITH_AES_128_SHA256 "DH-DSS-AES128-SHA256" +#define TLS1_TXT_DH_RSA_WITH_AES_128_SHA256 "DH-RSA-AES128-SHA256" +#define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256 "DHE-DSS-AES128-SHA256" +#define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256 "DHE-RSA-AES128-SHA256" +#define TLS1_TXT_DH_DSS_WITH_AES_256_SHA256 "DH-DSS-AES256-SHA256" +#define TLS1_TXT_DH_RSA_WITH_AES_256_SHA256 "DH-RSA-AES256-SHA256" +#define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256 "DHE-DSS-AES256-SHA256" +#define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256 "DHE-RSA-AES256-SHA256" +#define TLS1_TXT_ADH_WITH_AES_128_SHA256 "ADH-AES128-SHA256" +#define TLS1_TXT_ADH_WITH_AES_256_SHA256 "ADH-AES256-SHA256" + +/* TLS v1.2 GCM ciphersuites from RFC 5288. */ +#define TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256 "AES128-GCM-SHA256" +#define TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384 "AES256-GCM-SHA384" +#define TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256 "DHE-RSA-AES128-GCM-SHA256" +#define TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384 "DHE-RSA-AES256-GCM-SHA384" +#define TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256 "DH-RSA-AES128-GCM-SHA256" +#define TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384 "DH-RSA-AES256-GCM-SHA384" +#define TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256 "DHE-DSS-AES128-GCM-SHA256" +#define TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384 "DHE-DSS-AES256-GCM-SHA384" +#define TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256 "DH-DSS-AES128-GCM-SHA256" +#define TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384 "DH-DSS-AES256-GCM-SHA384" +#define TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256 "ADH-AES128-GCM-SHA256" +#define TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384 "ADH-AES256-GCM-SHA384" + +/* ECDH HMAC based ciphersuites from RFC 5289. */ + +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256 "ECDHE-ECDSA-AES128-SHA256" +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384 "ECDHE-ECDSA-AES256-SHA384" +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256 "ECDH-ECDSA-AES128-SHA256" +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384 "ECDH-ECDSA-AES256-SHA384" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256 "ECDHE-RSA-AES128-SHA256" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384 "ECDHE-RSA-AES256-SHA384" +#define TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256 "ECDH-RSA-AES128-SHA256" +#define TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384 "ECDH-RSA-AES256-SHA384" + +/* ECDH GCM based ciphersuites from RFC 5289. */ +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 "ECDHE-ECDSA-AES128-GCM-SHA256" +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 "ECDHE-ECDSA-AES256-GCM-SHA384" +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 "ECDH-ECDSA-AES128-GCM-SHA256" +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 "ECDH-ECDSA-AES256-GCM-SHA384" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256 "ECDHE-RSA-AES128-GCM-SHA256" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384 "ECDHE-RSA-AES256-GCM-SHA384" +#define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256 "ECDH-RSA-AES128-GCM-SHA256" +#define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384 "ECDH-RSA-AES256-GCM-SHA384" + +/* ChaCha20-Poly1305 based ciphersuites. */ +#define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_OLD "ECDHE-RSA-CHACHA20-POLY1305-OLD" +#define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_OLD "ECDHE-ECDSA-CHACHA20-POLY1305-OLD" +#define TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305_OLD "DHE-RSA-CHACHA20-POLY1305-OLD" +#define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305 "ECDHE-RSA-CHACHA20-POLY1305" +#define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 "ECDHE-ECDSA-CHACHA20-POLY1305" +#define TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305 "DHE-RSA-CHACHA20-POLY1305" + +#define TLS_CT_RSA_SIGN 1 +#define TLS_CT_DSS_SIGN 2 +#define TLS_CT_RSA_FIXED_DH 3 +#define TLS_CT_DSS_FIXED_DH 4 +#define TLS_CT_ECDSA_SIGN 64 +#define TLS_CT_RSA_FIXED_ECDH 65 +#define TLS_CT_ECDSA_FIXED_ECDH 66 +#define TLS_CT_GOST94_SIGN 21 +#define TLS_CT_GOST01_SIGN 22 +#define TLS_CT_GOST12_256_SIGN 238 /* FIXME: IANA */ +#define TLS_CT_GOST12_512_SIGN 239 /* FIXME: IANA */ +/* when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see + * comment there) */ +#define TLS_CT_NUMBER 11 + +#define TLS1_FINISH_MAC_LENGTH 12 + +#define TLS_MD_MAX_CONST_SIZE 20 +#define TLS_MD_CLIENT_FINISH_CONST "client finished" +#define TLS_MD_CLIENT_FINISH_CONST_SIZE 15 +#define TLS_MD_SERVER_FINISH_CONST "server finished" +#define TLS_MD_SERVER_FINISH_CONST_SIZE 15 +#define TLS_MD_SERVER_WRITE_KEY_CONST "server write key" +#define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE 16 +#define TLS_MD_KEY_EXPANSION_CONST "key expansion" +#define TLS_MD_KEY_EXPANSION_CONST_SIZE 13 +#define TLS_MD_CLIENT_WRITE_KEY_CONST "client write key" +#define TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE 16 +#define TLS_MD_SERVER_WRITE_KEY_CONST "server write key" +#define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE 16 +#define TLS_MD_IV_BLOCK_CONST "IV block" +#define TLS_MD_IV_BLOCK_CONST_SIZE 8 +#define TLS_MD_MASTER_SECRET_CONST "master secret" +#define TLS_MD_MASTER_SECRET_CONST_SIZE 13 + +/* TLS Session Ticket extension struct. */ +struct tls_session_ticket_ext_st { + unsigned short length; + void *data; +}; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/ts.h b/crypto/libressl/include/openssl/ts.h new file mode 100644 index 0000000000..a4cdba149b --- /dev/null +++ b/crypto/libressl/include/openssl/ts.h @@ -0,0 +1,839 @@ +/* $OpenBSD: ts.h,v 1.6 2014/06/12 15:49:30 deraadt Exp $ */ +/* Written by Zoltan Glozik (zglozik@opentsa.org) for the OpenSSL + * project 2002, 2003, 2004. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_TS_H +#define HEADER_TS_H + +#include + +#ifndef OPENSSL_NO_BUFFER +#include +#endif +#ifndef OPENSSL_NO_EVP +#include +#endif +#ifndef OPENSSL_NO_BIO +#include +#endif +#include +#include +#include + +#ifndef OPENSSL_NO_RSA +#include +#endif + +#ifndef OPENSSL_NO_DSA +#include +#endif + +#ifndef OPENSSL_NO_DH +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* +MessageImprint ::= SEQUENCE { + hashAlgorithm AlgorithmIdentifier, + hashedMessage OCTET STRING } +*/ + +typedef struct TS_msg_imprint_st { + X509_ALGOR *hash_algo; + ASN1_OCTET_STRING *hashed_msg; +} TS_MSG_IMPRINT; + +/* +TimeStampReq ::= SEQUENCE { + version INTEGER { v1(1) }, + messageImprint MessageImprint, + --a hash algorithm OID and the hash value of the data to be + --time-stamped + reqPolicy TSAPolicyId OPTIONAL, + nonce INTEGER OPTIONAL, + certReq BOOLEAN DEFAULT FALSE, + extensions [0] IMPLICIT Extensions OPTIONAL } +*/ + +typedef struct TS_req_st { + ASN1_INTEGER *version; + TS_MSG_IMPRINT *msg_imprint; + ASN1_OBJECT *policy_id; /* OPTIONAL */ + ASN1_INTEGER *nonce; /* OPTIONAL */ + ASN1_BOOLEAN cert_req; /* DEFAULT FALSE */ + STACK_OF(X509_EXTENSION) *extensions; /* [0] OPTIONAL */ +} TS_REQ; + +/* +Accuracy ::= SEQUENCE { + seconds INTEGER OPTIONAL, + millis [0] INTEGER (1..999) OPTIONAL, + micros [1] INTEGER (1..999) OPTIONAL } +*/ + +typedef struct TS_accuracy_st { + ASN1_INTEGER *seconds; + ASN1_INTEGER *millis; + ASN1_INTEGER *micros; +} TS_ACCURACY; + +/* +TSTInfo ::= SEQUENCE { + version INTEGER { v1(1) }, + policy TSAPolicyId, + messageImprint MessageImprint, + -- MUST have the same value as the similar field in + -- TimeStampReq + serialNumber INTEGER, + -- Time-Stamping users MUST be ready to accommodate integers + -- up to 160 bits. + genTime GeneralizedTime, + accuracy Accuracy OPTIONAL, + ordering BOOLEAN DEFAULT FALSE, + nonce INTEGER OPTIONAL, + -- MUST be present if the similar field was present + -- in TimeStampReq. In that case it MUST have the same value. + tsa [0] GeneralName OPTIONAL, + extensions [1] IMPLICIT Extensions OPTIONAL } +*/ + +typedef struct TS_tst_info_st { + ASN1_INTEGER *version; + ASN1_OBJECT *policy_id; + TS_MSG_IMPRINT *msg_imprint; + ASN1_INTEGER *serial; + ASN1_GENERALIZEDTIME *time; + TS_ACCURACY *accuracy; + ASN1_BOOLEAN ordering; + ASN1_INTEGER *nonce; + GENERAL_NAME *tsa; + STACK_OF(X509_EXTENSION) *extensions; +} TS_TST_INFO; + +/* +PKIStatusInfo ::= SEQUENCE { + status PKIStatus, + statusString PKIFreeText OPTIONAL, + failInfo PKIFailureInfo OPTIONAL } + +From RFC 1510 - section 3.1.1: +PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String + -- text encoded as UTF-8 String (note: each UTF8String SHOULD + -- include an RFC 1766 language tag to indicate the language + -- of the contained text) +*/ + +/* Possible values for status. See ts_resp_print.c && ts_resp_verify.c. */ + +#define TS_STATUS_GRANTED 0 +#define TS_STATUS_GRANTED_WITH_MODS 1 +#define TS_STATUS_REJECTION 2 +#define TS_STATUS_WAITING 3 +#define TS_STATUS_REVOCATION_WARNING 4 +#define TS_STATUS_REVOCATION_NOTIFICATION 5 + +/* Possible values for failure_info. See ts_resp_print.c && ts_resp_verify.c */ + +#define TS_INFO_BAD_ALG 0 +#define TS_INFO_BAD_REQUEST 2 +#define TS_INFO_BAD_DATA_FORMAT 5 +#define TS_INFO_TIME_NOT_AVAILABLE 14 +#define TS_INFO_UNACCEPTED_POLICY 15 +#define TS_INFO_UNACCEPTED_EXTENSION 16 +#define TS_INFO_ADD_INFO_NOT_AVAILABLE 17 +#define TS_INFO_SYSTEM_FAILURE 25 + +typedef struct TS_status_info_st { + ASN1_INTEGER *status; + STACK_OF(ASN1_UTF8STRING) *text; + ASN1_BIT_STRING *failure_info; +} TS_STATUS_INFO; + +DECLARE_STACK_OF(ASN1_UTF8STRING) +DECLARE_ASN1_SET_OF(ASN1_UTF8STRING) + +/* +TimeStampResp ::= SEQUENCE { + status PKIStatusInfo, + timeStampToken TimeStampToken OPTIONAL } +*/ + +typedef struct TS_resp_st { + TS_STATUS_INFO *status_info; + PKCS7 *token; + TS_TST_INFO *tst_info; +} TS_RESP; + +/* The structure below would belong to the ESS component. */ + +/* +IssuerSerial ::= SEQUENCE { + issuer GeneralNames, + serialNumber CertificateSerialNumber + } +*/ + +typedef struct ESS_issuer_serial { + STACK_OF(GENERAL_NAME) *issuer; + ASN1_INTEGER *serial; +} ESS_ISSUER_SERIAL; + +/* +ESSCertID ::= SEQUENCE { + certHash Hash, + issuerSerial IssuerSerial OPTIONAL +} +*/ + +typedef struct ESS_cert_id { + ASN1_OCTET_STRING *hash; /* Always SHA-1 digest. */ + ESS_ISSUER_SERIAL *issuer_serial; +} ESS_CERT_ID; + +DECLARE_STACK_OF(ESS_CERT_ID) +DECLARE_ASN1_SET_OF(ESS_CERT_ID) + +/* +SigningCertificate ::= SEQUENCE { + certs SEQUENCE OF ESSCertID, + policies SEQUENCE OF PolicyInformation OPTIONAL +} +*/ + +typedef struct ESS_signing_cert { + STACK_OF(ESS_CERT_ID) *cert_ids; + STACK_OF(POLICYINFO) *policy_info; +} ESS_SIGNING_CERT; + + +TS_REQ *TS_REQ_new(void); +void TS_REQ_free(TS_REQ *a); +int i2d_TS_REQ(const TS_REQ *a, unsigned char **pp); +TS_REQ *d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length); + +TS_REQ *TS_REQ_dup(TS_REQ *a); + +TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a); +int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a); +TS_REQ *d2i_TS_REQ_bio(BIO *fp, TS_REQ **a); +int i2d_TS_REQ_bio(BIO *fp, TS_REQ *a); + +TS_MSG_IMPRINT *TS_MSG_IMPRINT_new(void); +void TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a); +int i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp); +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a, + const unsigned char **pp, long length); + +TS_MSG_IMPRINT *TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a); + +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a); +int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a); +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT **a); +int i2d_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT *a); + +TS_RESP *TS_RESP_new(void); +void TS_RESP_free(TS_RESP *a); +int i2d_TS_RESP(const TS_RESP *a, unsigned char **pp); +TS_RESP *d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length); +TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token); +TS_RESP *TS_RESP_dup(TS_RESP *a); + +TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a); +int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a); +TS_RESP *d2i_TS_RESP_bio(BIO *fp, TS_RESP **a); +int i2d_TS_RESP_bio(BIO *fp, TS_RESP *a); + +TS_STATUS_INFO *TS_STATUS_INFO_new(void); +void TS_STATUS_INFO_free(TS_STATUS_INFO *a); +int i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp); +TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a, + const unsigned char **pp, long length); +TS_STATUS_INFO *TS_STATUS_INFO_dup(TS_STATUS_INFO *a); + +TS_TST_INFO *TS_TST_INFO_new(void); +void TS_TST_INFO_free(TS_TST_INFO *a); +int i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp); +TS_TST_INFO *d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp, + long length); +TS_TST_INFO *TS_TST_INFO_dup(TS_TST_INFO *a); + +TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a); +int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a); +TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO **a); +int i2d_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO *a); + +TS_ACCURACY *TS_ACCURACY_new(void); +void TS_ACCURACY_free(TS_ACCURACY *a); +int i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp); +TS_ACCURACY *d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp, + long length); +TS_ACCURACY *TS_ACCURACY_dup(TS_ACCURACY *a); + +ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void); +void ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a); +int i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a, + unsigned char **pp); +ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a, + const unsigned char **pp, long length); +ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a); + +ESS_CERT_ID *ESS_CERT_ID_new(void); +void ESS_CERT_ID_free(ESS_CERT_ID *a); +int i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp); +ESS_CERT_ID *d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp, + long length); +ESS_CERT_ID *ESS_CERT_ID_dup(ESS_CERT_ID *a); + +ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void); +void ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a); +int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, + unsigned char **pp); +ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a, + const unsigned char **pp, long length); +ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a); + +void ERR_load_TS_strings(void); + +int TS_REQ_set_version(TS_REQ *a, long version); +long TS_REQ_get_version(const TS_REQ *a); + +int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint); +TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a); + +int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg); +X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a); + +int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len); +ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a); + +int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy); +ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a); + +int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce); +const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a); + +int TS_REQ_set_cert_req(TS_REQ *a, int cert_req); +int TS_REQ_get_cert_req(const TS_REQ *a); + +STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a); +void TS_REQ_ext_free(TS_REQ *a); +int TS_REQ_get_ext_count(TS_REQ *a); +int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos); +int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos); +int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos); +X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc); +X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc); +int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc); +void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx); + +/* Function declarations for TS_REQ defined in ts/ts_req_print.c */ + +int TS_REQ_print_bio(BIO *bio, TS_REQ *a); + +/* Function declarations for TS_RESP defined in ts/ts_resp_utils.c */ + +int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *info); +TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a); + +/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */ +void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info); +PKCS7 *TS_RESP_get_token(TS_RESP *a); +TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a); + +int TS_TST_INFO_set_version(TS_TST_INFO *a, long version); +long TS_TST_INFO_get_version(const TS_TST_INFO *a); + +int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy_id); +ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a); + +int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint); +TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a); + +int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial); +const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a); + +int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime); +const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a); + +int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy); +TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a); + +int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds); +const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a); + +int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis); +const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a); + +int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros); +const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a); + +int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering); +int TS_TST_INFO_get_ordering(const TS_TST_INFO *a); + +int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce); +const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a); + +int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa); +GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a); + +STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a); +void TS_TST_INFO_ext_free(TS_TST_INFO *a); +int TS_TST_INFO_get_ext_count(TS_TST_INFO *a); +int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos); +int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos); +int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos); +X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc); +X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc); +int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc); +void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx); + +/* Declarations related to response generation, defined in ts/ts_resp_sign.c. */ + +/* Optional flags for response generation. */ + +/* Don't include the TSA name in response. */ +#define TS_TSA_NAME 0x01 + +/* Set ordering to true in response. */ +#define TS_ORDERING 0x02 + +/* + * Include the signer certificate and the other specified certificates in + * the ESS signing certificate attribute beside the PKCS7 signed data. + * Only the signer certificates is included by default. + */ +#define TS_ESS_CERT_ID_CHAIN 0x04 + +/* Forward declaration. */ +struct TS_resp_ctx; + +/* This must return a unique number less than 160 bits long. */ +typedef ASN1_INTEGER *(*TS_serial_cb)(struct TS_resp_ctx *, void *); + +/* This must return the seconds and microseconds since Jan 1, 1970 in + the sec and usec variables allocated by the caller. + Return non-zero for success and zero for failure. */ +typedef int (*TS_time_cb)(struct TS_resp_ctx *, void *, time_t *sec, long *usec); + +/* This must process the given extension. + * It can modify the TS_TST_INFO object of the context. + * Return values: !0 (processed), 0 (error, it must set the + * status info/failure info of the response). + */ +typedef int (*TS_extension_cb)(struct TS_resp_ctx *, X509_EXTENSION *, void *); + +typedef struct TS_resp_ctx { + X509 *signer_cert; + EVP_PKEY *signer_key; + STACK_OF(X509) *certs; /* Certs to include in signed data. */ + STACK_OF(ASN1_OBJECT) *policies; /* Acceptable policies. */ + ASN1_OBJECT *default_policy; /* It may appear in policies, too. */ + STACK_OF(EVP_MD) *mds; /* Acceptable message digests. */ + ASN1_INTEGER *seconds; /* accuracy, 0 means not specified. */ + ASN1_INTEGER *millis; /* accuracy, 0 means not specified. */ + ASN1_INTEGER *micros; /* accuracy, 0 means not specified. */ + unsigned clock_precision_digits; /* fraction of seconds in + time stamp token. */ + unsigned flags; /* Optional info, see values above. */ + + /* Callback functions. */ + TS_serial_cb serial_cb; + void *serial_cb_data; /* User data for serial_cb. */ + + TS_time_cb time_cb; + void *time_cb_data; /* User data for time_cb. */ + + TS_extension_cb extension_cb; + void *extension_cb_data; /* User data for extension_cb. */ + + /* These members are used only while creating the response. */ + TS_REQ *request; + TS_RESP *response; + TS_TST_INFO *tst_info; +} TS_RESP_CTX; + +DECLARE_STACK_OF(EVP_MD) +DECLARE_ASN1_SET_OF(EVP_MD) + +/* Creates a response context that can be used for generating responses. */ +TS_RESP_CTX *TS_RESP_CTX_new(void); +void TS_RESP_CTX_free(TS_RESP_CTX *ctx); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy); + +/* No additional certs are included in the response by default. */ +int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs); + +/* Adds a new acceptable policy, only the default policy + is accepted by default. */ +int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy); + +/* Adds a new acceptable message digest. Note that no message digests + are accepted by default. The md argument is shared with the caller. */ +int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md); + +/* Accuracy is not included by default. */ +int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, + int secs, int millis, int micros); + +/* Clock precision digits, i.e. the number of decimal digits: + '0' means sec, '3' msec, '6' usec, and so on. Default is 0. */ +int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, + unsigned clock_precision_digits); +/* At most we accept usec precision. */ +#define TS_MAX_CLOCK_PRECISION_DIGITS 6 + +/* No flags are set by default. */ +void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags); + +/* Default callback always returns a constant. */ +void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data); + +/* Default callback rejects all extensions. The extension callback is called + * when the TS_TST_INFO object is already set up and not signed yet. */ +/* FIXME: extension handling is not tested yet. */ +void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, + TS_extension_cb cb, void *data); + +/* The following methods can be used in the callbacks. */ +int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, + int status, const char *text); + +/* Sets the status info only if it is still TS_STATUS_GRANTED. */ +int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, + int status, const char *text); + +int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure); + +/* The get methods below can be used in the extension callback. */ +TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx); + +TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx); + +/* + * Creates the signed TS_TST_INFO and puts it in TS_RESP. + * In case of errors it sets the status info properly. + * Returns NULL only in case of memory allocation/fatal error. + */ +TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio); + +/* + * Declarations related to response verification, + * they are defined in ts/ts_resp_verify.c. + */ + +int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, + X509_STORE *store, X509 **signer_out); + +/* Context structure for the generic verify method. */ + +/* Verify the signer's certificate and the signature of the response. */ +#define TS_VFY_SIGNATURE (1u << 0) +/* Verify the version number of the response. */ +#define TS_VFY_VERSION (1u << 1) +/* Verify if the policy supplied by the user matches the policy of the TSA. */ +#define TS_VFY_POLICY (1u << 2) +/* Verify the message imprint provided by the user. This flag should not be + specified with TS_VFY_DATA. */ +#define TS_VFY_IMPRINT (1u << 3) +/* Verify the message imprint computed by the verify method from the user + provided data and the MD algorithm of the response. This flag should not be + specified with TS_VFY_IMPRINT. */ +#define TS_VFY_DATA (1u << 4) +/* Verify the nonce value. */ +#define TS_VFY_NONCE (1u << 5) +/* Verify if the TSA name field matches the signer certificate. */ +#define TS_VFY_SIGNER (1u << 6) +/* Verify if the TSA name field equals to the user provided name. */ +#define TS_VFY_TSA_NAME (1u << 7) + +/* You can use the following convenience constants. */ +#define TS_VFY_ALL_IMPRINT (TS_VFY_SIGNATURE \ + | TS_VFY_VERSION \ + | TS_VFY_POLICY \ + | TS_VFY_IMPRINT \ + | TS_VFY_NONCE \ + | TS_VFY_SIGNER \ + | TS_VFY_TSA_NAME) +#define TS_VFY_ALL_DATA (TS_VFY_SIGNATURE \ + | TS_VFY_VERSION \ + | TS_VFY_POLICY \ + | TS_VFY_DATA \ + | TS_VFY_NONCE \ + | TS_VFY_SIGNER \ + | TS_VFY_TSA_NAME) + +typedef struct TS_verify_ctx { + /* Set this to the union of TS_VFY_... flags you want to carry out. */ + unsigned flags; + + /* Must be set only with TS_VFY_SIGNATURE. certs is optional. */ + X509_STORE *store; + STACK_OF(X509) *certs; + + /* Must be set only with TS_VFY_POLICY. */ + ASN1_OBJECT *policy; + + /* Must be set only with TS_VFY_IMPRINT. If md_alg is NULL, + the algorithm from the response is used. */ + X509_ALGOR *md_alg; + unsigned char *imprint; + unsigned imprint_len; + + /* Must be set only with TS_VFY_DATA. */ + BIO *data; + + /* Must be set only with TS_VFY_TSA_NAME. */ + ASN1_INTEGER *nonce; + + /* Must be set only with TS_VFY_TSA_NAME. */ + GENERAL_NAME *tsa_name; +} TS_VERIFY_CTX; + +int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response); +int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token); + +/* + * Declarations related to response verification context, + * they are defined in ts/ts_verify_ctx.c. + */ + +/* Set all fields to zero. */ +TS_VERIFY_CTX *TS_VERIFY_CTX_new(void); +void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx); +void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx); +void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx); + +/* + * If ctx is NULL, it allocates and returns a new object, otherwise + * it returns ctx. It initialises all the members as follows: + * flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE) + * certs = NULL + * store = NULL + * policy = policy from the request or NULL if absent (in this case + * TS_VFY_POLICY is cleared from flags as well) + * md_alg = MD algorithm from request + * imprint, imprint_len = imprint from request + * data = NULL + * nonce, nonce_len = nonce from the request or NULL if absent (in this case + * TS_VFY_NONCE is cleared from flags as well) + * tsa_name = NULL + * Important: after calling this method TS_VFY_SIGNATURE should be added! + */ +TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx); + +/* Function declarations for TS_RESP defined in ts/ts_resp_print.c */ + +int TS_RESP_print_bio(BIO *bio, TS_RESP *a); +int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a); +int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a); + +/* Common utility functions defined in ts/ts_lib.c */ + +int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num); +int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj); +int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions); +int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg); +int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg); + +/* Function declarations for handling configuration options, + defined in ts/ts_conf.c */ + +X509 *TS_CONF_load_cert(const char *file); +STACK_OF(X509) *TS_CONF_load_certs(const char *file); +EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass); +const char *TS_CONF_get_tsa_section(CONF *conf, const char *section); +int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb, + TS_RESP_CTX *ctx); +int TS_CONF_set_crypto_device(CONF *conf, const char *section, + const char *device); +int TS_CONF_set_default_engine(const char *name); +int TS_CONF_set_signer_cert(CONF *conf, const char *section, + const char *cert, TS_RESP_CTX *ctx); +int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs, + TS_RESP_CTX *ctx); +int TS_CONF_set_signer_key(CONF *conf, const char *section, + const char *key, const char *pass, TS_RESP_CTX *ctx); +int TS_CONF_set_def_policy(CONF *conf, const char *section, + const char *policy, TS_RESP_CTX *ctx); +int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section, + TS_RESP_CTX *ctx); +int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section, + TS_RESP_CTX *ctx); + +/* -------------------------------------------------- */ +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_TS_strings(void); + +/* Error codes for the TS functions. */ + +/* Function codes. */ +#define TS_F_D2I_TS_RESP 147 +#define TS_F_DEF_SERIAL_CB 110 +#define TS_F_DEF_TIME_CB 111 +#define TS_F_ESS_ADD_SIGNING_CERT 112 +#define TS_F_ESS_CERT_ID_NEW_INIT 113 +#define TS_F_ESS_SIGNING_CERT_NEW_INIT 114 +#define TS_F_INT_TS_RESP_VERIFY_TOKEN 149 +#define TS_F_PKCS7_TO_TS_TST_INFO 148 +#define TS_F_TS_ACCURACY_SET_MICROS 115 +#define TS_F_TS_ACCURACY_SET_MILLIS 116 +#define TS_F_TS_ACCURACY_SET_SECONDS 117 +#define TS_F_TS_CHECK_IMPRINTS 100 +#define TS_F_TS_CHECK_NONCES 101 +#define TS_F_TS_CHECK_POLICY 102 +#define TS_F_TS_CHECK_SIGNING_CERTS 103 +#define TS_F_TS_CHECK_STATUS_INFO 104 +#define TS_F_TS_COMPUTE_IMPRINT 145 +#define TS_F_TS_CONF_SET_DEFAULT_ENGINE 146 +#define TS_F_TS_GET_STATUS_TEXT 105 +#define TS_F_TS_MSG_IMPRINT_SET_ALGO 118 +#define TS_F_TS_REQ_SET_MSG_IMPRINT 119 +#define TS_F_TS_REQ_SET_NONCE 120 +#define TS_F_TS_REQ_SET_POLICY_ID 121 +#define TS_F_TS_RESP_CREATE_RESPONSE 122 +#define TS_F_TS_RESP_CREATE_TST_INFO 123 +#define TS_F_TS_RESP_CTX_ADD_FAILURE_INFO 124 +#define TS_F_TS_RESP_CTX_ADD_MD 125 +#define TS_F_TS_RESP_CTX_ADD_POLICY 126 +#define TS_F_TS_RESP_CTX_NEW 127 +#define TS_F_TS_RESP_CTX_SET_ACCURACY 128 +#define TS_F_TS_RESP_CTX_SET_CERTS 129 +#define TS_F_TS_RESP_CTX_SET_DEF_POLICY 130 +#define TS_F_TS_RESP_CTX_SET_SIGNER_CERT 131 +#define TS_F_TS_RESP_CTX_SET_STATUS_INFO 132 +#define TS_F_TS_RESP_GET_POLICY 133 +#define TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION 134 +#define TS_F_TS_RESP_SET_STATUS_INFO 135 +#define TS_F_TS_RESP_SET_TST_INFO 150 +#define TS_F_TS_RESP_SIGN 136 +#define TS_F_TS_RESP_VERIFY_SIGNATURE 106 +#define TS_F_TS_RESP_VERIFY_TOKEN 107 +#define TS_F_TS_TST_INFO_SET_ACCURACY 137 +#define TS_F_TS_TST_INFO_SET_MSG_IMPRINT 138 +#define TS_F_TS_TST_INFO_SET_NONCE 139 +#define TS_F_TS_TST_INFO_SET_POLICY_ID 140 +#define TS_F_TS_TST_INFO_SET_SERIAL 141 +#define TS_F_TS_TST_INFO_SET_TIME 142 +#define TS_F_TS_TST_INFO_SET_TSA 143 +#define TS_F_TS_VERIFY 108 +#define TS_F_TS_VERIFY_CERT 109 +#define TS_F_TS_VERIFY_CTX_NEW 144 + +/* Reason codes. */ +#define TS_R_BAD_PKCS7_TYPE 132 +#define TS_R_BAD_TYPE 133 +#define TS_R_CERTIFICATE_VERIFY_ERROR 100 +#define TS_R_COULD_NOT_SET_ENGINE 127 +#define TS_R_COULD_NOT_SET_TIME 115 +#define TS_R_D2I_TS_RESP_INT_FAILED 128 +#define TS_R_DETACHED_CONTENT 134 +#define TS_R_ESS_ADD_SIGNING_CERT_ERROR 116 +#define TS_R_ESS_SIGNING_CERTIFICATE_ERROR 101 +#define TS_R_INVALID_NULL_POINTER 102 +#define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE 117 +#define TS_R_MESSAGE_IMPRINT_MISMATCH 103 +#define TS_R_NONCE_MISMATCH 104 +#define TS_R_NONCE_NOT_RETURNED 105 +#define TS_R_NO_CONTENT 106 +#define TS_R_NO_TIME_STAMP_TOKEN 107 +#define TS_R_PKCS7_ADD_SIGNATURE_ERROR 118 +#define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR 119 +#define TS_R_PKCS7_TO_TS_TST_INFO_FAILED 129 +#define TS_R_POLICY_MISMATCH 108 +#define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 120 +#define TS_R_RESPONSE_SETUP_ERROR 121 +#define TS_R_SIGNATURE_FAILURE 109 +#define TS_R_THERE_MUST_BE_ONE_SIGNER 110 +#define TS_R_TIME_SYSCALL_ERROR 122 +#define TS_R_TOKEN_NOT_PRESENT 130 +#define TS_R_TOKEN_PRESENT 131 +#define TS_R_TSA_NAME_MISMATCH 111 +#define TS_R_TSA_UNTRUSTED 112 +#define TS_R_TST_INFO_SETUP_ERROR 123 +#define TS_R_TS_DATASIGN 124 +#define TS_R_UNACCEPTABLE_POLICY 125 +#define TS_R_UNSUPPORTED_MD_ALGORITHM 126 +#define TS_R_UNSUPPORTED_VERSION 113 +#define TS_R_WRONG_CONTENT_TYPE 114 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/txt_db.h b/crypto/libressl/include/openssl/txt_db.h new file mode 100644 index 0000000000..38f4590811 --- /dev/null +++ b/crypto/libressl/include/openssl/txt_db.h @@ -0,0 +1,112 @@ +/* $OpenBSD: txt_db.h,v 1.8 2014/06/12 15:49:31 deraadt Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_TXT_DB_H +#define HEADER_TXT_DB_H + +#include + +#ifndef OPENSSL_NO_BIO +#include +#endif +#include +#include + +#define DB_ERROR_OK 0 +#define DB_ERROR_MALLOC 1 +#define DB_ERROR_INDEX_CLASH 2 +#define DB_ERROR_INDEX_OUT_OF_RANGE 3 +#define DB_ERROR_NO_INDEX 4 +#define DB_ERROR_INSERT_INDEX_CLASH 5 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef OPENSSL_STRING *OPENSSL_PSTRING; +DECLARE_SPECIAL_STACK_OF(OPENSSL_PSTRING, OPENSSL_STRING) + +typedef struct txt_db_st { + int num_fields; + STACK_OF(OPENSSL_PSTRING) *data; + LHASH_OF(OPENSSL_STRING) **index; + int (**qual)(OPENSSL_STRING *); + long error; + long arg1; + long arg2; + OPENSSL_STRING *arg_row; +} TXT_DB; + +#ifndef OPENSSL_NO_BIO +TXT_DB *TXT_DB_read(BIO *in, int num); +long TXT_DB_write(BIO *out, TXT_DB *db); +#else +TXT_DB *TXT_DB_read(char *in, int num); +long TXT_DB_write(char *out, TXT_DB *db); +#endif +int TXT_DB_create_index(TXT_DB *db, int field, int (*qual)(OPENSSL_STRING *), + LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp); +void TXT_DB_free(TXT_DB *db); +OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, OPENSSL_STRING *value); +int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *value); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/libressl/include/openssl/ui.h b/crypto/libressl/include/openssl/ui.h new file mode 100644 index 0000000000..e9d7af2a7c --- /dev/null +++ b/crypto/libressl/include/openssl/ui.h @@ -0,0 +1,384 @@ +/* $OpenBSD: ui.h,v 1.8 2014/06/12 15:49:31 deraadt Exp $ */ +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_UI_H +#define HEADER_UI_H + +#include + +#ifndef OPENSSL_NO_DEPRECATED +#include +#endif +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Declared already in ossl_typ.h */ +/* typedef struct ui_st UI; */ +/* typedef struct ui_method_st UI_METHOD; */ + + +/* All the following functions return -1 or NULL on error and in some cases + (UI_process()) -2 if interrupted or in some other way cancelled. + When everything is fine, they return 0, a positive value or a non-NULL + pointer, all depending on their purpose. */ + +/* Creators and destructor. */ +UI *UI_new(void); +UI *UI_new_method(const UI_METHOD *method); +void UI_free(UI *ui); + +/* The following functions are used to add strings to be printed and prompt + strings to prompt for data. The names are UI_{add,dup}__string + and UI_{add,dup}_input_boolean. + + UI_{add,dup}__string have the following meanings: + add add a text or prompt string. The pointers given to these + functions are used verbatim, no copying is done. + dup make a copy of the text or prompt string, then add the copy + to the collection of strings in the user interface. + + The function is a name for the functionality that the given + string shall be used for. It can be one of: + input use the string as data prompt. + verify use the string as verification prompt. This + is used to verify a previous input. + info use the string for informational output. + error use the string for error output. + Honestly, there's currently no difference between info and error for the + moment. + + UI_{add,dup}_input_boolean have the same semantics for "add" and "dup", + and are typically used when one wants to prompt for a yes/no response. + + + All of the functions in this group take a UI and a prompt string. + The string input and verify addition functions also take a flag argument, + a buffer for the result to end up with, a minimum input size and a maximum + input size (the result buffer MUST be large enough to be able to contain + the maximum number of characters). Additionally, the verify addition + functions takes another buffer to compare the result against. + The boolean input functions take an action description string (which should + be safe to ignore if the expected user action is obvious, for example with + a dialog box with an OK button and a Cancel button), a string of acceptable + characters to mean OK and to mean Cancel. The two last strings are checked + to make sure they don't have common characters. Additionally, the same + flag argument as for the string input is taken, as well as a result buffer. + The result buffer is required to be at least one byte long. Depending on + the answer, the first character from the OK or the Cancel character strings + will be stored in the first byte of the result buffer. No NUL will be + added, so the result is *not* a string. + + On success, the all return an index of the added information. That index + is usefull when retrieving results with UI_get0_result(). */ +int UI_add_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize); +int UI_dup_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize); +int UI_add_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, const char *test_buf); +int UI_dup_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, const char *test_buf); +int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf); +int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf); +int UI_add_info_string(UI *ui, const char *text); +int UI_dup_info_string(UI *ui, const char *text); +int UI_add_error_string(UI *ui, const char *text); +int UI_dup_error_string(UI *ui, const char *text); + +/* These are the possible flags. They can be or'ed together. */ +/* Use to have echoing of input */ +#define UI_INPUT_FLAG_ECHO 0x01 +/* Use a default password. Where that password is found is completely + up to the application, it might for example be in the user data set + with UI_add_user_data(). It is not recommended to have more than + one input in each UI being marked with this flag, or the application + might get confused. */ +#define UI_INPUT_FLAG_DEFAULT_PWD 0x02 + +/* The user of these routines may want to define flags of their own. The core + UI won't look at those, but will pass them on to the method routines. They + must use higher bits so they don't get confused with the UI bits above. + UI_INPUT_FLAG_USER_BASE tells which is the lowest bit to use. A good + example of use is this: + + #define MY_UI_FLAG1 (0x01 << UI_INPUT_FLAG_USER_BASE) + +*/ +#define UI_INPUT_FLAG_USER_BASE 16 + + +/* The following function helps construct a prompt. object_desc is a + textual short description of the object, for example "pass phrase", + and object_name is the name of the object (might be a card name or + a file name. + The returned string shall always be allocated on the heap with + malloc(), and need to be free'd with free(). + + If the ui_method doesn't contain a pointer to a user-defined prompt + constructor, a default string is built, looking like this: + + "Enter {object_desc} for {object_name}:" + + So, if object_desc has the value "pass phrase" and object_name has + the value "foo.key", the resulting string is: + + "Enter pass phrase for foo.key:" +*/ +char *UI_construct_prompt(UI *ui_method, const char *object_desc, + const char *object_name); + + +/* The following function is used to store a pointer to user-specific data. + Any previous such pointer will be returned and replaced. + + For callback purposes, this function makes a lot more sense than using + ex_data, since the latter requires that different parts of OpenSSL or + applications share the same ex_data index. + + Note that the UI_OpenSSL() method completely ignores the user data. + Other methods may not, however. */ +void *UI_add_user_data(UI *ui, void *user_data); +/* We need a user data retrieving function as well. */ +void *UI_get0_user_data(UI *ui); + +/* Return the result associated with a prompt given with the index i. */ +const char *UI_get0_result(UI *ui, int i); + +/* When all strings have been added, process the whole thing. */ +int UI_process(UI *ui); + +/* Give a user interface parametrised control commands. This can be used to + send down an integer, a data pointer or a function pointer, as well as + be used to get information from a UI. */ +int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f)(void)); + +/* The commands */ +/* Use UI_CONTROL_PRINT_ERRORS with the value 1 to have UI_process print the + OpenSSL error stack before printing any info or added error messages and + before any prompting. */ +#define UI_CTRL_PRINT_ERRORS 1 +/* Check if a UI_process() is possible to do again with the same instance of + a user interface. This makes UI_ctrl() return 1 if it is redoable, and 0 + if not. */ +#define UI_CTRL_IS_REDOABLE 2 + + +/* Some methods may use extra data */ +#define UI_set_app_data(s,arg) UI_set_ex_data(s,0,arg) +#define UI_get_app_data(s) UI_get_ex_data(s,0) +int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int UI_set_ex_data(UI *r, int idx, void *arg); +void *UI_get_ex_data(UI *r, int idx); + +/* Use specific methods instead of the built-in one */ +void UI_set_default_method(const UI_METHOD *meth); +const UI_METHOD *UI_get_default_method(void); +const UI_METHOD *UI_get_method(UI *ui); +const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth); + +/* The method with all the built-in thingies */ +UI_METHOD *UI_OpenSSL(void); + + +/* ---------- For method writers ---------- */ +/* A method contains a number of functions that implement the low level + of the User Interface. The functions are: + + an opener This function starts a session, maybe by opening + a channel to a tty, or by opening a window. + a writer This function is called to write a given string, + maybe to the tty, maybe as a field label in a + window. + a flusher This function is called to flush everything that + has been output so far. It can be used to actually + display a dialog box after it has been built. + a reader This function is called to read a given prompt, + maybe from the tty, maybe from a field in a + window. Note that it's called wth all string + structures, not only the prompt ones, so it must + check such things itself. + a closer This function closes the session, maybe by closing + the channel to the tty, or closing the window. + + All these functions are expected to return: + + 0 on error. + 1 on success. + -1 on out-of-band events, for example if some prompting has + been canceled (by pressing Ctrl-C, for example). This is + only checked when returned by the flusher or the reader. + + The way this is used, the opener is first called, then the writer for all + strings, then the flusher, then the reader for all strings and finally the + closer. Note that if you want to prompt from a terminal or other command + line interface, the best is to have the reader also write the prompts + instead of having the writer do it. If you want to prompt from a dialog + box, the writer can be used to build up the contents of the box, and the + flusher to actually display the box and run the event loop until all data + has been given, after which the reader only grabs the given data and puts + them back into the UI strings. + + All method functions take a UI as argument. Additionally, the writer and + the reader take a UI_STRING. +*/ + +/* The UI_STRING type is the data structure that contains all the needed info + about a string or a prompt, including test data for a verification prompt. +*/ +typedef struct ui_string_st UI_STRING; +DECLARE_STACK_OF(UI_STRING) + +/* The different types of strings that are currently supported. + This is only needed by method authors. */ +enum UI_string_types { + UIT_NONE = 0, + UIT_PROMPT, /* Prompt for a string */ + UIT_VERIFY, /* Prompt for a string and verify */ + UIT_BOOLEAN, /* Prompt for a yes/no response */ + UIT_INFO, /* Send info to the user */ + UIT_ERROR /* Send an error message to the user */ +}; + +/* Create and manipulate methods */ +UI_METHOD *UI_create_method(char *name); +void UI_destroy_method(UI_METHOD *ui_method); +int UI_method_set_opener(UI_METHOD *method, int (*opener)(UI *ui)); +int UI_method_set_writer(UI_METHOD *method, int (*writer)(UI *ui, UI_STRING *uis)); +int UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui)); +int UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis)); +int UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui)); +int UI_method_set_prompt_constructor(UI_METHOD *method, char *(*prompt_constructor)(UI* ui, const char* object_desc, const char* object_name)); +int (*UI_method_get_opener(UI_METHOD *method))(UI*); +int (*UI_method_get_writer(UI_METHOD *method))(UI*, UI_STRING*); +int (*UI_method_get_flusher(UI_METHOD *method))(UI*); +int (*UI_method_get_reader(UI_METHOD *method))(UI*, UI_STRING*); +int (*UI_method_get_closer(UI_METHOD *method))(UI*); +char * (*UI_method_get_prompt_constructor(UI_METHOD *method))(UI*, const char*, const char*); + +/* The following functions are helpers for method writers to access relevant + data from a UI_STRING. */ + +/* Return type of the UI_STRING */ +enum UI_string_types UI_get_string_type(UI_STRING *uis); +/* Return input flags of the UI_STRING */ +int UI_get_input_flags(UI_STRING *uis); +/* Return the actual string to output (the prompt, info or error) */ +const char *UI_get0_output_string(UI_STRING *uis); +/* Return the optional action string to output (the boolean promtp instruction) */ +const char *UI_get0_action_string(UI_STRING *uis); +/* Return the result of a prompt */ +const char *UI_get0_result_string(UI_STRING *uis); +/* Return the string to test the result against. Only useful with verifies. */ +const char *UI_get0_test_string(UI_STRING *uis); +/* Return the required minimum size of the result */ +int UI_get_result_minsize(UI_STRING *uis); +/* Return the required maximum size of the result */ +int UI_get_result_maxsize(UI_STRING *uis); +/* Set the result of a UI_STRING. */ +int UI_set_result(UI *ui, UI_STRING *uis, const char *result); + + +/* A couple of popular utility functions */ +int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt, int verify); +int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt, int verify); + + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_UI_strings(void); + +/* Error codes for the UI functions. */ + +/* Function codes. */ +#define UI_F_GENERAL_ALLOCATE_BOOLEAN 108 +#define UI_F_GENERAL_ALLOCATE_PROMPT 109 +#define UI_F_GENERAL_ALLOCATE_STRING 100 +#define UI_F_UI_CTRL 111 +#define UI_F_UI_DUP_ERROR_STRING 101 +#define UI_F_UI_DUP_INFO_STRING 102 +#define UI_F_UI_DUP_INPUT_BOOLEAN 110 +#define UI_F_UI_DUP_INPUT_STRING 103 +#define UI_F_UI_DUP_VERIFY_STRING 106 +#define UI_F_UI_GET0_RESULT 107 +#define UI_F_UI_NEW_METHOD 104 +#define UI_F_UI_SET_RESULT 105 + +/* Reason codes. */ +#define UI_R_COMMON_OK_AND_CANCEL_CHARACTERS 104 +#define UI_R_INDEX_TOO_LARGE 102 +#define UI_R_INDEX_TOO_SMALL 103 +#define UI_R_NO_RESULT_BUFFER 105 +#define UI_R_RESULT_TOO_LARGE 100 +#define UI_R_RESULT_TOO_SMALL 101 +#define UI_R_UNKNOWN_CONTROL_COMMAND 106 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/ui_compat.h b/crypto/libressl/include/openssl/ui_compat.h new file mode 100644 index 0000000000..0c016a76dd --- /dev/null +++ b/crypto/libressl/include/openssl/ui_compat.h @@ -0,0 +1,83 @@ +/* $OpenBSD$ */ +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_UI_COMPAT_H +#define HEADER_UI_COMPAT_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* The following functions were previously part of the DES section, + and are provided here for backward compatibility reasons. */ + +#define des_read_pw_string(b,l,p,v) \ + _ossl_old_des_read_pw_string((b),(l),(p),(v)) +#define des_read_pw(b,bf,s,p,v) \ + _ossl_old_des_read_pw((b),(bf),(s),(p),(v)) + +int _ossl_old_des_read_pw_string(char *buf, int length, const char *prompt, int verify); +int _ossl_old_des_read_pw(char *buf, char *buff, int size, const char *prompt, int verify); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/whrlpool.h b/crypto/libressl/include/openssl/whrlpool.h new file mode 100644 index 0000000000..33ab97f5b0 --- /dev/null +++ b/crypto/libressl/include/openssl/whrlpool.h @@ -0,0 +1,41 @@ +/* $OpenBSD: whrlpool.h,v 1.4 2014/06/12 15:49:31 deraadt Exp $ */ + +#include + +#ifndef HEADER_WHRLPOOL_H +#define HEADER_WHRLPOOL_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define WHIRLPOOL_DIGEST_LENGTH (512/8) +#define WHIRLPOOL_BBLOCK 512 +#define WHIRLPOOL_COUNTER (256/8) + +typedef struct { + union { + unsigned char c[WHIRLPOOL_DIGEST_LENGTH]; + /* double q is here to ensure 64-bit alignment */ + double q[WHIRLPOOL_DIGEST_LENGTH/sizeof(double)]; + } H; + unsigned char data[WHIRLPOOL_BBLOCK/8]; + unsigned int bitoff; + size_t bitlen[WHIRLPOOL_COUNTER/sizeof(size_t)]; + } WHIRLPOOL_CTX; + +#ifndef OPENSSL_NO_WHIRLPOOL +int WHIRLPOOL_Init (WHIRLPOOL_CTX *c); +int WHIRLPOOL_Update (WHIRLPOOL_CTX *c,const void *inp,size_t bytes); +void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c,const void *inp,size_t bits); +int WHIRLPOOL_Final (unsigned char *md,WHIRLPOOL_CTX *c); +unsigned char *WHIRLPOOL(const void *inp,size_t bytes,unsigned char *md); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/libressl/include/openssl/x509.h b/crypto/libressl/include/openssl/x509.h new file mode 100644 index 0000000000..b4477665b8 --- /dev/null +++ b/crypto/libressl/include/openssl/x509.h @@ -0,0 +1,1283 @@ +/* $OpenBSD: x509.h,v 1.22 2015/02/11 02:17:59 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_X509_H +#define HEADER_X509_H + +#include + +#ifndef OPENSSL_NO_BUFFER +#include +#endif +#ifndef OPENSSL_NO_EVP +#include +#endif +#ifndef OPENSSL_NO_BIO +#include +#endif +#include +#include +#include + +#ifndef OPENSSL_NO_EC +#include +#endif + +#ifndef OPENSSL_NO_ECDSA +#include +#endif + +#ifndef OPENSSL_NO_ECDH +#include +#endif + +#ifndef OPENSSL_NO_DEPRECATED +#ifndef OPENSSL_NO_RSA +#include +#endif +#ifndef OPENSSL_NO_DSA +#include +#endif +#ifndef OPENSSL_NO_DH +#include +#endif +#endif + +#ifndef OPENSSL_NO_SHA +#include +#endif +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WIN32) +#ifndef LIBRESSL_INTERNAL +#ifdef _MSC_VER +#pragma message("Warning, overriding WinCrypt defines") +#else +#warning overriding WinCrypt defines +#endif +#endif +#undef X509_NAME +#undef X509_CERT_PAIR +#undef X509_EXTENSIONS +#endif + +#define X509_FILETYPE_PEM 1 +#define X509_FILETYPE_ASN1 2 +#define X509_FILETYPE_DEFAULT 3 + +#define X509v3_KU_DIGITAL_SIGNATURE 0x0080 +#define X509v3_KU_NON_REPUDIATION 0x0040 +#define X509v3_KU_KEY_ENCIPHERMENT 0x0020 +#define X509v3_KU_DATA_ENCIPHERMENT 0x0010 +#define X509v3_KU_KEY_AGREEMENT 0x0008 +#define X509v3_KU_KEY_CERT_SIGN 0x0004 +#define X509v3_KU_CRL_SIGN 0x0002 +#define X509v3_KU_ENCIPHER_ONLY 0x0001 +#define X509v3_KU_DECIPHER_ONLY 0x8000 +#define X509v3_KU_UNDEF 0xffff + +typedef struct X509_objects_st + { + int nid; + int (*a2i)(void); + int (*i2a)(void); + } X509_OBJECTS; + +struct X509_algor_st + { + ASN1_OBJECT *algorithm; + ASN1_TYPE *parameter; + } /* X509_ALGOR */; + +DECLARE_ASN1_SET_OF(X509_ALGOR) + +typedef STACK_OF(X509_ALGOR) X509_ALGORS; + +typedef struct X509_val_st + { + ASN1_TIME *notBefore; + ASN1_TIME *notAfter; + } X509_VAL; + +struct X509_pubkey_st + { + X509_ALGOR *algor; + ASN1_BIT_STRING *public_key; + EVP_PKEY *pkey; + }; + +typedef struct X509_sig_st + { + X509_ALGOR *algor; + ASN1_OCTET_STRING *digest; + } X509_SIG; + +typedef struct X509_name_entry_st + { + ASN1_OBJECT *object; + ASN1_STRING *value; + int set; + int size; /* temp variable */ + } X509_NAME_ENTRY; + +DECLARE_STACK_OF(X509_NAME_ENTRY) +DECLARE_ASN1_SET_OF(X509_NAME_ENTRY) + +/* we always keep X509_NAMEs in 2 forms. */ +struct X509_name_st + { + STACK_OF(X509_NAME_ENTRY) *entries; + int modified; /* true if 'bytes' needs to be built */ +#ifndef OPENSSL_NO_BUFFER + BUF_MEM *bytes; +#else + char *bytes; +#endif +/* unsigned long hash; Keep the hash around for lookups */ + unsigned char *canon_enc; + int canon_enclen; + } /* X509_NAME */; + +DECLARE_STACK_OF(X509_NAME) + +#define X509_EX_V_NETSCAPE_HACK 0x8000 +#define X509_EX_V_INIT 0x0001 +typedef struct X509_extension_st + { + ASN1_OBJECT *object; + ASN1_BOOLEAN critical; + ASN1_OCTET_STRING *value; + } X509_EXTENSION; + +typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS; + +DECLARE_STACK_OF(X509_EXTENSION) +DECLARE_ASN1_SET_OF(X509_EXTENSION) + +/* a sequence of these are used */ +typedef struct x509_attributes_st + { + ASN1_OBJECT *object; + int single; /* 0 for a set, 1 for a single item (which is wrong) */ + union { + char *ptr; +/* 0 */ STACK_OF(ASN1_TYPE) *set; +/* 1 */ ASN1_TYPE *single; + } value; + } X509_ATTRIBUTE; + +DECLARE_STACK_OF(X509_ATTRIBUTE) +DECLARE_ASN1_SET_OF(X509_ATTRIBUTE) + + +typedef struct X509_req_info_st + { + ASN1_ENCODING enc; + ASN1_INTEGER *version; + X509_NAME *subject; + X509_PUBKEY *pubkey; + /* d=2 hl=2 l= 0 cons: cont: 00 */ + STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ + } X509_REQ_INFO; + +typedef struct X509_req_st + { + X509_REQ_INFO *req_info; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int references; + } X509_REQ; + +typedef struct x509_cinf_st + { + ASN1_INTEGER *version; /* [ 0 ] default of v1 */ + ASN1_INTEGER *serialNumber; + X509_ALGOR *signature; + X509_NAME *issuer; + X509_VAL *validity; + X509_NAME *subject; + X509_PUBKEY *key; + ASN1_BIT_STRING *issuerUID; /* [ 1 ] optional in v2 */ + ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */ + STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */ + ASN1_ENCODING enc; + } X509_CINF; + +/* This stuff is certificate "auxiliary info" + * it contains details which are useful in certificate + * stores and databases. When used this is tagged onto + * the end of the certificate itself + */ + +typedef struct x509_cert_aux_st + { + STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */ + STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */ + ASN1_UTF8STRING *alias; /* "friendly name" */ + ASN1_OCTET_STRING *keyid; /* key id of private key */ + STACK_OF(X509_ALGOR) *other; /* other unspecified info */ + } X509_CERT_AUX; + +struct x509_st + { + X509_CINF *cert_info; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int valid; + int references; + char *name; + CRYPTO_EX_DATA ex_data; + /* These contain copies of various extension values */ + long ex_pathlen; + long ex_pcpathlen; + unsigned long ex_flags; + unsigned long ex_kusage; + unsigned long ex_xkusage; + unsigned long ex_nscert; + ASN1_OCTET_STRING *skid; + AUTHORITY_KEYID *akid; + X509_POLICY_CACHE *policy_cache; + STACK_OF(DIST_POINT) *crldp; + STACK_OF(GENERAL_NAME) *altname; + NAME_CONSTRAINTS *nc; +#ifndef OPENSSL_NO_SHA + unsigned char sha1_hash[SHA_DIGEST_LENGTH]; +#endif + X509_CERT_AUX *aux; + } /* X509 */; + +DECLARE_STACK_OF(X509) +DECLARE_ASN1_SET_OF(X509) + +/* This is used for a table of trust checking functions */ + +typedef struct x509_trust_st { + int trust; + int flags; + int (*check_trust)(struct x509_trust_st *, X509 *, int); + char *name; + int arg1; + void *arg2; +} X509_TRUST; + +DECLARE_STACK_OF(X509_TRUST) + +typedef struct x509_cert_pair_st { + X509 *forward; + X509 *reverse; +} X509_CERT_PAIR; + +/* standard trust ids */ + +#define X509_TRUST_DEFAULT -1 /* Only valid in purpose settings */ + +#define X509_TRUST_COMPAT 1 +#define X509_TRUST_SSL_CLIENT 2 +#define X509_TRUST_SSL_SERVER 3 +#define X509_TRUST_EMAIL 4 +#define X509_TRUST_OBJECT_SIGN 5 +#define X509_TRUST_OCSP_SIGN 6 +#define X509_TRUST_OCSP_REQUEST 7 +#define X509_TRUST_TSA 8 + +/* Keep these up to date! */ +#define X509_TRUST_MIN 1 +#define X509_TRUST_MAX 8 + + +/* trust_flags values */ +#define X509_TRUST_DYNAMIC 1 +#define X509_TRUST_DYNAMIC_NAME 2 + +/* check_trust return codes */ + +#define X509_TRUST_TRUSTED 1 +#define X509_TRUST_REJECTED 2 +#define X509_TRUST_UNTRUSTED 3 + +/* Flags for X509_print_ex() */ + +#define X509_FLAG_COMPAT 0 +#define X509_FLAG_NO_HEADER 1L +#define X509_FLAG_NO_VERSION (1L << 1) +#define X509_FLAG_NO_SERIAL (1L << 2) +#define X509_FLAG_NO_SIGNAME (1L << 3) +#define X509_FLAG_NO_ISSUER (1L << 4) +#define X509_FLAG_NO_VALIDITY (1L << 5) +#define X509_FLAG_NO_SUBJECT (1L << 6) +#define X509_FLAG_NO_PUBKEY (1L << 7) +#define X509_FLAG_NO_EXTENSIONS (1L << 8) +#define X509_FLAG_NO_SIGDUMP (1L << 9) +#define X509_FLAG_NO_AUX (1L << 10) +#define X509_FLAG_NO_ATTRIBUTES (1L << 11) + +/* Flags specific to X509_NAME_print_ex() */ + +/* The field separator information */ + +#define XN_FLAG_SEP_MASK (0xf << 16) + +#define XN_FLAG_COMPAT 0 /* Traditional SSLeay: use old X509_NAME_print */ +#define XN_FLAG_SEP_COMMA_PLUS (1 << 16) /* RFC2253 ,+ */ +#define XN_FLAG_SEP_CPLUS_SPC (2 << 16) /* ,+ spaced: more readable */ +#define XN_FLAG_SEP_SPLUS_SPC (3 << 16) /* ;+ spaced */ +#define XN_FLAG_SEP_MULTILINE (4 << 16) /* One line per field */ + +#define XN_FLAG_DN_REV (1 << 20) /* Reverse DN order */ + +/* How the field name is shown */ + +#define XN_FLAG_FN_MASK (0x3 << 21) + +#define XN_FLAG_FN_SN 0 /* Object short name */ +#define XN_FLAG_FN_LN (1 << 21) /* Object long name */ +#define XN_FLAG_FN_OID (2 << 21) /* Always use OIDs */ +#define XN_FLAG_FN_NONE (3 << 21) /* No field names */ + +#define XN_FLAG_SPC_EQ (1 << 23) /* Put spaces round '=' */ + +/* This determines if we dump fields we don't recognise: + * RFC2253 requires this. + */ + +#define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24) + +#define XN_FLAG_FN_ALIGN (1 << 25) /* Align field names to 20 characters */ + +/* Complete set of RFC2253 flags */ + +#define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \ + XN_FLAG_SEP_COMMA_PLUS | \ + XN_FLAG_DN_REV | \ + XN_FLAG_FN_SN | \ + XN_FLAG_DUMP_UNKNOWN_FIELDS) + +/* readable oneline form */ + +#define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \ + ASN1_STRFLGS_ESC_QUOTE | \ + XN_FLAG_SEP_CPLUS_SPC | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_SN) + +/* readable multiline form */ + +#define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + XN_FLAG_SEP_MULTILINE | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_LN | \ + XN_FLAG_FN_ALIGN) + +struct x509_revoked_st + { + ASN1_INTEGER *serialNumber; + ASN1_TIME *revocationDate; + STACK_OF(X509_EXTENSION) /* optional */ *extensions; + /* Set up if indirect CRL */ + STACK_OF(GENERAL_NAME) *issuer; + /* Revocation reason */ + int reason; + int sequence; /* load sequence */ + }; + +DECLARE_STACK_OF(X509_REVOKED) +DECLARE_ASN1_SET_OF(X509_REVOKED) + +typedef struct X509_crl_info_st + { + ASN1_INTEGER *version; + X509_ALGOR *sig_alg; + X509_NAME *issuer; + ASN1_TIME *lastUpdate; + ASN1_TIME *nextUpdate; + STACK_OF(X509_REVOKED) *revoked; + STACK_OF(X509_EXTENSION) /* [0] */ *extensions; + ASN1_ENCODING enc; + } X509_CRL_INFO; + +struct X509_crl_st + { + /* actual signature */ + X509_CRL_INFO *crl; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int references; + int flags; + /* Copies of various extensions */ + AUTHORITY_KEYID *akid; + ISSUING_DIST_POINT *idp; + /* Convenient breakdown of IDP */ + int idp_flags; + int idp_reasons; + /* CRL and base CRL numbers for delta processing */ + ASN1_INTEGER *crl_number; + ASN1_INTEGER *base_crl_number; +#ifndef OPENSSL_NO_SHA + unsigned char sha1_hash[SHA_DIGEST_LENGTH]; +#endif + STACK_OF(GENERAL_NAMES) *issuers; + const X509_CRL_METHOD *meth; + void *meth_data; + } /* X509_CRL */; + +DECLARE_STACK_OF(X509_CRL) +DECLARE_ASN1_SET_OF(X509_CRL) + +typedef struct private_key_st + { + int version; + /* The PKCS#8 data types */ + X509_ALGOR *enc_algor; + ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */ + + /* When decrypted, the following will not be NULL */ + EVP_PKEY *dec_pkey; + + /* used to encrypt and decrypt */ + int key_length; + char *key_data; + int key_free; /* true if we should auto free key_data */ + + /* expanded version of 'enc_algor' */ + EVP_CIPHER_INFO cipher; + + int references; + } X509_PKEY; + +#ifndef OPENSSL_NO_EVP +typedef struct X509_info_st + { + X509 *x509; + X509_CRL *crl; + X509_PKEY *x_pkey; + + EVP_CIPHER_INFO enc_cipher; + int enc_len; + char *enc_data; + + int references; + } X509_INFO; + +DECLARE_STACK_OF(X509_INFO) +#endif + +/* The next 2 structures and their 8 routines were sent to me by + * Pat Richard and are used to manipulate + * Netscapes spki structures - useful if you are writing a CA web page + */ +typedef struct Netscape_spkac_st + { + X509_PUBKEY *pubkey; + ASN1_IA5STRING *challenge; /* challenge sent in atlas >= PR2 */ + } NETSCAPE_SPKAC; + +typedef struct Netscape_spki_st + { + NETSCAPE_SPKAC *spkac; /* signed public key and challenge */ + X509_ALGOR *sig_algor; + ASN1_BIT_STRING *signature; + } NETSCAPE_SPKI; + +/* Netscape certificate sequence structure */ +typedef struct Netscape_certificate_sequence + { + ASN1_OBJECT *type; + STACK_OF(X509) *certs; + } NETSCAPE_CERT_SEQUENCE; + +/* Unused (and iv length is wrong) +typedef struct CBCParameter_st + { + unsigned char iv[8]; + } CBC_PARAM; +*/ + +/* Password based encryption structure */ + +typedef struct PBEPARAM_st { +ASN1_OCTET_STRING *salt; +ASN1_INTEGER *iter; +} PBEPARAM; + +/* Password based encryption V2 structures */ + +typedef struct PBE2PARAM_st { +X509_ALGOR *keyfunc; +X509_ALGOR *encryption; +} PBE2PARAM; + +typedef struct PBKDF2PARAM_st { +ASN1_TYPE *salt; /* Usually OCTET STRING but could be anything */ +ASN1_INTEGER *iter; +ASN1_INTEGER *keylength; +X509_ALGOR *prf; +} PBKDF2PARAM; + + +/* PKCS#8 private key info structure */ + +struct pkcs8_priv_key_info_st + { + int broken; /* Flag for various broken formats */ +#define PKCS8_OK 0 +#define PKCS8_NO_OCTET 1 +#define PKCS8_EMBEDDED_PARAM 2 +#define PKCS8_NS_DB 3 +#define PKCS8_NEG_PRIVKEY 4 + ASN1_INTEGER *version; + X509_ALGOR *pkeyalg; + ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */ + STACK_OF(X509_ATTRIBUTE) *attributes; + }; + +#ifdef __cplusplus +} +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define X509_EXT_PACK_UNKNOWN 1 +#define X509_EXT_PACK_STRING 2 + +#define X509_get_version(x) ASN1_INTEGER_get((x)->cert_info->version) +/* #define X509_get_serialNumber(x) ((x)->cert_info->serialNumber) */ +#define X509_get_notBefore(x) ((x)->cert_info->validity->notBefore) +#define X509_get_notAfter(x) ((x)->cert_info->validity->notAfter) +#define X509_extract_key(x) X509_get_pubkey(x) /*****/ +#define X509_REQ_get_version(x) ASN1_INTEGER_get((x)->req_info->version) +#define X509_REQ_get_subject_name(x) ((x)->req_info->subject) +#define X509_REQ_extract_key(a) X509_REQ_get_pubkey(a) +#define X509_name_cmp(a,b) X509_NAME_cmp((a),(b)) +#define X509_get_signature_type(x) EVP_PKEY_type(OBJ_obj2nid((x)->sig_alg->algorithm)) + +#define X509_CRL_get_version(x) ASN1_INTEGER_get((x)->crl->version) +#define X509_CRL_get_lastUpdate(x) ((x)->crl->lastUpdate) +#define X509_CRL_get_nextUpdate(x) ((x)->crl->nextUpdate) +#define X509_CRL_get_issuer(x) ((x)->crl->issuer) +#define X509_CRL_get_REVOKED(x) ((x)->crl->revoked) + +void X509_CRL_set_default_method(const X509_CRL_METHOD *meth); +X509_CRL_METHOD *X509_CRL_METHOD_new( + int (*crl_init)(X509_CRL *crl), + int (*crl_free)(X509_CRL *crl), + int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret, + ASN1_INTEGER *ser, X509_NAME *issuer), + int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk)); +void X509_CRL_METHOD_free(X509_CRL_METHOD *m); + +void X509_CRL_set_meth_data(X509_CRL *crl, void *dat); +void *X509_CRL_get_meth_data(X509_CRL *crl); + +/* This one is only used so that a binary form can output, as in + * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf) */ +#define X509_get_X509_PUBKEY(x) ((x)->cert_info->key) + + +const char *X509_verify_cert_error_string(long n); + +#ifndef OPENSSL_NO_EVP +int X509_verify(X509 *a, EVP_PKEY *r); + +int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r); +int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r); +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r); + +NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len); +char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x); +EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x); +int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey); + +int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki); + +int X509_signature_dump(BIO *bp,const ASN1_STRING *sig, int indent); +int X509_signature_print(BIO *bp,X509_ALGOR *alg, ASN1_STRING *sig); + +int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx); +int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx); +int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx); +int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md); + +int X509_pubkey_digest(const X509 *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_digest(const X509 *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_CRL_digest(const X509_CRL *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_REQ_digest(const X509_REQ *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_NAME_digest(const X509_NAME *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +#endif + +X509 *d2i_X509_fp(FILE *fp, X509 **x509); +int i2d_X509_fp(FILE *fp,X509 *x509); +X509_CRL *d2i_X509_CRL_fp(FILE *fp,X509_CRL **crl); +int i2d_X509_CRL_fp(FILE *fp,X509_CRL *crl); +X509_REQ *d2i_X509_REQ_fp(FILE *fp,X509_REQ **req); +int i2d_X509_REQ_fp(FILE *fp,X509_REQ *req); +#ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_fp(FILE *fp,RSA **rsa); +int i2d_RSAPrivateKey_fp(FILE *fp,RSA *rsa); +RSA *d2i_RSAPublicKey_fp(FILE *fp,RSA **rsa); +int i2d_RSAPublicKey_fp(FILE *fp,RSA *rsa); +RSA *d2i_RSA_PUBKEY_fp(FILE *fp,RSA **rsa); +int i2d_RSA_PUBKEY_fp(FILE *fp,RSA *rsa); +#endif +#ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa); +int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa); +int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa); +#endif +#ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey); +int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey); +int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey); +#endif +X509_SIG *d2i_PKCS8_fp(FILE *fp,X509_SIG **p8); +int i2d_PKCS8_fp(FILE *fp,X509_SIG *p8); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key); +int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); +int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a); + +#ifndef OPENSSL_NO_BIO +X509 *d2i_X509_bio(BIO *bp,X509 **x509); +int i2d_X509_bio(BIO *bp,X509 *x509); +X509_CRL *d2i_X509_CRL_bio(BIO *bp,X509_CRL **crl); +int i2d_X509_CRL_bio(BIO *bp,X509_CRL *crl); +X509_REQ *d2i_X509_REQ_bio(BIO *bp,X509_REQ **req); +int i2d_X509_REQ_bio(BIO *bp,X509_REQ *req); +#ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_bio(BIO *bp,RSA **rsa); +int i2d_RSAPrivateKey_bio(BIO *bp,RSA *rsa); +RSA *d2i_RSAPublicKey_bio(BIO *bp,RSA **rsa); +int i2d_RSAPublicKey_bio(BIO *bp,RSA *rsa); +RSA *d2i_RSA_PUBKEY_bio(BIO *bp,RSA **rsa); +int i2d_RSA_PUBKEY_bio(BIO *bp,RSA *rsa); +#endif +#ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa); +int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa); +DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa); +int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa); +#endif +#ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey); +int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey); +int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey); +#endif +X509_SIG *d2i_PKCS8_bio(BIO *bp,X509_SIG **p8); +int i2d_PKCS8_bio(BIO *bp,X509_SIG *p8); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key); +int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); +int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); +#endif + +X509 *X509_dup(X509 *x509); +X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa); +X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex); +X509_CRL *X509_CRL_dup(X509_CRL *crl); +X509_REQ *X509_REQ_dup(X509_REQ *req); +X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn); +int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval); +void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval, + X509_ALGOR *algor); +void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md); +int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b); + +X509_NAME *X509_NAME_dup(X509_NAME *xn); +X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne); + +int X509_cmp_time(const ASN1_TIME *s, time_t *t); +int X509_cmp_current_time(const ASN1_TIME *s); +ASN1_TIME * X509_time_adj(ASN1_TIME *s, long adj, time_t *t); +ASN1_TIME * X509_time_adj_ex(ASN1_TIME *s, + int offset_day, long offset_sec, time_t *t); +ASN1_TIME * X509_gmtime_adj(ASN1_TIME *s, long adj); + +const char * X509_get_default_cert_area(void ); +const char * X509_get_default_cert_dir(void ); +const char * X509_get_default_cert_file(void ); +const char * X509_get_default_cert_dir_env(void ); +const char * X509_get_default_cert_file_env(void ); +const char * X509_get_default_private_dir(void ); + +X509_REQ * X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +X509 * X509_REQ_to_X509(X509_REQ *r, int days,EVP_PKEY *pkey); + +DECLARE_ASN1_FUNCTIONS(X509_ALGOR) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS) +DECLARE_ASN1_FUNCTIONS(X509_VAL) + +DECLARE_ASN1_FUNCTIONS(X509_PUBKEY) + +int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); +EVP_PKEY * X509_PUBKEY_get(X509_PUBKEY *key); +int X509_get_pubkey_parameters(EVP_PKEY *pkey, + STACK_OF(X509) *chain); +int i2d_PUBKEY(EVP_PKEY *a,unsigned char **pp); +EVP_PKEY * d2i_PUBKEY(EVP_PKEY **a,const unsigned char **pp, + long length); +#ifndef OPENSSL_NO_RSA +int i2d_RSA_PUBKEY(RSA *a,unsigned char **pp); +RSA * d2i_RSA_PUBKEY(RSA **a,const unsigned char **pp, + long length); +#endif +#ifndef OPENSSL_NO_DSA +int i2d_DSA_PUBKEY(DSA *a,unsigned char **pp); +DSA * d2i_DSA_PUBKEY(DSA **a,const unsigned char **pp, + long length); +#endif +#ifndef OPENSSL_NO_EC +int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp); +EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, + long length); +#endif + +DECLARE_ASN1_FUNCTIONS(X509_SIG) +DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO) +DECLARE_ASN1_FUNCTIONS(X509_REQ) + +DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE) +X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value); + +DECLARE_ASN1_FUNCTIONS(X509_EXTENSION) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS) + +DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY) + +DECLARE_ASN1_FUNCTIONS(X509_NAME) + +int X509_NAME_set(X509_NAME **xn, X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(X509_CINF) + +DECLARE_ASN1_FUNCTIONS(X509) +DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX) + +DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR) + +int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int X509_set_ex_data(X509 *r, int idx, void *arg); +void *X509_get_ex_data(X509 *r, int idx); +int i2d_X509_AUX(X509 *a,unsigned char **pp); +X509 * d2i_X509_AUX(X509 **a,const unsigned char **pp,long length); + +int X509_alias_set1(X509 *x, unsigned char *name, int len); +int X509_keyid_set1(X509 *x, unsigned char *id, int len); +unsigned char * X509_alias_get0(X509 *x, int *len); +unsigned char * X509_keyid_get0(X509 *x, int *len); +int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int); +int X509_TRUST_set(int *t, int trust); +int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj); +int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj); +void X509_trust_clear(X509 *x); +void X509_reject_clear(X509 *x); + +DECLARE_ASN1_FUNCTIONS(X509_REVOKED) +DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO) +DECLARE_ASN1_FUNCTIONS(X509_CRL) + +int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); +int X509_CRL_get0_by_serial(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial); +int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x); + +X509_PKEY * X509_PKEY_new(void ); +void X509_PKEY_free(X509_PKEY *a); + +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE) + +#ifndef OPENSSL_NO_EVP +X509_INFO * X509_INFO_new(void); +void X509_INFO_free(X509_INFO *a); +char * X509_NAME_oneline(X509_NAME *a,char *buf,int size); + +int ASN1_item_digest(const ASN1_ITEM *it,const EVP_MD *type,void *data, + unsigned char *md,unsigned int *len); + +int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature,void *data,EVP_PKEY *pkey); + +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, + void *data, EVP_PKEY *pkey, const EVP_MD *type); +int ASN1_item_sign_ctx(const ASN1_ITEM *it, + X509_ALGOR *algor1, X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx); +#endif + +int X509_set_version(X509 *x,long version); +int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial); +ASN1_INTEGER * X509_get_serialNumber(X509 *x); +int X509_set_issuer_name(X509 *x, X509_NAME *name); +X509_NAME * X509_get_issuer_name(X509 *a); +int X509_set_subject_name(X509 *x, X509_NAME *name); +X509_NAME * X509_get_subject_name(X509 *a); +int X509_set_notBefore(X509 *x, const ASN1_TIME *tm); +int X509_set_notAfter(X509 *x, const ASN1_TIME *tm); +int X509_set_pubkey(X509 *x, EVP_PKEY *pkey); +EVP_PKEY * X509_get_pubkey(X509 *x); +ASN1_BIT_STRING * X509_get0_pubkey_bitstr(const X509 *x); +int X509_certificate_type(X509 *x,EVP_PKEY *pubkey /* optional */); + +int X509_REQ_set_version(X509_REQ *x,long version); +int X509_REQ_set_subject_name(X509_REQ *req,X509_NAME *name); +int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey); +EVP_PKEY * X509_REQ_get_pubkey(X509_REQ *req); +int X509_REQ_extension_nid(int nid); +int * X509_REQ_get_extension_nids(void); +void X509_REQ_set_extension_nids(int *nids); +STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req); +int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, + int nid); +int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts); +int X509_REQ_get_attr_count(const X509_REQ *req); +int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, + int lastpos); +int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc); +X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc); +int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr); +int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_NID(X509_REQ *req, + int nid, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_txt(X509_REQ *req, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_CRL_set_version(X509_CRL *x, long version); +int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); +int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_sort(X509_CRL *crl); + +int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); +int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm); + +int X509_REQ_check_private_key(X509_REQ *x509,EVP_PKEY *pkey); + +int X509_check_private_key(X509 *x509,EVP_PKEY *pkey); + +int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_and_serial_hash(X509 *a); + +int X509_issuer_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_name_hash(X509 *a); + +int X509_subject_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_subject_name_hash(X509 *x); + +#ifndef OPENSSL_NO_MD5 +unsigned long X509_issuer_name_hash_old(X509 *a); +unsigned long X509_subject_name_hash_old(X509 *x); +#endif + +int X509_cmp(const X509 *a, const X509 *b); +int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); +unsigned long X509_NAME_hash(X509_NAME *x); +unsigned long X509_NAME_hash_old(X509_NAME *x); + +int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); +int X509_print_ex_fp(FILE *bp,X509 *x, unsigned long nmflag, unsigned long cflag); +int X509_print_fp(FILE *bp,X509 *x); +int X509_CRL_print_fp(FILE *bp,X509_CRL *x); +int X509_REQ_print_fp(FILE *bp,X509_REQ *req); +int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags); + +#ifndef OPENSSL_NO_BIO +int X509_NAME_print(BIO *bp, X509_NAME *name, int obase); +int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags); +int X509_print_ex(BIO *bp,X509 *x, unsigned long nmflag, unsigned long cflag); +int X509_print(BIO *bp,X509 *x); +int X509_ocspid_print(BIO *bp,X509 *x); +int X509_CERT_AUX_print(BIO *bp,X509_CERT_AUX *x, int indent); +int X509_CRL_print(BIO *bp,X509_CRL *x); +int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, unsigned long cflag); +int X509_REQ_print(BIO *bp,X509_REQ *req); +#endif + +int X509_NAME_entry_count(X509_NAME *name); +int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, + char *buf,int len); +int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, + char *buf,int len); + +/* NOTE: you should be passsing -1, not 0 as lastpos. The functions that use + * lastpos, search after that position on. */ +int X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos); +int X509_NAME_get_index_by_OBJ(X509_NAME *name,ASN1_OBJECT *obj, + int lastpos); +X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc); +X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); +int X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne, + int loc, int set); +int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, + unsigned char *bytes, int len, int loc, int set); +int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, + unsigned char *bytes, int len, int loc, int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, + const char *field, int type, const unsigned char *bytes, int len); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, + int type,unsigned char *bytes, int len); +int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, + const unsigned char *bytes, int len, int loc, int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, + ASN1_OBJECT *obj, int type,const unsigned char *bytes, + int len); +int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, + ASN1_OBJECT *obj); +int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, + const unsigned char *bytes, int len); +ASN1_OBJECT * X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne); +ASN1_STRING * X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne); + +int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x); +int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, + int nid, int lastpos); +int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x, + ASN1_OBJECT *obj,int lastpos); +int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x, + int crit, int lastpos); +X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc); +X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc); +STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, + X509_EXTENSION *ex, int loc); + +int X509_get_ext_count(X509 *x); +int X509_get_ext_by_NID(X509 *x, int nid, int lastpos); +int X509_get_ext_by_OBJ(X509 *x,ASN1_OBJECT *obj,int lastpos); +int X509_get_ext_by_critical(X509 *x, int crit, int lastpos); +X509_EXTENSION *X509_get_ext(X509 *x, int loc); +X509_EXTENSION *X509_delete_ext(X509 *x, int loc); +int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); +void * X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx); +int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_CRL_get_ext_count(X509_CRL *x); +int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos); +int X509_CRL_get_ext_by_OBJ(X509_CRL *x,ASN1_OBJECT *obj,int lastpos); +int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos); +X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc); +X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc); +int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc); +void * X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx); +int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_REVOKED_get_ext_count(X509_REVOKED *x); +int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos); +int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x,ASN1_OBJECT *obj,int lastpos); +int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos); +X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc); +X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc); +int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc); +void * X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx); +int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, + unsigned long flags); + +X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, + int nid, int crit, ASN1_OCTET_STRING *data); +X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, + ASN1_OBJECT *obj,int crit,ASN1_OCTET_STRING *data); +int X509_EXTENSION_set_object(X509_EXTENSION *ex,ASN1_OBJECT *obj); +int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit); +int X509_EXTENSION_set_data(X509_EXTENSION *ex, + ASN1_OCTET_STRING *data); +ASN1_OBJECT * X509_EXTENSION_get_object(X509_EXTENSION *ex); +ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne); +int X509_EXTENSION_get_critical(X509_EXTENSION *ex); + +int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x); +int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, + int lastpos); +int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc); +X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, + X509_ATTRIBUTE *attr); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x, + int nid, int type, + const unsigned char *bytes, int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x, + const char *attrname, int type, + const unsigned char *bytes, int len); +void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, + ASN1_OBJECT *obj, int lastpos, int type); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, + int atrtype, const void *data, int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, + const ASN1_OBJECT *obj, int atrtype, const void *data, int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, + const char *atrname, int type, const unsigned char *bytes, int len); +int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj); +int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len); +void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, + int atrtype, void *data); +int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr); +ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr); +ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx); + +int EVP_PKEY_get_attr_count(const EVP_PKEY *key); +int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, + int lastpos); +int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc); +X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc); +int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr); +int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key, + int nid, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_verify_cert(X509_STORE_CTX *ctx); + +/* lookup a cert from a X509 STACK */ +X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk,X509_NAME *name, + ASN1_INTEGER *serial); +X509 *X509_find_by_subject(STACK_OF(X509) *sk,X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(PBEPARAM) +DECLARE_ASN1_FUNCTIONS(PBE2PARAM) +DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM) + +int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, + const unsigned char *salt, int saltlen); + +X509_ALGOR *PKCS5_pbe_set(int alg, int iter, + const unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen, + unsigned char *aiv, int prf_nid); + +X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, + int prf_nid, int keylen); + +/* PKCS#8 utilities */ + +DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) + +EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8); +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey); +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken); +PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken); + +int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, + int version, int ptype, void *pval, + unsigned char *penc, int penclen); +int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, + PKCS8_PRIV_KEY_INFO *p8); + +int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, + int ptype, void *pval, + unsigned char *penc, int penclen); +int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, + X509_PUBKEY *pub); + +int X509_check_trust(X509 *x, int id, int flags); +int X509_TRUST_get_count(void); +X509_TRUST * X509_TRUST_get0(int idx); +int X509_TRUST_get_by_id(int id); +int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int), + char *name, int arg1, void *arg2); +void X509_TRUST_cleanup(void); +int X509_TRUST_get_flags(X509_TRUST *xp); +char *X509_TRUST_get0_name(X509_TRUST *xp); +int X509_TRUST_get_trust(X509_TRUST *xp); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_X509_strings(void); + +/* Error codes for the X509 functions. */ + +/* Function codes. */ +#define X509_F_ADD_CERT_DIR 100 +#define X509_F_BY_FILE_CTRL 101 +#define X509_F_CHECK_POLICY 145 +#define X509_F_DIR_CTRL 102 +#define X509_F_GET_CERT_BY_SUBJECT 103 +#define X509_F_NETSCAPE_SPKI_B64_DECODE 129 +#define X509_F_NETSCAPE_SPKI_B64_ENCODE 130 +#define X509_F_X509AT_ADD1_ATTR 135 +#define X509_F_X509V3_ADD_EXT 104 +#define X509_F_X509_ATTRIBUTE_CREATE_BY_NID 136 +#define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ 137 +#define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT 140 +#define X509_F_X509_ATTRIBUTE_GET0_DATA 139 +#define X509_F_X509_ATTRIBUTE_SET1_DATA 138 +#define X509_F_X509_CHECK_PRIVATE_KEY 128 +#define X509_F_X509_CRL_PRINT_FP 147 +#define X509_F_X509_EXTENSION_CREATE_BY_NID 108 +#define X509_F_X509_EXTENSION_CREATE_BY_OBJ 109 +#define X509_F_X509_GET_PUBKEY_PARAMETERS 110 +#define X509_F_X509_LOAD_CERT_CRL_FILE 132 +#define X509_F_X509_LOAD_CERT_FILE 111 +#define X509_F_X509_LOAD_CRL_FILE 112 +#define X509_F_X509_NAME_ADD_ENTRY 113 +#define X509_F_X509_NAME_ENTRY_CREATE_BY_NID 114 +#define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT 131 +#define X509_F_X509_NAME_ENTRY_SET_OBJECT 115 +#define X509_F_X509_NAME_ONELINE 116 +#define X509_F_X509_NAME_PRINT 117 +#define X509_F_X509_PRINT_EX_FP 118 +#define X509_F_X509_PUBKEY_GET 119 +#define X509_F_X509_PUBKEY_SET 120 +#define X509_F_X509_REQ_CHECK_PRIVATE_KEY 144 +#define X509_F_X509_REQ_PRINT_EX 121 +#define X509_F_X509_REQ_PRINT_FP 122 +#define X509_F_X509_REQ_TO_X509 123 +#define X509_F_X509_STORE_ADD_CERT 124 +#define X509_F_X509_STORE_ADD_CRL 125 +#define X509_F_X509_STORE_CTX_GET1_ISSUER 146 +#define X509_F_X509_STORE_CTX_INIT 143 +#define X509_F_X509_STORE_CTX_NEW 142 +#define X509_F_X509_STORE_CTX_PURPOSE_INHERIT 134 +#define X509_F_X509_TO_X509_REQ 126 +#define X509_F_X509_TRUST_ADD 133 +#define X509_F_X509_TRUST_SET 141 +#define X509_F_X509_VERIFY_CERT 127 + +/* Reason codes. */ +#define X509_R_BAD_X509_FILETYPE 100 +#define X509_R_BASE64_DECODE_ERROR 118 +#define X509_R_CANT_CHECK_DH_KEY 114 +#define X509_R_CERT_ALREADY_IN_HASH_TABLE 101 +#define X509_R_ERR_ASN1_LIB 102 +#define X509_R_INVALID_DIRECTORY 113 +#define X509_R_INVALID_FIELD_NAME 119 +#define X509_R_INVALID_TRUST 123 +#define X509_R_KEY_TYPE_MISMATCH 115 +#define X509_R_KEY_VALUES_MISMATCH 116 +#define X509_R_LOADING_CERT_DIR 103 +#define X509_R_LOADING_DEFAULTS 104 +#define X509_R_METHOD_NOT_SUPPORTED 124 +#define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 105 +#define X509_R_PUBLIC_KEY_DECODE_ERROR 125 +#define X509_R_PUBLIC_KEY_ENCODE_ERROR 126 +#define X509_R_SHOULD_RETRY 106 +#define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107 +#define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108 +#define X509_R_UNKNOWN_KEY_TYPE 117 +#define X509_R_UNKNOWN_NID 109 +#define X509_R_UNKNOWN_PURPOSE_ID 121 +#define X509_R_UNKNOWN_TRUST_ID 120 +#define X509_R_UNSUPPORTED_ALGORITHM 111 +#define X509_R_WRONG_LOOKUP_TYPE 112 +#define X509_R_WRONG_TYPE 122 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/openssl/x509_vfy.h b/crypto/libressl/include/openssl/x509_vfy.h new file mode 100644 index 0000000000..e4050b2172 --- /dev/null +++ b/crypto/libressl/include/openssl/x509_vfy.h @@ -0,0 +1,560 @@ +/* $OpenBSD: x509_vfy.h,v 1.15 2015/02/07 13:19:15 doug Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_X509_H +#include +/* openssl/x509.h ends up #include-ing this file at about the only + * appropriate moment. */ +#endif + +#ifndef HEADER_X509_VFY_H +#define HEADER_X509_VFY_H + +#include + +#ifndef OPENSSL_NO_LHASH +#include +#endif +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct x509_file_st + { + int num_paths; /* number of paths to files or directories */ + int num_alloced; + char **paths; /* the list of paths or directories */ + int *path_type; + } X509_CERT_FILE_CTX; + +/*******************************/ +/* +SSL_CTX -> X509_STORE + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + +SSL -> X509_STORE_CTX + ->X509_STORE + +The X509_STORE holds the tables etc for verification stuff. +A X509_STORE_CTX is used while validating a single certificate. +The X509_STORE has X509_LOOKUPs for looking up certs. +The X509_STORE then calls a function to actually verify the +certificate chain. +*/ + +#define X509_LU_RETRY -1 +#define X509_LU_FAIL 0 +#define X509_LU_X509 1 +#define X509_LU_CRL 2 +#define X509_LU_PKEY 3 + +typedef struct x509_object_st + { + /* one of the above types */ + int type; + union { + char *ptr; + X509 *x509; + X509_CRL *crl; + EVP_PKEY *pkey; + } data; + } X509_OBJECT; + +typedef struct x509_lookup_st X509_LOOKUP; + +DECLARE_STACK_OF(X509_LOOKUP) +DECLARE_STACK_OF(X509_OBJECT) + +/* This is a static that defines the function interface */ +typedef struct x509_lookup_method_st + { + const char *name; + int (*new_item)(X509_LOOKUP *ctx); + void (*free)(X509_LOOKUP *ctx); + int (*init)(X509_LOOKUP *ctx); + int (*shutdown)(X509_LOOKUP *ctx); + int (*ctrl)(X509_LOOKUP *ctx,int cmd,const char *argc,long argl, + char **ret); + int (*get_by_subject)(X509_LOOKUP *ctx,int type,X509_NAME *name, + X509_OBJECT *ret); + int (*get_by_issuer_serial)(X509_LOOKUP *ctx,int type,X509_NAME *name, + ASN1_INTEGER *serial,X509_OBJECT *ret); + int (*get_by_fingerprint)(X509_LOOKUP *ctx,int type, + unsigned char *bytes,int len, + X509_OBJECT *ret); + int (*get_by_alias)(X509_LOOKUP *ctx,int type,char *str,int len, + X509_OBJECT *ret); + } X509_LOOKUP_METHOD; + +/* This structure hold all parameters associated with a verify operation + * by including an X509_VERIFY_PARAM structure in related structures the + * parameters used can be customized + */ + +typedef struct X509_VERIFY_PARAM_st + { + char *name; + time_t check_time; /* Time to use */ + unsigned long inh_flags; /* Inheritance flags */ + unsigned long flags; /* Various verify flags */ + int purpose; /* purpose to check untrusted certificates */ + int trust; /* trust setting to check */ + int depth; /* Verify depth */ + STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */ + } X509_VERIFY_PARAM; + +DECLARE_STACK_OF(X509_VERIFY_PARAM) + +/* This is used to hold everything. It is used for all certificate + * validation. Once we have a certificate chain, the 'verify' + * function is then called to actually check the cert chain. */ +struct x509_store_st + { + /* The following is a cache of trusted certs */ + int cache; /* if true, stash any hits */ + STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */ + + /* These are external lookup methods */ + STACK_OF(X509_LOOKUP) *get_cert_methods; + + X509_VERIFY_PARAM *param; + + /* Callbacks for various operations */ + int (*verify)(X509_STORE_CTX *ctx); /* called to verify a certificate */ + int (*verify_cb)(int ok,X509_STORE_CTX *ctx); /* error callback */ + int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); /* get issuers cert from ctx */ + int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */ + int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */ + int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */ + int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ + int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ + STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm); + STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm); + int (*cleanup)(X509_STORE_CTX *ctx); + + CRYPTO_EX_DATA ex_data; + int references; + } /* X509_STORE */; + +int X509_STORE_set_depth(X509_STORE *store, int depth); + +#define X509_STORE_set_verify_cb_func(ctx,func) ((ctx)->verify_cb=(func)) +#define X509_STORE_set_verify_func(ctx,func) ((ctx)->verify=(func)) + +/* This is the functions plus an instance of the local variables. */ +struct x509_lookup_st + { + int init; /* have we been started */ + int skip; /* don't use us. */ + X509_LOOKUP_METHOD *method; /* the functions */ + char *method_data; /* method data */ + + X509_STORE *store_ctx; /* who owns us */ + } /* X509_LOOKUP */; + +/* This is a used when verifying cert chains. Since the + * gathering of the cert chain can take some time (and have to be + * 'retried', this needs to be kept and passed around. */ +struct x509_store_ctx_st /* X509_STORE_CTX */ + { + X509_STORE *ctx; + int current_method; /* used when looking up certs */ + + /* The following are set by the caller */ + X509 *cert; /* The cert to check */ + STACK_OF(X509) *untrusted; /* chain of X509s - untrusted - passed in */ + STACK_OF(X509_CRL) *crls; /* set of CRLs passed in */ + + X509_VERIFY_PARAM *param; + void *other_ctx; /* Other info for use with get_issuer() */ + + /* Callbacks for various operations */ + int (*verify)(X509_STORE_CTX *ctx); /* called to verify a certificate */ + int (*verify_cb)(int ok,X509_STORE_CTX *ctx); /* error callback */ + int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); /* get issuers cert from ctx */ + int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */ + int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */ + int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */ + int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ + int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ + int (*check_policy)(X509_STORE_CTX *ctx); + STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm); + STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm); + int (*cleanup)(X509_STORE_CTX *ctx); + + /* The following is built up */ + int valid; /* if 0, rebuild chain */ + int last_untrusted; /* index of last untrusted cert */ + STACK_OF(X509) *chain; /* chain of X509s - built up and trusted */ + X509_POLICY_TREE *tree; /* Valid policy tree */ + + int explicit_policy; /* Require explicit policy value */ + + /* When something goes wrong, this is why */ + int error_depth; + int error; + X509 *current_cert; + X509 *current_issuer; /* cert currently being tested as valid issuer */ + X509_CRL *current_crl; /* current CRL */ + + int current_crl_score; /* score of current CRL */ + unsigned int current_reasons; /* Reason mask */ + + X509_STORE_CTX *parent; /* For CRL path validation: parent context */ + + CRYPTO_EX_DATA ex_data; + } /* X509_STORE_CTX */; + +void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); + +#define X509_STORE_CTX_set_app_data(ctx,data) \ + X509_STORE_CTX_set_ex_data(ctx,0,data) +#define X509_STORE_CTX_get_app_data(ctx) \ + X509_STORE_CTX_get_ex_data(ctx,0) + +#define X509_L_FILE_LOAD 1 +#define X509_L_ADD_DIR 2 +#define X509_L_MEM 3 + +#define X509_LOOKUP_load_file(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL) + +#define X509_LOOKUP_add_dir(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL) + +#define X509_LOOKUP_add_mem(x,iov,type) \ + X509_LOOKUP_ctrl((x),X509_L_MEM,(const char *)(iov),\ + (long)(type),NULL) + +#define X509_V_OK 0 +/* illegal error (for uninitialized values, to avoid X509_V_OK): 1 */ + +#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 +#define X509_V_ERR_UNABLE_TO_GET_CRL 3 +#define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 +#define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 +#define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 +#define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 +#define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 +#define X509_V_ERR_CERT_NOT_YET_VALID 9 +#define X509_V_ERR_CERT_HAS_EXPIRED 10 +#define X509_V_ERR_CRL_NOT_YET_VALID 11 +#define X509_V_ERR_CRL_HAS_EXPIRED 12 +#define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 +#define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 +#define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 +#define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 +#define X509_V_ERR_OUT_OF_MEM 17 +#define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 +#define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 +#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 +#define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 +#define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 +#define X509_V_ERR_CERT_REVOKED 23 +#define X509_V_ERR_INVALID_CA 24 +#define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 +#define X509_V_ERR_INVALID_PURPOSE 26 +#define X509_V_ERR_CERT_UNTRUSTED 27 +#define X509_V_ERR_CERT_REJECTED 28 +/* These are 'informational' when looking for issuer cert */ +#define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 +#define X509_V_ERR_AKID_SKID_MISMATCH 30 +#define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 +#define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 + +#define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 +#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 +#define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 +#define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 +#define X509_V_ERR_INVALID_NON_CA 37 +#define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 +#define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 +#define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 + +#define X509_V_ERR_INVALID_EXTENSION 41 +#define X509_V_ERR_INVALID_POLICY_EXTENSION 42 +#define X509_V_ERR_NO_EXPLICIT_POLICY 43 +#define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 +#define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 + +#define X509_V_ERR_UNNESTED_RESOURCE 46 + +#define X509_V_ERR_PERMITTED_VIOLATION 47 +#define X509_V_ERR_EXCLUDED_VIOLATION 48 +#define X509_V_ERR_SUBTREE_MINMAX 49 +#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 +#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 +#define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 +#define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 + +/* The application is not happy */ +#define X509_V_ERR_APPLICATION_VERIFICATION 50 + +/* Certificate verify flags */ + +/* Send issuer+subject checks to verify_cb */ +#define X509_V_FLAG_CB_ISSUER_CHECK 0x1 +/* Use check time instead of current time */ +#define X509_V_FLAG_USE_CHECK_TIME 0x2 +/* Lookup CRLs */ +#define X509_V_FLAG_CRL_CHECK 0x4 +/* Lookup CRLs for whole chain */ +#define X509_V_FLAG_CRL_CHECK_ALL 0x8 +/* Ignore unhandled critical extensions */ +#define X509_V_FLAG_IGNORE_CRITICAL 0x10 +/* Disable workarounds for broken certificates */ +#define X509_V_FLAG_X509_STRICT 0x20 +/* Enable proxy certificate validation */ +#define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40 +/* Enable policy checking */ +#define X509_V_FLAG_POLICY_CHECK 0x80 +/* Policy variable require-explicit-policy */ +#define X509_V_FLAG_EXPLICIT_POLICY 0x100 +/* Policy variable inhibit-any-policy */ +#define X509_V_FLAG_INHIBIT_ANY 0x200 +/* Policy variable inhibit-policy-mapping */ +#define X509_V_FLAG_INHIBIT_MAP 0x400 +/* Notify callback that policy is OK */ +#define X509_V_FLAG_NOTIFY_POLICY 0x800 +/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */ +#define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000 +/* Delta CRL support */ +#define X509_V_FLAG_USE_DELTAS 0x2000 +/* Check selfsigned CA signature */ +#define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 +/* Do not check certificate or CRL validity against current time. */ +#define X509_V_FLAG_NO_CHECK_TIME 0x200000 + +#define X509_VP_FLAG_DEFAULT 0x1 +#define X509_VP_FLAG_OVERWRITE 0x2 +#define X509_VP_FLAG_RESET_FLAGS 0x4 +#define X509_VP_FLAG_LOCKED 0x8 +#define X509_VP_FLAG_ONCE 0x10 + +/* Internal use: mask of policy related options */ +#define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \ + | X509_V_FLAG_EXPLICIT_POLICY \ + | X509_V_FLAG_INHIBIT_ANY \ + | X509_V_FLAG_INHIBIT_MAP) + +int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,int type,X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x); +void X509_OBJECT_up_ref_count(X509_OBJECT *a); +void X509_OBJECT_free_contents(X509_OBJECT *a); +X509_STORE *X509_STORE_new(void ); +void X509_STORE_free(X509_STORE *v); + +STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm); +STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm); +int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); +int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); +int X509_STORE_set_trust(X509_STORE *ctx, int trust); +int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm); + +void X509_STORE_set_verify_cb(X509_STORE *ctx, + int (*verify_cb)(int, X509_STORE_CTX *)); + +X509_STORE_CTX *X509_STORE_CTX_new(void); + +int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + +void X509_STORE_CTX_free(X509_STORE_CTX *ctx); +int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, + X509 *x509, STACK_OF(X509) *chain); +void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); + +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m); + +X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); +X509_LOOKUP_METHOD *X509_LOOKUP_file(void); +X509_LOOKUP_METHOD *X509_LOOKUP_mem(void); + +int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); +int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); + +int X509_STORE_get_by_subject(X509_STORE_CTX *vs,int type,X509_NAME *name, + X509_OBJECT *ret); + +int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); + +int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type); + + +X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method); +void X509_LOOKUP_free(X509_LOOKUP *ctx); +int X509_LOOKUP_init(X509_LOOKUP *ctx); +int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret); +int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, + ASN1_INTEGER *serial, X509_OBJECT *ret); +int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, + unsigned char *bytes, int len, X509_OBJECT *ret); +int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, + int len, X509_OBJECT *ret); +int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); + +int X509_STORE_load_locations (X509_STORE *ctx, + const char *file, const char *dir); +int X509_STORE_load_mem(X509_STORE *ctx, void *buf, int len); +int X509_STORE_set_default_paths(X509_STORE *ctx); + +int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx,int idx,void *data); +void * X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx); +int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s); +int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); +X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); +X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx); +X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx); +X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x); +void X509_STORE_CTX_set_chain(X509_STORE_CTX *c,STACK_OF(X509) *sk); +void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c,STACK_OF(X509_CRL) *sk); +int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); +int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, + int purpose, int trust); +void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); +void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, + time_t t); +void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + int (*verify_cb)(int, X509_STORE_CTX *)); + +X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx); +int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx); + +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); +int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); + +/* X509_VERIFY_PARAM functions */ + +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); +void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name); +int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags); +int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose); +int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust); +void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth); +void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t); +int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, + ASN1_OBJECT *policy); +int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, + STACK_OF(ASN1_OBJECT) *policies); +int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); + +int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param); +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name); +void X509_VERIFY_PARAM_table_cleanup(void); + +int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, + STACK_OF(X509) *certs, + STACK_OF(ASN1_OBJECT) *policy_oids, + unsigned int flags); + +void X509_policy_tree_free(X509_POLICY_TREE *tree); + +int X509_policy_tree_level_count(const X509_POLICY_TREE *tree); +X509_POLICY_LEVEL * + X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i); + +STACK_OF(X509_POLICY_NODE) * + X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree); + +STACK_OF(X509_POLICY_NODE) * + X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree); + +int X509_policy_level_node_count(X509_POLICY_LEVEL *level); + +X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i); + +const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node); + +STACK_OF(POLICYQUALINFO) * + X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node); +const X509_POLICY_NODE * + X509_policy_node_get0_parent(const X509_POLICY_NODE *node); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/crypto/libressl/include/openssl/x509v3.h b/crypto/libressl/include/openssl/x509v3.h new file mode 100644 index 0000000000..72cfe2c76b --- /dev/null +++ b/crypto/libressl/include/openssl/x509v3.h @@ -0,0 +1,862 @@ +/* $OpenBSD: x509v3.h,v 1.15 2014/07/10 22:45:58 jsing Exp $ */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_X509V3_H +#define HEADER_X509V3_H + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Forward reference */ +struct v3_ext_method; +struct v3_ext_ctx; + +/* Useful typedefs */ + +typedef void * (*X509V3_EXT_NEW)(void); +typedef void (*X509V3_EXT_FREE)(void *); +typedef void * (*X509V3_EXT_D2I)(void *, const unsigned char ** , long); +typedef int (*X509V3_EXT_I2D)(void *, unsigned char **); +typedef STACK_OF(CONF_VALUE) * + (*X509V3_EXT_I2V)(const struct v3_ext_method *method, void *ext, + STACK_OF(CONF_VALUE) *extlist); +typedef void * (*X509V3_EXT_V2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, + STACK_OF(CONF_VALUE) *values); +typedef char * (*X509V3_EXT_I2S)(const struct v3_ext_method *method, void *ext); +typedef void * (*X509V3_EXT_S2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); +typedef int (*X509V3_EXT_I2R)(const struct v3_ext_method *method, void *ext, + BIO *out, int indent); +typedef void * (*X509V3_EXT_R2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); + +/* V3 extension structure */ + +struct v3_ext_method { +int ext_nid; +int ext_flags; +/* If this is set the following four fields are ignored */ +ASN1_ITEM_EXP *it; +/* Old style ASN1 calls */ +X509V3_EXT_NEW ext_new; +X509V3_EXT_FREE ext_free; +X509V3_EXT_D2I d2i; +X509V3_EXT_I2D i2d; + +/* The following pair is used for string extensions */ +X509V3_EXT_I2S i2s; +X509V3_EXT_S2I s2i; + +/* The following pair is used for multi-valued extensions */ +X509V3_EXT_I2V i2v; +X509V3_EXT_V2I v2i; + +/* The following are used for raw extensions */ +X509V3_EXT_I2R i2r; +X509V3_EXT_R2I r2i; + +void *usr_data; /* Any extension specific data */ +}; + +typedef struct X509V3_CONF_METHOD_st { +char * (*get_string)(void *db, char *section, char *value); +STACK_OF(CONF_VALUE) * (*get_section)(void *db, char *section); +void (*free_string)(void *db, char * string); +void (*free_section)(void *db, STACK_OF(CONF_VALUE) *section); +} X509V3_CONF_METHOD; + +/* Context specific info */ +struct v3_ext_ctx { +#define CTX_TEST 0x1 +int flags; +X509 *issuer_cert; +X509 *subject_cert; +X509_REQ *subject_req; +X509_CRL *crl; +X509V3_CONF_METHOD *db_meth; +void *db; +/* Maybe more here */ +}; + +typedef struct v3_ext_method X509V3_EXT_METHOD; + +DECLARE_STACK_OF(X509V3_EXT_METHOD) + +/* ext_flags values */ +#define X509V3_EXT_DYNAMIC 0x1 +#define X509V3_EXT_CTX_DEP 0x2 +#define X509V3_EXT_MULTILINE 0x4 + +typedef BIT_STRING_BITNAME ENUMERATED_NAMES; + +typedef struct BASIC_CONSTRAINTS_st { +int ca; +ASN1_INTEGER *pathlen; +} BASIC_CONSTRAINTS; + + +typedef struct PKEY_USAGE_PERIOD_st { +ASN1_GENERALIZEDTIME *notBefore; +ASN1_GENERALIZEDTIME *notAfter; +} PKEY_USAGE_PERIOD; + +typedef struct otherName_st { +ASN1_OBJECT *type_id; +ASN1_TYPE *value; +} OTHERNAME; + +typedef struct EDIPartyName_st { + ASN1_STRING *nameAssigner; + ASN1_STRING *partyName; +} EDIPARTYNAME; + +typedef struct GENERAL_NAME_st { + +#define GEN_OTHERNAME 0 +#define GEN_EMAIL 1 +#define GEN_DNS 2 +#define GEN_X400 3 +#define GEN_DIRNAME 4 +#define GEN_EDIPARTY 5 +#define GEN_URI 6 +#define GEN_IPADD 7 +#define GEN_RID 8 + +int type; +union { + char *ptr; + OTHERNAME *otherName; /* otherName */ + ASN1_IA5STRING *rfc822Name; + ASN1_IA5STRING *dNSName; + ASN1_TYPE *x400Address; + X509_NAME *directoryName; + EDIPARTYNAME *ediPartyName; + ASN1_IA5STRING *uniformResourceIdentifier; + ASN1_OCTET_STRING *iPAddress; + ASN1_OBJECT *registeredID; + + /* Old names */ + ASN1_OCTET_STRING *ip; /* iPAddress */ + X509_NAME *dirn; /* dirn */ + ASN1_IA5STRING *ia5;/* rfc822Name, dNSName, uniformResourceIdentifier */ + ASN1_OBJECT *rid; /* registeredID */ + ASN1_TYPE *other; /* x400Address */ +} d; +} GENERAL_NAME; + +typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES; + +typedef struct ACCESS_DESCRIPTION_st { + ASN1_OBJECT *method; + GENERAL_NAME *location; +} ACCESS_DESCRIPTION; + +typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; + +typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE; + +DECLARE_STACK_OF(GENERAL_NAME) +DECLARE_ASN1_SET_OF(GENERAL_NAME) + +DECLARE_STACK_OF(ACCESS_DESCRIPTION) +DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION) + +typedef struct DIST_POINT_NAME_st { +int type; +union { + GENERAL_NAMES *fullname; + STACK_OF(X509_NAME_ENTRY) *relativename; +} name; +/* If relativename then this contains the full distribution point name */ +X509_NAME *dpname; +} DIST_POINT_NAME; +/* All existing reasons */ +#define CRLDP_ALL_REASONS 0x807f + +#define CRL_REASON_NONE -1 +#define CRL_REASON_UNSPECIFIED 0 +#define CRL_REASON_KEY_COMPROMISE 1 +#define CRL_REASON_CA_COMPROMISE 2 +#define CRL_REASON_AFFILIATION_CHANGED 3 +#define CRL_REASON_SUPERSEDED 4 +#define CRL_REASON_CESSATION_OF_OPERATION 5 +#define CRL_REASON_CERTIFICATE_HOLD 6 +#define CRL_REASON_REMOVE_FROM_CRL 8 +#define CRL_REASON_PRIVILEGE_WITHDRAWN 9 +#define CRL_REASON_AA_COMPROMISE 10 + +struct DIST_POINT_st { +DIST_POINT_NAME *distpoint; +ASN1_BIT_STRING *reasons; +GENERAL_NAMES *CRLissuer; +int dp_reasons; +}; + +typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS; + +DECLARE_STACK_OF(DIST_POINT) +DECLARE_ASN1_SET_OF(DIST_POINT) + +struct AUTHORITY_KEYID_st { +ASN1_OCTET_STRING *keyid; +GENERAL_NAMES *issuer; +ASN1_INTEGER *serial; +}; + +/* Strong extranet structures */ + +typedef struct SXNET_ID_st { + ASN1_INTEGER *zone; + ASN1_OCTET_STRING *user; +} SXNETID; + +DECLARE_STACK_OF(SXNETID) +DECLARE_ASN1_SET_OF(SXNETID) + +typedef struct SXNET_st { + ASN1_INTEGER *version; + STACK_OF(SXNETID) *ids; +} SXNET; + +typedef struct NOTICEREF_st { + ASN1_STRING *organization; + STACK_OF(ASN1_INTEGER) *noticenos; +} NOTICEREF; + +typedef struct USERNOTICE_st { + NOTICEREF *noticeref; + ASN1_STRING *exptext; +} USERNOTICE; + +typedef struct POLICYQUALINFO_st { + ASN1_OBJECT *pqualid; + union { + ASN1_IA5STRING *cpsuri; + USERNOTICE *usernotice; + ASN1_TYPE *other; + } d; +} POLICYQUALINFO; + +DECLARE_STACK_OF(POLICYQUALINFO) +DECLARE_ASN1_SET_OF(POLICYQUALINFO) + +typedef struct POLICYINFO_st { + ASN1_OBJECT *policyid; + STACK_OF(POLICYQUALINFO) *qualifiers; +} POLICYINFO; + +typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES; + +DECLARE_STACK_OF(POLICYINFO) +DECLARE_ASN1_SET_OF(POLICYINFO) + +typedef struct POLICY_MAPPING_st { + ASN1_OBJECT *issuerDomainPolicy; + ASN1_OBJECT *subjectDomainPolicy; +} POLICY_MAPPING; + +DECLARE_STACK_OF(POLICY_MAPPING) + +typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS; + +typedef struct GENERAL_SUBTREE_st { + GENERAL_NAME *base; + ASN1_INTEGER *minimum; + ASN1_INTEGER *maximum; +} GENERAL_SUBTREE; + +DECLARE_STACK_OF(GENERAL_SUBTREE) + +struct NAME_CONSTRAINTS_st { + STACK_OF(GENERAL_SUBTREE) *permittedSubtrees; + STACK_OF(GENERAL_SUBTREE) *excludedSubtrees; +}; + +typedef struct POLICY_CONSTRAINTS_st { + ASN1_INTEGER *requireExplicitPolicy; + ASN1_INTEGER *inhibitPolicyMapping; +} POLICY_CONSTRAINTS; + +/* Proxy certificate structures, see RFC 3820 */ +typedef struct PROXY_POLICY_st + { + ASN1_OBJECT *policyLanguage; + ASN1_OCTET_STRING *policy; + } PROXY_POLICY; + +typedef struct PROXY_CERT_INFO_EXTENSION_st + { + ASN1_INTEGER *pcPathLengthConstraint; + PROXY_POLICY *proxyPolicy; + } PROXY_CERT_INFO_EXTENSION; + +DECLARE_ASN1_FUNCTIONS(PROXY_POLICY) +DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) + +struct ISSUING_DIST_POINT_st + { + DIST_POINT_NAME *distpoint; + int onlyuser; + int onlyCA; + ASN1_BIT_STRING *onlysomereasons; + int indirectCRL; + int onlyattr; + }; + +/* Values in idp_flags field */ +/* IDP present */ +#define IDP_PRESENT 0x1 +/* IDP values inconsistent */ +#define IDP_INVALID 0x2 +/* onlyuser true */ +#define IDP_ONLYUSER 0x4 +/* onlyCA true */ +#define IDP_ONLYCA 0x8 +/* onlyattr true */ +#define IDP_ONLYATTR 0x10 +/* indirectCRL true */ +#define IDP_INDIRECT 0x20 +/* onlysomereasons present */ +#define IDP_REASONS 0x40 + +#define X509V3_conf_err(val) ERR_asprintf_error_data( \ + "section:%s,name:%s,value:%s", val->section, \ + val->name, val->value); + +#define X509V3_set_ctx_test(ctx) \ + X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST) +#define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL; + +#define EXT_BITSTRING(nid, table) { nid, 0, ASN1_ITEM_ref(ASN1_BIT_STRING), \ + 0,0,0,0, \ + 0,0, \ + (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \ + (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, \ + NULL, NULL, \ + table} + +#define EXT_IA5STRING(nid) { nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), \ + 0,0,0,0, \ + (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, \ + (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, \ + 0,0,0,0, \ + NULL} + +#define EXT_END { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + + +/* X509_PURPOSE stuff */ + +#define EXFLAG_BCONS 0x1 +#define EXFLAG_KUSAGE 0x2 +#define EXFLAG_XKUSAGE 0x4 +#define EXFLAG_NSCERT 0x8 + +#define EXFLAG_CA 0x10 +/* Really self issued not necessarily self signed */ +#define EXFLAG_SI 0x20 +#define EXFLAG_SS 0x20 +#define EXFLAG_V1 0x40 +#define EXFLAG_INVALID 0x80 +#define EXFLAG_SET 0x100 +#define EXFLAG_CRITICAL 0x200 +#define EXFLAG_PROXY 0x400 + +#define EXFLAG_INVALID_POLICY 0x800 +#define EXFLAG_FRESHEST 0x1000 + +#define KU_DIGITAL_SIGNATURE 0x0080 +#define KU_NON_REPUDIATION 0x0040 +#define KU_KEY_ENCIPHERMENT 0x0020 +#define KU_DATA_ENCIPHERMENT 0x0010 +#define KU_KEY_AGREEMENT 0x0008 +#define KU_KEY_CERT_SIGN 0x0004 +#define KU_CRL_SIGN 0x0002 +#define KU_ENCIPHER_ONLY 0x0001 +#define KU_DECIPHER_ONLY 0x8000 + +#define NS_SSL_CLIENT 0x80 +#define NS_SSL_SERVER 0x40 +#define NS_SMIME 0x20 +#define NS_OBJSIGN 0x10 +#define NS_SSL_CA 0x04 +#define NS_SMIME_CA 0x02 +#define NS_OBJSIGN_CA 0x01 +#define NS_ANY_CA (NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA) + +#define XKU_SSL_SERVER 0x1 +#define XKU_SSL_CLIENT 0x2 +#define XKU_SMIME 0x4 +#define XKU_CODE_SIGN 0x8 +#define XKU_SGC 0x10 +#define XKU_OCSP_SIGN 0x20 +#define XKU_TIMESTAMP 0x40 +#define XKU_DVCS 0x80 + +#define X509_PURPOSE_DYNAMIC 0x1 +#define X509_PURPOSE_DYNAMIC_NAME 0x2 + +typedef struct x509_purpose_st { + int purpose; + int trust; /* Default trust ID */ + int flags; + int (*check_purpose)(const struct x509_purpose_st *, + const X509 *, int); + char *name; + char *sname; + void *usr_data; +} X509_PURPOSE; + +#define X509_PURPOSE_SSL_CLIENT 1 +#define X509_PURPOSE_SSL_SERVER 2 +#define X509_PURPOSE_NS_SSL_SERVER 3 +#define X509_PURPOSE_SMIME_SIGN 4 +#define X509_PURPOSE_SMIME_ENCRYPT 5 +#define X509_PURPOSE_CRL_SIGN 6 +#define X509_PURPOSE_ANY 7 +#define X509_PURPOSE_OCSP_HELPER 8 +#define X509_PURPOSE_TIMESTAMP_SIGN 9 + +#define X509_PURPOSE_MIN 1 +#define X509_PURPOSE_MAX 9 + +/* Flags for X509V3_EXT_print() */ + +#define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) +/* Return error for unknown extensions */ +#define X509V3_EXT_DEFAULT 0 +/* Print error for unknown extensions */ +#define X509V3_EXT_ERROR_UNKNOWN (1L << 16) +/* ASN1 parse unknown extensions */ +#define X509V3_EXT_PARSE_UNKNOWN (2L << 16) +/* BIO_dump unknown extensions */ +#define X509V3_EXT_DUMP_UNKNOWN (3L << 16) + +/* Flags for X509V3_add1_i2d */ + +#define X509V3_ADD_OP_MASK 0xfL +#define X509V3_ADD_DEFAULT 0L +#define X509V3_ADD_APPEND 1L +#define X509V3_ADD_REPLACE 2L +#define X509V3_ADD_REPLACE_EXISTING 3L +#define X509V3_ADD_KEEP_EXISTING 4L +#define X509V3_ADD_DELETE 5L +#define X509V3_ADD_SILENT 0x10 + +DECLARE_STACK_OF(X509_PURPOSE) + +DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS) + +DECLARE_ASN1_FUNCTIONS(SXNET) +DECLARE_ASN1_FUNCTIONS(SXNETID) + +int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen); +int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user, int userlen); +int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *izone, char *user, int userlen); + +ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone); +ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone); +ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone); + +DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID) + +DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD) + +DECLARE_ASN1_FUNCTIONS(GENERAL_NAME) +GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a); +int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b); + + + +ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + ASN1_BIT_STRING *bits, + STACK_OF(CONF_VALUE) *extlist); + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret); +int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen); + +DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES) + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, + GENERAL_NAMES *gen, STACK_OF(CONF_VALUE) *extlist); +GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); + +DECLARE_ASN1_FUNCTIONS(OTHERNAME) +DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME) +int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b); +void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value); +void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype); +int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, + ASN1_OBJECT *oid, ASN1_TYPE *value); +int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, + ASN1_OBJECT **poid, ASN1_TYPE **pvalue); + +char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *ia5); +ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str); + +DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) +int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION* a); + +DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES) +DECLARE_ASN1_FUNCTIONS(POLICYINFO) +DECLARE_ASN1_FUNCTIONS(POLICYQUALINFO) +DECLARE_ASN1_FUNCTIONS(USERNOTICE) +DECLARE_ASN1_FUNCTIONS(NOTICEREF) + +DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS) +DECLARE_ASN1_FUNCTIONS(DIST_POINT) +DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME) +DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT) + +int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname); + +int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc); + +DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) +DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) + +DECLARE_ASN1_ITEM(POLICY_MAPPING) +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) +DECLARE_ASN1_ITEM(POLICY_MAPPINGS) + +DECLARE_ASN1_ITEM(GENERAL_SUBTREE) +DECLARE_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) + +DECLARE_ASN1_ITEM(NAME_CONSTRAINTS) +DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) + +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) +DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS) + +GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + int gen_type, char *value, int is_nc); + +#ifdef HEADER_CONF_H +GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + CONF_VALUE *cnf); +GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc); +void X509V3_conf_free(CONF_VALUE *val); + +X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, char *value); +X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, char *value); +int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, STACK_OF(X509_EXTENSION) **sk); +int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509 *cert); +int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_REQ *req); +int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl); + +X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + int ext_nid, char *value); +X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *name, char *value); +int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509 *cert); +int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509_REQ *req); +int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509_CRL *crl); + +int X509V3_add_value_bool_nf(char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool); +int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint); +void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf); +void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash); +#endif + +char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section); +STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section); +void X509V3_string_free(X509V3_CTX *ctx, char *str); +void X509V3_section_free( X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section); +void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject, + X509_REQ *req, X509_CRL *crl, int flags); + +int X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_uchar(const char *name, const unsigned char *value, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_bool(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint, + STACK_OF(CONF_VALUE) **extlist); +char * i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint); +ASN1_INTEGER * s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value); +char * i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint); +char * i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint); +int X509V3_EXT_add(X509V3_EXT_METHOD *ext); +int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist); +int X509V3_EXT_add_alias(int nid_to, int nid_from); +void X509V3_EXT_cleanup(void); + +const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext); +const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); +int X509V3_add_standard_extensions(void); +STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); +void *X509V3_EXT_d2i(X509_EXTENSION *ext); +void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx); + + +X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc); +int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, int crit, unsigned long flags); + +char *hex_to_string(const unsigned char *buffer, long len); +unsigned char *string_to_hex(const char *str, long *len); +int name_cmp(const char *name, const char *cmp); + +void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, + int ml); +int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent); +int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent); + +int X509V3_extensions_print(BIO *out, char *title, STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent); + +int X509_check_ca(X509 *x); +int X509_check_purpose(X509 *x, int id, int ca); +int X509_supported_extension(X509_EXTENSION *ex); +int X509_PURPOSE_set(int *p, int purpose); +int X509_check_issued(X509 *issuer, X509 *subject); +int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid); +int X509_PURPOSE_get_count(void); +X509_PURPOSE * X509_PURPOSE_get0(int idx); +int X509_PURPOSE_get_by_sname(char *sname); +int X509_PURPOSE_get_by_id(int id); +int X509_PURPOSE_add(int id, int trust, int flags, + int (*ck)(const X509_PURPOSE *, const X509 *, int), + char *name, char *sname, void *arg); +char *X509_PURPOSE_get0_name(X509_PURPOSE *xp); +char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp); +int X509_PURPOSE_get_trust(X509_PURPOSE *xp); +void X509_PURPOSE_cleanup(void); +int X509_PURPOSE_get_id(X509_PURPOSE *); + +STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x); +STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x); +void X509_email_free(STACK_OF(OPENSSL_STRING) *sk); +STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x); + +ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc); +ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc); +int a2i_ipadd(unsigned char *ipout, const char *ipasc); +int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk, + unsigned long chtype); + +void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent); +DECLARE_STACK_OF(X509_POLICY_NODE) + + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_X509V3_strings(void); + +/* Error codes for the X509V3 functions. */ + +/* Function codes. */ +#define X509V3_F_A2I_GENERAL_NAME 164 +#define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE 161 +#define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL 162 +#define X509V3_F_COPY_EMAIL 122 +#define X509V3_F_COPY_ISSUER 123 +#define X509V3_F_DO_DIRNAME 144 +#define X509V3_F_DO_EXT_CONF 124 +#define X509V3_F_DO_EXT_I2D 135 +#define X509V3_F_DO_EXT_NCONF 151 +#define X509V3_F_DO_I2V_NAME_CONSTRAINTS 148 +#define X509V3_F_GNAMES_FROM_SECTNAME 156 +#define X509V3_F_HEX_TO_STRING 111 +#define X509V3_F_I2S_ASN1_ENUMERATED 121 +#define X509V3_F_I2S_ASN1_IA5STRING 149 +#define X509V3_F_I2S_ASN1_INTEGER 120 +#define X509V3_F_I2V_AUTHORITY_INFO_ACCESS 138 +#define X509V3_F_NOTICE_SECTION 132 +#define X509V3_F_NREF_NOS 133 +#define X509V3_F_POLICY_SECTION 131 +#define X509V3_F_PROCESS_PCI_VALUE 150 +#define X509V3_F_R2I_CERTPOL 130 +#define X509V3_F_R2I_PCI 155 +#define X509V3_F_S2I_ASN1_IA5STRING 100 +#define X509V3_F_S2I_ASN1_INTEGER 108 +#define X509V3_F_S2I_ASN1_OCTET_STRING 112 +#define X509V3_F_S2I_ASN1_SKEY_ID 114 +#define X509V3_F_S2I_SKEY_ID 115 +#define X509V3_F_SET_DIST_POINT_NAME 158 +#define X509V3_F_STRING_TO_HEX 113 +#define X509V3_F_SXNET_ADD_ID_ASC 125 +#define X509V3_F_SXNET_ADD_ID_INTEGER 126 +#define X509V3_F_SXNET_ADD_ID_ULONG 127 +#define X509V3_F_SXNET_GET_ID_ASC 128 +#define X509V3_F_SXNET_GET_ID_ULONG 129 +#define X509V3_F_V2I_ASIDENTIFIERS 163 +#define X509V3_F_V2I_ASN1_BIT_STRING 101 +#define X509V3_F_V2I_AUTHORITY_INFO_ACCESS 139 +#define X509V3_F_V2I_AUTHORITY_KEYID 119 +#define X509V3_F_V2I_BASIC_CONSTRAINTS 102 +#define X509V3_F_V2I_CRLD 134 +#define X509V3_F_V2I_EXTENDED_KEY_USAGE 103 +#define X509V3_F_V2I_GENERAL_NAMES 118 +#define X509V3_F_V2I_GENERAL_NAME_EX 117 +#define X509V3_F_V2I_IDP 157 +#define X509V3_F_V2I_IPADDRBLOCKS 159 +#define X509V3_F_V2I_ISSUER_ALT 153 +#define X509V3_F_V2I_NAME_CONSTRAINTS 147 +#define X509V3_F_V2I_POLICY_CONSTRAINTS 146 +#define X509V3_F_V2I_POLICY_MAPPINGS 145 +#define X509V3_F_V2I_SUBJECT_ALT 154 +#define X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL 160 +#define X509V3_F_V3_GENERIC_EXTENSION 116 +#define X509V3_F_X509V3_ADD1_I2D 140 +#define X509V3_F_X509V3_ADD_VALUE 105 +#define X509V3_F_X509V3_EXT_ADD 104 +#define X509V3_F_X509V3_EXT_ADD_ALIAS 106 +#define X509V3_F_X509V3_EXT_CONF 107 +#define X509V3_F_X509V3_EXT_I2D 136 +#define X509V3_F_X509V3_EXT_NCONF 152 +#define X509V3_F_X509V3_GET_SECTION 142 +#define X509V3_F_X509V3_GET_STRING 143 +#define X509V3_F_X509V3_GET_VALUE_BOOL 110 +#define X509V3_F_X509V3_PARSE_LIST 109 +#define X509V3_F_X509_PURPOSE_ADD 137 +#define X509V3_F_X509_PURPOSE_SET 141 + +/* Reason codes. */ +#define X509V3_R_BAD_IP_ADDRESS 118 +#define X509V3_R_BAD_OBJECT 119 +#define X509V3_R_BN_DEC2BN_ERROR 100 +#define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 101 +#define X509V3_R_DIRNAME_ERROR 149 +#define X509V3_R_DISTPOINT_ALREADY_SET 160 +#define X509V3_R_DUPLICATE_ZONE_ID 133 +#define X509V3_R_ERROR_CONVERTING_ZONE 131 +#define X509V3_R_ERROR_CREATING_EXTENSION 144 +#define X509V3_R_ERROR_IN_EXTENSION 128 +#define X509V3_R_EXPECTED_A_SECTION_NAME 137 +#define X509V3_R_EXTENSION_EXISTS 145 +#define X509V3_R_EXTENSION_NAME_ERROR 115 +#define X509V3_R_EXTENSION_NOT_FOUND 102 +#define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 103 +#define X509V3_R_EXTENSION_VALUE_ERROR 116 +#define X509V3_R_ILLEGAL_EMPTY_EXTENSION 151 +#define X509V3_R_ILLEGAL_HEX_DIGIT 113 +#define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 152 +#define X509V3_R_INVALID_MULTIPLE_RDNS 161 +#define X509V3_R_INVALID_ASNUMBER 162 +#define X509V3_R_INVALID_ASRANGE 163 +#define X509V3_R_INVALID_BOOLEAN_STRING 104 +#define X509V3_R_INVALID_EXTENSION_STRING 105 +#define X509V3_R_INVALID_INHERITANCE 165 +#define X509V3_R_INVALID_IPADDRESS 166 +#define X509V3_R_INVALID_NAME 106 +#define X509V3_R_INVALID_NULL_ARGUMENT 107 +#define X509V3_R_INVALID_NULL_NAME 108 +#define X509V3_R_INVALID_NULL_VALUE 109 +#define X509V3_R_INVALID_NUMBER 140 +#define X509V3_R_INVALID_NUMBERS 141 +#define X509V3_R_INVALID_OBJECT_IDENTIFIER 110 +#define X509V3_R_INVALID_OPTION 138 +#define X509V3_R_INVALID_POLICY_IDENTIFIER 134 +#define X509V3_R_INVALID_PROXY_POLICY_SETTING 153 +#define X509V3_R_INVALID_PURPOSE 146 +#define X509V3_R_INVALID_SAFI 164 +#define X509V3_R_INVALID_SECTION 135 +#define X509V3_R_INVALID_SYNTAX 143 +#define X509V3_R_ISSUER_DECODE_ERROR 126 +#define X509V3_R_MISSING_VALUE 124 +#define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS 142 +#define X509V3_R_NO_CONFIG_DATABASE 136 +#define X509V3_R_NO_ISSUER_CERTIFICATE 121 +#define X509V3_R_NO_ISSUER_DETAILS 127 +#define X509V3_R_NO_POLICY_IDENTIFIER 139 +#define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED 154 +#define X509V3_R_NO_PUBLIC_KEY 114 +#define X509V3_R_NO_SUBJECT_DETAILS 125 +#define X509V3_R_ODD_NUMBER_OF_DIGITS 112 +#define X509V3_R_OPERATION_NOT_DEFINED 148 +#define X509V3_R_OTHERNAME_ERROR 147 +#define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED 155 +#define X509V3_R_POLICY_PATH_LENGTH 156 +#define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED 157 +#define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED 158 +#define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159 +#define X509V3_R_SECTION_NOT_FOUND 150 +#define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS 122 +#define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID 123 +#define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 111 +#define X509V3_R_UNKNOWN_EXTENSION 129 +#define X509V3_R_UNKNOWN_EXTENSION_NAME 130 +#define X509V3_R_UNKNOWN_OPTION 120 +#define X509V3_R_UNSUPPORTED_OPTION 117 +#define X509V3_R_UNSUPPORTED_TYPE 167 +#define X509V3_R_USER_TOO_LONG 132 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/libressl/include/pqueue.h b/crypto/libressl/include/pqueue.h new file mode 100644 index 0000000000..5cf357a77b --- /dev/null +++ b/crypto/libressl/include/pqueue.h @@ -0,0 +1,89 @@ +/* $OpenBSD$ */ + +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_PQUEUE_H +#define HEADER_PQUEUE_H + +typedef struct _pqueue *pqueue; + +typedef struct _pitem { + unsigned char priority[8]; /* 64-bit value in big-endian encoding */ + void *data; + struct _pitem *next; +} pitem; + +typedef struct _pitem *piterator; + +pitem *pitem_new(unsigned char *prio64be, void *data); +void pitem_free(pitem *item); + +pqueue pqueue_new(void); +void pqueue_free(pqueue pq); + +pitem *pqueue_insert(pqueue pq, pitem *item); +pitem *pqueue_peek(pqueue pq); +pitem *pqueue_pop(pqueue pq); +pitem *pqueue_find(pqueue pq, unsigned char *prio64be); +pitem *pqueue_iterator(pqueue pq); +pitem *pqueue_next(piterator *iter); + +int pqueue_size(pqueue pq); + +#endif /* ! HEADER_PQUEUE_H */ diff --git a/crypto/libressl/include/tls.h b/crypto/libressl/include/tls.h new file mode 100644 index 0000000000..3e75eb7afe --- /dev/null +++ b/crypto/libressl/include/tls.h @@ -0,0 +1,128 @@ +/* $OpenBSD: tls.h,v 1.28 2016/04/28 17:05:59 jsing Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * 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 HEADER_TLS_H +#define HEADER_TLS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include + +#define TLS_API 20141031 + +#define TLS_PROTOCOL_TLSv1_0 (1 << 1) +#define TLS_PROTOCOL_TLSv1_1 (1 << 2) +#define TLS_PROTOCOL_TLSv1_2 (1 << 3) +#define TLS_PROTOCOL_TLSv1 \ + (TLS_PROTOCOL_TLSv1_0|TLS_PROTOCOL_TLSv1_1|TLS_PROTOCOL_TLSv1_2) + +#define TLS_PROTOCOLS_ALL TLS_PROTOCOL_TLSv1 +#define TLS_PROTOCOLS_DEFAULT TLS_PROTOCOL_TLSv1_2 + +#define TLS_WANT_POLLIN -2 +#define TLS_WANT_POLLOUT -3 + +struct tls; +struct tls_config; + +int tls_init(void); + +const char *tls_config_error(struct tls_config *_config); +const char *tls_error(struct tls *_ctx); + +struct tls_config *tls_config_new(void); +void tls_config_free(struct tls_config *_config); + +int tls_config_set_ca_file(struct tls_config *_config, const char *_ca_file); +int tls_config_set_ca_path(struct tls_config *_config, const char *_ca_path); +int tls_config_set_ca_mem(struct tls_config *_config, const uint8_t *_ca, + size_t _len); +int tls_config_set_cert_file(struct tls_config *_config, + const char *_cert_file); +int tls_config_set_cert_mem(struct tls_config *_config, const uint8_t *_cert, + size_t _len); +int tls_config_set_ciphers(struct tls_config *_config, const char *_ciphers); +int tls_config_set_dheparams(struct tls_config *_config, const char *_params); +int tls_config_set_ecdhecurve(struct tls_config *_config, const char *_name); +int tls_config_set_key_file(struct tls_config *_config, const char *_key_file); +int tls_config_set_key_mem(struct tls_config *_config, const uint8_t *_key, + size_t _len); +int tls_config_set_keypair_file(struct tls_config *_config, + const char *_cert_file, const char *_key_file); +int tls_config_set_keypair_mem(struct tls_config *_config, const uint8_t *_cert, + size_t _cert_len, const uint8_t *_key, size_t _key_len); +void tls_config_set_protocols(struct tls_config *_config, uint32_t _protocols); +void tls_config_set_verify_depth(struct tls_config *_config, int _verify_depth); + +void tls_config_prefer_ciphers_client(struct tls_config *_config); +void tls_config_prefer_ciphers_server(struct tls_config *_config); + +void tls_config_insecure_noverifycert(struct tls_config *_config); +void tls_config_insecure_noverifyname(struct tls_config *_config); +void tls_config_insecure_noverifytime(struct tls_config *_config); +void tls_config_verify(struct tls_config *_config); + +void tls_config_verify_client(struct tls_config *_config); +void tls_config_verify_client_optional(struct tls_config *_config); + +void tls_config_clear_keys(struct tls_config *_config); +int tls_config_parse_protocols(uint32_t *_protocols, const char *_protostr); + +struct tls *tls_client(void); +struct tls *tls_server(void); +int tls_configure(struct tls *_ctx, struct tls_config *_config); +void tls_reset(struct tls *_ctx); +void tls_free(struct tls *_ctx); + +int tls_accept_fds(struct tls *_ctx, struct tls **_cctx, int _fd_read, + int _fd_write); +int tls_accept_socket(struct tls *_ctx, struct tls **_cctx, int _socket); +int tls_connect(struct tls *_ctx, const char *_host, const char *_port); +int tls_connect_fds(struct tls *_ctx, int _fd_read, int _fd_write, + const char *_servername); +int tls_connect_servername(struct tls *_ctx, const char *_host, + const char *_port, const char *_servername); +int tls_connect_socket(struct tls *_ctx, int _s, const char *_servername); +int tls_handshake(struct tls *_ctx); +ssize_t tls_read(struct tls *_ctx, void *_buf, size_t _buflen); +ssize_t tls_write(struct tls *_ctx, const void *_buf, size_t _buflen); +int tls_close(struct tls *_ctx); + +int tls_peer_cert_provided(struct tls *_ctx); +int tls_peer_cert_contains_name(struct tls *_ctx, const char *_name); + +const char *tls_peer_cert_hash(struct tls *_ctx); +const char *tls_peer_cert_issuer(struct tls *_ctx); +const char *tls_peer_cert_subject(struct tls *_ctx); +time_t tls_peer_cert_notbefore(struct tls *_ctx); +time_t tls_peer_cert_notafter(struct tls *_ctx); + +const char *tls_conn_version(struct tls *_ctx); +const char *tls_conn_cipher(struct tls *_ctx); + +uint8_t *tls_load_file(const char *_file, size_t *_len, char *_password); + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_TLS_H */ diff --git a/crypto/libressl/ssl/VERSION b/crypto/libressl/ssl/VERSION new file mode 100644 index 0000000000..1d8514cdbf --- /dev/null +++ b/crypto/libressl/ssl/VERSION @@ -0,0 +1 @@ +39:0:0 diff --git a/crypto/libressl/ssl/bio_ssl.c b/crypto/libressl/ssl/bio_ssl.c new file mode 100644 index 0000000000..30767a2891 --- /dev/null +++ b/crypto/libressl/ssl/bio_ssl.c @@ -0,0 +1,581 @@ +/* $OpenBSD: bio_ssl.c,v 1.21 2014/11/16 14:12:47 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +static int ssl_write(BIO *h, const char *buf, int num); +static int ssl_read(BIO *h, char *buf, int size); +static int ssl_puts(BIO *h, const char *str); +static long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int ssl_new(BIO *h); +static int ssl_free(BIO *data); +static long ssl_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); +typedef struct bio_ssl_st { + SSL *ssl; /* The ssl handle :-) */ + /* re-negotiate every time the total number of bytes is this size */ + int num_renegotiates; + unsigned long renegotiate_count; + unsigned long byte_count; + unsigned long renegotiate_timeout; + time_t last_time; +} BIO_SSL; + +static BIO_METHOD methods_sslp = { + .type = BIO_TYPE_SSL, + .name = "ssl", + .bwrite = ssl_write, + .bread = ssl_read, + .bputs = ssl_puts, + .ctrl = ssl_ctrl, + .create = ssl_new, + .destroy = ssl_free, + .callback_ctrl = ssl_callback_ctrl, +}; + +BIO_METHOD * +BIO_f_ssl(void) +{ + return (&methods_sslp); +} + +static int +ssl_new(BIO *bi) +{ + BIO_SSL *bs; + + bs = calloc(1, sizeof(BIO_SSL)); + if (bs == NULL) { + BIOerr(BIO_F_SSL_NEW, ERR_R_MALLOC_FAILURE); + return (0); + } + bi->init = 0; + bi->ptr = (char *)bs; + bi->flags = 0; + return (1); +} + +static int +ssl_free(BIO *a) +{ + BIO_SSL *bs; + + if (a == NULL) + return (0); + bs = (BIO_SSL *)a->ptr; + if (bs->ssl != NULL) + SSL_shutdown(bs->ssl); + if (a->shutdown) { + if (a->init && (bs->ssl != NULL)) + SSL_free(bs->ssl); + a->init = 0; + a->flags = 0; + } + free(a->ptr); + return (1); +} + +static int +ssl_read(BIO *b, char *out, int outl) +{ + int ret = 1; + BIO_SSL *sb; + SSL *ssl; + int retry_reason = 0; + int r = 0; + + if (out == NULL) + return (0); + sb = (BIO_SSL *)b->ptr; + ssl = sb->ssl; + + BIO_clear_retry_flags(b); + + ret = SSL_read(ssl, out, outl); + + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_NONE: + if (ret <= 0) + break; + if (sb->renegotiate_count > 0) { + sb->byte_count += ret; + if (sb->byte_count > sb->renegotiate_count) { + sb->byte_count = 0; + sb->num_renegotiates++; + SSL_renegotiate(ssl); + r = 1; + } + } + if ((sb->renegotiate_timeout > 0) && (!r)) { + time_t tm; + + tm = time(NULL); + if (tm > sb->last_time + sb->renegotiate_timeout) { + sb->last_time = tm; + sb->num_renegotiates++; + SSL_renegotiate(ssl); + } + } + + break; + case SSL_ERROR_WANT_READ: + BIO_set_retry_read(b); + break; + case SSL_ERROR_WANT_WRITE: + BIO_set_retry_write(b); + break; + case SSL_ERROR_WANT_X509_LOOKUP: + BIO_set_retry_special(b); + retry_reason = BIO_RR_SSL_X509_LOOKUP; + break; + case SSL_ERROR_WANT_ACCEPT: + BIO_set_retry_special(b); + retry_reason = BIO_RR_ACCEPT; + break; + case SSL_ERROR_WANT_CONNECT: + BIO_set_retry_special(b); + retry_reason = BIO_RR_CONNECT; + break; + case SSL_ERROR_SYSCALL: + case SSL_ERROR_SSL: + case SSL_ERROR_ZERO_RETURN: + default: + break; + } + + b->retry_reason = retry_reason; + return (ret); +} + +static int +ssl_write(BIO *b, const char *out, int outl) +{ + int ret, r = 0; + int retry_reason = 0; + SSL *ssl; + BIO_SSL *bs; + + if (out == NULL) + return (0); + bs = (BIO_SSL *)b->ptr; + ssl = bs->ssl; + + BIO_clear_retry_flags(b); + +/* ret=SSL_do_handshake(ssl); + if (ret > 0) */ + ret = SSL_write(ssl, out, outl); + + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_NONE: + if (ret <= 0) + break; + if (bs->renegotiate_count > 0) { + bs->byte_count += ret; + if (bs->byte_count > bs->renegotiate_count) { + bs->byte_count = 0; + bs->num_renegotiates++; + SSL_renegotiate(ssl); + r = 1; + } + } + if ((bs->renegotiate_timeout > 0) && (!r)) { + time_t tm; + + tm = time(NULL); + if (tm > bs->last_time + bs->renegotiate_timeout) { + bs->last_time = tm; + bs->num_renegotiates++; + SSL_renegotiate(ssl); + } + } + break; + case SSL_ERROR_WANT_WRITE: + BIO_set_retry_write(b); + break; + case SSL_ERROR_WANT_READ: + BIO_set_retry_read(b); + break; + case SSL_ERROR_WANT_X509_LOOKUP: + BIO_set_retry_special(b); + retry_reason = BIO_RR_SSL_X509_LOOKUP; + break; + case SSL_ERROR_WANT_CONNECT: + BIO_set_retry_special(b); + retry_reason = BIO_RR_CONNECT; + case SSL_ERROR_SYSCALL: + case SSL_ERROR_SSL: + default: + break; + } + + b->retry_reason = retry_reason; + return (ret); +} + +static long +ssl_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + SSL **sslp, *ssl; + BIO_SSL *bs; + BIO *dbio, *bio; + long ret = 1; + + bs = (BIO_SSL *)b->ptr; + ssl = bs->ssl; + if ((ssl == NULL) && (cmd != BIO_C_SET_SSL)) + return (0); + switch (cmd) { + case BIO_CTRL_RESET: + SSL_shutdown(ssl); + + if (ssl->handshake_func == ssl->method->ssl_connect) + SSL_set_connect_state(ssl); + else if (ssl->handshake_func == ssl->method->ssl_accept) + SSL_set_accept_state(ssl); + + SSL_clear(ssl); + + if (b->next_bio != NULL) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + else if (ssl->rbio != NULL) + ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); + else + ret = 1; + break; + case BIO_CTRL_INFO: + ret = 0; + break; + case BIO_C_SSL_MODE: + if (num) /* client mode */ + SSL_set_connect_state(ssl); + else + SSL_set_accept_state(ssl); + break; + case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT: + ret = bs->renegotiate_timeout; + if (num < 60) + num = 5; + bs->renegotiate_timeout = (unsigned long)num; + bs->last_time = time(NULL); + break; + case BIO_C_SET_SSL_RENEGOTIATE_BYTES: + ret = bs->renegotiate_count; + if ((long)num >=512) + bs->renegotiate_count = (unsigned long)num; + break; + case BIO_C_GET_SSL_NUM_RENEGOTIATES: + ret = bs->num_renegotiates; + break; + case BIO_C_SET_SSL: + if (ssl != NULL) { + ssl_free(b); + if (!ssl_new(b)) + return 0; + } + b->shutdown = (int)num; + ssl = (SSL *)ptr; + ((BIO_SSL *)b->ptr)->ssl = ssl; + bio = SSL_get_rbio(ssl); + if (bio != NULL) { + if (b->next_bio != NULL) + BIO_push(bio, b->next_bio); + b->next_bio = bio; + CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO); + } + b->init = 1; + break; + case BIO_C_GET_SSL: + if (ptr != NULL) { + sslp = (SSL **)ptr; + *sslp = ssl; + } else + ret = 0; + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_WPENDING: + ret = BIO_ctrl(ssl->wbio, cmd, num, ptr); + break; + case BIO_CTRL_PENDING: + ret = SSL_pending(ssl); + if (ret == 0) + ret = BIO_pending(ssl->rbio); + break; + case BIO_CTRL_FLUSH: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(ssl->wbio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + case BIO_CTRL_PUSH: + if ((b->next_bio != NULL) && (b->next_bio != ssl->rbio)) { + SSL_set_bio(ssl, b->next_bio, b->next_bio); + CRYPTO_add(&b->next_bio->references, 1, CRYPTO_LOCK_BIO); + } + break; + case BIO_CTRL_POP: + /* Only detach if we are the BIO explicitly being popped */ + if (b == ptr) { + /* Shouldn't happen in practice because the + * rbio and wbio are the same when pushed. + */ + if (ssl->rbio != ssl->wbio) + BIO_free_all(ssl->wbio); + if (b->next_bio != NULL) + CRYPTO_add(&b->next_bio->references, -1, CRYPTO_LOCK_BIO); + ssl->wbio = NULL; + ssl->rbio = NULL; + } + break; + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + + b->retry_reason = 0; + ret = (int)SSL_do_handshake(ssl); + + switch (SSL_get_error(ssl, (int)ret)) { + case SSL_ERROR_WANT_READ: + BIO_set_flags(b, + BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY); + break; + case SSL_ERROR_WANT_WRITE: + BIO_set_flags(b, + BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY); + break; + case SSL_ERROR_WANT_CONNECT: + BIO_set_flags(b, + BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY); + b->retry_reason = b->next_bio->retry_reason; + break; + default: + break; + } + break; + case BIO_CTRL_DUP: + dbio = (BIO *)ptr; + if (((BIO_SSL *)dbio->ptr)->ssl != NULL) + SSL_free(((BIO_SSL *)dbio->ptr)->ssl); + ((BIO_SSL *)dbio->ptr)->ssl = SSL_dup(ssl); + ((BIO_SSL *)dbio->ptr)->renegotiate_count = + ((BIO_SSL *)b->ptr)->renegotiate_count; + ((BIO_SSL *)dbio->ptr)->byte_count = + ((BIO_SSL *)b->ptr)->byte_count; + ((BIO_SSL *)dbio->ptr)->renegotiate_timeout = + ((BIO_SSL *)b->ptr)->renegotiate_timeout; + ((BIO_SSL *)dbio->ptr)->last_time = + ((BIO_SSL *)b->ptr)->last_time; + ret = (((BIO_SSL *)dbio->ptr)->ssl != NULL); + break; + case BIO_C_GET_FD: + ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); + break; + case BIO_CTRL_SET_CALLBACK: + { + ret = 0; + } + break; + case BIO_CTRL_GET_CALLBACK: + { + void (**fptr)(const SSL *xssl, int type, int val); + + fptr = (void (**)(const SSL *xssl, int type, int val))ptr; + *fptr = SSL_get_info_callback(ssl); + } + break; + default: + ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); + break; + } + return (ret); +} + +static long +ssl_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + SSL *ssl; + BIO_SSL *bs; + long ret = 1; + + bs = (BIO_SSL *)b->ptr; + ssl = bs->ssl; + switch (cmd) { + case BIO_CTRL_SET_CALLBACK: + { + /* FIXME: setting this via a completely different prototype + seems like a crap idea */ + SSL_set_info_callback(ssl, (void (*)(const SSL *, int, int))fp); + } + break; + default: + ret = BIO_callback_ctrl(ssl->rbio, cmd, fp); + break; + } + return (ret); +} + +static int +ssl_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = BIO_write(bp, str, n); + return (ret); +} + +BIO * +BIO_new_buffer_ssl_connect(SSL_CTX *ctx) +{ + BIO *ret = NULL, *buf = NULL, *ssl = NULL; + + if ((buf = BIO_new(BIO_f_buffer())) == NULL) + goto err; + if ((ssl = BIO_new_ssl_connect(ctx)) == NULL) + goto err; + if ((ret = BIO_push(buf, ssl)) == NULL) + goto err; + return (ret); + +err: + BIO_free(buf); + BIO_free(ssl); + return (NULL); +} + +BIO * +BIO_new_ssl_connect(SSL_CTX *ctx) +{ + BIO *ret = NULL, *con = NULL, *ssl = NULL; + + if ((con = BIO_new(BIO_s_connect())) == NULL) + goto err; + if ((ssl = BIO_new_ssl(ctx, 1)) == NULL) + goto err; + if ((ret = BIO_push(ssl, con)) == NULL) + goto err; + return (ret); + +err: + BIO_free(con); + BIO_free(ssl); + return (NULL); +} + +BIO * +BIO_new_ssl(SSL_CTX *ctx, int client) +{ + BIO *ret; + SSL *ssl; + + if ((ret = BIO_new(BIO_f_ssl())) == NULL) + goto err; + if ((ssl = SSL_new(ctx)) == NULL) + goto err; + + if (client) + SSL_set_connect_state(ssl); + else + SSL_set_accept_state(ssl); + + BIO_set_ssl(ret, ssl, BIO_CLOSE); + return (ret); + +err: + BIO_free(ret); + return (NULL); +} + +int +BIO_ssl_copy_session_id(BIO *t, BIO *f) +{ + t = BIO_find_type(t, BIO_TYPE_SSL); + f = BIO_find_type(f, BIO_TYPE_SSL); + if ((t == NULL) || (f == NULL)) + return (0); + if ((((BIO_SSL *)t->ptr)->ssl == NULL) || + (((BIO_SSL *)f->ptr)->ssl == NULL)) + return (0); + SSL_copy_session_id(((BIO_SSL *)t->ptr)->ssl, ((BIO_SSL *)f->ptr)->ssl); + return (1); +} + +void +BIO_ssl_shutdown(BIO *b) +{ + SSL *s; + + while (b != NULL) { + if (b->method->type == BIO_TYPE_SSL) { + s = ((BIO_SSL *)b->ptr)->ssl; + SSL_shutdown(s); + break; + } + b = b->next_bio; + } +} diff --git a/crypto/libressl/ssl/bs_ber.c b/crypto/libressl/ssl/bs_ber.c new file mode 100644 index 0000000000..2a8f934116 --- /dev/null +++ b/crypto/libressl/ssl/bs_ber.c @@ -0,0 +1,268 @@ +/* $OpenBSD: bs_ber.c,v 1.7 2015/06/17 07:20:39 doug Exp $ */ +/* + * Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or 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 + +#include + +#include "bytestring.h" + +/* + * kMaxDepth is a just a sanity limit. The code should be such that the length + * of the input being processes always decreases. None the less, a very large + * input could otherwise cause the stack to overflow. + */ +static const unsigned int kMaxDepth = 2048; + +/* Non-strict version that allows a relaxed DER with indefinite form. */ +static int +cbs_nonstrict_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag, + size_t *out_header_len) +{ + return cbs_get_any_asn1_element_internal(cbs, out, + out_tag, out_header_len, 0); +} + +/* + * cbs_find_indefinite walks an ASN.1 structure in |orig_in| and sets + * |*indefinite_found| depending on whether an indefinite length element was + * found. The value of |orig_in| is not modified. + * + * Returns one on success (i.e. |*indefinite_found| was set) and zero on error. + */ +static int +cbs_find_indefinite(const CBS *orig_in, char *indefinite_found, + unsigned int depth) +{ + CBS in; + + if (depth > kMaxDepth) + return 0; + + CBS_init(&in, CBS_data(orig_in), CBS_len(orig_in)); + + while (CBS_len(&in) > 0) { + CBS contents; + unsigned int tag; + size_t header_len; + + if (!cbs_nonstrict_get_any_asn1_element(&in, &contents, &tag, + &header_len)) + return 0; + + /* Indefinite form not allowed by DER. */ + if (CBS_len(&contents) == header_len && header_len > 0 && + CBS_data(&contents)[header_len - 1] == 0x80) { + *indefinite_found = 1; + return 1; + } + if (tag & CBS_ASN1_CONSTRUCTED) { + if (!CBS_skip(&contents, header_len) || + !cbs_find_indefinite(&contents, indefinite_found, + depth + 1)) + return 0; + } + } + + *indefinite_found = 0; + return 1; +} + +/* + * is_primitive_type returns true if |tag| likely a primitive type. Normally + * one can just test the "constructed" bit in the tag but, in BER, even + * primitive tags can have the constructed bit if they have indefinite + * length. + */ +static char +is_primitive_type(unsigned int tag) +{ + return (tag & 0xc0) == 0 && + (tag & 0x1f) != (CBS_ASN1_SEQUENCE & 0x1f) && + (tag & 0x1f) != (CBS_ASN1_SET & 0x1f); +} + +/* + * is_eoc returns true if |header_len| and |contents|, as returned by + * |cbs_nonstrict_get_any_asn1_element|, indicate an "end of contents" (EOC) + * value. + */ +static char +is_eoc(size_t header_len, CBS *contents) +{ + return header_len == 2 && CBS_mem_equal(contents, "\x00\x00", 2); +} + +/* + * cbs_convert_indefinite reads data with DER encoding (but relaxed to allow + * indefinite form) from |in| and writes definite form DER data to |out|. If + * |squash_header| is set then the top-level of elements from |in| will not + * have their headers written. This is used when concatenating the fragments of + * an indefinite length, primitive value. If |looking_for_eoc| is set then any + * EOC elements found will cause the function to return after consuming it. + * It returns one on success and zero on error. + */ +static int +cbs_convert_indefinite(CBS *in, CBB *out, char squash_header, + char looking_for_eoc, unsigned int depth) +{ + if (depth > kMaxDepth) + return 0; + + while (CBS_len(in) > 0) { + CBS contents; + unsigned int tag; + size_t header_len; + CBB *out_contents, out_contents_storage; + + if (!cbs_nonstrict_get_any_asn1_element(in, &contents, &tag, + &header_len)) + return 0; + + out_contents = out; + + if (CBS_len(&contents) == header_len) { + if (is_eoc(header_len, &contents)) + return looking_for_eoc; + + if (header_len > 0 && + CBS_data(&contents)[header_len - 1] == 0x80) { + /* + * This is an indefinite length element. If + * it's a SEQUENCE or SET then we just need to + * write the out the contents as normal, but + * with a concrete length prefix. + * + * If it's a something else then the contents + * will be a series of DER elements of the same + * type which need to be concatenated. + */ + const char context_specific = (tag & 0xc0) + == 0x80; + char squash_child_headers = + is_primitive_type(tag); + + /* + * This is a hack, but it sufficies to handle + * NSS's output. If we find an indefinite + * length, context-specific tag with a definite, + * primtive tag inside it, then we assume that + * the context-specific tag is implicit and the + * tags within are fragments of a primitive type + * that need to be concatenated. + */ + if (context_specific && + (tag & CBS_ASN1_CONSTRUCTED)) { + CBS in_copy, inner_contents; + unsigned int inner_tag; + size_t inner_header_len; + + CBS_init(&in_copy, CBS_data(in), + CBS_len(in)); + if (!cbs_nonstrict_get_any_asn1_element( + &in_copy, &inner_contents, + &inner_tag, &inner_header_len)) + return 0; + + if (CBS_len(&inner_contents) > + inner_header_len && + is_primitive_type(inner_tag)) + squash_child_headers = 1; + } + + if (!squash_header) { + unsigned int out_tag = tag; + + if (squash_child_headers) + out_tag &= + ~CBS_ASN1_CONSTRUCTED; + + if (!CBB_add_asn1(out, + &out_contents_storage, out_tag)) + return 0; + + out_contents = &out_contents_storage; + } + + if (!cbs_convert_indefinite(in, out_contents, + squash_child_headers, + 1 /* looking for eoc */, depth + 1)) + return 0; + + if (out_contents != out && !CBB_flush(out)) + return 0; + + continue; + } + } + + if (!squash_header) { + if (!CBB_add_asn1(out, &out_contents_storage, tag)) + return 0; + + out_contents = &out_contents_storage; + } + + if (!CBS_skip(&contents, header_len)) + return 0; + + if (tag & CBS_ASN1_CONSTRUCTED) { + if (!cbs_convert_indefinite(&contents, out_contents, + 0 /* don't squash header */, + 0 /* not looking for eoc */, depth + 1)) + return 0; + } else { + if (!CBB_add_bytes(out_contents, CBS_data(&contents), + CBS_len(&contents))) + return 0; + } + + if (out_contents != out && !CBB_flush(out)) + return 0; + } + + return looking_for_eoc == 0; +} + +int +CBS_asn1_indefinite_to_definite(CBS *in, uint8_t **out, size_t *out_len) +{ + CBB cbb; + + /* + * First, do a quick walk to find any indefinite-length elements. Most + * of the time we hope that there aren't any and thus we can quickly + * return. + */ + char conversion_needed; + if (!cbs_find_indefinite(in, &conversion_needed, 0)) + return 0; + + if (!conversion_needed) { + *out = NULL; + *out_len = 0; + return 1; + } + + if (!CBB_init(&cbb, CBS_len(in))) + return 0; + if (!cbs_convert_indefinite(in, &cbb, 0, 0, 0)) { + CBB_cleanup(&cbb); + return 0; + } + + return CBB_finish(&cbb, out, out_len); +} diff --git a/crypto/libressl/ssl/bs_cbb.c b/crypto/libressl/ssl/bs_cbb.c new file mode 100644 index 0000000000..bfb59e67af --- /dev/null +++ b/crypto/libressl/ssl/bs_cbb.c @@ -0,0 +1,442 @@ +/* $OpenBSD: bs_cbb.c,v 1.12 2015/06/18 23:25:07 doug Exp $ */ +/* + * Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or 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 +#include +#include + +#include + +#include "bytestring.h" + +static int +cbb_init(CBB *cbb, uint8_t *buf, size_t cap) +{ + struct cbb_buffer_st *base; + + base = malloc(sizeof(struct cbb_buffer_st)); + if (base == NULL) + return 0; + + base->buf = buf; + base->len = 0; + base->cap = cap; + base->can_resize = 1; + + cbb->base = base; + cbb->is_top_level = 1; + + return 1; +} + +int +CBB_init(CBB *cbb, size_t initial_capacity) +{ + uint8_t *buf = NULL; + + memset(cbb, 0, sizeof(*cbb)); + + if (initial_capacity > 0) { + if ((buf = malloc(initial_capacity)) == NULL) + return 0; + } + + if (!cbb_init(cbb, buf, initial_capacity)) { + free(buf); + return 0; + } + + return 1; +} + +int +CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) +{ + memset(cbb, 0, sizeof(*cbb)); + + if (!cbb_init(cbb, buf, len)) + return 0; + + cbb->base->can_resize = 0; + + return 1; +} + +void +CBB_cleanup(CBB *cbb) +{ + if (cbb->base) { + if (cbb->base->can_resize) + free(cbb->base->buf); + + free(cbb->base); + } + cbb->base = NULL; +} + +static int +cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, size_t len) +{ + size_t newlen; + + if (base == NULL) + return 0; + + newlen = base->len + len; + if (newlen < base->len) + /* Overflow */ + return 0; + + if (newlen > base->cap) { + size_t newcap = base->cap * 2; + uint8_t *newbuf; + + if (!base->can_resize) + return 0; + + if (newcap < base->cap || newcap < newlen) + newcap = newlen; + + newbuf = realloc(base->buf, newcap); + if (newbuf == NULL) + return 0; + + base->buf = newbuf; + base->cap = newcap; + } + + if (out) + *out = base->buf + base->len; + + base->len = newlen; + return 1; +} + +static int +cbb_add_u(CBB *cbb, uint32_t v, size_t len_len) +{ + uint8_t *buf; + size_t i; + + if (len_len == 0) + return 1; + + if (len_len > 4) + return 0; + + if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, &buf, len_len)) + return 0; + + for (i = len_len - 1; i < len_len; i--) { + buf[i] = v; + v >>= 8; + } + return 1; +} + +int +CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) +{ + if (!cbb->is_top_level) + return 0; + + if (!CBB_flush(cbb)) + return 0; + + if (cbb->base->can_resize && (out_data == NULL || out_len == NULL)) + /* + * |out_data| and |out_len| can only be NULL if the CBB is + * fixed. + */ + return 0; + + if (out_data != NULL) + *out_data = cbb->base->buf; + + if (out_len != NULL) + *out_len = cbb->base->len; + + cbb->base->buf = NULL; + CBB_cleanup(cbb); + return 1; +} + +/* + * CBB_flush recurses and then writes out any pending length prefix. The current + * length of the underlying base is taken to be the length of the + * length-prefixed data. + */ +int +CBB_flush(CBB *cbb) +{ + size_t child_start, i, len; + + if (cbb->base == NULL) + return 0; + + if (cbb->child == NULL || cbb->pending_len_len == 0) + return 1; + + child_start = cbb->offset + cbb->pending_len_len; + + if (!CBB_flush(cbb->child) || child_start < cbb->offset || + cbb->base->len < child_start) + return 0; + + len = cbb->base->len - child_start; + + if (cbb->pending_is_asn1) { + /* + * For ASN.1, we assumed that we were using short form which + * only requires a single byte for the length octet. + * + * If it turns out that we need long form, we have to move + * the contents along in order to make space for more length + * octets. + */ + size_t len_len = 1; /* total number of length octets */ + uint8_t initial_length_byte; + + /* We already wrote 1 byte for the length. */ + assert (cbb->pending_len_len == 1); + + /* Check for long form */ + if (len > 0xfffffffe) + return 0; /* 0xffffffff is reserved */ + else if (len > 0xffffff) + len_len = 5; + else if (len > 0xffff) + len_len = 4; + else if (len > 0xff) + len_len = 3; + else if (len > 0x7f) + len_len = 2; + + if (len_len == 1) { + /* For short form, the initial byte is the length. */ + initial_length_byte = len; + len = 0; + + } else { + /* + * For long form, the initial byte is the number of + * subsequent length octets (plus bit 8 set). + */ + initial_length_byte = 0x80 | (len_len - 1); + + /* + * We need to move the contents along in order to make + * space for the long form length octets. + */ + size_t extra_bytes = len_len - 1; + if (!cbb_buffer_add(cbb->base, NULL, extra_bytes)) + return 0; + + memmove(cbb->base->buf + child_start + extra_bytes, + cbb->base->buf + child_start, len); + } + cbb->base->buf[cbb->offset++] = initial_length_byte; + cbb->pending_len_len = len_len - 1; + } + + for (i = cbb->pending_len_len - 1; i < cbb->pending_len_len; i--) { + cbb->base->buf[cbb->offset + i] = len; + len >>= 8; + } + if (len != 0) + return 0; + + cbb->child->base = NULL; + cbb->child = NULL; + cbb->pending_len_len = 0; + cbb->pending_is_asn1 = 0; + cbb->offset = 0; + + return 1; +} + + +static int +cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, size_t len_len) +{ + uint8_t *prefix_bytes; + + if (!CBB_flush(cbb)) + return 0; + + cbb->offset = cbb->base->len; + if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len)) + return 0; + + memset(prefix_bytes, 0, len_len); + memset(out_contents, 0, sizeof(CBB)); + out_contents->base = cbb->base; + cbb->child = out_contents; + cbb->pending_len_len = len_len; + cbb->pending_is_asn1 = 0; + + return 1; +} + +int +CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents) +{ + return cbb_add_length_prefixed(cbb, out_contents, 1); +} + +int +CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents) +{ + return cbb_add_length_prefixed(cbb, out_contents, 2); +} + +int +CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents) +{ + return cbb_add_length_prefixed(cbb, out_contents, 3); +} + +int +CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned int tag) +{ + if (tag > UINT8_MAX) + return 0; + + /* Long form identifier octets are not supported. */ + if ((tag & 0x1f) == 0x1f) + return 0; + + /* Short-form identifier octet only needs a single byte */ + if (!CBB_flush(cbb) || !CBB_add_u8(cbb, tag)) + return 0; + + /* + * Add 1 byte to cover the short-form length octet case. If it turns + * out we need long-form, it will be extended later. + */ + cbb->offset = cbb->base->len; + if (!CBB_add_u8(cbb, 0)) + return 0; + + memset(out_contents, 0, sizeof(CBB)); + out_contents->base = cbb->base; + cbb->child = out_contents; + cbb->pending_len_len = 1; + cbb->pending_is_asn1 = 1; + + return 1; +} + +int +CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len) +{ + uint8_t *dest; + + if (!CBB_add_space(cbb, &dest, len)) + return 0; + + memcpy(dest, data, len); + return 1; +} + +int +CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) +{ + if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, out_data, len)) + return 0; + + return 1; +} + +int +CBB_add_u8(CBB *cbb, size_t value) +{ + if (value > UINT8_MAX) + return 0; + + return cbb_add_u(cbb, (uint32_t)value, 1); +} + +int +CBB_add_u16(CBB *cbb, size_t value) +{ + if (value > UINT16_MAX) + return 0; + + return cbb_add_u(cbb, (uint32_t)value, 2); +} + +int +CBB_add_u24(CBB *cbb, size_t value) +{ + if (value > 0xffffffUL) + return 0; + + return cbb_add_u(cbb, (uint32_t)value, 3); +} + +int +CBB_add_asn1_uint64(CBB *cbb, uint64_t value) +{ + CBB child; + size_t i; + int started = 0; + + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) + return 0; + + for (i = 0; i < 8; i++) { + uint8_t byte = (value >> 8 * (7 - i)) & 0xff; + + /* + * ASN.1 restriction: first 9 bits cannot be all zeroes or + * all ones. Since this function only encodes unsigned + * integers, the only concerns are not encoding leading + * zeros and adding a padding byte if necessary. + * + * In practice, this means: + * 1) Skip leading octets of all zero bits in the value + * 2) After skipping the leading zero octets, if the next 9 + * bits are all ones, add an all zero prefix octet (and + * set the high bit of the prefix octet if negative). + * + * Additionally, for an unsigned value, add an all zero + * prefix if the high bit of the first octet would be one. + */ + if (!started) { + if (byte == 0) + /* Don't encode leading zeros. */ + continue; + + /* + * If the high bit is set, add a padding byte to make it + * unsigned. + */ + if ((byte & 0x80) && !CBB_add_u8(&child, 0)) + return 0; + + started = 1; + } + if (!CBB_add_u8(&child, byte)) + return 0; + } + + /* 0 is encoded as a single 0, not the empty string. */ + if (!started && !CBB_add_u8(&child, 0)) + return 0; + + return CBB_flush(cbb); +} diff --git a/crypto/libressl/ssl/bs_cbs.c b/crypto/libressl/ssl/bs_cbs.c new file mode 100644 index 0000000000..eee9083aa6 --- /dev/null +++ b/crypto/libressl/ssl/bs_cbs.c @@ -0,0 +1,511 @@ +/* $OpenBSD: bs_cbs.c,v 1.16 2015/06/23 05:58:28 doug Exp $ */ +/* + * Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or 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 +#include +#include + +#include +#include +#include + +#include "bytestring.h" + +void +CBS_init(CBS *cbs, const uint8_t *data, size_t len) +{ + cbs->data = data; + cbs->initial_len = len; + cbs->len = len; +} + +void +CBS_dup(const CBS *cbs, CBS *out) +{ + CBS_init(out, CBS_data(cbs), CBS_len(cbs)); + out->initial_len = cbs->initial_len; +} + +static int +cbs_get(CBS *cbs, const uint8_t **p, size_t n) +{ + if (cbs->len < n) + return 0; + + *p = cbs->data; + cbs->data += n; + cbs->len -= n; + return 1; +} + +size_t +CBS_offset(const CBS *cbs) +{ + return cbs->initial_len - cbs->len; +} + +int +CBS_skip(CBS *cbs, size_t len) +{ + const uint8_t *dummy; + return cbs_get(cbs, &dummy, len); +} + +const uint8_t * +CBS_data(const CBS *cbs) +{ + return cbs->data; +} + +size_t +CBS_len(const CBS *cbs) +{ + return cbs->len; +} + +int +CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len) +{ + free(*out_ptr); + *out_ptr = NULL; + *out_len = 0; + + if (cbs->len == 0) + return 1; + + if ((*out_ptr = malloc(cbs->len)) == NULL) + return 0; + + memcpy(*out_ptr, cbs->data, cbs->len); + + *out_len = cbs->len; + return 1; +} + +int +CBS_strdup(const CBS *cbs, char **out_ptr) +{ + free(*out_ptr); + *out_ptr = strndup((const char *)cbs->data, cbs->len); + return (*out_ptr != NULL); +} + +int +CBS_write_bytes(const CBS *cbs, uint8_t *dst, size_t dst_len, size_t *copied) +{ + if (dst_len < cbs->len) + return 0; + + memmove(dst, cbs->data, cbs->len); + + if (copied != NULL) + *copied = cbs->len; + + return 1; +} + +int +CBS_contains_zero_byte(const CBS *cbs) +{ + return memchr(cbs->data, 0, cbs->len) != NULL; +} + +int +CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) +{ + if (len != cbs->len) + return 0; + + return timingsafe_memcmp(cbs->data, data, len) == 0; +} + +static int +cbs_get_u(CBS *cbs, uint32_t *out, size_t len) +{ + uint32_t result = 0; + size_t i; + const uint8_t *data; + + if (len < 1 || len > 4) + return 0; + + if (!cbs_get(cbs, &data, len)) + return 0; + + for (i = 0; i < len; i++) { + result <<= 8; + result |= data[i]; + } + *out = result; + return 1; +} + +int +CBS_get_u8(CBS *cbs, uint8_t *out) +{ + const uint8_t *v; + + if (!cbs_get(cbs, &v, 1)) + return 0; + + *out = *v; + return 1; +} + +int +CBS_get_u16(CBS *cbs, uint16_t *out) +{ + uint32_t v; + + if (!cbs_get_u(cbs, &v, 2)) + return 0; + + *out = v; + return 1; +} + +int +CBS_get_u24(CBS *cbs, uint32_t *out) +{ + return cbs_get_u(cbs, out, 3); +} + +int +CBS_get_u32(CBS *cbs, uint32_t *out) +{ + return cbs_get_u(cbs, out, 4); +} + +int +CBS_get_bytes(CBS *cbs, CBS *out, size_t len) +{ + const uint8_t *v; + + if (!cbs_get(cbs, &v, len)) + return 0; + + CBS_init(out, v, len); + return 1; +} + +static int +cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) +{ + uint32_t len; + + if (!cbs_get_u(cbs, &len, len_len)) + return 0; + + return CBS_get_bytes(cbs, out, len); +} + +int +CBS_get_u8_length_prefixed(CBS *cbs, CBS *out) +{ + return cbs_get_length_prefixed(cbs, out, 1); +} + +int +CBS_get_u16_length_prefixed(CBS *cbs, CBS *out) +{ + return cbs_get_length_prefixed(cbs, out, 2); +} + +int +CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) +{ + return cbs_get_length_prefixed(cbs, out, 3); +} + +int +CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag, + size_t *out_header_len) +{ + return cbs_get_any_asn1_element_internal(cbs, out, out_tag, + out_header_len, 1); +} + +/* + * Review X.690 for details on ASN.1 DER encoding. + * + * If non-strict mode is enabled, then DER rules are relaxed + * for indefinite constructs (violates DER but a little closer to BER). + * Non-strict mode should only be used by bs_ber.c + * + * Sections 8, 10 and 11 for DER encoding + */ +int +cbs_get_any_asn1_element_internal(CBS *cbs, CBS *out, unsigned int *out_tag, + size_t *out_header_len, int strict) +{ + uint8_t tag, length_byte; + CBS header = *cbs; + CBS throwaway; + size_t len; + + if (out == NULL) + out = &throwaway; + + /* + * Get identifier octet and length octet. Only 1 octet for each + * is a CBS limitation. + */ + if (!CBS_get_u8(&header, &tag) || !CBS_get_u8(&header, &length_byte)) + return 0; + + /* CBS limitation: long form tags are not supported. */ + if ((tag & 0x1f) == 0x1f) + return 0; + + if (out_tag != NULL) + *out_tag = tag; + + if ((length_byte & 0x80) == 0) { + /* Short form length. */ + len = ((size_t) length_byte) + 2; + if (out_header_len != NULL) + *out_header_len = 2; + + } else { + /* Long form length. */ + const size_t num_bytes = length_byte & 0x7f; + uint32_t len32; + + /* ASN.1 reserved value for future extensions */ + if (num_bytes == 0x7f) + return 0; + + /* Handle indefinite form length */ + if (num_bytes == 0) { + /* DER encoding doesn't allow for indefinite form. */ + if (strict) + return 0; + + /* Primitive cannot use indefinite in BER or DER. */ + if ((tag & CBS_ASN1_CONSTRUCTED) == 0) + return 0; + + /* Constructed, indefinite length allowed in BER. */ + if (out_header_len != NULL) + *out_header_len = 2; + return CBS_get_bytes(cbs, out, 2); + } + + /* CBS limitation. */ + if (num_bytes > 4) + return 0; + + if (!cbs_get_u(&header, &len32, num_bytes)) + return 0; + + /* DER has a minimum length octet requirement. */ + if (len32 < 128) + /* Should have used short form instead */ + return 0; + + if ((len32 >> ((num_bytes - 1) * 8)) == 0) + /* Length should have been at least one byte shorter. */ + return 0; + + len = len32; + if (len + 2 + num_bytes < len) + /* Overflow. */ + return 0; + + len += 2 + num_bytes; + if (out_header_len != NULL) + *out_header_len = 2 + num_bytes; + } + + return CBS_get_bytes(cbs, out, len); +} + +static int +cbs_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value, int skip_header) +{ + size_t header_len; + unsigned int tag; + CBS throwaway; + + if (out == NULL) + out = &throwaway; + + if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) || + tag != tag_value) + return 0; + + if (skip_header && !CBS_skip(out, header_len)) { + assert(0); + return 0; + } + + return 1; +} + +int +CBS_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value) +{ + return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */); +} + +int +CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned int tag_value) +{ + return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */); +} + +int +CBS_peek_asn1_tag(const CBS *cbs, unsigned int tag_value) +{ + if (CBS_len(cbs) < 1) + return 0; + + /* + * Tag number 31 indicates the start of a long form number. + * This is valid in ASN.1, but CBS only supports short form. + */ + if ((tag_value & 0x1f) == 0x1f) + return 0; + + return CBS_data(cbs)[0] == tag_value; +} + +/* Encoding details are in ASN.1: X.690 section 8.3 */ +int +CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) +{ + CBS bytes; + const uint8_t *data; + size_t i, len; + + if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER)) + return 0; + + *out = 0; + data = CBS_data(&bytes); + len = CBS_len(&bytes); + + if (len == 0) + /* An INTEGER is encoded with at least one content octet. */ + return 0; + + if ((data[0] & 0x80) != 0) + /* Negative number. */ + return 0; + + if (data[0] == 0 && len > 1 && (data[1] & 0x80) == 0) + /* Violates smallest encoding rule: excessive leading zeros. */ + return 0; + + for (i = 0; i < len; i++) { + if ((*out >> 56) != 0) + /* Too large to represent as a uint64_t. */ + return 0; + + *out <<= 8; + *out |= data[i]; + } + + return 1; +} + +int +CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned int tag) +{ + if (CBS_peek_asn1_tag(cbs, tag)) { + if (!CBS_get_asn1(cbs, out, tag)) + return 0; + + *out_present = 1; + } else { + *out_present = 0; + } + return 1; +} + +int +CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present, + unsigned int tag) +{ + CBS child; + int present; + + if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) + return 0; + + if (present) { + if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) || + CBS_len(&child) != 0) + return 0; + } else { + CBS_init(out, NULL, 0); + } + if (out_present) + *out_present = present; + + return 1; +} + +int +CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned int tag, + uint64_t default_value) +{ + CBS child; + int present; + + if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) + return 0; + + if (present) { + if (!CBS_get_asn1_uint64(&child, out) || + CBS_len(&child) != 0) + return 0; + } else { + *out = default_value; + } + return 1; +} + +int +CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned int tag, + int default_value) +{ + CBS child, child2; + int present; + + if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) + return 0; + + if (present) { + uint8_t boolean; + + if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) || + CBS_len(&child2) != 1 || CBS_len(&child) != 0) + return 0; + + boolean = CBS_data(&child2)[0]; + if (boolean == 0) + *out = 0; + else if (boolean == 0xff) + *out = 1; + else + return 0; + + } else { + *out = default_value; + } + return 1; +} diff --git a/crypto/libressl/ssl/bytestring.h b/crypto/libressl/ssl/bytestring.h new file mode 100644 index 0000000000..3a1cc3d933 --- /dev/null +++ b/crypto/libressl/ssl/bytestring.h @@ -0,0 +1,511 @@ +/* $OpenBSD: bytestring.h,v 1.13 2015/06/18 23:25:07 doug Exp $ */ +/* + * Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or 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 OPENSSL_HEADER_BYTESTRING_H +#define OPENSSL_HEADER_BYTESTRING_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include +#include + +#include + +/* + * Bytestrings are used for parsing and building TLS and ASN.1 messages. + * + * A "CBS" (CRYPTO ByteString) represents a string of bytes in memory and + * provides utility functions for safely parsing length-prefixed structures + * like TLS and ASN.1 from it. + * + * A "CBB" (CRYPTO ByteBuilder) is a memory buffer that grows as needed and + * provides utility functions for building length-prefixed messages. + */ + +/* CRYPTO ByteString */ +typedef struct cbs_st { + const uint8_t *data; + size_t initial_len; + size_t len; +} CBS; + +/* + * CBS_init sets |cbs| to point to |data|. It does not take ownership of + * |data|. + */ +void CBS_init(CBS *cbs, const uint8_t *data, size_t len); + +/* + * CBS_skip advances |cbs| by |len| bytes. It returns one on success and zero + * otherwise. + */ +int CBS_skip(CBS *cbs, size_t len); + +/* + * CBS_data returns a pointer to the contents of |cbs|. + */ +const uint8_t *CBS_data(const CBS *cbs); + +/* + * CBS_len returns the number of bytes remaining in |cbs|. + */ +size_t CBS_len(const CBS *cbs); + +/* + * CBS_offset returns the current offset into the original data of |cbs|. + */ +size_t CBS_offset(const CBS *cbs); + +/* + * CBS_stow copies the current contents of |cbs| into |*out_ptr| and + * |*out_len|. If |*out_ptr| is not NULL, the contents are freed with + * free. It returns one on success and zero on allocation failure. On + * success, |*out_ptr| should be freed with free. If |cbs| is empty, + * |*out_ptr| will be NULL. + */ +int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len); + +/* + * CBS_strdup copies the current contents of |cbs| into |*out_ptr| as a + * NUL-terminated C string. If |*out_ptr| is not NULL, the contents are freed + * with free. It returns one on success and zero on allocation + * failure. On success, |*out_ptr| should be freed with free. + * + * NOTE: If |cbs| contains NUL bytes, the string will be truncated. Call + * |CBS_contains_zero_byte(cbs)| to check for NUL bytes. + */ +int CBS_strdup(const CBS *cbs, char **out_ptr); + +/* + * CBS_write_bytes writes all of the remaining data from |cbs| into |dst| + * if it is at most |dst_len| bytes. If |copied| is not NULL, it will be set + * to the amount copied. It returns one on success and zero otherwise. + */ +int CBS_write_bytes(const CBS *cbs, uint8_t *dst, size_t dst_len, + size_t *copied); + +/* + * CBS_contains_zero_byte returns one if the current contents of |cbs| contains + * a NUL byte and zero otherwise. + */ +int CBS_contains_zero_byte(const CBS *cbs); + +/* + * CBS_mem_equal compares the current contents of |cbs| with the |len| bytes + * starting at |data|. If they're equal, it returns one, otherwise zero. If the + * lengths match, it uses a constant-time comparison. + */ +int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len); + +/* + * CBS_get_u8 sets |*out| to the next uint8_t from |cbs| and advances |cbs|. It + * returns one on success and zero on error. + */ +int CBS_get_u8(CBS *cbs, uint8_t *out); + +/* + * CBS_get_u16 sets |*out| to the next, big-endian uint16_t from |cbs| and + * advances |cbs|. It returns one on success and zero on error. + */ +int CBS_get_u16(CBS *cbs, uint16_t *out); + +/* + * CBS_get_u24 sets |*out| to the next, big-endian 24-bit value from |cbs| and + * advances |cbs|. It returns one on success and zero on error. + */ +int CBS_get_u24(CBS *cbs, uint32_t *out); + +/* + * CBS_get_u32 sets |*out| to the next, big-endian uint32_t value from |cbs| + * and advances |cbs|. It returns one on success and zero on error. + */ +int CBS_get_u32(CBS *cbs, uint32_t *out); + +/* + * CBS_get_bytes sets |*out| to the next |len| bytes from |cbs| and advances + * |cbs|. It returns one on success and zero on error. + */ +int CBS_get_bytes(CBS *cbs, CBS *out, size_t len); + +/* + * CBS_get_u8_length_prefixed sets |*out| to the contents of an 8-bit, + * length-prefixed value from |cbs| and advances |cbs| over it. It returns one + * on success and zero on error. + */ +int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out); + +/* + * CBS_get_u16_length_prefixed sets |*out| to the contents of a 16-bit, + * big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It + * returns one on success and zero on error. + */ +int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out); + +/* + * CBS_get_u24_length_prefixed sets |*out| to the contents of a 24-bit, + * big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It + * returns one on success and zero on error. + */ +int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out); + + +/* Parsing ASN.1 */ + +/* + * While an identifier can be multiple octets, this library only handles the + * single octet variety currently. This limits support up to tag number 30 + * since tag number 31 is a reserved value to indicate multiple octets. + */ + +/* Bits 8 and 7: class tag type: See X.690 section 8.1.2.2. */ +#define CBS_ASN1_UNIVERSAL 0x00 +#define CBS_ASN1_APPLICATION 0x40 +#define CBS_ASN1_CONTEXT_SPECIFIC 0x80 +#define CBS_ASN1_PRIVATE 0xc0 + +/* Bit 6: Primitive or constructed: See X.690 section 8.1.2.3. */ +#define CBS_ASN1_PRIMITIVE 0x00 +#define CBS_ASN1_CONSTRUCTED 0x20 + +/* + * Bits 5 to 1 are the tag number. See X.680 section 8.6 for tag numbers of + * the universal class. + */ + +/* + * Common universal identifier octets. + * See X.690 section 8.1 and X.680 section 8.6 for universal tag numbers. + * + * Note: These definitions are the cause of some of the strange behavior in + * CBS's bs_ber.c. + * + * In BER, it is the sender's option to use primitive or constructed for + * bitstring (X.690 section 8.6.1) and octetstring (X.690 section 8.7.1). + * + * In DER, bitstring and octetstring are required to be primitive + * (X.690 section 10.2). + */ +#define CBS_ASN1_BOOLEAN (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x1) +#define CBS_ASN1_INTEGER (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x2) +#define CBS_ASN1_BITSTRING (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x3) +#define CBS_ASN1_OCTETSTRING (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x4) +#define CBS_ASN1_OBJECT (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x6) +#define CBS_ASN1_ENUMERATED (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0xa) +#define CBS_ASN1_SEQUENCE (CBS_ASN1_UNIVERSAL | CBS_ASN1_CONSTRUCTED | 0x10) +#define CBS_ASN1_SET (CBS_ASN1_UNIVERSAL | CBS_ASN1_CONSTRUCTED | 0x11) + +/* + * CBS_get_asn1 sets |*out| to the contents of DER-encoded, ASN.1 element (not + * including tag and length bytes) and advances |cbs| over it. The ASN.1 + * element must match |tag_value|. It returns one on success and zero + * on error. + * + * Tag numbers greater than 30 are not supported (i.e. short form only). + */ +int CBS_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value); + +/* + * CBS_get_asn1_element acts like |CBS_get_asn1| but |out| will include the + * ASN.1 header bytes too. + */ +int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned int tag_value); + +/* + * CBS_peek_asn1_tag looks ahead at the next ASN.1 tag and returns one + * if the next ASN.1 element on |cbs| would have tag |tag_value|. If + * |cbs| is empty or the tag does not match, it returns zero. Note: if + * it returns one, CBS_get_asn1 may still fail if the rest of the + * element is malformed. + */ +int CBS_peek_asn1_tag(const CBS *cbs, unsigned int tag_value); + +/* + * CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from + * |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to + * the tag number and |*out_header_len| to the length of the ASN.1 header. + * Each of |out|, |out_tag|, and |out_header_len| may be NULL to ignore + * the value. + * + * Tag numbers greater than 30 are not supported (i.e. short form only). + */ +int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag, + size_t *out_header_len); + +/* + * CBS_get_asn1_uint64 gets an ASN.1 INTEGER from |cbs| using |CBS_get_asn1| + * and sets |*out| to its value. It returns one on success and zero on error, + * where error includes the integer being negative, or too large to represent + * in 64 bits. + */ +int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out); + +/* + * CBS_get_optional_asn1 gets an optional explicitly-tagged element + * from |cbs| tagged with |tag| and sets |*out| to its contents. If + * present, it sets |*out_present| to one, otherwise zero. It returns + * one on success, whether or not the element was present, and zero on + * decode failure. + */ +int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, + unsigned int tag); + +/* + * CBS_get_optional_asn1_octet_string gets an optional + * explicitly-tagged OCTET STRING from |cbs|. If present, it sets + * |*out| to the string and |*out_present| to one. Otherwise, it sets + * |*out| to empty and |*out_present| to zero. |out_present| may be + * NULL. It returns one on success, whether or not the element was + * present, and zero on decode failure. + */ +int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present, + unsigned int tag); + +/* + * CBS_get_optional_asn1_uint64 gets an optional explicitly-tagged + * INTEGER from |cbs|. If present, it sets |*out| to the + * value. Otherwise, it sets |*out| to |default_value|. It returns one + * on success, whether or not the element was present, and zero on + * decode failure. + */ +int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned int tag, + uint64_t default_value); + +/* + * CBS_get_optional_asn1_bool gets an optional, explicitly-tagged BOOLEAN from + * |cbs|. If present, it sets |*out| to either zero or one, based on the + * boolean. Otherwise, it sets |*out| to |default_value|. It returns one on + * success, whether or not the element was present, and zero on decode + * failure. + */ +int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned int tag, + int default_value); + + +/* + * CRYPTO ByteBuilder. + * + * |CBB| objects allow one to build length-prefixed serialisations. A |CBB| + * object is associated with a buffer and new buffers are created with + * |CBB_init|. Several |CBB| objects can point at the same buffer when a + * length-prefix is pending, however only a single |CBB| can be 'current' at + * any one time. For example, if one calls |CBB_add_u8_length_prefixed| then + * the new |CBB| points at the same buffer as the original. But if the original + * |CBB| is used then the length prefix is written out and the new |CBB| must + * not be used again. + * + * If one needs to force a length prefix to be written out because a |CBB| is + * going out of scope, use |CBB_flush|. + */ + +struct cbb_buffer_st { + uint8_t *buf; + + /* The number of valid bytes. */ + size_t len; + + /* The size of buf. */ + size_t cap; + + /* + * One iff |buf| is owned by this object. If not then |buf| cannot be + * resized. + */ + char can_resize; +}; + +typedef struct cbb_st { + struct cbb_buffer_st *base; + + /* + * offset is the offset from the start of |base->buf| to the position of any + * pending length-prefix. + */ + size_t offset; + + /* child points to a child CBB if a length-prefix is pending. */ + struct cbb_st *child; + + /* + * pending_len_len contains the number of bytes in a pending length-prefix, + * or zero if no length-prefix is pending. + */ + uint8_t pending_len_len; + + char pending_is_asn1; + + /* + * is_top_level is true iff this is a top-level |CBB| (as opposed to a child + * |CBB|). Top-level objects are valid arguments for |CBB_finish|. + */ + char is_top_level; +} CBB; + +/* + * CBB_init initialises |cbb| with |initial_capacity|. Since a |CBB| grows as + * needed, the |initial_capacity| is just a hint. It returns one on success or + * zero on error. + */ +int CBB_init(CBB *cbb, size_t initial_capacity); + +/* + * CBB_init_fixed initialises |cbb| to write to |len| bytes at |buf|. Since + * |buf| cannot grow, trying to write more than |len| bytes will cause CBB + * functions to fail. It returns one on success or zero on error. + */ +int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len); + +/* + * CBB_cleanup frees all resources owned by |cbb| and other |CBB| objects + * writing to the same buffer. This should be used in an error case where a + * serialisation is abandoned. + */ +void CBB_cleanup(CBB *cbb); + +/* + * CBB_finish completes any pending length prefix and sets |*out_data| to a + * malloced buffer and |*out_len| to the length of that buffer. The caller + * takes ownership of the buffer and, unless the buffer was fixed with + * |CBB_init_fixed|, must call |free| when done. + * + * It can only be called on a "top level" |CBB|, i.e. one initialised with + * |CBB_init| or |CBB_init_fixed|. It returns one on success and zero on + * error. + */ +int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len); + +/* + * CBB_flush causes any pending length prefixes to be written out and any child + * |CBB| objects of |cbb| to be invalidated. It returns one on success or zero + * on error. + */ +int CBB_flush(CBB *cbb); + +/* + * CBB_add_u8_length_prefixed sets |*out_contents| to a new child of |cbb|. The + * data written to |*out_contents| will be prefixed in |cbb| with an 8-bit + * length. It returns one on success or zero on error. + */ +int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents); + +/* + * CBB_add_u16_length_prefixed sets |*out_contents| to a new child of |cbb|. + * The data written to |*out_contents| will be prefixed in |cbb| with a 16-bit, + * big-endian length. It returns one on success or zero on error. + */ +int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents); + +/* + * CBB_add_u24_length_prefixed sets |*out_contents| to a new child of |cbb|. + * The data written to |*out_contents| will be prefixed in |cbb| with a 24-bit, + * big-endian length. It returns one on success or zero on error. + */ +int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents); + +/* + * CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an + * ASN.1 object can be written. The |tag| argument will be used as the tag for + * the object. Passing in |tag| number 31 will return in an error since only + * single octet identifiers are supported. It returns one on success or zero + * on error. + */ +int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned int tag); + +/* + * CBB_add_bytes appends |len| bytes from |data| to |cbb|. It returns one on + * success and zero otherwise. + */ +int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len); + +/* + * CBB_add_space appends |len| bytes to |cbb| and sets |*out_data| to point to + * the beginning of that space. The caller must then write |len| bytes of + * actual contents to |*out_data|. It returns one on success and zero + * otherwise. + */ +int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len); + +/* + * CBB_add_u8 appends an 8-bit number from |value| to |cbb|. It returns one on + * success and zero otherwise. + */ +int CBB_add_u8(CBB *cbb, size_t value); + +/* + * CBB_add_u8 appends a 16-bit, big-endian number from |value| to |cbb|. It + * returns one on success and zero otherwise. + */ +int CBB_add_u16(CBB *cbb, size_t value); + +/* + * CBB_add_u24 appends a 24-bit, big-endian number from |value| to |cbb|. It + * returns one on success and zero otherwise. + */ +int CBB_add_u24(CBB *cbb, size_t value); + +/* + * CBB_add_asn1_uint64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1| + * and writes |value| in its contents. It returns one on success and zero on + * error. + */ +int CBB_add_asn1_uint64(CBB *cbb, uint64_t value); + +#ifdef LIBRESSL_INTERNAL +/* + * CBS_dup sets |out| to point to cbs's |data| and |len|. It results in two + * CBS that point to the same buffer. + */ +void CBS_dup(const CBS *cbs, CBS *out); + +/* + * cbs_get_any_asn1_element sets |*out| to contain the next ASN.1 element from + * |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to + * the tag number and |*out_header_len| to the length of the ASN.1 header. If + * strict mode is disabled and the element has indefinite length then |*out| + * will only contain the header. Each of |out|, |out_tag|, and + * |out_header_len| may be NULL to ignore the value. + * + * Tag numbers greater than 30 are not supported (i.e. short form only). + */ +int cbs_get_any_asn1_element_internal(CBS *cbs, CBS *out, unsigned int *out_tag, + size_t *out_header_len, int strict); + +/* + * CBS_asn1_indefinite_to_definite reads an ASN.1 structure from |in|. If it + * finds indefinite-length elements that otherwise appear to be valid DER, it + * attempts to convert the DER-like data to DER and sets |*out| and + * |*out_length| to describe a malloced buffer containing the DER data. + * Additionally, |*in| will be advanced over the ASN.1 data. + * + * If it doesn't find any indefinite-length elements then it sets |*out| to + * NULL and |*in| is unmodified. + * + * This is NOT a conversion from BER to DER. There are many restrictions when + * dealing with DER data. This is only concerned with one: indefinite vs. + * definite form. However, this suffices to handle the PKCS#7 and PKCS#12 output + * from NSS. + * + * It returns one on success and zero otherwise. + */ +int CBS_asn1_indefinite_to_definite(CBS *in, uint8_t **out, size_t *out_len); +#endif /* LIBRESSL_INTERNAL */ + +#if defined(__cplusplus) +} /* extern C */ +#endif + +#endif /* OPENSSL_HEADER_BYTESTRING_H */ diff --git a/crypto/libressl/ssl/d1_both.c b/crypto/libressl/ssl/d1_both.c new file mode 100644 index 0000000000..31b2fd9589 --- /dev/null +++ b/crypto/libressl/ssl/d1_both.c @@ -0,0 +1,1374 @@ +/* $OpenBSD: d1_both.c,v 1.38 2015/09/11 18:08:21 jsing Exp $ */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "ssl_locl.h" + +#include +#include +#include +#include + +#include "pqueue.h" +#include "bytestring.h" + +#define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8) + +#define RSMBLY_BITMASK_MARK(bitmask, start, end) { \ + if ((end) - (start) <= 8) { \ + long ii; \ + for (ii = (start); ii < (end); ii++) bitmask[((ii) >> 3)] |= (1 << ((ii) & 7)); \ + } else { \ + long ii; \ + bitmask[((start) >> 3)] |= bitmask_start_values[((start) & 7)]; \ + for (ii = (((start) >> 3) + 1); ii < ((((end) - 1)) >> 3); ii++) bitmask[ii] = 0xff; \ + bitmask[(((end) - 1) >> 3)] |= bitmask_end_values[((end) & 7)]; \ + } } + +#define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete) { \ + long ii; \ + OPENSSL_assert((msg_len) > 0); \ + is_complete = 1; \ + if (bitmask[(((msg_len) - 1) >> 3)] != bitmask_end_values[((msg_len) & 7)]) is_complete = 0; \ + if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \ + if (bitmask[ii] != 0xff) { is_complete = 0; break; } } + +static unsigned char bitmask_start_values[] = { + 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80 +}; +static unsigned char bitmask_end_values[] = { + 0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f +}; + +/* XDTLS: figure out the right values */ +static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28}; + +static unsigned int dtls1_guess_mtu(unsigned int curr_mtu); +static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, + unsigned long frag_len); +static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p); +static void dtls1_set_message_header_int(SSL *s, unsigned char mt, + unsigned long len, unsigned short seq_num, unsigned long frag_off, + unsigned long frag_len); +static long dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, + int *ok); + +static hm_fragment * +dtls1_hm_fragment_new(unsigned long frag_len, int reassembly) +{ + hm_fragment *frag = NULL; + unsigned char *buf = NULL; + unsigned char *bitmask = NULL; + + frag = malloc(sizeof(hm_fragment)); + if (frag == NULL) + return NULL; + + if (frag_len) { + buf = malloc(frag_len); + if (buf == NULL) { + free(frag); + return NULL; + } + } + + /* zero length fragment gets zero frag->fragment */ + frag->fragment = buf; + + /* Initialize reassembly bitmask if necessary */ + if (reassembly) { + bitmask = malloc(RSMBLY_BITMASK_SIZE(frag_len)); + if (bitmask == NULL) { + free(buf); + free(frag); + return NULL; + } + memset(bitmask, 0, RSMBLY_BITMASK_SIZE(frag_len)); + } + + frag->reassembly = bitmask; + + return frag; +} + +static void +dtls1_hm_fragment_free(hm_fragment *frag) +{ + if (frag == NULL) + return; + + if (frag->msg_header.is_ccs) { + EVP_CIPHER_CTX_free( + frag->msg_header.saved_retransmit_state.enc_write_ctx); + EVP_MD_CTX_destroy( + frag->msg_header.saved_retransmit_state.write_hash); + } + free(frag->fragment); + free(frag->reassembly); + free(frag); +} + +/* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */ +int +dtls1_do_write(SSL *s, int type) +{ + int ret; + int curr_mtu; + unsigned int len, frag_off, mac_size, blocksize; + + /* AHA! Figure out the MTU, and stick to the right size */ + if (s->d1->mtu < dtls1_min_mtu() && + !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { + s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), + BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); + + /* + * I've seen the kernel return bogus numbers when it + * doesn't know the MTU (ie., the initial write), so just + * make sure we have a reasonable number + */ + if (s->d1->mtu < dtls1_min_mtu()) { + s->d1->mtu = 0; + s->d1->mtu = dtls1_guess_mtu(s->d1->mtu); + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU, + s->d1->mtu, NULL); + } + } + + OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu()); + /* should have something reasonable now */ + + if (s->init_off == 0 && type == SSL3_RT_HANDSHAKE) + OPENSSL_assert(s->init_num == + (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH); + + if (s->write_hash) + mac_size = EVP_MD_CTX_size(s->write_hash); + else + mac_size = 0; + + if (s->enc_write_ctx && + (EVP_CIPHER_mode( s->enc_write_ctx->cipher) & EVP_CIPH_CBC_MODE)) + blocksize = 2 * EVP_CIPHER_block_size(s->enc_write_ctx->cipher); + else + blocksize = 0; + + frag_off = 0; + while (s->init_num) { + curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) - + DTLS1_RT_HEADER_LENGTH - mac_size - blocksize; + + if (curr_mtu <= DTLS1_HM_HEADER_LENGTH) { + /* grr.. we could get an error if MTU picked was wrong */ + ret = BIO_flush(SSL_get_wbio(s)); + if (ret <= 0) + return ret; + curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH - + mac_size - blocksize; + } + + if (s->init_num > curr_mtu) + len = curr_mtu; + else + len = s->init_num; + + + /* XDTLS: this function is too long. split out the CCS part */ + if (type == SSL3_RT_HANDSHAKE) { + if (s->init_off != 0) { + OPENSSL_assert(s->init_off > DTLS1_HM_HEADER_LENGTH); + s->init_off -= DTLS1_HM_HEADER_LENGTH; + s->init_num += DTLS1_HM_HEADER_LENGTH; + + if (s->init_num > curr_mtu) + len = curr_mtu; + else + len = s->init_num; + } + + dtls1_fix_message_header(s, frag_off, + len - DTLS1_HM_HEADER_LENGTH); + + dtls1_write_message_header(s, + (unsigned char *)&s->init_buf->data[s->init_off]); + + OPENSSL_assert(len >= DTLS1_HM_HEADER_LENGTH); + } + + ret = dtls1_write_bytes(s, type, + &s->init_buf->data[s->init_off], len); + if (ret < 0) { + /* + * Might need to update MTU here, but we don't know + * which previous packet caused the failure -- so + * can't really retransmit anything. continue as + * if everything is fine and wait for an alert to + * handle the retransmit + */ + if (BIO_ctrl(SSL_get_wbio(s), + BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0) + s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), + BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); + else + return (-1); + } else { + + /* + * Bad if this assert fails, only part of the + * handshake message got sent. but why would + * this happen? + */ + OPENSSL_assert(len == (unsigned int)ret); + + if (type == SSL3_RT_HANDSHAKE && + !s->d1->retransmitting) { + /* + * Should not be done for 'Hello Request's, + * but in that case we'll ignore the result + * anyway + */ + unsigned char *p = (unsigned char *)&s->init_buf->data[s->init_off]; + const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; + int xlen; + + if (frag_off == 0) { + /* + * Reconstruct message header is if it + * is being sent in single fragment + */ + *p++ = msg_hdr->type; + l2n3(msg_hdr->msg_len, p); + s2n (msg_hdr->seq, p); + l2n3(0, p); + l2n3(msg_hdr->msg_len, p); + p -= DTLS1_HM_HEADER_LENGTH; + xlen = ret; + } else { + p += DTLS1_HM_HEADER_LENGTH; + xlen = ret - DTLS1_HM_HEADER_LENGTH; + } + + tls1_finish_mac(s, p, xlen); + } + + if (ret == s->init_num) { + if (s->msg_callback) + s->msg_callback(1, s->version, type, + s->init_buf->data, + (size_t)(s->init_off + s->init_num), + s, s->msg_callback_arg); + + s->init_off = 0; + /* done writing this message */ + s->init_num = 0; + + return (1); + } + s->init_off += ret; + s->init_num -= ret; + frag_off += (ret -= DTLS1_HM_HEADER_LENGTH); + } + } + return (0); +} + + +/* + * Obtain handshake message of message type 'mt' (any if mt == -1), + * maximum acceptable body length 'max'. + * Read an entire handshake message. Handshake messages arrive in + * fragments. + */ +long +dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) +{ + int i, al; + struct hm_header_st *msg_hdr; + unsigned char *p; + unsigned long msg_len; + + /* + * s3->tmp is used to store messages that are unexpected, caused + * by the absence of an optional handshake message + */ + if (s->s3->tmp.reuse_message) { + s->s3->tmp.reuse_message = 0; + if ((mt >= 0) && (s->s3->tmp.message_type != mt)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_GET_MESSAGE, + SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + *ok = 1; + s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + s->init_num = (int)s->s3->tmp.message_size; + return s->init_num; + } + + msg_hdr = &s->d1->r_msg_hdr; + memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); + +again: + i = dtls1_get_message_fragment(s, st1, stn, max, ok); + if (i == DTLS1_HM_BAD_FRAGMENT || + i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */ + goto again; + else if (i <= 0 && !*ok) + return i; + + p = (unsigned char *)s->init_buf->data; + msg_len = msg_hdr->msg_len; + + /* reconstruct message header */ + *(p++) = msg_hdr->type; + l2n3(msg_len, p); + s2n (msg_hdr->seq, p); + l2n3(0, p); + l2n3(msg_len, p); + + p -= DTLS1_HM_HEADER_LENGTH; + msg_len += DTLS1_HM_HEADER_LENGTH; + + tls1_finish_mac(s, p, msg_len); + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, p, msg_len, + s, s->msg_callback_arg); + + memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); + + /* Don't change sequence numbers while listening */ + if (!s->d1->listen) + s->d1->handshake_read_seq++; + + s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + return s->init_num; + +f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + *ok = 0; + return -1; +} + + +static int +dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr, int max) +{ + size_t frag_off, frag_len, msg_len; + + msg_len = msg_hdr->msg_len; + frag_off = msg_hdr->frag_off; + frag_len = msg_hdr->frag_len; + + /* sanity checking */ + if ((frag_off + frag_len) > msg_len) { + SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, + SSL_R_EXCESSIVE_MESSAGE_SIZE); + return SSL_AD_ILLEGAL_PARAMETER; + } + + if ((frag_off + frag_len) > (unsigned long)max) { + SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, + SSL_R_EXCESSIVE_MESSAGE_SIZE); + return SSL_AD_ILLEGAL_PARAMETER; + } + + if ( s->d1->r_msg_hdr.frag_off == 0) /* first fragment */ + { + /* + * msg_len is limited to 2^24, but is effectively checked + * against max above + */ + if (!BUF_MEM_grow_clean(s->init_buf, + msg_len + DTLS1_HM_HEADER_LENGTH)) { + SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, ERR_R_BUF_LIB); + return SSL_AD_INTERNAL_ERROR; + } + + s->s3->tmp.message_size = msg_len; + s->d1->r_msg_hdr.msg_len = msg_len; + s->s3->tmp.message_type = msg_hdr->type; + s->d1->r_msg_hdr.type = msg_hdr->type; + s->d1->r_msg_hdr.seq = msg_hdr->seq; + } else if (msg_len != s->d1->r_msg_hdr.msg_len) { + /* + * They must be playing with us! BTW, failure to enforce + * upper limit would open possibility for buffer overrun. + */ + SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, + SSL_R_EXCESSIVE_MESSAGE_SIZE); + return SSL_AD_ILLEGAL_PARAMETER; + } + + return 0; /* no error */ +} + +static int +dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) +{ + /* + * (0) check whether the desired fragment is available + * if so: + * (1) copy over the fragment to s->init_buf->data[] + * (2) update s->init_num + */ + pitem *item; + hm_fragment *frag; + int al; + + *ok = 0; + item = pqueue_peek(s->d1->buffered_messages); + if (item == NULL) + return 0; + + frag = (hm_fragment *)item->data; + + /* Don't return if reassembly still in progress */ + if (frag->reassembly != NULL) + return 0; + + if (s->d1->handshake_read_seq == frag->msg_header.seq) { + unsigned long frag_len = frag->msg_header.frag_len; + pqueue_pop(s->d1->buffered_messages); + + al = dtls1_preprocess_fragment(s, &frag->msg_header, max); + + if (al == 0) /* no alert */ + { + unsigned char *p = (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + memcpy(&p[frag->msg_header.frag_off], + frag->fragment, frag->msg_header.frag_len); + } + + dtls1_hm_fragment_free(frag); + pitem_free(item); + + if (al == 0) { + *ok = 1; + return frag_len; + } + + ssl3_send_alert(s, SSL3_AL_FATAL, al); + s->init_num = 0; + *ok = 0; + return -1; + } else + return 0; +} + +/* + * dtls1_max_handshake_message_len returns the maximum number of bytes + * permitted in a DTLS handshake message for |s|. The minimum is 16KB, + * but may be greater if the maximum certificate list size requires it. + */ +static unsigned long +dtls1_max_handshake_message_len(const SSL *s) +{ + unsigned long max_len; + + max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; + if (max_len < (unsigned long)s->max_cert_list) + return s->max_cert_list; + return max_len; +} + +static int +dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) +{ + hm_fragment *frag = NULL; + pitem *item = NULL; + int i = -1, is_complete; + unsigned char seq64be[8]; + unsigned long frag_len = msg_hdr->frag_len; + + if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len || + msg_hdr->msg_len > dtls1_max_handshake_message_len(s)) + goto err; + + if (frag_len == 0) { + i = DTLS1_HM_FRAGMENT_RETRY; + goto err; + } + + /* Try to find item in queue */ + memset(seq64be, 0, sizeof(seq64be)); + seq64be[6] = (unsigned char)(msg_hdr->seq >> 8); + seq64be[7] = (unsigned char)msg_hdr->seq; + item = pqueue_find(s->d1->buffered_messages, seq64be); + + if (item == NULL) { + frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1); + if (frag == NULL) + goto err; + memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); + frag->msg_header.frag_len = frag->msg_header.msg_len; + frag->msg_header.frag_off = 0; + } else { + frag = (hm_fragment*)item->data; + if (frag->msg_header.msg_len != msg_hdr->msg_len) { + item = NULL; + frag = NULL; + goto err; + } + } + + /* + * If message is already reassembled, this must be a + * retransmit and can be dropped. + */ + if (frag->reassembly == NULL) { + unsigned char devnull [256]; + + while (frag_len) { + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + devnull, frag_len > sizeof(devnull) ? + sizeof(devnull) : frag_len, 0); + if (i <= 0) + goto err; + frag_len -= i; + } + i = DTLS1_HM_FRAGMENT_RETRY; + goto err; + } + + /* read the body of the fragment (header has already been read */ + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + frag->fragment + msg_hdr->frag_off, frag_len, 0); + if (i <= 0 || (unsigned long)i != frag_len) + goto err; + + RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off, + (long)(msg_hdr->frag_off + frag_len)); + + RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len, + is_complete); + + if (is_complete) { + free(frag->reassembly); + frag->reassembly = NULL; + } + + if (item == NULL) { + memset(seq64be, 0, sizeof(seq64be)); + seq64be[6] = (unsigned char)(msg_hdr->seq >> 8); + seq64be[7] = (unsigned char)(msg_hdr->seq); + + item = pitem_new(seq64be, frag); + if (item == NULL) { + i = -1; + goto err; + } + + pqueue_insert(s->d1->buffered_messages, item); + } + + return DTLS1_HM_FRAGMENT_RETRY; + +err: + if (item == NULL && frag != NULL) + dtls1_hm_fragment_free(frag); + *ok = 0; + return i; +} + + +static int +dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) +{ + int i = -1; + hm_fragment *frag = NULL; + pitem *item = NULL; + unsigned char seq64be[8]; + unsigned long frag_len = msg_hdr->frag_len; + + if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len) + goto err; + + /* Try to find item in queue, to prevent duplicate entries */ + memset(seq64be, 0, sizeof(seq64be)); + seq64be[6] = (unsigned char) (msg_hdr->seq >> 8); + seq64be[7] = (unsigned char) msg_hdr->seq; + item = pqueue_find(s->d1->buffered_messages, seq64be); + + /* + * If we already have an entry and this one is a fragment, + * don't discard it and rather try to reassemble it. + */ + if (item != NULL && frag_len < msg_hdr->msg_len) + item = NULL; + + /* + * Discard the message if sequence number was already there, is + * too far in the future, already in the queue or if we received + * a FINISHED before the SERVER_HELLO, which then must be a stale + * retransmit. + */ + if (msg_hdr->seq <= s->d1->handshake_read_seq || + msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL || + (s->d1->handshake_read_seq == 0 && + msg_hdr->type == SSL3_MT_FINISHED)) { + unsigned char devnull [256]; + + while (frag_len) { + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + devnull, frag_len > sizeof(devnull) ? + sizeof(devnull) : frag_len, 0); + if (i <= 0) + goto err; + frag_len -= i; + } + } else { + if (frag_len < msg_hdr->msg_len) + return dtls1_reassemble_fragment(s, msg_hdr, ok); + + if (frag_len > dtls1_max_handshake_message_len(s)) + goto err; + + frag = dtls1_hm_fragment_new(frag_len, 0); + if (frag == NULL) + goto err; + + memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); + + if (frag_len) { + /* read the body of the fragment (header has already been read */ + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + frag->fragment, frag_len, 0); + if (i <= 0 || (unsigned long)i != frag_len) + goto err; + } + + memset(seq64be, 0, sizeof(seq64be)); + seq64be[6] = (unsigned char)(msg_hdr->seq >> 8); + seq64be[7] = (unsigned char)(msg_hdr->seq); + + item = pitem_new(seq64be, frag); + if (item == NULL) + goto err; + + pqueue_insert(s->d1->buffered_messages, item); + } + + return DTLS1_HM_FRAGMENT_RETRY; + +err: + if (item == NULL && frag != NULL) + dtls1_hm_fragment_free(frag); + *ok = 0; + return i; +} + + +static long +dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) +{ + unsigned char wire[DTLS1_HM_HEADER_LENGTH]; + unsigned long len, frag_off, frag_len; + int i, al; + struct hm_header_st msg_hdr; + +again: + /* see if we have the required fragment already */ + if ((frag_len = dtls1_retrieve_buffered_fragment(s, max, ok)) || *ok) { + if (*ok) + s->init_num = frag_len; + return frag_len; + } + + /* read handshake message header */ + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, wire, + DTLS1_HM_HEADER_LENGTH, 0); + if (i <= 0) /* nbio, or an error */ + { + s->rwstate = SSL_READING; + *ok = 0; + return i; + } + /* Handshake fails if message header is incomplete */ + if (i != DTLS1_HM_HEADER_LENGTH || + /* parse the message fragment header */ + dtls1_get_message_header(wire, &msg_hdr) == 0) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, + SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + + /* + * if this is a future (or stale) message it gets buffered + * (or dropped)--no further processing at this time + * While listening, we accept seq 1 (ClientHello with cookie) + * although we're still expecting seq 0 (ClientHello) + */ + if (msg_hdr.seq != s->d1->handshake_read_seq && + !(s->d1->listen && msg_hdr.seq == 1)) + return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); + + len = msg_hdr.msg_len; + frag_off = msg_hdr.frag_off; + frag_len = msg_hdr.frag_len; + + if (frag_len && frag_len < len) + return dtls1_reassemble_fragment(s, &msg_hdr, ok); + + if (!s->server && s->d1->r_msg_hdr.frag_off == 0 && + wire[0] == SSL3_MT_HELLO_REQUEST) { + /* + * The server may always send 'Hello Request' messages -- + * we are doing a handshake anyway now, so ignore them + * if their format is correct. Does not count for + * 'Finished' MAC. + */ + if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) { + if (s->msg_callback) + s->msg_callback(0, s->version, + SSL3_RT_HANDSHAKE, wire, + DTLS1_HM_HEADER_LENGTH, s, + s->msg_callback_arg); + + s->init_num = 0; + goto again; + } + else /* Incorrectly formated Hello request */ + { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, + SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + } + + if ((al = dtls1_preprocess_fragment(s, &msg_hdr, max))) + goto f_err; + + /* XDTLS: ressurect this when restart is in place */ + s->state = stn; + + if (frag_len > 0) { + unsigned char *p = (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + &p[frag_off], frag_len, 0); + /* XDTLS: fix this--message fragments cannot span multiple packets */ + if (i <= 0) { + s->rwstate = SSL_READING; + *ok = 0; + return i; + } + } else + i = 0; + + /* + * XDTLS: an incorrectly formatted fragment should cause the + * handshake to fail + */ + if (i != (int)frag_len) { + al = SSL3_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, + SSL3_AD_ILLEGAL_PARAMETER); + goto f_err; + } + + *ok = 1; + + /* + * Note that s->init_num is *not* used as current offset in + * s->init_buf->data, but as a counter summing up fragments' + * lengths: as soon as they sum up to handshake packet + * length, we assume we have got all the fragments. + */ + s->init_num = frag_len; + return frag_len; + +f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + s->init_num = 0; + + *ok = 0; + return (-1); +} + +/* + * for these 2 messages, we need to + * ssl->enc_read_ctx re-init + * ssl->s3->read_sequence zero + * ssl->s3->read_mac_secret re-init + * ssl->session->read_sym_enc assign + * ssl->session->read_hash assign + */ +int +dtls1_send_change_cipher_spec(SSL *s, int a, int b) +{ + unsigned char *p; + + if (s->state == a) { + p = (unsigned char *)s->init_buf->data; + *p++=SSL3_MT_CCS; + s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; + s->init_num = DTLS1_CCS_HEADER_LENGTH; + + s->init_off = 0; + + dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, + s->d1->handshake_write_seq, 0, 0); + + /* buffer the message to handle re-xmits */ + dtls1_buffer_message(s, 1); + + s->state = b; + } + + /* SSL3_ST_CW_CHANGE_B */ + return (dtls1_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC)); +} + +static int +dtls1_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x) +{ + int n; + unsigned char *p; + + n = i2d_X509(x, NULL); + if (!BUF_MEM_grow_clean(buf, n + (*l) + 3)) { + SSLerr(SSL_F_DTLS1_ADD_CERT_TO_BUF, ERR_R_BUF_LIB); + return 0; + } + p = (unsigned char *)&(buf->data[*l]); + l2n3(n, p); + i2d_X509(x, &p); + *l += n + 3; + + return 1; +} + +unsigned long +dtls1_output_cert_chain(SSL *s, X509 *x) +{ + unsigned char *p; + int i; + unsigned long l = 3 + DTLS1_HM_HEADER_LENGTH; + BUF_MEM *buf; + + /* TLSv1 sends a chain with nothing in it, instead of an alert */ + buf = s->init_buf; + if (!BUF_MEM_grow_clean(buf, 10)) { + SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN, ERR_R_BUF_LIB); + return (0); + } + if (x != NULL) { + X509_STORE_CTX xs_ctx; + + if (!X509_STORE_CTX_init(&xs_ctx, s->ctx->cert_store, + x, NULL)) { + SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN, ERR_R_X509_LIB); + return (0); + } + + X509_verify_cert(&xs_ctx); + /* Don't leave errors in the queue */ + ERR_clear_error(); + for (i = 0; i < sk_X509_num(xs_ctx.chain); i++) { + x = sk_X509_value(xs_ctx.chain, i); + + if (!dtls1_add_cert_to_buf(buf, &l, x)) { + X509_STORE_CTX_cleanup(&xs_ctx); + return 0; + } + } + X509_STORE_CTX_cleanup(&xs_ctx); + } + /* Thawte special :-) */ + for (i = 0; i < sk_X509_num(s->ctx->extra_certs); i++) { + x = sk_X509_value(s->ctx->extra_certs, i); + if (!dtls1_add_cert_to_buf(buf, &l, x)) + return 0; + } + + l -= (3 + DTLS1_HM_HEADER_LENGTH); + + p = (unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]); + l2n3(l, p); + l += 3; + p = (unsigned char *)&(buf->data[0]); + p = dtls1_set_message_header(s, p, SSL3_MT_CERTIFICATE, l, 0, l); + + l += DTLS1_HM_HEADER_LENGTH; + return (l); +} + +int +dtls1_read_failed(SSL *s, int code) +{ + if (code > 0) { +#ifdef DEBUG + fprintf(stderr, "invalid state reached %s:%d", + __FILE__, __LINE__); +#endif + return 1; + } + + if (!dtls1_is_timer_expired(s)) { + /* + * not a timeout, none of our business, let higher layers + * handle this. in fact it's probably an error + */ + return code; + } + + if (!SSL_in_init(s)) /* done, no need to send a retransmit */ + { + BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ); + return code; + } + + return dtls1_handle_timeout(s); +} + +int +dtls1_get_queue_priority(unsigned short seq, int is_ccs) +{ + /* + * The index of the retransmission queue actually is the message + * sequence number, since the queue only contains messages of a + * single handshake. However, the ChangeCipherSpec has no message + * sequence number and so using only the sequence will result in + * the CCS and Finished having the same index. To prevent this, the + * sequence number is multiplied by 2. In case of a CCS 1 is + * subtracted. This does not only differ CSS and Finished, it also + * maintains the order of the index (important for priority queues) + * and fits in the unsigned short variable. + */ + return seq * 2 - is_ccs; +} + +int +dtls1_retransmit_buffered_messages(SSL *s) +{ + pqueue sent = s->d1->sent_messages; + piterator iter; + pitem *item; + hm_fragment *frag; + int found = 0; + + iter = pqueue_iterator(sent); + + for (item = pqueue_next(&iter); item != NULL; + item = pqueue_next(&iter)) { + frag = (hm_fragment *)item->data; + if (dtls1_retransmit_message(s, + (unsigned short)dtls1_get_queue_priority( + frag->msg_header.seq, frag->msg_header.is_ccs), 0, + &found) <= 0 && found) { +#ifdef DEBUG + fprintf(stderr, "dtls1_retransmit_message() failed\n"); +#endif + return -1; + } + } + + return 1; +} + +int +dtls1_buffer_message(SSL *s, int is_ccs) +{ + pitem *item; + hm_fragment *frag; + unsigned char seq64be[8]; + + /* Buffer the messsage in order to handle DTLS retransmissions. */ + + /* + * This function is called immediately after a message has + * been serialized + */ + OPENSSL_assert(s->init_off == 0); + + frag = dtls1_hm_fragment_new(s->init_num, 0); + if (frag == NULL) + return 0; + + memcpy(frag->fragment, s->init_buf->data, s->init_num); + + if (is_ccs) { + OPENSSL_assert(s->d1->w_msg_hdr.msg_len + + ((s->version == DTLS1_VERSION) ? + DTLS1_CCS_HEADER_LENGTH : 3) == (unsigned int)s->init_num); + } else { + OPENSSL_assert(s->d1->w_msg_hdr.msg_len + + DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num); + } + + frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len; + frag->msg_header.seq = s->d1->w_msg_hdr.seq; + frag->msg_header.type = s->d1->w_msg_hdr.type; + frag->msg_header.frag_off = 0; + frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len; + frag->msg_header.is_ccs = is_ccs; + + /* save current state*/ + frag->msg_header.saved_retransmit_state.enc_write_ctx = s->enc_write_ctx; + frag->msg_header.saved_retransmit_state.write_hash = s->write_hash; + frag->msg_header.saved_retransmit_state.session = s->session; + frag->msg_header.saved_retransmit_state.epoch = s->d1->w_epoch; + + memset(seq64be, 0, sizeof(seq64be)); + seq64be[6] = (unsigned char)(dtls1_get_queue_priority( + frag->msg_header.seq, frag->msg_header.is_ccs) >> 8); + seq64be[7] = (unsigned char)(dtls1_get_queue_priority( + frag->msg_header.seq, frag->msg_header.is_ccs)); + + item = pitem_new(seq64be, frag); + if (item == NULL) { + dtls1_hm_fragment_free(frag); + return 0; + } + + pqueue_insert(s->d1->sent_messages, item); + return 1; +} + +int +dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, + int *found) +{ + int ret; + /* XDTLS: for now assuming that read/writes are blocking */ + pitem *item; + hm_fragment *frag; + unsigned long header_length; + unsigned char seq64be[8]; + struct dtls1_retransmit_state saved_state; + unsigned char save_write_sequence[8]; + + /* + OPENSSL_assert(s->init_num == 0); + OPENSSL_assert(s->init_off == 0); + */ + + /* XDTLS: the requested message ought to be found, otherwise error */ + memset(seq64be, 0, sizeof(seq64be)); + seq64be[6] = (unsigned char)(seq >> 8); + seq64be[7] = (unsigned char)seq; + + item = pqueue_find(s->d1->sent_messages, seq64be); + if (item == NULL) { +#ifdef DEBUG + fprintf(stderr, "retransmit: message %d non-existant\n", seq); +#endif + *found = 0; + return 0; + } + + *found = 1; + frag = (hm_fragment *)item->data; + + if (frag->msg_header.is_ccs) + header_length = DTLS1_CCS_HEADER_LENGTH; + else + header_length = DTLS1_HM_HEADER_LENGTH; + + memcpy(s->init_buf->data, frag->fragment, + frag->msg_header.msg_len + header_length); + s->init_num = frag->msg_header.msg_len + header_length; + + dtls1_set_message_header_int(s, frag->msg_header.type, + frag->msg_header.msg_len, frag->msg_header.seq, 0, + frag->msg_header.frag_len); + + /* save current state */ + saved_state.enc_write_ctx = s->enc_write_ctx; + saved_state.write_hash = s->write_hash; + saved_state.session = s->session; + saved_state.epoch = s->d1->w_epoch; + + s->d1->retransmitting = 1; + + /* restore state in which the message was originally sent */ + s->enc_write_ctx = frag->msg_header.saved_retransmit_state.enc_write_ctx; + s->write_hash = frag->msg_header.saved_retransmit_state.write_hash; + s->session = frag->msg_header.saved_retransmit_state.session; + s->d1->w_epoch = frag->msg_header.saved_retransmit_state.epoch; + + if (frag->msg_header.saved_retransmit_state.epoch == + saved_state.epoch - 1) { + memcpy(save_write_sequence, s->s3->write_sequence, + sizeof(s->s3->write_sequence)); + memcpy(s->s3->write_sequence, s->d1->last_write_sequence, + sizeof(s->s3->write_sequence)); + } + + ret = dtls1_do_write(s, frag->msg_header.is_ccs ? + SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE); + + /* restore current state */ + s->enc_write_ctx = saved_state.enc_write_ctx; + s->write_hash = saved_state.write_hash; + s->session = saved_state.session; + s->d1->w_epoch = saved_state.epoch; + + if (frag->msg_header.saved_retransmit_state.epoch == + saved_state.epoch - 1) { + memcpy(s->d1->last_write_sequence, s->s3->write_sequence, + sizeof(s->s3->write_sequence)); + memcpy(s->s3->write_sequence, save_write_sequence, + sizeof(s->s3->write_sequence)); + } + + s->d1->retransmitting = 0; + + (void)BIO_flush(SSL_get_wbio(s)); + return ret; +} + +/* call this function when the buffered messages are no longer needed */ +void +dtls1_clear_record_buffer(SSL *s) +{ + pitem *item; + + for(item = pqueue_pop(s->d1->sent_messages); item != NULL; + item = pqueue_pop(s->d1->sent_messages)) { + dtls1_hm_fragment_free((hm_fragment *)item->data); + pitem_free(item); + } +} + +unsigned char * +dtls1_set_message_header(SSL *s, unsigned char *p, unsigned char mt, + unsigned long len, unsigned long frag_off, unsigned long frag_len) +{ + /* Don't change sequence numbers while listening */ + if (frag_off == 0 && !s->d1->listen) { + s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; + s->d1->next_handshake_write_seq++; + } + + dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq, + frag_off, frag_len); + + return p += DTLS1_HM_HEADER_LENGTH; +} + +/* don't actually do the writing, wait till the MTU has been retrieved */ +static void +dtls1_set_message_header_int(SSL *s, unsigned char mt, unsigned long len, + unsigned short seq_num, unsigned long frag_off, unsigned long frag_len) +{ + struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; + + msg_hdr->type = mt; + msg_hdr->msg_len = len; + msg_hdr->seq = seq_num; + msg_hdr->frag_off = frag_off; + msg_hdr->frag_len = frag_len; +} + +static void +dtls1_fix_message_header(SSL *s, unsigned long frag_off, unsigned long frag_len) +{ + struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; + + msg_hdr->frag_off = frag_off; + msg_hdr->frag_len = frag_len; +} + +static unsigned char * +dtls1_write_message_header(SSL *s, unsigned char *p) +{ + struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; + + *p++ = msg_hdr->type; + l2n3(msg_hdr->msg_len, p); + + s2n(msg_hdr->seq, p); + l2n3(msg_hdr->frag_off, p); + l2n3(msg_hdr->frag_len, p); + + return p; +} + +unsigned int +dtls1_min_mtu(void) +{ + return (g_probable_mtu[(sizeof(g_probable_mtu) / + sizeof(g_probable_mtu[0])) - 1]); +} + +static unsigned int +dtls1_guess_mtu(unsigned int curr_mtu) +{ + unsigned int i; + + if (curr_mtu == 0) + return g_probable_mtu[0]; + + for (i = 0; i < sizeof(g_probable_mtu) / sizeof(g_probable_mtu[0]); i++) + if (curr_mtu > g_probable_mtu[i]) + return g_probable_mtu[i]; + + return curr_mtu; +} + +int +dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr) +{ + CBS header; + uint32_t msg_len, frag_off, frag_len; + uint16_t seq; + uint8_t type; + + CBS_init(&header, data, sizeof(*msg_hdr)); + + memset(msg_hdr, 0, sizeof(*msg_hdr)); + + if (!CBS_get_u8(&header, &type)) + return 0; + if (!CBS_get_u24(&header, &msg_len)) + return 0; + if (!CBS_get_u16(&header, &seq)) + return 0; + if (!CBS_get_u24(&header, &frag_off)) + return 0; + if (!CBS_get_u24(&header, &frag_len)) + return 0; + + msg_hdr->type = type; + msg_hdr->msg_len = msg_len; + msg_hdr->seq = seq; + msg_hdr->frag_off = frag_off; + msg_hdr->frag_len = frag_len; + + return 1; +} + +void +dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr) +{ + memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st)); + + ccs_hdr->type = *(data++); +} + +int +dtls1_shutdown(SSL *s) +{ + int ret; + + ret = ssl3_shutdown(s); + return ret; +} diff --git a/crypto/libressl/ssl/d1_clnt.c b/crypto/libressl/ssl/d1_clnt.c new file mode 100644 index 0000000000..ebfc50e90d --- /dev/null +++ b/crypto/libressl/ssl/d1_clnt.c @@ -0,0 +1,724 @@ +/* $OpenBSD: d1_clnt.c,v 1.55 2015/09/12 16:10:07 doug Exp $ */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include "ssl_locl.h" + +#include +#include +#include +#include +#include +#include + +#include "bytestring.h" + +static const SSL_METHOD *dtls1_get_client_method(int ver); +static int dtls1_get_hello_verify(SSL *s); + +const SSL_METHOD DTLSv1_client_method_data = { + .version = DTLS1_VERSION, + .ssl_new = dtls1_new, + .ssl_clear = dtls1_clear, + .ssl_free = dtls1_free, + .ssl_accept = ssl_undefined_function, + .ssl_connect = dtls1_connect, + .ssl_read = ssl3_read, + .ssl_peek = ssl3_peek, + .ssl_write = ssl3_write, + .ssl_shutdown = dtls1_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_get_message = dtls1_get_message, + .ssl_read_bytes = dtls1_read_bytes, + .ssl_write_bytes = dtls1_write_app_data_bytes, + .ssl_dispatch_alert = dtls1_dispatch_alert, + .ssl_ctrl = dtls1_ctrl, + .ssl_ctx_ctrl = ssl3_ctx_ctrl, + .get_cipher_by_char = ssl3_get_cipher_by_char, + .put_cipher_by_char = ssl3_put_cipher_by_char, + .ssl_pending = ssl3_pending, + .num_ciphers = ssl3_num_ciphers, + .get_cipher = dtls1_get_cipher, + .get_ssl_method = dtls1_get_client_method, + .get_timeout = dtls1_default_timeout, + .ssl3_enc = &DTLSv1_enc_data, + .ssl_version = ssl_undefined_void_function, + .ssl_callback_ctrl = ssl3_callback_ctrl, + .ssl_ctx_callback_ctrl = ssl3_ctx_callback_ctrl, +}; + +const SSL_METHOD * +DTLSv1_client_method(void) +{ + return &DTLSv1_client_method_data; +} + +static const SSL_METHOD * +dtls1_get_client_method(int ver) +{ + if (ver == DTLS1_VERSION) + return (DTLSv1_client_method()); + return (NULL); +} + +int +dtls1_connect(SSL *s) +{ + void (*cb)(const SSL *ssl, int type, int val) = NULL; + int ret = -1; + int new_state, state, skip = 0; + + ERR_clear_error(); + errno = 0; + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + + + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_RENEGOTIATE: + s->renegotiate = 1; + s->state = SSL_ST_CONNECT; + s->ctx->stats.sess_connect_renegotiate++; + /* break */ + case SSL_ST_BEFORE: + case SSL_ST_CONNECT: + case SSL_ST_BEFORE|SSL_ST_CONNECT: + case SSL_ST_OK|SSL_ST_CONNECT: + + s->server = 0; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + if ((s->version & 0xff00 ) != (DTLS1_VERSION & 0xff00)) { + SSLerr(SSL_F_DTLS1_CONNECT, + ERR_R_INTERNAL_ERROR); + ret = -1; + goto end; + } + + /* s->version=SSL3_VERSION; */ + s->type = SSL_ST_CONNECT; + + if (!ssl3_setup_init_buffer(s)) { + ret = -1; + goto end; + } + if (!ssl3_setup_buffers(s)) { + ret = -1; + goto end; + } + if (!ssl_init_wbio_buffer(s, 0)) { + ret = -1; + goto end; + } + + /* don't push the buffering BIO quite yet */ + + s->state = SSL3_ST_CW_CLNT_HELLO_A; + s->ctx->stats.sess_connect++; + s->init_num = 0; + /* mark client_random uninitialized */ + memset(s->s3->client_random, 0, + sizeof(s->s3->client_random)); + s->d1->send_cookie = 0; + s->hit = 0; + break; + + + case SSL3_ST_CW_CLNT_HELLO_A: + case SSL3_ST_CW_CLNT_HELLO_B: + + s->shutdown = 0; + + /* every DTLS ClientHello resets Finished MAC */ + if (!tls1_init_finished_mac(s)) { + ret = -1; + goto end; + } + + dtls1_start_timer(s); + ret = ssl3_client_hello(s); + if (ret <= 0) + goto end; + + if (s->d1->send_cookie) { + s->state = SSL3_ST_CW_FLUSH; + s->s3->tmp.next_state = SSL3_ST_CR_SRVR_HELLO_A; + } else + s->state = SSL3_ST_CR_SRVR_HELLO_A; + + s->init_num = 0; + + /* turn on buffering for the next lot of output */ + if (s->bbio != s->wbio) + s->wbio = BIO_push(s->bbio, s->wbio); + + break; + + case SSL3_ST_CR_SRVR_HELLO_A: + case SSL3_ST_CR_SRVR_HELLO_B: + ret = ssl3_get_server_hello(s); + if (ret <= 0) + goto end; + else { + if (s->hit) { + + s->state = SSL3_ST_CR_FINISHED_A; + } else + s->state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A; + } + s->init_num = 0; + break; + + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: + + ret = dtls1_get_hello_verify(s); + if (ret <= 0) + goto end; + dtls1_stop_timer(s); + if ( s->d1->send_cookie) /* start again, with a cookie */ + s->state = SSL3_ST_CW_CLNT_HELLO_A; + else + s->state = SSL3_ST_CR_CERT_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_CERT_A: + case SSL3_ST_CR_CERT_B: + ret = ssl3_check_finished(s); + if (ret <= 0) + goto end; + if (ret == 2) { + s->hit = 1; + if (s->tlsext_ticket_expected) + s->state = SSL3_ST_CR_SESSION_TICKET_A; + else + s->state = SSL3_ST_CR_FINISHED_A; + s->init_num = 0; + break; + } + /* Check if it is anon DH. */ + if (!(s->s3->tmp.new_cipher->algorithm_auth & + SSL_aNULL)) { + ret = ssl3_get_server_certificate(s); + if (ret <= 0) + goto end; + if (s->tlsext_status_expected) + s->state = SSL3_ST_CR_CERT_STATUS_A; + else + s->state = SSL3_ST_CR_KEY_EXCH_A; + } else { + skip = 1; + s->state = SSL3_ST_CR_KEY_EXCH_A; + } + s->init_num = 0; + break; + + case SSL3_ST_CR_KEY_EXCH_A: + case SSL3_ST_CR_KEY_EXCH_B: + ret = ssl3_get_key_exchange(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_CERT_REQ_A; + s->init_num = 0; + + /* at this point we check that we have the + * required stuff from the server */ + if (!ssl3_check_cert_and_algorithm(s)) { + ret = -1; + goto end; + } + break; + + case SSL3_ST_CR_CERT_REQ_A: + case SSL3_ST_CR_CERT_REQ_B: + ret = ssl3_get_certificate_request(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_SRVR_DONE_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_SRVR_DONE_A: + case SSL3_ST_CR_SRVR_DONE_B: + ret = ssl3_get_server_done(s); + if (ret <= 0) + goto end; + dtls1_stop_timer(s); + if (s->s3->tmp.cert_req) + s->s3->tmp.next_state = SSL3_ST_CW_CERT_A; + else + s->s3->tmp.next_state = SSL3_ST_CW_KEY_EXCH_A; + s->init_num = 0; + s->state = s->s3->tmp.next_state; + break; + + case SSL3_ST_CW_CERT_A: + case SSL3_ST_CW_CERT_B: + case SSL3_ST_CW_CERT_C: + case SSL3_ST_CW_CERT_D: + dtls1_start_timer(s); + ret = dtls1_send_client_certificate(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CW_KEY_EXCH_A; + s->init_num = 0; + break; + + case SSL3_ST_CW_KEY_EXCH_A: + case SSL3_ST_CW_KEY_EXCH_B: + dtls1_start_timer(s); + ret = ssl3_send_client_key_exchange(s); + if (ret <= 0) + goto end; + + /* EAY EAY EAY need to check for DH fix cert + * sent back */ + /* For TLS, cert_req is set to 2, so a cert chain + * of nothing is sent, but no verify packet is sent */ + if (s->s3->tmp.cert_req == 1) { + s->state = SSL3_ST_CW_CERT_VRFY_A; + } else { + s->state = SSL3_ST_CW_CHANGE_A; + s->s3->change_cipher_spec = 0; + } + + s->init_num = 0; + break; + + case SSL3_ST_CW_CERT_VRFY_A: + case SSL3_ST_CW_CERT_VRFY_B: + dtls1_start_timer(s); + ret = ssl3_send_client_verify(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CW_CHANGE_A; + s->init_num = 0; + s->s3->change_cipher_spec = 0; + break; + + case SSL3_ST_CW_CHANGE_A: + case SSL3_ST_CW_CHANGE_B: + if (!s->hit) + dtls1_start_timer(s); + ret = dtls1_send_change_cipher_spec(s, + SSL3_ST_CW_CHANGE_A, SSL3_ST_CW_CHANGE_B); + if (ret <= 0) + goto end; + + s->state = SSL3_ST_CW_FINISHED_A; + s->init_num = 0; + + s->session->cipher = s->s3->tmp.new_cipher; + if (!s->method->ssl3_enc->setup_key_block(s)) { + ret = -1; + goto end; + } + + if (!s->method->ssl3_enc->change_cipher_state(s, + SSL3_CHANGE_CIPHER_CLIENT_WRITE)) { + ret = -1; + goto end; + } + + + dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); + break; + + case SSL3_ST_CW_FINISHED_A: + case SSL3_ST_CW_FINISHED_B: + if (!s->hit) + dtls1_start_timer(s); + ret = ssl3_send_finished(s, + SSL3_ST_CW_FINISHED_A, SSL3_ST_CW_FINISHED_B, + s->method->ssl3_enc->client_finished_label, + s->method->ssl3_enc->client_finished_label_len); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CW_FLUSH; + + /* clear flags */ + s->s3->flags&= ~SSL3_FLAGS_POP_BUFFER; + if (s->hit) { + s->s3->tmp.next_state = SSL_ST_OK; + if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED) { + s->state = SSL_ST_OK; + s->s3->flags |= SSL3_FLAGS_POP_BUFFER; + s->s3->delay_buf_pop_ret = 0; + } + } else { + + /* Allow NewSessionTicket if ticket expected */ + if (s->tlsext_ticket_expected) + s->s3->tmp.next_state = + SSL3_ST_CR_SESSION_TICKET_A; + else + s->s3->tmp.next_state = + SSL3_ST_CR_FINISHED_A; + } + s->init_num = 0; + break; + + case SSL3_ST_CR_SESSION_TICKET_A: + case SSL3_ST_CR_SESSION_TICKET_B: + ret = ssl3_get_new_session_ticket(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_FINISHED_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_CERT_STATUS_A: + case SSL3_ST_CR_CERT_STATUS_B: + ret = ssl3_get_cert_status(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_KEY_EXCH_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_FINISHED_A: + case SSL3_ST_CR_FINISHED_B: + s->d1->change_cipher_spec_ok = 1; + ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, + SSL3_ST_CR_FINISHED_B); + if (ret <= 0) + goto end; + dtls1_stop_timer(s); + + if (s->hit) + s->state = SSL3_ST_CW_CHANGE_A; + else + s->state = SSL_ST_OK; + + + s->init_num = 0; + break; + + case SSL3_ST_CW_FLUSH: + s->rwstate = SSL_WRITING; + if (BIO_flush(s->wbio) <= 0) { + /* If the write error was fatal, stop trying */ + if (!BIO_should_retry(s->wbio)) { + s->rwstate = SSL_NOTHING; + s->state = s->s3->tmp.next_state; + } + + ret = -1; + goto end; + } + s->rwstate = SSL_NOTHING; + s->state = s->s3->tmp.next_state; + break; + + case SSL_ST_OK: + /* clean a few things up */ + tls1_cleanup_key_block(s); + + /* If we are not 'joining' the last two packets, + * remove the buffering now */ + if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER)) + ssl_free_wbio_buffer(s); + /* else do it later in ssl3_write */ + + s->init_num = 0; + s->renegotiate = 0; + s->new_session = 0; + + ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); + if (s->hit) + s->ctx->stats.sess_hit++; + + ret = 1; + /* s->server=0; */ + s->handshake_func = dtls1_connect; + s->ctx->stats.sess_connect_good++; + + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_DONE, 1); + + /* done with handshaking */ + s->d1->handshake_read_seq = 0; + s->d1->next_handshake_write_seq = 0; + goto end; + /* break; */ + + default: + SSLerr(SSL_F_DTLS1_CONNECT, SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* break; */ + } + + /* did we do anything */ + if (!s->s3->tmp.reuse_message && !skip) { + if (s->debug) { + if ((ret = BIO_flush(s->wbio)) <= 0) + goto end; + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_CONNECT_LOOP, 1); + s->state = new_state; + } + } + skip = 0; + } + +end: + s->in_handshake--; + if (cb != NULL) + cb(s, SSL_CB_CONNECT_EXIT, ret); + + return (ret); +} + +static int +dtls1_get_hello_verify(SSL *s) +{ + long n; + int al, ok = 0; + size_t cookie_len; + uint16_t ssl_version; + CBS hello_verify_request, cookie; + + n = s->method->ssl_get_message(s, DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A, + DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B, -1, s->max_cert_list, &ok); + + if (!ok) + return ((int)n); + + if (s->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) { + s->d1->send_cookie = 0; + s->s3->tmp.reuse_message = 1; + return (1); + } + + if (n < 0) + goto truncated; + + CBS_init(&hello_verify_request, s->init_msg, n); + + if (!CBS_get_u16(&hello_verify_request, &ssl_version)) + goto truncated; + + if (ssl_version != s->version) { + SSLerr(SSL_F_DTLS1_GET_HELLO_VERIFY, SSL_R_WRONG_SSL_VERSION); + s->version = (s->version & 0xff00) | (ssl_version & 0xff); + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; + } + + if (!CBS_get_u8_length_prefixed(&hello_verify_request, &cookie)) + goto truncated; + + if (!CBS_write_bytes(&cookie, s->d1->cookie, + sizeof(s->d1->cookie), &cookie_len)) { + s->d1->cookie_len = 0; + al = SSL_AD_ILLEGAL_PARAMETER; + goto f_err; + } + s->d1->cookie_len = cookie_len; + s->d1->send_cookie = 1; + + return 1; + +truncated: + al = SSL_AD_DECODE_ERROR; +f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return -1; +} + +int +dtls1_send_client_certificate(SSL *s) +{ + X509 *x509 = NULL; + EVP_PKEY *pkey = NULL; + int i; + unsigned long l; + + if (s->state == SSL3_ST_CW_CERT_A) { + if ((s->cert == NULL) || (s->cert->key->x509 == NULL) || + (s->cert->key->privatekey == NULL)) + s->state = SSL3_ST_CW_CERT_B; + else + s->state = SSL3_ST_CW_CERT_C; + } + + /* We need to get a client cert */ + if (s->state == SSL3_ST_CW_CERT_B) { + /* If we get an error, we need to + * ssl->rwstate=SSL_X509_LOOKUP; return(-1); + * We then get retied later */ + i = 0; + i = ssl_do_client_cert_cb(s, &x509, &pkey); + if (i < 0) { + s->rwstate = SSL_X509_LOOKUP; + return (-1); + } + s->rwstate = SSL_NOTHING; + if ((i == 1) && (pkey != NULL) && (x509 != NULL)) { + s->state = SSL3_ST_CW_CERT_B; + if (!SSL_use_certificate(s, x509) || + !SSL_use_PrivateKey(s, pkey)) + i = 0; + } else if (i == 1) { + i = 0; + SSLerr(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE, + SSL_R_BAD_DATA_RETURNED_BY_CALLBACK); + } + + X509_free(x509); + EVP_PKEY_free(pkey); + if (i == 0) + s->s3->tmp.cert_req = 2; + + /* Ok, we have a cert */ + s->state = SSL3_ST_CW_CERT_C; + } + + if (s->state == SSL3_ST_CW_CERT_C) { + s->state = SSL3_ST_CW_CERT_D; + l = dtls1_output_cert_chain(s, + (s->s3->tmp.cert_req == 2) ? NULL : s->cert->key->x509); + s->init_num = (int)l; + s->init_off = 0; + + /* set header called by dtls1_output_cert_chain() */ + + /* buffer the message to handle re-xmits */ + dtls1_buffer_message(s, 0); + } + + /* SSL3_ST_CW_CERT_D */ + return (dtls1_do_write(s, SSL3_RT_HANDSHAKE)); +} diff --git a/crypto/libressl/ssl/d1_enc.c b/crypto/libressl/ssl/d1_enc.c new file mode 100644 index 0000000000..ba1b8171c9 --- /dev/null +++ b/crypto/libressl/ssl/d1_enc.c @@ -0,0 +1,212 @@ +/* $OpenBSD: d1_enc.c,v 1.10 2015/07/17 07:04:40 doug Exp $ */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include "ssl_locl.h" + +#include +#include +#include + +/* dtls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. + * + * Returns: + * 0: (in non-constant time) if the record is publically invalid (i.e. too + * short etc). + * 1: if the record's padding is valid / the encryption was successful. + * -1: if the record's padding/AEAD-authenticator is invalid or, if sending, + * an internal error occured. */ +int +dtls1_enc(SSL *s, int send) +{ + SSL3_RECORD *rec; + EVP_CIPHER_CTX *ds; + unsigned long l; + int bs, i, j, k, mac_size = 0; + const EVP_CIPHER *enc; + + if (send) { + if (EVP_MD_CTX_md(s->write_hash)) { + mac_size = EVP_MD_CTX_size(s->write_hash); + if (mac_size < 0) + return -1; + } + ds = s->enc_write_ctx; + rec = &(s->s3->wrec); + if (s->enc_write_ctx == NULL) + enc = NULL; + else { + enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx); + if (rec->data != rec->input) { +#ifdef DEBUG + /* we can't write into the input stream */ + fprintf(stderr, "%s:%d: rec->data != rec->input\n", + __FILE__, __LINE__); +#endif + } else if (EVP_CIPHER_block_size(ds->cipher) > 1) { + arc4random_buf(rec->input, + EVP_CIPHER_block_size(ds->cipher)); + } + } + } else { + if (EVP_MD_CTX_md(s->read_hash)) { + mac_size = EVP_MD_CTX_size(s->read_hash); + OPENSSL_assert(mac_size >= 0); + } + ds = s->enc_read_ctx; + rec = &(s->s3->rrec); + if (s->enc_read_ctx == NULL) + enc = NULL; + else + enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx); + } + + + if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { + memmove(rec->data, rec->input, rec->length); + rec->input = rec->data; + } else { + l = rec->length; + bs = EVP_CIPHER_block_size(ds->cipher); + + if ((bs != 1) && send) { + i = bs - ((int)l % bs); + + /* Add weird padding of upto 256 bytes */ + + /* we need to add 'i' padding bytes of value j */ + j = i - 1; + for (k = (int)l; k < (int)(l + i); k++) + rec->input[k] = j; + l += i; + rec->length += i; + } + + + if (!send) { + if (l == 0 || l % bs != 0) + return 0; + } + + EVP_Cipher(ds, rec->data, rec->input, l); + + + if ((bs != 1) && !send) + return tls1_cbc_remove_padding(s, rec, bs, mac_size); + } + return (1); +} + diff --git a/crypto/libressl/ssl/d1_lib.c b/crypto/libressl/ssl/d1_lib.c new file mode 100644 index 0000000000..3320b8c318 --- /dev/null +++ b/crypto/libressl/ssl/d1_lib.c @@ -0,0 +1,468 @@ +/* $OpenBSD: d1_lib.c,v 1.32 2015/10/07 13:20:48 bcook Exp $ */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include + +#include + +#include + +#include "pqueue.h" +#include "ssl_locl.h" + +int dtls1_listen(SSL *s, struct sockaddr *client); + +SSL3_ENC_METHOD DTLSv1_enc_data = { + .enc = dtls1_enc, + .mac = tls1_mac, + .setup_key_block = tls1_setup_key_block, + .generate_master_secret = tls1_generate_master_secret, + .change_cipher_state = tls1_change_cipher_state, + .final_finish_mac = tls1_final_finish_mac, + .finish_mac_length = TLS1_FINISH_MAC_LENGTH, + .cert_verify_mac = tls1_cert_verify_mac, + .client_finished_label = TLS_MD_CLIENT_FINISH_CONST, + .client_finished_label_len = TLS_MD_CLIENT_FINISH_CONST_SIZE, + .server_finished_label = TLS_MD_SERVER_FINISH_CONST, + .server_finished_label_len = TLS_MD_SERVER_FINISH_CONST_SIZE, + .alert_value = tls1_alert_code, + .export_keying_material = tls1_export_keying_material, + .enc_flags = SSL_ENC_FLAG_DTLS|SSL_ENC_FLAG_EXPLICIT_IV, +}; + +long +dtls1_default_timeout(void) +{ + /* 2 hours, the 24 hours mentioned in the DTLSv1 spec + * is way too long for http, the cache would over fill */ + return (60*60*2); +} + +int +dtls1_new(SSL *s) +{ + DTLS1_STATE *d1; + + if (!ssl3_new(s)) + return (0); + if ((d1 = calloc(1, sizeof *d1)) == NULL) { + ssl3_free(s); + return (0); + } + + /* d1->handshake_epoch=0; */ + + d1->unprocessed_rcds.q = pqueue_new(); + d1->processed_rcds.q = pqueue_new(); + d1->buffered_messages = pqueue_new(); + d1->sent_messages = pqueue_new(); + d1->buffered_app_data.q = pqueue_new(); + + if (s->server) { + d1->cookie_len = sizeof(s->d1->cookie); + } + + if (!d1->unprocessed_rcds.q || !d1->processed_rcds.q || + !d1->buffered_messages || !d1->sent_messages || + !d1->buffered_app_data.q) { + pqueue_free(d1->unprocessed_rcds.q); + pqueue_free(d1->processed_rcds.q); + pqueue_free(d1->buffered_messages); + pqueue_free(d1->sent_messages); + pqueue_free(d1->buffered_app_data.q); + free(d1); + ssl3_free(s); + return (0); + } + + s->d1 = d1; + s->method->ssl_clear(s); + return (1); +} + +static void +dtls1_clear_queues(SSL *s) +{ + pitem *item = NULL; + hm_fragment *frag = NULL; + DTLS1_RECORD_DATA *rdata; + + while ((item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) { + rdata = (DTLS1_RECORD_DATA *) item->data; + free(rdata->rbuf.buf); + free(item->data); + pitem_free(item); + } + + while ((item = pqueue_pop(s->d1->processed_rcds.q)) != NULL) { + rdata = (DTLS1_RECORD_DATA *) item->data; + free(rdata->rbuf.buf); + free(item->data); + pitem_free(item); + } + + while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) { + frag = (hm_fragment *)item->data; + free(frag->fragment); + free(frag); + pitem_free(item); + } + + while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) { + frag = (hm_fragment *)item->data; + free(frag->fragment); + free(frag); + pitem_free(item); + } + + while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) { + rdata = (DTLS1_RECORD_DATA *) item->data; + free(rdata->rbuf.buf); + free(item->data); + pitem_free(item); + } +} + +void +dtls1_free(SSL *s) +{ + if (s == NULL) + return; + + ssl3_free(s); + + dtls1_clear_queues(s); + + pqueue_free(s->d1->unprocessed_rcds.q); + pqueue_free(s->d1->processed_rcds.q); + pqueue_free(s->d1->buffered_messages); + pqueue_free(s->d1->sent_messages); + pqueue_free(s->d1->buffered_app_data.q); + + explicit_bzero(s->d1, sizeof *s->d1); + free(s->d1); + s->d1 = NULL; +} + +void +dtls1_clear(SSL *s) +{ + pqueue unprocessed_rcds; + pqueue processed_rcds; + pqueue buffered_messages; + pqueue sent_messages; + pqueue buffered_app_data; + unsigned int mtu; + + if (s->d1) { + unprocessed_rcds = s->d1->unprocessed_rcds.q; + processed_rcds = s->d1->processed_rcds.q; + buffered_messages = s->d1->buffered_messages; + sent_messages = s->d1->sent_messages; + buffered_app_data = s->d1->buffered_app_data.q; + mtu = s->d1->mtu; + + dtls1_clear_queues(s); + + memset(s->d1, 0, sizeof(*(s->d1))); + + if (s->server) { + s->d1->cookie_len = sizeof(s->d1->cookie); + } + + if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) { + s->d1->mtu = mtu; + } + + s->d1->unprocessed_rcds.q = unprocessed_rcds; + s->d1->processed_rcds.q = processed_rcds; + s->d1->buffered_messages = buffered_messages; + s->d1->sent_messages = sent_messages; + s->d1->buffered_app_data.q = buffered_app_data; + } + + ssl3_clear(s); + + s->version = DTLS1_VERSION; +} + +long +dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) +{ + int ret = 0; + + switch (cmd) { + case DTLS_CTRL_GET_TIMEOUT: + if (dtls1_get_timeout(s, (struct timeval*) parg) != NULL) { + ret = 1; + } + break; + case DTLS_CTRL_HANDLE_TIMEOUT: + ret = dtls1_handle_timeout(s); + break; + case DTLS_CTRL_LISTEN: + ret = dtls1_listen(s, parg); + break; + + default: + ret = ssl3_ctrl(s, cmd, larg, parg); + break; + } + return (ret); +} + +/* + * As it's impossible to use stream ciphers in "datagram" mode, this + * simple filter is designed to disengage them in DTLS. Unfortunately + * there is no universal way to identify stream SSL_CIPHER, so we have + * to explicitly list their SSL_* codes. Currently RC4 is the only one + * available, but if new ones emerge, they will have to be added... + */ +const SSL_CIPHER * +dtls1_get_cipher(unsigned int u) +{ + const SSL_CIPHER *ciph = ssl3_get_cipher(u); + + if (ciph != NULL) { + if (ciph->algorithm_enc == SSL_RC4) + return NULL; + } + + return ciph; +} + +void +dtls1_start_timer(SSL *s) +{ + + /* If timer is not set, initialize duration with 1 second */ + if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { + s->d1->timeout_duration = 1; + } + + /* Set timeout to current time */ + gettimeofday(&(s->d1->next_timeout), NULL); + + /* Add duration to current time */ + s->d1->next_timeout.tv_sec += s->d1->timeout_duration; + BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, + &(s->d1->next_timeout)); +} + +struct timeval* +dtls1_get_timeout(SSL *s, struct timeval* timeleft) +{ + struct timeval timenow; + + /* If no timeout is set, just return NULL */ + if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { + return NULL; + } + + /* Get current time */ + gettimeofday(&timenow, NULL); + + /* If timer already expired, set remaining time to 0 */ + if (s->d1->next_timeout.tv_sec < timenow.tv_sec || + (s->d1->next_timeout.tv_sec == timenow.tv_sec && + s->d1->next_timeout.tv_usec <= timenow.tv_usec)) { + memset(timeleft, 0, sizeof(struct timeval)); + return timeleft; + } + + /* Calculate time left until timer expires */ + memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval)); + timeleft->tv_sec -= timenow.tv_sec; + timeleft->tv_usec -= timenow.tv_usec; + if (timeleft->tv_usec < 0) { + timeleft->tv_sec--; + timeleft->tv_usec += 1000000; + } + + /* If remaining time is less than 15 ms, set it to 0 + * to prevent issues because of small devergences with + * socket timeouts. + */ + if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) { + memset(timeleft, 0, sizeof(struct timeval)); + } + + + return timeleft; +} + +int +dtls1_is_timer_expired(SSL *s) +{ + struct timeval timeleft; + + /* Get time left until timeout, return false if no timer running */ + if (dtls1_get_timeout(s, &timeleft) == NULL) { + return 0; + } + + /* Return false if timer is not expired yet */ + if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) { + return 0; + } + + /* Timer expired, so return true */ + return 1; +} + +void +dtls1_double_timeout(SSL *s) +{ + s->d1->timeout_duration *= 2; + if (s->d1->timeout_duration > 60) + s->d1->timeout_duration = 60; + dtls1_start_timer(s); +} + +void +dtls1_stop_timer(SSL *s) +{ + /* Reset everything */ + memset(&(s->d1->timeout), 0, sizeof(struct dtls1_timeout_st)); + memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); + s->d1->timeout_duration = 1; + BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, + &(s->d1->next_timeout)); + /* Clear retransmission buffer */ + dtls1_clear_record_buffer(s); +} + +int +dtls1_check_timeout_num(SSL *s) +{ + s->d1->timeout.num_alerts++; + + /* Reduce MTU after 2 unsuccessful retransmissions */ + if (s->d1->timeout.num_alerts > 2) { + s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), + BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL); + + } + + if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) { + /* fail the connection, enough alerts have been sent */ + SSLerr(SSL_F_DTLS1_CHECK_TIMEOUT_NUM, SSL_R_READ_TIMEOUT_EXPIRED); + return -1; + } + + return 0; +} + +int +dtls1_handle_timeout(SSL *s) +{ + /* if no timer is expired, don't do anything */ + if (!dtls1_is_timer_expired(s)) { + return 0; + } + + dtls1_double_timeout(s); + + if (dtls1_check_timeout_num(s) < 0) + return -1; + + s->d1->timeout.read_timeouts++; + if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) { + s->d1->timeout.read_timeouts = 1; + } + + dtls1_start_timer(s); + return dtls1_retransmit_buffered_messages(s); +} + +int +dtls1_listen(SSL *s, struct sockaddr *client) +{ + int ret; + + /* Ensure there is no state left over from a previous invocation */ + SSL_clear(s); + + SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE); + s->d1->listen = 1; + + ret = SSL_accept(s); + if (ret <= 0) + return ret; + + (void)BIO_dgram_get_peer(SSL_get_rbio(s), client); + return 1; +} + +void +dtls1_build_sequence_number(unsigned char *dst, unsigned char *seq, + unsigned short epoch) +{ + unsigned char dtlsseq[SSL3_SEQUENCE_SIZE]; + unsigned char *p; + + p = dtlsseq; + s2n(epoch, p); + memcpy(p, &seq[2], SSL3_SEQUENCE_SIZE - 2); + memcpy(dst, dtlsseq, SSL3_SEQUENCE_SIZE); +} diff --git a/crypto/libressl/ssl/d1_meth.c b/crypto/libressl/ssl/d1_meth.c new file mode 100644 index 0000000000..2169bae416 --- /dev/null +++ b/crypto/libressl/ssl/d1_meth.c @@ -0,0 +1,112 @@ +/* $OpenBSD: d1_meth.c,v 1.8 2014/12/14 15:30:50 jsing Exp $ */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include "ssl_locl.h" + +static const SSL_METHOD *dtls1_get_method(int ver); + +const SSL_METHOD DTLSv1_method_data = { + .version = DTLS1_VERSION, + .ssl_new = dtls1_new, + .ssl_clear = dtls1_clear, + .ssl_free = dtls1_free, + .ssl_accept = dtls1_accept, + .ssl_connect = dtls1_connect, + .ssl_read = ssl3_read, + .ssl_peek = ssl3_peek, + .ssl_write = ssl3_write, + .ssl_shutdown = dtls1_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_get_message = dtls1_get_message, + .ssl_read_bytes = dtls1_read_bytes, + .ssl_write_bytes = dtls1_write_app_data_bytes, + .ssl_dispatch_alert = dtls1_dispatch_alert, + .ssl_ctrl = dtls1_ctrl, + .ssl_ctx_ctrl = ssl3_ctx_ctrl, + .get_cipher_by_char = ssl3_get_cipher_by_char, + .put_cipher_by_char = ssl3_put_cipher_by_char, + .ssl_pending = ssl3_pending, + .num_ciphers = ssl3_num_ciphers, + .get_cipher = dtls1_get_cipher, + .get_ssl_method = dtls1_get_method, + .get_timeout = dtls1_default_timeout, + .ssl3_enc = &DTLSv1_enc_data, + .ssl_version = ssl_undefined_void_function, + .ssl_callback_ctrl = ssl3_callback_ctrl, + .ssl_ctx_callback_ctrl = ssl3_ctx_callback_ctrl, +}; + +const SSL_METHOD * +DTLSv1_method(void) +{ + return &DTLSv1_method_data; +} + +static const SSL_METHOD * +dtls1_get_method(int ver) +{ + if (ver == DTLS1_VERSION) + return (DTLSv1_method()); + return (NULL); +} diff --git a/crypto/libressl/ssl/d1_pkt.c b/crypto/libressl/ssl/d1_pkt.c new file mode 100644 index 0000000000..632376cf8d --- /dev/null +++ b/crypto/libressl/ssl/d1_pkt.c @@ -0,0 +1,1477 @@ +/* $OpenBSD: d1_pkt.c,v 1.47 2015/09/10 17:57:50 jsing Exp $ */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include + +#include "ssl_locl.h" + +#include +#include + +#include "pqueue.h" +#include "bytestring.h" + +/* mod 128 saturating subtract of two 64-bit values in big-endian order */ +static int +satsub64be(const unsigned char *v1, const unsigned char *v2) +{ + int ret, sat, brw, i; + + if (sizeof(long) == 8) + do { + long l; + + if (BYTE_ORDER == LITTLE_ENDIAN) + break; + /* not reached on little-endians */ + /* following test is redundant, because input is + * always aligned, but I take no chances... */ + if (((size_t)v1 | (size_t)v2) & 0x7) + break; + + l = *((long *)v1); + l -= *((long *)v2); + if (l > 128) + return 128; + else if (l<-128) + return -128; + else + return (int)l; + } while (0); + + ret = (int)v1[7] - (int)v2[7]; + sat = 0; + brw = ret >> 8; /* brw is either 0 or -1 */ + if (ret & 0x80) { + for (i = 6; i >= 0; i--) { + brw += (int)v1[i]-(int)v2[i]; + sat |= ~brw; + brw >>= 8; + } + } else { + for (i = 6; i >= 0; i--) { + brw += (int)v1[i]-(int)v2[i]; + sat |= brw; + brw >>= 8; + } + } + brw <<= 8; /* brw is either 0 or -256 */ + + if (sat & 0xff) + return brw | 0x80; + else + return brw + (ret & 0xFF); +} + +static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, + int len, int peek); +static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap); +static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap); +static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, + unsigned int *is_next_epoch); +static int dtls1_buffer_record(SSL *s, record_pqueue *q, + unsigned char *priority); +static int dtls1_process_record(SSL *s); + +/* copy buffered record into SSL structure */ +static int +dtls1_copy_record(SSL *s, pitem *item) +{ + DTLS1_RECORD_DATA *rdata; + + rdata = (DTLS1_RECORD_DATA *)item->data; + + free(s->s3->rbuf.buf); + + s->packet = rdata->packet; + s->packet_length = rdata->packet_length; + memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER)); + memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD)); + + /* Set proper sequence number for mac calculation */ + memcpy(&(s->s3->read_sequence[2]), &(rdata->packet[5]), 6); + + return (1); +} + + +static int +dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) +{ + DTLS1_RECORD_DATA *rdata; + pitem *item; + + /* Limit the size of the queue to prevent DOS attacks */ + if (pqueue_size(queue->q) >= 100) + return 0; + + rdata = malloc(sizeof(DTLS1_RECORD_DATA)); + item = pitem_new(priority, rdata); + if (rdata == NULL || item == NULL) + goto init_err; + + rdata->packet = s->packet; + rdata->packet_length = s->packet_length; + memcpy(&(rdata->rbuf), &(s->s3->rbuf), sizeof(SSL3_BUFFER)); + memcpy(&(rdata->rrec), &(s->s3->rrec), sizeof(SSL3_RECORD)); + + item->data = rdata; + + + s->packet = NULL; + s->packet_length = 0; + memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER)); + memset(&(s->s3->rrec), 0, sizeof(SSL3_RECORD)); + + if (!ssl3_setup_buffers(s)) + goto err; + + /* insert should not fail, since duplicates are dropped */ + if (pqueue_insert(queue->q, item) == NULL) + goto err; + + return (1); + +err: + free(rdata->rbuf.buf); + +init_err: + SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); + free(rdata); + pitem_free(item); + return (-1); +} + + +static int +dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue) +{ + pitem *item; + + item = pqueue_pop(queue->q); + if (item) { + dtls1_copy_record(s, item); + + free(item->data); + pitem_free(item); + + return (1); + } + + return (0); +} + + +/* retrieve a buffered record that belongs to the new epoch, i.e., not processed + * yet */ +#define dtls1_get_unprocessed_record(s) \ + dtls1_retrieve_buffered_record((s), \ + &((s)->d1->unprocessed_rcds)) + +/* retrieve a buffered record that belongs to the current epoch, ie, processed */ +#define dtls1_get_processed_record(s) \ + dtls1_retrieve_buffered_record((s), \ + &((s)->d1->processed_rcds)) + +static int +dtls1_process_buffered_records(SSL *s) +{ + pitem *item; + + item = pqueue_peek(s->d1->unprocessed_rcds.q); + if (item) { + /* Check if epoch is current. */ + if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch) + return (1); + /* Nothing to do. */ + + /* Process all the records. */ + while (pqueue_peek(s->d1->unprocessed_rcds.q)) { + dtls1_get_unprocessed_record(s); + if (! dtls1_process_record(s)) + return (0); + if (dtls1_buffer_record(s, &(s->d1->processed_rcds), + s->s3->rrec.seq_num) < 0) + return (-1); + } + } + + /* sync epoch numbers once all the unprocessed records + * have been processed */ + s->d1->processed_rcds.epoch = s->d1->r_epoch; + s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1; + + return (1); +} + +static int +dtls1_process_record(SSL *s) +{ + int i, al; + int enc_err; + SSL_SESSION *sess; + SSL3_RECORD *rr; + unsigned int mac_size, orig_len; + unsigned char md[EVP_MAX_MD_SIZE]; + + rr = &(s->s3->rrec); + sess = s->session; + + /* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, + * and we have that many bytes in s->packet + */ + rr->input = &(s->packet[DTLS1_RT_HEADER_LENGTH]); + + /* ok, we can now read from 's->packet' data into 'rr' + * rr->input points at rr->length bytes, which + * need to be copied into rr->data by either + * the decryption or by the decompression + * When the data is 'copied' into the rr->data buffer, + * rr->input will be pointed at the new buffer */ + + /* We now have - encrypted [ MAC [ compressed [ plain ] ] ] + * rr->length bytes of encrypted compressed stuff. */ + + /* check is not needed I believe */ + if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); + goto f_err; + } + + /* decrypt in place in 'rr->input' */ + rr->data = rr->input; + + enc_err = s->method->ssl3_enc->enc(s, 0); + /* enc_err is: + * 0: (in non-constant time) if the record is publically invalid. + * 1: if the padding is valid + * -1: if the padding is invalid */ + if (enc_err == 0) { + /* For DTLS we simply ignore bad packets. */ + rr->length = 0; + s->packet_length = 0; + goto err; + } + + + /* r->length is now the compressed data plus mac */ + if ((sess != NULL) && (s->enc_read_ctx != NULL) && + (EVP_MD_CTX_md(s->read_hash) != NULL)) { + /* s->read_hash != NULL => mac_size != -1 */ + unsigned char *mac = NULL; + unsigned char mac_tmp[EVP_MAX_MD_SIZE]; + mac_size = EVP_MD_CTX_size(s->read_hash); + OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); + + /* kludge: *_cbc_remove_padding passes padding length in rr->type */ + orig_len = rr->length + ((unsigned int)rr->type >> 8); + + /* orig_len is the length of the record before any padding was + * removed. This is public information, as is the MAC in use, + * therefore we can safely process the record in a different + * amount of time if it's too short to possibly contain a MAC. + */ + if (orig_len < mac_size || + /* CBC records must have a padding length byte too. */ + (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && + orig_len < mac_size + 1)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + + if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) { + /* We update the length so that the TLS header bytes + * can be constructed correctly but we need to extract + * the MAC in constant time from within the record, + * without leaking the contents of the padding bytes. + * */ + mac = mac_tmp; + ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); + rr->length -= mac_size; + } else { + /* In this case there's no padding, so |orig_len| + * equals |rec->length| and we checked that there's + * enough bytes for |mac_size| above. */ + rr->length -= mac_size; + mac = &rr->data[rr->length]; + } + + i = s->method->ssl3_enc->mac(s, md, 0 /* not send */); + if (i < 0 || mac == NULL || timingsafe_memcmp(md, mac, (size_t)mac_size) != 0) + enc_err = -1; + if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size) + enc_err = -1; + } + + if (enc_err < 0) { + /* decryption failed, silently discard message */ + rr->length = 0; + s->packet_length = 0; + goto err; + } + + if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_DATA_LENGTH_TOO_LONG); + goto f_err; + } + + rr->off = 0; + /* So at this point the following is true + * ssl->s3->rrec.type is the type of record + * ssl->s3->rrec.length == number of bytes in record + * ssl->s3->rrec.off == offset to first valid byte + * ssl->s3->rrec.data == where to take bytes from, increment + * after use :-). + */ + + /* we have pulled in a full packet so zero things */ + s->packet_length = 0; + return (1); + +f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); +err: + return (0); +} + + +/* Call this to get a new input record. + * It will return <= 0 if more data is needed, normally due to an error + * or non-blocking IO. + * When it finishes, one packet has been decoded and can be found in + * ssl->s3->rrec.type - is the type of record + * ssl->s3->rrec.data, - data + * ssl->s3->rrec.length, - number of bytes + */ +/* used only by dtls1_read_bytes */ +int +dtls1_get_record(SSL *s) +{ + int i, n; + SSL3_RECORD *rr; + unsigned char *p = NULL; + DTLS1_BITMAP *bitmap; + unsigned int is_next_epoch; + + rr = &(s->s3->rrec); + + /* The epoch may have changed. If so, process all the + * pending records. This is a non-blocking operation. */ + if (dtls1_process_buffered_records(s) < 0) + return (-1); + + /* if we're renegotiating, then there may be buffered records */ + if (dtls1_get_processed_record(s)) + return 1; + + /* get something from the wire */ + if (0) { +again: + /* dump this record on all retries */ + rr->length = 0; + s->packet_length = 0; + } + + /* check if we have the header */ + if ((s->rstate != SSL_ST_READ_BODY) || + (s->packet_length < DTLS1_RT_HEADER_LENGTH)) { + CBS header, seq_no; + uint16_t epoch, len, ssl_version; + uint8_t type; + + n = ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH, s->s3->rbuf.len, 0); + /* read timeout is handled by dtls1_read_bytes */ + if (n <= 0) + return(n); /* error or non-blocking */ + + /* this packet contained a partial record, dump it */ + if (s->packet_length != DTLS1_RT_HEADER_LENGTH) + goto again; + + s->rstate = SSL_ST_READ_BODY; + + CBS_init(&header, s->packet, s->packet_length); + + /* Pull apart the header into the DTLS1_RECORD */ + if (!CBS_get_u8(&header, &type)) + goto again; + if (!CBS_get_u16(&header, &ssl_version)) + goto again; + + /* sequence number is 64 bits, with top 2 bytes = epoch */ + if (!CBS_get_u16(&header, &epoch) || + !CBS_get_bytes(&header, &seq_no, 6)) + goto again; + + if (!CBS_write_bytes(&seq_no, &(s->s3->read_sequence[2]), + sizeof(s->s3->read_sequence) - 2, NULL)) + goto again; + if (!CBS_get_u16(&header, &len)) + goto again; + + rr->type = type; + rr->epoch = epoch; + rr->length = len; + + /* unexpected version, silently discard */ + if (!s->first_packet && ssl_version != s->version) + goto again; + + /* wrong version, silently discard record */ + if ((ssl_version & 0xff00) != (s->version & 0xff00)) + goto again; + + /* record too long, silently discard it */ + if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) + goto again; + + /* now s->rstate == SSL_ST_READ_BODY */ + p = (unsigned char *)CBS_data(&header); + } + + /* s->rstate == SSL_ST_READ_BODY, get and decode the data */ + + if (rr->length > s->packet_length - DTLS1_RT_HEADER_LENGTH) { + /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */ + i = rr->length; + n = ssl3_read_n(s, i, i, 1); + if (n <= 0) + return(n); /* error or non-blocking io */ + + /* this packet contained a partial record, dump it */ + if (n != i) + goto again; + + /* now n == rr->length, + * and s->packet_length == DTLS1_RT_HEADER_LENGTH + rr->length */ + } + s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */ + + /* match epochs. NULL means the packet is dropped on the floor */ + bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); + if (bitmap == NULL) + goto again; + + /* + * Check whether this is a repeat, or aged record. + * Don't check if we're listening and this message is + * a ClientHello. They can look as if they're replayed, + * since they arrive from different connections and + * would be dropped unnecessarily. + */ + if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE && + p != NULL && *p == SSL3_MT_CLIENT_HELLO) && + !dtls1_record_replay_check(s, bitmap)) + goto again; + + /* just read a 0 length packet */ + if (rr->length == 0) + goto again; + + /* If this record is from the next epoch (either HM or ALERT), + * and a handshake is currently in progress, buffer it since it + * cannot be processed at this time. However, do not buffer + * anything while listening. + */ + if (is_next_epoch) { + if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen) { + if (dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), + rr->seq_num) < 0) + return (-1); + /* Mark receipt of record. */ + dtls1_record_bitmap_update(s, bitmap); + } + goto again; + } + + if (!dtls1_process_record(s)) + goto again; + + /* Mark receipt of record. */ + dtls1_record_bitmap_update(s, bitmap); + + return (1); +} + +/* Return up to 'len' payload bytes received in 'type' records. + * 'type' is one of the following: + * + * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) + * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) + * - 0 (during a shutdown, no data has to be returned) + * + * If we don't have stored data to work from, read a SSL/TLS record first + * (possibly multiple records if we still don't have anything to return). + * + * This function must handle any surprises the peer may have for us, such as + * Alert records (e.g. close_notify), ChangeCipherSpec records (not really + * a surprise, but handled as if it were), or renegotiation requests. + * Also if record payloads contain fragments too small to process, we store + * them until there is enough for the respective protocol (the record protocol + * may use arbitrary fragmentation and even interleaving): + * Change cipher spec protocol + * just 1 byte needed, no need for keeping anything stored + * Alert protocol + * 2 bytes needed (AlertLevel, AlertDescription) + * Handshake protocol + * 4 bytes needed (HandshakeType, uint24 length) -- we just have + * to detect unexpected Client Hello and Hello Request messages + * here, anything else is handled by higher layers + * Application data protocol + * none of our business + */ +int +dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) +{ + int al, i, j, ret; + unsigned int n; + SSL3_RECORD *rr; + void (*cb)(const SSL *ssl, int type2, int val) = NULL; + + if (s->s3->rbuf.buf == NULL) /* Not initialized yet */ + if (!ssl3_setup_buffers(s)) + return (-1); + + if ((type && + type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_HANDSHAKE) || + (peek && (type != SSL3_RT_APPLICATION_DATA))) { + SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); + return -1; + } + + /* check whether there's a handshake message (client hello?) waiting */ + if ((ret = have_handshake_fragment(s, type, buf, len, peek))) + return ret; + + /* Now s->d1->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. */ + + if (!s->in_handshake && SSL_in_init(s)) + { + /* type == SSL3_RT_APPLICATION_DATA */ + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + } + +start: + s->rwstate = SSL_NOTHING; + + /* s->s3->rrec.type - is the type of record + * s->s3->rrec.data, - data + * s->s3->rrec.off, - offset into 'data' for next read + * s->s3->rrec.length, - number of bytes. */ + rr = &(s->s3->rrec); + + /* We are not handshaking and have no data yet, + * so process data buffered during the last handshake + * in advance, if any. + */ + if (s->state == SSL_ST_OK && rr->length == 0) { + pitem *item; + item = pqueue_pop(s->d1->buffered_app_data.q); + if (item) { + + dtls1_copy_record(s, item); + + free(item->data); + pitem_free(item); + } + } + + /* Check for timeout */ + if (dtls1_handle_timeout(s) > 0) + goto start; + + /* get new packet if necessary */ + if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY)) { + ret = dtls1_get_record(s); + if (ret <= 0) { + ret = dtls1_read_failed(s, ret); + /* anything other than a timeout is an error */ + if (ret <= 0) + return (ret); + else + goto start; + } + } + + if (s->d1->listen && rr->type != SSL3_RT_HANDSHAKE) { + rr->length = 0; + goto start; + } + + /* we now have a packet which can be read and processed */ + + if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, + * reset by ssl3_get_finished */ + && (rr->type != SSL3_RT_HANDSHAKE)) { + /* We now have application data between CCS and Finished. + * Most likely the packets were reordered on their way, so + * buffer the application data for later processing rather + * than dropping the connection. + */ + if (dtls1_buffer_record(s, &(s->d1->buffered_app_data), + rr->seq_num) < 0) { + SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); + return (-1); + } + rr->length = 0; + goto start; + } + + /* If the other end has shut down, throw anything we read away + * (even in 'peek' mode) */ + if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { + rr->length = 0; + s->rwstate = SSL_NOTHING; + return (0); + } + + + if (type == rr->type) /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */ + { + /* make sure that we are not getting application data when we + * are doing a handshake for the first time */ + if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && + (s->enc_read_ctx == NULL)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_APP_DATA_IN_HANDSHAKE); + goto f_err; + } + + if (len <= 0) + return (len); + + if ((unsigned int)len > rr->length) + n = rr->length; + else + n = (unsigned int)len; + + memcpy(buf, &(rr->data[rr->off]), n); + if (!peek) { + rr->length -= n; + rr->off += n; + if (rr->length == 0) { + s->rstate = SSL_ST_READ_HEADER; + rr->off = 0; + } + } + + return (n); + } + + + /* If we get here, then type != rr->type; if we have a handshake + * message, then it was unexpected (Hello Request or Client Hello). */ + + /* In case of record types for which we have 'fragment' storage, + * fill that so that we can process the data at a fixed place. + */ + { + unsigned int k, dest_maxlen = 0; + unsigned char *dest = NULL; + unsigned int *dest_len = NULL; + + if (rr->type == SSL3_RT_HANDSHAKE) { + dest_maxlen = sizeof s->d1->handshake_fragment; + dest = s->d1->handshake_fragment; + dest_len = &s->d1->handshake_fragment_len; + } else if (rr->type == SSL3_RT_ALERT) { + dest_maxlen = sizeof(s->d1->alert_fragment); + dest = s->d1->alert_fragment; + dest_len = &s->d1->alert_fragment_len; + } + /* else it's a CCS message, or application data or wrong */ + else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC) { + /* Application data while renegotiating + * is allowed. Try again reading. + */ + if (rr->type == SSL3_RT_APPLICATION_DATA) { + BIO *bio; + s->s3->in_read_app_data = 2; + bio = SSL_get_rbio(s); + s->rwstate = SSL_READING; + BIO_clear_retry_flags(bio); + BIO_set_retry_read(bio); + return (-1); + } + + /* Not certain if this is the right error handling */ + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD); + goto f_err; + } + + if (dest_maxlen > 0) { + /* XDTLS: In a pathalogical case, the Client Hello + * may be fragmented--don't always expect dest_maxlen bytes */ + if (rr->length < dest_maxlen) { +#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE + /* + * for normal alerts rr->length is 2, while + * dest_maxlen is 7 if we were to handle this + * non-existing alert... + */ + FIX ME +#endif + s->rstate = SSL_ST_READ_HEADER; + rr->length = 0; + goto start; + } + + /* now move 'n' bytes: */ + for ( k = 0; k < dest_maxlen; k++) { + dest[k] = rr->data[rr->off++]; + rr->length--; + } + *dest_len = dest_maxlen; + } + } + + /* s->d1->handshake_fragment_len == 12 iff rr->type == SSL3_RT_HANDSHAKE; + * s->d1->alert_fragment_len == 7 iff rr->type == SSL3_RT_ALERT. + * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */ + + /* If we are a client, check for an incoming 'Hello Request': */ + if ((!s->server) && + (s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && + (s->d1->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && + (s->session != NULL) && (s->session->cipher != NULL)) { + s->d1->handshake_fragment_len = 0; + + if ((s->d1->handshake_fragment[1] != 0) || + (s->d1->handshake_fragment[2] != 0) || + (s->d1->handshake_fragment[3] != 0)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_HELLO_REQUEST); + goto err; + } + + /* no need to check sequence number on HELLO REQUEST messages */ + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, + s->d1->handshake_fragment, 4, s, s->msg_callback_arg); + + if (SSL_is_init_finished(s) && + !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && + !s->s3->renegotiate) { + s->d1->handshake_read_seq++; + s->new_session = 1; + ssl3_renegotiate(s); + if (ssl3_renegotiate_check(s)) { + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + + if (!(s->mode & SSL_MODE_AUTO_RETRY)) { + if (s->s3->rbuf.left == 0) /* no read-ahead left? */ + { + BIO *bio; + /* In the case where we try to read application data, + * but we trigger an SSL handshake, we return -1 with + * the retry option set. Otherwise renegotiation may + * cause nasty problems in the blocking world */ + s->rwstate = SSL_READING; + bio = SSL_get_rbio(s); + BIO_clear_retry_flags(bio); + BIO_set_retry_read(bio); + return (-1); + } + } + } + } + /* we either finished a handshake or ignored the request, + * now try again to obtain the (application) data we were asked for */ + goto start; + } + + if (s->d1->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH) { + int alert_level = s->d1->alert_fragment[0]; + int alert_descr = s->d1->alert_fragment[1]; + + s->d1->alert_fragment_len = 0; + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_ALERT, + s->d1->alert_fragment, 2, s, s->msg_callback_arg); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + if (cb != NULL) { + j = (alert_level << 8) | alert_descr; + cb(s, SSL_CB_READ_ALERT, j); + } + + if (alert_level == 1) /* warning */ + { + s->s3->warn_alert = alert_descr; + if (alert_descr == SSL_AD_CLOSE_NOTIFY) { + s->shutdown |= SSL_RECEIVED_SHUTDOWN; + return (0); + } + } else if (alert_level == 2) /* fatal */ + { + s->rwstate = SSL_NOTHING; + s->s3->fatal_alert = alert_descr; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr); + ERR_asprintf_error_data("SSL alert number %d", + alert_descr); + s->shutdown|=SSL_RECEIVED_SHUTDOWN; + SSL_CTX_remove_session(s->ctx, s->session); + return (0); + } else { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNKNOWN_ALERT_TYPE); + goto f_err; + } + + goto start; + } + + if (s->shutdown & SSL_SENT_SHUTDOWN) /* but we have not received a shutdown */ + { + s->rwstate = SSL_NOTHING; + rr->length = 0; + return (0); + } + + if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { + struct ccs_header_st ccs_hdr; + unsigned int ccs_hdr_len = DTLS1_CCS_HEADER_LENGTH; + + dtls1_get_ccs_header(rr->data, &ccs_hdr); + + /* 'Change Cipher Spec' is just a single byte, so we know + * exactly what the record payload has to look like */ + /* XDTLS: check that epoch is consistent */ + if ((rr->length != ccs_hdr_len) || + (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) { + i = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_CHANGE_CIPHER_SPEC); + goto err; + } + + rr->length = 0; + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, + rr->data, 1, s, s->msg_callback_arg); + + /* We can't process a CCS now, because previous handshake + * messages are still missing, so just drop it. + */ + if (!s->d1->change_cipher_spec_ok) { + goto start; + } + + s->d1->change_cipher_spec_ok = 0; + + s->s3->change_cipher_spec = 1; + if (!ssl3_do_change_cipher_spec(s)) + goto err; + + /* do this whenever CCS is processed */ + dtls1_reset_seq_numbers(s, SSL3_CC_READ); + + goto start; + } + + /* Unexpected handshake message (Client Hello, or protocol violation) */ + if ((s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && + !s->in_handshake) { + struct hm_header_st msg_hdr; + + /* this may just be a stale retransmit */ + if (!dtls1_get_message_header(rr->data, &msg_hdr)) + return -1; + if (rr->epoch != s->d1->r_epoch) { + rr->length = 0; + goto start; + } + + /* If we are server, we may have a repeated FINISHED of the + * client here, then retransmit our CCS and FINISHED. + */ + if (msg_hdr.type == SSL3_MT_FINISHED) { + if (dtls1_check_timeout_num(s) < 0) + return -1; + + dtls1_retransmit_buffered_messages(s); + rr->length = 0; + goto start; + } + + if (((s->state&SSL_ST_MASK) == SSL_ST_OK) && + !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) { + s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; + s->renegotiate = 1; + s->new_session = 1; + } + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + + if (!(s->mode & SSL_MODE_AUTO_RETRY)) { + if (s->s3->rbuf.left == 0) /* no read-ahead left? */ + { + BIO *bio; + /* In the case where we try to read application data, + * but we trigger an SSL handshake, we return -1 with + * the retry option set. Otherwise renegotiation may + * cause nasty problems in the blocking world */ + s->rwstate = SSL_READING; + bio = SSL_get_rbio(s); + BIO_clear_retry_flags(bio); + BIO_set_retry_read(bio); + return (-1); + } + } + goto start; + } + + switch (rr->type) { + default: + /* TLS just ignores unknown message types */ + if (s->version == TLS1_VERSION) { + rr->length = 0; + goto start; + } + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD); + goto f_err; + case SSL3_RT_CHANGE_CIPHER_SPEC: + case SSL3_RT_ALERT: + case SSL3_RT_HANDSHAKE: + /* we already handled all of these, with the possible exception + * of SSL3_RT_HANDSHAKE when s->in_handshake is set, but that + * should not happen when type != rr->type */ + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); + goto f_err; + case SSL3_RT_APPLICATION_DATA: + /* At this point, we were expecting handshake data, + * but have application data. If the library was + * running inside ssl3_read() (i.e. in_read_app_data + * is set) and it makes sense to read application data + * at this point (session renegotiation not yet started), + * we will indulge it. + */ + if (s->s3->in_read_app_data && + (s->s3->total_renegotiations != 0) && + (((s->state & SSL_ST_CONNECT) && + (s->state >= SSL3_ST_CW_CLNT_HELLO_A) && + (s->state <= SSL3_ST_CR_SRVR_HELLO_A)) || ( + (s->state & SSL_ST_ACCEPT) && + (s->state <= SSL3_ST_SW_HELLO_REQ_A) && + (s->state >= SSL3_ST_SR_CLNT_HELLO_A)))) { + s->s3->in_read_app_data = 2; + return (-1); + } else { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD); + goto f_err; + } + } + /* not reached */ + +f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); +err: + return (-1); +} + +int +dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len) +{ + int i; + + if (SSL_in_init(s) && !s->in_handshake) + { + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); + return -1; + } + } + + if (len > SSL3_RT_MAX_PLAIN_LENGTH) { + SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES, SSL_R_DTLS_MESSAGE_TOO_BIG); + return -1; + } + + i = dtls1_write_bytes(s, type, buf_, len); + return i; +} + + + /* this only happens when a client hello is received and a handshake + * is started. */ +static int +have_handshake_fragment(SSL *s, int type, unsigned char *buf, + int len, int peek) +{ + + if ((type == SSL3_RT_HANDSHAKE) && (s->d1->handshake_fragment_len > 0)) + /* (partially) satisfy request from storage */ + { + unsigned char *src = s->d1->handshake_fragment; + unsigned char *dst = buf; + unsigned int k, n; + + /* peek == 0 */ + n = 0; + while ((len > 0) && (s->d1->handshake_fragment_len > 0)) { + *dst++ = *src++; + len--; + s->d1->handshake_fragment_len--; + n++; + } + /* move any remaining fragment bytes: */ + for (k = 0; k < s->d1->handshake_fragment_len; k++) + s->d1->handshake_fragment[k] = *src++; + return n; + } + + return 0; +} + + +/* Call this to write data in records of type 'type' + * It will return <= 0 if not all data has been sent or non-blocking IO. + */ +int +dtls1_write_bytes(SSL *s, int type, const void *buf, int len) +{ + int i; + + OPENSSL_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH); + s->rwstate = SSL_NOTHING; + i = do_dtls1_write(s, type, buf, len); + return i; +} + +int +do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len) +{ + unsigned char *p, *pseq; + int i, mac_size, clear = 0; + int prefix_len = 0; + SSL3_RECORD *wr; + SSL3_BUFFER *wb; + SSL_SESSION *sess; + int bs; + + /* first check if there is a SSL3_BUFFER still being written + * out. This will happen with non blocking IO */ + if (s->s3->wbuf.left != 0) { + OPENSSL_assert(0); /* XDTLS: want to see if we ever get here */ + return (ssl3_write_pending(s, type, buf, len)); + } + + /* If we have an alert to send, lets send it */ + if (s->s3->alert_dispatch) { + i = s->method->ssl_dispatch_alert(s); + if (i <= 0) + return (i); + /* if it went, fall through and send more stuff */ + } + + if (len == 0) + return 0; + + wr = &(s->s3->wrec); + wb = &(s->s3->wbuf); + sess = s->session; + + if ((sess == NULL) || (s->enc_write_ctx == NULL) || + (EVP_MD_CTX_md(s->write_hash) == NULL)) + clear = 1; + + if (clear) + mac_size = 0; + else { + mac_size = EVP_MD_CTX_size(s->write_hash); + if (mac_size < 0) + goto err; + } + + /* DTLS implements explicit IV, so no need for empty fragments. */ + + p = wb->buf + prefix_len; + + /* write the header */ + + *(p++) = type&0xff; + wr->type = type; + + *(p++) = (s->version >> 8); + *(p++) = s->version&0xff; + + /* field where we are to write out packet epoch, seq num and len */ + pseq = p; + + p += 10; + + /* lets setup the record stuff. */ + + /* Make space for the explicit IV in case of CBC. + * (this is a bit of a boundary violation, but what the heck). + */ + if (s->enc_write_ctx && + (EVP_CIPHER_mode( s->enc_write_ctx->cipher ) & EVP_CIPH_CBC_MODE)) + bs = EVP_CIPHER_block_size(s->enc_write_ctx->cipher); + else + bs = 0; + + wr->data = p + bs; + /* make room for IV in case of CBC */ + wr->length = (int)len; + wr->input = (unsigned char *)buf; + + /* we now 'read' from wr->input, wr->length bytes into + * wr->data */ + + memcpy(wr->data, wr->input, wr->length); + wr->input = wr->data; + + /* we should still have the output to wr->data and the input + * from wr->input. Length should be wr->length. + * wr->data still points in the wb->buf */ + + if (mac_size != 0) { + if (s->method->ssl3_enc->mac(s, &(p[wr->length + bs]), 1) < 0) + goto err; + wr->length += mac_size; + } + + /* this is true regardless of mac size */ + wr->input = p; + wr->data = p; + + + /* ssl3_enc can only have an error on read */ + if (bs) /* bs != 0 in case of CBC */ + { + arc4random_buf(p, bs); + /* master IV and last CBC residue stand for + * the rest of randomness */ + wr->length += bs; + } + + s->method->ssl3_enc->enc(s, 1); + + /* record length after mac and block padding */ +/* if (type == SSL3_RT_APPLICATION_DATA || + (type == SSL3_RT_ALERT && ! SSL_in_init(s))) */ + + /* there's only one epoch between handshake and app data */ + + s2n(s->d1->w_epoch, pseq); + + /* XDTLS: ?? */ +/* else + s2n(s->d1->handshake_epoch, pseq); +*/ + + memcpy(pseq, &(s->s3->write_sequence[2]), 6); + pseq += 6; + s2n(wr->length, pseq); + + /* we should now have + * wr->data pointing to the encrypted data, which is + * wr->length long */ + wr->type=type; /* not needed but helps for debugging */ + wr->length += DTLS1_RT_HEADER_LENGTH; + + tls1_record_sequence_increment(s->s3->write_sequence); + + /* now let's set up wb */ + wb->left = prefix_len + wr->length; + wb->offset = 0; + + /* memorize arguments so that ssl3_write_pending can detect bad write retries later */ + s->s3->wpend_tot = len; + s->s3->wpend_buf = buf; + s->s3->wpend_type = type; + s->s3->wpend_ret = len; + + /* we now just need to write the buffer */ + return ssl3_write_pending(s, type, buf, len); +err: + return -1; +} + + + +static int +dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap) +{ + int cmp; + unsigned int shift; + const unsigned char *seq = s->s3->read_sequence; + + cmp = satsub64be(seq, bitmap->max_seq_num); + if (cmp > 0) { + memcpy (s->s3->rrec.seq_num, seq, 8); + return 1; /* this record in new */ + } + shift = -cmp; + if (shift >= sizeof(bitmap->map)*8) + return 0; /* stale, outside the window */ + else if (bitmap->map & (1UL << shift)) + return 0; /* record previously received */ + + memcpy(s->s3->rrec.seq_num, seq, 8); + return 1; +} + + +static void +dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap) +{ + int cmp; + unsigned int shift; + const unsigned char *seq = s->s3->read_sequence; + + cmp = satsub64be(seq, bitmap->max_seq_num); + if (cmp > 0) { + shift = cmp; + if (shift < sizeof(bitmap->map)*8) + bitmap->map <<= shift, bitmap->map |= 1UL; + else + bitmap->map = 1UL; + memcpy(bitmap->max_seq_num, seq, 8); + } else { + shift = -cmp; + if (shift < sizeof(bitmap->map) * 8) + bitmap->map |= 1UL << shift; + } +} + + +int +dtls1_dispatch_alert(SSL *s) +{ + int i, j; + void (*cb)(const SSL *ssl, int type, int val) = NULL; + unsigned char buf[DTLS1_AL_HEADER_LENGTH]; + unsigned char *ptr = &buf[0]; + + s->s3->alert_dispatch = 0; + + memset(buf, 0x00, sizeof(buf)); + *ptr++ = s->s3->send_alert[0]; + *ptr++ = s->s3->send_alert[1]; + +#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE + if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) { + s2n(s->d1->handshake_read_seq, ptr); + l2n3(s->d1->r_msg_hdr.frag_off, ptr); + } +#endif + + i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf)); + if (i <= 0) { + s->s3->alert_dispatch = 1; + /* fprintf( stderr, "not done with alert\n" ); */ + } else { + if (s->s3->send_alert[0] == SSL3_AL_FATAL +#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE + || s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE +#endif + ) + (void)BIO_flush(s->wbio); + + if (s->msg_callback) + s->msg_callback(1, s->version, SSL3_RT_ALERT, + s->s3->send_alert, 2, s, s->msg_callback_arg); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + if (cb != NULL) { + j = (s->s3->send_alert[0]<<8)|s->s3->send_alert[1]; + cb(s, SSL_CB_WRITE_ALERT, j); + } + } + return (i); +} + + +static DTLS1_BITMAP * +dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, unsigned int *is_next_epoch) +{ + + *is_next_epoch = 0; + + /* In current epoch, accept HM, CCS, DATA, & ALERT */ + if (rr->epoch == s->d1->r_epoch) + return &s->d1->bitmap; + + /* Only HM and ALERT messages can be from the next epoch */ + else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) && + (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) { + *is_next_epoch = 1; + return &s->d1->next_bitmap; + } + + return NULL; +} + +void +dtls1_reset_seq_numbers(SSL *s, int rw) +{ + unsigned char *seq; + unsigned int seq_bytes = sizeof(s->s3->read_sequence); + + if (rw & SSL3_CC_READ) { + seq = s->s3->read_sequence; + s->d1->r_epoch++; + memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP)); + memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP)); + } else { + seq = s->s3->write_sequence; + memcpy(s->d1->last_write_sequence, seq, sizeof(s->s3->write_sequence)); + s->d1->w_epoch++; + } + + memset(seq, 0x00, seq_bytes); +} diff --git a/crypto/libressl/ssl/d1_srtp.c b/crypto/libressl/ssl/d1_srtp.c new file mode 100644 index 0000000000..feaf34d5e5 --- /dev/null +++ b/crypto/libressl/ssl/d1_srtp.c @@ -0,0 +1,473 @@ +/* $OpenBSD: d1_srtp.c,v 1.14 2015/07/17 17:36:24 doug Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* + * DTLS code by Eric Rescorla + * + * Copyright (C) 2006, Network Resonance, Inc. + * Copyright (C) 2011, RTFM, Inc. + */ + +#include + +#include + +#include "ssl_locl.h" + +#ifndef OPENSSL_NO_SRTP + +#include "bytestring.h" +#include "srtp.h" + +static SRTP_PROTECTION_PROFILE srtp_known_profiles[] = { + { + "SRTP_AES128_CM_SHA1_80", + SRTP_AES128_CM_SHA1_80, + }, + { + "SRTP_AES128_CM_SHA1_32", + SRTP_AES128_CM_SHA1_32, + }, + {0} +}; + +static int +find_profile_by_name(char *profile_name, SRTP_PROTECTION_PROFILE **pptr, + unsigned len) +{ + SRTP_PROTECTION_PROFILE *p; + + p = srtp_known_profiles; + while (p->name) { + if ((len == strlen(p->name)) && + !strncmp(p->name, profile_name, len)) { + *pptr = p; + return 0; + } + + p++; + } + + return 1; +} + +static int +find_profile_by_num(unsigned profile_num, SRTP_PROTECTION_PROFILE **pptr) +{ + SRTP_PROTECTION_PROFILE *p; + + p = srtp_known_profiles; + while (p->name) { + if (p->id == profile_num) { + *pptr = p; + return 0; + } + p++; + } + + return 1; +} + +static int +ssl_ctx_make_profiles(const char *profiles_string, + STACK_OF(SRTP_PROTECTION_PROFILE) **out) +{ + STACK_OF(SRTP_PROTECTION_PROFILE) *profiles; + + char *col; + char *ptr = (char *)profiles_string; + + SRTP_PROTECTION_PROFILE *p; + + if (!(profiles = sk_SRTP_PROTECTION_PROFILE_new_null())) { + SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, + SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES); + return 1; + } + + do { + col = strchr(ptr, ':'); + + if (!find_profile_by_name(ptr, &p, + col ? col - ptr : (int)strlen(ptr))) { + sk_SRTP_PROTECTION_PROFILE_push(profiles, p); + } else { + SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, + SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE); + sk_SRTP_PROTECTION_PROFILE_free(profiles); + return 1; + } + + if (col) + ptr = col + 1; + } while (col); + + *out = profiles; + + return 0; +} + +int +SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles) +{ + return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles); +} + +int +SSL_set_tlsext_use_srtp(SSL *s, const char *profiles) +{ + return ssl_ctx_make_profiles(profiles, &s->srtp_profiles); +} + + +STACK_OF(SRTP_PROTECTION_PROFILE) * +SSL_get_srtp_profiles(SSL *s) +{ + if (s != NULL) { + if (s->srtp_profiles != NULL) { + return s->srtp_profiles; + } else if ((s->ctx != NULL) && + (s->ctx->srtp_profiles != NULL)) { + return s->ctx->srtp_profiles; + } + } + + return NULL; +} + +SRTP_PROTECTION_PROFILE * +SSL_get_selected_srtp_profile(SSL *s) +{ + return s->srtp_profile; +} + +/* Note: this function returns 0 length if there are no + profiles specified */ +int +ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen) +{ + int ct = 0; + int i; + STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = 0; + SRTP_PROTECTION_PROFILE *prof; + + clnt = SSL_get_srtp_profiles(s); + + ct = sk_SRTP_PROTECTION_PROFILE_num(clnt); /* -1 if clnt == 0 */ + + if (p) { + if (ct == 0) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT, + SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST); + return 1; + } + + if ((2 + ct * 2 + 1) > maxlen) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT, + SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG); + return 1; + } + + /* Add the length */ + s2n(ct * 2, p); + for (i = 0; i < ct; i++) { + prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i); + s2n(prof->id, p); + } + + /* Add an empty use_mki value */ + *p++ = 0; + } + + *len = 2 + ct*2 + 1; + + return 0; +} + + +int +ssl_parse_clienthello_use_srtp_ext(SSL *s, const unsigned char *d, int len, + int *al) +{ + SRTP_PROTECTION_PROFILE *cprof, *sprof; + STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = 0, *srvr; + int i, j; + int ret = 1; + uint16_t id; + CBS cbs, ciphers, mki; + + if (len < 0) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *al = SSL_AD_DECODE_ERROR; + goto done; + } + + CBS_init(&cbs, d, len); + /* Pull off the cipher suite list */ + if (!CBS_get_u16_length_prefixed(&cbs, &ciphers) || + CBS_len(&ciphers) % 2) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *al = SSL_AD_DECODE_ERROR; + goto done; + } + + clnt = sk_SRTP_PROTECTION_PROFILE_new_null(); + + while (CBS_len(&ciphers) > 0) { + if (!CBS_get_u16(&ciphers, &id)) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *al = SSL_AD_DECODE_ERROR; + goto done; + } + + if (!find_profile_by_num(id, &cprof)) + sk_SRTP_PROTECTION_PROFILE_push(clnt, cprof); + else + ; /* Ignore */ + } + + /* Extract the MKI value as a sanity check, but discard it for now. */ + if (!CBS_get_u8_length_prefixed(&cbs, &mki) || + CBS_len(&cbs) != 0) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_MKI_VALUE); + *al = SSL_AD_DECODE_ERROR; + goto done; + } + + srvr = SSL_get_srtp_profiles(s); + + /* + * Pick our most preferred profile. If no profiles have been + * configured then the outer loop doesn't run + * (sk_SRTP_PROTECTION_PROFILE_num() = -1) + * and so we just return without doing anything. + */ + for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(srvr); i++) { + sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i); + + for (j = 0; j < sk_SRTP_PROTECTION_PROFILE_num(clnt); j++) { + cprof = sk_SRTP_PROTECTION_PROFILE_value(clnt, j); + + if (cprof->id == sprof->id) { + s->srtp_profile = sprof; + *al = 0; + ret = 0; + goto done; + } + } + } + + ret = 0; + +done: + if (clnt) + sk_SRTP_PROTECTION_PROFILE_free(clnt); + + return ret; +} + +int +ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen) +{ + if (p) { + if (maxlen < 5) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT, + SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG); + return 1; + } + + if (s->srtp_profile == 0) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT, + SSL_R_USE_SRTP_NOT_NEGOTIATED); + return 1; + } + s2n(2, p); + s2n(s->srtp_profile->id, p); + *p++ = 0; + } + *len = 5; + + return 0; +} + + +int +ssl_parse_serverhello_use_srtp_ext(SSL *s, const unsigned char *d, int len, int *al) +{ + STACK_OF(SRTP_PROTECTION_PROFILE) *clnt; + SRTP_PROTECTION_PROFILE *prof; + int i; + uint16_t id; + CBS cbs, profile_ids, mki; + + if (len < 0) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *al = SSL_AD_DECODE_ERROR; + return 1; + } + + CBS_init(&cbs, d, len); + + /* + * As per RFC 5764 section 4.1.1, server response MUST be a single + * profile id. + */ + if (!CBS_get_u16_length_prefixed(&cbs, &profile_ids) || + !CBS_get_u16(&profile_ids, &id) || CBS_len(&profile_ids) != 0) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *al = SSL_AD_DECODE_ERROR; + return 1; + } + + /* Must be no MKI, since we never offer one. */ + if (!CBS_get_u8_length_prefixed(&cbs, &mki) || CBS_len(&mki) != 0) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_MKI_VALUE); + *al = SSL_AD_ILLEGAL_PARAMETER; + return 1; + } + + clnt = SSL_get_srtp_profiles(s); + + /* Throw an error if the server gave us an unsolicited extension. */ + if (clnt == NULL) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, + SSL_R_NO_SRTP_PROFILES); + *al = SSL_AD_DECODE_ERROR; + return 1; + } + + /* + * Check to see if the server gave us something we support + * (and presumably offered). + */ + for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(clnt); i++) { + prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i); + + if (prof->id == id) { + s->srtp_profile = prof; + *al = 0; + return 0; + } + } + + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *al = SSL_AD_DECODE_ERROR; + return 1; +} + +#endif diff --git a/crypto/libressl/ssl/d1_srvr.c b/crypto/libressl/ssl/d1_srvr.c new file mode 100644 index 0000000000..f8e07031cd --- /dev/null +++ b/crypto/libressl/ssl/d1_srvr.c @@ -0,0 +1,751 @@ +/* $OpenBSD: d1_srvr.c,v 1.66 2015/09/12 20:51:33 jsing Exp $ */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include "ssl_locl.h" + +#include +#include +#include +#include +#include +#include +#include + +static const SSL_METHOD *dtls1_get_server_method(int ver); +static int dtls1_send_hello_verify_request(SSL *s); + +const SSL_METHOD DTLSv1_server_method_data = { + .version = DTLS1_VERSION, + .ssl_new = dtls1_new, + .ssl_clear = dtls1_clear, + .ssl_free = dtls1_free, + .ssl_accept = dtls1_accept, + .ssl_connect = ssl_undefined_function, + .ssl_read = ssl3_read, + .ssl_peek = ssl3_peek, + .ssl_write = ssl3_write, + .ssl_shutdown = dtls1_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_get_message = dtls1_get_message, + .ssl_read_bytes = dtls1_read_bytes, + .ssl_write_bytes = dtls1_write_app_data_bytes, + .ssl_dispatch_alert = dtls1_dispatch_alert, + .ssl_ctrl = dtls1_ctrl, + .ssl_ctx_ctrl = ssl3_ctx_ctrl, + .get_cipher_by_char = ssl3_get_cipher_by_char, + .put_cipher_by_char = ssl3_put_cipher_by_char, + .ssl_pending = ssl3_pending, + .num_ciphers = ssl3_num_ciphers, + .get_cipher = dtls1_get_cipher, + .get_ssl_method = dtls1_get_server_method, + .get_timeout = dtls1_default_timeout, + .ssl3_enc = &DTLSv1_enc_data, + .ssl_version = ssl_undefined_void_function, + .ssl_callback_ctrl = ssl3_callback_ctrl, + .ssl_ctx_callback_ctrl = ssl3_ctx_callback_ctrl, +}; + +const SSL_METHOD * +DTLSv1_server_method(void) +{ + return &DTLSv1_server_method_data; +} + +static const SSL_METHOD * +dtls1_get_server_method(int ver) +{ + if (ver == DTLS1_VERSION) + return (DTLSv1_server_method()); + return (NULL); +} + +int +dtls1_accept(SSL *s) +{ + void (*cb)(const SSL *ssl, int type, int val) = NULL; + unsigned long alg_k; + int ret = -1; + int new_state, state, skip = 0; + int listen; + + ERR_clear_error(); + errno = 0; + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + listen = s->d1->listen; + + /* init things to blank */ + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + + s->d1->listen = listen; + + if (s->cert == NULL) { + SSLerr(SSL_F_DTLS1_ACCEPT, SSL_R_NO_CERTIFICATE_SET); + ret = -1; + goto end; + } + + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_RENEGOTIATE: + s->renegotiate = 1; + /* s->state=SSL_ST_ACCEPT; */ + + case SSL_ST_BEFORE: + case SSL_ST_ACCEPT: + case SSL_ST_BEFORE|SSL_ST_ACCEPT: + case SSL_ST_OK|SSL_ST_ACCEPT: + + s->server = 1; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00)) { + SSLerr(SSL_F_DTLS1_ACCEPT, ERR_R_INTERNAL_ERROR); + ret = -1; + goto end; + } + s->type = SSL_ST_ACCEPT; + + if (!ssl3_setup_init_buffer(s)) { + ret = -1; + goto end; + } + if (!ssl3_setup_buffers(s)) { + ret = -1; + goto end; + } + + s->init_num = 0; + + if (s->state != SSL_ST_RENEGOTIATE) { + /* Ok, we now need to push on a buffering BIO so that + * the output is sent in a way that TCP likes :-) + * ...but not with SCTP :-) + */ + if (!ssl_init_wbio_buffer(s, 1)) { + ret = -1; + goto end; + } + + if (!tls1_init_finished_mac(s)) { + ret = -1; + goto end; + } + + s->state = SSL3_ST_SR_CLNT_HELLO_A; + s->ctx->stats.sess_accept++; + } else { + /* s->state == SSL_ST_RENEGOTIATE, + * we will just send a HelloRequest */ + s->ctx->stats.sess_accept_renegotiate++; + s->state = SSL3_ST_SW_HELLO_REQ_A; + } + + break; + + case SSL3_ST_SW_HELLO_REQ_A: + case SSL3_ST_SW_HELLO_REQ_B: + + s->shutdown = 0; + dtls1_clear_record_buffer(s); + dtls1_start_timer(s); + ret = ssl3_send_hello_request(s); + if (ret <= 0) + goto end; + s->s3->tmp.next_state = SSL3_ST_SR_CLNT_HELLO_A; + s->state = SSL3_ST_SW_FLUSH; + s->init_num = 0; + + if (!tls1_init_finished_mac(s)) { + ret = -1; + goto end; + } + break; + + case SSL3_ST_SW_HELLO_REQ_C: + s->state = SSL_ST_OK; + break; + + case SSL3_ST_SR_CLNT_HELLO_A: + case SSL3_ST_SR_CLNT_HELLO_B: + case SSL3_ST_SR_CLNT_HELLO_C: + + s->shutdown = 0; + ret = ssl3_get_client_hello(s); + if (ret <= 0) + goto end; + dtls1_stop_timer(s); + + if (ret == 1 && (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE)) + s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A; + else + s->state = SSL3_ST_SW_SRVR_HELLO_A; + + s->init_num = 0; + + /* Reflect ClientHello sequence to remain stateless while listening */ + if (listen) { + memcpy(s->s3->write_sequence, s->s3->read_sequence, sizeof(s->s3->write_sequence)); + } + + /* If we're just listening, stop here */ + if (listen && s->state == SSL3_ST_SW_SRVR_HELLO_A) { + ret = 2; + s->d1->listen = 0; + /* Set expected sequence numbers + * to continue the handshake. + */ + s->d1->handshake_read_seq = 2; + s->d1->handshake_write_seq = 1; + s->d1->next_handshake_write_seq = 1; + goto end; + } + + break; + + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: + + ret = dtls1_send_hello_verify_request(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_FLUSH; + s->s3->tmp.next_state = SSL3_ST_SR_CLNT_HELLO_A; + + /* HelloVerifyRequest resets Finished MAC */ + if (!tls1_init_finished_mac(s)) { + ret = -1; + goto end; + } + break; + + + case SSL3_ST_SW_SRVR_HELLO_A: + case SSL3_ST_SW_SRVR_HELLO_B: + s->renegotiate = 2; + dtls1_start_timer(s); + ret = ssl3_send_server_hello(s); + if (ret <= 0) + goto end; + + if (s->hit) { + if (s->tlsext_ticket_expected) + s->state = SSL3_ST_SW_SESSION_TICKET_A; + else + s->state = SSL3_ST_SW_CHANGE_A; + } else + s->state = SSL3_ST_SW_CERT_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_A: + case SSL3_ST_SW_CERT_B: + /* Check if it is anon DH. */ + if (!(s->s3->tmp.new_cipher->algorithm_auth & + SSL_aNULL)) { + dtls1_start_timer(s); + ret = dtls1_send_server_certificate(s); + if (ret <= 0) + goto end; + if (s->tlsext_status_expected) + s->state = SSL3_ST_SW_CERT_STATUS_A; + else + s->state = SSL3_ST_SW_KEY_EXCH_A; + } else { + skip = 1; + s->state = SSL3_ST_SW_KEY_EXCH_A; + } + s->init_num = 0; + break; + + case SSL3_ST_SW_KEY_EXCH_A: + case SSL3_ST_SW_KEY_EXCH_B: + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + + /* Only send if using a DH key exchange. */ + if (alg_k & (SSL_kDHE|SSL_kECDHE)) { + dtls1_start_timer(s); + ret = ssl3_send_server_key_exchange(s); + if (ret <= 0) + goto end; + } else + skip = 1; + + s->state = SSL3_ST_SW_CERT_REQ_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_REQ_A: + case SSL3_ST_SW_CERT_REQ_B: + /* + * Determine whether or not we need to request a + * certificate. + * + * Do not request a certificate if: + * + * - We did not ask for it (SSL_VERIFY_PEER is unset). + * + * - SSL_VERIFY_CLIENT_ONCE is set and we are + * renegotiating. + * + * - We are using an anonymous ciphersuites + * (see section "Certificate request" in SSL 3 drafts + * and in RFC 2246) ... except when the application + * insists on verification (against the specs, but + * s3_clnt.c accepts this for SSL 3). + */ + if (!(s->verify_mode & SSL_VERIFY_PEER) || + ((s->session->peer != NULL) && + (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) || + ((s->s3->tmp.new_cipher->algorithm_auth & + SSL_aNULL) && !(s->verify_mode & + SSL_VERIFY_FAIL_IF_NO_PEER_CERT))) { + /* no cert request */ + skip = 1; + s->s3->tmp.cert_request = 0; + s->state = SSL3_ST_SW_SRVR_DONE_A; + } else { + s->s3->tmp.cert_request = 1; + dtls1_start_timer(s); + ret = ssl3_send_certificate_request(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_SRVR_DONE_A; + s->init_num = 0; + } + break; + + case SSL3_ST_SW_SRVR_DONE_A: + case SSL3_ST_SW_SRVR_DONE_B: + dtls1_start_timer(s); + ret = ssl3_send_server_done(s); + if (ret <= 0) + goto end; + s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; + s->state = SSL3_ST_SW_FLUSH; + s->init_num = 0; + break; + + case SSL3_ST_SW_FLUSH: + s->rwstate = SSL_WRITING; + if (BIO_flush(s->wbio) <= 0) { + /* If the write error was fatal, stop trying */ + if (!BIO_should_retry(s->wbio)) { + s->rwstate = SSL_NOTHING; + s->state = s->s3->tmp.next_state; + } + + ret = -1; + goto end; + } + s->rwstate = SSL_NOTHING; + s->state = s->s3->tmp.next_state; + break; + + case SSL3_ST_SR_CERT_A: + case SSL3_ST_SR_CERT_B: + if (s->s3->tmp.cert_request) { + ret = ssl3_get_client_certificate(s); + if (ret <= 0) + goto end; + } + s->init_num = 0; + s->state = SSL3_ST_SR_KEY_EXCH_A; + break; + + case SSL3_ST_SR_KEY_EXCH_A: + case SSL3_ST_SR_KEY_EXCH_B: + ret = ssl3_get_client_key_exchange(s); + if (ret <= 0) + goto end; + + s->state = SSL3_ST_SR_CERT_VRFY_A; + s->init_num = 0; + + if (ret == 2) { + /* For the ECDH ciphersuites when + * the client sends its ECDH pub key in + * a certificate, the CertificateVerify + * message is not sent. + */ + s->state = SSL3_ST_SR_FINISHED_A; + s->init_num = 0; + } else if (SSL_USE_SIGALGS(s)) { + s->state = SSL3_ST_SR_CERT_VRFY_A; + s->init_num = 0; + if (!s->session->peer) + break; + + /* + * For sigalgs freeze the handshake buffer + * at this point and digest cached records. + */ + if (!s->s3->handshake_buffer) { + SSLerr(SSL_F_SSL3_ACCEPT, + ERR_R_INTERNAL_ERROR); + ret = -1; + goto end; + } + s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE; + if (!tls1_digest_cached_records(s)) { + ret = -1; + goto end; + } + } else { + s->state = SSL3_ST_SR_CERT_VRFY_A; + s->init_num = 0; + + /* We need to get hashes here so if there is + * a client cert, it can be verified */ + s->method->ssl3_enc->cert_verify_mac(s, + NID_md5, &(s->s3->tmp.cert_verify_md[0])); + s->method->ssl3_enc->cert_verify_mac(s, + NID_sha1, + &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH])); + } + break; + + case SSL3_ST_SR_CERT_VRFY_A: + case SSL3_ST_SR_CERT_VRFY_B: + + s->d1->change_cipher_spec_ok = 1; + /* we should decide if we expected this one */ + ret = ssl3_get_cert_verify(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SR_FINISHED_A; + s->init_num = 0; + break; + + case SSL3_ST_SR_FINISHED_A: + case SSL3_ST_SR_FINISHED_B: + s->d1->change_cipher_spec_ok = 1; + ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A, + SSL3_ST_SR_FINISHED_B); + if (ret <= 0) + goto end; + dtls1_stop_timer(s); + if (s->hit) + s->state = SSL_ST_OK; + else if (s->tlsext_ticket_expected) + s->state = SSL3_ST_SW_SESSION_TICKET_A; + else + s->state = SSL3_ST_SW_CHANGE_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_SESSION_TICKET_A: + case SSL3_ST_SW_SESSION_TICKET_B: + ret = ssl3_send_newsession_ticket(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_CHANGE_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_STATUS_A: + case SSL3_ST_SW_CERT_STATUS_B: + ret = ssl3_send_cert_status(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_KEY_EXCH_A; + s->init_num = 0; + break; + + + case SSL3_ST_SW_CHANGE_A: + case SSL3_ST_SW_CHANGE_B: + + s->session->cipher = s->s3->tmp.new_cipher; + if (!s->method->ssl3_enc->setup_key_block(s)) { + ret = -1; + goto end; + } + + ret = dtls1_send_change_cipher_spec(s, + SSL3_ST_SW_CHANGE_A, SSL3_ST_SW_CHANGE_B); + + if (ret <= 0) + goto end; + + + s->state = SSL3_ST_SW_FINISHED_A; + s->init_num = 0; + + if (!s->method->ssl3_enc->change_cipher_state(s, + SSL3_CHANGE_CIPHER_SERVER_WRITE)) { + ret = -1; + goto end; + } + + dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); + break; + + case SSL3_ST_SW_FINISHED_A: + case SSL3_ST_SW_FINISHED_B: + ret = ssl3_send_finished(s, + SSL3_ST_SW_FINISHED_A, SSL3_ST_SW_FINISHED_B, + s->method->ssl3_enc->server_finished_label, + s->method->ssl3_enc->server_finished_label_len); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_FLUSH; + if (s->hit) { + s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A; + + } else { + s->s3->tmp.next_state = SSL_ST_OK; + } + s->init_num = 0; + break; + + case SSL_ST_OK: + /* clean a few things up */ + tls1_cleanup_key_block(s); + + /* remove buffering on output */ + ssl_free_wbio_buffer(s); + + s->init_num = 0; + + if (s->renegotiate == 2) /* skipped if we just sent a HelloRequest */ + { + s->renegotiate = 0; + s->new_session = 0; + + ssl_update_cache(s, SSL_SESS_CACHE_SERVER); + + s->ctx->stats.sess_accept_good++; + /* s->server=1; */ + s->handshake_func = dtls1_accept; + + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_DONE, 1); + } + + ret = 1; + + /* done handshaking, next message is client hello */ + s->d1->handshake_read_seq = 0; + /* next message is server hello */ + s->d1->handshake_write_seq = 0; + s->d1->next_handshake_write_seq = 0; + goto end; + /* break; */ + + default: + SSLerr(SSL_F_DTLS1_ACCEPT, SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* break; */ + } + + if (!s->s3->tmp.reuse_message && !skip) { + if (s->debug) { + if ((ret = BIO_flush(s->wbio)) <= 0) + goto end; + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_ACCEPT_LOOP, 1); + s->state = new_state; + } + } + skip = 0; + } +end: + /* BIO_flush(s->wbio); */ + + s->in_handshake--; + + if (cb != NULL) + cb(s, SSL_CB_ACCEPT_EXIT, ret); + + return (ret); +} + +int +dtls1_send_hello_verify_request(SSL *s) +{ + unsigned char *d, *p; + + if (s->state == DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A) { + d = p = ssl3_handshake_msg_start(s, + DTLS1_MT_HELLO_VERIFY_REQUEST); + + *(p++) = s->version >> 8; + *(p++) = s->version & 0xFF; + + if (s->ctx->app_gen_cookie_cb == NULL || + s->ctx->app_gen_cookie_cb(s, s->d1->cookie, + &(s->d1->cookie_len)) == 0) { + SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST, + ERR_R_INTERNAL_ERROR); + return 0; + } + + *(p++) = (unsigned char) s->d1->cookie_len; + memcpy(p, s->d1->cookie, s->d1->cookie_len); + p += s->d1->cookie_len; + + ssl3_handshake_msg_finish(s, p - d); + + s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B; + } + + /* s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B */ + return (ssl3_handshake_write(s)); +} + +int +dtls1_send_server_certificate(SSL *s) +{ + unsigned long l; + X509 *x; + + if (s->state == SSL3_ST_SW_CERT_A) { + x = ssl_get_server_send_cert(s); + if (x == NULL) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE, + ERR_R_INTERNAL_ERROR); + return (0); + } + + l = dtls1_output_cert_chain(s, x); + s->state = SSL3_ST_SW_CERT_B; + s->init_num = (int)l; + s->init_off = 0; + + /* buffer the message to handle re-xmits */ + dtls1_buffer_message(s, 0); + } + + /* SSL3_ST_SW_CERT_B */ + return (dtls1_do_write(s, SSL3_RT_HANDSHAKE)); +} diff --git a/crypto/libressl/ssl/pqueue.c b/crypto/libressl/ssl/pqueue.c new file mode 100644 index 0000000000..d5b5a6b690 --- /dev/null +++ b/crypto/libressl/ssl/pqueue.c @@ -0,0 +1,201 @@ +/* $OpenBSD$ */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include "pqueue.h" + +typedef struct _pqueue { + pitem *items; + int count; +} pqueue_s; + +pitem * +pitem_new(unsigned char *prio64be, void *data) +{ + pitem *item = malloc(sizeof(pitem)); + + if (item == NULL) + return NULL; + + memcpy(item->priority, prio64be, sizeof(item->priority)); + + item->data = data; + item->next = NULL; + + return item; +} + +void +pitem_free(pitem *item) +{ + free(item); +} + +pqueue_s * +pqueue_new(void) +{ + return calloc(1, sizeof(pqueue_s)); +} + +void +pqueue_free(pqueue_s *pq) +{ + free(pq); +} + +pitem * +pqueue_insert(pqueue_s *pq, pitem *item) +{ + pitem *curr, *next; + + if (pq->items == NULL) { + pq->items = item; + return item; + } + + for (curr = NULL, next = pq->items; next != NULL; + curr = next, next = next->next) { + /* we can compare 64-bit value in big-endian encoding + * with memcmp:-) */ + int cmp = memcmp(next->priority, item->priority, + sizeof(item->priority)); + if (cmp > 0) { /* next > item */ + item->next = next; + + if (curr == NULL) + pq->items = item; + else + curr->next = item; + + return item; + } else if (cmp == 0) /* duplicates not allowed */ + return NULL; + } + + item->next = NULL; + curr->next = item; + + return item; +} + +pitem * +pqueue_peek(pqueue_s *pq) +{ + return pq->items; +} + +pitem * +pqueue_pop(pqueue_s *pq) +{ + pitem *item = pq->items; + + if (pq->items != NULL) + pq->items = pq->items->next; + + return item; +} + +pitem * +pqueue_find(pqueue_s *pq, unsigned char *prio64be) +{ + pitem *next; + + for (next = pq->items; next != NULL; next = next->next) + if (memcmp(next->priority, prio64be, + sizeof(next->priority)) == 0) + return next; + + return NULL; +} + +pitem * +pqueue_iterator(pqueue_s *pq) +{ + return pqueue_peek(pq); +} + +pitem * +pqueue_next(pitem **item) +{ + pitem *ret; + + if (item == NULL || *item == NULL) + return NULL; + + /* *item != NULL */ + ret = *item; + *item = (*item)->next; + + return ret; +} + +int +pqueue_size(pqueue_s *pq) +{ + pitem *item = pq->items; + int count = 0; + + while (item != NULL) { + count++; + item = item->next; + } + return count; +} diff --git a/crypto/libressl/ssl/s23_clnt.c b/crypto/libressl/ssl/s23_clnt.c new file mode 100644 index 0000000000..18350ba92b --- /dev/null +++ b/crypto/libressl/ssl/s23_clnt.c @@ -0,0 +1,480 @@ +/* $OpenBSD: s23_clnt.c,v 1.45 2015/09/11 14:39:05 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include "ssl_locl.h" + +#include +#include +#include + +static int ssl23_client_hello(SSL *s); +static int ssl23_get_server_hello(SSL *s); + +int +ssl23_connect(SSL *s) +{ + void (*cb)(const SSL *ssl, int type, int val) = NULL; + int ret = -1; + int new_state, state; + + ERR_clear_error(); + errno = 0; + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_BEFORE: + case SSL_ST_CONNECT: + case SSL_ST_BEFORE|SSL_ST_CONNECT: + case SSL_ST_OK|SSL_ST_CONNECT: + + if (s->session != NULL) { + SSLerr(SSL_F_SSL23_CONNECT, SSL_R_SSL23_DOING_SESSION_ID_REUSE); + ret = -1; + goto end; + } + s->server = 0; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + /* s->version=TLS1_VERSION; */ + s->type = SSL_ST_CONNECT; + + if (!ssl3_setup_init_buffer(s)) { + ret = -1; + goto end; + } + if (!ssl3_setup_buffers(s)) { + ret = -1; + goto end; + } + if (!tls1_init_finished_mac(s)) { + ret = -1; + goto end; + } + + s->state = SSL23_ST_CW_CLNT_HELLO_A; + s->ctx->stats.sess_connect++; + s->init_num = 0; + break; + + case SSL23_ST_CW_CLNT_HELLO_A: + case SSL23_ST_CW_CLNT_HELLO_B: + + s->shutdown = 0; + ret = ssl23_client_hello(s); + if (ret <= 0) + goto end; + s->state = SSL23_ST_CR_SRVR_HELLO_A; + s->init_num = 0; + + break; + + case SSL23_ST_CR_SRVR_HELLO_A: + case SSL23_ST_CR_SRVR_HELLO_B: + ret = ssl23_get_server_hello(s); + if (ret >= 0) + cb = NULL; + goto end; + /* break; */ + + default: + SSLerr(SSL_F_SSL23_CONNECT, SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* break; */ + } + + if (s->debug) { + (void)BIO_flush(s->wbio); + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_CONNECT_LOOP, 1); + s->state = new_state; + } + } + +end: + s->in_handshake--; + if (cb != NULL) + cb(s, SSL_CB_CONNECT_EXIT, ret); + + return (ret); +} + +static int +ssl23_client_hello(SSL *s) +{ + unsigned char *buf; + unsigned char *p, *d; + int i; + unsigned long l; + int version = 0, version_major, version_minor; + int ret; + unsigned long mask, options = s->options; + + /* + * SSL_OP_NO_X disables all protocols above X *if* there are + * some protocols below X enabled. This is required in order + * to maintain "version capability" vector contiguous. So + * that if application wants to disable TLS1.0 in favour of + * TLS1>=1, it would be insufficient to pass SSL_NO_TLSv1, the + * answer is SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2. + */ + mask = SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1; + version = TLS1_2_VERSION; + + if ((options & SSL_OP_NO_TLSv1_2) && (options & mask) != mask) + version = TLS1_1_VERSION; + mask &= ~SSL_OP_NO_TLSv1_1; + if ((options & SSL_OP_NO_TLSv1_1) && (options & mask) != mask) + version = TLS1_VERSION; + mask &= ~SSL_OP_NO_TLSv1; + + buf = (unsigned char *)s->init_buf->data; + if (s->state == SSL23_ST_CW_CLNT_HELLO_A) { + arc4random_buf(s->s3->client_random, SSL3_RANDOM_SIZE); + + if (version == TLS1_2_VERSION) { + version_major = TLS1_2_VERSION_MAJOR; + version_minor = TLS1_2_VERSION_MINOR; + } else if (version == TLS1_1_VERSION) { + version_major = TLS1_1_VERSION_MAJOR; + version_minor = TLS1_1_VERSION_MINOR; + } else if (version == TLS1_VERSION) { + version_major = TLS1_VERSION_MAJOR; + version_minor = TLS1_VERSION_MINOR; + } else { + SSLerr(SSL_F_SSL23_CLIENT_HELLO, + SSL_R_NO_PROTOCOLS_AVAILABLE); + return (-1); + } + + s->client_version = version; + + /* create Client Hello in SSL 3.0/TLS 1.0 format */ + + /* + * Do the record header (5 bytes) and handshake + * message header (4 bytes) last + */ + d = p = &(buf[SSL3_RT_HEADER_LENGTH + SSL3_HM_HEADER_LENGTH]); + + *(p++) = version_major; + *(p++) = version_minor; + + /* Random stuff */ + memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + + /* Session ID (zero since there is no reuse) */ + *(p++) = 0; + + /* Ciphers supported (using SSL 3.0/TLS 1.0 format) */ + i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &p[2]); + if (i == 0) { + SSLerr(SSL_F_SSL23_CLIENT_HELLO, + SSL_R_NO_CIPHERS_AVAILABLE); + return -1; + } + s2n(i, p); + p += i; + + /* add in (no) COMPRESSION */ + *(p++) = 1; + /* Add the NULL method */ + *(p++) = 0; + + /* TLS extensions*/ + if ((p = ssl_add_clienthello_tlsext(s, p, + buf + SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) { + SSLerr(SSL_F_SSL23_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + return -1; + } + + l = p - d; + + /* fill in 4-byte handshake header */ + d = &(buf[SSL3_RT_HEADER_LENGTH]); + *(d++) = SSL3_MT_CLIENT_HELLO; + l2n3(l, d); + + l += 4; + + if (l > SSL3_RT_MAX_PLAIN_LENGTH) { + SSLerr(SSL_F_SSL23_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + return -1; + } + + /* fill in 5-byte record header */ + d = buf; + *(d++) = SSL3_RT_HANDSHAKE; + *(d++) = version_major; + + /* + * Some servers hang if we use long client hellos + * and a record number > TLS 1.0. + */ + if (TLS1_get_client_version(s) > TLS1_VERSION) + *(d++) = 1; + else + *(d++) = version_minor; + s2n((int)l, d); + + /* number of bytes to write */ + s->init_num = p - buf; + s->init_off = 0; + + tls1_finish_mac(s, &(buf[SSL3_RT_HEADER_LENGTH]), + s->init_num - SSL3_RT_HEADER_LENGTH); + + s->state = SSL23_ST_CW_CLNT_HELLO_B; + s->init_off = 0; + } + + /* SSL3_ST_CW_CLNT_HELLO_B */ + ret = ssl23_write_bytes(s); + + if ((ret >= 2) && s->msg_callback) { + /* Client Hello has been sent; tell msg_callback */ + + s->msg_callback(1, version, SSL3_RT_HANDSHAKE, + s->init_buf->data + 5, ret - 5, s, s->msg_callback_arg); + } + + return ret; +} + +static int +ssl23_get_server_hello(SSL *s) +{ + char buf[8]; + unsigned char *p; + int i; + int n; + + n = ssl23_read_bytes(s, 7); + + if (n != 7) + return (n); + p = s->packet; + + memcpy(buf, p, n); + + /* Old unsupported sslv2 handshake */ + if ((p[0] & 0x80) && (p[2] == SSL2_MT_SERVER_HELLO) && + (p[5] == 0x00) && (p[6] == 0x02)) { + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, + SSL_R_UNSUPPORTED_PROTOCOL); + goto err; + } + + if (p[1] == SSL3_VERSION_MAJOR && + p[2] <= TLS1_2_VERSION_MINOR && + ((p[0] == SSL3_RT_HANDSHAKE && p[5] == SSL3_MT_SERVER_HELLO) || + (p[0] == SSL3_RT_ALERT && p[3] == 0 && p[4] == 2))) { + /* we have sslv3 or tls1 (server hello or alert) */ + + if ((p[2] == TLS1_VERSION_MINOR) && + !(s->options & SSL_OP_NO_TLSv1)) { + s->version = TLS1_VERSION; + s->method = TLSv1_client_method(); + } else if ((p[2] == TLS1_1_VERSION_MINOR) && + !(s->options & SSL_OP_NO_TLSv1_1)) { + s->version = TLS1_1_VERSION; + s->method = TLSv1_1_client_method(); + } else if ((p[2] == TLS1_2_VERSION_MINOR) && + !(s->options & SSL_OP_NO_TLSv1_2)) { + s->version = TLS1_2_VERSION; + s->method = TLSv1_2_client_method(); + } else { + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, + SSL_R_UNSUPPORTED_PROTOCOL); + goto err; + } + + if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING) { + /* fatal alert */ + void (*cb)(const SSL *ssl, int type, int val) = NULL; + int j; + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + i = p[5]; + if (cb != NULL) { + j = (i << 8) | p[6]; + cb(s, SSL_CB_READ_ALERT, j); + } + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_ALERT, + p + 5, 2, s, s->msg_callback_arg); + + s->rwstate = SSL_NOTHING; + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, + SSL_AD_REASON_OFFSET + p[6]); + goto err; + } + + if (!ssl_init_wbio_buffer(s, 1)) + goto err; + + /* we are in this state */ + s->state = SSL3_ST_CR_SRVR_HELLO_A; + + /* put the 7 bytes we have read into the input buffer + * for SSLv3 */ + s->rstate = SSL_ST_READ_HEADER; + s->packet_length = n; + if (s->s3->rbuf.buf == NULL) + if (!ssl3_setup_read_buffer(s)) + goto err; + s->packet = &(s->s3->rbuf.buf[0]); + memcpy(s->packet, buf, n); + s->s3->rbuf.left = n; + s->s3->rbuf.offset = 0; + + s->handshake_func = s->method->ssl_connect; + } else { + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNKNOWN_PROTOCOL); + goto err; + } + s->init_num = 0; + + /* + * Since, if we are sending a ssl23 client hello, we are not + * reusing a session-id + */ + if (!ssl_get_new_session(s, 0)) + goto err; + + return (SSL_connect(s)); +err: + return (-1); +} diff --git a/crypto/libressl/ssl/s23_lib.c b/crypto/libressl/ssl/s23_lib.c new file mode 100644 index 0000000000..09adebe1de --- /dev/null +++ b/crypto/libressl/ssl/s23_lib.c @@ -0,0 +1,132 @@ +/* $OpenBSD: s23_lib.c,v 1.17 2014/08/10 14:42:56 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include + +#include "ssl_locl.h" + +long +ssl23_default_timeout(void) +{ + return (300); +} + +int +ssl23_read(SSL *s, void *buf, int len) +{ + int n; + + errno = 0; + if (SSL_in_init(s) && (!s->in_handshake)) { + n = s->handshake_func(s); + if (n < 0) + return (n); + if (n == 0) { + SSLerr(SSL_F_SSL23_READ, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + return (SSL_read(s, buf, len)); + } else { + ssl_undefined_function(s); + return (-1); + } +} + +int +ssl23_peek(SSL *s, void *buf, int len) +{ + int n; + + errno = 0; + if (SSL_in_init(s) && (!s->in_handshake)) { + n = s->handshake_func(s); + if (n < 0) + return (n); + if (n == 0) { + SSLerr(SSL_F_SSL23_PEEK, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + return (SSL_peek(s, buf, len)); + } else { + ssl_undefined_function(s); + return (-1); + } +} + +int +ssl23_write(SSL *s, const void *buf, int len) +{ + int n; + + errno = 0; + if (SSL_in_init(s) && (!s->in_handshake)) { + n = s->handshake_func(s); + if (n < 0) + return (n); + if (n == 0) { + SSLerr(SSL_F_SSL23_WRITE, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + return (SSL_write(s, buf, len)); + } else { + ssl_undefined_function(s); + return (-1); + } +} diff --git a/crypto/libressl/ssl/s23_pkt.c b/crypto/libressl/ssl/s23_pkt.c new file mode 100644 index 0000000000..063c3a3d58 --- /dev/null +++ b/crypto/libressl/ssl/s23_pkt.c @@ -0,0 +1,116 @@ +/* $OpenBSD: s23_pkt.c,v 1.8 2014/06/12 15:49:31 deraadt Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include "ssl_locl.h" + +#include +#include + +int +ssl23_write_bytes(SSL *s) +{ + int i, num, tot; + char *buf; + + buf = s->init_buf->data; + tot = s->init_off; + num = s->init_num; + for (;;) { + s->rwstate = SSL_WRITING; + i = BIO_write(s->wbio, &(buf[tot]), num); + if (i <= 0) { + s->init_off = tot; + s->init_num = num; + return (i); + } + s->rwstate = SSL_NOTHING; + if (i == num) + return (tot + i); + + num -= i; + tot += i; + } +} + +/* return regularly only when we have read (at least) 'n' bytes */ +int +ssl23_read_bytes(SSL *s, int n) +{ + unsigned char *p; + int j; + + if (s->packet_length < (unsigned int)n) { + p = s->packet; + + for (;;) { + s->rwstate = SSL_READING; + j = BIO_read(s->rbio, (char *)&(p[s->packet_length]), + n - s->packet_length); + if (j <= 0) + return (j); + s->rwstate = SSL_NOTHING; + s->packet_length += j; + if (s->packet_length >= (unsigned int)n) + return (s->packet_length); + } + } + return (n); +} diff --git a/crypto/libressl/ssl/s23_srvr.c b/crypto/libressl/ssl/s23_srvr.c new file mode 100644 index 0000000000..745b8d7069 --- /dev/null +++ b/crypto/libressl/ssl/s23_srvr.c @@ -0,0 +1,514 @@ +/* $OpenBSD: s23_srvr.c,v 1.46 2015/10/25 15:49:04 doug Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include "ssl_locl.h" + +#include +#include +#include + +int ssl23_get_client_hello(SSL *s); + +int +ssl23_accept(SSL *s) +{ + void (*cb)(const SSL *ssl, int type, int val) = NULL; + int ret = -1; + int new_state, state; + + ERR_clear_error(); + errno = 0; + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_BEFORE: + case SSL_ST_ACCEPT: + case SSL_ST_BEFORE|SSL_ST_ACCEPT: + case SSL_ST_OK|SSL_ST_ACCEPT: + + s->server = 1; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + /* s->version=SSL3_VERSION; */ + s->type = SSL_ST_ACCEPT; + + if (!ssl3_setup_init_buffer(s)) { + ret = -1; + goto end; + } + if (!tls1_init_finished_mac(s)) { + ret = -1; + goto end; + } + + s->state = SSL23_ST_SR_CLNT_HELLO_A; + s->ctx->stats.sess_accept++; + s->init_num = 0; + break; + + case SSL23_ST_SR_CLNT_HELLO_A: + case SSL23_ST_SR_CLNT_HELLO_B: + + s->shutdown = 0; + ret = ssl23_get_client_hello(s); + if (ret >= 0) + cb = NULL; + goto end; + /* break; */ + + default: + SSLerr(SSL_F_SSL23_ACCEPT, SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* break; */ + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_ACCEPT_LOOP, 1); + s->state = new_state; + } + } + +end: + s->in_handshake--; + if (cb != NULL) + cb(s, SSL_CB_ACCEPT_EXIT, ret); + + return (ret); +} + + +int +ssl23_get_client_hello(SSL *s) +{ + char buf[11]; + /* + * sizeof(buf) == 11, because we'll need to request this many bytes in + * the initial read. + * We can detect SSL 3.0/TLS 1.0 Client Hellos ('type == 3') correctly + * only when the following is in a single record, which is not + * guaranteed by the protocol specification: + * Byte Content + * 0 type \ + * 1/2 version > record header + * 3/4 length / + * 5 msg_type \ + * 6-8 length > Client Hello message + * 9/10 client_version / + */ + unsigned char *p, *d, *d_len, *dd; + unsigned int i; + unsigned int csl, sil, cl; + int n = 0, j; + int type = 0; + int v[2]; + + if (s->state == SSL23_ST_SR_CLNT_HELLO_A) { + /* read the initial header */ + v[0] = v[1] = 0; + + if (!ssl3_setup_buffers(s)) + return -1; + + n = ssl23_read_bytes(s, sizeof buf); + if (n != sizeof buf) + return(n); + + p = s->packet; + + memcpy(buf, p, n); + + if ((p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO)) { + /* + * SSLv2 header + */ + if ((p[3] == 0x00) && (p[4] == 0x02)) { + /* SSLv2 support has been removed */ + goto unsupported; + + } else if (p[3] == SSL3_VERSION_MAJOR) { + v[0] = p[3]; + v[1] = p[4]; + /* SSLv3/TLS */ + + if (p[4] >= TLS1_VERSION_MINOR) { + if (p[4] >= TLS1_2_VERSION_MINOR && + !(s->options & SSL_OP_NO_TLSv1_2)) { + s->version = TLS1_2_VERSION; + s->state = SSL23_ST_SR_CLNT_HELLO_B; + } else if (p[4] >= TLS1_1_VERSION_MINOR && + !(s->options & SSL_OP_NO_TLSv1_1)) { + s->version = TLS1_1_VERSION; + /* type=2; */ /* done later to survive restarts */ + s->state = SSL23_ST_SR_CLNT_HELLO_B; + } else if (!(s->options & SSL_OP_NO_TLSv1)) { + s->version = TLS1_VERSION; + /* type=2; */ /* done later to survive restarts */ + s->state = SSL23_ST_SR_CLNT_HELLO_B; + } else { + goto unsupported; + } + } else { + /* SSLv3 support has been removed */ + goto unsupported; + } + } + } else if ((p[0] == SSL3_RT_HANDSHAKE) && + (p[1] == SSL3_VERSION_MAJOR) && + (p[5] == SSL3_MT_CLIENT_HELLO) && + ((p[3] == 0 && p[4] < 5 /* silly record length? */) || + (p[9] >= p[1]))) { + /* + * SSLv3 or tls1 header + */ + + v[0] = p[1]; /* major version (= SSL3_VERSION_MAJOR) */ + /* We must look at client_version inside the Client Hello message + * to get the correct minor version. + * However if we have only a pathologically small fragment of the + * Client Hello message, this would be difficult, and we'd have + * to read more records to find out. + * No known SSL 3.0 client fragments ClientHello like this, + * so we simply reject such connections to avoid + * protocol version downgrade attacks. */ + if (p[3] == 0 && p[4] < 6) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, + SSL_R_RECORD_TOO_SMALL); + return -1; + } + /* if major version number > 3 set minor to a value + * which will use the highest version 3 we support. + * If TLS 2.0 ever appears we will need to revise + * this.... + */ + if (p[9] > SSL3_VERSION_MAJOR) + v[1] = 0xff; + else + v[1] = p[10]; /* minor version according to client_version */ + if (v[1] >= TLS1_VERSION_MINOR) { + if (v[1] >= TLS1_2_VERSION_MINOR && + !(s->options & SSL_OP_NO_TLSv1_2)) { + s->version = TLS1_2_VERSION; + type = 3; + } else if (v[1] >= TLS1_1_VERSION_MINOR && + !(s->options & SSL_OP_NO_TLSv1_1)) { + s->version = TLS1_1_VERSION; + type = 3; + } else if (!(s->options & SSL_OP_NO_TLSv1)) { + s->version = TLS1_VERSION; + type = 3; + } else { + goto unsupported; + } + } else { + /* SSLv3 */ + if (!(s->options & SSL_OP_NO_TLSv1)) { + /* we won't be able to use TLS of course, + * but this will send an appropriate alert */ + s->version = TLS1_VERSION; + type = 3; + } else { + goto unsupported; + } + } + } + else if ((strncmp("GET ", (char *)p, 4) == 0) || + (strncmp("POST ",(char *)p, 5) == 0) || + (strncmp("HEAD ",(char *)p, 5) == 0) || + (strncmp("PUT ", (char *)p, 4) == 0)) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_HTTP_REQUEST); + return -1; + } else if (strncmp("CONNECT", (char *)p, 7) == 0) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_HTTPS_PROXY_REQUEST); + return -1; + } + } + + if (s->state == SSL23_ST_SR_CLNT_HELLO_B) { + /* we have SSLv3/TLSv1 in an SSLv2 header + * (other cases skip this state) */ + + /* + * Limit the support of "backward compatible" headers + * only to "backward" versions of TLS. If we have moved + * on to modernity, just say no. + */ + if (s->options & SSL_OP_NO_TLSv1) + goto unsupported; + + type = 2; + p = s->packet; + v[0] = p[3]; /* == SSL3_VERSION_MAJOR */ + v[1] = p[4]; + + /* An SSLv3/TLSv1 backwards-compatible CLIENT-HELLO in an SSLv2 + * header is sent directly on the wire, not wrapped as a TLS + * record. It's format is: + * Byte Content + * 0-1 msg_length + * 2 msg_type + * 3-4 version + * 5-6 cipher_spec_length + * 7-8 session_id_length + * 9-10 challenge_length + * ... ... + */ + n = ((p[0] & 0x7f) << 8) | p[1]; + if (n > (1024 * 4)) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_RECORD_TOO_LARGE); + return -1; + } + if (n < 9) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, + SSL_R_RECORD_LENGTH_MISMATCH); + return -1; + } + + j = ssl23_read_bytes(s, n + 2); + if (j != n + 2) + return -1; + + tls1_finish_mac(s, s->packet + 2, s->packet_length - 2); + if (s->msg_callback) + s->msg_callback(0, SSL2_VERSION, 0, s->packet + 2, + s->packet_length - 2, s, s->msg_callback_arg); + + p = s->packet; + p += 5; + n2s(p, csl); + n2s(p, sil); + n2s(p, cl); + d = (unsigned char *)s->init_buf->data; + if ((csl + sil + cl + 11) != s->packet_length) { + /* + * We can't have TLS extensions in SSL 2.0 format + * Client Hello, can we ? Error condition should be + * '>' otherwise + */ + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, + SSL_R_RECORD_LENGTH_MISMATCH); + return -1; + } + + /* record header: msg_type ... */ + *(d++) = SSL3_MT_CLIENT_HELLO; + /* ... and length (actual value will be written later) */ + d_len = d; + d += 3; + + /* client_version */ + *(d++) = SSL3_VERSION_MAJOR; /* == v[0] */ + *(d++) = v[1]; + + /* lets populate the random area */ + /* get the challenge_length */ + i = (cl > SSL3_RANDOM_SIZE) ? SSL3_RANDOM_SIZE : cl; + memset(d, 0, SSL3_RANDOM_SIZE); + memcpy(&(d[SSL3_RANDOM_SIZE - i]), &(p[csl + sil]), i); + d += SSL3_RANDOM_SIZE; + + /* no session-id reuse */ + *(d++) = 0; + + /* ciphers */ + j = 0; + dd = d; + d += 2; + for (i = 0; i < csl; i += 3) { + if (p[i] != 0) + continue; + *(d++) = p[i + 1]; + *(d++) = p[i + 2]; + j += 2; + } + s2n(j, dd); + + /* add in (no) COMPRESSION */ + *(d++) = 1; + *(d++) = 0; + + i = (d - (unsigned char *)s->init_buf->data) - 4; + l2n3((long)i, d_len); + + /* get the data reused from the init_buf */ + s->s3->tmp.reuse_message = 1; + s->s3->tmp.message_type = SSL3_MT_CLIENT_HELLO; + s->s3->tmp.message_size = i; + } + + /* imaginary new state (for program structure): */ + /* s->state = SSL23_SR_CLNT_HELLO_C */ + + if (type == 2 || type == 3) { + /* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */ + + if (!ssl_init_wbio_buffer(s, 1)) + return -1; + + /* we are in this state */ + s->state = SSL3_ST_SR_CLNT_HELLO_A; + + if (type == 3) { + /* put the 'n' bytes we have read into the input buffer + * for SSLv3 */ + s->rstate = SSL_ST_READ_HEADER; + s->packet_length = n; + if (s->s3->rbuf.buf == NULL) + if (!ssl3_setup_read_buffer(s)) + return -1; + + s->packet = &(s->s3->rbuf.buf[0]); + memcpy(s->packet, buf, n); + s->s3->rbuf.left = n; + s->s3->rbuf.offset = 0; + } else { + s->packet_length = 0; + s->s3->rbuf.left = 0; + s->s3->rbuf.offset = 0; + } + if (s->version == TLS1_2_VERSION) + s->method = TLSv1_2_server_method(); + else if (s->version == TLS1_1_VERSION) + s->method = TLSv1_1_server_method(); + else if (s->version == TLS1_VERSION) + s->method = TLSv1_server_method(); + else + goto unsupported; + s->handshake_func = s->method->ssl_accept; + } else { + /* bad, very bad */ + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL); + return -1; + } + s->init_num = 0; + + return (SSL_accept(s)); + + unsupported: + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); + return -1; +} diff --git a/crypto/libressl/ssl/s3_both.c b/crypto/libressl/ssl/s3_both.c new file mode 100644 index 0000000000..9cd263cb60 --- /dev/null +++ b/crypto/libressl/ssl/s3_both.c @@ -0,0 +1,743 @@ +/* $OpenBSD: s3_both.c,v 1.47 2015/09/11 18:08:21 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include +#include +#include + +#include "ssl_locl.h" + +#include +#include +#include +#include + +#include "bytestring.h" + +/* + * Send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or + * SSL3_RT_CHANGE_CIPHER_SPEC). + */ +int +ssl3_do_write(SSL *s, int type) +{ + int ret; + + ret = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off], + s->init_num); + if (ret < 0) + return (-1); + + if (type == SSL3_RT_HANDSHAKE) + /* + * Should not be done for 'Hello Request's, but in that case + * we'll ignore the result anyway. + */ + tls1_finish_mac(s, + (unsigned char *)&s->init_buf->data[s->init_off], ret); + + if (ret == s->init_num) { + if (s->msg_callback) + s->msg_callback(1, s->version, type, s->init_buf->data, + (size_t)(s->init_off + s->init_num), s, + s->msg_callback_arg); + return (1); + } + + s->init_off += ret; + s->init_num -= ret; + + return (0); +} + +int +ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen) +{ + unsigned char *p; + int md_len; + + if (s->state == a) { + md_len = s->method->ssl3_enc->finish_mac_length; + OPENSSL_assert(md_len <= EVP_MAX_MD_SIZE); + + if (s->method->ssl3_enc->final_finish_mac(s, sender, slen, + s->s3->tmp.finish_md) != md_len) + return (0); + s->s3->tmp.finish_md_len = md_len; + + /* Copy finished so we can use it for renegotiation checks. */ + if (s->type == SSL_ST_CONNECT) { + memcpy(s->s3->previous_client_finished, + s->s3->tmp.finish_md, md_len); + s->s3->previous_client_finished_len = md_len; + } else { + memcpy(s->s3->previous_server_finished, + s->s3->tmp.finish_md, md_len); + s->s3->previous_server_finished_len = md_len; + } + + p = ssl3_handshake_msg_start(s, SSL3_MT_FINISHED); + memcpy(p, s->s3->tmp.finish_md, md_len); + ssl3_handshake_msg_finish(s, md_len); + + s->state = b; + } + + return (ssl3_handshake_write(s)); +} + +/* + * ssl3_take_mac calculates the Finished MAC for the handshakes messages seen + * so far. + */ +static void +ssl3_take_mac(SSL *s) +{ + const char *sender; + int slen; + + /* + * If no new cipher setup return immediately: other functions will + * set the appropriate error. + */ + if (s->s3->tmp.new_cipher == NULL) + return; + + if (s->state & SSL_ST_CONNECT) { + sender = s->method->ssl3_enc->server_finished_label; + slen = s->method->ssl3_enc->server_finished_label_len; + } else { + sender = s->method->ssl3_enc->client_finished_label; + slen = s->method->ssl3_enc->client_finished_label_len; + } + + s->s3->tmp.peer_finish_md_len = + s->method->ssl3_enc->final_finish_mac(s, sender, slen, + s->s3->tmp.peer_finish_md); +} + +int +ssl3_get_finished(SSL *s, int a, int b) +{ + int al, ok, md_len; + long n; + CBS cbs; + + /* should actually be 36+4 :-) */ + n = s->method->ssl_get_message(s, a, b, SSL3_MT_FINISHED, 64, &ok); + if (!ok) + return ((int)n); + + /* If this occurs, we have missed a message */ + if (!s->s3->change_cipher_spec) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_GOT_A_FIN_BEFORE_A_CCS); + goto f_err; + } + s->s3->change_cipher_spec = 0; + + md_len = s->method->ssl3_enc->finish_mac_length; + + if (n < 0) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_BAD_DIGEST_LENGTH); + goto f_err; + } + + CBS_init(&cbs, s->init_msg, n); + + if (s->s3->tmp.peer_finish_md_len != md_len || + CBS_len(&cbs) != md_len) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_BAD_DIGEST_LENGTH); + goto f_err; + } + + if (!CBS_mem_equal(&cbs, s->s3->tmp.peer_finish_md, CBS_len(&cbs))) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_DIGEST_CHECK_FAILED); + goto f_err; + } + + /* Copy finished so we can use it for renegotiation checks. */ + OPENSSL_assert(md_len <= EVP_MAX_MD_SIZE); + if (s->type == SSL_ST_ACCEPT) { + memcpy(s->s3->previous_client_finished, + s->s3->tmp.peer_finish_md, md_len); + s->s3->previous_client_finished_len = md_len; + } else { + memcpy(s->s3->previous_server_finished, + s->s3->tmp.peer_finish_md, md_len); + s->s3->previous_server_finished_len = md_len; + } + + return (1); +f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return (0); +} + +/* for these 2 messages, we need to + * ssl->enc_read_ctx re-init + * ssl->s3->read_sequence zero + * ssl->s3->read_mac_secret re-init + * ssl->session->read_sym_enc assign + * ssl->session->read_hash assign + */ +int +ssl3_send_change_cipher_spec(SSL *s, int a, int b) +{ + unsigned char *p; + + if (s->state == a) { + p = (unsigned char *)s->init_buf->data; + *p = SSL3_MT_CCS; + s->init_num = 1; + s->init_off = 0; + + s->state = b; + } + + /* SSL3_ST_CW_CHANGE_B */ + return (ssl3_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC)); +} + +static int +ssl3_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x) +{ + int n; + unsigned char *p; + + n = i2d_X509(x, NULL); + if (!BUF_MEM_grow_clean(buf, n + (*l) + 3)) { + SSLerr(SSL_F_SSL3_ADD_CERT_TO_BUF, ERR_R_BUF_LIB); + return (-1); + } + /* XXX */ + p = (unsigned char *)&(buf->data[*l]); + l2n3(n, p); + i2d_X509(x, &p); + *l += n + 3; + + return (0); +} + +unsigned long +ssl3_output_cert_chain(SSL *s, X509 *x) +{ + unsigned char *p; + unsigned long l = ssl3_handshake_msg_hdr_len(s) + 3; + BUF_MEM *buf; + int no_chain; + int i; + + if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs) + no_chain = 1; + else + no_chain = 0; + + /* TLSv1 sends a chain with nothing in it, instead of an alert */ + buf = s->init_buf; + if (!BUF_MEM_grow_clean(buf, ssl3_handshake_msg_hdr_len(s) + 6)) { + SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN, ERR_R_BUF_LIB); + return (0); + } + if (x != NULL) { + if (no_chain) { + if (ssl3_add_cert_to_buf(buf, &l, x)) + return (0); + } else { + X509_STORE_CTX xs_ctx; + + if (!X509_STORE_CTX_init(&xs_ctx, s->ctx->cert_store, + x, NULL)) { + SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN, + ERR_R_X509_LIB); + return (0); + } + X509_verify_cert(&xs_ctx); + + /* Don't leave errors in the queue. */ + ERR_clear_error(); + for (i = 0; i < sk_X509_num(xs_ctx.chain); i++) { + x = sk_X509_value(xs_ctx.chain, i); + if (ssl3_add_cert_to_buf(buf, &l, x)) { + X509_STORE_CTX_cleanup(&xs_ctx); + return 0; + } + } + X509_STORE_CTX_cleanup(&xs_ctx); + } + } + /* Thawte special :-) */ + for (i = 0; i < sk_X509_num(s->ctx->extra_certs); i++) { + x = sk_X509_value(s->ctx->extra_certs, i); + if (ssl3_add_cert_to_buf(buf, &l, x)) + return (0); + } + + l -= ssl3_handshake_msg_hdr_len(s) + 3; + p = (unsigned char *)&(buf->data[4]); + l2n3(l, p); + l += 3; + p = (unsigned char *)&(buf->data[0]); + *(p++) = SSL3_MT_CERTIFICATE; + l2n3(l, p); + l += 4; /* XXX */ + return (l); +} + +/* + * Obtain handshake message of message type 'mt' (any if mt == -1), + * maximum acceptable body length 'max'. + * The first four bytes (msg_type and length) are read in state 'st1', + * the body is read in state 'stn'. + */ +long +ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) +{ + unsigned char *p; + uint32_t l; + long n; + int i, al; + CBS cbs; + uint8_t u8; + + if (s->s3->tmp.reuse_message) { + s->s3->tmp.reuse_message = 0; + if ((mt >= 0) && (s->s3->tmp.message_type != mt)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_MESSAGE, + SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + *ok = 1; + s->init_msg = s->init_buf->data + 4; + s->init_num = (int)s->s3->tmp.message_size; + return s->init_num; + } + + p = (unsigned char *)s->init_buf->data; + + /* s->init_num < 4 */ + if (s->state == st1) { + int skip_message; + + do { + while (s->init_num < 4) { + i = s->method->ssl_read_bytes(s, + SSL3_RT_HANDSHAKE, &p[s->init_num], + 4 - s->init_num, 0); + if (i <= 0) { + s->rwstate = SSL_READING; + *ok = 0; + return i; + } + s->init_num += i; + } + + skip_message = 0; + if (!s->server && p[0] == SSL3_MT_HELLO_REQUEST) { + /* + * The server may always send 'Hello Request' + * messages -- we are doing a handshake anyway + * now, so ignore them if their format is + * correct. Does not count for 'Finished' MAC. + */ + if (p[1] == 0 && p[2] == 0 &&p[3] == 0) { + s->init_num = 0; + skip_message = 1; + + if (s->msg_callback) + s->msg_callback(0, s->version, + SSL3_RT_HANDSHAKE, p, 4, s, + s->msg_callback_arg); + } + } + } while (skip_message); + + /* s->init_num == 4 */ + + if ((mt >= 0) && (*p != mt)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_MESSAGE, + SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + + /* XXX remove call to n2l3 */ + CBS_init(&cbs, p, 4); + if (!CBS_get_u8(&cbs, &u8) || + !CBS_get_u24(&cbs, &l)) { + SSLerr(SSL_F_SSL3_GET_MESSAGE, ERR_R_BUF_LIB); + goto err; + } + s->s3->tmp.message_type = u8; + + if (l > (unsigned long)max) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_MESSAGE, + SSL_R_EXCESSIVE_MESSAGE_SIZE); + goto f_err; + } + if (l && !BUF_MEM_grow_clean(s->init_buf, l + 4)) { + SSLerr(SSL_F_SSL3_GET_MESSAGE, ERR_R_BUF_LIB); + goto err; + } + s->s3->tmp.message_size = l; + s->state = stn; + + s->init_msg = s->init_buf->data + 4; + s->init_num = 0; + } + + /* next state (stn) */ + p = s->init_msg; + n = s->s3->tmp.message_size - s->init_num; + while (n > 0) { + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + &p[s->init_num], n, 0); + if (i <= 0) { + s->rwstate = SSL_READING; + *ok = 0; + return i; + } + s->init_num += i; + n -= i; + } + + /* If receiving Finished, record MAC of prior handshake messages for + * Finished verification. */ + if (*s->init_buf->data == SSL3_MT_FINISHED) + ssl3_take_mac(s); + + /* Feed this message into MAC computation. */ + tls1_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4); + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, + s->init_buf->data, (size_t)s->init_num + 4, s, + s->msg_callback_arg); + + *ok = 1; + return (s->init_num); + +f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); +err: + *ok = 0; + return (-1); +} + +int +ssl_cert_type(X509 *x, EVP_PKEY *pkey) +{ + EVP_PKEY *pk; + int ret = -1, i; + + if (pkey == NULL) + pk = X509_get_pubkey(x); + else + pk = pkey; + if (pk == NULL) + goto err; + + i = pk->type; + if (i == EVP_PKEY_RSA) { + ret = SSL_PKEY_RSA_ENC; + } else if (i == EVP_PKEY_DSA) { + ret = SSL_PKEY_DSA_SIGN; + } else if (i == EVP_PKEY_EC) { + ret = SSL_PKEY_ECC; + } else if (i == NID_id_GostR3410_2001 || + i == NID_id_GostR3410_2001_cc) { + ret = SSL_PKEY_GOST01; + } + +err: + if (!pkey) + EVP_PKEY_free(pk); + return (ret); +} + +int +ssl_verify_alarm_type(long type) +{ + int al; + + switch (type) { + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: + case X509_V_ERR_UNABLE_TO_GET_CRL: + case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: + al = SSL_AD_UNKNOWN_CA; + break; + case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: + case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: + case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: + case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: + case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: + case X509_V_ERR_CERT_NOT_YET_VALID: + case X509_V_ERR_CRL_NOT_YET_VALID: + case X509_V_ERR_CERT_UNTRUSTED: + case X509_V_ERR_CERT_REJECTED: + al = SSL_AD_BAD_CERTIFICATE; + break; + case X509_V_ERR_CERT_SIGNATURE_FAILURE: + case X509_V_ERR_CRL_SIGNATURE_FAILURE: + al = SSL_AD_DECRYPT_ERROR; + break; + case X509_V_ERR_CERT_HAS_EXPIRED: + case X509_V_ERR_CRL_HAS_EXPIRED: + al = SSL_AD_CERTIFICATE_EXPIRED; + break; + case X509_V_ERR_CERT_REVOKED: + al = SSL_AD_CERTIFICATE_REVOKED; + break; + case X509_V_ERR_OUT_OF_MEM: + al = SSL_AD_INTERNAL_ERROR; + break; + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: + case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: + case X509_V_ERR_CERT_CHAIN_TOO_LONG: + case X509_V_ERR_PATH_LENGTH_EXCEEDED: + case X509_V_ERR_INVALID_CA: + al = SSL_AD_UNKNOWN_CA; + break; + case X509_V_ERR_APPLICATION_VERIFICATION: + al = SSL_AD_HANDSHAKE_FAILURE; + break; + case X509_V_ERR_INVALID_PURPOSE: + al = SSL_AD_UNSUPPORTED_CERTIFICATE; + break; + default: + al = SSL_AD_CERTIFICATE_UNKNOWN; + break; + } + return (al); +} + +int +ssl3_setup_init_buffer(SSL *s) +{ + BUF_MEM *buf = NULL; + + if (s->init_buf != NULL) + return (1); + + if ((buf = BUF_MEM_new()) == NULL) + goto err; + if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) + goto err; + + s->init_buf = buf; + return (1); + +err: + BUF_MEM_free(buf); + return (0); +} + +int +ssl3_setup_read_buffer(SSL *s) +{ + unsigned char *p; + size_t len, align, headerlen; + + if (SSL_IS_DTLS(s)) + headerlen = DTLS1_RT_HEADER_LENGTH; + else + headerlen = SSL3_RT_HEADER_LENGTH; + + align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1); + + if (s->s3->rbuf.buf == NULL) { + len = SSL3_RT_MAX_PLAIN_LENGTH + + SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align; + if ((p = malloc(len)) == NULL) + goto err; + s->s3->rbuf.buf = p; + s->s3->rbuf.len = len; + } + + s->packet = &(s->s3->rbuf.buf[0]); + return 1; + +err: + SSLerr(SSL_F_SSL3_SETUP_READ_BUFFER, ERR_R_MALLOC_FAILURE); + return 0; +} + +int +ssl3_setup_write_buffer(SSL *s) +{ + unsigned char *p; + size_t len, align, headerlen; + + if (SSL_IS_DTLS(s)) + headerlen = DTLS1_RT_HEADER_LENGTH + 1; + else + headerlen = SSL3_RT_HEADER_LENGTH; + + align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1); + + if (s->s3->wbuf.buf == NULL) { + len = s->max_send_fragment + + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align; + if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) + len += headerlen + align + + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD; + + if ((p = malloc(len)) == NULL) + goto err; + s->s3->wbuf.buf = p; + s->s3->wbuf.len = len; + } + + return 1; + +err: + SSLerr(SSL_F_SSL3_SETUP_WRITE_BUFFER, ERR_R_MALLOC_FAILURE); + return 0; +} + +int +ssl3_setup_buffers(SSL *s) +{ + if (!ssl3_setup_read_buffer(s)) + return 0; + if (!ssl3_setup_write_buffer(s)) + return 0; + return 1; +} + +int +ssl3_release_write_buffer(SSL *s) +{ + free(s->s3->wbuf.buf); + s->s3->wbuf.buf = NULL; + return 1; +} + +int +ssl3_release_read_buffer(SSL *s) +{ + free(s->s3->rbuf.buf); + s->s3->rbuf.buf = NULL; + return 1; +} diff --git a/crypto/libressl/ssl/s3_cbc.c b/crypto/libressl/ssl/s3_cbc.c new file mode 100644 index 0000000000..8d6928397d --- /dev/null +++ b/crypto/libressl/ssl/s3_cbc.c @@ -0,0 +1,656 @@ +/* $OpenBSD: s3_cbc.c,v 1.11 2015/09/11 17:17:44 jsing Exp $ */ +/* ==================================================================== + * Copyright (c) 2012 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ssl_locl.h" + +#include +#include + +/* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length + * field. (SHA-384/512 have 128-bit length.) */ +#define MAX_HASH_BIT_COUNT_BYTES 16 + +/* MAX_HASH_BLOCK_SIZE is the maximum hash block size that we'll support. + * Currently SHA-384/512 has a 128-byte block size and that's the largest + * supported by TLS.) */ +#define MAX_HASH_BLOCK_SIZE 128 + +/* Some utility functions are needed: + * + * These macros return the given value with the MSB copied to all the other + * bits. They use the fact that arithmetic shift shifts-in the sign bit. + * However, this is not ensured by the C standard so you may need to replace + * them with something else on odd CPUs. */ +#define DUPLICATE_MSB_TO_ALL(x) ((unsigned)((int)(x) >> (sizeof(int) * 8 - 1))) +#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x))) + +/* constant_time_lt returns 0xff if a=b and 0x00 otherwise. */ +static unsigned +constant_time_ge(unsigned a, unsigned b) +{ + a -= b; + return DUPLICATE_MSB_TO_ALL(~a); +} + +/* constant_time_eq_8 returns 0xff if a==b and 0x00 otherwise. */ +static unsigned char +constant_time_eq_8(unsigned a, unsigned b) +{ + unsigned c = a ^ b; + c--; + return DUPLICATE_MSB_TO_ALL_8(c); +} + +/* tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC + * record in |rec| in constant time and returns 1 if the padding is valid and + * -1 otherwise. It also removes any explicit IV from the start of the record + * without leaking any timing about whether there was enough space after the + * padding was removed. + * + * block_size: the block size of the cipher used to encrypt the record. + * returns: + * 0: (in non-constant time) if the record is publicly invalid. + * 1: if the padding was valid + * -1: otherwise. */ +int +tls1_cbc_remove_padding(const SSL* s, SSL3_RECORD *rec, unsigned block_size, + unsigned mac_size) +{ + unsigned padding_length, good, to_check, i; + const unsigned overhead = 1 /* padding length byte */ + mac_size; + + /* Check if version requires explicit IV */ + if (SSL_USE_EXPLICIT_IV(s)) { + /* These lengths are all public so we can test them in + * non-constant time. + */ + if (overhead + block_size > rec->length) + return 0; + /* We can now safely skip explicit IV */ + rec->data += block_size; + rec->input += block_size; + rec->length -= block_size; + } else if (overhead > rec->length) + return 0; + + padding_length = rec->data[rec->length - 1]; + + if (EVP_CIPHER_flags(s->enc_read_ctx->cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) { + /* padding is already verified */ + rec->length -= padding_length + 1; + return 1; + } + + good = constant_time_ge(rec->length, overhead + padding_length); + /* The padding consists of a length byte at the end of the record and + * then that many bytes of padding, all with the same value as the + * length byte. Thus, with the length byte included, there are i+1 + * bytes of padding. + * + * We can't check just |padding_length+1| bytes because that leaks + * decrypted information. Therefore we always have to check the maximum + * amount of padding possible. (Again, the length of the record is + * public information so we can use it.) */ + to_check = 255; /* maximum amount of padding. */ + if (to_check > rec->length - 1) + to_check = rec->length - 1; + + for (i = 0; i < to_check; i++) { + unsigned char mask = constant_time_ge(padding_length, i); + unsigned char b = rec->data[rec->length - 1 - i]; + /* The final |padding_length+1| bytes should all have the value + * |padding_length|. Therefore the XOR should be zero. */ + good &= ~(mask&(padding_length ^ b)); + } + + /* If any of the final |padding_length+1| bytes had the wrong value, + * one or more of the lower eight bits of |good| will be cleared. We + * AND the bottom 8 bits together and duplicate the result to all the + * bits. */ + good &= good >> 4; + good &= good >> 2; + good &= good >> 1; + good <<= sizeof(good)*8 - 1; + good = DUPLICATE_MSB_TO_ALL(good); + + padding_length = good & (padding_length + 1); + rec->length -= padding_length; + rec->type |= padding_length<<8; /* kludge: pass padding length */ + + return (int)((good & 1) | (~good & -1)); +} + +/* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in + * constant time (independent of the concrete value of rec->length, which may + * vary within a 256-byte window). + * + * ssl3_cbc_remove_padding or tls1_cbc_remove_padding must be called prior to + * this function. + * + * On entry: + * rec->orig_len >= md_size + * md_size <= EVP_MAX_MD_SIZE + * + * If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with + * variable accesses in a 64-byte-aligned buffer. Assuming that this fits into + * a single or pair of cache-lines, then the variable memory accesses don't + * actually affect the timing. CPUs with smaller cache-lines [if any] are + * not multi-core and are not considered vulnerable to cache-timing attacks. + */ +#define CBC_MAC_ROTATE_IN_PLACE + +void +ssl3_cbc_copy_mac(unsigned char* out, const SSL3_RECORD *rec, + unsigned md_size, unsigned orig_len) +{ +#if defined(CBC_MAC_ROTATE_IN_PLACE) + unsigned char rotated_mac_buf[64 + EVP_MAX_MD_SIZE]; + unsigned char *rotated_mac; +#else + unsigned char rotated_mac[EVP_MAX_MD_SIZE]; +#endif + + /* mac_end is the index of |rec->data| just after the end of the MAC. */ + unsigned mac_end = rec->length; + unsigned mac_start = mac_end - md_size; + /* scan_start contains the number of bytes that we can ignore because + * the MAC's position can only vary by 255 bytes. */ + unsigned scan_start = 0; + unsigned i, j; + unsigned div_spoiler; + unsigned rotate_offset; + + OPENSSL_assert(orig_len >= md_size); + OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); + +#if defined(CBC_MAC_ROTATE_IN_PLACE) + rotated_mac = rotated_mac_buf + ((0 - (size_t)rotated_mac_buf)&63); +#endif + + /* This information is public so it's safe to branch based on it. */ + if (orig_len > md_size + 255 + 1) + scan_start = orig_len - (md_size + 255 + 1); + /* div_spoiler contains a multiple of md_size that is used to cause the + * modulo operation to be constant time. Without this, the time varies + * based on the amount of padding when running on Intel chips at least. + * + * The aim of right-shifting md_size is so that the compiler doesn't + * figure out that it can remove div_spoiler as that would require it + * to prove that md_size is always even, which I hope is beyond it. */ + div_spoiler = md_size >> 1; + div_spoiler <<= (sizeof(div_spoiler) - 1) * 8; + rotate_offset = (div_spoiler + mac_start - scan_start) % md_size; + + memset(rotated_mac, 0, md_size); + for (i = scan_start, j = 0; i < orig_len; i++) { + unsigned char mac_started = constant_time_ge(i, mac_start); + unsigned char mac_ended = constant_time_ge(i, mac_end); + unsigned char b = rec->data[i]; + rotated_mac[j++] |= b & mac_started & ~mac_ended; + j &= constant_time_lt(j, md_size); + } + + /* Now rotate the MAC */ +#if defined(CBC_MAC_ROTATE_IN_PLACE) + j = 0; + for (i = 0; i < md_size; i++) { + /* in case cache-line is 32 bytes, touch second line */ + ((volatile unsigned char *)rotated_mac)[rotate_offset^32]; + out[j++] = rotated_mac[rotate_offset++]; + rotate_offset &= constant_time_lt(rotate_offset, md_size); + } +#else + memset(out, 0, md_size); + rotate_offset = md_size - rotate_offset; + rotate_offset &= constant_time_lt(rotate_offset, md_size); + for (i = 0; i < md_size; i++) { + for (j = 0; j < md_size; j++) + out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset); + rotate_offset++; + rotate_offset &= constant_time_lt(rotate_offset, md_size); + } +#endif +} + +/* u32toLE serialises an unsigned, 32-bit number (n) as four bytes at (p) in + * little-endian order. The value of p is advanced by four. */ +#define u32toLE(n, p) \ + (*((p)++)=(unsigned char)(n), \ + *((p)++)=(unsigned char)(n>>8), \ + *((p)++)=(unsigned char)(n>>16), \ + *((p)++)=(unsigned char)(n>>24)) + +/* These functions serialize the state of a hash and thus perform the standard + * "final" operation without adding the padding and length that such a function + * typically does. */ +static void +tls1_md5_final_raw(void* ctx, unsigned char *md_out) +{ + MD5_CTX *md5 = ctx; + u32toLE(md5->A, md_out); + u32toLE(md5->B, md_out); + u32toLE(md5->C, md_out); + u32toLE(md5->D, md_out); +} + +static void +tls1_sha1_final_raw(void* ctx, unsigned char *md_out) +{ + SHA_CTX *sha1 = ctx; + l2n(sha1->h0, md_out); + l2n(sha1->h1, md_out); + l2n(sha1->h2, md_out); + l2n(sha1->h3, md_out); + l2n(sha1->h4, md_out); +} +#define LARGEST_DIGEST_CTX SHA_CTX + +static void +tls1_sha256_final_raw(void* ctx, unsigned char *md_out) +{ + SHA256_CTX *sha256 = ctx; + unsigned i; + + for (i = 0; i < 8; i++) { + l2n(sha256->h[i], md_out); + } +} +#undef LARGEST_DIGEST_CTX +#define LARGEST_DIGEST_CTX SHA256_CTX + +static void +tls1_sha512_final_raw(void* ctx, unsigned char *md_out) +{ + SHA512_CTX *sha512 = ctx; + unsigned i; + + for (i = 0; i < 8; i++) { + l2n8(sha512->h[i], md_out); + } +} +#undef LARGEST_DIGEST_CTX +#define LARGEST_DIGEST_CTX SHA512_CTX + +/* ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function + * which ssl3_cbc_digest_record supports. */ +char +ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx) +{ + switch (EVP_MD_CTX_type(ctx)) { + case NID_md5: + case NID_sha1: + case NID_sha224: + case NID_sha256: + case NID_sha384: + case NID_sha512: + return 1; + default: + return 0; + } +} + +/* ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS + * record. + * + * ctx: the EVP_MD_CTX from which we take the hash function. + * ssl3_cbc_record_digest_supported must return true for this EVP_MD_CTX. + * md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written. + * md_out_size: if non-NULL, the number of output bytes is written here. + * header: the 13-byte, TLS record header. + * data: the record data itself, less any preceeding explicit IV. + * data_plus_mac_size: the secret, reported length of the data and MAC + * once the padding has been removed. + * data_plus_mac_plus_padding_size: the public length of the whole + * record, including padding. + * is_sslv3: non-zero if we are to use SSLv3. Otherwise, TLS. + * + * On entry: by virtue of having been through one of the remove_padding + * functions, above, we know that data_plus_mac_size is large enough to contain + * a padding byte and MAC. (If the padding was invalid, it might contain the + * padding too. ) */ +int +ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, unsigned char* md_out, + size_t* md_out_size, const unsigned char header[13], + const unsigned char *data, size_t data_plus_mac_size, + size_t data_plus_mac_plus_padding_size, const unsigned char *mac_secret, + unsigned mac_secret_length, char is_sslv3) +{ + union { double align; + unsigned char c[sizeof(LARGEST_DIGEST_CTX)]; + } md_state; + void (*md_final_raw)(void *ctx, unsigned char *md_out); + void (*md_transform)(void *ctx, const unsigned char *block); + unsigned md_size, md_block_size = 64; + unsigned sslv3_pad_length = 40, header_length, variance_blocks, + len, max_mac_bytes, num_blocks, + num_starting_blocks, k, mac_end_offset, c, index_a, index_b; + unsigned int bits; /* at most 18 bits */ + unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES]; + /* hmac_pad is the masked HMAC key. */ + unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE]; + unsigned char first_block[MAX_HASH_BLOCK_SIZE]; + unsigned char mac_out[EVP_MAX_MD_SIZE]; + unsigned i, j, md_out_size_u; + EVP_MD_CTX md_ctx; + /* mdLengthSize is the number of bytes in the length field that terminates + * the hash. */ + unsigned md_length_size = 8; + char length_is_big_endian = 1; + + /* This is a, hopefully redundant, check that allows us to forget about + * many possible overflows later in this function. */ + OPENSSL_assert(data_plus_mac_plus_padding_size < 1024*1024); + + switch (EVP_MD_CTX_type(ctx)) { + case NID_md5: + MD5_Init((MD5_CTX*)md_state.c); + md_final_raw = tls1_md5_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) MD5_Transform; + md_size = 16; + sslv3_pad_length = 48; + length_is_big_endian = 0; + break; + case NID_sha1: + SHA1_Init((SHA_CTX*)md_state.c); + md_final_raw = tls1_sha1_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA1_Transform; + md_size = 20; + break; + case NID_sha224: + SHA224_Init((SHA256_CTX*)md_state.c); + md_final_raw = tls1_sha256_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform; + md_size = 224/8; + break; + case NID_sha256: + SHA256_Init((SHA256_CTX*)md_state.c); + md_final_raw = tls1_sha256_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform; + md_size = 32; + break; + case NID_sha384: + SHA384_Init((SHA512_CTX*)md_state.c); + md_final_raw = tls1_sha512_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform; + md_size = 384/8; + md_block_size = 128; + md_length_size = 16; + break; + case NID_sha512: + SHA512_Init((SHA512_CTX*)md_state.c); + md_final_raw = tls1_sha512_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform; + md_size = 64; + md_block_size = 128; + md_length_size = 16; + break; + default: + /* ssl3_cbc_record_digest_supported should have been + * called first to check that the hash function is + * supported. */ + OPENSSL_assert(0); + if (md_out_size) + *md_out_size = 0; + return 0; + } + + OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES); + OPENSSL_assert(md_block_size <= MAX_HASH_BLOCK_SIZE); + OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); + + header_length = 13; + if (is_sslv3) { + header_length = mac_secret_length + sslv3_pad_length + + 8 /* sequence number */ + + 1 /* record type */ + + 2 /* record length */; + } + + /* variance_blocks is the number of blocks of the hash that we have to + * calculate in constant time because they could be altered by the + * padding value. + * + * In SSLv3, the padding must be minimal so the end of the plaintext + * varies by, at most, 15+20 = 35 bytes. (We conservatively assume that + * the MAC size varies from 0..20 bytes.) In case the 9 bytes of hash + * termination (0x80 + 64-bit length) don't fit in the final block, we + * say that the final two blocks can vary based on the padding. + * + * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not + * required to be minimal. Therefore we say that the final six blocks + * can vary based on the padding. + * + * Later in the function, if the message is short and there obviously + * cannot be this many blocks then variance_blocks can be reduced. */ + variance_blocks = is_sslv3 ? 2 : 6; + /* From now on we're dealing with the MAC, which conceptually has 13 + * bytes of `header' before the start of the data (TLS) or 71/75 bytes + * (SSLv3) */ + len = data_plus_mac_plus_padding_size + header_length; + /* max_mac_bytes contains the maximum bytes of bytes in the MAC, including + * |header|, assuming that there's no padding. */ + max_mac_bytes = len - md_size - 1; + /* num_blocks is the maximum number of hash blocks. */ + num_blocks = (max_mac_bytes + 1 + md_length_size + md_block_size - 1) / md_block_size; + /* In order to calculate the MAC in constant time we have to handle + * the final blocks specially because the padding value could cause the + * end to appear somewhere in the final |variance_blocks| blocks and we + * can't leak where. However, |num_starting_blocks| worth of data can + * be hashed right away because no padding value can affect whether + * they are plaintext. */ + num_starting_blocks = 0; + /* k is the starting byte offset into the conceptual header||data where + * we start processing. */ + k = 0; + /* mac_end_offset is the index just past the end of the data to be + * MACed. */ + mac_end_offset = data_plus_mac_size + header_length - md_size; + /* c is the index of the 0x80 byte in the final hash block that + * contains application data. */ + c = mac_end_offset % md_block_size; + /* index_a is the hash block number that contains the 0x80 terminating + * value. */ + index_a = mac_end_offset / md_block_size; + /* index_b is the hash block number that contains the 64-bit hash + * length, in bits. */ + index_b = (mac_end_offset + md_length_size) / md_block_size; + /* bits is the hash-length in bits. It includes the additional hash + * block for the masked HMAC key, or whole of |header| in the case of + * SSLv3. */ + + /* For SSLv3, if we're going to have any starting blocks then we need + * at least two because the header is larger than a single block. */ + if (num_blocks > variance_blocks + (is_sslv3 ? 1 : 0)) { + num_starting_blocks = num_blocks - variance_blocks; + k = md_block_size*num_starting_blocks; + } + + bits = 8*mac_end_offset; + if (!is_sslv3) { + /* Compute the initial HMAC block. For SSLv3, the padding and + * secret bytes are included in |header| because they take more + * than a single block. */ + bits += 8*md_block_size; + memset(hmac_pad, 0, md_block_size); + OPENSSL_assert(mac_secret_length <= sizeof(hmac_pad)); + memcpy(hmac_pad, mac_secret, mac_secret_length); + for (i = 0; i < md_block_size; i++) + hmac_pad[i] ^= 0x36; + + md_transform(md_state.c, hmac_pad); + } + + if (length_is_big_endian) { + memset(length_bytes, 0, md_length_size - 4); + length_bytes[md_length_size - 4] = (unsigned char)(bits >> 24); + length_bytes[md_length_size - 3] = (unsigned char)(bits >> 16); + length_bytes[md_length_size - 2] = (unsigned char)(bits >> 8); + length_bytes[md_length_size - 1] = (unsigned char)bits; + } else { + memset(length_bytes, 0, md_length_size); + length_bytes[md_length_size - 5] = (unsigned char)(bits >> 24); + length_bytes[md_length_size - 6] = (unsigned char)(bits >> 16); + length_bytes[md_length_size - 7] = (unsigned char)(bits >> 8); + length_bytes[md_length_size - 8] = (unsigned char)bits; + } + + if (k > 0) { + if (is_sslv3) { + /* The SSLv3 header is larger than a single block. + * overhang is the number of bytes beyond a single + * block that the header consumes: either 7 bytes + * (SHA1) or 11 bytes (MD5). */ + unsigned overhang = header_length - md_block_size; + md_transform(md_state.c, header); + memcpy(first_block, header + md_block_size, overhang); + memcpy(first_block + overhang, data, md_block_size - overhang); + md_transform(md_state.c, first_block); + for (i = 1; i < k/md_block_size - 1; i++) + md_transform(md_state.c, data + md_block_size*i - overhang); + } else { + /* k is a multiple of md_block_size. */ + memcpy(first_block, header, 13); + memcpy(first_block + 13, data, md_block_size - 13); + md_transform(md_state.c, first_block); + for (i = 1; i < k/md_block_size; i++) + md_transform(md_state.c, data + md_block_size*i - 13); + } + } + + memset(mac_out, 0, sizeof(mac_out)); + + /* We now process the final hash blocks. For each block, we construct + * it in constant time. If the |i==index_a| then we'll include the 0x80 + * bytes and zero pad etc. For each block we selectively copy it, in + * constant time, to |mac_out|. */ + for (i = num_starting_blocks; i <= num_starting_blocks + variance_blocks; i++) { + unsigned char block[MAX_HASH_BLOCK_SIZE]; + unsigned char is_block_a = constant_time_eq_8(i, index_a); + unsigned char is_block_b = constant_time_eq_8(i, index_b); + for (j = 0; j < md_block_size; j++) { + unsigned char b = 0, is_past_c, is_past_cp1; + if (k < header_length) + b = header[k]; + else if (k < data_plus_mac_plus_padding_size + header_length) + b = data[k - header_length]; + k++; + + is_past_c = is_block_a & constant_time_ge(j, c); + is_past_cp1 = is_block_a & constant_time_ge(j, c + 1); + /* If this is the block containing the end of the + * application data, and we are at the offset for the + * 0x80 value, then overwrite b with 0x80. */ + b = (b&~is_past_c) | (0x80&is_past_c); + /* If this is the block containing the end of the + * application data and we're past the 0x80 value then + * just write zero. */ + b = b&~is_past_cp1; + /* If this is index_b (the final block), but not + * index_a (the end of the data), then the 64-bit + * length didn't fit into index_a and we're having to + * add an extra block of zeros. */ + b &= ~is_block_b | is_block_a; + + /* The final bytes of one of the blocks contains the + * length. */ + if (j >= md_block_size - md_length_size) { + /* If this is index_b, write a length byte. */ + b = (b&~is_block_b) | (is_block_b&length_bytes[j - (md_block_size - md_length_size)]); + } + block[j] = b; + } + + md_transform(md_state.c, block); + md_final_raw(md_state.c, block); + /* If this is index_b, copy the hash value to |mac_out|. */ + for (j = 0; j < md_size; j++) + mac_out[j] |= block[j]&is_block_b; + } + + EVP_MD_CTX_init(&md_ctx); + if (!EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */)) { + EVP_MD_CTX_cleanup(&md_ctx); + return 0; + } + if (is_sslv3) { + /* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */ + memset(hmac_pad, 0x5c, sslv3_pad_length); + + EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length); + EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length); + EVP_DigestUpdate(&md_ctx, mac_out, md_size); + } else { + /* Complete the HMAC in the standard manner. */ + for (i = 0; i < md_block_size; i++) + hmac_pad[i] ^= 0x6a; + + EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size); + EVP_DigestUpdate(&md_ctx, mac_out, md_size); + } + EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u); + if (md_out_size) + *md_out_size = md_out_size_u; + EVP_MD_CTX_cleanup(&md_ctx); + + return 1; +} diff --git a/crypto/libressl/ssl/s3_clnt.c b/crypto/libressl/ssl/s3_clnt.c new file mode 100644 index 0000000000..5e31e9aeec --- /dev/null +++ b/crypto/libressl/ssl/s3_clnt.c @@ -0,0 +1,2635 @@ +/* $OpenBSD: s3_clnt.c,v 1.137 2016/03/11 07:08:45 mmcc Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +#include +#include + +#include "ssl_locl.h" + +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_NO_ENGINE +#include +#endif +#ifndef OPENSSL_NO_GOST +#include +#endif + +#include "bytestring.h" + +static int ca_dn_cmp(const X509_NAME * const *a, const X509_NAME * const *b); + +int +ssl3_connect(SSL *s) +{ + void (*cb)(const SSL *ssl, int type, int val) = NULL; + int ret = -1; + int new_state, state, skip = 0; + + ERR_clear_error(); + errno = 0; + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_RENEGOTIATE: + s->renegotiate = 1; + s->state = SSL_ST_CONNECT; + s->ctx->stats.sess_connect_renegotiate++; + /* break */ + case SSL_ST_BEFORE: + case SSL_ST_CONNECT: + case SSL_ST_BEFORE|SSL_ST_CONNECT: + case SSL_ST_OK|SSL_ST_CONNECT: + + s->server = 0; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + if ((s->version & 0xff00 ) != 0x0300) { + SSLerr(SSL_F_SSL3_CONNECT, + ERR_R_INTERNAL_ERROR); + ret = -1; + goto end; + } + + /* s->version=SSL3_VERSION; */ + s->type = SSL_ST_CONNECT; + + if (!ssl3_setup_init_buffer(s)) { + ret = -1; + goto end; + } + if (!ssl3_setup_buffers(s)) { + ret = -1; + goto end; + } + if (!ssl_init_wbio_buffer(s, 0)) { + ret = -1; + goto end; + } + + /* don't push the buffering BIO quite yet */ + + if (!tls1_init_finished_mac(s)) { + ret = -1; + goto end; + } + + s->state = SSL3_ST_CW_CLNT_HELLO_A; + s->ctx->stats.sess_connect++; + s->init_num = 0; + break; + + case SSL3_ST_CW_CLNT_HELLO_A: + case SSL3_ST_CW_CLNT_HELLO_B: + + s->shutdown = 0; + ret = ssl3_client_hello(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_SRVR_HELLO_A; + s->init_num = 0; + + /* turn on buffering for the next lot of output */ + if (s->bbio != s->wbio) + s->wbio = BIO_push(s->bbio, s->wbio); + + break; + + case SSL3_ST_CR_SRVR_HELLO_A: + case SSL3_ST_CR_SRVR_HELLO_B: + ret = ssl3_get_server_hello(s); + if (ret <= 0) + goto end; + + if (s->hit) { + s->state = SSL3_ST_CR_FINISHED_A; + if (s->tlsext_ticket_expected) { + /* receive renewed session ticket */ + s->state = SSL3_ST_CR_SESSION_TICKET_A; + } + } else + s->state = SSL3_ST_CR_CERT_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_CERT_A: + case SSL3_ST_CR_CERT_B: + ret = ssl3_check_finished(s); + if (ret <= 0) + goto end; + if (ret == 2) { + s->hit = 1; + if (s->tlsext_ticket_expected) + s->state = SSL3_ST_CR_SESSION_TICKET_A; + else + s->state = SSL3_ST_CR_FINISHED_A; + s->init_num = 0; + break; + } + /* Check if it is anon DH/ECDH. */ + if (!(s->s3->tmp.new_cipher->algorithm_auth & + SSL_aNULL)) { + ret = ssl3_get_server_certificate(s); + if (ret <= 0) + goto end; + if (s->tlsext_status_expected) + s->state = SSL3_ST_CR_CERT_STATUS_A; + else + s->state = SSL3_ST_CR_KEY_EXCH_A; + } else { + skip = 1; + s->state = SSL3_ST_CR_KEY_EXCH_A; + } + s->init_num = 0; + break; + + case SSL3_ST_CR_KEY_EXCH_A: + case SSL3_ST_CR_KEY_EXCH_B: + ret = ssl3_get_key_exchange(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_CERT_REQ_A; + s->init_num = 0; + + /* + * At this point we check that we have the + * required stuff from the server. + */ + if (!ssl3_check_cert_and_algorithm(s)) { + ret = -1; + goto end; + } + break; + + case SSL3_ST_CR_CERT_REQ_A: + case SSL3_ST_CR_CERT_REQ_B: + ret = ssl3_get_certificate_request(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_SRVR_DONE_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_SRVR_DONE_A: + case SSL3_ST_CR_SRVR_DONE_B: + ret = ssl3_get_server_done(s); + if (ret <= 0) + goto end; + if (s->s3->tmp.cert_req) + s->state = SSL3_ST_CW_CERT_A; + else + s->state = SSL3_ST_CW_KEY_EXCH_A; + s->init_num = 0; + + break; + + case SSL3_ST_CW_CERT_A: + case SSL3_ST_CW_CERT_B: + case SSL3_ST_CW_CERT_C: + case SSL3_ST_CW_CERT_D: + ret = ssl3_send_client_certificate(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CW_KEY_EXCH_A; + s->init_num = 0; + break; + + case SSL3_ST_CW_KEY_EXCH_A: + case SSL3_ST_CW_KEY_EXCH_B: + ret = ssl3_send_client_key_exchange(s); + if (ret <= 0) + goto end; + /* + * EAY EAY EAY need to check for DH fix cert + * sent back + */ + /* + * For TLS, cert_req is set to 2, so a cert chain + * of nothing is sent, but no verify packet is sent + */ + /* + * XXX: For now, we do not support client + * authentication in ECDH cipher suites with + * ECDH (rather than ECDSA) certificates. + * We need to skip the certificate verify + * message when client's ECDH public key is sent + * inside the client certificate. + */ + if (s->s3->tmp.cert_req == 1) { + s->state = SSL3_ST_CW_CERT_VRFY_A; + } else { + s->state = SSL3_ST_CW_CHANGE_A; + s->s3->change_cipher_spec = 0; + } + if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) { + s->state = SSL3_ST_CW_CHANGE_A; + s->s3->change_cipher_spec = 0; + } + + s->init_num = 0; + break; + + case SSL3_ST_CW_CERT_VRFY_A: + case SSL3_ST_CW_CERT_VRFY_B: + ret = ssl3_send_client_verify(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CW_CHANGE_A; + s->init_num = 0; + s->s3->change_cipher_spec = 0; + break; + + case SSL3_ST_CW_CHANGE_A: + case SSL3_ST_CW_CHANGE_B: + ret = ssl3_send_change_cipher_spec(s, + SSL3_ST_CW_CHANGE_A, SSL3_ST_CW_CHANGE_B); + if (ret <= 0) + goto end; + + if (s->s3->next_proto_neg_seen) + s->state = SSL3_ST_CW_NEXT_PROTO_A; + else + s->state = SSL3_ST_CW_FINISHED_A; + s->init_num = 0; + + s->session->cipher = s->s3->tmp.new_cipher; + if (!s->method->ssl3_enc->setup_key_block(s)) { + ret = -1; + goto end; + } + + if (!s->method->ssl3_enc->change_cipher_state(s, + SSL3_CHANGE_CIPHER_CLIENT_WRITE)) { + ret = -1; + goto end; + } + + break; + + case SSL3_ST_CW_NEXT_PROTO_A: + case SSL3_ST_CW_NEXT_PROTO_B: + ret = ssl3_send_next_proto(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CW_FINISHED_A; + break; + + case SSL3_ST_CW_FINISHED_A: + case SSL3_ST_CW_FINISHED_B: + ret = ssl3_send_finished(s, SSL3_ST_CW_FINISHED_A, + SSL3_ST_CW_FINISHED_B, + s->method->ssl3_enc->client_finished_label, + s->method->ssl3_enc->client_finished_label_len); + if (ret <= 0) + goto end; + s->s3->flags |= SSL3_FLAGS_CCS_OK; + s->state = SSL3_ST_CW_FLUSH; + + /* clear flags */ + s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER; + if (s->hit) { + s->s3->tmp.next_state = SSL_ST_OK; + if (s->s3->flags & + SSL3_FLAGS_DELAY_CLIENT_FINISHED) { + s->state = SSL_ST_OK; + s->s3->flags|=SSL3_FLAGS_POP_BUFFER; + s->s3->delay_buf_pop_ret = 0; + } + } else { + /* Allow NewSessionTicket if ticket expected */ + if (s->tlsext_ticket_expected) + s->s3->tmp.next_state = + SSL3_ST_CR_SESSION_TICKET_A; + else + + s->s3->tmp.next_state = SSL3_ST_CR_FINISHED_A; + } + s->init_num = 0; + break; + + case SSL3_ST_CR_SESSION_TICKET_A: + case SSL3_ST_CR_SESSION_TICKET_B: + ret = ssl3_get_new_session_ticket(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_FINISHED_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_CERT_STATUS_A: + case SSL3_ST_CR_CERT_STATUS_B: + ret = ssl3_get_cert_status(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_KEY_EXCH_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_FINISHED_A: + case SSL3_ST_CR_FINISHED_B: + s->s3->flags |= SSL3_FLAGS_CCS_OK; + ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, + SSL3_ST_CR_FINISHED_B); + if (ret <= 0) + goto end; + + if (s->hit) + s->state = SSL3_ST_CW_CHANGE_A; + else + s->state = SSL_ST_OK; + s->init_num = 0; + break; + + case SSL3_ST_CW_FLUSH: + s->rwstate = SSL_WRITING; + if (BIO_flush(s->wbio) <= 0) { + ret = -1; + goto end; + } + s->rwstate = SSL_NOTHING; + s->state = s->s3->tmp.next_state; + break; + + case SSL_ST_OK: + /* clean a few things up */ + tls1_cleanup_key_block(s); + + if (s->init_buf != NULL) { + BUF_MEM_free(s->init_buf); + s->init_buf = NULL; + } + + /* + * If we are not 'joining' the last two packets, + * remove the buffering now + */ + if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER)) + ssl_free_wbio_buffer(s); + /* else do it later in ssl3_write */ + + s->init_num = 0; + s->renegotiate = 0; + s->new_session = 0; + + ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); + if (s->hit) + s->ctx->stats.sess_hit++; + + ret = 1; + /* s->server=0; */ + s->handshake_func = ssl3_connect; + s->ctx->stats.sess_connect_good++; + + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_DONE, 1); + + goto end; + /* break; */ + + default: + SSLerr(SSL_F_SSL3_CONNECT, + SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* break; */ + } + + /* did we do anything */ + if (!s->s3->tmp.reuse_message && !skip) { + if (s->debug) { + if ((ret = BIO_flush(s->wbio)) <= 0) + goto end; + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_CONNECT_LOOP, 1); + s->state = new_state; + } + } + skip = 0; + } + +end: + s->in_handshake--; + if (cb != NULL) + cb(s, SSL_CB_CONNECT_EXIT, ret); + + return (ret); +} + +int +ssl3_client_hello(SSL *s) +{ + unsigned char *bufend, *p, *d; + int i; + + if (s->state == SSL3_ST_CW_CLNT_HELLO_A) { + SSL_SESSION *sess = s->session; + + if ((sess == NULL) || + (sess->ssl_version != s->version) || + (!sess->session_id_length && !sess->tlsext_tick) || + (sess->not_resumable)) { + if (!ssl_get_new_session(s, 0)) + goto err; + } + /* else use the pre-loaded session */ + + /* + * If a DTLS ClientHello message is being resent after a + * HelloVerifyRequest, we must retain the original client + * random value. + */ + if (!SSL_IS_DTLS(s) || s->d1->send_cookie == 0) + arc4random_buf(s->s3->client_random, SSL3_RANDOM_SIZE); + + d = p = ssl3_handshake_msg_start(s, SSL3_MT_CLIENT_HELLO); + + /* + * Version indicates the negotiated version: for example from + * an SSLv2/v3 compatible client hello). The client_version + * field is the maximum version we permit and it is also + * used in RSA encrypted premaster secrets. Some servers can + * choke if we initially report a higher version then + * renegotiate to a lower one in the premaster secret. This + * didn't happen with TLS 1.0 as most servers supported it + * but it can with TLS 1.1 or later if the server only supports + * 1.0. + * + * Possible scenario with previous logic: + * 1. Client hello indicates TLS 1.2 + * 2. Server hello says TLS 1.0 + * 3. RSA encrypted premaster secret uses 1.2. + * 4. Handhaked proceeds using TLS 1.0. + * 5. Server sends hello request to renegotiate. + * 6. Client hello indicates TLS v1.0 as we now + * know that is maximum server supports. + * 7. Server chokes on RSA encrypted premaster secret + * containing version 1.0. + * + * For interoperability it should be OK to always use the + * maximum version we support in client hello and then rely + * on the checking of version to ensure the servers isn't + * being inconsistent: for example initially negotiating with + * TLS 1.0 and renegotiating with TLS 1.2. We do this by using + * client_version in client hello and not resetting it to + * the negotiated version. + */ + *(p++) = s->client_version >> 8; + *(p++) = s->client_version & 0xff; + + /* Random stuff */ + memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + + /* Session ID */ + if (s->new_session) + i = 0; + else + i = s->session->session_id_length; + *(p++) = i; + if (i != 0) { + if (i > (int)sizeof(s->session->session_id)) { + SSLerr(SSL_F_SSL3_CLIENT_HELLO, + ERR_R_INTERNAL_ERROR); + goto err; + } + memcpy(p, s->session->session_id, i); + p += i; + } + + /* DTLS Cookie. */ + if (SSL_IS_DTLS(s)) { + if (s->d1->cookie_len > sizeof(s->d1->cookie)) { + SSLerr(SSL_F_DTLS1_CLIENT_HELLO, + ERR_R_INTERNAL_ERROR); + goto err; + } + *(p++) = s->d1->cookie_len; + memcpy(p, s->d1->cookie, s->d1->cookie_len); + p += s->d1->cookie_len; + } + + /* Ciphers supported */ + i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &p[2]); + if (i == 0) { + SSLerr(SSL_F_SSL3_CLIENT_HELLO, + SSL_R_NO_CIPHERS_AVAILABLE); + goto err; + } + s2n(i, p); + p += i; + + /* add in (no) COMPRESSION */ + *(p++) = 1; + *(p++) = 0; /* Add the NULL method */ + + /* TLS extensions*/ + bufend = (unsigned char *)s->init_buf->data + + SSL3_RT_MAX_PLAIN_LENGTH; + if ((p = ssl_add_clienthello_tlsext(s, p, bufend)) == NULL) { + SSLerr(SSL_F_SSL3_CLIENT_HELLO, + ERR_R_INTERNAL_ERROR); + goto err; + } + + ssl3_handshake_msg_finish(s, p - d); + + s->state = SSL3_ST_CW_CLNT_HELLO_B; + } + + /* SSL3_ST_CW_CLNT_HELLO_B */ + return (ssl3_handshake_write(s)); + +err: + return (-1); +} + +int +ssl3_get_server_hello(SSL *s) +{ + STACK_OF(SSL_CIPHER) *sk; + const SSL_CIPHER *c; + unsigned char *p, *q, *d; + int i, al, ok; + unsigned int j; + uint16_t cipher_value; + long n; + unsigned long alg_k; + + n = s->method->ssl_get_message(s, SSL3_ST_CR_SRVR_HELLO_A, + SSL3_ST_CR_SRVR_HELLO_B, -1, 20000, /* ?? */ &ok); + + if (!ok) + return ((int)n); + + if (SSL_IS_DTLS(s)) { + if (s->s3->tmp.message_type == DTLS1_MT_HELLO_VERIFY_REQUEST) { + if (s->d1->send_cookie == 0) { + s->s3->tmp.reuse_message = 1; + return (1); + } else { + /* Already sent a cookie. */ + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_BAD_MESSAGE_TYPE); + goto f_err; + } + } + } + + if (s->s3->tmp.message_type != SSL3_MT_SERVER_HELLO) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_BAD_MESSAGE_TYPE); + goto f_err; + } + + d = p = (unsigned char *)s->init_msg; + + if (2 > n) + goto truncated; + if ((p[0] != (s->version >> 8)) || (p[1] != (s->version & 0xff))) { + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_SSL_VERSION); + s->version = (s->version&0xff00) | p[1]; + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; + } + p += 2; + + /* load the server hello data */ + + if (p + SSL3_RANDOM_SIZE + 1 - d > n) + goto truncated; + + /* load the server random */ + memcpy(s->s3->server_random, p, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + + /* get the session-id */ + j = *(p++); + + if ((j > sizeof s->session->session_id) || + (j > SSL3_SESSION_ID_SIZE)) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_SSL3_SESSION_ID_TOO_LONG); + goto f_err; + } + + if (p + j + 2 - d > n) + goto truncated; + + /* Get the cipher value. */ + q = p + j; + n2s(q, cipher_value); + + /* + * Check if we want to resume the session based on external + * pre-shared secret + */ + if (s->tls_session_secret_cb) { + SSL_CIPHER *pref_cipher = NULL; + s->session->master_key_length = sizeof(s->session->master_key); + if (s->tls_session_secret_cb(s, s->session->master_key, + &s->session->master_key_length, NULL, &pref_cipher, + s->tls_session_secret_cb_arg)) { + s->session->cipher = pref_cipher ? pref_cipher : + ssl3_get_cipher_by_value(cipher_value); + s->s3->flags |= SSL3_FLAGS_CCS_OK; + } + } + + if (j != 0 && j == s->session->session_id_length && + timingsafe_memcmp(p, s->session->session_id, j) == 0) { + if (s->sid_ctx_length != s->session->sid_ctx_length || + timingsafe_memcmp(s->session->sid_ctx, + s->sid_ctx, s->sid_ctx_length) != 0) { + /* actually a client application bug */ + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); + goto f_err; + } + s->s3->flags |= SSL3_FLAGS_CCS_OK; + s->hit = 1; + } else { + /* a miss or crap from the other end */ + + /* If we were trying for session-id reuse, make a new + * SSL_SESSION so we don't stuff up other people */ + s->hit = 0; + if (s->session->session_id_length > 0) { + if (!ssl_get_new_session(s, 0)) { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + } + s->session->session_id_length = j; + memcpy(s->session->session_id, p, j); /* j could be 0 */ + } + p += j; + + if ((c = ssl3_get_cipher_by_value(cipher_value)) == NULL) { + /* unknown cipher */ + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_UNKNOWN_CIPHER_RETURNED); + goto f_err; + } + + /* TLS v1.2 only ciphersuites require v1.2 or later */ + if ((c->algorithm_ssl & SSL_TLSV1_2) && + (TLS1_get_version(s) < TLS1_2_VERSION)) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_WRONG_CIPHER_RETURNED); + goto f_err; + } + p += SSL3_CIPHER_VALUE_SIZE; + + sk = ssl_get_ciphers_by_id(s); + i = sk_SSL_CIPHER_find(sk, c); + if (i < 0) { + /* we did not say we would use this cipher */ + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_WRONG_CIPHER_RETURNED); + goto f_err; + } + + /* + * Depending on the session caching (internal/external), the cipher + * and/or cipher_id values may not be set. Make sure that + * cipher_id is set and use it for comparison. + */ + if (s->session->cipher) + s->session->cipher_id = s->session->cipher->id; + if (s->hit && (s->session->cipher_id != c->id)) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED); + goto f_err; + } + s->s3->tmp.new_cipher = c; + /* + * Don't digest cached records if no sigalgs: we may need them for + * client authentication. + */ + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + if (!(SSL_USE_SIGALGS(s) || (alg_k & SSL_kGOST)) && + !tls1_digest_cached_records(s)) { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + /* lets get the compression algorithm */ + /* COMPRESSION */ + if (p + 1 - d > n) + goto truncated; + if (*(p++) != 0) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + goto f_err; + } + + /* TLS extensions*/ + if (!ssl_parse_serverhello_tlsext(s, &p, d, n, &al)) { + /* 'al' set by ssl_parse_serverhello_tlsext */ + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_PARSE_TLSEXT); + goto f_err; + } + if (ssl_check_serverhello_tlsext(s) <= 0) { + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_SERVERHELLO_TLSEXT); + goto err; + } + + if (p != d + n) + goto truncated; + + return (1); + +truncated: + /* wrong packet length */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_BAD_PACKET_LENGTH); +f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); +err: + return (-1); +} + +int +ssl3_get_server_certificate(SSL *s) +{ + int al, i, ok, ret = -1; + long n; + CBS cbs, cert_list; + X509 *x = NULL; + const unsigned char *q; + STACK_OF(X509) *sk = NULL; + SESS_CERT *sc; + EVP_PKEY *pkey = NULL; + + n = s->method->ssl_get_message(s, SSL3_ST_CR_CERT_A, + SSL3_ST_CR_CERT_B, -1, s->max_cert_list, &ok); + + if (!ok) + return ((int)n); + + if (s->s3->tmp.message_type == SSL3_MT_SERVER_KEY_EXCHANGE) { + s->s3->tmp.reuse_message = 1; + return (1); + } + + if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_BAD_MESSAGE_TYPE); + goto f_err; + } + + + if ((sk = sk_X509_new_null()) == NULL) { + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if (n < 0) + goto truncated; + + CBS_init(&cbs, s->init_msg, n); + if (CBS_len(&cbs) < 3) + goto truncated; + + if (!CBS_get_u24_length_prefixed(&cbs, &cert_list) || + CBS_len(&cbs) != 0) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_LENGTH_MISMATCH); + goto f_err; + } + + while (CBS_len(&cert_list) > 0) { + CBS cert; + + if (CBS_len(&cert_list) < 3) + goto truncated; + if (!CBS_get_u24_length_prefixed(&cert_list, &cert)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_CERT_LENGTH_MISMATCH); + goto f_err; + } + + q = CBS_data(&cert); + x = d2i_X509(NULL, &q, CBS_len(&cert)); + if (x == NULL) { + al = SSL_AD_BAD_CERTIFICATE; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + ERR_R_ASN1_LIB); + goto f_err; + } + if (q != CBS_data(&cert) + CBS_len(&cert)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_CERT_LENGTH_MISMATCH); + goto f_err; + } + if (!sk_X509_push(sk, x)) { + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + ERR_R_MALLOC_FAILURE); + goto err; + } + x = NULL; + } + + i = ssl_verify_cert_chain(s, sk); + if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0)) { + al = ssl_verify_alarm_type(s->verify_result); + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_CERTIFICATE_VERIFY_FAILED); + goto f_err; + + } + ERR_clear_error(); /* but we keep s->verify_result */ + + sc = ssl_sess_cert_new(); + if (sc == NULL) + goto err; + if (s->session->sess_cert) + ssl_sess_cert_free(s->session->sess_cert); + s->session->sess_cert = sc; + + sc->cert_chain = sk; + /* + * Inconsistency alert: cert_chain does include the peer's + * certificate, which we don't include in s3_srvr.c + */ + x = sk_X509_value(sk, 0); + sk = NULL; + /* VRS 19990621: possible memory leak; sk=null ==> !sk_pop_free() @end*/ + + pkey = X509_get_pubkey(x); + + if (pkey == NULL || EVP_PKEY_missing_parameters(pkey)) { + x = NULL; + al = SSL3_AL_FATAL; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS); + goto f_err; + } + + i = ssl_cert_type(x, pkey); + if (i < 0) { + x = NULL; + al = SSL3_AL_FATAL; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_UNKNOWN_CERTIFICATE_TYPE); + goto f_err; + } + + sc->peer_cert_type = i; + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + /* + * Why would the following ever happen? + * We just created sc a couple of lines ago. + */ + X509_free(sc->peer_pkeys[i].x509); + sc->peer_pkeys[i].x509 = x; + sc->peer_key = &(sc->peer_pkeys[i]); + + X509_free(s->session->peer); + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + s->session->peer = x; + s->session->verify_result = s->verify_result; + + x = NULL; + ret = 1; + + if (0) { +truncated: + /* wrong packet length */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_BAD_PACKET_LENGTH); +f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + } +err: + EVP_PKEY_free(pkey); + X509_free(x); + sk_X509_pop_free(sk, X509_free); + return (ret); +} + +int +ssl3_get_key_exchange(SSL *s) +{ + unsigned char *q, md_buf[EVP_MAX_MD_SIZE*2]; + EVP_MD_CTX md_ctx; + unsigned char *param, *p; + int al, i, j, param_len, ok; + long n, alg_k, alg_a; + EVP_PKEY *pkey = NULL; + const EVP_MD *md = NULL; + RSA *rsa = NULL; + DH *dh = NULL; + EC_KEY *ecdh = NULL; + BN_CTX *bn_ctx = NULL; + EC_POINT *srvr_ecpoint = NULL; + int curve_nid = 0; + int encoded_pt_len = 0; + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + alg_a = s->s3->tmp.new_cipher->algorithm_auth; + + /* + * Use same message size as in ssl3_get_certificate_request() + * as ServerKeyExchange message may be skipped. + */ + n = s->method->ssl_get_message(s, SSL3_ST_CR_KEY_EXCH_A, + SSL3_ST_CR_KEY_EXCH_B, -1, s->max_cert_list, &ok); + if (!ok) + return ((int)n); + + EVP_MD_CTX_init(&md_ctx); + + if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE) { + /* + * Do not skip server key exchange if this cipher suite uses + * ephemeral keys. + */ + if (alg_k & (SSL_kDHE|SSL_kECDHE)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_UNEXPECTED_MESSAGE); + al = SSL_AD_UNEXPECTED_MESSAGE; + goto f_err; + } + + s->s3->tmp.reuse_message = 1; + EVP_MD_CTX_cleanup(&md_ctx); + return (1); + } + + if (s->session->sess_cert != NULL) { + DH_free(s->session->sess_cert->peer_dh_tmp); + s->session->sess_cert->peer_dh_tmp = NULL; + + EC_KEY_free(s->session->sess_cert->peer_ecdh_tmp); + s->session->sess_cert->peer_ecdh_tmp = NULL; + } else { + s->session->sess_cert = ssl_sess_cert_new(); + if (s->session->sess_cert == NULL) + goto err; + } + + param = p = (unsigned char *)s->init_msg; + param_len = 0; + + if (alg_k & SSL_kDHE) { + if ((dh = DH_new()) == NULL) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + ERR_R_DH_LIB); + goto err; + } + if (2 > n) + goto truncated; + n2s(p, i); + param_len = i + 2; + if (param_len > n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_BAD_DH_P_LENGTH); + goto f_err; + } + if (!(dh->p = BN_bin2bn(p, i, NULL))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + ERR_R_BN_LIB); + goto err; + } + p += i; + + if (param_len + 2 > n) + goto truncated; + n2s(p, i); + param_len += i + 2; + if (param_len > n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_BAD_DH_G_LENGTH); + goto f_err; + } + if (!(dh->g = BN_bin2bn(p, i, NULL))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + ERR_R_BN_LIB); + goto err; + } + p += i; + + if (param_len + 2 > n) + goto truncated; + n2s(p, i); + param_len += i + 2; + if (param_len > n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_BAD_DH_PUB_KEY_LENGTH); + goto f_err; + } + if (!(dh->pub_key = BN_bin2bn(p, i, NULL))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + ERR_R_BN_LIB); + goto err; + } + p += i; + n -= param_len; + + /* + * Check the strength of the DH key just constructed. + * Discard keys weaker than 1024 bits. + */ + + if (DH_size(dh) < 1024 / 8) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_BAD_DH_P_LENGTH); + goto err; + } + + if (alg_a & SSL_aRSA) + pkey = X509_get_pubkey( + s->session->sess_cert->peer_pkeys[ + SSL_PKEY_RSA_ENC].x509); + else if (alg_a & SSL_aDSS) + pkey = X509_get_pubkey( + s->session->sess_cert->peer_pkeys[ + SSL_PKEY_DSA_SIGN].x509); + /* else anonymous DH, so no certificate or pkey. */ + + s->session->sess_cert->peer_dh_tmp = dh; + dh = NULL; + } else if (alg_k & SSL_kECDHE) { + const EC_GROUP *group; + EC_GROUP *ngroup; + + if ((ecdh = EC_KEY_new()) == NULL) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * Extract elliptic curve parameters and the + * server's ephemeral ECDH public key. + * Keep accumulating lengths of various components in + * param_len and make sure it never exceeds n. + */ + + /* + * XXX: For now we only support named (not generic) curves + * and the ECParameters in this case is just three bytes. + */ + param_len = 3; + if (param_len > n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + + /* + * Check curve is one of our preferences, if not server has + * sent an invalid curve. + */ + if (tls1_check_curve(s, p, param_len) != 1) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_CURVE); + goto f_err; + } + + if ((curve_nid = tls1_ec_curve_id2nid(*(p + 2))) == 0) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS); + goto f_err; + } + + ngroup = EC_GROUP_new_by_curve_name(curve_nid); + if (ngroup == NULL) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + ERR_R_EC_LIB); + goto err; + } + if (EC_KEY_set_group(ecdh, ngroup) == 0) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + ERR_R_EC_LIB); + goto err; + } + EC_GROUP_free(ngroup); + + group = EC_KEY_get0_group(ecdh); + + p += 3; + + /* Next, get the encoded ECPoint */ + if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) || + ((bn_ctx = BN_CTX_new()) == NULL)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if (param_len + 1 > n) + goto truncated; + encoded_pt_len = *p; + /* length of encoded point */ + p += 1; + param_len += (1 + encoded_pt_len); + if ((param_len > n) || (EC_POINT_oct2point(group, srvr_ecpoint, + p, encoded_pt_len, bn_ctx) == 0)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_BAD_ECPOINT); + goto f_err; + } + + n -= param_len; + p += encoded_pt_len; + + /* + * The ECC/TLS specification does not mention the use + * of DSA to sign ECParameters in the server key + * exchange message. We do support RSA and ECDSA. + */ + if (alg_a & SSL_aRSA) + pkey = X509_get_pubkey( + s->session->sess_cert->peer_pkeys[ + SSL_PKEY_RSA_ENC].x509); + else if (alg_a & SSL_aECDSA) + pkey = X509_get_pubkey( + s->session->sess_cert->peer_pkeys[ + SSL_PKEY_ECC].x509); + /* Else anonymous ECDH, so no certificate or pkey. */ + EC_KEY_set_public_key(ecdh, srvr_ecpoint); + s->session->sess_cert->peer_ecdh_tmp = ecdh; + ecdh = NULL; + BN_CTX_free(bn_ctx); + bn_ctx = NULL; + EC_POINT_free(srvr_ecpoint); + srvr_ecpoint = NULL; + } else if (alg_k) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + + /* p points to the next byte, there are 'n' bytes left */ + + /* if it was signed, check the signature */ + if (pkey != NULL) { + if (SSL_USE_SIGALGS(s)) { + int sigalg = tls12_get_sigid(pkey); + /* Should never happen */ + if (sigalg == -1) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + /* + * Check key type is consistent + * with signature + */ + if (2 > n) + goto truncated; + if (sigalg != (int)p[1]) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_WRONG_SIGNATURE_TYPE); + al = SSL_AD_DECODE_ERROR; + goto f_err; + } + md = tls12_get_hash(p[0]); + if (md == NULL) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_UNKNOWN_DIGEST); + al = SSL_AD_DECODE_ERROR; + goto f_err; + } + p += 2; + n -= 2; + } else + md = EVP_sha1(); + + if (2 > n) + goto truncated; + n2s(p, i); + n -= 2; + j = EVP_PKEY_size(pkey); + + if (i != n || n > j) { + /* wrong packet length */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_WRONG_SIGNATURE_LENGTH); + goto f_err; + } + + if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) { + int num; + + j = 0; + q = md_buf; + for (num = 2; num > 0; num--) { + if (!EVP_DigestInit_ex(&md_ctx, + (num == 2) ? s->ctx->md5 : s->ctx->sha1, + NULL)) { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + EVP_DigestUpdate(&md_ctx, + s->s3->client_random, + SSL3_RANDOM_SIZE); + EVP_DigestUpdate(&md_ctx, + s->s3->server_random, + SSL3_RANDOM_SIZE); + EVP_DigestUpdate(&md_ctx, param, param_len); + EVP_DigestFinal_ex(&md_ctx, q, + (unsigned int *)&i); + q += i; + j += i; + } + i = RSA_verify(NID_md5_sha1, md_buf, j, + p, n, pkey->pkey.rsa); + if (i < 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_BAD_RSA_DECRYPT); + goto f_err; + } + if (i == 0) { + /* bad signature */ + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_BAD_SIGNATURE); + goto f_err; + } + } else { + EVP_VerifyInit_ex(&md_ctx, md, NULL); + EVP_VerifyUpdate(&md_ctx, s->s3->client_random, + SSL3_RANDOM_SIZE); + EVP_VerifyUpdate(&md_ctx, s->s3->server_random, + SSL3_RANDOM_SIZE); + EVP_VerifyUpdate(&md_ctx, param, param_len); + if (EVP_VerifyFinal(&md_ctx, p,(int)n, pkey) <= 0) { + /* bad signature */ + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_BAD_SIGNATURE); + goto f_err; + } + } + } else { + /* aNULL does not need public keys. */ + if (!(alg_a & SSL_aNULL)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + /* still data left over */ + if (n != 0) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_EXTRA_DATA_IN_MESSAGE); + goto f_err; + } + } + EVP_PKEY_free(pkey); + EVP_MD_CTX_cleanup(&md_ctx); + return (1); +truncated: + /* wrong packet length */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_PACKET_LENGTH); +f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); +err: + EVP_PKEY_free(pkey); + RSA_free(rsa); + DH_free(dh); + BN_CTX_free(bn_ctx); + EC_POINT_free(srvr_ecpoint); + EC_KEY_free(ecdh); + EVP_MD_CTX_cleanup(&md_ctx); + return (-1); +} + +int +ssl3_get_certificate_request(SSL *s) +{ + int ok, ret = 0; + long n; + uint8_t ctype_num; + CBS cert_request, ctypes, rdn_list; + X509_NAME *xn = NULL; + const unsigned char *q; + STACK_OF(X509_NAME) *ca_sk = NULL; + + n = s->method->ssl_get_message(s, SSL3_ST_CR_CERT_REQ_A, + SSL3_ST_CR_CERT_REQ_B, -1, s->max_cert_list, &ok); + + if (!ok) + return ((int)n); + + s->s3->tmp.cert_req = 0; + + if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE) { + s->s3->tmp.reuse_message = 1; + /* + * If we get here we don't need any cached handshake records + * as we wont be doing client auth. + */ + if (s->s3->handshake_buffer) { + if (!tls1_digest_cached_records(s)) + goto err; + } + return (1); + } + + if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + SSL_R_WRONG_MESSAGE_TYPE); + goto err; + } + + /* TLS does not like anon-DH with client cert */ + if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER); + goto err; + } + + if (n < 0) + goto truncated; + CBS_init(&cert_request, s->init_msg, n); + + if ((ca_sk = sk_X509_NAME_new(ca_dn_cmp)) == NULL) { + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + ERR_R_MALLOC_FAILURE); + goto err; + } + + /* get the certificate types */ + if (!CBS_get_u8(&cert_request, &ctype_num)) + goto truncated; + + if (ctype_num > SSL3_CT_NUMBER) + ctype_num = SSL3_CT_NUMBER; + if (!CBS_get_bytes(&cert_request, &ctypes, ctype_num) || + !CBS_write_bytes(&ctypes, s->s3->tmp.ctype, + sizeof(s->s3->tmp.ctype), NULL)) { + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + + if (SSL_USE_SIGALGS(s)) { + CBS sigalgs; + + if (CBS_len(&cert_request) < 2) { + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + + /* Check we have enough room for signature algorithms and + * following length value. + */ + if (!CBS_get_u16_length_prefixed(&cert_request, &sigalgs)) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + if ((CBS_len(&sigalgs) & 1) || + !tls1_process_sigalgs(s, CBS_data(&sigalgs), + CBS_len(&sigalgs))) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + SSL_R_SIGNATURE_ALGORITHMS_ERROR); + goto err; + } + } + + /* get the CA RDNs */ + if (CBS_len(&cert_request) < 2) { + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + + if (!CBS_get_u16_length_prefixed(&cert_request, &rdn_list) || + CBS_len(&cert_request) != 0) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + SSL_R_LENGTH_MISMATCH); + goto err; + } + + while (CBS_len(&rdn_list) > 0) { + CBS rdn; + + if (CBS_len(&rdn_list) < 2) { + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + + if (!CBS_get_u16_length_prefixed(&rdn_list, &rdn)) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + SSL_R_CA_DN_TOO_LONG); + goto err; + } + + q = CBS_data(&rdn); + if ((xn = d2i_X509_NAME(NULL, &q, CBS_len(&rdn))) == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + ERR_R_ASN1_LIB); + goto err; + } + + if (q != CBS_data(&rdn) + CBS_len(&rdn)) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + SSL_R_CA_DN_LENGTH_MISMATCH); + goto err; + } + if (!sk_X509_NAME_push(ca_sk, xn)) { + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + ERR_R_MALLOC_FAILURE); + goto err; + } + xn = NULL; /* avoid free in err block */ + } + + /* we should setup a certificate to return.... */ + s->s3->tmp.cert_req = 1; + s->s3->tmp.ctype_num = ctype_num; + if (s->s3->tmp.ca_names != NULL) + sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); + s->s3->tmp.ca_names = ca_sk; + ca_sk = NULL; + + ret = 1; + if (0) { +truncated: + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + SSL_R_BAD_PACKET_LENGTH); + } +err: + X509_NAME_free(xn); + if (ca_sk != NULL) + sk_X509_NAME_pop_free(ca_sk, X509_NAME_free); + return (ret); +} + +static int +ca_dn_cmp(const X509_NAME * const *a, const X509_NAME * const *b) +{ + return (X509_NAME_cmp(*a, *b)); +} + +int +ssl3_get_new_session_ticket(SSL *s) +{ + int ok, al, ret = 0; + uint32_t lifetime_hint; + long n; + CBS cbs, session_ticket; + + n = s->method->ssl_get_message(s, SSL3_ST_CR_SESSION_TICKET_A, + SSL3_ST_CR_SESSION_TICKET_B, -1, 16384, &ok); + if (!ok) + return ((int)n); + + if (s->s3->tmp.message_type == SSL3_MT_FINISHED) { + s->s3->tmp.reuse_message = 1; + return (1); + } + if (s->s3->tmp.message_type != SSL3_MT_NEWSESSION_TICKET) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, + SSL_R_BAD_MESSAGE_TYPE); + goto f_err; + } + + if (n < 0) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, + SSL_R_LENGTH_MISMATCH); + goto f_err; + } + + CBS_init(&cbs, s->init_msg, n); + if (!CBS_get_u32(&cbs, &lifetime_hint) || +#if UINT32_MAX > LONG_MAX + lifetime_hint > LONG_MAX || +#endif + !CBS_get_u16_length_prefixed(&cbs, &session_ticket) || + CBS_len(&cbs) != 0) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, + SSL_R_LENGTH_MISMATCH); + goto f_err; + } + s->session->tlsext_tick_lifetime_hint = (long)lifetime_hint; + + if (!CBS_stow(&session_ticket, &s->session->tlsext_tick, + &s->session->tlsext_ticklen)) { + SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, + ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * There are two ways to detect a resumed ticket sesion. + * One is to set an appropriate session ID and then the server + * must return a match in ServerHello. This allows the normal + * client session ID matching to work and we know much + * earlier that the ticket has been accepted. + * + * The other way is to set zero length session ID when the + * ticket is presented and rely on the handshake to determine + * session resumption. + * + * We choose the former approach because this fits in with + * assumptions elsewhere in OpenSSL. The session ID is set + * to the SHA256 (or SHA1 is SHA256 is disabled) hash of the + * ticket. + */ + EVP_Digest(CBS_data(&session_ticket), CBS_len(&session_ticket), + s->session->session_id, &s->session->session_id_length, + EVP_sha256(), NULL); + ret = 1; + return (ret); +f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); +err: + return (-1); +} + +int +ssl3_get_cert_status(SSL *s) +{ + CBS cert_status, response; + size_t stow_len; + int ok, al; + long n; + uint8_t status_type; + + n = s->method->ssl_get_message(s, SSL3_ST_CR_CERT_STATUS_A, + SSL3_ST_CR_CERT_STATUS_B, SSL3_MT_CERTIFICATE_STATUS, + 16384, &ok); + + if (!ok) + return ((int)n); + + if (n < 0) { + /* need at least status type + length */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_STATUS, + SSL_R_LENGTH_MISMATCH); + goto f_err; + } + + CBS_init(&cert_status, s->init_msg, n); + if (!CBS_get_u8(&cert_status, &status_type) || + CBS_len(&cert_status) < 3) { + /* need at least status type + length */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_STATUS, + SSL_R_LENGTH_MISMATCH); + goto f_err; + } + + if (status_type != TLSEXT_STATUSTYPE_ocsp) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_STATUS, + SSL_R_UNSUPPORTED_STATUS_TYPE); + goto f_err; + } + + if (!CBS_get_u24_length_prefixed(&cert_status, &response) || + CBS_len(&cert_status) != 0) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_STATUS, + SSL_R_LENGTH_MISMATCH); + goto f_err; + } + + if (!CBS_stow(&response, &s->tlsext_ocsp_resp, + &stow_len) || stow_len > INT_MAX) { + s->tlsext_ocsp_resplen = 0; + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_STATUS, + ERR_R_MALLOC_FAILURE); + goto f_err; + } + s->tlsext_ocsp_resplen = (int)stow_len; + + if (s->ctx->tlsext_status_cb) { + int ret; + ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); + if (ret == 0) { + al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE; + SSLerr(SSL_F_SSL3_GET_CERT_STATUS, + SSL_R_INVALID_STATUS_RESPONSE); + goto f_err; + } + if (ret < 0) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_STATUS, + ERR_R_MALLOC_FAILURE); + goto f_err; + } + } + return (1); +f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return (-1); +} + +int +ssl3_get_server_done(SSL *s) +{ + int ok, ret = 0; + long n; + + n = s->method->ssl_get_message(s, SSL3_ST_CR_SRVR_DONE_A, + SSL3_ST_CR_SRVR_DONE_B, SSL3_MT_SERVER_DONE, + 30, /* should be very small, like 0 :-) */ &ok); + + if (!ok) + return ((int)n); + if (n > 0) { + /* should contain no data */ + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_SERVER_DONE, SSL_R_LENGTH_MISMATCH); + return (-1); + } + ret = 1; + return (ret); +} + +static int +ssl3_send_client_kex_rsa(SSL *s, SESS_CERT *sess_cert, unsigned char *p, + int *outlen) +{ + unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; + EVP_PKEY *pkey = NULL; + unsigned char *q; + int ret = -1; + int n; + + pkey = X509_get_pubkey(sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); + if (pkey == NULL || pkey->type != EVP_PKEY_RSA || + pkey->pkey.rsa == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + tmp_buf[0] = s->client_version >> 8; + tmp_buf[1] = s->client_version & 0xff; + arc4random_buf(&tmp_buf[2], sizeof(tmp_buf) - 2); + + s->session->master_key_length = sizeof(tmp_buf); + + q = p; + p += 2; + + n = RSA_public_encrypt(sizeof(tmp_buf), tmp_buf, p, pkey->pkey.rsa, + RSA_PKCS1_PADDING); + if (n <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_BAD_RSA_ENCRYPT); + goto err; + } + + s2n(n, q); + n += 2; + + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s->session->master_key, tmp_buf, sizeof(tmp_buf)); + + *outlen = n; + ret = 1; + +err: + explicit_bzero(tmp_buf, sizeof(tmp_buf)); + EVP_PKEY_free(pkey); + + return (ret); +} + +static int +ssl3_send_client_kex_dhe(SSL *s, SESS_CERT *sess_cert, unsigned char *p, + int *outlen) +{ + DH *dh_srvr = NULL, *dh_clnt = NULL; + unsigned char *key = NULL; + int key_size, n; + int ret = -1; + + /* Ensure that we have an ephemeral key for DHE. */ + if (sess_cert->peer_dh_tmp == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_UNABLE_TO_FIND_DH_PARAMETERS); + goto err; + } + dh_srvr = sess_cert->peer_dh_tmp; + + /* Generate a new random key. */ + if ((dh_clnt = DHparams_dup(dh_srvr)) == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); + goto err; + } + if (!DH_generate_key(dh_clnt)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); + goto err; + } + key_size = DH_size(dh_clnt); + if ((key = malloc(key_size)) == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + n = DH_compute_key(key, dh_srvr->pub_key, dh_clnt); + if (n <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); + goto err; + } + + /* Generate master key from the result. */ + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s->session->master_key, key, n); + + /* Send off the data. */ + n = BN_num_bytes(dh_clnt->pub_key); + s2n(n, p); + BN_bn2bin(dh_clnt->pub_key, p); + n += 2; + + *outlen = n; + ret = 1; + +err: + DH_free(dh_clnt); + if (key != NULL) + explicit_bzero(key, key_size); + free(key); + + return (ret); +} + +static int +ssl3_send_client_kex_ecdh(SSL *s, SESS_CERT *sess_cert, unsigned char *p, + int *outlen) +{ + EC_KEY *tkey, *clnt_ecdh = NULL; + const EC_GROUP *srvr_group = NULL; + const EC_POINT *srvr_ecpoint = NULL; + EVP_PKEY *srvr_pub_pkey = NULL; + BN_CTX *bn_ctx = NULL; + unsigned char *encodedPoint = NULL; + unsigned char *key = NULL; + unsigned long alg_k; + int encoded_pt_len = 0; + int key_size, n; + int ret = -1; + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + + /* Ensure that we have an ephemeral key for ECDHE. */ + if ((alg_k & SSL_kECDHE) && sess_cert->peer_ecdh_tmp == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + tkey = sess_cert->peer_ecdh_tmp; + + if (alg_k & (SSL_kECDHr|SSL_kECDHe)) { + /* Get the Server Public Key from certificate. */ + srvr_pub_pkey = X509_get_pubkey( + sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); + if (srvr_pub_pkey != NULL && srvr_pub_pkey->type == EVP_PKEY_EC) + tkey = srvr_pub_pkey->pkey.ec; + } + + if (tkey == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + srvr_group = EC_KEY_get0_group(tkey); + srvr_ecpoint = EC_KEY_get0_public_key(tkey); + + if (srvr_group == NULL || srvr_ecpoint == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if ((clnt_ecdh = EC_KEY_new()) == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); + goto err; + } + + /* Generate a new ECDH key pair. */ + if (!(EC_KEY_generate_key(clnt_ecdh))) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + key_size = ECDH_size(clnt_ecdh); + if (key_size <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + if ((key = malloc(key_size)) == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + } + n = ECDH_compute_key(key, key_size, srvr_ecpoint, clnt_ecdh, NULL); + if (n <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + + /* Generate master key from the result. */ + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s->session->master_key, key, n); + + /* + * First check the size of encoding and allocate memory accordingly. + */ + encoded_pt_len = EC_POINT_point2oct(srvr_group, + EC_KEY_get0_public_key(clnt_ecdh), + POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); + + bn_ctx = BN_CTX_new(); + encodedPoint = malloc(encoded_pt_len); + if (encodedPoint == NULL || bn_ctx == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Encode the public key */ + n = EC_POINT_point2oct(srvr_group, EC_KEY_get0_public_key(clnt_ecdh), + POINT_CONVERSION_UNCOMPRESSED, encodedPoint, encoded_pt_len, + bn_ctx); + + *p = n; /* length of encoded point */ + /* Encoded point will be copied here */ + p += 1; + + /* copy the point */ + memcpy((unsigned char *)p, encodedPoint, n); + /* increment n to account for length field */ + n += 1; + + *outlen = n; + ret = 1; + +err: + if (key != NULL) + explicit_bzero(key, key_size); + free(key); + + BN_CTX_free(bn_ctx); + free(encodedPoint); + EC_KEY_free(clnt_ecdh); + EVP_PKEY_free(srvr_pub_pkey); + + return (ret); +} + +static int +ssl3_send_client_kex_gost(SSL *s, SESS_CERT *sess_cert, unsigned char *p, + int *outlen) +{ + unsigned char premaster_secret[32], shared_ukm[32], tmp[256]; + EVP_PKEY *pub_key = NULL; + EVP_PKEY_CTX *pkey_ctx; + X509 *peer_cert; + size_t msglen; + unsigned int md_len; + EVP_MD_CTX *ukm_hash; + int ret = -1; + int nid; + int n; + + /* Get server sertificate PKEY and create ctx from it */ + peer_cert = sess_cert->peer_pkeys[SSL_PKEY_GOST01].x509; + if (peer_cert == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); + goto err; + } + + pub_key = X509_get_pubkey(peer_cert); + pkey_ctx = EVP_PKEY_CTX_new(pub_key, NULL); + + /* + * If we have send a certificate, and certificate key parameters match + * those of server certificate, use certificate key for key exchange. + * Otherwise, generate ephemeral key pair. + */ + EVP_PKEY_encrypt_init(pkey_ctx); + + /* Generate session key. */ + arc4random_buf(premaster_secret, 32); + + /* + * If we have client certificate, use its secret as peer key. + */ + if (s->s3->tmp.cert_req && s->cert->key->privatekey) { + if (EVP_PKEY_derive_set_peer(pkey_ctx, + s->cert->key->privatekey) <=0) { + /* + * If there was an error - just ignore it. + * Ephemeral key would be used. + */ + ERR_clear_error(); + } + } + + /* + * Compute shared IV and store it in algorithm-specific context data. + */ + ukm_hash = EVP_MD_CTX_create(); + if (ukm_hash == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if (ssl_get_algorithm2(s) & SSL_HANDSHAKE_MAC_GOST94) + nid = NID_id_GostR3411_94; + else + nid = NID_id_tc26_gost3411_2012_256; + if (!EVP_DigestInit(ukm_hash, EVP_get_digestbynid(nid))) + goto err; + EVP_DigestUpdate(ukm_hash, s->s3->client_random, SSL3_RANDOM_SIZE); + EVP_DigestUpdate(ukm_hash, s->s3->server_random, SSL3_RANDOM_SIZE); + EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len); + EVP_MD_CTX_destroy(ukm_hash); + if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, + EVP_PKEY_CTRL_SET_IV, 8, shared_ukm) < 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, SSL_R_LIBRARY_BUG); + goto err; + } + + /* + * Make GOST keytransport blob message, encapsulate it into sequence. + */ + *(p++) = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED; + msglen = 255; + if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, premaster_secret, + 32) < 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, SSL_R_LIBRARY_BUG); + goto err; + } + if (msglen >= 0x80) { + *(p++) = 0x81; + *(p++) = msglen & 0xff; + n = msglen + 3; + } else { + *(p++) = msglen & 0xff; + n = msglen + 2; + } + memcpy(p, tmp, msglen); + + /* Check if pubkey from client certificate was used. */ + if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, + NULL) > 0) { + /* Set flag "skip certificate verify". */ + s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; + } + EVP_PKEY_CTX_free(pkey_ctx); + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s->session->master_key, premaster_secret, 32); + + *outlen = n; + ret = 1; + +err: + explicit_bzero(premaster_secret, sizeof(premaster_secret)); + EVP_PKEY_free(pub_key); + + return (ret); +} + +int +ssl3_send_client_key_exchange(SSL *s) +{ + SESS_CERT *sess_cert; + unsigned long alg_k; + unsigned char *p; + int n = 0; + + if (s->state == SSL3_ST_CW_KEY_EXCH_A) { + p = ssl3_handshake_msg_start(s, SSL3_MT_CLIENT_KEY_EXCHANGE); + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + + if ((sess_cert = s->session->sess_cert) == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if (alg_k & SSL_kRSA) { + if (ssl3_send_client_kex_rsa(s, sess_cert, p, &n) != 1) + goto err; + } else if (alg_k & SSL_kDHE) { + if (ssl3_send_client_kex_dhe(s, sess_cert, p, &n) != 1) + goto err; + } else if (alg_k & (SSL_kECDHE|SSL_kECDHr|SSL_kECDHe)) { + if (ssl3_send_client_kex_ecdh(s, sess_cert, p, &n) != 1) + goto err; + } else if (alg_k & SSL_kGOST) { + if (ssl3_send_client_kex_gost(s, sess_cert, p, &n) != 1) + goto err; + } else { + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + ssl3_handshake_msg_finish(s, n); + + s->state = SSL3_ST_CW_KEY_EXCH_B; + } + + /* SSL3_ST_CW_KEY_EXCH_B */ + return (ssl3_handshake_write(s)); + +err: + return (-1); +} + +int +ssl3_send_client_verify(SSL *s) +{ + unsigned char *p; + unsigned char data[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH]; + EVP_PKEY *pkey; + EVP_PKEY_CTX *pctx = NULL; + EVP_MD_CTX mctx; + unsigned u = 0; + unsigned long n; + int j; + + EVP_MD_CTX_init(&mctx); + + if (s->state == SSL3_ST_CW_CERT_VRFY_A) { + p = ssl3_handshake_msg_start(s, SSL3_MT_CERTIFICATE_VERIFY); + + /* + * Create context from key and test if sha1 is allowed as + * digest. + */ + pkey = s->cert->key->privatekey; + pctx = EVP_PKEY_CTX_new(pkey, NULL); + EVP_PKEY_sign_init(pctx); + if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1()) > 0) { + if (!SSL_USE_SIGALGS(s)) + s->method->ssl3_enc->cert_verify_mac(s, + NID_sha1, &(data[MD5_DIGEST_LENGTH])); + } else { + ERR_clear_error(); + } + /* + * For TLS v1.2 send signature algorithm and signature + * using agreed digest and cached handshake records. + */ + if (SSL_USE_SIGALGS(s)) { + long hdatalen = 0; + void *hdata; + const EVP_MD *md = s->cert->key->digest; + hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, + &hdata); + if (hdatalen <= 0 || + !tls12_get_sigandhash(p, pkey, md)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, + ERR_R_INTERNAL_ERROR); + goto err; + } + p += 2; + if (!EVP_SignInit_ex(&mctx, md, NULL) || + !EVP_SignUpdate(&mctx, hdata, hdatalen) || + !EVP_SignFinal(&mctx, p + 2, &u, pkey)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, + ERR_R_EVP_LIB); + goto err; + } + s2n(u, p); + n = u + 4; + if (!tls1_digest_cached_records(s)) + goto err; + } else if (pkey->type == EVP_PKEY_RSA) { + s->method->ssl3_enc->cert_verify_mac( + s, NID_md5, &(data[0])); + if (RSA_sign(NID_md5_sha1, data, + MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, &(p[2]), + &u, pkey->pkey.rsa) <= 0 ) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, + ERR_R_RSA_LIB); + goto err; + } + s2n(u, p); + n = u + 2; + } else if (pkey->type == EVP_PKEY_DSA) { + if (!DSA_sign(pkey->save_type, + &(data[MD5_DIGEST_LENGTH]), + SHA_DIGEST_LENGTH, &(p[2]), + (unsigned int *)&j, pkey->pkey.dsa)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, + ERR_R_DSA_LIB); + goto err; + } + s2n(j, p); + n = j + 2; + } else if (pkey->type == EVP_PKEY_EC) { + if (!ECDSA_sign(pkey->save_type, + &(data[MD5_DIGEST_LENGTH]), + SHA_DIGEST_LENGTH, &(p[2]), + (unsigned int *)&j, pkey->pkey.ec)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, + ERR_R_ECDSA_LIB); + goto err; + } + s2n(j, p); + n = j + 2; +#ifndef OPENSSL_NO_GOST + } else if (pkey->type == NID_id_GostR3410_94 || + pkey->type == NID_id_GostR3410_2001) { + unsigned char signbuf[128]; + long hdatalen = 0; + void *hdata; + const EVP_MD *md; + int nid; + size_t sigsize; + + hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); + if (hdatalen <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, + ERR_R_INTERNAL_ERROR); + goto err; + } + if (!EVP_PKEY_get_default_digest_nid(pkey, &nid) || + !(md = EVP_get_digestbynid(nid))) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, + ERR_R_EVP_LIB); + goto err; + } + if (!EVP_DigestInit_ex(&mctx, md, NULL) || + !EVP_DigestUpdate(&mctx, hdata, hdatalen) || + !EVP_DigestFinal(&mctx, signbuf, &u) || + (EVP_PKEY_CTX_set_signature_md(pctx, md) <= 0) || + (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, + EVP_PKEY_CTRL_GOST_SIG_FORMAT, + GOST_SIG_FORMAT_RS_LE, + NULL) <= 0) || + (EVP_PKEY_sign(pctx, &(p[2]), &sigsize, + signbuf, u) <= 0)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, + ERR_R_EVP_LIB); + goto err; + } + if (!tls1_digest_cached_records(s)) + goto err; + j = sigsize; + s2n(j, p); + n = j + 2; +#endif + } else { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, + ERR_R_INTERNAL_ERROR); + goto err; + } + + s->state = SSL3_ST_CW_CERT_VRFY_B; + + ssl3_handshake_msg_finish(s, n); + } + + EVP_MD_CTX_cleanup(&mctx); + EVP_PKEY_CTX_free(pctx); + + return (ssl3_handshake_write(s)); + +err: + EVP_MD_CTX_cleanup(&mctx); + EVP_PKEY_CTX_free(pctx); + return (-1); +} + +int +ssl3_send_client_certificate(SSL *s) +{ + X509 *x509 = NULL; + EVP_PKEY *pkey = NULL; + int i; + unsigned long l; + + if (s->state == SSL3_ST_CW_CERT_A) { + if ((s->cert == NULL) || (s->cert->key->x509 == NULL) || + (s->cert->key->privatekey == NULL)) + s->state = SSL3_ST_CW_CERT_B; + else + s->state = SSL3_ST_CW_CERT_C; + } + + /* We need to get a client cert */ + if (s->state == SSL3_ST_CW_CERT_B) { + /* + * If we get an error, we need to + * ssl->rwstate=SSL_X509_LOOKUP; return(-1); + * We then get retied later + */ + i = ssl_do_client_cert_cb(s, &x509, &pkey); + if (i < 0) { + s->rwstate = SSL_X509_LOOKUP; + return (-1); + } + s->rwstate = SSL_NOTHING; + if ((i == 1) && (pkey != NULL) && (x509 != NULL)) { + s->state = SSL3_ST_CW_CERT_B; + if (!SSL_use_certificate(s, x509) || + !SSL_use_PrivateKey(s, pkey)) + i = 0; + } else if (i == 1) { + i = 0; + SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE, + SSL_R_BAD_DATA_RETURNED_BY_CALLBACK); + } + + X509_free(x509); + EVP_PKEY_free(pkey); + if (i == 0) + s->s3->tmp.cert_req = 2; + + /* Ok, we have a cert */ + s->state = SSL3_ST_CW_CERT_C; + } + + if (s->state == SSL3_ST_CW_CERT_C) { + s->state = SSL3_ST_CW_CERT_D; + l = ssl3_output_cert_chain(s, + (s->s3->tmp.cert_req == 2) ? NULL : s->cert->key->x509); + s->init_num = (int)l; + s->init_off = 0; + } + /* SSL3_ST_CW_CERT_D */ + return (ssl3_do_write(s, SSL3_RT_HANDSHAKE)); +} + +#define has_bits(i,m) (((i)&(m)) == (m)) + +int +ssl3_check_cert_and_algorithm(SSL *s) +{ + int i, idx; + long alg_k, alg_a; + EVP_PKEY *pkey = NULL; + SESS_CERT *sc; + DH *dh; + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + alg_a = s->s3->tmp.new_cipher->algorithm_auth; + + /* We don't have a certificate. */ + if (alg_a & SSL_aNULL) + return (1); + + sc = s->session->sess_cert; + if (sc == NULL) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + ERR_R_INTERNAL_ERROR); + goto err; + } + dh = s->session->sess_cert->peer_dh_tmp; + + /* This is the passed certificate. */ + + idx = sc->peer_cert_type; + if (idx == SSL_PKEY_ECC) { + if (ssl_check_srvr_ecc_cert_and_alg( + sc->peer_pkeys[idx].x509, s) == 0) { + /* check failed */ + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_BAD_ECC_CERT); + goto f_err; + } else { + return (1); + } + } + pkey = X509_get_pubkey(sc->peer_pkeys[idx].x509); + i = X509_certificate_type(sc->peer_pkeys[idx].x509, pkey); + EVP_PKEY_free(pkey); + + /* Check that we have a certificate if we require one. */ + if ((alg_a & SSL_aRSA) && !has_bits(i, EVP_PK_RSA|EVP_PKT_SIGN)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_RSA_SIGNING_CERT); + goto f_err; + } else if ((alg_a & SSL_aDSS) && + !has_bits(i, EVP_PK_DSA|EVP_PKT_SIGN)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_DSA_SIGNING_CERT); + goto f_err; + } + if ((alg_k & SSL_kRSA) && + !has_bits(i, EVP_PK_RSA|EVP_PKT_ENC)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_RSA_ENCRYPTING_CERT); + goto f_err; + } + if ((alg_k & SSL_kDHE) && + !(has_bits(i, EVP_PK_DH|EVP_PKT_EXCH) || (dh != NULL))) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_DH_KEY); + goto f_err; + } + + return (1); +f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); +err: + return (0); +} + +int +ssl3_send_next_proto(SSL *s) +{ + unsigned int len, padding_len; + unsigned char *d, *p; + + if (s->state == SSL3_ST_CW_NEXT_PROTO_A) { + d = p = ssl3_handshake_msg_start(s, SSL3_MT_NEXT_PROTO); + + len = s->next_proto_negotiated_len; + padding_len = 32 - ((len + 2) % 32); + *(p++) = len; + memcpy(p, s->next_proto_negotiated, len); + p += len; + *(p++) = padding_len; + memset(p, 0, padding_len); + p += padding_len; + + ssl3_handshake_msg_finish(s, p - d); + + s->state = SSL3_ST_CW_NEXT_PROTO_B; + } + + return (ssl3_handshake_write(s)); +} + +/* + * Check to see if handshake is full or resumed. Usually this is just a + * case of checking to see if a cache hit has occurred. In the case of + * session tickets we have to check the next message to be sure. + */ + +int +ssl3_check_finished(SSL *s) +{ + int ok; + long n; + + /* If we have no ticket it cannot be a resumed session. */ + if (!s->session->tlsext_tick) + return (1); + /* this function is called when we really expect a Certificate + * message, so permit appropriate message length */ + n = s->method->ssl_get_message(s, SSL3_ST_CR_CERT_A, + SSL3_ST_CR_CERT_B, -1, s->max_cert_list, &ok); + if (!ok) + return ((int)n); + s->s3->tmp.reuse_message = 1; + if ((s->s3->tmp.message_type == SSL3_MT_FINISHED) || + (s->s3->tmp.message_type == SSL3_MT_NEWSESSION_TICKET)) + return (2); + + return (1); +} + +int +ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey) +{ + int i = 0; + +#ifndef OPENSSL_NO_ENGINE + if (s->ctx->client_cert_engine) { + i = ENGINE_load_ssl_client_cert(s->ctx->client_cert_engine, s, + SSL_get_client_CA_list(s), + px509, ppkey, NULL, NULL, NULL); + if (i != 0) + return (i); + } +#endif + if (s->ctx->client_cert_cb) + i = s->ctx->client_cert_cb(s, px509, ppkey); + return (i); +} diff --git a/crypto/libressl/ssl/s3_lib.c b/crypto/libressl/ssl/s3_lib.c new file mode 100644 index 0000000000..69b05c6a40 --- /dev/null +++ b/crypto/libressl/ssl/s3_lib.c @@ -0,0 +1,2859 @@ +/* $OpenBSD: s3_lib.c,v 1.107 2016/01/27 02:06:16 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include + +#include +#include +#include + +#include "ssl_locl.h" +#include "bytestring.h" + +#define SSL3_NUM_CIPHERS (sizeof(ssl3_ciphers) / sizeof(SSL_CIPHER)) + +/* + * FIXED_NONCE_LEN is a macro that provides in the correct value to set the + * fixed nonce length in algorithms2. It is the inverse of the + * SSL_CIPHER_AEAD_FIXED_NONCE_LEN macro. + */ +#define FIXED_NONCE_LEN(x) (((x / 2) & 0xf) << 24) + +/* list of available SSLv3 ciphers (sorted by id) */ +SSL_CIPHER ssl3_ciphers[] = { + + /* The RSA ciphers */ + /* Cipher 01 */ + { + .valid = 1, + .name = SSL3_TXT_RSA_NULL_MD5, + .id = SSL3_CK_RSA_NULL_MD5, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_eNULL, + .algorithm_mac = SSL_MD5, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_STRONG_NONE, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 0, + .alg_bits = 0, + }, + + /* Cipher 02 */ + { + .valid = 1, + .name = SSL3_TXT_RSA_NULL_SHA, + .id = SSL3_CK_RSA_NULL_SHA, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_eNULL, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_STRONG_NONE, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 0, + .alg_bits = 0, + }, + + /* Cipher 04 */ + { + .valid = 1, + .name = SSL3_TXT_RSA_RC4_128_MD5, + .id = SSL3_CK_RSA_RC4_128_MD5, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_RC4, + .algorithm_mac = SSL_MD5, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_MEDIUM, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 05 */ + { + .valid = 1, + .name = SSL3_TXT_RSA_RC4_128_SHA, + .id = SSL3_CK_RSA_RC4_128_SHA, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_RC4, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_MEDIUM, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 07 */ +#ifndef OPENSSL_NO_IDEA + { + .valid = 1, + .name = SSL3_TXT_RSA_IDEA_128_SHA, + .id = SSL3_CK_RSA_IDEA_128_SHA, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_IDEA, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_MEDIUM, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, +#endif + + /* Cipher 09 */ + { + .valid = 1, + .name = SSL3_TXT_RSA_DES_64_CBC_SHA, + .id = SSL3_CK_RSA_DES_64_CBC_SHA, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_DES, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_LOW, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 56, + .alg_bits = 56, + }, + + /* Cipher 0A */ + { + .valid = 1, + .name = SSL3_TXT_RSA_DES_192_CBC3_SHA, + .id = SSL3_CK_RSA_DES_192_CBC3_SHA, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_3DES, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 112, + .alg_bits = 168, + }, + + /* + * Ephemeral DH (DHE) ciphers. + */ + + /* Cipher 12 */ + { + .valid = 1, + .name = SSL3_TXT_EDH_DSS_DES_64_CBC_SHA, + .id = SSL3_CK_EDH_DSS_DES_64_CBC_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aDSS, + .algorithm_enc = SSL_DES, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_LOW, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 56, + .alg_bits = 56, + }, + + /* Cipher 13 */ + { + .valid = 1, + .name = SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA, + .id = SSL3_CK_EDH_DSS_DES_192_CBC3_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aDSS, + .algorithm_enc = SSL_3DES, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 112, + .alg_bits = 168, + }, + + /* Cipher 15 */ + { + .valid = 1, + .name = SSL3_TXT_EDH_RSA_DES_64_CBC_SHA, + .id = SSL3_CK_EDH_RSA_DES_64_CBC_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_DES, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_LOW, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 56, + .alg_bits = 56, + }, + + /* Cipher 16 */ + { + .valid = 1, + .name = SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA, + .id = SSL3_CK_EDH_RSA_DES_192_CBC3_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_3DES, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 112, + .alg_bits = 168, + }, + + /* Cipher 18 */ + { + .valid = 1, + .name = SSL3_TXT_ADH_RC4_128_MD5, + .id = SSL3_CK_ADH_RC4_128_MD5, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_RC4, + .algorithm_mac = SSL_MD5, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_MEDIUM, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 1A */ + { + .valid = 1, + .name = SSL3_TXT_ADH_DES_64_CBC_SHA, + .id = SSL3_CK_ADH_DES_64_CBC_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_DES, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_LOW, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 56, + .alg_bits = 56, + }, + + /* Cipher 1B */ + { + .valid = 1, + .name = SSL3_TXT_ADH_DES_192_CBC_SHA, + .id = SSL3_CK_ADH_DES_192_CBC_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_3DES, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_SSLV3, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 112, + .alg_bits = 168, + }, + + /* + * AES ciphersuites. + */ + + /* Cipher 2F */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_AES_128_SHA, + .id = TLS1_CK_RSA_WITH_AES_128_SHA, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 32 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_DSS_WITH_AES_128_SHA, + .id = TLS1_CK_DHE_DSS_WITH_AES_128_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aDSS, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 33 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_AES_128_SHA, + .id = TLS1_CK_DHE_RSA_WITH_AES_128_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 34 */ + { + .valid = 1, + .name = TLS1_TXT_ADH_WITH_AES_128_SHA, + .id = TLS1_CK_ADH_WITH_AES_128_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 35 */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_AES_256_SHA, + .id = TLS1_CK_RSA_WITH_AES_256_SHA, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher 38 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_DSS_WITH_AES_256_SHA, + .id = TLS1_CK_DHE_DSS_WITH_AES_256_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aDSS, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher 39 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_AES_256_SHA, + .id = TLS1_CK_DHE_RSA_WITH_AES_256_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher 3A */ + { + .valid = 1, + .name = TLS1_TXT_ADH_WITH_AES_256_SHA, + .id = TLS1_CK_ADH_WITH_AES_256_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* TLS v1.2 ciphersuites */ + /* Cipher 3B */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_NULL_SHA256, + .id = TLS1_CK_RSA_WITH_NULL_SHA256, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_eNULL, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_STRONG_NONE, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 0, + .alg_bits = 0, + }, + + /* Cipher 3C */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_AES_128_SHA256, + .id = TLS1_CK_RSA_WITH_AES_128_SHA256, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 3D */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_AES_256_SHA256, + .id = TLS1_CK_RSA_WITH_AES_256_SHA256, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher 40 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256, + .id = TLS1_CK_DHE_DSS_WITH_AES_128_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aDSS, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + +#ifndef OPENSSL_NO_CAMELLIA + /* Camellia ciphersuites from RFC4132 (128-bit portion) */ + + /* Cipher 41 */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA, + .id = TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CAMELLIA128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 44 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, + .id = TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aDSS, + .algorithm_enc = SSL_CAMELLIA128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 45 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, + .id = TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CAMELLIA128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 46 */ + { + .valid = 1, + .name = TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA, + .id = TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_CAMELLIA128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, +#endif /* OPENSSL_NO_CAMELLIA */ + + /* TLS v1.2 ciphersuites */ + /* Cipher 67 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256, + .id = TLS1_CK_DHE_RSA_WITH_AES_128_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 6A */ + { + .valid = 1, + .name = TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256, + .id = TLS1_CK_DHE_DSS_WITH_AES_256_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aDSS, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher 6B */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256, + .id = TLS1_CK_DHE_RSA_WITH_AES_256_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher 6C */ + { + .valid = 1, + .name = TLS1_TXT_ADH_WITH_AES_128_SHA256, + .id = TLS1_CK_ADH_WITH_AES_128_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 6D */ + { + .valid = 1, + .name = TLS1_TXT_ADH_WITH_AES_256_SHA256, + .id = TLS1_CK_ADH_WITH_AES_256_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* GOST Ciphersuites */ + + /* Cipher 81 */ + { + .valid = 1, + .name = "GOST2001-GOST89-GOST89", + .id = 0x3000081, + .algorithm_mkey = SSL_kGOST, + .algorithm_auth = SSL_aGOST01, + .algorithm_enc = SSL_eGOST2814789CNT, + .algorithm_mac = SSL_GOST89MAC, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_GOST94|TLS1_PRF_GOST94| + TLS1_STREAM_MAC, + .strength_bits = 256, + .alg_bits = 256 + }, + + /* Cipher 83 */ + { + .valid = 1, + .name = "GOST2001-NULL-GOST94", + .id = 0x3000083, + .algorithm_mkey = SSL_kGOST, + .algorithm_auth = SSL_aGOST01, + .algorithm_enc = SSL_eNULL, + .algorithm_mac = SSL_GOST94, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_STRONG_NONE, + .algorithm2 = SSL_HANDSHAKE_MAC_GOST94|TLS1_PRF_GOST94, + .strength_bits = 0, + .alg_bits = 0 + }, + +#ifndef OPENSSL_NO_CAMELLIA + /* Camellia ciphersuites from RFC4132 (256-bit portion) */ + + /* Cipher 84 */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA, + .id = TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CAMELLIA256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher 87 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, + .id = TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aDSS, + .algorithm_enc = SSL_CAMELLIA256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher 88 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, + .id = TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CAMELLIA256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher 89 */ + { + .valid = 1, + .name = TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA, + .id = TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_CAMELLIA256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, +#endif /* OPENSSL_NO_CAMELLIA */ + + /* + * GCM ciphersuites from RFC5288. + */ + + /* Cipher 9C */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256, + .id = TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES128GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 9D */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384, + .id = TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES256GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher 9E */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256, + .id = TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES128GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher 9F */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384, + .id = TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES256GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher A2 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256, + .id = TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aDSS, + .algorithm_enc = SSL_AES128GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher A3 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384, + .id = TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aDSS, + .algorithm_enc = SSL_AES256GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher A6 */ + { + .valid = 1, + .name = TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256, + .id = TLS1_CK_ADH_WITH_AES_128_GCM_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_AES128GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher A7 */ + { + .valid = 1, + .name = TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384, + .id = TLS1_CK_ADH_WITH_AES_256_GCM_SHA384, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_AES256GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 256, + .alg_bits = 256, + }, + +#ifndef OPENSSL_NO_CAMELLIA + /* TLS 1.2 Camellia SHA-256 ciphersuites from RFC5932 */ + + /* Cipher BA */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA256, + .id = TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA256, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CAMELLIA128, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher BD */ + { + .valid = 1, + .name = TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256, + .id = TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aDSS, + .algorithm_enc = SSL_CAMELLIA128, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher BE */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, + .id = TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CAMELLIA128, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher BF */ + { + .valid = 1, + .name = TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA256, + .id = TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_CAMELLIA128, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C0 */ + { + .valid = 1, + .name = TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA256, + .id = TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA256, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CAMELLIA256, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher C3 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256, + .id = TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aDSS, + .algorithm_enc = SSL_CAMELLIA256, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher C4 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, + .id = TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CAMELLIA256, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher C5 */ + { + .valid = 1, + .name = TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA256, + .id = TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA256, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_CAMELLIA256, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 256, + .alg_bits = 256, + }, +#endif /* OPENSSL_NO_CAMELLIA */ + + /* Cipher C001 */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA, + .id = TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA, + .algorithm_mkey = SSL_kECDHe, + .algorithm_auth = SSL_aECDH, + .algorithm_enc = SSL_eNULL, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_STRONG_NONE, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 0, + .alg_bits = 0, + }, + + /* Cipher C002 */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA, + .id = TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA, + .algorithm_mkey = SSL_kECDHe, + .algorithm_auth = SSL_aECDH, + .algorithm_enc = SSL_RC4, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_MEDIUM, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C003 */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA, + .id = TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA, + .algorithm_mkey = SSL_kECDHe, + .algorithm_auth = SSL_aECDH, + .algorithm_enc = SSL_3DES, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 112, + .alg_bits = 168, + }, + + /* Cipher C004 */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + .id = TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + .algorithm_mkey = SSL_kECDHe, + .algorithm_auth = SSL_aECDH, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C005 */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + .id = TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + .algorithm_mkey = SSL_kECDHe, + .algorithm_auth = SSL_aECDH, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher C006 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA, + .id = TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_eNULL, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_STRONG_NONE, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 0, + .alg_bits = 0, + }, + + /* Cipher C007 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA, + .id = TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_RC4, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_MEDIUM, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C008 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA, + .id = TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_3DES, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 112, + .alg_bits = 168, + }, + + /* Cipher C009 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + .id = TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C00A */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + .id = TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher C00B */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_RSA_WITH_NULL_SHA, + .id = TLS1_CK_ECDH_RSA_WITH_NULL_SHA, + .algorithm_mkey = SSL_kECDHr, + .algorithm_auth = SSL_aECDH, + .algorithm_enc = SSL_eNULL, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_STRONG_NONE, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 0, + .alg_bits = 0, + }, + + /* Cipher C00C */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA, + .id = TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA, + .algorithm_mkey = SSL_kECDHr, + .algorithm_auth = SSL_aECDH, + .algorithm_enc = SSL_RC4, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_MEDIUM, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C00D */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA, + .id = TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA, + .algorithm_mkey = SSL_kECDHr, + .algorithm_auth = SSL_aECDH, + .algorithm_enc = SSL_3DES, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 112, + .alg_bits = 168, + }, + + /* Cipher C00E */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA, + .id = TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA, + .algorithm_mkey = SSL_kECDHr, + .algorithm_auth = SSL_aECDH, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C00F */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA, + .id = TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA, + .algorithm_mkey = SSL_kECDHr, + .algorithm_auth = SSL_aECDH, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher C010 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA, + .id = TLS1_CK_ECDHE_RSA_WITH_NULL_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_eNULL, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_STRONG_NONE, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 0, + .alg_bits = 0, + }, + + /* Cipher C011 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA, + .id = TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_RC4, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_MEDIUM, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C012 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA, + .id = TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_3DES, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 112, + .alg_bits = 168, + }, + + /* Cipher C013 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA, + .id = TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C014 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA, + .id = TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher C015 */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_anon_WITH_NULL_SHA, + .id = TLS1_CK_ECDH_anon_WITH_NULL_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_eNULL, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_STRONG_NONE, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 0, + .alg_bits = 0, + }, + + /* Cipher C016 */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA, + .id = TLS1_CK_ECDH_anon_WITH_RC4_128_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_RC4, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_MEDIUM, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C017 */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA, + .id = TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_3DES, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 112, + .alg_bits = 168, + }, + + /* Cipher C018 */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA, + .id = TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C019 */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA, + .id = TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA1, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + .strength_bits = 256, + .alg_bits = 256, + }, + + + /* HMAC based TLS v1.2 ciphersuites from RFC5289 */ + + /* Cipher C023 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256, + .id = TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C024 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384, + .id = TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA384, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher C025 */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256, + .id = TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256, + .algorithm_mkey = SSL_kECDHe, + .algorithm_auth = SSL_aECDH, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C026 */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384, + .id = TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384, + .algorithm_mkey = SSL_kECDHe, + .algorithm_auth = SSL_aECDH, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA384, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher C027 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256, + .id = TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C028 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384, + .id = TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA384, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher C029 */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256, + .id = TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256, + .algorithm_mkey = SSL_kECDHr, + .algorithm_auth = SSL_aECDH, + .algorithm_enc = SSL_AES128, + .algorithm_mac = SSL_SHA256, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C02A */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384, + .id = TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384, + .algorithm_mkey = SSL_kECDHr, + .algorithm_auth = SSL_aECDH, + .algorithm_enc = SSL_AES256, + .algorithm_mac = SSL_SHA384, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* GCM based TLS v1.2 ciphersuites from RFC5289 */ + + /* Cipher C02B */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + .id = TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_AES128GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C02C */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + .id = TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_AES256GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher C02D */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, + .id = TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, + .algorithm_mkey = SSL_kECDHe, + .algorithm_auth = SSL_aECDH, + .algorithm_enc = SSL_AES128GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C02E */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, + .id = TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, + .algorithm_mkey = SSL_kECDHe, + .algorithm_auth = SSL_aECDH, + .algorithm_enc = SSL_AES256GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher C02F */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + .id = TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES128GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C030 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + .id = TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_AES256GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher C031 */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256, + .id = TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256, + .algorithm_mkey = SSL_kECDHr, + .algorithm_auth = SSL_aECDH, + .algorithm_enc = SSL_AES128GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 128, + .alg_bits = 128, + }, + + /* Cipher C032 */ + { + .valid = 1, + .name = TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384, + .id = TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384, + .algorithm_mkey = SSL_kECDHr, + .algorithm_auth = SSL_aECDH, + .algorithm_enc = SSL_AES256GCM, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)| + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD, + .strength_bits = 256, + .alg_bits = 256, + }, + +#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) + /* Cipher CC13 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_OLD, + .id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CHACHA20POLY1305_OLD, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(0), + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher CC14 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_OLD, + .id = TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_CHACHA20POLY1305_OLD, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(0), + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher CC15 */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305_OLD, + .id = TLS1_CK_DHE_RSA_CHACHA20_POLY1305_OLD, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CHACHA20POLY1305_OLD, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(0), + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher CCA8 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305, + .id = TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CHACHA20POLY1305, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(12), + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher CCA9 */ + { + .valid = 1, + .name = TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, + .id = TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aECDSA, + .algorithm_enc = SSL_CHACHA20POLY1305, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(12), + .strength_bits = 256, + .alg_bits = 256, + }, + + /* Cipher CCAA */ + { + .valid = 1, + .name = TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305, + .id = TLS1_CK_DHE_RSA_CHACHA20_POLY1305, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aRSA, + .algorithm_enc = SSL_CHACHA20POLY1305, + .algorithm_mac = SSL_AEAD, + .algorithm_ssl = SSL_TLSV1_2, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256| + SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(12), + .strength_bits = 256, + .alg_bits = 256, + }, +#endif + + /* Cipher FF85 FIXME IANA */ + { + .valid = 1, + .name = "GOST2012256-GOST89-GOST89", + .id = 0x300ff85, /* FIXME IANA */ + .algorithm_mkey = SSL_kGOST, + .algorithm_auth = SSL_aGOST01, + .algorithm_enc = SSL_eGOST2814789CNT, + .algorithm_mac = SSL_GOST89MAC, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_STREEBOG256|TLS1_PRF_STREEBOG256| + TLS1_STREAM_MAC, + .strength_bits = 256, + .alg_bits = 256 + }, + + /* Cipher FF87 FIXME IANA */ + { + .valid = 1, + .name = "GOST2012256-NULL-STREEBOG256", + .id = 0x300ff87, /* FIXME IANA */ + .algorithm_mkey = SSL_kGOST, + .algorithm_auth = SSL_aGOST01, + .algorithm_enc = SSL_eNULL, + .algorithm_mac = SSL_STREEBOG256, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_STRONG_NONE, + .algorithm2 = SSL_HANDSHAKE_MAC_STREEBOG256|TLS1_PRF_STREEBOG256, + .strength_bits = 0, + .alg_bits = 0 + }, + + + /* end of list */ +}; + +int +ssl3_num_ciphers(void) +{ + return (SSL3_NUM_CIPHERS); +} + +const SSL_CIPHER * +ssl3_get_cipher(unsigned int u) +{ + if (u < SSL3_NUM_CIPHERS) + return (&(ssl3_ciphers[SSL3_NUM_CIPHERS - 1 - u])); + else + return (NULL); +} + +const SSL_CIPHER * +ssl3_get_cipher_by_id(unsigned int id) +{ + const SSL_CIPHER *cp; + SSL_CIPHER c; + + c.id = id; + cp = OBJ_bsearch_ssl_cipher_id(&c, ssl3_ciphers, SSL3_NUM_CIPHERS); + if (cp != NULL && cp->valid == 1) + return (cp); + + return (NULL); +} + +const SSL_CIPHER * +ssl3_get_cipher_by_value(uint16_t value) +{ + return ssl3_get_cipher_by_id(SSL3_CK_ID | value); +} + +uint16_t +ssl3_cipher_get_value(const SSL_CIPHER *c) +{ + return (c->id & SSL3_CK_VALUE_MASK); +} + +int +ssl3_pending(const SSL *s) +{ + if (s->rstate == SSL_ST_READ_BODY) + return 0; + + return (s->s3->rrec.type == SSL3_RT_APPLICATION_DATA) ? + s->s3->rrec.length : 0; +} + +int +ssl3_handshake_msg_hdr_len(SSL *s) +{ + return (SSL_IS_DTLS(s) ? DTLS1_HM_HEADER_LENGTH : + SSL3_HM_HEADER_LENGTH); +} + +unsigned char * +ssl3_handshake_msg_start(SSL *s, uint8_t msg_type) +{ + unsigned char *d, *p; + + d = p = (unsigned char *)s->init_buf->data; + + /* Handshake message type and length. */ + *(p++) = msg_type; + l2n3(0, p); + + return (d + ssl3_handshake_msg_hdr_len(s)); +} + +void +ssl3_handshake_msg_finish(SSL *s, unsigned int len) +{ + unsigned char *d, *p; + uint8_t msg_type; + + d = p = (unsigned char *)s->init_buf->data; + + /* Handshake message length. */ + msg_type = *(p++); + l2n3(len, p); + + s->init_num = ssl3_handshake_msg_hdr_len(s) + (int)len; + s->init_off = 0; + + if (SSL_IS_DTLS(s)) { + dtls1_set_message_header(s, d, msg_type, len, 0, len); + dtls1_buffer_message(s, 0); + } +} + +int +ssl3_handshake_write(SSL *s) +{ + if (SSL_IS_DTLS(s)) + return dtls1_do_write(s, SSL3_RT_HANDSHAKE); + + return ssl3_do_write(s, SSL3_RT_HANDSHAKE); +} + +int +ssl3_new(SSL *s) +{ + SSL3_STATE *s3; + + if ((s3 = calloc(1, sizeof *s3)) == NULL) + goto err; + memset(s3->rrec.seq_num, 0, sizeof(s3->rrec.seq_num)); + memset(s3->wrec.seq_num, 0, sizeof(s3->wrec.seq_num)); + + s->s3 = s3; + + s->method->ssl_clear(s); + return (1); +err: + return (0); +} + +void +ssl3_free(SSL *s) +{ + if (s == NULL) + return; + + tls1_cleanup_key_block(s); + ssl3_release_read_buffer(s); + ssl3_release_write_buffer(s); + + DH_free(s->s3->tmp.dh); + EC_KEY_free(s->s3->tmp.ecdh); + + if (s->s3->tmp.ca_names != NULL) + sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); + BIO_free(s->s3->handshake_buffer); + tls1_free_digest_list(s); + free(s->s3->alpn_selected); + + explicit_bzero(s->s3, sizeof *s->s3); + free(s->s3); + s->s3 = NULL; +} + +void +ssl3_clear(SSL *s) +{ + unsigned char *rp, *wp; + size_t rlen, wlen; + + tls1_cleanup_key_block(s); + if (s->s3->tmp.ca_names != NULL) + sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); + + DH_free(s->s3->tmp.dh); + s->s3->tmp.dh = NULL; + EC_KEY_free(s->s3->tmp.ecdh); + s->s3->tmp.ecdh = NULL; + + rp = s->s3->rbuf.buf; + wp = s->s3->wbuf.buf; + rlen = s->s3->rbuf.len; + wlen = s->s3->wbuf.len; + + BIO_free(s->s3->handshake_buffer); + s->s3->handshake_buffer = NULL; + + tls1_free_digest_list(s); + + free(s->s3->alpn_selected); + s->s3->alpn_selected = NULL; + + memset(s->s3, 0, sizeof *s->s3); + s->s3->rbuf.buf = rp; + s->s3->wbuf.buf = wp; + s->s3->rbuf.len = rlen; + s->s3->wbuf.len = wlen; + + ssl_free_wbio_buffer(s); + + s->packet_length = 0; + s->s3->renegotiate = 0; + s->s3->total_renegotiations = 0; + s->s3->num_renegotiations = 0; + s->s3->in_read_app_data = 0; + s->version = TLS1_VERSION; + + free(s->next_proto_negotiated); + s->next_proto_negotiated = NULL; + s->next_proto_negotiated_len = 0; +} + + +long +ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) +{ + int ret = 0; + + if (cmd == SSL_CTRL_SET_TMP_DH || cmd == SSL_CTRL_SET_TMP_DH_CB) { + if (!ssl_cert_inst(&s->cert)) { + SSLerr(SSL_F_SSL3_CTRL, + ERR_R_MALLOC_FAILURE); + return (0); + } + } + + switch (cmd) { + case SSL_CTRL_GET_SESSION_REUSED: + ret = s->hit; + break; + case SSL_CTRL_GET_CLIENT_CERT_REQUEST: + break; + case SSL_CTRL_GET_NUM_RENEGOTIATIONS: + ret = s->s3->num_renegotiations; + break; + case SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS: + ret = s->s3->num_renegotiations; + s->s3->num_renegotiations = 0; + break; + case SSL_CTRL_GET_TOTAL_RENEGOTIATIONS: + ret = s->s3->total_renegotiations; + break; + case SSL_CTRL_GET_FLAGS: + ret = (int)(s->s3->flags); + break; + case SSL_CTRL_NEED_TMP_RSA: + ret = 0; + break; + case SSL_CTRL_SET_TMP_RSA: + case SSL_CTRL_SET_TMP_RSA_CB: + SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + break; + case SSL_CTRL_SET_TMP_DH: + { + DH *dh = (DH *)parg; + if (dh == NULL) { + SSLerr(SSL_F_SSL3_CTRL, + ERR_R_PASSED_NULL_PARAMETER); + return (ret); + } + if ((dh = DHparams_dup(dh)) == NULL) { + SSLerr(SSL_F_SSL3_CTRL, + ERR_R_DH_LIB); + return (ret); + } + DH_free(s->cert->dh_tmp); + s->cert->dh_tmp = dh; + ret = 1; + } + break; + + case SSL_CTRL_SET_TMP_DH_CB: + SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (ret); + + case SSL_CTRL_SET_DH_AUTO: + s->cert->dh_tmp_auto = larg; + return 1; + + case SSL_CTRL_SET_TMP_ECDH: + { + EC_KEY *ecdh = NULL; + + if (parg == NULL) { + SSLerr(SSL_F_SSL3_CTRL, + ERR_R_PASSED_NULL_PARAMETER); + return (ret); + } + if (!EC_KEY_up_ref((EC_KEY *)parg)) { + SSLerr(SSL_F_SSL3_CTRL, + ERR_R_ECDH_LIB); + return (ret); + } + ecdh = (EC_KEY *)parg; + if (!(s->options & SSL_OP_SINGLE_ECDH_USE)) { + if (!EC_KEY_generate_key(ecdh)) { + EC_KEY_free(ecdh); + SSLerr(SSL_F_SSL3_CTRL, + ERR_R_ECDH_LIB); + return (ret); + } + } + EC_KEY_free(s->cert->ecdh_tmp); + s->cert->ecdh_tmp = ecdh; + ret = 1; + } + break; + case SSL_CTRL_SET_TMP_ECDH_CB: + { + SSLerr(SSL_F_SSL3_CTRL, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (ret); + } + break; + case SSL_CTRL_SET_TLSEXT_HOSTNAME: + if (larg == TLSEXT_NAMETYPE_host_name) { + free(s->tlsext_hostname); + s->tlsext_hostname = NULL; + + ret = 1; + if (parg == NULL) + break; + if (strlen((char *)parg) > TLSEXT_MAXLEN_host_name) { + SSLerr(SSL_F_SSL3_CTRL, + SSL_R_SSL3_EXT_INVALID_SERVERNAME); + return 0; + } + if ((s->tlsext_hostname = strdup((char *)parg)) + == NULL) { + SSLerr(SSL_F_SSL3_CTRL, + ERR_R_INTERNAL_ERROR); + return 0; + } + } else { + SSLerr(SSL_F_SSL3_CTRL, + SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE); + return 0; + } + break; + case SSL_CTRL_SET_TLSEXT_DEBUG_ARG: + s->tlsext_debug_arg = parg; + ret = 1; + break; + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE: + s->tlsext_status_type = larg; + ret = 1; + break; + + case SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS: + *(STACK_OF(X509_EXTENSION) **)parg = s->tlsext_ocsp_exts; + ret = 1; + break; + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS: + s->tlsext_ocsp_exts = parg; + ret = 1; + break; + + case SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS: + *(STACK_OF(OCSP_RESPID) **)parg = s->tlsext_ocsp_ids; + ret = 1; + break; + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS: + s->tlsext_ocsp_ids = parg; + ret = 1; + break; + + case SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP: + *(unsigned char **)parg = s->tlsext_ocsp_resp; + return s->tlsext_ocsp_resplen; + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP: + free(s->tlsext_ocsp_resp); + s->tlsext_ocsp_resp = parg; + s->tlsext_ocsp_resplen = larg; + ret = 1; + break; + + case SSL_CTRL_SET_ECDH_AUTO: + s->cert->ecdh_tmp_auto = larg; + ret = 1; + break; + + default: + break; + } + return (ret); +} + +long +ssl3_callback_ctrl(SSL *s, int cmd, void (*fp)(void)) +{ + int ret = 0; + + if (cmd == SSL_CTRL_SET_TMP_DH_CB) { + if (!ssl_cert_inst(&s->cert)) { + SSLerr(SSL_F_SSL3_CALLBACK_CTRL, + ERR_R_MALLOC_FAILURE); + return (0); + } + } + + switch (cmd) { + case SSL_CTRL_SET_TMP_RSA_CB: + SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + break; + case SSL_CTRL_SET_TMP_DH_CB: + s->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp; + break; + case SSL_CTRL_SET_TMP_ECDH_CB: + s->cert->ecdh_tmp_cb = (EC_KEY *(*)(SSL *, int, int))fp; + break; + case SSL_CTRL_SET_TLSEXT_DEBUG_CB: + s->tlsext_debug_cb = (void (*)(SSL *, int , int, + unsigned char *, int, void *))fp; + break; + default: + break; + } + return (ret); +} + +long +ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) +{ + CERT *cert; + + cert = ctx->cert; + + switch (cmd) { + case SSL_CTRL_NEED_TMP_RSA: + return (0); + case SSL_CTRL_SET_TMP_RSA: + case SSL_CTRL_SET_TMP_RSA_CB: + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); + case SSL_CTRL_SET_TMP_DH: + { + DH *new = NULL, *dh; + + dh = (DH *)parg; + if ((new = DHparams_dup(dh)) == NULL) { + SSLerr(SSL_F_SSL3_CTX_CTRL, + ERR_R_DH_LIB); + return 0; + } + DH_free(cert->dh_tmp); + cert->dh_tmp = new; + return 1; + } + /*break; */ + + case SSL_CTRL_SET_TMP_DH_CB: + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); + + case SSL_CTRL_SET_DH_AUTO: + ctx->cert->dh_tmp_auto = larg; + return (1); + + case SSL_CTRL_SET_TMP_ECDH: + { + EC_KEY *ecdh = NULL; + + if (parg == NULL) { + SSLerr(SSL_F_SSL3_CTX_CTRL, + ERR_R_ECDH_LIB); + return 0; + } + ecdh = EC_KEY_dup((EC_KEY *)parg); + if (ecdh == NULL) { + SSLerr(SSL_F_SSL3_CTX_CTRL, + ERR_R_EC_LIB); + return 0; + } + if (!(ctx->options & SSL_OP_SINGLE_ECDH_USE)) { + if (!EC_KEY_generate_key(ecdh)) { + EC_KEY_free(ecdh); + SSLerr(SSL_F_SSL3_CTX_CTRL, + ERR_R_ECDH_LIB); + return 0; + } + } + + EC_KEY_free(cert->ecdh_tmp); + cert->ecdh_tmp = ecdh; + return 1; + } + /* break; */ + case SSL_CTRL_SET_TMP_ECDH_CB: + { + SSLerr(SSL_F_SSL3_CTX_CTRL, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); + } + break; + case SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG: + ctx->tlsext_servername_arg = parg; + break; + case SSL_CTRL_SET_TLSEXT_TICKET_KEYS: + case SSL_CTRL_GET_TLSEXT_TICKET_KEYS: + { + unsigned char *keys = parg; + if (!keys) + return 48; + if (larg != 48) { + SSLerr(SSL_F_SSL3_CTX_CTRL, + SSL_R_INVALID_TICKET_KEYS_LENGTH); + return 0; + } + if (cmd == SSL_CTRL_SET_TLSEXT_TICKET_KEYS) { + memcpy(ctx->tlsext_tick_key_name, keys, 16); + memcpy(ctx->tlsext_tick_hmac_key, + keys + 16, 16); + memcpy(ctx->tlsext_tick_aes_key, keys + 32, 16); + } else { + memcpy(keys, ctx->tlsext_tick_key_name, 16); + memcpy(keys + 16, + ctx->tlsext_tick_hmac_key, 16); + memcpy(keys + 32, + ctx->tlsext_tick_aes_key, 16); + } + return 1; + } + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG: + ctx->tlsext_status_arg = parg; + return 1; + break; + + case SSL_CTRL_SET_ECDH_AUTO: + ctx->cert->ecdh_tmp_auto = larg; + return 1; + + /* A Thawte special :-) */ + case SSL_CTRL_EXTRA_CHAIN_CERT: + if (ctx->extra_certs == NULL) { + if ((ctx->extra_certs = sk_X509_new_null()) == NULL) + return (0); + } + sk_X509_push(ctx->extra_certs,(X509 *)parg); + break; + + case SSL_CTRL_GET_EXTRA_CHAIN_CERTS: + *(STACK_OF(X509) **)parg = ctx->extra_certs; + break; + + case SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS: + if (ctx->extra_certs) { + sk_X509_pop_free(ctx->extra_certs, X509_free); + ctx->extra_certs = NULL; + } + break; + + default: + return (0); + } + return (1); +} + +long +ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void)) +{ + CERT *cert; + + cert = ctx->cert; + + switch (cmd) { + case SSL_CTRL_SET_TMP_RSA_CB: + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); + case SSL_CTRL_SET_TMP_DH_CB: + cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp; + break; + case SSL_CTRL_SET_TMP_ECDH_CB: + cert->ecdh_tmp_cb = (EC_KEY *(*)(SSL *, int, int))fp; + break; + case SSL_CTRL_SET_TLSEXT_SERVERNAME_CB: + ctx->tlsext_servername_callback = + (int (*)(SSL *, int *, void *))fp; + break; + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB: + ctx->tlsext_status_cb = (int (*)(SSL *, void *))fp; + break; + + case SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB: + ctx->tlsext_ticket_key_cb = (int (*)(SSL *, unsigned char *, + unsigned char *, EVP_CIPHER_CTX *, HMAC_CTX *, int))fp; + break; + + default: + return (0); + } + return (1); +} + +/* + * This function needs to check if the ciphers required are actually available. + */ +const SSL_CIPHER * +ssl3_get_cipher_by_char(const unsigned char *p) +{ + CBS cipher; + uint16_t cipher_value; + + /* We have to assume it is at least 2 bytes due to existing API. */ + CBS_init(&cipher, p, 2); + if (!CBS_get_u16(&cipher, &cipher_value)) + return NULL; + + return ssl3_get_cipher_by_value(cipher_value); +} + +int +ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p) +{ + if (p != NULL) { + if ((c->id & ~SSL3_CK_VALUE_MASK) != SSL3_CK_ID) + return (0); + s2n(ssl3_cipher_get_value(c), p); + } + return (2); +} + +SSL_CIPHER * +ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, + STACK_OF(SSL_CIPHER) *srvr) +{ + unsigned long alg_k, alg_a, mask_k, mask_a; + STACK_OF(SSL_CIPHER) *prio, *allow; + SSL_CIPHER *c, *ret = NULL; + int i, ii, ok; + CERT *cert; + + /* Let's see which ciphers we can support */ + cert = s->cert; + + /* + * Do not set the compare functions, because this may lead to a + * reordering by "id". We want to keep the original ordering. + * We may pay a price in performance during sk_SSL_CIPHER_find(), + * but would have to pay with the price of sk_SSL_CIPHER_dup(). + */ + + if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { + prio = srvr; + allow = clnt; + } else { + prio = clnt; + allow = srvr; + } + + for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) { + c = sk_SSL_CIPHER_value(prio, i); + + /* Skip TLS v1.2 only ciphersuites if not supported. */ + if ((c->algorithm_ssl & SSL_TLSV1_2) && + !SSL_USE_TLS1_2_CIPHERS(s)) + continue; + + ssl_set_cert_masks(cert, c); + mask_k = cert->mask_k; + mask_a = cert->mask_a; + + alg_k = c->algorithm_mkey; + alg_a = c->algorithm_auth; + + + ok = (alg_k & mask_k) && (alg_a & mask_a); + + /* + * If we are considering an ECC cipher suite that uses our + * certificate check it. + */ + if (alg_a & (SSL_aECDSA|SSL_aECDH)) + ok = ok && tls1_check_ec_server_key(s); + /* + * If we are considering an ECC cipher suite that uses + * an ephemeral EC key check it. + */ + if (alg_k & SSL_kECDHE) + ok = ok && tls1_check_ec_tmp_key(s); + + if (!ok) + continue; + ii = sk_SSL_CIPHER_find(allow, c); + if (ii >= 0) { + ret = sk_SSL_CIPHER_value(allow, ii); + break; + } + } + return (ret); +} + +int +ssl3_get_req_cert_type(SSL *s, unsigned char *p) +{ + int ret = 0; + unsigned long alg_k; + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + +#ifndef OPENSSL_NO_GOST + if ((alg_k & SSL_kGOST)) { + p[ret++] = TLS_CT_GOST94_SIGN; + p[ret++] = TLS_CT_GOST01_SIGN; + p[ret++] = TLS_CT_GOST12_256_SIGN; + p[ret++] = TLS_CT_GOST12_512_SIGN; + } +#endif + + if (alg_k & SSL_kDHE) { + p[ret++] = SSL3_CT_RSA_FIXED_DH; + p[ret++] = SSL3_CT_DSS_FIXED_DH; + } + p[ret++] = SSL3_CT_RSA_SIGN; + p[ret++] = SSL3_CT_DSS_SIGN; + if ((alg_k & (SSL_kECDHr|SSL_kECDHe))) { + p[ret++] = TLS_CT_RSA_FIXED_ECDH; + p[ret++] = TLS_CT_ECDSA_FIXED_ECDH; + } + + /* + * ECDSA certs can be used with RSA cipher suites as well + * so we don't need to check for SSL_kECDH or SSL_kECDHE + */ + p[ret++] = TLS_CT_ECDSA_SIGN; + + return (ret); +} + +int +ssl3_shutdown(SSL *s) +{ + int ret; + + /* + * Don't do anything much if we have not done the handshake or + * we don't want to send messages :-) + */ + if ((s->quiet_shutdown) || (s->state == SSL_ST_BEFORE)) { + s->shutdown = (SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); + return (1); + } + + if (!(s->shutdown & SSL_SENT_SHUTDOWN)) { + s->shutdown|=SSL_SENT_SHUTDOWN; + ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY); + /* + * Our shutdown alert has been sent now, and if it still needs + * to be written, s->s3->alert_dispatch will be true + */ + if (s->s3->alert_dispatch) + return(-1); /* return WANT_WRITE */ + } else if (s->s3->alert_dispatch) { + /* resend it if not sent */ + ret = s->method->ssl_dispatch_alert(s); + if (ret == -1) { + /* + * We only get to return -1 here the 2nd/Nth + * invocation, we must have already signalled + * return 0 upon a previous invoation, + * return WANT_WRITE + */ + return (ret); + } + } else if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) { + /* If we are waiting for a close from our peer, we are closed */ + s->method->ssl_read_bytes(s, 0, NULL, 0, 0); + if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) { + return(-1); /* return WANT_READ */ + } + } + + if ((s->shutdown == (SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN)) && + !s->s3->alert_dispatch) + return (1); + else + return (0); +} + +int +ssl3_write(SSL *s, const void *buf, int len) +{ + int ret, n; + +#if 0 + if (s->shutdown & SSL_SEND_SHUTDOWN) { + s->rwstate = SSL_NOTHING; + return (0); + } +#endif + errno = 0; + if (s->s3->renegotiate) + ssl3_renegotiate_check(s); + + /* + * This is an experimental flag that sends the + * last handshake message in the same packet as the first + * use data - used to see if it helps the TCP protocol during + * session-id reuse + */ + /* The second test is because the buffer may have been removed */ + if ((s->s3->flags & SSL3_FLAGS_POP_BUFFER) && (s->wbio == s->bbio)) { + /* First time through, we write into the buffer */ + if (s->s3->delay_buf_pop_ret == 0) { + ret = ssl3_write_bytes(s, SSL3_RT_APPLICATION_DATA, + buf, len); + if (ret <= 0) + return (ret); + + s->s3->delay_buf_pop_ret = ret; + } + + s->rwstate = SSL_WRITING; + n = BIO_flush(s->wbio); + if (n <= 0) + return (n); + s->rwstate = SSL_NOTHING; + + /* We have flushed the buffer, so remove it */ + ssl_free_wbio_buffer(s); + s->s3->flags&= ~SSL3_FLAGS_POP_BUFFER; + + ret = s->s3->delay_buf_pop_ret; + s->s3->delay_buf_pop_ret = 0; + } else { + ret = s->method->ssl_write_bytes(s, SSL3_RT_APPLICATION_DATA, + buf, len); + if (ret <= 0) + return (ret); + } + + return (ret); +} + +static int +ssl3_read_internal(SSL *s, void *buf, int len, int peek) +{ + int ret; + + errno = 0; + if (s->s3->renegotiate) + ssl3_renegotiate_check(s); + s->s3->in_read_app_data = 1; + ret = s->method->ssl_read_bytes(s, + SSL3_RT_APPLICATION_DATA, buf, len, peek); + if ((ret == -1) && (s->s3->in_read_app_data == 2)) { + /* + * ssl3_read_bytes decided to call s->handshake_func, which + * called ssl3_read_bytes to read handshake data. + * However, ssl3_read_bytes actually found application data + * and thinks that application data makes sense here; so disable + * handshake processing and try to read application data again. + */ + s->in_handshake++; + ret = s->method->ssl_read_bytes(s, + SSL3_RT_APPLICATION_DATA, buf, len, peek); + s->in_handshake--; + } else + s->s3->in_read_app_data = 0; + + return (ret); +} + +int +ssl3_read(SSL *s, void *buf, int len) +{ + return ssl3_read_internal(s, buf, len, 0); +} + +int +ssl3_peek(SSL *s, void *buf, int len) +{ + return ssl3_read_internal(s, buf, len, 1); +} + +int +ssl3_renegotiate(SSL *s) +{ + if (s->handshake_func == NULL) + return (1); + + if (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) + return (0); + + s->s3->renegotiate = 1; + return (1); +} + +int +ssl3_renegotiate_check(SSL *s) +{ + int ret = 0; + + if (s->s3->renegotiate) { + if ((s->s3->rbuf.left == 0) && (s->s3->wbuf.left == 0) && + !SSL_in_init(s)) { + /* + * If we are the server, and we have sent + * a 'RENEGOTIATE' message, we need to go + * to SSL_ST_ACCEPT. + */ + /* SSL_ST_ACCEPT */ + s->state = SSL_ST_RENEGOTIATE; + s->s3->renegotiate = 0; + s->s3->num_renegotiations++; + s->s3->total_renegotiations++; + ret = 1; + } + } + return (ret); +} +/* + * If we are using default SHA1+MD5 algorithms switch to new SHA256 PRF + * and handshake macs if required. + */ +long +ssl_get_algorithm2(SSL *s) +{ + long alg2 = s->s3->tmp.new_cipher->algorithm2; + + if (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF && + alg2 == (SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF)) + return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256; + return alg2; +} diff --git a/crypto/libressl/ssl/s3_pkt.c b/crypto/libressl/ssl/s3_pkt.c new file mode 100644 index 0000000000..c5f2924480 --- /dev/null +++ b/crypto/libressl/ssl/s3_pkt.c @@ -0,0 +1,1391 @@ +/* $OpenBSD: s3_pkt.c,v 1.57 2015/09/12 16:10:07 doug Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include "ssl_locl.h" + +#include +#include + +#include "bytestring.h" + +static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, + unsigned int len, int create_empty_fragment); +static int ssl3_get_record(SSL *s); + +/* If extend == 0, obtain new n-byte packet; if extend == 1, increase + * packet by another n bytes. + * The packet will be in the sub-array of s->s3->rbuf.buf specified + * by s->packet and s->packet_length. + * (If s->read_ahead is set, 'max' bytes may be stored in rbuf + * [plus s->packet_length bytes if extend == 1].) + */ +int +ssl3_read_n(SSL *s, int n, int max, int extend) +{ + int i, len, left; + size_t align; + unsigned char *pkt; + SSL3_BUFFER *rb; + + if (n <= 0) + return n; + + rb = &(s->s3->rbuf); + if (rb->buf == NULL) + if (!ssl3_setup_read_buffer(s)) + return -1; + + left = rb->left; + align = (size_t)rb->buf + SSL3_RT_HEADER_LENGTH; + align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); + + if (!extend) { + /* start with empty packet ... */ + if (left == 0) + rb->offset = align; + else if (align != 0 && left >= SSL3_RT_HEADER_LENGTH) { + /* check if next packet length is large + * enough to justify payload alignment... */ + pkt = rb->buf + rb->offset; + if (pkt[0] == SSL3_RT_APPLICATION_DATA && + (pkt[3]<<8|pkt[4]) >= 128) { + /* Note that even if packet is corrupted + * and its length field is insane, we can + * only be led to wrong decision about + * whether memmove will occur or not. + * Header values has no effect on memmove + * arguments and therefore no buffer + * overrun can be triggered. */ + memmove(rb->buf + align, pkt, left); + rb->offset = align; + } + } + s->packet = rb->buf + rb->offset; + s->packet_length = 0; + /* ... now we can act as if 'extend' was set */ + } + + /* For DTLS/UDP reads should not span multiple packets + * because the read operation returns the whole packet + * at once (as long as it fits into the buffer). */ + if (SSL_IS_DTLS(s)) { + if (left > 0 && n > left) + n = left; + } + + /* if there is enough in the buffer from a previous read, take some */ + if (left >= n) { + s->packet_length += n; + rb->left = left - n; + rb->offset += n; + return (n); + } + + /* else we need to read more data */ + + len = s->packet_length; + pkt = rb->buf + align; + /* Move any available bytes to front of buffer: + * 'len' bytes already pointed to by 'packet', + * 'left' extra ones at the end */ + if (s->packet != pkt) { + /* len > 0 */ + memmove(pkt, s->packet, len + left); + s->packet = pkt; + rb->offset = len + align; + } + + if (n > (int)(rb->len - rb->offset)) { + /* does not happen */ + SSLerr(SSL_F_SSL3_READ_N, ERR_R_INTERNAL_ERROR); + return -1; + } + + if (!s->read_ahead) { + /* ignore max parameter */ + max = n; + } else { + if (max < n) + max = n; + if (max > (int)(rb->len - rb->offset)) + max = rb->len - rb->offset; + } + + while (left < n) { + /* Now we have len+left bytes at the front of s->s3->rbuf.buf + * and need to read in more until we have len+n (up to + * len+max if possible) */ + + errno = 0; + if (s->rbio != NULL) { + s->rwstate = SSL_READING; + i = BIO_read(s->rbio, pkt + len + left, max - left); + } else { + SSLerr(SSL_F_SSL3_READ_N, SSL_R_READ_BIO_NOT_SET); + i = -1; + } + + if (i <= 0) { + rb->left = left; + if (s->mode & SSL_MODE_RELEASE_BUFFERS && + !SSL_IS_DTLS(s)) { + if (len + left == 0) + ssl3_release_read_buffer(s); + } + return (i); + } + left += i; + + /* + * reads should *never* span multiple packets for DTLS because + * the underlying transport protocol is message oriented as + * opposed to byte oriented as in the TLS case. + */ + if (SSL_IS_DTLS(s)) { + if (n > left) + n = left; /* makes the while condition false */ + } + } + + /* done reading, now the book-keeping */ + rb->offset += n; + rb->left = left - n; + s->packet_length += n; + s->rwstate = SSL_NOTHING; + return (n); +} + +/* Call this to get a new input record. + * It will return <= 0 if more data is needed, normally due to an error + * or non-blocking IO. + * When it finishes, one packet has been decoded and can be found in + * ssl->s3->rrec.type - is the type of record + * ssl->s3->rrec.data, - data + * ssl->s3->rrec.length, - number of bytes + */ +/* used only by ssl3_read_bytes */ +static int +ssl3_get_record(SSL *s) +{ + int al; + int enc_err, n, i, ret = -1; + SSL3_RECORD *rr; + SSL_SESSION *sess; + unsigned char md[EVP_MAX_MD_SIZE]; + unsigned mac_size, orig_len; + + rr = &(s->s3->rrec); + sess = s->session; + +again: + /* check if we have the header */ + if ((s->rstate != SSL_ST_READ_BODY) || + (s->packet_length < SSL3_RT_HEADER_LENGTH)) { + CBS header; + uint16_t len, ssl_version; + uint8_t type; + + n = ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, s->s3->rbuf.len, 0); + if (n <= 0) + return(n); /* error or non-blocking */ + s->rstate = SSL_ST_READ_BODY; + + CBS_init(&header, s->packet, n); + + /* Pull apart the header into the SSL3_RECORD */ + if (!CBS_get_u8(&header, &type) || + !CBS_get_u16(&header, &ssl_version) || + !CBS_get_u16(&header, &len)) { + SSLerr(SSL_F_SSL3_GET_RECORD, + SSL_R_BAD_PACKET_LENGTH); + goto err; + } + + rr->type = type; + rr->length = len; + + /* Lets check version */ + if (!s->first_packet && ssl_version != s->version) { + SSLerr(SSL_F_SSL3_GET_RECORD, + SSL_R_WRONG_VERSION_NUMBER); + if ((s->version & 0xFF00) == (ssl_version & 0xFF00) && + !s->enc_write_ctx && !s->write_hash) + /* Send back error using their minor version number :-) */ + s->version = ssl_version; + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; + } + + if ((ssl_version >> 8) != SSL3_VERSION_MAJOR) { + SSLerr(SSL_F_SSL3_GET_RECORD, + SSL_R_WRONG_VERSION_NUMBER); + goto err; + } + + if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_SSL3_GET_RECORD, + SSL_R_PACKET_LENGTH_TOO_LONG); + goto f_err; + } + + /* now s->rstate == SSL_ST_READ_BODY */ + } + + /* s->rstate == SSL_ST_READ_BODY, get and decode the data */ + + if (rr->length > s->packet_length - SSL3_RT_HEADER_LENGTH) { + /* now s->packet_length == SSL3_RT_HEADER_LENGTH */ + i = rr->length; + n = ssl3_read_n(s, i, i, 1); + if (n <= 0) + return(n); /* error or non-blocking io */ + /* now n == rr->length, + * and s->packet_length == SSL3_RT_HEADER_LENGTH + rr->length */ + } + + s->rstate=SSL_ST_READ_HEADER; /* set state for later operations */ + + /* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, + * and we have that many bytes in s->packet + */ + rr->input = &(s->packet[SSL3_RT_HEADER_LENGTH]); + + /* ok, we can now read from 's->packet' data into 'rr' + * rr->input points at rr->length bytes, which + * need to be copied into rr->data by either + * the decryption or by the decompression + * When the data is 'copied' into the rr->data buffer, + * rr->input will be pointed at the new buffer */ + + /* We now have - encrypted [ MAC [ compressed [ plain ] ] ] + * rr->length bytes of encrypted compressed stuff. */ + + /* check is not needed I believe */ + if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); + goto f_err; + } + + /* decrypt in place in 'rr->input' */ + rr->data = rr->input; + + enc_err = s->method->ssl3_enc->enc(s, 0); + /* enc_err is: + * 0: (in non-constant time) if the record is publically invalid. + * 1: if the padding is valid + * -1: if the padding is invalid */ + if (enc_err == 0) { + al = SSL_AD_DECRYPTION_FAILED; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); + goto f_err; + } + + + /* r->length is now the compressed data plus mac */ + if ((sess != NULL) && (s->enc_read_ctx != NULL) && + (EVP_MD_CTX_md(s->read_hash) != NULL)) { + /* s->read_hash != NULL => mac_size != -1 */ + unsigned char *mac = NULL; + unsigned char mac_tmp[EVP_MAX_MD_SIZE]; + + mac_size = EVP_MD_CTX_size(s->read_hash); + OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); + + /* kludge: *_cbc_remove_padding passes padding length in rr->type */ + orig_len = rr->length + ((unsigned int)rr->type >> 8); + + /* orig_len is the length of the record before any padding was + * removed. This is public information, as is the MAC in use, + * therefore we can safely process the record in a different + * amount of time if it's too short to possibly contain a MAC. + */ + if (orig_len < mac_size || + /* CBC records must have a padding length byte too. */ + (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && + orig_len < mac_size + 1)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + + if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) { + /* We update the length so that the TLS header bytes + * can be constructed correctly but we need to extract + * the MAC in constant time from within the record, + * without leaking the contents of the padding bytes. + * */ + mac = mac_tmp; + ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); + rr->length -= mac_size; + } else { + /* In this case there's no padding, so |orig_len| + * equals |rec->length| and we checked that there's + * enough bytes for |mac_size| above. */ + rr->length -= mac_size; + mac = &rr->data[rr->length]; + } + + i = s->method->ssl3_enc->mac(s,md,0 /* not send */); + if (i < 0 || mac == NULL || + timingsafe_memcmp(md, mac, (size_t)mac_size) != 0) + enc_err = -1; + if (rr->length > + SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size) + enc_err = -1; + } + + if (enc_err < 0) { + /* + * A separate 'decryption_failed' alert was introduced with + * TLS 1.0, SSL 3.0 only has 'bad_record_mac'. But unless a + * decryption failure is directly visible from the ciphertext + * anyway, we should not reveal which kind of error + * occurred -- this might become visible to an attacker + * (e.g. via a logfile) + */ + al = SSL_AD_BAD_RECORD_MAC; + SSLerr(SSL_F_SSL3_GET_RECORD, + SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + goto f_err; + } + + if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_DATA_LENGTH_TOO_LONG); + goto f_err; + } + + rr->off = 0; + /* + * So at this point the following is true + * + * ssl->s3->rrec.type is the type of record + * ssl->s3->rrec.length == number of bytes in record + * ssl->s3->rrec.off == offset to first valid byte + * ssl->s3->rrec.data == where to take bytes from, increment + * after use :-). + */ + + /* we have pulled in a full packet so zero things */ + s->packet_length = 0; + + /* just read a 0 length packet */ + if (rr->length == 0) + goto again; + + return (1); + +f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); +err: + return (ret); +} + +/* Call this to write data in records of type 'type' + * It will return <= 0 if not all data has been sent or non-blocking IO. + */ +int +ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) +{ + const unsigned char *buf = buf_; + unsigned int tot, n, nw; + int i; + + if (len < 0) { + SSLerr(SSL_F_SSL3_WRITE_BYTES, ERR_R_INTERNAL_ERROR); + return -1; + } + + s->rwstate = SSL_NOTHING; + tot = s->s3->wnum; + s->s3->wnum = 0; + + if (SSL_in_init(s) && !s->in_handshake) { + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_SSL3_WRITE_BYTES, + SSL_R_SSL_HANDSHAKE_FAILURE); + return -1; + } + } + + if (len < tot) + len = tot; + n = (len - tot); + for (;;) { + if (n > s->max_send_fragment) + nw = s->max_send_fragment; + else + nw = n; + + i = do_ssl3_write(s, type, &(buf[tot]), nw, 0); + if (i <= 0) { + s->s3->wnum = tot; + return i; + } + + if ((i == (int)n) || (type == SSL3_RT_APPLICATION_DATA && + (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) { + /* + * Next chunk of data should get another prepended + * empty fragment in ciphersuites with known-IV + * weakness. + */ + s->s3->empty_fragment_done = 0; + + return tot + i; + } + + n -= i; + tot += i; + } +} + +static int +do_ssl3_write(SSL *s, int type, const unsigned char *buf, + unsigned int len, int create_empty_fragment) +{ + unsigned char *p, *plen; + int i, mac_size, clear = 0; + int prefix_len = 0; + int eivlen; + size_t align; + SSL3_RECORD *wr; + SSL3_BUFFER *wb = &(s->s3->wbuf); + SSL_SESSION *sess; + + if (wb->buf == NULL) + if (!ssl3_setup_write_buffer(s)) + return -1; + + /* first check if there is a SSL3_BUFFER still being written + * out. This will happen with non blocking IO */ + if (wb->left != 0) + return (ssl3_write_pending(s, type, buf, len)); + + /* If we have an alert to send, lets send it */ + if (s->s3->alert_dispatch) { + i = s->method->ssl_dispatch_alert(s); + if (i <= 0) + return (i); + /* if it went, fall through and send more stuff */ + /* we may have released our buffer, so get it again */ + if (wb->buf == NULL) + if (!ssl3_setup_write_buffer(s)) + return -1; + } + + if (len == 0 && !create_empty_fragment) + return 0; + + wr = &(s->s3->wrec); + sess = s->session; + + if ((sess == NULL) || (s->enc_write_ctx == NULL) || + (EVP_MD_CTX_md(s->write_hash) == NULL)) { + clear = s->enc_write_ctx ? 0 : 1; /* must be AEAD cipher */ + mac_size = 0; + } else { + mac_size = EVP_MD_CTX_size(s->write_hash); + if (mac_size < 0) + goto err; + } + + /* + * 'create_empty_fragment' is true only when this function calls + * itself. + */ + if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done) { + /* + * Countermeasure against known-IV weakness in CBC ciphersuites + * (see http://www.openssl.org/~bodo/tls-cbc.txt) + */ + if (s->s3->need_empty_fragments && + type == SSL3_RT_APPLICATION_DATA) { + /* recursive function call with 'create_empty_fragment' set; + * this prepares and buffers the data for an empty fragment + * (these 'prefix_len' bytes are sent out later + * together with the actual payload) */ + prefix_len = do_ssl3_write(s, type, buf, 0, 1); + if (prefix_len <= 0) + goto err; + + if (prefix_len > + (SSL3_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD)) { + /* insufficient space */ + SSLerr(SSL_F_DO_SSL3_WRITE, + ERR_R_INTERNAL_ERROR); + goto err; + } + } + + s->s3->empty_fragment_done = 1; + } + + if (create_empty_fragment) { + /* extra fragment would be couple of cipher blocks, + * which would be multiple of SSL3_ALIGN_PAYLOAD, so + * if we want to align the real payload, then we can + * just pretent we simply have two headers. */ + align = (size_t)wb->buf + 2 * SSL3_RT_HEADER_LENGTH; + align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); + + p = wb->buf + align; + wb->offset = align; + } else if (prefix_len) { + p = wb->buf + wb->offset + prefix_len; + } else { + align = (size_t)wb->buf + SSL3_RT_HEADER_LENGTH; + align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); + + p = wb->buf + align; + wb->offset = align; + } + + /* write the header */ + + *(p++) = type&0xff; + wr->type = type; + + *(p++) = (s->version >> 8); + /* Some servers hang if iniatial client hello is larger than 256 + * bytes and record version number > TLS 1.0 + */ + if (s->state == SSL3_ST_CW_CLNT_HELLO_B && !s->renegotiate && + TLS1_get_version(s) > TLS1_VERSION) + *(p++) = 0x1; + else + *(p++) = s->version&0xff; + + /* field where we are to write out packet length */ + plen = p; + p += 2; + + /* Explicit IV length. */ + if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s)) { + int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx); + if (mode == EVP_CIPH_CBC_MODE) { + eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx); + if (eivlen <= 1) + eivlen = 0; + } + /* Need explicit part of IV for GCM mode */ + else if (mode == EVP_CIPH_GCM_MODE) + eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN; + else + eivlen = 0; + } else if (s->aead_write_ctx != NULL && + s->aead_write_ctx->variable_nonce_in_record) { + eivlen = s->aead_write_ctx->variable_nonce_len; + } else + eivlen = 0; + + /* lets setup the record stuff. */ + wr->data = p + eivlen; + wr->length = (int)len; + wr->input = (unsigned char *)buf; + + /* we now 'read' from wr->input, wr->length bytes into wr->data */ + + memcpy(wr->data, wr->input, wr->length); + wr->input = wr->data; + + /* we should still have the output to wr->data and the input + * from wr->input. Length should be wr->length. + * wr->data still points in the wb->buf */ + + if (mac_size != 0) { + if (s->method->ssl3_enc->mac(s, + &(p[wr->length + eivlen]), 1) < 0) + goto err; + wr->length += mac_size; + } + + wr->input = p; + wr->data = p; + + if (eivlen) { + /* if (RAND_pseudo_bytes(p, eivlen) <= 0) + goto err; + */ + wr->length += eivlen; + } + + /* ssl3_enc can only have an error on read */ + s->method->ssl3_enc->enc(s, 1); + + /* record length after mac and block padding */ + s2n(wr->length, plen); + + /* we should now have + * wr->data pointing to the encrypted data, which is + * wr->length long */ + wr->type=type; /* not needed but helps for debugging */ + wr->length += SSL3_RT_HEADER_LENGTH; + + if (create_empty_fragment) { + /* we are in a recursive call; + * just return the length, don't write out anything here + */ + return wr->length; + } + + /* now let's set up wb */ + wb->left = prefix_len + wr->length; + + /* memorize arguments so that ssl3_write_pending can detect + * bad write retries later */ + s->s3->wpend_tot = len; + s->s3->wpend_buf = buf; + s->s3->wpend_type = type; + s->s3->wpend_ret = len; + + /* we now just need to write the buffer */ + return ssl3_write_pending(s, type, buf, len); +err: + return -1; +} + +/* if s->s3->wbuf.left != 0, we need to call this */ +int +ssl3_write_pending(SSL *s, int type, const unsigned char *buf, unsigned int len) +{ + int i; + SSL3_BUFFER *wb = &(s->s3->wbuf); + + /* XXXX */ + if ((s->s3->wpend_tot > (int)len) || ((s->s3->wpend_buf != buf) && + !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)) || + (s->s3->wpend_type != type)) { + SSLerr(SSL_F_SSL3_WRITE_PENDING, SSL_R_BAD_WRITE_RETRY); + return (-1); + } + + for (;;) { + errno = 0; + if (s->wbio != NULL) { + s->rwstate = SSL_WRITING; + i = BIO_write(s->wbio, + (char *)&(wb->buf[wb->offset]), + (unsigned int)wb->left); + } else { + SSLerr(SSL_F_SSL3_WRITE_PENDING, SSL_R_BIO_NOT_SET); + i = -1; + } + if (i == wb->left) { + wb->left = 0; + wb->offset += i; + if (s->mode & SSL_MODE_RELEASE_BUFFERS && + !SSL_IS_DTLS(s)) + ssl3_release_write_buffer(s); + s->rwstate = SSL_NOTHING; + return (s->s3->wpend_ret); + } else if (i <= 0) { + /* + * For DTLS, just drop it. That's kind of the + * whole point in using a datagram service. + */ + if (SSL_IS_DTLS(s)) + wb->left = 0; + return (i); + } + wb->offset += i; + wb->left -= i; + } +} + +/* Return up to 'len' payload bytes received in 'type' records. + * 'type' is one of the following: + * + * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) + * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) + * - 0 (during a shutdown, no data has to be returned) + * + * If we don't have stored data to work from, read a SSL/TLS record first + * (possibly multiple records if we still don't have anything to return). + * + * This function must handle any surprises the peer may have for us, such as + * Alert records (e.g. close_notify), ChangeCipherSpec records (not really + * a surprise, but handled as if it were), or renegotiation requests. + * Also if record payloads contain fragments too small to process, we store + * them until there is enough for the respective protocol (the record protocol + * may use arbitrary fragmentation and even interleaving): + * Change cipher spec protocol + * just 1 byte needed, no need for keeping anything stored + * Alert protocol + * 2 bytes needed (AlertLevel, AlertDescription) + * Handshake protocol + * 4 bytes needed (HandshakeType, uint24 length) -- we just have + * to detect unexpected Client Hello and Hello Request messages + * here, anything else is handled by higher layers + * Application data protocol + * none of our business + */ +int +ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) +{ + int al, i, j, ret; + unsigned int n; + SSL3_RECORD *rr; + void (*cb)(const SSL *ssl, int type2, int val) = NULL; + + if (s->s3->rbuf.buf == NULL) /* Not initialized yet */ + if (!ssl3_setup_read_buffer(s)) + return (-1); + + if (len < 0) { + SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR); + return -1; + } + + if ((type && type != SSL3_RT_APPLICATION_DATA && + type != SSL3_RT_HANDSHAKE) || + (peek && (type != SSL3_RT_APPLICATION_DATA))) { + SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR); + return -1; + } + + if ((type == SSL3_RT_HANDSHAKE) && + (s->s3->handshake_fragment_len > 0)) { + /* (partially) satisfy request from storage */ + unsigned char *src = s->s3->handshake_fragment; + unsigned char *dst = buf; + unsigned int k; + + /* peek == 0 */ + n = 0; + while ((len > 0) && (s->s3->handshake_fragment_len > 0)) { + *dst++ = *src++; + len--; + s->s3->handshake_fragment_len--; + n++; + } + /* move any remaining fragment bytes: */ + for (k = 0; k < s->s3->handshake_fragment_len; k++) + s->s3->handshake_fragment[k] = *src++; + return n; + } + + /* + * Now s->s3->handshake_fragment_len == 0 if + * type == SSL3_RT_HANDSHAKE. + */ + if (!s->in_handshake && SSL_in_init(s)) { + /* type == SSL3_RT_APPLICATION_DATA */ + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_SSL3_READ_BYTES, + SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + } +start: + s->rwstate = SSL_NOTHING; + + /* + * s->s3->rrec.type - is the type of record + * s->s3->rrec.data, - data + * s->s3->rrec.off, - offset into 'data' for next read + * s->s3->rrec.length, - number of bytes. + */ + rr = &(s->s3->rrec); + + /* get new packet if necessary */ + if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY)) { + ret = ssl3_get_record(s); + if (ret <= 0) + return (ret); + } + + /* we now have a packet which can be read and processed */ + + if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, + * reset by ssl3_get_finished */ + && (rr->type != SSL3_RT_HANDSHAKE)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, + SSL_R_DATA_BETWEEN_CCS_AND_FINISHED); + goto f_err; + } + + /* If the other end has shut down, throw anything we read away + * (even in 'peek' mode) */ + if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { + rr->length = 0; + s->rwstate = SSL_NOTHING; + return (0); + } + + + /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */ + if (type == rr->type) { + /* make sure that we are not getting application data when we + * are doing a handshake for the first time */ + if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && + (s->enc_read_ctx == NULL)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, + SSL_R_APP_DATA_IN_HANDSHAKE); + goto f_err; + } + + if (len <= 0) + return (len); + + if ((unsigned int)len > rr->length) + n = rr->length; + else + n = (unsigned int)len; + + memcpy(buf, &(rr->data[rr->off]), n); + if (!peek) { + memset(&(rr->data[rr->off]), 0, n); + rr->length -= n; + rr->off += n; + if (rr->length == 0) { + s->rstate = SSL_ST_READ_HEADER; + rr->off = 0; + if (s->mode & SSL_MODE_RELEASE_BUFFERS && + s->s3->rbuf.left == 0) + ssl3_release_read_buffer(s); + } + } + return (n); + } + + + /* If we get here, then type != rr->type; if we have a handshake + * message, then it was unexpected (Hello Request or Client Hello). */ + + { + /* + * In case of record types for which we have 'fragment' + * storage, * fill that so that we can process the data + * at a fixed place. + */ + unsigned int dest_maxlen = 0; + unsigned char *dest = NULL; + unsigned int *dest_len = NULL; + + if (rr->type == SSL3_RT_HANDSHAKE) { + dest_maxlen = sizeof s->s3->handshake_fragment; + dest = s->s3->handshake_fragment; + dest_len = &s->s3->handshake_fragment_len; + } else if (rr->type == SSL3_RT_ALERT) { + dest_maxlen = sizeof s->s3->alert_fragment; + dest = s->s3->alert_fragment; + dest_len = &s->s3->alert_fragment_len; + } + if (dest_maxlen > 0) { + /* available space in 'dest' */ + n = dest_maxlen - *dest_len; + if (rr->length < n) + n = rr->length; /* available bytes */ + + /* now move 'n' bytes: */ + while (n-- > 0) { + dest[(*dest_len)++] = rr->data[rr->off++]; + rr->length--; + } + + if (*dest_len < dest_maxlen) + goto start; /* fragment was too small */ + } + } + + /* s->s3->handshake_fragment_len == 4 iff rr->type == SSL3_RT_HANDSHAKE; + * s->s3->alert_fragment_len == 2 iff rr->type == SSL3_RT_ALERT. + * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */ + + /* If we are a client, check for an incoming 'Hello Request': */ + if ((!s->server) && (s->s3->handshake_fragment_len >= 4) && + (s->s3->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && + (s->session != NULL) && (s->session->cipher != NULL)) { + s->s3->handshake_fragment_len = 0; + + if ((s->s3->handshake_fragment[1] != 0) || + (s->s3->handshake_fragment[2] != 0) || + (s->s3->handshake_fragment[3] != 0)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_BAD_HELLO_REQUEST); + goto f_err; + } + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, + s->s3->handshake_fragment, 4, s, + s->msg_callback_arg); + + if (SSL_is_init_finished(s) && + !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && + !s->s3->renegotiate) { + ssl3_renegotiate(s); + if (ssl3_renegotiate_check(s)) { + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_SSL3_READ_BYTES, + SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + + if (!(s->mode & SSL_MODE_AUTO_RETRY)) { + if (s->s3->rbuf.left == 0) { + /* no read-ahead left? */ + BIO *bio; + /* In the case where we try to read application data, + * but we trigger an SSL handshake, we return -1 with + * the retry option set. Otherwise renegotiation may + * cause nasty problems in the blocking world */ + s->rwstate = SSL_READING; + bio = SSL_get_rbio(s); + BIO_clear_retry_flags(bio); + BIO_set_retry_read(bio); + return (-1); + } + } + } + } + /* we either finished a handshake or ignored the request, + * now try again to obtain the (application) data we were asked for */ + goto start; + } + /* If we are a server and get a client hello when renegotiation isn't + * allowed send back a no renegotiation alert and carry on. + * WARNING: experimental code, needs reviewing (steve) + */ + if (s->server && + SSL_is_init_finished(s) && + !s->s3->send_connection_binding && + (s->s3->handshake_fragment_len >= 4) && + (s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) && + (s->session != NULL) && (s->session->cipher != NULL)) { + /*s->s3->handshake_fragment_len = 0;*/ + rr->length = 0; + ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION); + goto start; + } + if (s->s3->alert_fragment_len >= 2) { + int alert_level = s->s3->alert_fragment[0]; + int alert_descr = s->s3->alert_fragment[1]; + + s->s3->alert_fragment_len = 0; + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_ALERT, + s->s3->alert_fragment, 2, s, s->msg_callback_arg); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + if (cb != NULL) { + j = (alert_level << 8) | alert_descr; + cb(s, SSL_CB_READ_ALERT, j); + } + + if (alert_level == 1) { + /* warning */ + s->s3->warn_alert = alert_descr; + if (alert_descr == SSL_AD_CLOSE_NOTIFY) { + s->shutdown |= SSL_RECEIVED_SHUTDOWN; + return (0); + } + /* This is a warning but we receive it if we requested + * renegotiation and the peer denied it. Terminate with + * a fatal alert because if application tried to + * renegotiatie it presumably had a good reason and + * expects it to succeed. + * + * In future we might have a renegotiation where we + * don't care if the peer refused it where we carry on. + */ + else if (alert_descr == SSL_AD_NO_RENEGOTIATION) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_READ_BYTES, + SSL_R_NO_RENEGOTIATION); + goto f_err; + } + } else if (alert_level == 2) { + /* fatal */ + s->rwstate = SSL_NOTHING; + s->s3->fatal_alert = alert_descr; + SSLerr(SSL_F_SSL3_READ_BYTES, + SSL_AD_REASON_OFFSET + alert_descr); + ERR_asprintf_error_data("SSL alert number %d", + alert_descr); + s->shutdown |= SSL_RECEIVED_SHUTDOWN; + SSL_CTX_remove_session(s->ctx, s->session); + return (0); + } else { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNKNOWN_ALERT_TYPE); + goto f_err; + } + + goto start; + } + + if (s->shutdown & SSL_SENT_SHUTDOWN) { + /* but we have not received a shutdown */ + s->rwstate = SSL_NOTHING; + rr->length = 0; + return (0); + } + + if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { + /* 'Change Cipher Spec' is just a single byte, so we know + * exactly what the record payload has to look like */ + if ((rr->length != 1) || (rr->off != 0) || + (rr->data[0] != SSL3_MT_CCS)) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_READ_BYTES, + SSL_R_BAD_CHANGE_CIPHER_SPEC); + goto f_err; + } + + /* Check we have a cipher to change to */ + if (s->s3->tmp.new_cipher == NULL) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, + SSL_R_CCS_RECEIVED_EARLY); + goto f_err; + } + + /* Check that we should be receiving a Change Cipher Spec. */ + if (!(s->s3->flags & SSL3_FLAGS_CCS_OK)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, + SSL_R_CCS_RECEIVED_EARLY); + goto f_err; + } + s->s3->flags &= ~SSL3_FLAGS_CCS_OK; + + rr->length = 0; + + if (s->msg_callback) { + s->msg_callback(0, s->version, + SSL3_RT_CHANGE_CIPHER_SPEC, rr->data, 1, s, + s->msg_callback_arg); + } + + s->s3->change_cipher_spec = 1; + if (!ssl3_do_change_cipher_spec(s)) + goto err; + else + goto start; + } + + /* Unexpected handshake message (Client Hello, or protocol violation) */ + if ((s->s3->handshake_fragment_len >= 4) && !s->in_handshake) { + if (((s->state&SSL_ST_MASK) == SSL_ST_OK) && + !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) { + s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; + s->renegotiate = 1; + s->new_session = 1; + } + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_SSL3_READ_BYTES, + SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + + if (!(s->mode & SSL_MODE_AUTO_RETRY)) { + if (s->s3->rbuf.left == 0) { /* no read-ahead left? */ + BIO *bio; + /* In the case where we try to read application data, + * but we trigger an SSL handshake, we return -1 with + * the retry option set. Otherwise renegotiation may + * cause nasty problems in the blocking world */ + s->rwstate = SSL_READING; + bio = SSL_get_rbio(s); + BIO_clear_retry_flags(bio); + BIO_set_retry_read(bio); + return (-1); + } + } + goto start; + } + + switch (rr->type) { + default: + /* + * TLS up to v1.1 just ignores unknown message types: + * TLS v1.2 give an unexpected message alert. + */ + if (s->version >= TLS1_VERSION && + s->version <= TLS1_1_VERSION) { + rr->length = 0; + goto start; + } + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD); + goto f_err; + case SSL3_RT_CHANGE_CIPHER_SPEC: + case SSL3_RT_ALERT: + case SSL3_RT_HANDSHAKE: + /* we already handled all of these, with the possible exception + * of SSL3_RT_HANDSHAKE when s->in_handshake is set, but that + * should not happen when type != rr->type */ + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR); + goto f_err; + case SSL3_RT_APPLICATION_DATA: + /* At this point, we were expecting handshake data, + * but have application data. If the library was + * running inside ssl3_read() (i.e. in_read_app_data + * is set) and it makes sense to read application data + * at this point (session renegotiation not yet started), + * we will indulge it. + */ + if (s->s3->in_read_app_data && + (s->s3->total_renegotiations != 0) && + (((s->state & SSL_ST_CONNECT) && + (s->state >= SSL3_ST_CW_CLNT_HELLO_A) && + (s->state <= SSL3_ST_CR_SRVR_HELLO_A)) || + ((s->state & SSL_ST_ACCEPT) && + (s->state <= SSL3_ST_SW_HELLO_REQ_A) && + (s->state >= SSL3_ST_SR_CLNT_HELLO_A)))) { + s->s3->in_read_app_data = 2; + return (-1); + } else { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD); + goto f_err; + } + } + /* not reached */ + +f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); +err: + return (-1); +} + +int +ssl3_do_change_cipher_spec(SSL *s) +{ + int i; + const char *sender; + int slen; + + if (s->state & SSL_ST_ACCEPT) + i = SSL3_CHANGE_CIPHER_SERVER_READ; + else + i = SSL3_CHANGE_CIPHER_CLIENT_READ; + + if (s->s3->tmp.key_block == NULL) { + if (s->session == NULL || s->session->master_key_length == 0) { + /* might happen if dtls1_read_bytes() calls this */ + SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, + SSL_R_CCS_RECEIVED_EARLY); + return (0); + } + + s->session->cipher = s->s3->tmp.new_cipher; + if (!s->method->ssl3_enc->setup_key_block(s)) + return (0); + } + + if (!s->method->ssl3_enc->change_cipher_state(s, i)) + return (0); + + /* we have to record the message digest at + * this point so we can get it before we read + * the finished message */ + if (s->state & SSL_ST_CONNECT) { + sender = s->method->ssl3_enc->server_finished_label; + slen = s->method->ssl3_enc->server_finished_label_len; + } else { + sender = s->method->ssl3_enc->client_finished_label; + slen = s->method->ssl3_enc->client_finished_label_len; + } + + i = s->method->ssl3_enc->final_finish_mac(s, sender, slen, + s->s3->tmp.peer_finish_md); + if (i == 0) { + SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR); + return 0; + } + s->s3->tmp.peer_finish_md_len = i; + + return (1); +} + +int +ssl3_send_alert(SSL *s, int level, int desc) +{ + /* Map tls/ssl alert value to correct one */ + desc = s->method->ssl3_enc->alert_value(desc); + if (desc < 0) + return -1; + /* If a fatal one, remove from cache */ + if ((level == 2) && (s->session != NULL)) + SSL_CTX_remove_session(s->ctx, s->session); + + s->s3->alert_dispatch = 1; + s->s3->send_alert[0] = level; + s->s3->send_alert[1] = desc; + if (s->s3->wbuf.left == 0) /* data still being written out? */ + return s->method->ssl_dispatch_alert(s); + + /* else data is still being written out, we will get written + * some time in the future */ + return -1; +} + +int +ssl3_dispatch_alert(SSL *s) +{ + int i, j; + void (*cb)(const SSL *ssl, int type, int val) = NULL; + + s->s3->alert_dispatch = 0; + i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2, 0); + if (i <= 0) { + s->s3->alert_dispatch = 1; + } else { + /* Alert sent to BIO. If it is important, flush it now. + * If the message does not get sent due to non-blocking IO, + * we will not worry too much. */ + if (s->s3->send_alert[0] == SSL3_AL_FATAL) + (void)BIO_flush(s->wbio); + + if (s->msg_callback) + s->msg_callback(1, s->version, SSL3_RT_ALERT, + s->s3->send_alert, 2, s, s->msg_callback_arg); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + if (cb != NULL) { + j = (s->s3->send_alert[0]<<8)|s->s3->send_alert[1]; + cb(s, SSL_CB_WRITE_ALERT, j); + } + } + return (i); +} diff --git a/crypto/libressl/ssl/s3_srvr.c b/crypto/libressl/ssl/s3_srvr.c new file mode 100644 index 0000000000..94974a6afc --- /dev/null +++ b/crypto/libressl/ssl/s3_srvr.c @@ -0,0 +1,2692 @@ +/* $OpenBSD: s3_srvr.c,v 1.125 2016/03/11 07:08:45 mmcc Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include + +#include "ssl_locl.h" + +#include +#include +#include +#include +#ifndef OPENSSL_NO_GOST +#include +#endif +#include +#include +#include +#include + +#include "bytestring.h" + +int +ssl3_accept(SSL *s) +{ + unsigned long alg_k; + void (*cb)(const SSL *ssl, int type, int val) = NULL; + int ret = -1; + int new_state, state, skip = 0; + + ERR_clear_error(); + errno = 0; + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + /* init things to blank */ + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + + if (s->cert == NULL) { + SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_NO_CERTIFICATE_SET); + ret = -1; + goto end; + } + + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_RENEGOTIATE: + s->renegotiate = 1; + /* s->state=SSL_ST_ACCEPT; */ + + case SSL_ST_BEFORE: + case SSL_ST_ACCEPT: + case SSL_ST_BEFORE|SSL_ST_ACCEPT: + case SSL_ST_OK|SSL_ST_ACCEPT: + + s->server = 1; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + if ((s->version >> 8) != 3) { + SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR); + ret = -1; + goto end; + } + s->type = SSL_ST_ACCEPT; + + if (!ssl3_setup_init_buffer(s)) { + ret = -1; + goto end; + } + if (!ssl3_setup_buffers(s)) { + ret = -1; + goto end; + } + + s->init_num = 0; + + if (s->state != SSL_ST_RENEGOTIATE) { + /* + * Ok, we now need to push on a buffering BIO + * so that the output is sent in a way that + * TCP likes :-) + */ + if (!ssl_init_wbio_buffer(s, 1)) { + ret = -1; + goto end; + } + + if (!tls1_init_finished_mac(s)) { + ret = -1; + goto end; + } + + s->state = SSL3_ST_SR_CLNT_HELLO_A; + s->ctx->stats.sess_accept++; + } else if (!s->s3->send_connection_binding) { + /* + * Server attempting to renegotiate with + * client that doesn't support secure + * renegotiation. + */ + SSLerr(SSL_F_SSL3_ACCEPT, + SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_HANDSHAKE_FAILURE); + ret = -1; + goto end; + } else { + /* + * s->state == SSL_ST_RENEGOTIATE, + * we will just send a HelloRequest + */ + s->ctx->stats.sess_accept_renegotiate++; + s->state = SSL3_ST_SW_HELLO_REQ_A; + } + break; + + case SSL3_ST_SW_HELLO_REQ_A: + case SSL3_ST_SW_HELLO_REQ_B: + + s->shutdown = 0; + ret = ssl3_send_hello_request(s); + if (ret <= 0) + goto end; + s->s3->tmp.next_state = SSL3_ST_SW_HELLO_REQ_C; + s->state = SSL3_ST_SW_FLUSH; + s->init_num = 0; + + if (!tls1_init_finished_mac(s)) { + ret = -1; + goto end; + } + break; + + case SSL3_ST_SW_HELLO_REQ_C: + s->state = SSL_ST_OK; + break; + + case SSL3_ST_SR_CLNT_HELLO_A: + case SSL3_ST_SR_CLNT_HELLO_B: + case SSL3_ST_SR_CLNT_HELLO_C: + + s->shutdown = 0; + if (s->rwstate != SSL_X509_LOOKUP) { + ret = ssl3_get_client_hello(s); + if (ret <= 0) + goto end; + } + + s->renegotiate = 2; + s->state = SSL3_ST_SW_SRVR_HELLO_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_SRVR_HELLO_A: + case SSL3_ST_SW_SRVR_HELLO_B: + ret = ssl3_send_server_hello(s); + if (ret <= 0) + goto end; + if (s->hit) { + if (s->tlsext_ticket_expected) + s->state = SSL3_ST_SW_SESSION_TICKET_A; + else + s->state = SSL3_ST_SW_CHANGE_A; + } + else + s->state = SSL3_ST_SW_CERT_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_A: + case SSL3_ST_SW_CERT_B: + /* Check if it is anon DH or anon ECDH. */ + if (!(s->s3->tmp.new_cipher->algorithm_auth & + SSL_aNULL)) { + ret = ssl3_send_server_certificate(s); + if (ret <= 0) + goto end; + if (s->tlsext_status_expected) + s->state = SSL3_ST_SW_CERT_STATUS_A; + else + s->state = SSL3_ST_SW_KEY_EXCH_A; + } else { + skip = 1; + s->state = SSL3_ST_SW_KEY_EXCH_A; + } + s->init_num = 0; + break; + + case SSL3_ST_SW_KEY_EXCH_A: + case SSL3_ST_SW_KEY_EXCH_B: + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + + /* + * Only send if using a DH key exchange. + * + * For ECC ciphersuites, we send a ServerKeyExchange + * message only if the cipher suite is ECDHE. In other + * cases, the server certificate contains the server's + * public key for key exchange. + */ + if (alg_k & (SSL_kDHE|SSL_kECDHE)) { + ret = ssl3_send_server_key_exchange(s); + if (ret <= 0) + goto end; + } else + skip = 1; + + s->state = SSL3_ST_SW_CERT_REQ_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_REQ_A: + case SSL3_ST_SW_CERT_REQ_B: + /* + * Determine whether or not we need to request a + * certificate. + * + * Do not request a certificate if: + * + * - We did not ask for it (SSL_VERIFY_PEER is unset). + * + * - SSL_VERIFY_CLIENT_ONCE is set and we are + * renegotiating. + * + * - We are using an anonymous ciphersuites + * (see section "Certificate request" in SSL 3 drafts + * and in RFC 2246) ... except when the application + * insists on verification (against the specs, but + * s3_clnt.c accepts this for SSL 3). + */ + if (!(s->verify_mode & SSL_VERIFY_PEER) || + ((s->session->peer != NULL) && + (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) || + ((s->s3->tmp.new_cipher->algorithm_auth & + SSL_aNULL) && !(s->verify_mode & + SSL_VERIFY_FAIL_IF_NO_PEER_CERT))) { + /* No cert request */ + skip = 1; + s->s3->tmp.cert_request = 0; + s->state = SSL3_ST_SW_SRVR_DONE_A; + if (s->s3->handshake_buffer) { + if (!tls1_digest_cached_records(s)) { + ret = -1; + goto end; + } + } + } else { + s->s3->tmp.cert_request = 1; + ret = ssl3_send_certificate_request(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_SRVR_DONE_A; + s->init_num = 0; + } + break; + + case SSL3_ST_SW_SRVR_DONE_A: + case SSL3_ST_SW_SRVR_DONE_B: + ret = ssl3_send_server_done(s); + if (ret <= 0) + goto end; + s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; + s->state = SSL3_ST_SW_FLUSH; + s->init_num = 0; + break; + + case SSL3_ST_SW_FLUSH: + + /* + * This code originally checked to see if + * any data was pending using BIO_CTRL_INFO + * and then flushed. This caused problems + * as documented in PR#1939. The proposed + * fix doesn't completely resolve this issue + * as buggy implementations of BIO_CTRL_PENDING + * still exist. So instead we just flush + * unconditionally. + */ + + s->rwstate = SSL_WRITING; + if (BIO_flush(s->wbio) <= 0) { + ret = -1; + goto end; + } + s->rwstate = SSL_NOTHING; + + s->state = s->s3->tmp.next_state; + break; + + case SSL3_ST_SR_CERT_A: + case SSL3_ST_SR_CERT_B: + if (s->s3->tmp.cert_request) { + ret = ssl3_get_client_certificate(s); + if (ret <= 0) + goto end; + } + s->init_num = 0; + s->state = SSL3_ST_SR_KEY_EXCH_A; + break; + + case SSL3_ST_SR_KEY_EXCH_A: + case SSL3_ST_SR_KEY_EXCH_B: + ret = ssl3_get_client_key_exchange(s); + if (ret <= 0) + goto end; + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + if (ret == 2) { + /* + * For the ECDH ciphersuites when + * the client sends its ECDH pub key in + * a certificate, the CertificateVerify + * message is not sent. + * Also for GOST ciphersuites when + * the client uses its key from the certificate + * for key exchange. + */ + if (s->s3->next_proto_neg_seen) + s->state = SSL3_ST_SR_NEXT_PROTO_A; + else + s->state = SSL3_ST_SR_FINISHED_A; + s->init_num = 0; + } else if (SSL_USE_SIGALGS(s) || (alg_k & SSL_kGOST)) { + s->state = SSL3_ST_SR_CERT_VRFY_A; + s->init_num = 0; + if (!s->session->peer) + break; + /* + * For sigalgs freeze the handshake buffer + * at this point and digest cached records. + */ + if (!s->s3->handshake_buffer) { + SSLerr(SSL_F_SSL3_ACCEPT, + ERR_R_INTERNAL_ERROR); + ret = -1; + goto end; + } + s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE; + if (!tls1_digest_cached_records(s)) { + ret = -1; + goto end; + } + } else { + int offset = 0; + int dgst_num; + + s->state = SSL3_ST_SR_CERT_VRFY_A; + s->init_num = 0; + + /* + * We need to get hashes here so if there is + * a client cert, it can be verified + * FIXME - digest processing for + * CertificateVerify should be generalized. + * But it is next step + */ + if (s->s3->handshake_buffer) { + if (!tls1_digest_cached_records(s)) { + ret = -1; + goto end; + } + } + for (dgst_num = 0; dgst_num < SSL_MAX_DIGEST; + dgst_num++) + if (s->s3->handshake_dgst[dgst_num]) { + int dgst_size; + + s->method->ssl3_enc->cert_verify_mac(s, + EVP_MD_CTX_type( + s->s3->handshake_dgst[dgst_num]), + &(s->s3->tmp.cert_verify_md[offset])); + dgst_size = EVP_MD_CTX_size( + s->s3->handshake_dgst[dgst_num]); + if (dgst_size < 0) { + ret = -1; + goto end; + } + offset += dgst_size; + } + } + break; + + case SSL3_ST_SR_CERT_VRFY_A: + case SSL3_ST_SR_CERT_VRFY_B: + s->s3->flags |= SSL3_FLAGS_CCS_OK; + + /* we should decide if we expected this one */ + ret = ssl3_get_cert_verify(s); + if (ret <= 0) + goto end; + + if (s->s3->next_proto_neg_seen) + s->state = SSL3_ST_SR_NEXT_PROTO_A; + else + s->state = SSL3_ST_SR_FINISHED_A; + s->init_num = 0; + break; + + case SSL3_ST_SR_NEXT_PROTO_A: + case SSL3_ST_SR_NEXT_PROTO_B: + ret = ssl3_get_next_proto(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL3_ST_SR_FINISHED_A; + break; + + case SSL3_ST_SR_FINISHED_A: + case SSL3_ST_SR_FINISHED_B: + s->s3->flags |= SSL3_FLAGS_CCS_OK; + ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A, + SSL3_ST_SR_FINISHED_B); + if (ret <= 0) + goto end; + if (s->hit) + s->state = SSL_ST_OK; + else if (s->tlsext_ticket_expected) + s->state = SSL3_ST_SW_SESSION_TICKET_A; + else + s->state = SSL3_ST_SW_CHANGE_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_SESSION_TICKET_A: + case SSL3_ST_SW_SESSION_TICKET_B: + ret = ssl3_send_newsession_ticket(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_CHANGE_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_STATUS_A: + case SSL3_ST_SW_CERT_STATUS_B: + ret = ssl3_send_cert_status(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_KEY_EXCH_A; + s->init_num = 0; + break; + + + case SSL3_ST_SW_CHANGE_A: + case SSL3_ST_SW_CHANGE_B: + + s->session->cipher = s->s3->tmp.new_cipher; + if (!s->method->ssl3_enc->setup_key_block(s)) { + ret = -1; + goto end; + } + + ret = ssl3_send_change_cipher_spec(s, + SSL3_ST_SW_CHANGE_A, SSL3_ST_SW_CHANGE_B); + + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_FINISHED_A; + s->init_num = 0; + + if (!s->method->ssl3_enc->change_cipher_state( + s, SSL3_CHANGE_CIPHER_SERVER_WRITE)) { + ret = -1; + goto end; + } + + break; + + case SSL3_ST_SW_FINISHED_A: + case SSL3_ST_SW_FINISHED_B: + ret = ssl3_send_finished(s, + SSL3_ST_SW_FINISHED_A, SSL3_ST_SW_FINISHED_B, + s->method->ssl3_enc->server_finished_label, + s->method->ssl3_enc->server_finished_label_len); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_FLUSH; + if (s->hit) { + if (s->s3->next_proto_neg_seen) { + s->s3->flags |= SSL3_FLAGS_CCS_OK; + s->s3->tmp.next_state = + SSL3_ST_SR_NEXT_PROTO_A; + } else + s->s3->tmp.next_state = + SSL3_ST_SR_FINISHED_A; + } else + s->s3->tmp.next_state = SSL_ST_OK; + s->init_num = 0; + break; + + case SSL_ST_OK: + /* clean a few things up */ + tls1_cleanup_key_block(s); + + BUF_MEM_free(s->init_buf); + s->init_buf = NULL; + + /* remove buffering on output */ + ssl_free_wbio_buffer(s); + + s->init_num = 0; + + /* skipped if we just sent a HelloRequest */ + if (s->renegotiate == 2) { + s->renegotiate = 0; + s->new_session = 0; + + ssl_update_cache(s, SSL_SESS_CACHE_SERVER); + + s->ctx->stats.sess_accept_good++; + /* s->server=1; */ + s->handshake_func = ssl3_accept; + + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_DONE, 1); + } + + ret = 1; + goto end; + /* break; */ + + default: + SSLerr(SSL_F_SSL3_ACCEPT, + SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* break; */ + } + + if (!s->s3->tmp.reuse_message && !skip) { + if (s->debug) { + if ((ret = BIO_flush(s->wbio)) <= 0) + goto end; + } + + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_ACCEPT_LOOP, 1); + s->state = new_state; + } + } + skip = 0; + } +end: + /* BIO_flush(s->wbio); */ + + s->in_handshake--; + if (cb != NULL) + cb(s, SSL_CB_ACCEPT_EXIT, ret); + return (ret); +} + +int +ssl3_send_hello_request(SSL *s) +{ + if (s->state == SSL3_ST_SW_HELLO_REQ_A) { + ssl3_handshake_msg_start(s, SSL3_MT_HELLO_REQUEST); + ssl3_handshake_msg_finish(s, 0); + + s->state = SSL3_ST_SW_HELLO_REQ_B; + } + + /* SSL3_ST_SW_HELLO_REQ_B */ + return (ssl3_handshake_write(s)); +} + +int +ssl3_get_client_hello(SSL *s) +{ + int i, j, ok, al, ret = -1; + unsigned int cookie_len; + long n; + unsigned long id; + unsigned char *p, *d; + SSL_CIPHER *c; + STACK_OF(SSL_CIPHER) *ciphers = NULL; + unsigned long alg_k; + + /* + * We do this so that we will respond with our native type. + * If we are TLSv1 and we get SSLv3, we will respond with TLSv1, + * This down switching should be handled by a different method. + * If we are SSLv3, we will respond with SSLv3, even if prompted with + * TLSv1. + */ + if (s->state == SSL3_ST_SR_CLNT_HELLO_A) { + s->state = SSL3_ST_SR_CLNT_HELLO_B; + } + s->first_packet = 1; + n = s->method->ssl_get_message(s, SSL3_ST_SR_CLNT_HELLO_B, + SSL3_ST_SR_CLNT_HELLO_C, SSL3_MT_CLIENT_HELLO, + SSL3_RT_MAX_PLAIN_LENGTH, &ok); + + if (!ok) + return ((int)n); + s->first_packet = 0; + d = p = (unsigned char *)s->init_msg; + + if (2 > n) + goto truncated; + /* + * Use version from inside client hello, not from record header. + * (may differ: see RFC 2246, Appendix E, second paragraph) + */ + s->client_version = (((int)p[0]) << 8)|(int)p[1]; + p += 2; + + if ((s->version == DTLS1_VERSION && s->client_version > s->version) || + (s->version != DTLS1_VERSION && s->client_version < s->version)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_WRONG_VERSION_NUMBER); + if ((s->client_version >> 8) == SSL3_VERSION_MAJOR && + !s->enc_write_ctx && !s->write_hash) { + /* + * Similar to ssl3_get_record, send alert using remote + * version number + */ + s->version = s->client_version; + } + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; + } + + /* + * If we require cookies and this ClientHello doesn't + * contain one, just return since we do not want to + * allocate any memory yet. So check cookie length... + */ + if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) { + unsigned int session_length, cookie_length; + + session_length = *(p + SSL3_RANDOM_SIZE); + cookie_length = *(p + SSL3_RANDOM_SIZE + session_length + 1); + + if (cookie_length == 0) + return (1); + } + + if (p + SSL3_RANDOM_SIZE + 1 - d > n) + goto truncated; + + /* load the client random */ + memcpy(s->s3->client_random, p, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + + /* get the session-id */ + j= *(p++); + if (p + j - d > n) + goto truncated; + + s->hit = 0; + /* + * Versions before 0.9.7 always allow clients to resume sessions in + * renegotiation. 0.9.7 and later allow this by default, but optionally + * ignore resumption requests with flag + * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION (it's a new flag + * rather than a change to default behavior so that applications + * relying on this for security won't even compile against older + * library versions). + * + * 1.0.1 and later also have a function SSL_renegotiate_abbreviated() + * to request renegotiation but not a new session (s->new_session + * remains unset): for servers, this essentially just means that the + * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION setting will be + * ignored. + */ + if ((s->new_session && (s->options & + SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION))) { + if (!ssl_get_new_session(s, 1)) + goto err; + } else { + i = ssl_get_prev_session(s, p, j, d + n); + if (i == 1) { /* previous session */ + s->hit = 1; + } else if (i == -1) + goto err; + else { + /* i == 0 */ + if (!ssl_get_new_session(s, 1)) + goto err; + } + } + + p += j; + + if (SSL_IS_DTLS(s)) { + /* cookie stuff */ + if (p + 1 - d > n) + goto truncated; + cookie_len = *(p++); + + /* + * The ClientHello may contain a cookie even if the + * HelloVerify message has not been sent--make sure that it + * does not cause an overflow. + */ + if (cookie_len > sizeof(s->d1->rcvd_cookie)) { + /* too much data */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_COOKIE_MISMATCH); + goto f_err; + } + + if (p + cookie_len - d > n) + goto truncated; + + /* verify the cookie if appropriate option is set. */ + if ((SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) && + cookie_len > 0) { + memcpy(s->d1->rcvd_cookie, p, cookie_len); + + if (s->ctx->app_verify_cookie_cb != NULL) { + if (s->ctx->app_verify_cookie_cb(s, + s->d1->rcvd_cookie, cookie_len) == 0) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_COOKIE_MISMATCH); + goto f_err; + } + /* else cookie verification succeeded */ + } else if (timingsafe_memcmp(s->d1->rcvd_cookie, s->d1->cookie, + s->d1->cookie_len) != 0) { + /* default verification */ + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_COOKIE_MISMATCH); + goto f_err; + } + + ret = 2; + } + + p += cookie_len; + } + + if (p + 2 - d > n) + goto truncated; + n2s(p, i); + if ((i == 0) && (j != 0)) { + /* we need a cipher if we are not resuming a session */ + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_NO_CIPHERS_SPECIFIED); + goto f_err; + } + if (p + i - d > n) + goto truncated; + if (i > 0) { + if ((ciphers = ssl_bytes_to_cipher_list(s, p, i)) == NULL) + goto err; + } + p += i; + + /* If it is a hit, check that the cipher is in the list */ + if ((s->hit) && (i > 0)) { + j = 0; + id = s->session->cipher->id; + + for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { + c = sk_SSL_CIPHER_value(ciphers, i); + if (c->id == id) { + j = 1; + break; + } + } + if (j == 0) { + /* + * We need to have the cipher in the cipher + * list if we are asked to reuse it + */ + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_REQUIRED_CIPHER_MISSING); + goto f_err; + } + } + + /* compression */ + if (p + 1 - d > n) + goto truncated; + i= *(p++); + if (p + i - d > n) + goto truncated; + for (j = 0; j < i; j++) { + if (p[j] == 0) + break; + } + + p += i; + if (j >= i) { + /* no compress */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_NO_COMPRESSION_SPECIFIED); + goto f_err; + } + + /* TLS extensions*/ + if (!ssl_parse_clienthello_tlsext(s, &p, d, n, &al)) { + /* 'al' set by ssl_parse_clienthello_tlsext */ + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_PARSE_TLSEXT); + goto f_err; + } + if (ssl_check_clienthello_tlsext_early(s) <= 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_CLIENTHELLO_TLSEXT); + goto err; + } + + /* + * Check if we want to use external pre-shared secret for this + * handshake for not reused session only. We need to generate + * server_random before calling tls_session_secret_cb in order to allow + * SessionTicket processing to use it in key derivation. + */ + arc4random_buf(s->s3->server_random, SSL3_RANDOM_SIZE); + + if (!s->hit && s->tls_session_secret_cb) { + SSL_CIPHER *pref_cipher = NULL; + + s->session->master_key_length = sizeof(s->session->master_key); + if (s->tls_session_secret_cb(s, s->session->master_key, + &s->session->master_key_length, ciphers, &pref_cipher, + s->tls_session_secret_cb_arg)) { + s->hit = 1; + s->session->ciphers = ciphers; + s->session->verify_result = X509_V_OK; + + ciphers = NULL; + + /* check if some cipher was preferred by call back */ + pref_cipher = pref_cipher ? pref_cipher : + ssl3_choose_cipher(s, s->session->ciphers, + SSL_get_ciphers(s)); + if (pref_cipher == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_NO_SHARED_CIPHER); + goto f_err; + } + + s->session->cipher = pref_cipher; + + if (s->cipher_list) + sk_SSL_CIPHER_free(s->cipher_list); + + if (s->cipher_list_by_id) + sk_SSL_CIPHER_free(s->cipher_list_by_id); + + s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers); + s->cipher_list_by_id = + sk_SSL_CIPHER_dup(s->session->ciphers); + } + } + + /* + * Given s->session->ciphers and SSL_get_ciphers, we must + * pick a cipher + */ + + if (!s->hit) { + if (s->session->ciphers != NULL) + sk_SSL_CIPHER_free(s->session->ciphers); + s->session->ciphers = ciphers; + if (ciphers == NULL) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_NO_CIPHERS_PASSED); + goto f_err; + } + ciphers = NULL; + c = ssl3_choose_cipher(s, s->session->ciphers, + SSL_get_ciphers(s)); + + if (c == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_NO_SHARED_CIPHER); + goto f_err; + } + s->s3->tmp.new_cipher = c; + } else { + s->s3->tmp.new_cipher = s->session->cipher; + } + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + if (!(SSL_USE_SIGALGS(s) || (alg_k & SSL_kGOST)) || + !(s->verify_mode & SSL_VERIFY_PEER)) { + if (!tls1_digest_cached_records(s)) { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + } + + /* + * We now have the following setup. + * client_random + * cipher_list - our prefered list of ciphers + * ciphers - the clients prefered list of ciphers + * compression - basically ignored right now + * ssl version is set - sslv3 + * s->session - The ssl session has been setup. + * s->hit - session reuse flag + * s->tmp.new_cipher - the new cipher to use. + */ + + /* Handles TLS extensions that we couldn't check earlier */ + if (ssl_check_clienthello_tlsext_late(s) <= 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); + goto err; + } + + if (ret < 0) + ret = 1; + if (0) { +truncated: + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_BAD_PACKET_LENGTH); +f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + } +err: + if (ciphers != NULL) + sk_SSL_CIPHER_free(ciphers); + return (ret); +} + +int +ssl3_send_server_hello(SSL *s) +{ + unsigned char *bufend; + unsigned char *p, *d; + int sl; + + if (s->state == SSL3_ST_SW_SRVR_HELLO_A) { + d = p = ssl3_handshake_msg_start(s, SSL3_MT_SERVER_HELLO); + + *(p++) = s->version >> 8; + *(p++) = s->version & 0xff; + + /* Random stuff */ + memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + + /* + * There are several cases for the session ID to send + * back in the server hello: + * + * - For session reuse from the session cache, + * we send back the old session ID. + * - If stateless session reuse (using a session ticket) + * is successful, we send back the client's "session ID" + * (which doesn't actually identify the session). + * - If it is a new session, we send back the new + * session ID. + * - However, if we want the new session to be single-use, + * we send back a 0-length session ID. + * + * s->hit is non-zero in either case of session reuse, + * so the following won't overwrite an ID that we're supposed + * to send back. + */ + if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER) + && !s->hit) + s->session->session_id_length = 0; + + sl = s->session->session_id_length; + if (sl > (int)sizeof(s->session->session_id)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, + ERR_R_INTERNAL_ERROR); + return (-1); + } + *(p++) = sl; + memcpy(p, s->session->session_id, sl); + p += sl; + + /* put the cipher */ + s2n(ssl3_cipher_get_value(s->s3->tmp.new_cipher), p); + + /* put the compression method */ + *(p++) = 0; + + bufend = (unsigned char *)s->init_buf->data + + SSL3_RT_MAX_PLAIN_LENGTH; + if ((p = ssl_add_serverhello_tlsext(s, p, bufend)) == NULL) { + SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, + ERR_R_INTERNAL_ERROR); + return (-1); + } + + ssl3_handshake_msg_finish(s, p - d); + } + + /* SSL3_ST_SW_SRVR_HELLO_B */ + return (ssl3_handshake_write(s)); +} + +int +ssl3_send_server_done(SSL *s) +{ + if (s->state == SSL3_ST_SW_SRVR_DONE_A) { + ssl3_handshake_msg_start(s, SSL3_MT_SERVER_DONE); + ssl3_handshake_msg_finish(s, 0); + + s->state = SSL3_ST_SW_SRVR_DONE_B; + } + + /* SSL3_ST_SW_SRVR_DONE_B */ + return (ssl3_handshake_write(s)); +} + +int +ssl3_send_server_key_exchange(SSL *s) +{ + unsigned char *q; + int j, num; + unsigned char md_buf[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH]; + unsigned int u; + DH *dh = NULL, *dhp; + EC_KEY *ecdh = NULL, *ecdhp; + unsigned char *encodedPoint = NULL; + int encodedlen = 0; + int curve_id = 0; + BN_CTX *bn_ctx = NULL; + + EVP_PKEY *pkey; + const EVP_MD *md = NULL; + unsigned char *p, *d; + int al, i; + unsigned long type; + int n; + CERT *cert; + BIGNUM *r[4]; + int nr[4], kn; + BUF_MEM *buf; + EVP_MD_CTX md_ctx; + + EVP_MD_CTX_init(&md_ctx); + if (s->state == SSL3_ST_SW_KEY_EXCH_A) { + type = s->s3->tmp.new_cipher->algorithm_mkey; + cert = s->cert; + + buf = s->init_buf; + + r[0] = r[1] = r[2] = r[3] = NULL; + n = 0; + if (type & SSL_kDHE) { + if (s->cert->dh_tmp_auto != 0) { + if ((dhp = ssl_get_auto_dh(s)) == NULL) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr( + SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto f_err; + } + } else + dhp = cert->dh_tmp; + + if (dhp == NULL && s->cert->dh_tmp_cb != NULL) + dhp = s->cert->dh_tmp_cb(s, 0, + SSL_C_PKEYLENGTH(s->s3->tmp.new_cipher)); + + if (dhp == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_MISSING_TMP_DH_KEY); + goto f_err; + } + + if (s->s3->tmp.dh != NULL) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if (s->cert->dh_tmp_auto != 0) { + dh = dhp; + } else if ((dh = DHparams_dup(dhp)) == NULL) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_DH_LIB); + goto err; + } + s->s3->tmp.dh = dh; + if (!DH_generate_key(dh)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_DH_LIB); + goto err; + } + r[0] = dh->p; + r[1] = dh->g; + r[2] = dh->pub_key; + } else if (type & SSL_kECDHE) { + const EC_GROUP *group; + + ecdhp = cert->ecdh_tmp; + if (s->cert->ecdh_tmp_auto != 0) { + int nid = tls1_get_shared_curve(s); + if (nid != NID_undef) + ecdhp = EC_KEY_new_by_curve_name(nid); + } else if (ecdhp == NULL && + s->cert->ecdh_tmp_cb != NULL) { + ecdhp = s->cert->ecdh_tmp_cb(s, 0, + SSL_C_PKEYLENGTH(s->s3->tmp.new_cipher)); + } + if (ecdhp == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_MISSING_TMP_ECDH_KEY); + goto f_err; + } + + if (s->s3->tmp.ecdh != NULL) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + /* Duplicate the ECDH structure. */ + if (s->cert->ecdh_tmp_auto != 0) { + ecdh = ecdhp; + } else if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_ECDH_LIB); + goto err; + } + s->s3->tmp.ecdh = ecdh; + + if ((EC_KEY_get0_public_key(ecdh) == NULL) || + (EC_KEY_get0_private_key(ecdh) == NULL) || + (s->options & SSL_OP_SINGLE_ECDH_USE)) { + if (!EC_KEY_generate_key(ecdh)) { + SSLerr( + SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_ECDH_LIB); + goto err; + } + } + + if (((group = EC_KEY_get0_group(ecdh)) == NULL) || + (EC_KEY_get0_public_key(ecdh) == NULL) || + (EC_KEY_get0_private_key(ecdh) == NULL)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_ECDH_LIB); + goto err; + } + + /* + * XXX: For now, we only support ephemeral ECDH + * keys over named (not generic) curves. For + * supported named curves, curve_id is non-zero. + */ + if ((curve_id = tls1_ec_nid2curve_id( + EC_GROUP_get_curve_name(group))) == 0) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); + goto err; + } + + /* + * Encode the public key. + * First check the size of encoding and + * allocate memory accordingly. + */ + encodedlen = EC_POINT_point2oct(group, + EC_KEY_get0_public_key(ecdh), + POINT_CONVERSION_UNCOMPRESSED, + NULL, 0, NULL); + + encodedPoint = malloc(encodedlen); + + bn_ctx = BN_CTX_new(); + if ((encodedPoint == NULL) || (bn_ctx == NULL)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + + encodedlen = EC_POINT_point2oct(group, + EC_KEY_get0_public_key(ecdh), + POINT_CONVERSION_UNCOMPRESSED, + encodedPoint, encodedlen, bn_ctx); + + if (encodedlen == 0) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_ECDH_LIB); + goto err; + } + + BN_CTX_free(bn_ctx); + bn_ctx = NULL; + + /* + * XXX: For now, we only support named (not + * generic) curves in ECDH ephemeral key exchanges. + * In this situation, we need four additional bytes + * to encode the entire ServerECDHParams + * structure. + */ + n = 4 + encodedlen; + + /* + * We'll generate the serverKeyExchange message + * explicitly so we can set these to NULLs + */ + r[0] = NULL; + r[1] = NULL; + r[2] = NULL; + r[3] = NULL; + } else + { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); + goto f_err; + } + for (i = 0; i < 4 && r[i] != NULL; i++) { + nr[i] = BN_num_bytes(r[i]); + n += 2 + nr[i]; + } + + if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)) { + if ((pkey = ssl_get_sign_pkey( + s, s->s3->tmp.new_cipher, &md)) == NULL) { + al = SSL_AD_DECODE_ERROR; + goto f_err; + } + kn = EVP_PKEY_size(pkey); + } else { + pkey = NULL; + kn = 0; + } + + if (!BUF_MEM_grow_clean(buf, ssl3_handshake_msg_hdr_len(s) + + n + kn)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_LIB_BUF); + goto err; + } + + d = p = ssl3_handshake_msg_start(s, + SSL3_MT_SERVER_KEY_EXCHANGE); + + for (i = 0; i < 4 && r[i] != NULL; i++) { + s2n(nr[i], p); + BN_bn2bin(r[i], p); + p += nr[i]; + } + + if (type & SSL_kECDHE) { + /* + * XXX: For now, we only support named (not generic) + * curves. + * In this situation, the serverKeyExchange message has: + * [1 byte CurveType], [2 byte CurveName] + * [1 byte length of encoded point], followed by + * the actual encoded point itself + */ + *p = NAMED_CURVE_TYPE; + p += 1; + *p = 0; + p += 1; + *p = curve_id; + p += 1; + *p = encodedlen; + p += 1; + memcpy((unsigned char*)p, + (unsigned char *)encodedPoint, encodedlen); + free(encodedPoint); + encodedPoint = NULL; + p += encodedlen; + } + + + /* not anonymous */ + if (pkey != NULL) { + /* + * n is the length of the params, they start at &(d[4]) + * and p points to the space at the end. + */ + if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) { + q = md_buf; + j = 0; + for (num = 2; num > 0; num--) { + if (!EVP_DigestInit_ex(&md_ctx, + (num == 2) ? s->ctx->md5 : + s->ctx->sha1, NULL)) + goto err; + EVP_DigestUpdate(&md_ctx, + s->s3->client_random, + SSL3_RANDOM_SIZE); + EVP_DigestUpdate(&md_ctx, + s->s3->server_random, + SSL3_RANDOM_SIZE); + EVP_DigestUpdate(&md_ctx, d, n); + EVP_DigestFinal_ex(&md_ctx, q, + (unsigned int *)&i); + q += i; + j += i; + } + if (RSA_sign(NID_md5_sha1, md_buf, j, + &(p[2]), &u, pkey->pkey.rsa) <= 0) { + SSLerr( + SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_LIB_RSA); + goto err; + } + s2n(u, p); + n += u + 2; + } else if (md) { + /* Send signature algorithm. */ + if (SSL_USE_SIGALGS(s)) { + if (!tls12_get_sigandhash(p, pkey, md)) { + /* Should never happen */ + al = SSL_AD_INTERNAL_ERROR; + SSLerr( + SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto f_err; + } + p += 2; + } + EVP_SignInit_ex(&md_ctx, md, NULL); + EVP_SignUpdate(&md_ctx, + s->s3->client_random, + SSL3_RANDOM_SIZE); + EVP_SignUpdate(&md_ctx, + s->s3->server_random, + SSL3_RANDOM_SIZE); + EVP_SignUpdate(&md_ctx, d, n); + if (!EVP_SignFinal(&md_ctx, &p[2], + (unsigned int *)&i, pkey)) { + SSLerr( + SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_LIB_EVP); + goto err; + } + s2n(i, p); + n += i + 2; + if (SSL_USE_SIGALGS(s)) + n += 2; + } else { + /* Is this error check actually needed? */ + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_UNKNOWN_PKEY_TYPE); + goto f_err; + } + } + + ssl3_handshake_msg_finish(s, n); + } + + s->state = SSL3_ST_SW_KEY_EXCH_B; + EVP_MD_CTX_cleanup(&md_ctx); + + return (ssl3_handshake_write(s)); + +f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); +err: + free(encodedPoint); + BN_CTX_free(bn_ctx); + EVP_MD_CTX_cleanup(&md_ctx); + return (-1); +} + +int +ssl3_send_certificate_request(SSL *s) +{ + unsigned char *p, *d; + int i, j, nl, off, n; + STACK_OF(X509_NAME) *sk = NULL; + X509_NAME *name; + BUF_MEM *buf; + + if (s->state == SSL3_ST_SW_CERT_REQ_A) { + buf = s->init_buf; + + d = p = ssl3_handshake_msg_start(s, + SSL3_MT_CERTIFICATE_REQUEST); + + /* get the list of acceptable cert types */ + p++; + n = ssl3_get_req_cert_type(s, p); + d[0] = n; + p += n; + n++; + + if (SSL_USE_SIGALGS(s)) { + nl = tls12_get_req_sig_algs(s, p + 2); + s2n(nl, p); + p += nl + 2; + n += nl + 2; + } + + off = n; + p += 2; + n += 2; + + sk = SSL_get_client_CA_list(s); + nl = 0; + if (sk != NULL) { + for (i = 0; i < sk_X509_NAME_num(sk); i++) { + name = sk_X509_NAME_value(sk, i); + j = i2d_X509_NAME(name, NULL); + if (!BUF_MEM_grow_clean(buf, + ssl3_handshake_msg_hdr_len(s) + n + j + + 2)) { + SSLerr( + SSL_F_SSL3_SEND_CERTIFICATE_REQUEST, + ERR_R_BUF_LIB); + goto err; + } + p = ssl3_handshake_msg_start(s, + SSL3_MT_CERTIFICATE_REQUEST) + n; + s2n(j, p); + i2d_X509_NAME(name, &p); + n += 2 + j; + nl += 2 + j; + } + } + /* else no CA names */ + p = ssl3_handshake_msg_start(s, + SSL3_MT_CERTIFICATE_REQUEST) + off; + s2n(nl, p); + + ssl3_handshake_msg_finish(s, n); + + s->state = SSL3_ST_SW_CERT_REQ_B; + } + + /* SSL3_ST_SW_CERT_REQ_B */ + return (ssl3_handshake_write(s)); +err: + return (-1); +} + +int +ssl3_get_client_key_exchange(SSL *s) +{ + int i, al, ok; + long n; + unsigned long alg_k; + unsigned char *d, *p; + RSA *rsa = NULL; + EVP_PKEY *pkey = NULL; + BIGNUM *pub = NULL; + DH *dh_srvr; + + EC_KEY *srvr_ecdh = NULL; + EVP_PKEY *clnt_pub_pkey = NULL; + EC_POINT *clnt_ecpoint = NULL; + BN_CTX *bn_ctx = NULL; + + /* 2048 maxlen is a guess. How long a key does that permit? */ + n = s->method->ssl_get_message(s, SSL3_ST_SR_KEY_EXCH_A, + SSL3_ST_SR_KEY_EXCH_B, SSL3_MT_CLIENT_KEY_EXCHANGE, 2048, &ok); + if (!ok) + return ((int)n); + d = p = (unsigned char *)s->init_msg; + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + + if (alg_k & SSL_kRSA) { + char fakekey[SSL_MAX_MASTER_KEY_LENGTH]; + + arc4random_buf(fakekey, sizeof(fakekey)); + fakekey[0] = s->client_version >> 8; + fakekey[1] = s->client_version & 0xff; + + pkey = s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey; + if ((pkey == NULL) || (pkey->type != EVP_PKEY_RSA) || + (pkey->pkey.rsa == NULL)) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_MISSING_RSA_CERTIFICATE); + goto f_err; + } + rsa = pkey->pkey.rsa; + + if (2 > n) + goto truncated; + n2s(p, i); + if (n != i + 2) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); + goto err; + } else + n = i; + + i = RSA_private_decrypt((int)n, p, p, rsa, RSA_PKCS1_PADDING); + + ERR_clear_error(); + + al = -1; + + if (i != SSL_MAX_MASTER_KEY_LENGTH) { + al = SSL_AD_DECODE_ERROR; + /* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT); */ + } + + if (p + 2 - d > n) /* needed in the SSL3 case */ + goto truncated; + if ((al == -1) && !((p[0] == (s->client_version >> 8)) && + (p[1] == (s->client_version & 0xff)))) { + /* + * The premaster secret must contain the same version + * number as the ClientHello to detect version rollback + * attacks (strangely, the protocol does not offer such + * protection for DH ciphersuites). + * However, buggy clients exist that send the negotiated + * protocol version instead if the server does not + * support the requested protocol version. + * If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such + * clients. + */ + if (!((s->options & SSL_OP_TLS_ROLLBACK_BUG) && + (p[0] == (s->version >> 8)) && + (p[1] == (s->version & 0xff)))) { + al = SSL_AD_DECODE_ERROR; + /* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_PROTOCOL_VERSION_NUMBER); */ + + /* + * The Klima-Pokorny-Rosa extension of + * Bleichenbacher's attack + * (http://eprint.iacr.org/2003/052/) exploits + * the version number check as a "bad version + * oracle" -- an alert would reveal that the + * plaintext corresponding to some ciphertext + * made up by the adversary is properly + * formatted except that the version number is + * wrong. + * To avoid such attacks, we should treat this + * just like any other decryption error. + */ + } + } + + if (al != -1) { + /* + * Some decryption failure -- use random value instead + * as countermeasure against Bleichenbacher's attack + * on PKCS #1 v1.5 RSA padding (see RFC 2246, + * section 7.4.7.1). + */ + i = SSL_MAX_MASTER_KEY_LENGTH; + p = fakekey; + } + + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s->session->master_key, + p, i); + explicit_bzero(p, i); + } else if (alg_k & SSL_kDHE) { + if (2 > n) + goto truncated; + n2s(p, i); + if (n != i + 2) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); + goto err; + } + + if (n == 0L) { + /* the parameters are in the cert */ + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_UNABLE_TO_DECODE_DH_CERTS); + goto f_err; + } else { + if (s->s3->tmp.dh == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_MISSING_TMP_DH_KEY); + goto f_err; + } else + dh_srvr = s->s3->tmp.dh; + } + + pub = BN_bin2bn(p, i, NULL); + if (pub == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_BN_LIB); + goto err; + } + + i = DH_compute_key(p, pub, dh_srvr); + + if (i <= 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_DH_LIB); + BN_clear_free(pub); + goto err; + } + + DH_free(s->s3->tmp.dh); + s->s3->tmp.dh = NULL; + + BN_clear_free(pub); + pub = NULL; + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret( + s, s->session->master_key, p, i); + explicit_bzero(p, i); + } else + + if (alg_k & (SSL_kECDHE|SSL_kECDHr|SSL_kECDHe)) { + int ret = 1; + int key_size; + const EC_KEY *tkey; + const EC_GROUP *group; + const BIGNUM *priv_key; + + /* Initialize structures for server's ECDH key pair. */ + if ((srvr_ecdh = EC_KEY_new()) == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Let's get server private key and group information. */ + if (alg_k & (SSL_kECDHr|SSL_kECDHe)) { + /* Use the certificate */ + tkey = s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec; + } else { + /* + * Use the ephermeral values we saved when + * generating the ServerKeyExchange msg. + */ + tkey = s->s3->tmp.ecdh; + } + + group = EC_KEY_get0_group(tkey); + priv_key = EC_KEY_get0_private_key(tkey); + + if (!EC_KEY_set_group(srvr_ecdh, group) || + !EC_KEY_set_private_key(srvr_ecdh, priv_key)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_EC_LIB); + goto err; + } + + /* Let's get client's public key */ + if ((clnt_ecpoint = EC_POINT_new(group)) == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if (n == 0L) { + /* Client Publickey was in Client Certificate */ + + if (alg_k & SSL_kECDHE) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_MISSING_TMP_ECDH_KEY); + goto f_err; + } + if (((clnt_pub_pkey = X509_get_pubkey( + s->session->peer)) == NULL) || + (clnt_pub_pkey->type != EVP_PKEY_EC)) { + /* + * XXX: For now, we do not support client + * authentication using ECDH certificates + * so this branch (n == 0L) of the code is + * never executed. When that support is + * added, we ought to ensure the key + * received in the certificate is + * authorized for key agreement. + * ECDH_compute_key implicitly checks that + * the two ECDH shares are for the same + * group. + */ + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_UNABLE_TO_DECODE_ECDH_CERTS); + goto f_err; + } + + if (EC_POINT_copy(clnt_ecpoint, + EC_KEY_get0_public_key(clnt_pub_pkey->pkey.ec)) + == 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_EC_LIB); + goto err; + } + ret = 2; /* Skip certificate verify processing */ + } else { + /* + * Get client's public key from encoded point + * in the ClientKeyExchange message. + */ + if ((bn_ctx = BN_CTX_new()) == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Get encoded point length */ + i = *p; + + p += 1; + if (n != 1 + i) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_EC_LIB); + goto err; + } + if (EC_POINT_oct2point(group, + clnt_ecpoint, p, i, bn_ctx) == 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_EC_LIB); + goto err; + } + /* + * p is pointing to somewhere in the buffer + * currently, so set it to the start. + */ + p = (unsigned char *)s->init_buf->data; + } + + /* Compute the shared pre-master secret */ + key_size = ECDH_size(srvr_ecdh); + if (key_size <= 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_ECDH_LIB); + goto err; + } + i = ECDH_compute_key(p, key_size, clnt_ecpoint, srvr_ecdh, + NULL); + if (i <= 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_ECDH_LIB); + goto err; + } + + EVP_PKEY_free(clnt_pub_pkey); + EC_POINT_free(clnt_ecpoint); + EC_KEY_free(srvr_ecdh); + BN_CTX_free(bn_ctx); + EC_KEY_free(s->s3->tmp.ecdh); + s->s3->tmp.ecdh = NULL; + + + /* Compute the master secret */ + s->session->master_key_length = s->method->ssl3_enc-> \ + generate_master_secret(s, s->session->master_key, p, i); + + explicit_bzero(p, i); + return (ret); + } else + if (alg_k & SSL_kGOST) { + int ret = 0; + EVP_PKEY_CTX *pkey_ctx; + EVP_PKEY *client_pub_pkey = NULL, *pk = NULL; + unsigned char premaster_secret[32], *start; + size_t outlen = 32, inlen; + unsigned long alg_a; + int Ttag, Tclass; + long Tlen; + + /* Get our certificate private key*/ + alg_a = s->s3->tmp.new_cipher->algorithm_auth; + if (alg_a & SSL_aGOST01) + pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey; + + pkey_ctx = EVP_PKEY_CTX_new(pk, NULL); + EVP_PKEY_decrypt_init(pkey_ctx); + /* + * If client certificate is present and is of the same type, + * maybe use it for key exchange. + * Don't mind errors from EVP_PKEY_derive_set_peer, because + * it is completely valid to use a client certificate for + * authorization only. + */ + client_pub_pkey = X509_get_pubkey(s->session->peer); + if (client_pub_pkey) { + if (EVP_PKEY_derive_set_peer(pkey_ctx, + client_pub_pkey) <= 0) + ERR_clear_error(); + } + if (2 > n) + goto truncated; + /* Decrypt session key */ + if (ASN1_get_object((const unsigned char **)&p, &Tlen, &Ttag, + &Tclass, n) != V_ASN1_CONSTRUCTED || + Ttag != V_ASN1_SEQUENCE || Tclass != V_ASN1_UNIVERSAL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DECRYPTION_FAILED); + goto gerr; + } + start = p; + inlen = Tlen; + if (EVP_PKEY_decrypt(pkey_ctx, premaster_secret, &outlen, + start, inlen) <=0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DECRYPTION_FAILED); + goto gerr; + } + /* Generate master secret */ + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret( + s, s->session->master_key, premaster_secret, 32); + /* Check if pubkey from client certificate was used */ + if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, + EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) + ret = 2; + else + ret = 1; +gerr: + EVP_PKEY_free(client_pub_pkey); + EVP_PKEY_CTX_free(pkey_ctx); + if (ret) + return (ret); + else + goto err; + } else { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_UNKNOWN_CIPHER_TYPE); + goto f_err; + } + + return (1); +truncated: + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_BAD_PACKET_LENGTH); +f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); +err: + EVP_PKEY_free(clnt_pub_pkey); + EC_POINT_free(clnt_ecpoint); + EC_KEY_free(srvr_ecdh); + BN_CTX_free(bn_ctx); + return (-1); +} + +int +ssl3_get_cert_verify(SSL *s) +{ + EVP_PKEY *pkey = NULL; + unsigned char *p; + int al, ok, ret = 0; + long n; + int type = 0, i, j; + X509 *peer; + const EVP_MD *md = NULL; + EVP_MD_CTX mctx; + EVP_MD_CTX_init(&mctx); + + n = s->method->ssl_get_message(s, SSL3_ST_SR_CERT_VRFY_A, + SSL3_ST_SR_CERT_VRFY_B, -1, SSL3_RT_MAX_PLAIN_LENGTH, &ok); + if (!ok) + return ((int)n); + + if (s->session->peer != NULL) { + peer = s->session->peer; + pkey = X509_get_pubkey(peer); + type = X509_certificate_type(peer, pkey); + } else { + peer = NULL; + pkey = NULL; + } + + if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY) { + s->s3->tmp.reuse_message = 1; + if (peer != NULL) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + SSL_R_MISSING_VERIFY_MESSAGE); + goto f_err; + } + ret = 1; + goto end; + } + + if (peer == NULL) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + SSL_R_NO_CLIENT_CERT_RECEIVED); + al = SSL_AD_UNEXPECTED_MESSAGE; + goto f_err; + } + + if (!(type & EVP_PKT_SIGN)) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE); + al = SSL_AD_ILLEGAL_PARAMETER; + goto f_err; + } + + if (s->s3->change_cipher_spec) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + SSL_R_CCS_RECEIVED_EARLY); + al = SSL_AD_UNEXPECTED_MESSAGE; + goto f_err; + } + + /* we now have a signature that we need to verify */ + p = (unsigned char *)s->init_msg; + /* + * Check for broken implementations of GOST ciphersuites. + * + * If key is GOST and n is exactly 64, it is a bare + * signature without length field. + */ + if (n == 64 && (pkey->type == NID_id_GostR3410_94 || + pkey->type == NID_id_GostR3410_2001) ) { + i = 64; + } else { + if (SSL_USE_SIGALGS(s)) { + int sigalg = tls12_get_sigid(pkey); + /* Should never happen */ + if (sigalg == -1) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + ERR_R_INTERNAL_ERROR); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + if (2 > n) + goto truncated; + /* Check key type is consistent with signature */ + if (sigalg != (int)p[1]) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + SSL_R_WRONG_SIGNATURE_TYPE); + al = SSL_AD_DECODE_ERROR; + goto f_err; + } + md = tls12_get_hash(p[0]); + if (md == NULL) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + SSL_R_UNKNOWN_DIGEST); + al = SSL_AD_DECODE_ERROR; + goto f_err; + } + p += 2; + n -= 2; + } + if (2 > n) + goto truncated; + n2s(p, i); + n -= 2; + if (i > n) + goto truncated; + } + j = EVP_PKEY_size(pkey); + if ((i > j) || (n > j) || (n <= 0)) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + SSL_R_WRONG_SIGNATURE_SIZE); + al = SSL_AD_DECODE_ERROR; + goto f_err; + } + + if (SSL_USE_SIGALGS(s)) { + long hdatalen = 0; + void *hdata; + hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); + if (hdatalen <= 0) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + ERR_R_INTERNAL_ERROR); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + if (!EVP_VerifyInit_ex(&mctx, md, NULL) || + !EVP_VerifyUpdate(&mctx, hdata, hdatalen)) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + ERR_R_EVP_LIB); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + + if (EVP_VerifyFinal(&mctx, p, i, pkey) <= 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + SSL_R_BAD_SIGNATURE); + goto f_err; + } + } else + if (pkey->type == EVP_PKEY_RSA) { + i = RSA_verify(NID_md5_sha1, s->s3->tmp.cert_verify_md, + MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, p, i, + pkey->pkey.rsa); + if (i < 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + SSL_R_BAD_RSA_DECRYPT); + goto f_err; + } + if (i == 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + SSL_R_BAD_RSA_SIGNATURE); + goto f_err; + } + } else + if (pkey->type == EVP_PKEY_DSA) { + j = DSA_verify(pkey->save_type, + &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]), + SHA_DIGEST_LENGTH, p, i, pkey->pkey.dsa); + if (j <= 0) { + /* bad signature */ + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + SSL_R_BAD_DSA_SIGNATURE); + goto f_err; + } + } else + if (pkey->type == EVP_PKEY_EC) { + j = ECDSA_verify(pkey->save_type, + &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]), + SHA_DIGEST_LENGTH, p, i, pkey->pkey.ec); + if (j <= 0) { + /* bad signature */ + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + SSL_R_BAD_ECDSA_SIGNATURE); + goto f_err; + } + } else +#ifndef OPENSSL_NO_GOST + if (pkey->type == NID_id_GostR3410_94 || + pkey->type == NID_id_GostR3410_2001) { + long hdatalen = 0; + void *hdata; + unsigned char signature[128]; + unsigned int siglen = sizeof(signature); + int nid; + EVP_PKEY_CTX *pctx; + + hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); + if (hdatalen <= 0) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + ERR_R_INTERNAL_ERROR); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + if (!EVP_PKEY_get_default_digest_nid(pkey, &nid) || + !(md = EVP_get_digestbynid(nid))) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + ERR_R_EVP_LIB); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + pctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pctx) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + ERR_R_EVP_LIB); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + if (!EVP_DigestInit_ex(&mctx, md, NULL) || + !EVP_DigestUpdate(&mctx, hdata, hdatalen) || + !EVP_DigestFinal(&mctx, signature, &siglen) || + (EVP_PKEY_verify_init(pctx) <= 0) || + (EVP_PKEY_CTX_set_signature_md(pctx, md) <= 0) || + (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_VERIFY, + EVP_PKEY_CTRL_GOST_SIG_FORMAT, + GOST_SIG_FORMAT_RS_LE, + NULL) <= 0)) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + ERR_R_EVP_LIB); + al = SSL_AD_INTERNAL_ERROR; + EVP_PKEY_CTX_free(pctx); + goto f_err; + } + + if (EVP_PKEY_verify(pctx, p, i, signature, siglen) <= 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + SSL_R_BAD_SIGNATURE); + EVP_PKEY_CTX_free(pctx); + goto f_err; + } + + EVP_PKEY_CTX_free(pctx); + } else +#endif + { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + ERR_R_INTERNAL_ERROR); + al = SSL_AD_UNSUPPORTED_CERTIFICATE; + goto f_err; + } + + + ret = 1; + if (0) { +truncated: + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_PACKET_LENGTH); +f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + } +end: + if (s->s3->handshake_buffer) { + BIO_free(s->s3->handshake_buffer); + s->s3->handshake_buffer = NULL; + s->s3->flags &= ~TLS1_FLAGS_KEEP_HANDSHAKE; + } + EVP_MD_CTX_cleanup(&mctx); + EVP_PKEY_free(pkey); + return (ret); +} + +int +ssl3_get_client_certificate(SSL *s) +{ + CBS cbs, client_certs; + int i, ok, al, ret = -1; + X509 *x = NULL; + long n; + const unsigned char *q; + STACK_OF(X509) *sk = NULL; + + n = s->method->ssl_get_message(s, SSL3_ST_SR_CERT_A, SSL3_ST_SR_CERT_B, + -1, s->max_cert_list, &ok); + + if (!ok) + return ((int)n); + + if (s->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) { + if ((s->verify_mode & SSL_VERIFY_PEER) && + (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + al = SSL_AD_HANDSHAKE_FAILURE; + goto f_err; + } + /* + * If tls asked for a client cert, + * the client must return a 0 list. + */ + if (s->s3->tmp.cert_request) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST + ); + al = SSL_AD_UNEXPECTED_MESSAGE; + goto f_err; + } + s->s3->tmp.reuse_message = 1; + return (1); + } + + if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_WRONG_MESSAGE_TYPE); + goto f_err; + } + + if (n < 0) + goto truncated; + + CBS_init(&cbs, s->init_msg, n); + + if ((sk = sk_X509_new_null()) == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!CBS_get_u24_length_prefixed(&cbs, &client_certs) || + CBS_len(&cbs) != 0) + goto truncated; + + while (CBS_len(&client_certs) > 0) { + CBS cert; + + if (!CBS_get_u24_length_prefixed(&client_certs, &cert)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_CERT_LENGTH_MISMATCH); + goto f_err; + } + + q = CBS_data(&cert); + x = d2i_X509(NULL, &q, CBS_len(&cert)); + if (x == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + ERR_R_ASN1_LIB); + goto err; + } + if (q != CBS_data(&cert) + CBS_len(&cert)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_CERT_LENGTH_MISMATCH); + goto f_err; + } + if (!sk_X509_push(sk, x)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + ERR_R_MALLOC_FAILURE); + goto err; + } + x = NULL; + } + + if (sk_X509_num(sk) <= 0) { + /* + * TLS does not mind 0 certs returned. + * Fail for TLS only if we required a certificate. + */ + if ((s->verify_mode & SSL_VERIFY_PEER) && + (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + al = SSL_AD_HANDSHAKE_FAILURE; + goto f_err; + } + /* No client certificate so digest cached records */ + if (s->s3->handshake_buffer && !tls1_digest_cached_records(s)) { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + } else { + i = ssl_verify_cert_chain(s, sk); + if (i <= 0) { + al = ssl_verify_alarm_type(s->verify_result); + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_NO_CERTIFICATE_RETURNED); + goto f_err; + } + } + + X509_free(s->session->peer); + s->session->peer = sk_X509_shift(sk); + s->session->verify_result = s->verify_result; + + /* + * With the current implementation, sess_cert will always be NULL + * when we arrive here + */ + if (s->session->sess_cert == NULL) { + s->session->sess_cert = ssl_sess_cert_new(); + if (s->session->sess_cert == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + ERR_R_MALLOC_FAILURE); + goto err; + } + } + if (s->session->sess_cert->cert_chain != NULL) + sk_X509_pop_free(s->session->sess_cert->cert_chain, X509_free); + s->session->sess_cert->cert_chain = sk; + + /* + * Inconsistency alert: cert_chain does *not* include the + * peer's own certificate, while we do include it in s3_clnt.c + */ + + sk = NULL; + + ret = 1; + if (0) { +truncated: + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_BAD_PACKET_LENGTH); +f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + } +err: + X509_free(x); + if (sk != NULL) + sk_X509_pop_free(sk, X509_free); + return (ret); +} + +int +ssl3_send_server_certificate(SSL *s) +{ + unsigned long l; + X509 *x; + + if (s->state == SSL3_ST_SW_CERT_A) { + x = ssl_get_server_send_cert(s); + if (x == NULL) { + SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, + ERR_R_INTERNAL_ERROR); + return (0); + } + + l = ssl3_output_cert_chain(s, x); + s->state = SSL3_ST_SW_CERT_B; + s->init_num = (int)l; + s->init_off = 0; + } + + /* SSL3_ST_SW_CERT_B */ + return (ssl3_handshake_write(s)); +} + +/* send a new session ticket (not necessarily for a new session) */ +int +ssl3_send_newsession_ticket(SSL *s) +{ + if (s->state == SSL3_ST_SW_SESSION_TICKET_A) { + unsigned char *d, *p, *senc, *macstart; + const unsigned char *const_p; + int len, slen_full, slen; + SSL_SESSION *sess; + unsigned int hlen; + EVP_CIPHER_CTX ctx; + HMAC_CTX hctx; + SSL_CTX *tctx = s->initial_ctx; + unsigned char iv[EVP_MAX_IV_LENGTH]; + unsigned char key_name[16]; + + /* get session encoding length */ + slen_full = i2d_SSL_SESSION(s->session, NULL); + /* + * Some length values are 16 bits, so forget it if session is + * too long + */ + if (slen_full > 0xFF00) + return (-1); + senc = malloc(slen_full); + if (!senc) + return (-1); + p = senc; + i2d_SSL_SESSION(s->session, &p); + + /* + * Create a fresh copy (not shared with other threads) to + * clean up + */ + const_p = senc; + sess = d2i_SSL_SESSION(NULL, &const_p, slen_full); + if (sess == NULL) { + free(senc); + return (-1); + } + + /* ID is irrelevant for the ticket */ + sess->session_id_length = 0; + + slen = i2d_SSL_SESSION(sess, NULL); + if (slen > slen_full) { + /* shouldn't ever happen */ + free(senc); + return (-1); + } + p = senc; + i2d_SSL_SESSION(sess, &p); + SSL_SESSION_free(sess); + + /* + * Grow buffer if need be: the length calculation is as + * follows 1 (size of message name) + 3 (message length + * bytes) + 4 (ticket lifetime hint) + 2 (ticket length) + + * 16 (key name) + max_iv_len (iv length) + + * session_length + max_enc_block_size (max encrypted session + * length) + max_md_size (HMAC). + */ + if (!BUF_MEM_grow(s->init_buf, ssl3_handshake_msg_hdr_len(s) + + 22 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH + + EVP_MAX_MD_SIZE + slen)) { + free(senc); + return (-1); + } + + d = p = ssl3_handshake_msg_start(s, SSL3_MT_NEWSESSION_TICKET); + + EVP_CIPHER_CTX_init(&ctx); + HMAC_CTX_init(&hctx); + + /* + * Initialize HMAC and cipher contexts. If callback present + * it does all the work otherwise use generated values + * from parent ctx. + */ + if (tctx->tlsext_ticket_key_cb) { + if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, + &hctx, 1) < 0) { + free(senc); + EVP_CIPHER_CTX_cleanup(&ctx); + return (-1); + } + } else { + arc4random_buf(iv, 16); + EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, + tctx->tlsext_tick_aes_key, iv); + HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, + tlsext_tick_md(), NULL); + memcpy(key_name, tctx->tlsext_tick_key_name, 16); + } + + /* + * Ticket lifetime hint (advisory only): + * We leave this unspecified for resumed session + * (for simplicity), and guess that tickets for new + * sessions will live as long as their sessions. + */ + l2n(s->hit ? 0 : s->session->timeout, p); + + /* Skip ticket length for now */ + p += 2; + /* Output key name */ + macstart = p; + memcpy(p, key_name, 16); + p += 16; + /* output IV */ + memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx)); + p += EVP_CIPHER_CTX_iv_length(&ctx); + /* Encrypt session data */ + EVP_EncryptUpdate(&ctx, p, &len, senc, slen); + p += len; + EVP_EncryptFinal_ex(&ctx, p, &len); + p += len; + EVP_CIPHER_CTX_cleanup(&ctx); + + HMAC_Update(&hctx, macstart, p - macstart); + HMAC_Final(&hctx, p, &hlen); + HMAC_CTX_cleanup(&hctx); + p += hlen; + + /* Now write out lengths: p points to end of data written */ + /* Total length */ + len = p - d; + + /* Skip ticket lifetime hint. */ + p = d + 4; + s2n(len - 6, p); /* Message length */ + + ssl3_handshake_msg_finish(s, len); + + s->state = SSL3_ST_SW_SESSION_TICKET_B; + + free(senc); + } + + /* SSL3_ST_SW_SESSION_TICKET_B */ + return (ssl3_handshake_write(s)); +} + +int +ssl3_send_cert_status(SSL *s) +{ + unsigned char *p; + + if (s->state == SSL3_ST_SW_CERT_STATUS_A) { + /* + * Grow buffer if need be: the length calculation is as + * follows 1 (message type) + 3 (message length) + + * 1 (ocsp response type) + 3 (ocsp response length) + * + (ocsp response) + */ + if (!BUF_MEM_grow(s->init_buf, SSL3_HM_HEADER_LENGTH + 4 + + s->tlsext_ocsp_resplen)) + return (-1); + + p = ssl3_handshake_msg_start(s, SSL3_MT_CERTIFICATE_STATUS); + + *(p++) = s->tlsext_status_type; + l2n3(s->tlsext_ocsp_resplen, p); + memcpy(p, s->tlsext_ocsp_resp, s->tlsext_ocsp_resplen); + + ssl3_handshake_msg_finish(s, s->tlsext_ocsp_resplen + 4); + + s->state = SSL3_ST_SW_CERT_STATUS_B; + } + + /* SSL3_ST_SW_CERT_STATUS_B */ + return (ssl3_handshake_write(s)); +} + +/* + * ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. + * It sets the next_proto member in s if found + */ +int +ssl3_get_next_proto(SSL *s) +{ + CBS cbs, proto, padding; + int ok; + long n; + size_t len; + + /* + * Clients cannot send a NextProtocol message if we didn't see the + * extension in their ClientHello + */ + if (!s->s3->next_proto_neg_seen) { + SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, + SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION); + return (-1); + } + + /* 514 maxlen is enough for the payload format below */ + n = s->method->ssl_get_message(s, SSL3_ST_SR_NEXT_PROTO_A, + SSL3_ST_SR_NEXT_PROTO_B, SSL3_MT_NEXT_PROTO, 514, &ok); + if (!ok) + return ((int)n); + + /* + * s->state doesn't reflect whether ChangeCipherSpec has been received + * in this handshake, but s->s3->change_cipher_spec does (will be reset + * by ssl3_get_finished). + */ + if (!s->s3->change_cipher_spec) { + SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, + SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS); + return (-1); + } + + if (n < 2) + return (0); + /* The body must be > 1 bytes long */ + + CBS_init(&cbs, s->init_msg, s->init_num); + + /* + * The payload looks like: + * uint8 proto_len; + * uint8 proto[proto_len]; + * uint8 padding_len; + * uint8 padding[padding_len]; + */ + if (!CBS_get_u8_length_prefixed(&cbs, &proto) || + !CBS_get_u8_length_prefixed(&cbs, &padding) || + CBS_len(&cbs) != 0) + return 0; + + /* + * XXX We should not NULL it, but this matches old behavior of not + * freeing before malloc. + */ + s->next_proto_negotiated = NULL; + s->next_proto_negotiated_len = 0; + + if (!CBS_stow(&proto, &s->next_proto_negotiated, &len)) { + SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, + ERR_R_MALLOC_FAILURE); + return (0); + } + s->next_proto_negotiated_len = (uint8_t)len; + + return (1); +} diff --git a/crypto/libressl/ssl/srtp.h b/crypto/libressl/ssl/srtp.h new file mode 100644 index 0000000000..5b6f0868ad --- /dev/null +++ b/crypto/libressl/ssl/srtp.h @@ -0,0 +1,142 @@ +/* $OpenBSD: srtp.h,v 1.5 2014/12/14 15:30:50 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* + * DTLS code by Eric Rescorla + * + * Copyright (C) 2006, Network Resonance, Inc. + * Copyright (C) 2011, RTFM, Inc. + */ + +#ifndef HEADER_D1_SRTP_H +#define HEADER_D1_SRTP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define SRTP_AES128_CM_SHA1_80 0x0001 +#define SRTP_AES128_CM_SHA1_32 0x0002 +#define SRTP_AES128_F8_SHA1_80 0x0003 +#define SRTP_AES128_F8_SHA1_32 0x0004 +#define SRTP_NULL_SHA1_80 0x0005 +#define SRTP_NULL_SHA1_32 0x0006 + +int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles); +int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles); + +STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl); +SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/libressl/ssl/ssl_algs.c b/crypto/libressl/ssl/ssl_algs.c new file mode 100644 index 0000000000..3b72d3493a --- /dev/null +++ b/crypto/libressl/ssl/ssl_algs.c @@ -0,0 +1,131 @@ +/* $OpenBSD: ssl_algs.c,v 1.21 2014/11/18 05:33:43 miod Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include + +#include "ssl_locl.h" + +int +SSL_library_init(void) +{ + +#ifndef OPENSSL_NO_DES + EVP_add_cipher(EVP_des_cbc()); + EVP_add_cipher(EVP_des_ede3_cbc()); +#endif +#ifndef OPENSSL_NO_IDEA + EVP_add_cipher(EVP_idea_cbc()); +#endif +#ifndef OPENSSL_NO_RC4 + EVP_add_cipher(EVP_rc4()); +#if !defined(OPENSSL_NO_MD5) && (defined(__x86_64) || defined(__x86_64__)) + EVP_add_cipher(EVP_rc4_hmac_md5()); +#endif +#endif +#ifndef OPENSSL_NO_RC2 + EVP_add_cipher(EVP_rc2_cbc()); + /* Not actually used for SSL/TLS but this makes PKCS#12 work + * if an application only calls SSL_library_init(). + */ + EVP_add_cipher(EVP_rc2_40_cbc()); +#endif + EVP_add_cipher(EVP_aes_128_cbc()); + EVP_add_cipher(EVP_aes_192_cbc()); + EVP_add_cipher(EVP_aes_256_cbc()); + EVP_add_cipher(EVP_aes_128_gcm()); + EVP_add_cipher(EVP_aes_256_gcm()); + EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1()); + EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1()); +#ifndef OPENSSL_NO_CAMELLIA + EVP_add_cipher(EVP_camellia_128_cbc()); + EVP_add_cipher(EVP_camellia_256_cbc()); +#endif +#ifndef OPENSSL_NO_GOST + EVP_add_cipher(EVP_gost2814789_cfb64()); + EVP_add_cipher(EVP_gost2814789_cnt()); +#endif + + EVP_add_digest(EVP_md5()); + EVP_add_digest_alias(SN_md5, "ssl2-md5"); + EVP_add_digest_alias(SN_md5, "ssl3-md5"); + EVP_add_digest(EVP_sha1()); /* RSA with sha1 */ + EVP_add_digest_alias(SN_sha1, "ssl3-sha1"); + EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA); + EVP_add_digest(EVP_sha224()); + EVP_add_digest(EVP_sha256()); + EVP_add_digest(EVP_sha384()); + EVP_add_digest(EVP_sha512()); + EVP_add_digest(EVP_dss1()); /* DSA with sha1 */ + EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2); + EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1"); + EVP_add_digest_alias(SN_dsaWithSHA1, "dss1"); + EVP_add_digest(EVP_ecdsa()); +#ifndef OPENSSL_NO_GOST + EVP_add_digest(EVP_gostr341194()); + EVP_add_digest(EVP_gost2814789imit()); + EVP_add_digest(EVP_streebog256()); + EVP_add_digest(EVP_streebog512()); +#endif + /* initialize cipher/digest methods table */ + ssl_load_ciphers(); + return (1); +} + diff --git a/crypto/libressl/ssl/ssl_asn1.c b/crypto/libressl/ssl/ssl_asn1.c new file mode 100644 index 0000000000..a3fc1a9f73 --- /dev/null +++ b/crypto/libressl/ssl/ssl_asn1.c @@ -0,0 +1,691 @@ +/* $OpenBSD: ssl_asn1.c,v 1.40 2014/12/14 15:30:50 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include "ssl_locl.h" + +#include +#include + +/* XXX - these are here to avoid including asn1_mac.h */ +int asn1_GetSequence(ASN1_const_CTX *c, long *length); +void asn1_add_error(const unsigned char *address, int offset); + +typedef struct ssl_session_asn1_st { + ASN1_INTEGER version; + ASN1_INTEGER ssl_version; + ASN1_OCTET_STRING cipher; + ASN1_OCTET_STRING master_key; + ASN1_OCTET_STRING session_id; + ASN1_OCTET_STRING session_id_context; + ASN1_INTEGER time; + ASN1_INTEGER timeout; + ASN1_INTEGER verify_result; + ASN1_OCTET_STRING tlsext_hostname; + ASN1_INTEGER tlsext_tick_lifetime; + ASN1_OCTET_STRING tlsext_tick; +} SSL_SESSION_ASN1; + +int +i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) +{ +#define LSIZE2 (sizeof(long)*2) + int v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0, v9 = 0, v10 = 0; + unsigned char buf[4], ibuf1[LSIZE2], ibuf2[LSIZE2]; + unsigned char ibuf3[LSIZE2], ibuf4[LSIZE2], ibuf5[LSIZE2]; + unsigned char ibuf6[LSIZE2]; + SSL_SESSION_ASN1 a; + unsigned char *p; + int len = 0, ret; + long l; + + if ((in == NULL) || ((in->cipher == NULL) && (in->cipher_id == 0))) + return (0); + + /* + * Note that I cheat in the following 2 assignments. + * I know that if the ASN1_INTEGER passed to ASN1_INTEGER_set + * is > sizeof(long)+1, the buffer will not be re-malloc()ed. + * This is a bit evil but makes things simple, no dynamic allocation + * to clean up :-) + */ + a.version.length = LSIZE2; + a.version.type = V_ASN1_INTEGER; + a.version.data = ibuf1; + ASN1_INTEGER_set(&(a.version), SSL_SESSION_ASN1_VERSION); + len += i2d_ASN1_INTEGER(&(a.version), NULL); + + a.ssl_version.length = LSIZE2; + a.ssl_version.type = V_ASN1_INTEGER; + a.ssl_version.data = ibuf2; + ASN1_INTEGER_set(&(a.ssl_version), in->ssl_version); + len += i2d_ASN1_INTEGER(&(a.ssl_version), NULL); + + a.cipher.length = 2; + a.cipher.type = V_ASN1_OCTET_STRING; + l = (in->cipher == NULL) ? in->cipher_id : in->cipher->id; + buf[0] = ((unsigned char)(l >> 8L)) & 0xff; + buf[1] = ((unsigned char)(l)) & 0xff; + a.cipher.data = buf; + len += i2d_ASN1_OCTET_STRING(&(a.cipher), NULL); + + a.master_key.length = in->master_key_length; + a.master_key.type = V_ASN1_OCTET_STRING; + a.master_key.data = in->master_key; + len += i2d_ASN1_OCTET_STRING(&(a.master_key), NULL); + + a.session_id.length = in->session_id_length; + a.session_id.type = V_ASN1_OCTET_STRING; + a.session_id.data = in->session_id; + len += i2d_ASN1_OCTET_STRING(&(a.session_id), NULL); + + if (in->time != 0L) { + a.time.length = LSIZE2; + a.time.type = V_ASN1_INTEGER; + a.time.data = ibuf3; + ASN1_INTEGER_set(&(a.time), in->time); /* XXX 2038 */ + v1 = i2d_ASN1_INTEGER(&(a.time), NULL); + len += ASN1_object_size(1, v1, 1); + } + + if (in->timeout != 0L) { + a.timeout.length = LSIZE2; + a.timeout.type = V_ASN1_INTEGER; + a.timeout.data = ibuf4; + ASN1_INTEGER_set(&(a.timeout), in->timeout); + v2 = i2d_ASN1_INTEGER(&(a.timeout), NULL); + len += ASN1_object_size(1, v2, 2); + } + + if (in->peer != NULL) { + v3 = i2d_X509(in->peer, NULL); + len += ASN1_object_size(1, v3, 3); + } + + a.session_id_context.length = in->sid_ctx_length; + a.session_id_context.type = V_ASN1_OCTET_STRING; + a.session_id_context.data = in->sid_ctx; + v4 = i2d_ASN1_OCTET_STRING(&(a.session_id_context), NULL); + len += ASN1_object_size(1, v4, 4); + + if (in->verify_result != X509_V_OK) { + a.verify_result.length = LSIZE2; + a.verify_result.type = V_ASN1_INTEGER; + a.verify_result.data = ibuf5; + ASN1_INTEGER_set(&a.verify_result, in->verify_result); + v5 = i2d_ASN1_INTEGER(&(a.verify_result), NULL); + len += ASN1_object_size(1, v5, 5); + } + + if (in->tlsext_hostname) { + a.tlsext_hostname.length = strlen(in->tlsext_hostname); + a.tlsext_hostname.type = V_ASN1_OCTET_STRING; + a.tlsext_hostname.data = (unsigned char *)in->tlsext_hostname; + v6 = i2d_ASN1_OCTET_STRING(&(a.tlsext_hostname), NULL); + len += ASN1_object_size(1, v6, 6); + } + + /* 7 - PSK identity hint. */ + /* 8 - PSK identity. */ + + if (in->tlsext_tick_lifetime_hint > 0) { + a.tlsext_tick_lifetime.length = LSIZE2; + a.tlsext_tick_lifetime.type = V_ASN1_INTEGER; + a.tlsext_tick_lifetime.data = ibuf6; + ASN1_INTEGER_set(&a.tlsext_tick_lifetime, + in->tlsext_tick_lifetime_hint); + v9 = i2d_ASN1_INTEGER(&(a.tlsext_tick_lifetime), NULL); + len += ASN1_object_size(1, v9, 9); + } + + if (in->tlsext_tick) { + a.tlsext_tick.length = in->tlsext_ticklen; + a.tlsext_tick.type = V_ASN1_OCTET_STRING; + a.tlsext_tick.data = (unsigned char *)in->tlsext_tick; + v10 = i2d_ASN1_OCTET_STRING(&(a.tlsext_tick), NULL); + len += ASN1_object_size(1, v10, 10); + } + + /* 11 - Compression method. */ + /* 12 - SRP username. */ + + /* If given a NULL pointer, return the length only. */ + ret = (ASN1_object_size(1, len, V_ASN1_SEQUENCE)); + if (pp == NULL) + return (ret); + + /* Burp out the ASN1. */ + p = *pp; + ASN1_put_object(&p, 1, len, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); + i2d_ASN1_INTEGER(&(a.version), &p); + i2d_ASN1_INTEGER(&(a.ssl_version), &p); + i2d_ASN1_OCTET_STRING(&(a.cipher), &p); + i2d_ASN1_OCTET_STRING(&(a.session_id), &p); + i2d_ASN1_OCTET_STRING(&(a.master_key), &p); + if (in->time != 0L) { + ASN1_put_object(&p, 1, v1, 1, V_ASN1_CONTEXT_SPECIFIC); + i2d_ASN1_INTEGER(&(a.time), &p); + } + if (in->timeout != 0L) { + ASN1_put_object(&p, 1, v2, 2, V_ASN1_CONTEXT_SPECIFIC); + i2d_ASN1_INTEGER(&(a.timeout), &p); + } + if (in->peer != NULL) { + ASN1_put_object(&p, 1, v3, 3, V_ASN1_CONTEXT_SPECIFIC); + i2d_X509(in->peer, &p); + } + ASN1_put_object(&p, 1, v4, 4, V_ASN1_CONTEXT_SPECIFIC); + i2d_ASN1_OCTET_STRING(&(a.session_id_context), &p); + if (in->verify_result != X509_V_OK) { + ASN1_put_object(&p, 1, v5, 5, V_ASN1_CONTEXT_SPECIFIC); + i2d_ASN1_INTEGER(&(a.verify_result), &p); + } + if (in->tlsext_hostname) { + ASN1_put_object(&p, 1, v6, 6, V_ASN1_CONTEXT_SPECIFIC); + i2d_ASN1_OCTET_STRING(&(a.tlsext_hostname), &p); + } + /* 7 - PSK identity hint. */ + /* 8 - PSK identity. */ + if (in->tlsext_tick_lifetime_hint > 0) { + ASN1_put_object(&p, 1, v9, 9, V_ASN1_CONTEXT_SPECIFIC); + i2d_ASN1_INTEGER(&(a.tlsext_tick_lifetime), &p); + } + if (in->tlsext_tick) { + ASN1_put_object(&p, 1, v10, 10, V_ASN1_CONTEXT_SPECIFIC); + i2d_ASN1_OCTET_STRING(&(a.tlsext_tick), &p); + } + /* 11 - Compression method. */ + /* 12 - SRP username. */ + + *pp = p; + return (ret); +} + +SSL_SESSION * +d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length) +{ + SSL_SESSION *ret = NULL; + ASN1_const_CTX c; + ASN1_INTEGER ai, *aip; + ASN1_OCTET_STRING os, *osp; + int ssl_version = 0, i; + int Tinf, Ttag, Tclass; + long Tlen; + long id; + + c.pp = pp; + c.p = *pp; + c.q = *pp; + c.max = (length == 0) ? 0 : (c.p + length); + c.slen = length; + + if (a == NULL || *a == NULL) { + if ((ret = SSL_SESSION_new()) == NULL) { + SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + } else + ret = *a; + + aip = &ai; + osp = &os; + + if (!asn1_GetSequence(&c, &length)) { + SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + + ai.data = NULL; + ai.length = 0; + c.q = c.p; + if (d2i_ASN1_INTEGER(&aip, &c.p, c.slen) == NULL) { + SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + c.slen -= (c.p - c.q); + + if (ai.data != NULL) { + free(ai.data); + ai.data = NULL; + ai.length = 0; + } + + /* we don't care about the version right now :-) */ + c.q = c.p; + if (d2i_ASN1_INTEGER(&aip, &c.p, c.slen) == NULL) { + SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + c.slen -= (c.p - c.q); + ssl_version = (int)ASN1_INTEGER_get(aip); + ret->ssl_version = ssl_version; + if (ai.data != NULL) { + free(ai.data); + ai.data = NULL; + ai.length = 0; + } + + os.data = NULL; + os.length = 0; + c.q = c.p; + if (d2i_ASN1_OCTET_STRING(&osp, &c.p, c.slen) == NULL) { + SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + c.slen -= (c.p - c.q); + if ((ssl_version >> 8) >= SSL3_VERSION_MAJOR) { + if (os.length != 2) { + SSLerr(SSL_F_D2I_SSL_SESSION, + SSL_R_CIPHER_CODE_WRONG_LENGTH); + goto err; + } + id = 0x03000000L | ((unsigned long)os.data[0]<<8L) | + (unsigned long)os.data[1]; + } else { + SSLerr(SSL_F_D2I_SSL_SESSION, SSL_R_UNKNOWN_SSL_VERSION); + goto err; + } + + ret->cipher = NULL; + ret->cipher_id = id; + + c.q = c.p; + if (d2i_ASN1_OCTET_STRING(&osp, &c.p, c.slen) == NULL) { + SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + c.slen -= (c.p - c.q); + + i = SSL3_MAX_SSL_SESSION_ID_LENGTH; + if (os.length > i) + os.length = i; + if (os.length > (int)sizeof(ret->session_id)) /* can't happen */ + os.length = sizeof(ret->session_id); + + ret->session_id_length = os.length; + OPENSSL_assert(os.length <= (int)sizeof(ret->session_id)); + memcpy(ret->session_id, os.data, os.length); + + c.q = c.p; + if (d2i_ASN1_OCTET_STRING(&osp, &c.p, c.slen) == NULL) { + SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + c.slen -= (c.p - c.q); + if (os.length > SSL_MAX_MASTER_KEY_LENGTH) + ret->master_key_length = SSL_MAX_MASTER_KEY_LENGTH; + else + ret->master_key_length = os.length; + memcpy(ret->master_key, os.data, ret->master_key_length); + + os.length = 0; + + /* 1 - Time (INTEGER). */ + /* XXX 2038 */ + ai.length = 0; + if (c.slen != 0L && + *c.p == (V_ASN1_CONSTRUCTED | V_ASN1_CONTEXT_SPECIFIC | 1)) { + c.q = c.p; + Tinf = ASN1_get_object(&c.p, &Tlen, &Ttag, &Tclass, c.slen); + if (Tinf & 0x80) { + SSLerr(SSL_F_D2I_SSL_SESSION, + ERR_R_BAD_ASN1_OBJECT_HEADER); + goto err; + } + if (Tinf == (V_ASN1_CONSTRUCTED + 1)) + Tlen = c.slen - (c.p - c.q) - 2; + if (d2i_ASN1_INTEGER(&aip, &c.p, Tlen) == NULL) { + SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + if (Tinf == (V_ASN1_CONSTRUCTED + 1)) { + Tlen = c.slen - (c.p - c.q); + if(!ASN1_const_check_infinite_end(&c.p, Tlen)) { + SSLerr(SSL_F_D2I_SSL_SESSION, + ERR_R_MISSING_ASN1_EOS); + goto err; + } + } + c.slen -= (c.p - c.q); + } + if (ai.data != NULL) { + ret->time = ASN1_INTEGER_get(aip); + free(ai.data); + ai.data = NULL; + ai.length = 0; + } else + ret->time = time(NULL); + + /* 2 - Timeout (INTEGER). */ + ai.length = 0; + if (c.slen != 0L && + *c.p == (V_ASN1_CONSTRUCTED | V_ASN1_CONTEXT_SPECIFIC | 2)) { + c.q = c.p; + Tinf = ASN1_get_object(&c.p, &Tlen, &Ttag, &Tclass, c.slen); + if (Tinf & 0x80) { + SSLerr(SSL_F_D2I_SSL_SESSION, + ERR_R_BAD_ASN1_OBJECT_HEADER); + goto err; + } + if (Tinf == (V_ASN1_CONSTRUCTED + 1)) + Tlen = c.slen - (c.p - c.q) - 2; + if (d2i_ASN1_INTEGER(&aip, &c.p, Tlen) == NULL) { + SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + if (Tinf == (V_ASN1_CONSTRUCTED + 1)) { + Tlen = c.slen - (c.p - c.q); + if(!ASN1_const_check_infinite_end(&c.p, Tlen)) { + SSLerr(SSL_F_D2I_SSL_SESSION, + ERR_R_MISSING_ASN1_EOS); + goto err; + } + } + c.slen -= (c.p - c.q); + } + if (ai.data != NULL) { + ret->timeout = ASN1_INTEGER_get(aip); + free(ai.data); + ai.data = NULL; + ai.length = 0; + } else + ret->timeout = 3; + + /* 3 - Peer (X509). */ + X509_free(ret->peer); + ret->peer = NULL; + + if (c.slen != 0L && + *c.p == (V_ASN1_CONSTRUCTED | V_ASN1_CONTEXT_SPECIFIC | 3)) { + c.q = c.p; + Tinf = ASN1_get_object(&c.p, &Tlen, &Ttag, &Tclass, c.slen); + if (Tinf & 0x80) { + SSLerr(SSL_F_D2I_SSL_SESSION, + ERR_R_BAD_ASN1_OBJECT_HEADER); + goto err; + } + if (Tinf == (V_ASN1_CONSTRUCTED + 1)) + Tlen = c.slen - (c.p - c.q) - 2; + if (d2i_X509(&ret->peer, &c.p, Tlen) == NULL) { + SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + if (Tinf == (V_ASN1_CONSTRUCTED + 1)) { + Tlen = c.slen - (c.p - c.q); + if(!ASN1_const_check_infinite_end(&c.p, Tlen)) { + SSLerr(SSL_F_D2I_SSL_SESSION, + ERR_R_MISSING_ASN1_EOS); + goto err; + } + } + c.slen -= (c.p - c.q); + } + + /* 4 - Session ID (OCTET STRING). */ + os.length = 0; + free(os.data); + os.data = NULL; + if (c.slen != 0L && + *c.p == (V_ASN1_CONSTRUCTED | V_ASN1_CONTEXT_SPECIFIC | 4)) { + c.q = c.p; + Tinf = ASN1_get_object(&c.p, &Tlen, &Ttag, &Tclass, c.slen); + if (Tinf & 0x80) { + SSLerr(SSL_F_D2I_SSL_SESSION, + ERR_R_BAD_ASN1_OBJECT_HEADER); + goto err; + } + if (Tinf == (V_ASN1_CONSTRUCTED + 1)) + Tlen = c.slen - (c.p - c.q) - 2; + if (d2i_ASN1_OCTET_STRING(&osp, &c.p, Tlen) == NULL) { + SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + if (Tinf == (V_ASN1_CONSTRUCTED + 1)) { + Tlen = c.slen - (c.p - c.q); + if(!ASN1_const_check_infinite_end(&c.p, Tlen)) { + SSLerr(SSL_F_D2I_SSL_SESSION, + ERR_R_MISSING_ASN1_EOS); + goto err; + } + } + c.slen -= (c.p - c.q); + } + if (os.data != NULL) { + if (os.length > SSL_MAX_SID_CTX_LENGTH) { + SSLerr(SSL_F_D2I_SSL_SESSION, SSL_R_BAD_LENGTH); + goto err; + } else { + ret->sid_ctx_length = os.length; + memcpy(ret->sid_ctx, os.data, os.length); + } + free(os.data); + os.data = NULL; + os.length = 0; + } else + ret->sid_ctx_length = 0; + + /* 5 - Verify_result. */ + ai.length = 0; + if (c.slen != 0L && + *c.p == (V_ASN1_CONSTRUCTED | V_ASN1_CONTEXT_SPECIFIC | 5)) { + c.q = c.p; + Tinf = ASN1_get_object(&c.p, &Tlen, &Ttag, &Tclass, c.slen); + if (Tinf & 0x80) { + SSLerr(SSL_F_D2I_SSL_SESSION, + ERR_R_BAD_ASN1_OBJECT_HEADER); + goto err; + } + if (Tinf == (V_ASN1_CONSTRUCTED + 1)) + Tlen = c.slen - (c.p - c.q) - 2; + if (d2i_ASN1_INTEGER(&aip, &c.p, Tlen) == NULL) { + SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + if (Tinf == (V_ASN1_CONSTRUCTED + 1)) { + Tlen = c.slen - (c.p - c.q); + if(!ASN1_const_check_infinite_end(&c.p, Tlen)) { + SSLerr(SSL_F_D2I_SSL_SESSION, + ERR_R_MISSING_ASN1_EOS); + goto err; + } + } + c.slen -= (c.p - c.q); + } + if (ai.data != NULL) { + ret->verify_result = ASN1_INTEGER_get(aip); + free(ai.data); + ai.data = NULL; + ai.length = 0; + } else + ret->verify_result = X509_V_OK; + + /* 6 - HostName (OCTET STRING). */ + os.length = 0; + os.data = NULL; + if (c.slen != 0L && + *c.p == (V_ASN1_CONSTRUCTED | V_ASN1_CONTEXT_SPECIFIC | 6)) { + c.q = c.p; + Tinf = ASN1_get_object(&c.p, &Tlen, &Ttag, &Tclass, c.slen); + if (Tinf & 0x80) { + SSLerr(SSL_F_D2I_SSL_SESSION, + ERR_R_BAD_ASN1_OBJECT_HEADER); + goto err; + } + if (Tinf == (V_ASN1_CONSTRUCTED + 1)) + Tlen = c.slen - (c.p - c.q) - 2; + if (d2i_ASN1_OCTET_STRING(&osp, &c.p, Tlen) == NULL) { + SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + if (Tinf == (V_ASN1_CONSTRUCTED + 1)) { + Tlen = c.slen - (c.p - c.q); + if(!ASN1_const_check_infinite_end(&c.p, Tlen)) { + SSLerr(SSL_F_D2I_SSL_SESSION, + ERR_R_MISSING_ASN1_EOS); + goto err; + } + } + c.slen -= (c.p - c.q); + } + if (os.data) { + ret->tlsext_hostname = strndup((char *)os.data, os.length); + free(os.data); + os.data = NULL; + os.length = 0; + } else + ret->tlsext_hostname = NULL; + + /* 7 - PSK identity hint (OCTET STRING). */ + /* 8 - PSK identity (OCTET STRING). */ + + /* 9 - Ticket lifetime. */ + ai.length = 0; + if (c.slen != 0L && + *c.p == (V_ASN1_CONSTRUCTED | V_ASN1_CONTEXT_SPECIFIC | 9)) { + c.q = c.p; + Tinf = ASN1_get_object(&c.p, &Tlen, &Ttag, &Tclass, c.slen); + if (Tinf & 0x80) { + SSLerr(SSL_F_D2I_SSL_SESSION, + ERR_R_BAD_ASN1_OBJECT_HEADER); + goto err; + } + if (Tinf == (V_ASN1_CONSTRUCTED + 1)) + Tlen = c.slen - (c.p - c.q) - 2; + if (d2i_ASN1_INTEGER(&aip, &c.p, Tlen) == NULL) { + SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + if (Tinf == (V_ASN1_CONSTRUCTED + 1)) { + Tlen = c.slen - (c.p - c.q); + if(!ASN1_const_check_infinite_end(&c.p, Tlen)) { + SSLerr(SSL_F_D2I_SSL_SESSION, + ERR_R_MISSING_ASN1_EOS); + goto err; + } + } + c.slen -= (c.p - c.q); + } + if (ai.data != NULL) { + ret->tlsext_tick_lifetime_hint = ASN1_INTEGER_get(aip); + free(ai.data); + ai.data = NULL; + ai.length = 0; + } else if (ret->tlsext_ticklen && ret->session_id_length) + ret->tlsext_tick_lifetime_hint = -1; + else + ret->tlsext_tick_lifetime_hint = 0; + os.length = 0; + os.data = NULL; + + /* 10 - Ticket (OCTET STRING). */ + if (c.slen != 0L && + *c.p == (V_ASN1_CONSTRUCTED | V_ASN1_CONTEXT_SPECIFIC | 10)) { + c.q = c.p; + Tinf = ASN1_get_object(&c.p, &Tlen, &Ttag, &Tclass, c.slen); + if (Tinf & 0x80) { + SSLerr(SSL_F_D2I_SSL_SESSION, + ERR_R_BAD_ASN1_OBJECT_HEADER); + goto err; + } + if (Tinf == (V_ASN1_CONSTRUCTED + 1)) + Tlen = c.slen - (c.p - c.q) - 2; + if (d2i_ASN1_OCTET_STRING(&osp, &c.p, Tlen) == NULL) { + SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + if (Tinf == (V_ASN1_CONSTRUCTED + 1)) { + Tlen = c.slen - (c.p - c.q); + if(!ASN1_const_check_infinite_end(&c.p, Tlen)) { + SSLerr(SSL_F_D2I_SSL_SESSION, + ERR_R_MISSING_ASN1_EOS); + goto err; + } + } + c.slen -= (c.p - c.q); + } + if (os.data) { + ret->tlsext_tick = os.data; + ret->tlsext_ticklen = os.length; + os.data = NULL; + os.length = 0; + } else + ret->tlsext_tick = NULL; + + /* 11 - Compression method (OCTET STRING). */ + /* 12 - SRP username (OCTET STRING). */ + + if (!asn1_const_Finish(&c)) { + SSLerr(SSL_F_D2I_SSL_SESSION, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + + *pp = c.p; + if (a != NULL) + *a = ret; + + return (ret); + +err: + ERR_asprintf_error_data("offset=%d", (int)(c.q - *pp)); + if (ret != NULL && (a == NULL || *a != ret)) + SSL_SESSION_free(ret); + + return (NULL); +} diff --git a/crypto/libressl/ssl/ssl_cert.c b/crypto/libressl/ssl/ssl_cert.c new file mode 100644 index 0000000000..3b12e20ba4 --- /dev/null +++ b/crypto/libressl/ssl/ssl_cert.c @@ -0,0 +1,722 @@ +/* $OpenBSD: ssl_cert.c,v 1.51 2015/09/11 17:37:47 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ssl_locl.h" + +int +SSL_get_ex_data_X509_STORE_CTX_idx(void) +{ + static volatile int ssl_x509_store_ctx_idx = -1; + int got_write_lock = 0; + + CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); + + if (ssl_x509_store_ctx_idx < 0) { + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + got_write_lock = 1; + + if (ssl_x509_store_ctx_idx < 0) { + ssl_x509_store_ctx_idx = + X509_STORE_CTX_get_ex_new_index( + 0, "SSL for verify callback", NULL, NULL, NULL); + } + } + + if (got_write_lock) + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + else + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + + return ssl_x509_store_ctx_idx; +} + +static void +ssl_cert_set_default_md(CERT *cert) +{ + /* Set digest values to defaults */ + cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); + cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); + cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); + cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); +#ifndef OPENSSL_NO_GOST + cert->pkeys[SSL_PKEY_GOST01].digest = EVP_gostr341194(); +#endif +} + +CERT * +ssl_cert_new(void) +{ + CERT *ret; + + ret = calloc(1, sizeof(CERT)); + if (ret == NULL) { + SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + ret->key = &(ret->pkeys[SSL_PKEY_RSA_ENC]); + ret->references = 1; + ssl_cert_set_default_md(ret); + return (ret); +} + +CERT * +ssl_cert_dup(CERT *cert) +{ + CERT *ret; + int i; + + ret = calloc(1, sizeof(CERT)); + if (ret == NULL) { + SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + /* + * same as ret->key = ret->pkeys + (cert->key - cert->pkeys), + * if you find that more readable + */ + ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]]; + + ret->valid = cert->valid; + ret->mask_k = cert->mask_k; + ret->mask_a = cert->mask_a; + + if (cert->dh_tmp != NULL) { + ret->dh_tmp = DHparams_dup(cert->dh_tmp); + if (ret->dh_tmp == NULL) { + SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB); + goto err; + } + if (cert->dh_tmp->priv_key) { + BIGNUM *b = BN_dup(cert->dh_tmp->priv_key); + if (!b) { + SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); + goto err; + } + ret->dh_tmp->priv_key = b; + } + if (cert->dh_tmp->pub_key) { + BIGNUM *b = BN_dup(cert->dh_tmp->pub_key); + if (!b) { + SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); + goto err; + } + ret->dh_tmp->pub_key = b; + } + } + ret->dh_tmp_cb = cert->dh_tmp_cb; + ret->dh_tmp_auto = cert->dh_tmp_auto; + + if (cert->ecdh_tmp) { + ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp); + if (ret->ecdh_tmp == NULL) { + SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB); + goto err; + } + } + ret->ecdh_tmp_cb = cert->ecdh_tmp_cb; + ret->ecdh_tmp_auto = cert->ecdh_tmp_auto; + + for (i = 0; i < SSL_PKEY_NUM; i++) { + if (cert->pkeys[i].x509 != NULL) { + ret->pkeys[i].x509 = cert->pkeys[i].x509; + CRYPTO_add(&ret->pkeys[i].x509->references, 1, + CRYPTO_LOCK_X509); + } + + if (cert->pkeys[i].privatekey != NULL) { + ret->pkeys[i].privatekey = cert->pkeys[i].privatekey; + CRYPTO_add(&ret->pkeys[i].privatekey->references, 1, + CRYPTO_LOCK_EVP_PKEY); + + switch (i) { + /* + * If there was anything special to do for + * certain types of keys, we'd do it here. + * (Nothing at the moment, I think.) + */ + + case SSL_PKEY_RSA_ENC: + case SSL_PKEY_RSA_SIGN: + /* We have an RSA key. */ + break; + + case SSL_PKEY_DSA_SIGN: + /* We have a DSA key. */ + break; + + case SSL_PKEY_DH_RSA: + case SSL_PKEY_DH_DSA: + /* We have a DH key. */ + break; + + case SSL_PKEY_ECC: + /* We have an ECC key */ + break; + + default: + /* Can't happen. */ + SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG); + } + } + } + + /* + * ret->extra_certs *should* exist, but currently the own certificate + * chain is held inside SSL_CTX + */ + + ret->references = 1; + /* + * Set digests to defaults. NB: we don't copy existing values + * as they will be set during handshake. + */ + ssl_cert_set_default_md(ret); + + return (ret); + +err: + DH_free(ret->dh_tmp); + EC_KEY_free(ret->ecdh_tmp); + + for (i = 0; i < SSL_PKEY_NUM; i++) { + X509_free(ret->pkeys[i].x509); + EVP_PKEY_free(ret->pkeys[i].privatekey); + } + free (ret); + return NULL; +} + + +void +ssl_cert_free(CERT *c) +{ + int i; + + if (c == NULL) + return; + + i = CRYPTO_add(&c->references, -1, CRYPTO_LOCK_SSL_CERT); + if (i > 0) + return; + + DH_free(c->dh_tmp); + EC_KEY_free(c->ecdh_tmp); + + for (i = 0; i < SSL_PKEY_NUM; i++) { + X509_free(c->pkeys[i].x509); + EVP_PKEY_free(c->pkeys[i].privatekey); + } + + free(c); +} + +int +ssl_cert_inst(CERT **o) +{ + /* + * Create a CERT if there isn't already one + * (which cannot really happen, as it is initially created in + * SSL_CTX_new; but the earlier code usually allows for that one + * being non-existant, so we follow that behaviour, as it might + * turn out that there actually is a reason for it -- but I'm + * not sure that *all* of the existing code could cope with + * s->cert being NULL, otherwise we could do without the + * initialization in SSL_CTX_new). + */ + + if (o == NULL) { + SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (*o == NULL) { + if ((*o = ssl_cert_new()) == NULL) { + SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE); + return (0); + } + } + return (1); +} + + +SESS_CERT * +ssl_sess_cert_new(void) +{ + SESS_CERT *ret; + + ret = calloc(1, sizeof *ret); + if (ret == NULL) { + SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]); + ret->references = 1; + + return ret; +} + +void +ssl_sess_cert_free(SESS_CERT *sc) +{ + int i; + + if (sc == NULL) + return; + + i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT); + if (i > 0) + return; + + /* i == 0 */ + if (sc->cert_chain != NULL) + sk_X509_pop_free(sc->cert_chain, X509_free); + for (i = 0; i < SSL_PKEY_NUM; i++) + X509_free(sc->peer_pkeys[i].x509); + + DH_free(sc->peer_dh_tmp); + EC_KEY_free(sc->peer_ecdh_tmp); + + free(sc); +} + +int +ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) +{ + X509_STORE_CTX ctx; + X509 *x; + int ret; + + if ((sk == NULL) || (sk_X509_num(sk) == 0)) + return (0); + + x = sk_X509_value(sk, 0); + if (!X509_STORE_CTX_init(&ctx, s->ctx->cert_store, x, sk)) { + SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_X509_LIB); + return (0); + } + X509_STORE_CTX_set_ex_data(&ctx, + SSL_get_ex_data_X509_STORE_CTX_idx(), s); + + /* + * We need to inherit the verify parameters. These can be + * determined by the context: if its a server it will verify + * SSL client certificates or vice versa. + */ + X509_STORE_CTX_set_default(&ctx, + s->server ? "ssl_client" : "ssl_server"); + + /* + * Anything non-default in "param" should overwrite anything + * in the ctx. + */ + X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param); + + if (s->verify_callback) + X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback); + + if (s->ctx->app_verify_callback != NULL) + ret = s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg); + else + ret = X509_verify_cert(&ctx); + + s->verify_result = ctx.error; + X509_STORE_CTX_cleanup(&ctx); + + return (ret); +} + +static void +set_client_CA_list(STACK_OF(X509_NAME) **ca_list, + STACK_OF(X509_NAME) *name_list) +{ + if (*ca_list != NULL) + sk_X509_NAME_pop_free(*ca_list, X509_NAME_free); + + *ca_list = name_list; +} + +STACK_OF(X509_NAME) * +SSL_dup_CA_list(STACK_OF(X509_NAME) *sk) +{ + int i; + STACK_OF(X509_NAME) *ret; + X509_NAME *name; + + ret = sk_X509_NAME_new_null(); + for (i = 0; i < sk_X509_NAME_num(sk); i++) { + name = X509_NAME_dup(sk_X509_NAME_value(sk, i)); + if ((name == NULL) || !sk_X509_NAME_push(ret, name)) { + sk_X509_NAME_pop_free(ret, X509_NAME_free); + return (NULL); + } + } + return (ret); +} + +void +SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) +{ + set_client_CA_list(&(s->client_CA), name_list); +} + +void +SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) +{ + set_client_CA_list(&(ctx->client_CA), name_list); +} + +STACK_OF(X509_NAME) * +SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) +{ + return (ctx->client_CA); +} + +STACK_OF(X509_NAME) * +SSL_get_client_CA_list(const SSL *s) +{ + if (s->type == SSL_ST_CONNECT) { + /* We are in the client. */ + if (((s->version >> 8) == SSL3_VERSION_MAJOR) && + (s->s3 != NULL)) + return (s->s3->tmp.ca_names); + else + return (NULL); + } else { + if (s->client_CA != NULL) + return (s->client_CA); + else + return (s->ctx->client_CA); + } +} + +static int +add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x) +{ + X509_NAME *name; + + if (x == NULL) + return (0); + if ((*sk == NULL) && ((*sk = sk_X509_NAME_new_null()) == NULL)) + return (0); + + if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL) + return (0); + + if (!sk_X509_NAME_push(*sk, name)) { + X509_NAME_free(name); + return (0); + } + return (1); +} + +int +SSL_add_client_CA(SSL *ssl, X509 *x) +{ + return (add_client_CA(&(ssl->client_CA), x)); +} + +int +SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) +{ + return (add_client_CA(&(ctx->client_CA), x)); +} + +static int +xname_cmp(const X509_NAME * const *a, const X509_NAME * const *b) +{ + return (X509_NAME_cmp(*a, *b)); +} + +/*! + * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed; + * it doesn't really have anything to do with clients (except that a common use + * for a stack of CAs is to send it to the client). Actually, it doesn't have + * much to do with CAs, either, since it will load any old cert. + * \param file the file containing one or more certs. + * \return a ::STACK containing the certs. + */ +STACK_OF(X509_NAME) * +SSL_load_client_CA_file(const char *file) +{ + BIO *in; + X509 *x = NULL; + X509_NAME *xn = NULL; + STACK_OF(X509_NAME) *ret = NULL, *sk; + + sk = sk_X509_NAME_new(xname_cmp); + + in = BIO_new(BIO_s_file_internal()); + + if ((sk == NULL) || (in == NULL)) { + SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!BIO_read_filename(in, file)) + goto err; + + for (;;) { + if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) + break; + if (ret == NULL) { + ret = sk_X509_NAME_new_null(); + if (ret == NULL) { + SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, + ERR_R_MALLOC_FAILURE); + goto err; + } + } + if ((xn = X509_get_subject_name(x)) == NULL) goto err; + /* check for duplicates */ + xn = X509_NAME_dup(xn); + if (xn == NULL) + goto err; + if (sk_X509_NAME_find(sk, xn) >= 0) + X509_NAME_free(xn); + else { + sk_X509_NAME_push(sk, xn); + sk_X509_NAME_push(ret, xn); + } + } + + if (0) { +err: + if (ret != NULL) + sk_X509_NAME_pop_free(ret, X509_NAME_free); + ret = NULL; + } + if (sk != NULL) + sk_X509_NAME_free(sk); + BIO_free(in); + X509_free(x); + if (ret != NULL) + ERR_clear_error(); + return (ret); +} + +/*! + * Add a file of certs to a stack. + * \param stack the stack to add to. + * \param file the file to add from. All certs in this file that are not + * already in the stack will be added. + * \return 1 for success, 0 for failure. Note that in the case of failure some + * certs may have been added to \c stack. + */ + +int +SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, + const char *file) +{ + BIO *in; + X509 *x = NULL; + X509_NAME *xn = NULL; + int ret = 1; + int (*oldcmp)(const X509_NAME * const *a, const X509_NAME * const *b); + + oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp); + + in = BIO_new(BIO_s_file_internal()); + + if (in == NULL) { + SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!BIO_read_filename(in, file)) + goto err; + + for (;;) { + if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) + break; + if ((xn = X509_get_subject_name(x)) == NULL) goto err; + xn = X509_NAME_dup(xn); + if (xn == NULL) + goto err; + if (sk_X509_NAME_find(stack, xn) >= 0) + X509_NAME_free(xn); + else + sk_X509_NAME_push(stack, xn); + } + + ERR_clear_error(); + + if (0) { +err: + ret = 0; + } + BIO_free(in); + X509_free(x); + + (void)sk_X509_NAME_set_cmp_func(stack, oldcmp); + + return ret; +} + +/*! + * Add a directory of certs to a stack. + * \param stack the stack to append to. + * \param dir the directory to append from. All files in this directory will be + * examined as potential certs. Any that are acceptable to + * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will + * be included. + * \return 1 for success, 0 for failure. Note that in the case of failure some + * certs may have been added to \c stack. + */ + +int +SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, const char *dir) +{ + DIR *dirp = NULL; + char *path = NULL; + int ret = 0; + + dirp = opendir(dir); + if (dirp) { + struct dirent *dp; + while ((dp = readdir(dirp)) != NULL) { + if (asprintf(&path, "%s/%s", dir, dp->d_name) != -1) { + ret = SSL_add_file_cert_subjects_to_stack( + stack, path); + free(path); + } + if (!ret) + break; + } + (void) closedir(dirp); + } + if (!ret) { + SYSerr(SYS_F_OPENDIR, errno); + ERR_asprintf_error_data("opendir ('%s')", dir); + SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB); + } + return ret; +} diff --git a/crypto/libressl/ssl/ssl_ciph.c b/crypto/libressl/ssl/ssl_ciph.c new file mode 100644 index 0000000000..371df9a6b8 --- /dev/null +++ b/crypto/libressl/ssl/ssl_ciph.c @@ -0,0 +1,1798 @@ +/* $OpenBSD: ssl_ciph.c,v 1.85 2016/04/28 16:06:53 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include + +#include + +#ifndef OPENSSL_NO_ENGINE +#include +#endif + +#include "ssl_locl.h" + +#define SSL_ENC_DES_IDX 0 +#define SSL_ENC_3DES_IDX 1 +#define SSL_ENC_RC4_IDX 2 +#define SSL_ENC_IDEA_IDX 3 +#define SSL_ENC_NULL_IDX 4 +#define SSL_ENC_AES128_IDX 5 +#define SSL_ENC_AES256_IDX 6 +#define SSL_ENC_CAMELLIA128_IDX 7 +#define SSL_ENC_CAMELLIA256_IDX 8 +#define SSL_ENC_GOST89_IDX 9 +#define SSL_ENC_AES128GCM_IDX 10 +#define SSL_ENC_AES256GCM_IDX 11 +#define SSL_ENC_NUM_IDX 12 + + +static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +#define SSL_MD_MD5_IDX 0 +#define SSL_MD_SHA1_IDX 1 +#define SSL_MD_GOST94_IDX 2 +#define SSL_MD_GOST89MAC_IDX 3 +#define SSL_MD_SHA256_IDX 4 +#define SSL_MD_SHA384_IDX 5 +#define SSL_MD_STREEBOG256_IDX 6 +#define SSL_MD_STREEBOG512_IDX 7 +/*Constant SSL_MAX_DIGEST equal to size of digests array should be + * defined in the + * ssl_locl.h */ +#define SSL_MD_NUM_IDX SSL_MAX_DIGEST +static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static int ssl_mac_pkey_id[SSL_MD_NUM_IDX] = { + EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_GOSTIMIT, + EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, +}; + +static int ssl_mac_secret_size[SSL_MD_NUM_IDX] = { + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static int ssl_handshake_digest_flag[SSL_MD_NUM_IDX] = { + SSL_HANDSHAKE_MAC_MD5, SSL_HANDSHAKE_MAC_SHA, + SSL_HANDSHAKE_MAC_GOST94, 0, SSL_HANDSHAKE_MAC_SHA256, + SSL_HANDSHAKE_MAC_SHA384, SSL_HANDSHAKE_MAC_STREEBOG256, + SSL_HANDSHAKE_MAC_STREEBOG512 +}; + +#define CIPHER_ADD 1 +#define CIPHER_KILL 2 +#define CIPHER_DEL 3 +#define CIPHER_ORD 4 +#define CIPHER_SPECIAL 5 + +typedef struct cipher_order_st { + const SSL_CIPHER *cipher; + int active; + int dead; + struct cipher_order_st *next, *prev; +} CIPHER_ORDER; + +static const SSL_CIPHER cipher_aliases[] = { + + /* "ALL" doesn't include eNULL (must be specifically enabled) */ + { + .name = SSL_TXT_ALL, + .algorithm_enc = ~SSL_eNULL, + }, + + /* "COMPLEMENTOFALL" */ + { + .name = SSL_TXT_CMPALL, + .algorithm_enc = SSL_eNULL, + }, + + /* + * "COMPLEMENTOFDEFAULT" + * (does *not* include ciphersuites not found in ALL!) + */ + { + .name = SSL_TXT_CMPDEF, + .algorithm_mkey = SSL_kDHE|SSL_kECDHE, + .algorithm_auth = SSL_aNULL, + .algorithm_enc = ~SSL_eNULL, + }, + + /* + * key exchange aliases + * (some of those using only a single bit here combine multiple key + * exchange algs according to the RFCs, e.g. kEDH combines DHE_DSS + * and DHE_RSA) + */ + { + .name = SSL_TXT_kRSA, + .algorithm_mkey = SSL_kRSA, + }, + { + .name = SSL_TXT_kEDH, + .algorithm_mkey = SSL_kDHE, + }, + { + .name = SSL_TXT_DH, + .algorithm_mkey = SSL_kDHE, + }, + + { + .name = SSL_TXT_kECDHr, + .algorithm_mkey = SSL_kECDHr, + }, + { + .name = SSL_TXT_kECDHe, + .algorithm_mkey = SSL_kECDHe, + }, + { + .name = SSL_TXT_kECDH, + .algorithm_mkey = SSL_kECDHr|SSL_kECDHe, + }, + { + .name = SSL_TXT_kEECDH, + .algorithm_mkey = SSL_kECDHE, + }, + { + .name = SSL_TXT_ECDH, + .algorithm_mkey = SSL_kECDHr|SSL_kECDHe|SSL_kECDHE, + }, + + { + .name = SSL_TXT_kGOST, + .algorithm_mkey = SSL_kGOST, + }, + + /* server authentication aliases */ + { + .name = SSL_TXT_aRSA, + .algorithm_auth = SSL_aRSA, + }, + { + .name = SSL_TXT_aDSS, + .algorithm_auth = SSL_aDSS, + }, + { + .name = SSL_TXT_DSS, + .algorithm_auth = SSL_aDSS, + }, + { + .name = SSL_TXT_aNULL, + .algorithm_auth = SSL_aNULL, + }, + { + .name = SSL_TXT_aECDH, + .algorithm_auth = SSL_aECDH, + }, + { + .name = SSL_TXT_aECDSA, + .algorithm_auth = SSL_aECDSA, + }, + { + .name = SSL_TXT_ECDSA, + .algorithm_auth = SSL_aECDSA, + }, + { + .name = SSL_TXT_aGOST01, + .algorithm_auth = SSL_aGOST01, + }, + { + .name = SSL_TXT_aGOST, + .algorithm_auth = SSL_aGOST01, + }, + + /* aliases combining key exchange and server authentication */ + { + .name = SSL_TXT_DHE, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = ~SSL_aNULL, + }, + { + .name = SSL_TXT_EDH, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = ~SSL_aNULL, + }, + { + .name = SSL_TXT_ECDHE, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = ~SSL_aNULL, + }, + { + .name = SSL_TXT_EECDH, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = ~SSL_aNULL, + }, + { + .name = SSL_TXT_NULL, + .algorithm_enc = SSL_eNULL, + }, + { + .name = SSL_TXT_RSA, + .algorithm_mkey = SSL_kRSA, + .algorithm_auth = SSL_aRSA, + }, + { + .name = SSL_TXT_ADH, + .algorithm_mkey = SSL_kDHE, + .algorithm_auth = SSL_aNULL, + }, + { + .name = SSL_TXT_AECDH, + .algorithm_mkey = SSL_kECDHE, + .algorithm_auth = SSL_aNULL, + }, + + /* symmetric encryption aliases */ + { + .name = SSL_TXT_DES, + .algorithm_enc = SSL_DES, + }, + { + .name = SSL_TXT_3DES, + .algorithm_enc = SSL_3DES, + }, + { + .name = SSL_TXT_RC4, + .algorithm_enc = SSL_RC4, + }, + { + .name = SSL_TXT_IDEA, + .algorithm_enc = SSL_IDEA, + }, + { + .name = SSL_TXT_eNULL, + .algorithm_enc = SSL_eNULL, + }, + { + .name = SSL_TXT_AES128, + .algorithm_enc = SSL_AES128|SSL_AES128GCM, + }, + { + .name = SSL_TXT_AES256, + .algorithm_enc = SSL_AES256|SSL_AES256GCM, + }, + { + .name = SSL_TXT_AES, + .algorithm_enc = SSL_AES, + }, + { + .name = SSL_TXT_AES_GCM, + .algorithm_enc = SSL_AES128GCM|SSL_AES256GCM, + }, + { + .name = SSL_TXT_CAMELLIA128, + .algorithm_enc = SSL_CAMELLIA128, + }, + { + .name = SSL_TXT_CAMELLIA256, + .algorithm_enc = SSL_CAMELLIA256, + }, + { + .name = SSL_TXT_CAMELLIA, + .algorithm_enc = SSL_CAMELLIA128|SSL_CAMELLIA256, + }, + { + .name = SSL_TXT_CHACHA20, + .algorithm_enc = SSL_CHACHA20POLY1305|SSL_CHACHA20POLY1305_OLD, + }, + + /* MAC aliases */ + { + .name = SSL_TXT_AEAD, + .algorithm_mac = SSL_AEAD, + }, + { + .name = SSL_TXT_MD5, + .algorithm_mac = SSL_MD5, + }, + { + .name = SSL_TXT_SHA1, + .algorithm_mac = SSL_SHA1, + }, + { + .name = SSL_TXT_SHA, + .algorithm_mac = SSL_SHA1, + }, + { + .name = SSL_TXT_GOST94, + .algorithm_mac = SSL_GOST94, + }, + { + .name = SSL_TXT_GOST89MAC, + .algorithm_mac = SSL_GOST89MAC, + }, + { + .name = SSL_TXT_SHA256, + .algorithm_mac = SSL_SHA256, + }, + { + .name = SSL_TXT_SHA384, + .algorithm_mac = SSL_SHA384, + }, + { + .name = SSL_TXT_STREEBOG256, + .algorithm_mac = SSL_STREEBOG256, + }, + { + .name = SSL_TXT_STREEBOG512, + .algorithm_mac = SSL_STREEBOG512, + }, + + /* protocol version aliases */ + { + .name = SSL_TXT_SSLV3, + .algorithm_ssl = SSL_SSLV3, + }, + { + .name = SSL_TXT_TLSV1, + .algorithm_ssl = SSL_TLSV1, + }, + { + .name = SSL_TXT_TLSV1_2, + .algorithm_ssl = SSL_TLSV1_2, + }, + + /* strength classes */ + { + .name = SSL_TXT_LOW, + .algo_strength = SSL_LOW, + }, + { + .name = SSL_TXT_MEDIUM, + .algo_strength = SSL_MEDIUM, + }, + { + .name = SSL_TXT_HIGH, + .algo_strength = SSL_HIGH, + }, +}; + +void +ssl_load_ciphers(void) +{ + ssl_cipher_methods[SSL_ENC_DES_IDX] = + EVP_get_cipherbyname(SN_des_cbc); + ssl_cipher_methods[SSL_ENC_3DES_IDX] = + EVP_get_cipherbyname(SN_des_ede3_cbc); + ssl_cipher_methods[SSL_ENC_RC4_IDX] = + EVP_get_cipherbyname(SN_rc4); +#ifndef OPENSSL_NO_IDEA + ssl_cipher_methods[SSL_ENC_IDEA_IDX] = + EVP_get_cipherbyname(SN_idea_cbc); +#else + ssl_cipher_methods[SSL_ENC_IDEA_IDX] = NULL; +#endif + ssl_cipher_methods[SSL_ENC_AES128_IDX] = + EVP_get_cipherbyname(SN_aes_128_cbc); + ssl_cipher_methods[SSL_ENC_AES256_IDX] = + EVP_get_cipherbyname(SN_aes_256_cbc); + ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] = + EVP_get_cipherbyname(SN_camellia_128_cbc); + ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] = + EVP_get_cipherbyname(SN_camellia_256_cbc); + ssl_cipher_methods[SSL_ENC_GOST89_IDX] = + EVP_get_cipherbyname(SN_gost89_cnt); + + ssl_cipher_methods[SSL_ENC_AES128GCM_IDX] = + EVP_get_cipherbyname(SN_aes_128_gcm); + ssl_cipher_methods[SSL_ENC_AES256GCM_IDX] = + EVP_get_cipherbyname(SN_aes_256_gcm); + + ssl_digest_methods[SSL_MD_MD5_IDX] = + EVP_get_digestbyname(SN_md5); + ssl_mac_secret_size[SSL_MD_MD5_IDX] = + EVP_MD_size(ssl_digest_methods[SSL_MD_MD5_IDX]); + OPENSSL_assert(ssl_mac_secret_size[SSL_MD_MD5_IDX] >= 0); + ssl_digest_methods[SSL_MD_SHA1_IDX] = + EVP_get_digestbyname(SN_sha1); + ssl_mac_secret_size[SSL_MD_SHA1_IDX] = + EVP_MD_size(ssl_digest_methods[SSL_MD_SHA1_IDX]); + OPENSSL_assert(ssl_mac_secret_size[SSL_MD_SHA1_IDX] >= 0); + ssl_digest_methods[SSL_MD_GOST94_IDX] = + EVP_get_digestbyname(SN_id_GostR3411_94); + if (ssl_digest_methods[SSL_MD_GOST94_IDX]) { + ssl_mac_secret_size[SSL_MD_GOST94_IDX] = + EVP_MD_size(ssl_digest_methods[SSL_MD_GOST94_IDX]); + OPENSSL_assert(ssl_mac_secret_size[SSL_MD_GOST94_IDX] >= 0); + } + ssl_digest_methods[SSL_MD_GOST89MAC_IDX] = + EVP_get_digestbyname(SN_id_Gost28147_89_MAC); + if (ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]) { + ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX] = 32; + } + + ssl_digest_methods[SSL_MD_SHA256_IDX] = + EVP_get_digestbyname(SN_sha256); + ssl_mac_secret_size[SSL_MD_SHA256_IDX] = + EVP_MD_size(ssl_digest_methods[SSL_MD_SHA256_IDX]); + ssl_digest_methods[SSL_MD_SHA384_IDX] = + EVP_get_digestbyname(SN_sha384); + ssl_mac_secret_size[SSL_MD_SHA384_IDX] = + EVP_MD_size(ssl_digest_methods[SSL_MD_SHA384_IDX]); + ssl_digest_methods[SSL_MD_STREEBOG256_IDX] = + EVP_get_digestbyname(SN_id_tc26_gost3411_2012_256); + ssl_mac_secret_size[SSL_MD_STREEBOG256_IDX] = + EVP_MD_size(ssl_digest_methods[SSL_MD_STREEBOG256_IDX]); + ssl_digest_methods[SSL_MD_STREEBOG512_IDX] = + EVP_get_digestbyname(SN_id_tc26_gost3411_2012_512); + ssl_mac_secret_size[SSL_MD_STREEBOG512_IDX] = + EVP_MD_size(ssl_digest_methods[SSL_MD_STREEBOG512_IDX]); +} + +int +ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, + const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size) +{ + const SSL_CIPHER *c; + int i; + + c = s->cipher; + if (c == NULL) + return (0); + + /* + * This function does not handle EVP_AEAD. + * See ssl_cipher_get_aead_evp instead. + */ + if (c->algorithm2 & SSL_CIPHER_ALGORITHM2_AEAD) + return(0); + + if ((enc == NULL) || (md == NULL)) + return (0); + + switch (c->algorithm_enc) { + case SSL_DES: + i = SSL_ENC_DES_IDX; + break; + case SSL_3DES: + i = SSL_ENC_3DES_IDX; + break; + case SSL_RC4: + i = SSL_ENC_RC4_IDX; + break; + case SSL_IDEA: + i = SSL_ENC_IDEA_IDX; + break; + case SSL_eNULL: + i = SSL_ENC_NULL_IDX; + break; + case SSL_AES128: + i = SSL_ENC_AES128_IDX; + break; + case SSL_AES256: + i = SSL_ENC_AES256_IDX; + break; + case SSL_CAMELLIA128: + i = SSL_ENC_CAMELLIA128_IDX; + break; + case SSL_CAMELLIA256: + i = SSL_ENC_CAMELLIA256_IDX; + break; + case SSL_eGOST2814789CNT: + i = SSL_ENC_GOST89_IDX; + break; + case SSL_AES128GCM: + i = SSL_ENC_AES128GCM_IDX; + break; + case SSL_AES256GCM: + i = SSL_ENC_AES256GCM_IDX; + break; + default: + i = -1; + break; + } + + if ((i < 0) || (i >= SSL_ENC_NUM_IDX)) + *enc = NULL; + else { + if (i == SSL_ENC_NULL_IDX) + *enc = EVP_enc_null(); + else + *enc = ssl_cipher_methods[i]; + } + + switch (c->algorithm_mac) { + case SSL_MD5: + i = SSL_MD_MD5_IDX; + break; + case SSL_SHA1: + i = SSL_MD_SHA1_IDX; + break; + case SSL_SHA256: + i = SSL_MD_SHA256_IDX; + break; + case SSL_SHA384: + i = SSL_MD_SHA384_IDX; + break; + case SSL_GOST94: + i = SSL_MD_GOST94_IDX; + break; + case SSL_GOST89MAC: + i = SSL_MD_GOST89MAC_IDX; + break; + case SSL_STREEBOG256: + i = SSL_MD_STREEBOG256_IDX; + break; + case SSL_STREEBOG512: + i = SSL_MD_STREEBOG512_IDX; + break; + default: + i = -1; + break; + } + if ((i < 0) || (i >= SSL_MD_NUM_IDX)) { + *md = NULL; + + if (mac_pkey_type != NULL) + *mac_pkey_type = NID_undef; + if (mac_secret_size != NULL) + *mac_secret_size = 0; + if (c->algorithm_mac == SSL_AEAD) + mac_pkey_type = NULL; + } else { + *md = ssl_digest_methods[i]; + if (mac_pkey_type != NULL) + *mac_pkey_type = ssl_mac_pkey_id[i]; + if (mac_secret_size != NULL) + *mac_secret_size = ssl_mac_secret_size[i]; + } + + if ((*enc != NULL) && + (*md != NULL || (EVP_CIPHER_flags(*enc)&EVP_CIPH_FLAG_AEAD_CIPHER)) && + (!mac_pkey_type || *mac_pkey_type != NID_undef)) { + const EVP_CIPHER *evp; + + if (s->ssl_version >> 8 != TLS1_VERSION_MAJOR || + s->ssl_version < TLS1_VERSION) + return 1; + + if (c->algorithm_enc == SSL_RC4 && + c->algorithm_mac == SSL_MD5 && + (evp = EVP_get_cipherbyname("RC4-HMAC-MD5"))) + *enc = evp, *md = NULL; + else if (c->algorithm_enc == SSL_AES128 && + c->algorithm_mac == SSL_SHA1 && + (evp = EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA1"))) + *enc = evp, *md = NULL; + else if (c->algorithm_enc == SSL_AES256 && + c->algorithm_mac == SSL_SHA1 && + (evp = EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1"))) + *enc = evp, *md = NULL; + return (1); + } else + return (0); +} + +/* + * ssl_cipher_get_evp_aead sets aead to point to the correct EVP_AEAD object + * for s->cipher. It returns 1 on success and 0 on error. + */ +int +ssl_cipher_get_evp_aead(const SSL_SESSION *s, const EVP_AEAD **aead) +{ + const SSL_CIPHER *c = s->cipher; + + *aead = NULL; + + if (c == NULL) + return 0; + if ((c->algorithm2 & SSL_CIPHER_ALGORITHM2_AEAD) == 0) + return 0; + + switch (c->algorithm_enc) { +#ifndef OPENSSL_NO_AES + case SSL_AES128GCM: + *aead = EVP_aead_aes_128_gcm(); + return 1; + case SSL_AES256GCM: + *aead = EVP_aead_aes_256_gcm(); + return 1; +#endif +#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) + case SSL_CHACHA20POLY1305: + *aead = EVP_aead_chacha20_poly1305(); + return 1; + case SSL_CHACHA20POLY1305_OLD: + *aead = EVP_aead_chacha20_poly1305_old(); + return 1; +#endif + default: + break; + } + return 0; +} + +int +ssl_get_handshake_digest(int idx, long *mask, const EVP_MD **md) +{ + if (idx < 0 || idx >= SSL_MD_NUM_IDX) { + return 0; + } + *mask = ssl_handshake_digest_flag[idx]; + if (*mask) + *md = ssl_digest_methods[idx]; + else + *md = NULL; + return 1; +} + +#define ITEM_SEP(a) \ + (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ',')) + +static void +ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr, + CIPHER_ORDER **tail) +{ + if (curr == *tail) + return; + if (curr == *head) + *head = curr->next; + if (curr->prev != NULL) + curr->prev->next = curr->next; + if (curr->next != NULL) + curr->next->prev = curr->prev; + (*tail)->next = curr; + curr->prev= *tail; + curr->next = NULL; + *tail = curr; +} + +static void +ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr, + CIPHER_ORDER **tail) +{ + if (curr == *head) + return; + if (curr == *tail) + *tail = curr->prev; + if (curr->next != NULL) + curr->next->prev = curr->prev; + if (curr->prev != NULL) + curr->prev->next = curr->next; + (*head)->prev = curr; + curr->next= *head; + curr->prev = NULL; + *head = curr; +} + +static void +ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, + unsigned long *enc, unsigned long *mac, unsigned long *ssl) +{ + *mkey = 0; + *auth = 0; + *enc = 0; + *mac = 0; + *ssl = 0; + + /* + * Check for the availability of GOST 34.10 public/private key + * algorithms. If they are not available disable the associated + * authentication and key exchange algorithms. + */ + if (EVP_PKEY_meth_find(NID_id_GostR3410_2001) == NULL) { + *auth |= SSL_aGOST01; + *mkey |= SSL_kGOST; + } + +#ifdef SSL_FORBID_ENULL + *enc |= SSL_eNULL; +#endif + + *enc |= (ssl_cipher_methods[SSL_ENC_DES_IDX ] == NULL) ? SSL_DES : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_RC4_IDX ] == NULL) ? SSL_RC4 : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES128 : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_AES256_IDX] == NULL) ? SSL_AES256 : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_AES128GCM_IDX] == NULL) ? SSL_AES128GCM : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_AES256GCM_IDX] == NULL) ? SSL_AES256GCM : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == NULL) ? SSL_CAMELLIA128 : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] == NULL) ? SSL_CAMELLIA256 : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_GOST89_IDX] == NULL) ? SSL_eGOST2814789CNT : 0; + + *mac |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 : 0; + *mac |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1 : 0; + *mac |= (ssl_digest_methods[SSL_MD_SHA256_IDX] == NULL) ? SSL_SHA256 : 0; + *mac |= (ssl_digest_methods[SSL_MD_SHA384_IDX] == NULL) ? SSL_SHA384 : 0; + *mac |= (ssl_digest_methods[SSL_MD_GOST94_IDX] == NULL) ? SSL_GOST94 : 0; + *mac |= (ssl_digest_methods[SSL_MD_GOST89MAC_IDX] == NULL) ? SSL_GOST89MAC : 0; + *mac |= (ssl_digest_methods[SSL_MD_STREEBOG256_IDX] == NULL) ? SSL_STREEBOG256 : 0; + *mac |= (ssl_digest_methods[SSL_MD_STREEBOG512_IDX] == NULL) ? SSL_STREEBOG512 : 0; + +} + +static void +ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, int num_of_ciphers, + unsigned long disabled_mkey, unsigned long disabled_auth, + unsigned long disabled_enc, unsigned long disabled_mac, + unsigned long disabled_ssl, CIPHER_ORDER *co_list, + CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) +{ + int i, co_list_num; + const SSL_CIPHER *c; + + /* + * We have num_of_ciphers descriptions compiled in, depending on the + * method selected (SSLv3, TLSv1, etc). These will later be sorted in + * a linked list with at most num entries. + */ + + /* Get the initial list of ciphers */ + co_list_num = 0; /* actual count of ciphers */ + for (i = 0; i < num_of_ciphers; i++) { + c = ssl_method->get_cipher(i); + /* drop those that use any of that is not available */ + if ((c != NULL) && c->valid && + !(c->algorithm_mkey & disabled_mkey) && + !(c->algorithm_auth & disabled_auth) && + !(c->algorithm_enc & disabled_enc) && + !(c->algorithm_mac & disabled_mac) && + !(c->algorithm_ssl & disabled_ssl)) { + co_list[co_list_num].cipher = c; + co_list[co_list_num].next = NULL; + co_list[co_list_num].prev = NULL; + co_list[co_list_num].active = 0; + co_list_num++; + /* + if (!sk_push(ca_list,(char *)c)) goto err; + */ + } + } + + /* + * Prepare linked list from list entries + */ + if (co_list_num > 0) { + co_list[0].prev = NULL; + + if (co_list_num > 1) { + co_list[0].next = &co_list[1]; + + for (i = 1; i < co_list_num - 1; i++) { + co_list[i].prev = &co_list[i - 1]; + co_list[i].next = &co_list[i + 1]; + } + + co_list[co_list_num - 1].prev = + &co_list[co_list_num - 2]; + } + + co_list[co_list_num - 1].next = NULL; + + *head_p = &co_list[0]; + *tail_p = &co_list[co_list_num - 1]; + } +} + +static void +ssl_cipher_collect_aliases(const SSL_CIPHER **ca_list, int num_of_group_aliases, + unsigned long disabled_mkey, unsigned long disabled_auth, + unsigned long disabled_enc, unsigned long disabled_mac, + unsigned long disabled_ssl, CIPHER_ORDER *head) +{ + CIPHER_ORDER *ciph_curr; + const SSL_CIPHER **ca_curr; + int i; + unsigned long mask_mkey = ~disabled_mkey; + unsigned long mask_auth = ~disabled_auth; + unsigned long mask_enc = ~disabled_enc; + unsigned long mask_mac = ~disabled_mac; + unsigned long mask_ssl = ~disabled_ssl; + + /* + * First, add the real ciphers as already collected + */ + ciph_curr = head; + ca_curr = ca_list; + while (ciph_curr != NULL) { + *ca_curr = ciph_curr->cipher; + ca_curr++; + ciph_curr = ciph_curr->next; + } + + /* + * Now we add the available ones from the cipher_aliases[] table. + * They represent either one or more algorithms, some of which + * in any affected category must be supported (set in enabled_mask), + * or represent a cipher strength value (will be added in any case because algorithms=0). + */ + for (i = 0; i < num_of_group_aliases; i++) { + unsigned long algorithm_mkey = cipher_aliases[i].algorithm_mkey; + unsigned long algorithm_auth = cipher_aliases[i].algorithm_auth; + unsigned long algorithm_enc = cipher_aliases[i].algorithm_enc; + unsigned long algorithm_mac = cipher_aliases[i].algorithm_mac; + unsigned long algorithm_ssl = cipher_aliases[i].algorithm_ssl; + + if (algorithm_mkey) + if ((algorithm_mkey & mask_mkey) == 0) + continue; + + if (algorithm_auth) + if ((algorithm_auth & mask_auth) == 0) + continue; + + if (algorithm_enc) + if ((algorithm_enc & mask_enc) == 0) + continue; + + if (algorithm_mac) + if ((algorithm_mac & mask_mac) == 0) + continue; + + if (algorithm_ssl) + if ((algorithm_ssl & mask_ssl) == 0) + continue; + + *ca_curr = (SSL_CIPHER *)(cipher_aliases + i); + ca_curr++; + } + + *ca_curr = NULL; /* end of list */ +} + +static void +ssl_cipher_apply_rule(unsigned long cipher_id, unsigned long alg_mkey, + unsigned long alg_auth, unsigned long alg_enc, unsigned long alg_mac, + unsigned long alg_ssl, unsigned long algo_strength, + int rule, int strength_bits, CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) +{ + CIPHER_ORDER *head, *tail, *curr, *next, *last; + const SSL_CIPHER *cp; + int reverse = 0; + + + if (rule == CIPHER_DEL) + reverse = 1; /* needed to maintain sorting between currently deleted ciphers */ + + head = *head_p; + tail = *tail_p; + + if (reverse) { + next = tail; + last = head; + } else { + next = head; + last = tail; + } + + curr = NULL; + for (;;) { + if (curr == last) + break; + curr = next; + next = reverse ? curr->prev : curr->next; + + cp = curr->cipher; + + /* + * Selection criteria is either the value of strength_bits + * or the algorithms used. + */ + if (strength_bits >= 0) { + if (strength_bits != cp->strength_bits) + continue; + } else { + + if (alg_mkey && !(alg_mkey & cp->algorithm_mkey)) + continue; + if (alg_auth && !(alg_auth & cp->algorithm_auth)) + continue; + if (alg_enc && !(alg_enc & cp->algorithm_enc)) + continue; + if (alg_mac && !(alg_mac & cp->algorithm_mac)) + continue; + if (alg_ssl && !(alg_ssl & cp->algorithm_ssl)) + continue; + if ((algo_strength & SSL_STRONG_MASK) && !(algo_strength & SSL_STRONG_MASK & cp->algo_strength)) + continue; + } + + + /* add the cipher if it has not been added yet. */ + if (rule == CIPHER_ADD) { + /* reverse == 0 */ + if (!curr->active) { + ll_append_tail(&head, curr, &tail); + curr->active = 1; + } + } + /* Move the added cipher to this location */ + else if (rule == CIPHER_ORD) { + /* reverse == 0 */ + if (curr->active) { + ll_append_tail(&head, curr, &tail); + } + } else if (rule == CIPHER_DEL) { + /* reverse == 1 */ + if (curr->active) { + /* most recently deleted ciphersuites get best positions + * for any future CIPHER_ADD (note that the CIPHER_DEL loop + * works in reverse to maintain the order) */ + ll_append_head(&head, curr, &tail); + curr->active = 0; + } + } else if (rule == CIPHER_KILL) { + /* reverse == 0 */ + if (head == curr) + head = curr->next; + else + curr->prev->next = curr->next; + if (tail == curr) + tail = curr->prev; + curr->active = 0; + if (curr->next != NULL) + curr->next->prev = curr->prev; + if (curr->prev != NULL) + curr->prev->next = curr->next; + curr->next = NULL; + curr->prev = NULL; + } + } + + *head_p = head; + *tail_p = tail; +} + +static int +ssl_cipher_strength_sort(CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) +{ + int max_strength_bits, i, *number_uses; + CIPHER_ORDER *curr; + + /* + * This routine sorts the ciphers with descending strength. The sorting + * must keep the pre-sorted sequence, so we apply the normal sorting + * routine as '+' movement to the end of the list. + */ + max_strength_bits = 0; + curr = *head_p; + while (curr != NULL) { + if (curr->active && + (curr->cipher->strength_bits > max_strength_bits)) + max_strength_bits = curr->cipher->strength_bits; + curr = curr->next; + } + + number_uses = calloc((max_strength_bits + 1), sizeof(int)); + if (!number_uses) { + SSLerr(SSL_F_SSL_CIPHER_STRENGTH_SORT, ERR_R_MALLOC_FAILURE); + return (0); + } + + /* + * Now find the strength_bits values actually used + */ + curr = *head_p; + while (curr != NULL) { + if (curr->active) + number_uses[curr->cipher->strength_bits]++; + curr = curr->next; + } + /* + * Go through the list of used strength_bits values in descending + * order. + */ + for (i = max_strength_bits; i >= 0; i--) + if (number_uses[i] > 0) + ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, head_p, tail_p); + + free(number_uses); + return (1); +} + +static int +ssl_cipher_process_rulestr(const char *rule_str, CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p, const SSL_CIPHER **ca_list) +{ + unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl; + unsigned long algo_strength; + int j, multi, found, rule, retval, ok, buflen; + unsigned long cipher_id = 0; + const char *l, *buf; + char ch; + + retval = 1; + l = rule_str; + for (;;) { + ch = *l; + + if (ch == '\0') + break; + + if (ch == '-') { + rule = CIPHER_DEL; + l++; + } else if (ch == '+') { + rule = CIPHER_ORD; + l++; + } else if (ch == '!') { + rule = CIPHER_KILL; + l++; + } else if (ch == '@') { + rule = CIPHER_SPECIAL; + l++; + } else { + rule = CIPHER_ADD; + } + + if (ITEM_SEP(ch)) { + l++; + continue; + } + + alg_mkey = 0; + alg_auth = 0; + alg_enc = 0; + alg_mac = 0; + alg_ssl = 0; + algo_strength = 0; + + for (;;) { + ch = *l; + buf = l; + buflen = 0; + while (((ch >= 'A') && (ch <= 'Z')) || + ((ch >= '0') && (ch <= '9')) || + ((ch >= 'a') && (ch <= 'z')) || + (ch == '-') || (ch == '.')) { + ch = *(++l); + buflen++; + } + + if (buflen == 0) { + /* + * We hit something we cannot deal with, + * it is no command or separator nor + * alphanumeric, so we call this an error. + */ + SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, + SSL_R_INVALID_COMMAND); + retval = found = 0; + l++; + break; + } + + if (rule == CIPHER_SPECIAL) { + /* unused -- avoid compiler warning */ + found = 0; + /* special treatment */ + break; + } + + /* check for multi-part specification */ + if (ch == '+') { + multi = 1; + l++; + } else + multi = 0; + + /* + * Now search for the cipher alias in the ca_list. + * Be careful with the strncmp, because the "buflen" + * limitation will make the rule "ADH:SOME" and the + * cipher "ADH-MY-CIPHER" look like a match for + * buflen=3. So additionally check whether the cipher + * name found has the correct length. We can save a + * strlen() call: just checking for the '\0' at the + * right place is sufficient, we have to strncmp() + * anyway (we cannot use strcmp(), because buf is not + * '\0' terminated.) + */ + j = found = 0; + cipher_id = 0; + while (ca_list[j]) { + if (!strncmp(buf, ca_list[j]->name, buflen) && + (ca_list[j]->name[buflen] == '\0')) { + found = 1; + break; + } else + j++; + } + + if (!found) + break; /* ignore this entry */ + + if (ca_list[j]->algorithm_mkey) { + if (alg_mkey) { + alg_mkey &= ca_list[j]->algorithm_mkey; + if (!alg_mkey) { + found = 0; + break; + } + } else + alg_mkey = ca_list[j]->algorithm_mkey; + } + + if (ca_list[j]->algorithm_auth) { + if (alg_auth) { + alg_auth &= ca_list[j]->algorithm_auth; + if (!alg_auth) { + found = 0; + break; + } + } else + alg_auth = ca_list[j]->algorithm_auth; + } + + if (ca_list[j]->algorithm_enc) { + if (alg_enc) { + alg_enc &= ca_list[j]->algorithm_enc; + if (!alg_enc) { + found = 0; + break; + } + } else + alg_enc = ca_list[j]->algorithm_enc; + } + + if (ca_list[j]->algorithm_mac) { + if (alg_mac) { + alg_mac &= ca_list[j]->algorithm_mac; + if (!alg_mac) { + found = 0; + break; + } + } else + alg_mac = ca_list[j]->algorithm_mac; + } + + if (ca_list[j]->algo_strength & SSL_STRONG_MASK) { + if (algo_strength & SSL_STRONG_MASK) { + algo_strength &= + (ca_list[j]->algo_strength & + SSL_STRONG_MASK) | ~SSL_STRONG_MASK; + if (!(algo_strength & + SSL_STRONG_MASK)) { + found = 0; + break; + } + } else + algo_strength |= + ca_list[j]->algo_strength & + SSL_STRONG_MASK; + } + + if (ca_list[j]->valid) { + /* + * explicit ciphersuite found; its protocol + * version does not become part of the search + * pattern! + */ + cipher_id = ca_list[j]->id; + } else { + /* + * not an explicit ciphersuite; only in this + * case, the protocol version is considered + * part of the search pattern + */ + if (ca_list[j]->algorithm_ssl) { + if (alg_ssl) { + alg_ssl &= + ca_list[j]->algorithm_ssl; + if (!alg_ssl) { + found = 0; + break; + } + } else + alg_ssl = + ca_list[j]->algorithm_ssl; + } + } + + if (!multi) + break; + } + + /* + * Ok, we have the rule, now apply it + */ + if (rule == CIPHER_SPECIAL) { + /* special command */ + ok = 0; + if ((buflen == 8) && !strncmp(buf, "STRENGTH", 8)) + ok = ssl_cipher_strength_sort(head_p, tail_p); + else + SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, + SSL_R_INVALID_COMMAND); + if (ok == 0) + retval = 0; + /* + * We do not support any "multi" options + * together with "@", so throw away the + * rest of the command, if any left, until + * end or ':' is found. + */ + while ((*l != '\0') && !ITEM_SEP(*l)) + l++; + } else if (found) { + ssl_cipher_apply_rule(cipher_id, alg_mkey, alg_auth, + alg_enc, alg_mac, alg_ssl, algo_strength, rule, + -1, head_p, tail_p); + } else { + while ((*l != '\0') && !ITEM_SEP(*l)) + l++; + } + if (*l == '\0') + break; /* done */ + } + + return (retval); +} + +static inline int +ssl_aes_is_accelerated(void) +{ +#if defined(__i386__) || defined(__x86_64__) + return ((OPENSSL_cpu_caps() & (1ULL << 57)) != 0); +#else + return (0); +#endif +} + +STACK_OF(SSL_CIPHER) * +ssl_create_cipher_list(const SSL_METHOD *ssl_method, + STACK_OF(SSL_CIPHER) **cipher_list, + STACK_OF(SSL_CIPHER) **cipher_list_by_id, + const char *rule_str) +{ + int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases; + unsigned long disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl; + STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list; + const char *rule_p; + CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr; + const SSL_CIPHER **ca_list = NULL; + + /* + * Return with error if nothing to do. + */ + if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL) + return NULL; + + /* + * To reduce the work to do we only want to process the compiled + * in algorithms, so we first get the mask of disabled ciphers. + */ + ssl_cipher_get_disabled(&disabled_mkey, &disabled_auth, &disabled_enc, &disabled_mac, &disabled_ssl); + + /* + * Now we have to collect the available ciphers from the compiled + * in ciphers. We cannot get more than the number compiled in, so + * it is used for allocation. + */ + num_of_ciphers = ssl_method->num_ciphers(); + co_list = reallocarray(NULL, num_of_ciphers, sizeof(CIPHER_ORDER)); + if (co_list == NULL) { + SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + return(NULL); /* Failure */ + } + + ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, + disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl, + co_list, &head, &tail); + + + /* Now arrange all ciphers by preference: */ + + /* Everything else being equal, prefer ephemeral ECDH over other key exchange mechanisms */ + ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail); + ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail); + + if (ssl_aes_is_accelerated() == 1) { + /* + * We have hardware assisted AES - prefer AES as a symmetric + * cipher, with CHACHA20 second. + */ + ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0, + CIPHER_ADD, -1, &head, &tail); + ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305, + 0, 0, 0, CIPHER_ADD, -1, &head, &tail); + ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305_OLD, + 0, 0, 0, CIPHER_ADD, -1, &head, &tail); + } else { + /* + * CHACHA20 is fast and safe on all hardware and is thus our + * preferred symmetric cipher, with AES second. + */ + ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305, + 0, 0, 0, CIPHER_ADD, -1, &head, &tail); + ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305_OLD, + 0, 0, 0, CIPHER_ADD, -1, &head, &tail); + ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0, + CIPHER_ADD, -1, &head, &tail); + } + + /* Temporarily enable everything else for sorting */ + ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail); + + /* Low priority for MD5 */ + ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head, &tail); + + /* Move anonymous ciphers to the end. Usually, these will remain disabled. + * (For applications that allow them, they aren't too bad, but we prefer + * authenticated ciphers.) */ + ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); + + /* Move ciphers without forward secrecy to the end */ + ssl_cipher_apply_rule(0, 0, SSL_aECDH, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); + ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); + + /* RC4 is sort of broken - move it to the end */ + ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); + + /* Now sort by symmetric encryption strength. The above ordering remains + * in force within each class */ + if (!ssl_cipher_strength_sort(&head, &tail)) { + free(co_list); + return NULL; + } + + /* Now disable everything (maintaining the ordering!) */ + ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail); + + + /* + * We also need cipher aliases for selecting based on the rule_str. + * There might be two types of entries in the rule_str: 1) names + * of ciphers themselves 2) aliases for groups of ciphers. + * For 1) we need the available ciphers and for 2) the cipher + * groups of cipher_aliases added together in one list (otherwise + * we would be happy with just the cipher_aliases table). + */ + num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER); + num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1; + ca_list = reallocarray(NULL, num_of_alias_max, sizeof(SSL_CIPHER *)); + if (ca_list == NULL) { + free(co_list); + SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + return(NULL); /* Failure */ + } + ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, + disabled_mkey, disabled_auth, disabled_enc, + disabled_mac, disabled_ssl, head); + + /* + * If the rule_string begins with DEFAULT, apply the default rule + * before using the (possibly available) additional rules. + */ + ok = 1; + rule_p = rule_str; + if (strncmp(rule_str, "DEFAULT", 7) == 0) { + ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST, + &head, &tail, ca_list); + rule_p += 7; + if (*rule_p == ':') + rule_p++; + } + + if (ok && (strlen(rule_p) > 0)) + ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list); + + free((void *)ca_list); /* Not needed anymore */ + + if (!ok) { + /* Rule processing failure */ + free(co_list); + return (NULL); + } + + /* + * Allocate new "cipherstack" for the result, return with error + * if we cannot get one. + */ + if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) { + free(co_list); + return (NULL); + } + + /* + * The cipher selection for the list is done. The ciphers are added + * to the resulting precedence to the STACK_OF(SSL_CIPHER). + */ + for (curr = head; curr != NULL; curr = curr->next) { + if (curr->active) { + sk_SSL_CIPHER_push(cipherstack, curr->cipher); + } + } + free(co_list); /* Not needed any longer */ + + tmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack); + if (tmp_cipher_list == NULL) { + sk_SSL_CIPHER_free(cipherstack); + return NULL; + } + if (*cipher_list != NULL) + sk_SSL_CIPHER_free(*cipher_list); + *cipher_list = cipherstack; + if (*cipher_list_by_id != NULL) + sk_SSL_CIPHER_free(*cipher_list_by_id); + *cipher_list_by_id = tmp_cipher_list; + (void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id, + ssl_cipher_ptr_id_cmp); + + sk_SSL_CIPHER_sort(*cipher_list_by_id); + return (cipherstack); +} + +const SSL_CIPHER * +SSL_CIPHER_get_by_id(unsigned int id) +{ + return ssl3_get_cipher_by_id(id); +} + +const SSL_CIPHER * +SSL_CIPHER_get_by_value(uint16_t value) +{ + return ssl3_get_cipher_by_value(value); +} + +char * +SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) +{ + unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, alg2; + const char *ver, *kx, *au, *enc, *mac; + char *ret; + int l; + + alg_mkey = cipher->algorithm_mkey; + alg_auth = cipher->algorithm_auth; + alg_enc = cipher->algorithm_enc; + alg_mac = cipher->algorithm_mac; + alg_ssl = cipher->algorithm_ssl; + + alg2 = cipher->algorithm2; + + if (alg_ssl & SSL_SSLV3) + ver = "SSLv3"; + else if (alg_ssl & SSL_TLSV1_2) + ver = "TLSv1.2"; + else + ver = "unknown"; + + switch (alg_mkey) { + case SSL_kRSA: + kx = "RSA"; + break; + case SSL_kDHE: + kx = "DH"; + break; + case SSL_kECDHr: + kx = "ECDH/RSA"; + break; + case SSL_kECDHe: + kx = "ECDH/ECDSA"; + break; + case SSL_kECDHE: + kx = "ECDH"; + break; + case SSL_kGOST: + kx = "GOST"; + break; + default: + kx = "unknown"; + } + + switch (alg_auth) { + case SSL_aRSA: + au = "RSA"; + break; + case SSL_aDSS: + au = "DSS"; + break; + case SSL_aECDH: + au = "ECDH"; + break; + case SSL_aNULL: + au = "None"; + break; + case SSL_aECDSA: + au = "ECDSA"; + break; + case SSL_aGOST01: + au = "GOST01"; + break; + default: + au = "unknown"; + break; + } + + switch (alg_enc) { + case SSL_DES: + enc = "DES(56)"; + break; + case SSL_3DES: + enc = "3DES(168)"; + break; + case SSL_RC4: + enc = alg2 & SSL2_CF_8_BYTE_ENC ? "RC4(64)" : "RC4(128)"; + break; + case SSL_IDEA: + enc = "IDEA(128)"; + break; + case SSL_eNULL: + enc = "None"; + break; + case SSL_AES128: + enc = "AES(128)"; + break; + case SSL_AES256: + enc = "AES(256)"; + break; + case SSL_AES128GCM: + enc = "AESGCM(128)"; + break; + case SSL_AES256GCM: + enc = "AESGCM(256)"; + break; + case SSL_CAMELLIA128: + enc = "Camellia(128)"; + break; + case SSL_CAMELLIA256: + enc = "Camellia(256)"; + break; + case SSL_CHACHA20POLY1305: + enc = "ChaCha20-Poly1305"; + break; + case SSL_CHACHA20POLY1305_OLD: + enc = "ChaCha20-Poly1305-Old"; + break; + case SSL_eGOST2814789CNT: + enc = "GOST-28178-89-CNT"; + break; + default: + enc = "unknown"; + break; + } + + switch (alg_mac) { + case SSL_MD5: + mac = "MD5"; + break; + case SSL_SHA1: + mac = "SHA1"; + break; + case SSL_SHA256: + mac = "SHA256"; + break; + case SSL_SHA384: + mac = "SHA384"; + break; + case SSL_AEAD: + mac = "AEAD"; + break; + case SSL_GOST94: + mac = "GOST94"; + break; + case SSL_GOST89MAC: + mac = "GOST89IMIT"; + break; + case SSL_STREEBOG256: + mac = "STREEBOG256"; + break; + case SSL_STREEBOG512: + mac = "STREEBOG512"; + break; + default: + mac = "unknown"; + break; + } + + if (asprintf(&ret, "%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n", + cipher->name, ver, kx, au, enc, mac) == -1) + return "OPENSSL_malloc Error"; + + if (buf != NULL) { + l = strlcpy(buf, ret, len); + free(ret); + ret = buf; + if (l >= len) + ret = "Buffer too small"; + } + + return (ret); +} + +char * +SSL_CIPHER_get_version(const SSL_CIPHER *c) +{ + if (c == NULL) + return("(NONE)"); + if ((c->id >> 24) == 3) + return("TLSv1/SSLv3"); + else + return("unknown"); +} + +/* return the actual cipher being used */ +const char * +SSL_CIPHER_get_name(const SSL_CIPHER *c) +{ + if (c != NULL) + return (c->name); + return("(NONE)"); +} + +/* number of bits for symmetric cipher */ +int +SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits) +{ + int ret = 0; + + if (c != NULL) { + if (alg_bits != NULL) + *alg_bits = c->alg_bits; + ret = c->strength_bits; + } + return (ret); +} + +unsigned long +SSL_CIPHER_get_id(const SSL_CIPHER *c) +{ + return c->id; +} + +uint16_t +SSL_CIPHER_get_value(const SSL_CIPHER *c) +{ + return ssl3_cipher_get_value(c); +} + +void * +SSL_COMP_get_compression_methods(void) +{ + return NULL; +} + +int +SSL_COMP_add_compression_method(int id, void *cm) +{ + return 1; +} + +const char * +SSL_COMP_get_name(const void *comp) +{ + return NULL; +} diff --git a/crypto/libressl/ssl/ssl_err.c b/crypto/libressl/ssl/ssl_err.c new file mode 100644 index 0000000000..00c537ae17 --- /dev/null +++ b/crypto/libressl/ssl/ssl_err.c @@ -0,0 +1,615 @@ +/* $OpenBSD: ssl_err.c,v 1.28 2014/12/14 15:30:50 jsing Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include + +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_SSL,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_SSL,0,reason) + +static ERR_STRING_DATA SSL_str_functs[]= { + {ERR_FUNC(SSL_F_CLIENT_CERTIFICATE), "CLIENT_CERTIFICATE"}, + {ERR_FUNC(SSL_F_CLIENT_FINISHED), "CLIENT_FINISHED"}, + {ERR_FUNC(SSL_F_CLIENT_HELLO), "CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_CLIENT_MASTER_KEY), "CLIENT_MASTER_KEY"}, + {ERR_FUNC(SSL_F_D2I_SSL_SESSION), "d2i_SSL_SESSION"}, + {ERR_FUNC(SSL_F_DO_DTLS1_WRITE), "DO_DTLS1_WRITE"}, + {ERR_FUNC(SSL_F_DO_SSL3_WRITE), "DO_SSL3_WRITE"}, + {ERR_FUNC(SSL_F_DTLS1_ACCEPT), "DTLS1_ACCEPT"}, + {ERR_FUNC(SSL_F_DTLS1_ADD_CERT_TO_BUF), "DTLS1_ADD_CERT_TO_BUF"}, + {ERR_FUNC(SSL_F_DTLS1_BUFFER_RECORD), "DTLS1_BUFFER_RECORD"}, + {ERR_FUNC(SSL_F_DTLS1_CHECK_TIMEOUT_NUM), "DTLS1_CHECK_TIMEOUT_NUM"}, + {ERR_FUNC(SSL_F_DTLS1_CLIENT_HELLO), "DTLS1_CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_DTLS1_CONNECT), "DTLS1_CONNECT"}, + {ERR_FUNC(SSL_F_DTLS1_ENC), "DTLS1_ENC"}, + {ERR_FUNC(SSL_F_DTLS1_GET_HELLO_VERIFY), "DTLS1_GET_HELLO_VERIFY"}, + {ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE), "DTLS1_GET_MESSAGE"}, + {ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT), "DTLS1_GET_MESSAGE_FRAGMENT"}, + {ERR_FUNC(SSL_F_DTLS1_GET_RECORD), "DTLS1_GET_RECORD"}, + {ERR_FUNC(SSL_F_DTLS1_HANDLE_TIMEOUT), "DTLS1_HANDLE_TIMEOUT"}, + {ERR_FUNC(SSL_F_DTLS1_HEARTBEAT), "DTLS1_HEARTBEAT"}, + {ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN), "DTLS1_OUTPUT_CERT_CHAIN"}, + {ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "DTLS1_PREPROCESS_FRAGMENT"}, + {ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE), "DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"}, + {ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD), "DTLS1_PROCESS_RECORD"}, + {ERR_FUNC(SSL_F_DTLS1_READ_BYTES), "DTLS1_READ_BYTES"}, + {ERR_FUNC(SSL_F_DTLS1_READ_FAILED), "DTLS1_READ_FAILED"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST), "DTLS1_SEND_CERTIFICATE_REQUEST"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE), "DTLS1_SEND_CLIENT_CERTIFICATE"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE), "DTLS1_SEND_CLIENT_KEY_EXCHANGE"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_VERIFY), "DTLS1_SEND_CLIENT_VERIFY"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST), "DTLS1_SEND_HELLO_VERIFY_REQUEST"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE), "DTLS1_SEND_SERVER_CERTIFICATE"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_HELLO), "DTLS1_SEND_SERVER_HELLO"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE), "DTLS1_SEND_SERVER_KEY_EXCHANGE"}, + {ERR_FUNC(SSL_F_DTLS1_WRITE_APP_DATA_BYTES), "DTLS1_WRITE_APP_DATA_BYTES"}, + {ERR_FUNC(SSL_F_GET_CLIENT_FINISHED), "GET_CLIENT_FINISHED"}, + {ERR_FUNC(SSL_F_GET_CLIENT_HELLO), "GET_CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_GET_CLIENT_MASTER_KEY), "GET_CLIENT_MASTER_KEY"}, + {ERR_FUNC(SSL_F_GET_SERVER_FINISHED), "GET_SERVER_FINISHED"}, + {ERR_FUNC(SSL_F_GET_SERVER_HELLO), "GET_SERVER_HELLO"}, + {ERR_FUNC(SSL_F_GET_SERVER_VERIFY), "GET_SERVER_VERIFY"}, + {ERR_FUNC(SSL_F_I2D_SSL_SESSION), "i2d_SSL_SESSION"}, + {ERR_FUNC(SSL_F_READ_N), "READ_N"}, + {ERR_FUNC(SSL_F_REQUEST_CERTIFICATE), "REQUEST_CERTIFICATE"}, + {ERR_FUNC(SSL_F_SERVER_FINISH), "SERVER_FINISH"}, + {ERR_FUNC(SSL_F_SERVER_HELLO), "SERVER_HELLO"}, + {ERR_FUNC(SSL_F_SERVER_VERIFY), "SERVER_VERIFY"}, + {ERR_FUNC(SSL_F_SSL23_ACCEPT), "SSL23_ACCEPT"}, + {ERR_FUNC(SSL_F_SSL23_CLIENT_HELLO), "SSL23_CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_SSL23_CONNECT), "SSL23_CONNECT"}, + {ERR_FUNC(SSL_F_SSL23_GET_CLIENT_HELLO), "SSL23_GET_CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_SSL23_GET_SERVER_HELLO), "SSL23_GET_SERVER_HELLO"}, + {ERR_FUNC(SSL_F_SSL23_PEEK), "SSL23_PEEK"}, + {ERR_FUNC(SSL_F_SSL23_READ), "SSL23_READ"}, + {ERR_FUNC(SSL_F_SSL23_WRITE), "SSL23_WRITE"}, + {ERR_FUNC(SSL_F_SSL2_ACCEPT), "SSL2_ACCEPT"}, + {ERR_FUNC(SSL_F_SSL2_CONNECT), "SSL2_CONNECT"}, + {ERR_FUNC(SSL_F_SSL2_ENC_INIT), "SSL2_ENC_INIT"}, + {ERR_FUNC(SSL_F_SSL2_GENERATE_KEY_MATERIAL), "SSL2_GENERATE_KEY_MATERIAL"}, + {ERR_FUNC(SSL_F_SSL2_PEEK), "SSL2_PEEK"}, + {ERR_FUNC(SSL_F_SSL2_READ), "SSL2_READ"}, + {ERR_FUNC(SSL_F_SSL2_READ_INTERNAL), "SSL2_READ_INTERNAL"}, + {ERR_FUNC(SSL_F_SSL2_SET_CERTIFICATE), "SSL2_SET_CERTIFICATE"}, + {ERR_FUNC(SSL_F_SSL2_WRITE), "SSL2_WRITE"}, + {ERR_FUNC(SSL_F_SSL3_ACCEPT), "SSL3_ACCEPT"}, + {ERR_FUNC(SSL_F_SSL3_ADD_CERT_TO_BUF), "SSL3_ADD_CERT_TO_BUF"}, + {ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL), "SSL3_CALLBACK_CTRL"}, + {ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE), "SSL3_CHANGE_CIPHER_STATE"}, + {ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM), "SSL3_CHECK_CERT_AND_ALGORITHM"}, + {ERR_FUNC(SSL_F_SSL3_CHECK_CLIENT_HELLO), "SSL3_CHECK_CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_SSL3_CLIENT_HELLO), "SSL3_CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_SSL3_CONNECT), "SSL3_CONNECT"}, + {ERR_FUNC(SSL_F_SSL3_CTRL), "SSL3_CTRL"}, + {ERR_FUNC(SSL_F_SSL3_CTX_CTRL), "SSL3_CTX_CTRL"}, + {ERR_FUNC(SSL_F_SSL3_DIGEST_CACHED_RECORDS), "SSL3_DIGEST_CACHED_RECORDS"}, + {ERR_FUNC(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC), "SSL3_DO_CHANGE_CIPHER_SPEC"}, + {ERR_FUNC(SSL_F_SSL3_ENC), "SSL3_ENC"}, + {ERR_FUNC(SSL_F_SSL3_GENERATE_KEY_BLOCK), "SSL3_GENERATE_KEY_BLOCK"}, + {ERR_FUNC(SSL_F_SSL3_GET_CERTIFICATE_REQUEST), "SSL3_GET_CERTIFICATE_REQUEST"}, + {ERR_FUNC(SSL_F_SSL3_GET_CERT_STATUS), "SSL3_GET_CERT_STATUS"}, + {ERR_FUNC(SSL_F_SSL3_GET_CERT_VERIFY), "SSL3_GET_CERT_VERIFY"}, + {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_CERTIFICATE), "SSL3_GET_CLIENT_CERTIFICATE"}, + {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_HELLO), "SSL3_GET_CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE), "SSL3_GET_CLIENT_KEY_EXCHANGE"}, + {ERR_FUNC(SSL_F_SSL3_GET_FINISHED), "SSL3_GET_FINISHED"}, + {ERR_FUNC(SSL_F_SSL3_GET_KEY_EXCHANGE), "SSL3_GET_KEY_EXCHANGE"}, + {ERR_FUNC(SSL_F_SSL3_GET_MESSAGE), "SSL3_GET_MESSAGE"}, + {ERR_FUNC(SSL_F_SSL3_GET_NEW_SESSION_TICKET), "SSL3_GET_NEW_SESSION_TICKET"}, + {ERR_FUNC(SSL_F_SSL3_GET_NEXT_PROTO), "SSL3_GET_NEXT_PROTO"}, + {ERR_FUNC(SSL_F_SSL3_GET_RECORD), "SSL3_GET_RECORD"}, + {ERR_FUNC(SSL_F_SSL3_GET_SERVER_CERTIFICATE), "SSL3_GET_SERVER_CERTIFICATE"}, + {ERR_FUNC(SSL_F_SSL3_GET_SERVER_DONE), "SSL3_GET_SERVER_DONE"}, + {ERR_FUNC(SSL_F_SSL3_GET_SERVER_HELLO), "SSL3_GET_SERVER_HELLO"}, + {ERR_FUNC(SSL_F_SSL3_HANDSHAKE_MAC), "ssl3_handshake_mac"}, + {ERR_FUNC(SSL_F_SSL3_NEW_SESSION_TICKET), "SSL3_NEW_SESSION_TICKET"}, + {ERR_FUNC(SSL_F_SSL3_OUTPUT_CERT_CHAIN), "SSL3_OUTPUT_CERT_CHAIN"}, + {ERR_FUNC(SSL_F_SSL3_PEEK), "SSL3_PEEK"}, + {ERR_FUNC(SSL_F_SSL3_READ_BYTES), "SSL3_READ_BYTES"}, + {ERR_FUNC(SSL_F_SSL3_READ_N), "SSL3_READ_N"}, + {ERR_FUNC(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST), "SSL3_SEND_CERTIFICATE_REQUEST"}, + {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE), "SSL3_SEND_CLIENT_CERTIFICATE"}, + {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE), "SSL3_SEND_CLIENT_KEY_EXCHANGE"}, + {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_VERIFY), "SSL3_SEND_CLIENT_VERIFY"}, + {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_CERTIFICATE), "SSL3_SEND_SERVER_CERTIFICATE"}, + {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_HELLO), "SSL3_SEND_SERVER_HELLO"}, + {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE), "SSL3_SEND_SERVER_KEY_EXCHANGE"}, + {ERR_FUNC(SSL_F_SSL3_SETUP_KEY_BLOCK), "SSL3_SETUP_KEY_BLOCK"}, + {ERR_FUNC(SSL_F_SSL3_SETUP_READ_BUFFER), "SSL3_SETUP_READ_BUFFER"}, + {ERR_FUNC(SSL_F_SSL3_SETUP_WRITE_BUFFER), "SSL3_SETUP_WRITE_BUFFER"}, + {ERR_FUNC(SSL_F_SSL3_WRITE_BYTES), "SSL3_WRITE_BYTES"}, + {ERR_FUNC(SSL_F_SSL3_WRITE_PENDING), "SSL3_WRITE_PENDING"}, + {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT), "SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT"}, + {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT), "SSL_ADD_CLIENTHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT), "SSL_ADD_CLIENTHELLO_USE_SRTP_EXT"}, + {ERR_FUNC(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK), "SSL_add_dir_cert_subjects_to_stack"}, + {ERR_FUNC(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK), "SSL_add_file_cert_subjects_to_stack"}, + {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT), "SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT"}, + {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT), "SSL_ADD_SERVERHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT), "SSL_ADD_SERVERHELLO_USE_SRTP_EXT"}, + {ERR_FUNC(SSL_F_SSL_BAD_METHOD), "SSL_BAD_METHOD"}, + {ERR_FUNC(SSL_F_SSL_BYTES_TO_CIPHER_LIST), "SSL_BYTES_TO_CIPHER_LIST"}, + {ERR_FUNC(SSL_F_SSL_CERT_DUP), "SSL_CERT_DUP"}, + {ERR_FUNC(SSL_F_SSL_CERT_INST), "SSL_CERT_INST"}, + {ERR_FUNC(SSL_F_SSL_CERT_INSTANTIATE), "SSL_CERT_INSTANTIATE"}, + {ERR_FUNC(SSL_F_SSL_CERT_NEW), "SSL_CERT_NEW"}, + {ERR_FUNC(SSL_F_SSL_CHECK_PRIVATE_KEY), "SSL_check_private_key"}, + {ERR_FUNC(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT), "SSL_CHECK_SERVERHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG), "SSL_CHECK_SRVR_ECC_CERT_AND_ALG"}, + {ERR_FUNC(SSL_F_SSL_CIPHER_PROCESS_RULESTR), "SSL_CIPHER_PROCESS_RULESTR"}, + {ERR_FUNC(SSL_F_SSL_CIPHER_STRENGTH_SORT), "SSL_CIPHER_STRENGTH_SORT"}, + {ERR_FUNC(SSL_F_SSL_CLEAR), "SSL_clear"}, + {ERR_FUNC(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD), "SSL_COMP_add_compression_method"}, + {ERR_FUNC(SSL_F_SSL_CREATE_CIPHER_LIST), "SSL_CREATE_CIPHER_LIST"}, + {ERR_FUNC(SSL_F_SSL_CTRL), "SSL_ctrl"}, + {ERR_FUNC(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY), "SSL_CTX_check_private_key"}, + {ERR_FUNC(SSL_F_SSL_CTX_MAKE_PROFILES), "SSL_CTX_MAKE_PROFILES"}, + {ERR_FUNC(SSL_F_SSL_CTX_NEW), "SSL_CTX_new"}, + {ERR_FUNC(SSL_F_SSL_CTX_SET_CIPHER_LIST), "SSL_CTX_set_cipher_list"}, + {ERR_FUNC(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE), "SSL_CTX_set_client_cert_engine"}, + {ERR_FUNC(SSL_F_SSL_CTX_SET_PURPOSE), "SSL_CTX_set_purpose"}, + {ERR_FUNC(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT), "SSL_CTX_set_session_id_context"}, + {ERR_FUNC(SSL_F_SSL_CTX_SET_SSL_VERSION), "SSL_CTX_set_ssl_version"}, + {ERR_FUNC(SSL_F_SSL_CTX_SET_TRUST), "SSL_CTX_set_trust"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE), "SSL_CTX_use_certificate"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1), "SSL_CTX_use_certificate_ASN1"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE), "SSL_CTX_use_certificate_chain_file"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE), "SSL_CTX_use_certificate_file"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY), "SSL_CTX_use_PrivateKey"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1), "SSL_CTX_use_PrivateKey_ASN1"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE), "SSL_CTX_use_PrivateKey_file"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT), "SSL_CTX_use_psk_identity_hint"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY), "SSL_CTX_use_RSAPrivateKey"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1), "SSL_CTX_use_RSAPrivateKey_ASN1"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE), "SSL_CTX_use_RSAPrivateKey_file"}, + {ERR_FUNC(SSL_F_SSL_DO_HANDSHAKE), "SSL_do_handshake"}, + {ERR_FUNC(SSL_F_SSL_GET_NEW_SESSION), "SSL_GET_NEW_SESSION"}, + {ERR_FUNC(SSL_F_SSL_GET_PREV_SESSION), "SSL_GET_PREV_SESSION"}, + {ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_CERT), "SSL_GET_SERVER_SEND_CERT"}, + {ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_PKEY), "SSL_GET_SERVER_SEND_PKEY"}, + {ERR_FUNC(SSL_F_SSL_GET_SIGN_PKEY), "SSL_GET_SIGN_PKEY"}, + {ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER), "SSL_INIT_WBIO_BUFFER"}, + {ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE), "SSL_load_client_CA_file"}, + {ERR_FUNC(SSL_F_SSL_NEW), "SSL_new"}, + {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT), "SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT"}, + {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT), "SSL_PARSE_CLIENTHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT), "SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT"}, + {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT), "SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT"}, + {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT), "SSL_PARSE_SERVERHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT), "SSL_PARSE_SERVERHELLO_USE_SRTP_EXT"}, + {ERR_FUNC(SSL_F_SSL_PEEK), "SSL_peek"}, + {ERR_FUNC(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT), "SSL_PREPARE_CLIENTHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT), "SSL_PREPARE_SERVERHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_SSL_READ), "SSL_read"}, + {ERR_FUNC(SSL_F_SSL_RSA_PRIVATE_DECRYPT), "SSL_RSA_PRIVATE_DECRYPT"}, + {ERR_FUNC(SSL_F_SSL_RSA_PUBLIC_ENCRYPT), "SSL_RSA_PUBLIC_ENCRYPT"}, + {ERR_FUNC(SSL_F_SSL_SESSION_NEW), "SSL_SESSION_new"}, + {ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"}, + {ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT), "SSL_SESSION_set1_id_context"}, + {ERR_FUNC(SSL_F_SSL_SESS_CERT_NEW), "SSL_SESS_CERT_NEW"}, + {ERR_FUNC(SSL_F_SSL_SET_CERT), "SSL_SET_CERT"}, + {ERR_FUNC(SSL_F_SSL_SET_CIPHER_LIST), "SSL_set_cipher_list"}, + {ERR_FUNC(SSL_F_SSL_SET_FD), "SSL_set_fd"}, + {ERR_FUNC(SSL_F_SSL_SET_PKEY), "SSL_SET_PKEY"}, + {ERR_FUNC(SSL_F_SSL_SET_PURPOSE), "SSL_set_purpose"}, + {ERR_FUNC(SSL_F_SSL_SET_RFD), "SSL_set_rfd"}, + {ERR_FUNC(SSL_F_SSL_SET_SESSION), "SSL_set_session"}, + {ERR_FUNC(SSL_F_SSL_SET_SESSION_ID_CONTEXT), "SSL_set_session_id_context"}, + {ERR_FUNC(SSL_F_SSL_SET_SESSION_TICKET_EXT), "SSL_set_session_ticket_ext"}, + {ERR_FUNC(SSL_F_SSL_SET_TRUST), "SSL_set_trust"}, + {ERR_FUNC(SSL_F_SSL_SET_WFD), "SSL_set_wfd"}, + {ERR_FUNC(SSL_F_SSL_SHUTDOWN), "SSL_shutdown"}, + {ERR_FUNC(SSL_F_SSL_SRP_CTX_INIT), "SSL_SRP_CTX_init"}, + {ERR_FUNC(SSL_F_SSL_UNDEFINED_CONST_FUNCTION), "SSL_UNDEFINED_CONST_FUNCTION"}, + {ERR_FUNC(SSL_F_SSL_UNDEFINED_FUNCTION), "SSL_UNDEFINED_FUNCTION"}, + {ERR_FUNC(SSL_F_SSL_UNDEFINED_VOID_FUNCTION), "SSL_UNDEFINED_VOID_FUNCTION"}, + {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE), "SSL_use_certificate"}, + {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_ASN1), "SSL_use_certificate_ASN1"}, + {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_FILE), "SSL_use_certificate_file"}, + {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY), "SSL_use_PrivateKey"}, + {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_ASN1), "SSL_use_PrivateKey_ASN1"}, + {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_FILE), "SSL_use_PrivateKey_file"}, + {ERR_FUNC(SSL_F_SSL_USE_PSK_IDENTITY_HINT), "SSL_use_psk_identity_hint"}, + {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY), "SSL_use_RSAPrivateKey"}, + {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1), "SSL_use_RSAPrivateKey_ASN1"}, + {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE), "SSL_use_RSAPrivateKey_file"}, + {ERR_FUNC(SSL_F_SSL_VERIFY_CERT_CHAIN), "SSL_VERIFY_CERT_CHAIN"}, + {ERR_FUNC(SSL_F_SSL_WRITE), "SSL_write"}, + {ERR_FUNC(SSL_F_TLS1_AEAD_CTX_INIT), "TLS1_AEAD_CTX_INIT"}, + {ERR_FUNC(SSL_F_TLS1_CERT_VERIFY_MAC), "tls1_cert_verify_mac"}, + {ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE), "TLS1_CHANGE_CIPHER_STATE"}, + {ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE_AEAD), "TLS1_CHANGE_CIPHER_STATE_AEAD"}, + {ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE_CIPHER), "TLS1_CHANGE_CIPHER_STATE_CIPHER"}, + {ERR_FUNC(SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT), "TLS1_CHECK_SERVERHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_TLS1_ENC), "TLS1_ENC"}, + {ERR_FUNC(SSL_F_TLS1_EXPORT_KEYING_MATERIAL), "TLS1_EXPORT_KEYING_MATERIAL"}, + {ERR_FUNC(SSL_F_TLS1_HEARTBEAT), "SSL_F_TLS1_HEARTBEAT"}, + {ERR_FUNC(SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT), "TLS1_PREPARE_CLIENTHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT), "TLS1_PREPARE_SERVERHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_TLS1_PRF), "tls1_prf"}, + {ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "TLS1_SETUP_KEY_BLOCK"}, + {ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"}, + {0, NULL} +}; + +static ERR_STRING_DATA SSL_str_reasons[]= { + {ERR_REASON(SSL_R_APP_DATA_IN_HANDSHAKE) , "app data in handshake"}, + {ERR_REASON(SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT), "attempt to reuse session in different context"}, + {ERR_REASON(SSL_R_BAD_ALERT_RECORD) , "bad alert record"}, + {ERR_REASON(SSL_R_BAD_AUTHENTICATION_TYPE), "bad authentication type"}, + {ERR_REASON(SSL_R_BAD_CHANGE_CIPHER_SPEC), "bad change cipher spec"}, + {ERR_REASON(SSL_R_BAD_CHECKSUM) , "bad checksum"}, + {ERR_REASON(SSL_R_BAD_DATA_RETURNED_BY_CALLBACK), "bad data returned by callback"}, + {ERR_REASON(SSL_R_BAD_DECOMPRESSION) , "bad decompression"}, + {ERR_REASON(SSL_R_BAD_DH_G_LENGTH) , "bad dh g length"}, + {ERR_REASON(SSL_R_BAD_DH_PUB_KEY_LENGTH) , "bad dh pub key length"}, + {ERR_REASON(SSL_R_BAD_DH_P_LENGTH) , "bad dh p length"}, + {ERR_REASON(SSL_R_BAD_DIGEST_LENGTH) , "bad digest length"}, + {ERR_REASON(SSL_R_BAD_DSA_SIGNATURE) , "bad dsa signature"}, + {ERR_REASON(SSL_R_BAD_ECC_CERT) , "bad ecc cert"}, + {ERR_REASON(SSL_R_BAD_ECDSA_SIGNATURE) , "bad ecdsa signature"}, + {ERR_REASON(SSL_R_BAD_ECPOINT) , "bad ecpoint"}, + {ERR_REASON(SSL_R_BAD_HANDSHAKE_LENGTH) , "bad handshake length"}, + {ERR_REASON(SSL_R_BAD_HELLO_REQUEST) , "bad hello request"}, + {ERR_REASON(SSL_R_BAD_LENGTH) , "bad length"}, + {ERR_REASON(SSL_R_BAD_MAC_DECODE) , "bad mac decode"}, + {ERR_REASON(SSL_R_BAD_MAC_LENGTH) , "bad mac length"}, + {ERR_REASON(SSL_R_BAD_MESSAGE_TYPE) , "bad message type"}, + {ERR_REASON(SSL_R_BAD_PACKET_LENGTH) , "bad packet length"}, + {ERR_REASON(SSL_R_BAD_PROTOCOL_VERSION_NUMBER), "bad protocol version number"}, + {ERR_REASON(SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH), "bad psk identity hint length"}, + {ERR_REASON(SSL_R_BAD_RESPONSE_ARGUMENT) , "bad response argument"}, + {ERR_REASON(SSL_R_BAD_RSA_DECRYPT) , "bad rsa decrypt"}, + {ERR_REASON(SSL_R_BAD_RSA_ENCRYPT) , "bad rsa encrypt"}, + {ERR_REASON(SSL_R_BAD_RSA_E_LENGTH) , "bad rsa e length"}, + {ERR_REASON(SSL_R_BAD_RSA_MODULUS_LENGTH), "bad rsa modulus length"}, + {ERR_REASON(SSL_R_BAD_RSA_SIGNATURE) , "bad rsa signature"}, + {ERR_REASON(SSL_R_BAD_SIGNATURE) , "bad signature"}, + {ERR_REASON(SSL_R_BAD_SRP_A_LENGTH) , "bad srp a length"}, + {ERR_REASON(SSL_R_BAD_SRP_B_LENGTH) , "bad srp b length"}, + {ERR_REASON(SSL_R_BAD_SRP_G_LENGTH) , "bad srp g length"}, + {ERR_REASON(SSL_R_BAD_SRP_N_LENGTH) , "bad srp n length"}, + {ERR_REASON(SSL_R_BAD_SRP_S_LENGTH) , "bad srp s length"}, + {ERR_REASON(SSL_R_BAD_SRTP_MKI_VALUE) , "bad srtp mki value"}, + {ERR_REASON(SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST), "bad srtp protection profile list"}, + {ERR_REASON(SSL_R_BAD_SSL_FILETYPE) , "bad ssl filetype"}, + {ERR_REASON(SSL_R_BAD_SSL_SESSION_ID_LENGTH), "bad ssl session id length"}, + {ERR_REASON(SSL_R_BAD_STATE) , "bad state"}, + {ERR_REASON(SSL_R_BAD_WRITE_RETRY) , "bad write retry"}, + {ERR_REASON(SSL_R_BIO_NOT_SET) , "bio not set"}, + {ERR_REASON(SSL_R_BLOCK_CIPHER_PAD_IS_WRONG), "block cipher pad is wrong"}, + {ERR_REASON(SSL_R_BN_LIB) , "bn lib"}, + {ERR_REASON(SSL_R_CA_DN_LENGTH_MISMATCH) , "ca dn length mismatch"}, + {ERR_REASON(SSL_R_CA_DN_TOO_LONG) , "ca dn too long"}, + {ERR_REASON(SSL_R_CCS_RECEIVED_EARLY) , "ccs received early"}, + {ERR_REASON(SSL_R_CERTIFICATE_VERIFY_FAILED), "certificate verify failed"}, + {ERR_REASON(SSL_R_CERT_LENGTH_MISMATCH) , "cert length mismatch"}, + {ERR_REASON(SSL_R_CHALLENGE_IS_DIFFERENT), "challenge is different"}, + {ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH), "cipher code wrong length"}, + {ERR_REASON(SSL_R_CIPHER_COMPRESSION_UNAVAILABLE), "cipher compression unavailable"}, + {ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE), "cipher or hash unavailable"}, + {ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR), "cipher table src error"}, + {ERR_REASON(SSL_R_CLIENTHELLO_TLSEXT) , "clienthello tlsext"}, + {ERR_REASON(SSL_R_COMPRESSED_LENGTH_TOO_LONG), "compressed length too long"}, + {ERR_REASON(SSL_R_COMPRESSION_DISABLED) , "compression disabled"}, + {ERR_REASON(SSL_R_COMPRESSION_FAILURE) , "compression failure"}, + {ERR_REASON(SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE), "compression id not within private range"}, + {ERR_REASON(SSL_R_COMPRESSION_LIBRARY_ERROR), "compression library error"}, + {ERR_REASON(SSL_R_CONNECTION_ID_IS_DIFFERENT), "connection id is different"}, + {ERR_REASON(SSL_R_CONNECTION_TYPE_NOT_SET), "connection type not set"}, + {ERR_REASON(SSL_R_COOKIE_MISMATCH) , "cookie mismatch"}, + {ERR_REASON(SSL_R_DATA_BETWEEN_CCS_AND_FINISHED), "data between ccs and finished"}, + {ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG) , "data length too long"}, + {ERR_REASON(SSL_R_DECRYPTION_FAILED) , "decryption failed"}, + {ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC), "decryption failed or bad record mac"}, + {ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG), "dh public value length is wrong"}, + {ERR_REASON(SSL_R_DIGEST_CHECK_FAILED) , "digest check failed"}, + {ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG) , "dtls message too big"}, + {ERR_REASON(SSL_R_DUPLICATE_COMPRESSION_ID), "duplicate compression id"}, + {ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT), "ecc cert not for key agreement"}, + {ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_SIGNING), "ecc cert not for signing"}, + {ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE), "ecc cert should have rsa signature"}, + {ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE), "ecc cert should have sha1 signature"}, + {ERR_REASON(SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER), "ecgroup too large for cipher"}, + {ERR_REASON(SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST), "empty srtp protection profile list"}, + {ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG), "encrypted length too long"}, + {ERR_REASON(SSL_R_ERROR_GENERATING_TMP_RSA_KEY), "error generating tmp rsa key"}, + {ERR_REASON(SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST), "error in received cipher list"}, + {ERR_REASON(SSL_R_EXCESSIVE_MESSAGE_SIZE), "excessive message size"}, + {ERR_REASON(SSL_R_EXTRA_DATA_IN_MESSAGE) , "extra data in message"}, + {ERR_REASON(SSL_R_GOT_A_FIN_BEFORE_A_CCS), "got a fin before a ccs"}, + {ERR_REASON(SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS), "got next proto before a ccs"}, + {ERR_REASON(SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION), "got next proto without seeing extension"}, + {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST) , "https proxy request"}, + {ERR_REASON(SSL_R_HTTP_REQUEST) , "http request"}, + {ERR_REASON(SSL_R_ILLEGAL_PADDING) , "illegal padding"}, + {ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK), "inappropriate fallback"}, + {ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION), "inconsistent compression"}, + {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH), "invalid challenge length"}, + {ERR_REASON(SSL_R_INVALID_COMMAND) , "invalid command"}, + {ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM), "invalid compression algorithm"}, + {ERR_REASON(SSL_R_INVALID_PURPOSE) , "invalid purpose"}, + {ERR_REASON(SSL_R_INVALID_SRP_USERNAME) , "invalid srp username"}, + {ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE), "invalid status response"}, + {ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH), "invalid ticket keys length"}, + {ERR_REASON(SSL_R_INVALID_TRUST) , "invalid trust"}, + {ERR_REASON(SSL_R_KEY_ARG_TOO_LONG) , "key arg too long"}, + {ERR_REASON(SSL_R_KRB5) , "krb5"}, + {ERR_REASON(SSL_R_KRB5_C_CC_PRINC) , "krb5 client cc principal (no tkt?)"}, + {ERR_REASON(SSL_R_KRB5_C_GET_CRED) , "krb5 client get cred"}, + {ERR_REASON(SSL_R_KRB5_C_INIT) , "krb5 client init"}, + {ERR_REASON(SSL_R_KRB5_C_MK_REQ) , "krb5 client mk_req (expired tkt?)"}, + {ERR_REASON(SSL_R_KRB5_S_BAD_TICKET) , "krb5 server bad ticket"}, + {ERR_REASON(SSL_R_KRB5_S_INIT) , "krb5 server init"}, + {ERR_REASON(SSL_R_KRB5_S_RD_REQ) , "krb5 server rd_req (keytab perms?)"}, + {ERR_REASON(SSL_R_KRB5_S_TKT_EXPIRED) , "krb5 server tkt expired"}, + {ERR_REASON(SSL_R_KRB5_S_TKT_NYV) , "krb5 server tkt not yet valid"}, + {ERR_REASON(SSL_R_KRB5_S_TKT_SKEW) , "krb5 server tkt skew"}, + {ERR_REASON(SSL_R_LENGTH_MISMATCH) , "length mismatch"}, + {ERR_REASON(SSL_R_LENGTH_TOO_SHORT) , "length too short"}, + {ERR_REASON(SSL_R_LIBRARY_BUG) , "library bug"}, + {ERR_REASON(SSL_R_LIBRARY_HAS_NO_CIPHERS), "library has no ciphers"}, + {ERR_REASON(SSL_R_MESSAGE_TOO_LONG) , "message too long"}, + {ERR_REASON(SSL_R_MISSING_DH_DSA_CERT) , "missing dh dsa cert"}, + {ERR_REASON(SSL_R_MISSING_DH_KEY) , "missing dh key"}, + {ERR_REASON(SSL_R_MISSING_DH_RSA_CERT) , "missing dh rsa cert"}, + {ERR_REASON(SSL_R_MISSING_DSA_SIGNING_CERT), "missing dsa signing cert"}, + {ERR_REASON(SSL_R_MISSING_EXPORT_TMP_DH_KEY), "missing export tmp dh key"}, + {ERR_REASON(SSL_R_MISSING_EXPORT_TMP_RSA_KEY), "missing export tmp rsa key"}, + {ERR_REASON(SSL_R_MISSING_RSA_CERTIFICATE), "missing rsa certificate"}, + {ERR_REASON(SSL_R_MISSING_RSA_ENCRYPTING_CERT), "missing rsa encrypting cert"}, + {ERR_REASON(SSL_R_MISSING_RSA_SIGNING_CERT), "missing rsa signing cert"}, + {ERR_REASON(SSL_R_MISSING_SRP_PARAM) , "can't find SRP server param"}, + {ERR_REASON(SSL_R_MISSING_TMP_DH_KEY) , "missing tmp dh key"}, + {ERR_REASON(SSL_R_MISSING_TMP_ECDH_KEY) , "missing tmp ecdh key"}, + {ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY) , "missing tmp rsa key"}, + {ERR_REASON(SSL_R_MISSING_TMP_RSA_PKEY) , "missing tmp rsa pkey"}, + {ERR_REASON(SSL_R_MISSING_VERIFY_MESSAGE), "missing verify message"}, + {ERR_REASON(SSL_R_MULTIPLE_SGC_RESTARTS) , "multiple sgc restarts"}, + {ERR_REASON(SSL_R_NON_SSLV2_INITIAL_PACKET), "non sslv2 initial packet"}, + {ERR_REASON(SSL_R_NO_CERTIFICATES_RETURNED), "no certificates returned"}, + {ERR_REASON(SSL_R_NO_CERTIFICATE_ASSIGNED), "no certificate assigned"}, + {ERR_REASON(SSL_R_NO_CERTIFICATE_RETURNED), "no certificate returned"}, + {ERR_REASON(SSL_R_NO_CERTIFICATE_SET) , "no certificate set"}, + {ERR_REASON(SSL_R_NO_CERTIFICATE_SPECIFIED), "no certificate specified"}, + {ERR_REASON(SSL_R_NO_CIPHERS_AVAILABLE) , "no ciphers available"}, + {ERR_REASON(SSL_R_NO_CIPHERS_PASSED) , "no ciphers passed"}, + {ERR_REASON(SSL_R_NO_CIPHERS_SPECIFIED) , "no ciphers specified"}, + {ERR_REASON(SSL_R_NO_CIPHER_LIST) , "no cipher list"}, + {ERR_REASON(SSL_R_NO_CIPHER_MATCH) , "no cipher match"}, + {ERR_REASON(SSL_R_NO_CLIENT_CERT_METHOD) , "no client cert method"}, + {ERR_REASON(SSL_R_NO_CLIENT_CERT_RECEIVED), "no client cert received"}, + {ERR_REASON(SSL_R_NO_COMPRESSION_SPECIFIED), "no compression specified"}, + {ERR_REASON(SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER), "Peer haven't sent GOST certificate, required for selected ciphersuite"}, + {ERR_REASON(SSL_R_NO_METHOD_SPECIFIED) , "no method specified"}, + {ERR_REASON(SSL_R_NO_PRIVATEKEY) , "no privatekey"}, + {ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED), "no private key assigned"}, + {ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE), "no protocols available"}, + {ERR_REASON(SSL_R_NO_PUBLICKEY) , "no publickey"}, + {ERR_REASON(SSL_R_NO_RENEGOTIATION) , "no renegotiation"}, + {ERR_REASON(SSL_R_NO_REQUIRED_DIGEST) , "digest requred for handshake isn't computed"}, + {ERR_REASON(SSL_R_NO_SHARED_CIPHER) , "no shared cipher"}, + {ERR_REASON(SSL_R_NO_SRTP_PROFILES) , "no srtp profiles"}, + {ERR_REASON(SSL_R_NO_VERIFY_CALLBACK) , "no verify callback"}, + {ERR_REASON(SSL_R_NULL_SSL_CTX) , "null ssl ctx"}, + {ERR_REASON(SSL_R_NULL_SSL_METHOD_PASSED), "null ssl method passed"}, + {ERR_REASON(SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED), "old session cipher not returned"}, + {ERR_REASON(SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED), "old session compression algorithm not returned"}, + {ERR_REASON(SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE), "only tls allowed in fips mode"}, + {ERR_REASON(SSL_R_PACKET_LENGTH_TOO_LONG), "packet length too long"}, + {ERR_REASON(SSL_R_PARSE_TLSEXT) , "parse tlsext"}, + {ERR_REASON(SSL_R_PATH_TOO_LONG) , "path too long"}, + {ERR_REASON(SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE), "peer did not return a certificate"}, + {ERR_REASON(SSL_R_PEER_ERROR) , "peer error"}, + {ERR_REASON(SSL_R_PEER_ERROR_CERTIFICATE), "peer error certificate"}, + {ERR_REASON(SSL_R_PEER_ERROR_NO_CERTIFICATE), "peer error no certificate"}, + {ERR_REASON(SSL_R_PEER_ERROR_NO_CIPHER) , "peer error no cipher"}, + {ERR_REASON(SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE), "peer error unsupported certificate type"}, + {ERR_REASON(SSL_R_PRE_MAC_LENGTH_TOO_LONG), "pre mac length too long"}, + {ERR_REASON(SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS), "problems mapping cipher functions"}, + {ERR_REASON(SSL_R_PROTOCOL_IS_SHUTDOWN) , "protocol is shutdown"}, + {ERR_REASON(SSL_R_PSK_IDENTITY_NOT_FOUND), "psk identity not found"}, + {ERR_REASON(SSL_R_PSK_NO_CLIENT_CB) , "psk no client cb"}, + {ERR_REASON(SSL_R_PSK_NO_SERVER_CB) , "psk no server cb"}, + {ERR_REASON(SSL_R_PUBLIC_KEY_ENCRYPT_ERROR), "public key encrypt error"}, + {ERR_REASON(SSL_R_PUBLIC_KEY_IS_NOT_RSA) , "public key is not rsa"}, + {ERR_REASON(SSL_R_PUBLIC_KEY_NOT_RSA) , "public key not rsa"}, + {ERR_REASON(SSL_R_READ_BIO_NOT_SET) , "read bio not set"}, + {ERR_REASON(SSL_R_READ_TIMEOUT_EXPIRED) , "read timeout expired"}, + {ERR_REASON(SSL_R_READ_WRONG_PACKET_TYPE), "read wrong packet type"}, + {ERR_REASON(SSL_R_RECORD_LENGTH_MISMATCH), "record length mismatch"}, + {ERR_REASON(SSL_R_RECORD_TOO_LARGE) , "record too large"}, + {ERR_REASON(SSL_R_RECORD_TOO_SMALL) , "record too small"}, + {ERR_REASON(SSL_R_RENEGOTIATE_EXT_TOO_LONG), "renegotiate ext too long"}, + {ERR_REASON(SSL_R_RENEGOTIATION_ENCODING_ERR), "renegotiation encoding err"}, + {ERR_REASON(SSL_R_RENEGOTIATION_MISMATCH), "renegotiation mismatch"}, + {ERR_REASON(SSL_R_REQUIRED_CIPHER_MISSING), "required cipher missing"}, + {ERR_REASON(SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING), "required compresssion algorithm missing"}, + {ERR_REASON(SSL_R_REUSE_CERT_LENGTH_NOT_ZERO), "reuse cert length not zero"}, + {ERR_REASON(SSL_R_REUSE_CERT_TYPE_NOT_ZERO), "reuse cert type not zero"}, + {ERR_REASON(SSL_R_REUSE_CIPHER_LIST_NOT_ZERO), "reuse cipher list not zero"}, + {ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING), "scsv received when renegotiating"}, + {ERR_REASON(SSL_R_SERVERHELLO_TLSEXT) , "serverhello tlsext"}, + {ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED), "session id context uninitialized"}, + {ERR_REASON(SSL_R_SHORT_READ) , "short read"}, + {ERR_REASON(SSL_R_SIGNATURE_ALGORITHMS_ERROR), "signature algorithms error"}, + {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE), "signature for non signing certificate"}, + {ERR_REASON(SSL_R_SRP_A_CALC) , "error with the srp params"}, + {ERR_REASON(SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES), "srtp could not allocate profiles"}, + {ERR_REASON(SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG), "srtp protection profile list too long"}, + {ERR_REASON(SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE), "srtp unknown protection profile"}, + {ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE), "ssl23 doing session id reuse"}, + {ERR_REASON(SSL_R_SSL2_CONNECTION_ID_TOO_LONG), "ssl2 connection id too long"}, + {ERR_REASON(SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT), "ssl3 ext invalid ecpointformat"}, + {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME), "ssl3 ext invalid servername"}, + {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE), "ssl3 ext invalid servername type"}, + {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_LONG), "ssl3 session id too long"}, + {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_SHORT), "ssl3 session id too short"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_BAD_CERTIFICATE), "sslv3 alert bad certificate"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_BAD_RECORD_MAC), "sslv3 alert bad record mac"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED), "sslv3 alert certificate expired"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED), "sslv3 alert certificate revoked"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN), "sslv3 alert certificate unknown"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE), "sslv3 alert decompression failure"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE), "sslv3 alert handshake failure"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER), "sslv3 alert illegal parameter"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_NO_CERTIFICATE), "sslv3 alert no certificate"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE), "sslv3 alert unexpected message"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE), "sslv3 alert unsupported certificate"}, + {ERR_REASON(SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION), "ssl ctx has no default ssl version"}, + {ERR_REASON(SSL_R_SSL_HANDSHAKE_FAILURE) , "ssl handshake failure"}, + {ERR_REASON(SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS), "ssl library has no ciphers"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_CALLBACK_FAILED), "ssl session id callback failed"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_CONFLICT), "ssl session id conflict"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG), "ssl session id context too long"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH), "ssl session id has bad length"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_IS_DIFFERENT), "ssl session id is different"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_ACCESS_DENIED), "tlsv1 alert access denied"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_DECODE_ERROR), "tlsv1 alert decode error"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED), "tlsv1 alert decryption failed"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR), "tlsv1 alert decrypt error"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION), "tlsv1 alert export restriction"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK), "tlsv1 alert inappropriate fallback"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY), "tlsv1 alert insufficient security"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR), "tlsv1 alert internal error"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION), "tlsv1 alert no renegotiation"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_PROTOCOL_VERSION), "tlsv1 alert protocol version"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_RECORD_OVERFLOW), "tlsv1 alert record overflow"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_UNKNOWN_CA), "tlsv1 alert unknown ca"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_USER_CANCELLED), "tlsv1 alert user cancelled"}, + {ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE), "tlsv1 bad certificate hash value"}, + {ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE), "tlsv1 bad certificate status response"}, + {ERR_REASON(SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE), "tlsv1 certificate unobtainable"}, + {ERR_REASON(SSL_R_TLSV1_UNRECOGNIZED_NAME), "tlsv1 unrecognized name"}, + {ERR_REASON(SSL_R_TLSV1_UNSUPPORTED_EXTENSION), "tlsv1 unsupported extension"}, + {ERR_REASON(SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER), "tls client cert req with anon cipher"}, + {ERR_REASON(SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT), "peer does not accept heartbeats"}, + {ERR_REASON(SSL_R_TLS_HEARTBEAT_PENDING) , "heartbeat request already pending"}, + {ERR_REASON(SSL_R_TLS_ILLEGAL_EXPORTER_LABEL), "tls illegal exporter label"}, + {ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST), "tls invalid ecpointformat list"}, + {ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST), "tls peer did not respond with certificate list"}, + {ERR_REASON(SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG), "tls rsa encrypted value length is wrong"}, + {ERR_REASON(SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER), "tried to use unsupported cipher"}, + {ERR_REASON(SSL_R_UNABLE_TO_DECODE_DH_CERTS), "unable to decode dh certs"}, + {ERR_REASON(SSL_R_UNABLE_TO_DECODE_ECDH_CERTS), "unable to decode ecdh certs"}, + {ERR_REASON(SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY), "unable to extract public key"}, + {ERR_REASON(SSL_R_UNABLE_TO_FIND_DH_PARAMETERS), "unable to find dh parameters"}, + {ERR_REASON(SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS), "unable to find ecdh parameters"}, + {ERR_REASON(SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS), "unable to find public key parameters"}, + {ERR_REASON(SSL_R_UNABLE_TO_FIND_SSL_METHOD), "unable to find ssl method"}, + {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES), "unable to load ssl2 md5 routines"}, + {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES), "unable to load ssl3 md5 routines"}, + {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES), "unable to load ssl3 sha1 routines"}, + {ERR_REASON(SSL_R_UNEXPECTED_MESSAGE) , "unexpected message"}, + {ERR_REASON(SSL_R_UNEXPECTED_RECORD) , "unexpected record"}, + {ERR_REASON(SSL_R_UNINITIALIZED) , "uninitialized"}, + {ERR_REASON(SSL_R_UNKNOWN_ALERT_TYPE) , "unknown alert type"}, + {ERR_REASON(SSL_R_UNKNOWN_CERTIFICATE_TYPE), "unknown certificate type"}, + {ERR_REASON(SSL_R_UNKNOWN_CIPHER_RETURNED), "unknown cipher returned"}, + {ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE) , "unknown cipher type"}, + {ERR_REASON(SSL_R_UNKNOWN_DIGEST) , "unknown digest"}, + {ERR_REASON(SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE), "unknown key exchange type"}, + {ERR_REASON(SSL_R_UNKNOWN_PKEY_TYPE) , "unknown pkey type"}, + {ERR_REASON(SSL_R_UNKNOWN_PROTOCOL) , "unknown protocol"}, + {ERR_REASON(SSL_R_UNKNOWN_REMOTE_ERROR_TYPE), "unknown remote error type"}, + {ERR_REASON(SSL_R_UNKNOWN_SSL_VERSION) , "unknown ssl version"}, + {ERR_REASON(SSL_R_UNKNOWN_STATE) , "unknown state"}, + {ERR_REASON(SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED), "unsafe legacy renegotiation disabled"}, + {ERR_REASON(SSL_R_UNSUPPORTED_CIPHER) , "unsupported cipher"}, + {ERR_REASON(SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM), "unsupported compression algorithm"}, + {ERR_REASON(SSL_R_UNSUPPORTED_DIGEST_TYPE), "unsupported digest type"}, + {ERR_REASON(SSL_R_UNSUPPORTED_ELLIPTIC_CURVE), "unsupported elliptic curve"}, + {ERR_REASON(SSL_R_UNSUPPORTED_PROTOCOL) , "unsupported protocol"}, + {ERR_REASON(SSL_R_UNSUPPORTED_SSL_VERSION), "unsupported ssl version"}, + {ERR_REASON(SSL_R_UNSUPPORTED_STATUS_TYPE), "unsupported status type"}, + {ERR_REASON(SSL_R_USE_SRTP_NOT_NEGOTIATED), "use srtp not negotiated"}, + {ERR_REASON(SSL_R_WRITE_BIO_NOT_SET) , "write bio not set"}, + {ERR_REASON(SSL_R_WRONG_CIPHER_RETURNED) , "wrong cipher returned"}, + {ERR_REASON(SSL_R_WRONG_CURVE) , "wrong curve"}, + {ERR_REASON(SSL_R_WRONG_MESSAGE_TYPE) , "wrong message type"}, + {ERR_REASON(SSL_R_WRONG_NUMBER_OF_KEY_BITS), "wrong number of key bits"}, + {ERR_REASON(SSL_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"}, + {ERR_REASON(SSL_R_WRONG_SIGNATURE_SIZE) , "wrong signature size"}, + {ERR_REASON(SSL_R_WRONG_SIGNATURE_TYPE) , "wrong signature type"}, + {ERR_REASON(SSL_R_WRONG_SSL_VERSION) , "wrong ssl version"}, + {ERR_REASON(SSL_R_WRONG_VERSION_NUMBER) , "wrong version number"}, + {ERR_REASON(SSL_R_X509_LIB) , "x509 lib"}, + {ERR_REASON(SSL_R_X509_VERIFICATION_SETUP_PROBLEMS), "x509 verification setup problems"}, + {0, NULL} +}; + +#endif + +void +ERR_load_SSL_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(SSL_str_functs[0].error) == NULL) { + ERR_load_strings(0, SSL_str_functs); + ERR_load_strings(0, SSL_str_reasons); + } +#endif +} diff --git a/crypto/libressl/ssl/ssl_err2.c b/crypto/libressl/ssl/ssl_err2.c new file mode 100644 index 0000000000..aa6eca26bb --- /dev/null +++ b/crypto/libressl/ssl/ssl_err2.c @@ -0,0 +1,72 @@ +/* $OpenBSD: ssl_err2.c,v 1.6 2014/11/16 14:12:47 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include +#include + +void +SSL_load_error_strings(void) +{ +#ifndef OPENSSL_NO_ERR + ERR_load_crypto_strings(); + ERR_load_SSL_strings(); +#endif +} + diff --git a/crypto/libressl/ssl/ssl_lib.c b/crypto/libressl/ssl/ssl_lib.c new file mode 100644 index 0000000000..409fed4b40 --- /dev/null +++ b/crypto/libressl/ssl/ssl_lib.c @@ -0,0 +1,3062 @@ +/* $OpenBSD: ssl_lib.c,v 1.115 2015/10/19 17:59:39 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include + +#include "ssl_locl.h" + +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_NO_ENGINE +#include +#endif + +#include "bytestring.h" + +const char *SSL_version_str = OPENSSL_VERSION_TEXT; + +SSL3_ENC_METHOD ssl3_undef_enc_method = { + /* + * Evil casts, but these functions are only called if there's a + * library bug. + */ + .enc = (int (*)(SSL *, int))ssl_undefined_function, + .mac = (int (*)(SSL *, unsigned char *, int))ssl_undefined_function, + .setup_key_block = ssl_undefined_function, + .generate_master_secret = (int (*)(SSL *, unsigned char *, + unsigned char *, int))ssl_undefined_function, + .change_cipher_state = (int (*)(SSL*, int))ssl_undefined_function, + .final_finish_mac = (int (*)(SSL *, const char*, int, + unsigned char *))ssl_undefined_function, + .finish_mac_length = 0, + .cert_verify_mac = (int (*)(SSL *, int, + unsigned char *))ssl_undefined_function, + .client_finished_label = NULL, + .client_finished_label_len = 0, + .server_finished_label = NULL, + .server_finished_label_len = 0, + .alert_value = (int (*)(int))ssl_undefined_function, + .export_keying_material = (int (*)(SSL *, unsigned char *, size_t, + const char *, size_t, const unsigned char *, size_t, + int use_context))ssl_undefined_function, + .enc_flags = 0, +}; + +int +SSL_clear(SSL *s) +{ + if (s->method == NULL) { + SSLerr(SSL_F_SSL_CLEAR, SSL_R_NO_METHOD_SPECIFIED); + return (0); + } + + if (ssl_clear_bad_session(s)) { + SSL_SESSION_free(s->session); + s->session = NULL; + } + + s->error = 0; + s->hit = 0; + s->shutdown = 0; + + if (s->renegotiate) { + SSLerr(SSL_F_SSL_CLEAR, ERR_R_INTERNAL_ERROR); + return (0); + } + + s->type = 0; + + s->state = SSL_ST_BEFORE|((s->server) ? SSL_ST_ACCEPT : SSL_ST_CONNECT); + + s->version = s->method->version; + s->client_version = s->version; + s->rwstate = SSL_NOTHING; + s->rstate = SSL_ST_READ_HEADER; + + BUF_MEM_free(s->init_buf); + s->init_buf = NULL; + + ssl_clear_cipher_ctx(s); + ssl_clear_hash_ctx(&s->read_hash); + ssl_clear_hash_ctx(&s->write_hash); + + s->first_packet = 0; + + /* + * Check to see if we were changed into a different method, if + * so, revert back if we are not doing session-id reuse. + */ + if (!s->in_handshake && (s->session == NULL) && + (s->method != s->ctx->method)) { + s->method->ssl_free(s); + s->method = s->ctx->method; + if (!s->method->ssl_new(s)) + return (0); + } else + s->method->ssl_clear(s); + + return (1); +} + +/* Used to change an SSL_CTXs default SSL method type */ +int +SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) +{ + STACK_OF(SSL_CIPHER) *sk; + + ctx->method = meth; + + sk = ssl_create_cipher_list(ctx->method, &(ctx->cipher_list), + &(ctx->cipher_list_by_id), SSL_DEFAULT_CIPHER_LIST); + if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0)) { + SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION, + SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS); + return (0); + } + return (1); +} + +SSL * +SSL_new(SSL_CTX *ctx) +{ + SSL *s; + + if (ctx == NULL) { + SSLerr(SSL_F_SSL_NEW, SSL_R_NULL_SSL_CTX); + return (NULL); + } + if (ctx->method == NULL) { + SSLerr(SSL_F_SSL_NEW, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION); + return (NULL); + } + + s = calloc(1, sizeof(SSL)); + if (s == NULL) + goto err; + + + s->options = ctx->options; + s->mode = ctx->mode; + s->max_cert_list = ctx->max_cert_list; + + if (ctx->cert != NULL) { + /* + * Earlier library versions used to copy the pointer to + * the CERT, not its contents; only when setting new + * parameters for the per-SSL copy, ssl_cert_new would be + * called (and the direct reference to the per-SSL_CTX + * settings would be lost, but those still were indirectly + * accessed for various purposes, and for that reason they + * used to be known as s->ctx->default_cert). + * Now we don't look at the SSL_CTX's CERT after having + * duplicated it once. + */ + s->cert = ssl_cert_dup(ctx->cert); + if (s->cert == NULL) + goto err; + } else + s->cert=NULL; /* Cannot really happen (see SSL_CTX_new) */ + + s->read_ahead = ctx->read_ahead; + s->msg_callback = ctx->msg_callback; + s->msg_callback_arg = ctx->msg_callback_arg; + s->verify_mode = ctx->verify_mode; + s->sid_ctx_length = ctx->sid_ctx_length; + OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx); + memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx)); + s->verify_callback = ctx->default_verify_callback; + s->generate_session_id = ctx->generate_session_id; + + s->param = X509_VERIFY_PARAM_new(); + if (!s->param) + goto err; + X509_VERIFY_PARAM_inherit(s->param, ctx->param); + s->quiet_shutdown = ctx->quiet_shutdown; + s->max_send_fragment = ctx->max_send_fragment; + + CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); + s->ctx = ctx; + s->tlsext_debug_cb = 0; + s->tlsext_debug_arg = NULL; + s->tlsext_ticket_expected = 0; + s->tlsext_status_type = -1; + s->tlsext_status_expected = 0; + s->tlsext_ocsp_ids = NULL; + s->tlsext_ocsp_exts = NULL; + s->tlsext_ocsp_resp = NULL; + s->tlsext_ocsp_resplen = -1; + CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); + s->initial_ctx = ctx; + s->next_proto_negotiated = NULL; + + if (s->ctx->alpn_client_proto_list != NULL) { + s->alpn_client_proto_list = + malloc(s->ctx->alpn_client_proto_list_len); + if (s->alpn_client_proto_list == NULL) + goto err; + memcpy(s->alpn_client_proto_list, + s->ctx->alpn_client_proto_list, + s->ctx->alpn_client_proto_list_len); + s->alpn_client_proto_list_len = + s->ctx->alpn_client_proto_list_len; + } + + s->verify_result = X509_V_OK; + + s->method = ctx->method; + + if (!s->method->ssl_new(s)) + goto err; + + s->references = 1; + s->server = (ctx->method->ssl_accept == ssl_undefined_function) ? 0 : 1; + + SSL_clear(s); + + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data); + + return (s); + +err: + SSL_free(s); + SSLerr(SSL_F_SSL_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); +} + +int +SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx, + unsigned int sid_ctx_len) +{ + if (sid_ctx_len > sizeof ctx->sid_ctx) { + SSLerr(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT, + SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + return (0); + } + ctx->sid_ctx_length = sid_ctx_len; + memcpy(ctx->sid_ctx, sid_ctx, sid_ctx_len); + + return (1); +} + +int +SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, + unsigned int sid_ctx_len) +{ + if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) { + SSLerr(SSL_F_SSL_SET_SESSION_ID_CONTEXT, + SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + return (0); + } + ssl->sid_ctx_length = sid_ctx_len; + memcpy(ssl->sid_ctx, sid_ctx, sid_ctx_len); + + return (1); +} + +int +SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb) +{ + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + ctx->generate_session_id = cb; + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + return (1); +} + +int +SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb) +{ + CRYPTO_w_lock(CRYPTO_LOCK_SSL); + ssl->generate_session_id = cb; + CRYPTO_w_unlock(CRYPTO_LOCK_SSL); + return (1); +} + +int +SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, + unsigned int id_len) +{ + /* + * A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp + * shows how we can "construct" a session to give us the desired + * check - ie. to find if there's a session in the hash table + * that would conflict with any new session built out of this + * id/id_len and the ssl_version in use by this SSL. + */ + SSL_SESSION r, *p; + + if (id_len > sizeof r.session_id) + return (0); + + r.ssl_version = ssl->version; + r.session_id_length = id_len; + memcpy(r.session_id, id, id_len); + + CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); + p = lh_SSL_SESSION_retrieve(ssl->ctx->sessions, &r); + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + return (p != NULL); +} + +int +SSL_CTX_set_purpose(SSL_CTX *s, int purpose) +{ + return (X509_VERIFY_PARAM_set_purpose(s->param, purpose)); +} + +int +SSL_set_purpose(SSL *s, int purpose) +{ + return (X509_VERIFY_PARAM_set_purpose(s->param, purpose)); +} + +int +SSL_CTX_set_trust(SSL_CTX *s, int trust) +{ + return (X509_VERIFY_PARAM_set_trust(s->param, trust)); +} + +int +SSL_set_trust(SSL *s, int trust) +{ + return (X509_VERIFY_PARAM_set_trust(s->param, trust)); +} + +int +SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm) +{ + return (X509_VERIFY_PARAM_set1(ctx->param, vpm)); +} + +int +SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm) +{ + return (X509_VERIFY_PARAM_set1(ssl->param, vpm)); +} + +void +SSL_free(SSL *s) +{ + int i; + + if (s == NULL) + return; + + i = CRYPTO_add(&s->references, -1, CRYPTO_LOCK_SSL); + if (i > 0) + return; + + if (s->param) + X509_VERIFY_PARAM_free(s->param); + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data); + + if (s->bbio != NULL) { + /* If the buffering BIO is in place, pop it off */ + if (s->bbio == s->wbio) { + s->wbio = BIO_pop(s->wbio); + } + BIO_free(s->bbio); + s->bbio = NULL; + } + + if (s->rbio != s->wbio) + BIO_free_all(s->rbio); + BIO_free_all(s->wbio); + + if (s->init_buf != NULL) + BUF_MEM_free(s->init_buf); + + /* add extra stuff */ + if (s->cipher_list != NULL) + sk_SSL_CIPHER_free(s->cipher_list); + if (s->cipher_list_by_id != NULL) + sk_SSL_CIPHER_free(s->cipher_list_by_id); + + /* Make the next call work :-) */ + if (s->session != NULL) { + ssl_clear_bad_session(s); + SSL_SESSION_free(s->session); + } + + ssl_clear_cipher_ctx(s); + ssl_clear_hash_ctx(&s->read_hash); + ssl_clear_hash_ctx(&s->write_hash); + + if (s->cert != NULL) + ssl_cert_free(s->cert); + /* Free up if allocated */ + + free(s->tlsext_hostname); + SSL_CTX_free(s->initial_ctx); + free(s->tlsext_ecpointformatlist); + free(s->tlsext_ellipticcurvelist); + if (s->tlsext_ocsp_exts) + sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, + X509_EXTENSION_free); + if (s->tlsext_ocsp_ids) + sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free); + free(s->tlsext_ocsp_resp); + + if (s->client_CA != NULL) + sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free); + + if (s->method != NULL) + s->method->ssl_free(s); + + SSL_CTX_free(s->ctx); + + + free(s->next_proto_negotiated); + free(s->alpn_client_proto_list); + +#ifndef OPENSSL_NO_SRTP + if (s->srtp_profiles) + sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles); +#endif + + free(s); +} + +void +SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) +{ + /* If the output buffering BIO is still in place, remove it */ + if (s->bbio != NULL) { + if (s->wbio == s->bbio) { + s->wbio = s->wbio->next_bio; + s->bbio->next_bio = NULL; + } + } + + if (s->rbio != rbio && s->rbio != s->wbio) + BIO_free_all(s->rbio); + if (s->wbio != wbio) + BIO_free_all(s->wbio); + s->rbio = rbio; + s->wbio = wbio; +} + +BIO * +SSL_get_rbio(const SSL *s) +{ + return (s->rbio); +} + +BIO * +SSL_get_wbio(const SSL *s) +{ + return (s->wbio); +} + +int +SSL_get_fd(const SSL *s) +{ + return (SSL_get_rfd(s)); +} + +int +SSL_get_rfd(const SSL *s) +{ + int ret = -1; + BIO *b, *r; + + b = SSL_get_rbio(s); + r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR); + if (r != NULL) + BIO_get_fd(r, &ret); + return (ret); +} + +int +SSL_get_wfd(const SSL *s) +{ + int ret = -1; + BIO *b, *r; + + b = SSL_get_wbio(s); + r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR); + if (r != NULL) + BIO_get_fd(r, &ret); + return (ret); +} + +int +SSL_set_fd(SSL *s, int fd) +{ + int ret = 0; + BIO *bio = NULL; + + bio = BIO_new(BIO_s_socket()); + + if (bio == NULL) { + SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB); + goto err; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set_bio(s, bio, bio); + ret = 1; +err: + return (ret); +} + +int +SSL_set_wfd(SSL *s, int fd) +{ + int ret = 0; + BIO *bio = NULL; + + if ((s->rbio == NULL) || (BIO_method_type(s->rbio) != BIO_TYPE_SOCKET) + || ((int)BIO_get_fd(s->rbio, NULL) != fd)) { + bio = BIO_new(BIO_s_socket()); + + if (bio == NULL) { + SSLerr(SSL_F_SSL_SET_WFD, ERR_R_BUF_LIB); + goto err; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set_bio(s, SSL_get_rbio(s), bio); + } else + SSL_set_bio(s, SSL_get_rbio(s), SSL_get_rbio(s)); + ret = 1; +err: + return (ret); +} + +int +SSL_set_rfd(SSL *s, int fd) +{ + int ret = 0; + BIO *bio = NULL; + + if ((s->wbio == NULL) || (BIO_method_type(s->wbio) != BIO_TYPE_SOCKET) + || ((int)BIO_get_fd(s->wbio, NULL) != fd)) { + bio = BIO_new(BIO_s_socket()); + + if (bio == NULL) { + SSLerr(SSL_F_SSL_SET_RFD, ERR_R_BUF_LIB); + goto err; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set_bio(s, bio, SSL_get_wbio(s)); + } else + SSL_set_bio(s, SSL_get_wbio(s), SSL_get_wbio(s)); + ret = 1; +err: + return (ret); +} + + +/* return length of latest Finished message we sent, copy to 'buf' */ +size_t +SSL_get_finished(const SSL *s, void *buf, size_t count) +{ + size_t ret = 0; + + if (s->s3 != NULL) { + ret = s->s3->tmp.finish_md_len; + if (count > ret) + count = ret; + memcpy(buf, s->s3->tmp.finish_md, count); + } + return (ret); +} + +/* return length of latest Finished message we expected, copy to 'buf' */ +size_t +SSL_get_peer_finished(const SSL *s, void *buf, size_t count) +{ + size_t ret = 0; + + if (s->s3 != NULL) { + ret = s->s3->tmp.peer_finish_md_len; + if (count > ret) + count = ret; + memcpy(buf, s->s3->tmp.peer_finish_md, count); + } + return (ret); +} + + +int +SSL_get_verify_mode(const SSL *s) +{ + return (s->verify_mode); +} + +int +SSL_get_verify_depth(const SSL *s) +{ + return (X509_VERIFY_PARAM_get_depth(s->param)); +} + +int +(*SSL_get_verify_callback(const SSL *s))(int, X509_STORE_CTX *) +{ + return (s->verify_callback); +} + +int +SSL_CTX_get_verify_mode(const SSL_CTX *ctx) +{ + return (ctx->verify_mode); +} + +int +SSL_CTX_get_verify_depth(const SSL_CTX *ctx) +{ + return (X509_VERIFY_PARAM_get_depth(ctx->param)); +} + +int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int, X509_STORE_CTX *) +{ + return (ctx->default_verify_callback); +} + +void +SSL_set_verify(SSL *s, int mode, + int (*callback)(int ok, X509_STORE_CTX *ctx)) +{ + s->verify_mode = mode; + if (callback != NULL) + s->verify_callback = callback; +} + +void +SSL_set_verify_depth(SSL *s, int depth) +{ + X509_VERIFY_PARAM_set_depth(s->param, depth); +} + +void +SSL_set_read_ahead(SSL *s, int yes) +{ + s->read_ahead = yes; +} + +int +SSL_get_read_ahead(const SSL *s) +{ + return (s->read_ahead); +} + +int +SSL_pending(const SSL *s) +{ + /* + * SSL_pending cannot work properly if read-ahead is enabled + * (SSL_[CTX_]ctrl(..., SSL_CTRL_SET_READ_AHEAD, 1, NULL)), + * and it is impossible to fix since SSL_pending cannot report + * errors that may be observed while scanning the new data. + * (Note that SSL_pending() is often used as a boolean value, + * so we'd better not return -1.) + */ + return (s->method->ssl_pending(s)); +} + +X509 * +SSL_get_peer_certificate(const SSL *s) +{ + X509 *r; + + if ((s == NULL) || (s->session == NULL)) + r = NULL; + else + r = s->session->peer; + + if (r == NULL) + return (r); + + CRYPTO_add(&r->references, 1, CRYPTO_LOCK_X509); + + return (r); +} + +STACK_OF(X509) * +SSL_get_peer_cert_chain(const SSL *s) +{ + STACK_OF(X509) *r; + + if ((s == NULL) || (s->session == NULL) || + (s->session->sess_cert == NULL)) + r = NULL; + else + r = s->session->sess_cert->cert_chain; + + /* + * If we are a client, cert_chain includes the peer's own + * certificate; + * if we are a server, it does not. + */ + return (r); +} + +/* + * Now in theory, since the calling process own 't' it should be safe to + * modify. We need to be able to read f without being hassled + */ +void +SSL_copy_session_id(SSL *t, const SSL *f) +{ + CERT *tmp; + + /* Do we need to to SSL locking? */ + SSL_set_session(t, SSL_get_session(f)); + + /* + * What if we are setup as SSLv2 but want to talk SSLv3 or + * vice-versa. + */ + if (t->method != f->method) { + t->method->ssl_free(t); /* cleanup current */ + t->method=f->method; /* change method */ + t->method->ssl_new(t); /* setup new */ + } + + tmp = t->cert; + if (f->cert != NULL) { + CRYPTO_add(&f->cert->references, 1, CRYPTO_LOCK_SSL_CERT); + t->cert = f->cert; + } else + t->cert = NULL; + if (tmp != NULL) + ssl_cert_free(tmp); + SSL_set_session_id_context(t, f->sid_ctx, f->sid_ctx_length); +} + +/* Fix this so it checks all the valid key/cert options */ +int +SSL_CTX_check_private_key(const SSL_CTX *ctx) +{ + if ((ctx == NULL) || (ctx->cert == NULL) || + (ctx->cert->key->x509 == NULL)) { + SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY, + SSL_R_NO_CERTIFICATE_ASSIGNED); + return (0); + } + if (ctx->cert->key->privatekey == NULL) { + SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY, + SSL_R_NO_PRIVATE_KEY_ASSIGNED); + return (0); + } + return (X509_check_private_key(ctx->cert->key->x509, + ctx->cert->key->privatekey)); +} + +/* Fix this function so that it takes an optional type parameter */ +int +SSL_check_private_key(const SSL *ssl) +{ + if (ssl == NULL) { + SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, + ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (ssl->cert == NULL) { + SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, + SSL_R_NO_CERTIFICATE_ASSIGNED); + return (0); + } + if (ssl->cert->key->x509 == NULL) { + SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, + SSL_R_NO_CERTIFICATE_ASSIGNED); + return (0); + } + if (ssl->cert->key->privatekey == NULL) { + SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, + SSL_R_NO_PRIVATE_KEY_ASSIGNED); + return (0); + } + return (X509_check_private_key(ssl->cert->key->x509, + ssl->cert->key->privatekey)); +} + +int +SSL_accept(SSL *s) +{ + if (s->handshake_func == NULL) + SSL_set_accept_state(s); /* Not properly initialized yet */ + + return (s->method->ssl_accept(s)); +} + +int +SSL_connect(SSL *s) +{ + if (s->handshake_func == NULL) + SSL_set_connect_state(s); /* Not properly initialized yet */ + + return (s->method->ssl_connect(s)); +} + +long +SSL_get_default_timeout(const SSL *s) +{ + return (s->method->get_timeout()); +} + +int +SSL_read(SSL *s, void *buf, int num) +{ + if (s->handshake_func == NULL) { + SSLerr(SSL_F_SSL_READ, SSL_R_UNINITIALIZED); + return (-1); + } + + if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { + s->rwstate = SSL_NOTHING; + return (0); + } + return (s->method->ssl_read(s, buf, num)); +} + +int +SSL_peek(SSL *s, void *buf, int num) +{ + if (s->handshake_func == NULL) { + SSLerr(SSL_F_SSL_PEEK, SSL_R_UNINITIALIZED); + return (-1); + } + + if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { + return (0); + } + return (s->method->ssl_peek(s, buf, num)); +} + +int +SSL_write(SSL *s, const void *buf, int num) +{ + if (s->handshake_func == NULL) { + SSLerr(SSL_F_SSL_WRITE, SSL_R_UNINITIALIZED); + return (-1); + } + + if (s->shutdown & SSL_SENT_SHUTDOWN) { + s->rwstate = SSL_NOTHING; + SSLerr(SSL_F_SSL_WRITE, SSL_R_PROTOCOL_IS_SHUTDOWN); + return (-1); + } + return (s->method->ssl_write(s, buf, num)); +} + +int +SSL_shutdown(SSL *s) +{ + /* + * Note that this function behaves differently from what one might + * expect. Return values are 0 for no success (yet), + * 1 for success; but calling it once is usually not enough, + * even if blocking I/O is used (see ssl3_shutdown). + */ + + if (s->handshake_func == NULL) { + SSLerr(SSL_F_SSL_SHUTDOWN, SSL_R_UNINITIALIZED); + return (-1); + } + + if ((s != NULL) && !SSL_in_init(s)) + return (s->method->ssl_shutdown(s)); + else + return (1); +} + +int +SSL_renegotiate(SSL *s) +{ + if (s->renegotiate == 0) + s->renegotiate = 1; + + s->new_session = 1; + + return (s->method->ssl_renegotiate(s)); +} + +int +SSL_renegotiate_abbreviated(SSL *s) +{ + if (s->renegotiate == 0) + s->renegotiate = 1; + + s->new_session = 0; + + return (s->method->ssl_renegotiate(s)); +} + +int +SSL_renegotiate_pending(SSL *s) +{ + /* + * Becomes true when negotiation is requested; + * false again once a handshake has finished. + */ + return (s->renegotiate != 0); +} + +long +SSL_ctrl(SSL *s, int cmd, long larg, void *parg) +{ + long l; + + switch (cmd) { + case SSL_CTRL_GET_READ_AHEAD: + return (s->read_ahead); + case SSL_CTRL_SET_READ_AHEAD: + l = s->read_ahead; + s->read_ahead = larg; + return (l); + + case SSL_CTRL_SET_MSG_CALLBACK_ARG: + s->msg_callback_arg = parg; + return (1); + + case SSL_CTRL_OPTIONS: + return (s->options|=larg); + case SSL_CTRL_CLEAR_OPTIONS: + return (s->options&=~larg); + case SSL_CTRL_MODE: + return (s->mode|=larg); + case SSL_CTRL_CLEAR_MODE: + return (s->mode &=~larg); + case SSL_CTRL_GET_MAX_CERT_LIST: + return (s->max_cert_list); + case SSL_CTRL_SET_MAX_CERT_LIST: + l = s->max_cert_list; + s->max_cert_list = larg; + return (l); + case SSL_CTRL_SET_MTU: +#ifndef OPENSSL_NO_DTLS1 + if (larg < (long)dtls1_min_mtu()) + return (0); +#endif + if (SSL_IS_DTLS(s)) { + s->d1->mtu = larg; + return (larg); + } + return (0); + case SSL_CTRL_SET_MAX_SEND_FRAGMENT: + if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) + return (0); + s->max_send_fragment = larg; + return (1); + case SSL_CTRL_GET_RI_SUPPORT: + if (s->s3) + return (s->s3->send_connection_binding); + else return (0); + default: + return (s->method->ssl_ctrl(s, cmd, larg, parg)); + } +} + +long +SSL_callback_ctrl(SSL *s, int cmd, void (*fp)(void)) +{ + switch (cmd) { + case SSL_CTRL_SET_MSG_CALLBACK: + s->msg_callback = (void (*)(int write_p, int version, + int content_type, const void *buf, size_t len, + SSL *ssl, void *arg))(fp); + return (1); + + default: + return (s->method->ssl_callback_ctrl(s, cmd, fp)); + } +} + +LHASH_OF(SSL_SESSION) * +SSL_CTX_sessions(SSL_CTX *ctx) +{ + return (ctx->sessions); +} + +long +SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) +{ + long l; + + switch (cmd) { + case SSL_CTRL_GET_READ_AHEAD: + return (ctx->read_ahead); + case SSL_CTRL_SET_READ_AHEAD: + l = ctx->read_ahead; + ctx->read_ahead = larg; + return (l); + + case SSL_CTRL_SET_MSG_CALLBACK_ARG: + ctx->msg_callback_arg = parg; + return (1); + + case SSL_CTRL_GET_MAX_CERT_LIST: + return (ctx->max_cert_list); + case SSL_CTRL_SET_MAX_CERT_LIST: + l = ctx->max_cert_list; + ctx->max_cert_list = larg; + return (l); + + case SSL_CTRL_SET_SESS_CACHE_SIZE: + l = ctx->session_cache_size; + ctx->session_cache_size = larg; + return (l); + case SSL_CTRL_GET_SESS_CACHE_SIZE: + return (ctx->session_cache_size); + case SSL_CTRL_SET_SESS_CACHE_MODE: + l = ctx->session_cache_mode; + ctx->session_cache_mode = larg; + return (l); + case SSL_CTRL_GET_SESS_CACHE_MODE: + return (ctx->session_cache_mode); + + case SSL_CTRL_SESS_NUMBER: + return (lh_SSL_SESSION_num_items(ctx->sessions)); + case SSL_CTRL_SESS_CONNECT: + return (ctx->stats.sess_connect); + case SSL_CTRL_SESS_CONNECT_GOOD: + return (ctx->stats.sess_connect_good); + case SSL_CTRL_SESS_CONNECT_RENEGOTIATE: + return (ctx->stats.sess_connect_renegotiate); + case SSL_CTRL_SESS_ACCEPT: + return (ctx->stats.sess_accept); + case SSL_CTRL_SESS_ACCEPT_GOOD: + return (ctx->stats.sess_accept_good); + case SSL_CTRL_SESS_ACCEPT_RENEGOTIATE: + return (ctx->stats.sess_accept_renegotiate); + case SSL_CTRL_SESS_HIT: + return (ctx->stats.sess_hit); + case SSL_CTRL_SESS_CB_HIT: + return (ctx->stats.sess_cb_hit); + case SSL_CTRL_SESS_MISSES: + return (ctx->stats.sess_miss); + case SSL_CTRL_SESS_TIMEOUTS: + return (ctx->stats.sess_timeout); + case SSL_CTRL_SESS_CACHE_FULL: + return (ctx->stats.sess_cache_full); + case SSL_CTRL_OPTIONS: + return (ctx->options|=larg); + case SSL_CTRL_CLEAR_OPTIONS: + return (ctx->options&=~larg); + case SSL_CTRL_MODE: + return (ctx->mode|=larg); + case SSL_CTRL_CLEAR_MODE: + return (ctx->mode&=~larg); + case SSL_CTRL_SET_MAX_SEND_FRAGMENT: + if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) + return (0); + ctx->max_send_fragment = larg; + return (1); + default: + return (ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg)); + } +} + +long +SSL_CTX_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void)) +{ + switch (cmd) { + case SSL_CTRL_SET_MSG_CALLBACK: + ctx->msg_callback = (void (*)(int write_p, int version, + int content_type, const void *buf, size_t len, SSL *ssl, + void *arg))(fp); + return (1); + + default: + return (ctx->method->ssl_ctx_callback_ctrl(ctx, cmd, fp)); + } +} + +int +ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b) +{ + long l; + + l = a->id - b->id; + if (l == 0L) + return (0); + else + return ((l > 0) ? 1:-1); +} + +int +ssl_cipher_ptr_id_cmp(const SSL_CIPHER * const *ap, + const SSL_CIPHER * const *bp) +{ + long l; + + l = (*ap)->id - (*bp)->id; + if (l == 0L) + return (0); + else + return ((l > 0) ? 1:-1); +} + +/* + * Return a STACK of the ciphers available for the SSL and in order of + * preference. + */ +STACK_OF(SSL_CIPHER) * +SSL_get_ciphers(const SSL *s) +{ + if (s != NULL) { + if (s->cipher_list != NULL) { + return (s->cipher_list); + } else if ((s->ctx != NULL) && (s->ctx->cipher_list != NULL)) { + return (s->ctx->cipher_list); + } + } + return (NULL); +} + +/* + * Return a STACK of the ciphers available for the SSL and in order of + * algorithm id. + */ +STACK_OF(SSL_CIPHER) * +ssl_get_ciphers_by_id(SSL *s) +{ + if (s != NULL) { + if (s->cipher_list_by_id != NULL) { + return (s->cipher_list_by_id); + } else if ((s->ctx != NULL) && + (s->ctx->cipher_list_by_id != NULL)) { + return (s->ctx->cipher_list_by_id); + } + } + return (NULL); +} + +/* The old interface to get the same thing as SSL_get_ciphers(). */ +const char * +SSL_get_cipher_list(const SSL *s, int n) +{ + SSL_CIPHER *c; + STACK_OF(SSL_CIPHER) *sk; + + if (s == NULL) + return (NULL); + sk = SSL_get_ciphers(s); + if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= n)) + return (NULL); + c = sk_SSL_CIPHER_value(sk, n); + if (c == NULL) + return (NULL); + return (c->name); +} + +/* Specify the ciphers to be used by default by the SSL_CTX. */ +int +SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) +{ + STACK_OF(SSL_CIPHER) *sk; + + sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list, + &ctx->cipher_list_by_id, str); + /* + * ssl_create_cipher_list may return an empty stack if it + * was unable to find a cipher matching the given rule string + * (for example if the rule string specifies a cipher which + * has been disabled). This is not an error as far as + * ssl_create_cipher_list is concerned, and hence + * ctx->cipher_list and ctx->cipher_list_by_id has been + * updated. + */ + if (sk == NULL) + return (0); + else if (sk_SSL_CIPHER_num(sk) == 0) { + SSLerr(SSL_F_SSL_CTX_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH); + return (0); + } + return (1); +} + +/* Specify the ciphers to be used by the SSL. */ +int +SSL_set_cipher_list(SSL *s, const char *str) +{ + STACK_OF(SSL_CIPHER) *sk; + + sk = ssl_create_cipher_list(s->ctx->method, &s->cipher_list, + &s->cipher_list_by_id, str); + /* see comment in SSL_CTX_set_cipher_list */ + if (sk == NULL) + return (0); + else if (sk_SSL_CIPHER_num(sk) == 0) { + SSLerr(SSL_F_SSL_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH); + return (0); + } + return (1); +} + +/* works well for SSLv2, not so good for SSLv3 */ +char * +SSL_get_shared_ciphers(const SSL *s, char *buf, int len) +{ + char *end; + STACK_OF(SSL_CIPHER) *sk; + SSL_CIPHER *c; + size_t curlen = 0; + int i; + + if (s->session == NULL || s->session->ciphers == NULL || len < 2) + return (NULL); + + sk = s->session->ciphers; + if (sk_SSL_CIPHER_num(sk) == 0) + return (NULL); + + buf[0] = '\0'; + for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { + c = sk_SSL_CIPHER_value(sk, i); + end = buf + curlen; + if (strlcat(buf, c->name, len) >= len || + (curlen = strlcat(buf, ":", len)) >= len) { + /* remove truncated cipher from list */ + *end = '\0'; + break; + } + } + /* remove trailing colon */ + if ((end = strrchr(buf, ':')) != NULL) + *end = '\0'; + return (buf); +} + +int +ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, unsigned char *p) +{ + int i; + SSL_CIPHER *c; + unsigned char *q; + + if (sk == NULL) + return (0); + q = p; + + for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { + c = sk_SSL_CIPHER_value(sk, i); + + /* Skip TLS v1.2 only ciphersuites if lower than v1.2 */ + if ((c->algorithm_ssl & SSL_TLSV1_2) && + (TLS1_get_client_version(s) < TLS1_2_VERSION)) + continue; + + s2n(ssl3_cipher_get_value(c), p); + } + + /* + * If p == q, no ciphers and caller indicates an error. Otherwise + * add SCSV if not renegotiating. + */ + if (p != q && !s->renegotiate) + s2n(SSL3_CK_SCSV & SSL3_CK_VALUE_MASK, p); + + return (p - q); +} + +STACK_OF(SSL_CIPHER) * +ssl_bytes_to_cipher_list(SSL *s, const unsigned char *p, int num) +{ + CBS cbs; + const SSL_CIPHER *c; + STACK_OF(SSL_CIPHER) *sk = NULL; + unsigned long cipher_id; + uint16_t cipher_value, max_version; + + if (s->s3) + s->s3->send_connection_binding = 0; + + /* + * RFC 5246 section 7.4.1.2 defines the interval as [2,2^16-2]. + */ + if (num < 2 || num > 0x10000 - 2) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, + SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); + return (NULL); + } + + if ((sk = sk_SSL_CIPHER_new_null()) == NULL) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + goto err; + } + + CBS_init(&cbs, p, num); + while (CBS_len(&cbs) > 0) { + if (!CBS_get_u16(&cbs, &cipher_value)) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, + SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); + goto err; + } + + cipher_id = SSL3_CK_ID | cipher_value; + + if (s->s3 != NULL && cipher_id == SSL3_CK_SCSV) { + /* + * TLS_EMPTY_RENEGOTIATION_INFO_SCSV is fatal if + * renegotiating. + */ + if (s->renegotiate) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, + SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING); + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_HANDSHAKE_FAILURE); + + goto err; + } + s->s3->send_connection_binding = 1; + continue; + } + + if (cipher_id == SSL3_CK_FALLBACK_SCSV) { + /* + * TLS_FALLBACK_SCSV indicates that the client + * previously tried a higher protocol version. + * Fail if the current version is an unexpected + * downgrade. + */ + max_version = ssl_max_server_version(s); + if (max_version == 0 || s->version < max_version) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, + SSL_R_INAPPROPRIATE_FALLBACK); + if (s->s3 != NULL) + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_INAPPROPRIATE_FALLBACK); + goto err; + } + continue; + } + + if ((c = ssl3_get_cipher_by_value(cipher_value)) != NULL) { + if (!sk_SSL_CIPHER_push(sk, c)) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, + ERR_R_MALLOC_FAILURE); + goto err; + } + } + } + + return (sk); + +err: + sk_SSL_CIPHER_free(sk); + + return (NULL); +} + + +/* + * Return a servername extension value if provided in Client Hello, or NULL. + * So far, only host_name types are defined (RFC 3546). + */ +const char * +SSL_get_servername(const SSL *s, const int type) +{ + if (type != TLSEXT_NAMETYPE_host_name) + return (NULL); + + return (s->session && !s->tlsext_hostname ? + s->session->tlsext_hostname : + s->tlsext_hostname); +} + +int +SSL_get_servername_type(const SSL *s) +{ + if (s->session && + (!s->tlsext_hostname ? + s->session->tlsext_hostname : s->tlsext_hostname)) + return (TLSEXT_NAMETYPE_host_name); + return (-1); +} + +/* + * SSL_select_next_proto implements the standard protocol selection. It is + * expected that this function is called from the callback set by + * SSL_CTX_set_next_proto_select_cb. + * + * The protocol data is assumed to be a vector of 8-bit, length prefixed byte + * strings. The length byte itself is not included in the length. A byte + * string of length 0 is invalid. No byte string may be truncated. + * + * The current, but experimental algorithm for selecting the protocol is: + * + * 1) If the server doesn't support NPN then this is indicated to the + * callback. In this case, the client application has to abort the connection + * or have a default application level protocol. + * + * 2) If the server supports NPN, but advertises an empty list then the + * client selects the first protcol in its list, but indicates via the + * API that this fallback case was enacted. + * + * 3) Otherwise, the client finds the first protocol in the server's list + * that it supports and selects this protocol. This is because it's + * assumed that the server has better information about which protocol + * a client should use. + * + * 4) If the client doesn't support any of the server's advertised + * protocols, then this is treated the same as case 2. + * + * It returns either + * OPENSSL_NPN_NEGOTIATED if a common protocol was found, or + * OPENSSL_NPN_NO_OVERLAP if the fallback case was reached. + */ +int +SSL_select_next_proto(unsigned char **out, unsigned char *outlen, + const unsigned char *server, unsigned int server_len, + const unsigned char *client, unsigned int client_len) +{ + unsigned int i, j; + const unsigned char *result; + int status = OPENSSL_NPN_UNSUPPORTED; + + /* + * For each protocol in server preference order, + * see if we support it. + */ + for (i = 0; i < server_len; ) { + for (j = 0; j < client_len; ) { + if (server[i] == client[j] && + memcmp(&server[i + 1], + &client[j + 1], server[i]) == 0) { + /* We found a match */ + result = &server[i]; + status = OPENSSL_NPN_NEGOTIATED; + goto found; + } + j += client[j]; + j++; + } + i += server[i]; + i++; + } + + /* There's no overlap between our protocols and the server's list. */ + result = client; + status = OPENSSL_NPN_NO_OVERLAP; + +found: + *out = (unsigned char *) result + 1; + *outlen = result[0]; + return (status); +} + +/* + * SSL_get0_next_proto_negotiated sets *data and *len to point to the client's + * requested protocol for this connection and returns 0. If the client didn't + * request any protocol, then *data is set to NULL. + * + * Note that the client can request any protocol it chooses. The value returned + * from this function need not be a member of the list of supported protocols + * provided by the callback. + */ +void +SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, + unsigned *len) +{ + *data = s->next_proto_negotiated; + if (!*data) { + *len = 0; + } else { + *len = s->next_proto_negotiated_len; + } +} + +/* + * SSL_CTX_set_next_protos_advertised_cb sets a callback that is called when a + * TLS server needs a list of supported protocols for Next Protocol + * Negotiation. The returned list must be in wire format. The list is returned + * by setting |out| to point to it and |outlen| to its length. This memory will + * not be modified, but one should assume that the SSL* keeps a reference to + * it. + * + * The callback should return SSL_TLSEXT_ERR_OK if it wishes to advertise. + * Otherwise, no such extension will be included in the ServerHello. + */ +void +SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *ctx, int (*cb) (SSL *ssl, + const unsigned char **out, unsigned int *outlen, void *arg), void *arg) +{ + ctx->next_protos_advertised_cb = cb; + ctx->next_protos_advertised_cb_arg = arg; +} + +/* + * SSL_CTX_set_next_proto_select_cb sets a callback that is called when a + * client needs to select a protocol from the server's provided list. |out| + * must be set to point to the selected protocol (which may be within |in|). + * The length of the protocol name must be written into |outlen|. The server's + * advertised protocols are provided in |in| and |inlen|. The callback can + * assume that |in| is syntactically valid. + * + * The client must select a protocol. It is fatal to the connection if this + * callback returns a value other than SSL_TLSEXT_ERR_OK. + */ +void +SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int (*cb) (SSL *s, + unsigned char **out, unsigned char *outlen, const unsigned char *in, + unsigned int inlen, void *arg), void *arg) +{ + ctx->next_proto_select_cb = cb; + ctx->next_proto_select_cb_arg = arg; +} + +/* + * SSL_CTX_set_alpn_protos sets the ALPN protocol list to the specified + * protocols, which must be in wire-format (i.e. a series of non-empty, + * 8-bit length-prefixed strings). Returns 0 on success. + */ +int +SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, + unsigned int protos_len) +{ + free(ctx->alpn_client_proto_list); + if ((ctx->alpn_client_proto_list = malloc(protos_len)) == NULL) + return (1); + memcpy(ctx->alpn_client_proto_list, protos, protos_len); + ctx->alpn_client_proto_list_len = protos_len; + + return (0); +} + +/* + * SSL_set_alpn_protos sets the ALPN protocol list to the specified + * protocols, which must be in wire-format (i.e. a series of non-empty, + * 8-bit length-prefixed strings). Returns 0 on success. + */ +int +SSL_set_alpn_protos(SSL *ssl, const unsigned char* protos, + unsigned int protos_len) +{ + free(ssl->alpn_client_proto_list); + if ((ssl->alpn_client_proto_list = malloc(protos_len)) == NULL) + return (1); + memcpy(ssl->alpn_client_proto_list, protos, protos_len); + ssl->alpn_client_proto_list_len = protos_len; + + return (0); +} + +/* + * SSL_CTX_set_alpn_select_cb sets a callback function that is called during + * ClientHello processing in order to select an ALPN protocol from the + * client's list of offered protocols. + */ +void +SSL_CTX_set_alpn_select_cb(SSL_CTX* ctx, + int (*cb) (SSL *ssl, const unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, void *arg), void *arg) +{ + ctx->alpn_select_cb = cb; + ctx->alpn_select_cb_arg = arg; +} + +/* + * SSL_get0_alpn_selected gets the selected ALPN protocol (if any). On return + * it sets data to point to len bytes of protocol name (not including the + * leading length-prefix byte). If the server didn't respond with* a negotiated + * protocol then len will be zero. + */ +void +SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, + unsigned *len) +{ + *data = NULL; + *len = 0; + + if (ssl->s3 != NULL) { + *data = ssl->s3->alpn_selected; + *len = ssl->s3->alpn_selected_len; + } +} + +int +SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, const unsigned char *p, size_t plen, + int use_context) +{ + return (s->method->ssl3_enc->export_keying_material(s, out, olen, + label, llen, p, plen, use_context)); +} + +static unsigned long +ssl_session_hash(const SSL_SESSION *a) +{ + unsigned long l; + + l = (unsigned long) + ((unsigned int) a->session_id[0] )| + ((unsigned int) a->session_id[1]<< 8L)| + ((unsigned long)a->session_id[2]<<16L)| + ((unsigned long)a->session_id[3]<<24L); + return (l); +} + +/* + * NB: If this function (or indeed the hash function which uses a sort of + * coarser function than this one) is changed, ensure + * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on being + * able to construct an SSL_SESSION that will collide with any existing session + * with a matching session ID. + */ +static int +ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b) +{ + if (a->ssl_version != b->ssl_version) + return (1); + if (a->session_id_length != b->session_id_length) + return (1); + if (timingsafe_memcmp(a->session_id, b->session_id, a->session_id_length) != 0) + return (1); + return (0); +} + +/* + * These wrapper functions should remain rather than redeclaring + * SSL_SESSION_hash and SSL_SESSION_cmp for void* types and casting each + * variable. The reason is that the functions aren't static, they're exposed via + * ssl.h. + */ +static +IMPLEMENT_LHASH_HASH_FN(ssl_session, SSL_SESSION) +static +IMPLEMENT_LHASH_COMP_FN(ssl_session, SSL_SESSION) + +SSL_CTX * +SSL_CTX_new(const SSL_METHOD *meth) +{ + SSL_CTX *ret = NULL; + + if (meth == NULL) { + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_NULL_SSL_METHOD_PASSED); + return (NULL); + } + + if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) { + SSLerr(SSL_F_SSL_CTX_NEW, + SSL_R_X509_VERIFICATION_SETUP_PROBLEMS); + goto err; + } + ret = calloc(1, sizeof(SSL_CTX)); + if (ret == NULL) + goto err; + + ret->method = meth; + + ret->cert_store = NULL; + ret->session_cache_mode = SSL_SESS_CACHE_SERVER; + ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT; + ret->session_cache_head = NULL; + ret->session_cache_tail = NULL; + + /* We take the system default */ + ret->session_timeout = meth->get_timeout(); + + ret->new_session_cb = 0; + ret->remove_session_cb = 0; + ret->get_session_cb = 0; + ret->generate_session_id = 0; + + memset((char *)&ret->stats, 0, sizeof(ret->stats)); + + ret->references = 1; + ret->quiet_shutdown = 0; + + ret->info_callback = NULL; + + ret->app_verify_callback = 0; + ret->app_verify_arg = NULL; + + ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT; + ret->read_ahead = 0; + ret->msg_callback = 0; + ret->msg_callback_arg = NULL; + ret->verify_mode = SSL_VERIFY_NONE; + ret->sid_ctx_length = 0; + ret->default_verify_callback = NULL; + if ((ret->cert = ssl_cert_new()) == NULL) + goto err; + + ret->default_passwd_callback = 0; + ret->default_passwd_callback_userdata = NULL; + ret->client_cert_cb = 0; + ret->app_gen_cookie_cb = 0; + ret->app_verify_cookie_cb = 0; + + ret->sessions = lh_SSL_SESSION_new(); + if (ret->sessions == NULL) + goto err; + ret->cert_store = X509_STORE_new(); + if (ret->cert_store == NULL) + goto err; + + ssl_create_cipher_list(ret->method, &ret->cipher_list, + &ret->cipher_list_by_id, SSL_DEFAULT_CIPHER_LIST); + if (ret->cipher_list == NULL || + sk_SSL_CIPHER_num(ret->cipher_list) <= 0) { + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_LIBRARY_HAS_NO_CIPHERS); + goto err2; + } + + ret->param = X509_VERIFY_PARAM_new(); + if (!ret->param) + goto err; + + if ((ret->md5 = EVP_get_digestbyname("ssl3-md5")) == NULL) { + SSLerr(SSL_F_SSL_CTX_NEW, + SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES); + goto err2; + } + if ((ret->sha1 = EVP_get_digestbyname("ssl3-sha1")) == NULL) { + SSLerr(SSL_F_SSL_CTX_NEW, + SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES); + goto err2; + } + + if ((ret->client_CA = sk_X509_NAME_new_null()) == NULL) + goto err; + + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data); + + ret->extra_certs = NULL; + + ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; + + ret->tlsext_servername_callback = 0; + ret->tlsext_servername_arg = NULL; + + /* Setup RFC4507 ticket keys */ + arc4random_buf(ret->tlsext_tick_key_name, 16); + arc4random_buf(ret->tlsext_tick_hmac_key, 16); + arc4random_buf(ret->tlsext_tick_aes_key, 16); + + ret->tlsext_status_cb = 0; + ret->tlsext_status_arg = NULL; + + ret->next_protos_advertised_cb = 0; + ret->next_proto_select_cb = 0; +#ifndef OPENSSL_NO_ENGINE + ret->client_cert_engine = NULL; +#ifdef OPENSSL_SSL_CLIENT_ENGINE_AUTO +#define eng_strx(x) #x +#define eng_str(x) eng_strx(x) + /* Use specific client engine automatically... ignore errors */ + { + ENGINE *eng; + eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO)); + if (!eng) { + ERR_clear_error(); + ENGINE_load_builtin_engines(); + eng = ENGINE_by_id(eng_str( + OPENSSL_SSL_CLIENT_ENGINE_AUTO)); + } + if (!eng || !SSL_CTX_set_client_cert_engine(ret, eng)) + ERR_clear_error(); + } +#endif +#endif + /* + * Default is to connect to non-RI servers. When RI is more widely + * deployed might change this. + */ + ret->options |= SSL_OP_LEGACY_SERVER_CONNECT; + + return (ret); +err: + SSLerr(SSL_F_SSL_CTX_NEW, ERR_R_MALLOC_FAILURE); +err2: + SSL_CTX_free(ret); + return (NULL); +} + +void +SSL_CTX_free(SSL_CTX *a) +{ + int i; + + if (a == NULL) + return; + + i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_SSL_CTX); + if (i > 0) + return; + + if (a->param) + X509_VERIFY_PARAM_free(a->param); + + /* + * Free internal session cache. However: the remove_cb() may reference + * the ex_data of SSL_CTX, thus the ex_data store can only be removed + * after the sessions were flushed. + * As the ex_data handling routines might also touch the session cache, + * the most secure solution seems to be: empty (flush) the cache, then + * free ex_data, then finally free the cache. + * (See ticket [openssl.org #212].) + */ + if (a->sessions != NULL) + SSL_CTX_flush_sessions(a, 0); + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data); + + if (a->sessions != NULL) + lh_SSL_SESSION_free(a->sessions); + + if (a->cert_store != NULL) + X509_STORE_free(a->cert_store); + if (a->cipher_list != NULL) + sk_SSL_CIPHER_free(a->cipher_list); + if (a->cipher_list_by_id != NULL) + sk_SSL_CIPHER_free(a->cipher_list_by_id); + if (a->cert != NULL) + ssl_cert_free(a->cert); + if (a->client_CA != NULL) + sk_X509_NAME_pop_free(a->client_CA, X509_NAME_free); + if (a->extra_certs != NULL) + sk_X509_pop_free(a->extra_certs, X509_free); + +#ifndef OPENSSL_NO_SRTP + if (a->srtp_profiles) + sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles); +#endif + +#ifndef OPENSSL_NO_ENGINE + if (a->client_cert_engine) + ENGINE_finish(a->client_cert_engine); +#endif + + free(a->alpn_client_proto_list); + + free(a); +} + +void +SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb) +{ + ctx->default_passwd_callback = cb; +} + +void +SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u) +{ + ctx->default_passwd_callback_userdata = u; +} + +void +SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *, + void *), void *arg) +{ + ctx->app_verify_callback = cb; + ctx->app_verify_arg = arg; +} + +void +SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*cb)(int, X509_STORE_CTX *)) +{ + ctx->verify_mode = mode; + ctx->default_verify_callback = cb; +} + +void +SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) +{ + X509_VERIFY_PARAM_set_depth(ctx->param, depth); +} + +void +ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) +{ + CERT_PKEY *cpk; + int rsa_enc, rsa_sign, dh_tmp, dsa_sign; + unsigned long mask_k, mask_a; + int have_ecc_cert, ecdh_ok, ecdsa_ok; + int have_ecdh_tmp; + X509 *x = NULL; + EVP_PKEY *ecc_pkey = NULL; + int signature_nid = 0, pk_nid = 0, md_nid = 0; + + if (c == NULL) + return; + + dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL || + c->dh_tmp_auto != 0); + + have_ecdh_tmp = (c->ecdh_tmp != NULL || c->ecdh_tmp_cb != NULL || + c->ecdh_tmp_auto != 0); + cpk = &(c->pkeys[SSL_PKEY_RSA_ENC]); + rsa_enc = (cpk->x509 != NULL && cpk->privatekey != NULL); + cpk = &(c->pkeys[SSL_PKEY_RSA_SIGN]); + rsa_sign = (cpk->x509 != NULL && cpk->privatekey != NULL); + cpk = &(c->pkeys[SSL_PKEY_DSA_SIGN]); + dsa_sign = (cpk->x509 != NULL && cpk->privatekey != NULL); +/* FIX THIS EAY EAY EAY */ + cpk = &(c->pkeys[SSL_PKEY_ECC]); + have_ecc_cert = (cpk->x509 != NULL && cpk->privatekey != NULL); + mask_k = 0; + mask_a = 0; + + cpk = &(c->pkeys[SSL_PKEY_GOST01]); + if (cpk->x509 != NULL && cpk->privatekey !=NULL) { + mask_k |= SSL_kGOST; + mask_a |= SSL_aGOST01; + } + + if (rsa_enc) + mask_k|=SSL_kRSA; + + if (dh_tmp) + mask_k|=SSL_kDHE; + + if (rsa_enc || rsa_sign) + mask_a|=SSL_aRSA; + + if (dsa_sign) + mask_a|=SSL_aDSS; + + mask_a|=SSL_aNULL; + + /* + * An ECC certificate may be usable for ECDH and/or + * ECDSA cipher suites depending on the key usage extension. + */ + if (have_ecc_cert) { + /* This call populates extension flags (ex_flags) */ + x = (c->pkeys[SSL_PKEY_ECC]).x509; + X509_check_purpose(x, -1, 0); + ecdh_ok = (x->ex_flags & EXFLAG_KUSAGE) ? + (x->ex_kusage & X509v3_KU_KEY_AGREEMENT) : 1; + ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ? + (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1; + ecc_pkey = X509_get_pubkey(x); + EVP_PKEY_free(ecc_pkey); + if ((x->sig_alg) && (x->sig_alg->algorithm)) { + signature_nid = OBJ_obj2nid(x->sig_alg->algorithm); + OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid); + } + if (ecdh_ok) { + if (pk_nid == NID_rsaEncryption || pk_nid == NID_rsa) { + mask_k|=SSL_kECDHr; + mask_a|=SSL_aECDH; + } + if (pk_nid == NID_X9_62_id_ecPublicKey) { + mask_k|=SSL_kECDHe; + mask_a|=SSL_aECDH; + } + } + if (ecdsa_ok) + mask_a|=SSL_aECDSA; + } + + if (have_ecdh_tmp) { + mask_k|=SSL_kECDHE; + } + + + c->mask_k = mask_k; + c->mask_a = mask_a; + c->valid = 1; +} + +/* This handy macro borrowed from crypto/x509v3/v3_purp.c */ +#define ku_reject(x, usage) \ + (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) + + +int +ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) +{ + unsigned long alg_k, alg_a; + int signature_nid = 0, md_nid = 0, pk_nid = 0; + const SSL_CIPHER *cs = s->s3->tmp.new_cipher; + + alg_k = cs->algorithm_mkey; + alg_a = cs->algorithm_auth; + + /* This call populates the ex_flags field correctly */ + X509_check_purpose(x, -1, 0); + if ((x->sig_alg) && (x->sig_alg->algorithm)) { + signature_nid = OBJ_obj2nid(x->sig_alg->algorithm); + OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid); + } + if (alg_k & SSL_kECDHe || alg_k & SSL_kECDHr) { + /* key usage, if present, must allow key agreement */ + if (ku_reject(x, X509v3_KU_KEY_AGREEMENT)) { + SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, + SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT); + return (0); + } + if ((alg_k & SSL_kECDHe) && TLS1_get_version(s) < + TLS1_2_VERSION) { + /* signature alg must be ECDSA */ + if (pk_nid != NID_X9_62_id_ecPublicKey) { + SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, + SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE); + return (0); + } + } + if ((alg_k & SSL_kECDHr) && TLS1_get_version(s) < + TLS1_2_VERSION) { + /* signature alg must be RSA */ + if (pk_nid != NID_rsaEncryption && pk_nid != NID_rsa) { + SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, + SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE); + return (0); + } + } + } + if (alg_a & SSL_aECDSA) { + /* key usage, if present, must allow signing */ + if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE)) { + SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, + SSL_R_ECC_CERT_NOT_FOR_SIGNING); + return (0); + } + } + + return (1); + /* all checks are ok */ +} + + +/* THIS NEEDS CLEANING UP */ +CERT_PKEY * +ssl_get_server_send_pkey(const SSL *s) +{ + unsigned long alg_k, alg_a; + CERT *c; + int i; + + c = s->cert; + ssl_set_cert_masks(c, s->s3->tmp.new_cipher); + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + alg_a = s->s3->tmp.new_cipher->algorithm_auth; + + if (alg_k & (SSL_kECDHr|SSL_kECDHe)) { + /* + * We don't need to look at SSL_kECDHE + * since no certificate is needed for + * anon ECDH and for authenticated + * ECDHE, the check for the auth + * algorithm will set i correctly + * NOTE: For ECDH-RSA, we need an ECC + * not an RSA cert but for EECDH-RSA + * we need an RSA cert. Placing the + * checks for SSL_kECDH before RSA + * checks ensures the correct cert is chosen. + */ + i = SSL_PKEY_ECC; + } else if (alg_a & SSL_aECDSA) { + i = SSL_PKEY_ECC; + } else if (alg_a & SSL_aDSS) { + i = SSL_PKEY_DSA_SIGN; + } else if (alg_a & SSL_aRSA) { + if (c->pkeys[SSL_PKEY_RSA_ENC].x509 == NULL) + i = SSL_PKEY_RSA_SIGN; + else + i = SSL_PKEY_RSA_ENC; + } else if (alg_a & SSL_aGOST01) { + i = SSL_PKEY_GOST01; + } else { /* if (alg_a & SSL_aNULL) */ + SSLerr(SSL_F_SSL_GET_SERVER_SEND_PKEY, ERR_R_INTERNAL_ERROR); + return (NULL); + } + + return (c->pkeys + i); +} + +X509 * +ssl_get_server_send_cert(const SSL *s) +{ + CERT_PKEY *cpk; + + cpk = ssl_get_server_send_pkey(s); + if (!cpk) + return (NULL); + return (cpk->x509); +} + +EVP_PKEY * +ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher, const EVP_MD **pmd) +{ + unsigned long alg_a; + CERT *c; + int idx = -1; + + alg_a = cipher->algorithm_auth; + c = s->cert; + + if ((alg_a & SSL_aDSS) && + (c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL)) + idx = SSL_PKEY_DSA_SIGN; + else if (alg_a & SSL_aRSA) { + if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL) + idx = SSL_PKEY_RSA_SIGN; + else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL) + idx = SSL_PKEY_RSA_ENC; + } else if ((alg_a & SSL_aECDSA) && + (c->pkeys[SSL_PKEY_ECC].privatekey != NULL)) + idx = SSL_PKEY_ECC; + if (idx == -1) { + SSLerr(SSL_F_SSL_GET_SIGN_PKEY, ERR_R_INTERNAL_ERROR); + return (NULL); + } + if (pmd) + *pmd = c->pkeys[idx].digest; + return (c->pkeys[idx].privatekey); +} + +DH * +ssl_get_auto_dh(SSL *s) +{ + CERT_PKEY *cpk; + int keylen; + DH *dhp; + + if (s->cert->dh_tmp_auto == 2) { + keylen = 1024; + } else if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) { + keylen = 1024; + if (s->s3->tmp.new_cipher->strength_bits == 256) + keylen = 3072; + } else { + if ((cpk = ssl_get_server_send_pkey(s)) == NULL) + return (NULL); + if (cpk->privatekey == NULL || cpk->privatekey->pkey.dh == NULL) + return (NULL); + keylen = EVP_PKEY_bits(cpk->privatekey); + } + + if ((dhp = DH_new()) == NULL) + return (NULL); + + dhp->g = BN_new(); + if (dhp->g != NULL) + BN_set_word(dhp->g, 2); + + if (keylen >= 8192) + dhp->p = get_rfc3526_prime_8192(NULL); + else if (keylen >= 4096) + dhp->p = get_rfc3526_prime_4096(NULL); + else if (keylen >= 3072) + dhp->p = get_rfc3526_prime_3072(NULL); + else if (keylen >= 2048) + dhp->p = get_rfc3526_prime_2048(NULL); + else if (keylen >= 1536) + dhp->p = get_rfc3526_prime_1536(NULL); + else + dhp->p = get_rfc2409_prime_1024(NULL); + + if (dhp->p == NULL || dhp->g == NULL) { + DH_free(dhp); + return (NULL); + } + return (dhp); +} + +void +ssl_update_cache(SSL *s, int mode) +{ + int i; + + /* + * If the session_id_length is 0, we are not supposed to cache it, + * and it would be rather hard to do anyway :-) + */ + if (s->session->session_id_length == 0) + return; + + i = s->session_ctx->session_cache_mode; + if ((i & mode) && (!s->hit) && ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) + || SSL_CTX_add_session(s->session_ctx, s->session)) + && (s->session_ctx->new_session_cb != NULL)) { + CRYPTO_add(&s->session->references, 1, CRYPTO_LOCK_SSL_SESSION); + if (!s->session_ctx->new_session_cb(s, s->session)) + SSL_SESSION_free(s->session); + } + + /* auto flush every 255 connections */ + if ((!(i & SSL_SESS_CACHE_NO_AUTO_CLEAR)) && + ((i & mode) == mode)) { + if ((((mode & SSL_SESS_CACHE_CLIENT) ? + s->session_ctx->stats.sess_connect_good : + s->session_ctx->stats.sess_accept_good) & 0xff) == 0xff) { + SSL_CTX_flush_sessions(s->session_ctx, time(NULL)); + } + } +} + +const SSL_METHOD * +SSL_get_ssl_method(SSL *s) +{ + return (s->method); +} + +int +SSL_set_ssl_method(SSL *s, const SSL_METHOD *meth) +{ + int conn = -1; + int ret = 1; + + if (s->method != meth) { + if (s->handshake_func != NULL) + conn = (s->handshake_func == s->method->ssl_connect); + + if (s->method->version == meth->version) + s->method = meth; + else { + s->method->ssl_free(s); + s->method = meth; + ret = s->method->ssl_new(s); + } + + if (conn == 1) + s->handshake_func = meth->ssl_connect; + else if (conn == 0) + s->handshake_func = meth->ssl_accept; + } + return (ret); +} + +int +SSL_get_error(const SSL *s, int i) +{ + int reason; + unsigned long l; + BIO *bio; + + if (i > 0) + return (SSL_ERROR_NONE); + + /* Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake + * etc, where we do encode the error */ + if ((l = ERR_peek_error()) != 0) { + if (ERR_GET_LIB(l) == ERR_LIB_SYS) + return (SSL_ERROR_SYSCALL); + else + return (SSL_ERROR_SSL); + } + + if ((i < 0) && SSL_want_read(s)) { + bio = SSL_get_rbio(s); + if (BIO_should_read(bio)) { + return (SSL_ERROR_WANT_READ); + } else if (BIO_should_write(bio)) { + /* + * This one doesn't make too much sense... We never + * try to write to the rbio, and an application + * program where rbio and wbio are separate couldn't + * even know what it should wait for. However if we + * ever set s->rwstate incorrectly (so that we have + * SSL_want_read(s) instead of SSL_want_write(s)) + * and rbio and wbio *are* the same, this test works + * around that bug; so it might be safer to keep it. + */ + return (SSL_ERROR_WANT_WRITE); + } else if (BIO_should_io_special(bio)) { + reason = BIO_get_retry_reason(bio); + if (reason == BIO_RR_CONNECT) + return (SSL_ERROR_WANT_CONNECT); + else if (reason == BIO_RR_ACCEPT) + return (SSL_ERROR_WANT_ACCEPT); + else + return (SSL_ERROR_SYSCALL); /* unknown */ + } + } + + if ((i < 0) && SSL_want_write(s)) { + bio = SSL_get_wbio(s); + if (BIO_should_write(bio)) { + return (SSL_ERROR_WANT_WRITE); + } else if (BIO_should_read(bio)) { + /* + * See above (SSL_want_read(s) with + * BIO_should_write(bio)) + */ + return (SSL_ERROR_WANT_READ); + } else if (BIO_should_io_special(bio)) { + reason = BIO_get_retry_reason(bio); + if (reason == BIO_RR_CONNECT) + return (SSL_ERROR_WANT_CONNECT); + else if (reason == BIO_RR_ACCEPT) + return (SSL_ERROR_WANT_ACCEPT); + else + return (SSL_ERROR_SYSCALL); + } + } + if ((i < 0) && SSL_want_x509_lookup(s)) { + return (SSL_ERROR_WANT_X509_LOOKUP); + } + + if (i == 0) { + if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) && + (s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) + return (SSL_ERROR_ZERO_RETURN); + } + return (SSL_ERROR_SYSCALL); +} + +int +SSL_do_handshake(SSL *s) +{ + int ret = 1; + + if (s->handshake_func == NULL) { + SSLerr(SSL_F_SSL_DO_HANDSHAKE, SSL_R_CONNECTION_TYPE_NOT_SET); + return (-1); + } + + s->method->ssl_renegotiate_check(s); + + if (SSL_in_init(s) || SSL_in_before(s)) { + ret = s->handshake_func(s); + } + return (ret); +} + +/* + * For the next 2 functions, SSL_clear() sets shutdown and so + * one of these calls will reset it + */ +void +SSL_set_accept_state(SSL *s) +{ + s->server = 1; + s->shutdown = 0; + s->state = SSL_ST_ACCEPT|SSL_ST_BEFORE; + s->handshake_func = s->method->ssl_accept; + /* clear the current cipher */ + ssl_clear_cipher_ctx(s); + ssl_clear_hash_ctx(&s->read_hash); + ssl_clear_hash_ctx(&s->write_hash); +} + +void +SSL_set_connect_state(SSL *s) +{ + s->server = 0; + s->shutdown = 0; + s->state = SSL_ST_CONNECT|SSL_ST_BEFORE; + s->handshake_func = s->method->ssl_connect; + /* clear the current cipher */ + ssl_clear_cipher_ctx(s); + ssl_clear_hash_ctx(&s->read_hash); + ssl_clear_hash_ctx(&s->write_hash); +} + +int +ssl_undefined_function(SSL *s) +{ + SSLerr(SSL_F_SSL_UNDEFINED_FUNCTION, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); +} + +int +ssl_undefined_void_function(void) +{ + SSLerr(SSL_F_SSL_UNDEFINED_VOID_FUNCTION, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); +} + +int +ssl_undefined_const_function(const SSL *s) +{ + SSLerr(SSL_F_SSL_UNDEFINED_CONST_FUNCTION, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); +} + +const char * +ssl_version_string(int ver) +{ + switch (ver) { + case DTLS1_VERSION: + return (SSL_TXT_DTLS1); + case TLS1_VERSION: + return (SSL_TXT_TLSV1); + case TLS1_1_VERSION: + return (SSL_TXT_TLSV1_1); + case TLS1_2_VERSION: + return (SSL_TXT_TLSV1_2); + default: + return ("unknown"); + } +} + +const char * +SSL_get_version(const SSL *s) +{ + return ssl_version_string(s->version); +} + +uint16_t +ssl_max_server_version(SSL *s) +{ + uint16_t max_version; + + /* + * The SSL method will be changed during version negotiation, as such + * we want to use the SSL method from the context. + */ + max_version = s->ctx->method->version; + + if (SSL_IS_DTLS(s)) + return (DTLS1_VERSION); + + if ((s->options & SSL_OP_NO_TLSv1_2) == 0 && + max_version >= TLS1_2_VERSION) + return (TLS1_2_VERSION); + if ((s->options & SSL_OP_NO_TLSv1_1) == 0 && + max_version >= TLS1_1_VERSION) + return (TLS1_1_VERSION); + if ((s->options & SSL_OP_NO_TLSv1) == 0 && + max_version >= TLS1_VERSION) + return (TLS1_VERSION); + + return (0); +} + +SSL * +SSL_dup(SSL *s) +{ + STACK_OF(X509_NAME) *sk; + X509_NAME *xn; + SSL *ret; + int i; + + if ((ret = SSL_new(SSL_get_SSL_CTX(s))) == NULL) + return (NULL); + + ret->version = s->version; + ret->type = s->type; + ret->method = s->method; + + if (s->session != NULL) { + /* This copies session-id, SSL_METHOD, sid_ctx, and 'cert' */ + SSL_copy_session_id(ret, s); + } else { + /* + * No session has been established yet, so we have to expect + * that s->cert or ret->cert will be changed later -- + * they should not both point to the same object, + * and thus we can't use SSL_copy_session_id. + */ + + ret->method->ssl_free(ret); + ret->method = s->method; + ret->method->ssl_new(ret); + + if (s->cert != NULL) { + if (ret->cert != NULL) { + ssl_cert_free(ret->cert); + } + ret->cert = ssl_cert_dup(s->cert); + if (ret->cert == NULL) + goto err; + } + + SSL_set_session_id_context(ret, + s->sid_ctx, s->sid_ctx_length); + } + + ret->options = s->options; + ret->mode = s->mode; + SSL_set_max_cert_list(ret, SSL_get_max_cert_list(s)); + SSL_set_read_ahead(ret, SSL_get_read_ahead(s)); + ret->msg_callback = s->msg_callback; + ret->msg_callback_arg = s->msg_callback_arg; + SSL_set_verify(ret, SSL_get_verify_mode(s), + SSL_get_verify_callback(s)); + SSL_set_verify_depth(ret, SSL_get_verify_depth(s)); + ret->generate_session_id = s->generate_session_id; + + SSL_set_info_callback(ret, SSL_get_info_callback(s)); + + ret->debug = s->debug; + + /* copy app data, a little dangerous perhaps */ + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL, + &ret->ex_data, &s->ex_data)) + goto err; + + /* setup rbio, and wbio */ + if (s->rbio != NULL) { + if (!BIO_dup_state(s->rbio,(char *)&ret->rbio)) + goto err; + } + if (s->wbio != NULL) { + if (s->wbio != s->rbio) { + if (!BIO_dup_state(s->wbio,(char *)&ret->wbio)) + goto err; + } else + ret->wbio = ret->rbio; + } + ret->rwstate = s->rwstate; + ret->in_handshake = s->in_handshake; + ret->handshake_func = s->handshake_func; + ret->server = s->server; + ret->renegotiate = s->renegotiate; + ret->new_session = s->new_session; + ret->quiet_shutdown = s->quiet_shutdown; + ret->shutdown = s->shutdown; + /* SSL_dup does not really work at any state, though */ + ret->state=s->state; + ret->rstate = s->rstate; + + /* + * Would have to copy ret->init_buf, ret->init_msg, ret->init_num, + * ret->init_off + */ + ret->init_num = 0; + + ret->hit = s->hit; + + X509_VERIFY_PARAM_inherit(ret->param, s->param); + + /* dup the cipher_list and cipher_list_by_id stacks */ + if (s->cipher_list != NULL) { + if ((ret->cipher_list = + sk_SSL_CIPHER_dup(s->cipher_list)) == NULL) + goto err; + } + if (s->cipher_list_by_id != NULL) { + if ((ret->cipher_list_by_id = + sk_SSL_CIPHER_dup(s->cipher_list_by_id)) == NULL) + goto err; + } + + /* Dup the client_CA list */ + if (s->client_CA != NULL) { + if ((sk = sk_X509_NAME_dup(s->client_CA)) == NULL) goto err; + ret->client_CA = sk; + for (i = 0; i < sk_X509_NAME_num(sk); i++) { + xn = sk_X509_NAME_value(sk, i); + if (sk_X509_NAME_set(sk, i, + X509_NAME_dup(xn)) == NULL) { + X509_NAME_free(xn); + goto err; + } + } + } + + if (0) { +err: + if (ret != NULL) + SSL_free(ret); + ret = NULL; + } + return (ret); +} + +void +ssl_clear_cipher_ctx(SSL *s) +{ + EVP_CIPHER_CTX_free(s->enc_read_ctx); + s->enc_read_ctx = NULL; + EVP_CIPHER_CTX_free(s->enc_write_ctx); + s->enc_write_ctx = NULL; + + if (s->aead_read_ctx != NULL) { + EVP_AEAD_CTX_cleanup(&s->aead_read_ctx->ctx); + free(s->aead_read_ctx); + s->aead_read_ctx = NULL; + } + if (s->aead_write_ctx != NULL) { + EVP_AEAD_CTX_cleanup(&s->aead_write_ctx->ctx); + free(s->aead_write_ctx); + s->aead_write_ctx = NULL; + } + +} + +/* Fix this function so that it takes an optional type parameter */ +X509 * +SSL_get_certificate(const SSL *s) +{ + if (s->cert != NULL) + return (s->cert->key->x509); + else + return (NULL); +} + +/* Fix this function so that it takes an optional type parameter */ +EVP_PKEY * +SSL_get_privatekey(SSL *s) +{ + if (s->cert != NULL) + return (s->cert->key->privatekey); + else + return (NULL); +} + +const SSL_CIPHER * +SSL_get_current_cipher(const SSL *s) +{ + if ((s->session != NULL) && (s->session->cipher != NULL)) + return (s->session->cipher); + return (NULL); +} +const void * +SSL_get_current_compression(SSL *s) +{ + return (NULL); +} + +const void * +SSL_get_current_expansion(SSL *s) +{ + return (NULL); +} + +int +ssl_init_wbio_buffer(SSL *s, int push) +{ + BIO *bbio; + + if (s->bbio == NULL) { + bbio = BIO_new(BIO_f_buffer()); + if (bbio == NULL) + return (0); + s->bbio = bbio; + } else { + bbio = s->bbio; + if (s->bbio == s->wbio) + s->wbio = BIO_pop(s->wbio); + } + (void)BIO_reset(bbio); +/* if (!BIO_set_write_buffer_size(bbio,16*1024)) */ + if (!BIO_set_read_buffer_size(bbio, 1)) { + SSLerr(SSL_F_SSL_INIT_WBIO_BUFFER, ERR_R_BUF_LIB); + return (0); + } + if (push) { + if (s->wbio != bbio) + s->wbio = BIO_push(bbio, s->wbio); + } else { + if (s->wbio == bbio) + s->wbio = BIO_pop(bbio); + } + return (1); +} + +void +ssl_free_wbio_buffer(SSL *s) +{ + if (s == NULL) + return; + + if (s->bbio == NULL) + return; + + if (s->bbio == s->wbio) { + /* remove buffering */ + s->wbio = BIO_pop(s->wbio); + } + BIO_free(s->bbio); + s->bbio = NULL; +} + +void +SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode) +{ + ctx->quiet_shutdown = mode; +} + +int +SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx) +{ + return (ctx->quiet_shutdown); +} + +void +SSL_set_quiet_shutdown(SSL *s, int mode) +{ + s->quiet_shutdown = mode; +} + +int +SSL_get_quiet_shutdown(const SSL *s) +{ + return (s->quiet_shutdown); +} + +void +SSL_set_shutdown(SSL *s, int mode) +{ + s->shutdown = mode; +} + +int +SSL_get_shutdown(const SSL *s) +{ + return (s->shutdown); +} + +int +SSL_version(const SSL *s) +{ + return (s->version); +} + +SSL_CTX * +SSL_get_SSL_CTX(const SSL *ssl) +{ + return (ssl->ctx); +} + +SSL_CTX * +SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx) +{ + if (ssl->ctx == ctx) + return (ssl->ctx); + if (ctx == NULL) + ctx = ssl->initial_ctx; + if (ssl->cert != NULL) + ssl_cert_free(ssl->cert); + ssl->cert = ssl_cert_dup(ctx->cert); + CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); + SSL_CTX_free(ssl->ctx); /* decrement reference count */ + ssl->ctx = ctx; + return (ssl->ctx); +} + +int +SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) +{ + return (X509_STORE_set_default_paths(ctx->cert_store)); +} + +int +SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, + const char *CApath) +{ + return (X509_STORE_load_locations(ctx->cert_store, CAfile, CApath)); +} + +int +SSL_CTX_load_verify_mem(SSL_CTX *ctx, void *buf, int len) +{ + return (X509_STORE_load_mem(ctx->cert_store, buf, len)); +} + +void +SSL_set_info_callback(SSL *ssl, void (*cb)(const SSL *ssl, int type, int val)) +{ + ssl->info_callback = cb; +} + +void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl, int type, int val) +{ + return (ssl->info_callback); +} + +int +SSL_state(const SSL *ssl) +{ + return (ssl->state); +} + +void +SSL_set_state(SSL *ssl, int state) +{ + ssl->state = state; +} + +void +SSL_set_verify_result(SSL *ssl, long arg) +{ + ssl->verify_result = arg; +} + +long +SSL_get_verify_result(const SSL *ssl) +{ + return (ssl->verify_result); +} + +int +SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return (CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, argl, argp, + new_func, dup_func, free_func)); +} + +int +SSL_set_ex_data(SSL *s, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); +} + +void * +SSL_get_ex_data(const SSL *s, int idx) +{ + return (CRYPTO_get_ex_data(&s->ex_data, idx)); +} + +int +SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return (CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, argl, argp, + new_func, dup_func, free_func)); +} + +int +SSL_CTX_set_ex_data(SSL_CTX *s, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); +} + +void * +SSL_CTX_get_ex_data(const SSL_CTX *s, int idx) +{ + return (CRYPTO_get_ex_data(&s->ex_data, idx)); +} + +int +ssl_ok(SSL *s) +{ + return (1); +} + +X509_STORE * +SSL_CTX_get_cert_store(const SSL_CTX *ctx) +{ + return (ctx->cert_store); +} + +void +SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) +{ + if (ctx->cert_store != NULL) + X509_STORE_free(ctx->cert_store); + ctx->cert_store = store; +} + +int +SSL_want(const SSL *s) +{ + return (s->rwstate); +} + +void +SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx, RSA *(*cb)(SSL *ssl, int is_export, + int keylength)) +{ + SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_RSA_CB,(void (*)(void))cb); +} + +void +SSL_set_tmp_rsa_callback(SSL *ssl, RSA *(*cb)(SSL *ssl, int is_export, + int keylength)) +{ + SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_RSA_CB,(void (*)(void))cb); +} + +void +SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, DH *(*dh)(SSL *ssl, int is_export, + int keylength)) +{ + SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_DH_CB,(void (*)(void))dh); +} + +void +SSL_set_tmp_dh_callback(SSL *ssl, DH *(*dh)(SSL *ssl, int is_export, + int keylength)) +{ + SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_DH_CB,(void (*)(void))dh); +} + +void +SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx, EC_KEY *(*ecdh)(SSL *ssl, + int is_export, int keylength)) +{ + SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_ECDH_CB, + (void (*)(void))ecdh); +} + +void +SSL_set_tmp_ecdh_callback(SSL *ssl, EC_KEY *(*ecdh)(SSL *ssl, int is_export, + int keylength)) +{ + SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_ECDH_CB,(void (*)(void))ecdh); +} + + +void +SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, + int content_type, const void *buf, size_t len, SSL *ssl, void *arg)) +{ + SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_MSG_CALLBACK, + (void (*)(void))cb); +} + +void +SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, + int content_type, const void *buf, size_t len, SSL *ssl, void *arg)) +{ + SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb); +} + +void +ssl_clear_hash_ctx(EVP_MD_CTX **hash) +{ + if (*hash) + EVP_MD_CTX_destroy(*hash); + *hash = NULL; +} + +void +SSL_set_debug(SSL *s, int debug) +{ + s->debug = debug; +} + +int +SSL_cache_hit(SSL *s) +{ + return (s->hit); +} + +IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id); diff --git a/crypto/libressl/ssl/ssl_locl.h b/crypto/libressl/ssl/ssl_locl.h new file mode 100644 index 0000000000..63198fbc67 --- /dev/null +++ b/crypto/libressl/ssl/ssl_locl.h @@ -0,0 +1,847 @@ +/* $OpenBSD: ssl_locl.h,v 1.128 2015/09/12 15:08:54 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifndef HEADER_SSL_LOCL_H +#define HEADER_SSL_LOCL_H + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define c2l(c,l) (l = ((unsigned long)(*((c)++))) , \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<<24)) + +/* NOTE - c is not incremented as per c2l */ +#define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c))))<<24; \ + case 7: l2|=((unsigned long)(*(--(c))))<<16; \ + case 6: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 5: l2|=((unsigned long)(*(--(c)))); \ + case 4: l1 =((unsigned long)(*(--(c))))<<24; \ + case 3: l1|=((unsigned long)(*(--(c))))<<16; \ + case 2: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 1: l1|=((unsigned long)(*(--(c)))); \ + } \ + } + +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff)) + +#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24, \ + l|=((unsigned long)(*((c)++)))<<16, \ + l|=((unsigned long)(*((c)++)))<< 8, \ + l|=((unsigned long)(*((c)++)))) + +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +#define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \ + *((c)++)=(unsigned char)(((l)>>48)&0xff), \ + *((c)++)=(unsigned char)(((l)>>40)&0xff), \ + *((c)++)=(unsigned char)(((l)>>32)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +/* NOTE - c is not incremented as per l2c */ +#define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +#define n2s(c,s) ((s=(((unsigned int)(c[0]))<< 8)| \ + (((unsigned int)(c[1])) )),c+=2) +#define s2n(s,c) ((c[0]=(unsigned char)(((s)>> 8)&0xff), \ + c[1]=(unsigned char)(((s) )&0xff)),c+=2) + +#define n2l3(c,l) ((l =(((unsigned long)(c[0]))<<16)| \ + (((unsigned long)(c[1]))<< 8)| \ + (((unsigned long)(c[2])) )),c+=3) + +#define l2n3(l,c) ((c[0]=(unsigned char)(((l)>>16)&0xff), \ + c[1]=(unsigned char)(((l)>> 8)&0xff), \ + c[2]=(unsigned char)(((l) )&0xff)),c+=3) + +/* LOCAL STUFF */ + +#define SSL_DECRYPT 0 +#define SSL_ENCRYPT 1 + +/* + * Define the Bitmasks for SSL_CIPHER.algorithms. + * This bits are used packed as dense as possible. If new methods/ciphers + * etc will be added, the bits a likely to change, so this information + * is for internal library use only, even though SSL_CIPHER.algorithms + * can be publicly accessed. + * Use the according functions for cipher management instead. + * + * The bit mask handling in the selection and sorting scheme in + * ssl_create_cipher_list() has only limited capabilities, reflecting + * that the different entities within are mutually exclusive: + * ONLY ONE BIT PER MASK CAN BE SET AT A TIME. + */ + +/* Bits for algorithm_mkey (key exchange algorithm) */ +#define SSL_kRSA 0x00000001L /* RSA key exchange */ +#define SSL_kDHE 0x00000008L /* tmp DH key no DH cert */ +#define SSL_kECDHr 0x00000020L /* ECDH cert, RSA CA cert */ +#define SSL_kECDHe 0x00000040L /* ECDH cert, ECDSA CA cert */ +#define SSL_kECDHE 0x00000080L /* ephemeral ECDH */ +#define SSL_kGOST 0x00000200L /* GOST key exchange */ + +/* Bits for algorithm_auth (server authentication) */ +#define SSL_aRSA 0x00000001L /* RSA auth */ +#define SSL_aDSS 0x00000002L /* DSS auth */ +#define SSL_aNULL 0x00000004L /* no auth (i.e. use ADH or AECDH) */ +#define SSL_aECDH 0x00000010L /* Fixed ECDH auth (kECDHe or kECDHr) */ +#define SSL_aECDSA 0x00000040L /* ECDSA auth*/ +#define SSL_aGOST01 0x00000200L /* GOST R 34.10-2001 signature auth */ + + +/* Bits for algorithm_enc (symmetric encryption) */ +#define SSL_DES 0x00000001L +#define SSL_3DES 0x00000002L +#define SSL_RC4 0x00000004L +#define SSL_IDEA 0x00000008L +#define SSL_eNULL 0x00000010L +#define SSL_AES128 0x00000020L +#define SSL_AES256 0x00000040L +#define SSL_CAMELLIA128 0x00000080L +#define SSL_CAMELLIA256 0x00000100L +#define SSL_eGOST2814789CNT 0x00000200L +#define SSL_AES128GCM 0x00000400L +#define SSL_AES256GCM 0x00000800L +#define SSL_CHACHA20POLY1305 0x00001000L +#define SSL_CHACHA20POLY1305_OLD 0x00002000L + +#define SSL_AES (SSL_AES128|SSL_AES256|SSL_AES128GCM|SSL_AES256GCM) +#define SSL_CAMELLIA (SSL_CAMELLIA128|SSL_CAMELLIA256) + + +/* Bits for algorithm_mac (symmetric authentication) */ + +#define SSL_MD5 0x00000001L +#define SSL_SHA1 0x00000002L +#define SSL_GOST94 0x00000004L +#define SSL_GOST89MAC 0x00000008L +#define SSL_SHA256 0x00000010L +#define SSL_SHA384 0x00000020L +/* Not a real MAC, just an indication it is part of cipher */ +#define SSL_AEAD 0x00000040L +#define SSL_STREEBOG256 0x00000080L +#define SSL_STREEBOG512 0x00000100L + +/* Bits for algorithm_ssl (protocol version) */ +#define SSL_SSLV3 0x00000002L +#define SSL_TLSV1 SSL_SSLV3 /* for now */ +#define SSL_TLSV1_2 0x00000004L + + +/* Bits for algorithm2 (handshake digests and other extra flags) */ + +#define SSL_HANDSHAKE_MAC_MD5 0x10 +#define SSL_HANDSHAKE_MAC_SHA 0x20 +#define SSL_HANDSHAKE_MAC_GOST94 0x40 +#define SSL_HANDSHAKE_MAC_SHA256 0x80 +#define SSL_HANDSHAKE_MAC_SHA384 0x100 +#define SSL_HANDSHAKE_MAC_STREEBOG256 0x200 +#define SSL_HANDSHAKE_MAC_STREEBOG512 0x400 +#define SSL_HANDSHAKE_MAC_DEFAULT (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA) + +/* When adding new digest in the ssl_ciph.c and increment SSM_MD_NUM_IDX + * make sure to update this constant too */ +#define SSL_MAX_DIGEST 8 + +#define SSL3_CK_ID 0x03000000 +#define SSL3_CK_VALUE_MASK 0x0000ffff + +#define TLS1_PRF_DGST_MASK (0xff << TLS1_PRF_DGST_SHIFT) + +#define TLS1_PRF_DGST_SHIFT 10 +#define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT) +#define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT) +#define TLS1_PRF_SHA256 (SSL_HANDSHAKE_MAC_SHA256 << TLS1_PRF_DGST_SHIFT) +#define TLS1_PRF_SHA384 (SSL_HANDSHAKE_MAC_SHA384 << TLS1_PRF_DGST_SHIFT) +#define TLS1_PRF_GOST94 (SSL_HANDSHAKE_MAC_GOST94 << TLS1_PRF_DGST_SHIFT) +#define TLS1_PRF_STREEBOG256 (SSL_HANDSHAKE_MAC_STREEBOG256 << TLS1_PRF_DGST_SHIFT) +#define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1) + +/* Stream MAC for GOST ciphersuites from cryptopro draft + * (currently this also goes into algorithm2) */ +#define TLS1_STREAM_MAC 0x04 + +/* + * SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD is an algorithm2 flag that + * indicates that the variable part of the nonce is included as a prefix of + * the record (AES-GCM, for example, does this with an 8-byte variable nonce.) + */ +#define SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD (1 << 22) + +/* + * SSL_CIPHER_ALGORITHM2_AEAD is an algorithm2 flag that indicates the cipher + * is implemented via an EVP_AEAD. + */ +#define SSL_CIPHER_ALGORITHM2_AEAD (1 << 23) + +/* + * SSL_CIPHER_AEAD_FIXED_NONCE_LEN returns the number of bytes of fixed nonce + * for an SSL_CIPHER with the SSL_CIPHER_ALGORITHM2_AEAD flag. + */ +#define SSL_CIPHER_AEAD_FIXED_NONCE_LEN(ssl_cipher) \ + (((ssl_cipher->algorithm2 >> 24) & 0xf) * 2) + +/* + * Cipher strength information. + */ +#define SSL_STRONG_MASK 0x000001fcL +#define SSL_STRONG_NONE 0x00000004L +#define SSL_LOW 0x00000020L +#define SSL_MEDIUM 0x00000040L +#define SSL_HIGH 0x00000080L + +/* + * The keylength (measured in RSA key bits, I guess) for temporary keys. + * Cipher argument is so that this can be variable in the future. + */ +#define SSL_C_PKEYLENGTH(c) 1024 + +/* Check if an SSL structure is using DTLS. */ +#define SSL_IS_DTLS(s) (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) + +/* See if we need explicit IV. */ +#define SSL_USE_EXPLICIT_IV(s) \ + (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_EXPLICIT_IV) + +/* See if we use signature algorithms extension. */ +#define SSL_USE_SIGALGS(s) \ + (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SIGALGS) + +/* Allow TLS 1.2 ciphersuites: applies to DTLS 1.2 as well as TLS 1.2. */ +#define SSL_USE_TLS1_2_CIPHERS(s) \ + (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS) + +/* Mostly for SSLv3 */ +#define SSL_PKEY_RSA_ENC 0 +#define SSL_PKEY_RSA_SIGN 1 +#define SSL_PKEY_DSA_SIGN 2 +#define SSL_PKEY_DH_RSA 3 +#define SSL_PKEY_DH_DSA 4 +#define SSL_PKEY_ECC 5 +#define SSL_PKEY_GOST01 6 +#define SSL_PKEY_NUM 7 + +/* SSL_kRSA <- RSA_ENC | (RSA_TMP & RSA_SIGN) | + * <- (EXPORT & (RSA_ENC | RSA_TMP) & RSA_SIGN) + * SSL_kDH <- DH_ENC & (RSA_ENC | RSA_SIGN | DSA_SIGN) + * SSL_kDHE <- RSA_ENC | RSA_SIGN | DSA_SIGN + * SSL_aRSA <- RSA_ENC | RSA_SIGN + * SSL_aDSS <- DSA_SIGN + */ + +/* +#define CERT_INVALID 0 +#define CERT_PUBLIC_KEY 1 +#define CERT_PRIVATE_KEY 2 +*/ + +/* From ECC-TLS draft, used in encoding the curve type in + * ECParameters + */ +#define EXPLICIT_PRIME_CURVE_TYPE 1 +#define EXPLICIT_CHAR2_CURVE_TYPE 2 +#define NAMED_CURVE_TYPE 3 + +typedef struct cert_pkey_st { + X509 *x509; + EVP_PKEY *privatekey; + /* Digest to use when signing */ + const EVP_MD *digest; +} CERT_PKEY; + +typedef struct cert_st { + /* Current active set */ + CERT_PKEY *key; /* ALWAYS points to an element of the pkeys array + * Probably it would make more sense to store + * an index, not a pointer. */ + + /* The following masks are for the key and auth + * algorithms that are supported by the certs below */ + int valid; + unsigned long mask_k; + unsigned long mask_a; + + DH *dh_tmp; + DH *(*dh_tmp_cb)(SSL *ssl, int is_export, int keysize); + int dh_tmp_auto; + + EC_KEY *ecdh_tmp; + EC_KEY *(*ecdh_tmp_cb)(SSL *ssl, int is_export, int keysize); + int ecdh_tmp_auto; + + CERT_PKEY pkeys[SSL_PKEY_NUM]; + + int references; /* >1 only if SSL_copy_session_id is used */ +} CERT; + + +typedef struct sess_cert_st { + STACK_OF(X509) *cert_chain; /* as received from peer */ + + /* The 'peer_...' members are used only by clients. */ + int peer_cert_type; + + CERT_PKEY *peer_key; /* points to an element of peer_pkeys (never NULL!) */ + CERT_PKEY peer_pkeys[SSL_PKEY_NUM]; + /* Obviously we don't have the private keys of these, + * so maybe we shouldn't even use the CERT_PKEY type here. */ + + DH *peer_dh_tmp; + EC_KEY *peer_ecdh_tmp; + + int references; /* actually always 1 at the moment */ +} SESS_CERT; + + +/*#define SSL_DEBUG */ +/*#define RSA_DEBUG */ + +/* This is for the SSLv3/TLSv1.0 differences in crypto/hash stuff + * It is a bit of a mess of functions, but hell, think of it as + * an opaque structure :-) */ +typedef struct ssl3_enc_method { + int (*enc)(SSL *, int); + int (*mac)(SSL *, unsigned char *, int); + int (*setup_key_block)(SSL *); + int (*generate_master_secret)(SSL *, unsigned char *, + unsigned char *, int); + int (*change_cipher_state)(SSL *, int); + int (*final_finish_mac)(SSL *, const char *, int, unsigned char *); + int finish_mac_length; + int (*cert_verify_mac)(SSL *, int, unsigned char *); + const char *client_finished_label; + int client_finished_label_len; + const char *server_finished_label; + int server_finished_label_len; + int (*alert_value)(int); + int (*export_keying_material)(SSL *, unsigned char *, size_t, + const char *, size_t, const unsigned char *, size_t, + int use_context); + /* Flags indicating protocol version requirements. */ + unsigned int enc_flags; +} SSL3_ENC_METHOD; + +/* + * Flag values for enc_flags. + */ + +/* Uses explicit IV. */ +#define SSL_ENC_FLAG_EXPLICIT_IV (1 << 0) + +/* Uses signature algorithms extension. */ +#define SSL_ENC_FLAG_SIGALGS (1 << 1) + +/* Uses SHA256 default PRF. */ +#define SSL_ENC_FLAG_SHA256_PRF (1 << 2) + +/* Is DTLS. */ +#define SSL_ENC_FLAG_DTLS (1 << 3) + +/* Allow TLS 1.2 ciphersuites: applies to DTLS 1.2 as well as TLS 1.2. */ +#define SSL_ENC_FLAG_TLS1_2_CIPHERS (1 << 4) + +/* + * ssl_aead_ctx_st contains information about an AEAD that is being used to + * encrypt an SSL connection. + */ +struct ssl_aead_ctx_st { + EVP_AEAD_CTX ctx; + /* + * fixed_nonce contains any bytes of the nonce that are fixed for all + * records. + */ + unsigned char fixed_nonce[12]; + unsigned char fixed_nonce_len; + unsigned char variable_nonce_len; + unsigned char xor_fixed_nonce; + unsigned char tag_len; + /* + * variable_nonce_in_record is non-zero if the variable nonce + * for a record is included as a prefix before the ciphertext. + */ + char variable_nonce_in_record; +}; + +extern SSL3_ENC_METHOD ssl3_undef_enc_method; +extern SSL_CIPHER ssl3_ciphers[]; + +const char *ssl_version_string(int ver); +uint16_t ssl_max_server_version(SSL *s); + +extern SSL3_ENC_METHOD DTLSv1_enc_data; +extern SSL3_ENC_METHOD TLSv1_enc_data; +extern SSL3_ENC_METHOD TLSv1_1_enc_data; +extern SSL3_ENC_METHOD TLSv1_2_enc_data; + +void ssl_clear_cipher_ctx(SSL *s); +int ssl_clear_bad_session(SSL *s); +CERT *ssl_cert_new(void); +CERT *ssl_cert_dup(CERT *cert); +int ssl_cert_inst(CERT **o); +void ssl_cert_free(CERT *c); +SESS_CERT *ssl_sess_cert_new(void); +void ssl_sess_cert_free(SESS_CERT *sc); +int ssl_get_new_session(SSL *s, int session); +int ssl_get_prev_session(SSL *s, unsigned char *session, int len, + const unsigned char *limit); +int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b); +DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id); +int ssl_cipher_ptr_id_cmp(const SSL_CIPHER * const *ap, + const SSL_CIPHER * const *bp); +STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const unsigned char *p, + int num); +int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, + unsigned char *p); +STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *meth, + STACK_OF(SSL_CIPHER) **pref, STACK_OF(SSL_CIPHER) **sorted, + const char *rule_str); +void ssl_update_cache(SSL *s, int mode); +int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, + const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size); +int ssl_cipher_get_evp_aead(const SSL_SESSION *s, const EVP_AEAD **aead); +int ssl_get_handshake_digest(int i, long *mask, const EVP_MD **md); + +int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk); +int ssl_undefined_function(SSL *s); +int ssl_undefined_void_function(void); +int ssl_undefined_const_function(const SSL *s); +CERT_PKEY *ssl_get_server_send_pkey(const SSL *s); +X509 *ssl_get_server_send_cert(const SSL *); +EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *c, const EVP_MD **pmd); +DH *ssl_get_auto_dh(SSL *s); +int ssl_cert_type(X509 *x, EVP_PKEY *pkey); +void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher); +STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s); +int ssl_verify_alarm_type(long type); +void ssl_load_ciphers(void); + +const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p); +int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p); +int ssl3_send_server_certificate(SSL *s); +int ssl3_send_newsession_ticket(SSL *s); +int ssl3_send_cert_status(SSL *s); +int ssl3_get_finished(SSL *s, int state_a, int state_b); +int ssl3_send_change_cipher_spec(SSL *s, int state_a, int state_b); +int ssl3_do_write(SSL *s, int type); +int ssl3_send_alert(SSL *s, int level, int desc); +int ssl3_get_req_cert_type(SSL *s, unsigned char *p); +long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok); +int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen); +int ssl3_num_ciphers(void); +const SSL_CIPHER *ssl3_get_cipher(unsigned int u); +const SSL_CIPHER *ssl3_get_cipher_by_id(unsigned int id); +const SSL_CIPHER *ssl3_get_cipher_by_value(uint16_t value); +uint16_t ssl3_cipher_get_value(const SSL_CIPHER *c); +int ssl3_renegotiate(SSL *ssl); + +int ssl3_renegotiate_check(SSL *ssl); + +int ssl3_dispatch_alert(SSL *s); +int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek); +int ssl3_write_bytes(SSL *s, int type, const void *buf, int len); +unsigned long ssl3_output_cert_chain(SSL *s, X509 *x); +SSL_CIPHER *ssl3_choose_cipher(SSL *ssl, STACK_OF(SSL_CIPHER) *clnt, + STACK_OF(SSL_CIPHER) *srvr); +int ssl3_setup_buffers(SSL *s); +int ssl3_setup_init_buffer(SSL *s); +int ssl3_setup_read_buffer(SSL *s); +int ssl3_setup_write_buffer(SSL *s); +int ssl3_release_read_buffer(SSL *s); +int ssl3_release_write_buffer(SSL *s); +int ssl3_new(SSL *s); +void ssl3_free(SSL *s); +int ssl3_accept(SSL *s); +int ssl3_connect(SSL *s); +int ssl3_read(SSL *s, void *buf, int len); +int ssl3_peek(SSL *s, void *buf, int len); +int ssl3_write(SSL *s, const void *buf, int len); +int ssl3_shutdown(SSL *s); +void ssl3_clear(SSL *s); +long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg); +long ssl3_ctx_ctrl(SSL_CTX *s, int cmd, long larg, void *parg); +long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp)(void)); +long ssl3_ctx_callback_ctrl(SSL_CTX *s, int cmd, void (*fp)(void)); +int ssl3_pending(const SSL *s); + +int ssl3_handshake_msg_hdr_len(SSL *s); +unsigned char *ssl3_handshake_msg_start(SSL *s, uint8_t htype); +void ssl3_handshake_msg_finish(SSL *s, unsigned int len); +int ssl3_handshake_write(SSL *s); + +void tls1_record_sequence_increment(unsigned char *seq); +int ssl3_do_change_cipher_spec(SSL *ssl); + +int ssl23_read(SSL *s, void *buf, int len); +int ssl23_peek(SSL *s, void *buf, int len); +int ssl23_write(SSL *s, const void *buf, int len); +long ssl23_default_timeout(void); + +long tls1_default_timeout(void); +int dtls1_do_write(SSL *s, int type); +int ssl3_read_n(SSL *s, int n, int max, int extend); +int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek); +int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, + unsigned int len); +unsigned char *dtls1_set_message_header(SSL *s, unsigned char *p, + unsigned char mt, unsigned long len, unsigned long frag_off, + unsigned long frag_len); + +int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf, int len); +int dtls1_write_bytes(SSL *s, int type, const void *buf, int len); + +int dtls1_send_change_cipher_spec(SSL *s, int a, int b); +unsigned long dtls1_output_cert_chain(SSL *s, X509 *x); +int dtls1_read_failed(SSL *s, int code); +int dtls1_buffer_message(SSL *s, int ccs); +int dtls1_retransmit_message(SSL *s, unsigned short seq, + unsigned long frag_off, int *found); +int dtls1_get_queue_priority(unsigned short seq, int is_ccs); +int dtls1_retransmit_buffered_messages(SSL *s); +void dtls1_clear_record_buffer(SSL *s); +int dtls1_get_message_header(unsigned char *data, + struct hm_header_st *msg_hdr); +void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr); +void dtls1_reset_seq_numbers(SSL *s, int rw); +void dtls1_build_sequence_number(unsigned char *dst, unsigned char *seq, + unsigned short epoch); +long dtls1_default_timeout(void); +struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft); +int dtls1_check_timeout_num(SSL *s); +int dtls1_handle_timeout(SSL *s); +const SSL_CIPHER *dtls1_get_cipher(unsigned int u); +void dtls1_start_timer(SSL *s); +void dtls1_stop_timer(SSL *s); +int dtls1_is_timer_expired(SSL *s); +void dtls1_double_timeout(SSL *s); +unsigned int dtls1_min_mtu(void); + +/* some client-only functions */ +int ssl3_client_hello(SSL *s); +int ssl3_get_server_hello(SSL *s); +int ssl3_get_certificate_request(SSL *s); +int ssl3_get_new_session_ticket(SSL *s); +int ssl3_get_cert_status(SSL *s); +int ssl3_get_server_done(SSL *s); +int ssl3_send_client_verify(SSL *s); +int ssl3_send_client_certificate(SSL *s); +int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey); +int ssl3_send_client_key_exchange(SSL *s); +int ssl3_get_key_exchange(SSL *s); +int ssl3_get_server_certificate(SSL *s); +int ssl3_check_cert_and_algorithm(SSL *s); +int ssl3_check_finished(SSL *s); +int ssl3_send_next_proto(SSL *s); + +int dtls1_send_client_certificate(SSL *s); + +/* some server-only functions */ +int ssl3_get_client_hello(SSL *s); +int ssl3_send_server_hello(SSL *s); +int ssl3_send_hello_request(SSL *s); +int ssl3_send_server_key_exchange(SSL *s); +int ssl3_send_certificate_request(SSL *s); +int ssl3_send_server_done(SSL *s); +int ssl3_get_client_certificate(SSL *s); +int ssl3_get_client_key_exchange(SSL *s); +int ssl3_get_cert_verify(SSL *s); +int ssl3_get_next_proto(SSL *s); + +int dtls1_send_server_certificate(SSL *s); + +int ssl23_accept(SSL *s); +int ssl23_connect(SSL *s); +int ssl23_read_bytes(SSL *s, int n); +int ssl23_write_bytes(SSL *s); + +int tls1_new(SSL *s); +void tls1_free(SSL *s); +void tls1_clear(SSL *s); +long tls1_ctrl(SSL *s, int cmd, long larg, void *parg); +long tls1_callback_ctrl(SSL *s, int cmd, void (*fp)(void)); + +int dtls1_new(SSL *s); +int dtls1_accept(SSL *s); +int dtls1_connect(SSL *s); +void dtls1_free(SSL *s); +void dtls1_clear(SSL *s); +long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg); +int dtls1_shutdown(SSL *s); + +long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok); +int dtls1_get_record(SSL *s); +int do_dtls1_write(SSL *s, int type, const unsigned char *buf, + unsigned int len); +int dtls1_dispatch_alert(SSL *s); +int dtls1_enc(SSL *s, int snd); + +int ssl_init_wbio_buffer(SSL *s, int push); +void ssl_free_wbio_buffer(SSL *s); + +int tls1_init_finished_mac(SSL *s); +void tls1_finish_mac(SSL *s, const unsigned char *buf, int len); +void tls1_free_digest_list(SSL *s); +void tls1_cleanup_key_block(SSL *s); +int tls1_digest_cached_records(SSL *s); +int tls1_change_cipher_state(SSL *s, int which); +int tls1_setup_key_block(SSL *s); +int tls1_enc(SSL *s, int snd); +int tls1_final_finish_mac(SSL *s, const char *str, int slen, unsigned char *p); +int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *p); +int tls1_mac(SSL *ssl, unsigned char *md, int snd); +int tls1_generate_master_secret(SSL *s, unsigned char *out, + unsigned char *p, int len); +int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, const unsigned char *p, size_t plen, + int use_context); +int tls1_alert_code(int code); +int ssl_ok(SSL *s); + +int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s); + +SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n); + +int tls1_ec_curve_id2nid(uint16_t curve_id); +uint16_t tls1_ec_nid2curve_id(int nid); +int tls1_check_curve(SSL *s, const unsigned char *p, size_t len); +int tls1_get_shared_curve(SSL *s); + +unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, + unsigned char *limit); + +unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, + unsigned char *limit); + +int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, + unsigned char *d, int n, int *al); +int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, + unsigned char *d, int n, int *al); +int ssl_check_clienthello_tlsext_early(SSL *s); +int ssl_check_clienthello_tlsext_late(SSL *s); +int ssl_check_serverhello_tlsext(SSL *s); + +#define tlsext_tick_md EVP_sha256 +int tls1_process_ticket(SSL *s, const unsigned char *session_id, int len, + const unsigned char *limit, SSL_SESSION **ret); +int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, + const EVP_MD *md); +int tls12_get_sigid(const EVP_PKEY *pk); +const EVP_MD *tls12_get_hash(unsigned char hash_alg); + +void ssl_clear_hash_ctx(EVP_MD_CTX **hash); +int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, + int *len, int maxlen); +int ssl_parse_serverhello_renegotiate_ext(SSL *s, const unsigned char *d, + int len, int *al); +int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, + int *len, int maxlen); +int ssl_parse_clienthello_renegotiate_ext(SSL *s, const unsigned char *d, + int len, int *al); +long ssl_get_algorithm2(SSL *s); +int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize); +int tls12_get_req_sig_algs(SSL *s, unsigned char *p); + +int tls1_check_ec_server_key(SSL *s); +int tls1_check_ec_tmp_key(SSL *s); + +int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, + int *len, int maxlen); +int ssl_parse_clienthello_use_srtp_ext(SSL *s, const unsigned char *d, + int len, int *al); +int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, + int *len, int maxlen); +int ssl_parse_serverhello_use_srtp_ext(SSL *s, const unsigned char *d, + int len, int *al); + +/* s3_cbc.c */ +void ssl3_cbc_copy_mac(unsigned char *out, const SSL3_RECORD *rec, + unsigned md_size, unsigned orig_len); +int tls1_cbc_remove_padding(const SSL *s, SSL3_RECORD *rec, + unsigned block_size, unsigned mac_size); +char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx); +int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, unsigned char *md_out, + size_t *md_out_size, const unsigned char header[13], + const unsigned char *data, size_t data_plus_mac_size, + size_t data_plus_mac_plus_padding_size, const unsigned char *mac_secret, + unsigned mac_secret_length, char is_sslv3); + +#endif diff --git a/crypto/libressl/ssl/ssl_rsa.c b/crypto/libressl/ssl/ssl_rsa.c new file mode 100644 index 0000000000..a9bb38d27a --- /dev/null +++ b/crypto/libressl/ssl/ssl_rsa.c @@ -0,0 +1,751 @@ +/* $OpenBSD: ssl_rsa.c,v 1.20 2015/02/06 01:37:11 reyk Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include "ssl_locl.h" + +#include +#include +#include +#include +#include + +static int ssl_set_cert(CERT *c, X509 *x509); +static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey); +static int ssl_ctx_use_certificate_chain_bio(SSL_CTX *, BIO *); + +int +SSL_use_certificate(SSL *ssl, X509 *x) +{ + if (x == NULL) { + SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (!ssl_cert_inst(&ssl->cert)) { + SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_MALLOC_FAILURE); + return (0); + } + return (ssl_set_cert(ssl->cert, x)); +} + +int +SSL_use_certificate_file(SSL *ssl, const char *file, int type) +{ + int j; + BIO *in; + int ret = 0; + X509 *x = NULL; + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + x = d2i_X509_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + x = PEM_read_bio_X509(in, NULL, + ssl->ctx->default_passwd_callback, + ssl->ctx->default_passwd_callback_userdata); + } else { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (x == NULL) { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, j); + goto end; + } + + ret = SSL_use_certificate(ssl, x); +end: + X509_free(x); + BIO_free(in); + return (ret); +} + +int +SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len) +{ + X509 *x; + int ret; + + x = d2i_X509(NULL, &d,(long)len); + if (x == NULL) { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_use_certificate(ssl, x); + X509_free(x); + return (ret); +} + +int +SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) +{ + EVP_PKEY *pkey; + int ret; + + if (rsa == NULL) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (!ssl_cert_inst(&ssl->cert)) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_MALLOC_FAILURE); + return (0); + } + if ((pkey = EVP_PKEY_new()) == NULL) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB); + return (0); + } + + RSA_up_ref(rsa); + EVP_PKEY_assign_RSA(pkey, rsa); + + ret = ssl_set_pkey(ssl->cert, pkey); + EVP_PKEY_free(pkey); + return (ret); +} + +static int +ssl_set_pkey(CERT *c, EVP_PKEY *pkey) +{ + int i; + + i = ssl_cert_type(NULL, pkey); + if (i < 0) { + SSLerr(SSL_F_SSL_SET_PKEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + return (0); + } + + if (c->pkeys[i].x509 != NULL) { + EVP_PKEY *pktmp; + pktmp = X509_get_pubkey(c->pkeys[i].x509); + EVP_PKEY_copy_parameters(pktmp, pkey); + EVP_PKEY_free(pktmp); + ERR_clear_error(); + + /* + * Don't check the public/private key, this is mostly + * for smart cards. + */ + if ((pkey->type == EVP_PKEY_RSA) && + (RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK)) +; + else + if (!X509_check_private_key(c->pkeys[i].x509, pkey)) { + X509_free(c->pkeys[i].x509); + c->pkeys[i].x509 = NULL; + return 0; + } + } + + EVP_PKEY_free(c->pkeys[i].privatekey); + CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); + c->pkeys[i].privatekey = pkey; + c->key = &(c->pkeys[i]); + + c->valid = 0; + return (1); +} + +int +SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) +{ + int j, ret = 0; + BIO *in; + RSA *rsa = NULL; + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + rsa = d2i_RSAPrivateKey_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + rsa = PEM_read_bio_RSAPrivateKey(in, NULL, + ssl->ctx->default_passwd_callback, + ssl->ctx->default_passwd_callback_userdata); + } else { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + if (rsa == NULL) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, j); + goto end; + } + ret = SSL_use_RSAPrivateKey(ssl, rsa); + RSA_free(rsa); +end: + BIO_free(in); + return (ret); +} + +int +SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len) +{ + int ret; + const unsigned char *p; + RSA *rsa; + + p = d; + if ((rsa = d2i_RSAPrivateKey(NULL, &p,(long)len)) == NULL) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_use_RSAPrivateKey(ssl, rsa); + RSA_free(rsa); + return (ret); +} + +int +SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) +{ + int ret; + + if (pkey == NULL) { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (!ssl_cert_inst(&ssl->cert)) { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE); + return (0); + } + ret = ssl_set_pkey(ssl->cert, pkey); + return (ret); +} + +int +SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) +{ + int j, ret = 0; + BIO *in; + EVP_PKEY *pkey = NULL; + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + pkey = PEM_read_bio_PrivateKey(in, NULL, + ssl->ctx->default_passwd_callback, + ssl->ctx->default_passwd_callback_userdata); + } else if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + pkey = d2i_PrivateKey_bio(in, NULL); + } else { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + if (pkey == NULL) { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, j); + goto end; + } + ret = SSL_use_PrivateKey(ssl, pkey); + EVP_PKEY_free(pkey); +end: + BIO_free(in); + return (ret); +} + +int +SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len) +{ + int ret; + const unsigned char *p; + EVP_PKEY *pkey; + + p = d; + if ((pkey = d2i_PrivateKey(type, NULL, &p,(long)len)) == NULL) { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_use_PrivateKey(ssl, pkey); + EVP_PKEY_free(pkey); + return (ret); +} + +int +SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) +{ + if (x == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (!ssl_cert_inst(&ctx->cert)) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_MALLOC_FAILURE); + return (0); + } + return (ssl_set_cert(ctx->cert, x)); +} + +static int +ssl_set_cert(CERT *c, X509 *x) +{ + EVP_PKEY *pkey; + int i; + + pkey = X509_get_pubkey(x); + if (pkey == NULL) { + SSLerr(SSL_F_SSL_SET_CERT, SSL_R_X509_LIB); + return (0); + } + + i = ssl_cert_type(x, pkey); + if (i < 0) { + SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + EVP_PKEY_free(pkey); + return (0); + } + + if (c->pkeys[i].privatekey != NULL) { + EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey); + ERR_clear_error(); + + /* + * Don't check the public/private key, this is mostly + * for smart cards. + */ + if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) && + (RSA_flags(c->pkeys[i].privatekey->pkey.rsa) & + RSA_METHOD_FLAG_NO_CHECK)) +; + else + if (!X509_check_private_key(x, c->pkeys[i].privatekey)) { + /* + * don't fail for a cert/key mismatch, just free + * current private key (when switching to a different + * cert & key, first this function should be used, + * then ssl_set_pkey + */ + EVP_PKEY_free(c->pkeys[i].privatekey); + c->pkeys[i].privatekey = NULL; + /* clear error queue */ + ERR_clear_error(); + } + } + + EVP_PKEY_free(pkey); + + X509_free(c->pkeys[i].x509); + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + c->pkeys[i].x509 = x; + c->key = &(c->pkeys[i]); + + c->valid = 0; + return (1); +} + +int +SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) +{ + int j; + BIO *in; + int ret = 0; + X509 *x = NULL; + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + x = d2i_X509_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + } else { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (x == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, j); + goto end; + } + + ret = SSL_CTX_use_certificate(ctx, x); +end: + X509_free(x); + BIO_free(in); + return (ret); +} + +int +SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d) +{ + X509 *x; + int ret; + + x = d2i_X509(NULL, &d,(long)len); + if (x == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_CTX_use_certificate(ctx, x); + X509_free(x); + return (ret); +} + +int +SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) +{ + int ret; + EVP_PKEY *pkey; + + if (rsa == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (!ssl_cert_inst(&ctx->cert)) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_MALLOC_FAILURE); + return (0); + } + if ((pkey = EVP_PKEY_new()) == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB); + return (0); + } + + RSA_up_ref(rsa); + EVP_PKEY_assign_RSA(pkey, rsa); + + ret = ssl_set_pkey(ctx->cert, pkey); + EVP_PKEY_free(pkey); + return (ret); +} + +int +SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) +{ + int j, ret = 0; + BIO *in; + RSA *rsa = NULL; + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + rsa = d2i_RSAPrivateKey_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + rsa = PEM_read_bio_RSAPrivateKey(in, NULL, + ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + } else { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + if (rsa == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, j); + goto end; + } + ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); + RSA_free(rsa); +end: + BIO_free(in); + return (ret); +} + +int +SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len) +{ + int ret; + const unsigned char *p; + RSA *rsa; + + p = d; + if ((rsa = d2i_RSAPrivateKey(NULL, &p,(long)len)) == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); + RSA_free(rsa); + return (ret); +} + +int +SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) +{ + if (pkey == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, + ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (!ssl_cert_inst(&ctx->cert)) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE); + return (0); + } + return (ssl_set_pkey(ctx->cert, pkey)); +} + +int +SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) +{ + int j, ret = 0; + BIO *in; + EVP_PKEY *pkey = NULL; + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + pkey = PEM_read_bio_PrivateKey(in, NULL, + ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + } else if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + pkey = d2i_PrivateKey_bio(in, NULL); + } else { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, + SSL_R_BAD_SSL_FILETYPE); + goto end; + } + if (pkey == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, j); + goto end; + } + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + EVP_PKEY_free(pkey); +end: + BIO_free(in); + return (ret); +} + +int +SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d, + long len) +{ + int ret; + const unsigned char *p; + EVP_PKEY *pkey; + + p = d; + if ((pkey = d2i_PrivateKey(type, NULL, &p,(long)len)) == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + EVP_PKEY_free(pkey); + return (ret); +} + + +/* + * Read a bio that contains our certificate in "PEM" format, + * possibly followed by a sequence of CA certificates that should be + * sent to the peer in the Certificate message. + */ +static int +ssl_ctx_use_certificate_chain_bio(SSL_CTX *ctx, BIO *in) +{ + int ret = 0; + X509 *x = NULL; + + ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */ + + x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + if (x == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB); + goto end; + } + + ret = SSL_CTX_use_certificate(ctx, x); + + if (ERR_peek_error() != 0) + ret = 0; + /* Key/certificate mismatch doesn't imply ret==0 ... */ + if (ret) { + /* + * If we could set up our certificate, now proceed to + * the CA certificates. + */ + X509 *ca; + int r; + unsigned long err; + + if (ctx->extra_certs != NULL) { + sk_X509_pop_free(ctx->extra_certs, X509_free); + ctx->extra_certs = NULL; + } + + while ((ca = PEM_read_bio_X509(in, NULL, + ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata)) != NULL) { + r = SSL_CTX_add_extra_chain_cert(ctx, ca); + if (!r) { + X509_free(ca); + ret = 0; + goto end; + } + /* + * Note that we must not free r if it was successfully + * added to the chain (while we must free the main + * certificate, since its reference count is increased + * by SSL_CTX_use_certificate). + */ + } + + /* When the while loop ends, it's usually just EOF. */ + err = ERR_peek_last_error(); + if (ERR_GET_LIB(err) == ERR_LIB_PEM && + ERR_GET_REASON(err) == PEM_R_NO_START_LINE) + ERR_clear_error(); + else + ret = 0; /* some real error */ + } + +end: + X509_free(x); + return (ret); +} + +int +SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) +{ + BIO *in; + int ret = 0; + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_SYS_LIB); + goto end; + } + + ret = ssl_ctx_use_certificate_chain_bio(ctx, in); + +end: + BIO_free(in); + return (ret); +} + +int +SSL_CTX_use_certificate_chain_mem(SSL_CTX *ctx, void *buf, int len) +{ + BIO *in; + int ret = 0; + + in = BIO_new_mem_buf(buf, len); + if (in == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB); + goto end; + } + + ret = ssl_ctx_use_certificate_chain_bio(ctx, in); + +end: + BIO_free(in); + return (ret); +} diff --git a/crypto/libressl/ssl/ssl_sess.c b/crypto/libressl/ssl/ssl_sess.c new file mode 100644 index 0000000000..102f4dddec --- /dev/null +++ b/crypto/libressl/ssl/ssl_sess.c @@ -0,0 +1,1099 @@ +/* $OpenBSD: ssl_sess.c,v 1.48 2015/09/10 17:57:50 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include + +#ifndef OPENSSL_NO_ENGINE +#include +#endif + +#include "ssl_locl.h" + +static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s); +static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s); +static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck); + +/* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */ +SSL_SESSION * +SSL_get_session(const SSL *ssl) +{ + return (ssl->session); +} + +/* variant of SSL_get_session: caller really gets something */ +SSL_SESSION * +SSL_get1_session(SSL *ssl) +{ + SSL_SESSION *sess; + + /* + * Need to lock this all up rather than just use CRYPTO_add so that + * somebody doesn't free ssl->session between when we check it's + * non-null and when we up the reference count. + */ + CRYPTO_w_lock(CRYPTO_LOCK_SSL_SESSION); + sess = ssl->session; + if (sess) + sess->references++; + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_SESSION); + + return (sess); +} + +int +SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, + argl, argp, new_func, dup_func, free_func); +} + +int +SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); +} + +void * +SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx) +{ + return (CRYPTO_get_ex_data(&s->ex_data, idx)); +} + +SSL_SESSION * +SSL_SESSION_new(void) +{ + SSL_SESSION *ss; + + ss = calloc(1, sizeof(SSL_SESSION)); + if (ss == NULL) { + SSLerr(SSL_F_SSL_SESSION_NEW, ERR_R_MALLOC_FAILURE); + return (0); + } + + ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */ + ss->references = 1; + ss->timeout=60*5+4; /* 5 minute timeout by default */ + ss->time = time(NULL); + ss->prev = NULL; + ss->next = NULL; + ss->tlsext_hostname = NULL; + + ss->tlsext_ecpointformatlist_length = 0; + ss->tlsext_ecpointformatlist = NULL; + ss->tlsext_ellipticcurvelist_length = 0; + ss->tlsext_ellipticcurvelist = NULL; + + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); + + return (ss); +} + +const unsigned char * +SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len) +{ + if (len) + *len = s->session_id_length; + return s->session_id; +} + +unsigned int +SSL_SESSION_get_compress_id(const SSL_SESSION *s) +{ + return 0; +} + +/* + * SSLv3/TLSv1 has 32 bytes (256 bits) of session ID space. As such, filling + * the ID with random gunk repeatedly until we have no conflict is going to + * complete in one iteration pretty much "most" of the time (btw: + * understatement). So, if it takes us 10 iterations and we still can't avoid + * a conflict - well that's a reasonable point to call it quits. Either the + * arc4random code is broken or someone is trying to open roughly very close to + * 2^128 (or 2^256) SSL sessions to our server. How you might store that many + * sessions is perhaps a more interesting question... + */ + +#define MAX_SESS_ID_ATTEMPTS 10 + +static int +def_generate_session_id(const SSL *ssl, unsigned char *id, unsigned int *id_len) +{ + unsigned int retry = 0; + + do { + arc4random_buf(id, *id_len); + } while (SSL_has_matching_session_id(ssl, id, *id_len) && + (++retry < MAX_SESS_ID_ATTEMPTS)); + + if (retry < MAX_SESS_ID_ATTEMPTS) + return 1; + + /* else - woops a session_id match */ + /* XXX We should also check the external cache -- + * but the probability of a collision is negligible, and + * we could not prevent the concurrent creation of sessions + * with identical IDs since we currently don't have means + * to atomically check whether a session ID already exists + * and make a reservation for it if it does not + * (this problem applies to the internal cache as well). + */ + return 0; +} + +int +ssl_get_new_session(SSL *s, int session) +{ + unsigned int tmp; + SSL_SESSION *ss = NULL; + GEN_SESSION_CB cb = def_generate_session_id; + + /* This gets used by clients and servers. */ + + if ((ss = SSL_SESSION_new()) == NULL) + return (0); + + /* If the context has a default timeout, use it */ + if (s->session_ctx->session_timeout == 0) + ss->timeout = SSL_get_default_timeout(s); + else + ss->timeout = s->session_ctx->session_timeout; + + if (s->session != NULL) { + SSL_SESSION_free(s->session); + s->session = NULL; + } + + if (session) { + switch (s->version) { + case TLS1_VERSION: + case TLS1_1_VERSION: + case TLS1_2_VERSION: + case DTLS1_VERSION: + ss->ssl_version = s->version; + ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; + break; + default: + SSLerr(SSL_F_SSL_GET_NEW_SESSION, + SSL_R_UNSUPPORTED_SSL_VERSION); + SSL_SESSION_free(ss); + return (0); + } + + /* If RFC4507 ticket use empty session ID. */ + if (s->tlsext_ticket_expected) { + ss->session_id_length = 0; + goto sess_id_done; + } + + /* Choose which callback will set the session ID. */ + CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); + if (s->generate_session_id) + cb = s->generate_session_id; + else if (s->session_ctx->generate_session_id) + cb = s->session_ctx->generate_session_id; + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + + /* Choose a session ID. */ + tmp = ss->session_id_length; + if (!cb(s, ss->session_id, &tmp)) { + /* The callback failed */ + SSLerr(SSL_F_SSL_GET_NEW_SESSION, + SSL_R_SSL_SESSION_ID_CALLBACK_FAILED); + SSL_SESSION_free(ss); + return (0); + } + + /* + * Don't allow the callback to set the session length to zero. + * nor set it higher than it was. + */ + if (!tmp || (tmp > ss->session_id_length)) { + /* The callback set an illegal length */ + SSLerr(SSL_F_SSL_GET_NEW_SESSION, + SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH); + SSL_SESSION_free(ss); + return (0); + } + ss->session_id_length = tmp; + + /* Finally, check for a conflict. */ + if (SSL_has_matching_session_id(s, ss->session_id, + ss->session_id_length)) { + SSLerr(SSL_F_SSL_GET_NEW_SESSION, + SSL_R_SSL_SESSION_ID_CONFLICT); + SSL_SESSION_free(ss); + return (0); + } + +sess_id_done: + if (s->tlsext_hostname) { + ss->tlsext_hostname = strdup(s->tlsext_hostname); + if (ss->tlsext_hostname == NULL) { + SSLerr(SSL_F_SSL_GET_NEW_SESSION, + ERR_R_INTERNAL_ERROR); + SSL_SESSION_free(ss); + return 0; + } + } + } else { + ss->session_id_length = 0; + } + + if (s->sid_ctx_length > sizeof ss->sid_ctx) { + SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR); + SSL_SESSION_free(ss); + return 0; + } + + memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length); + ss->sid_ctx_length = s->sid_ctx_length; + s->session = ss; + ss->ssl_version = s->version; + ss->verify_result = X509_V_OK; + + return (1); +} + +/* + * ssl_get_prev attempts to find an SSL_SESSION to be used to resume this + * connection. It is only called by servers. + * + * session_id: points at the session ID in the ClientHello. This code will + * read past the end of this in order to parse out the session ticket + * extension, if any. + * len: the length of the session ID. + * limit: a pointer to the first byte after the ClientHello. + * + * Returns: + * -1: error + * 0: a session may have been found. + * + * Side effects: + * - If a session is found then s->session is pointed at it (after freeing + * an existing session if need be) and s->verify_result is set from the + * session. + * - Both for new and resumed sessions, s->tlsext_ticket_expected is set + * to 1 if the server should issue a new session ticket (to 0 otherwise). + */ +int +ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, + const unsigned char *limit) +{ + SSL_SESSION *ret = NULL; + int fatal = 0; + int try_session_cache = 1; + int r; + + /* This is used only by servers. */ + + if (len > SSL_MAX_SSL_SESSION_ID_LENGTH) + goto err; + + if (len == 0) + try_session_cache = 0; + + /* Sets s->tlsext_ticket_expected. */ + r = tls1_process_ticket(s, session_id, len, limit, &ret); + switch (r) { + case -1: /* Error during processing */ + fatal = 1; + goto err; + case 0: /* No ticket found */ + case 1: /* Zero length ticket found */ + break; /* Ok to carry on processing session id. */ + case 2: /* Ticket found but not decrypted. */ + case 3: /* Ticket decrypted, *ret has been set. */ + try_session_cache = 0; + break; + default: + abort(); + } + + if (try_session_cache && ret == NULL && + !(s->session_ctx->session_cache_mode & + SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) { + SSL_SESSION data; + data.ssl_version = s->version; + data.session_id_length = len; + memcpy(data.session_id, session_id, len); + + CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); + ret = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data); + if (ret != NULL) { + /* Don't allow other threads to steal it. */ + CRYPTO_add(&ret->references, 1, + CRYPTO_LOCK_SSL_SESSION); + } + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + + if (ret == NULL) + s->session_ctx->stats.sess_miss++; + } + + if (try_session_cache && ret == NULL && + s->session_ctx->get_session_cb != NULL) { + int copy = 1; + + if ((ret = s->session_ctx->get_session_cb(s, session_id, + len, ©))) { + s->session_ctx->stats.sess_cb_hit++; + + /* + * Increment reference count now if the session + * callback asks us to do so (note that if the session + * structures returned by the callback are shared + * between threads, it must handle the reference count + * itself [i.e. copy == 0], or things won't be + * thread-safe). + */ + if (copy) + CRYPTO_add(&ret->references, 1, + CRYPTO_LOCK_SSL_SESSION); + + /* + * Add the externally cached session to the internal + * cache as well if and only if we are supposed to. + */ + if (!(s->session_ctx->session_cache_mode & + SSL_SESS_CACHE_NO_INTERNAL_STORE)) + /* + * The following should not return 1, + * otherwise, things are very strange. + */ + SSL_CTX_add_session(s->session_ctx, ret); + } + } + + if (ret == NULL) + goto err; + + /* Now ret is non-NULL and we own one of its reference counts. */ + + if (ret->sid_ctx_length != s->sid_ctx_length || + timingsafe_memcmp(ret->sid_ctx, + s->sid_ctx, ret->sid_ctx_length) != 0) { + /* We have the session requested by the client, but we don't + * want to use it in this context. */ + goto err; /* treat like cache miss */ + } + + if ((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) { + /* + * We can't be sure if this session is being used out of + * context, which is especially important for SSL_VERIFY_PEER. + * The application should have used + * SSL[_CTX]_set_session_id_context. + * + * For this error case, we generate an error instead of treating + * the event like a cache miss (otherwise it would be easy for + * applications to effectively disable the session cache by + * accident without anyone noticing). + */ + SSLerr(SSL_F_SSL_GET_PREV_SESSION, + SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED); + fatal = 1; + goto err; + } + + if (ret->cipher == NULL) { + ret->cipher = ssl3_get_cipher_by_id(ret->cipher_id); + if (ret->cipher == NULL) + goto err; + } + + if (ret->timeout < (time(NULL) - ret->time)) { + /* timeout */ + s->session_ctx->stats.sess_timeout++; + if (try_session_cache) { + /* session was from the cache, so remove it */ + SSL_CTX_remove_session(s->session_ctx, ret); + } + goto err; + } + + s->session_ctx->stats.sess_hit++; + + if (s->session != NULL) + SSL_SESSION_free(s->session); + s->session = ret; + s->verify_result = s->session->verify_result; + return 1; + +err: + if (ret != NULL) { + SSL_SESSION_free(ret); + if (!try_session_cache) { + /* + * The session was from a ticket, so we should + * issue a ticket for the new session. + */ + s->tlsext_ticket_expected = 1; + } + } + if (fatal) + return -1; + else + return 0; +} + +int +SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) +{ + int ret = 0; + SSL_SESSION *s; + + /* + * Add just 1 reference count for the SSL_CTX's session cache + * even though it has two ways of access: each session is in a + * doubly linked list and an lhash. + */ + CRYPTO_add(&c->references, 1, CRYPTO_LOCK_SSL_SESSION); + + /* + * If session c is in already in cache, we take back the increment + * later. + */ + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + s = lh_SSL_SESSION_insert(ctx->sessions, c); + + /* + * s != NULL iff we already had a session with the given PID. + * In this case, s == c should hold (then we did not really modify + * ctx->sessions), or we're in trouble. + */ + if (s != NULL && s != c) { + /* We *are* in trouble ... */ + SSL_SESSION_list_remove(ctx, s); + SSL_SESSION_free(s); + /* + * ... so pretend the other session did not exist in cache + * (we cannot handle two SSL_SESSION structures with identical + * session ID in the same cache, which could happen e.g. when + * two threads concurrently obtain the same session from an + * external cache). + */ + s = NULL; + } + + /* Put at the head of the queue unless it is already in the cache */ + if (s == NULL) + SSL_SESSION_list_add(ctx, c); + + if (s != NULL) { + /* + * existing cache entry -- decrement previously incremented + * reference count because it already takes into account the + * cache. + */ + SSL_SESSION_free(s); /* s == c */ + ret = 0; + } else { + /* + * New cache entry -- remove old ones if cache has become + * too large. + */ + + ret = 1; + + if (SSL_CTX_sess_get_cache_size(ctx) > 0) { + while (SSL_CTX_sess_number(ctx) > + SSL_CTX_sess_get_cache_size(ctx)) { + if (!remove_session_lock(ctx, + ctx->session_cache_tail, 0)) + break; + else + ctx->stats.sess_cache_full++; + } + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + return (ret); +} + +int +SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c) +{ + return remove_session_lock(ctx, c, 1); +} + +static int +remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck) +{ + SSL_SESSION *r; + int ret = 0; + + if ((c != NULL) && (c->session_id_length != 0)) { + if (lck) + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) == c) { + ret = 1; + r = lh_SSL_SESSION_delete(ctx->sessions, c); + SSL_SESSION_list_remove(ctx, c); + } + if (lck) + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + + if (ret) { + r->not_resumable = 1; + if (ctx->remove_session_cb != NULL) + ctx->remove_session_cb(ctx, r); + SSL_SESSION_free(r); + } + } else + ret = 0; + return (ret); +} + +void +SSL_SESSION_free(SSL_SESSION *ss) +{ + int i; + + if (ss == NULL) + return; + + i = CRYPTO_add(&ss->references, -1, CRYPTO_LOCK_SSL_SESSION); + if (i > 0) + return; + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); + + explicit_bzero(ss->master_key, sizeof ss->master_key); + explicit_bzero(ss->session_id, sizeof ss->session_id); + if (ss->sess_cert != NULL) + ssl_sess_cert_free(ss->sess_cert); + X509_free(ss->peer); + if (ss->ciphers != NULL) + sk_SSL_CIPHER_free(ss->ciphers); + free(ss->tlsext_hostname); + free(ss->tlsext_tick); + ss->tlsext_ecpointformatlist_length = 0; + free(ss->tlsext_ecpointformatlist); + ss->tlsext_ellipticcurvelist_length = 0; + free(ss->tlsext_ellipticcurvelist); + explicit_bzero(ss, sizeof(*ss)); + free(ss); +} + +int +SSL_set_session(SSL *s, SSL_SESSION *session) +{ + int ret = 0; + const SSL_METHOD *meth; + + if (session != NULL) { + meth = s->ctx->method->get_ssl_method(session->ssl_version); + if (meth == NULL) + meth = s->method->get_ssl_method(session->ssl_version); + if (meth == NULL) { + SSLerr(SSL_F_SSL_SET_SESSION, + SSL_R_UNABLE_TO_FIND_SSL_METHOD); + return (0); + } + + if (meth != s->method) { + if (!SSL_set_ssl_method(s, meth)) + return (0); + } + + + /* CRYPTO_w_lock(CRYPTO_LOCK_SSL);*/ + CRYPTO_add(&session->references, 1, CRYPTO_LOCK_SSL_SESSION); + if (s->session != NULL) + SSL_SESSION_free(s->session); + s->session = session; + s->verify_result = s->session->verify_result; + /* CRYPTO_w_unlock(CRYPTO_LOCK_SSL);*/ + ret = 1; + } else { + if (s->session != NULL) { + SSL_SESSION_free(s->session); + s->session = NULL; + } + + meth = s->ctx->method; + if (meth != s->method) { + if (!SSL_set_ssl_method(s, meth)) + return (0); + } + ret = 1; + } + return (ret); +} + +long +SSL_SESSION_set_timeout(SSL_SESSION *s, long t) +{ + if (s == NULL) + return (0); + s->timeout = t; + return (1); +} + +long +SSL_SESSION_get_timeout(const SSL_SESSION *s) +{ + if (s == NULL) + return (0); + return (s->timeout); +} + +/* XXX 2038 */ +long +SSL_SESSION_get_time(const SSL_SESSION *s) +{ + if (s == NULL) + return (0); + return (s->time); +} + +/* XXX 2038 */ +long +SSL_SESSION_set_time(SSL_SESSION *s, long t) +{ + if (s == NULL) + return (0); + s->time = t; + return (t); +} + +X509 * +SSL_SESSION_get0_peer(SSL_SESSION *s) +{ + return s->peer; +} + +int +SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, + unsigned int sid_ctx_len) +{ + if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) { + SSLerr(SSL_F_SSL_SESSION_SET1_ID_CONTEXT, + SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + return 0; + } + s->sid_ctx_length = sid_ctx_len; + memcpy(s->sid_ctx, sid_ctx, sid_ctx_len); + + return 1; +} + +long +SSL_CTX_set_timeout(SSL_CTX *s, long t) +{ + long l; + + if (s == NULL) + return (0); + l = s->session_timeout; + s->session_timeout = t; + + return (l); +} + +long +SSL_CTX_get_timeout(const SSL_CTX *s) +{ + if (s == NULL) + return (0); + return (s->session_timeout); +} + +int +SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, + void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, + SSL_CIPHER **cipher, void *arg), void *arg) +{ + if (s == NULL) + return (0); + s->tls_session_secret_cb = tls_session_secret_cb; + s->tls_session_secret_cb_arg = arg; + return (1); +} + +int +SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb, + void *arg) +{ + if (s == NULL) + return (0); + s->tls_session_ticket_ext_cb = cb; + s->tls_session_ticket_ext_cb_arg = arg; + return (1); +} + +int +SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len) +{ + if (s->version >= TLS1_VERSION) { + free(s->tlsext_session_ticket); + s->tlsext_session_ticket = + malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len); + if (!s->tlsext_session_ticket) { + SSLerr(SSL_F_SSL_SET_SESSION_TICKET_EXT, + ERR_R_MALLOC_FAILURE); + return 0; + } + + if (ext_data) { + s->tlsext_session_ticket->length = ext_len; + s->tlsext_session_ticket->data = + s->tlsext_session_ticket + 1; + memcpy(s->tlsext_session_ticket->data, + ext_data, ext_len); + } else { + s->tlsext_session_ticket->length = 0; + s->tlsext_session_ticket->data = NULL; + } + + return 1; + } + + return 0; +} + +typedef struct timeout_param_st { + SSL_CTX *ctx; + long time; + LHASH_OF(SSL_SESSION) *cache; +} TIMEOUT_PARAM; + +static void +timeout_doall_arg(SSL_SESSION *s, TIMEOUT_PARAM *p) +{ + if ((p->time == 0) || (p->time > (s->time + s->timeout))) { + /* timeout */ + /* The reason we don't call SSL_CTX_remove_session() is to + * save on locking overhead */ + (void)lh_SSL_SESSION_delete(p->cache, s); + SSL_SESSION_list_remove(p->ctx, s); + s->not_resumable = 1; + if (p->ctx->remove_session_cb != NULL) + p->ctx->remove_session_cb(p->ctx, s); + SSL_SESSION_free(s); + } +} + +static +IMPLEMENT_LHASH_DOALL_ARG_FN(timeout, SSL_SESSION, TIMEOUT_PARAM) + +/* XXX 2038 */ +void +SSL_CTX_flush_sessions(SSL_CTX *s, long t) +{ + unsigned long i; + TIMEOUT_PARAM tp; + + tp.ctx = s; + tp.cache = s->sessions; + if (tp.cache == NULL) + return; + tp.time = t; + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + i = CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load; + CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = 0; + lh_SSL_SESSION_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout), + TIMEOUT_PARAM, &tp); + CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = i; + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); +} + +int +ssl_clear_bad_session(SSL *s) +{ + if ((s->session != NULL) && !(s->shutdown & SSL_SENT_SHUTDOWN) && + !(SSL_in_init(s) || SSL_in_before(s))) { + SSL_CTX_remove_session(s->ctx, s->session); + return (1); + } else + return (0); +} + +/* locked by SSL_CTX in the calling function */ +static void +SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s) +{ + if ((s->next == NULL) || (s->prev == NULL)) + return; + + if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail)) { + /* last element in list */ + if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) { + /* only one element in list */ + ctx->session_cache_head = NULL; + ctx->session_cache_tail = NULL; + } else { + ctx->session_cache_tail = s->prev; + s->prev->next = + (SSL_SESSION *)&(ctx->session_cache_tail); + } + } else { + if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) { + /* first element in list */ + ctx->session_cache_head = s->next; + s->next->prev = + (SSL_SESSION *)&(ctx->session_cache_head); + } else { + /* middle of list */ + s->next->prev = s->prev; + s->prev->next = s->next; + } + } + s->prev = s->next = NULL; +} + +static void +SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s) +{ + if ((s->next != NULL) && (s->prev != NULL)) + SSL_SESSION_list_remove(ctx, s); + + if (ctx->session_cache_head == NULL) { + ctx->session_cache_head = s; + ctx->session_cache_tail = s; + s->prev = (SSL_SESSION *)&(ctx->session_cache_head); + s->next = (SSL_SESSION *)&(ctx->session_cache_tail); + } else { + s->next = ctx->session_cache_head; + s->next->prev = s; + s->prev = (SSL_SESSION *)&(ctx->session_cache_head); + ctx->session_cache_head = s; + } +} + +void +SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, + int (*cb)(struct ssl_st *ssl, SSL_SESSION *sess)) { + ctx->new_session_cb = cb; +} + +int +(*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl, SSL_SESSION *sess) +{ + return ctx->new_session_cb; +} + +void +SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, + void (*cb)(SSL_CTX *ctx, SSL_SESSION *sess)) +{ + ctx->remove_session_cb = cb; +} + +void +(*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(SSL_CTX * ctx, SSL_SESSION *sess) +{ + return ctx->remove_session_cb; +} + +void +SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, SSL_SESSION *(*cb)(struct ssl_st *ssl, + unsigned char *data, int len, int *copy)) +{ + ctx->get_session_cb = cb; +} + +SSL_SESSION * +(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(SSL *ssl, unsigned char *data, + int len, int *copy) +{ + return ctx->get_session_cb; +} + +void +SSL_CTX_set_info_callback(SSL_CTX *ctx, + void (*cb)(const SSL *ssl, int type, int val)) +{ + ctx->info_callback = cb; +} + +void +(*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl, int type, int val) +{ + return ctx->info_callback; +} + +void +SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, + int (*cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey)) +{ + ctx->client_cert_cb = cb; +} + +int +(*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL * ssl, X509 ** x509, + EVP_PKEY **pkey) +{ + return ctx->client_cert_cb; +} + +#ifndef OPENSSL_NO_ENGINE +int +SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e) +{ + if (!ENGINE_init(e)) { + SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, + ERR_R_ENGINE_LIB); + return 0; + } + if (!ENGINE_get_ssl_client_cert_function(e)) { + SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, + SSL_R_NO_CLIENT_CERT_METHOD); + ENGINE_finish(e); + return 0; + } + ctx->client_cert_engine = e; + return 1; +} +#endif + +void +SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, + int (*cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)) +{ + ctx->app_gen_cookie_cb = cb; +} + +void +SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, + int (*cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len)) +{ + ctx->app_verify_cookie_cb = cb; +} + +IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION) diff --git a/crypto/libressl/ssl/ssl_stat.c b/crypto/libressl/ssl/ssl_stat.c new file mode 100644 index 0000000000..4ccf024e99 --- /dev/null +++ b/crypto/libressl/ssl/ssl_stat.c @@ -0,0 +1,801 @@ +/* $OpenBSD: ssl_stat.c,v 1.11 2014/07/13 00:08:44 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include + +#include "ssl_locl.h" + +const char * +SSL_state_string_long(const SSL *s) +{ + const char *str; + + switch (s->state) { + case SSL_ST_BEFORE: + str = "before SSL initialization"; + break; + case SSL_ST_ACCEPT: + str = "before accept initialization"; + break; + case SSL_ST_CONNECT: + str = "before connect initialization"; + break; + case SSL_ST_OK: + str = "SSL negotiation finished successfully"; + break; + case SSL_ST_RENEGOTIATE: + str = "SSL renegotiate ciphers"; + break; + case SSL_ST_BEFORE|SSL_ST_CONNECT: + str = "before/connect initialization"; + break; + case SSL_ST_OK|SSL_ST_CONNECT: + str = "ok/connect SSL initialization"; + break; + case SSL_ST_BEFORE|SSL_ST_ACCEPT: + str = "before/accept initialization"; + break; + case SSL_ST_OK|SSL_ST_ACCEPT: + str = "ok/accept SSL initialization"; + break; + + /* SSLv3 additions */ + case SSL3_ST_CW_CLNT_HELLO_A: + str = "SSLv3 write client hello A"; + break; + case SSL3_ST_CW_CLNT_HELLO_B: + str = "SSLv3 write client hello B"; + break; + case SSL3_ST_CR_SRVR_HELLO_A: + str = "SSLv3 read server hello A"; + break; + case SSL3_ST_CR_SRVR_HELLO_B: + str = "SSLv3 read server hello B"; + break; + case SSL3_ST_CR_CERT_A: + str = "SSLv3 read server certificate A"; + break; + case SSL3_ST_CR_CERT_B: + str = "SSLv3 read server certificate B"; + break; + case SSL3_ST_CR_KEY_EXCH_A: + str = "SSLv3 read server key exchange A"; + break; + case SSL3_ST_CR_KEY_EXCH_B: + str = "SSLv3 read server key exchange B"; + break; + case SSL3_ST_CR_CERT_REQ_A: + str = "SSLv3 read server certificate request A"; + break; + case SSL3_ST_CR_CERT_REQ_B: + str = "SSLv3 read server certificate request B"; + break; + case SSL3_ST_CR_SESSION_TICKET_A: + str = "SSLv3 read server session ticket A"; + break; + case SSL3_ST_CR_SESSION_TICKET_B: + str = "SSLv3 read server session ticket B"; + break; + case SSL3_ST_CR_SRVR_DONE_A: + str = "SSLv3 read server done A"; + break; + case SSL3_ST_CR_SRVR_DONE_B: + str = "SSLv3 read server done B"; + break; + case SSL3_ST_CW_CERT_A: + str = "SSLv3 write client certificate A"; + break; + case SSL3_ST_CW_CERT_B: + str = "SSLv3 write client certificate B"; + break; + case SSL3_ST_CW_CERT_C: + str = "SSLv3 write client certificate C"; + break; + case SSL3_ST_CW_CERT_D: + str = "SSLv3 write client certificate D"; + break; + case SSL3_ST_CW_KEY_EXCH_A: + str = "SSLv3 write client key exchange A"; + break; + case SSL3_ST_CW_KEY_EXCH_B: + str = "SSLv3 write client key exchange B"; + break; + case SSL3_ST_CW_CERT_VRFY_A: + str = "SSLv3 write certificate verify A"; + break; + case SSL3_ST_CW_CERT_VRFY_B: + str = "SSLv3 write certificate verify B"; + break; + + case SSL3_ST_CW_CHANGE_A: + case SSL3_ST_SW_CHANGE_A: + str = "SSLv3 write change cipher spec A"; + break; + case SSL3_ST_CW_CHANGE_B: + case SSL3_ST_SW_CHANGE_B: + str = "SSLv3 write change cipher spec B"; + break; + case SSL3_ST_CW_FINISHED_A: + case SSL3_ST_SW_FINISHED_A: + str = "SSLv3 write finished A"; + break; + case SSL3_ST_CW_FINISHED_B: + case SSL3_ST_SW_FINISHED_B: + str = "SSLv3 write finished B"; + break; + case SSL3_ST_CR_CHANGE_A: + case SSL3_ST_SR_CHANGE_A: + str = "SSLv3 read change cipher spec A"; + break; + case SSL3_ST_CR_CHANGE_B: + case SSL3_ST_SR_CHANGE_B: + str = "SSLv3 read change cipher spec B"; + break; + case SSL3_ST_CR_FINISHED_A: + case SSL3_ST_SR_FINISHED_A: + str = "SSLv3 read finished A"; + break; + case SSL3_ST_CR_FINISHED_B: + case SSL3_ST_SR_FINISHED_B: + str = "SSLv3 read finished B"; + break; + + case SSL3_ST_CW_FLUSH: + case SSL3_ST_SW_FLUSH: + str = "SSLv3 flush data"; + break; + + case SSL3_ST_SR_CLNT_HELLO_A: + str = "SSLv3 read client hello A"; + break; + case SSL3_ST_SR_CLNT_HELLO_B: + str = "SSLv3 read client hello B"; + break; + case SSL3_ST_SR_CLNT_HELLO_C: + str = "SSLv3 read client hello C"; + break; + case SSL3_ST_SW_HELLO_REQ_A: + str = "SSLv3 write hello request A"; + break; + case SSL3_ST_SW_HELLO_REQ_B: + str = "SSLv3 write hello request B"; + break; + case SSL3_ST_SW_HELLO_REQ_C: + str = "SSLv3 write hello request C"; + break; + case SSL3_ST_SW_SRVR_HELLO_A: + str = "SSLv3 write server hello A"; + break; + case SSL3_ST_SW_SRVR_HELLO_B: + str = "SSLv3 write server hello B"; + break; + case SSL3_ST_SW_CERT_A: + str = "SSLv3 write certificate A"; + break; + case SSL3_ST_SW_CERT_B: + str = "SSLv3 write certificate B"; + break; + case SSL3_ST_SW_KEY_EXCH_A: + str = "SSLv3 write key exchange A"; + break; + case SSL3_ST_SW_KEY_EXCH_B: + str = "SSLv3 write key exchange B"; + break; + case SSL3_ST_SW_CERT_REQ_A: + str = "SSLv3 write certificate request A"; + break; + case SSL3_ST_SW_CERT_REQ_B: + str = "SSLv3 write certificate request B"; + break; + case SSL3_ST_SW_SESSION_TICKET_A: + str = "SSLv3 write session ticket A"; + break; + case SSL3_ST_SW_SESSION_TICKET_B: + str = "SSLv3 write session ticket B"; + break; + case SSL3_ST_SW_SRVR_DONE_A: + str = "SSLv3 write server done A"; + break; + case SSL3_ST_SW_SRVR_DONE_B: + str = "SSLv3 write server done B"; + break; + case SSL3_ST_SR_CERT_A: + str = "SSLv3 read client certificate A"; + break; + case SSL3_ST_SR_CERT_B: + str = "SSLv3 read client certificate B"; + break; + case SSL3_ST_SR_KEY_EXCH_A: + str = "SSLv3 read client key exchange A"; + break; + case SSL3_ST_SR_KEY_EXCH_B: + str = "SSLv3 read client key exchange B"; + break; + case SSL3_ST_SR_CERT_VRFY_A: + str = "SSLv3 read certificate verify A"; + break; + case SSL3_ST_SR_CERT_VRFY_B: + str = "SSLv3 read certificate verify B"; + break; + + /* DTLS */ + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: + str = "DTLS1 read hello verify request A"; + break; + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: + str = "DTLS1 read hello verify request B"; + break; + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: + str = "DTLS1 write hello verify request A"; + break; + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: + str = "DTLS1 write hello verify request B"; + break; + + default: + str = "unknown state"; + break; + } + return (str); +} + +const char * +SSL_rstate_string_long(const SSL *s) +{ + const char *str; + + switch (s->rstate) { + case SSL_ST_READ_HEADER: + str = "read header"; + break; + case SSL_ST_READ_BODY: + str = "read body"; + break; + case SSL_ST_READ_DONE: + str = "read done"; + break; + default: + str = "unknown"; + break; + } + return (str); +} + +const char * +SSL_state_string(const SSL *s) +{ + const char *str; + + switch (s->state) { + case SSL_ST_BEFORE: + str = "PINIT "; + break; + case SSL_ST_ACCEPT: + str = "AINIT "; + break; + case SSL_ST_CONNECT: + str = "CINIT "; + break; + case SSL_ST_OK: + str = "SSLOK "; + break; + + /* SSLv3 additions */ + case SSL3_ST_SW_FLUSH: + case SSL3_ST_CW_FLUSH: + str = "3FLUSH"; + break; + case SSL3_ST_CW_CLNT_HELLO_A: + str = "3WCH_A"; + break; + case SSL3_ST_CW_CLNT_HELLO_B: + str = "3WCH_B"; + break; + case SSL3_ST_CR_SRVR_HELLO_A: + str = "3RSH_A"; + break; + case SSL3_ST_CR_SRVR_HELLO_B: + str = "3RSH_B"; + break; + case SSL3_ST_CR_CERT_A: + str = "3RSC_A"; + break; + case SSL3_ST_CR_CERT_B: + str = "3RSC_B"; + break; + case SSL3_ST_CR_KEY_EXCH_A: + str = "3RSKEA"; + break; + case SSL3_ST_CR_KEY_EXCH_B: + str = "3RSKEB"; + break; + case SSL3_ST_CR_CERT_REQ_A: + str = "3RCR_A"; + break; + case SSL3_ST_CR_CERT_REQ_B: + str = "3RCR_B"; + break; + case SSL3_ST_CR_SRVR_DONE_A: + str = "3RSD_A"; + break; + case SSL3_ST_CR_SRVR_DONE_B: + str = "3RSD_B"; + break; + case SSL3_ST_CW_CERT_A: + str = "3WCC_A"; + break; + case SSL3_ST_CW_CERT_B: + str = "3WCC_B"; + break; + case SSL3_ST_CW_CERT_C: + str = "3WCC_C"; + break; + case SSL3_ST_CW_CERT_D: + str = "3WCC_D"; + break; + case SSL3_ST_CW_KEY_EXCH_A: + str = "3WCKEA"; + break; + case SSL3_ST_CW_KEY_EXCH_B: + str = "3WCKEB"; + break; + case SSL3_ST_CW_CERT_VRFY_A: + str = "3WCV_A"; + break; + case SSL3_ST_CW_CERT_VRFY_B: + str = "3WCV_B"; + break; + + case SSL3_ST_SW_CHANGE_A: + case SSL3_ST_CW_CHANGE_A: + str = "3WCCSA"; + break; + case SSL3_ST_SW_CHANGE_B: + case SSL3_ST_CW_CHANGE_B: + str = "3WCCSB"; + break; + case SSL3_ST_SW_FINISHED_A: + case SSL3_ST_CW_FINISHED_A: + str = "3WFINA"; + break; + case SSL3_ST_SW_FINISHED_B: + case SSL3_ST_CW_FINISHED_B: + str = "3WFINB"; + break; + case SSL3_ST_SR_CHANGE_A: + case SSL3_ST_CR_CHANGE_A: + str = "3RCCSA"; + break; + case SSL3_ST_SR_CHANGE_B: + case SSL3_ST_CR_CHANGE_B: + str = "3RCCSB"; + break; + case SSL3_ST_SR_FINISHED_A: + case SSL3_ST_CR_FINISHED_A: + str = "3RFINA"; + break; + case SSL3_ST_SR_FINISHED_B: + case SSL3_ST_CR_FINISHED_B: + str = "3RFINB"; + break; + + case SSL3_ST_SW_HELLO_REQ_A: + str = "3WHR_A"; + break; + case SSL3_ST_SW_HELLO_REQ_B: + str = "3WHR_B"; + break; + case SSL3_ST_SW_HELLO_REQ_C: + str = "3WHR_C"; + break; + case SSL3_ST_SR_CLNT_HELLO_A: + str = "3RCH_A"; + break; + case SSL3_ST_SR_CLNT_HELLO_B: + str = "3RCH_B"; + break; + case SSL3_ST_SR_CLNT_HELLO_C: + str = "3RCH_C"; + break; + case SSL3_ST_SW_SRVR_HELLO_A: + str = "3WSH_A"; + break; + case SSL3_ST_SW_SRVR_HELLO_B: + str = "3WSH_B"; + break; + case SSL3_ST_SW_CERT_A: + str = "3WSC_A"; + break; + case SSL3_ST_SW_CERT_B: + str = "3WSC_B"; + break; + case SSL3_ST_SW_KEY_EXCH_A: + str = "3WSKEA"; + break; + case SSL3_ST_SW_KEY_EXCH_B: + str = "3WSKEB"; + break; + case SSL3_ST_SW_CERT_REQ_A: + str = "3WCR_A"; + break; + case SSL3_ST_SW_CERT_REQ_B: + str = "3WCR_B"; + break; + case SSL3_ST_SW_SRVR_DONE_A: + str = "3WSD_A"; + break; + case SSL3_ST_SW_SRVR_DONE_B: + str = "3WSD_B"; + break; + case SSL3_ST_SR_CERT_A: + str = "3RCC_A"; + break; + case SSL3_ST_SR_CERT_B: + str = "3RCC_B"; + break; + case SSL3_ST_SR_KEY_EXCH_A: + str = "3RCKEA"; + break; + case SSL3_ST_SR_KEY_EXCH_B: + str = "3RCKEB"; + break; + case SSL3_ST_SR_CERT_VRFY_A: + str = "3RCV_A"; + break; + case SSL3_ST_SR_CERT_VRFY_B: + str = "3RCV_B"; + break; + + /* DTLS */ + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: + str = "DRCHVA"; + break; + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: + str = "DRCHVB"; + break; + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: + str = "DWCHVA"; + break; + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: + str = "DWCHVB"; + break; + + default: + str = "UNKWN "; + break; + } + return (str); +} + +const char * +SSL_alert_type_string_long(int value) +{ + value >>= 8; + if (value == SSL3_AL_WARNING) + return ("warning"); + else if (value == SSL3_AL_FATAL) + return ("fatal"); + else + return ("unknown"); +} + +const char * +SSL_alert_type_string(int value) +{ + value >>= 8; + if (value == SSL3_AL_WARNING) + return ("W"); + else if (value == SSL3_AL_FATAL) + return ("F"); + else + return ("U"); +} + +const char * +SSL_alert_desc_string(int value) +{ + const char *str; + + switch (value & 0xff) { + case SSL3_AD_CLOSE_NOTIFY: + str = "CN"; + break; + case SSL3_AD_UNEXPECTED_MESSAGE: + str = "UM"; + break; + case SSL3_AD_BAD_RECORD_MAC: + str = "BM"; + break; + case SSL3_AD_DECOMPRESSION_FAILURE: + str = "DF"; + break; + case SSL3_AD_HANDSHAKE_FAILURE: + str = "HF"; + break; + case SSL3_AD_NO_CERTIFICATE: + str = "NC"; + break; + case SSL3_AD_BAD_CERTIFICATE: + str = "BC"; + break; + case SSL3_AD_UNSUPPORTED_CERTIFICATE: + str = "UC"; + break; + case SSL3_AD_CERTIFICATE_REVOKED: + str = "CR"; + break; + case SSL3_AD_CERTIFICATE_EXPIRED: + str = "CE"; + break; + case SSL3_AD_CERTIFICATE_UNKNOWN: + str = "CU"; + break; + case SSL3_AD_ILLEGAL_PARAMETER: + str = "IP"; + break; + case TLS1_AD_DECRYPTION_FAILED: + str = "DC"; + break; + case TLS1_AD_RECORD_OVERFLOW: + str = "RO"; + break; + case TLS1_AD_UNKNOWN_CA: + str = "CA"; + break; + case TLS1_AD_ACCESS_DENIED: + str = "AD"; + break; + case TLS1_AD_DECODE_ERROR: + str = "DE"; + break; + case TLS1_AD_DECRYPT_ERROR: + str = "CY"; + break; + case TLS1_AD_EXPORT_RESTRICTION: + str = "ER"; + break; + case TLS1_AD_PROTOCOL_VERSION: + str = "PV"; + break; + case TLS1_AD_INSUFFICIENT_SECURITY: + str = "IS"; + break; + case TLS1_AD_INTERNAL_ERROR: + str = "IE"; + break; + case TLS1_AD_USER_CANCELLED: + str = "US"; + break; + case TLS1_AD_NO_RENEGOTIATION: + str = "NR"; + break; + case TLS1_AD_UNSUPPORTED_EXTENSION: + str = "UE"; + break; + case TLS1_AD_CERTIFICATE_UNOBTAINABLE: + str = "CO"; + break; + case TLS1_AD_UNRECOGNIZED_NAME: + str = "UN"; + break; + case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + str = "BR"; + break; + case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: + str = "BH"; + break; + case TLS1_AD_UNKNOWN_PSK_IDENTITY: + str = "UP"; + break; + default: + str = "UK"; + break; + } + return (str); +} + +const char * +SSL_alert_desc_string_long(int value) +{ + const char *str; + + switch (value & 0xff) { + case SSL3_AD_CLOSE_NOTIFY: + str = "close notify"; + break; + case SSL3_AD_UNEXPECTED_MESSAGE: + str = "unexpected_message"; + break; + case SSL3_AD_BAD_RECORD_MAC: + str = "bad record mac"; + break; + case SSL3_AD_DECOMPRESSION_FAILURE: + str = "decompression failure"; + break; + case SSL3_AD_HANDSHAKE_FAILURE: + str = "handshake failure"; + break; + case SSL3_AD_NO_CERTIFICATE: + str = "no certificate"; + break; + case SSL3_AD_BAD_CERTIFICATE: + str = "bad certificate"; + break; + case SSL3_AD_UNSUPPORTED_CERTIFICATE: + str = "unsupported certificate"; + break; + case SSL3_AD_CERTIFICATE_REVOKED: + str = "certificate revoked"; + break; + case SSL3_AD_CERTIFICATE_EXPIRED: + str = "certificate expired"; + break; + case SSL3_AD_CERTIFICATE_UNKNOWN: + str = "certificate unknown"; + break; + case SSL3_AD_ILLEGAL_PARAMETER: + str = "illegal parameter"; + break; + case TLS1_AD_DECRYPTION_FAILED: + str = "decryption failed"; + break; + case TLS1_AD_RECORD_OVERFLOW: + str = "record overflow"; + break; + case TLS1_AD_UNKNOWN_CA: + str = "unknown CA"; + break; + case TLS1_AD_ACCESS_DENIED: + str = "access denied"; + break; + case TLS1_AD_DECODE_ERROR: + str = "decode error"; + break; + case TLS1_AD_DECRYPT_ERROR: + str = "decrypt error"; + break; + case TLS1_AD_EXPORT_RESTRICTION: + str = "export restriction"; + break; + case TLS1_AD_PROTOCOL_VERSION: + str = "protocol version"; + break; + case TLS1_AD_INSUFFICIENT_SECURITY: + str = "insufficient security"; + break; + case TLS1_AD_INTERNAL_ERROR: + str = "internal error"; + break; + case TLS1_AD_USER_CANCELLED: + str = "user canceled"; + break; + case TLS1_AD_NO_RENEGOTIATION: + str = "no renegotiation"; + break; + case TLS1_AD_UNSUPPORTED_EXTENSION: + str = "unsupported extension"; + break; + case TLS1_AD_CERTIFICATE_UNOBTAINABLE: + str = "certificate unobtainable"; + break; + case TLS1_AD_UNRECOGNIZED_NAME: + str = "unrecognized name"; + break; + case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + str = "bad certificate status response"; + break; + case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: + str = "bad certificate hash value"; + break; + case TLS1_AD_UNKNOWN_PSK_IDENTITY: + str = "unknown PSK identity"; + break; + default: + str = "unknown"; + break; + } + return (str); +} + +const char * +SSL_rstate_string(const SSL *s) +{ + const char *str; + + switch (s->rstate) { + case SSL_ST_READ_HEADER: + str = "RH"; + break; + case SSL_ST_READ_BODY: + str = "RB"; + break; + case SSL_ST_READ_DONE: + str = "RD"; + break; + default: + str = "unknown"; + break; + } + return (str); +} diff --git a/crypto/libressl/ssl/ssl_txt.c b/crypto/libressl/ssl/ssl_txt.c new file mode 100644 index 0000000000..3bd46654cc --- /dev/null +++ b/crypto/libressl/ssl/ssl_txt.c @@ -0,0 +1,188 @@ +/* $OpenBSD: ssl_txt.c,v 1.25 2014/11/16 14:12:47 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +#include + +#include + +#include "ssl_locl.h" + +int +SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file_internal())) == NULL) { + SSLerr(SSL_F_SSL_SESSION_PRINT_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = SSL_SESSION_print(b, x); + BIO_free(b); + return (ret); +} + +int +SSL_SESSION_print(BIO *bp, const SSL_SESSION *x) +{ + unsigned int i; + const char *s; + + if (x == NULL) + goto err; + if (BIO_puts(bp, "SSL-Session:\n") <= 0) + goto err; + + s = ssl_version_string(x->ssl_version); + if (BIO_printf(bp, " Protocol : %s\n", s) <= 0) + goto err; + + if (x->cipher == NULL) { + if (((x->cipher_id) & 0xff000000) == 0x02000000) { + if (BIO_printf(bp, " Cipher : %06lX\n", x->cipher_id&0xffffff) <= 0) + goto err; + } else { + if (BIO_printf(bp, " Cipher : %04lX\n", x->cipher_id&0xffff) <= 0) + goto err; + } + } else { + if (BIO_printf(bp, " Cipher : %s\n",((x->cipher == NULL)?"unknown":x->cipher->name)) <= 0) + goto err; + } + if (BIO_puts(bp, " Session-ID: ") <= 0) + goto err; + for (i = 0; i < x->session_id_length; i++) { + if (BIO_printf(bp, "%02X", x->session_id[i]) <= 0) + goto err; + } + if (BIO_puts(bp, "\n Session-ID-ctx: ") <= 0) + goto err; + for (i = 0; i < x->sid_ctx_length; i++) { + if (BIO_printf(bp, "%02X", x->sid_ctx[i]) <= 0) + goto err; + } + if (BIO_puts(bp, "\n Master-Key: ") <= 0) + goto err; + for (i = 0; i < (unsigned int)x->master_key_length; i++) { + if (BIO_printf(bp, "%02X", x->master_key[i]) <= 0) + goto err; + } + if (x->tlsext_tick_lifetime_hint) { + if (BIO_printf(bp, + "\n TLS session ticket lifetime hint: %ld (seconds)", + x->tlsext_tick_lifetime_hint) <= 0) + goto err; + } + if (x->tlsext_tick) { + if (BIO_puts(bp, "\n TLS session ticket:\n") <= 0) + goto err; + if (BIO_dump_indent(bp, (char *)x->tlsext_tick, x->tlsext_ticklen, 4) <= 0) + goto err; + } + + if (x->time != 0) { + if (BIO_printf(bp, "\n Start Time: %"PRId64, (int64_t)x->time) <= 0) + goto err; + } + if (x->timeout != 0L) { + if (BIO_printf(bp, "\n Timeout : %ld (sec)", x->timeout) <= 0) + goto err; + } + if (BIO_puts(bp, "\n") <= 0) + goto err; + + if (BIO_puts(bp, " Verify return code: ") <= 0) + goto err; + + if (BIO_printf(bp, "%ld (%s)\n", x->verify_result, + X509_verify_cert_error_string(x->verify_result)) <= 0) + goto err; + + return (1); +err: + return (0); +} + diff --git a/crypto/libressl/ssl/t1_clnt.c b/crypto/libressl/ssl/t1_clnt.c new file mode 100644 index 0000000000..2fc777dbcb --- /dev/null +++ b/crypto/libressl/ssl/t1_clnt.c @@ -0,0 +1,237 @@ +/* $OpenBSD: t1_clnt.c,v 1.17 2015/02/06 08:30:23 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include "ssl_locl.h" + +#include +#include +#include + +static const SSL_METHOD *tls1_get_client_method(int ver); + +const SSL_METHOD TLS_client_method_data = { + .version = TLS1_2_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = ssl_undefined_function, + .ssl_connect = ssl23_connect, + .ssl_read = ssl23_read, + .ssl_peek = ssl23_peek, + .ssl_write = ssl23_write, + .ssl_shutdown = ssl_undefined_function, + .ssl_renegotiate = ssl_undefined_function, + .ssl_renegotiate_check = ssl_ok, + .ssl_get_message = ssl3_get_message, + .ssl_read_bytes = ssl3_read_bytes, + .ssl_write_bytes = ssl3_write_bytes, + .ssl_dispatch_alert = ssl3_dispatch_alert, + .ssl_ctrl = ssl3_ctrl, + .ssl_ctx_ctrl = ssl3_ctx_ctrl, + .get_cipher_by_char = ssl3_get_cipher_by_char, + .put_cipher_by_char = ssl3_put_cipher_by_char, + .ssl_pending = ssl_undefined_const_function, + .num_ciphers = ssl3_num_ciphers, + .get_cipher = ssl3_get_cipher, + .get_ssl_method = tls1_get_client_method, + .get_timeout = ssl23_default_timeout, + .ssl3_enc = &ssl3_undef_enc_method, + .ssl_version = ssl_undefined_void_function, + .ssl_callback_ctrl = ssl3_callback_ctrl, + .ssl_ctx_callback_ctrl = ssl3_ctx_callback_ctrl, +}; + +const SSL_METHOD TLSv1_client_method_data = { + .version = TLS1_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = ssl_undefined_function, + .ssl_connect = ssl3_connect, + .ssl_read = ssl3_read, + .ssl_peek = ssl3_peek, + .ssl_write = ssl3_write, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_get_message = ssl3_get_message, + .ssl_read_bytes = ssl3_read_bytes, + .ssl_write_bytes = ssl3_write_bytes, + .ssl_dispatch_alert = ssl3_dispatch_alert, + .ssl_ctrl = ssl3_ctrl, + .ssl_ctx_ctrl = ssl3_ctx_ctrl, + .get_cipher_by_char = ssl3_get_cipher_by_char, + .put_cipher_by_char = ssl3_put_cipher_by_char, + .ssl_pending = ssl3_pending, + .num_ciphers = ssl3_num_ciphers, + .get_cipher = ssl3_get_cipher, + .get_ssl_method = tls1_get_client_method, + .get_timeout = tls1_default_timeout, + .ssl3_enc = &TLSv1_enc_data, + .ssl_version = ssl_undefined_void_function, + .ssl_callback_ctrl = ssl3_callback_ctrl, + .ssl_ctx_callback_ctrl = ssl3_ctx_callback_ctrl, +}; + +const SSL_METHOD TLSv1_1_client_method_data = { + .version = TLS1_1_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = ssl_undefined_function, + .ssl_connect = ssl3_connect, + .ssl_read = ssl3_read, + .ssl_peek = ssl3_peek, + .ssl_write = ssl3_write, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_get_message = ssl3_get_message, + .ssl_read_bytes = ssl3_read_bytes, + .ssl_write_bytes = ssl3_write_bytes, + .ssl_dispatch_alert = ssl3_dispatch_alert, + .ssl_ctrl = ssl3_ctrl, + .ssl_ctx_ctrl = ssl3_ctx_ctrl, + .get_cipher_by_char = ssl3_get_cipher_by_char, + .put_cipher_by_char = ssl3_put_cipher_by_char, + .ssl_pending = ssl3_pending, + .num_ciphers = ssl3_num_ciphers, + .get_cipher = ssl3_get_cipher, + .get_ssl_method = tls1_get_client_method, + .get_timeout = tls1_default_timeout, + .ssl3_enc = &TLSv1_1_enc_data, + .ssl_version = ssl_undefined_void_function, + .ssl_callback_ctrl = ssl3_callback_ctrl, + .ssl_ctx_callback_ctrl = ssl3_ctx_callback_ctrl, +}; + +const SSL_METHOD TLSv1_2_client_method_data = { + .version = TLS1_2_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = ssl_undefined_function, + .ssl_connect = ssl3_connect, + .ssl_read = ssl3_read, + .ssl_peek = ssl3_peek, + .ssl_write = ssl3_write, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_get_message = ssl3_get_message, + .ssl_read_bytes = ssl3_read_bytes, + .ssl_write_bytes = ssl3_write_bytes, + .ssl_dispatch_alert = ssl3_dispatch_alert, + .ssl_ctrl = ssl3_ctrl, + .ssl_ctx_ctrl = ssl3_ctx_ctrl, + .get_cipher_by_char = ssl3_get_cipher_by_char, + .put_cipher_by_char = ssl3_put_cipher_by_char, + .ssl_pending = ssl3_pending, + .num_ciphers = ssl3_num_ciphers, + .get_cipher = ssl3_get_cipher, + .get_ssl_method = tls1_get_client_method, + .get_timeout = tls1_default_timeout, + .ssl3_enc = &TLSv1_2_enc_data, + .ssl_version = ssl_undefined_void_function, + .ssl_callback_ctrl = ssl3_callback_ctrl, + .ssl_ctx_callback_ctrl = ssl3_ctx_callback_ctrl, +}; + +static const SSL_METHOD * +tls1_get_client_method(int ver) +{ + if (ver == TLS1_2_VERSION) + return (TLSv1_2_client_method()); + if (ver == TLS1_1_VERSION) + return (TLSv1_1_client_method()); + if (ver == TLS1_VERSION) + return (TLSv1_client_method()); + return (NULL); +} + +const SSL_METHOD * +SSLv23_client_method(void) +{ + return (TLS_client_method()); +} + +const SSL_METHOD * +TLS_client_method(void) +{ + return (&TLS_client_method_data); +} + +const SSL_METHOD * +TLSv1_client_method(void) +{ + return (&TLSv1_client_method_data); +} + +const SSL_METHOD * +TLSv1_1_client_method(void) +{ + return (&TLSv1_1_client_method_data); +} + +const SSL_METHOD * +TLSv1_2_client_method(void) +{ + return (&TLSv1_2_client_method_data); +} diff --git a/crypto/libressl/ssl/t1_enc.c b/crypto/libressl/ssl/t1_enc.c new file mode 100644 index 0000000000..cc4802d96a --- /dev/null +++ b/crypto/libressl/ssl/t1_enc.c @@ -0,0 +1,1419 @@ +/* $OpenBSD: t1_enc.c,v 1.84 2016/03/06 14:52:15 beck Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include + +#include "ssl_locl.h" + +#include +#include +#include + +void +tls1_cleanup_key_block(SSL *s) +{ + if (s->s3->tmp.key_block != NULL) { + explicit_bzero(s->s3->tmp.key_block, + s->s3->tmp.key_block_length); + free(s->s3->tmp.key_block); + s->s3->tmp.key_block = NULL; + } + s->s3->tmp.key_block_length = 0; +} + +int +tls1_init_finished_mac(SSL *s) +{ + BIO_free(s->s3->handshake_buffer); + tls1_free_digest_list(s); + + s->s3->handshake_buffer = BIO_new(BIO_s_mem()); + if (s->s3->handshake_buffer == NULL) + return (0); + + (void)BIO_set_close(s->s3->handshake_buffer, BIO_CLOSE); + + return (1); +} + +void +tls1_free_digest_list(SSL *s) +{ + int i; + + if (s == NULL) + return; + + if (s->s3->handshake_dgst == NULL) + return; + for (i = 0; i < SSL_MAX_DIGEST; i++) { + if (s->s3->handshake_dgst[i]) + EVP_MD_CTX_destroy(s->s3->handshake_dgst[i]); + } + free(s->s3->handshake_dgst); + s->s3->handshake_dgst = NULL; +} + +void +tls1_finish_mac(SSL *s, const unsigned char *buf, int len) +{ + if (s->s3->handshake_buffer && + !(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) { + BIO_write(s->s3->handshake_buffer, (void *)buf, len); + } else { + int i; + for (i = 0; i < SSL_MAX_DIGEST; i++) { + if (s->s3->handshake_dgst[i]!= NULL) + EVP_DigestUpdate(s->s3->handshake_dgst[i], buf, len); + } + } +} + +int +tls1_digest_cached_records(SSL *s) +{ + int i; + long mask; + const EVP_MD *md; + long hdatalen; + void *hdata; + + tls1_free_digest_list(s); + + s->s3->handshake_dgst = calloc(SSL_MAX_DIGEST, sizeof(EVP_MD_CTX *)); + if (s->s3->handshake_dgst == NULL) { + SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE); + return 0; + } + hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); + if (hdatalen <= 0) { + SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, + SSL_R_BAD_HANDSHAKE_LENGTH); + return 0; + } + + /* Loop through bits of the algorithm2 field and create MD contexts. */ + for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) { + if ((mask & ssl_get_algorithm2(s)) && md) { + s->s3->handshake_dgst[i] = EVP_MD_CTX_create(); + if (s->s3->handshake_dgst[i] == NULL) { + SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, + ERR_R_MALLOC_FAILURE); + return 0; + } + if (!EVP_DigestInit_ex(s->s3->handshake_dgst[i], + md, NULL)) { + EVP_MD_CTX_destroy(s->s3->handshake_dgst[i]); + return 0; + } + if (!EVP_DigestUpdate(s->s3->handshake_dgst[i], hdata, + hdatalen)) + return 0; + } + } + + if (!(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) { + BIO_free(s->s3->handshake_buffer); + s->s3->handshake_buffer = NULL; + } + + return 1; +} + +void +tls1_record_sequence_increment(unsigned char *seq) +{ + int i; + + for (i = SSL3_SEQUENCE_SIZE - 1; i >= 0; i--) { + if (++seq[i] != 0) + break; + } +} + +/* seed1 through seed5 are virtually concatenated */ +static int +tls1_P_hash(const EVP_MD *md, const unsigned char *sec, int sec_len, + const void *seed1, int seed1_len, const void *seed2, int seed2_len, + const void *seed3, int seed3_len, const void *seed4, int seed4_len, + const void *seed5, int seed5_len, unsigned char *out, int olen) +{ + int chunk; + size_t j; + EVP_MD_CTX ctx, ctx_tmp; + EVP_PKEY *mac_key; + unsigned char A1[EVP_MAX_MD_SIZE]; + size_t A1_len; + int ret = 0; + + chunk = EVP_MD_size(md); + OPENSSL_assert(chunk >= 0); + + EVP_MD_CTX_init(&ctx); + EVP_MD_CTX_init(&ctx_tmp); + mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len); + if (!mac_key) + goto err; + if (!EVP_DigestSignInit(&ctx, NULL, md, NULL, mac_key)) + goto err; + if (!EVP_DigestSignInit(&ctx_tmp, NULL, md, NULL, mac_key)) + goto err; + if (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len)) + goto err; + if (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len)) + goto err; + if (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len)) + goto err; + if (seed4 && !EVP_DigestSignUpdate(&ctx, seed4, seed4_len)) + goto err; + if (seed5 && !EVP_DigestSignUpdate(&ctx, seed5, seed5_len)) + goto err; + if (!EVP_DigestSignFinal(&ctx, A1, &A1_len)) + goto err; + + for (;;) { + /* Reinit mac contexts */ + if (!EVP_DigestSignInit(&ctx, NULL, md, NULL, mac_key)) + goto err; + if (!EVP_DigestSignInit(&ctx_tmp, NULL, md, NULL, mac_key)) + goto err; + if (!EVP_DigestSignUpdate(&ctx, A1, A1_len)) + goto err; + if (!EVP_DigestSignUpdate(&ctx_tmp, A1, A1_len)) + goto err; + if (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len)) + goto err; + if (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len)) + goto err; + if (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len)) + goto err; + if (seed4 && !EVP_DigestSignUpdate(&ctx, seed4, seed4_len)) + goto err; + if (seed5 && !EVP_DigestSignUpdate(&ctx, seed5, seed5_len)) + goto err; + + if (olen > chunk) { + if (!EVP_DigestSignFinal(&ctx, out, &j)) + goto err; + out += j; + olen -= j; + /* calc the next A1 value */ + if (!EVP_DigestSignFinal(&ctx_tmp, A1, &A1_len)) + goto err; + } else { + /* last one */ + if (!EVP_DigestSignFinal(&ctx, A1, &A1_len)) + goto err; + memcpy(out, A1, olen); + break; + } + } + ret = 1; + +err: + EVP_PKEY_free(mac_key); + EVP_MD_CTX_cleanup(&ctx); + EVP_MD_CTX_cleanup(&ctx_tmp); + explicit_bzero(A1, sizeof(A1)); + return ret; +} + +/* seed1 through seed5 are virtually concatenated */ +static int +tls1_PRF(long digest_mask, const void *seed1, int seed1_len, const void *seed2, + int seed2_len, const void *seed3, int seed3_len, const void *seed4, + int seed4_len, const void *seed5, int seed5_len, const unsigned char *sec, + int slen, unsigned char *out1, unsigned char *out2, int olen) +{ + int len, i, idx, count; + const unsigned char *S1; + long m; + const EVP_MD *md; + int ret = 0; + + /* Count number of digests and partition sec evenly */ + count = 0; + for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) { + if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask) + count++; + } + if (count == 0) { + SSLerr(SSL_F_TLS1_PRF, + SSL_R_SSL_HANDSHAKE_FAILURE); + goto err; + } + len = slen / count; + if (count == 1) + slen = 0; + S1 = sec; + memset(out1, 0, olen); + for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) { + if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask) { + if (!md) { + SSLerr(SSL_F_TLS1_PRF, + SSL_R_UNSUPPORTED_DIGEST_TYPE); + goto err; + } + if (!tls1_P_hash(md , S1, len + (slen&1), seed1, + seed1_len, seed2, seed2_len, seed3, seed3_len, + seed4, seed4_len, seed5, seed5_len, out2, olen)) + goto err; + S1 += len; + for (i = 0; i < olen; i++) { + out1[i] ^= out2[i]; + } + } + } + ret = 1; + +err: + return ret; +} + +static int +tls1_generate_key_block(SSL *s, unsigned char *km, unsigned char *tmp, int num) +{ + int ret; + + ret = tls1_PRF(ssl_get_algorithm2(s), + TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE, + s->s3->server_random, SSL3_RANDOM_SIZE, + s->s3->client_random, SSL3_RANDOM_SIZE, + NULL, 0, NULL, 0, + s->session->master_key, s->session->master_key_length, + km, tmp, num); + return ret; +} + +/* + * tls1_aead_ctx_init allocates aead_ctx, if needed. It returns 1 on success + * and 0 on failure. + */ +static int +tls1_aead_ctx_init(SSL_AEAD_CTX **aead_ctx) +{ + if (*aead_ctx != NULL) { + EVP_AEAD_CTX_cleanup(&(*aead_ctx)->ctx); + return (1); + } + + *aead_ctx = malloc(sizeof(SSL_AEAD_CTX)); + if (*aead_ctx == NULL) { + SSLerr(SSL_F_TLS1_AEAD_CTX_INIT, ERR_R_MALLOC_FAILURE); + return (0); + } + + return (1); +} + +static int +tls1_change_cipher_state_aead(SSL *s, char is_read, const unsigned char *key, + unsigned key_len, const unsigned char *iv, unsigned iv_len) +{ + const EVP_AEAD *aead = s->s3->tmp.new_aead; + SSL_AEAD_CTX *aead_ctx; + + if (is_read) { + if (!tls1_aead_ctx_init(&s->aead_read_ctx)) + return 0; + aead_ctx = s->aead_read_ctx; + } else { + if (!tls1_aead_ctx_init(&s->aead_write_ctx)) + return 0; + aead_ctx = s->aead_write_ctx; + } + + if (!EVP_AEAD_CTX_init(&aead_ctx->ctx, aead, key, key_len, + EVP_AEAD_DEFAULT_TAG_LENGTH, NULL)) + return (0); + if (iv_len > sizeof(aead_ctx->fixed_nonce)) { + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE_AEAD, + ERR_R_INTERNAL_ERROR); + return (0); + } + memcpy(aead_ctx->fixed_nonce, iv, iv_len); + aead_ctx->fixed_nonce_len = iv_len; + aead_ctx->variable_nonce_len = 8; /* always the case, currently. */ + aead_ctx->variable_nonce_in_record = + (s->s3->tmp.new_cipher->algorithm2 & + SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD) != 0; + aead_ctx->xor_fixed_nonce = + s->s3->tmp.new_cipher->algorithm_enc == SSL_CHACHA20POLY1305; + aead_ctx->tag_len = EVP_AEAD_max_overhead(aead); + + if (aead_ctx->xor_fixed_nonce) { + if (aead_ctx->fixed_nonce_len != EVP_AEAD_nonce_length(aead) || + aead_ctx->variable_nonce_len > EVP_AEAD_nonce_length(aead)) { + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE_AEAD, + ERR_R_INTERNAL_ERROR); + return (0); + } + } else { + if (aead_ctx->variable_nonce_len + aead_ctx->fixed_nonce_len != + EVP_AEAD_nonce_length(aead)) { + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE_AEAD, + ERR_R_INTERNAL_ERROR); + return (0); + } + } + + return (1); +} + +/* + * tls1_change_cipher_state_cipher performs the work needed to switch cipher + * states when using EVP_CIPHER. The argument is_read is true iff this function + * is being called due to reading, as opposed to writing, a ChangeCipherSpec + * message. In order to support export ciphersuites, use_client_keys indicates + * whether the key material provided is in the "client write" direction. + */ +static int +tls1_change_cipher_state_cipher(SSL *s, char is_read, char use_client_keys, + const unsigned char *mac_secret, unsigned int mac_secret_size, + const unsigned char *key, unsigned int key_len, const unsigned char *iv, + unsigned int iv_len) +{ + EVP_CIPHER_CTX *cipher_ctx; + const EVP_CIPHER *cipher; + EVP_MD_CTX *mac_ctx; + const EVP_MD *mac; + int mac_type; + + cipher = s->s3->tmp.new_sym_enc; + mac = s->s3->tmp.new_hash; + mac_type = s->s3->tmp.new_mac_pkey_type; + + if (is_read) { + if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) + s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM; + else + s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; + + EVP_CIPHER_CTX_free(s->enc_read_ctx); + s->enc_read_ctx = NULL; + EVP_MD_CTX_destroy(s->read_hash); + s->read_hash = NULL; + + if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL) + goto err; + s->enc_read_ctx = cipher_ctx; + if ((mac_ctx = EVP_MD_CTX_create()) == NULL) + goto err; + s->read_hash = mac_ctx; + } else { + if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) + s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; + else + s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; + + /* + * DTLS fragments retain a pointer to the compression, cipher + * and hash contexts, so that it can restore state in order + * to perform retransmissions. As such, we cannot free write + * contexts that are used for DTLS - these are instead freed + * by DTLS when its frees a ChangeCipherSpec fragment. + */ + if (!SSL_IS_DTLS(s)) { + EVP_CIPHER_CTX_free(s->enc_write_ctx); + s->enc_write_ctx = NULL; + EVP_MD_CTX_destroy(s->write_hash); + s->write_hash = NULL; + } + if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL) + goto err; + s->enc_write_ctx = cipher_ctx; + if ((mac_ctx = EVP_MD_CTX_create()) == NULL) + goto err; + s->write_hash = mac_ctx; + } + + if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE) { + EVP_CipherInit_ex(cipher_ctx, cipher, NULL, key, NULL, + !is_read); + EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GCM_SET_IV_FIXED, + iv_len, (unsigned char *)iv); + } else + EVP_CipherInit_ex(cipher_ctx, cipher, NULL, key, iv, !is_read); + + if (!(EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)) { + EVP_PKEY *mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, + mac_secret, mac_secret_size); + if (mac_key == NULL) + goto err; + EVP_DigestSignInit(mac_ctx, NULL, mac, NULL, mac_key); + EVP_PKEY_free(mac_key); + } else if (mac_secret_size > 0) { + /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */ + EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_AEAD_SET_MAC_KEY, + mac_secret_size, (unsigned char *)mac_secret); + } + + if (s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT) { + int nid; + if (s->s3->tmp.new_cipher->algorithm2 & SSL_HANDSHAKE_MAC_GOST94) + nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet; + else + nid = NID_id_tc26_gost_28147_param_Z; + + EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GOST_SET_SBOX, nid, 0); + if (s->s3->tmp.new_cipher->algorithm_mac == SSL_GOST89MAC) + EVP_MD_CTX_ctrl(mac_ctx, EVP_MD_CTRL_GOST_SET_SBOX, nid, 0); + } + + return (1); + +err: + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE_CIPHER, ERR_R_MALLOC_FAILURE); + return (0); +} + +int +tls1_change_cipher_state(SSL *s, int which) +{ + const unsigned char *client_write_mac_secret, *server_write_mac_secret; + const unsigned char *client_write_key, *server_write_key; + const unsigned char *client_write_iv, *server_write_iv; + const unsigned char *mac_secret, *key, *iv; + int mac_secret_size, key_len, iv_len; + unsigned char *key_block, *seq; + const EVP_CIPHER *cipher; + const EVP_AEAD *aead; + char is_read, use_client_keys; + + + cipher = s->s3->tmp.new_sym_enc; + aead = s->s3->tmp.new_aead; + + /* + * is_read is true if we have just read a ChangeCipherSpec message, + * that is we need to update the read cipherspec. Otherwise we have + * just written one. + */ + is_read = (which & SSL3_CC_READ) != 0; + + /* + * use_client_keys is true if we wish to use the keys for the "client + * write" direction. This is the case if we're a client sending a + * ChangeCipherSpec, or a server reading a client's ChangeCipherSpec. + */ + use_client_keys = ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || + (which == SSL3_CHANGE_CIPHER_SERVER_READ)); + + + /* + * Reset sequence number to zero - for DTLS this is handled in + * dtls1_reset_seq_numbers(). + */ + if (!SSL_IS_DTLS(s)) { + seq = is_read ? s->s3->read_sequence : s->s3->write_sequence; + memset(seq, 0, SSL3_SEQUENCE_SIZE); + } + + if (aead != NULL) { + key_len = EVP_AEAD_key_length(aead); + iv_len = SSL_CIPHER_AEAD_FIXED_NONCE_LEN(s->s3->tmp.new_cipher); + } else { + key_len = EVP_CIPHER_key_length(cipher); + iv_len = EVP_CIPHER_iv_length(cipher); + + /* If GCM mode only part of IV comes from PRF. */ + if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE) + iv_len = EVP_GCM_TLS_FIXED_IV_LEN; + } + + mac_secret_size = s->s3->tmp.new_mac_secret_size; + + key_block = s->s3->tmp.key_block; + client_write_mac_secret = key_block; + key_block += mac_secret_size; + server_write_mac_secret = key_block; + key_block += mac_secret_size; + client_write_key = key_block; + key_block += key_len; + server_write_key = key_block; + key_block += key_len; + client_write_iv = key_block; + key_block += iv_len; + server_write_iv = key_block; + key_block += iv_len; + + if (use_client_keys) { + mac_secret = client_write_mac_secret; + key = client_write_key; + iv = client_write_iv; + } else { + mac_secret = server_write_mac_secret; + key = server_write_key; + iv = server_write_iv; + } + + if (key_block - s->s3->tmp.key_block != s->s3->tmp.key_block_length) { + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); + goto err2; + } + + if (is_read) { + memcpy(s->s3->read_mac_secret, mac_secret, mac_secret_size); + s->s3->read_mac_secret_size = mac_secret_size; + } else { + memcpy(s->s3->write_mac_secret, mac_secret, mac_secret_size); + s->s3->write_mac_secret_size = mac_secret_size; + } + + if (aead != NULL) { + return tls1_change_cipher_state_aead(s, is_read, key, key_len, + iv, iv_len); + } + + return tls1_change_cipher_state_cipher(s, is_read, use_client_keys, + mac_secret, mac_secret_size, key, key_len, iv, iv_len); + +err2: + return (0); +} + +int +tls1_setup_key_block(SSL *s) +{ + unsigned char *key_block, *tmp_block = NULL; + int mac_type = NID_undef, mac_secret_size = 0; + int key_block_len, key_len, iv_len; + const EVP_CIPHER *cipher = NULL; + const EVP_AEAD *aead = NULL; + const EVP_MD *mac = NULL; + int ret = 0; + + if (s->s3->tmp.key_block_length != 0) + return (1); + + if (s->session->cipher && + (s->session->cipher->algorithm2 & SSL_CIPHER_ALGORITHM2_AEAD)) { + if (!ssl_cipher_get_evp_aead(s->session, &aead)) { + SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, + SSL_R_CIPHER_OR_HASH_UNAVAILABLE); + return (0); + } + key_len = EVP_AEAD_key_length(aead); + iv_len = SSL_CIPHER_AEAD_FIXED_NONCE_LEN(s->session->cipher); + } else { + if (!ssl_cipher_get_evp(s->session, &cipher, &mac, &mac_type, + &mac_secret_size)) { + SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, + SSL_R_CIPHER_OR_HASH_UNAVAILABLE); + return (0); + } + key_len = EVP_CIPHER_key_length(cipher); + iv_len = EVP_CIPHER_iv_length(cipher); + + /* If GCM mode only part of IV comes from PRF. */ + if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE) + iv_len = EVP_GCM_TLS_FIXED_IV_LEN; + } + + s->s3->tmp.new_aead = aead; + s->s3->tmp.new_sym_enc = cipher; + s->s3->tmp.new_hash = mac; + s->s3->tmp.new_mac_pkey_type = mac_type; + s->s3->tmp.new_mac_secret_size = mac_secret_size; + + tls1_cleanup_key_block(s); + + if ((key_block = reallocarray(NULL, mac_secret_size + key_len + iv_len, + 2)) == NULL) { + SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE); + goto err; + } + key_block_len = (mac_secret_size + key_len + iv_len) * 2; + + s->s3->tmp.key_block_length = key_block_len; + s->s3->tmp.key_block = key_block; + + if ((tmp_block = malloc(key_block_len)) == NULL) { + SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!tls1_generate_key_block(s, key_block, tmp_block, key_block_len)) + goto err; + + if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) && + s->method->version <= TLS1_VERSION) { + /* + * Enable vulnerability countermeasure for CBC ciphers with + * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt) + */ + s->s3->need_empty_fragments = 1; + + if (s->session->cipher != NULL) { + if (s->session->cipher->algorithm_enc == SSL_eNULL) + s->s3->need_empty_fragments = 0; + +#ifndef OPENSSL_NO_RC4 + if (s->session->cipher->algorithm_enc == SSL_RC4) + s->s3->need_empty_fragments = 0; +#endif + } + } + + ret = 1; + +err: + if (tmp_block) { + explicit_bzero(tmp_block, key_block_len); + free(tmp_block); + } + return (ret); +} + +/* tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. + * + * Returns: + * 0: (in non-constant time) if the record is publically invalid (i.e. too + * short etc). + * 1: if the record's padding is valid / the encryption was successful. + * -1: if the record's padding/AEAD-authenticator is invalid or, if sending, + * an internal error occured. + */ +int +tls1_enc(SSL *s, int send) +{ + const SSL_AEAD_CTX *aead; + const EVP_CIPHER *enc; + EVP_CIPHER_CTX *ds; + SSL3_RECORD *rec; + unsigned char *seq; + unsigned long l; + int bs, i, j, k, pad = 0, ret, mac_size = 0; + + if (send) { + aead = s->aead_write_ctx; + rec = &s->s3->wrec; + seq = s->s3->write_sequence; + } else { + aead = s->aead_read_ctx; + rec = &s->s3->rrec; + seq = s->s3->read_sequence; + } + + if (aead) { + unsigned char ad[13], *in, *out, nonce[16]; + size_t out_len, pad_len = 0; + unsigned int nonce_used; + + if (SSL_IS_DTLS(s)) { + dtls1_build_sequence_number(ad, seq, + send ? s->d1->w_epoch : s->d1->r_epoch); + } else { + memcpy(ad, seq, SSL3_SEQUENCE_SIZE); + tls1_record_sequence_increment(seq); + } + + ad[8] = rec->type; + ad[9] = (unsigned char)(s->version >> 8); + ad[10] = (unsigned char)(s->version); + + if (aead->variable_nonce_len > 8 || + aead->variable_nonce_len > sizeof(nonce)) + return -1; + + if (aead->xor_fixed_nonce) { + if (aead->fixed_nonce_len > sizeof(nonce) || + aead->variable_nonce_len > aead->fixed_nonce_len) + return -1; /* Should never happen. */ + pad_len = aead->fixed_nonce_len - aead->variable_nonce_len; + } else { + if (aead->fixed_nonce_len + + aead->variable_nonce_len > sizeof(nonce)) + return -1; /* Should never happen. */ + } + + if (send) { + size_t len = rec->length; + size_t eivlen = 0; + in = rec->input; + out = rec->data; + + if (aead->xor_fixed_nonce) { + /* + * The sequence number is left zero + * padded, then xored with the fixed + * nonce. + */ + memset(nonce, 0, pad_len); + memcpy(nonce + pad_len, ad, + aead->variable_nonce_len); + for (i = 0; i < aead->fixed_nonce_len; i++) + nonce[i] ^= aead->fixed_nonce[i]; + nonce_used = aead->fixed_nonce_len; + } else { + /* + * When sending we use the sequence number as + * the variable part of the nonce. + */ + memcpy(nonce, aead->fixed_nonce, + aead->fixed_nonce_len); + nonce_used = aead->fixed_nonce_len; + memcpy(nonce + nonce_used, ad, + aead->variable_nonce_len); + nonce_used += aead->variable_nonce_len; + } + + /* + * In do_ssl3_write, rec->input is moved forward by + * variable_nonce_len in order to leave space for the + * variable nonce. Thus we can copy the sequence number + * bytes into place without overwriting any of the + * plaintext. + */ + if (aead->variable_nonce_in_record) { + memcpy(out, ad, aead->variable_nonce_len); + len -= aead->variable_nonce_len; + eivlen = aead->variable_nonce_len; + } + + ad[11] = len >> 8; + ad[12] = len & 0xff; + + if (!EVP_AEAD_CTX_seal(&aead->ctx, + out + eivlen, &out_len, len + aead->tag_len, nonce, + nonce_used, in + eivlen, len, ad, sizeof(ad))) + return -1; + if (aead->variable_nonce_in_record) + out_len += aead->variable_nonce_len; + } else { + /* receive */ + size_t len = rec->length; + + if (rec->data != rec->input) + return -1; /* internal error - should never happen. */ + out = in = rec->input; + + if (len < aead->variable_nonce_len) + return 0; + + if (aead->xor_fixed_nonce) { + /* + * The sequence number is left zero + * padded, then xored with the fixed + * nonce. + */ + memset(nonce, 0, pad_len); + memcpy(nonce + pad_len, ad, + aead->variable_nonce_len); + for (i = 0; i < aead->fixed_nonce_len; i++) + nonce[i] ^= aead->fixed_nonce[i]; + nonce_used = aead->fixed_nonce_len; + } else { + memcpy(nonce, aead->fixed_nonce, + aead->fixed_nonce_len); + nonce_used = aead->fixed_nonce_len; + + memcpy(nonce + nonce_used, + aead->variable_nonce_in_record ? in : ad, + aead->variable_nonce_len); + nonce_used += aead->variable_nonce_len; + } + + if (aead->variable_nonce_in_record) { + in += aead->variable_nonce_len; + len -= aead->variable_nonce_len; + out += aead->variable_nonce_len; + } + + if (len < aead->tag_len) + return 0; + len -= aead->tag_len; + + ad[11] = len >> 8; + ad[12] = len & 0xff; + + if (!EVP_AEAD_CTX_open(&aead->ctx, out, &out_len, len, + nonce, nonce_used, in, len + aead->tag_len, ad, + sizeof(ad))) + return -1; + + rec->data = rec->input = out; + } + + rec->length = out_len; + + return 1; + } + + if (send) { + if (EVP_MD_CTX_md(s->write_hash)) { + int n = EVP_MD_CTX_size(s->write_hash); + OPENSSL_assert(n >= 0); + } + ds = s->enc_write_ctx; + if (s->enc_write_ctx == NULL) + enc = NULL; + else { + int ivlen = 0; + enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx); + if (SSL_USE_EXPLICIT_IV(s) && + EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE) + ivlen = EVP_CIPHER_iv_length(enc); + if (ivlen > 1) { + if (rec->data != rec->input) { +#ifdef DEBUG + /* we can't write into the input stream: + * Can this ever happen?? (steve) + */ + fprintf(stderr, + "%s:%d: rec->data != rec->input\n", + __FILE__, __LINE__); +#endif + } else + arc4random_buf(rec->input, ivlen); + } + } + } else { + if (EVP_MD_CTX_md(s->read_hash)) { + int n = EVP_MD_CTX_size(s->read_hash); + OPENSSL_assert(n >= 0); + } + ds = s->enc_read_ctx; + if (s->enc_read_ctx == NULL) + enc = NULL; + else + enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx); + } + + if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { + memmove(rec->data, rec->input, rec->length); + rec->input = rec->data; + ret = 1; + } else { + l = rec->length; + bs = EVP_CIPHER_block_size(ds->cipher); + + if (EVP_CIPHER_flags(ds->cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) { + unsigned char buf[13]; + + if (SSL_IS_DTLS(s)) { + dtls1_build_sequence_number(buf, seq, + send ? s->d1->w_epoch : s->d1->r_epoch); + } else { + memcpy(buf, seq, SSL3_SEQUENCE_SIZE); + tls1_record_sequence_increment(seq); + } + + buf[8] = rec->type; + buf[9] = (unsigned char)(s->version >> 8); + buf[10] = (unsigned char)(s->version); + buf[11] = rec->length >> 8; + buf[12] = rec->length & 0xff; + pad = EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_AEAD_TLS1_AAD, 13, buf); + if (send) { + l += pad; + rec->length += pad; + } + } else if ((bs != 1) && send) { + i = bs - ((int)l % bs); + + /* Add weird padding of upto 256 bytes */ + + /* we need to add 'i' padding bytes of value j */ + j = i - 1; + for (k = (int)l; k < (int)(l + i); k++) + rec->input[k] = j; + l += i; + rec->length += i; + } + + if (!send) { + if (l == 0 || l % bs != 0) + return 0; + } + + i = EVP_Cipher(ds, rec->data, rec->input, l); + if ((EVP_CIPHER_flags(ds->cipher) & + EVP_CIPH_FLAG_CUSTOM_CIPHER) ? (i < 0) : (i == 0)) + return -1; /* AEAD can fail to verify MAC */ + if (EVP_CIPHER_mode(enc) == EVP_CIPH_GCM_MODE && !send) { + rec->data += EVP_GCM_TLS_EXPLICIT_IV_LEN; + rec->input += EVP_GCM_TLS_EXPLICIT_IV_LEN; + rec->length -= EVP_GCM_TLS_EXPLICIT_IV_LEN; + } + + ret = 1; + if (EVP_MD_CTX_md(s->read_hash) != NULL) + mac_size = EVP_MD_CTX_size(s->read_hash); + if ((bs != 1) && !send) + ret = tls1_cbc_remove_padding(s, rec, bs, mac_size); + if (pad && !send) + rec->length -= pad; + } + return ret; +} + +int +tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out) +{ + EVP_MD_CTX ctx, *d = NULL; + unsigned int ret; + int i; + + if (s->s3->handshake_buffer) + if (!tls1_digest_cached_records(s)) + return 0; + + for (i = 0; i < SSL_MAX_DIGEST; i++) { + if (s->s3->handshake_dgst[i] && + EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) { + d = s->s3->handshake_dgst[i]; + break; + } + } + if (d == NULL) { + SSLerr(SSL_F_TLS1_CERT_VERIFY_MAC, SSL_R_NO_REQUIRED_DIGEST); + return 0; + } + + EVP_MD_CTX_init(&ctx); + if (!EVP_MD_CTX_copy_ex(&ctx, d)) + return 0; + EVP_DigestFinal_ex(&ctx, out, &ret); + EVP_MD_CTX_cleanup(&ctx); + + return ((int)ret); +} + +int +tls1_final_finish_mac(SSL *s, const char *str, int slen, unsigned char *out) +{ + unsigned int i; + EVP_MD_CTX ctx; + unsigned char buf[2*EVP_MAX_MD_SIZE]; + unsigned char *q, buf2[12]; + int idx; + long mask; + int err = 0; + const EVP_MD *md; + + q = buf; + + if (s->s3->handshake_buffer) + if (!tls1_digest_cached_records(s)) + return 0; + + EVP_MD_CTX_init(&ctx); + + for (idx = 0; ssl_get_handshake_digest(idx, &mask, &md); idx++) { + if (ssl_get_algorithm2(s) & mask) { + int hashsize = EVP_MD_size(md); + EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx]; + if (!hdgst || hashsize < 0 || + hashsize > (int)(sizeof buf - (size_t)(q - buf))) { + /* internal error: 'buf' is too small for this cipersuite! */ + err = 1; + } else { + if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) || + !EVP_DigestFinal_ex(&ctx, q, &i) || + (i != (unsigned int)hashsize)) + err = 1; + q += hashsize; + } + } + } + + if (!tls1_PRF(ssl_get_algorithm2(s), str, slen, buf, (int)(q - buf), + NULL, 0, NULL, 0, NULL, 0, + s->session->master_key, s->session->master_key_length, + out, buf2, sizeof buf2)) + err = 1; + EVP_MD_CTX_cleanup(&ctx); + + if (err) + return 0; + else + return sizeof buf2; +} + +int +tls1_mac(SSL *ssl, unsigned char *md, int send) +{ + SSL3_RECORD *rec; + unsigned char *seq; + EVP_MD_CTX *hash; + size_t md_size, orig_len; + EVP_MD_CTX hmac, *mac_ctx; + unsigned char header[13]; + int stream_mac = (send ? + (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM) : + (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM)); + int t; + + if (send) { + rec = &(ssl->s3->wrec); + seq = &(ssl->s3->write_sequence[0]); + hash = ssl->write_hash; + } else { + rec = &(ssl->s3->rrec); + seq = &(ssl->s3->read_sequence[0]); + hash = ssl->read_hash; + } + + t = EVP_MD_CTX_size(hash); + OPENSSL_assert(t >= 0); + md_size = t; + + /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */ + if (stream_mac) { + mac_ctx = hash; + } else { + if (!EVP_MD_CTX_copy(&hmac, hash)) + return -1; + mac_ctx = &hmac; + } + + if (SSL_IS_DTLS(ssl)) + dtls1_build_sequence_number(header, seq, + send ? ssl->d1->w_epoch : ssl->d1->r_epoch); + else + memcpy(header, seq, SSL3_SEQUENCE_SIZE); + + /* kludge: tls1_cbc_remove_padding passes padding length in rec->type */ + orig_len = rec->length + md_size + ((unsigned int)rec->type >> 8); + rec->type &= 0xff; + + header[8] = rec->type; + header[9] = (unsigned char)(ssl->version >> 8); + header[10] = (unsigned char)(ssl->version); + header[11] = (rec->length) >> 8; + header[12] = (rec->length) & 0xff; + + if (!send && + EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && + ssl3_cbc_record_digest_supported(mac_ctx)) { + /* This is a CBC-encrypted record. We must avoid leaking any + * timing-side channel information about how many blocks of + * data we are hashing because that gives an attacker a + * timing-oracle. */ + if (!ssl3_cbc_digest_record(mac_ctx, + md, &md_size, header, rec->input, + rec->length + md_size, orig_len, + ssl->s3->read_mac_secret, + ssl->s3->read_mac_secret_size, + 0 /* not SSLv3 */)) + return -1; + } else { + EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)); + EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length); + t = EVP_DigestSignFinal(mac_ctx, md, &md_size); + OPENSSL_assert(t > 0); + } + + if (!stream_mac) + EVP_MD_CTX_cleanup(&hmac); + + if (!SSL_IS_DTLS(ssl)) + tls1_record_sequence_increment(seq); + + return (md_size); +} + +int +tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, + int len) +{ + unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH]; + + tls1_PRF(ssl_get_algorithm2(s), + TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE, + s->s3->client_random, SSL3_RANDOM_SIZE, NULL, 0, + s->s3->server_random, SSL3_RANDOM_SIZE, NULL, 0, + p, len, s->session->master_key, buff, sizeof buff); + + return (SSL3_MASTER_SECRET_SIZE); +} + +int +tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, const unsigned char *context, + size_t contextlen, int use_context) +{ + unsigned char *buff; + unsigned char *val = NULL; + size_t vallen, currentvalpos; + int rv; + + buff = malloc(olen); + if (buff == NULL) + goto err2; + + /* construct PRF arguments + * we construct the PRF argument ourself rather than passing separate + * values into the TLS PRF to ensure that the concatenation of values + * does not create a prohibited label. + */ + vallen = llen + SSL3_RANDOM_SIZE * 2; + if (use_context) { + vallen += 2 + contextlen; + } + + val = malloc(vallen); + if (val == NULL) + goto err2; + currentvalpos = 0; + memcpy(val + currentvalpos, (unsigned char *) label, llen); + currentvalpos += llen; + memcpy(val + currentvalpos, s->s3->client_random, SSL3_RANDOM_SIZE); + currentvalpos += SSL3_RANDOM_SIZE; + memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE); + currentvalpos += SSL3_RANDOM_SIZE; + + if (use_context) { + val[currentvalpos] = (contextlen >> 8) & 0xff; + currentvalpos++; + val[currentvalpos] = contextlen & 0xff; + currentvalpos++; + if ((contextlen > 0) || (context != NULL)) { + memcpy(val + currentvalpos, context, contextlen); + } + } + + /* disallow prohibited labels + * note that SSL3_RANDOM_SIZE > max(prohibited label len) = + * 15, so size of val > max(prohibited label len) = 15 and the + * comparisons won't have buffer overflow + */ + if (memcmp(val, TLS_MD_CLIENT_FINISH_CONST, + TLS_MD_CLIENT_FINISH_CONST_SIZE) == 0) + goto err1; + if (memcmp(val, TLS_MD_SERVER_FINISH_CONST, + TLS_MD_SERVER_FINISH_CONST_SIZE) == 0) + goto err1; + if (memcmp(val, TLS_MD_MASTER_SECRET_CONST, + TLS_MD_MASTER_SECRET_CONST_SIZE) == 0) + goto err1; + if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST, + TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) + goto err1; + + rv = tls1_PRF(ssl_get_algorithm2(s), + val, vallen, NULL, 0, NULL, 0, NULL, 0, NULL, 0, + s->session->master_key, s->session->master_key_length, + out, buff, olen); + + goto ret; +err1: + SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, + SSL_R_TLS_ILLEGAL_EXPORTER_LABEL); + rv = 0; + goto ret; +err2: + SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, ERR_R_MALLOC_FAILURE); + rv = 0; +ret: + free(buff); + free(val); + + return (rv); +} + +int +tls1_alert_code(int code) +{ + switch (code) { + case SSL_AD_CLOSE_NOTIFY: + return (SSL3_AD_CLOSE_NOTIFY); + case SSL_AD_UNEXPECTED_MESSAGE: + return (SSL3_AD_UNEXPECTED_MESSAGE); + case SSL_AD_BAD_RECORD_MAC: + return (SSL3_AD_BAD_RECORD_MAC); + case SSL_AD_DECRYPTION_FAILED: + return (TLS1_AD_DECRYPTION_FAILED); + case SSL_AD_RECORD_OVERFLOW: + return (TLS1_AD_RECORD_OVERFLOW); + case SSL_AD_DECOMPRESSION_FAILURE: + return (SSL3_AD_DECOMPRESSION_FAILURE); + case SSL_AD_HANDSHAKE_FAILURE: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_NO_CERTIFICATE: + return (-1); + case SSL_AD_BAD_CERTIFICATE: + return (SSL3_AD_BAD_CERTIFICATE); + case SSL_AD_UNSUPPORTED_CERTIFICATE: + return (SSL3_AD_UNSUPPORTED_CERTIFICATE); + case SSL_AD_CERTIFICATE_REVOKED: + return (SSL3_AD_CERTIFICATE_REVOKED); + case SSL_AD_CERTIFICATE_EXPIRED: + return (SSL3_AD_CERTIFICATE_EXPIRED); + case SSL_AD_CERTIFICATE_UNKNOWN: + return (SSL3_AD_CERTIFICATE_UNKNOWN); + case SSL_AD_ILLEGAL_PARAMETER: + return (SSL3_AD_ILLEGAL_PARAMETER); + case SSL_AD_UNKNOWN_CA: + return (TLS1_AD_UNKNOWN_CA); + case SSL_AD_ACCESS_DENIED: + return (TLS1_AD_ACCESS_DENIED); + case SSL_AD_DECODE_ERROR: + return (TLS1_AD_DECODE_ERROR); + case SSL_AD_DECRYPT_ERROR: + return (TLS1_AD_DECRYPT_ERROR); + case SSL_AD_EXPORT_RESTRICTION: + return (TLS1_AD_EXPORT_RESTRICTION); + case SSL_AD_PROTOCOL_VERSION: + return (TLS1_AD_PROTOCOL_VERSION); + case SSL_AD_INSUFFICIENT_SECURITY: + return (TLS1_AD_INSUFFICIENT_SECURITY); + case SSL_AD_INTERNAL_ERROR: + return (TLS1_AD_INTERNAL_ERROR); + case SSL_AD_INAPPROPRIATE_FALLBACK: + return(TLS1_AD_INAPPROPRIATE_FALLBACK); + case SSL_AD_USER_CANCELLED: + return (TLS1_AD_USER_CANCELLED); + case SSL_AD_NO_RENEGOTIATION: + return (TLS1_AD_NO_RENEGOTIATION); + case SSL_AD_UNSUPPORTED_EXTENSION: + return (TLS1_AD_UNSUPPORTED_EXTENSION); + case SSL_AD_CERTIFICATE_UNOBTAINABLE: + return (TLS1_AD_CERTIFICATE_UNOBTAINABLE); + case SSL_AD_UNRECOGNIZED_NAME: + return (TLS1_AD_UNRECOGNIZED_NAME); + case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + return (TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE); + case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: + return (TLS1_AD_BAD_CERTIFICATE_HASH_VALUE); + case SSL_AD_UNKNOWN_PSK_IDENTITY: + return (TLS1_AD_UNKNOWN_PSK_IDENTITY); + default: + return (-1); + } +} diff --git a/crypto/libressl/ssl/t1_lib.c b/crypto/libressl/ssl/t1_lib.c new file mode 100644 index 0000000000..b225bb3c87 --- /dev/null +++ b/crypto/libressl/ssl/t1_lib.c @@ -0,0 +1,2404 @@ +/* $OpenBSD: t1_lib.c,v 1.86 2016/03/10 23:21:46 mmcc Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include +#include +#include + +#include "ssl_locl.h" +#include "bytestring.h" + +static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen, + const unsigned char *sess_id, int sesslen, + SSL_SESSION **psess); + +SSL3_ENC_METHOD TLSv1_enc_data = { + .enc = tls1_enc, + .mac = tls1_mac, + .setup_key_block = tls1_setup_key_block, + .generate_master_secret = tls1_generate_master_secret, + .change_cipher_state = tls1_change_cipher_state, + .final_finish_mac = tls1_final_finish_mac, + .finish_mac_length = TLS1_FINISH_MAC_LENGTH, + .cert_verify_mac = tls1_cert_verify_mac, + .client_finished_label = TLS_MD_CLIENT_FINISH_CONST, + .client_finished_label_len = TLS_MD_CLIENT_FINISH_CONST_SIZE, + .server_finished_label = TLS_MD_SERVER_FINISH_CONST, + .server_finished_label_len = TLS_MD_SERVER_FINISH_CONST_SIZE, + .alert_value = tls1_alert_code, + .export_keying_material = tls1_export_keying_material, + .enc_flags = 0, +}; + +SSL3_ENC_METHOD TLSv1_1_enc_data = { + .enc = tls1_enc, + .mac = tls1_mac, + .setup_key_block = tls1_setup_key_block, + .generate_master_secret = tls1_generate_master_secret, + .change_cipher_state = tls1_change_cipher_state, + .final_finish_mac = tls1_final_finish_mac, + .finish_mac_length = TLS1_FINISH_MAC_LENGTH, + .cert_verify_mac = tls1_cert_verify_mac, + .client_finished_label = TLS_MD_CLIENT_FINISH_CONST, + .client_finished_label_len = TLS_MD_CLIENT_FINISH_CONST_SIZE, + .server_finished_label = TLS_MD_SERVER_FINISH_CONST, + .server_finished_label_len = TLS_MD_SERVER_FINISH_CONST_SIZE, + .alert_value = tls1_alert_code, + .export_keying_material = tls1_export_keying_material, + .enc_flags = SSL_ENC_FLAG_EXPLICIT_IV, +}; + +SSL3_ENC_METHOD TLSv1_2_enc_data = { + .enc = tls1_enc, + .mac = tls1_mac, + .setup_key_block = tls1_setup_key_block, + .generate_master_secret = tls1_generate_master_secret, + .change_cipher_state = tls1_change_cipher_state, + .final_finish_mac = tls1_final_finish_mac, + .finish_mac_length = TLS1_FINISH_MAC_LENGTH, + .cert_verify_mac = tls1_cert_verify_mac, + .client_finished_label = TLS_MD_CLIENT_FINISH_CONST, + .client_finished_label_len = TLS_MD_CLIENT_FINISH_CONST_SIZE, + .server_finished_label = TLS_MD_SERVER_FINISH_CONST, + .server_finished_label_len = TLS_MD_SERVER_FINISH_CONST_SIZE, + .alert_value = tls1_alert_code, + .export_keying_material = tls1_export_keying_material, + .enc_flags = SSL_ENC_FLAG_EXPLICIT_IV|SSL_ENC_FLAG_SIGALGS| + SSL_ENC_FLAG_SHA256_PRF|SSL_ENC_FLAG_TLS1_2_CIPHERS, +}; + +long +tls1_default_timeout(void) +{ + /* 2 hours, the 24 hours mentioned in the TLSv1 spec + * is way too long for http, the cache would over fill */ + return (60 * 60 * 2); +} + +int +tls1_new(SSL *s) +{ + if (!ssl3_new(s)) + return (0); + s->method->ssl_clear(s); + return (1); +} + +void +tls1_free(SSL *s) +{ + if (s == NULL) + return; + + free(s->tlsext_session_ticket); + ssl3_free(s); +} + +void +tls1_clear(SSL *s) +{ + ssl3_clear(s); + s->version = s->method->version; +} + + +static int nid_list[] = { + NID_sect163k1, /* sect163k1 (1) */ + NID_sect163r1, /* sect163r1 (2) */ + NID_sect163r2, /* sect163r2 (3) */ + NID_sect193r1, /* sect193r1 (4) */ + NID_sect193r2, /* sect193r2 (5) */ + NID_sect233k1, /* sect233k1 (6) */ + NID_sect233r1, /* sect233r1 (7) */ + NID_sect239k1, /* sect239k1 (8) */ + NID_sect283k1, /* sect283k1 (9) */ + NID_sect283r1, /* sect283r1 (10) */ + NID_sect409k1, /* sect409k1 (11) */ + NID_sect409r1, /* sect409r1 (12) */ + NID_sect571k1, /* sect571k1 (13) */ + NID_sect571r1, /* sect571r1 (14) */ + NID_secp160k1, /* secp160k1 (15) */ + NID_secp160r1, /* secp160r1 (16) */ + NID_secp160r2, /* secp160r2 (17) */ + NID_secp192k1, /* secp192k1 (18) */ + NID_X9_62_prime192v1, /* secp192r1 (19) */ + NID_secp224k1, /* secp224k1 (20) */ + NID_secp224r1, /* secp224r1 (21) */ + NID_secp256k1, /* secp256k1 (22) */ + NID_X9_62_prime256v1, /* secp256r1 (23) */ + NID_secp384r1, /* secp384r1 (24) */ + NID_secp521r1, /* secp521r1 (25) */ + NID_brainpoolP256r1, /* brainpoolP256r1 (26) */ + NID_brainpoolP384r1, /* brainpoolP384r1 (27) */ + NID_brainpoolP512r1 /* brainpoolP512r1 (28) */ +}; + +static const uint8_t ecformats_default[] = { + TLSEXT_ECPOINTFORMAT_uncompressed, + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime, + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 +}; + +static const uint16_t eccurves_default[] = { + 14, /* sect571r1 (14) */ + 13, /* sect571k1 (13) */ + 25, /* secp521r1 (25) */ + 28, /* brainpool512r1 (28) */ + 11, /* sect409k1 (11) */ + 12, /* sect409r1 (12) */ + 27, /* brainpoolP384r1 (27) */ + 24, /* secp384r1 (24) */ + 9, /* sect283k1 (9) */ + 10, /* sect283r1 (10) */ + 26, /* brainpoolP256r1 (26) */ + 22, /* secp256k1 (22) */ + 23, /* secp256r1 (23) */ + 8, /* sect239k1 (8) */ + 6, /* sect233k1 (6) */ + 7, /* sect233r1 (7) */ + 20, /* secp224k1 (20) */ + 21, /* secp224r1 (21) */ + 4, /* sect193r1 (4) */ + 5, /* sect193r2 (5) */ + 18, /* secp192k1 (18) */ + 19, /* secp192r1 (19) */ + 1, /* sect163k1 (1) */ + 2, /* sect163r1 (2) */ + 3, /* sect163r2 (3) */ + 15, /* secp160k1 (15) */ + 16, /* secp160r1 (16) */ + 17, /* secp160r2 (17) */ +}; + +int +tls1_ec_curve_id2nid(uint16_t curve_id) +{ + /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */ + if ((curve_id < 1) || + ((unsigned int)curve_id > sizeof(nid_list) / sizeof(nid_list[0]))) + return 0; + return nid_list[curve_id - 1]; +} + +uint16_t +tls1_ec_nid2curve_id(int nid) +{ + /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */ + switch (nid) { + case NID_sect163k1: /* sect163k1 (1) */ + return 1; + case NID_sect163r1: /* sect163r1 (2) */ + return 2; + case NID_sect163r2: /* sect163r2 (3) */ + return 3; + case NID_sect193r1: /* sect193r1 (4) */ + return 4; + case NID_sect193r2: /* sect193r2 (5) */ + return 5; + case NID_sect233k1: /* sect233k1 (6) */ + return 6; + case NID_sect233r1: /* sect233r1 (7) */ + return 7; + case NID_sect239k1: /* sect239k1 (8) */ + return 8; + case NID_sect283k1: /* sect283k1 (9) */ + return 9; + case NID_sect283r1: /* sect283r1 (10) */ + return 10; + case NID_sect409k1: /* sect409k1 (11) */ + return 11; + case NID_sect409r1: /* sect409r1 (12) */ + return 12; + case NID_sect571k1: /* sect571k1 (13) */ + return 13; + case NID_sect571r1: /* sect571r1 (14) */ + return 14; + case NID_secp160k1: /* secp160k1 (15) */ + return 15; + case NID_secp160r1: /* secp160r1 (16) */ + return 16; + case NID_secp160r2: /* secp160r2 (17) */ + return 17; + case NID_secp192k1: /* secp192k1 (18) */ + return 18; + case NID_X9_62_prime192v1: /* secp192r1 (19) */ + return 19; + case NID_secp224k1: /* secp224k1 (20) */ + return 20; + case NID_secp224r1: /* secp224r1 (21) */ + return 21; + case NID_secp256k1: /* secp256k1 (22) */ + return 22; + case NID_X9_62_prime256v1: /* secp256r1 (23) */ + return 23; + case NID_secp384r1: /* secp384r1 (24) */ + return 24; + case NID_secp521r1: /* secp521r1 (25) */ + return 25; + case NID_brainpoolP256r1: /* brainpoolP256r1 (26) */ + return 26; + case NID_brainpoolP384r1: /* brainpoolP384r1 (27) */ + return 27; + case NID_brainpoolP512r1: /* brainpoolP512r1 (28) */ + return 28; + default: + return 0; + } +} + +/* + * Return the appropriate format list. If client_formats is non-zero, return + * the client/session formats. Otherwise return the custom format list if one + * exists, or the default formats if a custom list has not been specified. + */ +static void +tls1_get_formatlist(SSL *s, int client_formats, const uint8_t **pformats, + size_t *pformatslen) +{ + if (client_formats != 0) { + *pformats = s->session->tlsext_ecpointformatlist; + *pformatslen = s->session->tlsext_ecpointformatlist_length; + return; + } + + *pformats = s->tlsext_ecpointformatlist; + *pformatslen = s->tlsext_ecpointformatlist_length; + if (*pformats == NULL) { + *pformats = ecformats_default; + *pformatslen = sizeof(ecformats_default); + } +} + +/* + * Return the appropriate curve list. If client_curves is non-zero, return + * the client/session curves. Otherwise return the custom curve list if one + * exists, or the default curves if a custom list has not been specified. + */ +static void +tls1_get_curvelist(SSL *s, int client_curves, const uint16_t **pcurves, + size_t *pcurveslen) +{ + if (client_curves != 0) { + *pcurves = s->session->tlsext_ellipticcurvelist; + *pcurveslen = s->session->tlsext_ellipticcurvelist_length; + return; + } + + *pcurves = s->tlsext_ellipticcurvelist; + *pcurveslen = s->tlsext_ellipticcurvelist_length; + if (*pcurves == NULL) { + *pcurves = eccurves_default; + *pcurveslen = sizeof(eccurves_default) / 2; + } +} + +/* Check that a curve is one of our preferences. */ +int +tls1_check_curve(SSL *s, const unsigned char *p, size_t len) +{ + CBS cbs; + const uint16_t *curves; + size_t curveslen, i; + uint8_t type; + uint16_t cid; + + CBS_init(&cbs, p, len); + + /* Only named curves are supported. */ + if (CBS_len(&cbs) != 3 || + !CBS_get_u8(&cbs, &type) || + type != NAMED_CURVE_TYPE || + !CBS_get_u16(&cbs, &cid)) + return (0); + + tls1_get_curvelist(s, 0, &curves, &curveslen); + + for (i = 0; i < curveslen; i++) { + if (curves[i] == cid) + return (1); + } + return (0); +} + +int +tls1_get_shared_curve(SSL *s) +{ + size_t preflen, supplen, i, j; + const uint16_t *pref, *supp; + unsigned long server_pref; + + /* Cannot do anything on the client side. */ + if (s->server == 0) + return (NID_undef); + + /* Return first preference shared curve. */ + server_pref = (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE); + tls1_get_curvelist(s, (server_pref == 0), &pref, &preflen); + tls1_get_curvelist(s, (server_pref != 0), &supp, &supplen); + + for (i = 0; i < preflen; i++) { + for (j = 0; j < supplen; j++) { + if (pref[i] == supp[j]) + return (tls1_ec_curve_id2nid(pref[i])); + } + } + return (NID_undef); +} + +/* For an EC key set TLS ID and required compression based on parameters. */ +static int +tls1_set_ec_id(uint16_t *curve_id, uint8_t *comp_id, EC_KEY *ec) +{ + const EC_GROUP *grp; + const EC_METHOD *meth; + int is_prime = 0; + int nid, id; + + if (ec == NULL) + return (0); + + /* Determine if it is a prime field. */ + if ((grp = EC_KEY_get0_group(ec)) == NULL) + return (0); + if ((meth = EC_GROUP_method_of(grp)) == NULL) + return (0); + if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field) + is_prime = 1; + + /* Determine curve ID. */ + nid = EC_GROUP_get_curve_name(grp); + id = tls1_ec_nid2curve_id(nid); + + /* If we have an ID set it, otherwise set arbitrary explicit curve. */ + if (id != 0) + *curve_id = id; + else + *curve_id = is_prime ? 0xff01 : 0xff02; + + /* Specify the compression identifier. */ + if (comp_id != NULL) { + if (EC_KEY_get0_public_key(ec) == NULL) + return (0); + + if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_COMPRESSED) { + *comp_id = is_prime ? + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime : + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; + } else { + *comp_id = TLSEXT_ECPOINTFORMAT_uncompressed; + } + } + return (1); +} + +/* Check that an EC key is compatible with extensions. */ +static int +tls1_check_ec_key(SSL *s, const uint16_t *curve_id, const uint8_t *comp_id) +{ + size_t curveslen, formatslen, i; + const uint16_t *curves; + const uint8_t *formats; + + /* + * Check point formats extension if present, otherwise everything + * is supported (see RFC4492). + */ + tls1_get_formatlist(s, 1, &formats, &formatslen); + if (comp_id != NULL && formats != NULL) { + for (i = 0; i < formatslen; i++) { + if (formats[i] == *comp_id) + break; + } + if (i == formatslen) + return (0); + } + + /* + * Check curve list if present, otherwise everything is supported. + */ + tls1_get_curvelist(s, 1, &curves, &curveslen); + if (curve_id != NULL && curves != NULL) { + for (i = 0; i < curveslen; i++) { + if (curves[i] == *curve_id) + break; + } + if (i == curveslen) + return (0); + } + + return (1); +} + +/* Check EC server key is compatible with client extensions. */ +int +tls1_check_ec_server_key(SSL *s) +{ + CERT_PKEY *cpk = s->cert->pkeys + SSL_PKEY_ECC; + uint16_t curve_id; + uint8_t comp_id; + EVP_PKEY *pkey; + int rv; + + if (cpk->x509 == NULL || cpk->privatekey == NULL) + return (0); + if ((pkey = X509_get_pubkey(cpk->x509)) == NULL) + return (0); + rv = tls1_set_ec_id(&curve_id, &comp_id, pkey->pkey.ec); + EVP_PKEY_free(pkey); + if (rv != 1) + return (0); + + return tls1_check_ec_key(s, &curve_id, &comp_id); +} + +/* Check EC temporary key is compatible with client extensions. */ +int +tls1_check_ec_tmp_key(SSL *s) +{ + EC_KEY *ec = s->cert->ecdh_tmp; + uint16_t curve_id; + + if (s->cert->ecdh_tmp_auto != 0) { + /* Need a shared curve. */ + if (tls1_get_shared_curve(s) != NID_undef) + return (1); + return (0); + } + + if (ec == NULL) { + if (s->cert->ecdh_tmp_cb != NULL) + return (1); + return (0); + } + if (tls1_set_ec_id(&curve_id, NULL, ec) != 1) + return (0); + + return tls1_check_ec_key(s, &curve_id, NULL); +} + +/* + * List of supported signature algorithms and hashes. Should make this + * customisable at some point, for now include everything we support. + */ + +static unsigned char tls12_sigalgs[] = { + TLSEXT_hash_sha512, TLSEXT_signature_rsa, + TLSEXT_hash_sha512, TLSEXT_signature_dsa, + TLSEXT_hash_sha512, TLSEXT_signature_ecdsa, +#ifndef OPENSSL_NO_GOST + TLSEXT_hash_streebog_512, TLSEXT_signature_gostr12_512, +#endif + + TLSEXT_hash_sha384, TLSEXT_signature_rsa, + TLSEXT_hash_sha384, TLSEXT_signature_dsa, + TLSEXT_hash_sha384, TLSEXT_signature_ecdsa, + + TLSEXT_hash_sha256, TLSEXT_signature_rsa, + TLSEXT_hash_sha256, TLSEXT_signature_dsa, + TLSEXT_hash_sha256, TLSEXT_signature_ecdsa, + +#ifndef OPENSSL_NO_GOST + TLSEXT_hash_streebog_256, TLSEXT_signature_gostr12_256, + TLSEXT_hash_gost94, TLSEXT_signature_gostr01, +#endif + + TLSEXT_hash_sha224, TLSEXT_signature_rsa, + TLSEXT_hash_sha224, TLSEXT_signature_dsa, + TLSEXT_hash_sha224, TLSEXT_signature_ecdsa, + + TLSEXT_hash_sha1, TLSEXT_signature_rsa, + TLSEXT_hash_sha1, TLSEXT_signature_dsa, + TLSEXT_hash_sha1, TLSEXT_signature_ecdsa, +}; + +int +tls12_get_req_sig_algs(SSL *s, unsigned char *p) +{ + size_t slen = sizeof(tls12_sigalgs); + + if (p) + memcpy(p, tls12_sigalgs, slen); + return (int)slen; +} + +unsigned char * +ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) +{ + int extdatalen = 0; + unsigned char *ret = p; + int using_ecc = 0; + + /* See if we support any ECC ciphersuites. */ + if (s->version != DTLS1_VERSION && s->version >= TLS1_VERSION) { + STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s); + unsigned long alg_k, alg_a; + int i; + + for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) { + SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i); + + alg_k = c->algorithm_mkey; + alg_a = c->algorithm_auth; + + if ((alg_k & (SSL_kECDHE|SSL_kECDHr|SSL_kECDHe) || + (alg_a & SSL_aECDSA))) { + using_ecc = 1; + break; + } + } + } + + ret += 2; + + if (ret >= limit) + return NULL; /* this really never occurs, but ... */ + + if (s->tlsext_hostname != NULL) { + /* Add TLS extension servername to the Client Hello message */ + size_t size_str, lenmax; + + /* check for enough space. + 4 for the servername type and extension length + 2 for servernamelist length + 1 for the hostname type + 2 for hostname length + + hostname length + */ + + if ((size_t)(limit - ret) < 9) + return NULL; + + lenmax = limit - ret - 9; + if ((size_str = strlen(s->tlsext_hostname)) > lenmax) + return NULL; + + /* extension type and length */ + s2n(TLSEXT_TYPE_server_name, ret); + + s2n(size_str + 5, ret); + + /* length of servername list */ + s2n(size_str + 3, ret); + + /* hostname type, length and hostname */ + *(ret++) = (unsigned char) TLSEXT_NAMETYPE_host_name; + s2n(size_str, ret); + memcpy(ret, s->tlsext_hostname, size_str); + ret += size_str; + } + + /* Add RI if renegotiating */ + if (s->renegotiate) { + int el; + + if (!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, + ERR_R_INTERNAL_ERROR); + return NULL; + } + + if ((size_t)(limit - ret) < 4 + el) + return NULL; + + s2n(TLSEXT_TYPE_renegotiate, ret); + s2n(el, ret); + + if (!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, + ERR_R_INTERNAL_ERROR); + return NULL; + } + + ret += el; + } + + if (using_ecc) { + size_t curveslen, formatslen, lenmax; + const uint16_t *curves; + const uint8_t *formats; + int i; + + /* + * Add TLS extension ECPointFormats to the ClientHello message. + */ + tls1_get_formatlist(s, 0, &formats, &formatslen); + + if ((size_t)(limit - ret) < 5) + return NULL; + + lenmax = limit - ret - 5; + if (formatslen > lenmax) + return NULL; + if (formatslen > 255) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, + ERR_R_INTERNAL_ERROR); + return NULL; + } + + s2n(TLSEXT_TYPE_ec_point_formats, ret); + s2n(formatslen + 1, ret); + *(ret++) = (unsigned char)formatslen; + memcpy(ret, formats, formatslen); + ret += formatslen; + + /* + * Add TLS extension EllipticCurves to the ClientHello message. + */ + tls1_get_curvelist(s, 0, &curves, &curveslen); + + if ((size_t)(limit - ret) < 6) + return NULL; + + lenmax = limit - ret - 6; + if (curveslen > lenmax) + return NULL; + if (curveslen > 65532) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, + ERR_R_INTERNAL_ERROR); + return NULL; + } + + s2n(TLSEXT_TYPE_elliptic_curves, ret); + s2n((curveslen * 2) + 2, ret); + + /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for + * elliptic_curve_list, but the examples use two bytes. + * https://www1.ietf.org/mail-archive/web/tls/current/msg00538.html + * resolves this to two bytes. + */ + s2n(curveslen * 2, ret); + for (i = 0; i < curveslen; i++) + s2n(curves[i], ret); + } + + if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) { + int ticklen; + if (!s->new_session && s->session && s->session->tlsext_tick) + ticklen = s->session->tlsext_ticklen; + else if (s->session && s->tlsext_session_ticket && + s->tlsext_session_ticket->data) { + ticklen = s->tlsext_session_ticket->length; + s->session->tlsext_tick = malloc(ticklen); + if (!s->session->tlsext_tick) + return NULL; + memcpy(s->session->tlsext_tick, + s->tlsext_session_ticket->data, ticklen); + s->session->tlsext_ticklen = ticklen; + } else + ticklen = 0; + if (ticklen == 0 && s->tlsext_session_ticket && + s->tlsext_session_ticket->data == NULL) + goto skip_ext; + /* Check for enough room 2 for extension type, 2 for len + * rest for ticket + */ + if ((size_t)(limit - ret) < 4 + ticklen) + return NULL; + s2n(TLSEXT_TYPE_session_ticket, ret); + + s2n(ticklen, ret); + if (ticklen) { + memcpy(ret, s->session->tlsext_tick, ticklen); + ret += ticklen; + } + } +skip_ext: + + if (TLS1_get_client_version(s) >= TLS1_2_VERSION) { + if ((size_t)(limit - ret) < sizeof(tls12_sigalgs) + 6) + return NULL; + + s2n(TLSEXT_TYPE_signature_algorithms, ret); + s2n(sizeof(tls12_sigalgs) + 2, ret); + s2n(sizeof(tls12_sigalgs), ret); + memcpy(ret, tls12_sigalgs, sizeof(tls12_sigalgs)); + ret += sizeof(tls12_sigalgs); + } + + if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp && + s->version != DTLS1_VERSION) { + int i; + long extlen, idlen, itmp; + OCSP_RESPID *id; + + idlen = 0; + for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) { + id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i); + itmp = i2d_OCSP_RESPID(id, NULL); + if (itmp <= 0) + return NULL; + idlen += itmp + 2; + } + + if (s->tlsext_ocsp_exts) { + extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL); + if (extlen < 0) + return NULL; + } else + extlen = 0; + + if ((size_t)(limit - ret) < 7 + extlen + idlen) + return NULL; + s2n(TLSEXT_TYPE_status_request, ret); + if (extlen + idlen > 0xFFF0) + return NULL; + s2n(extlen + idlen + 5, ret); + *(ret++) = TLSEXT_STATUSTYPE_ocsp; + s2n(idlen, ret); + for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) { + /* save position of id len */ + unsigned char *q = ret; + id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i); + /* skip over id len */ + ret += 2; + itmp = i2d_OCSP_RESPID(id, &ret); + /* write id len */ + s2n(itmp, q); + } + s2n(extlen, ret); + if (extlen > 0) + i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret); + } + + if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len) { + /* The client advertises an emtpy extension to indicate its + * support for Next Protocol Negotiation */ + if ((size_t)(limit - ret) < 4) + return NULL; + s2n(TLSEXT_TYPE_next_proto_neg, ret); + s2n(0, ret); + } + + if (s->alpn_client_proto_list != NULL && + s->s3->tmp.finish_md_len == 0) { + if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len) + return (NULL); + s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); + s2n(2 + s->alpn_client_proto_list_len, ret); + s2n(s->alpn_client_proto_list_len, ret); + memcpy(ret, s->alpn_client_proto_list, + s->alpn_client_proto_list_len); + ret += s->alpn_client_proto_list_len; + } + +#ifndef OPENSSL_NO_SRTP + if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) { + int el; + + ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0); + + if ((size_t)(limit - ret) < 4 + el) + return NULL; + + s2n(TLSEXT_TYPE_use_srtp, ret); + s2n(el, ret); + + if (ssl_add_clienthello_use_srtp_ext(s, ret, &el, el)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, + ERR_R_INTERNAL_ERROR); + return NULL; + } + ret += el; + } +#endif + + /* + * Add padding to workaround bugs in F5 terminators. + * See https://tools.ietf.org/html/draft-agl-tls-padding-03 + * + * Note that this seems to trigger issues with IronPort SMTP + * appliances. + * + * NB: because this code works out the length of all existing + * extensions it MUST always appear last. + */ + if (s->options & SSL_OP_TLSEXT_PADDING) { + int hlen = ret - (unsigned char *)s->init_buf->data; + + /* + * The code in s23_clnt.c to build ClientHello messages + * includes the 5-byte record header in the buffer, while the + * code in s3_clnt.c does not. + */ + if (s->state == SSL23_ST_CW_CLNT_HELLO_A) + hlen -= 5; + if (hlen > 0xff && hlen < 0x200) { + hlen = 0x200 - hlen; + if (hlen >= 4) + hlen -= 4; + else + hlen = 0; + + s2n(TLSEXT_TYPE_padding, ret); + s2n(hlen, ret); + memset(ret, 0, hlen); + ret += hlen; + } + } + + if ((extdatalen = ret - p - 2) == 0) + return p; + + s2n(extdatalen, p); + return ret; +} + +unsigned char * +ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) +{ + int using_ecc, extdatalen = 0; + unsigned long alg_a, alg_k; + unsigned char *ret = p; + int next_proto_neg_seen; + + alg_a = s->s3->tmp.new_cipher->algorithm_auth; + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + using_ecc = (alg_k & (SSL_kECDHE|SSL_kECDHr|SSL_kECDHe) || + alg_a & SSL_aECDSA) && + s->session->tlsext_ecpointformatlist != NULL; + + ret += 2; + if (ret >= limit) + return NULL; /* this really never occurs, but ... */ + + if (!s->hit && s->servername_done == 1 && + s->session->tlsext_hostname != NULL) { + if ((size_t)(limit - ret) < 4) + return NULL; + + s2n(TLSEXT_TYPE_server_name, ret); + s2n(0, ret); + } + + if (s->s3->send_connection_binding) { + int el; + + if (!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0)) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, + ERR_R_INTERNAL_ERROR); + return NULL; + } + + if ((size_t)(limit - ret) < 4 + el) + return NULL; + + s2n(TLSEXT_TYPE_renegotiate, ret); + s2n(el, ret); + + if (!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el)) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, + ERR_R_INTERNAL_ERROR); + return NULL; + } + + ret += el; + } + + if (using_ecc && s->version != DTLS1_VERSION) { + const unsigned char *formats; + size_t formatslen, lenmax; + + /* + * Add TLS extension ECPointFormats to the ServerHello message. + */ + tls1_get_formatlist(s, 0, &formats, &formatslen); + + if ((size_t)(limit - ret) < 5) + return NULL; + + lenmax = limit - ret - 5; + if (formatslen > lenmax) + return NULL; + if (formatslen > 255) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, + ERR_R_INTERNAL_ERROR); + return NULL; + } + + s2n(TLSEXT_TYPE_ec_point_formats, ret); + s2n(formatslen + 1, ret); + *(ret++) = (unsigned char)formatslen; + memcpy(ret, formats, formatslen); + ret += formatslen; + } + + /* + * Currently the server should not respond with a SupportedCurves + * extension. + */ + + if (s->tlsext_ticket_expected && + !(SSL_get_options(s) & SSL_OP_NO_TICKET)) { + if ((size_t)(limit - ret) < 4) + return NULL; + + s2n(TLSEXT_TYPE_session_ticket, ret); + s2n(0, ret); + } + + if (s->tlsext_status_expected) { + if ((size_t)(limit - ret) < 4) + return NULL; + + s2n(TLSEXT_TYPE_status_request, ret); + s2n(0, ret); + } + +#ifndef OPENSSL_NO_SRTP + if (SSL_IS_DTLS(s) && s->srtp_profile) { + int el; + + ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0); + + if ((size_t)(limit - ret) < 4 + el) + return NULL; + + s2n(TLSEXT_TYPE_use_srtp, ret); + s2n(el, ret); + + if (ssl_add_serverhello_use_srtp_ext(s, ret, &el, el)) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, + ERR_R_INTERNAL_ERROR); + return NULL; + } + ret += el; + } +#endif + + if (((s->s3->tmp.new_cipher->id & 0xFFFF) == 0x80 || + (s->s3->tmp.new_cipher->id & 0xFFFF) == 0x81) && + (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG)) { + static const unsigned char cryptopro_ext[36] = { + 0xfd, 0xe8, /*65000*/ + 0x00, 0x20, /*32 bytes length*/ + 0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85, + 0x03, 0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06, + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08, + 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17 + }; + if ((size_t)(limit - ret) < sizeof(cryptopro_ext)) + return NULL; + memcpy(ret, cryptopro_ext, sizeof(cryptopro_ext)); + ret += sizeof(cryptopro_ext); + } + + next_proto_neg_seen = s->s3->next_proto_neg_seen; + s->s3->next_proto_neg_seen = 0; + if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb) { + const unsigned char *npa; + unsigned int npalen; + int r; + + r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen, + s->ctx->next_protos_advertised_cb_arg); + if (r == SSL_TLSEXT_ERR_OK) { + if ((size_t)(limit - ret) < 4 + npalen) + return NULL; + s2n(TLSEXT_TYPE_next_proto_neg, ret); + s2n(npalen, ret); + memcpy(ret, npa, npalen); + ret += npalen; + s->s3->next_proto_neg_seen = 1; + } + } + + if (s->s3->alpn_selected != NULL) { + const unsigned char *selected = s->s3->alpn_selected; + unsigned int len = s->s3->alpn_selected_len; + + if ((long)(limit - ret - 4 - 2 - 1 - len) < 0) + return (NULL); + s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); + s2n(3 + len, ret); + s2n(1 + len, ret); + *ret++ = len; + memcpy(ret, selected, len); + ret += len; + } + + if ((extdatalen = ret - p - 2) == 0) + return p; + + s2n(extdatalen, p); + return ret; +} + +/* + * tls1_alpn_handle_client_hello is called to process the ALPN extension in a + * ClientHello. + * data: the contents of the extension, not including the type and length. + * data_len: the number of bytes in data. + * al: a pointer to the alert value to send in the event of a non-zero + * return. + * returns: 1 on success. + */ +static int +tls1_alpn_handle_client_hello(SSL *s, const unsigned char *data, + unsigned int data_len, int *al) +{ + CBS cbs, proto_name_list, alpn; + const unsigned char *selected; + unsigned char selected_len; + int r; + + if (s->ctx->alpn_select_cb == NULL) + return (1); + + if (data_len < 2) + goto parse_error; + + CBS_init(&cbs, data, data_len); + + /* + * data should contain a uint16 length followed by a series of 8-bit, + * length-prefixed strings. + */ + if (!CBS_get_u16_length_prefixed(&cbs, &alpn) || + CBS_len(&alpn) < 2 || + CBS_len(&cbs) != 0) + goto parse_error; + + /* Validate data before sending to callback. */ + CBS_dup(&alpn, &proto_name_list); + while (CBS_len(&proto_name_list) > 0) { + CBS proto_name; + + if (!CBS_get_u8_length_prefixed(&proto_name_list, &proto_name) || + CBS_len(&proto_name) == 0) + goto parse_error; + } + + r = s->ctx->alpn_select_cb(s, &selected, &selected_len, + CBS_data(&alpn), CBS_len(&alpn), s->ctx->alpn_select_cb_arg); + if (r == SSL_TLSEXT_ERR_OK) { + free(s->s3->alpn_selected); + if ((s->s3->alpn_selected = malloc(selected_len)) == NULL) { + *al = SSL_AD_INTERNAL_ERROR; + return (-1); + } + memcpy(s->s3->alpn_selected, selected, selected_len); + s->s3->alpn_selected_len = selected_len; + } + + return (1); + +parse_error: + *al = SSL_AD_DECODE_ERROR; + return (0); +} + +int +ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, + int n, int *al) +{ + unsigned short type; + unsigned short size; + unsigned short len; + unsigned char *data = *p; + int renegotiate_seen = 0; + int sigalg_seen = 0; + + s->servername_done = 0; + s->tlsext_status_type = -1; + s->s3->next_proto_neg_seen = 0; + free(s->s3->alpn_selected); + s->s3->alpn_selected = NULL; + + if (data >= (d + n - 2)) + goto ri_check; + n2s(data, len); + + if (data > (d + n - len)) + goto ri_check; + + while (data <= (d + n - 4)) { + n2s(data, type); + n2s(data, size); + + if (data + size > (d + n)) + goto ri_check; + if (s->tlsext_debug_cb) + s->tlsext_debug_cb(s, 0, type, data, size, + s->tlsext_debug_arg); +/* The servername extension is treated as follows: + + - Only the hostname type is supported with a maximum length of 255. + - The servername is rejected if too long or if it contains zeros, + in which case an fatal alert is generated. + - The servername field is maintained together with the session cache. + - When a session is resumed, the servername call back invoked in order + to allow the application to position itself to the right context. + - The servername is acknowledged if it is new for a session or when + it is identical to a previously used for the same session. + Applications can control the behaviour. They can at any time + set a 'desirable' servername for a new SSL object. This can be the + case for example with HTTPS when a Host: header field is received and + a renegotiation is requested. In this case, a possible servername + presented in the new client hello is only acknowledged if it matches + the value of the Host: field. + - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION + if they provide for changing an explicit servername context for the session, + i.e. when the session has been established with a servername extension. + - On session reconnect, the servername extension may be absent. + +*/ + + if (type == TLSEXT_TYPE_server_name) { + unsigned char *sdata; + int servname_type; + int dsize; + + if (size < 2) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + n2s(data, dsize); + + size -= 2; + if (dsize > size) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + sdata = data; + while (dsize > 3) { + servname_type = *(sdata++); + + n2s(sdata, len); + dsize -= 3; + + if (len > dsize) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + if (s->servername_done == 0) + switch (servname_type) { + case TLSEXT_NAMETYPE_host_name: + if (!s->hit) { + if (s->session->tlsext_hostname) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + if (len > TLSEXT_MAXLEN_host_name) { + *al = TLS1_AD_UNRECOGNIZED_NAME; + return 0; + } + if ((s->session->tlsext_hostname = + malloc(len + 1)) == NULL) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + memcpy(s->session->tlsext_hostname, sdata, len); + s->session->tlsext_hostname[len] = '\0'; + if (strlen(s->session->tlsext_hostname) != len) { + free(s->session->tlsext_hostname); + s->session->tlsext_hostname = NULL; + *al = TLS1_AD_UNRECOGNIZED_NAME; + return 0; + } + s->servername_done = 1; + + + } else { + s->servername_done = s->session->tlsext_hostname && + strlen(s->session->tlsext_hostname) == len && + strncmp(s->session->tlsext_hostname, (char *)sdata, len) == 0; + } + break; + + default: + break; + } + + dsize -= len; + } + if (dsize != 0) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + } + + else if (type == TLSEXT_TYPE_ec_point_formats && + s->version != DTLS1_VERSION) { + unsigned char *sdata = data; + size_t formatslen; + uint8_t *formats; + + if (size < 1) { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + formatslen = *(sdata++); + if (formatslen != size - 1) { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + + if (!s->hit) { + free(s->session->tlsext_ecpointformatlist); + s->session->tlsext_ecpointformatlist = NULL; + s->session->tlsext_ecpointformatlist_length = 0; + + if ((formats = reallocarray(NULL, formatslen, + sizeof(uint8_t))) == NULL) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + memcpy(formats, sdata, formatslen); + s->session->tlsext_ecpointformatlist = formats; + s->session->tlsext_ecpointformatlist_length = + formatslen; + } + } else if (type == TLSEXT_TYPE_elliptic_curves && + s->version != DTLS1_VERSION) { + unsigned char *sdata = data; + size_t curveslen, i; + uint16_t *curves; + + if (size < 2) { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + n2s(sdata, curveslen); + if (curveslen != size - 2 || curveslen % 2 != 0) { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + curveslen /= 2; + + if (!s->hit) { + if (s->session->tlsext_ellipticcurvelist) { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + s->session->tlsext_ellipticcurvelist_length = 0; + if ((curves = reallocarray(NULL, curveslen, + sizeof(uint16_t))) == NULL) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + for (i = 0; i < curveslen; i++) + n2s(sdata, curves[i]); + s->session->tlsext_ellipticcurvelist = curves; + s->session->tlsext_ellipticcurvelist_length = curveslen; + } + } + else if (type == TLSEXT_TYPE_session_ticket) { + if (s->tls_session_ticket_ext_cb && + !s->tls_session_ticket_ext_cb(s, data, size, s->tls_session_ticket_ext_cb_arg)) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + } else if (type == TLSEXT_TYPE_renegotiate) { + if (!ssl_parse_clienthello_renegotiate_ext(s, data, size, al)) + return 0; + renegotiate_seen = 1; + } else if (type == TLSEXT_TYPE_signature_algorithms) { + int dsize; + if (sigalg_seen || size < 2) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + sigalg_seen = 1; + n2s(data, dsize); + size -= 2; + if (dsize != size || dsize & 1) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + if (!tls1_process_sigalgs(s, data, dsize)) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + } else if (type == TLSEXT_TYPE_status_request && + s->version != DTLS1_VERSION) { + + if (size < 5) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + s->tlsext_status_type = *data++; + size--; + if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) { + const unsigned char *sdata; + int dsize; + /* Read in responder_id_list */ + n2s(data, dsize); + size -= 2; + if (dsize > size ) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + while (dsize > 0) { + OCSP_RESPID *id; + int idsize; + if (dsize < 4) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + n2s(data, idsize); + dsize -= 2 + idsize; + size -= 2 + idsize; + if (dsize < 0) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + sdata = data; + data += idsize; + id = d2i_OCSP_RESPID(NULL, + &sdata, idsize); + if (!id) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + if (data != sdata) { + OCSP_RESPID_free(id); + *al = SSL_AD_DECODE_ERROR; + return 0; + } + if (!s->tlsext_ocsp_ids && + !(s->tlsext_ocsp_ids = + sk_OCSP_RESPID_new_null())) { + OCSP_RESPID_free(id); + *al = SSL_AD_INTERNAL_ERROR; + return 0; + } + if (!sk_OCSP_RESPID_push( + s->tlsext_ocsp_ids, id)) { + OCSP_RESPID_free(id); + *al = SSL_AD_INTERNAL_ERROR; + return 0; + } + } + + /* Read in request_extensions */ + if (size < 2) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + n2s(data, dsize); + size -= 2; + if (dsize != size) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + sdata = data; + if (dsize > 0) { + if (s->tlsext_ocsp_exts) { + sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, + X509_EXTENSION_free); + } + + s->tlsext_ocsp_exts = + d2i_X509_EXTENSIONS(NULL, + &sdata, dsize); + if (!s->tlsext_ocsp_exts || + (data + dsize != sdata)) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + } + } else { + /* We don't know what to do with any other type + * so ignore it. + */ + s->tlsext_status_type = -1; + } + } + else if (type == TLSEXT_TYPE_next_proto_neg && + s->s3->tmp.finish_md_len == 0 && + s->s3->alpn_selected == NULL) { + /* We shouldn't accept this extension on a + * renegotiation. + * + * s->new_session will be set on renegotiation, but we + * probably shouldn't rely that it couldn't be set on + * the initial renegotation too in certain cases (when + * there's some other reason to disallow resuming an + * earlier session -- the current code won't be doing + * anything like that, but this might change). + + * A valid sign that there's been a previous handshake + * in this connection is if s->s3->tmp.finish_md_len > + * 0. (We are talking about a check that will happen + * in the Hello protocol round, well before a new + * Finished message could have been computed.) */ + s->s3->next_proto_neg_seen = 1; + } + else if (type == + TLSEXT_TYPE_application_layer_protocol_negotiation && + s->ctx->alpn_select_cb != NULL && + s->s3->tmp.finish_md_len == 0) { + if (tls1_alpn_handle_client_hello(s, data, + size, al) != 1) + return (0); + /* ALPN takes precedence over NPN. */ + s->s3->next_proto_neg_seen = 0; + } + + /* session ticket processed earlier */ +#ifndef OPENSSL_NO_SRTP + else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) { + if (ssl_parse_clienthello_use_srtp_ext(s, data, size, al)) + return 0; + } +#endif + + data += size; + } + + *p = data; + +ri_check: + + /* Need RI if renegotiating */ + + if (!renegotiate_seen && s->renegotiate) { + *al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, + SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); + return 0; + } + + return 1; +} + +/* + * ssl_next_proto_validate validates a Next Protocol Negotiation block. No + * elements of zero length are allowed and the set of elements must exactly fill + * the length of the block. + */ +static char +ssl_next_proto_validate(const unsigned char *d, unsigned int len) +{ + CBS npn, value; + + CBS_init(&npn, d, len); + while (CBS_len(&npn) > 0) { + if (!CBS_get_u8_length_prefixed(&npn, &value) || + CBS_len(&value) == 0) + return 0; + } + return 1; +} + +int +ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, + int n, int *al) +{ + unsigned short length; + unsigned short type; + unsigned short size; + unsigned char *data = *p; + int tlsext_servername = 0; + int renegotiate_seen = 0; + + s->s3->next_proto_neg_seen = 0; + free(s->s3->alpn_selected); + s->s3->alpn_selected = NULL; + + if (data >= (d + n - 2)) + goto ri_check; + + n2s(data, length); + if (data + length != d + n) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + while (data <= (d + n - 4)) { + n2s(data, type); + n2s(data, size); + + if (data + size > (d + n)) + goto ri_check; + + if (s->tlsext_debug_cb) + s->tlsext_debug_cb(s, 1, type, data, size, + s->tlsext_debug_arg); + + if (type == TLSEXT_TYPE_server_name) { + if (s->tlsext_hostname == NULL || size > 0) { + *al = TLS1_AD_UNRECOGNIZED_NAME; + return 0; + } + tlsext_servername = 1; + + } + else if (type == TLSEXT_TYPE_ec_point_formats && + s->version != DTLS1_VERSION) { + unsigned char *sdata = data; + size_t formatslen; + uint8_t *formats; + + if (size < 1) { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + formatslen = *(sdata++); + if (formatslen != size - 1) { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + + if (!s->hit) { + free(s->session->tlsext_ecpointformatlist); + s->session->tlsext_ecpointformatlist = NULL; + s->session->tlsext_ecpointformatlist_length = 0; + + if ((formats = reallocarray(NULL, formatslen, + sizeof(uint8_t))) == NULL) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + memcpy(formats, sdata, formatslen); + s->session->tlsext_ecpointformatlist = formats; + s->session->tlsext_ecpointformatlist_length = + formatslen; + } + } + else if (type == TLSEXT_TYPE_session_ticket) { + if (s->tls_session_ticket_ext_cb && + !s->tls_session_ticket_ext_cb(s, data, size, s->tls_session_ticket_ext_cb_arg)) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + if ((SSL_get_options(s) & SSL_OP_NO_TICKET) || (size > 0)) { + *al = TLS1_AD_UNSUPPORTED_EXTENSION; + return 0; + } + s->tlsext_ticket_expected = 1; + } + else if (type == TLSEXT_TYPE_status_request && + s->version != DTLS1_VERSION) { + /* MUST be empty and only sent if we've requested + * a status request message. + */ + if ((s->tlsext_status_type == -1) || (size > 0)) { + *al = TLS1_AD_UNSUPPORTED_EXTENSION; + return 0; + } + /* Set flag to expect CertificateStatus message */ + s->tlsext_status_expected = 1; + } + else if (type == TLSEXT_TYPE_next_proto_neg && + s->s3->tmp.finish_md_len == 0) { + unsigned char *selected; + unsigned char selected_len; + + /* We must have requested it. */ + if (s->ctx->next_proto_select_cb == NULL) { + *al = TLS1_AD_UNSUPPORTED_EXTENSION; + return 0; + } + /* The data must be valid */ + if (!ssl_next_proto_validate(data, size)) { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + if (s->ctx->next_proto_select_cb(s, &selected, &selected_len, data, size, s->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + s->next_proto_negotiated = malloc(selected_len); + if (!s->next_proto_negotiated) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + memcpy(s->next_proto_negotiated, selected, selected_len); + s->next_proto_negotiated_len = selected_len; + s->s3->next_proto_neg_seen = 1; + } + else if (type == + TLSEXT_TYPE_application_layer_protocol_negotiation) { + unsigned int len; + + /* We must have requested it. */ + if (s->alpn_client_proto_list == NULL) { + *al = TLS1_AD_UNSUPPORTED_EXTENSION; + return 0; + } + if (size < 4) { + *al = TLS1_AD_DECODE_ERROR; + return (0); + } + + /* The extension data consists of: + * uint16 list_length + * uint8 proto_length; + * uint8 proto[proto_length]; */ + len = ((unsigned int)data[0]) << 8 | + ((unsigned int)data[1]); + if (len != (unsigned int)size - 2) { + *al = TLS1_AD_DECODE_ERROR; + return (0); + } + len = data[2]; + if (len != (unsigned int)size - 3) { + *al = TLS1_AD_DECODE_ERROR; + return (0); + } + free(s->s3->alpn_selected); + s->s3->alpn_selected = malloc(len); + if (s->s3->alpn_selected == NULL) { + *al = TLS1_AD_INTERNAL_ERROR; + return (0); + } + memcpy(s->s3->alpn_selected, data + 3, len); + s->s3->alpn_selected_len = len; + + } else if (type == TLSEXT_TYPE_renegotiate) { + if (!ssl_parse_serverhello_renegotiate_ext(s, data, size, al)) + return 0; + renegotiate_seen = 1; + } +#ifndef OPENSSL_NO_SRTP + else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) { + if (ssl_parse_serverhello_use_srtp_ext(s, data, + size, al)) + return 0; + } +#endif + + data += size; + + } + + if (data != d + n) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + if (!s->hit && tlsext_servername == 1) { + if (s->tlsext_hostname) { + if (s->session->tlsext_hostname == NULL) { + s->session->tlsext_hostname = + strdup(s->tlsext_hostname); + + if (!s->session->tlsext_hostname) { + *al = SSL_AD_UNRECOGNIZED_NAME; + return 0; + } + } else { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + } + } + + *p = data; + +ri_check: + + /* Determine if we need to see RI. Strictly speaking if we want to + * avoid an attack we should *always* see RI even on initial server + * hello because the client doesn't see any renegotiation during an + * attack. However this would mean we could not connect to any server + * which doesn't support RI so for the immediate future tolerate RI + * absence on initial connect only. + */ + if (!renegotiate_seen && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT)) { + *al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, + SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); + return 0; + } + + return 1; +} + +int +ssl_check_clienthello_tlsext_early(SSL *s) +{ + int ret = SSL_TLSEXT_ERR_NOACK; + int al = SSL_AD_UNRECOGNIZED_NAME; + + /* The handling of the ECPointFormats extension is done elsewhere, namely in + * ssl3_choose_cipher in s3_lib.c. + */ + /* The handling of the EllipticCurves extension is done elsewhere, namely in + * ssl3_choose_cipher in s3_lib.c. + */ + + if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) + ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg); + else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) + ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg); + + switch (ret) { + case SSL_TLSEXT_ERR_ALERT_FATAL: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return -1; + case SSL_TLSEXT_ERR_ALERT_WARNING: + ssl3_send_alert(s, SSL3_AL_WARNING, al); + return 1; + case SSL_TLSEXT_ERR_NOACK: + s->servername_done = 0; + default: + return 1; + } +} + +int +ssl_check_clienthello_tlsext_late(SSL *s) +{ + int ret = SSL_TLSEXT_ERR_OK; + int al = 0; /* XXX gcc3 */ + + /* If status request then ask callback what to do. + * Note: this must be called after servername callbacks in case + * the certificate has changed, and must be called after the cipher + * has been chosen because this may influence which certificate is sent + */ + if ((s->tlsext_status_type != -1) && + s->ctx && s->ctx->tlsext_status_cb) { + int r; + CERT_PKEY *certpkey; + certpkey = ssl_get_server_send_pkey(s); + /* If no certificate can't return certificate status */ + if (certpkey == NULL) { + s->tlsext_status_expected = 0; + return 1; + } + /* Set current certificate to one we will use so + * SSL_get_certificate et al can pick it up. + */ + s->cert->key = certpkey; + r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); + switch (r) { + /* We don't want to send a status request response */ + case SSL_TLSEXT_ERR_NOACK: + s->tlsext_status_expected = 0; + break; + /* status request response should be sent */ + case SSL_TLSEXT_ERR_OK: + if (s->tlsext_ocsp_resp) + s->tlsext_status_expected = 1; + else + s->tlsext_status_expected = 0; + break; + /* something bad happened */ + case SSL_TLSEXT_ERR_ALERT_FATAL: + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + al = SSL_AD_INTERNAL_ERROR; + goto err; + } + } else + s->tlsext_status_expected = 0; + +err: + switch (ret) { + case SSL_TLSEXT_ERR_ALERT_FATAL: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return -1; + case SSL_TLSEXT_ERR_ALERT_WARNING: + ssl3_send_alert(s, SSL3_AL_WARNING, al); + return 1; + default: + return 1; + } +} + +int +ssl_check_serverhello_tlsext(SSL *s) +{ + int ret = SSL_TLSEXT_ERR_NOACK; + int al = SSL_AD_UNRECOGNIZED_NAME; + + /* If we are client and using an elliptic curve cryptography cipher + * suite, then if server returns an EC point formats lists extension + * it must contain uncompressed. + */ + unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth; + if ((s->tlsext_ecpointformatlist != NULL) && + (s->tlsext_ecpointformatlist_length > 0) && + (s->session->tlsext_ecpointformatlist != NULL) && + (s->session->tlsext_ecpointformatlist_length > 0) && + ((alg_k & (SSL_kECDHE|SSL_kECDHr|SSL_kECDHe)) || (alg_a & SSL_aECDSA))) { + /* we are using an ECC cipher */ + size_t i; + unsigned char *list; + int found_uncompressed = 0; + list = s->session->tlsext_ecpointformatlist; + for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) { + if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed) { + found_uncompressed = 1; + break; + } + } + if (!found_uncompressed) { + SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT, SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST); + return -1; + } + } + ret = SSL_TLSEXT_ERR_OK; + + if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) + ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg); + else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) + ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg); + + /* If we've requested certificate status and we wont get one + * tell the callback + */ + if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected) && + s->ctx && s->ctx->tlsext_status_cb) { + int r; + /* Set resp to NULL, resplen to -1 so callback knows + * there is no response. + */ + free(s->tlsext_ocsp_resp); + s->tlsext_ocsp_resp = NULL; + s->tlsext_ocsp_resplen = -1; + r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); + if (r == 0) { + al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE; + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + } + if (r < 0) { + al = SSL_AD_INTERNAL_ERROR; + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + } + } + + switch (ret) { + case SSL_TLSEXT_ERR_ALERT_FATAL: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + + return -1; + case SSL_TLSEXT_ERR_ALERT_WARNING: + ssl3_send_alert(s, SSL3_AL_WARNING, al); + + return 1; + case SSL_TLSEXT_ERR_NOACK: + s->servername_done = 0; + default: + return 1; + } +} + +/* Since the server cache lookup is done early on in the processing of the + * ClientHello, and other operations depend on the result, we need to handle + * any TLS session ticket extension at the same time. + * + * session_id: points at the session ID in the ClientHello. This code will + * read past the end of this in order to parse out the session ticket + * extension, if any. + * len: the length of the session ID. + * limit: a pointer to the first byte after the ClientHello. + * ret: (output) on return, if a ticket was decrypted, then this is set to + * point to the resulting session. + * + * If s->tls_session_secret_cb is set then we are expecting a pre-shared key + * ciphersuite, in which case we have no use for session tickets and one will + * never be decrypted, nor will s->tlsext_ticket_expected be set to 1. + * + * Returns: + * -1: fatal error, either from parsing or decrypting the ticket. + * 0: no ticket was found (or was ignored, based on settings). + * 1: a zero length extension was found, indicating that the client supports + * session tickets but doesn't currently have one to offer. + * 2: either s->tls_session_secret_cb was set, or a ticket was offered but + * couldn't be decrypted because of a non-fatal error. + * 3: a ticket was successfully decrypted and *ret was set. + * + * Side effects: + * Sets s->tlsext_ticket_expected to 1 if the server will have to issue + * a new session ticket to the client because the client indicated support + * (and s->tls_session_secret_cb is NULL) but the client either doesn't have + * a session ticket or we couldn't use the one it gave us, or if + * s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket. + * Otherwise, s->tlsext_ticket_expected is set to 0. + */ +int +tls1_process_ticket(SSL *s, const unsigned char *session, int session_len, + const unsigned char *limit, SSL_SESSION **ret) +{ + /* Point after session ID in client hello */ + CBS session_id, cookie, cipher_list, compress_algo, extensions; + + *ret = NULL; + s->tlsext_ticket_expected = 0; + + /* If tickets disabled behave as if no ticket present + * to permit stateful resumption. + */ + if (SSL_get_options(s) & SSL_OP_NO_TICKET) + return 0; + if (!limit) + return 0; + + if (limit < session) + return -1; + + CBS_init(&session_id, session, limit - session); + + /* Skip past the session id */ + if (!CBS_skip(&session_id, session_len)) + return -1; + + /* Skip past DTLS cookie */ + if (SSL_IS_DTLS(s)) { + if (!CBS_get_u8_length_prefixed(&session_id, &cookie)) + return -1; + } + + /* Skip past cipher list */ + if (!CBS_get_u16_length_prefixed(&session_id, &cipher_list)) + return -1; + + /* Skip past compression algorithm list */ + if (!CBS_get_u8_length_prefixed(&session_id, &compress_algo)) + return -1; + + /* Now at start of extensions */ + if (CBS_len(&session_id) == 0) + return 0; + if (!CBS_get_u16_length_prefixed(&session_id, &extensions)) + return -1; + + while (CBS_len(&extensions) > 0) { + CBS ext_data; + uint16_t ext_type; + + if (!CBS_get_u16(&extensions, &ext_type) || + !CBS_get_u16_length_prefixed(&extensions, &ext_data)) + return -1; + + if (ext_type == TLSEXT_TYPE_session_ticket) { + int r; + if (CBS_len(&ext_data) == 0) { + /* The client will accept a ticket but doesn't + * currently have one. */ + s->tlsext_ticket_expected = 1; + return 1; + } + if (s->tls_session_secret_cb) { + /* Indicate that the ticket couldn't be + * decrypted rather than generating the session + * from ticket now, trigger abbreviated + * handshake based on external mechanism to + * calculate the master secret later. */ + return 2; + } + + r = tls_decrypt_ticket(s, CBS_data(&ext_data), + CBS_len(&ext_data), session, session_len, ret); + + switch (r) { + case 2: /* ticket couldn't be decrypted */ + s->tlsext_ticket_expected = 1; + return 2; + case 3: /* ticket was decrypted */ + return r; + case 4: /* ticket decrypted but need to renew */ + s->tlsext_ticket_expected = 1; + return 3; + default: /* fatal error */ + return -1; + } + } + } + return 0; +} + +/* tls_decrypt_ticket attempts to decrypt a session ticket. + * + * etick: points to the body of the session ticket extension. + * eticklen: the length of the session tickets extenion. + * sess_id: points at the session ID. + * sesslen: the length of the session ID. + * psess: (output) on return, if a ticket was decrypted, then this is set to + * point to the resulting session. + * + * Returns: + * -1: fatal error, either from parsing or decrypting the ticket. + * 2: the ticket couldn't be decrypted. + * 3: a ticket was successfully decrypted and *psess was set. + * 4: same as 3, but the ticket needs to be renewed. + */ +static int +tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen, + const unsigned char *sess_id, int sesslen, SSL_SESSION **psess) +{ + SSL_SESSION *sess; + unsigned char *sdec; + const unsigned char *p; + int slen, mlen, renew_ticket = 0; + unsigned char tick_hmac[EVP_MAX_MD_SIZE]; + HMAC_CTX hctx; + EVP_CIPHER_CTX ctx; + SSL_CTX *tctx = s->initial_ctx; + /* Need at least keyname + iv + some encrypted data */ + if (eticklen < 48) + return 2; + /* Initialize session ticket encryption and HMAC contexts */ + HMAC_CTX_init(&hctx); + EVP_CIPHER_CTX_init(&ctx); + if (tctx->tlsext_ticket_key_cb) { + unsigned char *nctick = (unsigned char *)etick; + int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16, + &ctx, &hctx, 0); + if (rv < 0) { + EVP_CIPHER_CTX_cleanup(&ctx); + return -1; + } + if (rv == 0) { + EVP_CIPHER_CTX_cleanup(&ctx); + return 2; + } + if (rv == 2) + renew_ticket = 1; + } else { + /* Check key name matches */ + if (timingsafe_memcmp(etick, tctx->tlsext_tick_key_name, 16)) + return 2; + HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, + tlsext_tick_md(), NULL); + EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, + tctx->tlsext_tick_aes_key, etick + 16); + } + /* Attempt to process session ticket, first conduct sanity and + * integrity checks on ticket. + */ + mlen = HMAC_size(&hctx); + if (mlen < 0) { + EVP_CIPHER_CTX_cleanup(&ctx); + return -1; + } + eticklen -= mlen; + /* Check HMAC of encrypted ticket */ + HMAC_Update(&hctx, etick, eticklen); + HMAC_Final(&hctx, tick_hmac, NULL); + HMAC_CTX_cleanup(&hctx); + if (timingsafe_memcmp(tick_hmac, etick + eticklen, mlen)) { + EVP_CIPHER_CTX_cleanup(&ctx); + return 2; + } + /* Attempt to decrypt session data */ + /* Move p after IV to start of encrypted ticket, update length */ + p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx); + eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx); + sdec = malloc(eticklen); + if (!sdec) { + EVP_CIPHER_CTX_cleanup(&ctx); + return -1; + } + EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen); + if (EVP_DecryptFinal_ex(&ctx, sdec + slen, &mlen) <= 0) { + free(sdec); + EVP_CIPHER_CTX_cleanup(&ctx); + return 2; + } + slen += mlen; + EVP_CIPHER_CTX_cleanup(&ctx); + p = sdec; + + sess = d2i_SSL_SESSION(NULL, &p, slen); + free(sdec); + if (sess) { + /* The session ID, if non-empty, is used by some clients to + * detect that the ticket has been accepted. So we copy it to + * the session structure. If it is empty set length to zero + * as required by standard. + */ + if (sesslen) + memcpy(sess->session_id, sess_id, sesslen); + sess->session_id_length = sesslen; + *psess = sess; + if (renew_ticket) + return 4; + else + return 3; + } + ERR_clear_error(); + /* For session parse failure, indicate that we need to send a new + * ticket. */ + return 2; +} + +/* Tables to translate from NIDs to TLS v1.2 ids */ + +typedef struct { + int nid; + int id; +} tls12_lookup; + +static tls12_lookup tls12_md[] = { + {NID_md5, TLSEXT_hash_md5}, + {NID_sha1, TLSEXT_hash_sha1}, + {NID_sha224, TLSEXT_hash_sha224}, + {NID_sha256, TLSEXT_hash_sha256}, + {NID_sha384, TLSEXT_hash_sha384}, + {NID_sha512, TLSEXT_hash_sha512}, + {NID_id_GostR3411_94, TLSEXT_hash_gost94}, + {NID_id_tc26_gost3411_2012_256, TLSEXT_hash_streebog_256}, + {NID_id_tc26_gost3411_2012_512, TLSEXT_hash_streebog_512} +}; + +static tls12_lookup tls12_sig[] = { + {EVP_PKEY_RSA, TLSEXT_signature_rsa}, + {EVP_PKEY_DSA, TLSEXT_signature_dsa}, + {EVP_PKEY_EC, TLSEXT_signature_ecdsa}, + {EVP_PKEY_GOSTR01, TLSEXT_signature_gostr01}, +}; + +static int +tls12_find_id(int nid, tls12_lookup *table, size_t tlen) +{ + size_t i; + for (i = 0; i < tlen; i++) { + if (table[i].nid == nid) + return table[i].id; + } + return -1; +} + +int +tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, const EVP_MD *md) +{ + int sig_id, md_id; + if (!md) + return 0; + md_id = tls12_find_id(EVP_MD_type(md), tls12_md, + sizeof(tls12_md) / sizeof(tls12_lookup)); + if (md_id == -1) + return 0; + sig_id = tls12_get_sigid(pk); + if (sig_id == -1) + return 0; + p[0] = (unsigned char)md_id; + p[1] = (unsigned char)sig_id; + return 1; +} + +int +tls12_get_sigid(const EVP_PKEY *pk) +{ + return tls12_find_id(pk->type, tls12_sig, + sizeof(tls12_sig) / sizeof(tls12_lookup)); +} + +const EVP_MD * +tls12_get_hash(unsigned char hash_alg) +{ + switch (hash_alg) { + case TLSEXT_hash_sha1: + return EVP_sha1(); + case TLSEXT_hash_sha224: + return EVP_sha224(); + case TLSEXT_hash_sha256: + return EVP_sha256(); + case TLSEXT_hash_sha384: + return EVP_sha384(); + case TLSEXT_hash_sha512: + return EVP_sha512(); +#ifndef OPENSSL_NO_GOST + case TLSEXT_hash_gost94: + return EVP_gostr341194(); + case TLSEXT_hash_streebog_256: + return EVP_streebog256(); + case TLSEXT_hash_streebog_512: + return EVP_streebog512(); +#endif + default: + return NULL; + } +} + +/* Set preferred digest for each key type */ + +int +tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize) +{ + int idx; + const EVP_MD *md; + CERT *c = s->cert; + CBS cbs; + + /* Extension ignored for inappropriate versions */ + if (!SSL_USE_SIGALGS(s)) + return 1; + + /* Should never happen */ + if (!c || dsize < 0) + return 0; + + CBS_init(&cbs, data, dsize); + + c->pkeys[SSL_PKEY_DSA_SIGN].digest = NULL; + c->pkeys[SSL_PKEY_RSA_SIGN].digest = NULL; + c->pkeys[SSL_PKEY_RSA_ENC].digest = NULL; + c->pkeys[SSL_PKEY_ECC].digest = NULL; + c->pkeys[SSL_PKEY_GOST01].digest = NULL; + + while (CBS_len(&cbs) > 0) { + uint8_t hash_alg, sig_alg; + + if (!CBS_get_u8(&cbs, &hash_alg) || + !CBS_get_u8(&cbs, &sig_alg)) { + /* Should never happen */ + return 0; + } + + switch (sig_alg) { + case TLSEXT_signature_rsa: + idx = SSL_PKEY_RSA_SIGN; + break; + case TLSEXT_signature_dsa: + idx = SSL_PKEY_DSA_SIGN; + break; + case TLSEXT_signature_ecdsa: + idx = SSL_PKEY_ECC; + break; + case TLSEXT_signature_gostr01: + case TLSEXT_signature_gostr12_256: + case TLSEXT_signature_gostr12_512: + idx = SSL_PKEY_GOST01; + break; + default: + continue; + } + + if (c->pkeys[idx].digest == NULL) { + md = tls12_get_hash(hash_alg); + if (md) { + c->pkeys[idx].digest = md; + if (idx == SSL_PKEY_RSA_SIGN) + c->pkeys[SSL_PKEY_RSA_ENC].digest = md; + } + } + + } + + /* Set any remaining keys to default values. NOTE: if alg is not + * supported it stays as NULL. + */ + if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest) + c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); + if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest) { + c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); + c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); + } + if (!c->pkeys[SSL_PKEY_ECC].digest) + c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); +#ifndef OPENSSL_NO_GOST + if (!c->pkeys[SSL_PKEY_GOST01].digest) + c->pkeys[SSL_PKEY_GOST01].digest = EVP_gostr341194(); +#endif + return 1; +} diff --git a/crypto/libressl/ssl/t1_meth.c b/crypto/libressl/ssl/t1_meth.c new file mode 100644 index 0000000000..6949e18cab --- /dev/null +++ b/crypto/libressl/ssl/t1_meth.c @@ -0,0 +1,235 @@ +/* $OpenBSD: t1_meth.c,v 1.16 2015/02/06 08:30:23 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include + +#include "ssl_locl.h" + +static const SSL_METHOD *tls1_get_method(int ver); + +const SSL_METHOD TLS_method_data = { + .version = TLS1_2_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = ssl23_accept, + .ssl_connect = ssl23_connect, + .ssl_read = ssl23_read, + .ssl_peek = ssl23_peek, + .ssl_write = ssl23_write, + .ssl_shutdown = ssl_undefined_function, + .ssl_renegotiate = ssl_undefined_function, + .ssl_renegotiate_check = ssl_ok, + .ssl_get_message = ssl3_get_message, + .ssl_read_bytes = ssl3_read_bytes, + .ssl_write_bytes = ssl3_write_bytes, + .ssl_dispatch_alert = ssl3_dispatch_alert, + .ssl_ctrl = ssl3_ctrl, + .ssl_ctx_ctrl = ssl3_ctx_ctrl, + .get_cipher_by_char = ssl3_get_cipher_by_char, + .put_cipher_by_char = ssl3_put_cipher_by_char, + .ssl_pending = ssl_undefined_const_function, + .num_ciphers = ssl3_num_ciphers, + .get_cipher = ssl3_get_cipher, + .get_ssl_method = tls1_get_method, + .get_timeout = ssl23_default_timeout, + .ssl3_enc = &ssl3_undef_enc_method, + .ssl_version = ssl_undefined_void_function, + .ssl_callback_ctrl = ssl3_callback_ctrl, + .ssl_ctx_callback_ctrl = ssl3_ctx_callback_ctrl, +}; + +const SSL_METHOD TLSv1_method_data = { + .version = TLS1_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = ssl3_accept, + .ssl_connect = ssl3_connect, + .ssl_read = ssl3_read, + .ssl_peek = ssl3_peek, + .ssl_write = ssl3_write, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_get_message = ssl3_get_message, + .ssl_read_bytes = ssl3_read_bytes, + .ssl_write_bytes = ssl3_write_bytes, + .ssl_dispatch_alert = ssl3_dispatch_alert, + .ssl_ctrl = ssl3_ctrl, + .ssl_ctx_ctrl = ssl3_ctx_ctrl, + .get_cipher_by_char = ssl3_get_cipher_by_char, + .put_cipher_by_char = ssl3_put_cipher_by_char, + .ssl_pending = ssl3_pending, + .num_ciphers = ssl3_num_ciphers, + .get_cipher = ssl3_get_cipher, + .get_ssl_method = tls1_get_method, + .get_timeout = tls1_default_timeout, + .ssl3_enc = &TLSv1_enc_data, + .ssl_version = ssl_undefined_void_function, + .ssl_callback_ctrl = ssl3_callback_ctrl, + .ssl_ctx_callback_ctrl = ssl3_ctx_callback_ctrl, +}; + +const SSL_METHOD TLSv1_1_method_data = { + .version = TLS1_1_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = ssl3_accept, + .ssl_connect = ssl3_connect, + .ssl_read = ssl3_read, + .ssl_peek = ssl3_peek, + .ssl_write = ssl3_write, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_get_message = ssl3_get_message, + .ssl_read_bytes = ssl3_read_bytes, + .ssl_write_bytes = ssl3_write_bytes, + .ssl_dispatch_alert = ssl3_dispatch_alert, + .ssl_ctrl = ssl3_ctrl, + .ssl_ctx_ctrl = ssl3_ctx_ctrl, + .get_cipher_by_char = ssl3_get_cipher_by_char, + .put_cipher_by_char = ssl3_put_cipher_by_char, + .ssl_pending = ssl3_pending, + .num_ciphers = ssl3_num_ciphers, + .get_cipher = ssl3_get_cipher, + .get_ssl_method = tls1_get_method, + .get_timeout = tls1_default_timeout, + .ssl3_enc = &TLSv1_1_enc_data, + .ssl_version = ssl_undefined_void_function, + .ssl_callback_ctrl = ssl3_callback_ctrl, + .ssl_ctx_callback_ctrl = ssl3_ctx_callback_ctrl, +}; + +const SSL_METHOD TLSv1_2_method_data = { + .version = TLS1_2_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = ssl3_accept, + .ssl_connect = ssl3_connect, + .ssl_read = ssl3_read, + .ssl_peek = ssl3_peek, + .ssl_write = ssl3_write, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_get_message = ssl3_get_message, + .ssl_read_bytes = ssl3_read_bytes, + .ssl_write_bytes = ssl3_write_bytes, + .ssl_dispatch_alert = ssl3_dispatch_alert, + .ssl_ctrl = ssl3_ctrl, + .ssl_ctx_ctrl = ssl3_ctx_ctrl, + .get_cipher_by_char = ssl3_get_cipher_by_char, + .put_cipher_by_char = ssl3_put_cipher_by_char, + .ssl_pending = ssl3_pending, + .num_ciphers = ssl3_num_ciphers, + .get_cipher = ssl3_get_cipher, + .get_ssl_method = tls1_get_method, + .get_timeout = tls1_default_timeout, + .ssl3_enc = &TLSv1_2_enc_data, + .ssl_version = ssl_undefined_void_function, + .ssl_callback_ctrl = ssl3_callback_ctrl, + .ssl_ctx_callback_ctrl = ssl3_ctx_callback_ctrl, +}; + +static const SSL_METHOD * +tls1_get_method(int ver) +{ + if (ver == TLS1_2_VERSION) + return (TLSv1_2_method()); + if (ver == TLS1_1_VERSION) + return (TLSv1_1_method()); + if (ver == TLS1_VERSION) + return (TLSv1_method()); + return (NULL); +} + +const SSL_METHOD * +SSLv23_method(void) +{ + return (TLS_method()); +} + +const SSL_METHOD * +TLS_method(void) +{ + return &TLS_method_data; +} + +const SSL_METHOD * +TLSv1_method(void) +{ + return (&TLSv1_method_data); +} + +const SSL_METHOD * +TLSv1_1_method(void) +{ + return (&TLSv1_1_method_data); +} + +const SSL_METHOD * +TLSv1_2_method(void) +{ + return (&TLSv1_2_method_data); +} diff --git a/crypto/libressl/ssl/t1_reneg.c b/crypto/libressl/ssl/t1_reneg.c new file mode 100644 index 0000000000..a8a6d757fb --- /dev/null +++ b/crypto/libressl/ssl/t1_reneg.c @@ -0,0 +1,286 @@ +/* $OpenBSD: t1_reneg.c,v 1.10 2015/06/20 04:04:36 doug Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2009 The OpenSSL Project. 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include + +#include "ssl_locl.h" +#include "bytestring.h" + +/* Add the client's renegotiation binding */ +int +ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len, + int maxlen) +{ + if (p) { + if ((s->s3->previous_client_finished_len + 1) > maxlen) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATE_EXT_TOO_LONG); + return 0; + } + + /* Length byte */ + *p = s->s3->previous_client_finished_len; + p++; + + memcpy(p, s->s3->previous_client_finished, + s->s3->previous_client_finished_len); + + } + + *len = s->s3->previous_client_finished_len + 1; + + return 1; +} + +/* Parse the client's renegotiation binding and abort if it's not + right */ +int +ssl_parse_clienthello_renegotiate_ext(SSL *s, const unsigned char *d, int len, + int *al) +{ + CBS cbs, reneg; + + if (len < 0) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_ENCODING_ERR); + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + CBS_init(&cbs, d, len); + if (!CBS_get_u8_length_prefixed(&cbs, &reneg) || + /* Consistency check */ + CBS_len(&cbs) != 0) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_ENCODING_ERR); + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + /* Check that the extension matches */ + if (CBS_len(&reneg) != s->s3->previous_client_finished_len) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_MISMATCH); + *al = SSL_AD_HANDSHAKE_FAILURE; + return 0; + } + + if (!CBS_mem_equal(&reneg, s->s3->previous_client_finished, + s->s3->previous_client_finished_len)) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_MISMATCH); + *al = SSL_AD_HANDSHAKE_FAILURE; + return 0; + } + + s->s3->send_connection_binding = 1; + + return 1; +} + +/* Add the server's renegotiation binding */ +int +ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len, + int maxlen) +{ + if (p) { + if ((s->s3->previous_client_finished_len + + s->s3->previous_server_finished_len + 1) > maxlen) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATE_EXT_TOO_LONG); + return 0; + } + + /* Length byte */ + *p = s->s3->previous_client_finished_len + + s->s3->previous_server_finished_len; + p++; + + memcpy(p, s->s3->previous_client_finished, + s->s3->previous_client_finished_len); + p += s->s3->previous_client_finished_len; + + memcpy(p, s->s3->previous_server_finished, + s->s3->previous_server_finished_len); + + } + + *len = s->s3->previous_client_finished_len + + s->s3->previous_server_finished_len + 1; + + return 1; +} + +/* Parse the server's renegotiation binding and abort if it's not + right */ +int +ssl_parse_serverhello_renegotiate_ext(SSL *s, const unsigned char *d, int len, int *al) +{ + CBS cbs, reneg, previous_client, previous_server; + int expected_len = s->s3->previous_client_finished_len + + s->s3->previous_server_finished_len; + + /* Check for logic errors */ + OPENSSL_assert(!expected_len || s->s3->previous_client_finished_len); + OPENSSL_assert(!expected_len || s->s3->previous_server_finished_len); + + if (len < 0) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_ENCODING_ERR); + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + CBS_init(&cbs, d, len); + + if (!CBS_get_u8_length_prefixed(&cbs, &reneg) || + /* Consistency check */ + CBS_len(&cbs) != 0) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_ENCODING_ERR); + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + /* Check that the extension matches */ + if (CBS_len(&reneg) != expected_len || + !CBS_get_bytes(&reneg, &previous_client, + s->s3->previous_client_finished_len) || + !CBS_get_bytes(&reneg, &previous_server, + s->s3->previous_server_finished_len) || + CBS_len(&reneg) != 0) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_MISMATCH); + *al = SSL_AD_HANDSHAKE_FAILURE; + return 0; + } + + if (!CBS_mem_equal(&previous_client, s->s3->previous_client_finished, + CBS_len(&previous_client))) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_MISMATCH); + *al = SSL_AD_HANDSHAKE_FAILURE; + return 0; + } + if (!CBS_mem_equal(&previous_server, s->s3->previous_server_finished, + CBS_len(&previous_server))) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_MISMATCH); + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + s->s3->send_connection_binding = 1; + + return 1; +} diff --git a/crypto/libressl/ssl/t1_srvr.c b/crypto/libressl/ssl/t1_srvr.c new file mode 100644 index 0000000000..90c9ba2b49 --- /dev/null +++ b/crypto/libressl/ssl/t1_srvr.c @@ -0,0 +1,238 @@ +/* $OpenBSD: t1_srvr.c,v 1.18 2015/02/06 08:30:23 jsing Exp $ */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#include "ssl_locl.h" + +#include +#include +#include +#include + +static const SSL_METHOD *tls1_get_server_method(int ver); + +const SSL_METHOD TLS_server_method_data = { + .version = TLS1_2_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = ssl23_accept, + .ssl_connect = ssl_undefined_function, + .ssl_read = ssl23_read, + .ssl_peek = ssl23_peek, + .ssl_write = ssl23_write, + .ssl_shutdown = ssl_undefined_function, + .ssl_renegotiate = ssl_undefined_function, + .ssl_renegotiate_check = ssl_ok, + .ssl_get_message = ssl3_get_message, + .ssl_read_bytes = ssl3_read_bytes, + .ssl_write_bytes = ssl3_write_bytes, + .ssl_dispatch_alert = ssl3_dispatch_alert, + .ssl_ctrl = ssl3_ctrl, + .ssl_ctx_ctrl = ssl3_ctx_ctrl, + .get_cipher_by_char = ssl3_get_cipher_by_char, + .put_cipher_by_char = ssl3_put_cipher_by_char, + .ssl_pending = ssl_undefined_const_function, + .num_ciphers = ssl3_num_ciphers, + .get_cipher = ssl3_get_cipher, + .get_ssl_method = tls1_get_server_method, + .get_timeout = ssl23_default_timeout, + .ssl3_enc = &ssl3_undef_enc_method, + .ssl_version = ssl_undefined_void_function, + .ssl_callback_ctrl = ssl3_callback_ctrl, + .ssl_ctx_callback_ctrl = ssl3_ctx_callback_ctrl, +}; + +const SSL_METHOD TLSv1_server_method_data = { + .version = TLS1_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = ssl3_accept, + .ssl_connect = ssl_undefined_function, + .ssl_read = ssl3_read, + .ssl_peek = ssl3_peek, + .ssl_write = ssl3_write, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_get_message = ssl3_get_message, + .ssl_read_bytes = ssl3_read_bytes, + .ssl_write_bytes = ssl3_write_bytes, + .ssl_dispatch_alert = ssl3_dispatch_alert, + .ssl_ctrl = ssl3_ctrl, + .ssl_ctx_ctrl = ssl3_ctx_ctrl, + .get_cipher_by_char = ssl3_get_cipher_by_char, + .put_cipher_by_char = ssl3_put_cipher_by_char, + .ssl_pending = ssl3_pending, + .num_ciphers = ssl3_num_ciphers, + .get_cipher = ssl3_get_cipher, + .get_ssl_method = tls1_get_server_method, + .get_timeout = tls1_default_timeout, + .ssl3_enc = &TLSv1_enc_data, + .ssl_version = ssl_undefined_void_function, + .ssl_callback_ctrl = ssl3_callback_ctrl, + .ssl_ctx_callback_ctrl = ssl3_ctx_callback_ctrl, +}; + +const SSL_METHOD TLSv1_1_server_method_data = { + .version = TLS1_1_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = ssl3_accept, + .ssl_connect = ssl_undefined_function, + .ssl_read = ssl3_read, + .ssl_peek = ssl3_peek, + .ssl_write = ssl3_write, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_get_message = ssl3_get_message, + .ssl_read_bytes = ssl3_read_bytes, + .ssl_write_bytes = ssl3_write_bytes, + .ssl_dispatch_alert = ssl3_dispatch_alert, + .ssl_ctrl = ssl3_ctrl, + .ssl_ctx_ctrl = ssl3_ctx_ctrl, + .get_cipher_by_char = ssl3_get_cipher_by_char, + .put_cipher_by_char = ssl3_put_cipher_by_char, + .ssl_pending = ssl3_pending, + .num_ciphers = ssl3_num_ciphers, + .get_cipher = ssl3_get_cipher, + .get_ssl_method = tls1_get_server_method, + .get_timeout = tls1_default_timeout, + .ssl3_enc = &TLSv1_1_enc_data, + .ssl_version = ssl_undefined_void_function, + .ssl_callback_ctrl = ssl3_callback_ctrl, + .ssl_ctx_callback_ctrl = ssl3_ctx_callback_ctrl, +}; + +const SSL_METHOD TLSv1_2_server_method_data = { + .version = TLS1_2_VERSION, + .ssl_new = tls1_new, + .ssl_clear = tls1_clear, + .ssl_free = tls1_free, + .ssl_accept = ssl3_accept, + .ssl_connect = ssl_undefined_function, + .ssl_read = ssl3_read, + .ssl_peek = ssl3_peek, + .ssl_write = ssl3_write, + .ssl_shutdown = ssl3_shutdown, + .ssl_renegotiate = ssl3_renegotiate, + .ssl_renegotiate_check = ssl3_renegotiate_check, + .ssl_get_message = ssl3_get_message, + .ssl_read_bytes = ssl3_read_bytes, + .ssl_write_bytes = ssl3_write_bytes, + .ssl_dispatch_alert = ssl3_dispatch_alert, + .ssl_ctrl = ssl3_ctrl, + .ssl_ctx_ctrl = ssl3_ctx_ctrl, + .get_cipher_by_char = ssl3_get_cipher_by_char, + .put_cipher_by_char = ssl3_put_cipher_by_char, + .ssl_pending = ssl3_pending, + .num_ciphers = ssl3_num_ciphers, + .get_cipher = ssl3_get_cipher, + .get_ssl_method = tls1_get_server_method, + .get_timeout = tls1_default_timeout, + .ssl3_enc = &TLSv1_2_enc_data, + .ssl_version = ssl_undefined_void_function, + .ssl_callback_ctrl = ssl3_callback_ctrl, + .ssl_ctx_callback_ctrl = ssl3_ctx_callback_ctrl, +}; + +static const SSL_METHOD * +tls1_get_server_method(int ver) +{ + if (ver == TLS1_2_VERSION) + return (TLSv1_2_server_method()); + if (ver == TLS1_1_VERSION) + return (TLSv1_1_server_method()); + if (ver == TLS1_VERSION) + return (TLSv1_server_method()); + return (NULL); +} + +const SSL_METHOD * +SSLv23_server_method(void) +{ + return (TLS_server_method()); +} + +const SSL_METHOD * +TLS_server_method(void) +{ + return (&TLS_server_method_data); +} + +const SSL_METHOD * +TLSv1_server_method(void) +{ + return (&TLSv1_server_method_data); +} + +const SSL_METHOD * +TLSv1_1_server_method(void) +{ + return (&TLSv1_1_server_method_data); +} + +const SSL_METHOD * +TLSv1_2_server_method(void) +{ + return (&TLSv1_2_server_method_data); +} diff --git a/crypto/libressl/tls/VERSION b/crypto/libressl/tls/VERSION new file mode 100644 index 0000000000..de03debdb2 --- /dev/null +++ b/crypto/libressl/tls/VERSION @@ -0,0 +1 @@ +11:0:0 diff --git a/crypto/libressl/tls/strsep.c b/crypto/libressl/tls/strsep.c new file mode 100644 index 0000000000..2ffc4b4c46 --- /dev/null +++ b/crypto/libressl/tls/strsep.c @@ -0,0 +1,70 @@ +/* $OpenBSD: strsep.c,v 1.7 2014/02/05 20:42:32 stsp Exp $ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +/* + * Get next token from string *stringp, where tokens are possibly-empty + * strings separated by characters from delim. + * + * Writes NULs into the string at *stringp to end tokens. + * delim need not remain constant from call to call. + * On return, *stringp points past the last NUL written (if there might + * be further tokens), or is NULL (if there are definitely no more tokens). + * + * If *stringp is NULL, strsep returns NULL. + */ +char * +strsep(char **stringp, const char *delim) +{ + char *s; + const char *spanp; + int c, sc; + char *tok; + + if ((s = *stringp) == NULL) + return (NULL); + for (tok = s;;) { + c = *s++; + spanp = delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *stringp = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} diff --git a/crypto/libressl/tls/tls.c b/crypto/libressl/tls/tls.c new file mode 100644 index 0000000000..fbe7b5d4d3 --- /dev/null +++ b/crypto/libressl/tls/tls.c @@ -0,0 +1,585 @@ +/* $OpenBSD: tls.c,v 1.40 2016/07/06 16:16:36 jsing Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * 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 + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include "tls_internal.h" + +static struct tls_config *tls_config_default; + +int +tls_init(void) +{ + static int tls_initialised = 0; + + if (tls_initialised) + return (0); + + SSL_load_error_strings(); + SSL_library_init(); + + if (BIO_sock_init() != 1) + return (-1); + + if ((tls_config_default = tls_config_new()) == NULL) + return (-1); + + tls_initialised = 1; + + return (0); +} + +const char * +tls_error(struct tls *ctx) +{ + return ctx->error.msg; +} + +static int +tls_error_vset(struct tls_error *error, int errnum, const char *fmt, va_list ap) +{ + char *errmsg = NULL; + int rv = -1; + + free(error->msg); + error->msg = NULL; + error->num = errnum; + + if (vasprintf(&errmsg, fmt, ap) == -1) { + errmsg = NULL; + goto err; + } + + if (errnum == -1) { + error->msg = errmsg; + return (0); + } + + if (asprintf(&error->msg, "%s: %s", errmsg, strerror(errnum)) == -1) { + error->msg = NULL; + goto err; + } + rv = 0; + + err: + free(errmsg); + + return (rv); +} + +int +tls_error_set(struct tls_error *error, const char *fmt, ...) +{ + va_list ap; + int errnum, rv; + + errnum = errno; + + va_start(ap, fmt); + rv = tls_error_vset(error, errnum, fmt, ap); + va_end(ap); + + return (rv); +} + +int +tls_error_setx(struct tls_error *error, const char *fmt, ...) +{ + va_list ap; + int rv; + + va_start(ap, fmt); + rv = tls_error_vset(error, -1, fmt, ap); + va_end(ap); + + return (rv); +} + +int +tls_config_set_error(struct tls_config *config, const char *fmt, ...) +{ + va_list ap; + int errnum, rv; + + errnum = errno; + + va_start(ap, fmt); + rv = tls_error_vset(&config->error, errnum, fmt, ap); + va_end(ap); + + return (rv); +} + +int +tls_config_set_errorx(struct tls_config *config, const char *fmt, ...) +{ + va_list ap; + int rv; + + va_start(ap, fmt); + rv = tls_error_vset(&config->error, -1, fmt, ap); + va_end(ap); + + return (rv); +} + +int +tls_set_error(struct tls *ctx, const char *fmt, ...) +{ + va_list ap; + int errnum, rv; + + errnum = errno; + + va_start(ap, fmt); + rv = tls_error_vset(&ctx->error, errnum, fmt, ap); + va_end(ap); + + return (rv); +} + +int +tls_set_errorx(struct tls *ctx, const char *fmt, ...) +{ + va_list ap; + int rv; + + va_start(ap, fmt); + rv = tls_error_vset(&ctx->error, -1, fmt, ap); + va_end(ap); + + return (rv); +} + +struct tls * +tls_new(void) +{ + struct tls *ctx; + + if ((ctx = calloc(1, sizeof(*ctx))) == NULL) + return (NULL); + + ctx->config = tls_config_default; + + tls_reset(ctx); + + return (ctx); +} + +int +tls_configure(struct tls *ctx, struct tls_config *config) +{ + if (config == NULL) + config = tls_config_default; + + ctx->config = config; + + if ((ctx->flags & TLS_SERVER) != 0) + return (tls_configure_server(ctx)); + + return (0); +} + +int +tls_configure_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, + struct tls_keypair *keypair, int required) +{ + EVP_PKEY *pkey = NULL; + X509 *cert = NULL; + BIO *bio = NULL; + + if (!required && + keypair->cert_mem == NULL && + keypair->key_mem == NULL && + keypair->cert_file == NULL && + keypair->key_file == NULL) + return(0); + + if (keypair->cert_mem != NULL) { + if (keypair->cert_len > INT_MAX) { + tls_set_errorx(ctx, "certificate too long"); + goto err; + } + + if (SSL_CTX_use_certificate_chain_mem(ssl_ctx, + keypair->cert_mem, keypair->cert_len) != 1) { + tls_set_errorx(ctx, "failed to load certificate"); + goto err; + } + cert = NULL; + } + if (keypair->key_mem != NULL) { + if (keypair->key_len > INT_MAX) { + tls_set_errorx(ctx, "key too long"); + goto err; + } + + if ((bio = BIO_new_mem_buf(keypair->key_mem, + keypair->key_len)) == NULL) { + tls_set_errorx(ctx, "failed to create buffer"); + goto err; + } + if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, + NULL)) == NULL) { + tls_set_errorx(ctx, "failed to read private key"); + goto err; + } + if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1) { + tls_set_errorx(ctx, "failed to load private key"); + goto err; + } + BIO_free(bio); + bio = NULL; + EVP_PKEY_free(pkey); + pkey = NULL; + } + + if (keypair->cert_file != NULL) { + if (SSL_CTX_use_certificate_chain_file(ssl_ctx, + keypair->cert_file) != 1) { + tls_set_errorx(ctx, "failed to load certificate file"); + goto err; + } + } + if (keypair->key_file != NULL) { + if (SSL_CTX_use_PrivateKey_file(ssl_ctx, + keypair->key_file, SSL_FILETYPE_PEM) != 1) { + tls_set_errorx(ctx, "failed to load private key file"); + goto err; + } + } + + if (SSL_CTX_check_private_key(ssl_ctx) != 1) { + tls_set_errorx(ctx, "private/public key mismatch"); + goto err; + } + + return (0); + + err: + EVP_PKEY_free(pkey); + X509_free(cert); + BIO_free(bio); + + return (1); +} + +int +tls_configure_ssl(struct tls *ctx) +{ + SSL_CTX_set_mode(ctx->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); + SSL_CTX_set_mode(ctx->ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); + + SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2); + SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv3); + + SSL_CTX_clear_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1); + SSL_CTX_clear_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1_1); + SSL_CTX_clear_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1_2); + + if ((ctx->config->protocols & TLS_PROTOCOL_TLSv1_0) == 0) + SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1); + if ((ctx->config->protocols & TLS_PROTOCOL_TLSv1_1) == 0) + SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1_1); + if ((ctx->config->protocols & TLS_PROTOCOL_TLSv1_2) == 0) + SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1_2); + + if (ctx->config->ciphers != NULL) { + if (SSL_CTX_set_cipher_list(ctx->ssl_ctx, + ctx->config->ciphers) != 1) { + tls_set_errorx(ctx, "failed to set ciphers"); + goto err; + } + } + + if (ctx->config->verify_time == 0) { + X509_VERIFY_PARAM_set_flags(ctx->ssl_ctx->param, + X509_V_FLAG_NO_CHECK_TIME); + } + + return (0); + + err: + return (-1); +} + +int +tls_configure_ssl_verify(struct tls *ctx, int verify) +{ + SSL_CTX_set_verify(ctx->ssl_ctx, verify, NULL); + + if (ctx->config->ca_mem != NULL) { + /* XXX do this in set. */ + if (ctx->config->ca_len > INT_MAX) { + tls_set_errorx(ctx, "ca too long"); + goto err; + } + if (SSL_CTX_load_verify_mem(ctx->ssl_ctx, + ctx->config->ca_mem, ctx->config->ca_len) != 1) { + tls_set_errorx(ctx, "ssl verify memory setup failure"); + goto err; + } + } else if (SSL_CTX_load_verify_locations(ctx->ssl_ctx, + ctx->config->ca_file, ctx->config->ca_path) != 1) { + tls_set_errorx(ctx, "ssl verify setup failure"); + goto err; + } + if (ctx->config->verify_depth >= 0) + SSL_CTX_set_verify_depth(ctx->ssl_ctx, + ctx->config->verify_depth); + + return (0); + + err: + return (-1); +} + +void +tls_free(struct tls *ctx) +{ + if (ctx == NULL) + return; + tls_reset(ctx); + free(ctx); +} + +void +tls_reset(struct tls *ctx) +{ + SSL_CTX_free(ctx->ssl_ctx); + SSL_free(ctx->ssl_conn); + X509_free(ctx->ssl_peer_cert); + + ctx->ssl_conn = NULL; + ctx->ssl_ctx = NULL; + ctx->ssl_peer_cert = NULL; + + ctx->socket = -1; + ctx->state = 0; + + free(ctx->servername); + ctx->servername = NULL; + + free(ctx->error.msg); + ctx->error.msg = NULL; + ctx->error.num = -1; + + tls_free_conninfo(ctx->conninfo); + free(ctx->conninfo); + ctx->conninfo = NULL; +} + +int +tls_ssl_error(struct tls *ctx, SSL *ssl_conn, int ssl_ret, const char *prefix) +{ + const char *errstr = "unknown error"; + unsigned long err; + int ssl_err; + + ssl_err = SSL_get_error(ssl_conn, ssl_ret); + switch (ssl_err) { + case SSL_ERROR_NONE: + case SSL_ERROR_ZERO_RETURN: + return (0); + + case SSL_ERROR_WANT_READ: + return (TLS_WANT_POLLIN); + + case SSL_ERROR_WANT_WRITE: + return (TLS_WANT_POLLOUT); + + case SSL_ERROR_SYSCALL: + if ((err = ERR_peek_error()) != 0) { + errstr = ERR_error_string(err, NULL); + } else if (ssl_ret == 0) { + if ((ctx->state & TLS_HANDSHAKE_COMPLETE) != 0) { + ctx->state |= TLS_EOF_NO_CLOSE_NOTIFY; + return (0); + } + errstr = "unexpected EOF"; + } else if (ssl_ret == -1) { + errstr = strerror(errno); + } + tls_set_errorx(ctx, "%s failed: %s", prefix, errstr); + return (-1); + + case SSL_ERROR_SSL: + if ((err = ERR_peek_error()) != 0) { + errstr = ERR_error_string(err, NULL); + } + tls_set_errorx(ctx, "%s failed: %s", prefix, errstr); + return (-1); + + case SSL_ERROR_WANT_CONNECT: + case SSL_ERROR_WANT_ACCEPT: + case SSL_ERROR_WANT_X509_LOOKUP: + default: + tls_set_errorx(ctx, "%s failed (%i)", prefix, ssl_err); + return (-1); + } +} + +int +tls_handshake(struct tls *ctx) +{ + int rv = -1; + + if ((ctx->flags & (TLS_CLIENT | TLS_SERVER_CONN)) == 0) { + tls_set_errorx(ctx, "invalid operation for context"); + goto out; + } + + if (ctx->conninfo == NULL && + (ctx->conninfo = calloc(1, sizeof(*ctx->conninfo))) == NULL) + goto out; + + if ((ctx->flags & TLS_CLIENT) != 0) + rv = tls_handshake_client(ctx); + else if ((ctx->flags & TLS_SERVER_CONN) != 0) + rv = tls_handshake_server(ctx); + + if (rv == 0) { + ctx->ssl_peer_cert = SSL_get_peer_certificate(ctx->ssl_conn); + if (tls_get_conninfo(ctx) == -1) + rv = -1; + } + out: + /* Prevent callers from performing incorrect error handling */ + errno = 0; + return (rv); +} + +ssize_t +tls_read(struct tls *ctx, void *buf, size_t buflen) +{ + ssize_t rv = -1; + int ssl_ret; + + if ((ctx->state & TLS_HANDSHAKE_COMPLETE) == 0) { + if ((rv = tls_handshake(ctx)) != 0) + goto out; + } + + if (buflen > INT_MAX) { + tls_set_errorx(ctx, "buflen too long"); + goto out; + } + + ERR_clear_error(); + if ((ssl_ret = SSL_read(ctx->ssl_conn, buf, buflen)) > 0) { + rv = (ssize_t)ssl_ret; + goto out; + } + rv = (ssize_t)tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret, "read"); + + out: + /* Prevent callers from performing incorrect error handling */ + errno = 0; + return (rv); +} + +ssize_t +tls_write(struct tls *ctx, const void *buf, size_t buflen) +{ + ssize_t rv = -1; + int ssl_ret; + + if ((ctx->state & TLS_HANDSHAKE_COMPLETE) == 0) { + if ((rv = tls_handshake(ctx)) != 0) + goto out; + } + + if (buflen > INT_MAX) { + tls_set_errorx(ctx, "buflen too long"); + goto out; + } + + ERR_clear_error(); + if ((ssl_ret = SSL_write(ctx->ssl_conn, buf, buflen)) > 0) { + rv = (ssize_t)ssl_ret; + goto out; + } + rv = (ssize_t)tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret, "write"); + + out: + /* Prevent callers from performing incorrect error handling */ + errno = 0; + return (rv); +} + +int +tls_close(struct tls *ctx) +{ + int ssl_ret; + int rv = 0; + + if ((ctx->flags & (TLS_CLIENT | TLS_SERVER_CONN)) == 0) { + tls_set_errorx(ctx, "invalid operation for context"); + rv = -1; + goto out; + } + + if (ctx->ssl_conn != NULL) { + ERR_clear_error(); + ssl_ret = SSL_shutdown(ctx->ssl_conn); + if (ssl_ret < 0) { + rv = tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret, + "shutdown"); + if (rv == TLS_WANT_POLLIN || rv == TLS_WANT_POLLOUT) + goto out; + } + } + + if (ctx->socket != -1) { + if (shutdown(ctx->socket, SHUT_RDWR) != 0) { + if (rv == 0 && + errno != ENOTCONN && errno != ECONNRESET) { + tls_set_error(ctx, "shutdown"); + rv = -1; + } + } + if (close(ctx->socket) != 0) { + if (rv == 0) { + tls_set_error(ctx, "close"); + rv = -1; + } + } + ctx->socket = -1; + } + + if ((ctx->state & TLS_EOF_NO_CLOSE_NOTIFY) != 0) { + tls_set_errorx(ctx, "EOF without close notify"); + rv = -1; + } + + out: + /* Prevent callers from performing incorrect error handling */ + errno = 0; + return (rv); +} diff --git a/crypto/libressl/tls/tls_client.c b/crypto/libressl/tls/tls_client.c new file mode 100644 index 0000000000..2149552a5a --- /dev/null +++ b/crypto/libressl/tls/tls_client.c @@ -0,0 +1,285 @@ +/* $OpenBSD: tls_client.c,v 1.32 2015/10/09 04:13:34 deraadt Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * 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 +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include "tls_internal.h" + +struct tls * +tls_client(void) +{ + struct tls *ctx; + + if ((ctx = tls_new()) == NULL) + return (NULL); + + ctx->flags |= TLS_CLIENT; + + return (ctx); +} + +int +tls_connect(struct tls *ctx, const char *host, const char *port) +{ + return tls_connect_servername(ctx, host, port, NULL); +} + +int +tls_connect_servername(struct tls *ctx, const char *host, const char *port, + const char *servername) +{ + struct addrinfo hints, *res, *res0; + const char *h = NULL, *p = NULL; + char *hs = NULL, *ps = NULL; + int rv = -1, s = -1, ret; + + if ((ctx->flags & TLS_CLIENT) == 0) { + tls_set_errorx(ctx, "not a client context"); + goto err; + } + + if (host == NULL) { + tls_set_errorx(ctx, "host not specified"); + goto err; + } + + /* + * If port is NULL try to extract a port from the specified host, + * otherwise use the default. + */ + if ((p = (char *)port) == NULL) { + ret = tls_host_port(host, &hs, &ps); + if (ret == -1) { + tls_set_errorx(ctx, "memory allocation failure"); + goto err; + } + if (ret != 0) { + tls_set_errorx(ctx, "no port provided"); + goto err; + } + } + + h = (hs != NULL) ? hs : host; + p = (ps != NULL) ? ps : port; + + /* + * First check if the host is specified as a numeric IP address, + * either IPv4 or IPv6, before trying to resolve the host. + * The AI_ADDRCONFIG resolver option will not return IPv4 or IPv6 + * records if it is not configured on an interface; not considering + * loopback addresses. Checking the numeric addresses first makes + * sure that connection attempts to numeric addresses and especially + * 127.0.0.1 or ::1 loopback addresses are always possible. + */ + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_STREAM; + + /* try as an IPv4 literal */ + hints.ai_family = AF_INET; + hints.ai_flags = AI_NUMERICHOST; + if (getaddrinfo(h, p, &hints, &res0) != 0) { + /* try again as an IPv6 literal */ + hints.ai_family = AF_INET6; + if (getaddrinfo(h, p, &hints, &res0) != 0) { + /* last try, with name resolution and save the error */ + hints.ai_family = AF_UNSPEC; + hints.ai_flags = AI_ADDRCONFIG; + if ((s = getaddrinfo(h, p, &hints, &res0)) != 0) { + tls_set_error(ctx, "%s", gai_strerror(s)); + goto err; + } + } + } + + /* It was resolved somehow; now try connecting to what we got */ + s = -1; + for (res = res0; res; res = res->ai_next) { + s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (s == -1) { + tls_set_error(ctx, "socket"); + continue; + } + if (connect(s, res->ai_addr, res->ai_addrlen) == -1) { + tls_set_error(ctx, "connect"); + close(s); + s = -1; + continue; + } + + break; /* Connected. */ + } + freeaddrinfo(res0); + + if (s == -1) + goto err; + + if (servername == NULL) + servername = h; + + if (tls_connect_socket(ctx, s, servername) != 0) { + close(s); + goto err; + } + + ctx->socket = s; + + rv = 0; + + err: + free(hs); + free(ps); + + return (rv); +} + +int +tls_connect_socket(struct tls *ctx, int s, const char *servername) +{ + return tls_connect_fds(ctx, s, s, servername); +} + +int +tls_connect_fds(struct tls *ctx, int fd_read, int fd_write, + const char *servername) +{ + union tls_addr addrbuf; + int rv = -1; + + if ((ctx->flags & TLS_CLIENT) == 0) { + tls_set_errorx(ctx, "not a client context"); + goto err; + } + + if (fd_read < 0 || fd_write < 0) { + tls_set_errorx(ctx, "invalid file descriptors"); + goto err; + } + + if (servername != NULL) { + if ((ctx->servername = strdup(servername)) == NULL) { + tls_set_errorx(ctx, "out of memory"); + goto err; + } + } + + if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) { + tls_set_errorx(ctx, "ssl context failure"); + goto err; + } + + if (tls_configure_ssl(ctx) != 0) + goto err; + if (tls_configure_keypair(ctx, ctx->ssl_ctx, ctx->config->keypair, 0) != 0) + goto err; + + if (ctx->config->verify_name) { + if (servername == NULL) { + tls_set_errorx(ctx, "server name not specified"); + goto err; + } + } + + if (ctx->config->verify_cert && + (tls_configure_ssl_verify(ctx, SSL_VERIFY_PEER) == -1)) + goto err; + + if ((ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) { + tls_set_errorx(ctx, "ssl connection failure"); + goto err; + } + if (SSL_set_app_data(ctx->ssl_conn, ctx) != 1) { + tls_set_errorx(ctx, "ssl application data failure"); + goto err; + } + if (SSL_set_rfd(ctx->ssl_conn, fd_read) != 1 || + SSL_set_wfd(ctx->ssl_conn, fd_write) != 1) { + tls_set_errorx(ctx, "ssl file descriptor failure"); + goto err; + } + + /* + * RFC4366 (SNI): Literal IPv4 and IPv6 addresses are not + * permitted in "HostName". + */ + if (servername != NULL && + inet_pton(AF_INET, servername, &addrbuf) != 1 && + inet_pton(AF_INET6, servername, &addrbuf) != 1) { + if (SSL_set_tlsext_host_name(ctx->ssl_conn, servername) == 0) { + tls_set_errorx(ctx, "server name indication failure"); + goto err; + } + } + + rv = 0; + + err: + return (rv); +} + +int +tls_handshake_client(struct tls *ctx) +{ + X509 *cert = NULL; + int ssl_ret; + int rv = -1; + + if ((ctx->flags & TLS_CLIENT) == 0) { + tls_set_errorx(ctx, "not a client context"); + goto err; + } + + ERR_clear_error(); + if ((ssl_ret = SSL_connect(ctx->ssl_conn)) != 1) { + rv = tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret, "handshake"); + goto err; + } + + if (ctx->config->verify_name) { + cert = SSL_get_peer_certificate(ctx->ssl_conn); + if (cert == NULL) { + tls_set_errorx(ctx, "no server certificate"); + goto err; + } + if ((rv = tls_check_name(ctx, cert, + ctx->servername)) != 0) { + if (rv != -2) + tls_set_errorx(ctx, "name `%s' not present in" + " server certificate", ctx->servername); + goto err; + } + } + + ctx->state |= TLS_HANDSHAKE_COMPLETE; + rv = 0; + + err: + X509_free(cert); + + return (rv); +} diff --git a/crypto/libressl/tls/tls_config.c b/crypto/libressl/tls/tls_config.c new file mode 100644 index 0000000000..a418177b81 --- /dev/null +++ b/crypto/libressl/tls/tls_config.c @@ -0,0 +1,454 @@ +/* $OpenBSD: tls_config.c,v 1.21 2016/07/07 14:09:03 jsing Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * 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 +#include +#include + +#include +#include "tls_internal.h" + +static int +set_string(const char **dest, const char *src) +{ + free((char *)*dest); + *dest = NULL; + if (src != NULL) + if ((*dest = strdup(src)) == NULL) + return -1; + return 0; +} + +static void * +memdup(const void *in, size_t len) +{ + void *out; + + if ((out = malloc(len)) == NULL) + return NULL; + memcpy(out, in, len); + return out; +} + +static int +set_mem(char **dest, size_t *destlen, const void *src, size_t srclen) +{ + free(*dest); + *dest = NULL; + *destlen = 0; + if (src != NULL) + if ((*dest = memdup(src, srclen)) == NULL) + return -1; + *destlen = srclen; + return 0; +} + +static struct tls_keypair * +tls_keypair_new() +{ + return calloc(1, sizeof(struct tls_keypair)); +} + +static int +tls_keypair_set_cert_file(struct tls_keypair *keypair, const char *cert_file) +{ + return set_string(&keypair->cert_file, cert_file); +} + +static int +tls_keypair_set_cert_mem(struct tls_keypair *keypair, const uint8_t *cert, + size_t len) +{ + return set_mem(&keypair->cert_mem, &keypair->cert_len, cert, len); +} + +static int +tls_keypair_set_key_file(struct tls_keypair *keypair, const char *key_file) +{ + return set_string(&keypair->key_file, key_file); +} + +static int +tls_keypair_set_key_mem(struct tls_keypair *keypair, const uint8_t *key, + size_t len) +{ + if (keypair->key_mem != NULL) + explicit_bzero(keypair->key_mem, keypair->key_len); + return set_mem(&keypair->key_mem, &keypair->key_len, key, len); +} + +static void +tls_keypair_clear(struct tls_keypair *keypair) +{ + tls_keypair_set_cert_mem(keypair, NULL, 0); + tls_keypair_set_key_mem(keypair, NULL, 0); +} + +static void +tls_keypair_free(struct tls_keypair *keypair) +{ + if (keypair == NULL) + return; + + tls_keypair_clear(keypair); + + free((char *)keypair->cert_file); + free(keypair->cert_mem); + free((char *)keypair->key_file); + free(keypair->key_mem); + + free(keypair); +} + +struct tls_config * +tls_config_new(void) +{ + struct tls_config *config; + + if ((config = calloc(1, sizeof(*config))) == NULL) + return (NULL); + + if ((config->keypair = tls_keypair_new()) == NULL) + goto err; + + /* + * Default configuration. + */ + if (tls_config_set_ca_file(config, _PATH_SSL_CA_FILE) != 0) + goto err; + if (tls_config_set_dheparams(config, "none") != 0) + goto err; + if (tls_config_set_ecdhecurve(config, "auto") != 0) + goto err; + if (tls_config_set_ciphers(config, "secure") != 0) + goto err; + + tls_config_set_protocols(config, TLS_PROTOCOLS_DEFAULT); + tls_config_set_verify_depth(config, 6); + + tls_config_prefer_ciphers_server(config); + + tls_config_verify(config); + + return (config); + + err: + tls_config_free(config); + return (NULL); +} + +void +tls_config_free(struct tls_config *config) +{ + struct tls_keypair *kp, *nkp; + + if (config == NULL) + return; + + for (kp = config->keypair; kp != NULL; kp = nkp) { + nkp = kp->next; + tls_keypair_free(kp); + } + + free(config->error.msg); + + free((char *)config->ca_file); + free((char *)config->ca_mem); + free((char *)config->ca_path); + free((char *)config->ciphers); + + free(config); +} + +const char * +tls_config_error(struct tls_config *config) +{ + return config->error.msg; +} + +void +tls_config_clear_keys(struct tls_config *config) +{ + struct tls_keypair *kp; + + for (kp = config->keypair; kp != NULL; kp = kp->next) + tls_keypair_clear(kp); + + tls_config_set_ca_mem(config, NULL, 0); +} + +int +tls_config_parse_protocols(uint32_t *protocols, const char *protostr) +{ + uint32_t proto, protos = 0; + char *s, *p, *q; + int negate; + + if ((s = strdup(protostr)) == NULL) + return (-1); + + q = s; + while ((p = strsep(&q, ",:")) != NULL) { + while (*p == ' ' || *p == '\t') + p++; + + negate = 0; + if (*p == '!') { + negate = 1; + p++; + } + + if (negate && protos == 0) + protos = TLS_PROTOCOLS_ALL; + + proto = 0; + if (strcasecmp(p, "all") == 0 || + strcasecmp(p, "legacy") == 0) + proto = TLS_PROTOCOLS_ALL; + else if (strcasecmp(p, "default") == 0 || + strcasecmp(p, "secure") == 0) + proto = TLS_PROTOCOLS_DEFAULT; + if (strcasecmp(p, "tlsv1") == 0) + proto = TLS_PROTOCOL_TLSv1; + else if (strcasecmp(p, "tlsv1.0") == 0) + proto = TLS_PROTOCOL_TLSv1_0; + else if (strcasecmp(p, "tlsv1.1") == 0) + proto = TLS_PROTOCOL_TLSv1_1; + else if (strcasecmp(p, "tlsv1.2") == 0) + proto = TLS_PROTOCOL_TLSv1_2; + + if (proto == 0) { + free(s); + return (-1); + } + + if (negate) + protos &= ~proto; + else + protos |= proto; + } + + *protocols = protos; + + free(s); + + return (0); +} + +int +tls_config_set_ca_file(struct tls_config *config, const char *ca_file) +{ + return set_string(&config->ca_file, ca_file); +} + +int +tls_config_set_ca_path(struct tls_config *config, const char *ca_path) +{ + return set_string(&config->ca_path, ca_path); +} + +int +tls_config_set_ca_mem(struct tls_config *config, const uint8_t *ca, size_t len) +{ + return set_mem(&config->ca_mem, &config->ca_len, ca, len); +} + +int +tls_config_set_cert_file(struct tls_config *config, const char *cert_file) +{ + return tls_keypair_set_cert_file(config->keypair, cert_file); +} + +int +tls_config_set_cert_mem(struct tls_config *config, const uint8_t *cert, + size_t len) +{ + return tls_keypair_set_cert_mem(config->keypair, cert, len); +} + +int +tls_config_set_ciphers(struct tls_config *config, const char *ciphers) +{ + SSL_CTX *ssl_ctx = NULL; + + if (ciphers == NULL || + strcasecmp(ciphers, "default") == 0 || + strcasecmp(ciphers, "secure") == 0) + ciphers = TLS_CIPHERS_DEFAULT; + else if (strcasecmp(ciphers, "compat") == 0) + ciphers = TLS_CIPHERS_COMPAT; + else if (strcasecmp(ciphers, "legacy") == 0) + ciphers = TLS_CIPHERS_LEGACY; + else if (strcasecmp(ciphers, "all") == 0 || + strcasecmp(ciphers, "insecure") == 0) + ciphers = TLS_CIPHERS_ALL; + + if ((ssl_ctx = SSL_CTX_new(SSLv23_method())) == NULL) { + tls_config_set_errorx(config, "out of memory"); + goto fail; + } + if (SSL_CTX_set_cipher_list(ssl_ctx, ciphers) != 1) { + tls_config_set_errorx(config, "no ciphers for '%s'", ciphers); + goto fail; + } + + SSL_CTX_free(ssl_ctx); + return set_string(&config->ciphers, ciphers); + + fail: + SSL_CTX_free(ssl_ctx); + return -1; +} + +int +tls_config_set_dheparams(struct tls_config *config, const char *params) +{ + int keylen; + + if (params == NULL || strcasecmp(params, "none") == 0) + keylen = 0; + else if (strcasecmp(params, "auto") == 0) + keylen = -1; + else if (strcasecmp(params, "legacy") == 0) + keylen = 1024; + else { + tls_config_set_errorx(config, "invalid dhe param '%s'", params); + return (-1); + } + + config->dheparams = keylen; + + return (0); +} + +int +tls_config_set_ecdhecurve(struct tls_config *config, const char *name) +{ + int nid; + + if (name == NULL || strcasecmp(name, "none") == 0) + nid = NID_undef; + else if (strcasecmp(name, "auto") == 0) + nid = -1; + else if ((nid = OBJ_txt2nid(name)) == NID_undef) { + tls_config_set_errorx(config, "invalid ecdhe curve '%s'", name); + return (-1); + } + + config->ecdhecurve = nid; + + return (0); +} + +int +tls_config_set_key_file(struct tls_config *config, const char *key_file) +{ + return tls_keypair_set_key_file(config->keypair, key_file); +} + +int +tls_config_set_key_mem(struct tls_config *config, const uint8_t *key, + size_t len) +{ + return tls_keypair_set_key_mem(config->keypair, key, len); +} + +int +tls_config_set_keypair_file(struct tls_config *config, + const char *cert_file, const char *key_file) +{ + if (tls_config_set_cert_file(config, cert_file) != 0) + return (-1); + if (tls_config_set_key_file(config, key_file) != 0) + return (-1); + + return (0); +} + +int +tls_config_set_keypair_mem(struct tls_config *config, const uint8_t *cert, + size_t cert_len, const uint8_t *key, size_t key_len) +{ + if (tls_config_set_cert_mem(config, cert, cert_len) != 0) + return (-1); + if (tls_config_set_key_mem(config, key, key_len) != 0) + return (-1); + + return (0); +} + +void +tls_config_set_protocols(struct tls_config *config, uint32_t protocols) +{ + config->protocols = protocols; +} + +void +tls_config_set_verify_depth(struct tls_config *config, int verify_depth) +{ + config->verify_depth = verify_depth; +} + +void +tls_config_prefer_ciphers_client(struct tls_config *config) +{ + config->ciphers_server = 0; +} + +void +tls_config_prefer_ciphers_server(struct tls_config *config) +{ + config->ciphers_server = 1; +} + +void +tls_config_insecure_noverifycert(struct tls_config *config) +{ + config->verify_cert = 0; +} + +void +tls_config_insecure_noverifyname(struct tls_config *config) +{ + config->verify_name = 0; +} + +void +tls_config_insecure_noverifytime(struct tls_config *config) +{ + config->verify_time = 0; +} + +void +tls_config_verify(struct tls_config *config) +{ + config->verify_cert = 1; + config->verify_name = 1; + config->verify_time = 1; +} + +void +tls_config_verify_client(struct tls_config *config) +{ + config->verify_client = 1; +} + +void +tls_config_verify_client_optional(struct tls_config *config) +{ + config->verify_client = 2; +} diff --git a/crypto/libressl/tls/tls_conninfo.c b/crypto/libressl/tls/tls_conninfo.c new file mode 100644 index 0000000000..8bdc40d0ed --- /dev/null +++ b/crypto/libressl/tls/tls_conninfo.c @@ -0,0 +1,214 @@ +/* $OpenBSD: tls_conninfo.c,v 1.4 2015/10/07 23:25:45 beck Exp $ */ +/* + * Copyright (c) 2015 Joel Sing + * Copyright (c) 2015 Bob Beck + * + * 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 + +#include + +#include +#include "tls_internal.h" + +static int +tls_hex_string(const unsigned char *in, size_t inlen, char **out, + size_t *outlen) +{ + static const char hex[] = "0123456789abcdef"; + size_t i, len; + char *p; + + if (outlen != NULL) + *outlen = 0; + + if (inlen >= SIZE_MAX) + return (-1); + if ((*out = reallocarray(NULL, inlen + 1, 2)) == NULL) + return (-1); + + p = *out; + len = 0; + for (i = 0; i < inlen; i++) { + p[len++] = hex[(in[i] >> 4) & 0x0f]; + p[len++] = hex[in[i] & 0x0f]; + } + p[len++] = 0; + + if (outlen != NULL) + *outlen = len; + + return (0); +} + +static int +tls_get_peer_cert_hash(struct tls *ctx, char **hash) +{ + char d[EVP_MAX_MD_SIZE], *dhex = NULL; + int dlen, rv = -1; + + *hash = NULL; + if (ctx->ssl_peer_cert == NULL) + return (0); + + if (X509_digest(ctx->ssl_peer_cert, EVP_sha256(), d, &dlen) != 1) { + tls_set_errorx(ctx, "digest failed"); + goto err; + } + + if (tls_hex_string(d, dlen, &dhex, NULL) != 0) { + tls_set_errorx(ctx, "digest hex string failed"); + goto err; + } + + if (asprintf(hash, "SHA256:%s", dhex) == -1) { + tls_set_errorx(ctx, "out of memory"); + *hash = NULL; + goto err; + } + + rv = 0; + +err: + free(dhex); + + return (rv); +} + +static int +tls_get_peer_cert_issuer(struct tls *ctx, char **issuer) +{ + X509_NAME *name = NULL; + + *issuer = NULL; + if (ctx->ssl_peer_cert == NULL) + return (-1); + if ((name = X509_get_issuer_name(ctx->ssl_peer_cert)) == NULL) + return (-1); + *issuer = X509_NAME_oneline(name, 0, 0); + if (*issuer == NULL) + return (-1); + return (0); +} + +static int +tls_get_peer_cert_subject(struct tls *ctx, char **subject) +{ + X509_NAME *name = NULL; + + *subject = NULL; + if (ctx->ssl_peer_cert == NULL) + return (-1); + if ((name = X509_get_subject_name(ctx->ssl_peer_cert)) == NULL) + return (-1); + *subject = X509_NAME_oneline(name, 0, 0); + if (*subject == NULL) + return (-1); + return (0); +} + +static int +tls_get_peer_cert_times(struct tls *ctx, time_t *notbefore, time_t *notafter) +{ + struct tm before_tm, after_tm; + ASN1_TIME *before, *after; + int rv = -1; + + memset(&before_tm, 0, sizeof(before_tm)); + memset(&after_tm, 0, sizeof(after_tm)); + + if (ctx->ssl_peer_cert != NULL) { + if ((before = X509_get_notBefore(ctx->ssl_peer_cert)) == NULL) + goto err; + if ((after = X509_get_notAfter(ctx->ssl_peer_cert)) == NULL) + goto err; + if (asn1_time_parse(before->data, before->length, &before_tm, 0) + == -1) + goto err; + if (asn1_time_parse(after->data, after->length, &after_tm, 0) + == -1) + goto err; + if ((*notbefore = timegm(&before_tm)) == -1) + goto err; + if ((*notafter = timegm(&after_tm)) == -1) + goto err; + } + rv = 0; + err: + return (rv); +} + +int +tls_get_conninfo(struct tls *ctx) { + const char * tmp; + if (ctx->ssl_peer_cert != NULL) { + if (tls_get_peer_cert_hash(ctx, &ctx->conninfo->hash) == -1) + goto err; + if (tls_get_peer_cert_subject(ctx, &ctx->conninfo->subject) + == -1) + goto err; + if (tls_get_peer_cert_issuer(ctx, &ctx->conninfo->issuer) == -1) + goto err; + if (tls_get_peer_cert_times(ctx, &ctx->conninfo->notbefore, + &ctx->conninfo->notafter) == -1) + goto err; + } + if ((tmp = SSL_get_version(ctx->ssl_conn)) == NULL) + goto err; + ctx->conninfo->version = strdup(tmp); + if (ctx->conninfo->version == NULL) + goto err; + if ((tmp = SSL_get_cipher(ctx->ssl_conn)) == NULL) + goto err; + ctx->conninfo->cipher = strdup(tmp); + if (ctx->conninfo->cipher == NULL) + goto err; + return (0); +err: + tls_free_conninfo(ctx->conninfo); + return (-1); +} + +void +tls_free_conninfo(struct tls_conninfo *conninfo) { + if (conninfo != NULL) { + free(conninfo->hash); + conninfo->hash = NULL; + free(conninfo->subject); + conninfo->subject = NULL; + free(conninfo->issuer); + conninfo->issuer = NULL; + free(conninfo->version); + conninfo->version = NULL; + free(conninfo->cipher); + conninfo->cipher = NULL; + } +} + +const char * +tls_conn_cipher(struct tls *ctx) +{ + if (ctx->conninfo == NULL) + return (NULL); + return (ctx->conninfo->cipher); +} + +const char * +tls_conn_version(struct tls *ctx) +{ + if (ctx->conninfo == NULL) + return (NULL); + return (ctx->conninfo->version); +} diff --git a/crypto/libressl/tls/tls_internal.h b/crypto/libressl/tls/tls_internal.h new file mode 100644 index 0000000000..95e1b4c9f1 --- /dev/null +++ b/crypto/libressl/tls/tls_internal.h @@ -0,0 +1,152 @@ +/* $OpenBSD: tls_internal.h,v 1.31 2016/07/07 14:09:03 jsing Exp $ */ +/* + * Copyright (c) 2014 Jeremie Courreges-Anglas + * Copyright (c) 2014 Joel Sing + * + * 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 HEADER_TLS_INTERNAL_H +#define HEADER_TLS_INTERNAL_H + +#include +#include + +#include + +#ifndef _PATH_SSL_CA_FILE +#define _PATH_SSL_CA_FILE "/etc/ssl/cert.pem" +#endif + +#define TLS_CIPHERS_DEFAULT "TLSv1.2+AEAD+ECDHE:TLSv1.2+AEAD+DHE" +#define TLS_CIPHERS_COMPAT "HIGH:!aNULL" +#define TLS_CIPHERS_LEGACY "HIGH:MEDIUM:!aNULL" +#define TLS_CIPHERS_ALL "ALL:!aNULL:!eNULL" + +union tls_addr { + struct in_addr ip4; + struct in6_addr ip6; +}; + +struct tls_error { + char *msg; + int num; +}; + +struct tls_keypair { + struct tls_keypair *next; + + const char *cert_file; + char *cert_mem; + size_t cert_len; + const char *key_file; + char *key_mem; + size_t key_len; +}; + +struct tls_config { + struct tls_error error; + + const char *ca_file; + const char *ca_path; + char *ca_mem; + size_t ca_len; + const char *ciphers; + int ciphers_server; + int dheparams; + int ecdhecurve; + struct tls_keypair *keypair; + uint32_t protocols; + int verify_cert; + int verify_client; + int verify_depth; + int verify_name; + int verify_time; +}; + +struct tls_conninfo { + char *issuer; + char *subject; + char *hash; + char *serial; + char *fingerprint; + char *version; + char *cipher; + time_t notbefore; + time_t notafter; +}; + +#define TLS_CLIENT (1 << 0) +#define TLS_SERVER (1 << 1) +#define TLS_SERVER_CONN (1 << 2) + +#define TLS_EOF_NO_CLOSE_NOTIFY (1 << 0) +#define TLS_HANDSHAKE_COMPLETE (1 << 1) + +struct tls { + struct tls_config *config; + struct tls_error error; + + uint32_t flags; + uint32_t state; + + char *servername; + int socket; + + SSL *ssl_conn; + SSL_CTX *ssl_ctx; + X509 *ssl_peer_cert; + struct tls_conninfo *conninfo; +}; + +struct tls *tls_new(void); +struct tls *tls_server_conn(struct tls *ctx); + +int tls_check_name(struct tls *ctx, X509 *cert, const char *servername); +int tls_configure_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, + struct tls_keypair *keypair, int required); +int tls_configure_server(struct tls *ctx); +int tls_configure_ssl(struct tls *ctx); +int tls_configure_ssl_verify(struct tls *ctx, int verify); +int tls_handshake_client(struct tls *ctx); +int tls_handshake_server(struct tls *ctx); +int tls_host_port(const char *hostport, char **host, char **port); + +int tls_error_set(struct tls_error *error, const char *fmt, ...) + __attribute__((__format__ (printf, 2, 3))) + __attribute__((__nonnull__ (2))); +int tls_error_setx(struct tls_error *error, const char *fmt, ...) + __attribute__((__format__ (printf, 2, 3))) + __attribute__((__nonnull__ (2))); +int tls_config_set_error(struct tls_config *cfg, const char *fmt, ...) + __attribute__((__format__ (printf, 2, 3))) + __attribute__((__nonnull__ (2))); +int tls_config_set_errorx(struct tls_config *cfg, const char *fmt, ...) + __attribute__((__format__ (printf, 2, 3))) + __attribute__((__nonnull__ (2))); +int tls_set_error(struct tls *ctx, const char *fmt, ...) + __attribute__((__format__ (printf, 2, 3))) + __attribute__((__nonnull__ (2))); +int tls_set_errorx(struct tls *ctx, const char *fmt, ...) + __attribute__((__format__ (printf, 2, 3))) + __attribute__((__nonnull__ (2))); + +int tls_ssl_error(struct tls *ctx, SSL *ssl_conn, int ssl_ret, + const char *prefix); + +int tls_get_conninfo(struct tls *ctx); +void tls_free_conninfo(struct tls_conninfo *conninfo); + +int asn1_time_parse(const char *, size_t, struct tm *, int); + +#endif /* HEADER_TLS_INTERNAL_H */ diff --git a/crypto/libressl/tls/tls_peer.c b/crypto/libressl/tls/tls_peer.c new file mode 100644 index 0000000000..5e31ab2297 --- /dev/null +++ b/crypto/libressl/tls/tls_peer.c @@ -0,0 +1,83 @@ +/* $OpenBSD: tls_peer.c,v 1.4 2015/09/12 21:00:38 beck Exp $ */ +/* + * Copyright (c) 2015 Joel Sing + * Copyright (c) 2015 Bob Beck + * + * 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 + +#include + +#include +#include "tls_internal.h" + +const char * +tls_peer_cert_hash(struct tls *ctx) +{ + if (ctx->conninfo) + return (ctx->conninfo->hash); + return NULL; +} +const char * +tls_peer_cert_issuer(struct tls *ctx) +{ + if (ctx->conninfo) + return (ctx->conninfo->issuer); + return NULL; +} + +const char * +tls_peer_cert_subject(struct tls *ctx) +{ + if (ctx->conninfo) + return (ctx->conninfo->subject); + return NULL; +} + +int +tls_peer_cert_provided(struct tls *ctx) +{ + return (ctx->ssl_peer_cert != NULL); +} + +int +tls_peer_cert_contains_name(struct tls *ctx, const char *name) +{ + if (ctx->ssl_peer_cert == NULL) + return (0); + + return (tls_check_name(ctx, ctx->ssl_peer_cert, name) == 0); +} + +time_t +tls_peer_cert_notbefore(struct tls *ctx) +{ + if (ctx->ssl_peer_cert == NULL) + return (-1); + if (ctx->conninfo == NULL) + return (-1); + return (ctx->conninfo->notbefore); +} + +time_t +tls_peer_cert_notafter(struct tls *ctx) +{ + if (ctx->ssl_peer_cert == NULL) + return (-1); + if (ctx->conninfo == NULL) + return (-1); + return (ctx->conninfo->notafter); +} + diff --git a/crypto/libressl/tls/tls_server.c b/crypto/libressl/tls/tls_server.c new file mode 100644 index 0000000000..58dbb60513 --- /dev/null +++ b/crypto/libressl/tls/tls_server.c @@ -0,0 +1,182 @@ +/* $OpenBSD: tls_server.c,v 1.18 2015/09/29 10:17:04 deraadt Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * + * 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 +#include +#include + +#include +#include "tls_internal.h" + +struct tls * +tls_server(void) +{ + struct tls *ctx; + + if ((ctx = tls_new()) == NULL) + return (NULL); + + ctx->flags |= TLS_SERVER; + + return (ctx); +} + +struct tls * +tls_server_conn(struct tls *ctx) +{ + struct tls *conn_ctx; + + if ((conn_ctx = tls_new()) == NULL) + return (NULL); + + conn_ctx->flags |= TLS_SERVER_CONN; + + return (conn_ctx); +} + +int +tls_configure_server(struct tls *ctx) +{ + EC_KEY *ecdh_key; + unsigned char sid[SSL_MAX_SSL_SESSION_ID_LENGTH]; + + if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_server_method())) == NULL) { + tls_set_errorx(ctx, "ssl context failure"); + goto err; + } + + if (tls_configure_ssl(ctx) != 0) + goto err; + if (tls_configure_keypair(ctx, ctx->ssl_ctx, ctx->config->keypair, 1) != 0) + goto err; + if (ctx->config->verify_client != 0) { + int verify = SSL_VERIFY_PEER; + if (ctx->config->verify_client == 1) + verify |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; + if (tls_configure_ssl_verify(ctx, verify) == -1) + goto err; + } + + if (ctx->config->dheparams == -1) + SSL_CTX_set_dh_auto(ctx->ssl_ctx, 1); + else if (ctx->config->dheparams == 1024) + SSL_CTX_set_dh_auto(ctx->ssl_ctx, 2); + + if (ctx->config->ecdhecurve == -1) { + SSL_CTX_set_ecdh_auto(ctx->ssl_ctx, 1); + } else if (ctx->config->ecdhecurve != NID_undef) { + if ((ecdh_key = EC_KEY_new_by_curve_name( + ctx->config->ecdhecurve)) == NULL) { + tls_set_errorx(ctx, "failed to set ECDHE curve"); + goto err; + } + SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_SINGLE_ECDH_USE); + SSL_CTX_set_tmp_ecdh(ctx->ssl_ctx, ecdh_key); + EC_KEY_free(ecdh_key); + } + + if (ctx->config->ciphers_server == 1) + SSL_CTX_set_options(ctx->ssl_ctx, + SSL_OP_CIPHER_SERVER_PREFERENCE); + + /* + * Set session ID context to a random value. We don't support + * persistent caching of sessions so it is OK to set a temporary + * session ID context that is valid during run time. + */ + arc4random_buf(sid, sizeof(sid)); + if (!SSL_CTX_set_session_id_context(ctx->ssl_ctx, sid, sizeof(sid))) { + tls_set_errorx(ctx, "failed to set session id context"); + goto err; + } + + return (0); + + err: + return (-1); +} + +int +tls_accept_socket(struct tls *ctx, struct tls **cctx, int socket) +{ + return (tls_accept_fds(ctx, cctx, socket, socket)); +} + +int +tls_accept_fds(struct tls *ctx, struct tls **cctx, int fd_read, int fd_write) +{ + struct tls *conn_ctx = NULL; + + if ((ctx->flags & TLS_SERVER) == 0) { + tls_set_errorx(ctx, "not a server context"); + goto err; + } + + if ((conn_ctx = tls_server_conn(ctx)) == NULL) { + tls_set_errorx(ctx, "connection context failure"); + goto err; + } + + if ((conn_ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) { + tls_set_errorx(ctx, "ssl failure"); + goto err; + } + if (SSL_set_app_data(conn_ctx->ssl_conn, conn_ctx) != 1) { + tls_set_errorx(ctx, "ssl application data failure"); + goto err; + } + if (SSL_set_rfd(conn_ctx->ssl_conn, fd_read) != 1 || + SSL_set_wfd(conn_ctx->ssl_conn, fd_write) != 1) { + tls_set_errorx(ctx, "ssl file descriptor failure"); + goto err; + } + + *cctx = conn_ctx; + + return (0); + + err: + tls_free(conn_ctx); + + *cctx = NULL; + + return (-1); +} + +int +tls_handshake_server(struct tls *ctx) +{ + int ssl_ret; + int rv = -1; + + if ((ctx->flags & TLS_SERVER_CONN) == 0) { + tls_set_errorx(ctx, "not a server connection context"); + goto err; + } + + ERR_clear_error(); + if ((ssl_ret = SSL_accept(ctx->ssl_conn)) != 1) { + rv = tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret, "handshake"); + goto err; + } + + ctx->state |= TLS_HANDSHAKE_COMPLETE; + rv = 0; + + err: + return (rv); +} diff --git a/crypto/libressl/tls/tls_util.c b/crypto/libressl/tls/tls_util.c new file mode 100644 index 0000000000..b3035c93e8 --- /dev/null +++ b/crypto/libressl/tls/tls_util.c @@ -0,0 +1,169 @@ +/* $OpenBSD: tls_util.c,v 1.2 2015/02/07 23:25:37 reyk Exp $ */ +/* + * Copyright (c) 2014 Joel Sing + * Copyright (c) 2015 Reyk Floeter + * + * 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 + +#include +#include +#include + +#include "tls.h" +#include "tls_internal.h" + +/* + * Extract the host and port from a colon separated value. For a literal IPv6 + * address the address must be contained with square braces. If a host and + * port are successfully extracted, the function will return 0 and the + * caller is responsible for freeing the host and port. If no port is found + * then the function will return 1, with both host and port being NULL. + * On memory allocation failure -1 will be returned. + */ +int +tls_host_port(const char *hostport, char **host, char **port) +{ + char *h, *p, *s; + int rv = 1; + + *host = NULL; + *port = NULL; + + if ((s = strdup(hostport)) == NULL) + goto fail; + + h = p = s; + + /* See if this is an IPv6 literal with square braces. */ + if (p[0] == '[') { + h++; + if ((p = strchr(s, ']')) == NULL) + goto done; + *p++ = '\0'; + } + + /* Find the port seperator. */ + if ((p = strchr(p, ':')) == NULL) + goto done; + + /* If there is another separator then we have issues. */ + if (strchr(p + 1, ':') != NULL) + goto done; + + *p++ = '\0'; + + if (asprintf(host, "%s", h) == -1) + goto fail; + if (asprintf(port, "%s", p) == -1) + goto fail; + + rv = 0; + goto done; + + fail: + free(*host); + *host = NULL; + free(*port); + *port = NULL; + rv = -1; + + done: + free(s); + + return (rv); +} + +static int +tls_password_cb(char *buf, int size, int rwflag, void *u) +{ + size_t len; + if (u == NULL) { + memset(buf, 0, size); + return (0); + } + if ((len = strlcpy(buf, u, size)) >= (size_t)size) + return (0); + return (len); +} + +uint8_t * +tls_load_file(const char *name, size_t *len, char *password) +{ + FILE *fp; + EVP_PKEY *key = NULL; + BIO *bio = NULL; + char *data, *buf = NULL; + struct stat st; + size_t size; + int fd = -1; + + *len = 0; + + if ((fd = open(name, O_RDONLY)) == -1) + return (NULL); + + /* Just load the file into memory without decryption */ + if (password == NULL) { + if (fstat(fd, &st) != 0) + goto fail; + size = (size_t)st.st_size; + if ((buf = calloc(1, size + 1)) == NULL) + goto fail; + if (read(fd, buf, size) != size) + goto fail; + close(fd); + goto done; + } + + /* Or read the (possibly) encrypted key from file */ + if ((fp = fdopen(fd, "r")) == NULL) + goto fail; + fd = -1; + + key = PEM_read_PrivateKey(fp, NULL, tls_password_cb, password); + fclose(fp); + if (key == NULL) + goto fail; + + /* Write unencrypted key to memory buffer */ + if ((bio = BIO_new(BIO_s_mem())) == NULL) + goto fail; + if (!PEM_write_bio_PrivateKey(bio, key, NULL, NULL, 0, NULL, NULL)) + goto fail; + if ((size = BIO_get_mem_data(bio, &data)) <= 0) + goto fail; + if ((buf = calloc(1, size)) == NULL) + goto fail; + memcpy(buf, data, size); + + BIO_free_all(bio); + EVP_PKEY_free(key); + + done: + *len = size; + return (buf); + + fail: + free(buf); + if (fd != -1) + close(fd); + if (bio != NULL) + BIO_free_all(bio); + if (key != NULL) + EVP_PKEY_free(key); + + return (NULL); +} diff --git a/crypto/libressl/tls/tls_verify.c b/crypto/libressl/tls/tls_verify.c new file mode 100644 index 0000000000..dd49dc826c --- /dev/null +++ b/crypto/libressl/tls/tls_verify.c @@ -0,0 +1,261 @@ +/* $OpenBSD: tls_verify.c,v 1.14 2015/09/29 10:17:04 deraadt Exp $ */ +/* + * Copyright (c) 2014 Jeremie Courreges-Anglas + * + * 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 + +#include +#include + +#include + +#include + +#include "tls_internal.h" + +static int tls_match_name(const char *cert_name, const char *name); +static int tls_check_subject_altname(struct tls *ctx, X509 *cert, + const char *name); +static int tls_check_common_name(struct tls *ctx, X509 *cert, const char *name); + +static int +tls_match_name(const char *cert_name, const char *name) +{ + const char *cert_domain, *domain, *next_dot; + + if (strcasecmp(cert_name, name) == 0) + return 0; + + /* Wildcard match? */ + if (cert_name[0] == '*') { + /* + * Valid wildcards: + * - "*.domain.tld" + * - "*.sub.domain.tld" + * - etc. + * Reject "*.tld". + * No attempt to prevent the use of eg. "*.co.uk". + */ + cert_domain = &cert_name[1]; + /* Disallow "*" */ + if (cert_domain[0] == '\0') + return -1; + /* Disallow "*foo" */ + if (cert_domain[0] != '.') + return -1; + /* Disallow "*.." */ + if (cert_domain[1] == '.') + return -1; + next_dot = strchr(&cert_domain[1], '.'); + /* Disallow "*.bar" */ + if (next_dot == NULL) + return -1; + /* Disallow "*.bar.." */ + if (next_dot[1] == '.') + return -1; + + domain = strchr(name, '.'); + + /* No wildcard match against a name with no host part. */ + if (name[0] == '.') + return -1; + /* No wildcard match against a name with no domain part. */ + if (domain == NULL || strlen(domain) == 1) + return -1; + + if (strcasecmp(cert_domain, domain) == 0) + return 0; + } + + return -1; +} + +/* See RFC 5280 section 4.2.1.6 for SubjectAltName details. */ +static int +tls_check_subject_altname(struct tls *ctx, X509 *cert, const char *name) +{ + STACK_OF(GENERAL_NAME) *altname_stack = NULL; + union tls_addr addrbuf; + int addrlen, type; + int count, i; + int rv = -1; + + altname_stack = X509_get_ext_d2i(cert, NID_subject_alt_name, + NULL, NULL); + if (altname_stack == NULL) + return -1; + + if (inet_pton(AF_INET, name, &addrbuf) == 1) { + type = GEN_IPADD; + addrlen = 4; + } else if (inet_pton(AF_INET6, name, &addrbuf) == 1) { + type = GEN_IPADD; + addrlen = 16; + } else { + type = GEN_DNS; + addrlen = 0; + } + + count = sk_GENERAL_NAME_num(altname_stack); + for (i = 0; i < count; i++) { + GENERAL_NAME *altname; + + altname = sk_GENERAL_NAME_value(altname_stack, i); + + if (altname->type != type) + continue; + + if (type == GEN_DNS) { + unsigned char *data; + int format, len; + + format = ASN1_STRING_type(altname->d.dNSName); + if (format == V_ASN1_IA5STRING) { + data = ASN1_STRING_data(altname->d.dNSName); + len = ASN1_STRING_length(altname->d.dNSName); + + if (len < 0 || len != strlen(data)) { + tls_set_errorx(ctx, + "error verifying name '%s': " + "NUL byte in subjectAltName, " + "probably a malicious certificate", + name); + rv = -2; + break; + } + + /* + * Per RFC 5280 section 4.2.1.6: + * " " is a legal domain name, but that + * dNSName must be rejected. + */ + if (strcmp(data, " ") == 0) { + tls_set_error(ctx, + "error verifying name '%s': " + "a dNSName of \" \" must not be " + "used", name); + rv = -2; + break; + } + + if (tls_match_name(data, name) == 0) { + rv = 0; + break; + } + } else { +#ifdef DEBUG + fprintf(stdout, "%s: unhandled subjectAltName " + "dNSName encoding (%d)\n", getprogname(), + format); +#endif + } + + } else if (type == GEN_IPADD) { + unsigned char *data; + int datalen; + + datalen = ASN1_STRING_length(altname->d.iPAddress); + data = ASN1_STRING_data(altname->d.iPAddress); + + if (datalen < 0) { + tls_set_errorx(ctx, + "Unexpected negative length for an " + "IP address: %d", datalen); + rv = -2; + break; + } + + /* + * Per RFC 5280 section 4.2.1.6: + * IPv4 must use 4 octets and IPv6 must use 16 octets. + */ + if (datalen == addrlen && + memcmp(data, &addrbuf, addrlen) == 0) { + rv = 0; + break; + } + } + } + + sk_GENERAL_NAME_pop_free(altname_stack, GENERAL_NAME_free); + return rv; +} + +static int +tls_check_common_name(struct tls *ctx, X509 *cert, const char *name) +{ + X509_NAME *subject_name; + char *common_name = NULL; + union tls_addr addrbuf; + int common_name_len; + int rv = -1; + + subject_name = X509_get_subject_name(cert); + if (subject_name == NULL) + goto out; + + common_name_len = X509_NAME_get_text_by_NID(subject_name, + NID_commonName, NULL, 0); + if (common_name_len < 0) + goto out; + + common_name = calloc(common_name_len + 1, 1); + if (common_name == NULL) + goto out; + + X509_NAME_get_text_by_NID(subject_name, NID_commonName, common_name, + common_name_len + 1); + + /* NUL bytes in CN? */ + if (common_name_len != strlen(common_name)) { + tls_set_errorx(ctx, "error verifying name '%s': " + "NUL byte in Common Name field, " + "probably a malicious certificate", name); + rv = -2; + goto out; + } + + if (inet_pton(AF_INET, name, &addrbuf) == 1 || + inet_pton(AF_INET6, name, &addrbuf) == 1) { + /* + * We don't want to attempt wildcard matching against IP + * addresses, so perform a simple comparison here. + */ + if (strcmp(common_name, name) == 0) + rv = 0; + else + rv = -1; + goto out; + } + + if (tls_match_name(common_name, name) == 0) + rv = 0; + out: + free(common_name); + return rv; +} + +int +tls_check_name(struct tls *ctx, X509 *cert, const char *name) +{ + int rv; + + rv = tls_check_subject_altname(ctx, cert, name); + if (rv == 0 || rv == -2) + return rv; + + return tls_check_common_name(ctx, cert, name); +}